chorus-codes 0.7.0 → 0.7.1

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 (291) 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/fallback-build-manifest.json +3 -3
  6. package/.next/prerender-manifest.json +3 -3
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/server/app/_not-found.html +1 -1
  15. package/.next/server/app/_not-found.rsc +1 -1
  16. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  21. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  22. package/.next/server/app/new.html +1 -1
  23. package/.next/server/app/new.rsc +1 -1
  24. package/.next/server/app/new.segments/_full.segment.rsc +1 -1
  25. package/.next/server/app/new.segments/_head.segment.rsc +1 -1
  26. package/.next/server/app/new.segments/_index.segment.rsc +1 -1
  27. package/.next/server/app/new.segments/_tree.segment.rsc +1 -1
  28. package/.next/server/app/new.segments/new/__PAGE__.segment.rsc +1 -1
  29. package/.next/server/app/new.segments/new.segment.rsc +1 -1
  30. package/.next/server/app/onboarding.html +1 -1
  31. package/.next/server/app/onboarding.rsc +1 -1
  32. package/.next/server/app/onboarding.segments/_full.segment.rsc +1 -1
  33. package/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
  34. package/.next/server/app/onboarding.segments/_index.segment.rsc +1 -1
  35. package/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
  36. package/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
  37. package/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
  38. package/.next/server/app/personas.html +1 -1
  39. package/.next/server/app/personas.rsc +1 -1
  40. package/.next/server/app/personas.segments/_full.segment.rsc +1 -1
  41. package/.next/server/app/personas.segments/_head.segment.rsc +1 -1
  42. package/.next/server/app/personas.segments/_index.segment.rsc +1 -1
  43. package/.next/server/app/personas.segments/_tree.segment.rsc +1 -1
  44. package/.next/server/app/personas.segments/personas/__PAGE__.segment.rsc +1 -1
  45. package/.next/server/app/personas.segments/personas.segment.rsc +1 -1
  46. package/.next/server/app/settings.html +1 -1
  47. package/.next/server/app/settings.rsc +1 -1
  48. package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  49. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  50. package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  51. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  52. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  53. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  54. package/.next/server/app/templates.html +1 -1
  55. package/.next/server/app/templates.rsc +1 -1
  56. package/.next/server/app/templates.segments/_full.segment.rsc +1 -1
  57. package/.next/server/app/templates.segments/_head.segment.rsc +1 -1
  58. package/.next/server/app/templates.segments/_index.segment.rsc +1 -1
  59. package/.next/server/app/templates.segments/_tree.segment.rsc +1 -1
  60. package/.next/server/app/templates.segments/templates/__PAGE__.segment.rsc +1 -1
  61. package/.next/server/app/templates.segments/templates.segment.rsc +1 -1
  62. package/.next/server/middleware-build-manifest.js +3 -3
  63. package/.next/server/pages/404.html +1 -1
  64. package/.next/server/pages/500.html +1 -1
  65. package/.next/server/server-reference-manifest.js +1 -1
  66. package/.next/server/server-reference-manifest.json +1 -1
  67. package/.next/trace +1 -1
  68. package/.next/trace-build +1 -1
  69. package/dist/cli/commands/doctor.js +116 -0
  70. package/dist/cli/commands/doctor.js.map +1 -0
  71. package/dist/cli/commands/init.js +211 -0
  72. package/dist/cli/commands/init.js.map +1 -0
  73. package/dist/cli/commands/start.js +240 -0
  74. package/dist/cli/commands/start.js.map +1 -0
  75. package/dist/cli/commands/status.js +54 -0
  76. package/dist/cli/commands/status.js.map +1 -0
  77. package/dist/cli/commands/stop.js +97 -0
  78. package/dist/cli/commands/stop.js.map +1 -0
  79. package/dist/cli/connect.js +108 -0
  80. package/dist/cli/connect.js.map +1 -0
  81. package/dist/cli/index.js +99 -0
  82. package/dist/cli/index.js.map +1 -0
  83. package/dist/cli/port-utils.js +260 -0
  84. package/dist/cli/port-utils.js.map +1 -0
  85. package/dist/cli/runtime-env.js +60 -0
  86. package/dist/cli/runtime-env.js.map +1 -0
  87. package/dist/cli/shared.js +54 -0
  88. package/dist/cli/shared.js.map +1 -0
  89. package/dist/cli/ui.js +60 -0
  90. package/dist/cli/ui.js.map +1 -0
  91. package/dist/daemon/agents/claude.js +98 -0
  92. package/dist/daemon/agents/claude.js.map +1 -0
  93. package/dist/daemon/agents/codex.js +160 -0
  94. package/dist/daemon/agents/codex.js.map +1 -0
  95. package/dist/daemon/agents/gemini.js +111 -0
  96. package/dist/daemon/agents/gemini.js.map +1 -0
  97. package/dist/daemon/agents/index.js +59 -0
  98. package/dist/daemon/agents/index.js.map +1 -0
  99. package/dist/daemon/agents/kimi.js +206 -0
  100. package/dist/daemon/agents/kimi.js.map +1 -0
  101. package/dist/daemon/agents/opencode.js +228 -0
  102. package/dist/daemon/agents/opencode.js.map +1 -0
  103. package/dist/daemon/agents/openrouter.js +274 -0
  104. package/dist/daemon/agents/openrouter.js.map +1 -0
  105. package/dist/daemon/agents/parsers/claude.js +63 -0
  106. package/dist/daemon/agents/parsers/claude.js.map +1 -0
  107. package/dist/daemon/agents/parsers/codex.js +51 -0
  108. package/dist/daemon/agents/parsers/codex.js.map +1 -0
  109. package/dist/daemon/agents/parsers/gemini.js +144 -0
  110. package/dist/daemon/agents/parsers/gemini.js.map +1 -0
  111. package/dist/daemon/agents/parsers/index.js +31 -0
  112. package/dist/daemon/agents/parsers/index.js.map +1 -0
  113. package/dist/daemon/agents/parsers/kimi.js +8 -0
  114. package/dist/daemon/agents/parsers/kimi.js.map +1 -0
  115. package/dist/daemon/agents/parsers/opencode.js +105 -0
  116. package/dist/daemon/agents/parsers/opencode.js.map +1 -0
  117. package/dist/daemon/agents/parsers/openrouter.js +69 -0
  118. package/dist/daemon/agents/parsers/openrouter.js.map +1 -0
  119. package/dist/daemon/agents/parsers/shared.js +17 -0
  120. package/dist/daemon/agents/parsers/shared.js.map +1 -0
  121. package/dist/daemon/agents/preflight.js +83 -0
  122. package/dist/daemon/agents/preflight.js.map +1 -0
  123. package/dist/daemon/agents/quote.js +45 -0
  124. package/dist/daemon/agents/quote.js.map +1 -0
  125. package/dist/daemon/agents/sandbox-guard.js +69 -0
  126. package/dist/daemon/agents/sandbox-guard.js.map +1 -0
  127. package/dist/daemon/agents/types.js +6 -0
  128. package/dist/daemon/agents/types.js.map +1 -0
  129. package/dist/daemon/api-response.js +65 -0
  130. package/dist/daemon/api-response.js.map +1 -0
  131. package/dist/daemon/error-detector.js +329 -0
  132. package/dist/daemon/error-detector.js.map +1 -0
  133. package/dist/daemon/headless.js +533 -0
  134. package/dist/daemon/headless.js.map +1 -0
  135. package/dist/daemon/index.js +333 -0
  136. package/dist/daemon/index.js.map +1 -0
  137. package/dist/daemon/openrouter.js +192 -0
  138. package/dist/daemon/openrouter.js.map +1 -0
  139. package/dist/daemon/orchestrators/claude.js +163 -0
  140. package/dist/daemon/orchestrators/claude.js.map +1 -0
  141. package/dist/daemon/orchestrators/codex.js +101 -0
  142. package/dist/daemon/orchestrators/codex.js.map +1 -0
  143. package/dist/daemon/orchestrators/cursor-windsurf.js +118 -0
  144. package/dist/daemon/orchestrators/cursor-windsurf.js.map +1 -0
  145. package/dist/daemon/orchestrators/gemini.js +108 -0
  146. package/dist/daemon/orchestrators/gemini.js.map +1 -0
  147. package/dist/daemon/orchestrators/index.js +90 -0
  148. package/dist/daemon/orchestrators/index.js.map +1 -0
  149. package/dist/daemon/orchestrators/kimi.js +108 -0
  150. package/dist/daemon/orchestrators/kimi.js.map +1 -0
  151. package/dist/daemon/orchestrators/opencode.js +152 -0
  152. package/dist/daemon/orchestrators/opencode.js.map +1 -0
  153. package/dist/daemon/orchestrators/shared.js +60 -0
  154. package/dist/daemon/orchestrators/shared.js.map +1 -0
  155. package/dist/daemon/output-watcher.js +131 -0
  156. package/dist/daemon/output-watcher.js.map +1 -0
  157. package/dist/daemon/participant-aborts.js +123 -0
  158. package/dist/daemon/participant-aborts.js.map +1 -0
  159. package/dist/daemon/reaper.js +46 -0
  160. package/dist/daemon/reaper.js.map +1 -0
  161. package/dist/daemon/routes/chats-events.js +62 -0
  162. package/dist/daemon/routes/chats-events.js.map +1 -0
  163. package/dist/daemon/routes/chats-stream.js +241 -0
  164. package/dist/daemon/routes/chats-stream.js.map +1 -0
  165. package/dist/daemon/routes/chats-validation.js +13 -0
  166. package/dist/daemon/routes/chats-validation.js.map +1 -0
  167. package/dist/daemon/routes/chats.js +545 -0
  168. package/dist/daemon/routes/chats.js.map +1 -0
  169. package/dist/daemon/routes/openrouter.js +103 -0
  170. package/dist/daemon/routes/openrouter.js.map +1 -0
  171. package/dist/daemon/routes/settings.js +199 -0
  172. package/dist/daemon/routes/settings.js.map +1 -0
  173. package/dist/daemon/routes/stats.js +155 -0
  174. package/dist/daemon/routes/stats.js.map +1 -0
  175. package/dist/daemon/routes/system.js +208 -0
  176. package/dist/daemon/routes/system.js.map +1 -0
  177. package/dist/daemon/routes/templates-personas.js +254 -0
  178. package/dist/daemon/routes/templates-personas.js.map +1 -0
  179. package/dist/daemon/routes/voices.js +139 -0
  180. package/dist/daemon/routes/voices.js.map +1 -0
  181. package/dist/daemon/runner/doer-driver.js +346 -0
  182. package/dist/daemon/runner/doer-driver.js.map +1 -0
  183. package/dist/daemon/runner/doer.js +336 -0
  184. package/dist/daemon/runner/doer.js.map +1 -0
  185. package/dist/daemon/runner/prior-round.js +140 -0
  186. package/dist/daemon/runner/prior-round.js.map +1 -0
  187. package/dist/daemon/runner/prompt-builder.js +292 -0
  188. package/dist/daemon/runner/prompt-builder.js.map +1 -0
  189. package/dist/daemon/runner/review-only-phase.js +103 -0
  190. package/dist/daemon/runner/review-only-phase.js.map +1 -0
  191. package/dist/daemon/runner/reviewer-driver.js +410 -0
  192. package/dist/daemon/runner/reviewer-driver.js.map +1 -0
  193. package/dist/daemon/runner/reviewer.js +384 -0
  194. package/dist/daemon/runner/reviewer.js.map +1 -0
  195. package/dist/daemon/runner/run-with-fallback.js +56 -0
  196. package/dist/daemon/runner/run-with-fallback.js.map +1 -0
  197. package/dist/daemon/runner/sanitize-name.js +8 -0
  198. package/dist/daemon/runner/sanitize-name.js.map +1 -0
  199. package/dist/daemon/runner/stream-file-writer.js +116 -0
  200. package/dist/daemon/runner/stream-file-writer.js.map +1 -0
  201. package/dist/daemon/runner/swap-sidecar.js +102 -0
  202. package/dist/daemon/runner/swap-sidecar.js.map +1 -0
  203. package/dist/daemon/runner/template-fallback.js +119 -0
  204. package/dist/daemon/runner/template-fallback.js.map +1 -0
  205. package/dist/daemon/runner/types.js +3 -0
  206. package/dist/daemon/runner/types.js.map +1 -0
  207. package/dist/daemon/runner/verdict.js +51 -0
  208. package/dist/daemon/runner/verdict.js.map +1 -0
  209. package/dist/daemon/runner-multiplex.js +364 -0
  210. package/dist/daemon/runner-multiplex.js.map +1 -0
  211. package/dist/daemon/runner.js +427 -0
  212. package/dist/daemon/runner.js.map +1 -0
  213. package/dist/daemon/ship.js +340 -0
  214. package/dist/daemon/ship.js.map +1 -0
  215. package/dist/daemon/template-cache.js +37 -0
  216. package/dist/daemon/template-cache.js.map +1 -0
  217. package/dist/daemon/tmux-types.js +9 -0
  218. package/dist/daemon/tmux-types.js.map +1 -0
  219. package/dist/daemon/tmux.js +341 -0
  220. package/dist/daemon/tmux.js.map +1 -0
  221. package/dist/lib/atomic-write.js +55 -0
  222. package/dist/lib/atomic-write.js.map +1 -0
  223. package/dist/lib/chat-events-bus.js +27 -0
  224. package/dist/lib/chat-events-bus.js.map +1 -0
  225. package/dist/lib/chat-slug.js +105 -0
  226. package/dist/lib/chat-slug.js.map +1 -0
  227. package/dist/lib/cli-detect.js +388 -0
  228. package/dist/lib/cli-detect.js.map +1 -0
  229. package/dist/lib/cli-health.js +156 -0
  230. package/dist/lib/cli-health.js.map +1 -0
  231. package/dist/lib/cli-paths.js +113 -0
  232. package/dist/lib/cli-paths.js.map +1 -0
  233. package/dist/lib/cli-precheck.js +141 -0
  234. package/dist/lib/cli-precheck.js.map +1 -0
  235. package/dist/lib/db/chats.js +244 -0
  236. package/dist/lib/db/chats.js.map +1 -0
  237. package/dist/lib/db/connection.js +254 -0
  238. package/dist/lib/db/connection.js.map +1 -0
  239. package/dist/lib/db/index.js +34 -0
  240. package/dist/lib/db/index.js.map +1 -0
  241. package/dist/lib/db/personas.js +65 -0
  242. package/dist/lib/db/personas.js.map +1 -0
  243. package/dist/lib/db/phase-events.js +172 -0
  244. package/dist/lib/db/phase-events.js.map +1 -0
  245. package/dist/lib/db/secrets.js +53 -0
  246. package/dist/lib/db/secrets.js.map +1 -0
  247. package/dist/lib/db/settings.js +47 -0
  248. package/dist/lib/db/settings.js.map +1 -0
  249. package/dist/lib/db/templates.js +75 -0
  250. package/dist/lib/db/templates.js.map +1 -0
  251. package/dist/lib/db/voices.js +184 -0
  252. package/dist/lib/db/voices.js.map +1 -0
  253. package/dist/lib/lineage-maps.js +200 -0
  254. package/dist/lib/lineage-maps.js.map +1 -0
  255. package/dist/lib/logger.js +186 -0
  256. package/dist/lib/logger.js.map +1 -0
  257. package/dist/lib/personas.js +117 -0
  258. package/dist/lib/personas.js.map +1 -0
  259. package/dist/lib/runtime-path.js +222 -0
  260. package/dist/lib/runtime-path.js.map +1 -0
  261. package/dist/lib/settings/billing.js +58 -0
  262. package/dist/lib/settings/billing.js.map +1 -0
  263. package/dist/lib/settings/permissions.js +81 -0
  264. package/dist/lib/settings/permissions.js.map +1 -0
  265. package/dist/lib/settings/transport.js +113 -0
  266. package/dist/lib/settings/transport.js.map +1 -0
  267. package/dist/lib/telemetry.js +290 -0
  268. package/dist/lib/telemetry.js.map +1 -0
  269. package/dist/lib/template-schema.js +319 -0
  270. package/dist/lib/template-schema.js.map +1 -0
  271. package/dist/lib/template-validation.js +82 -0
  272. package/dist/lib/template-validation.js.map +1 -0
  273. package/dist/lib/voices.js +533 -0
  274. package/dist/lib/voices.js.map +1 -0
  275. package/dist/mcp/client.js +138 -0
  276. package/dist/mcp/client.js.map +1 -0
  277. package/dist/mcp/index.js +178 -0
  278. package/dist/mcp/index.js.map +1 -0
  279. package/dist/mcp/tools.js +355 -0
  280. package/dist/mcp/tools.js.map +1 -0
  281. package/package.json +2 -1
  282. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js +0 -6077
  283. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js.map +0 -69
  284. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js +0 -6318
  285. package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js.map +0 -71
  286. package/.next/dev/types/cache-life.d.ts +0 -145
  287. package/.next/dev/types/routes.d.ts +0 -84
  288. package/.next/dev/types/validator.ts +0 -178
  289. /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 8H2I8TTPlrKuWCV-SxY5f}/_buildManifest.js +0 -0
  290. /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 8H2I8TTPlrKuWCV-SxY5f}/_clientMiddlewareManifest.js +0 -0
  291. /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 8H2I8TTPlrKuWCV-SxY5f}/_ssgManifest.js +0 -0
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerStatusCommand = registerStatusCommand;
4
+ const shared_js_1 = require("../shared.js");
5
+ const ui_js_1 = require("../ui.js");
6
+ function registerStatusCommand(program) {
7
+ program
8
+ .command('status')
9
+ .description('Check daemon health')
10
+ .action(async () => {
11
+ try {
12
+ const response = await fetch(`${shared_js_1.DAEMON_URL}/api/v1/health`);
13
+ if (!response.ok) {
14
+ console.log('');
15
+ console.log((0, ui_js_1.header)(ui_js_1.sym.err, 'Daemon is not running', 'start with `chorus start`'));
16
+ console.log('');
17
+ process.exit(1);
18
+ }
19
+ const envelope = (await response.json());
20
+ const data = envelope.data;
21
+ if (envelope.ok && data) {
22
+ const uptime = Math.floor(data.uptime / 1000);
23
+ const human = uptime < 60
24
+ ? `${uptime}s`
25
+ : uptime < 3600
26
+ ? `${Math.floor(uptime / 60)}m`
27
+ : `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`;
28
+ console.log('');
29
+ console.log((0, ui_js_1.header)(ui_js_1.sym.ok, 'Chorus is running'));
30
+ console.log('');
31
+ console.log((0, ui_js_1.kv)([
32
+ ['Version', ui_js_1.c.cyan(data.version)],
33
+ ['Uptime', ui_js_1.c.dim(human)],
34
+ ['Cockpit', ui_js_1.c.cyan(shared_js_1.COCKPIT_URL)],
35
+ ['Daemon', ui_js_1.c.dim(shared_js_1.DAEMON_URL)],
36
+ ]));
37
+ console.log('');
38
+ }
39
+ else {
40
+ console.log('');
41
+ console.log((0, ui_js_1.header)(ui_js_1.sym.err, 'Daemon is not responding correctly'));
42
+ console.log('');
43
+ process.exit(1);
44
+ }
45
+ }
46
+ catch {
47
+ console.log('');
48
+ console.log((0, ui_js_1.header)(ui_js_1.sym.err, 'Daemon is not running', 'start with `chorus start`'));
49
+ console.log('');
50
+ process.exit(1);
51
+ }
52
+ });
53
+ }
54
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":";;AAIA,sDAyDC;AA5DD,4CAAuD;AACvD,oCAA8C;AAE9C,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qBAAqB,CAAC;SAClC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,sBAAU,gBAAgB,CAAC,CAAC;YAC5D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CACT,IAAA,cAAM,EAAC,WAAG,CAAC,GAAG,EAAE,uBAAuB,EAAE,2BAA2B,CAAC,CACtE,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,QAAQ,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAGtC,CAAC;YACF,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAE3B,IAAI,QAAQ,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;gBAC9C,MAAM,KAAK,GACT,MAAM,GAAG,EAAE;oBACT,CAAC,CAAC,GAAG,MAAM,GAAG;oBACd,CAAC,CAAC,MAAM,GAAG,IAAI;wBACb,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG;wBAC/B,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC;gBAC7E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAA,cAAM,EAAC,WAAG,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CACT,IAAA,UAAE,EAAC;oBACD,CAAC,SAAS,EAAE,SAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACjC,CAAC,QAAQ,EAAE,SAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBACxB,CAAC,SAAS,EAAE,SAAC,CAAC,IAAI,CAAC,uBAAW,CAAC,CAAC;oBAChC,CAAC,QAAQ,EAAE,SAAC,CAAC,GAAG,CAAC,sBAAU,CAAC,CAAC;iBAC9B,CAAC,CACH,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAA,cAAM,EAAC,WAAG,CAAC,GAAG,EAAE,oCAAoC,CAAC,CAAC,CAAC;gBACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CACT,IAAA,cAAM,EAAC,WAAG,CAAC,GAAG,EAAE,uBAAuB,EAAE,2BAA2B,CAAC,CACtE,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerStopCommand = registerStopCommand;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const port_utils_js_1 = require("../port-utils.js");
11
+ const ui_js_1 = require("../ui.js");
12
+ /**
13
+ * Two-stage shutdown per managed process: SIGTERM, wait up to 1.5s,
14
+ * escalate to SIGKILL if still alive. Don't unlink the pidfile until
15
+ * the process is confirmed dead — otherwise an orphan that ignores
16
+ * SIGTERM keeps running while we forget about it (the bug behind the
17
+ * "stale next-server serving 500s" incident on 2026-05-03).
18
+ *
19
+ * Belt-and-braces: after pidfile-based shutdown, also sweep ports
20
+ * :7707 (daemon) and :5050 (cockpit). Catches the case where the
21
+ * pidfile was lost or pointed at a recycled PID but a real chorus
22
+ * process still owns the port.
23
+ */
24
+ function registerStopCommand(program) {
25
+ program
26
+ .command('stop')
27
+ .description('Stop the Chorus daemon and cockpit')
28
+ .action(async () => {
29
+ try {
30
+ const chorusDir = path_1.default.join(os_1.default.homedir(), '.chorus');
31
+ const daemonPidFile = path_1.default.join(chorusDir, 'daemon.pid');
32
+ const webPidFile = path_1.default.join(chorusDir, 'web.pid');
33
+ const daemonPidfileExists = fs_1.default.existsSync(daemonPidFile);
34
+ const webPidfileExists = fs_1.default.existsSync(webPidFile);
35
+ const daemonPortInUse = await (0, port_utils_js_1.isPortInUse)(7707);
36
+ const cockpitPortInUse = await (0, port_utils_js_1.isPortInUse)(5050);
37
+ if (!daemonPidfileExists &&
38
+ !webPidfileExists &&
39
+ !daemonPortInUse &&
40
+ !cockpitPortInUse) {
41
+ console.log('');
42
+ console.log((0, ui_js_1.header)(ui_js_1.sym.info, 'Chorus is not running', 'nothing to stop'));
43
+ console.log('');
44
+ return;
45
+ }
46
+ console.log('');
47
+ console.log((0, ui_js_1.header)(ui_js_1.sym.pointer, 'Stopping Chorus...'));
48
+ console.log('');
49
+ await stopProcess('Daemon', daemonPidFile);
50
+ await stopProcess('Cockpit', webPidFile);
51
+ // Port-based sweep — kills any chorus-owned listener that
52
+ // escaped the pidfile path. Errs on the side of cleanup;
53
+ // running a non-chorus service on these ports while invoking
54
+ // `chorus stop` is unsupported.
55
+ await sweepPort(7707, 'Daemon');
56
+ await sweepPort(5050, 'Cockpit');
57
+ console.log('');
58
+ }
59
+ catch (error) {
60
+ console.error(`${ui_js_1.sym.err} ${ui_js_1.c.red('Error stopping chorus:')}`, error);
61
+ process.exit(1);
62
+ }
63
+ });
64
+ }
65
+ async function stopProcess(label, pidFile) {
66
+ if (!fs_1.default.existsSync(pidFile))
67
+ return;
68
+ const pid = parseInt(fs_1.default.readFileSync(pidFile, 'utf-8'), 10);
69
+ if (!Number.isFinite(pid) || pid <= 0) {
70
+ fs_1.default.unlinkSync(pidFile);
71
+ return;
72
+ }
73
+ const dead = await (0, port_utils_js_1.killAndVerify)(pid, label);
74
+ if (dead) {
75
+ console.log(` ${ui_js_1.sym.ok} ${label.padEnd(7)} ${ui_js_1.c.dim(`(PID ${pid})`)}`);
76
+ // Only unlink once we've confirmed the process is gone. Earlier
77
+ // code unconditionally unlinked, which orphaned any process that
78
+ // ignored SIGTERM — its successor `chorus start` couldn't see
79
+ // the ghost owner of the port.
80
+ try {
81
+ fs_1.default.unlinkSync(pidFile);
82
+ }
83
+ catch {
84
+ /* already gone */
85
+ }
86
+ }
87
+ }
88
+ async function sweepPort(port, label) {
89
+ const pids = (0, port_utils_js_1.findPidsOnPort)(port);
90
+ for (const pid of pids) {
91
+ const dead = await (0, port_utils_js_1.killAndVerify)(pid, `${label} orphan`);
92
+ if (dead) {
93
+ console.log(` ${ui_js_1.sym.ok} ${label.padEnd(7)} ${ui_js_1.c.dim(`(orphan PID ${pid} on :${port})`)}`);
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../src/cli/commands/stop.ts"],"names":[],"mappings":";;;;;AAuBA,kDA+CC;AArED,4CAAoB;AACpB,4CAAoB;AACpB,gDAAwB;AACxB,oDAI0B;AAC1B,oCAA0C;AAE1C;;;;;;;;;;;GAWG;AACH,SAAgB,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,oCAAoC,CAAC;SACjD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;YACrD,MAAM,aAAa,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YACzD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAEnD,MAAM,mBAAmB,GAAG,YAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YACzD,MAAM,gBAAgB,GAAG,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,eAAe,GAAG,MAAM,IAAA,2BAAW,EAAC,IAAI,CAAC,CAAC;YAChD,MAAM,gBAAgB,GAAG,MAAM,IAAA,2BAAW,EAAC,IAAI,CAAC,CAAC;YAEjD,IACE,CAAC,mBAAmB;gBACpB,CAAC,gBAAgB;gBACjB,CAAC,eAAe;gBAChB,CAAC,gBAAgB,EACjB,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAA,cAAM,EAAC,WAAG,CAAC,IAAI,EAAE,uBAAuB,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,IAAA,cAAM,EAAC,WAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;YAC3C,MAAM,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YAEzC,0DAA0D;YAC1D,yDAAyD;YACzD,6DAA6D;YAC7D,gCAAgC;YAChC,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAChC,MAAM,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAEjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,GAAG,WAAG,CAAC,GAAG,IAAI,SAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,OAAe;IACvD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO;IACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACtC,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,IAAA,6BAAa,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,KAAK,WAAG,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;QACvE,gEAAgE;QAChE,iEAAiE;QACjE,8DAA8D;QAC9D,+BAA+B;QAC/B,IAAI,CAAC;YACH,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa;IAClD,MAAM,IAAI,GAAG,IAAA,8BAAc,EAAC,IAAI,CAAC,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,MAAM,IAAA,6BAAa,EAAC,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC;QACzD,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CACT,KAAK,WAAG,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAC,CAAC,GAAG,CAAC,eAAe,GAAG,QAAQ,IAAI,GAAG,CAAC,EAAE,CAC7E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * `chorus connect [orchestrator]` — wire Chorus into a CLI's MCP config so
4
+ * the user can call chorus.* tools from inside it. Removes the per-tool
5
+ * "Yes, allow for this project?" friction (Claude) or registers the MCP
6
+ * server (Codex/Gemini/OpenCode) which they don't have until we add it.
7
+ *
8
+ * Idempotent. Same logic exposed at daemon `POST /orchestrators/:name/connect`
9
+ * so the cockpit's /connect page can run it with one click.
10
+ *
11
+ * Usage:
12
+ * chorus connect # all detected CLIs
13
+ * chorus connect claude # just Claude Code
14
+ * chorus connect codex,gemini # comma-separated subset
15
+ */
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.runConnect = runConnect;
21
+ const node_path_1 = __importDefault(require("node:path"));
22
+ const index_js_1 = require("../daemon/orchestrators/index.js");
23
+ const CHORUS_BIN_PATH = node_path_1.default.resolve(__dirname, '..', '..', 'bin', 'chorus.mjs');
24
+ const ALL_NAMES = ['claude', 'codex', 'gemini', 'opencode', 'kimi', 'cursor', 'windsurf'];
25
+ function parseTargets(arg) {
26
+ if (!arg)
27
+ return null; // null = "all detected"
28
+ const wanted = arg.split(',').map((s) => s.trim().toLowerCase());
29
+ const valid = [];
30
+ for (const w of wanted) {
31
+ if (ALL_NAMES.includes(w)) {
32
+ valid.push(w);
33
+ }
34
+ else {
35
+ console.error(`Unknown orchestrator: '${w}'. Valid: ${ALL_NAMES.join(', ')}`);
36
+ process.exit(1);
37
+ }
38
+ }
39
+ return valid;
40
+ }
41
+ async function runConnect(orchestrator) {
42
+ const only = parseTargets(orchestrator);
43
+ const binPath = CHORUS_BIN_PATH;
44
+ console.log(`Connecting Chorus${only ? ` to: ${only.join(', ')}` : ''}...`);
45
+ console.log('');
46
+ try {
47
+ const result = await (0, index_js_1.autoConnectAll)({
48
+ binPath,
49
+ ...(only && only.length > 0 ? { only } : {}),
50
+ });
51
+ const statuses = (0, index_js_1.listOrchestrators)();
52
+ const promptsOnce = [];
53
+ const inheritsGlobal = [];
54
+ for (const step of result.steps) {
55
+ if (!step.detected) {
56
+ console.log(` ✗ ${step.label}: not detected on this machine`);
57
+ continue;
58
+ }
59
+ if (step.error) {
60
+ console.log(` ! ${step.label}: ${step.error}`);
61
+ continue;
62
+ }
63
+ const parts = [];
64
+ if (step.registered)
65
+ parts.push('MCP server registered');
66
+ else
67
+ parts.push('MCP already registered');
68
+ if (step.toolsAdded > 0)
69
+ parts.push(`${step.toolsAdded} tool(s) approved`);
70
+ else if (step.name === 'claude')
71
+ parts.push(`all ${index_js_1.CHORUS_TOOLS.length} tools already approved`);
72
+ if (step.slashCommand === 'installed')
73
+ parts.push('/chorus command installed');
74
+ else if (step.slashCommand === 'updated')
75
+ parts.push('/chorus command updated');
76
+ console.log(` ✓ ${step.label}: ${parts.join(' · ')}`);
77
+ const status = statuses.find((s) => s.name === step.name);
78
+ if (status?.firstCallBehavior === 'prompts_once')
79
+ promptsOnce.push(step.label);
80
+ if (status?.firstCallBehavior === 'inherits_global')
81
+ inheritsGlobal.push(step.label);
82
+ }
83
+ if (!result.anyConnected) {
84
+ console.log('');
85
+ console.log('No supported CLIs detected. Install Claude Code, Codex, Gemini, OpenCode, Kimi, Cursor, or Windsurf then retry.');
86
+ return;
87
+ }
88
+ console.log('');
89
+ console.log('Restart any CLI you just connected so it picks up the new MCP server.');
90
+ console.log('Inside the CLI: try `/chorus bug-diagnose <paste a snippet>` (Claude) or');
91
+ console.log('say `chorus, run bug-diagnose on <snippet>` (any other CLI).');
92
+ if (promptsOnce.length > 0) {
93
+ console.log('');
94
+ console.log(`Heads up: ${promptsOnce.join(', ')} will show a one-time permission prompt`);
95
+ console.log('on your first chorus.* tool call. Click "Always allow" to make it stick.');
96
+ }
97
+ if (inheritsGlobal.length > 0) {
98
+ console.log('');
99
+ console.log(`${inheritsGlobal.join(', ')} use a global approval policy — whether tool calls`);
100
+ console.log('prompt depends on your existing config (we don\'t override it).');
101
+ }
102
+ }
103
+ catch (err) {
104
+ console.error(`\nFailed: ${err instanceof Error ? err.message : String(err)}`);
105
+ process.exit(1);
106
+ }
107
+ }
108
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/cli/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const commander_1 = require("commander");
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const open_1 = __importDefault(require("open"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const doctor_js_1 = require("./commands/doctor.js");
12
+ const init_js_1 = require("./commands/init.js");
13
+ const start_js_1 = require("./commands/start.js");
14
+ const status_js_1 = require("./commands/status.js");
15
+ const stop_js_1 = require("./commands/stop.js");
16
+ const runtime_env_js_1 = require("./runtime-env.js");
17
+ const shared_js_1 = require("./shared.js");
18
+ const ui_js_1 = require("./ui.js");
19
+ const program = new commander_1.Command();
20
+ program
21
+ .name('chorus')
22
+ .description('Driver-agnostic multi-LLM peer review for code decisions')
23
+ .version(shared_js_1.pkg.version);
24
+ // Show a quick-start banner before the standard help so first-time
25
+ // users see the setup sequence even when npm's global install hides
26
+ // postinstall stdout. State-aware: chorus.db is the marker — dir alone
27
+ // is not enough, an empty ~/.chorus can exist from a prior aborted
28
+ // install.
29
+ program.addHelpText('beforeAll', () => {
30
+ const chorusDir = path_1.default.join(os_1.default.homedir(), '.chorus');
31
+ const dbFile = path_1.default.join(chorusDir, 'chorus.db');
32
+ const daemonPid = path_1.default.join(chorusDir, 'daemon.pid');
33
+ const initialised = fs_1.default.existsSync(dbFile);
34
+ const running = fs_1.default.existsSync(daemonPid);
35
+ if (!initialised) {
36
+ return [
37
+ '',
38
+ ` ${ui_js_1.sym.rocket} ${ui_js_1.c.bold('Welcome to Chorus')} ${ui_js_1.c.dim('— two commands to get going:')}`,
39
+ '',
40
+ ` ${ui_js_1.c.cyan('1.')} ${ui_js_1.c.bold('chorus init')} ${ui_js_1.c.dim('register MCP with your editors + seed templates + detect CLIs')}`,
41
+ ` ${ui_js_1.c.cyan('2.')} ${ui_js_1.c.bold('chorus start')} ${ui_js_1.c.dim('bring up the daemon + cockpit at')} ${ui_js_1.c.cyan('http://127.0.0.1:5050')}`,
42
+ '',
43
+ ].join('\n');
44
+ }
45
+ if (!running) {
46
+ return [
47
+ '',
48
+ ` ${ui_js_1.sym.pointer} ${ui_js_1.c.bold('Daemon is stopped.')} ${ui_js_1.c.dim('Bring it back up:')}`,
49
+ '',
50
+ ` ${ui_js_1.c.bold('chorus start')}`,
51
+ '',
52
+ ].join('\n');
53
+ }
54
+ return '';
55
+ });
56
+ (0, init_js_1.registerInitCommand)(program);
57
+ (0, start_js_1.registerStartCommand)(program);
58
+ (0, stop_js_1.registerStopCommand)(program);
59
+ (0, status_js_1.registerStatusCommand)(program);
60
+ (0, doctor_js_1.registerDoctorCommand)(program);
61
+ program
62
+ .command('ui')
63
+ .description('Open the Chorus web UI in default browser')
64
+ .action(async () => {
65
+ try {
66
+ const env = (0, runtime_env_js_1.detectRuntimeEnv)();
67
+ (0, shared_js_1.printCockpitAccessHint)();
68
+ if ((0, runtime_env_js_1.shouldAutoOpenBrowser)(env)) {
69
+ await (0, open_1.default)(shared_js_1.COCKPIT_URL);
70
+ console.log(`\nOpening ${shared_js_1.COCKPIT_URL}...`);
71
+ }
72
+ }
73
+ catch (error) {
74
+ console.error('Failed to open browser:', error);
75
+ process.exit(1);
76
+ }
77
+ });
78
+ program
79
+ .command('connect [orchestrator]')
80
+ .description('Pre-approve all Chorus MCP tools in your orchestrator (default: claude)')
81
+ .action(async (orchestrator) => {
82
+ const { runConnect } = await import('./connect.js');
83
+ runConnect(orchestrator);
84
+ });
85
+ program
86
+ .command('mcp')
87
+ .description('Run the MCP server on stdio (for orchestrators)')
88
+ .action(async () => {
89
+ // Hand off stdio to the MCP server. This call never returns under
90
+ // normal operation — the orchestrator (Claude Code, Codex, Cursor)
91
+ // holds the pipe open and pumps JSON-RPC messages until it shuts
92
+ // the child down.
93
+ await import('../mcp/index.js');
94
+ });
95
+ program.parse(process.argv);
96
+ if (!process.argv.slice(2).length) {
97
+ program.outputHelp();
98
+ }
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;;;AAAA,yCAAoC;AACpC,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AACpB,gDAAwB;AACxB,oDAA6D;AAC7D,gDAAyD;AACzD,kDAA2D;AAC3D,oDAA6D;AAC7D,gDAAyD;AACzD,qDAA2E;AAC3E,2CAIqB;AACrB,mCAAiC;AAEjC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,eAAG,CAAC,OAAO,CAAC,CAAC;AAExB,mEAAmE;AACnE,oEAAoE;AACpE,uEAAuE;AACvE,mEAAmE;AACnE,WAAW;AACX,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,GAAG,EAAE;IACpC,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,EAAE;YACF,KAAK,WAAG,CAAC,MAAM,IAAI,SAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,SAAC,CAAC,GAAG,CAAC,8BAA8B,CAAC,EAAE;YACzF,EAAE;YACF,OAAO,SAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,SAAC,CAAC,GAAG,CAAC,+DAA+D,CAAC,EAAE;YAC5H,OAAO,SAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAC,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,SAAC,CAAC,GAAG,CAAC,kCAAkC,CAAC,IAAI,SAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,EAAE;YAClI,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,EAAE;YACF,KAAK,WAAG,CAAC,OAAO,IAAI,SAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,SAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,EAAE;YAChF,EAAE;YACF,OAAO,SAAC,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE;YAC/B,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC;AAEH,IAAA,6BAAmB,EAAC,OAAO,CAAC,CAAC;AAC7B,IAAA,+BAAoB,EAAC,OAAO,CAAC,CAAC;AAC9B,IAAA,6BAAmB,EAAC,OAAO,CAAC,CAAC;AAC7B,IAAA,iCAAqB,EAAC,OAAO,CAAC,CAAC;AAC/B,IAAA,iCAAqB,EAAC,OAAO,CAAC,CAAC;AAE/B,OAAO;KACJ,OAAO,CAAC,IAAI,CAAC;KACb,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iCAAgB,GAAE,CAAC;QAC/B,IAAA,kCAAsB,GAAE,CAAC;QACzB,IAAI,IAAA,sCAAqB,EAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAA,cAAI,EAAC,uBAAW,CAAC,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,aAAa,uBAAW,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,wBAAwB,CAAC;KACjC,WAAW,CACV,yEAAyE,CAC1E;KACA,MAAM,CAAC,KAAK,EAAE,YAAqB,EAAE,EAAE;IACtC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IACpD,UAAU,CAAC,YAAY,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,kEAAkE;IAClE,mEAAmE;IACnE,iEAAiE;IACjE,kBAAkB;IAClB,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAClC,OAAO,CAAC,UAAU,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isPortInUse = isPortInUse;
7
+ exports.findPidsOnPort = findPidsOnPort;
8
+ exports.pidLooksLikeChorus = pidLooksLikeChorus;
9
+ exports.killAndVerify = killAndVerify;
10
+ const child_process_1 = require("child_process");
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const net_1 = __importDefault(require("net"));
13
+ const ui_js_1 = require("./ui.js");
14
+ /**
15
+ * Probe whether anything is listening on a TCP port on 127.0.0.1.
16
+ *
17
+ * Used by the start-path orphan reaper: if a previous next-server from
18
+ * an earlier `chorus start` survived a `chorus stop` (because the
19
+ * pidfile was lost or the SIGTERM was ignored), the next start would
20
+ * silently race against it on :5050 and leave the user stuck on stale
21
+ * chunks after a rebuild.
22
+ */
23
+ function isPortInUse(port, host = '127.0.0.1', timeoutMs = 500) {
24
+ return new Promise((resolve) => {
25
+ const sock = new net_1.default.Socket();
26
+ let settled = false;
27
+ const finish = (inUse) => {
28
+ if (settled)
29
+ return;
30
+ settled = true;
31
+ try {
32
+ sock.destroy();
33
+ }
34
+ catch {
35
+ /* ignore */
36
+ }
37
+ resolve(inUse);
38
+ };
39
+ sock.setTimeout(timeoutMs);
40
+ sock.once('connect', () => finish(true));
41
+ sock.once('timeout', () => finish(false));
42
+ sock.once('error', () => finish(false));
43
+ sock.connect(port, host);
44
+ });
45
+ }
46
+ /**
47
+ * Find any process holding a TCP listener on `port` on 127.0.0.1.
48
+ * Returns the PIDs found via `ss`/`lsof`. Best-effort — returns [] on
49
+ * platforms where neither tool is available.
50
+ *
51
+ * Why: pidfile-based tracking is fragile (file deleted on a partial
52
+ * stop, PID reused by an unrelated process). Port-based reaping is the
53
+ * source of truth — if something's bound to :5050, we want it gone
54
+ * before we spawn our own.
55
+ */
56
+ function findPidsOnPort(port) {
57
+ const candidates = [
58
+ {
59
+ cmd: `ss -ltnp 'sport = :${port}' 2>/dev/null`,
60
+ parse: (out) => {
61
+ const pids = [];
62
+ for (const m of out.matchAll(/pid=(\d+)/g)) {
63
+ const pid = parseInt(m[1], 10);
64
+ if (Number.isFinite(pid) && pid > 0)
65
+ pids.push(pid);
66
+ }
67
+ return pids;
68
+ },
69
+ },
70
+ {
71
+ cmd: `lsof -nP -iTCP:${port} -sTCP:LISTEN -t 2>/dev/null`,
72
+ parse: (out) => out
73
+ .split(/\s+/)
74
+ .map((s) => parseInt(s, 10))
75
+ .filter((n) => Number.isFinite(n) && n > 0),
76
+ },
77
+ ];
78
+ for (const { cmd, parse } of candidates) {
79
+ try {
80
+ const out = (0, child_process_1.execSync)(cmd, {
81
+ encoding: 'utf-8',
82
+ stdio: ['ignore', 'pipe', 'ignore'],
83
+ });
84
+ const pids = parse(out);
85
+ if (pids.length > 0)
86
+ return Array.from(new Set(pids));
87
+ }
88
+ catch {
89
+ /* tool not present or no match — try next */
90
+ }
91
+ }
92
+ return [];
93
+ }
94
+ /**
95
+ * Read the process's command line so we can decide whether it looks
96
+ * like a chorus orphan (safe to reap) vs a foreign process the user
97
+ * owns (refuse to kill — Grafana/another dev server happens to be on
98
+ * 5050 or 7707). Linux exposes /proc/<pid>/cmdline; macOS doesn't, so
99
+ * we fall back to `ps -p <pid> -o command=`.
100
+ */
101
+ function readCmdline(pid) {
102
+ try {
103
+ const procPath = `/proc/${pid}/cmdline`;
104
+ if (fs_1.default.existsSync(procPath)) {
105
+ // /proc/<pid>/cmdline is NUL-separated argv. Replace with spaces
106
+ // so we can substring-match against the joined invocation.
107
+ return fs_1.default.readFileSync(procPath, 'utf-8').replace(/ /g, ' ').trim();
108
+ }
109
+ }
110
+ catch {
111
+ /* race with process exit, fall through to ps */
112
+ }
113
+ try {
114
+ // execFileSync over execSync so a future loosening of `pid`'s
115
+ // numeric type can't slip into a shell command-injection. argv
116
+ // goes straight to ps without an intermediate sh -c.
117
+ const out = (0, child_process_1.execFileSync)('ps', ['-p', String(pid), '-o', 'command='], {
118
+ encoding: 'utf-8',
119
+ stdio: ['ignore', 'pipe', 'ignore'],
120
+ });
121
+ const trimmed = out.trim();
122
+ return trimmed.length > 0 ? trimmed : null;
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
128
+ /**
129
+ * Path-segment match for the chorus / chorus-codes directory names.
130
+ * Splitting on `/` so we accept `/dev/chorus/...` but not
131
+ * `/dev/chorus-experiments/...`. Used by the next-launcher fallback
132
+ * for both cmdline and cwd checks.
133
+ */
134
+ function pathHasChorusSegment(somePath) {
135
+ const segs = somePath.split('/');
136
+ return segs.includes('chorus') || segs.includes('chorus-codes');
137
+ }
138
+ function cmdlineHasChorusSegment(cmdline) {
139
+ for (const tok of cmdline.split(/\s+/)) {
140
+ if (pathHasChorusSegment(tok))
141
+ return true;
142
+ }
143
+ return false;
144
+ }
145
+ /**
146
+ * Does this process look like a chorus daemon or cockpit?
147
+ *
148
+ * The reap loop in `chorus start` kills whatever's bound to 5050/7707
149
+ * before respawning. Pre-fix, that loop would happily SIGKILL
150
+ * `grafana-server` or another user's `next dev` if either happened to
151
+ * be on the same port — silently murdering work and surprising the user.
152
+ *
153
+ * Accept anything whose argv mentions one of these markers, all of
154
+ * which are uniquely chorus-shaped:
155
+ * - `chorus/dist/daemon/index.js` — compiled daemon entrypoint
156
+ * - `src/daemon/index.ts` — dev (tsx) entrypoint
157
+ * - `chorus/bin/chorus.mjs` — CLI wrapper
158
+ * - `next-server` / `next start` running in a path that contains chorus
159
+ *
160
+ * Anything else returns false; the caller should refuse to reap and
161
+ * surface a clear "port is taken by <cmd>" error.
162
+ */
163
+ function pidLooksLikeChorus(pid) {
164
+ const cmdline = readCmdline(pid);
165
+ if (!cmdline) {
166
+ // Couldn't read cmdline (race / permission). Fail-closed: treat as
167
+ // foreign, force the user to investigate.
168
+ return { match: false, cmdline: null };
169
+ }
170
+ // Path markers covering both dev (repo) and installed (node_modules)
171
+ // layouts. The unscoped npm name `chorus-codes` lands the package at
172
+ // node_modules/chorus-codes/* on global installs.
173
+ //
174
+ // Each marker is prefixed with `/` so substring search anchors on a
175
+ // path-segment boundary. Without the leading slash,
176
+ // `cmdline.includes('chorus/dist/...')` would match
177
+ // `/x/notchorus/dist/...` or `/x/mychorus-fork/dist/...`.
178
+ const markers = [
179
+ '/chorus/dist/daemon/index.js',
180
+ '/chorus/src/daemon/index.ts',
181
+ '/chorus/bin/chorus.mjs',
182
+ '/chorus/dist/cli/index.js',
183
+ '/chorus-codes/dist/daemon/index.js',
184
+ '/chorus-codes/src/daemon/index.ts',
185
+ '/chorus-codes/bin/chorus.mjs',
186
+ '/chorus-codes/dist/cli/index.js',
187
+ ];
188
+ if (markers.some((m) => cmdline.includes(m)))
189
+ return { match: true, cmdline };
190
+ // next-server is the cockpit. The launcher may show up as either the
191
+ // literal `next-server (vXX.YY.ZZ)` worker title (Next overwrites
192
+ // process.title once running, wiping the original argv — chorus
193
+ // disappears from cmdline at that point) OR as the original `node
194
+ // node_modules/next/dist/bin/next start` argv. To stay safe in both
195
+ // states, accept either form when the cmdline carries a chorus path
196
+ // segment OR the process's cwd has one — chorus start always spawns
197
+ // Next with cwd: packageRoot. Path-segment matching (split + includes)
198
+ // so /home/user/chorus-experiments/marketing-site doesn't mistakenly
199
+ // match.
200
+ const nextLauncher = cmdline.includes('next-server') ||
201
+ /node_modules\/next\/dist\/bin\/next (start|dev)/.test(cmdline);
202
+ if (nextLauncher) {
203
+ if (cmdlineHasChorusSegment(cmdline))
204
+ return { match: true, cmdline };
205
+ let cwd = null;
206
+ try {
207
+ cwd = fs_1.default.readlinkSync(`/proc/${pid}/cwd`);
208
+ }
209
+ catch {
210
+ /* not Linux or process gone — fall through */
211
+ }
212
+ if (cwd && pathHasChorusSegment(cwd))
213
+ return { match: true, cmdline };
214
+ }
215
+ return { match: false, cmdline };
216
+ }
217
+ /**
218
+ * Send SIGTERM to a PID and wait up to `gracefulMs` for it to die. If
219
+ * still alive, escalate to SIGKILL. Returns true if the process is
220
+ * gone by the time we return (or never existed in the first place),
221
+ * false if SIGKILL also failed.
222
+ */
223
+ async function killAndVerify(pid, label, gracefulMs = 1500) {
224
+ const isAlive = () => {
225
+ try {
226
+ process.kill(pid, 0);
227
+ return true;
228
+ }
229
+ catch {
230
+ return false;
231
+ }
232
+ };
233
+ if (!isAlive())
234
+ return true;
235
+ try {
236
+ process.kill(pid, 'SIGTERM');
237
+ }
238
+ catch {
239
+ /* gone already */
240
+ }
241
+ const deadline = Date.now() + gracefulMs;
242
+ while (Date.now() < deadline) {
243
+ if (!isAlive())
244
+ return true;
245
+ await new Promise((r) => setTimeout(r, 100));
246
+ }
247
+ // Stubborn — escalate.
248
+ try {
249
+ process.kill(pid, 'SIGKILL');
250
+ }
251
+ catch {
252
+ /* may already be dead */
253
+ }
254
+ await new Promise((r) => setTimeout(r, 200));
255
+ if (!isAlive())
256
+ return true;
257
+ console.warn(` ${ui_js_1.sym.err} ${label} PID ${pid} survived SIGKILL — manual cleanup needed`);
258
+ return false;
259
+ }
260
+ //# sourceMappingURL=port-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-utils.js","sourceRoot":"","sources":["../../src/cli/port-utils.ts"],"names":[],"mappings":"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"}