From 43648f7a467705aa203dd8d7d2b61ee3b70fdcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 13:06:05 +0300 Subject: [PATCH 01/12] Add Linux CEF runtime path --- .github/workflows/release.yml | 29 +- Cargo.lock | 524 ++++++++++++++++++++++----- Cargo.toml | 1 + crates/ai/Cargo.toml | 10 +- crates/ai/src/acp/bridge.rs | 26 +- crates/ai/src/acp/bridge_commands.rs | 2 +- crates/ai/src/acp/bridge_init.rs | 23 +- crates/ai/src/acp/bridge_prompt.rs | 3 +- crates/ai/src/acp/client.rs | 3 +- crates/ai/src/acp/config.rs | 3 +- crates/ai/src/acp/mod.rs | 1 + crates/ai/src/acp/process.rs | 68 ++++ crates/ai/src/lib.rs | 1 + crates/ai/src/runtime.rs | 5 + crates/debugger/Cargo.toml | 7 +- crates/debugger/src/lib.rs | 55 ++- crates/extensions/Cargo.toml | 7 +- crates/extensions/src/installer.rs | 3 +- crates/extensions/src/lib.rs | 1 + crates/extensions/src/runtime.rs | 5 + crates/lsp/Cargo.toml | 7 +- crates/lsp/src/client.rs | 3 +- crates/lsp/src/lib.rs | 1 + crates/lsp/src/manager.rs | 6 +- crates/lsp/src/runtime.rs | 5 + crates/remote/Cargo.toml | 7 +- crates/remote/src/lib.rs | 6 +- crates/remote/src/runtime.rs | 5 + crates/remote/src/terminal.rs | 7 +- crates/terminal/Cargo.toml | 7 +- crates/terminal/src/connection.rs | 4 +- crates/terminal/src/lib.rs | 1 + crates/terminal/src/manager.rs | 20 +- crates/terminal/src/runtime.rs | 5 + crates/tooling/Cargo.toml | 7 +- crates/tooling/src/installer.rs | 39 +- crates/tooling/src/lib.rs | 1 + crates/tooling/src/runtime.rs | 5 + package.json | 1 + src-tauri/Cargo.toml | 48 ++- src-tauri/src/app_runtime.rs | 5 + src-tauri/src/app_setup.rs | 41 ++- src-tauri/src/commands/ui/window.rs | 26 +- src-tauri/src/file_events.rs | 12 +- src-tauri/src/main.rs | 22 +- 45 files changed, 858 insertions(+), 210 deletions(-) create mode 100644 crates/ai/src/acp/process.rs create mode 100644 crates/ai/src/runtime.rs create mode 100644 crates/extensions/src/runtime.rs create mode 100644 crates/lsp/src/runtime.rs create mode 100644 crates/remote/src/runtime.rs create mode 100644 crates/terminal/src/runtime.rs create mode 100644 crates/tooling/src/runtime.rs create mode 100644 src-tauri/src/app_runtime.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3174922fa..cb5ccbe43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,6 +87,7 @@ jobs: artifact: "macos-aarch64" os: "macos" args: "--target aarch64-apple-darwin" + cargo_features: "" target: "aarch64-apple-darwin" bundle_path: "target/aarch64-apple-darwin/release/bundle" timeout_minutes: 60 @@ -95,6 +96,7 @@ jobs: artifact: "macos-x86_64" os: "macos" args: "--target x86_64-apple-darwin" + cargo_features: "" target: "x86_64-apple-darwin" bundle_path: "target/x86_64-apple-darwin/release/bundle" timeout_minutes: 60 @@ -103,22 +105,25 @@ jobs: artifact: "linux-x86_64" os: "linux" args: "" + cargo_features: "--no-default-features --features linux-cef" target: "" bundle_path: "target/release/bundle" - timeout_minutes: 60 + timeout_minutes: 120 rustflags: "" - platform: "ubuntu-22.04-arm" artifact: "linux-aarch64" os: "linux" args: "" + cargo_features: "--no-default-features --features linux-cef" target: "" bundle_path: "target/release/bundle" - timeout_minutes: 60 + timeout_minutes: 120 rustflags: "" - platform: "windows-latest" artifact: "windows-x86_64" os: "windows" args: "--bundles nsis" + cargo_features: "" target: "" bundle_path: "target/release/bundle" timeout_minutes: 90 @@ -127,6 +132,7 @@ jobs: artifact: "windows-aarch64" os: "windows" args: "--target aarch64-pc-windows-msvc --bundles nsis" + cargo_features: "" target: "aarch64-pc-windows-msvc" bundle_path: "target/aarch64-pc-windows-msvc/release/bundle" timeout_minutes: 90 @@ -174,6 +180,13 @@ jobs: with: cache-on-failure: true + - name: Cache CEF binaries (Linux only) + if: matrix.os == 'linux' + uses: actions/cache@v4 + with: + path: ~/.local/share/cef + key: ${{ runner.os }}-${{ runner.arch }}-cef-v146.4.1 + - name: Cache Bun dependencies uses: actions/cache@v4 with: @@ -186,7 +199,11 @@ jobs: if: matrix.os == 'linux' run: | sudo apt-get update - sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils file + sudo apt-get install -y libgtk-3-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils file + + - name: Install Tauri CEF CLI (Linux only) + if: matrix.os == 'linux' + run: cargo install tauri-cli --git https://github.com/tauri-apps/tauri --branch feat/cef --locked - name: Install frontend dependencies run: bun install --ignore-scripts && bun scripts/postinstall.ts @@ -314,7 +331,11 @@ jobs: NO_STRIP: ${{ matrix.os == 'linux' && 'true' || '' }} RUSTFLAGS: ${{ matrix.rustflags }} run: | - bun tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} + if [[ "${{ matrix.os }}" == "linux" ]]; then + cargo tauri build ${{ matrix.args }} ${{ matrix.cargo_features }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} + else + bun tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} + fi - name: Collect Windows user installer (Windows only) if: matrix.os == 'windows' diff --git a/Cargo.lock b/Cargo.lock index 5f9201b3d..4e28c21dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -589,7 +589,7 @@ dependencies = [ "rand 0.8.5", "redis", "regex", - "reqwest", + "reqwest 0.12.24", "rusqlite", "serde", "serde_json", @@ -598,7 +598,7 @@ dependencies = [ "sqlx", "tar", "tauri", - "tauri-build", + "tauri-build 2.5.3", "tauri-plugin-clipboard-manager", "tauri-plugin-deep-link", "tauri-plugin-dialog", @@ -635,6 +635,7 @@ dependencies = [ "anyhow", "async-trait", "athas-terminal", + "libc", "log", "rusqlite", "serde", @@ -683,7 +684,7 @@ dependencies = [ "chrono", "flate2", "log", - "reqwest", + "reqwest 0.12.24", "serde", "serde_json", "sha256", @@ -707,7 +708,7 @@ version = "0.1.0" dependencies = [ "git2", "log", - "reqwest", + "reqwest 0.12.24", "serde", "serde_json", ] @@ -759,7 +760,7 @@ version = "0.1.0" dependencies = [ "flate2", "log", - "reqwest", + "reqwest 0.12.24", "serde", "tar", "tempfile", @@ -789,7 +790,7 @@ dependencies = [ "flate2", "futures-util", "log", - "reqwest", + "reqwest 0.12.24", "serde", "serde_json", "tar", @@ -1156,6 +1157,15 @@ dependencies = [ "bzip2-sys", ] +[[package]] +name = "bzip2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" +dependencies = [ + "libbz2-rs-sys", +] + [[package]] name = "bzip2-sys" version = "0.1.13+1.0.8" @@ -1251,6 +1261,30 @@ dependencies = [ "shlex", ] +[[package]] +name = "cef" +version = "146.4.1+146.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5dad6495c583fedab04a24f6fc08274c59a28b33967ca87709398e1f11c2ebe" +dependencies = [ + "cef-dll-sys", + "libloading 0.9.0", + "objc2 0.6.3", + "windows-sys 0.61.2", +] + +[[package]] +name = "cef-dll-sys" +version = "146.4.1+146.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6616217417da12da57bb7650acc3c8be0fc26e7120892ab926d2ba8d84c8c9c2" +dependencies = [ + "anyhow", + "cmake", + "download-cef", + "serde_json", +] + [[package]] name = "cesu8" version = "1.1.0" @@ -1340,6 +1374,46 @@ dependencies = [ "libloading 0.8.9", ] +[[package]] +name = "clap" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + [[package]] name = "clipboard-win" version = "5.4.1" @@ -1349,6 +1423,15 @@ dependencies = [ "error-code", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -1361,7 +1444,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -1398,6 +1481,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "unicode-width 0.2.2", + "windows-sys 0.61.2", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1480,6 +1575,24 @@ dependencies = [ "url", ] +[[package]] +name = "cookie_store" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" +dependencies = [ + "cookie", + "document-features", + "idna", + "indexmap 2.12.1", + "log", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1838,6 +1951,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "dioxus-debug-cell" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ea539174bb236e0e7dc9c12b19b88eae3cb574dedbd0252a2d43ea7e6de13e2" + [[package]] name = "dirs" version = "5.0.1" @@ -1971,6 +2090,25 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "download-cef" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7471a7d5d3bd8df1b3b75871f0317d8a6dd73270ab861cc97ae7907ee63e554" +dependencies = [ + "bzip2 0.6.1", + "clap", + "indicatif", + "regex", + "semver", + "serde", + "serde_json", + "sha1_smol", + "tar", + "thiserror 2.0.17", + "ureq", +] + [[package]] name = "doxygen-rs" version = "0.4.2" @@ -2068,6 +2206,12 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -3320,12 +3464,12 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", "tracing", - "windows-registry 0.6.1", + "windows-registry", ] [[package]] @@ -3354,9 +3498,9 @@ dependencies = [ [[package]] name = "ico" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" dependencies = [ "byteorder", "png 0.17.16", @@ -3523,6 +3667,19 @@ dependencies = [ "serde_core", ] +[[package]] +name = "indicatif" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9375e112e4b463ec1b1c6c011953545c65a30164fbab5b581df32b3abf0dcb88" +dependencies = [ + "console", + "portable-atomic", + "unicode-width 0.2.2", + "unit-prefix", + "web-time", +] + [[package]] name = "infer" version = "0.19.0" @@ -3719,10 +3876,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -3892,6 +4051,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "libbz2-rs-sys" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" + [[package]] name = "libc" version = "0.2.178" @@ -3907,7 +4072,7 @@ dependencies = [ "cc", "flate2", "pkg-config", - "reqwest", + "reqwest 0.12.24", "serde", "serde_json", "tar", @@ -3949,6 +4114,16 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libm" version = "0.2.15" @@ -5190,7 +5365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -5776,7 +5951,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.6.1", + "socket2 0.5.10", "thiserror 2.0.17", "tokio", "tracing", @@ -5813,7 +5988,7 @@ dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.5.10", "tracing", "windows-sys 0.60.2", ] @@ -6108,7 +6283,7 @@ dependencies = [ "base64 0.22.1", "bytes", "cookie", - "cookie_store", + "cookie_store 0.21.1", "encoding_rs", "futures-channel", "futures-core", @@ -6144,11 +6319,45 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", + "wasm-streams 0.4.2", "web-sys", "webpki-roots 1.0.4", ] +[[package]] +name = "reqwest" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams 0.5.0", + "web-sys", +] + [[package]] name = "resolv-conf" version = "0.7.6" @@ -6450,6 +6659,8 @@ dependencies = [ "schemars_derive 1.1.0", "serde", "serde_json", + "url", + "uuid", ] [[package]] @@ -6940,6 +7151,17 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "socks" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" +dependencies = [ + "byteorder", + "libc", + "winapi", +] + [[package]] name = "softbuffer" version = "0.4.6" @@ -7473,9 +7695,8 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15524fc7959bfcaa051ba6d0b3fb1ef18e978de2176c7c6acb977f7fd14d35c7" +version = "2.10.3" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" dependencies = [ "anyhow", "bytes", @@ -7502,17 +7723,18 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.3", "serde", "serde_json", "serde_repr", "serialize-to-javascript", "swift-rs", - "tauri-build", + "tauri-build 2.5.6", "tauri-macros", "tauri-runtime", + "tauri-runtime-cef", "tauri-runtime-wry", - "tauri-utils", + "tauri-utils 2.8.3", "thiserror 2.0.17", "tokio", "tray-icon", @@ -7539,7 +7761,28 @@ dependencies = [ "semver", "serde", "serde_json", - "tauri-utils", + "tauri-utils 2.8.1", + "tauri-winres", + "toml 0.9.8", + "walkdir", +] + +[[package]] +name = "tauri-build" +version = "2.5.6" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs 6.0.0", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 1.1.0", + "semver", + "serde", + "serde_json", + "tauri-utils 2.8.3", "tauri-winres", "toml 0.9.8", "walkdir", @@ -7547,9 +7790,8 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa9844cefcf99554a16e0a278156ae73b0d8680bbc0e2ad1e4287aadd8489cf" +version = "2.5.5" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" dependencies = [ "base64 0.22.1", "brotli", @@ -7564,7 +7806,7 @@ dependencies = [ "serde_json", "sha2", "syn 2.0.111", - "tauri-utils", + "tauri-utils 2.8.3", "thiserror 2.0.17", "time", "url", @@ -7574,16 +7816,15 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3764a12f886d8245e66b7ee9b43ccc47883399be2019a61d80cf0f4117446fde" +version = "2.5.5" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.111", "tauri-codegen", - "tauri-utils", + "tauri-utils 2.8.3", ] [[package]] @@ -7598,7 +7839,7 @@ dependencies = [ "schemars 0.8.22", "serde", "serde_json", - "tauri-utils", + "tauri-utils 2.8.1", "toml 0.9.8", "walkdir", ] @@ -7631,11 +7872,11 @@ dependencies = [ "serde_json", "tauri", "tauri-plugin", - "tauri-utils", + "tauri-utils 2.8.1", "thiserror 2.0.17", "tracing", "url", - "windows-registry 0.5.3", + "windows-registry", "windows-result 0.3.4", ] @@ -7673,7 +7914,7 @@ dependencies = [ "serde_repr", "tauri", "tauri-plugin", - "tauri-utils", + "tauri-utils 2.8.1", "thiserror 2.0.17", "toml 0.9.8", "url", @@ -7686,11 +7927,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c00685aceab12643cf024f712ab0448ba8fcadf86f2391d49d2e5aa732aacc70" dependencies = [ "bytes", - "cookie_store", + "cookie_store 0.21.1", "data-url", "http", "regex", - "reqwest", + "reqwest 0.12.24", "schemars 0.8.22", "serde", "serde_json", @@ -7828,7 +8069,7 @@ dependencies = [ "minisign-verify", "osakit", "percent-encoding", - "reqwest", + "reqwest 0.12.24", "semver", "serde", "serde_json", @@ -7861,9 +8102,8 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f766fe9f3d1efc4b59b17e7a891ad5ed195fa8d23582abb02e6c9a01137892" +version = "2.10.1" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" dependencies = [ "cookie", "dpi", @@ -7872,23 +8112,47 @@ dependencies = [ "jni", "objc2 0.6.3", "objc2-ui-kit", - "objc2-web-kit", "raw-window-handle", "serde", "serde_json", - "tauri-utils", + "tauri-utils 2.8.3", "thiserror 2.0.17", "url", - "webkit2gtk", - "webview2-com", "windows", ] +[[package]] +name = "tauri-runtime-cef" +version = "0.1.0" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" +dependencies = [ + "base64 0.22.1", + "cef", + "cef-dll-sys", + "dioxus-debug-cell", + "dirs 6.0.0", + "gtk", + "html5ever", + "http", + "kuchikiki", + "objc2 0.6.3", + "objc2-app-kit", + "objc2-foundation 0.3.2", + "raw-window-handle", + "serde", + "serde_json", + "sha2", + "tauri-runtime", + "tauri-utils 2.8.3", + "url", + "windows", + "x11-dl", +] + [[package]] name = "tauri-runtime-wry" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7950f3bde6bcca6655bc5e76d3d6ec587ceb81032851ab4ddbe1f508bdea2729" +version = "2.10.1" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" dependencies = [ "gtk", "http", @@ -7896,14 +8160,14 @@ dependencies = [ "log", "objc2 0.6.3", "objc2-app-kit", - "objc2-foundation 0.3.2", + "objc2-web-kit", "once_cell", "percent-encoding", "raw-window-handle", "softbuffer", "tao", "tauri-runtime", - "tauri-utils", + "tauri-utils 2.8.3", "url", "webkit2gtk", "webview2-com", @@ -7918,7 +8182,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76a423c51176eb3616ee9b516a9fa67fed5f0e78baaba680e44eb5dd2cc37490" dependencies = [ "anyhow", - "brotli", "cargo_metadata", "ctor", "dunce", @@ -7949,6 +8212,43 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-utils" +version = "2.8.3" +source = "git+https://github.com/tauri-apps/tauri?branch=feat%2Fcef#7815deda7cec511c2623c0e62d89ad02c026ba58" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dunce", + "glob", + "html5ever", + "http", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "regex", + "schemars 1.1.0", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.17", + "toml 0.9.8", + "url", + "urlpattern", + "uuid", + "walkdir", +] + [[package]] name = "tauri-winres" version = "0.3.5" @@ -8313,9 +8613,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.10.0", "bytes", @@ -8616,12 +8916,51 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unit-prefix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ureq" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +dependencies = [ + "base64 0.22.1", + "cookie_store 0.22.1", + "flate2", + "log", + "percent-encoding", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "socks", + "ureq-proto", + "utf8-zero", + "webpki-roots 1.0.4", +] + +[[package]] +name = "ureq-proto" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" +dependencies = [ + "base64 0.22.1", + "http", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.7" @@ -8658,6 +8997,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -8813,9 +9158,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" dependencies = [ "cfg-if", "once_cell", @@ -8826,22 +9171,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8849,9 +9191,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" dependencies = [ "bumpalo", "proc-macro2", @@ -8862,9 +9204,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" dependencies = [ "unicode-ident", ] @@ -8882,6 +9224,19 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wayland-backend" version = "0.3.11" @@ -8957,9 +9312,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" dependencies = [ "js-sys", "wasm-bindgen", @@ -8977,9 +9332,9 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -9001,9 +9356,9 @@ dependencies = [ [[package]] name = "webkit2gtk-sys" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" dependencies = [ "bitflags 1.3.2", "cairo-sys-rs", @@ -9129,7 +9484,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -9267,17 +9622,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" -dependencies = [ - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -9715,9 +10059,9 @@ checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wry" -version = "0.53.5" +version = "0.54.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728b7d4c8ec8d81cab295e0b5b8a4c263c0d41a785fb8f8c4df284e5411140a2" +checksum = "bb26159b420aa77684589a744ae9a9461a95395b848764ad12290a14d960a11a" dependencies = [ "base64 0.22.1", "block2 0.6.2", @@ -10011,7 +10355,7 @@ checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ "aes", "arbitrary", - "bzip2", + "bzip2 0.5.2", "constant_time_eq 0.3.1", "crc32fast", "crossbeam-utils", diff --git a/Cargo.toml b/Cargo.toml index 6705e2bcd..81fba1705 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ resolver = "2" [patch.crates-io] agent-client-protocol = { path = "vendor/agent-client-protocol" } agent-client-protocol-schema = { path = "vendor/agent-client-protocol-schema" } +tauri = { git = "https://github.com/tauri-apps/tauri", branch = "feat/cef" } [workspace.lints.clippy] uninlined_format_args = "allow" diff --git a/crates/ai/Cargo.toml b/crates/ai/Cargo.toml index 22627094d..25856cebb 100644 --- a/crates/ai/Cargo.toml +++ b/crates/ai/Cargo.toml @@ -3,6 +3,11 @@ name = "athas-ai" version = "0.1.0" edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = ["athas-terminal/tauri-wry", "tauri/wry", "tauri/x11"] +linux-cef = ["athas-terminal/linux-cef", "tauri/cef"] + [dependencies] agent-client-protocol = { version = "0.9", features = [ "unstable_session_config_options", @@ -12,13 +17,14 @@ agent-client-protocol = { version = "0.9", features = [ anyhow = "1.0" async-trait = "0.1" log = "0.4" +libc = "0.2" rusqlite = { version = "0.29.0", features = ["bundled"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tauri = { version = "2", features = ["test"] } +tauri = { version = "2", default-features = false, features = ["test"] } tokio = { version = "1.0", features = ["full"] } tokio-util = { version = "0.7", features = ["compat"] } -athas-terminal = { path = "../terminal" } +athas-terminal = { path = "../terminal", default-features = false } tempfile = "3" uuid = { version = "1.0", features = ["v4", "serde"] } which = "7.0" diff --git a/crates/ai/src/acp/bridge.rs b/crates/ai/src/acp/bridge.rs index ea653f62c..300d65749 100644 --- a/crates/ai/src/acp/bridge.rs +++ b/crates/ai/src/acp/bridge.rs @@ -4,14 +4,16 @@ use super::{ bridge_prompt::run_prompt, client::{AthasAcpClient, PermissionResponse}, config::AgentRegistry, + process::{stop_child_tree, terminate_process_group}, types::{AcpAgentCapabilities, AcpAgentStatus, AcpEvent, AgentConfig, SessionConfigOption}, }; +use crate::runtime::AthasAppHandle as AppHandle; use acp::Agent; use agent_client_protocol as acp; use anyhow::{Context, Result, bail}; use athas_terminal::TerminalManager; use std::{sync::Arc, thread}; -use tauri::{AppHandle, Emitter}; +use tauri::Emitter; use tokio::{ process::Child, runtime::Runtime, @@ -25,6 +27,7 @@ pub(super) struct AcpWorker { session_id: Option, auth_method_id: Option, process: Option, + process_group_id: Option, io_handle: Option>, client: Option>, agent_id: Option, @@ -39,6 +42,7 @@ impl AcpWorker { session_id: None, auth_method_id: None, process: None, + process_group_id: None, io_handle: None, client: None, agent_id: None, @@ -78,6 +82,7 @@ impl AcpWorker { self.connection = None; self.session_id = None; self.process = None; + self.process_group_id = None; self.client = None; self.agent_id = None; self.agent_capabilities = None; @@ -129,6 +134,7 @@ impl AcpWorker { self.connection = Some(initialized.connection); self.session_id = initialized.session_id.clone(); self.auth_method_id = initialized.auth_method_id; + self.process_group_id = initialized.process_group_id; self.process = Some(initialized.process); self.io_handle = Some(initialized.io_handle); self.client = Some(initialized.client); @@ -250,8 +256,8 @@ impl AcpWorker { handle.abort(); } - if let Some(mut process) = self.process.take() { - let _ = process.kill().await; + if let Some(process) = self.process.take() { + stop_child_tree(process, self.process_group_id.take()).await; } self.connection = None; @@ -261,6 +267,7 @@ impl AcpWorker { self.agent_id = None; self.agent_capabilities = None; self.app_handle = None; + self.process_group_id = None; Ok(()) } @@ -280,6 +287,19 @@ impl AcpWorker { } } +impl Drop for AcpWorker { + fn drop(&mut self) { + if let Some(handle) = self.io_handle.take() { + handle.abort(); + } + + if let Some(mut process) = self.process.take() { + terminate_process_group(self.process_group_id.take()); + let _ = process.start_kill(); + } + } +} + /// Manages ACP agent connections via a dedicated worker thread #[derive(Clone)] pub struct AcpAgentBridge { diff --git a/crates/ai/src/acp/bridge_commands.rs b/crates/ai/src/acp/bridge_commands.rs index af236b7d3..14a0977cc 100644 --- a/crates/ai/src/acp/bridge_commands.rs +++ b/crates/ai/src/acp/bridge_commands.rs @@ -3,10 +3,10 @@ use super::{ client::PermissionResponse, types::{AcpAgentStatus, AgentConfig}, }; +use crate::runtime::AthasAppHandle as AppHandle; use anyhow::Result; use athas_terminal::TerminalManager; use std::sync::Arc; -use tauri::AppHandle; use tokio::sync::{Mutex, mpsc, oneshot}; /// Commands that can be sent to the ACP worker thread diff --git a/crates/ai/src/acp/bridge_init.rs b/crates/ai/src/acp/bridge_init.rs index 6947d7a47..d5f560b66 100644 --- a/crates/ai/src/acp/bridge_init.rs +++ b/crates/ai/src/acp/bridge_init.rs @@ -1,17 +1,19 @@ use super::{ client::{AthasAcpClient, PermissionResponse}, + process::{force_kill_process_group, stop_child_tree_mut, terminate_process_group}, types::{ AcpAgentCapabilities, AcpEvent, AgentConfig, SessionConfigOption, SessionMode, SessionModeState, }, }; +use crate::runtime::AthasAppHandle as AppHandle; use acp::Agent; use agent_client_protocol as acp; use anyhow::{Result, bail}; use athas_terminal::TerminalManager; use serde_json::json; use std::{path::PathBuf, process::Stdio, sync::Arc}; -use tauri::{AppHandle, Emitter}; +use tauri::Emitter; use tokio::{ process::{Child, Command}, sync::mpsc, @@ -24,6 +26,7 @@ pub(super) struct InitializedAcpWorker { pub auth_method_id: Option, pub agent_capabilities: AcpAgentCapabilities, pub process: Child, + pub process_group_id: Option, pub io_handle: tokio::task::JoinHandle<()>, pub client: Arc, pub permission_sender: mpsc::Sender, @@ -39,6 +42,7 @@ pub(super) async fn initialize_worker( ) -> Result { let (mut child, uses_npx_codex_adapter) = spawn_agent_process(config, workspace_path.as_deref())?; + let process_group_id = child.id(); let stdin = child .stdin .take() @@ -114,6 +118,7 @@ pub(super) async fn initialize_worker( auth_method_id, agent_capabilities, process: child, + process_group_id, io_handle, client, permission_sender, @@ -137,9 +142,9 @@ where } fn configure_background_agent_command(command: &mut Command) { - #[cfg(not(target_os = "windows"))] + #[cfg(unix)] { - let _ = command; + command.process_group(0); } #[cfg(target_os = "windows")] @@ -254,12 +259,14 @@ async fn initialize_connection( } Ok(Err(e)) => { io_handle.abort(); - let _ = child.kill().await; + let process_group_id = child.id(); + stop_child_tree_mut(child, process_group_id).await; bail!("Failed to initialize ACP connection: {}", e); } Err(_) => { io_handle.abort(); - let _ = child.kill().await; + let process_group_id = child.id(); + stop_child_tree_mut(child, process_group_id).await; bail!( "ACP initialization timed out - agent may not support ACP protocol or requires \ different arguments" @@ -316,6 +323,7 @@ async fn bootstrap_session( { if let Err(e) = authenticate(connection.clone()).await { ctx.io_handle.abort(); + terminate_process_group(ctx.child.id()); let _ = ctx.child.kill().await; bail!("{}", e); } @@ -346,6 +354,7 @@ async fn bootstrap_session( } Ok(Err(err)) => { ctx.io_handle.abort(); + terminate_process_group(ctx.child.id()); let _ = ctx.child.kill().await; bail!( "Failed to load ACP session {}: {}", @@ -355,6 +364,7 @@ async fn bootstrap_session( } Err(_) => { ctx.io_handle.abort(); + force_kill_process_group(ctx.child.id()); let _ = ctx.child.kill().await; bail!("ACP session/load timed out"); } @@ -367,6 +377,7 @@ async fn bootstrap_session( { if let Err(e) = authenticate(connection.clone()).await { ctx.io_handle.abort(); + terminate_process_group(ctx.child.id()); let _ = ctx.child.kill().await; bail!("{}", e); } @@ -379,12 +390,14 @@ async fn bootstrap_session( Ok(Err(e)) => { log::error!("Failed to create ACP session: {}", e); ctx.io_handle.abort(); + terminate_process_group(ctx.child.id()); let _ = ctx.child.kill().await; bail!("Failed to create ACP session: {}", e); } Err(_) => { log::error!("ACP session creation timed out"); ctx.io_handle.abort(); + force_kill_process_group(ctx.child.id()); let _ = ctx.child.kill().await; bail!("ACP session creation timed out"); } diff --git a/crates/ai/src/acp/bridge_prompt.rs b/crates/ai/src/acp/bridge_prompt.rs index 83cde9591..cd6f70017 100644 --- a/crates/ai/src/acp/bridge_prompt.rs +++ b/crates/ai/src/acp/bridge_prompt.rs @@ -1,9 +1,10 @@ use super::types::{AcpEvent, StopReason}; +use crate::runtime::AthasAppHandle as AppHandle; use acp::Agent; use agent_client_protocol as acp; use anyhow::{Context, Result, bail}; use std::sync::Arc; -use tauri::{AppHandle, Emitter}; +use tauri::Emitter; const ACP_PROMPT_TIMEOUT_SECONDS: u64 = 90; diff --git a/crates/ai/src/acp/client.rs b/crates/ai/src/acp/client.rs index 3bbc5c0a8..3a8abc18f 100644 --- a/crates/ai/src/acp/client.rs +++ b/crates/ai/src/acp/client.rs @@ -6,6 +6,7 @@ use super::{ SessionConfigOptionKind, SessionConfigOptionValue, UiAction, }, }; +use crate::runtime::AthasAppHandle as AppHandle; use agent_client_protocol as acp; use async_trait::async_trait; use athas_terminal::{TerminalConfig, TerminalManager}; @@ -14,7 +15,7 @@ use std::{ path::PathBuf, sync::{Arc, Mutex as StdMutex}, }; -use tauri::{AppHandle, Emitter, Listener}; +use tauri::{Emitter, Listener}; use tokio::sync::{Mutex, mpsc, oneshot}; /// Response for permission requests diff --git a/crates/ai/src/acp/config.rs b/crates/ai/src/acp/config.rs index e83f0a664..3203590b9 100644 --- a/crates/ai/src/acp/config.rs +++ b/crates/ai/src/acp/config.rs @@ -1,4 +1,5 @@ use super::types::{AgentConfig, AgentRuntime}; +use crate::runtime::AthasAppHandle as AppHandle; use std::{ collections::HashMap, env, fs, @@ -7,7 +8,7 @@ use std::{ sync::OnceLock, time::Instant, }; -use tauri::{AppHandle, Manager}; +use tauri::Manager; /// Cache duration for binary detection (60 seconds) const DETECTION_CACHE_SECONDS: u64 = 60; diff --git a/crates/ai/src/acp/mod.rs b/crates/ai/src/acp/mod.rs index fb1a3ed83..7223f2b43 100644 --- a/crates/ai/src/acp/mod.rs +++ b/crates/ai/src/acp/mod.rs @@ -4,6 +4,7 @@ mod bridge_init; mod bridge_prompt; mod client; mod config; +mod process; mod terminal_state; pub mod types; diff --git a/crates/ai/src/acp/process.rs b/crates/ai/src/acp/process.rs new file mode 100644 index 000000000..746e7dd94 --- /dev/null +++ b/crates/ai/src/acp/process.rs @@ -0,0 +1,68 @@ +use std::time::Duration; +use tokio::{process::Child, time::timeout}; + +const GRACEFUL_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(2); + +#[cfg(unix)] +fn signal_process_group(process_group_id: Option, signal: libc::c_int) { + let Some(process_group_id) = process_group_id else { + return; + }; + + if process_group_id == 0 || process_group_id > libc::pid_t::MAX as u32 { + return; + } + + unsafe { + let _ = libc::kill(-(process_group_id as libc::pid_t), signal); + } +} + +pub(super) fn terminate_process_group(process_group_id: Option) { + #[cfg(unix)] + signal_process_group(process_group_id, libc::SIGTERM); + + #[cfg(not(unix))] + { + let _ = process_group_id; + } +} + +pub(super) fn force_kill_process_group(process_group_id: Option) { + #[cfg(unix)] + signal_process_group(process_group_id, libc::SIGKILL); + + #[cfg(not(unix))] + { + let _ = process_group_id; + } +} + +pub(super) async fn stop_child_tree(process: Child, process_group_id: Option) { + let mut process = process; + terminate_process_group(process_group_id); + + if timeout(GRACEFUL_SHUTDOWN_TIMEOUT, process.wait()) + .await + .is_ok() + { + return; + } + + force_kill_process_group(process_group_id); + let _ = process.kill().await; +} + +pub(super) async fn stop_child_tree_mut(process: &mut Child, process_group_id: Option) { + terminate_process_group(process_group_id); + + if timeout(GRACEFUL_SHUTDOWN_TIMEOUT, process.wait()) + .await + .is_ok() + { + return; + } + + force_kill_process_group(process_group_id); + let _ = process.kill().await; +} diff --git a/crates/ai/src/lib.rs b/crates/ai/src/lib.rs index 456ac8d35..f9e048450 100644 --- a/crates/ai/src/lib.rs +++ b/crates/ai/src/lib.rs @@ -1,5 +1,6 @@ pub mod acp; pub mod chat_history; +mod runtime; pub use acp::{AcpAgentBridge, AcpAgentStatus, AgentConfig, AgentRuntime}; pub use chat_history::{ diff --git a/crates/ai/src/runtime.rs b/crates/ai/src/runtime.rs new file mode 100644 index 000000000..8518ee768 --- /dev/null +++ b/crates/ai/src/runtime.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "linux-cef")] +pub type AthasAppHandle = tauri::AppHandle; + +#[cfg(not(feature = "linux-cef"))] +pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/debugger/Cargo.toml b/crates/debugger/Cargo.toml index 4abd766ea..45f9821f4 100644 --- a/crates/debugger/Cargo.toml +++ b/crates/debugger/Cargo.toml @@ -3,11 +3,16 @@ name = "athas-debugger" version = "0.1.0" edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = ["tauri/wry", "tauri/x11"] +linux-cef = ["tauri/cef"] + [dependencies] anyhow = "1.0" athas-runtime = { path = "../runtime" } log = "0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tauri = { version = "2", features = ["test"] } +tauri = { version = "2", default-features = false, features = ["test"] } uuid = { version = "1.0", features = ["v4", "serde"] } diff --git a/crates/debugger/src/lib.rs b/crates/debugger/src/lib.rs index b3a36ecda..32277eae0 100644 --- a/crates/debugger/src/lib.rs +++ b/crates/debugger/src/lib.rs @@ -13,7 +13,7 @@ use std::{ }, thread, }; -use tauri::{AppHandle, Emitter, Wry}; +use tauri::{AppHandle, Emitter, Runtime}; use uuid::Uuid; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -66,14 +66,16 @@ struct DebugSessionHandle { } pub struct DebugManager { - app_handle: AppHandle, + emitter: Arc, sessions: Arc>>, } impl DebugManager { - pub fn new(app_handle: AppHandle) -> Self { + pub fn new(app_handle: AppHandle) -> Self { Self { - app_handle, + emitter: Arc::new(move |event, payload| { + let _ = app_handle.emit(event, payload); + }), sessions: Arc::new(Mutex::new(HashMap::new())), } } @@ -130,8 +132,8 @@ impl DebugManager { }; spawn_stdin_writer(stdin, stdin_rx); - spawn_stdout_reader(self.app_handle.clone(), session_id.clone(), stdout); - spawn_stderr_reader(self.app_handle.clone(), session_id.clone(), stderr); + spawn_stdout_reader(Arc::clone(&self.emitter), session_id.clone(), stdout); + spawn_stderr_reader(Arc::clone(&self.emitter), session_id.clone(), stderr); self .sessions @@ -148,7 +150,7 @@ impl DebugManager { ); spawn_exit_watcher( - self.app_handle.clone(), + Arc::clone(&self.emitter), Arc::clone(&self.sessions), info.id.clone(), child, @@ -215,7 +217,7 @@ impl DebugManager { let _ = child.kill(); } - emit_session_ended(&self.app_handle, session_id, "stopped"); + emit_session_ended(&self.emitter, session_id, "stopped"); Ok(()) } @@ -257,7 +259,7 @@ fn spawn_stdin_writer( } fn spawn_stdout_reader( - app_handle: AppHandle, + emitter: Arc, session_id: String, stdout: std::process::ChildStdout, ) { @@ -267,7 +269,8 @@ fn spawn_stdout_reader( loop { match read_protocol_message(&mut reader) { Ok(Some(message)) => { - let _ = app_handle.emit( + emit_payload( + &emitter, "debugger_message", DebugProtocolMessage { session_id: session_id.clone(), @@ -276,12 +279,12 @@ fn spawn_stdout_reader( ); } Ok(None) => { - emit_session_ended(&app_handle, &session_id, "adapter stdout closed"); + emit_session_ended(&emitter, &session_id, "adapter stdout closed"); break; } Err(error) => { log::warn!("Debug adapter stdout read error: {error}"); - emit_session_ended(&app_handle, &session_id, "adapter stdout read error"); + emit_session_ended(&emitter, &session_id, "adapter stdout read error"); break; } } @@ -290,7 +293,7 @@ fn spawn_stdout_reader( } fn spawn_stderr_reader( - app_handle: AppHandle, + emitter: Arc, session_id: String, stderr: std::process::ChildStderr, ) { @@ -304,7 +307,8 @@ fn spawn_stderr_reader( Ok(0) => break, Ok(_) => { if !line.trim().is_empty() { - let _ = app_handle.emit( + emit_payload( + &emitter, "debugger_output", DebugProcessOutput { session_id: session_id.clone(), @@ -324,7 +328,7 @@ fn spawn_stderr_reader( } fn spawn_exit_watcher( - app_handle: AppHandle, + emitter: Arc, sessions: Arc>>, session_id: String, child: Arc>, @@ -342,7 +346,7 @@ fn spawn_exit_watcher( sessions.remove(&session_id); } - emit_session_ended(&app_handle, &session_id, &reason); + emit_session_ended(&emitter, &session_id, &reason); }); } @@ -377,8 +381,23 @@ fn read_protocol_message( Ok(Some(serde_json::from_slice(&content)?)) } -fn emit_session_ended(app_handle: &AppHandle, session_id: &str, reason: &str) { - let _ = app_handle.emit( +fn emit_payload( + emitter: &Arc, + event: &str, + payload: S, +) { + if let Ok(value) = serde_json::to_value(payload) { + emitter(event, value); + } +} + +fn emit_session_ended( + emitter: &Arc, + session_id: &str, + reason: &str, +) { + emit_payload( + emitter, "debugger_session_ended", DebugSessionEnded { session_id: session_id.to_string(), diff --git a/crates/extensions/Cargo.toml b/crates/extensions/Cargo.toml index 28b292703..9a3370e69 100644 --- a/crates/extensions/Cargo.toml +++ b/crates/extensions/Cargo.toml @@ -3,6 +3,11 @@ name = "athas-extensions" version = "0.1.0" edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = ["tauri/wry", "tauri/x11"] +linux-cef = ["tauri/cef"] + [dependencies] anyhow = "1.0" chrono = { version = "0.4.41", features = ["serde"] } @@ -13,4 +18,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha256 = "1.5" tar = "0.4" -tauri = { version = "2", features = ["test"] } +tauri = { version = "2", default-features = false, features = ["test"] } diff --git a/crates/extensions/src/installer.rs b/crates/extensions/src/installer.rs index 7b8374c40..6e9d42f5f 100644 --- a/crates/extensions/src/installer.rs +++ b/crates/extensions/src/installer.rs @@ -1,10 +1,11 @@ use super::types::{DownloadInfo, ExtensionMetadata, InstallProgress, InstallStatus}; +use crate::runtime::AthasAppHandle as AppHandle; use anyhow::{Context, Result}; use std::{ fs, path::{Path, PathBuf}, }; -use tauri::{AppHandle, Emitter, Manager}; +use tauri::{Emitter, Manager}; pub struct ExtensionInstaller { app_handle: AppHandle, diff --git a/crates/extensions/src/lib.rs b/crates/extensions/src/lib.rs index fdb3ae18b..fdc4e8bbd 100644 --- a/crates/extensions/src/lib.rs +++ b/crates/extensions/src/lib.rs @@ -1,4 +1,5 @@ pub mod installer; +mod runtime; pub mod types; pub use installer::*; diff --git a/crates/extensions/src/runtime.rs b/crates/extensions/src/runtime.rs new file mode 100644 index 000000000..8518ee768 --- /dev/null +++ b/crates/extensions/src/runtime.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "linux-cef")] +pub type AthasAppHandle = tauri::AppHandle; + +#[cfg(not(feature = "linux-cef"))] +pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/lsp/Cargo.toml b/crates/lsp/Cargo.toml index ad14ec001..6af52bd46 100644 --- a/crates/lsp/Cargo.toml +++ b/crates/lsp/Cargo.toml @@ -3,6 +3,11 @@ name = "athas-lsp" version = "0.1.0" edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = ["tauri/wry", "tauri/x11"] +linux-cef = ["tauri/cef"] + [dependencies] anyhow = "1.0" athas-runtime = { path = "../runtime" } @@ -11,7 +16,7 @@ log = "0.4" lsp-types = { version = "0.95", features = ["proposed"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tauri = { version = "2", features = ["test"] } +tauri = { version = "2", default-features = false, features = ["test"] } tokio = { version = "1.0", features = ["full"] } which = "7.0" diff --git a/crates/lsp/src/client.rs b/crates/lsp/src/client.rs index 04c0ccb97..5c4ad3187 100644 --- a/crates/lsp/src/client.rs +++ b/crates/lsp/src/client.rs @@ -1,3 +1,4 @@ +use crate::runtime::AthasAppHandle as AppHandle; use anyhow::{Context, Result, bail}; use athas_runtime::{NodeRuntime, process::configure_background_command}; use crossbeam_channel::{Sender, bounded}; @@ -15,7 +16,7 @@ use std::{ }, thread, }; -use tauri::{AppHandle, Emitter, Manager}; +use tauri::{Emitter, Manager}; use tokio::sync::oneshot; type PendingRequests = Arc>>>>; diff --git a/crates/lsp/src/lib.rs b/crates/lsp/src/lib.rs index 0e1472998..def2aec3f 100644 --- a/crates/lsp/src/lib.rs +++ b/crates/lsp/src/lib.rs @@ -3,6 +3,7 @@ pub mod config; pub mod manager; mod manager_state; mod manager_support; +mod runtime; pub mod types; pub mod utils; diff --git a/crates/lsp/src/manager.rs b/crates/lsp/src/manager.rs index 32b0a6f03..5fa13df80 100644 --- a/crates/lsp/src/manager.rs +++ b/crates/lsp/src/manager.rs @@ -2,7 +2,9 @@ use super::{ client::LspClient, config::{LspRegistry, LspSettings}, manager_state::{LspInstance, WorkspaceClients}, - manager_support, utils, + manager_support, + runtime::AthasAppHandle as AppHandle, + utils, }; use anyhow::{Context, Result, bail}; use lsp_types::*; @@ -11,7 +13,7 @@ use std::{ path::{Path, PathBuf}, time::Instant, }; -use tauri::{AppHandle, Manager as TauriManager}; +use tauri::Manager as TauriManager; pub struct LspManager { // Map (workspace path, language) to their LSP clients with reference counting diff --git a/crates/lsp/src/runtime.rs b/crates/lsp/src/runtime.rs new file mode 100644 index 000000000..8518ee768 --- /dev/null +++ b/crates/lsp/src/runtime.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "linux-cef")] +pub type AthasAppHandle = tauri::AppHandle; + +#[cfg(not(feature = "linux-cef"))] +pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/remote/Cargo.toml b/crates/remote/Cargo.toml index 3022cd43f..8e8e74406 100644 --- a/crates/remote/Cargo.toml +++ b/crates/remote/Cargo.toml @@ -3,11 +3,16 @@ name = "athas-remote" version = "0.1.0" edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = ["tauri/wry", "tauri/x11"] +linux-cef = ["tauri/cef"] + [dependencies] lazy_static = "1.4" log = "0.4" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" ssh2 = { version = "0.9", features = ["vendored-openssl"] } -tauri = { version = "2", features = ["test"] } +tauri = { version = "2", default-features = false, features = ["test"] } uuid = { version = "1", features = ["v4"] } diff --git a/crates/remote/src/lib.rs b/crates/remote/src/lib.rs index 4ffc6f992..912a751c9 100644 --- a/crates/remote/src/lib.rs +++ b/crates/remote/src/lib.rs @@ -1,4 +1,5 @@ mod file_ops; +mod runtime; mod ssh_helpers; mod state; mod terminal; @@ -8,6 +9,7 @@ use crate::{ read_directory as read_directory_inner, read_file as read_file_inner, write_file as write_file_inner, }, + runtime::AthasAppHandle as AppHandle, ssh_helpers::{create_ssh_session, exec_remote_command, shell_quote}, state::CONNECTIONS, terminal::{ @@ -77,7 +79,7 @@ pub async fn ssh_connect( Ok(connection) } -pub async fn ssh_disconnect(app: tauri::AppHandle, connection_id: String) -> Result<(), String> { +pub async fn ssh_disconnect(app: AppHandle, connection_id: String) -> Result<(), String> { let mut connections = CONNECTIONS .lock() .map_err(|e| format!("Failed to lock connections: {}", e))?; @@ -216,7 +218,7 @@ pub async fn ssh_copy_path( #[allow(clippy::too_many_arguments)] pub async fn create_remote_terminal( - app: tauri::AppHandle, + app: AppHandle, host: String, port: u16, username: String, diff --git a/crates/remote/src/runtime.rs b/crates/remote/src/runtime.rs new file mode 100644 index 000000000..8518ee768 --- /dev/null +++ b/crates/remote/src/runtime.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "linux-cef")] +pub type AthasAppHandle = tauri::AppHandle; + +#[cfg(not(feature = "linux-cef"))] +pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/remote/src/terminal.rs b/crates/remote/src/terminal.rs index 5d8df1b47..8afe8a3cd 100644 --- a/crates/remote/src/terminal.rs +++ b/crates/remote/src/terminal.rs @@ -1,4 +1,5 @@ use crate::{ + runtime::AthasAppHandle as AppHandle, ssh_helpers::{create_ssh_session, shell_quote}, state::{REMOTE_TERMINALS, RemoteTerminal}, }; @@ -13,7 +14,7 @@ use uuid::Uuid; #[allow(clippy::too_many_arguments)] pub(super) async fn create_remote_terminal( - app: tauri::AppHandle, + app: AppHandle, host: String, port: u16, username: String, @@ -126,7 +127,7 @@ pub(super) async fn close_remote_terminal(id: String) -> Result<(), String> { Ok(()) } -fn spawn_terminal_reader(app: tauri::AppHandle, id: String, channel: Arc>) { +fn spawn_terminal_reader(app: AppHandle, id: String, channel: Arc>) { thread::spawn(move || { let mut buffer = vec![0u8; 65536]; @@ -181,7 +182,7 @@ fn spawn_terminal_reader(app: tauri::AppHandle, id: String, channel: Arc; + +#[cfg(not(feature = "linux-cef"))] +pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/tooling/Cargo.toml b/crates/tooling/Cargo.toml index bacdab33d..6f05c7146 100644 --- a/crates/tooling/Cargo.toml +++ b/crates/tooling/Cargo.toml @@ -3,6 +3,11 @@ name = "athas-tooling" version = "0.1.0" edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = ["tauri/wry", "tauri/x11"] +linux-cef = ["tauri/cef"] + [dependencies] athas-runtime = { path = "../runtime" } flate2 = "1.0" @@ -11,7 +16,7 @@ log = "0.4" reqwest = { version = "0.12", features = ["stream"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -tauri = { version = "2", features = ["test"] } +tauri = { version = "2", default-features = false, features = ["test"] } tar = "0.4" tempfile = "3.20.0" url = "2.5" diff --git a/crates/tooling/src/installer.rs b/crates/tooling/src/installer.rs index f5f30f7cd..8e3c224bc 100644 --- a/crates/tooling/src/installer.rs +++ b/crates/tooling/src/installer.rs @@ -1,4 +1,4 @@ -use crate::{ToolConfig, ToolError, ToolRuntime, platform}; +use crate::{ToolConfig, ToolError, ToolRuntime, platform, runtime::AthasAppHandle as AppHandle}; use athas_runtime::{RuntimeManager, RuntimeType, process::configure_background_command}; use flate2::read::GzDecoder; use futures_util::StreamExt; @@ -41,7 +41,7 @@ fn validate_binary_download_url(input: &str) -> Result<(), ToolError> { pub struct ToolInstaller; impl ToolInstaller { - fn get_runtime_root(app_handle: &tauri::AppHandle) -> Result { + fn get_runtime_root(app_handle: &AppHandle) -> Result { app_handle .path() .app_data_dir() @@ -397,7 +397,7 @@ impl ToolInstaller { }) } - fn binary_install_dir(app_handle: &tauri::AppHandle, name: &str) -> Result { + fn binary_install_dir(app_handle: &AppHandle, name: &str) -> Result { Ok(Self::get_tools_dir(app_handle)?.join("binary").join(name)) } @@ -442,10 +442,7 @@ impl ToolInstaller { } /// Install a tool based on its configuration - pub async fn install( - app_handle: &tauri::AppHandle, - config: &ToolConfig, - ) -> Result { + pub async fn install(app_handle: &AppHandle, config: &ToolConfig) -> Result { match config.runtime { ToolRuntime::Bun => { let package = config @@ -513,7 +510,7 @@ impl ToolInstaller { } /// Get the installation directory for tools - pub fn get_tools_dir(app_handle: &tauri::AppHandle) -> Result { + pub fn get_tools_dir(app_handle: &AppHandle) -> Result { let data_dir = app_handle .path() .app_data_dir() @@ -523,7 +520,7 @@ impl ToolInstaller { /// Install a package via Bun (global) async fn install_via_bun( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, package: &str, command_name: &str, ) -> Result { @@ -568,7 +565,7 @@ impl ToolInstaller { /// Install a package via npm (global) async fn install_via_npm( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, package: &str, command_name: &str, ) -> Result { @@ -619,7 +616,7 @@ impl ToolInstaller { /// Install a package via pip (user) async fn install_via_pip( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, package: &str, command_name: &str, ) -> Result { @@ -688,7 +685,7 @@ impl ToolInstaller { /// Install a package via go install async fn install_via_go( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, package: &str, command_name: &str, ) -> Result { @@ -729,7 +726,7 @@ impl ToolInstaller { /// Install a package via cargo install async fn install_via_cargo( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, package: &str, command_name: &str, ) -> Result { @@ -843,7 +840,7 @@ impl ToolInstaller { /// Install a package via RubyGems into an Athas-managed GEM_HOME. async fn install_via_gem( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, package: &str, command_name: &str, ) -> Result { @@ -896,7 +893,7 @@ impl ToolInstaller { /// - A 100 MB streaming size cap, independently of any `Content-Length`. /// - Successful HTTP status. async fn download_binary( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, name: &str, command_name: &str, url: &str, @@ -948,10 +945,7 @@ impl ToolInstaller { } /// Check if a tool is installed - pub fn is_installed( - app_handle: &tauri::AppHandle, - config: &ToolConfig, - ) -> Result { + pub fn is_installed(app_handle: &AppHandle, config: &ToolConfig) -> Result { let path = Self::get_tool_path(app_handle, config)?; if !path.exists() { return Ok(false); @@ -962,10 +956,7 @@ impl ToolInstaller { } /// Get the path where a tool would be/is installed - pub fn get_tool_path( - app_handle: &tauri::AppHandle, - config: &ToolConfig, - ) -> Result { + pub fn get_tool_path(app_handle: &AppHandle, config: &ToolConfig) -> Result { let tools_dir = Self::get_tools_dir(app_handle)?; match config.runtime { @@ -1063,7 +1054,7 @@ impl ToolInstaller { /// For Node/Bun tools, this returns the package bin entrypoint (e.g. .js/.mjs) /// so the LSP client can run it with managed Node runtime. pub fn get_lsp_launch_path( - app_handle: &tauri::AppHandle, + app_handle: &AppHandle, config: &ToolConfig, ) -> Result { let tools_dir = Self::get_tools_dir(app_handle)?; diff --git a/crates/tooling/src/lib.rs b/crates/tooling/src/lib.rs index e03e7ac04..0693c9f53 100644 --- a/crates/tooling/src/lib.rs +++ b/crates/tooling/src/lib.rs @@ -1,6 +1,7 @@ mod installer; mod platform; mod registry; +mod runtime; mod types; pub use installer::ToolInstaller; diff --git a/crates/tooling/src/runtime.rs b/crates/tooling/src/runtime.rs new file mode 100644 index 000000000..8518ee768 --- /dev/null +++ b/crates/tooling/src/runtime.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "linux-cef")] +pub type AthasAppHandle = tauri::AppHandle; + +#[cfg(not(feature = "linux-cef"))] +pub type AthasAppHandle = tauri::AppHandle; diff --git a/package.json b/package.json index 5c4eaba63..1a5f81dda 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "dev:stable": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev", "dev:preview": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.preview.conf.json", "build:stable": "bun scripts/check-zig.ts && tauri build", + "build:linux-cef": "bun scripts/check-zig.ts && cargo tauri build --no-default-features --features linux-cef", "build:preview": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.preview.conf.json", "build:dev": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.dev.conf.json", "smoke": "bun scripts/smoke-app.ts", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 787c8aacc..d4389075c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -5,6 +5,30 @@ description = "Athas code editor" authors = ["you"] edition = "2024" +[features] +default = ["tauri-wry"] +tauri-wry = [ + "athas-ai/tauri-wry", + "athas-debugger/tauri-wry", + "athas-extensions/tauri-wry", + "athas-lsp/tauri-wry", + "athas-remote/tauri-wry", + "athas-terminal/tauri-wry", + "athas-tooling/tauri-wry", + "tauri/wry", + "tauri/x11", +] +linux-cef = [ + "athas-ai/linux-cef", + "athas-debugger/linux-cef", + "athas-extensions/linux-cef", + "athas-lsp/linux-cef", + "athas-remote/linux-cef", + "athas-terminal/linux-cef", + "athas-tooling/linux-cef", + "tauri/cef", +] + [lints] workspace = true @@ -27,18 +51,18 @@ env_logger = "0.11.8" futures-util = "0.3" git2 = { version = "0.20", features = ["vendored-libgit2", "vendored-openssl"] } athas-runtime = { path = "../crates/runtime" } -athas-tooling = { path = "../crates/tooling" } -athas-lsp = { path = "../crates/lsp" } -athas-remote = { path = "../crates/remote" } +athas-tooling = { path = "../crates/tooling", default-features = false } +athas-lsp = { path = "../crates/lsp", default-features = false } +athas-remote = { path = "../crates/remote", default-features = false } athas-project = { path = "../crates/project" } athas-database = { path = "../crates/database" } athas-version-control = { path = "../crates/version-control" } -athas-extensions = { path = "../crates/extensions" } -athas-terminal = { path = "../crates/terminal" } -athas-ai = { path = "../crates/ai" } +athas-extensions = { path = "../crates/extensions", default-features = false } +athas-terminal = { path = "../crates/terminal", default-features = false } +athas-ai = { path = "../crates/ai", default-features = false } athas-github = { path = "../crates/github" } athas-fff-search = { path = "../crates/fff-search" } -athas-debugger = { path = "../crates/debugger" } +athas-debugger = { path = "../crates/debugger", default-features = false } mimalloc = { version = "0.1", default-features = false } log = "0.4.27" percent-encoding = "2" @@ -63,7 +87,15 @@ sqlx = { version = "0.8.6", default-features = false, features = [ "postgres", "mysql", ] } -tauri = { version = "2", features = ["protocol-asset", "macos-private-api", "unstable", "test"] } +tauri = { version = "2", default-features = false, features = [ + "compression", + "common-controls-v6", + "dynamic-acl", + "macos-private-api", + "protocol-asset", + "test", + "unstable", +] } tauri-plugin-dialog = "2" tauri-plugin-fs = "2" tauri-plugin-http = "2" diff --git a/src-tauri/src/app_runtime.rs b/src-tauri/src/app_runtime.rs new file mode 100644 index 000000000..ec58b7b19 --- /dev/null +++ b/src-tauri/src/app_runtime.rs @@ -0,0 +1,5 @@ +#[cfg(all(target_os = "linux", feature = "linux-cef"))] +pub type AthasRuntime = tauri::Cef; + +#[cfg(not(all(target_os = "linux", feature = "linux-cef")))] +pub type AthasRuntime = tauri::Wry; diff --git a/src-tauri/src/app_setup.rs b/src-tauri/src/app_setup.rs index 9be54067d..333e40da8 100644 --- a/src-tauri/src/app_setup.rs +++ b/src-tauri/src/app_setup.rs @@ -1,4 +1,5 @@ use crate::{ + app_runtime::AthasRuntime, commands::{self, FffSearchState, FileClipboard, ThemeCache}, file_events::TauriFileChangeEmitter, menu, @@ -11,13 +12,13 @@ use athas_lsp::LspManager; use athas_project::FileWatcher; use log::{debug, info}; use std::sync::Arc; -use tauri::{Emitter, Manager, Wry}; +use tauri::{Emitter, Manager}; #[cfg(not(target_os = "windows"))] use tauri_plugin_os::platform; use tauri_plugin_store::StoreExt; use tokio::sync::Mutex; -pub fn configure_app(app: &mut tauri::App) -> Result<(), Box> { +pub fn configure_app(app: &mut tauri::App) -> Result<(), Box> { configure_menu(app)?; register_managed_state(app); emit_cli_open_requests(app); @@ -31,7 +32,7 @@ pub fn configure_app(app: &mut tauri::App) -> Result<(), Box) -> Result<(), Box> { +fn configure_menu(app: &mut tauri::App) -> Result<(), Box> { let store = app.store("settings.json")?; #[cfg(target_os = "windows")] @@ -61,7 +62,7 @@ fn configure_menu(app: &mut tauri::App) -> Result<(), Box) { +fn register_managed_state(app: &mut tauri::App) { log::info!("Starting app!"); app.manage(Arc::new(FileWatcher::new(Arc::new( @@ -85,7 +86,7 @@ fn register_managed_state(app: &mut tauri::App) { app.manage(FffSearchState::new()); } -fn emit_cli_open_requests(app: &tauri::App) { +fn emit_cli_open_requests(app: &tauri::App) { let cwd = std::env::current_dir().unwrap_or_default(); let args: Vec = std::env::args().skip(1).collect(); let open_requests = commands::development::cli_args::parse_cli_args(&args, &cwd); @@ -105,20 +106,22 @@ fn emit_cli_open_requests(app: &tauri::App) { }); } -fn configure_initial_window(app: &tauri::App) { +fn configure_initial_window(app: &tauri::App) { if let Some(window) = app.get_webview_window("main") { commands::ui::window::configure_app_window(&window); } } -fn get_active_webview_window(app: &tauri::AppHandle) -> Option> { +fn get_active_webview_window( + app: &tauri::AppHandle, +) -> Option> { app.get_focused_window() .and_then(|window| app.get_webview_window(window.label())) .or_else(|| app.get_webview_window("main")) .or_else(|| app.webview_windows().into_values().next()) } -fn handle_menu_event(app_handle: &tauri::AppHandle, event: tauri::menu::MenuEvent) { +fn handle_menu_event(app_handle: &tauri::AppHandle, event: tauri::menu::MenuEvent) { match event.id().0.as_str() { "new_window" => { let app_handle = app_handle.clone(); @@ -134,10 +137,12 @@ fn handle_menu_event(app_handle: &tauri::AppHandle, event: tauri::menu::Men match event_id { "quit" => { info!("Quit menu item clicked"); + shutdown_background_services(app_handle); std::process::exit(0); } "quit_app" => { info!("Quit app menu item triggered"); + shutdown_background_services(app_handle); std::process::exit(0); } "new_file" => { @@ -262,3 +267,23 @@ fn handle_menu_event(app_handle: &tauri::AppHandle, event: tauri::menu::Men } } } + +pub(crate) fn shutdown_background_services(app_handle: &tauri::AppHandle) { + if let Some(acp_bridge) = app_handle.try_state::>>() { + let acp_bridge = acp_bridge.inner().clone(); + tauri::async_runtime::block_on(async move { + let bridge = acp_bridge.lock().await; + if let Err(error) = bridge.stop_agent().await { + log::debug!("ACP shutdown returned error: {}", error); + } + }); + } + + if let Some(lsp_manager) = app_handle.try_state::() { + lsp_manager.shutdown(); + } + + if let Some(terminal_manager) = app_handle.try_state::>() { + terminal_manager.close_all(); + } +} diff --git a/src-tauri/src/commands/ui/window.rs b/src-tauri/src/commands/ui/window.rs index 15b598a47..567ecdb11 100644 --- a/src-tauri/src/commands/ui/window.rs +++ b/src-tauri/src/commands/ui/window.rs @@ -1,11 +1,9 @@ +use crate::app_runtime::AthasRuntime; use serde::{Deserialize, Serialize}; use std::sync::atomic::{AtomicU32, Ordering}; #[cfg(target_os = "macos")] use tauri::TitleBarStyle; -use tauri::{ - AppHandle, Emitter, Manager, WebviewBuilder, WebviewUrl, WebviewWindow, command, - webview::PageLoadEvent, -}; +use tauri::{Emitter, Manager, WebviewBuilder, WebviewUrl, command, webview::PageLoadEvent}; // Counter for generating unique web viewer labels static WEB_VIEWER_COUNTER: AtomicU32 = AtomicU32::new(0); @@ -76,7 +74,7 @@ fn build_window_open_url(request: Option<&CreateAppWindowRequest>) -> String { format!("/?{}", serializer.finish()) } -pub fn configure_app_window(window: &WebviewWindow) { +pub fn configure_app_window(window: &tauri::WebviewWindow) { #[cfg(target_os = "macos")] { use window_vibrancy::{NSVisualEffectMaterial, apply_vibrancy}; @@ -97,7 +95,7 @@ pub fn configure_app_window(window: &WebviewWindow) { } pub fn create_app_window_internal( - app: &AppHandle, + app: &tauri::AppHandle, request: Option, ) -> Result { let label = format!( @@ -134,7 +132,7 @@ pub fn create_app_window_internal( #[command] pub async fn create_app_window( - app: tauri::AppHandle, + app: tauri::AppHandle, request: Option, ) -> Result { create_app_window_internal(&app, request) @@ -312,7 +310,7 @@ fn build_webview_bridge_script(webview_label: &str) -> Result { #[command] pub async fn create_embedded_webview( - app: tauri::AppHandle, + app: tauri::AppHandle, url: String, x: f64, y: f64, @@ -390,7 +388,7 @@ pub async fn create_embedded_webview( #[command] pub async fn close_embedded_webview( - app: tauri::AppHandle, + app: tauri::AppHandle, webview_label: String, ) -> Result<(), String> { if let Some(webview) = app.get_webview(&webview_label) { @@ -403,7 +401,7 @@ pub async fn close_embedded_webview( #[command] pub async fn navigate_embedded_webview( - app: tauri::AppHandle, + app: tauri::AppHandle, webview_label: String, url: String, ) -> Result<(), String> { @@ -425,7 +423,7 @@ pub async fn navigate_embedded_webview( #[command] pub async fn resize_embedded_webview( - app: tauri::AppHandle, + app: tauri::AppHandle, webview_label: String, x: f64, y: f64, @@ -451,7 +449,7 @@ pub async fn resize_embedded_webview( #[command] pub async fn set_webview_visible( - app: tauri::AppHandle, + app: tauri::AppHandle, webview_label: String, visible: bool, ) -> Result<(), String> { @@ -473,7 +471,7 @@ pub async fn set_webview_visible( #[command] pub async fn open_webview_devtools( - app: tauri::AppHandle, + app: tauri::AppHandle, webview_label: String, ) -> Result<(), String> { if let Some(webview) = app.get_webview(&webview_label) { @@ -568,7 +566,7 @@ fn infer_webview_protocol(value: &str) -> &'static str { #[command] pub async fn set_webview_zoom( - app: tauri::AppHandle, + app: tauri::AppHandle, webview_label: String, zoom_level: f64, ) -> Result<(), String> { diff --git a/src-tauri/src/file_events.rs b/src-tauri/src/file_events.rs index 20dd40851..e8c4c4e93 100644 --- a/src-tauri/src/file_events.rs +++ b/src-tauri/src/file_events.rs @@ -1,17 +1,17 @@ use athas_project::{FileChangeEmitter, FileChangeEvent}; -use tauri::{AppHandle, Emitter}; +use tauri::{AppHandle, Emitter, Runtime}; -pub struct TauriFileChangeEmitter { - app_handle: AppHandle, +pub struct TauriFileChangeEmitter { + app_handle: AppHandle, } -impl TauriFileChangeEmitter { - pub fn new(app_handle: AppHandle) -> Self { +impl TauriFileChangeEmitter { + pub fn new(app_handle: AppHandle) -> Self { Self { app_handle } } } -impl FileChangeEmitter for TauriFileChangeEmitter { +impl FileChangeEmitter for TauriFileChangeEmitter { fn emit_file_change(&self, event: &FileChangeEvent) { let _ = self.app_handle.emit("file-changed", event); } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 894e1d677..6f346b445 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,10 +4,12 @@ #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; -use app_setup::configure_app; +use app_runtime::AthasRuntime; +use app_setup::{configure_app, shutdown_background_services}; use commands::*; use terminal::{close_terminal, create_terminal, list_shells, terminal_resize, terminal_write}; +mod app_runtime; mod app_setup; mod bootstrap; mod commands; @@ -17,9 +19,13 @@ mod menu; mod secure_storage; mod terminal; +#[cfg_attr( + all(target_os = "linux", feature = "linux-cef"), + tauri::cef_entry_point +)] fn main() { #[cfg(target_os = "linux")] - if std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() { + if cfg!(not(feature = "linux-cef")) && std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() { // SAFETY: Called at program start before any threads are spawned unsafe { std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1"); @@ -29,7 +35,7 @@ fn main() { #[cfg(target_os = "macos")] bootstrap::macos::disable_macos_autofill_heuristics(); - tauri::Builder::default() + tauri::Builder::::new() .plugin(tauri_plugin_store::Builder::default().build()) .plugin(tauri_plugin_clipboard_manager::init()) .plugin(logger::init(log::LevelFilter::Info)) @@ -340,6 +346,12 @@ fn main() { menu::toggle_menu_bar, menu::rebuild_menu_themes, ]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); + .build(tauri::generate_context!()) + .expect("error while building tauri application") + .run(|app_handle, event| match event { + tauri::RunEvent::ExitRequested { .. } | tauri::RunEvent::Exit => { + shutdown_background_services(app_handle); + } + _ => {} + }); } From dab72dd0e257c3930baa3b82b5e8a45bd5d3254b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 13:40:24 +0300 Subject: [PATCH 02/12] Add Linux CEF build workflow --- .github/workflows/linux-cef-build.yml | 130 ++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 .github/workflows/linux-cef-build.yml diff --git a/.github/workflows/linux-cef-build.yml b/.github/workflows/linux-cef-build.yml new file mode 100644 index 000000000..6d8707cef --- /dev/null +++ b/.github/workflows/linux-cef-build.yml @@ -0,0 +1,130 @@ +name: "Linux CEF Build" + +on: + pull_request: + branches: [master] + paths: + - ".github/workflows/linux-cef-build.yml" + - ".github/workflows/release.yml" + - "Cargo.lock" + - "Cargo.toml" + - "crates/**" + - "src-tauri/**" + - "package.json" + - "bun.lock" + workflow_dispatch: + inputs: + runner: + description: "Linux runner to build on" + required: true + default: "ubuntu-22.04" + type: choice + options: + - "ubuntu-22.04" + - "ubuntu-22.04-arm" + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ inputs.runner || 'ubuntu-22.04' }} + cancel-in-progress: true + +jobs: + build: + if: github.repository == 'athasdev/athas' + name: Build Linux CEF bundles + runs-on: ${{ inputs.runner || 'ubuntu-22.04' }} + timeout-minutes: 120 + env: + CARGO_TERM_COLOR: always + NO_STRIP: "true" + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Free disk space + run: | + echo "Disk usage before cleanup:" + df -h + sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android /opt/hostedtoolcache/CodeQL || true + sudo docker system prune -af || true + sudo apt-get clean + echo "Disk usage after cleanup:" + df -h + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + + - name: Setup Zig + uses: mlugg/setup-zig@v2 + with: + version: 0.16.0 + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Cache CEF binaries + uses: actions/cache@v4 + with: + path: ~/.local/share/cef + key: ${{ runner.os }}-${{ runner.arch }}-cef-v146.4.1 + + - name: Cache Bun dependencies + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install Linux dependencies + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils file + + - name: Install Tauri CEF CLI + run: cargo install tauri-cli --git https://github.com/tauri-apps/tauri --branch feat/cef --locked + + - name: Install frontend dependencies + run: bun install --ignore-scripts && bun scripts/postinstall.ts + + - name: Check Linux CEF feature graph + run: | + set -euo pipefail + cargo tree -p athas --no-default-features --features linux-cef -i tauri-runtime-cef + cargo tree -p athas --no-default-features --features linux-cef -i tauri-runtime-wry >/tmp/tauri-runtime-wry.txt 2>&1 || true + if grep -q '^tauri-runtime-wry ' /tmp/tauri-runtime-wry.txt; then + echo "tauri-runtime-wry must not be present in the Linux CEF build" + cat /tmp/tauri-runtime-wry.txt + exit 1 + fi + cargo tree -p athas --no-default-features --features linux-cef -i webkit2gtk >/tmp/webkit2gtk.txt 2>&1 || true + if grep -q '^webkit2gtk ' /tmp/webkit2gtk.txt; then + echo "webkit2gtk must not be present in the Linux CEF build" + cat /tmp/webkit2gtk.txt + exit 1 + fi + + - name: Build Linux CEF bundles + run: | + cargo tauri build \ + --no-default-features \ + --features linux-cef \ + --bundles appimage,deb,rpm \ + --config '{"bundle":{"createUpdaterArtifacts":false}}' + + - name: Upload Linux CEF bundles + uses: actions/upload-artifact@v4 + with: + name: linux-cef-${{ runner.arch }} + path: | + target/release/bundle/**/*.AppImage + target/release/bundle/**/*.deb + target/release/bundle/**/*.rpm + if-no-files-found: error From 5bad434341f416b5397acec55fe12ba5e8e83f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 13:58:05 +0300 Subject: [PATCH 03/12] Fix Linux CEF build arguments --- .github/workflows/linux-cef-build.yml | 7 ++++--- .github/workflows/release.yml | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linux-cef-build.yml b/.github/workflows/linux-cef-build.yml index 6d8707cef..6df9cb741 100644 --- a/.github/workflows/linux-cef-build.yml +++ b/.github/workflows/linux-cef-build.yml @@ -114,10 +114,11 @@ jobs: - name: Build Linux CEF bundles run: | cargo tauri build \ - --no-default-features \ - --features linux-cef \ --bundles appimage,deb,rpm \ - --config '{"bundle":{"createUpdaterArtifacts":false}}' + --config '{"bundle":{"createUpdaterArtifacts":false}}' \ + -- \ + --no-default-features \ + --features linux-cef - name: Upload Linux CEF bundles uses: actions/upload-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cb5ccbe43..4bdb4b0ae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -332,7 +332,7 @@ jobs: RUSTFLAGS: ${{ matrix.rustflags }} run: | if [[ "${{ matrix.os }}" == "linux" ]]; then - cargo tauri build ${{ matrix.args }} ${{ matrix.cargo_features }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} + cargo tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} -- ${{ matrix.cargo_features }} else bun tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} fi diff --git a/package.json b/package.json index 1a5f81dda..5081abb0b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "dev:stable": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev", "dev:preview": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.preview.conf.json", "build:stable": "bun scripts/check-zig.ts && tauri build", - "build:linux-cef": "bun scripts/check-zig.ts && cargo tauri build --no-default-features --features linux-cef", + "build:linux-cef": "bun scripts/check-zig.ts && cargo tauri build -- --no-default-features --features linux-cef", "build:preview": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.preview.conf.json", "build:dev": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.dev.conf.json", "smoke": "bun scripts/smoke-app.ts", From 4ac44344652b1d317c63cf780c48ddbc110dcf5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 14:02:15 +0300 Subject: [PATCH 04/12] Align Tauri JavaScript packages --- bun.lock | 46 +++++++++++++++++++++++++++++++--------------- package.json | 4 ++-- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/bun.lock b/bun.lock index 77541ad43..1d077eb4d 100644 --- a/bun.lock +++ b/bun.lock @@ -18,7 +18,7 @@ "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tooltip": "^1.2.8", "@tanstack/react-virtual": "^3.13.12", - "@tauri-apps/api": "^2.9.1", + "@tauri-apps/api": "^2.10.1", "@tauri-apps/plugin-clipboard-manager": "~2.3.2", "@tauri-apps/plugin-deep-link": "^2.4.5", "@tauri-apps/plugin-dialog": "^2.4.2", @@ -68,7 +68,7 @@ "@commitlint/cli": "^19.8.1", "@derekstride/tree-sitter-sql": "^0.3.11", "@tailwindcss/vite": "^4.1.17", - "@tauri-apps/cli": "^2.9.5", + "@tauri-apps/cli": "^2.10.1", "@tlaplus/tree-sitter-tlaplus": "^1.0.0", "@tree-sitter-grammars/tree-sitter-markdown": "^0.3.0", "@tree-sitter-grammars/tree-sitter-vue": "github:tree-sitter-grammars/tree-sitter-vue", @@ -698,31 +698,31 @@ "@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.12", "", {}, "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA=="], - "@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + "@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="], - "@tauri-apps/cli": ["@tauri-apps/cli@2.9.5", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.5", "@tauri-apps/cli-darwin-x64": "2.9.5", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.5", "@tauri-apps/cli-linux-arm64-gnu": "2.9.5", "@tauri-apps/cli-linux-arm64-musl": "2.9.5", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.5", "@tauri-apps/cli-linux-x64-gnu": "2.9.5", "@tauri-apps/cli-linux-x64-musl": "2.9.5", "@tauri-apps/cli-win32-arm64-msvc": "2.9.5", "@tauri-apps/cli-win32-ia32-msvc": "2.9.5", "@tauri-apps/cli-win32-x64-msvc": "2.9.5" }, "bin": { "tauri": "tauri.js" } }, "sha512-z88tX6O6kwTgMjYozhNGbehzQyBazgXejyH784CwSfBOWm06xFcogd0PY/jhcPsqzJF9kLRIkmlQy+cqdrioOQ=="], + "@tauri-apps/cli": ["@tauri-apps/cli@2.10.1", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.1", "@tauri-apps/cli-darwin-x64": "2.10.1", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1", "@tauri-apps/cli-linux-arm64-gnu": "2.10.1", "@tauri-apps/cli-linux-arm64-musl": "2.10.1", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.1", "@tauri-apps/cli-linux-x64-gnu": "2.10.1", "@tauri-apps/cli-linux-x64-musl": "2.10.1", "@tauri-apps/cli-win32-arm64-msvc": "2.10.1", "@tauri-apps/cli-win32-ia32-msvc": "2.10.1", "@tauri-apps/cli-win32-x64-msvc": "2.10.1" }, "bin": { "tauri": "tauri.js" } }, "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g=="], - "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.9.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P5XDyCwq3VbWGAplyfP/bgmuUITVDcypxgZUyX45SM7HbU1Nrkk0cNK1HCOkuNBAVVbWen2GUNWah/AiupHHXg=="], + "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.10.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ=="], - "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.9.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-JC9UfQ2ZKavx60dnNxsWztRF3oUH3dgPwN1WJ3/5RUy2aNwD/vXqvJAfNFZ4GWeQpoQ+PqJxduev0U4OMQonnA=="], + "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.10.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw=="], - "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.9.5", "", { "os": "linux", "cpu": "arm" }, "sha512-iCQm2Uvx8AheghfG/QUv1y8Ga9yquJt6xJwH1uF0x5KfmJmwBi8pHBvB924dDi59PS84qTdIBeJejQT00QX3Iw=="], + "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.10.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w=="], - "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.9.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-b6AW8Gr5nQOQIYH0TsUev7rEThGHIvsx192eElOmOz/dh33J4pninHK32laMj2hzHMJ27qmDq5vANL+wrFo9sg=="], + "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA=="], - "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.9.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-/gRBMnphS9E8riZ0LIbBhZ9Oy16A2rx/g3DGR0DcDBvUtkLfbL0lMu4s+sY85nkn9An15+cZ1ZK6d7AIqWahLA=="], + "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg=="], - "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.9.5", "", { "os": "linux", "cpu": "none" }, "sha512-NOzjPF9YIBodjdkFcJmqINT0k3YDoR5ANM/jg6Z6s3Zmk8ScN6inI60jTxcfgfWyITiKsPy7GJyYou3Cm2XNzw=="], + "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.10.1", "", { "os": "linux", "cpu": "none" }, "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw=="], - "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.9.5", "", { "os": "linux", "cpu": "x64" }, "sha512-SfGbwgvTphM5y+J91NyU/psleMUlyyPkZyDCFg8WU1HX8DpKUT3Vwhb/W1xpUBGb56tJgGCO46FCVkr8w4Areg=="], + "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw=="], - "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.9.5", "", { "os": "linux", "cpu": "x64" }, "sha512-ZfeoiASAOGDzyvN+TDAg8A1pCeS082h4uc0vZKvtWUN+9QBIMfz0yJwltAv+SN/afap6NS6DVkbPV3UVuI9V5A=="], + "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ=="], - "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.9.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-ulg7irow+ekjaK4inFHVq7m1KQebDSYNb17DFKV+h+x7qnLZymz2gHK7df2u4YyEjqvzwRd3AJpU3HNxRurSFQ=="], + "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.10.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg=="], - "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.9.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-6lF0k/Qduhn1Z3IOXlp2ts8jNOMIX4cK4Fbk3axGeX7LMcVVbOSEAFwbTqS8BKZDFac0WRS8N1C96+Ms5LOS1Q=="], + "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.10.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw=="], - "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.9.5", "", { "os": "win32", "cpu": "x64" }, "sha512-Vg50U74x1A4b2iBVtDcAVPbI1XVuzSmwlduuBM1VewxtRaVj5GDzWnYtBcnuIk+VGzNApRDfDhraAXGaW2a/Gw=="], + "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.10.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg=="], "@tauri-apps/plugin-clipboard-manager": ["@tauri-apps/plugin-clipboard-manager@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ=="], @@ -1782,10 +1782,26 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@tauri-apps/plugin-clipboard-manager/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + "@tauri-apps/plugin-deep-link/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + "@tauri-apps/plugin-dialog/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + + "@tauri-apps/plugin-fs/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + "@tauri-apps/plugin-http/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + "@tauri-apps/plugin-opener/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + + "@tauri-apps/plugin-os/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + + "@tauri-apps/plugin-process/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + + "@tauri-apps/plugin-shell/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + + "@tauri-apps/plugin-store/@tauri-apps/api": ["@tauri-apps/api@2.9.1", "", {}, "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw=="], + "@tauri-apps/plugin-updater/@tauri-apps/api": ["@tauri-apps/api@2.7.0", "", {}, "sha512-v7fVE8jqBl8xJFOcBafDzXFc8FnicoH3j8o8DNNs0tHuEBmXUDqrCOAzMRX0UkfpwqZLqvrvK0GNQ45DfnoVDg=="], "@tree-sitter-grammars/tree-sitter-markdown/node-addon-api": ["node-addon-api@8.6.0", "", {}, "sha512-gBVjCaqDlRUk0EwoPNKzIr9KkS9041G/q31IBShPs1Xz6UTA+EXdZADbzqAJQrpDRq71CIMnOP5VMut3SL0z5Q=="], diff --git a/package.json b/package.json index 5081abb0b..17afb12b2 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tooltip": "^1.2.8", "@tanstack/react-virtual": "^3.13.12", - "@tauri-apps/api": "^2.9.1", + "@tauri-apps/api": "^2.10.1", "@tauri-apps/plugin-clipboard-manager": "~2.3.2", "@tauri-apps/plugin-deep-link": "^2.4.5", "@tauri-apps/plugin-dialog": "^2.4.2", @@ -105,7 +105,7 @@ "@commitlint/cli": "^19.8.1", "@derekstride/tree-sitter-sql": "^0.3.11", "@tailwindcss/vite": "^4.1.17", - "@tauri-apps/cli": "^2.9.5", + "@tauri-apps/cli": "^2.10.1", "@tlaplus/tree-sitter-tlaplus": "^1.0.0", "@tree-sitter-grammars/tree-sitter-markdown": "^0.3.0", "@tree-sitter-grammars/tree-sitter-vue": "github:tree-sitter-grammars/tree-sitter-vue", From e95a59d2b34d94667c09beaf4ea3151684df91df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 14:31:14 +0300 Subject: [PATCH 05/12] Use concrete Tauri app handle runtime --- src-tauri/src/app_runtime.rs | 2 + src-tauri/src/commands/ai/acp.rs | 3 +- src-tauri/src/commands/ai/auth.rs | 9 +++-- src-tauri/src/commands/ai/chat_history.rs | 29 +++++++++----- src-tauri/src/commands/ai/tokens.rs | 6 +-- .../src/commands/database/credentials.rs | 18 +++++---- src-tauri/src/commands/development/cli.rs | 3 +- src-tauri/src/commands/development/runtime.rs | 3 +- src-tauri/src/commands/development/tools.rs | 2 +- src-tauri/src/commands/editor/search.rs | 4 +- src-tauri/src/commands/extensions.rs | 7 +++- src-tauri/src/commands/fuzzy.rs | 3 +- src-tauri/src/commands/project/clipboard.rs | 3 +- src-tauri/src/commands/project/remote.rs | 11 ++++-- .../commands/project/remote_credentials.rs | 6 +-- .../src/commands/version_control/github.rs | 39 +++++++++++-------- src-tauri/src/menu.rs | 7 +++- src-tauri/src/secure_storage.rs | 2 +- src-tauri/src/terminal.rs | 3 +- 19 files changed, 100 insertions(+), 60 deletions(-) diff --git a/src-tauri/src/app_runtime.rs b/src-tauri/src/app_runtime.rs index ec58b7b19..d02f29782 100644 --- a/src-tauri/src/app_runtime.rs +++ b/src-tauri/src/app_runtime.rs @@ -3,3 +3,5 @@ pub type AthasRuntime = tauri::Cef; #[cfg(not(all(target_os = "linux", feature = "linux-cef")))] pub type AthasRuntime = tauri::Wry; + +pub type AppHandle = tauri::AppHandle; diff --git a/src-tauri/src/commands/ai/acp.rs b/src-tauri/src/commands/ai/acp.rs index 02b713236..4c3476221 100644 --- a/src-tauri/src/commands/ai/acp.rs +++ b/src-tauri/src/commands/ai/acp.rs @@ -1,3 +1,4 @@ +use crate::app_runtime::AppHandle; use athas_ai::{AcpAgentBridge, AcpAgentStatus, AgentConfig, AgentRuntime}; use athas_runtime::{RuntimeManager, RuntimeType}; use athas_tooling::{ToolConfig, ToolInstaller, ToolRuntime}; @@ -7,7 +8,7 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use tauri::{AppHandle, Manager, State}; +use tauri::{Manager, State}; use tokio::sync::Mutex; pub type AcpBridgeState = Arc>; diff --git a/src-tauri/src/commands/ai/auth.rs b/src-tauri/src/commands/ai/auth.rs index cfa2b00be..453f6e4c7 100644 --- a/src-tauri/src/commands/ai/auth.rs +++ b/src-tauri/src/commands/ai/auth.rs @@ -5,18 +5,21 @@ const AUTH_TOKEN_KEY: &str = "athas_auth_token"; /// Store the auth token using OS keychain when available. #[command] -pub async fn store_auth_token(app: tauri::AppHandle, token: String) -> Result<(), String> { +pub async fn store_auth_token( + app: crate::app_runtime::AppHandle, + token: String, +) -> Result<(), String> { store_secret(&app, AUTH_TOKEN_KEY, &token) } /// Get the stored auth token #[command] -pub async fn get_auth_token(app: tauri::AppHandle) -> Result, String> { +pub async fn get_auth_token(app: crate::app_runtime::AppHandle) -> Result, String> { get_secret(&app, AUTH_TOKEN_KEY) } /// Remove the auth token #[command] -pub async fn remove_auth_token(app: tauri::AppHandle) -> Result<(), String> { +pub async fn remove_auth_token(app: crate::app_runtime::AppHandle) -> Result<(), String> { remove_secret(&app, AUTH_TOKEN_KEY) } diff --git a/src-tauri/src/commands/ai/chat_history.rs b/src-tauri/src/commands/ai/chat_history.rs index 48a3871ae..b126101ee 100644 --- a/src-tauri/src/commands/ai/chat_history.rs +++ b/src-tauri/src/commands/ai/chat_history.rs @@ -4,7 +4,7 @@ use athas_ai::{ use std::path::PathBuf; use tauri::{Manager, command}; -fn chat_history_db_path(app: &tauri::AppHandle) -> Result { +fn chat_history_db_path(app: &crate::app_runtime::AppHandle) -> Result { let app_data_dir = app .path() .app_data_dir() @@ -12,18 +12,18 @@ fn chat_history_db_path(app: &tauri::AppHandle) -> Result { Ok(app_data_dir.join("chat_history.db")) } -fn repository(app: &tauri::AppHandle) -> Result { +fn repository(app: &crate::app_runtime::AppHandle) -> Result { Ok(ChatHistoryRepository::new(chat_history_db_path(app)?)) } #[command] -pub async fn init_chat_database(app: tauri::AppHandle) -> Result<(), String> { +pub async fn init_chat_database(app: crate::app_runtime::AppHandle) -> Result<(), String> { repository(&app)?.initialize() } #[command] pub async fn save_chat( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, chat: ChatData, messages: Vec, tool_calls: Vec, @@ -32,27 +32,38 @@ pub async fn save_chat( } #[command] -pub async fn load_all_chats(app: tauri::AppHandle) -> Result, String> { +pub async fn load_all_chats(app: crate::app_runtime::AppHandle) -> Result, String> { repository(&app)?.load_all_chats() } #[command] -pub async fn load_chat(app: tauri::AppHandle, chat_id: String) -> Result { +pub async fn load_chat( + app: crate::app_runtime::AppHandle, + chat_id: String, +) -> Result { repository(&app)?.load_chat(&chat_id) } #[command] -pub async fn delete_chat(app: tauri::AppHandle, chat_id: String) -> Result<(), String> { +pub async fn delete_chat( + app: crate::app_runtime::AppHandle, + chat_id: String, +) -> Result<(), String> { repository(&app)?.delete_chat(&chat_id) } #[command] -pub async fn search_chats(app: tauri::AppHandle, query: String) -> Result, String> { +pub async fn search_chats( + app: crate::app_runtime::AppHandle, + query: String, +) -> Result, String> { repository(&app)?.search_chats(&query) } #[command] -pub async fn get_chat_stats(app: tauri::AppHandle) -> Result { +pub async fn get_chat_stats( + app: crate::app_runtime::AppHandle, +) -> Result { let stats: ChatStats = repository(&app)?.get_stats()?; Ok(serde_json::json!({ "total_chats": stats.total_chats, diff --git a/src-tauri/src/commands/ai/tokens.rs b/src-tauri/src/commands/ai/tokens.rs index c5a32ae61..c6d892054 100644 --- a/src-tauri/src/commands/ai/tokens.rs +++ b/src-tauri/src/commands/ai/tokens.rs @@ -8,7 +8,7 @@ fn provider_key(provider_id: &str) -> String { /// Store an AI provider token using OS keychain when available. #[command] pub async fn store_ai_provider_token( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, provider_id: String, token: String, ) -> Result<(), String> { @@ -18,7 +18,7 @@ pub async fn store_ai_provider_token( /// Get an AI provider token #[command] pub async fn get_ai_provider_token( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, provider_id: String, ) -> Result, String> { get_secret(&app, &provider_key(&provider_id)) @@ -27,7 +27,7 @@ pub async fn get_ai_provider_token( /// Remove an AI provider token #[command] pub async fn remove_ai_provider_token( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, provider_id: String, ) -> Result<(), String> { remove_secret(&app, &provider_key(&provider_id)) diff --git a/src-tauri/src/commands/database/credentials.rs b/src-tauri/src/commands/database/credentials.rs index 0aed7f94a..5ba54e3a1 100644 --- a/src-tauri/src/commands/database/credentials.rs +++ b/src-tauri/src/commands/database/credentials.rs @@ -19,7 +19,7 @@ const DB_CONNECTIONS_KEY: &str = "db_saved_connections"; #[command] pub async fn store_db_credential( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, password: String, ) -> Result<(), String> { @@ -29,7 +29,7 @@ pub async fn store_db_credential( #[command] pub async fn get_db_credential( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, ) -> Result, String> { let key = format!("{}{}", DB_CRED_PREFIX, connection_id); @@ -38,7 +38,7 @@ pub async fn get_db_credential( #[command] pub async fn remove_db_credential( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, ) -> Result<(), String> { let key = format!("{}{}", DB_CRED_PREFIX, connection_id); @@ -47,7 +47,7 @@ pub async fn remove_db_credential( #[command] pub async fn save_connection( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection: SavedConnection, ) -> Result<(), String> { // Get existing connections @@ -66,13 +66,15 @@ pub async fn save_connection( } #[command] -pub async fn list_saved_connections(app: tauri::AppHandle) -> Result, String> { +pub async fn list_saved_connections( + app: crate::app_runtime::AppHandle, +) -> Result, String> { get_saved_connections_internal(&app) } #[command] pub async fn delete_saved_connection( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, ) -> Result<(), String> { let mut connections = get_saved_connections_internal(&app)?; @@ -89,7 +91,9 @@ pub async fn delete_saved_connection( Ok(()) } -fn get_saved_connections_internal(app: &tauri::AppHandle) -> Result, String> { +fn get_saved_connections_internal( + app: &crate::app_runtime::AppHandle, +) -> Result, String> { match secure_storage::get_secret(app, DB_CONNECTIONS_KEY)? { Some(json) => serde_json::from_str(&json) .map_err(|e| format!("Failed to parse saved connections: {}", e)), diff --git a/src-tauri/src/commands/development/cli.rs b/src-tauri/src/commands/development/cli.rs index 5799dfbed..302c4dede 100644 --- a/src-tauri/src/commands/development/cli.rs +++ b/src-tauri/src/commands/development/cli.rs @@ -1,7 +1,8 @@ +use crate::app_runtime::AppHandle; use std::fs; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; -use tauri::{AppHandle, command}; +use tauri::command; // Platform-specific CLI paths #[cfg(unix)] diff --git a/src-tauri/src/commands/development/runtime.rs b/src-tauri/src/commands/development/runtime.rs index 660ec9d2c..01c17b41b 100644 --- a/src-tauri/src/commands/development/runtime.rs +++ b/src-tauri/src/commands/development/runtime.rs @@ -1,6 +1,7 @@ +use crate::app_runtime::AppHandle; use athas_runtime::{BunRuntime, NodeRuntime, RuntimeManager, RuntimeStatus, RuntimeType}; use std::path::PathBuf; -use tauri::{AppHandle, Manager}; +use tauri::Manager; fn managed_runtime_root(app_handle: &AppHandle) -> Result { app_handle diff --git a/src-tauri/src/commands/development/tools.rs b/src-tauri/src/commands/development/tools.rs index 0dad94a1c..c8ec05c78 100644 --- a/src-tauri/src/commands/development/tools.rs +++ b/src-tauri/src/commands/development/tools.rs @@ -1,8 +1,8 @@ +use crate::app_runtime::AppHandle; use athas_tooling::{ LanguageToolConfigSet, LanguageToolStatus, ToolInstaller, ToolRegistry, ToolStatus, ToolType, }; use serde_json::Value; -use tauri::AppHandle; #[tauri::command] pub fn frontend_trace(level: String, scope: String, message: String, payload: Option) { diff --git a/src-tauri/src/commands/editor/search.rs b/src-tauri/src/commands/editor/search.rs index 282503963..c5ea85e98 100644 --- a/src-tauri/src/commands/editor/search.rs +++ b/src-tauri/src/commands/editor/search.rs @@ -1,8 +1,8 @@ -use crate::commands::fuzzy::FffSearchState; +use crate::{app_runtime::AppHandle, commands::fuzzy::FffSearchState}; use athas_fff_search::{GrepMode, GrepSearchOptions, parse_grep_query}; use serde::{Deserialize, Serialize}; use std::time::{Duration, Instant}; -use tauri::{AppHandle, State}; +use tauri::State; const INITIAL_SCAN_WAIT_TIMEOUT: Duration = Duration::from_millis(1500); const INITIAL_SCAN_WAIT_INTERVAL: Duration = Duration::from_millis(25); diff --git a/src-tauri/src/commands/extensions.rs b/src-tauri/src/commands/extensions.rs index 0b63796fb..649ccd53f 100644 --- a/src-tauri/src/commands/extensions.rs +++ b/src-tauri/src/commands/extensions.rs @@ -1,3 +1,4 @@ +use crate::app_runtime::AppHandle; use athas_extensions::{DownloadInfo, ExtensionInstaller, ExtensionMetadata}; use sha2::{Digest, Sha256}; use std::{ @@ -6,7 +7,7 @@ use std::{ io::Write, path::{Path, PathBuf}, }; -use tauri::{AppHandle, Runtime, command}; +use tauri::{AppHandle as TauriAppHandle, Runtime, command}; use url::Url; fn validate_extension_id(extension_id: &str) -> Result<(), String> { @@ -219,7 +220,9 @@ fn get_extensions_dir() -> Result { } #[command] -pub fn get_bundled_extensions_path(app_handle: AppHandle) -> Result { +pub fn get_bundled_extensions_path( + app_handle: TauriAppHandle, +) -> Result { // In production, use Tauri's resource directory API // In development, fall back to the source path let extensions_path = if cfg!(debug_assertions) { diff --git a/src-tauri/src/commands/fuzzy.rs b/src-tauri/src/commands/fuzzy.rs index 063b046d8..0018882c5 100644 --- a/src-tauri/src/commands/fuzzy.rs +++ b/src-tauri/src/commands/fuzzy.rs @@ -1,3 +1,4 @@ +use crate::app_runtime::AppHandle; use athas_fff_search::{FffSearch, FffSearchHit}; use nucleo_matcher::{ Config, Matcher, Utf32Str, @@ -8,7 +9,7 @@ use std::{ path::{Path, PathBuf}, sync::{Mutex, OnceLock}, }; -use tauri::{AppHandle, Manager, State}; +use tauri::{Manager, State}; #[derive(Debug, Serialize, Deserialize)] pub struct FuzzyMatchItem { diff --git a/src-tauri/src/commands/project/clipboard.rs b/src-tauri/src/commands/project/clipboard.rs index 2a2017e81..19266c710 100644 --- a/src-tauri/src/commands/project/clipboard.rs +++ b/src-tauri/src/commands/project/clipboard.rs @@ -1,7 +1,8 @@ use super::{copy_dir_all, remove_dir_all}; +use crate::app_runtime::AppHandle; use serde::{Deserialize, Serialize}; use std::{fs, path::Path}; -use tauri::{AppHandle, Emitter, State, command}; +use tauri::{Emitter, State, command}; use tokio::sync::RwLock; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/src-tauri/src/commands/project/remote.rs b/src-tauri/src/commands/project/remote.rs index 7783f06b7..58b5f4141 100644 --- a/src-tauri/src/commands/project/remote.rs +++ b/src-tauri/src/commands/project/remote.rs @@ -15,7 +15,7 @@ use tauri::Emitter; #[tauri::command] #[allow(clippy::too_many_arguments)] pub async fn ssh_connect( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, host: String, port: u16, @@ -47,7 +47,10 @@ pub async fn ssh_connect( } #[tauri::command] -pub async fn ssh_disconnect(app: tauri::AppHandle, connection_id: String) -> Result<(), String> { +pub async fn ssh_disconnect( + app: crate::app_runtime::AppHandle, + connection_id: String, +) -> Result<(), String> { remote_ssh_disconnect(app.clone(), connection_id.clone()).await?; let _ = app.emit( @@ -63,7 +66,7 @@ pub async fn ssh_disconnect(app: tauri::AppHandle, connection_id: String) -> Res #[tauri::command] pub async fn ssh_disconnect_only( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, ) -> Result<(), String> { remote_ssh_disconnect_only(connection_id.clone()).await?; @@ -150,7 +153,7 @@ pub async fn ssh_copy_path( #[tauri::command] #[allow(clippy::too_many_arguments)] pub async fn create_remote_terminal( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, host: String, port: u16, username: String, diff --git a/src-tauri/src/commands/project/remote_credentials.rs b/src-tauri/src/commands/project/remote_credentials.rs index 7c37aa483..6be356226 100644 --- a/src-tauri/src/commands/project/remote_credentials.rs +++ b/src-tauri/src/commands/project/remote_credentials.rs @@ -9,7 +9,7 @@ fn remote_credential_key(connection_id: &str) -> String { #[command] pub async fn store_remote_credential( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, password: String, ) -> Result<(), String> { @@ -18,7 +18,7 @@ pub async fn store_remote_credential( #[command] pub async fn get_remote_credential( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, ) -> Result, String> { secure_storage::get_secret(&app, &remote_credential_key(&connection_id)) @@ -26,7 +26,7 @@ pub async fn get_remote_credential( #[command] pub async fn remove_remote_credential( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, connection_id: String, ) -> Result<(), String> { secure_storage::remove_secret(&app, &remote_credential_key(&connection_id)) diff --git a/src-tauri/src/commands/version_control/github.rs b/src-tauri/src/commands/version_control/github.rs index 73298f386..98a07bdf7 100644 --- a/src-tauri/src/commands/version_control/github.rs +++ b/src-tauri/src/commands/version_control/github.rs @@ -14,7 +14,7 @@ where .map_err(|error| format!("GitHub command task failed: {}", error))? } -fn get_stored_github_token(app: &tauri::AppHandle) -> Option { +fn get_stored_github_token(app: &crate::app_runtime::AppHandle) -> Option { get_secret(app, "github_token") .ok() .flatten() @@ -24,7 +24,7 @@ fn get_stored_github_token(app: &tauri::AppHandle) -> Option { #[tauri::command] pub async fn github_check_auth( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, ) -> Result { let github_token = get_stored_github_token(&app); run_blocking(move || athas_github::github_check_auth(github_token)).await @@ -32,7 +32,7 @@ pub async fn github_check_auth( #[tauri::command] pub async fn github_list_prs( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, filter: String, ) -> Result, String> { @@ -41,14 +41,14 @@ pub async fn github_list_prs( } #[tauri::command] -pub async fn github_get_current_user(app: tauri::AppHandle) -> Result { +pub async fn github_get_current_user(app: crate::app_runtime::AppHandle) -> Result { let github_token = get_stored_github_token(&app); run_blocking(move || athas_github::github_get_current_user(github_token)).await } #[tauri::command] pub async fn github_list_issues( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, ) -> Result, String> { let github_token = get_stored_github_token(&app); @@ -57,7 +57,7 @@ pub async fn github_list_issues( #[tauri::command] pub async fn github_list_workflow_runs( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, ) -> Result, String> { let github_token = get_stored_github_token(&app); @@ -66,7 +66,7 @@ pub async fn github_list_workflow_runs( #[tauri::command] pub async fn github_checkout_pr( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, pr_number: i64, ) -> Result<(), String> { @@ -76,7 +76,7 @@ pub async fn github_checkout_pr( #[tauri::command] pub async fn github_get_pr_details( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, pr_number: i64, ) -> Result { @@ -87,7 +87,7 @@ pub async fn github_get_pr_details( #[tauri::command] pub async fn github_get_pr_diff( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, pr_number: i64, ) -> Result { @@ -97,7 +97,7 @@ pub async fn github_get_pr_diff( #[tauri::command] pub async fn github_get_pr_files( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, pr_number: i64, ) -> Result, String> { @@ -107,7 +107,7 @@ pub async fn github_get_pr_files( #[tauri::command] pub async fn github_get_pr_comments( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, pr_number: i64, ) -> Result, String> { @@ -118,7 +118,7 @@ pub async fn github_get_pr_comments( #[tauri::command] pub async fn github_get_issue_details( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, issue_number: i64, ) -> Result { @@ -131,7 +131,7 @@ pub async fn github_get_issue_details( #[tauri::command] pub async fn github_get_workflow_run_details( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, run_id: i64, ) -> Result { @@ -144,7 +144,7 @@ pub async fn github_get_workflow_run_details( #[tauri::command] pub async fn github_get_workflow_job_logs( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, repo_path: String, job_id: i64, ) -> Result { @@ -154,16 +154,21 @@ pub async fn github_get_workflow_job_logs( } #[tauri::command] -pub async fn store_github_token(app: tauri::AppHandle, token: String) -> Result<(), String> { +pub async fn store_github_token( + app: crate::app_runtime::AppHandle, + token: String, +) -> Result<(), String> { store_secret(&app, "github_token", &token) } #[tauri::command] -pub async fn get_github_token(app: tauri::AppHandle) -> Result, String> { +pub async fn get_github_token( + app: crate::app_runtime::AppHandle, +) -> Result, String> { get_secret(&app, "github_token") } #[tauri::command] -pub async fn remove_github_token(app: tauri::AppHandle) -> Result<(), String> { +pub async fn remove_github_token(app: crate::app_runtime::AppHandle) -> Result<(), String> { remove_secret(&app, "github_token") } diff --git a/src-tauri/src/menu.rs b/src-tauri/src/menu.rs index 9ba555f08..c83982265 100644 --- a/src-tauri/src/menu.rs +++ b/src-tauri/src/menu.rs @@ -11,7 +11,7 @@ pub struct ThemeData { #[tauri::command] pub async fn rebuild_menu_themes( - app: tauri::AppHandle, + app: crate::app_runtime::AppHandle, themes: Vec, ) -> Result<(), String> { // Only rebuild menu if native menu bar is enabled @@ -27,7 +27,10 @@ pub async fn rebuild_menu_themes( } #[tauri::command] -pub async fn toggle_menu_bar(app: tauri::AppHandle, toggle: Option) -> Result<(), String> { +pub async fn toggle_menu_bar( + app: crate::app_runtime::AppHandle, + toggle: Option, +) -> Result<(), String> { #[cfg(target_os = "windows")] { let _ = toggle; diff --git a/src-tauri/src/secure_storage.rs b/src-tauri/src/secure_storage.rs index eae6fa4de..4ad63da5d 100644 --- a/src-tauri/src/secure_storage.rs +++ b/src-tauri/src/secure_storage.rs @@ -1,4 +1,4 @@ -use tauri::AppHandle; +use crate::app_runtime::AppHandle; use tauri_plugin_store::StoreExt; const SECURE_STORE_FILE: &str = "secure.json"; diff --git a/src-tauri/src/terminal.rs b/src-tauri/src/terminal.rs index 25412c8c1..7ce02f102 100644 --- a/src-tauri/src/terminal.rs +++ b/src-tauri/src/terminal.rs @@ -1,6 +1,7 @@ +use crate::app_runtime::AppHandle; use athas_terminal::{TerminalConfig, TerminalManager, shell::Shell}; use std::sync::Arc; -use tauri::{AppHandle, State}; +use tauri::State; #[tauri::command] pub async fn create_terminal( From bb6de3c9d34ef977c13dab57b9b0e337189916ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 17:24:58 +0300 Subject: [PATCH 06/12] Disable Linux CEF AppImage build --- .github/workflows/linux-cef-build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/linux-cef-build.yml b/.github/workflows/linux-cef-build.yml index 6df9cb741..af062f664 100644 --- a/.github/workflows/linux-cef-build.yml +++ b/.github/workflows/linux-cef-build.yml @@ -114,7 +114,7 @@ jobs: - name: Build Linux CEF bundles run: | cargo tauri build \ - --bundles appimage,deb,rpm \ + --bundles deb,rpm \ --config '{"bundle":{"createUpdaterArtifacts":false}}' \ -- \ --no-default-features \ @@ -125,7 +125,6 @@ jobs: with: name: linux-cef-${{ runner.arch }} path: | - target/release/bundle/**/*.AppImage target/release/bundle/**/*.deb target/release/bundle/**/*.rpm if-no-files-found: error From ca797d828322ec70c3a03c6768a0cbb9c811228e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Thu, 30 Apr 2026 20:25:08 +0300 Subject: [PATCH 07/12] Simplify release packaging --- .github/workflows/linux-cef-build.yml | 18 +- .github/workflows/release-preflight.yml | 2 +- .github/workflows/release.yml | 62 +++---- package.json | 2 +- scripts/release/package-linux-cef-tarball.sh | 182 +++++++++++++++++++ scripts/release/release-assets.mjs | 104 +++-------- src-tauri/tauri.conf.json | 2 +- 7 files changed, 242 insertions(+), 130 deletions(-) create mode 100755 scripts/release/package-linux-cef-tarball.sh diff --git a/.github/workflows/linux-cef-build.yml b/.github/workflows/linux-cef-build.yml index af062f664..2b22b27ff 100644 --- a/.github/workflows/linux-cef-build.yml +++ b/.github/workflows/linux-cef-build.yml @@ -30,11 +30,12 @@ concurrency: jobs: build: if: github.repository == 'athasdev/athas' - name: Build Linux CEF bundles + name: Build Linux CEF tarball runs-on: ${{ inputs.runner || 'ubuntu-22.04' }} timeout-minutes: 120 env: CARGO_TERM_COLOR: always + CEF_PATH: ${{ github.workspace }}/.cache/tauri-cef NO_STRIP: "true" steps: - uses: actions/checkout@v6 @@ -72,7 +73,7 @@ jobs: - name: Cache CEF binaries uses: actions/cache@v4 with: - path: ~/.local/share/cef + path: .cache/tauri-cef key: ${{ runner.os }}-${{ runner.arch }}-cef-v146.4.1 - name: Cache Bun dependencies @@ -111,20 +112,21 @@ jobs: exit 1 fi - - name: Build Linux CEF bundles + - name: Build Linux CEF app run: | cargo tauri build \ - --bundles deb,rpm \ + --no-bundle \ --config '{"bundle":{"createUpdaterArtifacts":false}}' \ -- \ --no-default-features \ --features linux-cef - - name: Upload Linux CEF bundles + - name: Package Linux CEF tarball + run: bash scripts/release/package-linux-cef-tarball.sh "${{ runner.arch }}" release-dist + + - name: Upload Linux CEF tarball uses: actions/upload-artifact@v4 with: name: linux-cef-${{ runner.arch }} - path: | - target/release/bundle/**/*.deb - target/release/bundle/**/*.rpm + path: release-dist/*.tar.gz if-no-files-found: error diff --git a/.github/workflows/release-preflight.yml b/.github/workflows/release-preflight.yml index 13c482b02..87a7beecd 100644 --- a/.github/workflows/release-preflight.yml +++ b/.github/workflows/release-preflight.yml @@ -44,7 +44,7 @@ jobs: bun -e ' const config = JSON.parse(await Bun.file("src-tauri/tauri.conf.json").text()); const targets = config.bundle?.targets ?? []; - const expected = ["app", "appimage", "deb", "dmg", "nsis", "rpm"]; + const expected = ["app", "dmg", "nsis"]; if (JSON.stringify(targets) !== JSON.stringify(expected)) { throw new Error(`Unexpected bundle targets: ${JSON.stringify(targets)}`); } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4bdb4b0ae..f20ad2bde 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -184,7 +184,7 @@ jobs: if: matrix.os == 'linux' uses: actions/cache@v4 with: - path: ~/.local/share/cef + path: .cache/tauri-cef key: ${{ runner.os }}-${{ runner.arch }}-cef-v146.4.1 - name: Cache Bun dependencies @@ -328,15 +328,35 @@ jobs: APPLE_ID: ${{ matrix.os == 'macos' && secrets.APPLE_ID || '' }} APPLE_PASSWORD: ${{ matrix.os == 'macos' && secrets.APPLE_PASSWORD || '' }} APPLE_TEAM_ID: ${{ matrix.os == 'macos' && secrets.APPLE_TEAM_ID || '' }} + CEF_PATH: ${{ matrix.os == 'linux' && format('{0}/.cache/tauri-cef', github.workspace) || '' }} NO_STRIP: ${{ matrix.os == 'linux' && 'true' || '' }} RUSTFLAGS: ${{ matrix.rustflags }} run: | if [[ "${{ matrix.os }}" == "linux" ]]; then - cargo tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} -- ${{ matrix.cargo_features }} + cargo tauri build --no-bundle ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} -- ${{ matrix.cargo_features }} else bun tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} fi + - name: Package Linux CEF tarball (Linux only) + if: matrix.os == 'linux' + env: + ATHAS_RELEASE_CHANNEL: ${{ needs.release-metadata.outputs.is_prerelease == 'true' && 'preview' || 'stable' }} + CEF_PATH: ${{ github.workspace }}/.cache/tauri-cef + run: bash scripts/release/package-linux-cef-tarball.sh "${{ runner.arch }}" release-dist + + - name: Sign Linux CEF tarball (Linux only) + if: matrix.os == 'linux' + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + run: | + set -euo pipefail + for archive in release-dist/*.tar.gz; do + bun tauri signer sign "$archive" + test -s "${archive}.sig" + done + - name: Collect Windows user installer (Windows only) if: matrix.os == 'windows' shell: pwsh @@ -355,41 +375,6 @@ jobs: throw "Could not find updater signature for $($setup.Name)." } - - name: Build Windows machine installer (Windows only) - if: matrix.os == 'windows' - shell: pwsh - env: - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - run: | - $configArgs = @() - if ("${{ needs.release-metadata.outputs.is_prerelease }}" -eq "true") { - $configArgs += @("--config", "src-tauri/tauri.preview.conf.json") - } - $configArgs += @( - "--config", - '{"bundle":{"createUpdaterArtifacts":true,"windows":{"nsis":{"installMode":"perMachine"}}}}' - ) - - bun tauri bundle ${{ matrix.args }} --bundles nsis @configArgs - - $setup = Get-ChildItem -Recurse -Path "${{ matrix.bundle_path }}" -File -Filter "*-setup.exe" | - Sort-Object LastWriteTime -Descending | - Select-Object -First 1 - if (-not $setup) { - throw "Could not find machine installer." - } - - $dest = Join-Path "release-dist" ($setup.Name -replace '-setup\.exe$', '-setup-machine.exe') - $destSig = "$dest.sig" - Copy-Item $setup.FullName $dest - if (Test-Path "$($setup.FullName).sig") { - Copy-Item "$($setup.FullName).sig" $destSig - Remove-Item "$($setup.FullName).sig" -Force - } else { - throw "Could not find updater signature for $($setup.Name)." - } - - name: Upload platform artifacts uses: actions/upload-artifact@v4 with: @@ -397,9 +382,6 @@ jobs: path: | ${{ matrix.bundle_path }}/**/*.dmg ${{ matrix.bundle_path }}/**/*.app.tar.gz - ${{ matrix.bundle_path }}/**/*.AppImage - ${{ matrix.bundle_path }}/**/*.deb - ${{ matrix.bundle_path }}/**/*.rpm ${{ matrix.bundle_path }}/**/*.sig release-dist/* if-no-files-found: error diff --git a/package.json b/package.json index 17afb12b2..1bf0f1fc2 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "dev:stable": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev", "dev:preview": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.preview.conf.json", "build:stable": "bun scripts/check-zig.ts && tauri build", - "build:linux-cef": "bun scripts/check-zig.ts && cargo tauri build -- --no-default-features --features linux-cef", + "build:linux-cef": "bun scripts/check-zig.ts && cargo tauri build --no-bundle -- --no-default-features --features linux-cef && bash scripts/release/package-linux-cef-tarball.sh $(uname -m) release-dist", "build:preview": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.preview.conf.json", "build:dev": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.dev.conf.json", "smoke": "bun scripts/smoke-app.ts", diff --git a/scripts/release/package-linux-cef-tarball.sh b/scripts/release/package-linux-cef-tarball.sh new file mode 100755 index 000000000..99074233e --- /dev/null +++ b/scripts/release/package-linux-cef-tarball.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash +set -euo pipefail + +arch_input="${1:?Usage: package-linux-cef-tarball.sh [out-dir]}" +out_dir="${2:-release-dist}" +channel="${ATHAS_RELEASE_CHANNEL:-stable}" + +case "$arch_input" in + X64 | x64 | amd64 | x86_64) + arch="x86_64" + ;; + ARM64 | arm64 | aarch64) + arch="aarch64" + ;; + *) + echo "Unsupported Linux architecture: $arch_input" >&2 + exit 1 + ;; +esac + +if [[ "$channel" == "preview" ]]; then + product_name="Athas Preview" + app_dir_name="athas-preview.app" + icon_dir="preview" + desktop_id="com.code.athas.preview" +else + product_name="Athas" + app_dir_name="athas.app" + icon_dir="prod" + desktop_id="com.code.athas" +fi + +version="$(bun -e 'console.log(JSON.parse(await Bun.file("package.json").text()).version)')" +binary="target/release/athas" + +if [[ ! -x "$binary" ]]; then + echo "Missing release binary at $binary" >&2 + exit 1 +fi + +find_cef_dir() { + local roots=() + + if [[ -n "${CEF_PATH:-}" ]]; then + roots+=("$CEF_PATH") + fi + + roots+=( + ".cache/tauri-cef" + "${HOME}/.cache/tauri-cef" + "${HOME}/.local/share/cef" + "target/release/build" + "target/debug/build" + ) + + for root in "${roots[@]}"; do + if [[ -f "${root}/libcef.so" ]]; then + dirname "${root}/libcef.so" + return 0 + fi + + if [[ -d "$root" ]]; then + local found + found="$(find "$root" -maxdepth 5 -type f -name libcef.so -print -quit)" + if [[ -n "$found" ]]; then + dirname "$found" + return 0 + fi + fi + done + + return 1 +} + +cef_dir="$(find_cef_dir)" || { + echo "Could not find a CEF distribution containing libcef.so." >&2 + echo "Set CEF_PATH or run the Linux CEF build first." >&2 + exit 1 +} + +if command -v readelf >/dev/null 2>&1; then + if ! readelf -d "$binary" | grep -q '\$ORIGIN'; then + echo "Release binary does not include an \$ORIGIN RUNPATH for bundled CEF." >&2 + exit 1 + fi +fi + +staging="$(mktemp -d)" +trap 'rm -rf "$staging"' EXIT + +app_root="${staging}/${app_dir_name}" +bin_dir="${app_root}/bin" +libexec_dir="${app_root}/libexec" +resource_dir="${app_root}/lib/${product_name}" +desktop_dir="${app_root}/share/applications" +icon_base_dir="${app_root}/share/icons/hicolor" + +install -d "$bin_dir" "$libexec_dir" "$resource_dir" "$desktop_dir" +install -m 755 "$binary" "${libexec_dir}/athas" +ln -s ../libexec/athas "${bin_dir}/athas" + +cp -R src/extensions/bundled "${resource_dir}/bundled" + +cef_files=( + libcef.so + icudtl.dat + v8_context_snapshot.bin + chrome_100_percent.pak + chrome_200_percent.pak + resources.pak + libEGL.so + libGLESv2.so + libvk_swiftshader.so + vk_swiftshader_icd.json + libvulkan.so.1 + chrome-sandbox +) + +for file in "${cef_files[@]}"; do + if [[ ! -f "${cef_dir}/${file}" ]]; then + echo "CEF file is missing: ${cef_dir}/${file}" >&2 + exit 1 + fi + install -m 755 "${cef_dir}/${file}" "${libexec_dir}/${file}" +done + +if [[ ! -d "${cef_dir}/locales" ]]; then + echo "CEF locales directory is missing: ${cef_dir}/locales" >&2 + exit 1 +fi +install -d "${libexec_dir}/locales" +cp "${cef_dir}/locales/"*.pak "${libexec_dir}/locales/" + +if command -v strip >/dev/null 2>&1; then + find "$libexec_dir" -maxdepth 1 -type f \( -name '*.so' -o -name '*.so.*' \) -exec strip --strip-unneeded {} + +fi + +for size in 32 128; do + icon_src="src-tauri/icons/${icon_dir}/${size}x${size}.png" + if [[ -f "$icon_src" ]]; then + install -D -m 644 "$icon_src" "${icon_base_dir}/${size}x${size}/apps/athas.png" + fi +done + +if [[ -f "src-tauri/icons/${icon_dir}/128x128@2x.png" ]]; then + install -D -m 644 \ + "src-tauri/icons/${icon_dir}/128x128@2x.png" \ + "${icon_base_dir}/256x256@2/apps/athas.png" +fi + +cat > "${desktop_dir}/${desktop_id}.desktop" <&2 + exit 1 + fi +done + +echo "Created ${archive_path}" diff --git a/scripts/release/release-assets.mjs b/scripts/release/release-assets.mjs index f454c3a92..e44f6f7ee 100755 --- a/scripts/release/release-assets.mjs +++ b/scripts/release/release-assets.mjs @@ -131,38 +131,14 @@ function requiredAssets(version, channel) { checksum: true, }, { - id: "linux-x64-appimage", - pattern: new RegExp(`^${appPrefix}_${escapedVersion}_amd64\\.AppImage$`), + id: "linux-x64-tarball", + pattern: new RegExp(`^${appPrefix}_${escapedVersion}_linux-x86_64\\.tar\\.gz$`), signature: true, checksum: true, }, { - id: "linux-arm64-appimage", - pattern: new RegExp(`^${appPrefix}_${escapedVersion}_aarch64\\.AppImage$`), - signature: true, - checksum: true, - }, - { - id: "linux-x64-deb", - pattern: new RegExp(`^${appPrefix}_${escapedVersion}_amd64\\.deb$`), - signature: true, - checksum: true, - }, - { - id: "linux-arm64-deb", - pattern: new RegExp(`^${appPrefix}_${escapedVersion}_arm64\\.deb$`), - signature: true, - checksum: true, - }, - { - id: "linux-x64-rpm", - pattern: new RegExp(`^${appPrefix}-${escapedVersion}-1\\.x86_64\\.rpm$`), - signature: true, - checksum: true, - }, - { - id: "linux-arm64-rpm", - pattern: new RegExp(`^${appPrefix}-${escapedVersion}-1\\.aarch64\\.rpm$`), + id: "linux-arm64-tarball", + pattern: new RegExp(`^${appPrefix}_${escapedVersion}_linux-aarch64\\.tar\\.gz$`), signature: true, checksum: true, }, @@ -178,25 +154,19 @@ function requiredAssets(version, channel) { signature: true, checksum: true, }, - { - id: "windows-x64-machine-nsis", - pattern: new RegExp(`^${appPrefix}_${escapedVersion}_x64-setup-machine\\.exe$`), - signature: true, - checksum: true, - }, - { - id: "windows-arm64-machine-nsis", - pattern: new RegExp(`^${appPrefix}_${escapedVersion}_arm64-setup-machine\\.exe$`), - signature: true, - checksum: true, - }, ]; } function forbiddenAssetPatterns(version) { const escapedVersion = escapeRegExp(version); const appPrefix = "Athas(?: Preview)?"; - return [new RegExp(`^${appPrefix}_${escapedVersion}_(?:x64|arm64)_en-US\\.msi(?:\\.sig)?$`)]; + return [ + new RegExp(`^${appPrefix}_${escapedVersion}_(?:x64|arm64)_en-US\\.msi(?:\\.sig)?$`), + new RegExp(`^${appPrefix}_${escapedVersion}_(?:amd64|aarch64)\\.AppImage(?:\\.sig)?$`), + new RegExp(`^${appPrefix}_${escapedVersion}_(?:amd64|arm64)\\.deb(?:\\.sig)?$`), + new RegExp(`^${appPrefix}-${escapedVersion}-1\\.(?:x86_64|aarch64)\\.rpm(?:\\.sig)?$`), + new RegExp(`^${appPrefix}_${escapedVersion}_(?:x64|arm64)-setup-machine\\.exe(?:\\.sig)?$`), + ]; } function findRequiredAsset(filesByName, required) { @@ -262,12 +232,8 @@ function buildLatestJson({ tag, repo, notes, assets }) { const version = versionFromTag(tag); const macArm = assetById(assets, "macos-arm64-updater"); const macX64 = assetById(assets, "macos-x64-updater"); - const linuxX64AppImage = assetById(assets, "linux-x64-appimage"); - const linuxArmAppImage = assetById(assets, "linux-arm64-appimage"); - const linuxX64Deb = assetById(assets, "linux-x64-deb"); - const linuxArmDeb = assetById(assets, "linux-arm64-deb"); - const linuxX64Rpm = assetById(assets, "linux-x64-rpm"); - const linuxArmRpm = assetById(assets, "linux-arm64-rpm"); + const linuxX64Tarball = assetById(assets, "linux-x64-tarball"); + const linuxArmTarball = assetById(assets, "linux-arm64-tarball"); const winX64Nsis = assetById(assets, "windows-x64-nsis"); const winArmNsis = assetById(assets, "windows-arm64-nsis"); @@ -293,36 +259,20 @@ function buildLatestJson({ tag, repo, notes, assets }) { url: releaseUrl(repo, tag, macX64.name), }, "linux-aarch64": { - signature: readSignature(linuxArmAppImage.signaturePath), - url: releaseUrl(repo, tag, linuxArmAppImage.name), - }, - "linux-aarch64-appimage": { - signature: readSignature(linuxArmAppImage.signaturePath), - url: releaseUrl(repo, tag, linuxArmAppImage.name), + signature: readSignature(linuxArmTarball.signaturePath), + url: releaseUrl(repo, tag, linuxArmTarball.name), }, - "linux-aarch64-deb": { - signature: readSignature(linuxArmDeb.signaturePath), - url: releaseUrl(repo, tag, linuxArmDeb.name), - }, - "linux-aarch64-rpm": { - signature: readSignature(linuxArmRpm.signaturePath), - url: releaseUrl(repo, tag, linuxArmRpm.name), + "linux-aarch64-tar.gz": { + signature: readSignature(linuxArmTarball.signaturePath), + url: releaseUrl(repo, tag, linuxArmTarball.name), }, "linux-x86_64": { - signature: readSignature(linuxX64AppImage.signaturePath), - url: releaseUrl(repo, tag, linuxX64AppImage.name), - }, - "linux-x86_64-appimage": { - signature: readSignature(linuxX64AppImage.signaturePath), - url: releaseUrl(repo, tag, linuxX64AppImage.name), - }, - "linux-x86_64-deb": { - signature: readSignature(linuxX64Deb.signaturePath), - url: releaseUrl(repo, tag, linuxX64Deb.name), + signature: readSignature(linuxX64Tarball.signaturePath), + url: releaseUrl(repo, tag, linuxX64Tarball.name), }, - "linux-x86_64-rpm": { - signature: readSignature(linuxX64Rpm.signaturePath), - url: releaseUrl(repo, tag, linuxX64Rpm.name), + "linux-x86_64-tar.gz": { + signature: readSignature(linuxX64Tarball.signaturePath), + url: releaseUrl(repo, tag, linuxX64Tarball.name), }, "windows-x86_64": { signature: readSignature(winX64Nsis.signaturePath), @@ -399,13 +349,9 @@ function validateLatestJson(latestJson, { tag, repo, assetNames }) { "darwin-x86_64", "darwin-x86_64-app", "linux-aarch64", - "linux-aarch64-appimage", - "linux-aarch64-deb", - "linux-aarch64-rpm", + "linux-aarch64-tar.gz", "linux-x86_64", - "linux-x86_64-appimage", - "linux-x86_64-deb", - "linux-x86_64-rpm", + "linux-x86_64-tar.gz", "windows-x86_64", "windows-x86_64-nsis", "windows-aarch64", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f98ca9992..4c49a97aa 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -40,7 +40,7 @@ }, "bundle": { "active": true, - "targets": ["app", "appimage", "deb", "dmg", "nsis", "rpm"], + "targets": ["app", "dmg", "nsis"], "createUpdaterArtifacts": true, "icon": [ "icons/prod/32x32.png", From 659020990e0aaf0604158f833e949ca8cf68de17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Fri, 1 May 2026 02:32:28 +0300 Subject: [PATCH 08/12] Add Linux CEF runtime rpath --- src-tauri/build.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 4f29a94d0..1ff4aead6 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -3,5 +3,11 @@ fn main() { println!("cargo:rustc-link-arg-bin=athas=/NODEFAULTLIB:libvcruntime.lib"); } + if std::env::var_os("CARGO_FEATURE_LINUX_CEF").is_some() + && std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") + { + println!("cargo:rustc-link-arg-bin=athas=-Wl,-rpath,$ORIGIN"); + } + tauri_build::build() } From 54844adf35665a73db810b63d9444f7267cbad65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Fri, 1 May 2026 02:36:26 +0300 Subject: [PATCH 09/12] Install Zig in Linux setup --- scripts/setup/linux.sh | 131 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 4 deletions(-) diff --git a/scripts/setup/linux.sh b/scripts/setup/linux.sh index 9df25e43e..b0a7ff008 100755 --- a/scripts/setup/linux.sh +++ b/scripts/setup/linux.sh @@ -9,6 +9,7 @@ GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' +REQUIRED_ZIG_VERSION="0.16.0" print_status() { echo -e "${BLUE}[INFO]${NC} $1"; } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } @@ -57,28 +58,47 @@ command_exists() { command -v "$1" &> /dev/null } +version_at_least() { + local current="$1" + local minimum="$2" + + if [[ -z "$current" ]]; then + return 1 + fi + + [[ "$(printf '%s\n%s\n' "$minimum" "$current" | sort -V | head -n1)" == "$minimum" ]] +} + +get_zig_version() { + if ! command_exists zig; then + return 1 + fi + + zig version 2>/dev/null | grep -Eo '[0-9]+(\.[0-9]+){1,3}' | head -n1 +} + install_system_deps() { print_status "Installing system dependencies for $DISTRO..." case $DISTRO in "ubuntu") sudo apt-get update - sudo apt-get install -y build-essential curl wget file libssl-dev libgtk-3-dev libwebkit2gtk-4.1-dev libsoup-3.0-dev libayatana-appindicator3-dev librsvg2-dev pkg-config + sudo apt-get install -y build-essential curl wget file xz-utils libssl-dev libgtk-3-dev libwebkit2gtk-4.1-dev libsoup-3.0-dev libayatana-appindicator3-dev librsvg2-dev pkg-config # Deps for git2 and ssh2 sudo apt-get install -y libssl-dev pkgconf perl ;; "fedora") - sudo dnf install -y gcc gcc-c++ make curl wget file openssl-devel gtk3-devel webkit2gtk4.1-devel libsoup3-devel libayatana-appindicator-gtk3-devel librsvg2-devel pkgconf-pkg-config + sudo dnf install -y gcc gcc-c++ make curl wget file xz openssl-devel gtk3-devel webkit2gtk4.1-devel libsoup3-devel libayatana-appindicator-gtk3-devel librsvg2-devel pkgconf-pkg-config # Deps for git2 and ssh2 sudo dnf install -y openssl-devel pkgconf perl-FindBin perl-IPC-Cmd perl ;; "arch") - sudo pacman -S --needed --noconfirm base-devel curl wget file openssl gtk3 webkit2gtk-4.1 libsoup3 libayatana-appindicator librsvg pkgconf + sudo pacman -S --needed --noconfirm base-devel curl wget file xz openssl gtk3 webkit2gtk-4.1 libsoup3 libayatana-appindicator librsvg pkgconf # Deps for git2 and ssh2 sudo pacman -S --needed --noconfirm openssl pkgconf perl ;; "opensuse") - sudo zypper install -y gcc gcc-c++ make curl wget file libopenssl-devel gtk3-devel webkit2gtk3-devel libsoup3-devel libayatana-appindicator3-devel librsvg-devel pkg-config + sudo zypper install -y gcc gcc-c++ make curl wget file xz libopenssl-devel gtk3-devel webkit2gtk3-devel libsoup3-devel libayatana-appindicator3-devel librsvg-devel pkg-config # Deps for git2 and ssh2 sudo zypper install -y openssl-devel pkgconf perl-FindBin perl-IPC-Cmd perl ;; @@ -96,6 +116,99 @@ install_system_deps() { print_success "System dependencies installed successfully" } +install_zig_with_package_manager() { + case $DISTRO in + "ubuntu") + sudo apt-get install -y zig + ;; + "fedora") + sudo dnf install -y zig + ;; + "arch") + sudo pacman -S --needed --noconfirm zig + ;; + "opensuse") + sudo zypper install -y zig + ;; + *) + return 1 + ;; + esac +} + +install_zig_from_archive() { + local machine + local zig_target + local install_root + local install_dir + local archive_dir + local archive_url + local temp_dir + + machine="$(uname -m)" + case "$machine" in + "x86_64") + zig_target="x86_64-linux" + ;; + "aarch64"|"arm64") + zig_target="aarch64-linux" + ;; + *) + print_error "Unsupported architecture for Zig install: $machine" + return 1 + ;; + esac + + install_root="$HOME/.local/share/athas-dev/zig" + install_dir="$install_root/$REQUIRED_ZIG_VERSION" + archive_dir="zig-$zig_target-$REQUIRED_ZIG_VERSION" + archive_url="https://ziglang.org/download/$REQUIRED_ZIG_VERSION/$archive_dir.tar.xz" + temp_dir="$(mktemp -d)" + + print_status "Downloading Zig $REQUIRED_ZIG_VERSION from ziglang.org..." + curl -fL "$archive_url" -o "$temp_dir/zig.tar.xz" + + rm -rf "$install_dir" + mkdir -p "$install_root" "$HOME/.local/bin" + tar -xJf "$temp_dir/zig.tar.xz" -C "$install_root" + mv "$install_root/$archive_dir" "$install_dir" + ln -sfn "$install_dir/zig" "$HOME/.local/bin/zig" + export PATH="$HOME/.local/bin:$PATH" + rm -rf "$temp_dir" +} + +install_zig() { + local zig_version + + zig_version="$(get_zig_version || true)" + if version_at_least "$zig_version" "$REQUIRED_ZIG_VERSION"; then + print_success "Zig is already installed (v$zig_version)" + return + fi + + print_status "Installing Zig $REQUIRED_ZIG_VERSION+..." + if ! install_zig_with_package_manager; then + print_warning "Could not install Zig with the system package manager." + fi + + zig_version="$(get_zig_version || true)" + if version_at_least "$zig_version" "$REQUIRED_ZIG_VERSION"; then + print_success "Zig is ready (v$zig_version)" + return + fi + + print_warning "System package manager did not provide Zig $REQUIRED_ZIG_VERSION+." + install_zig_from_archive + + zig_version="$(get_zig_version || true)" + if ! version_at_least "$zig_version" "$REQUIRED_ZIG_VERSION"; then + print_error "Zig $REQUIRED_ZIG_VERSION+ is required, but setup could not verify the installed version." + exit 1 + fi + + print_success "Zig is ready (v$zig_version)" +} + install_rust() { if command_exists rustc && command_exists cargo; then print_success "Rust is already installed ($(rustc --version))" @@ -161,6 +274,15 @@ verify_basic() { print_warning "Tauri CLI not found, but may work after restart" fi + local zig_version + zig_version="$(get_zig_version || true)" + if version_at_least "$zig_version" "$REQUIRED_ZIG_VERSION"; then + print_success "Zig found (v$zig_version)" + else + print_error "Zig $REQUIRED_ZIG_VERSION+ missing" + return 1 + fi + return 0 } @@ -178,6 +300,7 @@ main() { print_status "Detected libc: $LIBC" install_system_deps + install_zig install_rust install_tauri_cli install_bun From b4a892b05a02a06f2316c4c848ea012675d14268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Fri, 1 May 2026 03:09:13 +0300 Subject: [PATCH 10/12] Fix Linux CEF tarball verification --- scripts/release/package-linux-cef-tarball.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/release/package-linux-cef-tarball.sh b/scripts/release/package-linux-cef-tarball.sh index 99074233e..e1a9c7b2d 100755 --- a/scripts/release/package-linux-cef-tarball.sh +++ b/scripts/release/package-linux-cef-tarball.sh @@ -165,6 +165,9 @@ archive_name="${product_name}_${version}_linux-${arch}.tar.gz" archive_path="${out_dir}/${archive_name}" tar -C "$staging" -czf "$archive_path" "$app_dir_name" +archive_contents="${staging}/archive-contents.txt" +tar -tzf "$archive_path" > "$archive_contents" + for required in \ "${app_dir_name}/libexec/athas" \ "${app_dir_name}/libexec/libcef.so" \ @@ -172,8 +175,8 @@ for required in \ "${app_dir_name}/libexec/locales/en-US.pak" \ "${app_dir_name}/lib/${product_name}/bundled" do - if ! tar -tzf "$archive_path" | grep -Fxq "$required" \ - && ! tar -tzf "$archive_path" | grep -Fxq "${required}/"; then + if ! grep -Fxq "$required" "$archive_contents" \ + && ! grep -Fxq "${required}/" "$archive_contents"; then echo "Linux CEF tarball is missing ${required}" >&2 exit 1 fi From 453a322b4ebe6932950b1164e2ae15a81762be4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Fri, 1 May 2026 15:15:42 +0300 Subject: [PATCH 11/12] Rename CEF feature flag --- .../{linux-cef-build.yml => linux-build.yml} | 31 ++++++++++--------- .github/workflows/release.yml | 10 +++--- crates/ai/Cargo.toml | 2 +- crates/ai/src/runtime.rs | 4 +-- crates/debugger/Cargo.toml | 2 +- crates/extensions/Cargo.toml | 2 +- crates/extensions/src/runtime.rs | 4 +-- crates/lsp/Cargo.toml | 2 +- crates/lsp/src/runtime.rs | 4 +-- crates/remote/Cargo.toml | 2 +- crates/remote/src/runtime.rs | 4 +-- crates/terminal/Cargo.toml | 2 +- crates/terminal/src/runtime.rs | 4 +-- crates/tooling/Cargo.toml | 2 +- crates/tooling/src/runtime.rs | 4 +-- package.json | 3 +- ...ef-tarball.sh => package-linux-tarball.sh} | 6 ++-- src-tauri/Cargo.toml | 16 +++++----- src-tauri/build.rs | 2 +- src-tauri/src/app_runtime.rs | 4 +-- src-tauri/src/main.rs | 7 ++--- 21 files changed, 58 insertions(+), 59 deletions(-) rename .github/workflows/{linux-cef-build.yml => linux-build.yml} (79%) rename scripts/release/{package-linux-cef-tarball.sh => package-linux-tarball.sh} (95%) diff --git a/.github/workflows/linux-cef-build.yml b/.github/workflows/linux-build.yml similarity index 79% rename from .github/workflows/linux-cef-build.yml rename to .github/workflows/linux-build.yml index 2b22b27ff..a39b3c0da 100644 --- a/.github/workflows/linux-cef-build.yml +++ b/.github/workflows/linux-build.yml @@ -1,10 +1,10 @@ -name: "Linux CEF Build" +name: "Linux Build" on: pull_request: branches: [master] paths: - - ".github/workflows/linux-cef-build.yml" + - ".github/workflows/linux-build.yml" - ".github/workflows/release.yml" - "Cargo.lock" - "Cargo.toml" @@ -12,6 +12,7 @@ on: - "src-tauri/**" - "package.json" - "bun.lock" + - "scripts/release/package-linux-tarball.sh" workflow_dispatch: inputs: runner: @@ -30,7 +31,7 @@ concurrency: jobs: build: if: github.repository == 'athasdev/athas' - name: Build Linux CEF tarball + name: Build Linux tarball runs-on: ${{ inputs.runner || 'ubuntu-22.04' }} timeout-minutes: 120 env: @@ -95,38 +96,38 @@ jobs: - name: Install frontend dependencies run: bun install --ignore-scripts && bun scripts/postinstall.ts - - name: Check Linux CEF feature graph + - name: Check Linux feature graph run: | set -euo pipefail - cargo tree -p athas --no-default-features --features linux-cef -i tauri-runtime-cef - cargo tree -p athas --no-default-features --features linux-cef -i tauri-runtime-wry >/tmp/tauri-runtime-wry.txt 2>&1 || true + cargo tree -p athas --no-default-features --features cef -i tauri-runtime-cef + cargo tree -p athas --no-default-features --features cef -i tauri-runtime-wry >/tmp/tauri-runtime-wry.txt 2>&1 || true if grep -q '^tauri-runtime-wry ' /tmp/tauri-runtime-wry.txt; then - echo "tauri-runtime-wry must not be present in the Linux CEF build" + echo "tauri-runtime-wry must not be present in the Linux build" cat /tmp/tauri-runtime-wry.txt exit 1 fi - cargo tree -p athas --no-default-features --features linux-cef -i webkit2gtk >/tmp/webkit2gtk.txt 2>&1 || true + cargo tree -p athas --no-default-features --features cef -i webkit2gtk >/tmp/webkit2gtk.txt 2>&1 || true if grep -q '^webkit2gtk ' /tmp/webkit2gtk.txt; then - echo "webkit2gtk must not be present in the Linux CEF build" + echo "webkit2gtk must not be present in the Linux build" cat /tmp/webkit2gtk.txt exit 1 fi - - name: Build Linux CEF app + - name: Build Linux app run: | cargo tauri build \ --no-bundle \ --config '{"bundle":{"createUpdaterArtifacts":false}}' \ -- \ --no-default-features \ - --features linux-cef + --features cef - - name: Package Linux CEF tarball - run: bash scripts/release/package-linux-cef-tarball.sh "${{ runner.arch }}" release-dist + - name: Package Linux tarball + run: bash scripts/release/package-linux-tarball.sh "${{ runner.arch }}" release-dist - - name: Upload Linux CEF tarball + - name: Upload Linux tarball uses: actions/upload-artifact@v4 with: - name: linux-cef-${{ runner.arch }} + name: linux-${{ runner.arch }} path: release-dist/*.tar.gz if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f20ad2bde..4e91bb4b1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -105,7 +105,7 @@ jobs: artifact: "linux-x86_64" os: "linux" args: "" - cargo_features: "--no-default-features --features linux-cef" + cargo_features: "--no-default-features --features cef" target: "" bundle_path: "target/release/bundle" timeout_minutes: 120 @@ -114,7 +114,7 @@ jobs: artifact: "linux-aarch64" os: "linux" args: "" - cargo_features: "--no-default-features --features linux-cef" + cargo_features: "--no-default-features --features cef" target: "" bundle_path: "target/release/bundle" timeout_minutes: 120 @@ -338,14 +338,14 @@ jobs: bun tauri build ${{ matrix.args }} ${{ needs.release-metadata.outputs.is_prerelease == 'true' && '--config src-tauri/tauri.preview.conf.json' || '' }} fi - - name: Package Linux CEF tarball (Linux only) + - name: Package Linux tarball (Linux only) if: matrix.os == 'linux' env: ATHAS_RELEASE_CHANNEL: ${{ needs.release-metadata.outputs.is_prerelease == 'true' && 'preview' || 'stable' }} CEF_PATH: ${{ github.workspace }}/.cache/tauri-cef - run: bash scripts/release/package-linux-cef-tarball.sh "${{ runner.arch }}" release-dist + run: bash scripts/release/package-linux-tarball.sh "${{ runner.arch }}" release-dist - - name: Sign Linux CEF tarball (Linux only) + - name: Sign Linux tarball (Linux only) if: matrix.os == 'linux' env: TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} diff --git a/crates/ai/Cargo.toml b/crates/ai/Cargo.toml index 25856cebb..10bad53bd 100644 --- a/crates/ai/Cargo.toml +++ b/crates/ai/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["athas-terminal/tauri-wry", "tauri/wry", "tauri/x11"] -linux-cef = ["athas-terminal/linux-cef", "tauri/cef"] +cef = ["athas-terminal/cef", "tauri/cef"] [dependencies] agent-client-protocol = { version = "0.9", features = [ diff --git a/crates/ai/src/runtime.rs b/crates/ai/src/runtime.rs index 8518ee768..6ba3dca0a 100644 --- a/crates/ai/src/runtime.rs +++ b/crates/ai/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "linux-cef")] +#[cfg(feature = "cef")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "linux-cef"))] +#[cfg(not(feature = "cef"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/debugger/Cargo.toml b/crates/debugger/Cargo.toml index 45f9821f4..94fb7c476 100644 --- a/crates/debugger/Cargo.toml +++ b/crates/debugger/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -linux-cef = ["tauri/cef"] +cef = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/extensions/Cargo.toml b/crates/extensions/Cargo.toml index 9a3370e69..a9cb28efd 100644 --- a/crates/extensions/Cargo.toml +++ b/crates/extensions/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -linux-cef = ["tauri/cef"] +cef = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/extensions/src/runtime.rs b/crates/extensions/src/runtime.rs index 8518ee768..6ba3dca0a 100644 --- a/crates/extensions/src/runtime.rs +++ b/crates/extensions/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "linux-cef")] +#[cfg(feature = "cef")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "linux-cef"))] +#[cfg(not(feature = "cef"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/lsp/Cargo.toml b/crates/lsp/Cargo.toml index 6af52bd46..09c929f7b 100644 --- a/crates/lsp/Cargo.toml +++ b/crates/lsp/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -linux-cef = ["tauri/cef"] +cef = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/lsp/src/runtime.rs b/crates/lsp/src/runtime.rs index 8518ee768..6ba3dca0a 100644 --- a/crates/lsp/src/runtime.rs +++ b/crates/lsp/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "linux-cef")] +#[cfg(feature = "cef")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "linux-cef"))] +#[cfg(not(feature = "cef"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/remote/Cargo.toml b/crates/remote/Cargo.toml index 8e8e74406..89a606ef7 100644 --- a/crates/remote/Cargo.toml +++ b/crates/remote/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -linux-cef = ["tauri/cef"] +cef = ["tauri/cef"] [dependencies] lazy_static = "1.4" diff --git a/crates/remote/src/runtime.rs b/crates/remote/src/runtime.rs index 8518ee768..6ba3dca0a 100644 --- a/crates/remote/src/runtime.rs +++ b/crates/remote/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "linux-cef")] +#[cfg(feature = "cef")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "linux-cef"))] +#[cfg(not(feature = "cef"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/terminal/Cargo.toml b/crates/terminal/Cargo.toml index 15a119949..dbbff9e4b 100644 --- a/crates/terminal/Cargo.toml +++ b/crates/terminal/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -linux-cef = ["tauri/cef"] +cef = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/terminal/src/runtime.rs b/crates/terminal/src/runtime.rs index 8518ee768..6ba3dca0a 100644 --- a/crates/terminal/src/runtime.rs +++ b/crates/terminal/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "linux-cef")] +#[cfg(feature = "cef")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "linux-cef"))] +#[cfg(not(feature = "cef"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/tooling/Cargo.toml b/crates/tooling/Cargo.toml index 6f05c7146..4f5b10cb4 100644 --- a/crates/tooling/Cargo.toml +++ b/crates/tooling/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -linux-cef = ["tauri/cef"] +cef = ["tauri/cef"] [dependencies] athas-runtime = { path = "../runtime" } diff --git a/crates/tooling/src/runtime.rs b/crates/tooling/src/runtime.rs index 8518ee768..6ba3dca0a 100644 --- a/crates/tooling/src/runtime.rs +++ b/crates/tooling/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "linux-cef")] +#[cfg(feature = "cef")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "linux-cef"))] +#[cfg(not(feature = "cef"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/package.json b/package.json index 1bf0f1fc2..cfc943672 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,9 @@ "dev": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.dev.conf.json", "dev:stable": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev", "dev:preview": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.preview.conf.json", + "dev:cef": "bun scripts/check-zig.ts && cargo tauri dev --config src-tauri/tauri.dev.conf.json -- --no-default-features --features cef", "build:stable": "bun scripts/check-zig.ts && tauri build", - "build:linux-cef": "bun scripts/check-zig.ts && cargo tauri build --no-bundle -- --no-default-features --features linux-cef && bash scripts/release/package-linux-cef-tarball.sh $(uname -m) release-dist", + "build:linux": "bun scripts/check-zig.ts && cargo tauri build --no-bundle -- --no-default-features --features cef && bash scripts/release/package-linux-tarball.sh $(uname -m) release-dist", "build:preview": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.preview.conf.json", "build:dev": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.dev.conf.json", "smoke": "bun scripts/smoke-app.ts", diff --git a/scripts/release/package-linux-cef-tarball.sh b/scripts/release/package-linux-tarball.sh similarity index 95% rename from scripts/release/package-linux-cef-tarball.sh rename to scripts/release/package-linux-tarball.sh index e1a9c7b2d..243a5ee19 100755 --- a/scripts/release/package-linux-cef-tarball.sh +++ b/scripts/release/package-linux-tarball.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -arch_input="${1:?Usage: package-linux-cef-tarball.sh [out-dir]}" +arch_input="${1:?Usage: package-linux-tarball.sh [out-dir]}" out_dir="${2:-release-dist}" channel="${ATHAS_RELEASE_CHANNEL:-stable}" @@ -74,7 +74,7 @@ find_cef_dir() { cef_dir="$(find_cef_dir)" || { echo "Could not find a CEF distribution containing libcef.so." >&2 - echo "Set CEF_PATH or run the Linux CEF build first." >&2 + echo "Set CEF_PATH or run the Linux build first." >&2 exit 1 } @@ -177,7 +177,7 @@ for required in \ do if ! grep -Fxq "$required" "$archive_contents" \ && ! grep -Fxq "${required}/" "$archive_contents"; then - echo "Linux CEF tarball is missing ${required}" >&2 + echo "Linux tarball is missing ${required}" >&2 exit 1 fi done diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index d4389075c..3e25c3a7c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -18,14 +18,14 @@ tauri-wry = [ "tauri/wry", "tauri/x11", ] -linux-cef = [ - "athas-ai/linux-cef", - "athas-debugger/linux-cef", - "athas-extensions/linux-cef", - "athas-lsp/linux-cef", - "athas-remote/linux-cef", - "athas-terminal/linux-cef", - "athas-tooling/linux-cef", +cef = [ + "athas-ai/cef", + "athas-debugger/cef", + "athas-extensions/cef", + "athas-lsp/cef", + "athas-remote/cef", + "athas-terminal/cef", + "athas-tooling/cef", "tauri/cef", ] diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 1ff4aead6..32b9cb2ce 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -3,7 +3,7 @@ fn main() { println!("cargo:rustc-link-arg-bin=athas=/NODEFAULTLIB:libvcruntime.lib"); } - if std::env::var_os("CARGO_FEATURE_LINUX_CEF").is_some() + if std::env::var_os("CARGO_FEATURE_CEF").is_some() && std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") { println!("cargo:rustc-link-arg-bin=athas=-Wl,-rpath,$ORIGIN"); diff --git a/src-tauri/src/app_runtime.rs b/src-tauri/src/app_runtime.rs index d02f29782..81ff5e51d 100644 --- a/src-tauri/src/app_runtime.rs +++ b/src-tauri/src/app_runtime.rs @@ -1,7 +1,7 @@ -#[cfg(all(target_os = "linux", feature = "linux-cef"))] +#[cfg(all(target_os = "linux", feature = "cef"))] pub type AthasRuntime = tauri::Cef; -#[cfg(not(all(target_os = "linux", feature = "linux-cef")))] +#[cfg(not(all(target_os = "linux", feature = "cef")))] pub type AthasRuntime = tauri::Wry; pub type AppHandle = tauri::AppHandle; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 6f346b445..a36671885 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -19,13 +19,10 @@ mod menu; mod secure_storage; mod terminal; -#[cfg_attr( - all(target_os = "linux", feature = "linux-cef"), - tauri::cef_entry_point -)] +#[cfg_attr(all(target_os = "linux", feature = "cef"), tauri::cef_entry_point)] fn main() { #[cfg(target_os = "linux")] - if cfg!(not(feature = "linux-cef")) && std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() { + if cfg!(not(feature = "cef")) && std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() { // SAFETY: Called at program start before any threads are spawned unsafe { std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1"); From bbc5d0d075b20fcc602ec48a52f84eda6bcffa5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20=C3=96zg=C3=BCl?= Date: Fri, 1 May 2026 15:24:51 +0300 Subject: [PATCH 12/12] Rename Linux runtime feature --- .github/workflows/linux-build.yml | 8 ++++---- .github/workflows/release.yml | 4 ++-- crates/ai/Cargo.toml | 2 +- crates/ai/src/runtime.rs | 4 ++-- crates/debugger/Cargo.toml | 2 +- crates/extensions/Cargo.toml | 2 +- crates/extensions/src/runtime.rs | 4 ++-- crates/lsp/Cargo.toml | 2 +- crates/lsp/src/runtime.rs | 4 ++-- crates/remote/Cargo.toml | 2 +- crates/remote/src/runtime.rs | 4 ++-- crates/terminal/Cargo.toml | 2 +- crates/terminal/src/runtime.rs | 4 ++-- crates/tooling/Cargo.toml | 2 +- crates/tooling/src/runtime.rs | 4 ++-- package.json | 4 ++-- src-tauri/Cargo.toml | 16 ++++++++-------- src-tauri/build.rs | 2 +- src-tauri/src/app_runtime.rs | 4 ++-- src-tauri/src/main.rs | 4 ++-- 20 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index a39b3c0da..6d97d7a24 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -99,14 +99,14 @@ jobs: - name: Check Linux feature graph run: | set -euo pipefail - cargo tree -p athas --no-default-features --features cef -i tauri-runtime-cef - cargo tree -p athas --no-default-features --features cef -i tauri-runtime-wry >/tmp/tauri-runtime-wry.txt 2>&1 || true + cargo tree -p athas --no-default-features --features linux -i tauri-runtime-cef + cargo tree -p athas --no-default-features --features linux -i tauri-runtime-wry >/tmp/tauri-runtime-wry.txt 2>&1 || true if grep -q '^tauri-runtime-wry ' /tmp/tauri-runtime-wry.txt; then echo "tauri-runtime-wry must not be present in the Linux build" cat /tmp/tauri-runtime-wry.txt exit 1 fi - cargo tree -p athas --no-default-features --features cef -i webkit2gtk >/tmp/webkit2gtk.txt 2>&1 || true + cargo tree -p athas --no-default-features --features linux -i webkit2gtk >/tmp/webkit2gtk.txt 2>&1 || true if grep -q '^webkit2gtk ' /tmp/webkit2gtk.txt; then echo "webkit2gtk must not be present in the Linux build" cat /tmp/webkit2gtk.txt @@ -120,7 +120,7 @@ jobs: --config '{"bundle":{"createUpdaterArtifacts":false}}' \ -- \ --no-default-features \ - --features cef + --features linux - name: Package Linux tarball run: bash scripts/release/package-linux-tarball.sh "${{ runner.arch }}" release-dist diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4e91bb4b1..2c251a285 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -105,7 +105,7 @@ jobs: artifact: "linux-x86_64" os: "linux" args: "" - cargo_features: "--no-default-features --features cef" + cargo_features: "--no-default-features --features linux" target: "" bundle_path: "target/release/bundle" timeout_minutes: 120 @@ -114,7 +114,7 @@ jobs: artifact: "linux-aarch64" os: "linux" args: "" - cargo_features: "--no-default-features --features cef" + cargo_features: "--no-default-features --features linux" target: "" bundle_path: "target/release/bundle" timeout_minutes: 120 diff --git a/crates/ai/Cargo.toml b/crates/ai/Cargo.toml index 10bad53bd..94624aefe 100644 --- a/crates/ai/Cargo.toml +++ b/crates/ai/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["athas-terminal/tauri-wry", "tauri/wry", "tauri/x11"] -cef = ["athas-terminal/cef", "tauri/cef"] +linux = ["athas-terminal/linux", "tauri/cef"] [dependencies] agent-client-protocol = { version = "0.9", features = [ diff --git a/crates/ai/src/runtime.rs b/crates/ai/src/runtime.rs index 6ba3dca0a..28476a4b6 100644 --- a/crates/ai/src/runtime.rs +++ b/crates/ai/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "cef")] +#[cfg(feature = "linux")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "cef"))] +#[cfg(not(feature = "linux"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/debugger/Cargo.toml b/crates/debugger/Cargo.toml index 94fb7c476..479c23ec6 100644 --- a/crates/debugger/Cargo.toml +++ b/crates/debugger/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -cef = ["tauri/cef"] +linux = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/extensions/Cargo.toml b/crates/extensions/Cargo.toml index a9cb28efd..021abe55b 100644 --- a/crates/extensions/Cargo.toml +++ b/crates/extensions/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -cef = ["tauri/cef"] +linux = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/extensions/src/runtime.rs b/crates/extensions/src/runtime.rs index 6ba3dca0a..28476a4b6 100644 --- a/crates/extensions/src/runtime.rs +++ b/crates/extensions/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "cef")] +#[cfg(feature = "linux")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "cef"))] +#[cfg(not(feature = "linux"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/lsp/Cargo.toml b/crates/lsp/Cargo.toml index 09c929f7b..39fc1c52f 100644 --- a/crates/lsp/Cargo.toml +++ b/crates/lsp/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -cef = ["tauri/cef"] +linux = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/lsp/src/runtime.rs b/crates/lsp/src/runtime.rs index 6ba3dca0a..28476a4b6 100644 --- a/crates/lsp/src/runtime.rs +++ b/crates/lsp/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "cef")] +#[cfg(feature = "linux")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "cef"))] +#[cfg(not(feature = "linux"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/remote/Cargo.toml b/crates/remote/Cargo.toml index 89a606ef7..79481e443 100644 --- a/crates/remote/Cargo.toml +++ b/crates/remote/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -cef = ["tauri/cef"] +linux = ["tauri/cef"] [dependencies] lazy_static = "1.4" diff --git a/crates/remote/src/runtime.rs b/crates/remote/src/runtime.rs index 6ba3dca0a..28476a4b6 100644 --- a/crates/remote/src/runtime.rs +++ b/crates/remote/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "cef")] +#[cfg(feature = "linux")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "cef"))] +#[cfg(not(feature = "linux"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/terminal/Cargo.toml b/crates/terminal/Cargo.toml index dbbff9e4b..1f030ca14 100644 --- a/crates/terminal/Cargo.toml +++ b/crates/terminal/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -cef = ["tauri/cef"] +linux = ["tauri/cef"] [dependencies] anyhow = "1.0" diff --git a/crates/terminal/src/runtime.rs b/crates/terminal/src/runtime.rs index 6ba3dca0a..28476a4b6 100644 --- a/crates/terminal/src/runtime.rs +++ b/crates/terminal/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "cef")] +#[cfg(feature = "linux")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "cef"))] +#[cfg(not(feature = "linux"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/crates/tooling/Cargo.toml b/crates/tooling/Cargo.toml index 4f5b10cb4..01022d6f7 100644 --- a/crates/tooling/Cargo.toml +++ b/crates/tooling/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [features] default = ["tauri-wry"] tauri-wry = ["tauri/wry", "tauri/x11"] -cef = ["tauri/cef"] +linux = ["tauri/cef"] [dependencies] athas-runtime = { path = "../runtime" } diff --git a/crates/tooling/src/runtime.rs b/crates/tooling/src/runtime.rs index 6ba3dca0a..28476a4b6 100644 --- a/crates/tooling/src/runtime.rs +++ b/crates/tooling/src/runtime.rs @@ -1,5 +1,5 @@ -#[cfg(feature = "cef")] +#[cfg(feature = "linux")] pub type AthasAppHandle = tauri::AppHandle; -#[cfg(not(feature = "cef"))] +#[cfg(not(feature = "linux"))] pub type AthasAppHandle = tauri::AppHandle; diff --git a/package.json b/package.json index cfc943672..b9b8c5b35 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "dev": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.dev.conf.json", "dev:stable": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev", "dev:preview": "bun scripts/check-zig.ts && WEBKIT_DISABLE_DMABUF_RENDERER=1 tauri dev --config src-tauri/tauri.preview.conf.json", - "dev:cef": "bun scripts/check-zig.ts && cargo tauri dev --config src-tauri/tauri.dev.conf.json -- --no-default-features --features cef", + "dev:linux": "bun scripts/check-zig.ts && cargo tauri dev --config src-tauri/tauri.dev.conf.json -- --no-default-features --features linux", "build:stable": "bun scripts/check-zig.ts && tauri build", - "build:linux": "bun scripts/check-zig.ts && cargo tauri build --no-bundle -- --no-default-features --features cef && bash scripts/release/package-linux-tarball.sh $(uname -m) release-dist", + "build:linux": "bun scripts/check-zig.ts && cargo tauri build --no-bundle -- --no-default-features --features linux && bash scripts/release/package-linux-tarball.sh $(uname -m) release-dist", "build:preview": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.preview.conf.json", "build:dev": "bun scripts/check-zig.ts && tauri build --config src-tauri/tauri.dev.conf.json", "smoke": "bun scripts/smoke-app.ts", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 3e25c3a7c..a675464f0 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -18,14 +18,14 @@ tauri-wry = [ "tauri/wry", "tauri/x11", ] -cef = [ - "athas-ai/cef", - "athas-debugger/cef", - "athas-extensions/cef", - "athas-lsp/cef", - "athas-remote/cef", - "athas-terminal/cef", - "athas-tooling/cef", +linux = [ + "athas-ai/linux", + "athas-debugger/linux", + "athas-extensions/linux", + "athas-lsp/linux", + "athas-remote/linux", + "athas-terminal/linux", + "athas-tooling/linux", "tauri/cef", ] diff --git a/src-tauri/build.rs b/src-tauri/build.rs index 32b9cb2ce..b980218e7 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -3,7 +3,7 @@ fn main() { println!("cargo:rustc-link-arg-bin=athas=/NODEFAULTLIB:libvcruntime.lib"); } - if std::env::var_os("CARGO_FEATURE_CEF").is_some() + if std::env::var_os("CARGO_FEATURE_LINUX").is_some() && std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux") { println!("cargo:rustc-link-arg-bin=athas=-Wl,-rpath,$ORIGIN"); diff --git a/src-tauri/src/app_runtime.rs b/src-tauri/src/app_runtime.rs index 81ff5e51d..02217ccf5 100644 --- a/src-tauri/src/app_runtime.rs +++ b/src-tauri/src/app_runtime.rs @@ -1,7 +1,7 @@ -#[cfg(all(target_os = "linux", feature = "cef"))] +#[cfg(all(target_os = "linux", feature = "linux"))] pub type AthasRuntime = tauri::Cef; -#[cfg(not(all(target_os = "linux", feature = "cef")))] +#[cfg(not(all(target_os = "linux", feature = "linux")))] pub type AthasRuntime = tauri::Wry; pub type AppHandle = tauri::AppHandle; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a36671885..a558f947b 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -19,10 +19,10 @@ mod menu; mod secure_storage; mod terminal; -#[cfg_attr(all(target_os = "linux", feature = "cef"), tauri::cef_entry_point)] +#[cfg_attr(all(target_os = "linux", feature = "linux"), tauri::cef_entry_point)] fn main() { #[cfg(target_os = "linux")] - if cfg!(not(feature = "cef")) && std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() { + if cfg!(not(feature = "linux")) && std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() { // SAFETY: Called at program start before any threads are spawned unsafe { std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");