@h-rig/runtime 0.0.6-alpha.0
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.
- package/README.md +27 -0
- package/dist/bin/rig-agent-dispatch.js +9615 -0
- package/dist/bin/rig-agent.js +9512 -0
- package/dist/bin/rig-browser-tool.js +269 -0
- package/dist/src/agent-mode.js +48 -0
- package/dist/src/baked-secrets.js +121 -0
- package/dist/src/binary-build-worker.js +312 -0
- package/dist/src/binary-run.js +540 -0
- package/dist/src/boundaries.js +1 -0
- package/dist/src/build-time-config.js +25 -0
- package/dist/src/control-plane/agent-roles.js +27 -0
- package/dist/src/control-plane/agent-wrapper.js +9621 -0
- package/dist/src/control-plane/authority-files.js +582 -0
- package/dist/src/control-plane/browser-contract.js +135 -0
- package/dist/src/control-plane/controlled-bash.js +1111 -0
- package/dist/src/control-plane/errors.js +13 -0
- package/dist/src/control-plane/harness-main.js +10828 -0
- package/dist/src/control-plane/hook-materializer.js +75 -0
- package/dist/src/control-plane/hooks/audit-trail.js +353 -0
- package/dist/src/control-plane/hooks/completion-verification.js +7552 -0
- package/dist/src/control-plane/hooks/import-guard.js +890 -0
- package/dist/src/control-plane/hooks/inject-context.js +4189 -0
- package/dist/src/control-plane/hooks/post-edit-lint.js +43 -0
- package/dist/src/control-plane/hooks/safety-guard.js +910 -0
- package/dist/src/control-plane/hooks/scope-guard.js +907 -0
- package/dist/src/control-plane/hooks/shared.js +44 -0
- package/dist/src/control-plane/hooks/submodule-branch.js +7797 -0
- package/dist/src/control-plane/hooks/task-runtime-start.js +7799 -0
- package/dist/src/control-plane/hooks/test-integrity-guard.js +891 -0
- package/dist/src/control-plane/materialize-task-config.js +453 -0
- package/dist/src/control-plane/memory-sync/cli.js +2019 -0
- package/dist/src/control-plane/memory-sync/db.js +753 -0
- package/dist/src/control-plane/memory-sync/embed.js +281 -0
- package/dist/src/control-plane/memory-sync/index.js +2049 -0
- package/dist/src/control-plane/memory-sync/query.js +294 -0
- package/dist/src/control-plane/memory-sync/read.js +784 -0
- package/dist/src/control-plane/memory-sync/types.js +6 -0
- package/dist/src/control-plane/memory-sync/write.js +1547 -0
- package/dist/src/control-plane/native/git-native.js +490 -0
- package/dist/src/control-plane/native/git-ops.js +2860 -0
- package/dist/src/control-plane/native/harness-cli.js +9721 -0
- package/dist/src/control-plane/native/pr-automation.js +373 -0
- package/dist/src/control-plane/native/profile-ops.js +481 -0
- package/dist/src/control-plane/native/repo-ops.js +2342 -0
- package/dist/src/control-plane/native/root-resolver.js +66 -0
- package/dist/src/control-plane/native/run-ops.js +3281 -0
- package/dist/src/control-plane/native/runtime-native-sidecar.js +299 -0
- package/dist/src/control-plane/native/runtime-native.js +392 -0
- package/dist/src/control-plane/native/scope-rules.js +17 -0
- package/dist/src/control-plane/native/task-ops.js +6320 -0
- package/dist/src/control-plane/native/task-state.js +1512 -0
- package/dist/src/control-plane/native/utils.js +535 -0
- package/dist/src/control-plane/native/validator-binaries.js +889 -0
- package/dist/src/control-plane/native/validator.js +2197 -0
- package/dist/src/control-plane/native/verifier.js +3249 -0
- package/dist/src/control-plane/native/workspace-ops.js +1635 -0
- package/dist/src/control-plane/plugin-host-context.js +334 -0
- package/dist/src/control-plane/project-main-pre-run-sync.js +630 -0
- package/dist/src/control-plane/provider/claude-stream-records.js +158 -0
- package/dist/src/control-plane/provider/codex-app-server.js +885 -0
- package/dist/src/control-plane/provider/codex-exec-records.js +203 -0
- package/dist/src/control-plane/provider/rig-task-run-skill.js +39 -0
- package/dist/src/control-plane/provider/runtime-instructions.js +96 -0
- package/dist/src/control-plane/remote.js +854 -0
- package/dist/src/control-plane/repos/index.js +473 -0
- package/dist/src/control-plane/repos/layout.js +124 -0
- package/dist/src/control-plane/repos/mirror/bootstrap.js +268 -0
- package/dist/src/control-plane/repos/mirror/refresh.js +398 -0
- package/dist/src/control-plane/repos/mirror/state.js +167 -0
- package/dist/src/control-plane/repos/registry.js +77 -0
- package/dist/src/control-plane/repos/types.js +1 -0
- package/dist/src/control-plane/runtime/agent-mode.js +48 -0
- package/dist/src/control-plane/runtime/baked-secrets.js +120 -0
- package/dist/src/control-plane/runtime/claude-tool-router-binary.js +343 -0
- package/dist/src/control-plane/runtime/claude-tool-router.js +520 -0
- package/dist/src/control-plane/runtime/context.js +216 -0
- package/dist/src/control-plane/runtime/events.js +218 -0
- package/dist/src/control-plane/runtime/guard-types.js +6 -0
- package/dist/src/control-plane/runtime/guard.js +880 -0
- package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +1194 -0
- package/dist/src/control-plane/runtime/image/index.js +2255 -0
- package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +1191 -0
- package/dist/src/control-plane/runtime/image.js +2255 -0
- package/dist/src/control-plane/runtime/index.js +8511 -0
- package/dist/src/control-plane/runtime/isolation/discovery.js +599 -0
- package/dist/src/control-plane/runtime/isolation/home.js +1217 -0
- package/dist/src/control-plane/runtime/isolation/index.js +8193 -0
- package/dist/src/control-plane/runtime/isolation/runner.js +2651 -0
- package/dist/src/control-plane/runtime/isolation/shared.js +501 -0
- package/dist/src/control-plane/runtime/isolation/toolchain.js +1892 -0
- package/dist/src/control-plane/runtime/isolation/types.js +1 -0
- package/dist/src/control-plane/runtime/isolation/worktree.js +509 -0
- package/dist/src/control-plane/runtime/isolation.js +8193 -0
- package/dist/src/control-plane/runtime/overlay.js +67 -0
- package/dist/src/control-plane/runtime/plugin-mode.js +41 -0
- package/dist/src/control-plane/runtime/plugins.js +1131 -0
- package/dist/src/control-plane/runtime/provisioning-env.js +220 -0
- package/dist/src/control-plane/runtime/queue.js +8358 -0
- package/dist/src/control-plane/runtime/rig-shell.js +205 -0
- package/dist/src/control-plane/runtime/rig-tools.js +182 -0
- package/dist/src/control-plane/runtime/runner-context.js +1 -0
- package/dist/src/control-plane/runtime/runtime-paths.js +184 -0
- package/dist/src/control-plane/runtime/sandbox/backend-bwrap.js +311 -0
- package/dist/src/control-plane/runtime/sandbox/backend-none.js +21 -0
- package/dist/src/control-plane/runtime/sandbox/backend-seatbelt.js +268 -0
- package/dist/src/control-plane/runtime/sandbox/backend.js +1718 -0
- package/dist/src/control-plane/runtime/sandbox/orchestrator.js +1745 -0
- package/dist/src/control-plane/runtime/sandbox/utils.js +137 -0
- package/dist/src/control-plane/runtime/sandbox-backend-bwrap.js +311 -0
- package/dist/src/control-plane/runtime/sandbox-backend-none.js +21 -0
- package/dist/src/control-plane/runtime/sandbox-backend-seatbelt.js +268 -0
- package/dist/src/control-plane/runtime/sandbox-backend.js +1718 -0
- package/dist/src/control-plane/runtime/sandbox-orchestrator.js +1745 -0
- package/dist/src/control-plane/runtime/sandbox-utils.js +137 -0
- package/dist/src/control-plane/runtime/snapshot/index.js +454 -0
- package/dist/src/control-plane/runtime/snapshot/sidecar.js +502 -0
- package/dist/src/control-plane/runtime/snapshot/task-run.js +1578 -0
- package/dist/src/control-plane/runtime/snapshot-sidecar.js +498 -0
- package/dist/src/control-plane/runtime/snapshot.js +454 -0
- package/dist/src/control-plane/runtime/task-run-snapshot.js +1578 -0
- package/dist/src/control-plane/runtime/tool-gateway.js +422 -0
- package/dist/src/control-plane/runtime/tooling/browser-tools.js +32 -0
- package/dist/src/control-plane/runtime/tooling/claude-router-binary.js +343 -0
- package/dist/src/control-plane/runtime/tooling/claude-router.js +524 -0
- package/dist/src/control-plane/runtime/tooling/file-tools.js +182 -0
- package/dist/src/control-plane/runtime/tooling/gateway.js +422 -0
- package/dist/src/control-plane/runtime/tooling/index.js +1290 -0
- package/dist/src/control-plane/runtime/tooling/shell.js +205 -0
- package/dist/src/control-plane/runtime/types.js +1 -0
- package/dist/src/control-plane/setup-version.js +14 -0
- package/dist/src/control-plane/state-sync/index.js +1509 -0
- package/dist/src/control-plane/state-sync/read.js +856 -0
- package/dist/src/control-plane/state-sync/reconcile.js +260 -0
- package/dist/src/control-plane/state-sync/repo.js +302 -0
- package/dist/src/control-plane/state-sync/types.js +111 -0
- package/dist/src/control-plane/state-sync/write.js +1469 -0
- package/dist/src/control-plane/task-fields.js +38 -0
- package/dist/src/control-plane/task-source-bootstrap.js +46 -0
- package/dist/src/control-plane/task-source.js +30 -0
- package/dist/src/control-plane/tasks/legacy-task-config-source.js +130 -0
- package/dist/src/control-plane/tasks/plugin-task-source.js +103 -0
- package/dist/src/control-plane/tasks/source-aware-task-config-source.js +611 -0
- package/dist/src/control-plane/tasks/source-lifecycle.js +1093 -0
- package/dist/src/control-plane/tasks/task-record-reader.js +9 -0
- package/dist/src/control-plane/validators/boundary/public-apis.js +107 -0
- package/dist/src/control-plane/validators/integration/_shared.js +51 -0
- package/dist/src/control-plane/validators/integration/adm-audit-http.js +85 -0
- package/dist/src/control-plane/validators/integration/adm-auth-http.js +78 -0
- package/dist/src/control-plane/validators/integration/adm-issuer-http.js +80 -0
- package/dist/src/control-plane/validators/integration/adm-migration.js +78 -0
- package/dist/src/control-plane/validators/integration/adm-scaffold.js +78 -0
- package/dist/src/control-plane/validators/runtime-registration.js +64 -0
- package/dist/src/control-plane/validators/shared.js +683 -0
- package/dist/src/events.js +218 -0
- package/dist/src/execution.js +35 -0
- package/dist/src/index.js +1633 -0
- package/dist/src/layout.js +145 -0
- package/dist/src/local-server.js +202 -0
- package/dist/src/plugins.js +329 -0
- package/dist/src/remote-http.js +83 -0
- package/dist/src/runtime-context.js +216 -0
- package/dist/src/types.js +1 -0
- package/native/darwin-arm64/bin/rig-git +0 -0
- package/native/darwin-arm64/bin/rig-shell +0 -0
- package/native/darwin-arm64/bin/rig-tools +0 -0
- package/native/darwin-arm64/lib/runtime-native-darwin-arm64.dylib +0 -0
- package/native/darwin-arm64/lib/runtime-native.dylib +0 -0
- package/native/darwin-arm64/manifest.json +1 -0
- package/native/linux-x64/bin/rig-git +0 -0
- package/native/linux-x64/bin/rig-shell +0 -0
- package/native/linux-x64/bin/rig-tools +0 -0
- package/native/linux-x64/lib/runtime-native-linux-x64.so +0 -0
- package/native/linux-x64/lib/runtime-native.so +0 -0
- package/native/linux-x64/manifest.json +1 -0
- package/package.json +74 -0
- package/skills/rig-task-run.md +71 -0
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/native/validator-binaries.ts
|
|
3
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, rmSync as rmSync3, statSync as statSync2 } from "fs";
|
|
4
|
+
import { dirname as dirname4, resolve as resolve7 } from "path";
|
|
5
|
+
|
|
6
|
+
// packages/runtime/src/binary-run.ts
|
|
7
|
+
import { chmodSync, cpSync, existsSync as existsSync2, mkdirSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
8
|
+
import { basename as basename2, dirname as dirname2, resolve as resolve2 } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
11
|
+
|
|
12
|
+
// packages/runtime/src/layout.ts
|
|
13
|
+
import { existsSync } from "fs";
|
|
14
|
+
import { basename, dirname, resolve } from "path";
|
|
15
|
+
var RIG_DEFINITION_DIRNAME = "rig";
|
|
16
|
+
var RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
17
|
+
function resolveMonorepoRoot(projectRoot) {
|
|
18
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
19
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
20
|
+
if (explicit) {
|
|
21
|
+
const explicitRoot = resolve(explicit);
|
|
22
|
+
const explicitParent = dirname(explicitRoot);
|
|
23
|
+
if (basename(explicitParent) === ".worktrees") {
|
|
24
|
+
const owner = dirname(explicitParent);
|
|
25
|
+
const ownerHasGit = existsSync(resolve(owner, ".git"));
|
|
26
|
+
const ownerHasTaskConfig = existsSync(resolve(owner, ".rig", "task-config.json"));
|
|
27
|
+
const ownerHasRigConfig = existsSync(resolve(owner, "rig.config.ts"));
|
|
28
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
29
|
+
return owner;
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
|
|
32
|
+
}
|
|
33
|
+
if (!existsSync(resolve(explicitRoot, ".git"))) {
|
|
34
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
|
|
35
|
+
}
|
|
36
|
+
const hasTaskConfig = existsSync(resolve(explicitRoot, ".rig", "task-config.json"));
|
|
37
|
+
const hasRigConfig = existsSync(resolve(explicitRoot, "rig.config.ts"));
|
|
38
|
+
if (!hasTaskConfig && !hasRigConfig) {
|
|
39
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
|
|
40
|
+
}
|
|
41
|
+
return explicitRoot;
|
|
42
|
+
}
|
|
43
|
+
const projectParent = dirname(normalizedProjectRoot);
|
|
44
|
+
if (basename(projectParent) === ".worktrees") {
|
|
45
|
+
const worktreeOwner = dirname(projectParent);
|
|
46
|
+
const ownerHasGit = existsSync(resolve(worktreeOwner, ".git"));
|
|
47
|
+
const ownerHasTaskConfig = existsSync(resolve(worktreeOwner, ".rig", "task-config.json"));
|
|
48
|
+
const ownerHasRigConfig = existsSync(resolve(worktreeOwner, "rig.config.ts"));
|
|
49
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
50
|
+
return worktreeOwner;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return normalizedProjectRoot;
|
|
54
|
+
}
|
|
55
|
+
function resolveRuntimeWorkspaceLayout(workspaceDir) {
|
|
56
|
+
const root = resolve(workspaceDir);
|
|
57
|
+
const rigRoot = resolve(root, ".rig");
|
|
58
|
+
const logsDir = resolve(rigRoot, "logs");
|
|
59
|
+
const stateDir = resolve(rigRoot, "state");
|
|
60
|
+
const runtimeDir = resolve(rigRoot, "runtime");
|
|
61
|
+
const binDir = resolve(rigRoot, "bin");
|
|
62
|
+
return {
|
|
63
|
+
workspaceDir: root,
|
|
64
|
+
rigRoot,
|
|
65
|
+
stateDir,
|
|
66
|
+
logsDir,
|
|
67
|
+
artifactsRoot: resolve(root, RIG_ARTIFACTS_DIRNAME),
|
|
68
|
+
runtimeDir,
|
|
69
|
+
homeDir: resolve(rigRoot, "home"),
|
|
70
|
+
tmpDir: resolve(rigRoot, "tmp"),
|
|
71
|
+
cacheDir: resolve(rigRoot, "cache"),
|
|
72
|
+
sessionDir: resolve(rigRoot, "session"),
|
|
73
|
+
binDir,
|
|
74
|
+
distDir: resolve(rigRoot, "dist"),
|
|
75
|
+
pluginBinDir: resolve(binDir, "plugins"),
|
|
76
|
+
contextPath: resolve(rigRoot, "runtime-context.json"),
|
|
77
|
+
controlPlaneEventsFile: resolve(logsDir, "control-plane.events.jsonl")
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function resolveActiveRuntimeWorkspaceRoot(monorepoRoot) {
|
|
81
|
+
const explicit = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
82
|
+
if (!explicit) {
|
|
83
|
+
throw new Error("No active runtime workspace. Set RIG_TASK_WORKSPACE or provision a task runtime first.");
|
|
84
|
+
}
|
|
85
|
+
return resolve(explicit);
|
|
86
|
+
}
|
|
87
|
+
function resolveRigLayout(projectRoot) {
|
|
88
|
+
const monorepoRoot = resolveMonorepoRoot(projectRoot);
|
|
89
|
+
const definitionRoot = resolve(projectRoot, RIG_DEFINITION_DIRNAME);
|
|
90
|
+
const runtimeWorkspaceRoot = resolveActiveRuntimeWorkspaceRoot(monorepoRoot);
|
|
91
|
+
const runtimeLayout = resolveRuntimeWorkspaceLayout(runtimeWorkspaceRoot);
|
|
92
|
+
const policyDir = resolve(definitionRoot, "policy");
|
|
93
|
+
return {
|
|
94
|
+
projectRoot,
|
|
95
|
+
monorepoRoot,
|
|
96
|
+
definitionRoot,
|
|
97
|
+
runtimeWorkspaceRoot,
|
|
98
|
+
stateRoot: runtimeLayout.rigRoot,
|
|
99
|
+
artifactsRoot: runtimeLayout.artifactsRoot,
|
|
100
|
+
configPath: resolve(definitionRoot, "config.sh"),
|
|
101
|
+
taskConfigPath: resolve(runtimeWorkspaceRoot, ".rig", "task-config.json"),
|
|
102
|
+
policyDir,
|
|
103
|
+
policyFile: resolve(policyDir, "policy.json"),
|
|
104
|
+
pluginsDir: resolve(definitionRoot, "plugins"),
|
|
105
|
+
hooksDir: resolve(definitionRoot, "hooks"),
|
|
106
|
+
toolsDir: resolve(definitionRoot, "tools"),
|
|
107
|
+
templatesDir: resolve(definitionRoot, "templates"),
|
|
108
|
+
validationDir: resolve(definitionRoot, "validation"),
|
|
109
|
+
stateDir: runtimeLayout.stateDir,
|
|
110
|
+
logsDir: runtimeLayout.logsDir,
|
|
111
|
+
notificationsDir: resolve(definitionRoot, "notifications"),
|
|
112
|
+
runtimeDir: runtimeLayout.runtimeDir,
|
|
113
|
+
distDir: runtimeLayout.distDir,
|
|
114
|
+
binDir: runtimeLayout.binDir,
|
|
115
|
+
pluginBinDir: runtimeLayout.pluginBinDir,
|
|
116
|
+
keybindingsPath: resolve(definitionRoot, "keybindings.json"),
|
|
117
|
+
controlPlaneEventsFile: runtimeLayout.controlPlaneEventsFile
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// packages/runtime/src/binary-run.ts
|
|
122
|
+
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
123
|
+
async function buildRuntimeBinary(options) {
|
|
124
|
+
return runSerializedRuntimeBinaryBuild(async () => {
|
|
125
|
+
const resolved = resolveRuntimeBinaryBuildOptions(options);
|
|
126
|
+
runBestEffortBuildGc();
|
|
127
|
+
const manifestPath = runtimeBinaryCacheManifestPath(resolved.outputPath);
|
|
128
|
+
const buildKey = createRuntimeBinaryBuildKey({
|
|
129
|
+
entrypoint: resolved.entrypoint,
|
|
130
|
+
define: resolved.define,
|
|
131
|
+
env: resolved.env
|
|
132
|
+
});
|
|
133
|
+
if (await isRuntimeBinaryBuildFresh({ outputPath: resolved.outputPath, manifestPath, buildKey })) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (shouldUseRuntimeBinaryBuildWorker()) {
|
|
137
|
+
await buildRuntimeBinaryViaWorker(resolved);
|
|
138
|
+
} else {
|
|
139
|
+
await buildRuntimeBinaryInProcess(resolved, { manifestPath, buildKey });
|
|
140
|
+
}
|
|
141
|
+
runBestEffortBuildGc();
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
145
|
+
const tempBuildDir = resolve2(dirname2(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
146
|
+
const tempOutputPath = resolve2(tempBuildDir, basename2(options.outputPath));
|
|
147
|
+
mkdirSync(tempBuildDir, { recursive: true });
|
|
148
|
+
await withTemporaryEnv({
|
|
149
|
+
...options.env,
|
|
150
|
+
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
151
|
+
}, async () => withTemporaryCwd(tempBuildDir, async () => {
|
|
152
|
+
const buildResult = await Bun.build({
|
|
153
|
+
entrypoints: [options.entrypoint],
|
|
154
|
+
compile: {
|
|
155
|
+
target: currentCompileTarget(),
|
|
156
|
+
outfile: tempOutputPath
|
|
157
|
+
},
|
|
158
|
+
target: "bun",
|
|
159
|
+
format: "esm",
|
|
160
|
+
minify: true,
|
|
161
|
+
bytecode: true,
|
|
162
|
+
metafile: true,
|
|
163
|
+
define: options.define ? {
|
|
164
|
+
__RIG_BUILD_CONFIG__: JSON.stringify(options.define)
|
|
165
|
+
} : undefined
|
|
166
|
+
});
|
|
167
|
+
if (!buildResult.success) {
|
|
168
|
+
const details = buildResult.logs.map((log) => [log.message, log.position?.file ? `${log.position.file}:${log.position.line}:${log.position.column}` : ""].filter(Boolean).join(" ")).filter(Boolean).join(`
|
|
169
|
+
`);
|
|
170
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
171
|
+
}
|
|
172
|
+
if (!existsSync2(tempOutputPath)) {
|
|
173
|
+
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
174
|
+
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
175
|
+
}
|
|
176
|
+
renameSync(tempOutputPath, options.outputPath);
|
|
177
|
+
chmodSync(options.outputPath, 493);
|
|
178
|
+
if (manifest) {
|
|
179
|
+
await writeRuntimeBinaryCacheManifest({
|
|
180
|
+
manifestPath: manifest.manifestPath,
|
|
181
|
+
buildKey: manifest.buildKey,
|
|
182
|
+
cwd: tempBuildDir,
|
|
183
|
+
metafile: buildResult.metafile
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
})).finally(() => {
|
|
187
|
+
rmSync(tempBuildDir, { recursive: true, force: true });
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function runBestEffortBuildGc() {
|
|
191
|
+
try {
|
|
192
|
+
drainMicrotasks();
|
|
193
|
+
} catch {}
|
|
194
|
+
try {
|
|
195
|
+
gcAndSweep();
|
|
196
|
+
} catch {}
|
|
197
|
+
}
|
|
198
|
+
function runtimeBinaryCacheManifestPath(outputPath) {
|
|
199
|
+
return `${outputPath}.build-manifest.json`;
|
|
200
|
+
}
|
|
201
|
+
function resolveRuntimeBinaryBuildOptions(options) {
|
|
202
|
+
return {
|
|
203
|
+
...options,
|
|
204
|
+
entrypoint: resolve2(options.cwd, options.sourcePath),
|
|
205
|
+
outputPath: resolve2(options.outputPath)
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function shouldUseRuntimeBinaryBuildWorker() {
|
|
209
|
+
if (process.env.RIG_RUNTIME_BUILD_WORKER === "1") {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (process.env.RIG_RUNTIME_BUILD_IN_PROCESS === "1") {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
async function buildRuntimeBinaryViaWorker(options) {
|
|
218
|
+
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
219
|
+
if (!workerSourcePath || !existsSync2(workerSourcePath)) {
|
|
220
|
+
await buildRuntimeBinaryInProcess(options, {
|
|
221
|
+
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
222
|
+
buildKey: createRuntimeBinaryBuildKey({
|
|
223
|
+
entrypoint: options.entrypoint,
|
|
224
|
+
define: options.define,
|
|
225
|
+
env: options.env
|
|
226
|
+
})
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const payloadPath = createRuntimeBinaryBuildWorkerPayloadPath(options.outputPath);
|
|
231
|
+
const bunCli = resolveRuntimeBinaryBuildWorkerInvocation();
|
|
232
|
+
await Bun.write(payloadPath, `${JSON.stringify(options)}
|
|
233
|
+
`);
|
|
234
|
+
const build = Bun.spawn([bunCli.command, workerSourcePath, payloadPath], {
|
|
235
|
+
cwd: options.cwd,
|
|
236
|
+
stdout: "pipe",
|
|
237
|
+
stderr: "pipe",
|
|
238
|
+
env: {
|
|
239
|
+
...process.env,
|
|
240
|
+
...options.env,
|
|
241
|
+
...bunCli.env,
|
|
242
|
+
RIG_RUNTIME_BUILD_WORKER: "1"
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
246
|
+
build.exited,
|
|
247
|
+
new Response(build.stdout).text(),
|
|
248
|
+
new Response(build.stderr).text()
|
|
249
|
+
]);
|
|
250
|
+
rmSync(payloadPath, { force: true });
|
|
251
|
+
if (exitCode !== 0) {
|
|
252
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
256
|
+
return resolve2(dirname2(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
257
|
+
}
|
|
258
|
+
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
259
|
+
const envRoots = [
|
|
260
|
+
options.cwd?.trim(),
|
|
261
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
262
|
+
process.env.PROJECT_RIG_ROOT?.trim()
|
|
263
|
+
].filter(Boolean);
|
|
264
|
+
for (const root of envRoots) {
|
|
265
|
+
const candidate = resolve2(root, "packages/runtime/src/binary-build-worker.ts");
|
|
266
|
+
if (existsSync2(candidate)) {
|
|
267
|
+
return candidate;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
const localCandidate = resolve2(import.meta.dir, "binary-build-worker.ts");
|
|
271
|
+
return existsSync2(localCandidate) ? localCandidate : null;
|
|
272
|
+
}
|
|
273
|
+
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
274
|
+
const bunPath = Bun.which("bun");
|
|
275
|
+
if (bunPath) {
|
|
276
|
+
return { command: bunPath, env: {} };
|
|
277
|
+
}
|
|
278
|
+
if (process.execPath?.trim()) {
|
|
279
|
+
return {
|
|
280
|
+
command: process.execPath,
|
|
281
|
+
env: { BUN_BE_BUN: "1" }
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
throw new Error("bun is required to run the runtime binary build worker.");
|
|
285
|
+
}
|
|
286
|
+
function currentCompileTarget() {
|
|
287
|
+
if (process.platform === "darwin") {
|
|
288
|
+
return process.arch === "arm64" ? "bun-darwin-arm64" : "bun-darwin-x64";
|
|
289
|
+
}
|
|
290
|
+
if (process.platform === "linux") {
|
|
291
|
+
return process.arch === "arm64" ? "bun-linux-arm64" : "bun-linux-x64";
|
|
292
|
+
}
|
|
293
|
+
return "bun-windows-x64";
|
|
294
|
+
}
|
|
295
|
+
function createRuntimeBinaryBuildKey(input) {
|
|
296
|
+
return JSON.stringify({
|
|
297
|
+
version: 1,
|
|
298
|
+
bunVersion: Bun.version,
|
|
299
|
+
platform: process.platform,
|
|
300
|
+
arch: process.arch,
|
|
301
|
+
entrypoint: input.entrypoint,
|
|
302
|
+
define: sortRecord(input.define),
|
|
303
|
+
env: sortRecord(input.env)
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
async function isRuntimeBinaryBuildFresh(input) {
|
|
307
|
+
if (!existsSync2(input.outputPath) || !existsSync2(input.manifestPath)) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
let manifest = null;
|
|
311
|
+
try {
|
|
312
|
+
manifest = await Bun.file(input.manifestPath).json();
|
|
313
|
+
} catch {
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
if (!manifest || manifest.version !== 1 || manifest.buildKey !== input.buildKey) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
320
|
+
if (!existsSync2(filePath)) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
if (await sha256File(filePath) !== expectedDigest) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
async function writeRuntimeBinaryCacheManifest(input) {
|
|
330
|
+
const inputs = {};
|
|
331
|
+
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
332
|
+
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
333
|
+
if (!normalized || !existsSync2(normalized)) {
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
inputs[normalized] = await sha256File(normalized);
|
|
337
|
+
}
|
|
338
|
+
const manifest = {
|
|
339
|
+
version: 1,
|
|
340
|
+
buildKey: input.buildKey,
|
|
341
|
+
inputs
|
|
342
|
+
};
|
|
343
|
+
await Bun.write(input.manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
344
|
+
`);
|
|
345
|
+
}
|
|
346
|
+
function normalizeBuildInputPath(cwd, inputPath) {
|
|
347
|
+
if (!inputPath) {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
if (inputPath.startsWith("file://")) {
|
|
351
|
+
return fileURLToPath(inputPath);
|
|
352
|
+
}
|
|
353
|
+
if (inputPath.startsWith("<")) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
return resolve2(cwd, inputPath);
|
|
357
|
+
}
|
|
358
|
+
async function sha256File(path) {
|
|
359
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
360
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
361
|
+
return hasher.digest("hex");
|
|
362
|
+
}
|
|
363
|
+
function sortRecord(value) {
|
|
364
|
+
if (!value) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
|
|
368
|
+
}
|
|
369
|
+
async function runSerializedRuntimeBinaryBuild(action) {
|
|
370
|
+
const previous = runtimeBinaryBuildQueue;
|
|
371
|
+
let release;
|
|
372
|
+
runtimeBinaryBuildQueue = new Promise((resolve3) => {
|
|
373
|
+
release = resolve3;
|
|
374
|
+
});
|
|
375
|
+
await previous;
|
|
376
|
+
try {
|
|
377
|
+
return await action();
|
|
378
|
+
} finally {
|
|
379
|
+
release();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
async function withTemporaryEnv(env, action) {
|
|
383
|
+
if (!env) {
|
|
384
|
+
return action();
|
|
385
|
+
}
|
|
386
|
+
const previousValues = new Map;
|
|
387
|
+
for (const [key, value] of Object.entries(env)) {
|
|
388
|
+
previousValues.set(key, process.env[key]);
|
|
389
|
+
if (value === undefined) {
|
|
390
|
+
delete process.env[key];
|
|
391
|
+
} else {
|
|
392
|
+
process.env[key] = value;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
return await action();
|
|
397
|
+
} finally {
|
|
398
|
+
for (const [key, value] of previousValues.entries()) {
|
|
399
|
+
if (value === undefined) {
|
|
400
|
+
delete process.env[key];
|
|
401
|
+
} else {
|
|
402
|
+
process.env[key] = value;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
async function withTemporaryCwd(cwd, action) {
|
|
408
|
+
const previousCwd = process.cwd();
|
|
409
|
+
process.chdir(cwd);
|
|
410
|
+
try {
|
|
411
|
+
return await action();
|
|
412
|
+
} finally {
|
|
413
|
+
process.chdir(previousCwd);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
418
|
+
import { delimiter, resolve as resolve4 } from "path";
|
|
419
|
+
|
|
420
|
+
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
421
|
+
import { existsSync as existsSync3, readdirSync, realpathSync } from "fs";
|
|
422
|
+
import { resolve as resolve3 } from "path";
|
|
423
|
+
|
|
424
|
+
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
425
|
+
function uniq(values) {
|
|
426
|
+
return [...new Set(values)];
|
|
427
|
+
}
|
|
428
|
+
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
429
|
+
function resolveBunBinaryPath() {
|
|
430
|
+
const explicit = normalizeExecutablePath(process.env.RIG_BUN_PATH?.trim());
|
|
431
|
+
if (explicit) {
|
|
432
|
+
return explicit;
|
|
433
|
+
}
|
|
434
|
+
const pathBun = normalizeExecutablePath(Bun.which("bun")?.trim());
|
|
435
|
+
if (pathBun && !looksLikeRuntimeGateway(pathBun)) {
|
|
436
|
+
return pathBun;
|
|
437
|
+
}
|
|
438
|
+
const home = process.env.HOME?.trim();
|
|
439
|
+
const fallbackCandidates = [
|
|
440
|
+
home ? resolve3(home, ".bun/bin/bun") : "",
|
|
441
|
+
"/opt/homebrew/bin/bun",
|
|
442
|
+
"/usr/local/bin/bun",
|
|
443
|
+
"/usr/bin/bun"
|
|
444
|
+
];
|
|
445
|
+
for (const candidate of fallbackCandidates) {
|
|
446
|
+
const normalized = normalizeExecutablePath(candidate);
|
|
447
|
+
if (normalized) {
|
|
448
|
+
return normalized;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const execPath = normalizeExecutablePath(process.execPath?.trim());
|
|
452
|
+
if (execPath && !looksLikeRuntimeGateway(execPath)) {
|
|
453
|
+
return execPath;
|
|
454
|
+
}
|
|
455
|
+
throw new Error("bun not found in PATH");
|
|
456
|
+
}
|
|
457
|
+
function resolveClaudeBinaryPath() {
|
|
458
|
+
const explicit = normalizeExecutablePath(process.env.RIG_CLAUDE_PATH?.trim());
|
|
459
|
+
if (explicit) {
|
|
460
|
+
return explicit;
|
|
461
|
+
}
|
|
462
|
+
const pathClaude = normalizeExecutablePath(Bun.which("claude")?.trim());
|
|
463
|
+
if (pathClaude && !looksLikeRuntimeGateway(pathClaude)) {
|
|
464
|
+
return pathClaude;
|
|
465
|
+
}
|
|
466
|
+
const home = process.env.HOME?.trim();
|
|
467
|
+
const fallbackCandidates = [
|
|
468
|
+
home ? resolve3(home, ".local/bin/claude") : "",
|
|
469
|
+
home ? resolve3(home, ".local/share/claude/local/claude") : "",
|
|
470
|
+
"/opt/homebrew/bin/claude",
|
|
471
|
+
"/usr/local/bin/claude",
|
|
472
|
+
"/usr/bin/claude"
|
|
473
|
+
];
|
|
474
|
+
for (const candidate of fallbackCandidates) {
|
|
475
|
+
const normalized = normalizeExecutablePath(candidate);
|
|
476
|
+
if (normalized) {
|
|
477
|
+
return normalized;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
throw new Error("claude not found in PATH");
|
|
481
|
+
}
|
|
482
|
+
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
483
|
+
return resolve3(bunBinaryPath, "../..");
|
|
484
|
+
}
|
|
485
|
+
function resolveClaudeInstallDir() {
|
|
486
|
+
const realPath = resolveClaudeBinaryPath();
|
|
487
|
+
return resolve3(realPath, "..");
|
|
488
|
+
}
|
|
489
|
+
function resolveNodeInstallDir() {
|
|
490
|
+
const preferredNode = resolvePreferredNodeBinary();
|
|
491
|
+
if (!preferredNode)
|
|
492
|
+
return null;
|
|
493
|
+
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
494
|
+
if (explicitNode && resolve3(explicitNode) === resolve3(preferredNode)) {
|
|
495
|
+
return preferredNode.endsWith("/bin/node") ? resolve3(preferredNode, "../..") : resolve3(preferredNode, "..");
|
|
496
|
+
}
|
|
497
|
+
try {
|
|
498
|
+
const realPath = realpathSync(preferredNode);
|
|
499
|
+
if (realPath.endsWith("/bin/node")) {
|
|
500
|
+
return resolve3(realPath, "../..");
|
|
501
|
+
}
|
|
502
|
+
return resolve3(realPath, "..");
|
|
503
|
+
} catch {
|
|
504
|
+
return resolve3(preferredNode, "..");
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function resolvePreferredNodeBinary() {
|
|
508
|
+
const candidates = [];
|
|
509
|
+
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
510
|
+
if (envNode) {
|
|
511
|
+
const explicit = resolve3(envNode);
|
|
512
|
+
if (existsSync3(explicit)) {
|
|
513
|
+
return explicit;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const nvmBin = process.env.NVM_BIN?.trim();
|
|
517
|
+
if (nvmBin) {
|
|
518
|
+
candidates.push(resolve3(nvmBin, "node"));
|
|
519
|
+
}
|
|
520
|
+
const home = process.env.HOME?.trim();
|
|
521
|
+
if (home) {
|
|
522
|
+
const nvmVersionsDir = resolve3(home, ".nvm/versions/node");
|
|
523
|
+
if (existsSync3(nvmVersionsDir)) {
|
|
524
|
+
try {
|
|
525
|
+
const versionDirs = readdirSync(nvmVersionsDir).map((entry) => entry.trim()).filter((entry) => /^v\d+\.\d+\.\d+$/.test(entry)).sort((a, b) => Bun.semver.order(b.replace(/^v/, ""), a.replace(/^v/, "")));
|
|
526
|
+
for (const versionDir of versionDirs) {
|
|
527
|
+
candidates.push(resolve3(nvmVersionsDir, versionDir, "bin/node"));
|
|
528
|
+
}
|
|
529
|
+
} catch {}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const whichNode = Bun.which("node");
|
|
533
|
+
if (whichNode) {
|
|
534
|
+
candidates.push(whichNode);
|
|
535
|
+
}
|
|
536
|
+
const deduped = uniq(candidates.map((candidate) => resolve3(candidate)));
|
|
537
|
+
const existing = deduped.filter((candidate) => existsSync3(candidate));
|
|
538
|
+
if (existing.length === 0) {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
const stable = existing.find((candidate) => {
|
|
542
|
+
const major = inferNodeMajor(candidate);
|
|
543
|
+
return typeof major === "number" && major >= 18 && major <= 24;
|
|
544
|
+
});
|
|
545
|
+
if (stable) {
|
|
546
|
+
return stable;
|
|
547
|
+
}
|
|
548
|
+
return existing[0] ?? null;
|
|
549
|
+
}
|
|
550
|
+
function inferNodeMajor(nodeBinaryPath) {
|
|
551
|
+
const normalized = resolve3(nodeBinaryPath).replace(/\\/g, "/");
|
|
552
|
+
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
553
|
+
if (!match) {
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
const major = Number.parseInt(match[1], 10);
|
|
557
|
+
return Number.isFinite(major) ? major : null;
|
|
558
|
+
}
|
|
559
|
+
function normalizeExecutablePath(candidate) {
|
|
560
|
+
if (!candidate) {
|
|
561
|
+
return "";
|
|
562
|
+
}
|
|
563
|
+
const normalized = resolve3(candidate);
|
|
564
|
+
if (!existsSync3(normalized)) {
|
|
565
|
+
return "";
|
|
566
|
+
}
|
|
567
|
+
try {
|
|
568
|
+
return realpathSync(normalized);
|
|
569
|
+
} catch {
|
|
570
|
+
return normalized;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function looksLikeRuntimeGateway(candidate) {
|
|
574
|
+
const normalized = resolve3(candidate).replace(/\\/g, "/");
|
|
575
|
+
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
579
|
+
function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
580
|
+
const env = { ...baseEnv };
|
|
581
|
+
const realBash = baseEnv.RIG_REAL_BASH?.trim() || "/bin/bash";
|
|
582
|
+
const bunBinary = baseEnv.RIG_BUN_PATH?.trim() || resolveBunBinaryPath();
|
|
583
|
+
const bunDir = resolveBunInstallDir(bunBinary);
|
|
584
|
+
const claudeBinary = baseEnv.RIG_CLAUDE_PATH?.trim() || (() => {
|
|
585
|
+
try {
|
|
586
|
+
return resolveClaudeBinaryPath();
|
|
587
|
+
} catch {
|
|
588
|
+
return "";
|
|
589
|
+
}
|
|
590
|
+
})();
|
|
591
|
+
const claudeDir = claudeBinary ? (() => {
|
|
592
|
+
try {
|
|
593
|
+
return resolveClaudeInstallDir();
|
|
594
|
+
} catch {
|
|
595
|
+
return resolve4(claudeBinary, "..");
|
|
596
|
+
}
|
|
597
|
+
})() : "";
|
|
598
|
+
const nodeDir = resolveNodeInstallDir();
|
|
599
|
+
const realHome = baseEnv.HOME?.trim();
|
|
600
|
+
const inheritedPath = (baseEnv.PATH ?? "").split(delimiter).map((entry) => entry.trim()).filter(Boolean).filter((entry) => !entry.endsWith("/.rig/bin") && !entry.endsWith("/rig/tools"));
|
|
601
|
+
const pathEntries = [
|
|
602
|
+
`${bunDir}/bin`,
|
|
603
|
+
claudeDir,
|
|
604
|
+
nodeDir ? `${nodeDir}/bin` : "",
|
|
605
|
+
realHome ? resolve4(realHome, ".local/bin") : "",
|
|
606
|
+
realHome ? resolve4(realHome, ".cargo/bin") : "",
|
|
607
|
+
...inheritedPath,
|
|
608
|
+
"/usr/local/bin",
|
|
609
|
+
"/usr/local/sbin",
|
|
610
|
+
"/opt/homebrew/bin",
|
|
611
|
+
"/opt/homebrew/sbin",
|
|
612
|
+
"/usr/bin",
|
|
613
|
+
"/bin",
|
|
614
|
+
"/usr/sbin",
|
|
615
|
+
"/sbin"
|
|
616
|
+
].filter(Boolean);
|
|
617
|
+
env.BASH = realBash;
|
|
618
|
+
env.SHELL = baseEnv.SHELL?.trim() || realBash;
|
|
619
|
+
env.PATH = [...new Set(pathEntries)].join(delimiter);
|
|
620
|
+
env.RIG_BUN_PATH = bunBinary;
|
|
621
|
+
if (claudeBinary) {
|
|
622
|
+
env.RIG_CLAUDE_PATH = claudeBinary;
|
|
623
|
+
}
|
|
624
|
+
env.PYTHON = env.PYTHON?.trim() || "python3";
|
|
625
|
+
const nodeGypPath = Bun.which("node-gyp");
|
|
626
|
+
if (nodeGypPath) {
|
|
627
|
+
env.npm_config_node_gyp = nodeGypPath;
|
|
628
|
+
}
|
|
629
|
+
delete env.RIG_BASH_ACTIVE;
|
|
630
|
+
delete env.RIG_BASH_MODE;
|
|
631
|
+
return env;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// packages/runtime/src/control-plane/native/utils.ts
|
|
635
|
+
import { resolve as resolve6 } from "path";
|
|
636
|
+
|
|
637
|
+
// packages/runtime/src/control-plane/native/runtime-native.ts
|
|
638
|
+
import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
|
|
639
|
+
import { copyFileSync, existsSync as existsSync4, mkdirSync as mkdirSync2, renameSync as renameSync2, rmSync as rmSync2, statSync } from "fs";
|
|
640
|
+
import { tmpdir } from "os";
|
|
641
|
+
import { dirname as dirname3, resolve as resolve5 } from "path";
|
|
642
|
+
var sharedNativeRuntimeOutputDir = resolve5(tmpdir(), "rig-native");
|
|
643
|
+
var sharedNativeRuntimeOutputPath = resolve5(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
|
|
644
|
+
var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
|
|
645
|
+
var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
|
|
646
|
+
async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOutputPath, options = {}) {
|
|
647
|
+
if (await buildNativeRuntimeLibrary(outputPath, options)) {
|
|
648
|
+
return outputPath;
|
|
649
|
+
}
|
|
650
|
+
return !options.force && existsSync4(outputPath) ? outputPath : null;
|
|
651
|
+
}
|
|
652
|
+
async function loadNativeRuntimeLibrary() {
|
|
653
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
656
|
+
for (const candidate of nativeRuntimeLibraryCandidates()) {
|
|
657
|
+
if (!candidate || !existsSync4(candidate)) {
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
const loaded = tryDlopenNativeRuntimeLibrary(candidate);
|
|
661
|
+
if (loaded) {
|
|
662
|
+
return loaded;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
const builtLibraryPath = await ensureNativeRuntimeLibraryPath(sharedNativeRuntimeOutputPath, { force: true });
|
|
666
|
+
if (!builtLibraryPath) {
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
669
|
+
return tryDlopenNativeRuntimeLibrary(builtLibraryPath);
|
|
670
|
+
}
|
|
671
|
+
function nativePackageLibraryCandidates(fromDir, names) {
|
|
672
|
+
const candidates = [];
|
|
673
|
+
let cursor = resolve5(fromDir);
|
|
674
|
+
for (let index = 0;index < 8; index += 1) {
|
|
675
|
+
for (const name of names) {
|
|
676
|
+
candidates.push(resolve5(cursor, "native", `${process.platform}-${process.arch}`, name), resolve5(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve5(cursor, "native", name), resolve5(cursor, "native", "lib", name));
|
|
677
|
+
}
|
|
678
|
+
const parent = dirname3(cursor);
|
|
679
|
+
if (parent === cursor)
|
|
680
|
+
break;
|
|
681
|
+
cursor = parent;
|
|
682
|
+
}
|
|
683
|
+
return candidates;
|
|
684
|
+
}
|
|
685
|
+
function nativeRuntimeLibraryCandidates() {
|
|
686
|
+
const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
|
|
687
|
+
const execDir = process.execPath?.trim() ? dirname3(process.execPath.trim()) : "";
|
|
688
|
+
const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
|
|
689
|
+
return [...new Set([
|
|
690
|
+
explicit,
|
|
691
|
+
...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
|
|
692
|
+
execDir ? resolve5(execDir, colocatedNativeRuntimeFileName) : "",
|
|
693
|
+
execDir ? resolve5(execDir, platformSpecific) : "",
|
|
694
|
+
execDir ? resolve5(execDir, "..", colocatedNativeRuntimeFileName) : "",
|
|
695
|
+
execDir ? resolve5(execDir, "..", platformSpecific) : "",
|
|
696
|
+
execDir ? resolve5(execDir, "lib", colocatedNativeRuntimeFileName) : "",
|
|
697
|
+
execDir ? resolve5(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
|
|
698
|
+
sharedNativeRuntimeOutputPath
|
|
699
|
+
].filter(Boolean))];
|
|
700
|
+
}
|
|
701
|
+
function resolveNativeRuntimeSourcePath() {
|
|
702
|
+
const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
|
|
703
|
+
if (explicit && existsSync4(explicit)) {
|
|
704
|
+
return explicit;
|
|
705
|
+
}
|
|
706
|
+
const bundled = resolve5(import.meta.dir, "../../../native/snapshot.zig");
|
|
707
|
+
return existsSync4(bundled) ? bundled : null;
|
|
708
|
+
}
|
|
709
|
+
async function buildNativeRuntimeLibrary(outputPath, options = {}) {
|
|
710
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
const zigBinary = Bun.which("zig");
|
|
714
|
+
const sourcePath = resolveNativeRuntimeSourcePath();
|
|
715
|
+
if (!zigBinary || !sourcePath) {
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
719
|
+
try {
|
|
720
|
+
mkdirSync2(dirname3(outputPath), { recursive: true });
|
|
721
|
+
const needsBuild = options.force === true || !existsSync4(outputPath) || statSync(sourcePath).mtimeMs > statSync(outputPath).mtimeMs;
|
|
722
|
+
if (!needsBuild) {
|
|
723
|
+
return true;
|
|
724
|
+
}
|
|
725
|
+
const build = Bun.spawn([
|
|
726
|
+
zigBinary,
|
|
727
|
+
"build-lib",
|
|
728
|
+
sourcePath,
|
|
729
|
+
"-dynamic",
|
|
730
|
+
"-O",
|
|
731
|
+
"ReleaseFast",
|
|
732
|
+
`-femit-bin=${tempOutputPath}`
|
|
733
|
+
], {
|
|
734
|
+
cwd: import.meta.dir,
|
|
735
|
+
stdout: "pipe",
|
|
736
|
+
stderr: "pipe"
|
|
737
|
+
});
|
|
738
|
+
const exitCode = await build.exited;
|
|
739
|
+
if (exitCode !== 0 || !existsSync4(tempOutputPath)) {
|
|
740
|
+
rmSync2(tempOutputPath, { force: true });
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
renameSync2(tempOutputPath, outputPath);
|
|
744
|
+
return true;
|
|
745
|
+
} catch {
|
|
746
|
+
rmSync2(tempOutputPath, { force: true });
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
function tryDlopenNativeRuntimeLibrary(outputPath) {
|
|
751
|
+
try {
|
|
752
|
+
return dlopen(outputPath, {
|
|
753
|
+
rig_scope_match: {
|
|
754
|
+
args: ["ptr", "ptr"],
|
|
755
|
+
returns: "u8"
|
|
756
|
+
},
|
|
757
|
+
snapshot_capture: {
|
|
758
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
759
|
+
returns: "ptr"
|
|
760
|
+
},
|
|
761
|
+
snapshot_delta: {
|
|
762
|
+
args: ["ptr", "ptr"],
|
|
763
|
+
returns: "ptr"
|
|
764
|
+
},
|
|
765
|
+
snapshot_store_delta: {
|
|
766
|
+
args: ["ptr", "ptr", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
|
|
767
|
+
returns: "ptr"
|
|
768
|
+
},
|
|
769
|
+
snapshot_inspect_delta: {
|
|
770
|
+
args: ["ptr", "u64"],
|
|
771
|
+
returns: "ptr"
|
|
772
|
+
},
|
|
773
|
+
snapshot_apply_delta: {
|
|
774
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
775
|
+
returns: "ptr"
|
|
776
|
+
},
|
|
777
|
+
snapshot_release: {
|
|
778
|
+
args: ["ptr"],
|
|
779
|
+
returns: "void"
|
|
780
|
+
},
|
|
781
|
+
runtime_hash_file: {
|
|
782
|
+
args: ["ptr", "u64"],
|
|
783
|
+
returns: "ptr"
|
|
784
|
+
},
|
|
785
|
+
runtime_hash_tree: {
|
|
786
|
+
args: ["ptr", "u64"],
|
|
787
|
+
returns: "ptr"
|
|
788
|
+
},
|
|
789
|
+
runtime_prepare_paths: {
|
|
790
|
+
args: ["ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
|
|
791
|
+
returns: "ptr"
|
|
792
|
+
},
|
|
793
|
+
runtime_link_dependency_layer: {
|
|
794
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
795
|
+
returns: "ptr"
|
|
796
|
+
},
|
|
797
|
+
runtime_scan_worktrees: {
|
|
798
|
+
args: ["ptr", "u64"],
|
|
799
|
+
returns: "ptr"
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
} catch {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// packages/runtime/src/control-plane/native/utils.ts
|
|
808
|
+
function resolveMonorepoRoot2(projectRoot) {
|
|
809
|
+
return resolveMonorepoRoot(projectRoot);
|
|
810
|
+
}
|
|
811
|
+
var scopeRegexCache = new Map;
|
|
812
|
+
function resolveHarnessPaths(projectRoot) {
|
|
813
|
+
const hasRuntimeWorkspace = Boolean(process.env.RIG_TASK_WORKSPACE?.trim());
|
|
814
|
+
const monorepoRoot = resolveMonorepoRoot2(projectRoot);
|
|
815
|
+
const harnessRoot = resolve6(projectRoot, "rig");
|
|
816
|
+
const stateRoot = resolve6(projectRoot, ".rig");
|
|
817
|
+
const layout = hasRuntimeWorkspace ? resolveRigLayout(projectRoot) : null;
|
|
818
|
+
const stateDir = layout?.stateDir ?? resolve6(stateRoot, "state");
|
|
819
|
+
const logsDir = layout?.logsDir ?? resolve6(stateRoot, "logs");
|
|
820
|
+
const artifactsDir = layout?.artifactsRoot ?? resolve6(monorepoRoot, "artifacts");
|
|
821
|
+
const taskConfigPath = layout?.taskConfigPath ?? resolve6(monorepoRoot, ".rig", "task-config.json");
|
|
822
|
+
const binDir = layout?.binDir ?? resolve6(stateRoot, "bin");
|
|
823
|
+
return {
|
|
824
|
+
harnessRoot,
|
|
825
|
+
stateDir: process.env.RIG_STATE_DIR || stateDir,
|
|
826
|
+
artifactsDir,
|
|
827
|
+
logsDir: process.env.RIG_LOGS_DIR || logsDir,
|
|
828
|
+
binDir,
|
|
829
|
+
hooksDir: resolve6(harnessRoot, "hooks"),
|
|
830
|
+
validationDir: resolve6(harnessRoot, "validation"),
|
|
831
|
+
taskConfigPath,
|
|
832
|
+
sessionPath: process.env.RIG_SESSION_FILE || resolve6(stateRoot, "session", "session.json"),
|
|
833
|
+
monorepoRoot,
|
|
834
|
+
tsApiTestsDir: process.env.TS_API_TESTS_DIR || resolve6(monorepoRoot, "TSAPITests"),
|
|
835
|
+
taskRepoCommitsPath: resolve6(stateDir, "task-repo-commits.json"),
|
|
836
|
+
baseRepoPinsPath: resolve6(stateDir, "base-repo-pins.json"),
|
|
837
|
+
failedApproachesPath: resolve6(stateDir, "failed_approaches.md"),
|
|
838
|
+
agentProfilePath: resolve6(stateDir, "agent-profile.json"),
|
|
839
|
+
reviewProfilePath: resolve6(stateDir, "review-profile.json")
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
// packages/runtime/src/control-plane/native/validator-binaries.ts
|
|
844
|
+
function resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext) {
|
|
845
|
+
if (runtimeContext) {
|
|
846
|
+
return resolve7(runtimeContext.binDir, "validators", binaryName);
|
|
847
|
+
}
|
|
848
|
+
return resolve7(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
|
|
849
|
+
}
|
|
850
|
+
async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
|
|
851
|
+
const match = checkId.match(/^([a-z][\w-]*):([a-z][\w-]*)$/);
|
|
852
|
+
if (!match) {
|
|
853
|
+
return null;
|
|
854
|
+
}
|
|
855
|
+
const category = match[1];
|
|
856
|
+
const check = match[2];
|
|
857
|
+
if (!category || !check) {
|
|
858
|
+
return null;
|
|
859
|
+
}
|
|
860
|
+
const binaryName = `${category}-${check}`;
|
|
861
|
+
const binaryPath = resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
|
|
862
|
+
const hostProjectRoot = runtimeContext?.hostProjectRoot?.trim() || projectRoot;
|
|
863
|
+
const sourcePath = resolve7(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
|
|
864
|
+
if (!existsSync5(sourcePath)) {
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
const sourceMtime = statSync2(sourcePath).mtimeMs;
|
|
868
|
+
const binaryExists = existsSync5(binaryPath);
|
|
869
|
+
const binaryMtime = binaryExists ? statSync2(binaryPath).mtimeMs : 0;
|
|
870
|
+
if (!binaryExists || sourceMtime > binaryMtime) {
|
|
871
|
+
if (binaryExists) {
|
|
872
|
+
rmSync3(binaryPath, { force: true });
|
|
873
|
+
rmSync3(`${binaryPath}.build-manifest.json`, { force: true });
|
|
874
|
+
}
|
|
875
|
+
mkdirSync3(dirname4(binaryPath), { recursive: true });
|
|
876
|
+
await buildRuntimeBinary({
|
|
877
|
+
sourcePath: `packages/runtime/src/control-plane/validators/${category}/${check}.ts`,
|
|
878
|
+
outputPath: binaryPath,
|
|
879
|
+
cwd: hostProjectRoot,
|
|
880
|
+
define: { AGENT_BUN_PATH: resolveBunBinaryPath() },
|
|
881
|
+
env: runtimeProvisioningEnv()
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
return existsSync5(binaryPath) ? binaryPath : null;
|
|
885
|
+
}
|
|
886
|
+
export {
|
|
887
|
+
resolveValidatorBinaryPath,
|
|
888
|
+
ensureValidatorBinary
|
|
889
|
+
};
|