@rigkit/cli 0.2.9 → 0.2.10
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/package.json +4 -4
- package/src/cli.test.ts +106 -1
- package/src/cli.ts +18 -0
- package/src/completion.test.ts +263 -8
- package/src/completion.ts +828 -339
- package/src/update-check.ts +224 -0
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigkit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"chalk": "^5.6.2",
|
|
23
23
|
"commander": "^14.0.3",
|
|
24
24
|
"inquirer": "^13.4.3",
|
|
25
|
-
"@rigkit/
|
|
26
|
-
"@rigkit/
|
|
27
|
-
"@rigkit/runtime-client": "0.2.
|
|
25
|
+
"@rigkit/provider-cmux": "0.2.10",
|
|
26
|
+
"@rigkit/engine": "0.2.10",
|
|
27
|
+
"@rigkit/runtime-client": "0.2.10"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/bun": "latest",
|
package/src/cli.test.ts
CHANGED
|
@@ -43,6 +43,76 @@ describe("CLI entrypoint", () => {
|
|
|
43
43
|
expect(help.stdout).toContain("cache Inspect and clear Rigkit cache");
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
+
test("prints an update notice when latest metadata is newer", async () => {
|
|
47
|
+
const rigkitHome = mkdtempSync(join(tmpdir(), "rigkit-cli-update-"));
|
|
48
|
+
const latestVersion = nextPatchVersion(RIGKIT_CLI_VERSION);
|
|
49
|
+
const server = Bun.serve({
|
|
50
|
+
hostname: "127.0.0.1",
|
|
51
|
+
port: 0,
|
|
52
|
+
fetch() {
|
|
53
|
+
return Response.json({
|
|
54
|
+
version: latestVersion,
|
|
55
|
+
installerUrl: "https://www.rigkit.dev/install",
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const result = await runCli(["doctor", "--cli"], {
|
|
62
|
+
env: {
|
|
63
|
+
RIGKIT_HOME: rigkitHome,
|
|
64
|
+
RIGKIT_UPDATE_CHECK: "1",
|
|
65
|
+
RIGKIT_UPDATE_TIMEOUT_MS: "2000",
|
|
66
|
+
RIGKIT_UPDATE_URL: `http://127.0.0.1:${server.port}/latest.json`,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(result.exitCode).toBe(0);
|
|
71
|
+
expect(result.stdout).toContain(RIGKIT_CLI_VERSION);
|
|
72
|
+
expect(result.stderr).toContain(`rig ${latestVersion} is available`);
|
|
73
|
+
expect(result.stderr).toContain("update with: curl -fsSL https://www.rigkit.dev/install | sh");
|
|
74
|
+
} finally {
|
|
75
|
+
server.stop(true);
|
|
76
|
+
rmSync(rigkitHome, { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("does not print update notices for JSON output", async () => {
|
|
81
|
+
const rigkitHome = mkdtempSync(join(tmpdir(), "rigkit-cli-update-json-"));
|
|
82
|
+
let requests = 0;
|
|
83
|
+
const server = Bun.serve({
|
|
84
|
+
hostname: "127.0.0.1",
|
|
85
|
+
port: 0,
|
|
86
|
+
fetch() {
|
|
87
|
+
requests += 1;
|
|
88
|
+
return Response.json({
|
|
89
|
+
version: nextPatchVersion(RIGKIT_CLI_VERSION),
|
|
90
|
+
installerUrl: "https://www.rigkit.dev/install",
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const result = await runCli(["doctor", "--cli", "--json"], {
|
|
97
|
+
env: {
|
|
98
|
+
RIGKIT_HOME: rigkitHome,
|
|
99
|
+
RIGKIT_UPDATE_CHECK: "1",
|
|
100
|
+
RIGKIT_UPDATE_URL: `http://127.0.0.1:${server.port}/latest.json`,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
expect(result.exitCode).toBe(0);
|
|
105
|
+
expect(result.stderr).toBe("");
|
|
106
|
+
expect(JSON.parse(result.stdout)).toMatchObject({
|
|
107
|
+
cliVersion: RIGKIT_CLI_VERSION,
|
|
108
|
+
});
|
|
109
|
+
expect(requests).toBe(0);
|
|
110
|
+
} finally {
|
|
111
|
+
server.stop(true);
|
|
112
|
+
rmSync(rigkitHome, { recursive: true, force: true });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
46
116
|
test("rejects operation shorthand at the root", async () => {
|
|
47
117
|
const result = await runCli(["unknown"]);
|
|
48
118
|
|
|
@@ -124,6 +194,31 @@ describe("CLI entrypoint", () => {
|
|
|
124
194
|
}
|
|
125
195
|
});
|
|
126
196
|
|
|
197
|
+
test("does not render a success marker when cache invalidation is a no-op", async () => {
|
|
198
|
+
const projectDir = mkdtempSync(join(tmpdir(), "rigkit-cli-cache-invalidate-"));
|
|
199
|
+
|
|
200
|
+
await withWorkspaceRuntime({ projectDir, cacheInvalidated: 0 }, async ({ env }) => {
|
|
201
|
+
const result = await runCli([`-chdir=${projectDir}`, "cache", "invalidate", "missing-task"], { env });
|
|
202
|
+
|
|
203
|
+
expect(result.exitCode).toBe(0);
|
|
204
|
+
expect(result.stderr).toBe("");
|
|
205
|
+
expect(result.stdout.trim()).toBe("no cache entries invalidated");
|
|
206
|
+
expect(result.stdout).not.toContain("✓");
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("preserves JSON output for zero cache invalidations", async () => {
|
|
211
|
+
const projectDir = mkdtempSync(join(tmpdir(), "rigkit-cli-cache-invalidate-json-"));
|
|
212
|
+
|
|
213
|
+
await withWorkspaceRuntime({ projectDir, cacheInvalidated: 0 }, async ({ env }) => {
|
|
214
|
+
const result = await runCli([`-chdir=${projectDir}`, "cache", "invalidate", "missing-task", "--json"], { env });
|
|
215
|
+
|
|
216
|
+
expect(result.exitCode).toBe(0);
|
|
217
|
+
expect(result.stderr).toBe("");
|
|
218
|
+
expect(JSON.parse(result.stdout)).toEqual({ ok: true, invalidated: 0 });
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
127
222
|
test("lists workspaces from the project runtime", async () => {
|
|
128
223
|
const projectDir = mkdtempSync(join(tmpdir(), "rigkit-cli-ls-"));
|
|
129
224
|
|
|
@@ -241,6 +336,7 @@ async function runCli(
|
|
|
241
336
|
stderr: "pipe",
|
|
242
337
|
env: {
|
|
243
338
|
...process.env,
|
|
339
|
+
RIGKIT_UPDATE_CHECK: "0",
|
|
244
340
|
...options.env,
|
|
245
341
|
FORCE_COLOR: "0",
|
|
246
342
|
NO_COLOR: "1",
|
|
@@ -255,8 +351,14 @@ async function runCli(
|
|
|
255
351
|
return { exitCode, stdout, stderr };
|
|
256
352
|
}
|
|
257
353
|
|
|
354
|
+
function nextPatchVersion(version: string): string {
|
|
355
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
356
|
+
if (!match) return "999.0.0";
|
|
357
|
+
return `${match[1]}.${match[2]}.${Number(match[3]) + 1}`;
|
|
358
|
+
}
|
|
359
|
+
|
|
258
360
|
async function withWorkspaceRuntime(
|
|
259
|
-
input: { projectDir: string },
|
|
361
|
+
input: { projectDir: string; cacheInvalidated?: number },
|
|
260
362
|
run: (context: { env: Record<string, string> }) => Promise<void>,
|
|
261
363
|
): Promise<void> {
|
|
262
364
|
const rigkitHome = mkdtempSync(join(tmpdir(), "rigkit-home-"));
|
|
@@ -306,6 +408,9 @@ async function withWorkspaceRuntime(
|
|
|
306
408
|
}],
|
|
307
409
|
});
|
|
308
410
|
}
|
|
411
|
+
if (pathname === "/cache/invalidate") {
|
|
412
|
+
return runtimeJson({ ok: true, invalidated: input.cacheInvalidated ?? 1 });
|
|
413
|
+
}
|
|
309
414
|
if (pathname === "/operations") {
|
|
310
415
|
return runtimeJson({
|
|
311
416
|
operations: [{
|
package/src/cli.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { initProject, normalizeMachineName, type InitProjectResult } from "./ini
|
|
|
25
25
|
import { openExternalTarget } from "./interaction.ts";
|
|
26
26
|
import { createRunPresenter, type RunPresenter } from "./run-presenter.ts";
|
|
27
27
|
import { createRunLogger, type RunLogger } from "./run-logger.ts";
|
|
28
|
+
import { maybePrintUpdateNotice } from "./update-check.ts";
|
|
28
29
|
import {
|
|
29
30
|
completeRig,
|
|
30
31
|
formatCompletionItems,
|
|
@@ -220,6 +221,14 @@ async function runCli(argv: string[]): Promise<void> {
|
|
|
220
221
|
await runHelp(makeInvocation(rootOptions(program)));
|
|
221
222
|
});
|
|
222
223
|
|
|
224
|
+
program.hook("postAction", async (_thisCommand, actionCommand) => {
|
|
225
|
+
await maybePrintUpdateNotice({
|
|
226
|
+
commandName: actionCommand.name(),
|
|
227
|
+
currentVersion: RIGKIT_CLI_VERSION,
|
|
228
|
+
json: commandWantsJson(program, actionCommand),
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
223
232
|
program
|
|
224
233
|
.command("init")
|
|
225
234
|
.description("Initialize a Rigkit project")
|
|
@@ -408,6 +417,11 @@ function rootOptions(program: Command): GlobalOptions {
|
|
|
408
417
|
};
|
|
409
418
|
}
|
|
410
419
|
|
|
420
|
+
function commandWantsJson(program: Command, actionCommand: Command): boolean {
|
|
421
|
+
const options = actionCommand.opts<{ json?: boolean }>();
|
|
422
|
+
return Boolean(rootOptions(program).json || options.json);
|
|
423
|
+
}
|
|
424
|
+
|
|
411
425
|
function parsePackageManagerOption(value: string | undefined): PackageManager | undefined {
|
|
412
426
|
if (value === undefined) return undefined;
|
|
413
427
|
if (isPackageManager(value)) return value;
|
|
@@ -1144,6 +1158,10 @@ async function runCacheInvalidate(invocation: CliInvocation, options: CacheInval
|
|
|
1144
1158
|
printJson(result);
|
|
1145
1159
|
return;
|
|
1146
1160
|
}
|
|
1161
|
+
if (result.invalidated === 0) {
|
|
1162
|
+
console.log(ui.dim("no cache entries invalidated"));
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1147
1165
|
console.log(
|
|
1148
1166
|
`${ui.ok(ui.sym.ok)} invalidated ${result.invalidated} cache ${result.invalidated === 1 ? "entry" : "entries"}`,
|
|
1149
1167
|
);
|
package/src/completion.test.ts
CHANGED
|
@@ -15,7 +15,7 @@ describe("CLI completion", () => {
|
|
|
15
15
|
currentIndex: 2,
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
expect(items.map((item) => item.value)).toEqual(["api", "web"]);
|
|
18
|
+
expect(items.map((item) => item.value)).toEqual(["api", "web", "--json", "--help"]);
|
|
19
19
|
expect(items[0]?.description).toBe("created 2h ago");
|
|
20
20
|
});
|
|
21
21
|
});
|
|
@@ -43,7 +43,7 @@ describe("CLI completion", () => {
|
|
|
43
43
|
currentIndex: 3,
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
-
expect(items.map((item) => item.value)).toEqual(["api", "web"]);
|
|
46
|
+
expect(items.map((item) => item.value)).toEqual(["api", "web", "--json", "--help"]);
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -128,7 +128,7 @@ describe("CLI completion", () => {
|
|
|
128
128
|
words: ["rig", "run", ""],
|
|
129
129
|
currentIndex: 2,
|
|
130
130
|
});
|
|
131
|
-
expect(roots.map((item) => item.value)).toEqual(["api", "web"]);
|
|
131
|
+
expect(roots.map((item) => item.value)).toEqual(["api", "web", "--json", "--help"]);
|
|
132
132
|
expect(roots[0]).toMatchObject({ description: "created 2h ago" });
|
|
133
133
|
|
|
134
134
|
const exactWorkspace = await completeRig({
|
|
@@ -143,7 +143,7 @@ describe("CLI completion", () => {
|
|
|
143
143
|
words: ["rig", "run", "api", ""],
|
|
144
144
|
currentIndex: 3,
|
|
145
145
|
});
|
|
146
|
-
expect(workspaceAfterSpace.map((item) => item.value)).toEqual(["remove", "open-cmux"]);
|
|
146
|
+
expect(workspaceAfterSpace.map((item) => item.value)).toEqual(["remove", "open-cmux", "--json", "--help"]);
|
|
147
147
|
|
|
148
148
|
const operationPrefix = await completeRig({
|
|
149
149
|
cwd: projectDir,
|
|
@@ -162,7 +162,7 @@ describe("CLI completion", () => {
|
|
|
162
162
|
words: ["rig", "rm", ""],
|
|
163
163
|
currentIndex: 2,
|
|
164
164
|
});
|
|
165
|
-
expect(workspaces.map((item) => item.value)).toEqual(["api", "web"]);
|
|
165
|
+
expect(workspaces.map((item) => item.value)).toEqual(["api", "web", "-y", "--yes", "--all", "--json", "--help"]);
|
|
166
166
|
|
|
167
167
|
const flags = await completeRig({
|
|
168
168
|
cwd: projectDir,
|
|
@@ -204,7 +204,7 @@ describe("CLI completion", () => {
|
|
|
204
204
|
currentIndex: 2,
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
-
expect(subcommands.map((item) => item.value)).toEqual(["ls", "clear"]);
|
|
207
|
+
expect(subcommands.map((item) => item.value)).toEqual(["ls", "clear", "invalidate"]);
|
|
208
208
|
|
|
209
209
|
const clearFlags = await completeRig({
|
|
210
210
|
cwd: process.cwd(),
|
|
@@ -217,9 +217,129 @@ describe("CLI completion", () => {
|
|
|
217
217
|
"--global",
|
|
218
218
|
"--all",
|
|
219
219
|
"--json",
|
|
220
|
+
"--help",
|
|
220
221
|
]);
|
|
221
222
|
});
|
|
222
223
|
|
|
224
|
+
test("completes project operation flags and workflow values", async () => {
|
|
225
|
+
const projectDir = mkdtempSync(join(tmpdir(), "rigkit-completion-"));
|
|
226
|
+
await withWorkspaceRuntime({ projectDir }, async () => {
|
|
227
|
+
const flags = await completeRig({
|
|
228
|
+
cwd: projectDir,
|
|
229
|
+
words: ["rig", "apply", "--"],
|
|
230
|
+
currentIndex: 2,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
expect(flags.map((item) => item.value)).toEqual([
|
|
234
|
+
"--workflow",
|
|
235
|
+
"--dry-run",
|
|
236
|
+
"--all",
|
|
237
|
+
"--discover",
|
|
238
|
+
"--json",
|
|
239
|
+
"--help",
|
|
240
|
+
]);
|
|
241
|
+
|
|
242
|
+
const workflowValues = await completeRig({
|
|
243
|
+
cwd: projectDir,
|
|
244
|
+
words: ["rig", "apply", "--workflow", ""],
|
|
245
|
+
currentIndex: 3,
|
|
246
|
+
});
|
|
247
|
+
expect(workflowValues.map((item) => item.value)).toEqual(["smoke", "api"]);
|
|
248
|
+
|
|
249
|
+
const inlineWorkflow = await completeRig({
|
|
250
|
+
cwd: projectDir,
|
|
251
|
+
words: ["rig", "apply", "--workflow=s"],
|
|
252
|
+
currentIndex: 2,
|
|
253
|
+
});
|
|
254
|
+
expect(inlineWorkflow.map((item) => item.value)).toEqual(["--workflow=smoke"]);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("completes workspace operation flags and enum values", async () => {
|
|
259
|
+
const projectDir = mkdtempSync(join(tmpdir(), "rigkit-completion-"));
|
|
260
|
+
await withWorkspaceRuntime({ projectDir }, async () => {
|
|
261
|
+
const flags = await completeRig({
|
|
262
|
+
cwd: projectDir,
|
|
263
|
+
words: ["rig", "run", "api", "open-cmux", "--"],
|
|
264
|
+
currentIndex: 4,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
expect(flags.map((item) => item.value)).toEqual(["--layout", "--json", "--help"]);
|
|
268
|
+
|
|
269
|
+
const values = await completeRig({
|
|
270
|
+
cwd: projectDir,
|
|
271
|
+
words: ["rig", "run", "api", "open-cmux", "--layout", ""],
|
|
272
|
+
currentIndex: 5,
|
|
273
|
+
});
|
|
274
|
+
expect(values.map((item) => item.value)).toEqual(["tabs", "splits"]);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
test("completes cache invalidate targets and flags", async () => {
|
|
279
|
+
const projectDir = mkdtempSync(join(tmpdir(), "rigkit-completion-"));
|
|
280
|
+
await withWorkspaceRuntime({ projectDir }, async () => {
|
|
281
|
+
const targets = await completeRig({
|
|
282
|
+
cwd: projectDir,
|
|
283
|
+
words: ["rig", "cache", "invalidate", ""],
|
|
284
|
+
currentIndex: 3,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
expect(targets.map((item) => item.value)).toEqual([
|
|
288
|
+
"install-tooling",
|
|
289
|
+
"build",
|
|
290
|
+
"--all",
|
|
291
|
+
"-y",
|
|
292
|
+
"--yes",
|
|
293
|
+
"--json",
|
|
294
|
+
"--help",
|
|
295
|
+
]);
|
|
296
|
+
|
|
297
|
+
const flags = await completeRig({
|
|
298
|
+
cwd: projectDir,
|
|
299
|
+
words: ["rig", "cache", "invalidate", "--"],
|
|
300
|
+
currentIndex: 3,
|
|
301
|
+
});
|
|
302
|
+
expect(flags.map((item) => item.value)).toEqual(["--all", "--yes", "--json", "--help"]);
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
test("completes static command flags and option values", async () => {
|
|
307
|
+
const initFlags = await completeRig({
|
|
308
|
+
cwd: process.cwd(),
|
|
309
|
+
words: ["rig", "init", "--"],
|
|
310
|
+
currentIndex: 2,
|
|
311
|
+
});
|
|
312
|
+
expect(initFlags.map((item) => item.value)).toEqual([
|
|
313
|
+
"--name",
|
|
314
|
+
"--api-key",
|
|
315
|
+
"--package-manager",
|
|
316
|
+
"--force",
|
|
317
|
+
"--json",
|
|
318
|
+
"--help",
|
|
319
|
+
]);
|
|
320
|
+
|
|
321
|
+
const packageManagers = await completeRig({
|
|
322
|
+
cwd: process.cwd(),
|
|
323
|
+
words: ["rig", "init", "--package-manager", "p"],
|
|
324
|
+
currentIndex: 3,
|
|
325
|
+
});
|
|
326
|
+
expect(packageManagers.map((item) => item.value)).toEqual(["pnpm"]);
|
|
327
|
+
|
|
328
|
+
const doctorFlags = await completeRig({
|
|
329
|
+
cwd: process.cwd(),
|
|
330
|
+
words: ["rig", "doctor", "--"],
|
|
331
|
+
currentIndex: 2,
|
|
332
|
+
});
|
|
333
|
+
expect(doctorFlags.map((item) => item.value)).toEqual(["--cli", "--json", "--help"]);
|
|
334
|
+
|
|
335
|
+
const completionShells = await completeRig({
|
|
336
|
+
cwd: process.cwd(),
|
|
337
|
+
words: ["rig", "completion", ""],
|
|
338
|
+
currentIndex: 2,
|
|
339
|
+
});
|
|
340
|
+
expect(completionShells.map((item) => item.value)).toEqual(["bash", "fish", "zsh", "--help"]);
|
|
341
|
+
});
|
|
342
|
+
|
|
223
343
|
test("formats shell completion items", () => {
|
|
224
344
|
const items = [{ value: "api", description: "vm-api" }];
|
|
225
345
|
|
|
@@ -254,7 +374,7 @@ describe("CLI completion", () => {
|
|
|
254
374
|
currentIndex: 2,
|
|
255
375
|
});
|
|
256
376
|
|
|
257
|
-
expect(items.map((item) => item.value)).toEqual(["workspaces", "snapshots", "config", "--json"]);
|
|
377
|
+
expect(items.map((item) => item.value)).toEqual(["workspaces", "snapshots", "config", "--json", "--help"]);
|
|
258
378
|
});
|
|
259
379
|
});
|
|
260
380
|
|
|
@@ -321,9 +441,139 @@ async function withWorkspaceRuntime(
|
|
|
321
441
|
],
|
|
322
442
|
});
|
|
323
443
|
}
|
|
444
|
+
if (pathname === "/workflows") {
|
|
445
|
+
return runtimeJson({
|
|
446
|
+
workflows: [
|
|
447
|
+
{
|
|
448
|
+
name: "smoke",
|
|
449
|
+
providers: [],
|
|
450
|
+
nodes: ["install-tooling", "build"],
|
|
451
|
+
operations: ["plan", "apply", "create"],
|
|
452
|
+
createsWorkspace: true,
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: "api",
|
|
456
|
+
providers: [],
|
|
457
|
+
nodes: ["install-tooling"],
|
|
458
|
+
operations: ["plan", "apply"],
|
|
459
|
+
createsWorkspace: false,
|
|
460
|
+
},
|
|
461
|
+
],
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
if (pathname === "/cache") {
|
|
465
|
+
const nowMs = Date.now();
|
|
466
|
+
return runtimeJson({
|
|
467
|
+
entries: [
|
|
468
|
+
{
|
|
469
|
+
scope: "local",
|
|
470
|
+
workflow: "smoke",
|
|
471
|
+
nodePath: "install-tooling",
|
|
472
|
+
nodeName: "install-tooling",
|
|
473
|
+
nodeKind: "task",
|
|
474
|
+
runId: "run-install",
|
|
475
|
+
invalidated: false,
|
|
476
|
+
createdAt: new Date(nowMs - 60_000).toISOString(),
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
scope: "local",
|
|
480
|
+
workflow: "smoke",
|
|
481
|
+
nodePath: "build",
|
|
482
|
+
nodeName: "build",
|
|
483
|
+
nodeKind: "task",
|
|
484
|
+
runId: "run-build",
|
|
485
|
+
invalidated: false,
|
|
486
|
+
createdAt: new Date(nowMs - 30_000).toISOString(),
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
scope: "local",
|
|
490
|
+
workflow: "smoke",
|
|
491
|
+
nodePath: "old-task",
|
|
492
|
+
nodeName: "old-task",
|
|
493
|
+
nodeKind: "task",
|
|
494
|
+
runId: "run-old",
|
|
495
|
+
invalidated: true,
|
|
496
|
+
createdAt: new Date(nowMs - 10_000).toISOString(),
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
scope: "global",
|
|
500
|
+
workflow: "smoke",
|
|
501
|
+
nodePath: "base",
|
|
502
|
+
nodeName: "base",
|
|
503
|
+
nodeKind: "task",
|
|
504
|
+
runId: "run-base",
|
|
505
|
+
invalidated: false,
|
|
506
|
+
createdAt: new Date(nowMs - 5_000).toISOString(),
|
|
507
|
+
fragmentHash: "fragment",
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
});
|
|
511
|
+
}
|
|
324
512
|
if (pathname === "/operations") {
|
|
325
513
|
return runtimeJson({
|
|
326
514
|
operations: [
|
|
515
|
+
{
|
|
516
|
+
id: "plan",
|
|
517
|
+
kind: "command",
|
|
518
|
+
source: "core",
|
|
519
|
+
title: "Plan",
|
|
520
|
+
description: "Show cached and pending steps",
|
|
521
|
+
cli: {
|
|
522
|
+
options: [{ name: "workflow", flag: "--workflow" }],
|
|
523
|
+
},
|
|
524
|
+
inputSchema: {
|
|
525
|
+
type: "object",
|
|
526
|
+
additionalProperties: false,
|
|
527
|
+
properties: {
|
|
528
|
+
workflow: { type: "string", enum: ["smoke", "api"] },
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
id: "apply",
|
|
534
|
+
kind: "command",
|
|
535
|
+
source: "core",
|
|
536
|
+
title: "Apply",
|
|
537
|
+
description: "Resolve the workflow",
|
|
538
|
+
cli: {
|
|
539
|
+
options: [
|
|
540
|
+
{ name: "workflow", flag: "--workflow" },
|
|
541
|
+
{ name: "dryRun", flag: "--dry-run", type: "boolean" },
|
|
542
|
+
],
|
|
543
|
+
},
|
|
544
|
+
inputSchema: {
|
|
545
|
+
type: "object",
|
|
546
|
+
additionalProperties: false,
|
|
547
|
+
properties: {
|
|
548
|
+
workflow: { type: "string", enum: ["smoke", "api"] },
|
|
549
|
+
dryRun: { type: "boolean" },
|
|
550
|
+
},
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
id: "create",
|
|
555
|
+
kind: "command",
|
|
556
|
+
source: "core",
|
|
557
|
+
title: "Create",
|
|
558
|
+
description: "Create a workspace",
|
|
559
|
+
createsWorkspace: true,
|
|
560
|
+
cli: {
|
|
561
|
+
positionals: [{ name: "name", index: 0 }],
|
|
562
|
+
options: [
|
|
563
|
+
{ name: "workflow", flag: "--workflow" },
|
|
564
|
+
{ name: "name", flag: "--name", required: true },
|
|
565
|
+
],
|
|
566
|
+
},
|
|
567
|
+
inputSchema: {
|
|
568
|
+
type: "object",
|
|
569
|
+
additionalProperties: false,
|
|
570
|
+
required: ["name"],
|
|
571
|
+
properties: {
|
|
572
|
+
workflow: { type: "string", enum: ["smoke", "api"] },
|
|
573
|
+
name: { type: "string" },
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
},
|
|
327
577
|
{
|
|
328
578
|
id: "ssh",
|
|
329
579
|
kind: "command",
|
|
@@ -365,10 +615,15 @@ async function withWorkspaceRuntime(
|
|
|
365
615
|
source: "config",
|
|
366
616
|
title: "Open cmux",
|
|
367
617
|
description: "open cmux",
|
|
618
|
+
cli: {
|
|
619
|
+
options: [{ name: "layout", flag: "--layout", type: "string" }],
|
|
620
|
+
},
|
|
368
621
|
inputSchema: {
|
|
369
622
|
type: "object",
|
|
370
623
|
additionalProperties: false,
|
|
371
|
-
properties: {
|
|
624
|
+
properties: {
|
|
625
|
+
layout: { type: "string", enum: ["tabs", "splits"] },
|
|
626
|
+
},
|
|
372
627
|
},
|
|
373
628
|
},
|
|
374
629
|
],
|