create-pracht 0.4.1 → 0.4.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/README.md CHANGED
@@ -17,7 +17,7 @@ npm run dev
17
17
  - Detects the active package manager from the current environment.
18
18
  - Lets the user choose between the Node.js, Cloudflare, and Vercel adapters.
19
19
  - Optionally wires up Tailwind CSS (`tailwindcss` + `@tailwindcss/vite`, a global stylesheet, and the shell import).
20
- - Scaffolds a minimal app with a route manifest or pages router, shell, home route, sample API route, runnable project README, and agent instructions.
20
+ - Scaffolds a minimal app with a route manifest or pages router, shell, home route, sample API route, runnable project README, TypeScript typecheck script, and agent instructions.
21
21
  - Manifest scaffolds include a commented-out `constraints` example in `src/routes.ts`, ready for `pracht verify`.
22
22
  - The generated `.gitignore` keeps `.pracht/app-graph.json` committable, and the README and agent instructions cover the `pracht verify` / `pracht plan` / `pracht report` loop.
23
23
  - Seeds the pracht Claude Code skills into `.claude/skills/` and writes a `.mcp.json` registering the `pracht mcp` server (yes-default prompt; skipped with `--no-agent-tools`).
@@ -80,6 +80,7 @@ Cloudflare scaffolds also include:
80
80
 
81
81
  - `dev` -> `pracht dev`
82
82
  - `build` -> `pracht build`
83
+ - `typecheck` -> `tsc --noEmit`
83
84
 
84
85
  Node starters also include:
85
86
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-pracht",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Interactive and scriptable starter CLI for creating full-stack Preact apps with Pracht.",
5
5
  "keywords": [
6
6
  "pracht",
@@ -91,9 +91,11 @@ target. From `pracht inspect api --json`:
91
91
  serves ALL methods but reports `methods: []` — treat
92
92
  `hasDefaultHandler: true` as "every method exposed". On older CLIs where
93
93
  the field is missing, grep the handler file for `export default` instead.
94
- - For each mutation handler (named method export or default handler), check
95
- whether `defineApp({ api: { middleware } })` applies a Gate, OR the handler
96
- reads/validates a session itself.
94
+ - For each mutation handler (named method export or default handler) and each
95
+ HTTP-exposed capability, check whether
96
+ `defineApp({ api: { middleware } })` applies a Gate, OR the handler/capability
97
+ reads and validates a session itself. App-level API middleware wraps generated
98
+ capability endpoints before capability-specific middleware.
97
99
  - Common bug: dashboard route is protected by middleware, but
98
100
  `POST /api/items` is not — attacker bypasses the UI entirely.
99
101
 
@@ -128,7 +128,8 @@ The canonical shape is in `recipes-auth.md` (the `origin-check.ts` example).
128
128
 
129
129
  Verify the wiring: the middleware name must appear in
130
130
  `defineApp({ api: { middleware: [...] } })` — that single global list applies
131
- to every API route. There is no per-group API middleware, and
131
+ to every API route and generated capability HTTP endpoint. There is no
132
+ per-group API middleware, and
132
133
  `pracht inspect api --json` output has no middleware field, so the manifest is
133
134
  the only place to check.
134
135
 
@@ -115,6 +115,12 @@ Check for accidental exposure outside loaders:
115
115
  intentionally public, so flag client-side `VITE_*` references unless they are
116
116
  explicitly allowlisted and reviewed. Warn loudly if a public env name has a
117
117
  secret-shaped name.
118
+ - Flag any client-side read of `import.meta.env` that is not a single-key
119
+ access — a bare reference, destructuring, a spread, or bracket access such as
120
+ `const env = import.meta.env` or `import.meta.env["MODE"]`. Vite replaces
121
+ those with an object literal holding **every** exposed variable, so the
122
+ `VITE_*` values land in the bundle with no accessor text left for a
123
+ name-based grep to find. Use `publicEnv` to enumerate public values.
118
124
  - Confirm server-side env access uses `serverEnv` (from
119
125
  `@pracht/core/env/server`) or `context.env` rather than ad-hoc globals.
120
126
 
@@ -77,8 +77,9 @@ a markdown summary (graph diff + verify + budgets) worth attaching to it.
77
77
  deployment environment. List them for the user.
78
78
  - If the app mounts `createImageHandler()` from `@pracht/image/node`, confirm
79
79
  `sharp` is installed and `localOrigin` is the same trusted public origin as
80
- `nodeAdapter({ canonicalOrigin })`. A production-relative image endpoint
81
- without both values is an error.
80
+ `nodeAdapter({ canonicalOrigin })`. A relative image endpoint without both
81
+ values is an error in every environment; loopback-looking request origins
82
+ are intentionally not trusted.
82
83
  - Reverse-proxy / TLS termination configured (out of scope for this skill —
83
84
  flag for confirmation).
84
85
 
package/src/index.js CHANGED
@@ -21,6 +21,7 @@ const FALLBACK_VERSION_RANGES = {
21
21
  "@pracht/vite-plugin": "^0.3.2",
22
22
  "@tailwindcss/vite": "^4.1.0",
23
23
  tailwindcss: "^4.1.0",
24
+ typescript: "^6.0.0",
24
25
  vercel: "^56.5.0",
25
26
  };
26
27
 
@@ -567,6 +568,7 @@ async function buildProjectFiles({
567
568
  "@pracht/vite-plugin",
568
569
  "@pracht/core",
569
570
  adapter.packageName,
571
+ "typescript",
570
572
  ];
571
573
  if (adapter.id === "vercel") {
572
574
  packagesToResolve.push("vercel");
@@ -664,6 +666,7 @@ function createPackageJson({ adapter, projectName, tailwind, versions }) {
664
666
  const scripts = {
665
667
  build: "pracht build",
666
668
  dev: "pracht dev",
669
+ typecheck: "tsc --noEmit",
667
670
  };
668
671
 
669
672
  if (adapter.id === "node") {
@@ -676,6 +679,7 @@ function createPackageJson({ adapter, projectName, tailwind, versions }) {
676
679
  "@pracht/vite-plugin": versions["@pracht/vite-plugin"],
677
680
  preact: "^10.26.9",
678
681
  "preact-render-to-string": "^6.5.13",
682
+ typescript: versions["typescript"],
679
683
  vite: "^8.0.0",
680
684
  };
681
685
 
@@ -1116,6 +1120,8 @@ function createReadme({ adapter, agentTools, packageManager, projectName, router
1116
1120
  const previewCommand = packageManager === "npm" ? "npm run preview" : `${packageManager} preview`;
1117
1121
  const startCommand = packageManager === "npm" ? "npm run start" : `${packageManager} start`;
1118
1122
  const deployCommand = packageManager === "npm" ? "npm run deploy" : `${packageManager} deploy`;
1123
+ const typecheckCommand =
1124
+ packageManager === "npm" ? "npm run typecheck" : `${packageManager} typecheck`;
1119
1125
 
1120
1126
  const lines = [
1121
1127
  `# ${projectName}`,
@@ -1126,6 +1132,7 @@ function createReadme({ adapter, agentTools, packageManager, projectName, router
1126
1132
  "",
1127
1133
  `- \`${installCommand}\``,
1128
1134
  `- \`${devCommand}\``,
1135
+ `- \`${typecheckCommand}\``,
1129
1136
  ];
1130
1137
 
1131
1138
  if (adapter.id === "node") {