Skip to content

fix(cli): reconcile W9 against the merged sdk store surface - #74

Merged
devin-ai-integration[bot] merged 1 commit into
v2from
fix/sdk-dom-lib
Oct 8, 2026
Merged

devin-ai-integration[bot] merged 1 commit into
v2from
fix/sdk-dom-lib

Conversation

@espetro

@espetro espetro commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

W8 (sdk) and W9 (cli) were implemented in parallel against the pre-merge API sketch; when #73 landed with the canonical store surface, the cli drifted. This PR reconciles the cli to the sdk as shipped, so harness works end-to-end on merged v2 — the first PR where the whole stack is real (no stubs anywhere in the path).

Closes the wave-2 reconciliation item in .agents/plans/2026-10-07-v2-foundation.md.

Changes

  • api.ts → type-only re-export hub of the sdk surface (Store, ports, wire types) + cli-local bridge constants. Re-exports are erased at build → drift is impossible by construction.
  • ports/fs.ts rewritten to sdk's FsPort: byte-oriented readFile/writeFile/appendFile, .code-carrying errors (ENOENT→not-found, EEXIST→exists, …), stat→null on missing, createExclusive via O_EXCL, readlink + ln-backed symlink (island rule).
  • ports/exec.ts rewritten to run(command, args, opts) → {code, stdout, stderr} over execFile only (no shell).
  • root.ts: resolves the agents root (~/.agents), not the harness dir — the sdk owns harness/ beneath it. (Was causing doubled harness/harness/ paths at runtime.)
  • cli.ts: createStore(root, ports, { actor, approveExec }) — TTY sessions get a y/N prompt per exec class.
  • commands: add maps --skill-target→installTarget + adds --update; list forwards kinds/enabledOnly; audit reads store.auditLog(); serve reads harness/config.toml under the store root.
  • errors.ts: toCliError forwards StoreError.kind/data structurally — a trust-violation or manifest-invalid (with issues) now surfaces as such instead of internal.
  • testing layer rewritten to canonical shapes: in-memory FsPort (bytes, dirents, createExclusive) + a full-surface mock Store (list/get/install/remove/setEnabled/materialize/verify/doctor/policy/auditLog/subscribe/readLock).
  • sdk: removed the declare global block in ports.ts (collides with @types/node at TS2300 in consumers); globals now come from lib: ["DOM","DOM.Iterable"] in tsconfig.
  • tsdown.config.ts: deps.alwaysBundle: ["@any-harness/sdk"] — dist/cli.js must run standalone for scriptc packaging; neverBundle doesn't override dependency auto-externalization.

Test plan

  • pnpm -r test — 121/121 pass (spec 1, metaharness 4, sdk 59, cli 57)
  • pnpm -r typecheck clean
  • E2E smoke on real binary: add local: → list → verify → disable/enable → audit → doctor → remove on a fresh ANYHARNESS_HOME
  • serve over stdio: capabilities.negotiate handshake → session → capability-gated extensions.list; error envelopes verified (-32602/-32001/-32002/-32601)

Notes

Link to Devin session: https://app.devin.ai/sessions/b930ce55fa0b489c98bc27f0b9a3927c
Open in Devin Desktop: https://app.devin.ai/desktop/session/b930ce55fa0b489c98bc27f0b9a3927c?variant=devin
Requested by: @espetro

W8 landed with the canonical store API; the cli was pinned against the
pre-merge sketch. Reconciles to the sdk as shipped:

- api.ts is now a type-only re-export hub of the sdk surface + the
  cli-local bridge constants (drift-proof by construction)
- ports/fs.ts: byte-oriented ops, .code-carrying errors (ENOENT→not-found
  etc.), stat→null on missing, createExclusive via O_EXCL, readlink +
  ln-backed symlink
- ports/exec.ts: run(command, args, opts) → {code,stdout,stderr} over
  execFile only
- root.ts resolves the AGENTS ROOT (~/.agents), not the harness dir —
  the sdk owns harness/ beneath it
- createStore gets {actor, approveExec}; TTY sessions answer approveExec
  via a y/N prompt per exec class
- add maps --skill-target to installTarget + --update; list forwards
  kinds/enabledOnly; audit reads store.auditLog(); serve reads
  harness/config.toml under the store root
- toCliError forwards StoreError.kind + data instead of flattening
  every store failure to "internal"
- testing layer rewritten to the canonical shapes (memory FsPort,
  full-surface mock Store); all test fixtures updated
- sdk: drop the declare-global block (collides with @types/node at
  TS2300), take TextEncoder/URL et al. from lib DOM instead; tsdown
  alwaysBundle sdk so dist/cli.js runs standalone for scriptc

Verified end-to-end: add/list/verify/disable/enable/audit/doctor/remove
on a fresh store + stdio bridge handshake with capability-gated
extensions.list.
@devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Cursor Bugbot was not present after the first check poll, so that automated-review signal was skipped. No applicable approval policy or remaining configured signal requires human review on the current head.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@devin-ai-integration
devin-ai-integration Bot merged commit 3ad0ef5 into v2 Oct 8, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant