@gh-symphony/cli 0.0.19 → 0.0.21
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.
- package/README.md +30 -2
- package/dist/chunk-A67CMOYE.js +684 -0
- package/dist/{chunk-TILHWBP6.js → chunk-C67H3OUL.js} +239 -36
- package/dist/{chunk-RN2PACNV.js → chunk-JN3TQVFV.js} +721 -74
- package/dist/{chunk-GKENCODJ.js → chunk-KY6WKH66.js} +437 -101
- package/dist/{chunk-6CI3UUMH.js → chunk-MYVJ6HK4.js} +950 -1240
- package/dist/{chunk-M3IFVLQS.js → chunk-QEONJ5DZ.js} +978 -72
- package/dist/{chunk-H2YXSYOZ.js → chunk-S6VIK4FF.js} +59 -31
- package/dist/chunk-SXGT7LOF.js +1060 -0
- package/dist/{doctor-IYHCFXOZ.js → doctor-4HBRICHP.js} +102 -37
- package/dist/index.js +38 -17
- package/dist/{init-KZT6YNOH.js → init-HZ3JEDGQ.js} +7 -2
- package/dist/{project-DNALEWO3.js → project-25NQ4J4Y.js} +8 -6
- package/dist/{recover-C3V2QAUB.js → recover-L3MJHHDA.js} +4 -2
- package/dist/{repo-HDDE7OUI.js → repo-TDCWQR6P.js} +72 -14
- package/dist/{run-XI2S5Y4V.js → run-XJQ6BF7U.js} +4 -2
- package/dist/{setup-K4CYYJBF.js → setup-B2SVLW2R.js} +46 -8
- package/dist/{start-M6IQGRFO.js → start-I2CC7BLW.js} +6 -4
- package/dist/{upgrade-F4VE4XBS.js → upgrade-OJXPZRYE.js} +2 -2
- package/dist/{version-Y5RYNWMF.js → version-TBDCTKDO.js} +1 -1
- package/dist/worker-entry.js +522 -867
- package/dist/{workflow-TBIFY5MO.js → workflow-BLJH2HC3.js} +176 -10
- package/package.json +5 -3
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
parseWorkflowMarkdown
|
|
4
|
-
} from "./chunk-M3IFVLQS.js";
|
|
5
2
|
import {
|
|
6
3
|
GitHubApiError,
|
|
7
4
|
REQUIRED_GH_SCOPES,
|
|
@@ -15,7 +12,14 @@ import {
|
|
|
15
12
|
runGhAuthLogin,
|
|
16
13
|
runGhAuthRefresh,
|
|
17
14
|
validateGitHubToken
|
|
18
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-C67H3OUL.js";
|
|
16
|
+
import {
|
|
17
|
+
isClaudeRuntimeCommand,
|
|
18
|
+
parseWorkflowMarkdown,
|
|
19
|
+
resolveClaudeCommandBinary,
|
|
20
|
+
resolveRuntimeCommandBinary,
|
|
21
|
+
runClaudePreflight
|
|
22
|
+
} from "./chunk-QEONJ5DZ.js";
|
|
19
23
|
import {
|
|
20
24
|
resolveRuntimeRoot
|
|
21
25
|
} from "./chunk-5NV3LSAJ.js";
|
|
@@ -55,7 +59,8 @@ var DEFAULT_DEPENDENCIES = {
|
|
|
55
59
|
stdinIsTTY: process.stdin.isTTY === true,
|
|
56
60
|
stdoutIsTTY: process.stdout.isTTY === true,
|
|
57
61
|
execPath: process.execPath,
|
|
58
|
-
cliArgv: [...process.argv]
|
|
62
|
+
cliArgv: [...process.argv],
|
|
63
|
+
fetchImpl: fetch
|
|
59
64
|
};
|
|
60
65
|
var MINIMUM_NODE_MAJOR = 24;
|
|
61
66
|
var MINIMUM_NODE_VERSION = `v${MINIMUM_NODE_MAJOR}.0.0`;
|
|
@@ -98,6 +103,17 @@ function failCheck(id, title, summary, remediation, details) {
|
|
|
98
103
|
details
|
|
99
104
|
};
|
|
100
105
|
}
|
|
106
|
+
function warnCheck(id, title, summary, remediation, details) {
|
|
107
|
+
return {
|
|
108
|
+
id,
|
|
109
|
+
title,
|
|
110
|
+
status: "warn",
|
|
111
|
+
required: true,
|
|
112
|
+
summary,
|
|
113
|
+
remediation,
|
|
114
|
+
details
|
|
115
|
+
};
|
|
116
|
+
}
|
|
101
117
|
function formatAuthSource(source) {
|
|
102
118
|
return source === "env" ? "GITHUB_GRAPHQL_TOKEN" : "gh CLI";
|
|
103
119
|
}
|
|
@@ -233,31 +249,27 @@ async function commandExistsOnPath(binary, deps) {
|
|
|
233
249
|
}
|
|
234
250
|
return false;
|
|
235
251
|
}
|
|
236
|
-
function
|
|
237
|
-
const
|
|
238
|
-
if (
|
|
239
|
-
return
|
|
252
|
+
function toDoctorClaudeCheck(check) {
|
|
253
|
+
const id = check.id;
|
|
254
|
+
if (check.status === "pass") {
|
|
255
|
+
return passCheck(id, check.title, check.summary, check.details);
|
|
240
256
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return value === "-c" || value === "-lc";
|
|
250
|
-
});
|
|
251
|
-
if (flagIndex >= 0 && flagIndex + 1 < tokens.length) {
|
|
252
|
-
const nested = stripQuotes(tokens[flagIndex + 1]);
|
|
253
|
-
const nestedTokens = nested.match(/"[^"]*"|'[^']*'|\S+/g) ?? [];
|
|
254
|
-
return nestedTokens.length > 0 ? stripQuotes(nestedTokens[0]) : shell;
|
|
255
|
-
}
|
|
257
|
+
if (check.status === "warn") {
|
|
258
|
+
return warnCheck(
|
|
259
|
+
id,
|
|
260
|
+
check.title,
|
|
261
|
+
check.summary,
|
|
262
|
+
check.remediation,
|
|
263
|
+
check.details
|
|
264
|
+
);
|
|
256
265
|
}
|
|
257
|
-
return
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
266
|
+
return failCheck(
|
|
267
|
+
id,
|
|
268
|
+
check.title,
|
|
269
|
+
check.summary,
|
|
270
|
+
check.remediation ?? "Fix the Claude runtime readiness check.",
|
|
271
|
+
check.details
|
|
272
|
+
);
|
|
261
273
|
}
|
|
262
274
|
function parseMajorNodeVersion(version) {
|
|
263
275
|
const matched = version.match(/^v?(\d+)(?:\.\d+)?(?:\.\d+)?$/);
|
|
@@ -276,7 +288,10 @@ async function checkGitInstallation(deps) {
|
|
|
276
288
|
encoding: "utf8",
|
|
277
289
|
stdio: ["pipe", "pipe", "pipe"]
|
|
278
290
|
}).toString().trim();
|
|
279
|
-
return version ? { installed: true, version } : {
|
|
291
|
+
return version ? { installed: true, version } : {
|
|
292
|
+
installed: false,
|
|
293
|
+
error: "git --version returned an empty response."
|
|
294
|
+
};
|
|
280
295
|
} catch (error) {
|
|
281
296
|
return {
|
|
282
297
|
installed: false,
|
|
@@ -387,7 +402,11 @@ Usage: gh-symphony doctor [--project-id <project-id>] [--fix]`
|
|
|
387
402
|
const ghInstalled = deps.checkGhInstalled();
|
|
388
403
|
if (ghInstalled) {
|
|
389
404
|
checks.push(
|
|
390
|
-
passCheck(
|
|
405
|
+
passCheck(
|
|
406
|
+
"gh_installation",
|
|
407
|
+
"gh CLI installation",
|
|
408
|
+
"gh CLI is installed."
|
|
409
|
+
)
|
|
391
410
|
);
|
|
392
411
|
} else if (envToken) {
|
|
393
412
|
checks.push(
|
|
@@ -664,7 +683,7 @@ Usage: gh-symphony doctor [--project-id <project-id>] [--fix]`
|
|
|
664
683
|
);
|
|
665
684
|
}
|
|
666
685
|
if (workflow.status === "pass") {
|
|
667
|
-
const binary =
|
|
686
|
+
const binary = resolveRuntimeCommandBinary(workflow.command);
|
|
668
687
|
if (binary && await commandExistsOnPath(binary, deps)) {
|
|
669
688
|
checks.push(
|
|
670
689
|
passCheck(
|
|
@@ -685,6 +704,24 @@ Usage: gh-symphony doctor [--project-id <project-id>] [--fix]`
|
|
|
685
704
|
)
|
|
686
705
|
);
|
|
687
706
|
}
|
|
707
|
+
if (isClaudeRuntimeCommand(workflow.command)) {
|
|
708
|
+
const claudePreflight = await runClaudePreflight(
|
|
709
|
+
{
|
|
710
|
+
cwd: process.cwd(),
|
|
711
|
+
env: process.env,
|
|
712
|
+
command: resolveClaudeCommandBinary(workflow.command) ?? void 0,
|
|
713
|
+
includeGhAuth: false
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
execFileSync: deps.execFileSync,
|
|
717
|
+
readFile: deps.readFile,
|
|
718
|
+
access: deps.access,
|
|
719
|
+
fetchImpl: deps.fetchImpl,
|
|
720
|
+
platform: deps.platform
|
|
721
|
+
}
|
|
722
|
+
);
|
|
723
|
+
checks.push(...claudePreflight.checks.map(toDoctorClaudeCheck));
|
|
724
|
+
}
|
|
688
725
|
} else {
|
|
689
726
|
checks.push(
|
|
690
727
|
failCheck(
|
|
@@ -697,7 +734,7 @@ Usage: gh-symphony doctor [--project-id <project-id>] [--fix]`
|
|
|
697
734
|
);
|
|
698
735
|
}
|
|
699
736
|
return {
|
|
700
|
-
ok: checks.every((check) => check.status
|
|
737
|
+
ok: checks.every((check) => check.status !== "fail"),
|
|
701
738
|
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
702
739
|
configDir: options.configDir,
|
|
703
740
|
projectId: resolvedProjectId,
|
|
@@ -749,9 +786,13 @@ function runCliRemediation(title, checkId, args, deps, options, interactive, det
|
|
|
749
786
|
details
|
|
750
787
|
);
|
|
751
788
|
}
|
|
752
|
-
const result = deps.spawnSync(
|
|
753
|
-
|
|
754
|
-
|
|
789
|
+
const result = deps.spawnSync(
|
|
790
|
+
deps.execPath,
|
|
791
|
+
[cliEntry, "--config", options.configDir, ...args],
|
|
792
|
+
{
|
|
793
|
+
stdio: "inherit"
|
|
794
|
+
}
|
|
795
|
+
);
|
|
755
796
|
if ((result.status ?? 1) === 0) {
|
|
756
797
|
return remediationStep(
|
|
757
798
|
`remediate_${checkId}`,
|
|
@@ -1007,7 +1048,15 @@ async function runDoctorFixes(report, deps, options) {
|
|
|
1007
1048
|
const reason = typeof check.details?.reason === "string" ? check.details.reason : null;
|
|
1008
1049
|
const title = reason === "missing" ? "Repository workflow initialization" : "Repository workflow regeneration";
|
|
1009
1050
|
steps.push(
|
|
1010
|
-
runCliRemediation(
|
|
1051
|
+
runCliRemediation(
|
|
1052
|
+
title,
|
|
1053
|
+
check.id,
|
|
1054
|
+
["init"],
|
|
1055
|
+
deps,
|
|
1056
|
+
options,
|
|
1057
|
+
interactive,
|
|
1058
|
+
check.details
|
|
1059
|
+
)
|
|
1011
1060
|
);
|
|
1012
1061
|
break;
|
|
1013
1062
|
}
|
|
@@ -1037,6 +1086,21 @@ async function runDoctorFixes(report, deps, options) {
|
|
|
1037
1086
|
);
|
|
1038
1087
|
break;
|
|
1039
1088
|
}
|
|
1089
|
+
case "claude_binary":
|
|
1090
|
+
case "anthropic_api_key":
|
|
1091
|
+
case "claude_mcp_config":
|
|
1092
|
+
steps.push(
|
|
1093
|
+
remediationStep(
|
|
1094
|
+
`remediate_${check.id}`,
|
|
1095
|
+
check.id,
|
|
1096
|
+
check.title,
|
|
1097
|
+
"manual",
|
|
1098
|
+
check.remediation ?? "Fix the Claude runtime readiness check.",
|
|
1099
|
+
void 0,
|
|
1100
|
+
check.details
|
|
1101
|
+
)
|
|
1102
|
+
);
|
|
1103
|
+
break;
|
|
1040
1104
|
}
|
|
1041
1105
|
}
|
|
1042
1106
|
return steps;
|
|
@@ -1060,7 +1124,8 @@ function renderTextReport(report) {
|
|
|
1060
1124
|
lines.push("");
|
|
1061
1125
|
}
|
|
1062
1126
|
for (const check of report.checks) {
|
|
1063
|
-
|
|
1127
|
+
const statusLabel = check.status === "pass" ? "PASS" : check.status === "warn" ? "WARN" : "FAIL";
|
|
1128
|
+
lines.push(`${statusLabel} ${check.title}`);
|
|
1064
1129
|
lines.push(` ${check.summary}`);
|
|
1065
1130
|
if (check.remediation) {
|
|
1066
1131
|
lines.push(` Fix: ${check.remediation}`);
|
package/dist/index.js
CHANGED
|
@@ -278,21 +278,21 @@ ${bashFunction}complete -F _gh_symphony_completion gh-symphony
|
|
|
278
278
|
|
|
279
279
|
// src/index.ts
|
|
280
280
|
var COMMANDS = {
|
|
281
|
-
workflow: () => import("./workflow-
|
|
282
|
-
init: () => import("./init-
|
|
283
|
-
setup: () => import("./setup-
|
|
284
|
-
doctor: () => import("./doctor-
|
|
285
|
-
upgrade: () => import("./upgrade-
|
|
286
|
-
start: () => import("./start-
|
|
281
|
+
workflow: () => import("./workflow-BLJH2HC3.js"),
|
|
282
|
+
init: () => import("./init-HZ3JEDGQ.js"),
|
|
283
|
+
setup: () => import("./setup-B2SVLW2R.js"),
|
|
284
|
+
doctor: () => import("./doctor-4HBRICHP.js"),
|
|
285
|
+
upgrade: () => import("./upgrade-OJXPZRYE.js"),
|
|
286
|
+
start: () => import("./start-I2CC7BLW.js"),
|
|
287
287
|
stop: () => import("./stop-7MFCBQVW.js"),
|
|
288
288
|
status: () => import("./status-QSCFVGRQ.js"),
|
|
289
|
-
run: () => import("./run-
|
|
290
|
-
recover: () => import("./recover-
|
|
289
|
+
run: () => import("./run-XJQ6BF7U.js"),
|
|
290
|
+
recover: () => import("./recover-L3MJHHDA.js"),
|
|
291
291
|
logs: () => import("./logs-6JKKYDGJ.js"),
|
|
292
|
-
project: () => import("./project-
|
|
293
|
-
repo: () => import("./repo-
|
|
292
|
+
project: () => import("./project-25NQ4J4Y.js"),
|
|
293
|
+
repo: () => import("./repo-TDCWQR6P.js"),
|
|
294
294
|
config: () => import("./config-cmd-DNXNL26Z.js"),
|
|
295
|
-
version: () => import("./version-
|
|
295
|
+
version: () => import("./version-TBDCTKDO.js")
|
|
296
296
|
};
|
|
297
297
|
function addGlobalOptions(command) {
|
|
298
298
|
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");
|
|
@@ -356,7 +356,7 @@ function createProgram() {
|
|
|
356
356
|
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")
|
|
357
357
|
);
|
|
358
358
|
addGlobalOptions(
|
|
359
|
-
program.command("init", { hidden: true }).description("Alias for 'gh-symphony workflow init'").option("--non-interactive", "Run without prompts").option("--project <id>", "GitHub Project ID or URL").option("--output <path>", "Write WORKFLOW.md to a custom path").option("--skip-skills", "Skip runtime skill generation").option("--skip-context", "Skip .gh-symphony/context.yaml generation").option("--dry-run", "Preview generated files without writing them").allowExcessArguments(false)
|
|
359
|
+
program.command("init", { hidden: true }).description("Alias for 'gh-symphony workflow init'").option("--non-interactive", "Run without prompts").option("--project <id>", "GitHub Project ID or URL").option("--output <path>", "Write WORKFLOW.md to a custom path").option("--runtime <kind>", "Runtime preset: codex-app-server or claude-print").option("--skip-skills", "Skip runtime skill generation").option("--skip-context", "Skip .gh-symphony/context.yaml generation").option("--dry-run", "Preview generated files without writing them").allowExcessArguments(false)
|
|
360
360
|
).action(async function() {
|
|
361
361
|
markInvoked();
|
|
362
362
|
const values = this.optsWithGlobals();
|
|
@@ -364,6 +364,7 @@ function createProgram() {
|
|
|
364
364
|
pushOption(args, "--non-interactive", values.nonInteractive);
|
|
365
365
|
pushOption(args, "--project", values.project);
|
|
366
366
|
pushOption(args, "--output", values.output);
|
|
367
|
+
pushOption(args, "--runtime", values.runtime);
|
|
367
368
|
pushOption(args, "--skip-skills", values.skipSkills);
|
|
368
369
|
pushOption(args, "--skip-context", values.skipContext);
|
|
369
370
|
pushOption(args, "--dry-run", values.dryRun);
|
|
@@ -381,7 +382,7 @@ function createProgram() {
|
|
|
381
382
|
);
|
|
382
383
|
});
|
|
383
384
|
addGlobalOptions(
|
|
384
|
-
workflow.command("init").description("Generate WORKFLOW.md and workflow support files").option("--non-interactive", "Run without prompts").option("--project <id>", "GitHub Project ID or URL").option("--output <path>", "Write WORKFLOW.md to a custom path").option("--skip-skills", "Skip runtime skill generation").option("--skip-context", "Skip .gh-symphony/context.yaml generation").option("--dry-run", "Preview generated files without writing them").allowExcessArguments(false)
|
|
385
|
+
workflow.command("init").description("Generate WORKFLOW.md and workflow support files").option("--non-interactive", "Run without prompts").option("--project <id>", "GitHub Project ID or URL").option("--output <path>", "Write WORKFLOW.md to a custom path").option("--runtime <kind>", "Runtime preset: codex-app-server or claude-print").option("--skip-skills", "Skip runtime skill generation").option("--skip-context", "Skip .gh-symphony/context.yaml generation").option("--dry-run", "Preview generated files without writing them").allowExcessArguments(false)
|
|
385
386
|
).action(async function() {
|
|
386
387
|
markInvoked();
|
|
387
388
|
const values = this.optsWithGlobals();
|
|
@@ -389,6 +390,7 @@ function createProgram() {
|
|
|
389
390
|
pushOption(args, "--non-interactive", values.nonInteractive);
|
|
390
391
|
pushOption(args, "--project", values.project);
|
|
391
392
|
pushOption(args, "--output", values.output);
|
|
393
|
+
pushOption(args, "--runtime", values.runtime);
|
|
392
394
|
pushOption(args, "--skip-skills", values.skipSkills);
|
|
393
395
|
pushOption(args, "--skip-context", values.skipContext);
|
|
394
396
|
pushOption(args, "--dry-run", values.dryRun);
|
|
@@ -404,12 +406,14 @@ function createProgram() {
|
|
|
404
406
|
await invokeHandler("workflow", args, values);
|
|
405
407
|
});
|
|
406
408
|
addGlobalOptions(
|
|
407
|
-
workflow.command("preview").description("Render the final worker prompt from a sample issue").option("--file <path>", "Read a custom WORKFLOW.md path").option("--sample <json>", "Read sample issue JSON from a file").option("--attempt <n>", "Render as retry attempt n").allowExcessArguments(false)
|
|
409
|
+
workflow.command("preview").description("Render the final worker prompt from a sample or live issue").option("--file <path>", "Read a custom WORKFLOW.md path").option("--issue <owner/repo#number>", "Load a live GitHub Project issue").option("--project-id <projectId>", "Managed project identifier").addOption(new Option("--project <projectId>").hideHelp()).option("--sample <json>", "Read sample issue JSON from a file").option("--attempt <n>", "Render as retry attempt n").allowExcessArguments(false)
|
|
408
410
|
).action(async function() {
|
|
409
411
|
markInvoked();
|
|
410
412
|
const values = this.optsWithGlobals();
|
|
411
413
|
const args = ["preview"];
|
|
412
414
|
pushOption(args, "--file", values.file);
|
|
415
|
+
pushOption(args, "--issue", values.issue);
|
|
416
|
+
pushOption(args, "--project-id", resolveProjectId(values));
|
|
413
417
|
pushOption(args, "--sample", values.sample);
|
|
414
418
|
pushOption(args, "--attempt", values.attempt);
|
|
415
419
|
await invokeHandler("workflow", args, values);
|
|
@@ -430,7 +434,10 @@ function createProgram() {
|
|
|
430
434
|
await invokeHandler("setup", args, values);
|
|
431
435
|
});
|
|
432
436
|
addGlobalOptions(
|
|
433
|
-
program.command("doctor").description("Run diagnostics and optional first-run remediation").option("--project-id <projectId>", "Project identifier").option(
|
|
437
|
+
program.command("doctor").description("Run diagnostics and optional first-run remediation").option("--project-id <projectId>", "Project identifier").option(
|
|
438
|
+
"--fix",
|
|
439
|
+
"Apply safe remediation steps and print manual follow-ups"
|
|
440
|
+
).addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
|
|
434
441
|
).action(async function() {
|
|
435
442
|
markInvoked();
|
|
436
443
|
const values = this.optsWithGlobals();
|
|
@@ -446,7 +453,13 @@ function createProgram() {
|
|
|
446
453
|
await invokeHandler("upgrade", [], this.optsWithGlobals());
|
|
447
454
|
});
|
|
448
455
|
addGlobalOptions(
|
|
449
|
-
program.command("start").description("Start the orchestrator").option("-d, --daemon", "Start in daemon mode").option("--once", "Run a single orchestration tick and exit").option(
|
|
456
|
+
program.command("start").description("Start the orchestrator").option("-d, --daemon", "Start in daemon mode").option("--once", "Run a single orchestration tick and exit").option(
|
|
457
|
+
"--http [port]",
|
|
458
|
+
"Expose dashboard and refresh endpoints over HTTP"
|
|
459
|
+
).option(
|
|
460
|
+
"--web [port]",
|
|
461
|
+
"Expose the control plane web dashboard and API over HTTP"
|
|
462
|
+
).option("--log-level <level>", "Orchestrator lifecycle log level").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
|
|
450
463
|
).action(async function() {
|
|
451
464
|
markInvoked();
|
|
452
465
|
const values = this.optsWithGlobals();
|
|
@@ -455,6 +468,7 @@ function createProgram() {
|
|
|
455
468
|
pushOption(args, "--daemon", values.daemon);
|
|
456
469
|
pushOption(args, "--once", values.once);
|
|
457
470
|
pushOption(args, "--http", values.http);
|
|
471
|
+
pushOption(args, "--web", values.web);
|
|
458
472
|
pushOption(args, "--log-level", values.logLevel);
|
|
459
473
|
await invokeHandler("start", args, values);
|
|
460
474
|
});
|
|
@@ -549,7 +563,13 @@ function createProgram() {
|
|
|
549
563
|
);
|
|
550
564
|
});
|
|
551
565
|
addGlobalOptions(
|
|
552
|
-
project.command("start").description("Start a specific project").option("-d, --daemon", "Start in daemon mode").option("--once", "Run a single orchestration tick and exit").option(
|
|
566
|
+
project.command("start").description("Start a specific project").option("-d, --daemon", "Start in daemon mode").option("--once", "Run a single orchestration tick and exit").option(
|
|
567
|
+
"--http [port]",
|
|
568
|
+
"Expose dashboard and refresh endpoints over HTTP"
|
|
569
|
+
).option(
|
|
570
|
+
"--web [port]",
|
|
571
|
+
"Expose the control plane web dashboard and API over HTTP"
|
|
572
|
+
).option("--log-level <level>", "Orchestrator lifecycle log level").option("--project-id <projectId>", "Project identifier").addOption(new Option("--project <projectId>").hideHelp()).allowExcessArguments(false)
|
|
553
573
|
).action(async function() {
|
|
554
574
|
markInvoked();
|
|
555
575
|
const values = this.optsWithGlobals();
|
|
@@ -558,6 +578,7 @@ function createProgram() {
|
|
|
558
578
|
pushOption(args, "--daemon", values.daemon);
|
|
559
579
|
pushOption(args, "--once", values.once);
|
|
560
580
|
pushOption(args, "--http", values.http);
|
|
581
|
+
pushOption(args, "--web", values.web);
|
|
561
582
|
pushOption(args, "--log-level", values.logLevel);
|
|
562
583
|
await invokeHandler("project", args, values);
|
|
563
584
|
});
|
|
@@ -9,12 +9,15 @@ import {
|
|
|
9
9
|
planWorkflowArtifacts,
|
|
10
10
|
promptStateMappings,
|
|
11
11
|
renderDryRunPreview,
|
|
12
|
+
resolvePriorityField,
|
|
12
13
|
resolveStatusField,
|
|
14
|
+
warnIfProjectDiscoveryPartial,
|
|
13
15
|
writeConfig,
|
|
14
16
|
writeEcosystem,
|
|
15
17
|
writeWorkflowPlan
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-JN3TQVFV.js";
|
|
19
|
+
import "./chunk-C67H3OUL.js";
|
|
20
|
+
import "./chunk-QEONJ5DZ.js";
|
|
18
21
|
import "./chunk-ROGRTUFI.js";
|
|
19
22
|
export {
|
|
20
23
|
abortIfCancelled,
|
|
@@ -26,7 +29,9 @@ export {
|
|
|
26
29
|
planWorkflowArtifacts,
|
|
27
30
|
promptStateMappings,
|
|
28
31
|
renderDryRunPreview,
|
|
32
|
+
resolvePriorityField,
|
|
29
33
|
resolveStatusField,
|
|
34
|
+
warnIfProjectDiscoveryPartial,
|
|
30
35
|
writeConfig,
|
|
31
36
|
writeEcosystem,
|
|
32
37
|
writeWorkflowPlan
|
|
@@ -3,12 +3,14 @@ import {
|
|
|
3
3
|
project_default,
|
|
4
4
|
promptProjectRegistrationOptions,
|
|
5
5
|
renderProjectRegistrationSummary
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-S6VIK4FF.js";
|
|
7
|
+
import "./chunk-JN3TQVFV.js";
|
|
8
|
+
import "./chunk-KY6WKH66.js";
|
|
9
|
+
import "./chunk-MYVJ6HK4.js";
|
|
10
|
+
import "./chunk-A67CMOYE.js";
|
|
11
|
+
import "./chunk-SXGT7LOF.js";
|
|
12
|
+
import "./chunk-C67H3OUL.js";
|
|
13
|
+
import "./chunk-QEONJ5DZ.js";
|
|
12
14
|
import "./chunk-XN5ABWZ6.js";
|
|
13
15
|
import "./chunk-MVRF7BES.js";
|
|
14
16
|
import "./chunk-5NV3LSAJ.js";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runCli
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-MYVJ6HK4.js";
|
|
5
|
+
import "./chunk-A67CMOYE.js";
|
|
6
|
+
import "./chunk-SXGT7LOF.js";
|
|
7
|
+
import "./chunk-QEONJ5DZ.js";
|
|
6
8
|
import {
|
|
7
9
|
resolveRuntimeRoot
|
|
8
10
|
} from "./chunk-5NV3LSAJ.js";
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
GitHubRepositoryLookupError,
|
|
3
4
|
GitHubScopeError,
|
|
4
5
|
checkRequiredScopes,
|
|
5
6
|
createClient,
|
|
6
7
|
getGhToken,
|
|
7
8
|
getProjectDetail,
|
|
9
|
+
getRepositoryMetadata,
|
|
8
10
|
validateToken
|
|
9
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-C67H3OUL.js";
|
|
10
12
|
import {
|
|
11
13
|
loadActiveProjectConfig,
|
|
12
14
|
loadGlobalConfig,
|
|
@@ -77,6 +79,9 @@ function displayScopeError(error) {
|
|
|
77
79
|
function formatRepoSpec(repo) {
|
|
78
80
|
return `${repo.owner}/${repo.name}`;
|
|
79
81
|
}
|
|
82
|
+
function fallbackCloneUrl(repo) {
|
|
83
|
+
return `https://github.com/${repo.owner}/${repo.name}.git`;
|
|
84
|
+
}
|
|
80
85
|
function sortRepos(repos) {
|
|
81
86
|
return [...repos].sort(
|
|
82
87
|
(left, right) => formatRepoSpec(left).localeCompare(formatRepoSpec(right))
|
|
@@ -151,27 +156,79 @@ async function repoAdd(args, options) {
|
|
|
151
156
|
process.exitCode = 1;
|
|
152
157
|
return;
|
|
153
158
|
}
|
|
159
|
+
const activeProjectId = global.activeProject;
|
|
154
160
|
const [owner, name] = repoSpec.split("/");
|
|
155
161
|
if (!owner || !name) {
|
|
156
162
|
process.stderr.write("Invalid repo format. Use: owner/name\n");
|
|
157
163
|
process.exitCode = 2;
|
|
158
164
|
return;
|
|
159
165
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
166
|
+
const requestedRepo = { owner, name };
|
|
167
|
+
const addRepository = async (repo, message, warning) => {
|
|
168
|
+
if (ws.repositories.some((entry) => repoKey(entry) === repoKey(repo))) {
|
|
169
|
+
process.stdout.write(
|
|
170
|
+
`Repository ${formatRepoSpec(repo)} is already configured.
|
|
171
|
+
`
|
|
172
|
+
);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
ws.repositories.push(repo);
|
|
176
|
+
await saveProjectConfig(options.configDir, activeProjectId, ws);
|
|
177
|
+
if (warning) {
|
|
178
|
+
process.stderr.write(`${warning}
|
|
179
|
+
`);
|
|
180
|
+
}
|
|
181
|
+
process.stdout.write(`${message}
|
|
164
182
|
`);
|
|
183
|
+
};
|
|
184
|
+
let token;
|
|
185
|
+
try {
|
|
186
|
+
token = getGhToken();
|
|
187
|
+
} catch {
|
|
188
|
+
await addRepository(
|
|
189
|
+
{
|
|
190
|
+
...requestedRepo,
|
|
191
|
+
cloneUrl: fallbackCloneUrl(requestedRepo)
|
|
192
|
+
},
|
|
193
|
+
`Added repository without validation: ${formatRepoSpec(requestedRepo)}`,
|
|
194
|
+
"Warning: GitHub authentication is unavailable, so the repository was saved without validation. Run 'gh auth login --scopes repo,read:org,project' or set GITHUB_GRAPHQL_TOKEN to validate access before saving."
|
|
195
|
+
);
|
|
165
196
|
return;
|
|
166
197
|
}
|
|
167
|
-
|
|
168
|
-
owner,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
198
|
+
try {
|
|
199
|
+
const repository = await getRepositoryMetadata(createClient(token), owner, name);
|
|
200
|
+
await addRepository(
|
|
201
|
+
{
|
|
202
|
+
owner: repository.owner,
|
|
203
|
+
name: repository.name,
|
|
204
|
+
cloneUrl: repository.cloneUrl || fallbackCloneUrl(repository)
|
|
205
|
+
},
|
|
206
|
+
`Added repository after validation: ${formatRepoSpec(repository)}`
|
|
207
|
+
);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
if (error instanceof GitHubRepositoryLookupError && error.reason === "offline") {
|
|
210
|
+
await addRepository(
|
|
211
|
+
{
|
|
212
|
+
...requestedRepo,
|
|
213
|
+
cloneUrl: fallbackCloneUrl(requestedRepo)
|
|
214
|
+
},
|
|
215
|
+
`Added repository without validation: ${formatRepoSpec(requestedRepo)}`,
|
|
216
|
+
`Warning: ${error.message} Saved the repository without validation. ${error.remediation}`
|
|
217
|
+
);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (error instanceof GitHubRepositoryLookupError) {
|
|
221
|
+
process.stderr.write(`${error.message}
|
|
222
|
+
${error.remediation}
|
|
174
223
|
`);
|
|
224
|
+
} else {
|
|
225
|
+
process.stderr.write(
|
|
226
|
+
`${error instanceof Error ? error.message : "Repository validation failed."}
|
|
227
|
+
`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
process.exitCode = 1;
|
|
231
|
+
}
|
|
175
232
|
}
|
|
176
233
|
async function repoRemove(args, options) {
|
|
177
234
|
const [repoSpec] = args;
|
|
@@ -193,8 +250,9 @@ async function repoRemove(args, options) {
|
|
|
193
250
|
return;
|
|
194
251
|
}
|
|
195
252
|
const [owner, name] = repoSpec.split("/");
|
|
253
|
+
const requestedRepo = { owner, name };
|
|
196
254
|
const idx = ws.repositories.findIndex(
|
|
197
|
-
(r) => r
|
|
255
|
+
(r) => repoKey(r) === repoKey(requestedRepo)
|
|
198
256
|
);
|
|
199
257
|
if (idx === -1) {
|
|
200
258
|
process.stderr.write(`Repository ${repoSpec} is not configured.
|
|
@@ -204,7 +262,7 @@ async function repoRemove(args, options) {
|
|
|
204
262
|
}
|
|
205
263
|
ws.repositories.splice(idx, 1);
|
|
206
264
|
await saveProjectConfig(options.configDir, global.activeProject, ws);
|
|
207
|
-
process.stdout.write(`Removed repository: ${
|
|
265
|
+
process.stdout.write(`Removed repository: ${formatRepoSpec(requestedRepo)}
|
|
208
266
|
`);
|
|
209
267
|
}
|
|
210
268
|
async function repoSync(args, options) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runCli
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-MYVJ6HK4.js";
|
|
5
|
+
import "./chunk-A67CMOYE.js";
|
|
6
|
+
import "./chunk-SXGT7LOF.js";
|
|
7
|
+
import "./chunk-QEONJ5DZ.js";
|
|
6
8
|
import {
|
|
7
9
|
resolveRuntimeRoot
|
|
8
10
|
} from "./chunk-5NV3LSAJ.js";
|