Skip to content

fix(desktop): keep node:crypto out of the renderer's protocol barrel import graph - #4720

Closed
bytelazy wants to merge 1 commit into
apache:mainfrom
bytelazy:fix/renderer-node-crypto-protocol-barrel
Closed

fix(desktop): keep node:crypto out of the renderer's protocol barrel import graph#4720
bytelazy wants to merge 1 commit into
apache:mainfrom
bytelazy:fix/renderer-node-crypto-protocol-barrel

Conversation

@bytelazy

Copy link
Copy Markdown

Summary

The Desktop renderer stays on the index.html preload skeleton forever when launched with vite dev. The renderer startup graph imports a value (MESSAGE_QUEUE_MAX_ENTRIES) from @maka/runtime-host/protocol, whose barrel export * re-exports client-capability.js. That module imported node:crypto for clientCapabilityEntityId. Vite dev does no tree-shaking, so evaluating the barrel evaluates client-capability.js in the browser, where the top-level node:crypto destructure throws and kills the renderer import graph before React mounts — with no terminal error.

The fix moves clientCapabilityEntityId (and its node:crypto import) out of protocol/client-capability.ts into a Node-only module packages/runtime-host/src/capability-entity-id.ts, re-exported as @maka/runtime-host/capability-entity-id (the same standalone-subpath shape as profile-kind). The three call sites (two Desktop main-process, one CLI) import it from there. The protocol barrel and every module it re-exports are now free of node: builtins, so the renderer can keep importing browser-safe values without evaluating node:crypto.

clientCapabilityEntityId had no unit test before; one is added so the moved behavior is pinned.

Verification of the root cause against the current tree:

  • packages/runtime-host/src/protocol/client-capability.ts:20 imported node:crypto, the only Node builtin in the barrel's export * closure.
  • A grep of every export * from './*.js' target in packages/runtime-host/src/protocol/index.ts confirms no other node: builtin remains.
  • The renderer imports MESSAGE_QUEUE_MAX_ENTRIES (value) from the barrel in session-workspace-actions.ts:38, which is what triggers module evaluation.

Fixes#4706

Verification

  • New unit test for clientCapabilityEntityId (5 cases): wire-safe passthrough, space/punctuation normalization, over-length truncation, digest distinction, explicit max length — all pass with node --test --experimental-strip-types (Node v24.20.0).
  • clientCapabilityEntityId references now point only at the new module and the three call sites; no call site still imports it from @maka/runtime-host/protocol.
  • client-capability.ts has no remaining node:crypto / createHash reference.
  • tsconfig.json (include: ['src'], rootDir: src, outDir: dist) compiles src/capability-entity-id.ts to dist/capability-entity-id.js, matching the added exports["./capability-entity-id"] — same pattern as the existing profile-kind subpath.

Not run: the full Desktop dev launch (npm run dev) and the runtime-host test:dist/typecheck, because a full workspace npm ci does not complete from this network. The change is a pure relocation with no logic change and a pinned unit test; a maintainer with the workspace installed can confirm npm run dev renders past the skeleton, and npm --workspace @maka/runtime-host run typecheck.

AI use

  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code — traced the import chain to the node:crypto source, relocated clientCapabilityEntityId, updated the call sites and exports, and wrote the unit test. The commit carries a Generated-by: Claude (Claude Code) trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

(The runtime-host typecheck/test suites are not runnable from this environment as noted under Verification; the new unit test passes locally via type-stripping.)

Does this PR entail a change in behavior?

  • Yes — the renderer can once again mount under vite dev, which it could not before.

…import graph
The renderer startup graph pulls a value import from @maka/runtime-host/protocol
(MESSAGE_QUEUE_MAX_ENTRIES in session-workspace-actions.ts). The barrel
re-exports client-capability.js, which imported node:crypto for
clientCapabilityEntityId. Vite dev does no tree-shaking, so evaluating the
barrel evaluates client-capability.js in the browser, and the top-level
node:crypto destructure throws — the renderer stays on the preload skeleton
forever with no terminal error.
Move clientCapabilityEntityId into its own Node-only module
(packages/runtime-host/src/capability-entity-id.ts) with the node:crypto
import, and re-export it as @maka/runtime-host/capability-entity-id (the same
shape as profile-kind). Point the three call sites (two desktop main, one cli)
at it. The protocol barrel and every module it export-* now has no node:
builtin, so the renderer can import browser-safe values from it without
evaluating node:crypto.
Add a unit test for clientCapabilityEntityId, which had none before, so the
moved behavior is pinned.
Fixesapache#4706
Generated-by: Claude (Claude Code)
@github-actionsgithub-actionsBot added the effort/M Under 500 readable lines label Sep 4, 2026
@bytelazy

Copy link
Copy Markdown
Author

Closing — #4705 landed the same fix (merged 2026-09-04 02:38 UTC) while this PR was still in the review queue. Same root cause, same approach (move clientCapabilityEntityId into a Node-only Runtime Host export), and #4705 is more complete: it also adds a protocol-compatible-changes entry and a vite-workspace-packages regression test that mine lacks. No reason to keep this open. Sorry for the duplicate — I should have checked recently-merged PRs, not just open ones, before opening this.

@bytelazybytelazy closed this Sep 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/MUnder 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(desktop): npm run dev stuck on preload skeleton — protocol barrel pulls node:crypto into the renderer

1 participant

@bytelazy