@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,1892 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
3
|
+
import {
|
|
4
|
+
existsSync as existsSync11,
|
|
5
|
+
lstatSync,
|
|
6
|
+
mkdirSync as mkdirSync7,
|
|
7
|
+
readdirSync as readdirSync2,
|
|
8
|
+
readFileSync as readFileSync2,
|
|
9
|
+
rmSync as rmSync7,
|
|
10
|
+
statSync as statSync4,
|
|
11
|
+
symlinkSync as symlinkSync4
|
|
12
|
+
} from "fs";
|
|
13
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
14
|
+
import { dirname as dirname8, resolve as resolve12 } from "path";
|
|
15
|
+
|
|
16
|
+
// packages/runtime/src/binary-run.ts
|
|
17
|
+
import { chmodSync, cpSync, existsSync as existsSync2, mkdirSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
18
|
+
import { basename as basename2, dirname as dirname2, resolve as resolve2 } from "path";
|
|
19
|
+
import { fileURLToPath } from "url";
|
|
20
|
+
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
21
|
+
|
|
22
|
+
// packages/runtime/src/layout.ts
|
|
23
|
+
import { existsSync } from "fs";
|
|
24
|
+
import { basename, dirname, resolve } from "path";
|
|
25
|
+
function resolveMonorepoRoot(projectRoot) {
|
|
26
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
27
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
28
|
+
if (explicit) {
|
|
29
|
+
const explicitRoot = resolve(explicit);
|
|
30
|
+
const explicitParent = dirname(explicitRoot);
|
|
31
|
+
if (basename(explicitParent) === ".worktrees") {
|
|
32
|
+
const owner = dirname(explicitParent);
|
|
33
|
+
const ownerHasGit = existsSync(resolve(owner, ".git"));
|
|
34
|
+
const ownerHasTaskConfig = existsSync(resolve(owner, ".rig", "task-config.json"));
|
|
35
|
+
const ownerHasRigConfig = existsSync(resolve(owner, "rig.config.ts"));
|
|
36
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
37
|
+
return owner;
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
|
|
40
|
+
}
|
|
41
|
+
if (!existsSync(resolve(explicitRoot, ".git"))) {
|
|
42
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
|
|
43
|
+
}
|
|
44
|
+
const hasTaskConfig = existsSync(resolve(explicitRoot, ".rig", "task-config.json"));
|
|
45
|
+
const hasRigConfig = existsSync(resolve(explicitRoot, "rig.config.ts"));
|
|
46
|
+
if (!hasTaskConfig && !hasRigConfig) {
|
|
47
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
|
|
48
|
+
}
|
|
49
|
+
return explicitRoot;
|
|
50
|
+
}
|
|
51
|
+
const projectParent = dirname(normalizedProjectRoot);
|
|
52
|
+
if (basename(projectParent) === ".worktrees") {
|
|
53
|
+
const worktreeOwner = dirname(projectParent);
|
|
54
|
+
const ownerHasGit = existsSync(resolve(worktreeOwner, ".git"));
|
|
55
|
+
const ownerHasTaskConfig = existsSync(resolve(worktreeOwner, ".rig", "task-config.json"));
|
|
56
|
+
const ownerHasRigConfig = existsSync(resolve(worktreeOwner, "rig.config.ts"));
|
|
57
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
58
|
+
return worktreeOwner;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return normalizedProjectRoot;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// packages/runtime/src/binary-run.ts
|
|
65
|
+
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
66
|
+
async function buildRuntimeBinary(options) {
|
|
67
|
+
return runSerializedRuntimeBinaryBuild(async () => {
|
|
68
|
+
const resolved = resolveRuntimeBinaryBuildOptions(options);
|
|
69
|
+
runBestEffortBuildGc();
|
|
70
|
+
const manifestPath = runtimeBinaryCacheManifestPath(resolved.outputPath);
|
|
71
|
+
const buildKey = createRuntimeBinaryBuildKey({
|
|
72
|
+
entrypoint: resolved.entrypoint,
|
|
73
|
+
define: resolved.define,
|
|
74
|
+
env: resolved.env
|
|
75
|
+
});
|
|
76
|
+
if (await isRuntimeBinaryBuildFresh({ outputPath: resolved.outputPath, manifestPath, buildKey })) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (shouldUseRuntimeBinaryBuildWorker()) {
|
|
80
|
+
await buildRuntimeBinaryViaWorker(resolved);
|
|
81
|
+
} else {
|
|
82
|
+
await buildRuntimeBinaryInProcess(resolved, { manifestPath, buildKey });
|
|
83
|
+
}
|
|
84
|
+
runBestEffortBuildGc();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
88
|
+
const tempBuildDir = resolve2(dirname2(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
89
|
+
const tempOutputPath = resolve2(tempBuildDir, basename2(options.outputPath));
|
|
90
|
+
mkdirSync(tempBuildDir, { recursive: true });
|
|
91
|
+
await withTemporaryEnv({
|
|
92
|
+
...options.env,
|
|
93
|
+
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
94
|
+
}, async () => withTemporaryCwd(tempBuildDir, async () => {
|
|
95
|
+
const buildResult = await Bun.build({
|
|
96
|
+
entrypoints: [options.entrypoint],
|
|
97
|
+
compile: {
|
|
98
|
+
target: currentCompileTarget(),
|
|
99
|
+
outfile: tempOutputPath
|
|
100
|
+
},
|
|
101
|
+
target: "bun",
|
|
102
|
+
format: "esm",
|
|
103
|
+
minify: true,
|
|
104
|
+
bytecode: true,
|
|
105
|
+
metafile: true,
|
|
106
|
+
define: options.define ? {
|
|
107
|
+
__RIG_BUILD_CONFIG__: JSON.stringify(options.define)
|
|
108
|
+
} : undefined
|
|
109
|
+
});
|
|
110
|
+
if (!buildResult.success) {
|
|
111
|
+
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(`
|
|
112
|
+
`);
|
|
113
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
114
|
+
}
|
|
115
|
+
if (!existsSync2(tempOutputPath)) {
|
|
116
|
+
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
117
|
+
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
118
|
+
}
|
|
119
|
+
renameSync(tempOutputPath, options.outputPath);
|
|
120
|
+
chmodSync(options.outputPath, 493);
|
|
121
|
+
if (manifest) {
|
|
122
|
+
await writeRuntimeBinaryCacheManifest({
|
|
123
|
+
manifestPath: manifest.manifestPath,
|
|
124
|
+
buildKey: manifest.buildKey,
|
|
125
|
+
cwd: tempBuildDir,
|
|
126
|
+
metafile: buildResult.metafile
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
})).finally(() => {
|
|
130
|
+
rmSync(tempBuildDir, { recursive: true, force: true });
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function runBestEffortBuildGc() {
|
|
134
|
+
try {
|
|
135
|
+
drainMicrotasks();
|
|
136
|
+
} catch {}
|
|
137
|
+
try {
|
|
138
|
+
gcAndSweep();
|
|
139
|
+
} catch {}
|
|
140
|
+
}
|
|
141
|
+
function runtimeBinaryCacheManifestPath(outputPath) {
|
|
142
|
+
return `${outputPath}.build-manifest.json`;
|
|
143
|
+
}
|
|
144
|
+
function resolveRuntimeBinaryBuildOptions(options) {
|
|
145
|
+
return {
|
|
146
|
+
...options,
|
|
147
|
+
entrypoint: resolve2(options.cwd, options.sourcePath),
|
|
148
|
+
outputPath: resolve2(options.outputPath)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function shouldUseRuntimeBinaryBuildWorker() {
|
|
152
|
+
if (process.env.RIG_RUNTIME_BUILD_WORKER === "1") {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
if (process.env.RIG_RUNTIME_BUILD_IN_PROCESS === "1") {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
async function buildRuntimeBinaryViaWorker(options) {
|
|
161
|
+
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
162
|
+
if (!workerSourcePath || !existsSync2(workerSourcePath)) {
|
|
163
|
+
await buildRuntimeBinaryInProcess(options, {
|
|
164
|
+
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
165
|
+
buildKey: createRuntimeBinaryBuildKey({
|
|
166
|
+
entrypoint: options.entrypoint,
|
|
167
|
+
define: options.define,
|
|
168
|
+
env: options.env
|
|
169
|
+
})
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const payloadPath = createRuntimeBinaryBuildWorkerPayloadPath(options.outputPath);
|
|
174
|
+
const bunCli = resolveRuntimeBinaryBuildWorkerInvocation();
|
|
175
|
+
await Bun.write(payloadPath, `${JSON.stringify(options)}
|
|
176
|
+
`);
|
|
177
|
+
const build = Bun.spawn([bunCli.command, workerSourcePath, payloadPath], {
|
|
178
|
+
cwd: options.cwd,
|
|
179
|
+
stdout: "pipe",
|
|
180
|
+
stderr: "pipe",
|
|
181
|
+
env: {
|
|
182
|
+
...process.env,
|
|
183
|
+
...options.env,
|
|
184
|
+
...bunCli.env,
|
|
185
|
+
RIG_RUNTIME_BUILD_WORKER: "1"
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
189
|
+
build.exited,
|
|
190
|
+
new Response(build.stdout).text(),
|
|
191
|
+
new Response(build.stderr).text()
|
|
192
|
+
]);
|
|
193
|
+
rmSync(payloadPath, { force: true });
|
|
194
|
+
if (exitCode !== 0) {
|
|
195
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
199
|
+
return resolve2(dirname2(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
200
|
+
}
|
|
201
|
+
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
202
|
+
const envRoots = [
|
|
203
|
+
options.cwd?.trim(),
|
|
204
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
205
|
+
process.env.PROJECT_RIG_ROOT?.trim()
|
|
206
|
+
].filter(Boolean);
|
|
207
|
+
for (const root of envRoots) {
|
|
208
|
+
const candidate = resolve2(root, "packages/runtime/src/binary-build-worker.ts");
|
|
209
|
+
if (existsSync2(candidate)) {
|
|
210
|
+
return candidate;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const localCandidate = resolve2(import.meta.dir, "binary-build-worker.ts");
|
|
214
|
+
return existsSync2(localCandidate) ? localCandidate : null;
|
|
215
|
+
}
|
|
216
|
+
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
217
|
+
const bunPath = Bun.which("bun");
|
|
218
|
+
if (bunPath) {
|
|
219
|
+
return { command: bunPath, env: {} };
|
|
220
|
+
}
|
|
221
|
+
if (process.execPath?.trim()) {
|
|
222
|
+
return {
|
|
223
|
+
command: process.execPath,
|
|
224
|
+
env: { BUN_BE_BUN: "1" }
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
throw new Error("bun is required to run the runtime binary build worker.");
|
|
228
|
+
}
|
|
229
|
+
function currentCompileTarget() {
|
|
230
|
+
if (process.platform === "darwin") {
|
|
231
|
+
return process.arch === "arm64" ? "bun-darwin-arm64" : "bun-darwin-x64";
|
|
232
|
+
}
|
|
233
|
+
if (process.platform === "linux") {
|
|
234
|
+
return process.arch === "arm64" ? "bun-linux-arm64" : "bun-linux-x64";
|
|
235
|
+
}
|
|
236
|
+
return "bun-windows-x64";
|
|
237
|
+
}
|
|
238
|
+
function createRuntimeBinaryBuildKey(input) {
|
|
239
|
+
return JSON.stringify({
|
|
240
|
+
version: 1,
|
|
241
|
+
bunVersion: Bun.version,
|
|
242
|
+
platform: process.platform,
|
|
243
|
+
arch: process.arch,
|
|
244
|
+
entrypoint: input.entrypoint,
|
|
245
|
+
define: sortRecord(input.define),
|
|
246
|
+
env: sortRecord(input.env)
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async function isRuntimeBinaryBuildFresh(input) {
|
|
250
|
+
if (!existsSync2(input.outputPath) || !existsSync2(input.manifestPath)) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
let manifest = null;
|
|
254
|
+
try {
|
|
255
|
+
manifest = await Bun.file(input.manifestPath).json();
|
|
256
|
+
} catch {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
if (!manifest || manifest.version !== 1 || manifest.buildKey !== input.buildKey) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
263
|
+
if (!existsSync2(filePath)) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
if (await sha256File(filePath) !== expectedDigest) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
async function writeRuntimeBinaryCacheManifest(input) {
|
|
273
|
+
const inputs = {};
|
|
274
|
+
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
275
|
+
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
276
|
+
if (!normalized || !existsSync2(normalized)) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
inputs[normalized] = await sha256File(normalized);
|
|
280
|
+
}
|
|
281
|
+
const manifest = {
|
|
282
|
+
version: 1,
|
|
283
|
+
buildKey: input.buildKey,
|
|
284
|
+
inputs
|
|
285
|
+
};
|
|
286
|
+
await Bun.write(input.manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
287
|
+
`);
|
|
288
|
+
}
|
|
289
|
+
function normalizeBuildInputPath(cwd, inputPath) {
|
|
290
|
+
if (!inputPath) {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
if (inputPath.startsWith("file://")) {
|
|
294
|
+
return fileURLToPath(inputPath);
|
|
295
|
+
}
|
|
296
|
+
if (inputPath.startsWith("<")) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
return resolve2(cwd, inputPath);
|
|
300
|
+
}
|
|
301
|
+
async function sha256File(path) {
|
|
302
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
303
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
304
|
+
return hasher.digest("hex");
|
|
305
|
+
}
|
|
306
|
+
function sortRecord(value) {
|
|
307
|
+
if (!value) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
|
|
311
|
+
}
|
|
312
|
+
async function runSerializedRuntimeBinaryBuild(action) {
|
|
313
|
+
const previous = runtimeBinaryBuildQueue;
|
|
314
|
+
let release;
|
|
315
|
+
runtimeBinaryBuildQueue = new Promise((resolve3) => {
|
|
316
|
+
release = resolve3;
|
|
317
|
+
});
|
|
318
|
+
await previous;
|
|
319
|
+
try {
|
|
320
|
+
return await action();
|
|
321
|
+
} finally {
|
|
322
|
+
release();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async function withTemporaryEnv(env, action) {
|
|
326
|
+
if (!env) {
|
|
327
|
+
return action();
|
|
328
|
+
}
|
|
329
|
+
const previousValues = new Map;
|
|
330
|
+
for (const [key, value] of Object.entries(env)) {
|
|
331
|
+
previousValues.set(key, process.env[key]);
|
|
332
|
+
if (value === undefined) {
|
|
333
|
+
delete process.env[key];
|
|
334
|
+
} else {
|
|
335
|
+
process.env[key] = value;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
return await action();
|
|
340
|
+
} finally {
|
|
341
|
+
for (const [key, value] of previousValues.entries()) {
|
|
342
|
+
if (value === undefined) {
|
|
343
|
+
delete process.env[key];
|
|
344
|
+
} else {
|
|
345
|
+
process.env[key] = value;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function withTemporaryCwd(cwd, action) {
|
|
351
|
+
const previousCwd = process.cwd();
|
|
352
|
+
process.chdir(cwd);
|
|
353
|
+
try {
|
|
354
|
+
return await action();
|
|
355
|
+
} finally {
|
|
356
|
+
process.chdir(previousCwd);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// packages/runtime/src/control-plane/native/git-native.ts
|
|
361
|
+
import { chmodSync as chmodSync2, copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
362
|
+
import { tmpdir } from "os";
|
|
363
|
+
import { dirname as dirname3, isAbsolute, resolve as resolve3 } from "path";
|
|
364
|
+
var sharedGitNativeOutputDir = resolve3(tmpdir(), "rig-native");
|
|
365
|
+
var sharedGitNativeOutputPath = resolve3(sharedGitNativeOutputDir, `rig-git-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
366
|
+
var trackerCommandUsageProbe = "usage: rig-git fetch-ref <repo-path> <remote> <branch>";
|
|
367
|
+
function temporaryGitBinaryOutputPath(outputPath) {
|
|
368
|
+
const suffix = process.platform === "win32" ? ".exe" : "";
|
|
369
|
+
return resolve3(dirname3(outputPath), `.rig-git-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}${suffix}`);
|
|
370
|
+
}
|
|
371
|
+
function publishGitBinary(tempOutputPath, outputPath) {
|
|
372
|
+
try {
|
|
373
|
+
renameSync2(tempOutputPath, outputPath);
|
|
374
|
+
} catch (error) {
|
|
375
|
+
if (process.platform === "win32" && existsSync3(outputPath)) {
|
|
376
|
+
rmSync2(outputPath, { force: true });
|
|
377
|
+
renameSync2(tempOutputPath, outputPath);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function runtimeRigGitFileName() {
|
|
384
|
+
return `rig-git${process.platform === "win32" ? ".exe" : ""}`;
|
|
385
|
+
}
|
|
386
|
+
function rigGitSourceCandidates() {
|
|
387
|
+
const execDir = process.execPath?.trim() ? dirname3(process.execPath.trim()) : "";
|
|
388
|
+
const cwd = process.cwd()?.trim() || "";
|
|
389
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
390
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
391
|
+
const moduleRelativeSource = resolve3(import.meta.dir, "../../../native/rig-git.zig");
|
|
392
|
+
return [...new Set([
|
|
393
|
+
process.env.RIG_NATIVE_GIT_SOURCE?.trim() || "",
|
|
394
|
+
moduleRelativeSource,
|
|
395
|
+
projectRoot ? resolve3(projectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
396
|
+
hostProjectRoot ? resolve3(hostProjectRoot, "packages/runtime/native/rig-git.zig") : "",
|
|
397
|
+
cwd ? resolve3(cwd, "packages/runtime/native/rig-git.zig") : "",
|
|
398
|
+
execDir ? resolve3(execDir, "..", "..", "packages/runtime/native/rig-git.zig") : "",
|
|
399
|
+
execDir ? resolve3(execDir, "..", "native", "rig-git.zig") : ""
|
|
400
|
+
].filter(Boolean))];
|
|
401
|
+
}
|
|
402
|
+
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
403
|
+
const candidates = [];
|
|
404
|
+
let cursor = resolve3(fromDir);
|
|
405
|
+
for (let index = 0;index < 8; index += 1) {
|
|
406
|
+
candidates.push(resolve3(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve3(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve3(cursor, "native", fileName), resolve3(cursor, "native", "bin", fileName));
|
|
407
|
+
const parent = dirname3(cursor);
|
|
408
|
+
if (parent === cursor)
|
|
409
|
+
break;
|
|
410
|
+
cursor = parent;
|
|
411
|
+
}
|
|
412
|
+
return candidates;
|
|
413
|
+
}
|
|
414
|
+
function rigGitBinaryCandidates() {
|
|
415
|
+
const execDir = process.execPath?.trim() ? dirname3(process.execPath.trim()) : "";
|
|
416
|
+
const fileName = runtimeRigGitFileName();
|
|
417
|
+
const explicit = process.env.RIG_NATIVE_GIT_BIN?.trim() || "";
|
|
418
|
+
return [...new Set([
|
|
419
|
+
explicit,
|
|
420
|
+
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
421
|
+
execDir ? resolve3(execDir, fileName) : "",
|
|
422
|
+
execDir ? resolve3(execDir, "..", fileName) : "",
|
|
423
|
+
execDir ? resolve3(execDir, "..", "bin", fileName) : "",
|
|
424
|
+
sharedGitNativeOutputPath
|
|
425
|
+
].filter(Boolean))];
|
|
426
|
+
}
|
|
427
|
+
function resolveGitSourcePath() {
|
|
428
|
+
for (const candidate of rigGitSourceCandidates()) {
|
|
429
|
+
if (candidate && existsSync3(candidate)) {
|
|
430
|
+
return candidate;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
function resolveGitBinaryPath() {
|
|
436
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
for (const candidate of rigGitBinaryCandidates()) {
|
|
440
|
+
if (candidate && existsSync3(candidate)) {
|
|
441
|
+
return candidate;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
function binarySupportsTrackerCommandsSync(binaryPath) {
|
|
447
|
+
try {
|
|
448
|
+
const probe = Bun.spawnSync([binaryPath, "fetch-ref", "."], {
|
|
449
|
+
stdout: "pipe",
|
|
450
|
+
stderr: "pipe"
|
|
451
|
+
});
|
|
452
|
+
const stdout = probe.stdout.toString().trim();
|
|
453
|
+
const stderr = probe.stderr.toString().trim();
|
|
454
|
+
if (stdout.includes('"error":"unknown command"')) {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
return probe.exitCode === 2 && stderr.includes(trackerCommandUsageProbe);
|
|
458
|
+
} catch {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function nativeBuildManifestPath(outputPath) {
|
|
463
|
+
return `${outputPath}.build-manifest.json`;
|
|
464
|
+
}
|
|
465
|
+
async function hasMatchingNativeBuildManifest(manifestPath, buildKey) {
|
|
466
|
+
if (!existsSync3(manifestPath)) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
try {
|
|
470
|
+
const manifest = await Bun.file(manifestPath).json();
|
|
471
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
472
|
+
} catch {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
async function sha256File2(path) {
|
|
477
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
478
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
479
|
+
return hasher.digest("hex");
|
|
480
|
+
}
|
|
481
|
+
async function ensureRigGitBinaryPath(outputPath = sharedGitNativeOutputPath) {
|
|
482
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
483
|
+
throw new Error("Zig native git is disabled via RIG_DISABLE_ZIG_NATIVE=1");
|
|
484
|
+
}
|
|
485
|
+
const sourcePath = resolveGitSourcePath();
|
|
486
|
+
if (!sourcePath) {
|
|
487
|
+
const binaryPath = resolveGitBinaryPath();
|
|
488
|
+
if (binaryPath) {
|
|
489
|
+
return binaryPath;
|
|
490
|
+
}
|
|
491
|
+
throw new Error("rig-git.zig source file not found.");
|
|
492
|
+
}
|
|
493
|
+
const zigBinary = Bun.which("zig");
|
|
494
|
+
if (!zigBinary) {
|
|
495
|
+
throw new Error("zig is required to build native Rig git tools.");
|
|
496
|
+
}
|
|
497
|
+
mkdirSync2(dirname3(outputPath), { recursive: true });
|
|
498
|
+
const sourceDigest = await sha256File2(sourcePath);
|
|
499
|
+
const buildKey = JSON.stringify({
|
|
500
|
+
version: 1,
|
|
501
|
+
zigBinary,
|
|
502
|
+
platform: process.platform,
|
|
503
|
+
arch: process.arch,
|
|
504
|
+
sourcePath,
|
|
505
|
+
sourceDigest
|
|
506
|
+
});
|
|
507
|
+
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
508
|
+
const needsBuild = !existsSync3(outputPath) || !await hasMatchingNativeBuildManifest(manifestPath, buildKey) || !binarySupportsTrackerCommandsSync(outputPath);
|
|
509
|
+
if (!needsBuild) {
|
|
510
|
+
chmodSync2(outputPath, 493);
|
|
511
|
+
return outputPath;
|
|
512
|
+
}
|
|
513
|
+
const tempOutputPath = temporaryGitBinaryOutputPath(outputPath);
|
|
514
|
+
const build = Bun.spawn([
|
|
515
|
+
zigBinary,
|
|
516
|
+
"build-exe",
|
|
517
|
+
sourcePath,
|
|
518
|
+
"-O",
|
|
519
|
+
"ReleaseFast",
|
|
520
|
+
`-femit-bin=${tempOutputPath}`
|
|
521
|
+
], {
|
|
522
|
+
cwd: dirname3(sourcePath),
|
|
523
|
+
stdout: "pipe",
|
|
524
|
+
stderr: "pipe"
|
|
525
|
+
});
|
|
526
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
527
|
+
build.exited,
|
|
528
|
+
new Response(build.stdout).text(),
|
|
529
|
+
new Response(build.stderr).text()
|
|
530
|
+
]);
|
|
531
|
+
if (exitCode !== 0 || !existsSync3(tempOutputPath)) {
|
|
532
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
533
|
+
`);
|
|
534
|
+
throw new Error(`Failed to build native Rig git tools: ${details || `zig exited with code ${exitCode}`}`);
|
|
535
|
+
}
|
|
536
|
+
chmodSync2(tempOutputPath, 493);
|
|
537
|
+
if (existsSync3(outputPath) && await hasMatchingNativeBuildManifest(manifestPath, buildKey)) {
|
|
538
|
+
rmSync2(tempOutputPath, { force: true });
|
|
539
|
+
chmodSync2(outputPath, 493);
|
|
540
|
+
return outputPath;
|
|
541
|
+
}
|
|
542
|
+
publishGitBinary(tempOutputPath, outputPath);
|
|
543
|
+
if (!binarySupportsTrackerCommandsSync(outputPath)) {
|
|
544
|
+
rmSync2(outputPath, { force: true });
|
|
545
|
+
throw new Error("Failed to build native Rig git tools: tracker command probe failed");
|
|
546
|
+
}
|
|
547
|
+
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
548
|
+
`);
|
|
549
|
+
return outputPath;
|
|
550
|
+
}
|
|
551
|
+
async function materializeRigGitBinary(targetDir) {
|
|
552
|
+
const sourcePath = await ensureRigGitBinaryPath();
|
|
553
|
+
const targetPath = resolve3(targetDir, runtimeRigGitFileName());
|
|
554
|
+
mkdirSync2(targetDir, { recursive: true });
|
|
555
|
+
const sourceDigest = await sha256File2(sourcePath);
|
|
556
|
+
const buildKey = JSON.stringify({
|
|
557
|
+
version: 1,
|
|
558
|
+
sourcePath,
|
|
559
|
+
sourceDigest
|
|
560
|
+
});
|
|
561
|
+
const needsCopy = !existsSync3(targetPath) || !await hasMatchingNativeBuildManifest(nativeBuildManifestPath(targetPath), buildKey);
|
|
562
|
+
if (needsCopy) {
|
|
563
|
+
copyFileSync(sourcePath, targetPath);
|
|
564
|
+
chmodSync2(targetPath, 493);
|
|
565
|
+
await Bun.write(nativeBuildManifestPath(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
566
|
+
`);
|
|
567
|
+
}
|
|
568
|
+
return targetPath;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// packages/runtime/src/control-plane/native/runtime-native.ts
|
|
572
|
+
import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
|
|
573
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync4, mkdirSync as mkdirSync3, renameSync as renameSync3, rmSync as rmSync3, statSync } from "fs";
|
|
574
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
575
|
+
import { dirname as dirname4, resolve as resolve4 } from "path";
|
|
576
|
+
var sharedNativeRuntimeOutputDir = resolve4(tmpdir2(), "rig-native");
|
|
577
|
+
var sharedNativeRuntimeOutputPath = resolve4(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
|
|
578
|
+
var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
|
|
579
|
+
var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
|
|
580
|
+
function runtimePrepareTrackedPathsNative(input) {
|
|
581
|
+
const response = runNativeRuntimeSidecar({
|
|
582
|
+
op: "prepare-paths",
|
|
583
|
+
input
|
|
584
|
+
});
|
|
585
|
+
if (!response.ok) {
|
|
586
|
+
throw new Error(response.error);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
function runtimeLinkDependencyLayerNative(sourceDir, targetDir) {
|
|
590
|
+
const response = runNativeRuntimeSidecar({
|
|
591
|
+
op: "link-dependency-layer",
|
|
592
|
+
input: { sourceDir, targetDir }
|
|
593
|
+
});
|
|
594
|
+
if (!response.ok) {
|
|
595
|
+
throw new Error(response.error);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOutputPath, options = {}) {
|
|
599
|
+
if (await buildNativeRuntimeLibrary(outputPath, options)) {
|
|
600
|
+
return outputPath;
|
|
601
|
+
}
|
|
602
|
+
return !options.force && existsSync4(outputPath) ? outputPath : null;
|
|
603
|
+
}
|
|
604
|
+
async function materializeNativeRuntimeLibrary(targetDir) {
|
|
605
|
+
const sourcePath = await ensureNativeRuntimeLibraryPath();
|
|
606
|
+
if (!sourcePath) {
|
|
607
|
+
return null;
|
|
608
|
+
}
|
|
609
|
+
const targetPath = resolve4(targetDir, colocatedNativeRuntimeFileName);
|
|
610
|
+
mkdirSync3(targetDir, { recursive: true });
|
|
611
|
+
const needsCopy = !existsSync4(targetPath) || statSync(sourcePath).mtimeMs > statSync(targetPath).mtimeMs;
|
|
612
|
+
if (needsCopy) {
|
|
613
|
+
copyFileSync2(sourcePath, targetPath);
|
|
614
|
+
}
|
|
615
|
+
return targetPath;
|
|
616
|
+
}
|
|
617
|
+
async function loadNativeRuntimeLibrary() {
|
|
618
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
for (const candidate of nativeRuntimeLibraryCandidates()) {
|
|
622
|
+
if (!candidate || !existsSync4(candidate)) {
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
const loaded = tryDlopenNativeRuntimeLibrary(candidate);
|
|
626
|
+
if (loaded) {
|
|
627
|
+
return loaded;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
const builtLibraryPath = await ensureNativeRuntimeLibraryPath(sharedNativeRuntimeOutputPath, { force: true });
|
|
631
|
+
if (!builtLibraryPath) {
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
return tryDlopenNativeRuntimeLibrary(builtLibraryPath);
|
|
635
|
+
}
|
|
636
|
+
function nativePackageLibraryCandidates(fromDir, names) {
|
|
637
|
+
const candidates = [];
|
|
638
|
+
let cursor = resolve4(fromDir);
|
|
639
|
+
for (let index = 0;index < 8; index += 1) {
|
|
640
|
+
for (const name of names) {
|
|
641
|
+
candidates.push(resolve4(cursor, "native", `${process.platform}-${process.arch}`, name), resolve4(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve4(cursor, "native", name), resolve4(cursor, "native", "lib", name));
|
|
642
|
+
}
|
|
643
|
+
const parent = dirname4(cursor);
|
|
644
|
+
if (parent === cursor)
|
|
645
|
+
break;
|
|
646
|
+
cursor = parent;
|
|
647
|
+
}
|
|
648
|
+
return candidates;
|
|
649
|
+
}
|
|
650
|
+
function nativeRuntimeLibraryCandidates() {
|
|
651
|
+
const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
|
|
652
|
+
const execDir = process.execPath?.trim() ? dirname4(process.execPath.trim()) : "";
|
|
653
|
+
const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
|
|
654
|
+
return [...new Set([
|
|
655
|
+
explicit,
|
|
656
|
+
...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
|
|
657
|
+
execDir ? resolve4(execDir, colocatedNativeRuntimeFileName) : "",
|
|
658
|
+
execDir ? resolve4(execDir, platformSpecific) : "",
|
|
659
|
+
execDir ? resolve4(execDir, "..", colocatedNativeRuntimeFileName) : "",
|
|
660
|
+
execDir ? resolve4(execDir, "..", platformSpecific) : "",
|
|
661
|
+
execDir ? resolve4(execDir, "lib", colocatedNativeRuntimeFileName) : "",
|
|
662
|
+
execDir ? resolve4(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
|
|
663
|
+
sharedNativeRuntimeOutputPath
|
|
664
|
+
].filter(Boolean))];
|
|
665
|
+
}
|
|
666
|
+
function resolveNativeRuntimeSourcePath() {
|
|
667
|
+
const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
|
|
668
|
+
if (explicit && existsSync4(explicit)) {
|
|
669
|
+
return explicit;
|
|
670
|
+
}
|
|
671
|
+
const bundled = resolve4(import.meta.dir, "../../../native/snapshot.zig");
|
|
672
|
+
return existsSync4(bundled) ? bundled : null;
|
|
673
|
+
}
|
|
674
|
+
function resolveNativeRuntimeSidecarSourcePath() {
|
|
675
|
+
const envRoots = [
|
|
676
|
+
process.cwd()?.trim(),
|
|
677
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
678
|
+
process.env.PROJECT_RIG_ROOT?.trim()
|
|
679
|
+
].filter(Boolean);
|
|
680
|
+
for (const root of envRoots) {
|
|
681
|
+
for (const relative of [
|
|
682
|
+
"packages/runtime/src/control-plane/native/runtime-native-sidecar.ts",
|
|
683
|
+
"packages/runtime/dist/src/control-plane/native/runtime-native-sidecar.js"
|
|
684
|
+
]) {
|
|
685
|
+
const candidate = resolve4(root, relative);
|
|
686
|
+
if (existsSync4(candidate)) {
|
|
687
|
+
return candidate;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
for (const localCandidate of [
|
|
692
|
+
resolve4(import.meta.dir, "runtime-native-sidecar.js"),
|
|
693
|
+
resolve4(import.meta.dir, "runtime-native-sidecar.ts")
|
|
694
|
+
]) {
|
|
695
|
+
if (existsSync4(localCandidate))
|
|
696
|
+
return localCandidate;
|
|
697
|
+
}
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
async function buildNativeRuntimeLibrary(outputPath, options = {}) {
|
|
701
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
702
|
+
return false;
|
|
703
|
+
}
|
|
704
|
+
const zigBinary = Bun.which("zig");
|
|
705
|
+
const sourcePath = resolveNativeRuntimeSourcePath();
|
|
706
|
+
if (!zigBinary || !sourcePath) {
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
710
|
+
try {
|
|
711
|
+
mkdirSync3(dirname4(outputPath), { recursive: true });
|
|
712
|
+
const needsBuild = options.force === true || !existsSync4(outputPath) || statSync(sourcePath).mtimeMs > statSync(outputPath).mtimeMs;
|
|
713
|
+
if (!needsBuild) {
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
const build = Bun.spawn([
|
|
717
|
+
zigBinary,
|
|
718
|
+
"build-lib",
|
|
719
|
+
sourcePath,
|
|
720
|
+
"-dynamic",
|
|
721
|
+
"-O",
|
|
722
|
+
"ReleaseFast",
|
|
723
|
+
`-femit-bin=${tempOutputPath}`
|
|
724
|
+
], {
|
|
725
|
+
cwd: import.meta.dir,
|
|
726
|
+
stdout: "pipe",
|
|
727
|
+
stderr: "pipe"
|
|
728
|
+
});
|
|
729
|
+
const exitCode = await build.exited;
|
|
730
|
+
if (exitCode !== 0 || !existsSync4(tempOutputPath)) {
|
|
731
|
+
rmSync3(tempOutputPath, { force: true });
|
|
732
|
+
return false;
|
|
733
|
+
}
|
|
734
|
+
renameSync3(tempOutputPath, outputPath);
|
|
735
|
+
return true;
|
|
736
|
+
} catch {
|
|
737
|
+
rmSync3(tempOutputPath, { force: true });
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
function tryDlopenNativeRuntimeLibrary(outputPath) {
|
|
742
|
+
try {
|
|
743
|
+
return dlopen(outputPath, {
|
|
744
|
+
rig_scope_match: {
|
|
745
|
+
args: ["ptr", "ptr"],
|
|
746
|
+
returns: "u8"
|
|
747
|
+
},
|
|
748
|
+
snapshot_capture: {
|
|
749
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
750
|
+
returns: "ptr"
|
|
751
|
+
},
|
|
752
|
+
snapshot_delta: {
|
|
753
|
+
args: ["ptr", "ptr"],
|
|
754
|
+
returns: "ptr"
|
|
755
|
+
},
|
|
756
|
+
snapshot_store_delta: {
|
|
757
|
+
args: ["ptr", "ptr", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
|
|
758
|
+
returns: "ptr"
|
|
759
|
+
},
|
|
760
|
+
snapshot_inspect_delta: {
|
|
761
|
+
args: ["ptr", "u64"],
|
|
762
|
+
returns: "ptr"
|
|
763
|
+
},
|
|
764
|
+
snapshot_apply_delta: {
|
|
765
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
766
|
+
returns: "ptr"
|
|
767
|
+
},
|
|
768
|
+
snapshot_release: {
|
|
769
|
+
args: ["ptr"],
|
|
770
|
+
returns: "void"
|
|
771
|
+
},
|
|
772
|
+
runtime_hash_file: {
|
|
773
|
+
args: ["ptr", "u64"],
|
|
774
|
+
returns: "ptr"
|
|
775
|
+
},
|
|
776
|
+
runtime_hash_tree: {
|
|
777
|
+
args: ["ptr", "u64"],
|
|
778
|
+
returns: "ptr"
|
|
779
|
+
},
|
|
780
|
+
runtime_prepare_paths: {
|
|
781
|
+
args: ["ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
|
|
782
|
+
returns: "ptr"
|
|
783
|
+
},
|
|
784
|
+
runtime_link_dependency_layer: {
|
|
785
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
786
|
+
returns: "ptr"
|
|
787
|
+
},
|
|
788
|
+
runtime_scan_worktrees: {
|
|
789
|
+
args: ["ptr", "u64"],
|
|
790
|
+
returns: "ptr"
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
} catch {
|
|
794
|
+
return null;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
function runNativeRuntimeSidecar(request) {
|
|
798
|
+
const sidecarSourcePath = resolveNativeRuntimeSidecarSourcePath();
|
|
799
|
+
if (!sidecarSourcePath) {
|
|
800
|
+
throw new Error("runtime-native-sidecar.ts source file not found.");
|
|
801
|
+
}
|
|
802
|
+
const bunCli = resolveNativeRuntimeSidecarInvocation();
|
|
803
|
+
const proc = Bun.spawnSync([bunCli.command, sidecarSourcePath, JSON.stringify(request)], {
|
|
804
|
+
cwd: process.env.RIG_HOST_PROJECT_ROOT?.trim() || process.cwd(),
|
|
805
|
+
stdout: "pipe",
|
|
806
|
+
stderr: "pipe",
|
|
807
|
+
env: {
|
|
808
|
+
...process.env,
|
|
809
|
+
...bunCli.env,
|
|
810
|
+
RIG_NATIVE_RUNTIME_SIDECAR: "1"
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
if (proc.exitCode !== 0) {
|
|
814
|
+
throw new Error(proc.stderr.toString() || proc.stdout.toString() || `runtime native sidecar exited ${proc.exitCode}`);
|
|
815
|
+
}
|
|
816
|
+
const stdout = proc.stdout.toString().trim();
|
|
817
|
+
if (!stdout) {
|
|
818
|
+
throw new Error("runtime native sidecar returned empty output.");
|
|
819
|
+
}
|
|
820
|
+
return JSON.parse(stdout);
|
|
821
|
+
}
|
|
822
|
+
function resolveNativeRuntimeSidecarInvocation() {
|
|
823
|
+
const bunPath = Bun.which("bun");
|
|
824
|
+
if (bunPath) {
|
|
825
|
+
return { command: bunPath, env: {} };
|
|
826
|
+
}
|
|
827
|
+
if (process.execPath?.trim()) {
|
|
828
|
+
return {
|
|
829
|
+
command: process.execPath,
|
|
830
|
+
env: { BUN_BE_BUN: "1" }
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
throw new Error("bun is required to run the runtime native sidecar.");
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
837
|
+
import { delimiter, resolve as resolve6 } from "path";
|
|
838
|
+
|
|
839
|
+
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
840
|
+
import { existsSync as existsSync5, readdirSync, realpathSync } from "fs";
|
|
841
|
+
import { resolve as resolve5 } from "path";
|
|
842
|
+
|
|
843
|
+
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
844
|
+
function uniq(values) {
|
|
845
|
+
return [...new Set(values)];
|
|
846
|
+
}
|
|
847
|
+
// packages/runtime/src/control-plane/runtime/runtime-paths.ts
|
|
848
|
+
function resolveBunBinaryPath() {
|
|
849
|
+
const explicit = normalizeExecutablePath(process.env.RIG_BUN_PATH?.trim());
|
|
850
|
+
if (explicit) {
|
|
851
|
+
return explicit;
|
|
852
|
+
}
|
|
853
|
+
const pathBun = normalizeExecutablePath(Bun.which("bun")?.trim());
|
|
854
|
+
if (pathBun && !looksLikeRuntimeGateway(pathBun)) {
|
|
855
|
+
return pathBun;
|
|
856
|
+
}
|
|
857
|
+
const home = process.env.HOME?.trim();
|
|
858
|
+
const fallbackCandidates = [
|
|
859
|
+
home ? resolve5(home, ".bun/bin/bun") : "",
|
|
860
|
+
"/opt/homebrew/bin/bun",
|
|
861
|
+
"/usr/local/bin/bun",
|
|
862
|
+
"/usr/bin/bun"
|
|
863
|
+
];
|
|
864
|
+
for (const candidate of fallbackCandidates) {
|
|
865
|
+
const normalized = normalizeExecutablePath(candidate);
|
|
866
|
+
if (normalized) {
|
|
867
|
+
return normalized;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
const execPath = normalizeExecutablePath(process.execPath?.trim());
|
|
871
|
+
if (execPath && !looksLikeRuntimeGateway(execPath)) {
|
|
872
|
+
return execPath;
|
|
873
|
+
}
|
|
874
|
+
throw new Error("bun not found in PATH");
|
|
875
|
+
}
|
|
876
|
+
function resolveClaudeBinaryPath() {
|
|
877
|
+
const explicit = normalizeExecutablePath(process.env.RIG_CLAUDE_PATH?.trim());
|
|
878
|
+
if (explicit) {
|
|
879
|
+
return explicit;
|
|
880
|
+
}
|
|
881
|
+
const pathClaude = normalizeExecutablePath(Bun.which("claude")?.trim());
|
|
882
|
+
if (pathClaude && !looksLikeRuntimeGateway(pathClaude)) {
|
|
883
|
+
return pathClaude;
|
|
884
|
+
}
|
|
885
|
+
const home = process.env.HOME?.trim();
|
|
886
|
+
const fallbackCandidates = [
|
|
887
|
+
home ? resolve5(home, ".local/bin/claude") : "",
|
|
888
|
+
home ? resolve5(home, ".local/share/claude/local/claude") : "",
|
|
889
|
+
"/opt/homebrew/bin/claude",
|
|
890
|
+
"/usr/local/bin/claude",
|
|
891
|
+
"/usr/bin/claude"
|
|
892
|
+
];
|
|
893
|
+
for (const candidate of fallbackCandidates) {
|
|
894
|
+
const normalized = normalizeExecutablePath(candidate);
|
|
895
|
+
if (normalized) {
|
|
896
|
+
return normalized;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
throw new Error("claude not found in PATH");
|
|
900
|
+
}
|
|
901
|
+
function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
|
|
902
|
+
return resolve5(bunBinaryPath, "../..");
|
|
903
|
+
}
|
|
904
|
+
function resolveClaudeInstallDir() {
|
|
905
|
+
const realPath = resolveClaudeBinaryPath();
|
|
906
|
+
return resolve5(realPath, "..");
|
|
907
|
+
}
|
|
908
|
+
function resolveNodeInstallDir() {
|
|
909
|
+
const preferredNode = resolvePreferredNodeBinary();
|
|
910
|
+
if (!preferredNode)
|
|
911
|
+
return null;
|
|
912
|
+
const explicitNode = process.env.RIG_NODE_BIN?.trim();
|
|
913
|
+
if (explicitNode && resolve5(explicitNode) === resolve5(preferredNode)) {
|
|
914
|
+
return preferredNode.endsWith("/bin/node") ? resolve5(preferredNode, "../..") : resolve5(preferredNode, "..");
|
|
915
|
+
}
|
|
916
|
+
try {
|
|
917
|
+
const realPath = realpathSync(preferredNode);
|
|
918
|
+
if (realPath.endsWith("/bin/node")) {
|
|
919
|
+
return resolve5(realPath, "../..");
|
|
920
|
+
}
|
|
921
|
+
return resolve5(realPath, "..");
|
|
922
|
+
} catch {
|
|
923
|
+
return resolve5(preferredNode, "..");
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
function resolvePreferredNodeBinary() {
|
|
927
|
+
const candidates = [];
|
|
928
|
+
const envNode = process.env.RIG_NODE_BIN?.trim();
|
|
929
|
+
if (envNode) {
|
|
930
|
+
const explicit = resolve5(envNode);
|
|
931
|
+
if (existsSync5(explicit)) {
|
|
932
|
+
return explicit;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
const nvmBin = process.env.NVM_BIN?.trim();
|
|
936
|
+
if (nvmBin) {
|
|
937
|
+
candidates.push(resolve5(nvmBin, "node"));
|
|
938
|
+
}
|
|
939
|
+
const home = process.env.HOME?.trim();
|
|
940
|
+
if (home) {
|
|
941
|
+
const nvmVersionsDir = resolve5(home, ".nvm/versions/node");
|
|
942
|
+
if (existsSync5(nvmVersionsDir)) {
|
|
943
|
+
try {
|
|
944
|
+
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/, "")));
|
|
945
|
+
for (const versionDir of versionDirs) {
|
|
946
|
+
candidates.push(resolve5(nvmVersionsDir, versionDir, "bin/node"));
|
|
947
|
+
}
|
|
948
|
+
} catch {}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
const whichNode = Bun.which("node");
|
|
952
|
+
if (whichNode) {
|
|
953
|
+
candidates.push(whichNode);
|
|
954
|
+
}
|
|
955
|
+
const deduped = uniq(candidates.map((candidate) => resolve5(candidate)));
|
|
956
|
+
const existing = deduped.filter((candidate) => existsSync5(candidate));
|
|
957
|
+
if (existing.length === 0) {
|
|
958
|
+
return null;
|
|
959
|
+
}
|
|
960
|
+
const stable = existing.find((candidate) => {
|
|
961
|
+
const major = inferNodeMajor(candidate);
|
|
962
|
+
return typeof major === "number" && major >= 18 && major <= 24;
|
|
963
|
+
});
|
|
964
|
+
if (stable) {
|
|
965
|
+
return stable;
|
|
966
|
+
}
|
|
967
|
+
return existing[0] ?? null;
|
|
968
|
+
}
|
|
969
|
+
function inferNodeMajor(nodeBinaryPath) {
|
|
970
|
+
const normalized = resolve5(nodeBinaryPath).replace(/\\/g, "/");
|
|
971
|
+
const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
|
|
972
|
+
if (!match) {
|
|
973
|
+
return null;
|
|
974
|
+
}
|
|
975
|
+
const major = Number.parseInt(match[1], 10);
|
|
976
|
+
return Number.isFinite(major) ? major : null;
|
|
977
|
+
}
|
|
978
|
+
function normalizeExecutablePath(candidate) {
|
|
979
|
+
if (!candidate) {
|
|
980
|
+
return "";
|
|
981
|
+
}
|
|
982
|
+
const normalized = resolve5(candidate);
|
|
983
|
+
if (!existsSync5(normalized)) {
|
|
984
|
+
return "";
|
|
985
|
+
}
|
|
986
|
+
try {
|
|
987
|
+
return realpathSync(normalized);
|
|
988
|
+
} catch {
|
|
989
|
+
return normalized;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
function looksLikeRuntimeGateway(candidate) {
|
|
993
|
+
const normalized = resolve5(candidate).replace(/\\/g, "/");
|
|
994
|
+
return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// packages/runtime/src/control-plane/runtime/provisioning-env.ts
|
|
998
|
+
function runtimeProvisioningEnv(baseEnv = process.env) {
|
|
999
|
+
const env = { ...baseEnv };
|
|
1000
|
+
const realBash = baseEnv.RIG_REAL_BASH?.trim() || "/bin/bash";
|
|
1001
|
+
const bunBinary = baseEnv.RIG_BUN_PATH?.trim() || resolveBunBinaryPath();
|
|
1002
|
+
const bunDir = resolveBunInstallDir(bunBinary);
|
|
1003
|
+
const claudeBinary = baseEnv.RIG_CLAUDE_PATH?.trim() || (() => {
|
|
1004
|
+
try {
|
|
1005
|
+
return resolveClaudeBinaryPath();
|
|
1006
|
+
} catch {
|
|
1007
|
+
return "";
|
|
1008
|
+
}
|
|
1009
|
+
})();
|
|
1010
|
+
const claudeDir = claudeBinary ? (() => {
|
|
1011
|
+
try {
|
|
1012
|
+
return resolveClaudeInstallDir();
|
|
1013
|
+
} catch {
|
|
1014
|
+
return resolve6(claudeBinary, "..");
|
|
1015
|
+
}
|
|
1016
|
+
})() : "";
|
|
1017
|
+
const nodeDir = resolveNodeInstallDir();
|
|
1018
|
+
const realHome = baseEnv.HOME?.trim();
|
|
1019
|
+
const inheritedPath = (baseEnv.PATH ?? "").split(delimiter).map((entry) => entry.trim()).filter(Boolean).filter((entry) => !entry.endsWith("/.rig/bin") && !entry.endsWith("/rig/tools"));
|
|
1020
|
+
const pathEntries = [
|
|
1021
|
+
`${bunDir}/bin`,
|
|
1022
|
+
claudeDir,
|
|
1023
|
+
nodeDir ? `${nodeDir}/bin` : "",
|
|
1024
|
+
realHome ? resolve6(realHome, ".local/bin") : "",
|
|
1025
|
+
realHome ? resolve6(realHome, ".cargo/bin") : "",
|
|
1026
|
+
...inheritedPath,
|
|
1027
|
+
"/usr/local/bin",
|
|
1028
|
+
"/usr/local/sbin",
|
|
1029
|
+
"/opt/homebrew/bin",
|
|
1030
|
+
"/opt/homebrew/sbin",
|
|
1031
|
+
"/usr/bin",
|
|
1032
|
+
"/bin",
|
|
1033
|
+
"/usr/sbin",
|
|
1034
|
+
"/sbin"
|
|
1035
|
+
].filter(Boolean);
|
|
1036
|
+
env.BASH = realBash;
|
|
1037
|
+
env.SHELL = baseEnv.SHELL?.trim() || realBash;
|
|
1038
|
+
env.PATH = [...new Set(pathEntries)].join(delimiter);
|
|
1039
|
+
env.RIG_BUN_PATH = bunBinary;
|
|
1040
|
+
if (claudeBinary) {
|
|
1041
|
+
env.RIG_CLAUDE_PATH = claudeBinary;
|
|
1042
|
+
}
|
|
1043
|
+
env.PYTHON = env.PYTHON?.trim() || "python3";
|
|
1044
|
+
const nodeGypPath = Bun.which("node-gyp");
|
|
1045
|
+
if (nodeGypPath) {
|
|
1046
|
+
env.npm_config_node_gyp = nodeGypPath;
|
|
1047
|
+
}
|
|
1048
|
+
delete env.RIG_BASH_ACTIVE;
|
|
1049
|
+
delete env.RIG_BASH_MODE;
|
|
1050
|
+
return env;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// packages/runtime/src/control-plane/runtime/tooling/gateway.ts
|
|
1054
|
+
import { existsSync as existsSync9, rmSync as rmSync6, symlinkSync as symlinkSync3 } from "fs";
|
|
1055
|
+
import { resolve as resolve10 } from "path";
|
|
1056
|
+
|
|
1057
|
+
// packages/runtime/src/control-plane/runtime/tooling/shell.ts
|
|
1058
|
+
import { chmodSync as chmodSync3, copyFileSync as copyFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
|
|
1059
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
1060
|
+
import { basename as basename3, dirname as dirname5, resolve as resolve7 } from "path";
|
|
1061
|
+
var sharedNativeShellOutputDir = resolve7(tmpdir3(), "rig-native");
|
|
1062
|
+
var sharedNativeShellOutputPath = resolve7(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1063
|
+
function runtimeRigShellFileName() {
|
|
1064
|
+
return `rig-shell${process.platform === "win32" ? ".exe" : ""}`;
|
|
1065
|
+
}
|
|
1066
|
+
async function ensureRigShellBinaryPath(outputPath = sharedNativeShellOutputPath) {
|
|
1067
|
+
const sourcePath = resolveRigShellSourcePath();
|
|
1068
|
+
if (!sourcePath) {
|
|
1069
|
+
const bundledBinary = resolveBundledRigShellBinaryPath();
|
|
1070
|
+
if (bundledBinary) {
|
|
1071
|
+
return bundledBinary;
|
|
1072
|
+
}
|
|
1073
|
+
throw new Error("rig-shell.zig source file not found.");
|
|
1074
|
+
}
|
|
1075
|
+
const zigBinary = Bun.which("zig");
|
|
1076
|
+
if (!zigBinary) {
|
|
1077
|
+
throw new Error("zig is required to build the native Rig shell.");
|
|
1078
|
+
}
|
|
1079
|
+
mkdirSync4(dirname5(outputPath), { recursive: true });
|
|
1080
|
+
const sourceDigest = await sha256File3(sourcePath);
|
|
1081
|
+
const buildKey = JSON.stringify({
|
|
1082
|
+
version: 1,
|
|
1083
|
+
zigBinary,
|
|
1084
|
+
platform: process.platform,
|
|
1085
|
+
arch: process.arch,
|
|
1086
|
+
sourcePath,
|
|
1087
|
+
sourceDigest
|
|
1088
|
+
});
|
|
1089
|
+
const manifestPath = nativeBuildManifestPath2(outputPath);
|
|
1090
|
+
const needsBuild = !existsSync6(outputPath) || !await hasMatchingNativeBuildManifest2(manifestPath, buildKey);
|
|
1091
|
+
if (!needsBuild) {
|
|
1092
|
+
return outputPath;
|
|
1093
|
+
}
|
|
1094
|
+
const build = Bun.spawn([
|
|
1095
|
+
zigBinary,
|
|
1096
|
+
"build-exe",
|
|
1097
|
+
sourcePath,
|
|
1098
|
+
"-O",
|
|
1099
|
+
"ReleaseFast",
|
|
1100
|
+
`-femit-bin=${outputPath}`
|
|
1101
|
+
], {
|
|
1102
|
+
cwd: dirname5(sourcePath),
|
|
1103
|
+
stdout: "pipe",
|
|
1104
|
+
stderr: "pipe"
|
|
1105
|
+
});
|
|
1106
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
1107
|
+
build.exited,
|
|
1108
|
+
new Response(build.stdout).text(),
|
|
1109
|
+
new Response(build.stderr).text()
|
|
1110
|
+
]);
|
|
1111
|
+
if (exitCode !== 0 || !existsSync6(outputPath)) {
|
|
1112
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
1113
|
+
`);
|
|
1114
|
+
throw new Error(`Failed to build native Rig shell: ${details || `zig exited with code ${exitCode}`}`);
|
|
1115
|
+
}
|
|
1116
|
+
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
1117
|
+
`);
|
|
1118
|
+
return outputPath;
|
|
1119
|
+
}
|
|
1120
|
+
async function materializeRigShellBinary(targetDir) {
|
|
1121
|
+
const sourcePath = await ensureRigShellBinaryPath();
|
|
1122
|
+
const targetPath = resolve7(targetDir, runtimeRigShellFileName());
|
|
1123
|
+
mkdirSync4(targetDir, { recursive: true });
|
|
1124
|
+
const sourceDigest = await sha256File3(sourcePath);
|
|
1125
|
+
const buildKey = JSON.stringify({
|
|
1126
|
+
version: 1,
|
|
1127
|
+
sourcePath,
|
|
1128
|
+
sourceDigest
|
|
1129
|
+
});
|
|
1130
|
+
const needsCopy = !existsSync6(targetPath) || !await hasMatchingNativeBuildManifest2(nativeBuildManifestPath2(targetPath), buildKey);
|
|
1131
|
+
if (needsCopy) {
|
|
1132
|
+
copyFileSync3(sourcePath, targetPath);
|
|
1133
|
+
chmodSync3(targetPath, 493);
|
|
1134
|
+
await Bun.write(nativeBuildManifestPath2(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
1135
|
+
`);
|
|
1136
|
+
}
|
|
1137
|
+
return targetPath;
|
|
1138
|
+
}
|
|
1139
|
+
function resolveRigShellSourcePath() {
|
|
1140
|
+
for (const candidate of rigShellSourceCandidates()) {
|
|
1141
|
+
if (candidate && existsSync6(candidate)) {
|
|
1142
|
+
return candidate;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
return null;
|
|
1146
|
+
}
|
|
1147
|
+
function resolveBundledRigShellBinaryPath() {
|
|
1148
|
+
for (const candidate of rigShellBinaryCandidates()) {
|
|
1149
|
+
if (candidate && existsSync6(candidate)) {
|
|
1150
|
+
return candidate;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
return null;
|
|
1154
|
+
}
|
|
1155
|
+
function rigShellSourceCandidates() {
|
|
1156
|
+
const execDir = process.execPath?.trim() ? dirname5(process.execPath.trim()) : "";
|
|
1157
|
+
const cwd = process.cwd()?.trim() || "";
|
|
1158
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
1159
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
1160
|
+
return [...new Set([
|
|
1161
|
+
process.env.RIG_NATIVE_SHELL_SOURCE?.trim() || "",
|
|
1162
|
+
cwd ? resolve7(cwd, "packages/runtime/native/rig-shell.zig") : "",
|
|
1163
|
+
projectRoot ? resolve7(projectRoot, "packages/runtime/native/rig-shell.zig") : "",
|
|
1164
|
+
hostProjectRoot ? resolve7(hostProjectRoot, "packages/runtime/native/rig-shell.zig") : "",
|
|
1165
|
+
execDir ? resolve7(execDir, "..", "..", "packages/runtime/native/rig-shell.zig") : "",
|
|
1166
|
+
execDir ? resolve7(execDir, "..", "native", "rig-shell.zig") : "",
|
|
1167
|
+
resolve7(import.meta.dir, "../../../../native/rig-shell.zig")
|
|
1168
|
+
].filter(Boolean))];
|
|
1169
|
+
}
|
|
1170
|
+
function nativePackageBinaryCandidates2(fromDir, fileName) {
|
|
1171
|
+
const candidates = [];
|
|
1172
|
+
let cursor = resolve7(fromDir);
|
|
1173
|
+
for (let index = 0;index < 8; index += 1) {
|
|
1174
|
+
candidates.push(resolve7(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve7(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve7(cursor, "native", fileName), resolve7(cursor, "native", "bin", fileName));
|
|
1175
|
+
const parent = dirname5(cursor);
|
|
1176
|
+
if (parent === cursor)
|
|
1177
|
+
break;
|
|
1178
|
+
cursor = parent;
|
|
1179
|
+
}
|
|
1180
|
+
return candidates;
|
|
1181
|
+
}
|
|
1182
|
+
function rigShellBinaryCandidates() {
|
|
1183
|
+
const execDir = process.execPath?.trim() ? dirname5(process.execPath.trim()) : "";
|
|
1184
|
+
const fileName = runtimeRigShellFileName();
|
|
1185
|
+
return [...new Set([
|
|
1186
|
+
process.env.RIG_NATIVE_SHELL_BIN?.trim() || "",
|
|
1187
|
+
...nativePackageBinaryCandidates2(import.meta.dir, fileName),
|
|
1188
|
+
execDir ? resolve7(execDir, fileName) : "",
|
|
1189
|
+
execDir ? resolve7(execDir, "..", fileName) : "",
|
|
1190
|
+
execDir ? resolve7(execDir, "..", "bin", fileName) : ""
|
|
1191
|
+
].filter(Boolean))];
|
|
1192
|
+
}
|
|
1193
|
+
function runtimeToolGatewayNames() {
|
|
1194
|
+
return [
|
|
1195
|
+
"bash",
|
|
1196
|
+
"sh",
|
|
1197
|
+
"zsh",
|
|
1198
|
+
"git",
|
|
1199
|
+
"bun",
|
|
1200
|
+
"node",
|
|
1201
|
+
"python3",
|
|
1202
|
+
"rg",
|
|
1203
|
+
"grep",
|
|
1204
|
+
"sed",
|
|
1205
|
+
"cat",
|
|
1206
|
+
"ls",
|
|
1207
|
+
"find",
|
|
1208
|
+
"tsc",
|
|
1209
|
+
"gh",
|
|
1210
|
+
"mkdir",
|
|
1211
|
+
"rm",
|
|
1212
|
+
"mv",
|
|
1213
|
+
"cp",
|
|
1214
|
+
"touch",
|
|
1215
|
+
"pwd",
|
|
1216
|
+
"head",
|
|
1217
|
+
"tail",
|
|
1218
|
+
"wc",
|
|
1219
|
+
"sort",
|
|
1220
|
+
"uniq",
|
|
1221
|
+
"awk",
|
|
1222
|
+
"xargs",
|
|
1223
|
+
"dirname",
|
|
1224
|
+
"basename",
|
|
1225
|
+
"realpath",
|
|
1226
|
+
"env",
|
|
1227
|
+
"jq",
|
|
1228
|
+
"tee",
|
|
1229
|
+
"which"
|
|
1230
|
+
];
|
|
1231
|
+
}
|
|
1232
|
+
function nativeBuildManifestPath2(outputPath) {
|
|
1233
|
+
return `${outputPath}.build-manifest.json`;
|
|
1234
|
+
}
|
|
1235
|
+
async function hasMatchingNativeBuildManifest2(manifestPath, buildKey) {
|
|
1236
|
+
if (!existsSync6(manifestPath)) {
|
|
1237
|
+
return false;
|
|
1238
|
+
}
|
|
1239
|
+
try {
|
|
1240
|
+
const manifest = await Bun.file(manifestPath).json();
|
|
1241
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
1242
|
+
} catch {
|
|
1243
|
+
return false;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
async function sha256File3(path) {
|
|
1247
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
1248
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
1249
|
+
return hasher.digest("hex");
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// packages/runtime/src/control-plane/runtime/tooling/browser-tools.ts
|
|
1253
|
+
import { existsSync as existsSync7, rmSync as rmSync4, symlinkSync } from "fs";
|
|
1254
|
+
import { resolve as resolve8 } from "path";
|
|
1255
|
+
function runtimeBrowserToolBinaryName() {
|
|
1256
|
+
return `rig-browser-tool${process.platform === "win32" ? ".exe" : ""}`;
|
|
1257
|
+
}
|
|
1258
|
+
function runtimeBrowserToolNames() {
|
|
1259
|
+
return [
|
|
1260
|
+
"rig-browser-launch",
|
|
1261
|
+
"rig-browser-check",
|
|
1262
|
+
"rig-browser-attach-info",
|
|
1263
|
+
"rig-browser-e2e",
|
|
1264
|
+
"rig-browser-reset-profile"
|
|
1265
|
+
];
|
|
1266
|
+
}
|
|
1267
|
+
async function materializeRuntimeBrowserTools(targetDir) {
|
|
1268
|
+
const binaryPath = resolve8(targetDir, runtimeBrowserToolBinaryName());
|
|
1269
|
+
for (const tool of runtimeBrowserToolNames()) {
|
|
1270
|
+
const toolPath = resolve8(targetDir, tool);
|
|
1271
|
+
if (existsSync7(toolPath)) {
|
|
1272
|
+
rmSync4(toolPath, { force: true, recursive: true });
|
|
1273
|
+
}
|
|
1274
|
+
symlinkSync(binaryPath, toolPath);
|
|
1275
|
+
}
|
|
1276
|
+
return binaryPath;
|
|
1277
|
+
}
|
|
1278
|
+
// packages/runtime/src/control-plane/runtime/tooling/file-tools.ts
|
|
1279
|
+
import { chmodSync as chmodSync4, copyFileSync as copyFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync5, rmSync as rmSync5, symlinkSync as symlinkSync2 } from "fs";
|
|
1280
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
1281
|
+
import { basename as basename4, dirname as dirname6, resolve as resolve9 } from "path";
|
|
1282
|
+
var sharedNativeToolsOutputDir = resolve9(tmpdir4(), "rig-native");
|
|
1283
|
+
var sharedNativeToolsOutputPath = resolve9(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1284
|
+
function runtimeRigToolsFileName() {
|
|
1285
|
+
return `rig-tools${process.platform === "win32" ? ".exe" : ""}`;
|
|
1286
|
+
}
|
|
1287
|
+
function runtimeFileToolNames() {
|
|
1288
|
+
return [
|
|
1289
|
+
"rig-read",
|
|
1290
|
+
"rig-write",
|
|
1291
|
+
"rig-edit",
|
|
1292
|
+
"rig-glob",
|
|
1293
|
+
"rig-grep"
|
|
1294
|
+
];
|
|
1295
|
+
}
|
|
1296
|
+
async function ensureRigToolsBinaryPath(outputPath = sharedNativeToolsOutputPath) {
|
|
1297
|
+
const sourcePath = resolveRigToolsSourcePath();
|
|
1298
|
+
if (!sourcePath) {
|
|
1299
|
+
const bundledBinary = resolveBundledRigToolsBinaryPath();
|
|
1300
|
+
if (bundledBinary) {
|
|
1301
|
+
return bundledBinary;
|
|
1302
|
+
}
|
|
1303
|
+
throw new Error("rig-tools.zig source file not found.");
|
|
1304
|
+
}
|
|
1305
|
+
const zigBinary = Bun.which("zig");
|
|
1306
|
+
if (!zigBinary) {
|
|
1307
|
+
throw new Error("zig is required to build native Rig file tools.");
|
|
1308
|
+
}
|
|
1309
|
+
mkdirSync5(dirname6(outputPath), { recursive: true });
|
|
1310
|
+
const sourceDigest = await sha256File4(sourcePath);
|
|
1311
|
+
const buildKey = JSON.stringify({
|
|
1312
|
+
version: 1,
|
|
1313
|
+
zigBinary,
|
|
1314
|
+
platform: process.platform,
|
|
1315
|
+
arch: process.arch,
|
|
1316
|
+
sourcePath,
|
|
1317
|
+
sourceDigest
|
|
1318
|
+
});
|
|
1319
|
+
const manifestPath = nativeBuildManifestPath3(outputPath);
|
|
1320
|
+
const needsBuild = !existsSync8(outputPath) || !await hasMatchingNativeBuildManifest3(manifestPath, buildKey);
|
|
1321
|
+
if (!needsBuild) {
|
|
1322
|
+
return outputPath;
|
|
1323
|
+
}
|
|
1324
|
+
const build = Bun.spawn([
|
|
1325
|
+
zigBinary,
|
|
1326
|
+
"build-exe",
|
|
1327
|
+
sourcePath,
|
|
1328
|
+
"-O",
|
|
1329
|
+
"ReleaseFast",
|
|
1330
|
+
`-femit-bin=${outputPath}`
|
|
1331
|
+
], {
|
|
1332
|
+
cwd: dirname6(sourcePath),
|
|
1333
|
+
stdout: "pipe",
|
|
1334
|
+
stderr: "pipe"
|
|
1335
|
+
});
|
|
1336
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
1337
|
+
build.exited,
|
|
1338
|
+
new Response(build.stdout).text(),
|
|
1339
|
+
new Response(build.stderr).text()
|
|
1340
|
+
]);
|
|
1341
|
+
if (exitCode !== 0 || !existsSync8(outputPath)) {
|
|
1342
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
1343
|
+
`);
|
|
1344
|
+
throw new Error(`Failed to build native Rig file tools: ${details || `zig exited with code ${exitCode}`}`);
|
|
1345
|
+
}
|
|
1346
|
+
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
1347
|
+
`);
|
|
1348
|
+
return outputPath;
|
|
1349
|
+
}
|
|
1350
|
+
async function materializeRuntimeFileTools(targetDir) {
|
|
1351
|
+
const sourcePath = await ensureRigToolsBinaryPath();
|
|
1352
|
+
const targetPath = resolve9(targetDir, runtimeRigToolsFileName());
|
|
1353
|
+
mkdirSync5(targetDir, { recursive: true });
|
|
1354
|
+
const sourceDigest = await sha256File4(sourcePath);
|
|
1355
|
+
const buildKey = JSON.stringify({
|
|
1356
|
+
version: 1,
|
|
1357
|
+
sourcePath,
|
|
1358
|
+
sourceDigest
|
|
1359
|
+
});
|
|
1360
|
+
const needsCopy = !existsSync8(targetPath) || !await hasMatchingNativeBuildManifest3(nativeBuildManifestPath3(targetPath), buildKey);
|
|
1361
|
+
if (needsCopy) {
|
|
1362
|
+
copyFileSync4(sourcePath, targetPath);
|
|
1363
|
+
chmodSync4(targetPath, 493);
|
|
1364
|
+
await Bun.write(nativeBuildManifestPath3(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
1365
|
+
`);
|
|
1366
|
+
}
|
|
1367
|
+
for (const tool of runtimeFileToolNames()) {
|
|
1368
|
+
const toolPath = resolve9(targetDir, tool);
|
|
1369
|
+
if (existsSync8(toolPath)) {
|
|
1370
|
+
rmSync5(toolPath, { force: true, recursive: true });
|
|
1371
|
+
}
|
|
1372
|
+
symlinkSync2(targetPath, toolPath);
|
|
1373
|
+
}
|
|
1374
|
+
return targetPath;
|
|
1375
|
+
}
|
|
1376
|
+
function resolveRigToolsSourcePath() {
|
|
1377
|
+
for (const candidate of rigToolsSourceCandidates()) {
|
|
1378
|
+
if (candidate && existsSync8(candidate)) {
|
|
1379
|
+
return candidate;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
return null;
|
|
1383
|
+
}
|
|
1384
|
+
function resolveBundledRigToolsBinaryPath() {
|
|
1385
|
+
for (const candidate of rigToolsBinaryCandidates()) {
|
|
1386
|
+
if (candidate && existsSync8(candidate)) {
|
|
1387
|
+
return candidate;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return null;
|
|
1391
|
+
}
|
|
1392
|
+
function rigToolsSourceCandidates() {
|
|
1393
|
+
const execDir = process.execPath?.trim() ? dirname6(process.execPath.trim()) : "";
|
|
1394
|
+
const cwd = process.cwd()?.trim() || "";
|
|
1395
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
1396
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
1397
|
+
return [...new Set([
|
|
1398
|
+
process.env.RIG_NATIVE_TOOLS_SOURCE?.trim() || "",
|
|
1399
|
+
cwd ? resolve9(cwd, "packages/runtime/native/rig-tools.zig") : "",
|
|
1400
|
+
projectRoot ? resolve9(projectRoot, "packages/runtime/native/rig-tools.zig") : "",
|
|
1401
|
+
hostProjectRoot ? resolve9(hostProjectRoot, "packages/runtime/native/rig-tools.zig") : "",
|
|
1402
|
+
execDir ? resolve9(execDir, "..", "..", "packages/runtime/native/rig-tools.zig") : "",
|
|
1403
|
+
execDir ? resolve9(execDir, "..", "native", "rig-tools.zig") : "",
|
|
1404
|
+
resolve9(import.meta.dir, "../../../../native/rig-tools.zig")
|
|
1405
|
+
].filter(Boolean))];
|
|
1406
|
+
}
|
|
1407
|
+
function nativePackageBinaryCandidates3(fromDir, fileName) {
|
|
1408
|
+
const candidates = [];
|
|
1409
|
+
let cursor = resolve9(fromDir);
|
|
1410
|
+
for (let index = 0;index < 8; index += 1) {
|
|
1411
|
+
candidates.push(resolve9(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve9(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve9(cursor, "native", fileName), resolve9(cursor, "native", "bin", fileName));
|
|
1412
|
+
const parent = dirname6(cursor);
|
|
1413
|
+
if (parent === cursor)
|
|
1414
|
+
break;
|
|
1415
|
+
cursor = parent;
|
|
1416
|
+
}
|
|
1417
|
+
return candidates;
|
|
1418
|
+
}
|
|
1419
|
+
function rigToolsBinaryCandidates() {
|
|
1420
|
+
const execDir = process.execPath?.trim() ? dirname6(process.execPath.trim()) : "";
|
|
1421
|
+
const fileName = runtimeRigToolsFileName();
|
|
1422
|
+
return [...new Set([
|
|
1423
|
+
process.env.RIG_NATIVE_TOOLS_BIN?.trim() || "",
|
|
1424
|
+
...nativePackageBinaryCandidates3(import.meta.dir, fileName),
|
|
1425
|
+
execDir ? resolve9(execDir, fileName) : "",
|
|
1426
|
+
execDir ? resolve9(execDir, "..", fileName) : "",
|
|
1427
|
+
execDir ? resolve9(execDir, "..", "bin", fileName) : ""
|
|
1428
|
+
].filter(Boolean))];
|
|
1429
|
+
}
|
|
1430
|
+
function nativeBuildManifestPath3(outputPath) {
|
|
1431
|
+
return `${outputPath}.build-manifest.json`;
|
|
1432
|
+
}
|
|
1433
|
+
async function hasMatchingNativeBuildManifest3(manifestPath, buildKey) {
|
|
1434
|
+
if (!existsSync8(manifestPath)) {
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
try {
|
|
1438
|
+
const manifest = await Bun.file(manifestPath).json();
|
|
1439
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
1440
|
+
} catch {
|
|
1441
|
+
return false;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
async function sha256File4(path) {
|
|
1445
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
1446
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
1447
|
+
return hasher.digest("hex");
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
// packages/runtime/src/control-plane/runtime/tooling/gateway.ts
|
|
1451
|
+
function runtimeGatewayToolNames() {
|
|
1452
|
+
return runtimeToolGatewayNames();
|
|
1453
|
+
}
|
|
1454
|
+
async function materializeRuntimeToolGateway(binDir) {
|
|
1455
|
+
const shellPath = await materializeRigShellBinary(binDir);
|
|
1456
|
+
for (const tool of runtimeGatewayToolNames()) {
|
|
1457
|
+
const toolPath = resolve10(binDir, tool);
|
|
1458
|
+
if (existsSync9(toolPath)) {
|
|
1459
|
+
rmSync6(toolPath, { force: true, recursive: true });
|
|
1460
|
+
}
|
|
1461
|
+
symlinkSync3(shellPath, toolPath);
|
|
1462
|
+
}
|
|
1463
|
+
await materializeRuntimeBrowserTools(binDir);
|
|
1464
|
+
return resolve10(binDir, runtimeRigShellFileName());
|
|
1465
|
+
}
|
|
1466
|
+
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
1467
|
+
import { chmodSync as chmodSync5, copyFileSync as copyFileSync5, existsSync as existsSync10, mkdirSync as mkdirSync6, statSync as statSync3 } from "fs";
|
|
1468
|
+
import { tmpdir as tmpdir5 } from "os";
|
|
1469
|
+
import { dirname as dirname7, resolve as resolve11 } from "path";
|
|
1470
|
+
var sharedRouterOutputDir = resolve11(tmpdir5(), "rig-native");
|
|
1471
|
+
var sharedRouterOutputPath = resolve11(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1472
|
+
function runtimeClaudeToolRouterFileName() {
|
|
1473
|
+
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
1474
|
+
}
|
|
1475
|
+
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
1476
|
+
const sourcePath = resolve11(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
1477
|
+
mkdirSync6(dirname7(outputPath), { recursive: true });
|
|
1478
|
+
const needsBuild = !existsSync10(outputPath) || statSync3(sourcePath).mtimeMs > statSync3(outputPath).mtimeMs;
|
|
1479
|
+
if (!needsBuild) {
|
|
1480
|
+
return outputPath;
|
|
1481
|
+
}
|
|
1482
|
+
await buildRuntimeBinary({
|
|
1483
|
+
sourcePath: "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts",
|
|
1484
|
+
outputPath,
|
|
1485
|
+
cwd: projectRoot
|
|
1486
|
+
});
|
|
1487
|
+
chmodSync5(outputPath, 493);
|
|
1488
|
+
return outputPath;
|
|
1489
|
+
}
|
|
1490
|
+
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
1491
|
+
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
1492
|
+
const targetPath = resolve11(targetDir, runtimeClaudeToolRouterFileName());
|
|
1493
|
+
mkdirSync6(targetDir, { recursive: true });
|
|
1494
|
+
const needsCopy = !existsSync10(targetPath) || statSync3(sourcePath).mtimeMs > statSync3(targetPath).mtimeMs;
|
|
1495
|
+
if (needsCopy) {
|
|
1496
|
+
copyFileSync5(sourcePath, targetPath);
|
|
1497
|
+
chmodSync5(targetPath, 493);
|
|
1498
|
+
}
|
|
1499
|
+
return targetPath;
|
|
1500
|
+
}
|
|
1501
|
+
// packages/runtime/src/control-plane/native/utils.ts
|
|
1502
|
+
function resolveMonorepoRoot2(projectRoot) {
|
|
1503
|
+
return resolveMonorepoRoot(projectRoot);
|
|
1504
|
+
}
|
|
1505
|
+
var scopeRegexCache = new Map;
|
|
1506
|
+
|
|
1507
|
+
// packages/runtime/src/control-plane/runtime/isolation/shared.ts
|
|
1508
|
+
var generatedCredentialFiles = new Set;
|
|
1509
|
+
function resolveMonorepoRoot3(projectRoot) {
|
|
1510
|
+
return resolveMonorepoRoot2(projectRoot);
|
|
1511
|
+
}
|
|
1512
|
+
function sha256Hex(input) {
|
|
1513
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
1514
|
+
hasher.update(input);
|
|
1515
|
+
return hasher.digest("hex");
|
|
1516
|
+
}
|
|
1517
|
+
function taskRuntimeId(taskId) {
|
|
1518
|
+
return `task-${taskId}`;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
// packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
|
|
1522
|
+
var GIT_INDEX_LOCK_MAX_RETRIES = 20;
|
|
1523
|
+
var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
|
|
1524
|
+
var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
|
|
1525
|
+
function resolveRigSourceRoot(projectRoot) {
|
|
1526
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
|
|
1527
|
+
if (hostProjectRoot && existsSync11(resolve12(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
|
|
1528
|
+
return hostProjectRoot;
|
|
1529
|
+
}
|
|
1530
|
+
const fromModule = resolve12(import.meta.dir, "../../../../../..");
|
|
1531
|
+
if (existsSync11(resolve12(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
|
|
1532
|
+
return fromModule;
|
|
1533
|
+
}
|
|
1534
|
+
return projectRoot;
|
|
1535
|
+
}
|
|
1536
|
+
function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
|
|
1537
|
+
for (const path of [logsDir, stateDir, sessionDir, resolve12(sessionDir, "session.json")]) {
|
|
1538
|
+
removeSymbolicLink(path);
|
|
1539
|
+
}
|
|
1540
|
+
runtimePrepareTrackedPathsNative({
|
|
1541
|
+
logsDir,
|
|
1542
|
+
stateDir,
|
|
1543
|
+
sessionDir,
|
|
1544
|
+
controlledBashLogFile: resolve12(logsDir, "controlled-bash.jsonl"),
|
|
1545
|
+
eventsFile: resolve12(logsDir, "control-plane.events.jsonl")
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
|
|
1549
|
+
await mkdir(stateDir, { recursive: true });
|
|
1550
|
+
await mkdir(sessionDir, { recursive: true });
|
|
1551
|
+
const failedApproachesPath = resolve12(stateDir, "failed_approaches.md");
|
|
1552
|
+
if (!existsSync11(failedApproachesPath)) {
|
|
1553
|
+
await writeFile(failedApproachesPath, `# Failed Approaches
|
|
1554
|
+
|
|
1555
|
+
`);
|
|
1556
|
+
}
|
|
1557
|
+
const hookTripsPath = resolve12(stateDir, "hook_trips.log");
|
|
1558
|
+
if (!existsSync11(hookTripsPath)) {
|
|
1559
|
+
await writeFile(hookTripsPath, "");
|
|
1560
|
+
}
|
|
1561
|
+
const sessionFile = resolve12(sessionDir, "session.json");
|
|
1562
|
+
if (taskId) {
|
|
1563
|
+
await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
|
|
1567
|
+
const artifactDir = resolve12(workspaceDir, "artifacts", taskId);
|
|
1568
|
+
const runtimeSnapshotDir = resolve12(artifactDir, "runtime-snapshots");
|
|
1569
|
+
let preservedTrackedFiles = false;
|
|
1570
|
+
for (const file of [
|
|
1571
|
+
"changed-files.txt",
|
|
1572
|
+
"pr-state.json",
|
|
1573
|
+
"review-state.json",
|
|
1574
|
+
"review-feedback.md",
|
|
1575
|
+
"review-greptile-raw.json",
|
|
1576
|
+
"review-status.txt",
|
|
1577
|
+
"validation-summary.json"
|
|
1578
|
+
]) {
|
|
1579
|
+
const relativePath = `artifacts/${taskId}/${file}`;
|
|
1580
|
+
if (await resetTrackedArtifactPath(workspaceDir, relativePath)) {
|
|
1581
|
+
preservedTrackedFiles = true;
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1584
|
+
rmSync7(resolve12(artifactDir, file), { force: true });
|
|
1585
|
+
}
|
|
1586
|
+
const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
|
|
1587
|
+
if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
|
|
1588
|
+
preservedTrackedFiles = true;
|
|
1589
|
+
} else {
|
|
1590
|
+
rmSync7(runtimeSnapshotDir, { recursive: true, force: true });
|
|
1591
|
+
}
|
|
1592
|
+
if (preservedTrackedFiles) {
|
|
1593
|
+
console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
function prepareRuntimeWorkspace(projectRoot, workspaceDir) {
|
|
1597
|
+
const monorepoRoot = resolveMonorepoRoot3(projectRoot);
|
|
1598
|
+
linkRuntimeDependencyLayers(monorepoRoot, workspaceDir);
|
|
1599
|
+
syncRuntimeWorkspaceSources(projectRoot, workspaceDir);
|
|
1600
|
+
}
|
|
1601
|
+
async function materializeRuntimeHostToolWrappers(binDir) {
|
|
1602
|
+
await materializeRuntimeToolGateway(binDir);
|
|
1603
|
+
await materializeRuntimeFileTools(binDir);
|
|
1604
|
+
}
|
|
1605
|
+
async function buildRuntimeToolchain(options) {
|
|
1606
|
+
const hookNames = [
|
|
1607
|
+
"scope-guard",
|
|
1608
|
+
"import-guard",
|
|
1609
|
+
"safety-guard",
|
|
1610
|
+
"test-integrity-guard",
|
|
1611
|
+
"audit-trail",
|
|
1612
|
+
"post-edit-lint",
|
|
1613
|
+
"completion-verification",
|
|
1614
|
+
"inject-context",
|
|
1615
|
+
"task-runtime-start"
|
|
1616
|
+
];
|
|
1617
|
+
const runtimeBins = ensureRuntimeBinTrees(options.binDir);
|
|
1618
|
+
const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(options.binDir);
|
|
1619
|
+
if (!nativeRuntimeLibraryPath) {
|
|
1620
|
+
throw new Error("Failed to provision the native Zig runtime library.");
|
|
1621
|
+
}
|
|
1622
|
+
const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
|
|
1623
|
+
await buildBinary("packages/cli/bin/rig.ts", resolve12(options.binDir, "rig"), rigSourceRoot);
|
|
1624
|
+
await buildBinary("packages/runtime/bin/rig-agent.ts", resolve12(options.binDir, "rig-agent"), rigSourceRoot, {
|
|
1625
|
+
...options.runtimeSecretDefines,
|
|
1626
|
+
AGENT_TASK_ID: options.taskId,
|
|
1627
|
+
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
1628
|
+
AGENT_RUNTIME_ID: options.runtimeId,
|
|
1629
|
+
AGENT_SCOPE_HASH: options.bakedScopeHash,
|
|
1630
|
+
AGENT_MANIFEST_PATH: options.manifestPath,
|
|
1631
|
+
AGENT_BINARY_PATH: resolve12(options.binDir, "rig-agent"),
|
|
1632
|
+
AGENT_INFO_OUTPUT: options.bakedInfoOutput,
|
|
1633
|
+
AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
|
|
1634
|
+
AGENT_STATUS_OUTPUT: options.bakedStatusOutput
|
|
1635
|
+
});
|
|
1636
|
+
await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve12(options.binDir, "controlled-bash"), rigSourceRoot, {
|
|
1637
|
+
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
1638
|
+
AGENT_LOGS_DIR: options.logsDir,
|
|
1639
|
+
AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
|
|
1640
|
+
AGENT_TS_API_TESTS_DIR: resolve12(options.workspaceDir, "TSAPITests"),
|
|
1641
|
+
AGENT_RIG_AGENT_BIN: resolve12(options.binDir, "rig-agent")
|
|
1642
|
+
});
|
|
1643
|
+
await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve12(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
|
|
1644
|
+
await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve12(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
|
|
1645
|
+
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
1646
|
+
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
1647
|
+
});
|
|
1648
|
+
const hookDefines = {
|
|
1649
|
+
AGENT_PROJECT_ROOT: options.projectRoot,
|
|
1650
|
+
AGENT_BUN_PATH: resolveBunBinaryPath()
|
|
1651
|
+
};
|
|
1652
|
+
for (const hookName of hookNames) {
|
|
1653
|
+
await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve12(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
|
|
1654
|
+
}
|
|
1655
|
+
const pluginsDir = resolve12(options.projectRoot, "rig/plugins");
|
|
1656
|
+
if (existsSync11(pluginsDir)) {
|
|
1657
|
+
for (const entry of readdirSync2(pluginsDir, { withFileTypes: true })) {
|
|
1658
|
+
const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
|
|
1659
|
+
if (!match)
|
|
1660
|
+
continue;
|
|
1661
|
+
await buildBinary(`rig/plugins/${entry.name}`, resolve12(runtimeBins.pluginsDir, match[1]), options.projectRoot);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
await materializeRigGitBinary(options.binDir);
|
|
1665
|
+
await materializeClaudeToolRouterBinary(rigSourceRoot, options.binDir);
|
|
1666
|
+
await materializeRuntimeHostToolWrappers(options.binDir);
|
|
1667
|
+
await materializeRuntimeBrowserTools(options.binDir);
|
|
1668
|
+
}
|
|
1669
|
+
async function writeRuntimeManifest(config) {
|
|
1670
|
+
const scopeHash = sha256Hex(JSON.stringify(config.scopes));
|
|
1671
|
+
const binarySha256 = sha256Hex(readFileSync2(config.binaryPath));
|
|
1672
|
+
const manifestPath = resolve12(config.runtimeRoot, "manifest.json");
|
|
1673
|
+
const manifest = {
|
|
1674
|
+
runtimeId: config.runtimeId,
|
|
1675
|
+
taskId: config.taskId,
|
|
1676
|
+
scopeHash,
|
|
1677
|
+
builtAt: new Date().toISOString(),
|
|
1678
|
+
workspaceDir: config.workspaceDir,
|
|
1679
|
+
binDir: config.binDir,
|
|
1680
|
+
binary: {
|
|
1681
|
+
path: config.binaryPath,
|
|
1682
|
+
sha256: binarySha256
|
|
1683
|
+
}
|
|
1684
|
+
};
|
|
1685
|
+
await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
1686
|
+
`, "utf-8");
|
|
1687
|
+
}
|
|
1688
|
+
async function buildBinary(entrypoint, outputPath, cwd, defines) {
|
|
1689
|
+
await buildRuntimeBinary({
|
|
1690
|
+
sourcePath: entrypoint,
|
|
1691
|
+
outputPath,
|
|
1692
|
+
cwd,
|
|
1693
|
+
define: defines,
|
|
1694
|
+
env: runtimeProvisioningEnv()
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
function syncRuntimeWorkspaceSources(projectRoot, workspaceDir) {}
|
|
1698
|
+
function removeSymbolicLink(path) {
|
|
1699
|
+
try {
|
|
1700
|
+
if (!lstatSync(path).isSymbolicLink()) {
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
} catch {
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
rmSync7(path, { force: true, recursive: true });
|
|
1707
|
+
}
|
|
1708
|
+
async function resetTrackedArtifactPath(workspaceDir, relativePath) {
|
|
1709
|
+
const tracked = await runGitLsFiles(workspaceDir, relativePath);
|
|
1710
|
+
if (!tracked) {
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
await restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, async () => {
|
|
1714
|
+
const restore = await Bun.$`git -C ${workspaceDir} checkout -- ${relativePath}`.quiet().nothrow();
|
|
1715
|
+
return {
|
|
1716
|
+
exitCode: restore.exitCode,
|
|
1717
|
+
output: restore.stderr.toString() || restore.stdout.toString()
|
|
1718
|
+
};
|
|
1719
|
+
}, { sleep: Bun.sleep });
|
|
1720
|
+
return true;
|
|
1721
|
+
}
|
|
1722
|
+
async function runGitLsFiles(workspaceDir, relativePath) {
|
|
1723
|
+
const tracked = await Bun.$`git -C ${workspaceDir} ls-files --error-unmatch -- ${relativePath}`.quiet().nothrow();
|
|
1724
|
+
return tracked.exitCode === 0;
|
|
1725
|
+
}
|
|
1726
|
+
async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, restorePath, options = {}) {
|
|
1727
|
+
const sleep = options.sleep ?? Bun.sleep;
|
|
1728
|
+
const maxRetries = options.maxRetries ?? GIT_INDEX_LOCK_MAX_RETRIES;
|
|
1729
|
+
const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
|
|
1730
|
+
const now = options.now ?? Date.now;
|
|
1731
|
+
const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
|
|
1732
|
+
const removeFile = options.removeFile ?? ((path) => rmSync7(path, { force: true }));
|
|
1733
|
+
const log = options.log ?? console.warn;
|
|
1734
|
+
let lastOutput = "";
|
|
1735
|
+
for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
|
|
1736
|
+
const restore = await restorePath();
|
|
1737
|
+
if (restore.exitCode === 0) {
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
lastOutput = restore.output;
|
|
1741
|
+
if (!isGitIndexLockError(lastOutput)) {
|
|
1742
|
+
break;
|
|
1743
|
+
}
|
|
1744
|
+
const lockPath = parseGitIndexLockPath(lastOutput);
|
|
1745
|
+
if (attempt === maxRetries) {
|
|
1746
|
+
if (lockPath && tryClearStaleGitIndexLock(lockPath, {
|
|
1747
|
+
now,
|
|
1748
|
+
statMtimeMs,
|
|
1749
|
+
removeFile,
|
|
1750
|
+
log
|
|
1751
|
+
})) {
|
|
1752
|
+
const recovered = await restorePath();
|
|
1753
|
+
if (recovered.exitCode === 0) {
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
lastOutput = recovered.output;
|
|
1757
|
+
}
|
|
1758
|
+
break;
|
|
1759
|
+
}
|
|
1760
|
+
await sleep(retryDelayMs);
|
|
1761
|
+
}
|
|
1762
|
+
throw new Error(`Failed to restore tracked runtime artifact path ${relativePath} in ${workspaceDir}: ${lastOutput}`);
|
|
1763
|
+
}
|
|
1764
|
+
function isGitIndexLockError(output) {
|
|
1765
|
+
return /index\.lock|Unable to create '.+index\.lock'.*File exists/i.test(output);
|
|
1766
|
+
}
|
|
1767
|
+
function parseGitIndexLockPath(output) {
|
|
1768
|
+
const match = output.match(/Unable to create '([^']+index\.lock)'/i);
|
|
1769
|
+
return match?.[1] ?? null;
|
|
1770
|
+
}
|
|
1771
|
+
function tryClearStaleGitIndexLock(lockPath, options) {
|
|
1772
|
+
const mtimeMs = options.statMtimeMs(lockPath);
|
|
1773
|
+
if (mtimeMs === null) {
|
|
1774
|
+
return false;
|
|
1775
|
+
}
|
|
1776
|
+
if (options.now() - mtimeMs < GIT_INDEX_LOCK_STALE_AFTER_MS) {
|
|
1777
|
+
return false;
|
|
1778
|
+
}
|
|
1779
|
+
options.removeFile(lockPath);
|
|
1780
|
+
options.log(`[rig-agent] Cleared stale git index lock during run recovery: ${lockPath}`);
|
|
1781
|
+
return true;
|
|
1782
|
+
}
|
|
1783
|
+
function readFileMtimeMs(path) {
|
|
1784
|
+
try {
|
|
1785
|
+
return statSync4(path).mtimeMs;
|
|
1786
|
+
} catch {
|
|
1787
|
+
return null;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
|
|
1791
|
+
linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
|
|
1792
|
+
const sourceNodeModules = resolve12(monorepoRoot, "humoongate", "node_modules");
|
|
1793
|
+
if (!existsSync11(sourceNodeModules)) {} else {
|
|
1794
|
+
const runtimeHumoongate = resolve12(workspaceDir, "humoongate");
|
|
1795
|
+
if (existsSync11(resolve12(runtimeHumoongate, "package.json"))) {
|
|
1796
|
+
const targetNodeModules = resolve12(runtimeHumoongate, "node_modules");
|
|
1797
|
+
runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
const runtimeHpNext = resolve12(workspaceDir, "microservices", "hp-next-frontend", "app");
|
|
1801
|
+
if (!existsSync11(resolve12(runtimeHpNext, "package.json"))) {
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
const sourceHpNextNodeModules = resolve12(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
|
|
1805
|
+
const sourceMonorepoNodeModules = resolve12(monorepoRoot, "node_modules");
|
|
1806
|
+
const targetHpNextNodeModules = resolve12(runtimeHpNext, "node_modules");
|
|
1807
|
+
if (existsSync11(sourceHpNextNodeModules)) {
|
|
1808
|
+
runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
if (existsSync11(sourceMonorepoNodeModules)) {
|
|
1812
|
+
runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
|
|
1816
|
+
linkNodeModulesLayer(resolve12(monorepoRoot, "node_modules"), resolve12(workspaceDir, "node_modules"));
|
|
1817
|
+
for (const relativePackageDir of [
|
|
1818
|
+
"apps/native-app/apps/marketing",
|
|
1819
|
+
"apps/native-app/apps/web",
|
|
1820
|
+
"apps/native-app/apps/browser",
|
|
1821
|
+
"apps/native-app/apps/desktop",
|
|
1822
|
+
"apps/native-app/scripts",
|
|
1823
|
+
"apps/tui",
|
|
1824
|
+
"packages/cli",
|
|
1825
|
+
"packages/client",
|
|
1826
|
+
"packages/contracts",
|
|
1827
|
+
"packages/core",
|
|
1828
|
+
"packages/hook-kit",
|
|
1829
|
+
"packages/plugin-testkit",
|
|
1830
|
+
"packages/runtime",
|
|
1831
|
+
"packages/scripts",
|
|
1832
|
+
"packages/server",
|
|
1833
|
+
"packages/shared",
|
|
1834
|
+
"packages/skill-loader",
|
|
1835
|
+
"packages/standard-plugin",
|
|
1836
|
+
"packages/validator-kit"
|
|
1837
|
+
]) {
|
|
1838
|
+
const workspacePackageDir = resolve12(workspaceDir, relativePackageDir);
|
|
1839
|
+
if (!existsSync11(resolve12(workspacePackageDir, "package.json"))) {
|
|
1840
|
+
continue;
|
|
1841
|
+
}
|
|
1842
|
+
linkNodeModulesLayer(resolve12(monorepoRoot, relativePackageDir, "node_modules"), resolve12(workspacePackageDir, "node_modules"));
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
function linkNodeModulesLayer(sourceDir, targetDir) {
|
|
1846
|
+
if (!existsSync11(sourceDir) || existsSync11(targetDir)) {
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
try {
|
|
1850
|
+
runtimeLinkDependencyLayerNative(sourceDir, targetDir);
|
|
1851
|
+
return;
|
|
1852
|
+
} catch (error) {
|
|
1853
|
+
console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
|
|
1854
|
+
}
|
|
1855
|
+
mkdirSync7(dirname8(targetDir), { recursive: true });
|
|
1856
|
+
symlinkSync4(sourceDir, targetDir, "dir");
|
|
1857
|
+
}
|
|
1858
|
+
function ensureRuntimeBinTrees(runtimeBinDir) {
|
|
1859
|
+
const hooksDir = resolve12(runtimeBinDir, "hooks");
|
|
1860
|
+
const pluginsDir = resolve12(runtimeBinDir, "plugins");
|
|
1861
|
+
const validatorsDir = resolve12(runtimeBinDir, "validators");
|
|
1862
|
+
mkdirSync7(hooksDir, { recursive: true });
|
|
1863
|
+
mkdirSync7(pluginsDir, { recursive: true });
|
|
1864
|
+
mkdirSync7(validatorsDir, { recursive: true });
|
|
1865
|
+
return { hooksDir, pluginsDir, validatorsDir };
|
|
1866
|
+
}
|
|
1867
|
+
function runtimeWorktreeId(workspaceDir) {
|
|
1868
|
+
return workspaceDir.split("/").at(-1) || "runtime";
|
|
1869
|
+
}
|
|
1870
|
+
function isCanonicalTaskRuntime(taskId, runtimeId) {
|
|
1871
|
+
return runtimeId === taskRuntimeId(taskId);
|
|
1872
|
+
}
|
|
1873
|
+
var __testOnly = {
|
|
1874
|
+
isGitIndexLockError,
|
|
1875
|
+
parseGitIndexLockPath,
|
|
1876
|
+
restoreTrackedArtifactPathWithRetry,
|
|
1877
|
+
tryClearStaleGitIndexLock
|
|
1878
|
+
};
|
|
1879
|
+
export {
|
|
1880
|
+
writeRuntimeManifest,
|
|
1881
|
+
syncRuntimeWorkspaceSources,
|
|
1882
|
+
runtimeWorktreeId,
|
|
1883
|
+
resetEphemeralTaskArtifacts,
|
|
1884
|
+
prepareTrackedRuntimePaths,
|
|
1885
|
+
prepareRuntimeWorkspace,
|
|
1886
|
+
materializeRuntimeHostToolWrappers,
|
|
1887
|
+
isCanonicalTaskRuntime,
|
|
1888
|
+
initializeRuntimeStateFiles,
|
|
1889
|
+
buildRuntimeToolchain,
|
|
1890
|
+
buildBinary,
|
|
1891
|
+
__testOnly
|
|
1892
|
+
};
|