@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/index.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
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
|
|
@@ -8,8 +23,6 @@ import { resolve } from "path";
|
|
|
8
23
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
9
24
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
10
25
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
11
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
12
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
13
26
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
14
27
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
15
28
|
function withProjectRoot(projectRoot) {
|
|
@@ -18,7 +31,6 @@ function withProjectRoot(projectRoot) {
|
|
|
18
31
|
function formatCommand(parts) {
|
|
19
32
|
return parts.map((part) => /[^a-zA-Z0-9_./:-]/.test(part) ? JSON.stringify(part) : part).join(" ");
|
|
20
33
|
}
|
|
21
|
-
var AGENT_DISPATCH_SOURCE = "packages/runtime/bin/rig-agent-dispatch.ts";
|
|
22
34
|
function hasAgentDispatchSource(root) {
|
|
23
35
|
return existsSync(resolve(root, AGENT_DISPATCH_SOURCE));
|
|
24
36
|
}
|
|
@@ -63,13 +75,6 @@ async function ensureAgentShellBinary(projectRoot, options = {}) {
|
|
|
63
75
|
}
|
|
64
76
|
async function initializeRuntime(options) {
|
|
65
77
|
const eventBus = new EventBus({ projectRoot: options.projectRoot, runId: options.runId });
|
|
66
|
-
const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
|
|
67
|
-
const plugins = await PluginManager.load({
|
|
68
|
-
projectRoot: options.projectRoot,
|
|
69
|
-
runId: eventBus.getRunId(),
|
|
70
|
-
eventBus,
|
|
71
|
-
runtimeContext
|
|
72
|
-
});
|
|
73
78
|
const context = {
|
|
74
79
|
projectRoot: options.projectRoot,
|
|
75
80
|
dryRun: options.dryRun,
|
|
@@ -77,10 +82,8 @@ async function initializeRuntime(options) {
|
|
|
77
82
|
runId: eventBus.getRunId(),
|
|
78
83
|
policyMode: options.policyMode,
|
|
79
84
|
eventBus,
|
|
80
|
-
plugins,
|
|
81
85
|
emitEvent: async (type, payload) => {
|
|
82
|
-
|
|
83
|
-
await plugins.onEvent(event);
|
|
86
|
+
await eventBus.emit(type, payload);
|
|
84
87
|
}
|
|
85
88
|
};
|
|
86
89
|
context.runCommand = async (parts) => runCommand(context, parts);
|
|
@@ -89,8 +92,7 @@ async function initializeRuntime(options) {
|
|
|
89
92
|
outputMode: context.outputMode,
|
|
90
93
|
dryRun: context.dryRun,
|
|
91
94
|
policyMode: context.policyMode ?? loadPolicy(options.projectRoot).mode,
|
|
92
|
-
policyFile: resolve(options.projectRoot, "rig/policy/policy.json")
|
|
93
|
-
plugins: context.plugins.list()
|
|
95
|
+
policyFile: resolve(options.projectRoot, "rig/policy/policy.json")
|
|
94
96
|
});
|
|
95
97
|
return context;
|
|
96
98
|
}
|
|
@@ -141,7 +143,6 @@ async function runCommand(context, parts) {
|
|
|
141
143
|
});
|
|
142
144
|
throw new CliError(`Policy blocked command: ${formatted}`, 126);
|
|
143
145
|
}
|
|
144
|
-
await context.plugins.beforeCommand({ command: commandWithEnv, formattedCommand: formatted });
|
|
145
146
|
const startedAt = new Date;
|
|
146
147
|
await context.emitEvent("command.started", {
|
|
147
148
|
command: commandWithEnv,
|
|
@@ -161,7 +162,6 @@ async function runCommand(context, parts) {
|
|
|
161
162
|
if (context.outputMode === "text") {
|
|
162
163
|
console.log(`$ ${formatted}`);
|
|
163
164
|
}
|
|
164
|
-
await context.plugins.afterCommand(dryResult);
|
|
165
165
|
await context.emitEvent("command.finished", {
|
|
166
166
|
...dryResult,
|
|
167
167
|
dryRun: true
|
|
@@ -201,7 +201,6 @@ async function runCommand(context, parts) {
|
|
|
201
201
|
stdout: context.outputMode === "json" ? stdout : undefined,
|
|
202
202
|
stderr: context.outputMode === "json" ? stderr : undefined
|
|
203
203
|
};
|
|
204
|
-
await context.plugins.afterCommand(result);
|
|
205
204
|
if (exitCode !== 0) {
|
|
206
205
|
await context.emitEvent("command.failed", {
|
|
207
206
|
...result
|
|
@@ -260,11 +259,278 @@ Usage: ${usage}`);
|
|
|
260
259
|
}
|
|
261
260
|
return taskId;
|
|
262
261
|
}
|
|
262
|
+
var AGENT_DISPATCH_SOURCE = "packages/runtime/bin/rig-agent-dispatch.ts";
|
|
263
|
+
var init_runner = () => {};
|
|
264
|
+
|
|
265
|
+
// packages/cli/src/commands/_parsers.ts
|
|
266
|
+
import { homedir } from "os";
|
|
267
|
+
import { resolve as resolve7 } from "path";
|
|
268
|
+
function parsePositiveInt(value, option, fallback) {
|
|
269
|
+
if (!value) {
|
|
270
|
+
return fallback;
|
|
271
|
+
}
|
|
272
|
+
const parsed = Number.parseInt(value, 10);
|
|
273
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
274
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
275
|
+
}
|
|
276
|
+
return parsed;
|
|
277
|
+
}
|
|
278
|
+
function parseOptionalPositiveInt(value, option) {
|
|
279
|
+
if (!value) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const parsed = Number.parseInt(value, 10);
|
|
283
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
284
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
285
|
+
}
|
|
286
|
+
return parsed;
|
|
287
|
+
}
|
|
288
|
+
function parseRequiredPositiveInt(value, option) {
|
|
289
|
+
if (!value) {
|
|
290
|
+
throw new CliError2(`Missing value for ${option}.`);
|
|
291
|
+
}
|
|
292
|
+
const parsed = Number.parseInt(value, 10);
|
|
293
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
294
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
295
|
+
}
|
|
296
|
+
return parsed;
|
|
297
|
+
}
|
|
298
|
+
function parseAction(value) {
|
|
299
|
+
if (!value || value === "validate") {
|
|
300
|
+
return "validate";
|
|
301
|
+
}
|
|
302
|
+
if (value === "verify") {
|
|
303
|
+
return "verify";
|
|
304
|
+
}
|
|
305
|
+
if (value === "pipeline") {
|
|
306
|
+
return "pipeline";
|
|
307
|
+
}
|
|
308
|
+
throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
|
|
309
|
+
}
|
|
310
|
+
function parseIsolationMode(value, allowOff) {
|
|
311
|
+
if (!value) {
|
|
312
|
+
return "worktree";
|
|
313
|
+
}
|
|
314
|
+
if (value === "worktree") {
|
|
315
|
+
return value;
|
|
316
|
+
}
|
|
317
|
+
if (allowOff && value === "off") {
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
|
|
321
|
+
}
|
|
322
|
+
function parseInstallScope(value) {
|
|
323
|
+
if (!value || value === "user") {
|
|
324
|
+
return "user";
|
|
325
|
+
}
|
|
326
|
+
if (value === "system") {
|
|
327
|
+
return "system";
|
|
328
|
+
}
|
|
329
|
+
throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
|
|
330
|
+
}
|
|
331
|
+
function resolveInstallDir(scope, explicitPath) {
|
|
332
|
+
if (explicitPath) {
|
|
333
|
+
return resolve7(explicitPath);
|
|
334
|
+
}
|
|
335
|
+
if (scope === "system") {
|
|
336
|
+
return "/usr/local/bin";
|
|
337
|
+
}
|
|
338
|
+
return resolve7(homedir(), ".local/bin");
|
|
339
|
+
}
|
|
340
|
+
async function loadRigConfigOrNull(projectRoot) {
|
|
341
|
+
try {
|
|
342
|
+
const { loadConfig } = await import("@rig/core/load-config");
|
|
343
|
+
return await loadConfig(projectRoot);
|
|
344
|
+
} catch {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
var init__parsers = __esm(() => {
|
|
349
|
+
init_runner();
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
// packages/cli/src/commands/plugin.ts
|
|
353
|
+
var exports_plugin = {};
|
|
354
|
+
__export(exports_plugin, {
|
|
355
|
+
resolvePluginCliCommand: () => resolvePluginCliCommand,
|
|
356
|
+
executePlugin: () => executePlugin
|
|
357
|
+
});
|
|
358
|
+
import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
|
|
359
|
+
async function executePlugin(context, args) {
|
|
360
|
+
const [command = "list", ...rest] = args;
|
|
361
|
+
switch (command) {
|
|
362
|
+
case "list": {
|
|
363
|
+
requireNoExtraArgs(rest, "rig plugin list");
|
|
364
|
+
const declarative = [];
|
|
365
|
+
const config = await loadRigConfigOrNull(context.projectRoot);
|
|
366
|
+
if (config && Array.isArray(config.plugins)) {
|
|
367
|
+
for (const plugin of config.plugins) {
|
|
368
|
+
const c = plugin.contributes ?? {};
|
|
369
|
+
declarative.push({
|
|
370
|
+
name: plugin.name,
|
|
371
|
+
version: plugin.version,
|
|
372
|
+
validators: (c.validators ?? []).map((v) => v.id),
|
|
373
|
+
hooks: (c.hooks ?? []).map((h) => h.id),
|
|
374
|
+
agentRoles: (c.agentRoles ?? []).map((r) => r.id),
|
|
375
|
+
repoSources: (c.repoSources ?? []).map((r) => r.id),
|
|
376
|
+
taskSources: (c.taskSources ?? []).map((s) => s.id),
|
|
377
|
+
skills: (c.skills ?? []).map((s) => s.id),
|
|
378
|
+
taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
|
|
379
|
+
cliCommands: (c.cliCommands ?? []).map((entry) => entry.id)
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (context.outputMode === "text") {
|
|
384
|
+
if (declarative.length === 0) {
|
|
385
|
+
console.log("No plugins loaded. Declare plugins in rig.config.ts.");
|
|
386
|
+
} else {
|
|
387
|
+
console.log("Plugins (rig.config.ts):");
|
|
388
|
+
for (const p of declarative) {
|
|
389
|
+
console.log(` ${p.name}@${p.version}`);
|
|
390
|
+
const lines = [];
|
|
391
|
+
if (p.validators.length)
|
|
392
|
+
lines.push(` validators: ${p.validators.join(", ")}`);
|
|
393
|
+
if (p.hooks.length)
|
|
394
|
+
lines.push(` hooks: ${p.hooks.join(", ")}`);
|
|
395
|
+
if (p.agentRoles.length)
|
|
396
|
+
lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
|
|
397
|
+
if (p.repoSources.length)
|
|
398
|
+
lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
|
|
399
|
+
if (p.taskSources.length)
|
|
400
|
+
lines.push(` task-sources: ${p.taskSources.join(", ")}`);
|
|
401
|
+
if (p.skills.length)
|
|
402
|
+
lines.push(` skills: ${p.skills.join(", ")}`);
|
|
403
|
+
if (p.taskFieldExtensions.length)
|
|
404
|
+
lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
|
|
405
|
+
if (p.cliCommands.length)
|
|
406
|
+
lines.push(` cli-commands: ${p.cliCommands.join(", ")} (run with \`rig plugin run <id>\`)`);
|
|
407
|
+
for (const line of lines)
|
|
408
|
+
console.log(line);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
ok: true,
|
|
414
|
+
group: "plugin",
|
|
415
|
+
command,
|
|
416
|
+
details: { declarative }
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
case "validate": {
|
|
420
|
+
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
421
|
+
requireNoExtraArgs(remaining, "rig plugin validate --task <task-id>");
|
|
422
|
+
const taskId = requireTask(task, "rig plugin validate --task <task-id>");
|
|
423
|
+
const hostCtx = await buildPluginHostContext(context.projectRoot);
|
|
424
|
+
if (!hostCtx) {
|
|
425
|
+
throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
|
|
426
|
+
}
|
|
427
|
+
const validators = hostCtx.validatorRegistry.list();
|
|
428
|
+
const results = [];
|
|
429
|
+
for (const validator of validators) {
|
|
430
|
+
try {
|
|
431
|
+
results.push(await validator.run({
|
|
432
|
+
taskId,
|
|
433
|
+
workspaceRoot: context.projectRoot,
|
|
434
|
+
scope: []
|
|
435
|
+
}));
|
|
436
|
+
} catch (error) {
|
|
437
|
+
results.push({
|
|
438
|
+
id: validator.id,
|
|
439
|
+
passed: false,
|
|
440
|
+
summary: `${validator.id} failed unexpectedly`,
|
|
441
|
+
details: `${error}`
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const passed = results.filter((result) => result.passed).length;
|
|
446
|
+
const failed = results.length - passed;
|
|
447
|
+
if (context.outputMode === "text") {
|
|
448
|
+
if (results.length === 0) {
|
|
449
|
+
console.log("No plugin validators registered.");
|
|
450
|
+
} else {
|
|
451
|
+
for (const result of results) {
|
|
452
|
+
const icon = result.passed ? "PASS" : "FAIL";
|
|
453
|
+
console.log(`[${icon}] ${result.id}: ${result.summary}`);
|
|
454
|
+
if (result.details && !result.passed) {
|
|
455
|
+
console.log(result.details);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (failed > 0) {
|
|
461
|
+
throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
ok: true,
|
|
465
|
+
group: "plugin",
|
|
466
|
+
command,
|
|
467
|
+
details: {
|
|
468
|
+
taskId,
|
|
469
|
+
passed,
|
|
470
|
+
failed,
|
|
471
|
+
results
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
case "run": {
|
|
476
|
+
const [commandId, ...commandArgs] = rest;
|
|
477
|
+
if (!commandId) {
|
|
478
|
+
throw new CliError2("Usage: rig plugin run <command-id> [args...]");
|
|
479
|
+
}
|
|
480
|
+
const hostCtx = await buildPluginHostContext(context.projectRoot);
|
|
481
|
+
if (!hostCtx) {
|
|
482
|
+
throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
|
|
483
|
+
}
|
|
484
|
+
const registration = resolvePluginCliCommand(hostCtx.pluginHost.listCliCommands(), commandId);
|
|
485
|
+
if (!registration) {
|
|
486
|
+
const available = hostCtx.pluginHost.listCliCommands().map((entry) => entry.id);
|
|
487
|
+
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);
|
|
488
|
+
}
|
|
489
|
+
if (context.dryRun) {
|
|
490
|
+
if (context.outputMode === "text") {
|
|
491
|
+
console.log(`[dry-run] ${registration.command}${commandArgs.length ? ` ${commandArgs.join(" ")}` : ""}`);
|
|
492
|
+
}
|
|
493
|
+
return { ok: true, group: "plugin", command, details: { id: registration.id, dryRun: true } };
|
|
494
|
+
}
|
|
495
|
+
const proc = Bun.spawn(["bash", "-c", `${registration.command} "$@"`, registration.id, ...commandArgs], {
|
|
496
|
+
cwd: context.projectRoot,
|
|
497
|
+
env: process.env,
|
|
498
|
+
stdin: "inherit",
|
|
499
|
+
stdout: "inherit",
|
|
500
|
+
stderr: "inherit"
|
|
501
|
+
});
|
|
502
|
+
const exitCode = await proc.exited;
|
|
503
|
+
if (exitCode !== 0) {
|
|
504
|
+
throw new CliError2(`Plugin command "${registration.id}" exited with code ${exitCode}.`, exitCode);
|
|
505
|
+
}
|
|
506
|
+
return { ok: true, group: "plugin", command, details: { id: registration.id, exitCode } };
|
|
507
|
+
}
|
|
508
|
+
default:
|
|
509
|
+
throw new CliError2(`Unknown plugin command: ${command}`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
function resolvePluginCliCommand(commands, requested) {
|
|
513
|
+
const exact = commands.find((entry) => entry.id === requested);
|
|
514
|
+
if (exact)
|
|
515
|
+
return exact;
|
|
516
|
+
const byLocalPart = commands.filter((entry) => entry.id.split(":").slice(1).join(":") === requested);
|
|
517
|
+
return byLocalPart.length === 1 ? byLocalPart[0] : undefined;
|
|
518
|
+
}
|
|
519
|
+
var init_plugin = __esm(() => {
|
|
520
|
+
init_runner();
|
|
521
|
+
init__parsers();
|
|
522
|
+
});
|
|
263
523
|
|
|
264
524
|
// packages/cli/src/commands.ts
|
|
525
|
+
init_runner();
|
|
526
|
+
import {
|
|
527
|
+
existsSync as existsSync14
|
|
528
|
+
} from "fs";
|
|
529
|
+
import { resolve as resolve23 } from "path";
|
|
265
530
|
import { readBuildConfig } from "@rig/runtime/build-time-config";
|
|
266
531
|
|
|
267
532
|
// packages/cli/src/commands/browser.ts
|
|
533
|
+
init_runner();
|
|
268
534
|
import { mkdirSync as mkdirSync3, rmSync as rmSync2 } from "fs";
|
|
269
535
|
import { resolve as resolve5 } from "path";
|
|
270
536
|
import { spawn } from "child_process";
|
|
@@ -275,6 +541,7 @@ import pc2 from "picocolors";
|
|
|
275
541
|
import { runCapture as runCapture2 } from "@rig/runtime/control-plane/native/utils";
|
|
276
542
|
|
|
277
543
|
// packages/cli/src/commands/task-report-bug.ts
|
|
544
|
+
init_runner();
|
|
278
545
|
import { existsSync as existsSync3, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
279
546
|
import { resolve as resolve4 } from "path";
|
|
280
547
|
import * as clack from "@clack/prompts";
|
|
@@ -491,15 +758,15 @@ function buildBugReportMarkdown(input, browser, screenshots, assets) {
|
|
|
491
758
|
...input.issueId ? [
|
|
492
759
|
`- Canonical task assets live under \`artifacts/${input.issueId}/bug-report/\`.`,
|
|
493
760
|
`- Start with \`artifacts/${input.issueId}/bug-report/task.md\` and the files in \`artifacts/${input.issueId}/bug-report/assets/\`.`,
|
|
494
|
-
browserRequired ? `- Run \`
|
|
761
|
+
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.`
|
|
495
762
|
] : [
|
|
496
|
-
"- Draft-only report: convert this into a
|
|
763
|
+
"- Draft-only report: convert this into a Rig task before assigning it to an agent run."
|
|
497
764
|
],
|
|
498
765
|
"",
|
|
499
766
|
"## Validation",
|
|
500
767
|
"",
|
|
501
768
|
"```bash",
|
|
502
|
-
...input.issueId ? [`
|
|
769
|
+
...input.issueId ? [`rig task validate --task ${input.issueId}`] : [],
|
|
503
770
|
...browserRequired ? [
|
|
504
771
|
"bun run app:check:browser:hp-next",
|
|
505
772
|
"bun run app:e2e:browser:hp-next"
|
|
@@ -646,7 +913,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
646
913
|
pending = outputRootResult.rest;
|
|
647
914
|
const slugResult = takeOption(pending, "--slug");
|
|
648
915
|
pending = slugResult.rest;
|
|
649
|
-
requireNoExtraArgs(pending, "
|
|
916
|
+
requireNoExtraArgs(pending, "rig report-bug [--no-prompt] [--no-beads] [--browser|--no-browser] --title <text> --url <url> [--asset <dragged-file>]");
|
|
650
917
|
let draft = {
|
|
651
918
|
outputRoot: outputRootResult.value || "",
|
|
652
919
|
title: titleResult.value,
|
|
@@ -751,7 +1018,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
751
1018
|
console.log(`Evidence assets: ${result.assetDir}`);
|
|
752
1019
|
if (taskConfigPath) {
|
|
753
1020
|
console.log(`Task config: ${taskConfigPath}`);
|
|
754
|
-
console.log(`Run:
|
|
1021
|
+
console.log(`Run: rig task info --task ${issueId}`);
|
|
755
1022
|
}
|
|
756
1023
|
}
|
|
757
1024
|
return {
|
|
@@ -1574,7 +1841,7 @@ async function executeBrowser(context, args) {
|
|
|
1574
1841
|
return { ok: true, group: "browser", command: "help" };
|
|
1575
1842
|
}
|
|
1576
1843
|
if (command === "explain") {
|
|
1577
|
-
requireNoExtraArgs(rest, "
|
|
1844
|
+
requireNoExtraArgs(rest, "rig browser explain");
|
|
1578
1845
|
console.log(browserAgentUsageText());
|
|
1579
1846
|
return { ok: true, group: "browser", command: "explain" };
|
|
1580
1847
|
}
|
|
@@ -1600,7 +1867,7 @@ ${browserHelpText()}`);
|
|
|
1600
1867
|
|
|
1601
1868
|
${browserHelpText()}`);
|
|
1602
1869
|
}
|
|
1603
|
-
requireNoExtraArgs(appRest, `
|
|
1870
|
+
requireNoExtraArgs(appRest, `rig browser ${command} ${subcommand}`);
|
|
1604
1871
|
await context.runCommand(["bun", "run", `app:${subcommand}:browser:${appSlug}`]);
|
|
1605
1872
|
return { ok: true, group: "browser", command: `${command}-${subcommand}` };
|
|
1606
1873
|
}
|
|
@@ -1612,7 +1879,7 @@ ${browserHelpText()}`);
|
|
|
1612
1879
|
};
|
|
1613
1880
|
const packageScript = packageScripts[command];
|
|
1614
1881
|
if (packageScript) {
|
|
1615
|
-
requireNoExtraArgs(rest, `
|
|
1882
|
+
requireNoExtraArgs(rest, `rig browser ${command}`);
|
|
1616
1883
|
await context.runCommand(["bun", "run", "--filter=@rig/browser", packageScript]);
|
|
1617
1884
|
return { ok: true, group: "browser", command };
|
|
1618
1885
|
}
|
|
@@ -1639,7 +1906,7 @@ async function executeBrowserDemo(context, args) {
|
|
|
1639
1906
|
pending = keepOpenFlag.rest;
|
|
1640
1907
|
const noBuildFlag = takeFlag(pending, "--no-build");
|
|
1641
1908
|
pending = noBuildFlag.rest;
|
|
1642
|
-
requireNoExtraArgs(pending, "
|
|
1909
|
+
requireNoExtraArgs(pending, "rig browser demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]");
|
|
1643
1910
|
if (context.outputMode !== "text" || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
1644
1911
|
throw new CliError2("rig browser demo requires an interactive TTY in text mode.");
|
|
1645
1912
|
}
|
|
@@ -2099,6 +2366,7 @@ async function stopBrowserDemo(child) {
|
|
|
2099
2366
|
}
|
|
2100
2367
|
|
|
2101
2368
|
// packages/cli/src/commands/profile-and-review.ts
|
|
2369
|
+
init_runner();
|
|
2102
2370
|
import {
|
|
2103
2371
|
setProfile,
|
|
2104
2372
|
setReviewProfile,
|
|
@@ -2150,17 +2418,17 @@ async function executeProfile(context, args) {
|
|
|
2150
2418
|
const [command = "show", ...rest] = args;
|
|
2151
2419
|
switch (command) {
|
|
2152
2420
|
case "show":
|
|
2153
|
-
requireNoExtraArgs(rest, "
|
|
2421
|
+
requireNoExtraArgs(rest, "rig profile show");
|
|
2154
2422
|
await withMutedConsole(context.outputMode === "json", () => showProfile(context.projectRoot));
|
|
2155
2423
|
return { ok: true, group: "profile", command };
|
|
2156
2424
|
case "set": {
|
|
2157
2425
|
if (rest.length === 0) {
|
|
2158
|
-
throw new CliError2("Usage:
|
|
2426
|
+
throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi> or set [--model ...] [--runtime ...] [--plugin ...]");
|
|
2159
2427
|
}
|
|
2160
2428
|
const preset = rest[0];
|
|
2161
2429
|
if (preset && !preset.startsWith("-")) {
|
|
2162
2430
|
if (rest.length !== 1) {
|
|
2163
|
-
throw new CliError2("Usage:
|
|
2431
|
+
throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi>");
|
|
2164
2432
|
}
|
|
2165
2433
|
try {
|
|
2166
2434
|
await withMutedConsole(context.outputMode === "json", () => setProfile(context.projectRoot, { preset }));
|
|
@@ -2176,7 +2444,7 @@ async function executeProfile(context, args) {
|
|
|
2176
2444
|
pending = runtimeResult.rest;
|
|
2177
2445
|
const pluginResult = takeOption(pending, "--plugin");
|
|
2178
2446
|
pending = pluginResult.rest;
|
|
2179
|
-
requireNoExtraArgs(pending, "
|
|
2447
|
+
requireNoExtraArgs(pending, "rig profile set [--model ...] [--runtime ...] [--plugin ...]");
|
|
2180
2448
|
if (!modelResult.value && !runtimeResult.value && !pluginResult.value) {
|
|
2181
2449
|
throw new CliError2("Provide at least one of --model, --runtime, or --plugin.");
|
|
2182
2450
|
}
|
|
@@ -2208,21 +2476,21 @@ async function executeReview(context, args) {
|
|
|
2208
2476
|
const [command = "show", ...rest] = args;
|
|
2209
2477
|
switch (command) {
|
|
2210
2478
|
case "show":
|
|
2211
|
-
requireNoExtraArgs(rest, "
|
|
2479
|
+
requireNoExtraArgs(rest, "rig review show");
|
|
2212
2480
|
await withMutedConsole(context.outputMode === "json", () => showReviewProfile(context.projectRoot));
|
|
2213
2481
|
return { ok: true, group: "review", command };
|
|
2214
2482
|
case "set": {
|
|
2215
2483
|
if (rest.length === 0) {
|
|
2216
|
-
throw new CliError2("Usage:
|
|
2484
|
+
throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
|
|
2217
2485
|
}
|
|
2218
2486
|
const mode = rest[0];
|
|
2219
2487
|
if (!mode) {
|
|
2220
|
-
throw new CliError2("Usage:
|
|
2488
|
+
throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
|
|
2221
2489
|
}
|
|
2222
2490
|
let pending = rest.slice(1);
|
|
2223
2491
|
const providerResult = takeOption(pending, "--provider");
|
|
2224
2492
|
pending = providerResult.rest;
|
|
2225
|
-
requireNoExtraArgs(pending, "
|
|
2493
|
+
requireNoExtraArgs(pending, "rig review set <off|advisory|required> [--provider greptile]");
|
|
2226
2494
|
try {
|
|
2227
2495
|
await withMutedConsole(context.outputMode === "json", () => {
|
|
2228
2496
|
return setReviewProfile(context.projectRoot, mode, providerResult.value);
|
|
@@ -2238,10 +2506,12 @@ async function executeReview(context, args) {
|
|
|
2238
2506
|
}
|
|
2239
2507
|
|
|
2240
2508
|
// packages/cli/src/commands/repo-git-harness.ts
|
|
2509
|
+
init_runner();
|
|
2241
2510
|
import { executeHarnessCommand } from "@rig/runtime/control-plane/native/harness-cli";
|
|
2242
2511
|
import { repoEnsure, resetBaseline } from "@rig/runtime/control-plane/native/repo-ops";
|
|
2243
2512
|
|
|
2244
2513
|
// packages/cli/src/commands/_policy.ts
|
|
2514
|
+
init_runner();
|
|
2245
2515
|
import { appendFileSync, mkdirSync as mkdirSync4 } from "fs";
|
|
2246
2516
|
import { resolve as resolve6 } from "path";
|
|
2247
2517
|
import { evaluate as evaluate2, loadPolicy as loadPolicy2, resolveAction as resolveAction2 } from "@rig/runtime/control-plane/runtime/guard";
|
|
@@ -2307,13 +2577,13 @@ async function executeRepo(context, args) {
|
|
|
2307
2577
|
switch (command) {
|
|
2308
2578
|
case "sync": {
|
|
2309
2579
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
2310
|
-
requireNoExtraArgs(remaining, "
|
|
2580
|
+
requireNoExtraArgs(remaining, "rig repo sync [--task <task-id>]");
|
|
2311
2581
|
withMutedConsole(context.outputMode === "json", () => repoEnsure(context.projectRoot, task || undefined));
|
|
2312
2582
|
return { ok: true, group: "repo", command, details: { task: task || null } };
|
|
2313
2583
|
}
|
|
2314
2584
|
case "reset-baseline": {
|
|
2315
2585
|
const { value: keepTaskStatusFlag, rest: remaining } = takeFlag(rest, "--keep-task-status");
|
|
2316
|
-
requireNoExtraArgs(remaining, "
|
|
2586
|
+
requireNoExtraArgs(remaining, "rig repo reset-baseline [--keep-task-status]");
|
|
2317
2587
|
withMutedConsole(context.outputMode === "json", () => resetBaseline(context.projectRoot, keepTaskStatusFlag));
|
|
2318
2588
|
return { ok: true, group: "repo", command, details: { keepTaskStatus: keepTaskStatusFlag } };
|
|
2319
2589
|
}
|
|
@@ -2323,7 +2593,7 @@ async function executeRepo(context, args) {
|
|
|
2323
2593
|
}
|
|
2324
2594
|
async function executeGit(context, args) {
|
|
2325
2595
|
if (args.length === 0) {
|
|
2326
|
-
throw new CliError2("Usage:
|
|
2596
|
+
throw new CliError2("Usage: rig git <git-flow args...>");
|
|
2327
2597
|
}
|
|
2328
2598
|
await enforceNativeCommandPolicy(context, args, {
|
|
2329
2599
|
commandPrefix: "rig-agent git",
|
|
@@ -2336,7 +2606,7 @@ async function executeGit(context, args) {
|
|
|
2336
2606
|
return { ok: true, group: "git", command: args[0] ?? "git" };
|
|
2337
2607
|
}
|
|
2338
2608
|
try {
|
|
2339
|
-
await executeHarnessCommand(context.projectRoot,
|
|
2609
|
+
await executeHarnessCommand(context.projectRoot, ["git", ...args]);
|
|
2340
2610
|
} catch (error) {
|
|
2341
2611
|
throw new CliError2(error instanceof Error ? error.message : String(error), 2);
|
|
2342
2612
|
}
|
|
@@ -2344,7 +2614,7 @@ async function executeGit(context, args) {
|
|
|
2344
2614
|
}
|
|
2345
2615
|
async function executeHarness(context, args) {
|
|
2346
2616
|
if (args.length === 0) {
|
|
2347
|
-
throw new CliError2("Usage:
|
|
2617
|
+
throw new CliError2("Usage: rig harness <harness args...>");
|
|
2348
2618
|
}
|
|
2349
2619
|
await enforceNativeCommandPolicy(context, args, {
|
|
2350
2620
|
commandPrefix: "rig-agent",
|
|
@@ -2357,236 +2627,49 @@ async function executeHarness(context, args) {
|
|
|
2357
2627
|
return { ok: true, group: "harness", command: args[0] ?? "harness" };
|
|
2358
2628
|
}
|
|
2359
2629
|
try {
|
|
2360
|
-
await executeHarnessCommand(context.projectRoot,
|
|
2630
|
+
await executeHarnessCommand(context.projectRoot, args);
|
|
2361
2631
|
} catch (error) {
|
|
2362
2632
|
throw new CliError2(error instanceof Error ? error.message : String(error), 2);
|
|
2363
2633
|
}
|
|
2364
2634
|
return { ok: true, group: "harness", command: args[0] ?? "harness" };
|
|
2365
2635
|
}
|
|
2366
2636
|
|
|
2367
|
-
// packages/cli/src/commands
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2637
|
+
// packages/cli/src/commands.ts
|
|
2638
|
+
init_plugin();
|
|
2639
|
+
|
|
2640
|
+
// packages/cli/src/commands/queue.ts
|
|
2641
|
+
init_runner();
|
|
2642
|
+
init__parsers();
|
|
2643
|
+
import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
|
|
2644
|
+
|
|
2645
|
+
// packages/cli/src/commands/_preflight.ts
|
|
2646
|
+
init_runner();
|
|
2647
|
+
import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
2648
|
+
|
|
2649
|
+
// packages/cli/src/commands/_connection-state.ts
|
|
2650
|
+
init_runner();
|
|
2651
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2652
|
+
import { homedir as homedir2 } from "os";
|
|
2653
|
+
import { dirname, resolve as resolve8 } from "path";
|
|
2654
|
+
function resolveGlobalConnectionsPath(env = process.env) {
|
|
2655
|
+
const explicit = env.RIG_CONNECTIONS_FILE?.trim();
|
|
2656
|
+
if (explicit)
|
|
2657
|
+
return resolve8(explicit);
|
|
2658
|
+
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2659
|
+
if (stateDir)
|
|
2660
|
+
return resolve8(stateDir, "connections.json");
|
|
2661
|
+
return resolve8(homedir2(), ".rig", "connections.json");
|
|
2379
2662
|
}
|
|
2380
|
-
function
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
}
|
|
2390
|
-
function parseRequiredPositiveInt(value, option) {
|
|
2391
|
-
if (!value) {
|
|
2392
|
-
throw new CliError2(`Missing value for ${option}.`);
|
|
2393
|
-
}
|
|
2394
|
-
const parsed = Number.parseInt(value, 10);
|
|
2395
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
2396
|
-
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
2397
|
-
}
|
|
2398
|
-
return parsed;
|
|
2399
|
-
}
|
|
2400
|
-
function parseAction(value) {
|
|
2401
|
-
if (!value || value === "validate") {
|
|
2402
|
-
return "validate";
|
|
2403
|
-
}
|
|
2404
|
-
if (value === "verify") {
|
|
2405
|
-
return "verify";
|
|
2406
|
-
}
|
|
2407
|
-
if (value === "pipeline") {
|
|
2408
|
-
return "pipeline";
|
|
2409
|
-
}
|
|
2410
|
-
throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
|
|
2411
|
-
}
|
|
2412
|
-
function parseIsolationMode(value, allowOff) {
|
|
2413
|
-
if (!value) {
|
|
2414
|
-
return "worktree";
|
|
2415
|
-
}
|
|
2416
|
-
if (value === "worktree") {
|
|
2417
|
-
return value;
|
|
2418
|
-
}
|
|
2419
|
-
if (allowOff && value === "off") {
|
|
2420
|
-
return value;
|
|
2421
|
-
}
|
|
2422
|
-
throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
|
|
2423
|
-
}
|
|
2424
|
-
function parseInstallScope(value) {
|
|
2425
|
-
if (!value || value === "user") {
|
|
2426
|
-
return "user";
|
|
2427
|
-
}
|
|
2428
|
-
if (value === "system") {
|
|
2429
|
-
return "system";
|
|
2430
|
-
}
|
|
2431
|
-
throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
|
|
2432
|
-
}
|
|
2433
|
-
function resolveInstallDir(scope, explicitPath) {
|
|
2434
|
-
if (explicitPath) {
|
|
2435
|
-
return resolve7(explicitPath);
|
|
2436
|
-
}
|
|
2437
|
-
if (scope === "system") {
|
|
2438
|
-
return "/usr/local/bin";
|
|
2439
|
-
}
|
|
2440
|
-
return resolve7(homedir(), ".local/bin");
|
|
2441
|
-
}
|
|
2442
|
-
async function loadRigConfigOrNull(projectRoot) {
|
|
2443
|
-
try {
|
|
2444
|
-
const { loadConfig } = await import("@rig/core/load-config");
|
|
2445
|
-
return await loadConfig(projectRoot);
|
|
2446
|
-
} catch {
|
|
2447
|
-
return null;
|
|
2448
|
-
}
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
// packages/cli/src/commands/plugin.ts
|
|
2452
|
-
async function executePlugin(context, args) {
|
|
2453
|
-
const [command = "list", ...rest] = args;
|
|
2454
|
-
switch (command) {
|
|
2455
|
-
case "list": {
|
|
2456
|
-
requireNoExtraArgs(rest, "bun run rig plugin list");
|
|
2457
|
-
const legacyPlugins = context.plugins.list();
|
|
2458
|
-
const declarative = [];
|
|
2459
|
-
const config = await loadRigConfigOrNull(context.projectRoot);
|
|
2460
|
-
if (config && Array.isArray(config.plugins)) {
|
|
2461
|
-
for (const plugin of config.plugins) {
|
|
2462
|
-
const c = plugin.contributes ?? {};
|
|
2463
|
-
declarative.push({
|
|
2464
|
-
name: plugin.name,
|
|
2465
|
-
version: plugin.version,
|
|
2466
|
-
validators: (c.validators ?? []).map((v) => v.id),
|
|
2467
|
-
hooks: (c.hooks ?? []).map((h) => h.id),
|
|
2468
|
-
agentRoles: (c.agentRoles ?? []).map((r) => r.id),
|
|
2469
|
-
repoSources: (c.repoSources ?? []).map((r) => r.id),
|
|
2470
|
-
taskSources: (c.taskSources ?? []).map((s) => s.id),
|
|
2471
|
-
skills: (c.skills ?? []).map((s) => s.id),
|
|
2472
|
-
taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
|
|
2473
|
-
cliCommands: (c.cliCommands ?? []).map((c2) => c2.id)
|
|
2474
|
-
});
|
|
2475
|
-
}
|
|
2476
|
-
}
|
|
2477
|
-
if (context.outputMode === "text") {
|
|
2478
|
-
if (legacyPlugins.length === 0 && declarative.length === 0) {
|
|
2479
|
-
console.log("No plugins loaded.");
|
|
2480
|
-
}
|
|
2481
|
-
if (declarative.length > 0) {
|
|
2482
|
-
console.log("Declarative plugins (rig.config.ts):");
|
|
2483
|
-
for (const p of declarative) {
|
|
2484
|
-
console.log(` ${p.name}@${p.version}`);
|
|
2485
|
-
const lines = [];
|
|
2486
|
-
if (p.validators.length)
|
|
2487
|
-
lines.push(` validators: ${p.validators.join(", ")}`);
|
|
2488
|
-
if (p.hooks.length)
|
|
2489
|
-
lines.push(` hooks: ${p.hooks.join(", ")}`);
|
|
2490
|
-
if (p.agentRoles.length)
|
|
2491
|
-
lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
|
|
2492
|
-
if (p.repoSources.length)
|
|
2493
|
-
lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
|
|
2494
|
-
if (p.taskSources.length)
|
|
2495
|
-
lines.push(` task-sources: ${p.taskSources.join(", ")}`);
|
|
2496
|
-
if (p.skills.length)
|
|
2497
|
-
lines.push(` skills: ${p.skills.join(", ")}`);
|
|
2498
|
-
if (p.taskFieldExtensions.length)
|
|
2499
|
-
lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
|
|
2500
|
-
if (p.cliCommands.length)
|
|
2501
|
-
lines.push(` cli-commands: ${p.cliCommands.join(", ")}`);
|
|
2502
|
-
for (const line of lines)
|
|
2503
|
-
console.log(line);
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
if (legacyPlugins.length > 0) {
|
|
2507
|
-
console.log("Legacy disk-scan plugins (rig/plugins/):");
|
|
2508
|
-
for (const plugin of legacyPlugins) {
|
|
2509
|
-
const validators = plugin.validators.length > 0 ? plugin.validators.join(", ") : "none";
|
|
2510
|
-
console.log(` ${plugin.name} (validators: ${validators})`);
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
}
|
|
2514
|
-
return {
|
|
2515
|
-
ok: true,
|
|
2516
|
-
group: "plugin",
|
|
2517
|
-
command,
|
|
2518
|
-
details: { declarative, legacy: legacyPlugins }
|
|
2519
|
-
};
|
|
2520
|
-
}
|
|
2521
|
-
case "validate": {
|
|
2522
|
-
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
2523
|
-
requireNoExtraArgs(remaining, "bun run rig plugin validate --task <beads-id>");
|
|
2524
|
-
const taskId = requireTask(task, "bun run rig plugin validate --task <beads-id>");
|
|
2525
|
-
const results = await context.plugins.runValidators(taskId);
|
|
2526
|
-
const passed = results.filter((result) => result.passed).length;
|
|
2527
|
-
const failed = results.length - passed;
|
|
2528
|
-
if (context.outputMode === "text") {
|
|
2529
|
-
if (results.length === 0) {
|
|
2530
|
-
console.log("No plugin validators registered.");
|
|
2531
|
-
} else {
|
|
2532
|
-
for (const result of results) {
|
|
2533
|
-
const icon = result.passed ? "PASS" : "FAIL";
|
|
2534
|
-
console.log(`[${icon}] ${result.id}: ${result.summary}`);
|
|
2535
|
-
if (result.details && !result.passed) {
|
|
2536
|
-
console.log(result.details);
|
|
2537
|
-
}
|
|
2538
|
-
}
|
|
2539
|
-
}
|
|
2540
|
-
}
|
|
2541
|
-
if (failed > 0) {
|
|
2542
|
-
throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
|
|
2543
|
-
}
|
|
2544
|
-
return {
|
|
2545
|
-
ok: true,
|
|
2546
|
-
group: "plugin",
|
|
2547
|
-
command,
|
|
2548
|
-
details: {
|
|
2549
|
-
taskId,
|
|
2550
|
-
passed,
|
|
2551
|
-
failed,
|
|
2552
|
-
results
|
|
2553
|
-
}
|
|
2554
|
-
};
|
|
2555
|
-
}
|
|
2556
|
-
default:
|
|
2557
|
-
throw new CliError2(`Unknown plugin command: ${command}`);
|
|
2558
|
-
}
|
|
2559
|
-
}
|
|
2560
|
-
|
|
2561
|
-
// packages/cli/src/commands/queue.ts
|
|
2562
|
-
import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
|
|
2563
|
-
|
|
2564
|
-
// packages/cli/src/commands/_preflight.ts
|
|
2565
|
-
import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
2566
|
-
|
|
2567
|
-
// packages/cli/src/commands/_connection-state.ts
|
|
2568
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2569
|
-
import { homedir as homedir2 } from "os";
|
|
2570
|
-
import { dirname, resolve as resolve8 } from "path";
|
|
2571
|
-
function resolveGlobalConnectionsPath(env = process.env) {
|
|
2572
|
-
const explicit = env.RIG_CONNECTIONS_FILE?.trim();
|
|
2573
|
-
if (explicit)
|
|
2574
|
-
return resolve8(explicit);
|
|
2575
|
-
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2576
|
-
if (stateDir)
|
|
2577
|
-
return resolve8(stateDir, "connections.json");
|
|
2578
|
-
return resolve8(homedir2(), ".rig", "connections.json");
|
|
2579
|
-
}
|
|
2580
|
-
function resolveRepoConnectionPath(projectRoot) {
|
|
2581
|
-
return resolve8(projectRoot, ".rig", "state", "connection.json");
|
|
2582
|
-
}
|
|
2583
|
-
function readJsonFile2(path) {
|
|
2584
|
-
if (!existsSync4(path))
|
|
2585
|
-
return null;
|
|
2586
|
-
try {
|
|
2587
|
-
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2588
|
-
} catch (error) {
|
|
2589
|
-
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
2663
|
+
function resolveRepoConnectionPath(projectRoot) {
|
|
2664
|
+
return resolve8(projectRoot, ".rig", "state", "connection.json");
|
|
2665
|
+
}
|
|
2666
|
+
function readJsonFile2(path) {
|
|
2667
|
+
if (!existsSync4(path))
|
|
2668
|
+
return null;
|
|
2669
|
+
try {
|
|
2670
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2671
|
+
} catch (error) {
|
|
2672
|
+
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
2590
2673
|
}
|
|
2591
2674
|
}
|
|
2592
2675
|
function writeJsonFile2(path, value) {
|
|
@@ -2661,12 +2744,13 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
2661
2744
|
const global = readGlobalConnections(options);
|
|
2662
2745
|
const connection = global.connections[repo.selected];
|
|
2663
2746
|
if (!connection) {
|
|
2664
|
-
throw new CliError2(`Selected Rig
|
|
2747
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
2665
2748
|
}
|
|
2666
2749
|
return { alias: repo.selected, connection };
|
|
2667
2750
|
}
|
|
2668
2751
|
|
|
2669
2752
|
// packages/cli/src/commands/_server-client.ts
|
|
2753
|
+
init_runner();
|
|
2670
2754
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
2671
2755
|
import { resolve as resolve9 } from "path";
|
|
2672
2756
|
import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
|
|
@@ -3153,7 +3237,7 @@ async function runFastTaskRunPreflight(context, options = {}) {
|
|
|
3153
3237
|
}
|
|
3154
3238
|
}
|
|
3155
3239
|
const repo = readRepoConnection(context.projectRoot);
|
|
3156
|
-
checks.push(repo ? preflightCheck("project-link", "project linked to Rig
|
|
3240
|
+
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>`."));
|
|
3157
3241
|
try {
|
|
3158
3242
|
const auth = await request("/api/github/auth/status");
|
|
3159
3243
|
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>`."));
|
|
@@ -3271,7 +3355,7 @@ async function executeQueue(context, args) {
|
|
|
3271
3355
|
pending = failFastResult.rest;
|
|
3272
3356
|
const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
|
|
3273
3357
|
pending = skipProjectSyncResult.rest;
|
|
3274
|
-
requireNoExtraArgs(pending, "
|
|
3358
|
+
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]");
|
|
3275
3359
|
const workers = parsePositiveInt(workersResult.value, "--workers", 2);
|
|
3276
3360
|
const maxTasks = parsePositiveInt(maxTasksResult.value, "--max-tasks", 10);
|
|
3277
3361
|
const action = parseAction(actionResult.value);
|
|
@@ -3315,6 +3399,7 @@ async function executeQueue(context, args) {
|
|
|
3315
3399
|
}
|
|
3316
3400
|
|
|
3317
3401
|
// packages/cli/src/commands/agent.ts
|
|
3402
|
+
init_runner();
|
|
3318
3403
|
import { resolve as resolve11 } from "path";
|
|
3319
3404
|
import {
|
|
3320
3405
|
agentId,
|
|
@@ -3422,6 +3507,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
3422
3507
|
}
|
|
3423
3508
|
|
|
3424
3509
|
// packages/cli/src/commands/agent.ts
|
|
3510
|
+
init__parsers();
|
|
3425
3511
|
function splitAtDoubleDash(args) {
|
|
3426
3512
|
const separatorIndex = args.indexOf("--");
|
|
3427
3513
|
if (separatorIndex === -1) {
|
|
@@ -3449,7 +3535,7 @@ async function executeAgent(context, args) {
|
|
|
3449
3535
|
const [command = "list", ...rest] = args;
|
|
3450
3536
|
switch (command) {
|
|
3451
3537
|
case "list": {
|
|
3452
|
-
requireNoExtraArgs(rest, "
|
|
3538
|
+
requireNoExtraArgs(rest, "rig agent list");
|
|
3453
3539
|
const runtimes = await listAgentRuntimes(context.projectRoot);
|
|
3454
3540
|
if (context.outputMode === "text") {
|
|
3455
3541
|
if (runtimes.length === 0) {
|
|
@@ -3470,12 +3556,12 @@ async function executeAgent(context, args) {
|
|
|
3470
3556
|
pending = modeResult.rest;
|
|
3471
3557
|
const taskResult = takeOption(pending, "--task");
|
|
3472
3558
|
pending = taskResult.rest;
|
|
3473
|
-
requireNoExtraArgs(pending, "
|
|
3559
|
+
requireNoExtraArgs(pending, "rig agent prepare --task <id> [--id <id>] [--mode worktree]");
|
|
3474
3560
|
const mode = parseIsolationMode(modeResult.value, false);
|
|
3475
3561
|
const id = idResult.value || agentId("agent");
|
|
3476
3562
|
const taskId = taskResult.value?.trim();
|
|
3477
3563
|
if (!taskId) {
|
|
3478
|
-
throw new CliError2("Usage:
|
|
3564
|
+
throw new CliError2("Usage: rig agent prepare --task <id> [--id <id>] [--mode worktree]");
|
|
3479
3565
|
}
|
|
3480
3566
|
const runtime = await withMutedConsole(context.outputMode === "json", () => ensureAgentRuntime({
|
|
3481
3567
|
projectRoot: context.projectRoot,
|
|
@@ -3493,7 +3579,7 @@ async function executeAgent(context, args) {
|
|
|
3493
3579
|
case "run": {
|
|
3494
3580
|
const { options, commandParts } = splitAtDoubleDash(rest);
|
|
3495
3581
|
if (commandParts.length === 0) {
|
|
3496
|
-
throw new CliError2("Usage:
|
|
3582
|
+
throw new CliError2("Usage: rig agent run [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3497
3583
|
}
|
|
3498
3584
|
let pending = options;
|
|
3499
3585
|
const idResult = takeOption(pending, "--id");
|
|
@@ -3504,12 +3590,12 @@ async function executeAgent(context, args) {
|
|
|
3504
3590
|
pending = taskResult.rest;
|
|
3505
3591
|
const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
|
|
3506
3592
|
pending = skipProjectSyncResult.rest;
|
|
3507
|
-
requireNoExtraArgs(pending, "
|
|
3593
|
+
requireNoExtraArgs(pending, "rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3508
3594
|
const mode = parseIsolationMode(modeResult.value, false);
|
|
3509
3595
|
const id = idResult.value || agentId("agent-run");
|
|
3510
3596
|
const taskId = taskResult.value?.trim();
|
|
3511
3597
|
if (!taskId) {
|
|
3512
|
-
throw new CliError2("Usage:
|
|
3598
|
+
throw new CliError2("Usage: rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3513
3599
|
}
|
|
3514
3600
|
await runProjectMainSyncPreflight(context, { disabled: skipProjectSyncResult.value });
|
|
3515
3601
|
const createdAt = new Date().toISOString();
|
|
@@ -3623,7 +3709,7 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
|
|
|
3623
3709
|
pending = allResult.rest;
|
|
3624
3710
|
const idResult = takeOption(pending, "--id");
|
|
3625
3711
|
pending = idResult.rest;
|
|
3626
|
-
requireNoExtraArgs(pending, "
|
|
3712
|
+
requireNoExtraArgs(pending, "rig agent cleanup (--id <id> | --all)");
|
|
3627
3713
|
if (!allResult.value && !idResult.value) {
|
|
3628
3714
|
throw new CliError2("Provide --id <id> or --all.");
|
|
3629
3715
|
}
|
|
@@ -3655,6 +3741,8 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
|
|
|
3655
3741
|
}
|
|
3656
3742
|
|
|
3657
3743
|
// packages/cli/src/commands/dist.ts
|
|
3744
|
+
init_runner();
|
|
3745
|
+
init__parsers();
|
|
3658
3746
|
import {
|
|
3659
3747
|
chmodSync,
|
|
3660
3748
|
copyFileSync as copyFileSync2,
|
|
@@ -3759,7 +3847,7 @@ async function executeDist(context, args) {
|
|
|
3759
3847
|
switch (command) {
|
|
3760
3848
|
case "build": {
|
|
3761
3849
|
const { value: outputDir, rest: pending } = takeOption(rest, "--output-dir");
|
|
3762
|
-
requireNoExtraArgs(pending, "
|
|
3850
|
+
requireNoExtraArgs(pending, "rig dist build [--output-dir <dir>]");
|
|
3763
3851
|
const commandParts = ["bun", "run", "packages/cli/bin/build-rig-binaries.ts"];
|
|
3764
3852
|
if (outputDir) {
|
|
3765
3853
|
commandParts.push("--output-dir", outputDir);
|
|
@@ -3773,7 +3861,7 @@ async function executeDist(context, args) {
|
|
|
3773
3861
|
pending = scopeResult.rest;
|
|
3774
3862
|
const pathResult = takeOption(pending, "--path");
|
|
3775
3863
|
pending = pathResult.rest;
|
|
3776
|
-
requireNoExtraArgs(pending, "
|
|
3864
|
+
requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
|
|
3777
3865
|
const scope = parseInstallScope(scopeResult.value);
|
|
3778
3866
|
const installDir = resolveInstallDir(scope, pathResult.value);
|
|
3779
3867
|
mkdirSync6(installDir, { recursive: true });
|
|
@@ -3816,7 +3904,7 @@ async function executeDist(context, args) {
|
|
|
3816
3904
|
};
|
|
3817
3905
|
}
|
|
3818
3906
|
case "doctor": {
|
|
3819
|
-
requireNoExtraArgs(rest, "
|
|
3907
|
+
requireNoExtraArgs(rest, "rig dist doctor");
|
|
3820
3908
|
const details = await runDistDoctor(context.projectRoot);
|
|
3821
3909
|
if (context.outputMode === "text") {
|
|
3822
3910
|
console.log(`bun: ${details.bun.available ? `ok (${details.bun.version})` : "missing"}`);
|
|
@@ -3827,7 +3915,7 @@ async function executeDist(context, args) {
|
|
|
3827
3915
|
return { ok: true, group: "dist", command, details };
|
|
3828
3916
|
}
|
|
3829
3917
|
case "rebuild-agent": {
|
|
3830
|
-
requireNoExtraArgs(rest, "
|
|
3918
|
+
requireNoExtraArgs(rest, "rig dist rebuild-agent");
|
|
3831
3919
|
const fp = await computeRuntimeImageFingerprint(context.projectRoot);
|
|
3832
3920
|
const currentId = computeRuntimeImageId(fp);
|
|
3833
3921
|
const imagesDir = resolve12(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
|
|
@@ -3972,6 +4060,7 @@ async function executeDist(context, args) {
|
|
|
3972
4060
|
}
|
|
3973
4061
|
|
|
3974
4062
|
// packages/cli/src/commands/inbox.ts
|
|
4063
|
+
init_runner();
|
|
3975
4064
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
3976
4065
|
import { resolve as resolve13 } from "path";
|
|
3977
4066
|
import {
|
|
@@ -3979,99 +4068,501 @@ import {
|
|
|
3979
4068
|
readJsonlFile as readJsonlFile3,
|
|
3980
4069
|
resolveAuthorityRunDir as resolveAuthorityRunDir2
|
|
3981
4070
|
} from "@rig/runtime/control-plane/authority-files";
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
return
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4071
|
+
|
|
4072
|
+
// packages/cli/src/commands/_cli-format.ts
|
|
4073
|
+
import { log as log3, note as note3 } from "@clack/prompts";
|
|
4074
|
+
import pc3 from "picocolors";
|
|
4075
|
+
function stringField(record, key, fallback = "") {
|
|
4076
|
+
const value = record[key];
|
|
4077
|
+
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
4078
|
+
}
|
|
4079
|
+
function numberField(record, key) {
|
|
4080
|
+
const value = record[key];
|
|
4081
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4082
|
+
}
|
|
4083
|
+
function arrayField(record, key) {
|
|
4084
|
+
const value = record[key];
|
|
4085
|
+
return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
|
|
4086
|
+
}
|
|
4087
|
+
function rawObject(record) {
|
|
4088
|
+
const raw = record.raw;
|
|
4089
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
4090
|
+
}
|
|
4091
|
+
function truncate(value, width) {
|
|
4092
|
+
if (value.length <= width)
|
|
4093
|
+
return value;
|
|
4094
|
+
if (width <= 1)
|
|
4095
|
+
return "\u2026";
|
|
4096
|
+
return `${value.slice(0, width - 1)}\u2026`;
|
|
4097
|
+
}
|
|
4098
|
+
function pad(value, width) {
|
|
4099
|
+
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
4100
|
+
}
|
|
4101
|
+
function statusColor(status) {
|
|
4102
|
+
const normalized = status.toLowerCase();
|
|
4103
|
+
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
|
|
4104
|
+
return pc3.green;
|
|
4105
|
+
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
4106
|
+
return pc3.red;
|
|
4107
|
+
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
4108
|
+
return pc3.cyan;
|
|
4109
|
+
if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
|
|
4110
|
+
return pc3.yellow;
|
|
4111
|
+
return pc3.dim;
|
|
4112
|
+
}
|
|
4113
|
+
function compactDate(value) {
|
|
4114
|
+
if (!value.trim())
|
|
4115
|
+
return "";
|
|
4116
|
+
const parsed = Date.parse(value);
|
|
4117
|
+
if (!Number.isFinite(parsed))
|
|
4118
|
+
return value;
|
|
4119
|
+
return new Date(parsed).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z");
|
|
4120
|
+
}
|
|
4121
|
+
function compactValue(value) {
|
|
4122
|
+
if (value === null || value === undefined)
|
|
4123
|
+
return "";
|
|
4124
|
+
if (typeof value === "string")
|
|
4125
|
+
return value;
|
|
4126
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
4127
|
+
return String(value);
|
|
4128
|
+
if (Array.isArray(value))
|
|
4129
|
+
return value.map(compactValue).filter(Boolean).join(", ");
|
|
4130
|
+
return JSON.stringify(value);
|
|
4131
|
+
}
|
|
4132
|
+
function firstString(record, keys, fallback = "") {
|
|
4133
|
+
for (const key of keys) {
|
|
4134
|
+
const value = stringField(record, key);
|
|
4135
|
+
if (value)
|
|
4136
|
+
return value;
|
|
4137
|
+
}
|
|
4138
|
+
return fallback;
|
|
4139
|
+
}
|
|
4140
|
+
function runIdOf(run) {
|
|
4141
|
+
return firstString(run, ["runId", "id"], "(unknown-run)");
|
|
4142
|
+
}
|
|
4143
|
+
function taskIdOf(run) {
|
|
4144
|
+
return firstString(run, ["taskId", "task", "task_id"]);
|
|
4145
|
+
}
|
|
4146
|
+
function runTitleOf(run) {
|
|
4147
|
+
return firstString(run, ["title", "summary", "name"], taskIdOf(run) || "(untitled)");
|
|
4148
|
+
}
|
|
4149
|
+
function requestIdOf(entry) {
|
|
4150
|
+
return firstString(entry, ["requestId", "id", "approvalId", "inputId"], "(unknown-request)");
|
|
4151
|
+
}
|
|
4152
|
+
function shouldUseClackOutput() {
|
|
4153
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
4154
|
+
}
|
|
4155
|
+
function printFormattedOutput(message2, options = {}) {
|
|
4156
|
+
if (!shouldUseClackOutput()) {
|
|
4157
|
+
console.log(message2);
|
|
4158
|
+
return;
|
|
4159
|
+
}
|
|
4160
|
+
if (options.title)
|
|
4161
|
+
note3(message2, options.title);
|
|
4162
|
+
else
|
|
4163
|
+
log3.message(message2);
|
|
4164
|
+
}
|
|
4165
|
+
function formatStatusPill(status) {
|
|
4166
|
+
const label = status || "unknown";
|
|
4167
|
+
return statusColor(label)(`\u25CF ${label}`);
|
|
4168
|
+
}
|
|
4169
|
+
function formatSection(title, subtitle) {
|
|
4170
|
+
return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
4171
|
+
}
|
|
4172
|
+
function formatSuccessCard(title, rows = []) {
|
|
4173
|
+
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}`);
|
|
4174
|
+
return [formatSection(title), ...body].join(`
|
|
4175
|
+
`);
|
|
4176
|
+
}
|
|
4177
|
+
function formatNextSteps(steps) {
|
|
4178
|
+
if (steps.length === 0)
|
|
4179
|
+
return [];
|
|
4180
|
+
return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
|
|
4181
|
+
}
|
|
4182
|
+
function formatTaskList(tasks, options = {}) {
|
|
4183
|
+
if (options.raw)
|
|
4184
|
+
return tasks.map((task) => JSON.stringify(task)).join(`
|
|
4185
|
+
`);
|
|
4186
|
+
if (tasks.length === 0)
|
|
4187
|
+
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(`
|
|
4188
|
+
`);
|
|
4189
|
+
const rows = tasks.map((task) => {
|
|
4190
|
+
const raw = rawObject(task);
|
|
4191
|
+
const id = stringField(task, "id", "<unknown>");
|
|
4192
|
+
const status = stringField(task, "status", "unknown");
|
|
4193
|
+
const title = stringField(task, "title", "Untitled task");
|
|
4194
|
+
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
4195
|
+
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
4196
|
+
return { id, status, title, source, labels };
|
|
4197
|
+
});
|
|
4198
|
+
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
4199
|
+
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
4200
|
+
const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
4201
|
+
const body = rows.map((row) => {
|
|
4202
|
+
const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
4203
|
+
const source = row.source ? pc3.dim(` ${row.source}`) : "";
|
|
4204
|
+
return [
|
|
4205
|
+
pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
4206
|
+
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
4207
|
+
`${row.title}${labels}${source}`
|
|
4208
|
+
].join(" ");
|
|
4209
|
+
});
|
|
4210
|
+
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(`
|
|
4211
|
+
`);
|
|
4212
|
+
}
|
|
4213
|
+
function formatTaskCard(task, options = {}) {
|
|
4214
|
+
const raw = rawObject(task);
|
|
4215
|
+
const id = stringField(task, "id", stringField(raw, "id", "<unknown>"));
|
|
4216
|
+
const status = stringField(task, "status", stringField(raw, "status", "unknown"));
|
|
4217
|
+
const title = stringField(task, "title", stringField(raw, "title", "Untitled task"));
|
|
4218
|
+
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
4219
|
+
const url = stringField(task, "url", stringField(raw, "url", ""));
|
|
4220
|
+
const number = numberField(task, "number") ?? numberField(raw, "number");
|
|
4221
|
+
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
4222
|
+
const assignees = arrayField(task, "assignees").length > 0 ? arrayField(task, "assignees") : arrayField(raw, "assignees");
|
|
4223
|
+
const readiness = compactValue(task.readiness ?? raw.readiness);
|
|
4224
|
+
const validators = compactValue(task.validators ?? raw.validators ?? task.validation ?? raw.validation);
|
|
4225
|
+
const rows = [
|
|
4226
|
+
["task", pc3.bold(id)],
|
|
4227
|
+
["status", formatStatusPill(status)],
|
|
4228
|
+
["title", title],
|
|
4229
|
+
["source", source],
|
|
4230
|
+
["number", number],
|
|
4231
|
+
["labels", labels.length ? labels.map((label) => `#${label}`).join(" ") : ""],
|
|
4232
|
+
["assignees", assignees.join(", ")],
|
|
4233
|
+
["readiness", readiness],
|
|
4234
|
+
["validators", validators],
|
|
4235
|
+
["url", url]
|
|
4236
|
+
];
|
|
4237
|
+
return [
|
|
4238
|
+
formatSuccessCard(options.title ?? (options.selected ? "Selected task" : "Task"), rows),
|
|
4239
|
+
"",
|
|
4240
|
+
...formatNextSteps([`Start: \`rig task run ${id}\``, `Details: \`rig task show ${id} --raw\``])
|
|
4241
|
+
].join(`
|
|
4242
|
+
`);
|
|
4243
|
+
}
|
|
4244
|
+
function formatTaskDetails(task) {
|
|
4245
|
+
return formatTaskCard(task, { title: "Task details" });
|
|
4246
|
+
}
|
|
4247
|
+
function formatRunList(runs, options = {}) {
|
|
4248
|
+
if (runs.length === 0) {
|
|
4249
|
+
return [
|
|
4250
|
+
formatSection("Runs", "none recorded"),
|
|
4251
|
+
options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
|
|
4252
|
+
"",
|
|
4253
|
+
...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
|
|
4254
|
+
].join(`
|
|
4255
|
+
`);
|
|
4256
|
+
}
|
|
4257
|
+
const rows = runs.map((run) => {
|
|
4258
|
+
const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
|
|
4259
|
+
const status = stringField(run, "status", "unknown");
|
|
4260
|
+
const taskId = stringField(run, "taskId", "");
|
|
4261
|
+
const title = stringField(run, "title", taskId || "(untitled)");
|
|
4262
|
+
const runtime = stringField(run, "runtimeAdapter", "");
|
|
4263
|
+
return { runId, status, title, runtime };
|
|
4264
|
+
});
|
|
4265
|
+
const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
|
|
4266
|
+
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
4267
|
+
const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
4268
|
+
const body = rows.map((row) => [
|
|
4269
|
+
pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
|
|
4270
|
+
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
4271
|
+
`${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
|
|
4272
|
+
].join(" "));
|
|
4273
|
+
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(`
|
|
4274
|
+
`);
|
|
4275
|
+
}
|
|
4276
|
+
function formatSubmittedRun(input) {
|
|
4277
|
+
const rows = [["run", pc3.bold(input.runId)]];
|
|
4278
|
+
if (input.task) {
|
|
4279
|
+
const id = stringField(input.task, "id", "<unknown>");
|
|
4280
|
+
const status = stringField(input.task, "status", "unknown");
|
|
4281
|
+
const title = stringField(input.task, "title", "Untitled task");
|
|
4282
|
+
rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
4283
|
+
}
|
|
4284
|
+
const runtime = [input.runtimeAdapter || "pi", input.runtimeMode || "full-access", input.interactionMode || "default"].filter(Boolean).join(" \xB7 ");
|
|
4285
|
+
rows.push(["runtime", runtime]);
|
|
4286
|
+
return [
|
|
4287
|
+
formatSuccessCard("Run submitted", rows),
|
|
4288
|
+
"",
|
|
4289
|
+
...formatNextSteps([
|
|
4290
|
+
`Attach: \`rig run attach ${input.runId} --follow\``,
|
|
4291
|
+
`Inspect: \`rig run show ${input.runId}\``,
|
|
4292
|
+
input.detached ? "Submitted detached; attach when you are ready." : "Interactive mode opens the native bundled Pi frontend."
|
|
4293
|
+
])
|
|
4294
|
+
].join(`
|
|
4295
|
+
`);
|
|
4296
|
+
}
|
|
4297
|
+
function formatRunCard(run, options = {}) {
|
|
4298
|
+
const raw = rawObject(run);
|
|
4299
|
+
const merged = { ...raw, ...run };
|
|
4300
|
+
const runId = runIdOf(merged);
|
|
4301
|
+
const status = firstString(merged, ["status"], "unknown");
|
|
4302
|
+
const taskId = taskIdOf(merged);
|
|
4303
|
+
const title = runTitleOf(merged);
|
|
4304
|
+
const runtime = firstString(merged, ["runtimeAdapter", "runtime", "adapter"]);
|
|
4305
|
+
const mode = firstString(merged, ["runtimeMode", "mode"]);
|
|
4306
|
+
const interaction = firstString(merged, ["interactionMode"]);
|
|
4307
|
+
const created = compactDate(firstString(merged, ["createdAt"]));
|
|
4308
|
+
const started = compactDate(firstString(merged, ["startedAt"]));
|
|
4309
|
+
const updated = compactDate(firstString(merged, ["updatedAt"]));
|
|
4310
|
+
const completed = compactDate(firstString(merged, ["completedAt", "finishedAt"]));
|
|
4311
|
+
const worktree = firstString(merged, ["worktreePath", "cwd", "projectRoot"]);
|
|
4312
|
+
const piSession = merged.piSession && typeof merged.piSession === "object" && !Array.isArray(merged.piSession) ? firstString(merged.piSession, ["sessionId", "id"]) : "";
|
|
4313
|
+
const timeline = Array.isArray(merged.timeline) ? merged.timeline.length : null;
|
|
4314
|
+
const approvals = Array.isArray(merged.approvals) ? merged.approvals.length : null;
|
|
4315
|
+
const inputs = Array.isArray(merged.userInputs) ? merged.userInputs.length : null;
|
|
4316
|
+
const rows = [
|
|
4317
|
+
["run", pc3.bold(runId)],
|
|
4318
|
+
["status", formatStatusPill(status)],
|
|
4319
|
+
["task", taskId],
|
|
4320
|
+
["title", title],
|
|
4321
|
+
["runtime", [runtime, mode, interaction].filter(Boolean).join(" \xB7 ")],
|
|
4322
|
+
["created", created],
|
|
4323
|
+
["started", started],
|
|
4324
|
+
["updated", updated],
|
|
4325
|
+
["completed", completed],
|
|
4326
|
+
["worktree", worktree],
|
|
4327
|
+
["pi", piSession],
|
|
4328
|
+
["timeline", timeline],
|
|
4329
|
+
["approvals", approvals],
|
|
4330
|
+
["inputs", inputs]
|
|
4331
|
+
];
|
|
4332
|
+
return [
|
|
4333
|
+
formatSuccessCard(options.title ?? "Run details", rows),
|
|
4334
|
+
"",
|
|
4335
|
+
...formatNextSteps([`Follow live: \`rig run attach ${runId} --follow\``, `Raw payload: \`rig run show ${runId} --raw\``])
|
|
4336
|
+
].join(`
|
|
4337
|
+
`);
|
|
4338
|
+
}
|
|
4339
|
+
function formatRunStatus(summary, options = {}) {
|
|
4340
|
+
const activeRuns = summary.activeRuns ?? [];
|
|
4341
|
+
const recentRuns = summary.recentRuns ?? [];
|
|
4342
|
+
const lines = [formatSection("Run status", options.source === "server" ? "selected server" : "local state")];
|
|
4343
|
+
lines.push("", pc3.bold(`Active runs (${activeRuns.length})`));
|
|
4344
|
+
if (activeRuns.length === 0) {
|
|
4345
|
+
lines.push(pc3.dim("No active runs."));
|
|
4346
|
+
} else {
|
|
4347
|
+
for (const run of activeRuns) {
|
|
4348
|
+
lines.push(formatRunSummaryLine(run));
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
lines.push("", pc3.bold(`Recent runs (${recentRuns.length})`));
|
|
4352
|
+
if (recentRuns.length === 0) {
|
|
4353
|
+
lines.push(pc3.dim("No recent terminal runs."));
|
|
4354
|
+
} else {
|
|
4355
|
+
for (const run of recentRuns.slice(0, 10)) {
|
|
4356
|
+
lines.push(formatRunSummaryLine(run));
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
lines.push("", ...formatNextSteps(["Start work: `rig task run --next`", "Attach: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"]));
|
|
4360
|
+
return lines.join(`
|
|
4361
|
+
`);
|
|
4362
|
+
}
|
|
4363
|
+
function formatRunSummaryLine(run) {
|
|
4364
|
+
const record = run;
|
|
4365
|
+
const runId = runIdOf(record);
|
|
4366
|
+
const status = firstString(record, ["status"], "unknown");
|
|
4367
|
+
const taskId = taskIdOf(record);
|
|
4368
|
+
const title = runTitleOf(record);
|
|
4369
|
+
const runtime = firstString(record, ["runtimeAdapter", "runtime", "adapter"]);
|
|
4370
|
+
const descriptor = [taskId, title].filter(Boolean).join(" \xB7 ");
|
|
4371
|
+
return `${pc3.dim("\u2502")} ${pc3.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? pc3.dim(` ${runtime}`) : ""}`;
|
|
4372
|
+
}
|
|
4373
|
+
function formatInboxList(kind, entries) {
|
|
4374
|
+
const title = kind === "approvals" ? "Approval inbox" : "Input inbox";
|
|
4375
|
+
if (entries.length === 0) {
|
|
4376
|
+
return [
|
|
4377
|
+
formatSection(title, "empty"),
|
|
4378
|
+
pc3.dim(kind === "approvals" ? "No pending approvals." : "No pending user-input requests."),
|
|
4379
|
+
"",
|
|
4380
|
+
...formatNextSteps(["Check runs: `rig run status`", "Start work: `rig task run --next`"])
|
|
4381
|
+
].join(`
|
|
4382
|
+
`);
|
|
4383
|
+
}
|
|
4384
|
+
const lines = [formatSection(title, `${entries.length} pending`)];
|
|
4385
|
+
for (const entry of entries) {
|
|
4386
|
+
const record = entry.record && typeof entry.record === "object" && !Array.isArray(entry.record) ? entry.record : entry;
|
|
4387
|
+
const runId = firstString(entry, ["runId"], firstString(record, ["runId"]));
|
|
4388
|
+
const taskId = firstString(entry, ["taskId"], firstString(record, ["taskId", "task"]));
|
|
4389
|
+
const requestId = requestIdOf(record);
|
|
4390
|
+
const status = firstString(record, ["status", "state"], "pending");
|
|
4391
|
+
const prompt = firstString(record, ["prompt", "message", "reason", "title", "summary"], kind === "approvals" ? "Approval requested" : "Input requested");
|
|
4392
|
+
lines.push(`${pc3.dim("\u2502")} ${pc3.bold(requestId)} ${formatStatusPill(status)} ${prompt}`);
|
|
4393
|
+
lines.push(`${pc3.dim("\u2502")} ${pc3.dim("run ")} ${runId || "(unknown-run)"}${taskId ? pc3.dim(` task ${taskId}`) : ""}`);
|
|
4394
|
+
}
|
|
4395
|
+
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`"]));
|
|
4396
|
+
return lines.join(`
|
|
4397
|
+
`);
|
|
4398
|
+
}
|
|
4399
|
+
function formatConnectionList(connections) {
|
|
4400
|
+
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
4401
|
+
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
4402
|
+
const lines = rows.map(([alias, connection]) => [
|
|
4403
|
+
pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
4404
|
+
formatStatusPill(connection.kind),
|
|
4405
|
+
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
4406
|
+
].join(" "));
|
|
4407
|
+
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(`
|
|
4408
|
+
`);
|
|
4409
|
+
}
|
|
4410
|
+
function formatConnectionStatus(selected, connections) {
|
|
4411
|
+
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
4412
|
+
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
4413
|
+
return [
|
|
4414
|
+
formatSection("Rig server", "selected for this repo"),
|
|
4415
|
+
`${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
|
|
4416
|
+
`${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
4417
|
+
`${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
|
|
4418
|
+
"",
|
|
4419
|
+
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
4420
|
+
].join(`
|
|
4421
|
+
`);
|
|
4422
|
+
}
|
|
4423
|
+
|
|
4424
|
+
// packages/cli/src/commands/inbox.ts
|
|
4425
|
+
function isRemoteConnectionSelected(projectRoot) {
|
|
4426
|
+
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
4427
|
+
}
|
|
4428
|
+
function runMatches(entry, filters) {
|
|
4429
|
+
const runId = typeof entry.runId === "string" ? entry.runId : typeof entry.id === "string" ? entry.id : "";
|
|
4430
|
+
const taskId = typeof entry.taskId === "string" ? entry.taskId : "";
|
|
4431
|
+
return (!filters.run || runId === filters.run) && (!filters.task || taskId === filters.task);
|
|
4432
|
+
}
|
|
4433
|
+
function normalizeRemoteRunDetails(payload) {
|
|
4434
|
+
const run = payload.run;
|
|
4435
|
+
if (run && typeof run === "object" && !Array.isArray(run)) {
|
|
4436
|
+
return {
|
|
4437
|
+
...run,
|
|
4438
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
4439
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
4440
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
4441
|
+
};
|
|
4442
|
+
}
|
|
4443
|
+
return payload;
|
|
4444
|
+
}
|
|
4445
|
+
function remoteRecordsFromRun(run, kind) {
|
|
4446
|
+
const key = kind === "approvals" ? "approvals" : "userInputs";
|
|
4447
|
+
const direct = run[key];
|
|
4448
|
+
if (!Array.isArray(direct))
|
|
4449
|
+
return [];
|
|
4450
|
+
const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
|
|
4451
|
+
const taskId = typeof run.taskId === "string" ? run.taskId : "";
|
|
4452
|
+
return direct.filter((record) => Boolean(record && typeof record === "object" && !Array.isArray(record))).map((record) => ({ runId, taskId, record }));
|
|
4453
|
+
}
|
|
4454
|
+
async function listRemoteInboxRecords(context, kind, filters) {
|
|
4455
|
+
const runs = (await listRunsViaServer(context, { limit: 100 })).filter((entry) => runMatches(entry, filters));
|
|
4456
|
+
const records = [];
|
|
4457
|
+
for (const run of runs) {
|
|
4458
|
+
const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
|
|
4459
|
+
const detailed = runId ? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, runId).catch(() => run)) : run;
|
|
4460
|
+
records.push(...remoteRecordsFromRun(detailed, kind));
|
|
4461
|
+
}
|
|
4462
|
+
return records;
|
|
4463
|
+
}
|
|
4464
|
+
function listLocalInboxRecords(context, kind, filters) {
|
|
4465
|
+
const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
|
|
4466
|
+
const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
|
|
4467
|
+
return runs.flatMap((entry) => readJsonlFile3(resolve13(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
|
|
4468
|
+
runId: entry.runId,
|
|
4469
|
+
taskId: entry.taskId ?? undefined,
|
|
4470
|
+
record
|
|
4471
|
+
})));
|
|
4472
|
+
}
|
|
4473
|
+
async function listInboxRecords(context, kind, filters) {
|
|
4474
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4475
|
+
return listRemoteInboxRecords(context, kind, filters);
|
|
4476
|
+
}
|
|
4477
|
+
return listLocalInboxRecords(context, kind, filters);
|
|
4478
|
+
}
|
|
4479
|
+
async function executeInbox(context, args) {
|
|
4480
|
+
const [command = "approvals", ...rest] = args;
|
|
4481
|
+
switch (command) {
|
|
4482
|
+
case "approvals": {
|
|
4483
|
+
let pending = rest;
|
|
4484
|
+
const run = takeOption(pending, "--run");
|
|
4485
|
+
pending = run.rest;
|
|
4486
|
+
const task = takeOption(pending, "--task");
|
|
4487
|
+
pending = task.rest;
|
|
4488
|
+
requireNoExtraArgs(pending, "rig inbox approvals [--run <id>] [--task <id>]");
|
|
4489
|
+
const approvals = await listInboxRecords(context, "approvals", { run: run.value, task: task.value });
|
|
4490
|
+
if (context.outputMode === "text") {
|
|
4491
|
+
printFormattedOutput(formatInboxList("approvals", approvals));
|
|
4492
|
+
}
|
|
4493
|
+
return { ok: true, group: "inbox", command, details: { approvals } };
|
|
4494
|
+
}
|
|
4495
|
+
case "approve": {
|
|
4496
|
+
let pending = rest;
|
|
4497
|
+
const run = takeOption(pending, "--run");
|
|
4498
|
+
pending = run.rest;
|
|
4499
|
+
const request = takeOption(pending, "--request");
|
|
4500
|
+
pending = request.rest;
|
|
4501
|
+
const decision = takeOption(pending, "--decision");
|
|
4502
|
+
pending = decision.rest;
|
|
4503
|
+
const note4 = takeOption(pending, "--note");
|
|
4504
|
+
pending = note4.rest;
|
|
4505
|
+
requireNoExtraArgs(pending, "rig inbox approve --run <id> --request <id> --decision approve|reject [--note <text>]");
|
|
4506
|
+
if (!run.value || !request.value || !decision.value) {
|
|
4507
|
+
throw new CliError2("approve requires --run, --request, and --decision.");
|
|
4508
|
+
}
|
|
4509
|
+
if (decision.value !== "approve" && decision.value !== "reject") {
|
|
4510
|
+
throw new CliError2("decision must be approve or reject.");
|
|
4511
|
+
}
|
|
4512
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4513
|
+
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);
|
|
4514
|
+
}
|
|
4515
|
+
const approvalsPath = resolve13(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
|
|
4516
|
+
const approvals = readJsonlFile3(approvalsPath);
|
|
4517
|
+
const resolvedAt = new Date().toISOString();
|
|
4518
|
+
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);
|
|
4519
|
+
writeFileSync4(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
|
|
4520
|
+
`)}
|
|
4521
|
+
`, "utf8");
|
|
4522
|
+
return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, decision: decision.value } };
|
|
4523
|
+
}
|
|
4524
|
+
case "inputs": {
|
|
4525
|
+
let pending = rest;
|
|
4526
|
+
const run = takeOption(pending, "--run");
|
|
4527
|
+
pending = run.rest;
|
|
4528
|
+
const task = takeOption(pending, "--task");
|
|
4529
|
+
pending = task.rest;
|
|
4530
|
+
requireNoExtraArgs(pending, "rig inbox inputs [--run <id>] [--task <id>]");
|
|
4531
|
+
const requests = await listInboxRecords(context, "inputs", { run: run.value, task: task.value });
|
|
4532
|
+
if (context.outputMode === "text") {
|
|
4533
|
+
printFormattedOutput(formatInboxList("inputs", requests));
|
|
4534
|
+
}
|
|
4535
|
+
return { ok: true, group: "inbox", command, details: { requests } };
|
|
4536
|
+
}
|
|
4537
|
+
case "respond": {
|
|
4538
|
+
let pending = rest;
|
|
4539
|
+
const run = takeOption(pending, "--run");
|
|
4540
|
+
pending = run.rest;
|
|
4541
|
+
const request = takeOption(pending, "--request");
|
|
4542
|
+
pending = request.rest;
|
|
4543
|
+
const answers = [];
|
|
4544
|
+
const remaining = [];
|
|
4545
|
+
for (let index = 0;index < pending.length; index += 1) {
|
|
4546
|
+
const current = pending[index];
|
|
4547
|
+
if (current === "--answer") {
|
|
4548
|
+
const next2 = pending[index + 1];
|
|
4549
|
+
if (!next2 || next2.startsWith("-")) {
|
|
4550
|
+
throw new CliError2("Missing value for --answer");
|
|
4551
|
+
}
|
|
4552
|
+
answers.push(next2);
|
|
4553
|
+
index += 1;
|
|
4554
|
+
continue;
|
|
4555
|
+
}
|
|
4556
|
+
if (current !== undefined) {
|
|
4557
|
+
remaining.push(current);
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
requireNoExtraArgs(remaining, "rig inbox respond --run <id> --request <id> --answer key=value [--answer key=value]");
|
|
4561
|
+
if (!run.value || !request.value || answers.length === 0) {
|
|
4562
|
+
throw new CliError2("respond requires --run, --request, and at least one --answer.");
|
|
4563
|
+
}
|
|
4564
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4565
|
+
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);
|
|
4075
4566
|
}
|
|
4076
4567
|
const parsedAnswers = Object.fromEntries(answers.map((entry) => {
|
|
4077
4568
|
const [key, ...restValue] = entry.split("=");
|
|
@@ -4092,6 +4583,7 @@ async function executeInbox(context, args) {
|
|
|
4092
4583
|
}
|
|
4093
4584
|
|
|
4094
4585
|
// packages/cli/src/commands/init.ts
|
|
4586
|
+
init_runner();
|
|
4095
4587
|
import { appendFileSync as appendFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
4096
4588
|
import { spawnSync } from "child_process";
|
|
4097
4589
|
import { resolve as resolve17 } from "path";
|
|
@@ -4367,9 +4859,11 @@ async function uploadSnapshotArchiveViaServer(context, input) {
|
|
|
4367
4859
|
}
|
|
4368
4860
|
|
|
4369
4861
|
// packages/cli/src/commands/_doctor-checks.ts
|
|
4862
|
+
init_runner();
|
|
4370
4863
|
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
|
|
4371
4864
|
import { resolve as resolve16 } from "path";
|
|
4372
4865
|
import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
|
|
4866
|
+
init__parsers();
|
|
4373
4867
|
function check(id, label, status, detail, remediation) {
|
|
4374
4868
|
return {
|
|
4375
4869
|
id,
|
|
@@ -4496,7 +4990,7 @@ async function runRigDoctorChecks(options) {
|
|
|
4496
4990
|
const taskSourceKind = config?.taskSource?.kind;
|
|
4497
4991
|
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."));
|
|
4498
4992
|
const repo = readRepoConnection(projectRoot);
|
|
4499
|
-
checks.push(repo ? check("project-link", "repo selected Rig
|
|
4993
|
+
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>`."));
|
|
4500
4994
|
const selected = (() => {
|
|
4501
4995
|
try {
|
|
4502
4996
|
return resolveSelectedConnection(projectRoot);
|
|
@@ -4504,7 +4998,7 @@ async function runRigDoctorChecks(options) {
|
|
|
4504
4998
|
return null;
|
|
4505
4999
|
}
|
|
4506
5000
|
})();
|
|
4507
|
-
checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server
|
|
5001
|
+
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));
|
|
4508
5002
|
let server = null;
|
|
4509
5003
|
try {
|
|
4510
5004
|
server = await (options.resolveServer ?? ensureServerForCli)(projectRoot);
|
|
@@ -5301,173 +5795,19 @@ async function executeInit(context, args) {
|
|
|
5301
5795
|
const parsed = parseInitOptions(args);
|
|
5302
5796
|
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) {
|
|
5303
5797
|
if (parsed.rest.length > 0)
|
|
5304
|
-
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5305
|
-
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);
|
|
5306
|
-
return runControlPlaneInit(context, parsed.options);
|
|
5307
|
-
}
|
|
5308
|
-
if (parsed.rest.length > 0)
|
|
5309
|
-
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5310
|
-
Usage: rig init`, 1);
|
|
5311
|
-
return runInteractiveControlPlaneInit(context, await loadClackPrompts());
|
|
5312
|
-
}
|
|
5313
|
-
|
|
5314
|
-
// packages/cli/src/commands/connect.ts
|
|
5315
|
-
import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
|
|
5316
|
-
|
|
5317
|
-
// packages/cli/src/commands/_cli-format.ts
|
|
5318
|
-
import pc3 from "picocolors";
|
|
5319
|
-
function stringField(record, key, fallback = "") {
|
|
5320
|
-
const value = record[key];
|
|
5321
|
-
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
5322
|
-
}
|
|
5323
|
-
function arrayField(record, key) {
|
|
5324
|
-
const value = record[key];
|
|
5325
|
-
return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
|
|
5326
|
-
}
|
|
5327
|
-
function rawObject(record) {
|
|
5328
|
-
const raw = record.raw;
|
|
5329
|
-
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
5330
|
-
}
|
|
5331
|
-
function truncate(value, width) {
|
|
5332
|
-
if (value.length <= width)
|
|
5333
|
-
return value;
|
|
5334
|
-
if (width <= 1)
|
|
5335
|
-
return "\u2026";
|
|
5336
|
-
return `${value.slice(0, width - 1)}\u2026`;
|
|
5337
|
-
}
|
|
5338
|
-
function pad(value, width) {
|
|
5339
|
-
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
5340
|
-
}
|
|
5341
|
-
function statusColor(status) {
|
|
5342
|
-
const normalized = status.toLowerCase();
|
|
5343
|
-
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected"].includes(normalized))
|
|
5344
|
-
return pc3.green;
|
|
5345
|
-
if (["failed", "needs_attention", "needs-attention", "blocked", "error"].includes(normalized))
|
|
5346
|
-
return pc3.red;
|
|
5347
|
-
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
5348
|
-
return pc3.cyan;
|
|
5349
|
-
if (["ready", "open", "queued", "created", "preparing", "local"].includes(normalized))
|
|
5350
|
-
return pc3.yellow;
|
|
5351
|
-
return pc3.dim;
|
|
5352
|
-
}
|
|
5353
|
-
function formatStatusPill(status) {
|
|
5354
|
-
const label = status || "unknown";
|
|
5355
|
-
return statusColor(label)(`\u25CF ${label}`);
|
|
5356
|
-
}
|
|
5357
|
-
function formatSection(title, subtitle) {
|
|
5358
|
-
return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
5359
|
-
}
|
|
5360
|
-
function formatSuccessCard(title, rows = []) {
|
|
5361
|
-
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}`);
|
|
5362
|
-
return [formatSection(title), ...body].join(`
|
|
5363
|
-
`);
|
|
5364
|
-
}
|
|
5365
|
-
function formatNextSteps(steps) {
|
|
5366
|
-
if (steps.length === 0)
|
|
5367
|
-
return [];
|
|
5368
|
-
return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
|
|
5369
|
-
}
|
|
5370
|
-
function formatTaskList(tasks, options = {}) {
|
|
5371
|
-
if (options.raw)
|
|
5372
|
-
return tasks.map((task) => JSON.stringify(task)).join(`
|
|
5373
|
-
`);
|
|
5374
|
-
if (tasks.length === 0)
|
|
5375
|
-
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(`
|
|
5376
|
-
`);
|
|
5377
|
-
const rows = tasks.map((task) => {
|
|
5378
|
-
const raw = rawObject(task);
|
|
5379
|
-
const id = stringField(task, "id", "<unknown>");
|
|
5380
|
-
const status = stringField(task, "status", "unknown");
|
|
5381
|
-
const title = stringField(task, "title", "Untitled task");
|
|
5382
|
-
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
5383
|
-
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
5384
|
-
return { id, status, title, source, labels };
|
|
5385
|
-
});
|
|
5386
|
-
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
5387
|
-
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
5388
|
-
const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
5389
|
-
const body = rows.map((row) => {
|
|
5390
|
-
const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
5391
|
-
const source = row.source ? pc3.dim(` ${row.source}`) : "";
|
|
5392
|
-
return [
|
|
5393
|
-
pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
5394
|
-
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
5395
|
-
`${row.title}${labels}${source}`
|
|
5396
|
-
].join(" ");
|
|
5397
|
-
});
|
|
5398
|
-
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(`
|
|
5399
|
-
`);
|
|
5400
|
-
}
|
|
5401
|
-
function formatRunList(runs, options = {}) {
|
|
5402
|
-
if (runs.length === 0) {
|
|
5403
|
-
return [
|
|
5404
|
-
formatSection("Runs", "none recorded"),
|
|
5405
|
-
options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
|
|
5406
|
-
"",
|
|
5407
|
-
...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
|
|
5408
|
-
].join(`
|
|
5409
|
-
`);
|
|
5410
|
-
}
|
|
5411
|
-
const rows = runs.map((run) => {
|
|
5412
|
-
const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
|
|
5413
|
-
const status = stringField(run, "status", "unknown");
|
|
5414
|
-
const taskId = stringField(run, "taskId", "");
|
|
5415
|
-
const title = stringField(run, "title", taskId || "(untitled)");
|
|
5416
|
-
const runtime = stringField(run, "runtimeAdapter", "");
|
|
5417
|
-
return { runId, status, title, runtime };
|
|
5418
|
-
});
|
|
5419
|
-
const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
|
|
5420
|
-
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
5421
|
-
const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
5422
|
-
const body = rows.map((row) => [
|
|
5423
|
-
pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
|
|
5424
|
-
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
5425
|
-
`${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
|
|
5426
|
-
].join(" "));
|
|
5427
|
-
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(`
|
|
5428
|
-
`);
|
|
5429
|
-
}
|
|
5430
|
-
function formatSubmittedRun(input) {
|
|
5431
|
-
const rows = [["run", pc3.bold(input.runId)]];
|
|
5432
|
-
if (input.task) {
|
|
5433
|
-
const id = stringField(input.task, "id", "<unknown>");
|
|
5434
|
-
const status = stringField(input.task, "status", "unknown");
|
|
5435
|
-
const title = stringField(input.task, "title", "Untitled task");
|
|
5436
|
-
rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
5437
|
-
}
|
|
5438
|
-
return [
|
|
5439
|
-
formatSuccessCard("Run submitted", rows),
|
|
5440
|
-
"",
|
|
5441
|
-
...formatNextSteps([`Attach: \`rig run attach ${input.runId} --follow\``, `Inspect: \`rig run show --run ${input.runId}\``])
|
|
5442
|
-
].join(`
|
|
5443
|
-
`);
|
|
5444
|
-
}
|
|
5445
|
-
function formatConnectionList(connections) {
|
|
5446
|
-
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
5447
|
-
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
5448
|
-
const lines = rows.map(([alias, connection]) => [
|
|
5449
|
-
pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
5450
|
-
formatStatusPill(connection.kind),
|
|
5451
|
-
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
5452
|
-
].join(" "));
|
|
5453
|
-
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(`
|
|
5454
|
-
`);
|
|
5455
|
-
}
|
|
5456
|
-
function formatConnectionStatus(selected, connections) {
|
|
5457
|
-
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
5458
|
-
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
5459
|
-
return [
|
|
5460
|
-
formatSection("Rig server", "selected for this repo"),
|
|
5461
|
-
`${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
|
|
5462
|
-
`${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
5463
|
-
`${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
|
|
5464
|
-
"",
|
|
5465
|
-
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
5466
|
-
].join(`
|
|
5467
|
-
`);
|
|
5798
|
+
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5799
|
+
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);
|
|
5800
|
+
return runControlPlaneInit(context, parsed.options);
|
|
5801
|
+
}
|
|
5802
|
+
if (parsed.rest.length > 0)
|
|
5803
|
+
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5804
|
+
Usage: rig init`, 1);
|
|
5805
|
+
return runInteractiveControlPlaneInit(context, await loadClackPrompts());
|
|
5468
5806
|
}
|
|
5469
5807
|
|
|
5470
5808
|
// packages/cli/src/commands/connect.ts
|
|
5809
|
+
init_runner();
|
|
5810
|
+
import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
|
|
5471
5811
|
function usageName(options) {
|
|
5472
5812
|
return `rig ${options.group}`;
|
|
5473
5813
|
}
|
|
@@ -5579,6 +5919,7 @@ async function executeConnect(context, args) {
|
|
|
5579
5919
|
}
|
|
5580
5920
|
|
|
5581
5921
|
// packages/cli/src/commands/github.ts
|
|
5922
|
+
init_runner();
|
|
5582
5923
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
5583
5924
|
function printPayload(context, payload, fallback) {
|
|
5584
5925
|
if (context.outputMode === "json")
|
|
@@ -5634,6 +5975,7 @@ async function executeGithub(context, args) {
|
|
|
5634
5975
|
}
|
|
5635
5976
|
|
|
5636
5977
|
// packages/cli/src/commands/doctor.ts
|
|
5978
|
+
init_runner();
|
|
5637
5979
|
async function executeDoctor(context, args) {
|
|
5638
5980
|
requireNoExtraArgs(args, "rig doctor");
|
|
5639
5981
|
const checks = await runRigDoctorChecks({ projectRoot: context.projectRoot });
|
|
@@ -5649,6 +5991,7 @@ async function executeDoctor(context, args) {
|
|
|
5649
5991
|
}
|
|
5650
5992
|
|
|
5651
5993
|
// packages/cli/src/commands/_run-driver-helpers.ts
|
|
5994
|
+
init_runner();
|
|
5652
5995
|
import { readFileSync as readFileSync7 } from "fs";
|
|
5653
5996
|
import { resolve as resolve18 } from "path";
|
|
5654
5997
|
import {
|
|
@@ -5876,6 +6219,7 @@ function renderSourceScopeValidation(task, validation) {
|
|
|
5876
6219
|
}
|
|
5877
6220
|
|
|
5878
6221
|
// packages/cli/src/commands/inspect.ts
|
|
6222
|
+
init_runner();
|
|
5879
6223
|
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
|
|
5880
6224
|
import { resolve as resolve19 } from "path";
|
|
5881
6225
|
import {
|
|
@@ -5892,8 +6236,8 @@ async function executeInspect(context, args) {
|
|
|
5892
6236
|
switch (command) {
|
|
5893
6237
|
case "logs": {
|
|
5894
6238
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5895
|
-
requireNoExtraArgs(remaining, "
|
|
5896
|
-
const requiredTask = requireTask(task, "
|
|
6239
|
+
requireNoExtraArgs(remaining, "rig inspect logs --task <task-id>");
|
|
6240
|
+
const requiredTask = requireTask(task, "rig inspect logs --task <task-id>");
|
|
5897
6241
|
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];
|
|
5898
6242
|
if (!latestRun) {
|
|
5899
6243
|
throw new CliError2(`No runs found for ${requiredTask}.`);
|
|
@@ -5907,8 +6251,8 @@ async function executeInspect(context, args) {
|
|
|
5907
6251
|
}
|
|
5908
6252
|
case "artifacts": {
|
|
5909
6253
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5910
|
-
requireNoExtraArgs(remaining, "
|
|
5911
|
-
const requiredTask = requireTask(task, "
|
|
6254
|
+
requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
|
|
6255
|
+
const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
|
|
5912
6256
|
const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync11(path));
|
|
5913
6257
|
if (!artifactRoot) {
|
|
5914
6258
|
throw new CliError2(`No artifacts found for ${requiredTask}.`);
|
|
@@ -5922,8 +6266,8 @@ async function executeInspect(context, args) {
|
|
|
5922
6266
|
previewPending = task.rest;
|
|
5923
6267
|
const file = takeOption(previewPending, "--file");
|
|
5924
6268
|
previewPending = file.rest;
|
|
5925
|
-
requireNoExtraArgs(previewPending, "
|
|
5926
|
-
const requiredTask = requireTask(task.value, "
|
|
6269
|
+
requireNoExtraArgs(previewPending, "rig inspect artifact --task <task-id> --file <name>");
|
|
6270
|
+
const requiredTask = requireTask(task.value, "rig inspect artifact --task <task-id> --file <name>");
|
|
5927
6271
|
if (!file.value) {
|
|
5928
6272
|
throw new CliError2("Missing --file for rig inspect artifact.");
|
|
5929
6273
|
}
|
|
@@ -5952,7 +6296,7 @@ async function executeInspect(context, args) {
|
|
|
5952
6296
|
}
|
|
5953
6297
|
case "diff": {
|
|
5954
6298
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5955
|
-
requireNoExtraArgs(remaining, "
|
|
6299
|
+
requireNoExtraArgs(remaining, "rig inspect diff [--task <task-id>]");
|
|
5956
6300
|
if (task) {
|
|
5957
6301
|
const files = changedFilesForTask(context.projectRoot, task, false);
|
|
5958
6302
|
for (const file of files) {
|
|
@@ -5964,7 +6308,7 @@ async function executeInspect(context, args) {
|
|
|
5964
6308
|
return { ok: true, group: "inspect", command, details: { task: task || null } };
|
|
5965
6309
|
}
|
|
5966
6310
|
case "failures": {
|
|
5967
|
-
requireNoExtraArgs(rest, "
|
|
6311
|
+
requireNoExtraArgs(rest, "rig inspect failures");
|
|
5968
6312
|
const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
|
|
5969
6313
|
if (!existsSync11(failed)) {
|
|
5970
6314
|
console.log("No failures recorded.");
|
|
@@ -5974,7 +6318,7 @@ async function executeInspect(context, args) {
|
|
|
5974
6318
|
return { ok: true, group: "inspect", command };
|
|
5975
6319
|
}
|
|
5976
6320
|
case "graph":
|
|
5977
|
-
requireNoExtraArgs(rest, "
|
|
6321
|
+
requireNoExtraArgs(rest, "rig inspect graph");
|
|
5978
6322
|
{
|
|
5979
6323
|
const monorepoRoot = resolveMonorepoRoot2(context.projectRoot);
|
|
5980
6324
|
const result = runCapture3(["br", "--no-db", "list", "--pretty"], monorepoRoot);
|
|
@@ -5985,7 +6329,7 @@ async function executeInspect(context, args) {
|
|
|
5985
6329
|
}
|
|
5986
6330
|
return { ok: true, group: "inspect", command };
|
|
5987
6331
|
case "audit": {
|
|
5988
|
-
requireNoExtraArgs(rest, "
|
|
6332
|
+
requireNoExtraArgs(rest, "rig inspect audit");
|
|
5989
6333
|
const auditPath = resolve19(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
5990
6334
|
if (!existsSync11(auditPath)) {
|
|
5991
6335
|
console.log("No audit log found.");
|
|
@@ -6003,6 +6347,8 @@ async function executeInspect(context, args) {
|
|
|
6003
6347
|
}
|
|
6004
6348
|
|
|
6005
6349
|
// packages/cli/src/commands/inspector.ts
|
|
6350
|
+
init_runner();
|
|
6351
|
+
init__parsers();
|
|
6006
6352
|
import { iterateServerSentEvents } from "@rig/client";
|
|
6007
6353
|
import { ensureLocalRigServerConnection as ensureLocalRigServerConnection2 } from "@rig/runtime/local-server";
|
|
6008
6354
|
function formatInspectorStreamLine(payload) {
|
|
@@ -6044,7 +6390,7 @@ async function executeInspector(context, args) {
|
|
|
6044
6390
|
pending = secondsResult.rest;
|
|
6045
6391
|
const pollMsResult = takeOption(pending, "--poll-ms");
|
|
6046
6392
|
pending = pollMsResult.rest;
|
|
6047
|
-
requireNoExtraArgs(pending, "
|
|
6393
|
+
requireNoExtraArgs(pending, "rig inspector stream [--once] [--seconds <n>] [--poll-ms <n>]");
|
|
6048
6394
|
const seconds = secondsResult.value ? parseRequiredPositiveInt(secondsResult.value, "--seconds") : null;
|
|
6049
6395
|
const pollMs = pollMsResult.value ? parseRequiredPositiveInt(pollMsResult.value, "--poll-ms") : null;
|
|
6050
6396
|
if (context.outputMode === "json" && !onceResult.value && !seconds) {
|
|
@@ -6138,7 +6484,7 @@ async function executeInspector(context, args) {
|
|
|
6138
6484
|
let pending = rest;
|
|
6139
6485
|
const scanIdResult = takeOption(pending, "--scan-id");
|
|
6140
6486
|
pending = scanIdResult.rest;
|
|
6141
|
-
requireNoExtraArgs(pending, "
|
|
6487
|
+
requireNoExtraArgs(pending, "rig inspector scan-upstream-drift [--scan-id <id>]");
|
|
6142
6488
|
const connection = await ensureLocalRigServerConnection2(context.projectRoot);
|
|
6143
6489
|
const response = await fetch(new URL("/api/inspector/tools/invoke", connection.baseUrl), {
|
|
6144
6490
|
method: "POST",
|
|
@@ -6193,6 +6539,8 @@ async function executeInspector(context, args) {
|
|
|
6193
6539
|
}
|
|
6194
6540
|
|
|
6195
6541
|
// packages/cli/src/commands/remote.ts
|
|
6542
|
+
init_runner();
|
|
6543
|
+
init__parsers();
|
|
6196
6544
|
import {
|
|
6197
6545
|
doctorManagedRemoteEndpoints,
|
|
6198
6546
|
listManagedRemoteEndpoints,
|
|
@@ -6249,7 +6597,7 @@ async function executeRemote(context, args) {
|
|
|
6249
6597
|
const [subcommand = "list", ...subRest] = rest;
|
|
6250
6598
|
switch (subcommand) {
|
|
6251
6599
|
case "list": {
|
|
6252
|
-
requireNoExtraArgs(subRest, "
|
|
6600
|
+
requireNoExtraArgs(subRest, "rig remote endpoint list");
|
|
6253
6601
|
const endpoints = listManagedRemoteEndpoints(undefined, context.projectRoot);
|
|
6254
6602
|
const redactedEndpoints = endpoints.map((endpoint2) => redactRemoteEndpoint(endpoint2));
|
|
6255
6603
|
if (context.outputMode === "text") {
|
|
@@ -6273,7 +6621,7 @@ async function executeRemote(context, args) {
|
|
|
6273
6621
|
pending2 = port.rest;
|
|
6274
6622
|
const token = takeOption(pending2, "--token");
|
|
6275
6623
|
pending2 = token.rest;
|
|
6276
|
-
requireNoExtraArgs(pending2, "
|
|
6624
|
+
requireNoExtraArgs(pending2, "rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>");
|
|
6277
6625
|
if (!alias.value || !host.value || !token.value || !port.value) {
|
|
6278
6626
|
throw new CliError2("remote endpoint add requires --alias, --host, --port, and --token.");
|
|
6279
6627
|
}
|
|
@@ -6300,7 +6648,7 @@ async function executeRemote(context, args) {
|
|
|
6300
6648
|
pending2 = port.rest;
|
|
6301
6649
|
const token = takeOption(pending2, "--token");
|
|
6302
6650
|
pending2 = token.rest;
|
|
6303
|
-
requireNoExtraArgs(pending2, "
|
|
6651
|
+
requireNoExtraArgs(pending2, "rig remote endpoint update --id <id> [--alias <a>] [--host <h>] [--port <n>] [--token <t>]");
|
|
6304
6652
|
if (!endpointId.value && !alias.value) {
|
|
6305
6653
|
throw new CliError2("remote endpoint update requires --id <id> or --alias <a>.");
|
|
6306
6654
|
}
|
|
@@ -6323,7 +6671,7 @@ async function executeRemote(context, args) {
|
|
|
6323
6671
|
let pending2 = subRest;
|
|
6324
6672
|
const alias = takeOption(pending2, "--alias");
|
|
6325
6673
|
pending2 = alias.rest;
|
|
6326
|
-
requireNoExtraArgs(pending2, "
|
|
6674
|
+
requireNoExtraArgs(pending2, "rig remote endpoint remove --alias <a>");
|
|
6327
6675
|
if (!alias.value) {
|
|
6328
6676
|
throw new CliError2("remote endpoint remove requires --alias.");
|
|
6329
6677
|
}
|
|
@@ -6340,7 +6688,7 @@ async function executeRemote(context, args) {
|
|
|
6340
6688
|
let pending2 = subRest;
|
|
6341
6689
|
const alias = takeOption(pending2, "--alias");
|
|
6342
6690
|
pending2 = alias.rest;
|
|
6343
|
-
requireNoExtraArgs(pending2, "
|
|
6691
|
+
requireNoExtraArgs(pending2, "rig remote endpoint test --alias <a>");
|
|
6344
6692
|
if (!alias.value) {
|
|
6345
6693
|
throw new CliError2("remote endpoint test requires --alias.");
|
|
6346
6694
|
}
|
|
@@ -6371,7 +6719,7 @@ async function executeRemote(context, args) {
|
|
|
6371
6719
|
}
|
|
6372
6720
|
}
|
|
6373
6721
|
case "migrate": {
|
|
6374
|
-
requireNoExtraArgs(subRest, "
|
|
6722
|
+
requireNoExtraArgs(subRest, "rig remote endpoint migrate");
|
|
6375
6723
|
const result = migrateManagedRemoteEndpoints(context.projectRoot);
|
|
6376
6724
|
if (context.outputMode === "text") {
|
|
6377
6725
|
console.log(`Imported ${result.imported} endpoint(s) from ${result.sourcePath}${result.skipped > 0 ? `, skipped ${result.skipped}` : ""}.`);
|
|
@@ -6379,7 +6727,7 @@ async function executeRemote(context, args) {
|
|
|
6379
6727
|
return { ok: true, group: "remote", command: "endpoint migrate", details: result };
|
|
6380
6728
|
}
|
|
6381
6729
|
case "doctor": {
|
|
6382
|
-
requireNoExtraArgs(subRest, "
|
|
6730
|
+
requireNoExtraArgs(subRest, "rig remote endpoint doctor");
|
|
6383
6731
|
const result = doctorManagedRemoteEndpoints(context.projectRoot);
|
|
6384
6732
|
if (context.outputMode === "text") {
|
|
6385
6733
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -6432,17 +6780,17 @@ async function executeRemote(context, args) {
|
|
|
6432
6780
|
try {
|
|
6433
6781
|
switch (command) {
|
|
6434
6782
|
case "test": {
|
|
6435
|
-
requireNoExtraArgs(pending, "
|
|
6783
|
+
requireNoExtraArgs(pending, "rig remote test [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6436
6784
|
const response = await withClient((client) => client.ping());
|
|
6437
6785
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6438
6786
|
}
|
|
6439
6787
|
case "status": {
|
|
6440
|
-
requireNoExtraArgs(pending, "
|
|
6788
|
+
requireNoExtraArgs(pending, "rig remote status [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6441
6789
|
const response = await withClient((client) => client.getState());
|
|
6442
6790
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6443
6791
|
}
|
|
6444
6792
|
case "tasks": {
|
|
6445
|
-
requireNoExtraArgs(pending, "
|
|
6793
|
+
requireNoExtraArgs(pending, "rig remote tasks [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6446
6794
|
const response = await withClient((client) => client.getTasks());
|
|
6447
6795
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6448
6796
|
}
|
|
@@ -6452,7 +6800,7 @@ async function executeRemote(context, args) {
|
|
|
6452
6800
|
watchPending = secondsResult.rest;
|
|
6453
6801
|
const eventResult = takeOption(watchPending, "--event");
|
|
6454
6802
|
watchPending = eventResult.rest;
|
|
6455
|
-
requireNoExtraArgs(watchPending, "
|
|
6803
|
+
requireNoExtraArgs(watchPending, "rig remote watch [--seconds <n>] [--event <type>] [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6456
6804
|
const seconds = parseOptionalPositiveInt(secondsResult.value, "--seconds");
|
|
6457
6805
|
const eventFilter = eventResult.value || undefined;
|
|
6458
6806
|
if (context.outputMode === "json" && !seconds) {
|
|
@@ -6521,7 +6869,7 @@ async function executeRemote(context, args) {
|
|
|
6521
6869
|
case "stop":
|
|
6522
6870
|
case "continue":
|
|
6523
6871
|
case "refresh": {
|
|
6524
|
-
requireNoExtraArgs(pending, `
|
|
6872
|
+
requireNoExtraArgs(pending, `rig remote ${command} [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6525
6873
|
const response = await withClient(async (client) => {
|
|
6526
6874
|
switch (command) {
|
|
6527
6875
|
case "pause":
|
|
@@ -6544,7 +6892,7 @@ async function executeRemote(context, args) {
|
|
|
6544
6892
|
let countPending = pending;
|
|
6545
6893
|
const countResult = takeOption(countPending, "--count");
|
|
6546
6894
|
countPending = countResult.rest;
|
|
6547
|
-
requireNoExtraArgs(countPending, `
|
|
6895
|
+
requireNoExtraArgs(countPending, `rig remote ${command} --count <n> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6548
6896
|
const count = parseRequiredPositiveInt(countResult.value, "--count");
|
|
6549
6897
|
const response = await withClient(async (client) => command === "add-iterations" ? await client.addIterations(count) : await client.removeIterations(count));
|
|
6550
6898
|
assertRemoteOperationSuccess(command, response);
|
|
@@ -6555,8 +6903,8 @@ async function executeRemote(context, args) {
|
|
|
6555
6903
|
let taskPending = pending;
|
|
6556
6904
|
const taskResult = takeOption(taskPending, "--task");
|
|
6557
6905
|
taskPending = taskResult.rest;
|
|
6558
|
-
requireNoExtraArgs(taskPending, `
|
|
6559
|
-
const taskId = requireTask(taskResult.value, `
|
|
6906
|
+
requireNoExtraArgs(taskPending, `rig remote ${command} --task <id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6907
|
+
const taskId = requireTask(taskResult.value, `rig remote ${command} --task <id>`);
|
|
6560
6908
|
const response = await withClient(async (client) => command === "prompt-preview" ? await client.getPromptPreview(taskId) : await client.getIterationOutput(taskId));
|
|
6561
6909
|
assertRemoteOperationSuccess(command, response);
|
|
6562
6910
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
@@ -6569,7 +6917,7 @@ async function executeRemote(context, args) {
|
|
|
6569
6917
|
orchestrationPending = maxIterationsResult.rest;
|
|
6570
6918
|
const directMergeResult = takeFlag(orchestrationPending, "--direct-merge");
|
|
6571
6919
|
orchestrationPending = directMergeResult.rest;
|
|
6572
|
-
requireNoExtraArgs(orchestrationPending, "
|
|
6920
|
+
requireNoExtraArgs(orchestrationPending, "rig remote orchestrate-start [--max-workers <n>] [--max-iterations <n>] [--direct-merge]");
|
|
6573
6921
|
const response = await withClient((client) => client.startOrchestration({
|
|
6574
6922
|
maxWorkers: parseOptionalPositiveInt(maxWorkersResult.value, "--max-workers"),
|
|
6575
6923
|
maxIterations: parseOptionalPositiveInt(maxIterationsResult.value, "--max-iterations"),
|
|
@@ -6590,8 +6938,8 @@ async function executeRemote(context, args) {
|
|
|
6590
6938
|
let orchestrationPending = pending;
|
|
6591
6939
|
const idResult = takeOption(orchestrationPending, "--id");
|
|
6592
6940
|
orchestrationPending = idResult.rest;
|
|
6593
|
-
requireNoExtraArgs(orchestrationPending, `
|
|
6594
|
-
const orchestrationId = requireTask(idResult.value, `
|
|
6941
|
+
requireNoExtraArgs(orchestrationPending, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6942
|
+
const orchestrationId = requireTask(idResult.value, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6595
6943
|
const response = await withClient(async (client) => {
|
|
6596
6944
|
switch (command) {
|
|
6597
6945
|
case "orchestrate-pause":
|
|
@@ -6619,6 +6967,8 @@ async function executeRemote(context, args) {
|
|
|
6619
6967
|
}
|
|
6620
6968
|
|
|
6621
6969
|
// packages/cli/src/commands/run.ts
|
|
6970
|
+
init_runner();
|
|
6971
|
+
init__parsers();
|
|
6622
6972
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
6623
6973
|
import {
|
|
6624
6974
|
listAuthorityRuns as listAuthorityRuns3,
|
|
@@ -6636,7 +6986,7 @@ import {
|
|
|
6636
6986
|
startRun,
|
|
6637
6987
|
defaultStartRunOptions
|
|
6638
6988
|
} from "@rig/runtime/control-plane/native/run-ops";
|
|
6639
|
-
import { loadRuntimeContextFromEnv
|
|
6989
|
+
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
6640
6990
|
|
|
6641
6991
|
// packages/cli/src/commands/_operator-surface.ts
|
|
6642
6992
|
import { createInterface } from "readline";
|
|
@@ -6655,8 +7005,8 @@ var CANONICAL_STAGES = [
|
|
|
6655
7005
|
"Merge",
|
|
6656
7006
|
"Complete"
|
|
6657
7007
|
];
|
|
6658
|
-
function logDetail(
|
|
6659
|
-
return typeof
|
|
7008
|
+
function logDetail(log4) {
|
|
7009
|
+
return typeof log4.detail === "string" ? log4.detail.trim() : "";
|
|
6660
7010
|
}
|
|
6661
7011
|
function parseProviderProtocolLog(title, detail) {
|
|
6662
7012
|
if (title.trim().toLowerCase() !== "agent output")
|
|
@@ -6703,12 +7053,12 @@ function renderOperatorSnapshot(snapshot) {
|
|
|
6703
7053
|
const status = String(run.status ?? "unknown");
|
|
6704
7054
|
const logs = snapshot.logs ?? [];
|
|
6705
7055
|
const latestByStage = new Map;
|
|
6706
|
-
for (const
|
|
6707
|
-
const title = String(
|
|
6708
|
-
const stageName = String(
|
|
7056
|
+
for (const log4 of logs) {
|
|
7057
|
+
const title = String(log4.title ?? "").toLowerCase();
|
|
7058
|
+
const stageName = String(log4.stage ?? "").toLowerCase();
|
|
6709
7059
|
const stage = CANONICAL_STAGES.find((candidate) => candidate.toLowerCase() === title || candidate.toLowerCase() === stageName);
|
|
6710
7060
|
if (stage)
|
|
6711
|
-
latestByStage.set(stage,
|
|
7061
|
+
latestByStage.set(stage, log4);
|
|
6712
7062
|
}
|
|
6713
7063
|
const stageLines = CANONICAL_STAGES.flatMap((stage) => {
|
|
6714
7064
|
const match = latestByStage.get(stage);
|
|
@@ -7512,7 +7862,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
7512
7862
|
}
|
|
7513
7863
|
|
|
7514
7864
|
// packages/cli/src/commands/run.ts
|
|
7515
|
-
function
|
|
7865
|
+
function normalizeRemoteRunDetails2(payload) {
|
|
7516
7866
|
const run = payload.run;
|
|
7517
7867
|
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
7518
7868
|
return null;
|
|
@@ -7524,11 +7874,11 @@ function normalizeRemoteRunDetails(payload) {
|
|
|
7524
7874
|
};
|
|
7525
7875
|
}
|
|
7526
7876
|
var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
|
|
7527
|
-
function
|
|
7877
|
+
function isRemoteConnectionSelected2(projectRoot) {
|
|
7528
7878
|
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
7529
7879
|
}
|
|
7530
7880
|
async function listRunsForSelectedConnection(context, options = {}) {
|
|
7531
|
-
if (
|
|
7881
|
+
if (isRemoteConnectionSelected2(context.projectRoot)) {
|
|
7532
7882
|
return { runs: await listRunsViaServer(context, options), source: "server" };
|
|
7533
7883
|
}
|
|
7534
7884
|
return { runs: listAuthorityRuns3(context.projectRoot), source: "local" };
|
|
@@ -7537,9 +7887,6 @@ function runStringField(run, key, fallback = "") {
|
|
|
7537
7887
|
const value = run[key];
|
|
7538
7888
|
return typeof value === "string" && value.trim() ? value : fallback;
|
|
7539
7889
|
}
|
|
7540
|
-
function runDisplayTitle(run) {
|
|
7541
|
-
return runStringField(run, "title", runStringField(run, "taskId", "(untitled)"));
|
|
7542
|
-
}
|
|
7543
7890
|
function buildServerRunStatus(runs) {
|
|
7544
7891
|
const activeRuns = runs.filter((run) => !REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
7545
7892
|
const recentRuns = runs.filter((run) => REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
@@ -7606,13 +7953,13 @@ async function promptForEpicSelection(projectRoot, command) {
|
|
|
7606
7953
|
}
|
|
7607
7954
|
async function executeRun(context, args) {
|
|
7608
7955
|
const [command = "status", ...rest] = args;
|
|
7609
|
-
const runtimeContext =
|
|
7956
|
+
const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
|
|
7610
7957
|
switch (command) {
|
|
7611
7958
|
case "list": {
|
|
7612
|
-
requireNoExtraArgs(rest, "
|
|
7959
|
+
requireNoExtraArgs(rest, "rig run list");
|
|
7613
7960
|
const { runs, source } = await listRunsForSelectedConnection(context, { limit: 100 });
|
|
7614
7961
|
if (context.outputMode === "text") {
|
|
7615
|
-
|
|
7962
|
+
printFormattedOutput(formatRunList(runs, { source }));
|
|
7616
7963
|
}
|
|
7617
7964
|
return { ok: true, group: "run", command, details: { runs, source } };
|
|
7618
7965
|
}
|
|
@@ -7622,7 +7969,7 @@ async function executeRun(context, args) {
|
|
|
7622
7969
|
pending = run.rest;
|
|
7623
7970
|
const purgeArtifacts = takeFlag(pending, "--purge-artifacts");
|
|
7624
7971
|
pending = purgeArtifacts.rest;
|
|
7625
|
-
requireNoExtraArgs(pending, "
|
|
7972
|
+
requireNoExtraArgs(pending, "rig run delete --run <id> [--purge-artifacts]");
|
|
7626
7973
|
if (!run.value) {
|
|
7627
7974
|
throw new CliError2("run delete requires --run <id>.");
|
|
7628
7975
|
}
|
|
@@ -7652,7 +7999,7 @@ async function executeRun(context, args) {
|
|
|
7652
7999
|
pending = keepRuntimes.rest;
|
|
7653
8000
|
const keepQueue = takeFlag(pending, "--keep-queue");
|
|
7654
8001
|
pending = keepQueue.rest;
|
|
7655
|
-
requireNoExtraArgs(pending, "
|
|
8002
|
+
requireNoExtraArgs(pending, "rig run cleanup --all [--keep-artifacts] [--keep-runtimes] [--keep-queue]");
|
|
7656
8003
|
if (!all.value) {
|
|
7657
8004
|
throw new CliError2("run cleanup currently requires --all.");
|
|
7658
8005
|
}
|
|
@@ -7671,20 +8018,25 @@ async function executeRun(context, args) {
|
|
|
7671
8018
|
}
|
|
7672
8019
|
case "show": {
|
|
7673
8020
|
let pending = rest;
|
|
8021
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
8022
|
+
pending = rawResult.rest;
|
|
7674
8023
|
const run = takeOption(pending, "--run");
|
|
7675
8024
|
pending = run.rest;
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
8025
|
+
const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
|
|
8026
|
+
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
8027
|
+
requireNoExtraArgs(extra, "rig run show <id>|--run <id> [--raw]");
|
|
8028
|
+
const runId = run.value ?? positionalRunId;
|
|
8029
|
+
if (!runId) {
|
|
8030
|
+
throw new CliError2("run show requires a run id.");
|
|
7679
8031
|
}
|
|
7680
|
-
const record = readAuthorityRun4(context.projectRoot,
|
|
8032
|
+
const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
|
|
7681
8033
|
if (!record) {
|
|
7682
|
-
throw new CliError2(`Run not found: ${
|
|
8034
|
+
throw new CliError2(`Run not found: ${runId}`, 2);
|
|
7683
8035
|
}
|
|
7684
8036
|
if (context.outputMode === "text") {
|
|
7685
|
-
|
|
8037
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(record, null, 2) : formatRunCard(record));
|
|
7686
8038
|
}
|
|
7687
|
-
return { ok: true, group: "run", command, details: record };
|
|
8039
|
+
return { ok: true, group: "run", command, details: { ...record, rawOutput: rawResult.value } };
|
|
7688
8040
|
}
|
|
7689
8041
|
case "timeline": {
|
|
7690
8042
|
let pending = rest;
|
|
@@ -7692,7 +8044,7 @@ async function executeRun(context, args) {
|
|
|
7692
8044
|
pending = run.rest;
|
|
7693
8045
|
const follow = takeFlag(pending, "--follow");
|
|
7694
8046
|
pending = follow.rest;
|
|
7695
|
-
requireNoExtraArgs(pending, "
|
|
8047
|
+
requireNoExtraArgs(pending, "rig run timeline --run <id> [--follow]");
|
|
7696
8048
|
if (!run.value) {
|
|
7697
8049
|
throw new CliError2("run timeline requires --run <id>.");
|
|
7698
8050
|
}
|
|
@@ -7729,7 +8081,7 @@ async function executeRun(context, args) {
|
|
|
7729
8081
|
pending = pollMs.rest;
|
|
7730
8082
|
const positionalRunId = pending.length > 0 ? pending[0] : undefined;
|
|
7731
8083
|
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
7732
|
-
requireNoExtraArgs(extra, "
|
|
8084
|
+
requireNoExtraArgs(extra, "rig run attach <run-id>|--run <run-id> [--message <text>] [--once|--follow] [--poll-ms <ms>]");
|
|
7733
8085
|
const runId = runOption.value ?? positionalRunId;
|
|
7734
8086
|
if (!runId) {
|
|
7735
8087
|
throw new CliError2("run attach requires a run id.", 2);
|
|
@@ -7749,28 +8101,18 @@ async function executeRun(context, args) {
|
|
|
7749
8101
|
return { ok: true, group: "run", command, details: { ...attached, steered: attached.steered || steered } };
|
|
7750
8102
|
}
|
|
7751
8103
|
case "status": {
|
|
7752
|
-
requireNoExtraArgs(rest, "
|
|
8104
|
+
requireNoExtraArgs(rest, "rig run status");
|
|
7753
8105
|
if (context.dryRun) {
|
|
7754
8106
|
if (context.outputMode === "text") {
|
|
7755
8107
|
console.log("[dry-run] rig run status");
|
|
7756
8108
|
}
|
|
7757
8109
|
return { ok: true, group: "run", command };
|
|
7758
8110
|
}
|
|
7759
|
-
const summary =
|
|
8111
|
+
const summary = isRemoteConnectionSelected2(context.projectRoot) ? buildServerRunStatus(await listRunsViaServer(context, { limit: 100 })) : runStatus(context.projectRoot, runtimeContext);
|
|
7760
8112
|
const activeRuns = Array.isArray(summary.activeRuns) ? summary.activeRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
7761
8113
|
const recentRuns = Array.isArray(summary.recentRuns) ? summary.recentRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
7762
8114
|
if (context.outputMode === "text") {
|
|
7763
|
-
|
|
7764
|
-
for (const run of activeRuns) {
|
|
7765
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
7766
|
-
}
|
|
7767
|
-
if (recentRuns.length > 0) {
|
|
7768
|
-
console.log("");
|
|
7769
|
-
console.log("Recent runs:");
|
|
7770
|
-
for (const run of recentRuns) {
|
|
7771
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
7772
|
-
}
|
|
7773
|
-
}
|
|
8115
|
+
printFormattedOutput(formatRunStatus({ activeRuns, recentRuns, runs: Array.isArray(summary.runs) ? summary.runs : [...activeRuns, ...recentRuns] }, { source: isRemoteConnectionSelected2(context.projectRoot) ? "server" : "local" }));
|
|
7774
8116
|
}
|
|
7775
8117
|
return { ok: true, group: "run", command, details: summary };
|
|
7776
8118
|
}
|
|
@@ -7794,7 +8136,7 @@ async function executeRun(context, args) {
|
|
|
7794
8136
|
pending = pollResult.rest;
|
|
7795
8137
|
const noServerResult = takeFlag(pending, "--no-server");
|
|
7796
8138
|
pending = noServerResult.rest;
|
|
7797
|
-
requireNoExtraArgs(pending, "
|
|
8139
|
+
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]");
|
|
7798
8140
|
if (promptEpicResult.value && noEpicPromptResult.value) {
|
|
7799
8141
|
throw new CliError2("Cannot use --prompt-epic and --no-epic-prompt together.");
|
|
7800
8142
|
}
|
|
@@ -7842,7 +8184,7 @@ async function executeRun(context, args) {
|
|
|
7842
8184
|
};
|
|
7843
8185
|
}
|
|
7844
8186
|
case "resume": {
|
|
7845
|
-
requireNoExtraArgs(rest, "
|
|
8187
|
+
requireNoExtraArgs(rest, "rig run resume");
|
|
7846
8188
|
if (context.dryRun) {
|
|
7847
8189
|
if (context.outputMode === "text") {
|
|
7848
8190
|
console.log("[dry-run] rig run resume");
|
|
@@ -7856,7 +8198,7 @@ async function executeRun(context, args) {
|
|
|
7856
8198
|
return { ok: true, group: "run", command, details: resumed };
|
|
7857
8199
|
}
|
|
7858
8200
|
case "restart": {
|
|
7859
|
-
requireNoExtraArgs(rest, "
|
|
8201
|
+
requireNoExtraArgs(rest, "rig run restart");
|
|
7860
8202
|
if (context.dryRun) {
|
|
7861
8203
|
if (context.outputMode === "text") {
|
|
7862
8204
|
console.log("[dry-run] rig run restart");
|
|
@@ -7873,7 +8215,7 @@ async function executeRun(context, args) {
|
|
|
7873
8215
|
const runOption = takeOption(rest, "--run");
|
|
7874
8216
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
7875
8217
|
const extra = positionalRunId ? runOption.rest.slice(1) : runOption.rest;
|
|
7876
|
-
requireNoExtraArgs(extra, "
|
|
8218
|
+
requireNoExtraArgs(extra, "rig run stop [<run-id>|--run <id>]");
|
|
7877
8219
|
const runId = runOption.value ?? positionalRunId;
|
|
7878
8220
|
if (context.dryRun) {
|
|
7879
8221
|
return {
|
|
@@ -7912,6 +8254,7 @@ async function executeRun(context, args) {
|
|
|
7912
8254
|
}
|
|
7913
8255
|
|
|
7914
8256
|
// packages/cli/src/commands/server.ts
|
|
8257
|
+
init_runner();
|
|
7915
8258
|
async function executeServer(context, args, options) {
|
|
7916
8259
|
const [command = "status", ...rest] = args;
|
|
7917
8260
|
if (["status", "list", "add", "use"].includes(command)) {
|
|
@@ -8013,6 +8356,7 @@ async function executeServer(context, args, options) {
|
|
|
8013
8356
|
}
|
|
8014
8357
|
|
|
8015
8358
|
// packages/cli/src/commands/task.ts
|
|
8359
|
+
init_runner();
|
|
8016
8360
|
import { readFileSync as readFileSync9 } from "fs";
|
|
8017
8361
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
8018
8362
|
import { resolve as resolve20 } from "path";
|
|
@@ -8038,50 +8382,426 @@ import { cancel as cancel3, isCancel as isCancel3, select as select3 } from "@cl
|
|
|
8038
8382
|
function taskId2(task) {
|
|
8039
8383
|
return typeof task.id === "string" && task.id.trim() ? task.id : "<unknown>";
|
|
8040
8384
|
}
|
|
8041
|
-
async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
8042
|
-
if (tasks.length === 0)
|
|
8043
|
-
return null;
|
|
8044
|
-
if (tasks.length === 1)
|
|
8045
|
-
return tasks[0];
|
|
8046
|
-
const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8047
|
-
if (!isTty) {
|
|
8048
|
-
throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
|
|
8385
|
+
async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
8386
|
+
if (tasks.length === 0)
|
|
8387
|
+
return null;
|
|
8388
|
+
if (tasks.length === 1)
|
|
8389
|
+
return tasks[0];
|
|
8390
|
+
const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8391
|
+
if (!isTty) {
|
|
8392
|
+
throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
|
|
8393
|
+
}
|
|
8394
|
+
if (io.prompt || io.renderer) {
|
|
8395
|
+
const prompt = io.prompt ?? promptForTaskSelection;
|
|
8396
|
+
const renderer = io.renderer ?? { writeLine: (line) => process.stdout.write(`${line}
|
|
8397
|
+
`) };
|
|
8398
|
+
renderer.writeLine("Select Rig task:");
|
|
8399
|
+
for (const row of renderTaskPickerRows(tasks))
|
|
8400
|
+
renderer.writeLine(` ${row}`);
|
|
8401
|
+
const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
|
|
8402
|
+
if (!answer2)
|
|
8403
|
+
return null;
|
|
8404
|
+
if (/^\d+$/.test(answer2)) {
|
|
8405
|
+
const index2 = Number.parseInt(answer2, 10) - 1;
|
|
8406
|
+
return tasks[index2] ?? null;
|
|
8407
|
+
}
|
|
8408
|
+
return tasks.find((task) => taskId2(task) === answer2) ?? null;
|
|
8409
|
+
}
|
|
8410
|
+
const options = tasks.map((task, index2) => ({
|
|
8411
|
+
value: `${index2}`,
|
|
8412
|
+
label: `${taskId2(task)} \xB7 ${typeof task.title === "string" && task.title.trim() ? task.title.trim() : "Untitled task"}`,
|
|
8413
|
+
hint: typeof task.status === "string" && task.status.trim() ? task.status.trim() : undefined
|
|
8414
|
+
}));
|
|
8415
|
+
const answer = await select3({
|
|
8416
|
+
message: "Select Rig task",
|
|
8417
|
+
options
|
|
8418
|
+
});
|
|
8419
|
+
if (isCancel3(answer)) {
|
|
8420
|
+
cancel3("No task selected.");
|
|
8421
|
+
return null;
|
|
8422
|
+
}
|
|
8423
|
+
const index = Number.parseInt(String(answer), 10);
|
|
8424
|
+
return Number.isFinite(index) ? tasks[index] ?? null : null;
|
|
8425
|
+
}
|
|
8426
|
+
|
|
8427
|
+
// packages/cli/src/commands/_help-catalog.ts
|
|
8428
|
+
import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
|
|
8429
|
+
import pc4 from "picocolors";
|
|
8430
|
+
var TOP_LEVEL_SECTIONS = [
|
|
8431
|
+
{
|
|
8432
|
+
title: "Server",
|
|
8433
|
+
subtitle: "choose the local or remote Rig server that owns this repo",
|
|
8434
|
+
commands: [
|
|
8435
|
+
{ command: "rig server status", description: "Show the selected local/remote server for this repo." },
|
|
8436
|
+
{ command: "rig server use local", description: "Switch this repo back to the local Rig server." },
|
|
8437
|
+
{ command: "rig server add <alias> <url>", description: "Save a remote Rig server alias." },
|
|
8438
|
+
{ command: "rig server use <alias>", description: "Switch this repo to a saved remote server." },
|
|
8439
|
+
{ command: "rig server list", description: "Show saved server aliases, including local." }
|
|
8440
|
+
]
|
|
8441
|
+
},
|
|
8442
|
+
{
|
|
8443
|
+
title: "Tasks",
|
|
8444
|
+
subtitle: "find work, inspect it, and submit Pi-backed workers",
|
|
8445
|
+
commands: [
|
|
8446
|
+
{ command: "rig task list", description: "List tasks from the selected task source/server." },
|
|
8447
|
+
{ command: "rig task next", description: "Show the next matching task as a selected-task card." },
|
|
8448
|
+
{ command: "rig task show <id>", description: "Show a human task summary; add --raw or --json for the full payload." },
|
|
8449
|
+
{ command: "rig task run <id|--next> [--detach]", description: "Submit a task run; interactive mode follows with bundled Pi." }
|
|
8450
|
+
]
|
|
8451
|
+
},
|
|
8452
|
+
{
|
|
8453
|
+
title: "Runs",
|
|
8454
|
+
subtitle: "observe, attach to, and stop live or recent runs",
|
|
8455
|
+
commands: [
|
|
8456
|
+
{ command: "rig run list", description: "List recent runs from the selected server or local state." },
|
|
8457
|
+
{ command: "rig run show <id>", description: "Show a human run summary; add --raw or --json for the full payload." },
|
|
8458
|
+
{ command: "rig run attach <id> --follow", description: "Open the native bundled Pi live view for a worker run." },
|
|
8459
|
+
{ command: "rig run stop <id>", description: "Request cancellation for a running worker." }
|
|
8460
|
+
]
|
|
8461
|
+
},
|
|
8462
|
+
{
|
|
8463
|
+
title: "Review / inbox",
|
|
8464
|
+
subtitle: "clear blocked runs and configure completion review",
|
|
8465
|
+
commands: [
|
|
8466
|
+
{ command: "rig inbox approvals", description: "List pending approval requests from local/server run state." },
|
|
8467
|
+
{ command: "rig inbox inputs", description: "List pending user-input requests from local/server run state." },
|
|
8468
|
+
{ command: "rig review show|set", description: "Inspect or change the review gate policy." }
|
|
8469
|
+
]
|
|
8470
|
+
},
|
|
8471
|
+
{
|
|
8472
|
+
title: "Health / setup",
|
|
8473
|
+
subtitle: "bootstrap and diagnose the repo/server/GitHub/Pi path",
|
|
8474
|
+
commands: [
|
|
8475
|
+
{ command: "rig init", description: "Interactive setup: config, GitHub auth, task source, server, checkout, Pi." },
|
|
8476
|
+
{ command: "rig doctor", description: "Diagnose project/server/GitHub/task/Pi wiring." },
|
|
8477
|
+
{ command: "rig github auth status", description: "Show GitHub auth state on the selected Rig server." }
|
|
8478
|
+
]
|
|
8479
|
+
}
|
|
8480
|
+
];
|
|
8481
|
+
var PRIMARY_GROUPS = [
|
|
8482
|
+
{
|
|
8483
|
+
name: "server",
|
|
8484
|
+
summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
|
|
8485
|
+
usage: ["rig server <status|list|add|use|start> [options]"],
|
|
8486
|
+
commands: [
|
|
8487
|
+
{ command: "status", description: "Show the selected server for this repo.", primary: true },
|
|
8488
|
+
{ command: "use local", description: "Switch this repo to the local Rig server.", primary: true },
|
|
8489
|
+
{ command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
|
|
8490
|
+
{ command: "use <alias>", description: "Select a saved remote server alias.", primary: true },
|
|
8491
|
+
{ command: "list", description: "List saved local/remote server aliases.", primary: true },
|
|
8492
|
+
{ command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process." }
|
|
8493
|
+
],
|
|
8494
|
+
examples: [
|
|
8495
|
+
"rig server status",
|
|
8496
|
+
"rig server add prod https://where.rig-does.work",
|
|
8497
|
+
"rig server use prod",
|
|
8498
|
+
"rig server use local",
|
|
8499
|
+
"rig server start --port 3773"
|
|
8500
|
+
],
|
|
8501
|
+
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
|
|
8502
|
+
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
8503
|
+
},
|
|
8504
|
+
{
|
|
8505
|
+
name: "task",
|
|
8506
|
+
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
8507
|
+
usage: ["rig task <list|next|show|run> [options]"],
|
|
8508
|
+
commands: [
|
|
8509
|
+
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
8510
|
+
{ command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
|
|
8511
|
+
{ command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
|
|
8512
|
+
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
8513
|
+
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
8514
|
+
{ command: "details --task <id>", description: "Show full task info from the configured source." },
|
|
8515
|
+
{ command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
|
|
8516
|
+
{ command: "reset --task <id>", description: "Compatibility spelling of `reopen --task <id>`." },
|
|
8517
|
+
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
8518
|
+
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
8519
|
+
],
|
|
8520
|
+
examples: [
|
|
8521
|
+
"rig task list --assignee @me --limit 20",
|
|
8522
|
+
"rig task next",
|
|
8523
|
+
"rig task show 123 --raw",
|
|
8524
|
+
"rig task run --next",
|
|
8525
|
+
"rig task run #123 --runtime-adapter pi",
|
|
8526
|
+
"rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
|
|
8527
|
+
],
|
|
8528
|
+
next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
|
|
8529
|
+
},
|
|
8530
|
+
{
|
|
8531
|
+
name: "run",
|
|
8532
|
+
summary: "Observe, attach to, and control Rig runs.",
|
|
8533
|
+
usage: ["rig run <list|status|show|attach|stop> [options]"],
|
|
8534
|
+
commands: [
|
|
8535
|
+
{ command: "list", description: "List recent runs from the selected server or local state.", primary: true },
|
|
8536
|
+
{ command: "status", description: "Render active and recent run groups.", primary: true },
|
|
8537
|
+
{ command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
|
|
8538
|
+
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
|
|
8539
|
+
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
8540
|
+
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
8541
|
+
{ command: "resume", description: "Resume the most recent interrupted local run." },
|
|
8542
|
+
{ command: "restart", description: "Restart the most recent local run from a clean runtime." },
|
|
8543
|
+
{ command: "delete|cleanup", description: "Remove completed run records/artifacts." }
|
|
8544
|
+
],
|
|
8545
|
+
examples: [
|
|
8546
|
+
"rig run list",
|
|
8547
|
+
"rig run status",
|
|
8548
|
+
"rig run show <run-id>",
|
|
8549
|
+
"rig run attach <run-id> --follow",
|
|
8550
|
+
"rig run stop <run-id>"
|
|
8551
|
+
],
|
|
8552
|
+
next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
|
|
8553
|
+
},
|
|
8554
|
+
{
|
|
8555
|
+
name: "inbox",
|
|
8556
|
+
summary: "Review approval and user-input requests that block worker runs.",
|
|
8557
|
+
usage: ["rig inbox <approvals|approve|inputs|respond> [options]"],
|
|
8558
|
+
commands: [
|
|
8559
|
+
{ command: "approvals [--run <id>] [--task <id>]", description: "List pending approvals.", primary: true },
|
|
8560
|
+
{ command: "inputs [--run <id>] [--task <id>]", description: "List pending user-input requests.", primary: true },
|
|
8561
|
+
{ command: "approve --run <id> --request <id> --decision approve|reject", description: "Resolve an approval request." },
|
|
8562
|
+
{ command: "respond --run <id> --request <id> --answer key=value", description: "Answer a user-input request." }
|
|
8563
|
+
],
|
|
8564
|
+
examples: [
|
|
8565
|
+
"rig inbox approvals",
|
|
8566
|
+
"rig inbox inputs --run <run-id>",
|
|
8567
|
+
"rig inbox approve --run <run-id> --request <request-id> --decision approve"
|
|
8568
|
+
],
|
|
8569
|
+
next: ["Rejoin the run after resolving a block: `rig run attach <run-id> --follow`."]
|
|
8570
|
+
},
|
|
8571
|
+
{
|
|
8572
|
+
name: "review",
|
|
8573
|
+
summary: "Inspect or change completion review gate policy.",
|
|
8574
|
+
usage: ["rig review <show|set>"],
|
|
8575
|
+
commands: [
|
|
8576
|
+
{ command: "show", description: "Show current review gate settings.", primary: true },
|
|
8577
|
+
{ command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider.", primary: true }
|
|
8578
|
+
],
|
|
8579
|
+
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
8580
|
+
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
8581
|
+
},
|
|
8582
|
+
{
|
|
8583
|
+
name: "init",
|
|
8584
|
+
summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
|
|
8585
|
+
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
8586
|
+
commands: [
|
|
8587
|
+
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
8588
|
+
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
8589
|
+
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
8590
|
+
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
8591
|
+
],
|
|
8592
|
+
examples: [
|
|
8593
|
+
"rig init",
|
|
8594
|
+
"rig init --yes --repo humanity-org/humanwork",
|
|
8595
|
+
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
8596
|
+
],
|
|
8597
|
+
next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
|
|
8598
|
+
},
|
|
8599
|
+
{
|
|
8600
|
+
name: "doctor",
|
|
8601
|
+
summary: "Diagnostics for project/server/GitHub/Pi state.",
|
|
8602
|
+
usage: ["rig doctor"],
|
|
8603
|
+
commands: [
|
|
8604
|
+
{ command: "doctor", description: "Run setup and runtime diagnostics.", primary: true },
|
|
8605
|
+
{ command: "check", description: "Compatibility spelling for diagnostics." }
|
|
8606
|
+
],
|
|
8607
|
+
examples: ["rig doctor", "rig doctor --json"],
|
|
8608
|
+
next: ["Use `rig server status` and `rig github auth status` to inspect common failure points."]
|
|
8609
|
+
},
|
|
8610
|
+
{
|
|
8611
|
+
name: "github",
|
|
8612
|
+
summary: "GitHub auth helpers for the selected Rig server.",
|
|
8613
|
+
usage: ["rig github auth <status|import-gh|token>"],
|
|
8614
|
+
commands: [
|
|
8615
|
+
{ command: "auth status", description: "Show GitHub auth state.", primary: true },
|
|
8616
|
+
{ command: "auth import-gh", description: "Import the current `gh` token into the selected server." },
|
|
8617
|
+
{ command: "auth token --token <token>", description: "Store a token on the selected server." }
|
|
8618
|
+
],
|
|
8619
|
+
examples: ["rig github auth status", "rig github auth import-gh"],
|
|
8620
|
+
next: ["After auth is valid, use `rig task run --next`."]
|
|
8621
|
+
}
|
|
8622
|
+
];
|
|
8623
|
+
var ADVANCED_GROUPS = [
|
|
8624
|
+
{ 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." }] },
|
|
8625
|
+
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
8626
|
+
{ 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." }] },
|
|
8627
|
+
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
8628
|
+
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
8629
|
+
{
|
|
8630
|
+
name: "browser",
|
|
8631
|
+
summary: "Browser/app diagnostics for browser-required tasks.",
|
|
8632
|
+
usage: ["rig browser <help|explain|demo|app|hp-next> [options]"],
|
|
8633
|
+
commands: [
|
|
8634
|
+
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
|
|
8635
|
+
{ command: "explain", description: "Explain the browser-required task contract." },
|
|
8636
|
+
{ command: "demo", description: "Run browser demo flows against a local page." },
|
|
8637
|
+
{ command: "app", description: "Launch the Rig Browser workstation app." },
|
|
8638
|
+
{ command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
|
|
8639
|
+
]
|
|
8640
|
+
},
|
|
8641
|
+
{
|
|
8642
|
+
name: "plugin",
|
|
8643
|
+
summary: "Plugin listing, validation, and plugin-contributed commands.",
|
|
8644
|
+
usage: ["rig plugin <list|validate|run> [options]"],
|
|
8645
|
+
commands: [
|
|
8646
|
+
{ command: "list", description: "List plugins declared in rig.config.ts and their contributions." },
|
|
8647
|
+
{ command: "validate --task <id>", description: "Run plugin-contributed validators for a task." },
|
|
8648
|
+
{ command: "run <command-id> [args...]", description: "Execute a plugin-contributed CLI command (also callable as `rig <command-id>`)." }
|
|
8649
|
+
]
|
|
8650
|
+
},
|
|
8651
|
+
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
8652
|
+
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
8653
|
+
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
8654
|
+
{ name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
|
|
8655
|
+
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
8656
|
+
{ name: "remote", summary: "Compatibility remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
|
|
8657
|
+
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
8658
|
+
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
8659
|
+
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
8660
|
+
];
|
|
8661
|
+
var ADVANCED_COMMANDS = [
|
|
8662
|
+
{ command: "rig server task-run ...", description: "Internal server-owned task execution entry point." },
|
|
8663
|
+
{ command: "rig server notify-test [--event <type>]", description: "Internal event notification smoke command." },
|
|
8664
|
+
{ command: "rig run start|start-serial|start-parallel", description: "Compatibility local run starters; prefer `rig task run ...`." },
|
|
8665
|
+
{ command: "rig remote orchestrate-*", description: "Compatibility remote orchestration commands." }
|
|
8666
|
+
];
|
|
8667
|
+
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
8668
|
+
function heading(title) {
|
|
8669
|
+
return pc4.bold(pc4.cyan(title));
|
|
8670
|
+
}
|
|
8671
|
+
function commandLine(command, description) {
|
|
8672
|
+
const commandColumn = command.length >= 38 ? `${command} ` : command.padEnd(38);
|
|
8673
|
+
return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
|
|
8674
|
+
}
|
|
8675
|
+
function renderCommandBlock(commands) {
|
|
8676
|
+
return commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8677
|
+
`);
|
|
8678
|
+
}
|
|
8679
|
+
function renderGroup(group) {
|
|
8680
|
+
const lines = [
|
|
8681
|
+
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
8682
|
+
"",
|
|
8683
|
+
pc4.bold("Usage"),
|
|
8684
|
+
...group.usage.map((line) => ` ${line}`),
|
|
8685
|
+
"",
|
|
8686
|
+
pc4.bold("Commands"),
|
|
8687
|
+
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
8688
|
+
];
|
|
8689
|
+
if (group.examples?.length) {
|
|
8690
|
+
lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
|
|
8691
|
+
}
|
|
8692
|
+
if (group.next?.length) {
|
|
8693
|
+
lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
8694
|
+
}
|
|
8695
|
+
if (group.advanced?.length) {
|
|
8696
|
+
lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
8697
|
+
}
|
|
8698
|
+
return lines.join(`
|
|
8699
|
+
`);
|
|
8700
|
+
}
|
|
8701
|
+
function renderTopLevelHelp() {
|
|
8702
|
+
return [
|
|
8703
|
+
`${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
8704
|
+
pc4.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox/review gates."),
|
|
8705
|
+
"",
|
|
8706
|
+
...TOP_LEVEL_SECTIONS.flatMap((section) => [
|
|
8707
|
+
`${pc4.bold(pc4.magenta(`\u25C7 ${section.title}`))} \u2014 ${pc4.dim(section.subtitle)}`,
|
|
8708
|
+
renderCommandBlock(section.commands),
|
|
8709
|
+
""
|
|
8710
|
+
]),
|
|
8711
|
+
pc4.dim("More: `rig help --advanced` for dev/compatibility commands; `rig <group> --help` for rich per-group help; `rig --version` for the installed version."),
|
|
8712
|
+
"",
|
|
8713
|
+
pc4.bold("Global options"),
|
|
8714
|
+
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
8715
|
+
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
8716
|
+
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
8717
|
+
].join(`
|
|
8718
|
+
`).trimEnd();
|
|
8719
|
+
}
|
|
8720
|
+
function renderAdvancedHelp() {
|
|
8721
|
+
return [
|
|
8722
|
+
`${heading("rig advanced")} \u2014 compatibility, diagnostics, and internal surfaces`,
|
|
8723
|
+
"",
|
|
8724
|
+
pc4.bold("Primary groups"),
|
|
8725
|
+
" server, task, run, inbox, review, init, doctor, github",
|
|
8726
|
+
"",
|
|
8727
|
+
pc4.bold("Advanced commands"),
|
|
8728
|
+
...ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)),
|
|
8729
|
+
"",
|
|
8730
|
+
pc4.bold("Advanced groups"),
|
|
8731
|
+
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
8732
|
+
"",
|
|
8733
|
+
pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, `rig run`, `rig inbox`, and `rig review` for day-to-day work.")
|
|
8734
|
+
].join(`
|
|
8735
|
+
`);
|
|
8736
|
+
}
|
|
8737
|
+
function renderGroupHelp(groupName) {
|
|
8738
|
+
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
8739
|
+
return group ? renderGroup(group) : null;
|
|
8740
|
+
}
|
|
8741
|
+
function shouldUseClackOutput2() {
|
|
8742
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
8743
|
+
}
|
|
8744
|
+
function printTopLevelHelp() {
|
|
8745
|
+
if (!shouldUseClackOutput2()) {
|
|
8746
|
+
console.log(renderTopLevelHelp());
|
|
8747
|
+
return;
|
|
8049
8748
|
}
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
`) };
|
|
8054
|
-
renderer.writeLine("Select Rig task:");
|
|
8055
|
-
for (const row of renderTaskPickerRows(tasks))
|
|
8056
|
-
renderer.writeLine(` ${row}`);
|
|
8057
|
-
const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
|
|
8058
|
-
if (!answer2)
|
|
8059
|
-
return null;
|
|
8060
|
-
if (/^\d+$/.test(answer2)) {
|
|
8061
|
-
const index2 = Number.parseInt(answer2, 10) - 1;
|
|
8062
|
-
return tasks[index2] ?? null;
|
|
8063
|
-
}
|
|
8064
|
-
return tasks.find((task) => taskId2(task) === answer2) ?? null;
|
|
8749
|
+
intro3("rig");
|
|
8750
|
+
for (const section of TOP_LEVEL_SECTIONS) {
|
|
8751
|
+
note4(renderCommandBlock(section.commands), `${section.title} \u2014 ${section.subtitle}`);
|
|
8065
8752
|
}
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8753
|
+
log4.info("More: rig help --advanced \xB7 rig <group> --help \xB7 rig --version");
|
|
8754
|
+
note4([
|
|
8755
|
+
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
8756
|
+
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
8757
|
+
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
8758
|
+
].join(`
|
|
8759
|
+
`), "Global options");
|
|
8760
|
+
outro3("Server \u2192 task \u2192 run \u2192 inbox/review.");
|
|
8761
|
+
}
|
|
8762
|
+
function printAdvancedHelp() {
|
|
8763
|
+
if (!shouldUseClackOutput2()) {
|
|
8764
|
+
console.log(renderAdvancedHelp());
|
|
8765
|
+
return;
|
|
8078
8766
|
}
|
|
8079
|
-
|
|
8080
|
-
|
|
8767
|
+
intro3("rig advanced");
|
|
8768
|
+
note4(ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8769
|
+
`), "Advanced commands");
|
|
8770
|
+
note4(ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)).join(`
|
|
8771
|
+
`), "Advanced groups");
|
|
8772
|
+
outro3("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox \xB7 rig review.");
|
|
8773
|
+
}
|
|
8774
|
+
function printGroupHelpDocument(groupName) {
|
|
8775
|
+
const rendered = renderGroupHelp(groupName) ?? renderTopLevelHelp();
|
|
8776
|
+
if (!shouldUseClackOutput2()) {
|
|
8777
|
+
console.log(rendered);
|
|
8778
|
+
return;
|
|
8779
|
+
}
|
|
8780
|
+
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
8781
|
+
if (!group) {
|
|
8782
|
+
printTopLevelHelp();
|
|
8783
|
+
return;
|
|
8784
|
+
}
|
|
8785
|
+
intro3(`rig ${group.name}`);
|
|
8786
|
+
note4(group.summary, "Purpose");
|
|
8787
|
+
note4(group.usage.join(`
|
|
8788
|
+
`), "Usage");
|
|
8789
|
+
note4(group.commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8790
|
+
`), "Commands");
|
|
8791
|
+
if (group.examples?.length)
|
|
8792
|
+
note4(group.examples.map((line) => `$ ${line}`).join(`
|
|
8793
|
+
`), "Examples");
|
|
8794
|
+
if (group.next?.length)
|
|
8795
|
+
note4(group.next.map((line) => `\u203A ${line}`).join(`
|
|
8796
|
+
`), "Next steps");
|
|
8797
|
+
if (group.advanced?.length)
|
|
8798
|
+
log4.info(group.advanced.join(`
|
|
8799
|
+
`));
|
|
8800
|
+
outro3("Run with --json when scripts need structured output.");
|
|
8081
8801
|
}
|
|
8082
8802
|
|
|
8083
8803
|
// packages/cli/src/commands/task.ts
|
|
8084
|
-
import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
|
|
8804
|
+
import { buildPluginHostContext as buildPluginHostContext2 } from "@rig/runtime/control-plane/plugin-host-context";
|
|
8085
8805
|
import { loadConfig } from "@rig/core/load-config";
|
|
8086
8806
|
async function readStdin() {
|
|
8087
8807
|
const chunks = [];
|
|
@@ -8231,27 +8951,30 @@ function summarizeTask(task, options = {}) {
|
|
|
8231
8951
|
...options.raw ? { raw: raw ?? task } : {}
|
|
8232
8952
|
};
|
|
8233
8953
|
}
|
|
8234
|
-
function printTaskSummary(task) {
|
|
8235
|
-
console.log(formatTaskList([task]));
|
|
8236
|
-
}
|
|
8237
8954
|
async function validatorRegistryForTaskCommands(projectRoot) {
|
|
8238
|
-
return
|
|
8955
|
+
return buildPluginHostContext2(projectRoot).then((ctx) => ctx?.validatorRegistry ?? undefined).catch(() => {
|
|
8239
8956
|
return;
|
|
8240
8957
|
});
|
|
8241
8958
|
}
|
|
8242
8959
|
async function executeTask(context, args, options) {
|
|
8243
|
-
|
|
8960
|
+
if (args.length === 0) {
|
|
8961
|
+
if (context.outputMode === "text") {
|
|
8962
|
+
printGroupHelpDocument("task");
|
|
8963
|
+
}
|
|
8964
|
+
return { ok: true, group: "task", command: "help" };
|
|
8965
|
+
}
|
|
8966
|
+
const [command = "help", ...rest] = args;
|
|
8244
8967
|
switch (command) {
|
|
8245
8968
|
case "list": {
|
|
8246
8969
|
let pending = rest;
|
|
8247
8970
|
const rawResult = takeFlag(pending, "--raw");
|
|
8248
8971
|
pending = rawResult.rest;
|
|
8249
8972
|
const { filters, rest: remaining } = parseTaskFilters(pending);
|
|
8250
|
-
requireNoExtraArgs(remaining, "
|
|
8973
|
+
requireNoExtraArgs(remaining, "rig task list [--raw] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
8251
8974
|
const tasks = await listWorkspaceTasksViaServer(context, filters);
|
|
8252
8975
|
if (context.outputMode === "text") {
|
|
8253
8976
|
const renderedTasks = rawResult.value ? tasks.map((task) => summarizeTask(task, { raw: true })) : tasks.map((task) => summarizeTask(task));
|
|
8254
|
-
|
|
8977
|
+
printFormattedOutput(formatTaskList(renderedTasks, { raw: rawResult.value }));
|
|
8255
8978
|
}
|
|
8256
8979
|
return {
|
|
8257
8980
|
ok: true,
|
|
@@ -8261,10 +8984,13 @@ async function executeTask(context, args, options) {
|
|
|
8261
8984
|
};
|
|
8262
8985
|
}
|
|
8263
8986
|
case "show": {
|
|
8264
|
-
|
|
8987
|
+
let pending = rest;
|
|
8988
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
8989
|
+
pending = rawResult.rest;
|
|
8990
|
+
const taskOption = takeOption(pending, "--task");
|
|
8265
8991
|
const positional = taskOption.rest.length > 0 && taskOption.rest[0] && !taskOption.rest[0].startsWith("-") ? taskOption.rest[0] : undefined;
|
|
8266
8992
|
const remaining = positional ? taskOption.rest.slice(1) : taskOption.rest;
|
|
8267
|
-
requireNoExtraArgs(remaining, "
|
|
8993
|
+
requireNoExtraArgs(remaining, "rig task show <id>|--task <id> [--raw]");
|
|
8268
8994
|
const taskId3 = normalizeTaskRunTaskId(taskOption.value ?? positional);
|
|
8269
8995
|
if (!taskId3)
|
|
8270
8996
|
throw new CliError2("task show requires a task id.", 2);
|
|
@@ -8272,19 +8998,20 @@ async function executeTask(context, args, options) {
|
|
|
8272
8998
|
if (!task)
|
|
8273
8999
|
throw new CliError2(`Task not found: ${taskId3}`, 3);
|
|
8274
9000
|
const summary = summarizeTask(task, { raw: true });
|
|
8275
|
-
if (context.outputMode === "text")
|
|
8276
|
-
|
|
8277
|
-
|
|
9001
|
+
if (context.outputMode === "text") {
|
|
9002
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(summary, null, 2) : formatTaskDetails(summary));
|
|
9003
|
+
}
|
|
9004
|
+
return { ok: true, group: "task", command, details: { task: summary, raw: rawResult.value } };
|
|
8278
9005
|
}
|
|
8279
9006
|
case "next": {
|
|
8280
9007
|
const { filters, rest: remaining } = parseTaskFilters(rest);
|
|
8281
|
-
requireNoExtraArgs(remaining, "
|
|
9008
|
+
requireNoExtraArgs(remaining, "rig task next [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
8282
9009
|
const selected = await selectNextWorkspaceTaskViaServer(context, filters);
|
|
8283
9010
|
if (context.outputMode === "text") {
|
|
8284
9011
|
if (selected.task) {
|
|
8285
|
-
|
|
9012
|
+
printFormattedOutput(formatTaskCard(summarizeTask(selected.task, { raw: true }), { title: "Selected task", selected: true }));
|
|
8286
9013
|
} else {
|
|
8287
|
-
|
|
9014
|
+
printFormattedOutput("No matching tasks.\n\nNext\n\u203A Try `rig task list` to inspect available work.\n\u203A Check server: `rig server status`");
|
|
8288
9015
|
}
|
|
8289
9016
|
}
|
|
8290
9017
|
return {
|
|
@@ -8300,31 +9027,31 @@ async function executeTask(context, args, options) {
|
|
|
8300
9027
|
}
|
|
8301
9028
|
case "info": {
|
|
8302
9029
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8303
|
-
requireNoExtraArgs(remaining, "
|
|
9030
|
+
requireNoExtraArgs(remaining, "rig task info [--task <task-id>]");
|
|
8304
9031
|
await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, task || undefined));
|
|
8305
9032
|
return { ok: true, group: "task", command, details: { task: task || null } };
|
|
8306
9033
|
}
|
|
8307
9034
|
case "scope": {
|
|
8308
9035
|
const filesFlag = takeFlag(rest, "--files");
|
|
8309
9036
|
const { value: task, rest: remaining } = takeOption(filesFlag.rest, "--task");
|
|
8310
|
-
requireNoExtraArgs(remaining, "
|
|
9037
|
+
requireNoExtraArgs(remaining, "rig task scope [--task <id>] [--files]");
|
|
8311
9038
|
await withMutedConsole(context.outputMode === "json", () => taskScope(context.projectRoot, filesFlag.value, task || undefined));
|
|
8312
9039
|
return { ok: true, group: "task", command, details: { files: filesFlag.value, task: task || null } };
|
|
8313
9040
|
}
|
|
8314
9041
|
case "deps":
|
|
8315
|
-
requireNoExtraArgs(rest, "
|
|
9042
|
+
requireNoExtraArgs(rest, "rig task deps");
|
|
8316
9043
|
await withMutedConsole(context.outputMode === "json", () => taskDeps(context.projectRoot));
|
|
8317
9044
|
return { ok: true, group: "task", command };
|
|
8318
9045
|
case "status":
|
|
8319
|
-
requireNoExtraArgs(rest, "
|
|
9046
|
+
requireNoExtraArgs(rest, "rig task status");
|
|
8320
9047
|
withMutedConsole(context.outputMode === "json", () => taskStatus2(context.projectRoot));
|
|
8321
9048
|
return { ok: true, group: "task", command };
|
|
8322
9049
|
case "artifacts":
|
|
8323
|
-
requireNoExtraArgs(rest, "
|
|
9050
|
+
requireNoExtraArgs(rest, "rig task artifacts");
|
|
8324
9051
|
withMutedConsole(context.outputMode === "json", () => taskArtifacts(context.projectRoot));
|
|
8325
9052
|
return { ok: true, group: "task", command };
|
|
8326
9053
|
case "artifact-dir": {
|
|
8327
|
-
requireNoExtraArgs(rest, "
|
|
9054
|
+
requireNoExtraArgs(rest, "rig task artifact-dir");
|
|
8328
9055
|
const path = taskArtifactDir(context.projectRoot);
|
|
8329
9056
|
if (context.outputMode === "text") {
|
|
8330
9057
|
console.log(path);
|
|
@@ -8333,7 +9060,7 @@ async function executeTask(context, args, options) {
|
|
|
8333
9060
|
}
|
|
8334
9061
|
case "artifact-write": {
|
|
8335
9062
|
if (rest.length < 1) {
|
|
8336
|
-
throw new CliError2(`Usage:
|
|
9063
|
+
throw new CliError2(`Usage: rig task artifact-write <filename> [--file <path>]
|
|
8337
9064
|
` + ` Reads content from stdin (or --file), writes to the active task artifact dir.
|
|
8338
9065
|
` + " Example: echo '...' | rig task artifact-write collection-audit.md");
|
|
8339
9066
|
}
|
|
@@ -8346,7 +9073,7 @@ async function executeTask(context, args, options) {
|
|
|
8346
9073
|
content = await readStdin();
|
|
8347
9074
|
}
|
|
8348
9075
|
if (!artifactFilename) {
|
|
8349
|
-
throw new CliError2("Usage:
|
|
9076
|
+
throw new CliError2("Usage: rig task artifact-write <filename> [--file path]");
|
|
8350
9077
|
}
|
|
8351
9078
|
withMutedConsole(context.outputMode === "json", () => taskArtifactWrite(context.projectRoot, artifactFilename, content));
|
|
8352
9079
|
return { ok: true, group: "task", command, details: { filename: artifactFilename } };
|
|
@@ -8355,11 +9082,11 @@ async function executeTask(context, args, options) {
|
|
|
8355
9082
|
return options.executeTaskReportBug(context, rest);
|
|
8356
9083
|
case "lookup": {
|
|
8357
9084
|
if (rest.length !== 1) {
|
|
8358
|
-
throw new CliError2("Usage:
|
|
9085
|
+
throw new CliError2("Usage: rig task lookup <task-id>");
|
|
8359
9086
|
}
|
|
8360
9087
|
const lookupId = rest[0];
|
|
8361
9088
|
if (!lookupId) {
|
|
8362
|
-
throw new CliError2("Usage:
|
|
9089
|
+
throw new CliError2("Usage: rig task lookup <task-id>");
|
|
8363
9090
|
}
|
|
8364
9091
|
const result = taskLookup2(context.projectRoot, lookupId);
|
|
8365
9092
|
if (context.outputMode === "text") {
|
|
@@ -8369,17 +9096,17 @@ async function executeTask(context, args, options) {
|
|
|
8369
9096
|
}
|
|
8370
9097
|
case "record": {
|
|
8371
9098
|
if (rest.length < 2) {
|
|
8372
|
-
throw new CliError2("Usage:
|
|
9099
|
+
throw new CliError2("Usage: rig task record <decision|failure> <text>");
|
|
8373
9100
|
}
|
|
8374
9101
|
const type = rest[0];
|
|
8375
9102
|
if (type !== "decision" && type !== "failure") {
|
|
8376
|
-
throw new CliError2("Usage:
|
|
9103
|
+
throw new CliError2("Usage: rig task record <decision|failure> <text>");
|
|
8377
9104
|
}
|
|
8378
9105
|
withMutedConsole(context.outputMode === "json", () => taskRecord(context.projectRoot, type, rest.slice(1).join(" ")));
|
|
8379
9106
|
return { ok: true, group: "task", command, details: { type: rest[0] } };
|
|
8380
9107
|
}
|
|
8381
9108
|
case "ready":
|
|
8382
|
-
requireNoExtraArgs(rest, "
|
|
9109
|
+
requireNoExtraArgs(rest, "rig task ready");
|
|
8383
9110
|
await withMutedConsole(context.outputMode === "json", () => taskReady(context.projectRoot));
|
|
8384
9111
|
return { ok: true, group: "task", command };
|
|
8385
9112
|
case "run": {
|
|
@@ -8416,7 +9143,7 @@ async function executeTask(context, args, options) {
|
|
|
8416
9143
|
if (positionalTaskId) {
|
|
8417
9144
|
pending = pending.slice(1);
|
|
8418
9145
|
}
|
|
8419
|
-
requireNoExtraArgs(pending, "
|
|
9146
|
+
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]");
|
|
8420
9147
|
if (nextResult.value && (taskResult.value || positionalTaskId)) {
|
|
8421
9148
|
throw new CliError2("task run cannot combine --next with an explicit task id.", 2);
|
|
8422
9149
|
}
|
|
@@ -8470,10 +9197,24 @@ async function executeTask(context, args, options) {
|
|
|
8470
9197
|
});
|
|
8471
9198
|
let attachDetails = null;
|
|
8472
9199
|
if (!detachResult.value && context.outputMode === "text") {
|
|
8473
|
-
|
|
9200
|
+
printFormattedOutput(formatSubmittedRun({
|
|
9201
|
+
runId: submitted.runId,
|
|
9202
|
+
task: selectedTask ? summarizeTask(selectedTask) : null,
|
|
9203
|
+
runtimeAdapter,
|
|
9204
|
+
runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
|
|
9205
|
+
interactionMode: interactionModeResult.value || "default",
|
|
9206
|
+
detached: false
|
|
9207
|
+
}));
|
|
8474
9208
|
attachDetails = await attachRunOperatorView(context, { runId: submitted.runId, follow: true });
|
|
8475
9209
|
} else if (context.outputMode === "text") {
|
|
8476
|
-
|
|
9210
|
+
printFormattedOutput(formatSubmittedRun({
|
|
9211
|
+
runId: submitted.runId,
|
|
9212
|
+
task: selectedTask ? summarizeTask(selectedTask) : null,
|
|
9213
|
+
runtimeAdapter,
|
|
9214
|
+
runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
|
|
9215
|
+
interactionMode: interactionModeResult.value || "default",
|
|
9216
|
+
detached: true
|
|
9217
|
+
}));
|
|
8477
9218
|
}
|
|
8478
9219
|
return {
|
|
8479
9220
|
ok: true,
|
|
@@ -8497,7 +9238,7 @@ async function executeTask(context, args, options) {
|
|
|
8497
9238
|
}
|
|
8498
9239
|
case "validate": {
|
|
8499
9240
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8500
|
-
requireNoExtraArgs(remaining, "
|
|
9241
|
+
requireNoExtraArgs(remaining, "rig task validate [--task <task-id>]");
|
|
8501
9242
|
if (context.dryRun) {
|
|
8502
9243
|
await context.runCommand(["rig", "task", "validate", ...task ? ["--task", task] : []]);
|
|
8503
9244
|
return { ok: true, group: "task", command, details: { task: task || "active" } };
|
|
@@ -8510,12 +9251,12 @@ async function executeTask(context, args, options) {
|
|
|
8510
9251
|
}
|
|
8511
9252
|
case "verify": {
|
|
8512
9253
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8513
|
-
requireNoExtraArgs(remaining, "
|
|
9254
|
+
requireNoExtraArgs(remaining, "rig task verify [--task <task-id>]");
|
|
8514
9255
|
if (context.dryRun) {
|
|
8515
9256
|
await context.runCommand(["rig", "task", "verify", ...task ? ["--task", task] : []]);
|
|
8516
9257
|
return { ok: true, group: "task", command, details: { task: task || "active" } };
|
|
8517
9258
|
}
|
|
8518
|
-
const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot,
|
|
9259
|
+
const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot, task || undefined));
|
|
8519
9260
|
if (!ok) {
|
|
8520
9261
|
throw new CliError2(`Verification rejected for ${task || "active task"}.`, 2);
|
|
8521
9262
|
}
|
|
@@ -8523,15 +9264,19 @@ async function executeTask(context, args, options) {
|
|
|
8523
9264
|
}
|
|
8524
9265
|
case "reset": {
|
|
8525
9266
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8526
|
-
requireNoExtraArgs(remaining, "
|
|
8527
|
-
const requiredTask = requireTask(task, "
|
|
8528
|
-
|
|
8529
|
-
|
|
9267
|
+
requireNoExtraArgs(remaining, "rig task reset --task <task-id>");
|
|
9268
|
+
const requiredTask = requireTask(task, "rig task reset --task <task-id>");
|
|
9269
|
+
const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
|
|
9270
|
+
all: false,
|
|
9271
|
+
taskId: requiredTask,
|
|
9272
|
+
dryRun: false
|
|
9273
|
+
}));
|
|
9274
|
+
return { ok: true, group: "task", command, details: summary };
|
|
8530
9275
|
}
|
|
8531
9276
|
case "details": {
|
|
8532
9277
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8533
|
-
requireNoExtraArgs(remaining, "
|
|
8534
|
-
const requiredTask = requireTask(task, "
|
|
9278
|
+
requireNoExtraArgs(remaining, "rig task details --task <task-id>");
|
|
9279
|
+
const requiredTask = requireTask(task, "rig task details --task <task-id>");
|
|
8535
9280
|
await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, requiredTask));
|
|
8536
9281
|
return { ok: true, group: "task", command, details: { task: requiredTask } };
|
|
8537
9282
|
}
|
|
@@ -8539,9 +9284,9 @@ async function executeTask(context, args, options) {
|
|
|
8539
9284
|
const { value: task, rest: rest1 } = takeOption(rest, "--task");
|
|
8540
9285
|
const allFlag = takeFlag(rest1, "--all");
|
|
8541
9286
|
const { rest: remaining } = takeOption(allFlag.rest, "--reason");
|
|
8542
|
-
requireNoExtraArgs(remaining, "
|
|
9287
|
+
requireNoExtraArgs(remaining, "rig task reopen [--task <id> | --all] [--reason <text>]");
|
|
8543
9288
|
if (!allFlag.value && !task) {
|
|
8544
|
-
throw new CliError2("Usage:
|
|
9289
|
+
throw new CliError2("Usage: rig task reopen [--task <id> | --all] [--reason <text>]");
|
|
8545
9290
|
}
|
|
8546
9291
|
const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
|
|
8547
9292
|
all: allFlag.value,
|
|
@@ -8556,6 +9301,7 @@ async function executeTask(context, args, options) {
|
|
|
8556
9301
|
}
|
|
8557
9302
|
|
|
8558
9303
|
// packages/cli/src/commands/task-run-driver.ts
|
|
9304
|
+
init_runner();
|
|
8559
9305
|
import { copyFileSync as copyFileSync3, existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
8560
9306
|
import { resolve as resolve21 } from "path";
|
|
8561
9307
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
@@ -10572,19 +11318,20 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
10572
11318
|
}
|
|
10573
11319
|
|
|
10574
11320
|
// packages/cli/src/commands/test.ts
|
|
11321
|
+
init_runner();
|
|
10575
11322
|
async function executeTest(context, args) {
|
|
10576
11323
|
const [command = "unit", ...rest] = args;
|
|
10577
11324
|
switch (command) {
|
|
10578
11325
|
case "unit":
|
|
10579
|
-
requireNoExtraArgs(rest, "
|
|
11326
|
+
requireNoExtraArgs(rest, "rig test unit");
|
|
10580
11327
|
await context.runCommand(["bun", "test", "tests/harness/", "--ignore", "tests/harness/e2e/**"]);
|
|
10581
11328
|
return { ok: true, group: "test", command };
|
|
10582
11329
|
case "e2e":
|
|
10583
|
-
requireNoExtraArgs(rest, "
|
|
11330
|
+
requireNoExtraArgs(rest, "rig test e2e");
|
|
10584
11331
|
await context.runCommand(["bun", "test", "tests/harness/e2e/"]);
|
|
10585
11332
|
return { ok: true, group: "test", command };
|
|
10586
11333
|
case "all":
|
|
10587
|
-
requireNoExtraArgs(rest, "
|
|
11334
|
+
requireNoExtraArgs(rest, "rig test all");
|
|
10588
11335
|
await context.runCommand(["bun", "test", "tests/harness/"]);
|
|
10589
11336
|
return { ok: true, group: "test", command };
|
|
10590
11337
|
default:
|
|
@@ -10593,6 +11340,7 @@ async function executeTest(context, args) {
|
|
|
10593
11340
|
}
|
|
10594
11341
|
|
|
10595
11342
|
// packages/cli/src/commands/setup.ts
|
|
11343
|
+
init_runner();
|
|
10596
11344
|
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
10597
11345
|
import { resolve as resolve22 } from "path";
|
|
10598
11346
|
import { createPluginHost } from "@rig/core";
|
|
@@ -10600,11 +11348,12 @@ import {
|
|
|
10600
11348
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
10601
11349
|
MIN_SUPPORTED_BUN_VERSION as MIN_SUPPORTED_BUN_VERSION2
|
|
10602
11350
|
} from "@rig/runtime/control-plane/setup-version";
|
|
11351
|
+
init__parsers();
|
|
10603
11352
|
async function executeSetup(context, args) {
|
|
10604
11353
|
const [command = "check", ...rest] = args;
|
|
10605
11354
|
switch (command) {
|
|
10606
11355
|
case "bootstrap":
|
|
10607
|
-
requireNoExtraArgs(rest, "
|
|
11356
|
+
requireNoExtraArgs(rest, "rig setup bootstrap");
|
|
10608
11357
|
{
|
|
10609
11358
|
const hostBash = Bun.which("bash") || "/bin/bash";
|
|
10610
11359
|
const env = { ...process.env };
|
|
@@ -10627,25 +11376,19 @@ async function executeSetup(context, args) {
|
|
|
10627
11376
|
}
|
|
10628
11377
|
return { ok: true, group: "setup", command };
|
|
10629
11378
|
case "check":
|
|
10630
|
-
requireNoExtraArgs(rest, `
|
|
11379
|
+
requireNoExtraArgs(rest, `rig setup ${command}`);
|
|
10631
11380
|
{
|
|
10632
11381
|
const checks = await withMutedConsole(context.outputMode === "json", () => runSetupCheck(context.projectRoot));
|
|
10633
11382
|
return { ok: true, group: "setup", command, details: { checks, failures: countDoctorFailures(checks) } };
|
|
10634
11383
|
}
|
|
10635
11384
|
case "setup":
|
|
10636
|
-
requireNoExtraArgs(rest, "
|
|
11385
|
+
requireNoExtraArgs(rest, "rig setup setup");
|
|
10637
11386
|
withMutedConsole(context.outputMode === "json", () => runSetupInit(context.projectRoot));
|
|
10638
11387
|
return { ok: true, group: "setup", command };
|
|
10639
11388
|
case "preflight":
|
|
10640
|
-
requireNoExtraArgs(rest, "
|
|
11389
|
+
requireNoExtraArgs(rest, "rig setup preflight");
|
|
10641
11390
|
await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
|
|
10642
11391
|
return { ok: true, group: "setup", command };
|
|
10643
|
-
case "install-agent-shell":
|
|
10644
|
-
requireNoExtraArgs(rest, "bun run rig setup install-agent-shell");
|
|
10645
|
-
if (context.outputMode === "text") {
|
|
10646
|
-
console.log("install-agent-shell is deprecated. Runtime shells now use compiled rig-agent directly.");
|
|
10647
|
-
}
|
|
10648
|
-
return { ok: true, group: "setup", command };
|
|
10649
11392
|
default:
|
|
10650
11393
|
throw new CliError2(`Unknown setup command: ${command}`);
|
|
10651
11394
|
}
|
|
@@ -10696,6 +11439,7 @@ async function runSetupPreflight(projectRoot) {
|
|
|
10696
11439
|
}
|
|
10697
11440
|
|
|
10698
11441
|
// packages/cli/src/commands/workspace.ts
|
|
11442
|
+
init_runner();
|
|
10699
11443
|
import {
|
|
10700
11444
|
mutateWorkspaceServiceFabric,
|
|
10701
11445
|
readWorkspaceRemoteFleet,
|
|
@@ -10706,7 +11450,7 @@ async function executeWorkspace(context, args) {
|
|
|
10706
11450
|
const [command = "summary", ...rest] = args;
|
|
10707
11451
|
switch (command) {
|
|
10708
11452
|
case "summary": {
|
|
10709
|
-
requireNoExtraArgs(rest, "
|
|
11453
|
+
requireNoExtraArgs(rest, "rig workspace summary");
|
|
10710
11454
|
const summary = await readWorkspaceSummary(context.projectRoot);
|
|
10711
11455
|
if (context.outputMode === "text") {
|
|
10712
11456
|
console.log("Workspace Summary");
|
|
@@ -10731,7 +11475,7 @@ Warnings:`);
|
|
|
10731
11475
|
return { ok: true, group: "workspace", command, details: summary };
|
|
10732
11476
|
}
|
|
10733
11477
|
case "topology": {
|
|
10734
|
-
requireNoExtraArgs(rest, "
|
|
11478
|
+
requireNoExtraArgs(rest, "rig workspace topology");
|
|
10735
11479
|
const topology = readWorkspaceTopology(context.projectRoot);
|
|
10736
11480
|
if (context.outputMode === "text") {
|
|
10737
11481
|
console.log(`Topology: ${topology.status}`);
|
|
@@ -10744,7 +11488,7 @@ Warnings:`);
|
|
|
10744
11488
|
return { ok: true, group: "workspace", command, details: topology };
|
|
10745
11489
|
}
|
|
10746
11490
|
case "remote-hosts": {
|
|
10747
|
-
requireNoExtraArgs(rest, "
|
|
11491
|
+
requireNoExtraArgs(rest, "rig workspace remote-hosts");
|
|
10748
11492
|
const fleet = readWorkspaceRemoteFleet(context.projectRoot);
|
|
10749
11493
|
if (context.outputMode === "text") {
|
|
10750
11494
|
console.log(`Remote Hosts: ${fleet.status}`);
|
|
@@ -10759,7 +11503,7 @@ Warnings:`);
|
|
|
10759
11503
|
let pending = serviceRest;
|
|
10760
11504
|
const services = takeOption(pending, "--service");
|
|
10761
11505
|
pending = services.rest;
|
|
10762
|
-
requireNoExtraArgs(pending, "
|
|
11506
|
+
requireNoExtraArgs(pending, "rig workspace service-fabric <status|up|verify|down> [--service <name>]");
|
|
10763
11507
|
if (action !== "status" && action !== "up" && action !== "verify" && action !== "down") {
|
|
10764
11508
|
throw new CliError2(`Unknown workspace service-fabric action: ${action}`);
|
|
10765
11509
|
}
|
|
@@ -10780,200 +11524,6 @@ Warnings:`);
|
|
|
10780
11524
|
}
|
|
10781
11525
|
}
|
|
10782
11526
|
|
|
10783
|
-
// packages/cli/src/commands/_help-catalog.ts
|
|
10784
|
-
import pc4 from "picocolors";
|
|
10785
|
-
var PRIMARY_GROUPS = [
|
|
10786
|
-
{
|
|
10787
|
-
name: "init",
|
|
10788
|
-
summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
|
|
10789
|
-
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
10790
|
-
commands: [
|
|
10791
|
-
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
10792
|
-
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
10793
|
-
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
10794
|
-
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
10795
|
-
],
|
|
10796
|
-
examples: [
|
|
10797
|
-
"rig init",
|
|
10798
|
-
"rig init --yes --repo humanity-org/humanwork",
|
|
10799
|
-
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
10800
|
-
],
|
|
10801
|
-
next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
|
|
10802
|
-
},
|
|
10803
|
-
{
|
|
10804
|
-
name: "server",
|
|
10805
|
-
summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
|
|
10806
|
-
usage: ["rig server <status|list|add|use|start> [options]"],
|
|
10807
|
-
commands: [
|
|
10808
|
-
{ command: "status", description: "Show the selected server for this repo.", primary: true },
|
|
10809
|
-
{ command: "list", description: "List saved local/remote server aliases.", primary: true },
|
|
10810
|
-
{ command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
|
|
10811
|
-
{ command: "use [alias|local]", description: "Select a server; prompts in an interactive TTY.", primary: true },
|
|
10812
|
-
{ command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process.", primary: true }
|
|
10813
|
-
],
|
|
10814
|
-
examples: [
|
|
10815
|
-
"rig server status",
|
|
10816
|
-
"rig server add prod https://where.rig-does.work",
|
|
10817
|
-
"rig server use prod",
|
|
10818
|
-
"rig server use local",
|
|
10819
|
-
"rig server start --port 3773"
|
|
10820
|
-
],
|
|
10821
|
-
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
|
|
10822
|
-
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
10823
|
-
},
|
|
10824
|
-
{
|
|
10825
|
-
name: "task",
|
|
10826
|
-
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
10827
|
-
usage: ["rig task <list|next|show|run> [options]"],
|
|
10828
|
-
commands: [
|
|
10829
|
-
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
10830
|
-
{ command: "next [filters]", description: "Pick the next matching task.", primary: true },
|
|
10831
|
-
{ command: "show <id>|--task <id>", description: "Show task details.", primary: true },
|
|
10832
|
-
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
10833
|
-
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
10834
|
-
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
10835
|
-
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
10836
|
-
],
|
|
10837
|
-
examples: [
|
|
10838
|
-
"rig task list --assignee @me --limit 20",
|
|
10839
|
-
"rig task run --next",
|
|
10840
|
-
"rig task run #123 --runtime-adapter pi",
|
|
10841
|
-
"rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
|
|
10842
|
-
],
|
|
10843
|
-
next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
|
|
10844
|
-
},
|
|
10845
|
-
{
|
|
10846
|
-
name: "run",
|
|
10847
|
-
summary: "Observe, attach to, and control Rig runs.",
|
|
10848
|
-
usage: ["rig run <list|status|show|attach|stop> [options]"],
|
|
10849
|
-
commands: [
|
|
10850
|
-
{ command: "list", description: "List recent runs from the selected server or local state.", primary: true },
|
|
10851
|
-
{ command: "status", description: "Summarize active and recent runs.", primary: true },
|
|
10852
|
-
{ command: "show --run <id>", description: "Show one run record.", primary: true },
|
|
10853
|
-
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; `--follow` launches native bundled Pi for live Pi runs.", primary: true },
|
|
10854
|
-
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
10855
|
-
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
10856
|
-
{ command: "delete|cleanup", description: "Remove completed run records/artifacts." }
|
|
10857
|
-
],
|
|
10858
|
-
examples: [
|
|
10859
|
-
"rig run list",
|
|
10860
|
-
"rig run attach 01234567-89ab-cdef-0123-456789abcdef --follow",
|
|
10861
|
-
"rig run show --run <run-id>",
|
|
10862
|
-
"rig run stop <run-id>"
|
|
10863
|
-
],
|
|
10864
|
-
next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
|
|
10865
|
-
}
|
|
10866
|
-
];
|
|
10867
|
-
var ADVANCED_GROUPS = [
|
|
10868
|
-
{ 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." }] },
|
|
10869
|
-
{ name: "github", summary: "GitHub auth helpers.", usage: ["rig github auth <status|import-gh|token>"], commands: [{ command: "auth status", description: "Show GitHub auth state." }] },
|
|
10870
|
-
{ name: "doctor", summary: "Diagnostics for project/server/GitHub/Pi state.", usage: ["rig doctor [check|run|shared|...]"], commands: [{ command: "check", description: "Run diagnostics." }] },
|
|
10871
|
-
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
10872
|
-
{ 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." }] },
|
|
10873
|
-
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
10874
|
-
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
10875
|
-
{ name: "review", summary: "Review policy configuration.", usage: ["rig review <show|set>"], commands: [{ command: "show", description: "Show review settings." }] },
|
|
10876
|
-
{ name: "browser", summary: "Browser/app diagnostics.", usage: ["rig browser <help|explain|demo|app>"], commands: [{ command: "help", description: "Browser command help." }] },
|
|
10877
|
-
{ name: "plugin", summary: "Plugin validation/listing.", usage: ["rig plugin <list|validate>"], commands: [{ command: "list", description: "List plugins." }] },
|
|
10878
|
-
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
10879
|
-
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
10880
|
-
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
10881
|
-
{ name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
|
|
10882
|
-
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
10883
|
-
{ name: "remote", summary: "Legacy remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
|
|
10884
|
-
{ name: "inbox", summary: "Approval/input inbox for blocked runs.", usage: ["rig inbox <approvals|approve|inputs|respond>"], commands: [{ command: "approvals", description: "List pending approvals." }] },
|
|
10885
|
-
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
10886
|
-
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
10887
|
-
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
10888
|
-
];
|
|
10889
|
-
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
10890
|
-
function heading(title) {
|
|
10891
|
-
return pc4.bold(pc4.cyan(title));
|
|
10892
|
-
}
|
|
10893
|
-
function commandLine(command, description) {
|
|
10894
|
-
const commandColumn = command.length >= 34 ? `${command} ` : command.padEnd(34);
|
|
10895
|
-
return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
|
|
10896
|
-
}
|
|
10897
|
-
function renderGroup(group) {
|
|
10898
|
-
const lines = [
|
|
10899
|
-
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
10900
|
-
"",
|
|
10901
|
-
pc4.bold("Usage"),
|
|
10902
|
-
...group.usage.map((line) => ` ${line}`),
|
|
10903
|
-
"",
|
|
10904
|
-
pc4.bold("Commands"),
|
|
10905
|
-
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
10906
|
-
];
|
|
10907
|
-
if (group.examples?.length) {
|
|
10908
|
-
lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
|
|
10909
|
-
}
|
|
10910
|
-
if (group.next?.length) {
|
|
10911
|
-
lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
10912
|
-
}
|
|
10913
|
-
if (group.advanced?.length) {
|
|
10914
|
-
lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
10915
|
-
}
|
|
10916
|
-
return lines.join(`
|
|
10917
|
-
`);
|
|
10918
|
-
}
|
|
10919
|
-
function renderTopLevelHelp() {
|
|
10920
|
-
return [
|
|
10921
|
-
`${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
10922
|
-
pc4.dim("A repo-local CLI for setup, server selection, task runs, live attach, and completion review."),
|
|
10923
|
-
"",
|
|
10924
|
-
`${pc4.bold(pc4.magenta("\u25C7 Start here"))} \u2014 ${pc4.dim("bootstrap a repo and choose where Rig runs")}`,
|
|
10925
|
-
commandLine("rig init", "Interactive setup: project config, GitHub auth, task source, server, checkout, Pi."),
|
|
10926
|
-
commandLine("rig init --yes", "Non-interactive setup using detected defaults; good for repeatable installs."),
|
|
10927
|
-
commandLine("rig server status", "Show whether this repo is using local Rig or a remote server."),
|
|
10928
|
-
commandLine("rig server use <alias|local>", "Switch the server that owns task/run state for this repo."),
|
|
10929
|
-
"",
|
|
10930
|
-
`${pc4.bold(pc4.magenta("\u25C7 Daily task loop"))} \u2014 ${pc4.dim("find work, start a worker, and rejoin it later")}`,
|
|
10931
|
-
commandLine("rig task list", "List tasks from the selected task source/server with status, labels, and source."),
|
|
10932
|
-
commandLine("rig task next", "Pick the next matching task without starting it."),
|
|
10933
|
-
commandLine("rig task run --next", "Start the next task and attach to the live bundled Pi frontend."),
|
|
10934
|
-
commandLine("rig task run #123 --detach", "Submit a specific issue/task and return immediately."),
|
|
10935
|
-
"",
|
|
10936
|
-
`${pc4.bold(pc4.magenta("\u25C7 Live run control"))} \u2014 ${pc4.dim("observe, steer, stop, or inspect active runs")}`,
|
|
10937
|
-
commandLine("rig run list", "Show recent/active runs from the selected server or local state."),
|
|
10938
|
-
commandLine("rig run attach <run-id> --follow", "Open the native Pi live view for a worker-backed run."),
|
|
10939
|
-
commandLine("rig run show --run <id>", "Print one run record; add `--json` for automation."),
|
|
10940
|
-
commandLine("rig run stop <run-id>", "Request cancellation for a running worker."),
|
|
10941
|
-
"",
|
|
10942
|
-
`${pc4.bold(pc4.magenta("\u25C7 Core groups"))} \u2014 ${pc4.dim("run `rig <group> --help` for detailed commands and examples")}`,
|
|
10943
|
-
...PRIMARY_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
10944
|
-
commandLine("doctor", "Diagnose project/server/GitHub/task/Pi wiring when setup or runs misbehave."),
|
|
10945
|
-
"",
|
|
10946
|
-
`${pc4.bold(pc4.magenta("\u25C7 More"))}`,
|
|
10947
|
-
commandLine("rig help --advanced", "Legacy, dev, diagnostics, browser, queue, agent, remote, git, harness commands."),
|
|
10948
|
-
commandLine("rig <group> --help", "Rich per-group help with usage, descriptions, examples, and next steps."),
|
|
10949
|
-
commandLine("rig --version", "Print the installed Rig CLI version."),
|
|
10950
|
-
"",
|
|
10951
|
-
`${pc4.bold(pc4.magenta("\u25C7 Global options"))}`,
|
|
10952
|
-
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
10953
|
-
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
10954
|
-
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
10955
|
-
].join(`
|
|
10956
|
-
`);
|
|
10957
|
-
}
|
|
10958
|
-
function renderAdvancedHelp() {
|
|
10959
|
-
return [
|
|
10960
|
-
`${heading("rig advanced")} \u2014 legacy, dev, and compatibility groups`,
|
|
10961
|
-
"",
|
|
10962
|
-
pc4.bold("Primary groups are still"),
|
|
10963
|
-
" init, server, task, run",
|
|
10964
|
-
"",
|
|
10965
|
-
pc4.bold("Advanced groups"),
|
|
10966
|
-
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
10967
|
-
"",
|
|
10968
|
-
pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, and `rig run` for day-to-day work.")
|
|
10969
|
-
].join(`
|
|
10970
|
-
`);
|
|
10971
|
-
}
|
|
10972
|
-
function renderGroupHelp(groupName) {
|
|
10973
|
-
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
10974
|
-
return group ? renderGroup(group) : null;
|
|
10975
|
-
}
|
|
10976
|
-
|
|
10977
11527
|
// packages/cli/src/commands.ts
|
|
10978
11528
|
import { ensureProjectMainFreshBeforeRun as ensureProjectMainFreshBeforeRun2 } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
10979
11529
|
var TOP_LEVEL_ALIASES = {
|
|
@@ -10981,11 +11531,10 @@ var TOP_LEVEL_ALIASES = {
|
|
|
10981
11531
|
check: ["setup", "check"],
|
|
10982
11532
|
preflight: ["setup", "preflight"],
|
|
10983
11533
|
install: ["dist", "install"],
|
|
10984
|
-
"install-shell": ["setup", "install-agent-shell"],
|
|
10985
11534
|
status: ["run", "status"],
|
|
10986
11535
|
start: ["task", "run", "--next"],
|
|
10987
11536
|
"start-parallel": ["run", "start-parallel"],
|
|
10988
|
-
"start-serial": ["
|
|
11537
|
+
"start-serial": ["run", "start-serial"],
|
|
10989
11538
|
resume: ["run", "resume"],
|
|
10990
11539
|
stop: ["run", "stop"],
|
|
10991
11540
|
ready: ["task", "ready"],
|
|
@@ -11014,6 +11563,30 @@ var TOP_LEVEL_ALIASES = {
|
|
|
11014
11563
|
"remote-watch": ["remote", "watch"],
|
|
11015
11564
|
doctor: ["doctor", "check"]
|
|
11016
11565
|
};
|
|
11566
|
+
var PROJECT_REQUIRED_GROUPS = new Set([
|
|
11567
|
+
"task",
|
|
11568
|
+
"run",
|
|
11569
|
+
"inbox",
|
|
11570
|
+
"review",
|
|
11571
|
+
"queue",
|
|
11572
|
+
"agent",
|
|
11573
|
+
"repo",
|
|
11574
|
+
"inspect"
|
|
11575
|
+
]);
|
|
11576
|
+
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
11577
|
+
function hasInitializedRigProject(projectRoot) {
|
|
11578
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync14(resolve23(projectRoot, name))) || existsSync14(resolve23(projectRoot, ".rig"));
|
|
11579
|
+
}
|
|
11580
|
+
function requireInitializedRigProject(context, group) {
|
|
11581
|
+
if (hasInitializedRigProject(context.projectRoot)) {
|
|
11582
|
+
return;
|
|
11583
|
+
}
|
|
11584
|
+
throw new CliError2([
|
|
11585
|
+
`No Rig project found at ${context.projectRoot} (expected rig.config.ts or a .rig/ state directory).`,
|
|
11586
|
+
"Run `rig init` to set up this repo, or pass --project <path> to point at an existing Rig project."
|
|
11587
|
+
].join(`
|
|
11588
|
+
`), 2);
|
|
11589
|
+
}
|
|
11017
11590
|
var GROUPS = new Set([
|
|
11018
11591
|
"init",
|
|
11019
11592
|
"setup",
|
|
@@ -11041,7 +11614,7 @@ var GROUPS = new Set([
|
|
|
11041
11614
|
"test"
|
|
11042
11615
|
]);
|
|
11043
11616
|
function printGroupHelp(group) {
|
|
11044
|
-
|
|
11617
|
+
printGroupHelpDocument(group);
|
|
11045
11618
|
}
|
|
11046
11619
|
function isHelpArg(arg) {
|
|
11047
11620
|
return arg === "--help" || arg === "-h" || arg === "help";
|
|
@@ -11051,7 +11624,7 @@ function helpText() {
|
|
|
11051
11624
|
}
|
|
11052
11625
|
async function execute(context, args) {
|
|
11053
11626
|
if (args.length === 0) {
|
|
11054
|
-
|
|
11627
|
+
printTopLevelHelp();
|
|
11055
11628
|
return { ok: true, group: "help", command: "show" };
|
|
11056
11629
|
}
|
|
11057
11630
|
const [first, ...rest] = args;
|
|
@@ -11062,14 +11635,14 @@ ${helpText()}`);
|
|
|
11062
11635
|
}
|
|
11063
11636
|
if (first === "help" || first === "--help" || first === "-h") {
|
|
11064
11637
|
if (rest[0] === "--advanced") {
|
|
11065
|
-
|
|
11638
|
+
printAdvancedHelp();
|
|
11066
11639
|
return { ok: true, group: "help", command: "advanced" };
|
|
11067
11640
|
}
|
|
11068
11641
|
if (rest[0]) {
|
|
11069
|
-
|
|
11642
|
+
printGroupHelp(rest[0]);
|
|
11070
11643
|
return { ok: true, group: "help", command: rest[0] };
|
|
11071
11644
|
}
|
|
11072
|
-
|
|
11645
|
+
printTopLevelHelp();
|
|
11073
11646
|
return { ok: true, group: "help", command: "show" };
|
|
11074
11647
|
}
|
|
11075
11648
|
if (first === "--version" || first === "-V" || first === "version") {
|
|
@@ -11111,10 +11684,28 @@ ${helpText()}`);
|
|
|
11111
11684
|
}
|
|
11112
11685
|
return executeGroup(context, group, [command, ...aliasArgs, ...rest]);
|
|
11113
11686
|
}
|
|
11687
|
+
if (await matchesPluginCliCommand(context, first)) {
|
|
11688
|
+
return executeGroup(context, "plugin", ["run", first, ...rest]);
|
|
11689
|
+
}
|
|
11114
11690
|
throw new CliError2(`Unknown group or command: ${first}
|
|
11115
11691
|
|
|
11116
11692
|
${helpText()}`);
|
|
11117
11693
|
}
|
|
11694
|
+
async function matchesPluginCliCommand(context, requested) {
|
|
11695
|
+
if (!hasInitializedRigProject(context.projectRoot)) {
|
|
11696
|
+
return false;
|
|
11697
|
+
}
|
|
11698
|
+
try {
|
|
11699
|
+
const { buildPluginHostContext: buildPluginHostContext3 } = await import("@rig/runtime/control-plane/plugin-host-context");
|
|
11700
|
+
const hostCtx = await buildPluginHostContext3(context.projectRoot);
|
|
11701
|
+
if (!hostCtx)
|
|
11702
|
+
return false;
|
|
11703
|
+
const { resolvePluginCliCommand: resolvePluginCliCommand2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
|
|
11704
|
+
return Boolean(resolvePluginCliCommand2(hostCtx.pluginHost.listCliCommands(), requested));
|
|
11705
|
+
} catch {
|
|
11706
|
+
return false;
|
|
11707
|
+
}
|
|
11708
|
+
}
|
|
11118
11709
|
var GROUPS_WITH_CUSTOM_HELP = new Set(["browser"]);
|
|
11119
11710
|
async function executeGroup(context, group, args) {
|
|
11120
11711
|
if (isHelpArg(args[0]) && !GROUPS_WITH_CUSTOM_HELP.has(group)) {
|
|
@@ -11123,6 +11714,9 @@ async function executeGroup(context, group, args) {
|
|
|
11123
11714
|
}
|
|
11124
11715
|
return { ok: true, group, command: "help" };
|
|
11125
11716
|
}
|
|
11717
|
+
if (PROJECT_REQUIRED_GROUPS.has(group)) {
|
|
11718
|
+
requireInitializedRigProject(context, group);
|
|
11719
|
+
}
|
|
11126
11720
|
switch (group) {
|
|
11127
11721
|
case "setup":
|
|
11128
11722
|
return executeSetup(context, args);
|
|
@@ -11194,8 +11788,8 @@ var __testOnly = {
|
|
|
11194
11788
|
validateRequiredBugPromptValue
|
|
11195
11789
|
};
|
|
11196
11790
|
// packages/cli/src/launcher.ts
|
|
11197
|
-
import { existsSync as
|
|
11198
|
-
import { basename as basename2, resolve as
|
|
11791
|
+
import { existsSync as existsSync15 } from "fs";
|
|
11792
|
+
import { basename as basename2, resolve as resolve24 } from "path";
|
|
11199
11793
|
import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
|
|
11200
11794
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
|
|
11201
11795
|
function parsePolicyMode(value) {
|
|
@@ -11208,7 +11802,7 @@ function parsePolicyMode(value) {
|
|
|
11208
11802
|
throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
|
|
11209
11803
|
}
|
|
11210
11804
|
function hasRigProjectMarker(candidate) {
|
|
11211
|
-
return
|
|
11805
|
+
return existsSync15(resolve24(candidate, RIG_DEFINITION_DIRNAME)) || existsSync15(resolve24(candidate, RIG_STATE_DIRNAME)) || existsSync15(resolve24(candidate, "rig.config.ts")) || existsSync15(resolve24(candidate, "rig.config.json")) || existsSync15(resolve24(candidate, ".git"));
|
|
11212
11806
|
}
|
|
11213
11807
|
function resolveProjectRoot({
|
|
11214
11808
|
envProjectRoot,
|
|
@@ -11217,19 +11811,19 @@ function resolveProjectRoot({
|
|
|
11217
11811
|
cwd = process.cwd()
|
|
11218
11812
|
}) {
|
|
11219
11813
|
if (envProjectRoot) {
|
|
11220
|
-
return
|
|
11814
|
+
return resolve24(cwd, envProjectRoot);
|
|
11221
11815
|
}
|
|
11222
11816
|
const fallbackImportDir = importDir ?? cwd;
|
|
11223
11817
|
const execName = basename2(execPath).toLowerCase();
|
|
11224
|
-
const execCandidates = execName === "rig" || execName === "rig.exe" ? [
|
|
11225
|
-
const candidates = [cwd, ...execCandidates,
|
|
11818
|
+
const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve24(execPath, "..", "..")] : [];
|
|
11819
|
+
const candidates = [cwd, ...execCandidates, resolve24(fallbackImportDir, "..")];
|
|
11226
11820
|
for (const candidate of candidates) {
|
|
11227
11821
|
const nearest = resolveNearestRigProjectRoot(candidate);
|
|
11228
11822
|
if (hasRigProjectMarker(nearest)) {
|
|
11229
11823
|
return nearest;
|
|
11230
11824
|
}
|
|
11231
11825
|
}
|
|
11232
|
-
return
|
|
11826
|
+
return resolve24(cwd);
|
|
11233
11827
|
}
|
|
11234
11828
|
function normalizeCliErrorCode(message2, isCliError) {
|
|
11235
11829
|
if (message2.startsWith("Invalid --policy-mode value:")) {
|
|
@@ -11296,7 +11890,7 @@ async function runRigCli(module, options = {}) {
|
|
|
11296
11890
|
runId: context.runId,
|
|
11297
11891
|
outcome,
|
|
11298
11892
|
eventsFile: context.eventBus.getEventsFile(),
|
|
11299
|
-
policyFile:
|
|
11893
|
+
policyFile: resolve24(projectRoot, "rig", "policy", "policy.json"),
|
|
11300
11894
|
policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
|
|
11301
11895
|
}, null, 2));
|
|
11302
11896
|
}
|
|
@@ -11320,6 +11914,7 @@ function hydrateProcessEnvFromDotEnv(projectRoot) {
|
|
|
11320
11914
|
}
|
|
11321
11915
|
|
|
11322
11916
|
// packages/cli/src/index.ts
|
|
11917
|
+
init_runner();
|
|
11323
11918
|
var RIG_CLI_PACKAGE = "@rig/cli";
|
|
11324
11919
|
export {
|
|
11325
11920
|
withProjectRoot,
|