You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Findings from a full-stack tic-tac-toe dogfood session (scaffolded with npm create webjs@latest, Drizzle/SQLite). Seven friction points. Items 1, 2, 3, and 7 are fixed in the dogfood PR; items 4, 5, 6 are tracked here as open. The related service-worker /sw.js 404 is already tracked as #830 (also fixed in the same PR).
Findings
1. Page-action redirect footgun, 307 vs 303 (a real bug, cost ~10 min). FIXED in the dogfood PR.
The agent threw redirect() in the home page action, which is a 307 that preserves the POST body, so the browser re-POSTed to the game page and Number(null) === 0 placed a phantom X. The gallery's forms/todo/file-storage demos all RETURN { success: true, redirect } (303 PRG) but never warn against THROWING redirect() from a page action. Fix: explicit comment in the forms demo and the todo example's action contrasting return { redirect } (303 PRG) with throw redirect() (307, re-POSTs and re-runs the mutation), plus defensive formData parsing (guard the Number(null)===0 trap).
2. No component browser test in the gallery (a 2-iteration loop). FIXED in the dogfood PR.
The agent wrote its board test with it() + @esm-bundle/chai, hit "mocha UI is tdd, chai isn't in the importmap", then rewrote to test() + inline assert. The correct idioms exist only in the generic test/hello/browser/hello.test.js, which the agent never opened. Fix: ship a browser test co-located with the components gallery demo (counter-card) using suite/test + ssrFixture + inline assert, plus a harder pointer in AGENTS.md's testing section.
3. Drizzle read where-clause hesitation (minor). FIXED in the dogfood PR.
The agent avoided the relational API ("relational-API uncertainty") and used the core db.select().where(eq()). Both styles already appear in the gallery (db.query.todos.findFirst({ where: { id } }) in toggle-todo). Fix: a one-line comment in the todo query naming the two equivalent read styles.
4. MCP source tool returns "no matches" for symbols that exist. OPEN.
source({ query }) returned "no matches" twice for symbols present in node_modules/@webjsdev/server/src/page-action.js and ssr.js (action, actionData). The agent fell back to grepping node_modules and lost trust in the MCP.
Where: packages/mcp/src/mcp-source.js. Symbols: walkSource(dir, deps) (bounded by MAX_FILES), the query-mode grep (MAX_GREP, ~L145+), FRAMEWORK_PACKAGES = ['core','server','cli','intellisense','ui'], resolveFrameworkRoots. Dep-injectable { roots, readFile, readdir } for testing.
Likely cause: the query grep only searches the file set from walkSource, which is silently bounded by MAX_FILES, so a file past the cap (e.g. page-action.js) is never read and the query returns empty rather than a truncation notice. A silent cap yielding "no matches" reads as authoritative absence, the worst failure mode.
Fix: right-size or remove the cap on the query path, OR surface a "results may be incomplete, N files skipped" notice, OR index by symbol. Add a packages/mcp/test/*.test.mjs fake-tree case where the target symbol lives past MAX_FILES (counterfactual: empty before the fix).
5. Drizzle rc.3 to rc.4 drift. OPEN.
The scaffold pins drizzle-orm: ^1.0.0-rc.3 but install resolved rc.4 (a caret prerelease still admits later rc.N of the same version), which drove the API uncertainty in #3. rc.4 works (verified in generated apps), so the drift is benign today, but it is nondeterministic. Decide: pin the tested rc exactly in the generated package.json (packages/cli/lib/create.js), or document the supported rc range in AGENTS.md / agent-docs/orm.md.
6. Install and command friction. OPEN (mostly environment).
npx webjs resolved to a wrong package, a mise shim shadowed the CLI, and npm create webjs@latest needed two corrections. The canonical command is already documented, but the getting-started page could state it more prominently and warn about global-shim shadowing. Where: docs/app/docs/getting-started/page.ts.
7. Browser-test Chromium prerequisite. FIXED (note) in the dogfood PR.
"Chromium binary for WTR isn't installed" cost a step. Fix: note the one-time npx playwright install chromium in the testing docs and the test/hello/browser/hello.test.js header. Plus the recurring CWD / absolute-path confusion (minor, environment).
Acceptance criteria
Items 1, 2, 3, 7 land in the dogfood PR (gallery comments, a component browser test, the drizzle read note, the chromium prereq note), verified by generate + boot + webjs check.
Item 4 (MCP): source({ query }) finds real @webjsdev/server/src symbols, or reports truncation, with a fake-tree unit test that is red before the fix.
Item 5: the generated drizzle-orm pin is deterministic (exact) or the supported rc is documented.
Item 6: getting-started names the canonical scaffold command prominently.
Problem
Findings from a full-stack tic-tac-toe dogfood session (scaffolded with
npm create webjs@latest, Drizzle/SQLite). Seven friction points. Items 1, 2, 3, and 7 are fixed in the dogfood PR; items 4, 5, 6 are tracked here as open. The related service-worker/sw.js404 is already tracked as #830 (also fixed in the same PR).Findings
1. Page-action redirect footgun, 307 vs 303 (a real bug, cost ~10 min). FIXED in the dogfood PR.
The agent threw
redirect()in the home page action, which is a 307 that preserves the POST body, so the browser re-POSTed to the game page andNumber(null) === 0placed a phantom X. The gallery's forms/todo/file-storage demos all RETURN{ success: true, redirect }(303 PRG) but never warn against THROWINGredirect()from a page action. Fix: explicit comment in the forms demo and the todo example'sactioncontrasting return{ redirect }(303 PRG) with throwredirect()(307, re-POSTs and re-runs the mutation), plus defensiveformDataparsing (guard theNumber(null)===0trap).2. No component browser test in the gallery (a 2-iteration loop). FIXED in the dogfood PR.
The agent wrote its board test with
it()+@esm-bundle/chai, hit "mocha UI istdd, chai isn't in the importmap", then rewrote totest()+ inline assert. The correct idioms exist only in the generictest/hello/browser/hello.test.js, which the agent never opened. Fix: ship a browser test co-located with the components gallery demo (counter-card) usingsuite/test+ssrFixture+ inline assert, plus a harder pointer in AGENTS.md's testing section.3. Drizzle read where-clause hesitation (minor). FIXED in the dogfood PR.
The agent avoided the relational API ("relational-API uncertainty") and used the core
db.select().where(eq()). Both styles already appear in the gallery (db.query.todos.findFirst({ where: { id } })in toggle-todo). Fix: a one-line comment in the todo query naming the two equivalent read styles.4. MCP
sourcetool returns "no matches" for symbols that exist. OPEN.source({ query })returned "no matches" twice for symbols present innode_modules/@webjsdev/server/src/page-action.jsandssr.js(action,actionData). The agent fell back to greppingnode_modulesand lost trust in the MCP.packages/mcp/src/mcp-source.js. Symbols:walkSource(dir, deps)(bounded byMAX_FILES), thequery-mode grep (MAX_GREP, ~L145+),FRAMEWORK_PACKAGES = ['core','server','cli','intellisense','ui'],resolveFrameworkRoots. Dep-injectable{ roots, readFile, readdir }for testing.walkSource, which is silently bounded byMAX_FILES, so a file past the cap (e.g.page-action.js) is never read and the query returns empty rather than a truncation notice. A silent cap yielding "no matches" reads as authoritative absence, the worst failure mode.packages/mcp/test/*.test.mjsfake-tree case where the target symbol lives pastMAX_FILES(counterfactual: empty before the fix).5. Drizzle rc.3 to rc.4 drift. OPEN.
The scaffold pins
drizzle-orm: ^1.0.0-rc.3but install resolvedrc.4(a caret prerelease still admits later rc.N of the same version), which drove the API uncertainty in #3. rc.4 works (verified in generated apps), so the drift is benign today, but it is nondeterministic. Decide: pin the tested rc exactly in the generatedpackage.json(packages/cli/lib/create.js), or document the supported rc range in AGENTS.md /agent-docs/orm.md.6. Install and command friction. OPEN (mostly environment).
npx webjsresolved to a wrong package, amiseshim shadowed the CLI, andnpm create webjs@latestneeded two corrections. The canonical command is already documented, but the getting-started page could state it more prominently and warn about global-shim shadowing. Where:docs/app/docs/getting-started/page.ts.7. Browser-test Chromium prerequisite. FIXED (note) in the dogfood PR.
"Chromium binary for WTR isn't installed" cost a step. Fix: note the one-time
npx playwright install chromiumin the testing docs and thetest/hello/browser/hello.test.jsheader. Plus the recurring CWD / absolute-path confusion (minor, environment).Acceptance criteria
webjs check.source({ query })finds real@webjsdev/server/srcsymbols, or reports truncation, with a fake-tree unit test that is red before the fix./sw.jsbug (dogfood: scaffold serves public at /public/* so the documented /sw.js service worker 404s #830) is fixed (tracked separately, same PR).