@h-rig/cli 0.0.6-alpha.28 → 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.
Files changed (40) hide show
  1. package/dist/bin/rig.js +421 -241
  2. package/dist/src/commands/_connection-state.js +0 -2
  3. package/dist/src/commands/_doctor-checks.js +0 -2
  4. package/dist/src/commands/_help-catalog.js +27 -3
  5. package/dist/src/commands/_operator-view.js +0 -2
  6. package/dist/src/commands/_parsers.js +0 -2
  7. package/dist/src/commands/_pi-frontend.js +0 -2
  8. package/dist/src/commands/_pi-worker-bridge-extension.js +0 -2
  9. package/dist/src/commands/_policy.js +0 -2
  10. package/dist/src/commands/_preflight.js +0 -2
  11. package/dist/src/commands/_run-driver-helpers.js +0 -2
  12. package/dist/src/commands/_server-client.js +0 -2
  13. package/dist/src/commands/_snapshot-upload.js +0 -2
  14. package/dist/src/commands/agent.js +0 -2
  15. package/dist/src/commands/browser.js +0 -2
  16. package/dist/src/commands/connect.js +0 -2
  17. package/dist/src/commands/dist.js +0 -2
  18. package/dist/src/commands/doctor.js +0 -2
  19. package/dist/src/commands/github.js +0 -2
  20. package/dist/src/commands/inbox.js +0 -2
  21. package/dist/src/commands/init.js +0 -2
  22. package/dist/src/commands/inspect.js +0 -2
  23. package/dist/src/commands/inspector.js +0 -2
  24. package/dist/src/commands/plugin.js +73 -19
  25. package/dist/src/commands/profile-and-review.js +0 -2
  26. package/dist/src/commands/queue.js +0 -2
  27. package/dist/src/commands/remote.js +0 -2
  28. package/dist/src/commands/repo-git-harness.js +2 -4
  29. package/dist/src/commands/run.js +2 -4
  30. package/dist/src/commands/server.js +0 -2
  31. package/dist/src/commands/setup.js +0 -8
  32. package/dist/src/commands/task-report-bug.js +0 -2
  33. package/dist/src/commands/task-run-driver.js +0 -2
  34. package/dist/src/commands/task.js +34 -7
  35. package/dist/src/commands/test.js +0 -2
  36. package/dist/src/commands/workspace.js +0 -2
  37. package/dist/src/commands.js +403 -214
  38. package/dist/src/index.js +415 -238
  39. package/dist/src/runner.js +2 -17
  40. package/package.json +6 -6
@@ -1,12 +1,25 @@
1
1
  // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
2
17
  var __require = import.meta.require;
3
18
 
4
19
  // packages/cli/src/runner.ts
5
20
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
6
21
  import { CliError } from "@rig/runtime/control-plane/errors";
7
22
  import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
8
- import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
9
- import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
10
23
  import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
11
24
  import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
12
25
  function formatCommand(parts) {
@@ -57,11 +70,277 @@ Usage: ${usage}`);
57
70
  }
58
71
  return taskId;
59
72
  }
73
+ var init_runner = () => {};
74
+
75
+ // packages/cli/src/commands/_parsers.ts
76
+ import { homedir } from "os";
77
+ import { resolve as resolve6 } from "path";
78
+ function parsePositiveInt(value, option, fallback) {
79
+ if (!value) {
80
+ return fallback;
81
+ }
82
+ const parsed = Number.parseInt(value, 10);
83
+ if (!Number.isFinite(parsed) || parsed <= 0) {
84
+ throw new CliError2(`Invalid ${option} value: ${value}`);
85
+ }
86
+ return parsed;
87
+ }
88
+ function parseOptionalPositiveInt(value, option) {
89
+ if (!value) {
90
+ return;
91
+ }
92
+ const parsed = Number.parseInt(value, 10);
93
+ if (!Number.isFinite(parsed) || parsed <= 0) {
94
+ throw new CliError2(`Invalid ${option} value: ${value}`);
95
+ }
96
+ return parsed;
97
+ }
98
+ function parseRequiredPositiveInt(value, option) {
99
+ if (!value) {
100
+ throw new CliError2(`Missing value for ${option}.`);
101
+ }
102
+ const parsed = Number.parseInt(value, 10);
103
+ if (!Number.isFinite(parsed) || parsed <= 0) {
104
+ throw new CliError2(`Invalid ${option} value: ${value}`);
105
+ }
106
+ return parsed;
107
+ }
108
+ function parseAction(value) {
109
+ if (!value || value === "validate") {
110
+ return "validate";
111
+ }
112
+ if (value === "verify") {
113
+ return "verify";
114
+ }
115
+ if (value === "pipeline") {
116
+ return "pipeline";
117
+ }
118
+ throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
119
+ }
120
+ function parseIsolationMode(value, allowOff) {
121
+ if (!value) {
122
+ return "worktree";
123
+ }
124
+ if (value === "worktree") {
125
+ return value;
126
+ }
127
+ if (allowOff && value === "off") {
128
+ return value;
129
+ }
130
+ throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
131
+ }
132
+ function parseInstallScope(value) {
133
+ if (!value || value === "user") {
134
+ return "user";
135
+ }
136
+ if (value === "system") {
137
+ return "system";
138
+ }
139
+ throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
140
+ }
141
+ function resolveInstallDir(scope, explicitPath) {
142
+ if (explicitPath) {
143
+ return resolve6(explicitPath);
144
+ }
145
+ if (scope === "system") {
146
+ return "/usr/local/bin";
147
+ }
148
+ return resolve6(homedir(), ".local/bin");
149
+ }
150
+ async function loadRigConfigOrNull(projectRoot) {
151
+ try {
152
+ const { loadConfig } = await import("@rig/core/load-config");
153
+ return await loadConfig(projectRoot);
154
+ } catch {
155
+ return null;
156
+ }
157
+ }
158
+ var init__parsers = __esm(() => {
159
+ init_runner();
160
+ });
161
+
162
+ // packages/cli/src/commands/plugin.ts
163
+ var exports_plugin = {};
164
+ __export(exports_plugin, {
165
+ resolvePluginCliCommand: () => resolvePluginCliCommand,
166
+ executePlugin: () => executePlugin
167
+ });
168
+ import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
169
+ async function executePlugin(context, args) {
170
+ const [command = "list", ...rest] = args;
171
+ switch (command) {
172
+ case "list": {
173
+ requireNoExtraArgs(rest, "rig plugin list");
174
+ const declarative = [];
175
+ const config = await loadRigConfigOrNull(context.projectRoot);
176
+ if (config && Array.isArray(config.plugins)) {
177
+ for (const plugin of config.plugins) {
178
+ const c = plugin.contributes ?? {};
179
+ declarative.push({
180
+ name: plugin.name,
181
+ version: plugin.version,
182
+ validators: (c.validators ?? []).map((v) => v.id),
183
+ hooks: (c.hooks ?? []).map((h) => h.id),
184
+ agentRoles: (c.agentRoles ?? []).map((r) => r.id),
185
+ repoSources: (c.repoSources ?? []).map((r) => r.id),
186
+ taskSources: (c.taskSources ?? []).map((s) => s.id),
187
+ skills: (c.skills ?? []).map((s) => s.id),
188
+ taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
189
+ cliCommands: (c.cliCommands ?? []).map((entry) => entry.id)
190
+ });
191
+ }
192
+ }
193
+ if (context.outputMode === "text") {
194
+ if (declarative.length === 0) {
195
+ console.log("No plugins loaded. Declare plugins in rig.config.ts.");
196
+ } else {
197
+ console.log("Plugins (rig.config.ts):");
198
+ for (const p of declarative) {
199
+ console.log(` ${p.name}@${p.version}`);
200
+ const lines = [];
201
+ if (p.validators.length)
202
+ lines.push(` validators: ${p.validators.join(", ")}`);
203
+ if (p.hooks.length)
204
+ lines.push(` hooks: ${p.hooks.join(", ")}`);
205
+ if (p.agentRoles.length)
206
+ lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
207
+ if (p.repoSources.length)
208
+ lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
209
+ if (p.taskSources.length)
210
+ lines.push(` task-sources: ${p.taskSources.join(", ")}`);
211
+ if (p.skills.length)
212
+ lines.push(` skills: ${p.skills.join(", ")}`);
213
+ if (p.taskFieldExtensions.length)
214
+ lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
215
+ if (p.cliCommands.length)
216
+ lines.push(` cli-commands: ${p.cliCommands.join(", ")} (run with \`rig plugin run <id>\`)`);
217
+ for (const line of lines)
218
+ console.log(line);
219
+ }
220
+ }
221
+ }
222
+ return {
223
+ ok: true,
224
+ group: "plugin",
225
+ command,
226
+ details: { declarative }
227
+ };
228
+ }
229
+ case "validate": {
230
+ const { value: task, rest: remaining } = takeOption(rest, "--task");
231
+ requireNoExtraArgs(remaining, "rig plugin validate --task <task-id>");
232
+ const taskId = requireTask(task, "rig plugin validate --task <task-id>");
233
+ const hostCtx = await buildPluginHostContext(context.projectRoot);
234
+ if (!hostCtx) {
235
+ throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
236
+ }
237
+ const validators = hostCtx.validatorRegistry.list();
238
+ const results = [];
239
+ for (const validator of validators) {
240
+ try {
241
+ results.push(await validator.run({
242
+ taskId,
243
+ workspaceRoot: context.projectRoot,
244
+ scope: []
245
+ }));
246
+ } catch (error) {
247
+ results.push({
248
+ id: validator.id,
249
+ passed: false,
250
+ summary: `${validator.id} failed unexpectedly`,
251
+ details: `${error}`
252
+ });
253
+ }
254
+ }
255
+ const passed = results.filter((result) => result.passed).length;
256
+ const failed = results.length - passed;
257
+ if (context.outputMode === "text") {
258
+ if (results.length === 0) {
259
+ console.log("No plugin validators registered.");
260
+ } else {
261
+ for (const result of results) {
262
+ const icon = result.passed ? "PASS" : "FAIL";
263
+ console.log(`[${icon}] ${result.id}: ${result.summary}`);
264
+ if (result.details && !result.passed) {
265
+ console.log(result.details);
266
+ }
267
+ }
268
+ }
269
+ }
270
+ if (failed > 0) {
271
+ throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
272
+ }
273
+ return {
274
+ ok: true,
275
+ group: "plugin",
276
+ command,
277
+ details: {
278
+ taskId,
279
+ passed,
280
+ failed,
281
+ results
282
+ }
283
+ };
284
+ }
285
+ case "run": {
286
+ const [commandId, ...commandArgs] = rest;
287
+ if (!commandId) {
288
+ throw new CliError2("Usage: rig plugin run <command-id> [args...]");
289
+ }
290
+ const hostCtx = await buildPluginHostContext(context.projectRoot);
291
+ if (!hostCtx) {
292
+ throw new CliError2(`No rig.config found at ${context.projectRoot}. Run \`rig init\` to set up plugins.`, 2);
293
+ }
294
+ const registration = resolvePluginCliCommand(hostCtx.pluginHost.listCliCommands(), commandId);
295
+ if (!registration) {
296
+ const available = hostCtx.pluginHost.listCliCommands().map((entry) => entry.id);
297
+ throw new CliError2(available.length > 0 ? `Unknown plugin command "${commandId}". Available: ${available.join(", ")}` : `No plugin CLI commands are registered. Plugins contribute them via contributes.cliCommands.`, 2);
298
+ }
299
+ if (context.dryRun) {
300
+ if (context.outputMode === "text") {
301
+ console.log(`[dry-run] ${registration.command}${commandArgs.length ? ` ${commandArgs.join(" ")}` : ""}`);
302
+ }
303
+ return { ok: true, group: "plugin", command, details: { id: registration.id, dryRun: true } };
304
+ }
305
+ const proc = Bun.spawn(["bash", "-c", `${registration.command} "$@"`, registration.id, ...commandArgs], {
306
+ cwd: context.projectRoot,
307
+ env: process.env,
308
+ stdin: "inherit",
309
+ stdout: "inherit",
310
+ stderr: "inherit"
311
+ });
312
+ const exitCode = await proc.exited;
313
+ if (exitCode !== 0) {
314
+ throw new CliError2(`Plugin command "${registration.id}" exited with code ${exitCode}.`, exitCode);
315
+ }
316
+ return { ok: true, group: "plugin", command, details: { id: registration.id, exitCode } };
317
+ }
318
+ default:
319
+ throw new CliError2(`Unknown plugin command: ${command}`);
320
+ }
321
+ }
322
+ function resolvePluginCliCommand(commands, requested) {
323
+ const exact = commands.find((entry) => entry.id === requested);
324
+ if (exact)
325
+ return exact;
326
+ const byLocalPart = commands.filter((entry) => entry.id.split(":").slice(1).join(":") === requested);
327
+ return byLocalPart.length === 1 ? byLocalPart[0] : undefined;
328
+ }
329
+ var init_plugin = __esm(() => {
330
+ init_runner();
331
+ init__parsers();
332
+ });
60
333
 
61
334
  // packages/cli/src/commands.ts
335
+ init_runner();
336
+ import {
337
+ existsSync as existsSync13
338
+ } from "fs";
339
+ import { resolve as resolve22 } from "path";
62
340
  import { readBuildConfig } from "@rig/runtime/build-time-config";
63
341
 
64
342
  // packages/cli/src/commands/browser.ts
343
+ init_runner();
65
344
  import { mkdirSync as mkdirSync2, rmSync as rmSync2 } from "fs";
66
345
  import { resolve as resolve4 } from "path";
67
346
  import { spawn } from "child_process";
@@ -72,6 +351,7 @@ import pc2 from "picocolors";
72
351
  import { runCapture as runCapture2 } from "@rig/runtime/control-plane/native/utils";
73
352
 
74
353
  // packages/cli/src/commands/task-report-bug.ts
354
+ init_runner();
75
355
  import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
76
356
  import { resolve as resolve3 } from "path";
77
357
  import * as clack from "@clack/prompts";
@@ -1896,6 +2176,7 @@ async function stopBrowserDemo(child) {
1896
2176
  }
1897
2177
 
1898
2178
  // packages/cli/src/commands/profile-and-review.ts
2179
+ init_runner();
1899
2180
  import {
1900
2181
  setProfile,
1901
2182
  setReviewProfile,
@@ -2035,10 +2316,12 @@ async function executeReview(context, args) {
2035
2316
  }
2036
2317
 
2037
2318
  // packages/cli/src/commands/repo-git-harness.ts
2319
+ init_runner();
2038
2320
  import { executeHarnessCommand } from "@rig/runtime/control-plane/native/harness-cli";
2039
2321
  import { repoEnsure, resetBaseline } from "@rig/runtime/control-plane/native/repo-ops";
2040
2322
 
2041
2323
  // packages/cli/src/commands/_policy.ts
2324
+ init_runner();
2042
2325
  import { appendFileSync, mkdirSync as mkdirSync3 } from "fs";
2043
2326
  import { resolve as resolve5 } from "path";
2044
2327
  import { evaluate as evaluate2, loadPolicy as loadPolicy2, resolveAction as resolveAction2 } from "@rig/runtime/control-plane/runtime/guard";
@@ -2133,7 +2416,7 @@ async function executeGit(context, args) {
2133
2416
  return { ok: true, group: "git", command: args[0] ?? "git" };
2134
2417
  }
2135
2418
  try {
2136
- await executeHarnessCommand(context.projectRoot, context.plugins, ["git", ...args]);
2419
+ await executeHarnessCommand(context.projectRoot, ["git", ...args]);
2137
2420
  } catch (error) {
2138
2421
  throw new CliError2(error instanceof Error ? error.message : String(error), 2);
2139
2422
  }
@@ -2154,214 +2437,27 @@ async function executeHarness(context, args) {
2154
2437
  return { ok: true, group: "harness", command: args[0] ?? "harness" };
2155
2438
  }
2156
2439
  try {
2157
- await executeHarnessCommand(context.projectRoot, context.plugins, args);
2440
+ await executeHarnessCommand(context.projectRoot, args);
2158
2441
  } catch (error) {
2159
2442
  throw new CliError2(error instanceof Error ? error.message : String(error), 2);
2160
2443
  }
2161
2444
  return { ok: true, group: "harness", command: args[0] ?? "harness" };
2162
2445
  }
2163
2446
 
2164
- // packages/cli/src/commands/_parsers.ts
2165
- import { homedir } from "os";
2166
- import { resolve as resolve6 } from "path";
2167
- function parsePositiveInt(value, option, fallback) {
2168
- if (!value) {
2169
- return fallback;
2170
- }
2171
- const parsed = Number.parseInt(value, 10);
2172
- if (!Number.isFinite(parsed) || parsed <= 0) {
2173
- throw new CliError2(`Invalid ${option} value: ${value}`);
2174
- }
2175
- return parsed;
2176
- }
2177
- function parseOptionalPositiveInt(value, option) {
2178
- if (!value) {
2179
- return;
2180
- }
2181
- const parsed = Number.parseInt(value, 10);
2182
- if (!Number.isFinite(parsed) || parsed <= 0) {
2183
- throw new CliError2(`Invalid ${option} value: ${value}`);
2184
- }
2185
- return parsed;
2186
- }
2187
- function parseRequiredPositiveInt(value, option) {
2188
- if (!value) {
2189
- throw new CliError2(`Missing value for ${option}.`);
2190
- }
2191
- const parsed = Number.parseInt(value, 10);
2192
- if (!Number.isFinite(parsed) || parsed <= 0) {
2193
- throw new CliError2(`Invalid ${option} value: ${value}`);
2194
- }
2195
- return parsed;
2196
- }
2197
- function parseAction(value) {
2198
- if (!value || value === "validate") {
2199
- return "validate";
2200
- }
2201
- if (value === "verify") {
2202
- return "verify";
2203
- }
2204
- if (value === "pipeline") {
2205
- return "pipeline";
2206
- }
2207
- throw new CliError2(`Invalid --action value: ${value}. Use validate, verify, or pipeline.`);
2208
- }
2209
- function parseIsolationMode(value, allowOff) {
2210
- if (!value) {
2211
- return "worktree";
2212
- }
2213
- if (value === "worktree") {
2214
- return value;
2215
- }
2216
- if (allowOff && value === "off") {
2217
- return value;
2218
- }
2219
- throw new CliError2(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
2220
- }
2221
- function parseInstallScope(value) {
2222
- if (!value || value === "user") {
2223
- return "user";
2224
- }
2225
- if (value === "system") {
2226
- return "system";
2227
- }
2228
- throw new CliError2(`Invalid --scope value: ${value}. Use user|system.`);
2229
- }
2230
- function resolveInstallDir(scope, explicitPath) {
2231
- if (explicitPath) {
2232
- return resolve6(explicitPath);
2233
- }
2234
- if (scope === "system") {
2235
- return "/usr/local/bin";
2236
- }
2237
- return resolve6(homedir(), ".local/bin");
2238
- }
2239
- async function loadRigConfigOrNull(projectRoot) {
2240
- try {
2241
- const { loadConfig } = await import("@rig/core/load-config");
2242
- return await loadConfig(projectRoot);
2243
- } catch {
2244
- return null;
2245
- }
2246
- }
2247
-
2248
- // packages/cli/src/commands/plugin.ts
2249
- async function executePlugin(context, args) {
2250
- const [command = "list", ...rest] = args;
2251
- switch (command) {
2252
- case "list": {
2253
- requireNoExtraArgs(rest, "rig plugin list");
2254
- const legacyPlugins = context.plugins.list();
2255
- const declarative = [];
2256
- const config = await loadRigConfigOrNull(context.projectRoot);
2257
- if (config && Array.isArray(config.plugins)) {
2258
- for (const plugin of config.plugins) {
2259
- const c = plugin.contributes ?? {};
2260
- declarative.push({
2261
- name: plugin.name,
2262
- version: plugin.version,
2263
- validators: (c.validators ?? []).map((v) => v.id),
2264
- hooks: (c.hooks ?? []).map((h) => h.id),
2265
- agentRoles: (c.agentRoles ?? []).map((r) => r.id),
2266
- repoSources: (c.repoSources ?? []).map((r) => r.id),
2267
- taskSources: (c.taskSources ?? []).map((s) => s.id),
2268
- skills: (c.skills ?? []).map((s) => s.id),
2269
- taskFieldExtensions: (c.taskFieldSchemas ?? []).map((f) => f.id),
2270
- cliCommands: (c.cliCommands ?? []).map((c2) => c2.id)
2271
- });
2272
- }
2273
- }
2274
- if (context.outputMode === "text") {
2275
- if (legacyPlugins.length === 0 && declarative.length === 0) {
2276
- console.log("No plugins loaded.");
2277
- }
2278
- if (declarative.length > 0) {
2279
- console.log("Declarative plugins (rig.config.ts):");
2280
- for (const p of declarative) {
2281
- console.log(` ${p.name}@${p.version}`);
2282
- const lines = [];
2283
- if (p.validators.length)
2284
- lines.push(` validators: ${p.validators.join(", ")}`);
2285
- if (p.hooks.length)
2286
- lines.push(` hooks: ${p.hooks.join(", ")}`);
2287
- if (p.agentRoles.length)
2288
- lines.push(` agent-roles: ${p.agentRoles.join(", ")}`);
2289
- if (p.repoSources.length)
2290
- lines.push(` repo-sources: ${p.repoSources.join(", ")}`);
2291
- if (p.taskSources.length)
2292
- lines.push(` task-sources: ${p.taskSources.join(", ")}`);
2293
- if (p.skills.length)
2294
- lines.push(` skills: ${p.skills.join(", ")}`);
2295
- if (p.taskFieldExtensions.length)
2296
- lines.push(` task-fields: ${p.taskFieldExtensions.join(", ")}`);
2297
- if (p.cliCommands.length)
2298
- lines.push(` cli-commands: ${p.cliCommands.join(", ")}`);
2299
- for (const line of lines)
2300
- console.log(line);
2301
- }
2302
- }
2303
- if (legacyPlugins.length > 0) {
2304
- console.log("Legacy disk-scan plugins (rig/plugins/):");
2305
- for (const plugin of legacyPlugins) {
2306
- const validators = plugin.validators.length > 0 ? plugin.validators.join(", ") : "none";
2307
- console.log(` ${plugin.name} (validators: ${validators})`);
2308
- }
2309
- }
2310
- }
2311
- return {
2312
- ok: true,
2313
- group: "plugin",
2314
- command,
2315
- details: { declarative, legacy: legacyPlugins }
2316
- };
2317
- }
2318
- case "validate": {
2319
- const { value: task, rest: remaining } = takeOption(rest, "--task");
2320
- requireNoExtraArgs(remaining, "rig plugin validate --task <task-id>");
2321
- const taskId = requireTask(task, "rig plugin validate --task <task-id>");
2322
- const results = await context.plugins.runValidators(taskId);
2323
- const passed = results.filter((result) => result.passed).length;
2324
- const failed = results.length - passed;
2325
- if (context.outputMode === "text") {
2326
- if (results.length === 0) {
2327
- console.log("No plugin validators registered.");
2328
- } else {
2329
- for (const result of results) {
2330
- const icon = result.passed ? "PASS" : "FAIL";
2331
- console.log(`[${icon}] ${result.id}: ${result.summary}`);
2332
- if (result.details && !result.passed) {
2333
- console.log(result.details);
2334
- }
2335
- }
2336
- }
2337
- }
2338
- if (failed > 0) {
2339
- throw new CliError2(`Plugin validation failed for ${failed} validator(s).`, 2);
2340
- }
2341
- return {
2342
- ok: true,
2343
- group: "plugin",
2344
- command,
2345
- details: {
2346
- taskId,
2347
- passed,
2348
- failed,
2349
- results
2350
- }
2351
- };
2352
- }
2353
- default:
2354
- throw new CliError2(`Unknown plugin command: ${command}`);
2355
- }
2356
- }
2447
+ // packages/cli/src/commands.ts
2448
+ init_plugin();
2357
2449
 
2358
2450
  // packages/cli/src/commands/queue.ts
2451
+ init_runner();
2452
+ init__parsers();
2359
2453
  import { runPriorityQueue } from "@rig/runtime/control-plane/runtime/queue";
2360
2454
 
2361
2455
  // packages/cli/src/commands/_preflight.ts
2456
+ init_runner();
2362
2457
  import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
2363
2458
 
2364
2459
  // packages/cli/src/commands/_connection-state.ts
2460
+ init_runner();
2365
2461
  import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2366
2462
  import { homedir as homedir2 } from "os";
2367
2463
  import { dirname, resolve as resolve7 } from "path";
@@ -2464,6 +2560,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
2464
2560
  }
2465
2561
 
2466
2562
  // packages/cli/src/commands/_server-client.ts
2563
+ init_runner();
2467
2564
  import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
2468
2565
  import { resolve as resolve8 } from "path";
2469
2566
  import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
@@ -3112,6 +3209,7 @@ async function executeQueue(context, args) {
3112
3209
  }
3113
3210
 
3114
3211
  // packages/cli/src/commands/agent.ts
3212
+ init_runner();
3115
3213
  import { resolve as resolve10 } from "path";
3116
3214
  import {
3117
3215
  agentId,
@@ -3219,6 +3317,7 @@ function upsertAgentAuthorityRun(projectRoot, input) {
3219
3317
  }
3220
3318
 
3221
3319
  // packages/cli/src/commands/agent.ts
3320
+ init__parsers();
3222
3321
  function splitAtDoubleDash(args) {
3223
3322
  const separatorIndex = args.indexOf("--");
3224
3323
  if (separatorIndex === -1) {
@@ -3452,6 +3551,8 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
3452
3551
  }
3453
3552
 
3454
3553
  // packages/cli/src/commands/dist.ts
3554
+ init_runner();
3555
+ init__parsers();
3455
3556
  import {
3456
3557
  chmodSync,
3457
3558
  copyFileSync as copyFileSync2,
@@ -3769,6 +3870,7 @@ async function executeDist(context, args) {
3769
3870
  }
3770
3871
 
3771
3872
  // packages/cli/src/commands/inbox.ts
3873
+ init_runner();
3772
3874
  import { writeFileSync as writeFileSync4 } from "fs";
3773
3875
  import { resolve as resolve12 } from "path";
3774
3876
  import {
@@ -4291,6 +4393,7 @@ async function executeInbox(context, args) {
4291
4393
  }
4292
4394
 
4293
4395
  // packages/cli/src/commands/init.ts
4396
+ init_runner();
4294
4397
  import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
4295
4398
  import { spawnSync } from "child_process";
4296
4399
  import { resolve as resolve16 } from "path";
@@ -4566,9 +4669,11 @@ async function uploadSnapshotArchiveViaServer(context, input) {
4566
4669
  }
4567
4670
 
4568
4671
  // packages/cli/src/commands/_doctor-checks.ts
4672
+ init_runner();
4569
4673
  import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
4570
4674
  import { resolve as resolve15 } from "path";
4571
4675
  import { isSupportedBunVersion, MIN_SUPPORTED_BUN_VERSION } from "@rig/runtime/control-plane/setup-version";
4676
+ init__parsers();
4572
4677
  function check(id, label, status, detail, remediation) {
4573
4678
  return {
4574
4679
  id,
@@ -5511,6 +5616,7 @@ Usage: rig init`, 1);
5511
5616
  }
5512
5617
 
5513
5618
  // packages/cli/src/commands/connect.ts
5619
+ init_runner();
5514
5620
  import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
5515
5621
  function usageName(options) {
5516
5622
  return `rig ${options.group}`;
@@ -5623,6 +5729,7 @@ async function executeConnect(context, args) {
5623
5729
  }
5624
5730
 
5625
5731
  // packages/cli/src/commands/github.ts
5732
+ init_runner();
5626
5733
  import { spawnSync as spawnSync2 } from "child_process";
5627
5734
  function printPayload(context, payload, fallback) {
5628
5735
  if (context.outputMode === "json")
@@ -5678,6 +5785,7 @@ async function executeGithub(context, args) {
5678
5785
  }
5679
5786
 
5680
5787
  // packages/cli/src/commands/doctor.ts
5788
+ init_runner();
5681
5789
  async function executeDoctor(context, args) {
5682
5790
  requireNoExtraArgs(args, "rig doctor");
5683
5791
  const checks = await runRigDoctorChecks({ projectRoot: context.projectRoot });
@@ -5693,6 +5801,7 @@ async function executeDoctor(context, args) {
5693
5801
  }
5694
5802
 
5695
5803
  // packages/cli/src/commands/_run-driver-helpers.ts
5804
+ init_runner();
5696
5805
  import { readFileSync as readFileSync7 } from "fs";
5697
5806
  import { resolve as resolve17 } from "path";
5698
5807
  import {
@@ -5920,6 +6029,7 @@ function renderSourceScopeValidation(task, validation) {
5920
6029
  }
5921
6030
 
5922
6031
  // packages/cli/src/commands/inspect.ts
6032
+ init_runner();
5923
6033
  import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
5924
6034
  import { resolve as resolve18 } from "path";
5925
6035
  import {
@@ -6047,6 +6157,8 @@ async function executeInspect(context, args) {
6047
6157
  }
6048
6158
 
6049
6159
  // packages/cli/src/commands/inspector.ts
6160
+ init_runner();
6161
+ init__parsers();
6050
6162
  import { iterateServerSentEvents } from "@rig/client";
6051
6163
  import { ensureLocalRigServerConnection as ensureLocalRigServerConnection2 } from "@rig/runtime/local-server";
6052
6164
  function formatInspectorStreamLine(payload) {
@@ -6237,6 +6349,8 @@ async function executeInspector(context, args) {
6237
6349
  }
6238
6350
 
6239
6351
  // packages/cli/src/commands/remote.ts
6352
+ init_runner();
6353
+ init__parsers();
6240
6354
  import {
6241
6355
  doctorManagedRemoteEndpoints,
6242
6356
  listManagedRemoteEndpoints,
@@ -6663,6 +6777,8 @@ async function executeRemote(context, args) {
6663
6777
  }
6664
6778
 
6665
6779
  // packages/cli/src/commands/run.ts
6780
+ init_runner();
6781
+ init__parsers();
6666
6782
  import { createInterface as createInterface2 } from "readline/promises";
6667
6783
  import {
6668
6784
  listAuthorityRuns as listAuthorityRuns3,
@@ -6680,7 +6796,7 @@ import {
6680
6796
  startRun,
6681
6797
  defaultStartRunOptions
6682
6798
  } from "@rig/runtime/control-plane/native/run-ops";
6683
- import { loadRuntimeContextFromEnv as loadRuntimeContextFromEnv2 } from "@rig/runtime/control-plane/runtime/context";
6799
+ import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
6684
6800
 
6685
6801
  // packages/cli/src/commands/_operator-surface.ts
6686
6802
  import { createInterface } from "readline";
@@ -7647,7 +7763,7 @@ async function promptForEpicSelection(projectRoot, command) {
7647
7763
  }
7648
7764
  async function executeRun(context, args) {
7649
7765
  const [command = "status", ...rest] = args;
7650
- const runtimeContext = loadRuntimeContextFromEnv2() ?? undefined;
7766
+ const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
7651
7767
  switch (command) {
7652
7768
  case "list": {
7653
7769
  requireNoExtraArgs(rest, "rig run list");
@@ -7948,6 +8064,7 @@ async function executeRun(context, args) {
7948
8064
  }
7949
8065
 
7950
8066
  // packages/cli/src/commands/server.ts
8067
+ init_runner();
7951
8068
  async function executeServer(context, args, options) {
7952
8069
  const [command = "status", ...rest] = args;
7953
8070
  if (["status", "list", "add", "use"].includes(command)) {
@@ -8049,6 +8166,7 @@ async function executeServer(context, args, options) {
8049
8166
  }
8050
8167
 
8051
8168
  // packages/cli/src/commands/task.ts
8169
+ init_runner();
8052
8170
  import { readFileSync as readFileSync9 } from "fs";
8053
8171
  import { spawnSync as spawnSync3 } from "child_process";
8054
8172
  import { resolve as resolve19 } from "path";
@@ -8203,6 +8321,9 @@ var PRIMARY_GROUPS = [
8203
8321
  { command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
8204
8322
  { command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
8205
8323
  { command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
8324
+ { command: "details --task <id>", description: "Show full task info from the configured source." },
8325
+ { command: "reopen [--task <id> | --all] [--reason <text>]", description: "Reopen closed task(s) in the configured source." },
8326
+ { command: "reset --task <id>", description: "Compatibility spelling of `reopen --task <id>`." },
8206
8327
  { command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
8207
8328
  { command: "report-bug", description: "Create a structured bug report/task." }
8208
8329
  ],
@@ -8227,6 +8348,8 @@ var PRIMARY_GROUPS = [
8227
8348
  { command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
8228
8349
  { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
8229
8350
  { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
8351
+ { command: "resume", description: "Resume the most recent interrupted local run." },
8352
+ { command: "restart", description: "Restart the most recent local run from a clean runtime." },
8230
8353
  { command: "delete|cleanup", description: "Remove completed run records/artifacts." }
8231
8354
  ],
8232
8355
  examples: [
@@ -8313,8 +8436,28 @@ var ADVANCED_GROUPS = [
8313
8436
  { name: "inspect", summary: "Inspect logs, artifacts, graphs, failures.", usage: ["rig inspect <logs|artifacts|failures|graph|audit|diff>"], commands: [{ command: "logs --task <id>", description: "Inspect task logs." }] },
8314
8437
  { name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
8315
8438
  { name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
8316
- { name: "browser", summary: "Browser/app diagnostics.", usage: ["rig browser <help|explain|demo|app>"], commands: [{ command: "help", description: "Browser command help." }] },
8317
- { name: "plugin", summary: "Plugin validation/listing.", usage: ["rig plugin <list|validate>"], commands: [{ command: "list", description: "List plugins." }] },
8439
+ {
8440
+ name: "browser",
8441
+ summary: "Browser/app diagnostics for browser-required tasks.",
8442
+ usage: ["rig browser <help|explain|demo|app|hp-next> [options]"],
8443
+ commands: [
8444
+ { command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
8445
+ { command: "explain", description: "Explain the browser-required task contract." },
8446
+ { command: "demo", description: "Run browser demo flows against a local page." },
8447
+ { command: "app", description: "Launch the Rig Browser workstation app." },
8448
+ { command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
8449
+ ]
8450
+ },
8451
+ {
8452
+ name: "plugin",
8453
+ summary: "Plugin listing, validation, and plugin-contributed commands.",
8454
+ usage: ["rig plugin <list|validate|run> [options]"],
8455
+ commands: [
8456
+ { command: "list", description: "List plugins declared in rig.config.ts and their contributions." },
8457
+ { command: "validate --task <id>", description: "Run plugin-contributed validators for a task." },
8458
+ { command: "run <command-id> [args...]", description: "Execute a plugin-contributed CLI command (also callable as `rig <command-id>`)." }
8459
+ ]
8460
+ },
8318
8461
  { name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
8319
8462
  { name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
8320
8463
  { name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
@@ -8329,7 +8472,6 @@ var ADVANCED_COMMANDS = [
8329
8472
  { command: "rig server task-run ...", description: "Internal server-owned task execution entry point." },
8330
8473
  { command: "rig server notify-test [--event <type>]", description: "Internal event notification smoke command." },
8331
8474
  { command: "rig run start|start-serial|start-parallel", description: "Compatibility local run starters; prefer `rig task run ...`." },
8332
- { command: "rig setup install-agent-shell", description: "Development helper for materializing the agent shell." },
8333
8475
  { command: "rig remote orchestrate-*", description: "Compatibility remote orchestration commands." }
8334
8476
  ];
8335
8477
  var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
@@ -8469,7 +8611,7 @@ function printGroupHelpDocument(groupName) {
8469
8611
  }
8470
8612
 
8471
8613
  // packages/cli/src/commands/task.ts
8472
- import { buildPluginHostContext } from "@rig/runtime/control-plane/plugin-host-context";
8614
+ import { buildPluginHostContext as buildPluginHostContext2 } from "@rig/runtime/control-plane/plugin-host-context";
8473
8615
  import { loadConfig } from "@rig/core/load-config";
8474
8616
  async function readStdin() {
8475
8617
  const chunks = [];
@@ -8620,7 +8762,7 @@ function summarizeTask(task, options = {}) {
8620
8762
  };
8621
8763
  }
8622
8764
  async function validatorRegistryForTaskCommands(projectRoot) {
8623
- return buildPluginHostContext(projectRoot).then((ctx) => ctx?.validatorRegistry ?? undefined).catch(() => {
8765
+ return buildPluginHostContext2(projectRoot).then((ctx) => ctx?.validatorRegistry ?? undefined).catch(() => {
8624
8766
  return;
8625
8767
  });
8626
8768
  }
@@ -8924,7 +9066,7 @@ async function executeTask(context, args, options) {
8924
9066
  await context.runCommand(["rig", "task", "verify", ...task ? ["--task", task] : []]);
8925
9067
  return { ok: true, group: "task", command, details: { task: task || "active" } };
8926
9068
  }
8927
- const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot, context.plugins, task || undefined));
9069
+ const ok = await withMutedConsole(context.outputMode === "json", () => taskVerify(context.projectRoot, task || undefined));
8928
9070
  if (!ok) {
8929
9071
  throw new CliError2(`Verification rejected for ${task || "active task"}.`, 2);
8930
9072
  }
@@ -8934,8 +9076,12 @@ async function executeTask(context, args, options) {
8934
9076
  const { value: task, rest: remaining } = takeOption(rest, "--task");
8935
9077
  requireNoExtraArgs(remaining, "rig task reset --task <task-id>");
8936
9078
  const requiredTask = requireTask(task, "rig task reset --task <task-id>");
8937
- await context.runCommand(["br", "--no-db", "update", requiredTask, "--status", "open"]);
8938
- return { ok: true, group: "task", command, details: { task: requiredTask } };
9079
+ const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
9080
+ all: false,
9081
+ taskId: requiredTask,
9082
+ dryRun: false
9083
+ }));
9084
+ return { ok: true, group: "task", command, details: summary };
8939
9085
  }
8940
9086
  case "details": {
8941
9087
  const { value: task, rest: remaining } = takeOption(rest, "--task");
@@ -8965,6 +9111,7 @@ async function executeTask(context, args, options) {
8965
9111
  }
8966
9112
 
8967
9113
  // packages/cli/src/commands/task-run-driver.ts
9114
+ init_runner();
8968
9115
  import { copyFileSync as copyFileSync3, existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync10, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
8969
9116
  import { resolve as resolve20 } from "path";
8970
9117
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
@@ -10981,6 +11128,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
10981
11128
  }
10982
11129
 
10983
11130
  // packages/cli/src/commands/test.ts
11131
+ init_runner();
10984
11132
  async function executeTest(context, args) {
10985
11133
  const [command = "unit", ...rest] = args;
10986
11134
  switch (command) {
@@ -11002,6 +11150,7 @@ async function executeTest(context, args) {
11002
11150
  }
11003
11151
 
11004
11152
  // packages/cli/src/commands/setup.ts
11153
+ init_runner();
11005
11154
  import { existsSync as existsSync12, mkdirSync as mkdirSync8, readdirSync as readdirSync2, writeFileSync as writeFileSync7 } from "fs";
11006
11155
  import { resolve as resolve21 } from "path";
11007
11156
  import { createPluginHost } from "@rig/core";
@@ -11009,6 +11158,7 @@ import {
11009
11158
  isSupportedBunVersion as isSupportedBunVersion2,
11010
11159
  MIN_SUPPORTED_BUN_VERSION as MIN_SUPPORTED_BUN_VERSION2
11011
11160
  } from "@rig/runtime/control-plane/setup-version";
11161
+ init__parsers();
11012
11162
  async function executeSetup(context, args) {
11013
11163
  const [command = "check", ...rest] = args;
11014
11164
  switch (command) {
@@ -11049,12 +11199,6 @@ async function executeSetup(context, args) {
11049
11199
  requireNoExtraArgs(rest, "rig setup preflight");
11050
11200
  await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
11051
11201
  return { ok: true, group: "setup", command };
11052
- case "install-agent-shell":
11053
- requireNoExtraArgs(rest, "rig setup install-agent-shell");
11054
- if (context.outputMode === "text") {
11055
- console.log("install-agent-shell is deprecated. Runtime shells now use compiled rig-agent directly.");
11056
- }
11057
- return { ok: true, group: "setup", command };
11058
11202
  default:
11059
11203
  throw new CliError2(`Unknown setup command: ${command}`);
11060
11204
  }
@@ -11105,6 +11249,7 @@ async function runSetupPreflight(projectRoot) {
11105
11249
  }
11106
11250
 
11107
11251
  // packages/cli/src/commands/workspace.ts
11252
+ init_runner();
11108
11253
  import {
11109
11254
  mutateWorkspaceServiceFabric,
11110
11255
  readWorkspaceRemoteFleet,
@@ -11196,7 +11341,6 @@ var TOP_LEVEL_ALIASES = {
11196
11341
  check: ["setup", "check"],
11197
11342
  preflight: ["setup", "preflight"],
11198
11343
  install: ["dist", "install"],
11199
- "install-shell": ["setup", "install-agent-shell"],
11200
11344
  status: ["run", "status"],
11201
11345
  start: ["task", "run", "--next"],
11202
11346
  "start-parallel": ["run", "start-parallel"],
@@ -11229,6 +11373,30 @@ var TOP_LEVEL_ALIASES = {
11229
11373
  "remote-watch": ["remote", "watch"],
11230
11374
  doctor: ["doctor", "check"]
11231
11375
  };
11376
+ var PROJECT_REQUIRED_GROUPS = new Set([
11377
+ "task",
11378
+ "run",
11379
+ "inbox",
11380
+ "review",
11381
+ "queue",
11382
+ "agent",
11383
+ "repo",
11384
+ "inspect"
11385
+ ]);
11386
+ var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
11387
+ function hasInitializedRigProject(projectRoot) {
11388
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync13(resolve22(projectRoot, name))) || existsSync13(resolve22(projectRoot, ".rig"));
11389
+ }
11390
+ function requireInitializedRigProject(context, group) {
11391
+ if (hasInitializedRigProject(context.projectRoot)) {
11392
+ return;
11393
+ }
11394
+ throw new CliError2([
11395
+ `No Rig project found at ${context.projectRoot} (expected rig.config.ts or a .rig/ state directory).`,
11396
+ "Run `rig init` to set up this repo, or pass --project <path> to point at an existing Rig project."
11397
+ ].join(`
11398
+ `), 2);
11399
+ }
11232
11400
  var GROUPS = new Set([
11233
11401
  "init",
11234
11402
  "setup",
@@ -11326,10 +11494,28 @@ ${helpText()}`);
11326
11494
  }
11327
11495
  return executeGroup(context, group, [command, ...aliasArgs, ...rest]);
11328
11496
  }
11497
+ if (await matchesPluginCliCommand(context, first)) {
11498
+ return executeGroup(context, "plugin", ["run", first, ...rest]);
11499
+ }
11329
11500
  throw new CliError2(`Unknown group or command: ${first}
11330
11501
 
11331
11502
  ${helpText()}`);
11332
11503
  }
11504
+ async function matchesPluginCliCommand(context, requested) {
11505
+ if (!hasInitializedRigProject(context.projectRoot)) {
11506
+ return false;
11507
+ }
11508
+ try {
11509
+ const { buildPluginHostContext: buildPluginHostContext3 } = await import("@rig/runtime/control-plane/plugin-host-context");
11510
+ const hostCtx = await buildPluginHostContext3(context.projectRoot);
11511
+ if (!hostCtx)
11512
+ return false;
11513
+ const { resolvePluginCliCommand: resolvePluginCliCommand2 } = await Promise.resolve().then(() => (init_plugin(), exports_plugin));
11514
+ return Boolean(resolvePluginCliCommand2(hostCtx.pluginHost.listCliCommands(), requested));
11515
+ } catch {
11516
+ return false;
11517
+ }
11518
+ }
11333
11519
  var GROUPS_WITH_CUSTOM_HELP = new Set(["browser"]);
11334
11520
  async function executeGroup(context, group, args) {
11335
11521
  if (isHelpArg(args[0]) && !GROUPS_WITH_CUSTOM_HELP.has(group)) {
@@ -11338,6 +11524,9 @@ async function executeGroup(context, group, args) {
11338
11524
  }
11339
11525
  return { ok: true, group, command: "help" };
11340
11526
  }
11527
+ if (PROJECT_REQUIRED_GROUPS.has(group)) {
11528
+ requireInitializedRigProject(context, group);
11529
+ }
11341
11530
  switch (group) {
11342
11531
  case "setup":
11343
11532
  return executeSetup(context, args);