8 Commits

Author SHA1 Message Date
Michał Pierzchała 4f5a87b6b3 refactor(command-registry): move CLI flag grammar, text and command aliases down (#2561)
Move the vocabulary that both the CLI and commands read but no command's runtime
depends on into the package below both: flag types, registry, groups and the four
flag-definitions files, command-text, and cli-command-aliases. These are pure moves;
only their import specifiers change.

No compat re-export at the old paths — every consumer switches to the owning
subpath. The per-command defaults stay where they are for now (the daemon's edge into
the facet resolver is the harder cut and belongs with the daemon-closure work).

Part of #2545 / #2543.
2026-09-14 11:27:22 +02:00
Michał Pierzchała 2ec4e91b11 refactor(core): move the command descriptor registry into its own workspace package (#2348)
* refactor(core): move the command descriptor registry into its own package

`src/core/command-descriptor/`, `src/command-catalog.ts`, `src/core/wait-positionals.ts`
and `src/core/parse-timeout.ts` move as git renames into a new private package
`@agent-device/command-registry` (deps: contracts, selectors). One subpath per module
points straight at the moved file; no `index.ts`, no re-export at the old path. Every
consumer switches to the owning specifier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jqfa11D8QsCMuL17SsLvDz

* test(host-kit): pin the command-registry package inside the daemon code graph

The daemon reaches the registry and its catalog only by workspace specifier. A walk
that stopped at the package boundary would report an unchanged signature after a
descriptor edit, and the client would keep reusing a daemon running the superseded
policy. The manifest is asserted beside the sources because its `exports` map is what
chose them. The cache doc comment quoting the old ~800-module graph is corrected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jqfa11D8QsCMuL17SsLvDz

* chore(gates): point the descriptor-registry gates at the package path

R66's `COMMAND_DESCRIPTOR_MODULE`, R16's record-runtime join subject and the Fallow
`AssertTrue` totality-guard key follow the registry to its package. The two descriptor
hubs leave `HUB_ENTRY_FILES` because the package manifest now publishes them, so the
eager-closure gate discovers them as facades and one entry gets one rule; this also
flips `denyPlatformImplementations` from false (hub) to true (package entry) for both,
which is intentional and stricter. `command-registry` joins the ranked spine at rank 1.

No `APPROVED_OVER_CEILING` row: rename detection carries every moved entry's merge-base
baseline, so all twelve fall under the no-growth rule rather than a ceiling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jqfa11D8QsCMuL17SsLvDz

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-06 12:55:14 +02:00
Michał Pierzchała 35362fe517 refactor(cli): let help resolve command aliases itself and retire R12 (#2293)
* refactor(cli): let cli-help resolve the --help alias itself

bin.ts's --help fast path composed
buildCommandUsageText(normalizeCliCommandAlias(helpTarget)) inline, which
let a future edit call buildCommandUsageText raw without anyone noticing
until an alias's help silently dropped back to a full CLI bootstrap (the
regression #1641 fixed). Move the composition into cli-schema/cli-help.ts
as resolveHelpTargetUsageText, so bin.ts just calls one function that owns
its own alias normalization; bin.ts no longer imports the alias registry
at all.

Retargets cli-help-alias-fast-path.test.ts at the new function (same three
cases) and adds a process-level smoke test asserting `tap --help`/`launch
--help` stdout is byte-identical to `press --help`/`open --help`. Seen red
by temporarily removing the `tap` alias from CLI_COMMAND_ALIASES (both
fast and slow paths lose the alias, producing an "Unknown command: tap"
mismatch); green again after restoring it.

Verified manually: `node --experimental-strip-types src/bin.ts tap --help`
stays byte-identical to `press --help`, and `launch --help` to `open
--help`; `rotate --help` still falls through to the retired-command error.

* chore(gates): retire R12 now that cli-help owns its own alias resolution

bin.ts can no longer compose buildCommandUsageText and
normalizeCliCommandAlias incorrectly because it doesn't hold either import
any more — resolveHelpTargetUsageText in cli-schema/cli-help.ts is the only
call site, and cli-help-alias-fast-path.test.ts plus the new smoke-cli
process test pin it. The static R12 checker existed only to prove that
composition from source text; delete it along with its rule wiring in
check.ts (rule function, import, LAYERING_RULE_IDS/LAYERING_RULES entries,
header comment, summary string).

Drops scripts/layering/bin-alias-fast-path.ts (352 lines) and its test
(311 lines). Updates the two stale references left behind:
record-runtime-mechanics-policy.ts's comparison to R12's "delegate to your
single owner" shape, and check-wiring.test.ts's header, which named
bin-alias-fast-path.test.ts as the seam it protects.

rule-ids.ts discovers rule ids by scanning source text rather than a
hand-maintained list, so no entry there needed updating.

Verified: pnpm check:layering green (175/175), including
check-wiring.test.ts and rule-ids.test.ts; pnpm check:quick (lint +
typecheck) clean; scripts/__tests__/eager-closure-budgets.test.ts
(418/418) unaffected, since neither bin.ts nor cli-help.ts sits in any
HUB_ENTRY_FILES or facade closure — both files reach cli-help.ts only
through a dynamic import.

* test(cli): pin the alias help fast path with a coverage-based oracle

The byte-identical stdout test cannot fail when the fast path is bypassed:
src/cli.ts's slow path resolves the same alias and writes the identical
string, so a reintroduced hand-written table in bin.ts (the exact shape of
#1641) would still pass it. Add a second process-level test that runs
`tap`/`launch --help` and `rotate --help` with NODE_V8_COVERAGE set and reads
the subprocess's own coverage report for src/cli/process-entry.ts, the one
module runCli's slow path loads and the fast path never does.

Seen red: forcing the fast path to always fall through to runCli (simulating
the reintroduced-table bug) failed this test (bootstrappedFullCli true where
false was expected) while the byte-identical test stayed green; reverted and
confirmed both green.

* test(cli): restore an independent oracle for alias help parity

The canonical side of "alias help output matches its canonical command" also
called resolveHelpTargetUsageText, so the assertion became self-consistency:
a degenerate normalizer that maps every input to one canonical command would
make aliasHelp and canonicalHelp equal for every case. Compare
resolveHelpTargetUsageText(alias) against buildCommandUsageText(canonical)
(no alias normalization on the canonical side) instead, restoring the
original two-source oracle.

Seen red: pointing resolveHelpTargetUsageText at a degenerate
`return buildCommandUsageText('press')` failed this test
("launch --help" no longer byte-identical to "open --help"); reverted and
confirmed green.

* refactor(mcp): route the help tool through resolveHelpTargetUsageText

server-guide.ts's help tool composed
buildCommandUsageText(normalizeCliCommandAlias(topic)) inline, the same
composition bin.ts held before this PR moved it into cli-help.ts. That left
a second hand-written call site the R12 gate's own kill criterion said had
to be gone before retirement was moot. Call resolveHelpTargetUsageText(topic)
instead; behavior is unchanged (manually confirmed tap/press and rotate
topics still match) since it's the same composition, and no closure/layering
change since server-guide.ts already imports cli-help.ts statically.

* style: apply oxfmt

* test(cli): prove the help fast path for every registered alias

* refactor(cli): make the process entry importable and test it directly

bin.ts ran its dispatch at import time, so the only way to prove that an
alias --help never loads the full CLI was to spawn the process under
NODE_V8_COVERAGE and grep the report for process-entry.ts. That oracle
needed a paragraph to justify; the code was wrong, not the comment.

The dispatch now lives in src/cli/entry.ts as runEntry(argv, modules, io),
with the five lazy imports injected by bin.ts. entry.test.ts drives it with
recording loaders and the real help module: every registry alias prints its
canonical help with only the help module loaded, an unknown topic falls
through to the CLI loader, --version, bare usage, mcp, and startup failures
each have one case. The subprocess coverage machinery, the alias table pin,
and the multi-line comments are gone; the smoke test keeps one
registry-derived byte-identical alias --help check against the real bin.ts.

Seen red: hand-routing long-press and relaunch to the CLI loader inside
entry.ts failed "every registered alias prints its canonical help without
loading the CLI"; restored.
2026-09-05 20:01:21 +02:00
Michał Pierzchała e832325e87 refactor(substrate): split host mechanics into @agent-device/host-kit capability ports (#2088)
* refactor: split generic host mechanics into @agent-device/host-kit (#2082 W1)

The shared src/utils closure that blocked the platform-family moves lands
on declared owners: generic host mechanics form a new private
@agent-device/host-kit package between kernel and capture-kit, and
capture-kit keeps capture, snapshot, and recording behavior, depending on
host-kit for the mechanics it needs. tar-stream and yauzl move with the
archive code.

Every seam's exported subpaths are pinned in package-boundaries.test.ts,
the layering model ranks the new zone, R13's allow-list names it, and each
seam carries an exact eager-closure row. ADR-0019's substrate amendment
describes the layout.

Tests that mocked two of the moved modules separately became duplicate
same-seam vi.mock factories, where the second silently replaced the first;
those are merged, and the mocks that production code reaches past are
pinned at their injection points instead.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* refactor(host-kit): one narrow capability port per export

The four technical barrels (exec/fs/values/request) grouped by category
rather than by capability, so a consumer needing one mechanic evaluated
unrelated ones. Each export is now a single capability over the host
machine: command, process, diagnostics, retry, archive, file, request,
version. A port re-exports only what a consumer of that capability uses,
and every port carries its own eager-closure row.

Most of the old values barrel was never host mechanics. Pure record
readers, config-source values, result text, memoization, async scoping,
coordinate validation, and device-scope parsing touch no process, file, or
environment, so they join kernel's other primitives instead.

Closures fall accordingly: capture-kit's png-worker-client from 20 to 10,
png-resize from 28 to 18, session-teardown from 79 to 68, and the CLI from
386 to 380.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* chore: drop the migration inventories and trim the touched comments

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* docs: trim the touched host-kit and mutation-lane comments

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* docs: keep tool directives only in the touched files

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* docs: keep tool directives only across the touched tree

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* fix: point the Swift parity comment at the real TS twin and test

The W1 move rewrote this citation to packages/contracts/src/mobile-snapshot-semantics.ts,
which does not exist: the module went to capture-kit while isTapPointInsideViewport itself
went to packages/contracts/src/snapshot-visibility.ts. The TS test line was left pointing at
the pre-move path. Both now resolve.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

* fix: repoint comment citations at the homes this refactor moved them to

The W1 move left ~20 comment citations pointing at src/utils/*.ts and
src/request/*.ts paths that no longer exist. Each now names the capability
port that owns the symbol, which survives further file moves:

  exec -> host-kit/command          host-process, owner-identity -> host-kit/process
  diagnostics -> host-kit/diagnostics   atomic-file, process-lock -> host-kit/file
  retry -> host-kit/retry           request progress/cancel -> host-kit/request
  version -> host-kit/version       ttl-memo, source-value, parsing, device-isolation,
                                    keyed-lock, success-text -> kernel subpaths

Comment-only; no closure, budget, or behavior change. ADR citations are left
as written, being dated records of the decision rather than live references.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-28 07:46:48 +02:00
Michał Pierzchała cdc754e6ed perf: speed up iOS agent recovery and streamline CLI guidance (#1700)
* Avoid interactive children in parent taps

* docs: streamline no-skill CLI help

* perf: recover faster from sparse iOS trees

* fix: preserve selector context for blocked parent taps

* fix: preserve coordinate text-entry focus

* fix: preserve thin parent touch targets

* fix: fail closed for unscoped iOS typing

* test: isolate replay lock fixture

* test: share node integration process
2026-08-10 20:43:01 +02:00
Michał Pierzchała a0ce6f1df2 feat: reinstall command for reuse and agent ergonomics (#47)
* Refine reinstall flow and add agent-focused coverage

* Avoid duplicate readiness preflight in open flow

* Document boot and reinstall in website docs and skill

* Bound iOS boot commands and enforce runCmd timeouts

* Align boot readiness with timeout profiles across platforms

* Refine boot docs: troubleshooting-only and non-CI wording

* Clarify open vs boot fallback guidance
2026-02-12 17:17:56 +01:00
Zhongjin Lu 31a639ab5f feat: add version flags and unify version lookup (#44)
Co-authored-by: Zhongjin Lu <zhongjin.lu@mondorobotics.com>
2026-02-11 17:02:47 +01:00
Michał Pierzchała 9a3570fa1c feat: Daemon modularization + capability-gated command routing + CI/test pipeline (#20)
* feat: Daemon modularization + capability-gated command routing + CI/test pipeline updates

* update android test

* fix arch

* no serial

* fixup tests locally; update runner on CI

* increase timeout

* drop unnecessary node build
2026-02-08 15:20:59 +01:00