chorus-codes 0.7.0 → 0.7.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 (293) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/cache/.previewinfo +1 -1
  4. package/.next/cache/.rscinfo +1 -1
  5. package/.next/cache/.tsbuildinfo +1 -1
  6. package/.next/fallback-build-manifest.json +3 -3
  7. package/.next/prerender-manifest.json +3 -3
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/server/app/_not-found.html +1 -1
  16. package/.next/server/app/_not-found.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/server/app/new.html +1 -1
  24. package/.next/server/app/new.rsc +1 -1
  25. package/.next/server/app/new.segments/_full.segment.rsc +1 -1
  26. package/.next/server/app/new.segments/_head.segment.rsc +1 -1
  27. package/.next/server/app/new.segments/_index.segment.rsc +1 -1
  28. package/.next/server/app/new.segments/_tree.segment.rsc +1 -1
  29. package/.next/server/app/new.segments/new/__PAGE__.segment.rsc +1 -1
  30. package/.next/server/app/new.segments/new.segment.rsc +1 -1
  31. package/.next/server/app/onboarding.html +1 -1
  32. package/.next/server/app/onboarding.rsc +1 -1
  33. package/.next/server/app/onboarding.segments/_full.segment.rsc +1 -1
  34. package/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
  35. package/.next/server/app/onboarding.segments/_index.segment.rsc +1 -1
  36. package/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
  37. package/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
  38. package/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
  39. package/.next/server/app/personas.html +1 -1
  40. package/.next/server/app/personas.rsc +1 -1
  41. package/.next/server/app/personas.segments/_full.segment.rsc +1 -1
  42. package/.next/server/app/personas.segments/_head.segment.rsc +1 -1
  43. package/.next/server/app/personas.segments/_index.segment.rsc +1 -1
  44. package/.next/server/app/personas.segments/_tree.segment.rsc +1 -1
  45. package/.next/server/app/personas.segments/personas/__PAGE__.segment.rsc +1 -1
  46. package/.next/server/app/personas.segments/personas.segment.rsc +1 -1
  47. package/.next/server/app/settings.html +1 -1
  48. package/.next/server/app/settings.rsc +1 -1
  49. package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  50. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  51. package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  52. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  53. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  54. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  55. package/.next/server/app/templates.html +1 -1
  56. package/.next/server/app/templates.rsc +1 -1
  57. package/.next/server/app/templates.segments/_full.segment.rsc +1 -1
  58. package/.next/server/app/templates.segments/_head.segment.rsc +1 -1
  59. package/.next/server/app/templates.segments/_index.segment.rsc +1 -1
  60. package/.next/server/app/templates.segments/_tree.segment.rsc +1 -1
  61. package/.next/server/app/templates.segments/templates/__PAGE__.segment.rsc +1 -1
  62. package/.next/server/app/templates.segments/templates.segment.rsc +1 -1
  63. package/.next/server/middleware-build-manifest.js +3 -3
  64. package/.next/server/pages/404.html +1 -1
  65. package/.next/server/pages/500.html +1 -1
  66. package/.next/server/server-reference-manifest.js +1 -1
  67. package/.next/server/server-reference-manifest.json +1 -1
  68. package/.next/trace +1 -1
  69. package/.next/trace-build +1 -1
  70. package/README.md +38 -15
  71. package/dist/cli/commands/doctor.js +116 -0
  72. package/dist/cli/commands/doctor.js.map +1 -0
  73. package/dist/cli/commands/init.js +211 -0
  74. package/dist/cli/commands/init.js.map +1 -0
  75. package/dist/cli/commands/start.js +298 -0
  76. package/dist/cli/commands/start.js.map +1 -0
  77. package/dist/cli/commands/status.js +54 -0
  78. package/dist/cli/commands/status.js.map +1 -0
  79. package/dist/cli/commands/stop.js +97 -0
  80. package/dist/cli/commands/stop.js.map +1 -0
  81. package/dist/cli/connect.js +108 -0
  82. package/dist/cli/connect.js.map +1 -0
  83. package/dist/cli/index.js +99 -0
  84. package/dist/cli/index.js.map +1 -0
  85. package/dist/cli/port-utils.js +260 -0
  86. package/dist/cli/port-utils.js.map +1 -0
  87. package/dist/cli/runtime-env.js +60 -0
  88. package/dist/cli/runtime-env.js.map +1 -0
  89. package/dist/cli/shared.js +54 -0
  90. package/dist/cli/shared.js.map +1 -0
  91. package/dist/cli/ui.js +60 -0
  92. package/dist/cli/ui.js.map +1 -0
  93. package/dist/daemon/agents/claude.js +98 -0
  94. package/dist/daemon/agents/claude.js.map +1 -0
  95. package/dist/daemon/agents/codex.js +160 -0
  96. package/dist/daemon/agents/codex.js.map +1 -0
  97. package/dist/daemon/agents/gemini.js +111 -0
  98. package/dist/daemon/agents/gemini.js.map +1 -0
  99. package/dist/daemon/agents/index.js +59 -0
  100. package/dist/daemon/agents/index.js.map +1 -0
  101. package/dist/daemon/agents/kimi.js +206 -0
  102. package/dist/daemon/agents/kimi.js.map +1 -0
  103. package/dist/daemon/agents/opencode.js +228 -0
  104. package/dist/daemon/agents/opencode.js.map +1 -0
  105. package/dist/daemon/agents/openrouter.js +274 -0
  106. package/dist/daemon/agents/openrouter.js.map +1 -0
  107. package/dist/daemon/agents/parsers/claude.js +63 -0
  108. package/dist/daemon/agents/parsers/claude.js.map +1 -0
  109. package/dist/daemon/agents/parsers/codex.js +51 -0
  110. package/dist/daemon/agents/parsers/codex.js.map +1 -0
  111. package/dist/daemon/agents/parsers/gemini.js +144 -0
  112. package/dist/daemon/agents/parsers/gemini.js.map +1 -0
  113. package/dist/daemon/agents/parsers/index.js +31 -0
  114. package/dist/daemon/agents/parsers/index.js.map +1 -0
  115. package/dist/daemon/agents/parsers/kimi.js +8 -0
  116. package/dist/daemon/agents/parsers/kimi.js.map +1 -0
  117. package/dist/daemon/agents/parsers/opencode.js +105 -0
  118. package/dist/daemon/agents/parsers/opencode.js.map +1 -0
  119. package/dist/daemon/agents/parsers/openrouter.js +69 -0
  120. package/dist/daemon/agents/parsers/openrouter.js.map +1 -0
  121. package/dist/daemon/agents/parsers/shared.js +17 -0
  122. package/dist/daemon/agents/parsers/shared.js.map +1 -0
  123. package/dist/daemon/agents/preflight.js +83 -0
  124. package/dist/daemon/agents/preflight.js.map +1 -0
  125. package/dist/daemon/agents/quote.js +45 -0
  126. package/dist/daemon/agents/quote.js.map +1 -0
  127. package/dist/daemon/agents/sandbox-guard.js +69 -0
  128. package/dist/daemon/agents/sandbox-guard.js.map +1 -0
  129. package/dist/daemon/agents/types.js +6 -0
  130. package/dist/daemon/agents/types.js.map +1 -0
  131. package/dist/daemon/api-response.js +65 -0
  132. package/dist/daemon/api-response.js.map +1 -0
  133. package/dist/daemon/error-detector.js +329 -0
  134. package/dist/daemon/error-detector.js.map +1 -0
  135. package/dist/daemon/headless.js +533 -0
  136. package/dist/daemon/headless.js.map +1 -0
  137. package/dist/daemon/index.js +333 -0
  138. package/dist/daemon/index.js.map +1 -0
  139. package/dist/daemon/openrouter.js +192 -0
  140. package/dist/daemon/openrouter.js.map +1 -0
  141. package/dist/daemon/orchestrators/claude.js +163 -0
  142. package/dist/daemon/orchestrators/claude.js.map +1 -0
  143. package/dist/daemon/orchestrators/codex.js +101 -0
  144. package/dist/daemon/orchestrators/codex.js.map +1 -0
  145. package/dist/daemon/orchestrators/cursor-windsurf.js +118 -0
  146. package/dist/daemon/orchestrators/cursor-windsurf.js.map +1 -0
  147. package/dist/daemon/orchestrators/gemini.js +108 -0
  148. package/dist/daemon/orchestrators/gemini.js.map +1 -0
  149. package/dist/daemon/orchestrators/index.js +90 -0
  150. package/dist/daemon/orchestrators/index.js.map +1 -0
  151. package/dist/daemon/orchestrators/kimi.js +108 -0
  152. package/dist/daemon/orchestrators/kimi.js.map +1 -0
  153. package/dist/daemon/orchestrators/opencode.js +152 -0
  154. package/dist/daemon/orchestrators/opencode.js.map +1 -0
  155. package/dist/daemon/orchestrators/shared.js +60 -0
  156. package/dist/daemon/orchestrators/shared.js.map +1 -0
  157. package/dist/daemon/output-watcher.js +131 -0
  158. package/dist/daemon/output-watcher.js.map +1 -0
  159. package/dist/daemon/participant-aborts.js +123 -0
  160. package/dist/daemon/participant-aborts.js.map +1 -0
  161. package/dist/daemon/reaper.js +46 -0
  162. package/dist/daemon/reaper.js.map +1 -0
  163. package/dist/daemon/routes/chats-events.js +62 -0
  164. package/dist/daemon/routes/chats-events.js.map +1 -0
  165. package/dist/daemon/routes/chats-stream.js +241 -0
  166. package/dist/daemon/routes/chats-stream.js.map +1 -0
  167. package/dist/daemon/routes/chats-validation.js +13 -0
  168. package/dist/daemon/routes/chats-validation.js.map +1 -0
  169. package/dist/daemon/routes/chats.js +545 -0
  170. package/dist/daemon/routes/chats.js.map +1 -0
  171. package/dist/daemon/routes/openrouter.js +103 -0
  172. package/dist/daemon/routes/openrouter.js.map +1 -0
  173. package/dist/daemon/routes/settings.js +199 -0
  174. package/dist/daemon/routes/settings.js.map +1 -0
  175. package/dist/daemon/routes/stats.js +155 -0
  176. package/dist/daemon/routes/stats.js.map +1 -0
  177. package/dist/daemon/routes/system.js +208 -0
  178. package/dist/daemon/routes/system.js.map +1 -0
  179. package/dist/daemon/routes/templates-personas.js +254 -0
  180. package/dist/daemon/routes/templates-personas.js.map +1 -0
  181. package/dist/daemon/routes/voices.js +139 -0
  182. package/dist/daemon/routes/voices.js.map +1 -0
  183. package/dist/daemon/runner/doer-driver.js +346 -0
  184. package/dist/daemon/runner/doer-driver.js.map +1 -0
  185. package/dist/daemon/runner/doer.js +336 -0
  186. package/dist/daemon/runner/doer.js.map +1 -0
  187. package/dist/daemon/runner/prior-round.js +140 -0
  188. package/dist/daemon/runner/prior-round.js.map +1 -0
  189. package/dist/daemon/runner/prompt-builder.js +292 -0
  190. package/dist/daemon/runner/prompt-builder.js.map +1 -0
  191. package/dist/daemon/runner/review-only-phase.js +103 -0
  192. package/dist/daemon/runner/review-only-phase.js.map +1 -0
  193. package/dist/daemon/runner/reviewer-driver.js +410 -0
  194. package/dist/daemon/runner/reviewer-driver.js.map +1 -0
  195. package/dist/daemon/runner/reviewer.js +384 -0
  196. package/dist/daemon/runner/reviewer.js.map +1 -0
  197. package/dist/daemon/runner/run-with-fallback.js +56 -0
  198. package/dist/daemon/runner/run-with-fallback.js.map +1 -0
  199. package/dist/daemon/runner/sanitize-name.js +8 -0
  200. package/dist/daemon/runner/sanitize-name.js.map +1 -0
  201. package/dist/daemon/runner/stream-file-writer.js +116 -0
  202. package/dist/daemon/runner/stream-file-writer.js.map +1 -0
  203. package/dist/daemon/runner/swap-sidecar.js +102 -0
  204. package/dist/daemon/runner/swap-sidecar.js.map +1 -0
  205. package/dist/daemon/runner/template-fallback.js +119 -0
  206. package/dist/daemon/runner/template-fallback.js.map +1 -0
  207. package/dist/daemon/runner/types.js +3 -0
  208. package/dist/daemon/runner/types.js.map +1 -0
  209. package/dist/daemon/runner/verdict.js +51 -0
  210. package/dist/daemon/runner/verdict.js.map +1 -0
  211. package/dist/daemon/runner-multiplex.js +364 -0
  212. package/dist/daemon/runner-multiplex.js.map +1 -0
  213. package/dist/daemon/runner.js +427 -0
  214. package/dist/daemon/runner.js.map +1 -0
  215. package/dist/daemon/ship.js +340 -0
  216. package/dist/daemon/ship.js.map +1 -0
  217. package/dist/daemon/template-cache.js +37 -0
  218. package/dist/daemon/template-cache.js.map +1 -0
  219. package/dist/daemon/tmux-types.js +9 -0
  220. package/dist/daemon/tmux-types.js.map +1 -0
  221. package/dist/daemon/tmux.js +341 -0
  222. package/dist/daemon/tmux.js.map +1 -0
  223. package/dist/lib/atomic-write.js +55 -0
  224. package/dist/lib/atomic-write.js.map +1 -0
  225. package/dist/lib/chat-events-bus.js +27 -0
  226. package/dist/lib/chat-events-bus.js.map +1 -0
  227. package/dist/lib/chat-slug.js +105 -0
  228. package/dist/lib/chat-slug.js.map +1 -0
  229. package/dist/lib/cli-detect.js +388 -0
  230. package/dist/lib/cli-detect.js.map +1 -0
  231. package/dist/lib/cli-health.js +156 -0
  232. package/dist/lib/cli-health.js.map +1 -0
  233. package/dist/lib/cli-paths.js +113 -0
  234. package/dist/lib/cli-paths.js.map +1 -0
  235. package/dist/lib/cli-precheck.js +141 -0
  236. package/dist/lib/cli-precheck.js.map +1 -0
  237. package/dist/lib/db/chats.js +244 -0
  238. package/dist/lib/db/chats.js.map +1 -0
  239. package/dist/lib/db/connection.js +254 -0
  240. package/dist/lib/db/connection.js.map +1 -0
  241. package/dist/lib/db/index.js +34 -0
  242. package/dist/lib/db/index.js.map +1 -0
  243. package/dist/lib/db/personas.js +65 -0
  244. package/dist/lib/db/personas.js.map +1 -0
  245. package/dist/lib/db/phase-events.js +172 -0
  246. package/dist/lib/db/phase-events.js.map +1 -0
  247. package/dist/lib/db/secrets.js +53 -0
  248. package/dist/lib/db/secrets.js.map +1 -0
  249. package/dist/lib/db/settings.js +47 -0
  250. package/dist/lib/db/settings.js.map +1 -0
  251. package/dist/lib/db/templates.js +75 -0
  252. package/dist/lib/db/templates.js.map +1 -0
  253. package/dist/lib/db/voices.js +184 -0
  254. package/dist/lib/db/voices.js.map +1 -0
  255. package/dist/lib/lineage-maps.js +200 -0
  256. package/dist/lib/lineage-maps.js.map +1 -0
  257. package/dist/lib/logger.js +186 -0
  258. package/dist/lib/logger.js.map +1 -0
  259. package/dist/lib/personas.js +117 -0
  260. package/dist/lib/personas.js.map +1 -0
  261. package/dist/lib/runtime-path.js +222 -0
  262. package/dist/lib/runtime-path.js.map +1 -0
  263. package/dist/lib/settings/billing.js +58 -0
  264. package/dist/lib/settings/billing.js.map +1 -0
  265. package/dist/lib/settings/permissions.js +81 -0
  266. package/dist/lib/settings/permissions.js.map +1 -0
  267. package/dist/lib/settings/transport.js +113 -0
  268. package/dist/lib/settings/transport.js.map +1 -0
  269. package/dist/lib/telemetry.js +290 -0
  270. package/dist/lib/telemetry.js.map +1 -0
  271. package/dist/lib/template-schema.js +319 -0
  272. package/dist/lib/template-schema.js.map +1 -0
  273. package/dist/lib/template-validation.js +82 -0
  274. package/dist/lib/template-validation.js.map +1 -0
  275. package/dist/lib/voices.js +533 -0
  276. package/dist/lib/voices.js.map +1 -0
  277. package/dist/mcp/client.js +138 -0
  278. package/dist/mcp/client.js.map +1 -0
  279. package/dist/mcp/index.js +178 -0
  280. package/dist/mcp/index.js.map +1 -0
  281. package/dist/mcp/tools.js +355 -0
  282. package/dist/mcp/tools.js.map +1 -0
  283. package/package.json +2 -1
  284. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js +0 -6077
  285. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js.map +0 -69
  286. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js +0 -6318
  287. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js.map +0 -71
  288. package/.next/dev/types/cache-life.d.ts +0 -145
  289. package/.next/dev/types/routes.d.ts +0 -84
  290. package/.next/dev/types/validator.ts +0 -178
  291. /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_buildManifest.js +0 -0
  292. /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_clientMiddlewareManifest.js +0 -0
  293. /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_ssgManifest.js +0 -0
@@ -0,0 +1,533 @@
1
+ "use strict";
2
+ /**
3
+ * Headless transport — spawn helpers, timeout/abort enforcement, heartbeat,
4
+ * and orphan cleanup. Used by every shim's `runHeadless` implementation.
5
+ *
6
+ * Why this module exists:
7
+ * - tmux holds a TUI process resident (~200-500MB per CLI). 3 reviewers in
8
+ * parallel = 1-1.5GB just sitting there. Headless drops that to zero
9
+ * between rounds (process spawns, runs, exits).
10
+ * - Pane-scraping regex is fragile. Stream-json events are structured.
11
+ * - Permission dialogs mostly disappear in headless mode (CLIs auto-approve).
12
+ *
13
+ * Stuck-process safety (CRITICAL):
14
+ * - Every spawn enforces `timeoutMs` (default 10min) — SIGTERM on timeout,
15
+ * SIGKILL after 5s grace.
16
+ * - AbortSignal does the same kill sequence.
17
+ * - Daemon-startup reaper sweeps for orphan PIDs from prior runs (chats
18
+ * marked drafting/reviewing whose subprocesses outlived a daemon restart).
19
+ * - Without these, a hung CLI burns paid API tokens forever.
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.setSpawnPath = setSpawnPath;
56
+ exports.getSpawnPath = getSpawnPath;
57
+ exports.reapOrphanProcesses = reapOrphanProcesses;
58
+ exports.spawnHeadless = spawnHeadless;
59
+ const child_process_1 = require("child_process");
60
+ const fs = __importStar(require("fs"));
61
+ const os = __importStar(require("os"));
62
+ const path = __importStar(require("path"));
63
+ const cli_paths_js_1 = require("../lib/cli-paths.js");
64
+ /**
65
+ * Cached merged PATH for subprocess spawns. Populated by the daemon
66
+ * boot path via `primeRuntimePath()`. Synchronous reads only — spawn
67
+ * sites can't await. When unset (tests, pre-prime spawns) we fall back
68
+ * to process.env.PATH unchanged, matching pre-fix behaviour.
69
+ *
70
+ * Composition (front-to-back, dedup):
71
+ * 1. process.env.PATH — daemon's own runtime
72
+ * 2. captured interactive PATH — what the user's terminal sees
73
+ * 3. known install dirs that exist — ~/.opencode/bin etc.
74
+ * 4. saved manual cli_paths' dirnames — custom-location binaries
75
+ *
76
+ * See src/lib/runtime-path.ts for the builder used at prime time.
77
+ */
78
+ let cachedSpawnPath = null;
79
+ function setSpawnPath(merged) {
80
+ cachedSpawnPath = merged;
81
+ }
82
+ function getSpawnPath() {
83
+ return cachedSpawnPath;
84
+ }
85
+ function spawnEnv(extra) {
86
+ const base = { ...process.env, ...(extra ?? {}) };
87
+ // Caller-supplied env wins if it explicitly sets PATH (rare; tests).
88
+ if (extra?.PATH)
89
+ return base;
90
+ if (cachedSpawnPath)
91
+ base.PATH = cachedSpawnPath;
92
+ // Belt-and-braces: prepend any cached manual-path dirs that aren't
93
+ // already in the merged PATH. Covers "save endpoint ran after prime"
94
+ // — refreshCache stuffs new entries; we re-prepend at spawn time
95
+ // without forcing the daemon to re-run the full prime sequence.
96
+ const dirs = cli_paths_js_1.cliPaths.cachedDirs();
97
+ if (dirs.length > 0) {
98
+ const existing = (base.PATH ?? '').split(path.delimiter);
99
+ const missing = dirs.filter((d) => d && !existing.includes(d));
100
+ if (missing.length > 0) {
101
+ base.PATH = [...missing, ...existing].filter((p) => p).join(path.delimiter);
102
+ }
103
+ }
104
+ return base;
105
+ }
106
+ const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
107
+ const KILL_GRACE_MS = 5_000; // SIGKILL after SIGTERM + 5s
108
+ const HEARTBEAT_INTERVAL_MS = 5_000; // progress event for non-streaming CLIs
109
+ /**
110
+ * Where we persist child PIDs across daemon restarts so the reaper can find
111
+ * orphans. One file per spawn, deleted on clean exit.
112
+ */
113
+ const PID_DIR = path.join(os.homedir(), '.chorus', 'pids');
114
+ function ensurePidDir() {
115
+ if (!fs.existsSync(PID_DIR))
116
+ fs.mkdirSync(PID_DIR, { recursive: true });
117
+ }
118
+ function pidFilePath(pid) {
119
+ return path.join(PID_DIR, `${pid}.json`);
120
+ }
121
+ /**
122
+ * Register a child PID on disk so the reaper can clean it up if the daemon
123
+ * crashes. Called from spawn helpers below; matched by `unregisterPid` on
124
+ * clean exit.
125
+ */
126
+ function registerPid(rec) {
127
+ ensurePidDir();
128
+ try {
129
+ fs.writeFileSync(pidFilePath(rec.pid), JSON.stringify(rec), 'utf-8');
130
+ }
131
+ catch {
132
+ // Best-effort — failing to register doesn't block the spawn.
133
+ }
134
+ }
135
+ function unregisterPid(pid) {
136
+ try {
137
+ fs.unlinkSync(pidFilePath(pid));
138
+ }
139
+ catch {
140
+ // Already gone, fine.
141
+ }
142
+ }
143
+ function processIsAlive(pid) {
144
+ try {
145
+ process.kill(pid, 0);
146
+ return true;
147
+ }
148
+ catch {
149
+ return false;
150
+ }
151
+ }
152
+ /**
153
+ * Daemon-startup reaper. Walks PID_DIR, kills any process that's still alive
154
+ * (orphan from a prior daemon crash), and clears the records.
155
+ *
156
+ * Call once from the daemon's bootstrap before accepting requests. Without
157
+ * this, a daemon crash mid-run leaves child CLIs alive — they'll keep
158
+ * burning subscription quota or API tokens until manually killed.
159
+ */
160
+ function reapOrphanProcesses() {
161
+ if (!fs.existsSync(PID_DIR))
162
+ return { reaped: 0, cleared: 0 };
163
+ let reaped = 0;
164
+ let cleared = 0;
165
+ for (const entry of fs.readdirSync(PID_DIR)) {
166
+ if (!entry.endsWith('.json'))
167
+ continue;
168
+ const recordPath = path.join(PID_DIR, entry);
169
+ try {
170
+ const rec = JSON.parse(fs.readFileSync(recordPath, 'utf-8'));
171
+ // Check if the process is still alive.
172
+ if (processIsAlive(rec.pid)) {
173
+ // Still alive — orphan. Send SIGTERM.
174
+ try {
175
+ process.kill(rec.pid, 'SIGTERM');
176
+ }
177
+ catch {
178
+ /* ignore */
179
+ }
180
+ // Schedule SIGKILL after grace; use unref so it doesn't block exit.
181
+ const t = setTimeout(() => {
182
+ try {
183
+ process.kill(rec.pid, 'SIGKILL');
184
+ }
185
+ catch {
186
+ // already gone
187
+ }
188
+ }, KILL_GRACE_MS);
189
+ t.unref();
190
+ reaped++;
191
+ // IMPORTANT: Do not unlink the record yet. If daemon crashes during
192
+ // the grace period, the PID record stays on disk for next startup.
193
+ // The next reaper run will find it and try again.
194
+ }
195
+ else {
196
+ // Process already dead — safe to clear the record.
197
+ cleared++;
198
+ try {
199
+ fs.unlinkSync(recordPath);
200
+ }
201
+ catch {
202
+ /* ignore */
203
+ }
204
+ }
205
+ }
206
+ catch {
207
+ // Malformed record — drop it.
208
+ try {
209
+ fs.unlinkSync(recordPath);
210
+ }
211
+ catch {
212
+ /* ignore */
213
+ }
214
+ }
215
+ }
216
+ return { reaped, cleared };
217
+ }
218
+ /**
219
+ * Spawn a headless CLI subprocess and yield AgentEvents from its stdout.
220
+ *
221
+ * Lifecycle:
222
+ * 1. Spawn child + register PID for orphan reaper
223
+ * 2. Pipe stdinPayload (if any), close stdin
224
+ * 3. Stream stdout line-by-line through parseLine → events queue
225
+ * 4. Emit progress heartbeats if enabled
226
+ * 5. On exit: emit onExit(fullStdout) events, then close iterator
227
+ * 6. On abort/timeout: SIGTERM, then SIGKILL after KILL_GRACE_MS
228
+ * 7. unregister PID on any exit path
229
+ */
230
+ function spawnHeadless(opts) {
231
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
232
+ const startedAt = Date.now();
233
+ const child = (0, child_process_1.spawn)(opts.command, [...opts.args], {
234
+ cwd: opts.cwd,
235
+ env: spawnEnv(opts.env),
236
+ stdio: ['pipe', 'pipe', 'pipe'],
237
+ });
238
+ if (child.pid !== undefined) {
239
+ registerPid({
240
+ pid: child.pid,
241
+ cli: opts.cli,
242
+ chatId: opts.chatId,
243
+ startedAt,
244
+ cwd: opts.cwd,
245
+ });
246
+ }
247
+ else {
248
+ console.warn(`[headless] spawn succeeded but child.pid is undefined (cli=${opts.cli})`);
249
+ }
250
+ // Buffer of pending events for the async iterator. We push from stdout
251
+ // listener / heartbeat / exit; the iterator's `next()` drains.
252
+ const queue = [];
253
+ let queueResolver = null;
254
+ let closed = false;
255
+ const enqueue = (e) => {
256
+ queue.push(e);
257
+ if (queueResolver) {
258
+ const r = queueResolver;
259
+ queueResolver = null;
260
+ r();
261
+ }
262
+ };
263
+ const closeQueue = () => {
264
+ closed = true;
265
+ if (queueResolver) {
266
+ const r = queueResolver;
267
+ queueResolver = null;
268
+ r();
269
+ }
270
+ };
271
+ // ─── stdin payload ─────────────────────────────────────────────────────
272
+ if (opts.stdinPayload !== undefined) {
273
+ try {
274
+ child.stdin.write(opts.stdinPayload);
275
+ child.stdin.end();
276
+ }
277
+ catch {
278
+ // child may have died before stdin pipe ready
279
+ }
280
+ }
281
+ else {
282
+ // Always close stdin to unblock CLIs that block on EOF
283
+ try {
284
+ child.stdin.end();
285
+ }
286
+ catch {
287
+ /* ignore */
288
+ }
289
+ }
290
+ // ─── stdout / stderr accumulators ──────────────────────────────────────
291
+ //
292
+ // fullStdout + fullStderr buffer the entire CLI output for `onExit` callers
293
+ // (codex/opencode emit one final blob, parsed at exit) and for the tail
294
+ // diagnostic on hangs (lines 391–392 below). A pathological CLI streaming
295
+ // unparsed output forever would otherwise grow these strings unbounded
296
+ // until the daemon OOMs. Cap each at MAX_FULL_BUFFER_BYTES; once exceeded
297
+ // we keep accumulating *for parsing* via stdoutBuf (line-mode), but stop
298
+ // appending to the full-text accumulator and set a truncation flag the
299
+ // exit path surfaces in error events.
300
+ const MAX_FULL_BUFFER_BYTES = 10 * 1024 * 1024; // 10 MB
301
+ let stdoutBuf = '';
302
+ let fullStdout = '';
303
+ let stdoutTruncated = false;
304
+ let fullStderr = '';
305
+ let stderrTruncated = false;
306
+ child.stdout.setEncoding('utf-8');
307
+ child.stdout.on('data', (chunk) => {
308
+ if (!stdoutTruncated) {
309
+ if (Buffer.byteLength(fullStdout, 'utf-8') + Buffer.byteLength(chunk, 'utf-8') > MAX_FULL_BUFFER_BYTES) {
310
+ stdoutTruncated = true;
311
+ }
312
+ else {
313
+ fullStdout += chunk;
314
+ }
315
+ }
316
+ stdoutBuf += chunk;
317
+ let nl;
318
+ while ((nl = stdoutBuf.indexOf('\n')) !== -1) {
319
+ const line = stdoutBuf.slice(0, nl);
320
+ stdoutBuf = stdoutBuf.slice(nl + 1);
321
+ try {
322
+ for (const evt of opts.parseLine(line))
323
+ enqueue(evt);
324
+ }
325
+ catch (err) {
326
+ enqueue({
327
+ type: 'error',
328
+ kind: 'parse_error',
329
+ message: err instanceof Error ? err.message : String(err),
330
+ });
331
+ }
332
+ }
333
+ });
334
+ // ─── stderr (for error visibility, not parsing) ────────────────────────
335
+ child.stderr.setEncoding('utf-8');
336
+ child.stderr.on('data', (chunk) => {
337
+ if (stderrTruncated)
338
+ return;
339
+ if (Buffer.byteLength(fullStderr, 'utf-8') + Buffer.byteLength(chunk, 'utf-8') > MAX_FULL_BUFFER_BYTES) {
340
+ stderrTruncated = true;
341
+ return;
342
+ }
343
+ fullStderr += chunk;
344
+ });
345
+ // ─── heartbeat ─────────────────────────────────────────────────────────
346
+ let heartbeatHandle = null;
347
+ if (opts.heartbeat) {
348
+ heartbeatHandle = setInterval(() => {
349
+ if (closed)
350
+ return;
351
+ enqueue({ type: 'progress', elapsedMs: Date.now() - startedAt });
352
+ }, HEARTBEAT_INTERVAL_MS);
353
+ heartbeatHandle.unref();
354
+ }
355
+ // ─── timeout + abort kill plumbing ─────────────────────────────────────
356
+ let killReason;
357
+ const sigtermThenKill = (reason) => {
358
+ if (killReason)
359
+ return; // already killing
360
+ killReason = reason;
361
+ try {
362
+ child.kill('SIGTERM');
363
+ }
364
+ catch {
365
+ /* ignore */
366
+ }
367
+ const t = setTimeout(() => {
368
+ try {
369
+ child.kill('SIGKILL');
370
+ }
371
+ catch {
372
+ /* ignore */
373
+ }
374
+ }, KILL_GRACE_MS);
375
+ t.unref();
376
+ };
377
+ const timeoutHandle = setTimeout(() => {
378
+ sigtermThenKill('timeout');
379
+ }, timeoutMs);
380
+ timeoutHandle.unref();
381
+ const abortHandler = () => sigtermThenKill('aborted');
382
+ if (opts.abortSignal) {
383
+ if (opts.abortSignal.aborted) {
384
+ sigtermThenKill('aborted');
385
+ }
386
+ else {
387
+ opts.abortSignal.addEventListener('abort', abortHandler, { once: true });
388
+ }
389
+ }
390
+ // ─── exit ─────────────────────────────────────────────────────────────
391
+ const done = new Promise((resolve) => {
392
+ child.on('exit', (code) => {
393
+ clearTimeout(timeoutHandle);
394
+ if (heartbeatHandle)
395
+ clearInterval(heartbeatHandle);
396
+ if (opts.abortSignal) {
397
+ opts.abortSignal.removeEventListener('abort', abortHandler);
398
+ }
399
+ unregisterPid(child.pid ?? -1);
400
+ // Drain any trailing partial line through parser one more time.
401
+ if (stdoutBuf.length > 0) {
402
+ try {
403
+ for (const evt of opts.parseLine(stdoutBuf))
404
+ enqueue(evt);
405
+ }
406
+ catch {
407
+ /* parse errors at EOF aren't fatal */
408
+ }
409
+ stdoutBuf = '';
410
+ }
411
+ // Per-shim final emission (e.g. message_done from full output for
412
+ // one-shot CLIs). When the 10 MB accumulator cap was hit we MUST
413
+ // surface a partial-output warning — non-streaming CLIs (codex,
414
+ // opencode) feed fullStdout into onExit() to parse the final blob,
415
+ // and a truncated blob would parse as "complete" silently. The
416
+ // warning is independent of exit code: a "successful" run with a
417
+ // truncated diagnostic is still incomplete from the user's view.
418
+ if (stdoutTruncated || stderrTruncated) {
419
+ enqueue({
420
+ type: 'error',
421
+ kind: 'output_truncated',
422
+ message: `${opts.cli} output exceeded ${MAX_FULL_BUFFER_BYTES / (1024 * 1024)} MB cap; trailing data dropped. Final parse may be incomplete.`,
423
+ });
424
+ }
425
+ if (opts.onExit) {
426
+ try {
427
+ for (const evt of opts.onExit(fullStdout, fullStderr, code))
428
+ enqueue(evt);
429
+ }
430
+ catch {
431
+ /* ignore */
432
+ }
433
+ }
434
+ if (killReason && code !== 0) {
435
+ enqueue({
436
+ type: 'error',
437
+ kind: killReason,
438
+ message: killReason === 'timeout'
439
+ ? `CLI ${opts.cli} timed out after ${Math.round(timeoutMs / 1000)}s`
440
+ : `CLI ${opts.cli} cancelled`,
441
+ });
442
+ }
443
+ else if (code !== 0 && code !== null) {
444
+ // Process exited non-zero on its own — likely auth/config/quota.
445
+ // Surface BOTH stderr and stdout so the user sees an actionable
446
+ // message instead of a silent 0-byte answer.md. Some CLIs print
447
+ // their actual error to stdout (kimi: "LLM not set") and only
448
+ // bookkeeping info to stderr ("To resume this session: ..."), so
449
+ // checking both is non-optional. Trim to keep it terse.
450
+ const stderrTail = fullStderr.trim().slice(-300);
451
+ const stdoutTail = fullStdout.trim().slice(-300);
452
+ // Specialize the most common failure mode at launch — daemon
453
+ // spawned from a non-interactive shell, can't find the CLI on
454
+ // PATH. Bash exits 127 and prints "command not found" to one
455
+ // of the streams. Without this branch the generic `cli_failed`
456
+ // surfaces "opencode exited 127: bash: line 1: opencode: command
457
+ // not found", which is technically accurate but doesn't tell
458
+ // the user how to fix it. Emit `cli_not_in_path` instead with
459
+ // a doctor pointer.
460
+ const cmdNotFound = /command not found|: not found/i;
461
+ const isPathError = code === 127 || cmdNotFound.test(stderrTail) || cmdNotFound.test(stdoutTail);
462
+ if (isPathError) {
463
+ enqueue({
464
+ type: 'error',
465
+ kind: 'cli_not_in_path',
466
+ message: `${opts.cli} not found on the daemon's PATH. ` +
467
+ `Run 'chorus doctor' for a diagnosis, or set the path manually ` +
468
+ `via Settings → Connect a CLI → "I know where it is".`,
469
+ });
470
+ closeQueue();
471
+ resolve({ code, killed: Boolean(killReason), reason: killReason });
472
+ return;
473
+ }
474
+ const tails = [stdoutTail, stderrTail].filter((s) => s.length > 0).join(' | ');
475
+ // If we hit the 10 MB accumulator cap, the *leading* output is
476
+ // captured but the trailing part is dropped on the floor (we stop
477
+ // appending early to avoid OOM). Surface a short note so the user
478
+ // knows the diagnostic is partial; the full output, if needed, is
479
+ // recoverable via the per-round artifact files in the chat dir.
480
+ const truncationNote = stdoutTruncated || stderrTruncated
481
+ ? `[output truncated at ${MAX_FULL_BUFFER_BYTES / (1024 * 1024)}MB cap]`
482
+ : '';
483
+ const detail = [tails, truncationNote].filter((s) => s.length > 0).join(' ');
484
+ enqueue({
485
+ type: 'error',
486
+ kind: 'cli_failed',
487
+ message: detail.length > 0
488
+ ? `${opts.cli} exited ${code}: ${detail}`
489
+ : `${opts.cli} exited ${code} with no output`,
490
+ });
491
+ }
492
+ closeQueue();
493
+ resolve({ code, killed: Boolean(killReason), reason: killReason });
494
+ });
495
+ child.on('error', (err) => {
496
+ // ENOENT is the direct-spawn equivalent of bash's exit-127 — the
497
+ // binary literally isn't on the daemon's PATH. Surface the same
498
+ // doctor pointer as the bash-wrapped path-error branch above.
499
+ const enoent = err.code === 'ENOENT' ||
500
+ /ENOENT/.test(err.message);
501
+ enqueue({
502
+ type: 'error',
503
+ kind: enoent ? 'cli_not_in_path' : 'spawn_failed',
504
+ message: enoent
505
+ ? `${opts.cli} not found on the daemon's PATH (ENOENT: ${err.message}). ` +
506
+ `Run 'chorus doctor' or set the path manually via Settings.`
507
+ : err.message,
508
+ });
509
+ // 'exit' will follow with code=null
510
+ });
511
+ });
512
+ // ─── async iterator ────────────────────────────────────────────────────
513
+ const events = {
514
+ [Symbol.asyncIterator]() {
515
+ return {
516
+ async next() {
517
+ while (queue.length === 0 && !closed) {
518
+ await new Promise((resolve) => {
519
+ queueResolver = resolve;
520
+ });
521
+ }
522
+ if (queue.length > 0) {
523
+ const value = queue.shift();
524
+ return { value, done: false };
525
+ }
526
+ return { value: undefined, done: true };
527
+ },
528
+ };
529
+ },
530
+ };
531
+ return { pid: child.pid ?? -1, events, done };
532
+ }
533
+ //# sourceMappingURL=headless.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headless.js","sourceRoot":"","sources":["../../src/daemon/headless.ts"],"names":[],"mappings":"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"}