@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,137 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
3
|
+
import { existsSync as existsSync2, readdirSync, realpathSync } from "fs";
|
|
4
|
+
import { resolve as resolve2 } from "path";
|
|
5
|
+
|
|
6
|
+
// packages/runtime/src/layout.ts
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { basename, dirname, resolve } from "path";
|
|
9
|
+
function resolveMonorepoRoot(projectRoot) {
|
|
10
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
11
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
12
|
+
if (explicit) {
|
|
13
|
+
const explicitRoot = resolve(explicit);
|
|
14
|
+
const explicitParent = dirname(explicitRoot);
|
|
15
|
+
if (basename(explicitParent) === ".worktrees") {
|
|
16
|
+
const owner = dirname(explicitParent);
|
|
17
|
+
const ownerHasGit = existsSync(resolve(owner, ".git"));
|
|
18
|
+
const ownerHasTaskConfig = existsSync(resolve(owner, ".rig", "task-config.json"));
|
|
19
|
+
const ownerHasRigConfig = existsSync(resolve(owner, "rig.config.ts"));
|
|
20
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
21
|
+
return owner;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
|
|
24
|
+
}
|
|
25
|
+
if (!existsSync(resolve(explicitRoot, ".git"))) {
|
|
26
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
|
|
27
|
+
}
|
|
28
|
+
const hasTaskConfig = existsSync(resolve(explicitRoot, ".rig", "task-config.json"));
|
|
29
|
+
const hasRigConfig = existsSync(resolve(explicitRoot, "rig.config.ts"));
|
|
30
|
+
if (!hasTaskConfig && !hasRigConfig) {
|
|
31
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
|
|
32
|
+
}
|
|
33
|
+
return explicitRoot;
|
|
34
|
+
}
|
|
35
|
+
const projectParent = dirname(normalizedProjectRoot);
|
|
36
|
+
if (basename(projectParent) === ".worktrees") {
|
|
37
|
+
const worktreeOwner = dirname(projectParent);
|
|
38
|
+
const ownerHasGit = existsSync(resolve(worktreeOwner, ".git"));
|
|
39
|
+
const ownerHasTaskConfig = existsSync(resolve(worktreeOwner, ".rig", "task-config.json"));
|
|
40
|
+
const ownerHasRigConfig = existsSync(resolve(worktreeOwner, "rig.config.ts"));
|
|
41
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
42
|
+
return worktreeOwner;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return normalizedProjectRoot;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
49
|
+
function toRealPath(path) {
|
|
50
|
+
if (!existsSync2(path)) {
|
|
51
|
+
return resolve2(path);
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
return realpathSync.native(path);
|
|
55
|
+
} catch {
|
|
56
|
+
return resolve2(path);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
60
|
+
const candidates = new Set;
|
|
61
|
+
const addPath = (candidate) => {
|
|
62
|
+
if (existsSync2(candidate)) {
|
|
63
|
+
candidates.add(toRealPath(candidate));
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
addPath(resolve2(projectRoot, ".git"));
|
|
67
|
+
addPath(resolve2(workspaceDir, "..", "..", ".git"));
|
|
68
|
+
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
69
|
+
addPath(resolve2(repoRoot, ".git"));
|
|
70
|
+
}
|
|
71
|
+
const workspaceGit = resolve2(workspaceDir, ".git");
|
|
72
|
+
if (existsSync2(workspaceGit)) {
|
|
73
|
+
addPath(workspaceGit);
|
|
74
|
+
}
|
|
75
|
+
return [...candidates];
|
|
76
|
+
}
|
|
77
|
+
function resolveHostRepoRootPaths(projectRoot) {
|
|
78
|
+
const candidates = new Set;
|
|
79
|
+
const addPath = (candidate) => {
|
|
80
|
+
if (existsSync2(candidate)) {
|
|
81
|
+
candidates.add(toRealPath(candidate));
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
try {
|
|
85
|
+
const monorepoRoot = resolveMonorepoRoot(projectRoot);
|
|
86
|
+
if (toRealPath(monorepoRoot) !== toRealPath(projectRoot)) {
|
|
87
|
+
addPath(monorepoRoot);
|
|
88
|
+
}
|
|
89
|
+
} catch {}
|
|
90
|
+
const reposDir = resolve2(projectRoot, "repos");
|
|
91
|
+
if (existsSync2(reposDir)) {
|
|
92
|
+
for (const entry of readdirSync(reposDir, { withFileTypes: true })) {
|
|
93
|
+
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
94
|
+
addPath(resolve2(reposDir, entry.name));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return [...candidates];
|
|
99
|
+
}
|
|
100
|
+
function resolveNetworkWithPolicy(sandboxConfig, envOverride) {
|
|
101
|
+
if (envOverride) {
|
|
102
|
+
const envValue = parseBooleanEnv(envOverride, sandboxConfig.network);
|
|
103
|
+
if (envValue !== sandboxConfig.network) {
|
|
104
|
+
console.warn(`[sandbox] RIG_RUNTIME_SANDBOX_NETWORK=${envOverride} overrides policy sandbox.network=${sandboxConfig.network}`);
|
|
105
|
+
}
|
|
106
|
+
return envValue;
|
|
107
|
+
}
|
|
108
|
+
return sandboxConfig.network;
|
|
109
|
+
}
|
|
110
|
+
function parseBooleanEnv(raw, fallback) {
|
|
111
|
+
if (!raw) {
|
|
112
|
+
return fallback;
|
|
113
|
+
}
|
|
114
|
+
const normalized = raw.trim().toLowerCase();
|
|
115
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return fallback;
|
|
122
|
+
}
|
|
123
|
+
function uniq(values) {
|
|
124
|
+
return [...new Set(values)];
|
|
125
|
+
}
|
|
126
|
+
function seatbeltString(value) {
|
|
127
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
uniq,
|
|
131
|
+
toRealPath,
|
|
132
|
+
seatbeltString,
|
|
133
|
+
resolveNetworkWithPolicy,
|
|
134
|
+
resolveHostRepoRootPaths,
|
|
135
|
+
resolveHostGitMetadataPaths,
|
|
136
|
+
parseBooleanEnv
|
|
137
|
+
};
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// packages/runtime/src/control-plane/runtime/sandbox/backend-bwrap.ts
|
|
5
|
+
import { mkdirSync } from "fs";
|
|
6
|
+
import { resolve as resolve3 } from "path";
|
|
7
|
+
|
|
8
|
+
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
9
|
+
import { existsSync as existsSync2, readdirSync, realpathSync } from "fs";
|
|
10
|
+
import { resolve as resolve2 } from "path";
|
|
11
|
+
|
|
12
|
+
// packages/runtime/src/layout.ts
|
|
13
|
+
import { existsSync } from "fs";
|
|
14
|
+
import { basename, dirname, resolve } from "path";
|
|
15
|
+
function resolveMonorepoRoot(projectRoot) {
|
|
16
|
+
const normalizedProjectRoot = resolve(projectRoot);
|
|
17
|
+
const explicit = process.env.MONOREPO_ROOT?.trim();
|
|
18
|
+
if (explicit) {
|
|
19
|
+
const explicitRoot = resolve(explicit);
|
|
20
|
+
const explicitParent = dirname(explicitRoot);
|
|
21
|
+
if (basename(explicitParent) === ".worktrees") {
|
|
22
|
+
const owner = dirname(explicitParent);
|
|
23
|
+
const ownerHasGit = existsSync(resolve(owner, ".git"));
|
|
24
|
+
const ownerHasTaskConfig = existsSync(resolve(owner, ".rig", "task-config.json"));
|
|
25
|
+
const ownerHasRigConfig = existsSync(resolve(owner, "rig.config.ts"));
|
|
26
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
27
|
+
return owner;
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`MONOREPO_ROOT points to worktree ${explicitRoot}, but the owner checkout is incomplete at ${owner}.`);
|
|
30
|
+
}
|
|
31
|
+
if (!existsSync(resolve(explicitRoot, ".git"))) {
|
|
32
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but no git checkout was found there.`);
|
|
33
|
+
}
|
|
34
|
+
const hasTaskConfig = existsSync(resolve(explicitRoot, ".rig", "task-config.json"));
|
|
35
|
+
const hasRigConfig = existsSync(resolve(explicitRoot, "rig.config.ts"));
|
|
36
|
+
if (!hasTaskConfig && !hasRigConfig) {
|
|
37
|
+
throw new Error(`MONOREPO_ROOT points to ${explicitRoot}, but neither .rig/task-config.json nor rig.config.ts exists there.`);
|
|
38
|
+
}
|
|
39
|
+
return explicitRoot;
|
|
40
|
+
}
|
|
41
|
+
const projectParent = dirname(normalizedProjectRoot);
|
|
42
|
+
if (basename(projectParent) === ".worktrees") {
|
|
43
|
+
const worktreeOwner = dirname(projectParent);
|
|
44
|
+
const ownerHasGit = existsSync(resolve(worktreeOwner, ".git"));
|
|
45
|
+
const ownerHasTaskConfig = existsSync(resolve(worktreeOwner, ".rig", "task-config.json"));
|
|
46
|
+
const ownerHasRigConfig = existsSync(resolve(worktreeOwner, "rig.config.ts"));
|
|
47
|
+
if (ownerHasGit && (ownerHasTaskConfig || ownerHasRigConfig)) {
|
|
48
|
+
return worktreeOwner;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return normalizedProjectRoot;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// packages/runtime/src/control-plane/runtime/sandbox/utils.ts
|
|
55
|
+
function toRealPath(path) {
|
|
56
|
+
if (!existsSync2(path)) {
|
|
57
|
+
return resolve2(path);
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
return realpathSync.native(path);
|
|
61
|
+
} catch {
|
|
62
|
+
return resolve2(path);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
|
|
66
|
+
const candidates = new Set;
|
|
67
|
+
const addPath = (candidate) => {
|
|
68
|
+
if (existsSync2(candidate)) {
|
|
69
|
+
candidates.add(toRealPath(candidate));
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
addPath(resolve2(projectRoot, ".git"));
|
|
73
|
+
addPath(resolve2(workspaceDir, "..", "..", ".git"));
|
|
74
|
+
for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
|
|
75
|
+
addPath(resolve2(repoRoot, ".git"));
|
|
76
|
+
}
|
|
77
|
+
const workspaceGit = resolve2(workspaceDir, ".git");
|
|
78
|
+
if (existsSync2(workspaceGit)) {
|
|
79
|
+
addPath(workspaceGit);
|
|
80
|
+
}
|
|
81
|
+
return [...candidates];
|
|
82
|
+
}
|
|
83
|
+
function resolveHostRepoRootPaths(projectRoot) {
|
|
84
|
+
const candidates = new Set;
|
|
85
|
+
const addPath = (candidate) => {
|
|
86
|
+
if (existsSync2(candidate)) {
|
|
87
|
+
candidates.add(toRealPath(candidate));
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
try {
|
|
91
|
+
const monorepoRoot = resolveMonorepoRoot(projectRoot);
|
|
92
|
+
if (toRealPath(monorepoRoot) !== toRealPath(projectRoot)) {
|
|
93
|
+
addPath(monorepoRoot);
|
|
94
|
+
}
|
|
95
|
+
} catch {}
|
|
96
|
+
const reposDir = resolve2(projectRoot, "repos");
|
|
97
|
+
if (existsSync2(reposDir)) {
|
|
98
|
+
for (const entry of readdirSync(reposDir, { withFileTypes: true })) {
|
|
99
|
+
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
100
|
+
addPath(resolve2(reposDir, entry.name));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return [...candidates];
|
|
105
|
+
}
|
|
106
|
+
function resolveNetworkWithPolicy(sandboxConfig, envOverride) {
|
|
107
|
+
if (envOverride) {
|
|
108
|
+
const envValue = parseBooleanEnv(envOverride, sandboxConfig.network);
|
|
109
|
+
if (envValue !== sandboxConfig.network) {
|
|
110
|
+
console.warn(`[sandbox] RIG_RUNTIME_SANDBOX_NETWORK=${envOverride} overrides policy sandbox.network=${sandboxConfig.network}`);
|
|
111
|
+
}
|
|
112
|
+
return envValue;
|
|
113
|
+
}
|
|
114
|
+
return sandboxConfig.network;
|
|
115
|
+
}
|
|
116
|
+
function parseBooleanEnv(raw, fallback) {
|
|
117
|
+
if (!raw) {
|
|
118
|
+
return fallback;
|
|
119
|
+
}
|
|
120
|
+
const normalized = raw.trim().toLowerCase();
|
|
121
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return fallback;
|
|
128
|
+
}
|
|
129
|
+
function uniq(values) {
|
|
130
|
+
return [...new Set(values)];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// packages/runtime/src/control-plane/runtime/sandbox/backend-bwrap.ts
|
|
134
|
+
class BwrapBackend {
|
|
135
|
+
kind = "linux-bwrap";
|
|
136
|
+
binaryPath;
|
|
137
|
+
config;
|
|
138
|
+
ctx;
|
|
139
|
+
resolvedPaths;
|
|
140
|
+
which;
|
|
141
|
+
constructor(binaryPath, config, ctx, resolvedPaths, which) {
|
|
142
|
+
this.binaryPath = binaryPath;
|
|
143
|
+
this.config = config;
|
|
144
|
+
this.ctx = ctx;
|
|
145
|
+
this.resolvedPaths = resolvedPaths;
|
|
146
|
+
this.which = which ?? ((bin) => Bun.which(bin));
|
|
147
|
+
}
|
|
148
|
+
wrap(options) {
|
|
149
|
+
const command = this.buildCommand(options);
|
|
150
|
+
return {
|
|
151
|
+
command,
|
|
152
|
+
enabled: true,
|
|
153
|
+
backend: "linux-bwrap"
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
buildCommand(options) {
|
|
157
|
+
const { runtime, projectRoot, command } = options;
|
|
158
|
+
const { ctx, resolvedPaths, config } = this;
|
|
159
|
+
const workspaceReal = ctx.realPath(runtime.workspaceDir);
|
|
160
|
+
const runtimeRootReal = ctx.realPath(runtime.rootDir);
|
|
161
|
+
const homeReal = ctx.realPath(runtime.homeDir);
|
|
162
|
+
const tmpReal = ctx.realPath(runtime.tmpDir);
|
|
163
|
+
const cacheReal = ctx.realPath(runtime.cacheDir);
|
|
164
|
+
const hostGitDirs = resolveHostGitMetadataPaths(projectRoot, runtime.workspaceDir);
|
|
165
|
+
const hostRepoRoots = resolveHostRepoRootPaths(projectRoot).map((repoRoot) => ctx.realPath(repoRoot));
|
|
166
|
+
const bunDir = ctx.realPath(resolvedPaths.bunDir);
|
|
167
|
+
const claudeDir = resolvedPaths.claudeDir ? ctx.realPath(resolvedPaths.claudeDir) : null;
|
|
168
|
+
const allowNetwork = resolveNetworkWithPolicy(config, process.env.RIG_RUNTIME_SANDBOX_NETWORK);
|
|
169
|
+
const args = [
|
|
170
|
+
this.binaryPath,
|
|
171
|
+
"--die-with-parent",
|
|
172
|
+
"--new-session",
|
|
173
|
+
"--unshare-pid",
|
|
174
|
+
"--tmpfs",
|
|
175
|
+
"/",
|
|
176
|
+
"--ro-bind",
|
|
177
|
+
"/usr",
|
|
178
|
+
"/usr",
|
|
179
|
+
"--ro-bind",
|
|
180
|
+
"/bin",
|
|
181
|
+
"/bin",
|
|
182
|
+
"--ro-bind",
|
|
183
|
+
"/sbin",
|
|
184
|
+
"/sbin"
|
|
185
|
+
];
|
|
186
|
+
for (const libPath of ["/lib", "/lib64"]) {
|
|
187
|
+
if (ctx.pathExists(libPath)) {
|
|
188
|
+
args.push("--ro-bind", libPath, libPath);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const etcEntry of [
|
|
192
|
+
"/etc/ld.so.cache",
|
|
193
|
+
"/etc/ld.so.conf",
|
|
194
|
+
"/etc/ld.so.conf.d",
|
|
195
|
+
"/etc/resolv.conf",
|
|
196
|
+
"/etc/hosts",
|
|
197
|
+
"/etc/nsswitch.conf",
|
|
198
|
+
"/etc/gai.conf",
|
|
199
|
+
"/etc/host.conf",
|
|
200
|
+
"/etc/ssl",
|
|
201
|
+
"/etc/ca-certificates",
|
|
202
|
+
"/etc/pki",
|
|
203
|
+
"/etc/passwd",
|
|
204
|
+
"/etc/group",
|
|
205
|
+
"/etc/localtime",
|
|
206
|
+
"/etc/timezone",
|
|
207
|
+
"/etc/locale.conf",
|
|
208
|
+
"/etc/default/locale"
|
|
209
|
+
]) {
|
|
210
|
+
if (ctx.pathExists(etcEntry)) {
|
|
211
|
+
args.push("--ro-bind", etcEntry, etcEntry);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (ctx.pathExists("/run/systemd/resolve")) {
|
|
215
|
+
args.push("--ro-bind", "/run/systemd/resolve", "/run/systemd/resolve");
|
|
216
|
+
}
|
|
217
|
+
if (ctx.pathExists("/run/nscd")) {
|
|
218
|
+
args.push("--ro-bind", "/run/nscd", "/run/nscd");
|
|
219
|
+
}
|
|
220
|
+
args.push("--ro-bind", bunDir, bunDir);
|
|
221
|
+
if (claudeDir) {
|
|
222
|
+
args.push("--ro-bind", claudeDir, claudeDir);
|
|
223
|
+
}
|
|
224
|
+
if (resolvedPaths.nodeDir && ctx.pathExists(resolvedPaths.nodeDir)) {
|
|
225
|
+
args.push("--ro-bind", resolvedPaths.nodeDir, resolvedPaths.nodeDir);
|
|
226
|
+
}
|
|
227
|
+
for (const depPath of resolvedPaths.depRoots) {
|
|
228
|
+
if (ctx.pathExists(depPath)) {
|
|
229
|
+
args.push("--ro-bind", depPath, depPath);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const projectRootReal = ctx.realPath(projectRoot);
|
|
233
|
+
if (projectRootReal !== workspaceReal && !projectRootReal.startsWith(workspaceReal + "/") && ctx.pathExists(projectRootReal)) {
|
|
234
|
+
args.push("--ro-bind", projectRootReal, projectRootReal);
|
|
235
|
+
}
|
|
236
|
+
for (const repoRoot of hostRepoRoots) {
|
|
237
|
+
if (!ctx.pathExists(repoRoot) || repoRoot === workspaceReal || repoRoot.startsWith(workspaceReal + "/") || repoRoot === projectRootReal || repoRoot.startsWith(projectRootReal + "/")) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
args.push("--ro-bind", repoRoot, repoRoot);
|
|
241
|
+
}
|
|
242
|
+
args.push("--bind", workspaceReal, workspaceReal);
|
|
243
|
+
args.push("--bind", runtimeRootReal, runtimeRootReal);
|
|
244
|
+
for (const rwPath of uniq([homeReal, tmpReal, cacheReal])) {
|
|
245
|
+
if (rwPath !== runtimeRootReal && !rwPath.startsWith(runtimeRootReal + "/")) {
|
|
246
|
+
args.push("--bind", rwPath, rwPath);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (const gitPath of hostGitDirs) {
|
|
250
|
+
if (!ctx.pathExists(gitPath))
|
|
251
|
+
continue;
|
|
252
|
+
if (gitPath === runtimeRootReal || gitPath.startsWith(runtimeRootReal + "/"))
|
|
253
|
+
continue;
|
|
254
|
+
if (gitPath === workspaceReal || gitPath.startsWith(workspaceReal + "/"))
|
|
255
|
+
continue;
|
|
256
|
+
args.push("--bind", gitPath, gitPath);
|
|
257
|
+
}
|
|
258
|
+
const realHome = process.env.HOME?.trim();
|
|
259
|
+
if (realHome) {
|
|
260
|
+
for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
|
|
261
|
+
const binPath = ctx.realPath(resolve3(realHome, binSubdir));
|
|
262
|
+
if (ctx.pathExists(binPath)) {
|
|
263
|
+
args.push("--ro-bind", binPath, binPath);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const agentSshDir = resolve3(homeReal, ".ssh");
|
|
267
|
+
if (ctx.pathExists(agentSshDir)) {
|
|
268
|
+
args.push("--ro-bind", agentSshDir, agentSshDir);
|
|
269
|
+
} else {
|
|
270
|
+
const hostSshDir = resolve3(realHome, ".ssh");
|
|
271
|
+
if (ctx.pathExists(hostSshDir)) {
|
|
272
|
+
mkdirSync(agentSshDir, { recursive: true });
|
|
273
|
+
args.push("--ro-bind", hostSshDir, agentSshDir);
|
|
274
|
+
args.push("--ro-bind", hostSshDir, hostSshDir);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
args.push("--proc", "/proc");
|
|
279
|
+
args.push("--dev", "/dev");
|
|
280
|
+
args.push("--tmpfs", "/tmp");
|
|
281
|
+
args.push("--unsetenv", "CLAUDECODE");
|
|
282
|
+
args.push("--setenv", "HOME", homeReal);
|
|
283
|
+
args.push("--setenv", "TMPDIR", "/tmp");
|
|
284
|
+
args.push("--chdir", workspaceReal);
|
|
285
|
+
if (!allowNetwork) {
|
|
286
|
+
args.push("--unshare-net");
|
|
287
|
+
}
|
|
288
|
+
args.push("--", ...this.resolveCommandBinary(command));
|
|
289
|
+
return args;
|
|
290
|
+
}
|
|
291
|
+
resolveCommandBinary(command) {
|
|
292
|
+
if (command.length === 0)
|
|
293
|
+
return command;
|
|
294
|
+
const [bin, ...rest] = command;
|
|
295
|
+
if (!bin)
|
|
296
|
+
return command;
|
|
297
|
+
const resolved = this.which(bin);
|
|
298
|
+
if (!resolved)
|
|
299
|
+
return command;
|
|
300
|
+
try {
|
|
301
|
+
const { realpathSync: realpathSync2 } = __require("fs");
|
|
302
|
+
const resolvedBinary = realpathSync2(resolved);
|
|
303
|
+
return [resolvedBinary, ...rest];
|
|
304
|
+
} catch {
|
|
305
|
+
return [resolved, ...rest];
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
export {
|
|
310
|
+
BwrapBackend
|
|
311
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/runtime/sandbox/backend-none.ts
|
|
3
|
+
class NoSandboxBackend {
|
|
4
|
+
kind = "none";
|
|
5
|
+
reason;
|
|
6
|
+
constructor(reason) {
|
|
7
|
+
this.reason = reason;
|
|
8
|
+
}
|
|
9
|
+
wrap(options) {
|
|
10
|
+
return {
|
|
11
|
+
command: options.command,
|
|
12
|
+
enabled: false,
|
|
13
|
+
backend: "none",
|
|
14
|
+
reason: this.reason,
|
|
15
|
+
metadata: undefined
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
NoSandboxBackend
|
|
21
|
+
};
|