Skip to content

Releases: amontlabs/lcu

LCU 0.9.6

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 06 Oct 13:51
1180362

LCU 0.9.6

Fixes reported in 0.9.5, a Claude Code plugin install path, and a command to undo Chrome site decisions. The Chrome relay now runs on LCU's own Python and is refreshed by lcu update, lcu doctor catches a macOS home folder too long for the helper socket, and a slow macOS turn-end cleanup no longer fails a Pi turn. Everything else is as in 0.9.5. Windows remains deferred.

Changes

  • Claude Code plugin (#8, #7). On Apple Silicon macOS, claude plugin marketplace add amontlabs/lcu then claude plugin install lcu@lcu installs the latest release when LCU is missing (only if its SHA-256 matches) and runs lcu setup --agent claude-code --yes. The plugin has no MCP entry of its own, and claude plugin uninstall removes only the plugin. On Linux and Intel Macs it says once that it does not apply. Docs: Claude Code plugin.
  • Home folder too long on macOS (#15, #12). OpenAI's signed helper refuses a socket path over 103 bytes, so with more than 13 characters after /Users/ every call failed with Sky Computer Use native pipe startup failed. LCU cannot change the helper; lcu doctor now exits 2 with the path and its length, and lcu setup prints the same warning. Docs: macOS.
  • Chrome relay pinned to LCU's Python (#16, #11). On macOS and Linux the relay was started with whatever python3 Chrome's short PATH found. It is now lcu-native-host.py behind a /bin/sh wrapper, lcu-native-host, that runs the interpreter LCU was installed with, falls back to another Python 3.12+ from the same search, and otherwise to /usr/bin/python3 only if it is 3.8 or newer. lcu browser status reports a relay installed before this change as outdated until it is refreshed.
  • macOS turn end in Pi and Oh My Pi (#17, #14). The original host waits 5 s for turn-end handlers, and LCU's macOS hook allowed 22 s, so a slow cleanup failed the turn with "turn-ended handlers timed out" and could leave later tool calls failing. The hook now answers within 4 s while cleanup finishes in the background, the next Sky request still waits for it, and Pi warns and retries instead of failing the turn.
  • Reconnect the Chrome extension (#18, #10). An extension connected before lcu setup --chrome keeps the original host and fails with Browser request-header policy requires caller identity. Setup, lcu browser install and the docs now say to restart Chrome or turn the extension off and on, and lcu browser status prints where the manifest points when it no longer points at LCU's relay. Docs: troubleshooting.
  • lcu origins (#21, #19). lcu origins [list] shows the allowed and denied sites the original runtime saved per agent session, and lcu origins forget <origin> removes a saved decision (by default from the denied list of every session) so the site is asked about again. It never allows a site. The docs now say LCU_APPROVED_ORIGINS is read only by the Pi and Oh My Pi extension and cannot lift a saved denial. Docs: Chrome site decisions.
  • lcu update refreshes the Chrome relay (#22). When this installation's relay is still registered, the update reinstalls it through the lcu browser install code path, replacing only manifests that already pointed at it, and asks you to reconnect the extension when anything changed. It does nothing for accounts that never set up Chrome. A manifest taken back by the ChatGPT app is left alone, and the update prints lcu browser install. A refresh error is a warning, not an update failure. Docs: upgrades.
  • Windows installer (#20, #13). The installer found the native-pipe host by a minified name that changed in OpenAI.Codex 26.930.7945.0. It now finds the host by structure (vendored acorn 8.18.0, MIT, used only to parse), checks the layout before copying the app, and removes a copy it made when a later step fails. No Windows archive is published and this was not tested live on Windows.

The refresh in #22 runs on the update from 0.9.5: lcu update in 0.9.5 runs the new release's lcu update --post-install after installing it. Chrome users who update from 0.9.5 should see Refreshed the Chrome relay at ... and then restart Chrome or turn the ChatGPT extension off and on. Run lcu browser install yourself as the desktop account, then reconnect, if the update printed a warning or lcu browser install (for example because the ChatGPT app took the manifest back), if it ran as root (sudo, or the sudo installer command it prints for a prefix this account cannot write), or if you installed 0.9.6 by hand with --runtime-only.

The original runtime, tool schemas and instructions are unchanged; LCU's own macOS hook timeout changed in #17. No new tested app pairs are claimed.

Source and packages

All archives were built from commit 48b203b (the Linux archives by tests/run.sh in the disposable lcu-verification images, arm64 natively and amd64 emulated on an aarch64 Docker host). The later commit on main adds only this file, which is not in the archives.

Archive SHA-256
lcu-0.9.6-darwin-arm64.tar.gz 8f94738876f0ab5585b348c3bb963fced1511df539728e50fb8f7d50e6053464
lcu-0.9.6-linux-arm64.tar.gz a0475bf68e0254ec0f703ed2a967a7383bc43975006b2f0df9d671149ff57c51
lcu-0.9.6-linux-x64.tar.gz 15a3476102147b8f48b47863e1cc9f28adc0ec7711021f3ede916921fba0db3a

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Each contains lcu/origins.py; compared with 0.9.5 the macOS member list adds only that file and three verification records. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537). Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm test --prefix adapters on macOS: 131 tests, 123 passed, 8 skipped (installed Pi and Windows), none failed. New tests cover the typed turn-cleanup timeout and Pi holding a new turn's tools until cleanup clears.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on macOS: 640 tests passed, 1 skipped (the plugin hook's missing-Python case, because this host has a qualifying Python in /opt/homebrew/bin).
  • tests/run.sh linux/arm64 (native, original sandbox required in the read-only gate) against the pinned official ChatGPT 26.915.31945 package: 640 Python tests (24 skips: the 18 plugin hook tests, which need shasum, and 6 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls, sandbox and hung-engine suites, and the read-only mount gate all passed.
  • tests/run.sh linux/amd64 (emulated; the original sandbox cannot be required there) passed with the same suites.

Not verified

None of these changes was observed on a real desktop: the plugin's first session on a clean account (install, register, restart, a computer-use call), lcu doctor on an account with a long home folder, real Chrome launching the new relay, reconnecting the extension, declining, forgetting and being asked again about a site, a real lcu update with Chrome connected, and a slow live macOS turn end. The Windows host change was checked against the macOS 26.930.21537 bundle only. #23 (macOS turn-ended notify exceeding its 3 s timeout) is open and not addressed here. Everything listed under "Not verified" in 0.9.5 still applies.

LCU 0.9.5

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 05 Oct 16:31
641295e

LCU 0.9.5

Adds a local diagnostic log so a hung js call can be explained. In Claude Code, js calls once hung until the 120 s MCP timeout and worked again later, and nothing recorded what the relay was waiting on. The adapters now write a metadata-only log of each call and approval. Everything else is as in 0.9.4. Windows remains deferred.

Changes

  • Diagnostic log. The Claude Code and Codex relays and the shared client (Pi, Oh My Pi, Hermes) write one JSON-lines file per process under ~/Library/Logs/LCU/ (macOS) or ${XDG_STATE_HOME:-~/.local/state}/lcu/logs/ (Linux). It records when each call started and ended and how (ok, tool error, timeout, aborted), whether an approval was opened and for which app, whether the lcu-approve mod claimed it, and the choice. It never records tool arguments, results, approval messages, UI text, error text or session ids.
  • Strict retention. Files older than 7 days are deleted when an adapter starts, the oldest are deleted past 20 MiB in total, and one process stops writing at 2 MiB. LCU_DIAGNOSTIC_LOG=0 turns the log off and LCU_LOG_DIR moves it. Files never leave the computer.
  • lcu status --json has a diagnostic_log object, and lcu status and lcu doctor print the directory and policy.
  • Docs: diagnostic log.

No runtime, tool schema, instruction or input behavior changed, and no new tested app pairs are claimed.

Source and packages

All archives were built from commit 49dd2fc (the Linux archives by tests/run.sh in the disposable lcu-verification images, arm64 natively and amd64 emulated on an aarch64 Docker host). The later commits on main add only this file and test-only changes to adapters/test/claude.test.mjs, which are not in the archives.

Archive SHA-256
lcu-0.9.5-darwin-arm64.tar.gz f1f4511bbd14064ef591cdcad6907a3c1c858705c2ea9eb02d0e7bf8cad7afad
lcu-0.9.5-linux-arm64.tar.gz 5b0eabe7557bb261a4718cfa3cf8a3310b923db7be31609cdc56b8ebad5d253c
lcu-0.9.5-linux-x64.tar.gz 6a1bd569d38c012c38c1175ea2cdabe65530bb87311e73b6c994563d52e38e31

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Each contains adapters/diagnostics.mjs and lcu/diagnostic_log.py. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537). Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm test --prefix adapters on macOS: 128 tests, 120 passed, 8 skipped (installed Pi and Windows), none failed. New tests cover the log location, disabling, age and total-size pruning, the per-file cap, file and directory modes, an unwritable directory, and Claude and Codex relay runs whose logs hold call and approval events but none of the code, result, approval message or id markers.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on macOS: 487 tests passed, including the check that the Python and JavaScript retention constants match.
  • tests/run.sh linux/arm64 (native, original sandbox required in the read-only gate) against the pinned official ChatGPT 26.915.31945 package: 487 Python tests (5 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls, sandbox and hung-engine suites, and the read-only mount gate all passed.
  • tests/run.sh linux/amd64 (emulated; the original sandbox cannot be required there) passed with the same suites.

Not verified

The log was not yet observed in a live Claude Code or Codex session, and the hang that motivated it was not reproduced. Everything listed under "Not verified" in 0.9.4 still applies.

LCU 0.9.4

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 05 Oct 13:43
805e7dc

LCU 0.9.4

Stops the Pi adapter from breaking the prompt cache after tool_search (#6). In Pi, each tool that tool_search discovered made the next request re-send the whole context uncached on OpenAI/Codex models (reported as 80-115k tokens per discovery). Pi users should upgrade and rerun lcu setup --agent pi. Everything else is as in 0.9.3. Windows remains deferred.

Cause

The Pi extension added LCU's original initialization instructions by returning systemPrompt from before_agent_start. Pi treats a returned systemPrompt as forceSystemPrompt: for that run it replaces the structured prompt and collapses the system messages, including tool-addition deltas, into one head that holds the full current tool list. Each discovered tool therefore changed the start of the request instead of being sent as an additional_tools item at the end, so the cached prefix no longer matched. This was traced in the installed Pi 0.86.0 source (extensions/runner.js emitBeforeAgentStart, agent-session.js _installAgentForcedPromptProjection, pi-ai openai-responses-shared.js).

Changes

  • Instructions go through systemPromptOptions. When Pi passes event.systemPromptOptions, the adapter appends the instructions once to its appendSystemPrompt and returns nothing, so Pi keeps its structured prompt and tool deltas. Pi copies its base options for each run, so the text does not accumulate.
  • Unchanged fallback. Without systemPromptOptions the adapter returns the appended prompt as before: an extra array section for Oh My Pi, whose before_agent_start event at v18.4.1 has only prompt, images and systemPrompt: string[], and a string for older Pi.
  • Docs: adapters, instructions and a dated note in the OMP record.

No runtime, tool schema or input behavior changed, and no new tested app pairs are claimed.

Source and packages

All archives were built from commit 268d0e2 (the Linux archives by tests/run.sh in the disposable lcu-verification images, each architecture natively or emulated as below). The later commit on main adds only this file.

Archive SHA-256
lcu-0.9.4-darwin-arm64.tar.gz 78ed918299796520d8f8223eee0ba3ba679bb82ec6ae8b22b0ba8e74993366cf
lcu-0.9.4-linux-arm64.tar.gz 2841dfaa0e28721d08bd49d9ef9d82554add95e09ea79c24e8c1d89a8b1f48e5
lcu-0.9.4-linux-x64.tar.gz ad6137c19b46771959c52b803d0f072a08a57ee052e032c93542f2e448280195

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Each contains the changed adapters/pi/index.ts. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537). Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm ci --prefix adapters && npm test --prefix adapters on macOS: 116 tests, 108 passed, 8 skipped (installed Pi and Windows), none failed. The Pi tests cover the systemPromptOptions path (empty and existing append text, no duplicate on a second call) and the string fallback; the OMP tests cover the array fallback.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on the macOS development host with Python 3.12.10: 483 tests passed.
  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) against the pinned official ChatGPT 26.915.31945 package: 483 Python tests (5 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls, sandbox and hung-engine suites, and the read-only mount gate all passed.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites: 483 Python tests (5 environment skips).

Not verified

The fix was not exercised in a live Pi session, and the prompt-cache saving was not measured; the cause and the fix rest on the Pi 0.86.0 and Oh My Pi v18.4.1 sources and on unit tests. Everything listed under "Not verified" in 0.9.3 still applies.

LCU 0.9.3

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 05 Oct 13:09
d360b64

LCU 0.9.3

Keeps the Linux JavaScript kernel sandboxed, and fixes the Claude app's missing approval pane. On Linux, since 0.8.2 the model's JavaScript (the original node_repl kernel) ran with no sandbox at all, because LCU sent Codex's disabled sandbox state to keep the Sky desktop service working. From this release the kernel stays inside codex sandbox and only the verified Sky worker runs outside it. On macOS, the Claude desktop app's Code tab never showed the per-app approval pane, so every approval was declined; it now appears. Linux users should upgrade and rerun setup; Claude app users should upgrade and rerun lcu setup --agent claude-code. Everything else is as in 0.9.2. Windows remains deferred.

Cause

  • Linux kernel. Under codex sandbox the original runtime's seccomp filter also refuses connect(2) to the X11 socket, so Sky could not reach the desktop and every js call failed. LCU 0.8.2 to 0.9.2 avoided that by disabling the sandbox for both the kernel and the worker, leaving the model's JavaScript running with the account's permissions.
  • Claude app approvals. In the desktop app's Code tab, $.session.surfaces() returns an empty list while panes can still be placed. The lcu-approve mod took that for a headless session, so the engine declined every approval.

Changes

  • Sandbox split on Linux. CODEX_CLI_PATH points at bin/lcu-codex-sandbox (lcu/sandbox_shim.py), which stands between node_repl and codex sandbox. The kernel goes to the real codex sandbox unchanged; the trusted worker that hosts Sky runs outside it only when positively identified as the selected runtime's own; every other sandbox invocation is refused, never run unsandboxed. It fails closed.
  • Modes. LCU_NODE_REPL_SANDBOX unset is the default above; host restores the original behavior (including the X11 failure where bubblewrap works); the new off restores the 0.8.2 to 0.9.2 behavior (nothing sandboxed). A sandbox state sent by the host still wins.
  • lcu doctor reports the sandbox state and runs its availability check from its own scratch directory; it says that the kernel's subprocesses stay confined. The original runtime starts from / when the launch directory cannot be entered.
  • Approval pane in the Claude app. The mod shows the pane when the app reports no surfaces but places panes.
  • Docs: adapters, the installation guide and the verification record.

No tool schema or macOS input behavior changed, and no new tested app pairs are claimed.

Source and packages

All archives were built from commit b051e9e (the Linux archives by tests/run.sh in the disposable lcu-verification images, each architecture natively or emulated as below). The later commits on main change only documentation and CI workflow files: this file and .github/workflows/claude.yml.

Archive SHA-256
lcu-0.9.3-darwin-arm64.tar.gz 8c2cfcf7e7d466657d25e7841bec9c684a6f057f32d4e490e2c627be2c2221dc
lcu-0.9.3-linux-arm64.tar.gz a419284a52df0f970199a64631c3b4552a035a3a657cbbb015f2936763ec5db5
lcu-0.9.3-linux-x64.tar.gz 026b729a1131c5b58bca27b94dae62c3d248c0bf6135120b9e3f40f6ffcaa72e

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Both Linux archives contain lcu/sandbox_shim.py and an executable bin/lcu-codex-sandbox; the macOS archive contains the fixed adapters/claude-mod/lcu-approve/hooks/register.tsx. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537) with swiftc. Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm ci --prefix adapters && npm test --prefix adapters on macOS: 116 tests, 108 passed, 8 skipped (installed Pi), none failed.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on the macOS development host with Python 3.12.10: 483 tests passed. Two test_hermes_harness errors that had been seen on this host with 0.9.2 did not occur in these runs.
  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) against the pinned official ChatGPT 26.915.31945 package: the first run failed one test, test_wait_drains_pty_while_waiting_for_agent_end_observer (a test-only race in counting a pty's output, unrelated to the release; 1,038,075 of 1,048,576 bytes seen). The test was fixed in b051e9e and everything was rebuilt and rerun: 483 Python tests (5 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls and hung-engine suites, and the read-only mount gate all passed.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites: 483 Python tests (5 environment skips).
  • The sandbox split itself was verified on a Linux x86-64 host with a working bubblewrap; the verification record lists what ran.

Not verified

Claude Code, Pi, Oh My Pi, Hermes and a system Codex CLI were not installed on the Linux verification host; their registrations were exercised only through the shared relay and client paths. Chrome was skipped there. A live ARM64 desktop run of the sandbox split was not made beyond the ARM64 gate above. The approval pane fix was not driven in a real Claude app session for this release. Everything listed under "Not verified" in 0.9.1 still applies.

LCU 0.9.2

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 05 Oct 09:03
90463a8

LCU 0.9.2

Fixes setup failing for accounts with many agent skills (#5). On macOS, an account with a few hundred global skills saw every lcu setup and install.sh run end with old skill cleanup failed: skill installer returned invalid JSON for each agent and exit 1, although registration succeeded. Because the run failed, setup.json was never written, so the Chrome, audio and approval choices and the pending harnesses were lost and lcu setup --reconcile had nothing to work from. Affected users should upgrade and rerun setup. Everything else is as in 0.9.1. Windows remains deferred.

Cause

Setup lists installed skills with the bundled skills CLI to remove the lcu skill registered by LCU 0.6.0 and earlier. That CLI prints its JSON and then calls process.exit(). On macOS, Node writes to a pipe asynchronously, so everything past the 64 KiB pipe buffer was dropped and the JSON could not be read. Writes to a file are synchronous on every platform.

Changes

  • Installer output is read through files. lcu/capture.py runs a child with stdout and stderr captured in temporary files instead of pipes. The old-skill listing, the original Chrome extension and native-host diagnostics (lcu setup --chrome status), and the original Chrome native-host install use it. The Chrome install now also has a 120 s limit and reports the installer's error output.
  • Old-skill cleanup cannot fail setup. It is legacy housekeeping; a failure is now printed as <Harness>: skipped old LCU skill cleanup: ... and setup continues.
  • Setup saves choices even when a step fails. setup.json keeps Chrome, audio, approval mode and pending harnesses after a failed registration step, so the printed retry command and --reconcile keep them. A pending harness that fails stays pending; other failed harnesses are retried with the printed command. Previously nothing was saved after a failure.
  • One failing harness no longer stops the others. An unexpected error in a registration step is recorded for that harness, with its type, and setup continues with the next one. Codex registration output is validated before use.
  • Accurate retry and errors. The retry command repeats --approval only when it was given or is auto; a defaulted ask is no longer added, since an explicit --approval ask removes approval entries. The failure message lists the failed steps (codex: MCP, pi: extension). Installer-output errors give the output size and the child's error text. install.sh now says that setup failed rather than that agent registration failed.

No runtime, tool schema or input behavior changed, and no new tested app pairs are claimed.

Source and packages

All archives were built from commit 9c6c5e6 (the Linux archives by tests/run.sh in the disposable lcu-verification images from a clean checkout of that commit, each architecture natively or emulated as below; the release-notes commit changes only this file).

Archive SHA-256
lcu-0.9.2-darwin-arm64.tar.gz 2273bfffeb1189c761d6342a8cfcbdc5e18b4309ead434765b7614bb759984a1
lcu-0.9.2-linux-arm64.tar.gz 18e0220c9abc2eade0178005ee8b99555a1aec493d70a6d3e0ad3a8c45989417
lcu-0.9.2-linux-x64.tar.gz a0c8bf44c5d77123bfc567611fbcd2749c9bdb711ddbfa2c7d9c873a9fc2b070

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Each contains lcu/capture.py. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537) with swiftc. Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm ci --prefix adapters && npm test --prefix adapters on macOS: 116 tests, 108 passed, 8 skipped (installed Pi), none failed.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on the macOS development host with Python 3.12.10 and 3.14: 450 tests passed on each. New tests run a real Node child that prints more than 64 KiB and then calls process.exit(0), and cover setup state, retry and per-harness errors after failed steps.
  • Issue reproduction (new for this release): with the darwin archive's own lcu/setup.py and bundled skills CLI and the app's Node, against a temporary home holding 700 global skills plus an LCU 0.6.0 lcu skill. Through a pipe the listing was cut at 65,536 bytes, as reported; remove_old_skill read the full list, removed the old skill, and reported nothing to remove on a second run.
  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) passed against the pinned official ChatGPT 26.915.31945 package: 450 Python tests (5 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls and hung-engine suites, and the read-only mount gate.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites: 450 Python tests (5 environment skips).

Not verified

A rerun on the reporter's machine. The Claude mod is unchanged from 0.9.1 and its checks were not repeated. Everything listed under "Not verified" in 0.9.1 still applies.

LCU 0.9.1

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 04 Oct 23:02
866184b

LCU 0.9.1

lcu-0.9.1-demo.mp4

Fixes the Claude mod failing to load in 0.9.0, and adds lcu update. In 0.9.0 the lcu-approve mod's types contract (types/index.d.ts) was missing from the release archives, so Claude Code refused to load the installed mod (claude plugin validate reported "types: Path not found: ./types/index.d.ts" and "lcu-approve.apps is not declared"). The approval pane and /computer-use-apps did not load. 0.9.0 users should upgrade and rerun lcu setup --agent claude-code. Everything else is as in 0.9.0. Windows remains deferred.

Changes

  • The archives ship the mod's types contract. scripts/provision_agent_tools.py no longer drops types when it copies adapters/claude-mod, so the installed lcu-approve has every file of the source mod except its tests. A test in tests/test_build_platforms.py checks this on the built archive.
  • lcu update. Downloads this platform's archive and its .sha256 for the latest release, verifies it, extracts it and runs its installer with --runtime-only, the same prefix and the recorded app (Linux adds --skip-system). Falls back to the system curl when Python has no CA certificates. It asks on a terminal; without one it requires --yes and otherwise exits 2 with instructions. It never downloads or installs the ChatGPT app. If this account cannot write the prefix it prints the sudo command instead. The new release then refreshes the user-scope lcu-approve mod, so mod fixes arrive with the update. Restart agents afterwards; lcu prune reclaims the old release.
  • lcu update --check [--json]. Checks now whether a newer release exists, by following the redirect of https://github.com/amontlabs/lcu/releases/latest (no GitHub API; nothing is sent beyond that request) and reading the optional severity marker in that tag's docs/releases/<version>.md. Exits 1 on a network error.
  • Update notices. lcu update --notice [--json] is cache-only and never blocks; it refreshes the per-account cache in the background at most every 10 minutes (about 1 hour after a failed check), so a release reaches open sessions within about 10 minutes. lcu status (text and the update JSON key) and lcu doctor show the cached notice; it never fails doctor. For Claude Code, the lcu-approve mod runs it at session start and on prompts (at most every 10 minutes, once per release per session): the agent is told to tell the user and offer lcu update, and the user sees a toast. For Codex CLI, setup adds LCU-owned SessionStart and UserPromptSubmit hooks that give the agent the same notice. Pi, Oh My Pi and Hermes have no session hook.
  • Severity markers. A release's notes may carry <!-- lcu-severity: security --> or <!-- lcu-severity: breaking -->, which prefixes the notice with "Security update:" or "Breaking update:". This release has none.
  • Opt out. LCU_NO_UPDATE_CHECK=1 disables the background check and notices. Source checkouts never report updates. Offline installs are not recorded; set the variable on machines without network access.

No runtime, tool schema or input behavior changed, and no new tested app pairs are claimed.

Source and packages

All archives were built from commit 71942ef (the Linux archives by tests/run.sh in the disposable lcu-verification images from a clean checkout of that commit, each architecture natively or emulated as below; the release-notes commit changes only this file).

Archive SHA-256
lcu-0.9.1-darwin-arm64.tar.gz 2bc0d675d8a8c2aa42fca78636a222e421fb1a8d54df5512f4071c269dc47cff
lcu-0.9.1-linux-arm64.tar.gz 864db7b7195c7fb655f97a28d71669fb412d01c2db28dcb4c170b28cd0b83d54
lcu-0.9.1-linux-x64.tar.gz e24da59a03b2789349403f19d4e5a54f58dd7d9d2ff9f4373c61871a46af368d

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Each contains adapters/claude-mod/lcu-approve/types/index.d.ts, lcu/update.py and lcu/update_apply.py. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537) with swiftc. Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm ci --prefix adapters && npm test --prefix adapters on macOS: 116 tests, 108 passed, 8 skipped (installed Pi), none failed.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on the macOS development host with Python 3.12.10 and 3.14 (with adapters/node_modules present): 435 tests passed on each.
  • claude plugin validate and claude plugin test on adapters/claude-mod/lcu-approve (mod 0.4.0) with the Claude app's bundled Claude Code 2.1.286: validation passed, 36 of 36 tests passed.
  • python3 tests/claude_approval_mod.py --claude <2.1.286> (a real Claude Code CLI with a scripted local model and a fixture runtime, temporary HOME): all 11 scenarios passed.
  • Installed-mod check (new for this release): the darwin archive was extracted and its own lcu/claude_mod.py install() was run against a temporary home directory (the installer resolves the account's real home from the system, not $HOME, so install.sh was not used for this check); the resulting .claude/skills/lcu-approve held every mod file including types/index.d.ts plus lcu.json, was identical to the archive's adapters/claude-mod/lcu-approve apart from lcu.json, and claude plugin validate on it (2.1.286) passed. bin/lcu update --help runs from the extracted archive.
  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) passed against the pinned official ChatGPT 26.915.31945 package: 435 Python tests (5 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls and hung-engine suites, and the read-only mount gate.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites: 435 Python tests (5 environment skips).
  • The update feature's author reports an end-to-end run of lcu update against a fake release; that run is not repeated here.

Not verified

A live lcu update install against a published release, the post-install mod refresh on a real install, and the update notices in real Claude Code and Codex sessions (the notice hooks are covered by unit tests and the scripted Claude Code run only). Everything else listed under "Not verified" in 0.9.0 still applies.

LCU 0.9.0

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 04 Oct 21:52
4641853

Superseded by 0.9.1. 0.9.0's archives left out the lcu-approve mod's types/index.d.ts, so Claude Code refused to load the approval mod. Upgrade to 0.9.1 and rerun lcu setup --agent claude-code.

LCU 0.9.0

Approve apps from the Claude app, and manage approved apps with Touch ID. The Claude app's Code tab now shows computer use's per-app question as a native "Computer use approval" pane (it used to fail with "Computer Use was not approved"), lcu apps lists, allows and revokes always-allowed apps on macOS behind Touch ID, and LCU never lets an agent approve the app it runs in. --approval auto is now documented as an optional setting for unattended machines. Windows remains deferred.

Changes

  • Redesigned panes and the /computer-use-apps panel. The approval pane was redesigned (app name and bundle id, one sentence, the choices, a "High risk" badge with the runtime's warning). That warning is shown as "Allowing computer use to control this app ... monitor the agent", not with the runtime's own product name, and the icon cell is left out on terminals that cannot draw pictures. The new /computer-use-apps command opens an Approved apps panel: one compact line per always-allowed app with Revoke (Touch ID or password on macOS), apps that are no longer installed grouped below, this conversation's grants, and an Allow field. The panel scrolls when it is taller than the pane.
  • Native approvals in the Claude app and terminal. lcu setup --agent claude-code installs a small Claude Code mod, lcu-approve (adapters/claude-mod/lcu-approve), at ~/.claude/skills/lcu-approve (or the project's .claude/skills with --scope project). It shows the runtime's approval as a pane with Allow this conversation, Always allow (when offered) and Deny, or as a question dialog on a terminal narrower than 144 columns. The hook returns at once and never holds an approval pending while a person decides; pane presses go through a ui.press hook and report failures. The Claude relay gained two mod-only tools (approval_request, approval_choice) that it refuses unless the call comes from the plugin, and the model cannot call them. Needs the Claude app or Claude Code 2.1.287 or later; without the mod nothing changes.
  • lcu apps (macOS). lcu apps, lcu apps allow <app> and lcu apps revoke <app> manage Computer Use's always-allowed list. allow and revoke are confirmed with Touch ID or the login password through bin/lcu-owner-auth, a small helper the macOS build compiles and signs ad hoc (the build now needs swiftc). Browsers and password managers warn; apps the runtime refuses are declined. Linux says it has no per-app approval.
  • Approval guards. The app hosting the agent (Claude desktop, an editor running an agent extension, the terminal) is never approved, whatever the user answers. --approval auto now writes exact rules for js and js_reset only, never the whole lcu server; --approval ask still removes the older server-wide entries LCU recorded.
  • Positioning of --approval auto. It is optional and meant for unattended machines (VMs, CI). Normally your harness's own permission settings decide whether the agent may call LCU's tools (for example Claude's "don't ask again"); LCU's per-app approval holds in every permission mode. README, installation guide, adapter notes and lcu setup --help now say so.
  • Claude desktop registration. Register LCU for the Claude app through Claude Code (lcu setup --agent claude-code), not Claude Desktop's Connectors (claude_desktop_config.json), which currently breaks identity (#3). Stated in the installation guide.
  • Includes main's CI. GitHub Actions unit, Windows, lint and archive-payload jobs (scripts/check_archive.py) and the Linux container gate, plus the test fixes made for them.

No runtime, tool schema or input behavior changed, and no new tested app pairs are claimed.

Source and packages

All archives were built from commit 87f9685 (the Linux archives by tests/run.sh in the disposable lcu-verification images, each architecture natively or emulated as below; the release-notes commit changes only this file).

Archive SHA-256
lcu-0.9.0-darwin-arm64.tar.gz d8357b6ced96164e2990e71d96579bda894271a6c83983b171b4ee6ad69adbaa
lcu-0.9.0-linux-arm64.tar.gz c13bbd501a7c6637b7bce35fedc1783ef580641301ebd572d143483ac9f6f23b
lcu-0.9.0-linux-x64.tar.gz b3eddf212f77948de2fd2e55ae3f4c5372fed11262c8ead8838dd9de4e478e50

Each archive has a matching .sha256 sidecar, checked with shasum -a 256 -c, and scripts/check_archive.py accepts all three. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537) with swiftc. Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • npm ci --prefix adapters && npm test --prefix adapters on macOS: 116 tests, 108 passed, 8 skipped (installed Pi), none failed.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on the macOS development host with Python 3.12.10 and 3.14: 394 tests passed (Python 3.12.10 on the macOS host; the 3.14 run predates the last change and was not repeated).
  • claude plugin validate and claude plugin test on adapters/claude-mod/lcu-approve with the Claude app's bundled Claude Code 2.1.286: validation passed, 21 of 21 tests passed.
  • python3 tests/claude_approval_mod.py --claude <2.1.286> (a real Claude Code CLI with a scripted local model and a fixture runtime, temporary HOME): all 11 scenarios passed, covering pane session/always/deny/dismiss/session-only/slow answers, the narrow-terminal dialog, no mod, headless, and the model being refused the mod-only tools.
  • python3 tests/codex_approval_mode.py --cli ~/.local/bin/codex (codex-cli 0.160.0): passed; ask leaves the prompt in force, auto runs the tool without one.
  • The CI lint checks (shellcheck at error severity, JSON parse) pass locally; ruff, the Windows job and the GitHub-hosted runners were not run.
  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) passed against the pinned official ChatGPT 26.915.31945 package: 394 Python tests (4 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls and hung-engine suites, and the read-only mount gate.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites: 394 Python tests (4 environment skips).

Verified live

On 2026-10-04, in the Claude app 2.19675.0 (bundled Claude Code 2.1.286): a real Calculator approval showed the pane, the click recorded the choice and the js call completed in 2 s. lcu apps revoke and lcu apps allow ran with real Touch ID.

Not verified

The VS Code extension (the mod is expected to work there but was not driven), the redesigned panes in the Claude app itself (they were rendered in a real terminal through the preview mod, not driven in the app, and the scroll of a list taller than 26 rows was not exercised), Windows (no per-app mod, lcu apps or guard checks), the Claude desktop Connectors path (documented as unsupported), and a real Codex, Pi, OMP or Hermes session with the new guards. Linux has no per-app approval in the original runtime, so none of the pane or lcu apps features apply there; the harness's approval of LCU's tools is the only gate.

LCU 0.8.9

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 04 Oct 11:48
793dfee

LCU 0.8.9

This release fixes three problems found in use: native-app approvals that timed out, launchers that failed under an older python3, and Hermes runs that hung waiting for an approval nobody could answer. No runtime, tool schema or input behavior changed, and it adds no new tested app pairs or harness verification claims. Windows remains deferred.

Changes

  • Approvals no longer time out while a person decides (Claude Code and Codex relays, Pi extension). The relays forwarded each native-app approval to the harness with the MCP SDK's default 60 s request timeout, so a slow decision cancelled the approval, and the 120 s tool-call deadline kept running while the approval was open. Approvals are now forwarded without a timer, every tool-call deadline is paused while any approval is pending (and resumes afterwards), and aborting the call still cancels the pending approvals.
  • Launchers run under Python 3.12 or newer. bin/lcu and bin/lcu-session re-execute themselves under a suitable interpreter when PATH resolves python3 to an older one, trying LCU_PYTHON, then python3.14, python3.13, python3.12 and python3. If none is 3.12 or newer, they exit with a clear message instead of a traceback. scripts/install.sh now selects a 3.12+ interpreter too. The new module is lcu/interpreter.py.
  • Hermes headless runs cancel approvals immediately. Hermes single-query (-z), chat -q, cron and other runs without an approval callback used to block on standard input for an answer that could never arrive. The bridge now cancels the approval at once, so the call fails fast instead of hanging.
  • Release builder. scripts/build_bundle.py now includes lcu/interpreter.py in every archive (the launchers import it), and the platform build tests check for it.
  • Documentation. The adapter and installation guides now state that the original Linux runtime asks for no per-app approval (only the macOS and Windows targets do), so on Linux the harness's own approval of LCU's tools is the only gate before desktop control. The adapter notes also describe the approval timing and Hermes behavior above.

Source and packages

All archives were built from commit c181e05 (the Linux archives by tests/run.sh in the disposable lcu-verification images, each architecture natively or emulated as below; the release-notes commit changes only this file).

Archive SHA-256
lcu-0.8.9-darwin-arm64.tar.gz 914af27f8958004d0f3f8cd6e786a093fb2548d63544653722644ef2b6825b87
lcu-0.8.9-linux-arm64.tar.gz 9e2fefa062a7c6ed538cd91e6b8941a53d279827676f976192fb6be8232c99f0
lcu-0.8.9-linux-x64.tar.gz 6fe663335c04645db58133747b2791a37fbe3a8d9cd1d2273940df42b0dd91c1

Each archive has a matching .sha256 sidecar. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537). Archives are not byte-reproducible across builds; the Linux archives above are the ones that each gate run built and tested.

Gates

  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) passed against the pinned official ChatGPT 26.915.31945 package: 353 Python tests (3 environment skips), offline in-place installation, agent registration, the original GTK desktop suite, the adapter-path, GTK 4, controls and hung-engine suites, and the read-only mount gate.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites: 353 Python tests (3 environment skips).
  • npm ci --prefix adapters && npm test --prefix adapters on macOS: 90 tests, 82 passed, 8 skipped (installed Pi and other environment skips), none failed.
  • python3 -m unittest discover -b -s tests -p 'test_*.py' on the macOS development host with Python 3.12.10 and with 3.14: 353 tests passed on both, including tests/test_interpreter.py, the new Hermes headless tests and the two Hermes bridge tests that errored on the 0.8.8 macOS host before npm ci.
  • The built macOS archive's bin/lcu --help ran from the extracted tree under a PATH of only /usr/bin:/bin and under Homebrew's PATH.
  • Not run: ChatGPT 26.928.31416 and 26.930.41038 (only the pinned package was used), a real Claude Code, Codex, Pi or Hermes session with a slow approval, a real Hermes -z or cron run, the approval timing against a real harness, any macOS desktop action, and Windows. The macOS archive was built only. The gates ran in disposable containers; no personal desktop and no Linux test machine were used.

LCU 0.8.8

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 03 Oct 12:07
04fa368

LCU 0.8.8

This release lets one setup run cover harnesses that are installed later. It changes setup only: no runtime, adapter or input behavior changed, and it adds no new tested app pairs or harness verification claims. Windows remains deferred.

Changes

  • lcu setup --allow-missing (with --agent all, --agent auto or explicit --agent lists). Pi, Oh My Pi and Hermes need their own executable to register; when it is absent LCU skips that harness, prints <Harness>: not installed; will register when it appears, and records it as pending. Codex and Claude Code already register without their CLI and still register at once. The output lists what was registered and what is pending; the exit status is 0 when only missing harnesses are left and nonzero for a real registration failure (the retry command keeps --allow-missing). Without the flag a missing harness is still a failure.
  • lcu setup --reconcile. Registers each pending harness whose executable now exists (on PATH, ~/.local/bin, ~/.bun/bin, ~/.npm-global/bin or ~/.cargo/bin) with the saved Chrome, audio and approval choices and the saved scope and session, then removes it from pending. It never prompts, is silent and lock-free when nothing is pending or no pending harness is installed (one small file read), takes the per-account setup lock when it has work, re-reads the state under it, never touches a harness that is not pending, and keeps a harness that fails pending (exit status 1; the next run retries). Safe at every login or boot.
  • State. ~/.local/state/lcu/setup.json gains pending and pending_context (scope, project, session); they are written only while something is pending, and an older file without them loads as "nothing pending". A later --approval ask|auto (or --chrome/--audio) updates the saved values that reconcile applies; an explicit setup of a pending harness clears it from pending.
  • lcu status --json reports pending (also in setup.pending); the text output names pending harnesses.
  • The installers forward --allow-missing to setup and reject --reconcile (run it from the installed release). See Harnesses installed later, ADAPTERS and the verification note.

Source and packages

The archives were built from commit 5dca08d (Linux archives in the disposable lcu-verification images, each architecture natively or emulated as below).

Archive SHA-256
lcu-0.8.8-darwin-arm64.tar.gz 758872066db15db4ec3d1b7f8a5f8f79af439b5b99330388d040fa0d8828d398
lcu-0.8.8-linux-arm64.tar.gz edf19c055648245fadcfe073cfdc06623f7b5503f9c866b374ab8134f9439de1
lcu-0.8.8-linux-x64.tar.gz c45e6375e8ee66d09882a6aa17eae6307243665d0f827b6619ea5990502e3d60

Each archive has a matching .sha256 sidecar. Archives contain no OpenAI application binaries or copied original instructions. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537). Archives are not byte-reproducible across builds, and these were built separately from the archives that each gate run tested (same source apart from the verification note and release notes).

Gates

  • tests/run.sh linux/arm64 (native on an aarch64 Docker host, original sandbox required in the read-only gate) passed against the pinned official ChatGPT 26.915.31945 package: 346 Python tests (3 environment skips, 21 of them new in tests/test_setup_pending.py), offline in-place installation, agent registration, the new tests/pending_registration.py container check, the original GTK desktop suite, the adapter-path, GTK 4, controls and hung-engine suites, and the read-only mount gate.
  • tests/run.sh linux/amd64 (emulated on that host; the original sandbox cannot be required there) passed with the same suites, including tests/pending_registration.py.
  • tests/pending_registration.py (real registration in the container): setup --agent all --allow-missing --approval auto as an account whose PATH hides Pi registered Codex and Claude Code with the approval entries, wrote nothing for Pi, and recorded Pi, OMP and Hermes as pending; lcu status --json listed them; --reconcile with nothing installed printed nothing and left setup.json byte-identical; after the real Pi launcher was placed in ~/.local/bin, --reconcile registered it through pi install (the package is in ~/.pi/agent/settings.json), left OMP and Hermes pending, and a second run was silent.
  • On the macOS development host the Python suite ran with 2 errors in test_hermes_harness.py that also occur on the unmodified 0.8.7 tree there (they pass in the Linux gate).
  • Not run: ChatGPT 26.928.31416 (only the pinned package was used this time), any real OMP or Hermes registration after a later install (mocked CLIs in the unit tests only), a real Claude Code or Codex CLI installed after LCU wrote its configuration, a login or boot trigger for --reconcile, any macOS desktop action, and Windows. The macOS archive was built only. The gates ran in disposable containers; no personal desktop and no Linux test machine were used.

LCU 0.8.7

Choose a tag to compare

@0xpolarzero 0xpolarzero released this 02 Oct 23:48
edf6710

LCU 0.8.7

This release fixes the last three review findings in the Linux window-targeted input translation, and one defect that the 26.928.31416 gate exposed. It adds no new harness verification claims and no new tested app pairs; Windows remains deferred.

Changes

  • A timed-out translated call no longer leaves buttons or modifiers pressed. A timeout during a translated drag (or a hang after the button went down) left Button1 pressed after the worker exited, so later pointer motion continued the drag. Translated drags now get a time budget that follows their path: the 30 s base bound plus 20 ms per path point and 2 ms per pixel of path length (a click adds its hold duration for each click, a key chord its hold duration), capped at 5 minutes; a valid 4,000-point drag is no longer killed at 30 s. When a translated call times out, or fails by itself, after it may have pressed something, LCU reads the X server's pressed buttons and keys and releases through XTEST only what that call pressed (the button its action uses and the keys of a held chord; never what was already down).
  • The original engine is ended by LCU on a timeout. The 26.928.31416 gate showed that its engine survives the worker's exit (26.915.31945's transport kills it), so a resumed engine delivered the late key (also with 0.8.6). LCU now ends the engine processes below the worker itself, then releases input, then stops the worker, and reports the timeout only after that.
  • An active pointer grab by another client refuses pointer input. A popup menu's grab received the click although the window at the point was the target. Before a translated pointer action the helper probes with XGrabPointer on the root (no event mask, undone at once); an existing grab, a frozen state or no answer fails the call with an explicit error and sends nothing. The probe discards pointer events that arrive during its round trip (well under a millisecond).
  • PID-namespace proof from the real socket. Equal numeric pids in two PID namespaces passed the previous proof. The helper now finds the X server through the display's local socket (/proc/net/unix, /proc/*/fd holders) and requires its ns/pid link to equal LCU's. TCP displays and servers LCU cannot identify (for example one running as another account) fail closed; the X-Resource self-check remains as an additional condition.
  • Documented known limits (see Linux window-targeted input): the gap between the checks and the XTEST delivery, keyboard and passive grabs, XInput2-only grabs, and window managers other than Openbox and Xfwm4.
  • SYSTEM_PACKAGES is unchanged (libxtst6, now also used for the release, was already listed). LCU_LINUX_INPUT_TRANSLATION=off and the per-pair native_input switch are unchanged. See the verification note.

Source and packages

The archives were built from commit 45eece9.

Archive SHA-256
lcu-0.8.7-darwin-arm64.tar.gz 547496461db3b5019ca0e714ab4b9580f7eb55b79bf79eaf91ba245f5d2af73b
lcu-0.8.7-linux-arm64.tar.gz 9c7f87529f6fc19a40ad518cf54b4709eef11af304ae39f5a1293b906bb84afb
lcu-0.8.7-linux-x64.tar.gz f2c8f7930635cfd9743bd5022a90b1da5bc67ca25f0406261655207499778269

Each archive has a matching .sha256 sidecar. Archives contain no OpenAI application binaries or copied original instructions. The Linux archives are release builds of that commit; each gate run tested its own build of the same source. The macOS archive was built from /Applications/ChatGPT.app (26.930.21537) as for earlier releases. Archives are not byte-reproducible across builds.

Gates

  • tests/run.sh linux/arm64 (native, original sandbox required in the read-only gate, with the negative control and the stricter-host-profile check) passed against both the official ChatGPT 26.915.31945 (the pinned package) and 26.928.31416 (downloaded from OpenAI's package pool; the SHA-256 equals the recorded app_sha256): 325 Python tests (3 environment skips), offline in-place installation, agent registration, the exported MCP contract, the original GTK desktop suite, the adapter-path suite, the GTK 4 window-targeted suite (now also with a popup holding an active pointer grab: every pointer action refused, nothing reaching the popup or the target), the controls suite, the hung-engine suite, the new drag suite and the read-only mount gate. tests/run.sh linux/amd64 (emulated; the sandbox cannot be required there) passed against both packages as well. The new drag suite: an 800-point drag outlasts its 2 s base bound and completes (7.5 s on the arm64 container, 8 s emulated); a drag with a held Shift whose real engine is stopped with SIGSTOP right after the button went down is released (the X server then reports no button and no Shift, the drag area receives the release, the engine is replaced); with the release neutered the same test fails with "Button1 stayed pressed". 26.915.31945 has no key_down/key_up, so the pass-through checks only ran against 26.928.31416.
  • The 26.928.31416 gate exposed the engine that survives the worker's exit (the late key z reached the entry in tests/linux_input_hang.py, with the 0.8.6 wrapper too); it passes with the fix on both architectures. The arm64 gates were run twice, before and after the drag test was resized for fast hosts (500 points against a 3 s base, then 800 points against 2 s); the final-source runs are the ones listed in the table above.
  • Native x86-64 on an Ubuntu 26.04 host with native Docker, in a temporary directory with throwaway images and volumes: the release build of the x64 archive passed the desktop suites as the unprivileged account against both packages with the app on a read-only volume and the original sandbox required (4.4 ms per drag point there). The host's full tests/run.sh was not used: its first stage runs the installer test in Docker's default profile, where the original sandbox cannot start (the same environment limit as for 0.8.6), and the second app-folder move of the read-only gate was not repeated by hand. Three throwaway containers whose Xvfb entered uninterruptible sleep on that host could not be removed (docker kill reports no exit event) and were left running; they hold no application, VM, ~/.silo or ~/.microsandbox state.
  • adapters/test/linux-sky-service.test.mjs: 42 in-memory tests (10 new), and node --test adapters/test/*.test.mjs passes (78 passed, 8 environment skips, 0 failed).
  • The aligned-pid regression (a child PID namespace whose helper pid equals the pid the server sees: the X-Resource check alone trusts the server, the socket proof refuses) was run privileged against a real Xvfb on arm64 and on native x86-64; the gates themselves run unprivileged, where tests/linux_xres_namespace.py skips that half with a notice.
  • The macOS archive was built; no desktop action ran on macOS and no model-driven run was made for this release. Real popup menus and notification daemons (the popup and the overlay are fixture windows), other window managers than Openbox, real Chrome or Electron applications, fractional scaling and a window from a genuinely remote X client were not exercised.