@gh-symphony/cli 0.0.13 → 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.
- package/dist/chunk-5NV3LSAJ.js +11 -0
- package/dist/chunk-6HBZC3BE.js +468 -0
- package/dist/chunk-76QPITKI.js +109 -0
- package/dist/chunk-IWR4UQEJ.js +2250 -0
- package/dist/chunk-JO3AXHQI.js +130 -0
- package/dist/chunk-M7OSMUTN.js +874 -0
- package/dist/chunk-MVRF7BES.js +68 -0
- package/dist/chunk-RNWX7DQU.js +4617 -0
- package/dist/chunk-ROGRTUFI.js +108 -0
- package/dist/chunk-TH5QPO3Y.js +67 -0
- package/dist/config-cmd-AZ7POMAA.js +110 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +568 -356
- package/dist/init-EZXQAXZM.js +17 -0
- package/dist/logs-6LNGT2GF.js +188 -0
- package/dist/project-3ELXQ35D.js +678 -0
- package/dist/recover-T6ME6C56.js +130 -0
- package/dist/repo-R3XBIVAX.js +121 -0
- package/dist/run-DYINRZHK.js +107 -0
- package/dist/start-PIFQMIC2.js +15 -0
- package/dist/status-3WK5BWRZ.js +11 -0
- package/dist/stop-AA3AP5M6.js +9 -0
- package/dist/version-VBB62JWI.js +30 -0
- package/package.json +11 -6
- package/dist/ansi.d.ts +0 -15
- package/dist/ansi.js +0 -53
- package/dist/commands/config-cmd.d.ts +0 -3
- package/dist/commands/config-cmd.js +0 -90
- package/dist/commands/help.d.ts +0 -3
- package/dist/commands/help.js +0 -55
- package/dist/commands/init.d.ts +0 -34
- package/dist/commands/init.js +0 -477
- package/dist/commands/logs.d.ts +0 -3
- package/dist/commands/logs.js +0 -184
- package/dist/commands/project.d.ts +0 -3
- package/dist/commands/project.js +0 -649
- package/dist/commands/recover.d.ts +0 -3
- package/dist/commands/recover.js +0 -119
- package/dist/commands/repo.d.ts +0 -3
- package/dist/commands/repo.js +0 -103
- package/dist/commands/run.d.ts +0 -3
- package/dist/commands/run.js +0 -95
- package/dist/commands/start.d.ts +0 -20
- package/dist/commands/start.js +0 -344
- package/dist/commands/status-refresh.d.ts +0 -9
- package/dist/commands/status-refresh.js +0 -27
- package/dist/commands/status.d.ts +0 -3
- package/dist/commands/status.js +0 -237
- package/dist/commands/stop.d.ts +0 -3
- package/dist/commands/stop.js +0 -92
- package/dist/commands/version.d.ts +0 -3
- package/dist/commands/version.js +0 -21
- package/dist/completion.d.ts +0 -1
- package/dist/completion.js +0 -204
- package/dist/config.d.ts +0 -38
- package/dist/config.js +0 -82
- package/dist/context/context-types.d.ts +0 -36
- package/dist/context/context-types.js +0 -1
- package/dist/context/generate-context-yaml.d.ts +0 -15
- package/dist/context/generate-context-yaml.js +0 -129
- package/dist/dashboard/renderer.d.ts +0 -9
- package/dist/dashboard/renderer.js +0 -220
- package/dist/detection/environment-detector.d.ts +0 -11
- package/dist/detection/environment-detector.js +0 -140
- package/dist/github/client.d.ts +0 -71
- package/dist/github/client.js +0 -348
- package/dist/github/gh-auth.d.ts +0 -34
- package/dist/github/gh-auth.js +0 -110
- package/dist/mapping/smart-defaults.d.ts +0 -17
- package/dist/mapping/smart-defaults.js +0 -86
- package/dist/orchestrator-runtime.d.ts +0 -1
- package/dist/orchestrator-runtime.js +0 -4
- package/dist/orchestrator-status-endpoint.d.ts +0 -5
- package/dist/orchestrator-status-endpoint.js +0 -27
- package/dist/project-selection.d.ts +0 -8
- package/dist/project-selection.js +0 -56
- package/dist/skills/skill-writer.d.ts +0 -14
- package/dist/skills/skill-writer.js +0 -62
- package/dist/skills/templates/commit.d.ts +0 -2
- package/dist/skills/templates/commit.js +0 -45
- package/dist/skills/templates/document.d.ts +0 -7
- package/dist/skills/templates/document.js +0 -16
- package/dist/skills/templates/gh-project.d.ts +0 -2
- package/dist/skills/templates/gh-project.js +0 -88
- package/dist/skills/templates/gh-symphony.d.ts +0 -2
- package/dist/skills/templates/gh-symphony.js +0 -125
- package/dist/skills/templates/index.d.ts +0 -8
- package/dist/skills/templates/index.js +0 -28
- package/dist/skills/templates/land.d.ts +0 -2
- package/dist/skills/templates/land.js +0 -59
- package/dist/skills/templates/pull.d.ts +0 -2
- package/dist/skills/templates/pull.js +0 -41
- package/dist/skills/templates/push.d.ts +0 -2
- package/dist/skills/templates/push.js +0 -36
- package/dist/skills/types.d.ts +0 -23
- package/dist/skills/types.js +0 -1
- package/dist/workflow/generate-reference-workflow.d.ts +0 -9
- package/dist/workflow/generate-reference-workflow.js +0 -261
- package/dist/workflow/generate-workflow-md.d.ts +0 -12
- package/dist/workflow/generate-workflow-md.js +0 -134
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
type RefreshRequestOptions = {
|
|
2
|
-
fetchImpl?: typeof fetch;
|
|
3
|
-
timeoutMs?: number;
|
|
4
|
-
env?: NodeJS.ProcessEnv;
|
|
5
|
-
baseUrl?: string | null;
|
|
6
|
-
};
|
|
7
|
-
export declare function resolveOrchestratorStatusBaseUrl(env?: NodeJS.ProcessEnv): string;
|
|
8
|
-
export declare function requestOrchestratorRefresh(options?: RefreshRequestOptions): Promise<boolean>;
|
|
9
|
-
export {};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export function resolveOrchestratorStatusBaseUrl(env = process.env) {
|
|
2
|
-
const host = env.ORCHESTRATOR_STATUS_HOST ?? "127.0.0.1";
|
|
3
|
-
const port = env.ORCHESTRATOR_STATUS_PORT ?? "4680";
|
|
4
|
-
const urlHost = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
5
|
-
return `http://${urlHost}:${port}`;
|
|
6
|
-
}
|
|
7
|
-
export async function requestOrchestratorRefresh(options = {}) {
|
|
8
|
-
const fetchImpl = options.fetchImpl ?? fetch;
|
|
9
|
-
const timeoutMs = options.timeoutMs ?? 5_000;
|
|
10
|
-
const signal = AbortSignal.timeout(timeoutMs);
|
|
11
|
-
const baseUrl = "baseUrl" in options
|
|
12
|
-
? options.baseUrl
|
|
13
|
-
: resolveOrchestratorStatusBaseUrl(options.env);
|
|
14
|
-
if (!baseUrl) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
const response = await fetchImpl(`${baseUrl}/api/v1/refresh`, {
|
|
19
|
-
method: "POST",
|
|
20
|
-
signal,
|
|
21
|
-
});
|
|
22
|
-
return response.ok;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
package/dist/commands/status.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { resolveRuntimeRoot, } from "../orchestrator-runtime.js";
|
|
4
|
-
import { handleMissingManagedProjectConfig, resolveManagedProjectConfig, } from "../project-selection.js";
|
|
5
|
-
import { bold, dim, green, red, yellow, cyan, stripAnsi } from "../ansi.js";
|
|
6
|
-
import { clearScreen, showCursor, hideCursor } from "../ansi.js";
|
|
7
|
-
import { renderDashboard } from "../dashboard/renderer.js";
|
|
8
|
-
import { resolveProjectOrchestratorStatusBaseUrl } from "../orchestrator-status-endpoint.js";
|
|
9
|
-
import { requestOrchestratorRefresh } from "./status-refresh.js";
|
|
10
|
-
const WATCH_REFRESH_TIMEOUT_MS = 1_500;
|
|
11
|
-
function healthIcon(health) {
|
|
12
|
-
switch (health) {
|
|
13
|
-
case "idle":
|
|
14
|
-
case "running":
|
|
15
|
-
return green("●");
|
|
16
|
-
case "degraded":
|
|
17
|
-
return red("●");
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function relativeTime(isoString) {
|
|
21
|
-
const now = new Date();
|
|
22
|
-
const then = new Date(isoString);
|
|
23
|
-
const diffMs = now.getTime() - then.getTime();
|
|
24
|
-
const diffS = Math.floor(diffMs / 1000);
|
|
25
|
-
const diffM = Math.floor(diffS / 60);
|
|
26
|
-
const diffH = Math.floor(diffM / 60);
|
|
27
|
-
if (diffS < 60)
|
|
28
|
-
return `${diffS}s ago`;
|
|
29
|
-
if (diffM < 60)
|
|
30
|
-
return `${diffM}m ago`;
|
|
31
|
-
return `${diffH}h ago`;
|
|
32
|
-
}
|
|
33
|
-
function truncate(s, len) {
|
|
34
|
-
if (s.length <= len)
|
|
35
|
-
return s;
|
|
36
|
-
return s.slice(0, len - 3) + "...";
|
|
37
|
-
}
|
|
38
|
-
function renderLegacyStatus(snapshot, noColor) {
|
|
39
|
-
const apply = noColor ? (s) => stripAnsi(s) : (s) => s;
|
|
40
|
-
const lines = [];
|
|
41
|
-
// Header
|
|
42
|
-
const headerTitle = `gh-symphony ∙ ${snapshot.slug}`;
|
|
43
|
-
const headerWidth = 45;
|
|
44
|
-
const headerPadding = Math.max(0, headerWidth - stripAnsi(headerTitle).length);
|
|
45
|
-
lines.push("╭" + "─".repeat(headerWidth) + "╮");
|
|
46
|
-
lines.push("│ " + apply(bold(headerTitle)) + " ".repeat(headerPadding) + "│");
|
|
47
|
-
lines.push("╰" + "─".repeat(headerWidth) + "╯");
|
|
48
|
-
lines.push("");
|
|
49
|
-
// Health and last tick
|
|
50
|
-
const healthStr = apply(`${healthIcon(snapshot.health)} Health ${snapshot.health}`);
|
|
51
|
-
const lastTickStr = apply(`Last tick ${relativeTime(snapshot.lastTickAt)}`);
|
|
52
|
-
lines.push(` ${healthStr}${" ".repeat(Math.max(0, 30 - stripAnsi(healthStr).length))}${lastTickStr}`);
|
|
53
|
-
lines.push("");
|
|
54
|
-
// Summary stats
|
|
55
|
-
const dispatchedStr = apply(`Dispatched ${snapshot.summary.dispatched}`);
|
|
56
|
-
const activeRunsStr = apply(`Active Runs ${snapshot.summary.activeRuns}`);
|
|
57
|
-
const suppressedStr = apply(`Suppressed ${snapshot.summary.suppressed}`);
|
|
58
|
-
const recoveredStr = apply(`Recovered ${snapshot.summary.recovered}`);
|
|
59
|
-
lines.push(` ${dispatchedStr}${" ".repeat(Math.max(0, 20 - stripAnsi(dispatchedStr).length))}${activeRunsStr}`);
|
|
60
|
-
lines.push(` ${suppressedStr}${" ".repeat(Math.max(0, 20 - stripAnsi(suppressedStr).length))}${recoveredStr}`);
|
|
61
|
-
lines.push("");
|
|
62
|
-
// Active runs table
|
|
63
|
-
if (snapshot.activeRuns.length > 0) {
|
|
64
|
-
lines.push(" Active Runs:");
|
|
65
|
-
for (const run of snapshot.activeRuns) {
|
|
66
|
-
const runIdDisplay = truncate(run.runId, 12);
|
|
67
|
-
const stateStr = apply(cyan(run.issueState));
|
|
68
|
-
const statusColor = run.status === "running"
|
|
69
|
-
? green
|
|
70
|
-
: run.status === "failed"
|
|
71
|
-
? red
|
|
72
|
-
: run.status === "succeeded"
|
|
73
|
-
? green
|
|
74
|
-
: dim;
|
|
75
|
-
const statusStr = apply(statusColor(run.status));
|
|
76
|
-
lines.push(` ${runIdDisplay} ${run.issueIdentifier} ${stateStr} ${statusStr}`);
|
|
77
|
-
}
|
|
78
|
-
lines.push("");
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
lines.push(" No active runs.");
|
|
82
|
-
lines.push("");
|
|
83
|
-
}
|
|
84
|
-
// Retry queue
|
|
85
|
-
if (snapshot.retryQueue.length > 0) {
|
|
86
|
-
lines.push(" Retry Queue:");
|
|
87
|
-
for (const retry of snapshot.retryQueue) {
|
|
88
|
-
const runIdDisplay = truncate(retry.runId, 12);
|
|
89
|
-
const nextRetryDisplay = retry.nextRetryAt
|
|
90
|
-
? relativeTime(retry.nextRetryAt)
|
|
91
|
-
: "pending";
|
|
92
|
-
lines.push(` ${runIdDisplay} ${retry.issueIdentifier} ${apply(yellow(retry.retryKind))} ${nextRetryDisplay}`);
|
|
93
|
-
}
|
|
94
|
-
lines.push("");
|
|
95
|
-
}
|
|
96
|
-
// Last error
|
|
97
|
-
if (snapshot.lastError) {
|
|
98
|
-
lines.push(apply(red(` ✗ ${snapshot.lastError}`)));
|
|
99
|
-
lines.push("");
|
|
100
|
-
}
|
|
101
|
-
// Token usage
|
|
102
|
-
if (snapshot.codexTotals) {
|
|
103
|
-
const tokenStr = apply(`Tokens: ${snapshot.codexTotals.inputTokens} in / ${snapshot.codexTotals.outputTokens} out / ${snapshot.codexTotals.totalTokens} total`);
|
|
104
|
-
lines.push(` ${tokenStr}`);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
lines.push(" Tokens: 0 in / 0 out / 0 total");
|
|
108
|
-
}
|
|
109
|
-
return lines.join("\n");
|
|
110
|
-
}
|
|
111
|
-
function parseStatusArgs(args) {
|
|
112
|
-
const parsed = {
|
|
113
|
-
watch: false,
|
|
114
|
-
};
|
|
115
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
116
|
-
const arg = args[i];
|
|
117
|
-
if (arg === "--watch" || arg === "-w") {
|
|
118
|
-
parsed.watch = true;
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (arg === "--project" || arg === "--project-id") {
|
|
122
|
-
const value = args[i + 1];
|
|
123
|
-
if (!value || value.startsWith("-")) {
|
|
124
|
-
parsed.error = `Option '${arg}' argument missing`;
|
|
125
|
-
return parsed;
|
|
126
|
-
}
|
|
127
|
-
parsed.projectId = value;
|
|
128
|
-
i += 1;
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
if (arg?.startsWith("-")) {
|
|
132
|
-
parsed.error = `Unknown option '${arg}'`;
|
|
133
|
-
return parsed;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return parsed;
|
|
137
|
-
}
|
|
138
|
-
async function readStatusSnapshot(runtimeRoot, projectId) {
|
|
139
|
-
try {
|
|
140
|
-
const statusPath = join(runtimeRoot, "projects", projectId, "status.json");
|
|
141
|
-
const content = await readFile(statusPath, "utf-8");
|
|
142
|
-
return JSON.parse(content);
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const handler = async (args, options) => {
|
|
149
|
-
const parsed = parseStatusArgs(args);
|
|
150
|
-
if (parsed.error) {
|
|
151
|
-
process.stderr.write(`${parsed.error}\n`);
|
|
152
|
-
process.stderr.write("Usage: gh-symphony status [--project-id <project-id>] [--watch]\n");
|
|
153
|
-
process.exitCode = 2;
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const projectConfig = await resolveManagedProjectConfig({
|
|
157
|
-
configDir: options.configDir,
|
|
158
|
-
requestedProjectId: parsed.projectId,
|
|
159
|
-
});
|
|
160
|
-
if (!projectConfig) {
|
|
161
|
-
handleMissingManagedProjectConfig();
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
const runtimeRoot = resolveRuntimeRoot(options.configDir);
|
|
165
|
-
const projectId = projectConfig.projectId;
|
|
166
|
-
if (parsed.watch) {
|
|
167
|
-
const isTTY = process.stdout.isTTY === true;
|
|
168
|
-
let terminalWidth = process.stdout.columns ?? 115;
|
|
169
|
-
let runPromise = null;
|
|
170
|
-
const run = async () => {
|
|
171
|
-
const baseUrl = await resolveProjectOrchestratorStatusBaseUrl({
|
|
172
|
-
configDir: options.configDir,
|
|
173
|
-
projectId,
|
|
174
|
-
});
|
|
175
|
-
await requestOrchestratorRefresh({
|
|
176
|
-
baseUrl,
|
|
177
|
-
timeoutMs: WATCH_REFRESH_TIMEOUT_MS,
|
|
178
|
-
});
|
|
179
|
-
const snapshot = await readStatusSnapshot(runtimeRoot, projectId);
|
|
180
|
-
if (options.json || !isTTY) {
|
|
181
|
-
process.stdout.write(JSON.stringify(snapshot, null, 2) + "\n");
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
if (!snapshot) {
|
|
185
|
-
process.stdout.write(clearScreen() + "Unable to read status snapshot.\n");
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
process.stdout.write(clearScreen() +
|
|
189
|
-
renderDashboard([snapshot], {
|
|
190
|
-
terminalWidth,
|
|
191
|
-
noColor: options.noColor,
|
|
192
|
-
}) +
|
|
193
|
-
"\n");
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
const tick = () => {
|
|
197
|
-
if (runPromise) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
runPromise = run().finally(() => {
|
|
201
|
-
runPromise = null;
|
|
202
|
-
});
|
|
203
|
-
};
|
|
204
|
-
if (isTTY) {
|
|
205
|
-
process.stdout.write(hideCursor());
|
|
206
|
-
}
|
|
207
|
-
tick();
|
|
208
|
-
await runPromise;
|
|
209
|
-
const interval = setInterval(tick, 2000);
|
|
210
|
-
process.on("SIGWINCH", () => {
|
|
211
|
-
terminalWidth = process.stdout.columns ?? terminalWidth;
|
|
212
|
-
});
|
|
213
|
-
const shutdown = () => {
|
|
214
|
-
clearInterval(interval);
|
|
215
|
-
process.stdout.write(showCursor() + "\n");
|
|
216
|
-
process.exit(0);
|
|
217
|
-
};
|
|
218
|
-
process.on("SIGINT", shutdown);
|
|
219
|
-
process.on("SIGTERM", shutdown);
|
|
220
|
-
await new Promise(() => { });
|
|
221
|
-
}
|
|
222
|
-
// Single status query
|
|
223
|
-
const snapshot = await readStatusSnapshot(runtimeRoot, projectId);
|
|
224
|
-
if (snapshot) {
|
|
225
|
-
if (options.json) {
|
|
226
|
-
process.stdout.write(JSON.stringify(snapshot, null, 2) + "\n");
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
process.stdout.write(renderLegacyStatus(snapshot, options.noColor) + "\n");
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
process.stderr.write("Unable to read status snapshot.\n");
|
|
234
|
-
process.exitCode = 1;
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
export default handler;
|
package/dist/commands/stop.d.ts
DELETED
package/dist/commands/stop.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { readFile, rm } from "node:fs/promises";
|
|
2
|
-
import { daemonPidPath, orchestratorPortPath } from "../config.js";
|
|
3
|
-
import { handleMissingManagedProjectConfig, resolveManagedProjectConfig, } from "../project-selection.js";
|
|
4
|
-
function parseStopArgs(args) {
|
|
5
|
-
const parsed = {
|
|
6
|
-
force: false,
|
|
7
|
-
};
|
|
8
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
9
|
-
const arg = args[i];
|
|
10
|
-
if (arg === "--force") {
|
|
11
|
-
parsed.force = true;
|
|
12
|
-
continue;
|
|
13
|
-
}
|
|
14
|
-
if (arg === "--project" || arg === "--project-id") {
|
|
15
|
-
const value = args[i + 1];
|
|
16
|
-
if (!value || value.startsWith("-")) {
|
|
17
|
-
parsed.error = `Option '${arg}' argument missing`;
|
|
18
|
-
return parsed;
|
|
19
|
-
}
|
|
20
|
-
parsed.projectId = value;
|
|
21
|
-
i += 1;
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
if (arg?.startsWith("-")) {
|
|
25
|
-
parsed.error = `Unknown option '${arg}'`;
|
|
26
|
-
return parsed;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return parsed;
|
|
30
|
-
}
|
|
31
|
-
const handler = async (args, options) => {
|
|
32
|
-
const parsed = parseStopArgs(args);
|
|
33
|
-
if (parsed.error) {
|
|
34
|
-
process.stderr.write(`${parsed.error}\n`);
|
|
35
|
-
process.stderr.write("Usage: gh-symphony stop --project-id <project-id> [--force]\n");
|
|
36
|
-
process.exitCode = 2;
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const resolvedForce = parsed.force;
|
|
40
|
-
const projectConfig = await resolveManagedProjectConfig({
|
|
41
|
-
configDir: options.configDir,
|
|
42
|
-
requestedProjectId: parsed.projectId,
|
|
43
|
-
});
|
|
44
|
-
if (!projectConfig) {
|
|
45
|
-
handleMissingManagedProjectConfig();
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const resolvedProjectId = projectConfig.projectId;
|
|
49
|
-
const pidPath = daemonPidPath(options.configDir, resolvedProjectId);
|
|
50
|
-
const portPath = orchestratorPortPath(options.configDir, resolvedProjectId);
|
|
51
|
-
let pidStr;
|
|
52
|
-
try {
|
|
53
|
-
pidStr = await readFile(pidPath, "utf8");
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
process.stderr.write(`No running daemon found for project "${resolvedProjectId}" (PID file missing).\n`);
|
|
57
|
-
process.exitCode = 1;
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const pid = Number.parseInt(pidStr.trim(), 10);
|
|
61
|
-
if (!Number.isFinite(pid)) {
|
|
62
|
-
process.stderr.write(`Invalid PID in ${pidPath}: ${pidStr}\n`);
|
|
63
|
-
process.exitCode = 1;
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
try {
|
|
67
|
-
// Check if process is running
|
|
68
|
-
process.kill(pid, 0);
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
process.stdout.write(`Daemon for project "${resolvedProjectId}" (PID ${pid}) is not running. Cleaning up PID file.\n`);
|
|
72
|
-
await rm(pidPath, { force: true });
|
|
73
|
-
await rm(portPath, { force: true });
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const signal = resolvedForce ? "SIGKILL" : "SIGTERM";
|
|
77
|
-
try {
|
|
78
|
-
process.kill(pid, signal);
|
|
79
|
-
process.stdout.write(`Sent ${signal} to orchestrator (PID ${pid}).\n`);
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
process.stderr.write(`Failed to stop process ${pid}: ${error instanceof Error ? error.message : "Unknown error"}\n`);
|
|
83
|
-
process.exitCode = 1;
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
await rm(pidPath, { force: true });
|
|
87
|
-
if (resolvedForce) {
|
|
88
|
-
await rm(portPath, { force: true });
|
|
89
|
-
}
|
|
90
|
-
process.stdout.write("Daemon stopped.\n");
|
|
91
|
-
};
|
|
92
|
-
export default handler;
|
package/dist/commands/version.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { resolve, dirname } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
const handler = async (_args, options) => {
|
|
5
|
-
let version = "0.0.0";
|
|
6
|
-
try {
|
|
7
|
-
const pkgPath = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json");
|
|
8
|
-
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
9
|
-
version = pkg.version ?? version;
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
// Fall back to default
|
|
13
|
-
}
|
|
14
|
-
if (options.json) {
|
|
15
|
-
process.stdout.write(JSON.stringify({ version }) + "\n");
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
process.stdout.write(`gh-symphony v${version}\n`);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
export default handler;
|
package/dist/completion.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function renderCompletionScript(shell: "bash" | "zsh" | "fish"): string;
|
package/dist/completion.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
const TOP_LEVEL_COMMANDS = [
|
|
2
|
-
"init",
|
|
3
|
-
"start",
|
|
4
|
-
"stop",
|
|
5
|
-
"status",
|
|
6
|
-
"run",
|
|
7
|
-
"recover",
|
|
8
|
-
"logs",
|
|
9
|
-
"project",
|
|
10
|
-
"repo",
|
|
11
|
-
"config",
|
|
12
|
-
"completion",
|
|
13
|
-
"help",
|
|
14
|
-
"version",
|
|
15
|
-
];
|
|
16
|
-
const GLOBAL_OPTIONS = [
|
|
17
|
-
"--config",
|
|
18
|
-
"--config-dir",
|
|
19
|
-
"--verbose",
|
|
20
|
-
"-v",
|
|
21
|
-
"--json",
|
|
22
|
-
"--no-color",
|
|
23
|
-
"--help",
|
|
24
|
-
"-h",
|
|
25
|
-
"--version",
|
|
26
|
-
"-V",
|
|
27
|
-
];
|
|
28
|
-
const GLOBAL_OPTIONS_WITH_VALUES = ["--config", "--config-dir"];
|
|
29
|
-
const COMMAND_OPTIONS = {
|
|
30
|
-
completion: ["bash", "zsh", "fish"],
|
|
31
|
-
start: ["--project-id", "--project", "--daemon", "-d", ...GLOBAL_OPTIONS],
|
|
32
|
-
stop: ["--project-id", "--project", "--force", ...GLOBAL_OPTIONS],
|
|
33
|
-
status: ["--project-id", "--project", "--watch", "-w", ...GLOBAL_OPTIONS],
|
|
34
|
-
run: ["--project-id", "--project", "--watch", "-w", ...GLOBAL_OPTIONS],
|
|
35
|
-
recover: ["--project-id", "--project", "--dry-run", ...GLOBAL_OPTIONS],
|
|
36
|
-
logs: [
|
|
37
|
-
"--project-id",
|
|
38
|
-
"--project",
|
|
39
|
-
"--follow",
|
|
40
|
-
"-f",
|
|
41
|
-
"--issue",
|
|
42
|
-
"--run",
|
|
43
|
-
"--level",
|
|
44
|
-
...GLOBAL_OPTIONS,
|
|
45
|
-
],
|
|
46
|
-
project: ["add", "list", "remove", "start", "stop", "switch", "status"],
|
|
47
|
-
"project:add": [
|
|
48
|
-
"--non-interactive",
|
|
49
|
-
"--project",
|
|
50
|
-
"--workspace-dir",
|
|
51
|
-
"--assigned-only",
|
|
52
|
-
...GLOBAL_OPTIONS,
|
|
53
|
-
],
|
|
54
|
-
"project:list": [...GLOBAL_OPTIONS],
|
|
55
|
-
"project:remove": [...GLOBAL_OPTIONS],
|
|
56
|
-
"project:start": [
|
|
57
|
-
"--project-id",
|
|
58
|
-
"--project",
|
|
59
|
-
"--daemon",
|
|
60
|
-
"-d",
|
|
61
|
-
...GLOBAL_OPTIONS,
|
|
62
|
-
],
|
|
63
|
-
"project:stop": ["--project-id", "--project", "--force", ...GLOBAL_OPTIONS],
|
|
64
|
-
"project:switch": [...GLOBAL_OPTIONS],
|
|
65
|
-
"project:status": [
|
|
66
|
-
"--project-id",
|
|
67
|
-
"--project",
|
|
68
|
-
"--watch",
|
|
69
|
-
"-w",
|
|
70
|
-
...GLOBAL_OPTIONS,
|
|
71
|
-
],
|
|
72
|
-
repo: ["list", "add", "remove"],
|
|
73
|
-
"repo:list": [...GLOBAL_OPTIONS],
|
|
74
|
-
"repo:add": [...GLOBAL_OPTIONS],
|
|
75
|
-
"repo:remove": [...GLOBAL_OPTIONS],
|
|
76
|
-
config: ["show", "set", "edit"],
|
|
77
|
-
"config:show": [...GLOBAL_OPTIONS],
|
|
78
|
-
"config:set": [...GLOBAL_OPTIONS],
|
|
79
|
-
"config:edit": [...GLOBAL_OPTIONS],
|
|
80
|
-
};
|
|
81
|
-
function quoteWords(values) {
|
|
82
|
-
return values.join(" ");
|
|
83
|
-
}
|
|
84
|
-
function renderBashCasePatterns() {
|
|
85
|
-
return Object.entries(COMMAND_OPTIONS)
|
|
86
|
-
.map(([key, values]) => {
|
|
87
|
-
const [command, subcommand] = key.split(":");
|
|
88
|
-
if (!subcommand) {
|
|
89
|
-
if (command === "completion") {
|
|
90
|
-
return ` completion)\n COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )\n return\n ;;`;
|
|
91
|
-
}
|
|
92
|
-
if (command === "project" ||
|
|
93
|
-
command === "repo" ||
|
|
94
|
-
command === "config") {
|
|
95
|
-
return ` ${command})\n COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )\n return\n ;;`;
|
|
96
|
-
}
|
|
97
|
-
return ` ${command})\n COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )\n return\n ;;`;
|
|
98
|
-
}
|
|
99
|
-
return ` ${command}:${subcommand})\n COMPREPLY=( $(compgen -W "${quoteWords(values)}" -- "$cur") )\n return\n ;;`;
|
|
100
|
-
})
|
|
101
|
-
.join("\n");
|
|
102
|
-
}
|
|
103
|
-
function renderFishLines() {
|
|
104
|
-
const lines = GLOBAL_OPTIONS.map((option) => option.startsWith("--")
|
|
105
|
-
? `complete -c gh-symphony -f -l ${option.slice(2)}`
|
|
106
|
-
: `complete -c gh-symphony -f -s ${option.slice(1)}`);
|
|
107
|
-
for (const command of TOP_LEVEL_COMMANDS) {
|
|
108
|
-
lines.push(`complete -c gh-symphony -f -n '__fish_use_subcommand' -a '${command}'`);
|
|
109
|
-
}
|
|
110
|
-
for (const subcommand of COMMAND_OPTIONS.project ?? []) {
|
|
111
|
-
lines.push(`complete -c gh-symphony -f -n '__fish_seen_subcommand_from project' -a '${subcommand}'`);
|
|
112
|
-
}
|
|
113
|
-
for (const subcommand of COMMAND_OPTIONS.repo ?? []) {
|
|
114
|
-
lines.push(`complete -c gh-symphony -f -n '__fish_seen_subcommand_from repo' -a '${subcommand}'`);
|
|
115
|
-
}
|
|
116
|
-
for (const subcommand of COMMAND_OPTIONS.config ?? []) {
|
|
117
|
-
lines.push(`complete -c gh-symphony -f -n '__fish_seen_subcommand_from config' -a '${subcommand}'`);
|
|
118
|
-
}
|
|
119
|
-
for (const shell of COMMAND_OPTIONS.completion ?? []) {
|
|
120
|
-
lines.push(`complete -c gh-symphony -f -n '__fish_seen_subcommand_from completion' -a '${shell}'`);
|
|
121
|
-
}
|
|
122
|
-
return lines.join("\n");
|
|
123
|
-
}
|
|
124
|
-
export function renderCompletionScript(shell) {
|
|
125
|
-
if (shell === "fish") {
|
|
126
|
-
return `${renderFishLines()}\n`;
|
|
127
|
-
}
|
|
128
|
-
const bashFunction = `# shellcheck shell=bash
|
|
129
|
-
_gh_symphony_find_context() {
|
|
130
|
-
GH_SYMPHONY_COMMAND=""
|
|
131
|
-
GH_SYMPHONY_SUBCOMMAND=""
|
|
132
|
-
|
|
133
|
-
local idx=1
|
|
134
|
-
local token=""
|
|
135
|
-
local expects_value=0
|
|
136
|
-
|
|
137
|
-
while (( idx < COMP_CWORD )); do
|
|
138
|
-
token="\${COMP_WORDS[idx]}"
|
|
139
|
-
|
|
140
|
-
if (( expects_value )); then
|
|
141
|
-
expects_value=0
|
|
142
|
-
(( idx++ ))
|
|
143
|
-
continue
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
case "\${token}" in
|
|
147
|
-
${GLOBAL_OPTIONS_WITH_VALUES.map((option) => `${option}`).join("|")})
|
|
148
|
-
expects_value=1
|
|
149
|
-
;;
|
|
150
|
-
${GLOBAL_OPTIONS_WITH_VALUES.map((option) => `${option}=*`).join("|")})
|
|
151
|
-
;;
|
|
152
|
-
${GLOBAL_OPTIONS.filter((option) => !GLOBAL_OPTIONS_WITH_VALUES.includes(option)).join("|")})
|
|
153
|
-
;;
|
|
154
|
-
-*)
|
|
155
|
-
;;
|
|
156
|
-
*)
|
|
157
|
-
if [[ -z "\${GH_SYMPHONY_COMMAND}" ]]; then
|
|
158
|
-
GH_SYMPHONY_COMMAND="\${token}"
|
|
159
|
-
elif [[ -z "\${GH_SYMPHONY_SUBCOMMAND}" ]]; then
|
|
160
|
-
GH_SYMPHONY_SUBCOMMAND="\${token}"
|
|
161
|
-
fi
|
|
162
|
-
;;
|
|
163
|
-
esac
|
|
164
|
-
|
|
165
|
-
(( idx++ ))
|
|
166
|
-
done
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
_gh_symphony_completion() {
|
|
170
|
-
local cur prev path
|
|
171
|
-
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
172
|
-
prev=""
|
|
173
|
-
if (( COMP_CWORD > 0 )); then
|
|
174
|
-
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
_gh_symphony_find_context
|
|
178
|
-
path="\${GH_SYMPHONY_COMMAND}"
|
|
179
|
-
|
|
180
|
-
if [[ -z "\${path}" ]]; then
|
|
181
|
-
COMPREPLY=( $(compgen -W "${quoteWords(TOP_LEVEL_COMMANDS)} ${quoteWords(GLOBAL_OPTIONS)}" -- "$cur") )
|
|
182
|
-
return
|
|
183
|
-
fi
|
|
184
|
-
|
|
185
|
-
if [[ "\${path}" == "project" || "\${path}" == "repo" || "\${path}" == "config" || "\${path}" == "completion" ]]; then
|
|
186
|
-
if [[ -n "\${GH_SYMPHONY_SUBCOMMAND}" ]]; then
|
|
187
|
-
path="\${path}:\${GH_SYMPHONY_SUBCOMMAND}"
|
|
188
|
-
fi
|
|
189
|
-
fi
|
|
190
|
-
|
|
191
|
-
case "\${path}" in
|
|
192
|
-
${renderBashCasePatterns()}
|
|
193
|
-
esac
|
|
194
|
-
}
|
|
195
|
-
`;
|
|
196
|
-
if (shell === "zsh") {
|
|
197
|
-
return `autoload -Uz compinit && compinit
|
|
198
|
-
autoload -U +X bashcompinit && bashcompinit
|
|
199
|
-
${bashFunction}complete -F _gh_symphony_completion gh-symphony
|
|
200
|
-
`;
|
|
201
|
-
}
|
|
202
|
-
return `${bashFunction}complete -F _gh_symphony_completion gh-symphony
|
|
203
|
-
`;
|
|
204
|
-
}
|
package/dist/config.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { OrchestratorProjectConfig } from "@gh-symphony/core";
|
|
2
|
-
export declare const DEFAULT_CONFIG_DIR: string;
|
|
3
|
-
export declare const CONFIG_FILE = "config.json";
|
|
4
|
-
export declare const DAEMON_PID_FILE = "daemon.pid";
|
|
5
|
-
export declare const ORCHESTRATOR_LOG_FILE = "orchestrator.log";
|
|
6
|
-
export declare const ORCHESTRATOR_PORT_FILE = "port";
|
|
7
|
-
export type CliGlobalConfig = {
|
|
8
|
-
activeProject: string | null;
|
|
9
|
-
projects: string[];
|
|
10
|
-
};
|
|
11
|
-
export type CliProjectTrackerSettings = Record<string, string | number | boolean> & {
|
|
12
|
-
projectId?: string;
|
|
13
|
-
assignedOnly?: boolean;
|
|
14
|
-
timeoutMs?: number;
|
|
15
|
-
};
|
|
16
|
-
export type CliProjectConfig = Omit<OrchestratorProjectConfig, "tracker"> & {
|
|
17
|
-
displayName?: string;
|
|
18
|
-
tracker: Omit<OrchestratorProjectConfig["tracker"], "settings"> & {
|
|
19
|
-
settings?: CliProjectTrackerSettings;
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
export type StateRole = "active" | "wait" | "terminal";
|
|
23
|
-
export type StateMapping = {
|
|
24
|
-
role: StateRole;
|
|
25
|
-
goal?: string;
|
|
26
|
-
};
|
|
27
|
-
export declare function resolveConfigDir(override?: string): string;
|
|
28
|
-
export declare function configFilePath(configDir: string): string;
|
|
29
|
-
export declare function projectConfigDir(configDir: string, projectId: string): string;
|
|
30
|
-
export declare function projectConfigPath(configDir: string, projectId: string): string;
|
|
31
|
-
export declare function daemonPidPath(configDir: string, projectId: string): string;
|
|
32
|
-
export declare function orchestratorLogPath(configDir: string, projectId: string): string;
|
|
33
|
-
export declare function orchestratorPortPath(configDir: string, projectId: string): string;
|
|
34
|
-
export declare function loadGlobalConfig(configDir: string): Promise<CliGlobalConfig | null>;
|
|
35
|
-
export declare function saveGlobalConfig(configDir: string, config: CliGlobalConfig): Promise<void>;
|
|
36
|
-
export declare function loadProjectConfig(configDir: string, projectId: string): Promise<CliProjectConfig | null>;
|
|
37
|
-
export declare function saveProjectConfig(configDir: string, projectId: string, config: CliProjectConfig): Promise<void>;
|
|
38
|
-
export declare function loadActiveProjectConfig(configDir: string): Promise<CliProjectConfig | null>;
|