@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,540 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/binary-run.ts
|
|
3
|
+
import { spawn as nodeSpawn } from "child_process";
|
|
4
|
+
import { chmodSync, cpSync, existsSync as existsSync2, mkdirSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
5
|
+
import { basename as basename2, dirname as dirname2, resolve as resolve2 } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { drainMicrotasks, gcAndSweep } from "bun:jsc";
|
|
8
|
+
|
|
9
|
+
// packages/runtime/src/layout.ts
|
|
10
|
+
import { existsSync } from "fs";
|
|
11
|
+
import { basename, dirname, resolve } from "path";
|
|
12
|
+
var RIG_DEFINITION_DIRNAME = "rig";
|
|
13
|
+
var RIG_ARTIFACTS_DIRNAME = "artifacts";
|
|
14
|
+
function resolveMonorepoRoot(projectRoot) {
|
|
15
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
16
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
17
|
+
if (explicit) {
|
|
18
|
+
const explicitRoot = resolve(explicit);
|
|
19
|
+
const explicitParent = dirname(explicitRoot);
|
|
20
|
+
if (basename(explicitParent) === ".worktrees") {
|
|
21
|
+
const owner = dirname(explicitParent);
|
|
22
|
+
const ownerHasGit = existsSync(resolve(owner, ".git"));
|
|
23
|
+
const ownerHasTaskConfig = existsSync(resolve(owner, ".rig", "task-config.json"));
|
|
24
|
+
const ownerHasRigConfig = existsSync(resolve(owner, "rig.config.ts"));
|
|
25
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
26
|
+
return owner;
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
|
|
29
|
+
}
|
|
30
|
+
if (!existsSync(resolve(explicitRoot, ".git"))) {
|
|
31
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
|
|
32
|
+
}
|
|
33
|
+
const hasTaskConfig = existsSync(resolve(explicitRoot, ".rig", "task-config.json"));
|
|
34
|
+
const hasRigConfig = existsSync(resolve(explicitRoot, "rig.config.ts"));
|
|
35
|
+
if (!hasTaskConfig && !hasRigConfig) {
|
|
36
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
|
|
37
|
+
}
|
|
38
|
+
return explicitRoot;
|
|
39
|
+
}
|
|
40
|
+
const projectParent = dirname(normalizedProjectRoot);
|
|
41
|
+
if (basename(projectParent) === ".worktrees") {
|
|
42
|
+
const worktreeOwner = dirname(projectParent);
|
|
43
|
+
const ownerHasGit = existsSync(resolve(worktreeOwner, ".git"));
|
|
44
|
+
const ownerHasTaskConfig = existsSync(resolve(worktreeOwner, ".rig", "task-config.json"));
|
|
45
|
+
const ownerHasRigConfig = existsSync(resolve(worktreeOwner, "rig.config.ts"));
|
|
46
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
47
|
+
return worktreeOwner;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return normalizedProjectRoot;
|
|
51
|
+
}
|
|
52
|
+
function resolveRuntimeWorkspaceLayout(workspaceDir) {
|
|
53
|
+
const root = resolve(workspaceDir);
|
|
54
|
+
const rigRoot = resolve(root, ".rig");
|
|
55
|
+
const logsDir = resolve(rigRoot, "logs");
|
|
56
|
+
const stateDir = resolve(rigRoot, "state");
|
|
57
|
+
const runtimeDir = resolve(rigRoot, "runtime");
|
|
58
|
+
const binDir = resolve(rigRoot, "bin");
|
|
59
|
+
return {
|
|
60
|
+
workspaceDir: root,
|
|
61
|
+
rigRoot,
|
|
62
|
+
stateDir,
|
|
63
|
+
logsDir,
|
|
64
|
+
artifactsRoot: resolve(root, RIG_ARTIFACTS_DIRNAME),
|
|
65
|
+
runtimeDir,
|
|
66
|
+
homeDir: resolve(rigRoot, "home"),
|
|
67
|
+
tmpDir: resolve(rigRoot, "tmp"),
|
|
68
|
+
cacheDir: resolve(rigRoot, "cache"),
|
|
69
|
+
sessionDir: resolve(rigRoot, "session"),
|
|
70
|
+
binDir,
|
|
71
|
+
distDir: resolve(rigRoot, "dist"),
|
|
72
|
+
pluginBinDir: resolve(binDir, "plugins"),
|
|
73
|
+
contextPath: resolve(rigRoot, "runtime-context.json"),
|
|
74
|
+
controlPlaneEventsFile: resolve(logsDir, "control-plane.events.jsonl")
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function resolveActiveRuntimeWorkspaceRoot(monorepoRoot) {
|
|
78
|
+
const explicit = process.env.RIG_TASK_WORKSPACE?.trim();
|
|
79
|
+
if (!explicit) {
|
|
80
|
+
throw new Error("No active runtime workspace. Set RIG_TASK_WORKSPACE or provision a task runtime first.");
|
|
81
|
+
}
|
|
82
|
+
return resolve(explicit);
|
|
83
|
+
}
|
|
84
|
+
function resolveRigLayout(projectRoot) {
|
|
85
|
+
const monorepoRoot = resolveMonorepoRoot(projectRoot);
|
|
86
|
+
const definitionRoot = resolve(projectRoot, RIG_DEFINITION_DIRNAME);
|
|
87
|
+
const runtimeWorkspaceRoot = resolveActiveRuntimeWorkspaceRoot(monorepoRoot);
|
|
88
|
+
const runtimeLayout = resolveRuntimeWorkspaceLayout(runtimeWorkspaceRoot);
|
|
89
|
+
const policyDir = resolve(definitionRoot, "policy");
|
|
90
|
+
return {
|
|
91
|
+
projectRoot,
|
|
92
|
+
monorepoRoot,
|
|
93
|
+
definitionRoot,
|
|
94
|
+
runtimeWorkspaceRoot,
|
|
95
|
+
stateRoot: runtimeLayout.rigRoot,
|
|
96
|
+
artifactsRoot: runtimeLayout.artifactsRoot,
|
|
97
|
+
configPath: resolve(definitionRoot, "config.sh"),
|
|
98
|
+
taskConfigPath: resolve(runtimeWorkspaceRoot, ".rig", "task-config.json"),
|
|
99
|
+
policyDir,
|
|
100
|
+
policyFile: resolve(policyDir, "policy.json"),
|
|
101
|
+
pluginsDir: resolve(definitionRoot, "plugins"),
|
|
102
|
+
hooksDir: resolve(definitionRoot, "hooks"),
|
|
103
|
+
toolsDir: resolve(definitionRoot, "tools"),
|
|
104
|
+
templatesDir: resolve(definitionRoot, "templates"),
|
|
105
|
+
validationDir: resolve(definitionRoot, "validation"),
|
|
106
|
+
stateDir: runtimeLayout.stateDir,
|
|
107
|
+
logsDir: runtimeLayout.logsDir,
|
|
108
|
+
notificationsDir: resolve(definitionRoot, "notifications"),
|
|
109
|
+
runtimeDir: runtimeLayout.runtimeDir,
|
|
110
|
+
distDir: runtimeLayout.distDir,
|
|
111
|
+
binDir: runtimeLayout.binDir,
|
|
112
|
+
pluginBinDir: runtimeLayout.pluginBinDir,
|
|
113
|
+
keybindingsPath: resolve(definitionRoot, "keybindings.json"),
|
|
114
|
+
controlPlaneEventsFile: runtimeLayout.controlPlaneEventsFile
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// packages/runtime/src/binary-run.ts
|
|
119
|
+
var runtimeBinaryAssetEntries = [
|
|
120
|
+
"hooks",
|
|
121
|
+
"lib",
|
|
122
|
+
"tools",
|
|
123
|
+
"templates",
|
|
124
|
+
"policy",
|
|
125
|
+
"plugins",
|
|
126
|
+
"config.sh",
|
|
127
|
+
"task-config.json"
|
|
128
|
+
];
|
|
129
|
+
var runtimeBinaryBuildQueue = Promise.resolve();
|
|
130
|
+
function isRuntimeBinaryAssetEntry(value) {
|
|
131
|
+
return runtimeBinaryAssetEntries.includes(value);
|
|
132
|
+
}
|
|
133
|
+
function createRuntimeBinaryBuildManifest(input) {
|
|
134
|
+
return {
|
|
135
|
+
name: input.name ?? "project-rig-harness",
|
|
136
|
+
builtAt: input.builtAt ?? new Date().toISOString(),
|
|
137
|
+
gitHead: input.gitHead ?? "unknown",
|
|
138
|
+
bunVersion: input.bunVersion,
|
|
139
|
+
binaries: { ...input.binaries },
|
|
140
|
+
runtimeAssets: [...input.runtimeAssets ?? runtimeBinaryAssetEntries]
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
async function buildRuntimeBinary(options) {
|
|
144
|
+
return runSerializedRuntimeBinaryBuild(async () => {
|
|
145
|
+
const resolved = resolveRuntimeBinaryBuildOptions(options);
|
|
146
|
+
runBestEffortBuildGc();
|
|
147
|
+
const manifestPath = runtimeBinaryCacheManifestPath(resolved.outputPath);
|
|
148
|
+
const buildKey = createRuntimeBinaryBuildKey({
|
|
149
|
+
entrypoint: resolved.entrypoint,
|
|
150
|
+
define: resolved.define,
|
|
151
|
+
env: resolved.env
|
|
152
|
+
});
|
|
153
|
+
if (await isRuntimeBinaryBuildFresh({ outputPath: resolved.outputPath, manifestPath, buildKey })) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (shouldUseRuntimeBinaryBuildWorker()) {
|
|
157
|
+
await buildRuntimeBinaryViaWorker(resolved);
|
|
158
|
+
} else {
|
|
159
|
+
await buildRuntimeBinaryInProcess(resolved, { manifestPath, buildKey });
|
|
160
|
+
}
|
|
161
|
+
runBestEffortBuildGc();
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function buildRuntimeBinarySync(options) {
|
|
165
|
+
const resolved = resolveRuntimeBinaryBuildOptions(options);
|
|
166
|
+
runBestEffortBuildGc();
|
|
167
|
+
runRuntimeBinaryBuildWorkerSync(resolved);
|
|
168
|
+
runBestEffortBuildGc();
|
|
169
|
+
}
|
|
170
|
+
async function buildRuntimeBinaryInProcess(options, manifest) {
|
|
171
|
+
const tempBuildDir = resolve2(dirname2(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
172
|
+
const tempOutputPath = resolve2(tempBuildDir, basename2(options.outputPath));
|
|
173
|
+
mkdirSync(tempBuildDir, { recursive: true });
|
|
174
|
+
await withTemporaryEnv({
|
|
175
|
+
...options.env,
|
|
176
|
+
...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
|
|
177
|
+
}, async () => withTemporaryCwd(tempBuildDir, async () => {
|
|
178
|
+
const buildResult = await Bun.build({
|
|
179
|
+
entrypoints: [options.entrypoint],
|
|
180
|
+
compile: {
|
|
181
|
+
target: currentCompileTarget(),
|
|
182
|
+
outfile: tempOutputPath
|
|
183
|
+
},
|
|
184
|
+
target: "bun",
|
|
185
|
+
format: "esm",
|
|
186
|
+
minify: true,
|
|
187
|
+
bytecode: true,
|
|
188
|
+
metafile: true,
|
|
189
|
+
define: options.define ? {
|
|
190
|
+
__RIG_BUILD_CONFIG__: JSON.stringify(options.define)
|
|
191
|
+
} : undefined
|
|
192
|
+
});
|
|
193
|
+
if (!buildResult.success) {
|
|
194
|
+
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(`
|
|
195
|
+
`);
|
|
196
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
|
|
197
|
+
}
|
|
198
|
+
if (!existsSync2(tempOutputPath)) {
|
|
199
|
+
const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
|
|
200
|
+
throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
|
|
201
|
+
}
|
|
202
|
+
renameSync(tempOutputPath, options.outputPath);
|
|
203
|
+
chmodSync(options.outputPath, 493);
|
|
204
|
+
if (manifest) {
|
|
205
|
+
await writeRuntimeBinaryCacheManifest({
|
|
206
|
+
manifestPath: manifest.manifestPath,
|
|
207
|
+
buildKey: manifest.buildKey,
|
|
208
|
+
cwd: tempBuildDir,
|
|
209
|
+
metafile: buildResult.metafile
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
})).finally(() => {
|
|
213
|
+
rmSync(tempBuildDir, { recursive: true, force: true });
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function runBestEffortBuildGc() {
|
|
217
|
+
try {
|
|
218
|
+
drainMicrotasks();
|
|
219
|
+
} catch {}
|
|
220
|
+
try {
|
|
221
|
+
gcAndSweep();
|
|
222
|
+
} catch {}
|
|
223
|
+
}
|
|
224
|
+
function runtimeBinaryCacheManifestPath(outputPath) {
|
|
225
|
+
return `${outputPath}.build-manifest.json`;
|
|
226
|
+
}
|
|
227
|
+
function resolveRuntimeBinaryBuildOptions(options) {
|
|
228
|
+
return {
|
|
229
|
+
...options,
|
|
230
|
+
entrypoint: resolve2(options.cwd, options.sourcePath),
|
|
231
|
+
outputPath: resolve2(options.outputPath)
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function shouldUseRuntimeBinaryBuildWorker() {
|
|
235
|
+
if (process.env.RIG_RUNTIME_BUILD_WORKER === "1") {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
if (process.env.RIG_RUNTIME_BUILD_IN_PROCESS === "1") {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
async function buildRuntimeBinaryViaWorker(options) {
|
|
244
|
+
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
245
|
+
if (!workerSourcePath || !existsSync2(workerSourcePath)) {
|
|
246
|
+
await buildRuntimeBinaryInProcess(options, {
|
|
247
|
+
manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
|
|
248
|
+
buildKey: createRuntimeBinaryBuildKey({
|
|
249
|
+
entrypoint: options.entrypoint,
|
|
250
|
+
define: options.define,
|
|
251
|
+
env: options.env
|
|
252
|
+
})
|
|
253
|
+
});
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const payloadPath = createRuntimeBinaryBuildWorkerPayloadPath(options.outputPath);
|
|
257
|
+
const bunCli = resolveRuntimeBinaryBuildWorkerInvocation();
|
|
258
|
+
await Bun.write(payloadPath, `${JSON.stringify(options)}
|
|
259
|
+
`);
|
|
260
|
+
const build = Bun.spawn([bunCli.command, workerSourcePath, payloadPath], {
|
|
261
|
+
cwd: options.cwd,
|
|
262
|
+
stdout: "pipe",
|
|
263
|
+
stderr: "pipe",
|
|
264
|
+
env: {
|
|
265
|
+
...process.env,
|
|
266
|
+
...options.env,
|
|
267
|
+
...bunCli.env,
|
|
268
|
+
RIG_RUNTIME_BUILD_WORKER: "1"
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
272
|
+
build.exited,
|
|
273
|
+
new Response(build.stdout).text(),
|
|
274
|
+
new Response(build.stderr).text()
|
|
275
|
+
]);
|
|
276
|
+
rmSync(payloadPath, { force: true });
|
|
277
|
+
if (exitCode !== 0) {
|
|
278
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function runRuntimeBinaryBuildWorkerSync(options) {
|
|
282
|
+
const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
|
|
283
|
+
if (!workerSourcePath || !existsSync2(workerSourcePath)) {
|
|
284
|
+
throw new Error(`Failed to build ${options.entrypoint}: runtime binary build worker not found`);
|
|
285
|
+
}
|
|
286
|
+
const payloadPath = createRuntimeBinaryBuildWorkerPayloadPath(options.outputPath);
|
|
287
|
+
const bunCli = resolveRuntimeBinaryBuildWorkerInvocation();
|
|
288
|
+
try {
|
|
289
|
+
writeFileSync(payloadPath, `${JSON.stringify(options)}
|
|
290
|
+
`, "utf-8");
|
|
291
|
+
const result = Bun.spawnSync([bunCli.command, workerSourcePath, payloadPath], {
|
|
292
|
+
cwd: options.cwd,
|
|
293
|
+
stdout: "pipe",
|
|
294
|
+
stderr: "pipe",
|
|
295
|
+
env: {
|
|
296
|
+
...process.env,
|
|
297
|
+
...options.env,
|
|
298
|
+
...bunCli.env,
|
|
299
|
+
RIG_RUNTIME_BUILD_WORKER: "1"
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
if (result.exitCode !== 0) {
|
|
303
|
+
const stderr = result.stderr.toString();
|
|
304
|
+
const stdout = result.stdout.toString();
|
|
305
|
+
throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${result.exitCode}`).trim()}`);
|
|
306
|
+
}
|
|
307
|
+
} finally {
|
|
308
|
+
rmSync(payloadPath, { force: true });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
|
|
312
|
+
return resolve2(dirname2(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
313
|
+
}
|
|
314
|
+
function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
|
|
315
|
+
const envRoots = [
|
|
316
|
+
options.cwd?.trim(),
|
|
317
|
+
process.env.RIG_HOST_PROJECT_ROOT?.trim(),
|
|
318
|
+
process.env.PROJECT_RIG_ROOT?.trim()
|
|
319
|
+
].filter(Boolean);
|
|
320
|
+
for (const root of envRoots) {
|
|
321
|
+
const candidate = resolve2(root, "packages/runtime/src/binary-build-worker.ts");
|
|
322
|
+
if (existsSync2(candidate)) {
|
|
323
|
+
return candidate;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const localCandidate = resolve2(import.meta.dir, "binary-build-worker.ts");
|
|
327
|
+
return existsSync2(localCandidate) ? localCandidate : null;
|
|
328
|
+
}
|
|
329
|
+
function resolveRuntimeBinaryBuildWorkerInvocation() {
|
|
330
|
+
const bunPath = Bun.which("bun");
|
|
331
|
+
if (bunPath) {
|
|
332
|
+
return { command: bunPath, env: {} };
|
|
333
|
+
}
|
|
334
|
+
if (process.execPath?.trim()) {
|
|
335
|
+
return {
|
|
336
|
+
command: process.execPath,
|
|
337
|
+
env: { BUN_BE_BUN: "1" }
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
throw new Error("bun is required to run the runtime binary build worker.");
|
|
341
|
+
}
|
|
342
|
+
function currentCompileTarget() {
|
|
343
|
+
if (process.platform === "darwin") {
|
|
344
|
+
return process.arch === "arm64" ? "bun-darwin-arm64" : "bun-darwin-x64";
|
|
345
|
+
}
|
|
346
|
+
if (process.platform === "linux") {
|
|
347
|
+
return process.arch === "arm64" ? "bun-linux-arm64" : "bun-linux-x64";
|
|
348
|
+
}
|
|
349
|
+
return "bun-windows-x64";
|
|
350
|
+
}
|
|
351
|
+
function createRuntimeBinaryBuildKey(input) {
|
|
352
|
+
return JSON.stringify({
|
|
353
|
+
version: 1,
|
|
354
|
+
bunVersion: Bun.version,
|
|
355
|
+
platform: process.platform,
|
|
356
|
+
arch: process.arch,
|
|
357
|
+
entrypoint: input.entrypoint,
|
|
358
|
+
define: sortRecord(input.define),
|
|
359
|
+
env: sortRecord(input.env)
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async function isRuntimeBinaryBuildFresh(input) {
|
|
363
|
+
if (!existsSync2(input.outputPath) || !existsSync2(input.manifestPath)) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
let manifest = null;
|
|
367
|
+
try {
|
|
368
|
+
manifest = await Bun.file(input.manifestPath).json();
|
|
369
|
+
} catch {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
if (!manifest || manifest.version !== 1 || manifest.buildKey !== input.buildKey) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
|
|
376
|
+
if (!existsSync2(filePath)) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
if (await sha256File(filePath) !== expectedDigest) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
async function writeRuntimeBinaryCacheManifest(input) {
|
|
386
|
+
const inputs = {};
|
|
387
|
+
for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
|
|
388
|
+
const normalized = normalizeBuildInputPath(input.cwd, inputPath);
|
|
389
|
+
if (!normalized || !existsSync2(normalized)) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
inputs[normalized] = await sha256File(normalized);
|
|
393
|
+
}
|
|
394
|
+
const manifest = {
|
|
395
|
+
version: 1,
|
|
396
|
+
buildKey: input.buildKey,
|
|
397
|
+
inputs
|
|
398
|
+
};
|
|
399
|
+
await Bun.write(input.manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
400
|
+
`);
|
|
401
|
+
}
|
|
402
|
+
function normalizeBuildInputPath(cwd, inputPath) {
|
|
403
|
+
if (!inputPath) {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
if (inputPath.startsWith("file://")) {
|
|
407
|
+
return fileURLToPath(inputPath);
|
|
408
|
+
}
|
|
409
|
+
if (inputPath.startsWith("<")) {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
return resolve2(cwd, inputPath);
|
|
413
|
+
}
|
|
414
|
+
async function sha256File(path) {
|
|
415
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
416
|
+
hasher.update(await Bun.file(path).arrayBuffer());
|
|
417
|
+
return hasher.digest("hex");
|
|
418
|
+
}
|
|
419
|
+
function sortRecord(value) {
|
|
420
|
+
if (!value) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
|
|
424
|
+
}
|
|
425
|
+
async function runSerializedRuntimeBinaryBuild(action) {
|
|
426
|
+
const previous = runtimeBinaryBuildQueue;
|
|
427
|
+
let release;
|
|
428
|
+
runtimeBinaryBuildQueue = new Promise((resolve3) => {
|
|
429
|
+
release = resolve3;
|
|
430
|
+
});
|
|
431
|
+
await previous;
|
|
432
|
+
try {
|
|
433
|
+
return await action();
|
|
434
|
+
} finally {
|
|
435
|
+
release();
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
async function withTemporaryEnv(env, action) {
|
|
439
|
+
if (!env) {
|
|
440
|
+
return action();
|
|
441
|
+
}
|
|
442
|
+
const previousValues = new Map;
|
|
443
|
+
for (const [key, value] of Object.entries(env)) {
|
|
444
|
+
previousValues.set(key, process.env[key]);
|
|
445
|
+
if (value === undefined) {
|
|
446
|
+
delete process.env[key];
|
|
447
|
+
} else {
|
|
448
|
+
process.env[key] = value;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
try {
|
|
452
|
+
return await action();
|
|
453
|
+
} finally {
|
|
454
|
+
for (const [key, value] of previousValues.entries()) {
|
|
455
|
+
if (value === undefined) {
|
|
456
|
+
delete process.env[key];
|
|
457
|
+
} else {
|
|
458
|
+
process.env[key] = value;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
async function withTemporaryCwd(cwd, action) {
|
|
464
|
+
const previousCwd = process.cwd();
|
|
465
|
+
process.chdir(cwd);
|
|
466
|
+
try {
|
|
467
|
+
return await action();
|
|
468
|
+
} finally {
|
|
469
|
+
process.chdir(previousCwd);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function copyRuntimeBinaryAssets(options) {
|
|
473
|
+
const definitionRoot = options.rigDir ?? resolveRigLayout(options.projectRoot).definitionRoot;
|
|
474
|
+
const runtimeDir = resolve2(options.outputDir, "runtime", "rig");
|
|
475
|
+
mkdirSync(runtimeDir, { recursive: true });
|
|
476
|
+
const copiedEntries = [];
|
|
477
|
+
for (const entry of options.entries ?? runtimeBinaryAssetEntries) {
|
|
478
|
+
const source = resolve2(definitionRoot, entry);
|
|
479
|
+
if (!existsSync2(source)) {
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
cpSync(source, resolve2(runtimeDir, entry), { recursive: true });
|
|
483
|
+
copiedEntries.push(entry);
|
|
484
|
+
}
|
|
485
|
+
return { copiedEntries, runtimeDir };
|
|
486
|
+
}
|
|
487
|
+
async function launchRuntimeBinary(request) {
|
|
488
|
+
const options = {
|
|
489
|
+
cwd: request.cwd,
|
|
490
|
+
env: request.env ? { ...process.env, ...request.env } : process.env
|
|
491
|
+
};
|
|
492
|
+
if (request.timeoutMs !== undefined) {
|
|
493
|
+
options.timeoutMs = request.timeoutMs;
|
|
494
|
+
}
|
|
495
|
+
return spawnProcess(request.binaryPath, request.args, options);
|
|
496
|
+
}
|
|
497
|
+
async function spawnProcess(command, args, options) {
|
|
498
|
+
const child = nodeSpawn(command, args, {
|
|
499
|
+
cwd: options.cwd,
|
|
500
|
+
env: options.env,
|
|
501
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
502
|
+
});
|
|
503
|
+
let stdout = "";
|
|
504
|
+
let stderr = "";
|
|
505
|
+
child.stdout?.setEncoding("utf8");
|
|
506
|
+
child.stderr?.setEncoding("utf8");
|
|
507
|
+
child.stdout?.on("data", (chunk) => {
|
|
508
|
+
stdout += chunk;
|
|
509
|
+
});
|
|
510
|
+
child.stderr?.on("data", (chunk) => {
|
|
511
|
+
stderr += chunk;
|
|
512
|
+
});
|
|
513
|
+
let timedOut = false;
|
|
514
|
+
let timer;
|
|
515
|
+
const exitCode = await new Promise((resolveExit, rejectExit) => {
|
|
516
|
+
if (options.timeoutMs && options.timeoutMs > 0) {
|
|
517
|
+
timer = setTimeout(() => {
|
|
518
|
+
timedOut = true;
|
|
519
|
+
child.kill();
|
|
520
|
+
}, options.timeoutMs);
|
|
521
|
+
}
|
|
522
|
+
child.once("error", rejectExit);
|
|
523
|
+
child.once("close", (code) => resolveExit(code ?? (timedOut ? 1 : 0)));
|
|
524
|
+
}).finally(() => {
|
|
525
|
+
if (timer) {
|
|
526
|
+
clearTimeout(timer);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
return { exitCode, stdout, stderr, timedOut };
|
|
530
|
+
}
|
|
531
|
+
export {
|
|
532
|
+
runtimeBinaryAssetEntries,
|
|
533
|
+
launchRuntimeBinary,
|
|
534
|
+
isRuntimeBinaryAssetEntry,
|
|
535
|
+
createRuntimeBinaryBuildManifest,
|
|
536
|
+
copyRuntimeBinaryAssets,
|
|
537
|
+
buildRuntimeBinarySync,
|
|
538
|
+
buildRuntimeBinaryInProcess,
|
|
539
|
+
buildRuntimeBinary
|
|
540
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// @bun
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/build-time-config.ts
|
|
3
|
+
function normalizeBuildConfig(value) {
|
|
4
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5
|
+
return {};
|
|
6
|
+
}
|
|
7
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
|
|
8
|
+
}
|
|
9
|
+
function readBuildConfig() {
|
|
10
|
+
if (typeof __RIG_BUILD_CONFIG__ !== "undefined") {
|
|
11
|
+
return normalizeBuildConfig(__RIG_BUILD_CONFIG__);
|
|
12
|
+
}
|
|
13
|
+
const raw = process.env.RIG_BUILD_CONFIG_JSON?.trim();
|
|
14
|
+
if (!raw) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
return normalizeBuildConfig(JSON.parse(raw));
|
|
19
|
+
} catch {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
readBuildConfig
|
|
25
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/agent-roles.ts
|
|
3
|
+
function createAgentRoleRegistry(pluginRoles, configOverrides) {
|
|
4
|
+
const map = new Map;
|
|
5
|
+
for (const r of pluginRoles) {
|
|
6
|
+
if (map.has(r.id))
|
|
7
|
+
throw new Error(`agent role already registered: ${r.id}`);
|
|
8
|
+
const override = configOverrides?.[r.id];
|
|
9
|
+
const model = override?.model ?? r.defaultModel;
|
|
10
|
+
if (!model) {
|
|
11
|
+
throw new Error(`agent role "${r.id}" has no model \u2014 provide defaultModel in plugin or model in config.runtime.agentRoles.${r.id}`);
|
|
12
|
+
}
|
|
13
|
+
map.set(r.id, { ...r, model });
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
resolve(id) {
|
|
17
|
+
const r = map.get(id);
|
|
18
|
+
if (!r)
|
|
19
|
+
throw new Error(`agent role not registered: ${id}`);
|
|
20
|
+
return r;
|
|
21
|
+
},
|
|
22
|
+
list: () => Array.from(map.values())
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
createAgentRoleRegistry
|
|
27
|
+
};
|