Repository navigation
[G2] Expose the new evidence through napi, the TypeScript SDK and MCP (markers, tool-result facts, usage/requests, control kinds, continuity, change feed) with contract bumps #181
Description
Part of #160 (group 2 — depends on #164, #165, #169, #170, #171, #172, #175; and on #178/#179/#180 for their parts, which may land as follow-up commits under this issue. Parallel with #182).
Problem
The group-1 issues add columns and core read functions but deliberately leave the JS-facing layers for one coordinated change, because every field crosses four contract boundaries that are versioned separately (docs/architecture.md: native 15, catalog 3, hydration 2, relationship 1, evidence 1) and asserted by sdk-ts/src/{architecture,local-history-contract,session-evidence,relationships}.test.ts. Landing them piecemeal would bump NATIVE_CONTRACT_VERSION (sdk-ts/src/native.ts:22, crates/ai-hist-napi/src/lib.rs:161) six times.
After #162/#178 the napi crate may only call the SessionStore facade (plus the unstable-internal feature where a maintenance verb needs it). The napi layer today mirrors ~20 typed functions by hand; it also already has a JSON-in/JSON-out path for source plugins (crates/ai-hist-napi/src/sources.rs:29-43). Prefer the JSON path for the new operations: one session_store_call(op: String, args_json: String) -> String dispatcher over the seven facade methods, with the typed TS layer doing validation/normalization as it does now. That keeps the napi surface from growing by another dozen hand-mirrored functions and makes the TS SDK's native.ts the single place that knows the op names. Existing typed functions stay for compatibility until a later major.
Scope
- napi (
crates/ai-hist-napi/src/lib.rs): extendNativeSessionEvent(:249) withrequest_id, stop_reason, agent_version, is_sidechain, is_meta, turn_id, provider, project_key, control_kind, payload_bytes, payload_truncated, payload_hash, call_index, event_index, result_status, event_source, error_signal, subagent_session_id, agent_id, revision; add the JSON dispatcher coveringsession(fullSessionEvidence, withkinds/include_text),changes_since(+ consumer commit),capabilities,markers,requests,usage_summary,user_turns; extendhydrate_sessionresult withcapability/coverage([G1] Hydration reports capability "full" unconditionally for local sources; compute it from covered evidence kinds #169) and relationships with continuity kinds ([G1] First-class fork / resume / continuation relationships with cross-file reconciliation (Claude and Codex) #170). OneNATIVE_CONTRACT_VERSIONbump (15 → 16). - TS contracts (
sdk-ts/src/contracts.ts,normalization.ts,operations.ts,pagination.ts): new interfacesSessionMarker,SessionRequest,SessionUsageSummary,UserTurnBlock,EvidenceChange,SourceCapabilities,SessionEvidence;RelationshipTypewidened;tokenUsage()(normalization.ts:165) additionally returnsnormalizedUsage(fromsession_requests) beside the raw parsedtoken_json; async iteratorssessionMarkers,sessionRequests,changesSince. Bump catalog/hydration/relationship/evidence contract constants as each group-1 issue specified; the SDK validates all of them at load. - MCP (
sdk-ts/src/mcp-server.ts): new toolsget_session_markers,get_session_usage,get_session_requests,get_source_capabilities;get_session_eventsoutput gains the new fields; tool descriptions state accounting semantics ("usage is provider-reported; cost is not computed"). - CLI (
sdk-ts/src/cli.ts,crates/ai-hist-cli):ai-hist sessions markers SOURCE ID,ai-hist sessions usage SOURCE ID,ai-hist events --jsongains the fields additively;ai-hist sessions listgains--project <key>. - Offline fixture DB
sdk-ts/fixtures/offline-history.db.gzregenerated viaregenerate-offline-history.mjsfrom the corpus so TS tests exercise the new columns. - Docs:
docs/architecture.mdoperation table + contract list, reference for the new operations,CHANGELOG.mdBreaking + Added.
Acceptance
npm testgreen with the regenerated fixture DB;architecture.test.tsasserts the new contract versions.- MCP
get_session_usageon the corpus Claudemulti-block-turnreturns the same numbers as the Rustsession_usage_summary. ai-hist events --jsonon aslash-command-triadsession showscontrol_kindon the three rows.- A consumer on the old
ai-hist-nativeplatform package gets the existing contract-mismatch error, not a silent undefined field. crates/ai-hist-napicompiles against theSessionStorefacade only (grep forrusqlitein the napi crate returns nothing).
Out of scope
The Rust facade itself (#178).
Activity
Fix four review findings on the session-marker parsers
feat(sdk)!: read the change feed from Node (native contract 25)
test(sdk): assert #181's acceptance against the Rust fixture corpus
docs: merge the stale changes_since row; say get_session_requests nev…