@tangle-network/traces 0.4.0 → 0.4.1

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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -20
  3. package/package.json +19 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tangle Network
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,26 @@
1
1
  # traces
2
2
 
3
- Analyze your coding-agent session logs for failure modes — stuck loops, token bloat, dropped self-verification — with zero instrumentation. It reads the logs your harness (Claude Code, Codex, OpenCode, …) already writes to disk.
3
+ > Point `traces` at the session logs your coding agent already writes to disk — Claude Code, Codex, OpenCode, Gemini, and more — and get failure-mode + efficiency findings. **Zero instrumentation.** A CLI *and* an SDK.
4
4
 
5
- `traces` is a CLI and an SDK: run it ad-hoc, or build on it.
5
+ ![traces analyzing a real Claude Code session](https://raw.githubusercontent.com/tangle-network/traces/main/docs/demo.gif)
6
+
7
+ [![npm](https://img.shields.io/npm/v/@tangle-network/traces.svg)](https://www.npmjs.com/package/@tangle-network/traces)
8
+ [![license](https://img.shields.io/npm/l/@tangle-network/traces.svg)](./LICENSE)
9
+ [![node](https://img.shields.io/node/v/@tangle-network/traces.svg)](https://nodejs.org)
10
+
11
+ It reads the transcripts your harness leaves on disk, reconstructs the run as spans, and reports where the agent got stuck, burned tokens, or stopped checking its own work — locally, with no API key and no cost for the deterministic pass.
12
+
13
+ ## Contents
14
+
15
+ - [Install](#install)
16
+ - [Quick start](#quick-start)
17
+ - [What it finds](#what-it-finds)
18
+ - [Supported harnesses](#supported-harnesses)
19
+ - [CLI reference](#cli-reference)
20
+ - [Upload to the Intelligence Platform](#upload-to-the-intelligence-platform)
21
+ - [Library (SDK)](#library-sdk)
22
+ - [Examples](#examples)
23
+ - [Develop](#develop)
6
24
 
7
25
  ## Install
8
26
 
@@ -12,25 +30,33 @@ npx @tangle-network/traces analyze # or run without installing
12
30
  npm i @tangle-network/traces # or use it as a library
13
31
  ```
14
32
 
33
+ Requires Node ≥ 22.
34
+
15
35
  ## Quick start
16
36
 
17
37
  ```bash
18
38
  traces analyze --harness claude-code --last 1
19
39
  ```
20
40
 
21
- ```
22
- # Trace report — claude-code · 1 session · 2,429 spans
41
+ That's the command in the demo above. The **deterministic pass** — stuck loops, token growth, output decay, missing self-verification, tool monoculture — needs no API key and costs nothing.
23
42
 
24
- ## Stuck loops
25
- - `bash` ×7 with identical args in 48s (same git status retried, no state change)
43
+ Add `--llm` for the **agentic analysts** (failure-mode / knowledge-gap / knowledge-poisoning / improvement); they call OpenAI and respect `--budget <usd>`.
26
44
 
27
- ## Tool use
28
- - 1,204 tool calls · duplicate-call 22% · retry 6% · error 8%
29
- ```
45
+ Every run also writes an **OTLP-JSONL artifact** that feeds [HALO](https://github.com/context-labs/halo) (`halo spans.jsonl -p "diagnose"`) — analysis is never locked to one engine.
46
+
47
+ ## What it finds
48
+
49
+ The deterministic pass (free, no key) surfaces:
30
50
 
31
- The deterministic pass (stuck loops, token growth, tool monoculture, missing self-verification) needs no API key and costs nothing. Add `--llm` for the agentic analysts (failure-mode / knowledge-gap / knowledge-poisoning / improvement); they call OpenAI and respect `--budget`.
51
+ | Finding | Meaning |
52
+ |---|---|
53
+ | **Stuck loops** | the same tool called N× with identical args and no state change |
54
+ | **Monotonic input growth** | full history re-sent every step — context never compressed |
55
+ | **Output-length decay** | planning/reasoning per step shrinking as context grows |
56
+ | **No self-verification** | state-mutating actions never followed by an eval/inspect/check |
57
+ | **Tool monoculture / retry / error rates** | the shape of how the agent actually spent its calls |
32
58
 
33
- The written OTLP-JSONL artifact also feeds [HALO](https://github.com/context-labs/halo) (`halo spans.jsonl -p "diagnose"`) — analysis is never locked to one engine.
59
+ `--llm` adds agentic analysts that read the conversation and cluster higher-order failure and improvement signals.
34
60
 
35
61
  ## Supported harnesses
36
62
 
@@ -49,9 +75,9 @@ The written OTLP-JSONL artifact also feeds [HALO](https://github.com/context-lab
49
75
  | `github-copilot` (`copilot`) | `~/.copilot/session-state/<id>/events.jsonl` | fixture |
50
76
  | `forge` (`forgecode`) | `/dump` JSON exports | fixture |
51
77
 
52
- Factory stores token totals in `.settings.json`, not per turn. Forge reads `/dump` JSON exports (live SQLite is a follow-up). ACP-only bridges may not persist a local transcript.
78
+ Every adapter captures the full conversation — the **user's prompt** and the **assistant's response** text, plus tool calls/results and token usage. (`github-copilot` is the one exception: its log format carries no user prompt.) Factory stores token totals in `.settings.json`, not per turn. Forge reads `/dump` JSON exports (live SQLite is a follow-up). ACP-only bridges may not persist a local transcript.
53
79
 
54
- ## Commands
80
+ ## CLI reference
55
81
 
56
82
  ```bash
57
83
  traces list --harness claude-code --last 20 # discover sessions
@@ -78,20 +104,30 @@ traces upload --since 24h # upload last day to the Inte
78
104
  | `--min-loop <n>` | Identical repeated calls before flagging a loop (default 3) |
79
105
  | `--dry-run` / `--yes` | `upload`: preview without sending / skip the confirm prompt |
80
106
 
81
- `upload` redacts PII/secrets locally before anything leaves the machine, dedups against already-uploaded sessions, and tags each with metadata (harness, cwd, git branch, host). It needs `TANGLE_INGEST_URL` (or `TANGLE_ORCHESTRATOR_URL`), `TANGLE_INGEST_API_KEY` (or `TANGLE_API_KEY`), and `TANGLE_TENANT_ID`; without them, `--dry-run` still works.
107
+ ## Upload to the Intelligence Platform
108
+
109
+ `upload` **redacts PII/secrets locally before anything leaves the machine**, dedups against already-uploaded sessions, and tags each with metadata (harness, cwd, git branch, host).
110
+
111
+ ```bash
112
+ traces upload --since 24h --dry-run # see exactly what would be sent — no network
113
+ traces upload --since 24h # send it
114
+ ```
82
115
 
83
- ## Use as a library
116
+ It needs `TANGLE_INGEST_URL` (or `TANGLE_ORCHESTRATOR_URL`), `TANGLE_INGEST_API_KEY` (or `TANGLE_API_KEY`), and `TANGLE_TENANT_ID`. Without them, `--dry-run` still works fully.
84
117
 
85
- The CLI is a thin consumer of these exports. Full runnable examples in [`examples/`](./examples).
118
+ ## Library (SDK)
119
+
120
+ The CLI is a thin consumer of these exports.
86
121
 
87
122
  | Export | Signature | Use |
88
123
  |---|---|---|
89
124
  | `analyzeSpans` | `(spans, { registry?, ai?, budgetUsd? }) → AnalyzeResult` | run analysts — built-in, or **your own** via `registry` |
90
125
  | `watchSessions` | `(ObserverOptions) → Promise<void>` | live observer; `onLoop` / `onReport` / `signal` / `adapters` |
126
+ | `scanSessions` | `(ScanOptions) → AsyncIterable<ScannedSession>` | the shared locate→parse iterator |
91
127
  | `collectSessions` | `(CollectOptions) → SessionBatch[]` | redacted per-session batches for your own pipeline |
92
128
  | `redactSpans` | `(spans, rules?) → { spans, report }` | PII/secret redaction (`TRACES_REDACTION_RULES`) |
93
129
  | `planUpload` / `executeUpload` | `(…, { backend? }) → …` | redact + dedup + send to any sink |
94
- | `listAdapters` / `resolveAdapter` | `() → […]` / `(id) → adapter` | the harness registry |
130
+ | `selectAdapters` / `listAdapters` / `resolveAdapter` | adapter selection + the harness registry |
95
131
  | `HarnessTraceAdapter` | interface (`locate` + `parse`) | implement to add a harness |
96
132
 
97
133
  ```ts
@@ -103,12 +139,25 @@ await watchSessions({ all: true, signal: c.signal, onLoop: (l) => alert(l.toolNa
103
139
 
104
140
  // Run your own analyst instead of the built-ins:
105
141
  const registry = new AnalystRegistry()
106
- registry.register({ id: 'mine', description: '…', inputKind: 'trace-store', cost: { kind: 'deterministic' }, version: '1.0.0',
107
- async analyze() { return [makeFinding({ analyst_id: 'mine', area: 'custom', claim: '…', severity: 'info', evidence_refs: [], confidence: 0.9 })] } })
142
+ registry.register({
143
+ id: 'mine', description: '…', inputKind: 'trace-store', cost: { kind: 'deterministic' }, version: '1.0.0',
144
+ async analyze() {
145
+ return [makeFinding({ analyst_id: 'mine', area: 'custom', claim: '…', severity: 'info', evidence_refs: [], confidence: 0.9 })]
146
+ },
147
+ })
108
148
  await analyzeSpans(spans, { registry })
109
149
  ```
110
150
 
111
- Add a new harness: implement `HarnessTraceAdapter` and pass it via `adapters: [...]` to `watchSessions`/`collectSessions`, or drop a file in `src/adapters/`. See [`examples/register-harness.ts`](./examples/register-harness.ts).
151
+ ## Examples
152
+
153
+ Runnable, in [`examples/`](./examples):
154
+
155
+ | File | Shows |
156
+ |---|---|
157
+ | [`observe-and-alert.ts`](./examples/observe-and-alert.ts) | tail live sessions and alert on stuck loops |
158
+ | [`custom-analyst.ts`](./examples/custom-analyst.ts) | register and run your own analyst |
159
+ | [`custom-backend.ts`](./examples/custom-backend.ts) | redact + dedup + upload to your own sink |
160
+ | [`register-harness.ts`](./examples/register-harness.ts) | add a new harness by implementing `HarnessTraceAdapter` |
112
161
 
113
162
  ## Develop
114
163
 
package/package.json CHANGED
@@ -1,9 +1,27 @@
1
1
  {
2
2
  "name": "@tangle-network/traces",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/tangle-network/traces.git"
10
+ },
11
+ "homepage": "https://github.com/tangle-network/traces#readme",
12
+ "bugs": "https://github.com/tangle-network/traces/issues",
13
+ "keywords": [
14
+ "ai-agents",
15
+ "observability",
16
+ "tracing",
17
+ "otlp",
18
+ "claude-code",
19
+ "codex",
20
+ "opencode",
21
+ "agent-eval",
22
+ "llm",
23
+ "coding-agent"
24
+ ],
7
25
  "packageManager": "pnpm@10.33.4",
8
26
  "main": "./dist/index.js",
9
27
  "types": "./dist/index.d.ts",