@gh-symphony/cli 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/chunk-5NV3LSAJ.js +11 -0
  2. package/dist/chunk-6HBZC3BE.js +468 -0
  3. package/dist/chunk-76QPITKI.js +109 -0
  4. package/dist/chunk-IWR4UQEJ.js +2250 -0
  5. package/dist/chunk-JO3AXHQI.js +130 -0
  6. package/dist/chunk-M7OSMUTN.js +874 -0
  7. package/dist/chunk-MVRF7BES.js +68 -0
  8. package/dist/chunk-RNWX7DQU.js +4617 -0
  9. package/dist/chunk-ROGRTUFI.js +108 -0
  10. package/dist/chunk-TH5QPO3Y.js +67 -0
  11. package/dist/config-cmd-AZ7POMAA.js +110 -0
  12. package/dist/index.d.ts +5 -4
  13. package/dist/index.js +568 -356
  14. package/dist/init-EZXQAXZM.js +17 -0
  15. package/dist/logs-6LNGT2GF.js +188 -0
  16. package/dist/project-3ELXQ35D.js +678 -0
  17. package/dist/recover-T6ME6C56.js +130 -0
  18. package/dist/repo-R3XBIVAX.js +121 -0
  19. package/dist/run-DYINRZHK.js +107 -0
  20. package/dist/start-PIFQMIC2.js +15 -0
  21. package/dist/status-3WK5BWRZ.js +11 -0
  22. package/dist/stop-AA3AP5M6.js +9 -0
  23. package/dist/version-VBB62JWI.js +30 -0
  24. package/package.json +9 -4
  25. package/dist/ansi.d.ts +0 -15
  26. package/dist/ansi.js +0 -53
  27. package/dist/commands/config-cmd.d.ts +0 -3
  28. package/dist/commands/config-cmd.js +0 -90
  29. package/dist/commands/help.d.ts +0 -3
  30. package/dist/commands/help.js +0 -55
  31. package/dist/commands/init.d.ts +0 -34
  32. package/dist/commands/init.js +0 -477
  33. package/dist/commands/logs.d.ts +0 -3
  34. package/dist/commands/logs.js +0 -184
  35. package/dist/commands/project.d.ts +0 -3
  36. package/dist/commands/project.js +0 -649
  37. package/dist/commands/recover.d.ts +0 -3
  38. package/dist/commands/recover.js +0 -119
  39. package/dist/commands/repo.d.ts +0 -3
  40. package/dist/commands/repo.js +0 -103
  41. package/dist/commands/run.d.ts +0 -3
  42. package/dist/commands/run.js +0 -95
  43. package/dist/commands/start.d.ts +0 -20
  44. package/dist/commands/start.js +0 -344
  45. package/dist/commands/status-refresh.d.ts +0 -9
  46. package/dist/commands/status-refresh.js +0 -27
  47. package/dist/commands/status.d.ts +0 -3
  48. package/dist/commands/status.js +0 -237
  49. package/dist/commands/stop.d.ts +0 -3
  50. package/dist/commands/stop.js +0 -92
  51. package/dist/commands/version.d.ts +0 -3
  52. package/dist/commands/version.js +0 -21
  53. package/dist/completion.d.ts +0 -1
  54. package/dist/completion.js +0 -204
  55. package/dist/config.d.ts +0 -38
  56. package/dist/config.js +0 -82
  57. package/dist/context/context-types.d.ts +0 -36
  58. package/dist/context/context-types.js +0 -1
  59. package/dist/context/generate-context-yaml.d.ts +0 -15
  60. package/dist/context/generate-context-yaml.js +0 -129
  61. package/dist/dashboard/renderer.d.ts +0 -9
  62. package/dist/dashboard/renderer.js +0 -220
  63. package/dist/detection/environment-detector.d.ts +0 -11
  64. package/dist/detection/environment-detector.js +0 -140
  65. package/dist/github/client.d.ts +0 -71
  66. package/dist/github/client.js +0 -348
  67. package/dist/github/gh-auth.d.ts +0 -34
  68. package/dist/github/gh-auth.js +0 -110
  69. package/dist/mapping/smart-defaults.d.ts +0 -17
  70. package/dist/mapping/smart-defaults.js +0 -86
  71. package/dist/orchestrator-runtime.d.ts +0 -1
  72. package/dist/orchestrator-runtime.js +0 -4
  73. package/dist/orchestrator-status-endpoint.d.ts +0 -5
  74. package/dist/orchestrator-status-endpoint.js +0 -27
  75. package/dist/project-selection.d.ts +0 -8
  76. package/dist/project-selection.js +0 -56
  77. package/dist/skills/skill-writer.d.ts +0 -14
  78. package/dist/skills/skill-writer.js +0 -62
  79. package/dist/skills/templates/commit.d.ts +0 -2
  80. package/dist/skills/templates/commit.js +0 -45
  81. package/dist/skills/templates/document.d.ts +0 -7
  82. package/dist/skills/templates/document.js +0 -16
  83. package/dist/skills/templates/gh-project.d.ts +0 -2
  84. package/dist/skills/templates/gh-project.js +0 -88
  85. package/dist/skills/templates/gh-symphony.d.ts +0 -2
  86. package/dist/skills/templates/gh-symphony.js +0 -125
  87. package/dist/skills/templates/index.d.ts +0 -8
  88. package/dist/skills/templates/index.js +0 -28
  89. package/dist/skills/templates/land.d.ts +0 -2
  90. package/dist/skills/templates/land.js +0 -59
  91. package/dist/skills/templates/pull.d.ts +0 -2
  92. package/dist/skills/templates/pull.js +0 -41
  93. package/dist/skills/templates/push.d.ts +0 -2
  94. package/dist/skills/templates/push.js +0 -36
  95. package/dist/skills/types.d.ts +0 -23
  96. package/dist/skills/types.js +0 -1
  97. package/dist/workflow/generate-reference-workflow.d.ts +0 -9
  98. package/dist/workflow/generate-reference-workflow.js +0 -261
  99. package/dist/workflow/generate-workflow-md.d.ts +0 -12
  100. package/dist/workflow/generate-workflow-md.js +0 -134
@@ -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
- }
@@ -1,3 +0,0 @@
1
- import type { GlobalOptions } from "../index.js";
2
- declare const handler: (args: string[], options: GlobalOptions) => Promise<void>;
3
- export default handler;
@@ -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;
@@ -1,3 +0,0 @@
1
- import type { GlobalOptions } from "../index.js";
2
- declare const handler: (args: string[], options: GlobalOptions) => Promise<void>;
3
- export default handler;
@@ -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;
@@ -1,3 +0,0 @@
1
- import type { GlobalOptions } from "../index.js";
2
- declare const handler: (_args: string[], options: GlobalOptions) => Promise<void>;
3
- export default handler;
@@ -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;
@@ -1 +0,0 @@
1
- export declare function renderCompletionScript(shell: "bash" | "zsh" | "fish"): string;
@@ -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>;