refactor: #203 follow-up — agentkeys-protocol wire crate (wasm-safe) + ts-rs frontend bindings#215
Open
hanwencheng wants to merge 1 commit into
Open
refactor: #203 follow-up — agentkeys-protocol wire crate (wasm-safe) + ts-rs frontend bindings#215hanwencheng wants to merge 1 commit into
hanwencheng wants to merge 1 commit into
Conversation
…+ ts-rs frontend bindings B1 + B2 of docs/plan/frontend-testability-cli-web-parity.md (after the Codex adversarial review). B1: extract the broker/worker wire types into a standalone wasm-safe agentkeys-protocol crate (pure serde). agentkeys-backend-client re-exports them as ::protocol (back-compat); agentkeys-web-core (wasm) now shares them instead of its own copy, killing the cap-mint ttl_seconds drift (u64 vs Option<u64>). The shared on-wire BrokerCapRequest uses Option<u64> + skip (faithful to the broker's serde default); the native caller-side CapMintRequest is unchanged (no ripple to mcp/daemon). New CI gate: cargo check --target wasm32-unknown-unknown -p agentkeys-web-core proves no native deps (aws-sdk-sts/tokio) leak into the browser build. B2: generate the frontend Api* wire types from the daemon's ui_bridge.rs structs via ts-rs (apps/parent-control/lib/generated/); daemon.ts imports them and drops the 5 hand-declared interfaces (-49 lines). u64 -> number, skip-serialize Options -> optional. New CI gate: cargo test regenerates + git diff --exit-code on the generated dir, so a daemon struct rename is a frontend compile error. Verified: cargo build/test/clippy -D warnings (native + wasm32), npm run typecheck (clean except pre-existing core.ts wasm-artifact errors), fixture --check unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
B1 + B2 of the frontend-testability / CLI↔web-parity plan (
docs/plan/frontend-testability-cli-web-parity.md), implemented after a Codex adversarial review. Both push the broker/worker wire contract down the parity ladder (CLAUDE.md "Parity/wiring checks evolve down a ladder"): from hand-mirrored copies that drift silently → to a single shared definition where drift is a compile error / CI-red.Builds on #213 (which removed the in-memory MCP backend + collapsed the
Backendwrapper) — that was B0.B1 —
agentkeys-protocol: one wasm-safe wire-type crateprotocol.rs) into a standaloneagentkeys-protocolcrate — pure serde, no transport, compiles towasm32.agentkeys-backend-client(native, + STS via the provisioner) re-exports them as::protocol(back-compat — every existingagentkeys_backend_client::protocol::*path still resolves).agentkeys-web-core(browser/wasm) now shares the same crate instead of its own copy — killing a live cap-mint drift:ttl_secondswas a requiredu64in backend-client butOption<u64>in web-core. The shared on-wireBrokerCapRequestusesOption<u64>+ skip (faithful to the broker's#[serde(default = "default_ttl_seconds")]); the native caller-sideCapMintRequeststaysu64→ zero ripple to mcp-server/daemon, and the wire stays byte-identical (it always sendsSome(..)).agentkeys-backend-clientdirectly? (the Codex finding) — that crate pullsaws-sdk-sts+tokio+ nativereqwestvia the provisioner and breaks the wasm build. Sharing only the pure-serde protocol crate avoids that.harness-ci.ymlrust-checks):cargo check --target wasm32-unknown-unknown -p agentkeys-web-core(default +--features wasm) — fails if a native dep ever leaks into the browser build.B2 — ts-rs: generate the frontend
Api*wire typesui_bridge.rsApi*structs derivets_rs::TSand export toapps/parent-control/lib/generated/*.ts.apps/parent-control/lib/client/daemon.tsimports the generated types and drops the 5 hand-declared interfaces (−49 lines). A daemon-side field rename is now a frontend compile error instead of silent drift (rung 2 → rung 3).u64→number(#[ts(type = "number")]; ts-rs defaults tobigint, which the JSON wire + mappers don't use); skip-serializeOptions → optional?:(#[ts(optional)]).cargo testregenerates the bindings, thengit diff --exit-code apps/parent-control/lib/generated/fails if a struct changed without committing the regenerated.ts(same discipline as the backend-protocol fixtures).Verification
cargo build --workspace✓ ·cargo test(protocol + backend-client + web-core + daemonexport_bindings) ✓ ·cargo clippy -D warnings(native + daemon) ✓cargo check --target wasm32-unknown-unknown -p agentkeys-web-core(default +--features wasm) ✓ — confirmed noaws-sdk-sts/tokio in the wasm dep tree.npm run typecheck✓ — clean except 2 pre-existingcore.tserrors (thelib/wasm/wasm-pack output isn't built in a fresh checkout; unrelated to this PR).--check✓ —cap_mint_request.jsonbyte-unchanged.What did NOT land (rest of the plan)
CapTokenis opaque-by-design (no drift); pairing isn't duplicated. Documented in the plan doc.FakeBackend+ Playwright) — not started.ApiProposedScope+ classify/credentials wire types are still hand-declared indaemon.ts— next ts-rs codegen batch.🤖 Generated with Claude Code