@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,1290 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/runtime/tooling/shell.ts
|
|
3
|
+
import { chmodSync, copyFileSync, existsSync, mkdirSync } from "fs";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { basename, dirname, resolve } from "path";
|
|
6
|
+
var sharedNativeShellOutputDir = resolve(tmpdir(), "rig-native");
|
|
7
|
+
var sharedNativeShellOutputPath = resolve(sharedNativeShellOutputDir, `rig-shell-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
8
|
+
function runtimeRigShellFileName() {
|
|
9
|
+
return `rig-shell${process.platform === "win32" ? ".exe" : ""}`;
|
|
10
|
+
}
|
|
11
|
+
async function ensureRigShellBinaryPath(outputPath = sharedNativeShellOutputPath) {
|
|
12
|
+
const sourcePath = resolveRigShellSourcePath();
|
|
13
|
+
if (!sourcePath) {
|
|
14
|
+
const bundledBinary = resolveBundledRigShellBinaryPath();
|
|
15
|
+
if (bundledBinary) {
|
|
16
|
+
return bundledBinary;
|
|
17
|
+
}
|
|
18
|
+
throw new Error("rig-shell.zig source file not found.");
|
|
19
|
+
}
|
|
20
|
+
const zigBinary = Bun.which("zig");
|
|
21
|
+
if (!zigBinary) {
|
|
22
|
+
throw new Error("zig is required to build the native Rig shell.");
|
|
23
|
+
}
|
|
24
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
25
|
+
const sourceDigest = await sha256File(sourcePath);
|
|
26
|
+
const buildKey = JSON.stringify({
|
|
27
|
+
version: 1,
|
|
28
|
+
zigBinary,
|
|
29
|
+
platform: process.platform,
|
|
30
|
+
arch: process.arch,
|
|
31
|
+
sourcePath,
|
|
32
|
+
sourceDigest
|
|
33
|
+
});
|
|
34
|
+
const manifestPath = nativeBuildManifestPath(outputPath);
|
|
35
|
+
const needsBuild = !existsSync(outputPath) || !await hasMatchingNativeBuildManifest(manifestPath, buildKey);
|
|
36
|
+
if (!needsBuild) {
|
|
37
|
+
return outputPath;
|
|
38
|
+
}
|
|
39
|
+
const build = Bun.spawn([
|
|
40
|
+
zigBinary,
|
|
41
|
+
"build-exe",
|
|
42
|
+
sourcePath,
|
|
43
|
+
"-O",
|
|
44
|
+
"ReleaseFast",
|
|
45
|
+
`-femit-bin=${outputPath}`
|
|
46
|
+
], {
|
|
47
|
+
cwd: dirname(sourcePath),
|
|
48
|
+
stdout: "pipe",
|
|
49
|
+
stderr: "pipe"
|
|
50
|
+
});
|
|
51
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
52
|
+
build.exited,
|
|
53
|
+
new Response(build.stdout).text(),
|
|
54
|
+
new Response(build.stderr).text()
|
|
55
|
+
]);
|
|
56
|
+
if (exitCode !== 0 || !existsSync(outputPath)) {
|
|
57
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
58
|
+
`);
|
|
59
|
+
throw new Error(`Failed to build native Rig shell: ${details || `zig exited with code ${exitCode}`}`);
|
|
60
|
+
}
|
|
61
|
+
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
62
|
+
`);
|
|
63
|
+
return outputPath;
|
|
64
|
+
}
|
|
65
|
+
async function materializeRigShellBinary(targetDir) {
|
|
66
|
+
const sourcePath = await ensureRigShellBinaryPath();
|
|
67
|
+
const targetPath = resolve(targetDir, runtimeRigShellFileName());
|
|
68
|
+
mkdirSync(targetDir, { recursive: true });
|
|
69
|
+
const sourceDigest = await sha256File(sourcePath);
|
|
70
|
+
const buildKey = JSON.stringify({
|
|
71
|
+
version: 1,
|
|
72
|
+
sourcePath,
|
|
73
|
+
sourceDigest
|
|
74
|
+
});
|
|
75
|
+
const needsCopy = !existsSync(targetPath) || !await hasMatchingNativeBuildManifest(nativeBuildManifestPath(targetPath), buildKey);
|
|
76
|
+
if (needsCopy) {
|
|
77
|
+
copyFileSync(sourcePath, targetPath);
|
|
78
|
+
chmodSync(targetPath, 493);
|
|
79
|
+
await Bun.write(nativeBuildManifestPath(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
return targetPath;
|
|
83
|
+
}
|
|
84
|
+
function resolveRigShellSourcePath() {
|
|
85
|
+
for (const candidate of rigShellSourceCandidates()) {
|
|
86
|
+
if (candidate && existsSync(candidate)) {
|
|
87
|
+
return candidate;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function resolveBundledRigShellBinaryPath() {
|
|
93
|
+
for (const candidate of rigShellBinaryCandidates()) {
|
|
94
|
+
if (candidate && existsSync(candidate)) {
|
|
95
|
+
return candidate;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function rigShellSourceCandidates() {
|
|
101
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
102
|
+
const cwd = process.cwd()?.trim() || "";
|
|
103
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
104
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
105
|
+
return [...new Set([
|
|
106
|
+
process.env.RIG_NATIVE_SHELL_SOURCE?.trim() || "",
|
|
107
|
+
cwd ? resolve(cwd, "packages/runtime/native/rig-shell.zig") : "",
|
|
108
|
+
projectRoot ? resolve(projectRoot, "packages/runtime/native/rig-shell.zig") : "",
|
|
109
|
+
hostProjectRoot ? resolve(hostProjectRoot, "packages/runtime/native/rig-shell.zig") : "",
|
|
110
|
+
execDir ? resolve(execDir, "..", "..", "packages/runtime/native/rig-shell.zig") : "",
|
|
111
|
+
execDir ? resolve(execDir, "..", "native", "rig-shell.zig") : "",
|
|
112
|
+
resolve(import.meta.dir, "../../../../native/rig-shell.zig")
|
|
113
|
+
].filter(Boolean))];
|
|
114
|
+
}
|
|
115
|
+
function nativePackageBinaryCandidates(fromDir, fileName) {
|
|
116
|
+
const candidates = [];
|
|
117
|
+
let cursor = resolve(fromDir);
|
|
118
|
+
for (let index = 0;index < 8; index += 1) {
|
|
119
|
+
candidates.push(resolve(cursor, "native", `${process.platform}-${process.arch}`, fileName), resolve(cursor, "native", `${process.platform}-${process.arch}`, "bin", fileName), resolve(cursor, "native", fileName), resolve(cursor, "native", "bin", fileName));
|
|
120
|
+
const parent = dirname(cursor);
|
|
121
|
+
if (parent === cursor)
|
|
122
|
+
break;
|
|
123
|
+
cursor = parent;
|
|
124
|
+
}
|
|
125
|
+
return candidates;
|
|
126
|
+
}
|
|
127
|
+
function rigShellBinaryCandidates() {
|
|
128
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
129
|
+
const fileName = runtimeRigShellFileName();
|
|
130
|
+
return [...new Set([
|
|
131
|
+
process.env.RIG_NATIVE_SHELL_BIN?.trim() || "",
|
|
132
|
+
...nativePackageBinaryCandidates(import.meta.dir, fileName),
|
|
133
|
+
execDir ? resolve(execDir, fileName) : "",
|
|
134
|
+
execDir ? resolve(execDir, "..", fileName) : "",
|
|
135
|
+
execDir ? resolve(execDir, "..", "bin", fileName) : ""
|
|
136
|
+
].filter(Boolean))];
|
|
137
|
+
}
|
|
138
|
+
function runtimeToolGatewayNames() {
|
|
139
|
+
return [
|
|
140
|
+
"bash",
|
|
141
|
+
"sh",
|
|
142
|
+
"zsh",
|
|
143
|
+
"git",
|
|
144
|
+
"bun",
|
|
145
|
+
"node",
|
|
146
|
+
"python3",
|
|
147
|
+
"rg",
|
|
148
|
+
"grep",
|
|
149
|
+
"sed",
|
|
150
|
+
"cat",
|
|
151
|
+
"ls",
|
|
152
|
+
"find",
|
|
153
|
+
"tsc",
|
|
154
|
+
"gh",
|
|
155
|
+
"mkdir",
|
|
156
|
+
"rm",
|
|
157
|
+
"mv",
|
|
158
|
+
"cp",
|
|
159
|
+
"touch",
|
|
160
|
+
"pwd",
|
|
161
|
+
"head",
|
|
162
|
+
"tail",
|
|
163
|
+
"wc",
|
|
164
|
+
"sort",
|
|
165
|
+
"uniq",
|
|
166
|
+
"awk",
|
|
167
|
+
"xargs",
|
|
168
|
+
"dirname",
|
|
169
|
+
"basename",
|
|
170
|
+
"realpath",
|
|
171
|
+
"env",
|
|
172
|
+
"jq",
|
|
173
|
+
"tee",
|
|
174
|
+
"which"
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
function shellBinaryBasename(path) {
|
|
178
|
+
return basename(path);
|
|
179
|
+
}
|
|
180
|
+
function nativeBuildManifestPath(outputPath) {
|
|
181
|
+
return `${outputPath}.build-manifest.json`;
|
|
182
|
+
}
|
|
183
|
+
async function hasMatchingNativeBuildManifest(manifestPath, buildKey) {
|
|
184
|
+
if (!existsSync(manifestPath)) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
const manifest = await Bun.file(manifestPath).json();
|
|
189
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
190
|
+
} catch {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async function sha256File(path) {
|
|
195
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
196
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
197
|
+
return hasher.digest("hex");
|
|
198
|
+
}
|
|
199
|
+
// packages/runtime/src/control-plane/runtime/tooling/browser-tools.ts
|
|
200
|
+
import { existsSync as existsSync2, rmSync, symlinkSync } from "fs";
|
|
201
|
+
import { resolve as resolve2 } from "path";
|
|
202
|
+
function runtimeBrowserToolBinaryName() {
|
|
203
|
+
return `rig-browser-tool${process.platform === "win32" ? ".exe" : ""}`;
|
|
204
|
+
}
|
|
205
|
+
function runtimeBrowserToolNames() {
|
|
206
|
+
return [
|
|
207
|
+
"rig-browser-launch",
|
|
208
|
+
"rig-browser-check",
|
|
209
|
+
"rig-browser-attach-info",
|
|
210
|
+
"rig-browser-e2e",
|
|
211
|
+
"rig-browser-reset-profile"
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
async function materializeRuntimeBrowserTools(targetDir) {
|
|
215
|
+
const binaryPath = resolve2(targetDir, runtimeBrowserToolBinaryName());
|
|
216
|
+
for (const tool of runtimeBrowserToolNames()) {
|
|
217
|
+
const toolPath = resolve2(targetDir, tool);
|
|
218
|
+
if (existsSync2(toolPath)) {
|
|
219
|
+
rmSync(toolPath, { force: true, recursive: true });
|
|
220
|
+
}
|
|
221
|
+
symlinkSync(binaryPath, toolPath);
|
|
222
|
+
}
|
|
223
|
+
return binaryPath;
|
|
224
|
+
}
|
|
225
|
+
// packages/runtime/src/control-plane/runtime/tooling/file-tools.ts
|
|
226
|
+
import { chmodSync as chmodSync2, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, rmSync as rmSync2, symlinkSync as symlinkSync2 } from "fs";
|
|
227
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
228
|
+
import { basename as basename2, dirname as dirname2, resolve as resolve3 } from "path";
|
|
229
|
+
var sharedNativeToolsOutputDir = resolve3(tmpdir2(), "rig-native");
|
|
230
|
+
var sharedNativeToolsOutputPath = resolve3(sharedNativeToolsOutputDir, `rig-tools-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
231
|
+
function runtimeRigToolsFileName() {
|
|
232
|
+
return `rig-tools${process.platform === "win32" ? ".exe" : ""}`;
|
|
233
|
+
}
|
|
234
|
+
function runtimeFileToolNames() {
|
|
235
|
+
return [
|
|
236
|
+
"rig-read",
|
|
237
|
+
"rig-write",
|
|
238
|
+
"rig-edit",
|
|
239
|
+
"rig-glob",
|
|
240
|
+
"rig-grep"
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
async function ensureRigToolsBinaryPath(outputPath = sharedNativeToolsOutputPath) {
|
|
244
|
+
const sourcePath = resolveRigToolsSourcePath();
|
|
245
|
+
if (!sourcePath) {
|
|
246
|
+
const bundledBinary = resolveBundledRigToolsBinaryPath();
|
|
247
|
+
if (bundledBinary) {
|
|
248
|
+
return bundledBinary;
|
|
249
|
+
}
|
|
250
|
+
throw new Error("rig-tools.zig source file not found.");
|
|
251
|
+
}
|
|
252
|
+
const zigBinary = Bun.which("zig");
|
|
253
|
+
if (!zigBinary) {
|
|
254
|
+
throw new Error("zig is required to build native Rig file tools.");
|
|
255
|
+
}
|
|
256
|
+
mkdirSync2(dirname2(outputPath), { recursive: true });
|
|
257
|
+
const sourceDigest = await sha256File2(sourcePath);
|
|
258
|
+
const buildKey = JSON.stringify({
|
|
259
|
+
version: 1,
|
|
260
|
+
zigBinary,
|
|
261
|
+
platform: process.platform,
|
|
262
|
+
arch: process.arch,
|
|
263
|
+
sourcePath,
|
|
264
|
+
sourceDigest
|
|
265
|
+
});
|
|
266
|
+
const manifestPath = nativeBuildManifestPath2(outputPath);
|
|
267
|
+
const needsBuild = !existsSync3(outputPath) || !await hasMatchingNativeBuildManifest2(manifestPath, buildKey);
|
|
268
|
+
if (!needsBuild) {
|
|
269
|
+
return outputPath;
|
|
270
|
+
}
|
|
271
|
+
const build = Bun.spawn([
|
|
272
|
+
zigBinary,
|
|
273
|
+
"build-exe",
|
|
274
|
+
sourcePath,
|
|
275
|
+
"-O",
|
|
276
|
+
"ReleaseFast",
|
|
277
|
+
`-femit-bin=${outputPath}`
|
|
278
|
+
], {
|
|
279
|
+
cwd: dirname2(sourcePath),
|
|
280
|
+
stdout: "pipe",
|
|
281
|
+
stderr: "pipe"
|
|
282
|
+
});
|
|
283
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
284
|
+
build.exited,
|
|
285
|
+
new Response(build.stdout).text(),
|
|
286
|
+
new Response(build.stderr).text()
|
|
287
|
+
]);
|
|
288
|
+
if (exitCode !== 0 || !existsSync3(outputPath)) {
|
|
289
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join(`
|
|
290
|
+
`);
|
|
291
|
+
throw new Error(`Failed to build native Rig file tools: ${details || `zig exited with code ${exitCode}`}`);
|
|
292
|
+
}
|
|
293
|
+
await Bun.write(manifestPath, `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
294
|
+
`);
|
|
295
|
+
return outputPath;
|
|
296
|
+
}
|
|
297
|
+
async function materializeRuntimeFileTools(targetDir) {
|
|
298
|
+
const sourcePath = await ensureRigToolsBinaryPath();
|
|
299
|
+
const targetPath = resolve3(targetDir, runtimeRigToolsFileName());
|
|
300
|
+
mkdirSync2(targetDir, { recursive: true });
|
|
301
|
+
const sourceDigest = await sha256File2(sourcePath);
|
|
302
|
+
const buildKey = JSON.stringify({
|
|
303
|
+
version: 1,
|
|
304
|
+
sourcePath,
|
|
305
|
+
sourceDigest
|
|
306
|
+
});
|
|
307
|
+
const needsCopy = !existsSync3(targetPath) || !await hasMatchingNativeBuildManifest2(nativeBuildManifestPath2(targetPath), buildKey);
|
|
308
|
+
if (needsCopy) {
|
|
309
|
+
copyFileSync2(sourcePath, targetPath);
|
|
310
|
+
chmodSync2(targetPath, 493);
|
|
311
|
+
await Bun.write(nativeBuildManifestPath2(targetPath), `${JSON.stringify({ version: 1, buildKey }, null, 2)}
|
|
312
|
+
`);
|
|
313
|
+
}
|
|
314
|
+
for (const tool of runtimeFileToolNames()) {
|
|
315
|
+
const toolPath = resolve3(targetDir, tool);
|
|
316
|
+
if (existsSync3(toolPath)) {
|
|
317
|
+
rmSync2(toolPath, { force: true, recursive: true });
|
|
318
|
+
}
|
|
319
|
+
symlinkSync2(targetPath, toolPath);
|
|
320
|
+
}
|
|
321
|
+
return targetPath;
|
|
322
|
+
}
|
|
323
|
+
function resolveRigToolsSourcePath() {
|
|
324
|
+
for (const candidate of rigToolsSourceCandidates()) {
|
|
325
|
+
if (candidate && existsSync3(candidate)) {
|
|
326
|
+
return candidate;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
function resolveBundledRigToolsBinaryPath() {
|
|
332
|
+
for (const candidate of rigToolsBinaryCandidates()) {
|
|
333
|
+
if (candidate && existsSync3(candidate)) {
|
|
334
|
+
return candidate;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
function rigToolsSourceCandidates() {
|
|
340
|
+
const execDir = process.execPath?.trim() ? dirname2(process.execPath.trim()) : "";
|
|
341
|
+
const cwd = process.cwd()?.trim() || "";
|
|
342
|
+
const projectRoot = process.env.PROJECT_RIG_ROOT?.trim() || "";
|
|
343
|
+
const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim() || "";
|
|
344
|
+
return [...new Set([
|
|
345
|
+
process.env.RIG_NATIVE_TOOLS_SOURCE?.trim() || "",
|
|
346
|
+
cwd ? resolve3(cwd, "packages/runtime/native/rig-tools.zig") : "",
|
|
347
|
+
projectRoot ? resolve3(projectRoot, "packages/runtime/native/rig-tools.zig") : "",
|
|
348
|
+
hostProjectRoot ? resolve3(hostProjectRoot, "packages/runtime/native/rig-tools.zig") : "",
|
|
349
|
+
execDir ? resolve3(execDir, "..", "..", "packages/runtime/native/rig-tools.zig") : "",
|
|
350
|
+
execDir ? resolve3(execDir, "..", "native", "rig-tools.zig") : "",
|
|
351
|
+
resolve3(import.meta.dir, "../../../../native/rig-tools.zig")
|
|
352
|
+
].filter(Boolean))];
|
|
353
|
+
}
|
|
354
|
+
function nativePackageBinaryCandidates2(fromDir, fileName) {
|
|
355
|
+
const candidates = [];
|
|
356
|
+
let cursor = resolve3(fromDir);
|
|
357
|
+
for (let index = 0;index < 8; index += 1) {
|
|
358
|
+
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));
|
|
359
|
+
const parent = dirname2(cursor);
|
|
360
|
+
if (parent === cursor)
|
|
361
|
+
break;
|
|
362
|
+
cursor = parent;
|
|
363
|
+
}
|
|
364
|
+
return candidates;
|
|
365
|
+
}
|
|
366
|
+
function rigToolsBinaryCandidates() {
|
|
367
|
+
const execDir = process.execPath?.trim() ? dirname2(process.execPath.trim()) : "";
|
|
368
|
+
const fileName = runtimeRigToolsFileName();
|
|
369
|
+
return [...new Set([
|
|
370
|
+
process.env.RIG_NATIVE_TOOLS_BIN?.trim() || "",
|
|
371
|
+
...nativePackageBinaryCandidates2(import.meta.dir, fileName),
|
|
372
|
+
execDir ? resolve3(execDir, fileName) : "",
|
|
373
|
+
execDir ? resolve3(execDir, "..", fileName) : "",
|
|
374
|
+
execDir ? resolve3(execDir, "..", "bin", fileName) : ""
|
|
375
|
+
].filter(Boolean))];
|
|
376
|
+
}
|
|
377
|
+
function runtimeFileToolBasename(path) {
|
|
378
|
+
return basename2(path);
|
|
379
|
+
}
|
|
380
|
+
function nativeBuildManifestPath2(outputPath) {
|
|
381
|
+
return `${outputPath}.build-manifest.json`;
|
|
382
|
+
}
|
|
383
|
+
async function hasMatchingNativeBuildManifest2(manifestPath, buildKey) {
|
|
384
|
+
if (!existsSync3(manifestPath)) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
const manifest = await Bun.file(manifestPath).json();
|
|
389
|
+
return manifest.version === 1 && manifest.buildKey === buildKey;
|
|
390
|
+
} catch {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async function sha256File2(path) {
|
|
395
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
396
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
397
|
+
return hasher.digest("hex");
|
|
398
|
+
}
|
|
399
|
+
// packages/runtime/src/control-plane/runtime/tooling/gateway.ts
|
|
400
|
+
import { existsSync as existsSync4, rmSync as rmSync3, symlinkSync as symlinkSync3 } from "fs";
|
|
401
|
+
import { resolve as resolve4 } from "path";
|
|
402
|
+
function runtimeGatewayToolNames() {
|
|
403
|
+
return runtimeToolGatewayNames();
|
|
404
|
+
}
|
|
405
|
+
async function materializeRuntimeToolGateway(binDir) {
|
|
406
|
+
const shellPath = await materializeRigShellBinary(binDir);
|
|
407
|
+
for (const tool of runtimeGatewayToolNames()) {
|
|
408
|
+
const toolPath = resolve4(binDir, tool);
|
|
409
|
+
if (existsSync4(toolPath)) {
|
|
410
|
+
rmSync3(toolPath, { force: true, recursive: true });
|
|
411
|
+
}
|
|
412
|
+
symlinkSync3(shellPath, toolPath);
|
|
413
|
+
}
|
|
414
|
+
await materializeRuntimeBrowserTools(binDir);
|
|
415
|
+
return resolve4(binDir, runtimeRigShellFileName());
|
|
416
|
+
}
|
|
417
|
+
// packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
|
|
418
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, statSync as statSync2, writeFileSync } from "fs";
|
|
419
|
+
import { resolve as resolve5 } from "path";
|
|
420
|
+
import { createInterface } from "readline";
|
|
421
|
+
var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
|
|
422
|
+
var CLAUDE_DISABLED_FILE_TOOLS = [
|
|
423
|
+
"Read",
|
|
424
|
+
"Edit",
|
|
425
|
+
"Write",
|
|
426
|
+
"NotebookEdit",
|
|
427
|
+
"Glob",
|
|
428
|
+
"Grep"
|
|
429
|
+
];
|
|
430
|
+
var ROUTER_VERSION = "0.1.0";
|
|
431
|
+
var CLAUDE_ROUTER_TOOL_DEFINITIONS = [
|
|
432
|
+
{
|
|
433
|
+
name: "read",
|
|
434
|
+
description: "Read a UTF-8 file from the current Rig task worktree, the outer control-plane repo ($PROJECT_RIG_ROOT), or the host monorepo checkout ($MONOREPO_MAIN_ROOT).",
|
|
435
|
+
inputSchema: {
|
|
436
|
+
type: "object",
|
|
437
|
+
properties: {
|
|
438
|
+
path: { type: "string", description: "Absolute or workspace-relative file path." },
|
|
439
|
+
offset: { type: "integer", minimum: 0 },
|
|
440
|
+
limit: { type: "integer", minimum: 1, maximum: 2097152 }
|
|
441
|
+
},
|
|
442
|
+
required: ["path"],
|
|
443
|
+
additionalProperties: false
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
name: "write",
|
|
448
|
+
description: "Write UTF-8 content to a file inside the current Rig task workspace only.",
|
|
449
|
+
inputSchema: {
|
|
450
|
+
type: "object",
|
|
451
|
+
properties: {
|
|
452
|
+
path: { type: "string", description: "Absolute or workspace-relative file path." },
|
|
453
|
+
content: { type: "string" },
|
|
454
|
+
create_parents: { type: "boolean" }
|
|
455
|
+
},
|
|
456
|
+
required: ["path", "content"],
|
|
457
|
+
additionalProperties: false
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
name: "edit",
|
|
462
|
+
description: "Replace one or more exact string occurrences in a UTF-8 file inside the current Rig task workspace only.",
|
|
463
|
+
inputSchema: {
|
|
464
|
+
type: "object",
|
|
465
|
+
properties: {
|
|
466
|
+
path: { type: "string", description: "Absolute or workspace-relative file path." },
|
|
467
|
+
old_string: { type: "string" },
|
|
468
|
+
new_string: { type: "string" },
|
|
469
|
+
replace_all: { type: "boolean" }
|
|
470
|
+
},
|
|
471
|
+
required: ["path", "old_string", "new_string"],
|
|
472
|
+
additionalProperties: false
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: "glob",
|
|
477
|
+
description: "Search files using a glob pattern across the current task worktree, $PROJECT_RIG_ROOT, or $MONOREPO_MAIN_ROOT.",
|
|
478
|
+
inputSchema: {
|
|
479
|
+
type: "object",
|
|
480
|
+
properties: {
|
|
481
|
+
pattern: { type: "string" },
|
|
482
|
+
path: { type: "string", description: "Optional workspace-relative search root." },
|
|
483
|
+
include_hidden: { type: "boolean" },
|
|
484
|
+
max_results: { type: "integer", minimum: 1, maximum: 5000 }
|
|
485
|
+
},
|
|
486
|
+
required: ["pattern"],
|
|
487
|
+
additionalProperties: false
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
name: "grep",
|
|
492
|
+
description: "Search file contents across the current task worktree, $PROJECT_RIG_ROOT, or $MONOREPO_MAIN_ROOT.",
|
|
493
|
+
inputSchema: {
|
|
494
|
+
type: "object",
|
|
495
|
+
properties: {
|
|
496
|
+
pattern: { type: "string" },
|
|
497
|
+
path: { type: "string", description: "Optional workspace-relative search root." },
|
|
498
|
+
literal: { type: "boolean" },
|
|
499
|
+
include_hidden: { type: "boolean" },
|
|
500
|
+
max_results: { type: "integer", minimum: 1, maximum: 500 },
|
|
501
|
+
glob: { type: "string", description: "Optional file glob filter passed through to ripgrep." }
|
|
502
|
+
},
|
|
503
|
+
required: ["pattern"],
|
|
504
|
+
additionalProperties: false
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
];
|
|
508
|
+
function claudeRuntimeToolCliArgs(configPath) {
|
|
509
|
+
return [
|
|
510
|
+
"--disallowedTools",
|
|
511
|
+
CLAUDE_DISABLED_FILE_TOOLS.join(","),
|
|
512
|
+
"--mcp-config",
|
|
513
|
+
configPath
|
|
514
|
+
];
|
|
515
|
+
}
|
|
516
|
+
function buildRuntimeToolRouterServerConfig(options) {
|
|
517
|
+
return {
|
|
518
|
+
type: "stdio",
|
|
519
|
+
command: resolve5(options.binDir, "rig-tool-router"),
|
|
520
|
+
args: [],
|
|
521
|
+
env: {
|
|
522
|
+
RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
|
|
523
|
+
RIG_RUNTIME_BIN_DIR: options.binDir
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function escapeTomlString(value) {
|
|
528
|
+
return value.replaceAll("\\", "\\\\").replaceAll('"', "\\\"");
|
|
529
|
+
}
|
|
530
|
+
function tomlString(value) {
|
|
531
|
+
return `"${escapeTomlString(value)}"`;
|
|
532
|
+
}
|
|
533
|
+
function tomlStringArray(values) {
|
|
534
|
+
return `[${values.map((value) => tomlString(value)).join(", ")}]`;
|
|
535
|
+
}
|
|
536
|
+
function tomlInlineTable(entries) {
|
|
537
|
+
return `{ ${Object.entries(entries).map(([key, value]) => `${key} = ${tomlString(value)}`).join(", ")} }`;
|
|
538
|
+
}
|
|
539
|
+
function codexRuntimeToolCliArgs(options) {
|
|
540
|
+
const serverConfig = buildRuntimeToolRouterServerConfig(options);
|
|
541
|
+
return [
|
|
542
|
+
"-a",
|
|
543
|
+
"never",
|
|
544
|
+
"-c",
|
|
545
|
+
`mcp_servers.${CLAUDE_ROUTER_SERVER_NAME}.command=${tomlString(serverConfig.command)}`,
|
|
546
|
+
"-c",
|
|
547
|
+
`mcp_servers.${CLAUDE_ROUTER_SERVER_NAME}.args=${tomlStringArray(serverConfig.args)}`,
|
|
548
|
+
"-c",
|
|
549
|
+
`mcp_servers.${CLAUDE_ROUTER_SERVER_NAME}.env=${tomlInlineTable(serverConfig.env)}`
|
|
550
|
+
];
|
|
551
|
+
}
|
|
552
|
+
function writeClaudeRuntimeToolRouterConfig(options) {
|
|
553
|
+
const configPath = resolve5(options.stateDir, "claude-runtime-tools.mcp.json");
|
|
554
|
+
mkdirSync3(options.stateDir, { recursive: true });
|
|
555
|
+
const payload = {
|
|
556
|
+
mcpServers: {
|
|
557
|
+
[CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
writeFileSync(configPath, `${JSON.stringify(payload, null, 2)}
|
|
561
|
+
`, "utf-8");
|
|
562
|
+
return configPath;
|
|
563
|
+
}
|
|
564
|
+
async function runClaudeToolRouterServer() {
|
|
565
|
+
const lineReader = createInterface({
|
|
566
|
+
input: process.stdin,
|
|
567
|
+
crlfDelay: Infinity
|
|
568
|
+
});
|
|
569
|
+
const inFlightToolCalls = new Set;
|
|
570
|
+
const trackToolCall = (call) => {
|
|
571
|
+
inFlightToolCalls.add(call);
|
|
572
|
+
call.finally(() => inFlightToolCalls.delete(call)).catch((err) => {
|
|
573
|
+
console.warn("[claude-router] in-flight tool call failure:", err);
|
|
574
|
+
});
|
|
575
|
+
};
|
|
576
|
+
for await (const line of lineReader) {
|
|
577
|
+
const trimmed = line.trim();
|
|
578
|
+
if (!trimmed) {
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
let request;
|
|
582
|
+
try {
|
|
583
|
+
request = JSON.parse(trimmed);
|
|
584
|
+
} catch {
|
|
585
|
+
continue;
|
|
586
|
+
}
|
|
587
|
+
if (!request.method) {
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
if (request.method === "notifications/initialized") {
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
if (request.method === "initialize") {
|
|
594
|
+
writeMessage({
|
|
595
|
+
jsonrpc: "2.0",
|
|
596
|
+
id: request.id ?? null,
|
|
597
|
+
result: {
|
|
598
|
+
protocolVersion: "2024-11-05",
|
|
599
|
+
capabilities: {
|
|
600
|
+
tools: {}
|
|
601
|
+
},
|
|
602
|
+
serverInfo: {
|
|
603
|
+
name: CLAUDE_ROUTER_SERVER_NAME,
|
|
604
|
+
version: ROUTER_VERSION
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
if (request.method === "ping") {
|
|
611
|
+
writeMessage({
|
|
612
|
+
jsonrpc: "2.0",
|
|
613
|
+
id: request.id ?? null,
|
|
614
|
+
result: {}
|
|
615
|
+
});
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
if (request.method === "tools/list") {
|
|
619
|
+
writeMessage({
|
|
620
|
+
jsonrpc: "2.0",
|
|
621
|
+
id: request.id ?? null,
|
|
622
|
+
result: {
|
|
623
|
+
tools: CLAUDE_ROUTER_TOOL_DEFINITIONS
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
if (request.method === "tools/call") {
|
|
629
|
+
const toolName = typeof request.params?.name === "string" ? request.params.name : "";
|
|
630
|
+
const args = isRecord(request.params?.arguments) ? request.params.arguments : {};
|
|
631
|
+
const requestId = request.id ?? null;
|
|
632
|
+
const toolCall = (async () => {
|
|
633
|
+
try {
|
|
634
|
+
const result = await invokeRuntimeTool(toolName, args);
|
|
635
|
+
writeMessage({
|
|
636
|
+
jsonrpc: "2.0",
|
|
637
|
+
id: requestId,
|
|
638
|
+
result
|
|
639
|
+
});
|
|
640
|
+
} catch (error) {
|
|
641
|
+
writeMessage({
|
|
642
|
+
jsonrpc: "2.0",
|
|
643
|
+
id: requestId,
|
|
644
|
+
error: {
|
|
645
|
+
code: -32603,
|
|
646
|
+
message: error instanceof Error ? error.message : String(error)
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
})();
|
|
651
|
+
trackToolCall(toolCall);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
writeMessage({
|
|
655
|
+
jsonrpc: "2.0",
|
|
656
|
+
id: request.id ?? null,
|
|
657
|
+
error: {
|
|
658
|
+
code: -32601,
|
|
659
|
+
message: `Unsupported method: ${request.method}`
|
|
660
|
+
}
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
if (inFlightToolCalls.size > 0) {
|
|
664
|
+
await Promise.allSettled(Array.from(inFlightToolCalls));
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
async function invokeRuntimeTool(toolName, args, options = {}) {
|
|
668
|
+
if (toolName === "shell") {
|
|
669
|
+
return invokeRuntimeShellTool(args, options);
|
|
670
|
+
}
|
|
671
|
+
const invocationEnv = options.env ?? process.env;
|
|
672
|
+
const binaryPath = resolveRuntimeToolBinary(toolName, invocationEnv);
|
|
673
|
+
if (!binaryPath) {
|
|
674
|
+
return {
|
|
675
|
+
content: [
|
|
676
|
+
{
|
|
677
|
+
type: "text",
|
|
678
|
+
text: `Unknown Rig runtime tool: ${toolName}`
|
|
679
|
+
}
|
|
680
|
+
],
|
|
681
|
+
isError: true
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
const proc = Bun.spawn([binaryPath], {
|
|
685
|
+
stdin: "pipe",
|
|
686
|
+
stdout: "pipe",
|
|
687
|
+
stderr: "pipe",
|
|
688
|
+
env: invocationEnv
|
|
689
|
+
});
|
|
690
|
+
const requestBody = `${JSON.stringify(args)}
|
|
691
|
+
`;
|
|
692
|
+
if (proc.stdin) {
|
|
693
|
+
await proc.stdin.write(requestBody);
|
|
694
|
+
await proc.stdin.end();
|
|
695
|
+
}
|
|
696
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
697
|
+
proc.exited,
|
|
698
|
+
readBunProcessPipe(proc.stdout),
|
|
699
|
+
readBunProcessPipe(proc.stderr)
|
|
700
|
+
]);
|
|
701
|
+
if (exitCode !== 0) {
|
|
702
|
+
const text = [stdout.trim(), stderr.trim()].filter(Boolean).join(`
|
|
703
|
+
`) || `Tool ${toolName} exited with code ${exitCode}`;
|
|
704
|
+
return {
|
|
705
|
+
content: [{ type: "text", text }],
|
|
706
|
+
isError: true
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
let payload;
|
|
710
|
+
try {
|
|
711
|
+
payload = JSON.parse(stdout);
|
|
712
|
+
} catch {
|
|
713
|
+
return {
|
|
714
|
+
content: [{ type: "text", text: stdout.trim() || `(empty output from ${toolName})` }],
|
|
715
|
+
isError: false
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
if (payload.ok === false) {
|
|
719
|
+
return {
|
|
720
|
+
content: [{ type: "text", text: String(payload.message ?? `Tool ${toolName} failed`) }],
|
|
721
|
+
structuredContent: payload,
|
|
722
|
+
isError: true
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
return {
|
|
726
|
+
content: [{ type: "text", text: renderToolText(toolName, payload) }],
|
|
727
|
+
structuredContent: payload,
|
|
728
|
+
isError: false
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
async function readBunProcessPipe(pipe) {
|
|
732
|
+
if (typeof pipe === "number" || !pipe) {
|
|
733
|
+
return "";
|
|
734
|
+
}
|
|
735
|
+
return new Response(pipe).text();
|
|
736
|
+
}
|
|
737
|
+
function resolveRuntimeToolBinary(toolName, env) {
|
|
738
|
+
const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
|
|
739
|
+
if (!binDir) {
|
|
740
|
+
return "";
|
|
741
|
+
}
|
|
742
|
+
const mapping = {
|
|
743
|
+
read: "rig-read",
|
|
744
|
+
write: "rig-write",
|
|
745
|
+
edit: "rig-edit",
|
|
746
|
+
glob: "rig-glob",
|
|
747
|
+
grep: "rig-grep"
|
|
748
|
+
};
|
|
749
|
+
const executable = mapping[toolName];
|
|
750
|
+
return executable ? resolve5(binDir, executable) : "";
|
|
751
|
+
}
|
|
752
|
+
function renderToolText(toolName, payload) {
|
|
753
|
+
if (toolName === "shell") {
|
|
754
|
+
const command = typeof payload.command === "string" ? payload.command : "(unknown command)";
|
|
755
|
+
const stdout = typeof payload.stdout === "string" ? payload.stdout.trim() : "";
|
|
756
|
+
const stderr = typeof payload.stderr === "string" ? payload.stderr.trim() : "";
|
|
757
|
+
const exitCode = typeof payload.exit_code === "number" ? payload.exit_code : null;
|
|
758
|
+
const output = [stdout, stderr].filter(Boolean).join(`
|
|
759
|
+
`);
|
|
760
|
+
const summary = exitCode === null ? command : `${command}
|
|
761
|
+
|
|
762
|
+
exit_code=${String(exitCode)}`;
|
|
763
|
+
return output ? `${summary}
|
|
764
|
+
|
|
765
|
+
${output}` : summary;
|
|
766
|
+
}
|
|
767
|
+
if (toolName === "read") {
|
|
768
|
+
const path = typeof payload.path === "string" ? payload.path : "(unknown path)";
|
|
769
|
+
const content = typeof payload.content === "string" ? payload.content : "";
|
|
770
|
+
const truncated = payload.truncated === true ? `
|
|
771
|
+
|
|
772
|
+
[truncated]` : "";
|
|
773
|
+
return `${path}
|
|
774
|
+
|
|
775
|
+
${content}${truncated}`;
|
|
776
|
+
}
|
|
777
|
+
if (toolName === "glob") {
|
|
778
|
+
const matches = Array.isArray(payload.matches) ? payload.matches.filter((value) => typeof value === "string") : [];
|
|
779
|
+
return matches.length > 0 ? matches.join(`
|
|
780
|
+
`) : "(no matches)";
|
|
781
|
+
}
|
|
782
|
+
if (toolName === "grep") {
|
|
783
|
+
const matches = Array.isArray(payload.matches) ? payload.matches.filter(isRecord) : [];
|
|
784
|
+
if (matches.length === 0) {
|
|
785
|
+
return "(no matches)";
|
|
786
|
+
}
|
|
787
|
+
return matches.map((match) => `${String(match.path ?? "(unknown)")}:${String(match.line_number ?? "?")}: ${String(match.line ?? "")}`).join(`
|
|
788
|
+
`);
|
|
789
|
+
}
|
|
790
|
+
if (toolName === "write") {
|
|
791
|
+
return `Wrote ${String(payload.bytes_written ?? 0)} bytes to ${String(payload.path ?? "(unknown path)")}.`;
|
|
792
|
+
}
|
|
793
|
+
if (toolName === "edit") {
|
|
794
|
+
return `Edited ${String(payload.path ?? "(unknown path)")}; replacements: ${String(payload.replacements ?? 0)}.`;
|
|
795
|
+
}
|
|
796
|
+
return JSON.stringify(payload, null, 2);
|
|
797
|
+
}
|
|
798
|
+
async function invokeRuntimeShellTool(args, options = {}) {
|
|
799
|
+
const command = typeof args.command === "string" ? args.command.trim() : "";
|
|
800
|
+
if (!command) {
|
|
801
|
+
return {
|
|
802
|
+
content: [{ type: "text", text: "Missing required shell `command` string." }],
|
|
803
|
+
isError: true
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
const invocationEnv = options.env ?? process.env;
|
|
807
|
+
const shellName = args.shell === "sh" ? "sh" : args.shell === "zsh" ? "zsh" : "bash";
|
|
808
|
+
const shellBinary = resolveRuntimeShellBinary(shellName, invocationEnv);
|
|
809
|
+
if (!shellBinary) {
|
|
810
|
+
return {
|
|
811
|
+
content: [{ type: "text", text: `Missing Rig runtime shell binary for ${shellName}.` }],
|
|
812
|
+
isError: true
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
const workspaceRoot = resolve5(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
|
|
816
|
+
const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
|
|
817
|
+
const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
|
|
818
|
+
if (!existsSync5(workdir)) {
|
|
819
|
+
return {
|
|
820
|
+
content: [{
|
|
821
|
+
type: "text",
|
|
822
|
+
text: `Shell workdir does not exist inside the task workspace: ${requestedWorkdir || "."}`
|
|
823
|
+
}],
|
|
824
|
+
isError: true
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
try {
|
|
828
|
+
if (!statSync2(workdir).isDirectory()) {
|
|
829
|
+
return {
|
|
830
|
+
content: [{
|
|
831
|
+
type: "text",
|
|
832
|
+
text: `Shell workdir is not a directory inside the task workspace: ${requestedWorkdir || "."}`
|
|
833
|
+
}],
|
|
834
|
+
isError: true
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
} catch (error) {
|
|
838
|
+
return {
|
|
839
|
+
content: [{
|
|
840
|
+
type: "text",
|
|
841
|
+
text: error instanceof Error ? error.message : String(error)
|
|
842
|
+
}],
|
|
843
|
+
isError: true
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
let proc = null;
|
|
847
|
+
try {
|
|
848
|
+
proc = Bun.spawn([shellBinary, shellName === "bash" ? "-lc" : "-c", command], {
|
|
849
|
+
cwd: workdir,
|
|
850
|
+
env: invocationEnv,
|
|
851
|
+
stdout: "pipe",
|
|
852
|
+
stderr: "pipe"
|
|
853
|
+
});
|
|
854
|
+
} catch (error) {
|
|
855
|
+
return {
|
|
856
|
+
content: [{
|
|
857
|
+
type: "text",
|
|
858
|
+
text: error instanceof Error ? error.message : String(error)
|
|
859
|
+
}],
|
|
860
|
+
isError: true
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
864
|
+
proc.exited,
|
|
865
|
+
readBunProcessPipe(proc.stdout),
|
|
866
|
+
readBunProcessPipe(proc.stderr)
|
|
867
|
+
]);
|
|
868
|
+
const payload = {
|
|
869
|
+
ok: exitCode === 0,
|
|
870
|
+
shell: shellName,
|
|
871
|
+
cwd: workdir,
|
|
872
|
+
command,
|
|
873
|
+
stdout,
|
|
874
|
+
stderr,
|
|
875
|
+
exit_code: exitCode
|
|
876
|
+
};
|
|
877
|
+
return {
|
|
878
|
+
content: [{ type: "text", text: renderToolText("shell", payload) }],
|
|
879
|
+
structuredContent: payload,
|
|
880
|
+
isError: exitCode !== 0
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
function resolveRuntimeShellBinary(shellName, env) {
|
|
884
|
+
const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
|
|
885
|
+
return binDir ? resolve5(binDir, shellName) : "";
|
|
886
|
+
}
|
|
887
|
+
function resolveWithinWorkspace(workspaceRoot, target) {
|
|
888
|
+
const resolvedTarget = resolve5(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
|
|
889
|
+
const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
|
|
890
|
+
const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
|
|
891
|
+
if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
|
|
892
|
+
return resolvedTarget;
|
|
893
|
+
}
|
|
894
|
+
throw new Error(`Shell workdir must stay inside the task workspace: ${target}`);
|
|
895
|
+
}
|
|
896
|
+
function normalizeWorkspaceRelativeTarget(target) {
|
|
897
|
+
const trimmed = target.trim();
|
|
898
|
+
if (!trimmed) {
|
|
899
|
+
return ".";
|
|
900
|
+
}
|
|
901
|
+
if (trimmed === "$MONOREPO_ROOT" || trimmed === "$RIG_TASK_WORKSPACE") {
|
|
902
|
+
return ".";
|
|
903
|
+
}
|
|
904
|
+
if (trimmed.startsWith("$MONOREPO_ROOT/")) {
|
|
905
|
+
return trimmed.slice("$MONOREPO_ROOT/".length);
|
|
906
|
+
}
|
|
907
|
+
if (trimmed.startsWith("$RIG_TASK_WORKSPACE/")) {
|
|
908
|
+
return trimmed.slice("$RIG_TASK_WORKSPACE/".length);
|
|
909
|
+
}
|
|
910
|
+
if (trimmed === "repos/spliter-monorepo") {
|
|
911
|
+
return ".";
|
|
912
|
+
}
|
|
913
|
+
if (trimmed.startsWith("repos/spliter-monorepo/")) {
|
|
914
|
+
return trimmed.slice("repos/spliter-monorepo/".length);
|
|
915
|
+
}
|
|
916
|
+
return trimmed;
|
|
917
|
+
}
|
|
918
|
+
function isRecord(value) {
|
|
919
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
920
|
+
}
|
|
921
|
+
function writeMessage(payload) {
|
|
922
|
+
process.stdout.write(`${JSON.stringify(payload)}
|
|
923
|
+
`);
|
|
924
|
+
}
|
|
925
|
+
if (false) {}
|
|
926
|
+
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
927
|
+
import { chmodSync as chmodSync4, copyFileSync as copyFileSync3, existsSync as existsSync7, mkdirSync as mkdirSync5, statSync as statSync3 } from "fs";
|
|
928
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
929
|
+
import { dirname as dirname4, resolve as resolve7 } from "path";
|
|
930
|
+
|
|
931
|
+
// packages/runtime/src/binary-run.ts
|
|
932
|
+
import { chmodSync as chmodSync3, cpSync, existsSync as existsSync6, mkdirSync as mkdirSync4, renameSync, rmSync as rmSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
933
|
+
import { basename as basename3, dirname as dirname3, resolve as resolve6 } from "path";
|
|
934
|
+
import { fileURLToPath } from "url";
|
|
935
|
+
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
936
|
+
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
937
|
+
async function buildRuntimeBinary(options) {
|
|
938
|
+
return runSerializedRuntimeBinaryBuild(async () => {
|
|
939
|
+
const resolved = resolveRuntimeBinaryBuildOptions(options);
|
|
940
|
+
runBestEffortBuildGc();
|
|
941
|
+
const manifestPath = runtimeBinaryCacheManifestPath(resolved.outputPath);
|
|
942
|
+
const buildKey = createRuntimeBinaryBuildKey({
|
|
943
|
+
entrypoint: resolved.entrypoint,
|
|
944
|
+
define: resolved.define,
|
|
945
|
+
env: resolved.env
|
|
946
|
+
});
|
|
947
|
+
if (await isRuntimeBinaryBuildFresh({ outputPath: resolved.outputPath, manifestPath, buildKey })) {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
if (shouldUseRuntimeBinaryBuildWorker()) {
|
|
951
|
+
await buildRuntimeBinaryViaWorker(resolved);
|
|
952
|
+
} else {
|
|
953
|
+
await buildRuntimeBinaryInProcess(resolved, { manifestPath, buildKey });
|
|
954
|
+
}
|
|
955
|
+
runBestEffortBuildGc();
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
959
|
+
const tempBuildDir = resolve6(dirname3(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
960
|
+
const tempOutputPath = resolve6(tempBuildDir, basename3(options.outputPath));
|
|
961
|
+
mkdirSync4(tempBuildDir, { recursive: true });
|
|
962
|
+
await withTemporaryEnv({
|
|
963
|
+
...options.env,
|
|
964
|
+
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
965
|
+
}, async () => withTemporaryCwd(tempBuildDir, async () => {
|
|
966
|
+
const buildResult = await Bun.build({
|
|
967
|
+
entrypoints: [options.entrypoint],
|
|
968
|
+
compile: {
|
|
969
|
+
target: currentCompileTarget(),
|
|
970
|
+
outfile: tempOutputPath
|
|
971
|
+
},
|
|
972
|
+
target: "bun",
|
|
973
|
+
format: "esm",
|
|
974
|
+
minify: true,
|
|
975
|
+
bytecode: true,
|
|
976
|
+
metafile: true,
|
|
977
|
+
define: options.define ? {
|
|
978
|
+
__RIG_BUILD_CONFIG__: JSON.stringify(options.define)
|
|
979
|
+
} : undefined
|
|
980
|
+
});
|
|
981
|
+
if (!buildResult.success) {
|
|
982
|
+
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(`
|
|
983
|
+
`);
|
|
984
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
985
|
+
}
|
|
986
|
+
if (!existsSync6(tempOutputPath)) {
|
|
987
|
+
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
988
|
+
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
989
|
+
}
|
|
990
|
+
renameSync(tempOutputPath, options.outputPath);
|
|
991
|
+
chmodSync3(options.outputPath, 493);
|
|
992
|
+
if (manifest) {
|
|
993
|
+
await writeRuntimeBinaryCacheManifest({
|
|
994
|
+
manifestPath: manifest.manifestPath,
|
|
995
|
+
buildKey: manifest.buildKey,
|
|
996
|
+
cwd: tempBuildDir,
|
|
997
|
+
metafile: buildResult.metafile
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
})).finally(() => {
|
|
1001
|
+
rmSync4(tempBuildDir, { recursive: true, force: true });
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
function runBestEffortBuildGc() {
|
|
1005
|
+
try {
|
|
1006
|
+
drainMicrotasks();
|
|
1007
|
+
} catch {}
|
|
1008
|
+
try {
|
|
1009
|
+
gcAndSweep();
|
|
1010
|
+
} catch {}
|
|
1011
|
+
}
|
|
1012
|
+
function runtimeBinaryCacheManifestPath(outputPath) {
|
|
1013
|
+
return `${outputPath}.build-manifest.json`;
|
|
1014
|
+
}
|
|
1015
|
+
function resolveRuntimeBinaryBuildOptions(options) {
|
|
1016
|
+
return {
|
|
1017
|
+
...options,
|
|
1018
|
+
entrypoint: resolve6(options.cwd, options.sourcePath),
|
|
1019
|
+
outputPath: resolve6(options.outputPath)
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
function shouldUseRuntimeBinaryBuildWorker() {
|
|
1023
|
+
if (process.env.RIG_RUNTIME_BUILD_WORKER === "1") {
|
|
1024
|
+
return false;
|
|
1025
|
+
}
|
|
1026
|
+
if (process.env.RIG_RUNTIME_BUILD_IN_PROCESS === "1") {
|
|
1027
|
+
return false;
|
|
1028
|
+
}
|
|
1029
|
+
return true;
|
|
1030
|
+
}
|
|
1031
|
+
async function buildRuntimeBinaryViaWorker(options) {
|
|
1032
|
+
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
1033
|
+
if (!workerSourcePath || !existsSync6(workerSourcePath)) {
|
|
1034
|
+
await buildRuntimeBinaryInProcess(options, {
|
|
1035
|
+
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
1036
|
+
buildKey: createRuntimeBinaryBuildKey({
|
|
1037
|
+
entrypoint: options.entrypoint,
|
|
1038
|
+
define: options.define,
|
|
1039
|
+
env: options.env
|
|
1040
|
+
})
|
|
1041
|
+
});
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
const payloadPath = createRuntimeBinaryBuildWorkerPayloadPath(options.outputPath);
|
|
1045
|
+
const bunCli = resolveRuntimeBinaryBuildWorkerInvocation();
|
|
1046
|
+
await Bun.write(payloadPath, `${JSON.stringify(options)}
|
|
1047
|
+
`);
|
|
1048
|
+
const build = Bun.spawn([bunCli.command, workerSourcePath, payloadPath], {
|
|
1049
|
+
cwd: options.cwd,
|
|
1050
|
+
stdout: "pipe",
|
|
1051
|
+
stderr: "pipe",
|
|
1052
|
+
env: {
|
|
1053
|
+
...process.env,
|
|
1054
|
+
...options.env,
|
|
1055
|
+
...bunCli.env,
|
|
1056
|
+
RIG_RUNTIME_BUILD_WORKER: "1"
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
1060
|
+
build.exited,
|
|
1061
|
+
new Response(build.stdout).text(),
|
|
1062
|
+
new Response(build.stderr).text()
|
|
1063
|
+
]);
|
|
1064
|
+
rmSync4(payloadPath, { force: true });
|
|
1065
|
+
if (exitCode !== 0) {
|
|
1066
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
1070
|
+
return resolve6(dirname3(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
1071
|
+
}
|
|
1072
|
+
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
1073
|
+
const envRoots = [
|
|
1074
|
+
options.cwd?.trim(),
|
|
1075
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
1076
|
+
process.env.PROJECT_RIG_ROOT?.trim()
|
|
1077
|
+
].filter(Boolean);
|
|
1078
|
+
for (const root of envRoots) {
|
|
1079
|
+
const candidate = resolve6(root, "packages/runtime/src/binary-build-worker.ts");
|
|
1080
|
+
if (existsSync6(candidate)) {
|
|
1081
|
+
return candidate;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
const localCandidate = resolve6(import.meta.dir, "binary-build-worker.ts");
|
|
1085
|
+
return existsSync6(localCandidate) ? localCandidate : null;
|
|
1086
|
+
}
|
|
1087
|
+
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
1088
|
+
const bunPath = Bun.which("bun");
|
|
1089
|
+
if (bunPath) {
|
|
1090
|
+
return { command: bunPath, env: {} };
|
|
1091
|
+
}
|
|
1092
|
+
if (process.execPath?.trim()) {
|
|
1093
|
+
return {
|
|
1094
|
+
command: process.execPath,
|
|
1095
|
+
env: { BUN_BE_BUN: "1" }
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
throw new Error("bun is required to run the runtime binary build worker.");
|
|
1099
|
+
}
|
|
1100
|
+
function currentCompileTarget() {
|
|
1101
|
+
if (process.platform === "darwin") {
|
|
1102
|
+
return process.arch === "arm64" ? "bun-darwin-arm64" : "bun-darwin-x64";
|
|
1103
|
+
}
|
|
1104
|
+
if (process.platform === "linux") {
|
|
1105
|
+
return process.arch === "arm64" ? "bun-linux-arm64" : "bun-linux-x64";
|
|
1106
|
+
}
|
|
1107
|
+
return "bun-windows-x64";
|
|
1108
|
+
}
|
|
1109
|
+
function createRuntimeBinaryBuildKey(input) {
|
|
1110
|
+
return JSON.stringify({
|
|
1111
|
+
version: 1,
|
|
1112
|
+
bunVersion: Bun.version,
|
|
1113
|
+
platform: process.platform,
|
|
1114
|
+
arch: process.arch,
|
|
1115
|
+
entrypoint: input.entrypoint,
|
|
1116
|
+
define: sortRecord(input.define),
|
|
1117
|
+
env: sortRecord(input.env)
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
async function isRuntimeBinaryBuildFresh(input) {
|
|
1121
|
+
if (!existsSync6(input.outputPath) || !existsSync6(input.manifestPath)) {
|
|
1122
|
+
return false;
|
|
1123
|
+
}
|
|
1124
|
+
let manifest = null;
|
|
1125
|
+
try {
|
|
1126
|
+
manifest = await Bun.file(input.manifestPath).json();
|
|
1127
|
+
} catch {
|
|
1128
|
+
return false;
|
|
1129
|
+
}
|
|
1130
|
+
if (!manifest || manifest.version !== 1 || manifest.buildKey !== input.buildKey) {
|
|
1131
|
+
return false;
|
|
1132
|
+
}
|
|
1133
|
+
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
1134
|
+
if (!existsSync6(filePath)) {
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1137
|
+
if (await sha256File3(filePath) !== expectedDigest) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
return true;
|
|
1142
|
+
}
|
|
1143
|
+
async function writeRuntimeBinaryCacheManifest(input) {
|
|
1144
|
+
const inputs = {};
|
|
1145
|
+
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
1146
|
+
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
1147
|
+
if (!normalized || !existsSync6(normalized)) {
|
|
1148
|
+
continue;
|
|
1149
|
+
}
|
|
1150
|
+
inputs[normalized] = await sha256File3(normalized);
|
|
1151
|
+
}
|
|
1152
|
+
const manifest = {
|
|
1153
|
+
version: 1,
|
|
1154
|
+
buildKey: input.buildKey,
|
|
1155
|
+
inputs
|
|
1156
|
+
};
|
|
1157
|
+
await Bun.write(input.manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
1158
|
+
`);
|
|
1159
|
+
}
|
|
1160
|
+
function normalizeBuildInputPath(cwd, inputPath) {
|
|
1161
|
+
if (!inputPath) {
|
|
1162
|
+
return null;
|
|
1163
|
+
}
|
|
1164
|
+
if (inputPath.startsWith("file://")) {
|
|
1165
|
+
return fileURLToPath(inputPath);
|
|
1166
|
+
}
|
|
1167
|
+
if (inputPath.startsWith("<")) {
|
|
1168
|
+
return null;
|
|
1169
|
+
}
|
|
1170
|
+
return resolve6(cwd, inputPath);
|
|
1171
|
+
}
|
|
1172
|
+
async function sha256File3(path) {
|
|
1173
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
1174
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
1175
|
+
return hasher.digest("hex");
|
|
1176
|
+
}
|
|
1177
|
+
function sortRecord(value) {
|
|
1178
|
+
if (!value) {
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
|
|
1182
|
+
}
|
|
1183
|
+
async function runSerializedRuntimeBinaryBuild(action) {
|
|
1184
|
+
const previous = runtimeBinaryBuildQueue;
|
|
1185
|
+
let release;
|
|
1186
|
+
runtimeBinaryBuildQueue = new Promise((resolve7) => {
|
|
1187
|
+
release = resolve7;
|
|
1188
|
+
});
|
|
1189
|
+
await previous;
|
|
1190
|
+
try {
|
|
1191
|
+
return await action();
|
|
1192
|
+
} finally {
|
|
1193
|
+
release();
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
async function withTemporaryEnv(env, action) {
|
|
1197
|
+
if (!env) {
|
|
1198
|
+
return action();
|
|
1199
|
+
}
|
|
1200
|
+
const previousValues = new Map;
|
|
1201
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1202
|
+
previousValues.set(key, process.env[key]);
|
|
1203
|
+
if (value === undefined) {
|
|
1204
|
+
delete process.env[key];
|
|
1205
|
+
} else {
|
|
1206
|
+
process.env[key] = value;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
try {
|
|
1210
|
+
return await action();
|
|
1211
|
+
} finally {
|
|
1212
|
+
for (const [key, value] of previousValues.entries()) {
|
|
1213
|
+
if (value === undefined) {
|
|
1214
|
+
delete process.env[key];
|
|
1215
|
+
} else {
|
|
1216
|
+
process.env[key] = value;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
async function withTemporaryCwd(cwd, action) {
|
|
1222
|
+
const previousCwd = process.cwd();
|
|
1223
|
+
process.chdir(cwd);
|
|
1224
|
+
try {
|
|
1225
|
+
return await action();
|
|
1226
|
+
} finally {
|
|
1227
|
+
process.chdir(previousCwd);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
|
|
1232
|
+
var sharedRouterOutputDir = resolve7(tmpdir3(), "rig-native");
|
|
1233
|
+
var sharedRouterOutputPath = resolve7(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
|
|
1234
|
+
function runtimeClaudeToolRouterFileName() {
|
|
1235
|
+
return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
|
|
1236
|
+
}
|
|
1237
|
+
async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
|
|
1238
|
+
const sourcePath = resolve7(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
|
|
1239
|
+
mkdirSync5(dirname4(outputPath), { recursive: true });
|
|
1240
|
+
const needsBuild = !existsSync7(outputPath) || statSync3(sourcePath).mtimeMs > statSync3(outputPath).mtimeMs;
|
|
1241
|
+
if (!needsBuild) {
|
|
1242
|
+
return outputPath;
|
|
1243
|
+
}
|
|
1244
|
+
await buildRuntimeBinary({
|
|
1245
|
+
sourcePath: "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts",
|
|
1246
|
+
outputPath,
|
|
1247
|
+
cwd: projectRoot
|
|
1248
|
+
});
|
|
1249
|
+
chmodSync4(outputPath, 493);
|
|
1250
|
+
return outputPath;
|
|
1251
|
+
}
|
|
1252
|
+
async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
|
|
1253
|
+
const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
|
|
1254
|
+
const targetPath = resolve7(targetDir, runtimeClaudeToolRouterFileName());
|
|
1255
|
+
mkdirSync5(targetDir, { recursive: true });
|
|
1256
|
+
const needsCopy = !existsSync7(targetPath) || statSync3(sourcePath).mtimeMs > statSync3(targetPath).mtimeMs;
|
|
1257
|
+
if (needsCopy) {
|
|
1258
|
+
copyFileSync3(sourcePath, targetPath);
|
|
1259
|
+
chmodSync4(targetPath, 493);
|
|
1260
|
+
}
|
|
1261
|
+
return targetPath;
|
|
1262
|
+
}
|
|
1263
|
+
export {
|
|
1264
|
+
writeClaudeRuntimeToolRouterConfig,
|
|
1265
|
+
shellBinaryBasename,
|
|
1266
|
+
runtimeToolGatewayNames,
|
|
1267
|
+
runtimeRigToolsFileName,
|
|
1268
|
+
runtimeRigShellFileName,
|
|
1269
|
+
runtimeGatewayToolNames,
|
|
1270
|
+
runtimeFileToolNames,
|
|
1271
|
+
runtimeFileToolBasename,
|
|
1272
|
+
runtimeClaudeToolRouterFileName,
|
|
1273
|
+
runtimeBrowserToolNames,
|
|
1274
|
+
runtimeBrowserToolBinaryName,
|
|
1275
|
+
runClaudeToolRouterServer,
|
|
1276
|
+
materializeRuntimeToolGateway,
|
|
1277
|
+
materializeRuntimeFileTools,
|
|
1278
|
+
materializeRuntimeBrowserTools,
|
|
1279
|
+
materializeRigShellBinary,
|
|
1280
|
+
materializeClaudeToolRouterBinary,
|
|
1281
|
+
invokeRuntimeTool,
|
|
1282
|
+
ensureRigToolsBinaryPath,
|
|
1283
|
+
ensureRigShellBinaryPath,
|
|
1284
|
+
ensureClaudeToolRouterBinaryPath,
|
|
1285
|
+
codexRuntimeToolCliArgs,
|
|
1286
|
+
claudeRuntimeToolCliArgs,
|
|
1287
|
+
CLAUDE_ROUTER_TOOL_DEFINITIONS,
|
|
1288
|
+
CLAUDE_ROUTER_SERVER_NAME,
|
|
1289
|
+
CLAUDE_DISABLED_FILE_TOOLS
|
|
1290
|
+
};
|