@goah/cli 0.13.0 → 0.13.2

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 (236) hide show
  1. package/dist/LICENSE +201 -0
  2. package/dist/THIRD-PARTY-NOTICES.md +2319 -0
  3. package/dist/anthropic-messages-WBFOHES5.js +7214 -0
  4. package/dist/azure-openai-responses-NZFH3PO6.js +253 -0
  5. package/dist/chunk-25XSBFX6.js +639 -0
  6. package/dist/chunk-2QBQZGXF.js +110 -0
  7. package/dist/chunk-2ZP2NBW3.js +345 -0
  8. package/dist/chunk-4KA63VNZ.js +2 -0
  9. package/dist/chunk-4M6TXTT5.js +86 -0
  10. package/dist/chunk-4US7ZHT3.js +20 -0
  11. package/dist/chunk-6M3OOCKO.js +11809 -0
  12. package/dist/chunk-7AXAFDPG.js +17 -0
  13. package/dist/chunk-7E7V6OIU.js +920 -0
  14. package/dist/chunk-BXA47DTF.js +548 -0
  15. package/dist/chunk-D2DVAH37.js +25 -0
  16. package/dist/chunk-FSBUS2BI.js +26 -0
  17. package/dist/chunk-GKDRAHLI.js +4787 -0
  18. package/dist/chunk-H462EFJP.js +89 -0
  19. package/dist/chunk-IIJQ3DW4.js +35 -0
  20. package/dist/chunk-JQD5EWJY.js +34 -0
  21. package/dist/chunk-K26BVR6O.js +61 -0
  22. package/dist/chunk-KAO7WIXG.js +31 -0
  23. package/dist/chunk-KJ4HJCTK.js +1178 -0
  24. package/dist/chunk-LBKI23CC.js +9810 -0
  25. package/dist/chunk-LKBKZEHT.js +41 -0
  26. package/dist/chunk-MD7TLTXZ.js +18 -0
  27. package/dist/chunk-MPXK7QBL.js +868 -0
  28. package/dist/chunk-NRLGWZJC.js +11 -0
  29. package/dist/chunk-QBD6EJ2Z.js +1746 -0
  30. package/dist/chunk-R6I3VKME.js +132 -0
  31. package/dist/chunk-TJON22J4.js +87 -0
  32. package/dist/chunk-ULY36ME4.js +33097 -0
  33. package/dist/chunk-XALZLRYK.js +9221 -0
  34. package/dist/chunk-XPQKM3L7.js +57 -0
  35. package/dist/chunk-YH6YJ2IB.js +1773 -0
  36. package/dist/cli.d.ts +0 -2
  37. package/dist/cli.js +13716 -580
  38. package/dist/console/assets/{index-Rtc_B7cs.js → index-B1vGMXKr.js} +11 -11
  39. package/dist/console/assets/{index-Rtc_B7cs.js.map → index-B1vGMXKr.js.map} +1 -1
  40. package/dist/console/index.html +1 -1
  41. package/dist/dist-65MDQA4Q.js +1126 -0
  42. package/dist/dist-KNR2XL6J.js +39 -0
  43. package/dist/execution.d.ts +557 -2
  44. package/dist/execution.js +37 -2
  45. package/dist/faux-runner-worker.js +128 -0
  46. package/dist/google-generative-ai-YMHXZSFE.js +422 -0
  47. package/dist/google-vertex-X6DB3ZQ6.js +471 -0
  48. package/dist/index.d.ts +853 -25
  49. package/dist/index.js +84 -385
  50. package/dist/kernel.d.ts +39 -2
  51. package/dist/kernel.js +21 -2
  52. package/dist/mistral-conversations-TY3MMD6G.js +718 -0
  53. package/dist/multipart-parser-F6M4NJZU.js +373 -0
  54. package/dist/openai-codex-responses-BRDUMLN5.js +1374 -0
  55. package/dist/openai-completions-CX634XN3.js +1139 -0
  56. package/dist/openai-responses-HMCXJIHT.js +300 -0
  57. package/dist/openrouter-images-KTWET2H2.js +148 -0
  58. package/dist/pi-messages-XL5OEC4K.js +307 -0
  59. package/dist/pi-worker.js +671 -0
  60. package/dist/runner-pi.d.ts +342 -2
  61. package/dist/runner-pi.js +46 -2
  62. package/dist/runner-registry-GD4BYCQC.js +22 -0
  63. package/dist/sqlite.d.ts +446 -2
  64. package/dist/sqlite.js +15 -2
  65. package/dist/src-F2KBSV4T.js +1398 -0
  66. package/dist/supervisor.d.ts +625 -2
  67. package/dist/supervisor.js +39 -2
  68. package/dist/testkit.d.ts +564 -2
  69. package/dist/testkit.js +127 -2
  70. package/dist/transcript.d.ts +84 -2
  71. package/dist/transcript.js +25 -2
  72. package/dist/verification-worker.js +72 -0
  73. package/package.json +2 -26
  74. package/dist/cli.d.ts.map +0 -1
  75. package/dist/cli.js.map +0 -1
  76. package/dist/control.d.ts +0 -106
  77. package/dist/control.d.ts.map +0 -1
  78. package/dist/control.js +0 -242
  79. package/dist/control.js.map +0 -1
  80. package/dist/execution.d.ts.map +0 -1
  81. package/dist/execution.js.map +0 -1
  82. package/dist/index.d.ts.map +0 -1
  83. package/dist/index.js.map +0 -1
  84. package/dist/kernel.d.ts.map +0 -1
  85. package/dist/kernel.js.map +0 -1
  86. package/dist/live-config.d.ts +0 -10
  87. package/dist/live-config.d.ts.map +0 -1
  88. package/dist/live-config.js +0 -44
  89. package/dist/live-config.js.map +0 -1
  90. package/dist/prompt-queue.d.ts +0 -13
  91. package/dist/prompt-queue.d.ts.map +0 -1
  92. package/dist/prompt-queue.js +0 -35
  93. package/dist/prompt-queue.js.map +0 -1
  94. package/dist/runner-pi.d.ts.map +0 -1
  95. package/dist/runner-pi.js.map +0 -1
  96. package/dist/runner-registry.d.ts +0 -8
  97. package/dist/runner-registry.d.ts.map +0 -1
  98. package/dist/runner-registry.js +0 -12
  99. package/dist/runner-registry.js.map +0 -1
  100. package/dist/searchable-select.d.ts +0 -24
  101. package/dist/searchable-select.d.ts.map +0 -1
  102. package/dist/searchable-select.js +0 -61
  103. package/dist/searchable-select.js.map +0 -1
  104. package/dist/secret-input.d.ts +0 -8
  105. package/dist/secret-input.d.ts.map +0 -1
  106. package/dist/secret-input.js +0 -14
  107. package/dist/secret-input.js.map +0 -1
  108. package/dist/setup-wizard.d.ts +0 -22
  109. package/dist/setup-wizard.d.ts.map +0 -1
  110. package/dist/setup-wizard.js +0 -154
  111. package/dist/setup-wizard.js.map +0 -1
  112. package/dist/sqlite.d.ts.map +0 -1
  113. package/dist/sqlite.js.map +0 -1
  114. package/dist/supervisor.d.ts.map +0 -1
  115. package/dist/supervisor.js.map +0 -1
  116. package/dist/testkit.d.ts.map +0 -1
  117. package/dist/testkit.js.map +0 -1
  118. package/dist/thread-inspect.d.ts +0 -47
  119. package/dist/thread-inspect.d.ts.map +0 -1
  120. package/dist/thread-inspect.js +0 -78
  121. package/dist/thread-inspect.js.map +0 -1
  122. package/dist/transcript.d.ts.map +0 -1
  123. package/dist/transcript.js.map +0 -1
  124. package/dist/tui-theme.d.ts +0 -17
  125. package/dist/tui-theme.d.ts.map +0 -1
  126. package/dist/tui-theme.js +0 -19
  127. package/dist/tui-theme.js.map +0 -1
  128. package/dist/tui.d.ts +0 -24
  129. package/dist/tui.d.ts.map +0 -1
  130. package/dist/tui.js +0 -784
  131. package/dist/tui.js.map +0 -1
  132. package/dist/update.d.ts +0 -16
  133. package/dist/update.d.ts.map +0 -1
  134. package/dist/update.js +0 -67
  135. package/dist/update.js.map +0 -1
  136. package/dist/web-console.d.ts +0 -33
  137. package/dist/web-console.d.ts.map +0 -1
  138. package/dist/web-console.js +0 -242
  139. package/dist/web-console.js.map +0 -1
  140. package/dist/welcome.d.ts +0 -30
  141. package/dist/welcome.d.ts.map +0 -1
  142. package/dist/welcome.js +0 -69
  143. package/dist/welcome.js.map +0 -1
  144. package/node_modules/goah-ledger-contract/dist/execution.d.ts +0 -544
  145. package/node_modules/goah-ledger-contract/dist/execution.d.ts.map +0 -1
  146. package/node_modules/goah-ledger-contract/dist/execution.js +0 -52
  147. package/node_modules/goah-ledger-contract/dist/execution.js.map +0 -1
  148. package/node_modules/goah-ledger-contract/dist/index.d.ts +0 -4
  149. package/node_modules/goah-ledger-contract/dist/index.d.ts.map +0 -1
  150. package/node_modules/goah-ledger-contract/dist/index.js +0 -4
  151. package/node_modules/goah-ledger-contract/dist/index.js.map +0 -1
  152. package/node_modules/goah-ledger-contract/dist/kernel.d.ts +0 -37
  153. package/node_modules/goah-ledger-contract/dist/kernel.d.ts.map +0 -1
  154. package/node_modules/goah-ledger-contract/dist/kernel.js +0 -8
  155. package/node_modules/goah-ledger-contract/dist/kernel.js.map +0 -1
  156. package/node_modules/goah-ledger-contract/dist/transcript.d.ts +0 -63
  157. package/node_modules/goah-ledger-contract/dist/transcript.d.ts.map +0 -1
  158. package/node_modules/goah-ledger-contract/dist/transcript.js +0 -115
  159. package/node_modules/goah-ledger-contract/dist/transcript.js.map +0 -1
  160. package/node_modules/goah-ledger-contract/package.json +0 -28
  161. package/node_modules/goah-ledger-sqlite/dist/index.d.ts +0 -86
  162. package/node_modules/goah-ledger-sqlite/dist/index.d.ts.map +0 -1
  163. package/node_modules/goah-ledger-sqlite/dist/index.js +0 -1254
  164. package/node_modules/goah-ledger-sqlite/dist/index.js.map +0 -1
  165. package/node_modules/goah-ledger-sqlite/package.json +0 -26
  166. package/node_modules/goah-runner-pi/dist/configurator.d.ts +0 -20
  167. package/node_modules/goah-runner-pi/dist/configurator.d.ts.map +0 -1
  168. package/node_modules/goah-runner-pi/dist/configurator.js +0 -423
  169. package/node_modules/goah-runner-pi/dist/configurator.js.map +0 -1
  170. package/node_modules/goah-runner-pi/dist/credential-store.d.ts +0 -14
  171. package/node_modules/goah-runner-pi/dist/credential-store.d.ts.map +0 -1
  172. package/node_modules/goah-runner-pi/dist/credential-store.js +0 -163
  173. package/node_modules/goah-runner-pi/dist/credential-store.js.map +0 -1
  174. package/node_modules/goah-runner-pi/dist/env-spec.d.ts +0 -17
  175. package/node_modules/goah-runner-pi/dist/env-spec.d.ts.map +0 -1
  176. package/node_modules/goah-runner-pi/dist/env-spec.js +0 -95
  177. package/node_modules/goah-runner-pi/dist/env-spec.js.map +0 -1
  178. package/node_modules/goah-runner-pi/dist/index.d.ts +0 -76
  179. package/node_modules/goah-runner-pi/dist/index.d.ts.map +0 -1
  180. package/node_modules/goah-runner-pi/dist/index.js +0 -326
  181. package/node_modules/goah-runner-pi/dist/index.js.map +0 -1
  182. package/node_modules/goah-runner-pi/dist/model-provider.d.ts +0 -30
  183. package/node_modules/goah-runner-pi/dist/model-provider.d.ts.map +0 -1
  184. package/node_modules/goah-runner-pi/dist/model-provider.js +0 -96
  185. package/node_modules/goah-runner-pi/dist/model-provider.js.map +0 -1
  186. package/node_modules/goah-runner-pi/dist/pi-worker.d.ts +0 -31
  187. package/node_modules/goah-runner-pi/dist/pi-worker.d.ts.map +0 -1
  188. package/node_modules/goah-runner-pi/dist/pi-worker.js +0 -579
  189. package/node_modules/goah-runner-pi/dist/pi-worker.js.map +0 -1
  190. package/node_modules/goah-runner-pi/dist/steering-no-ack.test-fixture.d.ts +0 -2
  191. package/node_modules/goah-runner-pi/dist/steering-no-ack.test-fixture.d.ts.map +0 -1
  192. package/node_modules/goah-runner-pi/dist/steering-no-ack.test-fixture.js +0 -3
  193. package/node_modules/goah-runner-pi/dist/steering-no-ack.test-fixture.js.map +0 -1
  194. package/node_modules/goah-runner-pi/dist/steering-reject.test-fixture.d.ts +0 -2
  195. package/node_modules/goah-runner-pi/dist/steering-reject.test-fixture.d.ts.map +0 -1
  196. package/node_modules/goah-runner-pi/dist/steering-reject.test-fixture.js +0 -5
  197. package/node_modules/goah-runner-pi/dist/steering-reject.test-fixture.js.map +0 -1
  198. package/node_modules/goah-runner-pi/dist/steering-worker.test-fixture.d.ts +0 -2
  199. package/node_modules/goah-runner-pi/dist/steering-worker.test-fixture.d.ts.map +0 -1
  200. package/node_modules/goah-runner-pi/dist/steering-worker.test-fixture.js +0 -5
  201. package/node_modules/goah-runner-pi/dist/steering-worker.test-fixture.js.map +0 -1
  202. package/node_modules/goah-runner-pi/dist/test-helpers.d.ts +0 -4
  203. package/node_modules/goah-runner-pi/dist/test-helpers.d.ts.map +0 -1
  204. package/node_modules/goah-runner-pi/dist/test-helpers.js +0 -13
  205. package/node_modules/goah-runner-pi/dist/test-helpers.js.map +0 -1
  206. package/node_modules/goah-runner-pi/dist/verification-worker.d.ts +0 -2
  207. package/node_modules/goah-runner-pi/dist/verification-worker.d.ts.map +0 -1
  208. package/node_modules/goah-runner-pi/dist/verification-worker.js +0 -46
  209. package/node_modules/goah-runner-pi/dist/verification-worker.js.map +0 -1
  210. package/node_modules/goah-runner-pi/package.json +0 -28
  211. package/node_modules/goah-supervisor/dist/context-view.d.ts +0 -30
  212. package/node_modules/goah-supervisor/dist/context-view.d.ts.map +0 -1
  213. package/node_modules/goah-supervisor/dist/context-view.js +0 -58
  214. package/node_modules/goah-supervisor/dist/context-view.js.map +0 -1
  215. package/node_modules/goah-supervisor/dist/index.d.ts +0 -96
  216. package/node_modules/goah-supervisor/dist/index.d.ts.map +0 -1
  217. package/node_modules/goah-supervisor/dist/index.js +0 -1075
  218. package/node_modules/goah-supervisor/dist/index.js.map +0 -1
  219. package/node_modules/goah-supervisor/dist/roles.d.ts +0 -4
  220. package/node_modules/goah-supervisor/dist/roles.d.ts.map +0 -1
  221. package/node_modules/goah-supervisor/dist/roles.js +0 -29
  222. package/node_modules/goah-supervisor/dist/roles.js.map +0 -1
  223. package/node_modules/goah-supervisor/dist/verification.d.ts +0 -61
  224. package/node_modules/goah-supervisor/dist/verification.d.ts.map +0 -1
  225. package/node_modules/goah-supervisor/dist/verification.js +0 -135
  226. package/node_modules/goah-supervisor/dist/verification.js.map +0 -1
  227. package/node_modules/goah-supervisor/package.json +0 -26
  228. package/node_modules/goah-testkit/dist/faux-runner-worker.d.ts +0 -2
  229. package/node_modules/goah-testkit/dist/faux-runner-worker.d.ts.map +0 -1
  230. package/node_modules/goah-testkit/dist/faux-runner-worker.js +0 -82
  231. package/node_modules/goah-testkit/dist/faux-runner-worker.js.map +0 -1
  232. package/node_modules/goah-testkit/dist/index.d.ts +0 -49
  233. package/node_modules/goah-testkit/dist/index.d.ts.map +0 -1
  234. package/node_modules/goah-testkit/dist/index.js +0 -96
  235. package/node_modules/goah-testkit/dist/index.js.map +0 -1
  236. package/node_modules/goah-testkit/package.json +0 -29
@@ -0,0 +1,1178 @@
1
+ import { createRequire as __goahCreateRequire } from "node:module";
2
+ const require = __goahCreateRequire(import.meta.url);
3
+ import {
4
+ runnerPlugin
5
+ } from "./chunk-D2DVAH37.js";
6
+ import {
7
+ SQLITE_SCHEMA_VERSION,
8
+ SqliteLedger
9
+ } from "./chunk-YH6YJ2IB.js";
10
+ import {
11
+ RunnerRouter,
12
+ Supervisor,
13
+ deriveRecoveryViews
14
+ } from "./chunk-QBD6EJ2Z.js";
15
+ import {
16
+ ProcessRunner,
17
+ piWorkerPath,
18
+ resolveEnvSpec
19
+ } from "./chunk-7E7V6OIU.js";
20
+ import {
21
+ createPiModel
22
+ } from "./chunk-6M3OOCKO.js";
23
+ import {
24
+ replayTranscript
25
+ } from "./chunk-R6I3VKME.js";
26
+ import {
27
+ normalizeAssistantText
28
+ } from "./chunk-TJON22J4.js";
29
+
30
+ // node_modules/.dist-original/index.js
31
+ import { accessSync, chmodSync as chmodSync3, constants, existsSync as existsSync3, mkdirSync as mkdirSync2, openSync, closeSync, readFileSync as readFileSync3, renameSync, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync2 } from "node:fs";
32
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
33
+ import { homedir as homedir2 } from "node:os";
34
+ import { dirname as dirname2, isAbsolute, join as join4, resolve as resolve2 } from "node:path";
35
+ import { DatabaseSync } from "node:sqlite";
36
+
37
+ // node_modules/.dist-original/thread-inspect.js
38
+ import { homedir } from "node:os";
39
+ function listThreads(ledger) {
40
+ return ledger.threads().map((thread) => summarizeThread(ledger, thread.id)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
41
+ }
42
+ function showThread(ledger, threadId) {
43
+ if (!ledger.thread(threadId))
44
+ throw new Error(`thread not found: ${threadId}`);
45
+ return { thread: summarizeThread(ledger, threadId), turns: ledger.turns(threadId).map((turn) => {
46
+ const events = ledger.readStream(`turn:${turn.id}`);
47
+ return { ...turn, leaseToken: null, items: ledger.turnItems(turn.id), transcript: events.some((event) => event.type === "transcript.started") ? replayTranscript(events) : null };
48
+ }) };
49
+ }
50
+ function replayThread(ledger, threadId) {
51
+ return showThread(ledger, threadId);
52
+ }
53
+ function showTurnContext(ledger, turnId) {
54
+ if (!ledger.turn(turnId))
55
+ throw new Error(`turn not found: ${turnId}`);
56
+ return contextSnapshot(ledger.readStream(`turn:${turnId}`));
57
+ }
58
+ function streamEvents(ledger, streamId, fromStreamSeq = 1) {
59
+ if (!streamId.trim())
60
+ throw new Error("--stream is required");
61
+ if (!Number.isInteger(fromStreamSeq) || fromStreamSeq < 1)
62
+ throw new Error("--from must be a positive integer");
63
+ return ledger.readStream(streamId, fromStreamSeq);
64
+ }
65
+ function exportThread(ledger, threadId, options = {}) {
66
+ const detail = showThread(ledger, threadId);
67
+ const value = {
68
+ format: "goah.thread-export.v1",
69
+ exportedAt: options.now ?? (/* @__PURE__ */ new Date()).toISOString(),
70
+ redacted: !options.raw,
71
+ thread: detail.thread,
72
+ events: ledger.turns(threadId).flatMap((turn) => ledger.readStream(`turn:${turn.id}`)).sort((a, b) => a.seq - b.seq)
73
+ };
74
+ return options.raw ? value : redactValue(value);
75
+ }
76
+ function redactValue(value, key = "") {
77
+ if (SENSITIVE_KEY.test(key))
78
+ return "[REDACTED]";
79
+ if (Array.isArray(value))
80
+ return value.map((item) => redactValue(item));
81
+ if (value && typeof value === "object")
82
+ return Object.fromEntries(Object.entries(value).map(([childKey, child]) => [childKey, redactValue(child, childKey)]));
83
+ if (typeof value !== "string")
84
+ return value;
85
+ return value.replaceAll(homedir(), "<HOME>").replace(/\bBearer\s+[^\s"']+/gi, "Bearer [REDACTED]").replace(/\b(?:sk|ak|key)[-_][A-Za-z0-9_-]{12,}\b/gi, "[REDACTED]").replace(/((?:api[_-]?key|token|secret|password|authorization)\s*[=:]\s*)[^\s,;"']+/gi, "$1[REDACTED]");
86
+ }
87
+ function summarizeThread(ledger, threadId) {
88
+ const thread = ledger.thread(threadId);
89
+ if (!thread)
90
+ throw new Error(`thread not found: ${threadId}`);
91
+ const turns = ledger.turns(threadId);
92
+ const items = turns.flatMap((turn) => ledger.turnItems(turn.id));
93
+ return { threadId, agent: thread.agent, status: turns.some((turn) => turn.status === "in_progress") ? "in_progress" : "idle", turnCount: turns.length, itemCount: items.length, toolCalls: items.filter((item) => item.type === "tool_call").length, updatedAt: thread.updatedAt };
94
+ }
95
+ function contextSnapshot(events) {
96
+ const event = events.findLast((candidate) => candidate.type === "request.prepared");
97
+ if (!event)
98
+ return null;
99
+ const request = event.data;
100
+ return {
101
+ eventSeq: event.seq,
102
+ provider: request.provider,
103
+ model: request.model,
104
+ systemPrompt: request.systemPrompt,
105
+ text: request.activeContext,
106
+ sourceSeqs: request.sourceSeqs,
107
+ toolCount: request.tools.length,
108
+ messageCount: request.messages.length,
109
+ modelConfig: request.modelConfig
110
+ };
111
+ }
112
+ var SENSITIVE_KEY = /^(?:api[_-]?key|token|(?:lease|fencing|access|refresh|auth)[_-]?token|secret|password|authorization|cookie|set-cookie)$/i;
113
+
114
+ // node_modules/.dist-original/control.js
115
+ import { createHash } from "node:crypto";
116
+ import { chmodSync, existsSync, mkdirSync, rmSync } from "node:fs";
117
+ import { createConnection, createServer } from "node:net";
118
+ import { join as join2 } from "node:path";
119
+
120
+ // node_modules/.dist-original/update.js
121
+ import { spawn } from "node:child_process";
122
+ import { readFileSync, realpathSync } from "node:fs";
123
+ import { dirname, join, resolve, sep } from "node:path";
124
+ import { fileURLToPath } from "node:url";
125
+ function packageRoot() {
126
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..");
127
+ }
128
+ function installedVersion(root = packageRoot()) {
129
+ return JSON.parse(readFileSync(join(root, "package.json"), "utf8")).version;
130
+ }
131
+ function planNpmUpdate(root, globalPrefix, target, npm = process.platform === "win32" ? "npm.cmd" : "npm") {
132
+ const installed = realpathSync(root);
133
+ const globalRoots = process.platform === "win32" ? [join(globalPrefix, "node_modules")] : [join(globalPrefix, "lib", "node_modules"), join(globalPrefix, "node_modules")];
134
+ if (globalRoots.some((directory) => isInside(installed, directory)))
135
+ return { command: npm, args: ["install", "--global", `@goah/cli@${target}`], mode: "global", prefix: globalPrefix };
136
+ const marker = `${sep}node_modules${sep}@goah${sep}cli`;
137
+ const index = installed.lastIndexOf(marker);
138
+ if (index < 0)
139
+ throw new Error("This Goah is running from a source checkout. Build or install @goah/cli instead of self-updating the checkout.");
140
+ const prefix = installed.slice(0, index);
141
+ return { command: npm, args: ["install", "--prefix", prefix, `@goah/cli@${target}`], mode: "prefix", prefix };
142
+ }
143
+ async function runUpdate(options = {}) {
144
+ const current = installedVersion();
145
+ const target = options.target !== void 0 ? options.target : await capture("npm", ["view", "@goah/cli", "version", "--json"]).then((text) => String(JSON.parse(text)));
146
+ if (current === target) {
147
+ console.log(`Goah ${current} is already up to date.`);
148
+ return;
149
+ }
150
+ const globalPrefix = (await capture("npm", ["prefix", "--global"])).trim();
151
+ const plan = planNpmUpdate(packageRoot(), globalPrefix, target);
152
+ if (options.check) {
153
+ console.log(`Goah ${current} \u2192 ${target} is available.`);
154
+ return;
155
+ }
156
+ if (!options.dryRun)
157
+ console.log(`Updating Goah ${current} \u2192 ${target}\u2026`);
158
+ else
159
+ console.log(`Would run: ${plan.command} ${plan.args.join(" ")}`);
160
+ if (options.dryRun)
161
+ return;
162
+ await runQuiet(plan.command, [...plan.args, "--no-fund", "--no-audit", "--loglevel=error"]);
163
+ const updated = installedVersion();
164
+ if (updated !== target)
165
+ throw new Error(`npm completed but the active installation reports ${updated}, expected ${target}`);
166
+ console.log(`Updated Goah to ${updated}. The next goah launch will restart the resident daemon automatically.`);
167
+ }
168
+ function isInside(path, directory) {
169
+ const prefix = resolve(directory);
170
+ return path === prefix || path.startsWith(`${prefix}${sep}`);
171
+ }
172
+ function capture(command, args) {
173
+ return new Promise((resolveOutput, reject) => {
174
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
175
+ let stdout = "";
176
+ let stderr = "";
177
+ child.stdout.on("data", (chunk) => {
178
+ stdout += chunk.toString();
179
+ });
180
+ child.stderr.on("data", (chunk) => {
181
+ stderr += chunk.toString();
182
+ });
183
+ child.once("error", reject);
184
+ child.once("close", (code) => code === 0 ? resolveOutput(stdout) : reject(new Error(stderr.trim() || `${command} exited ${code}`)));
185
+ });
186
+ }
187
+ function runQuiet(command, args) {
188
+ return new Promise((resolveRun, reject) => {
189
+ const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
190
+ let stdout = "";
191
+ let stderr = "";
192
+ child.stdout.on("data", (chunk) => {
193
+ stdout += chunk.toString();
194
+ });
195
+ child.stderr.on("data", (chunk) => {
196
+ stderr += chunk.toString();
197
+ });
198
+ child.once("error", reject);
199
+ child.once("close", (code) => code === 0 ? resolveRun() : reject(new Error(stderr.trim() || stdout.trim() || `${command} exited ${code}`)));
200
+ });
201
+ }
202
+
203
+ // node_modules/.dist-original/control.js
204
+ var CONTROL_LINE_LIMIT = 1e6;
205
+ function controlEndpoint(stateDir) {
206
+ if (process.platform !== "win32")
207
+ return join2(stateDir, "control.sock");
208
+ return `\\\\.\\pipe\\goah-${createHash("sha256").update(stateDir).digest("hex").slice(0, 16)}`;
209
+ }
210
+ async function runControlServer(supervisor, ledger, stateDir, signal, options = {}) {
211
+ mkdirSync(stateDir, { recursive: true });
212
+ const endpoint = controlEndpoint(stateDir);
213
+ if (process.platform !== "win32" && existsSync(endpoint))
214
+ rmSync(endpoint);
215
+ const sockets = /* @__PURE__ */ new Set();
216
+ const server = createServer((socket) => {
217
+ sockets.add(socket);
218
+ socket.on("error", () => void 0);
219
+ socket.once("close", () => sockets.delete(socket));
220
+ void serve(socket, supervisor, ledger, options.reloadRuntime, options.stop);
221
+ });
222
+ await new Promise((resolve3, reject) => {
223
+ server.once("error", reject);
224
+ server.listen(endpoint, resolve3);
225
+ });
226
+ if (process.platform !== "win32")
227
+ chmodSync(endpoint, 384);
228
+ await new Promise((resolve3) => {
229
+ const stop = () => {
230
+ for (const socket of sockets)
231
+ socket.destroy();
232
+ server.close(() => resolve3());
233
+ };
234
+ if (signal.aborted)
235
+ stop();
236
+ else
237
+ signal.addEventListener("abort", stop, { once: true });
238
+ });
239
+ if (process.platform !== "win32" && existsSync(endpoint))
240
+ rmSync(endpoint);
241
+ }
242
+ async function requestControl(stateDir, request) {
243
+ let result;
244
+ await streamControl(stateDir, request, (frame) => {
245
+ if (frame.type === "error")
246
+ throw new Error(frame.error);
247
+ if (frame.type === "result")
248
+ result = frame.value;
249
+ });
250
+ if (result === void 0)
251
+ throw new Error("control request ended without a result");
252
+ return result;
253
+ }
254
+ async function streamControl(stateDir, request, onFrame, signal) {
255
+ if (signal?.aborted)
256
+ return;
257
+ const socket = createConnection(controlEndpoint(stateDir));
258
+ const abort = () => socket.destroy();
259
+ signal?.addEventListener("abort", abort, { once: true });
260
+ try {
261
+ await new Promise((resolve3, reject) => {
262
+ socket.once("connect", resolve3);
263
+ socket.once("error", reject);
264
+ socket.once("close", () => signal?.aborted ? resolve3() : reject(new Error("control connection closed before connecting")));
265
+ });
266
+ if (signal?.aborted)
267
+ return;
268
+ socket.write(`${JSON.stringify(request)}
269
+ `);
270
+ let buffer = "";
271
+ await new Promise((resolve3, reject) => {
272
+ socket.on("data", (chunk) => {
273
+ buffer += chunk.toString();
274
+ while (buffer.includes("\n")) {
275
+ const index = buffer.indexOf("\n");
276
+ const line = buffer.slice(0, index);
277
+ buffer = buffer.slice(index + 1);
278
+ if (!line)
279
+ continue;
280
+ try {
281
+ onFrame(JSON.parse(line));
282
+ } catch (error) {
283
+ reject(error);
284
+ socket.destroy();
285
+ }
286
+ }
287
+ });
288
+ socket.once("end", resolve3);
289
+ socket.once("close", resolve3);
290
+ socket.once("error", reject);
291
+ });
292
+ } finally {
293
+ signal?.removeEventListener("abort", abort);
294
+ socket.destroy();
295
+ }
296
+ }
297
+ async function controlAvailable(stateDir) {
298
+ try {
299
+ return await requestControl(stateDir, { op: "ping" }) === "pong";
300
+ } catch {
301
+ return false;
302
+ }
303
+ }
304
+ async function serve(socket, supervisor, ledger, reloadRuntime, stop) {
305
+ let buffer = "";
306
+ let bufferedBytes = 0;
307
+ socket.on("data", (chunk) => {
308
+ bufferedBytes += chunk.length;
309
+ if (bufferedBytes > CONTROL_LINE_LIMIT) {
310
+ socket.removeAllListeners("data");
311
+ write(socket, { type: "error", error: "control request exceeded 1 MB" });
312
+ socket.end();
313
+ return;
314
+ }
315
+ buffer += chunk.toString();
316
+ const index = buffer.indexOf("\n");
317
+ if (index < 0)
318
+ return;
319
+ socket.removeAllListeners("data");
320
+ const line = buffer.slice(0, index);
321
+ let request;
322
+ try {
323
+ request = JSON.parse(line);
324
+ } catch (error) {
325
+ write(socket, { type: "error", error: error instanceof Error ? error.message : String(error) });
326
+ socket.end();
327
+ return;
328
+ }
329
+ void dispatch(request, socket, supervisor, ledger, reloadRuntime, stop).catch((error) => {
330
+ write(socket, { type: "error", error: error instanceof Error ? error.message : String(error) });
331
+ socket.end();
332
+ });
333
+ });
334
+ }
335
+ async function dispatch(request, socket, supervisor, ledger, reloadRuntime, stop) {
336
+ if (request.op === "interact") {
337
+ await interact(request.message, socket, supervisor, ledger);
338
+ return;
339
+ }
340
+ if (request.op === "goal.interact") {
341
+ const accepted = await supervisor.startHumanGoalTurn(request.objective, request.id);
342
+ write(socket, { type: "accepted", turnId: accepted.turnId, value: accepted });
343
+ for await (const frame of turnFrames(accepted.turnId, ledger, () => !socket.destroyed))
344
+ write(socket, frame);
345
+ socket.end();
346
+ return;
347
+ }
348
+ if (request.op === "turn.attach") {
349
+ for await (const frame of turnFrames(request.turnId, ledger, () => !socket.destroyed))
350
+ write(socket, frame);
351
+ socket.end();
352
+ return;
353
+ }
354
+ let value;
355
+ if (request.op === "daemon.stop") {
356
+ value = { stopping: true };
357
+ setTimeout(() => stop?.(), 10);
358
+ } else if (request.op === "daemon.version")
359
+ value = installedVersion();
360
+ else if (request.op === "config.reload") {
361
+ const swap = reloadRuntime ? await reloadRuntime(request.configPath) : void 0;
362
+ if (swap) {
363
+ supervisor.swapRunner(swap.runner, swap.profiles);
364
+ if (swap.ledger) {
365
+ ledger.close();
366
+ ledger = swap.ledger;
367
+ }
368
+ }
369
+ value = { reloaded: Boolean(swap) };
370
+ } else if (request.op === "ping")
371
+ value = "pong";
372
+ else if (request.op === "status")
373
+ value = snapshot(ledger, supervisor);
374
+ else if (request.op === "goal.start")
375
+ value = supervisor.startGoal(request.objective, request.id);
376
+ else if (request.op === "goal.update")
377
+ value = supervisor.updateGoal(request.id, { ...request.objective !== void 0 ? { objective: request.objective } : {}, ...request.observationMethod !== void 0 ? { observationMethod: request.observationMethod } : {}, ...request.verificationMethod !== void 0 ? { verificationMethod: request.verificationMethod } : {} }, "human");
378
+ else if (request.op === "goal.observe")
379
+ value = supervisor.confirmObservationMethod(request.id, request.observationMethod);
380
+ else if (request.op === "goal.transition")
381
+ value = supervisor.transitionGoal(request.id, request.phase, "human");
382
+ else if (request.op === "goal.complete")
383
+ value = supervisor.completeGoal({ goalId: request.id, revision: requiredGoal(ledger, request.id).revision, reason: request.reason, evidence: request.evidence }, "human");
384
+ else if (request.op === "ceo.send")
385
+ value = await supervisor.sendToCeo({ message: request.message });
386
+ else if (request.op === "ceo.status")
387
+ value = ceoStatus(ledger, supervisor);
388
+ else if (request.op === "ceo.inbox")
389
+ value = ledger.unreadMail("human");
390
+ else if (request.op === "work.records")
391
+ value = ledger.workRecords();
392
+ else if (request.op === "work.record")
393
+ value = ledger.workRecord(request.goalId);
394
+ else if (request.op === "work.history")
395
+ value = ledger.workRecordHistory(request.goalId);
396
+ else if (request.op === "work.diff")
397
+ value = ledger.workRecordDiff(request.goalId, request.fromRevision, request.toRevision);
398
+ else if (request.op === "wake.stop")
399
+ value = await supervisor.stopAgentWake(request.agent, request.goalId);
400
+ else if (request.op === "turn.interrupt")
401
+ value = await supervisor.interruptTurn(request.turnId);
402
+ else if (request.op === "turn.steer")
403
+ value = await supervisor.startHumanTurn(request.message);
404
+ else
405
+ value = { unknown: String(request) };
406
+ write(socket, { type: "result", value });
407
+ socket.end();
408
+ }
409
+ async function interact(message, socket, supervisor, ledger) {
410
+ for await (const frame of interactFrames(message, supervisor, ledger, () => !socket.destroyed))
411
+ write(socket, frame);
412
+ socket.end();
413
+ }
414
+ async function* interactFrames(message, supervisor, ledger, isActive = () => true) {
415
+ if (!message.trim())
416
+ throw new Error("message is required");
417
+ const accepted = await supervisor.startHumanTurn(message);
418
+ yield { type: "accepted", turnId: accepted.turnId, value: accepted };
419
+ yield* turnFrames(accepted.turnId, ledger, isActive);
420
+ }
421
+ async function* turnFrames(turnId, ledger, isActive) {
422
+ let nextStreamSeq = 1;
423
+ const turn = ledger.turn(turnId);
424
+ if (!turn)
425
+ throw new Error("Turn not found");
426
+ const drain = async function* () {
427
+ const events = ledger.readStream(`turn:${turnId}`, nextStreamSeq);
428
+ for (const event of events) {
429
+ nextStreamSeq = event.streamSeq + 1;
430
+ if (isTurnPresentationEvent(event.type))
431
+ yield { type: "event", event };
432
+ }
433
+ };
434
+ while (true) {
435
+ if (!isActive())
436
+ return;
437
+ yield* drain();
438
+ const current = ledger.turn(turnId);
439
+ if (!current)
440
+ throw new Error("Turn disappeared");
441
+ if (current.status !== "in_progress") {
442
+ yield* drain();
443
+ const answer = ledger.turnItems(turnId).filter((item) => item.type === "assistant_message").at(-1);
444
+ const answerText = String(answer?.data?.text ?? "");
445
+ const streamed = answerText !== "" && ledger.readStream(`turn:${turnId}`).some((event) => event.type === "response.committed" ? event.data.text === answerText : event.type === "message.assistant.completed" && assistantEventText(event.data) === answerText);
446
+ yield { type: "result", value: { turn: { ...current, leaseToken: null }, ...answer && !streamed ? { response: { content: answerText } } : {} } };
447
+ return;
448
+ }
449
+ await new Promise((resolve3) => setTimeout(resolve3, 50));
450
+ }
451
+ }
452
+ function snapshot(ledger, supervisor) {
453
+ return { seq: ledger.events().at(-1)?.seq ?? 0, threads: ledger.threads(), turns: ledger.turns().map((turn) => ({ ...turn, leaseToken: null })), goals: ledger.goals(), team: supervisor.teamList(), wakes: ledger.wakes(), wakeTriggers: ledger.wakes().flatMap((wake) => ledger.wakeTriggers(wake.id)), schedules: ledger.schedules() };
454
+ }
455
+ function ceoStatus(ledger, supervisor) {
456
+ return { root: supervisor.currentRoot(), roots: ledger.goals().filter((goal) => goal.parentId === null && goal.owner === "ceo"), team: supervisor.teamList(), pendingHuman: ledger.unreadMail("human"), recentCeoHandoffs: ledger.eventsSince(0, ["handoff.recorded"]).filter((event) => event.actor === "ceo").slice(-10) };
457
+ }
458
+ function requiredGoal(ledger, id) {
459
+ const goal = ledger.goal(id);
460
+ if (!goal)
461
+ throw new Error("goal not found");
462
+ return goal;
463
+ }
464
+ function assistantEventText(value) {
465
+ if (!value || typeof value !== "object" || Array.isArray(value) || !value.message || typeof value.message !== "object" || Array.isArray(value.message))
466
+ return "";
467
+ const content = value.message.content;
468
+ if (typeof content === "string")
469
+ return normalizeAssistantText(content);
470
+ if (!Array.isArray(content))
471
+ return "";
472
+ return content.map((item) => item && typeof item === "object" && !Array.isArray(item) && item.type === "text" && typeof item.text === "string" ? normalizeAssistantText(item.text) : "").filter(Boolean).join("\n");
473
+ }
474
+ function isTurnPresentationEvent(type) {
475
+ return type.startsWith("message.") || type.startsWith("tool.") || type.startsWith("item.") || type.startsWith("turn.") || type === "response.committed" || type === "handoff.recorded" || type === "transcript.interrupted" || type === "transcript.completed";
476
+ }
477
+ function write(socket, frame) {
478
+ socket.write(`${JSON.stringify(frame)}
479
+ `);
480
+ }
481
+
482
+ // node_modules/.dist-original/web-console.js
483
+ import { randomUUID } from "node:crypto";
484
+ import { chmodSync as chmodSync2, existsSync as existsSync2, readFileSync as readFileSync2, rmSync as rmSync2, statSync, writeFileSync } from "node:fs";
485
+ import { createServer as createServer2 } from "node:http";
486
+ import { extname, join as join3, normalize } from "node:path";
487
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
488
+ var assetsDirectory = fileURLToPath2(new URL("./console/", import.meta.url));
489
+ function consoleMetadataPath(stateDir) {
490
+ return join3(stateDir, "console.json");
491
+ }
492
+ function readConsoleMetadata(stateDir) {
493
+ const path = consoleMetadataPath(stateDir);
494
+ if (!existsSync2(path))
495
+ return null;
496
+ try {
497
+ const value = JSON.parse(readFileSync2(path, "utf8"));
498
+ if (!value.url || !Number.isInteger(value.port) || !value.token)
499
+ return null;
500
+ return value;
501
+ } catch {
502
+ return null;
503
+ }
504
+ }
505
+ function consoleSnapshot(ledger, supervisor, now = (/* @__PURE__ */ new Date()).toISOString()) {
506
+ const events = ledger.events().slice(-300).map((event) => redactValue(event));
507
+ return redactValue({
508
+ seq: ledger.events().at(-1)?.seq ?? 0,
509
+ now,
510
+ currentRoot: supervisor.currentRoot(),
511
+ goals: ledger.goals(),
512
+ team: supervisor.teamList(now),
513
+ threads: ledger.threads(),
514
+ turns: ledger.turns().map((turn) => ({ ...turn, leaseToken: null })),
515
+ wakes: ledger.wakes(),
516
+ wakeTriggers: ledger.wakes().flatMap((wake) => ledger.wakeTriggers(wake.id)),
517
+ schedules: ledger.schedules(),
518
+ recoveries: deriveRecoveryViews(ledger),
519
+ mailbox: ledger.mailbox(),
520
+ events
521
+ });
522
+ }
523
+ function organizationTrajectory(ledger, options = {}) {
524
+ const limit = Math.min(Math.max(options.limit ?? 100, 1), 200);
525
+ const beforeSeq = options.beforeSeq ?? Number.MAX_SAFE_INTEGER;
526
+ const wakeAgents = new Map(ledger.wakes().map((wake) => [wake.id, wake.agent]));
527
+ const candidates = ledger.events().filter((event) => {
528
+ if (event.seq >= beforeSeq || !isTrajectoryEvent(event.type))
529
+ return false;
530
+ const wakeId = event.streamId.startsWith("wake:") ? event.streamId.slice("wake:".length) : null;
531
+ const agent = wakeId ? wakeAgents.get(wakeId) ?? event.actor : event.actor;
532
+ if (options.agent && agent !== options.agent)
533
+ return false;
534
+ if (options.type && !event.type.startsWith(`${options.type}.`))
535
+ return false;
536
+ return true;
537
+ }).reverse();
538
+ const page = candidates.slice(0, limit);
539
+ return {
540
+ items: page.map((event) => {
541
+ const wakeId = event.streamId.startsWith("wake:") ? event.streamId.slice("wake:".length) : null;
542
+ return { event: redactValue(event), agent: wakeId ? wakeAgents.get(wakeId) ?? event.actor : event.actor, wakeId };
543
+ }),
544
+ nextBeforeSeq: candidates.length > limit ? page.at(-1)?.seq ?? null : null
545
+ };
546
+ }
547
+ async function runWebConsole(supervisor, ledger, stateDir, signal, options = {}) {
548
+ const host = options.host ?? "127.0.0.1";
549
+ if (!["127.0.0.1", "localhost", "::1"].includes(host))
550
+ throw new Error("Goah Console only binds to loopback hosts");
551
+ const token = randomUUID();
552
+ let allowedHost = "";
553
+ const server = createServer2((request, response) => {
554
+ route(request, response, supervisor, ledger, token, allowedHost).catch((error) => {
555
+ const message = { error: error instanceof Error ? error.message : String(error) };
556
+ if (response.headersSent)
557
+ response.end(`data: ${JSON.stringify({ ...message, type: "error" })}
558
+
559
+ `);
560
+ else
561
+ sendJson(response, 500, message);
562
+ });
563
+ });
564
+ await new Promise((resolve3, reject) => {
565
+ server.once("error", reject);
566
+ server.listen(options.port ?? 0, host, resolve3);
567
+ });
568
+ const address = server.address();
569
+ if (!address || typeof address === "string")
570
+ throw new Error("console server did not bind a TCP port");
571
+ const metadata = { url: `http://${host.includes(":") ? `[${host}]` : host}:${address.port}/`, host, port: address.port, pid: process.pid, token };
572
+ allowedHost = new URL(metadata.url).host;
573
+ const metadataPath = consoleMetadataPath(stateDir);
574
+ writeFileSync(metadataPath, `${JSON.stringify(metadata, null, 2)}
575
+ `, { mode: 384 });
576
+ if (process.platform !== "win32")
577
+ chmodSync2(metadataPath, 384);
578
+ options.onListening?.(metadata);
579
+ await new Promise((resolve3) => {
580
+ const stop = () => server.close(() => resolve3());
581
+ if (signal.aborted)
582
+ stop();
583
+ else
584
+ signal.addEventListener("abort", stop, { once: true });
585
+ });
586
+ rmSync2(metadataPath, { force: true });
587
+ }
588
+ async function route(request, response, supervisor, ledger, token, allowedHost) {
589
+ setHeaders(response);
590
+ if (request.headers.host !== allowedHost) {
591
+ sendJson(response, 403, { error: "console host is not allowed" });
592
+ return;
593
+ }
594
+ const url = new URL(request.url ?? "/", "http://127.0.0.1");
595
+ if (url.pathname.startsWith("/api/")) {
596
+ if (!authorized(request, url, token)) {
597
+ sendJson(response, 403, { error: "console authorization failed" });
598
+ return;
599
+ }
600
+ if (request.method === "GET" && url.pathname === "/api/snapshot") {
601
+ sendJson(response, 200, consoleSnapshot(ledger, supervisor));
602
+ return;
603
+ }
604
+ if (request.method === "GET" && url.pathname === "/api/trajectory") {
605
+ const options = {};
606
+ const beforeSeq = positiveInteger(url.searchParams.get("beforeSeq"));
607
+ if (beforeSeq)
608
+ options.beforeSeq = beforeSeq;
609
+ const limit = positiveInteger(url.searchParams.get("limit"));
610
+ if (limit)
611
+ options.limit = limit;
612
+ const agent = nonEmpty(url.searchParams.get("agent"));
613
+ if (agent)
614
+ options.agent = agent;
615
+ const type = nonEmpty(url.searchParams.get("type"));
616
+ if (type)
617
+ options.type = type;
618
+ sendJson(response, 200, organizationTrajectory(ledger, options));
619
+ return;
620
+ }
621
+ if (request.method === "GET" && url.pathname.startsWith("/api/threads/")) {
622
+ const threadId = decodeURIComponent(url.pathname.slice("/api/threads/".length));
623
+ const thread = ledger.thread(threadId);
624
+ if (!thread) {
625
+ sendJson(response, 404, { error: "thread not found" });
626
+ return;
627
+ }
628
+ const turns = ledger.turns(threadId);
629
+ sendJson(response, 200, redactValue({ thread, turns: turns.map((turn) => ({ ...turn, leaseToken: null, items: ledger.turnItems(turn.id) })) }));
630
+ return;
631
+ }
632
+ if (request.method === "POST" && url.pathname === "/api/ceo") {
633
+ const body = await readBody(request);
634
+ const message = typeof body.message === "string" ? body.message.trim() : "";
635
+ if (!message) {
636
+ sendJson(response, 400, { error: "message is required" });
637
+ return;
638
+ }
639
+ sendJson(response, 202, await supervisor.startHumanTurn(message));
640
+ return;
641
+ }
642
+ if (request.method === "POST" && url.pathname === "/api/chat") {
643
+ const body = await readBody(request);
644
+ const message = typeof body.message === "string" ? body.message.trim() : "";
645
+ if (!message) {
646
+ sendJson(response, 400, { error: "message is required" });
647
+ return;
648
+ }
649
+ response.writeHead(200, { "content-type": "text/event-stream", "cache-control": "no-cache", connection: "keep-alive" });
650
+ let active = true;
651
+ request.on("close", () => {
652
+ active = false;
653
+ });
654
+ try {
655
+ for await (const frame of interactFrames(message, supervisor, ledger, () => active)) {
656
+ if (!active)
657
+ break;
658
+ response.write(`data: ${JSON.stringify(frame)}
659
+
660
+ `);
661
+ }
662
+ } catch (error) {
663
+ if (active)
664
+ response.write(`data: ${JSON.stringify({ type: "error", error: error instanceof Error ? error.message : String(error) })}
665
+
666
+ `);
667
+ }
668
+ response.end();
669
+ return;
670
+ }
671
+ sendJson(response, 404, { error: "not found" });
672
+ return;
673
+ }
674
+ if (request.method !== "GET" && request.method !== "HEAD") {
675
+ response.writeHead(405);
676
+ response.end();
677
+ return;
678
+ }
679
+ const relative = url.pathname === "/" ? "index.html" : normalize(url.pathname).replace(/^\/+/, "");
680
+ if (relative === "index.html")
681
+ response.setHeader("set-cookie", `goah_console=${token}; Path=/; HttpOnly; SameSite=Strict`);
682
+ const path = join3(assetsDirectory, relative);
683
+ if (!path.startsWith(assetsDirectory) || !existsSync2(path) || !statSync(path).isFile()) {
684
+ const fallback = join3(assetsDirectory, "index.html");
685
+ if (!existsSync2(fallback)) {
686
+ response.writeHead(503);
687
+ response.end("Console assets are not built. Run npm run build.");
688
+ return;
689
+ }
690
+ serveFile(response, fallback, request.method === "HEAD");
691
+ return;
692
+ }
693
+ serveFile(response, path, request.method === "HEAD");
694
+ }
695
+ function isTrajectoryEvent(type) {
696
+ return ["goal.", "delegation.", "handoff.", "wake.", "mail.", "schedule.", "observation.", "ceo.", "human."].some((prefix) => type.startsWith(prefix));
697
+ }
698
+ function positiveInteger(value) {
699
+ const parsed = Number(value);
700
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : void 0;
701
+ }
702
+ function nonEmpty(value) {
703
+ const result = value?.trim();
704
+ return result ? result : void 0;
705
+ }
706
+ function authorized(request, url, token) {
707
+ const supplied = request.headers.authorization?.replace(/^Bearer\s+/i, "") ?? url.searchParams.get("token");
708
+ if (supplied === token)
709
+ return true;
710
+ const cookieToken = request.headers.cookie?.split(";").map((value) => value.trim()).find((value) => value.startsWith("goah_console="))?.slice("goah_console=".length);
711
+ if (cookieToken === token)
712
+ return true;
713
+ return false;
714
+ }
715
+ function serveFile(response, path, head) {
716
+ const types = { ".html": "text/html; charset=utf-8", ".js": "text/javascript; charset=utf-8", ".css": "text/css; charset=utf-8", ".png": "image/png", ".svg": "image/svg+xml", ".map": "application/json" };
717
+ response.writeHead(200, { "content-type": types[extname(path)] ?? "application/octet-stream", "cache-control": extname(path) === ".html" ? "no-store" : "public, max-age=31536000, immutable" });
718
+ response.end(head ? void 0 : readFileSync2(path));
719
+ }
720
+ function setHeaders(response) {
721
+ response.setHeader("content-security-policy", "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'none'");
722
+ response.setHeader("referrer-policy", "no-referrer");
723
+ response.setHeader("x-content-type-options", "nosniff");
724
+ response.setHeader("x-frame-options", "DENY");
725
+ }
726
+ function sendJson(response, status, value) {
727
+ response.writeHead(status, { "content-type": "application/json; charset=utf-8", "cache-control": "no-store" });
728
+ response.end(`${JSON.stringify(value)}
729
+ `);
730
+ }
731
+ async function readBody(request) {
732
+ let body = "";
733
+ for await (const chunk of request) {
734
+ body += chunk.toString();
735
+ if (body.length > 65536)
736
+ throw new Error("request body is too large");
737
+ }
738
+ const parsed = JSON.parse(body || "{}");
739
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
740
+ }
741
+
742
+ // node_modules/.dist-original/index.js
743
+ var configRoots = /* @__PURE__ */ new WeakMap();
744
+ function loadConfig(path = "goah.config.json") {
745
+ recoverProfileTransaction();
746
+ const absolute = resolve2(path);
747
+ const config = JSON.parse(readFileSync3(absolute, "utf8"));
748
+ if (config.version !== 1 && config.version !== 2)
749
+ throw new Error(`unsupported goah config version: ${String(config.version)}`);
750
+ const base = dirname2(absolute);
751
+ const root = config.workspace ? absolutePath(base, config.workspace) : base;
752
+ delete config.workspace;
753
+ delete config.limits;
754
+ delete config.heartbeatPolicies;
755
+ delete config.progressPolicies;
756
+ configRoots.set(config, root);
757
+ config.stateDir = absolutePath(base, config.stateDir);
758
+ if (config.runner) {
759
+ config.runner.command = resolveCommand(config.runner.command);
760
+ config.runner.args = config.runner.args.map((arg) => arg === "$GOAH_PI_WORKER" ? piWorkerPath() : arg);
761
+ }
762
+ if (!config.runnerProfiles?.length && config.runner?.env?.GOAH_PI_PROVIDER && config.runner.env.GOAH_PI_MODEL) {
763
+ const env = config.runner.env;
764
+ const provider = env.GOAH_PI_PROVIDER;
765
+ const model = env.GOAH_PI_MODEL;
766
+ const keyRef = Object.entries(env).find(([key, value]) => key.endsWith("API_KEY") && value.startsWith("env:"));
767
+ config.runnerProfiles = [{ id: "default", runner: "pi", config: { provider, model, ...keyRef ? { apiKeyEnv: keyRef[1].slice(4) } : {}, ...env.GOAH_PI_BASE_URL ? { baseUrl: env.GOAH_PI_BASE_URL } : {} } }];
768
+ if (config.profiles)
769
+ config.profiles = config.profiles.map((profile) => ({ ...profile, runnerProfile: profile.runnerProfile ?? "default" }));
770
+ }
771
+ return config;
772
+ }
773
+ function createRuntime(config) {
774
+ mkdirSync2(config.stateDir, { recursive: true });
775
+ const ledger = new SqliteLedger(join4(config.stateDir, "ledger.sqlite"));
776
+ const runner = config.runnerProfiles?.length ? new RunnerRouter(new Map(config.runnerProfiles.map((profile) => [profile.id, runnerPlugin(profile.runner).create(profile.config, configRoot(config))]))) : legacyRunner(config);
777
+ const supervisor = new Supervisor(ledger, runner, new class {
778
+ now() {
779
+ return /* @__PURE__ */ new Date();
780
+ }
781
+ }(), {
782
+ ...config.profiles ? { profiles: config.profiles } : {},
783
+ ...config.runnerProfiles ? { runnerProfiles: config.runnerProfiles } : {},
784
+ ...config.retryPolicy ? { retryPolicy: config.retryPolicy } : {}
785
+ });
786
+ return { ledger, supervisor };
787
+ }
788
+ function defaultConfig(directory, options = {}) {
789
+ const provider = options.provider ?? "faux";
790
+ const model = options.model ?? defaultModel(provider);
791
+ const runnerProfile = { id: "default", runner: "pi", config: { provider, model, thinking: "medium", ...options.apiKeyEnv ? { apiKeyEnv: options.apiKeyEnv } : {}, ...options.baseUrl ? { baseUrl: options.baseUrl } : {}, ...options.contextWindowTokens ? { contextWindowTokens: options.contextWindowTokens } : {}, ...options.maxOutputTokensPerTurn ? { maxOutputTokens: options.maxOutputTokensPerTurn } : {} } };
792
+ return {
793
+ version: 2,
794
+ stateDir: defaultStateDir(directory),
795
+ runnerProfiles: [runnerProfile],
796
+ profiles: [{ agent: "ceo", role: "ceo", runnerProfile: "default" }, { agent: options.agent ?? "worker", role: "child", runnerProfile: "default" }]
797
+ };
798
+ }
799
+ var SupervisorLock = class {
800
+ path;
801
+ #owned = false;
802
+ constructor(stateDir) {
803
+ this.path = join4(stateDir, "supervisor.lock");
804
+ }
805
+ acquire() {
806
+ mkdirSync2(dirname2(this.path), { recursive: true });
807
+ if (existsSync3(this.path)) {
808
+ const pid = Number(readFileSync3(this.path, "utf8"));
809
+ if (Number.isInteger(pid) && alive(pid))
810
+ throw new Error(`supervisor already running with pid ${pid}`);
811
+ rmSync3(this.path);
812
+ }
813
+ const fd = openSync(this.path, "wx");
814
+ writeFileSync2(fd, String(process.pid));
815
+ closeSync(fd);
816
+ this.#owned = true;
817
+ }
818
+ release() {
819
+ if (this.#owned) {
820
+ rmSync3(this.path, { force: true });
821
+ this.#owned = false;
822
+ }
823
+ }
824
+ };
825
+ function writeDefaultConfig(path = "goah.config.json", options = {}, overwrite = false) {
826
+ const absolute = resolve2(path);
827
+ if (existsSync3(absolute) && !overwrite)
828
+ throw new Error(`${absolute} already exists`);
829
+ writeFileSync2(absolute, `${JSON.stringify(defaultConfig(dirname2(absolute), options), null, 2)}
830
+ `);
831
+ }
832
+ function profilePath() {
833
+ return join4(process.env.GOAH_STATE_HOME ?? join4(homedir2(), ".goah"), "profile.json");
834
+ }
835
+ function readDefaultRunnerProfile() {
836
+ recoverProfileTransaction();
837
+ try {
838
+ const raw = JSON.parse(readFileSync3(profilePath(), "utf8"));
839
+ if (typeof raw.id === "string" && typeof raw.runner === "string" && raw.config && typeof raw.config === "object")
840
+ return raw;
841
+ if (typeof raw.provider === "string" && typeof raw.model === "string") {
842
+ const { provider, model, apiKeyEnv, baseUrl, contextWindowTokens, maxOutputTokensPerTurn } = raw;
843
+ return { id: "default", runner: "pi", config: { provider, model, ...typeof apiKeyEnv === "string" ? { apiKeyEnv } : {}, ...typeof baseUrl === "string" ? { baseUrl } : {}, ...typeof contextWindowTokens === "number" ? { contextWindowTokens } : {}, ...typeof maxOutputTokensPerTurn === "number" ? { maxOutputTokens: maxOutputTokensPerTurn } : {} } };
844
+ }
845
+ return null;
846
+ } catch {
847
+ return null;
848
+ }
849
+ }
850
+ function writeDefaultRunnerProfile(profile) {
851
+ withProfileLock(() => {
852
+ recoverProfileTransactionUnlocked();
853
+ writeDefaultRunnerProfileUnlocked(profile);
854
+ });
855
+ }
856
+ function writeDefaultRunnerProfileUnlocked(profile) {
857
+ mkdirSync2(dirname2(profilePath()), { recursive: true });
858
+ const temporary = `${profilePath()}.${process.pid}.tmp`;
859
+ writeFileSync2(temporary, `${JSON.stringify(profile, null, 2)}
860
+ `, { mode: 384 });
861
+ renameSync(temporary, profilePath());
862
+ chmodSync3(profilePath(), 384);
863
+ }
864
+ function updateWorkspaceRunnerProfile(path, profile) {
865
+ withProfileLock(() => {
866
+ recoverProfileTransactionUnlocked();
867
+ updateWorkspaceRunnerProfileUnlocked(path, profile);
868
+ });
869
+ }
870
+ function updateWorkspaceRunnerProfileUnlocked(path, profile) {
871
+ const absolute = resolve2(path);
872
+ const current = existsSync3(absolute) ? JSON.parse(readFileSync3(absolute, "utf8")) : defaultConfig(dirname2(absolute));
873
+ current.runnerProfiles = [...(current.runnerProfiles ?? []).filter((item) => item.id !== profile.id), profile];
874
+ current.profiles = (current.profiles ?? [{ agent: "ceo", role: "ceo" }, { agent: "worker", role: "child" }]).map((agent) => ({ ...agent, runnerProfile: agent.runnerProfile ?? profile.id }));
875
+ const temporary = `${absolute}.${process.pid}.tmp`;
876
+ writeFileSync2(temporary, `${JSON.stringify(current, null, 2)}
877
+ `);
878
+ renameSync(temporary, absolute);
879
+ }
880
+ function persistRunnerProfile(profile, workspacePath) {
881
+ withProfileLock(() => {
882
+ recoverProfileTransactionUnlocked();
883
+ const targets = [profilePath(), ...workspacePath ? [resolve2(workspacePath)] : []];
884
+ const before = targets.map((path) => ({ path, content: existsSync3(path) ? readFileSync3(path) : null }));
885
+ writeProfileTransaction(before);
886
+ try {
887
+ writeDefaultRunnerProfileUnlocked(profile);
888
+ if (workspacePath)
889
+ updateWorkspaceRunnerProfileUnlocked(workspacePath, profile);
890
+ rmSync3(profileTransactionPath(), { force: true });
891
+ } catch (error) {
892
+ restoreProfileSnapshots(before);
893
+ rmSync3(profileTransactionPath(), { force: true });
894
+ throw error;
895
+ }
896
+ });
897
+ }
898
+ function withProfileLock(operation) {
899
+ const lock = `${profilePath()}.lock`;
900
+ const ownerPath = join4(lock, "owner.json");
901
+ const token = randomUUID2();
902
+ mkdirSync2(dirname2(lock), { recursive: true });
903
+ acquireProfileLock(lock, ownerPath, token);
904
+ try {
905
+ return operation();
906
+ } finally {
907
+ if (readProfileLockOwner(ownerPath)?.token === token)
908
+ rmSync3(lock, { recursive: true, force: true });
909
+ }
910
+ }
911
+ function acquireProfileLock(lock, ownerPath, token) {
912
+ while (true) {
913
+ try {
914
+ mkdirSync2(lock);
915
+ try {
916
+ writeFileSync2(ownerPath, JSON.stringify({ pid: process.pid, token }), { mode: 384 });
917
+ } catch (error) {
918
+ rmSync3(lock, { recursive: true, force: true });
919
+ throw error;
920
+ }
921
+ return;
922
+ } catch (error) {
923
+ if (error.code !== "EEXIST")
924
+ throw error;
925
+ }
926
+ const owner = readProfileLockOwner(ownerPath);
927
+ let oldUnownedLock = false;
928
+ try {
929
+ oldUnownedLock = !owner && Date.now() - statSync2(lock).mtimeMs > 5e3;
930
+ } catch (error) {
931
+ if (error.code === "ENOENT")
932
+ continue;
933
+ throw error;
934
+ }
935
+ if (owner && processIsAlive(owner.pid) || !owner && !oldUnownedLock)
936
+ throw new Error("Another Goah process is updating Runner Profiles; try again.");
937
+ const stale = `${lock}.stale.${token}`;
938
+ try {
939
+ renameSync(lock, stale);
940
+ rmSync3(stale, { recursive: true, force: true });
941
+ } catch (error) {
942
+ if (error.code !== "ENOENT")
943
+ throw error;
944
+ }
945
+ }
946
+ }
947
+ function profileTransactionPath() {
948
+ return join4(dirname2(profilePath()), "profile-transaction.json");
949
+ }
950
+ function writeProfileTransaction(snapshots) {
951
+ const path = profileTransactionPath();
952
+ const temporary = `${path}.${process.pid}.tmp`;
953
+ mkdirSync2(dirname2(path), { recursive: true });
954
+ writeFileSync2(temporary, `${JSON.stringify({ version: 1, snapshots: snapshots.map((snapshot2) => ({ path: snapshot2.path, content: snapshot2.content?.toString("base64") ?? null })) })}
955
+ `, { mode: 384 });
956
+ renameSync(temporary, path);
957
+ chmodSync3(path, 384);
958
+ }
959
+ function restoreProfileSnapshots(snapshots) {
960
+ for (const snapshot2 of snapshots) {
961
+ if (snapshot2.content === null)
962
+ rmSync3(snapshot2.path, { force: true });
963
+ else {
964
+ mkdirSync2(dirname2(snapshot2.path), { recursive: true });
965
+ const temporary = `${snapshot2.path}.${process.pid}.rollback.tmp`;
966
+ writeFileSync2(temporary, snapshot2.content, snapshot2.path === profilePath() ? { mode: 384 } : void 0);
967
+ renameSync(temporary, snapshot2.path);
968
+ if (snapshot2.path === profilePath())
969
+ chmodSync3(snapshot2.path, 384);
970
+ }
971
+ }
972
+ }
973
+ function recoverProfileTransaction() {
974
+ if (existsSync3(profileTransactionPath()))
975
+ withProfileLock(recoverProfileTransactionUnlocked);
976
+ }
977
+ function recoverProfileTransactionUnlocked() {
978
+ const path = profileTransactionPath();
979
+ if (!existsSync3(path))
980
+ return;
981
+ const value = JSON.parse(readFileSync3(path, "utf8"));
982
+ if (value.version !== 1 || !Array.isArray(value.snapshots))
983
+ throw new Error("Goah Runner Profile transaction journal is invalid");
984
+ const snapshots = value.snapshots.map((snapshot2) => {
985
+ if (typeof snapshot2.path !== "string" || snapshot2.content !== null && typeof snapshot2.content !== "string")
986
+ throw new Error("Goah Runner Profile transaction journal is invalid");
987
+ return { path: snapshot2.path, content: snapshot2.content === null ? null : Buffer.from(snapshot2.content, "base64") };
988
+ });
989
+ restoreProfileSnapshots(snapshots);
990
+ rmSync3(path, { force: true });
991
+ }
992
+ function readProfileLockOwner(path) {
993
+ try {
994
+ const value = JSON.parse(readFileSync3(path, "utf8"));
995
+ return Number.isInteger(value.pid) && Number(value.pid) > 0 && typeof value.token === "string" ? value : null;
996
+ } catch (error) {
997
+ if (error.code === "ENOENT" || error instanceof SyntaxError)
998
+ return null;
999
+ throw error;
1000
+ }
1001
+ }
1002
+ function processIsAlive(pid) {
1003
+ try {
1004
+ process.kill(pid, 0);
1005
+ return true;
1006
+ } catch (error) {
1007
+ return error.code === "EPERM";
1008
+ }
1009
+ }
1010
+ function diagnoseConfig(config) {
1011
+ const checks = [];
1012
+ const check = (name, fn) => {
1013
+ try {
1014
+ checks.push({ name, ok: true, detail: fn() });
1015
+ } catch (error) {
1016
+ checks.push({ name, ok: false, detail: error instanceof Error ? error.message : String(error) });
1017
+ }
1018
+ };
1019
+ check("node", () => {
1020
+ if (Number(process.versions.node.split(".")[0]) < 24)
1021
+ throw new Error(`Node ${process.versions.node} is unsupported; require >=24`);
1022
+ return process.versions.node;
1023
+ });
1024
+ check("root", () => {
1025
+ const root = configRoot(config);
1026
+ accessSync(root, constants.R_OK | constants.W_OK);
1027
+ return `${root} (runner-owned local execution)`;
1028
+ });
1029
+ check("state", () => {
1030
+ const existing = nearestExisting(config.stateDir);
1031
+ accessSync(existing, constants.W_OK);
1032
+ const database = join4(config.stateDir, "ledger.sqlite");
1033
+ if (!existsSync3(database))
1034
+ return `${config.stateDir} (will create)`;
1035
+ const db = new DatabaseSync(database, { readOnly: true });
1036
+ try {
1037
+ const version = db.prepare("PRAGMA user_version").get().user_version;
1038
+ if (version > SQLITE_SCHEMA_VERSION)
1039
+ throw new Error(`ledger schema ${version} is newer than supported schema ${SQLITE_SCHEMA_VERSION}`);
1040
+ if (version > 0 && version < SQLITE_SCHEMA_VERSION)
1041
+ throw new Error(`ledger schema ${version} predates runtime schema ${SQLITE_SCHEMA_VERSION}; recreate this development workspace`);
1042
+ return `${database} (schema ${version})`;
1043
+ } finally {
1044
+ db.close();
1045
+ }
1046
+ });
1047
+ check("runner", () => {
1048
+ if (config.runnerProfiles?.length) {
1049
+ for (const profile of config.runnerProfiles)
1050
+ runnerPlugin(profile.runner);
1051
+ return config.runnerProfiles.map((profile) => `${profile.id}:${profile.runner}`).join(", ");
1052
+ }
1053
+ if (!config.runner)
1054
+ throw new Error("no runner is configured");
1055
+ accessSync(config.runner.command, constants.X_OK);
1056
+ const workerArg = config.runner.args[0];
1057
+ if (workerArg && isAbsolute(workerArg))
1058
+ accessSync(workerArg, constants.R_OK);
1059
+ const env = resolveEnvSpec(config.runner.env, { root: configRoot(config) });
1060
+ const provider = requiredEnv(env, "GOAH_PI_PROVIDER");
1061
+ const modelId = requiredEnv(env, "GOAH_PI_MODEL");
1062
+ const model = createPiModel(provider, modelId, env).model;
1063
+ return `${provider}/${modelId} context=${model.contextWindow} output=${model.maxTokens}; auth is checked when the wake starts`;
1064
+ });
1065
+ return { ok: checks.every((item) => item.ok || item.severity === "warning"), checks };
1066
+ }
1067
+ function statusSnapshot(ledger) {
1068
+ const events = ledger.events();
1069
+ const wakes = ledger.wakes().map((wake) => {
1070
+ const turn = wake.turnId ? ledger.turn(wake.turnId) : null;
1071
+ const turnEvents = turn ? ledger.readStream(`turn:${turn.id}`) : [];
1072
+ const tokensUsed = turnEvents.reduce((total, event) => total + assistantTokens(event.data), 0);
1073
+ return { ...wake, tokensUsed, abnormalReason: turn?.status === "failed" ? field(turn.error, "message") : null };
1074
+ });
1075
+ const goals = ledger.goals();
1076
+ const handoffs = events.filter((event) => event.type === "handoff.recorded").slice(-20).map((event) => ({ seq: event.seq, ts: event.ts, agent: event.actor, streamId: event.streamId, handoff: event.data }));
1077
+ const modelCapabilitiesByAgent = Object.fromEntries(ledger.threads().flatMap((thread) => {
1078
+ const turnIds = new Set(ledger.turns(thread.id).map((turn) => turn.id));
1079
+ const capability = [...events].reverse().find((event) => event.type === "transcript.started" && event.streamId.startsWith("turn:") && turnIds.has(event.streamId.slice("turn:".length)))?.data;
1080
+ return capability ? [[thread.agent, capability]] : [];
1081
+ }));
1082
+ const modelCapabilities = modelCapabilitiesByAgent.ceo ?? [...events].reverse().find((event) => event.type === "transcript.started")?.data ?? null;
1083
+ return { seq: events.at(-1)?.seq ?? 0, threads: ledger.threads(), turns: ledger.turns().map((turn) => ({ ...turn, leaseToken: null })), goals, wakes, wakeTriggers: wakes.flatMap((wake) => ledger.wakeTriggers(wake.id)), schedules: ledger.schedules(), modelCapabilities, modelCapabilitiesByAgent, recentHandoffs: handoffs };
1084
+ }
1085
+ function defaultModel(provider) {
1086
+ if (provider === "faux")
1087
+ return "faux-goah";
1088
+ throw new Error(`--model is required for ${provider}; interactive setup discovers models through the selected Runner.`);
1089
+ }
1090
+ function legacyRunner(config) {
1091
+ if (!config.runner)
1092
+ throw new Error("no runner profiles are configured");
1093
+ const { env, ...spec } = config.runner;
1094
+ return new ProcessRunner({ ...spec, envSpec: env, cwd: configRoot(config) });
1095
+ }
1096
+ function requiredEnv(env, name) {
1097
+ const value = env[name];
1098
+ if (!value)
1099
+ throw new Error(`${name} is missing`);
1100
+ return value;
1101
+ }
1102
+ function nearestExisting(path) {
1103
+ let current = resolve2(path);
1104
+ while (!existsSync3(current)) {
1105
+ const parent = dirname2(current);
1106
+ if (parent === current)
1107
+ break;
1108
+ current = parent;
1109
+ }
1110
+ return current;
1111
+ }
1112
+ function defaultStateDir(directory) {
1113
+ const id = createHash2("sha256").update(resolve2(directory)).digest("hex").slice(0, 16);
1114
+ return join4(process.env.GOAH_STATE_HOME ?? join4(homedir2(), ".goah", "state"), id);
1115
+ }
1116
+ function field(value, key) {
1117
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value[key] : void 0;
1118
+ }
1119
+ function assistantTokens(value) {
1120
+ const message = field(value, "message");
1121
+ if (field(message, "role") !== "assistant")
1122
+ return 0;
1123
+ const usage = field(message, "usage");
1124
+ const total = field(usage, "totalTokens");
1125
+ return typeof total === "number" ? total : 0;
1126
+ }
1127
+ function resolveCommand(command) {
1128
+ return command === "$NODE" ? process.execPath : command;
1129
+ }
1130
+ function absolutePath(base, value) {
1131
+ return isAbsolute(value) ? value : resolve2(base, value);
1132
+ }
1133
+ function alive(pid) {
1134
+ try {
1135
+ process.kill(pid, 0);
1136
+ return true;
1137
+ } catch {
1138
+ return false;
1139
+ }
1140
+ }
1141
+ function configRoot(config) {
1142
+ return configRoots.get(config) ?? process.cwd();
1143
+ }
1144
+
1145
+ export {
1146
+ listThreads,
1147
+ showThread,
1148
+ replayThread,
1149
+ showTurnContext,
1150
+ streamEvents,
1151
+ exportThread,
1152
+ redactValue,
1153
+ installedVersion,
1154
+ runUpdate,
1155
+ controlEndpoint,
1156
+ runControlServer,
1157
+ requestControl,
1158
+ streamControl,
1159
+ controlAvailable,
1160
+ consoleMetadataPath,
1161
+ readConsoleMetadata,
1162
+ consoleSnapshot,
1163
+ organizationTrajectory,
1164
+ runWebConsole,
1165
+ loadConfig,
1166
+ createRuntime,
1167
+ defaultConfig,
1168
+ SupervisorLock,
1169
+ writeDefaultConfig,
1170
+ profilePath,
1171
+ readDefaultRunnerProfile,
1172
+ writeDefaultRunnerProfile,
1173
+ updateWorkspaceRunnerProfile,
1174
+ persistRunnerProfile,
1175
+ diagnoseConfig,
1176
+ statusSnapshot,
1177
+ configRoot
1178
+ };