feat(claude-code): local Claude Code connector with full agent traces - #25
Open
volod-vana wants to merge 1 commit into
Open
feat(claude-code): local Claude Code connector with full agent traces#25volod-vana wants to merge 1 commit into
volod-vana wants to merge 1 commit into
Conversation
Publishes the local Claude Code connector (previously only on my machine)
and adds the scope this was built for: `claude_code.trajectories`, the
full step-by-step trace of each session.
Semo AI (and buyers like them) want agent trajectories, not chat: the
action-observation loop of a real run. Claude Code already writes exactly
that to ~/.claude/projects/*.jsonl. `claude_code.sessions` deliberately
carries only the shape of a run; the new scope carries the bodies.
Scopes
- claude_code.usage aggregate tokens, cost, activity (unchanged)
- claude_code.sessions per-session metadata, no bodies (unchanged shape,
now also lists subagent runs, linked to their parent)
- claude_code.prompts typed prompt history (unchanged, now redacted)
- claude_code.trajectories NEW: prompts, assistant reasoning and replies,
every tool call with its input, every tool result
with its output, in order. Calls and results are
linked by callId so the loop can be rebuilt without
reparsing the transcript.
Why it is a separate scope: these payloads contain source code, file paths
and command output from the machine. Its own scope means a user can grant the
cheap metadata without ever granting the transcript, and a host can gate the
two differently.
Safety rails
- credential-shaped strings are redacted before export (Anthropic/OpenAI keys,
GitHub tokens/PATs, Slack, AWS, Google, JWTs, bearer tokens, PEM blocks,
0x64-hex, and SECRET/TOKEN/PASSWORD-style assignments); the count is
reported by type, the matched text never is
- per-step bodies capped (CLAUDE_CODE_MAX_STEP_CHARS, default 8000)
- whole-scope payload budget (CLAUDE_CODE_MAX_MB, default 24), newest first
- both caps surface as `degraded` honest-telemetry errors, so a capped export
can never be mistaken for a complete one
Redaction is best-effort pattern matching, not de-identification. It is the
floor, not the guarantee.
Also in this change
- subagent transcripts (`<session>/subagents/agent-*.jsonl`) were invisible to
the old single-level walk. On my machine that was 144 of 310 traces. The walk
now recurses and tags each transcript with `kind` and `parentSessionId`.
- the result envelope now satisfies the honest-telemetry contract it never did
before: `requestedScopes`, an `errors` array, and an object-shaped
`exportSummary.details`. Scopes are also gated on requestedScopes, so a host
asking for metadata alone never pays to build traces.
- schemas/scope-catalog.schema.json only accepted `*-playwright.json`
manifests in its provenance list. The manifest schema has always allowed
`runtime: vanilla`, so the filename pattern was the stale half.
Verified end to end on this machine through the real runner
(`node run-connector.cjs connectors/anthropic/claude-code-local.js`):
310 sessions (166 main + 144 subagent), 26,036 trace steps, 10,354 tool calls,
1,539 redactions, 24 MB at the default budget, classified `partial` with the
budget and truncation reported as degraded. All four payloads validate against
their published schemas. Unit tests 15/15; manifest, source-id-stability,
scope-catalog, additive-schema and page-api checks clean.
Claude-Session: https://claude.ai/code/session_012ZQPAhPHFaF3fmmxUNHma8
Schema Health Check — All ClearAll 54 scopes have consistent local schema files. |
volod-vana
marked this pull request as ready for review
July 31, 2026 05:13
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.
Why
A buyer conversation (Semo AI) asked for agent trajectories — the action-observation loop of real runs — not chat transcripts. Claude Code already writes exactly that to
~/.claude/projects/*.jsonl. This publishes the local Claude Code connector and adds the scope that carries it.claude_code.sessionsdeliberately carries only the shape of a run (turn counts, models, timing).claude_code.trajectoriescarries the bodies.Scopes
claude_code.usageclaude_code.sessionsclaude_code.promptsclaude_code.trajectoriesTool calls and results are linked by
callId, so a consumer can rebuild the loop without reparsing the transcript. Steps carryrole,type,at,model, andsidechain.Why a separate scope: these payloads contain source code, file paths and command output from the machine. Its own scope lets a user grant the cheap metadata without ever granting the transcript, and lets a host gate the two differently.
Safety rails on the trajectory scope
0x+64-hex, andSECRET/TOKEN/PASSWORD-style assignments. The count is reported by type; the matched text never is.CLAUDE_CODE_MAX_STEP_CHARS(default 8000), each cut body marks itselftruncatedwith its original length.CLAUDE_CODE_MAX_MB(default 24), newest sessions first.degradedhonest-telemetry errors, so a capped export can never be mistaken for a complete one.Redaction is best-effort pattern matching, not a de-identification pipeline. It is the floor, not the guarantee. Anything sold or shared still needs a real privacy pass.
Two fixes that came out of building it
<project>/<sessionId>.jsonland missed<session>/subagents/agent-*.jsonl. On my machine that was 144 of 310 traces. The walk now recurses and tags each transcript withkindandparentSessionId.requestedScopes, noerrorsarray, and a stringexportSummary.details. Now it satisfiesvalidate-honest-telemetry-conformance, and scopes are gated onrequestedScopesso a host asking for metadata alone never pays to build traces.schemas/scope-catalog.schema.jsononly accepted*-playwright.jsonin its provenance list. The manifest schema has always allowedruntime: vanilla, so the filename pattern was the stale half.Verification (real run, this machine)
node run-connector.cjs connectors/anthropic/claude-code-local.js --runner-dir <desktop runner>secret_assignment1077,hex_secret429,bearer16,jwt10,anthropic_key3,github_token2,google_key2)degradedpartial,scopeSummary: {requested: 4, produced: 4, degraded: 1, omitted: 0}Checks: unit tests 15/15,
claude-export-ingest5/5,validate-manifests20 manifests 0 errors,check-source-id-stability,scope-catalog:check,check-additive-schemas(51),check-page-api-additiveall clean.Known trade-off
hex_secretredacts any0x+ 64 hex, which also catches transaction hashes and data-point ids. It fires often on Vana work (429 hits here). I kept it fail-safe — a raw private key has the same shape — and the tally makes the cost visible. Easy to narrow to context-matched hits if reviewers prefer.Not in this PR
https://claude.ai/code/session_012ZQPAhPHFaF3fmmxUNHma8