From 4bc6321aff16c6cdd1638831e80221cf6aada2d7 Mon Sep 17 00:00:00 2001 From: Looped Date: Wed, 2 Sep 2026 01:43:57 +0300 Subject: [PATCH 1/6] Add Windows desktop support - run agent CLIs and terminals with Windows-native process handling\n- normalize Windows paths and add Acrylic window styling\n- build, test, and publish an NSIS installer\n\nCloses #18 --- .github/ISSUE_TEMPLATE/bug_report.yml | 19 ++- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 40 ++++- CHANGELOG.md | 4 + CONTRIBUTING.md | 2 +- Cargo.lock | 101 +++++++++++- README.md | 16 +- index.html | 1 + package.json | 3 +- src-tauri/Cargo.toml | 3 + src-tauri/build.rs | 7 + src-tauri/icons/installer-sidebar.bmp | Bin 0 -> 154542 bytes src-tauri/src/checkpoint.rs | 7 +- src-tauri/src/fs.rs | 71 ++++---- src-tauri/src/harness.rs | 227 +++++++++++++++++++------- src-tauri/src/lib.rs | 49 ++++-- src-tauri/src/pty.rs | 219 ++++++++++++++++++------- src-tauri/src/search.rs | 3 +- src-tauri/src/skills.rs | 2 +- src-tauri/src/window.rs | 11 +- src-tauri/tauri.windows.conf.json | 34 ++++ src/App.tsx | 4 +- src/chrome/FileTree.tsx | 4 +- src/chrome/FileTypeIcon.tsx | 23 +-- src/chrome/ProjectRail.tsx | 4 +- src/index.css | 10 +- src/lib/appearance.ts | 3 +- src/lib/fileIndex.ts | 4 +- src/lib/fs.ts | 22 ++- src/lib/paths.test.ts | 63 +++++++ src/lib/paths.ts | 73 +++++++-- src/lib/platform.ts | 6 + src/lib/recents.test.ts | 37 ++--- src/lib/recents.ts | 68 ++++---- src/lib/search.ts | 3 +- src/surfaces/TerminalView.tsx | 44 +++-- 36 files changed, 891 insertions(+), 298 deletions(-) create mode 100644 src-tauri/icons/installer-sidebar.bmp create mode 100644 src-tauri/tauri.windows.conf.json create mode 100644 src/lib/paths.test.ts diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index a49ea143..d4cd37c2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -5,7 +5,7 @@ body: - type: markdown attributes: value: | - MonoCode is macOS (Apple Silicon) only. Linux and Windows are out of scope. + MonoCode supports macOS, Linux, and Windows. - type: input id: version @@ -15,11 +15,22 @@ body: validations: required: true + - type: dropdown + id: os + attributes: + label: Operating system + options: + - macOS + - Linux + - Windows + validations: + required: true + - type: input - id: macos + id: os-version attributes: - label: macOS version - placeholder: "15.5" + label: OS version + placeholder: "Windows 11, Ubuntu 24.04, macOS 15.5" validations: required: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 752b3033..b95ba6e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: check: strategy: matrix: - os: [macos-latest, ubuntu-latest] + os: [macos-latest, ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 766e983f..1f9566d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ permissions: jobs: release: - needs: linux + needs: [linux, windows] runs-on: macos-latest steps: - uses: actions/checkout@v4 @@ -168,6 +168,12 @@ jobs: name: linux-packages path: target/release/bundle/linux + - name: Download Windows packages + uses: actions/download-artifact@v4 + with: + name: windows-packages + path: target/release/bundle/nsis + - name: GitHub Release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -181,14 +187,15 @@ jobs: shopt -s nullglob DEB=("$BUNDLE"/linux/*.deb) APPIMAGE=("$BUNDLE"/linux/*.AppImage) - if (( ${#DEB[@]} != 1 || ${#APPIMAGE[@]} != 1 )); then - echo "Expected exactly one .deb and one AppImage" >&2 + NSIS=("$BUNDLE"/nsis/*.exe) + if (( ${#DEB[@]} != 1 || ${#APPIMAGE[@]} != 1 || ${#NSIS[@]} != 1 )); then + echo "Expected exactly one .deb, one AppImage, and one NSIS installer" >&2 exit 1 fi gh release create "$GITHUB_REF_NAME" \ --title "MonoCode $VERSION" \ --notes "See CHANGELOG.md for details." \ - "$DMG" "$TAR" "$SIG" "${DEB[0]}" "${APPIMAGE[0]}" + "$DMG" "$TAR" "$SIG" "${DEB[0]}" "${APPIMAGE[0]}" "${NSIS[0]}" linux: name: Linux packages @@ -230,3 +237,28 @@ jobs: name: linux-packages path: release-artifacts/ if-no-files-found: error + + windows: + name: Windows packages + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - uses: dtolnay/rust-toolchain@stable + + - run: npm ci + + - name: Build Windows packages + run: npm run build:windows + + - name: Upload Windows packages + uses: actions/upload-artifact@v4 + with: + name: windows-packages + path: target/release/bundle/nsis/*.exe + if-no-files-found: error diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e19b987..754a1130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Windows is a supported desktop target. Terminals, agent CLIs, and the rest of the macOS/Linux feature set run there, and the window uses Tauri Acrylic in place of macOS vibrancy. + ## [0.1.28] - 2026-09-01 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index deb4c4a6..acafbb0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ You need Node.js 20+, a current stable Rust toolchain, and at least one provider - [omp](https://omp.sh) - `curl -fsSL https://omp.sh/install | sh` - [fx](https://fx.sh) - `curl -fsSL https://fx.sh/setup.sh | bash` then `fx login` -macOS and Linux are supported targets. On Debian/Ubuntu, `npm run setup:linux:deb` installs the native Tauri build dependencies. +macOS, Linux, and Windows are supported targets. On Debian/Ubuntu, `npm run setup:linux:deb` installs the native Tauri build dependencies. ```bash npm install diff --git a/Cargo.lock b/Cargo.lock index 7790a1a9..402e17f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -462,6 +462,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" version = "0.4.45" @@ -834,6 +840,12 @@ dependencies = [ "tendril", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dpi" version = "0.1.2" @@ -896,7 +908,7 @@ dependencies = [ "rustc_version", "toml 1.1.4+spec-1.1.0", "vswhom", - "winreg", + "winreg 0.55.0", ] [[package]] @@ -1016,6 +1028,17 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "filedescriptor" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] + [[package]] name = "filetime" version = "0.2.29" @@ -2014,6 +2037,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libappindicator" version = "0.9.0" @@ -2180,6 +2209,7 @@ dependencies = [ "objc2-app-kit", "objc2-foundation", "objc2-user-notifications", + "portable-pty", "raw-window-handle", "rusqlite", "serde", @@ -2245,6 +2275,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.13.1", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "num-conv" version = "0.2.2" @@ -2772,6 +2814,27 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "portable-pty" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "downcast-rs", + "filedescriptor", + "lazy_static", + "libc", + "log", + "nix", + "serial2", + "shared_library", + "shell-words", + "winapi", + "winreg 0.10.1", +] + [[package]] name = "potential_utf" version = "0.1.5" @@ -3413,6 +3476,17 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "serial2" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16809bc35793b19ce4e0c53924bc0dce3937f15487997cfdaed936004180730" +dependencies = [ + "cfg-if", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "serialize-to-javascript" version = "0.1.2" @@ -3455,6 +3529,22 @@ dependencies = [ "digest", ] +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + [[package]] name = "shlex" version = "2.0.1" @@ -5353,6 +5443,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "winreg" version = "0.55.0" diff --git a/README.md b/README.md index ddd6d39a..7ccdb1b4 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ macOS (Apple Silicon): download [MonoCode.dmg](https://dl.usemono.dev/MonoCode.d Linux (x86_64): download the `.deb` or AppImage from [GitHub Releases](https://github.com/hardbeat920/monocode/releases/latest). Install the `.deb` with `sudo apt install ./MonoCode_*.deb`, or make the AppImage executable with `chmod +x MonoCode_*.AppImage` and run it directly. +Windows (x86_64): download the NSIS installer from [GitHub Releases](https://github.com/hardbeat920/monocode/releases/latest) and run it. + ## Some notes This is very early and you should expect bugs. @@ -39,9 +41,9 @@ Small, focused pull requests are welcome. Anything large is worth an issue first ## Build from source -Supports macOS and Linux. +Supports macOS, Linux, and Windows. -Need Node.js 20+ and a current stable Rust toolchain. On Linux, ensure standard Tauri prerequisites are installed (e.g. `libwebkit2gtk-4.1-dev`, `libgtk-3-dev`, `libsoup-3.0-dev`, `libjavascriptcoregtk-4.1-dev`). +Need Node.js 20+ and a current stable Rust toolchain. On Linux, ensure standard Tauri prerequisites are installed (e.g. `libwebkit2gtk-4.1-dev`, `libgtk-3-dev`, `libsoup-3.0-dev`, `libjavascriptcoregtk-4.1-dev`). On Windows, the installer bootstraps the [WebView2](https://developer.microsoft.com/microsoft-edge/webview2/) runtime when it is missing. ```bash npm install @@ -61,6 +63,16 @@ npm run build:linux The Linux build emits `.deb` and AppImage bundles under `target/release/bundle/`. Tauri loads `src-tauri/tauri.linux.conf.json` automatically for Linux development and builds. +### Windows packages + +```bash +npm ci +npm run build:windows +``` + +The Windows build emits an NSIS installer under `target/release/bundle/nsis/`. +Tauri loads `src-tauri/tauri.windows.conf.json` automatically for Windows development and builds. + ## License [MIT](LICENSE). Provider names and logos are trademarks of their owners - see [NOTICE](NOTICE). diff --git a/index.html b/index.html index b8182e8e..28eb0578 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,7 @@ + MonoCode