Skip to content

docs: README still offers @webjsdev/ui to non-WebJs projects, via a 404 command #1264

Description

@vivek7405

All line anchors in this issue were re-verified against HEAD 5ac991ce on 2026-08-06. If a file has moved under you, re-anchor by the quoted text, which is exact.

Problem

The root README.md still advertises @webjsdev/ui to projects outside WebJs, which #1235 retired, and it does so with a command that cannot work from the audience it names.

README.md L60 is the **WebJs UI is the matching AI-first component library.** bullet. Its final sentence reads, verbatim:

It is auto-installed with @webjsdev/cli, and projects outside WebJs can use npx webjsui add button card dialog.

That one clause carries two independent defects.

1. It contradicts the scoping decision. #1235 landed as b0bc2742, feat!: scope @webjsdev/ui to WebJs apps, drop project detection. It deleted detectProject() and defaultsForProject(), replaced the per-framework defaults with fixed constants, and recorded the scope as invariant 7 in packages/ui/AGENTS.md L403: "The kit targets WebJs apps, and only WebJs apps (#1129) ... Do NOT reintroduce a detectProject() in any form." The same commit rewrote packages/ui/README.md, whose install section now reads "Option A : through @webjsdev/cli (the normal path)" and "Option B : the standalone binary", where Option B is framed at L76 as "a WebJs app that skipped the global install", not as a path for another framework. The root README kept the pre-#1235 framing, so the project's most-read surface still makes an offer the package deliberately withdrew.

2. The command 404s from the audience the sentence names. npx webjsui ... resolves the PACKAGE name webjsui. No such package is published. Verified on 2026-08-06:

https://registry.npmjs.org/webjsui   -> 404
https://registry.npmjs.org/webjsdev  -> 200
https://registry.npmjs.org/@webjsdev/ui -> 200

The binary exists only inside @webjsdev/ui, which declares "bin": { "webjsui": "bin/webjsui.js" } in packages/ui/package.json L6-L8. So npx webjsui resolves only when @webjsdev/ui is already a local dependency and npx finds node_modules/.bin/webjsui. That is precisely the case the sentence excludes, since it addresses a project that has installed nothing. packages/ui/README.md gets this right by putting npm install -D @webjsdev/ui and npm install @webjsdev/core (L81-L82) ahead of its two npx webjsui lines (L83-L84).

The same unrunnable-command defect is repeated in the CLI's own printed hints. Eight command strings across five files in packages/ui/src tell the user to run npx webjsui <cmd> or a bare webjsui <cmd>. Neither resolves for the most common caller. A user who reached the command through webjs ui add has @webjsdev/ui resolved from the CLI's own install, not linked into the project, and packages/cli/lib/create.js L457-L462 states outright that "@webjsdev/ui is intentionally NOT pinned" by the scaffold. The package already wrote down the correct form and the reason, in the pointerLine() JSDoc at packages/ui/src/registry/example.js L81-L86, which uses the explicit npx @webjsdev/ui view form. The printed hints never adopted it.

Found during the #1100 review cycle. The packages/ui/README.md half was fixed by #1235. The root README and the printed hints were missed.

Corrections to the previous statement of this issue

The earlier draft of this body is superseded on three points, each corrected here.

  • It settled on npx webjsdev ui add button card dialog as the README replacement. This body reverses that, for the reason given under Design.
  • It scoped the printed-hint fix to init.js and add.js only. The sweep below found the same defect in diff.js, info.js, and fetcher.js. All eight strings move together.
  • It cited packages/ui/src/registry/example.js as authority without noting that the JSDoc's stated MECHANISM is wrong. That comment says npx "would resolve to an unrelated webjsui package". There is no webjsui package at all, so npx fails to resolve rather than resolving to something unrelated. The conclusion is right and the reason is not, and this PR corrects it because it cites it.

Design / approach

Settled framing. The README's replacement sentence mirrors packages/ui/README.md's post-#1235 install section, both halves of it. Option A is that a WebJs app with @webjsdev/cli installed has nothing to add, because the kit is a hard dependency of the CLI (packages/cli/package.json L22 declares "@webjsdev/ui": "^0.3.1"). Option B is that a WebJs app which skipped the global install runs the two npm installs first, then npx webjsui. Nothing in the sentence names another framework.

What settled it: packages/ui/README.md is the source of truth that #1235 corrected, and the root README's job is to agree with it rather than to invent a third dialect. Putting the install commands ahead of the npx webjsui line is also what fixes defect 2 at its root, since the bin resolves once the package is a local dependency. This is standard practice for a package README pair, where the umbrella README summarises and the package README defines.

Rejected, with reasons:

  • npx webjsdev ui add button card dialog as the README fallback. It resolves (the webjsdev wrapper is published and depends on @webjsdev/cli), it is one command instead of three, and it is the form .agents/skills/webjs/references/ui-kit.md and the scaffold templates already teach. The honest tradeoff is that it is shorter. It loses because the README would then teach a form the package's own README does not mention, which is how the drift in this issue started. The agent skill and the scaffold speak to an agent inside a project, where brevity in a generated hint matters. The README speaks to a reader who will click through to packages/ui/README.md next, and those two pages disagreeing is the defect being fixed.
  • Keep npx webjsui with no install line in front of it. That leaves defect 2 unfixed.
  • Cut the clause entirely and link to packages/ui/README.md. It throws away a useful answer for the reader who does not have the global CLI, and the bullet already links to webjs.dev/ui.
  • Reframe as "other frameworks are untested but it renders anywhere". That re-advertises what feat!: scope @webjsdev/ui to WebJs apps, drop project detection #1235 dropped, and it reads as hedged maturity copy.
  • Rewrite packages/ui/README.md L83-L84 instead. Those two lines sit directly under the two npm installs, so the bin is linked by the time they run. feat!: scope @webjsdev/ui to WebJs apps, drop project detection #1235 wrote them deliberately and they are correct.

Settled form for the printed CLI hints: the explicit npx @webjsdev/ui <cmd> form. What settled it: the package already documented this exact rule and its rationale in pointerLine(), and @webjsdev/ui is published, so the command resolves with zero prior install no matter how the user reached the CLI. Using webjs ui <cmd> instead was rejected because a user running the standalone binary may have no @webjsdev/cli at all. Using the bare webjsui name was rejected because that is the defect.

Guard question, settled: no guard on the prose, one unit test on the printed hints.

  • No test asserting the README wording. A grep-based guard over README.md pins marketing copy to a string literal, so any later rewording reds CI for a non-defect and trains the next author to edit the guard rather than think. Industry practice for one-off prose drift is a review catch, not a regression test, and the drift here was a genuine one-off (the package README half was already corrected in the same release cycle). The acceptance criteria below carry the greps as a manual check instead.
  • Yes, unit tests on the CLI hints. Those are not prose. They are strings a program prints, with a functional contract (the printed command must resolve for the caller who sees it), which is exactly the kind of thing a test should hold. They are also cheap, because the capture-and-assert harness already exists in the package. Independently, .claude/hooks/require-tests-with-src.sh requires a test alongside any packages/*/src change, so the tests are not optional here in any case.

Implementation plan

Each step names the file, the line anchor at HEAD 5ac991ce, the text as it exists today, and the exact replacement.

Step 1. Rewrite the final sentence of the README UI bullet

File: README.md, L60. Change only the final sentence. The rest of the bullet is correct and stays byte-identical.

Remove:

It is auto-installed with `@webjsdev/cli`, and projects outside WebJs can use `npx webjsui add button card dialog`.

Replace with:

It ships as a hard dependency of `@webjsdev/cli`, so a WebJs app that installed the CLI needs no separate install, and a WebJs app that skipped the global install runs `npm install -D @webjsdev/ui` and `npm install @webjsdev/core` first, then `npx webjsui add button card dialog`.

The resulting L60 in full, so the implementer can diff against it:

- **WebJs UI is the matching AI-first component library.** Its 32 primitives at [webjs.dev/ui](https://webjs.dev/ui) are written for AI agents, in two tiers: pure class-helper functions (`buttonClass`, `cardClass`, `inputClass`) for visual primitives, plus a small set of stateful custom elements (`<ui-dialog>`, `<ui-tabs>`, `<ui-popover>`) for the cases where state matters. Running `webjs ui add button card dialog` copies the source into your project, so you own it and can edit it. It ships as a hard dependency of `@webjsdev/cli`, so a WebJs app that installed the CLI needs no separate install, and a WebJs app that skipped the global install runs `npm install -D @webjsdev/ui` and `npm install @webjsdev/core` first, then `npx webjsui add button card dialog`.

Step 2. Fix the printed hint in init

File: packages/ui/src/commands/init.js, L165. Today:

    logger.info(`Add components with:  ${logger.cyan('npx webjsui add button card dialog')}`);

Replace with:

    logger.info(`Add components with:  ${logger.cyan('npx @webjsdev/ui add button card dialog')}`);

Step 3. Fix the two printed hints in add

File: packages/ui/src/commands/add.js, L28 and L34. Today:

      logger.info(`Run ${logger.cyan('npx webjsui init')} first.`);
      logger.info(`Try ${logger.cyan('npx webjsui add button')} or ${logger.cyan('npx webjsui list')}.`);

Replace with:

      logger.info(`Run ${logger.cyan('npx @webjsdev/ui init')} first.`);
      logger.info(`Try ${logger.cyan('npx @webjsdev/ui add button')} or ${logger.cyan('npx @webjsdev/ui list')}.`);

Step 4. Fix the two printed hints in diff

File: packages/ui/src/commands/diff.js, L18 and L55. Today:

      logger.error('No components.json. Run `webjsui init` first.');
    else logger.info(`\n${changed} file${changed === 1 ? '' : 's'} differ. Re-add with ${logger.cyan('webjsui add <name> -o')} to overwrite.`);

Replace with:

      logger.error('No components.json. Run `npx @webjsdev/ui init` first.');
    else logger.info(`\n${changed} file${changed === 1 ? '' : 's'} differ. Re-add with ${logger.cyan('npx @webjsdev/ui add <name> -o')} to overwrite.`);

Step 5. Fix the printed hint in info

File: packages/ui/src/commands/info.js, L18. Today:

    logger.info(`${logger.bold('Config')}       ${config ? 'components.json ✔' : 'components.json ✖ (run `webjsui init`)'}`);

Replace with:

    logger.info(`${logger.bold('Config')}       ${config ? 'components.json ✔' : 'components.json ✖ (run `npx @webjsdev/ui init`)'}`);

Keep the / glyphs exactly as they are.

Step 6. Fix the unknown-item error message in the fetcher

File: packages/ui/src/registry/fetcher.js, L58. Today:

        `Unknown registry item "${name}". Run \`webjsui list\` to see the available components.`,

Replace with:

        `Unknown registry item "${name}". Run \`npx @webjsdev/ui list\` to see the available components.`,

Step 7. Correct the stale mechanism in the pointerLine() JSDoc

File: packages/ui/src/registry/example.js, L81-L86. This PR cites this comment as the authority for steps 2 to 6, and its stated mechanism is wrong, so it is corrected in the same pass. Today:

/**
 * The one-line pointer left in place of a stripped example. Uses the EXPLICIT
 * `npx @webjsdev/ui view` form (not the bare `webjsui` bin name, which npx would
 * resolve to an unrelated `webjsui` package when it is not a direct dep, e.g. in
 * a scaffolded app where `@webjsdev/ui` is only transitive). Works in a WebJs
 * app and a standalone project alike.
 */

Replace with:

/**
 * The one-line pointer left in place of a stripped example. Uses the EXPLICIT
 * `npx @webjsdev/ui view` form, not the bare `webjsui` bin name. `webjsui` is a
 * bin declared INSIDE `@webjsdev/ui` and is not a published package name (the
 * registry 404s on it), so `npx webjsui` resolves only where the kit is already
 * a direct dep. It is not one in a scaffolded app, where `@webjsdev/ui` is
 * intentionally unpinned (packages/cli/lib/create.js). The explicit form works
 * in a WebJs app and a standalone project alike, and every user-facing hint
 * printed by this package's commands uses it for the same reason (#1264).
 */

The pointerLine() return value at L88 is already the explicit form and does not change.

Step 8. Fix the command-form mismatch on the website UI page

File: website/app/ui/page.ts, L124. The page's own Install block at L97-L98 teaches webjs ui init / webjs ui add, then ten lines later the prose switches dialect. Today:

        <code>webjsui view &lt;name&gt;</code> and by the read-only MCP <code>ui</code> tool, rather

Replace with:

        <code>webjs ui view &lt;name&gt;</code> and by the read-only MCP <code>ui</code> tool, rather

webjs ui view is correct here and npx @webjsdev/ui view is not, because this paragraph sits inside a page whose Install block has already established a WebJs app with the CLI. Keep the &lt; / &gt; entities.

Step 9. Add the two unit tests

Specified under Tests below.

Full sweep

Every path was found with git grep -n over the whole repository for webjsui, outside WebJs, non-WebJs, and @webjsdev/ui, plus a targeted pass over README.md, AGENTS.md, .agents/, website/, docs/, packages/ui/, packages/cli/templates/, and blog/.

Must move (9 files, 12 strings):

File and line Today Verdict
README.md L60 It is auto-installed with @webjsdev/cli, and projects outside WebJs can use npx webjsui add button card dialog. Both defects. Step 1. It is the only surviving "outside WebJs" offer in the repository.
packages/ui/src/commands/init.js L165 npx webjsui add button card dialog Unrunnable hint. Step 2.
packages/ui/src/commands/add.js L28 npx webjsui init Unrunnable hint. Step 3.
packages/ui/src/commands/add.js L34 npx webjsui add button, npx webjsui list Unrunnable hints. Step 3.
packages/ui/src/commands/diff.js L18 Run `webjsui init` first. Unrunnable hint. Step 4.
packages/ui/src/commands/diff.js L55 webjsui add <name> -o Unrunnable hint. Step 4.
packages/ui/src/commands/info.js L18 (run `webjsui init`) Unrunnable hint. Step 5.
packages/ui/src/registry/fetcher.js L58 Run `webjsui list` Unrunnable hint in a thrown error. Step 6.
packages/ui/src/registry/example.js L81-L86 JSDoc claiming npx resolves an "unrelated webjsui package" Wrong mechanism in the rationale this PR cites. Step 7.
website/app/ui/page.ts L124 webjsui view <name> Dialect mismatch with the same page's Install block. Step 8.

Correct as written, do NOT touch:

File and line Why it stays
packages/ui/README.md L74-L90 The post-#1235 "Option B : the standalone binary" section. L81-L82 install both packages, so L83-L84's npx webjsui init / npx webjsui add button card dialog resolve. This is the source of truth step 1 aligns with.
packages/ui/README.md L40, L108, L113, L116-L126 Bin-name references and the command table inside the package's own README, where webjsui IS the binary. Not copy-and-run hints for a caller who may lack it.
packages/ui/AGENTS.md L3, L84, L282-L292, L330, L340, L452, L552 The internal command table and module map. Bin-name references in agent docs.
packages/ui/AGENTS.md L403-L415 Invariant 7. Its "it will render in a non-WebJs host, but that is not a supported, tested, or advertised path" is the scoping STATEMENT, the opposite of an offer. It is what the README must agree with.
packages/ui/package.json L5 description, L28-L35 keywords The npm registry blurb. Already WebJs-scoped ("The AI-first component library for WebJs ..."), corrected by #1235. Keywords are shadcn, ui, web-components, tailwind, components, webjs, with no cross-framework claim.
packages/ui/src/index.js L19 .name('webjsui'), the commander program name. It IS the bin name.
packages/ui/src/registry/local.js L5, L19, L87 and extract.js L5, L128 and fetcher.js L47 JSDoc naming the CLI leaf, not printed to a user.
packages/cli/bin/webjs.js L527-L542 Bin resolution for the webjs ui proxy. Real identifiers.
packages/cli/test/resolve-bin/resolve-bin.test.mjs L34-L50 Asserts the bin resolves. Real identifiers.
packages/cli/lib/create.js L170, L1135, L1601-L1611 The L1601 comment already explains why the scaffold prints npx webjsdev ui ... rather than npx webjs ui .... Correct and unrelated.
packages/cli/README.md L54-L65 Teaches webjs ui init / webjs ui add and says the kit is a hard dependency of the CLI. No cross-framework claim, no bare webjsui invocation.
packages/mcp/README.md L41, packages/mcp/AGENTS.md L51, packages/mcp/src/mcp.js L383, packages/mcp/test/mcp.test.mjs L354 Name webjsui view as the CLI leaf the MCP ui tool mirrors. Internal reference, not an invocation.
.agents/skills/webjs/references/ui-kit.md L5-L7, L35, L39, L43, L53, L56, L72 Already npx webjsdev ui <cmd>, which resolves. Agent-facing, inside a project.
.agents/skills/webjs/references/styling.md L76, L94 Already npx webjsdev ui add.
.agents/skills/webjs/SKILL.md L47 Routing row only.
packages/cli/templates/partials/agents-playbook-fullstack.md L16, L49, L53, L126-L127 Already npx webjsdev ui <cmd>.
packages/cli/templates/scripts/clear-gallery.mjs L23, L32, L64, L143, L147, L187 Already npx webjsdev ui add <name> or webjs ui add.
packages/cli/templates/gallery/components/ui/*.ts Header comments referencing webjs ui add <name> inside a scaffolded WebJs app.
website/app/ui/page.ts L89-L98 The Install block. Already "In a WebJs app there is nothing to install", consistent with #1235.
website/app/docs/ai-first/page.ts L52, website/app/docs/configuration/page.ts L74, website/app/docs/layout.ts L90 Mention the kit with no host-project claim.
website/AGENTS.md L45, L60, L126, website/.gitignore L2, website/public/input.css L4, website/modules/ui/utils/tier.ts L2, website/app/ui/registry/route.ts L8 Internal notes about the mirrored registry.
blog/why-webjs.md L42, L104 and blog/accessible-web-components-by-default.md L19-L23, L91 Use webjs ui add button card dialog inside an explicitly WebJs context. Correct, and blog posts are dated artefacts.
blog/light-dom-by-default.md L92, blog/light-dom-slots-with-full-parity.md L39, L135, blog/signals-replaced-setstate.md L102 Name the kit with no install or host claim.
changelog/ui/0.3.9.md L11 A frozen historical entry. Changelogs are never rewritten.
packages/ui/packages/registry/themes/index.css L2, packages/ui/packages/website/AGENTS.md L26, packages/ui/packages/website/middleware.ts L22 Bin-name references in generated CSS and the nested gallery's notes.
packages/ui/test/*.test.js tmpdir prefixes (webjsui-add-, webjsui-init-, and so on) Directory-name prefixes, not commands.
package-lock.json L7088 The generated bin map. Never hand-edited.
docs/ No hit at all. It is the redirect-only host.

Tests

New, in packages/ui/test/init-command.test.js. Add a case at the end of the file that runs a full successful init while capturing console.log, then asserts the printed hint. logger.info is a thin console.log wrapper (packages/ui/src/utils/logger.js L4), so a single reassignment captures it. The file already carries the stubFetch() and tmp() helpers and the reassign-then-restore-in-finally pattern (see L176-L194).

test('init: the success hint prints a command that resolves without a prior install (#1264)', async () => {
  stubFetch();
  const d = tmp();
  const origLog = console.log;
  const out = [];
  console.log = (...args) => out.push(args.join(' '));
  try {
    await init.parseAsync(['--yes', '--cwd', d, '--registry', 'http://test/r'], { from: 'user' });
  } finally {
    console.log = origLog;
    globalThis.fetch = origFetch;
    rmSync(d, { recursive: true });
  }
  const text = out.join('\n');
  assert.match(text, /npx @webjsdev\/ui add/);
  assert.doesNotMatch(text, /npx webjsui/, 'the bare bin name does not resolve for a `webjs ui` caller');
});

New, in packages/ui/test/add-command.test.js. Add two cases covering the two early-return hint paths. Both call process.exit(1), so reuse the existing stub-and-throw pattern from L136-L156 rather than inventing one.

test('add: the missing-config hint prints a resolvable command (#1264)', async () => {
  stubFetch();
  const d = mkdtempSync(join(tmpdir(), 'webjsui-add-hint-'));
  const origExit = process.exit;
  const origError = console.error;
  const origLog = console.log;
  const out = [];
  process.exit = ((c) => { throw new Error('exit:' + c); });
  console.error = (...args) => out.push(args.join(' '));
  console.log = (...args) => out.push(args.join(' '));
  try {
    await assert.rejects(
      () => add.parseAsync(['button', '--cwd', d, '--registry', 'http://test/r'], { from: 'user' }),
      /exit:1/,
    );
  } finally {
    process.exit = origExit;
    console.error = origError;
    console.log = origLog;
    globalThis.fetch = origFetch;
    rmSync(d, { recursive: true });
  }
  const text = out.join('\n');
  assert.match(text, /npx @webjsdev\/ui init/);
  assert.doesNotMatch(text, /npx webjsui/);
});

test('add: the no-components hint prints resolvable commands (#1264)', async () => {
  stubFetch();
  const d = tmp();
  const origExit = process.exit;
  const origError = console.error;
  const origLog = console.log;
  const out = [];
  process.exit = ((c) => { throw new Error('exit:' + c); });
  console.error = (...args) => out.push(args.join(' '));
  console.log = (...args) => out.push(args.join(' '));
  try {
    await assert.rejects(
      () => add.parseAsync(['--cwd', d, '--registry', 'http://test/r'], { from: 'user' }),
      /exit:1/,
    );
  } finally {
    process.exit = origExit;
    console.error = origError;
    console.log = origLog;
    globalThis.fetch = origFetch;
    rmSync(d, { recursive: true });
  }
  const text = out.join('\n');
  assert.match(text, /npx @webjsdev\/ui add button/);
  assert.match(text, /npx @webjsdev\/ui list/);
  assert.doesNotMatch(text, /npx webjsui/);
});

No ANSI stripping is needed. logger.cyan wraps the whole command string, so kleur's escape codes sit outside npx @webjsdev/ui add rather than inside it, and the assertions below match either way.

diff.js, info.js, and fetcher.js are covered by the existing suites (diff-command.test.js, list-view-info.test.js, fetcher.test.js). Extend an existing case in each with the same stripped-text assertion rather than adding a third harness, if the case already captures output. Where it does not, the two cases above plus the manual greps in the acceptance criteria are sufficient, because those three strings are literals with no branching around them.

Counterfactual, required before the PR is ready. Restore npx webjsui add button card dialog at init.js L165 alone and confirm the new init-command.test.js case reds. Restore add.js L28 alone and confirm the missing-config case reds. Record both in the PR body.

Run: npm test --workspace=@webjsdev/ui.

Layers that are N/A, with reasons:

  • Browser: nothing renders. The only source edits are strings printed to a terminal.
  • E2E: no HTTP surface changes.
  • Smoke: no scaffold output changes. webjs create does not emit any of the edited strings, and the scaffold's own npx webjsdev ui ... hints in create.js L1601-L1611 are unchanged.
  • Bun parity: nothing runtime-sensitive. No serializer, listener, dispatch, stream, crypto, TS-stripper, auth, or CORS path is touched. If .claude/hooks/require-bun-parity-with-runtime-src.sh fires on the packages/ui/src staging, the change still carries no cross-runtime behaviour to prove, so record that in the PR body rather than writing a hollow test/bun/* file.

Docs

This is primarily a doc change, and the doc gate (.claude/hooks/require-docs-with-src.sh) is satisfied by steps 1 and 8 riding in the same commit as steps 2 to 7. Do not reach for WEBJS_NO_DOC_GATE=1.

Surfaces that must be in sync when this lands:

  • README.md L60. Edited in step 1. The npm-visible root README and the highest-traffic surface.
  • packages/ui/README.md L61-L92. Unchanged, and it is the surface step 1 is being aligned TO. Re-read it before writing step 1 and confirm the two agree.
  • packages/ui/AGENTS.md invariant 7 (L403-L415). Unchanged. It is the recorded scope decision the README must not contradict.
  • website/app/ui/page.ts L124. Edited in step 8. The public UI kit page.
  • packages/ui/src/registry/example.js L81-L86. Edited in step 7. It is the in-code rule the other seven strings now follow.
  • .agents/skills/webjs/references/ui-kit.md. Verified already correct (npx webjsdev ui <cmd>). No edit. The two forms coexist deliberately: the skill addresses an agent inside a project, the ui package's own hints address whoever ran the binary.
  • packages/cli/templates/**. Verified already correct. No scaffold output changes, so no webjs create regeneration is needed.
  • packages/cli/README.md. Verified already correct. No edit.
  • AGENTS.md (root) L516. Lists webjs ui init | add | list | view in the CLI reference. Correct, no edit.
  • Changelog. Do not hand-write one. The PR title feeds backfill-changelog.js, so title the PR docs: stop offering @webjsdev/ui to non-WebJs projects via a 404 command (or another docs: subject under 72 characters). Put Closes #1264 in the PR body.
  • No version bump. @webjsdev/ui is published and this touches its src, so it accrues release debt, but the release PR is separate and is opened only on the owner's go-ahead.

Acceptance criteria

  • README.md L60 no longer offers @webjsdev/ui to projects outside WebJs, and names WebJs as the host in both halves of the replacement sentence
  • The replacement sentence puts npm install -D @webjsdev/ui and npm install @webjsdev/core ahead of npx webjsui add button card dialog, matching packages/ui/README.md L81-L84
  • git grep -n 'outside WebJs' -- '*.md' 'website/**' returns nothing
  • git grep -n 'npx webjsui' -- packages/ui/src/ website/ README.md returns nothing
  • git grep -n 'webjsui' -- packages/ui/src/commands/ packages/ui/src/registry/fetcher.js returns nothing in a user-printed string
  • packages/ui/README.md L74-L92 is byte-identical to HEAD 5ac991ce
  • website/app/ui/page.ts L124 reads webjs ui view &lt;name&gt;
  • packages/ui/src/registry/example.js no longer claims npx resolves an "unrelated webjsui package", and pointerLine()'s return value is unchanged
  • npm test --workspace=@webjsdev/ui passes, including the three new cases
  • Each new case reds when its own source line alone is reverted, and both counterfactuals are recorded in the PR body
  • webjs check is clean, and webjs doctor is clean on website (a website/ file is edited, and the required conventions CI job runs doctor over it, gating on that app's webjs.doctor.gate error entries)
  • No AGENTS.md invariant 11 violation in any new prose. No em-dash, no space-surrounded hyphen or semicolon as a pause, no colon attached to a code-shaped left-hand side, WebJs capitalized wherever it names the project, lowercase webjs only as a code token
  • The PR body records the decision to widen into packages/ui/src, with the reason that the scaffold does not pin @webjsdev/ui (packages/cli/lib/create.js L457-L462), so a webjs ui-reached caller cannot run a bare webjsui

Out of scope

The implementer must not widen into any of these.

  • Publishing a webjsui package to claim the name. The name resolving to nothing is not what this issue fixes, and squatting an npm name is a separate decision with its own security surface.
  • Renaming the webjsui bin, or adding a second bin to @webjsdev/ui. The bin name is correct. Only the places that TELL a user to type it are wrong.
  • Re-litigating feat!: scope @webjsdev/ui to WebJs apps, drop project detection #1235. The kit is scoped to WebJs apps. Do not add back a detectProject(), a per-framework default, or hedged "it might work elsewhere" copy anywhere.
  • Rewriting packages/ui/README.md. It is the target of the alignment, not a subject of it.
  • Changing the npx webjsdev ui <cmd> form used by the agent skill and the scaffold templates. Those resolve and are addressed to a different reader. Two forms coexisting is the settled outcome, not drift.
  • A repo-wide command-form linter. Rejected under the guard question above.
  • A version bump or a release PR for @webjsdev/ui. Release debt is reported to the owner, never opened unprompted.
  • Editing changelog/ui/0.3.9.md or any other changelog entry.
  • Filing follow-up issues. Anything this PR turns up goes in the PR body or a message to the owner. A small tweak in a file this PR already touches is folded in.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Type

No type

Projects

Status
Ready

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions