@gh-symphony/cli 0.0.14 → 0.0.15

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 (100) hide show
  1. package/dist/chunk-5NV3LSAJ.js +11 -0
  2. package/dist/chunk-6HBZC3BE.js +468 -0
  3. package/dist/chunk-76QPITKI.js +109 -0
  4. package/dist/chunk-IWR4UQEJ.js +2250 -0
  5. package/dist/chunk-JO3AXHQI.js +130 -0
  6. package/dist/chunk-M7OSMUTN.js +874 -0
  7. package/dist/chunk-MVRF7BES.js +68 -0
  8. package/dist/chunk-RNWX7DQU.js +4617 -0
  9. package/dist/chunk-ROGRTUFI.js +108 -0
  10. package/dist/chunk-TH5QPO3Y.js +67 -0
  11. package/dist/config-cmd-AZ7POMAA.js +110 -0
  12. package/dist/index.d.ts +5 -4
  13. package/dist/index.js +568 -356
  14. package/dist/init-EZXQAXZM.js +17 -0
  15. package/dist/logs-6LNGT2GF.js +188 -0
  16. package/dist/project-3ELXQ35D.js +678 -0
  17. package/dist/recover-T6ME6C56.js +130 -0
  18. package/dist/repo-R3XBIVAX.js +121 -0
  19. package/dist/run-DYINRZHK.js +107 -0
  20. package/dist/start-PIFQMIC2.js +15 -0
  21. package/dist/status-3WK5BWRZ.js +11 -0
  22. package/dist/stop-AA3AP5M6.js +9 -0
  23. package/dist/version-VBB62JWI.js +30 -0
  24. package/package.json +9 -4
  25. package/dist/ansi.d.ts +0 -15
  26. package/dist/ansi.js +0 -53
  27. package/dist/commands/config-cmd.d.ts +0 -3
  28. package/dist/commands/config-cmd.js +0 -90
  29. package/dist/commands/help.d.ts +0 -3
  30. package/dist/commands/help.js +0 -55
  31. package/dist/commands/init.d.ts +0 -34
  32. package/dist/commands/init.js +0 -477
  33. package/dist/commands/logs.d.ts +0 -3
  34. package/dist/commands/logs.js +0 -184
  35. package/dist/commands/project.d.ts +0 -3
  36. package/dist/commands/project.js +0 -649
  37. package/dist/commands/recover.d.ts +0 -3
  38. package/dist/commands/recover.js +0 -119
  39. package/dist/commands/repo.d.ts +0 -3
  40. package/dist/commands/repo.js +0 -103
  41. package/dist/commands/run.d.ts +0 -3
  42. package/dist/commands/run.js +0 -95
  43. package/dist/commands/start.d.ts +0 -20
  44. package/dist/commands/start.js +0 -344
  45. package/dist/commands/status-refresh.d.ts +0 -9
  46. package/dist/commands/status-refresh.js +0 -27
  47. package/dist/commands/status.d.ts +0 -3
  48. package/dist/commands/status.js +0 -237
  49. package/dist/commands/stop.d.ts +0 -3
  50. package/dist/commands/stop.js +0 -92
  51. package/dist/commands/version.d.ts +0 -3
  52. package/dist/commands/version.js +0 -21
  53. package/dist/completion.d.ts +0 -1
  54. package/dist/completion.js +0 -204
  55. package/dist/config.d.ts +0 -38
  56. package/dist/config.js +0 -82
  57. package/dist/context/context-types.d.ts +0 -36
  58. package/dist/context/context-types.js +0 -1
  59. package/dist/context/generate-context-yaml.d.ts +0 -15
  60. package/dist/context/generate-context-yaml.js +0 -129
  61. package/dist/dashboard/renderer.d.ts +0 -9
  62. package/dist/dashboard/renderer.js +0 -220
  63. package/dist/detection/environment-detector.d.ts +0 -11
  64. package/dist/detection/environment-detector.js +0 -140
  65. package/dist/github/client.d.ts +0 -71
  66. package/dist/github/client.js +0 -348
  67. package/dist/github/gh-auth.d.ts +0 -34
  68. package/dist/github/gh-auth.js +0 -110
  69. package/dist/mapping/smart-defaults.d.ts +0 -17
  70. package/dist/mapping/smart-defaults.js +0 -86
  71. package/dist/orchestrator-runtime.d.ts +0 -1
  72. package/dist/orchestrator-runtime.js +0 -4
  73. package/dist/orchestrator-status-endpoint.d.ts +0 -5
  74. package/dist/orchestrator-status-endpoint.js +0 -27
  75. package/dist/project-selection.d.ts +0 -8
  76. package/dist/project-selection.js +0 -56
  77. package/dist/skills/skill-writer.d.ts +0 -14
  78. package/dist/skills/skill-writer.js +0 -62
  79. package/dist/skills/templates/commit.d.ts +0 -2
  80. package/dist/skills/templates/commit.js +0 -45
  81. package/dist/skills/templates/document.d.ts +0 -7
  82. package/dist/skills/templates/document.js +0 -16
  83. package/dist/skills/templates/gh-project.d.ts +0 -2
  84. package/dist/skills/templates/gh-project.js +0 -88
  85. package/dist/skills/templates/gh-symphony.d.ts +0 -2
  86. package/dist/skills/templates/gh-symphony.js +0 -125
  87. package/dist/skills/templates/index.d.ts +0 -8
  88. package/dist/skills/templates/index.js +0 -28
  89. package/dist/skills/templates/land.d.ts +0 -2
  90. package/dist/skills/templates/land.js +0 -59
  91. package/dist/skills/templates/pull.d.ts +0 -2
  92. package/dist/skills/templates/pull.js +0 -41
  93. package/dist/skills/templates/push.d.ts +0 -2
  94. package/dist/skills/templates/push.js +0 -36
  95. package/dist/skills/types.d.ts +0 -23
  96. package/dist/skills/types.js +0 -1
  97. package/dist/workflow/generate-reference-workflow.d.ts +0 -9
  98. package/dist/workflow/generate-reference-workflow.js +0 -261
  99. package/dist/workflow/generate-workflow-md.d.ts +0 -12
  100. package/dist/workflow/generate-workflow-md.js +0 -134
package/dist/index.js CHANGED
@@ -1,383 +1,595 @@
1
1
  #!/usr/bin/env node
2
- import { realpathSync } from "node:fs";
3
- import { pathToFileURL } from "node:url";
4
- import { Command, CommanderError, InvalidArgumentError, Option, } from "commander";
5
- import { resolveConfigDir } from "./config.js";
6
- import { renderCompletionScript } from "./completion.js";
7
- const COMMANDS = {
8
- init: () => import("./commands/init.js"),
9
- start: () => import("./commands/start.js"),
10
- stop: () => import("./commands/stop.js"),
11
- status: () => import("./commands/status.js"),
12
- run: () => import("./commands/run.js"),
13
- recover: () => import("./commands/recover.js"),
14
- logs: () => import("./commands/logs.js"),
15
- project: () => import("./commands/project.js"),
16
- repo: () => import("./commands/repo.js"),
17
- config: () => import("./commands/config-cmd.js"),
18
- version: () => import("./commands/version.js"),
2
+ import {
3
+ resolveConfigDir
4
+ } from "./chunk-ROGRTUFI.js";
5
+
6
+ // src/index.ts
7
+ import { realpathSync } from "fs";
8
+ import { pathToFileURL } from "url";
9
+ import {
10
+ Command,
11
+ CommanderError,
12
+ InvalidArgumentError,
13
+ Option
14
+ } from "commander";
15
+
16
+ // src/completion.ts
17
+ var TOP_LEVEL_COMMANDS = [
18
+ "init",
19
+ "start",
20
+ "stop",
21
+ "status",
22
+ "run",
23
+ "recover",
24
+ "logs",
25
+ "project",
26
+ "repo",
27
+ "config",
28
+ "completion",
29
+ "help",
30
+ "version"
31
+ ];
32
+ var GLOBAL_OPTIONS = [
33
+ "--config",
34
+ "--config-dir",
35
+ "--verbose",
36
+ "-v",
37
+ "--json",
38
+ "--no-color",
39
+ "--help",
40
+ "-h",
41
+ "--version",
42
+ "-V"
43
+ ];
44
+ var GLOBAL_OPTIONS_WITH_VALUES = ["--config", "--config-dir"];
45
+ var COMMAND_OPTIONS = {
46
+ completion: ["bash", "zsh", "fish"],
47
+ start: ["--project-id", "--project", "--daemon", "-d", ...GLOBAL_OPTIONS],
48
+ stop: ["--project-id", "--project", "--force", ...GLOBAL_OPTIONS],
49
+ status: ["--project-id", "--project", "--watch", "-w", ...GLOBAL_OPTIONS],
50
+ run: ["--project-id", "--project", "--watch", "-w", ...GLOBAL_OPTIONS],
51
+ recover: ["--project-id", "--project", "--dry-run", ...GLOBAL_OPTIONS],
52
+ logs: [
53
+ "--project-id",
54
+ "--project",
55
+ "--follow",
56
+ "-f",
57
+ "--issue",
58
+ "--run",
59
+ "--level",
60
+ ...GLOBAL_OPTIONS
61
+ ],
62
+ project: ["add", "list", "remove", "start", "stop", "switch", "status"],
63
+ "project:add": [
64
+ "--non-interactive",
65
+ "--project",
66
+ "--workspace-dir",
67
+ "--assigned-only",
68
+ ...GLOBAL_OPTIONS
69
+ ],
70
+ "project:list": [...GLOBAL_OPTIONS],
71
+ "project:remove": [...GLOBAL_OPTIONS],
72
+ "project:start": [
73
+ "--project-id",
74
+ "--project",
75
+ "--daemon",
76
+ "-d",
77
+ ...GLOBAL_OPTIONS
78
+ ],
79
+ "project:stop": ["--project-id", "--project", "--force", ...GLOBAL_OPTIONS],
80
+ "project:switch": [...GLOBAL_OPTIONS],
81
+ "project:status": [
82
+ "--project-id",
83
+ "--project",
84
+ "--watch",
85
+ "-w",
86
+ ...GLOBAL_OPTIONS
87
+ ],
88
+ repo: ["list", "add", "remove"],
89
+ "repo:list": [...GLOBAL_OPTIONS],
90
+ "repo:add": [...GLOBAL_OPTIONS],
91
+ "repo:remove": [...GLOBAL_OPTIONS],
92
+ config: ["show", "set", "edit"],
93
+ "config:show": [...GLOBAL_OPTIONS],
94
+ "config:set": [...GLOBAL_OPTIONS],
95
+ "config:edit": [...GLOBAL_OPTIONS]
96
+ };
97
+ function quoteWords(values) {
98
+ return values.join(" ");
99
+ }
100
+ function renderBashCasePatterns() {
101
+ return Object.entries(COMMAND_OPTIONS).map(([key, values]) => {
102
+ const [command, subcommand] = key.split(":");
103
+ if (!subcommand) {
104
+ if (command === "completion") {
105
+ return ` completion)
106
+ COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )
107
+ return
108
+ ;;`;
109
+ }
110
+ if (command === "project" || command === "repo" || command === "config") {
111
+ return ` ${command})
112
+ COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )
113
+ return
114
+ ;;`;
115
+ }
116
+ return ` ${command})
117
+ COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )
118
+ return
119
+ ;;`;
120
+ }
121
+ return ` ${command}:${subcommand})
122
+ COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )
123
+ return
124
+ ;;`;
125
+ }).join("\n");
126
+ }
127
+ function renderFishLines() {
128
+ const lines = GLOBAL_OPTIONS.map(
129
+ (option) => option.startsWith("--") ? `complete -c gh-symphony -f -l ${option.slice(2)}` : `complete -c gh-symphony -f -s ${option.slice(1)}`
130
+ );
131
+ for (const command of TOP_LEVEL_COMMANDS) {
132
+ lines.push(
133
+ `complete -c gh-symphony -f -n '__fish_use_subcommand' -a '${command}'`
134
+ );
135
+ }
136
+ for (const subcommand of COMMAND_OPTIONS.project ?? []) {
137
+ lines.push(
138
+ `complete -c gh-symphony -f -n '__fish_seen_subcommand_from project' -a '${subcommand}'`
139
+ );
140
+ }
141
+ for (const subcommand of COMMAND_OPTIONS.repo ?? []) {
142
+ lines.push(
143
+ `complete -c gh-symphony -f -n '__fish_seen_subcommand_from repo' -a '${subcommand}'`
144
+ );
145
+ }
146
+ for (const subcommand of COMMAND_OPTIONS.config ?? []) {
147
+ lines.push(
148
+ `complete -c gh-symphony -f -n '__fish_seen_subcommand_from config' -a '${subcommand}'`
149
+ );
150
+ }
151
+ for (const shell of COMMAND_OPTIONS.completion ?? []) {
152
+ lines.push(
153
+ `complete -c gh-symphony -f -n '__fish_seen_subcommand_from completion' -a '${shell}'`
154
+ );
155
+ }
156
+ return lines.join("\n");
157
+ }
158
+ function renderCompletionScript(shell) {
159
+ if (shell === "fish") {
160
+ return `${renderFishLines()}
161
+ `;
162
+ }
163
+ const bashFunction = `# shellcheck shell=bash
164
+ _gh_symphony_find_context() {
165
+ GH_SYMPHONY_COMMAND=""
166
+ GH_SYMPHONY_SUBCOMMAND=""
167
+
168
+ local idx=1
169
+ local token=""
170
+ local expects_value=0
171
+
172
+ while (( idx < COMP_CWORD )); do
173
+ token="\${COMP_WORDS[idx]}"
174
+
175
+ if (( expects_value )); then
176
+ expects_value=0
177
+ (( idx++ ))
178
+ continue
179
+ fi
180
+
181
+ case "\${token}" in
182
+ ${GLOBAL_OPTIONS_WITH_VALUES.map((option) => `${option}`).join("|")})
183
+ expects_value=1
184
+ ;;
185
+ ${GLOBAL_OPTIONS_WITH_VALUES.map((option) => `${option}=*`).join("|")})
186
+ ;;
187
+ ${GLOBAL_OPTIONS.filter((option) => !GLOBAL_OPTIONS_WITH_VALUES.includes(option)).join("|")})
188
+ ;;
189
+ -*)
190
+ ;;
191
+ *)
192
+ if [[ -z "\${GH_SYMPHONY_COMMAND}" ]]; then
193
+ GH_SYMPHONY_COMMAND="\${token}"
194
+ elif [[ -z "\${GH_SYMPHONY_SUBCOMMAND}" ]]; then
195
+ GH_SYMPHONY_SUBCOMMAND="\${token}"
196
+ fi
197
+ ;;
198
+ esac
199
+
200
+ (( idx++ ))
201
+ done
202
+ }
203
+
204
+ _gh_symphony_completion() {
205
+ local cur prev path
206
+ cur="\${COMP_WORDS[COMP_CWORD]}"
207
+ prev=""
208
+ if (( COMP_CWORD > 0 )); then
209
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
210
+ fi
211
+
212
+ _gh_symphony_find_context
213
+ path="\${GH_SYMPHONY_COMMAND}"
214
+
215
+ if [[ -z "\${path}" ]]; then
216
+ COMPREPLY=( $(compgen -W "${quoteWords(TOP_LEVEL_COMMANDS)} ${quoteWords(GLOBAL_OPTIONS)}" -- "$cur") )
217
+ return
218
+ fi
219
+
220
+ if [[ "\${path}" == "project" || "\${path}" == "repo" || "\${path}" == "config" || "\${path}" == "completion" ]]; then
221
+ if [[ -n "\${GH_SYMPHONY_SUBCOMMAND}" ]]; then
222
+ path="\${path}:\${GH_SYMPHONY_SUBCOMMAND}"
223
+ fi
224
+ fi
225
+
226
+ case "\${path}" in
227
+ ${renderBashCasePatterns()}
228
+ esac
229
+ }
230
+ `;
231
+ if (shell === "zsh") {
232
+ return `autoload -Uz compinit && compinit
233
+ autoload -U +X bashcompinit && bashcompinit
234
+ ${bashFunction}complete -F _gh_symphony_completion gh-symphony
235
+ `;
236
+ }
237
+ return `${bashFunction}complete -F _gh_symphony_completion gh-symphony
238
+ `;
239
+ }
240
+
241
+ // src/index.ts
242
+ var COMMANDS = {
243
+ init: () => import("./init-EZXQAXZM.js"),
244
+ start: () => import("./start-PIFQMIC2.js"),
245
+ stop: () => import("./stop-AA3AP5M6.js"),
246
+ status: () => import("./status-3WK5BWRZ.js"),
247
+ run: () => import("./run-DYINRZHK.js"),
248
+ recover: () => import("./recover-T6ME6C56.js"),
249
+ logs: () => import("./logs-6LNGT2GF.js"),
250
+ project: () => import("./project-3ELXQ35D.js"),
251
+ repo: () => import("./repo-R3XBIVAX.js"),
252
+ config: () => import("./config-cmd-AZ7POMAA.js"),
253
+ version: () => import("./version-VBB62JWI.js")
19
254
  };
20
255
  function addGlobalOptions(command) {
21
- return command
22
- .option("--config <dir>", "Config directory")
23
- .addOption(new Option("--config-dir <dir>").hideHelp())
24
- .option("-v, --verbose", "Enable verbose output")
25
- .option("--json", "Output in JSON format")
26
- .option("--no-color", "Disable color output");
256
+ return command.option("--config <dir>", "Config directory").addOption(new Option("--config-dir <dir>").hideHelp()).option("-v, --verbose", "Enable verbose output").option("--json", "Output in JSON format").option("--no-color", "Disable color output");
27
257
  }
28
258
  function resolveGlobalOptions(values) {
29
- const configInput = typeof values.config === "string"
30
- ? values.config
31
- : typeof values.configDir === "string"
32
- ? values.configDir
33
- : undefined;
34
- const options = {
35
- configDir: resolveConfigDir(configInput),
36
- verbose: Boolean(values.verbose),
37
- json: Boolean(values.json),
38
- noColor: Boolean(values.noColor),
39
- };
40
- if (options.noColor) {
41
- process.env.NO_COLOR = "1";
42
- }
43
- return options;
259
+ const configInput = typeof values.config === "string" ? values.config : typeof values.configDir === "string" ? values.configDir : void 0;
260
+ const options = {
261
+ configDir: resolveConfigDir(configInput),
262
+ verbose: Boolean(values.verbose),
263
+ json: Boolean(values.json),
264
+ noColor: Boolean(values.noColor)
265
+ };
266
+ if (options.noColor) {
267
+ process.env.NO_COLOR = "1";
268
+ }
269
+ return options;
44
270
  }
45
271
  function resolveProjectId(values) {
46
- return values.projectId ?? values.project;
272
+ return values.projectId ?? values.project;
47
273
  }
48
274
  function pushOption(args, flag, value) {
49
- if (typeof value === "string" && value.length > 0) {
50
- args.push(flag, value);
51
- return;
52
- }
53
- if (value === true) {
54
- args.push(flag);
55
- }
275
+ if (typeof value === "string" && value.length > 0) {
276
+ args.push(flag, value);
277
+ return;
278
+ }
279
+ if (value === true) {
280
+ args.push(flag);
281
+ }
56
282
  }
57
283
  async function invokeHandler(key, args, values) {
58
- const module = await COMMANDS[key]();
59
- await module.default(args, resolveGlobalOptions(values));
284
+ const module = await COMMANDS[key]();
285
+ await module.default(args, resolveGlobalOptions(values));
60
286
  }
61
287
  function shellArgument(value) {
62
- if (value === "bash" || value === "zsh" || value === "fish") {
63
- return value;
64
- }
65
- throw new InvalidArgumentError("Shell must be one of: bash, zsh, fish");
288
+ if (value === "bash" || value === "zsh" || value === "fish") {
289
+ return value;
290
+ }
291
+ throw new InvalidArgumentError("Shell must be one of: bash, zsh, fish");
66
292
  }
67
293
  function hasVersionFlag(argv) {
68
- return argv.some((arg) => arg === "--version" || arg === "-V");
294
+ return argv.some((arg) => arg === "--version" || arg === "-V");
69
295
  }
70
296
  function resolveVersionOptions(argv) {
71
- const options = {
72
- configDir: resolveConfigDir(),
73
- verbose: argv.some((arg) => arg === "--verbose" || arg === "-v"),
74
- json: argv.includes("--json"),
75
- noColor: argv.includes("--no-color"),
76
- };
77
- if (options.noColor) {
78
- process.env.NO_COLOR = "1";
79
- }
80
- return options;
297
+ const options = {
298
+ configDir: resolveConfigDir(),
299
+ verbose: argv.some((arg) => arg === "--verbose" || arg === "-v"),
300
+ json: argv.includes("--json"),
301
+ noColor: argv.includes("--no-color")
302
+ };
303
+ if (options.noColor) {
304
+ process.env.NO_COLOR = "1";
305
+ }
306
+ return options;
81
307
  }
82
308
  function createProgram() {
83
- let actionInvoked = false;
84
- const markInvoked = () => {
85
- actionInvoked = true;
86
- };
87
- const program = addGlobalOptions(new Command()
88
- .name("gh-symphony")
89
- .description("AI Coding Agent Orchestrator")
90
- .exitOverride()
91
- .helpOption("-h, --help", "Show help")
92
- .addHelpCommand("help [command]", "Show help for command")
93
- .showHelpAfterError("(run with --help for usage)")
94
- .option("-V, --version", "Show version"));
95
- addGlobalOptions(program
96
- .command("init")
97
- .description("Interactive project setup wizard")
98
- .allowExcessArguments(false)).action(async function () {
99
- markInvoked();
100
- await invokeHandler("init", [], this.optsWithGlobals());
101
- });
102
- addGlobalOptions(program
103
- .command("start")
104
- .description("Start the orchestrator")
105
- .option("-d, --daemon", "Start in daemon mode")
106
- .option("--log-level <level>", "Orchestrator lifecycle log level")
107
- .option("--project-id <projectId>", "Project identifier")
108
- .addOption(new Option("--project <projectId>").hideHelp())
109
- .allowExcessArguments(false)).action(async function () {
110
- markInvoked();
111
- const values = this.optsWithGlobals();
112
- const args = [];
113
- pushOption(args, "--project-id", resolveProjectId(values));
114
- pushOption(args, "--daemon", values.daemon);
115
- pushOption(args, "--log-level", values.logLevel);
116
- await invokeHandler("start", args, values);
117
- });
118
- addGlobalOptions(program
119
- .command("stop")
120
- .description("Stop the background orchestrator")
121
- .option("--force", "Force stop with SIGKILL")
122
- .option("--project-id <projectId>", "Project identifier")
123
- .addOption(new Option("--project <projectId>").hideHelp())
124
- .allowExcessArguments(false)).action(async function () {
125
- markInvoked();
126
- const values = this.optsWithGlobals();
127
- const args = [];
128
- pushOption(args, "--project-id", resolveProjectId(values));
129
- pushOption(args, "--force", values.force);
130
- await invokeHandler("stop", args, values);
131
- });
132
- addGlobalOptions(program
133
- .command("status")
134
- .description("Show orchestrator status")
135
- .option("-w, --watch", "Watch status continuously")
136
- .option("--project-id <projectId>", "Project identifier")
137
- .addOption(new Option("--project <projectId>").hideHelp())
138
- .allowExcessArguments(false)).action(async function () {
139
- markInvoked();
140
- const values = this.optsWithGlobals();
141
- const args = [];
142
- pushOption(args, "--project-id", resolveProjectId(values));
143
- pushOption(args, "--watch", values.watch);
144
- await invokeHandler("status", args, values);
145
- });
146
- addGlobalOptions(program
147
- .command("run")
148
- .description("Dispatch a single issue")
149
- .argument("<issue>", "Issue identifier")
150
- .option("--log-level <level>", "Orchestrator lifecycle log level")
151
- .option("-w, --watch", "Watch status after dispatch")
152
- .option("--project-id <projectId>", "Project identifier")
153
- .addOption(new Option("--project <projectId>").hideHelp())
154
- .allowExcessArguments(false)).action(async function (issue) {
155
- markInvoked();
156
- const values = this.optsWithGlobals();
157
- const args = [issue];
158
- pushOption(args, "--project-id", resolveProjectId(values));
159
- pushOption(args, "--log-level", values.logLevel);
160
- pushOption(args, "--watch", values.watch);
161
- await invokeHandler("run", args, values);
162
- });
163
- addGlobalOptions(program
164
- .command("recover")
165
- .description("Recover stalled runs")
166
- .option("--dry-run", "Show recoverable runs without recovering")
167
- .option("--project-id <projectId>", "Project identifier")
168
- .addOption(new Option("--project <projectId>").hideHelp())
169
- .allowExcessArguments(false)).action(async function () {
170
- markInvoked();
171
- const values = this.optsWithGlobals();
172
- const args = [];
173
- pushOption(args, "--project-id", resolveProjectId(values));
174
- pushOption(args, "--dry-run", values.dryRun);
175
- await invokeHandler("recover", args, values);
176
- });
177
- addGlobalOptions(program
178
- .command("logs")
179
- .description("View orchestrator logs")
180
- .option("-f, --follow", "Follow new log lines")
181
- .option("--issue <issue>", "Filter by issue identifier")
182
- .option("--run <runId>", "Read events for a specific run")
183
- .option("--level <level>", "Filter by log level")
184
- .option("--project-id <projectId>", "Project identifier")
185
- .addOption(new Option("--project <projectId>").hideHelp())
186
- .allowExcessArguments(false)).action(async function () {
187
- markInvoked();
188
- const values = this.optsWithGlobals();
189
- const args = [];
190
- pushOption(args, "--project-id", resolveProjectId(values));
191
- pushOption(args, "--follow", values.follow);
192
- pushOption(args, "--issue", values.issue);
193
- pushOption(args, "--run", values.run);
194
- pushOption(args, "--level", values.level);
195
- await invokeHandler("logs", args, values);
196
- });
197
- const project = addGlobalOptions(program.command("project").description("Manage configured projects"));
198
- project.action(async function () {
199
- markInvoked();
200
- await invokeHandler("project", [], this.optsWithGlobals());
201
- });
202
- addGlobalOptions(project
203
- .command("add")
204
- .description("Add a new project")
205
- .option("--non-interactive", "Run without prompts")
206
- .option("--project <id>", "GitHub Project ID")
207
- .option("--workspace-dir <path>", "Workspace directory")
208
- .option("--assigned-only", "Limit processing to assigned issues")
209
- .allowExcessArguments(false)).action(async function () {
210
- markInvoked();
211
- const values = this.optsWithGlobals();
212
- const args = [];
213
- pushOption(args, "--non-interactive", values.nonInteractive);
214
- pushOption(args, "--project", values.project);
215
- pushOption(args, "--workspace-dir", values.workspaceDir);
216
- pushOption(args, "--assigned-only", values.assignedOnly);
217
- await invokeHandler("project", ["add", ...args], values);
218
- });
219
- addGlobalOptions(project.command("list").description("List configured projects")).action(async function () {
220
- markInvoked();
221
- const values = this.optsWithGlobals();
222
- await invokeHandler("project", ["list"], values);
223
- });
224
- addGlobalOptions(project
225
- .command("remove")
226
- .description("Remove a project")
227
- .argument("<projectId>", "Project identifier")
228
- .allowExcessArguments(false)).action(async function (projectId) {
229
- markInvoked();
230
- await invokeHandler("project", ["remove", projectId], this.optsWithGlobals());
231
- });
232
- addGlobalOptions(project
233
- .command("start")
234
- .description("Start a specific project")
235
- .option("-d, --daemon", "Start in daemon mode")
236
- .option("--log-level <level>", "Orchestrator lifecycle log level")
237
- .option("--project-id <projectId>", "Project identifier")
238
- .addOption(new Option("--project <projectId>").hideHelp())
239
- .allowExcessArguments(false)).action(async function () {
240
- markInvoked();
241
- const values = this.optsWithGlobals();
242
- const args = ["start"];
243
- pushOption(args, "--project-id", resolveProjectId(values));
244
- pushOption(args, "--daemon", values.daemon);
245
- pushOption(args, "--log-level", values.logLevel);
246
- await invokeHandler("project", args, values);
247
- });
248
- addGlobalOptions(project
249
- .command("stop")
250
- .description("Stop a specific project")
251
- .option("--force", "Force stop with SIGKILL")
252
- .option("--project-id <projectId>", "Project identifier")
253
- .addOption(new Option("--project <projectId>").hideHelp())
254
- .allowExcessArguments(false)).action(async function () {
255
- markInvoked();
256
- const values = this.optsWithGlobals();
257
- const args = ["stop"];
258
- pushOption(args, "--project-id", resolveProjectId(values));
259
- pushOption(args, "--force", values.force);
260
- await invokeHandler("project", args, values);
261
- });
262
- addGlobalOptions(project.command("switch").description("Switch the active project")).action(async function () {
263
- markInvoked();
264
- await invokeHandler("project", ["switch"], this.optsWithGlobals());
265
- });
266
- addGlobalOptions(project
267
- .command("status")
268
- .description("Show status for a specific project")
269
- .option("-w, --watch", "Watch status continuously")
270
- .option("--project-id <projectId>", "Project identifier")
271
- .addOption(new Option("--project <projectId>").hideHelp())
272
- .allowExcessArguments(false)).action(async function () {
273
- markInvoked();
274
- const values = this.optsWithGlobals();
275
- const args = ["status"];
276
- pushOption(args, "--project-id", resolveProjectId(values));
277
- pushOption(args, "--watch", values.watch);
278
- await invokeHandler("project", args, values);
279
- });
280
- const repo = addGlobalOptions(program
281
- .command("repo")
282
- .description("Manage repositories in the active project"));
283
- repo.action(async function () {
284
- markInvoked();
285
- await invokeHandler("repo", [], this.optsWithGlobals());
286
- });
287
- addGlobalOptions(repo.command("list").description("List repositories")).action(async function () {
288
- markInvoked();
289
- await invokeHandler("repo", ["list"], this.optsWithGlobals());
290
- });
291
- addGlobalOptions(repo
292
- .command("add")
293
- .description("Add a repository")
294
- .argument("<owner/name>", "Repository spec")
295
- .allowExcessArguments(false)).action(async function (repoSpec) {
296
- markInvoked();
297
- await invokeHandler("repo", ["add", repoSpec], this.optsWithGlobals());
298
- });
299
- addGlobalOptions(repo
300
- .command("remove")
301
- .description("Remove a repository")
302
- .argument("<owner/name>", "Repository spec")
303
- .allowExcessArguments(false)).action(async function (repoSpec) {
304
- markInvoked();
305
- await invokeHandler("repo", ["remove", repoSpec], this.optsWithGlobals());
306
- });
307
- const config = addGlobalOptions(program.command("config").description("Manage CLI configuration"));
308
- config.action(async function () {
309
- markInvoked();
310
- await invokeHandler("config", [], this.optsWithGlobals());
311
- });
312
- addGlobalOptions(config.command("show").description("Show configuration")).action(async function () {
313
- markInvoked();
314
- await invokeHandler("config", ["show"], this.optsWithGlobals());
315
- });
316
- addGlobalOptions(config
317
- .command("set")
318
- .description("Set a configuration value")
319
- .argument("<key>", "Configuration key")
320
- .argument("<value>", "Configuration value")
321
- .allowExcessArguments(false)).action(async function (key, value) {
322
- markInvoked();
323
- await invokeHandler("config", ["set", key, value], this.optsWithGlobals());
324
- });
325
- addGlobalOptions(config.command("edit").description("Open config in $EDITOR")).action(async function () {
326
- markInvoked();
327
- await invokeHandler("config", ["edit"], this.optsWithGlobals());
328
- });
329
- addGlobalOptions(program
330
- .command("completion")
331
- .description("Print shell completion script")
332
- .argument("<shell>", "Shell name", shellArgument)
333
- .allowExcessArguments(false)).action(async function (shell) {
334
- markInvoked();
335
- process.stdout.write(renderCompletionScript(shell));
336
- });
337
- program
338
- .command("version")
339
- .description("Show version")
340
- .allowExcessArguments(false)
341
- .action(async function () {
342
- markInvoked();
343
- await invokeHandler("version", [], this.optsWithGlobals());
344
- });
345
- return { program, wasInvoked: () => actionInvoked };
309
+ let actionInvoked = false;
310
+ const markInvoked = () => {
311
+ actionInvoked = true;
312
+ };
313
+ const program = addGlobalOptions(
314
+ new Command().name("gh-symphony").description("AI Coding Agent Orchestrator").exitOverride().helpOption("-h, --help", "Show help").addHelpCommand("help [command]", "Show help for command").showHelpAfterError("(run with --help for usage)").option("-V, --version", "Show version")
315
+ );
316
+ addGlobalOptions(
317
+ program.command("init").description("Interactive project setup wizard").allowExcessArguments(false)
318
+ ).action(async function() {
319
+ markInvoked();
320
+ await invokeHandler("init", [], this.optsWithGlobals());
321
+ });
322
+ addGlobalOptions(
323
+ program.command("start").description("Start the orchestrator").option("-d, --daemon", "Start in daemon mode").option("--http [port]", "Expose dashboard and refresh endpoints over HTTP").option("--log-level <level>", "Orchestrator lifecycle log level").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
324
+ ).action(async function() {
325
+ markInvoked();
326
+ const values = this.optsWithGlobals();
327
+ const args = [];
328
+ pushOption(args, "--project-id", resolveProjectId(values));
329
+ pushOption(args, "--daemon", values.daemon);
330
+ pushOption(args, "--http", values.http);
331
+ pushOption(args, "--log-level", values.logLevel);
332
+ await invokeHandler("start", args, values);
333
+ });
334
+ addGlobalOptions(
335
+ program.command("stop").description("Stop the background orchestrator").option("--force", "Force stop with SIGKILL").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
336
+ ).action(async function() {
337
+ markInvoked();
338
+ const values = this.optsWithGlobals();
339
+ const args = [];
340
+ pushOption(args, "--project-id", resolveProjectId(values));
341
+ pushOption(args, "--force", values.force);
342
+ await invokeHandler("stop", args, values);
343
+ });
344
+ addGlobalOptions(
345
+ program.command("status").description("Show orchestrator status").option("-w, --watch", "Watch status continuously").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
346
+ ).action(async function() {
347
+ markInvoked();
348
+ const values = this.optsWithGlobals();
349
+ const args = [];
350
+ pushOption(args, "--project-id", resolveProjectId(values));
351
+ pushOption(args, "--watch", values.watch);
352
+ await invokeHandler("status", args, values);
353
+ });
354
+ addGlobalOptions(
355
+ program.command("run").description("Dispatch a single issue").argument("<issue>", "Issue identifier").option("--log-level <level>", "Orchestrator lifecycle log level").option("-w, --watch", "Watch status after dispatch").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
356
+ ).action(async function(issue) {
357
+ markInvoked();
358
+ const values = this.optsWithGlobals();
359
+ const args = [issue];
360
+ pushOption(args, "--project-id", resolveProjectId(values));
361
+ pushOption(args, "--log-level", values.logLevel);
362
+ pushOption(args, "--watch", values.watch);
363
+ await invokeHandler("run", args, values);
364
+ });
365
+ addGlobalOptions(
366
+ program.command("recover").description("Recover stalled runs").option("--dry-run", "Show recoverable runs without recovering").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
367
+ ).action(async function() {
368
+ markInvoked();
369
+ const values = this.optsWithGlobals();
370
+ const args = [];
371
+ pushOption(args, "--project-id", resolveProjectId(values));
372
+ pushOption(args, "--dry-run", values.dryRun);
373
+ await invokeHandler("recover", args, values);
374
+ });
375
+ addGlobalOptions(
376
+ program.command("logs").description("View orchestrator logs").option("-f, --follow", "Follow new log lines").option("--issue <issue>", "Filter by issue identifier").option("--run <runId>", "Read events for a specific run").option("--level <level>", "Filter by log level").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
377
+ ).action(async function() {
378
+ markInvoked();
379
+ const values = this.optsWithGlobals();
380
+ const args = [];
381
+ pushOption(args, "--project-id", resolveProjectId(values));
382
+ pushOption(args, "--follow", values.follow);
383
+ pushOption(args, "--issue", values.issue);
384
+ pushOption(args, "--run", values.run);
385
+ pushOption(args, "--level", values.level);
386
+ await invokeHandler("logs", args, values);
387
+ });
388
+ const project = addGlobalOptions(
389
+ program.command("project").description("Manage configured projects")
390
+ );
391
+ project.action(async function() {
392
+ markInvoked();
393
+ await invokeHandler("project", [], this.optsWithGlobals());
394
+ });
395
+ addGlobalOptions(
396
+ project.command("add").description("Add a new project").option("--non-interactive", "Run without prompts").option("--project <id>", "GitHub Project ID").option("--workspace-dir <path>", "Workspace directory").option("--assigned-only", "Limit processing to assigned issues").allowExcessArguments(false)
397
+ ).action(async function() {
398
+ markInvoked();
399
+ const values = this.optsWithGlobals();
400
+ const args = [];
401
+ pushOption(args, "--non-interactive", values.nonInteractive);
402
+ pushOption(args, "--project", values.project);
403
+ pushOption(args, "--workspace-dir", values.workspaceDir);
404
+ pushOption(args, "--assigned-only", values.assignedOnly);
405
+ await invokeHandler("project", ["add", ...args], values);
406
+ });
407
+ addGlobalOptions(
408
+ project.command("list").description("List configured projects")
409
+ ).action(async function() {
410
+ markInvoked();
411
+ const values = this.optsWithGlobals();
412
+ await invokeHandler("project", ["list"], values);
413
+ });
414
+ addGlobalOptions(
415
+ project.command("remove").description("Remove a project").argument("<projectId>", "Project identifier").allowExcessArguments(false)
416
+ ).action(async function(projectId) {
417
+ markInvoked();
418
+ await invokeHandler(
419
+ "project",
420
+ ["remove", projectId],
421
+ this.optsWithGlobals()
422
+ );
423
+ });
424
+ addGlobalOptions(
425
+ project.command("start").description("Start a specific project").option("-d, --daemon", "Start in daemon mode").option("--http [port]", "Expose dashboard and refresh endpoints over HTTP").option("--log-level <level>", "Orchestrator lifecycle log level").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
426
+ ).action(async function() {
427
+ markInvoked();
428
+ const values = this.optsWithGlobals();
429
+ const args = ["start"];
430
+ pushOption(args, "--project-id", resolveProjectId(values));
431
+ pushOption(args, "--daemon", values.daemon);
432
+ pushOption(args, "--http", values.http);
433
+ pushOption(args, "--log-level", values.logLevel);
434
+ await invokeHandler("project", args, values);
435
+ });
436
+ addGlobalOptions(
437
+ project.command("stop").description("Stop a specific project").option("--force", "Force stop with SIGKILL").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
438
+ ).action(async function() {
439
+ markInvoked();
440
+ const values = this.optsWithGlobals();
441
+ const args = ["stop"];
442
+ pushOption(args, "--project-id", resolveProjectId(values));
443
+ pushOption(args, "--force", values.force);
444
+ await invokeHandler("project", args, values);
445
+ });
446
+ addGlobalOptions(
447
+ project.command("switch").description("Switch the active project")
448
+ ).action(async function() {
449
+ markInvoked();
450
+ await invokeHandler(
451
+ "project",
452
+ ["switch"],
453
+ this.optsWithGlobals()
454
+ );
455
+ });
456
+ addGlobalOptions(
457
+ project.command("status").description("Show status for a specific project").option("-w, --watch", "Watch status continuously").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
458
+ ).action(async function() {
459
+ markInvoked();
460
+ const values = this.optsWithGlobals();
461
+ const args = ["status"];
462
+ pushOption(args, "--project-id", resolveProjectId(values));
463
+ pushOption(args, "--watch", values.watch);
464
+ await invokeHandler("project", args, values);
465
+ });
466
+ const repo = addGlobalOptions(
467
+ program.command("repo").description("Manage repositories in the active project")
468
+ );
469
+ repo.action(async function() {
470
+ markInvoked();
471
+ await invokeHandler("repo", [], this.optsWithGlobals());
472
+ });
473
+ addGlobalOptions(
474
+ repo.command("list").description("List repositories")
475
+ ).action(async function() {
476
+ markInvoked();
477
+ await invokeHandler(
478
+ "repo",
479
+ ["list"],
480
+ this.optsWithGlobals()
481
+ );
482
+ });
483
+ addGlobalOptions(
484
+ repo.command("add").description("Add a repository").argument("<owner/name>", "Repository spec").allowExcessArguments(false)
485
+ ).action(async function(repoSpec) {
486
+ markInvoked();
487
+ await invokeHandler(
488
+ "repo",
489
+ ["add", repoSpec],
490
+ this.optsWithGlobals()
491
+ );
492
+ });
493
+ addGlobalOptions(
494
+ repo.command("remove").description("Remove a repository").argument("<owner/name>", "Repository spec").allowExcessArguments(false)
495
+ ).action(async function(repoSpec) {
496
+ markInvoked();
497
+ await invokeHandler(
498
+ "repo",
499
+ ["remove", repoSpec],
500
+ this.optsWithGlobals()
501
+ );
502
+ });
503
+ const config = addGlobalOptions(
504
+ program.command("config").description("Manage CLI configuration")
505
+ );
506
+ config.action(async function() {
507
+ markInvoked();
508
+ await invokeHandler("config", [], this.optsWithGlobals());
509
+ });
510
+ addGlobalOptions(
511
+ config.command("show").description("Show configuration")
512
+ ).action(async function() {
513
+ markInvoked();
514
+ await invokeHandler(
515
+ "config",
516
+ ["show"],
517
+ this.optsWithGlobals()
518
+ );
519
+ });
520
+ addGlobalOptions(
521
+ config.command("set").description("Set a configuration value").argument("<key>", "Configuration key").argument("<value>", "Configuration value").allowExcessArguments(false)
522
+ ).action(async function(key, value) {
523
+ markInvoked();
524
+ await invokeHandler(
525
+ "config",
526
+ ["set", key, value],
527
+ this.optsWithGlobals()
528
+ );
529
+ });
530
+ addGlobalOptions(
531
+ config.command("edit").description("Open config in $EDITOR")
532
+ ).action(async function() {
533
+ markInvoked();
534
+ await invokeHandler(
535
+ "config",
536
+ ["edit"],
537
+ this.optsWithGlobals()
538
+ );
539
+ });
540
+ addGlobalOptions(
541
+ program.command("completion").description("Print shell completion script").argument("<shell>", "Shell name", shellArgument).allowExcessArguments(false)
542
+ ).action(async function(shell) {
543
+ markInvoked();
544
+ process.stdout.write(renderCompletionScript(shell));
545
+ });
546
+ program.command("version").description("Show version").allowExcessArguments(false).action(async function() {
547
+ markInvoked();
548
+ await invokeHandler(
549
+ "version",
550
+ [],
551
+ this.optsWithGlobals()
552
+ );
553
+ });
554
+ return { program, wasInvoked: () => actionInvoked };
346
555
  }
347
- export async function runCli(argv) {
348
- const { program, wasInvoked } = createProgram();
349
- if (hasVersionFlag(argv)) {
350
- const versionModule = await COMMANDS.version();
351
- await versionModule.default([], resolveVersionOptions(argv));
352
- return;
556
+ async function runCli(argv) {
557
+ const { program, wasInvoked } = createProgram();
558
+ if (hasVersionFlag(argv)) {
559
+ const versionModule = await COMMANDS.version();
560
+ await versionModule.default([], resolveVersionOptions(argv));
561
+ return;
562
+ }
563
+ try {
564
+ await program.parseAsync(["node", "gh-symphony", ...argv], {
565
+ from: "node"
566
+ });
567
+ if (!wasInvoked()) {
568
+ program.outputHelp();
353
569
  }
354
- try {
355
- await program.parseAsync(["node", "gh-symphony", ...argv], {
356
- from: "node",
357
- });
358
- if (!wasInvoked()) {
359
- program.outputHelp();
360
- }
570
+ } catch (error) {
571
+ if (error instanceof CommanderError && error.code === "commander.helpDisplayed") {
572
+ return;
361
573
  }
362
- catch (error) {
363
- if (error instanceof CommanderError &&
364
- error.code === "commander.helpDisplayed") {
365
- return;
366
- }
367
- if (error instanceof CommanderError) {
368
- process.exitCode = error.exitCode;
369
- return;
370
- }
371
- throw error;
574
+ if (error instanceof CommanderError) {
575
+ process.exitCode = error.exitCode;
576
+ return;
372
577
  }
578
+ throw error;
579
+ }
373
580
  }
374
581
  async function main() {
375
- await runCli(process.argv.slice(2));
582
+ await runCli(process.argv.slice(2));
376
583
  }
377
- if (process.argv[1] &&
378
- import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
379
- main().catch((error) => {
380
- process.stderr.write(`${error instanceof Error ? error.message : "Unknown error"}\n`);
381
- process.exitCode = 1;
382
- });
584
+ if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
585
+ main().catch((error) => {
586
+ process.stderr.write(
587
+ `${error instanceof Error ? error.message : "Unknown error"}
588
+ `
589
+ );
590
+ process.exitCode = 1;
591
+ });
383
592
  }
593
+ export {
594
+ runCli
595
+ };