@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,454 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/runtime/src/control-plane/runtime/snapshot.ts
|
|
3
|
+
import { ptr as ptr2, toBuffer as toBuffer2 } from "bun:ffi";
|
|
4
|
+
|
|
5
|
+
// packages/runtime/src/control-plane/native/runtime-native.ts
|
|
6
|
+
import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
|
|
7
|
+
import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync, statSync } from "fs";
|
|
8
|
+
import { tmpdir } from "os";
|
|
9
|
+
import { dirname, resolve } from "path";
|
|
10
|
+
var sharedNativeRuntimeOutputDir = resolve(tmpdir(), "rig-native");
|
|
11
|
+
var sharedNativeRuntimeOutputPath = resolve(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
|
|
12
|
+
var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
|
|
13
|
+
var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
|
|
14
|
+
function requireNativeRuntimeLibrary(feature) {
|
|
15
|
+
if (!nativeRuntimeLibrary) {
|
|
16
|
+
throw new Error(`Native Zig runtime is required for ${feature}`);
|
|
17
|
+
}
|
|
18
|
+
return nativeRuntimeLibrary;
|
|
19
|
+
}
|
|
20
|
+
async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOutputPath, options = {}) {
|
|
21
|
+
if (await buildNativeRuntimeLibrary(outputPath, options)) {
|
|
22
|
+
return outputPath;
|
|
23
|
+
}
|
|
24
|
+
return !options.force && existsSync(outputPath) ? outputPath : null;
|
|
25
|
+
}
|
|
26
|
+
async function loadNativeRuntimeLibrary() {
|
|
27
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
for (const candidate of nativeRuntimeLibraryCandidates()) {
|
|
31
|
+
if (!candidate || !existsSync(candidate)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const loaded = tryDlopenNativeRuntimeLibrary(candidate);
|
|
35
|
+
if (loaded) {
|
|
36
|
+
return loaded;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const builtLibraryPath = await ensureNativeRuntimeLibraryPath(sharedNativeRuntimeOutputPath, { force: true });
|
|
40
|
+
if (!builtLibraryPath) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return tryDlopenNativeRuntimeLibrary(builtLibraryPath);
|
|
44
|
+
}
|
|
45
|
+
function nativePackageLibraryCandidates(fromDir, names) {
|
|
46
|
+
const candidates = [];
|
|
47
|
+
let cursor = resolve(fromDir);
|
|
48
|
+
for (let index = 0;index < 8; index += 1) {
|
|
49
|
+
for (const name of names) {
|
|
50
|
+
candidates.push(resolve(cursor, "native", `${process.platform}-${process.arch}`, name), resolve(cursor, "native", `${process.platform}-${process.arch}`, "lib", name), resolve(cursor, "native", name), resolve(cursor, "native", "lib", name));
|
|
51
|
+
}
|
|
52
|
+
const parent = dirname(cursor);
|
|
53
|
+
if (parent === cursor)
|
|
54
|
+
break;
|
|
55
|
+
cursor = parent;
|
|
56
|
+
}
|
|
57
|
+
return candidates;
|
|
58
|
+
}
|
|
59
|
+
function nativeRuntimeLibraryCandidates() {
|
|
60
|
+
const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
|
|
61
|
+
const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
|
|
62
|
+
const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
|
|
63
|
+
return [...new Set([
|
|
64
|
+
explicit,
|
|
65
|
+
...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
|
|
66
|
+
execDir ? resolve(execDir, colocatedNativeRuntimeFileName) : "",
|
|
67
|
+
execDir ? resolve(execDir, platformSpecific) : "",
|
|
68
|
+
execDir ? resolve(execDir, "..", colocatedNativeRuntimeFileName) : "",
|
|
69
|
+
execDir ? resolve(execDir, "..", platformSpecific) : "",
|
|
70
|
+
execDir ? resolve(execDir, "lib", colocatedNativeRuntimeFileName) : "",
|
|
71
|
+
execDir ? resolve(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
|
|
72
|
+
sharedNativeRuntimeOutputPath
|
|
73
|
+
].filter(Boolean))];
|
|
74
|
+
}
|
|
75
|
+
function resolveNativeRuntimeSourcePath() {
|
|
76
|
+
const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
|
|
77
|
+
if (explicit && existsSync(explicit)) {
|
|
78
|
+
return explicit;
|
|
79
|
+
}
|
|
80
|
+
const bundled = resolve(import.meta.dir, "../../../native/snapshot.zig");
|
|
81
|
+
return existsSync(bundled) ? bundled : null;
|
|
82
|
+
}
|
|
83
|
+
async function buildNativeRuntimeLibrary(outputPath, options = {}) {
|
|
84
|
+
if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const zigBinary = Bun.which("zig");
|
|
88
|
+
const sourcePath = resolveNativeRuntimeSourcePath();
|
|
89
|
+
if (!zigBinary || !sourcePath) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
93
|
+
try {
|
|
94
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
95
|
+
const needsBuild = options.force === true || !existsSync(outputPath) || statSync(sourcePath).mtimeMs > statSync(outputPath).mtimeMs;
|
|
96
|
+
if (!needsBuild) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
const build = Bun.spawn([
|
|
100
|
+
zigBinary,
|
|
101
|
+
"build-lib",
|
|
102
|
+
sourcePath,
|
|
103
|
+
"-dynamic",
|
|
104
|
+
"-O",
|
|
105
|
+
"ReleaseFast",
|
|
106
|
+
`-femit-bin=${tempOutputPath}`
|
|
107
|
+
], {
|
|
108
|
+
cwd: import.meta.dir,
|
|
109
|
+
stdout: "pipe",
|
|
110
|
+
stderr: "pipe"
|
|
111
|
+
});
|
|
112
|
+
const exitCode = await build.exited;
|
|
113
|
+
if (exitCode !== 0 || !existsSync(tempOutputPath)) {
|
|
114
|
+
rmSync(tempOutputPath, { force: true });
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
renameSync(tempOutputPath, outputPath);
|
|
118
|
+
return true;
|
|
119
|
+
} catch {
|
|
120
|
+
rmSync(tempOutputPath, { force: true });
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function tryDlopenNativeRuntimeLibrary(outputPath) {
|
|
125
|
+
try {
|
|
126
|
+
return dlopen(outputPath, {
|
|
127
|
+
rig_scope_match: {
|
|
128
|
+
args: ["ptr", "ptr"],
|
|
129
|
+
returns: "u8"
|
|
130
|
+
},
|
|
131
|
+
snapshot_capture: {
|
|
132
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
133
|
+
returns: "ptr"
|
|
134
|
+
},
|
|
135
|
+
snapshot_delta: {
|
|
136
|
+
args: ["ptr", "ptr"],
|
|
137
|
+
returns: "ptr"
|
|
138
|
+
},
|
|
139
|
+
snapshot_store_delta: {
|
|
140
|
+
args: ["ptr", "ptr", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
|
|
141
|
+
returns: "ptr"
|
|
142
|
+
},
|
|
143
|
+
snapshot_inspect_delta: {
|
|
144
|
+
args: ["ptr", "u64"],
|
|
145
|
+
returns: "ptr"
|
|
146
|
+
},
|
|
147
|
+
snapshot_apply_delta: {
|
|
148
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
149
|
+
returns: "ptr"
|
|
150
|
+
},
|
|
151
|
+
snapshot_release: {
|
|
152
|
+
args: ["ptr"],
|
|
153
|
+
returns: "void"
|
|
154
|
+
},
|
|
155
|
+
runtime_hash_file: {
|
|
156
|
+
args: ["ptr", "u64"],
|
|
157
|
+
returns: "ptr"
|
|
158
|
+
},
|
|
159
|
+
runtime_hash_tree: {
|
|
160
|
+
args: ["ptr", "u64"],
|
|
161
|
+
returns: "ptr"
|
|
162
|
+
},
|
|
163
|
+
runtime_prepare_paths: {
|
|
164
|
+
args: ["ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
|
|
165
|
+
returns: "ptr"
|
|
166
|
+
},
|
|
167
|
+
runtime_link_dependency_layer: {
|
|
168
|
+
args: ["ptr", "u64", "ptr", "u64"],
|
|
169
|
+
returns: "ptr"
|
|
170
|
+
},
|
|
171
|
+
runtime_scan_worktrees: {
|
|
172
|
+
args: ["ptr", "u64"],
|
|
173
|
+
returns: "ptr"
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
} catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// packages/runtime/src/control-plane/runtime/snapshot.ts
|
|
182
|
+
var MANIFEST_HANDLE_SIZE = 40;
|
|
183
|
+
var DELTA_RESULT_SIZE = 72;
|
|
184
|
+
var FILE_ENTRY_SIZE = 40;
|
|
185
|
+
var DELTA_ENTRY_SIZE = 24;
|
|
186
|
+
var STRING_SLICE_SIZE = 16;
|
|
187
|
+
var STORE_RESULT_SIZE = 104;
|
|
188
|
+
var INSPECT_RESULT_SIZE = 144;
|
|
189
|
+
var OPERATION_RESULT_SIZE = 24;
|
|
190
|
+
var MANIFEST_NATIVE_HANDLE = Symbol("manifest-native-handle");
|
|
191
|
+
var DEFAULT_EXCLUDES = new Set([
|
|
192
|
+
"node_modules",
|
|
193
|
+
".git",
|
|
194
|
+
".worktrees",
|
|
195
|
+
".tmp",
|
|
196
|
+
".rig",
|
|
197
|
+
"artifacts"
|
|
198
|
+
]);
|
|
199
|
+
var nativeSnapshotLibrary = requireNativeRuntimeLibrary("runtime snapshots");
|
|
200
|
+
var manifestReleaseRegistry = typeof FinalizationRegistry !== "undefined" ? new FinalizationRegistry((resourcePtr) => {
|
|
201
|
+
try {
|
|
202
|
+
nativeSnapshotLibrary.symbols.snapshot_release(resourcePtr);
|
|
203
|
+
} catch {}
|
|
204
|
+
}) : null;
|
|
205
|
+
function captureManifest(rootDir, options) {
|
|
206
|
+
const exclude = options?.exclude ?? DEFAULT_EXCLUDES;
|
|
207
|
+
const captured = captureManifestEntries(rootDir, [...exclude]);
|
|
208
|
+
const manifest = {
|
|
209
|
+
root: rootDir,
|
|
210
|
+
capturedAt: new Date().toISOString(),
|
|
211
|
+
entries: captured.entries
|
|
212
|
+
};
|
|
213
|
+
manifest[MANIFEST_NATIVE_HANDLE] = captured.nativeHandle;
|
|
214
|
+
manifestReleaseRegistry?.register(manifest, captured.nativeHandle, manifest);
|
|
215
|
+
return manifest;
|
|
216
|
+
}
|
|
217
|
+
function releaseManifest(manifest) {
|
|
218
|
+
if (!manifest) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const nativeManifest = manifest;
|
|
222
|
+
const handle = nativeManifest[MANIFEST_NATIVE_HANDLE];
|
|
223
|
+
if (!handle) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
manifestReleaseRegistry?.unregister(manifest);
|
|
227
|
+
delete nativeManifest[MANIFEST_NATIVE_HANDLE];
|
|
228
|
+
nativeSnapshotLibrary.symbols.snapshot_release(handle);
|
|
229
|
+
}
|
|
230
|
+
function computeDelta(before, after, taskId) {
|
|
231
|
+
const deltaEntries = computeDeltaEntries(before, after);
|
|
232
|
+
return {
|
|
233
|
+
taskId,
|
|
234
|
+
baseManifestHash: computeManifestHash(before),
|
|
235
|
+
capturedAt: new Date().toISOString(),
|
|
236
|
+
modified: deltaEntries.modified,
|
|
237
|
+
created: deltaEntries.created,
|
|
238
|
+
deleted: deltaEntries.deleted
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function inspectSnapshot(snapshotPath) {
|
|
242
|
+
const pathBuffer = Buffer.from(snapshotPath, "utf8");
|
|
243
|
+
const resultPtr = nativeSnapshotLibrary.symbols.snapshot_inspect_delta(Number(ptr2(pathBuffer)), pathBuffer.byteLength);
|
|
244
|
+
if (!resultPtr) {
|
|
245
|
+
throw new Error(`snapshot_inspect_delta returned null for ${snapshotPath}`);
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
const resultView = viewAt(resultPtr, INSPECT_RESULT_SIZE);
|
|
249
|
+
throwIfError(nativeSnapshotLibrary.symbols, resultView, 128, 136, "snapshot_inspect_delta");
|
|
250
|
+
return {
|
|
251
|
+
taskId: readString(readU64(resultView, 8), readU64(resultView, 16)),
|
|
252
|
+
baseManifestHash: readString(readU64(resultView, 24), readU64(resultView, 32)),
|
|
253
|
+
capturedAt: readString(readU64(resultView, 40), readU64(resultView, 48)),
|
|
254
|
+
modified: readDeltaEntries(readU64(resultView, 56), readU64(resultView, 64)),
|
|
255
|
+
created: readDeltaEntries(readU64(resultView, 72), readU64(resultView, 80)),
|
|
256
|
+
deleted: readStringSliceArray(readU64(resultView, 88), readU64(resultView, 96)),
|
|
257
|
+
blobCount: readU64(resultView, 104),
|
|
258
|
+
blobsSize: readU64(resultView, 112),
|
|
259
|
+
compressedSize: readU64(resultView, 120)
|
|
260
|
+
};
|
|
261
|
+
} finally {
|
|
262
|
+
nativeSnapshotLibrary.symbols.snapshot_release(resultPtr);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function snapshotBefore(worktreeDir, exclude) {
|
|
266
|
+
return captureManifest(worktreeDir, { exclude });
|
|
267
|
+
}
|
|
268
|
+
function snapshotAfter(worktreeDir, beforeManifest, taskId, outputPath, exclude) {
|
|
269
|
+
const afterManifest = captureManifest(worktreeDir, { exclude });
|
|
270
|
+
const delta = computeDelta(beforeManifest, afterManifest, taskId);
|
|
271
|
+
const capturedAt = new Date().toISOString();
|
|
272
|
+
const meta = storeSnapshotArchive(beforeManifest, afterManifest, worktreeDir, taskId, capturedAt, outputPath);
|
|
273
|
+
meta.beforeEntries = beforeManifest.entries.size;
|
|
274
|
+
meta.afterEntries = afterManifest.entries.size;
|
|
275
|
+
return { delta: { ...delta, capturedAt: meta.capturedAt, baseManifestHash: meta.baseManifestHash ?? delta.baseManifestHash }, meta, afterManifest };
|
|
276
|
+
}
|
|
277
|
+
function reconstructFromSnapshot(snapshotPath, targetDir) {
|
|
278
|
+
const snapshotPathBuffer = Buffer.from(snapshotPath, "utf8");
|
|
279
|
+
const targetDirBuffer = Buffer.from(targetDir, "utf8");
|
|
280
|
+
const resultPtr = nativeSnapshotLibrary.symbols.snapshot_apply_delta(Number(ptr2(snapshotPathBuffer)), snapshotPathBuffer.byteLength, Number(ptr2(targetDirBuffer)), targetDirBuffer.byteLength);
|
|
281
|
+
if (!resultPtr) {
|
|
282
|
+
throw new Error(`snapshot_apply_delta returned null for ${snapshotPath}`);
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
const resultView = viewAt(resultPtr, OPERATION_RESULT_SIZE);
|
|
286
|
+
throwIfError(nativeSnapshotLibrary.symbols, resultView, 8, 16, "snapshot_apply_delta");
|
|
287
|
+
} finally {
|
|
288
|
+
nativeSnapshotLibrary.symbols.snapshot_release(resultPtr);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function captureManifestEntries(rootDir, exclude) {
|
|
292
|
+
const rootBuffer = Buffer.from(rootDir, "utf8");
|
|
293
|
+
const excludeBuffer = Buffer.from(exclude.join("\x00"), "utf8");
|
|
294
|
+
const handlePtr = nativeSnapshotLibrary.symbols.snapshot_capture(Number(ptr2(rootBuffer)), rootBuffer.byteLength, Number(ptr2(excludeBuffer)), excludeBuffer.byteLength);
|
|
295
|
+
if (!handlePtr) {
|
|
296
|
+
throw new Error(`snapshot_capture returned null for ${rootDir}`);
|
|
297
|
+
}
|
|
298
|
+
const handleView = viewAt(handlePtr, MANIFEST_HANDLE_SIZE);
|
|
299
|
+
try {
|
|
300
|
+
throwIfError(nativeSnapshotLibrary.symbols, handleView, 24, 32, "snapshot_capture");
|
|
301
|
+
const entriesPtr = readU64(handleView, 8);
|
|
302
|
+
const entriesLen = readU64(handleView, 16);
|
|
303
|
+
const entries = new Map;
|
|
304
|
+
for (let index = 0;index < entriesLen; index += 1) {
|
|
305
|
+
const entryView = viewAt(entriesPtr + index * FILE_ENTRY_SIZE, FILE_ENTRY_SIZE);
|
|
306
|
+
const path = readString(readU64(entryView, 0), readU64(entryView, 8));
|
|
307
|
+
entries.set(path, {
|
|
308
|
+
path,
|
|
309
|
+
hash: readBigU64(entryView, 16).toString(16),
|
|
310
|
+
size: readU64(entryView, 24),
|
|
311
|
+
mode: readU64(entryView, 32)
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
entries,
|
|
316
|
+
nativeHandle: handlePtr
|
|
317
|
+
};
|
|
318
|
+
} catch (error) {
|
|
319
|
+
nativeSnapshotLibrary.symbols.snapshot_release(handlePtr);
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function computeDeltaEntries(before, after) {
|
|
324
|
+
const beforeHandle = before[MANIFEST_NATIVE_HANDLE];
|
|
325
|
+
const afterHandle = after[MANIFEST_NATIVE_HANDLE];
|
|
326
|
+
if (!beforeHandle || !afterHandle) {
|
|
327
|
+
throw new Error("snapshot manifests must carry native handles");
|
|
328
|
+
}
|
|
329
|
+
const resultPtr = nativeSnapshotLibrary.symbols.snapshot_delta(beforeHandle, afterHandle);
|
|
330
|
+
if (!resultPtr) {
|
|
331
|
+
throw new Error("snapshot_delta returned null");
|
|
332
|
+
}
|
|
333
|
+
try {
|
|
334
|
+
const resultView = viewAt(resultPtr, DELTA_RESULT_SIZE);
|
|
335
|
+
throwIfError(nativeSnapshotLibrary.symbols, resultView, 56, 64, "snapshot_delta");
|
|
336
|
+
return {
|
|
337
|
+
modified: readDeltaEntries(readU64(resultView, 8), readU64(resultView, 16)),
|
|
338
|
+
created: readDeltaEntries(readU64(resultView, 24), readU64(resultView, 32)),
|
|
339
|
+
deleted: readStringSliceArray(readU64(resultView, 40), readU64(resultView, 48))
|
|
340
|
+
};
|
|
341
|
+
} finally {
|
|
342
|
+
nativeSnapshotLibrary.symbols.snapshot_release(resultPtr);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function storeSnapshotArchive(beforeManifest, afterManifest, worktreeDir, taskId, capturedAt, outputPath) {
|
|
346
|
+
const beforeHandle = beforeManifest[MANIFEST_NATIVE_HANDLE];
|
|
347
|
+
const afterHandle = afterManifest[MANIFEST_NATIVE_HANDLE];
|
|
348
|
+
if (!beforeHandle || !afterHandle) {
|
|
349
|
+
throw new Error("snapshot manifests must carry native handles");
|
|
350
|
+
}
|
|
351
|
+
const worktreeBuffer = Buffer.from(worktreeDir, "utf8");
|
|
352
|
+
const taskBuffer = Buffer.from(taskId, "utf8");
|
|
353
|
+
const capturedAtBuffer = Buffer.from(capturedAt, "utf8");
|
|
354
|
+
const outputBuffer = Buffer.from(outputPath, "utf8");
|
|
355
|
+
const resultPtr = nativeSnapshotLibrary.symbols.snapshot_store_delta(beforeHandle, afterHandle, Number(ptr2(worktreeBuffer)), worktreeBuffer.byteLength, Number(ptr2(taskBuffer)), taskBuffer.byteLength, Number(ptr2(capturedAtBuffer)), capturedAtBuffer.byteLength, Number(ptr2(outputBuffer)), outputBuffer.byteLength);
|
|
356
|
+
if (!resultPtr) {
|
|
357
|
+
throw new Error(`snapshot_store_delta returned null for ${outputPath}`);
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
const resultView = viewAt(resultPtr, STORE_RESULT_SIZE);
|
|
361
|
+
throwIfError(nativeSnapshotLibrary.symbols, resultView, 88, 96, "snapshot_store_delta");
|
|
362
|
+
return {
|
|
363
|
+
taskId,
|
|
364
|
+
baseManifestHash: readString(readU64(resultView, 8), readU64(resultView, 16)),
|
|
365
|
+
capturedAt: readString(readU64(resultView, 24), readU64(resultView, 32)),
|
|
366
|
+
beforeEntries: 0,
|
|
367
|
+
afterEntries: 0,
|
|
368
|
+
modifiedCount: readU64(resultView, 40),
|
|
369
|
+
createdCount: readU64(resultView, 48),
|
|
370
|
+
deletedCount: readU64(resultView, 56),
|
|
371
|
+
blobCount: readU64(resultView, 64),
|
|
372
|
+
blobsSize: readU64(resultView, 72),
|
|
373
|
+
compressedSize: readU64(resultView, 80)
|
|
374
|
+
};
|
|
375
|
+
} finally {
|
|
376
|
+
nativeSnapshotLibrary.symbols.snapshot_release(resultPtr);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function computeManifestHash(manifest) {
|
|
380
|
+
const sorted = [...manifest.entries.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
381
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
382
|
+
for (const entry of sorted) {
|
|
383
|
+
hasher.update(entry.path);
|
|
384
|
+
hasher.update("\x00");
|
|
385
|
+
hasher.update(entry.hash);
|
|
386
|
+
hasher.update("\x00");
|
|
387
|
+
hasher.update(String(entry.size));
|
|
388
|
+
hasher.update("\x00");
|
|
389
|
+
hasher.update(String(entry.mode));
|
|
390
|
+
}
|
|
391
|
+
return hasher.digest("hex");
|
|
392
|
+
}
|
|
393
|
+
function readDeltaEntries(pointer, count) {
|
|
394
|
+
const values = [];
|
|
395
|
+
for (let index = 0;index < count; index += 1) {
|
|
396
|
+
const entryView = viewAt(pointer + index * DELTA_ENTRY_SIZE, DELTA_ENTRY_SIZE);
|
|
397
|
+
values.push({
|
|
398
|
+
path: readString(readU64(entryView, 0), readU64(entryView, 8)),
|
|
399
|
+
hash: readBigU64(entryView, 16).toString(16)
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
return values;
|
|
403
|
+
}
|
|
404
|
+
function readStringSliceArray(pointer, count) {
|
|
405
|
+
const values = [];
|
|
406
|
+
for (let index = 0;index < count; index += 1) {
|
|
407
|
+
const entryView = viewAt(pointer + index * STRING_SLICE_SIZE, STRING_SLICE_SIZE);
|
|
408
|
+
values.push(readString(readU64(entryView, 0), readU64(entryView, 8)));
|
|
409
|
+
}
|
|
410
|
+
return values;
|
|
411
|
+
}
|
|
412
|
+
function viewAt(pointer, size) {
|
|
413
|
+
const buffer = toBuffer2(pointer, 0, size);
|
|
414
|
+
return new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
415
|
+
}
|
|
416
|
+
function readString(pointer, length) {
|
|
417
|
+
if (!pointer || length === 0) {
|
|
418
|
+
return "";
|
|
419
|
+
}
|
|
420
|
+
return Buffer.from(toBuffer2(pointer, 0, length)).toString("utf8");
|
|
421
|
+
}
|
|
422
|
+
function readU64(view, offset) {
|
|
423
|
+
return Number(view.getBigUint64(offset, true));
|
|
424
|
+
}
|
|
425
|
+
function readBigU64(view, offset) {
|
|
426
|
+
return view.getBigUint64(offset, true);
|
|
427
|
+
}
|
|
428
|
+
function readError(view, pointerOffset, lengthOffset) {
|
|
429
|
+
const errorPointer = readU64(view, pointerOffset);
|
|
430
|
+
const errorLength = readU64(view, lengthOffset);
|
|
431
|
+
if (!errorPointer || !errorLength) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
return readString(errorPointer, errorLength);
|
|
435
|
+
}
|
|
436
|
+
function throwIfError(_symbols, view, pointerOffset, lengthOffset, label) {
|
|
437
|
+
const error = readError(view, pointerOffset, lengthOffset);
|
|
438
|
+
if (error) {
|
|
439
|
+
throw new Error(`${label} failed: ${error}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
var __testOnly = {
|
|
443
|
+
defaultExcludes: [...DEFAULT_EXCLUDES]
|
|
444
|
+
};
|
|
445
|
+
export {
|
|
446
|
+
snapshotBefore,
|
|
447
|
+
snapshotAfter,
|
|
448
|
+
releaseManifest,
|
|
449
|
+
reconstructFromSnapshot,
|
|
450
|
+
inspectSnapshot,
|
|
451
|
+
computeDelta,
|
|
452
|
+
captureManifest,
|
|
453
|
+
__testOnly
|
|
454
|
+
};
|