Skip to content

dogfood: webjs ui subcommand fails to resolve @webjsdev/ui bin (exports gate) #1073

Description

@vivek7405

Problem

webjs ui <subcmd> (and npx webjsdev ui add <name>) fails to launch even when @webjsdev/ui is installed, printing the misleading @webjsdev/ui could not be resolved. Reinstall the CLI: npm install -g webjsdev. The real cause is a resolver gate, not a missing package:

  • The ui dispatch in packages/cli/bin/webjs.js (the case 'ui': block, ~L499-520) resolves the bin by SUBPATH: req.resolve('@webjsdev/ui/bin/webjsui.js') (both the CLI-rooted and the cwd-fallback attempt).
  • @webjsdev/ui's package.json exports map lists only ., ./registry/schema, ./registry/extract, ./utils. With an exports field present, Node BLOCKS every unlisted subpath, so require.resolve('@webjsdev/ui/bin/webjsui.js') throws ERR_PACKAGE_PATH_NOT_EXPORTED even though packages/ui/bin/webjsui.js physically exists (verified).
  • Both attempts therefore throw, and the catch prints the misleading reinstall message. Running the bin file directly works, which is why it looks like a phantom resolution failure.

Found dogfooding: an agent building a real app could not run npx webjsdev ui add tabs, assumed the kit was unavailable, and hand-rolled the UI (tabs/buttons/inputs) instead, which then needed manual fixes (e.g. cursor-pointer) the official components would have carried. So this bug is a direct cause of agents hand-writing UI instead of using the kit (compounding #1070).

Design / approach

The CLI already has the exact fix for an exports-blocked bin: lib/resolve-bin.js resolveBin(cwd, pkgName, binName) (#570), which resolves the package's . export (always exported), walks to the package root, and reads the bin map. webjs db and webjs test --browser already use it; the ui dispatch was simply missed and still uses the raw subpath resolve. Switch the ui dispatch to resolveBin, keeping the CLI-root-first (hard-dep) then cwd-fallback order, and spawn with process.execPath (matching the sibling db/test paths, so it works under Bun / a Node-less image) instead of the literal 'node'.

Alternative considered and rejected: add "./bin/webjsui.js" to @webjsdev/ui's exports. That would also fix it, but it is a second package's change and leaves the CLI resolving bins two different ways; using the existing resolveBin is the single, consistent, version-robust fix (works regardless of the ui package's exports).

Implementation notes (for the implementing agent)

  • Where to edit: packages/cli/bin/webjs.js, the case 'ui': block (~L499-523). Replace both req.resolve('@webjsdev/ui/bin/webjsui.js') attempts with resolveBin(join(__dirname, '..'), '@webjsdev/ui', 'webjsui') (hard-dep, the CLI's own node_modules) then a resolveBin(process.cwd(), '@webjsdev/ui', 'webjsui') fallback (user installed it directly). Keep the same clear error + exit on total failure. resolveBin, __dirname, join, dirname, fileURLToPath are ALREADY imported at the top of the file, so no new imports. Drop the now-unused local createRequire in that block. Change spawn('node', ...) to spawn(process.execPath, ...).
  • Landmines: resolveBin(cwd, ...) roots resolution at join(cwd, 'package.json'), so pass the CLI package ROOT (join(__dirname, '..'), which is packages/cli) for the hard-dep path, NOT __dirname (the bin/ dir). In the monorepo @webjsdev/ui's . export is ./src/index.js; in a published install it may differ, but resolveBin walks to the package root either way, so it is layout-robust. Do NOT re-add a catch-all subpath resolve.
  • Invariants: CLI package invariant 1 (exactly the templates/flags surface, unchanged here); this is a resolution fix, no new command. Respect the prose-punctuation invariant (release: bump core/server/cli versions, honest engines fields #11) in any new comment.
  • Tests: extend packages/cli/test/resolve-bin/resolve-bin.test.mjs with a case asserting resolveBin(<cli root or repo root>, '@webjsdev/ui', 'webjsui') returns the real bin/webjsui.js path (and existsSync), PLUS a counterfactual that createRequire(...).resolve('@webjsdev/ui/bin/webjsui.js') THROWS ERR_PACKAGE_PATH_NOT_EXPORTED (proving the exports gate the fix bypasses). Optionally a test/cli/* spawn-level assertion that webjs ui list exits 0.
  • Verify: run webjs ui list (or node packages/cli/bin/webjs.js ui list) and confirm it launches the kit instead of the reinstall error.
  • Docs: none required (bugfix, no surface change). Mention in the cli changelog via the PR title (fix:).

Acceptance criteria

  • webjs ui list / npx webjsdev ui add <name> launches the kit when @webjsdev/ui is installed, no false "could not be resolved" error
  • The ui dispatch resolves via resolveBin, consistent with db / test --browser, and spawns with process.execPath
  • Test asserts resolveBin resolves the webjsui bin despite the exports gate, with a counterfactual that the raw subpath resolve throws ERR_PACKAGE_PATH_NOT_EXPORTED
  • The genuine not-installed case still prints the clear error and exits non-zero

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions