Skip to content

Commit ccbb365

Browse files
khaliqgantRicky Schema Cascadeclaude
authored
fix(persona-kit): defer @relayfile/local-mount import to call site (#121)
`@relayfile/local-mount` imports `@parcel/watcher` at module top, which loads a per-platform native binary at evaluation time (e.g. `@parcel/watcher-linux-x64-glibc` on Lambda). Eagerly importing it from `mount.ts` meant every `import('@agentworkforce/persona-kit')` evaluated the binary load — including server-side validation paths that never call `applyPersonaMount`. Concrete blast: cloud's deploy POST does `await import("@agentworkforce/persona-kit")` to call `parsePersonaSpec` on the uploaded bundle. The Lambda runtime is linux-x64-glibc, but OpenNext's tracer doesn't bundle @parcel/watcher's optional native prebuild, so the import resolution throws: "Persona validation is unavailable: @agentworkforce/persona-kit could not be loaded ... No prebuild or local build of @parcel/watcher found. Tried @parcel/watcher-linux-x64-glibc." Fix: lazy-import `@relayfile/local-mount` inside a small helper that `applyPersonaMount` awaits at call time. Mount is a CLI/runtime concern, not a server concern, so deferring is correct semantically and lets the native binary stay un-loaded on hosts that never apply a mount. The barrel `index.ts` re-exports stay intact — back-compat for any direct consumer of `applyPersonaMount`. The change is purely the import timing inside `mount.ts`. Verified: * 170/170 persona-kit tests pass. * 544 tests across the whole workforce repo pass (`pnpm run test`). * Probe script: `import('@agentworkforce/persona-kit')` followed by `parsePersonaSpec(...)` succeeds with NO `@parcel/watcher` load on the call path. Co-authored-by: Ricky Schema Cascade <ricky@agent-relay.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 33436ba commit ccbb365

1 file changed

Lines changed: 19 additions & 1 deletion

File tree

packages/persona-kit/src/mount.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
1-
import { createMount } from '@relayfile/local-mount';
21
import type { ResolvedMountPolicy } from './plan.js';
32

3+
// `@relayfile/local-mount` pulls in `@parcel/watcher`, which loads a
4+
// per-platform native binary at module evaluation time
5+
// (`@parcel/watcher-linux-x64-glibc`, `-darwin-arm64`, …). When
6+
// persona-kit is loaded server-side just to call `parsePersonaSpec`
7+
// (e.g. cloud's `import('@agentworkforce/persona-kit')` to validate a
8+
// deploy bundle), eagerly importing local-mount fails any host that
9+
// doesn't ship a matching prebuild — most notably AWS Lambda's
10+
// `@parcel/watcher-linux-x64-glibc`, which OpenNext doesn't bundle.
11+
//
12+
// Deferring the local-mount import to `applyPersonaMount`'s call site
13+
// means the native binary only loads when a mount is actually being
14+
// applied (which is a CLI/runtime concern, never a server-side
15+
// validation concern).
16+
async function loadCreateMount(): Promise<typeof import('@relayfile/local-mount').createMount> {
17+
const mod = await import('@relayfile/local-mount');
18+
return mod.createMount;
19+
}
20+
421
export interface PersonaMountHandle {
522
/**
623
* Working directory the harness should be spawned in. When the mount is
@@ -68,6 +85,7 @@ export async function applyPersonaMount(
6885
'applyPersonaMount: options.personaId is required when a mount policy is supplied'
6986
);
7087
}
88+
const createMount = await loadCreateMount();
7189
const handle = await createMount(options.cwd, options.mountDir, {
7290
ignoredPatterns: [...mount.ignoredPatterns],
7391
readonlyPatterns: [...mount.readonlyPatterns],

0 commit comments

Comments
 (0)