@tangle-network/traces 0.10.2 → 0.11.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/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ export { Analyst, AnalystContext, AnalystFinding, AnalystRegistry, buildDefaultA
5
5
  import { ExecutionReport } from '@tangle-network/agent-eval/contract';
6
6
  import { TraceAnalysisStore, RedactionRule, RedactionReport } from '@tangle-network/agent-eval/traces';
7
7
  export { DEFAULT_REDACTION_RULES, ErrorCluster, RedactionReport, RedactionRule, TraceAnalysisStore, redactString, redactValue } from '@tangle-network/agent-eval/traces';
8
+ import { SpawnEvent, NodeStatus, Runtime, Budget, Spend } from '@tangle-network/agent-runtime/kernel';
9
+ import { SupervisorRunNodeRole, SupervisorRunReader, SupervisorRunSources } from '@tangle-network/agent-eval/supervisor-run';
8
10
  import { TraceSpanEvent } from '@tangle-network/agent-eval/hosted';
9
11
  export { HostedClient, createHostedClient, hostedClientFromEnv } from '@tangle-network/agent-eval/hosted';
10
12
 
@@ -2052,6 +2054,512 @@ interface ObserverOptions {
2052
2054
  }
2053
2055
  declare function watchSessions(opts: ObserverOptions): Promise<void>;
2054
2056
 
2057
+ /**
2058
+ * A SECOND implementation of agent-eval's `SupervisorRunReader` port, over the
2059
+ * run directory that agent-runtime's `createFileRunContext(dir)` writes:
2060
+ *
2061
+ * <runDir>/spawn-journal.jsonl required — the append-only SpawnEvent log
2062
+ * <runDir>/coordination-log.jsonl optional — steer / delivery / question / settled
2063
+ * <runDir>/blobs/ optional — content-addressed settled results
2064
+ * <runDir>/result.json optional — the terminal outcome document
2065
+ *
2066
+ * `loopsSupervisorRunReader` is the other implementation, over a completely
2067
+ * different layout. Neither knows about the other, and NOTHING here analyzes:
2068
+ * `analyzeSupervisorRun` / `parseSupervisorTree` / `rollupSupervisorRuns` in
2069
+ * `@tangle-network/agent-eval/supervisor-run` compute every metric, and
2070
+ * `materializeTreeView` in `@tangle-network/agent-runtime/kernel` folds the
2071
+ * event log into the tree. This file is translation only.
2072
+ *
2073
+ * ## Two translations, both faithful
2074
+ *
2075
+ * 1. **The envelope.** agent-runtime's `FileSpawnJournal` writes each event
2076
+ * wrapped as `{kind:'event', root, event:{…}}` after one `{kind:'begin'}`
2077
+ * record. agent-eval's parser reads `kind` at the TOP level, so an
2078
+ * un-translated file parses as zero spawns AND zero malformed rows — a run
2079
+ * that reads as "the supervisor did nothing" rather than "I cannot read
2080
+ * this". The reader unwraps the envelope and re-emits flat JSONL.
2081
+ *
2082
+ * 2. **`role`.** `SupervisorRunSources.journal` documents
2083
+ * `role: 'supervisor' | 'worker'` on spawned rows for recursive readers.
2084
+ * agent-runtime's `SpawnEvent` has no such field, so it is INFERRED
2085
+ * structurally and exactly: a node that appears as another spawn's `parent`
2086
+ * is a supervisor; the root is a supervisor because it has no parent;
2087
+ * everything else is a worker. No new upstream field is needed for this,
2088
+ * and no depth limit applies — `<root>:s0:s0` classifies its parent
2089
+ * `<root>:s0` as a supervisor by the same rule that classifies the root.
2090
+ *
2091
+ * Steer traffic is translated the same way: this layout records steers in
2092
+ * `coordination-log.jsonl` rather than per-worker inbox files, and each
2093
+ * recorded field maps 1:1 onto the per-worker artifacts the analyzer reads.
2094
+ * Nothing is synthesized from an absent fact — an artifact this layout does
2095
+ * not keep is declared in `SourceLimits`, which is what turns the dependent
2096
+ * metric into `unavailable` instead of 0.
2097
+ */
2098
+
2099
+ declare const SPAWN_JOURNAL_FILE = "spawn-journal.jsonl";
2100
+ declare const COORDINATION_LOG_FILE = "coordination-log.jsonl";
2101
+ declare const RESULT_FILE = "result.json";
2102
+ declare const BLOBS_DIR = "blobs";
2103
+ interface RunContextJournal {
2104
+ /** The `root` of the `begin` record, or of the first event envelope. */
2105
+ readonly root: string | null;
2106
+ /** ISO instant the tree was begun, when a `begin` record was written. */
2107
+ readonly begunAt: string | null;
2108
+ /** Events in file order, unwrapped from their envelopes. */
2109
+ readonly events: readonly SpawnEvent[];
2110
+ /** Node ids that appear as some spawn's `parent` — the exact supervisor set. */
2111
+ readonly supervisorIds: ReadonlySet<string>;
2112
+ readonly invalidRows: number;
2113
+ readonly partialTail: boolean;
2114
+ readonly present: boolean;
2115
+ }
2116
+ /**
2117
+ * Unwrap `FileSpawnJournal`'s `{kind:'begin'|'event', root, event}` records.
2118
+ * A record whose `kind` is neither is counted as invalid rather than dropped:
2119
+ * an unrecognized record shape is a finding, not silence.
2120
+ */
2121
+ declare function readRunContextJournal(text: string | null): RunContextJournal;
2122
+ /**
2123
+ * A node's role, decided by the tree's own shape. `supervisorIds` is the set of
2124
+ * ids some spawn named as its parent, so the rule is exact at any depth and
2125
+ * needs no field agent-runtime does not emit.
2126
+ */
2127
+ declare function inferRole(id: string, parent: string | null | undefined, supervisorIds: ReadonlySet<string>): SupervisorRunNodeRole;
2128
+ /** One steer the driver sent down to a named node. */
2129
+ interface CoordinationSteer {
2130
+ readonly messageId: string | null;
2131
+ readonly toWorker: string | null;
2132
+ readonly instruction: string;
2133
+ readonly deliveryMode: string | null;
2134
+ readonly at: number | null;
2135
+ }
2136
+ /** A question a node raised up. `blocking` is the run-stopping urgency. */
2137
+ interface CoordinationQuestion {
2138
+ readonly id: string | null;
2139
+ readonly from: string | null;
2140
+ readonly question: string;
2141
+ readonly reason: string | null;
2142
+ readonly urgency: string | null;
2143
+ readonly status: string | null;
2144
+ readonly blocking: boolean;
2145
+ readonly at: number | null;
2146
+ }
2147
+ interface CoordinationLog {
2148
+ readonly present: boolean;
2149
+ readonly steers: readonly CoordinationSteer[];
2150
+ /** `messageId → delivered`, from `delivery` receipts. */
2151
+ readonly deliveries: readonly {
2152
+ messageId: string | null;
2153
+ delivered: boolean | null;
2154
+ }[];
2155
+ readonly questions: readonly CoordinationQuestion[];
2156
+ readonly invalidRows: number;
2157
+ readonly partialTail: boolean;
2158
+ }
2159
+ /**
2160
+ * Two record envelopes are in the wild for this file: the versioned
2161
+ * `{version, runId, source, record:{seq, at, event}}` and the flat
2162
+ * `{runId, at, event}`. Both carry the same `event`, so the unwrap is a single
2163
+ * lookup and neither shape is privileged.
2164
+ */
2165
+ declare function readCoordinationLog(text: string | null): CoordinationLog;
2166
+ interface FileRunContextReaderOptions {
2167
+ /** Override the run identity used for rollup grouping (default: the journal root). */
2168
+ readonly instanceId?: string | null;
2169
+ /** Which arm of a comparison this run is (default: the run directory's basename). */
2170
+ readonly arm?: string | null;
2171
+ }
2172
+ /**
2173
+ * Read a `createFileRunContext` run directory into `SupervisorRunSources`.
2174
+ * Never throws on a missing artifact: an absent file becomes a `null` field or
2175
+ * a declared `SourceLimits` reason, which is what makes the dependent metric
2176
+ * `unavailable` rather than 0.
2177
+ */
2178
+ declare function readFileRunContext(runDir: string, opts?: FileRunContextReaderOptions): Promise<SupervisorRunSources>;
2179
+ /** The `createFileRunContext` on-disk layout, as a `SupervisorRunReader`. */
2180
+ declare function fileRunContextSupervisorRunReader(runDir: string, opts?: FileRunContextReaderOptions): SupervisorRunReader;
2181
+ /** Does this directory hold a `createFileRunContext` run? */
2182
+ declare function isFileRunContextDir(runDir: string): Promise<boolean>;
2183
+ /**
2184
+ * A sum over spend records that keeps "unknown" out of the number.
2185
+ *
2186
+ * `usd` is the total of the records that priced themselves; `usdUnknown` is how
2187
+ * many declined to. A renderer that has 0 known records and >=1 unknown one must
2188
+ * print "unknown", never `$0.0000`: an unmetered turn and a free turn are
2189
+ * different facts, and agent-runtime's `Spend.usdKnown` is the only signal that
2190
+ * separates them (absent means known, per its contract).
2191
+ */
2192
+ interface SpendRoll {
2193
+ readonly records: number;
2194
+ readonly iterations: number;
2195
+ readonly tokensIn: number;
2196
+ readonly tokensOut: number;
2197
+ readonly usd: number;
2198
+ readonly usdKnownRecords: number;
2199
+ readonly usdUnknownRecords: number;
2200
+ }
2201
+ declare const ZERO_ROLL: SpendRoll;
2202
+ declare function addSpend(roll: SpendRoll, spend: Spend): SpendRoll;
2203
+ declare function mergeRolls(a: SpendRoll, b: SpendRoll): SpendRoll;
2204
+ interface RunContextNode {
2205
+ readonly id: string;
2206
+ readonly parent: string | null;
2207
+ readonly label: string;
2208
+ readonly depth: number;
2209
+ readonly role: SupervisorRunNodeRole;
2210
+ readonly status: NodeStatus;
2211
+ readonly runtime: Runtime | null;
2212
+ /** The budget this node was AUTHORED with, exactly as the spawn recorded it. */
2213
+ readonly budget: Budget;
2214
+ /** This node's own driver inference — its `metered` events. */
2215
+ readonly driver: SpendRoll;
2216
+ /** What this node's direct children consumed — their `settled` spend. */
2217
+ readonly children: SpendRoll;
2218
+ /** What this node's own settlement charged its parent (its whole subtree). */
2219
+ readonly settled: SpendRoll;
2220
+ readonly spawnedAt: number | null;
2221
+ readonly settledAt: number | null;
2222
+ /** Wall from spawn to settlement; null while the node is still live. */
2223
+ readonly wallMs: number | null;
2224
+ readonly outRef: string | null;
2225
+ /** Why a cancelled node was cancelled. */
2226
+ readonly cancelReason: string | null;
2227
+ }
2228
+ interface RunContextResult {
2229
+ readonly kind: string | null;
2230
+ readonly reason: string | null;
2231
+ readonly errorName: string | null;
2232
+ readonly errorMessage: string | null;
2233
+ }
2234
+ interface RunContextSnapshot {
2235
+ readonly runDir: string;
2236
+ readonly runId: string | null;
2237
+ readonly present: boolean;
2238
+ /** Depth-first, parents before children. */
2239
+ readonly nodes: readonly RunContextNode[];
2240
+ readonly maxDepth: number;
2241
+ readonly begunAt: number | null;
2242
+ /** Latest instant any event carried. */
2243
+ readonly lastEventAt: number | null;
2244
+ readonly questions: readonly CoordinationQuestion[];
2245
+ readonly steers: readonly CoordinationSteer[];
2246
+ readonly result: RunContextResult | null;
2247
+ /** True once `result.json` exists — the run has reached a terminal state. */
2248
+ readonly terminal: boolean;
2249
+ /** Rows that were present and unreadable, per artifact. */
2250
+ readonly invalidJournalRows: number;
2251
+ readonly invalidCoordinationRows: number;
2252
+ /** True when an artifact's last line was still being written. */
2253
+ readonly partialTail: boolean;
2254
+ /** Why the tree could not be folded, when it could not. */
2255
+ readonly treeError: string | null;
2256
+ }
2257
+ /**
2258
+ * Read the run directory into the shape a live view renders. The tree comes
2259
+ * from agent-runtime's own `materializeTreeView` — the owner's fold of its own
2260
+ * event log, so a new event kind stays correctly classified here without this
2261
+ * file changing.
2262
+ *
2263
+ * The one thing the fold deliberately does NOT answer is the split this view
2264
+ * exists for: `materializeTreeView` accumulates a node's `metered` driver
2265
+ * inference ONTO its settled child-work base, which is the right total and the
2266
+ * wrong breakdown. Driver and child spend are therefore rolled separately
2267
+ * straight off the events, which is a partition of the same rows, not a second
2268
+ * tree.
2269
+ */
2270
+ declare function readRunContextSnapshot(runDir: string): Promise<RunContextSnapshot>;
2271
+
2272
+ /**
2273
+ * The GENERAL run-tree source: reconstruct a run's shape from OTLP spans alone.
2274
+ *
2275
+ * `supervisor-run-context.ts` is the specific source — agent-runtime's durable
2276
+ * spawn journal, which carries the exact authored budget, settled spend, and
2277
+ * settlement status that telemetry does not. This file is the one that works
2278
+ * for emitters nobody has written yet: anything that emits spans carrying
2279
+ * `trace_id` / `span_id` / `parent_span_id` gets a tree, because the parent
2280
+ * pointer IS the tree. A supervisor, a pi session, a Claude subagent fan-out,
2281
+ * and a custom fanout all reach the same view through the same three fields.
2282
+ *
2283
+ * ## Nothing here is a second exporter or a second attribute vocabulary
2284
+ *
2285
+ * Spans are read with this repo's existing `exportTraceEvidenceFile`, which
2286
+ * already detects OpenInference / intelligence-span / sandbox-event files,
2287
+ * normalizes them onto `OtlpSpan`, redacts, and validates. Every attribute is
2288
+ * read through `@tangle-network/agent-eval/trace-attributes` alias lists
2289
+ * (`LLM_INPUT_TOKEN_ATTR_KEYS`, `LLM_COST_ATTR_KEYS`, `SPAN_KIND_ATTR_KEYS`, …),
2290
+ * which already cover both live vocabularies — OpenInference's
2291
+ * `llm.token_count.*` and GenAI semconv's `gen_ai.usage.*`. No key is invented
2292
+ * here, so a span this repo can already read is a span this view can already
2293
+ * place.
2294
+ *
2295
+ * ## What a span tree can and cannot say
2296
+ *
2297
+ * It can say the shape, the wall time, the tokens, and — when the emitter
2298
+ * priced them — the dollars. It CANNOT say the authored budget: neither
2299
+ * vocabulary carries a spawn's ceiling, so budget is reported as absent, never
2300
+ * as 0. That gap is exactly why the journal source exists and why, when both
2301
+ * are present, the journal's numbers win.
2302
+ */
2303
+
2304
+ type SpanNodeStatus = 'running' | 'done' | 'failed';
2305
+ interface SpanRunNode {
2306
+ readonly traceId: string;
2307
+ readonly spanId: string;
2308
+ /** The enclosing NODE's span id — not necessarily the raw parent span. */
2309
+ readonly parentNodeId: string | null;
2310
+ readonly label: string;
2311
+ readonly depth: number;
2312
+ /**
2313
+ * `driver` when this node has nested agent nodes below it, `leaf` otherwise.
2314
+ * Spans carry no spawn relationship, so delegation is read from the tree
2315
+ * itself — the only fact the telemetry actually states.
2316
+ */
2317
+ readonly role: 'driver' | 'leaf';
2318
+ readonly status: SpanNodeStatus;
2319
+ /** `service.name` — which harness or runtime emitted this subtree. */
2320
+ readonly runtime: string | null;
2321
+ /** This node's OWN inference: the LLM spans it emitted directly. */
2322
+ readonly driver: SpendRoll;
2323
+ /** What its nested agent nodes consumed, whole subtrees included. */
2324
+ readonly children: SpendRoll;
2325
+ /** Tool spans attributed to this node directly. */
2326
+ readonly toolCalls: number;
2327
+ readonly startMs: number;
2328
+ readonly endMs: number;
2329
+ readonly wallMs: number;
2330
+ /** Span status messages on this node or its non-node descendants. */
2331
+ readonly errors: readonly string[];
2332
+ }
2333
+ interface SpanRunSnapshot {
2334
+ readonly source: string;
2335
+ readonly present: boolean;
2336
+ /** Depth-first, parents before children, one subtree per trace. */
2337
+ readonly nodes: readonly SpanRunNode[];
2338
+ readonly maxDepth: number;
2339
+ readonly traceIds: readonly string[];
2340
+ readonly spanCount: number;
2341
+ readonly startMs: number | null;
2342
+ readonly endMs: number | null;
2343
+ /** LLM spans that recorded no token count at all — a gap, not a zero. */
2344
+ readonly llmSpansWithoutTokens: number;
2345
+ /** LLM spans that recorded no cost at all — a gap, not $0. */
2346
+ readonly llmSpansWithoutCost: number;
2347
+ /** Spans whose `parent_span_id` names a span not in the file. */
2348
+ readonly orphanSpans: number;
2349
+ /** Why the file could not be read, when it could not. */
2350
+ readonly readError: string | null;
2351
+ }
2352
+ declare const EMPTY_SPAN_RUN_SNAPSHOT: Omit<SpanRunSnapshot, 'source'>;
2353
+ /**
2354
+ * Fold a flat span batch into the node tree. Pure, so the same spans always
2355
+ * render the same text — which is what lets the live tail print only on change.
2356
+ */
2357
+ declare function buildSpanRunTree(spans: readonly OtlpSpan[], source: string): SpanRunSnapshot;
2358
+ /**
2359
+ * Read one span file into a snapshot. Never throws: a tail that catches the
2360
+ * writer mid-line, or an empty file the emitter has not filled yet, is a state
2361
+ * to display, not a crash.
2362
+ */
2363
+ declare function readSpanRunSnapshot(path: string): Promise<SpanRunSnapshot>;
2364
+ /**
2365
+ * The two run-level halves of a span tree, each counted exactly once: the
2366
+ * inference emitted by nodes that DELEGATED, and the inference emitted by the
2367
+ * leaves they delegated to. Every LLM span lands in exactly one half, so the
2368
+ * two add up to the run and neither hides inside the other.
2369
+ */
2370
+ declare function spanRunTotals(snapshot: SpanRunSnapshot): {
2371
+ driver: SpendRoll;
2372
+ leaves: SpendRoll;
2373
+ };
2374
+ /** The rendered view for one span snapshot. Pure. */
2375
+ declare function renderSpanRunSnapshot(snapshot: SpanRunSnapshot): string;
2376
+ /**
2377
+ * Span files at or immediately under `dir`. One level only, matching how the
2378
+ * journal source resolves a run directory: a run is the unit a caller names.
2379
+ */
2380
+ declare function findSpanSourceFiles(dir: string): Promise<string[]>;
2381
+
2382
+ /**
2383
+ * `traces watch <runDir>` — a live terminal view of a supervised run written by
2384
+ * agent-runtime's `createFileRunContext`.
2385
+ *
2386
+ * Plain stdout, no dependency, no cursor control: it works over SSH, in a CI
2387
+ * log, and through a pipe, and it prints a new block only when something
2388
+ * changed, so a long idle stretch does not scroll away the last real event.
2389
+ *
2390
+ * The whole view model comes from `readRunContextSnapshot`; this file only
2391
+ * formats. Two formatting rules carry the weight:
2392
+ *
2393
+ * - **Driver inference and child work never merge.** A supervisor's own
2394
+ * thinking and the work it spawned are separate lines on the same node,
2395
+ * because a single total cannot answer "which half spent the budget" — the
2396
+ * decisive question in three real runs, where a root burned its pool on its
2397
+ * own turns while its one child cost almost nothing.
2398
+ * - **Unknown is never rendered as zero.** `Spend.usdKnown === false` means
2399
+ * the harness did not price that inference; it does not mean the inference
2400
+ * was free. Those records are counted and named, never summed into `$0.00`.
2401
+ */
2402
+
2403
+ /**
2404
+ * The whole view for one snapshot. Pure: the same snapshot always renders the
2405
+ * same text, which is what lets the tail print only on change.
2406
+ */
2407
+ declare function renderRunContextSnapshot(snapshot: RunContextSnapshot): string;
2408
+ /**
2409
+ * The two run-level halves, each counted exactly once.
2410
+ *
2411
+ * Driver total sums every node's OWN `metered` inference, at any depth. Worker
2412
+ * total sums the settled spend of LEAF nodes only, because a nested
2413
+ * supervisor's settlement re-homes its whole subtree up to its parent — adding
2414
+ * it would count every grandchild twice, and the sub-total would silently
2415
+ * exceed the pool the run actually spent.
2416
+ */
2417
+ declare function runTotals(snapshot: RunContextSnapshot): {
2418
+ driver: SpendRoll;
2419
+ workers: SpendRoll;
2420
+ };
2421
+ /**
2422
+ * Resolve what the user pointed at: the run directory itself, or a parent
2423
+ * holding exactly one. A parent holding several is ambiguous and says so with
2424
+ * the candidates, rather than picking one.
2425
+ */
2426
+ declare function resolveRunContextDir(dir: string): Promise<string>;
2427
+
2428
+ /**
2429
+ * Formatting primitives shared by every `traces watch <target>` view.
2430
+ *
2431
+ * Two rules live here rather than in each renderer, because they are the whole
2432
+ * reason this view exists and a second copy would eventually disagree with the
2433
+ * first:
2434
+ *
2435
+ * - **Unknown is never rendered as zero.** A roll with no priced record prints
2436
+ * "cost unknown", not `$0.0000`. An unmetered turn and a free turn are
2437
+ * different facts.
2438
+ * - **A recorded $0 that burned tokens is printed AND flagged.** The recorded
2439
+ * value stands; the ambiguity is named next to it.
2440
+ *
2441
+ * Plain ASCII-plus-box-drawing, no cursor control and no colour: the output has
2442
+ * to survive SSH, a CI log, and a pipe into a file.
2443
+ */
2444
+
2445
+ declare const RULE: string;
2446
+ declare function int(n: number): string;
2447
+ declare function ms(value: number | null): string;
2448
+ /**
2449
+ * A dollar figure that keeps unknown out of the number. With no priced record
2450
+ * at all the answer is "cost unknown" — printing `$0.0000` there is the exact
2451
+ * fabrication this view exists to prevent.
2452
+ */
2453
+ declare function usd(roll: SpendRoll): string;
2454
+ /**
2455
+ * A roll that claims a price of exactly $0 while recording real tokens.
2456
+ *
2457
+ * agent-runtime's contract is that `Spend.usdKnown` absent means the dollar
2458
+ * figure IS known, so the honest number is $0 and this view prints it. But a
2459
+ * harness-billed brain (a CLI on a subscription) also records $0 without ever
2460
+ * setting `usdKnown:false`, and "free" and "unmetered" are the two facts this
2461
+ * view exists to keep apart. So the value stands and the ambiguity is named —
2462
+ * never the reverse.
2463
+ */
2464
+ declare function zeroPricedCost(roll: SpendRoll): boolean;
2465
+ declare function tokens(roll: SpendRoll): string;
2466
+ declare const STATUS_MARK: Record<string, string>;
2467
+ /**
2468
+ * Tree connectors for a depth-first node list. `lastAtDepth` records, per
2469
+ * ancestor level, whether that ancestor was its parent's last child, which is
2470
+ * what decides between a continuing `│` and a blank column — the difference
2471
+ * between a readable tree and an ambiguous indent at depth 3+.
2472
+ */
2473
+ declare function connectors(depth: number, lastAtDepth: readonly boolean[]): {
2474
+ head: string;
2475
+ detail: string;
2476
+ };
2477
+ /**
2478
+ * Walk a depth-first node list, handing each node the `lastAtDepth` state its
2479
+ * connectors need. A node is its parent's last child when no later node shares
2480
+ * that parent, which the caller's list order already encodes.
2481
+ */
2482
+ declare function forEachTreeNode<T extends {
2483
+ readonly depth: number;
2484
+ }>(nodes: readonly T[], parentKey: (node: T) => string | null, selfKey: (node: T) => string, visit: (node: T, lastAtDepth: readonly boolean[]) => void): void;
2485
+ /** Wrap to a terminal width so a long question is readable, never truncated. */
2486
+ declare function wrap(text: string, indent: number): string[];
2487
+
2488
+ /**
2489
+ * `traces watch <target>` — the live terminal view, over whichever sources the
2490
+ * target actually has.
2491
+ *
2492
+ * Two sources, one verb:
2493
+ *
2494
+ * - **General** — `run-span-tree.ts`, over OTLP spans. `trace_id` /
2495
+ * `span_id` / `parent_span_id` reconstruct the tree for ANY emitter, so a
2496
+ * system nobody has written yet is watchable the day it emits its first
2497
+ * span. It cannot report an authored budget, because no span vocabulary
2498
+ * carries one.
2499
+ * - **Specific** — `supervisor-run-context.ts`, over agent-runtime's durable
2500
+ * spawn journal. It carries the exact budget, spend, and settlement the
2501
+ * telemetry does not.
2502
+ *
2503
+ * When a run has both, the output shows both and LABELS which number came from
2504
+ * which: the journal section first, because its numbers are the authoritative
2505
+ * ones, then the span section for the shape and the per-turn detail. They are
2506
+ * never merged into one column, because a merged column cannot be audited —
2507
+ * and the numbers legitimately differ (a driver's spans price each turn; the
2508
+ * journal's `settled` re-homes a whole subtree onto its parent).
2509
+ *
2510
+ * Plain stdout, no dependency, no cursor control: it works over SSH, in a CI
2511
+ * log, and through a pipe. A block prints only when the rendered view changed,
2512
+ * so a long idle stretch never scrolls the last real event away.
2513
+ */
2514
+
2515
+ /** What a resolved target will be read from. At least one is always present. */
2516
+ interface RunWatchTarget {
2517
+ /** The directory holding `spawn-journal.jsonl`, when there is one. */
2518
+ readonly runDir: string | null;
2519
+ /** OTLP span files to fold, in read order. */
2520
+ readonly spanFiles: readonly string[];
2521
+ /** What the caller named, verbatim — the thing to print in an error. */
2522
+ readonly requested: string;
2523
+ }
2524
+ /**
2525
+ * Resolve what the user pointed at.
2526
+ *
2527
+ * A file the caller named is read as spans, whatever it is called. A directory
2528
+ * is the run directory when it holds a spawn journal, or the parent of exactly
2529
+ * one — the same rule `resolveRunContextDir` already applies — and either way
2530
+ * its span files come along. A directory with neither is an error naming both
2531
+ * things it looked for, because "nothing here" and "wrong kind of thing here"
2532
+ * are different mistakes.
2533
+ */
2534
+ declare function resolveRunWatchTarget(target: string): Promise<RunWatchTarget>;
2535
+ interface RunWatchSnapshot {
2536
+ readonly target: RunWatchTarget;
2537
+ /** Present only when the target has a spawn journal. */
2538
+ readonly journal: RunContextSnapshot | null;
2539
+ readonly spans: readonly SpanRunSnapshot[];
2540
+ /** True once every present source says the run is over. */
2541
+ readonly terminal: boolean;
2542
+ }
2543
+ declare function readRunWatchSnapshot(target: RunWatchTarget): Promise<RunWatchSnapshot>;
2544
+ declare function renderRunWatchSnapshot(snapshot: RunWatchSnapshot): string;
2545
+ interface WatchRunTargetOptions {
2546
+ /** Print one snapshot and return — what a script or an agent wants. */
2547
+ readonly once?: boolean;
2548
+ /** Poll period in ms (default 2000). */
2549
+ readonly intervalMs?: number;
2550
+ /** Where to write (default stdout). */
2551
+ readonly write?: (text: string) => void;
2552
+ readonly signal?: AbortSignal;
2553
+ /** Keep tailing after the run reaches a terminal state (default: stop). */
2554
+ readonly follow?: boolean;
2555
+ }
2556
+ /**
2557
+ * Tail a target until every source says the run is over. Prints a block only
2558
+ * when the rendered view changed, so the last thing on screen is always the
2559
+ * last thing that happened.
2560
+ */
2561
+ declare function watchRunTarget(target: RunWatchTarget, opts?: WatchRunTargetOptions): Promise<RunWatchSnapshot>;
2562
+
2055
2563
  /**
2056
2564
  * Privacy redaction for trace spans before upload.
2057
2565
  *
@@ -2212,4 +2720,4 @@ interface ExecuteOptions {
2212
2720
  /** Send the final, new outbound items (or write their dry-run OTLP). */
2213
2721
  declare function executeUpload(plan: UploadPlan, opts?: ExecuteOptions): Promise<UploadResult>;
2214
2722
 
2215
- export { ACTOR_ATTR, ATTR, type Actor, type AdoptionOptions, type AdoptionReport, AmpAdapter, type AnalyzeOptions, type AnalyzeResult, type BuildPolicyEvidenceOptions, type BuildSessionIndexOptions, type BuildTraceFindingPacketOptions, CODING_REDACTION_RULES, CONTENT_CAP, CORRECTIVE_REACTIONS, type ChatTrajectory, type ChatTrajectoryMessage, type ChatTrajectoryOptions, ClaudeAdapter, type CodeTraceBenchFileRef, type CodeTraceBenchImportOptions, type CodeTraceBenchImportReceipt, type CodeTraceBenchImportResult, type CodeTraceBenchImportedTrace, type CodeTraceBenchStep, CodexAdapter, CodexExecAdapter, CodexExecStreamError, CodexTaskScopeError, type CollectOptions, type CollectPolicyEvidenceOptions, type CollectSessionIndexOptions, type CollectSessionSelectionOptions, type CollectSessionWorkflowOptions, CopilotAdapter, type CorruptionMode, DEFAULT_HARNESS, EmptySessionError, type ExecuteOptions, type ExternalAnalysisKind, type ExternalAnalysisPayload, type ExternalAnalysisResult, type ExternalAnalyzer, type ExternalAnalyzerOptions, type ExternalDiscoveryCandidate, FactoryAdapter, ForgeAdapter, GeminiAdapter, type HaloAnalyzerOptions, type HaloReasoningEffort, type HarnessTraceAdapter, type HodoscopeAnalyzerOptions, type HodoscopeInput, type HodoscopeMessage, type HodoscopeSourceMapEntry, type HodoscopeTrajectory, INGEST_SOURCE_CLI, type InspectSessionIndexOptions, JsonSourceError, type JsonlCorruptionReceipt, JsonlParseError, type JsonlReadOptions, type LiveBatchOptions, type LocateOptions, type ObservedLoop, type ObserverOptions, OpencodeAdapter, type OtlpSpan, type OtlpSpanKind, type OtlpStatusCode, type ParentTaskResolution, type ParseOptions, PartialUploadError, PiAdapter, type PipelineOptions, type PipelineReport, type PlanOptions, type PolicyEvidenceLoopSummary, type PolicyEvidenceRecord, type PolicyEvidenceToolSummary, QwenAdapter, REACTIONS, type Reaction, type ReactionReport, type ReactionSessionReport, type Redactor, type RepoAttrs, type RepoResolution, type RepoResolutionSource, type RunResult, type RuntimeTrace, type ScanOptions, type ScannedSession, type SessionBatch, type SessionCorruptionReceipt, type SessionIdentityConflict, type SessionIdentityIndex, type SessionIntegrity, type SessionRef, type SessionRelationship, type SessionRole, type SessionSeedGroup, type SessionSelection, type SessionSelectionRow, type SessionSourceFile, type SessionWorkflow, SessionWorkflowError, type SessionWorkflowErrorCode, type SessionWorkflowIssue, type SessionWorkflowSession, type SessionWorkflowSummary, type SpanInput, type SpanRedaction, TRACES_REDACTION_RULES, type TraceAgenticRoute, type TraceAgenticRouteReason, type TraceAgenticRouteReasonCode, type TraceContextIndex, type TraceContextRoot, type TraceEvidenceExportOptions, type TraceEvidenceExportResult, type TraceEvidenceFormatOption, type TraceEvidenceInputFormat, type TraceEvidenceRow, type TraceExecutionOptions, type TraceFindingPacket, type TraceImprovementArtifacts, type TraceImprovementOptions, type TraceImprovementResult, type TraceIndexedFile, type TraceInspectionArea, type TraceInspectionFinding, type TraceInspectionReport, type TraceInspectionSeverity, type TraceInvestigationOptions, type TraceInvestigationResult, type TraceLiveAction, type TraceLiveActionKind, type TraceLiveAnalysisContext, type TraceLiveAnalyst, type TraceLiveBatch, type TraceLiveEvidence, type TraceLiveFinding, type TraceLiveLoop, type TraceLiveSeverity, type TraceSessionIndex, type TraceSessionIndexRow, type TraceStoreInvestigationOptions, type TraceStoreInvestigationResult, type TraceStreamEvent, type TraceStreamOptions, type TraceStreamReplayOptions, type TraceStreamSession, type TracesConfig, type TriggerPair, type UploadBackend, type UploadIdentity, type UploadItem, type UploadPlan, type UploadRecord, type UploadResult, type UploadState, type UserPromptInput, alreadyUploaded, analyzeAdoption, analyzeLiveBatch, analyzeReactions, analyzeSpans, applyRedactor, buildPolicyEvidenceRecord, buildSessionIndex, buildSessionIndexFromRows, buildTraceFindingPacket, capText, chatTrajectoryToSpans, classifyLiveActions, classifyReaction, claudeActor, codexActor, collectPolicyEvidence, collectSessionIndex, collectSessionSelection, collectSessionWorkflow, collectSessions, commandAnalyzer, commandRedactor, countSkillRunsJsonl, cwdMatchesSelection, defaultTraceLiveAnalysts, describeSessionRelationship, equivalentGitCwds, executeUpload, exportTraceEvidenceFile, exportTraceEvidenceRows, exportTraceEvidenceText, haloAnalyzer, hodoscopeAnalyzer, importCodeTraceBench, indexSessionIdsByTrace, inspectSessionIndex, isChatTrajectory, isChatTrajectoryMessage, knownHarnesses, listAdapters, loadState, loadTracesConfig, locateSessions, looksLikeAgentPrompt, mergeTracesConfig, normalizeRemote, outboundHash, parseIsoToEpochMs, parseSession, parseSince, planTraceAgenticRoute, planUpload, readJsonFile, readJsonl, readSessionIndexFile, recordSessionCorruption, redactSpans, renderInspectionReport, resolveAdapter, resolveRepoAttrs, resolveSessionRepoAttrs, runCommand, runExternalAnalyzers, runPipelines, runTraceImprovement, runTraceInvestigation, runTraceStoreInvestigation, saveReport, saveState, scanSessions, selectAdapters, serializeInspectionReport, serializePolicyEvidence, serializeSessionIndex, serializeSpans, serializeTraceStreamEvent, sessionHash, sessionIdFromAttributes, sessionIntegrityAttributes, span, stampRepoAttrs, stampSessionIdentity, stampSessionIntegrity, stampSpanWorkdirRepoAttrs, streamSessions, summarizeOtlpExecution, summarizeSpanExecution, takeJsonl, textIsSynthetic, toOpenInferenceSpan, toRuntimeStore, toTraceSpanEvents, totalAgenticFailureMessage, traceAgenticKinds, traceStreamEventsFromSpans, uploadKey, userPromptSpan, validateOtlpSpans, watchSessions, writeHodoscopeInput, writeInspectionReportFile, writeOtlpFile, writePolicyEvidenceFile, writeSessionIndexFile, writeTraceEvidenceExportFile, writeTraceImprovementArtifacts };
2723
+ export { ACTOR_ATTR, ATTR, type Actor, type AdoptionOptions, type AdoptionReport, AmpAdapter, type AnalyzeOptions, type AnalyzeResult, BLOBS_DIR, type BuildPolicyEvidenceOptions, type BuildSessionIndexOptions, type BuildTraceFindingPacketOptions, CODING_REDACTION_RULES, CONTENT_CAP, COORDINATION_LOG_FILE, CORRECTIVE_REACTIONS, type ChatTrajectory, type ChatTrajectoryMessage, type ChatTrajectoryOptions, ClaudeAdapter, type CodeTraceBenchFileRef, type CodeTraceBenchImportOptions, type CodeTraceBenchImportReceipt, type CodeTraceBenchImportResult, type CodeTraceBenchImportedTrace, type CodeTraceBenchStep, CodexAdapter, CodexExecAdapter, CodexExecStreamError, CodexTaskScopeError, type CollectOptions, type CollectPolicyEvidenceOptions, type CollectSessionIndexOptions, type CollectSessionSelectionOptions, type CollectSessionWorkflowOptions, type CoordinationLog, type CoordinationQuestion, type CoordinationSteer, CopilotAdapter, type CorruptionMode, DEFAULT_HARNESS, EMPTY_SPAN_RUN_SNAPSHOT, EmptySessionError, type ExecuteOptions, type ExternalAnalysisKind, type ExternalAnalysisPayload, type ExternalAnalysisResult, type ExternalAnalyzer, type ExternalAnalyzerOptions, type ExternalDiscoveryCandidate, FactoryAdapter, type FileRunContextReaderOptions, ForgeAdapter, GeminiAdapter, type HaloAnalyzerOptions, type HaloReasoningEffort, type HarnessTraceAdapter, type HodoscopeAnalyzerOptions, type HodoscopeInput, type HodoscopeMessage, type HodoscopeSourceMapEntry, type HodoscopeTrajectory, INGEST_SOURCE_CLI, type InspectSessionIndexOptions, JsonSourceError, type JsonlCorruptionReceipt, JsonlParseError, type JsonlReadOptions, type LiveBatchOptions, type LocateOptions, type ObservedLoop, type ObserverOptions, OpencodeAdapter, type OtlpSpan, type OtlpSpanKind, type OtlpStatusCode, type ParentTaskResolution, type ParseOptions, PartialUploadError, PiAdapter, type PipelineOptions, type PipelineReport, type PlanOptions, type PolicyEvidenceLoopSummary, type PolicyEvidenceRecord, type PolicyEvidenceToolSummary, QwenAdapter, REACTIONS, RESULT_FILE, RULE, type Reaction, type ReactionReport, type ReactionSessionReport, type Redactor, type RepoAttrs, type RepoResolution, type RepoResolutionSource, type RunContextJournal, type RunContextNode, type RunContextResult, type RunContextSnapshot, type RunResult, type RunWatchSnapshot, type RunWatchTarget, type RuntimeTrace, SPAWN_JOURNAL_FILE, STATUS_MARK, type ScanOptions, type ScannedSession, type SessionBatch, type SessionCorruptionReceipt, type SessionIdentityConflict, type SessionIdentityIndex, type SessionIntegrity, type SessionRef, type SessionRelationship, type SessionRole, type SessionSeedGroup, type SessionSelection, type SessionSelectionRow, type SessionSourceFile, type SessionWorkflow, SessionWorkflowError, type SessionWorkflowErrorCode, type SessionWorkflowIssue, type SessionWorkflowSession, type SessionWorkflowSummary, type SpanInput, type SpanNodeStatus, type SpanRedaction, type SpanRunNode, type SpanRunSnapshot, type SpendRoll, TRACES_REDACTION_RULES, type TraceAgenticRoute, type TraceAgenticRouteReason, type TraceAgenticRouteReasonCode, type TraceContextIndex, type TraceContextRoot, type TraceEvidenceExportOptions, type TraceEvidenceExportResult, type TraceEvidenceFormatOption, type TraceEvidenceInputFormat, type TraceEvidenceRow, type TraceExecutionOptions, type TraceFindingPacket, type TraceImprovementArtifacts, type TraceImprovementOptions, type TraceImprovementResult, type TraceIndexedFile, type TraceInspectionArea, type TraceInspectionFinding, type TraceInspectionReport, type TraceInspectionSeverity, type TraceInvestigationOptions, type TraceInvestigationResult, type TraceLiveAction, type TraceLiveActionKind, type TraceLiveAnalysisContext, type TraceLiveAnalyst, type TraceLiveBatch, type TraceLiveEvidence, type TraceLiveFinding, type TraceLiveLoop, type TraceLiveSeverity, type TraceSessionIndex, type TraceSessionIndexRow, type TraceStoreInvestigationOptions, type TraceStoreInvestigationResult, type TraceStreamEvent, type TraceStreamOptions, type TraceStreamReplayOptions, type TraceStreamSession, type TracesConfig, type TriggerPair, type UploadBackend, type UploadIdentity, type UploadItem, type UploadPlan, type UploadRecord, type UploadResult, type UploadState, type UserPromptInput, type WatchRunTargetOptions, ZERO_ROLL, addSpend, alreadyUploaded, analyzeAdoption, analyzeLiveBatch, analyzeReactions, analyzeSpans, applyRedactor, buildPolicyEvidenceRecord, buildSessionIndex, buildSessionIndexFromRows, buildSpanRunTree, buildTraceFindingPacket, capText, chatTrajectoryToSpans, classifyLiveActions, classifyReaction, claudeActor, codexActor, collectPolicyEvidence, collectSessionIndex, collectSessionSelection, collectSessionWorkflow, collectSessions, commandAnalyzer, commandRedactor, connectors, countSkillRunsJsonl, cwdMatchesSelection, defaultTraceLiveAnalysts, describeSessionRelationship, equivalentGitCwds, executeUpload, exportTraceEvidenceFile, exportTraceEvidenceRows, exportTraceEvidenceText, fileRunContextSupervisorRunReader, findSpanSourceFiles, forEachTreeNode, haloAnalyzer, hodoscopeAnalyzer, importCodeTraceBench, indexSessionIdsByTrace, inferRole, inspectSessionIndex, int, isChatTrajectory, isChatTrajectoryMessage, isFileRunContextDir, knownHarnesses, listAdapters, loadState, loadTracesConfig, locateSessions, looksLikeAgentPrompt, mergeRolls, mergeTracesConfig, ms, normalizeRemote, outboundHash, parseIsoToEpochMs, parseSession, parseSince, planTraceAgenticRoute, planUpload, readCoordinationLog, readFileRunContext, readJsonFile, readJsonl, readRunContextJournal, readRunContextSnapshot, readRunWatchSnapshot, readSessionIndexFile, readSpanRunSnapshot, recordSessionCorruption, redactSpans, renderInspectionReport, renderRunContextSnapshot, renderRunWatchSnapshot, renderSpanRunSnapshot, resolveAdapter, resolveRepoAttrs, resolveRunContextDir, resolveRunWatchTarget, resolveSessionRepoAttrs, runCommand, runExternalAnalyzers, runPipelines, runTotals, runTraceImprovement, runTraceInvestigation, runTraceStoreInvestigation, saveReport, saveState, scanSessions, selectAdapters, serializeInspectionReport, serializePolicyEvidence, serializeSessionIndex, serializeSpans, serializeTraceStreamEvent, sessionHash, sessionIdFromAttributes, sessionIntegrityAttributes, span, spanRunTotals, stampRepoAttrs, stampSessionIdentity, stampSessionIntegrity, stampSpanWorkdirRepoAttrs, streamSessions, summarizeOtlpExecution, summarizeSpanExecution, takeJsonl, textIsSynthetic, toOpenInferenceSpan, toRuntimeStore, toTraceSpanEvents, tokens, totalAgenticFailureMessage, traceAgenticKinds, traceStreamEventsFromSpans, uploadKey, usd, userPromptSpan, validateOtlpSpans, watchRunTarget, watchSessions, wrap, writeHodoscopeInput, writeInspectionReportFile, writeOtlpFile, writePolicyEvidenceFile, writeSessionIndexFile, writeTraceEvidenceExportFile, writeTraceImprovementArtifacts, zeroPricedCost };