@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,322 @@
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
+
56
+ // packages/cli-surface-plugin/src/commands/agent.ts
57
+ import {
58
+ agentId,
59
+ cleanupAgentRuntime,
60
+ ensureAgentRuntime,
61
+ listAgentRuntimes,
62
+ runInAgentRuntime
63
+ } from "@rig/runtime/control-plane/runtime/isolation";
64
+
65
+ // packages/cli-surface-plugin/src/withMutedConsole.ts
66
+ function isPromise(value) {
67
+ if (typeof value !== "object" && typeof value !== "function") {
68
+ return false;
69
+ }
70
+ return value !== null && typeof value.then === "function";
71
+ }
72
+ function withMutedConsole(mute, fn) {
73
+ if (!mute) {
74
+ return fn();
75
+ }
76
+ const originalLog = console.log;
77
+ const originalWarn = console.warn;
78
+ const originalInfo = console.info;
79
+ const restore = () => {
80
+ console.log = originalLog;
81
+ console.warn = originalWarn;
82
+ console.info = originalInfo;
83
+ };
84
+ console.log = () => {};
85
+ console.warn = () => {};
86
+ console.info = () => {};
87
+ try {
88
+ const result = fn();
89
+ if (isPromise(result)) {
90
+ return result.finally(restore);
91
+ }
92
+ restore();
93
+ return result;
94
+ } catch (error) {
95
+ restore();
96
+ throw error;
97
+ } finally {
98
+ if (console.log === originalLog) {
99
+ restore();
100
+ }
101
+ }
102
+ }
103
+
104
+ // packages/cli-surface-plugin/src/commands/_parsers.ts
105
+ function parseIsolationMode(value, allowOff) {
106
+ if (!value) {
107
+ return "worktree";
108
+ }
109
+ if (value === "worktree") {
110
+ return value;
111
+ }
112
+ if (allowOff && value === "off") {
113
+ return value;
114
+ }
115
+ throw new CliError(`Invalid isolation mode: ${value}. Use ${allowOff ? "off|" : ""}worktree.`);
116
+ }
117
+
118
+ // packages/cli-surface-plugin/src/commands/agent.ts
119
+ import { ensureProjectMainFreshBeforeRun } from "@rig/runtime/control-plane/project-main-pre-run-sync";
120
+ function splitAtDoubleDash(args) {
121
+ const separatorIndex = args.indexOf("--");
122
+ if (separatorIndex === -1) {
123
+ return { options: args, commandParts: [] };
124
+ }
125
+ return {
126
+ options: args.slice(0, separatorIndex),
127
+ commandParts: args.slice(separatorIndex + 1)
128
+ };
129
+ }
130
+ async function attachEventBusToProvisionedRuntime(context, workspaceDir) {
131
+ const previousWorkspace = process.env.RIG_TASK_WORKSPACE;
132
+ process.env.RIG_TASK_WORKSPACE = workspaceDir;
133
+ try {
134
+ await context.eventBus.attachRuntimeWorkspace(context.projectRoot);
135
+ } finally {
136
+ if (previousWorkspace === undefined) {
137
+ delete process.env.RIG_TASK_WORKSPACE;
138
+ } else {
139
+ process.env.RIG_TASK_WORKSPACE = previousWorkspace;
140
+ }
141
+ }
142
+ }
143
+ async function runProjectMainSyncPreflight(context, options) {
144
+ if (context.dryRun) {
145
+ if (context.outputMode === "text" && !options.disabled) {
146
+ console.log("[dry-run] project-rig pre-run sync check");
147
+ }
148
+ return;
149
+ }
150
+ const result = await ensureProjectMainFreshBeforeRun({
151
+ projectRoot: context.projectRoot,
152
+ disabled: options.disabled,
153
+ runBootstrap: async () => {
154
+ const bootstrap = await context.runCommand(["bun", "run", "bootstrap"]);
155
+ if (bootstrap.exitCode !== 0) {
156
+ throw new CliError(bootstrap.stderr || bootstrap.stdout || "bun run bootstrap failed during project pre-run sync", bootstrap.exitCode || 1);
157
+ }
158
+ }
159
+ });
160
+ if (context.outputMode !== "text") {
161
+ return;
162
+ }
163
+ switch (result.status) {
164
+ case "disabled":
165
+ console.log("Project pre-run sync skipped (--skip-project-sync).");
166
+ break;
167
+ case "skipped_not_main":
168
+ console.log(`Project pre-run sync skipped (current branch: ${result.branch}).`);
169
+ break;
170
+ case "up_to_date":
171
+ break;
172
+ case "local_ahead":
173
+ console.log(`Project pre-run sync skipped (local main ahead by ${result.localAhead} commit(s)).`);
174
+ break;
175
+ case "updated":
176
+ console.log(`Project pre-run sync updated local main from origin/main (+${result.remoteAhead}) and bootstrapped.`);
177
+ break;
178
+ }
179
+ }
180
+ async function executeAgent(context, args) {
181
+ const [command = "list", ...rest] = args;
182
+ switch (command) {
183
+ case "list": {
184
+ requireNoExtraArgs(rest, "rig agent list");
185
+ const runtimes = await listAgentRuntimes(context.projectRoot);
186
+ if (context.outputMode === "text") {
187
+ if (runtimes.length === 0) {
188
+ console.log("No agent runtimes.");
189
+ } else {
190
+ for (const runtime of runtimes) {
191
+ console.log(`${runtime.id} (${runtime.mode}) workspace=${runtime.workspaceDir} created=${runtime.createdAt}`);
192
+ }
193
+ }
194
+ }
195
+ return { ok: true, group: "agent", command, details: { runtimes } };
196
+ }
197
+ case "prepare": {
198
+ let pending = rest;
199
+ const idResult = takeOption(pending, "--id");
200
+ pending = idResult.rest;
201
+ const modeResult = takeOption(pending, "--mode");
202
+ pending = modeResult.rest;
203
+ const taskResult = takeOption(pending, "--task");
204
+ pending = taskResult.rest;
205
+ requireNoExtraArgs(pending, "rig agent prepare --task <id> [--id <id>] [--mode worktree]");
206
+ const mode = parseIsolationMode(modeResult.value, false);
207
+ const id = idResult.value || agentId("agent");
208
+ const taskId = taskResult.value?.trim();
209
+ if (!taskId) {
210
+ throw new CliError("Usage: rig agent prepare --task <id> [--id <id>] [--mode worktree]");
211
+ }
212
+ const runtime = await withMutedConsole(context.outputMode === "json", () => ensureAgentRuntime({
213
+ projectRoot: context.projectRoot,
214
+ id,
215
+ taskId,
216
+ mode
217
+ }));
218
+ await attachEventBusToProvisionedRuntime(context, runtime.workspaceDir);
219
+ if (context.outputMode === "text") {
220
+ console.log(`Prepared runtime ${runtime.id} (${runtime.mode})`);
221
+ console.log(`Workspace: ${runtime.workspaceDir}`);
222
+ }
223
+ return { ok: true, group: "agent", command, details: { runtime } };
224
+ }
225
+ case "run": {
226
+ const { options, commandParts } = splitAtDoubleDash(rest);
227
+ if (commandParts.length === 0) {
228
+ throw new CliError("Usage: rig agent run [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
229
+ }
230
+ let pending = options;
231
+ const idResult = takeOption(pending, "--id");
232
+ pending = idResult.rest;
233
+ const modeResult = takeOption(pending, "--mode");
234
+ pending = modeResult.rest;
235
+ const taskResult = takeOption(pending, "--task");
236
+ pending = taskResult.rest;
237
+ const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
238
+ pending = skipProjectSyncResult.rest;
239
+ requireNoExtraArgs(pending, "rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
240
+ const mode = parseIsolationMode(modeResult.value, false);
241
+ const id = idResult.value || agentId("agent-run");
242
+ const taskId = taskResult.value?.trim();
243
+ if (!taskId) {
244
+ throw new CliError("Usage: rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
245
+ }
246
+ await runProjectMainSyncPreflight(context, { disabled: skipProjectSyncResult.value });
247
+ try {
248
+ const runtime = await withMutedConsole(context.outputMode === "json", () => ensureAgentRuntime({
249
+ projectRoot: context.projectRoot,
250
+ id,
251
+ taskId,
252
+ mode
253
+ }));
254
+ await attachEventBusToProvisionedRuntime(context, runtime.workspaceDir);
255
+ const result = await runInAgentRuntime({
256
+ projectRoot: context.projectRoot,
257
+ runtime,
258
+ command: commandParts,
259
+ inheritStdio: context.outputMode === "text"
260
+ });
261
+ if (result.exitCode !== 0) {
262
+ throw new CliError(`Agent runtime command failed (${result.exitCode}) in ${runtime.id}${result.stderr ? `
263
+ ${result.stderr.trim()}` : ""}`, result.exitCode);
264
+ }
265
+ return {
266
+ ok: true,
267
+ group: "agent",
268
+ command,
269
+ details: {
270
+ runtimeId: runtime.id,
271
+ mode: runtime.mode,
272
+ command: commandParts,
273
+ exitCode: result.exitCode,
274
+ sandboxBackend: result.sandboxBackend,
275
+ sandboxEnabled: result.sandboxEnabled,
276
+ stdout: result.stdout,
277
+ stderr: result.stderr
278
+ }
279
+ };
280
+ } catch (error) {
281
+ throw error;
282
+ }
283
+ }
284
+ case "cleanup": {
285
+ let pending = rest;
286
+ const allResult = takeFlag(pending, "--all");
287
+ pending = allResult.rest;
288
+ const idResult = takeOption(pending, "--id");
289
+ pending = idResult.rest;
290
+ requireNoExtraArgs(pending, "rig agent cleanup (--id <id> | --all)");
291
+ if (!allResult.value && !idResult.value) {
292
+ throw new CliError("Provide --id <id> or --all.", 1, { hint: "Run `rig agent list` to find agent ids." });
293
+ }
294
+ const runtimes = await listAgentRuntimes(context.projectRoot);
295
+ const targets = allResult.value ? runtimes.map((runtime) => runtime.id) : [idResult.value];
296
+ for (const id of targets) {
297
+ await cleanupAgentRuntime({
298
+ projectRoot: context.projectRoot,
299
+ id
300
+ });
301
+ }
302
+ if (context.outputMode === "text") {
303
+ console.log(`Cleaned runtimes: ${targets.join(", ")}`);
304
+ }
305
+ return {
306
+ ok: true,
307
+ group: "agent",
308
+ command,
309
+ details: {
310
+ cleaned: targets,
311
+ count: targets.length,
312
+ all: allResult.value
313
+ }
314
+ };
315
+ }
316
+ default:
317
+ throw new CliError(`Unknown agent command: ${command}`, 1, { hint: "Run `rig agent --help` to list agent commands." });
318
+ }
319
+ }
320
+ export {
321
+ executeAgent
322
+ };
@@ -0,0 +1,3 @@
1
+ import type { CommandOutcome } from "@rig/runtime";
2
+ import { type RunnerContext } from "../runner";
3
+ export declare function executeConfig(context: RunnerContext, args: string[]): Promise<CommandOutcome>;
@@ -0,0 +1,193 @@
1
+ // @bun
2
+ // packages/cli-surface-plugin/src/commands/config.ts
3
+ import { existsSync, readFileSync, writeFileSync } from "fs";
4
+ import { resolve } from "path";
5
+ import { loadConfig } from "@rig/core/load-config";
6
+ import {
7
+ DEFAULT_RIG_RELAY_URL,
8
+ DEFAULT_RIG_REGISTRY_URL,
9
+ resolveDispatchTransportPlacement,
10
+ resolveRegistryBaseUrl,
11
+ resolveRelayUrl
12
+ } from "@rig/runtime/control-plane/remote-config";
13
+
14
+ // packages/cli-surface-plugin/src/runner.ts
15
+ import { EventBus } from "@rig/runtime/control-plane/runtime/events";
16
+ import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
17
+ import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
18
+ import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
19
+
20
+ class CliError extends RuntimeCliError {
21
+ hint;
22
+ constructor(message, exitCode = 1, options = {}) {
23
+ super(message, exitCode);
24
+ if (options.hint?.trim()) {
25
+ this.hint = options.hint.trim();
26
+ }
27
+ }
28
+ }
29
+ function requireNoExtraArgs(args, usage) {
30
+ if (args.length > 0) {
31
+ throw new CliError(`Unexpected arguments: ${args.join(" ")}
32
+ Usage: ${usage}`);
33
+ }
34
+ }
35
+
36
+ // packages/cli-surface-plugin/src/commands/_cli-format.ts
37
+ import pc from "picocolors";
38
+ import { runStatusColorRole, runStatusText, statusColorRole } from "@rig/client";
39
+ var dim = pc.dim;
40
+ var faintBar = pc.dim("\u2502");
41
+ var accent = pc.cyan;
42
+ function printFormattedOutput(message) {
43
+ console.log(message);
44
+ }
45
+
46
+ // packages/cli-surface-plugin/src/commands/config.ts
47
+ var KNOBS = {
48
+ "runtime.server.relayUrl": { env: "RIG_COLLAB_RELAY", effective: () => resolveRelayUrl(), def: DEFAULT_RIG_RELAY_URL },
49
+ "runtime.server.registryUrl": { env: "RIG_REGISTRY_URL", effective: (r) => resolveRegistryBaseUrl(r), def: DEFAULT_RIG_REGISTRY_URL },
50
+ "runtime.server.sshTarget": {
51
+ env: "RIG_SSH_TARGET",
52
+ effective: (r) => {
53
+ const placement = resolveDispatchTransportPlacement(r);
54
+ return placement.kind === "remote" ? placement.sshTarget : "(none \u2014 local placement)";
55
+ },
56
+ def: "(none)",
57
+ source: (r) => {
58
+ if (process.env.RIG_SSH_TARGET?.trim())
59
+ return null;
60
+ const placement = resolveDispatchTransportPlacement(r);
61
+ return placement.kind === "remote" && placement.selected ? `rig server use ${placement.selected.alias}` : null;
62
+ }
63
+ }
64
+ };
65
+ var ALIASES = {
66
+ relayUrl: "runtime.server.relayUrl",
67
+ registryUrl: "runtime.server.registryUrl",
68
+ sshTarget: "runtime.server.sshTarget"
69
+ };
70
+ function canonicalKey(key) {
71
+ return ALIASES[key] ?? key;
72
+ }
73
+ async function loadProjectConfig(root) {
74
+ try {
75
+ return await loadConfig(root);
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+ function configHasKnob(config, canonical, envKey) {
81
+ if (!config)
82
+ return false;
83
+ const server = config.runtime?.server;
84
+ const field = canonical.replace("runtime.server.", "");
85
+ if (server && server[field] !== undefined)
86
+ return true;
87
+ if (server && server.host !== undefined && (field === "relayUrl" || field === "registryUrl"))
88
+ return true;
89
+ const envMap = config.env;
90
+ return Boolean(envMap && envMap[envKey] !== undefined);
91
+ }
92
+ function describe(root, config, canonical) {
93
+ const knob = KNOBS[canonical];
94
+ if (!knob) {
95
+ const val = process.env[canonical];
96
+ const fromConfig = Boolean(config?.env?.[canonical]);
97
+ return `${canonical} = ${val ?? "(unset)"} [${val === undefined ? "default" : fromConfig ? "rig.config.ts" : "env"}]`;
98
+ }
99
+ const value = knob.effective(root);
100
+ const inConfig = configHasKnob(config, canonical, knob.env);
101
+ const ambient = Boolean(process.env[knob.env]);
102
+ const source = knob.source?.(root) ?? (inConfig ? "rig.config.ts" : ambient ? "env" : "default");
103
+ return `${canonical} = ${value} [${source}]`;
104
+ }
105
+ async function configGet(context, args) {
106
+ const root = context.projectRoot;
107
+ const config = await loadProjectConfig(root);
108
+ const text = context.outputMode === "text";
109
+ if (args[0]) {
110
+ const canonical = canonicalKey(args[0]);
111
+ requireNoExtraArgs(args.slice(1), "rig config get [<key>]");
112
+ if (text)
113
+ printFormattedOutput(describe(root, config, canonical));
114
+ return { ok: true, group: "config", command: "get", details: { key: canonical } };
115
+ }
116
+ const lines = ["\u25C6 Rig config \u2014 effective values (ambient env \u2192 rig.config.ts \u2192 default)"];
117
+ for (const canonical of Object.keys(KNOBS))
118
+ lines.push(` ${describe(root, config, canonical)}`);
119
+ const envMap = config?.env ?? {};
120
+ const envKeys = Object.keys(envMap);
121
+ lines.push(envKeys.length ? ` env overrides: ${envKeys.join(", ")}` : " env overrides: (none)");
122
+ if (text)
123
+ printFormattedOutput(lines.join(`
124
+ `));
125
+ return { ok: true, group: "config", command: "get", details: {} };
126
+ }
127
+ function writeEnvOverride(source, envKey, value) {
128
+ const entry = ` ${JSON.stringify(envKey)}: ${JSON.stringify(value)},`;
129
+ const envBlock = /env\s*:\s*\{([\s\S]*?)\}/m;
130
+ const m = envBlock.exec(source);
131
+ if (m) {
132
+ const body = m[1] ?? "";
133
+ const keyRe = new RegExp(`(^|\\n)\\s*${envKey.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")}\\s*:\\s*[^,\\n]*,?`, "m");
134
+ const quotedRe = new RegExp(`(^|\\n)\\s*["']${envKey}["']\\s*:\\s*[^,\\n]*,?`, "m");
135
+ if (keyRe.test(body) || quotedRe.test(body)) {
136
+ const newBody = body.replace(quotedRe, `
137
+ ${entry}`).replace(keyRe, `
138
+ ${entry}`);
139
+ return source.replace(envBlock, `env: {${newBody}
140
+ }`);
141
+ }
142
+ return source.replace(envBlock, `env: {
143
+ ${entry}${body}}`);
144
+ }
145
+ const defRe = /defineConfig\s*\(\s*\{/m;
146
+ if (!defRe.test(source)) {
147
+ throw new CliError("Could not find `defineConfig({` in rig.config.ts to insert an env override.", 2, {
148
+ hint: `Add manually: env: { ${JSON.stringify(envKey)}: ${JSON.stringify(value)} }`
149
+ });
150
+ }
151
+ return source.replace(defRe, (match) => `${match}
152
+ env: {
153
+ ${entry}
154
+ },`);
155
+ }
156
+ async function configSet(context, args) {
157
+ const [rawKey, ...valueParts] = args;
158
+ if (!rawKey || valueParts.length === 0) {
159
+ throw new CliError("Usage: rig config set <key> <value>", 2, {
160
+ hint: `Keys: ${Object.keys(ALIASES).join(", ")}, or any RIG_* env var.`
161
+ });
162
+ }
163
+ const value = valueParts.join(" ");
164
+ const canonical = canonicalKey(rawKey);
165
+ const envKey = KNOBS[canonical]?.env ?? canonical;
166
+ const configPath = resolve(context.projectRoot, "rig.config.ts");
167
+ if (!existsSync(configPath)) {
168
+ throw new CliError(`No rig.config.ts at ${context.projectRoot}.`, 2, { hint: "Run `rig init` first." });
169
+ }
170
+ const source = readFileSync(configPath, "utf8");
171
+ const updated = writeEnvOverride(source, envKey, value);
172
+ writeFileSync(configPath, updated);
173
+ if (context.outputMode === "text") {
174
+ printFormattedOutput(`Set ${canonical} (env ${envKey}) = ${value} in rig.config.ts`);
175
+ }
176
+ return { ok: true, group: "config", command: "set", details: { key: canonical, env: envKey, value } };
177
+ }
178
+ async function executeConfig(context, args) {
179
+ const [sub, ...rest] = args;
180
+ switch (sub) {
181
+ case "get":
182
+ return configGet(context, rest);
183
+ case "set":
184
+ return configSet(context, rest);
185
+ default:
186
+ throw new CliError("Usage: rig config <get|set>", 2, {
187
+ hint: "rig config get [<key>] \u2014 effective value + source; rig config set <key> <value> \u2014 write to rig.config.ts"
188
+ });
189
+ }
190
+ }
191
+ export {
192
+ executeConfig
193
+ };
@@ -0,0 +1,28 @@
1
+ import { type RunnerContext } from "../runner";
2
+ import type { CommandOutcome } from "@rig/runtime";
3
+ export type DistDoctorDetails = {
4
+ bun: {
5
+ available: boolean;
6
+ path: string | null;
7
+ version: string;
8
+ };
9
+ rig: {
10
+ onPath: boolean;
11
+ path: string | null;
12
+ runnable: boolean;
13
+ };
14
+ userBinDir: string;
15
+ userBinInPath: boolean;
16
+ latestDistBinary: string | null;
17
+ };
18
+ export type BuildTarget = {
19
+ source: string;
20
+ dest: string;
21
+ cwd: string;
22
+ };
23
+ export declare function collectRigValidatorBuildTargets(input: {
24
+ contextProjectRoot: string;
25
+ hostProjectRoot: string;
26
+ imageDir: string;
27
+ }): BuildTarget[];
28
+ export declare function executeDist(context: RunnerContext, args: string[]): Promise<CommandOutcome>;