@h-rig/cli-surface-plugin 0.0.6-alpha.146

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 (94) hide show
  1. package/README.md +1 -0
  2. package/dist/src/app/drone-ui.d.ts +34 -0
  3. package/dist/src/app/drone-ui.js +278 -0
  4. package/dist/src/commands/_async-ui.d.ts +10 -0
  5. package/dist/src/commands/_async-ui.js +121 -0
  6. package/dist/src/commands/_cli-format.d.ts +56 -0
  7. package/dist/src/commands/_cli-format.js +332 -0
  8. package/dist/src/commands/_connection-state.d.ts +54 -0
  9. package/dist/src/commands/_connection-state.js +187 -0
  10. package/dist/src/commands/_doctor-checks.d.ts +9 -0
  11. package/dist/src/commands/_doctor-checks.js +24 -0
  12. package/dist/src/commands/_help-catalog.d.ts +29 -0
  13. package/dist/src/commands/_help-catalog.js +157 -0
  14. package/dist/src/commands/_inprocess-services.d.ts +33 -0
  15. package/dist/src/commands/_inprocess-services.js +102 -0
  16. package/dist/src/commands/_json-output.d.ts +11 -0
  17. package/dist/src/commands/_json-output.js +54 -0
  18. package/dist/src/commands/_parsers.d.ts +15 -0
  19. package/dist/src/commands/_parsers.js +114 -0
  20. package/dist/src/commands/_paths.d.ts +11 -0
  21. package/dist/src/commands/_paths.js +50 -0
  22. package/dist/src/commands/_pi-frontend.d.ts +35 -0
  23. package/dist/src/commands/_pi-frontend.js +64 -0
  24. package/dist/src/commands/_pi-install.d.ts +42 -0
  25. package/dist/src/commands/_pi-install.js +167 -0
  26. package/dist/src/commands/_policy.d.ts +8 -0
  27. package/dist/src/commands/_policy.js +138 -0
  28. package/dist/src/commands/_probes.d.ts +1 -0
  29. package/dist/src/commands/_probes.js +13 -0
  30. package/dist/src/commands/_run-driver-helpers.d.ts +26 -0
  31. package/dist/src/commands/_run-driver-helpers.js +132 -0
  32. package/dist/src/commands/_run-subcommands.d.ts +3 -0
  33. package/dist/src/commands/_run-subcommands.js +31 -0
  34. package/dist/src/commands/_spinner.d.ts +25 -0
  35. package/dist/src/commands/_spinner.js +65 -0
  36. package/dist/src/commands/agent.d.ts +3 -0
  37. package/dist/src/commands/agent.js +322 -0
  38. package/dist/src/commands/config.d.ts +3 -0
  39. package/dist/src/commands/config.js +193 -0
  40. package/dist/src/commands/dist.d.ts +28 -0
  41. package/dist/src/commands/dist.js +435 -0
  42. package/dist/src/commands/doctor.d.ts +3 -0
  43. package/dist/src/commands/doctor.js +171 -0
  44. package/dist/src/commands/github.d.ts +3 -0
  45. package/dist/src/commands/github.js +342 -0
  46. package/dist/src/commands/inbox.d.ts +19 -0
  47. package/dist/src/commands/inbox.js +241 -0
  48. package/dist/src/commands/init.d.ts +64 -0
  49. package/dist/src/commands/init.js +1449 -0
  50. package/dist/src/commands/inspect.d.ts +20 -0
  51. package/dist/src/commands/inspect.js +337 -0
  52. package/dist/src/commands/pi.d.ts +3 -0
  53. package/dist/src/commands/pi.js +177 -0
  54. package/dist/src/commands/plugin.d.ts +20 -0
  55. package/dist/src/commands/plugin.js +238 -0
  56. package/dist/src/commands/profile-and-review.d.ts +4 -0
  57. package/dist/src/commands/profile-and-review.js +223 -0
  58. package/dist/src/commands/queue.d.ts +3 -0
  59. package/dist/src/commands/queue.js +197 -0
  60. package/dist/src/commands/remote.d.ts +3 -0
  61. package/dist/src/commands/remote.js +516 -0
  62. package/dist/src/commands/repo-git-harness.d.ts +5 -0
  63. package/dist/src/commands/repo-git-harness.js +282 -0
  64. package/dist/src/commands/run.d.ts +22 -0
  65. package/dist/src/commands/run.js +645 -0
  66. package/dist/src/commands/server.d.ts +3 -0
  67. package/dist/src/commands/server.js +155 -0
  68. package/dist/src/commands/setup.d.ts +16 -0
  69. package/dist/src/commands/setup.js +356 -0
  70. package/dist/src/commands/stats.d.ts +11 -0
  71. package/dist/src/commands/stats.js +219 -0
  72. package/dist/src/commands/task-run-driver.d.ts +93 -0
  73. package/dist/src/commands/task-run-driver.js +136 -0
  74. package/dist/src/commands/task.d.ts +46 -0
  75. package/dist/src/commands/task.js +555 -0
  76. package/dist/src/commands/test.d.ts +3 -0
  77. package/dist/src/commands/test.js +46 -0
  78. package/dist/src/commands/triage.d.ts +11 -0
  79. package/dist/src/commands/triage.js +224 -0
  80. package/dist/src/commands/workspace.d.ts +3 -0
  81. package/dist/src/commands/workspace.js +130 -0
  82. package/dist/src/kernel-dispatch.d.ts +15 -0
  83. package/dist/src/kernel-dispatch.js +16 -0
  84. package/dist/src/plugin.d.ts +3 -0
  85. package/dist/src/plugin.js +5440 -0
  86. package/dist/src/rig-config-package-deps.d.ts +10 -0
  87. package/dist/src/rig-config-package-deps.js +272 -0
  88. package/dist/src/runner.d.ts +47 -0
  89. package/dist/src/runner.js +267 -0
  90. package/dist/src/version.d.ts +8 -0
  91. package/dist/src/version.js +47 -0
  92. package/dist/src/withMutedConsole.d.ts +2 -0
  93. package/dist/src/withMutedConsole.js +42 -0
  94. package/package.json +34 -0
@@ -0,0 +1,516 @@
1
+ // @bun
2
+ // packages/cli-surface-plugin/src/runner.ts
3
+ import { EventBus } from "@rig/runtime/control-plane/runtime/events";
4
+ import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
5
+ import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
6
+ import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
7
+
8
+ class CliError extends RuntimeCliError {
9
+ hint;
10
+ constructor(message, exitCode = 1, options = {}) {
11
+ super(message, exitCode);
12
+ if (options.hint?.trim()) {
13
+ this.hint = options.hint.trim();
14
+ }
15
+ }
16
+ }
17
+ function takeFlag(args, flag) {
18
+ const rest = [];
19
+ let value = false;
20
+ for (const arg of args) {
21
+ if (arg === flag) {
22
+ value = true;
23
+ continue;
24
+ }
25
+ rest.push(arg);
26
+ }
27
+ return { value, rest };
28
+ }
29
+ function takeOption(args, option) {
30
+ const rest = [];
31
+ let value;
32
+ for (let index = 0;index < args.length; index += 1) {
33
+ const current = args[index];
34
+ if (current === option) {
35
+ const next = args[index + 1];
36
+ if (!next || next.startsWith("-")) {
37
+ throw new CliError(`Missing value for ${option}`, 1, { hint: `Provide a value after ${option}, e.g. \`${option} <value>\`.` });
38
+ }
39
+ value = next;
40
+ index += 1;
41
+ continue;
42
+ }
43
+ if (current !== undefined) {
44
+ rest.push(current);
45
+ }
46
+ }
47
+ return { value, rest };
48
+ }
49
+ function requireNoExtraArgs(args, usage) {
50
+ if (args.length > 0) {
51
+ throw new CliError(`Unexpected arguments: ${args.join(" ")}
52
+ Usage: ${usage}`);
53
+ }
54
+ }
55
+ function requireTask(taskId, usage) {
56
+ if (!taskId) {
57
+ throw new CliError(`Missing --task option.
58
+ Usage: ${usage}`);
59
+ }
60
+ return taskId;
61
+ }
62
+
63
+ // packages/cli-surface-plugin/src/commands/remote.ts
64
+ import {
65
+ doctorAuthorityRemoteEndpoints as doctorManagedRemoteEndpoints,
66
+ importLegacyRemoteEndpoints as migrateManagedRemoteEndpoints,
67
+ listManagedRemoteEndpoints,
68
+ RemoteCliError,
69
+ removeManagedRemoteEndpoint,
70
+ updateAuthorityRemoteEndpoint as updateManagedRemoteEndpointInAuthority,
71
+ upsertManagedRemoteEndpoint
72
+ } from "@rig/runtime/control-plane/remote-config";
73
+ import {
74
+ matchesEventFilter,
75
+ RemoteWsClient,
76
+ resolveRemoteEndpoint,
77
+ summarizeMessage
78
+ } from "@rig/runtime/control-plane/remote";
79
+
80
+ // packages/cli-surface-plugin/src/commands/_parsers.ts
81
+ function parseOptionalPositiveInt(value, option) {
82
+ if (!value) {
83
+ return;
84
+ }
85
+ const parsed = Number.parseInt(value, 10);
86
+ if (!Number.isFinite(parsed) || parsed <= 0) {
87
+ throw new CliError(`Invalid ${option} value: ${value}`, 1, { hint: `Pass a positive integer, e.g. \`${option} 10\`.` });
88
+ }
89
+ return parsed;
90
+ }
91
+ function parseRequiredPositiveInt(value, option) {
92
+ if (!value) {
93
+ throw new CliError(`Missing value for ${option}.`, 1, { hint: `Provide a value after ${option}, e.g. \`${option} 10\`.` });
94
+ }
95
+ const parsed = Number.parseInt(value, 10);
96
+ if (!Number.isFinite(parsed) || parsed <= 0) {
97
+ throw new CliError(`Invalid ${option} value: ${value}`, 1, { hint: `Pass a positive integer, e.g. \`${option} 10\`.` });
98
+ }
99
+ return parsed;
100
+ }
101
+
102
+ // packages/cli-surface-plugin/src/commands/remote.ts
103
+ function assertRemoteOperationSuccess(command, response) {
104
+ if (!("success" in response)) {
105
+ return;
106
+ }
107
+ if (response.success === false) {
108
+ const error = typeof response.error === "string" && response.error || `${command} failed without explicit error detail from remote server.`;
109
+ throw new RemoteCliError("RIG_REMOTE_OPERATION_FAILED", error, 3, { command, response: redactSecretFields(response) });
110
+ }
111
+ }
112
+ function redactRemoteEndpoint(endpoint) {
113
+ const { token, ...rest } = endpoint;
114
+ return {
115
+ ...rest,
116
+ token: "",
117
+ tokenConfigured: token.trim().length > 0
118
+ };
119
+ }
120
+ function isRecord(value) {
121
+ return value !== null && typeof value === "object" && !Array.isArray(value);
122
+ }
123
+ function isSecretKey(key) {
124
+ const normalized = key.toLowerCase();
125
+ return normalized === "token" || normalized === "authtoken" || normalized === "authorization" || normalized === "connectiontoken" || normalized === "access_token" || normalized === "secret";
126
+ }
127
+ function redactSecretFields(value) {
128
+ if (Array.isArray(value)) {
129
+ return value.map((entry) => redactSecretFields(entry));
130
+ }
131
+ if (!isRecord(value)) {
132
+ return value;
133
+ }
134
+ const redacted = {};
135
+ for (const [key, entry] of Object.entries(value)) {
136
+ redacted[key] = isSecretKey(key) && typeof entry === "string" ? entry.trim().length > 0 ? "[redacted]" : "" : redactSecretFields(entry);
137
+ }
138
+ return redacted;
139
+ }
140
+ async function executeRemote(context, args) {
141
+ const [command = "status", ...rest] = args;
142
+ if (command === "endpoint" || command === "endpoints") {
143
+ const [subcommand = "list", ...subRest] = rest;
144
+ switch (subcommand) {
145
+ case "list": {
146
+ requireNoExtraArgs(subRest, "rig remote endpoint list");
147
+ const endpoints = listManagedRemoteEndpoints(undefined, context.projectRoot);
148
+ const redactedEndpoints = endpoints.map((endpoint2) => redactRemoteEndpoint(endpoint2));
149
+ if (context.outputMode === "text") {
150
+ if (endpoints.length === 0) {
151
+ console.log("No remote endpoints configured.");
152
+ } else {
153
+ for (const endpoint2 of endpoints) {
154
+ console.log(`- ${endpoint2.alias} \xB7 ${endpoint2.host}:${endpoint2.port}${endpoint2.lastConnected ? ` \xB7 last connected ${endpoint2.lastConnected}` : ""}`);
155
+ }
156
+ }
157
+ }
158
+ return { ok: true, group: "remote", command: "endpoint list", details: { endpoints: redactedEndpoints } };
159
+ }
160
+ case "add": {
161
+ let pending2 = subRest;
162
+ const alias = takeOption(pending2, "--alias");
163
+ pending2 = alias.rest;
164
+ const host = takeOption(pending2, "--host");
165
+ pending2 = host.rest;
166
+ const port = takeOption(pending2, "--port");
167
+ pending2 = port.rest;
168
+ const token = takeOption(pending2, "--token");
169
+ pending2 = token.rest;
170
+ requireNoExtraArgs(pending2, "rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>");
171
+ if (!alias.value || !host.value || !token.value || !port.value) {
172
+ throw new CliError("remote endpoint add requires --alias, --host, --port, and --token.", 1, { hint: "Re-run as `rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>`." });
173
+ }
174
+ const created = upsertManagedRemoteEndpoint({
175
+ alias: alias.value,
176
+ host: host.value,
177
+ port: parseRequiredPositiveInt(port.value, "--port"),
178
+ token: token.value
179
+ }, undefined, context.projectRoot);
180
+ if (context.outputMode === "text") {
181
+ console.log(`Saved remote endpoint ${created.alias} -> ${created.host}:${created.port}`);
182
+ }
183
+ return { ok: true, group: "remote", command: "endpoint add", details: redactRemoteEndpoint(created) };
184
+ }
185
+ case "update": {
186
+ let pending2 = subRest;
187
+ const endpointId = takeOption(pending2, "--id");
188
+ pending2 = endpointId.rest;
189
+ const alias = takeOption(pending2, "--alias");
190
+ pending2 = alias.rest;
191
+ const host = takeOption(pending2, "--host");
192
+ pending2 = host.rest;
193
+ const port = takeOption(pending2, "--port");
194
+ pending2 = port.rest;
195
+ const token = takeOption(pending2, "--token");
196
+ pending2 = token.rest;
197
+ requireNoExtraArgs(pending2, "rig remote endpoint update --id <id> [--alias <a>] [--host <h>] [--port <n>] [--token <t>]");
198
+ if (!endpointId.value && !alias.value) {
199
+ throw new CliError("remote endpoint update requires --id <id> or --alias <a>.", 1, { hint: "List endpoints with `rig remote endpoint list`, then pass --id or --alias." });
200
+ }
201
+ const updated = updateManagedRemoteEndpointInAuthority(context.projectRoot, {
202
+ endpointId: endpointId.value || undefined,
203
+ alias: alias.value || undefined,
204
+ host: host.value || undefined,
205
+ port: port.value ? parseRequiredPositiveInt(port.value, "--port") : undefined,
206
+ token: token.value || undefined
207
+ });
208
+ if (!updated) {
209
+ throw new CliError("Remote endpoint not found.", 2, { hint: "Run `rig remote endpoint list` to see configured endpoints." });
210
+ }
211
+ if (context.outputMode === "text") {
212
+ console.log(`Updated remote endpoint ${updated.alias} -> ${updated.host}:${updated.port}`);
213
+ }
214
+ return { ok: true, group: "remote", command: "endpoint update", details: redactRemoteEndpoint(updated) };
215
+ }
216
+ case "remove": {
217
+ let pending2 = subRest;
218
+ const alias = takeOption(pending2, "--alias");
219
+ pending2 = alias.rest;
220
+ requireNoExtraArgs(pending2, "rig remote endpoint remove --alias <a>");
221
+ if (!alias.value) {
222
+ throw new CliError("remote endpoint remove requires --alias.", 1, { hint: "Run `rig remote endpoint list` to find the alias, then `rig remote endpoint remove --alias <a>`." });
223
+ }
224
+ const removed = removeManagedRemoteEndpoint(alias.value, undefined, context.projectRoot);
225
+ if (!removed) {
226
+ throw new CliError(`Remote endpoint alias not found: ${alias.value}`, 2, { hint: "Run `rig remote endpoint list` to see configured endpoint aliases." });
227
+ }
228
+ if (context.outputMode === "text") {
229
+ console.log(`Removed remote endpoint ${alias.value}`);
230
+ }
231
+ return { ok: true, group: "remote", command: "endpoint remove", details: { alias: alias.value } };
232
+ }
233
+ case "test": {
234
+ let pending2 = subRest;
235
+ const alias = takeOption(pending2, "--alias");
236
+ pending2 = alias.rest;
237
+ requireNoExtraArgs(pending2, "rig remote endpoint test --alias <a>");
238
+ if (!alias.value) {
239
+ throw new CliError("remote endpoint test requires --alias.", 1, { hint: "Run `rig remote endpoint list` to find the alias, then `rig remote endpoint test --alias <a>`." });
240
+ }
241
+ const endpoint2 = resolveRemoteEndpoint({ remoteAlias: alias.value, projectRoot: context.projectRoot });
242
+ const client = new RemoteWsClient(endpoint2);
243
+ const startedAt = Date.now();
244
+ try {
245
+ await client.connect();
246
+ const response = await client.ping();
247
+ const latencyMs = Date.now() - startedAt;
248
+ if (context.outputMode === "text") {
249
+ console.log(`Remote endpoint ${alias.value} responded in ${latencyMs}ms.`);
250
+ }
251
+ return {
252
+ ok: true,
253
+ group: "remote",
254
+ command: "endpoint test",
255
+ details: {
256
+ alias: alias.value,
257
+ host: endpoint2.host,
258
+ port: endpoint2.port,
259
+ latencyMs,
260
+ response: redactSecretFields(response)
261
+ }
262
+ };
263
+ } finally {
264
+ client.disconnect();
265
+ }
266
+ }
267
+ case "migrate": {
268
+ requireNoExtraArgs(subRest, "rig remote endpoint migrate");
269
+ const result = migrateManagedRemoteEndpoints(context.projectRoot);
270
+ if (context.outputMode === "text") {
271
+ console.log(`Imported ${result.imported} endpoint(s) from ${result.sourcePath}${result.skipped > 0 ? `, skipped ${result.skipped}` : ""}.`);
272
+ }
273
+ return { ok: true, group: "remote", command: "endpoint migrate", details: result };
274
+ }
275
+ case "doctor": {
276
+ requireNoExtraArgs(subRest, "rig remote endpoint doctor");
277
+ const result = doctorManagedRemoteEndpoints(context.projectRoot);
278
+ if (context.outputMode === "text") {
279
+ console.log(JSON.stringify(result, null, 2));
280
+ }
281
+ return { ok: true, group: "remote", command: "endpoint doctor", details: result };
282
+ }
283
+ default:
284
+ throw new CliError(`Unknown remote endpoint command: ${subcommand}`, 1, { hint: "Run `rig remote --help` for endpoint commands (list|add|update|remove|test)." });
285
+ }
286
+ }
287
+ let pending = rest;
288
+ const remoteAliasResult = takeOption(pending, "--remote");
289
+ pending = remoteAliasResult.rest;
290
+ const hostResult = takeOption(pending, "--host");
291
+ pending = hostResult.rest;
292
+ const portResult = takeOption(pending, "--port");
293
+ pending = portResult.rest;
294
+ const tokenResult = takeOption(pending, "--token");
295
+ pending = tokenResult.rest;
296
+ const endpoint = resolveRemoteEndpoint({
297
+ host: hostResult.value,
298
+ port: portResult.value,
299
+ token: tokenResult.value,
300
+ remoteAlias: remoteAliasResult.value,
301
+ projectRoot: context.projectRoot
302
+ });
303
+ const remoteMeta = {
304
+ source: endpoint.source,
305
+ alias: endpoint.alias || null,
306
+ host: endpoint.host,
307
+ port: endpoint.port
308
+ };
309
+ const withClient = async (runner) => {
310
+ const client = new RemoteWsClient(endpoint);
311
+ try {
312
+ await client.connect();
313
+ return await runner(client);
314
+ } finally {
315
+ client.disconnect();
316
+ }
317
+ };
318
+ const toDetails = (response) => ({
319
+ command: `remote ${command}`,
320
+ remote: remoteMeta,
321
+ requestId: response.id || null,
322
+ messageType: response.type,
323
+ payload: redactSecretFields(response),
324
+ error: null
325
+ });
326
+ try {
327
+ switch (command) {
328
+ case "test": {
329
+ requireNoExtraArgs(pending, "rig remote test [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
330
+ const response = await withClient((client) => client.ping());
331
+ return { ok: true, group: "remote", command, details: toDetails(response) };
332
+ }
333
+ case "status": {
334
+ requireNoExtraArgs(pending, "rig remote status [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
335
+ const response = await withClient((client) => client.getState());
336
+ return { ok: true, group: "remote", command, details: toDetails(response) };
337
+ }
338
+ case "tasks": {
339
+ requireNoExtraArgs(pending, "rig remote tasks [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
340
+ const response = await withClient((client) => client.getTasks());
341
+ return { ok: true, group: "remote", command, details: toDetails(response) };
342
+ }
343
+ case "watch": {
344
+ let watchPending = pending;
345
+ const secondsResult = takeOption(watchPending, "--seconds");
346
+ watchPending = secondsResult.rest;
347
+ const eventResult = takeOption(watchPending, "--event");
348
+ watchPending = eventResult.rest;
349
+ requireNoExtraArgs(watchPending, "rig remote watch [--seconds <n>] [--event <type>] [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
350
+ const seconds = parseOptionalPositiveInt(secondsResult.value, "--seconds");
351
+ const eventFilter = eventResult.value || undefined;
352
+ if (context.outputMode === "json" && !seconds) {
353
+ throw new CliError("--json remote watch requires --seconds <n> to produce bounded output.", 2, { hint: "Re-run as `rig remote watch --seconds 10 --json`." });
354
+ }
355
+ const captured = [];
356
+ let dropped = 0;
357
+ let received = 0;
358
+ let stop = false;
359
+ const onSignal = () => {
360
+ stop = true;
361
+ };
362
+ process.once("SIGINT", onSignal);
363
+ process.once("SIGTERM", onSignal);
364
+ try {
365
+ await withClient(async (client) => {
366
+ client.setEventHandler((event) => {
367
+ if (!matchesEventFilter(event.message, eventFilter)) {
368
+ return;
369
+ }
370
+ received += 1;
371
+ if (context.outputMode === "text") {
372
+ console.log(`[${event.receivedAt}] ${summarizeMessage(event.message)}`);
373
+ } else if (captured.length < 200) {
374
+ captured.push(event.message);
375
+ } else {
376
+ dropped += 1;
377
+ }
378
+ });
379
+ const subscribed = await client.subscribe(eventFilter ? [eventFilter] : []);
380
+ if (!subscribed.success) {
381
+ throw new RemoteCliError("RIG_REMOTE_SUBSCRIBE_FAILED", subscribed.error || "Failed to subscribe to remote events.", 3);
382
+ }
383
+ if (seconds) {
384
+ await Bun.sleep(seconds * 1000);
385
+ return;
386
+ }
387
+ while (!stop) {
388
+ await Bun.sleep(250);
389
+ }
390
+ });
391
+ } finally {
392
+ process.off("SIGINT", onSignal);
393
+ process.off("SIGTERM", onSignal);
394
+ }
395
+ return {
396
+ ok: true,
397
+ group: "remote",
398
+ command,
399
+ details: {
400
+ command: "remote watch",
401
+ remote: remoteMeta,
402
+ messageType: "stream",
403
+ requestId: null,
404
+ payload: context.outputMode === "json" ? captured : null,
405
+ error: null,
406
+ received,
407
+ dropped,
408
+ event: eventFilter || null,
409
+ seconds: seconds || null
410
+ }
411
+ };
412
+ }
413
+ case "pause":
414
+ case "resume":
415
+ case "stop":
416
+ case "continue":
417
+ case "refresh": {
418
+ requireNoExtraArgs(pending, `rig remote ${command} [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
419
+ const response = await withClient(async (client) => {
420
+ switch (command) {
421
+ case "pause":
422
+ return await client.pause();
423
+ case "resume":
424
+ return await client.resume();
425
+ case "stop":
426
+ return await client.interrupt();
427
+ case "continue":
428
+ return await client.continueExecution();
429
+ default:
430
+ return await client.refreshTasks();
431
+ }
432
+ });
433
+ assertRemoteOperationSuccess(command, response);
434
+ return { ok: true, group: "remote", command, details: toDetails(response) };
435
+ }
436
+ case "add-iterations":
437
+ case "remove-iterations": {
438
+ let countPending = pending;
439
+ const countResult = takeOption(countPending, "--count");
440
+ countPending = countResult.rest;
441
+ requireNoExtraArgs(countPending, `rig remote ${command} --count <n> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
442
+ const count = parseRequiredPositiveInt(countResult.value, "--count");
443
+ const response = await withClient(async (client) => command === "add-iterations" ? await client.addIterations(count) : await client.removeIterations(count));
444
+ assertRemoteOperationSuccess(command, response);
445
+ return { ok: true, group: "remote", command, details: toDetails(response) };
446
+ }
447
+ case "prompt-preview":
448
+ case "iteration-output": {
449
+ let taskPending = pending;
450
+ const taskResult = takeOption(taskPending, "--task");
451
+ taskPending = taskResult.rest;
452
+ requireNoExtraArgs(taskPending, `rig remote ${command} --task <id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
453
+ const taskId = requireTask(taskResult.value, `rig remote ${command} --task <id>`);
454
+ const response = await withClient(async (client) => command === "prompt-preview" ? await client.getPromptPreview(taskId) : await client.getIterationOutput(taskId));
455
+ assertRemoteOperationSuccess(command, response);
456
+ return { ok: true, group: "remote", command, details: toDetails(response) };
457
+ }
458
+ case "orchestrate-start": {
459
+ let orchestrationPending = pending;
460
+ const maxWorkersResult = takeOption(orchestrationPending, "--max-workers");
461
+ orchestrationPending = maxWorkersResult.rest;
462
+ const maxIterationsResult = takeOption(orchestrationPending, "--max-iterations");
463
+ orchestrationPending = maxIterationsResult.rest;
464
+ const directMergeResult = takeFlag(orchestrationPending, "--direct-merge");
465
+ orchestrationPending = directMergeResult.rest;
466
+ requireNoExtraArgs(orchestrationPending, "rig remote orchestrate-start [--max-workers <n>] [--max-iterations <n>] [--direct-merge]");
467
+ const response = await withClient((client) => client.startOrchestration({
468
+ maxWorkers: parseOptionalPositiveInt(maxWorkersResult.value, "--max-workers"),
469
+ maxIterations: parseOptionalPositiveInt(maxIterationsResult.value, "--max-iterations"),
470
+ directMerge: directMergeResult.value
471
+ }));
472
+ assertRemoteOperationSuccess(command, response);
473
+ return {
474
+ ok: true,
475
+ group: "remote",
476
+ command,
477
+ details: toDetails(response)
478
+ };
479
+ }
480
+ case "orchestrate-pause":
481
+ case "orchestrate-resume":
482
+ case "orchestrate-stop":
483
+ case "orchestrate-state": {
484
+ let orchestrationPending = pending;
485
+ const idResult = takeOption(orchestrationPending, "--id");
486
+ orchestrationPending = idResult.rest;
487
+ requireNoExtraArgs(orchestrationPending, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
488
+ const orchestrationId = requireTask(idResult.value, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
489
+ const response = await withClient(async (client) => {
490
+ switch (command) {
491
+ case "orchestrate-pause":
492
+ return await client.pauseOrchestration(orchestrationId);
493
+ case "orchestrate-resume":
494
+ return await client.resumeOrchestration(orchestrationId);
495
+ case "orchestrate-stop":
496
+ return await client.stopOrchestration(orchestrationId);
497
+ default:
498
+ return await client.getOrchestrationState(orchestrationId);
499
+ }
500
+ });
501
+ assertRemoteOperationSuccess(command, response);
502
+ return { ok: true, group: "remote", command, details: toDetails(response) };
503
+ }
504
+ default:
505
+ throw new CliError(`Unknown remote command: ${command}`, 1, { hint: "Run `rig remote --help` to list remote commands." });
506
+ }
507
+ } catch (error) {
508
+ if (error instanceof RemoteCliError) {
509
+ throw new CliError(`[${error.code}] ${error.message}`, error.exitCode);
510
+ }
511
+ throw error;
512
+ }
513
+ }
514
+ export {
515
+ executeRemote
516
+ };
@@ -0,0 +1,5 @@
1
+ import { type RunnerContext } from "../runner";
2
+ import type { CommandOutcome } from "@rig/runtime";
3
+ export declare function executeRepo(context: RunnerContext, args: string[]): Promise<CommandOutcome>;
4
+ export declare function executeGit(context: RunnerContext, args: string[]): Promise<CommandOutcome>;
5
+ export declare function executeHarness(context: RunnerContext, args: string[]): Promise<CommandOutcome>;