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,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":"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"}
@@ -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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"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * Detect where chorus is running so the CLI can print the right URL hint.
4
+ *
5
+ * The cockpit binds to 127.0.0.1:5050. On a native install that opens fine in
6
+ * the local browser. On remote-dev setups (VSCode/Cursor Remote-SSH,
7
+ * Codespaces, dev containers, plain SSH), the user's browser lives on a
8
+ * different host — they need their editor to forward the port.
9
+ *
10
+ * Detection is best-effort and read-only. We never guess; if no signal is
11
+ * present we report 'native' and let `open()` handle it.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.detectRuntimeEnv = detectRuntimeEnv;
15
+ exports.shouldAutoOpenBrowser = shouldAutoOpenBrowser;
16
+ function detectRuntimeEnv() {
17
+ const env = process.env;
18
+ if (env.CODESPACES === 'true') {
19
+ return {
20
+ kind: 'codespaces',
21
+ hint: 'Codespaces will auto-forward port 5050. Open the Ports tab and click 5050.',
22
+ };
23
+ }
24
+ // VSCode and Cursor both set VSCODE_IPC_HOOK_CLI when running through
25
+ // their integrated terminal. We tell them apart by the binary name in
26
+ // TERM_PROGRAM (Cursor sets 'cursor', VSCode sets 'vscode').
27
+ if (env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === 'vscode') {
28
+ const isCursor = env.TERM_PROGRAM === 'cursor' || env.CURSOR_TRACE_ID;
29
+ return {
30
+ kind: isCursor ? 'cursor-remote' : 'vscode-remote',
31
+ hint: `${isCursor ? 'Cursor' : 'VSCode'} should auto-forward 5050 — open the Ports tab in the bottom panel and click "Open in Browser" next to the row for 5050. If you don't see it, click "Forward a Port" and enter 5050.`,
32
+ };
33
+ }
34
+ if (env.WSL_DISTRO_NAME) {
35
+ // WSL2 forwards 127.0.0.1 to the Windows host automatically.
36
+ return {
37
+ kind: 'wsl',
38
+ hint: 'On WSL2, http://localhost:5050 in your Windows browser should just work.',
39
+ };
40
+ }
41
+ if (env.SSH_CONNECTION || env.SSH_TTY) {
42
+ return {
43
+ kind: 'ssh',
44
+ hint: 'Plain SSH session detected — no auto-forwarding. Either:\n' +
45
+ ' • Run `ssh -L 5050:127.0.0.1:5050 <host>` from your laptop and visit http://localhost:5050, or\n' +
46
+ ' • Use VSCode/Cursor Remote-SSH which forwards ports automatically.',
47
+ };
48
+ }
49
+ return { kind: 'native', hint: '' };
50
+ }
51
+ /**
52
+ * Should `chorus start --ui` actually try to spawn a browser?
53
+ * On remote-dev hosts there's usually no graphical browser; calling `open()`
54
+ * just emits an `xdg-open` error. Skip it and rely on the printed URL +
55
+ * the editor's own port-forwarding UI.
56
+ */
57
+ function shouldAutoOpenBrowser(env) {
58
+ return env.kind === 'native' || env.kind === 'wsl';
59
+ }
60
+ //# sourceMappingURL=runtime-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-env.js","sourceRoot":"","sources":["../../src/cli/runtime-env.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAgBH,4CAyCC;AAQD,sDAEC;AAnDD,SAAgB,gBAAgB;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAExB,IAAI,GAAG,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,IAAI,EACF,4EAA4E;SAC/E,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,sEAAsE;IACtE,6DAA6D;IAC7D,IAAI,GAAG,CAAC,mBAAmB,IAAI,GAAG,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC7D,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,GAAG,CAAC,eAAe,CAAC;QACtE,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe;YAClD,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,sLAAsL;SAC9N,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;QACxB,6DAA6D;QAC7D,OAAO;YACL,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,0EAA0E;SACjF,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACtC,OAAO;YACL,IAAI,EAAE,KAAK;YACX,IAAI,EACF,4DAA4D;gBAC5D,sGAAsG;gBACtG,wEAAwE;SAC3E,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,GAAmB;IACvD,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC;AACrD,CAAC"}
@@ -0,0 +1,54 @@
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.pkg = exports.CHORUS_BIN_PATH = exports.DAEMON_URL = exports.COCKPIT_URL = void 0;
7
+ exports.printCockpitAccessHint = printCockpitAccessHint;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const runtime_env_js_1 = require("./runtime-env.js");
11
+ const ui_js_1 = require("./ui.js");
12
+ exports.COCKPIT_URL = 'http://127.0.0.1:5050';
13
+ exports.DAEMON_URL = 'http://127.0.0.1:7707';
14
+ /**
15
+ * Absolute path to bin/chorus.mjs. Resolved from __dirname so the path
16
+ * is correct whether the CLI runs via:
17
+ * - `npm i -g chorus-codes` → /usr/local/lib/node_modules/chorus-codes/dist/cli/index.js
18
+ * - tsx dev mode → /home/.../chorus/src/cli/index.ts
19
+ * - direct dist → /home/.../chorus/dist/cli/index.js
20
+ *
21
+ * `process.argv[1]` would also work for the npm-installed case, but in
22
+ * tsx dev mode it points at the .ts file which `node` can't execute.
23
+ */
24
+ exports.CHORUS_BIN_PATH = path_1.default.resolve(__dirname, '..', '..', 'bin', 'chorus.mjs');
25
+ /**
26
+ * Read version from the shipped package.json so it can never drift.
27
+ * __dirname is dist/cli (built) or src/cli (tsx dev); ../../package.json
28
+ * resolves to the package root in both layouts.
29
+ */
30
+ exports.pkg = (() => {
31
+ try {
32
+ const pkgPath = path_1.default.resolve(__dirname, '..', '..', 'package.json');
33
+ const raw = fs_1.default.readFileSync(pkgPath, 'utf-8');
34
+ const parsed = JSON.parse(raw);
35
+ return {
36
+ version: parsed.version ?? '0.0.0',
37
+ name: parsed.name ?? 'chorus',
38
+ };
39
+ }
40
+ catch {
41
+ return { version: '0.0.0', name: 'chorus' };
42
+ }
43
+ })();
44
+ function printCockpitAccessHint() {
45
+ const env = (0, runtime_env_js_1.detectRuntimeEnv)();
46
+ console.log('');
47
+ console.log(` ${ui_js_1.c.gray('Open')} ${ui_js_1.c.cyan(exports.COCKPIT_URL)}`);
48
+ if (env.hint) {
49
+ console.log('');
50
+ console.log((0, ui_js_1.tip)(env.hint));
51
+ }
52
+ console.log('');
53
+ }
54
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/cli/shared.ts"],"names":[],"mappings":";;;;;;AA6CA,wDASC;AAtDD,4CAAoB;AACpB,gDAAwB;AACxB,qDAAoD;AACpD,mCAAiC;AAEpB,QAAA,WAAW,GAAG,uBAAuB,CAAC;AACtC,QAAA,UAAU,GAAG,uBAAuB,CAAC;AAElD;;;;;;;;;GASG;AACU,QAAA,eAAe,GAAG,cAAI,CAAC,OAAO,CACzC,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,YAAY,CACb,CAAC;AAEF;;;;GAIG;AACU,QAAA,GAAG,GAAsC,CAAC,GAAG,EAAE;IAC1D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwC,CAAC;QACtE,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO;YAClC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,QAAQ;SAC9B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC9C,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AAEL,SAAgB,sBAAsB;IACpC,MAAM,GAAG,GAAG,IAAA,iCAAgB,GAAE,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,SAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,SAAC,CAAC,IAAI,CAAC,mBAAW,CAAC,EAAE,CAAC,CAAC;IAC5D,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,IAAA,WAAG,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
package/dist/cli/ui.js ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * CLI output helpers — colors, symbols, formatters.
4
+ * Zero deps — raw ANSI escapes. Respects NO_COLOR env var.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.sym = exports.c = void 0;
8
+ exports.header = header;
9
+ exports.kv = kv;
10
+ exports.tip = tip;
11
+ const useColor = !process.env.NO_COLOR && process.stdout.isTTY !== false;
12
+ function ansi(code) {
13
+ return (s) => (useColor ? `\x1b[${code}m${s}\x1b[0m` : s);
14
+ }
15
+ exports.c = {
16
+ bold: ansi('1'),
17
+ dim: ansi('2'),
18
+ red: ansi('31'),
19
+ green: ansi('32'),
20
+ yellow: ansi('33'),
21
+ blue: ansi('34'),
22
+ magenta: ansi('35'),
23
+ cyan: ansi('36'),
24
+ gray: ansi('90'),
25
+ };
26
+ exports.sym = {
27
+ ok: exports.c.green('✓'),
28
+ err: exports.c.red('✗'),
29
+ bullet: exports.c.cyan('●'),
30
+ arrow: exports.c.gray('→'),
31
+ pointer: exports.c.cyan('▶'),
32
+ rocket: '🚀',
33
+ info: exports.c.blue('ⓘ'),
34
+ };
35
+ /**
36
+ * Header line with bold title, optional dim subtitle.
37
+ * header(sym.ok, 'Chorus started') → ✓ Chorus started
38
+ * header(sym.ok, 'Started', 'PID 1234') → ✓ Started (PID 1234)
39
+ */
40
+ function header(icon, title, sub) {
41
+ const main = `${icon} ${exports.c.bold(title)}`;
42
+ return sub ? `${main} ${exports.c.dim(sub)}` : main;
43
+ }
44
+ /**
45
+ * Aligned key/value rows. Pads keys to the longest key width.
46
+ * kv([['Cockpit', 'http://...'], ['Daemon', 'http://...']])
47
+ */
48
+ function kv(rows, indent = ' ') {
49
+ const width = Math.max(...rows.map(([k]) => k.length));
50
+ return rows
51
+ .map(([k, v]) => `${indent}${exports.c.gray(k.padEnd(width))} ${v}`)
52
+ .join('\n');
53
+ }
54
+ /**
55
+ * A boxed tip line. Used for one-time hints/footnotes.
56
+ */
57
+ function tip(text, indent = ' ') {
58
+ return `${indent}${exports.sym.info} ${exports.c.dim(text)}`;
59
+ }
60
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/cli/ui.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAmCH,wBAGC;AAMD,gBAKC;AAKD,kBAEC;AAtDD,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC;AAEzE,SAAS,IAAI,CAAC,IAAY;IACxB,OAAO,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAEY,QAAA,CAAC,GAAG;IACf,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IACf,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IACd,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;IACf,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;CACjB,CAAC;AAEW,QAAA,GAAG,GAAG;IACjB,EAAE,EAAE,SAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAChB,GAAG,EAAE,SAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACf,MAAM,EAAE,SAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACnB,KAAK,EAAE,SAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IAClB,OAAO,EAAE,SAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACpB,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE,SAAC,CAAC,IAAI,CAAC,GAAG,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,SAAgB,MAAM,CAAC,IAAY,EAAE,KAAa,EAAE,GAAY;IAC9D,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,SAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IACxC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,SAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAgB,EAAE,CAAC,IAA6B,EAAE,MAAM,GAAG,KAAK;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,GAAG,SAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;SAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,GAAG,CAAC,IAAY,EAAE,MAAM,GAAG,KAAK;IAC9C,OAAO,GAAG,MAAM,GAAG,WAAG,CAAC,IAAI,IAAI,SAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AAC/C,CAAC"}