@openscout/scout 0.2.73 → 0.2.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/bin/scoutd +0 -0
  2. package/dist/build-manifest.json +9 -0
  3. package/dist/client/assets/{RepoDiffViewer-D8gg36W3.js → RepoDiffViewer-CTXJvjIL.js} +1 -1
  4. package/dist/client/assets/{addon-fit-D4KdY-pj.js → addon-fit-3IrvLm2n.js} +1 -1
  5. package/dist/client/assets/{addon-webgl-Bo_tmKBp.js → addon-webgl-BgxIDUI-.js} +1 -1
  6. package/dist/client/assets/{arc.es-D0gujIKy.js → arc.es-Bh8P_xre.js} +1 -1
  7. package/dist/client/assets/c-BIGW1oBm.js +1 -0
  8. package/dist/client/assets/cpp-DIPi6g--.js +1 -0
  9. package/dist/client/assets/css-CLj8gQPS.js +1 -0
  10. package/dist/client/assets/dart-bE4Kk8sk.js +1 -0
  11. package/dist/client/assets/docker-BcOcwvcX.js +1 -0
  12. package/dist/client/assets/{embed-entry-CUVNwyB_.js → embed-entry-wAEtYUEM.js} +1 -1
  13. package/dist/client/assets/go-C27-OAKa.js +1 -0
  14. package/dist/client/assets/html-pp8916En.js +1 -0
  15. package/dist/client/assets/index-BK3mRYyN.js +272 -0
  16. package/dist/client/assets/index-Dm1ZQS9G.css +1 -0
  17. package/dist/client/assets/java-CylS5w8V.js +1 -0
  18. package/dist/client/assets/javascript-wDzz0qaB.js +1 -0
  19. package/dist/client/assets/json-Cp-IABpG.js +1 -0
  20. package/dist/client/assets/jsx-g9-lgVsj.js +1 -0
  21. package/dist/client/assets/kotlin-BdnUsdx6.js +1 -0
  22. package/dist/client/assets/make-CHLpvVh8.js +1 -0
  23. package/dist/client/assets/markdown-Cvjx9yec.js +1 -0
  24. package/dist/client/assets/objective-c-DXmwc3jG.js +1 -0
  25. package/dist/client/assets/proto-C7zT0LnQ.js +1 -0
  26. package/dist/client/assets/python-B6aJPvgy.js +1 -0
  27. package/dist/client/assets/ruby-B13GW9FM.js +1 -0
  28. package/dist/client/assets/rust-B1yitclQ.js +1 -0
  29. package/dist/client/assets/scss-D5BDwBP9.js +1 -0
  30. package/dist/client/assets/shellscript-Yzrsuije.js +1 -0
  31. package/dist/client/assets/sql-CRqJ_cUM.js +1 -0
  32. package/dist/client/assets/swift-D82vCrfD.js +1 -0
  33. package/dist/client/assets/toml-vGWfd6FD.js +1 -0
  34. package/dist/client/assets/tsx-COt5Ahok.js +1 -0
  35. package/dist/client/assets/typescript-BPQ3VLAy.js +1 -0
  36. package/dist/client/assets/wasm-CG6Dc4jp.js +1 -0
  37. package/dist/client/assets/xml-sdJ4AIDG.js +1 -0
  38. package/dist/client/assets/{xterm-RfflDFod.js → xterm-CoGJTxj9.js} +1 -1
  39. package/dist/client/assets/yaml-Buea-lGh.js +1 -0
  40. package/dist/client/index.html +2 -2
  41. package/dist/main.mjs +887 -584
  42. package/dist/node/main.mjs +115 -1
  43. package/dist/pairing-runtime-controller.mjs +2525 -895
  44. package/dist/runtime/base-daemon.mjs +77 -20
  45. package/dist/runtime/broker-daemon.mjs +1403 -705
  46. package/dist/runtime/broker-process-manager.mjs +29 -0
  47. package/dist/runtime/mesh-discover.mjs +29 -0
  48. package/dist/scout-control-plane-web.mjs +2970 -1116
  49. package/dist/scout-web-server.mjs +2970 -1116
  50. package/package.json +1 -1
  51. package/dist/client/assets/index-CRkjiso5.js +0 -257
  52. package/dist/client/assets/index-D_RX2cRb.css +0 -1
@@ -16,12 +16,12 @@ var __export = (target, all) => {
16
16
  var __require = import.meta.require;
17
17
 
18
18
  // packages/runtime/src/broker-daemon.ts
19
- import { createHash as createHash4, randomUUID as randomUUID5 } from "crypto";
19
+ import { createHash as createHash5, randomUUID as randomUUID5 } from "crypto";
20
20
  import { createServer } from "http";
21
21
  import { mkdir as mkdir11, readFile as readFile12, rename, stat as stat7, unlink as unlink2, writeFile as writeFile10 } from "fs/promises";
22
22
  import { createRequire as createRequire2 } from "module";
23
23
  import { hostname as hostname4 } from "os";
24
- import { basename as basename22, dirname as dirname25, join as join40, resolve as resolve20 } from "path";
24
+ import { basename as basename23, dirname as dirname26, join as join42, resolve as resolve20 } from "path";
25
25
 
26
26
  // node_modules/.bun/@trpc+server@11.16.0+1fb4c65d43e298b9/node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
27
27
  function mergeWithoutOverrides(obj1, ...objs) {
@@ -17392,6 +17392,7 @@ var DEFAULT_HOT_DISCOVERY_LIMIT = 64;
17392
17392
  var DEFAULT_SHALLOW_DISCOVERY_LIMIT = 160;
17393
17393
  var DEFAULT_DEEP_DISCOVERY_LIMIT = 160;
17394
17394
  var HEAD_READ_BYTES = 256 * 1024;
17395
+ var TAIL_READ_BYTES = 512 * 1024;
17395
17396
  var METADATA_CACHE_LIMIT = 512;
17396
17397
  var metadataCache = new Map;
17397
17398
  function rememberMetadata(file2, metadata) {
@@ -17452,6 +17453,27 @@ function readFileHead(filePath) {
17452
17453
  }
17453
17454
  }
17454
17455
  }
17456
+ function readFileTail(file2) {
17457
+ let fd = null;
17458
+ try {
17459
+ fd = openSync(file2.path, "r");
17460
+ const start = Math.max(0, file2.size - TAIL_READ_BYTES);
17461
+ const buffer = new Uint8Array(Math.min(file2.size, TAIL_READ_BYTES));
17462
+ const bytesRead = readSync(fd, buffer, 0, buffer.length, start);
17463
+ return {
17464
+ content: Buffer.from(buffer.subarray(0, bytesRead)).toString("utf8"),
17465
+ startsAtBeginning: start === 0
17466
+ };
17467
+ } catch {
17468
+ return { content: "", startsAtBeginning: false };
17469
+ } finally {
17470
+ if (fd != null) {
17471
+ try {
17472
+ closeSync(fd);
17473
+ } catch {}
17474
+ }
17475
+ }
17476
+ }
17455
17477
  function parseJsonRecord(line) {
17456
17478
  try {
17457
17479
  const value = JSON.parse(line);
@@ -17463,7 +17485,11 @@ function parseJsonRecord(line) {
17463
17485
  function readClaudeMetadata(file2) {
17464
17486
  const cached2 = metadataCache.get(file2.path);
17465
17487
  if (cached2 && cached2.mtimeMs === file2.mtimeMs && cached2.size === file2.size) {
17466
- return { cwd: cached2.cwd, sessionId: cached2.sessionId };
17488
+ return {
17489
+ cwd: cached2.cwd,
17490
+ sessionId: cached2.sessionId,
17491
+ lastEventAt: cached2.lastEventAt
17492
+ };
17467
17493
  }
17468
17494
  const head = readFileHead(file2.path);
17469
17495
  let cwd = null;
@@ -17474,11 +17500,23 @@ function readClaudeMetadata(file2) {
17474
17500
  continue;
17475
17501
  cwd ??= typeof record2.cwd === "string" && record2.cwd.trim() ? record2.cwd : null;
17476
17502
  sessionId ??= typeof record2.sessionId === "string" && record2.sessionId.trim() ? record2.sessionId : typeof record2.session_id === "string" && record2.session_id.trim() ? record2.session_id : null;
17477
- if (cwd && sessionId) {
17478
- return rememberMetadata(file2, { cwd, sessionId });
17479
- }
17503
+ if (cwd && sessionId)
17504
+ break;
17480
17505
  }
17481
- return rememberMetadata(file2, { cwd, sessionId });
17506
+ const tail = readFileTail(file2);
17507
+ const tailLines = tail.content.split(/\r?\n/);
17508
+ if (!tail.startsAtBeginning)
17509
+ tailLines.shift();
17510
+ let lastEventAt = null;
17511
+ for (let index = tailLines.length - 1;index >= 0; index -= 1) {
17512
+ const record2 = parseJsonRecord(tailLines[index]?.trim() ?? "");
17513
+ if (!record2)
17514
+ continue;
17515
+ lastEventAt = pickTimestamp(record2);
17516
+ if (lastEventAt != null)
17517
+ break;
17518
+ }
17519
+ return rememberMetadata(file2, { cwd, sessionId, lastEventAt });
17482
17520
  }
17483
17521
  function decodeProjectDir(dirName) {
17484
17522
  if (!dirName.startsWith("-"))
@@ -17705,6 +17743,7 @@ var ClaudeSource = {
17705
17743
  cwd,
17706
17744
  project: cwd ? basename(cwd) : projectDirNameForPath(file2.path) ?? "(unknown)",
17707
17745
  harness: "unattributed",
17746
+ lastEventAt: meta3.lastEventAt,
17708
17747
  mtimeMs: file2.mtimeMs,
17709
17748
  size: file2.size
17710
17749
  };
@@ -18818,20 +18857,32 @@ var GrokSource = {
18818
18857
  }
18819
18858
  };
18820
18859
 
18821
- // packages/runtime/src/tail/opencode-source.ts
18822
- import { closeSync as closeSync5, existsSync as existsSync6, openSync as openSync5, readdirSync as readdirSync5, readFileSync as readFileSync2, readSync as readSync5, statSync as statSync5 } from "fs";
18860
+ // packages/runtime/src/tail/kimi-source.ts
18861
+ import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync2, statSync as statSync5 } from "fs";
18823
18862
  import { homedir as homedir6 } from "os";
18824
- import { basename as basename5, join as join6, sep } from "path";
18825
- var SOURCE_NAME5 = "opencode";
18863
+ import { basename as basename5, dirname as dirname2, join as join6 } from "path";
18864
+ var SOURCE_NAME5 = "kimi";
18826
18865
  var MAX_SUMMARY_LEN5 = 200;
18827
18866
  var DEFAULT_HOT_DISCOVERY_WINDOW_MS5 = 10 * 60 * 1000;
18828
18867
  var DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS5 = 24 * 60 * 60 * 1000;
18829
18868
  var DEFAULT_DEEP_DISCOVERY_WINDOW_MS5 = 24 * 60 * 60 * 1000;
18830
- var DEFAULT_HOT_DISCOVERY_LIMIT5 = 32;
18831
- var DEFAULT_SHALLOW_DISCOVERY_LIMIT5 = 80;
18832
- var DEFAULT_DEEP_DISCOVERY_LIMIT5 = 80;
18833
- var DEFAULT_MESSAGES_PER_SESSION = 50;
18834
- var HEAD_READ_BYTES5 = 128 * 1024;
18869
+ var DEFAULT_HOT_DISCOVERY_LIMIT5 = 96;
18870
+ var DEFAULT_SHALLOW_DISCOVERY_LIMIT5 = 256;
18871
+ var DEFAULT_DEEP_DISCOVERY_LIMIT5 = 256;
18872
+ var METADATA_CACHE_LIMIT4 = 512;
18873
+ var TOOL_CALL_STATE_KEY2 = "kimiToolCallSummaries";
18874
+ var TOOL_CALL_STATE_LIMIT2 = 512;
18875
+ var metadataCache4 = new Map;
18876
+ function recordValue(value) {
18877
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
18878
+ }
18879
+ function parseJsonRecord5(line) {
18880
+ try {
18881
+ return recordValue(JSON.parse(line));
18882
+ } catch {
18883
+ return null;
18884
+ }
18885
+ }
18835
18886
  function readPositiveIntEnv5(names, fallback) {
18836
18887
  for (const name of names) {
18837
18888
  const raw = Number.parseInt(process.env[name] ?? "", 10);
@@ -18842,22 +18893,336 @@ function readPositiveIntEnv5(names, fallback) {
18842
18893
  }
18843
18894
  function discoveryWindowMs5(scope) {
18844
18895
  const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_WINDOW_MS5 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_WINDOW_MS5 : DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS5;
18845
- const scopedName = `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_WINDOW_MS`;
18846
- return readPositiveIntEnv5([scopedName, "OPENSCOUT_TAIL_DISCOVERY_WINDOW_MS"], fallback);
18896
+ return readPositiveIntEnv5([
18897
+ `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_WINDOW_MS`,
18898
+ "OPENSCOUT_TAIL_DISCOVERY_WINDOW_MS"
18899
+ ], fallback);
18847
18900
  }
18848
18901
  function discoveryLimit5(scope) {
18849
18902
  const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_LIMIT5 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_LIMIT5 : DEFAULT_SHALLOW_DISCOVERY_LIMIT5;
18903
+ return readPositiveIntEnv5([
18904
+ `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_LIMIT`,
18905
+ "OPENSCOUT_TAIL_DISCOVERY_LIMIT"
18906
+ ], fallback);
18907
+ }
18908
+ function kimiSessionsRoot() {
18909
+ const explicit = process.env.OPENSCOUT_TAIL_KIMI_SESSIONS_ROOT?.trim();
18910
+ if (explicit)
18911
+ return explicit;
18912
+ const kimiHome = process.env.KIMI_CODE_HOME?.trim() || join6(homedir6(), ".kimi-code");
18913
+ return join6(kimiHome, "sessions");
18914
+ }
18915
+ function isKimiProcess(command) {
18916
+ const base = commandBasename2(command);
18917
+ return base === "kimi" || command.includes("/.kimi-code/bin/kimi");
18918
+ }
18919
+ async function discoverKimiProcesses() {
18920
+ const all = await listProcesses();
18921
+ const byPid = new Map;
18922
+ for (const proc of all)
18923
+ byPid.set(proc.pid, proc);
18924
+ const out = [];
18925
+ await Promise.all(all.filter((proc) => isKimiProcess(proc.command)).map(async (proc) => {
18926
+ const cwd = await readCwd(proc.pid);
18927
+ const parentChain = buildParentChain(proc.pid, byPid);
18928
+ out.push({
18929
+ pid: proc.pid,
18930
+ ppid: proc.ppid,
18931
+ command: proc.command,
18932
+ etime: proc.etime,
18933
+ cwd,
18934
+ harness: classifyAttribution(parentChain),
18935
+ parentChain,
18936
+ source: SOURCE_NAME5
18937
+ });
18938
+ }));
18939
+ out.sort((left, right) => left.pid - right.pid);
18940
+ return out;
18941
+ }
18942
+ function walkRecentKimiWireFiles(root, scope) {
18943
+ if (!existsSync6(root))
18944
+ return [];
18945
+ const cutoff = Date.now() - discoveryWindowMs5(scope);
18946
+ const found = [];
18947
+ const stack = [root];
18948
+ while (stack.length > 0) {
18949
+ const directory = stack.pop();
18950
+ let entries = [];
18951
+ try {
18952
+ entries = readdirSync5(directory);
18953
+ } catch {
18954
+ continue;
18955
+ }
18956
+ for (const entry of entries) {
18957
+ const path = join6(directory, entry);
18958
+ let stats;
18959
+ try {
18960
+ stats = statSync5(path);
18961
+ } catch {
18962
+ continue;
18963
+ }
18964
+ if (stats.isDirectory()) {
18965
+ stack.push(path);
18966
+ } else if (entry === "wire.jsonl" && stats.mtimeMs >= cutoff) {
18967
+ found.push({ path, mtimeMs: stats.mtimeMs, size: stats.size });
18968
+ }
18969
+ }
18970
+ }
18971
+ return found.sort((left, right) => right.mtimeMs - left.mtimeMs).slice(0, discoveryLimit5(scope));
18972
+ }
18973
+ function readKimiTranscriptMetadata(file2) {
18974
+ const cached2 = metadataCache4.get(file2.path);
18975
+ if (cached2 && cached2.mtimeMs === file2.mtimeMs && cached2.size === file2.size) {
18976
+ return cached2;
18977
+ }
18978
+ const agentId = basename5(dirname2(file2.path));
18979
+ const sessionDirectory = dirname2(dirname2(dirname2(file2.path)));
18980
+ const parentSessionId = basename5(sessionDirectory);
18981
+ let cwd = null;
18982
+ let title = null;
18983
+ try {
18984
+ const state = recordValue(JSON.parse(readFileSync2(join6(sessionDirectory, "state.json"), "utf8")));
18985
+ cwd = typeof state?.workDir === "string" && state.workDir.trim() ? state.workDir.trim() : null;
18986
+ title = typeof state?.title === "string" && state.title.trim() ? state.title.trim() : null;
18987
+ } catch {}
18988
+ const metadata = {
18989
+ cwd,
18990
+ parentSessionId,
18991
+ agentId,
18992
+ sessionId: agentId === "main" ? parentSessionId : `${parentSessionId}:${agentId}`,
18993
+ title
18994
+ };
18995
+ metadataCache4.delete(file2.path);
18996
+ metadataCache4.set(file2.path, { ...file2, ...metadata });
18997
+ while (metadataCache4.size > METADATA_CACHE_LIMIT4) {
18998
+ const oldest = metadataCache4.keys().next().value;
18999
+ if (!oldest)
19000
+ break;
19001
+ metadataCache4.delete(oldest);
19002
+ }
19003
+ return metadata;
19004
+ }
19005
+ function discoverKimiTranscripts(scope) {
19006
+ return walkRecentKimiWireFiles(kimiSessionsRoot(), scope).map((file2) => {
19007
+ const metadata = readKimiTranscriptMetadata(file2);
19008
+ return {
19009
+ source: SOURCE_NAME5,
19010
+ transcriptPath: file2.path,
19011
+ sessionId: metadata.sessionId,
19012
+ cwd: metadata.cwd,
19013
+ project: metadata.cwd ? basename5(metadata.cwd) : "(unknown)",
19014
+ harness: "unattributed",
19015
+ mtimeMs: file2.mtimeMs,
19016
+ size: file2.size
19017
+ };
19018
+ });
19019
+ }
19020
+ function clip5(text, max = MAX_SUMMARY_LEN5) {
19021
+ const flat = text.replace(/\s+/gu, " ").trim();
19022
+ return flat.length <= max ? flat : `${flat.slice(0, max - 1)}\u2026`;
19023
+ }
19024
+ function parseTimestamp3(value) {
19025
+ if (typeof value === "number" && Number.isFinite(value)) {
19026
+ return value < 1000000000000 ? value * 1000 : value;
19027
+ }
19028
+ if (typeof value === "string" && value.trim()) {
19029
+ const parsed = Date.parse(value);
19030
+ return Number.isFinite(parsed) ? parsed : null;
19031
+ }
19032
+ return null;
19033
+ }
19034
+ function contentText(content) {
19035
+ if (typeof content === "string")
19036
+ return content.trim();
19037
+ if (!Array.isArray(content))
19038
+ return "";
19039
+ const parts = [];
19040
+ for (const item of content) {
19041
+ const part = recordValue(item);
19042
+ if (!part)
19043
+ continue;
19044
+ if (part.type === "text" && typeof part.text === "string")
19045
+ parts.push(part.text);
19046
+ else if (part.type === "image")
19047
+ parts.push("[image]");
19048
+ else if (part.type === "resource" || part.type === "resource_link")
19049
+ parts.push("[resource]");
19050
+ }
19051
+ return parts.join(" ").trim();
19052
+ }
19053
+ function toolCalls(ctx) {
19054
+ if (!ctx.state)
19055
+ return null;
19056
+ const existing = ctx.state[TOOL_CALL_STATE_KEY2];
19057
+ if (existing instanceof Map)
19058
+ return existing;
19059
+ const next = new Map;
19060
+ ctx.state[TOOL_CALL_STATE_KEY2] = next;
19061
+ return next;
19062
+ }
19063
+ function rememberToolCall2(ctx, id, summary) {
19064
+ if (!id)
19065
+ return;
19066
+ const calls = toolCalls(ctx);
19067
+ if (!calls)
19068
+ return;
19069
+ calls.delete(id);
19070
+ calls.set(id, summary);
19071
+ while (calls.size > TOOL_CALL_STATE_LIMIT2) {
19072
+ const oldest = calls.keys().next().value;
19073
+ if (!oldest)
19074
+ break;
19075
+ calls.delete(oldest);
19076
+ }
19077
+ }
19078
+ function eventIdentity(record2, lineOffset) {
19079
+ const event = recordValue(record2.event);
19080
+ const stable = [
19081
+ event?.uuid,
19082
+ event?.toolCallId,
19083
+ record2.toolCallId,
19084
+ record2.id
19085
+ ].find((value) => typeof value === "string" && value.trim());
19086
+ const type = typeof record2.type === "string" ? record2.type : "event";
19087
+ return `${type}:${typeof stable === "string" ? stable : `${String(record2.time ?? "na")}:${lineOffset}`}`;
19088
+ }
19089
+ function summarizeKimiRecord(record2, ctx) {
19090
+ const type = typeof record2.type === "string" ? record2.type : "";
19091
+ if (type === "turn.prompt") {
19092
+ return { kind: "user", summary: clip5(contentText(record2.input) || "[user]") };
19093
+ }
19094
+ if (type === "turn.steer") {
19095
+ const origin = recordValue(record2.origin);
19096
+ const status = typeof origin?.status === "string" ? origin.status : "update";
19097
+ return { kind: "system", summary: clip5(`background task ${status} \xB7 ${contentText(record2.input)}`) };
19098
+ }
19099
+ if (type === "turn.cancel") {
19100
+ return { kind: "system", summary: "turn cancelled" };
19101
+ }
19102
+ if (type === "permission.record_approval_result") {
19103
+ const result = recordValue(record2.result);
19104
+ const decision = typeof result?.decision === "string" ? result.decision : "recorded";
19105
+ const toolName = typeof record2.toolName === "string" ? record2.toolName : "tool";
19106
+ return { kind: "system", summary: clip5(`permission ${decision} \xB7 ${toolName}`) };
19107
+ }
19108
+ if (type === "plan_mode.enter" || type === "plan_mode.exit") {
19109
+ return { kind: "system", summary: type === "plan_mode.enter" ? "plan mode entered" : "plan mode exited" };
19110
+ }
19111
+ if (type === "full_compaction.begin" || type === "full_compaction.complete") {
19112
+ return { kind: "system", summary: type.endsWith("begin") ? "context compaction started" : "context compaction completed" };
19113
+ }
19114
+ if (type === "context.apply_compaction") {
19115
+ const summary = typeof record2.summary === "string" ? record2.summary : "";
19116
+ return { kind: "system", summary: clip5(`context compacted${summary ? ` \xB7 ${summary}` : ""}`) };
19117
+ }
19118
+ if (type !== "context.append_loop_event")
19119
+ return null;
19120
+ const event = recordValue(record2.event);
19121
+ const eventType = typeof event?.type === "string" ? event.type : "";
19122
+ if (eventType === "content.part") {
19123
+ const part = recordValue(event?.part);
19124
+ if (part?.type === "text" && typeof part.text === "string") {
19125
+ return { kind: "assistant", summary: clip5(part.text || "[assistant]") };
19126
+ }
19127
+ if (part?.type === "think" && typeof part.think === "string") {
19128
+ return { kind: "system", summary: clip5(`[thinking] ${part.think}`) };
19129
+ }
19130
+ return null;
19131
+ }
19132
+ if (eventType === "tool.call") {
19133
+ const name = typeof event?.name === "string" ? event.name : "tool";
19134
+ const summary = clip5(formatToolCall(name, event?.args));
19135
+ const callId = typeof event?.toolCallId === "string" ? event.toolCallId : "";
19136
+ rememberToolCall2(ctx, callId, summary);
19137
+ return { kind: "tool", summary };
19138
+ }
19139
+ if (eventType === "tool.result") {
19140
+ const callId = typeof event?.toolCallId === "string" ? event.toolCallId : "";
19141
+ return {
19142
+ kind: "tool-result",
19143
+ summary: clip5(formatToolResult(event?.result, toolCalls(ctx)?.get(callId)))
19144
+ };
19145
+ }
19146
+ return null;
19147
+ }
19148
+ function parseKimiLine(line, ctx) {
19149
+ const record2 = parseJsonRecord5(line.trim());
19150
+ if (!record2)
19151
+ return null;
19152
+ const parsed = summarizeKimiRecord(record2, ctx);
19153
+ if (!parsed)
19154
+ return null;
19155
+ const sessionId = ctx.transcript.sessionId ?? basename5(dirname2(dirname2(dirname2(ctx.transcriptPath))));
19156
+ const cwd = ctx.transcript.cwd ?? ctx.process.cwd ?? "";
19157
+ const nestedEvent = recordValue(record2.event);
19158
+ return {
19159
+ id: `${SOURCE_NAME5}:${sessionId}:${eventIdentity(record2, ctx.lineOffset)}`,
19160
+ ts: parseTimestamp3(record2.time) ?? parseTimestamp3(nestedEvent?.time) ?? parseTimestamp3(record2.created_at) ?? Date.now(),
19161
+ source: SOURCE_NAME5,
19162
+ sessionId,
19163
+ pid: ctx.process.pid,
19164
+ parentPid: ctx.process.ppid || null,
19165
+ project: cwd ? basename5(cwd) : ctx.transcript.project,
19166
+ cwd,
19167
+ harness: ctx.process.harness,
19168
+ kind: parsed.kind,
19169
+ summary: parsed.summary,
19170
+ raw: record2
19171
+ };
19172
+ }
19173
+ var KimiSource = {
19174
+ name: SOURCE_NAME5,
19175
+ discoverProcesses() {
19176
+ return discoverKimiProcesses();
19177
+ },
19178
+ discoverTranscripts(_processes, scope = "shallow") {
19179
+ return discoverKimiTranscripts(scope);
19180
+ },
19181
+ parseLine(line, ctx) {
19182
+ return parseKimiLine(line, ctx);
19183
+ }
19184
+ };
19185
+
19186
+ // packages/runtime/src/tail/opencode-source.ts
19187
+ import { closeSync as closeSync5, existsSync as existsSync7, openSync as openSync5, readdirSync as readdirSync6, readFileSync as readFileSync3, readSync as readSync5, statSync as statSync6 } from "fs";
19188
+ import { homedir as homedir7 } from "os";
19189
+ import { basename as basename6, join as join7, sep } from "path";
19190
+ var SOURCE_NAME6 = "opencode";
19191
+ var MAX_SUMMARY_LEN6 = 200;
19192
+ var DEFAULT_HOT_DISCOVERY_WINDOW_MS6 = 10 * 60 * 1000;
19193
+ var DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS6 = 24 * 60 * 60 * 1000;
19194
+ var DEFAULT_DEEP_DISCOVERY_WINDOW_MS6 = 24 * 60 * 60 * 1000;
19195
+ var DEFAULT_HOT_DISCOVERY_LIMIT6 = 32;
19196
+ var DEFAULT_SHALLOW_DISCOVERY_LIMIT6 = 80;
19197
+ var DEFAULT_DEEP_DISCOVERY_LIMIT6 = 80;
19198
+ var DEFAULT_MESSAGES_PER_SESSION = 50;
19199
+ var HEAD_READ_BYTES5 = 128 * 1024;
19200
+ function readPositiveIntEnv6(names, fallback) {
19201
+ for (const name of names) {
19202
+ const raw = Number.parseInt(process.env[name] ?? "", 10);
19203
+ if (Number.isFinite(raw) && raw > 0)
19204
+ return raw;
19205
+ }
19206
+ return fallback;
19207
+ }
19208
+ function discoveryWindowMs6(scope) {
19209
+ const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_WINDOW_MS6 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_WINDOW_MS6 : DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS6;
19210
+ const scopedName = `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_WINDOW_MS`;
19211
+ return readPositiveIntEnv6([scopedName, "OPENSCOUT_TAIL_DISCOVERY_WINDOW_MS"], fallback);
19212
+ }
19213
+ function discoveryLimit6(scope) {
19214
+ const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_LIMIT6 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_LIMIT6 : DEFAULT_SHALLOW_DISCOVERY_LIMIT6;
18850
19215
  const scopedName = `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_LIMIT`;
18851
- return readPositiveIntEnv5([scopedName, "OPENSCOUT_TAIL_DISCOVERY_LIMIT"], fallback);
19216
+ return readPositiveIntEnv6([scopedName, "OPENSCOUT_TAIL_DISCOVERY_LIMIT"], fallback);
18852
19217
  }
18853
19218
  function messagesPerSession() {
18854
- return readPositiveIntEnv5(["OPENSCOUT_TAIL_OPENCODE_MESSAGES_PER_SESSION"], DEFAULT_MESSAGES_PER_SESSION);
19219
+ return readPositiveIntEnv6(["OPENSCOUT_TAIL_OPENCODE_MESSAGES_PER_SESSION"], DEFAULT_MESSAGES_PER_SESSION);
18855
19220
  }
18856
19221
  function opencodeStorageRoots() {
18857
19222
  const explicit = process.env.OPENSCOUT_TAIL_OPENCODE_STORAGE_ROOT;
18858
19223
  if (explicit?.trim())
18859
19224
  return [explicit.trim()];
18860
- return [join6(homedir6(), ".local", "share", "opencode", "storage")].filter((root) => existsSync6(root));
19225
+ return [join7(homedir7(), ".local", "share", "opencode", "storage")].filter((root) => existsSync7(root));
18861
19226
  }
18862
19227
  function isOpenCodeProcess(command) {
18863
19228
  const base = commandBasename2(command).toLowerCase();
@@ -18881,7 +19246,7 @@ async function discoverOpenCodeProcesses() {
18881
19246
  cwd,
18882
19247
  harness: classifyAttribution(parentChain),
18883
19248
  parentChain,
18884
- source: SOURCE_NAME5
19249
+ source: SOURCE_NAME6
18885
19250
  });
18886
19251
  }));
18887
19252
  out.sort((a, b) => a.pid - b.pid);
@@ -18890,7 +19255,7 @@ async function discoverOpenCodeProcesses() {
18890
19255
  function metadataRecord3(value) {
18891
19256
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
18892
19257
  }
18893
- function parseJsonRecord5(text) {
19258
+ function parseJsonRecord6(text) {
18894
19259
  try {
18895
19260
  return metadataRecord3(JSON.parse(text));
18896
19261
  } catch {
@@ -18899,7 +19264,7 @@ function parseJsonRecord5(text) {
18899
19264
  }
18900
19265
  function readJsonFile2(filePath) {
18901
19266
  try {
18902
- return parseJsonRecord5(readFileSync2(filePath, "utf8"));
19267
+ return parseJsonRecord6(readFileSync3(filePath, "utf8"));
18903
19268
  } catch {
18904
19269
  return null;
18905
19270
  }
@@ -18941,22 +19306,22 @@ function partTimestamp(part) {
18941
19306
  return numberValue(time3, "end") ?? numberValue(time3, "start") ?? numberValue(time3, "created");
18942
19307
  }
18943
19308
  function walkRecentSessionFiles(root, scope) {
18944
- const cutoff = Date.now() - discoveryWindowMs5(scope);
19309
+ const cutoff = Date.now() - discoveryWindowMs6(scope);
18945
19310
  const found = [];
18946
- const stack = [join6(root, "session")];
19311
+ const stack = [join7(root, "session")];
18947
19312
  while (stack.length > 0) {
18948
19313
  const dir = stack.pop();
18949
19314
  let entries = [];
18950
19315
  try {
18951
- entries = readdirSync5(dir);
19316
+ entries = readdirSync6(dir);
18952
19317
  } catch {
18953
19318
  continue;
18954
19319
  }
18955
19320
  for (const entry of entries) {
18956
- const path = join6(dir, entry);
19321
+ const path = join7(dir, entry);
18957
19322
  let stats;
18958
19323
  try {
18959
- stats = statSync5(path);
19324
+ stats = statSync6(path);
18960
19325
  } catch {
18961
19326
  continue;
18962
19327
  }
@@ -18972,23 +19337,23 @@ function walkRecentSessionFiles(root, scope) {
18972
19337
  return found;
18973
19338
  }
18974
19339
  function walkRecentMessageSessionFiles(root, scope) {
18975
- const cutoff = Date.now() - discoveryWindowMs5(scope);
18976
- const messageRoot = join6(root, "message");
19340
+ const cutoff = Date.now() - discoveryWindowMs6(scope);
19341
+ const messageRoot = join7(root, "message");
18977
19342
  let sessionDirs = [];
18978
19343
  try {
18979
- sessionDirs = readdirSync5(messageRoot);
19344
+ sessionDirs = readdirSync6(messageRoot);
18980
19345
  } catch {
18981
19346
  return [];
18982
19347
  }
18983
19348
  const found = new Map;
18984
19349
  for (const sessionId of sessionDirs) {
18985
- const dir = join6(messageRoot, sessionId);
19350
+ const dir = join7(messageRoot, sessionId);
18986
19351
  let entries = [];
18987
19352
  try {
18988
- const stats = statSync5(dir);
19353
+ const stats = statSync6(dir);
18989
19354
  if (!stats.isDirectory())
18990
19355
  continue;
18991
- entries = readdirSync5(dir);
19356
+ entries = readdirSync6(dir);
18992
19357
  } catch {
18993
19358
  continue;
18994
19359
  }
@@ -18997,7 +19362,7 @@ function walkRecentMessageSessionFiles(root, scope) {
18997
19362
  if (!entry.endsWith(".json"))
18998
19363
  continue;
18999
19364
  try {
19000
- const stats = statSync5(join6(dir, entry));
19365
+ const stats = statSync6(join7(dir, entry));
19001
19366
  if (stats.isFile() && stats.mtimeMs >= cutoff && stats.mtimeMs > latestMessageMtime) {
19002
19367
  latestMessageMtime = stats.mtimeMs;
19003
19368
  }
@@ -19007,9 +19372,9 @@ function walkRecentMessageSessionFiles(root, scope) {
19007
19372
  }
19008
19373
  if (latestMessageMtime <= 0)
19009
19374
  continue;
19010
- const sessionPath = join6(root, "session", "global", `${sessionId}.json`);
19375
+ const sessionPath = join7(root, "session", "global", `${sessionId}.json`);
19011
19376
  try {
19012
- const sessionStats = statSync5(sessionPath);
19377
+ const sessionStats = statSync6(sessionPath);
19013
19378
  if (!sessionStats.isFile())
19014
19379
  continue;
19015
19380
  found.set(sessionPath, {
@@ -19024,7 +19389,7 @@ function walkRecentMessageSessionFiles(root, scope) {
19024
19389
  return [...found.values()];
19025
19390
  }
19026
19391
  function sessionIdFromPath(filePath) {
19027
- return basename5(filePath).replace(/\.json$/u, "");
19392
+ return basename6(filePath).replace(/\.json$/u, "");
19028
19393
  }
19029
19394
  function storageRootFromSessionPath(filePath) {
19030
19395
  const marker = `${sep}session${sep}`;
@@ -19045,17 +19410,17 @@ function discoverOpenCodeTranscripts(scope) {
19045
19410
  byPath.set(file2.path, file2);
19046
19411
  }
19047
19412
  }
19048
- return [...byPath.values()].sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, discoveryLimit5(scope)).map((file2) => {
19049
- const session = readJsonFile2(file2.path) ?? parseJsonRecord5(readFileHead5(file2.path));
19413
+ return [...byPath.values()].sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, discoveryLimit6(scope)).map((file2) => {
19414
+ const session = readJsonFile2(file2.path) ?? parseJsonRecord6(readFileHead5(file2.path));
19050
19415
  const sessionId = stringValue(session, "id") ?? sessionIdFromPath(file2.path);
19051
19416
  const cwd = stringValue(session, "directory");
19052
19417
  const title = stringValue(session, "title");
19053
19418
  return {
19054
- source: SOURCE_NAME5,
19419
+ source: SOURCE_NAME6,
19055
19420
  transcriptPath: file2.path,
19056
19421
  sessionId,
19057
19422
  cwd,
19058
- project: cwd ? basename5(cwd) : title ?? "OpenCode",
19423
+ project: cwd ? basename6(cwd) : title ?? "OpenCode",
19059
19424
  harness: "unattributed",
19060
19425
  mtimeMs: file2.mtimeMs,
19061
19426
  size: file2.size
@@ -19063,10 +19428,10 @@ function discoverOpenCodeTranscripts(scope) {
19063
19428
  });
19064
19429
  }
19065
19430
  function readOpenCodeMessages(root, sessionId) {
19066
- const dir = join6(root, "message", sessionId);
19431
+ const dir = join7(root, "message", sessionId);
19067
19432
  let entries = [];
19068
19433
  try {
19069
- entries = readdirSync5(dir);
19434
+ entries = readdirSync6(dir);
19070
19435
  } catch {
19071
19436
  return [];
19072
19437
  }
@@ -19074,10 +19439,10 @@ function readOpenCodeMessages(root, sessionId) {
19074
19439
  for (const entry of entries) {
19075
19440
  if (!entry.endsWith(".json"))
19076
19441
  continue;
19077
- const path = join6(dir, entry);
19442
+ const path = join7(dir, entry);
19078
19443
  let stats;
19079
19444
  try {
19080
- stats = statSync5(path);
19445
+ stats = statSync6(path);
19081
19446
  } catch {
19082
19447
  continue;
19083
19448
  }
@@ -19091,10 +19456,10 @@ function readOpenCodeMessages(root, sessionId) {
19091
19456
  return messages.sort((a, b) => (messageTimestamp(a) ?? a.__mtimeMs) - (messageTimestamp(b) ?? b.__mtimeMs)).slice(-messagesPerSession());
19092
19457
  }
19093
19458
  function readOpenCodeParts(root, messageId) {
19094
- const dir = join6(root, "part", messageId);
19459
+ const dir = join7(root, "part", messageId);
19095
19460
  let entries = [];
19096
19461
  try {
19097
- entries = readdirSync5(dir);
19462
+ entries = readdirSync6(dir);
19098
19463
  } catch {
19099
19464
  return [];
19100
19465
  }
@@ -19102,10 +19467,10 @@ function readOpenCodeParts(root, messageId) {
19102
19467
  for (const entry of entries) {
19103
19468
  if (!entry.endsWith(".json"))
19104
19469
  continue;
19105
- const path = join6(dir, entry);
19470
+ const path = join7(dir, entry);
19106
19471
  let stats;
19107
19472
  try {
19108
- stats = statSync5(path);
19473
+ stats = statSync6(path);
19109
19474
  } catch {
19110
19475
  continue;
19111
19476
  }
@@ -19118,7 +19483,7 @@ function readOpenCodeParts(root, messageId) {
19118
19483
  }
19119
19484
  return parts.sort((a, b) => (partTimestamp(a) ?? a.__mtimeMs) - (partTimestamp(b) ?? b.__mtimeMs));
19120
19485
  }
19121
- function clip5(text, max = MAX_SUMMARY_LEN5) {
19486
+ function clip6(text, max = MAX_SUMMARY_LEN6) {
19122
19487
  const flat = text.replace(/\s+/g, " ").trim();
19123
19488
  return flat.length <= max ? flat : `${flat.slice(0, max - 1)}\u2026`;
19124
19489
  }
@@ -19131,24 +19496,24 @@ function summarizeToolPart(part) {
19131
19496
  const tool = stringValue(part, "tool") ?? "tool";
19132
19497
  const status = stringValue(state, "status");
19133
19498
  const title = stringValue(state, "title") ?? stringValue(metadata, "description") ?? stringValue(metadata, "preview");
19134
- return clip5(`${tool}${status ? ` ${status}` : ""}${title ? ` \xB7 ${title}` : ""}`, 80);
19499
+ return clip6(`${tool}${status ? ` ${status}` : ""}${title ? ` \xB7 ${title}` : ""}`, 80);
19135
19500
  }
19136
19501
  function summarizeOpenCodeMessage(message, parts) {
19137
19502
  const textParts = parts.filter((part) => stringValue(part, "type") === "text").map((part) => stringValue(part, "text")).filter((text) => Boolean(text));
19138
19503
  if (textParts.length > 0)
19139
- return clip5(textParts.join(" "));
19504
+ return clip6(textParts.join(" "));
19140
19505
  const summary = nestedRecord(message, "summary");
19141
19506
  const title = stringValue(summary, "title");
19142
19507
  if (title)
19143
- return clip5(title);
19508
+ return clip6(title);
19144
19509
  const toolParts = parts.filter((part) => stringValue(part, "type") === "tool");
19145
19510
  if (toolParts.length > 0) {
19146
- return clip5(toolParts.slice(-3).map(summarizeToolPart).join(" \xB7 "));
19511
+ return clip6(toolParts.slice(-3).map(summarizeToolPart).join(" \xB7 "));
19147
19512
  }
19148
19513
  const role = stringValue(message, "role") ?? "message";
19149
19514
  const model = modelId(message);
19150
19515
  const finish = stringValue(message, "finish");
19151
- return clip5(`${role}${model ? ` \xB7 ${model}` : ""}${finish ? ` \xB7 ${finish}` : ""}`);
19516
+ return clip6(`${role}${model ? ` \xB7 ${model}` : ""}${finish ? ` \xB7 ${finish}` : ""}`);
19152
19517
  }
19153
19518
  function eventKindForRole(role) {
19154
19519
  if (role === "user")
@@ -19158,20 +19523,20 @@ function eventKindForRole(role) {
19158
19523
  return "system";
19159
19524
  }
19160
19525
  function openCodeEventFromMessage(message, parts, ctx, fallbackCwd, index) {
19161
- const messageId = stringValue(message, "id") ?? basename5(message.__filePath).replace(/\.json$/u, "");
19526
+ const messageId = stringValue(message, "id") ?? basename6(message.__filePath).replace(/\.json$/u, "");
19162
19527
  const sessionId = stringValue(message, "sessionID") ?? ctx.transcript.sessionId ?? sessionIdFromPath(ctx.transcriptPath);
19163
19528
  const pathRecord = nestedRecord(message, "path");
19164
19529
  const cwd = stringValue(pathRecord, "cwd") ?? fallbackCwd;
19165
19530
  const role = stringValue(message, "role");
19166
19531
  const ts = messageTimestamp(message) ?? message.__mtimeMs;
19167
19532
  return {
19168
- id: `${SOURCE_NAME5}:${sessionId}:${messageId}:${ts || index}`,
19533
+ id: `${SOURCE_NAME6}:${sessionId}:${messageId}:${ts || index}`,
19169
19534
  ts: ts || Date.now(),
19170
- source: SOURCE_NAME5,
19535
+ source: SOURCE_NAME6,
19171
19536
  sessionId,
19172
19537
  pid: ctx.process.pid,
19173
19538
  parentPid: ctx.process.ppid || null,
19174
- project: cwd ? basename5(cwd) : ctx.transcript.project,
19539
+ project: cwd ? basename6(cwd) : ctx.transcript.project,
19175
19540
  cwd,
19176
19541
  harness: ctx.process.harness,
19177
19542
  kind: eventKindForRole(role),
@@ -19183,7 +19548,7 @@ function openCodeEventFromMessage(message, parts, ctx, fallbackCwd, index) {
19183
19548
  };
19184
19549
  }
19185
19550
  function parseOpenCodeSession(text, ctx) {
19186
- const session = parseJsonRecord5(text);
19551
+ const session = parseJsonRecord6(text);
19187
19552
  if (!session)
19188
19553
  return [];
19189
19554
  const root = storageRootFromSessionPath(ctx.transcriptPath);
@@ -19193,7 +19558,7 @@ function parseOpenCodeSession(text, ctx) {
19193
19558
  const messages = readOpenCodeMessages(root, sessionId);
19194
19559
  if (messages.length > 0) {
19195
19560
  return messages.map((message, index) => {
19196
- const messageId = stringValue(message, "id") ?? basename5(message.__filePath).replace(/\.json$/u, "");
19561
+ const messageId = stringValue(message, "id") ?? basename6(message.__filePath).replace(/\.json$/u, "");
19197
19562
  return openCodeEventFromMessage(message, readOpenCodeParts(root, messageId), ctx, fallbackCwd, index);
19198
19563
  });
19199
19564
  }
@@ -19201,22 +19566,22 @@ function parseOpenCodeSession(text, ctx) {
19201
19566
  const updated = numberValue(nestedRecord(session, "time"), "updated") ?? numberValue(nestedRecord(session, "time"), "created") ?? Date.now();
19202
19567
  const title = stringValue(session, "title") ?? "session updated";
19203
19568
  return [{
19204
- id: `${SOURCE_NAME5}:${sessionId}:session:${updated}`,
19569
+ id: `${SOURCE_NAME6}:${sessionId}:session:${updated}`,
19205
19570
  ts: updated,
19206
- source: SOURCE_NAME5,
19571
+ source: SOURCE_NAME6,
19207
19572
  sessionId,
19208
19573
  pid: ctx.process.pid,
19209
19574
  parentPid: ctx.process.ppid || null,
19210
- project: fallbackCwd ? basename5(fallbackCwd) : ctx.transcript.project,
19575
+ project: fallbackCwd ? basename6(fallbackCwd) : ctx.transcript.project,
19211
19576
  cwd: fallbackCwd,
19212
19577
  harness: ctx.process.harness,
19213
19578
  kind: "system",
19214
- summary: clip5(title),
19579
+ summary: clip6(title),
19215
19580
  raw: session
19216
19581
  }];
19217
19582
  }
19218
19583
  var OpenCodeSource = {
19219
- name: SOURCE_NAME5,
19584
+ name: SOURCE_NAME6,
19220
19585
  discoverProcesses() {
19221
19586
  return discoverOpenCodeProcesses();
19222
19587
  },
@@ -19232,32 +19597,32 @@ var OpenCodeSource = {
19232
19597
  };
19233
19598
 
19234
19599
  // packages/runtime/src/tail/pi-source.ts
19235
- import { closeSync as closeSync6, existsSync as existsSync7, openSync as openSync6, readdirSync as readdirSync6, readSync as readSync6, statSync as statSync6 } from "fs";
19236
- import { homedir as homedir7 } from "os";
19237
- import { basename as basename6, join as join7, relative as relative2 } from "path";
19238
- var SOURCE_NAME6 = "pi";
19239
- var MAX_SUMMARY_LEN6 = 200;
19240
- var DEFAULT_HOT_DISCOVERY_WINDOW_MS6 = 10 * 60 * 1000;
19241
- var DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS6 = 24 * 60 * 60 * 1000;
19242
- var DEFAULT_DEEP_DISCOVERY_WINDOW_MS6 = 24 * 60 * 60 * 1000;
19243
- var DEFAULT_HOT_DISCOVERY_LIMIT6 = 64;
19244
- var DEFAULT_SHALLOW_DISCOVERY_LIMIT6 = 160;
19245
- var DEFAULT_DEEP_DISCOVERY_LIMIT6 = 160;
19600
+ import { closeSync as closeSync6, existsSync as existsSync8, openSync as openSync6, readdirSync as readdirSync7, readSync as readSync6, statSync as statSync7 } from "fs";
19601
+ import { homedir as homedir8 } from "os";
19602
+ import { basename as basename7, join as join8, relative as relative2 } from "path";
19603
+ var SOURCE_NAME7 = "pi";
19604
+ var MAX_SUMMARY_LEN7 = 200;
19605
+ var DEFAULT_HOT_DISCOVERY_WINDOW_MS7 = 10 * 60 * 1000;
19606
+ var DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS7 = 24 * 60 * 60 * 1000;
19607
+ var DEFAULT_DEEP_DISCOVERY_WINDOW_MS7 = 24 * 60 * 60 * 1000;
19608
+ var DEFAULT_HOT_DISCOVERY_LIMIT7 = 64;
19609
+ var DEFAULT_SHALLOW_DISCOVERY_LIMIT7 = 160;
19610
+ var DEFAULT_DEEP_DISCOVERY_LIMIT7 = 160;
19246
19611
  var HEAD_READ_BYTES6 = 256 * 1024;
19247
- var METADATA_CACHE_LIMIT4 = 512;
19248
- var metadataCache4 = new Map;
19612
+ var METADATA_CACHE_LIMIT5 = 512;
19613
+ var metadataCache5 = new Map;
19249
19614
  function rememberMetadata4(file2, metadata) {
19250
- metadataCache4.delete(file2.path);
19251
- metadataCache4.set(file2.path, { ...file2, ...metadata });
19252
- while (metadataCache4.size > METADATA_CACHE_LIMIT4) {
19253
- const oldest = metadataCache4.keys().next().value;
19615
+ metadataCache5.delete(file2.path);
19616
+ metadataCache5.set(file2.path, { ...file2, ...metadata });
19617
+ while (metadataCache5.size > METADATA_CACHE_LIMIT5) {
19618
+ const oldest = metadataCache5.keys().next().value;
19254
19619
  if (!oldest)
19255
19620
  break;
19256
- metadataCache4.delete(oldest);
19621
+ metadataCache5.delete(oldest);
19257
19622
  }
19258
19623
  return metadata;
19259
19624
  }
19260
- function readPositiveIntEnv6(names, fallback) {
19625
+ function readPositiveIntEnv7(names, fallback) {
19261
19626
  for (const name of names) {
19262
19627
  const raw = Number.parseInt(process.env[name] ?? "", 10);
19263
19628
  if (Number.isFinite(raw) && raw > 0)
@@ -19265,23 +19630,23 @@ function readPositiveIntEnv6(names, fallback) {
19265
19630
  }
19266
19631
  return fallback;
19267
19632
  }
19268
- function discoveryWindowMs6(scope) {
19269
- const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_WINDOW_MS6 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_WINDOW_MS6 : DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS6;
19633
+ function discoveryWindowMs7(scope) {
19634
+ const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_WINDOW_MS7 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_WINDOW_MS7 : DEFAULT_SHALLOW_DISCOVERY_WINDOW_MS7;
19270
19635
  const scopedName = `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_WINDOW_MS`;
19271
- return readPositiveIntEnv6([scopedName, "OPENSCOUT_TAIL_DISCOVERY_WINDOW_MS"], fallback);
19636
+ return readPositiveIntEnv7([scopedName, "OPENSCOUT_TAIL_DISCOVERY_WINDOW_MS"], fallback);
19272
19637
  }
19273
- function discoveryLimit6(scope) {
19274
- const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_LIMIT6 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_LIMIT6 : DEFAULT_SHALLOW_DISCOVERY_LIMIT6;
19638
+ function discoveryLimit7(scope) {
19639
+ const fallback = scope === "hot" ? DEFAULT_HOT_DISCOVERY_LIMIT7 : scope === "deep" ? DEFAULT_DEEP_DISCOVERY_LIMIT7 : DEFAULT_SHALLOW_DISCOVERY_LIMIT7;
19275
19640
  const scopedName = `OPENSCOUT_TAIL_${scope.toUpperCase()}_DISCOVERY_LIMIT`;
19276
- return readPositiveIntEnv6([scopedName, "OPENSCOUT_TAIL_DISCOVERY_LIMIT"], fallback);
19641
+ return readPositiveIntEnv7([scopedName, "OPENSCOUT_TAIL_DISCOVERY_LIMIT"], fallback);
19277
19642
  }
19278
19643
  function projectsRoot2() {
19279
- return process.env.OPENSCOUT_TAIL_PI_SESSIONS_ROOT ?? join7(homedir7(), ".pi", "agent", "sessions");
19644
+ return process.env.OPENSCOUT_TAIL_PI_SESSIONS_ROOT ?? join8(homedir8(), ".pi", "agent", "sessions");
19280
19645
  }
19281
19646
  function listJsonlFiles2(dir) {
19282
19647
  let entries = [];
19283
19648
  try {
19284
- entries = readdirSync6(dir);
19649
+ entries = readdirSync7(dir);
19285
19650
  } catch {
19286
19651
  return [];
19287
19652
  }
@@ -19304,7 +19669,7 @@ function readFileHead6(filePath) {
19304
19669
  }
19305
19670
  }
19306
19671
  }
19307
- function parseJsonRecord6(line) {
19672
+ function parseJsonRecord7(line) {
19308
19673
  try {
19309
19674
  const value = JSON.parse(line);
19310
19675
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -19312,7 +19677,7 @@ function parseJsonRecord6(line) {
19312
19677
  return null;
19313
19678
  }
19314
19679
  }
19315
- function parseTimestamp3(value) {
19680
+ function parseTimestamp4(value) {
19316
19681
  if (typeof value === "number" && Number.isFinite(value)) {
19317
19682
  return value > 1000000000000 ? value : value * 1000;
19318
19683
  }
@@ -19322,7 +19687,7 @@ function parseTimestamp3(value) {
19322
19687
  }
19323
19688
  return null;
19324
19689
  }
19325
- function clip6(text, max = MAX_SUMMARY_LEN6) {
19690
+ function clip7(text, max = MAX_SUMMARY_LEN7) {
19326
19691
  const flat = text.replace(/\s+/g, " ").trim();
19327
19692
  return flat.length <= max ? flat : `${flat.slice(0, max - 1)}\u2026`;
19328
19693
  }
@@ -19335,14 +19700,14 @@ function decodePiProjectDir(dirName) {
19335
19700
  return `/${inner.replace(/-/g, "/")}`;
19336
19701
  }
19337
19702
  function sessionIdFromPiPath(filePath) {
19338
- const name = basename6(filePath).replace(/\.jsonl$/, "");
19703
+ const name = basename7(filePath).replace(/\.jsonl$/, "");
19339
19704
  const separator = name.lastIndexOf("_");
19340
19705
  if (separator >= 0)
19341
19706
  return name.slice(separator + 1);
19342
19707
  return name;
19343
19708
  }
19344
19709
  function readPiMetadata(file2) {
19345
- const cached2 = metadataCache4.get(file2.path);
19710
+ const cached2 = metadataCache5.get(file2.path);
19346
19711
  if (cached2 && cached2.mtimeMs === file2.mtimeMs && cached2.size === file2.size) {
19347
19712
  return { cwd: cached2.cwd, sessionId: cached2.sessionId };
19348
19713
  }
@@ -19350,7 +19715,7 @@ function readPiMetadata(file2) {
19350
19715
  let cwd = null;
19351
19716
  let sessionId = null;
19352
19717
  for (const line of head.split(/\r?\n/)) {
19353
- const record2 = parseJsonRecord6(line.trim());
19718
+ const record2 = parseJsonRecord7(line.trim());
19354
19719
  if (!record2)
19355
19720
  continue;
19356
19721
  if (record2.type === "session") {
@@ -19376,26 +19741,26 @@ function fallbackCwdForPath2(filePath) {
19376
19741
  return dirName ? decodePiProjectDir(dirName) : null;
19377
19742
  }
19378
19743
  function listRecentPiProjectTranscripts(root, scope) {
19379
- const cutoff = Date.now() - discoveryWindowMs6(scope);
19744
+ const cutoff = Date.now() - discoveryWindowMs7(scope);
19380
19745
  const found = [];
19381
19746
  let projectDirs = [];
19382
19747
  try {
19383
- projectDirs = readdirSync6(root);
19748
+ projectDirs = readdirSync7(root);
19384
19749
  } catch {
19385
19750
  return [];
19386
19751
  }
19387
19752
  for (const entry of projectDirs) {
19388
- const projectDir = join7(root, entry);
19753
+ const projectDir = join8(root, entry);
19389
19754
  try {
19390
- if (!statSync6(projectDir).isDirectory())
19755
+ if (!statSync7(projectDir).isDirectory())
19391
19756
  continue;
19392
19757
  } catch {
19393
19758
  continue;
19394
19759
  }
19395
19760
  for (const file2 of listJsonlFiles2(projectDir)) {
19396
- const path = join7(projectDir, file2);
19761
+ const path = join8(projectDir, file2);
19397
19762
  try {
19398
- const stats = statSync6(path);
19763
+ const stats = statSync7(path);
19399
19764
  if (stats.mtimeMs < cutoff)
19400
19765
  continue;
19401
19766
  found.push({ path, mtimeMs: stats.mtimeMs, size: stats.size });
@@ -19404,7 +19769,7 @@ function listRecentPiProjectTranscripts(root, scope) {
19404
19769
  }
19405
19770
  }
19406
19771
  }
19407
- return found.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, discoveryLimit6(scope));
19772
+ return found.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, discoveryLimit7(scope));
19408
19773
  }
19409
19774
  function isPiProcess(command) {
19410
19775
  return commandBasename2(command) === "pi";
@@ -19427,7 +19792,7 @@ async function discoverPiProcesses() {
19427
19792
  cwd,
19428
19793
  harness: classifyAttribution(parentChain),
19429
19794
  parentChain,
19430
- source: SOURCE_NAME6
19795
+ source: SOURCE_NAME7
19431
19796
  });
19432
19797
  }));
19433
19798
  out.sort((a, b) => a.pid - b.pid);
@@ -19435,18 +19800,18 @@ async function discoverPiProcesses() {
19435
19800
  }
19436
19801
  function discoverPiTranscripts(scope) {
19437
19802
  const root = projectsRoot2();
19438
- if (!existsSync7(root))
19803
+ if (!existsSync8(root))
19439
19804
  return [];
19440
19805
  return listRecentPiProjectTranscripts(root, scope).map((file2) => {
19441
19806
  const meta3 = readPiMetadata(file2);
19442
19807
  const cwd = meta3.cwd ?? fallbackCwdForPath2(file2.path);
19443
19808
  const sessionId = meta3.sessionId ?? sessionIdFromPiPath(file2.path);
19444
19809
  return {
19445
- source: SOURCE_NAME6,
19810
+ source: SOURCE_NAME7,
19446
19811
  transcriptPath: file2.path,
19447
19812
  sessionId,
19448
19813
  cwd,
19449
- project: cwd ? basename6(cwd) : projectDirNameForPath2(file2.path) ?? "(unknown)",
19814
+ project: cwd ? basename7(cwd) : projectDirNameForPath2(file2.path) ?? "(unknown)",
19450
19815
  harness: "unattributed",
19451
19816
  mtimeMs: file2.mtimeMs,
19452
19817
  size: file2.size
@@ -19472,14 +19837,14 @@ function summarizePiMessage(message) {
19472
19837
  const content = message.content;
19473
19838
  if (role === "user") {
19474
19839
  const text = textFromPiContent(content);
19475
- return { kind: "user", summary: clip6(text || "[user]") };
19840
+ return { kind: "user", summary: clip7(text || "[user]") };
19476
19841
  }
19477
19842
  if (role === "toolResult") {
19478
19843
  const text = textFromPiContent(content);
19479
19844
  const toolName = typeof message.toolName === "string" ? message.toolName : undefined;
19480
19845
  return {
19481
19846
  kind: "tool-result",
19482
- summary: clip6(formatToolResult(text, toolName))
19847
+ summary: clip7(formatToolResult(text, toolName))
19483
19848
  };
19484
19849
  }
19485
19850
  if (role === "assistant") {
@@ -19501,14 +19866,14 @@ function summarizePiMessage(message) {
19501
19866
  }
19502
19867
  }
19503
19868
  if (toolParts.length > 0) {
19504
- return { kind: "tool", summary: clip6(toolParts.join(" \xB7 ")) };
19869
+ return { kind: "tool", summary: clip7(toolParts.join(" \xB7 ")) };
19505
19870
  }
19506
- return { kind: "assistant", summary: clip6(textParts.join(" ") || "[assistant]") };
19871
+ return { kind: "assistant", summary: clip7(textParts.join(" ") || "[assistant]") };
19507
19872
  }
19508
19873
  return null;
19509
19874
  }
19510
19875
  function parsePiLine(line, ctx) {
19511
- const record2 = parseJsonRecord6(line.trim());
19876
+ const record2 = parseJsonRecord7(line.trim());
19512
19877
  if (!record2 || record2.type !== "message" || typeof record2.message !== "object" || !record2.message) {
19513
19878
  return null;
19514
19879
  }
@@ -19518,16 +19883,16 @@ function parsePiLine(line, ctx) {
19518
19883
  return null;
19519
19884
  const sessionId = ctx.transcript.sessionId ?? sessionIdFromPiPath(ctx.transcriptPath);
19520
19885
  const cwd = ctx.transcript.cwd ?? ctx.process.cwd ?? "";
19521
- const ts = parseTimestamp3(record2.timestamp) ?? parseTimestamp3(message.timestamp) ?? Date.now();
19886
+ const ts = parseTimestamp4(record2.timestamp) ?? parseTimestamp4(message.timestamp) ?? Date.now();
19522
19887
  const recordId = typeof record2.id === "string" && record2.id.trim() ? record2.id : String(ctx.lineOffset);
19523
19888
  return {
19524
- id: `${SOURCE_NAME6}:${sessionId}:${recordId}`,
19889
+ id: `${SOURCE_NAME7}:${sessionId}:${recordId}`,
19525
19890
  ts,
19526
- source: SOURCE_NAME6,
19891
+ source: SOURCE_NAME7,
19527
19892
  sessionId,
19528
19893
  pid: ctx.process.pid,
19529
19894
  parentPid: ctx.process.ppid || null,
19530
- project: cwd ? basename6(cwd) : ctx.transcript.project,
19895
+ project: cwd ? basename7(cwd) : ctx.transcript.project,
19531
19896
  cwd,
19532
19897
  harness: ctx.process.harness,
19533
19898
  kind: parsed.kind,
@@ -19536,7 +19901,7 @@ function parsePiLine(line, ctx) {
19536
19901
  };
19537
19902
  }
19538
19903
  var PiSource = {
19539
- name: SOURCE_NAME6,
19904
+ name: SOURCE_NAME7,
19540
19905
  discoverProcesses() {
19541
19906
  return discoverPiProcesses();
19542
19907
  },
@@ -19566,19 +19931,19 @@ function sessionRegistryKey(transcript) {
19566
19931
  }
19567
19932
 
19568
19933
  // packages/runtime/src/tail/service.ts
19569
- function readPositiveIntEnv7(name, fallback) {
19934
+ function readPositiveIntEnv8(name, fallback) {
19570
19935
  const raw = Number.parseInt(process.env[name] ?? "", 10);
19571
19936
  return Number.isFinite(raw) && raw > 0 ? raw : fallback;
19572
19937
  }
19573
- var TAIL_POLL_INTERVAL_MS = readPositiveIntEnv7("OPENSCOUT_TAIL_POLL_INTERVAL_MS", 500);
19574
- var HOT_DISCOVERY_INTERVAL_MS = readPositiveIntEnv7("OPENSCOUT_TAIL_HOT_DISCOVERY_INTERVAL_MS", 30000);
19575
- var DISCOVERY_CACHE_MAX_AGE_MS = readPositiveIntEnv7("OPENSCOUT_TAIL_DISCOVERY_CACHE_MAX_AGE_MS", HOT_DISCOVERY_INTERVAL_MS);
19576
- var SHALLOW_DISCOVERY_INTERVAL_MS = readPositiveIntEnv7("OPENSCOUT_TAIL_SHALLOW_DISCOVERY_INTERVAL_MS", 10 * 60000);
19577
- var DEEP_DISCOVERY_INTERVAL_MS = readPositiveIntEnv7("OPENSCOUT_TAIL_DEEP_DISCOVERY_INTERVAL_MS", 60 * 60000);
19938
+ var TAIL_POLL_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_POLL_INTERVAL_MS", 500);
19939
+ var HOT_DISCOVERY_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_HOT_DISCOVERY_INTERVAL_MS", 30000);
19940
+ var DISCOVERY_CACHE_MAX_AGE_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_DISCOVERY_CACHE_MAX_AGE_MS", HOT_DISCOVERY_INTERVAL_MS);
19941
+ var SHALLOW_DISCOVERY_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_SHALLOW_DISCOVERY_INTERVAL_MS", 10 * 60000);
19942
+ var DEEP_DISCOVERY_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_DEEP_DISCOVERY_INTERVAL_MS", 60 * 60000);
19578
19943
  var PER_SESSION_BUFFER_LIMIT = 2000;
19579
19944
  var AGGREGATE_BUFFER_LIMIT = 1e4;
19580
- var QUIET_EVENT_COALESCE_WINDOW_MS = readPositiveIntEnv7("OPENSCOUT_TAIL_QUIET_EVENT_COALESCE_WINDOW_MS", 5000);
19581
- var QUIET_EVENT_COALESCE_MAX_KEYS = readPositiveIntEnv7("OPENSCOUT_TAIL_QUIET_EVENT_COALESCE_MAX_KEYS", 2000);
19945
+ var QUIET_EVENT_COALESCE_WINDOW_MS = readPositiveIntEnv8("OPENSCOUT_TAIL_QUIET_EVENT_COALESCE_WINDOW_MS", 5000);
19946
+ var QUIET_EVENT_COALESCE_MAX_KEYS = readPositiveIntEnv8("OPENSCOUT_TAIL_QUIET_EVENT_COALESCE_MAX_KEYS", 2000);
19582
19947
  var RAW_MAX_DEPTH = 5;
19583
19948
  var RAW_MAX_STRING_LEN = 1000;
19584
19949
  var RAW_MAX_ARRAY_ITEMS = 25;
@@ -19586,9 +19951,9 @@ var RAW_MAX_OBJECT_KEYS = 50;
19586
19951
  var RECENT_TRANSCRIPT_READ_BYTES = 512 * 1024;
19587
19952
  var SESSION_TRANSCRIPT_READ_BYTES = 8 * 1024 * 1024;
19588
19953
  var RECENT_TRANSCRIPT_LINES_PER_FILE = 200;
19589
- var RECENT_TRANSCRIPT_MAX_FILES = readPositiveIntEnv7("OPENSCOUT_TAIL_RECENT_TRANSCRIPT_MAX_FILES", 24);
19590
- var NATIVE_TAIL_SOURCES = new Set(["grok", "opencode", "cursor"]);
19591
- var sources = [GrokSource, ClaudeSource, CodexSource, CursorSource, OpenCodeSource, PiSource];
19954
+ var RECENT_TRANSCRIPT_MAX_FILES = readPositiveIntEnv8("OPENSCOUT_TAIL_RECENT_TRANSCRIPT_MAX_FILES", 24);
19955
+ var NATIVE_TAIL_SOURCES = new Set(["grok", "kimi", "opencode", "cursor"]);
19956
+ var sources = [GrokSource, KimiSource, ClaudeSource, CodexSource, CursorSource, OpenCodeSource, PiSource];
19592
19957
  var watchers = new Map;
19593
19958
  var aggregateBuffer = [];
19594
19959
  var perSessionBuffer = new Map;
@@ -20275,7 +20640,15 @@ function isCodexChunkToolResult(summary) {
20275
20640
  const trimmed = summary.trim();
20276
20641
  return trimmed.startsWith("-> Chunk ID:") || /^->\s+Wall time:/u.test(trimmed);
20277
20642
  }
20643
+ function isCursorProcessSample(event) {
20644
+ if (event.source !== "cursor" || event.kind !== "system")
20645
+ return false;
20646
+ const summary = event.summary.trim().toLowerCase();
20647
+ return summary === "process sample" || summary.startsWith("process sample \xB7");
20648
+ }
20278
20649
  function isTailNoiseEvent(event) {
20650
+ if (isCursorProcessSample(event))
20651
+ return true;
20279
20652
  if (event.source === "grok") {
20280
20653
  const summary2 = event.summary.trim().toLowerCase();
20281
20654
  if (summary2 === "first token" || summary2.startsWith("loop ")) {
@@ -20317,12 +20690,12 @@ function filterTailEventsForDisplay(events) {
20317
20690
  }
20318
20691
  // packages/runtime/src/harness-topology/service.ts
20319
20692
  import { createHash } from "crypto";
20320
- import { homedir as homedir12 } from "os";
20693
+ import { homedir as homedir13 } from "os";
20321
20694
 
20322
20695
  // packages/agent-sessions/src/adapters/claude-code/team-topology.ts
20323
- import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync3, statSync as statSync7 } from "fs";
20324
- import { homedir as homedir8 } from "os";
20325
- import { basename as basename7, dirname as dirname2, join as join8, relative as relative3 } from "path";
20696
+ import { existsSync as existsSync9, readdirSync as readdirSync8, readFileSync as readFileSync4, statSync as statSync8 } from "fs";
20697
+ import { homedir as homedir9 } from "os";
20698
+ import { basename as basename8, dirname as dirname3, join as join9, relative as relative3 } from "path";
20326
20699
  var TOPOLOGY_SCHEMA_VERSION = "openscout.observed-harness-topology.v1";
20327
20700
  var CLAUDE_TOPOLOGY_SOURCE = "claude-code-agent-teams";
20328
20701
  var SESSION_ID_KEYS = new Set([
@@ -20365,7 +20738,7 @@ function sourceRefId(kind, value) {
20365
20738
  }
20366
20739
  function readJsonObject(path) {
20367
20740
  try {
20368
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
20741
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
20369
20742
  return isObject3(parsed) ? parsed : null;
20370
20743
  } catch {
20371
20744
  return null;
@@ -20373,30 +20746,30 @@ function readJsonObject(path) {
20373
20746
  }
20374
20747
  function statIsDirectory(path) {
20375
20748
  try {
20376
- return statSync7(path).isDirectory();
20749
+ return statSync8(path).isDirectory();
20377
20750
  } catch {
20378
20751
  return false;
20379
20752
  }
20380
20753
  }
20381
20754
  function statIsFile(path) {
20382
20755
  try {
20383
- return statSync7(path).isFile();
20756
+ return statSync8(path).isFile();
20384
20757
  } catch {
20385
20758
  return false;
20386
20759
  }
20387
20760
  }
20388
20761
  function readTeamConfigs(homeDir) {
20389
- const teamsRoot = join8(homeDir, ".claude", "teams");
20390
- if (!existsSync8(teamsRoot) || !statIsDirectory(teamsRoot)) {
20762
+ const teamsRoot = join9(homeDir, ".claude", "teams");
20763
+ if (!existsSync9(teamsRoot) || !statIsDirectory(teamsRoot)) {
20391
20764
  return [];
20392
20765
  }
20393
20766
  const teams = [];
20394
- for (const entry of readdirSync7(teamsRoot)) {
20395
- const teamDir = join8(teamsRoot, entry);
20767
+ for (const entry of readdirSync8(teamsRoot)) {
20768
+ const teamDir = join9(teamsRoot, entry);
20396
20769
  if (!statIsDirectory(teamDir)) {
20397
20770
  continue;
20398
20771
  }
20399
- const configPath = join8(teamDir, "config.json");
20772
+ const configPath = join9(teamDir, "config.json");
20400
20773
  const config2 = readJsonObject(configPath);
20401
20774
  if (!config2) {
20402
20775
  continue;
@@ -20534,8 +20907,8 @@ function membersFromConfig(team, groupId, configRefId) {
20534
20907
  return { agents, relationships, agentByExternal };
20535
20908
  }
20536
20909
  function readTaskFiles(tasksRoot, teamName) {
20537
- const teamTasksRoot = join8(tasksRoot, teamName);
20538
- if (!existsSync8(teamTasksRoot) || !statIsDirectory(teamTasksRoot)) {
20910
+ const teamTasksRoot = join9(tasksRoot, teamName);
20911
+ if (!existsSync9(teamTasksRoot) || !statIsDirectory(teamTasksRoot)) {
20539
20912
  return [];
20540
20913
  }
20541
20914
  const result = [];
@@ -20544,8 +20917,8 @@ function readTaskFiles(tasksRoot, teamName) {
20544
20917
  const current = stack.pop();
20545
20918
  if (!current)
20546
20919
  continue;
20547
- for (const entry of readdirSync7(current)) {
20548
- const path = join8(current, entry);
20920
+ for (const entry of readdirSync8(current)) {
20921
+ const path = join9(current, entry);
20549
20922
  if (statIsDirectory(path)) {
20550
20923
  stack.push(path);
20551
20924
  } else if (statIsFile(path)) {
@@ -20576,14 +20949,14 @@ function firstMarkdownTitle(raw) {
20576
20949
  function parseTaskFile(taskPath, teamName, tasksRoot, sourceRef) {
20577
20950
  let raw;
20578
20951
  try {
20579
- raw = readFileSync3(taskPath, "utf8");
20952
+ raw = readFileSync4(taskPath, "utf8");
20580
20953
  } catch {
20581
20954
  return null;
20582
20955
  }
20583
- const relativePath = relative3(join8(tasksRoot, teamName), taskPath);
20956
+ const relativePath = relative3(join9(tasksRoot, teamName), taskPath);
20584
20957
  const fallbackId = relativePath.replace(/\.[^.]+$/u, "");
20585
- const fallbackTitle = firstMarkdownTitle(raw) ?? basename7(fallbackId);
20586
- const inferredState = inferTaskStateFromPath(dirname2(relativePath));
20958
+ const fallbackTitle = firstMarkdownTitle(raw) ?? basename8(fallbackId);
20959
+ const inferredState = inferTaskStateFromPath(dirname3(relativePath));
20587
20960
  let parsed = null;
20588
20961
  try {
20589
20962
  const json2 = JSON.parse(raw);
@@ -20614,7 +20987,7 @@ function parseTaskFile(taskPath, teamName, tasksRoot, sourceRef) {
20614
20987
  };
20615
20988
  }
20616
20989
  function tasksFromFiles(homeDir, teamName, agentByExternal) {
20617
- const tasksRoot = join8(homeDir, ".claude", "tasks");
20990
+ const tasksRoot = join9(homeDir, ".claude", "tasks");
20618
20991
  const taskFiles = readTaskFiles(tasksRoot, teamName);
20619
20992
  const sourceRefs = [];
20620
20993
  const parsedTasks = [];
@@ -20702,7 +21075,7 @@ function leaderAgentForTeam(team, groupId, configRefId, options) {
20702
21075
  };
20703
21076
  }
20704
21077
  function readClaudeAgentTeamTopology(options = {}) {
20705
- const homeDir = options.homeDir ?? homedir8();
21078
+ const homeDir = options.homeDir ?? homedir9();
20706
21079
  const teams = readTeamConfigs(homeDir).filter((team) => teamMatches(team, options));
20707
21080
  if (teams.length === 0) {
20708
21081
  return null;
@@ -20773,9 +21146,9 @@ function readClaudeAgentTeamTopology(options = {}) {
20773
21146
  }
20774
21147
 
20775
21148
  // packages/agent-sessions/src/adapters/claude-code/subagent-topology.ts
20776
- import { existsSync as existsSync9, readdirSync as readdirSync8, readFileSync as readFileSync4, statSync as statSync8 } from "fs";
20777
- import { homedir as homedir9 } from "os";
20778
- import { join as join9, normalize, sep as sep2 } from "path";
21149
+ import { existsSync as existsSync10, readdirSync as readdirSync9, readFileSync as readFileSync5, statSync as statSync9 } from "fs";
21150
+ import { homedir as homedir10 } from "os";
21151
+ import { join as join10, normalize, sep as sep2 } from "path";
20779
21152
  var TOPOLOGY_SCHEMA_VERSION2 = "openscout.observed-harness-topology.v1";
20780
21153
  var CLAUDE_SUBAGENT_TOPOLOGY_SOURCE = "claude-code-subagents";
20781
21154
  var DEFAULT_MAX_PARENT_SESSIONS = 40;
@@ -20797,28 +21170,28 @@ function sourceRefId2(kind, value) {
20797
21170
  }
20798
21171
  function statIsDirectory2(path) {
20799
21172
  try {
20800
- return statSync8(path).isDirectory();
21173
+ return statSync9(path).isDirectory();
20801
21174
  } catch {
20802
21175
  return false;
20803
21176
  }
20804
21177
  }
20805
21178
  function statIsFile2(path) {
20806
21179
  try {
20807
- return statSync8(path).isFile();
21180
+ return statSync9(path).isFile();
20808
21181
  } catch {
20809
21182
  return false;
20810
21183
  }
20811
21184
  }
20812
21185
  function statMtimeMs(path) {
20813
21186
  try {
20814
- return statSync8(path).mtimeMs;
21187
+ return statSync9(path).mtimeMs;
20815
21188
  } catch {
20816
21189
  return 0;
20817
21190
  }
20818
21191
  }
20819
21192
  function readText(path) {
20820
21193
  try {
20821
- return readFileSync4(path, "utf8");
21194
+ return readFileSync5(path, "utf8");
20822
21195
  } catch {
20823
21196
  return null;
20824
21197
  }
@@ -20851,30 +21224,30 @@ function parseJsonLines(path) {
20851
21224
  return events;
20852
21225
  }
20853
21226
  function projectsRoot3(homeDir) {
20854
- return join9(homeDir, ".claude", "projects");
21227
+ return join10(homeDir, ".claude", "projects");
20855
21228
  }
20856
21229
  function discoverParentSessionDirs(homeDir, maxParentSessions, sessionFilter) {
20857
21230
  const root = projectsRoot3(homeDir);
20858
- if (!existsSync9(root) || !statIsDirectory2(root))
21231
+ if (!existsSync10(root) || !statIsDirectory2(root))
20859
21232
  return [];
20860
21233
  const discovered = [];
20861
- for (const projectEntry of readdirSync8(root).sort()) {
20862
- const projectDir = join9(root, projectEntry);
21234
+ for (const projectEntry of readdirSync9(root).sort()) {
21235
+ const projectDir = join10(root, projectEntry);
20863
21236
  if (!statIsDirectory2(projectDir))
20864
21237
  continue;
20865
- for (const sessionEntry of readdirSync8(projectDir).sort()) {
21238
+ for (const sessionEntry of readdirSync9(projectDir).sort()) {
20866
21239
  if (sessionFilter && sessionEntry !== sessionFilter)
20867
21240
  continue;
20868
- const sessionDir = join9(projectDir, sessionEntry);
21241
+ const sessionDir = join10(projectDir, sessionEntry);
20869
21242
  if (!statIsDirectory2(sessionDir))
20870
21243
  continue;
20871
- const subagentsDir = join9(sessionDir, "subagents");
21244
+ const subagentsDir = join10(sessionDir, "subagents");
20872
21245
  if (!statIsDirectory2(subagentsDir))
20873
21246
  continue;
20874
- const directSubagents = readdirSync8(subagentsDir).some((entry) => /^agent-[a-zA-Z0-9]+\.jsonl$/u.test(entry));
21247
+ const directSubagents = readdirSync9(subagentsDir).some((entry) => /^agent-[a-zA-Z0-9]+\.jsonl$/u.test(entry));
20875
21248
  if (!directSubagents)
20876
21249
  continue;
20877
- const parentSessionPath = join9(projectDir, `${sessionEntry}.jsonl`);
21250
+ const parentSessionPath = join10(projectDir, `${sessionEntry}.jsonl`);
20878
21251
  discovered.push({
20879
21252
  sessionId: sessionEntry,
20880
21253
  projectDir,
@@ -21068,8 +21441,8 @@ function readSubagentRecord(parent, parentSummary, file2) {
21068
21441
  if (!match?.[1])
21069
21442
  return null;
21070
21443
  const agentId = match[1];
21071
- const transcriptPath = join9(parent.subagentsDir, file2);
21072
- const metaPath = join9(parent.subagentsDir, `agent-${agentId}.meta.json`);
21444
+ const transcriptPath = join10(parent.subagentsDir, file2);
21445
+ const metaPath = join10(parent.subagentsDir, `agent-${agentId}.meta.json`);
21073
21446
  const meta3 = statIsFile2(metaPath) ? parseSubagentMeta(metaPath) : undefined;
21074
21447
  const toolUseId = meta3?.toolUseId;
21075
21448
  const parentToolUse = toolUseId ? parentSummary.toolUses.get(toolUseId) : undefined;
@@ -21281,21 +21654,21 @@ function buildTopology(parents, observedAt) {
21281
21654
  };
21282
21655
  }
21283
21656
  function readClaudeSubagentTopology(options = {}) {
21284
- const homeDir = options.homeDir ?? homedir9();
21657
+ const homeDir = options.homeDir ?? homedir10();
21285
21658
  const maxParentSessions = options.maxParentSessions ?? DEFAULT_MAX_PARENT_SESSIONS;
21286
21659
  const sessionId = options.claudeSessionId?.trim();
21287
21660
  const parents = discoverParentSessionDirs(homeDir, maxParentSessions, sessionId).map((parent) => {
21288
21661
  const parentSummary = readParentSummary(parent.parentSessionPath);
21289
- const records = readdirSync8(parent.subagentsDir).sort().map((file2) => readSubagentRecord(parent, parentSummary, file2)).filter((record2) => Boolean(record2));
21662
+ const records = readdirSync9(parent.subagentsDir).sort().map((file2) => readSubagentRecord(parent, parentSummary, file2)).filter((record2) => Boolean(record2));
21290
21663
  return { parent, parentSummary, records };
21291
21664
  }).filter(({ parent, parentSummary, records }) => records.length > 0 && parentMatchesOptions(parent, parentSummary, records, options));
21292
21665
  return buildTopology(parents, (options.now ?? (() => new Date))().toISOString());
21293
21666
  }
21294
21667
 
21295
21668
  // packages/agent-sessions/src/adapters/claude-code/workflow-topology.ts
21296
- import { existsSync as existsSync10, readdirSync as readdirSync9, readFileSync as readFileSync5, statSync as statSync9 } from "fs";
21297
- import { homedir as homedir10 } from "os";
21298
- import { basename as basename9, join as join10, normalize as normalize2, relative as relative4, sep as sep3 } from "path";
21669
+ import { existsSync as existsSync11, readdirSync as readdirSync10, readFileSync as readFileSync6, statSync as statSync10 } from "fs";
21670
+ import { homedir as homedir11 } from "os";
21671
+ import { basename as basename10, join as join11, normalize as normalize2, relative as relative4, sep as sep3 } from "path";
21299
21672
  var TOPOLOGY_SCHEMA_VERSION3 = "openscout.observed-harness-topology.v1";
21300
21673
  var CLAUDE_WORKFLOW_TOPOLOGY_SOURCE = "claude-code-workflows";
21301
21674
  var DEFAULT_MAX_WORKFLOW_RUNS = 20;
@@ -21316,28 +21689,28 @@ function sourceRefId3(kind, value) {
21316
21689
  }
21317
21690
  function statIsDirectory3(path) {
21318
21691
  try {
21319
- return statSync9(path).isDirectory();
21692
+ return statSync10(path).isDirectory();
21320
21693
  } catch {
21321
21694
  return false;
21322
21695
  }
21323
21696
  }
21324
21697
  function statIsFile3(path) {
21325
21698
  try {
21326
- return statSync9(path).isFile();
21699
+ return statSync10(path).isFile();
21327
21700
  } catch {
21328
21701
  return false;
21329
21702
  }
21330
21703
  }
21331
21704
  function statMtimeMs2(path) {
21332
21705
  try {
21333
- return statSync9(path).mtimeMs;
21706
+ return statSync10(path).mtimeMs;
21334
21707
  } catch {
21335
21708
  return 0;
21336
21709
  }
21337
21710
  }
21338
21711
  function readText2(path) {
21339
21712
  try {
21340
- return readFileSync5(path, "utf8");
21713
+ return readFileSync6(path, "utf8");
21341
21714
  } catch {
21342
21715
  return null;
21343
21716
  }
@@ -21370,33 +21743,33 @@ function parseJsonLines2(path) {
21370
21743
  return events;
21371
21744
  }
21372
21745
  function discoverWorkflowDirs(homeDir, maxRuns) {
21373
- const projectsRoot4 = join10(homeDir, ".claude", "projects");
21374
- if (!existsSync10(projectsRoot4) || !statIsDirectory3(projectsRoot4)) {
21746
+ const projectsRoot4 = join11(homeDir, ".claude", "projects");
21747
+ if (!existsSync11(projectsRoot4) || !statIsDirectory3(projectsRoot4)) {
21375
21748
  return [];
21376
21749
  }
21377
21750
  const discovered = [];
21378
- for (const projectEntry of readdirSync9(projectsRoot4).sort()) {
21379
- const projectDir = join10(projectsRoot4, projectEntry);
21751
+ for (const projectEntry of readdirSync10(projectsRoot4).sort()) {
21752
+ const projectDir = join11(projectsRoot4, projectEntry);
21380
21753
  if (!statIsDirectory3(projectDir))
21381
21754
  continue;
21382
- for (const sessionEntry of readdirSync9(projectDir).sort()) {
21383
- const sessionDir = join10(projectDir, sessionEntry);
21755
+ for (const sessionEntry of readdirSync10(projectDir).sort()) {
21756
+ const sessionDir = join11(projectDir, sessionEntry);
21384
21757
  if (!statIsDirectory3(sessionDir))
21385
21758
  continue;
21386
- const workflowsRoot = join10(sessionDir, "subagents", "workflows");
21759
+ const workflowsRoot = join11(sessionDir, "subagents", "workflows");
21387
21760
  if (!statIsDirectory3(workflowsRoot))
21388
21761
  continue;
21389
- for (const runEntry of readdirSync9(workflowsRoot).sort()) {
21762
+ for (const runEntry of readdirSync10(workflowsRoot).sort()) {
21390
21763
  if (!runEntry.startsWith("wf_"))
21391
21764
  continue;
21392
- const workflowDir = join10(workflowsRoot, runEntry);
21765
+ const workflowDir = join11(workflowsRoot, runEntry);
21393
21766
  if (!statIsDirectory3(workflowDir))
21394
21767
  continue;
21395
21768
  discovered.push({
21396
21769
  runId: runEntry,
21397
21770
  workflowDir,
21398
21771
  parentSessionId: sessionEntry,
21399
- parentSessionPath: join10(projectDir, `${sessionEntry}.jsonl`),
21772
+ parentSessionPath: join11(projectDir, `${sessionEntry}.jsonl`),
21400
21773
  projectDir,
21401
21774
  mtimeMs: statMtimeMs2(workflowDir)
21402
21775
  });
@@ -21517,7 +21890,7 @@ function readWorkflowLaunch(parentSessionPath, runId) {
21517
21890
  return;
21518
21891
  }
21519
21892
  function findGeneratedScriptForRun(homeDir, runId) {
21520
- const projectsRoot4 = join10(homeDir, ".claude", "projects");
21893
+ const projectsRoot4 = join11(homeDir, ".claude", "projects");
21521
21894
  if (!statIsDirectory3(projectsRoot4))
21522
21895
  return;
21523
21896
  const stack = [{ path: projectsRoot4, depth: 0 }];
@@ -21525,8 +21898,8 @@ function findGeneratedScriptForRun(homeDir, runId) {
21525
21898
  const current = stack.pop();
21526
21899
  if (!current || current.depth > 8)
21527
21900
  continue;
21528
- for (const entry of readdirSync9(current.path).sort()) {
21529
- const fullPath = join10(current.path, entry);
21901
+ for (const entry of readdirSync10(current.path).sort()) {
21902
+ const fullPath = join11(current.path, entry);
21530
21903
  if (statIsDirectory3(fullPath)) {
21531
21904
  stack.push({ path: fullPath, depth: current.depth + 1 });
21532
21905
  } else if (statIsFile3(fullPath) && entry.endsWith(`${runId}.js`)) {
@@ -21597,7 +21970,7 @@ function readWorkflowScript(homeDir, launch, runId) {
21597
21970
  return parsed;
21598
21971
  }
21599
21972
  function readJournal(workflowDir) {
21600
- const journalPath = join10(workflowDir, "journal.jsonl");
21973
+ const journalPath = join11(workflowDir, "journal.jsonl");
21601
21974
  const events = parseJsonLines2(journalPath);
21602
21975
  const startedByAgent = new Map;
21603
21976
  const resultByAgent = new Map;
@@ -21703,11 +22076,11 @@ function statusForAgent(journal, agentId) {
21703
22076
  return "materialized";
21704
22077
  }
21705
22078
  function readWorkflowAgents(run2, journal, script) {
21706
- const files = statIsDirectory3(run2.workflowDir) ? readdirSync9(run2.workflowDir).sort() : [];
22079
+ const files = statIsDirectory3(run2.workflowDir) ? readdirSync10(run2.workflowDir).sort() : [];
21707
22080
  return files.map((file2) => /^agent-([a-zA-Z0-9]+)\.jsonl$/u.exec(file2)).filter((match) => Boolean(match)).map((match) => {
21708
22081
  const agentId = match[1] ?? "unknown";
21709
- const transcriptPath = join10(run2.workflowDir, `agent-${agentId}.jsonl`);
21710
- const metaPath = join10(run2.workflowDir, `agent-${agentId}.meta.json`);
22082
+ const transcriptPath = join11(run2.workflowDir, `agent-${agentId}.jsonl`);
22083
+ const metaPath = join11(run2.workflowDir, `agent-${agentId}.meta.json`);
21711
22084
  const events = parseJsonLines2(transcriptPath);
21712
22085
  const meta3 = readJsonObject3(metaPath);
21713
22086
  const result = resultObjectForAgent(journal, agentId);
@@ -21769,7 +22142,7 @@ function appendSourceRef2(sourceRefs, seen, sourceRef) {
21769
22142
  sourceRefs.push(sourceRef);
21770
22143
  }
21771
22144
  function agentNameForFile(relativeFile, agentId) {
21772
- return relativeFile ? basename9(relativeFile) : `workflow ${agentId.slice(0, 8)}`;
22145
+ return relativeFile ? basename10(relativeFile) : `workflow ${agentId.slice(0, 8)}`;
21773
22146
  }
21774
22147
  function plannedFileEntries(run2) {
21775
22148
  const basePath = run2.script?.basePath;
@@ -21804,7 +22177,7 @@ function buildTopologyForRuns(runs, observedAt) {
21804
22177
  const workflowGroupId = `claude-workflow:${runSegment}`;
21805
22178
  const workflowRefId = sourceRefId3("claude-workflow-dir", run2.workflowDir);
21806
22179
  const parentSessionRefId = sourceRefId3("claude-workflow-parent-session", run2.parentSessionPath);
21807
- const journalPath = join10(run2.workflowDir, "journal.jsonl");
22180
+ const journalPath = join11(run2.workflowDir, "journal.jsonl");
21808
22181
  const journalRefId = sourceRefId3("claude-workflow-journal", journalPath);
21809
22182
  const scriptRefId = run2.script?.scriptPath ? sourceRefId3("claude-workflow-script", run2.script.scriptPath) : undefined;
21810
22183
  appendSourceRef2(sourceRefs, sourceRefIds, {
@@ -22010,7 +22383,7 @@ function buildTopologyForRuns(runs, observedAt) {
22010
22383
  };
22011
22384
  }
22012
22385
  function readClaudeWorkflowTopology(options = {}) {
22013
- const homeDir = options.homeDir ?? homedir10();
22386
+ const homeDir = options.homeDir ?? homedir11();
22014
22387
  const maxRuns = options.maxWorkflowRuns ?? DEFAULT_MAX_WORKFLOW_RUNS;
22015
22388
  const sessionId = options.claudeSessionId?.trim();
22016
22389
  const runs = discoverWorkflowDirs(homeDir, maxRuns).filter((workflowDir) => !sessionId || workflowDir.parentSessionId === sessionId).map((workflowDir) => readWorkflowRun(homeDir, workflowDir)).filter((run2) => workflowMatchesOptions(run2, options));
@@ -22018,9 +22391,9 @@ function readClaudeWorkflowTopology(options = {}) {
22018
22391
  }
22019
22392
 
22020
22393
  // packages/agent-sessions/src/adapters/codex/topology.ts
22021
- import { existsSync as existsSync11, readdirSync as readdirSync10, readFileSync as readFileSync6, statSync as statSync10 } from "fs";
22022
- import { homedir as homedir11 } from "os";
22023
- import { basename as basename10, join as join11 } from "path";
22394
+ import { existsSync as existsSync12, readdirSync as readdirSync11, readFileSync as readFileSync7, statSync as statSync11 } from "fs";
22395
+ import { homedir as homedir12 } from "os";
22396
+ import { basename as basename11, join as join12 } from "path";
22024
22397
  var TOPOLOGY_SCHEMA_VERSION4 = "openscout.observed-harness-topology.v1";
22025
22398
  var CODEX_TOPOLOGY_SOURCE = "codex-subagents";
22026
22399
  function isObject6(value) {
@@ -22045,14 +22418,14 @@ function sourceRefId4(kind, value) {
22045
22418
  }
22046
22419
  function statIsDirectory4(path) {
22047
22420
  try {
22048
- return statSync10(path).isDirectory();
22421
+ return statSync11(path).isDirectory();
22049
22422
  } catch {
22050
22423
  return false;
22051
22424
  }
22052
22425
  }
22053
22426
  function statIsFile4(path) {
22054
22427
  try {
22055
- return statSync10(path).isFile();
22428
+ return statSync11(path).isFile();
22056
22429
  } catch {
22057
22430
  return false;
22058
22431
  }
@@ -22139,7 +22512,7 @@ function parseTomlKeyValues(raw) {
22139
22512
  }
22140
22513
  function readTomlKeyValues(path) {
22141
22514
  try {
22142
- return parseTomlKeyValues(readFileSync6(path, "utf8"));
22515
+ return parseTomlKeyValues(readFileSync7(path, "utf8"));
22143
22516
  } catch {
22144
22517
  return null;
22145
22518
  }
@@ -22153,22 +22526,22 @@ function firstString3(record2, keys) {
22153
22526
  return;
22154
22527
  }
22155
22528
  function readAgentDefinitions(root, scope) {
22156
- const agentsDir = join11(root, ".codex", "agents");
22157
- if (!existsSync11(agentsDir) || !statIsDirectory4(agentsDir)) {
22529
+ const agentsDir = join12(root, ".codex", "agents");
22530
+ if (!existsSync12(agentsDir) || !statIsDirectory4(agentsDir)) {
22158
22531
  return { agents: [], sourceRefs: [] };
22159
22532
  }
22160
22533
  const agents = [];
22161
22534
  const sourceRefs = [];
22162
- for (const entry of readdirSync10(agentsDir).sort()) {
22535
+ for (const entry of readdirSync11(agentsDir).sort()) {
22163
22536
  if (!entry.endsWith(".toml"))
22164
22537
  continue;
22165
- const path = join11(agentsDir, entry);
22538
+ const path = join12(agentsDir, entry);
22166
22539
  if (!statIsFile4(path))
22167
22540
  continue;
22168
22541
  const parsed = readTomlKeyValues(path);
22169
22542
  if (!parsed)
22170
22543
  continue;
22171
- const name = firstString3(parsed, ["name"]) ?? basename10(entry, ".toml");
22544
+ const name = firstString3(parsed, ["name"]) ?? basename11(entry, ".toml");
22172
22545
  const description = firstString3(parsed, ["description"]);
22173
22546
  const model = firstString3(parsed, ["model"]);
22174
22547
  const sandboxMode = firstString3(parsed, ["sandbox_mode", "sandbox"]);
@@ -22201,8 +22574,8 @@ function readAgentDefinitions(root, scope) {
22201
22574
  function readProjectAgentsConfig(cwd) {
22202
22575
  if (!cwd)
22203
22576
  return {};
22204
- const configPath = join11(cwd, ".codex", "config.toml");
22205
- if (!existsSync11(configPath) || !statIsFile4(configPath)) {
22577
+ const configPath = join12(cwd, ".codex", "config.toml");
22578
+ if (!existsSync12(configPath) || !statIsFile4(configPath)) {
22206
22579
  return {};
22207
22580
  }
22208
22581
  const parsed = readTomlKeyValues(configPath);
@@ -22261,7 +22634,7 @@ class CodexObservedTopologyTracker {
22261
22634
  this.threadPath = options.threadPath?.trim() || null;
22262
22635
  this.cwd = options.cwd;
22263
22636
  this.sessionName = options.sessionName;
22264
- this.homeDir = options.homeDir ?? homedir11();
22637
+ this.homeDir = options.homeDir ?? homedir12();
22265
22638
  this.now = options.now ?? (() => new Date);
22266
22639
  }
22267
22640
  updateThread(thread) {
@@ -22462,9 +22835,9 @@ class CodexObservedTopologyTracker {
22462
22835
  }
22463
22836
 
22464
22837
  // packages/runtime/src/harness-topology/service.ts
22465
- var DEFAULT_POLL_INTERVAL_MS = readPositiveIntEnv8("OPENSCOUT_TOPOLOGY_POLL_INTERVAL_MS", 1e4);
22838
+ var DEFAULT_POLL_INTERVAL_MS = readPositiveIntEnv9("OPENSCOUT_TOPOLOGY_POLL_INTERVAL_MS", 1e4);
22466
22839
  var EVENT_BUFFER_LIMIT = 500;
22467
- function readPositiveIntEnv8(name, fallback) {
22840
+ function readPositiveIntEnv9(name, fallback) {
22468
22841
  const raw = Number.parseInt(process.env[name] ?? "", 10);
22469
22842
  return Number.isFinite(raw) && raw > 0 ? raw : fallback;
22470
22843
  }
@@ -22512,7 +22885,7 @@ function normalizeSources(sources2) {
22512
22885
  }
22513
22886
  function scanObservedHarnessTopologies(options = {}) {
22514
22887
  const sources2 = normalizeSources(options.sources);
22515
- const homeDir = options.homeDir ?? homedir12();
22888
+ const homeDir = options.homeDir ?? homedir13();
22516
22889
  const now = options.now;
22517
22890
  const topologies = [];
22518
22891
  if (sources2.includes("claude")) {
@@ -25312,7 +25685,7 @@ class BrokerDeliveryStore {
25312
25685
 
25313
25686
  // packages/runtime/src/broker-journal.ts
25314
25687
  import { appendFile, mkdir, readFile, writeFile } from "fs/promises";
25315
- import { dirname as dirname4 } from "path";
25688
+ import { dirname as dirname5 } from "path";
25316
25689
  function cloneSnapshot(snapshot) {
25317
25690
  return createRuntimeRegistrySnapshot({
25318
25691
  nodes: { ...snapshot.nodes },
@@ -25465,7 +25838,7 @@ class FileBackedBrokerJournal {
25465
25838
  }
25466
25839
  const retained = this.selectEntriesToAppend(entries);
25467
25840
  this.writeQueue = this.writeQueue.then(async () => {
25468
- await mkdir(dirname4(this.filePath), { recursive: true });
25841
+ await mkdir(dirname5(this.filePath), { recursive: true });
25469
25842
  if (retained.length === 0) {
25470
25843
  return;
25471
25844
  }
@@ -25522,7 +25895,7 @@ class FileBackedBrokerJournal {
25522
25895
  return [...this.state.invocationDispatchJobs.values()].filter((job) => !options.state || job.state === options.state).sort((left, right) => left.createdAt - right.createdAt).slice(0, limit);
25523
25896
  }
25524
25897
  async rewriteEntries(entries) {
25525
- await mkdir(dirname4(this.filePath), { recursive: true });
25898
+ await mkdir(dirname5(this.filePath), { recursive: true });
25526
25899
  const payload = entries.length > 0 ? `${entries.map((entry) => JSON.stringify(entry)).join(`
25527
25900
  `)}
25528
25901
  ` : "";
@@ -26038,6 +26411,7 @@ class BrokerReadCursorStore {
26038
26411
  }
26039
26412
 
26040
26413
  // packages/runtime/src/broker-work-item-store.ts
26414
+ import { createHash as createHash2 } from "crypto";
26041
26415
  function metadataStringValue(metadata, key) {
26042
26416
  const value = metadata?.[key];
26043
26417
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -26098,11 +26472,34 @@ function metadataContainsDeliveryWorkItemValues(existing, expected) {
26098
26472
  }
26099
26473
  return true;
26100
26474
  }
26475
+ function deliveryWorkItemFingerprint(record2) {
26476
+ const metadata = { ...record2.metadata ?? {} };
26477
+ delete metadata.deliveryWorkItemFingerprint;
26478
+ const identity2 = normalizeComparableDeliveryValue({
26479
+ title: record2.title,
26480
+ summary: record2.summary,
26481
+ acceptanceState: record2.acceptanceState,
26482
+ createdById: record2.createdById,
26483
+ ownerId: record2.ownerId,
26484
+ nextMoveOwnerId: record2.nextMoveOwnerId,
26485
+ conversationId: record2.conversationId,
26486
+ parentId: record2.parentId,
26487
+ priority: record2.priority,
26488
+ labels: record2.labels,
26489
+ requestedById: record2.kind === "work_item" ? record2.requestedById : undefined,
26490
+ metadata
26491
+ });
26492
+ return createHash2("sha256").update(JSON.stringify(identity2)).digest("hex");
26493
+ }
26101
26494
  function existingDeliveryWorkItemMatches(existing, proposed) {
26102
26495
  if (existing.kind !== "work_item" || proposed.kind !== "work_item") {
26103
26496
  return false;
26104
26497
  }
26105
- return existing.title === proposed.title && (existing.summary ?? "") === (proposed.summary ?? "") && existing.acceptanceState === proposed.acceptanceState && existing.createdById === proposed.createdById && existing.ownerId === proposed.ownerId && existing.nextMoveOwnerId === proposed.nextMoveOwnerId && existing.conversationId === proposed.conversationId && existing.parentId === proposed.parentId && existing.priority === proposed.priority && sameDeliveryWorkItemLabels(existing.labels, proposed.labels) && existing.requestedById === proposed.requestedById && metadataContainsDeliveryWorkItemValues(existing.metadata, proposed.metadata);
26498
+ const existingFingerprint = metadataStringValue(existing.metadata, "deliveryWorkItemFingerprint");
26499
+ if (existingFingerprint) {
26500
+ return existingFingerprint === deliveryWorkItemFingerprint(proposed);
26501
+ }
26502
+ return existing.title === proposed.title && (existing.summary ?? "") === (proposed.summary ?? "") && existing.createdById === proposed.createdById && existing.conversationId === proposed.conversationId && existing.parentId === proposed.parentId && existing.priority === proposed.priority && sameDeliveryWorkItemLabels(existing.labels, proposed.labels) && existing.requestedById === proposed.requestedById && metadataContainsDeliveryWorkItemValues(existing.metadata, proposed.metadata);
26106
26503
  }
26107
26504
  function invocationCollaborationRecordId(invocation) {
26108
26505
  const nested = invocation.context?.["collaboration"];
@@ -26180,12 +26577,16 @@ class BrokerWorkItemStore {
26180
26577
  return;
26181
26578
  }
26182
26579
  const now = flight.completedAt ?? Date.now();
26183
- const nextState = flight.state === "completed" ? "done" : flight.state === "cancelled" ? "cancelled" : "waiting";
26184
- const nextEventKind = flight.state === "completed" ? "done" : flight.state === "cancelled" ? "cancelled" : "waiting";
26580
+ const requiresReview = flight.state === "completed" && record2.acceptanceState !== "none";
26581
+ const nextState = flight.state === "completed" ? requiresReview ? "review" : "done" : flight.state === "cancelled" ? "cancelled" : "waiting";
26582
+ const nextEventKind = flight.state === "completed" ? requiresReview ? "review_requested" : "done" : flight.state === "cancelled" ? "cancelled" : "waiting";
26583
+ const nextMoveOwnerId = requiresReview ? record2.requestedById ?? record2.createdById : flight.state === "failed" ? record2.requestedById ?? record2.ownerId : record2.nextMoveOwnerId;
26185
26584
  const summary = compactWorkSummary(output) ?? compactWorkSummary(flight.output) ?? compactWorkSummary(flight.error) ?? compactWorkSummary(flight.summary) ?? `${flight.targetAgentId} completed.`;
26186
26585
  const nextRecord = {
26187
26586
  ...record2,
26188
26587
  state: nextState,
26588
+ acceptanceState: requiresReview ? "pending" : record2.acceptanceState,
26589
+ nextMoveOwnerId,
26189
26590
  summary: record2.summary ?? summary,
26190
26591
  updatedAt: now,
26191
26592
  progress: {
@@ -26194,7 +26595,19 @@ class BrokerWorkItemStore {
26194
26595
  completedSteps: flight.state === "completed" ? 1 : record2.progress?.completedSteps,
26195
26596
  totalSteps: flight.state === "completed" ? 1 : record2.progress?.totalSteps
26196
26597
  },
26197
- ...flight.state === "completed" ? { completedAt: record2.completedAt ?? now } : {},
26598
+ reviewRequestedAt: requiresReview ? now : record2.reviewRequestedAt,
26599
+ completedAt: nextState === "done" || nextState === "cancelled" ? record2.completedAt ?? now : undefined,
26600
+ ...flight.state === "failed" ? {
26601
+ waitingOn: {
26602
+ kind: "actor",
26603
+ label: "Decide whether to retry the failed execution",
26604
+ ...nextMoveOwnerId ? { targetId: nextMoveOwnerId } : {},
26605
+ metadata: {
26606
+ invocationId: invocation.id,
26607
+ flightId: flight.id
26608
+ }
26609
+ }
26610
+ } : { waitingOn: undefined },
26198
26611
  metadata: {
26199
26612
  ...record2.metadata ?? {},
26200
26613
  lastInvocationId: invocation.id,
@@ -26245,7 +26658,7 @@ class BrokerWorkItemStore {
26245
26658
  const source = metadataStringValue(input.payload.invocationMetadata, "source") || metadataStringValue(input.payload.messageMetadata, "source") || "broker-delivery";
26246
26659
  const recordId = workItem.id?.trim() || input.payload.collaborationRecordId?.trim() || this.options.createId("work");
26247
26660
  const labels = mergeScoutLabels(input.payload.labels, workItem.labels);
26248
- return {
26661
+ const record2 = {
26249
26662
  id: recordId,
26250
26663
  kind: "work_item",
26251
26664
  state: "working",
@@ -26269,6 +26682,11 @@ class BrokerWorkItemStore {
26269
26682
  deliveryRequestId: input.requestId
26270
26683
  }
26271
26684
  };
26685
+ record2.metadata = {
26686
+ ...record2.metadata ?? {},
26687
+ deliveryWorkItemFingerprint: deliveryWorkItemFingerprint(record2)
26688
+ };
26689
+ return record2;
26272
26690
  }
26273
26691
  buildDeliveryWorkItemCreatedEvent(record2, input) {
26274
26692
  return {
@@ -26289,15 +26707,15 @@ class BrokerWorkItemStore {
26289
26707
 
26290
26708
  // packages/runtime/src/local-agents.ts
26291
26709
  import { randomUUID as randomUUID2 } from "crypto";
26292
- import { existsSync as existsSync27, readFileSync as readFileSync14 } from "fs";
26710
+ import { existsSync as existsSync29, readFileSync as readFileSync15 } from "fs";
26293
26711
  import { mkdir as mkdir8, rm as rm4, stat as stat6, writeFile as writeFile8 } from "fs/promises";
26294
- import { basename as basename15, dirname as dirname17, join as join28, resolve as resolve12 } from "path";
26712
+ import { basename as basename16, dirname as dirname18, join as join30, resolve as resolve12 } from "path";
26295
26713
  import { fileURLToPath as fileURLToPath6 } from "url";
26296
26714
 
26297
26715
  // packages/agent-sessions/src/codex-executable.ts
26298
26716
  import { execFileSync } from "child_process";
26299
26717
  import { accessSync, constants } from "fs";
26300
- import { delimiter, join as join12 } from "path";
26718
+ import { delimiter, join as join13 } from "path";
26301
26719
  function isExecutable(filePath) {
26302
26720
  if (!filePath)
26303
26721
  return false;
@@ -26341,11 +26759,11 @@ function codexAppBundleCandidates(env) {
26341
26759
  const appNames = ["Codex.app", "ChatGPT.app"];
26342
26760
  const candidates = appNames.flatMap((appName) => [
26343
26761
  {
26344
- path: join12("/Applications", appName, "Contents", "Resources", "codex"),
26762
+ path: join13("/Applications", appName, "Contents", "Resources", "codex"),
26345
26763
  source: "codex_app_bundle"
26346
26764
  },
26347
26765
  {
26348
- path: join12(env.HOME ?? "", "Applications", appName, "Contents", "Resources", "codex"),
26766
+ path: join13(env.HOME ?? "", "Applications", appName, "Contents", "Resources", "codex"),
26349
26767
  source: "codex_app_bundle"
26350
26768
  }
26351
26769
  ]);
@@ -26353,7 +26771,7 @@ function codexAppBundleCandidates(env) {
26353
26771
  }
26354
26772
  function pathCandidates(env) {
26355
26773
  return (env.PATH ?? "").split(delimiter).filter(Boolean).map((directory) => ({
26356
- path: join12(directory, "codex"),
26774
+ path: join13(directory, "codex"),
26357
26775
  source: "path"
26358
26776
  }));
26359
26777
  }
@@ -26364,7 +26782,7 @@ function commonCandidates(env) {
26364
26782
  "/opt/homebrew/bin",
26365
26783
  "/usr/local/bin"
26366
26784
  ].filter(Boolean).map((directory) => ({
26367
- path: join12(directory, "codex"),
26785
+ path: join13(directory, "codex"),
26368
26786
  source: "common"
26369
26787
  }));
26370
26788
  }
@@ -26490,9 +26908,9 @@ function isDispatchStalledError(error48) {
26490
26908
  }
26491
26909
  // packages/runtime/src/repo-service/process.ts
26492
26910
  import { spawn as spawn2 } from "child_process";
26493
- import { existsSync as existsSync12 } from "fs";
26911
+ import { existsSync as existsSync13 } from "fs";
26494
26912
  import { Socket as Socket2 } from "net";
26495
- import { dirname as dirname5, resolve } from "path";
26913
+ import { dirname as dirname6, resolve } from "path";
26496
26914
  import { fileURLToPath } from "url";
26497
26915
  var REPO_SERVICE_MAX_BUFFER = 2 * 1024 * 1024;
26498
26916
  var CAPABILITIES_SCHEMA2 = "openscout.probe.capabilities/v1";
@@ -26521,7 +26939,7 @@ function resolveRepoServiceCommand(subcommand) {
26521
26939
  if (explicit) {
26522
26940
  return { command: explicit, args: [subcommand], subcommand };
26523
26941
  }
26524
- const moduleDir = dirname5(fileURLToPath(import.meta.url));
26942
+ const moduleDir = dirname6(fileURLToPath(import.meta.url));
26525
26943
  const candidateRoots = [resolve(moduleDir, "../../../.."), process.cwd()];
26526
26944
  const seen = new Set;
26527
26945
  for (const root of candidateRoots) {
@@ -26529,7 +26947,7 @@ function resolveRepoServiceCommand(subcommand) {
26529
26947
  continue;
26530
26948
  seen.add(root);
26531
26949
  const manifestPath = resolve(root, "crates", "openscout-repo-service", "Cargo.toml");
26532
- if (!existsSync12(manifestPath))
26950
+ if (!existsSync13(manifestPath))
26533
26951
  continue;
26534
26952
  return {
26535
26953
  command: process.env.CARGO?.trim() || "cargo",
@@ -26645,7 +27063,7 @@ class RepoServiceSocketClient {
26645
27063
  return { state: "spawn" };
26646
27064
  }
26647
27065
  const socketPath = resolveScoutdProbesSocketPath(this.env);
26648
- const socketExists = existsSync12(socketPath);
27066
+ const socketExists = existsSync13(socketPath);
26649
27067
  if (!socketExists) {
26650
27068
  this.capabilities = null;
26651
27069
  this.lastError = null;
@@ -26931,8 +27349,8 @@ async function requestJsonWithBun2(connect, socketPath, payload, timeoutMs) {
26931
27349
  }
26932
27350
 
26933
27351
  // packages/runtime/src/system-probes/git-build-info.ts
26934
- import { existsSync as existsSync13, realpathSync, statSync as statSync11 } from "fs";
26935
- import { dirname as dirname6, resolve as resolve2 } from "path";
27352
+ import { existsSync as existsSync14, realpathSync, statSync as statSync12 } from "fs";
27353
+ import { dirname as dirname7, resolve as resolve2 } from "path";
26936
27354
  var staticMetadataByRepo = new Map;
26937
27355
  function realpathOrResolved(path) {
26938
27356
  try {
@@ -26944,8 +27362,8 @@ function realpathOrResolved(path) {
26944
27362
  function directoryOrParent(path) {
26945
27363
  const resolved = resolve2(path);
26946
27364
  try {
26947
- const stat2 = statSync11(resolved);
26948
- return stat2.isDirectory() ? resolved : dirname6(resolved);
27365
+ const stat2 = statSync12(resolved);
27366
+ return stat2.isDirectory() ? resolved : dirname7(resolved);
26949
27367
  } catch {
26950
27368
  return resolved;
26951
27369
  }
@@ -26953,10 +27371,10 @@ function directoryOrParent(path) {
26953
27371
  function canonicalRepoRoot(rawPath) {
26954
27372
  let current = realpathOrResolved(directoryOrParent(rawPath));
26955
27373
  while (true) {
26956
- if (existsSync13(resolve2(current, ".git"))) {
27374
+ if (existsSync14(resolve2(current, ".git"))) {
26957
27375
  return realpathOrResolved(current);
26958
27376
  }
26959
- const parent = dirname6(current);
27377
+ const parent = dirname7(current);
26960
27378
  if (parent === current) {
26961
27379
  return realpathOrResolved(directoryOrParent(rawPath));
26962
27380
  }
@@ -27576,8 +27994,8 @@ var tailscaleStatusProbe = defineProbe({
27576
27994
  });
27577
27995
 
27578
27996
  // packages/runtime/src/system-probes/tmux.ts
27579
- import { homedir as homedir13 } from "os";
27580
- import { join as join13 } from "path";
27997
+ import { homedir as homedir14 } from "os";
27998
+ import { join as join14 } from "path";
27581
27999
  var TMUX_TTL_MS = 5000;
27582
28000
  var TMUX_TIMEOUT_MS = 1500;
27583
28001
  var ZELLIJ_TIMEOUT_MS = 1500;
@@ -27628,7 +28046,7 @@ function tmuxSocketArgs(key) {
27628
28046
  return key === "default" ? [] : ["-S", key];
27629
28047
  }
27630
28048
  function zellijSocketDirFromEnv(env) {
27631
- return env.ZELLIJ_SOCKET_DIR?.trim() || env.OPENSCOUT_ZELLIJ_SOCKET_DIR?.trim() || join13(env.HOME?.trim() || homedir13(), ".openscout", "zellij-sockets");
28049
+ return env.ZELLIJ_SOCKET_DIR?.trim() || env.OPENSCOUT_ZELLIJ_SOCKET_DIR?.trim() || join14(env.HOME?.trim() || homedir14(), ".openscout", "zellij-sockets");
27632
28050
  }
27633
28051
  function zellijSocketKey(input) {
27634
28052
  if (typeof input === "string")
@@ -27837,15 +28255,15 @@ async function captureTmuxPane(target, input) {
27837
28255
  // packages/runtime/src/system-probes/sessions.ts
27838
28256
  import { createReadStream } from "fs";
27839
28257
  import { readdir, stat as stat2 } from "fs/promises";
27840
- import { homedir as homedir14 } from "os";
27841
- import { basename as basename11, dirname as dirname7, join as join14, resolve as resolve3 } from "path";
28258
+ import { homedir as homedir15 } from "os";
28259
+ import { basename as basename12, dirname as dirname8, join as join15, resolve as resolve3 } from "path";
27842
28260
  import { createInterface } from "readline";
27843
28261
  function positiveInteger2(value, fallback, max) {
27844
28262
  return Number.isFinite(value) && value > 0 ? Math.min(max, Math.floor(value)) : fallback;
27845
28263
  }
27846
28264
  function normalizeScanKey(input) {
27847
28265
  return {
27848
- home: resolve3(input.home?.trim() || homedir14()),
28266
+ home: resolve3(input.home?.trim() || homedir15()),
27849
28267
  workspaceRoot: input.workspaceRoot?.trim() ? resolve3(input.workspaceRoot) : null,
27850
28268
  maxAgeDays: positiveInteger2(input.maxAgeDays, 14, 3650),
27851
28269
  limit: positiveInteger2(input.limit, 250, 1e4)
@@ -27869,7 +28287,7 @@ function extractProjectName(filePath) {
27869
28287
  const claudeMatch = filePath.match(/\.claude\/projects\/[^/]*-dev-([^/]+)/);
27870
28288
  if (claudeMatch?.[1])
27871
28289
  return claudeMatch[1];
27872
- return basename11(dirname7(filePath)) || "unknown";
28290
+ return basename12(dirname8(filePath)) || "unknown";
27873
28291
  }
27874
28292
  function detectAgent(filePath, fallback = "unknown") {
27875
28293
  if (filePath.includes(".claude"))
@@ -27901,7 +28319,7 @@ async function scanJsonlFiles(input) {
27901
28319
  for (const entry of entries) {
27902
28320
  if (input.signal.aborted || out.length >= input.cap)
27903
28321
  return;
27904
- const filePath = join14(directory, entry.name);
28322
+ const filePath = join15(directory, entry.name);
27905
28323
  if (entry.isDirectory()) {
27906
28324
  if (input.skipSubagents && entry.name === "subagents")
27907
28325
  continue;
@@ -27932,9 +28350,9 @@ async function scanSessionFilesLocal(input, ctx) {
27932
28350
  const normalized = normalizeScanKey(input);
27933
28351
  const cutoffMs = Date.now() - normalized.maxAgeDays * 24 * 60 * 60000;
27934
28352
  const roots = [
27935
- { root: join14(normalized.home, ".claude", "projects"), agent: "claude-code", maxDepth: 8, skipSubagents: true },
27936
- { root: join14(normalized.home, ".codex"), agent: "codex", maxDepth: 8, skipSubagents: true },
27937
- { root: join14(normalized.home, ".openai-codex"), agent: "codex", maxDepth: 8, skipSubagents: true }
28353
+ { root: join15(normalized.home, ".claude", "projects"), agent: "claude-code", maxDepth: 8, skipSubagents: true },
28354
+ { root: join15(normalized.home, ".codex"), agent: "codex", maxDepth: 8, skipSubagents: true },
28355
+ { root: join15(normalized.home, ".openai-codex"), agent: "codex", maxDepth: 8, skipSubagents: true }
27938
28356
  ];
27939
28357
  const results = [];
27940
28358
  const cap = Math.max(normalized.limit * 4, normalized.limit + 100);
@@ -28037,7 +28455,7 @@ var sessionsSearchProbe = defineProbeFamily({
28037
28455
  run: (key, ctx) => searchSessionFilesLocal(parseKey(key), ctx)
28038
28456
  });
28039
28457
  // packages/runtime/src/system-probes/cert-status.ts
28040
- import { existsSync as existsSync14, realpathSync as realpathSync2 } from "fs";
28458
+ import { existsSync as existsSync15, realpathSync as realpathSync2 } from "fs";
28041
28459
  import { resolve as resolve4 } from "path";
28042
28460
  function canonicalCertPath(path) {
28043
28461
  try {
@@ -28058,7 +28476,7 @@ var certStatusProbe = defineProbeFamily({
28058
28476
  maxConcurrentKeys: 2,
28059
28477
  normalizeKey: canonicalCertPath,
28060
28478
  run: async (certPath, ctx) => {
28061
- if (!existsSync14(certPath)) {
28479
+ if (!existsSync15(certPath)) {
28062
28480
  return {
28063
28481
  certPath,
28064
28482
  exists: false,
@@ -29052,14 +29470,14 @@ class SessionRegistry {
29052
29470
  }
29053
29471
  }
29054
29472
  // packages/agent-sessions/src/adapters/grok-acp/adapter.ts
29055
- import { existsSync as existsSync15 } from "fs";
29056
- import { homedir as homedir15 } from "os";
29057
- import { join as join15 } from "path";
29473
+ import { existsSync as existsSync16 } from "fs";
29474
+ import { homedir as homedir16 } from "os";
29475
+ import { join as join16 } from "path";
29058
29476
 
29059
29477
  // packages/agent-sessions/src/adapters/acp/adapter.ts
29060
29478
  import { spawn as spawn3 } from "child_process";
29061
29479
  import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
29062
- import { dirname as dirname8, isAbsolute, relative as relative5, resolve as resolve5 } from "path";
29480
+ import { dirname as dirname9, isAbsolute, relative as relative5, resolve as resolve5 } from "path";
29063
29481
  import { pathToFileURL } from "url";
29064
29482
  var DEFAULT_STARTUP_TIMEOUT_MS = 30000;
29065
29483
  var DEFAULT_REQUEST_TIMEOUT_MS = 60000;
@@ -29830,7 +30248,7 @@ ${text}`
29830
30248
  return;
29831
30249
  }
29832
30250
  const filePath = this.resolveAllowedPath(requestedPath);
29833
- await mkdir2(dirname8(filePath), { recursive: true });
30251
+ await mkdir2(dirname9(filePath), { recursive: true });
29834
30252
  await writeFile2(filePath, params.content, "utf8");
29835
30253
  this.writeResult(message.id, {});
29836
30254
  }
@@ -30000,8 +30418,8 @@ function defaultGrokCommand(env) {
30000
30418
  if (override) {
30001
30419
  return override;
30002
30420
  }
30003
- const installed = join15(homedir15(), ".grok", "bin", "grok");
30004
- return existsSync15(installed) ? installed : "grok";
30421
+ const installed = join16(homedir16(), ".grok", "bin", "grok");
30422
+ return existsSync16(installed) ? installed : "grok";
30005
30423
  }
30006
30424
  function isRecord4(value) {
30007
30425
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -30062,6 +30480,66 @@ var createAdapter = (config2) => {
30062
30480
  }
30063
30481
  });
30064
30482
  };
30483
+ // packages/agent-sessions/src/adapters/kimi-acp/adapter.ts
30484
+ import { existsSync as existsSync17 } from "fs";
30485
+ import { homedir as homedir17 } from "os";
30486
+ import { join as join17 } from "path";
30487
+ var DEFAULT_KIMI_ARGS = ["acp"];
30488
+ var DEFAULT_KIMI_STARTUP_TIMEOUT_MS = 60000;
30489
+ var KIMI_ACP_ADAPTER_TYPE = "kimi-acp";
30490
+ function isRecord5(value) {
30491
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
30492
+ }
30493
+ function stringValue9(value) {
30494
+ return typeof value === "string" && value.trim() ? value.trim() : null;
30495
+ }
30496
+ function stringArray4(value) {
30497
+ if (!Array.isArray(value)) {
30498
+ return null;
30499
+ }
30500
+ const entries = value.filter((entry) => typeof entry === "string");
30501
+ return entries.length === value.length ? entries : null;
30502
+ }
30503
+ function firstNonEmptyString2(...values) {
30504
+ for (const value of values) {
30505
+ const trimmed = value?.trim();
30506
+ if (trimmed) {
30507
+ return trimmed;
30508
+ }
30509
+ }
30510
+ return null;
30511
+ }
30512
+ function defaultKimiCommand(env) {
30513
+ const override = firstNonEmptyString2(env?.KIMI_CLI_BIN, process.env.KIMI_CLI_BIN);
30514
+ if (override) {
30515
+ return override;
30516
+ }
30517
+ const installedCandidates = [
30518
+ join17(homedir17(), ".kimi-code", "bin", "kimi"),
30519
+ join17(homedir17(), ".local", "bin", "kimi")
30520
+ ];
30521
+ return installedCandidates.find((candidate) => existsSync17(candidate)) ?? "kimi";
30522
+ }
30523
+ var createAdapter2 = (config2) => {
30524
+ const rawOptions = isRecord5(config2.options) ? config2.options : {};
30525
+ const command = stringValue9(rawOptions.command) ?? defaultKimiCommand(config2.env);
30526
+ const args = stringArray4(rawOptions.args) ?? DEFAULT_KIMI_ARGS;
30527
+ const authMethodPreference = stringArray4(rawOptions.authMethodPreference) ?? ["login"];
30528
+ return new AcpAdapter({
30529
+ ...config2,
30530
+ options: {
30531
+ clientName: "openscout",
30532
+ clientTitle: "OpenScout",
30533
+ ...rawOptions,
30534
+ adapterType: KIMI_ACP_ADAPTER_TYPE,
30535
+ command,
30536
+ args,
30537
+ startupTimeoutMs: typeof rawOptions.startupTimeoutMs === "number" ? rawOptions.startupTimeoutMs : DEFAULT_KIMI_STARTUP_TIMEOUT_MS,
30538
+ requireAuth: typeof rawOptions.requireAuth === "boolean" ? rawOptions.requireAuth : true,
30539
+ authMethodPreference
30540
+ }
30541
+ });
30542
+ };
30065
30543
  // packages/agent-sessions/src/runtime/process.ts
30066
30544
  async function spawnHarnessProcess(command, args, options) {
30067
30545
  if (typeof Bun !== "undefined") {
@@ -31193,7 +31671,7 @@ class PiAdapter extends BaseAdapter {
31193
31671
  });
31194
31672
  }
31195
31673
  }
31196
- var createAdapter2 = (config2) => new PiAdapter(config2);
31674
+ var createAdapter3 = (config2) => new PiAdapter(config2);
31197
31675
  // packages/runtime/src/requester-timeout.ts
31198
31676
  class RequesterWaitTimeoutError extends Error {
31199
31677
  code = "REQUESTER_WAIT_TIMEOUT";
@@ -31210,32 +31688,32 @@ function isRequesterWaitTimeoutError(error48) {
31210
31688
  return error48 instanceof RequesterWaitTimeoutError || Boolean(error48) && typeof error48 === "object" && error48.code === "REQUESTER_WAIT_TIMEOUT" && typeof error48.timeoutMs === "number";
31211
31689
  }
31212
31690
 
31213
- // packages/runtime/src/grok-acp-invocation.ts
31214
- var GROK_ACP_HARD_CEILING_MS = 30 * 60000;
31215
- function completedText(snapshot) {
31691
+ // packages/runtime/src/acp-agent-invocation.ts
31692
+ var DEFAULT_ACP_HARD_CEILING_MS = 30 * 60000;
31693
+ function completedText(snapshot, label) {
31216
31694
  const turn = snapshot?.turns.at(-1);
31217
31695
  if (!turn) {
31218
- return "The Grok ACP session completed without an observable turn.";
31696
+ return `The ${label} session completed without an observable turn.`;
31219
31697
  }
31220
31698
  const text = turn.blocks.map(({ block }) => block.type === "text" ? block.text.trim() : "").filter(Boolean).join(`
31221
31699
 
31222
31700
  `);
31223
- return text || "The Grok ACP session completed without a text reply.";
31701
+ return text || `The ${label} session completed without a text reply.`;
31224
31702
  }
31225
- async function invokeGrokAcpAgent(options) {
31703
+ async function invokeAcpAgent(options) {
31226
31704
  const registry3 = new SessionRegistry({
31227
31705
  adapters: {
31228
- "grok-acp": createAdapter
31706
+ [options.adapterType]: options.createAdapter
31229
31707
  }
31230
31708
  });
31231
- const session = await registry3.createSession("grok-acp", {
31709
+ const session = await registry3.createSession(options.adapterType, {
31232
31710
  sessionId: options.sessionId,
31233
- name: options.name ?? "Grok ACP",
31711
+ name: options.name ?? options.label,
31234
31712
  cwd: options.cwd
31235
31713
  });
31236
- const turn = runGrokAcpTurn(registry3, session.id, options.prompt);
31714
+ const turn = runAcpTurn(registry3, session.id, options);
31237
31715
  try {
31238
- return await waitForRequesterResult(turn, options.timeoutMs, "Grok ACP");
31716
+ return await waitForRequesterResult(turn, options.timeoutMs, options.label);
31239
31717
  } catch (error48) {
31240
31718
  if (isRequesterWaitTimeoutError(error48)) {
31241
31719
  turn.catch(() => {
@@ -31245,52 +31723,48 @@ async function invokeGrokAcpAgent(options) {
31245
31723
  throw error48;
31246
31724
  }
31247
31725
  }
31248
- async function runGrokAcpTurn(registry3, sessionId, prompt) {
31726
+ async function runAcpTurn(registry3, sessionId, options) {
31249
31727
  try {
31250
31728
  await new Promise((resolve6, reject) => {
31251
31729
  let unsubscribe = () => {};
31252
31730
  let settled = false;
31731
+ const hardCeilingMs = options.hardCeilingMs ?? DEFAULT_ACP_HARD_CEILING_MS;
31253
31732
  const finish = (error48) => {
31254
31733
  if (settled)
31255
31734
  return;
31256
31735
  settled = true;
31257
31736
  clearTimeout(hardCeiling);
31258
31737
  unsubscribe();
31259
- if (error48) {
31738
+ if (error48)
31260
31739
  reject(error48);
31261
- } else {
31740
+ else
31262
31741
  resolve6();
31263
- }
31264
31742
  };
31265
31743
  const hardCeiling = setTimeout(() => {
31266
- finish(new Error(`Grok ACP exceeded the ${GROK_ACP_HARD_CEILING_MS}ms hard ceiling.`));
31267
- }, GROK_ACP_HARD_CEILING_MS);
31744
+ finish(new Error(`${options.label} exceeded the ${hardCeilingMs}ms hard ceiling.`));
31745
+ }, hardCeilingMs);
31268
31746
  hardCeiling.unref?.();
31269
31747
  unsubscribe = registry3.onEvent(({ event }) => {
31270
- if ("sessionId" in event && event.sessionId !== sessionId) {
31748
+ if ("sessionId" in event && event.sessionId !== sessionId)
31271
31749
  return;
31272
- }
31273
31750
  if (event.event === "turn:end") {
31274
31751
  finish();
31275
31752
  return;
31276
31753
  }
31277
31754
  if (event.event === "turn:error") {
31278
- finish(new Error(event.message || "Grok ACP turn failed."));
31755
+ finish(new Error(event.message || `${options.label} turn failed.`));
31279
31756
  }
31280
31757
  });
31281
- Promise.resolve(registry3.send({
31282
- sessionId,
31283
- text: prompt
31284
- })).catch((error48) => {
31758
+ Promise.resolve(registry3.send({ sessionId, text: options.prompt })).catch((error48) => {
31285
31759
  finish(error48 instanceof Error ? error48 : new Error(String(error48)));
31286
31760
  });
31287
31761
  });
31288
31762
  const snapshot = registry3.getSessionSnapshot(sessionId);
31289
31763
  return {
31290
- output: completedText(snapshot),
31764
+ output: completedText(snapshot, options.label),
31291
31765
  sessionId,
31292
31766
  metadata: {
31293
- adapterType: "grok-acp",
31767
+ adapterType: options.adapterType,
31294
31768
  providerMeta: snapshot?.session.providerMeta
31295
31769
  }
31296
31770
  };
@@ -31308,9 +31782,8 @@ function requesterTimeoutMs(timeoutMs) {
31308
31782
  }
31309
31783
  async function waitForRequesterResult(promise2, timeoutMs, label) {
31310
31784
  const effectiveTimeoutMs = requesterTimeoutMs(timeoutMs);
31311
- if (effectiveTimeoutMs === null) {
31785
+ if (effectiveTimeoutMs === null)
31312
31786
  return await promise2;
31313
- }
31314
31787
  let timer = null;
31315
31788
  const timeout = new Promise((_resolve, reject) => {
31316
31789
  timer = setTimeout(() => {
@@ -31319,9 +31792,28 @@ async function waitForRequesterResult(promise2, timeoutMs, label) {
31319
31792
  timer.unref?.();
31320
31793
  });
31321
31794
  return await Promise.race([promise2, timeout]).finally(() => {
31322
- if (timer) {
31795
+ if (timer)
31323
31796
  clearTimeout(timer);
31324
- }
31797
+ });
31798
+ }
31799
+
31800
+ // packages/runtime/src/grok-acp-invocation.ts
31801
+ async function invokeGrokAcpAgent(options) {
31802
+ return await invokeAcpAgent({
31803
+ ...options,
31804
+ adapterType: "grok-acp",
31805
+ createAdapter,
31806
+ label: "Grok ACP"
31807
+ });
31808
+ }
31809
+
31810
+ // packages/runtime/src/kimi-acp-invocation.ts
31811
+ async function invokeKimiAcpAgent(options) {
31812
+ return await invokeAcpAgent({
31813
+ ...options,
31814
+ adapterType: "kimi-acp",
31815
+ createAdapter: createAdapter2,
31816
+ label: "Kimi Code ACP"
31325
31817
  });
31326
31818
  }
31327
31819
 
@@ -31329,8 +31821,8 @@ async function waitForRequesterResult(promise2, timeoutMs, label) {
31329
31821
  import { randomUUID } from "crypto";
31330
31822
  import { spawn as spawn4 } from "child_process";
31331
31823
  import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
31332
- import { existsSync as existsSync17, readFileSync as readFileSync7 } from "fs";
31333
- import { join as join17 } from "path";
31824
+ import { existsSync as existsSync19, readFileSync as readFileSync8 } from "fs";
31825
+ import { join as join19 } from "path";
31334
31826
 
31335
31827
  // packages/runtime/src/managed-agent-environment.ts
31336
31828
  function managedAgentEnvironmentEntries(options) {
@@ -31357,31 +31849,31 @@ function buildManagedAgentShellExports(options) {
31357
31849
  }
31358
31850
 
31359
31851
  // packages/runtime/src/tool-resolution.ts
31360
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync16 } from "fs";
31361
- import { homedir as homedir16 } from "os";
31362
- import { basename as basename12, dirname as dirname9, join as join16, resolve as resolve6 } from "path";
31852
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync18 } from "fs";
31853
+ import { homedir as homedir18 } from "os";
31854
+ import { basename as basename13, dirname as dirname10, join as join18, resolve as resolve6 } from "path";
31363
31855
  var DEFAULT_COMMON_EXECUTABLE_DIRECTORIES = [
31364
- join16(homedir16(), ".bun", "bin"),
31856
+ join18(homedir18(), ".bun", "bin"),
31365
31857
  "/opt/homebrew/bin",
31366
31858
  "/usr/local/bin"
31367
31859
  ];
31368
31860
  function commonClaudeExecutableDirectories(env) {
31369
- const home = env.HOME ?? homedir16();
31861
+ const home = env.HOME ?? homedir18();
31370
31862
  return [
31371
- join16(home, ".local", "bin"),
31372
- join16(home, ".claude", "local"),
31863
+ join18(home, ".local", "bin"),
31864
+ join18(home, ".claude", "local"),
31373
31865
  "/opt/homebrew/bin",
31374
31866
  "/usr/local/bin",
31375
- join16(home, ".bun", "bin")
31867
+ join18(home, ".bun", "bin")
31376
31868
  ];
31377
31869
  }
31378
31870
  function expandHomePath(value, env = process.env) {
31379
- const home = env.HOME ?? homedir16();
31871
+ const home = env.HOME ?? homedir18();
31380
31872
  if (value === "~") {
31381
31873
  return home;
31382
31874
  }
31383
31875
  if (value.startsWith("~/")) {
31384
- return join16(home, value.slice(2));
31876
+ return join18(home, value.slice(2));
31385
31877
  }
31386
31878
  return value;
31387
31879
  }
@@ -31438,7 +31930,7 @@ function resolveExecutableFromSearch(options) {
31438
31930
  ], env);
31439
31931
  for (const directory of searchDirectories) {
31440
31932
  for (const name of options.names) {
31441
- const candidate = join16(directory, name);
31933
+ const candidate = join18(directory, name);
31442
31934
  if (isExecutablePath(candidate)) {
31443
31935
  return {
31444
31936
  path: candidate,
@@ -31452,7 +31944,7 @@ function resolveExecutableFromSearch(options) {
31452
31944
  function resolveExecutableFromDirectories(directories, names, env, source) {
31453
31945
  for (const directory of dedupeDirectories(directories, env)) {
31454
31946
  for (const name of names) {
31455
- const candidate = join16(directory, name);
31947
+ const candidate = join18(directory, name);
31456
31948
  if (isExecutablePath(candidate)) {
31457
31949
  return { path: candidate, source };
31458
31950
  }
@@ -31492,12 +31984,12 @@ function resolveOpenScoutRepoRoot(options = {}) {
31492
31984
  for (const start of starts) {
31493
31985
  let current = resolve6(start);
31494
31986
  while (true) {
31495
- const scoutEntry = join16(current, "apps", "desktop", "bin", "scout.ts");
31496
- const runtimeEntry = join16(current, "packages", "runtime", "bin", "openscout-runtime.mjs");
31497
- if (existsSync16(scoutEntry) && existsSync16(runtimeEntry)) {
31987
+ const scoutEntry = join18(current, "apps", "desktop", "bin", "scout.ts");
31988
+ const runtimeEntry = join18(current, "packages", "runtime", "bin", "openscout-runtime.mjs");
31989
+ if (existsSync18(scoutEntry) && existsSync18(runtimeEntry)) {
31498
31990
  return current;
31499
31991
  }
31500
- const parent = dirname9(current);
31992
+ const parent = dirname10(current);
31501
31993
  if (parent === current) {
31502
31994
  break;
31503
31995
  }
@@ -31510,8 +32002,8 @@ function resolveRepoEntrypoint(repoRoot, relativePath) {
31510
32002
  if (!repoRoot) {
31511
32003
  return null;
31512
32004
  }
31513
- const candidate = join16(repoRoot, relativePath);
31514
- return existsSync16(candidate) ? candidate : null;
32005
+ const candidate = join18(repoRoot, relativePath);
32006
+ return existsSync18(candidate) ? candidate : null;
31515
32007
  }
31516
32008
  function findExecutableOnSearchPath(name, env) {
31517
32009
  const searchDirectories = dedupeDirectories([
@@ -31519,7 +32011,7 @@ function findExecutableOnSearchPath(name, env) {
31519
32011
  ...DEFAULT_COMMON_EXECUTABLE_DIRECTORIES
31520
32012
  ], env);
31521
32013
  for (const directory of searchDirectories) {
31522
- const candidate = join16(directory, name);
32014
+ const candidate = join18(directory, name);
31523
32015
  if (isExecutablePath(candidate)) {
31524
32016
  return { path: candidate, source: "path" };
31525
32017
  }
@@ -31580,12 +32072,12 @@ function errorMessage2(error48) {
31580
32072
  var SESSION_CATALOG_FILENAME = "session-catalog.json";
31581
32073
  var SESSION_CATALOG_MAX_ENTRIES = 64;
31582
32074
  function readSessionCatalogSync(runtimeDirectory) {
31583
- const catalogPath = join17(runtimeDirectory, SESSION_CATALOG_FILENAME);
32075
+ const catalogPath = join19(runtimeDirectory, SESSION_CATALOG_FILENAME);
31584
32076
  try {
31585
- if (!existsSync17(catalogPath)) {
31586
- const legacyPath = join17(runtimeDirectory, "claude-session-id.txt");
31587
- if (existsSync17(legacyPath)) {
31588
- const legacyId = readFileSync7(legacyPath, "utf8").trim();
32077
+ if (!existsSync19(catalogPath)) {
32078
+ const legacyPath = join19(runtimeDirectory, "claude-session-id.txt");
32079
+ if (existsSync19(legacyPath)) {
32080
+ const legacyId = readFileSync8(legacyPath, "utf8").trim();
31589
32081
  if (legacyId) {
31590
32082
  return {
31591
32083
  activeSessionId: legacyId,
@@ -31595,7 +32087,7 @@ function readSessionCatalogSync(runtimeDirectory) {
31595
32087
  }
31596
32088
  return { activeSessionId: null, sessions: [] };
31597
32089
  }
31598
- const raw = readFileSync7(catalogPath, "utf8").trim();
32090
+ const raw = readFileSync8(catalogPath, "utf8").trim();
31599
32091
  if (!raw)
31600
32092
  return { activeSessionId: null, sessions: [] };
31601
32093
  const parsed = JSON.parse(raw);
@@ -31611,7 +32103,7 @@ async function readSessionCatalog(runtimeDirectory) {
31611
32103
  return readSessionCatalogSync(runtimeDirectory);
31612
32104
  }
31613
32105
  async function writeSessionCatalog(runtimeDirectory, catalog) {
31614
- const catalogPath = join17(runtimeDirectory, SESSION_CATALOG_FILENAME);
32106
+ const catalogPath = join19(runtimeDirectory, SESSION_CATALOG_FILENAME);
31615
32107
  await mkdir3(runtimeDirectory, { recursive: true });
31616
32108
  await writeFile3(catalogPath, JSON.stringify(catalog, null, 2) + `
31617
32109
  `);
@@ -31643,8 +32135,8 @@ class ClaudeStreamJsonSession {
31643
32135
  constructor(options) {
31644
32136
  this.options = options;
31645
32137
  this.catalogDirectory = options.runtimeDirectory;
31646
- this.stdoutLogPath = join17(options.logsDirectory, "stdout.log");
31647
- this.stderrLogPath = join17(options.logsDirectory, "stderr.log");
32138
+ this.stdoutLogPath = join19(options.logsDirectory, "stdout.log");
32139
+ this.stderrLogPath = join19(options.logsDirectory, "stderr.log");
31648
32140
  this.lastConfigSignature = this.configSignature(options);
31649
32141
  }
31650
32142
  matches(options) {
@@ -31800,7 +32292,7 @@ class ClaudeStreamJsonSession {
31800
32292
  async startSession() {
31801
32293
  await mkdir3(this.options.runtimeDirectory, { recursive: true });
31802
32294
  await mkdir3(this.options.logsDirectory, { recursive: true });
31803
- await writeFile3(join17(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
32295
+ await writeFile3(join19(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
31804
32296
  const catalog = await readSessionCatalog(this.catalogDirectory);
31805
32297
  this.claudeSessionId = catalog.activeSessionId;
31806
32298
  this.resumedSessionId = this.claudeSessionId;
@@ -31985,14 +32477,14 @@ async function shutdownClaudeStreamJsonAgent(options, shutdownOptions = {}) {
31985
32477
 
31986
32478
  // packages/agent-sessions/src/local/transports/codex-app-server.ts
31987
32479
  import { spawn as spawn5 } from "child_process";
31988
- import { homedir as homedir18 } from "os";
32480
+ import { homedir as homedir20 } from "os";
31989
32481
  import { appendFile as appendFile3, copyFile, mkdir as mkdir4, readFile as readFile5, rm as rm2, stat as stat3, symlink, writeFile as writeFile4 } from "fs/promises";
31990
- import { join as join19, resolve as resolve8 } from "path";
32482
+ import { join as join21, resolve as resolve8 } from "path";
31991
32483
 
31992
32484
  // packages/agent-sessions/src/codex-launch-config.ts
31993
- import { accessSync as accessSync3, constants as constants3, existsSync as existsSync18 } from "fs";
31994
- import { homedir as homedir17 } from "os";
31995
- import { basename as basename13, delimiter as delimiter2, dirname as dirname10, join as join18, resolve as resolve7 } from "path";
32485
+ import { accessSync as accessSync3, constants as constants3, existsSync as existsSync20 } from "fs";
32486
+ import { homedir as homedir19 } from "os";
32487
+ import { basename as basename14, delimiter as delimiter2, dirname as dirname11, join as join20, resolve as resolve7 } from "path";
31996
32488
  import { fileURLToPath as fileURLToPath2 } from "url";
31997
32489
  function isExecutable2(filePath) {
31998
32490
  if (!filePath) {
@@ -32013,7 +32505,7 @@ function ancestorChain(start) {
32013
32505
  let current = resolve7(start);
32014
32506
  while (true) {
32015
32507
  chain.push(current);
32016
- const parent = dirname10(current);
32508
+ const parent = dirname11(current);
32017
32509
  if (parent === current) {
32018
32510
  return chain;
32019
32511
  }
@@ -32023,14 +32515,14 @@ function ancestorChain(start) {
32023
32515
  function resolveExecutableFromSearchPath(names, env) {
32024
32516
  const pathEntries = (env.PATH ?? "").split(delimiter2).filter(Boolean);
32025
32517
  const commonDirectories = [
32026
- join18(homedir17(), ".local", "bin"),
32027
- join18(homedir17(), ".bun", "bin"),
32518
+ join20(homedir19(), ".local", "bin"),
32519
+ join20(homedir19(), ".bun", "bin"),
32028
32520
  "/opt/homebrew/bin",
32029
32521
  "/usr/local/bin"
32030
32522
  ];
32031
32523
  for (const directory of [...pathEntries, ...commonDirectories]) {
32032
32524
  for (const name of names) {
32033
- const candidate = join18(directory, name);
32525
+ const candidate = join20(directory, name);
32034
32526
  if (isExecutable2(candidate)) {
32035
32527
  return candidate;
32036
32528
  }
@@ -32049,7 +32541,7 @@ function resolveBunExecutable2(env) {
32049
32541
  return candidate;
32050
32542
  }
32051
32543
  }
32052
- if (basename13(process.execPath).startsWith("bun") && isExecutable2(process.execPath)) {
32544
+ if (basename14(process.execPath).startsWith("bun") && isExecutable2(process.execPath)) {
32053
32545
  return process.execPath;
32054
32546
  }
32055
32547
  return resolveExecutableFromSearchPath(["bun"], env);
@@ -32069,12 +32561,12 @@ function resolveScoutExecutable(env) {
32069
32561
  return resolveExecutableFromSearchPath(["scout"], env);
32070
32562
  }
32071
32563
  function resolveRepoScoutScript(currentDirectory) {
32072
- const moduleDirectory = dirname10(fileURLToPath2(import.meta.url));
32564
+ const moduleDirectory = dirname11(fileURLToPath2(import.meta.url));
32073
32565
  const starts = uniquePaths([currentDirectory, moduleDirectory]);
32074
32566
  for (const start of starts) {
32075
32567
  for (const candidate of ancestorChain(start)) {
32076
- const scriptPath = join18(candidate, "apps", "desktop", "bin", "scout.ts");
32077
- if (existsSync18(scriptPath)) {
32568
+ const scriptPath = join20(candidate, "apps", "desktop", "bin", "scout.ts");
32569
+ if (existsSync20(scriptPath)) {
32078
32570
  return scriptPath;
32079
32571
  }
32080
32572
  }
@@ -32191,6 +32683,10 @@ function normalizeCodexModelValue(value) {
32191
32683
  if (!trimmed) {
32192
32684
  return null;
32193
32685
  }
32686
+ const lower = trimmed.toLowerCase();
32687
+ if (lower === "5.6" || lower === "gpt-5.6") {
32688
+ return "gpt-5.6-sol";
32689
+ }
32194
32690
  if (/^\d+(?:\.\d+)*(?:-[A-Za-z0-9][A-Za-z0-9._-]*)?$/.test(trimmed)) {
32195
32691
  return `gpt-${trimmed}`;
32196
32692
  }
@@ -32417,7 +32913,7 @@ function isTruthyEnvironmentFlag(value) {
32417
32913
  }
32418
32914
  function defaultCodexHome(env) {
32419
32915
  const configured = env[MANAGED_CODEX_HOME_SOURCE_ENV]?.trim() || env.CODEX_HOME?.trim();
32420
- return configured ? resolve8(configured) : join19(homedir18(), ".codex");
32916
+ return configured ? resolve8(configured) : join21(homedir20(), ".codex");
32421
32917
  }
32422
32918
  function managedCodexHomeConfig(sourceConfig) {
32423
32919
  const selectedLines = [];
@@ -32448,8 +32944,8 @@ async function readOptionalTextFile(path) {
32448
32944
  }
32449
32945
  }
32450
32946
  async function linkOptionalCodexHomeFile(sourceHome, managedHome, fileName) {
32451
- const sourcePath = join19(sourceHome, fileName);
32452
- const targetPath = join19(managedHome, fileName);
32947
+ const sourcePath = join21(sourceHome, fileName);
32948
+ const targetPath = join21(managedHome, fileName);
32453
32949
  let sourceStat;
32454
32950
  try {
32455
32951
  sourceStat = await stat3(sourcePath);
@@ -32478,7 +32974,7 @@ async function prepareManagedCodexHome(options, env) {
32478
32974
  return env;
32479
32975
  }
32480
32976
  const sourceHome = defaultCodexHome(env);
32481
- const managedHome = join19(options.runtimeDirectory, MANAGED_CODEX_HOME_DIRECTORY);
32977
+ const managedHome = join21(options.runtimeDirectory, MANAGED_CODEX_HOME_DIRECTORY);
32482
32978
  if (resolve8(sourceHome) === resolve8(managedHome)) {
32483
32979
  return {
32484
32980
  ...env,
@@ -32487,8 +32983,8 @@ async function prepareManagedCodexHome(options, env) {
32487
32983
  };
32488
32984
  }
32489
32985
  await mkdir4(managedHome, { recursive: true });
32490
- const sourceConfig = await readOptionalTextFile(join19(sourceHome, "config.toml"));
32491
- await writeFile4(join19(managedHome, "config.toml"), managedCodexHomeConfig(sourceConfig), "utf8");
32986
+ const sourceConfig = await readOptionalTextFile(join21(sourceHome, "config.toml"));
32987
+ await writeFile4(join21(managedHome, "config.toml"), managedCodexHomeConfig(sourceConfig), "utf8");
32492
32988
  for (const fileName of MANAGED_CODEX_HOME_LINKED_FILES) {
32493
32989
  await linkOptionalCodexHomeFile(sourceHome, managedHome, fileName);
32494
32990
  }
@@ -32576,7 +33072,7 @@ function parseCodexMaybeJson(value) {
32576
33072
  }
32577
33073
  }
32578
33074
  async function readCodexSessionCatalog(runtimeDirectory) {
32579
- const raw = await readOptionalFile(join19(runtimeDirectory, SESSION_CATALOG_FILENAME2));
33075
+ const raw = await readOptionalFile(join21(runtimeDirectory, SESSION_CATALOG_FILENAME2));
32580
33076
  if (!raw) {
32581
33077
  return { activeSessionId: null, sessions: [] };
32582
33078
  }
@@ -32591,7 +33087,7 @@ async function readCodexSessionCatalog(runtimeDirectory) {
32591
33087
  }
32592
33088
  async function writeCodexSessionCatalog(runtimeDirectory, catalog) {
32593
33089
  await mkdir4(runtimeDirectory, { recursive: true });
32594
- await writeFile4(join19(runtimeDirectory, SESSION_CATALOG_FILENAME2), JSON.stringify(catalog, null, 2) + `
33090
+ await writeFile4(join21(runtimeDirectory, SESSION_CATALOG_FILENAME2), JSON.stringify(catalog, null, 2) + `
32595
33091
  `);
32596
33092
  }
32597
33093
  async function recordCodexSessionCatalog(runtimeDirectory, threadId, input) {
@@ -32652,10 +33148,10 @@ class CodexAppServerTransport {
32652
33148
  errorListeners = new Set;
32653
33149
  constructor(options) {
32654
33150
  this.options = options;
32655
- this.threadIdPath = join19(options.runtimeDirectory, "codex-thread-id.txt");
32656
- this.statePath = join19(options.runtimeDirectory, "state.json");
32657
- this.stdoutLogPath = join19(options.logsDirectory, "stdout.log");
32658
- this.stderrLogPath = join19(options.logsDirectory, "stderr.log");
33151
+ this.threadIdPath = join21(options.runtimeDirectory, "codex-thread-id.txt");
33152
+ this.statePath = join21(options.runtimeDirectory, "state.json");
33153
+ this.stdoutLogPath = join21(options.logsDirectory, "stdout.log");
33154
+ this.stderrLogPath = join21(options.logsDirectory, "stderr.log");
32659
33155
  this.lastConfigSignature = this.configSignature(options);
32660
33156
  }
32661
33157
  get currentThreadId() {
@@ -32810,7 +33306,7 @@ class CodexAppServerTransport {
32810
33306
  async startSession() {
32811
33307
  await mkdir4(this.options.runtimeDirectory, { recursive: true });
32812
33308
  await mkdir4(this.options.logsDirectory, { recursive: true });
32813
- await writeFile4(join19(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
33309
+ await writeFile4(join21(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
32814
33310
  this.proactiveShutdown = null;
32815
33311
  try {
32816
33312
  await assertCodexWorkingDirectory(this.options.cwd, this.options.agentName);
@@ -33479,9 +33975,9 @@ async function shutdownCodexAppServerLocalAgent(options, shutdownOptions = {}) {
33479
33975
  const session = codexAppServerClients.get(key);
33480
33976
  if (!session) {
33481
33977
  if (shutdownOptions.resetThread) {
33482
- const threadId = await readOptionalFile(join19(options.runtimeDirectory, "codex-thread-id.txt"));
33978
+ const threadId = await readOptionalFile(join21(options.runtimeDirectory, "codex-thread-id.txt"));
33483
33979
  await closeCodexSessionCatalog(options.runtimeDirectory, threadId);
33484
- await rm2(join19(options.runtimeDirectory, "codex-thread-id.txt"), { force: true });
33980
+ await rm2(join21(options.runtimeDirectory, "codex-thread-id.txt"), { force: true });
33485
33981
  }
33486
33982
  return;
33487
33983
  }
@@ -33627,16 +34123,16 @@ function buildInvocationCollaborationContextPrompt(invocation) {
33627
34123
  }
33628
34124
 
33629
34125
  // packages/runtime/src/pi-rpc.ts
33630
- import { existsSync as existsSync19 } from "fs";
34126
+ import { existsSync as existsSync21 } from "fs";
33631
34127
  import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
33632
34128
  import { execFileSync as execFileSync2 } from "child_process";
33633
- import { homedir as homedir19 } from "os";
33634
- import { join as join20 } from "path";
34129
+ import { homedir as homedir21 } from "os";
34130
+ import { join as join22 } from "path";
33635
34131
  var DEFAULT_PI_RPC_TIMEOUT_MS = 300000;
33636
34132
  var PI_SCOUT_EXTENSION_CANDIDATES = [
33637
34133
  process.env.OPENSCOUT_PI_SCOUT_EXTENSION_PATH,
33638
- join20(homedir19(), ".pi", "agent", "extensions", "pi-scout"),
33639
- join20(homedir19(), "dev", "pi-scout")
34134
+ join22(homedir21(), ".pi", "agent", "extensions", "pi-scout"),
34135
+ join22(homedir21(), "dev", "pi-scout")
33640
34136
  ].filter((candidate) => Boolean(candidate));
33641
34137
  var PI_RPC_FLAGS_WITH_VALUES = new Set([
33642
34138
  "--model",
@@ -33688,7 +34184,7 @@ function resolveDefaultPiScoutExtension() {
33688
34184
  return null;
33689
34185
  }
33690
34186
  for (const candidate of PI_SCOUT_EXTENSION_CANDIDATES) {
33691
- if (existsSync19(candidate)) {
34187
+ if (existsSync21(candidate)) {
33692
34188
  return candidate;
33693
34189
  }
33694
34190
  }
@@ -33768,7 +34264,7 @@ function parsePiRpcLaunchArgs(launchArgs, options) {
33768
34264
  const parsed = {
33769
34265
  extensions: [],
33770
34266
  extraArgs: [],
33771
- sessionDir: join20(options.runtimeDirectory, "pi-sessions")
34267
+ sessionDir: join22(options.runtimeDirectory, "pi-sessions")
33772
34268
  };
33773
34269
  for (let index = 0;index < launchArgs.length; index += 1) {
33774
34270
  const current = launchArgs[index] ?? "";
@@ -33880,11 +34376,11 @@ class PiRpcAgentSession {
33880
34376
  }
33881
34377
  await mkdir5(this.options.runtimeDirectory, { recursive: true });
33882
34378
  await mkdir5(this.options.logsDirectory, { recursive: true });
33883
- await writeFile5(join20(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
34379
+ await writeFile5(join22(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
33884
34380
  const launch = parsePiRpcLaunchArgs(this.options.launchArgs, {
33885
34381
  runtimeDirectory: this.options.runtimeDirectory
33886
34382
  });
33887
- const adapter2 = createAdapter2({
34383
+ const adapter2 = createAdapter3({
33888
34384
  sessionId: this.options.sessionId,
33889
34385
  name: `${this.options.agentName} Pi RPC`,
33890
34386
  cwd: this.options.cwd,
@@ -34048,10 +34544,10 @@ async function shutdownPiRpcAgent(options) {
34048
34544
 
34049
34545
  // packages/runtime/src/setup.ts
34050
34546
  import { execFileSync as execFileSync4 } from "child_process";
34051
- import { existsSync as existsSync22, readFileSync as readFileSync9 } from "fs";
34547
+ import { existsSync as existsSync24, readFileSync as readFileSync10 } from "fs";
34052
34548
  import { access, chmod, mkdir as mkdir7, readdir as readdir3, readFile as readFile8, realpath, rm as rm3, stat as stat5, writeFile as writeFile7 } from "fs/promises";
34053
- import { homedir as homedir23, hostname as hostname3, userInfo } from "os";
34054
- import { basename as basename14, dirname as dirname13, isAbsolute as isAbsolute2, join as join24, relative as relative6, resolve as resolve10 } from "path";
34549
+ import { homedir as homedir25, hostname as hostname3, userInfo } from "os";
34550
+ import { basename as basename15, dirname as dirname14, isAbsolute as isAbsolute2, join as join26, relative as relative6, resolve as resolve10 } from "path";
34055
34551
  import { fileURLToPath as fileURLToPath4 } from "url";
34056
34552
 
34057
34553
  // node_modules/.bun/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
@@ -35002,52 +35498,59 @@ function parse5(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
35002
35498
 
35003
35499
  // packages/runtime/src/harness-catalog.ts
35004
35500
  import { execFileSync as execFileSync3 } from "child_process";
35005
- import { existsSync as existsSync21, statSync as statSync12 } from "fs";
35501
+ import { existsSync as existsSync23, statSync as statSync13 } from "fs";
35006
35502
  import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
35007
- import { homedir as homedir21 } from "os";
35008
- import { dirname as dirname11, join as join22 } from "path";
35503
+ import { homedir as homedir23 } from "os";
35504
+ import { dirname as dirname12, join as join24 } from "path";
35009
35505
 
35010
35506
  // packages/runtime/src/support-paths.ts
35011
- import { existsSync as existsSync20, mkdirSync, rmSync, writeFileSync } from "fs";
35012
- import { homedir as homedir20 } from "os";
35013
- import { join as join21 } from "path";
35507
+ import { existsSync as existsSync22, mkdirSync, rmSync, writeFileSync } from "fs";
35508
+ import { homedir as homedir22 } from "os";
35509
+ import { join as join23 } from "path";
35014
35510
  var OPENSCOUT_RPC_CUTOVER_MARKER = "rpc-runtime-cutover-v1";
35511
+ function assertTestIsolatedUserData(operation, isolationEnvKey) {
35512
+ if (true)
35513
+ return;
35514
+ if (process.env[isolationEnvKey]?.trim())
35515
+ return;
35516
+ throw new Error(`Refusing to ${operation} while NODE_ENV=test without ${isolationEnvKey} set. ` + "Tests must isolate OpenScout user data in a temp directory (see prepareHome in onboarding.test.ts).");
35517
+ }
35015
35518
  function resolveOpenScoutSupportPaths() {
35016
- const home = homedir20();
35017
- const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join21(home, "Library", "Application Support", "OpenScout");
35018
- const logsDirectory = join21(supportDirectory, "logs");
35019
- const runtimeDirectory = join21(supportDirectory, "runtime");
35020
- const catalogDirectory = join21(supportDirectory, "catalog");
35021
- const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join21(home, ".openscout", "control-plane");
35022
- const knowledgeDirectory = join21(controlHome, "knowledge");
35519
+ const home = homedir22();
35520
+ const supportDirectory = process.env.OPENSCOUT_SUPPORT_DIRECTORY ?? join23(home, "Library", "Application Support", "OpenScout");
35521
+ const logsDirectory = join23(supportDirectory, "logs");
35522
+ const runtimeDirectory = join23(supportDirectory, "runtime");
35523
+ const catalogDirectory = join23(supportDirectory, "catalog");
35524
+ const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join23(home, ".openscout", "control-plane");
35525
+ const knowledgeDirectory = join23(controlHome, "knowledge");
35023
35526
  return {
35024
35527
  supportDirectory,
35025
35528
  logsDirectory,
35026
- appLogsDirectory: join21(logsDirectory, "app"),
35027
- brokerLogsDirectory: join21(logsDirectory, "broker"),
35529
+ appLogsDirectory: join23(logsDirectory, "app"),
35530
+ brokerLogsDirectory: join23(logsDirectory, "broker"),
35028
35531
  runtimeDirectory,
35029
35532
  catalogDirectory,
35030
- relayAgentsDirectory: join21(runtimeDirectory, "agents"),
35031
- settingsPath: join21(supportDirectory, "settings.json"),
35032
- harnessCatalogPath: join21(catalogDirectory, "harness-catalog.json"),
35033
- relayAgentsRegistryPath: join21(supportDirectory, "relay-agents.json"),
35034
- managedInstallsPath: join21(supportDirectory, "managed-installs.json"),
35035
- hostInfoPath: join21(supportDirectory, ".host-info"),
35036
- relayHubDirectory: process.env.OPENSCOUT_RELAY_HUB ?? join21(home, ".openscout", "relay"),
35533
+ relayAgentsDirectory: join23(runtimeDirectory, "agents"),
35534
+ settingsPath: join23(supportDirectory, "settings.json"),
35535
+ harnessCatalogPath: join23(catalogDirectory, "harness-catalog.json"),
35536
+ relayAgentsRegistryPath: join23(supportDirectory, "relay-agents.json"),
35537
+ managedInstallsPath: join23(supportDirectory, "managed-installs.json"),
35538
+ hostInfoPath: join23(supportDirectory, ".host-info"),
35539
+ relayHubDirectory: process.env.OPENSCOUT_RELAY_HUB ?? join23(home, ".openscout", "relay"),
35037
35540
  controlHome,
35038
35541
  knowledgeDirectory,
35039
- knowledgeQmdDirectory: join21(knowledgeDirectory, "qmd"),
35040
- knowledgeSqlitePath: join21(knowledgeDirectory, "knowledge.sqlite"),
35041
- desktopStatusPath: join21(supportDirectory, "agent-status.json"),
35042
- workspaceStatePath: join21(supportDirectory, "workspace-state.json"),
35043
- cutoverMarkerPath: join21(supportDirectory, OPENSCOUT_RPC_CUTOVER_MARKER)
35542
+ knowledgeQmdDirectory: join23(knowledgeDirectory, "qmd"),
35543
+ knowledgeSqlitePath: join23(knowledgeDirectory, "knowledge.sqlite"),
35544
+ desktopStatusPath: join23(supportDirectory, "agent-status.json"),
35545
+ workspaceStatePath: join23(supportDirectory, "workspace-state.json"),
35546
+ cutoverMarkerPath: join23(supportDirectory, OPENSCOUT_RPC_CUTOVER_MARKER)
35044
35547
  };
35045
35548
  }
35046
35549
  function localAgentRuntimeDirectory(agentId) {
35047
- return join21(resolveOpenScoutSupportPaths().relayAgentsDirectory, agentId);
35550
+ return join23(resolveOpenScoutSupportPaths().relayAgentsDirectory, agentId);
35048
35551
  }
35049
35552
  function localAgentLogsDirectory(agentId) {
35050
- return join21(localAgentRuntimeDirectory(agentId), "logs");
35553
+ return join23(localAgentRuntimeDirectory(agentId), "logs");
35051
35554
  }
35052
35555
  function relayAgentRuntimeDirectory(agentId) {
35053
35556
  return localAgentRuntimeDirectory(agentId);
@@ -35056,8 +35559,9 @@ function relayAgentLogsDirectory(agentId) {
35056
35559
  return localAgentLogsDirectory(agentId);
35057
35560
  }
35058
35561
  function ensureOpenScoutCleanSlateSync() {
35562
+ assertTestIsolatedUserData("reset the OpenScout support directory", "OPENSCOUT_SUPPORT_DIRECTORY");
35059
35563
  const paths = resolveOpenScoutSupportPaths();
35060
- if (existsSync20(paths.cutoverMarkerPath)) {
35564
+ if (existsSync22(paths.cutoverMarkerPath)) {
35061
35565
  return;
35062
35566
  }
35063
35567
  rmSync(paths.supportDirectory, { recursive: true, force: true });
@@ -35114,6 +35618,10 @@ var BUILT_IN_HARNESS_CATALOG = [
35114
35618
  command: "claude",
35115
35619
  sessionFlag: "--resume"
35116
35620
  },
35621
+ sessionDefaults: {
35622
+ defaultTransport: "tmux",
35623
+ fallbackTransports: ["claude_stream_json"]
35624
+ },
35117
35625
  capabilities: ["chat", "invoke", "deliver", "summarize", "review"]
35118
35626
  },
35119
35627
  {
@@ -35150,6 +35658,10 @@ var BUILT_IN_HARNESS_CATALOG = [
35150
35658
  command: "grok",
35151
35659
  sessionFlag: "--resume"
35152
35660
  },
35661
+ sessionDefaults: {
35662
+ defaultHarness: "grok-acp",
35663
+ defaultTransport: "grok_acp"
35664
+ },
35153
35665
  capabilities: ["chat", "invoke", "deliver", "summarize", "review"],
35154
35666
  metadata: {
35155
35667
  invocationModel: "tmux_interactive"
@@ -35189,6 +35701,9 @@ var BUILT_IN_HARNESS_CATALOG = [
35189
35701
  sessionFlag: "resume",
35190
35702
  cwdFlag: "-C"
35191
35703
  },
35704
+ sessionDefaults: {
35705
+ defaultTransport: "codex_app_server"
35706
+ },
35192
35707
  capabilities: ["chat", "invoke", "deliver", "review", "execute"]
35193
35708
  },
35194
35709
  {
@@ -35221,12 +35736,53 @@ var BUILT_IN_HARNESS_CATALOG = [
35221
35736
  loginCommand: "grok login",
35222
35737
  notReadyMessage: "Grok ACP is installed but still needs a cached login or XAI_API_KEY."
35223
35738
  },
35739
+ sessionDefaults: {
35740
+ defaultTransport: "grok_acp"
35741
+ },
35224
35742
  capabilities: ["chat", "invoke", "deliver", "review", "execute"],
35225
35743
  metadata: {
35226
35744
  adapterType: "grok-acp",
35227
35745
  transport: "acp_stdio"
35228
35746
  }
35229
35747
  },
35748
+ {
35749
+ name: "kimi",
35750
+ harness: "kimi",
35751
+ label: "Kimi Code",
35752
+ description: "Kimi Code CLI coding agent over ACP",
35753
+ homepage: "https://www.kimi.com/code/docs/en/",
35754
+ tags: ["coding", "cli", "kimi", "moonshot", "acp"],
35755
+ featured: true,
35756
+ order: 4,
35757
+ support: {
35758
+ ...DEFAULT_SUPPORT,
35759
+ workspace: true,
35760
+ collaboration: true,
35761
+ files: true
35762
+ },
35763
+ install: {
35764
+ binary: "kimi",
35765
+ requires: ["curl"],
35766
+ macos: "curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",
35767
+ linux: "curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash",
35768
+ windows: "irm https://code.kimi.com/kimi-code/install.ps1 | iex"
35769
+ },
35770
+ readiness: {
35771
+ anyOf: [
35772
+ { kind: "file", path: "~/.kimi-code/credentials", label: "~/.kimi-code/credentials", fileType: "directory" }
35773
+ ],
35774
+ loginCommand: "kimi login",
35775
+ notReadyMessage: "Kimi Code is installed but still needs a cached login from kimi login."
35776
+ },
35777
+ sessionDefaults: {
35778
+ defaultTransport: "kimi_acp"
35779
+ },
35780
+ capabilities: ["chat", "invoke", "deliver", "review", "execute"],
35781
+ metadata: {
35782
+ adapterType: "kimi-acp",
35783
+ transport: "acp_stdio"
35784
+ }
35785
+ },
35230
35786
  {
35231
35787
  name: "cursor",
35232
35788
  harness: "cursor",
@@ -35337,11 +35893,11 @@ var BUILT_IN_HARNESS_CATALOG = [
35337
35893
  }
35338
35894
  ];
35339
35895
  function expandHomePath2(value) {
35340
- const home = process.env.HOME?.trim() || homedir21();
35896
+ const home = process.env.HOME?.trim() || homedir23();
35341
35897
  if (value === "~")
35342
35898
  return home;
35343
35899
  if (value.startsWith("~/"))
35344
- return join22(home, value.slice(2));
35900
+ return join24(home, value.slice(2));
35345
35901
  return value;
35346
35902
  }
35347
35903
  function defaultWhichBinary(binary, platform) {
@@ -35375,12 +35931,12 @@ function defaultRunCommand(command, platform) {
35375
35931
  }
35376
35932
  function defaultRequirementExists(requirement) {
35377
35933
  const expanded = expandHomePath2(requirement.path);
35378
- if (!existsSync21(expanded))
35934
+ if (!existsSync23(expanded))
35379
35935
  return false;
35380
35936
  if (requirement.fileType === "any" || !requirement.fileType)
35381
35937
  return true;
35382
35938
  try {
35383
- const fileStat = statSync12(expanded);
35939
+ const fileStat = statSync13(expanded);
35384
35940
  return requirement.fileType === "directory" ? fileStat.isDirectory() : fileStat.isFile();
35385
35941
  } catch {
35386
35942
  return false;
@@ -35417,6 +35973,17 @@ function mergeLaunch(base, override) {
35417
35973
  args: override?.args ?? base?.args ?? []
35418
35974
  };
35419
35975
  }
35976
+ function mergeSessionDefaults(base, override) {
35977
+ const defaultTransport = override?.defaultTransport ?? base?.defaultTransport;
35978
+ if (!defaultTransport)
35979
+ return;
35980
+ return {
35981
+ ...base ?? {},
35982
+ ...override ?? {},
35983
+ defaultTransport,
35984
+ fallbackTransports: override?.fallbackTransports ? [...override.fallbackTransports] : base?.fallbackTransports ? [...base.fallbackTransports] : undefined
35985
+ };
35986
+ }
35420
35987
  function formatRequirement(requirement) {
35421
35988
  if (requirement.label?.trim())
35422
35989
  return requirement.label.trim();
@@ -35443,6 +36010,22 @@ function codexCandidateReport(candidate, selectedPath) {
35443
36010
  selected: candidate.path === selectedPath
35444
36011
  };
35445
36012
  }
36013
+ function resolveHarnessSessionDefaults(harness, options = {}) {
36014
+ if (!harness)
36015
+ return null;
36016
+ const entry = (options.entries ?? BUILT_IN_HARNESS_CATALOG).find((candidate) => candidate.harness === harness || candidate.name === harness);
36017
+ const defaults = entry?.sessionDefaults;
36018
+ if (!entry || !defaults)
36019
+ return null;
36020
+ const fallbackTransports = [...defaults.fallbackTransports ?? []];
36021
+ const supportedTransports = new Set([defaults.defaultTransport, ...fallbackTransports]);
36022
+ const requestedTransport = options.transportOverride?.trim();
36023
+ return {
36024
+ harness: String(defaults.defaultHarness ?? entry.harness),
36025
+ transport: requestedTransport && supportedTransports.has(requestedTransport) ? requestedTransport : defaults.defaultTransport,
36026
+ fallbackTransports
36027
+ };
36028
+ }
35446
36029
  function createBuiltInHarnessCatalog() {
35447
36030
  return BUILT_IN_HARNESS_CATALOG.map((entry) => ({
35448
36031
  ...entry,
@@ -35456,6 +36039,10 @@ function createBuiltInHarnessCatalog() {
35456
36039
  } : undefined,
35457
36040
  launch: entry.launch ? { ...entry.launch, args: [...entry.launch.args] } : undefined,
35458
36041
  resume: entry.resume ? { ...entry.resume } : undefined,
36042
+ sessionDefaults: entry.sessionDefaults ? {
36043
+ ...entry.sessionDefaults,
36044
+ fallbackTransports: entry.sessionDefaults.fallbackTransports ? [...entry.sessionDefaults.fallbackTransports] : undefined
36045
+ } : undefined,
35459
36046
  resolveEnv: entry.resolveEnv ? [...entry.resolveEnv] : undefined,
35460
36047
  capabilities: [...entry.capabilities],
35461
36048
  metadata: entry.metadata ? { ...entry.metadata } : undefined
@@ -35473,6 +36060,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
35473
36060
  install: mergeInstall(entry.install, override.install),
35474
36061
  readiness: mergeReadiness(entry.readiness, override.readiness),
35475
36062
  launch: mergeLaunch(entry.launch, override.launch),
36063
+ sessionDefaults: mergeSessionDefaults(entry.sessionDefaults, override.sessionDefaults),
35476
36064
  resume: override.resume && entry.resume ? { ...entry.resume, ...override.resume } : entry.resume,
35477
36065
  tags: override.tags ? [...override.tags] : entry.tags,
35478
36066
  capabilities: override.capabilities ? [...override.capabilities] : entry.capabilities,
@@ -35503,6 +36091,7 @@ function mergeHarnessCatalogEntries(baseEntries, overrides = {}) {
35503
36091
  readiness: mergeReadiness(undefined, override.readiness),
35504
36092
  launch: mergeLaunch(undefined, override.launch),
35505
36093
  resume: override.resume?.command && override.resume?.sessionFlag ? { command: override.resume.command, sessionFlag: override.resume.sessionFlag, cwdFlag: override.resume.cwdFlag } : undefined,
36094
+ sessionDefaults: mergeSessionDefaults(undefined, override.sessionDefaults),
35506
36095
  resolveEnv: override.resolveEnv ? [...override.resolveEnv] : undefined,
35507
36096
  capabilities: [...override.capabilities],
35508
36097
  metadata: override.metadata ? { ...override.metadata } : undefined
@@ -35586,7 +36175,7 @@ async function readHarnessCatalogOverrides(overridePath = resolveOpenScoutSuppor
35586
36175
  }
35587
36176
  }
35588
36177
  async function writeHarnessCatalogOverrides(overrides, overridePath = resolveOpenScoutSupportPaths().harnessCatalogPath) {
35589
- await mkdir6(dirname11(overridePath), { recursive: true });
36178
+ await mkdir6(dirname12(overridePath), { recursive: true });
35590
36179
  const payload = {
35591
36180
  version: HARNESS_CATALOG_VERSION,
35592
36181
  entries: overrides,
@@ -35596,7 +36185,7 @@ async function writeHarnessCatalogOverrides(overrides, overridePath = resolveOpe
35596
36185
  `, "utf8");
35597
36186
  }
35598
36187
  async function ensureHarnessCatalogOverrideFile(overridePath = resolveOpenScoutSupportPaths().harnessCatalogPath) {
35599
- if (existsSync21(overridePath))
36188
+ if (existsSync23(overridePath))
35600
36189
  return;
35601
36190
  await writeHarnessCatalogOverrides({}, overridePath);
35602
36191
  }
@@ -35618,7 +36207,7 @@ async function loadHarnessCatalogSnapshot(options = {}) {
35618
36207
  }
35619
36208
 
35620
36209
  // packages/runtime/src/open-scout-network.ts
35621
- import { readFileSync as readFileSync8 } from "fs";
36210
+ import { readFileSync as readFileSync9 } from "fs";
35622
36211
  var DEFAULT_OPENSCOUT_NETWORK_RENDEZVOUS_URL = "https://mesh.oscout.net";
35623
36212
  var DEFAULT_OPENSCOUT_NETWORK_PAIRING_RELAY_URL = "wss://mesh.oscout.net/v1/relay";
35624
36213
  function defaultOpenScoutNetworkSettings() {
@@ -35631,7 +36220,7 @@ function defaultOpenScoutNetworkSettings() {
35631
36220
  }
35632
36221
  function normalizeOpenScoutNetworkSettings(input) {
35633
36222
  const base = defaultOpenScoutNetworkSettings();
35634
- const record2 = isRecord5(input) ? input : {};
36223
+ const record2 = isRecord6(input) ? input : {};
35635
36224
  return {
35636
36225
  discoveryEnabled: typeof record2.discoveryEnabled === "boolean" ? record2.discoveryEnabled : base.discoveryEnabled,
35637
36226
  rendezvousUrl: normalizeUrlString(record2.rendezvousUrl, base.rendezvousUrl),
@@ -35641,10 +36230,10 @@ function normalizeOpenScoutNetworkSettings(input) {
35641
36230
  }
35642
36231
  function readOpenScoutNetworkSettingsSync() {
35643
36232
  try {
35644
- const raw = readFileSync8(resolveOpenScoutSupportPaths().settingsPath, "utf8");
36233
+ const raw = readFileSync9(resolveOpenScoutSupportPaths().settingsPath, "utf8");
35645
36234
  const parsed = JSON.parse(raw);
35646
- const network = isRecord5(parsed) && isRecord5(parsed.network) ? parsed.network : {};
35647
- return normalizeOpenScoutNetworkSettings(isRecord5(network.openScoutNetwork) ? network.openScoutNetwork : {});
36235
+ const network = isRecord6(parsed) && isRecord6(parsed.network) ? parsed.network : {};
36236
+ return normalizeOpenScoutNetworkSettings(isRecord6(network.openScoutNetwork) ? network.openScoutNetwork : {});
35648
36237
  } catch {
35649
36238
  return defaultOpenScoutNetworkSettings();
35650
36239
  }
@@ -35673,14 +36262,14 @@ function readBooleanEnv(value) {
35673
36262
  return false;
35674
36263
  return;
35675
36264
  }
35676
- function isRecord5(value) {
36265
+ function isRecord6(value) {
35677
36266
  return typeof value === "object" && value !== null && !Array.isArray(value);
35678
36267
  }
35679
36268
 
35680
36269
  // packages/runtime/src/user-project-hints.ts
35681
36270
  import { readdir as readdir2, readFile as readFile7, stat as stat4 } from "fs/promises";
35682
- import { homedir as homedir22 } from "os";
35683
- import { dirname as dirname12, join as join23, resolve as resolve9 } from "path";
36271
+ import { homedir as homedir24 } from "os";
36272
+ import { dirname as dirname13, join as join25, resolve as resolve9 } from "path";
35684
36273
  import { fileURLToPath as fileURLToPath3 } from "url";
35685
36274
  var PROJECT_HINT_MARKERS = [
35686
36275
  ".git",
@@ -35717,7 +36306,7 @@ async function resolveExistingDirectoryHint(pathLike) {
35717
36306
  return absolutePath;
35718
36307
  }
35719
36308
  if (info.isFile()) {
35720
- return dirname12(absolutePath);
36309
+ return dirname13(absolutePath);
35721
36310
  }
35722
36311
  } catch {
35723
36312
  return null;
@@ -35737,14 +36326,14 @@ async function findLikelyProjectRoot(absolutePath) {
35737
36326
  let lastCandidate = null;
35738
36327
  while (true) {
35739
36328
  for (const marker of PROJECT_HINT_MARKERS) {
35740
- if (await pathExists(join23(current, marker))) {
36329
+ if (await pathExists(join25(current, marker))) {
35741
36330
  lastCandidate = current;
35742
36331
  if (marker === ".git" || marker === ".openscout/project.json") {
35743
36332
  return current;
35744
36333
  }
35745
36334
  }
35746
36335
  }
35747
- const parent = dirname12(current);
36336
+ const parent = dirname13(current);
35748
36337
  if (parent === current) {
35749
36338
  return lastCandidate ?? absolutePath;
35750
36339
  }
@@ -35760,16 +36349,16 @@ async function appendPathHint(pathLike, roots) {
35760
36349
  }
35761
36350
  function cursorWorkspaceStoragePath(home) {
35762
36351
  if (process.platform === "darwin") {
35763
- return join23(home, "Library", "Application Support", "Cursor", "User", "workspaceStorage");
36352
+ return join25(home, "Library", "Application Support", "Cursor", "User", "workspaceStorage");
35764
36353
  }
35765
36354
  if (process.platform === "win32") {
35766
36355
  const appData = process.env.APPDATA;
35767
36356
  if (appData) {
35768
- return join23(appData, "Cursor", "User", "workspaceStorage");
36357
+ return join25(appData, "Cursor", "User", "workspaceStorage");
35769
36358
  }
35770
- return join23(home, "AppData", "Roaming", "Cursor", "User", "workspaceStorage");
36359
+ return join25(home, "AppData", "Roaming", "Cursor", "User", "workspaceStorage");
35771
36360
  }
35772
- return join23(home, ".config", "Cursor", "User", "workspaceStorage");
36361
+ return join25(home, ".config", "Cursor", "User", "workspaceStorage");
35773
36362
  }
35774
36363
  function collectPathLikeStrings(value, out, depth) {
35775
36364
  if (depth > 4 || value === null || value === undefined) {
@@ -35798,7 +36387,7 @@ function collectPathLikeStrings(value, out, depth) {
35798
36387
  }
35799
36388
  }
35800
36389
  async function appendCodexHistoryPaths(home, roots) {
35801
- const candidates = [join23(home, ".codex", "history.jsonl"), join23(home, ".openai-codex", "history.jsonl")];
36390
+ const candidates = [join25(home, ".codex", "history.jsonl"), join25(home, ".openai-codex", "history.jsonl")];
35802
36391
  const maxLines = 2500;
35803
36392
  const maxBytes = 4 * 1024 * 1024;
35804
36393
  for (const filePath of candidates) {
@@ -35849,7 +36438,7 @@ async function appendCursorWorkspacePaths(home, roots) {
35849
36438
  return;
35850
36439
  }
35851
36440
  for (const id of ids) {
35852
- const workspaceJsonPath = join23(base, id, "workspace.json");
36441
+ const workspaceJsonPath = join25(base, id, "workspace.json");
35853
36442
  let raw;
35854
36443
  try {
35855
36444
  raw = await readFile7(workspaceJsonPath, "utf8");
@@ -35885,7 +36474,7 @@ async function appendCursorWorkspacePaths(home, roots) {
35885
36474
  }
35886
36475
  const wsRaw = await readFile7(wsFile, "utf8");
35887
36476
  const wsDoc = JSON.parse(wsRaw);
35888
- const wsDir = dirname12(wsFile);
36477
+ const wsDir = dirname13(wsFile);
35889
36478
  for (const f of wsDoc.folders ?? []) {
35890
36479
  if (typeof f.path !== "string" || !f.path) {
35891
36480
  continue;
@@ -35898,7 +36487,7 @@ async function appendCursorWorkspacePaths(home, roots) {
35898
36487
  }
35899
36488
  }
35900
36489
  async function appendClaudeProjectSlugs(home, roots) {
35901
- const projectsDir = join23(home, ".claude", "projects");
36490
+ const projectsDir = join25(home, ".claude", "projects");
35902
36491
  let names = [];
35903
36492
  try {
35904
36493
  names = await readdir2(projectsDir, { withFileTypes: false });
@@ -35914,7 +36503,7 @@ async function appendClaudeProjectSlugs(home, roots) {
35914
36503
  }
35915
36504
  }
35916
36505
  async function appendClaudeSessionPaths(home, roots) {
35917
- const projectsDir = join23(home, ".claude", "projects");
36506
+ const projectsDir = join25(home, ".claude", "projects");
35918
36507
  const maxProjectDirectories = 200;
35919
36508
  const maxSessionFiles = 400;
35920
36509
  const maxLinesPerFile = 400;
@@ -35929,7 +36518,7 @@ async function appendClaudeSessionPaths(home, roots) {
35929
36518
  for (const projectName of projectNames) {
35930
36519
  let entries = [];
35931
36520
  try {
35932
- entries = await readdir2(join23(projectsDir, projectName), { withFileTypes: false });
36521
+ entries = await readdir2(join25(projectsDir, projectName), { withFileTypes: false });
35933
36522
  } catch {
35934
36523
  continue;
35935
36524
  }
@@ -35940,7 +36529,7 @@ async function appendClaudeSessionPaths(home, roots) {
35940
36529
  if (!entry.endsWith(".jsonl")) {
35941
36530
  continue;
35942
36531
  }
35943
- const sessionPath = join23(projectsDir, projectName, entry);
36532
+ const sessionPath = join25(projectsDir, projectName, entry);
35944
36533
  let info;
35945
36534
  try {
35946
36535
  info = await stat4(sessionPath);
@@ -35982,7 +36571,7 @@ async function appendClaudeSessionPaths(home, roots) {
35982
36571
  }
35983
36572
  }
35984
36573
  async function collectUserLevelProjectRootHints(options = {}) {
35985
- const home = options.home ?? homedir22();
36574
+ const home = options.home ?? homedir24();
35986
36575
  const roots = new Set;
35987
36576
  try {
35988
36577
  await appendClaudeProjectSlugs(home, roots);
@@ -36160,7 +36749,7 @@ async function matchNestedMarkers(projectRoot, nestedMarkers) {
36160
36749
  if (nestedMarkers.length === 0) {
36161
36750
  return [];
36162
36751
  }
36163
- const hits = await Promise.all(nestedMarkers.map(async (marker) => await pathExists2(join24(projectRoot, marker)) ? marker : null));
36752
+ const hits = await Promise.all(nestedMarkers.map(async (marker) => await pathExists2(join26(projectRoot, marker)) ? marker : null));
36164
36753
  return hits.filter((marker) => Boolean(marker));
36165
36754
  }
36166
36755
  function nowSeconds() {
@@ -36168,10 +36757,10 @@ function nowSeconds() {
36168
36757
  }
36169
36758
  function expandHomePath3(value) {
36170
36759
  if (value === "~") {
36171
- return homedir23();
36760
+ return homedir25();
36172
36761
  }
36173
36762
  if (value.startsWith("~/")) {
36174
- return join24(homedir23(), value.slice(2));
36763
+ return join26(homedir25(), value.slice(2));
36175
36764
  }
36176
36765
  return value;
36177
36766
  }
@@ -36258,16 +36847,16 @@ function resolveTelegramConfigSeedValue(key, currentDirectory) {
36258
36847
  return envValue;
36259
36848
  }
36260
36849
  if (currentDirectory) {
36261
- const currentDirValue = readEnvFileValue(join24(currentDirectory, ".env.local"), key).trim();
36850
+ const currentDirValue = readEnvFileValue(join26(currentDirectory, ".env.local"), key).trim();
36262
36851
  if (currentDirValue) {
36263
36852
  return currentDirValue;
36264
36853
  }
36265
36854
  }
36266
- const home = homedir23();
36855
+ const home = homedir25();
36267
36856
  if (!home) {
36268
36857
  return "";
36269
36858
  }
36270
- return readEnvFileValue(join24(home, ".env.local"), key).trim();
36859
+ return readEnvFileValue(join26(home, ".env.local"), key).trim();
36271
36860
  }
36272
36861
  function normalizeTelegramBridgeMode(value) {
36273
36862
  const normalized = typeof value === "string" ? value.trim().toLowerCase() : "";
@@ -36298,7 +36887,7 @@ function resolveNodeQualifier() {
36298
36887
  function readNodeAliasSync() {
36299
36888
  try {
36300
36889
  const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
36301
- const raw = readFileSync9(settingsPath, "utf8");
36890
+ const raw = readFileSync10(settingsPath, "utf8");
36302
36891
  const settings = JSON.parse(raw);
36303
36892
  return settings.node?.alias?.trim() || null;
36304
36893
  } catch {
@@ -36574,13 +37163,13 @@ function defaultSettings() {
36574
37163
  };
36575
37164
  }
36576
37165
  function projectConfigPath(projectRoot) {
36577
- return join24(projectRoot, ".openscout", "project.json");
37166
+ return join26(projectRoot, ".openscout", "project.json");
36578
37167
  }
36579
37168
  function projectGitignorePath(projectRoot) {
36580
- return join24(projectRoot, ".gitignore");
37169
+ return join26(projectRoot, ".gitignore");
36581
37170
  }
36582
37171
  function legacyLocalRelayLinkPath(projectRoot) {
36583
- return join24(projectRoot, ".openscout", "relay.json");
37172
+ return join26(projectRoot, ".openscout", "relay.json");
36584
37173
  }
36585
37174
  async function pathExists2(filePath) {
36586
37175
  try {
@@ -36606,15 +37195,15 @@ async function readJsonFile3(filePath) {
36606
37195
  }
36607
37196
  }
36608
37197
  async function writeJsonFile(filePath, value) {
36609
- await mkdir7(dirname13(filePath), { recursive: true });
37198
+ await mkdir7(dirname14(filePath), { recursive: true });
36610
37199
  await writeFile7(filePath, JSON.stringify(value, null, 2) + `
36611
37200
  `, "utf8");
36612
37201
  }
36613
37202
  function codexEnvironmentPath(projectRoot) {
36614
- return join24(projectRoot, ".codex", "environments", "environment.toml");
37203
+ return join26(projectRoot, ".codex", "environments", "environment.toml");
36615
37204
  }
36616
37205
  function currentHomeDirectory() {
36617
- return process.env.HOME?.trim() || homedir23();
37206
+ return process.env.HOME?.trim() || homedir25();
36618
37207
  }
36619
37208
  function normalizeProjectScriptSet(value) {
36620
37209
  if (typeof value !== "object" || !value) {
@@ -36770,11 +37359,11 @@ async function readCodexEnvironmentImport(projectRoot) {
36770
37359
  }
36771
37360
  async function readClaudeProjectImport(projectRoot) {
36772
37361
  const slug = encodeClaudeProjectsSlug(projectRoot);
36773
- const sourcePath = join24(currentHomeDirectory(), ".claude", "projects", slug);
37362
+ const sourcePath = join26(currentHomeDirectory(), ".claude", "projects", slug);
36774
37363
  if (!await isDirectory(sourcePath)) {
36775
37364
  return null;
36776
37365
  }
36777
- const memoryPath = await pathExists2(join24(sourcePath, "memory", "MEMORY.md")) ? join24(sourcePath, "memory", "MEMORY.md") : undefined;
37366
+ const memoryPath = await pathExists2(join26(sourcePath, "memory", "MEMORY.md")) ? join26(sourcePath, "memory", "MEMORY.md") : undefined;
36778
37367
  let entries = [];
36779
37368
  try {
36780
37369
  entries = await readdir3(sourcePath, { withFileTypes: false });
@@ -36789,7 +37378,7 @@ async function readClaudeProjectImport(projectRoot) {
36789
37378
  continue;
36790
37379
  }
36791
37380
  sessionCount += 1;
36792
- const sessionPath = join24(sourcePath, entry);
37381
+ const sessionPath = join26(sourcePath, entry);
36793
37382
  let body;
36794
37383
  try {
36795
37384
  body = await readFile8(sessionPath, "utf8");
@@ -36851,7 +37440,7 @@ function applyImportedEnvironmentSeeds(config2, codexImport, projectRoot) {
36851
37440
  ...(config2.environment?.actions?.length ?? 0) === 0 && importedEnvironment.actions ? { actions: importedEnvironment.actions } : {}
36852
37441
  };
36853
37442
  }
36854
- const defaultProjectName = titleCase(basename14(projectRoot));
37443
+ const defaultProjectName = titleCase(basename15(projectRoot));
36855
37444
  if (codexImport?.name?.trim() && (!config2.project.name?.trim() || config2.project.name === defaultProjectName)) {
36856
37445
  next.project = {
36857
37446
  ...config2.project,
@@ -36904,11 +37493,11 @@ async function ensureProjectConfigIgnored(projectRoot) {
36904
37493
  }
36905
37494
  async function readLegacyRelayConfig() {
36906
37495
  const relayHub = resolveOpenScoutSupportPaths().relayHubDirectory;
36907
- return readJsonFile3(join24(relayHub, "config.json"));
37496
+ return readJsonFile3(join26(relayHub, "config.json"));
36908
37497
  }
36909
37498
  async function readLegacyAgentRegistry() {
36910
37499
  const relayHub = resolveOpenScoutSupportPaths().relayHubDirectory;
36911
- return await readJsonFile3(join24(relayHub, "agents.json")) ?? {};
37500
+ return await readJsonFile3(join26(relayHub, "agents.json")) ?? {};
36912
37501
  }
36913
37502
  async function detectHarnessMarkers(projectRoot) {
36914
37503
  const detected = {
@@ -36920,7 +37509,7 @@ async function detectHarnessMarkers(projectRoot) {
36920
37509
  };
36921
37510
  for (const harness of MANAGED_AGENT_HARNESSES) {
36922
37511
  for (const marker of PROJECT_HARNESS_MARKERS[harness]) {
36923
- if (await pathExists2(join24(projectRoot, marker))) {
37512
+ if (await pathExists2(join26(projectRoot, marker))) {
36924
37513
  detected[harness].push(marker);
36925
37514
  }
36926
37515
  }
@@ -37067,7 +37656,7 @@ async function seedWorkspaceRoots(options) {
37067
37656
  const roots = new Set;
37068
37657
  const currentProjectRoot = options.currentDirectory ? await findNearestProjectRoot(options.currentDirectory) : null;
37069
37658
  if (currentProjectRoot) {
37070
- roots.add(dirname13(currentProjectRoot));
37659
+ roots.add(dirname14(currentProjectRoot));
37071
37660
  }
37072
37661
  const legacyRoot = options.legacyRelayConfig?.projectRoot?.trim();
37073
37662
  if (legacyRoot) {
@@ -37075,11 +37664,11 @@ async function seedWorkspaceRoots(options) {
37075
37664
  }
37076
37665
  for (const record2 of Object.values(options.legacyAgents ?? {})) {
37077
37666
  if (record2.cwd?.trim()) {
37078
- roots.add(dirname13(normalizePath(record2.cwd)));
37667
+ roots.add(dirname14(normalizePath(record2.cwd)));
37079
37668
  }
37080
37669
  }
37081
37670
  if (roots.size === 0) {
37082
- roots.add(join24(homedir23(), "dev"));
37671
+ roots.add(join26(homedir25(), "dev"));
37083
37672
  }
37084
37673
  return Array.from(roots);
37085
37674
  }
@@ -37094,7 +37683,7 @@ async function readOpenScoutSettings(options = {}) {
37094
37683
  legacyAgents
37095
37684
  });
37096
37685
  }
37097
- var SETUP_MODULE_DIRECTORY = dirname13(fileURLToPath4(import.meta.url));
37686
+ var SETUP_MODULE_DIRECTORY = dirname14(fileURLToPath4(import.meta.url));
37098
37687
  var SCOUT_SKILL_REPO_ROOT = resolve10(SETUP_MODULE_DIRECTORY, "..", "..", "..");
37099
37688
  async function readRelayAgentOverrides() {
37100
37689
  const supportPaths = resolveOpenScoutSupportPaths();
@@ -37177,13 +37766,13 @@ async function findNearestProjectRoot(startDirectory) {
37177
37766
  let current = normalizePath(startDirectory);
37178
37767
  let lastCandidate = null;
37179
37768
  while (true) {
37180
- if (await pathExists2(join24(current, ".git"))) {
37769
+ if (await pathExists2(join26(current, ".git"))) {
37181
37770
  return current;
37182
37771
  }
37183
- if (await pathExists2(projectConfigPath(current)) || await pathExists2(join24(current, "package.json")) || await pathExists2(join24(current, "AGENTS.md")) || await pathExists2(join24(current, "CLAUDE.md"))) {
37772
+ if (await pathExists2(projectConfigPath(current)) || await pathExists2(join26(current, "package.json")) || await pathExists2(join26(current, "AGENTS.md")) || await pathExists2(join26(current, "CLAUDE.md"))) {
37184
37773
  lastCandidate = current;
37185
37774
  }
37186
- const parent = dirname13(current);
37775
+ const parent = dirname14(current);
37187
37776
  if (parent === current) {
37188
37777
  return lastCandidate;
37189
37778
  }
@@ -37191,7 +37780,7 @@ async function findNearestProjectRoot(startDirectory) {
37191
37780
  }
37192
37781
  }
37193
37782
  function defaultProjectConfig(projectRoot, settings, preferredHarness) {
37194
- const projectName = basename14(projectRoot);
37783
+ const projectName = basename15(projectRoot);
37195
37784
  const definitionId = normalizeAgentId(projectName);
37196
37785
  const relativeRoot = relative6(projectRoot, projectRoot) || ".";
37197
37786
  return {
@@ -37365,7 +37954,7 @@ async function scanSourceRoot(sourceRoot) {
37365
37954
  if (PROJECT_SCAN_SKIP_DIRECTORIES.has(entry.name)) {
37366
37955
  continue;
37367
37956
  }
37368
- const nextPath = join24(currentDirectory, entry.name);
37957
+ const nextPath = join26(currentDirectory, entry.name);
37369
37958
  if (entry.isSymbolicLink()) {
37370
37959
  if (!await isDirectory(nextPath)) {
37371
37960
  continue;
@@ -37406,7 +37995,7 @@ function relativeProjectPath(projectRoot, sourceRoot) {
37406
37995
  return relative6(sourceRoot, projectRoot) || ".";
37407
37996
  }
37408
37997
  function resolveProjectRootFromConfig(projectRoot, config2) {
37409
- return normalizePath(join24(projectRoot, config2.project.root ?? "."));
37998
+ return normalizePath(join26(projectRoot, config2.project.root ?? "."));
37410
37999
  }
37411
38000
  function mergeResolvedAgentConfig(base, override, settings) {
37412
38001
  if (!override) {
@@ -37482,7 +38071,7 @@ function relayAgentOverrideFromResolvedConfig(config2) {
37482
38071
  }
37483
38072
  function projectDefaultDefinitionIds(config2) {
37484
38073
  return new Set([
37485
- basename14(config2.projectRoot),
38074
+ basename15(config2.projectRoot),
37486
38075
  config2.projectName
37487
38076
  ].map((value) => normalizeAgentId(value)).filter(Boolean));
37488
38077
  }
@@ -37523,8 +38112,8 @@ function selectorFromInput(value) {
37523
38112
  }
37524
38113
  async function resolveManifestBackedAgent(projectRoot, config2, settings, override) {
37525
38114
  const resolvedProjectRoot = resolveProjectRootFromConfig(projectRoot, config2);
37526
- const projectName = config2.project.name?.trim() || titleCase(config2.project.id || basename14(resolvedProjectRoot));
37527
- const fallbackDefinitionId = normalizeAgentId(config2.project.id || basename14(resolvedProjectRoot));
38115
+ const projectName = config2.project.name?.trim() || titleCase(config2.project.id || basename15(resolvedProjectRoot));
38116
+ const fallbackDefinitionId = normalizeAgentId(config2.project.id || basename15(resolvedProjectRoot));
37528
38117
  const definitionId = normalizeAgentId(config2.agent?.id || override?.definitionId || fallbackDefinitionId);
37529
38118
  const detectedHarness = await detectPreferredHarness(resolvedProjectRoot, settings.agents.defaultHarness);
37530
38119
  const runtimeDefaults = config2.agent?.runtime?.defaults;
@@ -37562,7 +38151,7 @@ async function resolveManifestBackedAgent(projectRoot, config2, settings, overri
37562
38151
  return mergeResolvedAgentConfig(base, override, settings);
37563
38152
  }
37564
38153
  async function resolveInferredAgent(projectRoot, settings, override) {
37565
- const projectName = basename14(projectRoot);
38154
+ const projectName = basename15(projectRoot);
37566
38155
  const definitionId = normalizeAgentId(override?.definitionId?.trim() || projectName);
37567
38156
  const detectedHarness = await detectPreferredHarness(projectRoot, settings.agents.defaultHarness);
37568
38157
  const defaultHarness = normalizeManagedHarness(override?.defaultHarness ?? override?.runtime?.harness, normalizeManagedHarness(detectedHarness, "claude"));
@@ -37598,7 +38187,7 @@ async function resolveInferredAgent(projectRoot, settings, override) {
37598
38187
  return mergeResolvedAgentConfig(base, override, settings);
37599
38188
  }
37600
38189
  async function buildProjectInventoryEntry(agent, sourceRoot) {
37601
- const manifestRoot = agent.projectConfigPath ? normalizePath(join24(dirname13(agent.projectConfigPath), "..")) : null;
38190
+ const manifestRoot = agent.projectConfigPath ? normalizePath(join26(dirname14(agent.projectConfigPath), "..")) : null;
37602
38191
  const manifest = manifestRoot ? await readProjectConfig(manifestRoot) : null;
37603
38192
  const markers = await detectHarnessMarkers(agent.projectRoot);
37604
38193
  const harnesses = new Map;
@@ -37706,7 +38295,7 @@ async function loadResolvedRelayAgents(options = {}) {
37706
38295
  const sourceRootByProject = new Map(workspaceCandidates.map((candidate) => [candidate.projectRoot, candidate.sourceRoot]));
37707
38296
  if (process.env.OPENSCOUT_SKIP_USER_PROJECT_HINTS !== "1") {
37708
38297
  try {
37709
- const hintHome = options.userLevelHintsHome ?? homedir23();
38298
+ const hintHome = options.userLevelHintsHome ?? homedir25();
37710
38299
  const userHints = await collectUserLevelProjectRootHints({ home: hintHome });
37711
38300
  for (const hint of userHints) {
37712
38301
  const normalized = normalizePath(hint);
@@ -37862,13 +38451,13 @@ async function ensureRelayAgentConfigured(value, options = {}) {
37862
38451
 
37863
38452
  // packages/runtime/src/broker-process-manager.ts
37864
38453
  import { spawn as spawn6, spawnSync as spawnSync2 } from "child_process";
37865
- import { existsSync as existsSync25, readFileSync as readFileSync12 } from "fs";
37866
- import { homedir as homedir25 } from "os";
37867
- import { dirname as dirname15, join as join26, resolve as resolve11 } from "path";
38454
+ import { existsSync as existsSync27, readFileSync as readFileSync13 } from "fs";
38455
+ import { homedir as homedir27 } from "os";
38456
+ import { dirname as dirname16, join as join28, resolve as resolve11 } from "path";
37868
38457
  import { fileURLToPath as fileURLToPath5 } from "url";
37869
38458
 
37870
38459
  // packages/runtime/src/broker-api.ts
37871
- import { existsSync as existsSync23 } from "fs";
38460
+ import { existsSync as existsSync25 } from "fs";
37872
38461
  import { request as httpRequest } from "http";
37873
38462
  var activeScoutBrokerServices = [];
37874
38463
  var DEFAULT_BROKER_JSON_REQUEST_TIMEOUT_MS = 30000;
@@ -37925,7 +38514,7 @@ function errorMessage4(error48) {
37925
38514
  }
37926
38515
  function requestBrokerOverUnixSocket(socketPath, baseUrl, path, options) {
37927
38516
  return new Promise((resolve11, reject) => {
37928
- if (!existsSync23(socketPath)) {
38517
+ if (!existsSync25(socketPath)) {
37929
38518
  reject(Object.assign(new Error(`Scout broker socket does not exist: ${socketPath}`), { code: "ENOENT" }));
37930
38519
  return;
37931
38520
  }
@@ -38070,11 +38659,11 @@ function unregisterActiveScoutBrokerService(serviceOrBaseUrl) {
38070
38659
  }
38071
38660
 
38072
38661
  // packages/runtime/src/tailscale.ts
38073
- import { readFileSync as readFileSync10 } from "fs";
38662
+ import { readFileSync as readFileSync11 } from "fs";
38074
38663
  import { execFileSync as execFileSync5 } from "child_process";
38075
38664
  var DEFAULT_TAILSCALE_STATUS_TIMEOUT_MS2 = 1500;
38076
38665
  function readStatusJsonFromFileSync(filePath) {
38077
- const raw = readFileSync10(filePath, "utf8");
38666
+ const raw = readFileSync11(filePath, "utf8");
38078
38667
  return parseTailscaleStatusJson(raw);
38079
38668
  }
38080
38669
  function statusTimeoutMs2(env) {
@@ -38130,14 +38719,14 @@ function readTailscaleSelfWebHostsSync(env = process.env) {
38130
38719
 
38131
38720
  // packages/runtime/src/local-config.ts
38132
38721
  import {
38133
- existsSync as existsSync24,
38722
+ existsSync as existsSync26,
38134
38723
  mkdirSync as mkdirSync2,
38135
- readFileSync as readFileSync11,
38724
+ readFileSync as readFileSync12,
38136
38725
  renameSync,
38137
38726
  writeFileSync as writeFileSync2
38138
38727
  } from "fs";
38139
- import { homedir as homedir24, hostname as osHostname } from "os";
38140
- import { dirname as dirname14, join as join25 } from "path";
38728
+ import { homedir as homedir26, hostname as osHostname } from "os";
38729
+ import { dirname as dirname15, join as join27 } from "path";
38141
38730
  var LOCAL_CONFIG_VERSION = 1;
38142
38731
  var DEFAULT_SCOUT_WEB_PORTAL_HOST = "scout.local";
38143
38732
  var DEFAULT_SCOUT_WEB_DEV_HOST = `dev.${DEFAULT_SCOUT_WEB_PORTAL_HOST}`;
@@ -38162,17 +38751,17 @@ var DEFAULT_LOCAL_CONFIG = {
38162
38751
  }
38163
38752
  };
38164
38753
  function localConfigHome() {
38165
- return process.env.OPENSCOUT_HOME ?? join25(homedir24(), ".openscout");
38754
+ return process.env.OPENSCOUT_HOME ?? join27(homedir26(), ".openscout");
38166
38755
  }
38167
38756
  function localConfigPath() {
38168
- return join25(localConfigHome(), "config.json");
38757
+ return join27(localConfigHome(), "config.json");
38169
38758
  }
38170
38759
  function loadLocalConfig() {
38171
38760
  const configPath = localConfigPath();
38172
- if (!existsSync24(configPath))
38761
+ if (!existsSync26(configPath))
38173
38762
  return { version: LOCAL_CONFIG_VERSION };
38174
38763
  try {
38175
- return validateLocalConfig(JSON.parse(readFileSync11(configPath, "utf8")));
38764
+ return validateLocalConfig(JSON.parse(readFileSync12(configPath, "utf8")));
38176
38765
  } catch {
38177
38766
  return { version: LOCAL_CONFIG_VERSION };
38178
38767
  }
@@ -38375,7 +38964,7 @@ function buildLocalBrokerControlUrl(host = DEFAULT_BROKER_HOST, port = DEFAULT_B
38375
38964
  return buildDefaultBrokerUrl(localBrokerControlHost2(host), port);
38376
38965
  }
38377
38966
  function buildDefaultBrokerSocketPath(runtimeDirectory) {
38378
- return join26(runtimeDirectory, "broker.sock");
38967
+ return join28(runtimeDirectory, "broker.sock");
38379
38968
  }
38380
38969
  var DEFAULT_BROKER_URL = buildDefaultBrokerUrl();
38381
38970
  function normalizeBrokerUrl(value) {
@@ -38408,17 +38997,17 @@ function runtimePackageDir() {
38408
38997
  const fromGlobal = findGlobalRuntimeDir();
38409
38998
  if (fromGlobal)
38410
38999
  return fromGlobal;
38411
- const moduleDir = dirname15(fileURLToPath5(import.meta.url));
39000
+ const moduleDir = dirname16(fileURLToPath5(import.meta.url));
38412
39001
  return resolve11(moduleDir, "..");
38413
39002
  }
38414
39003
  function isInstalledRuntimePackageDir(candidate) {
38415
- return existsSync25(join26(candidate, "package.json")) && existsSync25(join26(candidate, "bin", "openscout-runtime.mjs"));
39004
+ return existsSync27(join28(candidate, "package.json")) && existsSync27(join28(candidate, "bin", "openscout-runtime.mjs"));
38416
39005
  }
38417
39006
  function findGlobalRuntimeDir() {
38418
39007
  const candidates = [
38419
- join26(homedir25(), ".bun", "node_modules", "@openscout", "runtime"),
38420
- join26(homedir25(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
38421
- join26(homedir25(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
39008
+ join28(homedir27(), ".bun", "node_modules", "@openscout", "runtime"),
39009
+ join28(homedir27(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
39010
+ join28(homedir27(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
38422
39011
  ];
38423
39012
  for (const c of candidates) {
38424
39013
  if (isInstalledRuntimePackageDir(c))
@@ -38431,7 +39020,7 @@ function findGlobalRuntimeDir() {
38431
39020
  const scoutPkg = resolve11(scoutBin, "..", "..");
38432
39021
  if (isInstalledRuntimePackageDir(scoutPkg))
38433
39022
  return scoutPkg;
38434
- const nested = join26(scoutPkg, "node_modules", "@openscout", "runtime");
39023
+ const nested = join28(scoutPkg, "node_modules", "@openscout", "runtime");
38435
39024
  if (isInstalledRuntimePackageDir(nested))
38436
39025
  return nested;
38437
39026
  const sibling = resolve11(scoutPkg, "..", "runtime");
@@ -38442,7 +39031,7 @@ function findGlobalRuntimeDir() {
38442
39031
  return null;
38443
39032
  }
38444
39033
  function findBundledRuntimeDir() {
38445
- const moduleDir = dirname15(fileURLToPath5(import.meta.url));
39034
+ const moduleDir = dirname16(fileURLToPath5(import.meta.url));
38446
39035
  return resolveBundledRuntimeDirFromModuleDir(moduleDir);
38447
39036
  }
38448
39037
  function resolveBundledRuntimeDirFromModuleDir(moduleDir) {
@@ -38459,11 +39048,11 @@ function resolveBundledRuntimeDirFromModuleDir(moduleDir) {
38459
39048
  function findWorkspaceRuntimeDir(startDir) {
38460
39049
  let current = resolve11(startDir);
38461
39050
  while (true) {
38462
- const candidate = join26(current, "packages", "runtime");
38463
- if (existsSync25(join26(candidate, "package.json")) && existsSync25(join26(candidate, "src"))) {
39051
+ const candidate = join28(current, "packages", "runtime");
39052
+ if (existsSync27(join28(candidate, "package.json")) && existsSync27(join28(candidate, "src"))) {
38464
39053
  return candidate;
38465
39054
  }
38466
- const parent = dirname15(current);
39055
+ const parent = dirname16(current);
38467
39056
  if (parent === current)
38468
39057
  return null;
38469
39058
  current = parent;
@@ -38510,17 +39099,17 @@ function resolveBrokerServiceConfig() {
38510
39099
  const serviceAdapter = resolveBrokerServiceAdapter();
38511
39100
  const uid = typeof process.getuid === "function" ? process.getuid() : Number.parseInt(process.env.UID ?? "0", 10);
38512
39101
  const supportPaths = resolveOpenScoutSupportPaths();
38513
- const defaultSupportDir = join26(homedir25(), "Library", "Application Support", "OpenScout");
39102
+ const defaultSupportDir = join28(homedir27(), "Library", "Application Support", "OpenScout");
38514
39103
  const supportDirectory = isTmpPath(supportPaths.supportDirectory) ? defaultSupportDir : supportPaths.supportDirectory;
38515
- const runtimeDirectory = join26(supportDirectory, "runtime");
38516
- const logsDirectory = join26(supportDirectory, "logs", "broker");
38517
- const controlHome = isTmpPath(supportPaths.controlHome) ? join26(homedir25(), ".openscout", "control-plane") : supportPaths.controlHome;
39104
+ const runtimeDirectory = join28(supportDirectory, "runtime");
39105
+ const logsDirectory = join28(supportDirectory, "logs", "broker");
39106
+ const controlHome = isTmpPath(supportPaths.controlHome) ? join28(homedir27(), ".openscout", "control-plane") : supportPaths.controlHome;
38518
39107
  const advertiseScope = resolveAdvertiseScope();
38519
39108
  const brokerHost = resolveBrokerHost(advertiseScope);
38520
39109
  const brokerPort = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(resolveBrokerPort()), 10);
38521
39110
  const brokerUrl = resolveBrokerUrl(brokerHost, brokerPort, advertiseScope);
38522
39111
  const brokerSocketPath = process.env.OPENSCOUT_BROKER_SOCKET_PATH ?? buildDefaultBrokerSocketPath(runtimeDirectory);
38523
- const launchAgentPath = join26(homedir25(), "Library", "LaunchAgents", `${label}.plist`);
39112
+ const launchAgentPath = join28(homedir27(), "Library", "LaunchAgents", `${label}.plist`);
38524
39113
  return {
38525
39114
  label,
38526
39115
  mode,
@@ -38531,8 +39120,8 @@ function resolveBrokerServiceConfig() {
38531
39120
  supportDirectory,
38532
39121
  runtimeDirectory,
38533
39122
  logsDirectory,
38534
- stdoutLogPath: join26(logsDirectory, "stdout.log"),
38535
- stderrLogPath: join26(logsDirectory, "stderr.log"),
39123
+ stdoutLogPath: join28(logsDirectory, "stdout.log"),
39124
+ stderrLogPath: join28(logsDirectory, "stderr.log"),
38536
39125
  controlHome,
38537
39126
  runtimePackageDir: runtimePackageDir(),
38538
39127
  bunExecutable: serviceAdapter === "macos-scoutd" ? resolveBunExecutable3() : resolveOptionalBunExecutable(),
@@ -38566,10 +39155,10 @@ function resolveEnvExecutable(value) {
38566
39155
  function findWorkspaceRootFromRuntimeDir(runtimePackageDir2) {
38567
39156
  let current = resolve11(runtimePackageDir2);
38568
39157
  while (true) {
38569
- if (existsSync25(join26(current, "Cargo.toml")) && existsSync25(join26(current, "crates", "scoutd", "Cargo.toml"))) {
39158
+ if (existsSync27(join28(current, "Cargo.toml")) && existsSync27(join28(current, "crates", "scoutd", "Cargo.toml"))) {
38570
39159
  return current;
38571
39160
  }
38572
- const parent = dirname15(current);
39161
+ const parent = dirname16(current);
38573
39162
  if (parent === current)
38574
39163
  return null;
38575
39164
  current = parent;
@@ -38586,13 +39175,13 @@ function resolveScoutdCommand(config2 = resolveBrokerServiceConfig()) {
38586
39175
  }
38587
39176
  const workspaceRoot = findWorkspaceRootFromRuntimeDir(config2.runtimePackageDir);
38588
39177
  const packageCandidates = [
38589
- join26(config2.runtimePackageDir, "bin", "scoutd"),
38590
- join26(config2.runtimePackageDir, "native", "scoutd"),
38591
- join26(config2.runtimePackageDir, "scoutd"),
38592
- workspaceRoot ? join26(workspaceRoot, "packages", "cli", "bin", "scoutd") : null,
38593
- workspaceRoot ? join26(workspaceRoot, "packages", "runtime", "bin", "scoutd") : null,
38594
- join26(config2.runtimeDirectory, "scoutd"),
38595
- join26(dirname15(config2.runtimePackageDir), "scout", "bin", "scoutd")
39178
+ join28(config2.runtimePackageDir, "bin", "scoutd"),
39179
+ join28(config2.runtimePackageDir, "native", "scoutd"),
39180
+ join28(config2.runtimePackageDir, "scoutd"),
39181
+ workspaceRoot ? join28(workspaceRoot, "packages", "cli", "bin", "scoutd") : null,
39182
+ workspaceRoot ? join28(workspaceRoot, "packages", "runtime", "bin", "scoutd") : null,
39183
+ join28(config2.runtimeDirectory, "scoutd"),
39184
+ join28(dirname16(config2.runtimePackageDir), "scout", "bin", "scoutd")
38596
39185
  ];
38597
39186
  for (const candidate of packageCandidates) {
38598
39187
  const resolved = executableCandidate(candidate);
@@ -38606,8 +39195,8 @@ function resolveScoutdCommand(config2 = resolveBrokerServiceConfig()) {
38606
39195
  }
38607
39196
  if (workspaceRoot && workspaceScoutdAllowed()) {
38608
39197
  for (const candidate of [
38609
- join26(workspaceRoot, "target", "release", "scoutd"),
38610
- join26(workspaceRoot, "target", "debug", "scoutd")
39198
+ join28(workspaceRoot, "target", "release", "scoutd"),
39199
+ join28(workspaceRoot, "target", "debug", "scoutd")
38611
39200
  ]) {
38612
39201
  const resolved = executableCandidate(candidate);
38613
39202
  if (resolved) {
@@ -38641,7 +39230,7 @@ function nativeServiceEnvironment(config2, scoutdPath) {
38641
39230
  }
38642
39231
  return env;
38643
39232
  }
38644
- function isRecord6(value) {
39233
+ function isRecord7(value) {
38645
39234
  return typeof value === "object" && value !== null && !Array.isArray(value);
38646
39235
  }
38647
39236
  function readString3(value) {
@@ -38656,8 +39245,31 @@ function readNumber3(value) {
38656
39245
  function readHealthTransport(value) {
38657
39246
  return value === "unix_socket" || value === "http" || value === "in_process" ? value : undefined;
38658
39247
  }
39248
+ function readRuntimeFreshness(value) {
39249
+ if (!isRecord7(value))
39250
+ return;
39251
+ const state = readString3(value.state);
39252
+ const basis = readString3(value.basis);
39253
+ const detail = readString3(value.detail);
39254
+ if (!state || !basis || !detail)
39255
+ return;
39256
+ return {
39257
+ state,
39258
+ intentional: readBoolean(value.intentional) ?? false,
39259
+ basis,
39260
+ artifactCommit: readString3(value.artifactCommit) ?? null,
39261
+ expectedCommit: readString3(value.expectedCommit) ?? null,
39262
+ pin: readString3(value.pin) ?? null,
39263
+ pinReason: readString3(value.pinReason) ?? null,
39264
+ manifestPath: readString3(value.manifestPath) ?? null,
39265
+ version: readString3(value.version) ?? null,
39266
+ builtAt: readString3(value.builtAt) ?? null,
39267
+ sourceDirty: readBoolean(value.sourceDirty) ?? null,
39268
+ detail
39269
+ };
39270
+ }
38659
39271
  function normalizeNativeServiceStatus(input, config2) {
38660
- const healthRecord = isRecord6(input.health) ? input.health : {};
39272
+ const healthRecord = isRecord7(input.health) ? input.health : {};
38661
39273
  const healthReachable = readBoolean(healthRecord.reachable) ?? readBoolean(input.reachable) ?? false;
38662
39274
  const healthOk = readBoolean(healthRecord.ok) ?? (typeof input.health === "boolean" ? input.health : undefined) ?? false;
38663
39275
  const healthError = readString3(healthRecord.error) ?? readString3(input.healthError);
@@ -38665,12 +39277,13 @@ function normalizeNativeServiceStatus(input, config2) {
38665
39277
  const healthNodeId = readString3(healthRecord.nodeId);
38666
39278
  const healthMeshId = readString3(healthRecord.meshId);
38667
39279
  const healthSocketFallbackError = readString3(healthRecord.socketFallbackError);
38668
- const healthCounts = isRecord6(healthRecord.counts) ? healthRecord.counts : undefined;
38669
- const installed = readBoolean(input.installed) ?? existsSync25(config2.launchAgentPath);
39280
+ const healthCounts = isRecord7(healthRecord.counts) ? healthRecord.counts : undefined;
39281
+ const installed = readBoolean(input.installed) ?? existsSync27(config2.launchAgentPath);
38670
39282
  const loaded = readBoolean(input.loaded) ?? false;
38671
39283
  const stdoutLogPath = readString3(input.stdoutLogPath) ?? config2.stdoutLogPath;
38672
39284
  const stderrLogPath = readString3(input.stderrLogPath) ?? config2.stderrLogPath;
38673
39285
  const lastLogLine = readString3(input.lastLogLine) ?? (healthReachable ? readLastLogLine([stdoutLogPath, stderrLogPath]) : readLastLogLine([stderrLogPath, stdoutLogPath]));
39286
+ const runtimeFreshness = readRuntimeFreshness(input.runtimeFreshness);
38674
39287
  return {
38675
39288
  label: readString3(input.label) ?? config2.label,
38676
39289
  mode: readString3(input.mode) ?? config2.mode,
@@ -38701,10 +39314,11 @@ function normalizeNativeServiceStatus(input, config2) {
38701
39314
  ...healthNodeId ? { nodeId: healthNodeId } : {},
38702
39315
  ...healthMeshId ? { meshId: healthMeshId } : {},
38703
39316
  ...healthCounts ? { counts: healthCounts } : {},
38704
- ...isRecord6(healthRecord.build) ? { build: healthRecord.build } : {},
38705
- ...isRecord6(healthRecord.services) ? { services: healthRecord.services } : {},
39317
+ ...isRecord7(healthRecord.build) ? { build: healthRecord.build } : {},
39318
+ ...isRecord7(healthRecord.services) ? { services: healthRecord.services } : {},
38706
39319
  error: healthError
38707
39320
  },
39321
+ ...runtimeFreshness ? { runtimeFreshness } : {},
38708
39322
  lastLogLine
38709
39323
  };
38710
39324
  }
@@ -38796,7 +39410,7 @@ async function runScoutdServiceCommand(command, config2, timeoutMs = SCOUTD_DEFA
38796
39410
  function readCoreAgentsSync() {
38797
39411
  try {
38798
39412
  const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
38799
- const raw = readFileSync12(settingsPath, "utf8");
39413
+ const raw = readFileSync13(settingsPath, "utf8");
38800
39414
  const settings = JSON.parse(raw);
38801
39415
  const raw_agents = settings?.agents?.coreAgents;
38802
39416
  if (Array.isArray(raw_agents)) {
@@ -38809,10 +39423,10 @@ function bootoutCommand(config2) {
38809
39423
  return `/bin/launchctl bootout ${config2.serviceTarget}`;
38810
39424
  }
38811
39425
  function readLogLines(path) {
38812
- if (!existsSync25(path)) {
39426
+ if (!existsSync27(path)) {
38813
39427
  return [];
38814
39428
  }
38815
- return readFileSync12(path, "utf8").split(`
39429
+ return readFileSync13(path, "utf8").split(`
38816
39430
  `).map((line) => line.trim()).filter(Boolean);
38817
39431
  }
38818
39432
  function isPackageScriptBanner(line) {
@@ -39009,8 +39623,12 @@ function formatBrokerServiceStatus(status) {
39009
39623
  `reachable: ${status.reachable ? "yes" : "no"}`,
39010
39624
  `health: ${status.health.ok ? "ok" : status.health.error ?? "unreachable"}`,
39011
39625
  `health transport: ${status.health.transport ?? "unknown"}`,
39626
+ `runtime freshness: ${status.runtimeFreshness?.state ?? "unavailable"}`,
39012
39627
  `logs: ${status.stdoutLogPath}`
39013
39628
  ];
39629
+ if (status.runtimeFreshness) {
39630
+ lines.push(`runtime freshness detail: ${status.runtimeFreshness.detail}`);
39631
+ }
39014
39632
  if (status.health.socketFallbackError) {
39015
39633
  lines.push(`socket fallback: ${status.health.socketFallbackError}`);
39016
39634
  }
@@ -39087,28 +39705,28 @@ function compileCodexPermissionProfile(profileInput) {
39087
39705
  }
39088
39706
 
39089
39707
  // packages/runtime/src/user-config.ts
39090
- import { existsSync as existsSync26, readFileSync as readFileSync13, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
39091
- import { homedir as homedir26 } from "os";
39092
- import { dirname as dirname16, join as join27 } from "path";
39708
+ import { existsSync as existsSync28, readFileSync as readFileSync14, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
39709
+ import { homedir as homedir28 } from "os";
39710
+ import { dirname as dirname17, join as join29 } from "path";
39093
39711
  function userConfigPath() {
39094
- return join27(process.env.OPENSCOUT_HOME ?? join27(homedir26(), ".openscout"), "user.json");
39712
+ return join29(process.env.OPENSCOUT_HOME ?? join29(homedir28(), ".openscout"), "user.json");
39095
39713
  }
39096
39714
  function loadUserConfig() {
39097
39715
  const configPath = userConfigPath();
39098
- if (!existsSync26(configPath))
39716
+ if (!existsSync28(configPath))
39099
39717
  return {};
39100
39718
  try {
39101
- return JSON.parse(readFileSync13(configPath, "utf8"));
39719
+ return JSON.parse(readFileSync14(configPath, "utf8"));
39102
39720
  } catch {
39103
39721
  return {};
39104
39722
  }
39105
39723
  }
39106
39724
  function readSettingsOperatorName() {
39107
39725
  const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
39108
- if (!existsSync26(settingsPath))
39726
+ if (!existsSync28(settingsPath))
39109
39727
  return "";
39110
39728
  try {
39111
- const settings = JSON.parse(readFileSync13(settingsPath, "utf8"));
39729
+ const settings = JSON.parse(readFileSync14(settingsPath, "utf8"));
39112
39730
  const candidate = typeof settings.profile?.operatorName === "string" ? settings.profile.operatorName : typeof settings.operatorName === "string" ? settings.operatorName : "";
39113
39731
  return candidate.trim();
39114
39732
  } catch {
@@ -39128,7 +39746,7 @@ function resolveOperatorHandle() {
39128
39746
  }
39129
39747
 
39130
39748
  // packages/runtime/src/local-agents.ts
39131
- var MODULE_DIRECTORY = dirname17(fileURLToPath6(import.meta.url));
39749
+ var MODULE_DIRECTORY = dirname18(fileURLToPath6(import.meta.url));
39132
39750
  var OPENSCOUT_REPO_ROOT = resolve12(MODULE_DIRECTORY, "..", "..", "..");
39133
39751
  function isBrokerSnapshotMessage(value) {
39134
39752
  if (!value || typeof value !== "object")
@@ -39156,14 +39774,14 @@ function resolveProjectsRoot(projectPath) {
39156
39774
  }
39157
39775
  try {
39158
39776
  const supportPaths = resolveOpenScoutSupportPaths();
39159
- if (!existsSync27(supportPaths.settingsPath)) {
39160
- return dirname17(projectPath);
39777
+ if (!existsSync29(supportPaths.settingsPath)) {
39778
+ return dirname18(projectPath);
39161
39779
  }
39162
- const raw = JSON.parse(readFileSync14(supportPaths.settingsPath, "utf8"));
39780
+ const raw = JSON.parse(readFileSync15(supportPaths.settingsPath, "utf8"));
39163
39781
  const workspaceRoot = raw.discovery?.workspaceRoots?.find((entry) => typeof entry === "string" && entry.trim().length > 0);
39164
- return workspaceRoot ? resolve12(workspaceRoot) : dirname17(projectPath);
39782
+ return workspaceRoot ? resolve12(workspaceRoot) : dirname18(projectPath);
39165
39783
  } catch {
39166
- return dirname17(projectPath);
39784
+ return dirname18(projectPath);
39167
39785
  }
39168
39786
  }
39169
39787
  function resolveBrokerUrl2() {
@@ -39181,7 +39799,7 @@ function normalizeBrokerTimestamp(value) {
39181
39799
  return ms === null ? 0 : Math.floor(ms / 1000);
39182
39800
  }
39183
39801
  function scoutCliPath() {
39184
- return join28(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
39802
+ return join30(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
39185
39803
  }
39186
39804
  function legacyNodeBrokerRelayCommand() {
39187
39805
  return `node ${JSON.stringify(scoutCliPath())}`;
@@ -39205,17 +39823,18 @@ var SUPPORTED_LOCAL_AGENT_HARNESSES = ["claude", "codex", "grok", "pi"];
39205
39823
  var SUPPORTED_SCOUT_HARNESSES = [
39206
39824
  ...SUPPORTED_LOCAL_AGENT_HARNESSES,
39207
39825
  "grok-acp",
39826
+ "kimi",
39208
39827
  "flue"
39209
39828
  ];
39210
39829
  function resolveScoutSkillPath() {
39211
39830
  const candidatePaths = [
39212
- join28(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
39213
- join28(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
39214
- join28(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
39215
- join28(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
39831
+ join30(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
39832
+ join30(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
39833
+ join30(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
39834
+ join30(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
39216
39835
  ];
39217
39836
  for (const path of candidatePaths) {
39218
- if (existsSync27(path)) {
39837
+ if (existsSync29(path)) {
39219
39838
  return path;
39220
39839
  }
39221
39840
  }
@@ -39485,7 +40104,7 @@ function expandHomePath4(value) {
39485
40104
  return process.env.HOME ?? process.cwd();
39486
40105
  }
39487
40106
  if (value.startsWith("~/")) {
39488
- return join28(process.env.HOME ?? process.cwd(), value.slice(2));
40107
+ return join30(process.env.HOME ?? process.cwd(), value.slice(2));
39489
40108
  }
39490
40109
  return value;
39491
40110
  }
@@ -39770,6 +40389,23 @@ function stripLaunchReasoningEffortForHarness(harness, launchArgs) {
39770
40389
  }
39771
40390
  return next2;
39772
40391
  }
40392
+ if (harness === "claude" || harness === "grok") {
40393
+ const next2 = [];
40394
+ const normalized2 = normalizeLocalAgentLaunchArgs(launchArgs);
40395
+ const flags = ["--effort", "--reasoning-effort"];
40396
+ for (let index = 0;index < normalized2.length; index += 1) {
40397
+ const current = normalized2[index] ?? "";
40398
+ if (flags.includes(current)) {
40399
+ index += 1;
40400
+ continue;
40401
+ }
40402
+ if (flags.some((flag) => current.startsWith(`${flag}=`))) {
40403
+ continue;
40404
+ }
40405
+ next2.push(current);
40406
+ }
40407
+ return next2;
40408
+ }
39773
40409
  if (harness !== "codex") {
39774
40410
  return normalizeLaunchArgsForHarness(harness, launchArgs);
39775
40411
  }
@@ -39803,6 +40439,9 @@ function buildLaunchArgsForRequestedReasoningEffort(harness, reasoningEffort) {
39803
40439
  if (harness === "codex") {
39804
40440
  return normalizeCodexAppServerLaunchArgs(["--reasoning-effort", reasoningEffort]);
39805
40441
  }
40442
+ if (harness === "claude") {
40443
+ return ["--effort", reasoningEffort];
40444
+ }
39806
40445
  if (harness === "pi") {
39807
40446
  return ["--thinking", reasoningEffort.trim().toLowerCase() === "none" ? "off" : reasoningEffort];
39808
40447
  }
@@ -39963,7 +40602,7 @@ function normalizeLocalAgentCardLifecycle(value, now = Date.now()) {
39963
40602
  function normalizeLocalAgentRecord(agentId, record2) {
39964
40603
  const cwd = normalizeProjectPath(record2.cwd || process.cwd());
39965
40604
  const projectRoot = normalizeProjectPath(record2.projectRoot || cwd);
39966
- const project = record2.project?.trim() || basename15(projectRoot);
40605
+ const project = record2.project?.trim() || basename16(projectRoot);
39967
40606
  const definitionId = record2.definitionId?.trim() || agentId;
39968
40607
  const defaultHarness = activeLocalHarness(record2);
39969
40608
  const harnessProfiles = normalizeLocalHarnessProfiles(agentId, {
@@ -40015,7 +40654,7 @@ function localAgentRecordFromRelayAgentOverride(agentId, override) {
40015
40654
  return normalizeLocalAgentRecord(agentId, {
40016
40655
  definitionId: override.definitionId ?? agentId,
40017
40656
  registrationSource: override.source,
40018
- project: override.projectName ?? basename15(override.projectRoot || override.runtime?.cwd || agentId),
40657
+ project: override.projectName ?? basename16(override.projectRoot || override.runtime?.cwd || agentId),
40019
40658
  projectRoot: override.projectRoot ?? override.runtime?.cwd,
40020
40659
  tmuxSession: override.runtime?.sessionId ?? `relay-${agentId}`,
40021
40660
  cwd: override.runtime?.cwd ?? override.projectRoot,
@@ -40150,6 +40789,12 @@ function attachedCodexEndpointLaunchArgs(endpoint) {
40150
40789
  reasoningEffort: endpointMetadataString(endpoint, "reasoningEffort")
40151
40790
  });
40152
40791
  }
40792
+ function attachedClaudeEndpointLaunchArgs(endpoint) {
40793
+ return applyRequestedRuntimeOptionsToLaunchArgs("claude", endpointMetadataStringArray(endpoint, "launchArgs"), {
40794
+ model: endpointMetadataString(endpoint, "model"),
40795
+ reasoningEffort: endpointMetadataString(endpoint, "reasoningEffort")
40796
+ });
40797
+ }
40153
40798
  function attachedPiEndpointLaunchArgs(endpoint) {
40154
40799
  return applyRequestedRuntimeOptionsToLaunchArgs("pi", endpointMetadataStringArray(endpoint, "launchArgs"), {
40155
40800
  model: endpointMetadataString(endpoint, "model"),
@@ -40192,6 +40837,14 @@ function attachedLocalSessionSystemPrompt(endpoint) {
40192
40837
  }
40193
40838
  return "Resume the existing session without changing its identity or prior context.";
40194
40839
  }
40840
+ function attachedCodexApprovalPolicy(endpoint) {
40841
+ const value = endpointMetadataString(endpoint, "approvalPolicy");
40842
+ return value === "untrusted" || value === "on-request" || value === "on-failure" || value === "never" ? value : undefined;
40843
+ }
40844
+ function attachedCodexSandbox(endpoint) {
40845
+ const value = endpointMetadataString(endpoint, "sandbox");
40846
+ return value === "read-only" || value === "workspace-write" || value === "danger-full-access" ? value : undefined;
40847
+ }
40195
40848
  function buildCodexEndpointSessionOptions(endpoint) {
40196
40849
  const agentName = endpointAgentName(endpoint);
40197
40850
  const ownsSessionThread = endpoint.metadata?.source === "scoutbot";
@@ -40204,6 +40857,8 @@ function buildCodexEndpointSessionOptions(endpoint) {
40204
40857
  runtimeDirectory: relayAgentRuntimeDirectory(agentName),
40205
40858
  logsDirectory: relayAgentLogsDirectory(agentName),
40206
40859
  launchArgs: attachedCodexEndpointLaunchArgs(endpoint),
40860
+ approvalPolicy: attachedCodexApprovalPolicy(endpoint),
40861
+ sandbox: attachedCodexSandbox(endpoint),
40207
40862
  threadId,
40208
40863
  requireExistingThread: Boolean(threadId) && !ownsSessionThread
40209
40864
  });
@@ -40217,7 +40872,7 @@ function buildClaudeEndpointSessionOptions(endpoint) {
40217
40872
  systemPrompt: attachedLocalSessionSystemPrompt(endpoint),
40218
40873
  runtimeDirectory: relayAgentRuntimeDirectory(agentName),
40219
40874
  logsDirectory: relayAgentLogsDirectory(agentName),
40220
- launchArgs: []
40875
+ launchArgs: attachedClaudeEndpointLaunchArgs(endpoint)
40221
40876
  };
40222
40877
  }
40223
40878
  function buildPiEndpointSessionOptions(endpoint) {
@@ -40270,7 +40925,7 @@ function isLocalAgentEndpointAlive(endpoint) {
40270
40925
  if (endpoint.transport === "pi_rpc") {
40271
40926
  return isPiRpcAgentAlive(buildPiEndpointSessionOptions(endpoint));
40272
40927
  }
40273
- if (endpoint.transport === "grok_acp") {
40928
+ if (endpoint.transport === "grok_acp" || endpoint.transport === "kimi_acp") {
40274
40929
  return endpoint.state !== "offline";
40275
40930
  }
40276
40931
  const sessionId = endpoint.sessionId ?? (typeof endpoint.metadata?.tmuxSession === "string" ? String(endpoint.metadata.tmuxSession) : null);
@@ -40434,7 +41089,7 @@ function buildScoutReplyContext(agentName, invocation) {
40434
41089
  };
40435
41090
  }
40436
41091
  function scoutReplyContextPath(runtimeDirectory) {
40437
- return join28(runtimeDirectory, "scout-reply-context.json");
41092
+ return join30(runtimeDirectory, "scout-reply-context.json");
40438
41093
  }
40439
41094
  function withScoutReplyContextEnvironment(options) {
40440
41095
  return {
@@ -40702,7 +41357,7 @@ function stripLocalAgentReplyMetadata(body, flightId, asker) {
40702
41357
  async function sendLocalAgentPrompt(agentName, record2, prompt) {
40703
41358
  const harness = normalizeLocalAgentHarness(record2.harness);
40704
41359
  if (harness === "codex") {
40705
- const promptPipe = join28(relayAgentRuntimeDirectory(agentName), "prompt.pipe");
41360
+ const promptPipe = join30(relayAgentRuntimeDirectory(agentName), "prompt.pipe");
40706
41361
  await writeFile8(promptPipe, prompt.trim() + "\x00");
40707
41362
  return;
40708
41363
  }
@@ -40939,10 +41594,10 @@ function buildLocalAgentLaunchCommand(agentName, record2, projectPath, promptFil
40939
41594
  const harness = normalizeLocalAgentHarness(record2.harness);
40940
41595
  const extraArgs = shellQuoteArguments(harness === "claude" ? normalizeClaudeRuntimeLaunchArgs(record2.launchArgs) : harness === "grok" ? normalizeGrokRuntimeLaunchArgs(record2.launchArgs) : normalizeLaunchArgsForHarness(harness, record2.launchArgs));
40941
41596
  if (harness === "codex") {
40942
- return `exec bash ${JSON.stringify(workerScript ?? join28(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
41597
+ return `exec bash ${JSON.stringify(workerScript ?? join30(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
40943
41598
  }
40944
41599
  if (harness === "pi") {
40945
- const sessionDir = join28(relayAgentRuntimeDirectory(agentName), "pi-sessions");
41600
+ const sessionDir = join30(relayAgentRuntimeDirectory(agentName), "pi-sessions");
40946
41601
  return [
40947
41602
  "pi",
40948
41603
  `--append-system-prompt "$(cat ${JSON.stringify(promptFile)})"`,
@@ -40981,12 +41636,12 @@ function isShellCommandAvailable(binary) {
40981
41636
  if (!binary.trim())
40982
41637
  return false;
40983
41638
  if (binary.includes("/"))
40984
- return existsSync27(binary);
41639
+ return existsSync29(binary);
40985
41640
  const pathValue = process.env.PATH ?? "";
40986
41641
  for (const directory of pathValue.split(":")) {
40987
41642
  if (!directory)
40988
41643
  continue;
40989
- if (existsSync27(join28(directory, binary)))
41644
+ if (existsSync29(join30(directory, binary)))
40990
41645
  return true;
40991
41646
  }
40992
41647
  return false;
@@ -41038,7 +41693,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
41038
41693
  return normalizedRecord;
41039
41694
  }
41040
41695
  const projectPath = normalizedRecord.cwd;
41041
- const projectName = normalizedRecord.project || basename15(projectPath);
41696
+ const projectName = normalizedRecord.project || basename16(projectPath);
41042
41697
  const systemPromptTemplate = normalizedRecord.systemPrompt || buildLocalAgentSystemPromptTemplate();
41043
41698
  const systemPrompt = renderLocalAgentSystemPromptTemplate(systemPromptTemplate, buildLocalAgentTemplateContext(agentName, projectName, projectPath), { transport: normalizedRecord.transport });
41044
41699
  const agentRuntimeDir = relayAgentRuntimeDirectory(agentName);
@@ -41046,7 +41701,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
41046
41701
  await mkdir8(agentRuntimeDir, { recursive: true });
41047
41702
  await mkdir8(logsDir, { recursive: true });
41048
41703
  if (normalizedRecord.transport === "codex_app_server") {
41049
- await writeFile8(join28(agentRuntimeDir, "prompt.txt"), systemPrompt);
41704
+ await writeFile8(join30(agentRuntimeDir, "prompt.txt"), systemPrompt);
41050
41705
  await ensureCodexAppServerAgentOnline(buildCodexAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
41051
41706
  const registry4 = await readLocalAgentRegistry();
41052
41707
  registry4[agentName] = {
@@ -41058,7 +41713,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
41058
41713
  return registry4[agentName];
41059
41714
  }
41060
41715
  if (normalizedRecord.transport === "claude_stream_json") {
41061
- await writeFile8(join28(agentRuntimeDir, "prompt.txt"), systemPrompt);
41716
+ await writeFile8(join30(agentRuntimeDir, "prompt.txt"), systemPrompt);
41062
41717
  await ensureClaudeStreamJsonAgentOnline(buildClaudeAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
41063
41718
  const registry4 = await readLocalAgentRegistry();
41064
41719
  registry4[agentName] = {
@@ -41070,7 +41725,7 @@ async function ensureLocalAgentOnline(agentName, record2) {
41070
41725
  return registry4[agentName];
41071
41726
  }
41072
41727
  if (normalizedRecord.transport === "pi_rpc") {
41073
- await writeFile8(join28(agentRuntimeDir, "prompt.txt"), systemPrompt);
41728
+ await writeFile8(join30(agentRuntimeDir, "prompt.txt"), systemPrompt);
41074
41729
  await ensurePiRpcAgentOnline(buildPiAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
41075
41730
  const registry4 = await readLocalAgentRegistry();
41076
41731
  registry4[agentName] = {
@@ -41083,17 +41738,17 @@ async function ensureLocalAgentOnline(agentName, record2) {
41083
41738
  }
41084
41739
  const initialMessage = buildLocalAgentInitialMessage(projectName, agentName);
41085
41740
  const bootstrapPrompt = buildLocalAgentBootstrapPrompt(normalizeLocalAgentHarness(normalizedRecord.harness), systemPrompt, initialMessage);
41086
- const queueDirectory = join28(agentRuntimeDir, "queue");
41087
- const processingDirectory = join28(queueDirectory, "processing");
41088
- const processedDirectory = join28(queueDirectory, "processed");
41089
- const promptFile = join28(agentRuntimeDir, "prompt.txt");
41090
- const initialFile = join28(agentRuntimeDir, "initial.txt");
41091
- const launchScript = join28(agentRuntimeDir, "launch.sh");
41092
- const workerScript = join28(agentRuntimeDir, "codex-worker.sh");
41093
- const codexSessionIdFile = join28(agentRuntimeDir, "codex-session-id.txt");
41094
- const stateFile = join28(agentRuntimeDir, "state.json");
41095
- const stdoutLogFile = join28(logsDir, "stdout.log");
41096
- const stderrLogFile = join28(logsDir, "stderr.log");
41741
+ const queueDirectory = join30(agentRuntimeDir, "queue");
41742
+ const processingDirectory = join30(queueDirectory, "processing");
41743
+ const processedDirectory = join30(queueDirectory, "processed");
41744
+ const promptFile = join30(agentRuntimeDir, "prompt.txt");
41745
+ const initialFile = join30(agentRuntimeDir, "initial.txt");
41746
+ const launchScript = join30(agentRuntimeDir, "launch.sh");
41747
+ const workerScript = join30(agentRuntimeDir, "codex-worker.sh");
41748
+ const codexSessionIdFile = join30(agentRuntimeDir, "codex-session-id.txt");
41749
+ const stateFile = join30(agentRuntimeDir, "state.json");
41750
+ const stdoutLogFile = join30(logsDir, "stdout.log");
41751
+ const stderrLogFile = join30(logsDir, "stderr.log");
41097
41752
  await writeFile8(promptFile, systemPrompt);
41098
41753
  await writeFile8(initialFile, bootstrapPrompt);
41099
41754
  await writeFile8(stderrLogFile, "");
@@ -41157,14 +41812,15 @@ async function ensureLocalAgentOnline(agentName, record2) {
41157
41812
  updatedAt: new Date().toISOString()
41158
41813
  }, null, 2) + `
41159
41814
  `);
41160
- for (let attempt = 0;attempt < 20; attempt += 1) {
41161
- if (isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
41162
- break;
41815
+ let sessionOnline = false;
41816
+ for (let attempt = 0;attempt < 20 && !sessionOnline; attempt += 1) {
41817
+ sessionOnline = await isLocalAgentSessionAliveAsync(normalizedRecord.tmuxSession);
41818
+ if (!sessionOnline) {
41819
+ await new Promise((resolve13) => setTimeout(resolve13, 100));
41163
41820
  }
41164
- await new Promise((resolve13) => setTimeout(resolve13, 100));
41165
41821
  }
41166
- if (!isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
41167
- const stderrTail = existsSync27(stderrLogFile) ? readFileSync14(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
41822
+ if (!sessionOnline) {
41823
+ const stderrTail = existsSync29(stderrLogFile) ? readFileSync15(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
41168
41824
  `).trim() : "";
41169
41825
  throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
41170
41826
  ${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
@@ -41186,9 +41842,9 @@ ${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
41186
41842
  }
41187
41843
  function readPersistedSessionCatalogId(runtimeDir) {
41188
41844
  try {
41189
- const catalogPath = join28(runtimeDir, "session-catalog.json");
41190
- if (existsSync27(catalogPath)) {
41191
- const raw = readFileSync14(catalogPath, "utf8").trim();
41845
+ const catalogPath = join30(runtimeDir, "session-catalog.json");
41846
+ if (existsSync29(catalogPath)) {
41847
+ const raw = readFileSync15(catalogPath, "utf8").trim();
41192
41848
  if (raw) {
41193
41849
  const catalog = JSON.parse(raw);
41194
41850
  if (typeof catalog.activeSessionId === "string" && catalog.activeSessionId.trim()) {
@@ -41203,9 +41859,9 @@ function readPersistedSessionCatalogId(runtimeDir) {
41203
41859
  }
41204
41860
  function readPersistedLegacySessionId(runtimeDir, filename) {
41205
41861
  try {
41206
- const legacyPath = join28(runtimeDir, filename);
41207
- if (existsSync27(legacyPath)) {
41208
- const value = readFileSync14(legacyPath, "utf8").trim();
41862
+ const legacyPath = join30(runtimeDir, filename);
41863
+ if (existsSync29(legacyPath)) {
41864
+ const value = readFileSync15(legacyPath, "utf8").trim();
41209
41865
  return value || null;
41210
41866
  }
41211
41867
  return null;
@@ -41502,11 +42158,27 @@ async function invokeLocalAgentEndpoint(endpoint, invocation) {
41502
42158
  metadata: result.metadata
41503
42159
  };
41504
42160
  }
42161
+ if (!existing && endpoint.transport === "kimi_acp") {
42162
+ const cwd = endpoint.cwd ?? endpoint.projectRoot ?? process.cwd();
42163
+ const sessionId = endpoint.sessionId?.trim() || agentRuntimeId;
42164
+ const result = await invokeKimiAcpAgent({
42165
+ sessionId,
42166
+ cwd,
42167
+ prompt,
42168
+ name: String(endpoint.metadata?.agentName ?? endpoint.metadata?.definitionId ?? "Kimi Code ACP"),
42169
+ timeoutMs: invocation.timeoutMs
42170
+ });
42171
+ return {
42172
+ output: result.output,
42173
+ externalSessionId: result.sessionId,
42174
+ metadata: result.metadata
42175
+ };
42176
+ }
41505
42177
  const projectRoot = endpoint.projectRoot ?? endpoint.cwd;
41506
42178
  const requestedHarness = invocation.execution?.harness;
41507
42179
  const record2 = existing ?? (projectRoot ? {
41508
42180
  definitionId,
41509
- project: basename15(projectRoot),
42181
+ project: basename16(projectRoot),
41510
42182
  projectRoot,
41511
42183
  tmuxSession: String(endpoint.metadata?.tmuxSession ?? `relay-${agentRuntimeId}`),
41512
42184
  cwd: projectRoot,
@@ -41599,8 +42271,8 @@ function shouldDisableGeneratedCodexEndpoint(endpoint) {
41599
42271
  }
41600
42272
 
41601
42273
  // packages/runtime/src/scout-dispatcher.ts
41602
- import { homedir as homedir27 } from "os";
41603
- import { basename as basename16, resolve as resolve13 } from "path";
42274
+ import { homedir as homedir29 } from "os";
42275
+ import { basename as basename17, resolve as resolve13 } from "path";
41604
42276
 
41605
42277
  // packages/runtime/src/a2a-http-endpoint.ts
41606
42278
  import { randomUUID as randomUUID3 } from "crypto";
@@ -41939,7 +42611,8 @@ var directLocalAgentTransports = new Set([
41939
42611
  "codex_app_server",
41940
42612
  "claude_stream_json",
41941
42613
  "pi_rpc",
41942
- "grok_acp"
42614
+ "grok_acp",
42615
+ "kimi_acp"
41943
42616
  ]);
41944
42617
  function isDirectLocalAgentTransport(transport) {
41945
42618
  return typeof transport === "string" && directLocalAgentTransports.has(transport);
@@ -42220,7 +42893,7 @@ function normalizeProjectPath2(value) {
42220
42893
  const trimmed = value?.trim();
42221
42894
  if (!trimmed)
42222
42895
  return;
42223
- const home = process.env.HOME?.trim() || homedir27();
42896
+ const home = process.env.HOME?.trim() || homedir29();
42224
42897
  if (trimmed === "~")
42225
42898
  return home;
42226
42899
  if (trimmed.startsWith("~/"))
@@ -42445,7 +43118,7 @@ function resolveProjectPathTarget(snapshot, projectPath, options) {
42445
43118
  function sessionTargetLabel(endpoint, sessionId) {
42446
43119
  const shortId = sessionId.length > 8 ? sessionId.slice(0, 8) : sessionId;
42447
43120
  const root = endpoint.cwd?.trim() || endpoint.projectRoot?.trim();
42448
- return root ? `${basename16(root)}:${shortId}` : `session:${sessionId}`;
43121
+ return root ? `${basename17(root)}:${shortId}` : `session:${sessionId}`;
42449
43122
  }
42450
43123
  function resolveSessionTarget(snapshot, sessionId, options) {
42451
43124
  const label = sessionRouteLabel(sessionId, options.harness);
@@ -42740,7 +43413,7 @@ class BrokerDeliveryRouter {
42740
43413
  }
42741
43414
 
42742
43415
  // packages/runtime/src/session-alias.ts
42743
- import { basename as basename17 } from "path";
43416
+ import { basename as basename18 } from "path";
42744
43417
  function sessionActorAlias(snapshot, actorId) {
42745
43418
  const actor = snapshot.actors[actorId];
42746
43419
  if (!actor || actor.kind !== "session") {
@@ -42769,7 +43442,7 @@ function isCardlessSessionActor(snapshot, actorId) {
42769
43442
  return endpoint?.metadata?.cardless === true;
42770
43443
  }
42771
43444
  function formatSessionAliasPointer(input) {
42772
- const project = input.projectRoot?.trim() ? basename17(input.projectRoot.trim()) : null;
43445
+ const project = input.projectRoot?.trim() ? basename18(input.projectRoot.trim()) : null;
42773
43446
  const scope = [project, input.harness?.trim()].filter(Boolean).join(", ");
42774
43447
  const target = input.sessionId.length > 24 ? `${input.sessionId.slice(0, 12)}\u2026${input.sessionId.slice(-6)}` : input.sessionId;
42775
43448
  return scope ? `alias ${input.alias} \u2192 ${target} (${scope})` : `alias ${input.alias} \u2192 ${target}`;
@@ -44582,7 +45255,7 @@ class BrokerLocalAgentSyncService {
44582
45255
 
44583
45256
  // packages/runtime/src/iroh-bridge.ts
44584
45257
  import { spawn as spawn7 } from "child_process";
44585
- import { join as join29 } from "path";
45258
+ import { join as join31 } from "path";
44586
45259
  function resolveIrohBridgeBin() {
44587
45260
  const explicit = process.env.OPENSCOUT_IROH_BRIDGE_BIN?.trim();
44588
45261
  return explicit || null;
@@ -44592,7 +45265,7 @@ function resolveIrohBridgeIdentityPath() {
44592
45265
  if (explicit) {
44593
45266
  return explicit;
44594
45267
  }
44595
- return join29(resolveOpenScoutSupportPaths().runtimeDirectory, "mesh", "iroh.key");
45268
+ return join31(resolveOpenScoutSupportPaths().runtimeDirectory, "mesh", "iroh.key");
44596
45269
  }
44597
45270
  function canUseIrohBridge(options = {}) {
44598
45271
  return Boolean(options.bridgeBin?.trim() || resolveIrohBridgeBin());
@@ -45458,9 +46131,9 @@ function createPeerDeliveryWorker(deps, config2 = {}) {
45458
46131
  }
45459
46132
 
45460
46133
  // packages/runtime/src/pairing-session-agents.ts
45461
- import { existsSync as existsSync28, readFileSync as readFileSync15 } from "fs";
45462
- import { basename as basename18, join as join30 } from "path";
45463
- import { homedir as homedir28 } from "os";
46134
+ import { existsSync as existsSync30, readFileSync as readFileSync16 } from "fs";
46135
+ import { basename as basename19, join as join32 } from "path";
46136
+ import { homedir as homedir30 } from "os";
45464
46137
  var DEFAULT_PAIRING_PORT = 43130;
45465
46138
  var PAIRING_CONNECT_TIMEOUT_MS = 1500;
45466
46139
  var PAIRING_REQUEST_TIMEOUT_MS = 1e4;
@@ -45468,19 +46141,19 @@ var DEFAULT_PAIRING_POLL_INTERVAL_MS = 350;
45468
46141
  var DEFAULT_PAIRING_INVOCATION_TIMEOUT_MS = 45000;
45469
46142
  var MAX_SYNTHETIC_OUTPUT_CHARS = 1200;
45470
46143
  function pairingPaths() {
45471
- const home = process.env.HOME?.trim() || homedir28();
45472
- const rootDir = join30(home, ".scout", "pairing");
46144
+ const home = process.env.HOME?.trim() || homedir30();
46145
+ const rootDir = join32(home, ".scout", "pairing");
45473
46146
  return {
45474
- configPath: join30(rootDir, "config.json"),
45475
- runtimeStatePath: join30(rootDir, "runtime.json")
46147
+ configPath: join32(rootDir, "config.json"),
46148
+ runtimeStatePath: join32(rootDir, "runtime.json")
45476
46149
  };
45477
46150
  }
45478
46151
  function readJsonFile4(filePath) {
45479
- if (!existsSync28(filePath)) {
46152
+ if (!existsSync30(filePath)) {
45480
46153
  return null;
45481
46154
  }
45482
46155
  try {
45483
- return JSON.parse(readFileSync15(filePath, "utf8"));
46156
+ return JSON.parse(readFileSync16(filePath, "utf8"));
45484
46157
  } catch {
45485
46158
  return null;
45486
46159
  }
@@ -45490,7 +46163,7 @@ function resolvePairingBridgePort(options = {}) {
45490
46163
  return options.port;
45491
46164
  }
45492
46165
  const { configPath, runtimeStatePath } = pairingPaths();
45493
- const configExists = existsSync28(configPath);
46166
+ const configExists = existsSync30(configPath);
45494
46167
  const runtimeSnapshot = readJsonFile4(runtimeStatePath);
45495
46168
  if (!configExists && !runtimeSnapshot) {
45496
46169
  return null;
@@ -45647,7 +46320,7 @@ function shortPairingSessionId(sessionId) {
45647
46320
  }
45648
46321
  function pairingProjectLabel(session) {
45649
46322
  const cwd = session.cwd?.trim();
45650
- return cwd ? basename18(cwd) : null;
46323
+ return cwd ? basename19(cwd) : null;
45651
46324
  }
45652
46325
  function pairingDisplayName(session, shortId) {
45653
46326
  const explicit = session.name?.trim();
@@ -45678,6 +46351,9 @@ function pairingHarness(adapterType) {
45678
46351
  if (normalized === "grok-acp" || normalized.includes("grok") && normalized.includes("acp")) {
45679
46352
  return "grok-acp";
45680
46353
  }
46354
+ if (normalized === "kimi-acp" || normalized.includes("kimi")) {
46355
+ return "kimi";
46356
+ }
45681
46357
  return "bridge";
45682
46358
  }
45683
46359
  function pairingEndpointState(status) {
@@ -46030,9 +46706,9 @@ async function invokePairingSessionEndpoint(endpoint, invocation, options = {})
46030
46706
  }
46031
46707
 
46032
46708
  // packages/runtime/src/sqlite-store.ts
46033
- import { createHash as createHash3 } from "crypto";
46709
+ import { createHash as createHash4 } from "crypto";
46034
46710
  import { mkdirSync as mkdirSync4 } from "fs";
46035
- import { dirname as dirname18 } from "path";
46711
+ import { dirname as dirname19 } from "path";
46036
46712
 
46037
46713
  // node_modules/.bun/drizzle-orm@0.45.2+e80f9ee8788b3855/node_modules/drizzle-orm/entity.js
46038
46714
  var entityKind = Symbol.for("drizzle:entityKind");
@@ -46633,7 +47309,7 @@ function sql(strings, ...params) {
46633
47309
  return new SQL([new StringChunk(str)]);
46634
47310
  }
46635
47311
  sql2.raw = raw;
46636
- function join31(chunks, separator) {
47312
+ function join33(chunks, separator) {
46637
47313
  const result = [];
46638
47314
  for (const [i, chunk] of chunks.entries()) {
46639
47315
  if (i > 0 && separator !== undefined) {
@@ -46643,7 +47319,7 @@ function sql(strings, ...params) {
46643
47319
  }
46644
47320
  return new SQL(result);
46645
47321
  }
46646
- sql2.join = join31;
47322
+ sql2.join = join33;
46647
47323
  function identifier(value) {
46648
47324
  return new Name(value);
46649
47325
  }
@@ -48950,7 +49626,7 @@ class SQLiteSelectQueryBuilderBase extends TypedQueryBuilder {
48950
49626
  const tableName = getTableLikeName(table);
48951
49627
  for (const item of extractUsedTable(table))
48952
49628
  this.usedTables.add(item);
48953
- if (typeof tableName === "string" && this.config.joins?.some((join31) => join31.alias === tableName)) {
49629
+ if (typeof tableName === "string" && this.config.joins?.some((join33) => join33.alias === tableName)) {
48954
49630
  throw new Error(`Alias "${tableName}" is already used in this query`);
48955
49631
  }
48956
49632
  if (!this.isPartialSelect) {
@@ -49364,7 +50040,7 @@ class SQLiteUpdateBase extends QueryPromise {
49364
50040
  createJoin(joinType) {
49365
50041
  return (table, on) => {
49366
50042
  const tableName = getTableLikeName(table);
49367
- if (typeof tableName === "string" && this.config.joins.some((join31) => join31.alias === tableName)) {
50043
+ if (typeof tableName === "string" && this.config.joins.some((join33) => join33.alias === tableName)) {
49368
50044
  throw new Error(`Alias "${tableName}" is already used in this query`);
49369
50045
  }
49370
50046
  if (typeof on === "function") {
@@ -50746,8 +51422,8 @@ class NodeSqliteDatabaseAdapter {
50746
51422
  }
50747
51423
 
50748
51424
  // packages/runtime/src/control-plane-migrations.ts
50749
- import { existsSync as existsSync29 } from "fs";
50750
- import { join as join31 } from "path";
51425
+ import { existsSync as existsSync31 } from "fs";
51426
+ import { join as join33 } from "path";
50751
51427
  import { fileURLToPath as fileURLToPath7 } from "url";
50752
51428
 
50753
51429
  // node_modules/.bun/drizzle-orm@0.45.2+e80f9ee8788b3855/node_modules/drizzle-orm/migrator.js
@@ -51571,7 +52247,7 @@ function resolveControlPlaneDrizzleMigrationsFolder() {
51571
52247
  const candidates = ["../drizzle", "./drizzle"];
51572
52248
  for (const candidate of candidates) {
51573
52249
  const folder = fileURLToPath7(new URL(candidate, import.meta.url));
51574
- if (existsSync29(join31(folder, "meta", "_journal.json"))) {
52250
+ if (existsSync31(join33(folder, "meta", "_journal.json"))) {
51575
52251
  return folder;
51576
52252
  }
51577
52253
  }
@@ -51613,8 +52289,8 @@ function controlPlaneDatabaseFilename(database) {
51613
52289
  }
51614
52290
  function applyControlPlaneDrizzleMigrations(database) {
51615
52291
  const migrationsFolder = resolveControlPlaneDrizzleMigrationsFolder();
51616
- const journalPath = join31(migrationsFolder, "meta", "_journal.json");
51617
- if (!existsSync29(journalPath)) {
52292
+ const journalPath = join33(migrationsFolder, "meta", "_journal.json");
52293
+ if (!existsSync31(journalPath)) {
51618
52294
  return false;
51619
52295
  }
51620
52296
  const migrations = readMigrationFiles({ migrationsFolder });
@@ -51770,15 +52446,15 @@ class Conversations {
51770
52446
  }
51771
52447
 
51772
52448
  // packages/runtime/src/budget-observations.ts
51773
- import { createHash as createHash2 } from "crypto";
52449
+ import { createHash as createHash3 } from "crypto";
51774
52450
  var QUOTA_HISTORY_BUCKET_MS = 60 * 60 * 1000;
51775
52451
  function stableHash(value) {
51776
- return createHash2("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 24);
52452
+ return createHash3("sha256").update(JSON.stringify(value)).digest("hex").slice(0, 24);
51777
52453
  }
51778
52454
  function metadataRecord7(value) {
51779
52455
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
51780
52456
  }
51781
- function stringValue9(value) {
52457
+ function stringValue10(value) {
51782
52458
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
51783
52459
  }
51784
52460
  function numberValue6(value) {
@@ -51828,7 +52504,7 @@ function budgetObservationsFromEndpoint(endpoint, now = Date.now()) {
51828
52504
  harness: endpoint.harness,
51829
52505
  transport: endpoint.transport,
51830
52506
  adapterType: endpoint.transport,
51831
- model: stringValue9(metadata?.model),
52507
+ model: stringValue10(metadata?.model),
51832
52508
  sessionId: endpoint.sessionId,
51833
52509
  projectRoot: endpoint.projectRoot,
51834
52510
  cwd: endpoint.cwd,
@@ -51924,7 +52600,7 @@ function normalizeTimestampMs(value) {
51924
52600
  return epochMs(value);
51925
52601
  }
51926
52602
  function stableHash2(value, length = 20) {
51927
- return createHash3("sha256").update(value).digest("hex").slice(0, length);
52603
+ return createHash4("sha256").update(value).digest("hex").slice(0, length);
51928
52604
  }
51929
52605
  function metadataStringValue6(metadata, key) {
51930
52606
  const value = metadata?.[key];
@@ -51960,29 +52636,29 @@ function isSqliteConstraintError(error48) {
51960
52636
  function metadataValue2(metadata, key) {
51961
52637
  return metadata?.[key];
51962
52638
  }
51963
- function stringValue10(metadata, key) {
52639
+ function stringValue11(metadata, key) {
51964
52640
  const value = metadataValue2(metadata, key);
51965
52641
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
51966
52642
  }
51967
52643
  function invocationStringValue2(invocation, key) {
51968
- const contextValue = stringValue10(invocation.context, key);
52644
+ const contextValue = stringValue11(invocation.context, key);
51969
52645
  if (contextValue) {
51970
52646
  return contextValue;
51971
52647
  }
51972
52648
  const nestedContext = metadataValue2(invocation.context, "collaboration");
51973
52649
  if (nestedContext && typeof nestedContext === "object" && !Array.isArray(nestedContext)) {
51974
- const nestedValue = stringValue10(nestedContext, key);
52650
+ const nestedValue = stringValue11(nestedContext, key);
51975
52651
  if (nestedValue) {
51976
52652
  return nestedValue;
51977
52653
  }
51978
52654
  }
51979
- const metadataEntry = stringValue10(invocation.metadata, key);
52655
+ const metadataEntry = stringValue11(invocation.metadata, key);
51980
52656
  if (metadataEntry) {
51981
52657
  return metadataEntry;
51982
52658
  }
51983
52659
  const nestedMetadata = metadataValue2(invocation.metadata, "collaboration");
51984
52660
  if (nestedMetadata && typeof nestedMetadata === "object" && !Array.isArray(nestedMetadata)) {
51985
- return stringValue10(nestedMetadata, key);
52661
+ return stringValue11(nestedMetadata, key);
51986
52662
  }
51987
52663
  return;
51988
52664
  }
@@ -52300,7 +52976,7 @@ class SQLiteControlPlaneStore {
52300
52976
  flushPendingEventsTimer = null;
52301
52977
  conversationsApi = null;
52302
52978
  constructor(dbPath) {
52303
- mkdirSync4(dirname18(dbPath), { recursive: true });
52979
+ mkdirSync4(dirname19(dbPath), { recursive: true });
52304
52980
  this.db = openControlPlaneSqliteDatabase(dbPath, { create: true });
52305
52981
  configureControlPlaneDatabase(this.db);
52306
52982
  migrateControlPlaneDatabaseSchema(this.db);
@@ -54500,6 +55176,21 @@ class RecoverableSQLiteProjection {
54500
55176
  this.journal = journal;
54501
55177
  this.options = options;
54502
55178
  }
55179
+ statusSnapshot() {
55180
+ if (this.options.disabled) {
55181
+ return {
55182
+ state: "disabled",
55183
+ detail: "SQLite projection is disabled by configuration."
55184
+ };
55185
+ }
55186
+ if (this.store) {
55187
+ return { state: "ready", detail: null };
55188
+ }
55189
+ return {
55190
+ state: "degraded",
55191
+ detail: this.lastUnavailableReason ?? (this.closed ? "SQLite projection is closed." : "SQLite projection is not ready.")
55192
+ };
55193
+ }
54503
55194
  warm() {
54504
55195
  this.enqueue(async () => {
54505
55196
  await this.ensureStore();
@@ -54996,8 +55687,8 @@ class ThreadEventPlane {
54996
55687
  }
54997
55688
 
54998
55689
  // packages/runtime/src/build-info.ts
54999
- import { readFileSync as readFileSync16 } from "fs";
55000
- import { dirname as dirname19, join as join32 } from "path";
55690
+ import { readFileSync as readFileSync17 } from "fs";
55691
+ import { dirname as dirname20, join as join34 } from "path";
55001
55692
  import { fileURLToPath as fileURLToPath8 } from "url";
55002
55693
  var cachedBuildIdentity = null;
55003
55694
  function envString(...names) {
@@ -55011,8 +55702,8 @@ function envString(...names) {
55011
55702
  }
55012
55703
  function readRuntimePackageJson() {
55013
55704
  try {
55014
- const packagePath = join32(dirname19(fileURLToPath8(import.meta.url)), "..", "package.json");
55015
- const parsed = JSON.parse(readFileSync16(packagePath, "utf8"));
55705
+ const packagePath = join34(dirname20(fileURLToPath8(import.meta.url)), "..", "package.json");
55706
+ const parsed = JSON.parse(readFileSync17(packagePath, "utf8"));
55016
55707
  return {
55017
55708
  name: typeof parsed.name === "string" && parsed.name.trim() ? parsed.name.trim() : null,
55018
55709
  version: typeof parsed.version === "string" && parsed.version.trim() ? parsed.version.trim() : null
@@ -55625,6 +56316,7 @@ function createBrokerCoreService(deps) {
55625
56316
  meshId: deps.meshId,
55626
56317
  build: deps.build ?? loadOpenScoutRuntimeBuildIdentity(),
55627
56318
  services: deps.readChildServices?.(),
56319
+ ...deps.readProjectionStatus ? { projection: deps.readProjectionStatus() } : {},
55628
56320
  counts: {
55629
56321
  nodes: Object.keys(snapshot.nodes).length,
55630
56322
  actors: Object.keys(snapshot.actors).length,
@@ -55687,9 +56379,9 @@ function createBrokerCoreService(deps) {
55687
56379
  }
55688
56380
 
55689
56381
  // packages/runtime/src/mesh-rendezvous.ts
55690
- import { existsSync as existsSync30, readFileSync as readFileSync17 } from "fs";
55691
- import { homedir as homedir29 } from "os";
55692
- import { join as join33 } from "path";
56382
+ import { existsSync as existsSync32, readFileSync as readFileSync18 } from "fs";
56383
+ import { homedir as homedir31 } from "os";
56384
+ import { join as join35 } from "path";
55693
56385
  var DEFAULT_RENDEZVOUS_TTL_MS = 60000;
55694
56386
  var DEFAULT_RENDEZVOUS_INTERVAL_MS = 30000;
55695
56387
  function resolveMeshRendezvousPublishConfig(env = process.env, options = {}) {
@@ -55789,20 +56481,20 @@ function startMeshRendezvousPublisher(node, options) {
55789
56481
  };
55790
56482
  }
55791
56483
  function readMobilePairingMeshEntrypoint(env = process.env, now = Date.now()) {
55792
- const runtimeStatePath = env.OPENSCOUT_PAIRING_RUNTIME_STATE_PATH ?? join33(env.HOME ?? homedir29(), ".scout", "pairing", "runtime.json");
55793
- if (!existsSync30(runtimeStatePath)) {
56484
+ const runtimeStatePath = env.OPENSCOUT_PAIRING_RUNTIME_STATE_PATH ?? join35(env.HOME ?? homedir31(), ".scout", "pairing", "runtime.json");
56485
+ if (!existsSync32(runtimeStatePath)) {
55794
56486
  return;
55795
56487
  }
55796
56488
  try {
55797
- return mobilePairingMeshEntrypointFromSnapshot(JSON.parse(readFileSync17(runtimeStatePath, "utf8")), now);
56489
+ return mobilePairingMeshEntrypointFromSnapshot(JSON.parse(readFileSync18(runtimeStatePath, "utf8")), now);
55798
56490
  } catch {
55799
56491
  return;
55800
56492
  }
55801
56493
  }
55802
56494
  function mobilePairingMeshEntrypointFromSnapshot(input, now = Date.now()) {
55803
- if (!isRecord7(input))
56495
+ if (!isRecord8(input))
55804
56496
  return;
55805
- const pairing = isRecord7(input["pairing"]) ? input["pairing"] : undefined;
56497
+ const pairing = isRecord8(input["pairing"]) ? input["pairing"] : undefined;
55806
56498
  if (!pairing)
55807
56499
  return;
55808
56500
  const relay = readString5(pairing["relay"]);
@@ -55876,7 +56568,7 @@ function readFallbackRelays(pairing) {
55876
56568
  }
55877
56569
  try {
55878
56570
  const parsed = JSON.parse(qrValue);
55879
- return isRecord7(parsed) ? readStringArray(parsed["fallbackRelays"]) : [];
56571
+ return isRecord8(parsed) ? readStringArray(parsed["fallbackRelays"]) : [];
55880
56572
  } catch {
55881
56573
  return [];
55882
56574
  }
@@ -55890,7 +56582,7 @@ function readNumber5(value) {
55890
56582
  function readStringArray(value) {
55891
56583
  return Array.isArray(value) ? value.map(readString5).filter((entry) => Boolean(entry)) : [];
55892
56584
  }
55893
- function isRecord7(value) {
56585
+ function isRecord8(value) {
55894
56586
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
55895
56587
  }
55896
56588
  function isPublicKeyHex(value) {
@@ -55899,10 +56591,10 @@ function isPublicKeyHex(value) {
55899
56591
 
55900
56592
  // packages/runtime/src/mobile-push.ts
55901
56593
  import { Database as Database2 } from "bun:sqlite";
55902
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync18 } from "fs";
56594
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync19 } from "fs";
55903
56595
  import { connect as connectHttp2 } from "http2";
55904
56596
  import { createPrivateKey, sign as signWithKey } from "crypto";
55905
- import { dirname as dirname20, join as join34 } from "path";
56597
+ import { dirname as dirname21, join as join36 } from "path";
55906
56598
  var MOBILE_PUSH_SCHEMA = `
55907
56599
  CREATE TABLE IF NOT EXISTS mobile_push_registrations (
55908
56600
  id TEXT PRIMARY KEY,
@@ -55930,7 +56622,7 @@ var dbHandle = null;
55930
56622
  var dbPath = null;
55931
56623
  var cachedApnsJwt = null;
55932
56624
  function resolveControlPlaneDbPath() {
55933
- return join34(resolveOpenScoutSupportPaths().controlHome, "control-plane.sqlite");
56625
+ return join36(resolveOpenScoutSupportPaths().controlHome, "control-plane.sqlite");
55934
56626
  }
55935
56627
  function ensureMobilePushSchema(database) {
55936
56628
  database.exec("PRAGMA busy_timeout = 5000;");
@@ -55944,7 +56636,7 @@ function writeDb() {
55944
56636
  dbHandle = null;
55945
56637
  }
55946
56638
  if (!dbHandle) {
55947
- mkdirSync5(dirname20(nextPath), { recursive: true });
56639
+ mkdirSync5(dirname21(nextPath), { recursive: true });
55948
56640
  dbHandle = new Database2(nextPath, { create: true });
55949
56641
  dbPath = nextPath;
55950
56642
  ensureMobilePushSchema(dbHandle);
@@ -56135,7 +56827,7 @@ function loadApnsCredentials() {
56135
56827
  privateKeyPem = Buffer.from(inlineBase64, "base64").toString("utf8");
56136
56828
  }
56137
56829
  if (!privateKeyPem && path) {
56138
- privateKeyPem = readFileSync18(path, "utf8");
56830
+ privateKeyPem = readFileSync19(path, "utf8");
56139
56831
  }
56140
56832
  if (!teamId || !keyId || !privateKeyPem) {
56141
56833
  return null;
@@ -56314,8 +57006,8 @@ async function broadcastApnsAlertToActiveMobileDevices(alert) {
56314
57006
 
56315
57007
  // packages/runtime/src/repo-watch/index.ts
56316
57008
  import { lstat } from "fs/promises";
56317
- import { homedir as homedir30 } from "os";
56318
- import { basename as basename19, dirname as dirname21, isAbsolute as isAbsolute3, relative as relative7, resolve as resolve14 } from "path";
57009
+ import { homedir as homedir32 } from "os";
57010
+ import { basename as basename20, dirname as dirname22, isAbsolute as isAbsolute3, relative as relative7, resolve as resolve14 } from "path";
56319
57011
  var DEFAULT_CACHE_TTL_MS = 2500;
56320
57012
  var DEFAULT_MAX_ROOTS = 8;
56321
57013
  var DEFAULT_MAX_WORKTREES = 4;
@@ -56323,31 +57015,31 @@ var DEFAULT_MAX_FILES_PER_WORKTREE = 12;
56323
57015
  var DEFAULT_SCAN_BUDGET_MS = 4000;
56324
57016
  var cachedSnapshot = null;
56325
57017
  var lastUsefulSnapshot = null;
56326
- function readPositiveIntEnv9(name, fallback) {
57018
+ function readPositiveIntEnv10(name, fallback) {
56327
57019
  const raw = Number.parseInt(process.env[name] ?? "", 10);
56328
57020
  return Number.isFinite(raw) && raw > 0 ? raw : fallback;
56329
57021
  }
56330
- function stringValue11(value) {
57022
+ function stringValue12(value) {
56331
57023
  return typeof value === "string" && value.trim() ? value.trim() : null;
56332
57024
  }
56333
57025
  function metadataString4(metadata, key) {
56334
57026
  if (!metadata)
56335
57027
  return null;
56336
- return stringValue11(metadata[key]);
57028
+ return stringValue12(metadata[key]);
56337
57029
  }
56338
57030
  function expandHome(input) {
56339
57031
  if (input === "~")
56340
- return homedir30();
57032
+ return homedir32();
56341
57033
  if (input.startsWith("~/"))
56342
- return resolve14(homedir30(), input.slice(2));
57034
+ return resolve14(homedir32(), input.slice(2));
56343
57035
  return input;
56344
57036
  }
56345
57037
  function normalizePath2(input) {
56346
57038
  return resolve14(expandHome(input.trim()));
56347
57039
  }
56348
57040
  function isBroadLocalRootPath(path) {
56349
- const home = normalizePath2(homedir30());
56350
- return path === home || path === resolve14(home, "dev") || path === resolve14(home, "Developer") || path === dirname21(home) || path === "/";
57041
+ const home = normalizePath2(homedir32());
57042
+ return path === home || path === resolve14(home, "dev") || path === resolve14(home, "Developer") || path === dirname22(home) || path === "/";
56351
57043
  }
56352
57044
  function isTempLocalPath(path) {
56353
57045
  const roots = [
@@ -56463,7 +57155,7 @@ async function existingDirectoryForPath(path) {
56463
57155
  if (stats.isDirectory())
56464
57156
  return path;
56465
57157
  if (stats.isFile())
56466
- return dirname21(path);
57158
+ return dirname22(path);
56467
57159
  return null;
56468
57160
  } catch {
56469
57161
  return null;
@@ -56896,7 +57588,7 @@ async function scanWorktree(worktree, hints, git2, now, options) {
56896
57588
  return {
56897
57589
  id: `worktree:${hashId2(worktree.path)}`,
56898
57590
  path: worktree.path,
56899
- name: basename19(worktree.path) || worktree.path,
57591
+ name: basename20(worktree.path) || worktree.path,
56900
57592
  isBare: worktree.bare,
56901
57593
  branch,
56902
57594
  status: parsed.status,
@@ -56971,7 +57663,7 @@ async function scanProject(root, git2, now, maxWorktrees, options) {
56971
57663
  return {
56972
57664
  project: {
56973
57665
  id: `repo:${hashId2(root.commonGitDir)}`,
56974
- name: basename19(rootPath) || basename19(root.commonGitDir) || rootPath,
57666
+ name: basename20(rootPath) || basename20(root.commonGitDir) || rootPath,
56975
57667
  root: rootPath,
56976
57668
  commonGitDir: root.commonGitDir,
56977
57669
  attention,
@@ -57018,7 +57710,7 @@ function worktreeFromNative(worktree, hints) {
57018
57710
  return {
57019
57711
  id: `worktree:${hashId2(worktree.path)}`,
57020
57712
  path: worktree.path,
57021
- name: worktree.name || basename19(worktree.path) || worktree.path,
57713
+ name: worktree.name || basename20(worktree.path) || worktree.path,
57022
57714
  isBare: worktree.isBare,
57023
57715
  branch,
57024
57716
  status: worktree.status,
@@ -57051,7 +57743,7 @@ function projectsFromNativeScan(response, hints) {
57051
57743
  const rootPath = worktrees[0]?.path ?? rawProject.root;
57052
57744
  projects.push({
57053
57745
  id: `repo:${hashId2(rawProject.commonGitDir)}`,
57054
- name: basename19(rootPath) || basename19(rawProject.commonGitDir) || rootPath,
57746
+ name: basename20(rootPath) || basename20(rawProject.commonGitDir) || rootPath,
57055
57747
  root: rootPath,
57056
57748
  commonGitDir: rawProject.commonGitDir,
57057
57749
  attention,
@@ -57176,10 +57868,10 @@ async function scanWithTypeScriptRepoWatch(options) {
57176
57868
  async function getRepoWatchSnapshot(options = {}) {
57177
57869
  const now = options.now?.() ?? Date.now();
57178
57870
  const cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
57179
- const maxRoots = options.maxRoots ?? readPositiveIntEnv9("OPENSCOUT_REPO_WATCH_MAX_ROOTS", DEFAULT_MAX_ROOTS);
57180
- const maxWorktrees = options.maxWorktrees ?? readPositiveIntEnv9("OPENSCOUT_REPO_WATCH_MAX_WORKTREES", DEFAULT_MAX_WORKTREES);
57181
- const maxFiles = options.maxFilesPerWorktree ?? readPositiveIntEnv9("OPENSCOUT_REPO_WATCH_MAX_FILES_PER_WORKTREE", DEFAULT_MAX_FILES_PER_WORKTREE);
57182
- const scanBudgetMs = options.scanBudgetMs ?? readPositiveIntEnv9("OPENSCOUT_REPO_WATCH_SCAN_BUDGET_MS", DEFAULT_SCAN_BUDGET_MS);
57871
+ const maxRoots = options.maxRoots ?? readPositiveIntEnv10("OPENSCOUT_REPO_WATCH_MAX_ROOTS", DEFAULT_MAX_ROOTS);
57872
+ const maxWorktrees = options.maxWorktrees ?? readPositiveIntEnv10("OPENSCOUT_REPO_WATCH_MAX_WORKTREES", DEFAULT_MAX_WORKTREES);
57873
+ const maxFiles = options.maxFilesPerWorktree ?? readPositiveIntEnv10("OPENSCOUT_REPO_WATCH_MAX_FILES_PER_WORKTREE", DEFAULT_MAX_FILES_PER_WORKTREE);
57874
+ const scanBudgetMs = options.scanBudgetMs ?? readPositiveIntEnv10("OPENSCOUT_REPO_WATCH_SCAN_BUDGET_MS", DEFAULT_SCAN_BUDGET_MS);
57183
57875
  const deadlineMs = scanBudgetMs > 0 ? Date.now() + scanBudgetMs : null;
57184
57876
  const git2 = options.git ?? defaultGit;
57185
57877
  const hints = normalizeHints([
@@ -57389,8 +58081,8 @@ function repoWatchHintsFromTailDiscovery(discovery) {
57389
58081
 
57390
58082
  // packages/runtime/src/broker-web-control-service.ts
57391
58083
  import { spawn as spawn8 } from "child_process";
57392
- import { existsSync as existsSync31, mkdirSync as mkdirSync6, openSync as openSync7 } from "fs";
57393
- import { dirname as dirname22, join as join35, resolve as resolve15 } from "path";
58084
+ import { existsSync as existsSync33, mkdirSync as mkdirSync6, openSync as openSync7 } from "fs";
58085
+ import { dirname as dirname23, join as join37, resolve as resolve15 } from "path";
57394
58086
  import { fileURLToPath as fileURLToPath9 } from "url";
57395
58087
  var DEFAULT_WEB_PROCESS_NAME = "scout-web";
57396
58088
  var DEFAULT_START_POLL_TIMEOUT_MS = 15000;
@@ -57492,7 +58184,7 @@ class BrokerWebControlService {
57492
58184
  this.trustedHosts = new Set([...options.trustedHosts ?? []].map((host) => host.trim().replace(/\.$/, "").toLowerCase()).filter(Boolean));
57493
58185
  this.tailnetWebHosts = (options.tailnetWebHosts ?? []).map((host) => host.trim()).filter(Boolean);
57494
58186
  this.webProcessName = options.webProcessName ?? DEFAULT_WEB_PROCESS_NAME;
57495
- this.moduleDirectory = options.moduleDirectory ?? dirname22(fileURLToPath9(import.meta.url));
58187
+ this.moduleDirectory = options.moduleDirectory ?? dirname23(fileURLToPath9(import.meta.url));
57496
58188
  this.cwd = options.cwd ?? (() => process.cwd());
57497
58189
  this.sleep = options.sleep ?? ((ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms)));
57498
58190
  this.startPollTimeoutMs = options.startPollTimeoutMs ?? DEFAULT_START_POLL_TIMEOUT_MS;
@@ -57627,7 +58319,7 @@ class BrokerWebControlService {
57627
58319
  return this.options.resolveEntry();
57628
58320
  }
57629
58321
  const explicit = this.env.OPENSCOUT_WEB_SERVER_ENTRY?.trim();
57630
- if (explicit && existsSync31(explicit)) {
58322
+ if (explicit && existsSync33(explicit)) {
57631
58323
  return explicit;
57632
58324
  }
57633
58325
  const repoRoot = this.resolveRepoRoot();
@@ -57641,7 +58333,7 @@ class BrokerWebControlService {
57641
58333
  resolve15(this.moduleDirectory, "..", "..", "scout-control-plane-web.mjs"),
57642
58334
  resolve15(this.moduleDirectory, "..", "..", "scout-web-server.mjs")
57643
58335
  ];
57644
- return candidates.find((candidate) => existsSync31(candidate)) ?? null;
58336
+ return candidates.find((candidate) => existsSync33(candidate)) ?? null;
57645
58337
  }
57646
58338
  resolveRepoRoot() {
57647
58339
  return resolveOpenScoutRepoRoot({
@@ -57660,9 +58352,9 @@ class BrokerWebControlService {
57660
58352
  return this.options.resolveLogPath();
57661
58353
  }
57662
58354
  const config2 = resolveBrokerServiceConfig();
57663
- const logDirectory = join35(config2.supportDirectory, "logs", "web");
58355
+ const logDirectory = join37(config2.supportDirectory, "logs", "web");
57664
58356
  mkdirSync6(logDirectory, { recursive: true });
57665
- return join35(logDirectory, "supervised-web.log");
58357
+ return join37(logDirectory, "supervised-web.log");
57666
58358
  }
57667
58359
  spawnWebServer(context = {}) {
57668
58360
  const entry = this.resolveEntry();
@@ -58276,7 +58968,7 @@ class BrokerA2AService {
58276
58968
 
58277
58969
  // packages/runtime/src/broker-capability-matrix-service.ts
58278
58970
  import { mkdir as mkdir9, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
58279
- import { dirname as dirname23, join as join38 } from "path";
58971
+ import { dirname as dirname24, join as join40 } from "path";
58280
58972
 
58281
58973
  // packages/runtime/src/capability-matrix.ts
58282
58974
  function buildRuntimeCapabilityMatrixSnapshot(options) {
@@ -58736,10 +59428,10 @@ function errorMessage5(error48) {
58736
59428
 
58737
59429
  // packages/runtime/src/mcp-server-catalog.ts
58738
59430
  import { readFile as readFile9 } from "fs/promises";
58739
- import { join as join36 } from "path";
59431
+ import { join as join38 } from "path";
58740
59432
  var RUNTIME_MCP_SERVER_CATALOG_FILE = "mcp-servers.json";
58741
59433
  function resolveRuntimeMcpServerCatalogPath(path) {
58742
- return path ?? join36(resolveOpenScoutSupportPaths().catalogDirectory, RUNTIME_MCP_SERVER_CATALOG_FILE);
59434
+ return path ?? join38(resolveOpenScoutSupportPaths().catalogDirectory, RUNTIME_MCP_SERVER_CATALOG_FILE);
58743
59435
  }
58744
59436
  async function loadRuntimeMcpServerCatalog(options = {}) {
58745
59437
  const path = resolveRuntimeMcpServerCatalogPath(options.path);
@@ -58822,10 +59514,10 @@ function isNotFoundError(error48) {
58822
59514
 
58823
59515
  // packages/runtime/src/model-catalog.ts
58824
59516
  import { readFile as readFile10 } from "fs/promises";
58825
- import { join as join37 } from "path";
59517
+ import { join as join39 } from "path";
58826
59518
  var RUNTIME_MODEL_CATALOG_FILE = "model-catalog.json";
58827
59519
  function resolveRuntimeModelCatalogPath(path) {
58828
- return path ?? join37(resolveOpenScoutSupportPaths().catalogDirectory, RUNTIME_MODEL_CATALOG_FILE);
59520
+ return path ?? join39(resolveOpenScoutSupportPaths().catalogDirectory, RUNTIME_MODEL_CATALOG_FILE);
58829
59521
  }
58830
59522
  async function loadRuntimeModelCatalogInput(options = {}) {
58831
59523
  const path = resolveRuntimeModelCatalogPath(options.path);
@@ -58912,7 +59604,7 @@ function resolveCapabilityMatrixCacheTtlMs(env = process.env) {
58912
59604
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_CAPABILITY_MATRIX_CACHE_TTL_MS;
58913
59605
  }
58914
59606
  function defaultCapabilityMatrixCachePath() {
58915
- return join38(resolveOpenScoutSupportPaths().runtimeDirectory, "capability-matrix.json");
59607
+ return join40(resolveOpenScoutSupportPaths().runtimeDirectory, "capability-matrix.json");
58916
59608
  }
58917
59609
  function isCapabilityMatrixSnapshot(value) {
58918
59610
  return Boolean(value) && typeof value === "object" && typeof value.generatedAt === "number" && Array.isArray(value.sources) && Array.isArray(value.capabilities) && Array.isArray(value.warnings);
@@ -59003,7 +59695,7 @@ class BrokerCapabilityMatrixService {
59003
59695
  async writePersisted(snapshot) {
59004
59696
  try {
59005
59697
  const path = this.cachePath();
59006
- await (this.options.ensureDirectory ?? mkdir9)(dirname23(path), { recursive: true });
59698
+ await (this.options.ensureDirectory ?? mkdir9)(dirname24(path), { recursive: true });
59007
59699
  await (this.options.writeTextFile ?? writeFile9)(path, `${JSON.stringify(snapshot, null, 2)}
59008
59700
  `, "utf8");
59009
59701
  } catch {}
@@ -59011,7 +59703,7 @@ class BrokerCapabilityMatrixService {
59011
59703
  }
59012
59704
 
59013
59705
  // packages/runtime/src/broker-managed-session-helpers.ts
59014
- import { basename as basename20, resolve as resolve16 } from "path";
59706
+ import { basename as basename21, resolve as resolve16 } from "path";
59015
59707
  function localAgentMetadataSource(metadata) {
59016
59708
  const source = metadata?.source;
59017
59709
  return typeof source === "string" && source.trim().length > 0 ? source : null;
@@ -59127,11 +59819,11 @@ function updateManagedSessionAgent(agent, input) {
59127
59819
  };
59128
59820
  }
59129
59821
  function managedLocalSessionDefaultDisplayName(input) {
59130
- const projectName = basename20(input.projectRoot ?? input.cwd) || input.cwd;
59822
+ const projectName = basename21(input.projectRoot ?? input.cwd) || input.cwd;
59131
59823
  return input.transport === "codex_app_server" ? `Codex (${projectName})` : `Claude (${projectName})`;
59132
59824
  }
59133
59825
  function suggestedManagedLocalSessionSelector(input) {
59134
- const projectName = normalizeAgentSelectorSegment(basename20(input.projectRoot ?? input.cwd) || "session") || "session";
59826
+ const projectName = normalizeAgentSelectorSegment(basename21(input.projectRoot ?? input.cwd) || "session") || "session";
59135
59827
  const prefix = input.transport === "codex_app_server" ? "codex" : "claude";
59136
59828
  return `@${prefix}-${projectName}`;
59137
59829
  }
@@ -59169,7 +59861,7 @@ function buildManagedLocalSessionAgent(input) {
59169
59861
  function buildManagedLocalSessionPairingEndpointBinding(input) {
59170
59862
  const projectRoot = resolve16(input.projectRoot ?? input.cwd);
59171
59863
  const cwd = resolve16(input.cwd);
59172
- const projectName = basename20(projectRoot) || projectRoot;
59864
+ const projectName = basename21(projectRoot) || projectRoot;
59173
59865
  const definitionId = input.definitionId?.trim() || selectorHandle(input.selector ?? input.agentId);
59174
59866
  const base = buildManagedPairingEndpointBinding({
59175
59867
  agentId: input.agentId,
@@ -60221,8 +60913,23 @@ function localInvocationTargetIdentity(targetId, agent, actor) {
60221
60913
  }
60222
60914
 
60223
60915
  // packages/runtime/src/broker-cardless-session.ts
60224
- import { basename as basename21, resolve as resolve18 } from "path";
60916
+ import { basename as basename22, resolve as resolve18 } from "path";
60225
60917
  var CARDLESS_SESSION_SOURCE = "scout-cardless-session";
60918
+ function resolveCardlessSessionSpawnTarget(requestedHarness, options = {}) {
60919
+ const defaults = resolveHarnessSessionDefaults(requestedHarness ?? "claude", {
60920
+ transportOverride: options.claudeTransport
60921
+ });
60922
+ if (defaults && isCardlessSessionSpawnTransport(defaults.transport)) {
60923
+ return {
60924
+ harness: defaults.harness,
60925
+ transport: defaults.transport
60926
+ };
60927
+ }
60928
+ throw new Error(`cannot auto-spawn a session for harness "${requestedHarness}"; ` + `the harness catalog has no supported session defaults. ` + `Bring a worker online first (scout up) to use other harnesses.`);
60929
+ }
60930
+ function isCardlessSessionSpawnTransport(value) {
60931
+ return value === "claude_stream_json" || value === "codex_app_server" || value === "grok_acp" || value === "kimi_acp" || value === "tmux";
60932
+ }
60226
60933
  function resolveCardlessSessionPath(path) {
60227
60934
  return resolve18(expandHomePath(path));
60228
60935
  }
@@ -60260,7 +60967,7 @@ function cardlessSessionDisplayName(input) {
60260
60967
  }
60261
60968
  function buildCardlessSessionActor(input) {
60262
60969
  const projectRoot = resolveCardlessSessionPath(input.projectRoot ?? input.cwd);
60263
- const projectName = basename21(projectRoot) || projectRoot;
60970
+ const projectName = basename22(projectRoot) || projectRoot;
60264
60971
  const shortId = input.sessionId.length > 8 ? input.sessionId.slice(0, 8) : input.sessionId;
60265
60972
  const handle = cleanCardlessSessionHandle(input);
60266
60973
  return {
@@ -60283,7 +60990,7 @@ function buildCardlessSessionActor(input) {
60283
60990
  function buildCardlessSessionEndpoint(input) {
60284
60991
  const projectRoot = resolveCardlessSessionPath(input.projectRoot ?? input.cwd);
60285
60992
  const cwd = resolveCardlessSessionPath(input.cwd);
60286
- const projectName = basename21(projectRoot) || projectRoot;
60993
+ const projectName = basename22(projectRoot) || projectRoot;
60287
60994
  const externalSessionId = input.externalSessionId?.trim();
60288
60995
  const endpointSessionId = input.pairingSessionId?.trim() || input.sessionId;
60289
60996
  const launchArgs = input.launchArgs?.map((entry) => entry.trim()).filter(Boolean);
@@ -60334,14 +61041,14 @@ async function registerCardlessSession(registry3, input) {
60334
61041
  }
60335
61042
 
60336
61043
  // packages/runtime/src/provisional-agent-names-config.ts
60337
- import { existsSync as existsSync32, readFileSync as readFileSync19, writeFileSync as writeFileSync4, mkdirSync as mkdirSync7 } from "fs";
60338
- import { homedir as homedir31 } from "os";
60339
- import { isAbsolute as isAbsolute4, join as join39, resolve as resolve19 } from "path";
61044
+ import { existsSync as existsSync34, readFileSync as readFileSync20, writeFileSync as writeFileSync4, mkdirSync as mkdirSync7 } from "fs";
61045
+ import { homedir as homedir33 } from "os";
61046
+ import { isAbsolute as isAbsolute4, join as join41, resolve as resolve19 } from "path";
60340
61047
  function openScoutHome() {
60341
- return process.env.OPENSCOUT_HOME ?? join39(homedir31(), ".openscout");
61048
+ return process.env.OPENSCOUT_HOME ?? join41(homedir33(), ".openscout");
60342
61049
  }
60343
61050
  function defaultProvisionalAgentNamesPath() {
60344
- return join39(openScoutHome(), "provisional-agent-names.json");
61051
+ return join41(openScoutHome(), "provisional-agent-names.json");
60345
61052
  }
60346
61053
  function resolveProvisionalAgentNamesMode(config2) {
60347
61054
  return config2.provisionalAgentNamesMode === "extend" ? "extend" : "replace";
@@ -60370,7 +61077,7 @@ function resolvePoolFilePath(filePath) {
60370
61077
  return isAbsolute4(trimmed) ? trimmed : resolve19(openScoutHome(), trimmed);
60371
61078
  }
60372
61079
  function readProvisionalAgentNamesJsonFile(filePath) {
60373
- return parseProvisionalAgentNamesJson(readFileSync19(filePath, "utf8"));
61080
+ return parseProvisionalAgentNamesJson(readFileSync20(filePath, "utf8"));
60374
61081
  }
60375
61082
  function loadInlineProvisionalAgentNames(config2) {
60376
61083
  const customNames = normalizeProvisionalAgentNamesSetting(config2.provisionalAgentNames);
@@ -60386,7 +61093,7 @@ function loadInlineProvisionalAgentNames(config2) {
60386
61093
  }
60387
61094
  function loadFileProvisionalAgentNames(config2 = loadUserConfig()) {
60388
61095
  const envFile = process.env.OPENSCOUT_PROVISIONAL_AGENT_NAMES_FILE?.trim();
60389
- if (envFile && existsSync32(envFile)) {
61096
+ if (envFile && existsSync34(envFile)) {
60390
61097
  const names = readProvisionalAgentNamesJsonFile(envFile);
60391
61098
  if (names.length > 0) {
60392
61099
  return { names, source: "env-file", sourcePath: envFile };
@@ -60394,7 +61101,7 @@ function loadFileProvisionalAgentNames(config2 = loadUserConfig()) {
60394
61101
  }
60395
61102
  if (config2.provisionalAgentNamesFile?.trim()) {
60396
61103
  const filePath = resolvePoolFilePath(config2.provisionalAgentNamesFile);
60397
- if (existsSync32(filePath)) {
61104
+ if (existsSync34(filePath)) {
60398
61105
  const names = readProvisionalAgentNamesJsonFile(filePath);
60399
61106
  if (names.length > 0) {
60400
61107
  return { names, source: "user-config-file", sourcePath: filePath };
@@ -60402,7 +61109,7 @@ function loadFileProvisionalAgentNames(config2 = loadUserConfig()) {
60402
61109
  }
60403
61110
  }
60404
61111
  const homeJson = defaultProvisionalAgentNamesPath();
60405
- if (existsSync32(homeJson)) {
61112
+ if (existsSync34(homeJson)) {
60406
61113
  const names = readProvisionalAgentNamesJsonFile(homeJson);
60407
61114
  if (names.length > 0) {
60408
61115
  return { names, source: "home-json", sourcePath: homeJson };
@@ -60923,6 +61630,7 @@ var AGENT_HARNESSES = [
60923
61630
  "claude",
60924
61631
  "grok",
60925
61632
  "grok-acp",
61633
+ "kimi",
60926
61634
  "flue",
60927
61635
  "cursor",
60928
61636
  "native",
@@ -62091,12 +62799,12 @@ function createBrokerHttpRouter(deps) {
62091
62799
 
62092
62800
  // packages/runtime/src/broker-server-lifecycle.ts
62093
62801
  import { lstat as lstat2, mkdir as mkdir10, unlink } from "fs/promises";
62094
- import { dirname as dirname24 } from "path";
62802
+ import { dirname as dirname25 } from "path";
62095
62803
  function isAddressInUse(error48) {
62096
62804
  return Boolean(error48 && typeof error48 === "object" && "code" in error48 && error48.code === "EADDRINUSE");
62097
62805
  }
62098
62806
  async function prepareBrokerSocketPath(socketPath) {
62099
- await mkdir10(dirname24(socketPath), { recursive: true, mode: 448 });
62807
+ await mkdir10(dirname25(socketPath), { recursive: true, mode: 448 });
62100
62808
  try {
62101
62809
  const existing = await lstat2(socketPath);
62102
62810
  if (!existing.isSocket()) {
@@ -63929,14 +64637,14 @@ function createRuntimeId2(prefix) {
63929
64637
  return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
63930
64638
  }
63931
64639
  function resolveControlPlaneHome() {
63932
- return process.env.OPENSCOUT_CONTROL_HOME ?? join40(process.env.HOME ?? process.cwd(), ".openscout", "control-plane");
64640
+ return process.env.OPENSCOUT_CONTROL_HOME ?? join42(process.env.HOME ?? process.cwd(), ".openscout", "control-plane");
63933
64641
  }
63934
64642
  function sleep2(ms) {
63935
64643
  return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
63936
64644
  }
63937
64645
  var controlHome = resolveControlPlaneHome();
63938
- var dbPath2 = join40(controlHome, "control-plane.sqlite");
63939
- var journalPath = join40(controlHome, "broker-journal.jsonl");
64646
+ var dbPath2 = join42(controlHome, "control-plane.sqlite");
64647
+ var journalPath = join42(controlHome, "broker-journal.jsonl");
63940
64648
  var port = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT), 10);
63941
64649
  var advertiseScope = resolveAdvertiseScope();
63942
64650
  var host = resolveBrokerHost(advertiseScope);
@@ -64256,7 +64964,7 @@ function currentHostInfo() {
64256
64964
  }
64257
64965
  async function writeHostInfo() {
64258
64966
  const hostInfoPath = resolveOpenScoutSupportPaths().hostInfoPath;
64259
- await mkdir11(dirname25(hostInfoPath), { recursive: true });
64967
+ await mkdir11(dirname26(hostInfoPath), { recursive: true });
64260
64968
  const temporaryPath = `${hostInfoPath}.tmp`;
64261
64969
  await writeFile10(temporaryPath, `${JSON.stringify(currentHostInfo(), null, 2)}
64262
64970
  `, "utf8");
@@ -64281,7 +64989,7 @@ async function readRelayAgentRegistrySignature() {
64281
64989
  const registryPath = resolveOpenScoutSupportPaths().relayAgentsRegistryPath;
64282
64990
  const info = await stat7(registryPath);
64283
64991
  const contents = await readFile12(registryPath);
64284
- const hash2 = createHash4("sha256").update(contents).digest("base64url");
64992
+ const hash2 = createHash5("sha256").update(contents).digest("base64url");
64285
64993
  return `${info.mtimeMs}:${info.size}:${hash2}`;
64286
64994
  } catch (error48) {
64287
64995
  if (error48 && typeof error48 === "object" && "code" in error48 && error48.code === "ENOENT") {
@@ -64512,10 +65220,12 @@ async function createCardlessProjectSessionForDelivery(input) {
64512
65220
  input.createdAt;
64513
65221
  const projectRoot = resolve20(expandHomePath(input.projectPath));
64514
65222
  const requestedHarness = input.execution?.harness;
64515
- const { harness, transport } = resolveCardlessSpawnTarget(requestedHarness);
65223
+ const { harness, transport } = resolveCardlessSessionSpawnTarget(requestedHarness, {
65224
+ claudeTransport: process.env.OPENSCOUT_CLAUDE_CARDLESS_TRANSPORT
65225
+ });
64516
65226
  const launchArgs = launchArgsForCardlessSession(harness, input.execution);
64517
65227
  const sessionId = createRuntimeId2("session");
64518
- const projectName = basename22(projectRoot) || projectRoot;
65228
+ const projectName = basename23(projectRoot) || projectRoot;
64519
65229
  const snapshot = runtime.snapshot();
64520
65230
  const projectSessionIndex = Object.values(snapshot.endpoints).filter((endpoint2) => {
64521
65231
  const endpointProjectRoot = endpoint2.projectRoot ?? (typeof endpoint2.metadata?.projectRoot === "string" ? endpoint2.metadata.projectRoot : undefined) ?? endpoint2.cwd;
@@ -64564,19 +65274,6 @@ async function createCardlessProjectSessionForDelivery(input) {
64564
65274
  }
64565
65275
  };
64566
65276
  }
64567
- function resolveCardlessSpawnTarget(requestedHarness) {
64568
- switch (requestedHarness ?? "claude") {
64569
- case "codex":
64570
- return { harness: "codex", transport: "codex_app_server" };
64571
- case "grok":
64572
- case "grok-acp":
64573
- return { harness: "grok-acp", transport: "grok_acp" };
64574
- case "claude":
64575
- return { harness: "claude", transport: "claude_stream_json" };
64576
- default:
64577
- throw new Error(`cannot auto-spawn a session for harness "${requestedHarness}"; ` + `supported: claude, codex, grok (runs over ACP). ` + `Bring a worker online first (scout up) to use other harnesses.`);
64578
- }
64579
- }
64580
65277
  function launchArgsForCardlessSession(harness, execution) {
64581
65278
  const model = execution?.model?.trim();
64582
65279
  const reasoningEffort = execution?.reasoningEffort?.trim();
@@ -64786,6 +65483,7 @@ var brokerService = createBrokerCoreService({
64786
65483
  threadEvents,
64787
65484
  isReconciledStaleFlightActivityItem,
64788
65485
  readChildServices: () => webControl.readChildServiceSnapshots(),
65486
+ readProjectionStatus: () => projection.statusSnapshot(),
64789
65487
  readHome: () => homeService.read(),
64790
65488
  readCapabilities: readBrokerCapabilityMatrixSnapshot,
64791
65489
  executeCommand: handleCommand,