Skip to content

[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

Open

Description

@willwashburn

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

  1. napi (crates/ai-hist-napi/src/lib.rs): extend NativeSessionEvent (:249) with request_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 covering session (full SessionEvidence, with kinds/include_text), changes_since (+ consumer commit), capabilities, markers, requests, usage_summary, user_turns; extend hydrate_session result with capability/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). One NATIVE_CONTRACT_VERSION bump (15 → 16).
  2. TS contracts (sdk-ts/src/contracts.ts, normalization.ts, operations.ts, pagination.ts): new interfaces SessionMarker, SessionRequest, SessionUsageSummary, UserTurnBlock, EvidenceChange, SourceCapabilities, SessionEvidence; RelationshipType widened; tokenUsage() (normalization.ts:165) additionally returns normalizedUsage (from session_requests) beside the raw parsed token_json; async iterators sessionMarkers, sessionRequests, changesSince. Bump catalog/hydration/relationship/evidence contract constants as each group-1 issue specified; the SDK validates all of them at load.
  3. MCP (sdk-ts/src/mcp-server.ts): new tools get_session_markers, get_session_usage, get_session_requests, get_source_capabilities; get_session_events output gains the new fields; tool descriptions state accounting semantics ("usage is provider-reported; cost is not computed").
  4. 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 --json gains the fields additively; ai-hist sessions list gains --project <key>.
  5. Offline fixture DB sdk-ts/fixtures/offline-history.db.gz regenerated via regenerate-offline-history.mjs from the corpus so TS tests exercise the new columns.
  6. Docs: docs/architecture.md operation table + contract list, reference for the new operations, CHANGELOG.md Breaking + Added.

Acceptance

  • npm test green with the regenerated fixture DB; architecture.test.ts asserts the new contract versions.
  • MCP get_session_usage on the corpus Claude multi-block-turn returns the same numbers as the Rust session_usage_summary.
  • ai-hist events --json on a slash-command-triad session shows control_kind on the three rows.
  • A consumer on the old ai-hist-native platform package gets the existing contract-mismatch error, not a silent undefined field.
  • crates/ai-hist-napi compiles against the SessionStore facade only (grep for rusqlite in the napi crate returns nothing).

Out of scope

The Rust facade itself (#178).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions