@vibgrate/cli 2026.722.2 → 2026.727.1

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 (125) hide show
  1. package/DOCS.md +418 -196
  2. package/README.md +34 -7
  3. package/dist/baseline-K7YBFKZI.js +7 -0
  4. package/dist/{baseline-BD3A7EXD.js.map → baseline-K7YBFKZI.js.map} +1 -1
  5. package/dist/chunk-3BVSDMHV.js +2496 -0
  6. package/dist/chunk-3BVSDMHV.js.map +1 -0
  7. package/dist/{chunk-PY3DNX5H.js → chunk-3Q7QBWFW.js} +13 -2
  8. package/dist/chunk-3Q7QBWFW.js.map +1 -0
  9. package/dist/chunk-4CQ3MGNN.js +136 -0
  10. package/dist/chunk-4CQ3MGNN.js.map +1 -0
  11. package/dist/chunk-5I4VSBWQ.js +764 -0
  12. package/dist/chunk-5I4VSBWQ.js.map +1 -0
  13. package/dist/chunk-5Q54GEHM.js +29 -0
  14. package/dist/chunk-5Q54GEHM.js.map +1 -0
  15. package/dist/{chunk-2O5YZVZV.js → chunk-65MEOA4E.js} +21 -18
  16. package/dist/chunk-65MEOA4E.js.map +1 -0
  17. package/dist/{chunk-WNIIKCNF.js → chunk-6IOQJGFT.js} +29 -238
  18. package/dist/chunk-6IOQJGFT.js.map +1 -0
  19. package/dist/{chunk-CS37OBE3.js → chunk-7JHPQ6WF.js} +791 -783
  20. package/dist/chunk-7JHPQ6WF.js.map +1 -0
  21. package/dist/chunk-BPF3YX2U.js +64 -0
  22. package/dist/chunk-BPF3YX2U.js.map +1 -0
  23. package/dist/chunk-BWPBB45M.js +88 -0
  24. package/dist/chunk-BWPBB45M.js.map +1 -0
  25. package/dist/chunk-C4CKTAZP.js +1695 -0
  26. package/dist/chunk-C4CKTAZP.js.map +1 -0
  27. package/dist/chunk-EDAAG7BL.js +612 -0
  28. package/dist/chunk-EDAAG7BL.js.map +1 -0
  29. package/dist/chunk-EDBV33B7.js +57 -0
  30. package/dist/chunk-EDBV33B7.js.map +1 -0
  31. package/dist/chunk-HABUT7HW.js +233 -0
  32. package/dist/chunk-HABUT7HW.js.map +1 -0
  33. package/dist/{chunk-NONYJLOJ.js → chunk-HYZVHJ3Q.js} +3 -3
  34. package/dist/{chunk-NONYJLOJ.js.map → chunk-HYZVHJ3Q.js.map} +1 -1
  35. package/dist/chunk-IS7VTH2Q.js +627 -0
  36. package/dist/chunk-IS7VTH2Q.js.map +1 -0
  37. package/dist/chunk-IZDH67DX.js +289 -0
  38. package/dist/chunk-IZDH67DX.js.map +1 -0
  39. package/dist/chunk-J7LKEB2R.js +51 -0
  40. package/dist/chunk-J7LKEB2R.js.map +1 -0
  41. package/dist/chunk-JIBOJTGS.js +313 -0
  42. package/dist/chunk-JIBOJTGS.js.map +1 -0
  43. package/dist/chunk-JZYGEZTU.js +82 -0
  44. package/dist/chunk-JZYGEZTU.js.map +1 -0
  45. package/dist/chunk-K7REHDQS.js +776 -0
  46. package/dist/chunk-K7REHDQS.js.map +1 -0
  47. package/dist/chunk-KHJO4D5N.js +108 -0
  48. package/dist/chunk-KHJO4D5N.js.map +1 -0
  49. package/dist/chunk-NDMDSPFX.js +69 -0
  50. package/dist/chunk-NDMDSPFX.js.map +1 -0
  51. package/dist/chunk-OOIG3RUM.js +276 -0
  52. package/dist/chunk-OOIG3RUM.js.map +1 -0
  53. package/dist/{chunk-6CXTPC74.js → chunk-OXQNQW5J.js} +27 -6
  54. package/dist/chunk-OXQNQW5J.js.map +1 -0
  55. package/dist/chunk-PMYWZRRS.js +62 -0
  56. package/dist/chunk-PMYWZRRS.js.map +1 -0
  57. package/dist/chunk-PXHNTC6D.js +382 -0
  58. package/dist/chunk-PXHNTC6D.js.map +1 -0
  59. package/dist/{chunk-3MXNNBLI.js → chunk-S6CYDZEW.js} +1395 -1975
  60. package/dist/chunk-S6CYDZEW.js.map +1 -0
  61. package/dist/chunk-SZLF66FJ.js +843 -0
  62. package/dist/chunk-SZLF66FJ.js.map +1 -0
  63. package/dist/chunk-VXGV6NTD.js +476 -0
  64. package/dist/chunk-VXGV6NTD.js.map +1 -0
  65. package/dist/{chunk-5BDHQ7DD.js → chunk-WLETRGAC.js} +16 -9
  66. package/dist/chunk-WLETRGAC.js.map +1 -0
  67. package/dist/{chunk-I7GY7MVN.js → chunk-YDAT7LD2.js} +51 -11
  68. package/dist/chunk-YDAT7LD2.js.map +1 -0
  69. package/dist/cli.js +3412 -513
  70. package/dist/cli.js.map +1 -1
  71. package/dist/execution-env-3BN7Z737.js +3 -0
  72. package/dist/execution-env-3BN7Z737.js.map +1 -0
  73. package/dist/federation-EPZDUWCK.js +6 -0
  74. package/dist/federation-EPZDUWCK.js.map +1 -0
  75. package/dist/git-ref-HPRLUFFW.js +3 -0
  76. package/dist/git-ref-HPRLUFFW.js.map +1 -0
  77. package/dist/graph-backend-ZMSYOZMW.js +10 -0
  78. package/dist/graph-backend-ZMSYOZMW.js.map +1 -0
  79. package/dist/index.d.ts +432 -126
  80. package/dist/index.js +14 -7
  81. package/dist/index.js.map +1 -1
  82. package/dist/{interactive-A4DISSIW.js → interactive-ICL7D7LO.js} +185 -226
  83. package/dist/interactive-ICL7D7LO.js.map +1 -0
  84. package/dist/llm-host-2RAYQSDQ.js +8 -0
  85. package/dist/llm-host-2RAYQSDQ.js.map +1 -0
  86. package/dist/load-OHVKDX4R.js +7 -0
  87. package/dist/load-OHVKDX4R.js.map +1 -0
  88. package/dist/local-runtime-OJFLX2HI.js +4 -0
  89. package/dist/local-runtime-OJFLX2HI.js.map +1 -0
  90. package/dist/model-execution-profile-MQ2QCP24.js +3 -0
  91. package/dist/model-execution-profile-MQ2QCP24.js.map +1 -0
  92. package/dist/model-orchestrator-FFTZI3U2.js +8 -0
  93. package/dist/model-orchestrator-FFTZI3U2.js.map +1 -0
  94. package/dist/parse-worker.d.ts +1 -1
  95. package/dist/parse-worker.js +1 -1
  96. package/dist/paths-MCH75O3G.js +5 -0
  97. package/dist/paths-MCH75O3G.js.map +1 -0
  98. package/dist/resolve-gguf-4UPIGPEE.js +7 -0
  99. package/dist/resolve-gguf-4UPIGPEE.js.map +1 -0
  100. package/dist/runtime-session-IDU5BDUJ.js +17 -0
  101. package/dist/runtime-session-IDU5BDUJ.js.map +1 -0
  102. package/dist/session-L2OSDRPI.js +10 -0
  103. package/dist/{session-POJUDFPH.js.map → session-L2OSDRPI.js.map} +1 -1
  104. package/dist/{stream-json-Q2JGWPHB.js → stream-json-F74W5FCK.js} +16 -6
  105. package/dist/stream-json-F74W5FCK.js.map +1 -0
  106. package/dist/{types-Jl6RJ175.d.ts → types-ZMg1mSuu.d.ts} +3 -1
  107. package/dist/vgd-EGBQD7BW.js +16 -0
  108. package/dist/vgd-EGBQD7BW.js.map +1 -0
  109. package/package.json +9 -6
  110. package/dist/baseline-BD3A7EXD.js +0 -7
  111. package/dist/chunk-2O5YZVZV.js.map +0 -1
  112. package/dist/chunk-3MXNNBLI.js.map +0 -1
  113. package/dist/chunk-5BDHQ7DD.js.map +0 -1
  114. package/dist/chunk-6CXTPC74.js.map +0 -1
  115. package/dist/chunk-CS37OBE3.js.map +0 -1
  116. package/dist/chunk-GGJZA3Q6.js +0 -961
  117. package/dist/chunk-GGJZA3Q6.js.map +0 -1
  118. package/dist/chunk-I7GY7MVN.js.map +0 -1
  119. package/dist/chunk-JBXNQCGE.js +0 -484
  120. package/dist/chunk-JBXNQCGE.js.map +0 -1
  121. package/dist/chunk-PY3DNX5H.js.map +0 -1
  122. package/dist/chunk-WNIIKCNF.js.map +0 -1
  123. package/dist/interactive-A4DISSIW.js.map +0 -1
  124. package/dist/session-POJUDFPH.js +0 -6
  125. package/dist/stream-json-Q2JGWPHB.js.map +0 -1
@@ -0,0 +1,627 @@
1
+ import * as fs3 from 'fs';
2
+ import * as os from 'os';
3
+ import * as path3 from 'path';
4
+ import { spawnSync } from 'child_process';
5
+
6
+ // src/runtime/execution-env.ts
7
+ function buildFirecrackerConfig(paths, options) {
8
+ const bootArgs = [
9
+ "console=ttyS0",
10
+ "reboot=k",
11
+ "panic=1",
12
+ "pci=off",
13
+ "init=/sbin/vg-agent-init",
14
+ `vg_cmd=${encodeURIComponent(options.command)}`
15
+ ];
16
+ if (options.denyNetwork !== false) bootArgs.push("vg_net=off");
17
+ const cfg = {
18
+ "boot-source": {
19
+ kernel_image_path: paths.kernel,
20
+ boot_args: bootArgs.join(" ")
21
+ },
22
+ drives: [
23
+ {
24
+ drive_id: "rootfs",
25
+ path_on_host: paths.rootfs,
26
+ is_root_device: true,
27
+ is_read_only: false
28
+ }
29
+ ],
30
+ "machine-config": {
31
+ vcpu_count: options.vcpuCount ?? 1,
32
+ mem_size_mib: options.memSizeMib ?? 512,
33
+ smt: false
34
+ }
35
+ };
36
+ cfg["vg-writable-roots"] = [...options.writableRoots].map((r) => path3.resolve(r)).sort((a, b) => a.localeCompare(b));
37
+ if (options.denyNetwork === false) {
38
+ cfg["network-interfaces"] = [
39
+ {
40
+ iface_id: "eth0",
41
+ guest_mac: "06:00:00:00:00:01",
42
+ host_dev_name: "vmtap0"
43
+ }
44
+ ];
45
+ }
46
+ return cfg;
47
+ }
48
+ function firecrackerArgv(binary, configPath) {
49
+ return [binary, "--config-file", configPath, "--no-api"];
50
+ }
51
+ function resolveFirecrackerPaths(env = process.env, probeExists = (p) => {
52
+ try {
53
+ return fs3.existsSync(p);
54
+ } catch {
55
+ return false;
56
+ }
57
+ }) {
58
+ const binary = env.VIBGRATE_FIRECRACKER_BIN || which("firecracker") || "";
59
+ const kernel = env.VIBGRATE_FIRECRACKER_KERNEL || "";
60
+ const rootfs = env.VIBGRATE_FIRECRACKER_ROOTFS || "";
61
+ if (!binary || !kernel || !rootfs) return null;
62
+ if (!probeExists(binary) || !probeExists(kernel) || !probeExists(rootfs)) return null;
63
+ return { binary, kernel, rootfs };
64
+ }
65
+ function tryCreateFirecrackerEnv(options) {
66
+ const paths = options.paths === void 0 ? resolveFirecrackerPaths() : options.paths;
67
+ if (!paths) return null;
68
+ const denyNetwork = options.denyNetwork !== false;
69
+ const reason = options.reason ?? "L3 Firecracker microVM";
70
+ return {
71
+ tier: "L3",
72
+ label: "firecracker",
73
+ reason,
74
+ run(command, runOpts) {
75
+ const roots = options.writableRoots.length ? options.writableRoots : [runOpts.cwd];
76
+ const configPath = path3.join(
77
+ process.env.TMPDIR || "/tmp",
78
+ `vg-fc-${process.pid}-${Date.now()}.json`
79
+ );
80
+ const cfg = buildFirecrackerConfig(paths, {
81
+ writableRoots: roots,
82
+ command,
83
+ denyNetwork});
84
+ try {
85
+ fs3.writeFileSync(configPath, `${JSON.stringify(cfg, null, 2)}
86
+ `, {
87
+ encoding: "utf8",
88
+ mode: 384
89
+ });
90
+ const argv = firecrackerArgv(paths.binary, configPath);
91
+ const res = spawnSync(argv[0], argv.slice(1), {
92
+ encoding: "utf8",
93
+ timeout: runOpts.timeoutMs ?? 12e4,
94
+ maxBuffer: 10 * 1024 * 1024,
95
+ env: process.env
96
+ });
97
+ const stdout = (res.stdout ?? "") + (res.stderr ? `
98
+ ${res.stderr}` : "");
99
+ if (res.error) {
100
+ return {
101
+ stdout: `firecracker failed to start: ${res.error.message}`,
102
+ exitCode: 1
103
+ };
104
+ }
105
+ return { stdout, exitCode: res.status ?? 1 };
106
+ } finally {
107
+ try {
108
+ fs3.unlinkSync(configPath);
109
+ } catch {
110
+ }
111
+ }
112
+ }
113
+ };
114
+ }
115
+ function which(bin) {
116
+ try {
117
+ const res = spawnSync(process.platform === "win32" ? "where" : "which", [bin], {
118
+ encoding: "utf8"
119
+ });
120
+ if (res.status !== 0) return null;
121
+ const line = (res.stdout ?? "").trim().split("\n")[0]?.trim();
122
+ return line || null;
123
+ } catch {
124
+ return null;
125
+ }
126
+ }
127
+
128
+ // src/runtime/sandbox-backend.ts
129
+ function detectSandboxCapabilities(platform = process.platform) {
130
+ const backends = [];
131
+ if (platform === "darwin") {
132
+ const seatbelt = commandOnPath("sandbox-exec");
133
+ backends.push({
134
+ id: "seatbelt",
135
+ tier: "L1",
136
+ available: seatbelt,
137
+ reason: seatbelt ? "sandbox-exec present" : "sandbox-exec not found"
138
+ });
139
+ }
140
+ if (platform === "linux") {
141
+ const bwrap = commandOnPath("bwrap");
142
+ backends.push({
143
+ id: "bwrap",
144
+ tier: "L1",
145
+ available: bwrap,
146
+ reason: bwrap ? "bubblewrap present" : "bwrap not found"
147
+ });
148
+ const firejail = commandOnPath("firejail");
149
+ backends.push({
150
+ id: "firejail",
151
+ tier: "L2",
152
+ available: firejail,
153
+ reason: firejail ? "firejail present" : "firejail not found"
154
+ });
155
+ const runsc = commandOnPath("runsc");
156
+ backends.push({
157
+ id: "gvisor",
158
+ tier: "L2",
159
+ available: runsc,
160
+ reason: runsc ? "gVisor runsc present" : "runsc not found"
161
+ });
162
+ }
163
+ const fc = resolveFirecrackerPaths();
164
+ backends.push({
165
+ id: "firecracker",
166
+ tier: "L3",
167
+ available: !!fc,
168
+ reason: fc ? `Firecracker configured (${fc.binary})` : "Firecracker unset \u2014 set VIBGRATE_FIRECRACKER_BIN, _KERNEL, _ROOTFS"
169
+ });
170
+ backends.push({
171
+ id: "host",
172
+ tier: "L0",
173
+ available: true,
174
+ reason: "always available"
175
+ });
176
+ let bestTier = "L0";
177
+ for (const b of backends) {
178
+ if (!b.available) continue;
179
+ if (tierRank(b.tier) > tierRank(bestTier)) bestTier = b.tier;
180
+ }
181
+ return { platform, backends, bestTier };
182
+ }
183
+ function selectSandboxBackend(requested, caps = detectSandboxCapabilities()) {
184
+ const want = tierRank(requested);
185
+ const available = caps.backends.filter((b) => b.available);
186
+ const exact = available.find((b) => b.tier === requested && b.id !== "host");
187
+ if (exact) return exact;
188
+ const stronger = available.filter((b) => tierRank(b.tier) >= want && b.id !== "host").sort((a, b) => tierRank(a.tier) - tierRank(b.tier));
189
+ if (stronger[0]) return stronger[0];
190
+ const weaker = available.filter((b) => tierRank(b.tier) < want).sort((a, b) => tierRank(b.tier) - tierRank(a.tier));
191
+ if (weaker[0]) return weaker[0];
192
+ return available.find((b) => b.id === "host") ?? {
193
+ id: "host",
194
+ tier: "L0",
195
+ available: true,
196
+ reason: "fallback host"
197
+ };
198
+ }
199
+ function firejailArgv(writableRoots, command, options = {}) {
200
+ const args = [
201
+ "firejail",
202
+ "--quiet",
203
+ "--noprofile",
204
+ "--private-tmp",
205
+ "--nonewprivs",
206
+ "--nogroups"
207
+ ];
208
+ if (options.denyNetwork !== false) args.push("--net=none");
209
+ for (const root of writableRoots) {
210
+ args.push(`--whitelist=${root}`);
211
+ }
212
+ if (options.cwd) args.push(`--whitelist=${options.cwd}`);
213
+ args.push("--", "/bin/sh", "-c", command);
214
+ return args;
215
+ }
216
+ function tierRank(t) {
217
+ if (t === "L0") return 0;
218
+ if (t === "L1") return 1;
219
+ if (t === "L2") return 2;
220
+ return 3;
221
+ }
222
+ function commandOnPath(bin) {
223
+ try {
224
+ const res = spawnSync(process.platform === "win32" ? "where" : "which", [bin], { encoding: "utf8" });
225
+ return res.status === 0 && Boolean(res.stdout?.trim());
226
+ } catch {
227
+ return false;
228
+ }
229
+ }
230
+ function gvisorArgv(paths, options) {
231
+ const args = [
232
+ paths.binary,
233
+ "--rootless=true",
234
+ "--network=" + (options.denyNetwork === false ? "host" : "none"),
235
+ "do",
236
+ "--rootfs-path",
237
+ paths.rootfs
238
+ ];
239
+ for (const root of [...options.writableRoots].map((r) => path3.resolve(r)).sort()) {
240
+ args.push("--bind", `${root}:${root}:rw`);
241
+ }
242
+ if (options.cwd) {
243
+ args.push("--cwd", path3.resolve(options.cwd));
244
+ }
245
+ args.push("--", "/bin/sh", "-c", options.command);
246
+ return args;
247
+ }
248
+ function resolveGvisorPaths(env = process.env, probeExists = (p) => {
249
+ try {
250
+ return fs3.existsSync(p);
251
+ } catch {
252
+ return false;
253
+ }
254
+ }, which2 = whichBin) {
255
+ const binary = env.VIBGRATE_GVISOR_BIN || which2("runsc") || "";
256
+ const rootfs = env.VIBGRATE_GVISOR_ROOTFS || "";
257
+ if (!binary || !rootfs) return null;
258
+ if (!probeExists(binary) || !probeExists(rootfs)) return null;
259
+ return { binary, rootfs };
260
+ }
261
+ function tryCreateGvisorEnv(options) {
262
+ const paths = options.paths === void 0 ? resolveGvisorPaths() : options.paths;
263
+ if (!paths) return null;
264
+ const denyNetwork = options.denyNetwork !== false;
265
+ return {
266
+ tier: "L2",
267
+ label: "gvisor",
268
+ reason: options.reason ?? "L2 gVisor runsc",
269
+ run(command, runOpts) {
270
+ const roots = options.writableRoots.length ? options.writableRoots : [runOpts.cwd];
271
+ const argv = gvisorArgv(paths, {
272
+ writableRoots: roots,
273
+ command,
274
+ denyNetwork,
275
+ cwd: runOpts.cwd
276
+ });
277
+ const res = spawnSync(argv[0], argv.slice(1), {
278
+ encoding: "utf8",
279
+ timeout: runOpts.timeoutMs ?? 12e4,
280
+ maxBuffer: 10 * 1024 * 1024,
281
+ env: process.env
282
+ });
283
+ if (res.error) {
284
+ return { stdout: `gvisor failed to start: ${res.error.message}`, exitCode: 1 };
285
+ }
286
+ const stdout = (res.stdout ?? "") + (res.stderr ? `
287
+ ${res.stderr}` : "");
288
+ return { stdout, exitCode: res.status ?? 1 };
289
+ }
290
+ };
291
+ }
292
+ function whichBin(bin) {
293
+ try {
294
+ const res = spawnSync(process.platform === "win32" ? "where" : "which", [bin], {
295
+ encoding: "utf8"
296
+ });
297
+ if (res.status !== 0) return null;
298
+ return (res.stdout ?? "").trim().split("\n")[0]?.trim() || null;
299
+ } catch {
300
+ return null;
301
+ }
302
+ }
303
+
304
+ // src/runtime/execution-env.ts
305
+ function detectSecurityCapabilities(platform = process.platform) {
306
+ if (platform === "linux") {
307
+ return {
308
+ platform,
309
+ landlock: linuxLandlockAvailable(),
310
+ seatbelt: false,
311
+ bubblewrap: commandOnPath2("bwrap"),
312
+ firejail: commandOnPath2("firejail"),
313
+ gvisor: commandOnPath2("runsc")
314
+ };
315
+ }
316
+ if (platform === "darwin") {
317
+ return {
318
+ platform,
319
+ landlock: false,
320
+ seatbelt: macSeatbeltAvailable(),
321
+ bubblewrap: false,
322
+ firejail: false,
323
+ gvisor: false
324
+ };
325
+ }
326
+ return { platform, landlock: false, seatbelt: false, bubblewrap: false, firejail: false, gvisor: false };
327
+ }
328
+ function resolveExecutionEnv(requested = "L0", options = {}) {
329
+ const caps = options.capabilities ?? detectSecurityCapabilities();
330
+ const writableRoots = normalizeRoots(options.writableRoots);
331
+ const denyNetwork = options.denyNetwork !== false;
332
+ if (requested === "L0") return createHostExecutionEnv("explicit L0");
333
+ if (requested === "L3") {
334
+ const l3 = tryCreateFirecrackerEnv({
335
+ writableRoots,
336
+ denyNetwork,
337
+ reason: "L3 Firecracker microVM"
338
+ });
339
+ if (l3) return l3;
340
+ const l2 = tryCreateL2Env(caps, writableRoots, denyNetwork, requested);
341
+ if (l2) return l2;
342
+ const l1 = tryCreateL1Env(caps, writableRoots, denyNetwork, requested);
343
+ if (l1) return l1;
344
+ return createHostExecutionEnv("L3 not available (Firecracker images unset) \u2014 falling back to L0");
345
+ }
346
+ if (requested === "L2") {
347
+ const l2 = tryCreateL2Env(caps, writableRoots, denyNetwork, requested);
348
+ if (l2) return l2;
349
+ const l1 = tryCreateL1Env(caps, writableRoots, denyNetwork, requested);
350
+ if (l1) return l1;
351
+ return createHostExecutionEnv(`${requested} not available \u2014 falling back to L0`);
352
+ }
353
+ if (requested === "L1") {
354
+ const l1 = tryCreateL1Env(caps, writableRoots, denyNetwork, requested);
355
+ if (l1) return l1;
356
+ return createHostExecutionEnv("L1 requested but no Seatbelt/bubblewrap \u2014 falling back to L0");
357
+ }
358
+ return createHostExecutionEnv("unknown tier \u2014 falling back to L0");
359
+ }
360
+ function createHostExecutionEnv(reason = "host process") {
361
+ return {
362
+ tier: "L0",
363
+ label: "host",
364
+ reason,
365
+ run(command, options) {
366
+ return hostRun(command, options);
367
+ }
368
+ };
369
+ }
370
+ function buildSeatbeltProfile(writableRoots, options = {}) {
371
+ const roots = uniqueResolved([...writableRoots, ...options.tempRoots ?? defaultTempRoots()]);
372
+ const lines = [
373
+ "(version 1)",
374
+ "(deny default)",
375
+ "(allow process*)",
376
+ "(allow sysctl-read)",
377
+ "(allow mach*)",
378
+ "(allow system-socket)",
379
+ "(allow file-read*)",
380
+ '(allow file-write-data (literal "/dev/null"))',
381
+ '(allow file-write-data (literal "/dev/zero"))',
382
+ "(allow file-ioctl)",
383
+ '(allow file-write* (literal "/dev/tty"))',
384
+ '(allow file-write* (literal "/dev/dtracehelper"))'
385
+ ];
386
+ for (const root of roots) {
387
+ const escaped = escapeSeatbeltPath(root);
388
+ lines.push(`(allow file-write* (subpath "${escaped}"))`);
389
+ if (root.startsWith("/var/") || root.startsWith("/tmp")) {
390
+ lines.push(`(allow file-write* (subpath "${escapeSeatbeltPath(`/private${root}`)}"))`);
391
+ }
392
+ if (root.startsWith("/private/var/") || root.startsWith("/private/tmp")) {
393
+ const short = root.slice("/private".length);
394
+ lines.push(`(allow file-write* (subpath "${escapeSeatbeltPath(short)}"))`);
395
+ }
396
+ }
397
+ if (options.denyNetwork !== false) {
398
+ lines.push("(deny network*)");
399
+ } else {
400
+ lines.push("(allow network*)");
401
+ }
402
+ lines.push("(allow ipc*)");
403
+ lines.push("(allow signal)");
404
+ lines.push("(allow pseudo-tty)");
405
+ return `${lines.join("\n")}
406
+ `;
407
+ }
408
+ function seatbeltArgv(profilePath, command) {
409
+ return ["sandbox-exec", "-f", profilePath, "/bin/sh", "-c", command];
410
+ }
411
+ function bubblewrapArgv(writableRoots, command, options = {}) {
412
+ const args = [
413
+ "bwrap",
414
+ "--die-with-parent",
415
+ "--ro-bind",
416
+ "/",
417
+ "/",
418
+ "--dev",
419
+ "/dev",
420
+ "--proc",
421
+ "/proc",
422
+ "--tmpfs",
423
+ "/tmp"
424
+ ];
425
+ const roots = uniqueResolved(writableRoots);
426
+ for (const root of roots) {
427
+ args.push("--bind", root, root);
428
+ }
429
+ for (const t of defaultTempRoots()) {
430
+ if (fs3.existsSync(t)) args.push("--bind", t, t);
431
+ }
432
+ if (options.denyNetwork !== false) {
433
+ args.push("--unshare-net");
434
+ }
435
+ if (options.cwd) {
436
+ args.push("--chdir", options.cwd);
437
+ }
438
+ args.push("--", "/bin/sh", "-c", command);
439
+ return args;
440
+ }
441
+ function tryCreateL2Env(caps, writableRoots, denyNetwork, requested) {
442
+ if (caps.firejail) {
443
+ return createFirejailEnv(
444
+ requested === "L2" ? "L2 firejail process jail" : `${requested} requested; using L2 firejail`,
445
+ writableRoots,
446
+ denyNetwork
447
+ );
448
+ }
449
+ if (caps.gvisor) {
450
+ const gv = tryCreateGvisorEnv({
451
+ writableRoots,
452
+ denyNetwork,
453
+ reason: requested === "L2" ? "L2 gVisor runsc" : `${requested} requested; using L2 gVisor`
454
+ });
455
+ if (gv) return gv;
456
+ }
457
+ return null;
458
+ }
459
+ function tryCreateL1Env(caps, writableRoots, denyNetwork, requested) {
460
+ if (caps.seatbelt) {
461
+ return createSeatbeltEnv(
462
+ requested === "L1" ? "L1 Seatbelt (sandbox-exec) path isolation" : `${requested} requested; using L1 Seatbelt (sandbox-exec)`,
463
+ writableRoots,
464
+ denyNetwork
465
+ );
466
+ }
467
+ if (caps.bubblewrap) {
468
+ return createBubblewrapEnv(
469
+ requested === "L1" ? "L1 bubblewrap path isolation" : `${requested} requested; using L1 bubblewrap`,
470
+ writableRoots,
471
+ denyNetwork,
472
+ caps.landlock
473
+ );
474
+ }
475
+ if (caps.landlock) {
476
+ return null;
477
+ }
478
+ return null;
479
+ }
480
+ function createFirejailEnv(reason, writableRoots, denyNetwork) {
481
+ return {
482
+ tier: "L2",
483
+ label: "firejail",
484
+ reason,
485
+ run(command, options) {
486
+ const roots = writableRoots.length ? writableRoots : [options.cwd];
487
+ if (!roots.some((r) => isPathInside(options.cwd, r))) {
488
+ roots.push(path3.resolve(options.cwd));
489
+ }
490
+ const argv = firejailArgv(roots, command, { denyNetwork, cwd: options.cwd });
491
+ const res = spawnSync(argv[0], argv.slice(1), {
492
+ encoding: "utf8",
493
+ timeout: options.timeoutMs ?? 12e4,
494
+ maxBuffer: 10 * 1024 * 1024,
495
+ env: process.env
496
+ });
497
+ const stdout = (res.stdout ?? "") + (res.stderr ? `
498
+ ${res.stderr}` : "");
499
+ return { stdout, exitCode: res.status ?? 1 };
500
+ }
501
+ };
502
+ }
503
+ function createSeatbeltEnv(reason, writableRoots, denyNetwork) {
504
+ return {
505
+ tier: "L1",
506
+ label: "seatbelt",
507
+ reason,
508
+ run(command, options) {
509
+ const roots = writableRoots.length ? writableRoots : [options.cwd];
510
+ const profile = buildSeatbeltProfile(roots, { denyNetwork });
511
+ const profilePath = path3.join(os.tmpdir(), `vg-seatbelt-${process.pid}-${Date.now()}.sb`);
512
+ try {
513
+ fs3.writeFileSync(profilePath, profile, { encoding: "utf8", mode: 384 });
514
+ const argv = seatbeltArgv(profilePath, command);
515
+ const res = spawnSync(argv[0], argv.slice(1), {
516
+ cwd: options.cwd,
517
+ encoding: "utf8",
518
+ timeout: options.timeoutMs ?? 12e4,
519
+ maxBuffer: 10 * 1024 * 1024,
520
+ env: process.env
521
+ });
522
+ const stdout = (res.stdout ?? "") + (res.stderr ? `
523
+ ${res.stderr}` : "");
524
+ return { stdout, exitCode: res.status ?? 1 };
525
+ } finally {
526
+ try {
527
+ fs3.unlinkSync(profilePath);
528
+ } catch {
529
+ }
530
+ }
531
+ }
532
+ };
533
+ }
534
+ function createBubblewrapEnv(reason, writableRoots, denyNetwork, landlockPresent) {
535
+ return {
536
+ tier: "L1",
537
+ label: landlockPresent ? "bwrap+landlock-host" : "bwrap",
538
+ reason,
539
+ run(command, options) {
540
+ const roots = writableRoots.length ? writableRoots : [options.cwd];
541
+ if (!roots.some((r) => isPathInside(options.cwd, r))) {
542
+ roots.push(path3.resolve(options.cwd));
543
+ }
544
+ const argv = bubblewrapArgv(roots, command, { denyNetwork, cwd: options.cwd });
545
+ const res = spawnSync(argv[0], argv.slice(1), {
546
+ encoding: "utf8",
547
+ timeout: options.timeoutMs ?? 12e4,
548
+ maxBuffer: 10 * 1024 * 1024,
549
+ env: process.env
550
+ });
551
+ const stdout = (res.stdout ?? "") + (res.stderr ? `
552
+ ${res.stderr}` : "");
553
+ return { stdout, exitCode: res.status ?? 1 };
554
+ }
555
+ };
556
+ }
557
+ function hostRun(command, options) {
558
+ const res = spawnSync(command, {
559
+ cwd: options.cwd,
560
+ shell: true,
561
+ encoding: "utf8",
562
+ timeout: options.timeoutMs ?? 12e4,
563
+ maxBuffer: 10 * 1024 * 1024
564
+ });
565
+ const stdout = (res.stdout ?? "") + (res.stderr ? `
566
+ ${res.stderr}` : "");
567
+ return { stdout, exitCode: res.status ?? 1 };
568
+ }
569
+ function linuxLandlockAvailable() {
570
+ try {
571
+ return fs3.existsSync("/sys/kernel/security/landlock") || fs3.existsSync("/proc/sys/kernel/landlock");
572
+ } catch {
573
+ return false;
574
+ }
575
+ }
576
+ function macSeatbeltAvailable() {
577
+ return commandOnPath2("sandbox-exec");
578
+ }
579
+ function commandOnPath2(bin) {
580
+ try {
581
+ const res = spawnSync(process.platform === "win32" ? "where" : "which", [bin], { encoding: "utf8" });
582
+ return res.status === 0 && Boolean(res.stdout?.trim());
583
+ } catch {
584
+ return false;
585
+ }
586
+ }
587
+ function defaultTempRoots() {
588
+ const roots = [];
589
+ try {
590
+ roots.push(os.tmpdir());
591
+ } catch {
592
+ }
593
+ if (process.env.TMPDIR) roots.push(process.env.TMPDIR);
594
+ if (process.env.TMP) roots.push(process.env.TMP);
595
+ if (process.env.TEMP) roots.push(process.env.TEMP);
596
+ roots.push("/tmp", "/private/tmp");
597
+ return uniqueResolved(roots.filter((r) => typeof r === "string" && r.length > 0));
598
+ }
599
+ function normalizeRoots(roots) {
600
+ if (!roots?.length) return [];
601
+ return uniqueResolved(roots.filter((r) => typeof r === "string" && r.trim()).map((r) => r.trim()));
602
+ }
603
+ function uniqueResolved(paths) {
604
+ const seen = /* @__PURE__ */ new Set();
605
+ const out = [];
606
+ for (const p of paths) {
607
+ try {
608
+ const abs = path3.resolve(p);
609
+ if (seen.has(abs)) continue;
610
+ seen.add(abs);
611
+ out.push(abs);
612
+ } catch {
613
+ }
614
+ }
615
+ return out.sort((a, b) => a.localeCompare(b));
616
+ }
617
+ function escapeSeatbeltPath(p) {
618
+ return p.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
619
+ }
620
+ function isPathInside(child, parent) {
621
+ const rel = path3.relative(path3.resolve(parent), path3.resolve(child));
622
+ return rel === "" || !rel.startsWith("..") && !path3.isAbsolute(rel);
623
+ }
624
+
625
+ export { bubblewrapArgv, buildSeatbeltProfile, createHostExecutionEnv, detectSandboxCapabilities, detectSecurityCapabilities, firejailArgv, resolveExecutionEnv, seatbeltArgv, selectSandboxBackend };
626
+ //# sourceMappingURL=chunk-IS7VTH2Q.js.map
627
+ //# sourceMappingURL=chunk-IS7VTH2Q.js.map