Skip to content

feat(web-core): WASM-ready broker core + browser CoreBackend + dev.sh build (W0/X0/X1/X2)#172

Merged
hanwencheng merged 3 commits into
mainfrom
claude/core-broker-client
Jun 2, 2026
Merged

feat(web-core): WASM-ready broker core + browser CoreBackend + dev.sh build (W0/X0/X1/X2)#172
hanwencheng merged 3 commits into
mainfrom
claude/core-broker-client

Conversation

@hanwencheng
Copy link
Copy Markdown
Member

@hanwencheng hanwencheng commented Jun 2, 2026

Implements the keystone slices of the web-wiring plan (docs/plan/web-flow/wire-real-paths.md), toward #163. (Supersedes the original "broker client in agentkeys-core" framing — agentkeys-core is native-heavy and can't compile to wasm, so the client moves to a minimal dual-target crate.)

What

  • NEW crate agentkeys-web-core — the host-agnostic broker client (cap-mint /v1/cap/{memory,cred}-* + pairing claim/pending/ack), moved from agentkeys-core via git mv. Builds for native AND wasm32: reqwest is default-features=false with the browser fetch backend on wasm and rustls-tls on native (target-gated); crate-type = [cdylib, rlib]. wasm-bindgen exports (WebCore) behind --features wasm.
  • agentkeys-core drops the broker module (no consumer yet; future native consumers depend on agentkeys-web-core).
  • Web CoreBackend (lib/client/core.ts) — lazy-loads the WASM pkg and talks to the broker directly (the phone-first X1 path, no daemon); exposes the cap/pairing calls for the onboarding/pairing slices. Selectable via NEXT_PUBLIC_AGENTKEYS_BACKEND=core (default broker broker.litentry.org). AgentKeysClient read endpoints inherit EmptyBackend's disconnected state until the later W-phases wire them (honest empty states).
  • dev.sh build_wasmwasm-pack build, cached by a src+Cargo.toml+wasm-pack-version hash (skip when unchanged — the "verify same version"), copies the .wasm to public/wasm; graceful no-op if wasm-pack is absent. The generated pkg + public/wasm are gitignored (never committed).

Verified

  • cargo test -p agentkeys-web-core (broker tests) + cargo clippy --all-targets -- -D warnings + cargo fmt clean; agentkeys-core still builds.
  • cargo build --target wasm32-unknown-unknown -p agentkeys-web-core --features wasm + wasm-pack build generate the pkg.
  • apps/parent-control: tsc --noEmit + next build clean (the wasm import bundles).
  • bash -n dev.sh.

Next slices (separate PRs)

  • Grow the core surface (onboarding-state, actors, audit) so CoreBackend implements more of AgentKeysClient.
  • The ERC-4337 UserOp builder/signer in the core (E7) — needs live-EntryPoint cross-validation.
  • Wire the web onboarding/memory/pairing against broker.litentry.org (the user-provided live broker) + the harness WebAuthn-driving approach.

🤖 Generated with Claude Code

First implementation slice of docs/plan/web-flow/wire-real-paths.md (merged #162):
a typed, host-agnostic `agentkeys-core::broker::BrokerClient` that the daemon
ui-bridge, the future WASM CoreBackend (web), and the mobile UniFFI shell all
share — so the browser/phone never re-implement broker calls in TS/Swift
("consistency is structural").

Covers the master-plane endpoints the web wiring proxies:
- cap-mint: /v1/cap/{memory-put,memory-get,cred-store,cred-fetch} → CapToken
- pairing (§10.2 method A, master-side): /v1/agent/pairing/claim,
  /v1/agent/pending-bindings, /v1/agent/pending-bindings/ack

Design: builds on init_flow's conventions (BrokerError{Transport,Rejected,Decode};
trim trailing slash); stores no secret (bearer passed per call); host-agnostic
(no fs/clock/env) so it compiles for the wasm32 browser-fetch target — feature-
gating the crate's reqwest for wasm is the separate X1 build step. The
email/OAuth/SIWE auth flow already lives in init_flow and is unchanged.

Tests: axum-stub server per method (cap round-trip + bearer; pairing claim;
pending→ack; non-2xx → Rejected mapping). cargo test -p agentkeys-core: 145+3 ok;
clippy --all-targets -D warnings clean; fmt clean.

Next (separate PRs): X1 wasm-pack build + reqwest wasm feature-gate; daemon
ui-bridge consumes this client; X2 CoreBackend behind AgentKeysClient.
… build (X0/X1/X2)

Evolves the #172 broker client into the phone-first host model. agentkeys-core is
native-heavy (aws-sdk, keyring) → can't compile to wasm, so the host-agnostic
broker client moves to a new minimal crate that builds for BOTH native and wasm32.

- NEW crate `agentkeys-web-core`: the broker client (moved from agentkeys-core via
  git mv — cap-mint + pairing) + wasm-bindgen exports (`WebCore`, behind `--features
  wasm`). reqwest is default-features=false with the browser fetch backend on wasm32
  and rustls-tls on native (target-gated). crate-type = [cdylib, rlib].
- agentkeys-core: drops the broker module (no consumer yet; future native consumers
  depend on agentkeys-web-core directly). Workspace member + dep added.
- web app: `lib/client/core.ts` — `CoreBackend` lazy-loads the WASM pkg + talks to the
  broker directly (X1); exposes the cap/pairing calls for the onboarding/pairing
  slices. Registered as `NEXT_PUBLIC_AGENTKEYS_BACKEND=core` (default broker
  broker.litentry.org). The AgentKeysClient read endpoints inherit EmptyBackend's
  disconnected state until the later W-phases wire them (honest empty states).
- dev.sh: `build_wasm` step — wasm-pack build, cached by a src+Cargo.toml+wasm-pack
  version hash (skip when unchanged), copies the .wasm to public/wasm; graceful no-op
  if wasm-pack absent. Generated pkg + public/wasm are gitignored.

Verified: cargo test/clippy (-D warnings)/fmt on agentkeys-web-core + agentkeys-core;
wasm32 build + wasm-pack pkg generate; apps/parent-control tsc + next build clean;
bash -n dev.sh.
@hanwencheng hanwencheng force-pushed the claude/core-broker-client branch from ba2a2fb to 6b1c424 Compare June 2, 2026 09:21
@hanwencheng hanwencheng changed the title feat(core): host-agnostic broker client — W0/X0 of the web-wiring plan (#163) feat(web-core): WASM-ready broker core + browser CoreBackend + dev.sh build (W0/X0/X1/X2) Jun 2, 2026
- core.ts: memoize the WASM core per broker URL (Map) + evict on reject, so a second CoreBackend with a different broker gets its own instance and a transient load/broker failure no longer poisons the cache forever (HIGH).
- broker.rs: native client gets a 20s request timeout (wasm keeps the fetch backend) so a stalled broker can't hang a worker thread (MED).
- broker.rs: bound the echoed broker error body to 512 chars so an oversized response can't bloat a JS rejection/log line; status + endpoint preserved. Adds a regression test (MED).
- dev.sh: stabilize the wasm src-hash -- sort the file list (filesystem order no longer flips the hash) + add workspace Cargo.toml/Cargo.lock + rustc version so a transitive-dep bump busts the cache (MED).

Deferred (tracked): broker CORS for the browser-direct path + typed TS DTOs land with the live web e2e slice. status() stays disconnected by design until the read endpoints are wired.

Verified: cargo test (5 passed) + clippy -D warnings + fmt + wasm-pack build + tsc --noEmit + next build all green.
@hanwencheng hanwencheng merged commit 9bc258c into main Jun 2, 2026
8 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