@h-rig/cli 0.0.6-alpha.6 → 0.0.6-alpha.61

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 (52) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/rig.js +5033 -1895
  3. package/dist/src/commands/_authority-runs.js +2 -3
  4. package/dist/src/commands/_cli-format.js +369 -0
  5. package/dist/src/commands/_connection-state.js +12 -6
  6. package/dist/src/commands/_doctor-checks.js +79 -34
  7. package/dist/src/commands/_help-catalog.js +446 -0
  8. package/dist/src/commands/_operator-surface.js +220 -0
  9. package/dist/src/commands/_operator-view.js +1124 -64
  10. package/dist/src/commands/_parsers.js +0 -2
  11. package/dist/src/commands/_pi-frontend.js +1080 -0
  12. package/dist/src/commands/_pi-install.js +4 -3
  13. package/dist/src/commands/_pi-remote-session.js +771 -0
  14. package/dist/src/commands/_pi-worker-bridge-extension.js +834 -0
  15. package/dist/src/commands/_policy.js +0 -2
  16. package/dist/src/commands/_preflight.js +98 -116
  17. package/dist/src/commands/_run-driver-helpers.js +46 -19
  18. package/dist/src/commands/_run-replay.js +142 -0
  19. package/dist/src/commands/_server-client.js +225 -48
  20. package/dist/src/commands/_snapshot-upload.js +74 -30
  21. package/dist/src/commands/_spinner.js +63 -0
  22. package/dist/src/commands/_task-picker.js +44 -16
  23. package/dist/src/commands/agent.js +10 -12
  24. package/dist/src/commands/browser.js +4 -6
  25. package/dist/src/commands/connect.js +134 -26
  26. package/dist/src/commands/dist.js +4 -6
  27. package/dist/src/commands/doctor.js +79 -34
  28. package/dist/src/commands/github.js +76 -32
  29. package/dist/src/commands/inbox.js +410 -31
  30. package/dist/src/commands/init.js +398 -90
  31. package/dist/src/commands/inspect.js +296 -23
  32. package/dist/src/commands/inspector.js +2 -4
  33. package/dist/src/commands/pi.js +168 -0
  34. package/dist/src/commands/plugin.js +81 -22
  35. package/dist/src/commands/profile-and-review.js +8 -10
  36. package/dist/src/commands/queue.js +2 -3
  37. package/dist/src/commands/remote.js +18 -20
  38. package/dist/src/commands/repo-git-harness.js +6 -8
  39. package/dist/src/commands/run.js +1600 -131
  40. package/dist/src/commands/server.js +281 -42
  41. package/dist/src/commands/setup.js +84 -45
  42. package/dist/src/commands/task-report-bug.js +5 -7
  43. package/dist/src/commands/task-run-driver.js +736 -93
  44. package/dist/src/commands/task.js +1863 -262
  45. package/dist/src/commands/test.js +3 -5
  46. package/dist/src/commands/workspace.js +4 -6
  47. package/dist/src/commands.js +5675 -2531
  48. package/dist/src/index.js +5654 -2519
  49. package/dist/src/launcher.js +5 -3
  50. package/dist/src/report-bug.js +3 -3
  51. package/dist/src/runner.js +5 -19
  52. package/package.json +7 -5
@@ -3,8 +3,6 @@
3
3
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
4
4
  import { CliError } from "@rig/runtime/control-plane/errors";
5
5
  import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
6
- import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
7
- import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
8
6
  import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
9
7
  import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
10
8
  function takeOption(args, option) {
@@ -34,12 +32,14 @@ Usage: ${usage}`);
34
32
  }
35
33
  }
36
34
 
35
+ // packages/cli/src/commands/server.ts
36
+ import { resolveRigServerCommand } from "@rig/runtime/local-server";
37
+
37
38
  // packages/cli/src/commands/_authority-runs.ts
38
39
  import {
39
40
  readAuthorityRun,
40
41
  readJsonlFile,
41
- resolveAuthorityRunDir,
42
- writeJsonFile
42
+ writeAuthorityRunRecord
43
43
  } from "@rig/runtime/control-plane/authority-files";
44
44
 
45
45
  // packages/cli/src/commands/_paths.ts
@@ -60,11 +60,8 @@ function normalizeRuntimeAdapter(value) {
60
60
  return "claude-code";
61
61
  }
62
62
 
63
- // packages/cli/src/commands/_server-client.ts
64
- import { spawnSync } from "child_process";
65
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
66
- import { resolve as resolve2 } from "path";
67
- import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
63
+ // packages/cli/src/commands/connect.ts
64
+ import { cancel, isCancel, select } from "@clack/prompts";
68
65
 
69
66
  // packages/cli/src/commands/_connection-state.ts
70
67
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -91,6 +88,11 @@ function readJsonFile(path) {
91
88
  throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
92
89
  }
93
90
  }
91
+ function writeJsonFile(path, value) {
92
+ mkdirSync(dirname(path), { recursive: true });
93
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}
94
+ `, "utf8");
95
+ }
94
96
  function normalizeConnection(value) {
95
97
  if (!value || typeof value !== "object" || Array.isArray(value))
96
98
  return null;
@@ -120,6 +122,18 @@ function readGlobalConnections(options = {}) {
120
122
  }
121
123
  return { connections };
122
124
  }
125
+ function writeGlobalConnections(state, options = {}) {
126
+ writeJsonFile(resolveGlobalConnectionsPath(options.env ?? process.env), state);
127
+ }
128
+ function upsertGlobalConnection(alias, connection, options = {}) {
129
+ const cleanAlias = alias.trim();
130
+ if (!cleanAlias)
131
+ throw new CliError2("Connection alias is required.", 1);
132
+ const state = readGlobalConnections(options);
133
+ state.connections[cleanAlias] = connection;
134
+ writeGlobalConnections(state, options);
135
+ return state;
136
+ }
123
137
  function readRepoConnection(projectRoot) {
124
138
  const payload = readJsonFile(resolveRepoConnectionPath(projectRoot));
125
139
  if (!payload || typeof payload !== "object" || Array.isArray(payload))
@@ -131,25 +145,213 @@ function readRepoConnection(projectRoot) {
131
145
  return {
132
146
  selected,
133
147
  project: typeof record.project === "string" ? record.project : undefined,
134
- linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
148
+ linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
149
+ serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
135
150
  };
136
151
  }
152
+ function writeRepoConnection(projectRoot, state) {
153
+ writeJsonFile(resolveRepoConnectionPath(projectRoot), state);
154
+ }
137
155
  function resolveSelectedConnection(projectRoot, options = {}) {
138
156
  const repo = readRepoConnection(projectRoot);
139
157
  if (!repo)
140
158
  return null;
141
159
  if (repo.selected === "local")
142
- return { alias: "local", connection: { kind: "local", mode: "auto" } };
160
+ return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
143
161
  const global = readGlobalConnections(options);
144
162
  const connection = global.connections[repo.selected];
145
163
  if (!connection) {
146
- throw new CliError2(`Selected Rig connection "${repo.selected}" was not found. Run \`rig connect list\` or \`rig connect use local\`.`, 1);
164
+ throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
165
+ }
166
+ return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
167
+ }
168
+ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
169
+ const repo = readRepoConnection(projectRoot);
170
+ if (!repo)
171
+ return;
172
+ writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
173
+ }
174
+
175
+ // packages/cli/src/commands/_cli-format.ts
176
+ import { log, note } from "@clack/prompts";
177
+ import pc from "picocolors";
178
+ function truncate(value, width) {
179
+ if (value.length <= width)
180
+ return value;
181
+ if (width <= 1)
182
+ return "\u2026";
183
+ return `${value.slice(0, width - 1)}\u2026`;
184
+ }
185
+ function pad(value, width) {
186
+ return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
187
+ }
188
+ function statusColor(status) {
189
+ const normalized = status.toLowerCase();
190
+ if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
191
+ return pc.green;
192
+ if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
193
+ return pc.red;
194
+ if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
195
+ return pc.cyan;
196
+ if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
197
+ return pc.yellow;
198
+ return pc.dim;
199
+ }
200
+ function formatStatusPill(status) {
201
+ const label = status || "unknown";
202
+ return statusColor(label)(`\u25CF ${label}`);
203
+ }
204
+ function formatSection(title, subtitle) {
205
+ return `${pc.bold(pc.cyan("\u25C6"))} ${pc.bold(title)}${subtitle ? pc.dim(` \u2014 ${subtitle}`) : ""}`;
206
+ }
207
+ function formatSuccessCard(title, rows = []) {
208
+ const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc.dim("\u2502")} ${pc.dim(key.padEnd(12))} ${value}`);
209
+ return [formatSection(title), ...body].join(`
210
+ `);
211
+ }
212
+ function formatNextSteps(steps) {
213
+ if (steps.length === 0)
214
+ return [];
215
+ return [pc.bold("Next"), ...steps.map((step) => `${pc.dim("\u203A")} ${step}`)];
216
+ }
217
+ function formatConnectionList(connections) {
218
+ const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
219
+ const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
220
+ const lines = rows.map(([alias, connection]) => [
221
+ pc.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
222
+ formatStatusPill(connection.kind),
223
+ connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
224
+ ].join(" "));
225
+ return [formatSection("Rig servers", `${rows.length} available`), `${pc.bold(pad("ALIAS", aliasWidth))} ${pc.bold("KIND")} ${pc.bold("TARGET")}`, ...lines, "", ...formatNextSteps(["Select one: `rig server use <alias|local>`"])].join(`
226
+ `);
227
+ }
228
+ function formatConnectionStatus(selected, connections) {
229
+ const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
230
+ const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
231
+ return [
232
+ formatSection("Rig server", "selected for this repo"),
233
+ `${pc.dim("\u2502")} ${pc.dim("selected ")} ${pc.bold(selected)}`,
234
+ `${pc.dim("\u2502")} ${pc.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
235
+ `${pc.dim("\u2502")} ${pc.dim("target ")} ${target ?? "not configured"}`,
236
+ "",
237
+ ...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
238
+ ].join(`
239
+ `);
240
+ }
241
+
242
+ // packages/cli/src/commands/connect.ts
243
+ function usageName(options) {
244
+ return `rig ${options.group}`;
245
+ }
246
+ function parseConnection(alias, value, options) {
247
+ if (alias === "local" && !value)
248
+ return { kind: "local", mode: "auto" };
249
+ if (!value)
250
+ throw new CliError2(`Missing remote server URL. Usage: ${usageName(options)} add <alias> <url>`, 1);
251
+ let parsed;
252
+ try {
253
+ parsed = new URL(value);
254
+ } catch {
255
+ throw new CliError2(`Invalid Rig server URL: ${value}`, 1);
256
+ }
257
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
258
+ throw new CliError2("Rig remote server URL must be http(s).", 1);
259
+ }
260
+ return { kind: "remote", baseUrl: parsed.toString().replace(/\/+$/, "") };
261
+ }
262
+ function printJsonOrText(context, payload, text) {
263
+ if (context.outputMode === "json") {
264
+ console.log(JSON.stringify(payload, null, 2));
265
+ } else {
266
+ console.log(text);
267
+ }
268
+ }
269
+ async function promptForConnectionAlias(context) {
270
+ const state = readGlobalConnections();
271
+ const repo = readRepoConnection(context.projectRoot);
272
+ const options = [
273
+ { value: "local", label: "local", hint: "Use/start a local Rig server" },
274
+ ...Object.entries(state.connections).map(([alias, connection]) => ({
275
+ value: alias,
276
+ label: alias,
277
+ hint: connection.kind === "remote" ? connection.baseUrl : "local"
278
+ }))
279
+ ].filter((option, index, all) => all.findIndex((candidate) => candidate.value === option.value) === index);
280
+ const answer = await select({
281
+ message: "Select Rig server for this repo",
282
+ initialValue: repo?.selected ?? "local",
283
+ options
284
+ });
285
+ if (isCancel(answer)) {
286
+ cancel("No server selected.");
287
+ throw new CliError2("No server selected.", 3);
288
+ }
289
+ return String(answer);
290
+ }
291
+ async function executeConnectionCommand(context, args, options) {
292
+ const [command, ...rest] = args;
293
+ switch (command ?? "status") {
294
+ case "list": {
295
+ requireNoExtraArgs(rest, `${usageName(options)} list`);
296
+ const state = readGlobalConnections();
297
+ printJsonOrText(context, state, formatConnectionList(state.connections));
298
+ return { ok: true, group: options.group, command: "list", details: state };
299
+ }
300
+ case "add": {
301
+ const [alias, url, ...extra] = rest;
302
+ if (!alias)
303
+ throw new CliError2(`Missing alias. Usage: ${usageName(options)} add <alias> <url>`, 1);
304
+ requireNoExtraArgs(extra, `${usageName(options)} add <alias> <url>`);
305
+ const connection = parseConnection(alias, url, options);
306
+ const state = upsertGlobalConnection(alias, connection);
307
+ printJsonOrText(context, { alias, connection }, formatSuccessCard("Rig server saved", [
308
+ ["alias", alias],
309
+ ["target", connection.kind === "remote" ? connection.baseUrl : "local"],
310
+ ["next", `${usageName(options)} use ${alias}`]
311
+ ]));
312
+ return { ok: true, group: options.group, command: "add", details: { alias, connection, count: Object.keys(state.connections).length } };
313
+ }
314
+ case "use": {
315
+ let [alias, ...extra] = rest;
316
+ requireNoExtraArgs(extra, `${usageName(options)} use <alias|local>`);
317
+ if (!alias && options.interactiveUse && context.outputMode === "text" && process.stdin.isTTY) {
318
+ alias = await promptForConnectionAlias(context);
319
+ }
320
+ if (!alias)
321
+ throw new CliError2(`Missing alias. Usage: ${usageName(options)} use <alias|local>`, 1);
322
+ if (alias !== "local") {
323
+ const state = readGlobalConnections();
324
+ if (!state.connections[alias])
325
+ throw new CliError2(`Unknown Rig server: ${alias}`, 1);
326
+ }
327
+ const repoState = { selected: alias, linkedAt: new Date().toISOString() };
328
+ writeRepoConnection(context.projectRoot, repoState);
329
+ printJsonOrText(context, repoState, formatSuccessCard("Rig server selected", [
330
+ ["selected", alias],
331
+ ["scope", "this repo"],
332
+ ["next", "rig task list"]
333
+ ]));
334
+ return { ok: true, group: options.group, command: "use", details: repoState };
335
+ }
336
+ case "status": {
337
+ requireNoExtraArgs(rest, `${usageName(options)} status`);
338
+ const repo = readRepoConnection(context.projectRoot);
339
+ const global = readGlobalConnections();
340
+ const details = { selected: repo?.selected ?? "local", repo, connections: global.connections };
341
+ printJsonOrText(context, details, formatConnectionStatus(details.selected, global.connections));
342
+ return { ok: true, group: options.group, command: "status", details };
343
+ }
344
+ default:
345
+ throw new CliError2(`Unknown ${options.group} command: ${String(command)}
346
+ Usage: ${usageName(options)} <list|add|use|status>`, 1);
147
347
  }
148
- return { alias: repo.selected, connection };
149
348
  }
150
349
 
151
350
  // packages/cli/src/commands/_server-client.ts
152
- var cachedGitHubBearerToken;
351
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
352
+ import { resolve as resolve2 } from "path";
353
+ import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
354
+ var scopedGitHubBearerTokens = new Map;
153
355
  function cleanToken(value) {
154
356
  const trimmed = value?.trim();
155
357
  return trimmed ? trimmed : null;
@@ -166,41 +368,47 @@ function readPrivateRemoteSessionToken(projectRoot) {
166
368
  }
167
369
  }
168
370
  function readGitHubBearerTokenForRemote(projectRoot) {
169
- if (cachedGitHubBearerToken !== undefined)
170
- return cachedGitHubBearerToken;
371
+ const scopedKey = resolve2(projectRoot);
372
+ if (scopedGitHubBearerTokens.has(scopedKey))
373
+ return scopedGitHubBearerTokens.get(scopedKey) ?? null;
171
374
  const privateSession = readPrivateRemoteSessionToken(projectRoot);
172
- if (privateSession) {
173
- cachedGitHubBearerToken = privateSession;
174
- return cachedGitHubBearerToken;
175
- }
176
- const envToken = cleanToken(process.env.RIG_GITHUB_TOKEN) ?? cleanToken(process.env.GITHUB_TOKEN) ?? cleanToken(process.env.GH_TOKEN);
177
- if (envToken) {
178
- cachedGitHubBearerToken = envToken;
179
- return cachedGitHubBearerToken;
375
+ if (privateSession)
376
+ return privateSession;
377
+ return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
378
+ }
379
+ function readStoredGitHubAuthToken(projectRoot) {
380
+ const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
381
+ if (!existsSync2(path))
382
+ return null;
383
+ try {
384
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
385
+ return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
386
+ } catch {
387
+ return null;
180
388
  }
181
- const result = spawnSync("gh", ["auth", "token"], {
182
- encoding: "utf8",
183
- timeout: 5000,
184
- stdio: ["ignore", "pipe", "ignore"]
185
- });
186
- cachedGitHubBearerToken = result.status === 0 ? cleanToken(result.stdout) : null;
187
- return cachedGitHubBearerToken;
389
+ }
390
+ function readLocalConnectionFallbackToken(projectRoot) {
391
+ return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
188
392
  }
189
393
  async function ensureServerForCli(projectRoot) {
190
394
  try {
191
395
  const selected = resolveSelectedConnection(projectRoot);
192
396
  if (selected?.connection.kind === "remote") {
397
+ const authToken = readGitHubBearerTokenForRemote(projectRoot);
398
+ const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
193
399
  return {
194
400
  baseUrl: selected.connection.baseUrl,
195
- authToken: readGitHubBearerTokenForRemote(projectRoot),
196
- connectionKind: "remote"
401
+ authToken,
402
+ connectionKind: "remote",
403
+ serverProjectRoot
197
404
  };
198
405
  }
199
406
  const connection = await ensureLocalRigServerConnection(projectRoot);
200
407
  return {
201
408
  baseUrl: connection.baseUrl,
202
- authToken: connection.authToken,
203
- connectionKind: "local"
409
+ authToken: connection.authToken ?? readLocalConnectionFallbackToken(projectRoot),
410
+ connectionKind: "local",
411
+ serverProjectRoot: resolve2(projectRoot)
204
412
  };
205
413
  } catch (error) {
206
414
  if (error instanceof Error) {
@@ -209,6 +417,29 @@ async function ensureServerForCli(projectRoot) {
209
417
  throw error;
210
418
  }
211
419
  }
420
+ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
421
+ const repo = readRepoConnection(projectRoot);
422
+ const slug = repo?.project?.trim();
423
+ if (!slug)
424
+ return null;
425
+ try {
426
+ const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
427
+ headers: mergeHeaders(undefined, authToken)
428
+ });
429
+ if (!response.ok)
430
+ return null;
431
+ const payload = await response.json();
432
+ const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
433
+ const checkouts = Array.isArray(project?.checkouts) ? project.checkouts : [];
434
+ const latestCheckout = [...checkouts].reverse().find((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.path === "string"));
435
+ const path = typeof latestCheckout?.path === "string" && latestCheckout.path.trim() ? latestCheckout.path.trim() : null;
436
+ if (path)
437
+ writeRepoServerProjectRoot(projectRoot, path);
438
+ return path;
439
+ } catch {
440
+ return null;
441
+ }
442
+ }
212
443
  function mergeHeaders(headers, authToken) {
213
444
  const merged = new Headers(headers);
214
445
  if (authToken) {
@@ -233,9 +464,12 @@ function diagnosticMessage(payload) {
233
464
  }
234
465
  async function requestServerJson(context, pathname, init = {}) {
235
466
  const server = await ensureServerForCli(context.projectRoot);
467
+ const headers = mergeHeaders(init.headers, server.authToken);
468
+ if (server.serverProjectRoot)
469
+ headers.set("x-rig-project-root", server.serverProjectRoot);
236
470
  const response = await fetch(`${server.baseUrl}${pathname}`, {
237
471
  ...init,
238
- headers: mergeHeaders(init.headers, server.authToken)
472
+ headers
239
473
  });
240
474
  const text = await response.text();
241
475
  const payload = text.trim().length > 0 ? (() => {
@@ -286,7 +520,10 @@ async function submitTaskRunViaServer(context, input) {
286
520
 
287
521
  // packages/cli/src/commands/server.ts
288
522
  async function executeServer(context, args, options) {
289
- const [command = "start", ...rest] = args;
523
+ const [command = "status", ...rest] = args;
524
+ if (["status", "list", "add", "use"].includes(command)) {
525
+ return executeConnectionCommand(context, [command, ...rest], { group: "server", interactiveUse: true });
526
+ }
290
527
  switch (command) {
291
528
  case "start": {
292
529
  let pending = rest;
@@ -298,8 +535,9 @@ async function executeServer(context, args, options) {
298
535
  pending = pollResult.rest;
299
536
  const authTokenResult = takeOption(pending, "--auth-token");
300
537
  pending = authTokenResult.rest;
301
- requireNoExtraArgs(pending, "bun run rig server start [--host <host>] [--port <n>] [--poll-ms <n>] [--auth-token <token>]");
302
- const commandParts = ["rig-server", "start"];
538
+ requireNoExtraArgs(pending, "rig server start [--host <host>] [--port <n>] [--poll-ms <n>] [--auth-token <token>]");
539
+ const serverCommand = resolveRigServerCommand(context.projectRoot);
540
+ const commandParts = [serverCommand.command, ...serverCommand.commandArgs, "start"];
303
541
  if (hostResult.value) {
304
542
  commandParts.push("--host", hostResult.value);
305
543
  }
@@ -321,8 +559,9 @@ async function executeServer(context, args, options) {
321
559
  let pending = rest;
322
560
  const eventResult = takeOption(pending, "--event");
323
561
  pending = eventResult.rest;
324
- requireNoExtraArgs(pending, "bun run rig server notify-test [--event <type>]");
325
- const commandParts = ["rig-server", "notify-test"];
562
+ requireNoExtraArgs(pending, "rig server notify-test [--event <type>]");
563
+ const serverCommand = resolveRigServerCommand(context.projectRoot);
564
+ const commandParts = [serverCommand.command, ...serverCommand.commandArgs, "notify-test"];
326
565
  if (eventResult.value) {
327
566
  commandParts.push("--event", eventResult.value);
328
567
  }
@@ -349,7 +588,7 @@ async function executeServer(context, args, options) {
349
588
  pending = dirtyBaselineResult.rest;
350
589
  const prResult = takeOption(pending, "--pr");
351
590
  pending = prResult.rest;
352
- requireNoExtraArgs(pending, "bun run rig --run-id <run-id> server task-run [--task <id>] [--title <text>] [--runtime-adapter claude-code|codex|pi] [--model <model>] [--runtime-mode <mode>] [--interaction-mode <mode>] [--initial-prompt <text>] [--dirty-baseline head|dirty-snapshot] [--pr auto|ask|off]");
591
+ requireNoExtraArgs(pending, "rig --run-id <run-id> server task-run [--task <id>] [--title <text>] [--runtime-adapter claude-code|codex|pi] [--model <model>] [--runtime-mode <mode>] [--interaction-mode <mode>] [--initial-prompt <text>] [--dirty-baseline head|dirty-snapshot] [--pr auto|ask|off]");
353
592
  if (!taskResult.value && !initialPromptResult.value && !titleResult.value) {
354
593
  throw new CliError2("server task-run requires either --task <id> or --initial-prompt/--title for an ad hoc run.", 2);
355
594
  }