@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.
Files changed (176) hide show
  1. package/README.md +27 -0
  2. package/dist/bin/rig-agent-dispatch.js +9615 -0
  3. package/dist/bin/rig-agent.js +9512 -0
  4. package/dist/bin/rig-browser-tool.js +269 -0
  5. package/dist/src/agent-mode.js +48 -0
  6. package/dist/src/baked-secrets.js +121 -0
  7. package/dist/src/binary-build-worker.js +312 -0
  8. package/dist/src/binary-run.js +540 -0
  9. package/dist/src/boundaries.js +1 -0
  10. package/dist/src/build-time-config.js +25 -0
  11. package/dist/src/control-plane/agent-roles.js +27 -0
  12. package/dist/src/control-plane/agent-wrapper.js +9621 -0
  13. package/dist/src/control-plane/authority-files.js +582 -0
  14. package/dist/src/control-plane/browser-contract.js +135 -0
  15. package/dist/src/control-plane/controlled-bash.js +1111 -0
  16. package/dist/src/control-plane/errors.js +13 -0
  17. package/dist/src/control-plane/harness-main.js +10828 -0
  18. package/dist/src/control-plane/hook-materializer.js +75 -0
  19. package/dist/src/control-plane/hooks/audit-trail.js +353 -0
  20. package/dist/src/control-plane/hooks/completion-verification.js +7552 -0
  21. package/dist/src/control-plane/hooks/import-guard.js +890 -0
  22. package/dist/src/control-plane/hooks/inject-context.js +4189 -0
  23. package/dist/src/control-plane/hooks/post-edit-lint.js +43 -0
  24. package/dist/src/control-plane/hooks/safety-guard.js +910 -0
  25. package/dist/src/control-plane/hooks/scope-guard.js +907 -0
  26. package/dist/src/control-plane/hooks/shared.js +44 -0
  27. package/dist/src/control-plane/hooks/submodule-branch.js +7797 -0
  28. package/dist/src/control-plane/hooks/task-runtime-start.js +7799 -0
  29. package/dist/src/control-plane/hooks/test-integrity-guard.js +891 -0
  30. package/dist/src/control-plane/materialize-task-config.js +453 -0
  31. package/dist/src/control-plane/memory-sync/cli.js +2019 -0
  32. package/dist/src/control-plane/memory-sync/db.js +753 -0
  33. package/dist/src/control-plane/memory-sync/embed.js +281 -0
  34. package/dist/src/control-plane/memory-sync/index.js +2049 -0
  35. package/dist/src/control-plane/memory-sync/query.js +294 -0
  36. package/dist/src/control-plane/memory-sync/read.js +784 -0
  37. package/dist/src/control-plane/memory-sync/types.js +6 -0
  38. package/dist/src/control-plane/memory-sync/write.js +1547 -0
  39. package/dist/src/control-plane/native/git-native.js +490 -0
  40. package/dist/src/control-plane/native/git-ops.js +2860 -0
  41. package/dist/src/control-plane/native/harness-cli.js +9721 -0
  42. package/dist/src/control-plane/native/pr-automation.js +373 -0
  43. package/dist/src/control-plane/native/profile-ops.js +481 -0
  44. package/dist/src/control-plane/native/repo-ops.js +2342 -0
  45. package/dist/src/control-plane/native/root-resolver.js +66 -0
  46. package/dist/src/control-plane/native/run-ops.js +3281 -0
  47. package/dist/src/control-plane/native/runtime-native-sidecar.js +299 -0
  48. package/dist/src/control-plane/native/runtime-native.js +392 -0
  49. package/dist/src/control-plane/native/scope-rules.js +17 -0
  50. package/dist/src/control-plane/native/task-ops.js +6320 -0
  51. package/dist/src/control-plane/native/task-state.js +1512 -0
  52. package/dist/src/control-plane/native/utils.js +535 -0
  53. package/dist/src/control-plane/native/validator-binaries.js +889 -0
  54. package/dist/src/control-plane/native/validator.js +2197 -0
  55. package/dist/src/control-plane/native/verifier.js +3249 -0
  56. package/dist/src/control-plane/native/workspace-ops.js +1635 -0
  57. package/dist/src/control-plane/plugin-host-context.js +334 -0
  58. package/dist/src/control-plane/project-main-pre-run-sync.js +630 -0
  59. package/dist/src/control-plane/provider/claude-stream-records.js +158 -0
  60. package/dist/src/control-plane/provider/codex-app-server.js +885 -0
  61. package/dist/src/control-plane/provider/codex-exec-records.js +203 -0
  62. package/dist/src/control-plane/provider/rig-task-run-skill.js +39 -0
  63. package/dist/src/control-plane/provider/runtime-instructions.js +96 -0
  64. package/dist/src/control-plane/remote.js +854 -0
  65. package/dist/src/control-plane/repos/index.js +473 -0
  66. package/dist/src/control-plane/repos/layout.js +124 -0
  67. package/dist/src/control-plane/repos/mirror/bootstrap.js +268 -0
  68. package/dist/src/control-plane/repos/mirror/refresh.js +398 -0
  69. package/dist/src/control-plane/repos/mirror/state.js +167 -0
  70. package/dist/src/control-plane/repos/registry.js +77 -0
  71. package/dist/src/control-plane/repos/types.js +1 -0
  72. package/dist/src/control-plane/runtime/agent-mode.js +48 -0
  73. package/dist/src/control-plane/runtime/baked-secrets.js +120 -0
  74. package/dist/src/control-plane/runtime/claude-tool-router-binary.js +343 -0
  75. package/dist/src/control-plane/runtime/claude-tool-router.js +520 -0
  76. package/dist/src/control-plane/runtime/context.js +216 -0
  77. package/dist/src/control-plane/runtime/events.js +218 -0
  78. package/dist/src/control-plane/runtime/guard-types.js +6 -0
  79. package/dist/src/control-plane/runtime/guard.js +880 -0
  80. package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +1194 -0
  81. package/dist/src/control-plane/runtime/image/index.js +2255 -0
  82. package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +1191 -0
  83. package/dist/src/control-plane/runtime/image.js +2255 -0
  84. package/dist/src/control-plane/runtime/index.js +8511 -0
  85. package/dist/src/control-plane/runtime/isolation/discovery.js +599 -0
  86. package/dist/src/control-plane/runtime/isolation/home.js +1217 -0
  87. package/dist/src/control-plane/runtime/isolation/index.js +8193 -0
  88. package/dist/src/control-plane/runtime/isolation/runner.js +2651 -0
  89. package/dist/src/control-plane/runtime/isolation/shared.js +501 -0
  90. package/dist/src/control-plane/runtime/isolation/toolchain.js +1892 -0
  91. package/dist/src/control-plane/runtime/isolation/types.js +1 -0
  92. package/dist/src/control-plane/runtime/isolation/worktree.js +509 -0
  93. package/dist/src/control-plane/runtime/isolation.js +8193 -0
  94. package/dist/src/control-plane/runtime/overlay.js +67 -0
  95. package/dist/src/control-plane/runtime/plugin-mode.js +41 -0
  96. package/dist/src/control-plane/runtime/plugins.js +1131 -0
  97. package/dist/src/control-plane/runtime/provisioning-env.js +220 -0
  98. package/dist/src/control-plane/runtime/queue.js +8358 -0
  99. package/dist/src/control-plane/runtime/rig-shell.js +205 -0
  100. package/dist/src/control-plane/runtime/rig-tools.js +182 -0
  101. package/dist/src/control-plane/runtime/runner-context.js +1 -0
  102. package/dist/src/control-plane/runtime/runtime-paths.js +184 -0
  103. package/dist/src/control-plane/runtime/sandbox/backend-bwrap.js +311 -0
  104. package/dist/src/control-plane/runtime/sandbox/backend-none.js +21 -0
  105. package/dist/src/control-plane/runtime/sandbox/backend-seatbelt.js +268 -0
  106. package/dist/src/control-plane/runtime/sandbox/backend.js +1718 -0
  107. package/dist/src/control-plane/runtime/sandbox/orchestrator.js +1745 -0
  108. package/dist/src/control-plane/runtime/sandbox/utils.js +137 -0
  109. package/dist/src/control-plane/runtime/sandbox-backend-bwrap.js +311 -0
  110. package/dist/src/control-plane/runtime/sandbox-backend-none.js +21 -0
  111. package/dist/src/control-plane/runtime/sandbox-backend-seatbelt.js +268 -0
  112. package/dist/src/control-plane/runtime/sandbox-backend.js +1718 -0
  113. package/dist/src/control-plane/runtime/sandbox-orchestrator.js +1745 -0
  114. package/dist/src/control-plane/runtime/sandbox-utils.js +137 -0
  115. package/dist/src/control-plane/runtime/snapshot/index.js +454 -0
  116. package/dist/src/control-plane/runtime/snapshot/sidecar.js +502 -0
  117. package/dist/src/control-plane/runtime/snapshot/task-run.js +1578 -0
  118. package/dist/src/control-plane/runtime/snapshot-sidecar.js +498 -0
  119. package/dist/src/control-plane/runtime/snapshot.js +454 -0
  120. package/dist/src/control-plane/runtime/task-run-snapshot.js +1578 -0
  121. package/dist/src/control-plane/runtime/tool-gateway.js +422 -0
  122. package/dist/src/control-plane/runtime/tooling/browser-tools.js +32 -0
  123. package/dist/src/control-plane/runtime/tooling/claude-router-binary.js +343 -0
  124. package/dist/src/control-plane/runtime/tooling/claude-router.js +524 -0
  125. package/dist/src/control-plane/runtime/tooling/file-tools.js +182 -0
  126. package/dist/src/control-plane/runtime/tooling/gateway.js +422 -0
  127. package/dist/src/control-plane/runtime/tooling/index.js +1290 -0
  128. package/dist/src/control-plane/runtime/tooling/shell.js +205 -0
  129. package/dist/src/control-plane/runtime/types.js +1 -0
  130. package/dist/src/control-plane/setup-version.js +14 -0
  131. package/dist/src/control-plane/state-sync/index.js +1509 -0
  132. package/dist/src/control-plane/state-sync/read.js +856 -0
  133. package/dist/src/control-plane/state-sync/reconcile.js +260 -0
  134. package/dist/src/control-plane/state-sync/repo.js +302 -0
  135. package/dist/src/control-plane/state-sync/types.js +111 -0
  136. package/dist/src/control-plane/state-sync/write.js +1469 -0
  137. package/dist/src/control-plane/task-fields.js +38 -0
  138. package/dist/src/control-plane/task-source-bootstrap.js +46 -0
  139. package/dist/src/control-plane/task-source.js +30 -0
  140. package/dist/src/control-plane/tasks/legacy-task-config-source.js +130 -0
  141. package/dist/src/control-plane/tasks/plugin-task-source.js +103 -0
  142. package/dist/src/control-plane/tasks/source-aware-task-config-source.js +611 -0
  143. package/dist/src/control-plane/tasks/source-lifecycle.js +1093 -0
  144. package/dist/src/control-plane/tasks/task-record-reader.js +9 -0
  145. package/dist/src/control-plane/validators/boundary/public-apis.js +107 -0
  146. package/dist/src/control-plane/validators/integration/_shared.js +51 -0
  147. package/dist/src/control-plane/validators/integration/adm-audit-http.js +85 -0
  148. package/dist/src/control-plane/validators/integration/adm-auth-http.js +78 -0
  149. package/dist/src/control-plane/validators/integration/adm-issuer-http.js +80 -0
  150. package/dist/src/control-plane/validators/integration/adm-migration.js +78 -0
  151. package/dist/src/control-plane/validators/integration/adm-scaffold.js +78 -0
  152. package/dist/src/control-plane/validators/runtime-registration.js +64 -0
  153. package/dist/src/control-plane/validators/shared.js +683 -0
  154. package/dist/src/events.js +218 -0
  155. package/dist/src/execution.js +35 -0
  156. package/dist/src/index.js +1633 -0
  157. package/dist/src/layout.js +145 -0
  158. package/dist/src/local-server.js +202 -0
  159. package/dist/src/plugins.js +329 -0
  160. package/dist/src/remote-http.js +83 -0
  161. package/dist/src/runtime-context.js +216 -0
  162. package/dist/src/types.js +1 -0
  163. package/native/darwin-arm64/bin/rig-git +0 -0
  164. package/native/darwin-arm64/bin/rig-shell +0 -0
  165. package/native/darwin-arm64/bin/rig-tools +0 -0
  166. package/native/darwin-arm64/lib/runtime-native-darwin-arm64.dylib +0 -0
  167. package/native/darwin-arm64/lib/runtime-native.dylib +0 -0
  168. package/native/darwin-arm64/manifest.json +1 -0
  169. package/native/linux-x64/bin/rig-git +0 -0
  170. package/native/linux-x64/bin/rig-shell +0 -0
  171. package/native/linux-x64/bin/rig-tools +0 -0
  172. package/native/linux-x64/lib/runtime-native-linux-x64.so +0 -0
  173. package/native/linux-x64/lib/runtime-native.so +0 -0
  174. package/native/linux-x64/manifest.json +1 -0
  175. package/package.json +74 -0
  176. package/skills/rig-task-run.md +71 -0
@@ -0,0 +1,498 @@
1
+ // @bun
2
+ // packages/runtime/src/control-plane/runtime/snapshot-sidecar.ts
3
+ import { copyFileSync as copyFileSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, rmSync as rmSync2, writeFileSync } from "fs";
4
+ import { dirname as dirname2, relative, resolve as resolve2 } from "path";
5
+
6
+ // packages/runtime/src/control-plane/runtime/snapshot.ts
7
+ import { ptr as ptr2, toBuffer as toBuffer2 } from "bun:ffi";
8
+
9
+ // packages/runtime/src/control-plane/native/runtime-native.ts
10
+ import { dlopen, ptr, suffix, toBuffer } from "bun:ffi";
11
+ import { copyFileSync, existsSync, mkdirSync, renameSync, rmSync, statSync } from "fs";
12
+ import { tmpdir } from "os";
13
+ import { dirname, resolve } from "path";
14
+ var sharedNativeRuntimeOutputDir = resolve(tmpdir(), "rig-native");
15
+ var sharedNativeRuntimeOutputPath = resolve(sharedNativeRuntimeOutputDir, `runtime-native-${process.platform}-${process.arch}.${suffix}`);
16
+ var colocatedNativeRuntimeFileName = `runtime-native.${suffix}`;
17
+ var nativeRuntimeLibrary = await loadNativeRuntimeLibrary();
18
+ function requireNativeRuntimeLibrary(feature) {
19
+ if (!nativeRuntimeLibrary) {
20
+ throw new Error(`Native Zig runtime is required for ${feature}`);
21
+ }
22
+ return nativeRuntimeLibrary;
23
+ }
24
+ async function ensureNativeRuntimeLibraryPath(outputPath = sharedNativeRuntimeOutputPath, options = {}) {
25
+ if (await buildNativeRuntimeLibrary(outputPath, options)) {
26
+ return outputPath;
27
+ }
28
+ return !options.force && existsSync(outputPath) ? outputPath : null;
29
+ }
30
+ async function loadNativeRuntimeLibrary() {
31
+ if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
32
+ return null;
33
+ }
34
+ for (const candidate of nativeRuntimeLibraryCandidates()) {
35
+ if (!candidate || !existsSync(candidate)) {
36
+ continue;
37
+ }
38
+ const loaded = tryDlopenNativeRuntimeLibrary(candidate);
39
+ if (loaded) {
40
+ return loaded;
41
+ }
42
+ }
43
+ const builtLibraryPath = await ensureNativeRuntimeLibraryPath(sharedNativeRuntimeOutputPath, { force: true });
44
+ if (!builtLibraryPath) {
45
+ return null;
46
+ }
47
+ return tryDlopenNativeRuntimeLibrary(builtLibraryPath);
48
+ }
49
+ function nativePackageLibraryCandidates(fromDir, names) {
50
+ const candidates = [];
51
+ let cursor = resolve(fromDir);
52
+ for (let index = 0;index < 8; index += 1) {
53
+ for (const name of names) {
54
+ 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));
55
+ }
56
+ const parent = dirname(cursor);
57
+ if (parent === cursor)
58
+ break;
59
+ cursor = parent;
60
+ }
61
+ return candidates;
62
+ }
63
+ function nativeRuntimeLibraryCandidates() {
64
+ const explicit = process.env.RIG_NATIVE_RUNTIME_LIB?.trim() || "";
65
+ const execDir = process.execPath?.trim() ? dirname(process.execPath.trim()) : "";
66
+ const platformSpecific = `runtime-native-${process.platform}-${process.arch}.${suffix}`;
67
+ return [...new Set([
68
+ explicit,
69
+ ...nativePackageLibraryCandidates(import.meta.dir, [colocatedNativeRuntimeFileName, platformSpecific]),
70
+ execDir ? resolve(execDir, colocatedNativeRuntimeFileName) : "",
71
+ execDir ? resolve(execDir, platformSpecific) : "",
72
+ execDir ? resolve(execDir, "..", colocatedNativeRuntimeFileName) : "",
73
+ execDir ? resolve(execDir, "..", platformSpecific) : "",
74
+ execDir ? resolve(execDir, "lib", colocatedNativeRuntimeFileName) : "",
75
+ execDir ? resolve(execDir, "..", "lib", colocatedNativeRuntimeFileName) : "",
76
+ sharedNativeRuntimeOutputPath
77
+ ].filter(Boolean))];
78
+ }
79
+ function resolveNativeRuntimeSourcePath() {
80
+ const explicit = process.env.RIG_NATIVE_RUNTIME_SOURCE?.trim();
81
+ if (explicit && existsSync(explicit)) {
82
+ return explicit;
83
+ }
84
+ const bundled = resolve(import.meta.dir, "../../../native/snapshot.zig");
85
+ return existsSync(bundled) ? bundled : null;
86
+ }
87
+ async function buildNativeRuntimeLibrary(outputPath, options = {}) {
88
+ if (process.env.RIG_DISABLE_ZIG_NATIVE === "1") {
89
+ return false;
90
+ }
91
+ const zigBinary = Bun.which("zig");
92
+ const sourcePath = resolveNativeRuntimeSourcePath();
93
+ if (!zigBinary || !sourcePath) {
94
+ return false;
95
+ }
96
+ const tempOutputPath = `${outputPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
97
+ try {
98
+ mkdirSync(dirname(outputPath), { recursive: true });
99
+ const needsBuild = options.force === true || !existsSync(outputPath) || statSync(sourcePath).mtimeMs > statSync(outputPath).mtimeMs;
100
+ if (!needsBuild) {
101
+ return true;
102
+ }
103
+ const build = Bun.spawn([
104
+ zigBinary,
105
+ "build-lib",
106
+ sourcePath,
107
+ "-dynamic",
108
+ "-O",
109
+ "ReleaseFast",
110
+ `-femit-bin=${tempOutputPath}`
111
+ ], {
112
+ cwd: import.meta.dir,
113
+ stdout: "pipe",
114
+ stderr: "pipe"
115
+ });
116
+ const exitCode = await build.exited;
117
+ if (exitCode !== 0 || !existsSync(tempOutputPath)) {
118
+ rmSync(tempOutputPath, { force: true });
119
+ return false;
120
+ }
121
+ renameSync(tempOutputPath, outputPath);
122
+ return true;
123
+ } catch {
124
+ rmSync(tempOutputPath, { force: true });
125
+ return false;
126
+ }
127
+ }
128
+ function tryDlopenNativeRuntimeLibrary(outputPath) {
129
+ try {
130
+ return dlopen(outputPath, {
131
+ rig_scope_match: {
132
+ args: ["ptr", "ptr"],
133
+ returns: "u8"
134
+ },
135
+ snapshot_capture: {
136
+ args: ["ptr", "u64", "ptr", "u64"],
137
+ returns: "ptr"
138
+ },
139
+ snapshot_delta: {
140
+ args: ["ptr", "ptr"],
141
+ returns: "ptr"
142
+ },
143
+ snapshot_store_delta: {
144
+ args: ["ptr", "ptr", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
145
+ returns: "ptr"
146
+ },
147
+ snapshot_inspect_delta: {
148
+ args: ["ptr", "u64"],
149
+ returns: "ptr"
150
+ },
151
+ snapshot_apply_delta: {
152
+ args: ["ptr", "u64", "ptr", "u64"],
153
+ returns: "ptr"
154
+ },
155
+ snapshot_release: {
156
+ args: ["ptr"],
157
+ returns: "void"
158
+ },
159
+ runtime_hash_file: {
160
+ args: ["ptr", "u64"],
161
+ returns: "ptr"
162
+ },
163
+ runtime_hash_tree: {
164
+ args: ["ptr", "u64"],
165
+ returns: "ptr"
166
+ },
167
+ runtime_prepare_paths: {
168
+ args: ["ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64", "ptr", "u64"],
169
+ returns: "ptr"
170
+ },
171
+ runtime_link_dependency_layer: {
172
+ args: ["ptr", "u64", "ptr", "u64"],
173
+ returns: "ptr"
174
+ },
175
+ runtime_scan_worktrees: {
176
+ args: ["ptr", "u64"],
177
+ returns: "ptr"
178
+ }
179
+ });
180
+ } catch {
181
+ return null;
182
+ }
183
+ }
184
+
185
+ // packages/runtime/src/control-plane/runtime/snapshot.ts
186
+ var MANIFEST_HANDLE_SIZE = 40;
187
+ var DELTA_RESULT_SIZE = 72;
188
+ var FILE_ENTRY_SIZE = 40;
189
+ var DELTA_ENTRY_SIZE = 24;
190
+ var STRING_SLICE_SIZE = 16;
191
+ var STORE_RESULT_SIZE = 104;
192
+ var MANIFEST_NATIVE_HANDLE = Symbol("manifest-native-handle");
193
+ var DEFAULT_EXCLUDES = new Set([
194
+ "node_modules",
195
+ ".git",
196
+ ".worktrees",
197
+ ".tmp",
198
+ ".rig",
199
+ "artifacts"
200
+ ]);
201
+ var nativeSnapshotLibrary = requireNativeRuntimeLibrary("runtime snapshots");
202
+ var manifestReleaseRegistry = typeof FinalizationRegistry !== "undefined" ? new FinalizationRegistry((resourcePtr) => {
203
+ try {
204
+ nativeSnapshotLibrary.symbols.snapshot_release(resourcePtr);
205
+ } catch {}
206
+ }) : null;
207
+ function captureManifest(rootDir, options) {
208
+ const exclude = options?.exclude ?? DEFAULT_EXCLUDES;
209
+ const captured = captureManifestEntries(rootDir, [...exclude]);
210
+ const manifest = {
211
+ root: rootDir,
212
+ capturedAt: new Date().toISOString(),
213
+ entries: captured.entries
214
+ };
215
+ manifest[MANIFEST_NATIVE_HANDLE] = captured.nativeHandle;
216
+ manifestReleaseRegistry?.register(manifest, captured.nativeHandle, manifest);
217
+ return manifest;
218
+ }
219
+ function releaseManifest(manifest) {
220
+ if (!manifest) {
221
+ return;
222
+ }
223
+ const nativeManifest = manifest;
224
+ const handle = nativeManifest[MANIFEST_NATIVE_HANDLE];
225
+ if (!handle) {
226
+ return;
227
+ }
228
+ manifestReleaseRegistry?.unregister(manifest);
229
+ delete nativeManifest[MANIFEST_NATIVE_HANDLE];
230
+ nativeSnapshotLibrary.symbols.snapshot_release(handle);
231
+ }
232
+ function computeDelta(before, after, taskId) {
233
+ const deltaEntries = computeDeltaEntries(before, after);
234
+ return {
235
+ taskId,
236
+ baseManifestHash: computeManifestHash(before),
237
+ capturedAt: new Date().toISOString(),
238
+ modified: deltaEntries.modified,
239
+ created: deltaEntries.created,
240
+ deleted: deltaEntries.deleted
241
+ };
242
+ }
243
+ function snapshotBefore(worktreeDir, exclude) {
244
+ return captureManifest(worktreeDir, { exclude });
245
+ }
246
+ function snapshotAfter(worktreeDir, beforeManifest, taskId, outputPath, exclude) {
247
+ const afterManifest = captureManifest(worktreeDir, { exclude });
248
+ const delta = computeDelta(beforeManifest, afterManifest, taskId);
249
+ const capturedAt = new Date().toISOString();
250
+ const meta = storeSnapshotArchive(beforeManifest, afterManifest, worktreeDir, taskId, capturedAt, outputPath);
251
+ meta.beforeEntries = beforeManifest.entries.size;
252
+ meta.afterEntries = afterManifest.entries.size;
253
+ return { delta: { ...delta, capturedAt: meta.capturedAt, baseManifestHash: meta.baseManifestHash ?? delta.baseManifestHash }, meta, afterManifest };
254
+ }
255
+ function captureManifestEntries(rootDir, exclude) {
256
+ const rootBuffer = Buffer.from(rootDir, "utf8");
257
+ const excludeBuffer = Buffer.from(exclude.join("\x00"), "utf8");
258
+ const handlePtr = nativeSnapshotLibrary.symbols.snapshot_capture(Number(ptr2(rootBuffer)), rootBuffer.byteLength, Number(ptr2(excludeBuffer)), excludeBuffer.byteLength);
259
+ if (!handlePtr) {
260
+ throw new Error(`snapshot_capture returned null for ${rootDir}`);
261
+ }
262
+ const handleView = viewAt(handlePtr, MANIFEST_HANDLE_SIZE);
263
+ try {
264
+ throwIfError(nativeSnapshotLibrary.symbols, handleView, 24, 32, "snapshot_capture");
265
+ const entriesPtr = readU64(handleView, 8);
266
+ const entriesLen = readU64(handleView, 16);
267
+ const entries = new Map;
268
+ for (let index = 0;index < entriesLen; index += 1) {
269
+ const entryView = viewAt(entriesPtr + index * FILE_ENTRY_SIZE, FILE_ENTRY_SIZE);
270
+ const path = readString(readU64(entryView, 0), readU64(entryView, 8));
271
+ entries.set(path, {
272
+ path,
273
+ hash: readBigU64(entryView, 16).toString(16),
274
+ size: readU64(entryView, 24),
275
+ mode: readU64(entryView, 32)
276
+ });
277
+ }
278
+ return {
279
+ entries,
280
+ nativeHandle: handlePtr
281
+ };
282
+ } catch (error) {
283
+ nativeSnapshotLibrary.symbols.snapshot_release(handlePtr);
284
+ throw error;
285
+ }
286
+ }
287
+ function computeDeltaEntries(before, after) {
288
+ const beforeHandle = before[MANIFEST_NATIVE_HANDLE];
289
+ const afterHandle = after[MANIFEST_NATIVE_HANDLE];
290
+ if (!beforeHandle || !afterHandle) {
291
+ throw new Error("snapshot manifests must carry native handles");
292
+ }
293
+ const resultPtr = nativeSnapshotLibrary.symbols.snapshot_delta(beforeHandle, afterHandle);
294
+ if (!resultPtr) {
295
+ throw new Error("snapshot_delta returned null");
296
+ }
297
+ try {
298
+ const resultView = viewAt(resultPtr, DELTA_RESULT_SIZE);
299
+ throwIfError(nativeSnapshotLibrary.symbols, resultView, 56, 64, "snapshot_delta");
300
+ return {
301
+ modified: readDeltaEntries(readU64(resultView, 8), readU64(resultView, 16)),
302
+ created: readDeltaEntries(readU64(resultView, 24), readU64(resultView, 32)),
303
+ deleted: readStringSliceArray(readU64(resultView, 40), readU64(resultView, 48))
304
+ };
305
+ } finally {
306
+ nativeSnapshotLibrary.symbols.snapshot_release(resultPtr);
307
+ }
308
+ }
309
+ function storeSnapshotArchive(beforeManifest, afterManifest, worktreeDir, taskId, capturedAt, outputPath) {
310
+ const beforeHandle = beforeManifest[MANIFEST_NATIVE_HANDLE];
311
+ const afterHandle = afterManifest[MANIFEST_NATIVE_HANDLE];
312
+ if (!beforeHandle || !afterHandle) {
313
+ throw new Error("snapshot manifests must carry native handles");
314
+ }
315
+ const worktreeBuffer = Buffer.from(worktreeDir, "utf8");
316
+ const taskBuffer = Buffer.from(taskId, "utf8");
317
+ const capturedAtBuffer = Buffer.from(capturedAt, "utf8");
318
+ const outputBuffer = Buffer.from(outputPath, "utf8");
319
+ 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);
320
+ if (!resultPtr) {
321
+ throw new Error(`snapshot_store_delta returned null for ${outputPath}`);
322
+ }
323
+ try {
324
+ const resultView = viewAt(resultPtr, STORE_RESULT_SIZE);
325
+ throwIfError(nativeSnapshotLibrary.symbols, resultView, 88, 96, "snapshot_store_delta");
326
+ return {
327
+ taskId,
328
+ baseManifestHash: readString(readU64(resultView, 8), readU64(resultView, 16)),
329
+ capturedAt: readString(readU64(resultView, 24), readU64(resultView, 32)),
330
+ beforeEntries: 0,
331
+ afterEntries: 0,
332
+ modifiedCount: readU64(resultView, 40),
333
+ createdCount: readU64(resultView, 48),
334
+ deletedCount: readU64(resultView, 56),
335
+ blobCount: readU64(resultView, 64),
336
+ blobsSize: readU64(resultView, 72),
337
+ compressedSize: readU64(resultView, 80)
338
+ };
339
+ } finally {
340
+ nativeSnapshotLibrary.symbols.snapshot_release(resultPtr);
341
+ }
342
+ }
343
+ function computeManifestHash(manifest) {
344
+ const sorted = [...manifest.entries.values()].sort((left, right) => left.path.localeCompare(right.path));
345
+ const hasher = new Bun.CryptoHasher("sha256");
346
+ for (const entry of sorted) {
347
+ hasher.update(entry.path);
348
+ hasher.update("\x00");
349
+ hasher.update(entry.hash);
350
+ hasher.update("\x00");
351
+ hasher.update(String(entry.size));
352
+ hasher.update("\x00");
353
+ hasher.update(String(entry.mode));
354
+ }
355
+ return hasher.digest("hex");
356
+ }
357
+ function readDeltaEntries(pointer, count) {
358
+ const values = [];
359
+ for (let index = 0;index < count; index += 1) {
360
+ const entryView = viewAt(pointer + index * DELTA_ENTRY_SIZE, DELTA_ENTRY_SIZE);
361
+ values.push({
362
+ path: readString(readU64(entryView, 0), readU64(entryView, 8)),
363
+ hash: readBigU64(entryView, 16).toString(16)
364
+ });
365
+ }
366
+ return values;
367
+ }
368
+ function readStringSliceArray(pointer, count) {
369
+ const values = [];
370
+ for (let index = 0;index < count; index += 1) {
371
+ const entryView = viewAt(pointer + index * STRING_SLICE_SIZE, STRING_SLICE_SIZE);
372
+ values.push(readString(readU64(entryView, 0), readU64(entryView, 8)));
373
+ }
374
+ return values;
375
+ }
376
+ function viewAt(pointer, size) {
377
+ const buffer = toBuffer2(pointer, 0, size);
378
+ return new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
379
+ }
380
+ function readString(pointer, length) {
381
+ if (!pointer || length === 0) {
382
+ return "";
383
+ }
384
+ return Buffer.from(toBuffer2(pointer, 0, length)).toString("utf8");
385
+ }
386
+ function readU64(view, offset) {
387
+ return Number(view.getBigUint64(offset, true));
388
+ }
389
+ function readBigU64(view, offset) {
390
+ return view.getBigUint64(offset, true);
391
+ }
392
+ function readError(view, pointerOffset, lengthOffset) {
393
+ const errorPointer = readU64(view, pointerOffset);
394
+ const errorLength = readU64(view, lengthOffset);
395
+ if (!errorPointer || !errorLength) {
396
+ return null;
397
+ }
398
+ return readString(errorPointer, errorLength);
399
+ }
400
+ function throwIfError(_symbols, view, pointerOffset, lengthOffset, label) {
401
+ const error = readError(view, pointerOffset, lengthOffset);
402
+ if (error) {
403
+ throw new Error(`${label} failed: ${error}`);
404
+ }
405
+ }
406
+ var __testOnly = {
407
+ defaultExcludes: [...DEFAULT_EXCLUDES]
408
+ };
409
+
410
+ // packages/runtime/src/control-plane/runtime/snapshot-sidecar.ts
411
+ function parseArgs(argv) {
412
+ const values = new Map;
413
+ for (let index = 0;index < argv.length; index += 2) {
414
+ values.set(argv[index] ?? "", argv[index + 1] ?? "");
415
+ }
416
+ const workspaceDir = values.get("--workspace") ?? "";
417
+ const taskId = values.get("--task") ?? "";
418
+ const runtimeId = values.get("--runtime-id") ?? "";
419
+ const instanceId = values.get("--instance-id") ?? runtimeId;
420
+ const readyFile = values.get("--ready-file") ?? "";
421
+ const requestFile = values.get("--request-file") ?? "";
422
+ if (!workspaceDir || !taskId || !runtimeId || !instanceId || !readyFile || !requestFile) {
423
+ throw new Error("Usage: snapshot-sidecar.ts --workspace <dir> --task <id> --runtime-id <id> [--instance-id <id>] --ready-file <path> --request-file <path>");
424
+ }
425
+ return { workspaceDir, taskId, runtimeId, instanceId, readyFile, requestFile };
426
+ }
427
+ function sanitizeRuntimeRefSegment(value) {
428
+ const sanitized = value.trim().replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
429
+ return (sanitized || "runtime").slice(0, 64);
430
+ }
431
+ var waitBuffer = new Int32Array(new SharedArrayBuffer(4));
432
+ function readPayload(requestFile) {
433
+ while (!existsSync2(requestFile)) {
434
+ Atomics.wait(waitBuffer, 0, 0, 25);
435
+ }
436
+ const raw = readFileSync(requestFile, "utf-8").trim();
437
+ const payload = JSON.parse(raw);
438
+ if (!Array.isArray(payload.command) || typeof payload.exitCode !== "number") {
439
+ throw new Error("snapshot sidecar received malformed finalize payload");
440
+ }
441
+ return {
442
+ command: payload.command.map((part) => String(part)),
443
+ exitCode: payload.exitCode
444
+ };
445
+ }
446
+ async function runRuntimeSnapshotSidecar(argv = process.argv.slice(2)) {
447
+ const options = parseArgs(argv);
448
+ const beforeManifest = snapshotBefore(options.workspaceDir);
449
+ let afterManifest;
450
+ try {
451
+ mkdirSync2(dirname2(options.readyFile), { recursive: true });
452
+ writeFileSync(options.readyFile, `ready
453
+ `, "utf-8");
454
+ const payload = readPayload(options.requestFile);
455
+ const artifactDir = resolve2(options.workspaceDir, "artifacts", options.taskId, "runtime-snapshots");
456
+ mkdirSync2(artifactDir, { recursive: true });
457
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
458
+ const historyStem = `${timestamp}-${sanitizeRuntimeRefSegment(options.instanceId)}`;
459
+ const snapshotPath = resolve2(artifactDir, `${historyStem}.snap.bin`);
460
+ const latestSnapshotPath = resolve2(artifactDir, "latest.snap.bin");
461
+ const historyMetaPath = resolve2(artifactDir, `${historyStem}.json`);
462
+ const latestMetaPath = resolve2(artifactDir, "latest.json");
463
+ const result = snapshotAfter(options.workspaceDir, beforeManifest, options.taskId, snapshotPath);
464
+ afterManifest = result.afterManifest;
465
+ const metaPayload = {
466
+ taskId: options.taskId,
467
+ runtimeId: options.runtimeId,
468
+ exitCode: payload.exitCode,
469
+ command: payload.command,
470
+ workspaceDir: options.workspaceDir,
471
+ sidecarInstanceId: options.instanceId,
472
+ snapshotPath: relative(options.workspaceDir, snapshotPath).replaceAll("\\", "/"),
473
+ latestSnapshotPath: relative(options.workspaceDir, latestSnapshotPath).replaceAll("\\", "/"),
474
+ meta: result.meta,
475
+ recordedAt: new Date().toISOString()
476
+ };
477
+ copyFileSync2(snapshotPath, latestSnapshotPath);
478
+ writeFileSync(historyMetaPath, `${JSON.stringify(metaPayload, null, 2)}
479
+ `, "utf-8");
480
+ writeFileSync(latestMetaPath, `${JSON.stringify(metaPayload, null, 2)}
481
+ `, "utf-8");
482
+ console.log(JSON.stringify(metaPayload));
483
+ } finally {
484
+ releaseManifest(beforeManifest);
485
+ releaseManifest(afterManifest);
486
+ rmSync2(options.readyFile, { force: true });
487
+ rmSync2(options.requestFile, { force: true });
488
+ }
489
+ }
490
+ if (import.meta.main) {
491
+ runRuntimeSnapshotSidecar().catch((error) => {
492
+ console.error(error instanceof Error ? error.message : String(error));
493
+ process.exit(1);
494
+ });
495
+ }
496
+ export {
497
+ runRuntimeSnapshotSidecar
498
+ };