@agent-vm/gondolin-adapter 0.0.31 → 0.0.33
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/dist/index.d.ts +34 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +128 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BuildConfig, BuildConfig as BuildConfig$1, getDefaultBuildConfig } from "@earendil-works/gondolin";
|
|
1
|
+
import { BuildConfig, BuildConfig as BuildConfig$1, CreateHttpHooksResult, EnableIngressOptions, EnableSshOptions, IngressRoute as IngressRoute$1, ShadowPredicate, ShadowProviderOptions, VMOptions, VirtualProvider, getDefaultBuildConfig } from "@earendil-works/gondolin";
|
|
2
2
|
|
|
3
3
|
//#region src/build-pipeline.d.ts
|
|
4
4
|
interface BuildImageOptions {
|
|
@@ -53,6 +53,23 @@ declare function validateRuntimeMountPolicy(config: RuntimeMountPolicyConfig, op
|
|
|
53
53
|
readonly workDir: string;
|
|
54
54
|
}): Promise<void>;
|
|
55
55
|
//#endregion
|
|
56
|
+
//#region src/pinned-realfs.d.ts
|
|
57
|
+
interface PinnedRealFsRoot {
|
|
58
|
+
readonly hostPath: string;
|
|
59
|
+
readonly realPath: string;
|
|
60
|
+
readonly fd: number;
|
|
61
|
+
readonly device: number;
|
|
62
|
+
readonly inode: number;
|
|
63
|
+
}
|
|
64
|
+
interface CreatePinnedRealFsProviderOptions {
|
|
65
|
+
readonly root: PinnedRealFsRoot;
|
|
66
|
+
readonly createRealFsProvider: (hostPath: string) => VirtualProvider;
|
|
67
|
+
}
|
|
68
|
+
declare function pinRealFsRoot(hostPath: string): PinnedRealFsRoot;
|
|
69
|
+
declare function closePinnedRealFsRoot(root: PinnedRealFsRoot): void;
|
|
70
|
+
declare function assertPinnedRealFsRoot(root: PinnedRealFsRoot): void;
|
|
71
|
+
declare function createPinnedRealFsProvider(options: CreatePinnedRealFsProviderOptions): VirtualProvider;
|
|
72
|
+
//#endregion
|
|
56
73
|
//#region src/policy-compiler.d.ts
|
|
57
74
|
interface PolicySources {
|
|
58
75
|
readonly base: readonly string[];
|
|
@@ -131,11 +148,7 @@ interface ExecResult {
|
|
|
131
148
|
readonly stdout: string;
|
|
132
149
|
readonly stderr: string;
|
|
133
150
|
}
|
|
134
|
-
|
|
135
|
-
readonly prefix: string;
|
|
136
|
-
readonly port: number;
|
|
137
|
-
readonly stripPrefix?: boolean;
|
|
138
|
-
}
|
|
151
|
+
type IngressRoute = IngressRoute$1;
|
|
139
152
|
interface SshAccess {
|
|
140
153
|
readonly host: string;
|
|
141
154
|
readonly command?: string;
|
|
@@ -154,31 +167,31 @@ interface ManagedVmInstance {
|
|
|
154
167
|
readonly stdout?: string;
|
|
155
168
|
readonly stderr?: string;
|
|
156
169
|
}>;
|
|
157
|
-
enableSsh(options?:
|
|
158
|
-
enableIngress(options?:
|
|
170
|
+
enableSsh(options?: EnableSshOptions): Promise<SshAccess>;
|
|
171
|
+
enableIngress(options?: EnableIngressOptions): Promise<IngressAccess>;
|
|
159
172
|
setIngressRoutes(routes: readonly IngressRoute[]): void;
|
|
160
173
|
close(): Promise<void>;
|
|
161
174
|
}
|
|
162
175
|
interface ManagedVmDependencies {
|
|
163
|
-
createVm(vmOptions:
|
|
176
|
+
createVm(vmOptions: VMOptions): Promise<ManagedVmInstance>;
|
|
164
177
|
createHttpHooks(options: {
|
|
165
178
|
readonly allowedHosts: readonly string[];
|
|
166
179
|
readonly secrets: Record<string, SecretSpec>;
|
|
167
180
|
readonly onRequest?: (request: Request) => Promise<Request | Response | void>;
|
|
168
181
|
readonly onResponse?: (response: Response) => Promise<Response | void>;
|
|
169
|
-
}):
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
createShadowPathPredicate(paths: readonly string[]): unknown;
|
|
182
|
+
}): Pick<CreateHttpHooksResult, 'env' | 'httpHooks'>;
|
|
183
|
+
closePinnedRealFsRoot(root: PinnedRealFsRoot): void;
|
|
184
|
+
createPinnedRealFsProvider(root: PinnedRealFsRoot): VirtualProvider;
|
|
185
|
+
createRealFsProvider(hostPath: string): VirtualProvider;
|
|
186
|
+
createReadonlyProvider(provider: VirtualProvider): VirtualProvider;
|
|
187
|
+
createMemoryProvider(): VirtualProvider;
|
|
188
|
+
createShadowProvider(provider: VirtualProvider, options: ShadowProviderOptions): VirtualProvider;
|
|
189
|
+
createShadowPathPredicate(paths: readonly string[]): ShadowPredicate;
|
|
178
190
|
}
|
|
179
191
|
interface VfsMountSpec {
|
|
180
192
|
readonly kind: 'realfs' | 'realfs-readonly' | 'memory' | 'shadow';
|
|
181
193
|
readonly hostPath?: string;
|
|
194
|
+
readonly pinnedHostRoot?: PinnedRealFsRoot;
|
|
182
195
|
readonly shadowConfig?: {
|
|
183
196
|
readonly deny: readonly string[];
|
|
184
197
|
readonly tmpfs: readonly string[];
|
|
@@ -201,8 +214,8 @@ interface CreateVmOptions {
|
|
|
201
214
|
interface ManagedVm {
|
|
202
215
|
readonly id: string;
|
|
203
216
|
exec(command: string): Promise<ExecResult>;
|
|
204
|
-
enableSsh(options?:
|
|
205
|
-
enableIngress(options?:
|
|
217
|
+
enableSsh(options?: EnableSshOptions): Promise<SshAccess>;
|
|
218
|
+
enableIngress(options?: EnableIngressOptions): Promise<IngressAccess>;
|
|
206
219
|
getVmInstance(): ManagedVmInstance;
|
|
207
220
|
setIngressRoutes(routes: readonly IngressRoute[]): void;
|
|
208
221
|
close(): Promise<void>;
|
|
@@ -225,5 +238,5 @@ declare function writeFileAtomically(filePath: string, content: string, options?
|
|
|
225
238
|
readonly mode?: number;
|
|
226
239
|
}): Promise<void>;
|
|
227
240
|
//#endregion
|
|
228
|
-
export { type BuildConfig, BuildImageOptions, BuildImageResult, BuildOutput, CreateSecretResolverDependencies, CreateVmOptions, ExecFileOptions, ExecFileResult, ExecResult, IngressAccess, IngressRoute, ManagedVm, ManagedVmDependencies, ManagedVmInstance, PolicySources, ResolveGondolinMinimumZigVersionOptions, ResolvedVolume, RuntimeMountPolicyConfig, SecretRef, SecretResolver, SecretResolverClient, SecretSpec, SshAccess, TokenSource, VfsMountSpec, VolumeConfigEntry, WritableMountPolicy, buildImage, compilePolicy, computeBuildFingerprint, createManagedVm, createOpCliSecretResolver, createSecretResolver, dedupeStable, ensureVolumeDir, getDefaultBuildConfig, normalizeHostname, parseMinimumZigVersion, resolveGondolinMinimumZigVersion, resolveGondolinPackageJsonPath, resolveGondolinPackageSpec, resolveGuestMountPath, resolveServiceAccountToken, resolveVolumeDirs, validateRuntimeMountPolicy, validateWritableMount, writeFileAtomically };
|
|
241
|
+
export { type BuildConfig, BuildImageOptions, BuildImageResult, BuildOutput, CreatePinnedRealFsProviderOptions, CreateSecretResolverDependencies, CreateVmOptions, ExecFileOptions, ExecFileResult, ExecResult, IngressAccess, IngressRoute, ManagedVm, ManagedVmDependencies, ManagedVmInstance, PinnedRealFsRoot, PolicySources, ResolveGondolinMinimumZigVersionOptions, ResolvedVolume, RuntimeMountPolicyConfig, SecretRef, SecretResolver, SecretResolverClient, SecretSpec, SshAccess, TokenSource, VfsMountSpec, VolumeConfigEntry, WritableMountPolicy, assertPinnedRealFsRoot, buildImage, closePinnedRealFsRoot, compilePolicy, computeBuildFingerprint, createManagedVm, createOpCliSecretResolver, createPinnedRealFsProvider, createSecretResolver, dedupeStable, ensureVolumeDir, getDefaultBuildConfig, normalizeHostname, parseMinimumZigVersion, pinRealFsRoot, resolveGondolinMinimumZigVersion, resolveGondolinPackageJsonPath, resolveGondolinPackageSpec, resolveGuestMountPath, resolveServiceAccountToken, resolveVolumeDirs, validateRuntimeMountPolicy, validateWritableMount, writeFileAtomically };
|
|
229
242
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/build-pipeline.ts","../src/gondolin-package.ts","../src/mount-policy.ts","../src/policy-compiler.ts","../src/types.ts","../src/secret-resolver.ts","../src/vm-adapter.ts","../src/volume-manager.ts","../src/write-file-atomically.ts"],"sourcesContent":[],"mappings":";;;UAQiB,iBAAA;EAAA,SAAA,WAAiB,EACX,aAAA;EAUN,SAAA,QAAW,EAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/build-pipeline.ts","../src/gondolin-package.ts","../src/mount-policy.ts","../src/pinned-realfs.ts","../src/policy-compiler.ts","../src/types.ts","../src/secret-resolver.ts","../src/vm-adapter.ts","../src/volume-manager.ts","../src/write-file-atomically.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import crypto from "node:crypto";
|
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
+
import fs$1 from "node:fs";
|
|
6
7
|
import { execFile } from "node:child_process";
|
|
7
8
|
import { createClient } from "@1password/sdk";
|
|
8
9
|
import { MemoryProvider, ReadonlyProvider, RealFSProvider, ShadowProvider, VM, createHttpHooks, createShadowPathPredicate, getDefaultBuildConfig } from "@earendil-works/gondolin";
|
|
@@ -192,6 +193,57 @@ async function validateRuntimeMountPolicy(config, options) {
|
|
|
192
193
|
for (const resolvedWritableHostPath of writableHostPaths) if (protectedHostPaths.some((authHostPrefix) => pathsOverlap(resolvedWritableHostPath, authHostPrefix))) throw new Error(`Writable host path '${resolvedWritableHostPath}' targets an auth host directory. Set mountControls.allowAuthWrite=true to permit auth writes.`);
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/pinned-realfs.ts
|
|
198
|
+
function formatRootIdentity(root) {
|
|
199
|
+
return `${root.device}:${root.inode}`;
|
|
200
|
+
}
|
|
201
|
+
function openDirectoryNoFollow(candidatePath) {
|
|
202
|
+
return fs$1.openSync(candidatePath, fs$1.constants.O_RDONLY | fs$1.constants.O_DIRECTORY | fs$1.constants.O_NOFOLLOW);
|
|
203
|
+
}
|
|
204
|
+
function pinRealFsRoot(hostPath) {
|
|
205
|
+
if (!hostPath || !path.isAbsolute(hostPath)) throw new Error(`Pinned RealFS root must be a non-empty absolute path: ${hostPath}`);
|
|
206
|
+
const resolvedHostPath = path.resolve(hostPath);
|
|
207
|
+
const fd = openDirectoryNoFollow(resolvedHostPath);
|
|
208
|
+
try {
|
|
209
|
+
const stats = fs$1.fstatSync(fd);
|
|
210
|
+
if (!stats.isDirectory()) throw new Error(`Pinned RealFS root is not a directory: ${resolvedHostPath}`);
|
|
211
|
+
const realPath = fs$1.realpathSync(resolvedHostPath);
|
|
212
|
+
const realPathStats = fs$1.statSync(realPath);
|
|
213
|
+
if (realPathStats.dev !== stats.dev || realPathStats.ino !== stats.ino) throw new Error(`Pinned RealFS root changed while opening: ${resolvedHostPath} opened ${stats.dev}:${stats.ino} but resolved to ${realPathStats.dev}:${realPathStats.ino}`);
|
|
214
|
+
return {
|
|
215
|
+
device: stats.dev,
|
|
216
|
+
fd,
|
|
217
|
+
hostPath: resolvedHostPath,
|
|
218
|
+
inode: stats.ino,
|
|
219
|
+
realPath
|
|
220
|
+
};
|
|
221
|
+
} catch (error) {
|
|
222
|
+
fs$1.closeSync(fd);
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function closePinnedRealFsRoot(root) {
|
|
227
|
+
fs$1.closeSync(root.fd);
|
|
228
|
+
}
|
|
229
|
+
function assertPinnedRealFsRoot(root) {
|
|
230
|
+
const pinnedStats = fs$1.fstatSync(root.fd);
|
|
231
|
+
const currentStats = fs$1.statSync(root.realPath);
|
|
232
|
+
if (pinnedStats.dev !== root.device || pinnedStats.ino !== root.inode || currentStats.dev !== root.device || currentStats.ino !== root.inode) throw new Error(`Pinned RealFS root changed before mount access: ${root.realPath} expected ${formatRootIdentity(root)} got ${currentStats.dev}:${currentStats.ino}`);
|
|
233
|
+
}
|
|
234
|
+
function createPinnedRealFsProvider(options) {
|
|
235
|
+
assertPinnedRealFsRoot(options.root);
|
|
236
|
+
const provider = options.createRealFsProvider(options.root.realPath);
|
|
237
|
+
return new Proxy(provider, { get(target, property, receiver) {
|
|
238
|
+
const value = Reflect.get(target, property, receiver);
|
|
239
|
+
if (typeof value !== "function") return value;
|
|
240
|
+
return (...methodArguments) => {
|
|
241
|
+
assertPinnedRealFsRoot(options.root);
|
|
242
|
+
return Reflect.apply(value, target, methodArguments);
|
|
243
|
+
};
|
|
244
|
+
} });
|
|
245
|
+
}
|
|
246
|
+
|
|
195
247
|
//#endregion
|
|
196
248
|
//#region src/policy-compiler.ts
|
|
197
249
|
function normalizeHostname(rawHostname) {
|
|
@@ -337,6 +389,7 @@ async function createOpCliSecretResolver(options, dependencies = {}) {
|
|
|
337
389
|
//#endregion
|
|
338
390
|
//#region src/vm-adapter.ts
|
|
339
391
|
function createDefaultDependencies() {
|
|
392
|
+
const createDefaultRealFsProvider = (hostPath) => new RealFSProvider(hostPath);
|
|
340
393
|
return {
|
|
341
394
|
createVm: async (vmOptions) => await VM.create(vmOptions),
|
|
342
395
|
createHttpHooks: (hookOptions) => createHttpHooks({
|
|
@@ -348,7 +401,12 @@ function createDefaultDependencies() {
|
|
|
348
401
|
...hookOptions.onRequest ? { onRequest: hookOptions.onRequest } : {},
|
|
349
402
|
...hookOptions.onResponse ? { onResponse: hookOptions.onResponse } : {}
|
|
350
403
|
}),
|
|
351
|
-
|
|
404
|
+
closePinnedRealFsRoot,
|
|
405
|
+
createPinnedRealFsProvider: (root) => createPinnedRealFsProvider({
|
|
406
|
+
createRealFsProvider: createDefaultRealFsProvider,
|
|
407
|
+
root
|
|
408
|
+
}),
|
|
409
|
+
createRealFsProvider: createDefaultRealFsProvider,
|
|
352
410
|
createReadonlyProvider: (provider) => new ReadonlyProvider(provider),
|
|
353
411
|
createMemoryProvider: () => new MemoryProvider(),
|
|
354
412
|
createShadowProvider: (provider, shadowOptions) => new ShadowProvider(provider, shadowOptions),
|
|
@@ -360,17 +418,18 @@ function normalizeShadowPath(pathValue) {
|
|
|
360
418
|
if (trimmedPath.startsWith("/")) return trimmedPath;
|
|
361
419
|
return `/${trimmedPath.startsWith("./") ? trimmedPath.slice(2) : trimmedPath}`;
|
|
362
420
|
}
|
|
421
|
+
function createRealFsProviderForSpec(mountSpec, dependencies, mountKind) {
|
|
422
|
+
if (mountSpec.pinnedHostRoot) return dependencies.createPinnedRealFsProvider(mountSpec.pinnedHostRoot);
|
|
423
|
+
if (mountSpec.hostPath) return dependencies.createRealFsProvider(mountSpec.hostPath);
|
|
424
|
+
throw new Error(`${mountKind} mounts require hostPath or pinnedHostRoot`);
|
|
425
|
+
}
|
|
363
426
|
function createProviderFromSpec(mountSpec, dependencies) {
|
|
364
427
|
switch (mountSpec.kind) {
|
|
365
428
|
case "memory": return dependencies.createMemoryProvider();
|
|
366
|
-
case "realfs":
|
|
367
|
-
|
|
368
|
-
return dependencies.createRealFsProvider(mountSpec.hostPath);
|
|
369
|
-
case "realfs-readonly":
|
|
370
|
-
if (!mountSpec.hostPath) throw new Error("realfs-readonly mounts require hostPath");
|
|
371
|
-
return dependencies.createReadonlyProvider(dependencies.createRealFsProvider(mountSpec.hostPath));
|
|
429
|
+
case "realfs": return createRealFsProviderForSpec(mountSpec, dependencies, "realfs");
|
|
430
|
+
case "realfs-readonly": return dependencies.createReadonlyProvider(createRealFsProviderForSpec(mountSpec, dependencies, "realfs-readonly"));
|
|
372
431
|
case "shadow": {
|
|
373
|
-
let shadowProvider = mountSpec.hostPath ?
|
|
432
|
+
let shadowProvider = mountSpec.hostPath || mountSpec.pinnedHostRoot ? createRealFsProviderForSpec(mountSpec, dependencies, "shadow") : dependencies.createMemoryProvider();
|
|
374
433
|
const shadowConfig = mountSpec.shadowConfig;
|
|
375
434
|
if (shadowConfig?.deny.length) shadowProvider = dependencies.createShadowProvider(shadowProvider, {
|
|
376
435
|
shouldShadow: dependencies.createShadowPathPredicate(shadowConfig.deny.map((shadowPath) => normalizeShadowPath(shadowPath))),
|
|
@@ -390,38 +449,57 @@ function createVfsMounts(vfsMounts, dependencies) {
|
|
|
390
449
|
for (const [guestPath, mountSpec] of Object.entries(vfsMounts)) mountMap[guestPath] = createProviderFromSpec(mountSpec, dependencies);
|
|
391
450
|
return mountMap;
|
|
392
451
|
}
|
|
452
|
+
function collectPinnedRealFsRoots(vfsMounts) {
|
|
453
|
+
const roots = /* @__PURE__ */ new Map();
|
|
454
|
+
for (const mountSpec of Object.values(vfsMounts)) if (mountSpec.pinnedHostRoot) roots.set(mountSpec.pinnedHostRoot.fd, mountSpec.pinnedHostRoot);
|
|
455
|
+
return [...roots.values()];
|
|
456
|
+
}
|
|
457
|
+
function closePinnedRealFsRoots(roots, dependencies) {
|
|
458
|
+
for (const root of roots) dependencies.closePinnedRealFsRoot(root);
|
|
459
|
+
}
|
|
460
|
+
function closePinnedRealFsRootsAfterFailure(roots, dependencies) {
|
|
461
|
+
try {
|
|
462
|
+
closePinnedRealFsRoots(roots, dependencies);
|
|
463
|
+
} catch {}
|
|
464
|
+
}
|
|
393
465
|
async function createManagedVm(options, dependencies = createDefaultDependencies()) {
|
|
394
|
-
const hookBundle = dependencies.createHttpHooks({
|
|
395
|
-
allowedHosts: options.allowedHosts,
|
|
396
|
-
secrets: options.secrets,
|
|
397
|
-
...options.onRequest ? { onRequest: options.onRequest } : {},
|
|
398
|
-
...options.onResponse ? { onResponse: options.onResponse } : {}
|
|
399
|
-
});
|
|
400
466
|
const hasTcpHosts = options.tcpHosts && Object.keys(options.tcpHosts).length > 0;
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
mode: "synthetic",
|
|
420
|
-
syntheticHostMapping: "per-host"
|
|
467
|
+
const pinnedRealFsRoots = collectPinnedRealFsRoots(options.vfsMounts);
|
|
468
|
+
let vmInstance;
|
|
469
|
+
try {
|
|
470
|
+
const hookBundle = dependencies.createHttpHooks({
|
|
471
|
+
allowedHosts: options.allowedHosts,
|
|
472
|
+
secrets: options.secrets,
|
|
473
|
+
...options.onRequest ? { onRequest: options.onRequest } : {},
|
|
474
|
+
...options.onResponse ? { onResponse: options.onResponse } : {}
|
|
475
|
+
});
|
|
476
|
+
vmInstance = await dependencies.createVm({
|
|
477
|
+
...options.imagePath.length > 0 ? { sandbox: { imagePath: options.imagePath } } : {},
|
|
478
|
+
...options.sessionLabel ? { sessionLabel: options.sessionLabel } : {},
|
|
479
|
+
rootfs: { mode: options.rootfsMode },
|
|
480
|
+
memory: options.memory,
|
|
481
|
+
cpus: options.cpus,
|
|
482
|
+
env: {
|
|
483
|
+
...hookBundle.env,
|
|
484
|
+
...options.env
|
|
421
485
|
},
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
486
|
+
httpHooks: hookBundle.httpHooks,
|
|
487
|
+
vfs: {
|
|
488
|
+
fuseMount: "/data",
|
|
489
|
+
mounts: createVfsMounts(options.vfsMounts, dependencies)
|
|
490
|
+
},
|
|
491
|
+
...hasTcpHosts ? {
|
|
492
|
+
dns: {
|
|
493
|
+
mode: "synthetic",
|
|
494
|
+
syntheticHostMapping: "per-host"
|
|
495
|
+
},
|
|
496
|
+
tcp: { hosts: options.tcpHosts }
|
|
497
|
+
} : {}
|
|
498
|
+
});
|
|
499
|
+
} catch (error) {
|
|
500
|
+
closePinnedRealFsRootsAfterFailure(pinnedRealFsRoots, dependencies);
|
|
501
|
+
throw error;
|
|
502
|
+
}
|
|
425
503
|
return {
|
|
426
504
|
id: vmInstance.id,
|
|
427
505
|
async exec(command) {
|
|
@@ -445,7 +523,18 @@ async function createManagedVm(options, dependencies = createDefaultDependencies
|
|
|
445
523
|
vmInstance.setIngressRoutes(routes);
|
|
446
524
|
},
|
|
447
525
|
async close() {
|
|
448
|
-
|
|
526
|
+
let closeError;
|
|
527
|
+
try {
|
|
528
|
+
await vmInstance.close();
|
|
529
|
+
} catch (error) {
|
|
530
|
+
closeError = error;
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
closePinnedRealFsRoots(pinnedRealFsRoots, dependencies);
|
|
534
|
+
} catch (error) {
|
|
535
|
+
closeError ??= error;
|
|
536
|
+
}
|
|
537
|
+
if (closeError !== void 0) throw closeError;
|
|
449
538
|
}
|
|
450
539
|
};
|
|
451
540
|
}
|
|
@@ -486,5 +575,5 @@ async function writeFileAtomically(filePath, content, options = {}) {
|
|
|
486
575
|
}
|
|
487
576
|
|
|
488
577
|
//#endregion
|
|
489
|
-
export { buildImage, compilePolicy, computeBuildFingerprint, createManagedVm, createOpCliSecretResolver, createSecretResolver, dedupeStable, ensureVolumeDir, getDefaultBuildConfig, normalizeHostname, parseMinimumZigVersion, resolveGondolinMinimumZigVersion, resolveGondolinPackageJsonPath, resolveGondolinPackageSpec, resolveGuestMountPath, resolveServiceAccountToken, resolveVolumeDirs, validateRuntimeMountPolicy, validateWritableMount, writeFileAtomically };
|
|
578
|
+
export { assertPinnedRealFsRoot, buildImage, closePinnedRealFsRoot, compilePolicy, computeBuildFingerprint, createManagedVm, createOpCliSecretResolver, createPinnedRealFsProvider, createSecretResolver, dedupeStable, ensureVolumeDir, getDefaultBuildConfig, normalizeHostname, parseMinimumZigVersion, pinRealFsRoot, resolveGondolinMinimumZigVersion, resolveGondolinPackageJsonPath, resolveGondolinPackageSpec, resolveGuestMountPath, resolveServiceAccountToken, resolveVolumeDirs, validateRuntimeMountPolicy, validateWritableMount, writeFileAtomically };
|
|
490
579
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["parsed: unknown","rawContents: string","normalizedValues: string[]","resolvedSecrets: Record<string, string>","mountMap: Record<string, unknown>"],"sources":["../src/build-pipeline.ts","../src/gondolin-package.ts","../src/mount-policy.ts","../src/policy-compiler.ts","../src/secret-resolver.ts","../src/vm-adapter.ts","../src/volume-manager.ts","../src/write-file-atomically.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { BuildConfig, BuildOptions } from '@earendil-works/gondolin';\n\nexport type { BuildConfig } from '@earendil-works/gondolin';\n\nexport interface BuildImageOptions {\n\treadonly buildConfig: BuildConfig;\n\treadonly cacheDir: string;\n\t/** Directory to resolve relative paths in buildConfig (e.g. postBuild.copy.src).\n\t * Defaults to process.cwd() if not provided. */\n\treadonly configDir?: string;\n\treadonly fullReset?: boolean;\n\treadonly fingerprintInput?: unknown;\n\treadonly output?: BuildOutput;\n}\n\nexport interface BuildOutput {\n\twrite(chunk: string | Uint8Array): boolean;\n}\n\nexport interface BuildImageResult {\n\treadonly built: boolean;\n\treadonly fingerprint: string;\n\treadonly imagePath: string;\n}\n\ninterface BuildPipelineDependencies {\n\treadonly buildAssets?: (\n\t\tbuildConfig: BuildConfig,\n\t\toutputDirectory: string,\n\t\tconfigDir?: string,\n\t) => Promise<unknown>;\n\treadonly gondolinVersion?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null;\n}\n\nfunction stableSerialize(value: unknown): string {\n\tif (Array.isArray(value)) {\n\t\treturn `[${value.map((entry) => stableSerialize(entry)).join(',')}]`;\n\t}\n\n\tif (isRecord(value)) {\n\t\tconst objectEntries = Object.entries(value)\n\t\t\t.filter(([, entryValue]) => entryValue !== undefined)\n\t\t\t.toSorted(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey));\n\t\treturn `{${objectEntries\n\t\t\t.map(([entryKey, entryValue]) => `${JSON.stringify(entryKey)}:${stableSerialize(entryValue)}`)\n\t\t\t.join(',')}}`;\n\t}\n\n\treturn JSON.stringify(value);\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait fs.access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function hasBuiltAssets(outputDirectoryPath: string): Promise<boolean> {\n\treturn (\n\t\t(await pathExists(path.join(outputDirectoryPath, 'manifest.json'))) &&\n\t\t(await pathExists(path.join(outputDirectoryPath, 'rootfs.ext4'))) &&\n\t\t(await pathExists(path.join(outputDirectoryPath, 'initramfs.cpio.lz4'))) &&\n\t\t(await pathExists(path.join(outputDirectoryPath, 'vmlinuz-virt')))\n\t);\n}\n\nasync function loadBuildAssets(): Promise<\n\t(buildConfig: BuildConfig, outputDirectory: string, configDir?: string) => Promise<unknown>\n> {\n\tconst gondolinModule = await import('@earendil-works/gondolin');\n\treturn async (\n\t\tbuildConfig: BuildConfig,\n\t\toutputDirectory: string,\n\t\tconfigDir?: string,\n\t): Promise<unknown> =>\n\t\tawait gondolinModule.buildAssets(buildConfig, {\n\t\t\toutputDir: outputDirectory,\n\t\t\tverbose: false,\n\t\t\t...(configDir ? { configDir } : {}),\n\t\t} satisfies BuildOptions);\n}\n\nfunction createRedirectedWrite(output: BuildOutput): typeof process.stderr.write {\n\treturn ((\n\t\tchunk: string | Uint8Array,\n\t\tencodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n\t\tcallback?: (error?: Error | null) => void,\n\t): boolean => {\n\t\tconst writeCallback = typeof encodingOrCallback === 'function' ? encodingOrCallback : callback;\n\t\tconst wrote = output.write(chunk);\n\t\twriteCallback?.();\n\t\treturn wrote;\n\t}) as typeof process.stderr.write;\n}\n\nasync function withCapturedBuildOutput<TResult>(\n\toutput: BuildOutput | undefined,\n\tfn: () => Promise<TResult>,\n): Promise<TResult> {\n\tif (!output) {\n\t\treturn await fn();\n\t}\n\n\tconst originalStderrWrite = process.stderr.write.bind(process.stderr);\n\tconst originalStdoutWrite = process.stdout.write.bind(process.stdout);\n\tconst originalCi = process.env.CI;\n\tconst redirectedWrite = createRedirectedWrite(output);\n\n\tprocess.stderr.write = redirectedWrite;\n\tprocess.stdout.write = redirectedWrite;\n\tprocess.env.CI = 'true';\n\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\tprocess.stderr.write = originalStderrWrite;\n\t\tprocess.stdout.write = originalStdoutWrite;\n\t\tif (originalCi === undefined) {\n\t\t\tdelete process.env.CI;\n\t\t} else {\n\t\t\tprocess.env.CI = originalCi;\n\t\t}\n\t}\n}\n\nexport function computeBuildFingerprint(\n\tbuildConfig: BuildConfig,\n\tgondolinVersion: string = 'unknown',\n\tfingerprintInput?: unknown,\n): string {\n\tconst payload =\n\t\tfingerprintInput === undefined\n\t\t\t? `${stableSerialize(buildConfig)}|${gondolinVersion}`\n\t\t\t: `${stableSerialize(buildConfig)}|${gondolinVersion}|${stableSerialize(fingerprintInput)}`;\n\n\treturn crypto.createHash('sha256').update(payload).digest('hex').slice(0, 16);\n}\n\nexport async function buildImage(\n\toptions: BuildImageOptions,\n\tdependencies: BuildPipelineDependencies = {},\n): Promise<BuildImageResult> {\n\tconst fingerprint = computeBuildFingerprint(\n\t\toptions.buildConfig,\n\t\tdependencies.gondolinVersion,\n\t\toptions.fingerprintInput,\n\t);\n\tconst imagePath = path.join(options.cacheDir, fingerprint);\n\n\tif (options.fullReset) {\n\t\tawait fs.rm(imagePath, { recursive: true, force: true });\n\t}\n\n\tif (await hasBuiltAssets(imagePath)) {\n\t\treturn {\n\t\t\tbuilt: false,\n\t\t\tfingerprint,\n\t\t\timagePath,\n\t\t};\n\t}\n\n\tawait fs.mkdir(imagePath, { recursive: true });\n\tconst buildAssetsImplementation = dependencies.buildAssets ?? (await loadBuildAssets());\n\tawait withCapturedBuildOutput(options.output, async () => {\n\t\tawait buildAssetsImplementation(options.buildConfig, imagePath, options.configDir);\n\t});\n\n\tif (!(await hasBuiltAssets(imagePath))) {\n\t\tthrow new Error(`Expected Gondolin assets to be written to ${imagePath}.`);\n\t}\n\n\treturn {\n\t\tbuilt: true,\n\t\tfingerprint,\n\t\timagePath,\n\t};\n}\n","import fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { z } from 'zod';\n\nconst requireFromHere = createRequire(import.meta.url);\n\nconst gondolinPackageJsonSchema = z.object({\n\tversion: z.string().min(1),\n});\n\nfunction isMissingFileError(error: unknown): boolean {\n\treturn typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT';\n}\n\nfunction getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function parseMinimumZigVersion(rawContents: string): string {\n\tconst match = rawContents.match(/\\.minimum_zig_version\\s*=\\s*\"([^\"]*)\"/u);\n\tif (!match) {\n\t\tthrow new Error(\n\t\t\t'minimum_zig_version declaration not found. Expected a line like `.minimum_zig_version = \"0.15.2\"`.',\n\t\t);\n\t}\n\n\tconst version = match[1];\n\tif (!version) {\n\t\tthrow new Error('minimum_zig_version is empty.');\n\t}\n\treturn version;\n}\n\nexport function resolveGondolinPackageJsonPath(): string {\n\treturn requireFromHere.resolve('@earendil-works/gondolin/package.json');\n}\n\nexport async function resolveGondolinPackageSpec(): Promise<string> {\n\tconst packageJsonPath = resolveGondolinPackageJsonPath();\n\tconst parsed: unknown = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));\n\tconst packageJson = gondolinPackageJsonSchema.parse(parsed);\n\treturn `@earendil-works/gondolin@${packageJson.version}`;\n}\n\nexport interface ResolveGondolinMinimumZigVersionOptions {\n\treadonly buildZigZonPath?: string;\n}\n\nasync function resolveDefaultBuildZigZonPath(): Promise<string> {\n\tconst packageJsonPath = resolveGondolinPackageJsonPath();\n\treturn path.join(path.dirname(packageJsonPath), 'dist', 'guest', 'build.zig.zon');\n}\n\nexport async function resolveGondolinMinimumZigVersion(\n\toptions: ResolveGondolinMinimumZigVersionOptions = {},\n): Promise<string> {\n\tconst zonPath = options.buildZigZonPath ?? (await resolveDefaultBuildZigZonPath());\n\tlet rawContents: string;\n\ttry {\n\t\trawContents = await fs.readFile(zonPath, 'utf8');\n\t} catch (error) {\n\t\tif (isMissingFileError(error)) {\n\t\t\tthrow new Error(`Missing Gondolin build.zig.zon at '${zonPath}'.`, { cause: error });\n\t\t}\n\t\tthrow new Error(\n\t\t\t`Failed to read Gondolin build.zig.zon at '${zonPath}': ${getErrorMessage(error)}`,\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\ttry {\n\t\treturn parseMinimumZigVersion(rawContents);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to parse Gondolin build.zig.zon at '${zonPath}': ${getErrorMessage(error)}`,\n\t\t\t{ cause: error },\n\t\t);\n\t}\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nconst AUTH_GUEST_PATH_PREFIXES = [\n\t'/home/agent/.aws',\n\t'/home/agent/.claude',\n\t'/home/agent/.codex',\n\t'/home/agent/.gemini',\n\t'/home/openclaw/.aws',\n\t'/home/openclaw/.claude',\n\t'/home/openclaw/.codex',\n\t'/home/openclaw/.gemini',\n\t'/home/openclaw/.openclaw',\n] as const;\n\nexport interface WritableMountPolicy {\n\treadonly allowAuthWrite: boolean;\n\treadonly writableAllowedGuestPrefixes: readonly string[];\n}\n\nexport interface RuntimeMountPolicyConfig {\n\treadonly extraMounts: Readonly<Record<string, string>>;\n\treadonly mountControls: WritableMountPolicy;\n}\n\nfunction resolveAuthHostPrefixes(hostHome: string): readonly string[] {\n\treturn [\n\t\tpath.join(hostHome, '.aws'),\n\t\tpath.join(hostHome, '.claude'),\n\t\tpath.join(hostHome, '.codex'),\n\t\tpath.join(hostHome, '.gemini'),\n\t];\n}\n\nexport function resolveGuestMountPath(guestPath: string, workDir: string): string {\n\tif (path.isAbsolute(guestPath)) {\n\t\treturn path.resolve(guestPath);\n\t}\n\n\treturn path.resolve(workDir, guestPath);\n}\n\nfunction isPathWithinPrefix(candidatePath: string, prefixPath: string): boolean {\n\tconst relativePath = path.relative(prefixPath, candidatePath);\n\treturn relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath));\n}\n\nasync function normalizeHostPath(hostPath: string): Promise<string> {\n\tconst resolvedHostPath = path.resolve(hostPath);\n\n\ttry {\n\t\treturn await fs.realpath(resolvedHostPath);\n\t} catch {\n\t\treturn resolvedHostPath;\n\t}\n}\n\nfunction pathsOverlap(candidatePath: string, protectedPath: string): boolean {\n\treturn (\n\t\tisPathWithinPrefix(candidatePath, protectedPath) ||\n\t\tisPathWithinPrefix(protectedPath, candidatePath)\n\t);\n}\n\nexport function validateWritableMount(\n\tguestPath: string,\n\tpolicy: WritableMountPolicy,\n\toptions: { readonly workDir: string },\n): void {\n\tconst resolvedGuestPath = resolveGuestMountPath(guestPath, options.workDir);\n\tconst resolvedAllowedPrefixes = policy.writableAllowedGuestPrefixes.map((allowedPrefix) =>\n\t\tresolveGuestMountPath(allowedPrefix, options.workDir),\n\t);\n\n\tconst isAllowedGuestPath = resolvedAllowedPrefixes.some((allowedPrefix) =>\n\t\tisPathWithinPrefix(resolvedGuestPath, allowedPrefix),\n\t);\n\tif (!isAllowedGuestPath) {\n\t\tthrow new Error(\n\t\t\t`Writable mount guest path '${resolvedGuestPath}' is outside writable allowlist [${resolvedAllowedPrefixes.join(', ')}].`,\n\t\t);\n\t}\n\n\tif (!policy.allowAuthWrite) {\n\t\tconst targetsProtectedGuestPath = AUTH_GUEST_PATH_PREFIXES.some((authPrefix) =>\n\t\t\tisPathWithinPrefix(resolvedGuestPath, authPrefix),\n\t\t);\n\t\tif (targetsProtectedGuestPath) {\n\t\t\tthrow new Error(\n\t\t\t\t`Writable mount guest path '${resolvedGuestPath}' targets an auth mount path. Set mountControls.allowAuthWrite=true to permit auth writes.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport async function validateRuntimeMountPolicy(\n\tconfig: RuntimeMountPolicyConfig,\n\toptions: { readonly hostHome: string; readonly workDir: string },\n): Promise<void> {\n\tconst mountEntries = Object.entries(config.extraMounts);\n\tfor (const [guestPath] of mountEntries) {\n\t\tvalidateWritableMount(guestPath, config.mountControls, options);\n\t}\n\n\tif (config.mountControls.allowAuthWrite) {\n\t\treturn;\n\t}\n\n\tconst absoluteHostMountEntries = mountEntries.filter(([, hostPath]) => path.isAbsolute(hostPath));\n\tconst [protectedHostPaths, writableHostPaths] = await Promise.all([\n\t\tPromise.all(\n\t\t\tresolveAuthHostPrefixes(options.hostHome).map(\n\t\t\t\tasync (authHostPrefix) => await normalizeHostPath(authHostPrefix),\n\t\t\t),\n\t\t),\n\t\tPromise.all(\n\t\t\tabsoluteHostMountEntries.map(async ([, hostPath]) => await normalizeHostPath(hostPath)),\n\t\t),\n\t]);\n\n\tfor (const resolvedWritableHostPath of writableHostPaths) {\n\t\tconst overlapsProtectedHostPath = protectedHostPaths.some((authHostPrefix) =>\n\t\t\tpathsOverlap(resolvedWritableHostPath, authHostPrefix),\n\t\t);\n\n\t\tif (overlapsProtectedHostPath) {\n\t\t\tthrow new Error(\n\t\t\t\t`Writable host path '${resolvedWritableHostPath}' targets an auth host directory. Set mountControls.allowAuthWrite=true to permit auth writes.`,\n\t\t\t);\n\t\t}\n\t}\n}\n","export interface PolicySources {\n\treadonly base: readonly string[];\n\treadonly profile: readonly string[];\n\treadonly extra: readonly string[];\n}\n\nexport function normalizeHostname(rawHostname: string): string {\n\treturn rawHostname.trim().toLowerCase().replace(/\\.+$/u, '');\n}\n\nexport function dedupeStable(values: readonly string[]): string[] {\n\tconst seenHostnames = new Set<string>();\n\tconst normalizedValues: string[] = [];\n\n\tfor (const value of values) {\n\t\tconst normalizedValue = normalizeHostname(value);\n\t\tif (normalizedValue.length === 0 || normalizedValue.startsWith('#')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!seenHostnames.has(normalizedValue)) {\n\t\t\tseenHostnames.add(normalizedValue);\n\t\t\tnormalizedValues.push(normalizedValue);\n\t\t}\n\t}\n\n\treturn normalizedValues;\n}\n\nexport function compilePolicy(sources: PolicySources): string[] {\n\treturn dedupeStable([...sources.base, ...sources.profile, ...sources.extra]);\n}\n","import { execFile } from 'node:child_process';\n\nimport { createClient } from '@1password/sdk';\n\nimport type { SecretRef } from './types.js';\n\nexport interface SecretResolverClient {\n\treadonly secrets: {\n\t\tresolve(secretReference: string): Promise<string>;\n\t\tresolveAll(secretReferences: readonly string[]): Promise<unknown>;\n\t};\n}\n\nexport interface SecretResolver {\n\tresolve(ref: SecretRef): Promise<string>;\n\tresolveAll(refs: Record<string, SecretRef>): Promise<Record<string, string>>;\n}\n\n// --- Token source: how to obtain the 1Password service account token ---\n\nexport type TokenSource =\n\t| { readonly type: 'op-cli'; readonly ref: string }\n\t| { readonly type: 'env'; readonly envVar?: string | undefined }\n\t| { readonly type: 'keychain'; readonly service: string; readonly account: string };\n\nexport interface ExecFileOptions {\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n}\n\nexport interface ExecFileResult {\n\treadonly stdout: string;\n\treadonly stderr: string;\n}\n\nfunction writeStderr(message: string): void {\n\tprocess.stderr.write(`${message}\\n`);\n}\n\nfunction ensureMacOsForKeychain(): void {\n\tif (process.platform !== 'darwin') {\n\t\tthrow new Error(\n\t\t\t'Keychain token source is only supported on macOS. Use an env or op-cli token source on this platform so cmd-ts can surface a clear startup error.',\n\t\t);\n\t}\n}\n\nfunction execFileAsync(\n\tcommand: string,\n\targs: readonly string[],\n\toptions?: ExecFileOptions,\n): Promise<ExecFileResult> {\n\treturn new Promise((resolve, reject) => {\n\t\texecFile(\n\t\t\tcommand,\n\t\t\t[...args],\n\t\t\t{ env: options?.env, timeout: 30_000 },\n\t\t\t(error, stdout, stderr) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tconst errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\t\t\treject(new Error(`${command} failed: ${stderr.trim() || errorMessage}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tresolve({ stdout, stderr });\n\t\t\t},\n\t\t);\n\t});\n}\n\nconst SAFE_IDENTIFIER_PATTERN = /^[\\w.@-]+$/u;\n\nexport async function resolveServiceAccountToken(\n\tsource: TokenSource,\n\tdependencies?: {\n\t\treadonly execFileAsync?: (\n\t\t\tcommand: string,\n\t\t\targs: readonly string[],\n\t\t\toptions?: ExecFileOptions,\n\t\t) => Promise<ExecFileResult>;\n\t},\n): Promise<string> {\n\tconst exec = dependencies?.execFileAsync ?? execFileAsync;\n\n\tswitch (source.type) {\n\t\tcase 'op-cli': {\n\t\t\t// Uses `op read` which triggers biometric auth (Touch ID) on macOS\n\t\t\tconst result = await exec('op', ['read', source.ref]);\n\t\t\tconst token = result.stdout.trim();\n\t\t\tif (token.length === 0) {\n\t\t\t\tthrow new Error('op-cli token resolution returned empty value');\n\t\t\t}\n\n\t\t\treturn token;\n\t\t}\n\n\t\tcase 'env': {\n\t\t\tconst envVar = source.envVar ?? 'OP_SERVICE_ACCOUNT_TOKEN';\n\t\t\tconst token = process.env[envVar]?.trim();\n\t\t\tif (!token) {\n\t\t\t\tthrow new Error(`Environment variable ${envVar} is not set`);\n\t\t\t}\n\n\t\t\treturn token;\n\t\t}\n\n\t\tcase 'keychain': {\n\t\t\tensureMacOsForKeychain();\n\n\t\t\t// Validate keychain identifiers to prevent argument injection\n\t\t\tif (!SAFE_IDENTIFIER_PATTERN.test(source.service)) {\n\t\t\t\tthrow new Error('Keychain service name contains invalid characters');\n\t\t\t}\n\n\t\t\tif (!SAFE_IDENTIFIER_PATTERN.test(source.account)) {\n\t\t\t\tthrow new Error('Keychain account name contains invalid characters');\n\t\t\t}\n\n\t\t\t// macOS Keychain via `security find-generic-password`\n\t\t\tconst result = await exec('security', [\n\t\t\t\t'find-generic-password',\n\t\t\t\t'-s',\n\t\t\t\tsource.service,\n\t\t\t\t'-a',\n\t\t\t\tsource.account,\n\t\t\t\t'-w',\n\t\t\t]);\n\t\t\tconst token = result.stdout.trim();\n\t\t\tif (token.length === 0) {\n\t\t\t\tthrow new Error('Keychain token resolution returned empty value');\n\t\t\t}\n\n\t\t\treturn token;\n\t\t}\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported token source: ${JSON.stringify(source)}`);\n\t}\n}\n\n// --- Secret resolver: uses the token to resolve secrets via 1Password SDK ---\n\nexport interface CreateSecretResolverDependencies {\n\treadonly createClient?: (config: {\n\t\tauth: string;\n\t\tintegrationName: string;\n\t\tintegrationVersion: string;\n\t}) => Promise<SecretResolverClient>;\n\treadonly execFileAsync?: (\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions?: ExecFileOptions,\n\t) => Promise<ExecFileResult>;\n\treadonly integrationName?: string;\n\treadonly integrationVersion?: string;\n}\n\nasync function resolveSecretWithOpCli(\n\tserviceAccountToken: string,\n\tsecretReference: string,\n\texec: (\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions?: ExecFileOptions,\n\t) => Promise<ExecFileResult>,\n): Promise<string> {\n\tconst result = await exec('op', ['read', secretReference], {\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\tOP_SERVICE_ACCOUNT_TOKEN: serviceAccountToken,\n\t\t},\n\t});\n\treturn result.stdout.trim();\n}\n\nasync function resolveAllSecretsWithOpCli(\n\tserviceAccountToken: string,\n\trefs: Record<string, SecretRef>,\n\texec: (\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions?: ExecFileOptions,\n\t) => Promise<ExecFileResult>,\n): Promise<Record<string, string>> {\n\tconst resolvedSecrets: Record<string, string> = {};\n\n\tfor (const [secretName, secretRef] of Object.entries(refs)) {\n\t\t// Sequential resolution avoids concurrent `op read` failures with the same service account token.\n\t\t// oxlint-disable-next-line eslint/no-await-in-loop\n\t\tresolvedSecrets[secretName] = await resolveSecretWithOpCli(\n\t\t\tserviceAccountToken,\n\t\t\tsecretRef.ref,\n\t\t\texec,\n\t\t);\n\t}\n\n\treturn resolvedSecrets;\n}\n\nexport async function createSecretResolver(\n\toptions: {\n\t\treadonly serviceAccountToken: string;\n\t},\n\tdependencies: CreateSecretResolverDependencies = {},\n): Promise<SecretResolver> {\n\tconst exec = dependencies.execFileAsync ?? execFileAsync;\n\ttry {\n\t\tconst client = await (dependencies.createClient ?? createClient)({\n\t\t\tauth: options.serviceAccountToken,\n\t\t\tintegrationName: dependencies.integrationName ?? 'agent-vm',\n\t\t\tintegrationVersion: dependencies.integrationVersion ?? '0.0.1',\n\t\t});\n\n\t\treturn {\n\t\t\tresolve: async (ref: SecretRef): Promise<string> => {\n\t\t\t\ttry {\n\t\t\t\t\treturn await client.secrets.resolve(ref.ref);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\twriteStderr(\n\t\t\t\t\t\t`[secret-resolver] 1Password SDK resolve failed for ${ref.ref}; falling back to op CLI: ${message}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn await resolveSecretWithOpCli(options.serviceAccountToken, ref.ref, exec);\n\t\t\t\t}\n\t\t\t},\n\t\t\tresolveAll: async (refs: Record<string, SecretRef>): Promise<Record<string, string>> => {\n\t\t\t\tconst resolvedSecrets: Record<string, string> = {};\n\n\t\t\t\tfor (const [secretName, secretRef] of Object.entries(refs)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// oxlint-disable-next-line eslint/no-await-in-loop\n\t\t\t\t\t\tresolvedSecrets[secretName] = await client.secrets.resolve(secretRef.ref);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\t\twriteStderr(\n\t\t\t\t\t\t\t`[secret-resolver] 1Password SDK resolve failed for ${secretRef.ref}; falling back to op CLI: ${message}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Sequential fallback avoids concurrent `op read` failures when the SDK path is unhealthy.\n\t\t\t\t\t\t// oxlint-disable-next-line eslint/no-await-in-loop\n\t\t\t\t\t\tresolvedSecrets[secretName] = await resolveSecretWithOpCli(\n\t\t\t\t\t\t\toptions.serviceAccountToken,\n\t\t\t\t\t\t\tsecretRef.ref,\n\t\t\t\t\t\t\texec,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn resolvedSecrets;\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\twriteStderr(\n\t\t\t`[secret-resolver] 1Password SDK client creation failed; falling back to op CLI: ${message}`,\n\t\t);\n\t\treturn {\n\t\t\tresolve: async (ref: SecretRef): Promise<string> =>\n\t\t\t\tawait resolveSecretWithOpCli(options.serviceAccountToken, ref.ref, exec),\n\t\t\tresolveAll: async (refs: Record<string, SecretRef>): Promise<Record<string, string>> =>\n\t\t\t\tawait resolveAllSecretsWithOpCli(options.serviceAccountToken, refs, exec),\n\t\t};\n\t}\n}\n\nexport async function createOpCliSecretResolver(\n\toptions: {\n\t\treadonly serviceAccountToken: string;\n\t},\n\tdependencies: Pick<CreateSecretResolverDependencies, 'execFileAsync'> = {},\n): Promise<SecretResolver> {\n\tconst exec = dependencies.execFileAsync ?? execFileAsync;\n\n\treturn {\n\t\tresolve: async (ref: SecretRef): Promise<string> =>\n\t\t\tawait resolveSecretWithOpCli(options.serviceAccountToken, ref.ref, exec),\n\t\tresolveAll: async (refs: Record<string, SecretRef>): Promise<Record<string, string>> =>\n\t\t\tawait resolveAllSecretsWithOpCli(options.serviceAccountToken, refs, exec),\n\t};\n}\n","import {\n\tMemoryProvider,\n\tReadonlyProvider,\n\tRealFSProvider,\n\tShadowProvider,\n\tVM,\n\tcreateHttpHooks,\n\tcreateShadowPathPredicate,\n} from '@earendil-works/gondolin';\n\nimport type { SecretSpec } from './types.js';\n\nexport interface ExecResult {\n\treadonly exitCode: number;\n\treadonly stdout: string;\n\treadonly stderr: string;\n}\n\nexport interface IngressRoute {\n\treadonly prefix: string;\n\treadonly port: number;\n\treadonly stripPrefix?: boolean;\n}\n\nexport interface SshAccess {\n\treadonly host: string;\n\treadonly command?: string;\n\treadonly identityFile?: string;\n\treadonly port: number;\n\treadonly user?: string;\n}\n\nexport interface IngressAccess {\n\treadonly host: string;\n\treadonly port: number;\n}\n\nexport interface ManagedVmInstance {\n\treadonly id: string;\n\texec(command: string): Promise<{\n\t\treadonly exitCode: number;\n\t\treadonly stdout?: string;\n\t\treadonly stderr?: string;\n\t}>;\n\tenableSsh(options?: unknown): Promise<SshAccess>;\n\tenableIngress(options?: unknown): Promise<IngressAccess>;\n\tsetIngressRoutes(routes: readonly IngressRoute[]): void;\n\tclose(): Promise<void>;\n}\n\nexport interface ManagedVmDependencies {\n\tcreateVm(vmOptions: unknown): Promise<ManagedVmInstance>;\n\tcreateHttpHooks(options: {\n\t\treadonly allowedHosts: readonly string[];\n\t\treadonly secrets: Record<string, SecretSpec>;\n\t\treadonly onRequest?: (request: Request) => Promise<Request | Response | void>;\n\t\treadonly onResponse?: (response: Response) => Promise<Response | void>;\n\t}): {\n\t\treadonly env: Record<string, string>;\n\t\treadonly httpHooks: unknown;\n\t};\n\tcreateRealFsProvider(hostPath: string): unknown;\n\tcreateReadonlyProvider(provider: unknown): unknown;\n\tcreateMemoryProvider(): unknown;\n\tcreateShadowProvider(provider: unknown, options: unknown): unknown;\n\tcreateShadowPathPredicate(paths: readonly string[]): unknown;\n}\n\nexport interface VfsMountSpec {\n\treadonly kind: 'realfs' | 'realfs-readonly' | 'memory' | 'shadow';\n\treadonly hostPath?: string;\n\treadonly shadowConfig?: {\n\t\treadonly deny: readonly string[];\n\t\treadonly tmpfs: readonly string[];\n\t};\n}\n\nexport interface CreateVmOptions {\n\treadonly imagePath: string;\n\treadonly memory: string;\n\treadonly cpus: number;\n\treadonly rootfsMode: 'readonly' | 'memory' | 'cow';\n\treadonly allowedHosts: readonly string[];\n\treadonly secrets: Record<string, SecretSpec>;\n\treadonly vfsMounts: Record<string, VfsMountSpec>;\n\treadonly tcpHosts?: Record<string, string>;\n\treadonly env?: Record<string, string>;\n\treadonly sessionLabel?: string;\n\treadonly onRequest?: (request: Request) => Promise<Request | Response | void>;\n\treadonly onResponse?: (response: Response) => Promise<Response | void>;\n}\n\nexport interface ManagedVm {\n\treadonly id: string;\n\texec(command: string): Promise<ExecResult>;\n\tenableSsh(options?: unknown): Promise<SshAccess>;\n\tenableIngress(options?: unknown): Promise<IngressAccess>;\n\tgetVmInstance(): ManagedVmInstance;\n\tsetIngressRoutes(routes: readonly IngressRoute[]): void;\n\tclose(): Promise<void>;\n}\n\n/* oxlint-disable typescript-eslint/no-unsafe-type-assertion -- Gondolin SDK boundary:\n The dependency injection pattern uses `unknown` to decouple from SDK internals.\n The `as never` casts bridge our unknown-typed providers to the SDK's concrete types. */\nfunction createDefaultDependencies(): ManagedVmDependencies {\n\treturn {\n\t\tcreateVm: async (vmOptions: unknown): Promise<ManagedVmInstance> =>\n\t\t\t(await VM.create(vmOptions as never)) as unknown as ManagedVmInstance,\n\t\tcreateHttpHooks: (hookOptions) =>\n\t\t\tcreateHttpHooks({\n\t\t\t\tallowedHosts: [...hookOptions.allowedHosts],\n\t\t\t\tsecrets: Object.fromEntries(\n\t\t\t\t\tObject.entries(hookOptions.secrets).map(([secretName, secretSpec]) => [\n\t\t\t\t\t\tsecretName,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thosts: [...secretSpec.hosts],\n\t\t\t\t\t\t\tvalue: secretSpec.value,\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t\t...(hookOptions.onRequest ? { onRequest: hookOptions.onRequest } : {}),\n\t\t\t\t...(hookOptions.onResponse ? { onResponse: hookOptions.onResponse } : {}),\n\t\t\t}),\n\t\tcreateRealFsProvider: (hostPath: string): unknown => new RealFSProvider(hostPath),\n\t\tcreateReadonlyProvider: (provider: unknown): unknown => new ReadonlyProvider(provider as never),\n\t\tcreateMemoryProvider: (): unknown => new MemoryProvider(),\n\t\tcreateShadowProvider: (provider: unknown, shadowOptions: unknown): unknown =>\n\t\t\tnew ShadowProvider(provider as never, shadowOptions as never),\n\t\tcreateShadowPathPredicate: (paths: readonly string[]): unknown =>\n\t\t\tcreateShadowPathPredicate([...paths]),\n\t};\n}\n/* oxlint-enable typescript-eslint/no-unsafe-type-assertion */\n\nfunction normalizeShadowPath(pathValue: string): string {\n\tconst trimmedPath = pathValue.trim();\n\tif (trimmedPath.startsWith('/')) {\n\t\treturn trimmedPath;\n\t}\n\n\tconst relativePath = trimmedPath.startsWith('./') ? trimmedPath.slice('./'.length) : trimmedPath;\n\treturn `/${relativePath}`;\n}\n\nfunction createProviderFromSpec(\n\tmountSpec: VfsMountSpec,\n\tdependencies: ManagedVmDependencies,\n): unknown {\n\tswitch (mountSpec.kind) {\n\t\tcase 'memory':\n\t\t\treturn dependencies.createMemoryProvider();\n\t\tcase 'realfs': {\n\t\t\tif (!mountSpec.hostPath) {\n\t\t\t\tthrow new Error('realfs mounts require hostPath');\n\t\t\t}\n\n\t\t\treturn dependencies.createRealFsProvider(mountSpec.hostPath);\n\t\t}\n\t\tcase 'realfs-readonly': {\n\t\t\tif (!mountSpec.hostPath) {\n\t\t\t\tthrow new Error('realfs-readonly mounts require hostPath');\n\t\t\t}\n\n\t\t\treturn dependencies.createReadonlyProvider(\n\t\t\t\tdependencies.createRealFsProvider(mountSpec.hostPath),\n\t\t\t);\n\t\t}\n\t\tcase 'shadow': {\n\t\t\tconst baseProvider = mountSpec.hostPath\n\t\t\t\t? dependencies.createRealFsProvider(mountSpec.hostPath)\n\t\t\t\t: dependencies.createMemoryProvider();\n\n\t\t\tlet shadowProvider = baseProvider;\n\t\t\tconst shadowConfig = mountSpec.shadowConfig;\n\n\t\t\tif (shadowConfig?.deny.length) {\n\t\t\t\tshadowProvider = dependencies.createShadowProvider(shadowProvider, {\n\t\t\t\t\tshouldShadow: dependencies.createShadowPathPredicate(\n\t\t\t\t\t\tshadowConfig.deny.map((shadowPath) => normalizeShadowPath(shadowPath)),\n\t\t\t\t\t),\n\t\t\t\t\twriteMode: 'deny',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (shadowConfig?.tmpfs.length) {\n\t\t\t\tshadowProvider = dependencies.createShadowProvider(shadowProvider, {\n\t\t\t\t\tshouldShadow: dependencies.createShadowPathPredicate(\n\t\t\t\t\t\tshadowConfig.tmpfs.map((shadowPath) => normalizeShadowPath(shadowPath)),\n\t\t\t\t\t),\n\t\t\t\t\twriteMode: 'tmpfs',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn shadowProvider;\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(`Unsupported VFS mount kind: ${String(mountSpec.kind)}`);\n\t\t}\n\t}\n}\n\nfunction createVfsMounts(\n\tvfsMounts: Record<string, VfsMountSpec>,\n\tdependencies: ManagedVmDependencies,\n): Record<string, unknown> {\n\tconst mountMap: Record<string, unknown> = {};\n\n\tfor (const [guestPath, mountSpec] of Object.entries(vfsMounts)) {\n\t\tmountMap[guestPath] = createProviderFromSpec(mountSpec, dependencies);\n\t}\n\n\treturn mountMap;\n}\n\nexport async function createManagedVm(\n\toptions: CreateVmOptions,\n\tdependencies: ManagedVmDependencies = createDefaultDependencies(),\n): Promise<ManagedVm> {\n\tconst hookBundle = dependencies.createHttpHooks({\n\t\tallowedHosts: options.allowedHosts,\n\t\tsecrets: options.secrets,\n\t\t...(options.onRequest ? { onRequest: options.onRequest } : {}),\n\t\t...(options.onResponse ? { onResponse: options.onResponse } : {}),\n\t});\n\n\tconst hasTcpHosts = options.tcpHosts && Object.keys(options.tcpHosts).length > 0;\n\tconst hasImagePath = options.imagePath !== undefined && options.imagePath.length > 0;\n\tconst sandboxOptions = hasImagePath ? { imagePath: options.imagePath } : {};\n\tconst vmInstance = await dependencies.createVm({\n\t\t...(Object.keys(sandboxOptions).length > 0 ? { sandbox: sandboxOptions } : {}),\n\t\tsessionLabel: options.sessionLabel,\n\t\trootfs: {\n\t\t\tmode: options.rootfsMode,\n\t\t},\n\t\tmemory: options.memory,\n\t\tcpus: options.cpus,\n\t\tenv: {\n\t\t\t...hookBundle.env,\n\t\t\t...options.env,\n\t\t},\n\t\thttpHooks: hookBundle.httpHooks,\n\t\tvfs: {\n\t\t\tfuseMount: '/data',\n\t\t\tmounts: createVfsMounts(options.vfsMounts, dependencies),\n\t\t},\n\t\t...(hasTcpHosts\n\t\t\t? {\n\t\t\t\t\tdns: {\n\t\t\t\t\t\tmode: 'synthetic',\n\t\t\t\t\t\tsyntheticHostMapping: 'per-host',\n\t\t\t\t\t},\n\t\t\t\t\ttcp: {\n\t\t\t\t\t\thosts: options.tcpHosts,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t});\n\n\treturn {\n\t\tid: vmInstance.id,\n\t\tasync exec(command: string): Promise<ExecResult> {\n\t\t\tconst executionResult = await vmInstance.exec(command);\n\t\t\treturn {\n\t\t\t\texitCode: executionResult.exitCode,\n\t\t\t\tstdout: executionResult.stdout ?? '',\n\t\t\t\tstderr: executionResult.stderr ?? '',\n\t\t\t};\n\t\t},\n\t\tasync enableSsh(sshOptions?: unknown): Promise<SshAccess> {\n\t\t\treturn await vmInstance.enableSsh(sshOptions);\n\t\t},\n\t\tasync enableIngress(ingressOptions?: unknown): Promise<IngressAccess> {\n\t\t\treturn await vmInstance.enableIngress(ingressOptions);\n\t\t},\n\t\tgetVmInstance(): ManagedVmInstance {\n\t\t\treturn vmInstance;\n\t\t},\n\t\tsetIngressRoutes(routes: readonly IngressRoute[]): void {\n\t\t\tvmInstance.setIngressRoutes(routes);\n\t\t},\n\t\tasync close(): Promise<void> {\n\t\t\tawait vmInstance.close();\n\t\t},\n\t};\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface VolumeConfigEntry {\n\treadonly guestPath: string;\n}\n\nexport interface ResolvedVolume {\n\treadonly hostDir: string;\n\treadonly guestPath: string;\n}\n\nexport async function ensureVolumeDir(\n\tcacheBase: string,\n\tworkspaceHash: string,\n\tvolumeName: string,\n): Promise<string> {\n\tconst volumeDirectory = path.join(cacheBase, workspaceHash, volumeName);\n\tawait fs.mkdir(volumeDirectory, { recursive: true });\n\treturn volumeDirectory;\n}\n\nexport async function resolveVolumeDirs(\n\tcacheBase: string,\n\tworkspaceHash: string,\n\tvolumes: Readonly<Record<string, VolumeConfigEntry>>,\n): Promise<Record<string, ResolvedVolume>> {\n\tconst resolvedVolumeEntries = await Promise.all(\n\t\tObject.entries(volumes).map(\n\t\t\tasync ([volumeName, volumeConfig]) =>\n\t\t\t\t[\n\t\t\t\t\tvolumeName,\n\t\t\t\t\t{\n\t\t\t\t\t\tguestPath: volumeConfig.guestPath,\n\t\t\t\t\t\thostDir: await ensureVolumeDir(cacheBase, workspaceHash, volumeName),\n\t\t\t\t\t},\n\t\t\t\t] satisfies readonly [string, ResolvedVolume],\n\t\t),\n\t);\n\n\treturn Object.fromEntries(resolvedVolumeEntries);\n}\n","import fs from 'node:fs/promises';\n\nexport async function writeFileAtomically(\n\tfilePath: string,\n\tcontent: string,\n\toptions: {\n\t\treadonly mode?: number;\n\t} = {},\n): Promise<void> {\n\tconst temporaryFilePath = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n\tawait fs.writeFile(temporaryFilePath, content, {\n\t\tencoding: 'utf8',\n\t\t...(options.mode ? { mode: options.mode } : {}),\n\t});\n\ttry {\n\t\tawait fs.rename(temporaryFilePath, filePath);\n\t} catch (renameError) {\n\t\ttry {\n\t\t\tawait fs.rm(temporaryFilePath, { force: true });\n\t\t} catch (cleanupError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to replace '${filePath}' (${renameError instanceof Error ? renameError.message : JSON.stringify(renameError)}) and failed to remove temporary file '${temporaryFilePath}': ${cleanupError instanceof Error ? cleanupError.message : JSON.stringify(cleanupError)}`,\n\t\t\t\t{ cause: cleanupError },\n\t\t\t);\n\t\t}\n\t\tthrow renameError;\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["parsed: unknown","rawContents: string","fs","normalizedValues: string[]","resolvedSecrets: Record<string, string>","mountMap: Record<string, VirtualProvider>","vmInstance: ManagedVmInstance","closeError: unknown"],"sources":["../src/build-pipeline.ts","../src/gondolin-package.ts","../src/mount-policy.ts","../src/pinned-realfs.ts","../src/policy-compiler.ts","../src/secret-resolver.ts","../src/vm-adapter.ts","../src/volume-manager.ts","../src/write-file-atomically.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport type { BuildConfig, BuildOptions } from '@earendil-works/gondolin';\n\nexport type { BuildConfig } from '@earendil-works/gondolin';\n\nexport interface BuildImageOptions {\n\treadonly buildConfig: BuildConfig;\n\treadonly cacheDir: string;\n\t/** Directory to resolve relative paths in buildConfig (e.g. postBuild.copy.src).\n\t * Defaults to process.cwd() if not provided. */\n\treadonly configDir?: string;\n\treadonly fullReset?: boolean;\n\treadonly fingerprintInput?: unknown;\n\treadonly output?: BuildOutput;\n}\n\nexport interface BuildOutput {\n\twrite(chunk: string | Uint8Array): boolean;\n}\n\nexport interface BuildImageResult {\n\treadonly built: boolean;\n\treadonly fingerprint: string;\n\treadonly imagePath: string;\n}\n\ninterface BuildPipelineDependencies {\n\treadonly buildAssets?: (\n\t\tbuildConfig: BuildConfig,\n\t\toutputDirectory: string,\n\t\tconfigDir?: string,\n\t) => Promise<unknown>;\n\treadonly gondolinVersion?: string;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null;\n}\n\nfunction stableSerialize(value: unknown): string {\n\tif (Array.isArray(value)) {\n\t\treturn `[${value.map((entry) => stableSerialize(entry)).join(',')}]`;\n\t}\n\n\tif (isRecord(value)) {\n\t\tconst objectEntries = Object.entries(value)\n\t\t\t.filter(([, entryValue]) => entryValue !== undefined)\n\t\t\t.toSorted(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey));\n\t\treturn `{${objectEntries\n\t\t\t.map(([entryKey, entryValue]) => `${JSON.stringify(entryKey)}:${stableSerialize(entryValue)}`)\n\t\t\t.join(',')}}`;\n\t}\n\n\treturn JSON.stringify(value);\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n\ttry {\n\t\tawait fs.access(filePath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function hasBuiltAssets(outputDirectoryPath: string): Promise<boolean> {\n\treturn (\n\t\t(await pathExists(path.join(outputDirectoryPath, 'manifest.json'))) &&\n\t\t(await pathExists(path.join(outputDirectoryPath, 'rootfs.ext4'))) &&\n\t\t(await pathExists(path.join(outputDirectoryPath, 'initramfs.cpio.lz4'))) &&\n\t\t(await pathExists(path.join(outputDirectoryPath, 'vmlinuz-virt')))\n\t);\n}\n\nasync function loadBuildAssets(): Promise<\n\t(buildConfig: BuildConfig, outputDirectory: string, configDir?: string) => Promise<unknown>\n> {\n\tconst gondolinModule = await import('@earendil-works/gondolin');\n\treturn async (\n\t\tbuildConfig: BuildConfig,\n\t\toutputDirectory: string,\n\t\tconfigDir?: string,\n\t): Promise<unknown> =>\n\t\tawait gondolinModule.buildAssets(buildConfig, {\n\t\t\toutputDir: outputDirectory,\n\t\t\tverbose: false,\n\t\t\t...(configDir ? { configDir } : {}),\n\t\t} satisfies BuildOptions);\n}\n\nfunction createRedirectedWrite(output: BuildOutput): typeof process.stderr.write {\n\treturn ((\n\t\tchunk: string | Uint8Array,\n\t\tencodingOrCallback?: BufferEncoding | ((error?: Error | null) => void),\n\t\tcallback?: (error?: Error | null) => void,\n\t): boolean => {\n\t\tconst writeCallback = typeof encodingOrCallback === 'function' ? encodingOrCallback : callback;\n\t\tconst wrote = output.write(chunk);\n\t\twriteCallback?.();\n\t\treturn wrote;\n\t}) as typeof process.stderr.write;\n}\n\nasync function withCapturedBuildOutput<TResult>(\n\toutput: BuildOutput | undefined,\n\tfn: () => Promise<TResult>,\n): Promise<TResult> {\n\tif (!output) {\n\t\treturn await fn();\n\t}\n\n\tconst originalStderrWrite = process.stderr.write.bind(process.stderr);\n\tconst originalStdoutWrite = process.stdout.write.bind(process.stdout);\n\tconst originalCi = process.env.CI;\n\tconst redirectedWrite = createRedirectedWrite(output);\n\n\tprocess.stderr.write = redirectedWrite;\n\tprocess.stdout.write = redirectedWrite;\n\tprocess.env.CI = 'true';\n\n\ttry {\n\t\treturn await fn();\n\t} finally {\n\t\tprocess.stderr.write = originalStderrWrite;\n\t\tprocess.stdout.write = originalStdoutWrite;\n\t\tif (originalCi === undefined) {\n\t\t\tdelete process.env.CI;\n\t\t} else {\n\t\t\tprocess.env.CI = originalCi;\n\t\t}\n\t}\n}\n\nexport function computeBuildFingerprint(\n\tbuildConfig: BuildConfig,\n\tgondolinVersion: string = 'unknown',\n\tfingerprintInput?: unknown,\n): string {\n\tconst payload =\n\t\tfingerprintInput === undefined\n\t\t\t? `${stableSerialize(buildConfig)}|${gondolinVersion}`\n\t\t\t: `${stableSerialize(buildConfig)}|${gondolinVersion}|${stableSerialize(fingerprintInput)}`;\n\n\treturn crypto.createHash('sha256').update(payload).digest('hex').slice(0, 16);\n}\n\nexport async function buildImage(\n\toptions: BuildImageOptions,\n\tdependencies: BuildPipelineDependencies = {},\n): Promise<BuildImageResult> {\n\tconst fingerprint = computeBuildFingerprint(\n\t\toptions.buildConfig,\n\t\tdependencies.gondolinVersion,\n\t\toptions.fingerprintInput,\n\t);\n\tconst imagePath = path.join(options.cacheDir, fingerprint);\n\n\tif (options.fullReset) {\n\t\tawait fs.rm(imagePath, { recursive: true, force: true });\n\t}\n\n\tif (await hasBuiltAssets(imagePath)) {\n\t\treturn {\n\t\t\tbuilt: false,\n\t\t\tfingerprint,\n\t\t\timagePath,\n\t\t};\n\t}\n\n\tawait fs.mkdir(imagePath, { recursive: true });\n\tconst buildAssetsImplementation = dependencies.buildAssets ?? (await loadBuildAssets());\n\tawait withCapturedBuildOutput(options.output, async () => {\n\t\tawait buildAssetsImplementation(options.buildConfig, imagePath, options.configDir);\n\t});\n\n\tif (!(await hasBuiltAssets(imagePath))) {\n\t\tthrow new Error(`Expected Gondolin assets to be written to ${imagePath}.`);\n\t}\n\n\treturn {\n\t\tbuilt: true,\n\t\tfingerprint,\n\t\timagePath,\n\t};\n}\n","import fs from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport path from 'node:path';\n\nimport { z } from 'zod';\n\nconst requireFromHere = createRequire(import.meta.url);\n\nconst gondolinPackageJsonSchema = z.object({\n\tversion: z.string().min(1),\n});\n\nfunction isMissingFileError(error: unknown): boolean {\n\treturn typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT';\n}\n\nfunction getErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nexport function parseMinimumZigVersion(rawContents: string): string {\n\tconst match = rawContents.match(/\\.minimum_zig_version\\s*=\\s*\"([^\"]*)\"/u);\n\tif (!match) {\n\t\tthrow new Error(\n\t\t\t'minimum_zig_version declaration not found. Expected a line like `.minimum_zig_version = \"0.15.2\"`.',\n\t\t);\n\t}\n\n\tconst version = match[1];\n\tif (!version) {\n\t\tthrow new Error('minimum_zig_version is empty.');\n\t}\n\treturn version;\n}\n\nexport function resolveGondolinPackageJsonPath(): string {\n\treturn requireFromHere.resolve('@earendil-works/gondolin/package.json');\n}\n\nexport async function resolveGondolinPackageSpec(): Promise<string> {\n\tconst packageJsonPath = resolveGondolinPackageJsonPath();\n\tconst parsed: unknown = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));\n\tconst packageJson = gondolinPackageJsonSchema.parse(parsed);\n\treturn `@earendil-works/gondolin@${packageJson.version}`;\n}\n\nexport interface ResolveGondolinMinimumZigVersionOptions {\n\treadonly buildZigZonPath?: string;\n}\n\nasync function resolveDefaultBuildZigZonPath(): Promise<string> {\n\tconst packageJsonPath = resolveGondolinPackageJsonPath();\n\treturn path.join(path.dirname(packageJsonPath), 'dist', 'guest', 'build.zig.zon');\n}\n\nexport async function resolveGondolinMinimumZigVersion(\n\toptions: ResolveGondolinMinimumZigVersionOptions = {},\n): Promise<string> {\n\tconst zonPath = options.buildZigZonPath ?? (await resolveDefaultBuildZigZonPath());\n\tlet rawContents: string;\n\ttry {\n\t\trawContents = await fs.readFile(zonPath, 'utf8');\n\t} catch (error) {\n\t\tif (isMissingFileError(error)) {\n\t\t\tthrow new Error(`Missing Gondolin build.zig.zon at '${zonPath}'.`, { cause: error });\n\t\t}\n\t\tthrow new Error(\n\t\t\t`Failed to read Gondolin build.zig.zon at '${zonPath}': ${getErrorMessage(error)}`,\n\t\t\t{ cause: error },\n\t\t);\n\t}\n\n\ttry {\n\t\treturn parseMinimumZigVersion(rawContents);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to parse Gondolin build.zig.zon at '${zonPath}': ${getErrorMessage(error)}`,\n\t\t\t{ cause: error },\n\t\t);\n\t}\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nconst AUTH_GUEST_PATH_PREFIXES = [\n\t'/home/agent/.aws',\n\t'/home/agent/.claude',\n\t'/home/agent/.codex',\n\t'/home/agent/.gemini',\n\t'/home/openclaw/.aws',\n\t'/home/openclaw/.claude',\n\t'/home/openclaw/.codex',\n\t'/home/openclaw/.gemini',\n\t'/home/openclaw/.openclaw',\n] as const;\n\nexport interface WritableMountPolicy {\n\treadonly allowAuthWrite: boolean;\n\treadonly writableAllowedGuestPrefixes: readonly string[];\n}\n\nexport interface RuntimeMountPolicyConfig {\n\treadonly extraMounts: Readonly<Record<string, string>>;\n\treadonly mountControls: WritableMountPolicy;\n}\n\nfunction resolveAuthHostPrefixes(hostHome: string): readonly string[] {\n\treturn [\n\t\tpath.join(hostHome, '.aws'),\n\t\tpath.join(hostHome, '.claude'),\n\t\tpath.join(hostHome, '.codex'),\n\t\tpath.join(hostHome, '.gemini'),\n\t];\n}\n\nexport function resolveGuestMountPath(guestPath: string, workDir: string): string {\n\tif (path.isAbsolute(guestPath)) {\n\t\treturn path.resolve(guestPath);\n\t}\n\n\treturn path.resolve(workDir, guestPath);\n}\n\nfunction isPathWithinPrefix(candidatePath: string, prefixPath: string): boolean {\n\tconst relativePath = path.relative(prefixPath, candidatePath);\n\treturn relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath));\n}\n\nasync function normalizeHostPath(hostPath: string): Promise<string> {\n\tconst resolvedHostPath = path.resolve(hostPath);\n\n\ttry {\n\t\treturn await fs.realpath(resolvedHostPath);\n\t} catch {\n\t\treturn resolvedHostPath;\n\t}\n}\n\nfunction pathsOverlap(candidatePath: string, protectedPath: string): boolean {\n\treturn (\n\t\tisPathWithinPrefix(candidatePath, protectedPath) ||\n\t\tisPathWithinPrefix(protectedPath, candidatePath)\n\t);\n}\n\nexport function validateWritableMount(\n\tguestPath: string,\n\tpolicy: WritableMountPolicy,\n\toptions: { readonly workDir: string },\n): void {\n\tconst resolvedGuestPath = resolveGuestMountPath(guestPath, options.workDir);\n\tconst resolvedAllowedPrefixes = policy.writableAllowedGuestPrefixes.map((allowedPrefix) =>\n\t\tresolveGuestMountPath(allowedPrefix, options.workDir),\n\t);\n\n\tconst isAllowedGuestPath = resolvedAllowedPrefixes.some((allowedPrefix) =>\n\t\tisPathWithinPrefix(resolvedGuestPath, allowedPrefix),\n\t);\n\tif (!isAllowedGuestPath) {\n\t\tthrow new Error(\n\t\t\t`Writable mount guest path '${resolvedGuestPath}' is outside writable allowlist [${resolvedAllowedPrefixes.join(', ')}].`,\n\t\t);\n\t}\n\n\tif (!policy.allowAuthWrite) {\n\t\tconst targetsProtectedGuestPath = AUTH_GUEST_PATH_PREFIXES.some((authPrefix) =>\n\t\t\tisPathWithinPrefix(resolvedGuestPath, authPrefix),\n\t\t);\n\t\tif (targetsProtectedGuestPath) {\n\t\t\tthrow new Error(\n\t\t\t\t`Writable mount guest path '${resolvedGuestPath}' targets an auth mount path. Set mountControls.allowAuthWrite=true to permit auth writes.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nexport async function validateRuntimeMountPolicy(\n\tconfig: RuntimeMountPolicyConfig,\n\toptions: { readonly hostHome: string; readonly workDir: string },\n): Promise<void> {\n\tconst mountEntries = Object.entries(config.extraMounts);\n\tfor (const [guestPath] of mountEntries) {\n\t\tvalidateWritableMount(guestPath, config.mountControls, options);\n\t}\n\n\tif (config.mountControls.allowAuthWrite) {\n\t\treturn;\n\t}\n\n\tconst absoluteHostMountEntries = mountEntries.filter(([, hostPath]) => path.isAbsolute(hostPath));\n\tconst [protectedHostPaths, writableHostPaths] = await Promise.all([\n\t\tPromise.all(\n\t\t\tresolveAuthHostPrefixes(options.hostHome).map(\n\t\t\t\tasync (authHostPrefix) => await normalizeHostPath(authHostPrefix),\n\t\t\t),\n\t\t),\n\t\tPromise.all(\n\t\t\tabsoluteHostMountEntries.map(async ([, hostPath]) => await normalizeHostPath(hostPath)),\n\t\t),\n\t]);\n\n\tfor (const resolvedWritableHostPath of writableHostPaths) {\n\t\tconst overlapsProtectedHostPath = protectedHostPaths.some((authHostPrefix) =>\n\t\t\tpathsOverlap(resolvedWritableHostPath, authHostPrefix),\n\t\t);\n\n\t\tif (overlapsProtectedHostPath) {\n\t\t\tthrow new Error(\n\t\t\t\t`Writable host path '${resolvedWritableHostPath}' targets an auth host directory. Set mountControls.allowAuthWrite=true to permit auth writes.`,\n\t\t\t);\n\t\t}\n\t}\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { VirtualProvider } from '@earendil-works/gondolin';\n\nexport interface PinnedRealFsRoot {\n\treadonly hostPath: string;\n\treadonly realPath: string;\n\treadonly fd: number;\n\treadonly device: number;\n\treadonly inode: number;\n}\n\nexport interface CreatePinnedRealFsProviderOptions {\n\treadonly root: PinnedRealFsRoot;\n\treadonly createRealFsProvider: (hostPath: string) => VirtualProvider;\n}\n\nfunction formatRootIdentity(root: PinnedRealFsRoot): string {\n\treturn `${root.device}:${root.inode}`;\n}\n\nfunction openDirectoryNoFollow(candidatePath: string): number {\n\treturn fs.openSync(\n\t\tcandidatePath,\n\t\tfs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW,\n\t);\n}\n\nexport function pinRealFsRoot(hostPath: string): PinnedRealFsRoot {\n\tif (!hostPath || !path.isAbsolute(hostPath)) {\n\t\tthrow new Error(`Pinned RealFS root must be a non-empty absolute path: ${hostPath}`);\n\t}\n\n\tconst resolvedHostPath = path.resolve(hostPath);\n\tconst fd = openDirectoryNoFollow(resolvedHostPath);\n\ttry {\n\t\tconst stats = fs.fstatSync(fd);\n\t\tif (!stats.isDirectory()) {\n\t\t\tthrow new Error(`Pinned RealFS root is not a directory: ${resolvedHostPath}`);\n\t\t}\n\t\tconst realPath = fs.realpathSync(resolvedHostPath);\n\t\tconst realPathStats = fs.statSync(realPath);\n\t\tif (realPathStats.dev !== stats.dev || realPathStats.ino !== stats.ino) {\n\t\t\tthrow new Error(\n\t\t\t\t`Pinned RealFS root changed while opening: ${resolvedHostPath} opened ${stats.dev}:${stats.ino} but resolved to ${realPathStats.dev}:${realPathStats.ino}`,\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tdevice: stats.dev,\n\t\t\tfd,\n\t\t\thostPath: resolvedHostPath,\n\t\t\tinode: stats.ino,\n\t\t\trealPath,\n\t\t};\n\t} catch (error) {\n\t\tfs.closeSync(fd);\n\t\tthrow error;\n\t}\n}\n\nexport function closePinnedRealFsRoot(root: PinnedRealFsRoot): void {\n\tfs.closeSync(root.fd);\n}\n\nexport function assertPinnedRealFsRoot(root: PinnedRealFsRoot): void {\n\tconst pinnedStats = fs.fstatSync(root.fd);\n\tconst currentStats = fs.statSync(root.realPath);\n\tif (\n\t\tpinnedStats.dev !== root.device ||\n\t\tpinnedStats.ino !== root.inode ||\n\t\tcurrentStats.dev !== root.device ||\n\t\tcurrentStats.ino !== root.inode\n\t) {\n\t\tthrow new Error(\n\t\t\t`Pinned RealFS root changed before mount access: ${root.realPath} expected ${formatRootIdentity(root)} got ${currentStats.dev}:${currentStats.ino}`,\n\t\t);\n\t}\n}\n\ntype ProviderMethod = (...args: unknown[]) => unknown;\n\n/* oxlint-disable typescript-eslint/no-unsafe-type-assertion -- Reflect.get()\n loses the method signature from Gondolin's VirtualProvider union. The proxy\n keeps the same provider object and only wraps callable properties with the\n pinned-root assertion. */\nexport function createPinnedRealFsProvider(\n\toptions: CreatePinnedRealFsProviderOptions,\n): VirtualProvider {\n\tassertPinnedRealFsRoot(options.root);\n\tconst provider = options.createRealFsProvider(options.root.realPath);\n\n\treturn new Proxy(provider, {\n\t\tget(target: VirtualProvider, property: string | symbol, receiver: unknown): unknown {\n\t\t\tconst value = Reflect.get(target, property, receiver) as unknown;\n\t\t\tif (typeof value !== 'function') {\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\treturn (...methodArguments: readonly unknown[]): unknown => {\n\t\t\t\tassertPinnedRealFsRoot(options.root);\n\t\t\t\treturn Reflect.apply(value as ProviderMethod, target, methodArguments);\n\t\t\t};\n\t\t},\n\t});\n}\n/* oxlint-enable typescript-eslint/no-unsafe-type-assertion */\n","export interface PolicySources {\n\treadonly base: readonly string[];\n\treadonly profile: readonly string[];\n\treadonly extra: readonly string[];\n}\n\nexport function normalizeHostname(rawHostname: string): string {\n\treturn rawHostname.trim().toLowerCase().replace(/\\.+$/u, '');\n}\n\nexport function dedupeStable(values: readonly string[]): string[] {\n\tconst seenHostnames = new Set<string>();\n\tconst normalizedValues: string[] = [];\n\n\tfor (const value of values) {\n\t\tconst normalizedValue = normalizeHostname(value);\n\t\tif (normalizedValue.length === 0 || normalizedValue.startsWith('#')) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!seenHostnames.has(normalizedValue)) {\n\t\t\tseenHostnames.add(normalizedValue);\n\t\t\tnormalizedValues.push(normalizedValue);\n\t\t}\n\t}\n\n\treturn normalizedValues;\n}\n\nexport function compilePolicy(sources: PolicySources): string[] {\n\treturn dedupeStable([...sources.base, ...sources.profile, ...sources.extra]);\n}\n","import { execFile } from 'node:child_process';\n\nimport { createClient } from '@1password/sdk';\n\nimport type { SecretRef } from './types.js';\n\nexport interface SecretResolverClient {\n\treadonly secrets: {\n\t\tresolve(secretReference: string): Promise<string>;\n\t\tresolveAll(secretReferences: readonly string[]): Promise<unknown>;\n\t};\n}\n\nexport interface SecretResolver {\n\tresolve(ref: SecretRef): Promise<string>;\n\tresolveAll(refs: Record<string, SecretRef>): Promise<Record<string, string>>;\n}\n\n// --- Token source: how to obtain the 1Password service account token ---\n\nexport type TokenSource =\n\t| { readonly type: 'op-cli'; readonly ref: string }\n\t| { readonly type: 'env'; readonly envVar?: string | undefined }\n\t| { readonly type: 'keychain'; readonly service: string; readonly account: string };\n\nexport interface ExecFileOptions {\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n}\n\nexport interface ExecFileResult {\n\treadonly stdout: string;\n\treadonly stderr: string;\n}\n\nfunction writeStderr(message: string): void {\n\tprocess.stderr.write(`${message}\\n`);\n}\n\nfunction ensureMacOsForKeychain(): void {\n\tif (process.platform !== 'darwin') {\n\t\tthrow new Error(\n\t\t\t'Keychain token source is only supported on macOS. Use an env or op-cli token source on this platform so cmd-ts can surface a clear startup error.',\n\t\t);\n\t}\n}\n\nfunction execFileAsync(\n\tcommand: string,\n\targs: readonly string[],\n\toptions?: ExecFileOptions,\n): Promise<ExecFileResult> {\n\treturn new Promise((resolve, reject) => {\n\t\texecFile(\n\t\t\tcommand,\n\t\t\t[...args],\n\t\t\t{ env: options?.env, timeout: 30_000 },\n\t\t\t(error, stdout, stderr) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tconst errorMessage = error instanceof Error ? error.message : JSON.stringify(error);\n\t\t\t\t\treject(new Error(`${command} failed: ${stderr.trim() || errorMessage}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tresolve({ stdout, stderr });\n\t\t\t},\n\t\t);\n\t});\n}\n\nconst SAFE_IDENTIFIER_PATTERN = /^[\\w.@-]+$/u;\n\nexport async function resolveServiceAccountToken(\n\tsource: TokenSource,\n\tdependencies?: {\n\t\treadonly execFileAsync?: (\n\t\t\tcommand: string,\n\t\t\targs: readonly string[],\n\t\t\toptions?: ExecFileOptions,\n\t\t) => Promise<ExecFileResult>;\n\t},\n): Promise<string> {\n\tconst exec = dependencies?.execFileAsync ?? execFileAsync;\n\n\tswitch (source.type) {\n\t\tcase 'op-cli': {\n\t\t\t// Uses `op read` which triggers biometric auth (Touch ID) on macOS\n\t\t\tconst result = await exec('op', ['read', source.ref]);\n\t\t\tconst token = result.stdout.trim();\n\t\t\tif (token.length === 0) {\n\t\t\t\tthrow new Error('op-cli token resolution returned empty value');\n\t\t\t}\n\n\t\t\treturn token;\n\t\t}\n\n\t\tcase 'env': {\n\t\t\tconst envVar = source.envVar ?? 'OP_SERVICE_ACCOUNT_TOKEN';\n\t\t\tconst token = process.env[envVar]?.trim();\n\t\t\tif (!token) {\n\t\t\t\tthrow new Error(`Environment variable ${envVar} is not set`);\n\t\t\t}\n\n\t\t\treturn token;\n\t\t}\n\n\t\tcase 'keychain': {\n\t\t\tensureMacOsForKeychain();\n\n\t\t\t// Validate keychain identifiers to prevent argument injection\n\t\t\tif (!SAFE_IDENTIFIER_PATTERN.test(source.service)) {\n\t\t\t\tthrow new Error('Keychain service name contains invalid characters');\n\t\t\t}\n\n\t\t\tif (!SAFE_IDENTIFIER_PATTERN.test(source.account)) {\n\t\t\t\tthrow new Error('Keychain account name contains invalid characters');\n\t\t\t}\n\n\t\t\t// macOS Keychain via `security find-generic-password`\n\t\t\tconst result = await exec('security', [\n\t\t\t\t'find-generic-password',\n\t\t\t\t'-s',\n\t\t\t\tsource.service,\n\t\t\t\t'-a',\n\t\t\t\tsource.account,\n\t\t\t\t'-w',\n\t\t\t]);\n\t\t\tconst token = result.stdout.trim();\n\t\t\tif (token.length === 0) {\n\t\t\t\tthrow new Error('Keychain token resolution returned empty value');\n\t\t\t}\n\n\t\t\treturn token;\n\t\t}\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported token source: ${JSON.stringify(source)}`);\n\t}\n}\n\n// --- Secret resolver: uses the token to resolve secrets via 1Password SDK ---\n\nexport interface CreateSecretResolverDependencies {\n\treadonly createClient?: (config: {\n\t\tauth: string;\n\t\tintegrationName: string;\n\t\tintegrationVersion: string;\n\t}) => Promise<SecretResolverClient>;\n\treadonly execFileAsync?: (\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions?: ExecFileOptions,\n\t) => Promise<ExecFileResult>;\n\treadonly integrationName?: string;\n\treadonly integrationVersion?: string;\n}\n\nasync function resolveSecretWithOpCli(\n\tserviceAccountToken: string,\n\tsecretReference: string,\n\texec: (\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions?: ExecFileOptions,\n\t) => Promise<ExecFileResult>,\n): Promise<string> {\n\tconst result = await exec('op', ['read', secretReference], {\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\tOP_SERVICE_ACCOUNT_TOKEN: serviceAccountToken,\n\t\t},\n\t});\n\treturn result.stdout.trim();\n}\n\nasync function resolveAllSecretsWithOpCli(\n\tserviceAccountToken: string,\n\trefs: Record<string, SecretRef>,\n\texec: (\n\t\tcommand: string,\n\t\targs: readonly string[],\n\t\toptions?: ExecFileOptions,\n\t) => Promise<ExecFileResult>,\n): Promise<Record<string, string>> {\n\tconst resolvedSecrets: Record<string, string> = {};\n\n\tfor (const [secretName, secretRef] of Object.entries(refs)) {\n\t\t// Sequential resolution avoids concurrent `op read` failures with the same service account token.\n\t\t// oxlint-disable-next-line eslint/no-await-in-loop\n\t\tresolvedSecrets[secretName] = await resolveSecretWithOpCli(\n\t\t\tserviceAccountToken,\n\t\t\tsecretRef.ref,\n\t\t\texec,\n\t\t);\n\t}\n\n\treturn resolvedSecrets;\n}\n\nexport async function createSecretResolver(\n\toptions: {\n\t\treadonly serviceAccountToken: string;\n\t},\n\tdependencies: CreateSecretResolverDependencies = {},\n): Promise<SecretResolver> {\n\tconst exec = dependencies.execFileAsync ?? execFileAsync;\n\ttry {\n\t\tconst client = await (dependencies.createClient ?? createClient)({\n\t\t\tauth: options.serviceAccountToken,\n\t\t\tintegrationName: dependencies.integrationName ?? 'agent-vm',\n\t\t\tintegrationVersion: dependencies.integrationVersion ?? '0.0.1',\n\t\t});\n\n\t\treturn {\n\t\t\tresolve: async (ref: SecretRef): Promise<string> => {\n\t\t\t\ttry {\n\t\t\t\t\treturn await client.secrets.resolve(ref.ref);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\twriteStderr(\n\t\t\t\t\t\t`[secret-resolver] 1Password SDK resolve failed for ${ref.ref}; falling back to op CLI: ${message}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn await resolveSecretWithOpCli(options.serviceAccountToken, ref.ref, exec);\n\t\t\t\t}\n\t\t\t},\n\t\t\tresolveAll: async (refs: Record<string, SecretRef>): Promise<Record<string, string>> => {\n\t\t\t\tconst resolvedSecrets: Record<string, string> = {};\n\n\t\t\t\tfor (const [secretName, secretRef] of Object.entries(refs)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// oxlint-disable-next-line eslint/no-await-in-loop\n\t\t\t\t\t\tresolvedSecrets[secretName] = await client.secrets.resolve(secretRef.ref);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\t\t\twriteStderr(\n\t\t\t\t\t\t\t`[secret-resolver] 1Password SDK resolve failed for ${secretRef.ref}; falling back to op CLI: ${message}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Sequential fallback avoids concurrent `op read` failures when the SDK path is unhealthy.\n\t\t\t\t\t\t// oxlint-disable-next-line eslint/no-await-in-loop\n\t\t\t\t\t\tresolvedSecrets[secretName] = await resolveSecretWithOpCli(\n\t\t\t\t\t\t\toptions.serviceAccountToken,\n\t\t\t\t\t\t\tsecretRef.ref,\n\t\t\t\t\t\t\texec,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn resolvedSecrets;\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\twriteStderr(\n\t\t\t`[secret-resolver] 1Password SDK client creation failed; falling back to op CLI: ${message}`,\n\t\t);\n\t\treturn {\n\t\t\tresolve: async (ref: SecretRef): Promise<string> =>\n\t\t\t\tawait resolveSecretWithOpCli(options.serviceAccountToken, ref.ref, exec),\n\t\t\tresolveAll: async (refs: Record<string, SecretRef>): Promise<Record<string, string>> =>\n\t\t\t\tawait resolveAllSecretsWithOpCli(options.serviceAccountToken, refs, exec),\n\t\t};\n\t}\n}\n\nexport async function createOpCliSecretResolver(\n\toptions: {\n\t\treadonly serviceAccountToken: string;\n\t},\n\tdependencies: Pick<CreateSecretResolverDependencies, 'execFileAsync'> = {},\n): Promise<SecretResolver> {\n\tconst exec = dependencies.execFileAsync ?? execFileAsync;\n\n\treturn {\n\t\tresolve: async (ref: SecretRef): Promise<string> =>\n\t\t\tawait resolveSecretWithOpCli(options.serviceAccountToken, ref.ref, exec),\n\t\tresolveAll: async (refs: Record<string, SecretRef>): Promise<Record<string, string>> =>\n\t\t\tawait resolveAllSecretsWithOpCli(options.serviceAccountToken, refs, exec),\n\t};\n}\n","import {\n\tMemoryProvider,\n\tReadonlyProvider,\n\tRealFSProvider,\n\tShadowProvider,\n\tVM,\n\tcreateHttpHooks,\n\tcreateShadowPathPredicate,\n\ttype CreateHttpHooksResult,\n\ttype EnableIngressOptions,\n\ttype EnableSshOptions,\n\ttype IngressRoute as GondolinIngressRoute,\n\ttype ShadowPredicate,\n\ttype ShadowProviderOptions,\n\ttype VMOptions,\n\ttype VirtualProvider,\n} from '@earendil-works/gondolin';\n\nimport {\n\tclosePinnedRealFsRoot,\n\tcreatePinnedRealFsProvider,\n\ttype PinnedRealFsRoot,\n} from './pinned-realfs.js';\nimport type { SecretSpec } from './types.js';\n\nexport interface ExecResult {\n\treadonly exitCode: number;\n\treadonly stdout: string;\n\treadonly stderr: string;\n}\n\nexport type IngressRoute = GondolinIngressRoute;\n\nexport interface SshAccess {\n\treadonly host: string;\n\treadonly command?: string;\n\treadonly identityFile?: string;\n\treadonly port: number;\n\treadonly user?: string;\n}\n\nexport interface IngressAccess {\n\treadonly host: string;\n\treadonly port: number;\n}\n\nexport interface ManagedVmInstance {\n\treadonly id: string;\n\texec(command: string): Promise<{\n\t\treadonly exitCode: number;\n\t\treadonly stdout?: string;\n\t\treadonly stderr?: string;\n\t}>;\n\tenableSsh(options?: EnableSshOptions): Promise<SshAccess>;\n\tenableIngress(options?: EnableIngressOptions): Promise<IngressAccess>;\n\tsetIngressRoutes(routes: readonly IngressRoute[]): void;\n\tclose(): Promise<void>;\n}\n\nexport interface ManagedVmDependencies {\n\tcreateVm(vmOptions: VMOptions): Promise<ManagedVmInstance>;\n\tcreateHttpHooks(options: {\n\t\treadonly allowedHosts: readonly string[];\n\t\treadonly secrets: Record<string, SecretSpec>;\n\t\treadonly onRequest?: (request: Request) => Promise<Request | Response | void>;\n\t\treadonly onResponse?: (response: Response) => Promise<Response | void>;\n\t}): Pick<CreateHttpHooksResult, 'env' | 'httpHooks'>;\n\tclosePinnedRealFsRoot(root: PinnedRealFsRoot): void;\n\tcreatePinnedRealFsProvider(root: PinnedRealFsRoot): VirtualProvider;\n\tcreateRealFsProvider(hostPath: string): VirtualProvider;\n\tcreateReadonlyProvider(provider: VirtualProvider): VirtualProvider;\n\tcreateMemoryProvider(): VirtualProvider;\n\tcreateShadowProvider(provider: VirtualProvider, options: ShadowProviderOptions): VirtualProvider;\n\tcreateShadowPathPredicate(paths: readonly string[]): ShadowPredicate;\n}\n\nexport interface VfsMountSpec {\n\treadonly kind: 'realfs' | 'realfs-readonly' | 'memory' | 'shadow';\n\treadonly hostPath?: string;\n\treadonly pinnedHostRoot?: PinnedRealFsRoot;\n\treadonly shadowConfig?: {\n\t\treadonly deny: readonly string[];\n\t\treadonly tmpfs: readonly string[];\n\t};\n}\n\nexport interface CreateVmOptions {\n\treadonly imagePath: string;\n\treadonly memory: string;\n\treadonly cpus: number;\n\treadonly rootfsMode: 'readonly' | 'memory' | 'cow';\n\treadonly allowedHosts: readonly string[];\n\treadonly secrets: Record<string, SecretSpec>;\n\treadonly vfsMounts: Record<string, VfsMountSpec>;\n\treadonly tcpHosts?: Record<string, string>;\n\treadonly env?: Record<string, string>;\n\treadonly sessionLabel?: string;\n\treadonly onRequest?: (request: Request) => Promise<Request | Response | void>;\n\treadonly onResponse?: (response: Response) => Promise<Response | void>;\n}\n\nexport interface ManagedVm {\n\treadonly id: string;\n\texec(command: string): Promise<ExecResult>;\n\tenableSsh(options?: EnableSshOptions): Promise<SshAccess>;\n\tenableIngress(options?: EnableIngressOptions): Promise<IngressAccess>;\n\tgetVmInstance(): ManagedVmInstance;\n\tsetIngressRoutes(routes: readonly IngressRoute[]): void;\n\tclose(): Promise<void>;\n}\n\n/* oxlint-disable typescript-eslint/no-unsafe-type-assertion -- VM.create() returns\n Gondolin's concrete VM class; this adapter exposes only the narrower\n ManagedVmInstance interface used by agent-vm. */\nfunction createDefaultDependencies(): ManagedVmDependencies {\n\tconst createDefaultRealFsProvider = (hostPath: string): VirtualProvider =>\n\t\tnew RealFSProvider(hostPath);\n\treturn {\n\t\tcreateVm: async (vmOptions: VMOptions): Promise<ManagedVmInstance> =>\n\t\t\t(await VM.create(vmOptions)) as unknown as ManagedVmInstance,\n\t\tcreateHttpHooks: (hookOptions) =>\n\t\t\tcreateHttpHooks({\n\t\t\t\tallowedHosts: [...hookOptions.allowedHosts],\n\t\t\t\tsecrets: Object.fromEntries(\n\t\t\t\t\tObject.entries(hookOptions.secrets).map(([secretName, secretSpec]) => [\n\t\t\t\t\t\tsecretName,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thosts: [...secretSpec.hosts],\n\t\t\t\t\t\t\tvalue: secretSpec.value,\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t\t...(hookOptions.onRequest ? { onRequest: hookOptions.onRequest } : {}),\n\t\t\t\t...(hookOptions.onResponse ? { onResponse: hookOptions.onResponse } : {}),\n\t\t\t}),\n\t\tclosePinnedRealFsRoot,\n\t\tcreatePinnedRealFsProvider: (root: PinnedRealFsRoot): VirtualProvider =>\n\t\t\tcreatePinnedRealFsProvider({\n\t\t\t\tcreateRealFsProvider: createDefaultRealFsProvider,\n\t\t\t\troot,\n\t\t\t}),\n\t\tcreateRealFsProvider: createDefaultRealFsProvider,\n\t\tcreateReadonlyProvider: (provider: VirtualProvider): VirtualProvider =>\n\t\t\tnew ReadonlyProvider(provider),\n\t\tcreateMemoryProvider: (): VirtualProvider => new MemoryProvider(),\n\t\tcreateShadowProvider: (\n\t\t\tprovider: VirtualProvider,\n\t\t\tshadowOptions: ShadowProviderOptions,\n\t\t): VirtualProvider => new ShadowProvider(provider, shadowOptions),\n\t\tcreateShadowPathPredicate: (paths: readonly string[]): ShadowPredicate =>\n\t\t\tcreateShadowPathPredicate([...paths]),\n\t};\n}\n/* oxlint-enable typescript-eslint/no-unsafe-type-assertion */\n\nfunction normalizeShadowPath(pathValue: string): string {\n\tconst trimmedPath = pathValue.trim();\n\tif (trimmedPath.startsWith('/')) {\n\t\treturn trimmedPath;\n\t}\n\n\tconst relativePath = trimmedPath.startsWith('./') ? trimmedPath.slice('./'.length) : trimmedPath;\n\treturn `/${relativePath}`;\n}\n\nfunction createRealFsProviderForSpec(\n\tmountSpec: VfsMountSpec,\n\tdependencies: ManagedVmDependencies,\n\tmountKind: string,\n): VirtualProvider {\n\tif (mountSpec.pinnedHostRoot) {\n\t\treturn dependencies.createPinnedRealFsProvider(mountSpec.pinnedHostRoot);\n\t}\n\tif (mountSpec.hostPath) {\n\t\treturn dependencies.createRealFsProvider(mountSpec.hostPath);\n\t}\n\n\tthrow new Error(`${mountKind} mounts require hostPath or pinnedHostRoot`);\n}\n\nfunction createProviderFromSpec(\n\tmountSpec: VfsMountSpec,\n\tdependencies: ManagedVmDependencies,\n): VirtualProvider {\n\tswitch (mountSpec.kind) {\n\t\tcase 'memory':\n\t\t\treturn dependencies.createMemoryProvider();\n\t\tcase 'realfs': {\n\t\t\treturn createRealFsProviderForSpec(mountSpec, dependencies, 'realfs');\n\t\t}\n\t\tcase 'realfs-readonly': {\n\t\t\treturn dependencies.createReadonlyProvider(\n\t\t\t\tcreateRealFsProviderForSpec(mountSpec, dependencies, 'realfs-readonly'),\n\t\t\t);\n\t\t}\n\t\tcase 'shadow': {\n\t\t\tconst baseProvider =\n\t\t\t\tmountSpec.hostPath || mountSpec.pinnedHostRoot\n\t\t\t\t\t? createRealFsProviderForSpec(mountSpec, dependencies, 'shadow')\n\t\t\t\t\t: dependencies.createMemoryProvider();\n\n\t\t\tlet shadowProvider = baseProvider;\n\t\t\tconst shadowConfig = mountSpec.shadowConfig;\n\n\t\t\tif (shadowConfig?.deny.length) {\n\t\t\t\tshadowProvider = dependencies.createShadowProvider(shadowProvider, {\n\t\t\t\t\tshouldShadow: dependencies.createShadowPathPredicate(\n\t\t\t\t\t\tshadowConfig.deny.map((shadowPath) => normalizeShadowPath(shadowPath)),\n\t\t\t\t\t),\n\t\t\t\t\twriteMode: 'deny',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (shadowConfig?.tmpfs.length) {\n\t\t\t\tshadowProvider = dependencies.createShadowProvider(shadowProvider, {\n\t\t\t\t\tshouldShadow: dependencies.createShadowPathPredicate(\n\t\t\t\t\t\tshadowConfig.tmpfs.map((shadowPath) => normalizeShadowPath(shadowPath)),\n\t\t\t\t\t),\n\t\t\t\t\twriteMode: 'tmpfs',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn shadowProvider;\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(`Unsupported VFS mount kind: ${String(mountSpec.kind)}`);\n\t\t}\n\t}\n}\n\nfunction createVfsMounts(\n\tvfsMounts: Record<string, VfsMountSpec>,\n\tdependencies: ManagedVmDependencies,\n): Record<string, VirtualProvider> {\n\tconst mountMap: Record<string, VirtualProvider> = {};\n\n\tfor (const [guestPath, mountSpec] of Object.entries(vfsMounts)) {\n\t\tmountMap[guestPath] = createProviderFromSpec(mountSpec, dependencies);\n\t}\n\n\treturn mountMap;\n}\n\nfunction collectPinnedRealFsRoots(\n\tvfsMounts: Record<string, VfsMountSpec>,\n): readonly PinnedRealFsRoot[] {\n\tconst roots = new Map<number, PinnedRealFsRoot>();\n\tfor (const mountSpec of Object.values(vfsMounts)) {\n\t\tif (mountSpec.pinnedHostRoot) {\n\t\t\troots.set(mountSpec.pinnedHostRoot.fd, mountSpec.pinnedHostRoot);\n\t\t}\n\t}\n\treturn [...roots.values()];\n}\n\nfunction closePinnedRealFsRoots(\n\troots: readonly PinnedRealFsRoot[],\n\tdependencies: ManagedVmDependencies,\n): void {\n\tfor (const root of roots) {\n\t\tdependencies.closePinnedRealFsRoot(root);\n\t}\n}\n\nfunction closePinnedRealFsRootsAfterFailure(\n\troots: readonly PinnedRealFsRoot[],\n\tdependencies: ManagedVmDependencies,\n): void {\n\ttry {\n\t\tclosePinnedRealFsRoots(roots, dependencies);\n\t} catch {\n\t\t// Preserve the VM creation failure; leaked-fd risk is lower than hiding\n\t\t// the root cause of a failed lease.\n\t}\n}\n\nexport async function createManagedVm(\n\toptions: CreateVmOptions,\n\tdependencies: ManagedVmDependencies = createDefaultDependencies(),\n): Promise<ManagedVm> {\n\tconst hasTcpHosts = options.tcpHosts && Object.keys(options.tcpHosts).length > 0;\n\tconst pinnedRealFsRoots = collectPinnedRealFsRoots(options.vfsMounts);\n\tlet vmInstance: ManagedVmInstance;\n\ttry {\n\t\tconst hookBundle = dependencies.createHttpHooks({\n\t\t\tallowedHosts: options.allowedHosts,\n\t\t\tsecrets: options.secrets,\n\t\t\t...(options.onRequest ? { onRequest: options.onRequest } : {}),\n\t\t\t...(options.onResponse ? { onResponse: options.onResponse } : {}),\n\t\t});\n\t\tvmInstance = await dependencies.createVm({\n\t\t\t...(options.imagePath.length > 0 ? { sandbox: { imagePath: options.imagePath } } : {}),\n\t\t\t...(options.sessionLabel ? { sessionLabel: options.sessionLabel } : {}),\n\t\t\trootfs: {\n\t\t\t\tmode: options.rootfsMode,\n\t\t\t},\n\t\t\tmemory: options.memory,\n\t\t\tcpus: options.cpus,\n\t\t\tenv: {\n\t\t\t\t...hookBundle.env,\n\t\t\t\t...options.env,\n\t\t\t},\n\t\t\thttpHooks: hookBundle.httpHooks,\n\t\t\tvfs: {\n\t\t\t\tfuseMount: '/data',\n\t\t\t\tmounts: createVfsMounts(options.vfsMounts, dependencies),\n\t\t\t},\n\t\t\t...(hasTcpHosts\n\t\t\t\t? {\n\t\t\t\t\t\tdns: {\n\t\t\t\t\t\t\tmode: 'synthetic',\n\t\t\t\t\t\t\tsyntheticHostMapping: 'per-host',\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttcp: {\n\t\t\t\t\t\t\thosts: options.tcpHosts,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t});\n\t} catch (error) {\n\t\tclosePinnedRealFsRootsAfterFailure(pinnedRealFsRoots, dependencies);\n\t\tthrow error;\n\t}\n\n\treturn {\n\t\tid: vmInstance.id,\n\t\tasync exec(command: string): Promise<ExecResult> {\n\t\t\tconst executionResult = await vmInstance.exec(command);\n\t\t\treturn {\n\t\t\t\texitCode: executionResult.exitCode,\n\t\t\t\tstdout: executionResult.stdout ?? '',\n\t\t\t\tstderr: executionResult.stderr ?? '',\n\t\t\t};\n\t\t},\n\t\tasync enableSsh(sshOptions?: EnableSshOptions): Promise<SshAccess> {\n\t\t\treturn await vmInstance.enableSsh(sshOptions);\n\t\t},\n\t\tasync enableIngress(ingressOptions?: EnableIngressOptions): Promise<IngressAccess> {\n\t\t\treturn await vmInstance.enableIngress(ingressOptions);\n\t\t},\n\t\tgetVmInstance(): ManagedVmInstance {\n\t\t\treturn vmInstance;\n\t\t},\n\t\tsetIngressRoutes(routes: readonly IngressRoute[]): void {\n\t\t\tvmInstance.setIngressRoutes(routes);\n\t\t},\n\t\tasync close(): Promise<void> {\n\t\t\tlet closeError: unknown;\n\t\t\ttry {\n\t\t\t\tawait vmInstance.close();\n\t\t\t} catch (error) {\n\t\t\t\tcloseError = error;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tclosePinnedRealFsRoots(pinnedRealFsRoots, dependencies);\n\t\t\t} catch (error) {\n\t\t\t\tcloseError ??= error;\n\t\t\t}\n\t\t\tif (closeError !== undefined) {\n\t\t\t\tthrow closeError;\n\t\t\t}\n\t\t},\n\t};\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface VolumeConfigEntry {\n\treadonly guestPath: string;\n}\n\nexport interface ResolvedVolume {\n\treadonly hostDir: string;\n\treadonly guestPath: string;\n}\n\nexport async function ensureVolumeDir(\n\tcacheBase: string,\n\tworkspaceHash: string,\n\tvolumeName: string,\n): Promise<string> {\n\tconst volumeDirectory = path.join(cacheBase, workspaceHash, volumeName);\n\tawait fs.mkdir(volumeDirectory, { recursive: true });\n\treturn volumeDirectory;\n}\n\nexport async function resolveVolumeDirs(\n\tcacheBase: string,\n\tworkspaceHash: string,\n\tvolumes: Readonly<Record<string, VolumeConfigEntry>>,\n): Promise<Record<string, ResolvedVolume>> {\n\tconst resolvedVolumeEntries = await Promise.all(\n\t\tObject.entries(volumes).map(\n\t\t\tasync ([volumeName, volumeConfig]) =>\n\t\t\t\t[\n\t\t\t\t\tvolumeName,\n\t\t\t\t\t{\n\t\t\t\t\t\tguestPath: volumeConfig.guestPath,\n\t\t\t\t\t\thostDir: await ensureVolumeDir(cacheBase, workspaceHash, volumeName),\n\t\t\t\t\t},\n\t\t\t\t] satisfies readonly [string, ResolvedVolume],\n\t\t),\n\t);\n\n\treturn Object.fromEntries(resolvedVolumeEntries);\n}\n","import fs from 'node:fs/promises';\n\nexport async function writeFileAtomically(\n\tfilePath: string,\n\tcontent: string,\n\toptions: {\n\t\treadonly mode?: number;\n\t} = {},\n): Promise<void> {\n\tconst temporaryFilePath = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n\tawait fs.writeFile(temporaryFilePath, content, {\n\t\tencoding: 'utf8',\n\t\t...(options.mode ? { mode: options.mode } : {}),\n\t});\n\ttry {\n\t\tawait fs.rename(temporaryFilePath, filePath);\n\t} catch (renameError) {\n\t\ttry {\n\t\t\tawait fs.rm(temporaryFilePath, { force: true });\n\t\t} catch (cleanupError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to replace '${filePath}' (${renameError instanceof Error ? renameError.message : JSON.stringify(renameError)}) and failed to remove temporary file '${temporaryFilePath}': ${cleanupError instanceof Error ? cleanupError.message : JSON.stringify(cleanupError)}`,\n\t\t\t\t{ cause: cleanupError },\n\t\t\t);\n\t\t}\n\t\tthrow renameError;\n\t}\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-vm/gondolin-adapter",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.33",
|
|
4
4
|
"description": "Adapter over @earendil-works/gondolin: VM build pipeline, image cache, and secret resolver.",
|
|
5
5
|
"homepage": "https://github.com/ShravanSunder/agent-vm#readme",
|
|
6
6
|
"bugs": {
|