Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Bundled templates, scripts and sources are hashed, embedded and run as
# written: keep LF line endings in every checkout, Windows included.
* text=auto eol=lf
# Unified diffs require a leading context space before upstream tabs/blank lines.
tools/busybox-w32-patches/*.patch whitespace=-space-before-tab,-blank-at-eol
6 changes: 6 additions & 0 deletions .github/workflows/native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ jobs:
timeout-minutes: 120
env:
RUSTUP_TOOLCHAIN: '1.95.0'
# Full debug info plus incremental objects exhaust the hosted runner's
# disk before the integration binaries link. Keep line-number backtraces
# and every test; these jobs do not reuse incremental build state.
CARGO_PROFILE_DEV_DEBUG: line-tables-only
CARGO_PROFILE_TEST_DEBUG: line-tables-only
CARGO_INCREMENTAL: '0'
SHADOWCODE_BUILD_JOBS: '4'
# The Debian package must pass lintian (errors fail; warnings are reported).
SHADOWCODE_REQUIRE_LINTIAN: '1'
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/release-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ on:
- 'scripts/build-busybox-w32.sh'
- 'scripts/build-llama.cpp.sh'
- 'scripts/install-windows.ps1'
- 'scripts/stage-windows-crt.ps1'
- 'scripts/test-windows-installed-runtime.ps1'
- 'packaging/windows/**'
- 'src-tauri/tauri.windows.conf.json'
- 'tools/busybox-w32.pin'
Expand Down Expand Up @@ -98,6 +100,9 @@ jobs:
path: packaging/busybox-w32/bin
- name: Build the local model runtime (llama.cpp, CPU)
run: bash scripts/build-llama.cpp.sh --no-user-install --cpu-only
- name: Stage app-local Microsoft CRT
shell: powershell
run: ./scripts/stage-windows-crt.ps1
- name: Build the installer (NSIS, current user)
env:
SHADOWCODE_COMMIT: ${{ github.sha }}
Expand Down Expand Up @@ -128,6 +133,9 @@ jobs:
profile="$(mktemp -d)"
timeout 120 "$app/shadowcode.exe" --profile "$(cygpath -w "$profile")" doctor --json > "$profile/doctor.json" || true
node -e "const d=require(process.argv[1]); const c=(d.checks||[]).find(x=>x.id==='appcontainer'); if(!c||c.status!=='pass') throw new Error('Windows sandbox check: '+JSON.stringify(c))" "$(cygpath -w "$profile/doctor.json")"
- name: Check installed binaries without toolchain DLLs on PATH
shell: powershell
run: ./scripts/test-windows-installed-runtime.ps1 -AppDirectory "$env:LOCALAPPDATA\ShadowCode"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: windows-installer
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ jobs:
timeout-minutes: 150
env:
RUSTUP_TOOLCHAIN: '1.95.0'
# Full debug info plus incremental objects exhaust the hosted runner's
# disk before the integration binaries link. Keep line-number backtraces
# and every test; these jobs do not reuse incremental build state.
CARGO_PROFILE_DEV_DEBUG: line-tables-only
CARGO_PROFILE_TEST_DEBUG: line-tables-only
CARGO_INCREMENTAL: '0'
SHADOWCODE_BUILD_JOBS: '4'
# The Debian package must pass lintian (errors fail; warnings are reported).
SHADOWCODE_REQUIRE_LINTIAN: '1'
Expand Down Expand Up @@ -145,6 +151,12 @@ jobs:
timeout-minutes: 180
env:
RUSTUP_TOOLCHAIN: '1.95.0'
# Full debug info plus incremental objects exhaust the hosted runner's
# disk before the integration binaries link. Keep line-number backtraces
# and every test; these jobs do not reuse incremental build state.
CARGO_PROFILE_DEV_DEBUG: line-tables-only
CARGO_PROFILE_TEST_DEBUG: line-tables-only
CARGO_INCREMENTAL: '0'
SHADOWCODE_BUILD_JOBS: '4'
SHADOWCODE_REQUIRE_LINTIAN: '1'
outputs:
Expand Down
22 changes: 20 additions & 2 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ name: Windows
on:
push:
branches: [main]
paths: ['native/**', 'src-tauri/**', 'ui/**', 'Cargo.toml', 'Cargo.lock', '.github/workflows/windows.yml', 'scripts/build-llama.cpp.sh', 'tools/llama.cpp.pin', 'scripts/build-busybox-w32.sh', 'tools/busybox-w32.pin', 'packaging/windows/**']
paths: ['native/**', 'src-tauri/**', 'ui/**', 'Cargo.toml', 'Cargo.lock', '.github/workflows/windows.yml', 'scripts/build-llama.cpp.sh', 'scripts/stage-windows-crt.ps1', 'scripts/test-windows-installed-runtime.ps1', 'tools/llama.cpp.pin', 'scripts/build-busybox-w32.sh', 'tools/busybox-w32.pin', 'tools/busybox-w32-patches/**', 'packaging/windows/**']
pull_request:
paths: ['native/**', 'src-tauri/**', 'ui/**', 'Cargo.toml', 'Cargo.lock', '.github/workflows/windows.yml', 'scripts/build-llama.cpp.sh', 'tools/llama.cpp.pin', 'scripts/build-busybox-w32.sh', 'tools/busybox-w32.pin', 'packaging/windows/**']
paths: ['native/**', 'src-tauri/**', 'ui/**', 'Cargo.toml', 'Cargo.lock', '.github/workflows/windows.yml', 'scripts/build-llama.cpp.sh', 'scripts/stage-windows-crt.ps1', 'scripts/test-windows-installed-runtime.ps1', 'tools/llama.cpp.pin', 'scripts/build-busybox-w32.sh', 'tools/busybox-w32.pin', 'tools/busybox-w32-patches/**', 'packaging/windows/**']
permissions:
contents: read
concurrency:
Expand Down Expand Up @@ -58,6 +58,11 @@ jobs:
# The desktop crate embeds the built interface (tauri.conf.json frontendDist).
- run: npm --prefix ui ci
- run: npm --prefix ui run build
- name: Windows editor shortcuts and native clipboard regression tests
working-directory: ui
run: |
npx playwright install chromium
npx playwright test e2e/editor.spec.ts e2e/markdownWorker.spec.ts
- name: Compile everything for Windows (all errors at once)
run: |
set -o pipefail
Expand Down Expand Up @@ -144,6 +149,9 @@ jobs:
ls packaging/llama.cpp/bin
packaging/llama.cpp/bin/llama-server.exe --version
packaging/llama.cpp/bin/llama-server.exe --list-devices
- name: Stage app-local Microsoft CRT
shell: powershell
run: ./scripts/stage-windows-crt.ps1
- name: Build the preview installer (NSIS, current user)
run: CI=true ui/node_modules/.bin/tauri build --bundles nsis --config packaging/windows/bundle-runtime.conf.json
- name: The app starts and reports its version
Expand All @@ -162,6 +170,16 @@ jobs:
! grep -q "HOME is not set" <<<"$out"
test -d "$(cygpath -u "$LOCALAPPDATA")/ShadowCode/state"
test -d "$(cygpath -u "$APPDATA")/ShadowCode/config"
- name: Install and check with a clean runtime search path
shell: powershell
run: |
$setup = Get-ChildItem target/release/bundle/nsis/*-setup.exe | Select-Object -First 1
if (!$setup) { throw 'Preview installer missing' }
$install = Start-Process $setup.FullName -ArgumentList '/S' -PassThru
$handle = $install.Handle
$install.WaitForExit()
if ($install.ExitCode -ne 0) { throw "Installer failed: $($install.ExitCode)" }
./scripts/test-windows-installed-runtime.ps1 -AppDirectory "$env:LOCALAPPDATA\ShadowCode"
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: windows-preview-installer
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ src/shadow_agent/_assets/
/.claude/
/tools/busybox-w32/
/packaging/busybox-w32/bin/
/packaging/windows/crt/
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
read-only toolchains readable, the rest of the home folder hidden; the
network is off (no capabilities, this computer's own services included)
or on. Commands run in a bundled busybox-w32 `sh`, built from a pinned
commit with one patch (the container may not open the null device, so
`/dev/null` uses a handle the launcher opens for it); its complete source
commit with patches for the sandbox null-device handle and waiting for
foreground commands to finish inside AppContainer; its complete source
is attached to each release as `ShadowCode_VERSION_busybox-w32-source.tar.gz`.
The network allow-list is refused on Windows. `shadowcode doctor` and
**Settings › Permissions & network** report the Windows sandbox.
Expand All @@ -31,6 +31,15 @@
- **Contested writes.** Settings files replaced by two writers at the same
moment are retried (Windows refuses the second replacement), and writers
in one process queue for a database's write lock instead of polling it.
- **Windows startup and command results.** Bundle the required Microsoft CRT
beside the app and managed runtime, remove the runtime's unused OpenSSL
dependency, and preserve sandboxed child output and exit status. Debug
desktop builds reserve enough stack for the async CLI.
- **Windows editing and worktrees.** Support both Ctrl+Y and Ctrl+Shift+Z
redo, and use the platform shell when setting up a worktree.
- **Local model selection.** Selecting a configured GGUF model from a fresh
CLI process no longer requires opening the picker first; stale catalog
entries cannot select files removed from the profile's configuration.
- **Native runtime pins** follow Alpine 3.21's libcurl and libexpat security
updates.

Expand Down
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,17 @@ The code is open source; the Shadowfetch and ShadowCode product identity is cove
own terminal, go from commit to pull request, preview the app you're
building, dictate with your voice, and follow along from your phone.

ShadowCode **2.2.0** is the current release, available in [GitHub releases](https://github.com/ShadowfetchStudio/ShadowCode/releases/tag/v2.2.0) for x86_64 and 64-bit ARM Linux, from the signed APT repository below and for macOS (Apple silicon and Intel).
See the [2.2.0 release notes](https://github.com/ShadowfetchStudio/ShadowCode/releases/tag/v2.2.0) for changes and qualification
limits, and the [release history](CHANGELOG.md). Windows is in development
for the next release and is not released yet (see [Windows](#windows)).
ShadowCode **2.2.0** is the current public release for Linux and macOS,
available from [GitHub releases](https://github.com/ShadowfetchStudio/ShadowCode/releases/tag/v2.2.0)
and [shadowcode.org](https://shadowcode.org/).

**2.3.0 is a release candidate**, adding Windows. Its Windows installers
have passed CI and physical-laptop qualification, but public publication
is still pending. See the [candidate release notes](docs/RELEASE_NOTES.md),
[Windows qualification record](docs/WINDOWS_LAPTOP_QUALIFICATION.md), and
[release history](CHANGELOG.md). Download instructions below use published
versions; the Windows section describes the forthcoming release.


## Install

Expand Down Expand Up @@ -162,7 +169,7 @@ On Windows the app is in `%LOCALAPPDATA%\ShadowCode`, settings in
Shell commands run in an AppContainer sandbox with busybox `sh`, so they
keep their POSIX syntax; the network allow-list is not available on
Windows. The Windows version is new: it is tested on GitHub's Windows
runners, not yet on a wide range of PCs. See
runners and one Windows 11 laptop, not yet on a wide range of PCs. See
[the Windows port notes](docs/WINDOWS_PORT.md).

### AppImage (recommended)
Expand Down
17 changes: 16 additions & 1 deletion docs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,25 @@ ShadowCode 2.3.0 runs on Windows. The 2.2.0 notes follow below.
on Windows with "Access is denied", and busy databases no longer time out
with "database is locked".

- The Windows installer includes the Microsoft runtime DLLs needed to start
the app and local models on a machine without development tools.
- Sandboxed commands now wait for the child process and return its actual
output and exit status instead of sometimes reporting empty success.
- Windows redo accepts both Ctrl+Y and Ctrl+Shift+Z, and worktree setup uses
the platform shell.
- Selecting a local GGUF model from a fresh CLI process works without first
opening the model picker.

## Known limits

- The Windows version is new and has been tested on GitHub's Windows
machines, not yet on a wide range of PCs. Subscription tools were tested
machines and one Windows 11 laptop, not yet on a wide range of PCs.
Both the optimized Windows preview and release-workflow installer
completed a small Python repair task with Gemma 4 E4B on CPU, with the
original tests preserved and independently passing. This is not broad
model-quality qualification; see the
[qualification record](WINDOWS_LAPTOP_QUALIFICATION.md).
Subscription tools were tested
there with stand-in programs, not yet with each vendor's own Windows CLI.
Local models use the CPU only on Windows for now.

Expand Down
18 changes: 11 additions & 7 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ and authentication receipts to the exact candidate before publication.

Pushing a `v*` tag starts `.github/workflows/release.yml`. Publication follows
build/qualification, protected signing review and verification of all seven
public assets. The signing environment permits only the tag being released
(`v2.3.0` for 2.3.0); every later version needs reviewed trust-policy,
public assets. The signing environment must permit the tag being released. As verified
on October 31, 2026, it still permits `v2.2.0`; before 2.3.0, change its
deployment rule to `v2.3.0` after candidate review. Every later version needs reviewed trust-policy,
deployment-rule and tooling-pin updates. The workflow uses
`docs/RELEASE_NOTES.md` as the release text.

Expand Down Expand Up @@ -191,11 +192,14 @@ Public trust in `release/trust` currently allows the x86_64 and aarch64 targets,
The `release-signing` environment has the signing secret and requires review by
`Shadowfetchapps` (User ID `209457103`). Self-review is allowed and GitHub's
default administrator override remains unchanged. For 2.3.0 its sole
deployment rule is the tag `v2.3.0` (it was `v2.2.0` for 2.2.0, `v2.1.0` for 2.1.0, `v1.0.1` for
1.0.1, `v1.0.0` for 1.0.0, `v0.34.2` for 0.34.2 and `v0.33.1` for 0.33.1);
`NATIVE_RELEASE_SIGNING_ENVIRONMENT` points to that environment. For 2.3.0,
`NATIVE_RELEASE_TOOLING_COMMIT` pins the tagged release commit itself, as it
did for 0.33.1 (`e15c4480e65db5650af012bb2a9773dbe89acf84`).
deployment rule must be changed to `v2.3.0`. As verified on October 31,
2026, the actual GitHub rule still permits only `v2.2.0` and
`NATIVE_RELEASE_TOOLING_COMMIT` still points to the 2.2.0 commit,
`444e75f13c3512d57c226b39d6edf59fdb08a4c6`.
`NATIVE_RELEASE_SIGNING_ENVIRONMENT` points to `release-signing`. For 2.3.0,
set the tooling pin to the reviewed tagged release commit itself, as was
done for 0.33.1 (`e15c4480e65db5650af012bb2a9773dbe89acf84`).
These are release prerequisites, not configuration already applied.

Before tagging, finish review and push the tooling commit, then set
`NATIVE_RELEASE_TOOLING_COMMIT` to that exact 40-character SHA. Read back this pin from GitHub configuration before dispatching the release. Verify the environment protections and source/candidate
Expand Down
Loading
Loading