@h-rig/cli 0.0.6-alpha.27 → 0.0.6-alpha.29
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/bin/rig.js +1505 -907
- package/dist/src/commands/_cli-format.js +211 -6
- package/dist/src/commands/_connection-state.js +1 -3
- package/dist/src/commands/_doctor-checks.js +3 -5
- package/dist/src/commands/_help-catalog.js +251 -66
- package/dist/src/commands/_operator-view.js +1 -3
- package/dist/src/commands/_parsers.js +0 -2
- package/dist/src/commands/_pi-frontend.js +1 -3
- package/dist/src/commands/_pi-worker-bridge-extension.js +1 -3
- package/dist/src/commands/_policy.js +0 -2
- package/dist/src/commands/_preflight.js +2 -4
- package/dist/src/commands/_run-driver-helpers.js +0 -2
- package/dist/src/commands/_server-client.js +1 -3
- package/dist/src/commands/_snapshot-upload.js +1 -3
- package/dist/src/commands/agent.js +7 -9
- package/dist/src/commands/browser.js +4 -6
- package/dist/src/commands/connect.js +5 -6
- package/dist/src/commands/dist.js +4 -6
- package/dist/src/commands/doctor.js +3 -5
- package/dist/src/commands/github.js +1 -3
- package/dist/src/commands/inbox.js +351 -31
- package/dist/src/commands/init.js +3 -5
- package/dist/src/commands/inspect.js +10 -12
- package/dist/src/commands/inspector.js +2 -4
- package/dist/src/commands/plugin.js +76 -22
- package/dist/src/commands/profile-and-review.js +8 -10
- package/dist/src/commands/queue.js +1 -3
- package/dist/src/commands/remote.js +18 -20
- package/dist/src/commands/repo-git-harness.js +6 -8
- package/dist/src/commands/run.js +159 -41
- package/dist/src/commands/server.js +6 -7
- package/dist/src/commands/setup.js +7 -15
- package/dist/src/commands/task-report-bug.js +5 -7
- package/dist/src/commands/task-run-driver.js +1 -3
- package/dist/src/commands/task.js +483 -50
- package/dist/src/commands/test.js +3 -5
- package/dist/src/commands/workspace.js +4 -6
- package/dist/src/commands.js +1508 -901
- package/dist/src/index.js +1511 -916
- package/dist/src/report-bug.js +3 -3
- package/dist/src/runner.js +2 -17
- package/package.json +6 -6
package/dist/src/commands.js
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
2
17
|
var __require = import.meta.require;
|
|
3
18
|
|
|
4
19
|
// packages/cli/src/runner.ts
|
|
5
20
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
6
21
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
7
22
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
8
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
9
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
10
23
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
11
24
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
12
25
|
function formatCommand(parts) {
|
|
@@ -57,11 +70,277 @@ Usage: ${usage}`);
|
|
|
57
70
|
}
|
|
58
71
|
return taskId;
|
|
59
72
|
}
|
|
73
|
+
var init_runner = () => {};
|
|
74
|
+
|
|
75
|
+
// packages/cli/src/commands/_parsers.ts
|
|
76
|
+
import { homedir } from "os";
|
|
77
|
+
import { resolve as resolve6 } from "path";
|
|
78
|
+
function parsePositiveInt(value, option, fallback) {
|
|
79
|
+
if (!value) {
|
|
80
|
+
return fallback;
|
|
81
|
+
}
|
|
82
|
+
const parsed = Number.parseInt(value, 10);
|
|
83
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
84
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
85
|
+
}
|
|
86
|
+
return parsed;
|
|
87
|
+
}
|
|
88
|
+
function parseOptionalPositiveInt(value, option) {
|
|
89
|
+
if (!value) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const parsed = Number.parseInt(value, 10);
|
|
93
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
94
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
95
|
+
}
|
|
96
|
+
return parsed;
|
|
97
|
+
}
|
|
98
|
+
function parseRequiredPositiveInt(value, option) {
|
|
99
|
+
if (!value) {
|
|
100
|
+
throw new CliError2(`Missing value for ${option}.`);
|
|
101
|
+
}
|
|
102
|
+
const parsed = Number.parseInt(value, 10);
|
|
103
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
104
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
105
|
+
}
|
|
106
|
+
return parsed;
|
|
107
|
+
}
|
|
108
|
+
function parseAction(value) {
|
|
109
|
+
if (!value || value === "validate") {
|
|
110
|
+
return "validate";
|
|
111
|
+
}
|
|
112
|
+
if (value === "verify") {
|
|
113
|
+
return "verify";
|
|
114
|
+
}
|
|
115
|
+
if (value === "pipeline") {
|
|
116
|
+
return "pipeline";
|
|
117
|
+
}
|
|
118
|
+
throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
|
|
119
|
+
}
|
|
120
|
+
function parseIsolationMode(value, allowOff) {
|
|
121
|
+
if (!value) {
|
|
122
|
+
return "worktree";
|
|
123
|
+
}
|
|
124
|
+
if (value === "worktree") {
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
127
|
+
if (allowOff && value === "off") {
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
|
|
131
|
+
}
|
|
132
|
+
function parseInstallScope(value) {
|
|
133
|
+
if (!value || value === "user") {
|
|
134
|
+
return "user";
|
|
135
|
+
}
|
|
136
|
+
if (value === "system") {
|
|
137
|
+
return "system";
|
|
138
|
+
}
|
|
139
|
+
throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
|
|
140
|
+
}
|
|
141
|
+
function resolveInstallDir(scope, explicitPath) {
|
|
142
|
+
if (explicitPath) {
|
|
143
|
+
return resolve6(explicitPath);
|
|
144
|
+
}
|
|
145
|
+
if (scope === "system") {
|
|
146
|
+
return "/usr/local/bin";
|
|
147
|
+
}
|
|
148
|
+
return resolve6(homedir(), ".local/bin");
|
|
149
|
+
}
|
|
150
|
+
async function loadRigConfigOrNull(projectRoot) {
|
|
151
|
+
try {
|
|
152
|
+
const { loadConfig } = await import("@rig/core/load-config");
|
|
153
|
+
return await loadConfig(projectRoot);
|
|
154
|
+
} catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
var init__parsers = __esm(() => {
|
|
159
|
+
init_runner();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// packages/cli/src/commands/plugin.ts
|
|
163
|
+
var exports_plugin = {};
|
|
164
|
+
__export(exports_plugin, {
|
|
165
|
+
resolvePluginCliCommand: () => resolvePluginCliCommand,
|
|
166
|
+
executePlugin: () => executePlugin
|
|
167
|
+
});
|
|
168
|
+
import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
|
|
169
|
+
async function executePlugin(context, args) {
|
|
170
|
+
const [command = "list", ...rest] = args;
|
|
171
|
+
switch (command) {
|
|
172
|
+
case "list": {
|
|
173
|
+
requireNoExtraArgs(rest, "rig plugin list");
|
|
174
|
+
const declarative = [];
|
|
175
|
+
const config = await loadRigConfigOrNull(context.projectRoot);
|
|
176
|
+
if (config && Array.isArray(config.plugins)) {
|
|
177
|
+
for (const plugin of config.plugins) {
|
|
178
|
+
const c = plugin.contributes ?? {};
|
|
179
|
+
declarative.push({
|
|
180
|
+
name: plugin.name,
|
|
181
|
+
version: plugin.version,
|
|
182
|
+
validators: (c.validators ?? []).map((v) => v.id),
|
|
183
|
+
hooks: (c.hooks ?? []).map((h) => h.id),
|
|
184
|
+
agentRoles: (c.agentRoles ?? []).map((r) => r.id),
|
|
185
|
+
repoSources: (c.repoSources ?? []).map((r) => r.id),
|
|
186
|
+
taskSources: (c.taskSources ?? []).map((s) => s.id),
|
|
187
|
+
skills: (c.skills ?? []).map((s) => s.id),
|
|
188
|
+
taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
|
|
189
|
+
cliCommands: (c.cliCommands ?? []).map((entry) => entry.id)
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (context.outputMode === "text") {
|
|
194
|
+
if (declarative.length === 0) {
|
|
195
|
+
console.log("No plugins loaded. Declare plugins in rig.config.ts.");
|
|
196
|
+
} else {
|
|
197
|
+
console.log("Plugins (rig.config.ts):");
|
|
198
|
+
for (const p of declarative) {
|
|
199
|
+
console.log(` ${p.name}@${p.version}`);
|
|
200
|
+
const lines = [];
|
|
201
|
+
if (p.validators.length)
|
|
202
|
+
lines.push(` validators: ${p.validators.join(", ")}`);
|
|
203
|
+
if (p.hooks.length)
|
|
204
|
+
lines.push(` hooks: ${p.hooks.join(", ")}`);
|
|
205
|
+
if (p.agentRoles.length)
|
|
206
|
+
lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
|
|
207
|
+
if (p.repoSources.length)
|
|
208
|
+
lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
|
|
209
|
+
if (p.taskSources.length)
|
|
210
|
+
lines.push(` task-sources: ${p.taskSources.join(", ")}`);
|
|
211
|
+
if (p.skills.length)
|
|
212
|
+
lines.push(` skills: ${p.skills.join(", ")}`);
|
|
213
|
+
if (p.taskFieldExtensions.length)
|
|
214
|
+
lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
|
|
215
|
+
if (p.cliCommands.length)
|
|
216
|
+
lines.push(` cli-commands: ${p.cliCommands.join(", ")} (run with \`rig plugin run <id>\`)`);
|
|
217
|
+
for (const line of lines)
|
|
218
|
+
console.log(line);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
ok: true,
|
|
224
|
+
group: "plugin",
|
|
225
|
+
command,
|
|
226
|
+
details: { declarative }
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
case "validate": {
|
|
230
|
+
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
231
|
+
requireNoExtraArgs(remaining, "rig plugin validate --task <task-id>");
|
|
232
|
+
const taskId = requireTask(task, "rig plugin validate --task <task-id>");
|
|
233
|
+
const hostCtx = await buildPluginHostContext(context.projectRoot);
|
|
234
|
+
if (!hostCtx) {
|
|
235
|
+
throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
|
|
236
|
+
}
|
|
237
|
+
const validators = hostCtx.validatorRegistry.list();
|
|
238
|
+
const results = [];
|
|
239
|
+
for (const validator of validators) {
|
|
240
|
+
try {
|
|
241
|
+
results.push(await validator.run({
|
|
242
|
+
taskId,
|
|
243
|
+
workspaceRoot: context.projectRoot,
|
|
244
|
+
scope: []
|
|
245
|
+
}));
|
|
246
|
+
} catch (error) {
|
|
247
|
+
results.push({
|
|
248
|
+
id: validator.id,
|
|
249
|
+
passed: false,
|
|
250
|
+
summary: `${validator.id} failed unexpectedly`,
|
|
251
|
+
details: `${error}`
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const passed = results.filter((result) => result.passed).length;
|
|
256
|
+
const failed = results.length - passed;
|
|
257
|
+
if (context.outputMode === "text") {
|
|
258
|
+
if (results.length === 0) {
|
|
259
|
+
console.log("No plugin validators registered.");
|
|
260
|
+
} else {
|
|
261
|
+
for (const result of results) {
|
|
262
|
+
const icon = result.passed ? "PASS" : "FAIL";
|
|
263
|
+
console.log(`[${icon}] ${result.id}: ${result.summary}`);
|
|
264
|
+
if (result.details && !result.passed) {
|
|
265
|
+
console.log(result.details);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (failed > 0) {
|
|
271
|
+
throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
ok: true,
|
|
275
|
+
group: "plugin",
|
|
276
|
+
command,
|
|
277
|
+
details: {
|
|
278
|
+
taskId,
|
|
279
|
+
passed,
|
|
280
|
+
failed,
|
|
281
|
+
results
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
case "run": {
|
|
286
|
+
const [commandId, ...commandArgs] = rest;
|
|
287
|
+
if (!commandId) {
|
|
288
|
+
throw new CliError2("Usage: rig plugin run <command-id> [args...]");
|
|
289
|
+
}
|
|
290
|
+
const hostCtx = await buildPluginHostContext(context.projectRoot);
|
|
291
|
+
if (!hostCtx) {
|
|
292
|
+
throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
|
|
293
|
+
}
|
|
294
|
+
const registration = resolvePluginCliCommand(hostCtx.pluginHost.listCliCommands(), commandId);
|
|
295
|
+
if (!registration) {
|
|
296
|
+
const available = hostCtx.pluginHost.listCliCommands().map((entry) => entry.id);
|
|
297
|
+
throw new CliError2(available.length > 0 ? `Unknown plugin command "${commandId}". Available: ${available.join(", ")}` : `No plugin CLI commands are registered. Plugins contribute them via contributes.cliCommands.`, 2);
|
|
298
|
+
}
|
|
299
|
+
if (context.dryRun) {
|
|
300
|
+
if (context.outputMode === "text") {
|
|
301
|
+
console.log(`[dry-run] ${registration.command}${commandArgs.length ? ` ${commandArgs.join(" ")}` : ""}`);
|
|
302
|
+
}
|
|
303
|
+
return { ok: true, group: "plugin", command, details: { id: registration.id, dryRun: true } };
|
|
304
|
+
}
|
|
305
|
+
const proc = Bun.spawn(["bash", "-c", `${registration.command} "$@"`, registration.id, ...commandArgs], {
|
|
306
|
+
cwd: context.projectRoot,
|
|
307
|
+
env: process.env,
|
|
308
|
+
stdin: "inherit",
|
|
309
|
+
stdout: "inherit",
|
|
310
|
+
stderr: "inherit"
|
|
311
|
+
});
|
|
312
|
+
const exitCode = await proc.exited;
|
|
313
|
+
if (exitCode !== 0) {
|
|
314
|
+
throw new CliError2(`Plugin command "${registration.id}" exited with code ${exitCode}.`, exitCode);
|
|
315
|
+
}
|
|
316
|
+
return { ok: true, group: "plugin", command, details: { id: registration.id, exitCode } };
|
|
317
|
+
}
|
|
318
|
+
default:
|
|
319
|
+
throw new CliError2(`Unknown plugin command: ${command}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function resolvePluginCliCommand(commands, requested) {
|
|
323
|
+
const exact = commands.find((entry) => entry.id === requested);
|
|
324
|
+
if (exact)
|
|
325
|
+
return exact;
|
|
326
|
+
const byLocalPart = commands.filter((entry) => entry.id.split(":").slice(1).join(":") === requested);
|
|
327
|
+
return byLocalPart.length === 1 ? byLocalPart[0] : undefined;
|
|
328
|
+
}
|
|
329
|
+
var init_plugin = __esm(() => {
|
|
330
|
+
init_runner();
|
|
331
|
+
init__parsers();
|
|
332
|
+
});
|
|
60
333
|
|
|
61
334
|
// packages/cli/src/commands.ts
|
|
335
|
+
init_runner();
|
|
336
|
+
import {
|
|
337
|
+
existsSync as existsSync13
|
|
338
|
+
} from "fs";
|
|
339
|
+
import { resolve as resolve22 } from "path";
|
|
62
340
|
import { readBuildConfig } from "@rig/runtime/build-time-config";
|
|
63
341
|
|
|
64
342
|
// packages/cli/src/commands/browser.ts
|
|
343
|
+
init_runner();
|
|
65
344
|
import { mkdirSync as mkdirSync2, rmSync as rmSync2 } from "fs";
|
|
66
345
|
import { resolve as resolve4 } from "path";
|
|
67
346
|
import { spawn } from "child_process";
|
|
@@ -72,6 +351,7 @@ import pc2 from "picocolors";
|
|
|
72
351
|
import { runCapture as runCapture2 } from "@rig/runtime/control-plane/native/utils";
|
|
73
352
|
|
|
74
353
|
// packages/cli/src/commands/task-report-bug.ts
|
|
354
|
+
init_runner();
|
|
75
355
|
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
76
356
|
import { resolve as resolve3 } from "path";
|
|
77
357
|
import * as clack from "@clack/prompts";
|
|
@@ -288,15 +568,15 @@ function buildBugReportMarkdown(input, browser, screenshots, assets) {
|
|
|
288
568
|
...input.issueId ? [
|
|
289
569
|
`- Canonical task assets live under \`artifacts/${input.issueId}/bug-report/\`.`,
|
|
290
570
|
`- Start with \`artifacts/${input.issueId}/bug-report/task.md\` and the files in \`artifacts/${input.issueId}/bug-report/assets/\`.`,
|
|
291
|
-
browserRequired ? `- Run \`
|
|
571
|
+
browserRequired ? `- Run \`rig task info --task ${input.issueId}\` to confirm browser wiring before debugging.` : `- Run \`rig task info --task ${input.issueId}\` to confirm scope and artifact links before debugging.`
|
|
292
572
|
] : [
|
|
293
|
-
"- Draft-only report: convert this into a
|
|
573
|
+
"- Draft-only report: convert this into a Rig task before assigning it to an agent run."
|
|
294
574
|
],
|
|
295
575
|
"",
|
|
296
576
|
"## Validation",
|
|
297
577
|
"",
|
|
298
578
|
"```bash",
|
|
299
|
-
...input.issueId ? [`
|
|
579
|
+
...input.issueId ? [`rig task validate --task ${input.issueId}`] : [],
|
|
300
580
|
...browserRequired ? [
|
|
301
581
|
"bun run app:check:browser:hp-next",
|
|
302
582
|
"bun run app:e2e:browser:hp-next"
|
|
@@ -443,7 +723,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
443
723
|
pending = outputRootResult.rest;
|
|
444
724
|
const slugResult = takeOption(pending, "--slug");
|
|
445
725
|
pending = slugResult.rest;
|
|
446
|
-
requireNoExtraArgs(pending, "
|
|
726
|
+
requireNoExtraArgs(pending, "rig report-bug [--no-prompt] [--no-beads] [--browser|--no-browser] --title <text> --url <url> [--asset <dragged-file>]");
|
|
447
727
|
let draft = {
|
|
448
728
|
outputRoot: outputRootResult.value || "",
|
|
449
729
|
title: titleResult.value,
|
|
@@ -548,7 +828,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
548
828
|
console.log(`Evidence assets: ${result.assetDir}`);
|
|
549
829
|
if (taskConfigPath) {
|
|
550
830
|
console.log(`Task config: ${taskConfigPath}`);
|
|
551
|
-
console.log(`Run:
|
|
831
|
+
console.log(`Run: rig task info --task ${issueId}`);
|
|
552
832
|
}
|
|
553
833
|
}
|
|
554
834
|
return {
|
|
@@ -1371,7 +1651,7 @@ async function executeBrowser(context, args) {
|
|
|
1371
1651
|
return { ok: true, group: "browser", command: "help" };
|
|
1372
1652
|
}
|
|
1373
1653
|
if (command === "explain") {
|
|
1374
|
-
requireNoExtraArgs(rest, "
|
|
1654
|
+
requireNoExtraArgs(rest, "rig browser explain");
|
|
1375
1655
|
console.log(browserAgentUsageText());
|
|
1376
1656
|
return { ok: true, group: "browser", command: "explain" };
|
|
1377
1657
|
}
|
|
@@ -1397,7 +1677,7 @@ ${browserHelpText()}`);
|
|
|
1397
1677
|
|
|
1398
1678
|
${browserHelpText()}`);
|
|
1399
1679
|
}
|
|
1400
|
-
requireNoExtraArgs(appRest, `
|
|
1680
|
+
requireNoExtraArgs(appRest, `rig browser ${command} ${subcommand}`);
|
|
1401
1681
|
await context.runCommand(["bun", "run", `app:${subcommand}:browser:${appSlug}`]);
|
|
1402
1682
|
return { ok: true, group: "browser", command: `${command}-${subcommand}` };
|
|
1403
1683
|
}
|
|
@@ -1409,7 +1689,7 @@ ${browserHelpText()}`);
|
|
|
1409
1689
|
};
|
|
1410
1690
|
const packageScript = packageScripts[command];
|
|
1411
1691
|
if (packageScript) {
|
|
1412
|
-
requireNoExtraArgs(rest, `
|
|
1692
|
+
requireNoExtraArgs(rest, `rig browser ${command}`);
|
|
1413
1693
|
await context.runCommand(["bun", "run", "--filter=@rig/browser", packageScript]);
|
|
1414
1694
|
return { ok: true, group: "browser", command };
|
|
1415
1695
|
}
|
|
@@ -1436,7 +1716,7 @@ async function executeBrowserDemo(context, args) {
|
|
|
1436
1716
|
pending = keepOpenFlag.rest;
|
|
1437
1717
|
const noBuildFlag = takeFlag(pending, "--no-build");
|
|
1438
1718
|
pending = noBuildFlag.rest;
|
|
1439
|
-
requireNoExtraArgs(pending, "
|
|
1719
|
+
requireNoExtraArgs(pending, "rig browser demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]");
|
|
1440
1720
|
if (context.outputMode !== "text" || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
1441
1721
|
throw new CliError2("rig browser demo requires an interactive TTY in text mode.");
|
|
1442
1722
|
}
|
|
@@ -1896,6 +2176,7 @@ async function stopBrowserDemo(child) {
|
|
|
1896
2176
|
}
|
|
1897
2177
|
|
|
1898
2178
|
// packages/cli/src/commands/profile-and-review.ts
|
|
2179
|
+
init_runner();
|
|
1899
2180
|
import {
|
|
1900
2181
|
setProfile,
|
|
1901
2182
|
setReviewProfile,
|
|
@@ -1947,17 +2228,17 @@ async function executeProfile(context, args) {
|
|
|
1947
2228
|
const [command = "show", ...rest] = args;
|
|
1948
2229
|
switch (command) {
|
|
1949
2230
|
case "show":
|
|
1950
|
-
requireNoExtraArgs(rest, "
|
|
2231
|
+
requireNoExtraArgs(rest, "rig profile show");
|
|
1951
2232
|
await withMutedConsole(context.outputMode === "json", () => showProfile(context.projectRoot));
|
|
1952
2233
|
return { ok: true, group: "profile", command };
|
|
1953
2234
|
case "set": {
|
|
1954
2235
|
if (rest.length === 0) {
|
|
1955
|
-
throw new CliError2("Usage:
|
|
2236
|
+
throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi> or set [--model ...] [--runtime ...] [--plugin ...]");
|
|
1956
2237
|
}
|
|
1957
2238
|
const preset = rest[0];
|
|
1958
2239
|
if (preset && !preset.startsWith("-")) {
|
|
1959
2240
|
if (rest.length !== 1) {
|
|
1960
|
-
throw new CliError2("Usage:
|
|
2241
|
+
throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi>");
|
|
1961
2242
|
}
|
|
1962
2243
|
try {
|
|
1963
2244
|
await withMutedConsole(context.outputMode === "json", () => setProfile(context.projectRoot, { preset }));
|
|
@@ -1973,7 +2254,7 @@ async function executeProfile(context, args) {
|
|
|
1973
2254
|
pending = runtimeResult.rest;
|
|
1974
2255
|
const pluginResult = takeOption(pending, "--plugin");
|
|
1975
2256
|
pending = pluginResult.rest;
|
|
1976
|
-
requireNoExtraArgs(pending, "
|
|
2257
|
+
requireNoExtraArgs(pending, "rig profile set [--model ...] [--runtime ...] [--plugin ...]");
|
|
1977
2258
|
if (!modelResult.value && !runtimeResult.value && !pluginResult.value) {
|
|
1978
2259
|
throw new CliError2("Provide at least one of --model, --runtime, or --plugin.");
|
|
1979
2260
|
}
|
|
@@ -2005,21 +2286,21 @@ async function executeReview(context, args) {
|
|
|
2005
2286
|
const [command = "show", ...rest] = args;
|
|
2006
2287
|
switch (command) {
|
|
2007
2288
|
case "show":
|
|
2008
|
-
requireNoExtraArgs(rest, "
|
|
2289
|
+
requireNoExtraArgs(rest, "rig review show");
|
|
2009
2290
|
await withMutedConsole(context.outputMode === "json", () => showReviewProfile(context.projectRoot));
|
|
2010
2291
|
return { ok: true, group: "review", command };
|
|
2011
2292
|
case "set": {
|
|
2012
2293
|
if (rest.length === 0) {
|
|
2013
|
-
throw new CliError2("Usage:
|
|
2294
|
+
throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
|
|
2014
2295
|
}
|
|
2015
2296
|
const mode = rest[0];
|
|
2016
2297
|
if (!mode) {
|
|
2017
|
-
throw new CliError2("Usage:
|
|
2298
|
+
throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
|
|
2018
2299
|
}
|
|
2019
2300
|
let pending = rest.slice(1);
|
|
2020
2301
|
const providerResult = takeOption(pending, "--provider");
|
|
2021
2302
|
pending = providerResult.rest;
|
|
2022
|
-
requireNoExtraArgs(pending, "
|
|
2303
|
+
requireNoExtraArgs(pending, "rig review set <off|advisory|required> [--provider greptile]");
|
|
2023
2304
|
try {
|
|
2024
2305
|
await withMutedConsole(context.outputMode === "json", () => {
|
|
2025
2306
|
return setReviewProfile(context.projectRoot, mode, providerResult.value);
|
|
@@ -2035,10 +2316,12 @@ async function executeReview(context, args) {
|
|
|
2035
2316
|
}
|
|
2036
2317
|
|
|
2037
2318
|
// packages/cli/src/commands/repo-git-harness.ts
|
|
2319
|
+
init_runner();
|
|
2038
2320
|
import { executeHarnessCommand } from "@rig/runtime/control-plane/native/harness-cli";
|
|
2039
2321
|
import { repoEnsure, resetBaseline } from "@rig/runtime/control-plane/native/repo-ops";
|
|
2040
2322
|
|
|
2041
2323
|
// packages/cli/src/commands/_policy.ts
|
|
2324
|
+
init_runner();
|
|
2042
2325
|
import { appendFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
2043
2326
|
import { resolve as resolve5 } from "path";
|
|
2044
2327
|
import { evaluate as evaluate2, loadPolicy as loadPolicy2, resolveAction as resolveAction2 } from "@rig/runtime/control-plane/runtime/guard";
|
|
@@ -2104,13 +2387,13 @@ async function executeRepo(context, args) {
|
|
|
2104
2387
|
switch (command) {
|
|
2105
2388
|
case "sync": {
|
|
2106
2389
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
2107
|
-
requireNoExtraArgs(remaining, "
|
|
2390
|
+
requireNoExtraArgs(remaining, "rig repo sync [--task <task-id>]");
|
|
2108
2391
|
withMutedConsole(context.outputMode === "json", () => repoEnsure(context.projectRoot, task || undefined));
|
|
2109
2392
|
return { ok: true, group: "repo", command, details: { task: task || null } };
|
|
2110
2393
|
}
|
|
2111
2394
|
case "reset-baseline": {
|
|
2112
2395
|
const { value: keepTaskStatusFlag, rest: remaining } = takeFlag(rest, "--keep-task-status");
|
|
2113
|
-
requireNoExtraArgs(remaining, "
|
|
2396
|
+
requireNoExtraArgs(remaining, "rig repo reset-baseline [--keep-task-status]");
|
|
2114
2397
|
withMutedConsole(context.outputMode === "json", () => resetBaseline(context.projectRoot, keepTaskStatusFlag));
|
|
2115
2398
|
return { ok: true, group: "repo", command, details: { keepTaskStatus: keepTaskStatusFlag } };
|
|
2116
2399
|
}
|
|
@@ -2120,7 +2403,7 @@ async function executeRepo(context, args) {
|
|
|
2120
2403
|
}
|
|
2121
2404
|
async function executeGit(context, args) {
|
|
2122
2405
|
if (args.length === 0) {
|
|
2123
|
-
throw new CliError2("Usage:
|
|
2406
|
+
throw new CliError2("Usage: rig git <git-flow args...>");
|
|
2124
2407
|
}
|
|
2125
2408
|
await enforceNativeCommandPolicy(context, args, {
|
|
2126
2409
|
commandPrefix: "rig-agent git",
|
|
@@ -2133,7 +2416,7 @@ async function executeGit(context, args) {
|
|
|
2133
2416
|
return { ok: true, group: "git", command: args[0] ?? "git" };
|
|
2134
2417
|
}
|
|
2135
2418
|
try {
|
|
2136
|
-
await executeHarnessCommand(context.projectRoot,
|
|
2419
|
+
await executeHarnessCommand(context.projectRoot, ["git", ...args]);
|
|
2137
2420
|
} catch (error) {
|
|
2138
2421
|
throw new CliError2(error instanceof Error ? error.message : String(error), 2);
|
|
2139
2422
|
}
|
|
@@ -2141,7 +2424,7 @@ async function executeGit(context, args) {
|
|
|
2141
2424
|
}
|
|
2142
2425
|
async function executeHarness(context, args) {
|
|
2143
2426
|
if (args.length === 0) {
|
|
2144
|
-
throw new CliError2("Usage:
|
|
2427
|
+
throw new CliError2("Usage: rig harness <harness args...>");
|
|
2145
2428
|
}
|
|
2146
2429
|
await enforceNativeCommandPolicy(context, args, {
|
|
2147
2430
|
commandPrefix: "rig-agent",
|
|
@@ -2154,236 +2437,49 @@ async function executeHarness(context, args) {
|
|
|
2154
2437
|
return { ok: true, group: "harness", command: args[0] ?? "harness" };
|
|
2155
2438
|
}
|
|
2156
2439
|
try {
|
|
2157
|
-
await executeHarnessCommand(context.projectRoot,
|
|
2440
|
+
await executeHarnessCommand(context.projectRoot, args);
|
|
2158
2441
|
} catch (error) {
|
|
2159
2442
|
throw new CliError2(error instanceof Error ? error.message : String(error), 2);
|
|
2160
2443
|
}
|
|
2161
2444
|
return { ok: true, group: "harness", command: args[0] ?? "harness" };
|
|
2162
2445
|
}
|
|
2163
2446
|
|
|
2164
|
-
// packages/cli/src/commands
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2447
|
+
// packages/cli/src/commands.ts
|
|
2448
|
+
init_plugin();
|
|
2449
|
+
|
|
2450
|
+
// packages/cli/src/commands/queue.ts
|
|
2451
|
+
init_runner();
|
|
2452
|
+
init__parsers();
|
|
2453
|
+
import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
|
|
2454
|
+
|
|
2455
|
+
// packages/cli/src/commands/_preflight.ts
|
|
2456
|
+
init_runner();
|
|
2457
|
+
import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
2458
|
+
|
|
2459
|
+
// packages/cli/src/commands/_connection-state.ts
|
|
2460
|
+
init_runner();
|
|
2461
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2462
|
+
import { homedir as homedir2 } from "os";
|
|
2463
|
+
import { dirname, resolve as resolve7 } from "path";
|
|
2464
|
+
function resolveGlobalConnectionsPath(env = process.env) {
|
|
2465
|
+
const explicit = env.RIG_CONNECTIONS_FILE?.trim();
|
|
2466
|
+
if (explicit)
|
|
2467
|
+
return resolve7(explicit);
|
|
2468
|
+
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2469
|
+
if (stateDir)
|
|
2470
|
+
return resolve7(stateDir, "connections.json");
|
|
2471
|
+
return resolve7(homedir2(), ".rig", "connections.json");
|
|
2176
2472
|
}
|
|
2177
|
-
function
|
|
2178
|
-
|
|
2179
|
-
return;
|
|
2180
|
-
}
|
|
2181
|
-
const parsed = Number.parseInt(value, 10);
|
|
2182
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
2183
|
-
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
2184
|
-
}
|
|
2185
|
-
return parsed;
|
|
2473
|
+
function resolveRepoConnectionPath(projectRoot) {
|
|
2474
|
+
return resolve7(projectRoot, ".rig", "state", "connection.json");
|
|
2186
2475
|
}
|
|
2187
|
-
function
|
|
2188
|
-
if (!
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
throw new CliError2(`Invalid ${
|
|
2194
|
-
}
|
|
2195
|
-
return parsed;
|
|
2196
|
-
}
|
|
2197
|
-
function parseAction(value) {
|
|
2198
|
-
if (!value || value === "validate") {
|
|
2199
|
-
return "validate";
|
|
2200
|
-
}
|
|
2201
|
-
if (value === "verify") {
|
|
2202
|
-
return "verify";
|
|
2203
|
-
}
|
|
2204
|
-
if (value === "pipeline") {
|
|
2205
|
-
return "pipeline";
|
|
2206
|
-
}
|
|
2207
|
-
throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
|
|
2208
|
-
}
|
|
2209
|
-
function parseIsolationMode(value, allowOff) {
|
|
2210
|
-
if (!value) {
|
|
2211
|
-
return "worktree";
|
|
2212
|
-
}
|
|
2213
|
-
if (value === "worktree") {
|
|
2214
|
-
return value;
|
|
2215
|
-
}
|
|
2216
|
-
if (allowOff && value === "off") {
|
|
2217
|
-
return value;
|
|
2218
|
-
}
|
|
2219
|
-
throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
|
|
2220
|
-
}
|
|
2221
|
-
function parseInstallScope(value) {
|
|
2222
|
-
if (!value || value === "user") {
|
|
2223
|
-
return "user";
|
|
2224
|
-
}
|
|
2225
|
-
if (value === "system") {
|
|
2226
|
-
return "system";
|
|
2227
|
-
}
|
|
2228
|
-
throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
|
|
2229
|
-
}
|
|
2230
|
-
function resolveInstallDir(scope, explicitPath) {
|
|
2231
|
-
if (explicitPath) {
|
|
2232
|
-
return resolve6(explicitPath);
|
|
2233
|
-
}
|
|
2234
|
-
if (scope === "system") {
|
|
2235
|
-
return "/usr/local/bin";
|
|
2236
|
-
}
|
|
2237
|
-
return resolve6(homedir(), ".local/bin");
|
|
2238
|
-
}
|
|
2239
|
-
async function loadRigConfigOrNull(projectRoot) {
|
|
2240
|
-
try {
|
|
2241
|
-
const { loadConfig } = await import("@rig/core/load-config");
|
|
2242
|
-
return await loadConfig(projectRoot);
|
|
2243
|
-
} catch {
|
|
2244
|
-
return null;
|
|
2245
|
-
}
|
|
2246
|
-
}
|
|
2247
|
-
|
|
2248
|
-
// packages/cli/src/commands/plugin.ts
|
|
2249
|
-
async function executePlugin(context, args) {
|
|
2250
|
-
const [command = "list", ...rest] = args;
|
|
2251
|
-
switch (command) {
|
|
2252
|
-
case "list": {
|
|
2253
|
-
requireNoExtraArgs(rest, "bun run rig plugin list");
|
|
2254
|
-
const legacyPlugins = context.plugins.list();
|
|
2255
|
-
const declarative = [];
|
|
2256
|
-
const config = await loadRigConfigOrNull(context.projectRoot);
|
|
2257
|
-
if (config && Array.isArray(config.plugins)) {
|
|
2258
|
-
for (const plugin of config.plugins) {
|
|
2259
|
-
const c = plugin.contributes ?? {};
|
|
2260
|
-
declarative.push({
|
|
2261
|
-
name: plugin.name,
|
|
2262
|
-
version: plugin.version,
|
|
2263
|
-
validators: (c.validators ?? []).map((v) => v.id),
|
|
2264
|
-
hooks: (c.hooks ?? []).map((h) => h.id),
|
|
2265
|
-
agentRoles: (c.agentRoles ?? []).map((r) => r.id),
|
|
2266
|
-
repoSources: (c.repoSources ?? []).map((r) => r.id),
|
|
2267
|
-
taskSources: (c.taskSources ?? []).map((s) => s.id),
|
|
2268
|
-
skills: (c.skills ?? []).map((s) => s.id),
|
|
2269
|
-
taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
|
|
2270
|
-
cliCommands: (c.cliCommands ?? []).map((c2) => c2.id)
|
|
2271
|
-
});
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
if (context.outputMode === "text") {
|
|
2275
|
-
if (legacyPlugins.length === 0 && declarative.length === 0) {
|
|
2276
|
-
console.log("No plugins loaded.");
|
|
2277
|
-
}
|
|
2278
|
-
if (declarative.length > 0) {
|
|
2279
|
-
console.log("Declarative plugins (rig.config.ts):");
|
|
2280
|
-
for (const p of declarative) {
|
|
2281
|
-
console.log(` ${p.name}@${p.version}`);
|
|
2282
|
-
const lines = [];
|
|
2283
|
-
if (p.validators.length)
|
|
2284
|
-
lines.push(` validators: ${p.validators.join(", ")}`);
|
|
2285
|
-
if (p.hooks.length)
|
|
2286
|
-
lines.push(` hooks: ${p.hooks.join(", ")}`);
|
|
2287
|
-
if (p.agentRoles.length)
|
|
2288
|
-
lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
|
|
2289
|
-
if (p.repoSources.length)
|
|
2290
|
-
lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
|
|
2291
|
-
if (p.taskSources.length)
|
|
2292
|
-
lines.push(` task-sources: ${p.taskSources.join(", ")}`);
|
|
2293
|
-
if (p.skills.length)
|
|
2294
|
-
lines.push(` skills: ${p.skills.join(", ")}`);
|
|
2295
|
-
if (p.taskFieldExtensions.length)
|
|
2296
|
-
lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
|
|
2297
|
-
if (p.cliCommands.length)
|
|
2298
|
-
lines.push(` cli-commands: ${p.cliCommands.join(", ")}`);
|
|
2299
|
-
for (const line of lines)
|
|
2300
|
-
console.log(line);
|
|
2301
|
-
}
|
|
2302
|
-
}
|
|
2303
|
-
if (legacyPlugins.length > 0) {
|
|
2304
|
-
console.log("Legacy disk-scan plugins (rig/plugins/):");
|
|
2305
|
-
for (const plugin of legacyPlugins) {
|
|
2306
|
-
const validators = plugin.validators.length > 0 ? plugin.validators.join(", ") : "none";
|
|
2307
|
-
console.log(` ${plugin.name} (validators: ${validators})`);
|
|
2308
|
-
}
|
|
2309
|
-
}
|
|
2310
|
-
}
|
|
2311
|
-
return {
|
|
2312
|
-
ok: true,
|
|
2313
|
-
group: "plugin",
|
|
2314
|
-
command,
|
|
2315
|
-
details: { declarative, legacy: legacyPlugins }
|
|
2316
|
-
};
|
|
2317
|
-
}
|
|
2318
|
-
case "validate": {
|
|
2319
|
-
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
2320
|
-
requireNoExtraArgs(remaining, "bun run rig plugin validate --task <beads-id>");
|
|
2321
|
-
const taskId = requireTask(task, "bun run rig plugin validate --task <beads-id>");
|
|
2322
|
-
const results = await context.plugins.runValidators(taskId);
|
|
2323
|
-
const passed = results.filter((result) => result.passed).length;
|
|
2324
|
-
const failed = results.length - passed;
|
|
2325
|
-
if (context.outputMode === "text") {
|
|
2326
|
-
if (results.length === 0) {
|
|
2327
|
-
console.log("No plugin validators registered.");
|
|
2328
|
-
} else {
|
|
2329
|
-
for (const result of results) {
|
|
2330
|
-
const icon = result.passed ? "PASS" : "FAIL";
|
|
2331
|
-
console.log(`[${icon}] ${result.id}: ${result.summary}`);
|
|
2332
|
-
if (result.details && !result.passed) {
|
|
2333
|
-
console.log(result.details);
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2337
|
-
}
|
|
2338
|
-
if (failed > 0) {
|
|
2339
|
-
throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
|
|
2340
|
-
}
|
|
2341
|
-
return {
|
|
2342
|
-
ok: true,
|
|
2343
|
-
group: "plugin",
|
|
2344
|
-
command,
|
|
2345
|
-
details: {
|
|
2346
|
-
taskId,
|
|
2347
|
-
passed,
|
|
2348
|
-
failed,
|
|
2349
|
-
results
|
|
2350
|
-
}
|
|
2351
|
-
};
|
|
2352
|
-
}
|
|
2353
|
-
default:
|
|
2354
|
-
throw new CliError2(`Unknown plugin command: ${command}`);
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
|
|
2358
|
-
// packages/cli/src/commands/queue.ts
|
|
2359
|
-
import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
|
|
2360
|
-
|
|
2361
|
-
// packages/cli/src/commands/_preflight.ts
|
|
2362
|
-
import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
2363
|
-
|
|
2364
|
-
// packages/cli/src/commands/_connection-state.ts
|
|
2365
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2366
|
-
import { homedir as homedir2 } from "os";
|
|
2367
|
-
import { dirname, resolve as resolve7 } from "path";
|
|
2368
|
-
function resolveGlobalConnectionsPath(env = process.env) {
|
|
2369
|
-
const explicit = env.RIG_CONNECTIONS_FILE?.trim();
|
|
2370
|
-
if (explicit)
|
|
2371
|
-
return resolve7(explicit);
|
|
2372
|
-
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2373
|
-
if (stateDir)
|
|
2374
|
-
return resolve7(stateDir, "connections.json");
|
|
2375
|
-
return resolve7(homedir2(), ".rig", "connections.json");
|
|
2376
|
-
}
|
|
2377
|
-
function resolveRepoConnectionPath(projectRoot) {
|
|
2378
|
-
return resolve7(projectRoot, ".rig", "state", "connection.json");
|
|
2379
|
-
}
|
|
2380
|
-
function readJsonFile2(path) {
|
|
2381
|
-
if (!existsSync3(path))
|
|
2382
|
-
return null;
|
|
2383
|
-
try {
|
|
2384
|
-
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2385
|
-
} catch (error) {
|
|
2386
|
-
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
2476
|
+
function readJsonFile2(path) {
|
|
2477
|
+
if (!existsSync3(path))
|
|
2478
|
+
return null;
|
|
2479
|
+
try {
|
|
2480
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2481
|
+
} catch (error) {
|
|
2482
|
+
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
2387
2483
|
}
|
|
2388
2484
|
}
|
|
2389
2485
|
function writeJsonFile2(path, value) {
|
|
@@ -2458,12 +2554,13 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
2458
2554
|
const global = readGlobalConnections(options);
|
|
2459
2555
|
const connection = global.connections[repo.selected];
|
|
2460
2556
|
if (!connection) {
|
|
2461
|
-
throw new CliError2(`Selected Rig
|
|
2557
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
2462
2558
|
}
|
|
2463
2559
|
return { alias: repo.selected, connection };
|
|
2464
2560
|
}
|
|
2465
2561
|
|
|
2466
2562
|
// packages/cli/src/commands/_server-client.ts
|
|
2563
|
+
init_runner();
|
|
2467
2564
|
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
|
|
2468
2565
|
import { resolve as resolve8 } from "path";
|
|
2469
2566
|
import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
|
|
@@ -2950,7 +3047,7 @@ async function runFastTaskRunPreflight(context, options = {}) {
|
|
|
2950
3047
|
}
|
|
2951
3048
|
}
|
|
2952
3049
|
const repo = readRepoConnection(context.projectRoot);
|
|
2953
|
-
checks.push(repo ? preflightCheck("project-link", "project linked to Rig
|
|
3050
|
+
checks.push(repo ? preflightCheck("project-link", "project linked to Rig server", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to Rig server", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
|
|
2954
3051
|
try {
|
|
2955
3052
|
const auth = await request("/api/github/auth/status");
|
|
2956
3053
|
checks.push(isAuthenticated(auth) ? preflightCheck("github-auth", "GitHub auth valid", "pass") : preflightCheck("github-auth", "GitHub auth valid", legacyServerCompatibility ? "warn" : "fail", "not authenticated", "Run `rig github auth import-gh` or `rig github auth token --token <token>`."));
|
|
@@ -3068,7 +3165,7 @@ async function executeQueue(context, args) {
|
|
|
3068
3165
|
pending = failFastResult.rest;
|
|
3069
3166
|
const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
|
|
3070
3167
|
pending = skipProjectSyncResult.rest;
|
|
3071
|
-
requireNoExtraArgs(pending, "
|
|
3168
|
+
requireNoExtraArgs(pending, "rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]");
|
|
3072
3169
|
const workers = parsePositiveInt(workersResult.value, "--workers", 2);
|
|
3073
3170
|
const maxTasks = parsePositiveInt(maxTasksResult.value, "--max-tasks", 10);
|
|
3074
3171
|
const action = parseAction(actionResult.value);
|
|
@@ -3112,6 +3209,7 @@ async function executeQueue(context, args) {
|
|
|
3112
3209
|
}
|
|
3113
3210
|
|
|
3114
3211
|
// packages/cli/src/commands/agent.ts
|
|
3212
|
+
init_runner();
|
|
3115
3213
|
import { resolve as resolve10 } from "path";
|
|
3116
3214
|
import {
|
|
3117
3215
|
agentId,
|
|
@@ -3219,6 +3317,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
3219
3317
|
}
|
|
3220
3318
|
|
|
3221
3319
|
// packages/cli/src/commands/agent.ts
|
|
3320
|
+
init__parsers();
|
|
3222
3321
|
function splitAtDoubleDash(args) {
|
|
3223
3322
|
const separatorIndex = args.indexOf("--");
|
|
3224
3323
|
if (separatorIndex === -1) {
|
|
@@ -3246,7 +3345,7 @@ async function executeAgent(context, args) {
|
|
|
3246
3345
|
const [command = "list", ...rest] = args;
|
|
3247
3346
|
switch (command) {
|
|
3248
3347
|
case "list": {
|
|
3249
|
-
requireNoExtraArgs(rest, "
|
|
3348
|
+
requireNoExtraArgs(rest, "rig agent list");
|
|
3250
3349
|
const runtimes = await listAgentRuntimes(context.projectRoot);
|
|
3251
3350
|
if (context.outputMode === "text") {
|
|
3252
3351
|
if (runtimes.length === 0) {
|
|
@@ -3267,12 +3366,12 @@ async function executeAgent(context, args) {
|
|
|
3267
3366
|
pending = modeResult.rest;
|
|
3268
3367
|
const taskResult = takeOption(pending, "--task");
|
|
3269
3368
|
pending = taskResult.rest;
|
|
3270
|
-
requireNoExtraArgs(pending, "
|
|
3369
|
+
requireNoExtraArgs(pending, "rig agent prepare --task <id> [--id <id>] [--mode worktree]");
|
|
3271
3370
|
const mode = parseIsolationMode(modeResult.value, false);
|
|
3272
3371
|
const id = idResult.value || agentId("agent");
|
|
3273
3372
|
const taskId = taskResult.value?.trim();
|
|
3274
3373
|
if (!taskId) {
|
|
3275
|
-
throw new CliError2("Usage:
|
|
3374
|
+
throw new CliError2("Usage: rig agent prepare --task <id> [--id <id>] [--mode worktree]");
|
|
3276
3375
|
}
|
|
3277
3376
|
const runtime = await withMutedConsole(context.outputMode === "json", () => ensureAgentRuntime({
|
|
3278
3377
|
projectRoot: context.projectRoot,
|
|
@@ -3290,7 +3389,7 @@ async function executeAgent(context, args) {
|
|
|
3290
3389
|
case "run": {
|
|
3291
3390
|
const { options, commandParts } = splitAtDoubleDash(rest);
|
|
3292
3391
|
if (commandParts.length === 0) {
|
|
3293
|
-
throw new CliError2("Usage:
|
|
3392
|
+
throw new CliError2("Usage: rig agent run [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3294
3393
|
}
|
|
3295
3394
|
let pending = options;
|
|
3296
3395
|
const idResult = takeOption(pending, "--id");
|
|
@@ -3301,12 +3400,12 @@ async function executeAgent(context, args) {
|
|
|
3301
3400
|
pending = taskResult.rest;
|
|
3302
3401
|
const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
|
|
3303
3402
|
pending = skipProjectSyncResult.rest;
|
|
3304
|
-
requireNoExtraArgs(pending, "
|
|
3403
|
+
requireNoExtraArgs(pending, "rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3305
3404
|
const mode = parseIsolationMode(modeResult.value, false);
|
|
3306
3405
|
const id = idResult.value || agentId("agent-run");
|
|
3307
3406
|
const taskId = taskResult.value?.trim();
|
|
3308
3407
|
if (!taskId) {
|
|
3309
|
-
throw new CliError2("Usage:
|
|
3408
|
+
throw new CliError2("Usage: rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3310
3409
|
}
|
|
3311
3410
|
await runProjectMainSyncPreflight(context, { disabled: skipProjectSyncResult.value });
|
|
3312
3411
|
const createdAt = new Date().toISOString();
|
|
@@ -3420,7 +3519,7 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
|
|
|
3420
3519
|
pending = allResult.rest;
|
|
3421
3520
|
const idResult = takeOption(pending, "--id");
|
|
3422
3521
|
pending = idResult.rest;
|
|
3423
|
-
requireNoExtraArgs(pending, "
|
|
3522
|
+
requireNoExtraArgs(pending, "rig agent cleanup (--id <id> | --all)");
|
|
3424
3523
|
if (!allResult.value && !idResult.value) {
|
|
3425
3524
|
throw new CliError2("Provide --id <id> or --all.");
|
|
3426
3525
|
}
|
|
@@ -3452,6 +3551,8 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
|
|
|
3452
3551
|
}
|
|
3453
3552
|
|
|
3454
3553
|
// packages/cli/src/commands/dist.ts
|
|
3554
|
+
init_runner();
|
|
3555
|
+
init__parsers();
|
|
3455
3556
|
import {
|
|
3456
3557
|
chmodSync,
|
|
3457
3558
|
copyFileSync as copyFileSync2,
|
|
@@ -3556,7 +3657,7 @@ async function executeDist(context, args) {
|
|
|
3556
3657
|
switch (command) {
|
|
3557
3658
|
case "build": {
|
|
3558
3659
|
const { value: outputDir, rest: pending } = takeOption(rest, "--output-dir");
|
|
3559
|
-
requireNoExtraArgs(pending, "
|
|
3660
|
+
requireNoExtraArgs(pending, "rig dist build [--output-dir <dir>]");
|
|
3560
3661
|
const commandParts = ["bun", "run", "packages/cli/bin/build-rig-binaries.ts"];
|
|
3561
3662
|
if (outputDir) {
|
|
3562
3663
|
commandParts.push("--output-dir", outputDir);
|
|
@@ -3570,7 +3671,7 @@ async function executeDist(context, args) {
|
|
|
3570
3671
|
pending = scopeResult.rest;
|
|
3571
3672
|
const pathResult = takeOption(pending, "--path");
|
|
3572
3673
|
pending = pathResult.rest;
|
|
3573
|
-
requireNoExtraArgs(pending, "
|
|
3674
|
+
requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
|
|
3574
3675
|
const scope = parseInstallScope(scopeResult.value);
|
|
3575
3676
|
const installDir = resolveInstallDir(scope, pathResult.value);
|
|
3576
3677
|
mkdirSync5(installDir, { recursive: true });
|
|
@@ -3613,7 +3714,7 @@ async function executeDist(context, args) {
|
|
|
3613
3714
|
};
|
|
3614
3715
|
}
|
|
3615
3716
|
case "doctor": {
|
|
3616
|
-
requireNoExtraArgs(rest, "
|
|
3717
|
+
requireNoExtraArgs(rest, "rig dist doctor");
|
|
3617
3718
|
const details = await runDistDoctor(context.projectRoot);
|
|
3618
3719
|
if (context.outputMode === "text") {
|
|
3619
3720
|
console.log(`bun: ${details.bun.available ? `ok (${details.bun.version})` : "missing"}`);
|
|
@@ -3624,7 +3725,7 @@ async function executeDist(context, args) {
|
|
|
3624
3725
|
return { ok: true, group: "dist", command, details };
|
|
3625
3726
|
}
|
|
3626
3727
|
case "rebuild-agent": {
|
|
3627
|
-
requireNoExtraArgs(rest, "
|
|
3728
|
+
requireNoExtraArgs(rest, "rig dist rebuild-agent");
|
|
3628
3729
|
const fp = await computeRuntimeImageFingerprint(context.projectRoot);
|
|
3629
3730
|
const currentId = computeRuntimeImageId(fp);
|
|
3630
3731
|
const imagesDir = resolve11(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
|
|
@@ -3769,6 +3870,7 @@ async function executeDist(context, args) {
|
|
|
3769
3870
|
}
|
|
3770
3871
|
|
|
3771
3872
|
// packages/cli/src/commands/inbox.ts
|
|
3873
|
+
init_runner();
|
|
3772
3874
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
3773
3875
|
import { resolve as resolve12 } from "path";
|
|
3774
3876
|
import {
|
|
@@ -3776,108 +3878,510 @@ import {
|
|
|
3776
3878
|
readJsonlFile as readJsonlFile3,
|
|
3777
3879
|
resolveAuthorityRunDir as resolveAuthorityRunDir2
|
|
3778
3880
|
} from "@rig/runtime/control-plane/authority-files";
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
return
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
+
|
|
3882
|
+
// packages/cli/src/commands/_cli-format.ts
|
|
3883
|
+
import { log as log3, note as note3 } from "@clack/prompts";
|
|
3884
|
+
import pc3 from "picocolors";
|
|
3885
|
+
function stringField(record, key, fallback = "") {
|
|
3886
|
+
const value = record[key];
|
|
3887
|
+
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
3888
|
+
}
|
|
3889
|
+
function numberField(record, key) {
|
|
3890
|
+
const value = record[key];
|
|
3891
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
3892
|
+
}
|
|
3893
|
+
function arrayField(record, key) {
|
|
3894
|
+
const value = record[key];
|
|
3895
|
+
return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
|
|
3896
|
+
}
|
|
3897
|
+
function rawObject(record) {
|
|
3898
|
+
const raw = record.raw;
|
|
3899
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
3900
|
+
}
|
|
3901
|
+
function truncate(value, width) {
|
|
3902
|
+
if (value.length <= width)
|
|
3903
|
+
return value;
|
|
3904
|
+
if (width <= 1)
|
|
3905
|
+
return "\u2026";
|
|
3906
|
+
return `${value.slice(0, width - 1)}\u2026`;
|
|
3907
|
+
}
|
|
3908
|
+
function pad(value, width) {
|
|
3909
|
+
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
3910
|
+
}
|
|
3911
|
+
function statusColor(status) {
|
|
3912
|
+
const normalized = status.toLowerCase();
|
|
3913
|
+
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
|
|
3914
|
+
return pc3.green;
|
|
3915
|
+
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
3916
|
+
return pc3.red;
|
|
3917
|
+
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
3918
|
+
return pc3.cyan;
|
|
3919
|
+
if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
|
|
3920
|
+
return pc3.yellow;
|
|
3921
|
+
return pc3.dim;
|
|
3922
|
+
}
|
|
3923
|
+
function compactDate(value) {
|
|
3924
|
+
if (!value.trim())
|
|
3925
|
+
return "";
|
|
3926
|
+
const parsed = Date.parse(value);
|
|
3927
|
+
if (!Number.isFinite(parsed))
|
|
3928
|
+
return value;
|
|
3929
|
+
return new Date(parsed).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z");
|
|
3930
|
+
}
|
|
3931
|
+
function compactValue(value) {
|
|
3932
|
+
if (value === null || value === undefined)
|
|
3933
|
+
return "";
|
|
3934
|
+
if (typeof value === "string")
|
|
3935
|
+
return value;
|
|
3936
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
3937
|
+
return String(value);
|
|
3938
|
+
if (Array.isArray(value))
|
|
3939
|
+
return value.map(compactValue).filter(Boolean).join(", ");
|
|
3940
|
+
return JSON.stringify(value);
|
|
3941
|
+
}
|
|
3942
|
+
function firstString(record, keys, fallback = "") {
|
|
3943
|
+
for (const key of keys) {
|
|
3944
|
+
const value = stringField(record, key);
|
|
3945
|
+
if (value)
|
|
3946
|
+
return value;
|
|
3947
|
+
}
|
|
3948
|
+
return fallback;
|
|
3949
|
+
}
|
|
3950
|
+
function runIdOf(run) {
|
|
3951
|
+
return firstString(run, ["runId", "id"], "(unknown-run)");
|
|
3952
|
+
}
|
|
3953
|
+
function taskIdOf(run) {
|
|
3954
|
+
return firstString(run, ["taskId", "task", "task_id"]);
|
|
3955
|
+
}
|
|
3956
|
+
function runTitleOf(run) {
|
|
3957
|
+
return firstString(run, ["title", "summary", "name"], taskIdOf(run) || "(untitled)");
|
|
3958
|
+
}
|
|
3959
|
+
function requestIdOf(entry) {
|
|
3960
|
+
return firstString(entry, ["requestId", "id", "approvalId", "inputId"], "(unknown-request)");
|
|
3961
|
+
}
|
|
3962
|
+
function shouldUseClackOutput() {
|
|
3963
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
3964
|
+
}
|
|
3965
|
+
function printFormattedOutput(message2, options = {}) {
|
|
3966
|
+
if (!shouldUseClackOutput()) {
|
|
3967
|
+
console.log(message2);
|
|
3968
|
+
return;
|
|
3969
|
+
}
|
|
3970
|
+
if (options.title)
|
|
3971
|
+
note3(message2, options.title);
|
|
3972
|
+
else
|
|
3973
|
+
log3.message(message2);
|
|
3974
|
+
}
|
|
3975
|
+
function formatStatusPill(status) {
|
|
3976
|
+
const label = status || "unknown";
|
|
3977
|
+
return statusColor(label)(`\u25CF ${label}`);
|
|
3978
|
+
}
|
|
3979
|
+
function formatSection(title, subtitle) {
|
|
3980
|
+
return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
3981
|
+
}
|
|
3982
|
+
function formatSuccessCard(title, rows = []) {
|
|
3983
|
+
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc3.dim("\u2502")} ${pc3.dim(key.padEnd(12))} ${value}`);
|
|
3984
|
+
return [formatSection(title), ...body].join(`
|
|
3985
|
+
`);
|
|
3986
|
+
}
|
|
3987
|
+
function formatNextSteps(steps) {
|
|
3988
|
+
if (steps.length === 0)
|
|
3989
|
+
return [];
|
|
3990
|
+
return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
|
|
3991
|
+
}
|
|
3992
|
+
function formatTaskList(tasks, options = {}) {
|
|
3993
|
+
if (options.raw)
|
|
3994
|
+
return tasks.map((task) => JSON.stringify(task)).join(`
|
|
3995
|
+
`);
|
|
3996
|
+
if (tasks.length === 0)
|
|
3997
|
+
return [formatSection("Tasks", "none found"), ...formatNextSteps(["Try `rig server status` to confirm the selected server.", "Relax filters or run `rig task run --title ... --initial-prompt ...` for ad hoc work."])].join(`
|
|
3998
|
+
`);
|
|
3999
|
+
const rows = tasks.map((task) => {
|
|
4000
|
+
const raw = rawObject(task);
|
|
4001
|
+
const id = stringField(task, "id", "<unknown>");
|
|
4002
|
+
const status = stringField(task, "status", "unknown");
|
|
4003
|
+
const title = stringField(task, "title", "Untitled task");
|
|
4004
|
+
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
4005
|
+
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
4006
|
+
return { id, status, title, source, labels };
|
|
4007
|
+
});
|
|
4008
|
+
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
4009
|
+
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
4010
|
+
const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
4011
|
+
const body = rows.map((row) => {
|
|
4012
|
+
const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
4013
|
+
const source = row.source ? pc3.dim(` ${row.source}`) : "";
|
|
4014
|
+
return [
|
|
4015
|
+
pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
4016
|
+
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
4017
|
+
`${row.title}${labels}${source}`
|
|
4018
|
+
].join(" ");
|
|
4019
|
+
});
|
|
4020
|
+
return [formatSection("Tasks", `${rows.length} shown`), header, ...body, "", ...formatNextSteps(["Run one: `rig task run <id>` or `rig task run --next`", "Attach later: `rig run attach <run-id> --follow`"])].join(`
|
|
4021
|
+
`);
|
|
4022
|
+
}
|
|
4023
|
+
function formatTaskCard(task, options = {}) {
|
|
4024
|
+
const raw = rawObject(task);
|
|
4025
|
+
const id = stringField(task, "id", stringField(raw, "id", "<unknown>"));
|
|
4026
|
+
const status = stringField(task, "status", stringField(raw, "status", "unknown"));
|
|
4027
|
+
const title = stringField(task, "title", stringField(raw, "title", "Untitled task"));
|
|
4028
|
+
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
4029
|
+
const url = stringField(task, "url", stringField(raw, "url", ""));
|
|
4030
|
+
const number = numberField(task, "number") ?? numberField(raw, "number");
|
|
4031
|
+
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
4032
|
+
const assignees = arrayField(task, "assignees").length > 0 ? arrayField(task, "assignees") : arrayField(raw, "assignees");
|
|
4033
|
+
const readiness = compactValue(task.readiness ?? raw.readiness);
|
|
4034
|
+
const validators = compactValue(task.validators ?? raw.validators ?? task.validation ?? raw.validation);
|
|
4035
|
+
const rows = [
|
|
4036
|
+
["task", pc3.bold(id)],
|
|
4037
|
+
["status", formatStatusPill(status)],
|
|
4038
|
+
["title", title],
|
|
4039
|
+
["source", source],
|
|
4040
|
+
["number", number],
|
|
4041
|
+
["labels", labels.length ? labels.map((label) => `#${label}`).join(" ") : ""],
|
|
4042
|
+
["assignees", assignees.join(", ")],
|
|
4043
|
+
["readiness", readiness],
|
|
4044
|
+
["validators", validators],
|
|
4045
|
+
["url", url]
|
|
4046
|
+
];
|
|
4047
|
+
return [
|
|
4048
|
+
formatSuccessCard(options.title ?? (options.selected ? "Selected task" : "Task"), rows),
|
|
4049
|
+
"",
|
|
4050
|
+
...formatNextSteps([`Start: \`rig task run ${id}\``, `Details: \`rig task show ${id} --raw\``])
|
|
4051
|
+
].join(`
|
|
4052
|
+
`);
|
|
4053
|
+
}
|
|
4054
|
+
function formatTaskDetails(task) {
|
|
4055
|
+
return formatTaskCard(task, { title: "Task details" });
|
|
4056
|
+
}
|
|
4057
|
+
function formatRunList(runs, options = {}) {
|
|
4058
|
+
if (runs.length === 0) {
|
|
4059
|
+
return [
|
|
4060
|
+
formatSection("Runs", "none recorded"),
|
|
4061
|
+
options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
|
|
4062
|
+
"",
|
|
4063
|
+
...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
|
|
4064
|
+
].join(`
|
|
4065
|
+
`);
|
|
4066
|
+
}
|
|
4067
|
+
const rows = runs.map((run) => {
|
|
4068
|
+
const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
|
|
4069
|
+
const status = stringField(run, "status", "unknown");
|
|
4070
|
+
const taskId = stringField(run, "taskId", "");
|
|
4071
|
+
const title = stringField(run, "title", taskId || "(untitled)");
|
|
4072
|
+
const runtime = stringField(run, "runtimeAdapter", "");
|
|
4073
|
+
return { runId, status, title, runtime };
|
|
4074
|
+
});
|
|
4075
|
+
const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
|
|
4076
|
+
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
4077
|
+
const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
4078
|
+
const body = rows.map((row) => [
|
|
4079
|
+
pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
|
|
4080
|
+
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
4081
|
+
`${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
|
|
4082
|
+
].join(" "));
|
|
4083
|
+
return [formatSection("Runs", options.source === "server" ? "selected server" : "local state"), header, ...body, "", ...formatNextSteps(["Follow live: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"])].join(`
|
|
4084
|
+
`);
|
|
4085
|
+
}
|
|
4086
|
+
function formatSubmittedRun(input) {
|
|
4087
|
+
const rows = [["run", pc3.bold(input.runId)]];
|
|
4088
|
+
if (input.task) {
|
|
4089
|
+
const id = stringField(input.task, "id", "<unknown>");
|
|
4090
|
+
const status = stringField(input.task, "status", "unknown");
|
|
4091
|
+
const title = stringField(input.task, "title", "Untitled task");
|
|
4092
|
+
rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
4093
|
+
}
|
|
4094
|
+
const runtime = [input.runtimeAdapter || "pi", input.runtimeMode || "full-access", input.interactionMode || "default"].filter(Boolean).join(" \xB7 ");
|
|
4095
|
+
rows.push(["runtime", runtime]);
|
|
4096
|
+
return [
|
|
4097
|
+
formatSuccessCard("Run submitted", rows),
|
|
4098
|
+
"",
|
|
4099
|
+
...formatNextSteps([
|
|
4100
|
+
`Attach: \`rig run attach ${input.runId} --follow\``,
|
|
4101
|
+
`Inspect: \`rig run show ${input.runId}\``,
|
|
4102
|
+
input.detached ? "Submitted detached; attach when you are ready." : "Interactive mode opens the native bundled Pi frontend."
|
|
4103
|
+
])
|
|
4104
|
+
].join(`
|
|
4105
|
+
`);
|
|
4106
|
+
}
|
|
4107
|
+
function formatRunCard(run, options = {}) {
|
|
4108
|
+
const raw = rawObject(run);
|
|
4109
|
+
const merged = { ...raw, ...run };
|
|
4110
|
+
const runId = runIdOf(merged);
|
|
4111
|
+
const status = firstString(merged, ["status"], "unknown");
|
|
4112
|
+
const taskId = taskIdOf(merged);
|
|
4113
|
+
const title = runTitleOf(merged);
|
|
4114
|
+
const runtime = firstString(merged, ["runtimeAdapter", "runtime", "adapter"]);
|
|
4115
|
+
const mode = firstString(merged, ["runtimeMode", "mode"]);
|
|
4116
|
+
const interaction = firstString(merged, ["interactionMode"]);
|
|
4117
|
+
const created = compactDate(firstString(merged, ["createdAt"]));
|
|
4118
|
+
const started = compactDate(firstString(merged, ["startedAt"]));
|
|
4119
|
+
const updated = compactDate(firstString(merged, ["updatedAt"]));
|
|
4120
|
+
const completed = compactDate(firstString(merged, ["completedAt", "finishedAt"]));
|
|
4121
|
+
const worktree = firstString(merged, ["worktreePath", "cwd", "projectRoot"]);
|
|
4122
|
+
const piSession = merged.piSession && typeof merged.piSession === "object" && !Array.isArray(merged.piSession) ? firstString(merged.piSession, ["sessionId", "id"]) : "";
|
|
4123
|
+
const timeline = Array.isArray(merged.timeline) ? merged.timeline.length : null;
|
|
4124
|
+
const approvals = Array.isArray(merged.approvals) ? merged.approvals.length : null;
|
|
4125
|
+
const inputs = Array.isArray(merged.userInputs) ? merged.userInputs.length : null;
|
|
4126
|
+
const rows = [
|
|
4127
|
+
["run", pc3.bold(runId)],
|
|
4128
|
+
["status", formatStatusPill(status)],
|
|
4129
|
+
["task", taskId],
|
|
4130
|
+
["title", title],
|
|
4131
|
+
["runtime", [runtime, mode, interaction].filter(Boolean).join(" \xB7 ")],
|
|
4132
|
+
["created", created],
|
|
4133
|
+
["started", started],
|
|
4134
|
+
["updated", updated],
|
|
4135
|
+
["completed", completed],
|
|
4136
|
+
["worktree", worktree],
|
|
4137
|
+
["pi", piSession],
|
|
4138
|
+
["timeline", timeline],
|
|
4139
|
+
["approvals", approvals],
|
|
4140
|
+
["inputs", inputs]
|
|
4141
|
+
];
|
|
4142
|
+
return [
|
|
4143
|
+
formatSuccessCard(options.title ?? "Run details", rows),
|
|
4144
|
+
"",
|
|
4145
|
+
...formatNextSteps([`Follow live: \`rig run attach ${runId} --follow\``, `Raw payload: \`rig run show ${runId} --raw\``])
|
|
4146
|
+
].join(`
|
|
4147
|
+
`);
|
|
4148
|
+
}
|
|
4149
|
+
function formatRunStatus(summary, options = {}) {
|
|
4150
|
+
const activeRuns = summary.activeRuns ?? [];
|
|
4151
|
+
const recentRuns = summary.recentRuns ?? [];
|
|
4152
|
+
const lines = [formatSection("Run status", options.source === "server" ? "selected server" : "local state")];
|
|
4153
|
+
lines.push("", pc3.bold(`Active runs (${activeRuns.length})`));
|
|
4154
|
+
if (activeRuns.length === 0) {
|
|
4155
|
+
lines.push(pc3.dim("No active runs."));
|
|
4156
|
+
} else {
|
|
4157
|
+
for (const run of activeRuns) {
|
|
4158
|
+
lines.push(formatRunSummaryLine(run));
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
lines.push("", pc3.bold(`Recent runs (${recentRuns.length})`));
|
|
4162
|
+
if (recentRuns.length === 0) {
|
|
4163
|
+
lines.push(pc3.dim("No recent terminal runs."));
|
|
4164
|
+
} else {
|
|
4165
|
+
for (const run of recentRuns.slice(0, 10)) {
|
|
4166
|
+
lines.push(formatRunSummaryLine(run));
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
lines.push("", ...formatNextSteps(["Start work: `rig task run --next`", "Attach: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"]));
|
|
4170
|
+
return lines.join(`
|
|
4171
|
+
`);
|
|
4172
|
+
}
|
|
4173
|
+
function formatRunSummaryLine(run) {
|
|
4174
|
+
const record = run;
|
|
4175
|
+
const runId = runIdOf(record);
|
|
4176
|
+
const status = firstString(record, ["status"], "unknown");
|
|
4177
|
+
const taskId = taskIdOf(record);
|
|
4178
|
+
const title = runTitleOf(record);
|
|
4179
|
+
const runtime = firstString(record, ["runtimeAdapter", "runtime", "adapter"]);
|
|
4180
|
+
const descriptor = [taskId, title].filter(Boolean).join(" \xB7 ");
|
|
4181
|
+
return `${pc3.dim("\u2502")} ${pc3.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? pc3.dim(` ${runtime}`) : ""}`;
|
|
4182
|
+
}
|
|
4183
|
+
function formatInboxList(kind, entries) {
|
|
4184
|
+
const title = kind === "approvals" ? "Approval inbox" : "Input inbox";
|
|
4185
|
+
if (entries.length === 0) {
|
|
4186
|
+
return [
|
|
4187
|
+
formatSection(title, "empty"),
|
|
4188
|
+
pc3.dim(kind === "approvals" ? "No pending approvals." : "No pending user-input requests."),
|
|
4189
|
+
"",
|
|
4190
|
+
...formatNextSteps(["Check runs: `rig run status`", "Start work: `rig task run --next`"])
|
|
4191
|
+
].join(`
|
|
4192
|
+
`);
|
|
4193
|
+
}
|
|
4194
|
+
const lines = [formatSection(title, `${entries.length} pending`)];
|
|
4195
|
+
for (const entry of entries) {
|
|
4196
|
+
const record = entry.record && typeof entry.record === "object" && !Array.isArray(entry.record) ? entry.record : entry;
|
|
4197
|
+
const runId = firstString(entry, ["runId"], firstString(record, ["runId"]));
|
|
4198
|
+
const taskId = firstString(entry, ["taskId"], firstString(record, ["taskId", "task"]));
|
|
4199
|
+
const requestId = requestIdOf(record);
|
|
4200
|
+
const status = firstString(record, ["status", "state"], "pending");
|
|
4201
|
+
const prompt = firstString(record, ["prompt", "message", "reason", "title", "summary"], kind === "approvals" ? "Approval requested" : "Input requested");
|
|
4202
|
+
lines.push(`${pc3.dim("\u2502")} ${pc3.bold(requestId)} ${formatStatusPill(status)} ${prompt}`);
|
|
4203
|
+
lines.push(`${pc3.dim("\u2502")} ${pc3.dim("run ")} ${runId || "(unknown-run)"}${taskId ? pc3.dim(` task ${taskId}`) : ""}`);
|
|
4204
|
+
}
|
|
4205
|
+
lines.push("", ...formatNextSteps(kind === "approvals" ? ["Resolve: `rig inbox approve --run <run-id> --request <request-id> --decision approve|reject`", "Rejoin: `rig run attach <run-id> --follow`"] : ["Respond: `rig inbox respond --run <run-id> --request <request-id> --answer key=value`", "Rejoin: `rig run attach <run-id> --follow`"]));
|
|
4206
|
+
return lines.join(`
|
|
4207
|
+
`);
|
|
4208
|
+
}
|
|
4209
|
+
function formatConnectionList(connections) {
|
|
4210
|
+
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
4211
|
+
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
4212
|
+
const lines = rows.map(([alias, connection]) => [
|
|
4213
|
+
pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
4214
|
+
formatStatusPill(connection.kind),
|
|
4215
|
+
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
4216
|
+
].join(" "));
|
|
4217
|
+
return [formatSection("Rig servers", `${rows.length} available`), `${pc3.bold(pad("ALIAS", aliasWidth))} ${pc3.bold("KIND")} ${pc3.bold("TARGET")}`, ...lines, "", ...formatNextSteps(["Select one: `rig server use <alias|local>`"])].join(`
|
|
4218
|
+
`);
|
|
4219
|
+
}
|
|
4220
|
+
function formatConnectionStatus(selected, connections) {
|
|
4221
|
+
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
4222
|
+
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
4223
|
+
return [
|
|
4224
|
+
formatSection("Rig server", "selected for this repo"),
|
|
4225
|
+
`${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
|
|
4226
|
+
`${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
4227
|
+
`${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
|
|
4228
|
+
"",
|
|
4229
|
+
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
4230
|
+
].join(`
|
|
4231
|
+
`);
|
|
4232
|
+
}
|
|
4233
|
+
|
|
4234
|
+
// packages/cli/src/commands/inbox.ts
|
|
4235
|
+
function isRemoteConnectionSelected(projectRoot) {
|
|
4236
|
+
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
4237
|
+
}
|
|
4238
|
+
function runMatches(entry, filters) {
|
|
4239
|
+
const runId = typeof entry.runId === "string" ? entry.runId : typeof entry.id === "string" ? entry.id : "";
|
|
4240
|
+
const taskId = typeof entry.taskId === "string" ? entry.taskId : "";
|
|
4241
|
+
return (!filters.run || runId === filters.run) && (!filters.task || taskId === filters.task);
|
|
4242
|
+
}
|
|
4243
|
+
function normalizeRemoteRunDetails(payload) {
|
|
4244
|
+
const run = payload.run;
|
|
4245
|
+
if (run && typeof run === "object" && !Array.isArray(run)) {
|
|
4246
|
+
return {
|
|
4247
|
+
...run,
|
|
4248
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
4249
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
4250
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
4251
|
+
};
|
|
4252
|
+
}
|
|
4253
|
+
return payload;
|
|
4254
|
+
}
|
|
4255
|
+
function remoteRecordsFromRun(run, kind) {
|
|
4256
|
+
const key = kind === "approvals" ? "approvals" : "userInputs";
|
|
4257
|
+
const direct = run[key];
|
|
4258
|
+
if (!Array.isArray(direct))
|
|
4259
|
+
return [];
|
|
4260
|
+
const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
|
|
4261
|
+
const taskId = typeof run.taskId === "string" ? run.taskId : "";
|
|
4262
|
+
return direct.filter((record) => Boolean(record && typeof record === "object" && !Array.isArray(record))).map((record) => ({ runId, taskId, record }));
|
|
4263
|
+
}
|
|
4264
|
+
async function listRemoteInboxRecords(context, kind, filters) {
|
|
4265
|
+
const runs = (await listRunsViaServer(context, { limit: 100 })).filter((entry) => runMatches(entry, filters));
|
|
4266
|
+
const records = [];
|
|
4267
|
+
for (const run of runs) {
|
|
4268
|
+
const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
|
|
4269
|
+
const detailed = runId ? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, runId).catch(() => run)) : run;
|
|
4270
|
+
records.push(...remoteRecordsFromRun(detailed, kind));
|
|
4271
|
+
}
|
|
4272
|
+
return records;
|
|
4273
|
+
}
|
|
4274
|
+
function listLocalInboxRecords(context, kind, filters) {
|
|
4275
|
+
const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
|
|
4276
|
+
const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
|
|
4277
|
+
return runs.flatMap((entry) => readJsonlFile3(resolve12(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
|
|
4278
|
+
runId: entry.runId,
|
|
4279
|
+
taskId: entry.taskId ?? undefined,
|
|
4280
|
+
record
|
|
4281
|
+
})));
|
|
4282
|
+
}
|
|
4283
|
+
async function listInboxRecords(context, kind, filters) {
|
|
4284
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4285
|
+
return listRemoteInboxRecords(context, kind, filters);
|
|
4286
|
+
}
|
|
4287
|
+
return listLocalInboxRecords(context, kind, filters);
|
|
4288
|
+
}
|
|
4289
|
+
async function executeInbox(context, args) {
|
|
4290
|
+
const [command = "approvals", ...rest] = args;
|
|
4291
|
+
switch (command) {
|
|
4292
|
+
case "approvals": {
|
|
4293
|
+
let pending = rest;
|
|
4294
|
+
const run = takeOption(pending, "--run");
|
|
4295
|
+
pending = run.rest;
|
|
4296
|
+
const task = takeOption(pending, "--task");
|
|
4297
|
+
pending = task.rest;
|
|
4298
|
+
requireNoExtraArgs(pending, "rig inbox approvals [--run <id>] [--task <id>]");
|
|
4299
|
+
const approvals = await listInboxRecords(context, "approvals", { run: run.value, task: task.value });
|
|
4300
|
+
if (context.outputMode === "text") {
|
|
4301
|
+
printFormattedOutput(formatInboxList("approvals", approvals));
|
|
4302
|
+
}
|
|
4303
|
+
return { ok: true, group: "inbox", command, details: { approvals } };
|
|
4304
|
+
}
|
|
4305
|
+
case "approve": {
|
|
4306
|
+
let pending = rest;
|
|
4307
|
+
const run = takeOption(pending, "--run");
|
|
4308
|
+
pending = run.rest;
|
|
4309
|
+
const request = takeOption(pending, "--request");
|
|
4310
|
+
pending = request.rest;
|
|
4311
|
+
const decision = takeOption(pending, "--decision");
|
|
4312
|
+
pending = decision.rest;
|
|
4313
|
+
const note4 = takeOption(pending, "--note");
|
|
4314
|
+
pending = note4.rest;
|
|
4315
|
+
requireNoExtraArgs(pending, "rig inbox approve --run <id> --request <id> --decision approve|reject [--note <text>]");
|
|
4316
|
+
if (!run.value || !request.value || !decision.value) {
|
|
4317
|
+
throw new CliError2("approve requires --run, --request, and --decision.");
|
|
4318
|
+
}
|
|
4319
|
+
if (decision.value !== "approve" && decision.value !== "reject") {
|
|
4320
|
+
throw new CliError2("decision must be approve or reject.");
|
|
4321
|
+
}
|
|
4322
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4323
|
+
throw new CliError2("Remote approval resolution is not available from this CLI yet; use the server UI/API or switch to local state for direct JSONL edits.", 2);
|
|
4324
|
+
}
|
|
4325
|
+
const approvalsPath = resolve12(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
|
|
4326
|
+
const approvals = readJsonlFile3(approvalsPath);
|
|
4327
|
+
const resolvedAt = new Date().toISOString();
|
|
4328
|
+
const next = approvals.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", decision: decision.value, note: note4.value ?? null, resolvedAt } : entry);
|
|
4329
|
+
writeFileSync4(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
|
|
4330
|
+
`)}
|
|
4331
|
+
`, "utf8");
|
|
4332
|
+
return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, decision: decision.value } };
|
|
4333
|
+
}
|
|
4334
|
+
case "inputs": {
|
|
4335
|
+
let pending = rest;
|
|
4336
|
+
const run = takeOption(pending, "--run");
|
|
4337
|
+
pending = run.rest;
|
|
4338
|
+
const task = takeOption(pending, "--task");
|
|
4339
|
+
pending = task.rest;
|
|
4340
|
+
requireNoExtraArgs(pending, "rig inbox inputs [--run <id>] [--task <id>]");
|
|
4341
|
+
const requests = await listInboxRecords(context, "inputs", { run: run.value, task: task.value });
|
|
4342
|
+
if (context.outputMode === "text") {
|
|
4343
|
+
printFormattedOutput(formatInboxList("inputs", requests));
|
|
4344
|
+
}
|
|
4345
|
+
return { ok: true, group: "inbox", command, details: { requests } };
|
|
4346
|
+
}
|
|
4347
|
+
case "respond": {
|
|
4348
|
+
let pending = rest;
|
|
4349
|
+
const run = takeOption(pending, "--run");
|
|
4350
|
+
pending = run.rest;
|
|
4351
|
+
const request = takeOption(pending, "--request");
|
|
4352
|
+
pending = request.rest;
|
|
4353
|
+
const answers = [];
|
|
4354
|
+
const remaining = [];
|
|
4355
|
+
for (let index = 0;index < pending.length; index += 1) {
|
|
4356
|
+
const current = pending[index];
|
|
4357
|
+
if (current === "--answer") {
|
|
4358
|
+
const next2 = pending[index + 1];
|
|
4359
|
+
if (!next2 || next2.startsWith("-")) {
|
|
4360
|
+
throw new CliError2("Missing value for --answer");
|
|
4361
|
+
}
|
|
4362
|
+
answers.push(next2);
|
|
4363
|
+
index += 1;
|
|
4364
|
+
continue;
|
|
4365
|
+
}
|
|
4366
|
+
if (current !== undefined) {
|
|
4367
|
+
remaining.push(current);
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
requireNoExtraArgs(remaining, "rig inbox respond --run <id> --request <id> --answer key=value [--answer key=value]");
|
|
4371
|
+
if (!run.value || !request.value || answers.length === 0) {
|
|
4372
|
+
throw new CliError2("respond requires --run, --request, and at least one --answer.");
|
|
4373
|
+
}
|
|
4374
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4375
|
+
throw new CliError2("Remote input responses are not available from this CLI yet; use the server UI/API or switch to local state for direct JSONL edits.", 2);
|
|
4376
|
+
}
|
|
4377
|
+
const parsedAnswers = Object.fromEntries(answers.map((entry) => {
|
|
4378
|
+
const [key, ...restValue] = entry.split("=");
|
|
4379
|
+
return [key, restValue.join("=")];
|
|
4380
|
+
}));
|
|
4381
|
+
const requestsPath = resolve12(resolveAuthorityRunDir2(context.projectRoot, run.value), "user-input.jsonl");
|
|
4382
|
+
const requests = readJsonlFile3(requestsPath);
|
|
4383
|
+
const resolvedAt = new Date().toISOString();
|
|
4384
|
+
const next = requests.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", answers: parsedAnswers, respondedAt: resolvedAt, resolvedAt } : entry);
|
|
3881
4385
|
writeFileSync4(requestsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
|
|
3882
4386
|
`)}
|
|
3883
4387
|
`, "utf8");
|
|
@@ -3889,6 +4393,7 @@ async function executeInbox(context, args) {
|
|
|
3889
4393
|
}
|
|
3890
4394
|
|
|
3891
4395
|
// packages/cli/src/commands/init.ts
|
|
4396
|
+
init_runner();
|
|
3892
4397
|
import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
3893
4398
|
import { spawnSync } from "child_process";
|
|
3894
4399
|
import { resolve as resolve16 } from "path";
|
|
@@ -4164,9 +4669,11 @@ async function uploadSnapshotArchiveViaServer(context, input) {
|
|
|
4164
4669
|
}
|
|
4165
4670
|
|
|
4166
4671
|
// packages/cli/src/commands/_doctor-checks.ts
|
|
4672
|
+
init_runner();
|
|
4167
4673
|
import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
|
|
4168
4674
|
import { resolve as resolve15 } from "path";
|
|
4169
4675
|
import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
|
|
4676
|
+
init__parsers();
|
|
4170
4677
|
function check(id, label, status, detail, remediation) {
|
|
4171
4678
|
return {
|
|
4172
4679
|
id,
|
|
@@ -4293,7 +4800,7 @@ async function runRigDoctorChecks(options) {
|
|
|
4293
4800
|
const taskSourceKind = config?.taskSource?.kind;
|
|
4294
4801
|
checks.push(taskSourceKind ? check("task-source", "task source configured", "pass", taskSourceKind) : check("task-source", "task source configured", "fail", "missing taskSource", "Configure taskSource in rig.config.ts."));
|
|
4295
4802
|
const repo = readRepoConnection(projectRoot);
|
|
4296
|
-
checks.push(repo ? check("project-link", "repo selected Rig
|
|
4803
|
+
checks.push(repo ? check("project-link", "repo selected Rig server", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to link this checkout to a GitHub repo slug.") : check("project-link", "repo selected Rig server", "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
|
|
4297
4804
|
const selected = (() => {
|
|
4298
4805
|
try {
|
|
4299
4806
|
return resolveSelectedConnection(projectRoot);
|
|
@@ -4301,7 +4808,7 @@ async function runRigDoctorChecks(options) {
|
|
|
4301
4808
|
return null;
|
|
4302
4809
|
}
|
|
4303
4810
|
})();
|
|
4304
|
-
checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server
|
|
4811
|
+
checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server", repo ? "fail" : "warn", repo ? "selected alias is missing" : "will auto-start local server", repo ? "Run `rig server list` and `rig server use <alias|local>`." : undefined));
|
|
4305
4812
|
let server = null;
|
|
4306
4813
|
try {
|
|
4307
4814
|
server = await (options.resolveServer ?? ensureServerForCli)(projectRoot);
|
|
@@ -5097,174 +5604,20 @@ async function runInteractiveControlPlaneInit(context, prompts) {
|
|
|
5097
5604
|
async function executeInit(context, args) {
|
|
5098
5605
|
const parsed = parseInitOptions(args);
|
|
5099
5606
|
if (parsed.options.yes || parsed.options.server || parsed.options.repoSlug || parsed.options.githubToken || parsed.options.privateStateOnly || parsed.options.repair || parsed.options.githubAuthMethod || parsed.options.remoteCheckout) {
|
|
5100
|
-
if (parsed.rest.length > 0)
|
|
5101
|
-
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5102
|
-
Usage: rig init [--server local|remote] [--remote-url <url>] [--repo owner/repo] [--github-auth gh|token|device|skip] [--github-token <token>] [--github-project off|<project-id>] [--remote-checkout managed-clone|current-ref|uploaded-snapshot|existing-path] [--yes]`, 1);
|
|
5103
|
-
return runControlPlaneInit(context, parsed.options);
|
|
5104
|
-
}
|
|
5105
|
-
if (parsed.rest.length > 0)
|
|
5106
|
-
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5107
|
-
Usage: rig init`, 1);
|
|
5108
|
-
return runInteractiveControlPlaneInit(context, await loadClackPrompts());
|
|
5109
|
-
}
|
|
5110
|
-
|
|
5111
|
-
// packages/cli/src/commands/connect.ts
|
|
5112
|
-
import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
|
|
5113
|
-
|
|
5114
|
-
// packages/cli/src/commands/_cli-format.ts
|
|
5115
|
-
import pc3 from "picocolors";
|
|
5116
|
-
function stringField(record, key, fallback = "") {
|
|
5117
|
-
const value = record[key];
|
|
5118
|
-
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
5119
|
-
}
|
|
5120
|
-
function arrayField(record, key) {
|
|
5121
|
-
const value = record[key];
|
|
5122
|
-
return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
|
|
5123
|
-
}
|
|
5124
|
-
function rawObject(record) {
|
|
5125
|
-
const raw = record.raw;
|
|
5126
|
-
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
5127
|
-
}
|
|
5128
|
-
function truncate(value, width) {
|
|
5129
|
-
if (value.length <= width)
|
|
5130
|
-
return value;
|
|
5131
|
-
if (width <= 1)
|
|
5132
|
-
return "\u2026";
|
|
5133
|
-
return `${value.slice(0, width - 1)}\u2026`;
|
|
5134
|
-
}
|
|
5135
|
-
function pad(value, width) {
|
|
5136
|
-
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
5137
|
-
}
|
|
5138
|
-
function statusColor(status) {
|
|
5139
|
-
const normalized = status.toLowerCase();
|
|
5140
|
-
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected"].includes(normalized))
|
|
5141
|
-
return pc3.green;
|
|
5142
|
-
if (["failed", "needs_attention", "needs-attention", "blocked", "error"].includes(normalized))
|
|
5143
|
-
return pc3.red;
|
|
5144
|
-
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
5145
|
-
return pc3.cyan;
|
|
5146
|
-
if (["ready", "open", "queued", "created", "preparing", "local"].includes(normalized))
|
|
5147
|
-
return pc3.yellow;
|
|
5148
|
-
return pc3.dim;
|
|
5149
|
-
}
|
|
5150
|
-
function formatStatusPill(status) {
|
|
5151
|
-
const label = status || "unknown";
|
|
5152
|
-
return statusColor(label)(`\u25CF ${label}`);
|
|
5153
|
-
}
|
|
5154
|
-
function formatSection(title, subtitle) {
|
|
5155
|
-
return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
5156
|
-
}
|
|
5157
|
-
function formatSuccessCard(title, rows = []) {
|
|
5158
|
-
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc3.dim("\u2502")} ${pc3.dim(key.padEnd(9))} ${value}`);
|
|
5159
|
-
return [formatSection(title), ...body].join(`
|
|
5160
|
-
`);
|
|
5161
|
-
}
|
|
5162
|
-
function formatNextSteps(steps) {
|
|
5163
|
-
if (steps.length === 0)
|
|
5164
|
-
return [];
|
|
5165
|
-
return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
|
|
5166
|
-
}
|
|
5167
|
-
function formatTaskList(tasks, options = {}) {
|
|
5168
|
-
if (options.raw)
|
|
5169
|
-
return tasks.map((task) => JSON.stringify(task)).join(`
|
|
5170
|
-
`);
|
|
5171
|
-
if (tasks.length === 0)
|
|
5172
|
-
return [formatSection("Tasks", "none found"), ...formatNextSteps(["Try `rig server status` to confirm the selected server.", "Relax filters or run `rig task run --title ... --initial-prompt ...` for ad hoc work."])].join(`
|
|
5173
|
-
`);
|
|
5174
|
-
const rows = tasks.map((task) => {
|
|
5175
|
-
const raw = rawObject(task);
|
|
5176
|
-
const id = stringField(task, "id", "<unknown>");
|
|
5177
|
-
const status = stringField(task, "status", "unknown");
|
|
5178
|
-
const title = stringField(task, "title", "Untitled task");
|
|
5179
|
-
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
5180
|
-
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
5181
|
-
return { id, status, title, source, labels };
|
|
5182
|
-
});
|
|
5183
|
-
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
5184
|
-
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
5185
|
-
const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
5186
|
-
const body = rows.map((row) => {
|
|
5187
|
-
const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
5188
|
-
const source = row.source ? pc3.dim(` ${row.source}`) : "";
|
|
5189
|
-
return [
|
|
5190
|
-
pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
5191
|
-
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
5192
|
-
`${row.title}${labels}${source}`
|
|
5193
|
-
].join(" ");
|
|
5194
|
-
});
|
|
5195
|
-
return [formatSection("Tasks", `${rows.length} shown`), header, ...body, "", ...formatNextSteps(["Run one: `rig task run <id>` or `rig task run --next`", "Attach later: `rig run attach <run-id> --follow`"])].join(`
|
|
5196
|
-
`);
|
|
5197
|
-
}
|
|
5198
|
-
function formatRunList(runs, options = {}) {
|
|
5199
|
-
if (runs.length === 0) {
|
|
5200
|
-
return [
|
|
5201
|
-
formatSection("Runs", "none recorded"),
|
|
5202
|
-
options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
|
|
5203
|
-
"",
|
|
5204
|
-
...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
|
|
5205
|
-
].join(`
|
|
5206
|
-
`);
|
|
5207
|
-
}
|
|
5208
|
-
const rows = runs.map((run) => {
|
|
5209
|
-
const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
|
|
5210
|
-
const status = stringField(run, "status", "unknown");
|
|
5211
|
-
const taskId = stringField(run, "taskId", "");
|
|
5212
|
-
const title = stringField(run, "title", taskId || "(untitled)");
|
|
5213
|
-
const runtime = stringField(run, "runtimeAdapter", "");
|
|
5214
|
-
return { runId, status, title, runtime };
|
|
5215
|
-
});
|
|
5216
|
-
const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
|
|
5217
|
-
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
5218
|
-
const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
5219
|
-
const body = rows.map((row) => [
|
|
5220
|
-
pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
|
|
5221
|
-
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
5222
|
-
`${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
|
|
5223
|
-
].join(" "));
|
|
5224
|
-
return [formatSection("Runs", options.source === "server" ? "selected server" : "local state"), header, ...body, "", ...formatNextSteps(["Follow live: `rig run attach <run-id> --follow`", "Details: `rig run show --run <run-id>`"])].join(`
|
|
5225
|
-
`);
|
|
5226
|
-
}
|
|
5227
|
-
function formatSubmittedRun(input) {
|
|
5228
|
-
const rows = [["run", pc3.bold(input.runId)]];
|
|
5229
|
-
if (input.task) {
|
|
5230
|
-
const id = stringField(input.task, "id", "<unknown>");
|
|
5231
|
-
const status = stringField(input.task, "status", "unknown");
|
|
5232
|
-
const title = stringField(input.task, "title", "Untitled task");
|
|
5233
|
-
rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
5234
|
-
}
|
|
5235
|
-
return [
|
|
5236
|
-
formatSuccessCard("Run submitted", rows),
|
|
5237
|
-
"",
|
|
5238
|
-
...formatNextSteps([`Attach: \`rig run attach ${input.runId} --follow\``, `Inspect: \`rig run show --run ${input.runId}\``])
|
|
5239
|
-
].join(`
|
|
5240
|
-
`);
|
|
5241
|
-
}
|
|
5242
|
-
function formatConnectionList(connections) {
|
|
5243
|
-
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
5244
|
-
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
5245
|
-
const lines = rows.map(([alias, connection]) => [
|
|
5246
|
-
pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
5247
|
-
formatStatusPill(connection.kind),
|
|
5248
|
-
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
5249
|
-
].join(" "));
|
|
5250
|
-
return [formatSection("Rig servers", `${rows.length} available`), `${pc3.bold(pad("ALIAS", aliasWidth))} ${pc3.bold("KIND")} ${pc3.bold("TARGET")}`, ...lines, "", ...formatNextSteps(["Select one: `rig server use <alias|local>`"])].join(`
|
|
5251
|
-
`);
|
|
5252
|
-
}
|
|
5253
|
-
function formatConnectionStatus(selected, connections) {
|
|
5254
|
-
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
5255
|
-
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
5256
|
-
return [
|
|
5257
|
-
formatSection("Rig server", "selected for this repo"),
|
|
5258
|
-
`${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
|
|
5259
|
-
`${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
5260
|
-
`${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
|
|
5261
|
-
"",
|
|
5262
|
-
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
5263
|
-
].join(`
|
|
5264
|
-
`);
|
|
5607
|
+
if (parsed.rest.length > 0)
|
|
5608
|
+
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5609
|
+
Usage: rig init [--server local|remote] [--remote-url <url>] [--repo owner/repo] [--github-auth gh|token|device|skip] [--github-token <token>] [--github-project off|<project-id>] [--remote-checkout managed-clone|current-ref|uploaded-snapshot|existing-path] [--yes]`, 1);
|
|
5610
|
+
return runControlPlaneInit(context, parsed.options);
|
|
5611
|
+
}
|
|
5612
|
+
if (parsed.rest.length > 0)
|
|
5613
|
+
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5614
|
+
Usage: rig init`, 1);
|
|
5615
|
+
return runInteractiveControlPlaneInit(context, await loadClackPrompts());
|
|
5265
5616
|
}
|
|
5266
5617
|
|
|
5267
5618
|
// packages/cli/src/commands/connect.ts
|
|
5619
|
+
init_runner();
|
|
5620
|
+
import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
|
|
5268
5621
|
function usageName(options) {
|
|
5269
5622
|
return `rig ${options.group}`;
|
|
5270
5623
|
}
|
|
@@ -5376,6 +5729,7 @@ async function executeConnect(context, args) {
|
|
|
5376
5729
|
}
|
|
5377
5730
|
|
|
5378
5731
|
// packages/cli/src/commands/github.ts
|
|
5732
|
+
init_runner();
|
|
5379
5733
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
5380
5734
|
function printPayload(context, payload, fallback) {
|
|
5381
5735
|
if (context.outputMode === "json")
|
|
@@ -5431,6 +5785,7 @@ async function executeGithub(context, args) {
|
|
|
5431
5785
|
}
|
|
5432
5786
|
|
|
5433
5787
|
// packages/cli/src/commands/doctor.ts
|
|
5788
|
+
init_runner();
|
|
5434
5789
|
async function executeDoctor(context, args) {
|
|
5435
5790
|
requireNoExtraArgs(args, "rig doctor");
|
|
5436
5791
|
const checks = await runRigDoctorChecks({ projectRoot: context.projectRoot });
|
|
@@ -5446,6 +5801,7 @@ async function executeDoctor(context, args) {
|
|
|
5446
5801
|
}
|
|
5447
5802
|
|
|
5448
5803
|
// packages/cli/src/commands/_run-driver-helpers.ts
|
|
5804
|
+
init_runner();
|
|
5449
5805
|
import { readFileSync as readFileSync7 } from "fs";
|
|
5450
5806
|
import { resolve as resolve17 } from "path";
|
|
5451
5807
|
import {
|
|
@@ -5673,6 +6029,7 @@ function renderSourceScopeValidation(task, validation) {
|
|
|
5673
6029
|
}
|
|
5674
6030
|
|
|
5675
6031
|
// packages/cli/src/commands/inspect.ts
|
|
6032
|
+
init_runner();
|
|
5676
6033
|
import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
|
|
5677
6034
|
import { resolve as resolve18 } from "path";
|
|
5678
6035
|
import {
|
|
@@ -5689,8 +6046,8 @@ async function executeInspect(context, args) {
|
|
|
5689
6046
|
switch (command) {
|
|
5690
6047
|
case "logs": {
|
|
5691
6048
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5692
|
-
requireNoExtraArgs(remaining, "
|
|
5693
|
-
const requiredTask = requireTask(task, "
|
|
6049
|
+
requireNoExtraArgs(remaining, "rig inspect logs --task <task-id>");
|
|
6050
|
+
const requiredTask = requireTask(task, "rig inspect logs --task <task-id>");
|
|
5694
6051
|
const latestRun = listAuthorityRuns2(context.projectRoot).map((entry) => readAuthorityRun3(context.projectRoot, entry.runId)).filter((run) => Boolean(run)).filter((run) => run.taskId === requiredTask).sort((left, right) => String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? "")))[0];
|
|
5695
6052
|
if (!latestRun) {
|
|
5696
6053
|
throw new CliError2(`No runs found for ${requiredTask}.`);
|
|
@@ -5704,8 +6061,8 @@ async function executeInspect(context, args) {
|
|
|
5704
6061
|
}
|
|
5705
6062
|
case "artifacts": {
|
|
5706
6063
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5707
|
-
requireNoExtraArgs(remaining, "
|
|
5708
|
-
const requiredTask = requireTask(task, "
|
|
6064
|
+
requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
|
|
6065
|
+
const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
|
|
5709
6066
|
const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync10(path));
|
|
5710
6067
|
if (!artifactRoot) {
|
|
5711
6068
|
throw new CliError2(`No artifacts found for ${requiredTask}.`);
|
|
@@ -5719,8 +6076,8 @@ async function executeInspect(context, args) {
|
|
|
5719
6076
|
previewPending = task.rest;
|
|
5720
6077
|
const file = takeOption(previewPending, "--file");
|
|
5721
6078
|
previewPending = file.rest;
|
|
5722
|
-
requireNoExtraArgs(previewPending, "
|
|
5723
|
-
const requiredTask = requireTask(task.value, "
|
|
6079
|
+
requireNoExtraArgs(previewPending, "rig inspect artifact --task <task-id> --file <name>");
|
|
6080
|
+
const requiredTask = requireTask(task.value, "rig inspect artifact --task <task-id> --file <name>");
|
|
5724
6081
|
if (!file.value) {
|
|
5725
6082
|
throw new CliError2("Missing --file for rig inspect artifact.");
|
|
5726
6083
|
}
|
|
@@ -5749,7 +6106,7 @@ async function executeInspect(context, args) {
|
|
|
5749
6106
|
}
|
|
5750
6107
|
case "diff": {
|
|
5751
6108
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5752
|
-
requireNoExtraArgs(remaining, "
|
|
6109
|
+
requireNoExtraArgs(remaining, "rig inspect diff [--task <task-id>]");
|
|
5753
6110
|
if (task) {
|
|
5754
6111
|
const files = changedFilesForTask(context.projectRoot, task, false);
|
|
5755
6112
|
for (const file of files) {
|
|
@@ -5761,7 +6118,7 @@ async function executeInspect(context, args) {
|
|
|
5761
6118
|
return { ok: true, group: "inspect", command, details: { task: task || null } };
|
|
5762
6119
|
}
|
|
5763
6120
|
case "failures": {
|
|
5764
|
-
requireNoExtraArgs(rest, "
|
|
6121
|
+
requireNoExtraArgs(rest, "rig inspect failures");
|
|
5765
6122
|
const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
|
|
5766
6123
|
if (!existsSync10(failed)) {
|
|
5767
6124
|
console.log("No failures recorded.");
|
|
@@ -5771,7 +6128,7 @@ async function executeInspect(context, args) {
|
|
|
5771
6128
|
return { ok: true, group: "inspect", command };
|
|
5772
6129
|
}
|
|
5773
6130
|
case "graph":
|
|
5774
|
-
requireNoExtraArgs(rest, "
|
|
6131
|
+
requireNoExtraArgs(rest, "rig inspect graph");
|
|
5775
6132
|
{
|
|
5776
6133
|
const monorepoRoot = resolveMonorepoRoot2(context.projectRoot);
|
|
5777
6134
|
const result = runCapture3(["br", "--no-db", "list", "--pretty"], monorepoRoot);
|
|
@@ -5782,7 +6139,7 @@ async function executeInspect(context, args) {
|
|
|
5782
6139
|
}
|
|
5783
6140
|
return { ok: true, group: "inspect", command };
|
|
5784
6141
|
case "audit": {
|
|
5785
|
-
requireNoExtraArgs(rest, "
|
|
6142
|
+
requireNoExtraArgs(rest, "rig inspect audit");
|
|
5786
6143
|
const auditPath = resolve18(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
5787
6144
|
if (!existsSync10(auditPath)) {
|
|
5788
6145
|
console.log("No audit log found.");
|
|
@@ -5800,6 +6157,8 @@ async function executeInspect(context, args) {
|
|
|
5800
6157
|
}
|
|
5801
6158
|
|
|
5802
6159
|
// packages/cli/src/commands/inspector.ts
|
|
6160
|
+
init_runner();
|
|
6161
|
+
init__parsers();
|
|
5803
6162
|
import { iterateServerSentEvents } from "@rig/client";
|
|
5804
6163
|
import { ensureLocalRigServerConnection as ensureLocalRigServerConnection2 } from "@rig/runtime/local-server";
|
|
5805
6164
|
function formatInspectorStreamLine(payload) {
|
|
@@ -5841,7 +6200,7 @@ async function executeInspector(context, args) {
|
|
|
5841
6200
|
pending = secondsResult.rest;
|
|
5842
6201
|
const pollMsResult = takeOption(pending, "--poll-ms");
|
|
5843
6202
|
pending = pollMsResult.rest;
|
|
5844
|
-
requireNoExtraArgs(pending, "
|
|
6203
|
+
requireNoExtraArgs(pending, "rig inspector stream [--once] [--seconds <n>] [--poll-ms <n>]");
|
|
5845
6204
|
const seconds = secondsResult.value ? parseRequiredPositiveInt(secondsResult.value, "--seconds") : null;
|
|
5846
6205
|
const pollMs = pollMsResult.value ? parseRequiredPositiveInt(pollMsResult.value, "--poll-ms") : null;
|
|
5847
6206
|
if (context.outputMode === "json" && !onceResult.value && !seconds) {
|
|
@@ -5935,7 +6294,7 @@ async function executeInspector(context, args) {
|
|
|
5935
6294
|
let pending = rest;
|
|
5936
6295
|
const scanIdResult = takeOption(pending, "--scan-id");
|
|
5937
6296
|
pending = scanIdResult.rest;
|
|
5938
|
-
requireNoExtraArgs(pending, "
|
|
6297
|
+
requireNoExtraArgs(pending, "rig inspector scan-upstream-drift [--scan-id <id>]");
|
|
5939
6298
|
const connection = await ensureLocalRigServerConnection2(context.projectRoot);
|
|
5940
6299
|
const response = await fetch(new URL("/api/inspector/tools/invoke", connection.baseUrl), {
|
|
5941
6300
|
method: "POST",
|
|
@@ -5990,6 +6349,8 @@ async function executeInspector(context, args) {
|
|
|
5990
6349
|
}
|
|
5991
6350
|
|
|
5992
6351
|
// packages/cli/src/commands/remote.ts
|
|
6352
|
+
init_runner();
|
|
6353
|
+
init__parsers();
|
|
5993
6354
|
import {
|
|
5994
6355
|
doctorManagedRemoteEndpoints,
|
|
5995
6356
|
listManagedRemoteEndpoints,
|
|
@@ -6046,7 +6407,7 @@ async function executeRemote(context, args) {
|
|
|
6046
6407
|
const [subcommand = "list", ...subRest] = rest;
|
|
6047
6408
|
switch (subcommand) {
|
|
6048
6409
|
case "list": {
|
|
6049
|
-
requireNoExtraArgs(subRest, "
|
|
6410
|
+
requireNoExtraArgs(subRest, "rig remote endpoint list");
|
|
6050
6411
|
const endpoints = listManagedRemoteEndpoints(undefined, context.projectRoot);
|
|
6051
6412
|
const redactedEndpoints = endpoints.map((endpoint2) => redactRemoteEndpoint(endpoint2));
|
|
6052
6413
|
if (context.outputMode === "text") {
|
|
@@ -6070,7 +6431,7 @@ async function executeRemote(context, args) {
|
|
|
6070
6431
|
pending2 = port.rest;
|
|
6071
6432
|
const token = takeOption(pending2, "--token");
|
|
6072
6433
|
pending2 = token.rest;
|
|
6073
|
-
requireNoExtraArgs(pending2, "
|
|
6434
|
+
requireNoExtraArgs(pending2, "rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>");
|
|
6074
6435
|
if (!alias.value || !host.value || !token.value || !port.value) {
|
|
6075
6436
|
throw new CliError2("remote endpoint add requires --alias, --host, --port, and --token.");
|
|
6076
6437
|
}
|
|
@@ -6097,7 +6458,7 @@ async function executeRemote(context, args) {
|
|
|
6097
6458
|
pending2 = port.rest;
|
|
6098
6459
|
const token = takeOption(pending2, "--token");
|
|
6099
6460
|
pending2 = token.rest;
|
|
6100
|
-
requireNoExtraArgs(pending2, "
|
|
6461
|
+
requireNoExtraArgs(pending2, "rig remote endpoint update --id <id> [--alias <a>] [--host <h>] [--port <n>] [--token <t>]");
|
|
6101
6462
|
if (!endpointId.value && !alias.value) {
|
|
6102
6463
|
throw new CliError2("remote endpoint update requires --id <id> or --alias <a>.");
|
|
6103
6464
|
}
|
|
@@ -6120,7 +6481,7 @@ async function executeRemote(context, args) {
|
|
|
6120
6481
|
let pending2 = subRest;
|
|
6121
6482
|
const alias = takeOption(pending2, "--alias");
|
|
6122
6483
|
pending2 = alias.rest;
|
|
6123
|
-
requireNoExtraArgs(pending2, "
|
|
6484
|
+
requireNoExtraArgs(pending2, "rig remote endpoint remove --alias <a>");
|
|
6124
6485
|
if (!alias.value) {
|
|
6125
6486
|
throw new CliError2("remote endpoint remove requires --alias.");
|
|
6126
6487
|
}
|
|
@@ -6137,7 +6498,7 @@ async function executeRemote(context, args) {
|
|
|
6137
6498
|
let pending2 = subRest;
|
|
6138
6499
|
const alias = takeOption(pending2, "--alias");
|
|
6139
6500
|
pending2 = alias.rest;
|
|
6140
|
-
requireNoExtraArgs(pending2, "
|
|
6501
|
+
requireNoExtraArgs(pending2, "rig remote endpoint test --alias <a>");
|
|
6141
6502
|
if (!alias.value) {
|
|
6142
6503
|
throw new CliError2("remote endpoint test requires --alias.");
|
|
6143
6504
|
}
|
|
@@ -6168,7 +6529,7 @@ async function executeRemote(context, args) {
|
|
|
6168
6529
|
}
|
|
6169
6530
|
}
|
|
6170
6531
|
case "migrate": {
|
|
6171
|
-
requireNoExtraArgs(subRest, "
|
|
6532
|
+
requireNoExtraArgs(subRest, "rig remote endpoint migrate");
|
|
6172
6533
|
const result = migrateManagedRemoteEndpoints(context.projectRoot);
|
|
6173
6534
|
if (context.outputMode === "text") {
|
|
6174
6535
|
console.log(`Imported ${result.imported} endpoint(s) from ${result.sourcePath}${result.skipped > 0 ? `, skipped ${result.skipped}` : ""}.`);
|
|
@@ -6176,7 +6537,7 @@ async function executeRemote(context, args) {
|
|
|
6176
6537
|
return { ok: true, group: "remote", command: "endpoint migrate", details: result };
|
|
6177
6538
|
}
|
|
6178
6539
|
case "doctor": {
|
|
6179
|
-
requireNoExtraArgs(subRest, "
|
|
6540
|
+
requireNoExtraArgs(subRest, "rig remote endpoint doctor");
|
|
6180
6541
|
const result = doctorManagedRemoteEndpoints(context.projectRoot);
|
|
6181
6542
|
if (context.outputMode === "text") {
|
|
6182
6543
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -6229,17 +6590,17 @@ async function executeRemote(context, args) {
|
|
|
6229
6590
|
try {
|
|
6230
6591
|
switch (command) {
|
|
6231
6592
|
case "test": {
|
|
6232
|
-
requireNoExtraArgs(pending, "
|
|
6593
|
+
requireNoExtraArgs(pending, "rig remote test [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6233
6594
|
const response = await withClient((client) => client.ping());
|
|
6234
6595
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6235
6596
|
}
|
|
6236
6597
|
case "status": {
|
|
6237
|
-
requireNoExtraArgs(pending, "
|
|
6598
|
+
requireNoExtraArgs(pending, "rig remote status [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6238
6599
|
const response = await withClient((client) => client.getState());
|
|
6239
6600
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6240
6601
|
}
|
|
6241
6602
|
case "tasks": {
|
|
6242
|
-
requireNoExtraArgs(pending, "
|
|
6603
|
+
requireNoExtraArgs(pending, "rig remote tasks [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6243
6604
|
const response = await withClient((client) => client.getTasks());
|
|
6244
6605
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6245
6606
|
}
|
|
@@ -6249,7 +6610,7 @@ async function executeRemote(context, args) {
|
|
|
6249
6610
|
watchPending = secondsResult.rest;
|
|
6250
6611
|
const eventResult = takeOption(watchPending, "--event");
|
|
6251
6612
|
watchPending = eventResult.rest;
|
|
6252
|
-
requireNoExtraArgs(watchPending, "
|
|
6613
|
+
requireNoExtraArgs(watchPending, "rig remote watch [--seconds <n>] [--event <type>] [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6253
6614
|
const seconds = parseOptionalPositiveInt(secondsResult.value, "--seconds");
|
|
6254
6615
|
const eventFilter = eventResult.value || undefined;
|
|
6255
6616
|
if (context.outputMode === "json" && !seconds) {
|
|
@@ -6318,7 +6679,7 @@ async function executeRemote(context, args) {
|
|
|
6318
6679
|
case "stop":
|
|
6319
6680
|
case "continue":
|
|
6320
6681
|
case "refresh": {
|
|
6321
|
-
requireNoExtraArgs(pending, `
|
|
6682
|
+
requireNoExtraArgs(pending, `rig remote ${command} [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6322
6683
|
const response = await withClient(async (client) => {
|
|
6323
6684
|
switch (command) {
|
|
6324
6685
|
case "pause":
|
|
@@ -6341,7 +6702,7 @@ async function executeRemote(context, args) {
|
|
|
6341
6702
|
let countPending = pending;
|
|
6342
6703
|
const countResult = takeOption(countPending, "--count");
|
|
6343
6704
|
countPending = countResult.rest;
|
|
6344
|
-
requireNoExtraArgs(countPending, `
|
|
6705
|
+
requireNoExtraArgs(countPending, `rig remote ${command} --count <n> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6345
6706
|
const count = parseRequiredPositiveInt(countResult.value, "--count");
|
|
6346
6707
|
const response = await withClient(async (client) => command === "add-iterations" ? await client.addIterations(count) : await client.removeIterations(count));
|
|
6347
6708
|
assertRemoteOperationSuccess(command, response);
|
|
@@ -6352,8 +6713,8 @@ async function executeRemote(context, args) {
|
|
|
6352
6713
|
let taskPending = pending;
|
|
6353
6714
|
const taskResult = takeOption(taskPending, "--task");
|
|
6354
6715
|
taskPending = taskResult.rest;
|
|
6355
|
-
requireNoExtraArgs(taskPending, `
|
|
6356
|
-
const taskId = requireTask(taskResult.value, `
|
|
6716
|
+
requireNoExtraArgs(taskPending, `rig remote ${command} --task <id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6717
|
+
const taskId = requireTask(taskResult.value, `rig remote ${command} --task <id>`);
|
|
6357
6718
|
const response = await withClient(async (client) => command === "prompt-preview" ? await client.getPromptPreview(taskId) : await client.getIterationOutput(taskId));
|
|
6358
6719
|
assertRemoteOperationSuccess(command, response);
|
|
6359
6720
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
@@ -6366,7 +6727,7 @@ async function executeRemote(context, args) {
|
|
|
6366
6727
|
orchestrationPending = maxIterationsResult.rest;
|
|
6367
6728
|
const directMergeResult = takeFlag(orchestrationPending, "--direct-merge");
|
|
6368
6729
|
orchestrationPending = directMergeResult.rest;
|
|
6369
|
-
requireNoExtraArgs(orchestrationPending, "
|
|
6730
|
+
requireNoExtraArgs(orchestrationPending, "rig remote orchestrate-start [--max-workers <n>] [--max-iterations <n>] [--direct-merge]");
|
|
6370
6731
|
const response = await withClient((client) => client.startOrchestration({
|
|
6371
6732
|
maxWorkers: parseOptionalPositiveInt(maxWorkersResult.value, "--max-workers"),
|
|
6372
6733
|
maxIterations: parseOptionalPositiveInt(maxIterationsResult.value, "--max-iterations"),
|
|
@@ -6387,8 +6748,8 @@ async function executeRemote(context, args) {
|
|
|
6387
6748
|
let orchestrationPending = pending;
|
|
6388
6749
|
const idResult = takeOption(orchestrationPending, "--id");
|
|
6389
6750
|
orchestrationPending = idResult.rest;
|
|
6390
|
-
requireNoExtraArgs(orchestrationPending, `
|
|
6391
|
-
const orchestrationId = requireTask(idResult.value, `
|
|
6751
|
+
requireNoExtraArgs(orchestrationPending, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6752
|
+
const orchestrationId = requireTask(idResult.value, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6392
6753
|
const response = await withClient(async (client) => {
|
|
6393
6754
|
switch (command) {
|
|
6394
6755
|
case "orchestrate-pause":
|
|
@@ -6416,6 +6777,8 @@ async function executeRemote(context, args) {
|
|
|
6416
6777
|
}
|
|
6417
6778
|
|
|
6418
6779
|
// packages/cli/src/commands/run.ts
|
|
6780
|
+
init_runner();
|
|
6781
|
+
init__parsers();
|
|
6419
6782
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
6420
6783
|
import {
|
|
6421
6784
|
listAuthorityRuns as listAuthorityRuns3,
|
|
@@ -6433,7 +6796,7 @@ import {
|
|
|
6433
6796
|
startRun,
|
|
6434
6797
|
defaultStartRunOptions
|
|
6435
6798
|
} from "@rig/runtime/control-plane/native/run-ops";
|
|
6436
|
-
import { loadRuntimeContextFromEnv
|
|
6799
|
+
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
6437
6800
|
|
|
6438
6801
|
// packages/cli/src/commands/_operator-surface.ts
|
|
6439
6802
|
import { createInterface } from "readline";
|
|
@@ -6452,8 +6815,8 @@ var CANONICAL_STAGES = [
|
|
|
6452
6815
|
"Merge",
|
|
6453
6816
|
"Complete"
|
|
6454
6817
|
];
|
|
6455
|
-
function logDetail(
|
|
6456
|
-
return typeof
|
|
6818
|
+
function logDetail(log4) {
|
|
6819
|
+
return typeof log4.detail === "string" ? log4.detail.trim() : "";
|
|
6457
6820
|
}
|
|
6458
6821
|
function parseProviderProtocolLog(title, detail) {
|
|
6459
6822
|
if (title.trim().toLowerCase() !== "agent output")
|
|
@@ -6500,12 +6863,12 @@ function renderOperatorSnapshot(snapshot) {
|
|
|
6500
6863
|
const status = String(run.status ?? "unknown");
|
|
6501
6864
|
const logs = snapshot.logs ?? [];
|
|
6502
6865
|
const latestByStage = new Map;
|
|
6503
|
-
for (const
|
|
6504
|
-
const title = String(
|
|
6505
|
-
const stageName = String(
|
|
6866
|
+
for (const log4 of logs) {
|
|
6867
|
+
const title = String(log4.title ?? "").toLowerCase();
|
|
6868
|
+
const stageName = String(log4.stage ?? "").toLowerCase();
|
|
6506
6869
|
const stage = CANONICAL_STAGES.find((candidate) => candidate.toLowerCase() === title || candidate.toLowerCase() === stageName);
|
|
6507
6870
|
if (stage)
|
|
6508
|
-
latestByStage.set(stage,
|
|
6871
|
+
latestByStage.set(stage, log4);
|
|
6509
6872
|
}
|
|
6510
6873
|
const stageLines = CANONICAL_STAGES.flatMap((stage) => {
|
|
6511
6874
|
const match = latestByStage.get(stage);
|
|
@@ -7309,7 +7672,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
7309
7672
|
}
|
|
7310
7673
|
|
|
7311
7674
|
// packages/cli/src/commands/run.ts
|
|
7312
|
-
function
|
|
7675
|
+
function normalizeRemoteRunDetails2(payload) {
|
|
7313
7676
|
const run = payload.run;
|
|
7314
7677
|
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
7315
7678
|
return null;
|
|
@@ -7321,11 +7684,11 @@ function normalizeRemoteRunDetails(payload) {
|
|
|
7321
7684
|
};
|
|
7322
7685
|
}
|
|
7323
7686
|
var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
|
|
7324
|
-
function
|
|
7687
|
+
function isRemoteConnectionSelected2(projectRoot) {
|
|
7325
7688
|
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
7326
7689
|
}
|
|
7327
7690
|
async function listRunsForSelectedConnection(context, options = {}) {
|
|
7328
|
-
if (
|
|
7691
|
+
if (isRemoteConnectionSelected2(context.projectRoot)) {
|
|
7329
7692
|
return { runs: await listRunsViaServer(context, options), source: "server" };
|
|
7330
7693
|
}
|
|
7331
7694
|
return { runs: listAuthorityRuns3(context.projectRoot), source: "local" };
|
|
@@ -7334,9 +7697,6 @@ function runStringField(run, key, fallback = "") {
|
|
|
7334
7697
|
const value = run[key];
|
|
7335
7698
|
return typeof value === "string" && value.trim() ? value : fallback;
|
|
7336
7699
|
}
|
|
7337
|
-
function runDisplayTitle(run) {
|
|
7338
|
-
return runStringField(run, "title", runStringField(run, "taskId", "(untitled)"));
|
|
7339
|
-
}
|
|
7340
7700
|
function buildServerRunStatus(runs) {
|
|
7341
7701
|
const activeRuns = runs.filter((run) => !REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
7342
7702
|
const recentRuns = runs.filter((run) => REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
@@ -7403,13 +7763,13 @@ async function promptForEpicSelection(projectRoot, command) {
|
|
|
7403
7763
|
}
|
|
7404
7764
|
async function executeRun(context, args) {
|
|
7405
7765
|
const [command = "status", ...rest] = args;
|
|
7406
|
-
const runtimeContext =
|
|
7766
|
+
const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
|
|
7407
7767
|
switch (command) {
|
|
7408
7768
|
case "list": {
|
|
7409
|
-
requireNoExtraArgs(rest, "
|
|
7769
|
+
requireNoExtraArgs(rest, "rig run list");
|
|
7410
7770
|
const { runs, source } = await listRunsForSelectedConnection(context, { limit: 100 });
|
|
7411
7771
|
if (context.outputMode === "text") {
|
|
7412
|
-
|
|
7772
|
+
printFormattedOutput(formatRunList(runs, { source }));
|
|
7413
7773
|
}
|
|
7414
7774
|
return { ok: true, group: "run", command, details: { runs, source } };
|
|
7415
7775
|
}
|
|
@@ -7419,7 +7779,7 @@ async function executeRun(context, args) {
|
|
|
7419
7779
|
pending = run.rest;
|
|
7420
7780
|
const purgeArtifacts = takeFlag(pending, "--purge-artifacts");
|
|
7421
7781
|
pending = purgeArtifacts.rest;
|
|
7422
|
-
requireNoExtraArgs(pending, "
|
|
7782
|
+
requireNoExtraArgs(pending, "rig run delete --run <id> [--purge-artifacts]");
|
|
7423
7783
|
if (!run.value) {
|
|
7424
7784
|
throw new CliError2("run delete requires --run <id>.");
|
|
7425
7785
|
}
|
|
@@ -7449,7 +7809,7 @@ async function executeRun(context, args) {
|
|
|
7449
7809
|
pending = keepRuntimes.rest;
|
|
7450
7810
|
const keepQueue = takeFlag(pending, "--keep-queue");
|
|
7451
7811
|
pending = keepQueue.rest;
|
|
7452
|
-
requireNoExtraArgs(pending, "
|
|
7812
|
+
requireNoExtraArgs(pending, "rig run cleanup --all [--keep-artifacts] [--keep-runtimes] [--keep-queue]");
|
|
7453
7813
|
if (!all.value) {
|
|
7454
7814
|
throw new CliError2("run cleanup currently requires --all.");
|
|
7455
7815
|
}
|
|
@@ -7468,20 +7828,25 @@ async function executeRun(context, args) {
|
|
|
7468
7828
|
}
|
|
7469
7829
|
case "show": {
|
|
7470
7830
|
let pending = rest;
|
|
7831
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
7832
|
+
pending = rawResult.rest;
|
|
7471
7833
|
const run = takeOption(pending, "--run");
|
|
7472
7834
|
pending = run.rest;
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7835
|
+
const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
|
|
7836
|
+
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
7837
|
+
requireNoExtraArgs(extra, "rig run show <id>|--run <id> [--raw]");
|
|
7838
|
+
const runId = run.value ?? positionalRunId;
|
|
7839
|
+
if (!runId) {
|
|
7840
|
+
throw new CliError2("run show requires a run id.");
|
|
7476
7841
|
}
|
|
7477
|
-
const record = readAuthorityRun4(context.projectRoot,
|
|
7842
|
+
const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
|
|
7478
7843
|
if (!record) {
|
|
7479
|
-
throw new CliError2(`Run not found: ${
|
|
7844
|
+
throw new CliError2(`Run not found: ${runId}`, 2);
|
|
7480
7845
|
}
|
|
7481
7846
|
if (context.outputMode === "text") {
|
|
7482
|
-
|
|
7847
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(record, null, 2) : formatRunCard(record));
|
|
7483
7848
|
}
|
|
7484
|
-
return { ok: true, group: "run", command, details: record };
|
|
7849
|
+
return { ok: true, group: "run", command, details: { ...record, rawOutput: rawResult.value } };
|
|
7485
7850
|
}
|
|
7486
7851
|
case "timeline": {
|
|
7487
7852
|
let pending = rest;
|
|
@@ -7489,7 +7854,7 @@ async function executeRun(context, args) {
|
|
|
7489
7854
|
pending = run.rest;
|
|
7490
7855
|
const follow = takeFlag(pending, "--follow");
|
|
7491
7856
|
pending = follow.rest;
|
|
7492
|
-
requireNoExtraArgs(pending, "
|
|
7857
|
+
requireNoExtraArgs(pending, "rig run timeline --run <id> [--follow]");
|
|
7493
7858
|
if (!run.value) {
|
|
7494
7859
|
throw new CliError2("run timeline requires --run <id>.");
|
|
7495
7860
|
}
|
|
@@ -7526,7 +7891,7 @@ async function executeRun(context, args) {
|
|
|
7526
7891
|
pending = pollMs.rest;
|
|
7527
7892
|
const positionalRunId = pending.length > 0 ? pending[0] : undefined;
|
|
7528
7893
|
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
7529
|
-
requireNoExtraArgs(extra, "
|
|
7894
|
+
requireNoExtraArgs(extra, "rig run attach <run-id>|--run <run-id> [--message <text>] [--once|--follow] [--poll-ms <ms>]");
|
|
7530
7895
|
const runId = runOption.value ?? positionalRunId;
|
|
7531
7896
|
if (!runId) {
|
|
7532
7897
|
throw new CliError2("run attach requires a run id.", 2);
|
|
@@ -7546,28 +7911,18 @@ async function executeRun(context, args) {
|
|
|
7546
7911
|
return { ok: true, group: "run", command, details: { ...attached, steered: attached.steered || steered } };
|
|
7547
7912
|
}
|
|
7548
7913
|
case "status": {
|
|
7549
|
-
requireNoExtraArgs(rest, "
|
|
7914
|
+
requireNoExtraArgs(rest, "rig run status");
|
|
7550
7915
|
if (context.dryRun) {
|
|
7551
7916
|
if (context.outputMode === "text") {
|
|
7552
7917
|
console.log("[dry-run] rig run status");
|
|
7553
7918
|
}
|
|
7554
7919
|
return { ok: true, group: "run", command };
|
|
7555
7920
|
}
|
|
7556
|
-
const summary =
|
|
7921
|
+
const summary = isRemoteConnectionSelected2(context.projectRoot) ? buildServerRunStatus(await listRunsViaServer(context, { limit: 100 })) : runStatus(context.projectRoot, runtimeContext);
|
|
7557
7922
|
const activeRuns = Array.isArray(summary.activeRuns) ? summary.activeRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
7558
7923
|
const recentRuns = Array.isArray(summary.recentRuns) ? summary.recentRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
7559
7924
|
if (context.outputMode === "text") {
|
|
7560
|
-
|
|
7561
|
-
for (const run of activeRuns) {
|
|
7562
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
7563
|
-
}
|
|
7564
|
-
if (recentRuns.length > 0) {
|
|
7565
|
-
console.log("");
|
|
7566
|
-
console.log("Recent runs:");
|
|
7567
|
-
for (const run of recentRuns) {
|
|
7568
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
7569
|
-
}
|
|
7570
|
-
}
|
|
7925
|
+
printFormattedOutput(formatRunStatus({ activeRuns, recentRuns, runs: Array.isArray(summary.runs) ? summary.runs : [...activeRuns, ...recentRuns] }, { source: isRemoteConnectionSelected2(context.projectRoot) ? "server" : "local" }));
|
|
7571
7926
|
}
|
|
7572
7927
|
return { ok: true, group: "run", command, details: summary };
|
|
7573
7928
|
}
|
|
@@ -7591,7 +7946,7 @@ async function executeRun(context, args) {
|
|
|
7591
7946
|
pending = pollResult.rest;
|
|
7592
7947
|
const noServerResult = takeFlag(pending, "--no-server");
|
|
7593
7948
|
pending = noServerResult.rest;
|
|
7594
|
-
requireNoExtraArgs(pending, "
|
|
7949
|
+
requireNoExtraArgs(pending, "rig run start [--epic <id>] [--prompt-epic|--no-epic-prompt] [--ws-port <n>] [--server-host <host>] [--server-port <n>] [--poll-ms <n>] [--no-server]");
|
|
7595
7950
|
if (promptEpicResult.value && noEpicPromptResult.value) {
|
|
7596
7951
|
throw new CliError2("Cannot use --prompt-epic and --no-epic-prompt together.");
|
|
7597
7952
|
}
|
|
@@ -7639,7 +7994,7 @@ async function executeRun(context, args) {
|
|
|
7639
7994
|
};
|
|
7640
7995
|
}
|
|
7641
7996
|
case "resume": {
|
|
7642
|
-
requireNoExtraArgs(rest, "
|
|
7997
|
+
requireNoExtraArgs(rest, "rig run resume");
|
|
7643
7998
|
if (context.dryRun) {
|
|
7644
7999
|
if (context.outputMode === "text") {
|
|
7645
8000
|
console.log("[dry-run] rig run resume");
|
|
@@ -7653,7 +8008,7 @@ async function executeRun(context, args) {
|
|
|
7653
8008
|
return { ok: true, group: "run", command, details: resumed };
|
|
7654
8009
|
}
|
|
7655
8010
|
case "restart": {
|
|
7656
|
-
requireNoExtraArgs(rest, "
|
|
8011
|
+
requireNoExtraArgs(rest, "rig run restart");
|
|
7657
8012
|
if (context.dryRun) {
|
|
7658
8013
|
if (context.outputMode === "text") {
|
|
7659
8014
|
console.log("[dry-run] rig run restart");
|
|
@@ -7670,7 +8025,7 @@ async function executeRun(context, args) {
|
|
|
7670
8025
|
const runOption = takeOption(rest, "--run");
|
|
7671
8026
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
7672
8027
|
const extra = positionalRunId ? runOption.rest.slice(1) : runOption.rest;
|
|
7673
|
-
requireNoExtraArgs(extra, "
|
|
8028
|
+
requireNoExtraArgs(extra, "rig run stop [<run-id>|--run <id>]");
|
|
7674
8029
|
const runId = runOption.value ?? positionalRunId;
|
|
7675
8030
|
if (context.dryRun) {
|
|
7676
8031
|
return {
|
|
@@ -7709,6 +8064,7 @@ async function executeRun(context, args) {
|
|
|
7709
8064
|
}
|
|
7710
8065
|
|
|
7711
8066
|
// packages/cli/src/commands/server.ts
|
|
8067
|
+
init_runner();
|
|
7712
8068
|
async function executeServer(context, args, options) {
|
|
7713
8069
|
const [command = "status", ...rest] = args;
|
|
7714
8070
|
if (["status", "list", "add", "use"].includes(command)) {
|
|
@@ -7810,6 +8166,7 @@ async function executeServer(context, args, options) {
|
|
|
7810
8166
|
}
|
|
7811
8167
|
|
|
7812
8168
|
// packages/cli/src/commands/task.ts
|
|
8169
|
+
init_runner();
|
|
7813
8170
|
import { readFileSync as readFileSync9 } from "fs";
|
|
7814
8171
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
7815
8172
|
import { resolve as resolve19 } from "path";
|
|
@@ -7835,50 +8192,426 @@ import { cancel as cancel3, isCancel as isCancel3, select as select3 } from "@cl
|
|
|
7835
8192
|
function taskId2(task) {
|
|
7836
8193
|
return typeof task.id === "string" && task.id.trim() ? task.id : "<unknown>";
|
|
7837
8194
|
}
|
|
7838
|
-
async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
7839
|
-
if (tasks.length === 0)
|
|
7840
|
-
return null;
|
|
7841
|
-
if (tasks.length === 1)
|
|
7842
|
-
return tasks[0];
|
|
7843
|
-
const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
7844
|
-
if (!isTty) {
|
|
7845
|
-
throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
|
|
8195
|
+
async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
8196
|
+
if (tasks.length === 0)
|
|
8197
|
+
return null;
|
|
8198
|
+
if (tasks.length === 1)
|
|
8199
|
+
return tasks[0];
|
|
8200
|
+
const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8201
|
+
if (!isTty) {
|
|
8202
|
+
throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
|
|
8203
|
+
}
|
|
8204
|
+
if (io.prompt || io.renderer) {
|
|
8205
|
+
const prompt = io.prompt ?? promptForTaskSelection;
|
|
8206
|
+
const renderer = io.renderer ?? { writeLine: (line) => process.stdout.write(`${line}
|
|
8207
|
+
`) };
|
|
8208
|
+
renderer.writeLine("Select Rig task:");
|
|
8209
|
+
for (const row of renderTaskPickerRows(tasks))
|
|
8210
|
+
renderer.writeLine(` ${row}`);
|
|
8211
|
+
const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
|
|
8212
|
+
if (!answer2)
|
|
8213
|
+
return null;
|
|
8214
|
+
if (/^\d+$/.test(answer2)) {
|
|
8215
|
+
const index2 = Number.parseInt(answer2, 10) - 1;
|
|
8216
|
+
return tasks[index2] ?? null;
|
|
8217
|
+
}
|
|
8218
|
+
return tasks.find((task) => taskId2(task) === answer2) ?? null;
|
|
8219
|
+
}
|
|
8220
|
+
const options = tasks.map((task, index2) => ({
|
|
8221
|
+
value: `${index2}`,
|
|
8222
|
+
label: `${taskId2(task)} \xB7 ${typeof task.title === "string" && task.title.trim() ? task.title.trim() : "Untitled task"}`,
|
|
8223
|
+
hint: typeof task.status === "string" && task.status.trim() ? task.status.trim() : undefined
|
|
8224
|
+
}));
|
|
8225
|
+
const answer = await select3({
|
|
8226
|
+
message: "Select Rig task",
|
|
8227
|
+
options
|
|
8228
|
+
});
|
|
8229
|
+
if (isCancel3(answer)) {
|
|
8230
|
+
cancel3("No task selected.");
|
|
8231
|
+
return null;
|
|
8232
|
+
}
|
|
8233
|
+
const index = Number.parseInt(String(answer), 10);
|
|
8234
|
+
return Number.isFinite(index) ? tasks[index] ?? null : null;
|
|
8235
|
+
}
|
|
8236
|
+
|
|
8237
|
+
// packages/cli/src/commands/_help-catalog.ts
|
|
8238
|
+
import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
|
|
8239
|
+
import pc4 from "picocolors";
|
|
8240
|
+
var TOP_LEVEL_SECTIONS = [
|
|
8241
|
+
{
|
|
8242
|
+
title: "Server",
|
|
8243
|
+
subtitle: "choose the local or remote Rig server that owns this repo",
|
|
8244
|
+
commands: [
|
|
8245
|
+
{ command: "rig server status", description: "Show the selected local/remote server for this repo." },
|
|
8246
|
+
{ command: "rig server use local", description: "Switch this repo back to the local Rig server." },
|
|
8247
|
+
{ command: "rig server add <alias> <url>", description: "Save a remote Rig server alias." },
|
|
8248
|
+
{ command: "rig server use <alias>", description: "Switch this repo to a saved remote server." },
|
|
8249
|
+
{ command: "rig server list", description: "Show saved server aliases, including local." }
|
|
8250
|
+
]
|
|
8251
|
+
},
|
|
8252
|
+
{
|
|
8253
|
+
title: "Tasks",
|
|
8254
|
+
subtitle: "find work, inspect it, and submit Pi-backed workers",
|
|
8255
|
+
commands: [
|
|
8256
|
+
{ command: "rig task list", description: "List tasks from the selected task source/server." },
|
|
8257
|
+
{ command: "rig task next", description: "Show the next matching task as a selected-task card." },
|
|
8258
|
+
{ command: "rig task show <id>", description: "Show a human task summary; add --raw or --json for the full payload." },
|
|
8259
|
+
{ command: "rig task run <id|--next> [--detach]", description: "Submit a task run; interactive mode follows with bundled Pi." }
|
|
8260
|
+
]
|
|
8261
|
+
},
|
|
8262
|
+
{
|
|
8263
|
+
title: "Runs",
|
|
8264
|
+
subtitle: "observe, attach to, and stop live or recent runs",
|
|
8265
|
+
commands: [
|
|
8266
|
+
{ command: "rig run list", description: "List recent runs from the selected server or local state." },
|
|
8267
|
+
{ command: "rig run show <id>", description: "Show a human run summary; add --raw or --json for the full payload." },
|
|
8268
|
+
{ command: "rig run attach <id> --follow", description: "Open the native bundled Pi live view for a worker run." },
|
|
8269
|
+
{ command: "rig run stop <id>", description: "Request cancellation for a running worker." }
|
|
8270
|
+
]
|
|
8271
|
+
},
|
|
8272
|
+
{
|
|
8273
|
+
title: "Review / inbox",
|
|
8274
|
+
subtitle: "clear blocked runs and configure completion review",
|
|
8275
|
+
commands: [
|
|
8276
|
+
{ command: "rig inbox approvals", description: "List pending approval requests from local/server run state." },
|
|
8277
|
+
{ command: "rig inbox inputs", description: "List pending user-input requests from local/server run state." },
|
|
8278
|
+
{ command: "rig review show|set", description: "Inspect or change the review gate policy." }
|
|
8279
|
+
]
|
|
8280
|
+
},
|
|
8281
|
+
{
|
|
8282
|
+
title: "Health / setup",
|
|
8283
|
+
subtitle: "bootstrap and diagnose the repo/server/GitHub/Pi path",
|
|
8284
|
+
commands: [
|
|
8285
|
+
{ command: "rig init", description: "Interactive setup: config, GitHub auth, task source, server, checkout, Pi." },
|
|
8286
|
+
{ command: "rig doctor", description: "Diagnose project/server/GitHub/task/Pi wiring." },
|
|
8287
|
+
{ command: "rig github auth status", description: "Show GitHub auth state on the selected Rig server." }
|
|
8288
|
+
]
|
|
8289
|
+
}
|
|
8290
|
+
];
|
|
8291
|
+
var PRIMARY_GROUPS = [
|
|
8292
|
+
{
|
|
8293
|
+
name: "server",
|
|
8294
|
+
summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
|
|
8295
|
+
usage: ["rig server <status|list|add|use|start> [options]"],
|
|
8296
|
+
commands: [
|
|
8297
|
+
{ command: "status", description: "Show the selected server for this repo.", primary: true },
|
|
8298
|
+
{ command: "use local", description: "Switch this repo to the local Rig server.", primary: true },
|
|
8299
|
+
{ command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
|
|
8300
|
+
{ command: "use <alias>", description: "Select a saved remote server alias.", primary: true },
|
|
8301
|
+
{ command: "list", description: "List saved local/remote server aliases.", primary: true },
|
|
8302
|
+
{ command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process." }
|
|
8303
|
+
],
|
|
8304
|
+
examples: [
|
|
8305
|
+
"rig server status",
|
|
8306
|
+
"rig server add prod https://where.rig-does.work",
|
|
8307
|
+
"rig server use prod",
|
|
8308
|
+
"rig server use local",
|
|
8309
|
+
"rig server start --port 3773"
|
|
8310
|
+
],
|
|
8311
|
+
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
|
|
8312
|
+
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
8313
|
+
},
|
|
8314
|
+
{
|
|
8315
|
+
name: "task",
|
|
8316
|
+
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
8317
|
+
usage: ["rig task <list|next|show|run> [options]"],
|
|
8318
|
+
commands: [
|
|
8319
|
+
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
8320
|
+
{ command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
|
|
8321
|
+
{ command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
|
|
8322
|
+
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
8323
|
+
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
8324
|
+
{ command: "details --task <id>", description: "Show full task info from the configured source." },
|
|
8325
|
+
{ command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
|
|
8326
|
+
{ command: "reset --task <id>", description: "Compatibility spelling of `reopen --task <id>`." },
|
|
8327
|
+
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
8328
|
+
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
8329
|
+
],
|
|
8330
|
+
examples: [
|
|
8331
|
+
"rig task list --assignee @me --limit 20",
|
|
8332
|
+
"rig task next",
|
|
8333
|
+
"rig task show 123 --raw",
|
|
8334
|
+
"rig task run --next",
|
|
8335
|
+
"rig task run #123 --runtime-adapter pi",
|
|
8336
|
+
"rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
|
|
8337
|
+
],
|
|
8338
|
+
next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
|
|
8339
|
+
},
|
|
8340
|
+
{
|
|
8341
|
+
name: "run",
|
|
8342
|
+
summary: "Observe, attach to, and control Rig runs.",
|
|
8343
|
+
usage: ["rig run <list|status|show|attach|stop> [options]"],
|
|
8344
|
+
commands: [
|
|
8345
|
+
{ command: "list", description: "List recent runs from the selected server or local state.", primary: true },
|
|
8346
|
+
{ command: "status", description: "Render active and recent run groups.", primary: true },
|
|
8347
|
+
{ command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
|
|
8348
|
+
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
|
|
8349
|
+
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
8350
|
+
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
8351
|
+
{ command: "resume", description: "Resume the most recent interrupted local run." },
|
|
8352
|
+
{ command: "restart", description: "Restart the most recent local run from a clean runtime." },
|
|
8353
|
+
{ command: "delete|cleanup", description: "Remove completed run records/artifacts." }
|
|
8354
|
+
],
|
|
8355
|
+
examples: [
|
|
8356
|
+
"rig run list",
|
|
8357
|
+
"rig run status",
|
|
8358
|
+
"rig run show <run-id>",
|
|
8359
|
+
"rig run attach <run-id> --follow",
|
|
8360
|
+
"rig run stop <run-id>"
|
|
8361
|
+
],
|
|
8362
|
+
next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
|
|
8363
|
+
},
|
|
8364
|
+
{
|
|
8365
|
+
name: "inbox",
|
|
8366
|
+
summary: "Review approval and user-input requests that block worker runs.",
|
|
8367
|
+
usage: ["rig inbox <approvals|approve|inputs|respond> [options]"],
|
|
8368
|
+
commands: [
|
|
8369
|
+
{ command: "approvals [--run <id>] [--task <id>]", description: "List pending approvals.", primary: true },
|
|
8370
|
+
{ command: "inputs [--run <id>] [--task <id>]", description: "List pending user-input requests.", primary: true },
|
|
8371
|
+
{ command: "approve --run <id> --request <id> --decision approve|reject", description: "Resolve an approval request." },
|
|
8372
|
+
{ command: "respond --run <id> --request <id> --answer key=value", description: "Answer a user-input request." }
|
|
8373
|
+
],
|
|
8374
|
+
examples: [
|
|
8375
|
+
"rig inbox approvals",
|
|
8376
|
+
"rig inbox inputs --run <run-id>",
|
|
8377
|
+
"rig inbox approve --run <run-id> --request <request-id> --decision approve"
|
|
8378
|
+
],
|
|
8379
|
+
next: ["Rejoin the run after resolving a block: `rig run attach <run-id> --follow`."]
|
|
8380
|
+
},
|
|
8381
|
+
{
|
|
8382
|
+
name: "review",
|
|
8383
|
+
summary: "Inspect or change completion review gate policy.",
|
|
8384
|
+
usage: ["rig review <show|set>"],
|
|
8385
|
+
commands: [
|
|
8386
|
+
{ command: "show", description: "Show current review gate settings.", primary: true },
|
|
8387
|
+
{ command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider.", primary: true }
|
|
8388
|
+
],
|
|
8389
|
+
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
8390
|
+
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
8391
|
+
},
|
|
8392
|
+
{
|
|
8393
|
+
name: "init",
|
|
8394
|
+
summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
|
|
8395
|
+
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
8396
|
+
commands: [
|
|
8397
|
+
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
8398
|
+
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
8399
|
+
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
8400
|
+
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
8401
|
+
],
|
|
8402
|
+
examples: [
|
|
8403
|
+
"rig init",
|
|
8404
|
+
"rig init --yes --repo humanity-org/humanwork",
|
|
8405
|
+
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
8406
|
+
],
|
|
8407
|
+
next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
|
|
8408
|
+
},
|
|
8409
|
+
{
|
|
8410
|
+
name: "doctor",
|
|
8411
|
+
summary: "Diagnostics for project/server/GitHub/Pi state.",
|
|
8412
|
+
usage: ["rig doctor"],
|
|
8413
|
+
commands: [
|
|
8414
|
+
{ command: "doctor", description: "Run setup and runtime diagnostics.", primary: true },
|
|
8415
|
+
{ command: "check", description: "Compatibility spelling for diagnostics." }
|
|
8416
|
+
],
|
|
8417
|
+
examples: ["rig doctor", "rig doctor --json"],
|
|
8418
|
+
next: ["Use `rig server status` and `rig github auth status` to inspect common failure points."]
|
|
8419
|
+
},
|
|
8420
|
+
{
|
|
8421
|
+
name: "github",
|
|
8422
|
+
summary: "GitHub auth helpers for the selected Rig server.",
|
|
8423
|
+
usage: ["rig github auth <status|import-gh|token>"],
|
|
8424
|
+
commands: [
|
|
8425
|
+
{ command: "auth status", description: "Show GitHub auth state.", primary: true },
|
|
8426
|
+
{ command: "auth import-gh", description: "Import the current `gh` token into the selected server." },
|
|
8427
|
+
{ command: "auth token --token <token>", description: "Store a token on the selected server." }
|
|
8428
|
+
],
|
|
8429
|
+
examples: ["rig github auth status", "rig github auth import-gh"],
|
|
8430
|
+
next: ["After auth is valid, use `rig task run --next`."]
|
|
8431
|
+
}
|
|
8432
|
+
];
|
|
8433
|
+
var ADVANCED_GROUPS = [
|
|
8434
|
+
{ name: "connect", summary: "Compatibility alias for `rig server` selection commands.", usage: ["rig connect <status|list|add|use>"], commands: [{ command: "status|list|add|use", description: "Use `rig server ...` for the primary UX." }] },
|
|
8435
|
+
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
8436
|
+
{ name: "inspect", summary: "Inspect logs, artifacts, graphs, failures.", usage: ["rig inspect <logs|artifacts|failures|graph|audit|diff>"], commands: [{ command: "logs --task <id>", description: "Inspect task logs." }] },
|
|
8437
|
+
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
8438
|
+
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
8439
|
+
{
|
|
8440
|
+
name: "browser",
|
|
8441
|
+
summary: "Browser/app diagnostics for browser-required tasks.",
|
|
8442
|
+
usage: ["rig browser <help|explain|demo|app|hp-next> [options]"],
|
|
8443
|
+
commands: [
|
|
8444
|
+
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
|
|
8445
|
+
{ command: "explain", description: "Explain the browser-required task contract." },
|
|
8446
|
+
{ command: "demo", description: "Run browser demo flows against a local page." },
|
|
8447
|
+
{ command: "app", description: "Launch the Rig Browser workstation app." },
|
|
8448
|
+
{ command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
|
|
8449
|
+
]
|
|
8450
|
+
},
|
|
8451
|
+
{
|
|
8452
|
+
name: "plugin",
|
|
8453
|
+
summary: "Plugin listing, validation, and plugin-contributed commands.",
|
|
8454
|
+
usage: ["rig plugin <list|validate|run> [options]"],
|
|
8455
|
+
commands: [
|
|
8456
|
+
{ command: "list", description: "List plugins declared in rig.config.ts and their contributions." },
|
|
8457
|
+
{ command: "validate --task <id>", description: "Run plugin-contributed validators for a task." },
|
|
8458
|
+
{ command: "run <command-id> [args...]", description: "Execute a plugin-contributed CLI command (also callable as `rig <command-id>`)." }
|
|
8459
|
+
]
|
|
8460
|
+
},
|
|
8461
|
+
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
8462
|
+
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
8463
|
+
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
8464
|
+
{ name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
|
|
8465
|
+
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
8466
|
+
{ name: "remote", summary: "Compatibility remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
|
|
8467
|
+
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
8468
|
+
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
8469
|
+
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
8470
|
+
];
|
|
8471
|
+
var ADVANCED_COMMANDS = [
|
|
8472
|
+
{ command: "rig server task-run ...", description: "Internal server-owned task execution entry point." },
|
|
8473
|
+
{ command: "rig server notify-test [--event <type>]", description: "Internal event notification smoke command." },
|
|
8474
|
+
{ command: "rig run start|start-serial|start-parallel", description: "Compatibility local run starters; prefer `rig task run ...`." },
|
|
8475
|
+
{ command: "rig remote orchestrate-*", description: "Compatibility remote orchestration commands." }
|
|
8476
|
+
];
|
|
8477
|
+
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
8478
|
+
function heading(title) {
|
|
8479
|
+
return pc4.bold(pc4.cyan(title));
|
|
8480
|
+
}
|
|
8481
|
+
function commandLine(command, description) {
|
|
8482
|
+
const commandColumn = command.length >= 38 ? `${command} ` : command.padEnd(38);
|
|
8483
|
+
return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
|
|
8484
|
+
}
|
|
8485
|
+
function renderCommandBlock(commands) {
|
|
8486
|
+
return commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8487
|
+
`);
|
|
8488
|
+
}
|
|
8489
|
+
function renderGroup(group) {
|
|
8490
|
+
const lines = [
|
|
8491
|
+
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
8492
|
+
"",
|
|
8493
|
+
pc4.bold("Usage"),
|
|
8494
|
+
...group.usage.map((line) => ` ${line}`),
|
|
8495
|
+
"",
|
|
8496
|
+
pc4.bold("Commands"),
|
|
8497
|
+
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
8498
|
+
];
|
|
8499
|
+
if (group.examples?.length) {
|
|
8500
|
+
lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
|
|
8501
|
+
}
|
|
8502
|
+
if (group.next?.length) {
|
|
8503
|
+
lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
8504
|
+
}
|
|
8505
|
+
if (group.advanced?.length) {
|
|
8506
|
+
lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
8507
|
+
}
|
|
8508
|
+
return lines.join(`
|
|
8509
|
+
`);
|
|
8510
|
+
}
|
|
8511
|
+
function renderTopLevelHelp() {
|
|
8512
|
+
return [
|
|
8513
|
+
`${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
8514
|
+
pc4.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox/review gates."),
|
|
8515
|
+
"",
|
|
8516
|
+
...TOP_LEVEL_SECTIONS.flatMap((section) => [
|
|
8517
|
+
`${pc4.bold(pc4.magenta(`\u25C7 ${section.title}`))} \u2014 ${pc4.dim(section.subtitle)}`,
|
|
8518
|
+
renderCommandBlock(section.commands),
|
|
8519
|
+
""
|
|
8520
|
+
]),
|
|
8521
|
+
pc4.dim("More: `rig help --advanced` for dev/compatibility commands; `rig <group> --help` for rich per-group help; `rig --version` for the installed version."),
|
|
8522
|
+
"",
|
|
8523
|
+
pc4.bold("Global options"),
|
|
8524
|
+
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
8525
|
+
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
8526
|
+
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
8527
|
+
].join(`
|
|
8528
|
+
`).trimEnd();
|
|
8529
|
+
}
|
|
8530
|
+
function renderAdvancedHelp() {
|
|
8531
|
+
return [
|
|
8532
|
+
`${heading("rig advanced")} \u2014 compatibility, diagnostics, and internal surfaces`,
|
|
8533
|
+
"",
|
|
8534
|
+
pc4.bold("Primary groups"),
|
|
8535
|
+
" server, task, run, inbox, review, init, doctor, github",
|
|
8536
|
+
"",
|
|
8537
|
+
pc4.bold("Advanced commands"),
|
|
8538
|
+
...ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)),
|
|
8539
|
+
"",
|
|
8540
|
+
pc4.bold("Advanced groups"),
|
|
8541
|
+
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
8542
|
+
"",
|
|
8543
|
+
pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, `rig run`, `rig inbox`, and `rig review` for day-to-day work.")
|
|
8544
|
+
].join(`
|
|
8545
|
+
`);
|
|
8546
|
+
}
|
|
8547
|
+
function renderGroupHelp(groupName) {
|
|
8548
|
+
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
8549
|
+
return group ? renderGroup(group) : null;
|
|
8550
|
+
}
|
|
8551
|
+
function shouldUseClackOutput2() {
|
|
8552
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
8553
|
+
}
|
|
8554
|
+
function printTopLevelHelp() {
|
|
8555
|
+
if (!shouldUseClackOutput2()) {
|
|
8556
|
+
console.log(renderTopLevelHelp());
|
|
8557
|
+
return;
|
|
7846
8558
|
}
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
`) };
|
|
7851
|
-
renderer.writeLine("Select Rig task:");
|
|
7852
|
-
for (const row of renderTaskPickerRows(tasks))
|
|
7853
|
-
renderer.writeLine(` ${row}`);
|
|
7854
|
-
const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
|
|
7855
|
-
if (!answer2)
|
|
7856
|
-
return null;
|
|
7857
|
-
if (/^\d+$/.test(answer2)) {
|
|
7858
|
-
const index2 = Number.parseInt(answer2, 10) - 1;
|
|
7859
|
-
return tasks[index2] ?? null;
|
|
7860
|
-
}
|
|
7861
|
-
return tasks.find((task) => taskId2(task) === answer2) ?? null;
|
|
8559
|
+
intro3("rig");
|
|
8560
|
+
for (const section of TOP_LEVEL_SECTIONS) {
|
|
8561
|
+
note4(renderCommandBlock(section.commands), `${section.title} \u2014 ${section.subtitle}`);
|
|
7862
8562
|
}
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
8563
|
+
log4.info("More: rig help --advanced \xB7 rig <group> --help \xB7 rig --version");
|
|
8564
|
+
note4([
|
|
8565
|
+
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
8566
|
+
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
8567
|
+
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
8568
|
+
].join(`
|
|
8569
|
+
`), "Global options");
|
|
8570
|
+
outro3("Server \u2192 task \u2192 run \u2192 inbox/review.");
|
|
8571
|
+
}
|
|
8572
|
+
function printAdvancedHelp() {
|
|
8573
|
+
if (!shouldUseClackOutput2()) {
|
|
8574
|
+
console.log(renderAdvancedHelp());
|
|
8575
|
+
return;
|
|
7875
8576
|
}
|
|
7876
|
-
|
|
7877
|
-
|
|
8577
|
+
intro3("rig advanced");
|
|
8578
|
+
note4(ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8579
|
+
`), "Advanced commands");
|
|
8580
|
+
note4(ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)).join(`
|
|
8581
|
+
`), "Advanced groups");
|
|
8582
|
+
outro3("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox \xB7 rig review.");
|
|
8583
|
+
}
|
|
8584
|
+
function printGroupHelpDocument(groupName) {
|
|
8585
|
+
const rendered = renderGroupHelp(groupName) ?? renderTopLevelHelp();
|
|
8586
|
+
if (!shouldUseClackOutput2()) {
|
|
8587
|
+
console.log(rendered);
|
|
8588
|
+
return;
|
|
8589
|
+
}
|
|
8590
|
+
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
8591
|
+
if (!group) {
|
|
8592
|
+
printTopLevelHelp();
|
|
8593
|
+
return;
|
|
8594
|
+
}
|
|
8595
|
+
intro3(`rig ${group.name}`);
|
|
8596
|
+
note4(group.summary, "Purpose");
|
|
8597
|
+
note4(group.usage.join(`
|
|
8598
|
+
`), "Usage");
|
|
8599
|
+
note4(group.commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8600
|
+
`), "Commands");
|
|
8601
|
+
if (group.examples?.length)
|
|
8602
|
+
note4(group.examples.map((line) => `$ ${line}`).join(`
|
|
8603
|
+
`), "Examples");
|
|
8604
|
+
if (group.next?.length)
|
|
8605
|
+
note4(group.next.map((line) => `\u203A ${line}`).join(`
|
|
8606
|
+
`), "Next steps");
|
|
8607
|
+
if (group.advanced?.length)
|
|
8608
|
+
log4.info(group.advanced.join(`
|
|
8609
|
+
`));
|
|
8610
|
+
outro3("Run with --json when scripts need structured output.");
|
|
7878
8611
|
}
|
|
7879
8612
|
|
|
7880
8613
|
// packages/cli/src/commands/task.ts
|
|
7881
|
-
import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
|
|
8614
|
+
import { buildPluginHostContext as buildPluginHostContext2 } from "@rig/runtime/control-plane/plugin-host-context";
|
|
7882
8615
|
import { loadConfig } from "@rig/core/load-config";
|
|
7883
8616
|
async function readStdin() {
|
|
7884
8617
|
const chunks = [];
|
|
@@ -8028,27 +8761,30 @@ function summarizeTask(task, options = {}) {
|
|
|
8028
8761
|
...options.raw ? { raw: raw ?? task } : {}
|
|
8029
8762
|
};
|
|
8030
8763
|
}
|
|
8031
|
-
function printTaskSummary(task) {
|
|
8032
|
-
console.log(formatTaskList([task]));
|
|
8033
|
-
}
|
|
8034
8764
|
async function validatorRegistryForTaskCommands(projectRoot) {
|
|
8035
|
-
return
|
|
8765
|
+
return buildPluginHostContext2(projectRoot).then((ctx) => ctx?.validatorRegistry ?? undefined).catch(() => {
|
|
8036
8766
|
return;
|
|
8037
8767
|
});
|
|
8038
8768
|
}
|
|
8039
8769
|
async function executeTask(context, args, options) {
|
|
8040
|
-
|
|
8770
|
+
if (args.length === 0) {
|
|
8771
|
+
if (context.outputMode === "text") {
|
|
8772
|
+
printGroupHelpDocument("task");
|
|
8773
|
+
}
|
|
8774
|
+
return { ok: true, group: "task", command: "help" };
|
|
8775
|
+
}
|
|
8776
|
+
const [command = "help", ...rest] = args;
|
|
8041
8777
|
switch (command) {
|
|
8042
8778
|
case "list": {
|
|
8043
8779
|
let pending = rest;
|
|
8044
8780
|
const rawResult = takeFlag(pending, "--raw");
|
|
8045
8781
|
pending = rawResult.rest;
|
|
8046
8782
|
const { filters, rest: remaining } = parseTaskFilters(pending);
|
|
8047
|
-
requireNoExtraArgs(remaining, "
|
|
8783
|
+
requireNoExtraArgs(remaining, "rig task list [--raw] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
8048
8784
|
const tasks = await listWorkspaceTasksViaServer(context, filters);
|
|
8049
8785
|
if (context.outputMode === "text") {
|
|
8050
8786
|
const renderedTasks = rawResult.value ? tasks.map((task) => summarizeTask(task, { raw: true })) : tasks.map((task) => summarizeTask(task));
|
|
8051
|
-
|
|
8787
|
+
printFormattedOutput(formatTaskList(renderedTasks, { raw: rawResult.value }));
|
|
8052
8788
|
}
|
|
8053
8789
|
return {
|
|
8054
8790
|
ok: true,
|
|
@@ -8058,10 +8794,13 @@ async function executeTask(context, args, options) {
|
|
|
8058
8794
|
};
|
|
8059
8795
|
}
|
|
8060
8796
|
case "show": {
|
|
8061
|
-
|
|
8797
|
+
let pending = rest;
|
|
8798
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
8799
|
+
pending = rawResult.rest;
|
|
8800
|
+
const taskOption = takeOption(pending, "--task");
|
|
8062
8801
|
const positional = taskOption.rest.length > 0 && taskOption.rest[0] && !taskOption.rest[0].startsWith("-") ? taskOption.rest[0] : undefined;
|
|
8063
8802
|
const remaining = positional ? taskOption.rest.slice(1) : taskOption.rest;
|
|
8064
|
-
requireNoExtraArgs(remaining, "
|
|
8803
|
+
requireNoExtraArgs(remaining, "rig task show <id>|--task <id> [--raw]");
|
|
8065
8804
|
const taskId3 = normalizeTaskRunTaskId(taskOption.value ?? positional);
|
|
8066
8805
|
if (!taskId3)
|
|
8067
8806
|
throw new CliError2("task show requires a task id.", 2);
|
|
@@ -8069,19 +8808,20 @@ async function executeTask(context, args, options) {
|
|
|
8069
8808
|
if (!task)
|
|
8070
8809
|
throw new CliError2(`Task not found: ${taskId3}`, 3);
|
|
8071
8810
|
const summary = summarizeTask(task, { raw: true });
|
|
8072
|
-
if (context.outputMode === "text")
|
|
8073
|
-
|
|
8074
|
-
|
|
8811
|
+
if (context.outputMode === "text") {
|
|
8812
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(summary, null, 2) : formatTaskDetails(summary));
|
|
8813
|
+
}
|
|
8814
|
+
return { ok: true, group: "task", command, details: { task: summary, raw: rawResult.value } };
|
|
8075
8815
|
}
|
|
8076
8816
|
case "next": {
|
|
8077
8817
|
const { filters, rest: remaining } = parseTaskFilters(rest);
|
|
8078
|
-
requireNoExtraArgs(remaining, "
|
|
8818
|
+
requireNoExtraArgs(remaining, "rig task next [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
8079
8819
|
const selected = await selectNextWorkspaceTaskViaServer(context, filters);
|
|
8080
8820
|
if (context.outputMode === "text") {
|
|
8081
8821
|
if (selected.task) {
|
|
8082
|
-
|
|
8822
|
+
printFormattedOutput(formatTaskCard(summarizeTask(selected.task, { raw: true }), { title: "Selected task", selected: true }));
|
|
8083
8823
|
} else {
|
|
8084
|
-
|
|
8824
|
+
printFormattedOutput("No matching tasks.\n\nNext\n\u203A Try `rig task list` to inspect available work.\n\u203A Check server: `rig server status`");
|
|
8085
8825
|
}
|
|
8086
8826
|
}
|
|
8087
8827
|
return {
|
|
@@ -8097,31 +8837,31 @@ async function executeTask(context, args, options) {
|
|
|
8097
8837
|
}
|
|
8098
8838
|
case "info": {
|
|
8099
8839
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8100
|
-
requireNoExtraArgs(remaining, "
|
|
8840
|
+
requireNoExtraArgs(remaining, "rig task info [--task <task-id>]");
|
|
8101
8841
|
await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, task || undefined));
|
|
8102
8842
|
return { ok: true, group: "task", command, details: { task: task || null } };
|
|
8103
8843
|
}
|
|
8104
8844
|
case "scope": {
|
|
8105
8845
|
const filesFlag = takeFlag(rest, "--files");
|
|
8106
8846
|
const { value: task, rest: remaining } = takeOption(filesFlag.rest, "--task");
|
|
8107
|
-
requireNoExtraArgs(remaining, "
|
|
8847
|
+
requireNoExtraArgs(remaining, "rig task scope [--task <id>] [--files]");
|
|
8108
8848
|
await withMutedConsole(context.outputMode === "json", () => taskScope(context.projectRoot, filesFlag.value, task || undefined));
|
|
8109
8849
|
return { ok: true, group: "task", command, details: { files: filesFlag.value, task: task || null } };
|
|
8110
8850
|
}
|
|
8111
8851
|
case "deps":
|
|
8112
|
-
requireNoExtraArgs(rest, "
|
|
8852
|
+
requireNoExtraArgs(rest, "rig task deps");
|
|
8113
8853
|
await withMutedConsole(context.outputMode === "json", () => taskDeps(context.projectRoot));
|
|
8114
8854
|
return { ok: true, group: "task", command };
|
|
8115
8855
|
case "status":
|
|
8116
|
-
requireNoExtraArgs(rest, "
|
|
8856
|
+
requireNoExtraArgs(rest, "rig task status");
|
|
8117
8857
|
withMutedConsole(context.outputMode === "json", () => taskStatus2(context.projectRoot));
|
|
8118
8858
|
return { ok: true, group: "task", command };
|
|
8119
8859
|
case "artifacts":
|
|
8120
|
-
requireNoExtraArgs(rest, "
|
|
8860
|
+
requireNoExtraArgs(rest, "rig task artifacts");
|
|
8121
8861
|
withMutedConsole(context.outputMode === "json", () => taskArtifacts(context.projectRoot));
|
|
8122
8862
|
return { ok: true, group: "task", command };
|
|
8123
8863
|
case "artifact-dir": {
|
|
8124
|
-
requireNoExtraArgs(rest, "
|
|
8864
|
+
requireNoExtraArgs(rest, "rig task artifact-dir");
|
|
8125
8865
|
const path = taskArtifactDir(context.projectRoot);
|
|
8126
8866
|
if (context.outputMode === "text") {
|
|
8127
8867
|
console.log(path);
|
|
@@ -8130,7 +8870,7 @@ async function executeTask(context, args, options) {
|
|
|
8130
8870
|
}
|
|
8131
8871
|
case "artifact-write": {
|
|
8132
8872
|
if (rest.length < 1) {
|
|
8133
|
-
throw new CliError2(`Usage:
|
|
8873
|
+
throw new CliError2(`Usage: rig task artifact-write <filename> [--file <path>]
|
|
8134
8874
|
` + ` Reads content from stdin (or --file), writes to the active task artifact dir.
|
|
8135
8875
|
` + " Example: echo '...' | rig task artifact-write collection-audit.md");
|
|
8136
8876
|
}
|
|
@@ -8143,7 +8883,7 @@ async function executeTask(context, args, options) {
|
|
|
8143
8883
|
content = await readStdin();
|
|
8144
8884
|
}
|
|
8145
8885
|
if (!artifactFilename) {
|
|
8146
|
-
throw new CliError2("Usage:
|
|
8886
|
+
throw new CliError2("Usage: rig task artifact-write <filename> [--file path]");
|
|
8147
8887
|
}
|
|
8148
8888
|
withMutedConsole(context.outputMode === "json", () => taskArtifactWrite(context.projectRoot, artifactFilename, content));
|
|
8149
8889
|
return { ok: true, group: "task", command, details: { filename: artifactFilename } };
|
|
@@ -8152,11 +8892,11 @@ async function executeTask(context, args, options) {
|
|
|
8152
8892
|
return options.executeTaskReportBug(context, rest);
|
|
8153
8893
|
case "lookup": {
|
|
8154
8894
|
if (rest.length !== 1) {
|
|
8155
|
-
throw new CliError2("Usage:
|
|
8895
|
+
throw new CliError2("Usage: rig task lookup <task-id>");
|
|
8156
8896
|
}
|
|
8157
8897
|
const lookupId = rest[0];
|
|
8158
8898
|
if (!lookupId) {
|
|
8159
|
-
throw new CliError2("Usage:
|
|
8899
|
+
throw new CliError2("Usage: rig task lookup <task-id>");
|
|
8160
8900
|
}
|
|
8161
8901
|
const result = taskLookup2(context.projectRoot, lookupId);
|
|
8162
8902
|
if (context.outputMode === "text") {
|
|
@@ -8166,17 +8906,17 @@ async function executeTask(context, args, options) {
|
|
|
8166
8906
|
}
|
|
8167
8907
|
case "record": {
|
|
8168
8908
|
if (rest.length < 2) {
|
|
8169
|
-
throw new CliError2("Usage:
|
|
8909
|
+
throw new CliError2("Usage: rig task record <decision|failure> <text>");
|
|
8170
8910
|
}
|
|
8171
8911
|
const type = rest[0];
|
|
8172
8912
|
if (type !== "decision" && type !== "failure") {
|
|
8173
|
-
throw new CliError2("Usage:
|
|
8913
|
+
throw new CliError2("Usage: rig task record <decision|failure> <text>");
|
|
8174
8914
|
}
|
|
8175
8915
|
withMutedConsole(context.outputMode === "json", () => taskRecord(context.projectRoot, type, rest.slice(1).join(" ")));
|
|
8176
8916
|
return { ok: true, group: "task", command, details: { type: rest[0] } };
|
|
8177
8917
|
}
|
|
8178
8918
|
case "ready":
|
|
8179
|
-
requireNoExtraArgs(rest, "
|
|
8919
|
+
requireNoExtraArgs(rest, "rig task ready");
|
|
8180
8920
|
await withMutedConsole(context.outputMode === "json", () => taskReady(context.projectRoot));
|
|
8181
8921
|
return { ok: true, group: "task", command };
|
|
8182
8922
|
case "run": {
|
|
@@ -8213,7 +8953,7 @@ async function executeTask(context, args, options) {
|
|
|
8213
8953
|
if (positionalTaskId) {
|
|
8214
8954
|
pending = pending.slice(1);
|
|
8215
8955
|
}
|
|
8216
|
-
requireNoExtraArgs(pending, "
|
|
8956
|
+
requireNoExtraArgs(pending, "rig task run [#<issue>|<task-id>] [--next] [--task <id>] [--detach] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>] [--title <text>] [--runtime-adapter claude-code|codex|pi] [--model <model>] [--runtime-mode <mode>] [--interaction-mode <mode>] [--initial-prompt <text>] [--pr auto|ask|off] [--no-pr] [--dirty-baseline head|dirty-snapshot] [--skip-project-sync]");
|
|
8217
8957
|
if (nextResult.value && (taskResult.value || positionalTaskId)) {
|
|
8218
8958
|
throw new CliError2("task run cannot combine --next with an explicit task id.", 2);
|
|
8219
8959
|
}
|
|
@@ -8267,10 +9007,24 @@ async function executeTask(context, args, options) {
|
|
|
8267
9007
|
});
|
|
8268
9008
|
let attachDetails = null;
|
|
8269
9009
|
if (!detachResult.value && context.outputMode === "text") {
|
|
8270
|
-
|
|
9010
|
+
printFormattedOutput(formatSubmittedRun({
|
|
9011
|
+
runId: submitted.runId,
|
|
9012
|
+
task: selectedTask ? summarizeTask(selectedTask) : null,
|
|
9013
|
+
runtimeAdapter,
|
|
9014
|
+
runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
|
|
9015
|
+
interactionMode: interactionModeResult.value || "default",
|
|
9016
|
+
detached: false
|
|
9017
|
+
}));
|
|
8271
9018
|
attachDetails = await attachRunOperatorView(context, { runId: submitted.runId, follow: true });
|
|
8272
9019
|
} else if (context.outputMode === "text") {
|
|
8273
|
-
|
|
9020
|
+
printFormattedOutput(formatSubmittedRun({
|
|
9021
|
+
runId: submitted.runId,
|
|
9022
|
+
task: selectedTask ? summarizeTask(selectedTask) : null,
|
|
9023
|
+
runtimeAdapter,
|
|
9024
|
+
runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
|
|
9025
|
+
interactionMode: interactionModeResult.value || "default",
|
|
9026
|
+
detached: true
|
|
9027
|
+
}));
|
|
8274
9028
|
}
|
|
8275
9029
|
return {
|
|
8276
9030
|
ok: true,
|
|
@@ -8294,7 +9048,7 @@ async function executeTask(context, args, options) {
|
|
|
8294
9048
|
}
|
|
8295
9049
|
case "validate": {
|
|
8296
9050
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8297
|
-
requireNoExtraArgs(remaining, "
|
|
9051
|
+
requireNoExtraArgs(remaining, "rig task validate [--task <task-id>]");
|
|
8298
9052
|
if (context.dryRun) {
|
|
8299
9053
|
await context.runCommand(["rig", "task", "validate", ...task ? ["--task", task] : []]);
|
|
8300
9054
|
return { ok: true, group: "task", command, details: { task: task || "active" } };
|
|
@@ -8307,12 +9061,12 @@ async function executeTask(context, args, options) {
|
|
|
8307
9061
|
}
|
|
8308
9062
|
case "verify": {
|
|
8309
9063
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8310
|
-
requireNoExtraArgs(remaining, "
|
|
9064
|
+
requireNoExtraArgs(remaining, "rig task verify [--task <task-id>]");
|
|
8311
9065
|
if (context.dryRun) {
|
|
8312
9066
|
await context.runCommand(["rig", "task", "verify", ...task ? ["--task", task] : []]);
|
|
8313
9067
|
return { ok: true, group: "task", command, details: { task: task || "active" } };
|
|
8314
9068
|
}
|
|
8315
|
-
const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot,
|
|
9069
|
+
const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot, task || undefined));
|
|
8316
9070
|
if (!ok) {
|
|
8317
9071
|
throw new CliError2(`Verification rejected for ${task || "active task"}.`, 2);
|
|
8318
9072
|
}
|
|
@@ -8320,15 +9074,19 @@ async function executeTask(context, args, options) {
|
|
|
8320
9074
|
}
|
|
8321
9075
|
case "reset": {
|
|
8322
9076
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8323
|
-
requireNoExtraArgs(remaining, "
|
|
8324
|
-
const requiredTask = requireTask(task, "
|
|
8325
|
-
|
|
8326
|
-
|
|
9077
|
+
requireNoExtraArgs(remaining, "rig task reset --task <task-id>");
|
|
9078
|
+
const requiredTask = requireTask(task, "rig task reset --task <task-id>");
|
|
9079
|
+
const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
|
|
9080
|
+
all: false,
|
|
9081
|
+
taskId: requiredTask,
|
|
9082
|
+
dryRun: false
|
|
9083
|
+
}));
|
|
9084
|
+
return { ok: true, group: "task", command, details: summary };
|
|
8327
9085
|
}
|
|
8328
9086
|
case "details": {
|
|
8329
9087
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8330
|
-
requireNoExtraArgs(remaining, "
|
|
8331
|
-
const requiredTask = requireTask(task, "
|
|
9088
|
+
requireNoExtraArgs(remaining, "rig task details --task <task-id>");
|
|
9089
|
+
const requiredTask = requireTask(task, "rig task details --task <task-id>");
|
|
8332
9090
|
await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, requiredTask));
|
|
8333
9091
|
return { ok: true, group: "task", command, details: { task: requiredTask } };
|
|
8334
9092
|
}
|
|
@@ -8336,9 +9094,9 @@ async function executeTask(context, args, options) {
|
|
|
8336
9094
|
const { value: task, rest: rest1 } = takeOption(rest, "--task");
|
|
8337
9095
|
const allFlag = takeFlag(rest1, "--all");
|
|
8338
9096
|
const { rest: remaining } = takeOption(allFlag.rest, "--reason");
|
|
8339
|
-
requireNoExtraArgs(remaining, "
|
|
9097
|
+
requireNoExtraArgs(remaining, "rig task reopen [--task <id> | --all] [--reason <text>]");
|
|
8340
9098
|
if (!allFlag.value && !task) {
|
|
8341
|
-
throw new CliError2("Usage:
|
|
9099
|
+
throw new CliError2("Usage: rig task reopen [--task <id> | --all] [--reason <text>]");
|
|
8342
9100
|
}
|
|
8343
9101
|
const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
|
|
8344
9102
|
all: allFlag.value,
|
|
@@ -8353,6 +9111,7 @@ async function executeTask(context, args, options) {
|
|
|
8353
9111
|
}
|
|
8354
9112
|
|
|
8355
9113
|
// packages/cli/src/commands/task-run-driver.ts
|
|
9114
|
+
init_runner();
|
|
8356
9115
|
import { copyFileSync as copyFileSync3, existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
8357
9116
|
import { resolve as resolve20 } from "path";
|
|
8358
9117
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
@@ -10369,19 +11128,20 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
10369
11128
|
}
|
|
10370
11129
|
|
|
10371
11130
|
// packages/cli/src/commands/test.ts
|
|
11131
|
+
init_runner();
|
|
10372
11132
|
async function executeTest(context, args) {
|
|
10373
11133
|
const [command = "unit", ...rest] = args;
|
|
10374
11134
|
switch (command) {
|
|
10375
11135
|
case "unit":
|
|
10376
|
-
requireNoExtraArgs(rest, "
|
|
11136
|
+
requireNoExtraArgs(rest, "rig test unit");
|
|
10377
11137
|
await context.runCommand(["bun", "test", "tests/harness/", "--ignore", "tests/harness/e2e/**"]);
|
|
10378
11138
|
return { ok: true, group: "test", command };
|
|
10379
11139
|
case "e2e":
|
|
10380
|
-
requireNoExtraArgs(rest, "
|
|
11140
|
+
requireNoExtraArgs(rest, "rig test e2e");
|
|
10381
11141
|
await context.runCommand(["bun", "test", "tests/harness/e2e/"]);
|
|
10382
11142
|
return { ok: true, group: "test", command };
|
|
10383
11143
|
case "all":
|
|
10384
|
-
requireNoExtraArgs(rest, "
|
|
11144
|
+
requireNoExtraArgs(rest, "rig test all");
|
|
10385
11145
|
await context.runCommand(["bun", "test", "tests/harness/"]);
|
|
10386
11146
|
return { ok: true, group: "test", command };
|
|
10387
11147
|
default:
|
|
@@ -10390,6 +11150,7 @@ async function executeTest(context, args) {
|
|
|
10390
11150
|
}
|
|
10391
11151
|
|
|
10392
11152
|
// packages/cli/src/commands/setup.ts
|
|
11153
|
+
init_runner();
|
|
10393
11154
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, readdirSync as readdirSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
10394
11155
|
import { resolve as resolve21 } from "path";
|
|
10395
11156
|
import { createPluginHost } from "@rig/core";
|
|
@@ -10397,11 +11158,12 @@ import {
|
|
|
10397
11158
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
10398
11159
|
MIN_SUPPORTED_BUN_VERSION as MIN_SUPPORTED_BUN_VERSION2
|
|
10399
11160
|
} from "@rig/runtime/control-plane/setup-version";
|
|
11161
|
+
init__parsers();
|
|
10400
11162
|
async function executeSetup(context, args) {
|
|
10401
11163
|
const [command = "check", ...rest] = args;
|
|
10402
11164
|
switch (command) {
|
|
10403
11165
|
case "bootstrap":
|
|
10404
|
-
requireNoExtraArgs(rest, "
|
|
11166
|
+
requireNoExtraArgs(rest, "rig setup bootstrap");
|
|
10405
11167
|
{
|
|
10406
11168
|
const hostBash = Bun.which("bash") || "/bin/bash";
|
|
10407
11169
|
const env = { ...process.env };
|
|
@@ -10424,25 +11186,19 @@ async function executeSetup(context, args) {
|
|
|
10424
11186
|
}
|
|
10425
11187
|
return { ok: true, group: "setup", command };
|
|
10426
11188
|
case "check":
|
|
10427
|
-
requireNoExtraArgs(rest, `
|
|
11189
|
+
requireNoExtraArgs(rest, `rig setup ${command}`);
|
|
10428
11190
|
{
|
|
10429
11191
|
const checks = await withMutedConsole(context.outputMode === "json", () => runSetupCheck(context.projectRoot));
|
|
10430
11192
|
return { ok: true, group: "setup", command, details: { checks, failures: countDoctorFailures(checks) } };
|
|
10431
11193
|
}
|
|
10432
11194
|
case "setup":
|
|
10433
|
-
requireNoExtraArgs(rest, "
|
|
11195
|
+
requireNoExtraArgs(rest, "rig setup setup");
|
|
10434
11196
|
withMutedConsole(context.outputMode === "json", () => runSetupInit(context.projectRoot));
|
|
10435
11197
|
return { ok: true, group: "setup", command };
|
|
10436
11198
|
case "preflight":
|
|
10437
|
-
requireNoExtraArgs(rest, "
|
|
11199
|
+
requireNoExtraArgs(rest, "rig setup preflight");
|
|
10438
11200
|
await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
|
|
10439
11201
|
return { ok: true, group: "setup", command };
|
|
10440
|
-
case "install-agent-shell":
|
|
10441
|
-
requireNoExtraArgs(rest, "bun run rig setup install-agent-shell");
|
|
10442
|
-
if (context.outputMode === "text") {
|
|
10443
|
-
console.log("install-agent-shell is deprecated. Runtime shells now use compiled rig-agent directly.");
|
|
10444
|
-
}
|
|
10445
|
-
return { ok: true, group: "setup", command };
|
|
10446
11202
|
default:
|
|
10447
11203
|
throw new CliError2(`Unknown setup command: ${command}`);
|
|
10448
11204
|
}
|
|
@@ -10493,6 +11249,7 @@ async function runSetupPreflight(projectRoot) {
|
|
|
10493
11249
|
}
|
|
10494
11250
|
|
|
10495
11251
|
// packages/cli/src/commands/workspace.ts
|
|
11252
|
+
init_runner();
|
|
10496
11253
|
import {
|
|
10497
11254
|
mutateWorkspaceServiceFabric,
|
|
10498
11255
|
readWorkspaceRemoteFleet,
|
|
@@ -10503,7 +11260,7 @@ async function executeWorkspace(context, args) {
|
|
|
10503
11260
|
const [command = "summary", ...rest] = args;
|
|
10504
11261
|
switch (command) {
|
|
10505
11262
|
case "summary": {
|
|
10506
|
-
requireNoExtraArgs(rest, "
|
|
11263
|
+
requireNoExtraArgs(rest, "rig workspace summary");
|
|
10507
11264
|
const summary = await readWorkspaceSummary(context.projectRoot);
|
|
10508
11265
|
if (context.outputMode === "text") {
|
|
10509
11266
|
console.log("Workspace Summary");
|
|
@@ -10528,7 +11285,7 @@ Warnings:`);
|
|
|
10528
11285
|
return { ok: true, group: "workspace", command, details: summary };
|
|
10529
11286
|
}
|
|
10530
11287
|
case "topology": {
|
|
10531
|
-
requireNoExtraArgs(rest, "
|
|
11288
|
+
requireNoExtraArgs(rest, "rig workspace topology");
|
|
10532
11289
|
const topology = readWorkspaceTopology(context.projectRoot);
|
|
10533
11290
|
if (context.outputMode === "text") {
|
|
10534
11291
|
console.log(`Topology: ${topology.status}`);
|
|
@@ -10541,7 +11298,7 @@ Warnings:`);
|
|
|
10541
11298
|
return { ok: true, group: "workspace", command, details: topology };
|
|
10542
11299
|
}
|
|
10543
11300
|
case "remote-hosts": {
|
|
10544
|
-
requireNoExtraArgs(rest, "
|
|
11301
|
+
requireNoExtraArgs(rest, "rig workspace remote-hosts");
|
|
10545
11302
|
const fleet = readWorkspaceRemoteFleet(context.projectRoot);
|
|
10546
11303
|
if (context.outputMode === "text") {
|
|
10547
11304
|
console.log(`Remote Hosts: ${fleet.status}`);
|
|
@@ -10556,7 +11313,7 @@ Warnings:`);
|
|
|
10556
11313
|
let pending = serviceRest;
|
|
10557
11314
|
const services = takeOption(pending, "--service");
|
|
10558
11315
|
pending = services.rest;
|
|
10559
|
-
requireNoExtraArgs(pending, "
|
|
11316
|
+
requireNoExtraArgs(pending, "rig workspace service-fabric <status|up|verify|down> [--service <name>]");
|
|
10560
11317
|
if (action !== "status" && action !== "up" && action !== "verify" && action !== "down") {
|
|
10561
11318
|
throw new CliError2(`Unknown workspace service-fabric action: ${action}`);
|
|
10562
11319
|
}
|
|
@@ -10577,200 +11334,6 @@ Warnings:`);
|
|
|
10577
11334
|
}
|
|
10578
11335
|
}
|
|
10579
11336
|
|
|
10580
|
-
// packages/cli/src/commands/_help-catalog.ts
|
|
10581
|
-
import pc4 from "picocolors";
|
|
10582
|
-
var PRIMARY_GROUPS = [
|
|
10583
|
-
{
|
|
10584
|
-
name: "init",
|
|
10585
|
-
summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
|
|
10586
|
-
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
10587
|
-
commands: [
|
|
10588
|
-
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
10589
|
-
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
10590
|
-
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
10591
|
-
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
10592
|
-
],
|
|
10593
|
-
examples: [
|
|
10594
|
-
"rig init",
|
|
10595
|
-
"rig init --yes --repo humanity-org/humanwork",
|
|
10596
|
-
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
10597
|
-
],
|
|
10598
|
-
next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
|
|
10599
|
-
},
|
|
10600
|
-
{
|
|
10601
|
-
name: "server",
|
|
10602
|
-
summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
|
|
10603
|
-
usage: ["rig server <status|list|add|use|start> [options]"],
|
|
10604
|
-
commands: [
|
|
10605
|
-
{ command: "status", description: "Show the selected server for this repo.", primary: true },
|
|
10606
|
-
{ command: "list", description: "List saved local/remote server aliases.", primary: true },
|
|
10607
|
-
{ command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
|
|
10608
|
-
{ command: "use [alias|local]", description: "Select a server; prompts in an interactive TTY.", primary: true },
|
|
10609
|
-
{ command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process.", primary: true }
|
|
10610
|
-
],
|
|
10611
|
-
examples: [
|
|
10612
|
-
"rig server status",
|
|
10613
|
-
"rig server add prod https://where.rig-does.work",
|
|
10614
|
-
"rig server use prod",
|
|
10615
|
-
"rig server use local",
|
|
10616
|
-
"rig server start --port 3773"
|
|
10617
|
-
],
|
|
10618
|
-
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
|
|
10619
|
-
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
10620
|
-
},
|
|
10621
|
-
{
|
|
10622
|
-
name: "task",
|
|
10623
|
-
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
10624
|
-
usage: ["rig task <list|next|show|run> [options]"],
|
|
10625
|
-
commands: [
|
|
10626
|
-
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
10627
|
-
{ command: "next [filters]", description: "Pick the next matching task.", primary: true },
|
|
10628
|
-
{ command: "show <id>|--task <id>", description: "Show task details.", primary: true },
|
|
10629
|
-
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
10630
|
-
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
10631
|
-
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
10632
|
-
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
10633
|
-
],
|
|
10634
|
-
examples: [
|
|
10635
|
-
"rig task list --assignee @me --limit 20",
|
|
10636
|
-
"rig task run --next",
|
|
10637
|
-
"rig task run #123 --runtime-adapter pi",
|
|
10638
|
-
"rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
|
|
10639
|
-
],
|
|
10640
|
-
next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
|
|
10641
|
-
},
|
|
10642
|
-
{
|
|
10643
|
-
name: "run",
|
|
10644
|
-
summary: "Observe, attach to, and control Rig runs.",
|
|
10645
|
-
usage: ["rig run <list|status|show|attach|stop> [options]"],
|
|
10646
|
-
commands: [
|
|
10647
|
-
{ command: "list", description: "List recent runs from the selected server or local state.", primary: true },
|
|
10648
|
-
{ command: "status", description: "Summarize active and recent runs.", primary: true },
|
|
10649
|
-
{ command: "show --run <id>", description: "Show one run record.", primary: true },
|
|
10650
|
-
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; `--follow` launches native bundled Pi for live Pi runs.", primary: true },
|
|
10651
|
-
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
10652
|
-
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
10653
|
-
{ command: "delete|cleanup", description: "Remove completed run records/artifacts." }
|
|
10654
|
-
],
|
|
10655
|
-
examples: [
|
|
10656
|
-
"rig run list",
|
|
10657
|
-
"rig run attach 01234567-89ab-cdef-0123-456789abcdef --follow",
|
|
10658
|
-
"rig run show --run <run-id>",
|
|
10659
|
-
"rig run stop <run-id>"
|
|
10660
|
-
],
|
|
10661
|
-
next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
|
|
10662
|
-
}
|
|
10663
|
-
];
|
|
10664
|
-
var ADVANCED_GROUPS = [
|
|
10665
|
-
{ name: "connect", summary: "Compatibility alias for `rig server` selection commands.", usage: ["rig connect <status|list|add|use>"], commands: [{ command: "status|list|add|use", description: "Use `rig server ...` for the primary UX." }] },
|
|
10666
|
-
{ name: "github", summary: "GitHub auth helpers.", usage: ["rig github auth <status|import-gh|token>"], commands: [{ command: "auth status", description: "Show GitHub auth state." }] },
|
|
10667
|
-
{ name: "doctor", summary: "Diagnostics for project/server/GitHub/Pi state.", usage: ["rig doctor [check|run|shared|...]"], commands: [{ command: "check", description: "Run diagnostics." }] },
|
|
10668
|
-
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
10669
|
-
{ name: "inspect", summary: "Inspect logs, artifacts, graphs, failures.", usage: ["rig inspect <logs|artifacts|failures|graph|audit|diff>"], commands: [{ command: "logs --task <id>", description: "Inspect task logs." }] },
|
|
10670
|
-
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
10671
|
-
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
10672
|
-
{ name: "review", summary: "Review policy configuration.", usage: ["rig review <show|set>"], commands: [{ command: "show", description: "Show review settings." }] },
|
|
10673
|
-
{ name: "browser", summary: "Browser/app diagnostics.", usage: ["rig browser <help|explain|demo|app>"], commands: [{ command: "help", description: "Browser command help." }] },
|
|
10674
|
-
{ name: "plugin", summary: "Plugin validation/listing.", usage: ["rig plugin <list|validate>"], commands: [{ command: "list", description: "List plugins." }] },
|
|
10675
|
-
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
10676
|
-
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
10677
|
-
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
10678
|
-
{ name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
|
|
10679
|
-
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
10680
|
-
{ name: "remote", summary: "Legacy remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
|
|
10681
|
-
{ name: "inbox", summary: "Approval/input inbox for blocked runs.", usage: ["rig inbox <approvals|approve|inputs|respond>"], commands: [{ command: "approvals", description: "List pending approvals." }] },
|
|
10682
|
-
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
10683
|
-
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
10684
|
-
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
10685
|
-
];
|
|
10686
|
-
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
10687
|
-
function heading(title) {
|
|
10688
|
-
return pc4.bold(pc4.cyan(title));
|
|
10689
|
-
}
|
|
10690
|
-
function commandLine(command, description) {
|
|
10691
|
-
const commandColumn = command.length >= 34 ? `${command} ` : command.padEnd(34);
|
|
10692
|
-
return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
|
|
10693
|
-
}
|
|
10694
|
-
function renderGroup(group) {
|
|
10695
|
-
const lines = [
|
|
10696
|
-
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
10697
|
-
"",
|
|
10698
|
-
pc4.bold("Usage"),
|
|
10699
|
-
...group.usage.map((line) => ` ${line}`),
|
|
10700
|
-
"",
|
|
10701
|
-
pc4.bold("Commands"),
|
|
10702
|
-
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
10703
|
-
];
|
|
10704
|
-
if (group.examples?.length) {
|
|
10705
|
-
lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
|
|
10706
|
-
}
|
|
10707
|
-
if (group.next?.length) {
|
|
10708
|
-
lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
10709
|
-
}
|
|
10710
|
-
if (group.advanced?.length) {
|
|
10711
|
-
lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
10712
|
-
}
|
|
10713
|
-
return lines.join(`
|
|
10714
|
-
`);
|
|
10715
|
-
}
|
|
10716
|
-
function renderTopLevelHelp() {
|
|
10717
|
-
return [
|
|
10718
|
-
`${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
10719
|
-
pc4.dim("A repo-local CLI for setup, server selection, task runs, live attach, and completion review."),
|
|
10720
|
-
"",
|
|
10721
|
-
`${pc4.bold(pc4.magenta("\u25C7 Start here"))} \u2014 ${pc4.dim("bootstrap a repo and choose where Rig runs")}`,
|
|
10722
|
-
commandLine("rig init", "Interactive setup: project config, GitHub auth, task source, server, checkout, Pi."),
|
|
10723
|
-
commandLine("rig init --yes", "Non-interactive setup using detected defaults; good for repeatable installs."),
|
|
10724
|
-
commandLine("rig server status", "Show whether this repo is using local Rig or a remote server."),
|
|
10725
|
-
commandLine("rig server use <alias|local>", "Switch the server that owns task/run state for this repo."),
|
|
10726
|
-
"",
|
|
10727
|
-
`${pc4.bold(pc4.magenta("\u25C7 Daily task loop"))} \u2014 ${pc4.dim("find work, start a worker, and rejoin it later")}`,
|
|
10728
|
-
commandLine("rig task list", "List tasks from the selected task source/server with status, labels, and source."),
|
|
10729
|
-
commandLine("rig task next", "Pick the next matching task without starting it."),
|
|
10730
|
-
commandLine("rig task run --next", "Start the next task and attach to the live bundled Pi frontend."),
|
|
10731
|
-
commandLine("rig task run #123 --detach", "Submit a specific issue/task and return immediately."),
|
|
10732
|
-
"",
|
|
10733
|
-
`${pc4.bold(pc4.magenta("\u25C7 Live run control"))} \u2014 ${pc4.dim("observe, steer, stop, or inspect active runs")}`,
|
|
10734
|
-
commandLine("rig run list", "Show recent/active runs from the selected server or local state."),
|
|
10735
|
-
commandLine("rig run attach <run-id> --follow", "Open the native Pi live view for a worker-backed run."),
|
|
10736
|
-
commandLine("rig run show --run <id>", "Print one run record; add `--json` for automation."),
|
|
10737
|
-
commandLine("rig run stop <run-id>", "Request cancellation for a running worker."),
|
|
10738
|
-
"",
|
|
10739
|
-
`${pc4.bold(pc4.magenta("\u25C7 Core groups"))} \u2014 ${pc4.dim("run `rig <group> --help` for detailed commands and examples")}`,
|
|
10740
|
-
...PRIMARY_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
10741
|
-
commandLine("doctor", "Diagnose project/server/GitHub/task/Pi wiring when setup or runs misbehave."),
|
|
10742
|
-
"",
|
|
10743
|
-
`${pc4.bold(pc4.magenta("\u25C7 More"))}`,
|
|
10744
|
-
commandLine("rig help --advanced", "Legacy, dev, diagnostics, browser, queue, agent, remote, git, harness commands."),
|
|
10745
|
-
commandLine("rig <group> --help", "Rich per-group help with usage, descriptions, examples, and next steps."),
|
|
10746
|
-
commandLine("rig --version", "Print the installed Rig CLI version."),
|
|
10747
|
-
"",
|
|
10748
|
-
`${pc4.bold(pc4.magenta("\u25C7 Global options"))}`,
|
|
10749
|
-
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
10750
|
-
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
10751
|
-
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
10752
|
-
].join(`
|
|
10753
|
-
`);
|
|
10754
|
-
}
|
|
10755
|
-
function renderAdvancedHelp() {
|
|
10756
|
-
return [
|
|
10757
|
-
`${heading("rig advanced")} \u2014 legacy, dev, and compatibility groups`,
|
|
10758
|
-
"",
|
|
10759
|
-
pc4.bold("Primary groups are still"),
|
|
10760
|
-
" init, server, task, run",
|
|
10761
|
-
"",
|
|
10762
|
-
pc4.bold("Advanced groups"),
|
|
10763
|
-
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
10764
|
-
"",
|
|
10765
|
-
pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, and `rig run` for day-to-day work.")
|
|
10766
|
-
].join(`
|
|
10767
|
-
`);
|
|
10768
|
-
}
|
|
10769
|
-
function renderGroupHelp(groupName) {
|
|
10770
|
-
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
10771
|
-
return group ? renderGroup(group) : null;
|
|
10772
|
-
}
|
|
10773
|
-
|
|
10774
11337
|
// packages/cli/src/commands.ts
|
|
10775
11338
|
import { ensureProjectMainFreshBeforeRun as ensureProjectMainFreshBeforeRun2 } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
10776
11339
|
var TOP_LEVEL_ALIASES = {
|
|
@@ -10778,11 +11341,10 @@ var TOP_LEVEL_ALIASES = {
|
|
|
10778
11341
|
check: ["setup", "check"],
|
|
10779
11342
|
preflight: ["setup", "preflight"],
|
|
10780
11343
|
install: ["dist", "install"],
|
|
10781
|
-
"install-shell": ["setup", "install-agent-shell"],
|
|
10782
11344
|
status: ["run", "status"],
|
|
10783
11345
|
start: ["task", "run", "--next"],
|
|
10784
11346
|
"start-parallel": ["run", "start-parallel"],
|
|
10785
|
-
"start-serial": ["
|
|
11347
|
+
"start-serial": ["run", "start-serial"],
|
|
10786
11348
|
resume: ["run", "resume"],
|
|
10787
11349
|
stop: ["run", "stop"],
|
|
10788
11350
|
ready: ["task", "ready"],
|
|
@@ -10811,6 +11373,30 @@ var TOP_LEVEL_ALIASES = {
|
|
|
10811
11373
|
"remote-watch": ["remote", "watch"],
|
|
10812
11374
|
doctor: ["doctor", "check"]
|
|
10813
11375
|
};
|
|
11376
|
+
var PROJECT_REQUIRED_GROUPS = new Set([
|
|
11377
|
+
"task",
|
|
11378
|
+
"run",
|
|
11379
|
+
"inbox",
|
|
11380
|
+
"review",
|
|
11381
|
+
"queue",
|
|
11382
|
+
"agent",
|
|
11383
|
+
"repo",
|
|
11384
|
+
"inspect"
|
|
11385
|
+
]);
|
|
11386
|
+
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
11387
|
+
function hasInitializedRigProject(projectRoot) {
|
|
11388
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync13(resolve22(projectRoot, name))) || existsSync13(resolve22(projectRoot, ".rig"));
|
|
11389
|
+
}
|
|
11390
|
+
function requireInitializedRigProject(context, group) {
|
|
11391
|
+
if (hasInitializedRigProject(context.projectRoot)) {
|
|
11392
|
+
return;
|
|
11393
|
+
}
|
|
11394
|
+
throw new CliError2([
|
|
11395
|
+
`No Rig project found at ${context.projectRoot} (expected rig.config.ts or a .rig/ state directory).`,
|
|
11396
|
+
"Run `rig init` to set up this repo, or pass --project <path> to point at an existing Rig project."
|
|
11397
|
+
].join(`
|
|
11398
|
+
`), 2);
|
|
11399
|
+
}
|
|
10814
11400
|
var GROUPS = new Set([
|
|
10815
11401
|
"init",
|
|
10816
11402
|
"setup",
|
|
@@ -10838,7 +11424,7 @@ var GROUPS = new Set([
|
|
|
10838
11424
|
"test"
|
|
10839
11425
|
]);
|
|
10840
11426
|
function printGroupHelp(group) {
|
|
10841
|
-
|
|
11427
|
+
printGroupHelpDocument(group);
|
|
10842
11428
|
}
|
|
10843
11429
|
function isHelpArg(arg) {
|
|
10844
11430
|
return arg === "--help" || arg === "-h" || arg === "help";
|
|
@@ -10848,7 +11434,7 @@ function helpText() {
|
|
|
10848
11434
|
}
|
|
10849
11435
|
async function execute(context, args) {
|
|
10850
11436
|
if (args.length === 0) {
|
|
10851
|
-
|
|
11437
|
+
printTopLevelHelp();
|
|
10852
11438
|
return { ok: true, group: "help", command: "show" };
|
|
10853
11439
|
}
|
|
10854
11440
|
const [first, ...rest] = args;
|
|
@@ -10859,14 +11445,14 @@ ${helpText()}`);
|
|
|
10859
11445
|
}
|
|
10860
11446
|
if (first === "help" || first === "--help" || first === "-h") {
|
|
10861
11447
|
if (rest[0] === "--advanced") {
|
|
10862
|
-
|
|
11448
|
+
printAdvancedHelp();
|
|
10863
11449
|
return { ok: true, group: "help", command: "advanced" };
|
|
10864
11450
|
}
|
|
10865
11451
|
if (rest[0]) {
|
|
10866
|
-
|
|
11452
|
+
printGroupHelp(rest[0]);
|
|
10867
11453
|
return { ok: true, group: "help", command: rest[0] };
|
|
10868
11454
|
}
|
|
10869
|
-
|
|
11455
|
+
printTopLevelHelp();
|
|
10870
11456
|
return { ok: true, group: "help", command: "show" };
|
|
10871
11457
|
}
|
|
10872
11458
|
if (first === "--version" || first === "-V" || first === "version") {
|
|
@@ -10908,10 +11494,28 @@ ${helpText()}`);
|
|
|
10908
11494
|
}
|
|
10909
11495
|
return executeGroup(context, group, [command, ...aliasArgs, ...rest]);
|
|
10910
11496
|
}
|
|
11497
|
+
if (await matchesPluginCliCommand(context, first)) {
|
|
11498
|
+
return executeGroup(context, "plugin", ["run", first, ...rest]);
|
|
11499
|
+
}
|
|
10911
11500
|
throw new CliError2(`Unknown group or command: ${first}
|
|
10912
11501
|
|
|
10913
11502
|
${helpText()}`);
|
|
10914
11503
|
}
|
|
11504
|
+
async function matchesPluginCliCommand(context, requested) {
|
|
11505
|
+
if (!hasInitializedRigProject(context.projectRoot)) {
|
|
11506
|
+
return false;
|
|
11507
|
+
}
|
|
11508
|
+
try {
|
|
11509
|
+
const { buildPluginHostContext: buildPluginHostContext3 } = await import("@rig/runtime/control-plane/plugin-host-context");
|
|
11510
|
+
const hostCtx = await buildPluginHostContext3(context.projectRoot);
|
|
11511
|
+
if (!hostCtx)
|
|
11512
|
+
return false;
|
|
11513
|
+
const { resolvePluginCliCommand: resolvePluginCliCommand2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
|
|
11514
|
+
return Boolean(resolvePluginCliCommand2(hostCtx.pluginHost.listCliCommands(), requested));
|
|
11515
|
+
} catch {
|
|
11516
|
+
return false;
|
|
11517
|
+
}
|
|
11518
|
+
}
|
|
10915
11519
|
var GROUPS_WITH_CUSTOM_HELP = new Set(["browser"]);
|
|
10916
11520
|
async function executeGroup(context, group, args) {
|
|
10917
11521
|
if (isHelpArg(args[0]) && !GROUPS_WITH_CUSTOM_HELP.has(group)) {
|
|
@@ -10920,6 +11524,9 @@ async function executeGroup(context, group, args) {
|
|
|
10920
11524
|
}
|
|
10921
11525
|
return { ok: true, group, command: "help" };
|
|
10922
11526
|
}
|
|
11527
|
+
if (PROJECT_REQUIRED_GROUPS.has(group)) {
|
|
11528
|
+
requireInitializedRigProject(context, group);
|
|
11529
|
+
}
|
|
10923
11530
|
switch (group) {
|
|
10924
11531
|
case "setup":
|
|
10925
11532
|
return executeSetup(context, args);
|