@gh-symphony/cli 0.3.0 → 0.4.0
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 +2 -2
- package/dist/{chunk-5HQLPZR5.js → chunk-6OPRRC2J.js} +21 -1
- package/dist/{chunk-VHEGRYK7.js → chunk-B6G3KGBB.js} +210 -16
- package/dist/{chunk-2ZIPQ7ZS.js → chunk-QOX5UGUE.js} +1 -1
- package/dist/{chunk-GTNWFVFU.js → chunk-TTVGBHZI.js} +3 -3
- package/dist/{chunk-A7EFL6EJ.js → chunk-Z7CDL3T2.js} +1 -1
- package/dist/{chunk-GL55AKBI.js → chunk-ZPS4CQZJ.js} +357 -32
- package/dist/{doctor-3IIM4UYS.js → doctor-CCUTNEYN.js} +5 -5
- package/dist/index.js +6 -6
- package/dist/{repo-SLK4DDXH.js → repo-C2APQR2P.js} +21 -4
- package/dist/{setup-G5VYN6FV.js → setup-JINI7HBM.js} +3 -3
- package/dist/{upgrade-BXIHAENU.js → upgrade-EBD4LX5W.js} +2 -2
- package/dist/{version-MC2KSPJB.js → version-6Z354HHH.js} +1 -1
- package/dist/worker-entry.js +2 -2
- package/dist/{workflow-4OFPSVZ3.js → workflow-BOZ25AJ2.js} +5 -5
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ whether `WORKFLOW.md`, `.gh-symphony/context.yaml`,
|
|
|
88
88
|
`.gh-symphony/reference-workflow.md`, and runtime skill files would be created,
|
|
89
89
|
updated, or left unchanged, and then exits without modifying the repository.
|
|
90
90
|
|
|
91
|
-
The same detected environment data is applied to the generated artifacts, so `WORKFLOW.md`, `.gh-symphony/reference-workflow.md`, and the runtime skill templates already include repository-aware validation guidance for the detected package manager, monorepo layout, and explicit validation commands when they exist.
|
|
91
|
+
The same detected environment data is applied to the generated artifacts, so `WORKFLOW.md`, `.gh-symphony/reference-workflow.md`, and the runtime skill templates already include repository-aware validation guidance for the detected package manager, monorepo layout, and explicit validation commands when they exist. The `/gh-symphony` skill also ships a `references/` directory with workflow schema details and composable prompt-body postures for implementation, review, and maintenance workflows.
|
|
92
92
|
|
|
93
93
|
The detector is language-agnostic by default:
|
|
94
94
|
|
|
@@ -102,7 +102,7 @@ Examples of generated validation guidance include `make test`, `just build`, `uv
|
|
|
102
102
|
|
|
103
103
|
### Customizing Agent Behavior
|
|
104
104
|
|
|
105
|
-
`gh-symphony workflow init` generates skill files under `.codex/skills/` (or `.claude/skills/` for Claude Code). These skills define how the AI agent handles commits, pushes, pulls, and project status transitions.
|
|
105
|
+
`gh-symphony workflow init` generates skill files under `.codex/skills/` (or `.claude/skills/` for Claude Code). These skills define how the AI agent handles commits, pushes, pulls, and project status transitions. The generated `/gh-symphony` skill includes `references/` files that can be customized or extended without adding CLI flags.
|
|
106
106
|
|
|
107
107
|
You can further customize the agent's behavior by editing `WORKFLOW.md` — this is the policy layer that controls what the agent does at each workflow phase.
|
|
108
108
|
|
|
@@ -889,7 +889,8 @@ var SESSION_EXIT_CLASSIFICATIONS = [
|
|
|
889
889
|
"max-turns-reached",
|
|
890
890
|
"user-input-required",
|
|
891
891
|
"timeout",
|
|
892
|
-
"error"
|
|
892
|
+
"error",
|
|
893
|
+
"incomplete-turn-dirty-workspace"
|
|
893
894
|
];
|
|
894
895
|
function isSessionExitClassification(value) {
|
|
895
896
|
return typeof value === "string" && SESSION_EXIT_CLASSIFICATIONS.includes(value);
|
|
@@ -1471,11 +1472,30 @@ function buildProjectSnapshot(input) {
|
|
|
1471
1472
|
retryKind: run.retryKind ?? "failure",
|
|
1472
1473
|
nextRetryAt: run.nextRetryAt
|
|
1473
1474
|
})),
|
|
1475
|
+
recovery: findLatestRecovery([...allRuns ?? [], ...activeRuns]),
|
|
1474
1476
|
lastError,
|
|
1475
1477
|
codexTotals: aggregateTokenUsage(allRuns ?? activeRuns, lastTickAt),
|
|
1476
1478
|
rateLimits: rateLimits ?? null
|
|
1477
1479
|
};
|
|
1478
1480
|
}
|
|
1481
|
+
function findLatestRecovery(runs) {
|
|
1482
|
+
return [...runs].filter((run) => isUnresolvedRecoveryRun(run, runs)).sort((left, right) => {
|
|
1483
|
+
const leftTime = new Date(left.updatedAt).getTime();
|
|
1484
|
+
const rightTime = new Date(right.updatedAt).getTime();
|
|
1485
|
+
return rightTime - leftTime;
|
|
1486
|
+
}).find((run) => run.recovery)?.recovery ?? null;
|
|
1487
|
+
}
|
|
1488
|
+
function isUnresolvedRecoveryRun(run, runs) {
|
|
1489
|
+
if (!run.recovery) {
|
|
1490
|
+
return false;
|
|
1491
|
+
}
|
|
1492
|
+
if (run.status === "suppressed" && runs.some(
|
|
1493
|
+
(candidate) => candidate.runId !== run.runId && candidate.retryKind === "recovery" && candidate.recovery?.runId === run.recovery?.runId && new Date(candidate.updatedAt).getTime() > new Date(run.updatedAt).getTime() && candidate.status !== "running" && candidate.status !== "retrying"
|
|
1494
|
+
)) {
|
|
1495
|
+
return false;
|
|
1496
|
+
}
|
|
1497
|
+
return run.status === "suppressed" || run.retryKind === "recovery" && (run.status === "running" || run.status === "retrying");
|
|
1498
|
+
}
|
|
1479
1499
|
function aggregateTokenUsageByIssue(runs) {
|
|
1480
1500
|
const totals = /* @__PURE__ */ new Map();
|
|
1481
1501
|
for (const run of runs) {
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
resolveWorkflowRuntimeTimeouts,
|
|
31
31
|
safeReadDir,
|
|
32
32
|
scheduleRetryAt
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-6OPRRC2J.js";
|
|
34
34
|
import {
|
|
35
35
|
loadGlobalConfig,
|
|
36
36
|
loadProjectConfig
|
|
@@ -2313,14 +2313,21 @@ async function syncRepositoryForRun(input) {
|
|
|
2313
2313
|
});
|
|
2314
2314
|
}
|
|
2315
2315
|
async function ensureIssueWorkspaceRepository(input) {
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2316
|
+
let dirtyExistingWorkspaceAllowed = false;
|
|
2317
|
+
const repositoryDirectory = input.existingWorkspace ? await syncExistingIssueWorkspaceRepository(
|
|
2318
|
+
{
|
|
2319
|
+
...input,
|
|
2320
|
+
skipPull: Boolean(input.pullRequestBranch),
|
|
2321
|
+
allowDirty: input.allowDirtyExistingWorkspace
|
|
2322
|
+
},
|
|
2323
|
+
(dirtyAllowed) => {
|
|
2324
|
+
dirtyExistingWorkspaceAllowed = dirtyAllowed;
|
|
2325
|
+
}
|
|
2326
|
+
) : await cloneRepositoryForRun({
|
|
2320
2327
|
repository: input.repository,
|
|
2321
2328
|
targetDirectory: input.issueWorkspacePath
|
|
2322
2329
|
});
|
|
2323
|
-
if (input.pullRequestBranch) {
|
|
2330
|
+
if (input.pullRequestBranch && !dirtyExistingWorkspaceAllowed) {
|
|
2324
2331
|
await checkoutPullRequestBranch(
|
|
2325
2332
|
repositoryDirectory,
|
|
2326
2333
|
input.pullRequestBranch
|
|
@@ -2328,6 +2335,20 @@ async function ensureIssueWorkspaceRepository(input) {
|
|
|
2328
2335
|
}
|
|
2329
2336
|
return repositoryDirectory;
|
|
2330
2337
|
}
|
|
2338
|
+
async function inspectIssueWorkspaceDirtyStatus(input) {
|
|
2339
|
+
const repositoryDirectory = join(input.issueWorkspacePath, "repository");
|
|
2340
|
+
const hasGit = await pathExists(join(repositoryDirectory, ".git"));
|
|
2341
|
+
if (!hasGit) {
|
|
2342
|
+
return null;
|
|
2343
|
+
}
|
|
2344
|
+
const status = await readGitStatusPorcelain(repositoryDirectory);
|
|
2345
|
+
return {
|
|
2346
|
+
repositoryDirectory,
|
|
2347
|
+
dirty: status.trim().length > 0,
|
|
2348
|
+
dirtyFiles: parseGitStatusFiles(status),
|
|
2349
|
+
summary: status.trim() ? summarizeGitStatus(status) : null
|
|
2350
|
+
};
|
|
2351
|
+
}
|
|
2331
2352
|
async function loadRepositoryWorkflow(repositoryDirectory, _repository) {
|
|
2332
2353
|
const workflowPath = join(repositoryDirectory, "WORKFLOW.md");
|
|
2333
2354
|
try {
|
|
@@ -2377,7 +2398,7 @@ async function readGitHead(repositoryDirectory) {
|
|
|
2377
2398
|
return null;
|
|
2378
2399
|
}
|
|
2379
2400
|
}
|
|
2380
|
-
async function syncExistingIssueWorkspaceRepository(input) {
|
|
2401
|
+
async function syncExistingIssueWorkspaceRepository(input, onDirtyAllowed) {
|
|
2381
2402
|
await mkdir(input.issueWorkspacePath, { recursive: true });
|
|
2382
2403
|
const repositoryDirectory = join(input.issueWorkspacePath, "repository");
|
|
2383
2404
|
const lockDirectory = join(input.issueWorkspacePath, "repository.lock");
|
|
@@ -2394,6 +2415,10 @@ async function syncExistingIssueWorkspaceRepository(input) {
|
|
|
2394
2415
|
`could not be inspected: ${formatCommandError(error, "git status --porcelain failed")}`
|
|
2395
2416
|
);
|
|
2396
2417
|
}
|
|
2418
|
+
if (dirtyStatus.trim() && input.allowDirty) {
|
|
2419
|
+
onDirtyAllowed?.(true);
|
|
2420
|
+
return repositoryDirectory;
|
|
2421
|
+
}
|
|
2397
2422
|
if (dirtyStatus.trim()) {
|
|
2398
2423
|
throw createIssueWorkspacePreservedError(
|
|
2399
2424
|
repositoryDirectory,
|
|
@@ -2537,6 +2562,9 @@ function summarizeGitStatus(status) {
|
|
|
2537
2562
|
const summary = lines.slice(0, 5).join("; ");
|
|
2538
2563
|
return lines.length > 5 ? `${summary}; ...` : summary;
|
|
2539
2564
|
}
|
|
2565
|
+
function parseGitStatusFiles(status) {
|
|
2566
|
+
return status.trim().split(/\r?\n/).map((line) => line.slice(3).trim()).filter(Boolean);
|
|
2567
|
+
}
|
|
2540
2568
|
function normalizeWhitespace(value) {
|
|
2541
2569
|
return value.replace(/\s+/g, " ").trim();
|
|
2542
2570
|
}
|
|
@@ -3207,6 +3235,25 @@ function explainRuntimeOwnership(issue, issueRecords, runs) {
|
|
|
3207
3235
|
};
|
|
3208
3236
|
}
|
|
3209
3237
|
}
|
|
3238
|
+
if (latestRun?.status === "suppressed" && latestRun.recovery?.kind === "incomplete-turn-dirty-workspace") {
|
|
3239
|
+
return {
|
|
3240
|
+
id: "runtime_ownership",
|
|
3241
|
+
status: "warn",
|
|
3242
|
+
message: "Latest run has a recoverable incomplete-turn dirty workspace; dispatch will start a recovery turn.",
|
|
3243
|
+
details: {
|
|
3244
|
+
runId: latestRun.recovery.runId,
|
|
3245
|
+
issueId: latestRun.recovery.issueId,
|
|
3246
|
+
workspacePath: latestRun.recovery.workspacePath,
|
|
3247
|
+
dirtyFiles: latestRun.recovery.dirtyFiles,
|
|
3248
|
+
lastEvent: latestRun.recovery.lastEvent,
|
|
3249
|
+
lastEventAt: latestRun.recovery.lastEventAt,
|
|
3250
|
+
sessionId: latestRun.recovery.sessionId,
|
|
3251
|
+
threadId: latestRun.recovery.threadId,
|
|
3252
|
+
suggestedCommand: latestRun.recovery.suggestedCommand
|
|
3253
|
+
},
|
|
3254
|
+
hint: latestRun.recovery.suggestedCommand
|
|
3255
|
+
};
|
|
3256
|
+
}
|
|
3210
3257
|
return {
|
|
3211
3258
|
id: "runtime_ownership",
|
|
3212
3259
|
status: "pass",
|
|
@@ -3311,6 +3358,7 @@ var CONTINUATION_RETRY_DELAY_MS = 1e3;
|
|
|
3311
3358
|
var DEFAULT_WORKER_COMMAND = "node packages/worker/dist/index.js";
|
|
3312
3359
|
var DEFAULT_MAX_NONPRODUCTIVE_TURNS = 3;
|
|
3313
3360
|
var LOW_RATE_LIMIT_WARNING_THRESHOLD = 0.05;
|
|
3361
|
+
var MAX_RECOVERY_DIRTY_FILES_IN_CONTEXT = 50;
|
|
3314
3362
|
var MAX_FAILURE_RETRIES_EXCEEDED_REASON2 = "max_failure_retries_exceeded";
|
|
3315
3363
|
var LINKED_PR_ACTIVE_ISSUE_INACTIVE_MARKER_PREFIX = "gh-symphony:linked-pr-active-while-issue-inactive";
|
|
3316
3364
|
var STUCK_WORKER_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
@@ -3556,6 +3604,7 @@ var OrchestratorService = class {
|
|
|
3556
3604
|
kind: currentRun?.retryKind ?? null,
|
|
3557
3605
|
error: currentRun?.lastError ?? issueRecord.retryEntry?.error ?? null
|
|
3558
3606
|
} : null,
|
|
3607
|
+
recovery: currentRun?.recovery ?? null,
|
|
3559
3608
|
logs: {
|
|
3560
3609
|
codex_session_logs: currentRun === null ? [] : [
|
|
3561
3610
|
{
|
|
@@ -3786,6 +3835,12 @@ var OrchestratorService = class {
|
|
|
3786
3835
|
},
|
|
3787
3836
|
issue.identifier
|
|
3788
3837
|
);
|
|
3838
|
+
const recoveryContext = await this.resolveIncompleteTurnRecoveryContext(
|
|
3839
|
+
tenant,
|
|
3840
|
+
issue,
|
|
3841
|
+
latestRunsByIssueId.get(issue.id) ?? null,
|
|
3842
|
+
preferredWorkspaceKey
|
|
3843
|
+
);
|
|
3789
3844
|
issueRecords = upsertIssueOrchestration(issueRecords, {
|
|
3790
3845
|
issueId: issue.id,
|
|
3791
3846
|
identifier: issue.identifier,
|
|
@@ -3798,7 +3853,9 @@ var OrchestratorService = class {
|
|
|
3798
3853
|
});
|
|
3799
3854
|
let run;
|
|
3800
3855
|
try {
|
|
3801
|
-
run = await this.startRun(tenant, issue
|
|
3856
|
+
run = await this.startRun(tenant, issue, {
|
|
3857
|
+
recovery: recoveryContext
|
|
3858
|
+
});
|
|
3802
3859
|
} catch (error) {
|
|
3803
3860
|
issueRecords = releaseIssueOrchestration(issueRecords, issue.id, now);
|
|
3804
3861
|
throw error;
|
|
@@ -3855,6 +3912,11 @@ var OrchestratorService = class {
|
|
|
3855
3912
|
const activeWorkerPid = activeRun.processId;
|
|
3856
3913
|
this.sendSignal(activeWorkerPid, "SIGTERM");
|
|
3857
3914
|
this.retireWorkerPid(activeWorkerPid);
|
|
3915
|
+
const recovery = await this.classifyIncompleteTurnDirtyWorkspace(
|
|
3916
|
+
tenant,
|
|
3917
|
+
activeRun,
|
|
3918
|
+
now
|
|
3919
|
+
);
|
|
3858
3920
|
const suppressedRun = {
|
|
3859
3921
|
...activeRun,
|
|
3860
3922
|
status: "suppressed",
|
|
@@ -3862,7 +3924,17 @@ var OrchestratorService = class {
|
|
|
3862
3924
|
completedAt: now.toISOString(),
|
|
3863
3925
|
updatedAt: now.toISOString(),
|
|
3864
3926
|
runPhase: "canceled_by_reconciliation",
|
|
3865
|
-
|
|
3927
|
+
runtimeSession: recovery ? buildRuntimeSession(
|
|
3928
|
+
activeRun.runtimeSession,
|
|
3929
|
+
recovery.sessionId,
|
|
3930
|
+
recovery.threadId,
|
|
3931
|
+
"completed",
|
|
3932
|
+
activeRun.runtimeSession?.startedAt ?? activeRun.startedAt ?? now.toISOString(),
|
|
3933
|
+
now.toISOString(),
|
|
3934
|
+
"incomplete-turn-dirty-workspace"
|
|
3935
|
+
) : activeRun.runtimeSession,
|
|
3936
|
+
recovery,
|
|
3937
|
+
lastError: recovery ? "Run suppressed with recoverable incomplete-turn dirty workspace." : "Run suppressed because the tracker issue is no longer tracked."
|
|
3866
3938
|
};
|
|
3867
3939
|
await this.store.saveRun(suppressedRun);
|
|
3868
3940
|
this.logVerbose(
|
|
@@ -3888,6 +3960,11 @@ var OrchestratorService = class {
|
|
|
3888
3960
|
}
|
|
3889
3961
|
if (activeRun) {
|
|
3890
3962
|
const terminalState = isStateTerminal(issue.state, lifecycle);
|
|
3963
|
+
const recovery = terminalState ? null : await this.classifyIncompleteTurnDirtyWorkspace(
|
|
3964
|
+
tenant,
|
|
3965
|
+
activeRun,
|
|
3966
|
+
now
|
|
3967
|
+
);
|
|
3891
3968
|
const suppressedRun = {
|
|
3892
3969
|
...activeRun,
|
|
3893
3970
|
status: "suppressed",
|
|
@@ -3895,7 +3972,17 @@ var OrchestratorService = class {
|
|
|
3895
3972
|
completedAt: now.toISOString(),
|
|
3896
3973
|
updatedAt: now.toISOString(),
|
|
3897
3974
|
runPhase: "canceled_by_reconciliation",
|
|
3898
|
-
|
|
3975
|
+
runtimeSession: recovery ? buildRuntimeSession(
|
|
3976
|
+
activeRun.runtimeSession,
|
|
3977
|
+
recovery.sessionId,
|
|
3978
|
+
recovery.threadId,
|
|
3979
|
+
"completed",
|
|
3980
|
+
activeRun.runtimeSession?.startedAt ?? activeRun.startedAt ?? now.toISOString(),
|
|
3981
|
+
now.toISOString(),
|
|
3982
|
+
"incomplete-turn-dirty-workspace"
|
|
3983
|
+
) : activeRun.runtimeSession,
|
|
3984
|
+
recovery,
|
|
3985
|
+
lastError: recovery ? "Run suppressed with recoverable incomplete-turn dirty workspace." : terminalState ? "Run suppressed because the tracker issue moved to a terminal state." : "Run suppressed because the tracker state is no longer actionable."
|
|
3899
3986
|
};
|
|
3900
3987
|
await this.store.saveRun(suppressedRun);
|
|
3901
3988
|
this.logVerbose(
|
|
@@ -4247,7 +4334,7 @@ var OrchestratorService = class {
|
|
|
4247
4334
|
true
|
|
4248
4335
|
);
|
|
4249
4336
|
}
|
|
4250
|
-
async startRun(tenant, issue) {
|
|
4337
|
+
async startRun(tenant, issue, options = {}) {
|
|
4251
4338
|
if (this.shuttingDown || !this.running) {
|
|
4252
4339
|
throw new Error(
|
|
4253
4340
|
"Orchestrator is shutting down and cannot start new runs."
|
|
@@ -4289,7 +4376,8 @@ var OrchestratorService = class {
|
|
|
4289
4376
|
repository: issue.repository,
|
|
4290
4377
|
issueWorkspacePath,
|
|
4291
4378
|
existingWorkspace: Boolean(existingWorkspaceRecord),
|
|
4292
|
-
pullRequestBranch
|
|
4379
|
+
pullRequestBranch,
|
|
4380
|
+
allowDirtyExistingWorkspace: options.recovery?.kind === "incomplete-turn-dirty-workspace"
|
|
4293
4381
|
});
|
|
4294
4382
|
if (!existingWorkspaceRecord) {
|
|
4295
4383
|
const workspaceRecord = {
|
|
@@ -4340,9 +4428,10 @@ var OrchestratorService = class {
|
|
|
4340
4428
|
attempt: null
|
|
4341
4429
|
// first execution
|
|
4342
4430
|
});
|
|
4343
|
-
const renderedPrompt =
|
|
4431
|
+
const renderedPrompt = appendIncompleteTurnRecoveryPrompt(
|
|
4344
4432
|
workflow.promptTemplate,
|
|
4345
|
-
promptVariables
|
|
4433
|
+
promptVariables,
|
|
4434
|
+
options.recovery ?? null
|
|
4346
4435
|
);
|
|
4347
4436
|
await this.runHook(
|
|
4348
4437
|
"before_run",
|
|
@@ -4434,6 +4523,9 @@ var OrchestratorService = class {
|
|
|
4434
4523
|
SYMPHONY_CUMULATIVE_OUTPUT_TOKENS: "0",
|
|
4435
4524
|
SYMPHONY_CUMULATIVE_TOTAL_TOKENS: "0",
|
|
4436
4525
|
SYMPHONY_LAST_TURN_SUMMARY: "",
|
|
4526
|
+
SYMPHONY_RECOVERY_KIND: options.recovery?.kind ?? "",
|
|
4527
|
+
SYMPHONY_RECOVERY_DIRTY_FILES: options.recovery ? formatRecoveryDirtyFilesForContext(options.recovery.dirtyFiles) : "",
|
|
4528
|
+
SYMPHONY_RECOVERY_SUGGESTED_COMMAND: options.recovery?.suggestedCommand ?? "",
|
|
4437
4529
|
SYMPHONY_SESSION_STARTED_AT: "",
|
|
4438
4530
|
SYMPHONY_READ_TIMEOUT_MS: String(runtimeTimeouts.readTimeoutMs),
|
|
4439
4531
|
SYMPHONY_TURN_TIMEOUT_MS: String(runtimeTimeouts.turnTimeoutMs)
|
|
@@ -4547,7 +4639,7 @@ var OrchestratorService = class {
|
|
|
4547
4639
|
issueWorkspaceKey: workspaceKey,
|
|
4548
4640
|
workspaceRuntimeDir,
|
|
4549
4641
|
workflowPath: workflow.workflowPath,
|
|
4550
|
-
retryKind: null,
|
|
4642
|
+
retryKind: options.recovery ? "recovery" : null,
|
|
4551
4643
|
threadId: null,
|
|
4552
4644
|
cumulativeTurnCount: 0,
|
|
4553
4645
|
lastTurnSummary: null,
|
|
@@ -4558,7 +4650,8 @@ var OrchestratorService = class {
|
|
|
4558
4650
|
lastError: null,
|
|
4559
4651
|
nextRetryAt: null,
|
|
4560
4652
|
runPhase: "preparing_workspace",
|
|
4561
|
-
rateLimits: issue.rateLimits ?? null
|
|
4653
|
+
rateLimits: issue.rateLimits ?? null,
|
|
4654
|
+
recovery: options.recovery ?? null
|
|
4562
4655
|
};
|
|
4563
4656
|
}
|
|
4564
4657
|
async syncActiveRunIssueStates(tenant, trackerAdapter, activeRuns, now) {
|
|
@@ -5182,6 +5275,66 @@ var OrchestratorService = class {
|
|
|
5182
5275
|
);
|
|
5183
5276
|
return issue ? { issue, issues } : null;
|
|
5184
5277
|
}
|
|
5278
|
+
async classifyIncompleteTurnDirtyWorkspace(tenant, run, now) {
|
|
5279
|
+
if (run.runtimeSession?.status !== "active" || run.runtimeSession.exitClassification !== null || run.lastEvent === "turn_completed") {
|
|
5280
|
+
return null;
|
|
5281
|
+
}
|
|
5282
|
+
const workspaceKey = run.issueWorkspaceKey ?? deriveIssueWorkspaceKey(
|
|
5283
|
+
{
|
|
5284
|
+
adapter: tenant.tracker.adapter,
|
|
5285
|
+
issueSubjectId: run.issueSubjectId
|
|
5286
|
+
},
|
|
5287
|
+
run.issueIdentifier
|
|
5288
|
+
);
|
|
5289
|
+
const issueWorkspacePath = resolveIssueWorkspaceDirectory(
|
|
5290
|
+
this.store.projectDir(tenant.projectId),
|
|
5291
|
+
workspaceKey
|
|
5292
|
+
);
|
|
5293
|
+
const dirtyStatus = await inspectIssueWorkspaceDirtyStatus({
|
|
5294
|
+
issueWorkspacePath
|
|
5295
|
+
});
|
|
5296
|
+
if (!dirtyStatus?.dirty) {
|
|
5297
|
+
return null;
|
|
5298
|
+
}
|
|
5299
|
+
return {
|
|
5300
|
+
kind: "incomplete-turn-dirty-workspace",
|
|
5301
|
+
runId: run.runId,
|
|
5302
|
+
issueId: run.issueId,
|
|
5303
|
+
issueIdentifier: run.issueIdentifier,
|
|
5304
|
+
workspacePath: dirtyStatus.repositoryDirectory,
|
|
5305
|
+
dirtyFiles: dirtyStatus.dirtyFiles,
|
|
5306
|
+
lastEvent: run.lastEvent ?? null,
|
|
5307
|
+
lastEventAt: run.lastEventAt ?? null,
|
|
5308
|
+
sessionId: run.runtimeSession.sessionId ?? null,
|
|
5309
|
+
threadId: run.threadId ?? run.runtimeSession.threadId ?? null,
|
|
5310
|
+
suggestedCommand: `cd ${shellQuote(dirtyStatus.repositoryDirectory)} && git status --short && git diff`,
|
|
5311
|
+
detectedAt: now.toISOString()
|
|
5312
|
+
};
|
|
5313
|
+
}
|
|
5314
|
+
async resolveIncompleteTurnRecoveryContext(tenant, issue, latestRun, preferredWorkspaceKey) {
|
|
5315
|
+
const recovery = latestRun?.recovery;
|
|
5316
|
+
if (latestRun?.status !== "suppressed" || recovery?.kind !== "incomplete-turn-dirty-workspace" || latestRun.runtimeSession?.exitClassification !== "incomplete-turn-dirty-workspace") {
|
|
5317
|
+
return null;
|
|
5318
|
+
}
|
|
5319
|
+
const workspaceKey = latestRun.issueWorkspaceKey ?? preferredWorkspaceKey;
|
|
5320
|
+
const dirtyStatus = await inspectIssueWorkspaceDirtyStatus({
|
|
5321
|
+
issueWorkspacePath: resolveIssueWorkspaceDirectory(
|
|
5322
|
+
this.store.projectDir(tenant.projectId),
|
|
5323
|
+
workspaceKey
|
|
5324
|
+
)
|
|
5325
|
+
});
|
|
5326
|
+
if (!dirtyStatus?.dirty) {
|
|
5327
|
+
return null;
|
|
5328
|
+
}
|
|
5329
|
+
return {
|
|
5330
|
+
...recovery,
|
|
5331
|
+
issueId: issue.id,
|
|
5332
|
+
issueIdentifier: issue.identifier,
|
|
5333
|
+
workspacePath: dirtyStatus.repositoryDirectory,
|
|
5334
|
+
dirtyFiles: dirtyStatus.dirtyFiles,
|
|
5335
|
+
suggestedCommand: `cd ${shellQuote(dirtyStatus.repositoryDirectory)} && git status --short && git diff`
|
|
5336
|
+
};
|
|
5337
|
+
}
|
|
5185
5338
|
async fetchWorkerRunInfo(run) {
|
|
5186
5339
|
const latestRun = await this.store.loadRun(run.runId, run.projectId) ?? run;
|
|
5187
5340
|
const persistedTokenUsage = await this.readPersistedWorkerTokenUsage(latestRun);
|
|
@@ -5758,9 +5911,50 @@ function buildRuntimeSession(existing, sessionId, threadId, status, startedAt, u
|
|
|
5758
5911
|
exitClassification: exitClassification === void 0 ? existing?.exitClassification ?? null : exitClassification
|
|
5759
5912
|
};
|
|
5760
5913
|
}
|
|
5914
|
+
function appendIncompleteTurnRecoveryPrompt(promptTemplate, promptVariables, recovery) {
|
|
5915
|
+
const renderedPrompt = renderPrompt(promptTemplate, promptVariables);
|
|
5916
|
+
if (!recovery) {
|
|
5917
|
+
return renderedPrompt;
|
|
5918
|
+
}
|
|
5919
|
+
return [
|
|
5920
|
+
renderedPrompt,
|
|
5921
|
+
"",
|
|
5922
|
+
"## Recovery Context \u2014 Incomplete Turn Dirty Workspace",
|
|
5923
|
+
"",
|
|
5924
|
+
`Previous run: ${recovery.runId}`,
|
|
5925
|
+
`Workspace: ${recovery.workspacePath}`,
|
|
5926
|
+
`Last event: ${recovery.lastEvent ?? "unknown"}`,
|
|
5927
|
+
`Last event time: ${recovery.lastEventAt ?? "unknown"}`,
|
|
5928
|
+
`Session id: ${recovery.sessionId ?? "unknown"}`,
|
|
5929
|
+
`Thread id: ${recovery.threadId ?? "unknown"}`,
|
|
5930
|
+
"",
|
|
5931
|
+
"Dirty files:",
|
|
5932
|
+
...formatRecoveryDirtyFileLinesForPrompt(recovery.dirtyFiles),
|
|
5933
|
+
"",
|
|
5934
|
+
"Inspect the dirty diff before editing. If the partial work is correct, validate it, commit it, and push it. If it is invalid, revert it explicitly and record a blocker/comment with the reason. Do not discard uncommitted work without making an intentional recovery decision.",
|
|
5935
|
+
`Suggested operator command: ${recovery.suggestedCommand}`
|
|
5936
|
+
].join("\n");
|
|
5937
|
+
}
|
|
5938
|
+
function formatRecoveryDirtyFilesForContext(dirtyFiles) {
|
|
5939
|
+
return formatRecoveryDirtyFiles(dirtyFiles).join("\n");
|
|
5940
|
+
}
|
|
5941
|
+
function formatRecoveryDirtyFileLinesForPrompt(dirtyFiles) {
|
|
5942
|
+
return formatRecoveryDirtyFiles(dirtyFiles).map((file) => `- ${file}`);
|
|
5943
|
+
}
|
|
5944
|
+
function formatRecoveryDirtyFiles(dirtyFiles) {
|
|
5945
|
+
const visibleFiles = dirtyFiles.slice(0, MAX_RECOVERY_DIRTY_FILES_IN_CONTEXT);
|
|
5946
|
+
const remaining = dirtyFiles.length - visibleFiles.length;
|
|
5947
|
+
if (remaining <= 0) {
|
|
5948
|
+
return visibleFiles;
|
|
5949
|
+
}
|
|
5950
|
+
return [...visibleFiles, `... and ${remaining} more`];
|
|
5951
|
+
}
|
|
5761
5952
|
function resolvePersistedCumulativeTurnCount(run) {
|
|
5762
5953
|
return run.cumulativeTurnCount ?? run.turnCount ?? 0;
|
|
5763
5954
|
}
|
|
5955
|
+
function shellQuote(value) {
|
|
5956
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
5957
|
+
}
|
|
5764
5958
|
function resolveCumulativeTurnCount(run, turnCount) {
|
|
5765
5959
|
const carriedTotal = resolvePersistedCumulativeTurnCount(run);
|
|
5766
5960
|
if (turnCount === null) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
workflow_init_default
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZPS4CQZJ.js";
|
|
5
5
|
import {
|
|
6
6
|
fetchGithubProjectIssueByRepositoryAndNumber,
|
|
7
7
|
inspectManagedProjectSelection,
|
|
8
8
|
resolveTrackerAdapter
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-B6G3KGBB.js";
|
|
10
10
|
import {
|
|
11
11
|
GitHubApiError,
|
|
12
12
|
createClient,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
buildPromptVariables,
|
|
20
20
|
parseWorkflowMarkdown,
|
|
21
21
|
renderPrompt
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-6OPRRC2J.js";
|
|
23
23
|
import {
|
|
24
24
|
loadActiveProjectConfig
|
|
25
25
|
} from "./chunk-4ICDSQCJ.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
formatClaudePreflightText,
|
|
17
17
|
resolveClaudeCommandBinary,
|
|
18
18
|
runClaudePreflight
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-6OPRRC2J.js";
|
|
20
20
|
|
|
21
21
|
// src/mapping/smart-defaults.ts
|
|
22
22
|
var ROLE_PATTERNS = [
|
|
@@ -98,7 +98,7 @@ import * as p from "@clack/prompts";
|
|
|
98
98
|
import { spawnSync } from "child_process";
|
|
99
99
|
import { createHash } from "crypto";
|
|
100
100
|
import { chmod, mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
|
|
101
|
-
import {
|
|
101
|
+
import { dirname as dirname3, join as join3, relative, resolve } from "path";
|
|
102
102
|
|
|
103
103
|
// src/prompts/runtime-claude-constraints.ts
|
|
104
104
|
var CLAUDE_RUNTIME_CONSTRAINTS_SECTION = `## Runtime Constraints
|
|
@@ -1366,7 +1366,7 @@ function resolveRoleAction(role) {
|
|
|
1366
1366
|
|
|
1367
1367
|
// src/skills/skill-writer.ts
|
|
1368
1368
|
import { mkdir as mkdir2, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
|
|
1369
|
-
import { join as join2 } from "path";
|
|
1369
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
1370
1370
|
function normalizeRuntimeForSkills(runtime) {
|
|
1371
1371
|
if (isClaudeRuntime(runtime)) {
|
|
1372
1372
|
return "claude-code";
|
|
@@ -1393,10 +1393,12 @@ function buildSkillFilePlans(repoRoot, runtime, templates, context) {
|
|
|
1393
1393
|
}
|
|
1394
1394
|
return {
|
|
1395
1395
|
skillsDir,
|
|
1396
|
-
files: templates.
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1396
|
+
files: templates.flatMap(
|
|
1397
|
+
(template) => template.files.map((file) => ({
|
|
1398
|
+
path: join2(skillsDir, template.name, file.relativePath),
|
|
1399
|
+
content: file.generate(context)
|
|
1400
|
+
}))
|
|
1401
|
+
)
|
|
1400
1402
|
};
|
|
1401
1403
|
}
|
|
1402
1404
|
|
|
@@ -1436,8 +1438,9 @@ function generateGhSymphonySkill(ctx) {
|
|
|
1436
1438
|
`- \`${ctx.contextYamlPath}\` must exist (contains GitHub Project metadata)`
|
|
1437
1439
|
);
|
|
1438
1440
|
lines.push(
|
|
1439
|
-
`- \`${ctx.referenceWorkflowPath}\`
|
|
1441
|
+
`- \`${ctx.referenceWorkflowPath}\` may exist for compatibility with older generated ecosystems`
|
|
1440
1442
|
);
|
|
1443
|
+
lines.push("- `references/README.md` must exist beside this skill");
|
|
1441
1444
|
lines.push("- `gh` CLI must be authenticated");
|
|
1442
1445
|
lines.push("");
|
|
1443
1446
|
lines.push("## Repository Validation Guidance");
|
|
@@ -1462,49 +1465,70 @@ function generateGhSymphonySkill(ctx) {
|
|
|
1462
1465
|
lines.push("## Design Mode");
|
|
1463
1466
|
lines.push("");
|
|
1464
1467
|
lines.push(
|
|
1465
|
-
|
|
1468
|
+
"1. Read `WORKFLOW.md` if it exists and extract repository conventions:"
|
|
1469
|
+
);
|
|
1470
|
+
lines.push(" - test / lint / build commands from the prompt body");
|
|
1471
|
+
lines.push(" - lifecycle states from front matter");
|
|
1472
|
+
lines.push(
|
|
1473
|
+
"2. Read `references/README.md` for the available reference files."
|
|
1466
1474
|
);
|
|
1475
|
+
lines.push('3. Ask the user: "What should this orchestration accomplish?"');
|
|
1476
|
+
lines.push(" - implement (default) \u2014 write features / fix bugs");
|
|
1477
|
+
lines.push(" - review \u2014 review PRs and leave comments");
|
|
1478
|
+
lines.push(" - maintain \u2014 dependency bumps, chores, hygiene");
|
|
1479
|
+
lines.push(" - custom \u2014 describe in their own words");
|
|
1467
1480
|
lines.push(
|
|
1468
|
-
|
|
1481
|
+
"4. Pick the matching `references/workflow-posture-*.md` file(s); compose multiple files when the intent spans categories."
|
|
1469
1482
|
);
|
|
1470
|
-
lines.push("
|
|
1483
|
+
lines.push("5. Ask these setup questions:");
|
|
1471
1484
|
lines.push(" - Which status columns should be **active** (agent works)?");
|
|
1472
1485
|
lines.push(" - Which should be **wait** (agent pauses for human)?");
|
|
1473
1486
|
lines.push(" - Which should be **terminal** (agent stops)?");
|
|
1474
1487
|
lines.push(" - What runtime is being used? (codex / claude-code / custom)");
|
|
1475
1488
|
lines.push(" - Any custom hooks needed? (after_create, before_run, etc.)");
|
|
1489
|
+
lines.push("6. Generate WORKFLOW.md:");
|
|
1490
|
+
lines.push(" - front matter from `references/workflow-schema.md`");
|
|
1476
1491
|
lines.push(
|
|
1477
|
-
"
|
|
1492
|
+
" - prompt body from the selected posture file(s), adapted to actual repository commands"
|
|
1478
1493
|
);
|
|
1479
|
-
lines.push("
|
|
1494
|
+
lines.push("7. Show a diff or preview and confirm with the user.");
|
|
1495
|
+
lines.push("8. Validate via `gh-symphony workflow validate`.");
|
|
1480
1496
|
lines.push("");
|
|
1481
1497
|
lines.push("## Refine Mode");
|
|
1482
1498
|
lines.push("");
|
|
1483
1499
|
lines.push("1. Read the current `WORKFLOW.md`");
|
|
1484
|
-
lines.push(
|
|
1485
|
-
|
|
1500
|
+
lines.push(
|
|
1501
|
+
"2. Read `references/README.md` and select the relevant posture file(s)"
|
|
1502
|
+
);
|
|
1503
|
+
lines.push(
|
|
1504
|
+
"3. Compare the current prompt body against the selected posture references"
|
|
1505
|
+
);
|
|
1506
|
+
lines.push("4. Identify missing or incomplete sections:");
|
|
1486
1507
|
lines.push(" - Status Map with role annotations");
|
|
1487
1508
|
lines.push(" - Default Posture / Agent Instructions");
|
|
1488
1509
|
lines.push(" - Guardrails section");
|
|
1489
1510
|
lines.push(" - Workpad Template");
|
|
1490
1511
|
lines.push(" - Step 0 routing logic");
|
|
1491
|
-
lines.push("
|
|
1492
|
-
lines.push("
|
|
1512
|
+
lines.push("5. Propose improvements and apply with user confirmation");
|
|
1513
|
+
lines.push("6. Validate the refined file");
|
|
1493
1514
|
lines.push("");
|
|
1494
1515
|
lines.push("## Validate Mode");
|
|
1495
1516
|
lines.push("");
|
|
1496
1517
|
lines.push("Check the WORKFLOW.md for:");
|
|
1497
1518
|
lines.push("- Front matter is valid YAML");
|
|
1498
1519
|
lines.push(
|
|
1499
|
-
"- Required fields are present (see
|
|
1520
|
+
"- Required fields are present (see `references/workflow-schema.md`)"
|
|
1500
1521
|
);
|
|
1501
1522
|
lines.push(
|
|
1502
|
-
"- Template variables use only supported names (see
|
|
1523
|
+
"- Template variables use only supported names (see `references/workflow-schema.md`)"
|
|
1503
1524
|
);
|
|
1504
1525
|
lines.push("- Status Map matches the lifecycle configuration");
|
|
1505
1526
|
lines.push(
|
|
1506
1527
|
"- No unsupported double-brace variable patterns (only the 8 listed below are valid)"
|
|
1507
1528
|
);
|
|
1529
|
+
lines.push(
|
|
1530
|
+
"- Prompt body posture is consistent with the selected `references/workflow-posture-*.md` file(s)"
|
|
1531
|
+
);
|
|
1508
1532
|
lines.push("");
|
|
1509
1533
|
lines.push("## Supported Front Matter Fields");
|
|
1510
1534
|
lines.push("");
|
|
@@ -1901,22 +1925,319 @@ function generateLandSkill(_ctx) {
|
|
|
1901
1925
|
});
|
|
1902
1926
|
}
|
|
1903
1927
|
|
|
1928
|
+
// src/skills/templates/gh-symphony-references/readme.ts
|
|
1929
|
+
function generateGhSymphonyReferencesReadme(_ctx) {
|
|
1930
|
+
return [
|
|
1931
|
+
"# /gh-symphony references",
|
|
1932
|
+
"",
|
|
1933
|
+
"The /gh-symphony skill consults these files when designing or refining",
|
|
1934
|
+
"WORKFLOW.md.",
|
|
1935
|
+
"",
|
|
1936
|
+
"## Schema",
|
|
1937
|
+
"",
|
|
1938
|
+
"| File | What it is |",
|
|
1939
|
+
"| ---- | ---------- |",
|
|
1940
|
+
"| `workflow-schema.md` | All supported front matter fields and their types. |",
|
|
1941
|
+
"",
|
|
1942
|
+
"## Workflow prompt body postures",
|
|
1943
|
+
"",
|
|
1944
|
+
"When the user describes what the orchestration should do, pick the matching",
|
|
1945
|
+
"posture file(s) and use its prompt-body sections as the seed. Postures can be",
|
|
1946
|
+
"combined when the user's intent spans multiple categories.",
|
|
1947
|
+
"",
|
|
1948
|
+
"| File | Use when the user wants... |",
|
|
1949
|
+
"| ---- | -------------------------- |",
|
|
1950
|
+
"| `workflow-posture-implement.md` | Coding agent writes features / bug fixes (default). |",
|
|
1951
|
+
"| `workflow-posture-review.md` | Agent reviews PRs and leaves comments. No code writes. |",
|
|
1952
|
+
"| `workflow-posture-maintain.md` | Minimal-change maintenance: deps, lint sweeps, hygiene. |",
|
|
1953
|
+
"",
|
|
1954
|
+
"## Adding your own reference",
|
|
1955
|
+
"",
|
|
1956
|
+
"Drop a markdown file here with a descriptive name. The skill discovers files",
|
|
1957
|
+
"on each invocation; no code changes needed."
|
|
1958
|
+
].join("\n");
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
// src/skills/templates/gh-symphony-references/workflow-schema.ts
|
|
1962
|
+
function generateWorkflowSchemaReference(ctx) {
|
|
1963
|
+
const reference = generateReferenceWorkflow({
|
|
1964
|
+
runtime: ctx.runtime,
|
|
1965
|
+
statusColumns: ctx.statusColumns.map((column) => ({
|
|
1966
|
+
name: column.name,
|
|
1967
|
+
role: column.role
|
|
1968
|
+
})),
|
|
1969
|
+
projectId: ctx.projectId,
|
|
1970
|
+
priority: null,
|
|
1971
|
+
detectedEnvironment: ctx.detectedEnvironment
|
|
1972
|
+
});
|
|
1973
|
+
return [
|
|
1974
|
+
reference,
|
|
1975
|
+
"",
|
|
1976
|
+
"## Supported Template Variables",
|
|
1977
|
+
"",
|
|
1978
|
+
"Use these in the WORKFLOW.md prompt body with double-brace syntax.",
|
|
1979
|
+
"",
|
|
1980
|
+
"| Variable | Description |",
|
|
1981
|
+
"| -------- | ----------- |",
|
|
1982
|
+
"| `issue.identifier` | Issue identifier, for example `acme/platform#42`. |",
|
|
1983
|
+
"| `issue.title` | Issue title. |",
|
|
1984
|
+
"| `issue.state` | Current tracker state. |",
|
|
1985
|
+
"| `issue.description` | Issue body. |",
|
|
1986
|
+
"| `issue.url` | Issue URL. |",
|
|
1987
|
+
"| `issue.repository` | Repository in `owner/name` form. |",
|
|
1988
|
+
"| `issue.number` | Issue number. |",
|
|
1989
|
+
"| `attempt` | Retry attempt number, or null on the first run. |",
|
|
1990
|
+
"",
|
|
1991
|
+
"Only these variables are supported by strict-mode prompt rendering."
|
|
1992
|
+
].join("\n");
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
// src/skills/templates/gh-symphony-references/workflow-posture-implement.ts
|
|
1996
|
+
function generateWorkflowPostureImplementReference(ctx) {
|
|
1997
|
+
const validationGuidance = buildRepositoryValidationGuidance(
|
|
1998
|
+
ctx.detectedEnvironment
|
|
1999
|
+
);
|
|
2000
|
+
return [
|
|
2001
|
+
"# Workflow posture: implement",
|
|
2002
|
+
"",
|
|
2003
|
+
"Use this prompt-body posture when the agent should write features or fix bugs.",
|
|
2004
|
+
"This is the default posture and preserves the current generated WORKFLOW.md",
|
|
2005
|
+
"prompt-body behavior.",
|
|
2006
|
+
"",
|
|
2007
|
+
"## Agent Instructions",
|
|
2008
|
+
"",
|
|
2009
|
+
'You are an AI coding agent working on issue `{issue.identifier}`: "`{issue.title}`".',
|
|
2010
|
+
"",
|
|
2011
|
+
"**Repository:** `{issue.repository}`",
|
|
2012
|
+
"**Current state:** `{issue.state}`",
|
|
2013
|
+
"",
|
|
2014
|
+
"### Task",
|
|
2015
|
+
"",
|
|
2016
|
+
"`{issue.description}`",
|
|
2017
|
+
"",
|
|
2018
|
+
"### Default Posture",
|
|
2019
|
+
"",
|
|
2020
|
+
"1. This is an unattended orchestration session. Do not ask humans for follow-up actions.",
|
|
2021
|
+
"2. Only abort early if there is a genuine blocker (missing required credentials or secrets).",
|
|
2022
|
+
'3. In your final message, report only what was completed and any blockers. Do not include "next steps".',
|
|
2023
|
+
"",
|
|
2024
|
+
"### Repository Validation Guidance",
|
|
2025
|
+
"",
|
|
2026
|
+
...validationGuidance.map((line, index) => `${index + 1}. ${line}`),
|
|
2027
|
+
"",
|
|
2028
|
+
"### Workflow",
|
|
2029
|
+
"",
|
|
2030
|
+
"1. Read the issue description and understand the requirements.",
|
|
2031
|
+
"2. Explore the codebase to understand the relevant code structure.",
|
|
2032
|
+
"3. Implement the changes following the project's coding conventions.",
|
|
2033
|
+
"4. Write or update tests to cover the changes.",
|
|
2034
|
+
"5. Verify that all existing tests pass.",
|
|
2035
|
+
"6. Create a PR with a clear description of the changes.",
|
|
2036
|
+
"",
|
|
2037
|
+
"### Guardrails",
|
|
2038
|
+
"",
|
|
2039
|
+
"- Do not edit the issue body for planning or progress tracking.",
|
|
2040
|
+
"- If the issue is in a terminal state, do nothing and exit.",
|
|
2041
|
+
"- If you find out-of-scope improvements, open a separate issue rather than expanding the current scope.",
|
|
2042
|
+
"",
|
|
2043
|
+
"### Workpad Template",
|
|
2044
|
+
"",
|
|
2045
|
+
"Create a workpad comment on the issue with the following structure to track progress:",
|
|
2046
|
+
"",
|
|
2047
|
+
"```md",
|
|
2048
|
+
"## Workpad",
|
|
2049
|
+
"",
|
|
2050
|
+
"### Plan",
|
|
2051
|
+
"",
|
|
2052
|
+
"- [ ] 1. Task item",
|
|
2053
|
+
"",
|
|
2054
|
+
"### Acceptance Criteria",
|
|
2055
|
+
"",
|
|
2056
|
+
"- [ ] Criterion 1",
|
|
2057
|
+
"",
|
|
2058
|
+
"### Validation",
|
|
2059
|
+
"",
|
|
2060
|
+
"- [ ] Test: `command`",
|
|
2061
|
+
"",
|
|
2062
|
+
"### Notes",
|
|
2063
|
+
"",
|
|
2064
|
+
"- Progress notes",
|
|
2065
|
+
"```"
|
|
2066
|
+
].join("\n");
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
// src/skills/templates/gh-symphony-references/workflow-posture-review.ts
|
|
2070
|
+
function generateWorkflowPostureReviewReference(ctx) {
|
|
2071
|
+
const validationGuidance = buildRepositoryValidationGuidance(
|
|
2072
|
+
ctx.detectedEnvironment
|
|
2073
|
+
);
|
|
2074
|
+
return [
|
|
2075
|
+
"# Workflow posture: review",
|
|
2076
|
+
"",
|
|
2077
|
+
"Use this prompt-body posture when the agent should review PRs and leave",
|
|
2078
|
+
"comments. This posture is read-only for repository code.",
|
|
2079
|
+
"",
|
|
2080
|
+
"## Agent Instructions",
|
|
2081
|
+
"",
|
|
2082
|
+
'You are an AI code-review agent working on issue `{issue.identifier}`: "`{issue.title}`".',
|
|
2083
|
+
"",
|
|
2084
|
+
"**Repository:** `{issue.repository}`",
|
|
2085
|
+
"**Current state:** `{issue.state}`",
|
|
2086
|
+
"",
|
|
2087
|
+
"### Task",
|
|
2088
|
+
"",
|
|
2089
|
+
"`{issue.description}`",
|
|
2090
|
+
"",
|
|
2091
|
+
"### Default Posture",
|
|
2092
|
+
"",
|
|
2093
|
+
"1. Review linked pull requests. Do NOT write code, push commits, or open new PRs.",
|
|
2094
|
+
"2. Treat failing required tests as grounds to request changes unless the failure is clearly unrelated and documented.",
|
|
2095
|
+
"3. In your final message, report only the review outcome and any blockers. Do not include follow-up work for the human unless it is required to unblock review.",
|
|
2096
|
+
"",
|
|
2097
|
+
"### Repository Validation Guidance",
|
|
2098
|
+
"",
|
|
2099
|
+
...validationGuidance.map((line, index) => `${index + 1}. ${line}`),
|
|
2100
|
+
"",
|
|
2101
|
+
"### Workflow",
|
|
2102
|
+
"",
|
|
2103
|
+
"1. Find the PR linked from the issue, project item, or issue timeline.",
|
|
2104
|
+
"2. Read the PR title, body, diff, linked issue, existing reviews, inline comments, and check status.",
|
|
2105
|
+
"3. Run the repository's relevant tests, lint, typecheck, or build commands when available and practical.",
|
|
2106
|
+
"4. Leave inline review comments for concrete, actionable findings.",
|
|
2107
|
+
"5. Submit a summary review: approve only when the change is correct and validation is acceptable; otherwise request changes.",
|
|
2108
|
+
"",
|
|
2109
|
+
"### Guardrails",
|
|
2110
|
+
"",
|
|
2111
|
+
"- Never push code from this posture.",
|
|
2112
|
+
"- Never approve PRs that introduce new dependencies without explicitly noting the dependency risk and why it is acceptable.",
|
|
2113
|
+
"- If relevant tests fail and the failure is not proven unrelated, request changes.",
|
|
2114
|
+
"- Keep comments specific to correctness, maintainability, tests, security, and issue fit.",
|
|
2115
|
+
"- Do not create a workpad; the review threads on the PR are the audit trail."
|
|
2116
|
+
].join("\n");
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
// src/skills/templates/gh-symphony-references/workflow-posture-maintain.ts
|
|
2120
|
+
function generateWorkflowPostureMaintainReference(ctx) {
|
|
2121
|
+
const validationGuidance = buildRepositoryValidationGuidance(
|
|
2122
|
+
ctx.detectedEnvironment
|
|
2123
|
+
);
|
|
2124
|
+
return [
|
|
2125
|
+
"# Workflow posture: maintain",
|
|
2126
|
+
"",
|
|
2127
|
+
"Use this prompt-body posture for low-risk maintenance such as dependency",
|
|
2128
|
+
"bumps, lint sweeps, small chores, and repository hygiene.",
|
|
2129
|
+
"",
|
|
2130
|
+
"## Agent Instructions",
|
|
2131
|
+
"",
|
|
2132
|
+
'You are a maintenance coding agent working on issue `{issue.identifier}`: "`{issue.title}`".',
|
|
2133
|
+
"",
|
|
2134
|
+
"**Repository:** `{issue.repository}`",
|
|
2135
|
+
"**Current state:** `{issue.state}`",
|
|
2136
|
+
"",
|
|
2137
|
+
"### Task",
|
|
2138
|
+
"",
|
|
2139
|
+
"`{issue.description}`",
|
|
2140
|
+
"",
|
|
2141
|
+
"### Default Posture",
|
|
2142
|
+
"",
|
|
2143
|
+
"1. Make the smallest possible change that satisfies the maintenance request.",
|
|
2144
|
+
"2. Defer human-judgment calls instead of broadening scope.",
|
|
2145
|
+
"3. In your final message, report only what was completed and any blockers. Do not include optional next steps.",
|
|
2146
|
+
"",
|
|
2147
|
+
"### Repository Validation Guidance",
|
|
2148
|
+
"",
|
|
2149
|
+
...validationGuidance.map((line, index) => `${index + 1}. ${line}`),
|
|
2150
|
+
"",
|
|
2151
|
+
"### Workflow",
|
|
2152
|
+
"",
|
|
2153
|
+
"1. Identify the exact maintenance task and affected files.",
|
|
2154
|
+
"2. Make the minimal change needed; avoid drive-by refactors.",
|
|
2155
|
+
"3. Run the relevant tests, lint, typecheck, or build commands for the affected area.",
|
|
2156
|
+
"4. Create a PR when the change is complete, or exit with a blocker note if approval is required.",
|
|
2157
|
+
"",
|
|
2158
|
+
"### Guardrails",
|
|
2159
|
+
"",
|
|
2160
|
+
"- Do not perform major dependency bumps without explicit approval.",
|
|
2161
|
+
"- Do not delete files without confirmation unless the issue explicitly requests it.",
|
|
2162
|
+
"- If the implementation exceeds 50 lines of non-generated code, stop and ask for human confirmation before continuing.",
|
|
2163
|
+
"- Do not mix unrelated cleanup into the maintenance change.",
|
|
2164
|
+
"",
|
|
2165
|
+
"### Workpad Template",
|
|
2166
|
+
"",
|
|
2167
|
+
"Create a compact workpad comment on the issue with the following structure:",
|
|
2168
|
+
"",
|
|
2169
|
+
"```md",
|
|
2170
|
+
"## Workpad",
|
|
2171
|
+
"",
|
|
2172
|
+
"### Plan",
|
|
2173
|
+
"",
|
|
2174
|
+
"- [ ] Minimal maintenance change",
|
|
2175
|
+
"- [ ] Validation and PR handoff",
|
|
2176
|
+
"",
|
|
2177
|
+
"### Validation",
|
|
2178
|
+
"",
|
|
2179
|
+
"- [ ] Test/lint/typecheck/build command",
|
|
2180
|
+
"",
|
|
2181
|
+
"### Blockers",
|
|
2182
|
+
"",
|
|
2183
|
+
"None",
|
|
2184
|
+
"```"
|
|
2185
|
+
].join("\n");
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
// src/skills/templates/gh-symphony-references/index.ts
|
|
2189
|
+
var GH_SYMPHONY_REFERENCE_FILES = [
|
|
2190
|
+
{
|
|
2191
|
+
relativePath: "references/README.md",
|
|
2192
|
+
generate: generateGhSymphonyReferencesReadme
|
|
2193
|
+
},
|
|
2194
|
+
{
|
|
2195
|
+
relativePath: "references/workflow-schema.md",
|
|
2196
|
+
generate: generateWorkflowSchemaReference
|
|
2197
|
+
},
|
|
2198
|
+
{
|
|
2199
|
+
relativePath: "references/workflow-posture-implement.md",
|
|
2200
|
+
generate: generateWorkflowPostureImplementReference
|
|
2201
|
+
},
|
|
2202
|
+
{
|
|
2203
|
+
relativePath: "references/workflow-posture-review.md",
|
|
2204
|
+
generate: generateWorkflowPostureReviewReference
|
|
2205
|
+
},
|
|
2206
|
+
{
|
|
2207
|
+
relativePath: "references/workflow-posture-maintain.md",
|
|
2208
|
+
generate: generateWorkflowPostureMaintainReference
|
|
2209
|
+
}
|
|
2210
|
+
];
|
|
2211
|
+
|
|
1904
2212
|
// src/skills/templates/index.ts
|
|
1905
2213
|
var ALL_SKILL_TEMPLATES = [
|
|
1906
2214
|
{
|
|
1907
2215
|
name: "gh-symphony",
|
|
1908
|
-
|
|
1909
|
-
|
|
2216
|
+
files: [
|
|
2217
|
+
{ relativePath: "SKILL.md", generate: generateGhSymphonySkill },
|
|
2218
|
+
...GH_SYMPHONY_REFERENCE_FILES
|
|
2219
|
+
]
|
|
1910
2220
|
},
|
|
1911
2221
|
{
|
|
1912
2222
|
name: "gh-project",
|
|
1913
|
-
|
|
1914
|
-
generate: generateGhProjectSkill
|
|
2223
|
+
files: [{ relativePath: "SKILL.md", generate: generateGhProjectSkill }]
|
|
1915
2224
|
},
|
|
1916
|
-
{
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
2225
|
+
{
|
|
2226
|
+
name: "commit",
|
|
2227
|
+
files: [{ relativePath: "SKILL.md", generate: generateCommitSkill }]
|
|
2228
|
+
},
|
|
2229
|
+
{
|
|
2230
|
+
name: "push",
|
|
2231
|
+
files: [{ relativePath: "SKILL.md", generate: generatePushSkill }]
|
|
2232
|
+
},
|
|
2233
|
+
{
|
|
2234
|
+
name: "pull",
|
|
2235
|
+
files: [{ relativePath: "SKILL.md", generate: generatePullSkill }]
|
|
2236
|
+
},
|
|
2237
|
+
{
|
|
2238
|
+
name: "land",
|
|
2239
|
+
files: [{ relativePath: "SKILL.md", generate: generateLandSkill }]
|
|
2240
|
+
}
|
|
1920
2241
|
];
|
|
1921
2242
|
|
|
1922
2243
|
// src/commands/workflow-init.ts
|
|
@@ -2112,7 +2433,7 @@ async function writePlannedFile(file) {
|
|
|
2112
2433
|
if (file.status === "unchanged") {
|
|
2113
2434
|
return false;
|
|
2114
2435
|
}
|
|
2115
|
-
await mkdir3(
|
|
2436
|
+
await mkdir3(dirname3(file.path), { recursive: true });
|
|
2116
2437
|
const temporaryPath = `${file.path}.tmp`;
|
|
2117
2438
|
await writeFile3(temporaryPath, file.content, "utf8");
|
|
2118
2439
|
await rename2(temporaryPath, file.path);
|
|
@@ -2121,6 +2442,9 @@ async function writePlannedFile(file) {
|
|
|
2121
2442
|
}
|
|
2122
2443
|
return true;
|
|
2123
2444
|
}
|
|
2445
|
+
function skillNameForPath(skillsDir, filePath) {
|
|
2446
|
+
return relative(skillsDir, filePath).split(/[\\/]/)[0] ?? "";
|
|
2447
|
+
}
|
|
2124
2448
|
function resolveStatusField(projectDetail) {
|
|
2125
2449
|
return projectDetail.statusFields.find((f) => f.name.toLowerCase() === "status") ?? projectDetail.statusFields[0] ?? null;
|
|
2126
2450
|
}
|
|
@@ -2543,10 +2867,11 @@ async function planEcosystem(opts) {
|
|
|
2543
2867
|
}
|
|
2544
2868
|
);
|
|
2545
2869
|
for (const plannedSkill of plannedSkills) {
|
|
2870
|
+
const skillName = skillNameForPath(skillsDir, plannedSkill.path);
|
|
2546
2871
|
files.push(
|
|
2547
2872
|
await planFileChange({
|
|
2548
2873
|
path: plannedSkill.path,
|
|
2549
|
-
label: `Skill ${
|
|
2874
|
+
label: `Skill ${skillName}`,
|
|
2550
2875
|
content: plannedSkill.content,
|
|
2551
2876
|
mode: "create-only"
|
|
2552
2877
|
})
|
|
@@ -2596,7 +2921,7 @@ async function writeEcosystem(opts) {
|
|
|
2596
2921
|
continue;
|
|
2597
2922
|
}
|
|
2598
2923
|
if (file.label.startsWith("Skill ")) {
|
|
2599
|
-
const skillName =
|
|
2924
|
+
const skillName = file.label.slice("Skill ".length);
|
|
2600
2925
|
if (written) {
|
|
2601
2926
|
skillsWritten.push(skillName);
|
|
2602
2927
|
} else {
|
|
@@ -2616,8 +2941,8 @@ async function writeEcosystem(opts) {
|
|
|
2616
2941
|
afterCreateHookWritten,
|
|
2617
2942
|
contextYamlWritten,
|
|
2618
2943
|
referenceWorkflowWritten,
|
|
2619
|
-
skillsWritten: skillsWritten.sort(),
|
|
2620
|
-
skillsSkipped: skillsSkipped.sort()
|
|
2944
|
+
skillsWritten: [...new Set(skillsWritten)].sort(),
|
|
2945
|
+
skillsSkipped: [...new Set(skillsSkipped)].sort()
|
|
2621
2946
|
};
|
|
2622
2947
|
}
|
|
2623
2948
|
function formatPrioritySummaryLines(priority) {
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
parseIssueReference,
|
|
6
6
|
readGitHubProjectBinding,
|
|
7
7
|
renderIssueWorkflowPreview
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-TTVGBHZI.js";
|
|
9
|
+
import "./chunk-ZPS4CQZJ.js";
|
|
10
10
|
import {
|
|
11
11
|
fetchGithubProjectIssueByRepositoryAndNumber,
|
|
12
12
|
fetchGithubProjectIssues,
|
|
13
13
|
inspectManagedProjectSelection
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-B6G3KGBB.js";
|
|
15
|
+
import "./chunk-Z7CDL3T2.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveRuntimeRoot
|
|
18
18
|
} from "./chunk-RZ3WO7OV.js";
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
resolveClaudeCommandBinary,
|
|
41
41
|
resolveRuntimeCommandBinary,
|
|
42
42
|
runClaudePreflight
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-6OPRRC2J.js";
|
|
44
44
|
import {
|
|
45
45
|
configFilePath,
|
|
46
46
|
orchestratorLogPath,
|
package/dist/index.js
CHANGED
|
@@ -417,13 +417,13 @@ function createRemovedCommandHandler(message) {
|
|
|
417
417
|
|
|
418
418
|
// src/index.ts
|
|
419
419
|
var COMMANDS = {
|
|
420
|
-
workflow: () => import("./workflow-
|
|
421
|
-
setup: () => import("./setup-
|
|
422
|
-
doctor: () => import("./doctor-
|
|
423
|
-
upgrade: () => import("./upgrade-
|
|
424
|
-
repo: () => import("./repo-
|
|
420
|
+
workflow: () => import("./workflow-BOZ25AJ2.js"),
|
|
421
|
+
setup: () => import("./setup-JINI7HBM.js"),
|
|
422
|
+
doctor: () => import("./doctor-CCUTNEYN.js"),
|
|
423
|
+
upgrade: () => import("./upgrade-EBD4LX5W.js"),
|
|
424
|
+
repo: () => import("./repo-C2APQR2P.js"),
|
|
425
425
|
config: () => import("./config-cmd-AOZVS6GU.js"),
|
|
426
|
-
version: () => import("./version-
|
|
426
|
+
version: () => import("./version-6Z354HHH.js")
|
|
427
427
|
};
|
|
428
428
|
function addGlobalOptions(command) {
|
|
429
429
|
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");
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
initRepoRuntime,
|
|
19
19
|
parseRepoRuntimeFlags
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-QOX5UGUE.js";
|
|
21
21
|
import {
|
|
22
22
|
OrchestratorService,
|
|
23
23
|
acquireProjectLock,
|
|
@@ -33,8 +33,8 @@ import {
|
|
|
33
33
|
resolveOrchestratorLogLevel,
|
|
34
34
|
resolveTrackerAdapter,
|
|
35
35
|
runCli
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-B6G3KGBB.js";
|
|
37
|
+
import "./chunk-Z7CDL3T2.js";
|
|
38
38
|
import {
|
|
39
39
|
resolveRepoRuntimeRoot,
|
|
40
40
|
resolveRuntimeRoot
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
parseRecentEvents,
|
|
59
59
|
readJsonFile,
|
|
60
60
|
safeReadDir
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-6OPRRC2J.js";
|
|
62
62
|
import {
|
|
63
63
|
daemonPidPath,
|
|
64
64
|
httpStatusPath,
|
|
@@ -990,6 +990,7 @@ async function statusForIssue(reader, issueIdentifier) {
|
|
|
990
990
|
kind: resolvedRun?.retryKind ?? null,
|
|
991
991
|
error: resolvedRun?.lastError ?? issueRecord.retryEntry?.error ?? null
|
|
992
992
|
} : null,
|
|
993
|
+
recovery: resolvedRun?.recovery ?? null,
|
|
993
994
|
logs: {
|
|
994
995
|
codex_session_logs: resolvedRun === null ? [] : [
|
|
995
996
|
{
|
|
@@ -2568,6 +2569,22 @@ function renderLegacyStatus(snapshot, noColor) {
|
|
|
2568
2569
|
}
|
|
2569
2570
|
lines.push("");
|
|
2570
2571
|
}
|
|
2572
|
+
if (snapshot.recovery) {
|
|
2573
|
+
const recovery = snapshot.recovery;
|
|
2574
|
+
lines.push(apply(yellow(" Recoverable incomplete turn:")));
|
|
2575
|
+
lines.push(` Run ${recovery.runId}`);
|
|
2576
|
+
lines.push(` Issue ${recovery.issueId}`);
|
|
2577
|
+
lines.push(` Workspace ${recovery.workspacePath}`);
|
|
2578
|
+
lines.push(
|
|
2579
|
+
` Dirty ${recovery.dirtyFiles.length > 0 ? recovery.dirtyFiles.join(", ") : "none"}`
|
|
2580
|
+
);
|
|
2581
|
+
lines.push(` Last ${recovery.lastEvent ?? "unknown"}`);
|
|
2582
|
+
lines.push(` At ${recovery.lastEventAt ?? "unknown"}`);
|
|
2583
|
+
lines.push(` Session ${recovery.sessionId ?? "unknown"}`);
|
|
2584
|
+
lines.push(` Thread ${recovery.threadId ?? "unknown"}`);
|
|
2585
|
+
lines.push(` Command ${recovery.suggestedCommand}`);
|
|
2586
|
+
lines.push("");
|
|
2587
|
+
}
|
|
2571
2588
|
if (snapshot.lastError) {
|
|
2572
2589
|
lines.push(apply(red(` \u2717 ${snapshot.lastError}`)));
|
|
2573
2590
|
lines.push("");
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
validateStateMapping,
|
|
15
15
|
writeEcosystem,
|
|
16
16
|
writeWorkflowPlan
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZPS4CQZJ.js";
|
|
18
18
|
import {
|
|
19
19
|
initRepoRuntime
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-QOX5UGUE.js";
|
|
21
21
|
import "./chunk-RZ3WO7OV.js";
|
|
22
22
|
import {
|
|
23
23
|
GhAuthError,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
listUserProjects,
|
|
32
32
|
validateToken
|
|
33
33
|
} from "./chunk-SMNIGNS3.js";
|
|
34
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-6OPRRC2J.js";
|
|
35
35
|
import "./chunk-4ICDSQCJ.js";
|
|
36
36
|
|
|
37
37
|
// src/commands/setup.ts
|
|
@@ -16,8 +16,8 @@ function execFileAsync(file, args, execFileImpl = execFileCallback) {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
function resolveCurrentCliVersion() {
|
|
19
|
-
if ("0.
|
|
20
|
-
return "0.
|
|
19
|
+
if ("0.4.0".length > 0) {
|
|
20
|
+
return "0.4.0";
|
|
21
21
|
}
|
|
22
22
|
const pkg = JSON.parse(
|
|
23
23
|
readFileSync(new URL("../../package.json", import.meta.url), "utf8")
|
package/dist/worker-entry.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
normalizeCodexRuntimeEvents,
|
|
7
7
|
prepareCodexRuntimePlan,
|
|
8
8
|
resolveLocalRuntimeLaunchConfig
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-Z7CDL3T2.js";
|
|
10
10
|
import {
|
|
11
11
|
DEFAULT_AGENT_INPUT_REQUIRED_REASON,
|
|
12
12
|
classifySessionExit,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
resolveClaudeCommandBinary,
|
|
18
18
|
resolveWorkflowRuntimeCommand,
|
|
19
19
|
runClaudePreflight
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-6OPRRC2J.js";
|
|
21
21
|
|
|
22
22
|
// ../worker/src/index.ts
|
|
23
23
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
resetWorkflowCommandDependenciesForTest,
|
|
7
7
|
setWorkflowCommandDependenciesForTest,
|
|
8
8
|
workflow_default
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-TTVGBHZI.js";
|
|
10
|
+
import "./chunk-ZPS4CQZJ.js";
|
|
11
|
+
import "./chunk-B6G3KGBB.js";
|
|
12
|
+
import "./chunk-Z7CDL3T2.js";
|
|
13
13
|
import "./chunk-SMNIGNS3.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-6OPRRC2J.js";
|
|
15
15
|
import "./chunk-4ICDSQCJ.js";
|
|
16
16
|
export {
|
|
17
17
|
workflow_default as default,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gh-symphony/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "hojinzs",
|
|
6
6
|
"description": "Interactive CLI for GitHub Symphony orchestration",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"tsup": "^8.5.1",
|
|
44
44
|
"@gh-symphony/core": "0.0.14",
|
|
45
|
-
"@gh-symphony/
|
|
45
|
+
"@gh-symphony/orchestrator": "0.0.14",
|
|
46
46
|
"@gh-symphony/dashboard": "0.0.14",
|
|
47
|
+
"@gh-symphony/control-plane": "0.0.15",
|
|
48
|
+
"@gh-symphony/tracker-github": "0.0.14",
|
|
47
49
|
"@gh-symphony/runtime-claude": "0.0.14",
|
|
48
|
-
"@gh-symphony/
|
|
49
|
-
"@gh-symphony/worker": "0.0.14",
|
|
50
|
-
"@gh-symphony/tracker-github": "0.0.14"
|
|
50
|
+
"@gh-symphony/worker": "0.0.14"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
53
|
"build": "tsup",
|