@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/bin/rig.js
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __returnValue = (v) => v;
|
|
5
|
+
function __exportSetter(name, newValue) {
|
|
6
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
7
|
+
}
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
set: __exportSetter.bind(all, name)
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
3
18
|
var __require = import.meta.require;
|
|
4
19
|
|
|
5
|
-
// packages/cli/bin/rig.ts
|
|
6
|
-
import { loadPolicy as loadPolicy3 } from "@rig/runtime/control-plane/runtime/guard";
|
|
7
|
-
|
|
8
20
|
// packages/cli/src/runner.ts
|
|
9
21
|
var {$ } = globalThis.Bun;
|
|
10
22
|
import { existsSync, mkdirSync } from "fs";
|
|
@@ -12,8 +24,6 @@ import { resolve } from "path";
|
|
|
12
24
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
13
25
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
14
26
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
15
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
16
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
17
27
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
18
28
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
19
29
|
function withProjectRoot(projectRoot) {
|
|
@@ -22,7 +32,6 @@ function withProjectRoot(projectRoot) {
|
|
|
22
32
|
function formatCommand(parts) {
|
|
23
33
|
return parts.map((part) => /[^a-zA-Z0-9_./:-]/.test(part) ? JSON.stringify(part) : part).join(" ");
|
|
24
34
|
}
|
|
25
|
-
var AGENT_DISPATCH_SOURCE = "packages/runtime/bin/rig-agent-dispatch.ts";
|
|
26
35
|
function hasAgentDispatchSource(root) {
|
|
27
36
|
return existsSync(resolve(root, AGENT_DISPATCH_SOURCE));
|
|
28
37
|
}
|
|
@@ -67,13 +76,6 @@ async function ensureAgentShellBinary(projectRoot, options = {}) {
|
|
|
67
76
|
}
|
|
68
77
|
async function initializeRuntime(options) {
|
|
69
78
|
const eventBus = new EventBus({ projectRoot: options.projectRoot, runId: options.runId });
|
|
70
|
-
const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
|
|
71
|
-
const plugins = await PluginManager.load({
|
|
72
|
-
projectRoot: options.projectRoot,
|
|
73
|
-
runId: eventBus.getRunId(),
|
|
74
|
-
eventBus,
|
|
75
|
-
runtimeContext
|
|
76
|
-
});
|
|
77
79
|
const context = {
|
|
78
80
|
projectRoot: options.projectRoot,
|
|
79
81
|
dryRun: options.dryRun,
|
|
@@ -81,10 +83,8 @@ async function initializeRuntime(options) {
|
|
|
81
83
|
runId: eventBus.getRunId(),
|
|
82
84
|
policyMode: options.policyMode,
|
|
83
85
|
eventBus,
|
|
84
|
-
plugins,
|
|
85
86
|
emitEvent: async (type, payload) => {
|
|
86
|
-
|
|
87
|
-
await plugins.onEvent(event);
|
|
87
|
+
await eventBus.emit(type, payload);
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
context.runCommand = async (parts) => runCommand(context, parts);
|
|
@@ -93,8 +93,7 @@ async function initializeRuntime(options) {
|
|
|
93
93
|
outputMode: context.outputMode,
|
|
94
94
|
dryRun: context.dryRun,
|
|
95
95
|
policyMode: context.policyMode ?? loadPolicy(options.projectRoot).mode,
|
|
96
|
-
policyFile: resolve(options.projectRoot, "rig/policy/policy.json")
|
|
97
|
-
plugins: context.plugins.list()
|
|
96
|
+
policyFile: resolve(options.projectRoot, "rig/policy/policy.json")
|
|
98
97
|
});
|
|
99
98
|
return context;
|
|
100
99
|
}
|
|
@@ -145,7 +144,6 @@ async function runCommand(context, parts) {
|
|
|
145
144
|
});
|
|
146
145
|
throw new CliError(`Policy blocked command: ${formatted}`, 126);
|
|
147
146
|
}
|
|
148
|
-
await context.plugins.beforeCommand({ command: commandWithEnv, formattedCommand: formatted });
|
|
149
147
|
const startedAt = new Date;
|
|
150
148
|
await context.emitEvent("command.started", {
|
|
151
149
|
command: commandWithEnv,
|
|
@@ -165,7 +163,6 @@ async function runCommand(context, parts) {
|
|
|
165
163
|
if (context.outputMode === "text") {
|
|
166
164
|
console.log(`$ ${formatted}`);
|
|
167
165
|
}
|
|
168
|
-
await context.plugins.afterCommand(dryResult);
|
|
169
166
|
await context.emitEvent("command.finished", {
|
|
170
167
|
...dryResult,
|
|
171
168
|
dryRun: true
|
|
@@ -205,7 +202,6 @@ async function runCommand(context, parts) {
|
|
|
205
202
|
stdout: context.outputMode === "json" ? stdout : undefined,
|
|
206
203
|
stderr: context.outputMode === "json" ? stderr : undefined
|
|
207
204
|
};
|
|
208
|
-
await context.plugins.afterCommand(result);
|
|
209
205
|
if (exitCode !== 0) {
|
|
210
206
|
await context.emitEvent("command.failed", {
|
|
211
207
|
...result
|
|
@@ -264,11 +260,281 @@ Usage: ${usage}`);
|
|
|
264
260
|
}
|
|
265
261
|
return taskId;
|
|
266
262
|
}
|
|
263
|
+
var AGENT_DISPATCH_SOURCE = "packages/runtime/bin/rig-agent-dispatch.ts";
|
|
264
|
+
var init_runner = () => {};
|
|
265
|
+
|
|
266
|
+
// packages/cli/src/commands/_parsers.ts
|
|
267
|
+
import { homedir } from "os";
|
|
268
|
+
import { resolve as resolve7 } from "path";
|
|
269
|
+
function parsePositiveInt(value, option, fallback) {
|
|
270
|
+
if (!value) {
|
|
271
|
+
return fallback;
|
|
272
|
+
}
|
|
273
|
+
const parsed = Number.parseInt(value, 10);
|
|
274
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
275
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
276
|
+
}
|
|
277
|
+
return parsed;
|
|
278
|
+
}
|
|
279
|
+
function parseOptionalPositiveInt(value, option) {
|
|
280
|
+
if (!value) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const parsed = Number.parseInt(value, 10);
|
|
284
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
285
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
286
|
+
}
|
|
287
|
+
return parsed;
|
|
288
|
+
}
|
|
289
|
+
function parseRequiredPositiveInt(value, option) {
|
|
290
|
+
if (!value) {
|
|
291
|
+
throw new CliError2(`Missing value for ${option}.`);
|
|
292
|
+
}
|
|
293
|
+
const parsed = Number.parseInt(value, 10);
|
|
294
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
295
|
+
throw new CliError2(`Invalid ${option} value: ${value}`);
|
|
296
|
+
}
|
|
297
|
+
return parsed;
|
|
298
|
+
}
|
|
299
|
+
function parseAction(value) {
|
|
300
|
+
if (!value || value === "validate") {
|
|
301
|
+
return "validate";
|
|
302
|
+
}
|
|
303
|
+
if (value === "verify") {
|
|
304
|
+
return "verify";
|
|
305
|
+
}
|
|
306
|
+
if (value === "pipeline") {
|
|
307
|
+
return "pipeline";
|
|
308
|
+
}
|
|
309
|
+
throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
|
|
310
|
+
}
|
|
311
|
+
function parseIsolationMode(value, allowOff) {
|
|
312
|
+
if (!value) {
|
|
313
|
+
return "worktree";
|
|
314
|
+
}
|
|
315
|
+
if (value === "worktree") {
|
|
316
|
+
return value;
|
|
317
|
+
}
|
|
318
|
+
if (allowOff && value === "off") {
|
|
319
|
+
return value;
|
|
320
|
+
}
|
|
321
|
+
throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
|
|
322
|
+
}
|
|
323
|
+
function parseInstallScope(value) {
|
|
324
|
+
if (!value || value === "user") {
|
|
325
|
+
return "user";
|
|
326
|
+
}
|
|
327
|
+
if (value === "system") {
|
|
328
|
+
return "system";
|
|
329
|
+
}
|
|
330
|
+
throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
|
|
331
|
+
}
|
|
332
|
+
function resolveInstallDir(scope, explicitPath) {
|
|
333
|
+
if (explicitPath) {
|
|
334
|
+
return resolve7(explicitPath);
|
|
335
|
+
}
|
|
336
|
+
if (scope === "system") {
|
|
337
|
+
return "/usr/local/bin";
|
|
338
|
+
}
|
|
339
|
+
return resolve7(homedir(), ".local/bin");
|
|
340
|
+
}
|
|
341
|
+
async function loadRigConfigOrNull(projectRoot) {
|
|
342
|
+
try {
|
|
343
|
+
const { loadConfig } = await import("@rig/core/load-config");
|
|
344
|
+
return await loadConfig(projectRoot);
|
|
345
|
+
} catch {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
var init__parsers = __esm(() => {
|
|
350
|
+
init_runner();
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// packages/cli/src/commands/plugin.ts
|
|
354
|
+
var exports_plugin = {};
|
|
355
|
+
__export(exports_plugin, {
|
|
356
|
+
resolvePluginCliCommand: () => resolvePluginCliCommand,
|
|
357
|
+
executePlugin: () => executePlugin
|
|
358
|
+
});
|
|
359
|
+
import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
|
|
360
|
+
async function executePlugin(context, args) {
|
|
361
|
+
const [command = "list", ...rest] = args;
|
|
362
|
+
switch (command) {
|
|
363
|
+
case "list": {
|
|
364
|
+
requireNoExtraArgs(rest, "rig plugin list");
|
|
365
|
+
const declarative = [];
|
|
366
|
+
const config = await loadRigConfigOrNull(context.projectRoot);
|
|
367
|
+
if (config && Array.isArray(config.plugins)) {
|
|
368
|
+
for (const plugin of config.plugins) {
|
|
369
|
+
const c = plugin.contributes ?? {};
|
|
370
|
+
declarative.push({
|
|
371
|
+
name: plugin.name,
|
|
372
|
+
version: plugin.version,
|
|
373
|
+
validators: (c.validators ?? []).map((v) => v.id),
|
|
374
|
+
hooks: (c.hooks ?? []).map((h) => h.id),
|
|
375
|
+
agentRoles: (c.agentRoles ?? []).map((r) => r.id),
|
|
376
|
+
repoSources: (c.repoSources ?? []).map((r) => r.id),
|
|
377
|
+
taskSources: (c.taskSources ?? []).map((s) => s.id),
|
|
378
|
+
skills: (c.skills ?? []).map((s) => s.id),
|
|
379
|
+
taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
|
|
380
|
+
cliCommands: (c.cliCommands ?? []).map((entry) => entry.id)
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (context.outputMode === "text") {
|
|
385
|
+
if (declarative.length === 0) {
|
|
386
|
+
console.log("No plugins loaded. Declare plugins in rig.config.ts.");
|
|
387
|
+
} else {
|
|
388
|
+
console.log("Plugins (rig.config.ts):");
|
|
389
|
+
for (const p of declarative) {
|
|
390
|
+
console.log(` ${p.name}@${p.version}`);
|
|
391
|
+
const lines = [];
|
|
392
|
+
if (p.validators.length)
|
|
393
|
+
lines.push(` validators: ${p.validators.join(", ")}`);
|
|
394
|
+
if (p.hooks.length)
|
|
395
|
+
lines.push(` hooks: ${p.hooks.join(", ")}`);
|
|
396
|
+
if (p.agentRoles.length)
|
|
397
|
+
lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
|
|
398
|
+
if (p.repoSources.length)
|
|
399
|
+
lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
|
|
400
|
+
if (p.taskSources.length)
|
|
401
|
+
lines.push(` task-sources: ${p.taskSources.join(", ")}`);
|
|
402
|
+
if (p.skills.length)
|
|
403
|
+
lines.push(` skills: ${p.skills.join(", ")}`);
|
|
404
|
+
if (p.taskFieldExtensions.length)
|
|
405
|
+
lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
|
|
406
|
+
if (p.cliCommands.length)
|
|
407
|
+
lines.push(` cli-commands: ${p.cliCommands.join(", ")} (run with \`rig plugin run <id>\`)`);
|
|
408
|
+
for (const line of lines)
|
|
409
|
+
console.log(line);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
ok: true,
|
|
415
|
+
group: "plugin",
|
|
416
|
+
command,
|
|
417
|
+
details: { declarative }
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
case "validate": {
|
|
421
|
+
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
422
|
+
requireNoExtraArgs(remaining, "rig plugin validate --task <task-id>");
|
|
423
|
+
const taskId = requireTask(task, "rig plugin validate --task <task-id>");
|
|
424
|
+
const hostCtx = await buildPluginHostContext(context.projectRoot);
|
|
425
|
+
if (!hostCtx) {
|
|
426
|
+
throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
|
|
427
|
+
}
|
|
428
|
+
const validators = hostCtx.validatorRegistry.list();
|
|
429
|
+
const results = [];
|
|
430
|
+
for (const validator of validators) {
|
|
431
|
+
try {
|
|
432
|
+
results.push(await validator.run({
|
|
433
|
+
taskId,
|
|
434
|
+
workspaceRoot: context.projectRoot,
|
|
435
|
+
scope: []
|
|
436
|
+
}));
|
|
437
|
+
} catch (error) {
|
|
438
|
+
results.push({
|
|
439
|
+
id: validator.id,
|
|
440
|
+
passed: false,
|
|
441
|
+
summary: `${validator.id} failed unexpectedly`,
|
|
442
|
+
details: `${error}`
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
const passed = results.filter((result) => result.passed).length;
|
|
447
|
+
const failed = results.length - passed;
|
|
448
|
+
if (context.outputMode === "text") {
|
|
449
|
+
if (results.length === 0) {
|
|
450
|
+
console.log("No plugin validators registered.");
|
|
451
|
+
} else {
|
|
452
|
+
for (const result of results) {
|
|
453
|
+
const icon = result.passed ? "PASS" : "FAIL";
|
|
454
|
+
console.log(`[${icon}] ${result.id}: ${result.summary}`);
|
|
455
|
+
if (result.details && !result.passed) {
|
|
456
|
+
console.log(result.details);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
if (failed > 0) {
|
|
462
|
+
throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
ok: true,
|
|
466
|
+
group: "plugin",
|
|
467
|
+
command,
|
|
468
|
+
details: {
|
|
469
|
+
taskId,
|
|
470
|
+
passed,
|
|
471
|
+
failed,
|
|
472
|
+
results
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
case "run": {
|
|
477
|
+
const [commandId, ...commandArgs] = rest;
|
|
478
|
+
if (!commandId) {
|
|
479
|
+
throw new CliError2("Usage: rig plugin run <command-id> [args...]");
|
|
480
|
+
}
|
|
481
|
+
const hostCtx = await buildPluginHostContext(context.projectRoot);
|
|
482
|
+
if (!hostCtx) {
|
|
483
|
+
throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
|
|
484
|
+
}
|
|
485
|
+
const registration = resolvePluginCliCommand(hostCtx.pluginHost.listCliCommands(), commandId);
|
|
486
|
+
if (!registration) {
|
|
487
|
+
const available = hostCtx.pluginHost.listCliCommands().map((entry) => entry.id);
|
|
488
|
+
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);
|
|
489
|
+
}
|
|
490
|
+
if (context.dryRun) {
|
|
491
|
+
if (context.outputMode === "text") {
|
|
492
|
+
console.log(`[dry-run] ${registration.command}${commandArgs.length ? ` ${commandArgs.join(" ")}` : ""}`);
|
|
493
|
+
}
|
|
494
|
+
return { ok: true, group: "plugin", command, details: { id: registration.id, dryRun: true } };
|
|
495
|
+
}
|
|
496
|
+
const proc = Bun.spawn(["bash", "-c", `${registration.command} "$@"`, registration.id, ...commandArgs], {
|
|
497
|
+
cwd: context.projectRoot,
|
|
498
|
+
env: process.env,
|
|
499
|
+
stdin: "inherit",
|
|
500
|
+
stdout: "inherit",
|
|
501
|
+
stderr: "inherit"
|
|
502
|
+
});
|
|
503
|
+
const exitCode = await proc.exited;
|
|
504
|
+
if (exitCode !== 0) {
|
|
505
|
+
throw new CliError2(`Plugin command "${registration.id}" exited with code ${exitCode}.`, exitCode);
|
|
506
|
+
}
|
|
507
|
+
return { ok: true, group: "plugin", command, details: { id: registration.id, exitCode } };
|
|
508
|
+
}
|
|
509
|
+
default:
|
|
510
|
+
throw new CliError2(`Unknown plugin command: ${command}`);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function resolvePluginCliCommand(commands, requested) {
|
|
514
|
+
const exact = commands.find((entry) => entry.id === requested);
|
|
515
|
+
if (exact)
|
|
516
|
+
return exact;
|
|
517
|
+
const byLocalPart = commands.filter((entry) => entry.id.split(":").slice(1).join(":") === requested);
|
|
518
|
+
return byLocalPart.length === 1 ? byLocalPart[0] : undefined;
|
|
519
|
+
}
|
|
520
|
+
var init_plugin = __esm(() => {
|
|
521
|
+
init_runner();
|
|
522
|
+
init__parsers();
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// packages/cli/bin/rig.ts
|
|
526
|
+
import { loadPolicy as loadPolicy3 } from "@rig/runtime/control-plane/runtime/guard";
|
|
267
527
|
|
|
268
528
|
// packages/cli/src/commands.ts
|
|
529
|
+
init_runner();
|
|
530
|
+
import {
|
|
531
|
+
existsSync as existsSync14
|
|
532
|
+
} from "fs";
|
|
533
|
+
import { resolve as resolve23 } from "path";
|
|
269
534
|
import { readBuildConfig } from "@rig/runtime/build-time-config";
|
|
270
535
|
|
|
271
536
|
// packages/cli/src/commands/browser.ts
|
|
537
|
+
init_runner();
|
|
272
538
|
import { mkdirSync as mkdirSync3, rmSync as rmSync2 } from "fs";
|
|
273
539
|
import { resolve as resolve5 } from "path";
|
|
274
540
|
import { spawn } from "child_process";
|
|
@@ -279,6 +545,7 @@ import pc2 from "picocolors";
|
|
|
279
545
|
import { runCapture as runCapture2 } from "@rig/runtime/control-plane/native/utils";
|
|
280
546
|
|
|
281
547
|
// packages/cli/src/commands/task-report-bug.ts
|
|
548
|
+
init_runner();
|
|
282
549
|
import { existsSync as existsSync3, readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
283
550
|
import { resolve as resolve4 } from "path";
|
|
284
551
|
import * as clack from "@clack/prompts";
|
|
@@ -495,15 +762,15 @@ function buildBugReportMarkdown(input, browser, screenshots, assets) {
|
|
|
495
762
|
...input.issueId ? [
|
|
496
763
|
`- Canonical task assets live under \`artifacts/${input.issueId}/bug-report/\`.`,
|
|
497
764
|
`- Start with \`artifacts/${input.issueId}/bug-report/task.md\` and the files in \`artifacts/${input.issueId}/bug-report/assets/\`.`,
|
|
498
|
-
browserRequired ? `- Run \`
|
|
765
|
+
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.`
|
|
499
766
|
] : [
|
|
500
|
-
"- Draft-only report: convert this into a
|
|
767
|
+
"- Draft-only report: convert this into a Rig task before assigning it to an agent run."
|
|
501
768
|
],
|
|
502
769
|
"",
|
|
503
770
|
"## Validation",
|
|
504
771
|
"",
|
|
505
772
|
"```bash",
|
|
506
|
-
...input.issueId ? [`
|
|
773
|
+
...input.issueId ? [`rig task validate --task ${input.issueId}`] : [],
|
|
507
774
|
...browserRequired ? [
|
|
508
775
|
"bun run app:check:browser:hp-next",
|
|
509
776
|
"bun run app:e2e:browser:hp-next"
|
|
@@ -650,7 +917,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
650
917
|
pending = outputRootResult.rest;
|
|
651
918
|
const slugResult = takeOption(pending, "--slug");
|
|
652
919
|
pending = slugResult.rest;
|
|
653
|
-
requireNoExtraArgs(pending, "
|
|
920
|
+
requireNoExtraArgs(pending, "rig report-bug [--no-prompt] [--no-beads] [--browser|--no-browser] --title <text> --url <url> [--asset <dragged-file>]");
|
|
654
921
|
let draft = {
|
|
655
922
|
outputRoot: outputRootResult.value || "",
|
|
656
923
|
title: titleResult.value,
|
|
@@ -755,7 +1022,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
755
1022
|
console.log(`Evidence assets: ${result.assetDir}`);
|
|
756
1023
|
if (taskConfigPath) {
|
|
757
1024
|
console.log(`Task config: ${taskConfigPath}`);
|
|
758
|
-
console.log(`Run:
|
|
1025
|
+
console.log(`Run: rig task info --task ${issueId}`);
|
|
759
1026
|
}
|
|
760
1027
|
}
|
|
761
1028
|
return {
|
|
@@ -1578,7 +1845,7 @@ async function executeBrowser(context, args) {
|
|
|
1578
1845
|
return { ok: true, group: "browser", command: "help" };
|
|
1579
1846
|
}
|
|
1580
1847
|
if (command === "explain") {
|
|
1581
|
-
requireNoExtraArgs(rest, "
|
|
1848
|
+
requireNoExtraArgs(rest, "rig browser explain");
|
|
1582
1849
|
console.log(browserAgentUsageText());
|
|
1583
1850
|
return { ok: true, group: "browser", command: "explain" };
|
|
1584
1851
|
}
|
|
@@ -1604,7 +1871,7 @@ ${browserHelpText()}`);
|
|
|
1604
1871
|
|
|
1605
1872
|
${browserHelpText()}`);
|
|
1606
1873
|
}
|
|
1607
|
-
requireNoExtraArgs(appRest, `
|
|
1874
|
+
requireNoExtraArgs(appRest, `rig browser ${command} ${subcommand}`);
|
|
1608
1875
|
await context.runCommand(["bun", "run", `app:${subcommand}:browser:${appSlug}`]);
|
|
1609
1876
|
return { ok: true, group: "browser", command: `${command}-${subcommand}` };
|
|
1610
1877
|
}
|
|
@@ -1616,7 +1883,7 @@ ${browserHelpText()}`);
|
|
|
1616
1883
|
};
|
|
1617
1884
|
const packageScript = packageScripts[command];
|
|
1618
1885
|
if (packageScript) {
|
|
1619
|
-
requireNoExtraArgs(rest, `
|
|
1886
|
+
requireNoExtraArgs(rest, `rig browser ${command}`);
|
|
1620
1887
|
await context.runCommand(["bun", "run", "--filter=@rig/browser", packageScript]);
|
|
1621
1888
|
return { ok: true, group: "browser", command };
|
|
1622
1889
|
}
|
|
@@ -1643,7 +1910,7 @@ async function executeBrowserDemo(context, args) {
|
|
|
1643
1910
|
pending = keepOpenFlag.rest;
|
|
1644
1911
|
const noBuildFlag = takeFlag(pending, "--no-build");
|
|
1645
1912
|
pending = noBuildFlag.rest;
|
|
1646
|
-
requireNoExtraArgs(pending, "
|
|
1913
|
+
requireNoExtraArgs(pending, "rig browser demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]");
|
|
1647
1914
|
if (context.outputMode !== "text" || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
1648
1915
|
throw new CliError2("rig browser demo requires an interactive TTY in text mode.");
|
|
1649
1916
|
}
|
|
@@ -2103,6 +2370,7 @@ async function stopBrowserDemo(child) {
|
|
|
2103
2370
|
}
|
|
2104
2371
|
|
|
2105
2372
|
// packages/cli/src/commands/profile-and-review.ts
|
|
2373
|
+
init_runner();
|
|
2106
2374
|
import {
|
|
2107
2375
|
setProfile,
|
|
2108
2376
|
setReviewProfile,
|
|
@@ -2154,17 +2422,17 @@ async function executeProfile(context, args) {
|
|
|
2154
2422
|
const [command = "show", ...rest] = args;
|
|
2155
2423
|
switch (command) {
|
|
2156
2424
|
case "show":
|
|
2157
|
-
requireNoExtraArgs(rest, "
|
|
2425
|
+
requireNoExtraArgs(rest, "rig profile show");
|
|
2158
2426
|
await withMutedConsole(context.outputMode === "json", () => showProfile(context.projectRoot));
|
|
2159
2427
|
return { ok: true, group: "profile", command };
|
|
2160
2428
|
case "set": {
|
|
2161
2429
|
if (rest.length === 0) {
|
|
2162
|
-
throw new CliError2("Usage:
|
|
2430
|
+
throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi> or set [--model ...] [--runtime ...] [--plugin ...]");
|
|
2163
2431
|
}
|
|
2164
2432
|
const preset = rest[0];
|
|
2165
2433
|
if (preset && !preset.startsWith("-")) {
|
|
2166
2434
|
if (rest.length !== 1) {
|
|
2167
|
-
throw new CliError2("Usage:
|
|
2435
|
+
throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi>");
|
|
2168
2436
|
}
|
|
2169
2437
|
try {
|
|
2170
2438
|
await withMutedConsole(context.outputMode === "json", () => setProfile(context.projectRoot, { preset }));
|
|
@@ -2180,7 +2448,7 @@ async function executeProfile(context, args) {
|
|
|
2180
2448
|
pending = runtimeResult.rest;
|
|
2181
2449
|
const pluginResult = takeOption(pending, "--plugin");
|
|
2182
2450
|
pending = pluginResult.rest;
|
|
2183
|
-
requireNoExtraArgs(pending, "
|
|
2451
|
+
requireNoExtraArgs(pending, "rig profile set [--model ...] [--runtime ...] [--plugin ...]");
|
|
2184
2452
|
if (!modelResult.value && !runtimeResult.value && !pluginResult.value) {
|
|
2185
2453
|
throw new CliError2("Provide at least one of --model, --runtime, or --plugin.");
|
|
2186
2454
|
}
|
|
@@ -2212,21 +2480,21 @@ async function executeReview(context, args) {
|
|
|
2212
2480
|
const [command = "show", ...rest] = args;
|
|
2213
2481
|
switch (command) {
|
|
2214
2482
|
case "show":
|
|
2215
|
-
requireNoExtraArgs(rest, "
|
|
2483
|
+
requireNoExtraArgs(rest, "rig review show");
|
|
2216
2484
|
await withMutedConsole(context.outputMode === "json", () => showReviewProfile(context.projectRoot));
|
|
2217
2485
|
return { ok: true, group: "review", command };
|
|
2218
2486
|
case "set": {
|
|
2219
2487
|
if (rest.length === 0) {
|
|
2220
|
-
throw new CliError2("Usage:
|
|
2488
|
+
throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
|
|
2221
2489
|
}
|
|
2222
2490
|
const mode = rest[0];
|
|
2223
2491
|
if (!mode) {
|
|
2224
|
-
throw new CliError2("Usage:
|
|
2492
|
+
throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
|
|
2225
2493
|
}
|
|
2226
2494
|
let pending = rest.slice(1);
|
|
2227
2495
|
const providerResult = takeOption(pending, "--provider");
|
|
2228
2496
|
pending = providerResult.rest;
|
|
2229
|
-
requireNoExtraArgs(pending, "
|
|
2497
|
+
requireNoExtraArgs(pending, "rig review set <off|advisory|required> [--provider greptile]");
|
|
2230
2498
|
try {
|
|
2231
2499
|
await withMutedConsole(context.outputMode === "json", () => {
|
|
2232
2500
|
return setReviewProfile(context.projectRoot, mode, providerResult.value);
|
|
@@ -2242,10 +2510,12 @@ async function executeReview(context, args) {
|
|
|
2242
2510
|
}
|
|
2243
2511
|
|
|
2244
2512
|
// packages/cli/src/commands/repo-git-harness.ts
|
|
2513
|
+
init_runner();
|
|
2245
2514
|
import { executeHarnessCommand } from "@rig/runtime/control-plane/native/harness-cli";
|
|
2246
2515
|
import { repoEnsure, resetBaseline } from "@rig/runtime/control-plane/native/repo-ops";
|
|
2247
2516
|
|
|
2248
2517
|
// packages/cli/src/commands/_policy.ts
|
|
2518
|
+
init_runner();
|
|
2249
2519
|
import { appendFileSync, mkdirSync as mkdirSync4 } from "fs";
|
|
2250
2520
|
import { resolve as resolve6 } from "path";
|
|
2251
2521
|
import { evaluate as evaluate2, loadPolicy as loadPolicy2, resolveAction as resolveAction2 } from "@rig/runtime/control-plane/runtime/guard";
|
|
@@ -2311,13 +2581,13 @@ async function executeRepo(context, args) {
|
|
|
2311
2581
|
switch (command) {
|
|
2312
2582
|
case "sync": {
|
|
2313
2583
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
2314
|
-
requireNoExtraArgs(remaining, "
|
|
2584
|
+
requireNoExtraArgs(remaining, "rig repo sync [--task <task-id>]");
|
|
2315
2585
|
withMutedConsole(context.outputMode === "json", () => repoEnsure(context.projectRoot, task || undefined));
|
|
2316
2586
|
return { ok: true, group: "repo", command, details: { task: task || null } };
|
|
2317
2587
|
}
|
|
2318
2588
|
case "reset-baseline": {
|
|
2319
2589
|
const { value: keepTaskStatusFlag, rest: remaining } = takeFlag(rest, "--keep-task-status");
|
|
2320
|
-
requireNoExtraArgs(remaining, "
|
|
2590
|
+
requireNoExtraArgs(remaining, "rig repo reset-baseline [--keep-task-status]");
|
|
2321
2591
|
withMutedConsole(context.outputMode === "json", () => resetBaseline(context.projectRoot, keepTaskStatusFlag));
|
|
2322
2592
|
return { ok: true, group: "repo", command, details: { keepTaskStatus: keepTaskStatusFlag } };
|
|
2323
2593
|
}
|
|
@@ -2327,7 +2597,7 @@ async function executeRepo(context, args) {
|
|
|
2327
2597
|
}
|
|
2328
2598
|
async function executeGit(context, args) {
|
|
2329
2599
|
if (args.length === 0) {
|
|
2330
|
-
throw new CliError2("Usage:
|
|
2600
|
+
throw new CliError2("Usage: rig git <git-flow args...>");
|
|
2331
2601
|
}
|
|
2332
2602
|
await enforceNativeCommandPolicy(context, args, {
|
|
2333
2603
|
commandPrefix: "rig-agent git",
|
|
@@ -2340,7 +2610,7 @@ async function executeGit(context, args) {
|
|
|
2340
2610
|
return { ok: true, group: "git", command: args[0] ?? "git" };
|
|
2341
2611
|
}
|
|
2342
2612
|
try {
|
|
2343
|
-
await executeHarnessCommand(context.projectRoot,
|
|
2613
|
+
await executeHarnessCommand(context.projectRoot, ["git", ...args]);
|
|
2344
2614
|
} catch (error) {
|
|
2345
2615
|
throw new CliError2(error instanceof Error ? error.message : String(error), 2);
|
|
2346
2616
|
}
|
|
@@ -2348,7 +2618,7 @@ async function executeGit(context, args) {
|
|
|
2348
2618
|
}
|
|
2349
2619
|
async function executeHarness(context, args) {
|
|
2350
2620
|
if (args.length === 0) {
|
|
2351
|
-
throw new CliError2("Usage:
|
|
2621
|
+
throw new CliError2("Usage: rig harness <harness args...>");
|
|
2352
2622
|
}
|
|
2353
2623
|
await enforceNativeCommandPolicy(context, args, {
|
|
2354
2624
|
commandPrefix: "rig-agent",
|
|
@@ -2361,236 +2631,49 @@ async function executeHarness(context, args) {
|
|
|
2361
2631
|
return { ok: true, group: "harness", command: args[0] ?? "harness" };
|
|
2362
2632
|
}
|
|
2363
2633
|
try {
|
|
2364
|
-
await executeHarnessCommand(context.projectRoot,
|
|
2634
|
+
await executeHarnessCommand(context.projectRoot, args);
|
|
2365
2635
|
} catch (error) {
|
|
2366
2636
|
throw new CliError2(error instanceof Error ? error.message : String(error), 2);
|
|
2367
2637
|
}
|
|
2368
2638
|
return { ok: true, group: "harness", command: args[0] ?? "harness" };
|
|
2369
2639
|
}
|
|
2370
2640
|
|
|
2371
|
-
// packages/cli/src/commands
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
}
|
|
2408
|
-
if (value === "verify") {
|
|
2409
|
-
return "verify";
|
|
2410
|
-
}
|
|
2411
|
-
if (value === "pipeline") {
|
|
2412
|
-
return "pipeline";
|
|
2413
|
-
}
|
|
2414
|
-
throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
|
|
2415
|
-
}
|
|
2416
|
-
function parseIsolationMode(value, allowOff) {
|
|
2417
|
-
if (!value) {
|
|
2418
|
-
return "worktree";
|
|
2419
|
-
}
|
|
2420
|
-
if (value === "worktree") {
|
|
2421
|
-
return value;
|
|
2422
|
-
}
|
|
2423
|
-
if (allowOff && value === "off") {
|
|
2424
|
-
return value;
|
|
2425
|
-
}
|
|
2426
|
-
throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
|
|
2427
|
-
}
|
|
2428
|
-
function parseInstallScope(value) {
|
|
2429
|
-
if (!value || value === "user") {
|
|
2430
|
-
return "user";
|
|
2431
|
-
}
|
|
2432
|
-
if (value === "system") {
|
|
2433
|
-
return "system";
|
|
2434
|
-
}
|
|
2435
|
-
throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
|
|
2436
|
-
}
|
|
2437
|
-
function resolveInstallDir(scope, explicitPath) {
|
|
2438
|
-
if (explicitPath) {
|
|
2439
|
-
return resolve7(explicitPath);
|
|
2440
|
-
}
|
|
2441
|
-
if (scope === "system") {
|
|
2442
|
-
return "/usr/local/bin";
|
|
2443
|
-
}
|
|
2444
|
-
return resolve7(homedir(), ".local/bin");
|
|
2445
|
-
}
|
|
2446
|
-
async function loadRigConfigOrNull(projectRoot) {
|
|
2447
|
-
try {
|
|
2448
|
-
const { loadConfig } = await import("@rig/core/load-config");
|
|
2449
|
-
return await loadConfig(projectRoot);
|
|
2450
|
-
} catch {
|
|
2451
|
-
return null;
|
|
2452
|
-
}
|
|
2453
|
-
}
|
|
2454
|
-
|
|
2455
|
-
// packages/cli/src/commands/plugin.ts
|
|
2456
|
-
async function executePlugin(context, args) {
|
|
2457
|
-
const [command = "list", ...rest] = args;
|
|
2458
|
-
switch (command) {
|
|
2459
|
-
case "list": {
|
|
2460
|
-
requireNoExtraArgs(rest, "bun run rig plugin list");
|
|
2461
|
-
const legacyPlugins = context.plugins.list();
|
|
2462
|
-
const declarative = [];
|
|
2463
|
-
const config = await loadRigConfigOrNull(context.projectRoot);
|
|
2464
|
-
if (config && Array.isArray(config.plugins)) {
|
|
2465
|
-
for (const plugin of config.plugins) {
|
|
2466
|
-
const c = plugin.contributes ?? {};
|
|
2467
|
-
declarative.push({
|
|
2468
|
-
name: plugin.name,
|
|
2469
|
-
version: plugin.version,
|
|
2470
|
-
validators: (c.validators ?? []).map((v) => v.id),
|
|
2471
|
-
hooks: (c.hooks ?? []).map((h) => h.id),
|
|
2472
|
-
agentRoles: (c.agentRoles ?? []).map((r) => r.id),
|
|
2473
|
-
repoSources: (c.repoSources ?? []).map((r) => r.id),
|
|
2474
|
-
taskSources: (c.taskSources ?? []).map((s) => s.id),
|
|
2475
|
-
skills: (c.skills ?? []).map((s) => s.id),
|
|
2476
|
-
taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
|
|
2477
|
-
cliCommands: (c.cliCommands ?? []).map((c2) => c2.id)
|
|
2478
|
-
});
|
|
2479
|
-
}
|
|
2480
|
-
}
|
|
2481
|
-
if (context.outputMode === "text") {
|
|
2482
|
-
if (legacyPlugins.length === 0 && declarative.length === 0) {
|
|
2483
|
-
console.log("No plugins loaded.");
|
|
2484
|
-
}
|
|
2485
|
-
if (declarative.length > 0) {
|
|
2486
|
-
console.log("Declarative plugins (rig.config.ts):");
|
|
2487
|
-
for (const p of declarative) {
|
|
2488
|
-
console.log(` ${p.name}@${p.version}`);
|
|
2489
|
-
const lines = [];
|
|
2490
|
-
if (p.validators.length)
|
|
2491
|
-
lines.push(` validators: ${p.validators.join(", ")}`);
|
|
2492
|
-
if (p.hooks.length)
|
|
2493
|
-
lines.push(` hooks: ${p.hooks.join(", ")}`);
|
|
2494
|
-
if (p.agentRoles.length)
|
|
2495
|
-
lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
|
|
2496
|
-
if (p.repoSources.length)
|
|
2497
|
-
lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
|
|
2498
|
-
if (p.taskSources.length)
|
|
2499
|
-
lines.push(` task-sources: ${p.taskSources.join(", ")}`);
|
|
2500
|
-
if (p.skills.length)
|
|
2501
|
-
lines.push(` skills: ${p.skills.join(", ")}`);
|
|
2502
|
-
if (p.taskFieldExtensions.length)
|
|
2503
|
-
lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
|
|
2504
|
-
if (p.cliCommands.length)
|
|
2505
|
-
lines.push(` cli-commands: ${p.cliCommands.join(", ")}`);
|
|
2506
|
-
for (const line of lines)
|
|
2507
|
-
console.log(line);
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2510
|
-
if (legacyPlugins.length > 0) {
|
|
2511
|
-
console.log("Legacy disk-scan plugins (rig/plugins/):");
|
|
2512
|
-
for (const plugin of legacyPlugins) {
|
|
2513
|
-
const validators = plugin.validators.length > 0 ? plugin.validators.join(", ") : "none";
|
|
2514
|
-
console.log(` ${plugin.name} (validators: ${validators})`);
|
|
2515
|
-
}
|
|
2516
|
-
}
|
|
2517
|
-
}
|
|
2518
|
-
return {
|
|
2519
|
-
ok: true,
|
|
2520
|
-
group: "plugin",
|
|
2521
|
-
command,
|
|
2522
|
-
details: { declarative, legacy: legacyPlugins }
|
|
2523
|
-
};
|
|
2524
|
-
}
|
|
2525
|
-
case "validate": {
|
|
2526
|
-
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
2527
|
-
requireNoExtraArgs(remaining, "bun run rig plugin validate --task <beads-id>");
|
|
2528
|
-
const taskId = requireTask(task, "bun run rig plugin validate --task <beads-id>");
|
|
2529
|
-
const results = await context.plugins.runValidators(taskId);
|
|
2530
|
-
const passed = results.filter((result) => result.passed).length;
|
|
2531
|
-
const failed = results.length - passed;
|
|
2532
|
-
if (context.outputMode === "text") {
|
|
2533
|
-
if (results.length === 0) {
|
|
2534
|
-
console.log("No plugin validators registered.");
|
|
2535
|
-
} else {
|
|
2536
|
-
for (const result of results) {
|
|
2537
|
-
const icon = result.passed ? "PASS" : "FAIL";
|
|
2538
|
-
console.log(`[${icon}] ${result.id}: ${result.summary}`);
|
|
2539
|
-
if (result.details && !result.passed) {
|
|
2540
|
-
console.log(result.details);
|
|
2541
|
-
}
|
|
2542
|
-
}
|
|
2543
|
-
}
|
|
2544
|
-
}
|
|
2545
|
-
if (failed > 0) {
|
|
2546
|
-
throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
|
|
2547
|
-
}
|
|
2548
|
-
return {
|
|
2549
|
-
ok: true,
|
|
2550
|
-
group: "plugin",
|
|
2551
|
-
command,
|
|
2552
|
-
details: {
|
|
2553
|
-
taskId,
|
|
2554
|
-
passed,
|
|
2555
|
-
failed,
|
|
2556
|
-
results
|
|
2557
|
-
}
|
|
2558
|
-
};
|
|
2559
|
-
}
|
|
2560
|
-
default:
|
|
2561
|
-
throw new CliError2(`Unknown plugin command: ${command}`);
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
|
|
2565
|
-
// packages/cli/src/commands/queue.ts
|
|
2566
|
-
import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
|
|
2567
|
-
|
|
2568
|
-
// packages/cli/src/commands/_preflight.ts
|
|
2569
|
-
import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
2570
|
-
|
|
2571
|
-
// packages/cli/src/commands/_connection-state.ts
|
|
2572
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2573
|
-
import { homedir as homedir2 } from "os";
|
|
2574
|
-
import { dirname, resolve as resolve8 } from "path";
|
|
2575
|
-
function resolveGlobalConnectionsPath(env = process.env) {
|
|
2576
|
-
const explicit = env.RIG_CONNECTIONS_FILE?.trim();
|
|
2577
|
-
if (explicit)
|
|
2578
|
-
return resolve8(explicit);
|
|
2579
|
-
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2580
|
-
if (stateDir)
|
|
2581
|
-
return resolve8(stateDir, "connections.json");
|
|
2582
|
-
return resolve8(homedir2(), ".rig", "connections.json");
|
|
2583
|
-
}
|
|
2584
|
-
function resolveRepoConnectionPath(projectRoot) {
|
|
2585
|
-
return resolve8(projectRoot, ".rig", "state", "connection.json");
|
|
2586
|
-
}
|
|
2587
|
-
function readJsonFile2(path) {
|
|
2588
|
-
if (!existsSync4(path))
|
|
2589
|
-
return null;
|
|
2590
|
-
try {
|
|
2591
|
-
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2592
|
-
} catch (error) {
|
|
2593
|
-
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
2641
|
+
// packages/cli/src/commands.ts
|
|
2642
|
+
init_plugin();
|
|
2643
|
+
|
|
2644
|
+
// packages/cli/src/commands/queue.ts
|
|
2645
|
+
init_runner();
|
|
2646
|
+
init__parsers();
|
|
2647
|
+
import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
|
|
2648
|
+
|
|
2649
|
+
// packages/cli/src/commands/_preflight.ts
|
|
2650
|
+
init_runner();
|
|
2651
|
+
import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
2652
|
+
|
|
2653
|
+
// packages/cli/src/commands/_connection-state.ts
|
|
2654
|
+
init_runner();
|
|
2655
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2656
|
+
import { homedir as homedir2 } from "os";
|
|
2657
|
+
import { dirname, resolve as resolve8 } from "path";
|
|
2658
|
+
function resolveGlobalConnectionsPath(env = process.env) {
|
|
2659
|
+
const explicit = env.RIG_CONNECTIONS_FILE?.trim();
|
|
2660
|
+
if (explicit)
|
|
2661
|
+
return resolve8(explicit);
|
|
2662
|
+
const stateDir = env.RIG_GLOBAL_STATE_DIR?.trim();
|
|
2663
|
+
if (stateDir)
|
|
2664
|
+
return resolve8(stateDir, "connections.json");
|
|
2665
|
+
return resolve8(homedir2(), ".rig", "connections.json");
|
|
2666
|
+
}
|
|
2667
|
+
function resolveRepoConnectionPath(projectRoot) {
|
|
2668
|
+
return resolve8(projectRoot, ".rig", "state", "connection.json");
|
|
2669
|
+
}
|
|
2670
|
+
function readJsonFile2(path) {
|
|
2671
|
+
if (!existsSync4(path))
|
|
2672
|
+
return null;
|
|
2673
|
+
try {
|
|
2674
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
2675
|
+
} catch (error) {
|
|
2676
|
+
throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
|
|
2594
2677
|
}
|
|
2595
2678
|
}
|
|
2596
2679
|
function writeJsonFile2(path, value) {
|
|
@@ -2665,12 +2748,13 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
2665
2748
|
const global = readGlobalConnections(options);
|
|
2666
2749
|
const connection = global.connections[repo.selected];
|
|
2667
2750
|
if (!connection) {
|
|
2668
|
-
throw new CliError2(`Selected Rig
|
|
2751
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
2669
2752
|
}
|
|
2670
2753
|
return { alias: repo.selected, connection };
|
|
2671
2754
|
}
|
|
2672
2755
|
|
|
2673
2756
|
// packages/cli/src/commands/_server-client.ts
|
|
2757
|
+
init_runner();
|
|
2674
2758
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
2675
2759
|
import { resolve as resolve9 } from "path";
|
|
2676
2760
|
import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
|
|
@@ -3157,7 +3241,7 @@ async function runFastTaskRunPreflight(context, options = {}) {
|
|
|
3157
3241
|
}
|
|
3158
3242
|
}
|
|
3159
3243
|
const repo = readRepoConnection(context.projectRoot);
|
|
3160
|
-
checks.push(repo ? preflightCheck("project-link", "project linked to Rig
|
|
3244
|
+
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>`."));
|
|
3161
3245
|
try {
|
|
3162
3246
|
const auth = await request("/api/github/auth/status");
|
|
3163
3247
|
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>`."));
|
|
@@ -3275,7 +3359,7 @@ async function executeQueue(context, args) {
|
|
|
3275
3359
|
pending = failFastResult.rest;
|
|
3276
3360
|
const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
|
|
3277
3361
|
pending = skipProjectSyncResult.rest;
|
|
3278
|
-
requireNoExtraArgs(pending, "
|
|
3362
|
+
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]");
|
|
3279
3363
|
const workers = parsePositiveInt(workersResult.value, "--workers", 2);
|
|
3280
3364
|
const maxTasks = parsePositiveInt(maxTasksResult.value, "--max-tasks", 10);
|
|
3281
3365
|
const action = parseAction(actionResult.value);
|
|
@@ -3319,6 +3403,7 @@ async function executeQueue(context, args) {
|
|
|
3319
3403
|
}
|
|
3320
3404
|
|
|
3321
3405
|
// packages/cli/src/commands/agent.ts
|
|
3406
|
+
init_runner();
|
|
3322
3407
|
import { resolve as resolve11 } from "path";
|
|
3323
3408
|
import {
|
|
3324
3409
|
agentId,
|
|
@@ -3426,6 +3511,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
|
|
|
3426
3511
|
}
|
|
3427
3512
|
|
|
3428
3513
|
// packages/cli/src/commands/agent.ts
|
|
3514
|
+
init__parsers();
|
|
3429
3515
|
function splitAtDoubleDash(args) {
|
|
3430
3516
|
const separatorIndex = args.indexOf("--");
|
|
3431
3517
|
if (separatorIndex === -1) {
|
|
@@ -3453,7 +3539,7 @@ async function executeAgent(context, args) {
|
|
|
3453
3539
|
const [command = "list", ...rest] = args;
|
|
3454
3540
|
switch (command) {
|
|
3455
3541
|
case "list": {
|
|
3456
|
-
requireNoExtraArgs(rest, "
|
|
3542
|
+
requireNoExtraArgs(rest, "rig agent list");
|
|
3457
3543
|
const runtimes = await listAgentRuntimes(context.projectRoot);
|
|
3458
3544
|
if (context.outputMode === "text") {
|
|
3459
3545
|
if (runtimes.length === 0) {
|
|
@@ -3474,12 +3560,12 @@ async function executeAgent(context, args) {
|
|
|
3474
3560
|
pending = modeResult.rest;
|
|
3475
3561
|
const taskResult = takeOption(pending, "--task");
|
|
3476
3562
|
pending = taskResult.rest;
|
|
3477
|
-
requireNoExtraArgs(pending, "
|
|
3563
|
+
requireNoExtraArgs(pending, "rig agent prepare --task <id> [--id <id>] [--mode worktree]");
|
|
3478
3564
|
const mode = parseIsolationMode(modeResult.value, false);
|
|
3479
3565
|
const id = idResult.value || agentId("agent");
|
|
3480
3566
|
const taskId = taskResult.value?.trim();
|
|
3481
3567
|
if (!taskId) {
|
|
3482
|
-
throw new CliError2("Usage:
|
|
3568
|
+
throw new CliError2("Usage: rig agent prepare --task <id> [--id <id>] [--mode worktree]");
|
|
3483
3569
|
}
|
|
3484
3570
|
const runtime = await withMutedConsole(context.outputMode === "json", () => ensureAgentRuntime({
|
|
3485
3571
|
projectRoot: context.projectRoot,
|
|
@@ -3497,7 +3583,7 @@ async function executeAgent(context, args) {
|
|
|
3497
3583
|
case "run": {
|
|
3498
3584
|
const { options, commandParts } = splitAtDoubleDash(rest);
|
|
3499
3585
|
if (commandParts.length === 0) {
|
|
3500
|
-
throw new CliError2("Usage:
|
|
3586
|
+
throw new CliError2("Usage: rig agent run [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3501
3587
|
}
|
|
3502
3588
|
let pending = options;
|
|
3503
3589
|
const idResult = takeOption(pending, "--id");
|
|
@@ -3508,12 +3594,12 @@ async function executeAgent(context, args) {
|
|
|
3508
3594
|
pending = taskResult.rest;
|
|
3509
3595
|
const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
|
|
3510
3596
|
pending = skipProjectSyncResult.rest;
|
|
3511
|
-
requireNoExtraArgs(pending, "
|
|
3597
|
+
requireNoExtraArgs(pending, "rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3512
3598
|
const mode = parseIsolationMode(modeResult.value, false);
|
|
3513
3599
|
const id = idResult.value || agentId("agent-run");
|
|
3514
3600
|
const taskId = taskResult.value?.trim();
|
|
3515
3601
|
if (!taskId) {
|
|
3516
|
-
throw new CliError2("Usage:
|
|
3602
|
+
throw new CliError2("Usage: rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
|
|
3517
3603
|
}
|
|
3518
3604
|
await runProjectMainSyncPreflight(context, { disabled: skipProjectSyncResult.value });
|
|
3519
3605
|
const createdAt = new Date().toISOString();
|
|
@@ -3627,7 +3713,7 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
|
|
|
3627
3713
|
pending = allResult.rest;
|
|
3628
3714
|
const idResult = takeOption(pending, "--id");
|
|
3629
3715
|
pending = idResult.rest;
|
|
3630
|
-
requireNoExtraArgs(pending, "
|
|
3716
|
+
requireNoExtraArgs(pending, "rig agent cleanup (--id <id> | --all)");
|
|
3631
3717
|
if (!allResult.value && !idResult.value) {
|
|
3632
3718
|
throw new CliError2("Provide --id <id> or --all.");
|
|
3633
3719
|
}
|
|
@@ -3659,6 +3745,8 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
|
|
|
3659
3745
|
}
|
|
3660
3746
|
|
|
3661
3747
|
// packages/cli/src/commands/dist.ts
|
|
3748
|
+
init_runner();
|
|
3749
|
+
init__parsers();
|
|
3662
3750
|
import {
|
|
3663
3751
|
chmodSync,
|
|
3664
3752
|
copyFileSync as copyFileSync2,
|
|
@@ -3763,7 +3851,7 @@ async function executeDist(context, args) {
|
|
|
3763
3851
|
switch (command) {
|
|
3764
3852
|
case "build": {
|
|
3765
3853
|
const { value: outputDir, rest: pending } = takeOption(rest, "--output-dir");
|
|
3766
|
-
requireNoExtraArgs(pending, "
|
|
3854
|
+
requireNoExtraArgs(pending, "rig dist build [--output-dir <dir>]");
|
|
3767
3855
|
const commandParts = ["bun", "run", "packages/cli/bin/build-rig-binaries.ts"];
|
|
3768
3856
|
if (outputDir) {
|
|
3769
3857
|
commandParts.push("--output-dir", outputDir);
|
|
@@ -3777,7 +3865,7 @@ async function executeDist(context, args) {
|
|
|
3777
3865
|
pending = scopeResult.rest;
|
|
3778
3866
|
const pathResult = takeOption(pending, "--path");
|
|
3779
3867
|
pending = pathResult.rest;
|
|
3780
|
-
requireNoExtraArgs(pending, "
|
|
3868
|
+
requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
|
|
3781
3869
|
const scope = parseInstallScope(scopeResult.value);
|
|
3782
3870
|
const installDir = resolveInstallDir(scope, pathResult.value);
|
|
3783
3871
|
mkdirSync6(installDir, { recursive: true });
|
|
@@ -3820,7 +3908,7 @@ async function executeDist(context, args) {
|
|
|
3820
3908
|
};
|
|
3821
3909
|
}
|
|
3822
3910
|
case "doctor": {
|
|
3823
|
-
requireNoExtraArgs(rest, "
|
|
3911
|
+
requireNoExtraArgs(rest, "rig dist doctor");
|
|
3824
3912
|
const details = await runDistDoctor(context.projectRoot);
|
|
3825
3913
|
if (context.outputMode === "text") {
|
|
3826
3914
|
console.log(`bun: ${details.bun.available ? `ok (${details.bun.version})` : "missing"}`);
|
|
@@ -3831,7 +3919,7 @@ async function executeDist(context, args) {
|
|
|
3831
3919
|
return { ok: true, group: "dist", command, details };
|
|
3832
3920
|
}
|
|
3833
3921
|
case "rebuild-agent": {
|
|
3834
|
-
requireNoExtraArgs(rest, "
|
|
3922
|
+
requireNoExtraArgs(rest, "rig dist rebuild-agent");
|
|
3835
3923
|
const fp = await computeRuntimeImageFingerprint(context.projectRoot);
|
|
3836
3924
|
const currentId = computeRuntimeImageId(fp);
|
|
3837
3925
|
const imagesDir = resolve12(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
|
|
@@ -3976,6 +4064,7 @@ async function executeDist(context, args) {
|
|
|
3976
4064
|
}
|
|
3977
4065
|
|
|
3978
4066
|
// packages/cli/src/commands/inbox.ts
|
|
4067
|
+
init_runner();
|
|
3979
4068
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
3980
4069
|
import { resolve as resolve13 } from "path";
|
|
3981
4070
|
import {
|
|
@@ -3983,87 +4072,486 @@ import {
|
|
|
3983
4072
|
readJsonlFile as readJsonlFile3,
|
|
3984
4073
|
resolveAuthorityRunDir as resolveAuthorityRunDir2
|
|
3985
4074
|
} from "@rig/runtime/control-plane/authority-files";
|
|
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
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
return
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4075
|
+
|
|
4076
|
+
// packages/cli/src/commands/_cli-format.ts
|
|
4077
|
+
import { log as log3, note as note3 } from "@clack/prompts";
|
|
4078
|
+
import pc3 from "picocolors";
|
|
4079
|
+
function stringField(record, key, fallback = "") {
|
|
4080
|
+
const value = record[key];
|
|
4081
|
+
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
4082
|
+
}
|
|
4083
|
+
function numberField(record, key) {
|
|
4084
|
+
const value = record[key];
|
|
4085
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4086
|
+
}
|
|
4087
|
+
function arrayField(record, key) {
|
|
4088
|
+
const value = record[key];
|
|
4089
|
+
return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
|
|
4090
|
+
}
|
|
4091
|
+
function rawObject(record) {
|
|
4092
|
+
const raw = record.raw;
|
|
4093
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
4094
|
+
}
|
|
4095
|
+
function truncate(value, width) {
|
|
4096
|
+
if (value.length <= width)
|
|
4097
|
+
return value;
|
|
4098
|
+
if (width <= 1)
|
|
4099
|
+
return "\u2026";
|
|
4100
|
+
return `${value.slice(0, width - 1)}\u2026`;
|
|
4101
|
+
}
|
|
4102
|
+
function pad(value, width) {
|
|
4103
|
+
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
4104
|
+
}
|
|
4105
|
+
function statusColor(status) {
|
|
4106
|
+
const normalized = status.toLowerCase();
|
|
4107
|
+
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
|
|
4108
|
+
return pc3.green;
|
|
4109
|
+
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
4110
|
+
return pc3.red;
|
|
4111
|
+
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
4112
|
+
return pc3.cyan;
|
|
4113
|
+
if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
|
|
4114
|
+
return pc3.yellow;
|
|
4115
|
+
return pc3.dim;
|
|
4116
|
+
}
|
|
4117
|
+
function compactDate(value) {
|
|
4118
|
+
if (!value.trim())
|
|
4119
|
+
return "";
|
|
4120
|
+
const parsed = Date.parse(value);
|
|
4121
|
+
if (!Number.isFinite(parsed))
|
|
4122
|
+
return value;
|
|
4123
|
+
return new Date(parsed).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z");
|
|
4124
|
+
}
|
|
4125
|
+
function compactValue(value) {
|
|
4126
|
+
if (value === null || value === undefined)
|
|
4127
|
+
return "";
|
|
4128
|
+
if (typeof value === "string")
|
|
4129
|
+
return value;
|
|
4130
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
4131
|
+
return String(value);
|
|
4132
|
+
if (Array.isArray(value))
|
|
4133
|
+
return value.map(compactValue).filter(Boolean).join(", ");
|
|
4134
|
+
return JSON.stringify(value);
|
|
4135
|
+
}
|
|
4136
|
+
function firstString(record, keys, fallback = "") {
|
|
4137
|
+
for (const key of keys) {
|
|
4138
|
+
const value = stringField(record, key);
|
|
4139
|
+
if (value)
|
|
4140
|
+
return value;
|
|
4141
|
+
}
|
|
4142
|
+
return fallback;
|
|
4143
|
+
}
|
|
4144
|
+
function runIdOf(run) {
|
|
4145
|
+
return firstString(run, ["runId", "id"], "(unknown-run)");
|
|
4146
|
+
}
|
|
4147
|
+
function taskIdOf(run) {
|
|
4148
|
+
return firstString(run, ["taskId", "task", "task_id"]);
|
|
4149
|
+
}
|
|
4150
|
+
function runTitleOf(run) {
|
|
4151
|
+
return firstString(run, ["title", "summary", "name"], taskIdOf(run) || "(untitled)");
|
|
4152
|
+
}
|
|
4153
|
+
function requestIdOf(entry) {
|
|
4154
|
+
return firstString(entry, ["requestId", "id", "approvalId", "inputId"], "(unknown-request)");
|
|
4155
|
+
}
|
|
4156
|
+
function shouldUseClackOutput() {
|
|
4157
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
4158
|
+
}
|
|
4159
|
+
function printFormattedOutput(message2, options = {}) {
|
|
4160
|
+
if (!shouldUseClackOutput()) {
|
|
4161
|
+
console.log(message2);
|
|
4162
|
+
return;
|
|
4163
|
+
}
|
|
4164
|
+
if (options.title)
|
|
4165
|
+
note3(message2, options.title);
|
|
4166
|
+
else
|
|
4167
|
+
log3.message(message2);
|
|
4168
|
+
}
|
|
4169
|
+
function formatStatusPill(status) {
|
|
4170
|
+
const label = status || "unknown";
|
|
4171
|
+
return statusColor(label)(`\u25CF ${label}`);
|
|
4172
|
+
}
|
|
4173
|
+
function formatSection(title, subtitle) {
|
|
4174
|
+
return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
4175
|
+
}
|
|
4176
|
+
function formatSuccessCard(title, rows = []) {
|
|
4177
|
+
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}`);
|
|
4178
|
+
return [formatSection(title), ...body].join(`
|
|
4179
|
+
`);
|
|
4180
|
+
}
|
|
4181
|
+
function formatNextSteps(steps) {
|
|
4182
|
+
if (steps.length === 0)
|
|
4183
|
+
return [];
|
|
4184
|
+
return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
|
|
4185
|
+
}
|
|
4186
|
+
function formatTaskList(tasks, options = {}) {
|
|
4187
|
+
if (options.raw)
|
|
4188
|
+
return tasks.map((task) => JSON.stringify(task)).join(`
|
|
4189
|
+
`);
|
|
4190
|
+
if (tasks.length === 0)
|
|
4191
|
+
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(`
|
|
4192
|
+
`);
|
|
4193
|
+
const rows = tasks.map((task) => {
|
|
4194
|
+
const raw = rawObject(task);
|
|
4195
|
+
const id = stringField(task, "id", "<unknown>");
|
|
4196
|
+
const status = stringField(task, "status", "unknown");
|
|
4197
|
+
const title = stringField(task, "title", "Untitled task");
|
|
4198
|
+
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
4199
|
+
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
4200
|
+
return { id, status, title, source, labels };
|
|
4201
|
+
});
|
|
4202
|
+
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
4203
|
+
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
4204
|
+
const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
4205
|
+
const body = rows.map((row) => {
|
|
4206
|
+
const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
4207
|
+
const source = row.source ? pc3.dim(` ${row.source}`) : "";
|
|
4208
|
+
return [
|
|
4209
|
+
pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
4210
|
+
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
4211
|
+
`${row.title}${labels}${source}`
|
|
4212
|
+
].join(" ");
|
|
4213
|
+
});
|
|
4214
|
+
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(`
|
|
4215
|
+
`);
|
|
4216
|
+
}
|
|
4217
|
+
function formatTaskCard(task, options = {}) {
|
|
4218
|
+
const raw = rawObject(task);
|
|
4219
|
+
const id = stringField(task, "id", stringField(raw, "id", "<unknown>"));
|
|
4220
|
+
const status = stringField(task, "status", stringField(raw, "status", "unknown"));
|
|
4221
|
+
const title = stringField(task, "title", stringField(raw, "title", "Untitled task"));
|
|
4222
|
+
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
4223
|
+
const url = stringField(task, "url", stringField(raw, "url", ""));
|
|
4224
|
+
const number = numberField(task, "number") ?? numberField(raw, "number");
|
|
4225
|
+
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
4226
|
+
const assignees = arrayField(task, "assignees").length > 0 ? arrayField(task, "assignees") : arrayField(raw, "assignees");
|
|
4227
|
+
const readiness = compactValue(task.readiness ?? raw.readiness);
|
|
4228
|
+
const validators = compactValue(task.validators ?? raw.validators ?? task.validation ?? raw.validation);
|
|
4229
|
+
const rows = [
|
|
4230
|
+
["task", pc3.bold(id)],
|
|
4231
|
+
["status", formatStatusPill(status)],
|
|
4232
|
+
["title", title],
|
|
4233
|
+
["source", source],
|
|
4234
|
+
["number", number],
|
|
4235
|
+
["labels", labels.length ? labels.map((label) => `#${label}`).join(" ") : ""],
|
|
4236
|
+
["assignees", assignees.join(", ")],
|
|
4237
|
+
["readiness", readiness],
|
|
4238
|
+
["validators", validators],
|
|
4239
|
+
["url", url]
|
|
4240
|
+
];
|
|
4241
|
+
return [
|
|
4242
|
+
formatSuccessCard(options.title ?? (options.selected ? "Selected task" : "Task"), rows),
|
|
4243
|
+
"",
|
|
4244
|
+
...formatNextSteps([`Start: \`rig task run ${id}\``, `Details: \`rig task show ${id} --raw\``])
|
|
4245
|
+
].join(`
|
|
4246
|
+
`);
|
|
4247
|
+
}
|
|
4248
|
+
function formatTaskDetails(task) {
|
|
4249
|
+
return formatTaskCard(task, { title: "Task details" });
|
|
4250
|
+
}
|
|
4251
|
+
function formatRunList(runs, options = {}) {
|
|
4252
|
+
if (runs.length === 0) {
|
|
4253
|
+
return [
|
|
4254
|
+
formatSection("Runs", "none recorded"),
|
|
4255
|
+
options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
|
|
4256
|
+
"",
|
|
4257
|
+
...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
|
|
4258
|
+
].join(`
|
|
4259
|
+
`);
|
|
4260
|
+
}
|
|
4261
|
+
const rows = runs.map((run) => {
|
|
4262
|
+
const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
|
|
4263
|
+
const status = stringField(run, "status", "unknown");
|
|
4264
|
+
const taskId = stringField(run, "taskId", "");
|
|
4265
|
+
const title = stringField(run, "title", taskId || "(untitled)");
|
|
4266
|
+
const runtime = stringField(run, "runtimeAdapter", "");
|
|
4267
|
+
return { runId, status, title, runtime };
|
|
4268
|
+
});
|
|
4269
|
+
const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
|
|
4270
|
+
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
4271
|
+
const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
4272
|
+
const body = rows.map((row) => [
|
|
4273
|
+
pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
|
|
4274
|
+
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
4275
|
+
`${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
|
|
4276
|
+
].join(" "));
|
|
4277
|
+
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(`
|
|
4278
|
+
`);
|
|
4279
|
+
}
|
|
4280
|
+
function formatSubmittedRun(input) {
|
|
4281
|
+
const rows = [["run", pc3.bold(input.runId)]];
|
|
4282
|
+
if (input.task) {
|
|
4283
|
+
const id = stringField(input.task, "id", "<unknown>");
|
|
4284
|
+
const status = stringField(input.task, "status", "unknown");
|
|
4285
|
+
const title = stringField(input.task, "title", "Untitled task");
|
|
4286
|
+
rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
4287
|
+
}
|
|
4288
|
+
const runtime = [input.runtimeAdapter || "pi", input.runtimeMode || "full-access", input.interactionMode || "default"].filter(Boolean).join(" \xB7 ");
|
|
4289
|
+
rows.push(["runtime", runtime]);
|
|
4290
|
+
return [
|
|
4291
|
+
formatSuccessCard("Run submitted", rows),
|
|
4292
|
+
"",
|
|
4293
|
+
...formatNextSteps([
|
|
4294
|
+
`Attach: \`rig run attach ${input.runId} --follow\``,
|
|
4295
|
+
`Inspect: \`rig run show ${input.runId}\``,
|
|
4296
|
+
input.detached ? "Submitted detached; attach when you are ready." : "Interactive mode opens the native bundled Pi frontend."
|
|
4297
|
+
])
|
|
4298
|
+
].join(`
|
|
4299
|
+
`);
|
|
4300
|
+
}
|
|
4301
|
+
function formatRunCard(run, options = {}) {
|
|
4302
|
+
const raw = rawObject(run);
|
|
4303
|
+
const merged = { ...raw, ...run };
|
|
4304
|
+
const runId = runIdOf(merged);
|
|
4305
|
+
const status = firstString(merged, ["status"], "unknown");
|
|
4306
|
+
const taskId = taskIdOf(merged);
|
|
4307
|
+
const title = runTitleOf(merged);
|
|
4308
|
+
const runtime = firstString(merged, ["runtimeAdapter", "runtime", "adapter"]);
|
|
4309
|
+
const mode = firstString(merged, ["runtimeMode", "mode"]);
|
|
4310
|
+
const interaction = firstString(merged, ["interactionMode"]);
|
|
4311
|
+
const created = compactDate(firstString(merged, ["createdAt"]));
|
|
4312
|
+
const started = compactDate(firstString(merged, ["startedAt"]));
|
|
4313
|
+
const updated = compactDate(firstString(merged, ["updatedAt"]));
|
|
4314
|
+
const completed = compactDate(firstString(merged, ["completedAt", "finishedAt"]));
|
|
4315
|
+
const worktree = firstString(merged, ["worktreePath", "cwd", "projectRoot"]);
|
|
4316
|
+
const piSession = merged.piSession && typeof merged.piSession === "object" && !Array.isArray(merged.piSession) ? firstString(merged.piSession, ["sessionId", "id"]) : "";
|
|
4317
|
+
const timeline = Array.isArray(merged.timeline) ? merged.timeline.length : null;
|
|
4318
|
+
const approvals = Array.isArray(merged.approvals) ? merged.approvals.length : null;
|
|
4319
|
+
const inputs = Array.isArray(merged.userInputs) ? merged.userInputs.length : null;
|
|
4320
|
+
const rows = [
|
|
4321
|
+
["run", pc3.bold(runId)],
|
|
4322
|
+
["status", formatStatusPill(status)],
|
|
4323
|
+
["task", taskId],
|
|
4324
|
+
["title", title],
|
|
4325
|
+
["runtime", [runtime, mode, interaction].filter(Boolean).join(" \xB7 ")],
|
|
4326
|
+
["created", created],
|
|
4327
|
+
["started", started],
|
|
4328
|
+
["updated", updated],
|
|
4329
|
+
["completed", completed],
|
|
4330
|
+
["worktree", worktree],
|
|
4331
|
+
["pi", piSession],
|
|
4332
|
+
["timeline", timeline],
|
|
4333
|
+
["approvals", approvals],
|
|
4334
|
+
["inputs", inputs]
|
|
4335
|
+
];
|
|
4336
|
+
return [
|
|
4337
|
+
formatSuccessCard(options.title ?? "Run details", rows),
|
|
4338
|
+
"",
|
|
4339
|
+
...formatNextSteps([`Follow live: \`rig run attach ${runId} --follow\``, `Raw payload: \`rig run show ${runId} --raw\``])
|
|
4340
|
+
].join(`
|
|
4341
|
+
`);
|
|
4342
|
+
}
|
|
4343
|
+
function formatRunStatus(summary, options = {}) {
|
|
4344
|
+
const activeRuns = summary.activeRuns ?? [];
|
|
4345
|
+
const recentRuns = summary.recentRuns ?? [];
|
|
4346
|
+
const lines = [formatSection("Run status", options.source === "server" ? "selected server" : "local state")];
|
|
4347
|
+
lines.push("", pc3.bold(`Active runs (${activeRuns.length})`));
|
|
4348
|
+
if (activeRuns.length === 0) {
|
|
4349
|
+
lines.push(pc3.dim("No active runs."));
|
|
4350
|
+
} else {
|
|
4351
|
+
for (const run of activeRuns) {
|
|
4352
|
+
lines.push(formatRunSummaryLine(run));
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
lines.push("", pc3.bold(`Recent runs (${recentRuns.length})`));
|
|
4356
|
+
if (recentRuns.length === 0) {
|
|
4357
|
+
lines.push(pc3.dim("No recent terminal runs."));
|
|
4358
|
+
} else {
|
|
4359
|
+
for (const run of recentRuns.slice(0, 10)) {
|
|
4360
|
+
lines.push(formatRunSummaryLine(run));
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
lines.push("", ...formatNextSteps(["Start work: `rig task run --next`", "Attach: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"]));
|
|
4364
|
+
return lines.join(`
|
|
4365
|
+
`);
|
|
4366
|
+
}
|
|
4367
|
+
function formatRunSummaryLine(run) {
|
|
4368
|
+
const record = run;
|
|
4369
|
+
const runId = runIdOf(record);
|
|
4370
|
+
const status = firstString(record, ["status"], "unknown");
|
|
4371
|
+
const taskId = taskIdOf(record);
|
|
4372
|
+
const title = runTitleOf(record);
|
|
4373
|
+
const runtime = firstString(record, ["runtimeAdapter", "runtime", "adapter"]);
|
|
4374
|
+
const descriptor = [taskId, title].filter(Boolean).join(" \xB7 ");
|
|
4375
|
+
return `${pc3.dim("\u2502")} ${pc3.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? pc3.dim(` ${runtime}`) : ""}`;
|
|
4376
|
+
}
|
|
4377
|
+
function formatInboxList(kind, entries) {
|
|
4378
|
+
const title = kind === "approvals" ? "Approval inbox" : "Input inbox";
|
|
4379
|
+
if (entries.length === 0) {
|
|
4380
|
+
return [
|
|
4381
|
+
formatSection(title, "empty"),
|
|
4382
|
+
pc3.dim(kind === "approvals" ? "No pending approvals." : "No pending user-input requests."),
|
|
4383
|
+
"",
|
|
4384
|
+
...formatNextSteps(["Check runs: `rig run status`", "Start work: `rig task run --next`"])
|
|
4385
|
+
].join(`
|
|
4386
|
+
`);
|
|
4387
|
+
}
|
|
4388
|
+
const lines = [formatSection(title, `${entries.length} pending`)];
|
|
4389
|
+
for (const entry of entries) {
|
|
4390
|
+
const record = entry.record && typeof entry.record === "object" && !Array.isArray(entry.record) ? entry.record : entry;
|
|
4391
|
+
const runId = firstString(entry, ["runId"], firstString(record, ["runId"]));
|
|
4392
|
+
const taskId = firstString(entry, ["taskId"], firstString(record, ["taskId", "task"]));
|
|
4393
|
+
const requestId = requestIdOf(record);
|
|
4394
|
+
const status = firstString(record, ["status", "state"], "pending");
|
|
4395
|
+
const prompt = firstString(record, ["prompt", "message", "reason", "title", "summary"], kind === "approvals" ? "Approval requested" : "Input requested");
|
|
4396
|
+
lines.push(`${pc3.dim("\u2502")} ${pc3.bold(requestId)} ${formatStatusPill(status)} ${prompt}`);
|
|
4397
|
+
lines.push(`${pc3.dim("\u2502")} ${pc3.dim("run ")} ${runId || "(unknown-run)"}${taskId ? pc3.dim(` task ${taskId}`) : ""}`);
|
|
4398
|
+
}
|
|
4399
|
+
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`"]));
|
|
4400
|
+
return lines.join(`
|
|
4401
|
+
`);
|
|
4402
|
+
}
|
|
4403
|
+
function formatConnectionList(connections) {
|
|
4404
|
+
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
4405
|
+
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
4406
|
+
const lines = rows.map(([alias, connection]) => [
|
|
4407
|
+
pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
4408
|
+
formatStatusPill(connection.kind),
|
|
4409
|
+
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
4410
|
+
].join(" "));
|
|
4411
|
+
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(`
|
|
4412
|
+
`);
|
|
4413
|
+
}
|
|
4414
|
+
function formatConnectionStatus(selected, connections) {
|
|
4415
|
+
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
4416
|
+
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
4417
|
+
return [
|
|
4418
|
+
formatSection("Rig server", "selected for this repo"),
|
|
4419
|
+
`${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
|
|
4420
|
+
`${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
4421
|
+
`${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
|
|
4422
|
+
"",
|
|
4423
|
+
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
4424
|
+
].join(`
|
|
4425
|
+
`);
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
// packages/cli/src/commands/inbox.ts
|
|
4429
|
+
function isRemoteConnectionSelected(projectRoot) {
|
|
4430
|
+
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
4431
|
+
}
|
|
4432
|
+
function runMatches(entry, filters) {
|
|
4433
|
+
const runId = typeof entry.runId === "string" ? entry.runId : typeof entry.id === "string" ? entry.id : "";
|
|
4434
|
+
const taskId = typeof entry.taskId === "string" ? entry.taskId : "";
|
|
4435
|
+
return (!filters.run || runId === filters.run) && (!filters.task || taskId === filters.task);
|
|
4436
|
+
}
|
|
4437
|
+
function normalizeRemoteRunDetails(payload) {
|
|
4438
|
+
const run = payload.run;
|
|
4439
|
+
if (run && typeof run === "object" && !Array.isArray(run)) {
|
|
4440
|
+
return {
|
|
4441
|
+
...run,
|
|
4442
|
+
...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
|
|
4443
|
+
...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
|
|
4444
|
+
...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
|
|
4445
|
+
};
|
|
4446
|
+
}
|
|
4447
|
+
return payload;
|
|
4448
|
+
}
|
|
4449
|
+
function remoteRecordsFromRun(run, kind) {
|
|
4450
|
+
const key = kind === "approvals" ? "approvals" : "userInputs";
|
|
4451
|
+
const direct = run[key];
|
|
4452
|
+
if (!Array.isArray(direct))
|
|
4453
|
+
return [];
|
|
4454
|
+
const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
|
|
4455
|
+
const taskId = typeof run.taskId === "string" ? run.taskId : "";
|
|
4456
|
+
return direct.filter((record) => Boolean(record && typeof record === "object" && !Array.isArray(record))).map((record) => ({ runId, taskId, record }));
|
|
4457
|
+
}
|
|
4458
|
+
async function listRemoteInboxRecords(context, kind, filters) {
|
|
4459
|
+
const runs = (await listRunsViaServer(context, { limit: 100 })).filter((entry) => runMatches(entry, filters));
|
|
4460
|
+
const records = [];
|
|
4461
|
+
for (const run of runs) {
|
|
4462
|
+
const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
|
|
4463
|
+
const detailed = runId ? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, runId).catch(() => run)) : run;
|
|
4464
|
+
records.push(...remoteRecordsFromRun(detailed, kind));
|
|
4465
|
+
}
|
|
4466
|
+
return records;
|
|
4467
|
+
}
|
|
4468
|
+
function listLocalInboxRecords(context, kind, filters) {
|
|
4469
|
+
const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
|
|
4470
|
+
const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
|
|
4471
|
+
return runs.flatMap((entry) => readJsonlFile3(resolve13(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
|
|
4472
|
+
runId: entry.runId,
|
|
4473
|
+
taskId: entry.taskId ?? undefined,
|
|
4474
|
+
record
|
|
4475
|
+
})));
|
|
4476
|
+
}
|
|
4477
|
+
async function listInboxRecords(context, kind, filters) {
|
|
4478
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4479
|
+
return listRemoteInboxRecords(context, kind, filters);
|
|
4480
|
+
}
|
|
4481
|
+
return listLocalInboxRecords(context, kind, filters);
|
|
4482
|
+
}
|
|
4483
|
+
async function executeInbox(context, args) {
|
|
4484
|
+
const [command = "approvals", ...rest] = args;
|
|
4485
|
+
switch (command) {
|
|
4486
|
+
case "approvals": {
|
|
4487
|
+
let pending = rest;
|
|
4488
|
+
const run = takeOption(pending, "--run");
|
|
4489
|
+
pending = run.rest;
|
|
4490
|
+
const task = takeOption(pending, "--task");
|
|
4491
|
+
pending = task.rest;
|
|
4492
|
+
requireNoExtraArgs(pending, "rig inbox approvals [--run <id>] [--task <id>]");
|
|
4493
|
+
const approvals = await listInboxRecords(context, "approvals", { run: run.value, task: task.value });
|
|
4494
|
+
if (context.outputMode === "text") {
|
|
4495
|
+
printFormattedOutput(formatInboxList("approvals", approvals));
|
|
4496
|
+
}
|
|
4497
|
+
return { ok: true, group: "inbox", command, details: { approvals } };
|
|
4498
|
+
}
|
|
4499
|
+
case "approve": {
|
|
4500
|
+
let pending = rest;
|
|
4501
|
+
const run = takeOption(pending, "--run");
|
|
4502
|
+
pending = run.rest;
|
|
4503
|
+
const request = takeOption(pending, "--request");
|
|
4504
|
+
pending = request.rest;
|
|
4505
|
+
const decision = takeOption(pending, "--decision");
|
|
4506
|
+
pending = decision.rest;
|
|
4507
|
+
const note4 = takeOption(pending, "--note");
|
|
4508
|
+
pending = note4.rest;
|
|
4509
|
+
requireNoExtraArgs(pending, "rig inbox approve --run <id> --request <id> --decision approve|reject [--note <text>]");
|
|
4510
|
+
if (!run.value || !request.value || !decision.value) {
|
|
4511
|
+
throw new CliError2("approve requires --run, --request, and --decision.");
|
|
4512
|
+
}
|
|
4513
|
+
if (decision.value !== "approve" && decision.value !== "reject") {
|
|
4514
|
+
throw new CliError2("decision must be approve or reject.");
|
|
4515
|
+
}
|
|
4516
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4517
|
+
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);
|
|
4518
|
+
}
|
|
4519
|
+
const approvalsPath = resolve13(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
|
|
4520
|
+
const approvals = readJsonlFile3(approvalsPath);
|
|
4521
|
+
const resolvedAt = new Date().toISOString();
|
|
4522
|
+
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);
|
|
4523
|
+
writeFileSync4(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
|
|
4524
|
+
`)}
|
|
4525
|
+
`, "utf8");
|
|
4526
|
+
return { ok: true, group: "inbox", command, details: { runId: run.value, requestId: request.value, decision: decision.value } };
|
|
4527
|
+
}
|
|
4528
|
+
case "inputs": {
|
|
4529
|
+
let pending = rest;
|
|
4530
|
+
const run = takeOption(pending, "--run");
|
|
4531
|
+
pending = run.rest;
|
|
4532
|
+
const task = takeOption(pending, "--task");
|
|
4533
|
+
pending = task.rest;
|
|
4534
|
+
requireNoExtraArgs(pending, "rig inbox inputs [--run <id>] [--task <id>]");
|
|
4535
|
+
const requests = await listInboxRecords(context, "inputs", { run: run.value, task: task.value });
|
|
4536
|
+
if (context.outputMode === "text") {
|
|
4537
|
+
printFormattedOutput(formatInboxList("inputs", requests));
|
|
4538
|
+
}
|
|
4539
|
+
return { ok: true, group: "inbox", command, details: { requests } };
|
|
4540
|
+
}
|
|
4541
|
+
case "respond": {
|
|
4542
|
+
let pending = rest;
|
|
4543
|
+
const run = takeOption(pending, "--run");
|
|
4544
|
+
pending = run.rest;
|
|
4545
|
+
const request = takeOption(pending, "--request");
|
|
4546
|
+
pending = request.rest;
|
|
4547
|
+
const answers = [];
|
|
4548
|
+
const remaining = [];
|
|
4549
|
+
for (let index = 0;index < pending.length; index += 1) {
|
|
4550
|
+
const current = pending[index];
|
|
4551
|
+
if (current === "--answer") {
|
|
4552
|
+
const next2 = pending[index + 1];
|
|
4553
|
+
if (!next2 || next2.startsWith("-")) {
|
|
4554
|
+
throw new CliError2("Missing value for --answer");
|
|
4067
4555
|
}
|
|
4068
4556
|
answers.push(next2);
|
|
4069
4557
|
index += 1;
|
|
@@ -4073,10 +4561,13 @@ async function executeInbox(context, args) {
|
|
|
4073
4561
|
remaining.push(current);
|
|
4074
4562
|
}
|
|
4075
4563
|
}
|
|
4076
|
-
requireNoExtraArgs(remaining, "
|
|
4564
|
+
requireNoExtraArgs(remaining, "rig inbox respond --run <id> --request <id> --answer key=value [--answer key=value]");
|
|
4077
4565
|
if (!run.value || !request.value || answers.length === 0) {
|
|
4078
4566
|
throw new CliError2("respond requires --run, --request, and at least one --answer.");
|
|
4079
4567
|
}
|
|
4568
|
+
if (isRemoteConnectionSelected(context.projectRoot)) {
|
|
4569
|
+
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);
|
|
4570
|
+
}
|
|
4080
4571
|
const parsedAnswers = Object.fromEntries(answers.map((entry) => {
|
|
4081
4572
|
const [key, ...restValue] = entry.split("=");
|
|
4082
4573
|
return [key, restValue.join("=")];
|
|
@@ -4096,6 +4587,7 @@ async function executeInbox(context, args) {
|
|
|
4096
4587
|
}
|
|
4097
4588
|
|
|
4098
4589
|
// packages/cli/src/commands/init.ts
|
|
4590
|
+
init_runner();
|
|
4099
4591
|
import { appendFileSync as appendFileSync2, existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
4100
4592
|
import { spawnSync } from "child_process";
|
|
4101
4593
|
import { resolve as resolve17 } from "path";
|
|
@@ -4371,9 +4863,11 @@ async function uploadSnapshotArchiveViaServer(context, input) {
|
|
|
4371
4863
|
}
|
|
4372
4864
|
|
|
4373
4865
|
// packages/cli/src/commands/_doctor-checks.ts
|
|
4866
|
+
init_runner();
|
|
4374
4867
|
import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
|
|
4375
4868
|
import { resolve as resolve16 } from "path";
|
|
4376
4869
|
import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
|
|
4870
|
+
init__parsers();
|
|
4377
4871
|
function check(id, label, status, detail, remediation) {
|
|
4378
4872
|
return {
|
|
4379
4873
|
id,
|
|
@@ -4500,7 +4994,7 @@ async function runRigDoctorChecks(options) {
|
|
|
4500
4994
|
const taskSourceKind = config?.taskSource?.kind;
|
|
4501
4995
|
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."));
|
|
4502
4996
|
const repo = readRepoConnection(projectRoot);
|
|
4503
|
-
checks.push(repo ? check("project-link", "repo selected Rig
|
|
4997
|
+
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>`."));
|
|
4504
4998
|
const selected = (() => {
|
|
4505
4999
|
try {
|
|
4506
5000
|
return resolveSelectedConnection(projectRoot);
|
|
@@ -4508,7 +5002,7 @@ async function runRigDoctorChecks(options) {
|
|
|
4508
5002
|
return null;
|
|
4509
5003
|
}
|
|
4510
5004
|
})();
|
|
4511
|
-
checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server
|
|
5005
|
+
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));
|
|
4512
5006
|
let server = null;
|
|
4513
5007
|
try {
|
|
4514
5008
|
server = await (options.resolveServer ?? ensureServerForCli)(projectRoot);
|
|
@@ -5307,171 +5801,17 @@ async function executeInit(context, args) {
|
|
|
5307
5801
|
if (parsed.rest.length > 0)
|
|
5308
5802
|
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5309
5803
|
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);
|
|
5310
|
-
return runControlPlaneInit(context, parsed.options);
|
|
5311
|
-
}
|
|
5312
|
-
if (parsed.rest.length > 0)
|
|
5313
|
-
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5314
|
-
Usage: rig init`, 1);
|
|
5315
|
-
return runInteractiveControlPlaneInit(context, await loadClackPrompts());
|
|
5316
|
-
}
|
|
5317
|
-
|
|
5318
|
-
// packages/cli/src/commands/connect.ts
|
|
5319
|
-
import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
|
|
5320
|
-
|
|
5321
|
-
// packages/cli/src/commands/_cli-format.ts
|
|
5322
|
-
import pc3 from "picocolors";
|
|
5323
|
-
function stringField(record, key, fallback = "") {
|
|
5324
|
-
const value = record[key];
|
|
5325
|
-
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
5326
|
-
}
|
|
5327
|
-
function arrayField(record, key) {
|
|
5328
|
-
const value = record[key];
|
|
5329
|
-
return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
|
|
5330
|
-
}
|
|
5331
|
-
function rawObject(record) {
|
|
5332
|
-
const raw = record.raw;
|
|
5333
|
-
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
5334
|
-
}
|
|
5335
|
-
function truncate(value, width) {
|
|
5336
|
-
if (value.length <= width)
|
|
5337
|
-
return value;
|
|
5338
|
-
if (width <= 1)
|
|
5339
|
-
return "\u2026";
|
|
5340
|
-
return `${value.slice(0, width - 1)}\u2026`;
|
|
5341
|
-
}
|
|
5342
|
-
function pad(value, width) {
|
|
5343
|
-
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
5344
|
-
}
|
|
5345
|
-
function statusColor(status) {
|
|
5346
|
-
const normalized = status.toLowerCase();
|
|
5347
|
-
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected"].includes(normalized))
|
|
5348
|
-
return pc3.green;
|
|
5349
|
-
if (["failed", "needs_attention", "needs-attention", "blocked", "error"].includes(normalized))
|
|
5350
|
-
return pc3.red;
|
|
5351
|
-
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
5352
|
-
return pc3.cyan;
|
|
5353
|
-
if (["ready", "open", "queued", "created", "preparing", "local"].includes(normalized))
|
|
5354
|
-
return pc3.yellow;
|
|
5355
|
-
return pc3.dim;
|
|
5356
|
-
}
|
|
5357
|
-
function formatStatusPill(status) {
|
|
5358
|
-
const label = status || "unknown";
|
|
5359
|
-
return statusColor(label)(`\u25CF ${label}`);
|
|
5360
|
-
}
|
|
5361
|
-
function formatSection(title, subtitle) {
|
|
5362
|
-
return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
5363
|
-
}
|
|
5364
|
-
function formatSuccessCard(title, rows = []) {
|
|
5365
|
-
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}`);
|
|
5366
|
-
return [formatSection(title), ...body].join(`
|
|
5367
|
-
`);
|
|
5368
|
-
}
|
|
5369
|
-
function formatNextSteps(steps) {
|
|
5370
|
-
if (steps.length === 0)
|
|
5371
|
-
return [];
|
|
5372
|
-
return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
|
|
5373
|
-
}
|
|
5374
|
-
function formatTaskList(tasks, options = {}) {
|
|
5375
|
-
if (options.raw)
|
|
5376
|
-
return tasks.map((task) => JSON.stringify(task)).join(`
|
|
5377
|
-
`);
|
|
5378
|
-
if (tasks.length === 0)
|
|
5379
|
-
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(`
|
|
5380
|
-
`);
|
|
5381
|
-
const rows = tasks.map((task) => {
|
|
5382
|
-
const raw = rawObject(task);
|
|
5383
|
-
const id = stringField(task, "id", "<unknown>");
|
|
5384
|
-
const status = stringField(task, "status", "unknown");
|
|
5385
|
-
const title = stringField(task, "title", "Untitled task");
|
|
5386
|
-
const source = stringField(task, "source", stringField(raw, "source", ""));
|
|
5387
|
-
const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
|
|
5388
|
-
return { id, status, title, source, labels };
|
|
5389
|
-
});
|
|
5390
|
-
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
5391
|
-
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
5392
|
-
const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
5393
|
-
const body = rows.map((row) => {
|
|
5394
|
-
const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
5395
|
-
const source = row.source ? pc3.dim(` ${row.source}`) : "";
|
|
5396
|
-
return [
|
|
5397
|
-
pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
5398
|
-
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
5399
|
-
`${row.title}${labels}${source}`
|
|
5400
|
-
].join(" ");
|
|
5401
|
-
});
|
|
5402
|
-
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(`
|
|
5403
|
-
`);
|
|
5404
|
-
}
|
|
5405
|
-
function formatRunList(runs, options = {}) {
|
|
5406
|
-
if (runs.length === 0) {
|
|
5407
|
-
return [
|
|
5408
|
-
formatSection("Runs", "none recorded"),
|
|
5409
|
-
options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
|
|
5410
|
-
"",
|
|
5411
|
-
...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
|
|
5412
|
-
].join(`
|
|
5413
|
-
`);
|
|
5414
|
-
}
|
|
5415
|
-
const rows = runs.map((run) => {
|
|
5416
|
-
const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
|
|
5417
|
-
const status = stringField(run, "status", "unknown");
|
|
5418
|
-
const taskId = stringField(run, "taskId", "");
|
|
5419
|
-
const title = stringField(run, "title", taskId || "(untitled)");
|
|
5420
|
-
const runtime = stringField(run, "runtimeAdapter", "");
|
|
5421
|
-
return { runId, status, title, runtime };
|
|
5422
|
-
});
|
|
5423
|
-
const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
|
|
5424
|
-
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
5425
|
-
const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
|
|
5426
|
-
const body = rows.map((row) => [
|
|
5427
|
-
pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
|
|
5428
|
-
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
5429
|
-
`${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
|
|
5430
|
-
].join(" "));
|
|
5431
|
-
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(`
|
|
5432
|
-
`);
|
|
5433
|
-
}
|
|
5434
|
-
function formatSubmittedRun(input) {
|
|
5435
|
-
const rows = [["run", pc3.bold(input.runId)]];
|
|
5436
|
-
if (input.task) {
|
|
5437
|
-
const id = stringField(input.task, "id", "<unknown>");
|
|
5438
|
-
const status = stringField(input.task, "status", "unknown");
|
|
5439
|
-
const title = stringField(input.task, "title", "Untitled task");
|
|
5440
|
-
rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
5441
|
-
}
|
|
5442
|
-
return [
|
|
5443
|
-
formatSuccessCard("Run submitted", rows),
|
|
5444
|
-
"",
|
|
5445
|
-
...formatNextSteps([`Attach: \`rig run attach ${input.runId} --follow\``, `Inspect: \`rig run show --run ${input.runId}\``])
|
|
5446
|
-
].join(`
|
|
5447
|
-
`);
|
|
5448
|
-
}
|
|
5449
|
-
function formatConnectionList(connections) {
|
|
5450
|
-
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
5451
|
-
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
5452
|
-
const lines = rows.map(([alias, connection]) => [
|
|
5453
|
-
pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
5454
|
-
formatStatusPill(connection.kind),
|
|
5455
|
-
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
5456
|
-
].join(" "));
|
|
5457
|
-
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(`
|
|
5458
|
-
`);
|
|
5459
|
-
}
|
|
5460
|
-
function formatConnectionStatus(selected, connections) {
|
|
5461
|
-
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
5462
|
-
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
5463
|
-
return [
|
|
5464
|
-
formatSection("Rig server", "selected for this repo"),
|
|
5465
|
-
`${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
|
|
5466
|
-
`${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
5467
|
-
`${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
|
|
5468
|
-
"",
|
|
5469
|
-
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
5470
|
-
].join(`
|
|
5471
|
-
`);
|
|
5804
|
+
return runControlPlaneInit(context, parsed.options);
|
|
5805
|
+
}
|
|
5806
|
+
if (parsed.rest.length > 0)
|
|
5807
|
+
throw new CliError2(`Unexpected arguments: ${parsed.rest.join(" ")}
|
|
5808
|
+
Usage: rig init`, 1);
|
|
5809
|
+
return runInteractiveControlPlaneInit(context, await loadClackPrompts());
|
|
5472
5810
|
}
|
|
5473
5811
|
|
|
5474
5812
|
// packages/cli/src/commands/connect.ts
|
|
5813
|
+
init_runner();
|
|
5814
|
+
import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
|
|
5475
5815
|
function usageName(options) {
|
|
5476
5816
|
return `rig ${options.group}`;
|
|
5477
5817
|
}
|
|
@@ -5583,6 +5923,7 @@ async function executeConnect(context, args) {
|
|
|
5583
5923
|
}
|
|
5584
5924
|
|
|
5585
5925
|
// packages/cli/src/commands/github.ts
|
|
5926
|
+
init_runner();
|
|
5586
5927
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
5587
5928
|
function printPayload(context, payload, fallback) {
|
|
5588
5929
|
if (context.outputMode === "json")
|
|
@@ -5638,6 +5979,7 @@ async function executeGithub(context, args) {
|
|
|
5638
5979
|
}
|
|
5639
5980
|
|
|
5640
5981
|
// packages/cli/src/commands/doctor.ts
|
|
5982
|
+
init_runner();
|
|
5641
5983
|
async function executeDoctor(context, args) {
|
|
5642
5984
|
requireNoExtraArgs(args, "rig doctor");
|
|
5643
5985
|
const checks = await runRigDoctorChecks({ projectRoot: context.projectRoot });
|
|
@@ -5653,6 +5995,7 @@ async function executeDoctor(context, args) {
|
|
|
5653
5995
|
}
|
|
5654
5996
|
|
|
5655
5997
|
// packages/cli/src/commands/_run-driver-helpers.ts
|
|
5998
|
+
init_runner();
|
|
5656
5999
|
import { readFileSync as readFileSync7 } from "fs";
|
|
5657
6000
|
import { resolve as resolve18 } from "path";
|
|
5658
6001
|
import {
|
|
@@ -5880,6 +6223,7 @@ function renderSourceScopeValidation(task, validation) {
|
|
|
5880
6223
|
}
|
|
5881
6224
|
|
|
5882
6225
|
// packages/cli/src/commands/inspect.ts
|
|
6226
|
+
init_runner();
|
|
5883
6227
|
import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
|
|
5884
6228
|
import { resolve as resolve19 } from "path";
|
|
5885
6229
|
import {
|
|
@@ -5896,8 +6240,8 @@ async function executeInspect(context, args) {
|
|
|
5896
6240
|
switch (command) {
|
|
5897
6241
|
case "logs": {
|
|
5898
6242
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5899
|
-
requireNoExtraArgs(remaining, "
|
|
5900
|
-
const requiredTask = requireTask(task, "
|
|
6243
|
+
requireNoExtraArgs(remaining, "rig inspect logs --task <task-id>");
|
|
6244
|
+
const requiredTask = requireTask(task, "rig inspect logs --task <task-id>");
|
|
5901
6245
|
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];
|
|
5902
6246
|
if (!latestRun) {
|
|
5903
6247
|
throw new CliError2(`No runs found for ${requiredTask}.`);
|
|
@@ -5911,8 +6255,8 @@ async function executeInspect(context, args) {
|
|
|
5911
6255
|
}
|
|
5912
6256
|
case "artifacts": {
|
|
5913
6257
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5914
|
-
requireNoExtraArgs(remaining, "
|
|
5915
|
-
const requiredTask = requireTask(task, "
|
|
6258
|
+
requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
|
|
6259
|
+
const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
|
|
5916
6260
|
const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync11(path));
|
|
5917
6261
|
if (!artifactRoot) {
|
|
5918
6262
|
throw new CliError2(`No artifacts found for ${requiredTask}.`);
|
|
@@ -5926,8 +6270,8 @@ async function executeInspect(context, args) {
|
|
|
5926
6270
|
previewPending = task.rest;
|
|
5927
6271
|
const file = takeOption(previewPending, "--file");
|
|
5928
6272
|
previewPending = file.rest;
|
|
5929
|
-
requireNoExtraArgs(previewPending, "
|
|
5930
|
-
const requiredTask = requireTask(task.value, "
|
|
6273
|
+
requireNoExtraArgs(previewPending, "rig inspect artifact --task <task-id> --file <name>");
|
|
6274
|
+
const requiredTask = requireTask(task.value, "rig inspect artifact --task <task-id> --file <name>");
|
|
5931
6275
|
if (!file.value) {
|
|
5932
6276
|
throw new CliError2("Missing --file for rig inspect artifact.");
|
|
5933
6277
|
}
|
|
@@ -5956,7 +6300,7 @@ async function executeInspect(context, args) {
|
|
|
5956
6300
|
}
|
|
5957
6301
|
case "diff": {
|
|
5958
6302
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
5959
|
-
requireNoExtraArgs(remaining, "
|
|
6303
|
+
requireNoExtraArgs(remaining, "rig inspect diff [--task <task-id>]");
|
|
5960
6304
|
if (task) {
|
|
5961
6305
|
const files = changedFilesForTask(context.projectRoot, task, false);
|
|
5962
6306
|
for (const file of files) {
|
|
@@ -5968,7 +6312,7 @@ async function executeInspect(context, args) {
|
|
|
5968
6312
|
return { ok: true, group: "inspect", command, details: { task: task || null } };
|
|
5969
6313
|
}
|
|
5970
6314
|
case "failures": {
|
|
5971
|
-
requireNoExtraArgs(rest, "
|
|
6315
|
+
requireNoExtraArgs(rest, "rig inspect failures");
|
|
5972
6316
|
const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
|
|
5973
6317
|
if (!existsSync11(failed)) {
|
|
5974
6318
|
console.log("No failures recorded.");
|
|
@@ -5978,7 +6322,7 @@ async function executeInspect(context, args) {
|
|
|
5978
6322
|
return { ok: true, group: "inspect", command };
|
|
5979
6323
|
}
|
|
5980
6324
|
case "graph":
|
|
5981
|
-
requireNoExtraArgs(rest, "
|
|
6325
|
+
requireNoExtraArgs(rest, "rig inspect graph");
|
|
5982
6326
|
{
|
|
5983
6327
|
const monorepoRoot = resolveMonorepoRoot2(context.projectRoot);
|
|
5984
6328
|
const result = runCapture3(["br", "--no-db", "list", "--pretty"], monorepoRoot);
|
|
@@ -5989,7 +6333,7 @@ async function executeInspect(context, args) {
|
|
|
5989
6333
|
}
|
|
5990
6334
|
return { ok: true, group: "inspect", command };
|
|
5991
6335
|
case "audit": {
|
|
5992
|
-
requireNoExtraArgs(rest, "
|
|
6336
|
+
requireNoExtraArgs(rest, "rig inspect audit");
|
|
5993
6337
|
const auditPath = resolve19(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
|
|
5994
6338
|
if (!existsSync11(auditPath)) {
|
|
5995
6339
|
console.log("No audit log found.");
|
|
@@ -6007,6 +6351,8 @@ async function executeInspect(context, args) {
|
|
|
6007
6351
|
}
|
|
6008
6352
|
|
|
6009
6353
|
// packages/cli/src/commands/inspector.ts
|
|
6354
|
+
init_runner();
|
|
6355
|
+
init__parsers();
|
|
6010
6356
|
import { iterateServerSentEvents } from "@rig/client";
|
|
6011
6357
|
import { ensureLocalRigServerConnection as ensureLocalRigServerConnection2 } from "@rig/runtime/local-server";
|
|
6012
6358
|
function formatInspectorStreamLine(payload) {
|
|
@@ -6048,7 +6394,7 @@ async function executeInspector(context, args) {
|
|
|
6048
6394
|
pending = secondsResult.rest;
|
|
6049
6395
|
const pollMsResult = takeOption(pending, "--poll-ms");
|
|
6050
6396
|
pending = pollMsResult.rest;
|
|
6051
|
-
requireNoExtraArgs(pending, "
|
|
6397
|
+
requireNoExtraArgs(pending, "rig inspector stream [--once] [--seconds <n>] [--poll-ms <n>]");
|
|
6052
6398
|
const seconds = secondsResult.value ? parseRequiredPositiveInt(secondsResult.value, "--seconds") : null;
|
|
6053
6399
|
const pollMs = pollMsResult.value ? parseRequiredPositiveInt(pollMsResult.value, "--poll-ms") : null;
|
|
6054
6400
|
if (context.outputMode === "json" && !onceResult.value && !seconds) {
|
|
@@ -6142,7 +6488,7 @@ async function executeInspector(context, args) {
|
|
|
6142
6488
|
let pending = rest;
|
|
6143
6489
|
const scanIdResult = takeOption(pending, "--scan-id");
|
|
6144
6490
|
pending = scanIdResult.rest;
|
|
6145
|
-
requireNoExtraArgs(pending, "
|
|
6491
|
+
requireNoExtraArgs(pending, "rig inspector scan-upstream-drift [--scan-id <id>]");
|
|
6146
6492
|
const connection = await ensureLocalRigServerConnection2(context.projectRoot);
|
|
6147
6493
|
const response = await fetch(new URL("/api/inspector/tools/invoke", connection.baseUrl), {
|
|
6148
6494
|
method: "POST",
|
|
@@ -6197,6 +6543,8 @@ async function executeInspector(context, args) {
|
|
|
6197
6543
|
}
|
|
6198
6544
|
|
|
6199
6545
|
// packages/cli/src/commands/remote.ts
|
|
6546
|
+
init_runner();
|
|
6547
|
+
init__parsers();
|
|
6200
6548
|
import {
|
|
6201
6549
|
doctorManagedRemoteEndpoints,
|
|
6202
6550
|
listManagedRemoteEndpoints,
|
|
@@ -6253,7 +6601,7 @@ async function executeRemote(context, args) {
|
|
|
6253
6601
|
const [subcommand = "list", ...subRest] = rest;
|
|
6254
6602
|
switch (subcommand) {
|
|
6255
6603
|
case "list": {
|
|
6256
|
-
requireNoExtraArgs(subRest, "
|
|
6604
|
+
requireNoExtraArgs(subRest, "rig remote endpoint list");
|
|
6257
6605
|
const endpoints = listManagedRemoteEndpoints(undefined, context.projectRoot);
|
|
6258
6606
|
const redactedEndpoints = endpoints.map((endpoint2) => redactRemoteEndpoint(endpoint2));
|
|
6259
6607
|
if (context.outputMode === "text") {
|
|
@@ -6277,7 +6625,7 @@ async function executeRemote(context, args) {
|
|
|
6277
6625
|
pending2 = port.rest;
|
|
6278
6626
|
const token = takeOption(pending2, "--token");
|
|
6279
6627
|
pending2 = token.rest;
|
|
6280
|
-
requireNoExtraArgs(pending2, "
|
|
6628
|
+
requireNoExtraArgs(pending2, "rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>");
|
|
6281
6629
|
if (!alias.value || !host.value || !token.value || !port.value) {
|
|
6282
6630
|
throw new CliError2("remote endpoint add requires --alias, --host, --port, and --token.");
|
|
6283
6631
|
}
|
|
@@ -6304,7 +6652,7 @@ async function executeRemote(context, args) {
|
|
|
6304
6652
|
pending2 = port.rest;
|
|
6305
6653
|
const token = takeOption(pending2, "--token");
|
|
6306
6654
|
pending2 = token.rest;
|
|
6307
|
-
requireNoExtraArgs(pending2, "
|
|
6655
|
+
requireNoExtraArgs(pending2, "rig remote endpoint update --id <id> [--alias <a>] [--host <h>] [--port <n>] [--token <t>]");
|
|
6308
6656
|
if (!endpointId.value && !alias.value) {
|
|
6309
6657
|
throw new CliError2("remote endpoint update requires --id <id> or --alias <a>.");
|
|
6310
6658
|
}
|
|
@@ -6327,7 +6675,7 @@ async function executeRemote(context, args) {
|
|
|
6327
6675
|
let pending2 = subRest;
|
|
6328
6676
|
const alias = takeOption(pending2, "--alias");
|
|
6329
6677
|
pending2 = alias.rest;
|
|
6330
|
-
requireNoExtraArgs(pending2, "
|
|
6678
|
+
requireNoExtraArgs(pending2, "rig remote endpoint remove --alias <a>");
|
|
6331
6679
|
if (!alias.value) {
|
|
6332
6680
|
throw new CliError2("remote endpoint remove requires --alias.");
|
|
6333
6681
|
}
|
|
@@ -6344,7 +6692,7 @@ async function executeRemote(context, args) {
|
|
|
6344
6692
|
let pending2 = subRest;
|
|
6345
6693
|
const alias = takeOption(pending2, "--alias");
|
|
6346
6694
|
pending2 = alias.rest;
|
|
6347
|
-
requireNoExtraArgs(pending2, "
|
|
6695
|
+
requireNoExtraArgs(pending2, "rig remote endpoint test --alias <a>");
|
|
6348
6696
|
if (!alias.value) {
|
|
6349
6697
|
throw new CliError2("remote endpoint test requires --alias.");
|
|
6350
6698
|
}
|
|
@@ -6375,7 +6723,7 @@ async function executeRemote(context, args) {
|
|
|
6375
6723
|
}
|
|
6376
6724
|
}
|
|
6377
6725
|
case "migrate": {
|
|
6378
|
-
requireNoExtraArgs(subRest, "
|
|
6726
|
+
requireNoExtraArgs(subRest, "rig remote endpoint migrate");
|
|
6379
6727
|
const result = migrateManagedRemoteEndpoints(context.projectRoot);
|
|
6380
6728
|
if (context.outputMode === "text") {
|
|
6381
6729
|
console.log(`Imported ${result.imported} endpoint(s) from ${result.sourcePath}${result.skipped > 0 ? `, skipped ${result.skipped}` : ""}.`);
|
|
@@ -6383,7 +6731,7 @@ async function executeRemote(context, args) {
|
|
|
6383
6731
|
return { ok: true, group: "remote", command: "endpoint migrate", details: result };
|
|
6384
6732
|
}
|
|
6385
6733
|
case "doctor": {
|
|
6386
|
-
requireNoExtraArgs(subRest, "
|
|
6734
|
+
requireNoExtraArgs(subRest, "rig remote endpoint doctor");
|
|
6387
6735
|
const result = doctorManagedRemoteEndpoints(context.projectRoot);
|
|
6388
6736
|
if (context.outputMode === "text") {
|
|
6389
6737
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -6436,17 +6784,17 @@ async function executeRemote(context, args) {
|
|
|
6436
6784
|
try {
|
|
6437
6785
|
switch (command) {
|
|
6438
6786
|
case "test": {
|
|
6439
|
-
requireNoExtraArgs(pending, "
|
|
6787
|
+
requireNoExtraArgs(pending, "rig remote test [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6440
6788
|
const response = await withClient((client) => client.ping());
|
|
6441
6789
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6442
6790
|
}
|
|
6443
6791
|
case "status": {
|
|
6444
|
-
requireNoExtraArgs(pending, "
|
|
6792
|
+
requireNoExtraArgs(pending, "rig remote status [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6445
6793
|
const response = await withClient((client) => client.getState());
|
|
6446
6794
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6447
6795
|
}
|
|
6448
6796
|
case "tasks": {
|
|
6449
|
-
requireNoExtraArgs(pending, "
|
|
6797
|
+
requireNoExtraArgs(pending, "rig remote tasks [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6450
6798
|
const response = await withClient((client) => client.getTasks());
|
|
6451
6799
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
6452
6800
|
}
|
|
@@ -6456,7 +6804,7 @@ async function executeRemote(context, args) {
|
|
|
6456
6804
|
watchPending = secondsResult.rest;
|
|
6457
6805
|
const eventResult = takeOption(watchPending, "--event");
|
|
6458
6806
|
watchPending = eventResult.rest;
|
|
6459
|
-
requireNoExtraArgs(watchPending, "
|
|
6807
|
+
requireNoExtraArgs(watchPending, "rig remote watch [--seconds <n>] [--event <type>] [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
|
|
6460
6808
|
const seconds = parseOptionalPositiveInt(secondsResult.value, "--seconds");
|
|
6461
6809
|
const eventFilter = eventResult.value || undefined;
|
|
6462
6810
|
if (context.outputMode === "json" && !seconds) {
|
|
@@ -6525,7 +6873,7 @@ async function executeRemote(context, args) {
|
|
|
6525
6873
|
case "stop":
|
|
6526
6874
|
case "continue":
|
|
6527
6875
|
case "refresh": {
|
|
6528
|
-
requireNoExtraArgs(pending, `
|
|
6876
|
+
requireNoExtraArgs(pending, `rig remote ${command} [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6529
6877
|
const response = await withClient(async (client) => {
|
|
6530
6878
|
switch (command) {
|
|
6531
6879
|
case "pause":
|
|
@@ -6548,7 +6896,7 @@ async function executeRemote(context, args) {
|
|
|
6548
6896
|
let countPending = pending;
|
|
6549
6897
|
const countResult = takeOption(countPending, "--count");
|
|
6550
6898
|
countPending = countResult.rest;
|
|
6551
|
-
requireNoExtraArgs(countPending, `
|
|
6899
|
+
requireNoExtraArgs(countPending, `rig remote ${command} --count <n> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6552
6900
|
const count = parseRequiredPositiveInt(countResult.value, "--count");
|
|
6553
6901
|
const response = await withClient(async (client) => command === "add-iterations" ? await client.addIterations(count) : await client.removeIterations(count));
|
|
6554
6902
|
assertRemoteOperationSuccess(command, response);
|
|
@@ -6559,8 +6907,8 @@ async function executeRemote(context, args) {
|
|
|
6559
6907
|
let taskPending = pending;
|
|
6560
6908
|
const taskResult = takeOption(taskPending, "--task");
|
|
6561
6909
|
taskPending = taskResult.rest;
|
|
6562
|
-
requireNoExtraArgs(taskPending, `
|
|
6563
|
-
const taskId = requireTask(taskResult.value, `
|
|
6910
|
+
requireNoExtraArgs(taskPending, `rig remote ${command} --task <id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6911
|
+
const taskId = requireTask(taskResult.value, `rig remote ${command} --task <id>`);
|
|
6564
6912
|
const response = await withClient(async (client) => command === "prompt-preview" ? await client.getPromptPreview(taskId) : await client.getIterationOutput(taskId));
|
|
6565
6913
|
assertRemoteOperationSuccess(command, response);
|
|
6566
6914
|
return { ok: true, group: "remote", command, details: toDetails(response) };
|
|
@@ -6573,7 +6921,7 @@ async function executeRemote(context, args) {
|
|
|
6573
6921
|
orchestrationPending = maxIterationsResult.rest;
|
|
6574
6922
|
const directMergeResult = takeFlag(orchestrationPending, "--direct-merge");
|
|
6575
6923
|
orchestrationPending = directMergeResult.rest;
|
|
6576
|
-
requireNoExtraArgs(orchestrationPending, "
|
|
6924
|
+
requireNoExtraArgs(orchestrationPending, "rig remote orchestrate-start [--max-workers <n>] [--max-iterations <n>] [--direct-merge]");
|
|
6577
6925
|
const response = await withClient((client) => client.startOrchestration({
|
|
6578
6926
|
maxWorkers: parseOptionalPositiveInt(maxWorkersResult.value, "--max-workers"),
|
|
6579
6927
|
maxIterations: parseOptionalPositiveInt(maxIterationsResult.value, "--max-iterations"),
|
|
@@ -6594,8 +6942,8 @@ async function executeRemote(context, args) {
|
|
|
6594
6942
|
let orchestrationPending = pending;
|
|
6595
6943
|
const idResult = takeOption(orchestrationPending, "--id");
|
|
6596
6944
|
orchestrationPending = idResult.rest;
|
|
6597
|
-
requireNoExtraArgs(orchestrationPending, `
|
|
6598
|
-
const orchestrationId = requireTask(idResult.value, `
|
|
6945
|
+
requireNoExtraArgs(orchestrationPending, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6946
|
+
const orchestrationId = requireTask(idResult.value, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
|
|
6599
6947
|
const response = await withClient(async (client) => {
|
|
6600
6948
|
switch (command) {
|
|
6601
6949
|
case "orchestrate-pause":
|
|
@@ -6623,6 +6971,8 @@ async function executeRemote(context, args) {
|
|
|
6623
6971
|
}
|
|
6624
6972
|
|
|
6625
6973
|
// packages/cli/src/commands/run.ts
|
|
6974
|
+
init_runner();
|
|
6975
|
+
init__parsers();
|
|
6626
6976
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
6627
6977
|
import {
|
|
6628
6978
|
listAuthorityRuns as listAuthorityRuns3,
|
|
@@ -6640,7 +6990,7 @@ import {
|
|
|
6640
6990
|
startRun,
|
|
6641
6991
|
defaultStartRunOptions
|
|
6642
6992
|
} from "@rig/runtime/control-plane/native/run-ops";
|
|
6643
|
-
import { loadRuntimeContextFromEnv
|
|
6993
|
+
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
6644
6994
|
|
|
6645
6995
|
// packages/cli/src/commands/_operator-surface.ts
|
|
6646
6996
|
import { createInterface } from "readline";
|
|
@@ -6659,8 +7009,8 @@ var CANONICAL_STAGES = [
|
|
|
6659
7009
|
"Merge",
|
|
6660
7010
|
"Complete"
|
|
6661
7011
|
];
|
|
6662
|
-
function logDetail(
|
|
6663
|
-
return typeof
|
|
7012
|
+
function logDetail(log4) {
|
|
7013
|
+
return typeof log4.detail === "string" ? log4.detail.trim() : "";
|
|
6664
7014
|
}
|
|
6665
7015
|
function parseProviderProtocolLog(title, detail) {
|
|
6666
7016
|
if (title.trim().toLowerCase() !== "agent output")
|
|
@@ -6707,12 +7057,12 @@ function renderOperatorSnapshot(snapshot) {
|
|
|
6707
7057
|
const status = String(run.status ?? "unknown");
|
|
6708
7058
|
const logs = snapshot.logs ?? [];
|
|
6709
7059
|
const latestByStage = new Map;
|
|
6710
|
-
for (const
|
|
6711
|
-
const title = String(
|
|
6712
|
-
const stageName = String(
|
|
7060
|
+
for (const log4 of logs) {
|
|
7061
|
+
const title = String(log4.title ?? "").toLowerCase();
|
|
7062
|
+
const stageName = String(log4.stage ?? "").toLowerCase();
|
|
6713
7063
|
const stage = CANONICAL_STAGES.find((candidate) => candidate.toLowerCase() === title || candidate.toLowerCase() === stageName);
|
|
6714
7064
|
if (stage)
|
|
6715
|
-
latestByStage.set(stage,
|
|
7065
|
+
latestByStage.set(stage, log4);
|
|
6716
7066
|
}
|
|
6717
7067
|
const stageLines = CANONICAL_STAGES.flatMap((stage) => {
|
|
6718
7068
|
const match = latestByStage.get(stage);
|
|
@@ -7516,7 +7866,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
7516
7866
|
}
|
|
7517
7867
|
|
|
7518
7868
|
// packages/cli/src/commands/run.ts
|
|
7519
|
-
function
|
|
7869
|
+
function normalizeRemoteRunDetails2(payload) {
|
|
7520
7870
|
const run = payload.run;
|
|
7521
7871
|
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
7522
7872
|
return null;
|
|
@@ -7528,11 +7878,11 @@ function normalizeRemoteRunDetails(payload) {
|
|
|
7528
7878
|
};
|
|
7529
7879
|
}
|
|
7530
7880
|
var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
|
|
7531
|
-
function
|
|
7881
|
+
function isRemoteConnectionSelected2(projectRoot) {
|
|
7532
7882
|
return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
|
|
7533
7883
|
}
|
|
7534
7884
|
async function listRunsForSelectedConnection(context, options = {}) {
|
|
7535
|
-
if (
|
|
7885
|
+
if (isRemoteConnectionSelected2(context.projectRoot)) {
|
|
7536
7886
|
return { runs: await listRunsViaServer(context, options), source: "server" };
|
|
7537
7887
|
}
|
|
7538
7888
|
return { runs: listAuthorityRuns3(context.projectRoot), source: "local" };
|
|
@@ -7541,9 +7891,6 @@ function runStringField(run, key, fallback = "") {
|
|
|
7541
7891
|
const value = run[key];
|
|
7542
7892
|
return typeof value === "string" && value.trim() ? value : fallback;
|
|
7543
7893
|
}
|
|
7544
|
-
function runDisplayTitle(run) {
|
|
7545
|
-
return runStringField(run, "title", runStringField(run, "taskId", "(untitled)"));
|
|
7546
|
-
}
|
|
7547
7894
|
function buildServerRunStatus(runs) {
|
|
7548
7895
|
const activeRuns = runs.filter((run) => !REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
7549
7896
|
const recentRuns = runs.filter((run) => REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
@@ -7610,13 +7957,13 @@ async function promptForEpicSelection(projectRoot, command) {
|
|
|
7610
7957
|
}
|
|
7611
7958
|
async function executeRun(context, args) {
|
|
7612
7959
|
const [command = "status", ...rest] = args;
|
|
7613
|
-
const runtimeContext =
|
|
7960
|
+
const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
|
|
7614
7961
|
switch (command) {
|
|
7615
7962
|
case "list": {
|
|
7616
|
-
requireNoExtraArgs(rest, "
|
|
7963
|
+
requireNoExtraArgs(rest, "rig run list");
|
|
7617
7964
|
const { runs, source } = await listRunsForSelectedConnection(context, { limit: 100 });
|
|
7618
7965
|
if (context.outputMode === "text") {
|
|
7619
|
-
|
|
7966
|
+
printFormattedOutput(formatRunList(runs, { source }));
|
|
7620
7967
|
}
|
|
7621
7968
|
return { ok: true, group: "run", command, details: { runs, source } };
|
|
7622
7969
|
}
|
|
@@ -7626,7 +7973,7 @@ async function executeRun(context, args) {
|
|
|
7626
7973
|
pending = run.rest;
|
|
7627
7974
|
const purgeArtifacts = takeFlag(pending, "--purge-artifacts");
|
|
7628
7975
|
pending = purgeArtifacts.rest;
|
|
7629
|
-
requireNoExtraArgs(pending, "
|
|
7976
|
+
requireNoExtraArgs(pending, "rig run delete --run <id> [--purge-artifacts]");
|
|
7630
7977
|
if (!run.value) {
|
|
7631
7978
|
throw new CliError2("run delete requires --run <id>.");
|
|
7632
7979
|
}
|
|
@@ -7656,7 +8003,7 @@ async function executeRun(context, args) {
|
|
|
7656
8003
|
pending = keepRuntimes.rest;
|
|
7657
8004
|
const keepQueue = takeFlag(pending, "--keep-queue");
|
|
7658
8005
|
pending = keepQueue.rest;
|
|
7659
|
-
requireNoExtraArgs(pending, "
|
|
8006
|
+
requireNoExtraArgs(pending, "rig run cleanup --all [--keep-artifacts] [--keep-runtimes] [--keep-queue]");
|
|
7660
8007
|
if (!all.value) {
|
|
7661
8008
|
throw new CliError2("run cleanup currently requires --all.");
|
|
7662
8009
|
}
|
|
@@ -7675,20 +8022,25 @@ async function executeRun(context, args) {
|
|
|
7675
8022
|
}
|
|
7676
8023
|
case "show": {
|
|
7677
8024
|
let pending = rest;
|
|
8025
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
8026
|
+
pending = rawResult.rest;
|
|
7678
8027
|
const run = takeOption(pending, "--run");
|
|
7679
8028
|
pending = run.rest;
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
8029
|
+
const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
|
|
8030
|
+
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
8031
|
+
requireNoExtraArgs(extra, "rig run show <id>|--run <id> [--raw]");
|
|
8032
|
+
const runId = run.value ?? positionalRunId;
|
|
8033
|
+
if (!runId) {
|
|
8034
|
+
throw new CliError2("run show requires a run id.");
|
|
7683
8035
|
}
|
|
7684
|
-
const record = readAuthorityRun4(context.projectRoot,
|
|
8036
|
+
const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
|
|
7685
8037
|
if (!record) {
|
|
7686
|
-
throw new CliError2(`Run not found: ${
|
|
8038
|
+
throw new CliError2(`Run not found: ${runId}`, 2);
|
|
7687
8039
|
}
|
|
7688
8040
|
if (context.outputMode === "text") {
|
|
7689
|
-
|
|
8041
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(record, null, 2) : formatRunCard(record));
|
|
7690
8042
|
}
|
|
7691
|
-
return { ok: true, group: "run", command, details: record };
|
|
8043
|
+
return { ok: true, group: "run", command, details: { ...record, rawOutput: rawResult.value } };
|
|
7692
8044
|
}
|
|
7693
8045
|
case "timeline": {
|
|
7694
8046
|
let pending = rest;
|
|
@@ -7696,7 +8048,7 @@ async function executeRun(context, args) {
|
|
|
7696
8048
|
pending = run.rest;
|
|
7697
8049
|
const follow = takeFlag(pending, "--follow");
|
|
7698
8050
|
pending = follow.rest;
|
|
7699
|
-
requireNoExtraArgs(pending, "
|
|
8051
|
+
requireNoExtraArgs(pending, "rig run timeline --run <id> [--follow]");
|
|
7700
8052
|
if (!run.value) {
|
|
7701
8053
|
throw new CliError2("run timeline requires --run <id>.");
|
|
7702
8054
|
}
|
|
@@ -7733,7 +8085,7 @@ async function executeRun(context, args) {
|
|
|
7733
8085
|
pending = pollMs.rest;
|
|
7734
8086
|
const positionalRunId = pending.length > 0 ? pending[0] : undefined;
|
|
7735
8087
|
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
7736
|
-
requireNoExtraArgs(extra, "
|
|
8088
|
+
requireNoExtraArgs(extra, "rig run attach <run-id>|--run <run-id> [--message <text>] [--once|--follow] [--poll-ms <ms>]");
|
|
7737
8089
|
const runId = runOption.value ?? positionalRunId;
|
|
7738
8090
|
if (!runId) {
|
|
7739
8091
|
throw new CliError2("run attach requires a run id.", 2);
|
|
@@ -7753,28 +8105,18 @@ async function executeRun(context, args) {
|
|
|
7753
8105
|
return { ok: true, group: "run", command, details: { ...attached, steered: attached.steered || steered } };
|
|
7754
8106
|
}
|
|
7755
8107
|
case "status": {
|
|
7756
|
-
requireNoExtraArgs(rest, "
|
|
8108
|
+
requireNoExtraArgs(rest, "rig run status");
|
|
7757
8109
|
if (context.dryRun) {
|
|
7758
8110
|
if (context.outputMode === "text") {
|
|
7759
8111
|
console.log("[dry-run] rig run status");
|
|
7760
8112
|
}
|
|
7761
8113
|
return { ok: true, group: "run", command };
|
|
7762
8114
|
}
|
|
7763
|
-
const summary =
|
|
8115
|
+
const summary = isRemoteConnectionSelected2(context.projectRoot) ? buildServerRunStatus(await listRunsViaServer(context, { limit: 100 })) : runStatus(context.projectRoot, runtimeContext);
|
|
7764
8116
|
const activeRuns = Array.isArray(summary.activeRuns) ? summary.activeRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
7765
8117
|
const recentRuns = Array.isArray(summary.recentRuns) ? summary.recentRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
7766
8118
|
if (context.outputMode === "text") {
|
|
7767
|
-
|
|
7768
|
-
for (const run of activeRuns) {
|
|
7769
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
7770
|
-
}
|
|
7771
|
-
if (recentRuns.length > 0) {
|
|
7772
|
-
console.log("");
|
|
7773
|
-
console.log("Recent runs:");
|
|
7774
|
-
for (const run of recentRuns) {
|
|
7775
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
7776
|
-
}
|
|
7777
|
-
}
|
|
8119
|
+
printFormattedOutput(formatRunStatus({ activeRuns, recentRuns, runs: Array.isArray(summary.runs) ? summary.runs : [...activeRuns, ...recentRuns] }, { source: isRemoteConnectionSelected2(context.projectRoot) ? "server" : "local" }));
|
|
7778
8120
|
}
|
|
7779
8121
|
return { ok: true, group: "run", command, details: summary };
|
|
7780
8122
|
}
|
|
@@ -7798,7 +8140,7 @@ async function executeRun(context, args) {
|
|
|
7798
8140
|
pending = pollResult.rest;
|
|
7799
8141
|
const noServerResult = takeFlag(pending, "--no-server");
|
|
7800
8142
|
pending = noServerResult.rest;
|
|
7801
|
-
requireNoExtraArgs(pending, "
|
|
8143
|
+
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]");
|
|
7802
8144
|
if (promptEpicResult.value && noEpicPromptResult.value) {
|
|
7803
8145
|
throw new CliError2("Cannot use --prompt-epic and --no-epic-prompt together.");
|
|
7804
8146
|
}
|
|
@@ -7846,7 +8188,7 @@ async function executeRun(context, args) {
|
|
|
7846
8188
|
};
|
|
7847
8189
|
}
|
|
7848
8190
|
case "resume": {
|
|
7849
|
-
requireNoExtraArgs(rest, "
|
|
8191
|
+
requireNoExtraArgs(rest, "rig run resume");
|
|
7850
8192
|
if (context.dryRun) {
|
|
7851
8193
|
if (context.outputMode === "text") {
|
|
7852
8194
|
console.log("[dry-run] rig run resume");
|
|
@@ -7860,7 +8202,7 @@ async function executeRun(context, args) {
|
|
|
7860
8202
|
return { ok: true, group: "run", command, details: resumed };
|
|
7861
8203
|
}
|
|
7862
8204
|
case "restart": {
|
|
7863
|
-
requireNoExtraArgs(rest, "
|
|
8205
|
+
requireNoExtraArgs(rest, "rig run restart");
|
|
7864
8206
|
if (context.dryRun) {
|
|
7865
8207
|
if (context.outputMode === "text") {
|
|
7866
8208
|
console.log("[dry-run] rig run restart");
|
|
@@ -7877,7 +8219,7 @@ async function executeRun(context, args) {
|
|
|
7877
8219
|
const runOption = takeOption(rest, "--run");
|
|
7878
8220
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
7879
8221
|
const extra = positionalRunId ? runOption.rest.slice(1) : runOption.rest;
|
|
7880
|
-
requireNoExtraArgs(extra, "
|
|
8222
|
+
requireNoExtraArgs(extra, "rig run stop [<run-id>|--run <id>]");
|
|
7881
8223
|
const runId = runOption.value ?? positionalRunId;
|
|
7882
8224
|
if (context.dryRun) {
|
|
7883
8225
|
return {
|
|
@@ -7916,6 +8258,7 @@ async function executeRun(context, args) {
|
|
|
7916
8258
|
}
|
|
7917
8259
|
|
|
7918
8260
|
// packages/cli/src/commands/server.ts
|
|
8261
|
+
init_runner();
|
|
7919
8262
|
async function executeServer(context, args, options) {
|
|
7920
8263
|
const [command = "status", ...rest] = args;
|
|
7921
8264
|
if (["status", "list", "add", "use"].includes(command)) {
|
|
@@ -8017,6 +8360,7 @@ async function executeServer(context, args, options) {
|
|
|
8017
8360
|
}
|
|
8018
8361
|
|
|
8019
8362
|
// packages/cli/src/commands/task.ts
|
|
8363
|
+
init_runner();
|
|
8020
8364
|
import { readFileSync as readFileSync9 } from "fs";
|
|
8021
8365
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
8022
8366
|
import { resolve as resolve20 } from "path";
|
|
@@ -8042,50 +8386,426 @@ import { cancel as cancel3, isCancel as isCancel3, select as select3 } from "@cl
|
|
|
8042
8386
|
function taskId2(task) {
|
|
8043
8387
|
return typeof task.id === "string" && task.id.trim() ? task.id : "<unknown>";
|
|
8044
8388
|
}
|
|
8045
|
-
async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
8046
|
-
if (tasks.length === 0)
|
|
8047
|
-
return null;
|
|
8048
|
-
if (tasks.length === 1)
|
|
8049
|
-
return tasks[0];
|
|
8050
|
-
const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8051
|
-
if (!isTty) {
|
|
8052
|
-
throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
|
|
8389
|
+
async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
8390
|
+
if (tasks.length === 0)
|
|
8391
|
+
return null;
|
|
8392
|
+
if (tasks.length === 1)
|
|
8393
|
+
return tasks[0];
|
|
8394
|
+
const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
8395
|
+
if (!isTty) {
|
|
8396
|
+
throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
|
|
8397
|
+
}
|
|
8398
|
+
if (io.prompt || io.renderer) {
|
|
8399
|
+
const prompt = io.prompt ?? promptForTaskSelection;
|
|
8400
|
+
const renderer = io.renderer ?? { writeLine: (line) => process.stdout.write(`${line}
|
|
8401
|
+
`) };
|
|
8402
|
+
renderer.writeLine("Select Rig task:");
|
|
8403
|
+
for (const row of renderTaskPickerRows(tasks))
|
|
8404
|
+
renderer.writeLine(` ${row}`);
|
|
8405
|
+
const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
|
|
8406
|
+
if (!answer2)
|
|
8407
|
+
return null;
|
|
8408
|
+
if (/^\d+$/.test(answer2)) {
|
|
8409
|
+
const index2 = Number.parseInt(answer2, 10) - 1;
|
|
8410
|
+
return tasks[index2] ?? null;
|
|
8411
|
+
}
|
|
8412
|
+
return tasks.find((task) => taskId2(task) === answer2) ?? null;
|
|
8413
|
+
}
|
|
8414
|
+
const options = tasks.map((task, index2) => ({
|
|
8415
|
+
value: `${index2}`,
|
|
8416
|
+
label: `${taskId2(task)} \xB7 ${typeof task.title === "string" && task.title.trim() ? task.title.trim() : "Untitled task"}`,
|
|
8417
|
+
hint: typeof task.status === "string" && task.status.trim() ? task.status.trim() : undefined
|
|
8418
|
+
}));
|
|
8419
|
+
const answer = await select3({
|
|
8420
|
+
message: "Select Rig task",
|
|
8421
|
+
options
|
|
8422
|
+
});
|
|
8423
|
+
if (isCancel3(answer)) {
|
|
8424
|
+
cancel3("No task selected.");
|
|
8425
|
+
return null;
|
|
8426
|
+
}
|
|
8427
|
+
const index = Number.parseInt(String(answer), 10);
|
|
8428
|
+
return Number.isFinite(index) ? tasks[index] ?? null : null;
|
|
8429
|
+
}
|
|
8430
|
+
|
|
8431
|
+
// packages/cli/src/commands/_help-catalog.ts
|
|
8432
|
+
import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
|
|
8433
|
+
import pc4 from "picocolors";
|
|
8434
|
+
var TOP_LEVEL_SECTIONS = [
|
|
8435
|
+
{
|
|
8436
|
+
title: "Server",
|
|
8437
|
+
subtitle: "choose the local or remote Rig server that owns this repo",
|
|
8438
|
+
commands: [
|
|
8439
|
+
{ command: "rig server status", description: "Show the selected local/remote server for this repo." },
|
|
8440
|
+
{ command: "rig server use local", description: "Switch this repo back to the local Rig server." },
|
|
8441
|
+
{ command: "rig server add <alias> <url>", description: "Save a remote Rig server alias." },
|
|
8442
|
+
{ command: "rig server use <alias>", description: "Switch this repo to a saved remote server." },
|
|
8443
|
+
{ command: "rig server list", description: "Show saved server aliases, including local." }
|
|
8444
|
+
]
|
|
8445
|
+
},
|
|
8446
|
+
{
|
|
8447
|
+
title: "Tasks",
|
|
8448
|
+
subtitle: "find work, inspect it, and submit Pi-backed workers",
|
|
8449
|
+
commands: [
|
|
8450
|
+
{ command: "rig task list", description: "List tasks from the selected task source/server." },
|
|
8451
|
+
{ command: "rig task next", description: "Show the next matching task as a selected-task card." },
|
|
8452
|
+
{ command: "rig task show <id>", description: "Show a human task summary; add --raw or --json for the full payload." },
|
|
8453
|
+
{ command: "rig task run <id|--next> [--detach]", description: "Submit a task run; interactive mode follows with bundled Pi." }
|
|
8454
|
+
]
|
|
8455
|
+
},
|
|
8456
|
+
{
|
|
8457
|
+
title: "Runs",
|
|
8458
|
+
subtitle: "observe, attach to, and stop live or recent runs",
|
|
8459
|
+
commands: [
|
|
8460
|
+
{ command: "rig run list", description: "List recent runs from the selected server or local state." },
|
|
8461
|
+
{ command: "rig run show <id>", description: "Show a human run summary; add --raw or --json for the full payload." },
|
|
8462
|
+
{ command: "rig run attach <id> --follow", description: "Open the native bundled Pi live view for a worker run." },
|
|
8463
|
+
{ command: "rig run stop <id>", description: "Request cancellation for a running worker." }
|
|
8464
|
+
]
|
|
8465
|
+
},
|
|
8466
|
+
{
|
|
8467
|
+
title: "Review / inbox",
|
|
8468
|
+
subtitle: "clear blocked runs and configure completion review",
|
|
8469
|
+
commands: [
|
|
8470
|
+
{ command: "rig inbox approvals", description: "List pending approval requests from local/server run state." },
|
|
8471
|
+
{ command: "rig inbox inputs", description: "List pending user-input requests from local/server run state." },
|
|
8472
|
+
{ command: "rig review show|set", description: "Inspect or change the review gate policy." }
|
|
8473
|
+
]
|
|
8474
|
+
},
|
|
8475
|
+
{
|
|
8476
|
+
title: "Health / setup",
|
|
8477
|
+
subtitle: "bootstrap and diagnose the repo/server/GitHub/Pi path",
|
|
8478
|
+
commands: [
|
|
8479
|
+
{ command: "rig init", description: "Interactive setup: config, GitHub auth, task source, server, checkout, Pi." },
|
|
8480
|
+
{ command: "rig doctor", description: "Diagnose project/server/GitHub/task/Pi wiring." },
|
|
8481
|
+
{ command: "rig github auth status", description: "Show GitHub auth state on the selected Rig server." }
|
|
8482
|
+
]
|
|
8483
|
+
}
|
|
8484
|
+
];
|
|
8485
|
+
var PRIMARY_GROUPS = [
|
|
8486
|
+
{
|
|
8487
|
+
name: "server",
|
|
8488
|
+
summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
|
|
8489
|
+
usage: ["rig server <status|list|add|use|start> [options]"],
|
|
8490
|
+
commands: [
|
|
8491
|
+
{ command: "status", description: "Show the selected server for this repo.", primary: true },
|
|
8492
|
+
{ command: "use local", description: "Switch this repo to the local Rig server.", primary: true },
|
|
8493
|
+
{ command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
|
|
8494
|
+
{ command: "use <alias>", description: "Select a saved remote server alias.", primary: true },
|
|
8495
|
+
{ command: "list", description: "List saved local/remote server aliases.", primary: true },
|
|
8496
|
+
{ command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process." }
|
|
8497
|
+
],
|
|
8498
|
+
examples: [
|
|
8499
|
+
"rig server status",
|
|
8500
|
+
"rig server add prod https://where.rig-does.work",
|
|
8501
|
+
"rig server use prod",
|
|
8502
|
+
"rig server use local",
|
|
8503
|
+
"rig server start --port 3773"
|
|
8504
|
+
],
|
|
8505
|
+
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
|
|
8506
|
+
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
8507
|
+
},
|
|
8508
|
+
{
|
|
8509
|
+
name: "task",
|
|
8510
|
+
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
8511
|
+
usage: ["rig task <list|next|show|run> [options]"],
|
|
8512
|
+
commands: [
|
|
8513
|
+
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
8514
|
+
{ command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
|
|
8515
|
+
{ command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
|
|
8516
|
+
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
8517
|
+
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
8518
|
+
{ command: "details --task <id>", description: "Show full task info from the configured source." },
|
|
8519
|
+
{ command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
|
|
8520
|
+
{ command: "reset --task <id>", description: "Compatibility spelling of `reopen --task <id>`." },
|
|
8521
|
+
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
8522
|
+
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
8523
|
+
],
|
|
8524
|
+
examples: [
|
|
8525
|
+
"rig task list --assignee @me --limit 20",
|
|
8526
|
+
"rig task next",
|
|
8527
|
+
"rig task show 123 --raw",
|
|
8528
|
+
"rig task run --next",
|
|
8529
|
+
"rig task run #123 --runtime-adapter pi",
|
|
8530
|
+
"rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
|
|
8531
|
+
],
|
|
8532
|
+
next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
|
|
8533
|
+
},
|
|
8534
|
+
{
|
|
8535
|
+
name: "run",
|
|
8536
|
+
summary: "Observe, attach to, and control Rig runs.",
|
|
8537
|
+
usage: ["rig run <list|status|show|attach|stop> [options]"],
|
|
8538
|
+
commands: [
|
|
8539
|
+
{ command: "list", description: "List recent runs from the selected server or local state.", primary: true },
|
|
8540
|
+
{ command: "status", description: "Render active and recent run groups.", primary: true },
|
|
8541
|
+
{ command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
|
|
8542
|
+
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
|
|
8543
|
+
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
8544
|
+
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
8545
|
+
{ command: "resume", description: "Resume the most recent interrupted local run." },
|
|
8546
|
+
{ command: "restart", description: "Restart the most recent local run from a clean runtime." },
|
|
8547
|
+
{ command: "delete|cleanup", description: "Remove completed run records/artifacts." }
|
|
8548
|
+
],
|
|
8549
|
+
examples: [
|
|
8550
|
+
"rig run list",
|
|
8551
|
+
"rig run status",
|
|
8552
|
+
"rig run show <run-id>",
|
|
8553
|
+
"rig run attach <run-id> --follow",
|
|
8554
|
+
"rig run stop <run-id>"
|
|
8555
|
+
],
|
|
8556
|
+
next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
|
|
8557
|
+
},
|
|
8558
|
+
{
|
|
8559
|
+
name: "inbox",
|
|
8560
|
+
summary: "Review approval and user-input requests that block worker runs.",
|
|
8561
|
+
usage: ["rig inbox <approvals|approve|inputs|respond> [options]"],
|
|
8562
|
+
commands: [
|
|
8563
|
+
{ command: "approvals [--run <id>] [--task <id>]", description: "List pending approvals.", primary: true },
|
|
8564
|
+
{ command: "inputs [--run <id>] [--task <id>]", description: "List pending user-input requests.", primary: true },
|
|
8565
|
+
{ command: "approve --run <id> --request <id> --decision approve|reject", description: "Resolve an approval request." },
|
|
8566
|
+
{ command: "respond --run <id> --request <id> --answer key=value", description: "Answer a user-input request." }
|
|
8567
|
+
],
|
|
8568
|
+
examples: [
|
|
8569
|
+
"rig inbox approvals",
|
|
8570
|
+
"rig inbox inputs --run <run-id>",
|
|
8571
|
+
"rig inbox approve --run <run-id> --request <request-id> --decision approve"
|
|
8572
|
+
],
|
|
8573
|
+
next: ["Rejoin the run after resolving a block: `rig run attach <run-id> --follow`."]
|
|
8574
|
+
},
|
|
8575
|
+
{
|
|
8576
|
+
name: "review",
|
|
8577
|
+
summary: "Inspect or change completion review gate policy.",
|
|
8578
|
+
usage: ["rig review <show|set>"],
|
|
8579
|
+
commands: [
|
|
8580
|
+
{ command: "show", description: "Show current review gate settings.", primary: true },
|
|
8581
|
+
{ command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider.", primary: true }
|
|
8582
|
+
],
|
|
8583
|
+
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
8584
|
+
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
8585
|
+
},
|
|
8586
|
+
{
|
|
8587
|
+
name: "init",
|
|
8588
|
+
summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
|
|
8589
|
+
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
8590
|
+
commands: [
|
|
8591
|
+
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
8592
|
+
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
8593
|
+
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
8594
|
+
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
8595
|
+
],
|
|
8596
|
+
examples: [
|
|
8597
|
+
"rig init",
|
|
8598
|
+
"rig init --yes --repo humanity-org/humanwork",
|
|
8599
|
+
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
8600
|
+
],
|
|
8601
|
+
next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
|
|
8602
|
+
},
|
|
8603
|
+
{
|
|
8604
|
+
name: "doctor",
|
|
8605
|
+
summary: "Diagnostics for project/server/GitHub/Pi state.",
|
|
8606
|
+
usage: ["rig doctor"],
|
|
8607
|
+
commands: [
|
|
8608
|
+
{ command: "doctor", description: "Run setup and runtime diagnostics.", primary: true },
|
|
8609
|
+
{ command: "check", description: "Compatibility spelling for diagnostics." }
|
|
8610
|
+
],
|
|
8611
|
+
examples: ["rig doctor", "rig doctor --json"],
|
|
8612
|
+
next: ["Use `rig server status` and `rig github auth status` to inspect common failure points."]
|
|
8613
|
+
},
|
|
8614
|
+
{
|
|
8615
|
+
name: "github",
|
|
8616
|
+
summary: "GitHub auth helpers for the selected Rig server.",
|
|
8617
|
+
usage: ["rig github auth <status|import-gh|token>"],
|
|
8618
|
+
commands: [
|
|
8619
|
+
{ command: "auth status", description: "Show GitHub auth state.", primary: true },
|
|
8620
|
+
{ command: "auth import-gh", description: "Import the current `gh` token into the selected server." },
|
|
8621
|
+
{ command: "auth token --token <token>", description: "Store a token on the selected server." }
|
|
8622
|
+
],
|
|
8623
|
+
examples: ["rig github auth status", "rig github auth import-gh"],
|
|
8624
|
+
next: ["After auth is valid, use `rig task run --next`."]
|
|
8625
|
+
}
|
|
8626
|
+
];
|
|
8627
|
+
var ADVANCED_GROUPS = [
|
|
8628
|
+
{ 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." }] },
|
|
8629
|
+
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
8630
|
+
{ 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." }] },
|
|
8631
|
+
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
8632
|
+
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
8633
|
+
{
|
|
8634
|
+
name: "browser",
|
|
8635
|
+
summary: "Browser/app diagnostics for browser-required tasks.",
|
|
8636
|
+
usage: ["rig browser <help|explain|demo|app|hp-next> [options]"],
|
|
8637
|
+
commands: [
|
|
8638
|
+
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
|
|
8639
|
+
{ command: "explain", description: "Explain the browser-required task contract." },
|
|
8640
|
+
{ command: "demo", description: "Run browser demo flows against a local page." },
|
|
8641
|
+
{ command: "app", description: "Launch the Rig Browser workstation app." },
|
|
8642
|
+
{ command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
|
|
8643
|
+
]
|
|
8644
|
+
},
|
|
8645
|
+
{
|
|
8646
|
+
name: "plugin",
|
|
8647
|
+
summary: "Plugin listing, validation, and plugin-contributed commands.",
|
|
8648
|
+
usage: ["rig plugin <list|validate|run> [options]"],
|
|
8649
|
+
commands: [
|
|
8650
|
+
{ command: "list", description: "List plugins declared in rig.config.ts and their contributions." },
|
|
8651
|
+
{ command: "validate --task <id>", description: "Run plugin-contributed validators for a task." },
|
|
8652
|
+
{ command: "run <command-id> [args...]", description: "Execute a plugin-contributed CLI command (also callable as `rig <command-id>`)." }
|
|
8653
|
+
]
|
|
8654
|
+
},
|
|
8655
|
+
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
8656
|
+
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
8657
|
+
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
8658
|
+
{ name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
|
|
8659
|
+
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
8660
|
+
{ name: "remote", summary: "Compatibility remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
|
|
8661
|
+
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
8662
|
+
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
8663
|
+
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
8664
|
+
];
|
|
8665
|
+
var ADVANCED_COMMANDS = [
|
|
8666
|
+
{ command: "rig server task-run ...", description: "Internal server-owned task execution entry point." },
|
|
8667
|
+
{ command: "rig server notify-test [--event <type>]", description: "Internal event notification smoke command." },
|
|
8668
|
+
{ command: "rig run start|start-serial|start-parallel", description: "Compatibility local run starters; prefer `rig task run ...`." },
|
|
8669
|
+
{ command: "rig remote orchestrate-*", description: "Compatibility remote orchestration commands." }
|
|
8670
|
+
];
|
|
8671
|
+
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
8672
|
+
function heading(title) {
|
|
8673
|
+
return pc4.bold(pc4.cyan(title));
|
|
8674
|
+
}
|
|
8675
|
+
function commandLine(command, description) {
|
|
8676
|
+
const commandColumn = command.length >= 38 ? `${command} ` : command.padEnd(38);
|
|
8677
|
+
return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
|
|
8678
|
+
}
|
|
8679
|
+
function renderCommandBlock(commands) {
|
|
8680
|
+
return commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8681
|
+
`);
|
|
8682
|
+
}
|
|
8683
|
+
function renderGroup(group) {
|
|
8684
|
+
const lines = [
|
|
8685
|
+
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
8686
|
+
"",
|
|
8687
|
+
pc4.bold("Usage"),
|
|
8688
|
+
...group.usage.map((line) => ` ${line}`),
|
|
8689
|
+
"",
|
|
8690
|
+
pc4.bold("Commands"),
|
|
8691
|
+
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
8692
|
+
];
|
|
8693
|
+
if (group.examples?.length) {
|
|
8694
|
+
lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
|
|
8695
|
+
}
|
|
8696
|
+
if (group.next?.length) {
|
|
8697
|
+
lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
8698
|
+
}
|
|
8699
|
+
if (group.advanced?.length) {
|
|
8700
|
+
lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
8701
|
+
}
|
|
8702
|
+
return lines.join(`
|
|
8703
|
+
`);
|
|
8704
|
+
}
|
|
8705
|
+
function renderTopLevelHelp() {
|
|
8706
|
+
return [
|
|
8707
|
+
`${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
8708
|
+
pc4.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox/review gates."),
|
|
8709
|
+
"",
|
|
8710
|
+
...TOP_LEVEL_SECTIONS.flatMap((section) => [
|
|
8711
|
+
`${pc4.bold(pc4.magenta(`\u25C7 ${section.title}`))} \u2014 ${pc4.dim(section.subtitle)}`,
|
|
8712
|
+
renderCommandBlock(section.commands),
|
|
8713
|
+
""
|
|
8714
|
+
]),
|
|
8715
|
+
pc4.dim("More: `rig help --advanced` for dev/compatibility commands; `rig <group> --help` for rich per-group help; `rig --version` for the installed version."),
|
|
8716
|
+
"",
|
|
8717
|
+
pc4.bold("Global options"),
|
|
8718
|
+
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
8719
|
+
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
8720
|
+
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
8721
|
+
].join(`
|
|
8722
|
+
`).trimEnd();
|
|
8723
|
+
}
|
|
8724
|
+
function renderAdvancedHelp() {
|
|
8725
|
+
return [
|
|
8726
|
+
`${heading("rig advanced")} \u2014 compatibility, diagnostics, and internal surfaces`,
|
|
8727
|
+
"",
|
|
8728
|
+
pc4.bold("Primary groups"),
|
|
8729
|
+
" server, task, run, inbox, review, init, doctor, github",
|
|
8730
|
+
"",
|
|
8731
|
+
pc4.bold("Advanced commands"),
|
|
8732
|
+
...ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)),
|
|
8733
|
+
"",
|
|
8734
|
+
pc4.bold("Advanced groups"),
|
|
8735
|
+
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
8736
|
+
"",
|
|
8737
|
+
pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, `rig run`, `rig inbox`, and `rig review` for day-to-day work.")
|
|
8738
|
+
].join(`
|
|
8739
|
+
`);
|
|
8740
|
+
}
|
|
8741
|
+
function renderGroupHelp(groupName) {
|
|
8742
|
+
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
8743
|
+
return group ? renderGroup(group) : null;
|
|
8744
|
+
}
|
|
8745
|
+
function shouldUseClackOutput2() {
|
|
8746
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
8747
|
+
}
|
|
8748
|
+
function printTopLevelHelp() {
|
|
8749
|
+
if (!shouldUseClackOutput2()) {
|
|
8750
|
+
console.log(renderTopLevelHelp());
|
|
8751
|
+
return;
|
|
8053
8752
|
}
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
`) };
|
|
8058
|
-
renderer.writeLine("Select Rig task:");
|
|
8059
|
-
for (const row of renderTaskPickerRows(tasks))
|
|
8060
|
-
renderer.writeLine(` ${row}`);
|
|
8061
|
-
const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
|
|
8062
|
-
if (!answer2)
|
|
8063
|
-
return null;
|
|
8064
|
-
if (/^\d+$/.test(answer2)) {
|
|
8065
|
-
const index2 = Number.parseInt(answer2, 10) - 1;
|
|
8066
|
-
return tasks[index2] ?? null;
|
|
8067
|
-
}
|
|
8068
|
-
return tasks.find((task) => taskId2(task) === answer2) ?? null;
|
|
8753
|
+
intro3("rig");
|
|
8754
|
+
for (const section of TOP_LEVEL_SECTIONS) {
|
|
8755
|
+
note4(renderCommandBlock(section.commands), `${section.title} \u2014 ${section.subtitle}`);
|
|
8069
8756
|
}
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8757
|
+
log4.info("More: rig help --advanced \xB7 rig <group> --help \xB7 rig --version");
|
|
8758
|
+
note4([
|
|
8759
|
+
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
8760
|
+
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
8761
|
+
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
8762
|
+
].join(`
|
|
8763
|
+
`), "Global options");
|
|
8764
|
+
outro3("Server \u2192 task \u2192 run \u2192 inbox/review.");
|
|
8765
|
+
}
|
|
8766
|
+
function printAdvancedHelp() {
|
|
8767
|
+
if (!shouldUseClackOutput2()) {
|
|
8768
|
+
console.log(renderAdvancedHelp());
|
|
8769
|
+
return;
|
|
8082
8770
|
}
|
|
8083
|
-
|
|
8084
|
-
|
|
8771
|
+
intro3("rig advanced");
|
|
8772
|
+
note4(ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8773
|
+
`), "Advanced commands");
|
|
8774
|
+
note4(ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)).join(`
|
|
8775
|
+
`), "Advanced groups");
|
|
8776
|
+
outro3("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox \xB7 rig review.");
|
|
8777
|
+
}
|
|
8778
|
+
function printGroupHelpDocument(groupName) {
|
|
8779
|
+
const rendered = renderGroupHelp(groupName) ?? renderTopLevelHelp();
|
|
8780
|
+
if (!shouldUseClackOutput2()) {
|
|
8781
|
+
console.log(rendered);
|
|
8782
|
+
return;
|
|
8783
|
+
}
|
|
8784
|
+
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
8785
|
+
if (!group) {
|
|
8786
|
+
printTopLevelHelp();
|
|
8787
|
+
return;
|
|
8788
|
+
}
|
|
8789
|
+
intro3(`rig ${group.name}`);
|
|
8790
|
+
note4(group.summary, "Purpose");
|
|
8791
|
+
note4(group.usage.join(`
|
|
8792
|
+
`), "Usage");
|
|
8793
|
+
note4(group.commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
8794
|
+
`), "Commands");
|
|
8795
|
+
if (group.examples?.length)
|
|
8796
|
+
note4(group.examples.map((line) => `$ ${line}`).join(`
|
|
8797
|
+
`), "Examples");
|
|
8798
|
+
if (group.next?.length)
|
|
8799
|
+
note4(group.next.map((line) => `\u203A ${line}`).join(`
|
|
8800
|
+
`), "Next steps");
|
|
8801
|
+
if (group.advanced?.length)
|
|
8802
|
+
log4.info(group.advanced.join(`
|
|
8803
|
+
`));
|
|
8804
|
+
outro3("Run with --json when scripts need structured output.");
|
|
8085
8805
|
}
|
|
8086
8806
|
|
|
8087
8807
|
// packages/cli/src/commands/task.ts
|
|
8088
|
-
import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
|
|
8808
|
+
import { buildPluginHostContext as buildPluginHostContext2 } from "@rig/runtime/control-plane/plugin-host-context";
|
|
8089
8809
|
import { loadConfig } from "@rig/core/load-config";
|
|
8090
8810
|
async function readStdin() {
|
|
8091
8811
|
const chunks = [];
|
|
@@ -8235,27 +8955,30 @@ function summarizeTask(task, options = {}) {
|
|
|
8235
8955
|
...options.raw ? { raw: raw ?? task } : {}
|
|
8236
8956
|
};
|
|
8237
8957
|
}
|
|
8238
|
-
function printTaskSummary(task) {
|
|
8239
|
-
console.log(formatTaskList([task]));
|
|
8240
|
-
}
|
|
8241
8958
|
async function validatorRegistryForTaskCommands(projectRoot) {
|
|
8242
|
-
return
|
|
8959
|
+
return buildPluginHostContext2(projectRoot).then((ctx) => ctx?.validatorRegistry ?? undefined).catch(() => {
|
|
8243
8960
|
return;
|
|
8244
8961
|
});
|
|
8245
8962
|
}
|
|
8246
8963
|
async function executeTask(context, args, options) {
|
|
8247
|
-
|
|
8964
|
+
if (args.length === 0) {
|
|
8965
|
+
if (context.outputMode === "text") {
|
|
8966
|
+
printGroupHelpDocument("task");
|
|
8967
|
+
}
|
|
8968
|
+
return { ok: true, group: "task", command: "help" };
|
|
8969
|
+
}
|
|
8970
|
+
const [command = "help", ...rest] = args;
|
|
8248
8971
|
switch (command) {
|
|
8249
8972
|
case "list": {
|
|
8250
8973
|
let pending = rest;
|
|
8251
8974
|
const rawResult = takeFlag(pending, "--raw");
|
|
8252
8975
|
pending = rawResult.rest;
|
|
8253
8976
|
const { filters, rest: remaining } = parseTaskFilters(pending);
|
|
8254
|
-
requireNoExtraArgs(remaining, "
|
|
8977
|
+
requireNoExtraArgs(remaining, "rig task list [--raw] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
8255
8978
|
const tasks = await listWorkspaceTasksViaServer(context, filters);
|
|
8256
8979
|
if (context.outputMode === "text") {
|
|
8257
8980
|
const renderedTasks = rawResult.value ? tasks.map((task) => summarizeTask(task, { raw: true })) : tasks.map((task) => summarizeTask(task));
|
|
8258
|
-
|
|
8981
|
+
printFormattedOutput(formatTaskList(renderedTasks, { raw: rawResult.value }));
|
|
8259
8982
|
}
|
|
8260
8983
|
return {
|
|
8261
8984
|
ok: true,
|
|
@@ -8265,10 +8988,13 @@ async function executeTask(context, args, options) {
|
|
|
8265
8988
|
};
|
|
8266
8989
|
}
|
|
8267
8990
|
case "show": {
|
|
8268
|
-
|
|
8991
|
+
let pending = rest;
|
|
8992
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
8993
|
+
pending = rawResult.rest;
|
|
8994
|
+
const taskOption = takeOption(pending, "--task");
|
|
8269
8995
|
const positional = taskOption.rest.length > 0 && taskOption.rest[0] && !taskOption.rest[0].startsWith("-") ? taskOption.rest[0] : undefined;
|
|
8270
8996
|
const remaining = positional ? taskOption.rest.slice(1) : taskOption.rest;
|
|
8271
|
-
requireNoExtraArgs(remaining, "
|
|
8997
|
+
requireNoExtraArgs(remaining, "rig task show <id>|--task <id> [--raw]");
|
|
8272
8998
|
const taskId3 = normalizeTaskRunTaskId(taskOption.value ?? positional);
|
|
8273
8999
|
if (!taskId3)
|
|
8274
9000
|
throw new CliError2("task show requires a task id.", 2);
|
|
@@ -8276,19 +9002,20 @@ async function executeTask(context, args, options) {
|
|
|
8276
9002
|
if (!task)
|
|
8277
9003
|
throw new CliError2(`Task not found: ${taskId3}`, 3);
|
|
8278
9004
|
const summary = summarizeTask(task, { raw: true });
|
|
8279
|
-
if (context.outputMode === "text")
|
|
8280
|
-
|
|
8281
|
-
|
|
9005
|
+
if (context.outputMode === "text") {
|
|
9006
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(summary, null, 2) : formatTaskDetails(summary));
|
|
9007
|
+
}
|
|
9008
|
+
return { ok: true, group: "task", command, details: { task: summary, raw: rawResult.value } };
|
|
8282
9009
|
}
|
|
8283
9010
|
case "next": {
|
|
8284
9011
|
const { filters, rest: remaining } = parseTaskFilters(rest);
|
|
8285
|
-
requireNoExtraArgs(remaining, "
|
|
9012
|
+
requireNoExtraArgs(remaining, "rig task next [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
8286
9013
|
const selected = await selectNextWorkspaceTaskViaServer(context, filters);
|
|
8287
9014
|
if (context.outputMode === "text") {
|
|
8288
9015
|
if (selected.task) {
|
|
8289
|
-
|
|
9016
|
+
printFormattedOutput(formatTaskCard(summarizeTask(selected.task, { raw: true }), { title: "Selected task", selected: true }));
|
|
8290
9017
|
} else {
|
|
8291
|
-
|
|
9018
|
+
printFormattedOutput("No matching tasks.\n\nNext\n\u203A Try `rig task list` to inspect available work.\n\u203A Check server: `rig server status`");
|
|
8292
9019
|
}
|
|
8293
9020
|
}
|
|
8294
9021
|
return {
|
|
@@ -8304,31 +9031,31 @@ async function executeTask(context, args, options) {
|
|
|
8304
9031
|
}
|
|
8305
9032
|
case "info": {
|
|
8306
9033
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8307
|
-
requireNoExtraArgs(remaining, "
|
|
9034
|
+
requireNoExtraArgs(remaining, "rig task info [--task <task-id>]");
|
|
8308
9035
|
await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, task || undefined));
|
|
8309
9036
|
return { ok: true, group: "task", command, details: { task: task || null } };
|
|
8310
9037
|
}
|
|
8311
9038
|
case "scope": {
|
|
8312
9039
|
const filesFlag = takeFlag(rest, "--files");
|
|
8313
9040
|
const { value: task, rest: remaining } = takeOption(filesFlag.rest, "--task");
|
|
8314
|
-
requireNoExtraArgs(remaining, "
|
|
9041
|
+
requireNoExtraArgs(remaining, "rig task scope [--task <id>] [--files]");
|
|
8315
9042
|
await withMutedConsole(context.outputMode === "json", () => taskScope(context.projectRoot, filesFlag.value, task || undefined));
|
|
8316
9043
|
return { ok: true, group: "task", command, details: { files: filesFlag.value, task: task || null } };
|
|
8317
9044
|
}
|
|
8318
9045
|
case "deps":
|
|
8319
|
-
requireNoExtraArgs(rest, "
|
|
9046
|
+
requireNoExtraArgs(rest, "rig task deps");
|
|
8320
9047
|
await withMutedConsole(context.outputMode === "json", () => taskDeps(context.projectRoot));
|
|
8321
9048
|
return { ok: true, group: "task", command };
|
|
8322
9049
|
case "status":
|
|
8323
|
-
requireNoExtraArgs(rest, "
|
|
9050
|
+
requireNoExtraArgs(rest, "rig task status");
|
|
8324
9051
|
withMutedConsole(context.outputMode === "json", () => taskStatus2(context.projectRoot));
|
|
8325
9052
|
return { ok: true, group: "task", command };
|
|
8326
9053
|
case "artifacts":
|
|
8327
|
-
requireNoExtraArgs(rest, "
|
|
9054
|
+
requireNoExtraArgs(rest, "rig task artifacts");
|
|
8328
9055
|
withMutedConsole(context.outputMode === "json", () => taskArtifacts(context.projectRoot));
|
|
8329
9056
|
return { ok: true, group: "task", command };
|
|
8330
9057
|
case "artifact-dir": {
|
|
8331
|
-
requireNoExtraArgs(rest, "
|
|
9058
|
+
requireNoExtraArgs(rest, "rig task artifact-dir");
|
|
8332
9059
|
const path = taskArtifactDir(context.projectRoot);
|
|
8333
9060
|
if (context.outputMode === "text") {
|
|
8334
9061
|
console.log(path);
|
|
@@ -8337,7 +9064,7 @@ async function executeTask(context, args, options) {
|
|
|
8337
9064
|
}
|
|
8338
9065
|
case "artifact-write": {
|
|
8339
9066
|
if (rest.length < 1) {
|
|
8340
|
-
throw new CliError2(`Usage:
|
|
9067
|
+
throw new CliError2(`Usage: rig task artifact-write <filename> [--file <path>]
|
|
8341
9068
|
` + ` Reads content from stdin (or --file), writes to the active task artifact dir.
|
|
8342
9069
|
` + " Example: echo '...' | rig task artifact-write collection-audit.md");
|
|
8343
9070
|
}
|
|
@@ -8350,7 +9077,7 @@ async function executeTask(context, args, options) {
|
|
|
8350
9077
|
content = await readStdin();
|
|
8351
9078
|
}
|
|
8352
9079
|
if (!artifactFilename) {
|
|
8353
|
-
throw new CliError2("Usage:
|
|
9080
|
+
throw new CliError2("Usage: rig task artifact-write <filename> [--file path]");
|
|
8354
9081
|
}
|
|
8355
9082
|
withMutedConsole(context.outputMode === "json", () => taskArtifactWrite(context.projectRoot, artifactFilename, content));
|
|
8356
9083
|
return { ok: true, group: "task", command, details: { filename: artifactFilename } };
|
|
@@ -8359,11 +9086,11 @@ async function executeTask(context, args, options) {
|
|
|
8359
9086
|
return options.executeTaskReportBug(context, rest);
|
|
8360
9087
|
case "lookup": {
|
|
8361
9088
|
if (rest.length !== 1) {
|
|
8362
|
-
throw new CliError2("Usage:
|
|
9089
|
+
throw new CliError2("Usage: rig task lookup <task-id>");
|
|
8363
9090
|
}
|
|
8364
9091
|
const lookupId = rest[0];
|
|
8365
9092
|
if (!lookupId) {
|
|
8366
|
-
throw new CliError2("Usage:
|
|
9093
|
+
throw new CliError2("Usage: rig task lookup <task-id>");
|
|
8367
9094
|
}
|
|
8368
9095
|
const result = taskLookup2(context.projectRoot, lookupId);
|
|
8369
9096
|
if (context.outputMode === "text") {
|
|
@@ -8373,17 +9100,17 @@ async function executeTask(context, args, options) {
|
|
|
8373
9100
|
}
|
|
8374
9101
|
case "record": {
|
|
8375
9102
|
if (rest.length < 2) {
|
|
8376
|
-
throw new CliError2("Usage:
|
|
9103
|
+
throw new CliError2("Usage: rig task record <decision|failure> <text>");
|
|
8377
9104
|
}
|
|
8378
9105
|
const type = rest[0];
|
|
8379
9106
|
if (type !== "decision" && type !== "failure") {
|
|
8380
|
-
throw new CliError2("Usage:
|
|
9107
|
+
throw new CliError2("Usage: rig task record <decision|failure> <text>");
|
|
8381
9108
|
}
|
|
8382
9109
|
withMutedConsole(context.outputMode === "json", () => taskRecord(context.projectRoot, type, rest.slice(1).join(" ")));
|
|
8383
9110
|
return { ok: true, group: "task", command, details: { type: rest[0] } };
|
|
8384
9111
|
}
|
|
8385
9112
|
case "ready":
|
|
8386
|
-
requireNoExtraArgs(rest, "
|
|
9113
|
+
requireNoExtraArgs(rest, "rig task ready");
|
|
8387
9114
|
await withMutedConsole(context.outputMode === "json", () => taskReady(context.projectRoot));
|
|
8388
9115
|
return { ok: true, group: "task", command };
|
|
8389
9116
|
case "run": {
|
|
@@ -8420,7 +9147,7 @@ async function executeTask(context, args, options) {
|
|
|
8420
9147
|
if (positionalTaskId) {
|
|
8421
9148
|
pending = pending.slice(1);
|
|
8422
9149
|
}
|
|
8423
|
-
requireNoExtraArgs(pending, "
|
|
9150
|
+
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]");
|
|
8424
9151
|
if (nextResult.value && (taskResult.value || positionalTaskId)) {
|
|
8425
9152
|
throw new CliError2("task run cannot combine --next with an explicit task id.", 2);
|
|
8426
9153
|
}
|
|
@@ -8474,10 +9201,24 @@ async function executeTask(context, args, options) {
|
|
|
8474
9201
|
});
|
|
8475
9202
|
let attachDetails = null;
|
|
8476
9203
|
if (!detachResult.value && context.outputMode === "text") {
|
|
8477
|
-
|
|
9204
|
+
printFormattedOutput(formatSubmittedRun({
|
|
9205
|
+
runId: submitted.runId,
|
|
9206
|
+
task: selectedTask ? summarizeTask(selectedTask) : null,
|
|
9207
|
+
runtimeAdapter,
|
|
9208
|
+
runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
|
|
9209
|
+
interactionMode: interactionModeResult.value || "default",
|
|
9210
|
+
detached: false
|
|
9211
|
+
}));
|
|
8478
9212
|
attachDetails = await attachRunOperatorView(context, { runId: submitted.runId, follow: true });
|
|
8479
9213
|
} else if (context.outputMode === "text") {
|
|
8480
|
-
|
|
9214
|
+
printFormattedOutput(formatSubmittedRun({
|
|
9215
|
+
runId: submitted.runId,
|
|
9216
|
+
task: selectedTask ? summarizeTask(selectedTask) : null,
|
|
9217
|
+
runtimeAdapter,
|
|
9218
|
+
runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
|
|
9219
|
+
interactionMode: interactionModeResult.value || "default",
|
|
9220
|
+
detached: true
|
|
9221
|
+
}));
|
|
8481
9222
|
}
|
|
8482
9223
|
return {
|
|
8483
9224
|
ok: true,
|
|
@@ -8501,7 +9242,7 @@ async function executeTask(context, args, options) {
|
|
|
8501
9242
|
}
|
|
8502
9243
|
case "validate": {
|
|
8503
9244
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8504
|
-
requireNoExtraArgs(remaining, "
|
|
9245
|
+
requireNoExtraArgs(remaining, "rig task validate [--task <task-id>]");
|
|
8505
9246
|
if (context.dryRun) {
|
|
8506
9247
|
await context.runCommand(["rig", "task", "validate", ...task ? ["--task", task] : []]);
|
|
8507
9248
|
return { ok: true, group: "task", command, details: { task: task || "active" } };
|
|
@@ -8514,12 +9255,12 @@ async function executeTask(context, args, options) {
|
|
|
8514
9255
|
}
|
|
8515
9256
|
case "verify": {
|
|
8516
9257
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8517
|
-
requireNoExtraArgs(remaining, "
|
|
9258
|
+
requireNoExtraArgs(remaining, "rig task verify [--task <task-id>]");
|
|
8518
9259
|
if (context.dryRun) {
|
|
8519
9260
|
await context.runCommand(["rig", "task", "verify", ...task ? ["--task", task] : []]);
|
|
8520
9261
|
return { ok: true, group: "task", command, details: { task: task || "active" } };
|
|
8521
9262
|
}
|
|
8522
|
-
const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot,
|
|
9263
|
+
const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot, task || undefined));
|
|
8523
9264
|
if (!ok) {
|
|
8524
9265
|
throw new CliError2(`Verification rejected for ${task || "active task"}.`, 2);
|
|
8525
9266
|
}
|
|
@@ -8527,15 +9268,19 @@ async function executeTask(context, args, options) {
|
|
|
8527
9268
|
}
|
|
8528
9269
|
case "reset": {
|
|
8529
9270
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8530
|
-
requireNoExtraArgs(remaining, "
|
|
8531
|
-
const requiredTask = requireTask(task, "
|
|
8532
|
-
|
|
8533
|
-
|
|
9271
|
+
requireNoExtraArgs(remaining, "rig task reset --task <task-id>");
|
|
9272
|
+
const requiredTask = requireTask(task, "rig task reset --task <task-id>");
|
|
9273
|
+
const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
|
|
9274
|
+
all: false,
|
|
9275
|
+
taskId: requiredTask,
|
|
9276
|
+
dryRun: false
|
|
9277
|
+
}));
|
|
9278
|
+
return { ok: true, group: "task", command, details: summary };
|
|
8534
9279
|
}
|
|
8535
9280
|
case "details": {
|
|
8536
9281
|
const { value: task, rest: remaining } = takeOption(rest, "--task");
|
|
8537
|
-
requireNoExtraArgs(remaining, "
|
|
8538
|
-
const requiredTask = requireTask(task, "
|
|
9282
|
+
requireNoExtraArgs(remaining, "rig task details --task <task-id>");
|
|
9283
|
+
const requiredTask = requireTask(task, "rig task details --task <task-id>");
|
|
8539
9284
|
await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, requiredTask));
|
|
8540
9285
|
return { ok: true, group: "task", command, details: { task: requiredTask } };
|
|
8541
9286
|
}
|
|
@@ -8543,9 +9288,9 @@ async function executeTask(context, args, options) {
|
|
|
8543
9288
|
const { value: task, rest: rest1 } = takeOption(rest, "--task");
|
|
8544
9289
|
const allFlag = takeFlag(rest1, "--all");
|
|
8545
9290
|
const { rest: remaining } = takeOption(allFlag.rest, "--reason");
|
|
8546
|
-
requireNoExtraArgs(remaining, "
|
|
9291
|
+
requireNoExtraArgs(remaining, "rig task reopen [--task <id> | --all] [--reason <text>]");
|
|
8547
9292
|
if (!allFlag.value && !task) {
|
|
8548
|
-
throw new CliError2("Usage:
|
|
9293
|
+
throw new CliError2("Usage: rig task reopen [--task <id> | --all] [--reason <text>]");
|
|
8549
9294
|
}
|
|
8550
9295
|
const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
|
|
8551
9296
|
all: allFlag.value,
|
|
@@ -8560,6 +9305,7 @@ async function executeTask(context, args, options) {
|
|
|
8560
9305
|
}
|
|
8561
9306
|
|
|
8562
9307
|
// packages/cli/src/commands/task-run-driver.ts
|
|
9308
|
+
init_runner();
|
|
8563
9309
|
import { copyFileSync as copyFileSync3, existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
8564
9310
|
import { resolve as resolve21 } from "path";
|
|
8565
9311
|
import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
|
|
@@ -10576,19 +11322,20 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
|
|
|
10576
11322
|
}
|
|
10577
11323
|
|
|
10578
11324
|
// packages/cli/src/commands/test.ts
|
|
11325
|
+
init_runner();
|
|
10579
11326
|
async function executeTest(context, args) {
|
|
10580
11327
|
const [command = "unit", ...rest] = args;
|
|
10581
11328
|
switch (command) {
|
|
10582
11329
|
case "unit":
|
|
10583
|
-
requireNoExtraArgs(rest, "
|
|
11330
|
+
requireNoExtraArgs(rest, "rig test unit");
|
|
10584
11331
|
await context.runCommand(["bun", "test", "tests/harness/", "--ignore", "tests/harness/e2e/**"]);
|
|
10585
11332
|
return { ok: true, group: "test", command };
|
|
10586
11333
|
case "e2e":
|
|
10587
|
-
requireNoExtraArgs(rest, "
|
|
11334
|
+
requireNoExtraArgs(rest, "rig test e2e");
|
|
10588
11335
|
await context.runCommand(["bun", "test", "tests/harness/e2e/"]);
|
|
10589
11336
|
return { ok: true, group: "test", command };
|
|
10590
11337
|
case "all":
|
|
10591
|
-
requireNoExtraArgs(rest, "
|
|
11338
|
+
requireNoExtraArgs(rest, "rig test all");
|
|
10592
11339
|
await context.runCommand(["bun", "test", "tests/harness/"]);
|
|
10593
11340
|
return { ok: true, group: "test", command };
|
|
10594
11341
|
default:
|
|
@@ -10597,6 +11344,7 @@ async function executeTest(context, args) {
|
|
|
10597
11344
|
}
|
|
10598
11345
|
|
|
10599
11346
|
// packages/cli/src/commands/setup.ts
|
|
11347
|
+
init_runner();
|
|
10600
11348
|
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
10601
11349
|
import { resolve as resolve22 } from "path";
|
|
10602
11350
|
import { createPluginHost } from "@rig/core";
|
|
@@ -10604,11 +11352,12 @@ import {
|
|
|
10604
11352
|
isSupportedBunVersion as isSupportedBunVersion2,
|
|
10605
11353
|
MIN_SUPPORTED_BUN_VERSION as MIN_SUPPORTED_BUN_VERSION2
|
|
10606
11354
|
} from "@rig/runtime/control-plane/setup-version";
|
|
11355
|
+
init__parsers();
|
|
10607
11356
|
async function executeSetup(context, args) {
|
|
10608
11357
|
const [command = "check", ...rest] = args;
|
|
10609
11358
|
switch (command) {
|
|
10610
11359
|
case "bootstrap":
|
|
10611
|
-
requireNoExtraArgs(rest, "
|
|
11360
|
+
requireNoExtraArgs(rest, "rig setup bootstrap");
|
|
10612
11361
|
{
|
|
10613
11362
|
const hostBash = Bun.which("bash") || "/bin/bash";
|
|
10614
11363
|
const env = { ...process.env };
|
|
@@ -10631,25 +11380,19 @@ async function executeSetup(context, args) {
|
|
|
10631
11380
|
}
|
|
10632
11381
|
return { ok: true, group: "setup", command };
|
|
10633
11382
|
case "check":
|
|
10634
|
-
requireNoExtraArgs(rest, `
|
|
11383
|
+
requireNoExtraArgs(rest, `rig setup ${command}`);
|
|
10635
11384
|
{
|
|
10636
11385
|
const checks = await withMutedConsole(context.outputMode === "json", () => runSetupCheck(context.projectRoot));
|
|
10637
11386
|
return { ok: true, group: "setup", command, details: { checks, failures: countDoctorFailures(checks) } };
|
|
10638
11387
|
}
|
|
10639
11388
|
case "setup":
|
|
10640
|
-
requireNoExtraArgs(rest, "
|
|
11389
|
+
requireNoExtraArgs(rest, "rig setup setup");
|
|
10641
11390
|
withMutedConsole(context.outputMode === "json", () => runSetupInit(context.projectRoot));
|
|
10642
11391
|
return { ok: true, group: "setup", command };
|
|
10643
11392
|
case "preflight":
|
|
10644
|
-
requireNoExtraArgs(rest, "
|
|
11393
|
+
requireNoExtraArgs(rest, "rig setup preflight");
|
|
10645
11394
|
await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
|
|
10646
11395
|
return { ok: true, group: "setup", command };
|
|
10647
|
-
case "install-agent-shell":
|
|
10648
|
-
requireNoExtraArgs(rest, "bun run rig setup install-agent-shell");
|
|
10649
|
-
if (context.outputMode === "text") {
|
|
10650
|
-
console.log("install-agent-shell is deprecated. Runtime shells now use compiled rig-agent directly.");
|
|
10651
|
-
}
|
|
10652
|
-
return { ok: true, group: "setup", command };
|
|
10653
11396
|
default:
|
|
10654
11397
|
throw new CliError2(`Unknown setup command: ${command}`);
|
|
10655
11398
|
}
|
|
@@ -10700,6 +11443,7 @@ async function runSetupPreflight(projectRoot) {
|
|
|
10700
11443
|
}
|
|
10701
11444
|
|
|
10702
11445
|
// packages/cli/src/commands/workspace.ts
|
|
11446
|
+
init_runner();
|
|
10703
11447
|
import {
|
|
10704
11448
|
mutateWorkspaceServiceFabric,
|
|
10705
11449
|
readWorkspaceRemoteFleet,
|
|
@@ -10710,7 +11454,7 @@ async function executeWorkspace(context, args) {
|
|
|
10710
11454
|
const [command = "summary", ...rest] = args;
|
|
10711
11455
|
switch (command) {
|
|
10712
11456
|
case "summary": {
|
|
10713
|
-
requireNoExtraArgs(rest, "
|
|
11457
|
+
requireNoExtraArgs(rest, "rig workspace summary");
|
|
10714
11458
|
const summary = await readWorkspaceSummary(context.projectRoot);
|
|
10715
11459
|
if (context.outputMode === "text") {
|
|
10716
11460
|
console.log("Workspace Summary");
|
|
@@ -10735,7 +11479,7 @@ Warnings:`);
|
|
|
10735
11479
|
return { ok: true, group: "workspace", command, details: summary };
|
|
10736
11480
|
}
|
|
10737
11481
|
case "topology": {
|
|
10738
|
-
requireNoExtraArgs(rest, "
|
|
11482
|
+
requireNoExtraArgs(rest, "rig workspace topology");
|
|
10739
11483
|
const topology = readWorkspaceTopology(context.projectRoot);
|
|
10740
11484
|
if (context.outputMode === "text") {
|
|
10741
11485
|
console.log(`Topology: ${topology.status}`);
|
|
@@ -10748,7 +11492,7 @@ Warnings:`);
|
|
|
10748
11492
|
return { ok: true, group: "workspace", command, details: topology };
|
|
10749
11493
|
}
|
|
10750
11494
|
case "remote-hosts": {
|
|
10751
|
-
requireNoExtraArgs(rest, "
|
|
11495
|
+
requireNoExtraArgs(rest, "rig workspace remote-hosts");
|
|
10752
11496
|
const fleet = readWorkspaceRemoteFleet(context.projectRoot);
|
|
10753
11497
|
if (context.outputMode === "text") {
|
|
10754
11498
|
console.log(`Remote Hosts: ${fleet.status}`);
|
|
@@ -10763,7 +11507,7 @@ Warnings:`);
|
|
|
10763
11507
|
let pending = serviceRest;
|
|
10764
11508
|
const services = takeOption(pending, "--service");
|
|
10765
11509
|
pending = services.rest;
|
|
10766
|
-
requireNoExtraArgs(pending, "
|
|
11510
|
+
requireNoExtraArgs(pending, "rig workspace service-fabric <status|up|verify|down> [--service <name>]");
|
|
10767
11511
|
if (action !== "status" && action !== "up" && action !== "verify" && action !== "down") {
|
|
10768
11512
|
throw new CliError2(`Unknown workspace service-fabric action: ${action}`);
|
|
10769
11513
|
}
|
|
@@ -10784,200 +11528,6 @@ Warnings:`);
|
|
|
10784
11528
|
}
|
|
10785
11529
|
}
|
|
10786
11530
|
|
|
10787
|
-
// packages/cli/src/commands/_help-catalog.ts
|
|
10788
|
-
import pc4 from "picocolors";
|
|
10789
|
-
var PRIMARY_GROUPS = [
|
|
10790
|
-
{
|
|
10791
|
-
name: "init",
|
|
10792
|
-
summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
|
|
10793
|
-
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
10794
|
-
commands: [
|
|
10795
|
-
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
10796
|
-
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
10797
|
-
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
10798
|
-
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
10799
|
-
],
|
|
10800
|
-
examples: [
|
|
10801
|
-
"rig init",
|
|
10802
|
-
"rig init --yes --repo humanity-org/humanwork",
|
|
10803
|
-
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
10804
|
-
],
|
|
10805
|
-
next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
|
|
10806
|
-
},
|
|
10807
|
-
{
|
|
10808
|
-
name: "server",
|
|
10809
|
-
summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
|
|
10810
|
-
usage: ["rig server <status|list|add|use|start> [options]"],
|
|
10811
|
-
commands: [
|
|
10812
|
-
{ command: "status", description: "Show the selected server for this repo.", primary: true },
|
|
10813
|
-
{ command: "list", description: "List saved local/remote server aliases.", primary: true },
|
|
10814
|
-
{ command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
|
|
10815
|
-
{ command: "use [alias|local]", description: "Select a server; prompts in an interactive TTY.", primary: true },
|
|
10816
|
-
{ command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process.", primary: true }
|
|
10817
|
-
],
|
|
10818
|
-
examples: [
|
|
10819
|
-
"rig server status",
|
|
10820
|
-
"rig server add prod https://where.rig-does.work",
|
|
10821
|
-
"rig server use prod",
|
|
10822
|
-
"rig server use local",
|
|
10823
|
-
"rig server start --port 3773"
|
|
10824
|
-
],
|
|
10825
|
-
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
|
|
10826
|
-
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
10827
|
-
},
|
|
10828
|
-
{
|
|
10829
|
-
name: "task",
|
|
10830
|
-
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
10831
|
-
usage: ["rig task <list|next|show|run> [options]"],
|
|
10832
|
-
commands: [
|
|
10833
|
-
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
10834
|
-
{ command: "next [filters]", description: "Pick the next matching task.", primary: true },
|
|
10835
|
-
{ command: "show <id>|--task <id>", description: "Show task details.", primary: true },
|
|
10836
|
-
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
10837
|
-
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
10838
|
-
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
10839
|
-
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
10840
|
-
],
|
|
10841
|
-
examples: [
|
|
10842
|
-
"rig task list --assignee @me --limit 20",
|
|
10843
|
-
"rig task run --next",
|
|
10844
|
-
"rig task run #123 --runtime-adapter pi",
|
|
10845
|
-
"rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
|
|
10846
|
-
],
|
|
10847
|
-
next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
|
|
10848
|
-
},
|
|
10849
|
-
{
|
|
10850
|
-
name: "run",
|
|
10851
|
-
summary: "Observe, attach to, and control Rig runs.",
|
|
10852
|
-
usage: ["rig run <list|status|show|attach|stop> [options]"],
|
|
10853
|
-
commands: [
|
|
10854
|
-
{ command: "list", description: "List recent runs from the selected server or local state.", primary: true },
|
|
10855
|
-
{ command: "status", description: "Summarize active and recent runs.", primary: true },
|
|
10856
|
-
{ command: "show --run <id>", description: "Show one run record.", primary: true },
|
|
10857
|
-
{ command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; `--follow` launches native bundled Pi for live Pi runs.", primary: true },
|
|
10858
|
-
{ command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
|
|
10859
|
-
{ command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
|
|
10860
|
-
{ command: "delete|cleanup", description: "Remove completed run records/artifacts." }
|
|
10861
|
-
],
|
|
10862
|
-
examples: [
|
|
10863
|
-
"rig run list",
|
|
10864
|
-
"rig run attach 01234567-89ab-cdef-0123-456789abcdef --follow",
|
|
10865
|
-
"rig run show --run <run-id>",
|
|
10866
|
-
"rig run stop <run-id>"
|
|
10867
|
-
],
|
|
10868
|
-
next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
|
|
10869
|
-
}
|
|
10870
|
-
];
|
|
10871
|
-
var ADVANCED_GROUPS = [
|
|
10872
|
-
{ 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." }] },
|
|
10873
|
-
{ name: "github", summary: "GitHub auth helpers.", usage: ["rig github auth <status|import-gh|token>"], commands: [{ command: "auth status", description: "Show GitHub auth state." }] },
|
|
10874
|
-
{ name: "doctor", summary: "Diagnostics for project/server/GitHub/Pi state.", usage: ["rig doctor [check|run|shared|...]"], commands: [{ command: "check", description: "Run diagnostics." }] },
|
|
10875
|
-
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
10876
|
-
{ 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." }] },
|
|
10877
|
-
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
10878
|
-
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
10879
|
-
{ name: "review", summary: "Review policy configuration.", usage: ["rig review <show|set>"], commands: [{ command: "show", description: "Show review settings." }] },
|
|
10880
|
-
{ name: "browser", summary: "Browser/app diagnostics.", usage: ["rig browser <help|explain|demo|app>"], commands: [{ command: "help", description: "Browser command help." }] },
|
|
10881
|
-
{ name: "plugin", summary: "Plugin validation/listing.", usage: ["rig plugin <list|validate>"], commands: [{ command: "list", description: "List plugins." }] },
|
|
10882
|
-
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
10883
|
-
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
10884
|
-
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
10885
|
-
{ name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
|
|
10886
|
-
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
10887
|
-
{ name: "remote", summary: "Legacy remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
|
|
10888
|
-
{ name: "inbox", summary: "Approval/input inbox for blocked runs.", usage: ["rig inbox <approvals|approve|inputs|respond>"], commands: [{ command: "approvals", description: "List pending approvals." }] },
|
|
10889
|
-
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
10890
|
-
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
10891
|
-
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
10892
|
-
];
|
|
10893
|
-
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
10894
|
-
function heading(title) {
|
|
10895
|
-
return pc4.bold(pc4.cyan(title));
|
|
10896
|
-
}
|
|
10897
|
-
function commandLine(command, description) {
|
|
10898
|
-
const commandColumn = command.length >= 34 ? `${command} ` : command.padEnd(34);
|
|
10899
|
-
return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
|
|
10900
|
-
}
|
|
10901
|
-
function renderGroup(group) {
|
|
10902
|
-
const lines = [
|
|
10903
|
-
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
10904
|
-
"",
|
|
10905
|
-
pc4.bold("Usage"),
|
|
10906
|
-
...group.usage.map((line) => ` ${line}`),
|
|
10907
|
-
"",
|
|
10908
|
-
pc4.bold("Commands"),
|
|
10909
|
-
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
10910
|
-
];
|
|
10911
|
-
if (group.examples?.length) {
|
|
10912
|
-
lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
|
|
10913
|
-
}
|
|
10914
|
-
if (group.next?.length) {
|
|
10915
|
-
lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
10916
|
-
}
|
|
10917
|
-
if (group.advanced?.length) {
|
|
10918
|
-
lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
|
|
10919
|
-
}
|
|
10920
|
-
return lines.join(`
|
|
10921
|
-
`);
|
|
10922
|
-
}
|
|
10923
|
-
function renderTopLevelHelp() {
|
|
10924
|
-
return [
|
|
10925
|
-
`${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
10926
|
-
pc4.dim("A repo-local CLI for setup, server selection, task runs, live attach, and completion review."),
|
|
10927
|
-
"",
|
|
10928
|
-
`${pc4.bold(pc4.magenta("\u25C7 Start here"))} \u2014 ${pc4.dim("bootstrap a repo and choose where Rig runs")}`,
|
|
10929
|
-
commandLine("rig init", "Interactive setup: project config, GitHub auth, task source, server, checkout, Pi."),
|
|
10930
|
-
commandLine("rig init --yes", "Non-interactive setup using detected defaults; good for repeatable installs."),
|
|
10931
|
-
commandLine("rig server status", "Show whether this repo is using local Rig or a remote server."),
|
|
10932
|
-
commandLine("rig server use <alias|local>", "Switch the server that owns task/run state for this repo."),
|
|
10933
|
-
"",
|
|
10934
|
-
`${pc4.bold(pc4.magenta("\u25C7 Daily task loop"))} \u2014 ${pc4.dim("find work, start a worker, and rejoin it later")}`,
|
|
10935
|
-
commandLine("rig task list", "List tasks from the selected task source/server with status, labels, and source."),
|
|
10936
|
-
commandLine("rig task next", "Pick the next matching task without starting it."),
|
|
10937
|
-
commandLine("rig task run --next", "Start the next task and attach to the live bundled Pi frontend."),
|
|
10938
|
-
commandLine("rig task run #123 --detach", "Submit a specific issue/task and return immediately."),
|
|
10939
|
-
"",
|
|
10940
|
-
`${pc4.bold(pc4.magenta("\u25C7 Live run control"))} \u2014 ${pc4.dim("observe, steer, stop, or inspect active runs")}`,
|
|
10941
|
-
commandLine("rig run list", "Show recent/active runs from the selected server or local state."),
|
|
10942
|
-
commandLine("rig run attach <run-id> --follow", "Open the native Pi live view for a worker-backed run."),
|
|
10943
|
-
commandLine("rig run show --run <id>", "Print one run record; add `--json` for automation."),
|
|
10944
|
-
commandLine("rig run stop <run-id>", "Request cancellation for a running worker."),
|
|
10945
|
-
"",
|
|
10946
|
-
`${pc4.bold(pc4.magenta("\u25C7 Core groups"))} \u2014 ${pc4.dim("run `rig <group> --help` for detailed commands and examples")}`,
|
|
10947
|
-
...PRIMARY_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
10948
|
-
commandLine("doctor", "Diagnose project/server/GitHub/task/Pi wiring when setup or runs misbehave."),
|
|
10949
|
-
"",
|
|
10950
|
-
`${pc4.bold(pc4.magenta("\u25C7 More"))}`,
|
|
10951
|
-
commandLine("rig help --advanced", "Legacy, dev, diagnostics, browser, queue, agent, remote, git, harness commands."),
|
|
10952
|
-
commandLine("rig <group> --help", "Rich per-group help with usage, descriptions, examples, and next steps."),
|
|
10953
|
-
commandLine("rig --version", "Print the installed Rig CLI version."),
|
|
10954
|
-
"",
|
|
10955
|
-
`${pc4.bold(pc4.magenta("\u25C7 Global options"))}`,
|
|
10956
|
-
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
10957
|
-
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
10958
|
-
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
10959
|
-
].join(`
|
|
10960
|
-
`);
|
|
10961
|
-
}
|
|
10962
|
-
function renderAdvancedHelp() {
|
|
10963
|
-
return [
|
|
10964
|
-
`${heading("rig advanced")} \u2014 legacy, dev, and compatibility groups`,
|
|
10965
|
-
"",
|
|
10966
|
-
pc4.bold("Primary groups are still"),
|
|
10967
|
-
" init, server, task, run",
|
|
10968
|
-
"",
|
|
10969
|
-
pc4.bold("Advanced groups"),
|
|
10970
|
-
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
10971
|
-
"",
|
|
10972
|
-
pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, and `rig run` for day-to-day work.")
|
|
10973
|
-
].join(`
|
|
10974
|
-
`);
|
|
10975
|
-
}
|
|
10976
|
-
function renderGroupHelp(groupName) {
|
|
10977
|
-
const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
|
|
10978
|
-
return group ? renderGroup(group) : null;
|
|
10979
|
-
}
|
|
10980
|
-
|
|
10981
11531
|
// packages/cli/src/commands.ts
|
|
10982
11532
|
import { ensureProjectMainFreshBeforeRun as ensureProjectMainFreshBeforeRun2 } from "@rig/runtime/control-plane/project-main-pre-run-sync";
|
|
10983
11533
|
var TOP_LEVEL_ALIASES = {
|
|
@@ -10985,11 +11535,10 @@ var TOP_LEVEL_ALIASES = {
|
|
|
10985
11535
|
check: ["setup", "check"],
|
|
10986
11536
|
preflight: ["setup", "preflight"],
|
|
10987
11537
|
install: ["dist", "install"],
|
|
10988
|
-
"install-shell": ["setup", "install-agent-shell"],
|
|
10989
11538
|
status: ["run", "status"],
|
|
10990
11539
|
start: ["task", "run", "--next"],
|
|
10991
11540
|
"start-parallel": ["run", "start-parallel"],
|
|
10992
|
-
"start-serial": ["
|
|
11541
|
+
"start-serial": ["run", "start-serial"],
|
|
10993
11542
|
resume: ["run", "resume"],
|
|
10994
11543
|
stop: ["run", "stop"],
|
|
10995
11544
|
ready: ["task", "ready"],
|
|
@@ -11018,6 +11567,30 @@ var TOP_LEVEL_ALIASES = {
|
|
|
11018
11567
|
"remote-watch": ["remote", "watch"],
|
|
11019
11568
|
doctor: ["doctor", "check"]
|
|
11020
11569
|
};
|
|
11570
|
+
var PROJECT_REQUIRED_GROUPS = new Set([
|
|
11571
|
+
"task",
|
|
11572
|
+
"run",
|
|
11573
|
+
"inbox",
|
|
11574
|
+
"review",
|
|
11575
|
+
"queue",
|
|
11576
|
+
"agent",
|
|
11577
|
+
"repo",
|
|
11578
|
+
"inspect"
|
|
11579
|
+
]);
|
|
11580
|
+
var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
|
|
11581
|
+
function hasInitializedRigProject(projectRoot) {
|
|
11582
|
+
return RIG_CONFIG_FILENAMES.some((name) => existsSync14(resolve23(projectRoot, name))) || existsSync14(resolve23(projectRoot, ".rig"));
|
|
11583
|
+
}
|
|
11584
|
+
function requireInitializedRigProject(context, group) {
|
|
11585
|
+
if (hasInitializedRigProject(context.projectRoot)) {
|
|
11586
|
+
return;
|
|
11587
|
+
}
|
|
11588
|
+
throw new CliError2([
|
|
11589
|
+
`No Rig project found at ${context.projectRoot} (expected rig.config.ts or a .rig/ state directory).`,
|
|
11590
|
+
"Run `rig init` to set up this repo, or pass --project <path> to point at an existing Rig project."
|
|
11591
|
+
].join(`
|
|
11592
|
+
`), 2);
|
|
11593
|
+
}
|
|
11021
11594
|
var GROUPS = new Set([
|
|
11022
11595
|
"init",
|
|
11023
11596
|
"setup",
|
|
@@ -11045,7 +11618,7 @@ var GROUPS = new Set([
|
|
|
11045
11618
|
"test"
|
|
11046
11619
|
]);
|
|
11047
11620
|
function printGroupHelp(group) {
|
|
11048
|
-
|
|
11621
|
+
printGroupHelpDocument(group);
|
|
11049
11622
|
}
|
|
11050
11623
|
function isHelpArg(arg) {
|
|
11051
11624
|
return arg === "--help" || arg === "-h" || arg === "help";
|
|
@@ -11055,7 +11628,7 @@ function helpText() {
|
|
|
11055
11628
|
}
|
|
11056
11629
|
async function execute(context, args) {
|
|
11057
11630
|
if (args.length === 0) {
|
|
11058
|
-
|
|
11631
|
+
printTopLevelHelp();
|
|
11059
11632
|
return { ok: true, group: "help", command: "show" };
|
|
11060
11633
|
}
|
|
11061
11634
|
const [first, ...rest] = args;
|
|
@@ -11066,14 +11639,14 @@ ${helpText()}`);
|
|
|
11066
11639
|
}
|
|
11067
11640
|
if (first === "help" || first === "--help" || first === "-h") {
|
|
11068
11641
|
if (rest[0] === "--advanced") {
|
|
11069
|
-
|
|
11642
|
+
printAdvancedHelp();
|
|
11070
11643
|
return { ok: true, group: "help", command: "advanced" };
|
|
11071
11644
|
}
|
|
11072
11645
|
if (rest[0]) {
|
|
11073
|
-
|
|
11646
|
+
printGroupHelp(rest[0]);
|
|
11074
11647
|
return { ok: true, group: "help", command: rest[0] };
|
|
11075
11648
|
}
|
|
11076
|
-
|
|
11649
|
+
printTopLevelHelp();
|
|
11077
11650
|
return { ok: true, group: "help", command: "show" };
|
|
11078
11651
|
}
|
|
11079
11652
|
if (first === "--version" || first === "-V" || first === "version") {
|
|
@@ -11115,10 +11688,28 @@ ${helpText()}`);
|
|
|
11115
11688
|
}
|
|
11116
11689
|
return executeGroup(context, group, [command, ...aliasArgs, ...rest]);
|
|
11117
11690
|
}
|
|
11691
|
+
if (await matchesPluginCliCommand(context, first)) {
|
|
11692
|
+
return executeGroup(context, "plugin", ["run", first, ...rest]);
|
|
11693
|
+
}
|
|
11118
11694
|
throw new CliError2(`Unknown group or command: ${first}
|
|
11119
11695
|
|
|
11120
11696
|
${helpText()}`);
|
|
11121
11697
|
}
|
|
11698
|
+
async function matchesPluginCliCommand(context, requested) {
|
|
11699
|
+
if (!hasInitializedRigProject(context.projectRoot)) {
|
|
11700
|
+
return false;
|
|
11701
|
+
}
|
|
11702
|
+
try {
|
|
11703
|
+
const { buildPluginHostContext: buildPluginHostContext3 } = await import("@rig/runtime/control-plane/plugin-host-context");
|
|
11704
|
+
const hostCtx = await buildPluginHostContext3(context.projectRoot);
|
|
11705
|
+
if (!hostCtx)
|
|
11706
|
+
return false;
|
|
11707
|
+
const { resolvePluginCliCommand: resolvePluginCliCommand2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
|
|
11708
|
+
return Boolean(resolvePluginCliCommand2(hostCtx.pluginHost.listCliCommands(), requested));
|
|
11709
|
+
} catch {
|
|
11710
|
+
return false;
|
|
11711
|
+
}
|
|
11712
|
+
}
|
|
11122
11713
|
var GROUPS_WITH_CUSTOM_HELP = new Set(["browser"]);
|
|
11123
11714
|
async function executeGroup(context, group, args) {
|
|
11124
11715
|
if (isHelpArg(args[0]) && !GROUPS_WITH_CUSTOM_HELP.has(group)) {
|
|
@@ -11127,6 +11718,9 @@ async function executeGroup(context, group, args) {
|
|
|
11127
11718
|
}
|
|
11128
11719
|
return { ok: true, group, command: "help" };
|
|
11129
11720
|
}
|
|
11721
|
+
if (PROJECT_REQUIRED_GROUPS.has(group)) {
|
|
11722
|
+
requireInitializedRigProject(context, group);
|
|
11723
|
+
}
|
|
11130
11724
|
switch (group) {
|
|
11131
11725
|
case "setup":
|
|
11132
11726
|
return executeSetup(context, args);
|
|
@@ -11181,8 +11775,8 @@ async function executeGroup(context, group, args) {
|
|
|
11181
11775
|
}
|
|
11182
11776
|
}
|
|
11183
11777
|
// packages/cli/src/launcher.ts
|
|
11184
|
-
import { existsSync as
|
|
11185
|
-
import { basename as basename2, resolve as
|
|
11778
|
+
import { existsSync as existsSync15 } from "fs";
|
|
11779
|
+
import { basename as basename2, resolve as resolve24 } from "path";
|
|
11186
11780
|
import { loadDotEnvSecrets } from "@rig/runtime/baked-secrets";
|
|
11187
11781
|
import { RIG_DEFINITION_DIRNAME, RIG_STATE_DIRNAME, resolveNearestRigProjectRoot } from "@rig/runtime/layout";
|
|
11188
11782
|
function parsePolicyMode(value) {
|
|
@@ -11195,7 +11789,7 @@ function parsePolicyMode(value) {
|
|
|
11195
11789
|
throw new Error(`Invalid --policy-mode value: ${value}. Use off|observe|enforce.`);
|
|
11196
11790
|
}
|
|
11197
11791
|
function hasRigProjectMarker(candidate) {
|
|
11198
|
-
return
|
|
11792
|
+
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"));
|
|
11199
11793
|
}
|
|
11200
11794
|
function resolveProjectRoot({
|
|
11201
11795
|
envProjectRoot,
|
|
@@ -11204,19 +11798,19 @@ function resolveProjectRoot({
|
|
|
11204
11798
|
cwd = process.cwd()
|
|
11205
11799
|
}) {
|
|
11206
11800
|
if (envProjectRoot) {
|
|
11207
|
-
return
|
|
11801
|
+
return resolve24(cwd, envProjectRoot);
|
|
11208
11802
|
}
|
|
11209
11803
|
const fallbackImportDir = importDir ?? cwd;
|
|
11210
11804
|
const execName = basename2(execPath).toLowerCase();
|
|
11211
|
-
const execCandidates = execName === "rig" || execName === "rig.exe" ? [
|
|
11212
|
-
const candidates = [cwd, ...execCandidates,
|
|
11805
|
+
const execCandidates = execName === "rig" || execName === "rig.exe" ? [resolve24(execPath, "..", "..")] : [];
|
|
11806
|
+
const candidates = [cwd, ...execCandidates, resolve24(fallbackImportDir, "..")];
|
|
11213
11807
|
for (const candidate of candidates) {
|
|
11214
11808
|
const nearest = resolveNearestRigProjectRoot(candidate);
|
|
11215
11809
|
if (hasRigProjectMarker(nearest)) {
|
|
11216
11810
|
return nearest;
|
|
11217
11811
|
}
|
|
11218
11812
|
}
|
|
11219
|
-
return
|
|
11813
|
+
return resolve24(cwd);
|
|
11220
11814
|
}
|
|
11221
11815
|
function normalizeCliErrorCode(message2, isCliError) {
|
|
11222
11816
|
if (message2.startsWith("Invalid --policy-mode value:")) {
|
|
@@ -11283,7 +11877,7 @@ async function runRigCli(module, options = {}) {
|
|
|
11283
11877
|
runId: context.runId,
|
|
11284
11878
|
outcome,
|
|
11285
11879
|
eventsFile: context.eventBus.getEventsFile(),
|
|
11286
|
-
policyFile:
|
|
11880
|
+
policyFile: resolve24(projectRoot, "rig", "policy", "policy.json"),
|
|
11287
11881
|
policyMode: context.policyMode ?? policyMode ?? module.loadPolicy(projectRoot).mode
|
|
11288
11882
|
}, null, 2));
|
|
11289
11883
|
}
|
|
@@ -11305,6 +11899,10 @@ function hydrateProcessEnvFromDotEnv(projectRoot) {
|
|
|
11305
11899
|
}
|
|
11306
11900
|
}
|
|
11307
11901
|
}
|
|
11902
|
+
|
|
11903
|
+
// packages/cli/src/index.ts
|
|
11904
|
+
init_runner();
|
|
11905
|
+
|
|
11308
11906
|
// packages/cli/bin/rig.ts
|
|
11309
11907
|
var rigCliModule = {
|
|
11310
11908
|
CliError: CliError2,
|