@tangle-network/traces 0.21.1 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -7
- package/dist/{chunk-LB6AD6SX.js → chunk-COSWFESO.js} +615 -574
- package/dist/cli.js +69 -11
- package/dist/index.d.ts +100 -31
- package/dist/index.js +9 -3
- package/docs/trace-analysts.md +3 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -270,7 +270,6 @@ not the way to integrate a system you own — for that, [emit the contract](#int
|
|
|
270
270
|
| `qwen` (`qwen-code`) | `~/.qwen/projects/<cwd>/chats/*.jsonl` | fixture |
|
|
271
271
|
| `amp` | `~/.local/share/amp/threads/T-*.json` | fixture |
|
|
272
272
|
| `github-copilot` (`copilot`) | `~/.copilot/session-state/<id>/events.jsonl` | fixture |
|
|
273
|
-
| `forge` (`forgecode`) | `/dump` JSON exports | fixture |
|
|
274
273
|
|
|
275
274
|
Every adapter captures the conversation stored in one session file: the **user's prompt** and the **assistant's response** text, plus tool calls/results and token usage.
|
|
276
275
|
Claude Code, Codex, current OpenCode, Pi, Kimi, and Factory read native records through [`@tangle-network/harness-sessions`](https://github.com/tangle-network/agent-sdk/tree/main/packages/harness-sessions); traces adds conversation and workflow spans over its model and tool calls. Historical OpenCode JSON sessions remain readable through the older adapter because their IDs do not overlap the SQLite store. Kimi's wire log has no served-model field, so its model remains unknown rather than being guessed.
|
|
@@ -282,7 +281,6 @@ The Claude transcript proves turns and tool calls, but does not prove loop itera
|
|
|
282
281
|
Codex stores each worker in a separate session file; add `--workflow` to resolve the connected coordinator and worker files.
|
|
283
282
|
`github-copilot` is the one exception: its log format carries no user prompt.
|
|
284
283
|
Factory stores token totals in `.settings.json`, not per turn.
|
|
285
|
-
Forge reads `/dump` JSON exports; live SQLite remains unsupported.
|
|
286
284
|
ACP-only bridges may not persist a local transcript.
|
|
287
285
|
|
|
288
286
|
## CLI reference
|
|
@@ -297,6 +295,7 @@ traces investigate --all --last 10 --out report.md # explicit investigation ali
|
|
|
297
295
|
traces improve --all --last 10 --dir .traces/improvement
|
|
298
296
|
traces ask --harness codex --session <id> --question "Which commands failed?"
|
|
299
297
|
traces facts --harness codex --session <id> # the deterministic facts sheet, $0
|
|
298
|
+
traces facts --all --since 2026-10-14 --until 2026-10-15 # every session with a record that day, that day's turns
|
|
300
299
|
traces skills --since 30d # skill use across every local session, incremental, $0
|
|
301
300
|
traces diff run-a.otlp.jsonl run-b.otlp.jsonl # where two runs of one task first diverge
|
|
302
301
|
traces mcp --otlp spans.otlp.jsonl # read-only trace tools for an MCP client
|
|
@@ -349,7 +348,8 @@ See [Replay verification](./docs/replay-verify.md) for setup, semantics, and hon
|
|
|
349
348
|
| `--workflow` | Expand selected files through stable parent and child session IDs |
|
|
350
349
|
| `--max-workflow-sessions <n>` | Stop workflow expansion before parsing more than `n` files; default `100` |
|
|
351
350
|
| `--cwd <dir>` | Filter by working directory |
|
|
352
|
-
| `--since <t>` | `
|
|
351
|
+
| `--since <t>` | `30m`/`2h`/`7d` before now, or an ISO date. Commands that select sessions read those modified at or after it; `upload`: its window (default 24h); `facts`: opens a time window — see [Session facts](#session-facts) |
|
|
352
|
+
| `--until <t>` | `facts`: closes the time window (exclusive), same forms as `--since` |
|
|
353
353
|
| `--out <path>` | Write the report to a file |
|
|
354
354
|
| `--dir <path>` | `improve`: write the full artifact pack to this directory; `ask`: write `answers.json` + `report.md` there |
|
|
355
355
|
| `--otlp <file\|dir>` | **READ** OTLP-JSONL from any system, skipping the adapters; a directory reads the OTLP files under it (only `otlp/` when the producer made one) and names the JSONL that is not OTLP. `validate`, `check`, `analyze`, `investigate`, `improve`, `ask`, `stream` |
|
|
@@ -592,11 +592,14 @@ The same facts sheet includes observed tool outcomes, captured input/output byte
|
|
|
592
592
|
volumes, call-to-result intervals, compaction boundaries and available context
|
|
593
593
|
sizes, spawn intervals, and existing skill invocation/document-read evidence.
|
|
594
594
|
Each measurement carries coverage; absent telemetry remains unknown.
|
|
595
|
-
`facts --no-content` withholds conversation
|
|
596
|
-
|
|
595
|
+
`facts --no-content` withholds conversation (including each turn's `answered` text),
|
|
596
|
+
command, changed-file, working-directory and assignment text while retaining
|
|
597
|
+
measurement metadata. This is a local metadata view, not a
|
|
597
598
|
share-safety certificate.
|
|
598
599
|
|
|
599
600
|
SDK consumers use `buildSessionFactsReport(spans, { includeContent: false })`.
|
|
601
|
+
Pass `window: { since, until }` (ISO bounds) for the windowed report `facts --since/--until` prints, and use
|
|
602
|
+
`createSessionFactsReportBuilder(options)` (`add(spans)`, `addUnread(...)`, `build()`) to build it one session at a time.
|
|
600
603
|
Cache by `measurementVersion` and `sourceDigest`; `evidenceThrough` is the latest
|
|
601
604
|
recorded endpoint, not current liveness. Computing the sheet parses the supplied
|
|
602
605
|
spans; returning a stored sheet needs no model call or trace scan. Semantic
|
|
@@ -610,8 +613,17 @@ No model call, no engine, no budget — it costs $0 and always returns the same
|
|
|
610
613
|
traces facts --harness codex --session <id> # JSON on stdout
|
|
611
614
|
traces facts --harness codex --last 5 --format text # the short readable form
|
|
612
615
|
traces facts --otlp spans.otlp.jsonl --out facts.json
|
|
616
|
+
traces facts --harness claude-code --since 7d # every session with a record in the last week
|
|
617
|
+
traces facts --all --since 2026-10-14 --until 2026-10-15 # one day, across every harness
|
|
613
618
|
```
|
|
614
619
|
|
|
620
|
+
`--since <t>` and `--until <t>` open a half-open time window `[since, until)`; each takes `30m`/`2h`/`7d` before now or an ISO date, and either may be left open.
|
|
621
|
+
With a window, `facts` selects **every** session with a record that starts or ends inside it, not only the newest (`--last <n>` still caps it to the newest `n` per harness, and `--session` or `--otlp` still name the input).
|
|
622
|
+
Sessions are read one at a time, and a session file last modified before `since` is not read, because it cannot hold a later record.
|
|
623
|
+
Within a selected session, `humanTurns`, `excludedTurns` and `turnsByActor` keep only turns that started inside the window, so a one-day run counts only that day's turns; every other fact covers the whole session.
|
|
624
|
+
The report's `selection` states the window, both rules, the sessions read whose records all fell outside it (`outsideWindow`), and every session that could not be read (`unreadSessions`, each with its reason).
|
|
625
|
+
A report built without a window has `selection: null`.
|
|
626
|
+
|
|
615
627
|
| Fact | What it is |
|
|
616
628
|
|---|---|
|
|
617
629
|
| `toolCalls` | TOOL spans **this session's agent** actually invoked. Synthesized lifecycle spans are excluded and counted in `synthesizedToolSpans`, so the total is not high by the number of subagents; calls a spawned subagent made are excluded and counted in `subagentToolSpans` |
|
|
@@ -619,7 +631,8 @@ traces facts --otlp spans.otlp.jsonl --out facts.json
|
|
|
619
631
|
| `subagentToolSpans` | TOOL spans excluded because a subagent, not this agent, made the call. Zero on a trace that carries no subagent records |
|
|
620
632
|
| `subagents` | every subagent-spawning call with the task name the adapter recorded |
|
|
621
633
|
| `pullRequests` | the pull requests the commands created and merged, each named by number or head branch, with the command span and how the identity was joined. Scanned the way a shell reads the script, so a `gh pr create` inside a heredoc body is not a command that ran |
|
|
622
|
-
| `
|
|
634
|
+
| `cwd` | the working directory the harness recorded for the session (`traces.session.cwd` on the root span): Claude Code's first record `cwd`, Codex's `session_meta` cwd, Pi's session header, OpenCode's session directory (the older JSON store: its messages' `path.cwd`), Factory's `session_start`. Never decoded from a directory name or inferred from paths; `null` with the reason when the source names none or its adapter does not read one |
|
|
635
|
+
| `humanTurns` | `user.prompt` turns a person typed into this session, in order, with the timestamp. Inherited fork or compaction history, harness-injected blocks, and a second record of the same turn are excluded — each listed in `excludedTurns` with its reason and span ids, never silently dropped. `turnsByActor` shows every turn by actor so the filter is checkable. Each turn's `answered` is the last message this session's own agent wrote before it (not a subagent's, not inherited history), clipped to 1,500 characters with a `… [+N chars]` marker, with its span in `answeredSpanId`; `null` when the agent had written no text yet in the spans read (a `--latest-turn` read starts at the latest task, so its first turn has none) |
|
|
623
636
|
| `finalMessages` | the last message of the session's own agent, and of each subagent task, kept apart |
|
|
624
637
|
| `changedFiles` | paths the harness recorded for the changes it applied, plus paths named by patch headers and file-editing tool arguments, with the operation |
|
|
625
638
|
| `firstRecordAt` / `lastRecordAt` | the earliest span start and latest span end among this session's own records — a subagent that outlives the session does not stretch its window |
|
|
@@ -633,7 +646,8 @@ Three rules hold for every field:
|
|
|
633
646
|
- **Every fact names its span ids.** `spanIds` lists the spans the value was computed from, so any number here can be opened and checked. The sheet itself is not a span and cannot be cited.
|
|
634
647
|
- **A fact the spans cannot support is `null` with its reason.** It is never guessed, and never a silent zero. `partial` marks a measured value that is known to be incomplete — a truncated patch, or a list above the entry cap.
|
|
635
648
|
|
|
636
|
-
`facts` exits non-zero when a selected session cannot be read at all: a session that produced no record spans would otherwise print a sheet of zeros stating, in the sheet's own voice, that the session did nothing.
|
|
649
|
+
Without a window, `facts` exits non-zero when a selected session cannot be read at all: a session that produced no record spans would otherwise print a sheet of zeros stating, in the sheet's own voice, that the session did nothing.
|
|
650
|
+
With a window, a session that cannot be read — the parser failed, or no record could be read — is named in `selection.unreadSessions` with its reason and a warning on stderr, and the run still exits 0 with the sessions it could read; it is never counted as a session with no turns.
|
|
637
651
|
|
|
638
652
|
The same sheet reaches the model-backed analysts as prepared context, before their first model call — see [Trace analysts](docs/trace-analysts.md#session-facts-as-prepared-context).
|
|
639
653
|
|