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,16 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pre-deploy
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.4.0
|
|
4
4
|
description: |
|
|
5
|
-
Adapter-aware pre-deployment checklist
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
checklist", "is my build production-safe", or before running `wrangler
|
|
13
|
-
deploy` / `vercel deploy`.
|
|
5
|
+
Adapter-aware pre-deployment checklist (Node, Cloudflare Workers, Vercel, static)
|
|
6
|
+
for the failures that only surface in production: missing env vars, Node-only
|
|
7
|
+
APIs in edge bundles, absent ISG manifest, oversized bundles, missing
|
|
8
|
+
wrangler/vercel config, and static hosts without clean URLs, 404, or security
|
|
9
|
+
headers.
|
|
10
|
+
Use for "pre-deploy check", "ready to ship?", "deployment checklist", "is my
|
|
11
|
+
build production-safe", before `wrangler deploy` or `vercel deploy`.
|
|
14
12
|
allowed-tools:
|
|
15
13
|
- Bash
|
|
16
14
|
- Read
|
|
@@ -20,233 +18,206 @@ allowed-tools:
|
|
|
20
18
|
|
|
21
19
|
# Pracht Pre-Deploy
|
|
22
20
|
|
|
23
|
-
Run
|
|
24
|
-
contract;
|
|
21
|
+
Run before every production deploy. Each adapter has a different runtime
|
|
22
|
+
contract; enforce the one that matches the build. Never deploy on the user's
|
|
23
|
+
behalf — end at the verdict.
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
If the pracht MCP server is registered (see docs/MCP.md), prefer its tools
|
|
29
|
-
(`inspect_routes`, `inspect_api`, `inspect_build`, `doctor`, `verify`) over
|
|
25
|
+
MCP: when the pracht MCP server is registered (docs/MCP.md), prefer its
|
|
26
|
+
`inspect_routes`/`inspect_api`/`inspect_build`/`doctor`/`verify` tools over
|
|
30
27
|
shelling out.
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
`vercelAdapter()`, or `staticAdapter()`. Confirm with:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
pracht inspect build --json
|
|
37
|
-
```
|
|
29
|
+
## Step 1: Build, then detect the adapter
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
needs a vite config with the pracht plugin, and `inspect build` reads
|
|
41
|
-
artifacts from a prior build — if `pracht build` has not been run recently,
|
|
42
|
-
run it first:
|
|
31
|
+
Always build first — never lint a stale `dist/`.
|
|
43
32
|
|
|
44
33
|
```bash
|
|
45
34
|
pracht build
|
|
35
|
+
pracht inspect build --json
|
|
46
36
|
```
|
|
47
37
|
|
|
48
|
-
|
|
38
|
+
`adapterTarget` is authoritative; `vite.config.ts` (`nodeAdapter()`,
|
|
39
|
+
`cloudflareAdapter()`, `vercelAdapter()`, `staticAdapter()`) is the
|
|
40
|
+
cross-check. Never assume the adapter.
|
|
41
|
+
|
|
42
|
+
## Step 2: Framework-wide checks
|
|
49
43
|
|
|
50
44
|
```bash
|
|
51
45
|
pracht doctor --json
|
|
52
46
|
pracht verify --json
|
|
47
|
+
pracht typegen --check # only if src/pracht-routes.ts or src/pracht.d.ts exists
|
|
53
48
|
```
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
`src/pracht.d.ts` exists), also run:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
pracht typegen --check
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
These catch app-graph wiring problems independent of the adapter — including
|
|
50
|
+
These catch app-graph wiring problems independent of the adapter, including
|
|
63
51
|
`defineApp({ constraints })` violations and a stale `.pracht/app-graph.json`
|
|
64
|
-
snapshot (fix
|
|
65
|
-
|
|
52
|
+
snapshot (fix that with `pracht plan --write`, then re-review the plan output).
|
|
53
|
+
Resolve every `status: "error"` before continuing — **if `pracht doctor`
|
|
54
|
+
reports errors, stop here**; the remaining checks will be noisy false
|
|
55
|
+
positives. Stale generated typed-route files block deployment; if the app does
|
|
56
|
+
not use them yet, note that `typegen --check` is optional.
|
|
66
57
|
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
For a PR deploy, `pracht report --base origin/main` produces a markdown summary
|
|
59
|
+
(graph diff + verify + budgets) worth attaching.
|
|
69
60
|
|
|
70
|
-
## Step 3: Adapter
|
|
61
|
+
## Step 3: Adapter checklist
|
|
71
62
|
|
|
72
63
|
### Node (`@pracht/adapter-node`)
|
|
73
64
|
|
|
74
|
-
- `dist/server/server.js`
|
|
75
|
-
|
|
76
|
-
- `dist/server/
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
deployment environment. List them for the user.
|
|
80
|
-
- If the app mounts `createImageHandler()` from `@pracht/image/node`,
|
|
81
|
-
|
|
82
|
-
`nodeAdapter({ canonicalOrigin })`. A relative image endpoint without both
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- Reverse
|
|
86
|
-
|
|
87
|
-
- If the proxy strips Vite's deploy base,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
65
|
+
- `dist/server/server.js`, `dist/client/.vite/manifest.json`, and — if any
|
|
66
|
+
route is `render: "isg"` — `dist/server/isg-manifest.json` all exist.
|
|
67
|
+
- `pracht preview --skip-build` (or `node dist/server/server.js`) boots and
|
|
68
|
+
`curl localhost:3000` returns 200.
|
|
69
|
+
- Every env var the app reads (grep `process.env.*` across `src/`) is set in
|
|
70
|
+
the deployment environment. List them for the user.
|
|
71
|
+
- If the app mounts `createImageHandler()` from `@pracht/image/node`, `sharp`
|
|
72
|
+
is installed and `localOrigin` is the same trusted public origin as
|
|
73
|
+
`nodeAdapter({ canonicalOrigin })`. A relative image endpoint without both is
|
|
74
|
+
an error in every environment; loopback-looking request origins are
|
|
75
|
+
intentionally not trusted.
|
|
76
|
+
- Reverse proxy / TLS termination configured — out of scope here, flag for
|
|
77
|
+
confirmation.
|
|
78
|
+
- If the proxy strips Vite's deploy base, `nodeAdapter({ basePathStripped:
|
|
79
|
+
true })` is set; application code should still observe the public base in
|
|
80
|
+
`request.url`, and the proxy must own the bare-base redirect (`/app` →
|
|
81
|
+
`/app/`).
|
|
91
82
|
|
|
92
83
|
### Cloudflare Workers (`@pracht/adapter-cloudflare`)
|
|
93
84
|
|
|
94
|
-
- `wrangler.toml
|
|
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
|
-
- ISG
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
- Bundle size: measure what actually deploys — `dist/server/worker.js` plus
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
compressed
|
|
85
|
+
- `wrangler.toml`/`wrangler.jsonc` present at repo root, `assets.directory`
|
|
86
|
+
pointing at `dist/client`, and bindings declared for every `context.env.*`
|
|
87
|
+
access in loaders, middleware, and API routes (grep, then cross-check).
|
|
88
|
+
- `main` points at `dist/server/worker.js` — the thin deploy wrapper
|
|
89
|
+
re-exporting only the default handler and Cloudflare entrypoint classes.
|
|
90
|
+
Pointing it at `dist/server/server.js` is an **error**: workerd validates
|
|
91
|
+
every named export of the deploy entry and rejects the build metadata
|
|
92
|
+
(`buildTarget`, manifests, `resolvedApp`, …) that `server.js` exports for the
|
|
93
|
+
prerender pass.
|
|
94
|
+
- `no_bundle: true` plus an `ESModule` rule whose globs include `"**/*.js"`.
|
|
95
|
+
Pracht's Vite output is already bundled and may contain lazy server chunks;
|
|
96
|
+
these settings make Wrangler upload them as separate modules instead of
|
|
97
|
+
folding them into the entry.
|
|
98
|
+
- `compatibility_date` is set and is a date the installed workerd supports. It
|
|
99
|
+
must not be *newer* than the runtime, or workerd refuses to start ("This
|
|
100
|
+
Worker requires compatibility date X, but the newest date supported by this
|
|
101
|
+
server binary is Y"). Never set it to today's date — that is by construction
|
|
102
|
+
at or beyond the newest released workerd.
|
|
103
|
+
- **No Node-only APIs in the server bundle.** Grep the server files for `fs`,
|
|
104
|
+
`path` (Node form), `process.cwd`, `Buffer`, `__dirname`, `__filename`,
|
|
105
|
+
`crypto.createHash` (use `crypto.subtle`), `child_process`, `cluster`,
|
|
106
|
+
`worker_threads`. Check `compatibility_flags` first — with `nodejs_compat`,
|
|
107
|
+
`Buffer` and several `node:` modules are legal — and only flag what the
|
|
108
|
+
active flags do not cover. Dev already runs inside workerd via
|
|
109
|
+
`@cloudflare/vite-plugin`, so this is the backstop for code paths dev never
|
|
110
|
+
hits.
|
|
111
|
+
- An API route importing `@pracht/image/node` is an error on Workers (its
|
|
112
|
+
optimizer needs `sharp`). Require `cloudflareLoader` or `passthroughLoader`.
|
|
113
|
+
- ISG works out of the box via the per-colo Workers Cache API. If
|
|
114
|
+
time-revalidated routes should use the edge-tier Workers Caching upgrade,
|
|
115
|
+
confirm *both* sides: `cloudflareAdapter({ cache: true })` and
|
|
116
|
+
`"cache": { "enabled": true }` in wrangler config. With it enabled, flag ISG
|
|
117
|
+
routes reachable through unbounded query strings — require a bounded
|
|
118
|
+
allowlist or canonical redirect, or an uncached gateway with a normalized
|
|
119
|
+
`cf.cacheKey` — and check that markdown-capable routes normalize `Accept` at
|
|
120
|
+
the gateway when variant fan-out matters.
|
|
121
|
+
- Bundle size: measure what actually deploys — `dist/server/worker.js` plus its
|
|
122
|
+
`dist/server/server.js` import and lazy chunks (`worker.js` alone is a few
|
|
123
|
+
lines; `no_bundle` uploads the pre-built module graph). The Workers limit is
|
|
124
|
+
~1 MB compressed on free, ~10 MB on paid. Warn at 80% of the active limit.
|
|
134
125
|
|
|
135
126
|
### Vercel (`@pracht/adapter-vercel`)
|
|
136
127
|
|
|
137
|
-
- `.vercel/output/config.json` exists
|
|
128
|
+
- `.vercel/output/config.json` exists with `version: 3`, and
|
|
129
|
+
`.vercel/output/static/` is populated.
|
|
138
130
|
- The render function exists at
|
|
139
131
|
`.vercel/output/functions/<functionName>.func/server.js`. The name defaults
|
|
140
|
-
to `render` but is configurable via `vercelAdapter({ functionName })` —
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Node-only API still breaks the edge function.
|
|
152
|
-
- ISG functions: every `<route>.prerender-config.json` must sit next to a
|
|
153
|
-
**Serverless** `<route>.func` (`.vc-config.json` with `launcherType:
|
|
154
|
-
"Nodejs"`). Vercel rejects a prerender config paired with an edge function:
|
|
132
|
+
to `render` but is configurable via `vercelAdapter({ functionName })` — read
|
|
133
|
+
it from `vite.config.ts` rather than hardcoding `render.func`.
|
|
134
|
+
- Env vars are configured in the Vercel project. This cannot be verified from
|
|
135
|
+
the CLI alone: run `vercel env pull` and diff against `process.env.*` uses.
|
|
136
|
+
- **Run the Cloudflare Node-only API check unconditionally.** The render
|
|
137
|
+
function's `.vc-config.json` is always written with `runtime: "edge"`. Do not
|
|
138
|
+
skip it based on a runtime probe — ISG routes run the same bundle on Node,
|
|
139
|
+
but a Node-only API still breaks the edge function.
|
|
140
|
+
- Every `<route>.prerender-config.json` sits next to a **Serverless**
|
|
141
|
+
`<route>.func` (`.vc-config.json` with `launcherType: "Nodejs"`). Vercel
|
|
142
|
+
rejects a prerender config paired with an edge function:
|
|
155
143
|
`Unexpected function type "EdgeFunction" at path "<route>"`.
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- An API route importing `@pracht/image/node` is an error for the
|
|
144
|
+
- `vercelAdapter({ regions: "all" })` is valid for the Edge render function,
|
|
145
|
+
but generated Node ISG function configs must omit `regions` so the project
|
|
146
|
+
default applies; Node configs may only contain arrays of concrete region
|
|
147
|
+
identifiers.
|
|
148
|
+
- An API route importing `@pracht/image/node` is an error for the Edge
|
|
161
149
|
function. Require `vercelLoader` (with aligned allowed sizes) or
|
|
162
|
-
`passthroughLoader
|
|
163
|
-
- Build Output API v3 sanity: `config.json` has `version: 3`.
|
|
150
|
+
`passthroughLoader`.
|
|
164
151
|
|
|
165
152
|
### Static export (`@pracht/adapter-static`)
|
|
166
153
|
|
|
167
|
-
|
|
168
|
-
|
|
154
|
+
There is no server to get wrong, so this checklist is about what the *host*
|
|
155
|
+
must do and what the build cannot enforce.
|
|
169
156
|
|
|
170
157
|
- `dist/client/` exists and is the deploy root. `dist/server/` is build tooling
|
|
171
|
-
|
|
172
|
-
- The build
|
|
173
|
-
|
|
158
|
+
and must not be uploaded — it contains the prerender bundle.
|
|
159
|
+
- The build is the gate: it fails closed on `ssr`/`isg` routes, SPA loaders,
|
|
160
|
+
non-full SPA hydration, API routes, route/not-found middleware,
|
|
174
161
|
network-exposed capabilities, and any Vite `base` that is not `/` or a
|
|
175
|
-
root-absolute path
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
-
|
|
179
|
-
|
|
180
|
-
`try_files $uri $uri/index.html
|
|
181
|
-
-
|
|
182
|
-
|
|
183
|
-
`dist/client/404.html` exists
|
|
184
|
-
page
|
|
162
|
+
root-absolute path. If `pracht build` succeeded, those contracts already hold
|
|
163
|
+
— do not re-derive them by hand. Report a failing build verbatim; the message
|
|
164
|
+
names the routes.
|
|
165
|
+
- The host serves `index.html` for directory URLs. Confirm the actual setting:
|
|
166
|
+
S3 website endpoints need an index document, nginx needs
|
|
167
|
+
`try_files $uri $uri/index.html`; GitHub Pages and Netlify do it by default.
|
|
168
|
+
- The host maps `404.html` as its error document, or unknown URLs get the
|
|
169
|
+
host's generic error page instead of the app's `notFound` route. Verify
|
|
170
|
+
`dist/client/404.html` exists — if it does not, the app declares no
|
|
171
|
+
`notFound` page: `warn`.
|
|
185
172
|
- **Security headers are not applied.** Every other adapter sets the four
|
|
186
173
|
default security headers at request time; a static host has no request
|
|
187
|
-
runtime. `dist/server/headers-manifest.json` records
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
`add_header`).
|
|
191
|
-
|
|
174
|
+
runtime. `dist/server/headers-manifest.json` records what each route *would*
|
|
175
|
+
have carried — mirror the ones you need into the host's own header config
|
|
176
|
+
(`_headers` on Netlify, CloudFront response header policies, nginx
|
|
177
|
+
`add_header`). `error` for any app handling user input, `warn` otherwise.
|
|
178
|
+
HSTS and CSP are host-side decisions either way.
|
|
192
179
|
- If `staticAdapter({ fallback })` is configured, the host needs a rewrite of
|
|
193
|
-
unmatched URLs to that file
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
-
|
|
223
|
-
user-facing responses (or that `headers()` exports cover the same ground).
|
|
224
|
-
On a static export this check moves entirely to the host's header config —
|
|
225
|
-
see the static section above.
|
|
226
|
-
- Confirm `git status` is clean (deploying uncommitted work is a footgun).
|
|
180
|
+
unmatched URLs to that file that does not shadow real files. It makes unknown
|
|
181
|
+
URLs answer `200` (soft 404s), and without it the fallback file is inert —
|
|
182
|
+
deep links into dynamic `render: "spa"` routes will 404.
|
|
183
|
+
- Smoke test the real output, not the dev server: `pracht preview --skip-build`
|
|
184
|
+
serves `dist/client/` the way a dumb host would. Check `/`, one dynamic SSG
|
|
185
|
+
path, one deep link into a SPA route, and one unknown URL.
|
|
186
|
+
- Routes exporting `markdown` rely on server-side `Accept` negotiation, which a
|
|
187
|
+
static host cannot do — agents asking for `text/markdown` get HTML. The build
|
|
188
|
+
prints a note; publish `.md` files under `public/` if a raw-markdown corpus
|
|
189
|
+
matters.
|
|
190
|
+
- Sub-path deploys (GitHub Pages *project* site, S3 key prefix) need Vite
|
|
191
|
+
`base` set to that path (`base: "/my-project/"`), matching the deploy path
|
|
192
|
+
exactly — a mismatch 404s every asset. Then confirm no hand-written
|
|
193
|
+
root-absolute internal links: `grep -rn 'href="/' src/` and check each hit is
|
|
194
|
+
external, an asset under `public/`, or a `<Link route>`. Framework-owned URLs
|
|
195
|
+
from `@pracht/image`'s `defaultLoader` and the OpenAPI companion
|
|
196
|
+
UI/document already carry the base — do not flag their base-free route
|
|
197
|
+
declarations — but custom image loaders and OpenAPI provider asset URLs still
|
|
198
|
+
need to match the intended host. CDN bases (`https://cdn…`) and
|
|
199
|
+
document-relative bases (`""` / `"./"`) are build errors, not sub-path
|
|
200
|
+
deploys.
|
|
201
|
+
|
|
202
|
+
## Step 4: Cross-cutting
|
|
203
|
+
|
|
204
|
+
- `/audit-secrets` — no `process.env.*` or `context.env.*` value flows into a
|
|
205
|
+
loader return value.
|
|
206
|
+
- `/audit-headers` — `applyDefaultSecurityHeaders` is in use on user-facing
|
|
207
|
+
responses, or `headers()` exports cover the same ground. On a static export
|
|
208
|
+
this moves entirely to the host config; see above.
|
|
209
|
+
- `git status` is clean. Deploying uncommitted work is a footgun.
|
|
227
210
|
|
|
228
211
|
## Step 5: Report
|
|
229
212
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
2. Detect the adapter — never assume.
|
|
240
|
-
3. For Cloudflare/Vercel-edge, the Node-only API check is non-negotiable; an
|
|
241
|
-
API not covered by the active compatibility flags will crash the worker on
|
|
242
|
-
a code path that may never hit in dev.
|
|
243
|
-
4. For a static export, never report `READY` without naming the host settings
|
|
244
|
-
the deploy depends on (clean URLs, `404.html`, security headers, and the
|
|
245
|
-
fallback rewrite if configured). The build cannot verify any of them, so an
|
|
246
|
-
unqualified `READY` is the one way this skill can mislead.
|
|
247
|
-
5. If the app does not use generated typed route files yet, note that `pracht typegen --check` is optional; if it does, stale generated files block deployment.
|
|
248
|
-
6. Do not deploy on the user's behalf. End the skill at the verdict.
|
|
249
|
-
7. If `pracht doctor` reports errors, do not run any other checks until those
|
|
250
|
-
are resolved — they will produce noisy false positives.
|
|
213
|
+
A checklist grouped by `Framework`, `Adapter`, `Cross-cutting`. Tag each item
|
|
214
|
+
with a primary severity — `error` (blocks deploy), `warn` (proceeds but risky),
|
|
215
|
+
`info` — keeping pass/fail as the secondary per-item status. End with one line:
|
|
216
|
+
`READY` / `BLOCKED (N errors)` / `READY WITH WARNINGS (N warnings)`.
|
|
217
|
+
|
|
218
|
+
For a static export, never report `READY` without naming the host settings the
|
|
219
|
+
deploy depends on — clean URLs, `404.html`, security headers, and the fallback
|
|
220
|
+
rewrite if configured. The build cannot verify any of them, so an unqualified
|
|
221
|
+
`READY` is the one way this skill can mislead.
|
|
251
222
|
|
|
252
223
|
$ARGUMENTS
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scaffold-e2e
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.1
|
|
4
4
|
description: |
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
or "create smoke tests for my routes".
|
|
5
|
+
Set up Playwright for a pracht app: install it, generate a
|
|
6
|
+
`playwright.config.ts` that boots `pracht dev` (or the build via `pracht
|
|
7
|
+
preview`), and emit a smoke test per manifest route asserting 200, head/title,
|
|
8
|
+
no console errors, and navigation.
|
|
9
|
+
Use for "scaffold E2E", "set up Playwright", "add browser tests", "create smoke
|
|
10
|
+
tests for my routes".
|
|
12
11
|
allowed-tools:
|
|
13
12
|
- Bash
|
|
14
13
|
- Read
|
|
@@ -82,10 +81,10 @@ If `playwright.config.ts` already exists, merge — do not clobber.
|
|
|
82
81
|
|
|
83
82
|
## Step 4: Generate per-route smoke tests
|
|
84
83
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
config
|
|
84
|
+
MCP: when the pracht MCP server is registered (docs/MCP.md), prefer its
|
|
85
|
+
`inspect_routes`/`inspect_api`/`inspect_build`/`doctor`/`verify`/`generate_*`
|
|
86
|
+
tools over shelling out. `pracht inspect` needs the pracht plugin in the vite
|
|
87
|
+
config.
|
|
89
88
|
|
|
90
89
|
```bash
|
|
91
90
|
pracht inspect routes --json
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scaffold-tests
|
|
3
|
-
version: 1.2.
|
|
3
|
+
version: 1.2.1
|
|
4
4
|
description: |
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
`vitest
|
|
8
|
-
tests
|
|
9
|
-
|
|
10
|
-
Use when asked to "scaffold tests", "set up Vitest", "add unit tests",
|
|
11
|
-
"test this loader", or "test this route".
|
|
5
|
+
Set up Vitest for pracht routes, loaders, and middleware — browser mode with
|
|
6
|
+
`vitest-browser-preact` or JSDOM with `@testing-library/preact` — wiring
|
|
7
|
+
`vitest.config.ts`, `LoaderArgs` via `@pracht/test`, and runnable test files.
|
|
8
|
+
Use for "scaffold tests", "set up Vitest", "add unit tests", "test this loader",
|
|
9
|
+
"test this route".
|
|
12
10
|
allowed-tools:
|
|
13
11
|
- Bash
|
|
14
12
|
- Read
|
|
@@ -134,10 +132,10 @@ If `vitest.config.ts` already exists, merge — never clobber.
|
|
|
134
132
|
|
|
135
133
|
## Step 4: Generate the tests
|
|
136
134
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
config
|
|
135
|
+
MCP: when the pracht MCP server is registered (docs/MCP.md), prefer its
|
|
136
|
+
`inspect_routes`/`inspect_api`/`inspect_build`/`doctor`/`verify`/`generate_*`
|
|
137
|
+
tools over shelling out. `pracht inspect` needs the pracht plugin in the vite
|
|
138
|
+
config.
|
|
141
139
|
|
|
142
140
|
This skill covers **loaders, middleware, and components**. For API handlers
|
|
143
141
|
(`src/api/**`), delegate to `/pracht-test-api` — it owns handler enumeration and
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tune-render-mode
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.1
|
|
4
4
|
description: |
|
|
5
|
-
Recommend the right
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
route be SSG", "audit render modes", or "review SSG/ISG/SSR choices".
|
|
5
|
+
Recommend the right render mode (ssg, isg, ssr, spa) per route from what each
|
|
6
|
+
loader actually does, then apply the change after confirmation.
|
|
7
|
+
Use for "tune render modes", "should this route be SSG", "audit render modes",
|
|
8
|
+
"review SSG/ISG/SSR choices", "make my site faster".
|
|
10
9
|
allowed-tools:
|
|
11
10
|
- Bash
|
|
12
11
|
- Read
|
|
@@ -61,8 +60,8 @@ For each route:
|
|
|
61
60
|
|
|
62
61
|
## Step 1: Enumerate
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
MCP: when the pracht MCP server is registered (docs/MCP.md), prefer its
|
|
64
|
+
`inspect_routes`/`inspect_api`/`inspect_build`/`doctor`/`verify` tools over
|
|
66
65
|
shelling out.
|
|
67
66
|
|
|
68
67
|
```bash
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: typed-routes
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.1
|
|
4
4
|
description: |
|
|
5
|
-
Add or maintain pracht typed routes
|
|
6
|
-
and
|
|
7
|
-
links", "replace hard-coded hrefs", "run
|
|
8
|
-
|
|
5
|
+
Add or maintain pracht typed routes: run typegen, adopt route-id based links and
|
|
6
|
+
navigation, and replace hard-coded hrefs with generated helpers.
|
|
7
|
+
Use for "add typed routes", "fix typed links", "replace hard-coded hrefs", "run
|
|
8
|
+
typegen".
|
|
9
9
|
allowed-tools:
|
|
10
10
|
- Bash
|
|
11
11
|
- Read
|
|
@@ -24,10 +24,10 @@ Use this workflow to keep route ids, params, links, and navigation type-safe.
|
|
|
24
24
|
|
|
25
25
|
The resolved app graph is the source of truth — not a manual glob of `src/`.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
config
|
|
27
|
+
MCP: when the pracht MCP server is registered (docs/MCP.md), prefer its
|
|
28
|
+
`inspect_routes`/`inspect_api`/`inspect_build`/`doctor`/`verify`/`generate_*`
|
|
29
|
+
tools over shelling out. `pracht inspect` needs the pracht plugin in the vite
|
|
30
|
+
config.
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
pracht inspect routes --json
|
|
@@ -107,8 +107,12 @@ same-origin anchor. It also accepts navigation-behavior props:
|
|
|
107
107
|
`prefetch="none" | "hover" | "intent" | "viewport" | "render"` (per-link
|
|
108
108
|
prefetch strategy, default `"intent"`), `preserveScroll` (keep the scroll
|
|
109
109
|
position), and `viewTransition` (animate the navigation with the View Transitions API
|
|
110
|
-
where supported).
|
|
111
|
-
|
|
110
|
+
where supported). Set `speculate={false}` on links that browser speculation
|
|
111
|
+
rules must not prefetch or prerender. Because it is independent of the JS
|
|
112
|
+
`prefetch` strategy, use both `speculate={false}` and `prefetch="none"` for GET
|
|
113
|
+
links with side effects. There is also an imperative
|
|
114
|
+
`prefetch()` export and a `useNavigation()` hook for pending
|
|
115
|
+
navigation/submission state.
|
|
112
116
|
|
|
113
117
|
### Outside components
|
|
114
118
|
|