feat: portable coding agent across cli, web, mobile, and p2p#1032
feat: portable coding agent across cli, web, mobile, and p2p#1032ital0 wants to merge 87 commits into
Conversation
…sessions, more providers
Semgrep Security ScanNo security issues found. |
|
Preview environment deployed 🚀
Stack: Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — |
PR Metrics
Updated Fri, 10 Jul 2026 19:21:09 GMT · run #2261 |
c8d43a1 to
6be900d
Compare
There was a problem hiding this comment.
🔭 thunder-deep-review (advisory)
Complements the other bots — surfaces only what they did not flag. Never approves, never requests changes, never gates merge.
head: 6be900d44995 · mode: deep · deferred 5 item(s) already reported by other bots (best-effort dedup)
| }, | ||
| } | ||
|
|
||
| return [createBashTool(workspaceDir), jailedRead, jailedWrite, jailedEdit] |
There was a problem hiding this comment.
🚫 Blocking — Workspace jail confines read/write/edit but ships bash unconfined
Heads up — this is the one that worries me. createWorkspaceTools carefully wraps read/write/edit so their paths resolve inside the workspace, but then hands back createBashTool(workspaceDir) with no confinement at all. workspaceDir is only bash's cwd, so the model can walk straight out with cat ../../etc/passwd or an absolute path. This is the confinement layer used for the ACP serve path with untrusted remote peers, and in yolo mode the ACP gate auto-approves bash with no path check — so the jailed read/write/edit tools give a false sense of safety while their bash sibling defeats it. Could we either confine bash's cwd/argv to the workspace, or make it explicit that bash is intentionally unconfined and the jail is path-tools-only (and reconcile that with the yolo auto-approve)?
| } | ||
| const context = threadCtx('t-persist-retry', { onAcpSessionId }) | ||
|
|
||
| expect(adapter.fetch(init, context)).rejects.toThrow('persistence failed') |
There was a problem hiding this comment.
📐 Convention — The .rejects assertion isn't awaited, so it may never actually run
This expect(...).rejects.toThrow('persistence failed') isn't awaited. .rejects.toThrow() returns a promise, and without await the assertion can fail to settle before the test moves on — and the very next line does await drive(adapter, init, context, ...) reusing the same init/context, racing the still-in-flight first fetch. I'd add await in front so the first send's rejection is actually asserted and settled before the retry.
Note
Medium Risk
Touches encryption/device trust and a DB migration for P2P dialability; mitigated by canary proof, trusted-caller checks, upload deny lists, and broad tests, but deploy still needs migration 0021.
Overview
Adds server-managed iroh P2P identity for devices: migration
0021storesnode_id/node_id_attested_atonpowersync.devices, and a new canary-gatedPOST /devices/:deviceId/node-idlets only a trusted caller (withX-Device-ID+ validcanarySecret) bind a peer’s endpoint.node_idis deny-listed on PowerSync uploads; revoke, deny, and re-registration clear the binding so revoked/denied peers stay undialable.CI/release expands for the portable agent stack: path-filtered jobs for
shared/agent-core,cli/, and wasm artifact staleness/checksum checks;rustalso buildscrates/thunderbolt-acp-client. A new CLI release workflow builds darwin-arm64 / linux x64 & arm64 binaries and attaches them (plusSHA256SUMS) to the sharedv{version}GitHub Release, hooked fromrelease.ymlforalland nightly runs.Smaller config/tooling tweaks: optional
VITE_IROH_RELAY_URLin.env.example, Prettier ignores for committed wasm glue, and a narrowed backendtsconfigshared include list. Newpowersyncupload gate tests cover device trust spoofing and delete isolation.Reviewed by Cursor Bugbot for commit a4a0393. Bugbot is set up for automated code reviews on this repo. Configure here.