@tangle-network/traces 0.21.0 → 0.22.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.
@@ -110,7 +110,7 @@ var ATTR = {
110
110
  * (`deriveSubjectKey` reads `tangle.subject.key` first). Resolves to the git
111
111
  * remote (host/owner/repo) when readable, else the cwd path basename. */
112
112
  SUBJECT_KEY: "tangle.subject.key",
113
- /** Normalized git remote (e.g. `github.com/tangle-network/agent-dev-container`). */
113
+ /** Normalized git remote (e.g. `github.com/tangle-network/agent-container`). */
114
114
  GIT_REPOSITORY: "git.repository",
115
115
  /** Current branch at conversion time. */
116
116
  GIT_BRANCH_NAME: "git.branch",
@@ -1024,8 +1024,8 @@ var OTLP_WRITE_CHUNK_CHARS = 4 * 1024 * 1024;
1024
1024
  async function writeOtlpFile(spans, outPath) {
1025
1025
  const { mkdtemp: mkdtemp8, open: open4 } = await import("fs/promises");
1026
1026
  const { tmpdir: tmpdir8 } = await import("os");
1027
- const { join: join36 } = await import("path");
1028
- const path = outPath ?? join36(await mkdtemp8(join36(tmpdir8(), "traces-")), "spans.otlp.jsonl");
1027
+ const { join: join35 } = await import("path");
1028
+ const path = outPath ?? join35(await mkdtemp8(join35(tmpdir8(), "traces-")), "spans.otlp.jsonl");
1029
1029
  const handle = await open4(path, "w");
1030
1030
  try {
1031
1031
  let chunk = "";
@@ -2406,143 +2406,10 @@ var CopilotAdapter = class {
2406
2406
  }
2407
2407
  };
2408
2408
 
2409
- // src/adapters/forge.ts
2409
+ // src/adapters/gemini.ts
2410
2410
  import { readdir as readdir5, stat as stat4 } from "fs/promises";
2411
2411
  import { homedir as homedir3 } from "os";
2412
- import { basename as basename3, join as join5 } from "path";
2413
- var SERVICE4 = "forge";
2414
- function tokens(t) {
2415
- if (!t) return null;
2416
- return t.actual ?? t.approx ?? null;
2417
- }
2418
- function textOf2(content) {
2419
- return capText(content ?? "");
2420
- }
2421
- var ForgeAdapter = class {
2422
- harness = "forge";
2423
- aliases = ["forgecode"];
2424
- /** Directories scanned for `*-dump.json` exports. */
2425
- dumpDirs() {
2426
- return [process.cwd(), join5(homedir3(), ".forge")];
2427
- }
2428
- async locate(opts = {}) {
2429
- const refs = [];
2430
- const dirs = opts.cwd ? [opts.cwd] : this.dumpDirs();
2431
- for (const dir of dirs) {
2432
- let files;
2433
- try {
2434
- files = await readdir5(dir);
2435
- } catch (error) {
2436
- if (isMissingPathError(error)) continue;
2437
- throw error;
2438
- }
2439
- for (const f of files) {
2440
- if (!f.endsWith("-dump.json")) continue;
2441
- const path = join5(dir, f);
2442
- let st;
2443
- try {
2444
- st = await stat4(path);
2445
- } catch (error) {
2446
- if (isMissingPathError(error)) continue;
2447
- throw error;
2448
- }
2449
- if (opts.sinceMs && st.mtimeMs < opts.sinceMs) continue;
2450
- refs.push({ harness: this.harness, sessionId: basename3(f, ".json"), path, cwd: dir, mtimeMs: st.mtimeMs });
2451
- }
2452
- }
2453
- return refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
2454
- }
2455
- async parse(ref, options = {}) {
2456
- const dump = await readJsonFile(ref.path, options);
2457
- const ctx = dump.context ?? dump;
2458
- const traceId = ctx.conversation_id ?? ref.sessionId;
2459
- const rootId = `root:${traceId}`;
2460
- const messages = ctx.messages ?? [];
2461
- const spans = [
2462
- span({ traceId, spanId: rootId, parentSpanId: null, name: "session", kind: "AGENT", startTime: (/* @__PURE__ */ new Date(0)).toISOString(), service: SERVICE4, agent: SERVICE4 })
2463
- ];
2464
- if (ctx.conversation_id) spans[0].attributes["tangle.sessionId"] = ctx.conversation_id;
2465
- const toolByCallId = /* @__PURE__ */ new Map();
2466
- let step = 0;
2467
- let lastLlm = rootId;
2468
- for (const raw of messages) {
2469
- const entry = raw.message ?? raw;
2470
- const ts = (/* @__PURE__ */ new Date(0)).toISOString();
2471
- if (entry.text && entry.text.role === "user") {
2472
- const prompt = textOf2(entry.text.content);
2473
- if (prompt) {
2474
- spans.push(
2475
- userPromptSpan({
2476
- traceId,
2477
- spanId: `user:${step}`,
2478
- parentSpanId: rootId,
2479
- startTime: ts,
2480
- content: prompt,
2481
- contentSource: textSources(entry.text, "content"),
2482
- service: SERVICE4,
2483
- agent: SERVICE4,
2484
- step
2485
- })
2486
- );
2487
- step += 1;
2488
- }
2489
- } else if (entry.text) {
2490
- const llmId = `llm:${step}`;
2491
- spans.push(
2492
- span({
2493
- traceId,
2494
- spanId: llmId,
2495
- parentSpanId: rootId,
2496
- name: `message.${entry.text.role ?? "unknown"}`,
2497
- kind: "LLM",
2498
- startTime: ts,
2499
- service: SERVICE4,
2500
- agent: SERVICE4,
2501
- model: entry.text.model ?? null,
2502
- inputTokens: tokens(raw.usage?.prompt_tokens),
2503
- outputTokens: tokens(raw.usage?.completion_tokens),
2504
- step,
2505
- content: textOf2(entry.text.content) || null,
2506
- contentSource: textSources(entry.text, "content")
2507
- })
2508
- );
2509
- lastLlm = llmId;
2510
- step += 1;
2511
- for (const tc of entry.text.tool_calls ?? []) {
2512
- const id = tc.call_id ?? `${step}`;
2513
- const t = span({
2514
- traceId,
2515
- spanId: `tool:${id}`,
2516
- parentSpanId: llmId,
2517
- name: `tool.${tc.name ?? "tool"}`,
2518
- kind: "TOOL",
2519
- startTime: ts,
2520
- service: SERVICE4,
2521
- agent: SERVICE4,
2522
- tool: tc.name ?? "tool",
2523
- step,
2524
- extra: toolIoAttributes({ input: tc.arguments, inputSource: sourceOf(tc, "arguments") })
2525
- });
2526
- spans.push(t);
2527
- toolByCallId.set(id, t);
2528
- step += 1;
2529
- }
2530
- } else if (entry.tool) {
2531
- const t = toolByCallId.get(entry.tool.call_id ?? "");
2532
- if (t) {
2533
- t.status = entry.tool.output?.is_error ? { code: "ERROR", message: "tool reported error" } : { code: "OK" };
2534
- recordToolOutput(t, entry.tool.output?.values ?? entry.tool.output, entry.tool.output?.values != null ? sourceOf(entry.tool.output, "values") : sourceOf(entry.tool, "output"));
2535
- }
2536
- }
2537
- }
2538
- return spans;
2539
- }
2540
- };
2541
-
2542
- // src/adapters/gemini.ts
2543
- import { readdir as readdir6, stat as stat5 } from "fs/promises";
2544
- import { homedir as homedir4 } from "os";
2545
- import { join as join6 } from "path";
2412
+ import { join as join5 } from "path";
2546
2413
  function iso(ts, fallback) {
2547
2414
  if (typeof ts === "number") return new Date(ts).toISOString();
2548
2415
  if (typeof ts === "string" && ts.length > 0) return ts;
@@ -2551,7 +2418,7 @@ function iso(ts, fallback) {
2551
2418
  function toolStatusError(status2) {
2552
2419
  return status2 != null && /error|fail|cancel/i.test(status2);
2553
2420
  }
2554
- function textOf3(content) {
2421
+ function textOf2(content) {
2555
2422
  const s = typeof content === "string" ? content : JSON.stringify(content ?? "");
2556
2423
  return capText(s);
2557
2424
  }
@@ -2567,7 +2434,7 @@ var GeminiFamilyAdapter = class {
2567
2434
  this.homeDirName = cfg.homeDirName;
2568
2435
  }
2569
2436
  chatsRoot() {
2570
- return join6(homedir4(), this.homeDirName, "tmp");
2437
+ return join5(homedir3(), this.homeDirName, "tmp");
2571
2438
  }
2572
2439
  /** `<home>/projects.json` maps `{ <absolute-cwd>: <projectName> }`. The session
2573
2440
  * dir name (`tmp/<projectHash>/`) is that projectName for registered projects,
@@ -2577,7 +2444,7 @@ var GeminiFamilyAdapter = class {
2577
2444
  const nameToPath = /* @__PURE__ */ new Map();
2578
2445
  try {
2579
2446
  const projects = (await readJsonFile(
2580
- join6(homedir4(), this.homeDirName, "projects.json")
2447
+ join5(homedir3(), this.homeDirName, "projects.json")
2581
2448
  )).projects ?? {};
2582
2449
  for (const [path, name] of Object.entries(projects)) nameToPath.set(name, path);
2583
2450
  } catch (error) {
@@ -2589,7 +2456,7 @@ var GeminiFamilyAdapter = class {
2589
2456
  const root = this.chatsRoot();
2590
2457
  let projectDirs;
2591
2458
  try {
2592
- projectDirs = await readdir6(root);
2459
+ projectDirs = await readdir5(root);
2593
2460
  } catch (error) {
2594
2461
  if (isMissingPathError(error)) return [];
2595
2462
  throw error;
@@ -2598,20 +2465,20 @@ var GeminiFamilyAdapter = class {
2598
2465
  const refs = [];
2599
2466
  for (const pd of projectDirs) {
2600
2467
  const cwd = projectCwds.get(pd) ?? null;
2601
- const chatsDir = join6(root, pd, "chats");
2468
+ const chatsDir = join5(root, pd, "chats");
2602
2469
  let files;
2603
2470
  try {
2604
- files = await readdir6(chatsDir);
2471
+ files = await readdir5(chatsDir);
2605
2472
  } catch (error) {
2606
2473
  if (isMissingPathError(error)) continue;
2607
2474
  throw error;
2608
2475
  }
2609
2476
  for (const f of files) {
2610
2477
  if (!f.startsWith("session-") || !f.endsWith(".json")) continue;
2611
- const path = join6(chatsDir, f);
2478
+ const path = join5(chatsDir, f);
2612
2479
  let st;
2613
2480
  try {
2614
- st = await stat5(path);
2481
+ st = await stat4(path);
2615
2482
  } catch (error) {
2616
2483
  if (isMissingPathError(error)) continue;
2617
2484
  throw error;
@@ -2649,7 +2516,7 @@ var GeminiFamilyAdapter = class {
2649
2516
  const ts = iso(m.timestamp, start);
2650
2517
  const llmId = `llm:${mid}`;
2651
2518
  if (m.type === "user") {
2652
- const prompt = textOf3(m.content);
2519
+ const prompt = textOf2(m.content);
2653
2520
  if (prompt) {
2654
2521
  spans.push(
2655
2522
  userPromptSpan({
@@ -2681,7 +2548,7 @@ var GeminiFamilyAdapter = class {
2681
2548
  inputTokens: m.tokens?.input ?? null,
2682
2549
  outputTokens: m.tokens?.output ?? null,
2683
2550
  step,
2684
- content: textOf3(m.content) || null,
2551
+ content: textOf2(m.content) || null,
2685
2552
  contentSource: sourceOf(m, "content")
2686
2553
  })
2687
2554
  );
@@ -2766,6 +2633,22 @@ var SYNTHETIC_MARKERS = [
2766
2633
  "Staff-engineer code review"
2767
2634
  ];
2768
2635
  var AGENT_PROMPT = /^(you are\b|you're\b|read[- ]only\b|stop now\b|your task\b|your job\b|review the\b|audit\b|analyze the\b|return (only|a |the )|here is the\b|context:|task:|do not (revert|edit|touch)|work only in\b|you have been\b|act as\b|operate the\b|goal:|objective:)/i;
2636
+ var CLAUDE_MACHINE_PREFIXES = [
2637
+ "<local-command-caveat>",
2638
+ "<local-command-stdout>",
2639
+ "<local-command-stderr>",
2640
+ "Caveat: The messages below",
2641
+ "<task-notification>",
2642
+ "<bash-stdout>",
2643
+ "<bash-stderr>",
2644
+ "<user-prompt-submit-hook>",
2645
+ "[Request interrupted by user"
2646
+ ];
2647
+ function claudeRecordIsMachine(args) {
2648
+ if (args.isMeta === true || args.isCompactSummary === true || args.entrypoint === "sdk-cli") return true;
2649
+ const text2 = args.text.trimStart();
2650
+ return CLAUDE_MACHINE_PREFIXES.some((prefix) => text2.startsWith(prefix));
2651
+ }
2769
2652
  function textIsCmdOrInject(s) {
2770
2653
  return CMD_MARKERS.some((m) => s.includes(m)) || INJECT_MARKERS.some((m) => s.includes(m));
2771
2654
  }
@@ -2803,7 +2686,7 @@ function claudePromptStartsTask(args) {
2803
2686
  }
2804
2687
  function claudeActor(args) {
2805
2688
  if (args.isSidechain === true) return "subagent-spawn";
2806
- if (args.isMeta === true) return "injected";
2689
+ if (claudeRecordIsMachine(args)) return "injected";
2807
2690
  if (args.userType != null && args.userType !== "external") return "injected";
2808
2691
  if (textIsCmdOrInject(args.text)) return "injected";
2809
2692
  if (textIsSynthetic(args.text)) return "injected";
@@ -2848,6 +2731,7 @@ function codexKindsAreHuman(kinds) {
2848
2731
  return kinds.every((kind) => kind.startsWith("user."));
2849
2732
  }
2850
2733
  function codexActor(args) {
2734
+ if (args.isFirstUserTurn && args.scriptLaunched) return "injected";
2851
2735
  const recorded = codexKindsAreHuman(args.kinds);
2852
2736
  if (recorded !== void 0) return recorded ? "human" : "injected";
2853
2737
  if ((args.blocks ?? [args.text]).some(isCodexContextBlock)) return "injected";
@@ -2875,9 +2759,9 @@ var CORRECTIVE_REACTIONS = ["correction", "frustration", "jargon", "structure"];
2875
2759
 
2876
2760
  // src/adapters/claude.ts
2877
2761
  import { createHash as createHash6 } from "crypto";
2878
- import { readdir as readdir8, stat as stat6 } from "fs/promises";
2879
- import { homedir as homedir6 } from "os";
2880
- import { basename as basename5, join as join8, relative as relative3 } from "path";
2762
+ import { readdir as readdir7, stat as stat5 } from "fs/promises";
2763
+ import { homedir as homedir5 } from "os";
2764
+ import { basename as basename4, join as join7, relative as relative3 } from "path";
2881
2765
  import {
2882
2766
  applyLlmSpanOtlpAttributes as applyLlmSpanOtlpAttributes2,
2883
2767
  LLM_CACHED_TOKENS,
@@ -2888,12 +2772,12 @@ import {
2888
2772
  import { ATTR as ATTR3, deriveHexId as deriveHexId2 } from "@tangle-network/agent-trace-contract";
2889
2773
 
2890
2774
  // src/adapters/claude-subagent-sources.ts
2891
- import { readdir as readdir7, realpath } from "fs/promises";
2892
- import { homedir as homedir5 } from "os";
2893
- import { dirname as dirname3, isAbsolute as isAbsolute2, join as join7, relative as relative2, resolve as resolve3 } from "path";
2775
+ import { readdir as readdir6, realpath } from "fs/promises";
2776
+ import { homedir as homedir4 } from "os";
2777
+ import { dirname as dirname3, isAbsolute as isAbsolute2, join as join6, relative as relative2, resolve as resolve3 } from "path";
2894
2778
 
2895
2779
  // src/adapters/claude-workflow.ts
2896
- import { basename as basename4, dirname as dirname2, isAbsolute, relative, resolve as resolve2 } from "path";
2780
+ import { basename as basename3, dirname as dirname2, isAbsolute, relative, resolve as resolve2 } from "path";
2897
2781
  var ClaudeTaskScopeError = class extends Error {
2898
2782
  constructor(message) {
2899
2783
  super(message);
@@ -2905,7 +2789,7 @@ function validWorkflowRunReference(runId, transcriptDir) {
2905
2789
  const cleanRunId = runId.trim();
2906
2790
  const cleanTranscriptDir = transcriptDir.trim();
2907
2791
  const resolvedTranscriptDir = resolve2(cleanTranscriptDir);
2908
- if (!cleanRunId || cleanRunId === "." || cleanRunId === ".." || cleanRunId.includes("/") || cleanRunId.includes("\\") || !isAbsolute(cleanTranscriptDir) || basename4(resolvedTranscriptDir) !== cleanRunId || basename4(dirname2(resolvedTranscriptDir)) !== "workflows" || basename4(dirname2(dirname2(resolvedTranscriptDir))) !== "subagents") {
2792
+ if (!cleanRunId || cleanRunId === "." || cleanRunId === ".." || cleanRunId.includes("/") || cleanRunId.includes("\\") || !isAbsolute(cleanTranscriptDir) || basename3(resolvedTranscriptDir) !== cleanRunId || basename3(dirname2(resolvedTranscriptDir)) !== "workflows" || basename3(dirname2(dirname2(resolvedTranscriptDir))) !== "subagents") {
2909
2793
  return void 0;
2910
2794
  }
2911
2795
  return { runId: cleanRunId, transcriptDir: cleanTranscriptDir };
@@ -3067,14 +2951,14 @@ async function listSubagentFiles(root, signal, copiedWorkflow = false) {
3067
2951
  if (!dir) continue;
3068
2952
  let entries;
3069
2953
  try {
3070
- entries = await readdir7(dir, { withFileTypes: true });
2954
+ entries = await readdir6(dir, { withFileTypes: true });
3071
2955
  } catch (error) {
3072
2956
  if (isMissingPathError(error)) continue;
3073
2957
  throw error;
3074
2958
  }
3075
2959
  signal?.throwIfAborted();
3076
2960
  for (const entry of entries) {
3077
- const path = join7(dir, entry.name);
2961
+ const path = join6(dir, entry.name);
3078
2962
  if (copiedWorkflow && entry.isSymbolicLink()) {
3079
2963
  throw new ClaudeTaskScopeError(
3080
2964
  `Claude Workflow subagent does not match copied source: ${path}`
@@ -3094,7 +2978,7 @@ function pathIsWithin(root, target) {
3094
2978
  return path === "" || path !== ".." && !path.startsWith("../") && !path.startsWith("..\\") && !isAbsolute2(path);
3095
2979
  }
3096
2980
  function workflowStorageRoot(ref) {
3097
- const nativeRoot = resolve3(homedir5(), ".claude", "projects");
2981
+ const nativeRoot = resolve3(homedir4(), ".claude", "projects");
3098
2982
  return pathIsWithin(nativeRoot, ref.path) ? nativeRoot : dirname3(resolve3(ref.path));
3099
2983
  }
3100
2984
  function relocatedWorkflowDirectory(ref, binding) {
@@ -3103,10 +2987,10 @@ function relocatedWorkflowDirectory(ref, binding) {
3103
2987
  const parts = source.split("/").slice(-7);
3104
2988
  const sessionId = parts[3];
3105
2989
  if (parts[0] !== ".claude" || parts[1] !== "projects" || !parts[2] || !sessionId || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(sessionId) || parts[4] !== "subagents" || parts[5] !== "workflows" || parts[6] !== binding.runId) return void 0;
3106
- const sessionRoot2 = join7(dirname3(resolve3(ref.path)), sessionId);
2990
+ const sessionRoot2 = join6(dirname3(resolve3(ref.path)), sessionId);
3107
2991
  return {
3108
2992
  sessionRoot: sessionRoot2,
3109
- transcriptDir: join7(sessionRoot2, "subagents", "workflows", binding.runId)
2993
+ transcriptDir: join6(sessionRoot2, "subagents", "workflows", binding.runId)
3110
2994
  };
3111
2995
  }
3112
2996
  async function workflowTranscriptDirectories(ref, bindings) {
@@ -3179,7 +3063,7 @@ async function workflowTranscriptDirectories(ref, bindings) {
3179
3063
  );
3180
3064
  }
3181
3065
  async function collectClaudeSubagentSources(ref, bindings, signal) {
3182
- const subDir = join7(ref.path.replace(/\.jsonl$/, ""), "subagents");
3066
+ const subDir = join6(ref.path.replace(/\.jsonl$/, ""), "subagents");
3183
3067
  const filesByPath = /* @__PURE__ */ new Map();
3184
3068
  const workflowByPath = /* @__PURE__ */ new Map();
3185
3069
  for (const file of await listSubagentFiles(subDir, signal)) {
@@ -3219,7 +3103,7 @@ async function collectClaudeSubagentSources(ref, bindings, signal) {
3219
3103
  }
3220
3104
 
3221
3105
  // src/adapters/claude.ts
3222
- var SERVICE5 = "claude-code";
3106
+ var SERVICE4 = "claude-code";
3223
3107
  var AGENT_TOOL_RENAMED_IN = [2, 1, 63];
3224
3108
  function modelFacingToolNames(tools, version) {
3225
3109
  if (typeof version !== "string" || !atLeast(version, AGENT_TOOL_RENAMED_IN)) return [...tools];
@@ -3238,6 +3122,7 @@ var RUN_STATUS_ATTR = "run.status";
3238
3122
  var EPOCH = (/* @__PURE__ */ new Date(0)).toISOString();
3239
3123
  var HUMAN_ORIGIN = "human";
3240
3124
  var ORIGIN_EVIDENCE_ATTR = "traces.claude.actor_evidence";
3125
+ var MACHINE_RECORD_ATTR = "traces.claude.machine_record";
3241
3126
  var ORIGIN_RECORDED_ATTR = "traces.claude.origin_recorded";
3242
3127
  var ORIGIN_KIND_ATTR = "traces.claude.origin_kind";
3243
3128
  var COMMAND_NAME = /<command-name>([\s\S]*?)<\/command-name>/;
@@ -3269,7 +3154,7 @@ function normalizeClaudeIds(spans) {
3269
3154
  function asBlocks(content) {
3270
3155
  return Array.isArray(content) ? content : [];
3271
3156
  }
3272
- function textOf4(content) {
3157
+ function textOf3(content) {
3273
3158
  if (typeof content === "string") return capText(content);
3274
3159
  return capText(
3275
3160
  asBlocks(content).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n")
@@ -3349,7 +3234,7 @@ function projectClaudeEvent(event) {
3349
3234
  outputTokens: event.message.usage?.output_tokens ?? null,
3350
3235
  cachedInputTokens: event.message.usage?.cache_read_input_tokens ?? null,
3351
3236
  cacheWriteInputTokens: event.message.usage?.cache_creation_input_tokens ?? null,
3352
- content: textOf4(event.message.content) || null,
3237
+ content: textOf3(event.message.content) || null,
3353
3238
  contentSource: textSources(event.message, "content"),
3354
3239
  parentToolUseId: event.parent_tool_use_id ?? null,
3355
3240
  tools
@@ -3376,7 +3261,7 @@ function projectClaudeEvent(event) {
3376
3261
  sourceOf(block, "content")
3377
3262
  ));
3378
3263
  }
3379
- const prompt = textOf4(event.message.content);
3264
+ const prompt = textOf3(event.message.content);
3380
3265
  return {
3381
3266
  kind: "user",
3382
3267
  timestamp,
@@ -3386,6 +3271,8 @@ function projectClaudeEvent(event) {
3386
3271
  ...prompt ? {
3387
3272
  isSidechain: event.isSidechain === true,
3388
3273
  isMeta: event.isMeta === true,
3274
+ isCompactSummary: event.isCompactSummary === true,
3275
+ entrypoint: event.entrypoint ?? null,
3389
3276
  userType: event.userType ?? null,
3390
3277
  originKind: recordedOrigin(event.origin)
3391
3278
  } : {},
@@ -3406,7 +3293,7 @@ function projectClaudeEvent(event) {
3406
3293
  };
3407
3294
  }
3408
3295
  if (event.type === "attachment" && event.attachment?.type === "queued_command") {
3409
- const prompt = textOf4(event.attachment.prompt);
3296
+ const prompt = textOf3(event.attachment.prompt);
3410
3297
  if (prompt) {
3411
3298
  return {
3412
3299
  kind: "queued-prompt",
@@ -3512,6 +3399,7 @@ function applyOriginEnrichment(uid, originKind, state) {
3512
3399
  state.sawRecordedOrigin = true;
3513
3400
  prompt.attributes[ORIGIN_RECORDED_ATTR] = true;
3514
3401
  prompt.attributes[ORIGIN_KIND_ATTR] = originKind;
3402
+ if (prompt.attributes[MACHINE_RECORD_ATTR] === true) return;
3515
3403
  prompt.attributes[ACTOR_ATTR] = claudeActorFromOrigin(
3516
3404
  originKind,
3517
3405
  () => prompt.attributes[ACTOR_ATTR]
@@ -3554,7 +3442,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3554
3442
  name: "session.compacted",
3555
3443
  kind: "CHAIN",
3556
3444
  startTime: event.timestamp,
3557
- service: SERVICE5,
3445
+ service: SERVICE4,
3558
3446
  agent: ctx.agent,
3559
3447
  step: state.step++,
3560
3448
  extra
@@ -3573,7 +3461,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3573
3461
  name: "llm.turn",
3574
3462
  kind: "LLM",
3575
3463
  startTime: event.timestamp,
3576
- service: SERVICE5,
3464
+ service: SERVICE4,
3577
3465
  agent: ctx.agent,
3578
3466
  model: event.model,
3579
3467
  inputTokens: event.inputTokens,
@@ -3626,7 +3514,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3626
3514
  name: `tool.${tool.name}`,
3627
3515
  kind: "TOOL",
3628
3516
  startTime: event.timestamp,
3629
- service: SERVICE5,
3517
+ service: SERVICE4,
3630
3518
  agent: ctx.agent,
3631
3519
  tool: tool.name,
3632
3520
  step: state.step,
@@ -3645,10 +3533,15 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3645
3533
  }
3646
3534
  } else if (event.kind === "user") {
3647
3535
  if (event.prompt) {
3648
- const actor = claudeActorFromOrigin(event.originKind, () => claudeActor({
3536
+ const machine = claudeRecordIsMachine({
3537
+ text: event.prompt,
3538
+ isMeta: event.isMeta,
3539
+ isCompactSummary: event.isCompactSummary,
3540
+ entrypoint: event.entrypoint
3541
+ });
3542
+ const actor = machine ? "injected" : claudeActorFromOrigin(event.originKind, () => claudeActor({
3649
3543
  text: event.prompt ?? "",
3650
3544
  isSidechain: event.isSidechain,
3651
- isMeta: event.isMeta,
3652
3545
  userType: event.userType ?? null,
3653
3546
  isFirstUserTurn: !state.sawUserTurn
3654
3547
  }));
@@ -3660,13 +3553,14 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3660
3553
  spanId: `${ctx.idPrefix}${uid}:user`,
3661
3554
  parentSpanId: userParent ? userParent.span.span_id : ctx.rootParent,
3662
3555
  startTime: event.timestamp,
3663
- service: SERVICE5,
3556
+ service: SERVICE4,
3664
3557
  agent: ctx.agent,
3665
3558
  step: state.step,
3666
3559
  content: actor === "human" ? typedPromptText(event.prompt) : event.prompt,
3667
3560
  contentSource: event.contentSource,
3668
3561
  actor
3669
3562
  });
3563
+ if (machine) prompt.attributes[MACHINE_RECORD_ATTR] = true;
3670
3564
  if (event.originKind) {
3671
3565
  prompt.attributes[ORIGIN_RECORDED_ATTR] = true;
3672
3566
  prompt.attributes[ORIGIN_KIND_ATTR] = event.originKind;
@@ -3683,14 +3577,15 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3683
3577
  } else if (event.kind === "attachment") {
3684
3578
  backfillResult(state.toolSpanByUseId.get(event.result.toolUseId), event.timestamp, event.result);
3685
3579
  } else if (event.kind === "queued-prompt") {
3686
- const actor = claudeActorFromOrigin(event.originKind, () => "injected");
3580
+ const machine = claudeRecordIsMachine({ text: event.prompt });
3581
+ const actor = machine ? "injected" : claudeActorFromOrigin(event.originKind, () => "injected");
3687
3582
  if (event.originKind) state.sawRecordedOrigin = true;
3688
3583
  const prompt = userPromptSpan({
3689
3584
  traceId: ctx.traceId,
3690
3585
  spanId: `${ctx.idPrefix}${uid}:queued`,
3691
3586
  parentSpanId: ctx.rootParent,
3692
3587
  startTime: event.timestamp,
3693
- service: SERVICE5,
3588
+ service: SERVICE4,
3694
3589
  agent: ctx.agent,
3695
3590
  step: state.step,
3696
3591
  content: actor === "human" ? typedPromptText(event.prompt) : event.prompt,
@@ -3698,6 +3593,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3698
3593
  actor
3699
3594
  });
3700
3595
  prompt.attributes["traces.claude.queued"] = true;
3596
+ if (machine) prompt.attributes[MACHINE_RECORD_ATTR] = true;
3701
3597
  if (event.originKind) {
3702
3598
  prompt.attributes[ORIGIN_RECORDED_ATTR] = true;
3703
3599
  prompt.attributes[ORIGIN_KIND_ATTR] = event.originKind;
@@ -3715,7 +3611,7 @@ function consumeClaudeEvent(event, uid, ctx, state) {
3715
3611
  kind: "CHAIN",
3716
3612
  startTime: event.timestamp,
3717
3613
  endTime: event.timestamp,
3718
- service: SERVICE5,
3614
+ service: SERVICE4,
3719
3615
  agent: ctx.agent,
3720
3616
  step: state.step,
3721
3617
  extra: toolIoAttributes({ input: { path: event.path }, inputSource: event.contentSource })
@@ -3738,7 +3634,7 @@ function mergeAssistantMessage(event, messageId, llmSpan, ctx, state) {
3738
3634
  kind: "CHAIN",
3739
3635
  startTime: event.timestamp,
3740
3636
  endTime: event.timestamp,
3741
- service: SERVICE5,
3637
+ service: SERVICE4,
3742
3638
  agent: ctx.agent,
3743
3639
  step: state.step,
3744
3640
  content: typeof llmSpan.attributes.content === "string" ? llmSpan.attributes.content : "",
@@ -3923,7 +3819,7 @@ var ClaudeAdapter = class {
3923
3819
  harness = "claude-code";
3924
3820
  aliases = ["claude", "claudish", "openclaw", "nanoclaw"];
3925
3821
  root() {
3926
- return join8(homedir6(), ".claude", "projects");
3822
+ return join7(homedir5(), ".claude", "projects");
3927
3823
  }
3928
3824
  async sourcePaths(ref, options = {}) {
3929
3825
  const bindings = await readClaudeWorkflowBindings(ref, options);
@@ -3933,7 +3829,7 @@ var ClaudeAdapter = class {
3933
3829
  options.signal?.throwIfAborted();
3934
3830
  const path = file.replace(/\.jsonl$/, ".meta.json");
3935
3831
  try {
3936
- const source = await stat6(path);
3832
+ const source = await stat5(path);
3937
3833
  if (source.isFile()) metadataFiles.push(path);
3938
3834
  } catch (error) {
3939
3835
  if (!isMissingPathError(error)) throw error;
@@ -3946,27 +3842,27 @@ var ClaudeAdapter = class {
3946
3842
  const root = this.root();
3947
3843
  let projectDirs;
3948
3844
  try {
3949
- projectDirs = await readdir8(root);
3845
+ projectDirs = await readdir7(root);
3950
3846
  } catch (error) {
3951
3847
  if (isMissingPathError(error)) return [];
3952
3848
  throw error;
3953
3849
  }
3954
3850
  const refs = [];
3955
3851
  for (const dir of projectDirs) {
3956
- const dirPath = join8(root, dir);
3852
+ const dirPath = join7(root, dir);
3957
3853
  let files;
3958
3854
  try {
3959
- files = await readdir8(dirPath);
3855
+ files = await readdir7(dirPath);
3960
3856
  } catch (error) {
3961
3857
  if (isMissingPathError(error)) continue;
3962
3858
  throw error;
3963
3859
  }
3964
3860
  for (const f of files) {
3965
3861
  if (!f.endsWith(".jsonl")) continue;
3966
- const path = join8(dirPath, f);
3862
+ const path = join7(dirPath, f);
3967
3863
  let st;
3968
3864
  try {
3969
- st = await stat6(path);
3865
+ st = await stat5(path);
3970
3866
  } catch (error) {
3971
3867
  if (isMissingPathError(error)) continue;
3972
3868
  throw error;
@@ -3975,7 +3871,7 @@ var ClaudeAdapter = class {
3975
3871
  if (opts.sinceMs && st.mtimeMs < opts.sinceMs) continue;
3976
3872
  const cwd = `/${dir.replace(/^-/, "").replace(/-/g, "/")}`;
3977
3873
  if (opts.cwd && !cwd.startsWith(opts.cwd)) continue;
3978
- refs.push({ harness: this.harness, sessionId: basename5(f, ".jsonl"), path, cwd, mtimeMs: st.mtimeMs });
3874
+ refs.push({ harness: this.harness, sessionId: basename4(f, ".jsonl"), path, cwd, mtimeMs: st.mtimeMs });
3979
3875
  }
3980
3876
  }
3981
3877
  return refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
@@ -3990,7 +3886,7 @@ var ClaudeAdapter = class {
3990
3886
  const sourceRootId = `root:${sourceTraceId}`;
3991
3887
  const ctx = {
3992
3888
  traceId: sourceTraceId,
3993
- agent: SERVICE5,
3889
+ agent: SERVICE4,
3994
3890
  startStep: 0,
3995
3891
  idPrefix: "",
3996
3892
  rootParent: sourceRootId
@@ -4071,8 +3967,8 @@ var ClaudeAdapter = class {
4071
3967
  name: "session",
4072
3968
  kind: "AGENT",
4073
3969
  startTime: (/* @__PURE__ */ new Date(0)).toISOString(),
4074
- service: SERVICE5,
4075
- agent: SERVICE5
3970
+ service: SERVICE4,
3971
+ agent: SERVICE4
4076
3972
  });
4077
3973
  if (offeredTools) {
4078
3974
  root.attributes[TOOL_DEFINITIONS_ATTR] = JSON.stringify(offeredTools.map((name) => ({ type: "function", name })));
@@ -4105,7 +4001,7 @@ var ClaudeAdapter = class {
4105
4001
  }
4106
4002
  /** Parse nested `subagents/.../agent-*.jsonl`, parenting each under its Agent call. */
4107
4003
  async foldSubagents(ref, traceId, main, workflowBindings, out, options) {
4108
- const subDir = join8(ref.path.replace(/\.jsonl$/, ""), "subagents");
4004
+ const subDir = join7(ref.path.replace(/\.jsonl$/, ""), "subagents");
4109
4005
  const sources = await collectClaudeSubagentSources(
4110
4006
  ref,
4111
4007
  workflowBindings,
@@ -4129,7 +4025,7 @@ var ClaudeAdapter = class {
4129
4025
  const agent = {
4130
4026
  file,
4131
4027
  sourceKey,
4132
- agentId: basename5(file, ".jsonl").replace(/^agent-/, ""),
4028
+ agentId: basename4(file, ".jsonl").replace(/^agent-/, ""),
4133
4029
  meta,
4134
4030
  ...meta.toolUseId ? { parentToolUseId: meta.toolUseId } : {}
4135
4031
  };
@@ -4143,7 +4039,7 @@ var ClaudeAdapter = class {
4143
4039
  );
4144
4040
  const parsed = await parseClaudeSubagent(ref, traceId, agent, options);
4145
4041
  const { binding, confidence } = selectWorkflowBinding(
4146
- basename5(file),
4042
+ basename4(file),
4147
4043
  runBindings,
4148
4044
  firstSubagentTimestamp(agent, parsed),
4149
4045
  meta.toolUseId
@@ -4261,7 +4157,7 @@ function subagentLifecycleSpan(agent, parsed, traceId, parentSpanId, task, subDi
4261
4157
  // The transcript records what the child did, not whether the parent
4262
4158
  // accepted it; the parent's own tool span carries that status.
4263
4159
  status: "UNSET",
4264
- service: SERVICE5,
4160
+ service: SERVICE4,
4265
4161
  agent: agent.meta.agentType ? `subagent:${agent.meta.agentType}` : "subagent",
4266
4162
  extra: {
4267
4163
  ...toolIoAttributes({
@@ -4710,11 +4606,11 @@ async function resolveCodexParentTask(ref, childSessionId, options = {}) {
4710
4606
  }
4711
4607
 
4712
4608
  // src/adapters/codex.ts
4713
- import { readdir as readdir9, stat as stat7 } from "fs/promises";
4714
- import { homedir as homedir7 } from "os";
4715
- import { basename as basename6, join as join9 } from "path";
4609
+ import { readdir as readdir8, stat as stat6 } from "fs/promises";
4610
+ import { homedir as homedir6 } from "os";
4611
+ import { basename as basename5, join as join8 } from "path";
4716
4612
  import { deriveHexId as deriveHexId3 } from "@tangle-network/agent-trace-contract";
4717
- var SERVICE6 = "codex";
4613
+ var SERVICE5 = "codex";
4718
4614
  var SESSION_HEAD_LINES = 40;
4719
4615
  var MAX_INHERITED_SPANS = 200;
4720
4616
  var CODEX_SOURCE_TRACE_ID = "traces.codex.source_trace_id";
@@ -4755,7 +4651,7 @@ function tokenUsageSignature(usage) {
4755
4651
  usage.total_tokens ?? null
4756
4652
  ]);
4757
4653
  }
4758
- function textOf5(content) {
4654
+ function textOf4(content) {
4759
4655
  return capText(contentToString(content));
4760
4656
  }
4761
4657
  function numericStatus(value) {
@@ -5029,9 +4925,9 @@ function itemCountsJson(counts) {
5029
4925
  }
5030
4926
  function placeInnerSpans(pending, windows) {
5031
4927
  return pending.map((entry) => {
5032
- const { parent, join: join36 } = joinItem(windows, entry.startMs, entry.endMs);
4928
+ const { parent, join: join35 } = joinItem(windows, entry.startMs, entry.endMs);
5033
4929
  if (parent) entry.span.parent_span_id = parent.span_id;
5034
- entry.span.attributes["traces.codex.item_join"] = join36;
4930
+ entry.span.attributes["traces.codex.item_join"] = join35;
5035
4931
  return entry.span;
5036
4932
  });
5037
4933
  }
@@ -5047,8 +4943,8 @@ function commandSpan(context, item, command, recordTime) {
5047
4943
  startTime: start,
5048
4944
  status: status2.code,
5049
4945
  statusMessage: status2.message,
5050
- service: SERVICE6,
5051
- agent: SERVICE6,
4946
+ service: SERVICE5,
4947
+ agent: SERVICE5,
5052
4948
  extra: {
5053
4949
  ...toolIoAttributes({
5054
4950
  input: { command: command.command, ...command.cwd ? { cwd: command.cwd } : {} },
@@ -5080,8 +4976,8 @@ function fileChangeSpans(context, item, fileChange, recordTime) {
5080
4976
  startTime: start,
5081
4977
  status: status2.code,
5082
4978
  statusMessage: status2.message,
5083
- service: SERVICE6,
5084
- agent: SERVICE6,
4979
+ service: SERVICE5,
4980
+ agent: SERVICE5,
5085
4981
  extra: {
5086
4982
  ...toolIoAttributes({
5087
4983
  input: { path: change.path, kind: change.kind, ...change.movePath ? { move_path: change.movePath } : {} },
@@ -5129,40 +5025,40 @@ function isExpectedBlockingTool(name, input) {
5129
5025
  async function* walkRollouts(root) {
5130
5026
  let years;
5131
5027
  try {
5132
- years = await readdir9(root);
5028
+ years = await readdir8(root);
5133
5029
  } catch (error) {
5134
5030
  if (isMissingPathError(error)) return;
5135
5031
  throw error;
5136
5032
  }
5137
5033
  for (const y of years) {
5138
- const yp = join9(root, y);
5034
+ const yp = join8(root, y);
5139
5035
  let months;
5140
5036
  try {
5141
- months = await readdir9(yp);
5037
+ months = await readdir8(yp);
5142
5038
  } catch (error) {
5143
5039
  if (isMissingPathError(error)) continue;
5144
5040
  throw error;
5145
5041
  }
5146
5042
  for (const m of months) {
5147
- const mp = join9(yp, m);
5043
+ const mp = join8(yp, m);
5148
5044
  let days;
5149
5045
  try {
5150
- days = await readdir9(mp);
5046
+ days = await readdir8(mp);
5151
5047
  } catch (error) {
5152
5048
  if (isMissingPathError(error)) continue;
5153
5049
  throw error;
5154
5050
  }
5155
5051
  for (const d of days) {
5156
- const dp = join9(mp, d);
5052
+ const dp = join8(mp, d);
5157
5053
  let files;
5158
5054
  try {
5159
- files = await readdir9(dp);
5055
+ files = await readdir8(dp);
5160
5056
  } catch (error) {
5161
5057
  if (isMissingPathError(error)) continue;
5162
5058
  throw error;
5163
5059
  }
5164
5060
  for (const f of files) {
5165
- if (f.startsWith("rollout-") && f.endsWith(".jsonl")) yield join9(dp, f);
5061
+ if (f.startsWith("rollout-") && f.endsWith(".jsonl")) yield join8(dp, f);
5166
5062
  }
5167
5063
  }
5168
5064
  }
@@ -5172,19 +5068,19 @@ var CodexAdapter = class {
5172
5068
  harness = "codex";
5173
5069
  aliases = ["codex-acp"];
5174
5070
  root() {
5175
- return process.env.CODEX_HOME ? join9(process.env.CODEX_HOME, "sessions") : join9(homedir7(), ".codex", "sessions");
5071
+ return process.env.CODEX_HOME ? join8(process.env.CODEX_HOME, "sessions") : join8(homedir6(), ".codex", "sessions");
5176
5072
  }
5177
5073
  async refFromPath(path, opts) {
5178
5074
  let st;
5179
5075
  try {
5180
- st = await stat7(path);
5076
+ st = await stat6(path);
5181
5077
  } catch (error) {
5182
5078
  if (isMissingPathError(error)) return void 0;
5183
5079
  throw error;
5184
5080
  }
5185
5081
  if (opts.sinceMs && st.mtimeMs < opts.sinceMs) return void 0;
5186
5082
  let cwd = null;
5187
- let id = basename6(path).replace(/^rollout-[\dT-]+-/, "").replace(/\.jsonl$/, "");
5083
+ let id = basename5(path).replace(/^rollout-[\dT-]+-/, "").replace(/\.jsonl$/, "");
5188
5084
  const ref = { harness: this.harness, sessionId: id, path, cwd, mtimeMs: st.mtimeMs };
5189
5085
  const head = await takeJsonl(path, SESSION_HEAD_LINES, sessionJsonlOptions(ref));
5190
5086
  for (const parsed of head) {
@@ -5212,7 +5108,7 @@ var CodexAdapter = class {
5212
5108
  async locateBySessionId(sessionId, opts = {}) {
5213
5109
  const refs = [];
5214
5110
  for await (const path of walkRollouts(this.root())) {
5215
- if (!basename6(path).includes(sessionId)) continue;
5111
+ if (!basename5(path).includes(sessionId)) continue;
5216
5112
  const ref = await this.refFromPath(path, opts);
5217
5113
  if (ref?.sessionId === sessionId) refs.push(ref);
5218
5114
  }
@@ -5307,6 +5203,7 @@ var CodexAdapter = class {
5307
5203
  }
5308
5204
  }
5309
5205
  const traceId = meta?.payload?.id ?? ref.sessionId;
5206
+ const scriptLaunched = meta?.payload?.originator === "codex_exec" || meta?.payload?.source === "exec";
5310
5207
  const sessionRole = parentSessionId || meta?.payload?.thread_source === "subagent" ? "child" : "operator";
5311
5208
  const rootId = `root:${traceId}`;
5312
5209
  const root = span({
@@ -5316,8 +5213,8 @@ var CodexAdapter = class {
5316
5213
  name: "session",
5317
5214
  kind: "AGENT",
5318
5215
  startTime: selectedBoundary?.timestamp ?? meta?.timestamp ?? first?.timestamp ?? (/* @__PURE__ */ new Date(0)).toISOString(),
5319
- service: SERVICE6,
5320
- agent: SERVICE6,
5216
+ service: SERVICE5,
5217
+ agent: SERVICE5,
5321
5218
  model,
5322
5219
  status: "UNSET",
5323
5220
  extra: {
@@ -5373,7 +5270,7 @@ var CodexAdapter = class {
5373
5270
  recorded.span.attributes[USER_MESSAGE_EVENT_ATTR] = true;
5374
5271
  return;
5375
5272
  }
5376
- const actor = sessionRole === "child" ? "agent" : codexActor({ text: prompt, isFirstUserTurn: !sawUserTurn });
5273
+ const actor = sessionRole === "child" ? "agent" : codexActor({ text: prompt, isFirstUserTurn: !sawUserTurn, scriptLaunched });
5377
5274
  sawUserTurn = true;
5378
5275
  const turnSpan = userPromptSpan({
5379
5276
  traceId,
@@ -5382,8 +5279,8 @@ var CodexAdapter = class {
5382
5279
  startTime: ts,
5383
5280
  content: prompt,
5384
5281
  contentSource,
5385
- service: SERVICE6,
5386
- agent: SERVICE6,
5282
+ service: SERVICE5,
5283
+ agent: SERVICE5,
5387
5284
  step,
5388
5285
  actor
5389
5286
  });
@@ -5408,7 +5305,7 @@ var CodexAdapter = class {
5408
5305
  if (inheritedTurnKeys.has(dedupKey)) return;
5409
5306
  if (!claimInheritedSpan()) return;
5410
5307
  inheritedTurnKeys.add(dedupKey);
5411
- const actor = codexActor({ text: prompt, blocks, isFirstUserTurn: !sawInheritedTurn, kinds });
5308
+ const actor = codexActor({ text: prompt, blocks, isFirstUserTurn: !sawInheritedTurn, kinds, scriptLaunched });
5412
5309
  sawInheritedTurn = true;
5413
5310
  const turnSpan = userPromptSpan({
5414
5311
  traceId,
@@ -5417,8 +5314,8 @@ var CodexAdapter = class {
5417
5314
  startTime: ts,
5418
5315
  content: prompt,
5419
5316
  contentSource,
5420
- service: SERVICE6,
5421
- agent: SERVICE6,
5317
+ service: SERVICE5,
5318
+ agent: SERVICE5,
5422
5319
  step,
5423
5320
  actor
5424
5321
  });
@@ -5440,8 +5337,8 @@ var CodexAdapter = class {
5440
5337
  name: "session.compacted",
5441
5338
  kind: "CHAIN",
5442
5339
  startTime: ts,
5443
- service: SERVICE6,
5444
- agent: SERVICE6,
5340
+ service: SERVICE5,
5341
+ agent: SERVICE5,
5445
5342
  step,
5446
5343
  content: summary,
5447
5344
  contentSource: textSources(payload, "message"),
@@ -5527,8 +5424,8 @@ var CodexAdapter = class {
5527
5424
  name: "subagent.lifecycle",
5528
5425
  kind: "AGENT",
5529
5426
  startTime: eventTime2,
5530
- service: SERVICE6,
5531
- agent: SERVICE6,
5427
+ service: SERVICE5,
5428
+ agent: SERVICE5,
5532
5429
  step,
5533
5430
  status: "UNSET",
5534
5431
  extra: {
@@ -5606,8 +5503,8 @@ var CodexAdapter = class {
5606
5503
  name: "llm.turn",
5607
5504
  kind: "LLM",
5608
5505
  startTime: ts,
5609
- service: SERVICE6,
5610
- agent: SERVICE6,
5506
+ service: SERVICE5,
5507
+ agent: SERVICE5,
5611
5508
  model,
5612
5509
  inputTokens: u.input_tokens ?? null,
5613
5510
  outputTokens: u.output_tokens ?? null,
@@ -5639,8 +5536,8 @@ var CodexAdapter = class {
5639
5536
  kind: "TOOL",
5640
5537
  startTime: ts,
5641
5538
  status: "UNSET",
5642
- service: SERVICE6,
5643
- agent: SERVICE6,
5539
+ service: SERVICE5,
5540
+ agent: SERVICE5,
5644
5541
  tool: name,
5645
5542
  step,
5646
5543
  extra: {
@@ -5750,7 +5647,7 @@ var CodexAdapter = class {
5750
5647
  ]);
5751
5648
  if (seenAgentMessages.has(messageIdentity)) continue;
5752
5649
  seenAgentMessages.add(messageIdentity);
5753
- const text2 = textOf5(l.payload.content);
5650
+ const text2 = textOf4(l.payload.content);
5754
5651
  const author = l.payload.author;
5755
5652
  const recipient = l.payload.recipient;
5756
5653
  const messageType = /^Message Type:\s*FINAL_ANSWER\b/m.test(text2) ? "final" : /^Message Type:\s*MESSAGE\b/m.test(text2) ? "progress" : "unknown";
@@ -5763,8 +5660,8 @@ var CodexAdapter = class {
5763
5660
  name: `message.agent.${messageType}`,
5764
5661
  kind: "CHAIN",
5765
5662
  startTime: ts,
5766
- service: SERVICE6,
5767
- agent: SERVICE6,
5663
+ service: SERVICE5,
5664
+ agent: SERVICE5,
5768
5665
  step,
5769
5666
  content: text2,
5770
5667
  contentSource: textSources(l.payload, "content"),
@@ -5799,6 +5696,7 @@ var CodexAdapter = class {
5799
5696
  text: prompt,
5800
5697
  blocks: contentTextBlocks(l.payload.content),
5801
5698
  isFirstUserTurn: !sawUserTurn,
5699
+ scriptLaunched,
5802
5700
  kinds: l.payload.internal_chat_message_metadata_passthrough?.content_item_kinds
5803
5701
  });
5804
5702
  sawUserTurn = true;
@@ -5809,8 +5707,8 @@ var CodexAdapter = class {
5809
5707
  startTime: ts,
5810
5708
  content: prompt,
5811
5709
  contentSource: textSources(l.payload, "content"),
5812
- service: SERVICE6,
5813
- agent: SERVICE6,
5710
+ service: SERVICE5,
5711
+ agent: SERVICE5,
5814
5712
  step,
5815
5713
  actor
5816
5714
  });
@@ -5819,7 +5717,7 @@ var CodexAdapter = class {
5819
5717
  step += 1;
5820
5718
  }
5821
5719
  } else if (l.type === "response_item" && l.payload?.type === "message") {
5822
- const text2 = textOf5(l.payload.content);
5720
+ const text2 = textOf4(l.payload.content);
5823
5721
  if (text2) {
5824
5722
  spans.push(
5825
5723
  span({
@@ -5829,8 +5727,8 @@ var CodexAdapter = class {
5829
5727
  name: `message.${l.payload.role ?? "unknown"}`,
5830
5728
  kind: "CHAIN",
5831
5729
  startTime: ts,
5832
- service: SERVICE6,
5833
- agent: SERVICE6,
5730
+ service: SERVICE5,
5731
+ agent: SERVICE5,
5834
5732
  step,
5835
5733
  content: text2,
5836
5734
  contentSource: textSources(l.payload, "content")
@@ -5888,14 +5786,14 @@ var CodexAdapter = class {
5888
5786
  };
5889
5787
 
5890
5788
  // src/adapters/opencode.ts
5891
- import { readdir as readdir10, stat as stat8 } from "fs/promises";
5892
- import { homedir as homedir8 } from "os";
5893
- import { join as join10 } from "path";
5894
- var SERVICE7 = "opencode";
5789
+ import { readdir as readdir9, stat as stat7 } from "fs/promises";
5790
+ import { homedir as homedir7 } from "os";
5791
+ import { join as join9 } from "path";
5792
+ var SERVICE6 = "opencode";
5895
5793
  function isoOf(ms2) {
5896
5794
  return new Date(ms2 ?? 0).toISOString();
5897
5795
  }
5898
- function textOf6(parts) {
5796
+ function textOf5(parts) {
5899
5797
  return capText(
5900
5798
  parts.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("\n")
5901
5799
  );
@@ -5903,24 +5801,24 @@ function textOf6(parts) {
5903
5801
  var OpencodeAdapter = class {
5904
5802
  harness = "opencode";
5905
5803
  storage() {
5906
- const base = process.env.XDG_DATA_HOME ?? join10(homedir8(), ".local", "share");
5907
- return join10(base, "opencode", "storage");
5804
+ const base = process.env.XDG_DATA_HOME ?? join9(homedir7(), ".local", "share");
5805
+ return join9(base, "opencode", "storage");
5908
5806
  }
5909
5807
  async locate(opts = {}) {
5910
- const msgRoot = join10(this.storage(), "message");
5808
+ const msgRoot = join9(this.storage(), "message");
5911
5809
  let sessionDirs;
5912
5810
  try {
5913
- sessionDirs = await readdir10(msgRoot);
5811
+ sessionDirs = await readdir9(msgRoot);
5914
5812
  } catch (error) {
5915
5813
  if (isMissingPathError(error)) return [];
5916
5814
  throw error;
5917
5815
  }
5918
5816
  const refs = [];
5919
5817
  for (const sid of sessionDirs) {
5920
- const dir = join10(msgRoot, sid);
5818
+ const dir = join9(msgRoot, sid);
5921
5819
  let st;
5922
5820
  try {
5923
- st = await stat8(dir);
5821
+ st = await stat7(dir);
5924
5822
  } catch (error) {
5925
5823
  if (isMissingPathError(error)) continue;
5926
5824
  throw error;
@@ -5936,23 +5834,23 @@ var OpencodeAdapter = class {
5936
5834
  const paths = [];
5937
5835
  let step = 0;
5938
5836
  const messages = await Promise.all((await listJsonFiles(ref.path)).map(async (file) => {
5939
- const path = join10(ref.path, file);
5837
+ const path = join9(ref.path, file);
5940
5838
  paths.push(path);
5941
5839
  return readJsonFile(path);
5942
5840
  }));
5943
5841
  messages.sort((a, b) => (a.time?.created ?? 0) - (b.time?.created ?? 0));
5944
5842
  for (const message of messages) {
5945
5843
  const mid = message.id ?? `m${step}`;
5946
- const directory = join10(this.storage(), "part", mid);
5844
+ const directory = join9(this.storage(), "part", mid);
5947
5845
  let files = [];
5948
5846
  try {
5949
5847
  files = await listJsonFiles(directory);
5950
5848
  } catch (error) {
5951
5849
  if (!isMissingJsonSource(error)) throw error;
5952
5850
  }
5953
- paths.push(...files.map((file) => join10(directory, file)));
5954
- const parts = await Promise.all(files.map((file) => readJsonFile(join10(directory, file))));
5955
- if (message.role !== "user" || textOf6(parts)) step += 1;
5851
+ paths.push(...files.map((file) => join9(directory, file)));
5852
+ const parts = await Promise.all(files.map((file) => readJsonFile(join9(directory, file))));
5853
+ if (message.role !== "user" || textOf5(parts)) step += 1;
5956
5854
  step += parts.filter((part) => part.type === "tool" && part.tool).length;
5957
5855
  }
5958
5856
  return paths.sort();
@@ -5960,11 +5858,11 @@ var OpencodeAdapter = class {
5960
5858
  async parse(ref, options = {}) {
5961
5859
  const traceId = ref.sessionId;
5962
5860
  const rootId = `root:${traceId}`;
5963
- const partRoot = join10(this.storage(), "part");
5861
+ const partRoot = join9(this.storage(), "part");
5964
5862
  const msgFiles = await listJsonFiles(ref.path);
5965
5863
  const messages = [];
5966
5864
  for (const f of msgFiles) {
5967
- messages.push(await readJsonFile(join10(ref.path, f), options));
5865
+ messages.push(await readJsonFile(join9(ref.path, f), options));
5968
5866
  }
5969
5867
  messages.sort((a, b) => (a.time?.created ?? 0) - (b.time?.created ?? 0));
5970
5868
  const spans = [
@@ -5976,15 +5874,15 @@ var OpencodeAdapter = class {
5976
5874
  kind: "AGENT",
5977
5875
  startTime: isoOf(messages[0]?.time?.created),
5978
5876
  endTime: isoOf(messages.at(-1)?.time?.completed ?? messages.at(-1)?.time?.created),
5979
- service: SERVICE7,
5980
- agent: SERVICE7
5877
+ service: SERVICE6,
5878
+ agent: SERVICE6
5981
5879
  })
5982
5880
  ];
5983
5881
  let step = 0;
5984
5882
  for (const msg of messages) {
5985
5883
  const mid = msg.id ?? `m${step}`;
5986
5884
  const llmId = `llm:${mid}`;
5987
- const pdir = join10(partRoot, mid);
5885
+ const pdir = join9(partRoot, mid);
5988
5886
  const parts = [];
5989
5887
  let partFiles = [];
5990
5888
  try {
@@ -5993,9 +5891,9 @@ var OpencodeAdapter = class {
5993
5891
  if (!isMissingJsonSource(error)) throw error;
5994
5892
  }
5995
5893
  for (const pf of partFiles) {
5996
- parts.push(await readJsonFile(join10(pdir, pf), options));
5894
+ parts.push(await readJsonFile(join9(pdir, pf), options));
5997
5895
  }
5998
- const turnText2 = textOf6(parts);
5896
+ const turnText2 = textOf5(parts);
5999
5897
  const isUser = msg.role === "user";
6000
5898
  if (isUser) {
6001
5899
  if (turnText2) {
@@ -6005,8 +5903,8 @@ var OpencodeAdapter = class {
6005
5903
  spanId: `${llmId}:user`,
6006
5904
  parentSpanId: rootId,
6007
5905
  startTime: isoOf(msg.time?.created),
6008
- service: SERVICE7,
6009
- agent: SERVICE7,
5906
+ service: SERVICE6,
5907
+ agent: SERVICE6,
6010
5908
  step,
6011
5909
  content: turnText2,
6012
5910
  contentSource: parts.filter((part) => part.type === "text").flatMap((part) => {
@@ -6027,8 +5925,8 @@ var OpencodeAdapter = class {
6027
5925
  kind: "LLM",
6028
5926
  startTime: isoOf(msg.time?.created),
6029
5927
  endTime: isoOf(msg.time?.completed ?? msg.time?.created),
6030
- service: SERVICE7,
6031
- agent: SERVICE7,
5928
+ service: SERVICE6,
5929
+ agent: SERVICE6,
6032
5930
  model: msg.modelID ?? null,
6033
5931
  inputTokens: msg.tokens?.input ?? null,
6034
5932
  outputTokens: msg.tokens?.output ?? null,
@@ -6059,8 +5957,8 @@ var OpencodeAdapter = class {
6059
5957
  endTime: isoOf(msg.time?.completed ?? msg.time?.created),
6060
5958
  status: err ? "ERROR" : "OK",
6061
5959
  statusMessage: err ? (part.state?.error ?? "").slice(0, 500) : void 0,
6062
- service: SERVICE7,
6063
- agent: SERVICE7,
5960
+ service: SERVICE6,
5961
+ agent: SERVICE6,
6064
5962
  tool: part.tool,
6065
5963
  step,
6066
5964
  extra: toolIoAttributes({
@@ -6079,9 +5977,9 @@ var OpencodeAdapter = class {
6079
5977
  };
6080
5978
 
6081
5979
  // src/adapters/harness-sessions.ts
6082
- import { homedir as homedir9 } from "os";
6083
- import { open, stat as stat9 } from "fs/promises";
6084
- import { join as join11 } from "path";
5980
+ import { homedir as homedir8 } from "os";
5981
+ import { open, stat as stat8 } from "fs/promises";
5982
+ import { join as join10 } from "path";
6085
5983
  import {
6086
5984
  claudeCodeRefForFile,
6087
5985
  codexRefForFile,
@@ -6105,7 +6003,7 @@ function nativeRef(harness, ref) {
6105
6003
  case "pi":
6106
6004
  return selected(piRefForFile(ref.path));
6107
6005
  case "kimi-code":
6108
- return selected(kimiRefForFile(ref.path.endsWith("wire.jsonl") ? ref.path : join11(ref.path, "wire.jsonl")));
6006
+ return selected(kimiRefForFile(ref.path.endsWith("wire.jsonl") ? ref.path : join10(ref.path, "wire.jsonl")));
6109
6007
  case "factory-droids":
6110
6008
  return selected(factoryRefForFile(ref.path));
6111
6009
  case "opencode":
@@ -6316,7 +6214,7 @@ var HarnessSessionsAdapter = class {
6316
6214
  scopedAdapter;
6317
6215
  async locate(opts = {}) {
6318
6216
  if (this.scopedAdapter) return this.scopedAdapter.locate(opts);
6319
- const found = await this.reader.locate(homedir9(), { sinceMs: opts.sinceMs, cwd: opts.cwd });
6217
+ const found = await this.reader.locate(homedir8(), { sinceMs: opts.sinceMs, cwd: opts.cwd });
6320
6218
  const refs = found.filter((native) => this.nativeHarness !== "claude-code" || native.parentNativeSessionId === null).map((native) => {
6321
6219
  const ref = tracesRef(native, this.harness);
6322
6220
  this.refs.set(`${ref.sessionId}\0${ref.path}`, native);
@@ -6332,7 +6230,7 @@ var HarnessSessionsAdapter = class {
6332
6230
  if (this.scopedAdapter instanceof ClaudeAdapter) {
6333
6231
  return (await this.scopedAdapter.locate(opts)).filter((ref) => ref.sessionId === sessionId);
6334
6232
  }
6335
- const refs = await this.reader.locate(homedir9(), { nativeSessionId: sessionId, sinceMs: opts.sinceMs, cwd: opts.cwd });
6233
+ const refs = await this.reader.locate(homedir8(), { nativeSessionId: sessionId, sinceMs: opts.sinceMs, cwd: opts.cwd });
6336
6234
  const selected = refs.map((native) => {
6337
6235
  const ref = tracesRef(native, this.harness);
6338
6236
  this.refs.set(`${ref.sessionId}\0${ref.path}`, native);
@@ -6350,7 +6248,7 @@ var HarnessSessionsAdapter = class {
6350
6248
  const settings = ref.path.replace(/\.jsonl$/u, ".settings.json");
6351
6249
  if (paths.includes(settings)) return paths;
6352
6250
  try {
6353
- await stat9(settings);
6251
+ await stat8(settings);
6354
6252
  return [...paths, settings];
6355
6253
  } catch (error) {
6356
6254
  if (error.code === "ENOENT") return paths;
@@ -6497,11 +6395,11 @@ var SHARED_SESSION_ADAPTERS = [
6497
6395
  ];
6498
6396
 
6499
6397
  // src/adapters/qwen.ts
6500
- import { readdir as readdir11, stat as stat10 } from "fs/promises";
6501
- import { homedir as homedir10 } from "os";
6502
- import { basename as basename7, join as join12 } from "path";
6503
- var SERVICE8 = "qwen";
6504
- function textOf7(parts) {
6398
+ import { readdir as readdir10, stat as stat9 } from "fs/promises";
6399
+ import { homedir as homedir9 } from "os";
6400
+ import { basename as basename6, join as join11 } from "path";
6401
+ var SERVICE7 = "qwen";
6402
+ function textOf6(parts) {
6505
6403
  if (!parts) return "";
6506
6404
  return parts.filter((p) => typeof p.text === "string").map((p) => p.text).join("");
6507
6405
  }
@@ -6509,23 +6407,23 @@ var QwenAdapter = class {
6509
6407
  harness = "qwen";
6510
6408
  aliases = ["qwen-code"];
6511
6409
  root() {
6512
- return join12(homedir10(), ".qwen", "projects");
6410
+ return join11(homedir9(), ".qwen", "projects");
6513
6411
  }
6514
6412
  async locate(opts = {}) {
6515
6413
  const root = this.root();
6516
6414
  let projectDirs;
6517
6415
  try {
6518
- projectDirs = await readdir11(root);
6416
+ projectDirs = await readdir10(root);
6519
6417
  } catch (error) {
6520
6418
  if (isMissingPathError(error)) return [];
6521
6419
  throw error;
6522
6420
  }
6523
6421
  const refs = [];
6524
6422
  for (const pd of projectDirs) {
6525
- const chatsDir = join12(root, pd, "chats");
6423
+ const chatsDir = join11(root, pd, "chats");
6526
6424
  let files;
6527
6425
  try {
6528
- files = await readdir11(chatsDir);
6426
+ files = await readdir10(chatsDir);
6529
6427
  } catch (error) {
6530
6428
  if (isMissingPathError(error)) continue;
6531
6429
  throw error;
@@ -6533,16 +6431,16 @@ var QwenAdapter = class {
6533
6431
  if (opts.cwd) continue;
6534
6432
  for (const f of files) {
6535
6433
  if (!f.endsWith(".jsonl")) continue;
6536
- const path = join12(chatsDir, f);
6434
+ const path = join11(chatsDir, f);
6537
6435
  let st;
6538
6436
  try {
6539
- st = await stat10(path);
6437
+ st = await stat9(path);
6540
6438
  } catch (error) {
6541
6439
  if (isMissingPathError(error)) continue;
6542
6440
  throw error;
6543
6441
  }
6544
6442
  if (opts.sinceMs && st.mtimeMs < opts.sinceMs) continue;
6545
- refs.push({ harness: this.harness, sessionId: basename7(f, ".jsonl"), path, cwd: null, mtimeMs: st.mtimeMs });
6443
+ refs.push({ harness: this.harness, sessionId: basename6(f, ".jsonl"), path, cwd: null, mtimeMs: st.mtimeMs });
6546
6444
  }
6547
6445
  }
6548
6446
  return refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
@@ -6576,13 +6474,13 @@ var QwenAdapter = class {
6576
6474
  name: "llm.turn",
6577
6475
  kind: "LLM",
6578
6476
  startTime: ts,
6579
- service: SERVICE8,
6580
- agent: SERVICE8,
6477
+ service: SERVICE7,
6478
+ agent: SERVICE7,
6581
6479
  model: r.model ?? null,
6582
6480
  inputTokens: r.usageMetadata?.promptTokenCount ?? null,
6583
6481
  outputTokens: r.usageMetadata?.candidatesTokenCount ?? null,
6584
6482
  step,
6585
- content: capText(textOf7(r.message?.parts)) || null,
6483
+ content: capText(textOf6(r.message?.parts)) || null,
6586
6484
  contentSource: textSources(r.message, "parts")
6587
6485
  })
6588
6486
  );
@@ -6597,8 +6495,8 @@ var QwenAdapter = class {
6597
6495
  name: `tool.${name}`,
6598
6496
  kind: "TOOL",
6599
6497
  startTime: ts,
6600
- service: SERVICE8,
6601
- agent: SERVICE8,
6498
+ service: SERVICE7,
6499
+ agent: SERVICE7,
6602
6500
  tool: name,
6603
6501
  step,
6604
6502
  extra: toolIoAttributes({ input: p.functionCall.args, inputSource: sourceOf(p.functionCall, "args") })
@@ -6610,7 +6508,7 @@ var QwenAdapter = class {
6610
6508
  step += 1;
6611
6509
  }
6612
6510
  } else if (r.type === "user") {
6613
- const prompt = capText(textOf7(r.message?.parts));
6511
+ const prompt = capText(textOf6(r.message?.parts));
6614
6512
  if (prompt) {
6615
6513
  spans.push(
6616
6514
  userPromptSpan({
@@ -6618,8 +6516,8 @@ var QwenAdapter = class {
6618
6516
  spanId: `user:${r.uuid ?? step}`,
6619
6517
  parentSpanId: sourceRootId,
6620
6518
  startTime: ts,
6621
- service: SERVICE8,
6622
- agent: SERVICE8,
6519
+ service: SERVICE7,
6520
+ agent: SERVICE7,
6623
6521
  step,
6624
6522
  content: prompt,
6625
6523
  contentSource: textSources(r.message, "parts")
@@ -6655,8 +6553,8 @@ var QwenAdapter = class {
6655
6553
  kind: "AGENT",
6656
6554
  startTime: firstTimestamp ?? (/* @__PURE__ */ new Date(0)).toISOString(),
6657
6555
  endTime: lastTimestamp,
6658
- service: SERVICE8,
6659
- agent: SERVICE8
6556
+ service: SERVICE7,
6557
+ agent: SERVICE7
6660
6558
  });
6661
6559
  return [root, ...spans];
6662
6560
  }
@@ -6669,8 +6567,7 @@ var ADAPTERS = [
6669
6567
  new GeminiAdapter(),
6670
6568
  new QwenAdapter(),
6671
6569
  new AmpAdapter(),
6672
- new CopilotAdapter(),
6673
- new ForgeAdapter()
6570
+ new CopilotAdapter()
6674
6571
  ];
6675
6572
  var BY_NAME = /* @__PURE__ */ new Map();
6676
6573
  for (const a of ADAPTERS) {
@@ -6697,8 +6594,8 @@ function selectAdapters(opts) {
6697
6594
  }
6698
6595
 
6699
6596
  // src/repo.ts
6700
- import { realpath as realpath2, stat as stat11 } from "fs/promises";
6701
- import { dirname as dirname4, isAbsolute as isAbsolute3, join as join13, normalize, parse as parsePath } from "path";
6597
+ import { realpath as realpath2, stat as stat10 } from "fs/promises";
6598
+ import { dirname as dirname4, isAbsolute as isAbsolute3, join as join12, normalize, parse as parsePath } from "path";
6702
6599
  function normalizeRemote(url) {
6703
6600
  const raw = url.trim();
6704
6601
  if (!raw) return null;
@@ -6722,7 +6619,7 @@ function normalizeRemote(url) {
6722
6619
  return null;
6723
6620
  }
6724
6621
  async function readGit(cwd) {
6725
- await stat11(`${cwd}/.git`);
6622
+ await stat10(`${cwd}/.git`);
6726
6623
  const { execFile } = await import("child_process");
6727
6624
  const { promisify } = await import("util");
6728
6625
  const run = promisify(execFile);
@@ -6815,7 +6712,7 @@ function cwdMatchesSelection(cwd, selections) {
6815
6712
  }
6816
6713
  async function pathStat(path) {
6817
6714
  try {
6818
- return await stat11(path);
6715
+ return await stat10(path);
6819
6716
  } catch {
6820
6717
  return null;
6821
6718
  }
@@ -6839,7 +6736,7 @@ async function nearestExistingDir(path) {
6839
6736
  async function findGitRoot(path) {
6840
6737
  let cur = await nearestExistingDir(path);
6841
6738
  while (cur) {
6842
- if (await pathStat(join13(cur, ".git"))) return cur;
6739
+ if (await pathStat(join12(cur, ".git"))) return cur;
6843
6740
  const parent = dirname4(cur);
6844
6741
  if (parent === cur) return null;
6845
6742
  cur = parent;
@@ -6857,7 +6754,7 @@ async function repairDashedPath(cwd) {
6857
6754
  while (index < parts.length) {
6858
6755
  const nextPart = parts[index];
6859
6756
  if (!nextPart) break;
6860
- const exact = join13(current, nextPart);
6757
+ const exact = join12(current, nextPart);
6861
6758
  if (!await directoryExists(exact)) break;
6862
6759
  current = exact;
6863
6760
  index += 1;
@@ -6867,7 +6764,7 @@ async function repairDashedPath(cwd) {
6867
6764
  let consumed = 0;
6868
6765
  for (let n = parts.length - index; n >= 1; n -= 1) {
6869
6766
  const segment = parts.slice(index, index + n).join("-");
6870
- const candidate = join13(current, segment);
6767
+ const candidate = join12(current, segment);
6871
6768
  if (await directoryExists(candidate)) {
6872
6769
  match = candidate;
6873
6770
  consumed = n;
@@ -6951,7 +6848,7 @@ function extractAbsolutePaths(spans) {
6951
6848
  async function resolveRepoAttrs(cwd) {
6952
6849
  if (!cwd) return {};
6953
6850
  const attrs = { [ATTR.CWD]: cwd };
6954
- const basename16 = (() => {
6851
+ const basename15 = (() => {
6955
6852
  const trimmed = cwd.replace(/\/+$/g, "");
6956
6853
  const idx = trimmed.lastIndexOf("/");
6957
6854
  const name = idx === -1 ? trimmed : trimmed.slice(idx + 1);
@@ -6973,7 +6870,7 @@ async function resolveRepoAttrs(cwd) {
6973
6870
  if (commit) attrs[ATTR.GIT_COMMIT] = commit;
6974
6871
  } catch {
6975
6872
  }
6976
- attrs[ATTR.SUBJECT_KEY] = basename16;
6873
+ attrs[ATTR.SUBJECT_KEY] = basename15;
6977
6874
  return attrs;
6978
6875
  }
6979
6876
  async function repoCandidateForPath(path) {
@@ -7283,7 +7180,7 @@ function describeSessionRelationship(ref, spans) {
7283
7180
  // src/evidence.ts
7284
7181
  import { mkdtemp, writeFile as writeFile2 } from "fs/promises";
7285
7182
  import { tmpdir as tmpdir2 } from "os";
7286
- import { join as join14 } from "path";
7183
+ import { join as join13 } from "path";
7287
7184
  import {
7288
7185
  OPENINFERENCE_SPAN_KIND as OPENINFERENCE_SPAN_KIND3,
7289
7186
  TOOL_NAME as TOOL_NAME4
@@ -7413,14 +7310,14 @@ function serializePolicyEvidence(records) {
7413
7310
  `;
7414
7311
  }
7415
7312
  async function writePolicyEvidenceFile(records, outPath) {
7416
- const path = outPath ?? join14(await mkdtemp(join14(tmpdir2(), "traces-evidence-")), "policy-evidence.jsonl");
7313
+ const path = outPath ?? join13(await mkdtemp(join13(tmpdir2(), "traces-evidence-")), "policy-evidence.jsonl");
7417
7314
  await writeFile2(path, serializePolicyEvidence(records), "utf8");
7418
7315
  return path;
7419
7316
  }
7420
7317
 
7421
7318
  // src/adoption.ts
7422
7319
  import { readFile as readFile4 } from "fs/promises";
7423
- import { join as join15 } from "path";
7320
+ import { join as join14 } from "path";
7424
7321
  function toolName2(s) {
7425
7322
  const n = s.attributes["tool.name"];
7426
7323
  if (typeof n === "string") return n;
@@ -7540,7 +7437,7 @@ async function readLoopRuns(cwds, sessionIds) {
7540
7437
  seenCwds.add(cwd);
7541
7438
  const firstSourceByRun = /* @__PURE__ */ new Map();
7542
7439
  for (const artifactDir of [".agent", ".evolve"]) {
7543
- const path = join15(cwd, artifactDir, "skill-runs.jsonl");
7440
+ const path = join14(cwd, artifactDir, "skill-runs.jsonl");
7544
7441
  let raw;
7545
7442
  try {
7546
7443
  raw = await readFile4(path, "utf8");
@@ -8177,7 +8074,7 @@ var COMMAND_PREFIXES = /* @__PURE__ */ new Set([
8177
8074
  var ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
8178
8075
  var MAX_SHELL_DEPTH = 4;
8179
8076
  var MAX_WORDS = 2e4;
8180
- function basename8(word) {
8077
+ function basename7(word) {
8181
8078
  const cut = word.lastIndexOf("/");
8182
8079
  return cut === -1 ? word : word.slice(cut + 1);
8183
8080
  }
@@ -8276,7 +8173,7 @@ var ShellScanner = class {
8276
8173
  let start = 0;
8277
8174
  while (start < words.length) {
8278
8175
  const word = words[start];
8279
- if (ASSIGNMENT.test(word) || COMMAND_PREFIXES.has(basename8(word))) start += 1;
8176
+ if (ASSIGNMENT.test(word) || COMMAND_PREFIXES.has(basename7(word))) start += 1;
8280
8177
  else break;
8281
8178
  }
8282
8179
  return start === 0 || start >= words.length ? words : words.slice(start);
@@ -8417,7 +8314,7 @@ function shellCommands(script, depth = 0) {
8417
8314
  const out = [];
8418
8315
  for (const words of commands) {
8419
8316
  out.push(words);
8420
- const name = basename8(words[0] ?? "");
8317
+ const name = basename7(words[0] ?? "");
8421
8318
  if (!SHELLS.has(name) || depth >= MAX_SHELL_DEPTH) continue;
8422
8319
  for (let index = 1; index < words.length; index += 1) {
8423
8320
  const word = words[index];
@@ -8445,7 +8342,7 @@ function commandTextFromInput(input) {
8445
8342
  if (!Array.isArray(value) || value.length === 0) return void 0;
8446
8343
  const words = value.filter((entry) => typeof entry === "string");
8447
8344
  if (words.length !== value.length) return void 0;
8448
- const head = basename8(words[0] ?? "");
8345
+ const head = basename7(words[0] ?? "");
8449
8346
  if (SHELLS.has(head)) {
8450
8347
  const flag = words.findIndex((word, position) => position > 0 && /^-[a-z]*c$/.test(word));
8451
8348
  if (flag !== -1 && words[flag + 1] !== void 0) return words[flag + 1];
@@ -8507,7 +8404,7 @@ function stringAttribute2(span2, key) {
8507
8404
  const value = span2.attributes[key];
8508
8405
  return typeof value === "string" ? value : null;
8509
8406
  }
8510
- function basename9(word) {
8407
+ function basename8(word) {
8511
8408
  const cut = word.lastIndexOf("/");
8512
8409
  return cut === -1 ? word : word.slice(cut + 1);
8513
8410
  }
@@ -8590,7 +8487,7 @@ function numbersInLine(line) {
8590
8487
  function inferHeadBranch(commands, upTo, output) {
8591
8488
  for (let index = upTo - 1; index >= 0; index -= 1) {
8592
8489
  const words = commands[index];
8593
- if (basename9(words[0] ?? "") !== "git" || words.length < 2) continue;
8490
+ if (basename8(words[0] ?? "") !== "git" || words.length < 2) continue;
8594
8491
  const sub = words[1];
8595
8492
  const rest = words.slice(2);
8596
8493
  if (sub === "push") {
@@ -8665,7 +8562,7 @@ function eventsFromRecord(record2, recordIndex) {
8665
8562
  let createIndex = 0;
8666
8563
  for (let index = 0; index < commands.length; index += 1) {
8667
8564
  const words = commands[index];
8668
- if (words.length < 3 || !GH_NAMES.has(basename9(words[0])) || words[1] !== "pr") continue;
8565
+ if (words.length < 3 || !GH_NAMES.has(basename8(words[0])) || words[1] !== "pr") continue;
8669
8566
  const action = words[2];
8670
8567
  if (action === "create") {
8671
8568
  const printedNumber = printed[createIndex] ?? null;
@@ -9634,17 +9531,17 @@ import { isUtf8 as isUtf82 } from "buffer";
9634
9531
  import { createHash as createHash10 } from "crypto";
9635
9532
  import { constants } from "fs";
9636
9533
  import { lstat as lstat2, open as open2, realpath as realpath3 } from "fs/promises";
9637
- import { dirname as dirname8, isAbsolute as isAbsolute4, join as join19, relative as relative5, resolve as resolve6, sep as sep2 } from "path";
9534
+ import { dirname as dirname8, isAbsolute as isAbsolute4, join as join18, relative as relative5, resolve as resolve6, sep as sep2 } from "path";
9638
9535
 
9639
9536
  // src/bundle.ts
9640
9537
  import { createHash as createHash9 } from "crypto";
9641
- import { copyFile, cp, lstat, mkdir as mkdir2, readdir as readdir14, readFile as readFile7, stat as stat13, writeFile as writeFile5 } from "fs/promises";
9642
- import { dirname as dirname7, join as join18, relative as relative4, resolve as resolve5, sep } from "path";
9538
+ import { copyFile, cp, lstat, mkdir as mkdir2, readdir as readdir13, readFile as readFile7, stat as stat12, writeFile as writeFile5 } from "fs/promises";
9539
+ import { dirname as dirname7, join as join17, relative as relative4, resolve as resolve5, sep } from "path";
9643
9540
 
9644
9541
  // src/improvement.ts
9645
9542
  import { access, mkdir, mkdtemp as mkdtemp2, writeFile as writeFile3 } from "fs/promises";
9646
9543
  import { tmpdir as tmpdir3 } from "os";
9647
- import { dirname as dirname5, join as join16, resolve as resolve4 } from "path";
9544
+ import { dirname as dirname5, join as join15, resolve as resolve4 } from "path";
9648
9545
  import { pathToFileURL } from "url";
9649
9546
  import {
9650
9547
  AnalystRegistry,
@@ -10151,7 +10048,7 @@ function formatFindingRejections(reasons) {
10151
10048
 
10152
10049
  // src/external.ts
10153
10050
  import { spawn } from "child_process";
10154
- import { readdir as readdir12, readFile as readFile5 } from "fs/promises";
10051
+ import { readdir as readdir11, readFile as readFile5 } from "fs/promises";
10155
10052
  function forceKill(child) {
10156
10053
  try {
10157
10054
  child.kill("SIGKILL");
@@ -10256,14 +10153,14 @@ function readProcessTableWithPs() {
10256
10153
  });
10257
10154
  }
10258
10155
  async function readLinuxProcProcessTable() {
10259
- const entries = await readdir12("/proc", { withFileTypes: true });
10156
+ const entries = await readdir11("/proc", { withFileTypes: true });
10260
10157
  const rows = await Promise.all(
10261
10158
  entries.filter((entry) => entry.isDirectory() && /^\d+$/.test(entry.name)).map(async (entry) => {
10262
10159
  try {
10263
- const stat19 = await readFile5(`/proc/${entry.name}/stat`, "utf8");
10264
- const commandEnd = stat19.lastIndexOf(")");
10160
+ const stat18 = await readFile5(`/proc/${entry.name}/stat`, "utf8");
10161
+ const commandEnd = stat18.lastIndexOf(")");
10265
10162
  if (commandEnd < 0) return void 0;
10266
- const fields = stat19.slice(commandEnd + 1).trim().split(/\s+/);
10163
+ const fields = stat18.slice(commandEnd + 1).trim().split(/\s+/);
10267
10164
  const pid = Number(entry.name);
10268
10165
  const parentPid = Number(fields[1]);
10269
10166
  if (!Number.isSafeInteger(pid) || pid < 1 || !Number.isSafeInteger(parentPid) || parentPid < 0) {
@@ -11938,13 +11835,13 @@ async function runTraceStoreInvestigation(opts) {
11938
11835
  };
11939
11836
  }
11940
11837
  async function writeTraceImprovementArtifacts(result, outDir) {
11941
- const directory = outDir ? resolve4(outDir) : await mkdtemp2(join16(tmpdir3(), "traces-improvement-"));
11838
+ const directory = outDir ? resolve4(outDir) : await mkdtemp2(join15(tmpdir3(), "traces-improvement-"));
11942
11839
  await mkdir(directory, { recursive: true });
11943
11840
  const paths = {
11944
11841
  directory,
11945
- result: join16(directory, "result.json"),
11946
- evidence: join16(directory, "evidence.jsonl"),
11947
- report: join16(directory, "report.md"),
11842
+ result: join15(directory, "result.json"),
11843
+ evidence: join15(directory, "evidence.jsonl"),
11844
+ report: join15(directory, "report.md"),
11948
11845
  traces: result.otlpPath
11949
11846
  };
11950
11847
  const { report, ...machineResult } = result;
@@ -11957,11 +11854,11 @@ async function writeTraceImprovementArtifacts(result, outDir) {
11957
11854
  }
11958
11855
  async function runTraceImprovement(opts) {
11959
11856
  if (opts.sourceBundle && opts.outDir) await assertOutsideSourceBundle(opts.sourceBundle.path, opts.outDir);
11960
- const directory = opts.outDir ? resolve4(opts.outDir) : await mkdtemp2(join16(tmpdir3(), "traces-improvement-"));
11857
+ const directory = opts.outDir ? resolve4(opts.outDir) : await mkdtemp2(join15(tmpdir3(), "traces-improvement-"));
11961
11858
  await mkdir(directory, { recursive: true });
11962
11859
  const investigation = await runTraceInvestigation({
11963
11860
  ...opts,
11964
- otlpOutPath: opts.otlpOutPath ?? join16(directory, "traces.otlp.jsonl")
11861
+ otlpOutPath: opts.otlpOutPath ?? join15(directory, "traces.otlp.jsonl")
11965
11862
  });
11966
11863
  const result = {
11967
11864
  ...investigation,
@@ -11978,9 +11875,9 @@ async function saveReport(path, report) {
11978
11875
  }
11979
11876
 
11980
11877
  // src/session-index.ts
11981
- import { mkdtemp as mkdtemp3, readdir as readdir13, readFile as readFile6, stat as stat12, writeFile as writeFile4 } from "fs/promises";
11878
+ import { mkdtemp as mkdtemp3, readdir as readdir12, readFile as readFile6, stat as stat11, writeFile as writeFile4 } from "fs/promises";
11982
11879
  import { tmpdir as tmpdir4 } from "os";
11983
- import { dirname as dirname6, join as join17 } from "path";
11880
+ import { dirname as dirname6, join as join16 } from "path";
11984
11881
  function indexRow(record2) {
11985
11882
  return {
11986
11883
  session: record2.session,
@@ -12035,7 +11932,7 @@ function buildSessionIndex(records, opts = {}) {
12035
11932
  }
12036
11933
  async function pathStat2(path) {
12037
11934
  try {
12038
- return await stat12(path);
11935
+ return await stat11(path);
12039
11936
  } catch {
12040
11937
  return null;
12041
11938
  }
@@ -12053,7 +11950,7 @@ async function findContextRoot(cwd) {
12053
11950
  if (!s) return null;
12054
11951
  if (!s.isDirectory()) current = dirname6(current);
12055
11952
  for (; ; ) {
12056
- if (await pathStat2(join17(current, ".git")) || await dirExists(join17(current, ".evolve")) || await fileExists(join17(current, "AGENTS.md")) || await fileExists(join17(current, "CLAUDE.md"))) {
11953
+ if (await pathStat2(join16(current, ".git")) || await dirExists(join16(current, ".evolve")) || await fileExists(join16(current, "AGENTS.md")) || await fileExists(join16(current, "CLAUDE.md"))) {
12057
11954
  return current;
12058
11955
  }
12059
11956
  const parent = dirname6(current);
@@ -12115,13 +12012,13 @@ async function walkMarkdown(root, kind, maxFiles = 100) {
12115
12012
  if (out.length >= maxFiles) return;
12116
12013
  let entries;
12117
12014
  try {
12118
- entries = await readdir13(dir, { withFileTypes: true });
12015
+ entries = await readdir12(dir, { withFileTypes: true });
12119
12016
  } catch {
12120
12017
  return;
12121
12018
  }
12122
12019
  for (const entry of entries) {
12123
12020
  if (out.length >= maxFiles) return;
12124
- const path = join17(dir, entry.name);
12021
+ const path = join16(dir, entry.name);
12125
12022
  if (entry.isDirectory()) {
12126
12023
  await walk(path);
12127
12024
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -12136,33 +12033,33 @@ async function walkMarkdown(root, kind, maxFiles = 100) {
12136
12033
  async function collectContextRoot(root) {
12137
12034
  const files = [];
12138
12035
  for (const name of ["AGENTS.md", "CLAUDE.md", "GEMINI.md"]) {
12139
- const summary = await summarizeFile(join17(root, name), "instruction-doc");
12036
+ const summary = await summarizeFile(join16(root, name), "instruction-doc");
12140
12037
  if (summary) files.push(summary);
12141
12038
  }
12142
- const evolve = join17(root, ".evolve");
12039
+ const evolve = join16(root, ".evolve");
12143
12040
  for (const name of ["skill-runs.jsonl", "governor.jsonl", "experiments.jsonl"]) {
12144
- const summary = await summarizeFile(join17(evolve, name), "evolve-jsonl");
12041
+ const summary = await summarizeFile(join16(evolve, name), "evolve-jsonl");
12145
12042
  if (summary) files.push(summary);
12146
12043
  }
12147
12044
  for (const name of ["scorecard.json", "current.json"]) {
12148
- const summary = await summarizeFile(join17(evolve, name), "evolve-json");
12045
+ const summary = await summarizeFile(join16(evolve, name), "evolve-json");
12149
12046
  if (summary) files.push(summary);
12150
12047
  }
12151
- files.push(...await walkMarkdown(join17(evolve, "reflections"), "reflection"));
12152
- files.push(...await walkMarkdown(join17(evolve, "handoffs"), "handoff"));
12048
+ files.push(...await walkMarkdown(join16(evolve, "reflections"), "reflection"));
12049
+ files.push(...await walkMarkdown(join16(evolve, "handoffs"), "handoff"));
12153
12050
  for (const name of await listEvolveRootFiles(evolve)) {
12154
12051
  if (/^handoff-.*\.md$/.test(name)) {
12155
- const summary = await summarizeFile(join17(evolve, name), "handoff");
12052
+ const summary = await summarizeFile(join16(evolve, name), "handoff");
12156
12053
  if (summary) files.push(summary);
12157
12054
  }
12158
12055
  }
12159
- const progress2 = await summarizeFile(join17(evolve, "progress.md"), "other");
12056
+ const progress2 = await summarizeFile(join16(evolve, "progress.md"), "other");
12160
12057
  if (progress2) files.push(progress2);
12161
12058
  return { root, files: files.sort((a, b) => a.path.localeCompare(b.path)) };
12162
12059
  }
12163
12060
  async function listEvolveRootFiles(evolve) {
12164
12061
  try {
12165
- const entries = await readdir13(evolve, { withFileTypes: true });
12062
+ const entries = await readdir12(evolve, { withFileTypes: true });
12166
12063
  return entries.filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
12167
12064
  } catch {
12168
12065
  return [];
@@ -12211,7 +12108,7 @@ function serializeSessionIndex(index) {
12211
12108
  `;
12212
12109
  }
12213
12110
  async function writeSessionIndexFile(index, outPath) {
12214
- const path = outPath ?? join17(await mkdtemp3(join17(tmpdir4(), "traces-index-")), "session-index.json");
12111
+ const path = outPath ?? join16(await mkdtemp3(join16(tmpdir4(), "traces-index-")), "session-index.json");
12215
12112
  await writeFile4(path, serializeSessionIndex(index), "utf8");
12216
12113
  return path;
12217
12114
  }
@@ -12705,7 +12602,7 @@ function bundlePath(...parts) {
12705
12602
  }
12706
12603
  async function statOrNull(path) {
12707
12604
  try {
12708
- return await stat13(path);
12605
+ return await stat12(path);
12709
12606
  } catch (error) {
12710
12607
  if (isMissingPathError(error)) return null;
12711
12608
  if (error.code === "ENOTDIR") return null;
@@ -12754,8 +12651,8 @@ async function listSessionBundleFiles(root) {
12754
12651
  const pending = [resolve5(root)];
12755
12652
  while (pending.length > 0) {
12756
12653
  const dir = pending.pop();
12757
- for (const entry of await readdir14(dir, { withFileTypes: true })) {
12758
- const path = join18(dir, entry.name);
12654
+ for (const entry of await readdir13(dir, { withFileTypes: true })) {
12655
+ const path = join17(dir, entry.name);
12759
12656
  if (entry.isDirectory()) pending.push(path);
12760
12657
  else if (entry.isFile()) out.push(relative4(resolve5(root), path).split(sep).join("/"));
12761
12658
  }
@@ -12763,14 +12660,14 @@ async function listSessionBundleFiles(root) {
12763
12660
  return out.sort();
12764
12661
  }
12765
12662
  async function sliceLedgerJsonl(ctx, name) {
12766
- const source = join18(ctx.evolveDir, name);
12663
+ const source = join17(ctx.evolveDir, name);
12767
12664
  const s = await statOrNull(source);
12768
12665
  if (!s?.isFile()) {
12769
12666
  ctx.absent.push({ path: bundlePath("ledger", name), reason: `no ${name} at ${source}` });
12770
12667
  return;
12771
12668
  }
12772
12669
  const text2 = await readFile7(source, "utf8");
12773
- const target = join18(ctx.ledgerDir, name);
12670
+ const target = join17(ctx.ledgerDir, name);
12774
12671
  if (ctx.windowStartMs === null || ctx.windowEndMs === null) {
12775
12672
  await writeFile5(target, text2, "utf8");
12776
12673
  ctx.slices.push({ path: bundlePath("ledger", name), source, rule: "copied-whole" });
@@ -12789,19 +12686,19 @@ async function sliceLedgerJsonl(ctx, name) {
12789
12686
  });
12790
12687
  }
12791
12688
  async function copyLedgerWhole(ctx, name) {
12792
- const source = join18(ctx.evolveDir, name);
12689
+ const source = join17(ctx.evolveDir, name);
12793
12690
  const s = await statOrNull(source);
12794
12691
  if (!s?.isFile()) {
12795
12692
  ctx.absent.push({ path: bundlePath("ledger", name), reason: `no ${name} at ${source}` });
12796
12693
  return;
12797
12694
  }
12798
- await cp(source, join18(ctx.ledgerDir, name));
12695
+ await cp(source, join17(ctx.ledgerDir, name));
12799
12696
  ctx.slices.push({ path: bundlePath("ledger", name), source, rule: "copied-whole" });
12800
12697
  }
12801
12698
  async function copyLatestHandoff(ctx) {
12802
12699
  let names;
12803
12700
  try {
12804
- names = (await readdir14(ctx.evolveDir, { withFileTypes: true })).filter((entry) => entry.isFile() && /^handoff-.*\.md$/.test(entry.name)).map((entry) => entry.name).sort();
12701
+ names = (await readdir13(ctx.evolveDir, { withFileTypes: true })).filter((entry) => entry.isFile() && /^handoff-.*\.md$/.test(entry.name)).map((entry) => entry.name).sort();
12805
12702
  } catch {
12806
12703
  names = [];
12807
12704
  }
@@ -12813,12 +12710,12 @@ async function copyLatestHandoff(ctx) {
12813
12710
  });
12814
12711
  return;
12815
12712
  }
12816
- const source = join18(ctx.evolveDir, latest);
12817
- await cp(source, join18(ctx.ledgerDir, latest));
12713
+ const source = join17(ctx.evolveDir, latest);
12714
+ await cp(source, join17(ctx.ledgerDir, latest));
12818
12715
  ctx.slices.push({ path: bundlePath("ledger", latest), source, rule: "latest-by-name" });
12819
12716
  }
12820
12717
  async function copyWindowReflections(ctx) {
12821
- const reflectionsDir = join18(ctx.evolveDir, "reflections");
12718
+ const reflectionsDir = join17(ctx.evolveDir, "reflections");
12822
12719
  const s = await statOrNull(reflectionsDir);
12823
12720
  if (!s?.isDirectory()) {
12824
12721
  ctx.absent.push({
@@ -12827,7 +12724,7 @@ async function copyWindowReflections(ctx) {
12827
12724
  });
12828
12725
  return;
12829
12726
  }
12830
- const names = (await readdir14(reflectionsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort();
12727
+ const names = (await readdir13(reflectionsDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".md")).map((entry) => entry.name).sort();
12831
12728
  const windowed = ctx.windowStartMs === null || ctx.windowEndMs === null ? names : names.filter((name) => {
12832
12729
  const date = name.match(/(\d{4}-\d{2}-\d{2})/)?.[1];
12833
12730
  if (!date) return false;
@@ -12842,11 +12739,11 @@ async function copyWindowReflections(ctx) {
12842
12739
  });
12843
12740
  return;
12844
12741
  }
12845
- await mkdir2(join18(ctx.ledgerDir, "reflections"), { recursive: true });
12742
+ await mkdir2(join17(ctx.ledgerDir, "reflections"), { recursive: true });
12846
12743
  const rule = ctx.windowStartMs === null ? "copied-whole" : "session-window-dated-files";
12847
12744
  for (const name of windowed) {
12848
- const source = join18(reflectionsDir, name);
12849
- await cp(source, join18(ctx.ledgerDir, "reflections", name));
12745
+ const source = join17(reflectionsDir, name);
12746
+ await cp(source, join17(ctx.ledgerDir, "reflections", name));
12850
12747
  ctx.slices.push({ path: bundlePath("ledger", "reflections", name), source, rule });
12851
12748
  }
12852
12749
  }
@@ -12854,7 +12751,7 @@ async function assembleSessionBundle(opts) {
12854
12751
  const { adapter, ref } = opts;
12855
12752
  const generatedAt = opts.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
12856
12753
  try {
12857
- await stat13(ref.path);
12754
+ await stat12(ref.path);
12858
12755
  } catch (error) {
12859
12756
  if (isMissingPathError(error)) {
12860
12757
  throw new Error(`session transcript not found at ${ref.path} \u2014 a bundle cannot be assembled without its transcript`);
@@ -12870,17 +12767,17 @@ async function assembleSessionBundle(opts) {
12870
12767
  const transcriptSha256 = row.sourceFiles.find((file) => resolve5(file.path) === resolve5(ref.path))?.sha256 ?? row.sourceSha256;
12871
12768
  const outDir = resolve5(opts.outDir);
12872
12769
  await mkdir2(outDir, { recursive: true });
12873
- if ((await readdir14(outDir)).length > 0) {
12770
+ if ((await readdir13(outDir)).length > 0) {
12874
12771
  throw new Error(
12875
12772
  `bundle output directory ${outDir} is not empty \u2014 pass a new directory so one bundle holds exactly one session`
12876
12773
  );
12877
12774
  }
12878
12775
  const absent = [];
12879
12776
  const slices = [];
12880
- await mkdir2(join18(outDir, "session"), { recursive: true });
12881
- const subagentsSource = join18(ref.path.replace(/\.jsonl$/, ""), "subagents");
12777
+ await mkdir2(join17(outDir, "session"), { recursive: true });
12778
+ const subagentsSource = join17(ref.path.replace(/\.jsonl$/, ""), "subagents");
12882
12779
  if ((await statOrNull(subagentsSource))?.isDirectory()) {
12883
- await cp(subagentsSource, join18(outDir, "session", "subagents"), { recursive: true });
12780
+ await cp(subagentsSource, join17(outDir, "session", "subagents"), { recursive: true });
12884
12781
  } else {
12885
12782
  absent.push({ path: bundlePath("session", "subagents"), reason: `no subagents directory at ${subagentsSource}` });
12886
12783
  }
@@ -12890,7 +12787,7 @@ async function assembleSessionBundle(opts) {
12890
12787
  const sourceId = sourceFileId(file.path);
12891
12788
  const subagentRelative = relative4(subagentsSource, file.path);
12892
12789
  const path = resolve5(file.path) === resolve5(ref.path) ? bundlePath("session", "transcript.jsonl") : !subagentRelative.startsWith("..") && !subagentRelative.startsWith(sep) ? bundlePath("session", "subagents", subagentRelative) : bundlePath("session", "sources", `${sourceId}.jsonl`);
12893
- const target = join18(outDir, path);
12790
+ const target = join17(outDir, path);
12894
12791
  await mkdir2(dirname7(target), { recursive: true });
12895
12792
  await copyFile(file.path, target);
12896
12793
  if (await fileSha256(target, opts.signal) !== file.sha256) {
@@ -12898,8 +12795,8 @@ async function assembleSessionBundle(opts) {
12898
12795
  }
12899
12796
  retainedSourceIds.set(path, sourceId);
12900
12797
  }
12901
- await mkdir2(join18(outDir, "derived"), { recursive: true });
12902
- const otlpPath = join18(outDir, "derived", "trace.otlp.jsonl");
12798
+ await mkdir2(join17(outDir, "derived"), { recursive: true });
12799
+ const otlpPath = join17(outDir, "derived", "trace.otlp.jsonl");
12903
12800
  const investigation = await runTraceInvestigation({
12904
12801
  spans,
12905
12802
  harness: ref.harness,
@@ -12911,7 +12808,7 @@ async function assembleSessionBundle(opts) {
12911
12808
  signal: opts.signal,
12912
12809
  log: opts.log
12913
12810
  });
12914
- await writeFile5(join18(outDir, "derived", "report.md"), investigation.report, "utf8");
12811
+ await writeFile5(join17(outDir, "derived", "report.md"), investigation.report, "utf8");
12915
12812
  const evidence3 = await buildPolicyEvidenceRecord(ref, spans, {
12916
12813
  generatedAt,
12917
12814
  minLoopOccurrences: opts.minLoopOccurrences,
@@ -12919,13 +12816,13 @@ async function assembleSessionBundle(opts) {
12919
12816
  otlpPath: bundlePath("derived", "trace.otlp.jsonl"),
12920
12817
  sourceSha256: transcriptSha256
12921
12818
  });
12922
- await writeFile5(join18(outDir, "derived", "evidence.jsonl"), serializePolicyEvidence([evidence3]), "utf8");
12819
+ await writeFile5(join17(outDir, "derived", "evidence.jsonl"), serializePolicyEvidence([evidence3]), "utf8");
12923
12820
  const index = await buildSessionIndexFromRows([{ ref, spans }], {
12924
12821
  generatedAt,
12925
12822
  minLoopOccurrences: opts.minLoopOccurrences,
12926
12823
  selection: { command: "bundle", harness: ref.harness, session: ref.sessionId }
12927
12824
  });
12928
- await writeFile5(join18(outDir, "derived", "session-index.json"), serializeSessionIndex(index), "utf8");
12825
+ await writeFile5(join17(outDir, "derived", "session-index.json"), serializeSessionIndex(index), "utf8");
12929
12826
  const { firstSpanAt, lastSpanAt } = evidence3.metrics;
12930
12827
  const windowStartMs = firstSpanAt !== null ? Date.parse(firstSpanAt) - SESSION_WINDOW_PAD_MS : null;
12931
12828
  const windowEndMs = lastSpanAt !== null ? Date.parse(lastSpanAt) + SESSION_WINDOW_PAD_MS : null;
@@ -12933,11 +12830,11 @@ async function assembleSessionBundle(opts) {
12933
12830
  if (!contextRoot) {
12934
12831
  absent.push({ path: "ledger", reason: `no context root found from session cwd ${ref.cwd ?? "(unknown)"}` });
12935
12832
  } else {
12936
- const evolveDir = join18(contextRoot, ".evolve");
12833
+ const evolveDir = join17(contextRoot, ".evolve");
12937
12834
  if (!(await statOrNull(evolveDir))?.isDirectory()) {
12938
12835
  absent.push({ path: "ledger", reason: `no .evolve ledger at ${evolveDir}` });
12939
12836
  } else {
12940
- const ledgerDir = join18(outDir, "ledger");
12837
+ const ledgerDir = join17(outDir, "ledger");
12941
12838
  await mkdir2(ledgerDir, { recursive: true });
12942
12839
  const ctx = { evolveDir, ledgerDir, windowStartMs, windowEndMs, slices, absent };
12943
12840
  await sliceLedgerJsonl(ctx, "experiments.jsonl");
@@ -12957,8 +12854,8 @@ async function assembleSessionBundle(opts) {
12957
12854
  } else {
12958
12855
  const log = await runGitLog(ref.cwd, new Date(windowStartMs).toISOString(), new Date(windowEndMs).toISOString());
12959
12856
  if (log.succeeded) {
12960
- await mkdir2(join18(outDir, "repo"), { recursive: true });
12961
- await writeFile5(join18(outDir, "repo", "git-log.txt"), log.stdout ? `${log.stdout}
12857
+ await mkdir2(join17(outDir, "repo"), { recursive: true });
12858
+ await writeFile5(join17(outDir, "repo", "git-log.txt"), log.stdout ? `${log.stdout}
12962
12859
  ` : "", "utf8");
12963
12860
  } else {
12964
12861
  absent.push({ path: gitLogPath, reason: `git log failed in ${ref.cwd}: ${log.error}` });
@@ -12997,20 +12894,20 @@ async function assembleSessionBundle(opts) {
12997
12894
  async function hashSessionBundleFiles(root) {
12998
12895
  const files = [];
12999
12896
  for (const path of await listSessionBundleFiles(root)) {
13000
- const filePath = join18(root, path);
13001
- const info = await stat13(filePath);
12897
+ const filePath = join17(root, path);
12898
+ const info = await stat12(filePath);
13002
12899
  files.push({ path, bytes: info.size, sha256: await fileSha256(filePath) });
13003
12900
  }
13004
12901
  return files;
13005
12902
  }
13006
12903
  async function writeSessionBundleManifest(outDir, manifest) {
13007
- const manifestPath = join18(outDir, "manifest.json");
12904
+ const manifestPath = join17(outDir, "manifest.json");
13008
12905
  await writeFile5(manifestPath, `${JSON.stringify(manifest, null, 2)}
13009
12906
  `, "utf8");
13010
12907
  return manifestPath;
13011
12908
  }
13012
12909
  async function readSessionBundleManifest(bundleDir) {
13013
- const path = join18(resolve5(bundleDir), "manifest.json");
12910
+ const path = join17(resolve5(bundleDir), "manifest.json");
13014
12911
  let text2;
13015
12912
  try {
13016
12913
  text2 = await readFile7(path, "utf8");
@@ -13054,8 +12951,8 @@ async function nonRegularEntries(root) {
13054
12951
  const pending = [resolve5(root)];
13055
12952
  while (pending.length > 0) {
13056
12953
  const dir = pending.pop();
13057
- for (const entry of await readdir14(dir, { withFileTypes: true })) {
13058
- const path = join18(dir, entry.name);
12954
+ for (const entry of await readdir13(dir, { withFileTypes: true })) {
12955
+ const path = join17(dir, entry.name);
13059
12956
  if (entry.isDirectory()) pending.push(path);
13060
12957
  else if (!entry.isFile()) out.push(relative4(resolve5(root), path).split(sep).join("/"));
13061
12958
  }
@@ -13075,7 +12972,7 @@ async function verifySessionBundle(bundleDir) {
13075
12972
  continue;
13076
12973
  }
13077
12974
  listed.add(file.path);
13078
- const info = await lstat(join18(directory, file.path)).catch((error) => {
12975
+ const info = await lstat(join17(directory, file.path)).catch((error) => {
13079
12976
  if (isMissingPathError(error)) return null;
13080
12977
  throw error;
13081
12978
  });
@@ -13084,7 +12981,7 @@ async function verifySessionBundle(bundleDir) {
13084
12981
  continue;
13085
12982
  }
13086
12983
  if (!info.isFile()) continue;
13087
- const sha2562 = await fileSha256(join18(directory, file.path));
12984
+ const sha2562 = await fileSha256(join17(directory, file.path));
13088
12985
  if (info.size !== file.bytes || sha2562 !== file.sha256) {
13089
12986
  issues.push({
13090
12987
  kind: "mismatch",
@@ -13104,7 +13001,7 @@ async function verifySessionBundle(bundleDir) {
13104
13001
  }
13105
13002
  let source;
13106
13003
  if (manifest.projection) {
13107
- const sourceManifest = join18(manifest.projection.sourceDirectory, "manifest.json");
13004
+ const sourceManifest = join17(manifest.projection.sourceDirectory, "manifest.json");
13108
13005
  const bytes2 = await readFile7(sourceManifest).catch((error) => {
13109
13006
  if (isMissingPathError(error)) return null;
13110
13007
  throw error;
@@ -13142,7 +13039,7 @@ async function openBundleFile(root, file) {
13142
13039
  const path = containedPath(root, file.path);
13143
13040
  let current = root;
13144
13041
  for (const part of relative5(root, path).split(sep2)) {
13145
- current = join19(current, part);
13042
+ current = join18(current, part);
13146
13043
  if ((await lstat2(current)).isSymbolicLink()) throw new Error("bundle source symlinks are not permitted");
13147
13044
  }
13148
13045
  if (await realpath3(path) !== path) throw new Error("bundle source resolved outside its declared path");
@@ -13181,7 +13078,7 @@ async function createBundleSourceReader(directory, spans, options = {}) {
13181
13078
  options.signal?.throwIfAborted();
13182
13079
  if ((await lstat2(resolve6(directory))).isSymbolicLink()) throw new Error("bundle directory must not be a symlink");
13183
13080
  const root = await realpath3(resolve6(directory));
13184
- if ((await lstat2(join19(root, "manifest.json"))).isSymbolicLink()) throw new Error("bundle manifest must not be a symlink");
13081
+ if ((await lstat2(join18(root, "manifest.json"))).isSymbolicLink()) throw new Error("bundle manifest must not be a symlink");
13185
13082
  const manifest = await readSessionBundleManifest(root);
13186
13083
  if (manifest.view !== "full") throw new Error("original source reads require an explicitly authorized full bundle");
13187
13084
  if (!Array.isArray(manifest.files)) throw new Error("bundle manifest has no file receipts");
@@ -13203,7 +13100,7 @@ async function createBundleSourceReader(directory, spans, options = {}) {
13203
13100
  const traceFile = manifest.files.find((file) => file.path === TRACE_FILE);
13204
13101
  if (!traceFile) throw new Error("bundle has no derived trace receipt");
13205
13102
  await validateFile(root, traceFile, options.signal);
13206
- const recorded = await readOtlpInput(join19(root, TRACE_FILE));
13103
+ const recorded = await readOtlpInput(join18(root, TRACE_FILE));
13207
13104
  await validateFile(root, traceFile, options.signal);
13208
13105
  const original = new Map(recorded.spans.map((span2) => [identity(span2), span2]));
13209
13106
  const allowed = /* @__PURE__ */ new Map();
@@ -13601,7 +13498,7 @@ import {
13601
13498
  readFile as readFile10,
13602
13499
  rm as rm2
13603
13500
  } from "fs/promises";
13604
- import { basename as basename11, dirname as dirname10, join as join22, resolve as resolve8 } from "path";
13501
+ import { basename as basename10, dirname as dirname10, join as join21, resolve as resolve8 } from "path";
13605
13502
 
13606
13503
  // src/codetracebench-files.ts
13607
13504
  import { createHash as createHash12, randomUUID } from "crypto";
@@ -13614,18 +13511,18 @@ import {
13614
13511
  rename as rename2,
13615
13512
  rm,
13616
13513
  rmdir,
13617
- stat as stat14,
13514
+ stat as stat13,
13618
13515
  unlink,
13619
13516
  writeFile as writeFile6
13620
13517
  } from "fs/promises";
13621
13518
  import { hostname } from "os";
13622
- import { basename as basename10, dirname as dirname9, isAbsolute as isAbsolute5, join as join20, relative as relative6, resolve as resolve7, sep as sep3 } from "path";
13519
+ import { basename as basename9, dirname as dirname9, isAbsolute as isAbsolute5, join as join19, relative as relative6, resolve as resolve7, sep as sep3 } from "path";
13623
13520
  async function claimImportLock(input) {
13624
13521
  const claimId = randomUUID();
13625
13522
  const path = `${input.outputDirectory}.lock`;
13626
- const temporary = join20(
13523
+ const temporary = join19(
13627
13524
  dirname9(path),
13628
- `.${basename10(path)}.${claimId}.tmp`
13525
+ `.${basename9(path)}.${claimId}.tmp`
13629
13526
  );
13630
13527
  const metadata = {
13631
13528
  kind: "traces.codetracebench-import-lock",
@@ -13714,8 +13611,8 @@ async function publishStagedFiles(stagingDirectory, outputDirectory, files, sign
13714
13611
  try {
13715
13612
  for (const file of files) {
13716
13613
  signal.throwIfAborted();
13717
- const destination = join20(outputDirectory, file);
13718
- await link(join20(stagingDirectory, file), destination);
13614
+ const destination = join19(outputDirectory, file);
13615
+ await link(join19(stagingDirectory, file), destination);
13719
13616
  published.push(destination);
13720
13617
  }
13721
13618
  } catch (error) {
@@ -13745,7 +13642,7 @@ async function containedDirectory(path) {
13745
13642
  cause: error
13746
13643
  });
13747
13644
  }
13748
- const info = await stat14(canonical);
13645
+ const info = await stat13(canonical);
13749
13646
  if (!info.isDirectory()) {
13750
13647
  throw new TypeError(`CodeTraceBench trajectory path is not a directory: ${canonical}`);
13751
13648
  }
@@ -13768,7 +13665,7 @@ async function optionalContainedFile(root, candidate) {
13768
13665
  if (fromRoot === ".." || fromRoot.startsWith(`..${sep3}`) || isAbsolute5(fromRoot)) {
13769
13666
  throw new Error(`CodeTraceBench trajectory file escapes its input directory: ${candidate}`);
13770
13667
  }
13771
- const info = await stat14(canonical);
13668
+ const info = await stat13(canonical);
13772
13669
  if (!info.isFile()) {
13773
13670
  throw new TypeError(`CodeTraceBench trajectory path is not a file: ${candidate}`);
13774
13671
  }
@@ -13785,9 +13682,9 @@ async function assertPathMissing(path) {
13785
13682
  }
13786
13683
  async function atomicWriteFile(path, content, signal) {
13787
13684
  signal.throwIfAborted();
13788
- const temporary = join20(
13685
+ const temporary = join19(
13789
13686
  dirname9(path),
13790
- `.${basename10(path)}.${randomUUID()}.tmp`
13687
+ `.${basename9(path)}.${randomUUID()}.tmp`
13791
13688
  );
13792
13689
  try {
13793
13690
  await writeFile6(temporary, content, {
@@ -13813,17 +13710,17 @@ function isErrno(error, code) {
13813
13710
 
13814
13711
  // src/codetracebench-trajectory.ts
13815
13712
  import { readFile as readFile9 } from "fs/promises";
13816
- import { join as join21 } from "path";
13713
+ import { join as join20 } from "path";
13817
13714
  var TRAJECTORY_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$/;
13818
13715
  var LABEL_KEY = /\\?["'](?:incorrect_stages|incorrect_step_ids|unuseful_step_ids|annotation_relpath|incorrect_error_stage_count)\\?["']\s*:/i;
13819
13716
  var LABEL_ARRAY = /\\?["']labels\\?["']\s*:\s*\[[^\]]*\\?["'](?:incorrect|unuseful)\\?["']/i;
13820
13717
  var ANNOTATION_PATH = /(?:agent_failure_analysis|step_annotations(?:_all)?|merged_cleaned_step\d*)[\\/]/i;
13821
13718
  async function importTrajectory(input) {
13822
13719
  const { index, row, trajectoryDirectory, stagingDirectory, signal } = input;
13823
- const caseDirectory = join21(trajectoryDirectory, row.trajId);
13720
+ const caseDirectory = join20(trajectoryDirectory, row.trajId);
13824
13721
  const stepsPath = await containedFile(
13825
13722
  trajectoryDirectory,
13826
- join21(caseDirectory, "steps.json"),
13723
+ join20(caseDirectory, "steps.json"),
13827
13724
  `${row.trajId}: steps.json`
13828
13725
  );
13829
13726
  signal.throwIfAborted();
@@ -13864,7 +13761,7 @@ async function importTrajectory(input) {
13864
13761
  const serialized = serializeSpans(spans);
13865
13762
  assertNoLabelLeakInText(serialized, row, `${row.trajId}: serialized OTLP`);
13866
13763
  const outputFile = `${row.trajId}.otlp.jsonl`;
13867
- await atomicWriteFile(join21(stagingDirectory, outputFile), serialized, signal);
13764
+ await atomicWriteFile(join20(stagingDirectory, outputFile), serialized, signal);
13868
13765
  return {
13869
13766
  index,
13870
13767
  traceId: row.trajId,
@@ -14031,7 +13928,7 @@ function fileRef(value, label2) {
14031
13928
  };
14032
13929
  }
14033
13930
  async function readOptionalTask(trajectoryDirectory, caseDirectory, row, signal) {
14034
- const candidate = join21(caseDirectory, "task.md");
13931
+ const candidate = join20(caseDirectory, "task.md");
14035
13932
  const path = await optionalContainedFile(trajectoryDirectory, candidate);
14036
13933
  if (!path) {
14037
13934
  return {
@@ -14120,7 +14017,7 @@ async function importCodeTraceBench(options) {
14120
14017
  const rowsPath = resolve8(options.rowsPath);
14121
14018
  const trajectoryPath = resolve8(options.trajectoryDir);
14122
14019
  const outputDirectory = resolve8(options.outDir);
14123
- const outputBase = basename11(outputDirectory);
14020
+ const outputBase = basename10(outputDirectory);
14124
14021
  if (!outputBase || outputDirectory === dirname10(outputDirectory)) {
14125
14022
  throw new Error("CodeTraceBench output directory must not be a filesystem root");
14126
14023
  }
@@ -14164,7 +14061,7 @@ async function runCodeTraceBenchImport(input) {
14164
14061
  const rows = parseRows(rowsBytes.toString("utf8"), rowsPath);
14165
14062
  const sourceRows = validateRows(rows, rowsPath);
14166
14063
  const stagingDirectory = await mkdtemp4(
14167
- join22(dirname10(outputDirectory), `.${outputBase}.tmp-`)
14064
+ join21(dirname10(outputDirectory), `.${outputBase}.tmp-`)
14168
14065
  );
14169
14066
  const stop = new AbortController();
14170
14067
  const signal = outerSignal ? AbortSignal.any([outerSignal, stop.signal]) : stop.signal;
@@ -14224,10 +14121,10 @@ async function runCodeTraceBenchImport(input) {
14224
14121
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
14225
14122
  input: {
14226
14123
  revision,
14227
- rowsFile: basename11(rowsPath),
14124
+ rowsFile: basename10(rowsPath),
14228
14125
  rowsSha256,
14229
14126
  rowsBytes: rowsBytes.byteLength,
14230
- trajectoryDirectory: basename11(trajectoryDirectory),
14127
+ trajectoryDirectory: basename10(trajectoryDirectory),
14231
14128
  sha256: inputSha256
14232
14129
  },
14233
14130
  settings: {
@@ -14250,7 +14147,7 @@ async function runCodeTraceBenchImport(input) {
14250
14147
  };
14251
14148
  const receiptFile = "codetracebench-import.json";
14252
14149
  await atomicWriteFile(
14253
- join22(stagingDirectory, receiptFile),
14150
+ join21(stagingDirectory, receiptFile),
14254
14151
  `${JSON.stringify(receipt, null, 2)}
14255
14152
  `,
14256
14153
  signal
@@ -14265,7 +14162,7 @@ async function runCodeTraceBenchImport(input) {
14265
14162
  await rm2(stagingDirectory, { recursive: true, force: true });
14266
14163
  return {
14267
14164
  directory: outputDirectory,
14268
- receiptPath: join22(outputDirectory, receiptFile),
14165
+ receiptPath: join21(outputDirectory, receiptFile),
14269
14166
  receipt
14270
14167
  };
14271
14168
  } catch (error) {
@@ -14693,20 +14590,20 @@ async function cmdVerifyFindings(argv) {
14693
14590
 
14694
14591
  // src/hodoscope.ts
14695
14592
  import { createHash as createHash13 } from "crypto";
14696
- import { mkdir as mkdir5, mkdtemp as mkdtemp5, readFile as readFile11, readdir as readdir15, writeFile as writeFile7 } from "fs/promises";
14593
+ import { mkdir as mkdir5, mkdtemp as mkdtemp5, readFile as readFile11, readdir as readdir14, writeFile as writeFile7 } from "fs/promises";
14697
14594
  import { endianness, tmpdir as tmpdir5 } from "os";
14698
- import { join as join23, resolve as resolve9 } from "path";
14595
+ import { join as join22, resolve as resolve9 } from "path";
14699
14596
  var HODOSCOPE_VERSION = "0.2.4";
14700
14597
  async function writeHodoscopeInput(otlpPath, options = {}) {
14701
14598
  const explicitDirectory = options.directory ? resolve9(options.directory) : void 0;
14702
- const directory = explicitDirectory ?? await mkdtemp5(join23(tmpdir5(), "traces-hodoscope-input-"));
14599
+ const directory = explicitDirectory ?? await mkdtemp5(join22(tmpdir5(), "traces-hodoscope-input-"));
14703
14600
  if (explicitDirectory) {
14704
14601
  await mkdir5(directory, { recursive: true });
14705
- if ((await readdir15(directory)).length > 0) {
14602
+ if ((await readdir14(directory)).length > 0) {
14706
14603
  throw new Error(`Hodoscope explicit directory must be empty: ${directory}`);
14707
14604
  }
14708
14605
  }
14709
- const samples = join23(directory, "samples");
14606
+ const samples = join22(directory, "samples");
14710
14607
  await mkdir5(samples);
14711
14608
  const rows = [];
14712
14609
  for await (const value of readJsonl(otlpPath)) rows.push(parseOpenInferenceRow(value));
@@ -14732,7 +14629,7 @@ async function writeHodoscopeInput(otlpPath, options = {}) {
14732
14629
  }
14733
14630
  actionCount += actions;
14734
14631
  const file = `${createHash13("sha256").update(traceId).digest("hex").slice(0, 24)}.json`;
14735
- await writeFile7(join23(samples, file), `${JSON.stringify(trajectory, null, 2)}
14632
+ await writeFile7(join22(samples, file), `${JSON.stringify(trajectory, null, 2)}
14736
14633
  `, "utf8");
14737
14634
  }
14738
14635
  return {
@@ -14756,10 +14653,10 @@ function hodoscopeAnalyzer(options = {}) {
14756
14653
  async analyze(otlpPath, runOptions2 = {}) {
14757
14654
  const outputRoot = options.outputDir ? resolve9(options.outputDir) : tmpdir5();
14758
14655
  await mkdir5(outputRoot, { recursive: true });
14759
- const directory = await mkdtemp5(join23(outputRoot, "traces-hodoscope-"));
14760
- const input = join23(directory, "input");
14761
- const analysisFile = join23(directory, "analysis.hodoscope.json");
14762
- const samplesFile = join23(directory, "samples.json");
14656
+ const directory = await mkdtemp5(join22(outputRoot, "traces-hodoscope-"));
14657
+ const input = join22(directory, "input");
14658
+ const analysisFile = join22(directory, "analysis.hodoscope.json");
14659
+ const samplesFile = join22(directory, "samples.json");
14763
14660
  try {
14764
14661
  const prepared = await writeHodoscopeInput(otlpPath, {
14765
14662
  directory: input,
@@ -15382,7 +15279,7 @@ function assertPositiveInteger(name, value) {
15382
15279
  import { createHash as createHash14 } from "crypto";
15383
15280
  import { request as httpRequest } from "http";
15384
15281
  import { request as httpsRequest } from "https";
15385
- import { join as join24 } from "path";
15282
+ import { join as join23 } from "path";
15386
15283
  var DEFAULT_BRIDGE_URL = "http://localhost:4181";
15387
15284
  var DEFAULT_MODEL = "prime/zai/glm-5.2";
15388
15285
  var DEFAULT_TIMEOUT_MS = 12e5;
@@ -15396,12 +15293,12 @@ var ANALYST_ID = "prime";
15396
15293
  var TRAJECTORY_FILE_NAME = "trajectory.otlp.jsonl";
15397
15294
  async function fileDelivery(otlpPath, perAttributeCharCap, signal) {
15398
15295
  signal?.throwIfAborted();
15399
- const { copyFile: copyFile2, mkdtemp: mkdtemp8, stat: stat19 } = await import("fs/promises");
15296
+ const { copyFile: copyFile2, mkdtemp: mkdtemp8, stat: stat18 } = await import("fs/promises");
15400
15297
  const { tmpdir: tmpdir8 } = await import("os");
15401
- const { join: join36 } = await import("path");
15402
- const cwd = await mkdtemp8(join36(tmpdir8(), "traces-prime-"));
15403
- await copyFile2(otlpPath, join36(cwd, TRAJECTORY_FILE_NAME));
15404
- const artifactBytes = (await stat19(otlpPath)).size;
15298
+ const { join: join35 } = await import("path");
15299
+ const cwd = await mkdtemp8(join35(tmpdir8(), "traces-prime-"));
15300
+ await copyFile2(otlpPath, join35(cwd, TRAJECTORY_FILE_NAME));
15301
+ const artifactBytes = (await stat18(otlpPath)).size;
15405
15302
  return { mode: "file-cwd", perAttributeCharCap, renderedChars: artifactBytes, cwd, fileName: TRAJECTORY_FILE_NAME };
15406
15303
  }
15407
15304
  function positiveIntegerEnv(name) {
@@ -15429,8 +15326,8 @@ function normalizeUsage(raw) {
15429
15326
  }
15430
15327
  function mergeUsage(a, b) {
15431
15328
  const calls = a.calls !== null && b.calls !== null ? a.calls + b.calls : null;
15432
- const tokens3 = a.tokens !== null && b.tokens !== null && a.tokens.input !== null && b.tokens.input !== null && a.tokens.output !== null && b.tokens.output !== null ? { input: a.tokens.input + b.tokens.input, output: a.tokens.output + b.tokens.output } : null;
15433
- return { calls, tokens: tokens3, estimated: a.estimated || b.estimated };
15329
+ const tokens2 = a.tokens !== null && b.tokens !== null && a.tokens.input !== null && b.tokens.input !== null && a.tokens.output !== null && b.tokens.output !== null ? { input: a.tokens.input + b.tokens.input, output: a.tokens.output + b.tokens.output } : null;
15330
+ return { calls, tokens: tokens2, estimated: a.estimated || b.estimated };
15434
15331
  }
15435
15332
  function renderUsage(usage) {
15436
15333
  const calls = usage.calls === null ? "uncaptured" : String(usage.calls);
@@ -15638,11 +15535,11 @@ var FINDINGS_FILE_MAX_BYTES = 256 * 1024;
15638
15535
  var FINDINGS_FILE_NAME = "findings.json";
15639
15536
  async function readFindingsFile2(cwd, signal) {
15640
15537
  signal?.throwIfAborted();
15641
- const path = join24(cwd, FINDINGS_FILE_NAME);
15538
+ const path = join23(cwd, FINDINGS_FILE_NAME);
15642
15539
  let raw;
15643
- const { readFile: readFile21, stat: stat19 } = await import("fs/promises");
15540
+ const { readFile: readFile21, stat: stat18 } = await import("fs/promises");
15644
15541
  try {
15645
- const size = (await stat19(path)).size;
15542
+ const size = (await stat18(path)).size;
15646
15543
  if (size > FINDINGS_FILE_MAX_BYTES) {
15647
15544
  return { parsed: null, receipt: `${FINDINGS_FILE_NAME} is ${size} bytes (cap ${FINDINGS_FILE_MAX_BYTES}); refused` };
15648
15545
  }
@@ -16054,7 +15951,7 @@ async function applyRedactor(spans, redactor) {
16054
15951
  import { createHash as createHash15 } from "crypto";
16055
15952
  import { mkdtemp as mkdtemp6, readFile as readFile12, writeFile as writeFile8 } from "fs/promises";
16056
15953
  import { tmpdir as tmpdir6 } from "os";
16057
- import { join as join25 } from "path";
15954
+ import { join as join24 } from "path";
16058
15955
  import {
16059
15956
  firstNumberAttr as firstNumberAttr2,
16060
15957
  LLM_CACHED_TOKEN_ATTR_KEYS,
@@ -16725,7 +16622,7 @@ async function exportTraceEvidenceFile(inputPath, opts = {}) {
16725
16622
  }
16726
16623
  async function writeTraceEvidenceExportFile(inputPath, outPath, opts = {}) {
16727
16624
  const result = await exportTraceEvidenceFile(inputPath, opts);
16728
- const path = outPath ?? join25(await mkdtemp6(join25(tmpdir6(), "traces-export-")), "spans.openinference.jsonl");
16625
+ const path = outPath ?? join24(await mkdtemp6(join24(tmpdir6(), "traces-export-")), "spans.openinference.jsonl");
16729
16626
  await writeFile8(path, serializeSpans(result.spans), "utf8");
16730
16627
  return { ...result, path };
16731
16628
  }
@@ -16733,7 +16630,7 @@ async function writeTraceEvidenceExportFile(inputPath, outPath, opts = {}) {
16733
16630
  // src/inspect.ts
16734
16631
  import { mkdtemp as mkdtemp7, readFile as readFile13, writeFile as writeFile9 } from "fs/promises";
16735
16632
  import { tmpdir as tmpdir7 } from "os";
16736
- import { basename as basename12, join as join26 } from "path";
16633
+ import { basename as basename11, join as join25 } from "path";
16737
16634
  var severityRank2 = {
16738
16635
  high: 0,
16739
16636
  medium: 1,
@@ -16833,7 +16730,7 @@ function addSessionFindings(index, findings) {
16833
16730
  refs: errorSessions.slice(0, 5).map((row) => row.session.path)
16834
16731
  });
16835
16732
  }
16836
- const largeSessions = sessions.map((row) => ({ row, tokens: row.metrics.inputTokens + row.metrics.outputTokens })).filter(({ tokens: tokens3 }) => tokens3 >= 5e5).sort((a, b) => b.tokens - a.tokens);
16733
+ const largeSessions = sessions.map((row) => ({ row, tokens: row.metrics.inputTokens + row.metrics.outputTokens })).filter(({ tokens: tokens2 }) => tokens2 >= 5e5).sort((a, b) => b.tokens - a.tokens);
16837
16734
  if (largeSessions.length > 0) {
16838
16735
  const largest = largeSessions[0]?.tokens ?? 0;
16839
16736
  findings.push({
@@ -16842,7 +16739,7 @@ function addSessionFindings(index, findings) {
16842
16739
  area: "session",
16843
16740
  title: `${largeSessions.length} session(s) reported at least 500k summed tokens`,
16844
16741
  impact: largest,
16845
- evidence: largeSessions.slice(0, 5).map(({ row, tokens: tokens3 }) => `${sessionLabel(row)}: ${tokens3.toLocaleString()} reported summed tokens (${row.metrics.inputTokens.toLocaleString()} in, ${row.metrics.outputTokens.toLocaleString()} out)`),
16742
+ evidence: largeSessions.slice(0, 5).map(({ row, tokens: tokens2 }) => `${sessionLabel(row)}: ${tokens2.toLocaleString()} reported summed tokens (${row.metrics.inputTokens.toLocaleString()} in, ${row.metrics.outputTokens.toLocaleString()} out)`),
16846
16743
  next: "Check whether these sessions need shorter handoffs, smaller files, split tasks, or clearer token accounting before optimizing anything else.",
16847
16744
  refs: largeSessions.slice(0, 5).map(({ row }) => row.session.path)
16848
16745
  });
@@ -16916,7 +16813,7 @@ function addContextFindings(index, findings) {
16916
16813
  refs: invalidJsonlFiles.slice(0, 5).map((file) => file.path)
16917
16814
  });
16918
16815
  }
16919
- const skillRunFiles = files.filter((file) => basename12(file.path) === "skill-runs.jsonl" && (file.jsonl?.rows ?? 0) > 0).map((file) => {
16816
+ const skillRunFiles = files.filter((file) => basename11(file.path) === "skill-runs.jsonl" && (file.jsonl?.rows ?? 0) > 0).map((file) => {
16920
16817
  const rows = file.jsonl?.rows ?? 0;
16921
16818
  const keys = file.jsonl?.keys ?? {};
16922
16819
  const linkKeyCounts = {
@@ -17022,7 +16919,7 @@ async function readSessionIndexFile(path) {
17022
16919
  return parsed;
17023
16920
  }
17024
16921
  async function writeInspectionReportFile(report, outPath) {
17025
- const path = outPath ?? join26(await mkdtemp7(join26(tmpdir7(), "traces-inspect-")), "inspection-report.md");
16922
+ const path = outPath ?? join25(await mkdtemp7(join25(tmpdir7(), "traces-inspect-")), "inspection-report.md");
17026
16923
  await writeFile9(path, renderInspectionReport(report), "utf8");
17027
16924
  return path;
17028
16925
  }
@@ -17455,8 +17352,8 @@ async function streamSessions(opts) {
17455
17352
  }
17456
17353
 
17457
17354
  // src/supervisor-run-context.ts
17458
- import { readFile as readFile14, stat as stat15 } from "fs/promises";
17459
- import { basename as basename13, join as join27 } from "path";
17355
+ import { readFile as readFile14, stat as stat14 } from "fs/promises";
17356
+ import { basename as basename12, join as join26 } from "path";
17460
17357
  import { materializeTreeView } from "@tangle-network/agent-runtime/kernel";
17461
17358
  import {
17462
17359
  readRuntimeSupervisorRun
@@ -17625,14 +17522,14 @@ function parseInstant(v) {
17625
17522
  }
17626
17523
  async function readFileRunContext(runDir, opts = {}) {
17627
17524
  const sources = await readRuntimeSupervisorRun(runDir);
17628
- const coordination = readCoordinationLog(await readMaybe(join27(runDir, COORDINATION_LOG_FILE)));
17525
+ const coordination = readCoordinationLog(await readMaybe(join26(runDir, COORDINATION_LOG_FILE)));
17629
17526
  return {
17630
17527
  ...sources,
17631
17528
  instanceId: opts.instanceId !== void 0 ? opts.instanceId : sources.instanceId,
17632
- arm: opts.arm !== void 0 ? opts.arm : basename13(runDir),
17529
+ arm: opts.arm !== void 0 ? opts.arm : basename12(runDir),
17633
17530
  workers: sources.workers !== null && coordination.present ? workerSources(sources.workers, coordination) : sources.workers,
17634
17531
  ...sources.journal !== null ? {
17635
- rootTranscriptRef: join27(runDir, SPAWN_JOURNAL_FILE),
17532
+ rootTranscriptRef: join26(runDir, SPAWN_JOURNAL_FILE),
17636
17533
  traceCommand: `traces watch ${runDir}`
17637
17534
  } : {}
17638
17535
  };
@@ -17641,7 +17538,7 @@ function fileRunContextSupervisorRunReader(runDir, opts = {}) {
17641
17538
  return { runRef: runDir, read: () => readFileRunContext(runDir, opts) };
17642
17539
  }
17643
17540
  async function isFileRunContextDir(runDir) {
17644
- return stat15(join27(runDir, SPAWN_JOURNAL_FILE)).then((s) => s.isFile()).catch(() => false);
17541
+ return stat14(join26(runDir, SPAWN_JOURNAL_FILE)).then((s) => s.isFile()).catch(() => false);
17645
17542
  }
17646
17543
  function parseJsonObject(text2) {
17647
17544
  if (text2 === null) return null;
@@ -17707,9 +17604,9 @@ function mergeRolls(a, b) {
17707
17604
  };
17708
17605
  }
17709
17606
  async function readRunContextSnapshot(runDir) {
17710
- const journal = readRunContextJournal(await readMaybe(join27(runDir, SPAWN_JOURNAL_FILE)));
17711
- const coordination = readCoordinationLog(await readMaybe(join27(runDir, COORDINATION_LOG_FILE)));
17712
- const resultText = await readMaybe(join27(runDir, RESULT_FILE));
17607
+ const journal = readRunContextJournal(await readMaybe(join26(runDir, SPAWN_JOURNAL_FILE)));
17608
+ const coordination = readCoordinationLog(await readMaybe(join26(runDir, COORDINATION_LOG_FILE)));
17609
+ const resultText = await readMaybe(join26(runDir, RESULT_FILE));
17713
17610
  const result = parseResult(resultText);
17714
17611
  const view = safeTreeView(journal.events);
17715
17612
  const nodes = view === null ? [] : orderNodes(view, journal);
@@ -17843,7 +17740,7 @@ function usd(roll) {
17843
17740
  function zeroPricedCost(roll) {
17844
17741
  return roll.usdKnownRecords > 0 && roll.usd === 0 && roll.tokensIn + roll.tokensOut > 0;
17845
17742
  }
17846
- function tokens2(roll) {
17743
+ function tokens(roll) {
17847
17744
  return `in ${int(roll.tokensIn)} \xB7 out ${int(roll.tokensOut)}`;
17848
17745
  }
17849
17746
  var STATUS_MARK = {
@@ -17889,8 +17786,8 @@ function wrap(text2, indent) {
17889
17786
  }
17890
17787
 
17891
17788
  // src/run-span-tree.ts
17892
- import { readdir as readdir16 } from "fs/promises";
17893
- import { join as join28 } from "path";
17789
+ import { readdir as readdir15 } from "fs/promises";
17790
+ import { join as join27 } from "path";
17894
17791
  import {
17895
17792
  firstNumberAttr as firstNumberAttr3,
17896
17793
  LLM_COST_ATTR_KEYS as LLM_COST_ATTR_KEYS2,
@@ -18105,8 +18002,8 @@ function renderSpanRunSnapshot(snapshot) {
18105
18002
  ` ${snapshot.nodes.length} node(s) \xB7 depth ${snapshot.maxDepth} \xB7 ${int(snapshot.spanCount)} span(s) \xB7 ${snapshot.traceIds.length} trace(s) \xB7 elapsed ${ms(snapshot.endMs === null || snapshot.startMs === null ? null : snapshot.endMs - snapshot.startMs)}`
18106
18003
  );
18107
18004
  const delegating = snapshot.nodes.some((node) => node.role === "driver");
18108
- lines.push(` driver inference ${tokens2(totals.driver)} \xB7 ${usd(totals.driver)}`);
18109
- lines.push(` leaf inference ${tokens2(totals.leaves)} \xB7 ${usd(totals.leaves)}`);
18005
+ lines.push(` driver inference ${tokens(totals.driver)} \xB7 ${usd(totals.driver)}`);
18006
+ lines.push(` leaf inference ${tokens(totals.leaves)} \xB7 ${usd(totals.leaves)}`);
18110
18007
  if (!delegating) {
18111
18008
  lines.push(" (no delegation in these spans: every turn belongs to one agent, so the driver half is empty)");
18112
18009
  }
@@ -18129,11 +18026,11 @@ function renderSpanRunSnapshot(snapshot) {
18129
18026
  ].join(" ")
18130
18027
  );
18131
18028
  lines.push(
18132
- `${detail}driver ${node.driver.records} turn(s) \xB7 ${tokens2(node.driver)} \xB7 ${usd(node.driver)} \xB7 ${node.toolCalls} tool call(s)`
18029
+ `${detail}driver ${node.driver.records} turn(s) \xB7 ${tokens(node.driver)} \xB7 ${usd(node.driver)} \xB7 ${node.toolCalls} tool call(s)`
18133
18030
  );
18134
18031
  if (node.role === "driver") {
18135
18032
  lines.push(
18136
- `${detail}children ${node.children.records} turn(s) \xB7 ${tokens2(node.children)} \xB7 ${usd(node.children)}`
18033
+ `${detail}children ${node.children.records} turn(s) \xB7 ${tokens(node.children)} \xB7 ${usd(node.children)}`
18137
18034
  );
18138
18035
  }
18139
18036
  for (const error of node.errors.slice(0, 3)) lines.push(`${detail}error ${error}`);
@@ -18163,25 +18060,25 @@ function renderSpanRunSnapshot(snapshot) {
18163
18060
  var SPAN_FILE_PATTERN = /\.(?:otlp|spans|traces|openinference)\.(?:jsonl|ndjson)$|^traces?\.jsonl$|^spans\.jsonl$/i;
18164
18061
  async function findSpanSourceFiles(dir) {
18165
18062
  const found = [];
18166
- const entries = await readdir16(dir, { withFileTypes: true }).catch(() => []);
18063
+ const entries = await readdir15(dir, { withFileTypes: true }).catch(() => []);
18167
18064
  for (const entry of entries) {
18168
- const child = join28(dir, entry.name);
18065
+ const child = join27(dir, entry.name);
18169
18066
  if (entry.isFile()) {
18170
18067
  if (SPAN_FILE_PATTERN.test(entry.name)) found.push(child);
18171
18068
  continue;
18172
18069
  }
18173
18070
  if (!entry.isDirectory()) continue;
18174
- const nested = await readdir16(child, { withFileTypes: true }).catch(() => []);
18071
+ const nested = await readdir15(child, { withFileTypes: true }).catch(() => []);
18175
18072
  for (const inner of nested) {
18176
- if (inner.isFile() && SPAN_FILE_PATTERN.test(inner.name)) found.push(join28(child, inner.name));
18073
+ if (inner.isFile() && SPAN_FILE_PATTERN.test(inner.name)) found.push(join27(child, inner.name));
18177
18074
  }
18178
18075
  }
18179
18076
  return found.sort();
18180
18077
  }
18181
18078
 
18182
18079
  // src/supervisor-run-watch.ts
18183
- import { readdir as readdir17 } from "fs/promises";
18184
- import { join as join29 } from "path";
18080
+ import { readdir as readdir16 } from "fs/promises";
18081
+ import { join as join28 } from "path";
18185
18082
  function budget(node) {
18186
18083
  const parts = [`${int(node.budget.maxIterations)}it`, `${int(node.budget.maxTokens)}tok`];
18187
18084
  if (node.budget.maxUsd !== void 0) parts.push(`$${node.budget.maxUsd.toFixed(2)}`);
@@ -18213,17 +18110,17 @@ function renderNode(node, lastAtDepth, lines) {
18213
18110
  lines.push(head.join(" "));
18214
18111
  if (node.driver.records > 0 || node.role === "supervisor") {
18215
18112
  lines.push(
18216
- `${detail}driver ${node.driver.records} turn(s) \xB7 ${tokens2(node.driver)} \xB7 ${usd(node.driver)}` + budgetUse(node, node.driver)
18113
+ `${detail}driver ${node.driver.records} turn(s) \xB7 ${tokens(node.driver)} \xB7 ${usd(node.driver)}` + budgetUse(node, node.driver)
18217
18114
  );
18218
18115
  }
18219
18116
  if (node.children.records > 0 || node.role === "supervisor") {
18220
18117
  lines.push(
18221
- `${detail}children ${node.children.records} settled \xB7 ${tokens2(node.children)} \xB7 ${usd(node.children)}`
18118
+ `${detail}children ${node.children.records} settled \xB7 ${tokens(node.children)} \xB7 ${usd(node.children)}`
18222
18119
  );
18223
18120
  }
18224
18121
  if (node.settled.records > 0) {
18225
18122
  lines.push(
18226
- `${detail}settled ${node.settled.iterations}it \xB7 ${tokens2(node.settled)} \xB7 ${usd(node.settled)}` + budgetUse(node, node.settled)
18123
+ `${detail}settled ${node.settled.iterations}it \xB7 ${tokens(node.settled)} \xB7 ${usd(node.settled)}` + budgetUse(node, node.settled)
18227
18124
  );
18228
18125
  }
18229
18126
  if (node.cancelReason !== null) lines.push(`${detail}cancelled: ${node.cancelReason}`);
@@ -18247,8 +18144,8 @@ function renderRunContextSnapshot(snapshot) {
18247
18144
  lines.push(
18248
18145
  ` ${snapshot.nodes.length} node(s) \xB7 depth ${snapshot.maxDepth} \xB7 elapsed ${ms(elapsed(snapshot))}${snapshot.terminal ? "" : " \xB7 live"}`
18249
18146
  );
18250
- lines.push(` driver total ${tokens2(totals.driver)} \xB7 ${usd(totals.driver)}`);
18251
- lines.push(` worker total ${tokens2(totals.workers)} \xB7 ${usd(totals.workers)}`);
18147
+ lines.push(` driver total ${tokens(totals.driver)} \xB7 ${usd(totals.driver)}`);
18148
+ lines.push(` worker total ${tokens(totals.workers)} \xB7 ${usd(totals.workers)}`);
18252
18149
  lines.push("");
18253
18150
  if (snapshot.nodes.length === 0) lines.push(" (no node spawned yet)");
18254
18151
  forEachTreeNode(
@@ -18323,12 +18220,12 @@ function elapsed(snapshot) {
18323
18220
  }
18324
18221
  async function resolveRunContextDir(dir) {
18325
18222
  if (await isFileRunContextDir(dir)) return dir;
18326
- const entries = await readdir17(dir, { withFileTypes: true }).catch(() => null);
18223
+ const entries = await readdir16(dir, { withFileTypes: true }).catch(() => null);
18327
18224
  if (entries === null) throw new Error(`cannot read ${dir}`);
18328
18225
  const candidates = [];
18329
18226
  for (const entry of entries) {
18330
18227
  if (!entry.isDirectory()) continue;
18331
- const child = join29(dir, entry.name);
18228
+ const child = join28(dir, entry.name);
18332
18229
  if (await isFileRunContextDir(child)) candidates.push(child);
18333
18230
  }
18334
18231
  if (candidates.length === 1) return candidates[0];
@@ -18344,9 +18241,9 @@ async function resolveRunContextDir(dir) {
18344
18241
  }
18345
18242
 
18346
18243
  // src/run-watch.ts
18347
- import { stat as stat16 } from "fs/promises";
18244
+ import { stat as stat15 } from "fs/promises";
18348
18245
  async function resolveRunWatchTarget(target) {
18349
- const info = await stat16(target).catch(() => null);
18246
+ const info = await stat15(target).catch(() => null);
18350
18247
  if (info === null) throw new Error(`cannot read ${target}`);
18351
18248
  if (info.isFile()) return { runDir: null, spanFiles: [target], requested: target };
18352
18249
  const spanFiles = await findSpanSourceFiles(target);
@@ -18471,7 +18368,11 @@ function createAnalystModelOwner(opts) {
18471
18368
  provider: opts.provider,
18472
18369
  default: opts.model,
18473
18370
  reasoningEffort: "none",
18474
- maxVisibleOutputTokens: maxOutputTokens
18371
+ maxVisibleOutputTokens: maxOutputTokens,
18372
+ // Stream every analyst call. The Tangle Router bounds a buffered request by a deadline that
18373
+ // ends when response headers are sent, and a thinking model's long recursive step outlives
18374
+ // it (`request_deadline_exceeded`). A streamed response sends headers at the first byte.
18375
+ metadata: { stream: true }
18475
18376
  }
18476
18377
  };
18477
18378
  return {
@@ -18666,7 +18567,7 @@ function parseJsonAnswer(text2) {
18666
18567
 
18667
18568
  // src/ask.ts
18668
18569
  import { mkdir as mkdir6, readFile as readFile15, writeFile as writeFile10 } from "fs/promises";
18669
- import { join as join30, resolve as resolve10 } from "path";
18570
+ import { join as join29, resolve as resolve10 } from "path";
18670
18571
  import { performance } from "perf_hooks";
18671
18572
  import { CostCeilingReachedError, CostLedger } from "@tangle-network/agent-eval";
18672
18573
  import {
@@ -19222,8 +19123,8 @@ async function writeTraceQuestionsArtifacts(result, outDir) {
19222
19123
  await mkdir6(directory, { recursive: true });
19223
19124
  const paths = {
19224
19125
  directory,
19225
- result: join30(directory, "answers.json"),
19226
- report: join30(directory, "report.md"),
19126
+ result: join29(directory, "answers.json"),
19127
+ report: join29(directory, "report.md"),
19227
19128
  traces: result.otlpPath
19228
19129
  };
19229
19130
  const { report, ...machine } = result;
@@ -19286,8 +19187,8 @@ async function watchSessions(opts) {
19286
19187
 
19287
19188
  // src/bundle-view.ts
19288
19189
  import { createHash as createHash17 } from "crypto";
19289
- import { mkdir as mkdir7, readdir as readdir18, readFile as readFile16, writeFile as writeFile11 } from "fs/promises";
19290
- import { dirname as dirname11, join as join31, resolve as resolve11 } from "path";
19190
+ import { mkdir as mkdir7, readdir as readdir17, readFile as readFile16, writeFile as writeFile11 } from "fs/promises";
19191
+ import { dirname as dirname11, join as join30, resolve as resolve11 } from "path";
19291
19192
  var EVIDENCE_ONLY_ALLOW_LIST = [
19292
19193
  {
19293
19194
  path: "derived/session-index.json",
@@ -19411,7 +19312,7 @@ async function findSessionTextLeaks(opts) {
19411
19312
  const index = /* @__PURE__ */ new Map();
19412
19313
  const carried = [];
19413
19314
  for (const path of opts.carriedPaths) {
19414
- const signatures = sessionTextSignatures(await readFile16(join31(opts.viewDir, path), "utf8"));
19315
+ const signatures = sessionTextSignatures(await readFile16(join30(opts.viewDir, path), "utf8"));
19415
19316
  carried.push({ path, signatures: signatures.size });
19416
19317
  for (const signature of signatures) if (!index.has(signature)) index.set(signature, path);
19417
19318
  }
@@ -19419,7 +19320,7 @@ async function findSessionTextLeaks(opts) {
19419
19320
  const comparedSources = [];
19420
19321
  let sourceSignatures = 0;
19421
19322
  for (const sourcePath of opts.excludedPaths) {
19422
- const signatures = sessionTextSignatures(await readFile16(join31(opts.sourceDir, sourcePath), "utf8"));
19323
+ const signatures = sessionTextSignatures(await readFile16(join30(opts.sourceDir, sourcePath), "utf8"));
19423
19324
  comparedSources.push(sourcePath);
19424
19325
  sourceSignatures += signatures.size;
19425
19326
  for (const signature of signatures) {
@@ -19466,7 +19367,7 @@ async function projectSessionBundle(opts) {
19466
19367
  }
19467
19368
  const outDir = resolve11(opts.outDir);
19468
19369
  await mkdir7(outDir, { recursive: true });
19469
- if ((await readdir18(outDir)).length > 0) {
19370
+ if ((await readdir17(outDir)).length > 0) {
19470
19371
  throw new Error(
19471
19372
  `view output directory ${outDir} is not empty \u2014 pass a new directory so one directory holds exactly one view`
19472
19373
  );
@@ -19478,17 +19379,17 @@ async function projectSessionBundle(opts) {
19478
19379
  const candidates = [];
19479
19380
  for (const path of await listSessionBundleFiles(sourceDir)) {
19480
19381
  if (path === "manifest.json") continue;
19481
- const bytes2 = await readFile16(join31(sourceDir, path));
19382
+ const bytes2 = await readFile16(join30(sourceDir, path));
19482
19383
  const sha2562 = createHash17("sha256").update(bytes2).digest("hex");
19483
19384
  const recorded = sourceHashes.get(path);
19484
19385
  if (!recorded) {
19485
19386
  throw new Error(
19486
- `${join31(sourceDir, path)} is not listed in the bundle manifest \u2014 the bundle changed after assembly and cannot be projected; re-run \`traces bundle\``
19387
+ `${join30(sourceDir, path)} is not listed in the bundle manifest \u2014 the bundle changed after assembly and cannot be projected; re-run \`traces bundle\``
19487
19388
  );
19488
19389
  }
19489
19390
  if (recorded.sha256 !== sha2562) {
19490
19391
  throw new Error(
19491
- `${join31(sourceDir, path)} does not match its manifest hash (${recorded.sha256} recorded, ${sha2562} on disk) \u2014 the bundle changed after assembly and cannot be projected; re-run \`traces bundle\``
19392
+ `${join30(sourceDir, path)} does not match its manifest hash (${recorded.sha256} recorded, ${sha2562} on disk) \u2014 the bundle changed after assembly and cannot be projected; re-run \`traces bundle\``
19492
19393
  );
19493
19394
  }
19494
19395
  const verdict = classifyEvidenceOnlyPath(path);
@@ -19524,7 +19425,7 @@ async function projectSessionBundle(opts) {
19524
19425
  });
19525
19426
  continue;
19526
19427
  }
19527
- const target = join31(outDir, candidate.path);
19428
+ const target = join30(outDir, candidate.path);
19528
19429
  await mkdir7(dirname11(target), { recursive: true });
19529
19430
  await writeFile11(target, candidate.bytes);
19530
19431
  carriedPaths.push(candidate.path);
@@ -19541,7 +19442,7 @@ async function projectSessionBundle(opts) {
19541
19442
  })),
19542
19443
  matches: 0
19543
19444
  };
19544
- const sourceManifestBytes = await readFile16(join31(sourceDir, "manifest.json"));
19445
+ const sourceManifestBytes = await readFile16(join30(sourceDir, "manifest.json"));
19545
19446
  const manifest = {
19546
19447
  schemaVersion: 2,
19547
19448
  kind: "traces.session_bundle",
@@ -19564,14 +19465,14 @@ async function projectSessionBundle(opts) {
19564
19465
  }
19565
19466
 
19566
19467
  // src/diff.ts
19567
- import { stat as stat17 } from "fs/promises";
19468
+ import { stat as stat16 } from "fs/promises";
19568
19469
  import { ATTR as ATTR5 } from "@tangle-network/agent-trace-contract";
19569
19470
  import { ingestSpans as ingestSpans2 } from "@tangle-network/agent-eval/diagnosis";
19570
19471
  import { diffSteps, diffStepsFromSpans } from "@tangle-network/agent-eval/pipelines";
19571
19472
  async function readSpans(path) {
19572
19473
  const otlp = await readOtlpInput(path);
19573
19474
  if (otlp.spans.length > 0) return [...otlp.spans];
19574
- if (!(await stat17(path)).isFile()) {
19475
+ if (!(await stat16(path)).isFile()) {
19575
19476
  throw new Error(`${path}: no OTLP spans found (${otlp.issues.length} unusable row(s))`);
19576
19477
  }
19577
19478
  return (await exportTraceEvidenceFile(path)).spans;
@@ -19728,12 +19629,12 @@ function renderRunDiff(report) {
19728
19629
 
19729
19630
  // src/upload-state.ts
19730
19631
  import { mkdir as mkdir8, readFile as readFile17, writeFile as writeFile12 } from "fs/promises";
19731
- import { homedir as homedir11 } from "os";
19732
- import { dirname as dirname12, join as join32 } from "path";
19632
+ import { homedir as homedir10 } from "os";
19633
+ import { dirname as dirname12, join as join31 } from "path";
19733
19634
  import { contentHash } from "@tangle-network/agent-eval";
19734
19635
  function stateFile() {
19735
- const base = process.env.XDG_STATE_HOME ?? join32(homedir11(), ".local", "state");
19736
- return join32(base, "tangle-traces", "uploaded.json");
19636
+ const base = process.env.XDG_STATE_HOME ?? join31(homedir10(), ".local", "state");
19637
+ return join31(base, "tangle-traces", "uploaded.json");
19737
19638
  }
19738
19639
  function uploadKey(harness, sessionId) {
19739
19640
  return `${harness}:${sessionId}`;
@@ -19765,7 +19666,7 @@ function alreadyUploaded(state, harness, sessionId, hash2) {
19765
19666
  import { readFile as readFile18 } from "fs/promises";
19766
19667
  import { createRequire as createRequire2 } from "module";
19767
19668
  import { hostname as hostname2 } from "os";
19768
- import { basename as basename14, join as join33 } from "path";
19669
+ import { basename as basename13, join as join32 } from "path";
19769
19670
  import { hostedClientFromEnv } from "@tangle-network/agent-eval/hosted";
19770
19671
  import { assessShareSafety as assessShareSafety2, REDACTION_VERSION, redact as redact2, shareAllowed } from "@tangle-network/agent-eval/traces";
19771
19672
  var require2 = createRequire2(import.meta.url);
@@ -19789,7 +19690,7 @@ async function planUpload(opts = {}) {
19789
19690
  async function gitBranch(cwd) {
19790
19691
  if (!cwd) return void 0;
19791
19692
  try {
19792
- const head = await readFile18(join33(cwd, ".git", "HEAD"), "utf8");
19693
+ const head = await readFile18(join32(cwd, ".git", "HEAD"), "utf8");
19793
19694
  const m = head.match(/^ref:\s*refs\/heads\/(.+)$/m);
19794
19695
  return m?.[1]?.trim();
19795
19696
  } catch {
@@ -19799,7 +19700,7 @@ async function gitBranch(cwd) {
19799
19700
  async function sessionMeta(item) {
19800
19701
  const meta = {
19801
19702
  [ATTR.HARNESS]: item.ref.harness,
19802
- [ATTR.SESSION_FILE]: basename14(item.ref.path),
19703
+ [ATTR.SESSION_FILE]: basename13(item.ref.path),
19803
19704
  [ATTR.HOST]: hostname2(),
19804
19705
  [ATTR.UPLOADER]: `tangle-traces@${TRACES_VERSION}`,
19805
19706
  [ATTR.REDACTION_VERSION]: REDACTION_VERSION,
@@ -19964,8 +19865,8 @@ async function executeUpload(plan, opts = {}) {
19964
19865
  }
19965
19866
 
19966
19867
  // src/verify-safe.ts
19967
- import { lstat as lstat4, readdir as readdir19, readFile as readFile19 } from "fs/promises";
19968
- import { basename as basename15, extname, join as join34, relative as relative7 } from "path";
19868
+ import { lstat as lstat4, readdir as readdir18, readFile as readFile19 } from "fs/promises";
19869
+ import { basename as basename14, extname, join as join33, relative as relative7 } from "path";
19969
19870
  import {
19970
19871
  assessShareSafety as assessShareSafety3,
19971
19872
  combineVerdicts as combineVerdicts2
@@ -19978,7 +19879,7 @@ async function verifySafe(target, options = {}) {
19978
19879
  const unreadable = [];
19979
19880
  const files = await listFiles(target, unreadable);
19980
19881
  for (const file of files) {
19981
- const label2 = relative7(target, file) || basename15(file);
19882
+ const label2 = relative7(target, file) || basename14(file);
19982
19883
  let bytes2;
19983
19884
  try {
19984
19885
  bytes2 = await readFile19(file);
@@ -20011,22 +19912,22 @@ async function verifySafe(target, options = {}) {
20011
19912
  return { ...combineVerdicts2(profile, verdicts, unreadable), target, files: files.length };
20012
19913
  }
20013
19914
  async function listFiles(target, unreadable) {
20014
- let stat19;
19915
+ let stat18;
20015
19916
  try {
20016
- stat19 = await lstat4(target);
19917
+ stat18 = await lstat4(target);
20017
19918
  } catch (error) {
20018
19919
  unreadable.push(`${target}: ${error instanceof Error ? error.message : String(error)}`);
20019
19920
  return [];
20020
19921
  }
20021
- if (stat19.isFile()) return [target];
20022
- if (!stat19.isDirectory()) {
19922
+ if (stat18.isFile()) return [target];
19923
+ if (!stat18.isDirectory()) {
20023
19924
  unreadable.push(`${target}: not a regular file or directory`);
20024
19925
  return [];
20025
19926
  }
20026
19927
  const out = [];
20027
19928
  const walk = async (dir) => {
20028
- for (const entry of (await readdir19(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
20029
- const path = join34(dir, entry.name);
19929
+ for (const entry of (await readdir18(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
19930
+ const path = join33(dir, entry.name);
20030
19931
  if (entry.isDirectory()) await walk(path);
20031
19932
  else if (entry.isFile()) out.push(path);
20032
19933
  else unreadable.push(`${relative7(target, path)}: not a regular file`);
@@ -20078,9 +19979,9 @@ function formatVerdict(result) {
20078
19979
  }
20079
19980
 
20080
19981
  // src/skill-usage.ts
20081
- import { mkdir as mkdir9, open as open3, readdir as readdir20, readFile as readFile20, rename as rename3, stat as stat18, writeFile as writeFile13 } from "fs/promises";
20082
- import { homedir as homedir12 } from "os";
20083
- import { dirname as dirname13, join as join35 } from "path";
19982
+ import { mkdir as mkdir9, open as open3, readdir as readdir19, readFile as readFile20, rename as rename3, stat as stat17, writeFile as writeFile13 } from "fs/promises";
19983
+ import { homedir as homedir11 } from "os";
19984
+ import { dirname as dirname13, join as join34 } from "path";
20084
19985
  import { STORES } from "@tangle-network/harness-sessions/catalog";
20085
19986
  var CHUNK_BYTES = 8 * 1024 * 1024;
20086
19987
  var NEWLINE = 10;
@@ -20103,16 +20004,16 @@ var SKILL_READ_VERB = /(?:^|[\s;&|(`'"])(?:cat|sed|head|tail|less|more|awk|nl|ba
20103
20004
  var SKILL_DOCUMENT = /(?:^|[\s'"=:(`])((?:[^\s'"`;|&()]*\/)?([A-Za-z0-9][A-Za-z0-9._-]*))\/SKILL\.md\b/g;
20104
20005
  var SESSION_UUID = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/;
20105
20006
  function defaultSkillUsageSources() {
20106
- const codexHome = process.env.CODEX_HOME ?? join35(homedir12(), ".codex");
20007
+ const codexHome = process.env.CODEX_HOME ?? join34(homedir11(), ".codex");
20107
20008
  return {
20108
- claudeProjects: join35(homedir12(), STORES["claude-code.projects-jsonl"].root),
20109
- codexSessions: [join35(codexHome, ...STORES["codex.rollout-jsonl"].root.split("/").slice(1)), join35(codexHome, "archived_sessions")],
20110
- kimiSessions: join35(homedir12(), STORES["kimi.session-dir"].root)
20009
+ claudeProjects: join34(homedir11(), STORES["claude-code.projects-jsonl"].root),
20010
+ codexSessions: [join34(codexHome, ...STORES["codex.rollout-jsonl"].root.split("/").slice(1)), join34(codexHome, "archived_sessions")],
20011
+ kimiSessions: join34(homedir11(), STORES["kimi.session-dir"].root)
20111
20012
  };
20112
20013
  }
20113
20014
  function defaultSkillUsageStorePath() {
20114
- const state = process.env.XDG_STATE_HOME ?? join35(homedir12(), ".local", "state");
20115
- return join35(state, "traces", "skill-usage.json");
20015
+ const state = process.env.XDG_STATE_HOME ?? join34(homedir11(), ".local", "state");
20016
+ return join34(state, "traces", "skill-usage.json");
20116
20017
  }
20117
20018
  function eventKey(e) {
20118
20019
  return `${e.harness}\0${e.id}`;
@@ -20196,7 +20097,7 @@ var SkillUsageStore = class _SkillUsageStore {
20196
20097
  async refreshFile(harness, path) {
20197
20098
  let info;
20198
20099
  try {
20199
- info = await stat18(path);
20100
+ info = await stat17(path);
20200
20101
  } catch (error) {
20201
20102
  if (error.code === "ENOENT") return null;
20202
20103
  throw error;
@@ -20463,37 +20364,37 @@ async function jsonlFiles(roots, name) {
20463
20364
  for (const root of roots) {
20464
20365
  let entries;
20465
20366
  try {
20466
- entries = await readdir20(root, { recursive: true, withFileTypes: true });
20367
+ entries = await readdir19(root, { recursive: true, withFileTypes: true });
20467
20368
  } catch (error) {
20468
20369
  if (error.code === "ENOENT") continue;
20469
20370
  throw error;
20470
20371
  }
20471
20372
  for (const entry of entries) {
20472
- if (entry.isFile() && (name ? entry.name === name : entry.name.endsWith(".jsonl"))) files.push(join35(entry.parentPath, entry.name));
20373
+ if (entry.isFile() && (name ? entry.name === name : entry.name.endsWith(".jsonl"))) files.push(join34(entry.parentPath, entry.name));
20473
20374
  }
20474
20375
  }
20475
20376
  return files.sort();
20476
20377
  }
20477
20378
  function defaultSkillCatalogRoots() {
20478
- const codexHome = process.env.CODEX_HOME ?? join35(homedir12(), ".codex");
20379
+ const codexHome = process.env.CODEX_HOME ?? join34(homedir11(), ".codex");
20479
20380
  return {
20480
- claudeHome: join35(homedir12(), ".claude"),
20481
- codexSkillDirs: [join35(codexHome, "skills"), join35(codexHome, "skills", ".system"), join35(homedir12(), ".agents", "skills")]
20381
+ claudeHome: join34(homedir11(), ".claude"),
20382
+ codexSkillDirs: [join34(codexHome, "skills"), join34(codexHome, "skills", ".system"), join34(homedir11(), ".agents", "skills")]
20482
20383
  };
20483
20384
  }
20484
20385
  async function skillFolders(directory, prefix = "") {
20485
20386
  let entries;
20486
20387
  try {
20487
- entries = await readdir20(directory);
20388
+ entries = await readdir19(directory);
20488
20389
  } catch {
20489
20390
  return [];
20490
20391
  }
20491
20392
  const found = [];
20492
20393
  for (const entry of entries.sort()) {
20493
20394
  if (entry.startsWith(".")) continue;
20494
- const path = join35(directory, entry);
20395
+ const path = join34(directory, entry);
20495
20396
  try {
20496
- await stat18(join35(path, "SKILL.md"));
20397
+ await stat17(join34(path, "SKILL.md"));
20497
20398
  found.push({ name: `${prefix}${entry}`, path });
20498
20399
  } catch {
20499
20400
  }
@@ -20510,19 +20411,19 @@ async function readJsonObject(path) {
20510
20411
  }
20511
20412
  async function readInstalledSkills(roots = defaultSkillCatalogRoots()) {
20512
20413
  const installed = [];
20513
- for (const skill of await skillFolders(join35(roots.claudeHome, "skills"))) {
20414
+ for (const skill of await skillFolders(join34(roots.claudeHome, "skills"))) {
20514
20415
  installed.push({ ...skill, harness: "claude-code" });
20515
20416
  }
20516
- const settings = await readJsonObject(join35(roots.claudeHome, "settings.json"));
20417
+ const settings = await readJsonObject(join34(roots.claudeHome, "settings.json"));
20517
20418
  const enabled = settings?.enabledPlugins ?? {};
20518
- const plugins = await readJsonObject(join35(roots.claudeHome, "plugins", "installed_plugins.json"));
20419
+ const plugins = await readJsonObject(join34(roots.claudeHome, "plugins", "installed_plugins.json"));
20519
20420
  const pluginEntries = plugins?.plugins ?? {};
20520
20421
  for (const [key, value] of Object.entries(pluginEntries)) {
20521
20422
  if (enabled[key] !== true) continue;
20522
20423
  const plugin = key.split("@", 1)[0];
20523
20424
  for (const install of Array.isArray(value) ? value : [value]) {
20524
20425
  if (typeof install?.installPath !== "string") continue;
20525
- for (const skill of await skillFolders(join35(install.installPath, "skills"), `${plugin}:`)) {
20426
+ for (const skill of await skillFolders(join34(install.installPath, "skills"), `${plugin}:`)) {
20526
20427
  installed.push({ ...skill, harness: "claude-code" });
20527
20428
  }
20528
20429
  }
@@ -20695,7 +20596,6 @@ export {
20695
20596
  CodexExecStreamError,
20696
20597
  CodexExecAdapter,
20697
20598
  CopilotAdapter,
20698
- ForgeAdapter,
20699
20599
  GeminiAdapter,
20700
20600
  textIsSynthetic,
20701
20601
  looksLikeAgentPrompt,
@@ -20865,7 +20765,7 @@ export {
20865
20765
  ms,
20866
20766
  usd,
20867
20767
  zeroPricedCost,
20868
- tokens2 as tokens,
20768
+ tokens,
20869
20769
  STATUS_MARK,
20870
20770
  connectors,
20871
20771
  forEachTreeNode,