create-pracht 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/add-auth/SKILL.md +63 -143
- package/skills/add-capabilities/SKILL.md +409 -0
- package/skills/add-content/SKILL.md +242 -0
- package/skills/add-db/SKILL.md +93 -202
- package/skills/add-i18n/SKILL.md +178 -217
- package/skills/add-images/SKILL.md +203 -0
- package/skills/add-observability/SKILL.md +118 -15
- package/skills/add-openapi/SKILL.md +209 -0
- package/skills/audit-a11y/SKILL.md +8 -9
- package/skills/audit-agent-surface/SKILL.md +335 -0
- package/skills/audit-auth/SKILL.md +16 -11
- package/skills/audit-bundles/SKILL.md +56 -12
- package/skills/audit-csrf/SKILL.md +9 -10
- package/skills/audit-deps/SKILL.md +8 -8
- package/skills/audit-headers/SKILL.md +9 -10
- package/skills/audit-islands/SKILL.md +9 -10
- package/skills/audit-loaders/SKILL.md +23 -8
- package/skills/audit-redirects/SKILL.md +9 -10
- package/skills/audit-secrets/SKILL.md +6 -6
- package/skills/audit-seo/SKILL.md +8 -8
- package/skills/audit-shells/SKILL.md +8 -9
- package/skills/configure-isg/SKILL.md +9 -10
- package/skills/migrate-nextjs/SKILL.md +200 -415
- package/skills/pracht-debug/SKILL.md +165 -120
- package/skills/pracht-deploy/SKILL.md +248 -329
- package/skills/pracht-scaffold/SKILL.md +123 -146
- package/skills/pracht-test-api/SKILL.md +10 -10
- package/skills/pre-deploy/SKILL.md +166 -195
- package/skills/scaffold-e2e/SKILL.md +11 -12
- package/skills/scaffold-tests/SKILL.md +10 -12
- package/skills/tune-render-mode/SKILL.md +7 -8
- package/skills/typed-routes/SKILL.md +15 -11
- package/skills/upgrade-pracht/SKILL.md +12 -10
- package/src/index.js +43 -0
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pracht-debug
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.4.0
|
|
4
4
|
description: |
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Proactively suggest when the user reports errors or unexpected behavior
|
|
11
|
-
in a pracht application.
|
|
5
|
+
Framework-aware debugging for pracht: route matching, loader and API errors,
|
|
6
|
+
rendering and hydration, middleware, HMR, and build failures — root cause first.
|
|
7
|
+
Use for "debug this", "fix this bug", "why is this broken", "blank page",
|
|
8
|
+
"hydration mismatch", "404 on my route"; suggest it when the user reports
|
|
9
|
+
unexpected pracht behavior.
|
|
12
10
|
allowed-tools:
|
|
13
11
|
- Bash
|
|
14
12
|
- Read
|
|
@@ -21,126 +19,173 @@ allowed-tools:
|
|
|
21
19
|
|
|
22
20
|
# Pracht Debug
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
**Iron law: no fixes without root-cause investigation first.** Read the
|
|
23
|
+
relevant source before diagnosing, start from the most likely cause for the
|
|
24
|
+
symptom rather than a full audit, and when you find the root cause explain
|
|
25
|
+
*why* it breaks. After fixing, prove the fix — run the test, check the dev
|
|
26
|
+
server. Never say "this should fix it."
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
## Instruments
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
When another agent/tool needs the framework's resolved graph, prefer `pracht inspect routes --json`, `pracht inspect api --json`, or `pracht inspect build --json` over reconstructing it from source files. Prerequisites: `pracht inspect` needs the pracht plugin registered in the project's vite config, and `pracht inspect build` needs a prior `pracht build`.
|
|
30
|
-
If the pracht MCP server is registered (docs/MCP.md), prefer the `inspect_routes`/`inspect_api`/`doctor`/`verify` MCP tools over shelling out — same payloads, structured results.
|
|
31
|
-
While the dev server is running, `GET /_pracht` serves a devtools page with the same resolved route/API graph (raw JSON at `/_pracht.json`) — useful when you have a browser or `curl` handy but no CLI access. Under a Vite deploy base, prefix both paths with that base; links from the devtools and dev-404 pages already do so. Dev SSR responses also carry a `Server-Timing` header (`mw`, `loader`, `render` durations in ms) — check it in the browser Network panel or with `curl -sI` to see which phase makes a route slow.
|
|
30
|
+
Reach for these before deep manual inspection:
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
| Tool | Use |
|
|
33
|
+
| ---- | --- |
|
|
34
|
+
| `pracht verify` (`--changed` to scope to git-changed files) | Fast confidence check |
|
|
35
|
+
| `pracht doctor` | Broader broken wiring or missing files |
|
|
36
|
+
| `pracht inspect routes\|api\|build --json` | The resolved graph — never reconstruct it from source |
|
|
37
|
+
| `GET /_pracht` (JSON at `/_pracht.json`) | Same graph from a running dev server, no CLI needed |
|
|
38
|
+
| `Server-Timing` on dev SSR responses | `mw` / `loader` / `render` durations in ms — which phase is slow |
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
`pracht inspect` needs the pracht plugin in the vite config; `inspect build`
|
|
41
|
+
needs a prior `pracht build`. Under a Vite deploy base, prefix `/_pracht` with
|
|
42
|
+
that base (links from the devtools and dev-404 pages already do). When the
|
|
43
|
+
pracht MCP server is registered (docs/MCP.md), prefer the
|
|
44
|
+
`inspect_routes`/`inspect_api`/`doctor`/`verify` MCP tools — same payloads,
|
|
45
|
+
structured results.
|
|
36
46
|
|
|
37
|
-
##
|
|
47
|
+
## Checklist
|
|
38
48
|
|
|
39
|
-
Work
|
|
49
|
+
Work in order; stop at the root cause.
|
|
40
50
|
|
|
41
51
|
### 1. Route matching
|
|
42
52
|
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
53
|
+
- `pracht inspect routes --json` (or `curl http://localhost:5173/_pracht.json`)
|
|
54
|
+
for the resolved wiring; `pracht doctor` if a route may be missing, miswired,
|
|
55
|
+
or pointing at a missing module.
|
|
56
|
+
- Is the route in `src/routes.ts` with the right path? The manifest uses
|
|
57
|
+
relative paths like `"./routes/home.tsx"` — check for typos.
|
|
58
|
+
- Dynamic segments: `route("/users/:id", ...)` in the manifest, `[id].ts` in
|
|
59
|
+
filenames.
|
|
60
|
+
- If needed, grep the route path across the manifest and check
|
|
61
|
+
`matchAppRoute()`.
|
|
62
|
+
|
|
63
|
+
### 2. Typed routes and links
|
|
64
|
+
|
|
65
|
+
- A `<Link route="...">`, `href("...")`, or route-object `useNavigate()` that
|
|
66
|
+
fails to typecheck usually means stale generated files: `pracht typegen
|
|
67
|
+
--check`.
|
|
68
|
+
- Confirm the route id exists in `pracht inspect routes --json`. Fallback ids
|
|
69
|
+
get renamed by path changes.
|
|
70
|
+
- `src/pracht.d.ts` carries the inferred params. `:id`, `*`, and `:path*` are
|
|
71
|
+
required; extra params should fail at typecheck time.
|
|
72
|
+
- Runtime `Unknown pracht route id "..."`: dev appends `Did you mean "..."?`
|
|
73
|
+
plus the registered ids (production tree-shakes that and throws bare). Check
|
|
74
|
+
the typo first, then that `pracht typegen` ran and the component renders
|
|
75
|
+
inside the pracht route tree.
|
|
76
|
+
- For unexpected URLs, reproduce with `href(routeId, options)` and compare
|
|
77
|
+
against the route's resolved path and params.
|
|
78
|
+
|
|
79
|
+
### 3. Loader / API errors
|
|
80
|
+
|
|
81
|
+
- On slow pages, read `Server-Timing` before reading code.
|
|
82
|
+
- Loaders must return serializable data — no functions, no circular refs.
|
|
83
|
+
- API handlers must return `Response` objects, and a default export must branch
|
|
84
|
+
on `request.method`.
|
|
85
|
+
- Look for unhandled rejections or thrown errors.
|
|
86
|
+
- `LoaderArgs` destructuring must match what the framework provides:
|
|
87
|
+
`{ request, params, context, signal, url, route }`.
|
|
88
|
+
|
|
89
|
+
### 4. Rendering
|
|
90
|
+
|
|
91
|
+
- **Blank page** — check whether the route is `render: "spa"` (no SSR content
|
|
92
|
+
expected) rather than `"ssr"`.
|
|
93
|
+
- **Hydration mismatch** — dev shows a fixed red banner listing each mismatched
|
|
94
|
+
component (via Preact's `options.__m` hook). Compare server HTML against
|
|
95
|
+
client output. Usual causes: date/time differences, browser-only APIs during
|
|
96
|
+
SSR (`window`, `document`, `localStorage`), conditional rendering on client
|
|
97
|
+
state — or two copies of `@pracht/core` in the SSR module graph. The tell for
|
|
98
|
+
that last one: in the server-rendered HTML of *every* page, `useLocation()`
|
|
99
|
+
returns `/`, `useParams()` returns `{}`, and `useRouteData()` returns
|
|
100
|
+
`undefined`, while the hydrated client is correct — provider and hooks hold
|
|
101
|
+
different `createContext()` objects. The plugin prevents it by keeping
|
|
102
|
+
`@pracht/*` in `ssr.noExternal`; listing a `@pracht/*` package in
|
|
103
|
+
`ssr.external` overrides that and brings the split back.
|
|
104
|
+
- **Missing shell** — an unregistered shell name throws at manifest resolution
|
|
105
|
+
(`Unknown shell "..." for route "...". Did you mean "..."? Registered shells:
|
|
106
|
+
...`) and appears in the dev error overlay as soon as the manifest loads.
|
|
107
|
+
Check `defineApp({ shells })` and the route/group assignment.
|
|
108
|
+
- **404** — usually step 1, but a 404 on a URL you *do* expect means the loader
|
|
109
|
+
threw `notFound()`, not that matching failed. In `pracht dev`, unmatched
|
|
110
|
+
navigations render a dev-only 404 listing every registered route and its
|
|
111
|
+
render mode (also printed at dev-server startup, also in `pracht inspect
|
|
112
|
+
routes`). Apps declaring `defineApp({ notFound })` render their own 404 page
|
|
113
|
+
in dev and production alike, so that table is not shown — read `pracht
|
|
114
|
+
inspect routes` directly.
|
|
115
|
+
|
|
116
|
+
### 5. Middleware
|
|
117
|
+
|
|
118
|
+
- It must be registered in `defineApp({ middleware })` and applied via
|
|
119
|
+
`middleware: ["name"]` on the route or group. An unregistered name (route,
|
|
120
|
+
group, or `api.middleware`) throws at manifest resolution: `Unknown
|
|
121
|
+
middleware "..." for route "...". Did you mean "..."? Registered middleware:
|
|
122
|
+
...`
|
|
123
|
+
- Middleware is wrap-around and server-side only, wrapping loaders and API
|
|
124
|
+
handlers. It must always return a `Response`, either from `await next()` or
|
|
125
|
+
by short-circuiting. Common failures:
|
|
126
|
+
|
|
127
|
+
| Bug | Error |
|
|
128
|
+
| --- | ----- |
|
|
129
|
+
| Forgetting `return next()` | `Middleware "..." did not return a Response` |
|
|
130
|
+
| Calling `next()` twice | `Middleware "..." called next() multiple times` |
|
|
131
|
+
| Mutating a non-object `context` | Silent — mutations don't propagate; always pass an object |
|
|
132
|
+
|
|
133
|
+
### 6. API routes
|
|
134
|
+
|
|
135
|
+
- They live in `src/api/`, auto-discovered, no manifest entry.
|
|
136
|
+
`pracht inspect api --json` for the inventory.
|
|
137
|
+
- Path maps to URL: `src/api/health.ts` → `/api/health`,
|
|
138
|
+
`src/api/users/[id].ts` → `/api/users/:id`.
|
|
139
|
+
- Each file exports named method handlers (`GET`, `POST`, …) or one default
|
|
140
|
+
handler that branches on `request.method`. A missing method handler is a 405
|
|
141
|
+
when there is no default.
|
|
142
|
+
|
|
143
|
+
### 7. Vite plugin and HMR
|
|
144
|
+
|
|
145
|
+
- Is `pracht()` in `vite.config.ts`? Virtual modules are
|
|
146
|
+
`virtual:pracht/client` (hydration), `virtual:pracht/server` (SSR),
|
|
147
|
+
`virtual:pracht/islands-client` (islands hydration).
|
|
148
|
+
- HMR only watches `src/routes/`, `src/shells/`, `src/middleware/`,
|
|
149
|
+
`src/api/`, `src/server/`, `src/islands/`.
|
|
150
|
+
- What each change does: editing `src/routes.ts` restarts the dev server
|
|
151
|
+
(`server.restart()`, not a browser reload). Route, shell, and island
|
|
152
|
+
components use Preact Fast Refresh; route/shell edits and client-reachable
|
|
153
|
+
loader dependencies also re-fetch active route data, with rapid saves
|
|
154
|
+
coalesced so the newest result settles last and a failed latest refresh
|
|
155
|
+
falling back to a reload. Adding or removing a route `loader` or route/shell
|
|
156
|
+
`head` export reloads so generated client hints stay current, and editing a
|
|
157
|
+
route/shell exporting document `headers()` reloads because CSP and other
|
|
158
|
+
response headers cannot be patched. Compiled formats get refresh
|
|
159
|
+
instrumentation after their companion Vite plugin runs, but Markdown, MDX,
|
|
160
|
+
and configured additional formats reload conservatively because a transform
|
|
161
|
+
may synthesize `headers()` from metadata; default `.tsrx` preserves state
|
|
162
|
+
when its source is headerless. Everything else invalidates the server module.
|
|
163
|
+
|
|
164
|
+
### 8. Build and deployment
|
|
165
|
+
|
|
166
|
+
- `pracht build` runs the client and server builds, then prerenders SSG/ISG
|
|
167
|
+
routes. On serverful adapters a failed path is warned about and skipped, but
|
|
168
|
+
the build fails if *every* attempted prerender returns non-200 — use the
|
|
169
|
+
reported underlying error to fix the shared loader/render dependency; partial
|
|
170
|
+
output stays valid. Static exports fail on any bad path.
|
|
171
|
+
- `pracht preview` builds and serves production output locally (Node runs
|
|
172
|
+
`dist/server/server.js`; Cloudflare delegates to `wrangler dev`).
|
|
173
|
+
- `pracht inspect build --json` reports the resolved adapter target plus the
|
|
174
|
+
client/CSS/JS manifests from the last build.
|
|
175
|
+
- Client assets land in `dist/client/`, the server bundle in `dist/server/`.
|
|
176
|
+
The ISG manifest is `dist/server/isg-manifest.json`; on Cloudflare the build
|
|
177
|
+
also copies it to `dist/client/_pracht/isg.json` for the worker to read via
|
|
178
|
+
the assets binding.
|
|
179
|
+
- Confirm the adapter in `pracht({ adapter: … })` matches the deployment
|
|
180
|
+
target.
|
|
181
|
+
|
|
182
|
+
## Framework internals
|
|
183
|
+
|
|
184
|
+
- `handlePrachtRequest()` dispatches: API routes → middleware → loader →
|
|
185
|
+
render → HTML assembly.
|
|
186
|
+
- Route-state JSON is returned when the `x-pracht-route-state-request` header
|
|
187
|
+
is present (client-side navigation).
|
|
188
|
+
- Hydration state is injected as `window.__PRACHT_STATE__`.
|
|
189
|
+
- `initClientRouter()` intercepts link clicks and fetches that route state.
|
|
145
190
|
|
|
146
191
|
$ARGUMENTS
|