@h-rig/cli 0.0.6-alpha.64 → 0.0.6-alpha.66
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 +1349 -1599
- package/dist/src/commands/_connection-state.js +14 -5
- package/dist/src/commands/_doctor-checks.js +71 -11
- package/dist/src/commands/_help-catalog.js +99 -60
- package/dist/src/commands/_json-output.js +56 -0
- package/dist/src/commands/_operator-view.js +97 -784
- package/dist/src/commands/_parsers.js +18 -9
- package/dist/src/commands/_pi-frontend.js +96 -788
- package/dist/src/commands/_policy.js +12 -3
- package/dist/src/commands/_preflight.js +73 -13
- package/dist/src/commands/_run-driver-helpers.js +31 -5
- package/dist/src/commands/_run-replay.js +2 -2
- package/dist/src/commands/_server-client.js +76 -16
- package/dist/src/commands/_snapshot-upload.js +70 -10
- package/dist/src/commands/agent.js +21 -11
- package/dist/src/commands/browser.js +24 -15
- package/dist/src/commands/connect.js +22 -17
- package/dist/src/commands/dist.js +15 -6
- package/dist/src/commands/doctor.js +70 -10
- package/dist/src/commands/github.js +79 -19
- package/dist/src/commands/inbox.js +215 -131
- package/dist/src/commands/init.js +202 -35
- package/dist/src/commands/inspect.js +77 -17
- package/dist/src/commands/inspector.js +18 -9
- package/dist/src/commands/pi.js +18 -9
- package/dist/src/commands/plugin.js +19 -10
- package/dist/src/commands/profile-and-review.js +22 -13
- package/dist/src/commands/queue.js +19 -9
- package/dist/src/commands/remote.js +25 -16
- package/dist/src/commands/repo-git-harness.js +18 -9
- package/dist/src/commands/run.js +158 -805
- package/dist/src/commands/server.js +85 -25
- package/dist/src/commands/setup.js +73 -13
- package/dist/src/commands/stats.js +681 -0
- package/dist/src/commands/task-report-bug.js +24 -15
- package/dist/src/commands/task-run-driver.js +121 -49
- package/dist/src/commands/task.js +254 -893
- package/dist/src/commands/test.js +12 -3
- package/dist/src/commands/workspace.js +14 -5
- package/dist/src/commands.js +1339 -1650
- package/dist/src/index.js +1349 -1599
- package/dist/src/launcher.js +72 -10
- package/dist/src/runner.js +14 -5
- package/package.json +10 -7
- package/dist/src/commands/_pi-remote-session.js +0 -771
- package/dist/src/commands/_pi-worker-bridge-extension.js +0 -834
|
@@ -6,10 +6,19 @@ import { dirname, resolve } from "path";
|
|
|
6
6
|
|
|
7
7
|
// packages/cli/src/runner.ts
|
|
8
8
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
9
|
-
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
9
|
+
import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
|
|
10
10
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
11
11
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
class CliError extends RuntimeCliError {
|
|
14
|
+
hint;
|
|
15
|
+
constructor(message, exitCode = 1, options = {}) {
|
|
16
|
+
super(message, exitCode);
|
|
17
|
+
if (options.hint?.trim()) {
|
|
18
|
+
this.hint = options.hint.trim();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
13
22
|
|
|
14
23
|
// packages/cli/src/commands/_connection-state.ts
|
|
15
24
|
function resolveGlobalConnectionsPath(env = process.env) {
|
|
@@ -30,7 +39,7 @@ function readJsonFile(path) {
|
|
|
30
39
|
try {
|
|
31
40
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
32
41
|
} catch (error) {
|
|
33
|
-
throw new
|
|
42
|
+
throw new CliError(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1, { hint: "Fix or delete that file, then re-select a server with `rig server use <alias|local>`." });
|
|
34
43
|
}
|
|
35
44
|
}
|
|
36
45
|
function writeJsonFile(path, value) {
|
|
@@ -73,7 +82,7 @@ function writeGlobalConnections(state, options = {}) {
|
|
|
73
82
|
function upsertGlobalConnection(alias, connection, options = {}) {
|
|
74
83
|
const cleanAlias = alias.trim();
|
|
75
84
|
if (!cleanAlias)
|
|
76
|
-
throw new
|
|
85
|
+
throw new CliError("Connection alias is required.", 1, { hint: "Save a server with `rig server add <alias> <url>`." });
|
|
77
86
|
const state = readGlobalConnections(options);
|
|
78
87
|
state.connections[cleanAlias] = connection;
|
|
79
88
|
writeGlobalConnections(state, options);
|
|
@@ -106,7 +115,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
106
115
|
const global = readGlobalConnections(options);
|
|
107
116
|
const connection = global.connections[repo.selected];
|
|
108
117
|
if (!connection) {
|
|
109
|
-
throw new
|
|
118
|
+
throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
110
119
|
}
|
|
111
120
|
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
112
121
|
}
|
|
@@ -7,10 +7,19 @@ import { resolve as resolve4 } from "path";
|
|
|
7
7
|
|
|
8
8
|
// packages/cli/src/runner.ts
|
|
9
9
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
10
|
-
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
10
|
+
import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
|
|
11
11
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
12
12
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
class CliError extends RuntimeCliError {
|
|
15
|
+
hint;
|
|
16
|
+
constructor(message, exitCode = 1, options = {}) {
|
|
17
|
+
super(message, exitCode);
|
|
18
|
+
if (options.hint?.trim()) {
|
|
19
|
+
this.hint = options.hint.trim();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
14
23
|
|
|
15
24
|
// packages/cli/src/commands/_doctor-checks.ts
|
|
16
25
|
import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
|
|
@@ -37,7 +46,7 @@ function readJsonFile(path) {
|
|
|
37
46
|
try {
|
|
38
47
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
39
48
|
} catch (error) {
|
|
40
|
-
throw new
|
|
49
|
+
throw new CliError(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1, { hint: "Fix or delete that file, then re-select a server with `rig server use <alias|local>`." });
|
|
41
50
|
}
|
|
42
51
|
}
|
|
43
52
|
function writeJsonFile(path, value) {
|
|
@@ -101,7 +110,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
101
110
|
const global = readGlobalConnections(options);
|
|
102
111
|
const connection = global.connections[repo.selected];
|
|
103
112
|
if (!connection) {
|
|
104
|
-
throw new
|
|
113
|
+
throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
105
114
|
}
|
|
106
115
|
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
107
116
|
}
|
|
@@ -177,7 +186,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
177
186
|
};
|
|
178
187
|
} catch (error) {
|
|
179
188
|
if (error instanceof Error) {
|
|
180
|
-
throw new
|
|
189
|
+
throw new CliError(error.message, 1);
|
|
181
190
|
}
|
|
182
191
|
throw error;
|
|
183
192
|
}
|
|
@@ -227,15 +236,64 @@ function diagnosticMessage(payload) {
|
|
|
227
236
|
});
|
|
228
237
|
return messages.length > 0 ? messages.join("; ") : null;
|
|
229
238
|
}
|
|
239
|
+
var serverReachabilityCache = new Map;
|
|
240
|
+
async function probeServerReachability(baseUrl, authToken) {
|
|
241
|
+
try {
|
|
242
|
+
const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/server/status`, {
|
|
243
|
+
headers: mergeHeaders(undefined, authToken),
|
|
244
|
+
signal: AbortSignal.timeout(1500)
|
|
245
|
+
});
|
|
246
|
+
return response.ok;
|
|
247
|
+
} catch {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function cachedServerReachability(projectRoot, baseUrl, authToken) {
|
|
252
|
+
const key = resolve2(projectRoot);
|
|
253
|
+
const cached = serverReachabilityCache.get(key);
|
|
254
|
+
if (cached)
|
|
255
|
+
return cached;
|
|
256
|
+
const probe = probeServerReachability(baseUrl, authToken);
|
|
257
|
+
serverReachabilityCache.set(key, probe);
|
|
258
|
+
return probe;
|
|
259
|
+
}
|
|
260
|
+
function describeSelectedServer(projectRoot, server) {
|
|
261
|
+
try {
|
|
262
|
+
const selected = resolveSelectedConnection(projectRoot);
|
|
263
|
+
if (selected) {
|
|
264
|
+
return {
|
|
265
|
+
alias: selected.alias,
|
|
266
|
+
target: selected.connection.kind === "remote" ? selected.connection.baseUrl : server.baseUrl
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
} catch {}
|
|
270
|
+
return { alias: server.connectionKind === "remote" ? "remote" : "local", target: server.baseUrl };
|
|
271
|
+
}
|
|
272
|
+
async function buildServerFailureContext(projectRoot, server) {
|
|
273
|
+
const { alias, target } = describeSelectedServer(projectRoot, server);
|
|
274
|
+
const reachable = await cachedServerReachability(projectRoot, server.baseUrl, server.authToken);
|
|
275
|
+
const reachability = reachable ? "server is reachable" : "server is unreachable";
|
|
276
|
+
return {
|
|
277
|
+
contextLine: `Currently connected to: ${alias} at ${target} (${reachability}).`,
|
|
278
|
+
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
279
|
+
};
|
|
280
|
+
}
|
|
230
281
|
async function requestServerJson(context, pathname, init = {}) {
|
|
231
282
|
const server = await ensureServerForCli(context.projectRoot);
|
|
232
283
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
233
284
|
if (server.serverProjectRoot)
|
|
234
285
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
286
|
+
let response;
|
|
287
|
+
try {
|
|
288
|
+
response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
289
|
+
...init,
|
|
290
|
+
headers
|
|
291
|
+
});
|
|
292
|
+
} catch (error) {
|
|
293
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
294
|
+
throw new CliError(`Rig server request failed: ${error instanceof Error ? error.message : String(error)}
|
|
295
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
296
|
+
}
|
|
239
297
|
const text = await response.text();
|
|
240
298
|
const payload = text.trim().length > 0 ? (() => {
|
|
241
299
|
try {
|
|
@@ -247,7 +305,9 @@ async function requestServerJson(context, pathname, init = {}) {
|
|
|
247
305
|
if (!response.ok) {
|
|
248
306
|
const diagnostics = diagnosticMessage(payload);
|
|
249
307
|
const detail = diagnostics ?? (text || response.statusText);
|
|
250
|
-
|
|
308
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
309
|
+
throw new CliError(`Rig server request failed (${response.status}): ${detail}
|
|
310
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
251
311
|
}
|
|
252
312
|
return payload;
|
|
253
313
|
}
|
|
@@ -553,7 +613,7 @@ function countDoctorFailures(checks) {
|
|
|
553
613
|
function throwIfDoctorFailed(checks) {
|
|
554
614
|
const failures = countDoctorFailures(checks);
|
|
555
615
|
if (failures > 0) {
|
|
556
|
-
throw new
|
|
616
|
+
throw new CliError(`Doctor failed (${failures} failing check${failures === 1 ? "" : "s"}).`, 1);
|
|
557
617
|
}
|
|
558
618
|
}
|
|
559
619
|
export {
|
|
@@ -5,49 +5,47 @@ import pc from "picocolors";
|
|
|
5
5
|
var TOP_LEVEL_SECTIONS = [
|
|
6
6
|
{
|
|
7
7
|
title: "Start here",
|
|
8
|
-
subtitle: "one-time setup
|
|
8
|
+
subtitle: "one-time setup, pick a server",
|
|
9
9
|
commands: [
|
|
10
10
|
{ command: "rig init", description: "Wizard: config, GitHub auth, task source, server, Pi wiring." },
|
|
11
|
-
{ command: "rig
|
|
12
|
-
{ command: "rig server
|
|
11
|
+
{ command: "rig server use <alias|local>", description: "Pick which Rig server owns this repo (`rig server list` to see them)." },
|
|
12
|
+
{ command: "rig server status", description: "Show the selected server for this repo." }
|
|
13
13
|
]
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
title: "Work",
|
|
17
|
-
subtitle: "find a task
|
|
17
|
+
subtitle: "find a task, put an agent on it, answer what it asks",
|
|
18
18
|
commands: [
|
|
19
19
|
{ command: "rig task list", description: "What's on the board (from the selected source/server)." },
|
|
20
|
-
{ command: "rig task next", description: "The next ready task, as a card." },
|
|
21
20
|
{ command: "rig task run --next", description: "Dispatch an agent; interactive mode opens the native Pi session." },
|
|
22
|
-
{ command: "rig
|
|
21
|
+
{ command: "rig run status", description: "Active and recent runs at a glance." },
|
|
22
|
+
{ command: "rig run attach <id> --follow", description: "Join the live Pi session (worker keeps running if you /detach)." },
|
|
23
|
+
{ command: "rig inbox approvals", description: "Approvals workers are waiting on (then `rig inbox approve \u2026`)." }
|
|
23
24
|
]
|
|
24
25
|
},
|
|
25
26
|
{
|
|
26
|
-
title: "Watch
|
|
27
|
-
subtitle: "
|
|
27
|
+
title: "Watch",
|
|
28
|
+
subtitle: "fleet metrics and per-task forensics",
|
|
28
29
|
commands: [
|
|
29
|
-
{ command: "rig
|
|
30
|
-
{ command: "rig
|
|
31
|
-
{ command: "rig
|
|
32
|
-
{ command: "rig run stop <id>", description: "Cancel a running worker." }
|
|
30
|
+
{ command: "rig stats [--since 7d]", description: "Fleet metrics: completion/failure rates, median run time, steering, stalls." },
|
|
31
|
+
{ command: "rig inspect logs --task <id>", description: "Latest run log for a task." },
|
|
32
|
+
{ command: "rig inspect diff --task <id>", description: "Changed files for a task." }
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
title: "Unblock
|
|
37
|
-
subtitle: "
|
|
36
|
+
title: "Unblock",
|
|
37
|
+
subtitle: "diagnose wiring, fix auth",
|
|
38
38
|
commands: [
|
|
39
|
-
{ command: "rig
|
|
40
|
-
{ command: "rig
|
|
41
|
-
{ command: "rig review show|set", description: "The completion review gate (Greptile is mandatory on merges)." }
|
|
39
|
+
{ command: "rig doctor", description: "Check every part of the wiring \u2014 run this when anything feels off." },
|
|
40
|
+
{ command: "rig github auth status", description: "GitHub auth state on the selected server." }
|
|
42
41
|
]
|
|
43
42
|
},
|
|
44
43
|
{
|
|
45
44
|
title: "Extend",
|
|
46
|
-
subtitle: "
|
|
45
|
+
subtitle: "plugins contribute validators, hooks, task sources, commands",
|
|
47
46
|
commands: [
|
|
48
|
-
{ command: "rig
|
|
49
|
-
{ command: "rig
|
|
50
|
-
{ command: "rig plugin list", description: "What the rig.config.ts plugins contribute." }
|
|
47
|
+
{ command: "rig plugin list", description: "What the rig.config.ts plugins contribute." },
|
|
48
|
+
{ command: "rig plugin run <command-id>", description: "Execute a plugin-contributed CLI command." }
|
|
51
49
|
]
|
|
52
50
|
}
|
|
53
51
|
];
|
|
@@ -71,22 +69,20 @@ var PRIMARY_GROUPS = [
|
|
|
71
69
|
"rig server use local",
|
|
72
70
|
"rig server start --port 3773"
|
|
73
71
|
],
|
|
74
|
-
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."]
|
|
75
|
-
advanced: ["Compatibility alias: `rig connect ...` remains callable."]
|
|
72
|
+
next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."]
|
|
76
73
|
},
|
|
77
74
|
{
|
|
78
75
|
name: "task",
|
|
79
76
|
summary: "Find work, start Pi-backed runs, and validate task results.",
|
|
80
77
|
usage: ["rig task <list|next|show|run> [options]"],
|
|
81
78
|
commands: [
|
|
82
|
-
{ command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
79
|
+
{ command: "list [--assignee <login|me|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
|
|
83
80
|
{ command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
|
|
84
81
|
{ command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
|
|
85
82
|
{ command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
|
|
86
83
|
{ command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
|
|
87
84
|
{ command: "details --task <id>", description: "Show full task info from the configured source." },
|
|
88
85
|
{ command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
|
|
89
|
-
{ command: "reset --task <id>", description: "Compatibility spelling of `reopen --task <id>`." },
|
|
90
86
|
{ command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
|
|
91
87
|
{ command: "report-bug", description: "Create a structured bug report/task." }
|
|
92
88
|
],
|
|
@@ -144,15 +140,54 @@ var PRIMARY_GROUPS = [
|
|
|
144
140
|
next: ["Rejoin the run after resolving a block: `rig run attach <run-id> --follow`."]
|
|
145
141
|
},
|
|
146
142
|
{
|
|
147
|
-
name: "
|
|
148
|
-
summary: "
|
|
149
|
-
usage: ["rig
|
|
143
|
+
name: "stats",
|
|
144
|
+
summary: "Fleet metrics computed from on-disk run journals (no server required).",
|
|
145
|
+
usage: ["rig stats [show] [--since <7d|30d|ISO date>]"],
|
|
150
146
|
commands: [
|
|
151
|
-
{ command: "show", description: "
|
|
152
|
-
{ command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider.", primary: true }
|
|
147
|
+
{ command: "show [--since <window>]", description: "Total runs, completion/failure/needs-attention rates, median run time, steering, stalls, approvals.", primary: true }
|
|
153
148
|
],
|
|
154
|
-
examples: [
|
|
155
|
-
|
|
149
|
+
examples: [
|
|
150
|
+
"rig stats",
|
|
151
|
+
"rig stats --since 7d",
|
|
152
|
+
"rig stats --since 2026-06-01 --json"
|
|
153
|
+
],
|
|
154
|
+
next: ["Inspect outliers with `rig run list` and `rig run show <run-id>`.", "Use `--json` for the schema'd envelope (see docs/cli-json.md)."]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "inspect",
|
|
158
|
+
summary: "Inspect logs, artifacts, graphs, failures for a task.",
|
|
159
|
+
usage: ["rig inspect <logs|artifacts|failures|graph|audit|diff> --task <id>"],
|
|
160
|
+
commands: [
|
|
161
|
+
{ command: "logs --task <id>", description: "Latest run log for a task (local or selected server).", primary: true },
|
|
162
|
+
{ command: "artifacts --task <id>", description: "List the task's completion artifacts.", primary: true },
|
|
163
|
+
{ command: "failures --task <id>", description: "Recorded failures for a task.", primary: true },
|
|
164
|
+
{ command: "diff --task <id>", description: "Changed files for a task.", primary: true },
|
|
165
|
+
{ command: "graph", description: "Task dependency graph." },
|
|
166
|
+
{ command: "audit", description: "Controlled-command audit trail." }
|
|
167
|
+
],
|
|
168
|
+
examples: ["rig inspect logs --task <id>", "rig inspect diff --task <id>"],
|
|
169
|
+
next: ["Use `rig stats` for fleet-level metrics across runs."]
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: "repo",
|
|
173
|
+
summary: "Repository sync/baseline helpers for the Rig-managed checkout.",
|
|
174
|
+
usage: ["rig repo <sync|reset-baseline>"],
|
|
175
|
+
commands: [
|
|
176
|
+
{ command: "sync", description: "Sync project repository state.", primary: true },
|
|
177
|
+
{ command: "reset-baseline", description: "Reset the managed baseline for the repo." }
|
|
178
|
+
],
|
|
179
|
+
examples: ["rig repo sync"]
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: "plugin",
|
|
183
|
+
summary: "Plugin listing, validation, and plugin-contributed commands.",
|
|
184
|
+
usage: ["rig plugin <list|validate|run> [options]"],
|
|
185
|
+
commands: [
|
|
186
|
+
{ command: "list", description: "List plugins declared in rig.config.ts and their contributions.", primary: true },
|
|
187
|
+
{ command: "validate --task <id>", description: "Run plugin-contributed validators for a task.", primary: true },
|
|
188
|
+
{ command: "run <command-id> [args...]", description: "Execute a plugin-contributed CLI command (also callable as `rig <command-id>`)." }
|
|
189
|
+
],
|
|
190
|
+
examples: ["rig plugin list", "rig plugin run <command-id>"]
|
|
156
191
|
},
|
|
157
192
|
{
|
|
158
193
|
name: "init",
|
|
@@ -160,12 +195,14 @@ var PRIMARY_GROUPS = [
|
|
|
160
195
|
usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
|
|
161
196
|
commands: [
|
|
162
197
|
{ command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
|
|
198
|
+
{ command: "init --demo", description: "Offline demo project: files task source + 3 sample tasks, zero GitHub.", primary: true },
|
|
163
199
|
{ command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
|
|
164
200
|
{ command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
|
|
165
201
|
{ command: "init --repair", description: "Repair missing private state without replacing project config." }
|
|
166
202
|
],
|
|
167
203
|
examples: [
|
|
168
204
|
"rig init",
|
|
205
|
+
"rig init --demo",
|
|
169
206
|
"rig init --yes --repo humanity-org/humanwork",
|
|
170
207
|
"rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
|
|
171
208
|
],
|
|
@@ -196,23 +233,19 @@ var PRIMARY_GROUPS = [
|
|
|
196
233
|
}
|
|
197
234
|
];
|
|
198
235
|
var ADVANCED_GROUPS = [
|
|
199
|
-
{ 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." }] },
|
|
200
236
|
{ name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
|
|
237
|
+
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
201
238
|
{
|
|
202
|
-
name: "
|
|
203
|
-
summary: "Inspect
|
|
204
|
-
usage: ["rig
|
|
239
|
+
name: "review",
|
|
240
|
+
summary: "Inspect or change completion review gate policy.",
|
|
241
|
+
usage: ["rig review <show|set>"],
|
|
205
242
|
commands: [
|
|
206
|
-
{ command: "
|
|
207
|
-
{ command: "
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
{ command: "diff --task <id>", description: "Changed files for a task." }
|
|
212
|
-
]
|
|
243
|
+
{ command: "show", description: "Show current review gate settings." },
|
|
244
|
+
{ command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider." }
|
|
245
|
+
],
|
|
246
|
+
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
247
|
+
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
213
248
|
},
|
|
214
|
-
{ name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
|
|
215
|
-
{ name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
|
|
216
249
|
{
|
|
217
250
|
name: "browser",
|
|
218
251
|
summary: "Browser/app diagnostics for browser-required tasks.",
|
|
@@ -238,16 +271,6 @@ var ADVANCED_GROUPS = [
|
|
|
238
271
|
examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
|
|
239
272
|
next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
|
|
240
273
|
},
|
|
241
|
-
{
|
|
242
|
-
name: "plugin",
|
|
243
|
-
summary: "Plugin listing, validation, and plugin-contributed commands.",
|
|
244
|
-
usage: ["rig plugin <list|validate|run> [options]"],
|
|
245
|
-
commands: [
|
|
246
|
-
{ command: "list", description: "List plugins declared in rig.config.ts and their contributions." },
|
|
247
|
-
{ command: "validate --task <id>", description: "Run plugin-contributed validators for a task." },
|
|
248
|
-
{ command: "run <command-id> [args...]", description: "Execute a plugin-contributed CLI command (also callable as `rig <command-id>`)." }
|
|
249
|
-
]
|
|
250
|
-
},
|
|
251
274
|
{ name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
|
|
252
275
|
{ name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
|
|
253
276
|
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
@@ -320,7 +343,7 @@ function renderGroup(group) {
|
|
|
320
343
|
function renderTopLevelHelp() {
|
|
321
344
|
return [
|
|
322
345
|
`${heading("rig")} ${pc.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
323
|
-
pc.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox
|
|
346
|
+
pc.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox gates."),
|
|
324
347
|
"",
|
|
325
348
|
...TOP_LEVEL_SECTIONS.flatMap((section) => [
|
|
326
349
|
`${pc.bold(pc.magenta(`\u25C7 ${section.title}`))} \u2014 ${pc.dim(section.subtitle)}`,
|
|
@@ -341,7 +364,7 @@ function renderAdvancedHelp() {
|
|
|
341
364
|
`${heading("rig advanced")} \u2014 compatibility, diagnostics, and internal surfaces`,
|
|
342
365
|
"",
|
|
343
366
|
pc.bold("Primary groups"),
|
|
344
|
-
" server, task, run, inbox,
|
|
367
|
+
" init, server, task, run, inbox, repo, plugin, inspect, stats, doctor, github",
|
|
345
368
|
"",
|
|
346
369
|
pc.bold("Advanced commands"),
|
|
347
370
|
...ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)),
|
|
@@ -349,7 +372,7 @@ function renderAdvancedHelp() {
|
|
|
349
372
|
pc.bold("Advanced groups"),
|
|
350
373
|
...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
|
|
351
374
|
"",
|
|
352
|
-
pc.dim("All groups remain callable. Prefer `rig server`, `rig task`, `rig run`,
|
|
375
|
+
pc.dim("All groups remain callable. Prefer `rig server`, `rig task`, `rig run`, and `rig inbox` for day-to-day work.")
|
|
353
376
|
].join(`
|
|
354
377
|
`);
|
|
355
378
|
}
|
|
@@ -360,6 +383,21 @@ function renderGroupHelp(groupName) {
|
|
|
360
383
|
function listHelpGroups() {
|
|
361
384
|
return ALL_GROUPS.map((group) => group.name);
|
|
362
385
|
}
|
|
386
|
+
function suggestGroupCommandForWord(word) {
|
|
387
|
+
const normalized = word.trim().toLowerCase();
|
|
388
|
+
if (!normalized)
|
|
389
|
+
return null;
|
|
390
|
+
for (const group of ALL_GROUPS) {
|
|
391
|
+
for (const entry of group.commands) {
|
|
392
|
+
const firstToken = entry.command.split(/\s+/)[0] ?? "";
|
|
393
|
+
const names = firstToken.split("|").map((name) => name.trim().toLowerCase());
|
|
394
|
+
if (names.includes(normalized)) {
|
|
395
|
+
return `rig ${group.name} ${normalized}`;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
363
401
|
function shouldUseClackOutput() {
|
|
364
402
|
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
365
403
|
}
|
|
@@ -392,7 +430,7 @@ function printTopLevelHelp(state = {}) {
|
|
|
392
430
|
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
393
431
|
].join(`
|
|
394
432
|
`), "Global options");
|
|
395
|
-
outro("init \u2192 task run \u2192 watch
|
|
433
|
+
outro("init \u2192 task run \u2192 watch \u2192 inbox \u2192 merged.");
|
|
396
434
|
}
|
|
397
435
|
function printAdvancedHelp() {
|
|
398
436
|
if (!shouldUseClackOutput()) {
|
|
@@ -404,7 +442,7 @@ function printAdvancedHelp() {
|
|
|
404
442
|
`), "Advanced commands");
|
|
405
443
|
note(ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)).join(`
|
|
406
444
|
`), "Advanced groups");
|
|
407
|
-
outro("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox
|
|
445
|
+
outro("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox.");
|
|
408
446
|
}
|
|
409
447
|
function printGroupHelpDocument(groupName) {
|
|
410
448
|
const rendered = renderGroupHelp(groupName) ?? renderTopLevelHelp();
|
|
@@ -435,6 +473,7 @@ function printGroupHelpDocument(groupName) {
|
|
|
435
473
|
outro("Run with --json when scripts need structured output.");
|
|
436
474
|
}
|
|
437
475
|
export {
|
|
476
|
+
suggestGroupCommandForWord,
|
|
438
477
|
renderTopLevelHelp,
|
|
439
478
|
renderRigBanner,
|
|
440
479
|
renderGroupHelp,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/cli/src/commands/_json-output.ts
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
import {
|
|
5
|
+
RigDoctorCheckOutput,
|
|
6
|
+
RigInboxApprovalsOutput,
|
|
7
|
+
RigInboxInputsOutput,
|
|
8
|
+
RigRunListOutput,
|
|
9
|
+
RigRunShowOutput,
|
|
10
|
+
RigServerStatusOutput,
|
|
11
|
+
RigStatsOutput,
|
|
12
|
+
RigTaskListOutput,
|
|
13
|
+
RigTaskShowOutput
|
|
14
|
+
} from "@rig/contracts";
|
|
15
|
+
var CLI_OUTPUT_SCHEMAS = {
|
|
16
|
+
"task list": RigTaskListOutput,
|
|
17
|
+
"task show": RigTaskShowOutput,
|
|
18
|
+
"run list": RigRunListOutput,
|
|
19
|
+
"run show": RigRunShowOutput,
|
|
20
|
+
"server status": RigServerStatusOutput,
|
|
21
|
+
"inbox approvals": RigInboxApprovalsOutput,
|
|
22
|
+
"inbox inputs": RigInboxInputsOutput,
|
|
23
|
+
"doctor check": RigDoctorCheckOutput,
|
|
24
|
+
"stats show": RigStatsOutput
|
|
25
|
+
};
|
|
26
|
+
function isCommandOutcomeLike(value) {
|
|
27
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
28
|
+
return false;
|
|
29
|
+
const record = value;
|
|
30
|
+
return typeof record.group === "string" && typeof record.command === "string";
|
|
31
|
+
}
|
|
32
|
+
function buildCliJsonEnvelope(outcome, options = {}) {
|
|
33
|
+
if (!isCommandOutcomeLike(outcome))
|
|
34
|
+
return null;
|
|
35
|
+
const commandKey = `${outcome.group} ${outcome.command}`;
|
|
36
|
+
const schema = CLI_OUTPUT_SCHEMAS[commandKey];
|
|
37
|
+
if (!schema)
|
|
38
|
+
return null;
|
|
39
|
+
const warn = options.warn ?? ((message) => console.error(message));
|
|
40
|
+
const envelope = { v: 1, command: commandKey, data: outcome.details ?? {} };
|
|
41
|
+
try {
|
|
42
|
+
Schema.decodeUnknownSync(schema)(JSON.parse(JSON.stringify(envelope)));
|
|
43
|
+
return envelope;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
warn(`[rig] --json output for "${commandKey}" failed schema validation; printing legacy payload. ` + `(${error instanceof Error ? error.message.split(`
|
|
46
|
+
`)[0] : String(error)})`);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function listSchematizedCliCommands() {
|
|
51
|
+
return Object.keys(CLI_OUTPUT_SCHEMAS).sort();
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
listSchematizedCliCommands,
|
|
55
|
+
buildCliJsonEnvelope
|
|
56
|
+
};
|