@ahmed-3m/idea2prototype 0.9.1 → 1.0.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.1
4
+
5
+ Fixes for the critical + high findings of the 2026-10-20 repo review:
6
+
7
+ - Security: `add api-crud` refuses resource names another feature owns (`users`, `auth`, `jobs`, `uploads`, `events`, `sse`, `ping`, `ratelimit`, `cors`, `cors-ping`, `health`). `--resource users` used to share `data/users.json` with `auth-local` — anonymous `GET /api/users` served every salt + hash, and an anonymous POST could plant a login-capable account.
8
+ - Security: `upload` serves only passive types inline (text, csv, json, raster images); everything else — including html, svg, js — comes back as `application/octet-stream` + `content-disposition: attachment`, and every response carries `x-content-type-options: nosniff` + a sandboxing CSP. Uploaded HTML used to render on the app's own origin (stored XSS).
9
+ - Fix: `verify`/`check` boot the server even when no tests exist — a `start()` that throws used to verify PASS on syntax alone. Boot still skips after a syntax failure (structured `cause` on the tests step, no string coupling).
10
+ - Fix: `verify` accepts a foreign `start()` that returns a bare `http.Server` (port via `address()`, callback-style close) and never lets a throwing/hanging `close()` replace the verdict — it crashed with `app.close(...).catch is not a function` before printing anything.
11
+ - Fix: boot runs with the project as cwd (as the tests step already did), so `verify <dir>` from elsewhere boots the same app as `verify` from inside — scaffolds used to boot with no routes and no `public/`, foreign servers failed on cwd-relative reads.
12
+ - Fix: `api-crud` POST ignores client-sent `id`/`createdAt` (two POSTs with the same `id` created duplicates, the second unreachable); PUT keeps `createdAt` too. SKILL.md/README composition snippets follow the same body-first pattern.
13
+ - Tests: regression test per finding above (engine suite + the generated template tests that every scaffold runs). The review's seventh finding — `rateLimit()` sharing one bucket map — was fixed independently on main and shipped in 1.0.0.
14
+ - Fix: the upload route's path guard checks the separator boundary (`uploads` + `/`) — a sibling directory sharing the prefix (`uploads-x/`) used to pass the traversal check (flagged in review; served inert either way).
15
+
16
+ ## 1.0.0
17
+
18
+ First stable release. The scaffold contract — route objects, check/verify verdicts, `add`-module shapes — is frozen as-is; 1.x commits to additive changes only.
19
+
20
+ - Stress: every finding of the 2026-10-20 stress test (#49–#60) triaged and resolved. Data stores that fail to parse are quarantined (`data/<name>.json.corrupt-<ts>`, original bytes preserved) instead of silently wiped; single-writer and stateless-token semantics documented in the README; `ci.yml` runs with minimal permissions; README status line pinned by CI.
21
+ - Fix: `verify` (judge mode) discovers tests by node:test's own conventions (`*.test.{js,mjs,cjs}`, `test-*.js`, `*-test.js`/`*_test.js`, `test.js`, and everything under a `test/` dir, at any depth) — no more false PASS when failing tests live outside `tests/*.test.mjs` — and never reads or executes anything under `uploads/`, `data/`, `dist/`, `coverage/`, or `node_modules/`. The verdict header names its mode, boot-skip names the real cause, and an empty directory fails.
22
+ - Fix: `new` validates everything before writing a single file — reserved Windows device names (CON, NUL, COM1–9, …) and a 200-char cap apply to the final directory name AND every path component that will be created; quotes/backslashes/control characters in `--name`/`--idea` die instead of poisoning the JSON manifest mid-scaffold.
23
+ - Fix: the CLI never silently ignores input it doesn't understand — unknown flags, empty or flag-like flag values, and extra positional arguments die with the allowed list on every command; nested `new sub/proj` (missing parents created) works while an unusable parent dies with a readable message; a hung test run reports a `tests timed out` verdict on every supported Node (22's file-level runner timeout and 24's spawn-budget timeout both covered).
24
+ - Fix: `rateLimit({...})` instances own their buckets — independently configured wrappers no longer drain one shared budget (#54).
25
+ - Fix: the server templates answer oversize bodies with 413 before destroying the socket (up to 2× the limit drained so the 413 can be delivered; beyond that destroyed to bound the cost), turn contract-violating handler returns into clean 500s, clamp non-standard statuses, and send `null` for `[status]`-only returns. Both web and api templates are covered by live e2e tests.
26
+ - Fix: the package identity is scoped everywhere in-repo — `package.json` is `@ahmed-3m/idea2prototype` (what the release pipeline actually publishes); `publish.yml` no longer rewrites the name at publish time; tarball/global installs and the engine's registry-pin detection agree (pinned by a consistency test).
27
+ - CI: SHA-pinned actions upgraded to current majors (checkout v7.0.1, setup-node v7.1.0) plus weekly Dependabot bump-PRs so the pins stop rotting; nothing auto-merges.
28
+ - Benchmark: the 10-spec paired benchmark set is complete (this release archives specs 5–6 and 8–10: quiz, pomodoro, echo chat, habit tracker, word-counter CLI; spec 7 landed in 0.9.0). Across n=10: hand-written LOC −10%…−64% on 7 of 8 build-type specs (spec 6 at parity) and generated tests 2–3× the control's (parity on spec 6), full-depth verify vs. the control's recurring boot-skip; wall-clock split honestly, with the from-scratch arm faster on several small builds. All rubrics pre-registered; all judges mechanical.
29
+ - Tests: engine + consistency suite 46 → 69.
30
+
3
31
  ## 0.9.1
4
32
 
5
33
  - Fix: scaffolds made through a published install (`npx`, `npm i -g`) now pin registry coordinates in the check script (`npx -y @ahmed-3m/idea2prototype@<scaffold-version> check`) instead of an absolute path into the volatile npx cache — `npm run check` survives `npm cache clean` and runs on a second machine. Checkouts (repo clone, plugin cache) still pin the stable local engine path; the exact-version guarantee is unchanged either way. Template placeholder renamed `__IDEA2PROTOTYPE_BIN__` → `__IDEA2PROTOTYPE_CMD__` to match the broader contract.
package/README.md CHANGED
@@ -15,7 +15,9 @@ Idea2Prototype check — PASS (3/3)
15
15
  boot PASS GET /api/health -> 200, GET / -> 200 in 45ms
16
16
  ```
17
17
 
18
- **Status:** v0.9.0 · actively maintained · 0.x — the check/verify contract and template shapes are stable; new capabilities arrive as `add` modules.
18
+ **Status:** v1.0.1 · actively maintained · 1.x — the check/verify contract and template shapes are stable; new capabilities arrive as `add` modules.
19
+
20
+ > **Idea still fuzzy?** Start one stage earlier with [brainstorm2idea](https://github.com/ahmed-3m/brainstorm2idea) — a Socratic dialogue turns raw thought into a machine-linted `brief.md`, then hands off directly into `i2p new`.
19
21
 
20
22
  That verdict is the whole idea: an agent building a prototype should **never generate boilerplate it didn't need to, and never read logs it didn't need to**. The syntax step covers server code (`node --check`) and every `.js` under `public/`, recursively (parsed as both ESM and classic script — only code broken in both modes fails).
21
23
 
@@ -54,6 +56,8 @@ Idea2Prototype moves all three to deterministic code: `new` scaffolds a running,
54
56
 
55
57
  Templates: `web` (static frontend + health + auto-loading routes), `api` (JSON API + route manifest), `cli` (arg-parsed tool), `worker` (persistent job queue with retries), `library` (importable module: `createStore` + `memoAsync`). All Node >= 18.17, built-in `node:test`, zero installs — ever.
56
58
 
59
+ **JSON stores are single-writer.** Every `data/*.json` store is an in-memory list persisted on write by ONE server process — run two servers on the same project dir and each will clobber the other's acknowledged writes on its next persist (last writer wins the whole file). A store that fails to parse on first read is never silently wiped: it is quarantined as `data/<name>.json.corrupt-<timestamp>` (the original bytes are preserved for recovery) and the process starts empty with a loud stderr note. `auth-local` sessions are stateless HMAC tokens — logout clears the browser cookie only; a copied token stays valid until it expires.
60
+
57
61
  ## Quickstart
58
62
 
59
63
  **Any agent or plain shell — npx straight off npmjs, no clone needed:**
@@ -92,7 +96,7 @@ import { requireAuth } from './auth.mjs';
92
96
 
93
97
  POST: requireAuth(async ({ body, user }) => {
94
98
  // ...original handler body...
95
- const item = { id, createdAt, ...body, author: user.username };
99
+ const item = { ...body, id, createdAt, author: user.username }; // body first: server-owned fields win
96
100
  // ...persist and return [201, item]...
97
101
  }),
98
102
  ```
@@ -111,7 +115,7 @@ The generated CRUD test then needs a session instead of anonymous POSTs — regi
111
115
 
112
116
  ## Benchmarks
113
117
 
114
- `benchmarks/specs.md` is a pre-registered protocol: paired 2-arm design (same agent with vs. without the harness), blind functional judges, a symmetric verifier (`i2p verify`), and hypotheses stated up front. Results land in that file as they're measured — failures included. Three specs are archived: specs 1–2 (web app, API) favor the harness (23% fewer hand-written LOC, 2× tests, zero runner-compat failures — the control's from-scratch `npm test` broke on Node 24/Windows); spec 3 (micro-CLI) is an honest loss on speed and LOC — fixed overhead dominates tiny builds — with reliability and function at parity.
118
+ `benchmarks/specs.md` is a pre-registered protocol: paired 2-arm design (same agent with vs. without the harness), blind functional judges, a symmetric verifier (`i2p verify`), and hypotheses stated up front. Results land in that file as they're measured — failures included. Ten specs are archived. Specs 1–2 (web app, API) favor the harness (23% fewer hand-written LOC, 2× tests, zero runner-compat failures — the control's from-scratch `npm test` broke on Node 24/Windows); spec 3 (micro-CLI) is an honest loss on speed and LOC — fixed overhead dominates tiny builds — with reliability and function at parity; spec 4 (expense tracker) wrote ~43% fewer hand-written LOC with 3× tests; spec 7 (bookmarks API + tag filter) is the strongest result at ~64%. Across the set the pattern holds: hand-written LOC −10%…−64% on 7 of 8 build-type specs (spec 6 at parity), generated tests 2–3× the control's, full-depth verify against the control's recurring boot-skip — while the from-scratch arm stays faster on several small builds, recorded as such.
115
119
 
116
120
  ## Design rules
117
121
 
package/agents/AGENTS.md CHANGED
@@ -4,6 +4,8 @@ Copy this file into any project where your coding agent should build with idea2p
4
4
 
5
5
  You have `idea2prototype` (`i2p`) available — a zero-dependency prototype tool. Use it instead of hand-writing scaffolding. If the npm package isn't installed or available, run the engine directly instead of `npx @ahmed-3m/idea2prototype`: `node <path-to-idea2prototype-repo>/skills/idea2prototype/scripts/idea2prototype.mjs <command>`.
6
6
 
7
+ If starting from a fuzzy or unformed idea, load the `brainstorm2idea` skill and run `/b2i "<raw idea>"` to generate an approved `brief.md`, then run `b2i handoff <dir> --brief brief.md` (or `npx @ahmed-3m/brainstorm2idea handoff <dir>`) to scaffold directly into `idea2prototype new`.
8
+
7
9
  ## Commands
8
10
 
9
11
  - `npx @ahmed-3m/idea2prototype new <dir> --template web|api|cli|worker|library` — scaffold a running, tested project (~0 tokens vs 10–30k hand-written)
package/agents/CLAUDE.md CHANGED
@@ -4,6 +4,8 @@ Copy this file into any project where your coding agent should build with idea2p
4
4
 
5
5
  You have `idea2prototype` (`i2p`) available — a zero-dependency prototype tool. Use it instead of hand-writing scaffolding. If the npm package isn't installed or available, run the engine directly instead of `npx @ahmed-3m/idea2prototype`: `node <path-to-idea2prototype-repo>/skills/idea2prototype/scripts/idea2prototype.mjs <command>`.
6
6
 
7
+ If starting from a fuzzy or unformed idea, load the `brainstorm2idea` skill and run `/b2i "<raw idea>"` to generate an approved `brief.md`, then run `b2i handoff <dir> --brief brief.md` (or `npx @ahmed-3m/brainstorm2idea handoff <dir>`) to scaffold directly into `idea2prototype new`.
8
+
7
9
  ## Commands
8
10
 
9
11
  - `npx @ahmed-3m/idea2prototype new <dir> --template web|api|cli|worker|library` — scaffold a running, tested project (~0 tokens vs 10–30k hand-written)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ahmed-3m/idea2prototype",
3
- "version": "0.9.1",
4
- "description": "Turn ideas into tested prototypes — token-lean scaffolds + one-command verification for any coding agent. Zero dependencies.",
3
+ "version": "1.0.1",
4
+ "description": "Turn ideas into tested prototypes \u2014 token-lean scaffolds + one-command verification for any coding agent. Zero dependencies.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "ahmed-3m",
@@ -18,7 +18,7 @@ node "<skill-base>/scripts/idea2prototype.mjs" <command>
18
18
  `<skill-base>` is this skill's own directory (shown at the top of this skill when loaded). Commands:
19
19
 
20
20
  - `new <dir> --template web|api|cli|worker|library --name "..." --idea "..."` — scaffold a project
21
- - `add api-crud --resource <name>` — add a JSON-file CRUD resource + tests (web/api)
21
+ - `add api-crud --resource <name>` — add a JSON-file CRUD resource + tests (web/api). Names another feature owns are refused (`users`, `auth`, `jobs`, `uploads`, `events`, `ping`, …) — e.g. use `members`, not `users`, next to `auth-local`
22
22
  - `add auth-local` — register/login/logout/me accounts: scrypt hashes, HMAC-signed cookies, `requireAuth` helper (web/api)
23
23
  - `add upload` — multipart file uploads with fetch-back endpoint + tests (web/api)
24
24
  - `add rate-limit` — per-key fixed-window limiter: `rateLimit({ max, windowMs, keyFn })` wraps any handler, 429 + Retry-After + X-RateLimit-* headers, `GET /api/ping` demo (web/api)
@@ -52,7 +52,7 @@ import { requireAuth } from './auth.mjs';
52
52
  POST: requireAuth(async ({ body, user }) => {
53
53
  const bad = requireObject(body);
54
54
  if (bad) return bad;
55
- const item = { id: randomUUID(), createdAt: new Date().toISOString(), ...body, author: user.username };
55
+ const item = { ...body, id: randomUUID(), createdAt: new Date().toISOString(), author: user.username };
56
56
  (await load()).push(item);
57
57
  await persist();
58
58
  return [201, item];
@@ -92,4 +92,6 @@ Then `check` — the anon-401/authed-201 contract and the rest of the CRUD suite
92
92
  - `check` exits non-zero on failure, prints at most 3 failure notes — fix those, re-run. A trailing `note` line about scaffold/engine version drift is informational, not a failure. `check --json` gives the same verdict machine-readable. `verify [dir]` runs the same verdict on any Node project (benchmark/judge mode).
93
93
  - If the user asks for dependencies (a framework, a database), ask once, then add via `npm install` and extend the tests accordingly.
94
94
  - Projects are plain Node — `npm start` (web/api), `node cli.mjs help` (cli), `import ... from './index.mjs'` (library); no other tooling assumed.
95
+ - JSON stores (`data/*.json`) are single-writer: one server process per project dir — a second server's persist clobbers the first's acknowledged writes. A store that fails to parse on first read is quarantined (`data/<name>.json.corrupt-<ts>`, original bytes preserved) and the process starts empty with a loud stderr note — never a silent wipe.
96
+ - `auth-local` session tokens are stateless HMAC: logout clears the browser cookie only, and a token copied before logout stays valid until it expires — production-ish apps should shorten the TTL or add a server-side revocation list (the route's docblock says the same).
95
97
  - Templates are single-purpose: no cross-template composition exists. If a task needs background jobs inside a web/api project, `add worker-jobs` brings the worker template's queue in as a feature — no need to scaffold both. Feature composition (`auth-local` × `api-crud`, `rate-limit`, `cors`, `sse` streaming, `worker-jobs`) is supported; template composition is not.