@h-rig/cli 0.0.6-alpha.100 → 0.0.6-alpha.102

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 (112) hide show
  1. package/README.md +6 -27
  2. package/bin/rig.js +16 -0
  3. package/package.json +14 -40
  4. package/dist/bin/build-rig-binaries.d.ts +0 -2
  5. package/dist/bin/build-rig-binaries.js +0 -119
  6. package/dist/bin/rig.d.ts +0 -72
  7. package/dist/bin/rig.js +0 -17875
  8. package/dist/config/rig-default-config.yml +0 -5
  9. package/dist/src/app/drone-ui.d.ts +0 -34
  10. package/dist/src/app/drone-ui.js +0 -278
  11. package/dist/src/commands/_async-ui.d.ts +0 -10
  12. package/dist/src/commands/_async-ui.js +0 -121
  13. package/dist/src/commands/_cli-format.d.ts +0 -56
  14. package/dist/src/commands/_cli-format.js +0 -319
  15. package/dist/src/commands/_config-env.d.ts +0 -18
  16. package/dist/src/commands/_config-env.js +0 -22
  17. package/dist/src/commands/_connection-state.d.ts +0 -54
  18. package/dist/src/commands/_connection-state.js +0 -187
  19. package/dist/src/commands/_doctor-checks.d.ts +0 -46
  20. package/dist/src/commands/_doctor-checks.js +0 -352
  21. package/dist/src/commands/_help-catalog.d.ts +0 -29
  22. package/dist/src/commands/_help-catalog.js +0 -146
  23. package/dist/src/commands/_inprocess-services.d.ts +0 -33
  24. package/dist/src/commands/_inprocess-services.js +0 -102
  25. package/dist/src/commands/_json-output.d.ts +0 -11
  26. package/dist/src/commands/_json-output.js +0 -60
  27. package/dist/src/commands/_lazy-reconcile.d.ts +0 -34
  28. package/dist/src/commands/_lazy-reconcile.js +0 -102
  29. package/dist/src/commands/_parsers.d.ts +0 -15
  30. package/dist/src/commands/_parsers.js +0 -114
  31. package/dist/src/commands/_paths.d.ts +0 -11
  32. package/dist/src/commands/_paths.js +0 -50
  33. package/dist/src/commands/_pi-frontend.d.ts +0 -35
  34. package/dist/src/commands/_pi-frontend.js +0 -64
  35. package/dist/src/commands/_pi-install.d.ts +0 -42
  36. package/dist/src/commands/_pi-install.js +0 -167
  37. package/dist/src/commands/_policy.d.ts +0 -8
  38. package/dist/src/commands/_policy.js +0 -127
  39. package/dist/src/commands/_probes.d.ts +0 -1
  40. package/dist/src/commands/_probes.js +0 -13
  41. package/dist/src/commands/_run-bridge.d.ts +0 -114
  42. package/dist/src/commands/_run-bridge.js +0 -387
  43. package/dist/src/commands/_run-diagnostics.d.ts +0 -9
  44. package/dist/src/commands/_run-diagnostics.js +0 -51
  45. package/dist/src/commands/_run-driver-helpers.d.ts +0 -26
  46. package/dist/src/commands/_run-driver-helpers.js +0 -138
  47. package/dist/src/commands/_run-projection.d.ts +0 -50
  48. package/dist/src/commands/_run-projection.js +0 -349
  49. package/dist/src/commands/_run-subcommands.d.ts +0 -3
  50. package/dist/src/commands/_run-subcommands.js +0 -31
  51. package/dist/src/commands/_spinner.d.ts +0 -25
  52. package/dist/src/commands/_spinner.js +0 -65
  53. package/dist/src/commands/agent.d.ts +0 -3
  54. package/dist/src/commands/agent.js +0 -8952
  55. package/dist/src/commands/config.d.ts +0 -3
  56. package/dist/src/commands/config.js +0 -181
  57. package/dist/src/commands/dist.d.ts +0 -28
  58. package/dist/src/commands/dist.js +0 -417
  59. package/dist/src/commands/doctor.d.ts +0 -3
  60. package/dist/src/commands/doctor.js +0 -480
  61. package/dist/src/commands/github.d.ts +0 -3
  62. package/dist/src/commands/github.js +0 -342
  63. package/dist/src/commands/inbox.d.ts +0 -28
  64. package/dist/src/commands/inbox.js +0 -579
  65. package/dist/src/commands/init.d.ts +0 -64
  66. package/dist/src/commands/init.js +0 -1541
  67. package/dist/src/commands/inspect.d.ts +0 -20
  68. package/dist/src/commands/inspect.js +0 -764
  69. package/dist/src/commands/pi.d.ts +0 -3
  70. package/dist/src/commands/pi.js +0 -177
  71. package/dist/src/commands/plugin.d.ts +0 -16
  72. package/dist/src/commands/plugin.js +0 -714
  73. package/dist/src/commands/profile-and-review.d.ts +0 -4
  74. package/dist/src/commands/profile-and-review.js +0 -223
  75. package/dist/src/commands/queue.d.ts +0 -3
  76. package/dist/src/commands/queue.js +0 -197
  77. package/dist/src/commands/remote.d.ts +0 -3
  78. package/dist/src/commands/remote.js +0 -1340
  79. package/dist/src/commands/repo-git-harness.d.ts +0 -5
  80. package/dist/src/commands/repo-git-harness.js +0 -271
  81. package/dist/src/commands/run.d.ts +0 -21
  82. package/dist/src/commands/run.js +0 -17867
  83. package/dist/src/commands/server.d.ts +0 -3
  84. package/dist/src/commands/server.js +0 -249
  85. package/dist/src/commands/setup.d.ts +0 -16
  86. package/dist/src/commands/setup.js +0 -644
  87. package/dist/src/commands/stats.d.ts +0 -15
  88. package/dist/src/commands/stats.js +0 -632
  89. package/dist/src/commands/task-run-driver.d.ts +0 -94
  90. package/dist/src/commands/task-run-driver.js +0 -203
  91. package/dist/src/commands/task.d.ts +0 -35
  92. package/dist/src/commands/task.js +0 -818
  93. package/dist/src/commands/test.d.ts +0 -3
  94. package/dist/src/commands/test.js +0 -46
  95. package/dist/src/commands/triage.d.ts +0 -11
  96. package/dist/src/commands/triage.js +0 -227
  97. package/dist/src/commands/workspace.d.ts +0 -3
  98. package/dist/src/commands/workspace.js +0 -130
  99. package/dist/src/commands.d.ts +0 -13
  100. package/dist/src/commands.js +0 -17999
  101. package/dist/src/index.d.ts +0 -4
  102. package/dist/src/index.js +0 -18011
  103. package/dist/src/launcher.d.ts +0 -61
  104. package/dist/src/launcher.js +0 -199
  105. package/dist/src/operator-cli.d.ts +0 -2
  106. package/dist/src/operator-cli.js +0 -17867
  107. package/dist/src/operator-entry.d.ts +0 -1
  108. package/dist/src/operator-entry.js +0 -3
  109. package/dist/src/runner.d.ts +0 -47
  110. package/dist/src/runner.js +0 -267
  111. package/dist/src/withMutedConsole.d.ts +0 -2
  112. package/dist/src/withMutedConsole.js +0 -42
@@ -1,3 +0,0 @@
1
- import type { CommandOutcome } from "@rig/runtime";
2
- import { type RunnerContext } from "../runner";
3
- export declare function executeConfig(context: RunnerContext, args: string[]): Promise<CommandOutcome>;
@@ -1,181 +0,0 @@
1
- // @bun
2
- // packages/cli/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
- resolveRegistryBaseUrl,
10
- resolveRegistrySecret,
11
- resolveRelayUrl
12
- } from "@rig/runtime/control-plane/remote";
13
-
14
- // packages/cli/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/src/commands/_cli-format.ts
37
- import pc from "picocolors";
38
- var dim = pc.dim;
39
- var faintBar = pc.dim("\u2502");
40
- var accent = pc.cyan;
41
- function printFormattedOutput(message) {
42
- console.log(message);
43
- }
44
-
45
- // packages/cli/src/commands/config.ts
46
- var KNOBS = {
47
- "runtime.server.relayUrl": { env: "RIG_COLLAB_RELAY", effective: () => resolveRelayUrl(), def: DEFAULT_RIG_RELAY_URL },
48
- "runtime.server.registryUrl": { env: "RIG_REGISTRY_URL", effective: (r) => resolveRegistryBaseUrl(r), def: DEFAULT_RIG_REGISTRY_URL },
49
- "runtime.server.registrySecret": { env: "RIG_REGISTRY_SHARED_SECRET", effective: (r) => resolveRegistrySecret(r), def: "(built-in default)" },
50
- "runtime.server.sshTarget": { env: "RIG_SSH_TARGET", effective: () => process.env.RIG_SSH_TARGET?.trim() ?? "(none \u2014 local placement)", def: "(none)" }
51
- };
52
- var ALIASES = {
53
- relayUrl: "runtime.server.relayUrl",
54
- registryUrl: "runtime.server.registryUrl",
55
- registrySecret: "runtime.server.registrySecret",
56
- sshTarget: "runtime.server.sshTarget"
57
- };
58
- function canonicalKey(key) {
59
- return ALIASES[key] ?? key;
60
- }
61
- async function loadProjectConfig(root) {
62
- try {
63
- return await loadConfig(root);
64
- } catch {
65
- return null;
66
- }
67
- }
68
- function configHasKnob(config, canonical, envKey) {
69
- if (!config)
70
- return false;
71
- const server = config.runtime?.server;
72
- const field = canonical.replace("runtime.server.", "");
73
- if (server && server[field] !== undefined)
74
- return true;
75
- if (server && server.host !== undefined && (field === "relayUrl" || field === "registryUrl"))
76
- return true;
77
- const envMap = config.env;
78
- return Boolean(envMap && envMap[envKey] !== undefined);
79
- }
80
- function describe(root, config, canonical) {
81
- const knob = KNOBS[canonical];
82
- if (!knob) {
83
- const val = process.env[canonical];
84
- const fromConfig = Boolean(config?.env?.[canonical]);
85
- return `${canonical} = ${val ?? "(unset)"} [${val === undefined ? "default" : fromConfig ? "rig.config.ts" : "env"}]`;
86
- }
87
- const value = knob.effective(root);
88
- const inConfig = configHasKnob(config, canonical, knob.env);
89
- const ambient = Boolean(process.env[knob.env]);
90
- const source = inConfig ? "rig.config.ts" : ambient ? "env" : "default";
91
- return `${canonical} = ${value} [${source}]`;
92
- }
93
- async function configGet(context, args) {
94
- const root = context.projectRoot;
95
- const config = await loadProjectConfig(root);
96
- const text = context.outputMode === "text";
97
- if (args[0]) {
98
- const canonical = canonicalKey(args[0]);
99
- requireNoExtraArgs(args.slice(1), "rig config get [<key>]");
100
- if (text)
101
- printFormattedOutput(describe(root, config, canonical));
102
- return { ok: true, group: "config", command: "get", details: { key: canonical } };
103
- }
104
- const lines = ["\u25C6 Rig config \u2014 effective values (ambient env \u2192 rig.config.ts \u2192 default)"];
105
- for (const canonical of Object.keys(KNOBS))
106
- lines.push(` ${describe(root, config, canonical)}`);
107
- const envMap = config?.env ?? {};
108
- const envKeys = Object.keys(envMap);
109
- lines.push(envKeys.length ? ` env overrides: ${envKeys.join(", ")}` : " env overrides: (none)");
110
- if (text)
111
- printFormattedOutput(lines.join(`
112
- `));
113
- return { ok: true, group: "config", command: "get", details: {} };
114
- }
115
- function writeEnvOverride(source, envKey, value) {
116
- const entry = ` ${JSON.stringify(envKey)}: ${JSON.stringify(value)},`;
117
- const envBlock = /env\s*:\s*\{([\s\S]*?)\}/m;
118
- const m = envBlock.exec(source);
119
- if (m) {
120
- const body = m[1] ?? "";
121
- const keyRe = new RegExp(`(^|\\n)\\s*${envKey.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")}\\s*:\\s*[^,\\n]*,?`, "m");
122
- const quotedRe = new RegExp(`(^|\\n)\\s*["']${envKey}["']\\s*:\\s*[^,\\n]*,?`, "m");
123
- if (keyRe.test(body) || quotedRe.test(body)) {
124
- const newBody = body.replace(quotedRe, `
125
- ${entry}`).replace(keyRe, `
126
- ${entry}`);
127
- return source.replace(envBlock, `env: {${newBody}
128
- }`);
129
- }
130
- return source.replace(envBlock, `env: {
131
- ${entry}${body}}`);
132
- }
133
- const defRe = /defineConfig\s*\(\s*\{/m;
134
- if (!defRe.test(source)) {
135
- throw new CliError("Could not find `defineConfig({` in rig.config.ts to insert an env override.", 2, {
136
- hint: `Add manually: env: { ${JSON.stringify(envKey)}: ${JSON.stringify(value)} }`
137
- });
138
- }
139
- return source.replace(defRe, (match) => `${match}
140
- env: {
141
- ${entry}
142
- },`);
143
- }
144
- async function configSet(context, args) {
145
- const [rawKey, ...valueParts] = args;
146
- if (!rawKey || valueParts.length === 0) {
147
- throw new CliError("Usage: rig config set <key> <value>", 2, {
148
- hint: `Keys: ${Object.keys(ALIASES).join(", ")}, or any RIG_* env var.`
149
- });
150
- }
151
- const value = valueParts.join(" ");
152
- const canonical = canonicalKey(rawKey);
153
- const envKey = KNOBS[canonical]?.env ?? canonical;
154
- const configPath = resolve(context.projectRoot, "rig.config.ts");
155
- if (!existsSync(configPath)) {
156
- throw new CliError(`No rig.config.ts at ${context.projectRoot}.`, 2, { hint: "Run `rig init` first." });
157
- }
158
- const source = readFileSync(configPath, "utf8");
159
- const updated = writeEnvOverride(source, envKey, value);
160
- writeFileSync(configPath, updated);
161
- if (context.outputMode === "text") {
162
- printFormattedOutput(`Set ${canonical} (env ${envKey}) = ${value} in rig.config.ts`);
163
- }
164
- return { ok: true, group: "config", command: "set", details: { key: canonical, env: envKey, value } };
165
- }
166
- async function executeConfig(context, args) {
167
- const [sub, ...rest] = args;
168
- switch (sub) {
169
- case "get":
170
- return configGet(context, rest);
171
- case "set":
172
- return configSet(context, rest);
173
- default:
174
- throw new CliError("Usage: rig config <get|set>", 2, {
175
- hint: "rig config get [<key>] \u2014 effective value + source; rig config set <key> <value> \u2014 write to rig.config.ts"
176
- });
177
- }
178
- }
179
- export {
180
- executeConfig
181
- };
@@ -1,28 +0,0 @@
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>;
@@ -1,417 +0,0 @@
1
- // @bun
2
- // packages/cli/src/commands/dist.ts
3
- import {
4
- chmodSync,
5
- copyFileSync,
6
- existsSync,
7
- mkdirSync,
8
- readdirSync,
9
- readlinkSync,
10
- rmSync,
11
- statSync,
12
- symlinkSync,
13
- unlinkSync
14
- } from "fs";
15
- import { homedir as homedir2 } from "os";
16
- import { resolve as resolve3 } from "path";
17
-
18
- // packages/cli/src/runner.ts
19
- import { EventBus } from "@rig/runtime/control-plane/runtime/events";
20
- import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
21
- import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
22
- import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
23
-
24
- class CliError extends RuntimeCliError {
25
- hint;
26
- constructor(message, exitCode = 1, options = {}) {
27
- super(message, exitCode);
28
- if (options.hint?.trim()) {
29
- this.hint = options.hint.trim();
30
- }
31
- }
32
- }
33
- function takeOption(args, option) {
34
- const rest = [];
35
- let value;
36
- for (let index = 0;index < args.length; index += 1) {
37
- const current = args[index];
38
- if (current === option) {
39
- const next = args[index + 1];
40
- if (!next || next.startsWith("-")) {
41
- throw new CliError(`Missing value for ${option}`, 1, { hint: `Provide a value after ${option}, e.g. \`${option} <value>\`.` });
42
- }
43
- value = next;
44
- index += 1;
45
- continue;
46
- }
47
- if (current !== undefined) {
48
- rest.push(current);
49
- }
50
- }
51
- return { value, rest };
52
- }
53
- function requireNoExtraArgs(args, usage) {
54
- if (args.length > 0) {
55
- throw new CliError(`Unexpected arguments: ${args.join(" ")}
56
- Usage: ${usage}`);
57
- }
58
- }
59
-
60
- // packages/cli/src/commands/dist.ts
61
- import {
62
- computeRuntimeImageFingerprint,
63
- computeRuntimeImageId
64
- } from "@rig/runtime/control-plane/runtime/image/index";
65
- import { buildBinary as buildBinary2 } from "@rig/runtime/control-plane/runtime/isolation";
66
-
67
- // packages/cli/src/commands/_parsers.ts
68
- import { homedir } from "os";
69
- import { resolve } from "path";
70
- function parseInstallScope(value) {
71
- if (!value || value === "user") {
72
- return "user";
73
- }
74
- if (value === "system") {
75
- return "system";
76
- }
77
- throw new CliError(`Invalid --scope value: ${value}. Use user|system.`);
78
- }
79
- function resolveInstallDir(scope, explicitPath) {
80
- if (explicitPath) {
81
- return resolve(explicitPath);
82
- }
83
- if (scope === "system") {
84
- return "/usr/local/bin";
85
- }
86
- return resolve(homedir(), ".local/bin");
87
- }
88
-
89
- // packages/cli/src/commands/_paths.ts
90
- import { resolve as resolve2 } from "path";
91
- import { resolveMonorepoRoot } from "@rig/runtime/layout";
92
- function resolveControlPlaneMonorepoRoot(projectRoot) {
93
- return resolveMonorepoRoot(projectRoot);
94
- }
95
- function resolveControlPlaneHostStateRoot(projectRoot) {
96
- return resolve2(projectRoot, ".rig");
97
- }
98
- function resolveControlPlaneHostBinDir(projectRoot) {
99
- return resolve2(resolveControlPlaneHostStateRoot(projectRoot), "bin");
100
- }
101
- function resolveControlPlaneHostDistDir(projectRoot) {
102
- return resolve2(resolveControlPlaneHostStateRoot(projectRoot), "dist");
103
- }
104
- function resolveControlPlaneMonorepoStateRoot(projectRoot) {
105
- return resolve2(resolveControlPlaneMonorepoRoot(projectRoot), ".rig");
106
- }
107
- function resolveControlPlaneMonorepoRuntimeDir(projectRoot) {
108
- return resolve2(resolveControlPlaneMonorepoStateRoot(projectRoot), "runtime");
109
- }
110
-
111
- // packages/cli/src/commands/_probes.ts
112
- async function runQuietBinaryProbe(binaryPath, args, cwd) {
113
- try {
114
- const run = await Bun.$`${binaryPath} ${args}`.cwd(cwd).quiet().nothrow();
115
- return run.exitCode === 0;
116
- } catch {
117
- return false;
118
- }
119
- }
120
-
121
- // packages/cli/src/commands/dist.ts
122
- function collectRigValidatorBuildTargets(input) {
123
- const validatorsRoot = resolve3(input.hostProjectRoot, "packages/runtime/src/control-plane/validators");
124
- if (!existsSync(validatorsRoot))
125
- return [];
126
- const targets = [];
127
- for (const category of readdirSync(validatorsRoot, { withFileTypes: true })) {
128
- if (!category.isDirectory())
129
- continue;
130
- const categoryDir = resolve3(validatorsRoot, category.name);
131
- for (const entry of readdirSync(categoryDir, { withFileTypes: true })) {
132
- if (!entry.isFile() || !entry.name.endsWith(".ts"))
133
- continue;
134
- const check = entry.name.replace(/\.ts$/, "");
135
- if (!check || check === "index" || check === "shared")
136
- continue;
137
- const validatorName = `${category.name}-${check}`;
138
- targets.push({
139
- source: `packages/runtime/src/control-plane/validators/${category.name}/${entry.name}`,
140
- dest: resolve3(input.imageDir, `bin/validators/${validatorName}`),
141
- cwd: input.hostProjectRoot
142
- });
143
- }
144
- }
145
- return targets;
146
- }
147
- async function findLatestDistBinary(projectRoot) {
148
- const distRoot = resolveControlPlaneHostDistDir(projectRoot);
149
- if (!existsSync(distRoot)) {
150
- return null;
151
- }
152
- const candidates = [];
153
- for (const entry of readdirSync(distRoot, { withFileTypes: true })) {
154
- if (!entry.name.startsWith("rig-") && entry.name !== "rig")
155
- continue;
156
- const entryPath = resolve3(distRoot, entry.name);
157
- const binary = entry.isDirectory() ? resolve3(entryPath, "bin", "rig") : entryPath;
158
- try {
159
- const stat = statSync(binary);
160
- if (stat.isFile())
161
- candidates.push({ path: binary, mtimeMs: stat.mtimeMs });
162
- } catch {}
163
- }
164
- candidates.sort((a, b) => b.mtimeMs - a.mtimeMs);
165
- for (const { path } of candidates) {
166
- if (await isRunnableRigBinary(path, projectRoot))
167
- return path;
168
- }
169
- return null;
170
- }
171
- async function isRunnableRigBinary(binaryPath, projectRoot) {
172
- return runQuietBinaryProbe(binaryPath, ["help"], projectRoot);
173
- }
174
- async function runDistDoctor(projectRoot) {
175
- const bunPath = Bun.which("bun");
176
- const rigPath = Bun.which("rig");
177
- const userBinDir = resolve3(homedir2(), ".local/bin");
178
- const userBinInPath = (process.env.PATH || "").split(":").filter(Boolean).includes(userBinDir);
179
- let rigRunnable = false;
180
- if (rigPath) {
181
- rigRunnable = await runQuietBinaryProbe(rigPath, ["help"], projectRoot);
182
- }
183
- return {
184
- bun: {
185
- available: Boolean(bunPath),
186
- path: bunPath || null,
187
- version: Bun.version
188
- },
189
- rig: {
190
- onPath: Boolean(rigPath),
191
- path: rigPath || null,
192
- runnable: rigRunnable
193
- },
194
- userBinDir,
195
- userBinInPath,
196
- latestDistBinary: await findLatestDistBinary(projectRoot)
197
- };
198
- }
199
- async function executeDist(context, args) {
200
- const [command = "build", ...rest] = args;
201
- switch (command) {
202
- case "build": {
203
- const { value: outputDir, rest: pending } = takeOption(rest, "--output-dir");
204
- requireNoExtraArgs(pending, "rig dist build [--output-dir <dir>]");
205
- const commandParts = ["bun", "run", "packages/cli/bin/build-rig-binaries.ts"];
206
- if (outputDir)
207
- commandParts.push("--output-dir", outputDir);
208
- await context.runCommand(commandParts);
209
- return { ok: true, group: "dist", command, details: { outputDir: outputDir || null } };
210
- }
211
- case "install": {
212
- let pending = rest;
213
- const scopeResult = takeOption(pending, "--scope");
214
- pending = scopeResult.rest;
215
- const pathResult = takeOption(pending, "--dir");
216
- pending = pathResult.rest;
217
- requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--dir <dir>]");
218
- const scope = parseInstallScope(scopeResult.value);
219
- const installDir = resolveInstallDir(scope, pathResult.value);
220
- mkdirSync(installDir, { recursive: true });
221
- let source = await findLatestDistBinary(context.projectRoot);
222
- let buildDir = null;
223
- if (!source) {
224
- buildDir = resolve3(resolveControlPlaneHostDistDir(context.projectRoot), `rig-install-${Date.now()}`);
225
- await context.runCommand(["bun", "run", "packages/cli/bin/build-rig-binaries.ts", "--output-dir", buildDir]);
226
- source = resolve3(buildDir, "bin", "rig");
227
- }
228
- if (!existsSync(source)) {
229
- throw new CliError(`Unable to locate rig binary at ${source}.`, 2, { hint: "Build it first with `rig dist build`, then re-run `rig dist install`." });
230
- }
231
- const installedPath = resolve3(installDir, "rig");
232
- if (existsSync(installedPath)) {
233
- unlinkSync(installedPath);
234
- }
235
- copyFileSync(source, installedPath);
236
- chmodSync(installedPath, 493);
237
- const pathEntries = (process.env.PATH || "").split(":").filter(Boolean);
238
- const inPath = pathEntries.includes(installDir);
239
- if (context.outputMode === "text") {
240
- console.log(`Installed: ${installedPath}`);
241
- if (!inPath) {
242
- console.log(`PATH note: add ${installDir} to PATH to run 'rig' directly.`);
243
- }
244
- }
245
- return {
246
- ok: true,
247
- group: "dist",
248
- command,
249
- details: {
250
- scope,
251
- installDir,
252
- installedPath,
253
- sourcePath: source,
254
- builtNow: Boolean(buildDir),
255
- inPath
256
- }
257
- };
258
- }
259
- case "doctor": {
260
- requireNoExtraArgs(rest, "rig dist doctor");
261
- const details = await runDistDoctor(context.projectRoot);
262
- if (context.outputMode === "text") {
263
- console.log(`bun: ${details.bun.available ? `ok (${details.bun.version})` : "missing"}`);
264
- console.log(`rig on PATH: ${details.rig.onPath ? details.rig.path : "missing"}`);
265
- console.log(`user bin dir: ${details.userBinDir} (${details.userBinInPath ? "in PATH" : "not in PATH"})`);
266
- console.log(`latest dist binary: ${details.latestDistBinary || "none"}`);
267
- }
268
- return { ok: true, group: "dist", command, details };
269
- }
270
- case "rebuild-agent": {
271
- requireNoExtraArgs(rest, "rig dist rebuild-agent");
272
- const fp = await computeRuntimeImageFingerprint(context.projectRoot);
273
- const currentId = computeRuntimeImageId(fp);
274
- const imagesDir = resolve3(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
275
- mkdirSync(imagesDir, { recursive: true });
276
- let pruned = 0;
277
- for (const entry of readdirSync(imagesDir, { withFileTypes: true })) {
278
- if (entry.isDirectory() && entry.name !== currentId) {
279
- rmSync(resolve3(imagesDir, entry.name), { recursive: true, force: true });
280
- pruned++;
281
- }
282
- }
283
- if (pruned > 0 && context.outputMode === "text") {
284
- console.log(`Pruned ${pruned} stale image(s).`);
285
- }
286
- const imageDir = resolve3(imagesDir, currentId);
287
- mkdirSync(resolve3(imageDir, "bin/hooks"), { recursive: true });
288
- mkdirSync(resolve3(imageDir, "bin/plugins"), { recursive: true });
289
- mkdirSync(resolve3(imageDir, "bin/validators"), { recursive: true });
290
- const hookNames = [
291
- "scope-guard",
292
- "import-guard",
293
- "safety-guard",
294
- "test-integrity-guard",
295
- "audit-trail",
296
- "post-edit-lint",
297
- "completion-verification",
298
- "inject-context",
299
- "task-runtime-start"
300
- ];
301
- const targets = [];
302
- const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || context.projectRoot;
303
- targets.push({ source: "packages/runtime/bin/rig-agent.ts", dest: resolve3(imageDir, "bin/rig-agent"), cwd: hostProjectRoot });
304
- targets.push({ source: "packages/runtime/bin/rig-agent-dispatch.ts", dest: resolve3(resolveControlPlaneHostBinDir(context.projectRoot), "rig-agent"), cwd: hostProjectRoot });
305
- for (const hookName of hookNames) {
306
- const src = `packages/runtime/src/control-plane/hooks/${hookName}.ts`;
307
- targets.push({ source: src, dest: resolve3(imageDir, `bin/hooks/${hookName}`), cwd: hostProjectRoot });
308
- targets.push({ source: src, dest: resolve3(resolveControlPlaneHostBinDir(context.projectRoot), `hooks/${hookName}`), cwd: hostProjectRoot });
309
- }
310
- const pluginsDir = resolve3(context.projectRoot, "rig/plugins");
311
- const binPluginsDir = resolve3(resolveControlPlaneHostBinDir(context.projectRoot), "plugins");
312
- const validatorsRoot = resolve3(hostProjectRoot, "packages/runtime/src/control-plane/validators");
313
- const binValidatorsDir = resolve3(resolveControlPlaneHostBinDir(context.projectRoot), "validators");
314
- mkdirSync(binPluginsDir, { recursive: true });
315
- mkdirSync(binValidatorsDir, { recursive: true });
316
- if (existsSync(pluginsDir)) {
317
- for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
318
- const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
319
- if (!m)
320
- continue;
321
- targets.push({ source: `rig/plugins/${entry.name}`, dest: resolve3(imageDir, `bin/plugins/${m[1]}`), cwd: context.projectRoot });
322
- }
323
- }
324
- targets.push(...collectRigValidatorBuildTargets({ contextProjectRoot: context.projectRoot, hostProjectRoot, imageDir }));
325
- for (const { source, dest, cwd } of targets) {
326
- if (context.outputMode === "text") {
327
- console.log(`Building: ${dest}`);
328
- }
329
- const isValidator = dest.includes("/bin/validators/");
330
- await buildBinary2(source, dest, cwd, isValidator ? { AGENT_BUN_PATH: Bun.which("bun") || "bun" } : { AGENT_PROJECT_ROOT: context.projectRoot });
331
- }
332
- if (existsSync(pluginsDir)) {
333
- for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
334
- const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
335
- if (!m)
336
- continue;
337
- const pluginName = m[1];
338
- const imageBin = resolve3(imageDir, `bin/plugins/${pluginName}`);
339
- if (!pluginName)
340
- continue;
341
- const symlinkPath = resolve3(binPluginsDir, pluginName);
342
- if (existsSync(imageBin)) {
343
- try {
344
- unlinkSync(symlinkPath);
345
- } catch {}
346
- symlinkSync(imageBin, symlinkPath);
347
- }
348
- }
349
- }
350
- if (existsSync(validatorsRoot)) {
351
- const categories = readdirSync(validatorsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
352
- for (const category of categories) {
353
- const categoryDir = resolve3(validatorsRoot, category.name);
354
- for (const entry of readdirSync(categoryDir, { withFileTypes: true })) {
355
- if (!entry.isFile() || !entry.name.endsWith(".ts"))
356
- continue;
357
- const check = entry.name.replace(/\.ts$/, "");
358
- if (!check || check === "index" || check === "shared")
359
- continue;
360
- const validatorName = `${category.name}-${check}`;
361
- const imageBin = resolve3(imageDir, `bin/validators/${validatorName}`);
362
- const symlinkPath = resolve3(binValidatorsDir, validatorName);
363
- if (existsSync(imageBin)) {
364
- try {
365
- unlinkSync(symlinkPath);
366
- } catch {}
367
- symlinkSync(imageBin, symlinkPath);
368
- }
369
- }
370
- }
371
- }
372
- const agentsDir = resolve3(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "agents");
373
- if (existsSync(agentsDir)) {
374
- let relinkCount = 0;
375
- for (const agentEntry of readdirSync(agentsDir, { withFileTypes: true })) {
376
- if (!agentEntry.isDirectory())
377
- continue;
378
- const agentBinDir = resolve3(agentsDir, agentEntry.name, "worktree", ".rig", "bin");
379
- if (!existsSync(agentBinDir))
380
- continue;
381
- const walkDir = (dir) => {
382
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
383
- const fullPath = resolve3(dir, entry.name);
384
- if (entry.isDirectory()) {
385
- walkDir(fullPath);
386
- } else if (entry.isSymbolicLink()) {
387
- const target = readlinkSync(fullPath);
388
- if (target.includes("/.rig/runtime/images/") && !target.includes(`/${currentId}/`)) {
389
- const newTarget = target.replace(/\/\.rig\/runtime\/images\/[^/]+\//, `/.rig/runtime/images/${currentId}/`);
390
- try {
391
- unlinkSync(fullPath);
392
- symlinkSync(newTarget, fullPath);
393
- relinkCount++;
394
- } catch {}
395
- }
396
- }
397
- }
398
- };
399
- walkDir(agentBinDir);
400
- }
401
- if (relinkCount > 0 && context.outputMode === "text") {
402
- console.log(`Re-linked ${relinkCount} worktree symlink(s) to image ${currentId}.`);
403
- }
404
- }
405
- if (context.outputMode === "text") {
406
- console.log(`Rebuilt ${targets.length} binaries into image ${currentId}.`);
407
- }
408
- return { ok: true, group: "dist", command, details: { imageId: currentId, count: targets.length } };
409
- }
410
- default:
411
- throw new CliError(`Unknown dist command: ${command}`, 1, { hint: "Run `rig dist --help` \u2014 commands are build|install|doctor|rebuild-agent." });
412
- }
413
- }
414
- export {
415
- executeDist,
416
- collectRigValidatorBuildTargets
417
- };
@@ -1,3 +0,0 @@
1
- import type { CommandOutcome } from "@rig/runtime";
2
- import { type RunnerContext } from "../runner";
3
- export declare function executeDoctor(context: RunnerContext, args: string[]): Promise<CommandOutcome>;