- Prevent the composer from painting over terminal dock controls at larger zoom levels in short windows.
- Keep conversation/composer scrolling, menus and Latest activity reachable while preserving editor and composer drafts and the terminal session.
- Include a fallback for webviews without size container queries and regression coverage for the measured Windows geometry and CSS zoom.
- Display Windows folder names correctly in terminal notices, reserve complete terminal rows, and keep long notices, errors and terminal controls accessible by scrolling.
- Keep delayed startup restoration and workspace results from overriding newer conversation or project navigation.
- Check AppStream release metadata against the application version before native packaging.
- Retain 2.4.0 publication evidence and the native Windows failure that prompted this patch; qualify new installer bytes separately.
- Mac workspace. Direct Files/Terminal/Preview controls, a remembered resizable side panel, and an optional bottom terminal make code, conversation and output available together. Compact-window navigation remains recoverable.
- Project and evidence context. Show the working folder and branch alongside project checks and latest-task review. Project headings create tasks in their own workspace; creation and activation share one queue to prevent late replies from changing a newer selection.
- Mac keyboard and motion. Command-Shift-M chooses a model and Control-backtick reaches Terminal, leaving native window shortcuts intact. Option-arrow editing and IME composition stay with text input. Terminal cursor blinking follows reduced-motion changes.
- Apple shared memory. Correct speculative-page accounting, check current headroom before allocating on identified Apple Metal hardware, and explicitly disable the audited runtime's extra host prompt cache. Estimates and requested backend remain distinct from guaranteed allocation or observed GPU execution.
- Model load cancellation. Cancel pending preparation from Local models; cancellation interrupts readiness requests, and a rejected cancellation keeps tracking the original load until it settles.
- Review freshness. Keep markers bind to the content shown, expire after file changes, and cannot be restored from legacy path-only storage. Review requests stay with their task; failed/no-op undo retries an interrupted diff read.
- External-drive Mac work. Apple developer tools can access the metadata of their system temp directory while the sandbox continues blocking unrelated temp-file contents and writes.
- Research rationale and qualification evidence are recorded in the Mac upgrade report.
- Apple silicon. Packaging prefers native arm64 even when the shell is under Rosetta. llama.cpp Metal builds require
default.metalliband setGGML_METAL_PATH_RESOURCESat runtime.shadowcode doctorreports Apple silicon vs Intel vs Rosetta and whether the Metal shaders are present. - TMPDIR redaction. Darwin
/var/folders/<xx>/<yyyy>/Tnames are no longer treated as high-entropy secrets, so macOS command cards stay readable. - First useful action is one screen. Welcome is Open project (ask-first approvals by default). Sign-in, API keys and a free local download live on the empty conversation, not a second blocking wizard.
- Easy sign-in. Connect Codex, Claude Code, Cursor, Antigravity (Install & connect) and Grok from that same picker. Paste an OpenRouter, xAI or OpenAI key inline; new keys move to the macOS Keychain (or Linux desktop keyring) when one is available. Settings › Accounts remains the place to switch, disconnect and add other endpoints.
- Chat-first chrome. Sidebar threads show Working / Done / Needs approval. Permission mode short label is Allow edits. Changes includes Open pull request… into the Git tab.
Extends the existing Linux release signing key trust interval through 2.3.3. The tagged 2.3.2 candidate was not published because its trust interval ended at 2.3.1.
-
Relocate bundled WebKit helper paths so AppImages do not depend on the build host's Debian filesystem layout. Verify relocation against the shipped library bytes.
-
On compatible non-Debian desktop layouts, select a complete host WebKit/GTK stack to avoid mixing newer Mesa drivers with the bundled Debian graphics stack. Both helper executables and all native dependencies are checked; the bundled fallback remains available. No sandbox is disabled.
-
Closing the model picker no longer steals focus back from a composer the user has already focused. This fixes interrupted typing and accidental picker reopening.
-
Vendor discovery no longer selects unknown or interactive ACP authentication methods such as Grok browser login. It checks an existing session and leaves interactive sign-in to Connect. Known existing-login methods remain supported.
-
Sidebar shortcuts display Command on Apple keyboards and Control on Windows/Linux.
-
Add installed-engine endurance qualification for Windows, macOS, and Linux, with platform-specific process measurements and explicit test-scope limits.
-
Editor browser tests use the platform's document-navigation and editing shortcuts.
-
About → Website now opens https://shadowcode.org (was shadowfetchlinux.org/shadowcode); the AppStream homepage URL matches.
- Write-subagent guidance now states that an existing Git commit is required. A failed prerequisite check directs the parent to its own editing tools or read-only agents instead of asking it to create Git history just to delegate.
- Check the prerequisite before preparing a worktree. Regression coverage includes plain folders, repositories without commits, and committed repositories. Windows AppContainer restrictions remain in force; this does not grant external programs access to the null device or move shell commands outside the sandbox.
- Windows. ShadowCode builds and runs on 64-bit Windows 10 (1809 or
later) and 11:
ShadowCode_VERSION_x64-setup.exe, a per-user NSIS installer (no administrator rights), not code-signed (GitHub is the channel;scripts/install-windows.ps1installs from a release after checkingShadowCode_VERSION_windows.sha256). The app lives in%LOCALAPPDATA%\ShadowCode, settings in%APPDATA%\ShadowCode\config. The engine connection is a named pipe that only this user may open; terminals are pseudoconsoles (ConPTY) running PowerShell; subscription CLIs and agent commands run in job objects, so stopping or closing ShadowCode ends everything they started; llama.cpp is built with MSVC (CPU) and installed beside the app. - Windows sandbox. Agent shell commands run in an AppContainer: the
project and a scratch folder are writable, Windows, Program Files and
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 patches for the sandbox null-device handle and waiting for foreground commands to finish inside AppContainer; its complete source is attached to each release asShadowCode_VERSION_busybox-w32-source.tar.gz. The network allow-list is refused on Windows.shadowcode doctorand Settings › Permissions & network report the Windows sandbox. - Windows release workflow.
.github/workflows/release-windows.ymlbuilds the installer from the release tag, installs it through the install script, requires the doctor's sandbox check to pass and attaches the installer, the busybox source and their checksums;release.ymldispatches it with the macOS and Flatpak builds. - 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 current package revisions, including libcurl, libexpat, musl and zlib updates. Retained source archives include the matching distribution patches and verified source checksums.
- macOS. ShadowCode builds and runs as a Mac app:
ShadowCode.appinShadowCode_VERSION_aarch64.dmg(Apple silicon) and_x64.dmg(Intel), macOS 12 or later, ad-hoc signed and not notarized (GitHub is the channel;scripts/install-macos.shinstalls from a release after checkingShadowCode_VERSION_macos.sha256). Settings and history live in~/Library/Application Support/ShadowCode; opened from Finder the app adopts the login shell'sPATH; agent shell commands run under Seatbelt (sandbox-exec) mirroring bubblewrap: hidden home and other volumes, an emptyHOMEwith read-only toolchains, writes only in the project and scratch, network off, on or limited to the allow-list proxy; API keys can live in the login Keychain; terminals, the dev-server preview, worktree cleanup and SQLite inspection work without/proc; helpers die with the app through a kqueue watcher; llama.cpp is built with Metal and precompiled shaders..github/workflows/release-macos.ymlattaches the images to each published release. Details:docs/MACOS_PORT_ESTIMATE.md. - Flatpak bundles on every release.
.github/workflows/release-flatpak.ymlbuildsShadowCode_VERSION_x86_64.flatpakand_aarch64.flatpak(Vulkan runtime) from the release tag, installs and starts them, and attaches them withShadowCode_VERSION_flatpak.sha256. The publisher leaves these later attachments alone when it re-checks a published release. - Paths on approval cards. The high-entropy secret rule judges a path
under a well-known root (
/Users,/Volumes,/home, ...) one segment at a time, so a command's folder is no longer shown as[redacted secret]; a secret that is itself a segment is still hidden. - Free memory. Local models that run in RAM (or Apple silicon's shared
memory) note when they need more memory than is free right now
(
MemAvailableon Linux, free and reclaimable pages on macOS);hardware.available_bytesreports it. - Your own model servers. Settings › Accounts › Your own endpoints
connects Ollama, LM Studio, a llama.cpp or vLLM server, xAI, OpenAI or any
OpenAI-compatible API. Find models lists what the server offers; the
models you tick appear in the picker (servers on this computer under On
this computer, others under API keys, off in offline mode) and run with
ShadowCode's own agent. Test and Remove sit beside each one. A typed
key is saved on this computer only when you add models, under a name chosen
for the service (
api.deepseek.comusesDEEPSEEK_API_KEY), so two services never overwrite each other's key; a remote device never makes the desktop send a saved key to an address it typed. New routesPOST /api/providers/models,POST /api/models/endpointsandPOST /api/models/remove;GET /api/pickerlists these rows withcustom: true. - Settings › Agent. Steps per task, the token budget and autonomy profile,
tool time limit and output size, history shortening and summaries, provider
retries, fix attempts, the stuck check, subagent limits, checkpoints and the
commands that count as checks can be changed without editing
config.yaml. Each setting shows what it does, its range and default, and has a Reset; out-of-range values are caught before saving and a refused save shows the engine's reason. Only the settings you changed are saved, so a project's own agent settings are never copied into your profile. - Find in conversation.
Ctrl+F(or Find in conversation in the command palette) searches the open conversation's prompts, answers and notes, older saved messages included, and shows 3 of 12.Enter/Shift+EnterandF3/Shift+F3step through matches, opening older messages as needed; matches on screen are highlighted (the row is outlined where the webview cannot highlight text). A file editor and the terminal keep their ownCtrl+F. - Search finds words in answers. Task search in the sidebar and the Tasks
tab also matches the agent's answers, and a result whose title doesn't show
the words shows the message or answer that matched, with the words marked.
GET /api/sessions?q=rows carrymatch: {field, snippet, start, end}. - A smarter command palette.
Ctrl+Kmatches letters in order, so rev ch finds Review changes; word starts rank first and matched letters are bold. Typing also lists matching Conversations and Projects to open, and with nothing typed Recent shows the last five commands you ran. Screen readers follow the highlighted entry;Page Up/Page DownandHome/Endmove through the list. - Text size.
Ctrl+=(orCtrl++),Ctrl+-andCtrl+0zoom the whole window from 80% to 175%, with the new size shown briefly; it is saved asui.zoomand the window reopens at that size. The desktop zooms its webview; in a browser over remote access the terminal and editor still put the pointer on the right text. A phone or browser using remote access keeps its own size in its own storage, starting at 100%, and never changes the desktop's. Settings › Appearance gains a Text size control, and theme and text size now change as you pick them: leaving without saving puts back what you had. The palette offers Theme: same as the system, light and dark (the old toggle could never get back to System) and Zoom in, Zoom out and Reset zoom. - Message times. Prompts and answers show when they were sent, quietly at their edge ("14:32", "Yesterday 14:32", or the date), with the full date and time on hover; a quick reply keeps its time hidden until hovered. Times come from the conversation's record.
- All of a tool's output. Long output in the activity timeline and in hook cards offers Show all (N lines) / Show less and Copy, which copies all of it; very long output shows its last 2,000 lines and says so.
- Composer
/menu.Enterpicks the highlighted command, asTaband the@menu do, and the nextEntersends it. Commands whose name or description contains what you typed follow the name matches. - Notifications wait while you read them. A notification stays while the pointer is on it or focus is inside it, then finishes its remaining time.
- Screen readers hear milestones, not every update. Only the status bar's state is announced, and the conversation is a named log that isn't read out while it streams. One announcement says when an answer finished, a task failed or stopped, or an action needs approval; approval cards are named for their action.
- The page title names the open conversation, with a dot while a task runs, so a browser tab on a paired device says what it shows.
- Deleting an automation asks in the app's own dialog. The drawer's tabs are a tab list (arrow keys, Home/End). Latest activity jumps instead of gliding when the system asks for reduced motion.
- The theme follows the desktop by default.
ui.themenow defaults tosystemin the engine andconfig.example.yaml, as the window and onboarding already assumed; a profile that never chose a theme no longer opens light on a dark desktop. Saved choices are unchanged. docs/NATIVE_ROUTING.mdno longer points at a Custom model… control that does not exist.- Subagent settings are checked when saved. A
subagentsvalue that is misspelled, the wrong type or out of range (for examplemax_parallel: 20) is refused with the allowed range, instead of being clamped or ignored without a word. Aconfig.yamlsaved earlier still loads as before. - Settings › Agent shows what it saves. It showed the open project's own
agentvalues (from.shadow/config/config.yaml) as if they were the profile's, while saving to the profile. It now shows and compares against the profile's values and notes under a setting when the project uses another, for example "This project uses 200.".GET/PUT /api/configreturnagent_profileandagent_projectfor this. - Stop at a spending limit always ends the task as cancelled; it could end as failed when the answer reached the task before the engine did.
- Signed APT repository. Each release's authenticated
.debis indexed in an APT repository on GitHub Pages (stable/main, amd64 and arm64), signed with a dedicated OpenPGP key held in the protected release environment. Install it with a deb822.sourcesfile and aSigned-Bykeyring in/etc/apt/keyrings; updates and downgrade protection then come from APT. See the README's Debian section anddocs/DISTRIBUTING.md. - ARM64 (aarch64) builds. The AppImage (
_aarch64.AppImage), Debian package (_arm64.deb,Architecture: arm64), Flatpak (_aarch64.flatpak), the source-built AppImage runtime and the bundled llama.cpp runtime are built natively on aarch64. x86_64 package names and contents are unchanged. - Native CI runs on x86_64 and on GitHub's
ubuntu-24.04-armrunners. The release workflow qualifies aarch64 packages with every required gate, signs them with their own envelope and publishes them in the same release as x86_64. Their signature files carry an-aarch64suffix (RELEASE-AUTH-aarch64,RELEASE-AUTH-aarch64.sig,RELEASE-MANIFEST-aarch64.json,SHA256SUMS-aarch64); the x86_64 names are unchanged. The APT repository indexes the arm64.debtoo. - On ARM64, the in-app update notice names the aarch64 AppImage and its signature files, and treats a release as signed only when they are present.
- Release authentication accepts
aarch64-unknown-linux-gnuenvelopes with their own asset names. Trust policies may list several targets; releases for a target the policy does not name, or that switch target against accepted history, are refused. The publisher's trust policy now names bothx86_64-unknown-linux-gnuandaarch64-unknown-linux-gnu. - The AppImage installer installs only the AppImage for the machine's architecture and requires the signed target to match it.
build-flatpak.pygains--arch,--state-dir,--install-deps-fromand--cpu-only-llama.- Pull requests that touch packaging, scripts, the desktop, the core or workflows build the Flatpak with the GNOME 50 SDK and run the packaging checks on both architectures.
- Flatpak: hostname allow-list mode for agent shell commands now works. The host bubblewrap gets its own private network namespace, and a small packaged relay forwards loopback port 3128 to ShadowCode's allow-list proxy over a Unix socket. If the relay or proxy socket cannot be set up, the command is still refused.
- The window remembers its size again. ShadowCode now saves the size of the window's content, without the title bar or the shadow the desktop adds, and reopens at that size. On Wayland desktops such as KDE Plasma the window opens at the size you left it and no longer grows from launch to launch. The remembered size is still fitted to the screen (at most 90% of it, never below 520x640), so it fits a smaller screen too. Sizes saved by earlier versions are ignored, so the first launch after updating opens at the default size.
- The AppImage installer checks the first window and can roll back the
database. Before activation it snapshots the profile database with
SQLite's
VACUUM INTOand refuses while ShadowCode is running. With a display, it then starts the new version, which must report within 120 seconds that its database opened (and migrated) and its main window loaded. Otherwise the new version is stopped and the previous AppImage, llama.cpp runtime, launchers, desktop entry and database snapshot are restored.--recoverdoes the same after an installer crash during the check. The durable highest accepted release is not lowered by this rollback.SHADOWCODE_FIRST_START_CHECK(auto,require,skip) andSHADOWCODE_FIRST_START_TIMEOUTcontrol the check; without a display it is skipped. - The desktop app writes the installer's first-start report after the
database opened and the main window finished loading, and a hidden
shadowcode install-snapshot FILEcommand makes the installer's database snapshot. An older version still refuses a database a newer version changed, without changing it. - Model history per project in the picker. Every finished task records
the model that ran it, how long it took, its tokens, its cost when the
provider, vendor CLI or this computer reported it (otherwise shown as
cost unavailable, never estimated), and whether observed verification
passed. Picker rows show the median time, median reported cost, pass count
and number of tasks in this project, and Compare history shows all
models side by side. Stored in a new
model_outcomestable (database format 28, migrated with a backup like earlier formats). - Opt-in suggestion: the cheapest model that passed here before. Turn on
Suggest the cheapest model that passed here (
routing.suggest_from_history) to see a suggestion you can accept or dismiss. ShadowCode never switches models on its own; offline only local models are suggested, and spending limits for paid API models are respected. - New experimental endpoint
GET /api/models/outcomes.
- Update repository, contributor, release and package links for the ShadowfetchStudio GitHub account rename. Preserve verification of existing signed releases with the same pinned repository and publisher IDs.
- Introduce the Shadowfetch and ShadowCode trademark policy, update the project introduction, and show publisher, website, repository, and contributor information in About.
- Preserve host terminal job control, resizing, Ctrl-C, and cleanup through a host PTY relay.
- Build the native desktop and CPU/Vulkan llama.cpp runtime inside GNOME SDK 50 and export a single-file Flatpak. Host Git, terminals, and installed coding CLIs are reached through an explicit host bridge.
- Prevent remote projects from overlapping private profile directories, including a parent folder or an inherited desktop conversation.
- Remove secret-file contents from aggregate diff hunks and correctly decode Git-quoted filenames.
- Update source-map-js to its patched version.
- Flatpak uses its own application profile. Agent shell commands require host bubblewrap; host-name allow-list mode is refused in this package.
- This is a local build; publication and Flathub submission are separate steps.
- The window no longer grows each time it opens. On Wayland desktops such as KDE Plasma, every launch opened the window about 52 px wider and 99 px taller, until it no longer fit on the screen. The window draws its own title bar there, and the saved size included that title bar and the window's shadow, so restoring it added them again. ShadowCode no longer remembers the window's size on any desktop, so it opens at its default size, fitted to the screen. It still reopens maximized or full screen if you left it that way, and on X11 at the same place; on Wayland the desktop chooses where the window opens. A window that already grew opens at its normal size again.
- The window fits small screens. The window opened at 1380x920 even on a 1366x768 screen, so the composer and status bar sat under the panel. It now opens at no more than 90% of the screen, title bar included (1229x691 on a 1366x768 screen), and still at 1380x920 on larger screens. On X11 it fits the screen it reopens on, and a window last left low on the screen moves up until it fits. On Wayland, where the desktop picks the screen, it fits every screen. It opens maximized only when no screen can hold the smallest window (520x640). A window that was maximized when you closed it opens maximized again.
For people starting out:
- Free models first. Until a subscription is connected, the picker lists the free models on this computer first (Free · your code stays on this computer).
- What went wrong, in plain words. A task that fails for a common reason (key refused, out of credits or allowance, conversation too long, unknown model, rate limit, provider trouble, local model not running or failing, offline) explains it and offers the next step: Try again, Continue on another model…, Choose a model or Open Local models.
- Words you'll see. Help (
?) explains worktree, checkpoint, rewind, context, tokens, hunk and more; some words in the app show their meaning when you point at them. - Approvals you can read. Every approval card says in one sentence what
the action does, how much it can affect (Read-only to Needs admin) and
whether Rewind can undo it. A real shell parser reads pipelines,
&&lists,$(…), heredocs,sudoandbash -c; subscriptions' requests are explained the same way.
Safety and trust:
- Always allow here for exact test, build and lint commands, per project and revocable; never for anything that deletes, installs, uses the network, rewrites history or runs outside the project, and never for Codex, which asks only to leave its sandbox.
- Secret checks before every commit, push and pull request from ShadowCode (Remove from commit, Add to .gitignore, Commit anyway); binary key files, PEM/OpenSSH/PGP private keys and merge resolutions are covered, a check that can't read everything says so, and Push anyway sends only the commits that were checked. The agent's own commits never include a staged secret.
- Project Git hooks are asked about once per project, and again when a
hook or a hook tool's settings (
package.json,.pre-commit-config.yaml,lefthook.yml…) change; new packages are looked up on npm, PyPI and crates.io (does it exist, how new is it, is it one typo from a popular name); lockfiles are summarized. - Keys in the system keyring. Settings › Accounts › Where your keys are kept moves API keys into the Secret Service keyring (GNOME Keyring, KWallet, KeePassXC) and back; the private file stays the default. Backups with API keys include the keyring's keys.
- Small Git-ignored files that are costly to lose (
.env, local databases, keys) are saved before each step and restored by Rewind. - Heads-ups when a task skipped or deleted tests, removed assertions, changed CI or switched off a check. Only change these keeps a task to the files you @-mentioned.
Real work:
- One rulebook for every agent. Your profile's rules, skills, commands and agents reach ShadowCode's agent and every subscription CLI through each CLI's own per-run option (Settings › Rules & skills, skill checker, starter skills, import from Git).
- Second opinions. Review staged changes or one task with another model before committing, with findings on the lines they concern and Ask the agent to fix this; Ask another model checks an answer. Reviewers never edit files.
- Roles. A model or subscription per step: plan, implement, review (Settings › Roles, More › Roles).
- Spending limits for paid models (ask at $1 a task and $10 a day by
default; the GitHub Action's
max-costinput sets its limit), a price estimate before sending, Provider busy, retrying (2 of 5), Resume at a plan's reset time, Try on… another model, and Run details for every task. - Stuck detection pauses a task that fails the same way three times or
edits a file back and forth (Keep going, Give a hint, Try
another model, Stop); automations and editor tasks are told to
change course instead.
/compact [what to keep]shortens the conversation whatever its size, and/pinkeeps what matters through shortening; local models' malformed tool calls are repaired. - Large projects. The code index is kept between runs, covers up to 250,000 files, fills in progressively and can focus on one folder.
- Review by risk. Changed files are grouped (config and CI, dependencies, source, tests, generated, docs); Explain this change describes one file's change in plain words, on request.
- Worktree tasks can start from another branch and get setup commands,
copied files (such as
.env), teardown commands and their ownPORT. - A test caps what ShadowCode adds to each first request (system prompt and tool definitions) at today's size plus 10%.
Reliability:
- Your data. Settings › Your data (and
shadowcode backup,restore,doctor --repair,reset) backs up, restores, repairs and starts over; upgrades from every release since 0.28 are tested against saved profiles, and a newer profile is never opened by an older version. - A stable, checked API contract (
docs/API_CONTRACT.md) for 1.x. - A local model that runs out of GPU memory offers a smaller context or another model; a task that fails before any output ends cleanly with its reason; subscriptions' usage is kept when a turn fails; Rewind of a subscription turn keeps the files you saved during it; a window render error shows a reload screen.
- A rotating, redacted app log is included in health reports.
- The real-window test runs in a private Wayland session.
For people starting out:
- Start with no account. If no model is ready after you open a project, the first run offers a free model to run on this computer (recommended for your memory and graphics card, with its size and download time), an OpenRouter key, or a subscription.
- Free models built in. Settings › Local models lists five Apache-2.0 models, from Granite 4.2 3B (2.1 GB) to Qwen3.6 35B-A3B (19 GB), each pinned to an exact Hugging Face file and checked with SHA-256. Downloads start only on click, can be paused and resumed (even after a restart), check disk space first and stop in offline mode. gpt-oss now runs from its upstream file.
- Updates you can see. At most once a day ShadowCode asks GitHub for the
newest release (no identifiers sent) and shows a quiet notice with the right
way to update. New Settings › About shows version, commit, install
type, license and NOTICE. Distributions can switch the check off in
/etc/shadowcode/policy.yamlor at build time.
Everyday use:
- A calmer composer. Reasoning effort, Compare and Worktree move under
More (Escape or an outside click closes it);
Ctrl+Shift+Enterstill starts a worktree task. Unavailable options say why. - Polish everywhere. Errors read as plain sentences with Try again;
Escape closes every dialog and shortcuts no longer act behind one; the
status bar says "Not connected" when the engine is down; the drawer's
Tasks panel has keyboard-reachable Rename, Fork, Export and a confirmed
Delete; a sidebar hidden by a narrow window comes back;
/newkeeps typed text until the new task opens. Every screen passes axe in light and dark. - Visible task summaries refresh their check results together in one batched request after edits.
Vendors, verified live on current releases (Codex 0.158.0, Claude Code 2.1.284, Cursor Agent 2026.09.26, Grok 1.0.41, Antigravity agent server 1.2.1):
- Claude Code lists its real models, honours effort through
--effortand shows its 5-hour and weekly usage in Allowance. - Codex applies effort on follow-ups and no longer warns on every resume; Grok switches models on resumed conversations and takes an effort setting; a Cursor "Upgrade your plan" reply ends as a plan limit; replies no longer run together after a tool call.
- OpenRouter shows your account balance and explains refused requests with the provider's own message.
Reliability (each fix has a regression test):
- Rewind and Undo never delete files that existed before a task, and rewind restores permission changes.
- Automations, write subagents and cleanup keep any worktree that still holds work; subagent usage counts toward the parent task and subagent conversations are deleted with their parent.
- Long answers from slow local models are no longer cut off after ten minutes, and a CPU-only machine may take up to 15 minutes to start answering a long prompt; a taken port no longer moves a model to the CPU; local tasks in different projects no longer block each other.
- Compare lanes never continue on another model after a plan limit; hung
language servers, runtime wrapper scripts, stalled downloads, background
save errors, remote address changes and cancelled sign-ins can no longer
hang or leave processes behind.
shadowcode acpfollows progress through push events; the voice model is freed after five idle minutes.
Security and privacy:
- Secret files can no longer be read through odd spellings or symlinks; keys are redacted from stored terminal, slash-command and hook output; @-mentions skip secret files.
- "Allow for this task" no longer covers wrappers, interpreters or
git -c; ShadowCode never runs a repository's own Git filters and stays out of nested repositories. - Remote access answers only its own host names (no DNS rebinding) and every
API family has an explicit remote-access decision; the Landlock fallback
restricts Unix sockets and signals; the network allow-list judges
IPv4-mapped IPv6 correctly; a local conversation never starts a cloud
subagent.
cargo auditandnpm auditreport no known vulnerabilities.
Packaging:
- The Debian package passes lintian with no errors or warnings: copyright and
NOTICE, changelog, man page, bash/zsh/fish completions (also
shadowcode completions), icons at every size, correct dependencies, and purging it leaves your data in place.docs/DISTRIBUTING.mdexplains how to verify, ship and configure ShadowCode. - Richer AppStream metadata, validated strictly on every package build.
- The AppImage build uses the pinned, source-built runtime instead of upstream's newest.
Release run 36507326107
at 206fd03 passed native-source but stopped in the required
native-window gate. On a clean CI host no model is ready, so the welcome
offers a free model, an OpenRouter key or a subscription instead of
"Choose a model"; the window test only knew the second case. The test now
checks both. Nothing was signed or published; the v0.34.1 tag stays
unchanged, and 0.34.2 ships the same changes.
Release run 36499751141
at 3409d59 stopped in the required native-source gate: every Rust test
passed, but two new opt-in network tests (the Hugging Face catalog check and
a multi-GB download) were not on the gate's list of allowed optional tests,
and the gate refuses any unlisted skip. Nothing was signed or published. The
v0.34.0 tag stays unchanged.
- Runtime builds and notices refreshes preserve tracked source pins and reference metadata; actual build provenance stays in generated runtime output. Regression coverage reproduces the source-integrity failure that stopped the unpublished 0.33.0 attempt.
- Code highlighting, line numbers, undo/redo and recoverable editor drafts, with revision-checked saves and newline preservation.
- Bounded attached-context inventory with exclusions, truncation notices and approximate token counts.
- Run a check… from completed tasks: explicit commands, existing approvals, fresh output and verification receipts, no model selection or extra model turn, and preserved composer drafts.
- Independent provider sign-in recovery after navigation; cancellation remains Stopping… until acknowledged. Cached account state survives uncertain progress reads, and refresh waits for ongoing sign-ins.
- Safer Compare snapshots and recovery, unsaved-draft guards, and coordination of short workspace writes across cooperating ShadowCode processes.
- Shared native event listeners prevent per-task listener growth. A real source-built X11 endurance run passed 100 tasks after bounded warm-up; this is not GPU or physical Wayland endurance evidence.
- AppImage launch preserves an explicitly selected display backend; package normalization accepts only the exact expected linuxdeploy version field.
- Authenticated installer recovery and staged release verification are strengthened. Version 0.33.1 was published on September 28, 2026 from
e15c448, after all 15 required build gates and protected signing passed. The workflow publication job failed on a transient draft-listing response; publication resumed locally with the same frozen publisher and signed artifact, with all seven remote assets compared before publication. See the release notes for the exact evidence and remaining limits.
See release notes for scope and remaining qualification.
Release run 36414378697 at 9e385cb failed the managed-runtime source-integrity gate after the runtime built and its six tests passed. The builder rewrote tracked runtime pin/COMMIT timestamps. Signing and publication were skipped. The existing v0.33.0 tag remains unchanged; the separately qualified successor is 0.33.1. Earlier local 0.33.0 package and latency results remain evidence for those exact bytes only.
Everyday use:
- Composer.
@searches project files and folders (local and OpenRouter models read their contents; subscription CLIs get@path) and lists subagents. ↑ recalls earlier prompts, a Code / Plan / Ask switch sets the mode, and an effort control appears for models that support one (OpenRouterreasoning.effort, Codexmodel_reasoning_effort, Claude Code thinking budget, local thinking switch). - Message actions. Edit & resend (a fork, optionally rewinding later file changes), Retry and Copy on your messages; Copy and Fork on answers.
- Approvals show the change. File changes show a diff (or the new file),
commands show the full command and folder. "Allow for this task" grants the
same kind of action until the task ends (never for chained,
sudo, deleting or history-rewriting commands); "Deny with note" sends a reason. - Per-task Review. A full-width view of just the files a task changed, unified or split, with Keep / Undo per hunk and per file and Undo all.
- Safer rewind. Rewind asks first, marks the conversation and can be undone. It now also covers files changed by shell commands and by subscription CLIs (Codex, Claude Code, Cursor, Grok, Antigravity), through hidden checkpoint commits that never touch your index.
- Parallel tasks. Worktree next to Send (Ctrl+Shift+Enter) runs a task in its own copy of the project; Apply (checked first, conflicts listed), Keep as branch or Discard when it's done.
- Notifications for approvals (with a warning before one expires), failures, plan limits and finished tasks; clicking one opens the conversation. Sidebar badges for running, needs approval, failed and unread; a right-click menu; Alt+↑/↓ and Ctrl+Tab.
- Context and cost chip for every model, e.g.
42% · 38k / 128k · $0.12, with a breakdown on click. - Real terminal. Your own login shell on a pseudo-terminal (xterm.js), with tabs, kept while you switch tabs or the agent works; never shown to a model.
- Git tab. Create or switch branches, an editable suggested commit
message, push with your own sign-in, and pull requests through
ghorglabwith live CI checks (or the web compare page). - Tools tab in the drawer for Goals, Background processes, Worktrees, Automations and Issues; Settings › Advanced keeps configuration only.
- Preview. The drawer's Preview tab finds the project's dev servers and shows them through a private loopback proxy (phone, tablet and desktop widths; hot reload kept). Pick element sends an element's selector, text, role, size, key styles and HTML to your next message; page console errors can be attached too. Unavailable over remote access.
- Voice input. Hold the mic button (or Ctrl+Shift+Space) to dictate into the composer with whisper.cpp on this computer; models (74–141 MB) download only on request. OpenRouter transcription is optional and off by default.
A smarter agent (ShadowCode's own loop for local, OpenRouter and API models):
- Subagents.
spawn_agentruns read-onlyexplore,planandreviewhelpers, orgeneral, which edits an isolated worktree and returns a diff the agent applies with your approval; up to four at once.@nameruns one. Agent definitions from.shadow/agents,.claude/agents,.opencode/agent. - Reads other tools' files:
CLAUDE.md, nestedAGENTS.md/CLAUDE.md, Cursor rules, Claude Code commands and skills; the agent loads skills on its own. MCP tools are offered directly asmcp__server__tool, and enabled servers are passed to Codex, Claude Code, Cursor, Grok and Antigravity. - Code intelligence. Persistent language servers (rust-analyzer,
TypeScript, Pyright, gopls, clangd) report the errors an edit introduced;
go-to-definition and references; tree-sitter index for Python, Go, C, C++,
Java and JavaScript; a ranked repo map;
search_codewith keyword (BM25) and optional embedding search through the bundled llama.cpp. - Long conversations are summarized by the model instead of cut; prompt caching for Claude and Gemini on OpenRouter; per-task tokens and cost; retries on rate limits, overloads and dropped streams (never repeating a tool); full tool descriptions for large-context models.
Safety:
- Real shell sandbox. Commands see an empty home folder with read-only
toolchains; SSH keys, cloud credentials,
~/.configand ShadowCode's keys are never visible; only the project is writable. "Require sandbox" refuses commands without bubblewrap; otherwise Landlock applies with a warning. Shell network can be off, on, or limited to an allow-list enforced by a private network namespace and filtering proxy.
Beyond the window:
- Remote access. Settings › Remote access (or
shadowcode serve --remote) serves the interface to a phone or another computer: off by default, loopback unless you choose an address, QR pairing with a key per device, secrets hidden. Terminals work remotely only if you allow them; the host computer's microphone never does. Optional ntfy phone notifications. - Editors.
shadowcode acpruns ShadowCode as an Agent Client Protocol agent for Zed, JetBrains and other ACP editors, with its models, modes and approvals. - Automations. Scheduled prompts (hourly, daily, weekdays, weekly or
cron) in fresh worktrees, with catch-up, history and cost. "Start from an
issue" turns a GitHub or GitLab issue into a task and a closing pull
request. A GitHub Action runs a checksum-verified release headless from an
issue comment or label (
shadowcode run --approval approvefor disposable runners).
Under the hood:
- The application router is split into per-domain modules with typed requests; database work no longer blocks async workers; Compare state is updated transactionally.
- The window is split into hooks and components, reads one push feed instead of polling, keeps drawer state per project, and the light theme is really tested.
- License changed from MIT to Apache-2.0. A new
NOTICEfile credits Shadowfetch as ShadowCode's original creator; copies and derivative works must carry it (section 4(d)). The AppImage and deb ship it asShadowCode-NOTICEnext toShadowCode-LICENSE, and the package check requires it. Releases up to 0.31.0 remain available under MIT.
- Allowance. A status-bar button and panel (
GET /api/allowance) list each subscription's reported usage windows and reset times, OpenRouter credits left on the key, and local models ready to run. Only reported figures; states are ok, low (10% or less), limit reached, usage not reported, not signed in, not installed, offline and no key. - Keep going on a local model. When a subscription reports its plan limit,
the same conversation continues on a local model (
limits.on_limit:local, the default, orask;limits.fallback_modelpicks the model, otherwise the last local model used in the project, then the first ready one with tools). The conversation says "Codex reached its plan limit. Continuing on qwen3:14b on this computer." or why it could not. ShadowCode never retries on the same plan or buys more usage. - Compare.
POST /api/compareruns one task on 2 or 3 models, each in a managed worktree from a snapshot of HEAD plus uncommitted work (taken with a temporary index; the checkout and index are untouched). Keep applies one lane's diff to the working tree only aftergit apply --check; conflicting files are listed and nothing changes. Lanes are removed after keep or discard, and a per-project scoreboard counts wins. UI: Compare button next to Send, a Comparisons view with lanes side by side, lane conversations, and keep/discard/stop. - Lane conversations are hidden from the sidebar and never become a project or the folder reopened at startup.
- Live harness:
--allowanceand--compare <id>.
- Web toggle for OpenRouter rows. The 0.29.0 notes said OpenRouter tasks could use web tools, but the composer only showed Web for local rows. It now appears for OpenRouter rows too, and those rows no longer show the vendor-CLI note ("runs its own tools…"), since they run on ShadowCode's own loop.
OPENROUTER_API_KEYis removed from vendor CLIs. A key set in ShadowCode's environment was inherited by subscription CLIs; it is now on the same removal list as the other provider keys.- Secret scan.
scripts/check-secrets.mjsfails on real-looking API keys, private keys or a tracked.env/secrets.env(and, with--value-file, on an exact value without printing it). It runs in the Checks workflow. - Docs brought up to date for OpenRouter, Antigravity's agent server, the live test harness, data locations, API contract and test counts.
- Antigravity prompts wait for the model switch. Checked against the real
server after sign-in: a prompt sent while
session/set_config_optionwas still pending ended at once with no output. Prompts now wait for the switch (Cursor'ssession/set_modeltoo). A live task randate +%Ythrough a ShadowCode approval and answered; a follow-up resumed the same session. - Answers from subscriptions appear once. Vendor turns now send
model.stream_end, and the final result no longer repeats a reply with the same text, including in older conversations. - "Using Cursor · Auto · Cloud" instead of "Using auto · Cloud": the model note names the product, as the picker does.
- Quiet summary for answers. A finished task that changed no files and ran no checks shows one line ("Finished · 7s · No files were changed.") without a Review changes button, which now appears only when there are changes.
- Antigravity runs through Google's official ACP agent server (the
antigravity-acpentry in the ACP registry) instead ofagy's print mode. It now sends permission requests, so ShadowCode's approvals apply to its commands and edits, it accepts images, and it resumes sessions withsession/load. Models come from the session'smodelconfig option and are switched withsession/set_config_option. - Install from Accounts. The server is downloaded only when you choose
Install (334 MB from dl.google.com, size and SHA-256 pinned), unpacked
into
~/.local/share/shadowcode/antigravity-acp/1.2.1, and can be removed again. A built-in unzip handles the archive. - Private sign-in. The server keeps its Google sign-in in a profile owned by ShadowCode. Connect opens the browser and relays the link; Disconnect deletes the profile. Status checks and tasks can't open a browser: a printed sign-in link marks the row Sign in, and a task stops with that message at once.
- Clean launches. Each launch gets its own temp directory, removed
afterwards, and runs without Google API-key or cloud-project variables. On
hosts without an IPv6 loopback, the server's own
--enforce_kernel_ipv6_support=falseswitch is passed. - Questions the server asks through the permission channel are skipped with a note for now.
- OpenRouter API keys. People without a subscription can paste an
OpenRouter key in Settings › Accounts ›
OpenRouter and pick any of its text models from a new API keys group
in the picker, labelled as billed per token. The key is checked with
OpenRouter before it is saved to the profile's private
secrets.env, and is never shown again. Rows show price per million tokens, Vision and Chat only from OpenRouter's model list. Tasks run on ShadowCode's own agent loop, so permissions, approvals, checkpoints, the Web toggle, image attachments and review all apply. Offline mode turns the rows off. The group sits below On this computer, so a search that matches both picks the free local model. - Web search works again. DuckDuckGo refuses ShadowCode's honestly
labelled requests with a bot check.
web_searchnow falls back to Marginalia Search's public API instead of returning nothing, and reports both reasons if that fails too. - VPN DNS no longer blocks sites. Some VPN resolvers (NordVPN) answer
names such as
www.google.comwith an address in 192.0.0.0/24, whichweb_fetchrefused as reserved. Only that block's special-purpose hosts are refused now. - Antigravity no longer reports an empty success.
agy's headless mode denies any tool it would ask about, because it can't ask ShadowCode. When that leaves it with no answer, the task now fails and explains why.
- Settings › Accounts is shorter. Each card is headed by the product name (for example Codex), shows the version once, and puts the signed-in email and plan on one line. Ready accounts no longer repeat the status text or the usage reason. With reported rate-limit windows, the usage list is built from the structured snapshot, so reset times stay current and nothing appears twice. Credits appear only when the vendor says the account has some. Sign-in hints read "Choose Connect to sign in on 's page", with the official command as the alternative.
- Reset times round correctly. A window resetting in 2 h 59 min 50 s reads "resets in 3h", not "2h 60m".
- Stopped tasks are quiet. A task you stop that changed nothing shows one line ("Stopped · 2s · No files were changed.") instead of a red card. A partial reply is kept without an "Interrupted response" label, and no "Needs attention: Model request cancelled" note is added.
- A newly added local model always appears in the picker. Overlapping picker refreshes could let an older, slower answer replace a newer one; only the newest answer is applied now.
- Local model names come from the model. File-based GGUF rows use the
file's
general.name, plus the quantization from the file name when there is one (for example Qwen3 14B · Q4_K_M). Files without a name keep the file name; Ollama imports keep their tag. - Layout fixes. Notifications appear at the top centre, clear of the composer and the drawer's close button. The Settings navigation no longer wraps "Permissions & network". The drawer close button is a 32 px icon button.
- Onboarding no longer probes providers.
GET /api/onboardingreturns the folder and permission defaults only; it no longer starts local-server or vendor checks the window never shows.
- One composer picker, filled from
GET /api/picker. It has Subscriptions (Codex, Claude Code, Cursor, Antigravity, Grok) and On this computer (GGUF) groups. Routing uses stable IDs (cli:<vendor>[:<model>],local:gguf:<hash>). Rows show Local or Cloud, availability, Vision and Chat only badges, and usage. The selection is stored per conversation. - Vendor runtimes use official interfaces. Codex runs through
codex app-server. Claude Code runs throughclaude -pstream-json with host permission prompts. Cursor runs throughcursor-agent acp. Antigravity runs throughagy --print=stream-json (rewritten to the documented event protocol). Grok runs throughgrok agent stdio. Sign-in, models and image support come from each vendor's documented status commands or protocol handshakes, never from credential files. The non-existentcodex modelspath and the fake "Codex · Auto" row are gone. - Accounts page. Connect runs the official login command and relays its
URL or device code. Disconnect runs the official logout after a
confirmation, then clears cached status, stored usage and vendor sessions.
Antigravity sign-in and sign-out stay inside
agy. - Usage shows only reported figures. Codex shows rate-limit windows per quota pool, with plan, reset times and credits when reported, including updates pushed during a turn. Claude Code, Cursor, Antigravity and Grok show Usage unavailable with the reason. Usage snapshots are stored in SQLite (schema 25, backed up before migration). API-key logins are labelled API key login · billed per token.
- Plan limits stop the job. When a vendor reports its plan limit, the job
stops with the new status
limit_reached. ShadowCode doesn't retry. - Provider API keys are removed from vendor CLIs.
OPENAI_API_KEY,ANTHROPIC_API_KEYand similar variables are removed from every vendor task, login and logout. - Native sessions resume per conversation (
thread/resume,--resume,session/load,--conversation). - Switching providers needs consent. Switching provider mid-conversation sends a bounded handoff (at most 12,000 characters). Before local content or first images go to a cloud route, a consent dialog asks first.
- The local engine reads GGUF metadata. It gets the architecture, context,
chat template and projector from the file. Compatibility comes from the
runtime's
architectures.txt. The memory plan sizes the context to VRAM or RAM and accounts for per-layer KV heads and sliding windows. - Bundled llama.cpp runtime. A pinned llama.cpp (Vulkan module plus every x86-64 CPU variant) ships in both the AppImage and the deb, with its license notices. One model is loaded at a time. The server gets a per-launch key and has no web UI. If the GPU start fails, it retries once on the CPU. A task's lease prevents swapping the model mid-task. Load and Unload are in Settings › Local models.
- Ollama import by reference. Models from an existing Ollama store are imported without copying and without the daemon.
- Local vision. Vision on local models comes from the paired projector, and
vision models get a
view_imagetool. - Web tools for local models.
web_fetchandweb_search(DuckDuckGo HTML, sent as POST) block private networks. They pin DNS, re-check redirects, and limit time and size. Sources appear in the activity timeline. - Network modes online, web off and offline. Offline starts no vendor process and refuses cloud jobs.
- Permission modes. The user-facing modes are Ask before actions and Allow project edits, and older configs are migrated. New installs start in Ask mode. Each vendor's enforcement is explained in Settings. Read-only tasks deny vendor approval requests automatically.
- Safety. Stored tool and approval events are redacted. The trust gate covers every entry point, goals included. Control sockets left by dead engines are removed at startup.
- Interface. A quiet welcome with three suggestions. The activity timeline and the task summary are built from recorded events. Settings are split into Accounts, Local models, Permissions & network, Appearance and Advanced. Skills, goals, background processes, health, MCP, plugins, hooks, worktrees and Guardian moved under Advanced. Dead controls were removed (mode tabs, vendor chip, old model chooser, thinking card, custom model dialog).
- Installer.
scripts/install-appimage.shtakes the llama.cpp runtime from the AppImage, checks it, and swaps it into~/.local/lib/shadowcodeatomically, with rollback.SHA256SUMSis required unless--unverifiedis given. - CI. CI builds the managed llama.cpp before packaging and verifies the
runtime in both packages. The release checks
ui/package.jsonand the desktop entry against the tag. - Removed. The legacy 0.19 Python harness is gone, along with its pytest
suite, packaging and
serve-test-ui.py. The Playwright suite now runs againstvite previewwith a fake engine. Historical release ledgers moved todocs/archive/.
- Local GGUF rows load through a ShadowCode-managed llama.cpp runtime
(
~/.local/lib/shadowcode/llama-server). The engine prefers that binary over PATH. It does not start Ollama or LM Studio. Removing a catalog entry still never deletes weights. One GGUF is loaded at a time. - Codex, Claude Code, and Cursor now receive real image bytes on their official
interfaces (Codex
localImage, Claude image source blocks, ACPimage). Antigravity still rejects attachments because its stream-json input does not document image blocks. Local GGUF vision is enabled only when an mmproj companion file is present. - CPU llama.cpp is compiled from a pinned upstream commit and installed with the AppImage. Models are never auto-downloaded.
- One searchable composer picker with Subscriptions and On this computer. Rows are Codex, Claude Code, Cursor, Antigravity, and local GGUF/Ollama compatibility targets. Routing uses stable IDs, never display names.
- New Cursor ACP adapter (
cursor-agent acp) and Antigravityagystream-json adapter. Grok remains available but is not featured in the primary menu. - Usage labels are truthful: unknown is "Usage unavailable", never a made-up percent. Local rows say they run on this computer with no subscription quota.
- Local GGUF catalog: add a file or folder you already have. Removing an entry does not delete weights. llama.cpp is optional and not auto-downloaded.
- Images attach only when the selected route actually supports vision. Vendor CLIs reject images until the adapter forwards real image bytes.
- Quieter home: four suggestion chips, compact tools control, activity timeline. Provider chip stack and permanent Build/Plan/Review/Test tabs are off the default composer. Settings leads with Accounts and Local models.
- Welcome Banner: redesigned empty-state with 8 smart starter cards (Build a feature, Fix a bug, Explain this codebase, Write tests, Review my changes, Plan a refactor, Security audit, Optimize performance). Each card populates the composer and sets the correct mode in one click.
- Mode Tabs: replaced the cryptic "Build/Plan/Review/Test" dropdown with
accessible
role="tablist"icon-tabs that show a hover description of exactly what each mode does. - Header declutter: consolidated the "20-Min Flow" and "Open Weights" text pills into clean icon-only buttons — less noise, same functionality.
- Context bar: replaced the "Context X% · Ntokens" text in the status bar with a compact 48 px visual fill-bar that shows remaining context at a glance (turns danger-red above 80%). Full detail is available on hover.
- Status bar cleanup: removed the model name from the status bar (visible in the composer model picker) and moved the git branch inline for less clutter.
- CSS micro-polish: composer ring glow on focus; send-button subtle
scale-up/down on hover/active; suggestion cards lift on hover; smooth
fade-upanimation on the welcome banner; improved font rendering. - Dark mode parity: all new components (WelcomeBanner, ModeTabs, starter cards, ctx-bar) have matching dark-mode tokens and no flash-of-wrong-colour.
- Mobile: starter-grid collapses to 2-column below 540 px; mode tab labels are hidden on very small screens (icons remain).
- Vendor CLI agent backends: spawn the official Claude, Codex, or Grok CLI in a
trusted workspace. ShadowCode never reads, stores, or proxies vendor OAuth
tokens. Login remains
claude auth login,codex login, andgrok login. - Codex uses
codex app-serverJSON-RPC, withcodex exec --jsononly when app-server is unavailable. Grok uses ACP (grok agent stdio). Claude uses headless stream-json. Vendor tools and sandbox stay with the vendor; Pause and Steer interrupt and follow up. Rewind does not apply. - Doctor reports not installed / not logged in / ready without printing credentials. The model picker groups local vs vendor agents; knobs live in Settings → Advanced, including a Claude adapter disable flag.
- Anthropic policy note: third-party clients may not use Pro/Max OAuth tokens
directly (enforced 2026); driving the official
claudebinary with the user's login is currently tolerated but not guaranteed.
- Verification gate: the last test/build/lint command decides. A deliberately
observed failing test before a fix no longer prevents the final passing run
from counting as verified;
verification.summaryreportsred_greenwhen that sequence was observed. A failure after the last passing check still blocks it, and model prose never upgrades the claim level. - Bug-fix policy matches whole words; prompts about a "prefix", a "fixture" or "debug logging" no longer receive the failing-test-first instruction.
- Pausing a queued task is rejected before the steer control is flagged. A rejected pause previously parked the task forever once it started running.
- Parallel plan cleanup recovers when a worker checkout was deleted by hand: the stale Git record is pruned, the worker is listed as missing, and every branch is retained. Integration checks name the missing checkout.
.env.example,.env.sample,.env.template,.env.distand.env.defaultsare readable; their contents still pass through redaction.- Symbol index touch removes deleted files by their normalized path.
- Steering strip: one Steer action pauses at the next boundary and records the instruction; the toast states the task stays paused until Resume. Removed an unused prop.
- A failed scratch-directory cleanup after a sandboxed shell command is reported in the tool result instead of discarding the command's output.
- The AppImage installer records
X-ShadowCode-GitShain the desktop entry (fromSHADOWCODE_GIT_SHAor the checkout it runs from) and no longer duplicates the line on reinstall. - User guide documents the verification gate and secret redaction; parallel workspace docs describe missing-checkout recovery. Version bumped across crates, desktop, UI, Python package, desktop entry and docs.
- Preserve the caller directory and relative project/profile paths in AppImage launches. Replace the generic launcher that selected the extraction directory and injected nonexistent Python and GStreamer paths. External Python tools remain usable without bundling Python.
- Verify both extraction modes, relative paths with spaces and external Python
execution in packaged runtime checks. Install both
shadowandshadowcodealiases from the same verified release.
- Retain the selected Cargo home when sanitizing packaging PATH, so clean Rustup-based runners can invoke the compiler and package manager. Add compiler discovery and unsafe-node-link regression checks. Includes the native 0.22 workflow and reliability upgrade below.
- Fix clean-build CI ordering: build the real desktop executable before running process-death and reconnection tests. Repeat qualification through the release workflow before publishing. Includes the 0.22 upgrade described below.
- Native desktop controls for context windows, Ollama residency, response forks, parallel workspace preparation and combined integration checks.
- Durable, workspace-scoped parallel plans; cleanup refuses dirty or active checkouts and retains worker branches. Git filters and custom merge drivers cannot execute through these operations.
- Event forks retain completed tool context, exclude later turns and reject events belonging to other sessions. Original deletion preserves fork context.
- Rewind waits for a confirmed pause boundary and reserves idle workspaces; in-flight commands and other tasks cannot race checkpoint restoration. Task pause/resume controls are distinct from goal scheduling controls.
- Attached windows close promptly during owner reconnection and retain live event notifications across engine replacements and subsequent disconnects.
- Private AST cache with path confinement, content hashes, Unicode-safe signatures, deletion refresh, exact-name priority and syntactic call sites.
- Managed temporary scratch cleanup, corrected project mount order, operational bubblewrap probing and no automatic shell replay after an execution failure.
- Guardian state and proposal approvals scoped to profile/workspace. Diagnostics and draft proposals now accurately describe their limited behavior.
- Validated Ollama residency, numeric unload/indefinite wire values and saved routing preferences. Removed unused prompt hash computation.
- Fixed Ctrl+N after session activation and shortcut modifier overlap; improved model badge contrast in light, dark and dimmed dialog layouts.
- Split Markdown rendering into a separate UI bundle. Updated Happy DOM to a patched release and declared the supported Node minimum.
- Updated native build, packaging version, regression coverage and feature docs.
Crate, Tauri, CLI, AppImage, and Debian versions are 0.21.0. Rebuild packages from this tag; existing 0.20.0 AppImage/Debian filenames are stale.
- Long sessions keep an inspectable layered budget and a structured keep-list (intent, constraints, decisions, failures, plan). Compaction is still deterministic history truncation, not a model-written summary. Compact must not replace a request that already fits the hard 256-token reserve with a keep-list note that no longer fits; the 4096-token tester route was not raised.
- An attached desktop can reattach to a replaced engine process without starting jobs or replaying tools. GET/event catch-up is retried; mutating POST is not.
- Crash recovery classifies replay: reads may be repeated, shell and Git
history need confirmation, file mutations and
git_reset/git_cleanare never auto-replayed.recover_jobsmarks interrupted work and does not execute tools. - Tool results that hit a byte or range budget set
truncatedand a model-visible note (next_offsetonread_filewhen applicable). - Autonomy caps are named profiles that never raise the configured limits. Repeated identical tool calls warn, ask for a replan, then pause. Changing arguments continue.
verification.summarydistinguishes model claim, observed tool evidence, and verified commands. Prose such as “tests passed” is notverified.- Provider streams treat malformed JSON as an error, synthesize missing tool ids without inventing text, and do not execute tools on HTTP 429/500.
- Destructive Git stays behind elevated permission plus approval. Relocated worktrees are not guessed.
- Doctor and local stats stay on the machine. There is no product telemetry upload.
- Packaging constructs its own PATH and ignores host
/usr/local/binand Hermes node hijacks. The caller does not sanitize PATH. - The live-WAL interoperability test drives the writer with system
python3and stdlibsqlite3. It does not require Node 22node:sqlite(Ubuntu/usr/bin/nodeis often 18). - Shell execution is a lexical word list. It is not an OS sandbox. Checkpoints cover native file-tool changes, not arbitrary shell or Git side effects.
- Local models receive explicit runtime capability guidance and a read-only
system_infotool for grounded OS and connected-display answers. Incomplete host detection is represented as unknown; greetings do not trigger tools.
-
0.21 autonomy (feature branch): inspectable context budgets, structured compaction keep-lists, replay classification, progressive loop warn→replan→pause, named autonomy caps that never silently kill, claim vs observed vs verified completion, local Doctor store metrics, engine-process auto-reattach that does not retry mutations, explicit tool-result truncation notes, and worktree recovery that refuses path guessing. Not released. Package version remains 0.20.0.
-
Independent audit: Markdown keeps only fragment and credential-free http(s) links clickable; compatible streams continue unindexed tool-argument deltas and ignore repeated call ids/names; restart recovery writes a durable interrupted completion event.
-
The desktop previews a very large Markdown response before rendering all of it, with an explicit control to expand the complete durable response.
-
Desktop windows can attach to an existing headless/TUI engine with independent navigation and a visible shared-lifetime notice. Closing an attached window leaves engine-owned work running. A bounded private event feed supports live updates and completion notifications without an idle-window wake timer.
-
Live response updates reuse unchanged Markdown messages instead of reparsing earlier answers and code blocks on every update. Native catch-up combines adjacent fragments of the same response while preserving durable cursors and task/completion boundaries.
-
Native desktop saved-history pages support older/newer/latest navigation without loading thousands of events or tasks at once. Live work continues while browsing; original records remain available through export.
-
Reviewed desktop and CLI repair restores missing managed Git connection files while preserving the original index and local edits, with private recovery journals and refusal of conflicting or lost metadata.
-
Reviewed CLI and desktop copying carries staged, unstaged, binary and regular untracked edits into a new worktree while preserving the source. It rejects stale snapshots and retains partial destinations after failure.
-
Native terminal input uses level-triggered polling after CI exposed dropped keys around resize events. Full-color PTY checks verify Escape closes Help before the next task submission.
-
Reviewed CLI and desktop worktree return prepare incoming commits in the source index without committing. Stale reviews and active work are rejected; conflicts and ignored local files are preserved for explicit resolution.
-
CI now exercises 200 native tasks, stalled-provider cancellations and output floods while checking memory, descriptors, child cleanup and history integrity.
-
Native development: reviewed CLI and desktop rescue for missing worktrees restores retained commits into a new checkout while preserving the original branch, index and registration; missing uncommitted files are not reconstructed.
-
Desktop Settings adds worktree creation, opening through project trust, inspection and reviewed removal. Actions bind to the displayed source project; dirty or stale reviews cannot authorize removal.
-
Managed worktrees support inspection and reviewed clean removal. Dirty/ignored files, detached or locked checkouts, active tasks and background servers block removal. Branches and commits remain; private records are archived after success.
-
Native worktree creation starts an isolated branch from a local commit while preserving source checkout edits. CLI inventory and private recovery records retain visibility into interrupted creation. The complete worktree workflow remains in development.
-
Desktop polling uses compact recent/active job records instead of repeatedly transferring full saved results. Older active jobs remain visible; expanding queued prompts and opening conversations fetch their complete records on demand.
-
CLI conversation and job IDs resolve against the full saved history instead of recent-list limits. Old records remain available for continuation, export, rename and job inspection; default conversation selection is project-scoped. Indexed lookup avoids loading unrelated job results just to resolve a prefix.
-
Native
tuifrontend shares the Rust engine with desktop and CLI: Unicode input, conversation/model/project pickers, task modes, queued follow-ups, explicit approvals, tool cards and paged saved history. Terminal-owned workflows cancel on disconnect while unrelated work in an attached engine continues. Real PTY checks exercise submission, approval, planning and terminal restoration. -
Concurrent desktop/CLI settings changes preserve unrelated fields, project trust, integration grants and secret entries. Read–modify–write operations are serialized through the owning native engine. Rejected updates preserve the saved file; configuration/secret reads reject special files and remain bounded, and writes cannot exceed the size accepted on restart.
-
Native project plugins install reviewed built-in or local JSON bundles into real skills, slash commands, hooks and MCP definitions. Settings and CLI show contents and require current project/content hashes; executable integrations need separate activation. Private journals support interrupted-install cleanup, uninstall preserves local edits, and legacy plugin directories remain intact. Native Python/Linux/iOS workflows replace executable Python plugin loading.
-
MCP registration prints Codex, Claude Code and Cursor configuration for stdio or an existing authenticated HTTP gateway. Output references credential variables without exposing secrets; literal path encoding and option validation prevent accidental configuration changes. Independent official TypeScript SDK 1.x/2.x probes exercise both transports with real native approvals and test jobs.
-
Native MCP serving supports authenticated loopback Streamable HTTP alongside stdio. Both expose the same project-scoped tools, approvals and owned tasks. HTTP reconnects preserve the gateway's jobs; gateway shutdown cancels unfinished owned work while unrelated engine tasks continue. Mandatory credentials, host checks, denied browser origins, bounded traffic and protocol validation apply. The executable probe runs both transports against source and packaged builds.
-
Rust task engine with confined file tools, bounded processes, streaming local and compatible models, scoped approvals, checkpoints, persisted queues, and recovery. Settings and legacy history are migrated with backups.
-
Tauri desktop window embeds the compiled interface and communicates through IPC, without a Python runtime or browser launcher. Native dialogs, external links, window state, notifications, and managed shutdown are implemented.
-
Native profile directories are private to the current account, including existing profiles, without deleting data or changing existing parent-directory permissions. Unsafe profile leaves and lock files are rejected. Notifications keep full text contrast throughout their entrance animation.
-
Native SQLite tools, CLI and MCP queries replace the Python built-in reader, with parameter binding, live WAL support, confined paths, denied SQL writes and bounded/cancellable results. Bundled SQLite is updated to 3.53.2, including its WAL-reset corruption fix.
-
Required task inspection recognizes successful native database reads. Small model contexts can use a shorter, enforced response budget while retaining required input; requests that still cannot fit fail before contacting the model.
-
The native desktop can queue follow-up messages while the current task streams, show waiting work across project conversations and cancel individual queued tasks. Reloads select the running task first; queue cancellation cannot stop a task that has already begun. Sidebar activity and transcript progress now distinguish queued, running and completed work.
-
Native goals preserve milestone results, pause and resume, require recorded inspection/verification for the default checklist, and stop on failed checks. Goal tasks appear live in the conversation; results and progress are accessible from the drawer.
-
Native model routing adds editable Plan/Build/Review/Test selections, explicit task overrides, and recorded selection/fallback notices. Model registration distinguishes identical names on different endpoints and preserves saved credential references and context limits during discovery.
-
Native background processes run development servers and watchers alongside tasks, retain bounded live logs and durable history, honor project permissions, and stop managed child processes when the application closes. Legacy history is imported without signalling stored PIDs or replaying old commands.
-
Models can start project servers under shell permissions and command hooks, inspect bounded status/logs, and request scoped approval to stop them. Plan and Review retain read-only access. Background servers appear in the shared panel and survive coding-task completion or cancellation until explicitly stopped or the owning application closes, with durable task attribution. Background cards use readable labels and explicit start/stop prompts; approval headings wrap on compact windows and warning labels meet light-theme contrast. Following new activity now scrolls before paint, including task submission, so a newly added approval remains in view.
-
Native slash commands run real tasks and terminal actions, persist command cards, and support explicit project skills with source/hash provenance. Skills preserve Plan/Review restrictions and queued instructions; the editor validates metadata and rejects stale saves. Project notes guide subsequent tasks.
-
Native CLI runs tasks without a display, streams ordered event JSON, handles terminal and external approvals, and exposes sessions/export, checkpoints, goals, model settings, skills, and background controls. It shares an open desktop or explicit headless owner through a private Unix connection while keeping project selection independent. Interruptions, broken output pipes, and disconnected manual commands clean up their owned work.
-
Native window automation covers actual tool execution, approvals, reload, cancellation, goal progression/pause, accessibility, and subprocess cleanup.
-
Native lifecycle hooks use reviewed YAML/JSON command definitions with explicit project/content approval in Settings or the CLI. Command/commit gates block failed actions, completion checks drive bounded repair, and persisted results survive reload. Changed definitions require review; read-only tasks keep hooks inactive, and cancellation/shutdown wait for command cleanup. Legacy Python callbacks are surfaced for migration without importing them.
-
File tools explain how to create files with
expected_hash: missingand reject malformed hashes with actionable guidance. Existing read/stale-hash protections remain in force. Completion-check diagnostics are bounded before model repair. -
Ollama requests preserve runtime repair and compaction instructions for model templates that ignore later system messages. Original positions remain labelled, user/tool data retains its role, and saved conversation order is unchanged.
-
Native AppImage and Debian build scripts preserve per-format executable metadata, include versioned dependency notices, and check startup, versions, matching compiled code, notice hashes, and absence of Python sidecars. The packaged AppImage runs the same real-window workflow as the debug executable.
-
Source-built AppImage runtime gives every extraction-mode launch a private directory, forwards shutdown signals, and cleans up after payload exit. Concurrent CLI/window launches preserve each other's resources. The build retains runtime source archives, patches, notices, and compiler provenance; verification checks the packaged runtime code and matching source artifact.
-
Manual native-window probes with installed Ollama models cover minimal coding edits, visible command approval, independent verification, saved continuation, cancellation during actual streaming, checkpoint rewind, and process shutdown.
This development branch is not yet the replacement release. Remaining integrations, broader stress checks, packaging, and installation are tracked in the migration gates.
- Persistent project/task sidebar with search and pinned tasks.
- Refined light and dark surfaces, responsive composer, consistent iconography.
- Markdown responses, code-copy buttons, task plans, saved text drafts, and scrolling that respects the user's position.
- Accessible modal dialogs, labeled controls, keyboard navigation, reduced-motion support, and explicit approval buttons.
- Integrated bounded terminal and staged/unstaged review, including new files.
- Durable desktop job records, interrupted-run recovery, and active-run reconnect.
- ID-based SSE replay fixes duplicate prior tasks and the 800-event stall.
- Tool-call identifiers correctly correlate parallel operations.
- Session activation switches the backend workspace; follow-ups recover bounded conversation context and preserve custom titles.
- Cancellation waits for worker exit and releases pending approvals.
- Concurrent workspace jobs are rejected; direct edits wait for active jobs.
- Live and final plan changes are persisted and displayed.
- Git uses literal paths/NUL-delimited status; stale hunk requests are rejected.
- Cross-origin browser requests and untrusted Host headers are rejected.
- Direct workspace mutations enforce read-only mode.
- Standalone Linux x86_64 AppImage and portable archive with checksums.
- Python wheels include the compiled interface; MCP is a declared dependency.
- Source installer uses an isolated venv without uninstalling system packages.
- AppImage installer validates the executable before replacing earlier builds.
- CI checks Python, TypeScript, browser workflows, and accessibility; tag workflow produces release assets. Updated architecture, security, usage, and release docs.
Introduced the minimal drawer-based desktop, Goal Mode, per-task rewind, session management, model picker, notifications, and source-checkout updater. Release history is available on GitHub.