Skip to content

fix(persona-kit): defer @relayfile/local-mount import to call site#121

Merged
khaliqgant merged 1 commit into
mainfrom
fix-persona-kit/defer-local-mount-import
May 13, 2026
Merged

fix(persona-kit): defer @relayfile/local-mount import to call site#121
khaliqgant merged 1 commit into
mainfrom
fix-persona-kit/defer-local-mount-import

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

Summary

mount.ts imported @relayfile/local-mount at module top, which transitively imports @parcel/watcher and triggers a per-platform native-binary load at module evaluation time. That broke every server-side consumer that just wanted to call parsePersonaSpec — most visibly the cloud deploy POST handler in AWS Lambda.

Concrete blast

User ran agentworkforce deploy --no-prompt --harness-source oauth against agentrelay.com/cloud. After all the workspace/integrations/harness checks passed, the bundle upload landed at cloud's deploy POST, which does:

mod = await import("@agentworkforce/persona-kit");

…to validate the uploaded persona. The Lambda runtime is linux-x64-glibc, but OpenNext's dep-tracer didn't bundle @parcel/watcher's optional native prebuild (@parcel/watcher-linux-x64-glibc). Result:

500 {"error":"Persona validation is unavailable: @agentworkforce/persona-kit could not be loaded",
     "code":"persona_kit_unavailable",
     "details":[{"path":"persona","message":"No prebuild or local build of @parcel/watcher found.
        Tried @parcel/watcher-linux-x64-glibc. ..."}]}

The fix

@parcel/watcher is a real dep for the CLI/runtime path (auto-sync, watch mode). It is not a dep for the server-side validation path. The right thing is to load it only when a mount is actually being applied.

mount.ts now defers the @relayfile/local-mount import via a small loadCreateMount() helper that's awaited inside applyPersonaMount. At module-evaluation time mount.ts no longer touches the watcher; at call time, mount consumers see no behavior change. The barrel re-export from index.ts stays intact — no API breakage.

Verified

  • 170/170 persona-kit tests pass.
  • Full repo pnpm run test — 544 tests across 8 packages, all pass.
  • Local probe (dynamic-import the built dist + parsePersonaSpec(...)): succeeds with no @parcel/watcher load.

Once this publishes and the user retries their proactive-agents deploy, cloud's import('@agentworkforce/persona-kit') should succeed and parsePersonaSpec should run to completion — clearing the last known blocker on the end-to-end customer flow.

Test plan

  • pnpm -F @agentworkforce/persona-kit run test — 170/170 pass
  • pnpm run typecheck — all packages clean
  • pnpm run test — 544/544 pass repo-wide
  • Probe: import('@agentworkforce/persona-kit') + parsePersonaSpec does not trigger @parcel/watcher on darwin-arm64

🤖 Generated with Claude Code

`@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: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8d57a276-2b9d-49fc-942c-537291b3241e

📥 Commits

Reviewing files that changed from the base of the PR and between 97a800b and 6c6a142.

📒 Files selected for processing (1)
  • packages/persona-kit/src/mount.ts

📝 Walkthrough

Walkthrough

packages/persona-kit/src/mount.ts replaces a static top-level import of @relayfile/local-mount with a dynamic import helper function loadCreateMount(). The applyPersonaMount function now calls this async helper at mount time to obtain createMount, deferring native binary loading from module-evaluation time to mount-application time.

Changes

Deferred import refactor

Layer / File(s) Summary
Lazy-load createMount for deferred native binary initialization
packages/persona-kit/src/mount.ts
The static top-level import of @relayfile/local-mount is replaced with an internal loadCreateMount() async helper that dynamically imports the module and returns createMount. applyPersonaMount now calls await loadCreateMount() at mount-application time instead of using a statically imported binding.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • AgentWorkforce/workforce#81: Adds mount.test.ts coverage for applyPersonaMount's mount-policy and error behaviors, directly testing the function modified in this PR.
  • AgentWorkforce/workforce#56: Bumps the @relayfile/local-mount dependency version, directly related to the module being dynamically imported in this change.

Suggested reviewers

  • willwashburn

Poem

🐇 Hops through hoops to defer the load,
Native binaries need not road,
Lazy imports light the way,
Until the mount gets called—hooray!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: deferring the @relayfile/local-mount import to the call site, which directly addresses the core fix in the changeset.
Description check ✅ Passed The description thoroughly explains the problem (native binary loading at module evaluation time breaking server-side validation), the solution (deferred import via loadCreateMount helper), and provides concrete verification details.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-persona-kit/defer-local-mount-import

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

@khaliqgant khaliqgant merged commit ccbb365 into main May 13, 2026
3 checks passed
@khaliqgant khaliqgant deleted the fix-persona-kit/defer-local-mount-import branch May 13, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant