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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "anode",
"displayName": "Anode background Windows desktop",
"version": "0.11.1",
"version": "0.11.2",
"description": "Background Windows desktop for AI agents: native GUI automation, screenshots and app testing.",
"author": {
"name": "skulitom",
Expand Down
68 changes: 44 additions & 24 deletions .github/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,49 @@
## What's new in 0.11.1
## What's new in 0.11.2

This patch fixes issues found after 0.11.0 and adds live Windows validation of the merged changes.
This patch fixes bugs found after 0.11.1, most of them by AI agents using Anode every day.

- **Safer Android automation.** adb commands cannot change the shared server or replace/remove
another device's forwarded local port, including through repeated `wait-for-*` prefixes. Emulator
boot probes stay within the caller's reply deadline, even when adb hangs.
- **Reliable display recovery.** The viewer remembers the display Windows confirmed. A lost reply
is never replayed or treated as success, and lease cleanup restores a change that finishes late.
- **Recovery after an agent is killed.** A generated MCP session's desktop lease ends when its
process is gone and any admitted action finishes. Stable `ANODE_AGENT_ID` leases retain their
existing release-or-expiry behavior.
- **Older MCP audio clients work.** Clients using protocol `2024-11-05` receive recordings as WAV
resources; newer clients continue to receive native audio blocks.
- **MCP Registry publication.** Anode's initial metadata listing is live. Release CI now builds and
attests the optional MCPB bundle for owner testing; it remains a workflow artifact until its
separate Claude Desktop validation passes.
- **Typing keeps pace with the program.** `seat_type` and `anode type` sent characters as fast as
Windows took them, so a busy program, such as Chrome editing a long field, could drop and reorder
them while the call reported success. Characters now go out 15 ms apart by default, and typing
pauses while the program is busy; `perCharMs` sets the pace. A call that stops partway reports
exactly how many characters were typed.
- **`set_value` checks that the value took.** On a Chrome drop-down list (`<select>`), `set_value`
reported success while the list kept its old choice. Anode now reads the control back and fails,
saying to expand the list and pick the option, if the control still shows its old value.
- **Observation copes with more windows.** `seat_observe` failed on File Explorer windows ("Object
reference not set to an instance of an object"), and repeated a Chrome window's tree while one of
its drop-down lists was open. Both are fixed; a control listed twice now appears once.
- **Queued requests keep their deadline.** A request that waited behind a long operation, such as
typing, could lose its reply and leave the seat `detached`. It now answers, or fails, in time.
- **Running out of time is reported as such.** A desktop action stopped at its deadline answered
with a bare "A task was canceled." It now fails with `errorCode: "timed_out"` and says whether
anything ran (`started`).
- **A finished job's reply holds all its output.** `seat_job` and `anode job` could answer
`finished: true` with the end of the command's output missing. `finished: true` now comes only
with the output to its end.
- **Browser sign-in is clearer.** `anode browser --sign-in` explains its window in its first tab
and opens several addresses. When the seat's profile is open on the other desktop, `seat_browser`
and `--sign-in` refuse and name the process holding it, instead of reporting a window.
- **Faster startup.** CLI and MCP skip their first connection wait when no daemon is running, and
waiting callers wake as soon as the seat is ready ([measurements](https://github.com/skulitom/Anode/blob/v0.11.2/docs/STARTUP-PERFORMANCE.md)).
- **Clearer records of what Anode keeps.** A daemon started by a desktop app that redirects AppData,
such as the Claude desktop app, keeps its files in that app's package folder, which the privacy,
install and troubleshooting pages now say; `anode rendering --restore` finds a backup saved there.
The uninstaller ends with everything it leaves on the machine and how to remove each item.

**Validation.** All 83 quick checks passed. Live on Windows 11 Pro build 26200, native desktop
controls, actual mouse/keyboard delivery to Chrome, portrait and scaled displays, audio playback
and recording, Android boot/capture/stop, hidden-viewer pointer isolation and a seat-only Xbox
controller passed. Killing an MCP client cleared its lease in 406 ms and restored the display
before the next client acquired it. Both legacy and modern MCP audio formats passed against the
running seat. Package, installation and distribution checks are also part of the release workflow.
See the [validation record](https://github.com/skulitom/Anode/blob/v0.11.1/docs/RELEASE-READINESS.md)
for evidence and remaining coverage limits, including the untested live display reconnect fallback.
**Known issues.** A Chrome window's first observation can come back without the page, and the
page's controls sit deeper than the default `maxDepth` of 8: observe again with `maxDepth` 16. On
Windows' "Open File - Security Warning" dialog, `invoke` reports success without running anything:
focus the dialog with `seat_window`, then click. `seat_window` `raise` can leave a UWP app behind
the foreground window: use `focus`. `anode type` has no option for a slower pace. Fixes are planned
for a later release.

**Validation.** All 99 quick checks and the documentation check passed, and Windows CI repeated
the build, packaging, installation and distribution checks. The live checks in a Windows 11 seat,
their results and their limits are in the
[validation record](https://github.com/skulitom/Anode/blob/main/docs/RELEASE-READINESS.md).
See the [changelog](https://github.com/skulitom/Anode/blob/v0.11.2/CHANGELOG.md#0112--2026-10-10) for every
change.

## Install or upgrade

Expand Down Expand Up @@ -51,7 +71,7 @@ anode capabilities | Out-Host
agent afterward. Other MCP clients can launch `anode.exe` with the argument `mcp`.

**Upgrading:** save seat work, run `anode quit` (which closes every program in the seat), and close
agent sessions using Anode. Install 0.11.1, start Anode again and restart those agent sessions.
agent sessions using Anode. Install 0.11.2, start Anode again and restart those agent sessions.
Run `anode configure` to refresh the installed skill.

Requires 64-bit Windows 10/11 Pro, Enterprise or Education, or Windows Server with a Remote Desktop
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## Unreleased
## 0.11.2 — 2026-10-10

- **A finished job's reply holds all its output.** `seat_job` and `anode job` could answer `finished: true`
with the end of the command's output missing, when the command ended while the reply was being put
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ See [Install](#install) for custom locations and offline installs, or
**Ctrl+Alt+Shift+K** stops it (if another program holds that shortcut, use **Stop seat** in the viewer or
`anode kill`). Unsigned builds may trigger SmartScreen. No telemetry.

<!-- Remove this section in the release that ships #18 and #20. -->
<!-- 0.11.2 ships #18 and #20. Remove this section in the release after it. -->
### Known issues in 0.11.1

Two bugs in 0.11.1 have fixes waiting for the next release. Until then:
Two bugs in 0.11.1 are fixed in 0.11.2. On 0.11.1:

- **`seat_observe` fails on Windows 11 File Explorer windows** with "Object reference not set to an
instance of an object", and so does `seat_wait`. Use `seat_screenshot` and `seat_click` on those
Expand Down
5 changes: 4 additions & 1 deletion docs/DEVELOPMENT-TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ $lease = anode lease acquire --ttl 600 | Out-String | ConvertFrom-Json
if ($LASTEXITCODE -ne 0) { throw 'Desktop acquisition failed.' }
$env:ANODE_LEASE_TOKEN = $lease.leaseToken
powershell -ExecutionPolicy Bypass -File scripts\test-desktop.ps1
powershell -ExecutionPolicy Bypass -File scripts\test-chrome-form.ps1
powershell -ExecutionPolicy Bypass -File scripts\test-development.ps1 -InstallBrowserTools
powershell -ExecutionPolicy Bypass -File scripts\test-development.ps1 -VerifyInput
powershell -ExecutionPolicy Bypass -File scripts\test-pointer-isolation.ps1 -PlacePointer
Expand All @@ -105,7 +106,9 @@ the lease they inherit through the environment and never acquire one or start a

The native fixture covers Windows Forms and WPF: text, buttons, toggles, list selection, slider
values, delayed control states, password omission, stale references and report generation.
The development fixture checks command cwd/environment/streams/exit codes, starts a localhost server
The Chrome form check opens a local page in Chrome on a temporary profile and checks `set_value` on a
text field and a drop-down list, and an observation while the list is open; its result is under
`artifacts/chrome-form-test`. The development fixture checks command cwd/environment/streams/exit codes, starts a localhost server
and headed Chrome inside the seat, verifies both process sessions, exercises form/HTTP behavior and
mobile layout, and saves browser plus seat screenshots. Its browser context uses a separate temporary
profile, without copying the user's browser accounts. Output is under `output/playwright/development`;
Expand Down
2 changes: 1 addition & 1 deletion docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Useful options:

```powershell
# Choose a version and register installed Codex/Claude Code CLIs as well.
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -Version 0.11.1 -Client Auto
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -Version 0.11.2 -Client Auto
# A dedicated custom folder; leave PATH and the Start menu alone.
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 -InstallDirectory C:\Tools\Anode -NoPath -NoShortcut
```
Expand Down
129 changes: 124 additions & 5 deletions docs/RELEASE-READINESS.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,131 @@
# Release readiness — 2 October 2026
# Release readiness

## 0.11.2 candidate — 10 October 2026

**Scope:** the fixes merged since 0.11.1 (pull requests #10 to #32, except those still open, such
as #19, the Business edition's terms) and the startup changes in
[startup performance](STARTUP-PERFORMANCE.md). No new tools or commands; the tool count stays 41.
The candidate is the commit that sets the version to 0.11.2. Fixes merged after it are not in it.
The changelog dates 0.11.2 to 10 October, when its contents were fixed.

### Already checked, without a seat

- The candidate's tree (`main` at `98173de` plus the version change): all **99 quick checks** and
the documentation check passed locally on 10 October, and so did the release-mode distribution
check (`test-distribution.ps1 -Release`) on its package, MCPB bundle and registry entry. Windows
CI passed on `98173de`: Release build, packaging and the MCPB bundle, registry-entry validation,
quick self-tests, disposable install, update, rollback and uninstall, distribution and
documentation checks. CI repeats them on the candidate.
- Code fixes came with regression checks, in the quick suite or in CI's install tests, and each
pull request had a second, independent review before it merged.
- The .NET runtime pin is still the current 10.0 patch, **10.0.12** (Microsoft's release metadata,
10 October 2026). If a newer 10.0 patch is out when you tag, update `RuntimeFrameworkVersion` first.
- Publishing: merging the version change doesn't publish anything. Anode is already listed in the
MCP Registry (0.11.0, metadata only), so `publish-registry.yml` skips pushes to `main`; 0.11.2's
installable entry follows the release and the Claude Desktop bundle test
([publishing](PUBLISHING.md)).

### Owner's live check (about 25 minutes)

These need a real seat, so only the owner runs them. Installing the candidate also upgrades the
installed Anode. Before you start: no game in the seat, nothing open there you need (`anode quit`
closes every program in it), and the .NET 10 SDK, Node.js and Chrome installed.

1. **Build the candidate** (about 5 minutes):

```powershell
git clone https://github.com/skulitom/Anode anode-0.11.2
cd anode-0.11.2
$candidate = git log -1 --format=%H -S '<Version>0.11.2</Version>' -- src/Anode/Anode.csproj
git checkout $candidate
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\build.ps1 -OutputDirectory artifacts\pkg-build -ArchiveDirectory artifacts\pkg-release -QuickTest -Package
```

2. **Install it.** Close the agent apps and sessions that use Anode first (they keep `anode.exe`
open, and the installer stops rather than replace a running copy). Then:

```powershell
anode quit | Out-Host
powershell -NoProfile -ExecutionPolicy Bypass -File artifacts\pkg-release\install.ps1 -PackagePath artifacts\pkg-release\anode-windows-x64.zip -ChecksumPath artifacts\pkg-release\SHA256SUMS
```

In a new terminal, in the same folder:

```powershell
anode version | Out-Host
anode start --hidden | Out-Host
anode capabilities | Out-Host
```

`version` must say 0.11.2. Windows may ask you to sign in to the seat once.

3. **Run the live checks** (about 15 minutes), holding a lease:

```powershell
$env:ANODE_AGENT_ID = 'release-0.11.2'
$lease = anode lease acquire --ttl 600 | Out-String | ConvertFrom-Json
if ($LASTEXITCODE -ne 0) { throw 'Desktop acquisition failed.' }
$env:ANODE_LEASE_TOKEN = $lease.leaseToken
$exe = (Get-Command anode).Source
powershell -ExecutionPolicy Bypass -File scripts\test-desktop.ps1 -Anode $exe
powershell -ExecutionPolicy Bypass -File scripts\test-chrome-form.ps1 -Anode $exe
powershell -ExecutionPolicy Bypass -File scripts\test-development.ps1 -Anode $exe -InstallBrowserTools -VerifyInput
anode run explorer.exe C:\Windows | Out-Host
Start-Sleep -Seconds 2
$explorer = @((anode windows --query Windows --json | ConvertFrom-Json).windows | Where-Object process -eq 'explorer')[0]
if (-not $explorer) { throw 'No File Explorer window in the seat yet: wait a moment, then set $explorer again.' }
anode inspect $explorer.windowId | Out-Host
anode window $explorer.windowId close | Out-Host
anode lease release | Out-Host
```

| Check | What it covers in 0.11.2 | Passes when |
| --- | --- | --- |
| `test-desktop.ps1` | native controls, including `set_value`'s new read-back on a text box | it prints `"passed": true` |
| `test-chrome-form.ps1` | Chrome: a text field's `set_value` reads back within its 1.5 s wait; `set_value` on a `<select>` fails instead of reporting success; the open list's observation lists each control once | it prints `"passed": true`; a warning that the open list's options weren't listed is a finding for a later release, not a failure |
| `test-development.ps1` | typing's new pace, with mouse, key and text delivery checked in a headed Chrome page | it ends without an error |
| File Explorer | `inspect` on an Explorer window, which failed in 0.11.1 | it lists the window's controls |

4. **Release.** If every check passed, tag the candidate and push the tag from the candidate
checkout, whose `HEAD` is the candidate ([release process](../CONTRIBUTING.md#release-process),
step 6):

```powershell
git tag v0.11.2 HEAD
git push origin v0.11.2
```

The Release workflow builds, tests and publishes the release. After it: the package manifests
(step 7), and the Claude Desktop test of the workflow's MCPB bundle
([release gate](../packaging/mcpb/README.md#claude-desktop-test-release-gate)), which lets the
registry list 0.11.2 as installable. The validation results go into this record then.

### Covered without a live run

The seat profile held on the other desktop (Restart Manager), requests queued behind a long
operation, packaged apps' folders and the uninstaller's list are covered by quick checks with
stand-ins and by CI's disposable installs, not by a live seat. Startup timings are in
[startup performance](STARTUP-PERFORMANCE.md).

### Known and open, for a later release

- A Chrome window's first observation can come back without the page, and page controls sit below
the default `maxDepth` of 8. Observe again with `maxDepth` 16.
- On Windows' "Open File - Security Warning" dialog, `invoke` on Run reports success, but nothing
runs. Focus the dialog with `seat_window`, then click.
- `seat_window` `raise` can leave a UWP window behind the foreground window. Use `focus`.
- `anode type` has no option for a slower pace (MCP's `seat_type` has `perCharMs`).
- `anode.log` is never rotated ([privacy](PRIVACY.md)).

## 0.11.1 release validation — 2 October 2026

**Scope: 0.11.1 release validation.** All open PRs were reviewed, corrected where necessary and
merged after their Windows CI passed. The patch includes legacy MCP audio compatibility, shared
adb server/forward protections, bounded emulator startup, confirmed display memory and recovery
of leases owned by killed MCP processes. Publication remains gated by Windows CI and the Release
workflow.

## Live validation — 2 October 2026
### Live validation — 2 October 2026

The self-contained 0.11.1 candidate daemon and seat host ran together on Windows 11 Pro build
26200 in the separate `dev` channel, child session 3, initially 1280x720 at 100%. The user made
Expand All @@ -31,7 +150,7 @@ Local logs, JSON results, screenshots, audio and the MCP integration harness are
`artifacts/validation-0.11.1` (ignored by Git). The separate PR review record is under
`artifacts/pr-review-2026-10-02`.

## Automated validation
### Automated validation

- The candidate passed all **83 quick self-tests** and documentation checks. The environment
self-test (`selftest --no-gamepad`) passed **86 checks**, adding screen capture, geometry and
Expand All @@ -48,7 +167,7 @@ Local logs, JSON results, screenshots, audio and the MCP integration harness are
- The .NET 10 runtime pin remains **10.0.12**, verified against Microsoft's release metadata on
2 October 2026. The package includes that runtime.

## Remaining coverage limits
### Remaining coverage limits

- The live display reconnect fallback was not needed: every requested display applied live.
Credential-dialog seats refuse reconnects that would need the password again. Failed, clamped,
Expand All @@ -69,7 +188,7 @@ Local logs, JSON results, screenshots, audio and the MCP integration harness are
Authenticode signature. No clean-machine Windows compatibility certification, long-running
soak test or comprehensive security audit is claimed.

## Live validation — 28-29 September 2026
### Live validation — 28-29 September 2026

The earlier 0.11.0 evidence, including Android Studio, seat-browser profile checks and diagnosis of
the damaged Pixel 3a image, is preserved in the
Expand Down
2 changes: 1 addition & 1 deletion packaging/mcpb/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": "0.3",
"name": "anode",
"display_name": "Anode background Windows desktop",
"version": "0.11.1",
"version": "0.11.2",
"description": "Background Windows desktop for AI agents: native GUI automation, screenshots and app testing.",
"long_description": "Runs apps in a Windows child session with its own screen, pointer and keyboard focus, so an agent can automate native UI, take screenshots and run headed app/browser tests while you keep working. Requires 64-bit Windows 10/11 Pro, Enterprise or Education (or Windows Server with an RDP host) and a one-time `anode setup` as administrator. Shares your files, account and network; it is not a security sandbox.",
"author": {
Expand Down
Loading
Loading