| Files | Last commit | Last update |
|---|---|---|
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago | |
fix(macos): resolve native menus and verify lifecycle transitions (#376) * fix(macos): resolve native menus and verify lifecycle transitions Give app-owned menus process identity without a document window. Verify activation with fresh target AX focus and retain exact process generations. Reconcile caller waits after uncertain delivery without repeating the action. BREAKING CHANGE: JSON envelopes use 2.6; macOS app-owned menu snapshots omit data.window. * fix: keep headed preflight lookup inside the macos adapter Avoid an extra ref resolution on Linux and Windows while preserving strict native menu classification on macOS. Update the native inventory test to pass the bridge's explicit full-inventory argument. * fix: preserve native menu ownership through actions and waits * fix: preserve window identity across title changes Reuse the stored window identity check so a renamed window cannot satisfy a disappearance wait. Keep process-generation checks and return the current title. * refactor: share post-action observation and bound native recovery Observe window-owned refs through their original window so waits survive a closing sheet. Preserve partial Linux window reads until target lookup, and retry only transient macOS surface failures. * fix: preserve focus results and complete observation contracts Keep successful Linux focus results when a later read is incomplete and retain child counts across macOS fallback reads. Share saved process identity validation, clarify surface recovery, and cover incomplete reads and renamed windows. Register the shared observer in the CLI helper inventory. * style: match rustfmt output for CI * fix: preserve process-owned refs in post-action waits * style: format process owner observation guard | 3 days ago | |
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago | |
docs: remove the staleness and contradictions left after the Windows promotion (#278) * chore: let release-please carry the skill versions The four skills carried four unrelated versions (0.4.0, 0.4.1, 0.8.4, 0.8.4) in their frontmatter, and ClawHub publishes whatever that field says. Each now reads 0.10.1 with an x-release-please-version marker and is listed in release-please extra-files, so every release moves them with Cargo.toml and npm/package.json. * docs: remove the staleness and contradictions left after the Windows promotion A repo-wide sweep (a Haiku reader per file chunk, Sonnet verification of every candidate against the code, a Sonnet pass per cross-cutting topic and a completeness critic) found statements the code no longer supports. Corrected in place, each checked against the code before it landed: - Phase 2 and the Windows adapter described as in progress, planned or a stub in phases.md, CLAUDE.md, CONTRIBUTING.md, the architecture diagrams and the docs; the branching rules now name main as the line for macOS and Windows and feat/linux-adapter for the next phase. - Envelope examples still at 2.2 or 2.3, README's ad_init(4), removed FFI entrypoints and the dropped snapshot_id argument in docs, comments and error suggestions, bare @eN refs in examples and messages. - The README allowScripts advice, which contradicted npm 11's measured behaviour and named a package.json key a global install never reads. - The phases.md release tracker, a second copy of CHANGELOG.md whose dates had already diverged from it, now points to CHANGELOG.md. - File counts and hard-coded limits in docs and messages replaced by the constant or dropped where they would rot again; the FAQ platform table made identical to README's as phases.md promises. - The committed C header regenerated with cbindgen 0.29.4 for the FFI doc-comment corrections. * test: fail when a documented envelope version, ABI major or command count drifts from the code release-please moves the release version, but three values change with the code instead of the release: ENVELOPE_VERSION, AD_ABI_VERSION_MAJOR and the CLI command count. The docs had fallen behind on all three (envelope 2.2 and 2.3, ad_init(4), 58 commands). doc_literal_drift_tests reads the docs that state them and compares each literal with the constant, the header define and the clap command list. Each test was invert-verified by breaking one literal and watching it fail. * fix: require --agent-id for desktop actions in a multi-agent session on Windows too The multi-agent contract (CLAUDE.md, phases.md 2.17) says desktop UI actions need an agent id once a session runs in multi-agent mode, and Windows ships per-agent cursors. The preflight gate still carried the cfg!(target_os = "macos") it was written with before the Windows port merged, so a Windows multi-agent session let an action through with no agent id. The decision now lives in agent_id_missing, platform-neutral, and a_multi_agent_desktop_action_needs_an_agent_id_on_every_platform runs on every CI host; gating it to another OS makes it fail. * docs: repair the sweep's broken log-callback paragraph and tighten three corrections The FFI skill's ad_set_log_callback paragraph was left with an empty line, orphan fragments and a claim about installing over a foreign global subscriber that log_callback.rs contradicts: the callback is one process-wide slot fed only by events inside ad_* calls, and the FFI never installs a global subscriber. Also drops a reader's note from the envelope bump checklist in favour of naming the drift test, rewords the Effect doc in phase.rs, and wraps two FFI doc lines (header regenerated). * docs: cut the README to what a new user needs to install and run the tool The README had grown to 561 lines: a feature list in marketing voice, a second copy of the command reference, the cursor-overlay flag table, session, trace and CDP walkthroughs, and the ref-system contract, all of which the bundled skills and docs/json-output.md already carry. It now covers what the tool is, installation with the allow-scripts and attestation steps, permissions, the FFI entry point, the snapshot, act, re-snapshot loop, the full command list as one table, platform support and development, and points to the skills for the rest (128 lines). The two platform-table notes are split into plain sentences in README and FAQ alike, so the tables stay identical. The install test's comment no longer claims a modern npm blocks the postinstall, which npm 11 does not, and the drift test matches the unbolded command-count sentence. | 21 days ago | |
feat: agent-desktop mcp (#519) * feat: serve every command as an MCP tool with agent-desktop mcp Tools, schemas and argv are read from the clap command tree at runtime, so adding or removing a command changes the MCP surface with no MCP edit. Each call runs this binary as a child process, keeping the one-process-per-command model the adapters assume. Tested with unit tests over every generated tool, a process test of the stdio server, and a live GTK3 app under Xvfb, openbox and AT-SPI. * fix: bound mcp concurrency and message size, reject malformed messages A runaway client could start unbounded child processes or send one unbounded line. Calls now cap at 8 in flight with a retryable tool error, messages over 4 MiB are refused without stopping the server, and non-object JSON gets Invalid Request. Adds tests that flag-shaped values never become flags and that global flags cannot be set per call, plus a security note in the MCP guide. * fix: honor mcp cancellation and say what tools cannot set (#525) * fix: honor mcp cancellation and say what tools cannot set - notifications/cancelled now kills the call's child and frees its slot. Calls are registered before their thread starts, so a cancel that arrives first still lands. Before, a cancelled call ran to the end and held one of the 8 slots. - Server instructions and the MCP guide say global flags (session, agent id, headed, wait-for, trace) come only from the server's command line, and map the skills' CLI syntax to tool calls. Drops the 'removes nothing' claim and corrects the wrong-type error sentence. - mcp parse errors report command mcp instead of unknown, through one root_command() shared by main and the diagnostic. - key-down and key-up help says they fail closed, as mouse-down and mouse-up already do. - Tests: global flags go after mcp as documented and cover a boolean and a value flag; the NUL case now reaches spawn and checks its message. Tested: fmt, clippy -D warnings on the Linux host set, cargo test -p agent-desktop under dbus and Xvfb, and a live MCP client: cancel returns in about 20 ms and frees the slot (before: no reply in 15 s, next call busy). * fix: never start a cancelled mcp call and release every request id Review on the previous commit found two defects: a cancel that arrived before the call spawned still ran the command until the kill, and a tools/call rejected before running (unknown tool, bad arguments) left its id registered forever. - A Calls registry (src/mcp/calls.rs) owns the request-id lifecycle. The read loop admits an id, the call spawns under the registry lock, so a cancel lands either before the spawn (nothing runs) or after it (the child is killed), and respond() releases the id on every path. - A cancelled call gets no response, as the MCP cancellation spec asks. - A tools/call whose id is already in flight gets Invalid Request instead of silently sharing a slot. - stderr is captured again, so the no-envelope error keeps the child's stderr as before this branch. Tested: fmt, clippy -D warnings, cargo test -p agent-desktop under dbus and Xvfb, unit tests for cancel-before-start and id release (each fails when its check is removed), and a live MCP client: a cancelled call is killed and gets no response, an id is reusable after a protocol error, a duplicate in-flight id is refused, and a freed slot is reused. --------- Co-authored-by: roboeve[bot] <311457182+roboeve[bot]@users.noreply.github.com> * fix: let a cancelled mcp call release held input before it is killed Cancelling a headed drag on Linux while its button was down SIGKILLed the CLI, so its input-release handler never ran and the desktop kept the button held. A cancelled child now gets SIGTERM first. The CLI's existing Linux handler releases held keys and buttons (it waits up to 2 s for that) and exits. The child is killed only if it is still running 3 s later. The wait runs on its own thread so the read loop never blocks. Windows has no SIGTERM and still kills at once. Adds libc to the binary on unix for kill(2). Tested: fmt, clippy -D warnings, cargo test --locked -p agent-desktop under dbus and Xvfb, a unit test that a cancelled child sees SIGTERM before any kill (fails when SIGTERM is skipped), a check that a child ignoring SIGTERM is killed after 3 s, and a live headed drag under Xvfb, openbox and AT-SPI cancelled mid-drag over MCP: button[1] stayed down before this change and is up after it. --------- Co-authored-by: roboeve[bot] <311457182+roboeve[bot]@users.noreply.github.com> | 4 days ago | |
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago | |
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago | |
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago | |
feat(identity): resolve Linux and Windows refs through a capture rule (#442) * feat(identity): resolve Linux and Windows refs through a capture rule Linux and Windows expose no durable element address, so a ref there resolves only when one complete whole-window read proved it unique at capture and exactly one live element matches its full predicate now. Every place that publishes a ref proves it the same way, positional landings are confirmed against the predicate, FFI find re-identifies a landing before publishing it, and Linux menu refs keep their popup binding. The Windows strict resolver and the macOS path search lose their last callers and are deleted. * fix(identity): validate popup context before rooted reads publish refs Rooted find and snapshot drills accepted a matching predicate from a replacement Linux popup. The shared saved-ref observation now checks the captured popup binding against the same observation before refs are published. * fix(identity): keep shallow captures and read the window once per action Snapshots keep a finished shallow read and flag refs they could not prove with identity_unproven. A ref action reads the window once and still runs the full rule under the lease. Capture and resolution read the same evidence, including the forced renderer flag. Hydration keeps the proven predicate, skeleton anchors fall back to the nearest proven ancestor, token-rooted drills read only their subtree unless it holds a tokenless ref, macOS tokenless anchors land by position, interval typing reuses its first handle, and exact FFI entries refuse with ACTION_NOT_SUPPORTED. * fix(identity): prove refs in allocation coordinates and cut Linux read cost The capture proof looked refs up by native child index while allocation writes positions in the projected tree, so after a walker skipped a sibling a unique ref was published unproven. The proof now walks the allocation path through the observation's own child lists, and projection keeps those lists. A capture on an adapter without element tokens now reads the whole window once instead of a shallow walk followed by a whole-window read, and the Linux walker keeps up to 32 nodes in flight per level instead of 8, so a wide level costs one round of calls. * perf(linux): read only identity when re-counting a saved ref's window Resolving a tokenless ref re-reads its whole window to prove it is still unique. That read now asks for identity evidence only, and the Linux walker skips extents, actions and the GTK4 placement pass for it, which the count never uses. Capture, drill and rooted find reads keep their full evidence. Measured on Linux against the previous head, get and is drop by 9 to 40 ms per call with every run still resolving. * fix(snapshot): leave the shallow fallback time when the whole-window read runs long On adapters without element tokens a capture reads the whole window first. That read could spend the whole deadline, so the shallow fallback started expired and returned TIMEOUT instead of the shallow snapshot. The whole-window attempt now gets three quarters of the remaining time. The skills also no longer claim that an unnamed control is identified by role alone or that a re-drill keeps refs inside the drilled subtree. * fix(find): read a token root's subtree alone instead of the whole window find --root on a root carrying an element token observed the whole window to re-identify it, though a token re-identifies itself. Drill-down already reads such a root's subtree directly. Both now go through one helper, read_saved_root: a token root is read as its subtree and stands when the subtree publishes no tokenless ref; otherwise, and for every tokenless root, the whole-window capture proof still applies. * perf(linux): do not wait for a web window to settle when resolving a saved ref Resolving a tokenless ref re-reads its whole window to prove it is still unique. For a Chromium or Electron window that read ran the settle loop: three equal node counts 200 ms apart, so every action paid about 400 ms of sleep. On a page that kept changing the loop gave up, the observation was marked incomplete, and the ref was refused as unproven even though the element was identifiable. Settling belongs to capture, where refs are published and proven unique. A read that only resolves a saved ref now walks once. Ambiguity, an absent element and a walk cut short by its budget are still refused. * fix(find): treat unsettled addressability as publishable in a token-rooted find The subtree fast path counted only nodes already known to be ref-able, so a tokenless member whose actions were still unread passed the check, and hydration could then publish it without a window-wide capture proof; acting on it later failed with identity_not_unique. An unsettled node now counts as addressable, as an unread token already counts as absent, so such a subtree falls back to the window proof. * chore(deps): move async-executor off the yanked 1.14.0 cargo deny fails the audit on a yanked crate. 1.14.1 is the latest compatible release; nothing else in the lock file moves. * test(macos): give the zombie process-group test a deadline load cannot exhaust The 100 ms budget only bounded how fast an unrelated /usr/bin/true exits, so a busy machine skipped the final group probe and failed the test. The reap poll returns as soon as the child exits, so a 5 s ceiling keeps the test as fast while removing the flake. --------- Co-authored-by: vercel-security-reviewer-slack[bot] <321849240+vercel-security-reviewer-slack[bot]@users.noreply.github.com> Co-authored-by: roboeve[bot] <311457182+roboeve[bot]@users.noreply.github.com> | 5 days ago | |
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago | |
feat: accept stdin for text commands (#373) * feat: accept stdin for text commands * docs: clarify stdin input rules and examples * fix: tighten stdin input and output handling * test: adapt MCP text checks to stdin input * test: reject stdin input through MCP * refactor: move snapshot owner selection helper * style: format stdin help attribute | 3 days ago |
| Files | Last commit | Last update |
|---|---|---|
| 3 days ago | ||
| 3 days ago | ||
| 3 days ago | ||
| 21 days ago | ||
| 4 days ago | ||
| 3 days ago | ||
| 3 days ago | ||
| 3 days ago | ||
| 5 days ago | ||
| 3 days ago | ||
| 3 days ago |