@madojs/mado 0.5.1 → 0.6.0

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.
Files changed (101) hide show
  1. package/AGENTS.md +26 -0
  2. package/CHANGELOG.md +153 -0
  3. package/MADO_V1_PLAN.md +179 -0
  4. package/README.md +31 -13
  5. package/ROADMAP.md +28 -7
  6. package/TODO.md +72 -0
  7. package/dist/src/forms.d.ts +37 -4
  8. package/dist/src/forms.js +331 -57
  9. package/dist/src/forms.js.map +1 -1
  10. package/dist/src/html/bindings.d.ts +41 -0
  11. package/dist/src/html/bindings.js +163 -6
  12. package/dist/src/html/bindings.js.map +1 -1
  13. package/dist/src/html.d.ts +2 -0
  14. package/dist/src/html.js +1 -0
  15. package/dist/src/html.js.map +1 -1
  16. package/dist/src/index.d.ts +6 -6
  17. package/dist/src/index.js +2 -2
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/page.d.ts +56 -0
  20. package/dist/src/page.js +17 -0
  21. package/dist/src/page.js.map +1 -1
  22. package/dist/src/router/manifest.d.ts +16 -1
  23. package/dist/src/router/manifest.js +181 -38
  24. package/dist/src/router/manifest.js.map +1 -1
  25. package/dist/src/router/match.d.ts +7 -2
  26. package/dist/src/router/match.js +14 -4
  27. package/dist/src/router/match.js.map +1 -1
  28. package/dist/src/router/navigation.d.ts +10 -0
  29. package/dist/src/router/navigation.js +71 -3
  30. package/dist/src/router/navigation.js.map +1 -1
  31. package/dist/src/signal.d.ts +15 -1
  32. package/dist/src/signal.js +112 -16
  33. package/dist/src/signal.js.map +1 -1
  34. package/docs/en/02-project-layout.md +99 -40
  35. package/docs/en/10-app-architecture.md +141 -0
  36. package/docs/en/11-layouts.md +115 -0
  37. package/docs/en/12-auth-and-api.md +217 -0
  38. package/docs/en/13-deployment.md +192 -0
  39. package/docs/en/14-testing.md +82 -0
  40. package/docs/en/15-error-handling.md +100 -0
  41. package/docs/en/16-bake-cookbook.md +93 -0
  42. package/docs/en/README.md +7 -0
  43. package/docs/fr/10-app-architecture.md +61 -0
  44. package/docs/fr/11-layouts.md +35 -0
  45. package/docs/fr/12-auth-and-api.md +35 -0
  46. package/docs/fr/13-deployment.md +39 -0
  47. package/docs/fr/14-testing.md +41 -0
  48. package/docs/fr/15-error-handling.md +50 -0
  49. package/docs/fr/16-bake-cookbook.md +35 -0
  50. package/docs/fr/README.md +7 -0
  51. package/docs/ru/10-app-architecture.md +100 -0
  52. package/docs/ru/11-layouts.md +47 -0
  53. package/docs/ru/12-auth-and-api.md +53 -0
  54. package/docs/ru/13-deployment.md +60 -0
  55. package/docs/ru/14-testing.md +50 -0
  56. package/docs/ru/15-error-handling.md +56 -0
  57. package/docs/ru/16-bake-cookbook.md +55 -0
  58. package/docs/ru/README.md +7 -0
  59. package/docs/uk/10-app-architecture.md +56 -0
  60. package/docs/uk/11-layouts.md +34 -0
  61. package/docs/uk/12-auth-and-api.md +34 -0
  62. package/docs/uk/13-deployment.md +39 -0
  63. package/docs/uk/14-testing.md +34 -0
  64. package/docs/uk/15-error-handling.md +32 -0
  65. package/docs/uk/16-bake-cookbook.md +36 -0
  66. package/docs/uk/README.md +7 -0
  67. package/llms.txt +9 -1
  68. package/package.json +3 -1
  69. package/scripts/_config.mjs +224 -0
  70. package/scripts/bake.mjs +217 -120
  71. package/scripts/bundle.mjs +110 -67
  72. package/scripts/cli.mjs +119 -15
  73. package/scripts/preview.mjs +22 -12
  74. package/server/serve.mjs +82 -4
  75. package/starters/admin/README.md +63 -0
  76. package/starters/admin/index.html +21 -0
  77. package/starters/admin/mado.config.json +22 -0
  78. package/starters/admin/package.json +22 -0
  79. package/starters/admin/public/favicon.svg +4 -0
  80. package/starters/admin/src/components/x-button.ts +55 -0
  81. package/starters/admin/src/components/x-input.ts +74 -0
  82. package/starters/admin/src/layouts/app.ts +101 -0
  83. package/starters/admin/src/layouts/auth.ts +41 -0
  84. package/starters/admin/src/lib/api.ts +133 -0
  85. package/starters/admin/src/lib/auth.ts +83 -0
  86. package/starters/admin/src/main.ts +15 -0
  87. package/starters/admin/src/pages/admin/dashboard.ts +48 -0
  88. package/starters/admin/src/pages/admin/order-detail.ts +78 -0
  89. package/starters/admin/src/pages/admin/orders.ts +117 -0
  90. package/starters/admin/src/pages/home.ts +25 -0
  91. package/starters/admin/src/pages/login.ts +70 -0
  92. package/starters/admin/src/pages/not-found.ts +12 -0
  93. package/starters/admin/src/routes.ts +40 -0
  94. package/starters/admin/src/styles/global.ts +86 -0
  95. package/starters/admin/tsconfig.json +15 -0
  96. package/starters/crud/mado.config.json +20 -0
  97. package/starters/crud/package.json +8 -4
  98. package/starters/crud/src/routes.ts +4 -2
  99. package/starters/minimal/mado.config.json +20 -0
  100. package/starters/minimal/package.json +7 -3
  101. package/starters/minimal/src/routes.ts +4 -2
package/AGENTS.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  > This file is read by AI agents in IDEs (Cursor, Cline, Copilot, Continue, etc.).
4
4
  > Goal: prevent them from generating React-like code where Mado should be used.
5
+ >
6
+ > The v0.6 product-surface push is archived in
7
+ > [`MADO_V1_PLAN.md`](./MADO_V1_PLAN.md). New work should follow `ROADMAP.md`
8
+ > / `TODO.md` unless the user explicitly resumes that tracker.
5
9
 
6
10
  ## Project at a glance
7
11
 
@@ -289,6 +293,25 @@ src/
289
293
  └── lib/ ← API client, contexts, pure logic
290
294
  ```
291
295
 
296
+ ## App architecture for LLM
297
+
298
+ When generating an app, prefer the blessed production shape from
299
+ `docs/en/10-app-architecture.md` and the `starters/admin/` example:
300
+
301
+ - `src/main.ts` mounts `routesApi.view` and imports only global styles,
302
+ providers, and tiny shared components.
303
+ - `src/routes.ts` exports both `manifest` and `default routes(manifest, ...)`.
304
+ - Put route wrappers in `src/layouts/` via `layout()`, not ad-hoc shell logic
305
+ inside every page.
306
+ - Put backend access in `src/lib/api.ts` and auth/session logic in
307
+ `src/lib/auth.ts`; guards call auth helpers, pages call API helpers.
308
+ - Put one page per file under `src/pages/`; a page imports the feature
309
+ components it renders.
310
+ - Use `resource()` for reads, `mutation(..., { invalidates })` for writes,
311
+ and `useForm()` for form state/validation.
312
+ - Use `mado release` as the production path. `out/` is the only deploy
313
+ artifact; `dist/` is internal build output.
314
+
292
315
  ## Where to find specific answers
293
316
 
294
317
  | Question | File |
@@ -298,6 +321,9 @@ src/
298
321
  | How does the router work? | `src/router.ts` (~530 lines) |
299
322
  | How does resource + cache work? | `src/resource.ts` (297 lines) |
300
323
  | How do forms work? | `src/forms.ts` (212 lines) |
324
+ | How should an app be structured? | `docs/en/10-app-architecture.md` |
325
+ | How should errors be handled? | `docs/en/15-error-handling.md` |
326
+ | How should bake be used? | `docs/en/16-bake-cookbook.md` |
301
327
  | When something goes wrong | `docs/en/07-llm-pitfalls.md` |
302
328
 
303
329
  ## Before committing
package/CHANGELOG.md CHANGED
@@ -1,5 +1,158 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ Nothing yet.
6
+
7
+ ## 0.6.0
8
+
9
+ Product-surface release: app-mode defaults, blessed admin starter, release
10
+ pipeline, core hardening and v1 recipe docs.
11
+
12
+ Phase 1 — Repo-vs-app split:
13
+
14
+ ### Added
15
+ - `MADO_V1_PLAN.md` — executable tracker for the v1 push.
16
+ - `scripts/_config.mjs` — single configuration loader (defaults < `mado.config.json`
17
+ < CLI flags). Exports `loadConfig`, `detectContext`, `parseFlags`,
18
+ `resolveProjectPath`. [v1 F1.1]
19
+ - `mado release` command: one-shot `typecheck + build + bundle + bake + copy
20
+ public/ → out/` pipeline so apps have exactly one command to ship. [v1 F1.3]
21
+ - `mado.config.json` shipped in the `minimal` and `crud` starters with the
22
+ default app-mode layout (`src/routes.ts`, `index.html`, `out/`). [v1 F1.4]
23
+ - Tests: `test/config-loader.test.mjs`, `test/bake-cli.test.mjs` (11 + 3
24
+ cases covering context detection, config precedence, flag parsing, bake
25
+ flags, and the no-more-silent-`[object Object]` contract). [v1 F1.6]
26
+
27
+ ### Changed
28
+ - `scripts/bake.mjs` now reads configuration from `mado.config.json` and
29
+ accepts `--entry`, `--template`, `--out`, `--base-url` flags. In app-mode
30
+ defaults are `src/routes.ts` + `index.html` + `out/baked/`; the
31
+ `@madojs/mado → src/index.ts` alias is repo-only. [v1 F1.2]
32
+ - `scripts/bake.mjs` no longer renders unsupported values as `[object Object]`;
33
+ it raises a loud, file/route-targeted error with a hint instead. [v1 F1.2]
34
+ - `scripts/cli.mjs` detects repo-vs-app context, advertises `mado release`,
35
+ and ships a redesigned `mado help` that explains the dev / build / release
36
+ / preview pipeline. [v1 F1.3]
37
+ - Starter `package.json` scripts go through the `mado` CLI exclusively
38
+ (`mado build`, `mado dev`, `mado bundle`, `mado bake`, `mado release`,
39
+ `mado preview`). [v1 F1.4]
40
+ - `docs/en/02-project-layout.md` rewritten around the canonical `src/` /
41
+ `dist/` / `public/` / `out/` model plus a `mado.config.json` one-screen
42
+ reference. [v1 F1.5]
43
+ - `ROADMAP.md`, `TODO.md`, `AGENTS.md` now distinguish the completed
44
+ `MADO_V1_PLAN.md` archive from future roadmap/TODO work. [v1 F0]
45
+
46
+ Phase 2 — One blessed way:
47
+
48
+ ### Added
49
+ - `layout()` factory in `src/page.ts` (alias of `nested()`) plus `Guard` and
50
+ `GuardResult` types. Exported from the public API. [v1 F2.1 / F2.3]
51
+ - Route guards: nested groups and individual pages accept `guard: Guard | Guard[]`.
52
+ Verdicts: void (pass), `{ halt: true }`, or `{ redirect, replace? }`. Async-aware
53
+ with a sync fast path; throwing guards are treated as `halt`. [v1 F2.2]
54
+ - New starter `starters/admin/`: nested manifest with `/`, `/login`, `/admin`
55
+ groups; blessed `lib/api.ts` (`createApiClient`, `ApiError`, single-flight
56
+ 401-refresh) and `lib/auth.ts` (`accessToken`, `restoreSession`, `requireAuth`,
57
+ `login`, `logout`); `layouts/{app,auth}.ts` with a real admin shell; tiny
58
+ `x-button`/`x-input` design-token components; dashboard + orders + order-detail
59
+ pages; `mado.config.json` with a dev `/api` proxy; `public/favicon.svg`. [v1 F2.4]
60
+ - CLI advertises `mado init <name> --starter admin` and lists it in `mado help`.
61
+ [v1 F2.5]
62
+ - `docs/en/11-layouts.md` — the canonical layout recipe (nested routes) plus
63
+ two acceptable alternatives with caveats. [v1 F2.6]
64
+ - `docs/en/12-auth-and-api.md` — the blessed `api`/`auth` recipes, backend
65
+ contract, and dev-proxy hint. [v1 F2.7]
66
+ - `test/guards-layouts.test.mjs` — 7 cases covering the public `layout()`
67
+ alias, sync pass/halt/redirect, async guards, parent→page guard order, and
68
+ throwing-guard fallback. [v1 F2.8]
69
+
70
+ Phase 3 — Bake first-class + Release pipeline:
71
+
72
+ ### Added
73
+ - `mado release` writes `_redirects` (`/* /index.html 200`) and `_headers`
74
+ (immutable for `/assets/*`, no-cache for HTML) into `out/` when they do not
75
+ exist, so Cloudflare Pages / Netlify deploys "just work". [v1 F3.7]
76
+ - `docs/en/13-deployment.md` — VPS + nginx, Cloudflare Pages, S3/CloudFront,
77
+ Netlify and GitHub Pages recipes; cache-control matrix; GitHub Actions
78
+ release sketch; troubleshooting (deep-link 404, HTML caching, `[object Object]`).
79
+ [v1 F3.8 / F3.9]
80
+ - `test/release-pipeline.test.mjs` — end-to-end test: scaffold a temp app,
81
+ symlink the local framework, run `mado release`, assert that `out/index.html`,
82
+ `out/baked/index.html`, `out/baked/sitemap.xml`, `out/_redirects`, `out/_headers`,
83
+ and copied `public/` assets are all present. [v1 F3.10]
84
+
85
+ ### Changed
86
+ - `scripts/preview.mjs` now reads `mado.config.json` (`build.out`, `dev.port`),
87
+ refuses to auto-build by default in app-mode, and asks the user to run
88
+ `mado release` first. Legacy auto-build is opt-in via `PREVIEW_AUTOBUILD=1`
89
+ for the framework repo. [v1 F3.3]
90
+ - `scripts/bundle.mjs` is now app-mode aware: reads `mado.config.json` for
91
+ defaults, accepts `--entry/--html/--out` flags, and writes hashed bundles
92
+ into `out/assets/` so the new nginx / Cloudflare cache rules apply. The old
93
+ `examples/showcase` defaults are kept only in repo-mode for dogfooding.
94
+ [v1 F3.10]
95
+ - `server/serve.mjs` honors `dev.proxy` from `mado.config.json` and forwards
96
+ matching prefixes (e.g. `/api → http://localhost:3000`) without external
97
+ dependencies. The startup banner prints the active proxy table. [v1 F3.6]
98
+
99
+ ### Deferred to v0.7
100
+ - `mado dev` does not yet serve baked routes inline. Workaround: run
101
+ `mado release && mado preview`. [v1 F3.2]
102
+ - `mado check` (bake-safety scan over `bake:` routes) is not exposed yet.
103
+ The loud-error contract in `scripts/bake.mjs` covers the regression case.
104
+ [v1 F3.5]
105
+
106
+ Phase 4 — Core hardening:
107
+
108
+ ### Added
109
+ - `computed(fn, { equals })` option to suppress subscriber reruns when an
110
+ observed computed recomputes to an equal value. [v1 F4.3]
111
+ - HTML directives: `unsafeHTML()`, `ref()`, `classMap()` and `styleMap()` are
112
+ exported from the public API. Runtime bindings enforce valid positions and
113
+ clean up stale classes/styles/refs on updates and disposal. Bake can serialize
114
+ the static directive shapes it can safely represent. [v1 F4.4]
115
+ - `useForm()` now supports async validators via form-level `validateAsync`,
116
+ field-level `validateAsync`, `validating` / `validatingFields`, and explicit
117
+ `validate()` / `validateField()` methods. [v1 F4.5]
118
+ - `useForm().array(name)` adds a small field-array helper with dotted path names
119
+ (`items.0.title`) and wildcard schema validation (`items.*.title`). [v1 F4.5]
120
+ - `test/signal-cycle.test.mjs` covers self-triggering effect cycle detection.
121
+ [v1 F4.2]
122
+ - `test/html-directives.test.mjs` covers directive rendering, cleanup and
123
+ invalid child-position usage. [v1 F4.4]
124
+ - `test/forms.test.mjs` covers async validator races, async submit blocking,
125
+ and field-array wildcard validation. [v1 F4.5]
126
+ - Phase 4 now has an explicit coverage audit tying every core-hardening task to
127
+ its regression tests. [v1 F4.9]
128
+
129
+ ### Changed
130
+ - `computed()` now releases dependency subscriptions after unobserved reads and
131
+ after the last subscriber is disposed, avoiding long-lived stale subscriptions
132
+ in the signal graph. [v1 F4.1]
133
+ - The effect scheduler now detects runaway self-triggering cycles and emits a
134
+ clear diagnostic instead of flushing forever. [v1 F4.2]
135
+ - Runtime head management now clears Mado-managed tags on every navigation,
136
+ including pages without `head()` and pages whose `head()` throws, so stale
137
+ baked/runtime SEO tags cannot leak across routes. [v1 F4.8]
138
+ - Router navigation now saves/restores scroll positions for back/forward,
139
+ scrolls new navigations to the top, and moves focus to the main content
140
+ landmark after navigation. [v1 F4.6]
141
+ - `routes()` now supports a global `errorPage(err, params)` route boundary for
142
+ lazy loader, `load()` and `view()` errors, while local `page.errorView` still
143
+ wins. [v1 F4.7]
144
+
145
+ Phase 5 — Documentation:
146
+
147
+ ### Added
148
+ - `docs/en/10-app-architecture.md`, `14-testing.md`, `15-error-handling.md`
149
+ and `16-bake-cookbook.md` complete the v1 English recipe set. [v1 F5.1-F5.4]
150
+ - `AGENTS.md` now includes an "App architecture for LLM" section and `llms.txt`
151
+ links the v1 architecture, layout, auth/API, deployment, testing,
152
+ error-handling and bake docs. [v1 F5.5-F5.6]
153
+ - Russian, French and Ukrainian documentation now includes localized versions of
154
+ the v1 recipe docs `10` through `16`. [v1 F5.7]
155
+
3
156
  ## 0.5.1
4
157
 
5
158
  Patch release focused on first-user DX after the public npm launch.
@@ -0,0 +1,179 @@
1
+ # MadoJS — Road to v1 (completed v0.6 tracker)
2
+
3
+ > Completed tracker for the v0.6 product-surface push. The work agreed during
4
+ > the v1 audit is now closed and squash-merged into `main` as
5
+ > `feat: add v1 product surface`.
6
+ >
7
+ > Convention: every commit/PR that advances v1 references task IDs in its message,
8
+ > e.g. `[v1 F1.2] bake.mjs: app-mode defaults + --entry/--template/--out flags`.
9
+ > When a task is completed, tick its box here in the same commit.
10
+
11
+ ---
12
+
13
+ ## 0. Mental model (write this into docs first)
14
+
15
+ Three artifact states. One deploy artifact. End of story.
16
+
17
+ | Folder | What it is | Who writes | Who reads | Deployed? |
18
+ |-------------|----------------------------------------------------------------|-------------------|----------------------------|-------------------|
19
+ | `src/` | your source (TS) | you | `tsc`, `esbuild` | no |
20
+ | `dist/` | `tsc` output (native ESM JS for the browser) | `mado build` | `mado dev`, dev browser | no (internal) |
21
+ | `public/` | static assets (favicons, images, robots.txt) | you | `mado bundle` copies it | as part of `out/` |
22
+ | `out/` | **the only deploy artifact**: SPA shell + bundles + baked HTML | `mado release` | nginx / CDN / CF / VPS | ✅ yes |
23
+
24
+ One-liner for users:
25
+ > Develop with `mado dev`. To deploy: run `mado release`, then upload `out/` anywhere.
26
+
27
+ `mado release` = `typecheck` + `build` + `bundle` + `bake` + copy `public/*` → `out/`.
28
+ One command. One artifact. Zero questions about where things live.
29
+
30
+ ---
31
+
32
+ ## 1. Problem map (consolidated)
33
+
34
+ ### Layer A — Core (from the audit)
35
+ - **A1** Computed leaks: no refcount/owner; once read, computed stays subscribed to deps forever.
36
+ - **A2** No cycle-detection in `effect` (e.g. `effect(() => x.set(x()+1))` runs forever).
37
+ - **A3** No `equals` option on `computed`.
38
+ - **A4** No template directives: `unsafeHTML`, `ref`, `classMap`, `styleMap`.
39
+ - **A5** `useForm`: no async validators, no field-arrays.
40
+ - **A6** `resource`/`invalidate`: no typed key relationship; pattern miss is silent.
41
+ - **A7** Router: no scroll restoration / focus management / error boundary.
42
+ - **A8** `head()`: not obvious how dedup/cleanup happens across navigation.
43
+
44
+ ### Layer B — DX, tooling, product surface (from dogfooding)
45
+ - **B1** CLI/bake hardcoded to `examples/` and alias `@madojs/mado → src/index.ts` — repo-mode leaks into user apps.
46
+ - **B2** No single blessed way for **layouts** (LLM and humans both guess).
47
+ - **B3** No blessed way for **auth + API client + dev-proxy**.
48
+ - **B4** No single config file (`mado.config.json`); everything is env vars.
49
+ - **B5** Unclear model for `dist/` vs `out/` vs `public/`.
50
+ - **B6** No `mado release` (one deploy artifact).
51
+ - **B7** Bake silently renders `[object Object]` for `each()`.
52
+ - **B8** Bake lives "next to" the app instead of inside `mado dev`.
53
+ - **B9** No route guard API.
54
+ - **B10** `crud` starter looks like raw scaffold; no admin-template.
55
+ - **B11** Docs missing: app-architecture, layouts, auth-and-api, deployment, testing, error-handling, bake-cookbook.
56
+ - **B12** Starter scaffolds contain `examples/` legacy.
57
+
58
+ ---
59
+
60
+ ## 2. Phases (deliver in order; phase 5 runs in parallel)
61
+
62
+ ### 🟦 Phase 1 — Repo-vs-app split (P0)
63
+
64
+ Goal: kill `examples/` leakage; make app-mode the default.
65
+
66
+ ### 🟩 Phase 2 — One blessed way (P0)
67
+
68
+ Goal: conventions over flexibility. Layouts, guards, auth, api — one recipe each.
69
+
70
+ ### 🟨 Phase 3 — Bake first-class + Release pipeline (P0)
71
+
72
+ Goal: pragmatic path from `mado dev` to production on VPS / Cloudflare / static CDN.
73
+
74
+ ### 🟪 Phase 4 — Core hardening (P1)
75
+
76
+ Goal: long-term correctness of signals, html, router, forms, head.
77
+
78
+ ### 🟫 Phase 5 — Documentation (P0/P1, in parallel)
79
+
80
+ Goal: a backender can ship an admin app reading only the docs.
81
+
82
+ ---
83
+
84
+ ## 3. Acceptance scenario for v1
85
+
86
+ ```bash
87
+ npm exec --package @madojs/mado@latest -- mado init dashboard --starter admin
88
+ cd dashboard
89
+ npm install
90
+ mado dev
91
+ # / → public landing
92
+ # /admin → redirected to /login (guard works)
93
+ # log in → admin shell with sidebar / topbar / dashboard / orders table
94
+
95
+ mado release
96
+ rsync -avz out/ user@vps:/var/www/dashboard/
97
+ # done
98
+ ```
99
+
100
+ If a backend developer reaches production **without reading `bake.mjs`,
101
+ without setting env vars, without asking "where does layout live?",
102
+ and without an `examples/` folder in their app** — v1 is done.
103
+
104
+ ---
105
+
106
+ ## 4. Tracker
107
+
108
+ ### Phase 1 — Repo-vs-app split ✅
109
+ - [x] **F1.1** `mado.config.json` schema + loader (`scripts/_config.mjs`)
110
+ - [x] **F1.2** `scripts/bake.mjs`: flags `--entry/--template/--out/--base-url`, app-mode defaults, no `examples/` alias in app-mode, loud errors instead of silent `[object Object]`
111
+ - [x] **F1.3** `scripts/cli.mjs`: detect repo vs app, read `mado.config.json`, redesigned help, new `mado release` command
112
+ - [x] **F1.4** Starters cleanup: `mado.config.json` and blessed CLI scripts in `starters/minimal` and `starters/crud`; no `examples/` references
113
+ - [x] **F1.5** `docs/en/02-project-layout.md` rewritten around the canonical `src/`/`dist/`/`public/`/`out/` model and `mado.config.json`
114
+ - [x] **F1.6** `test/config-loader.test.mjs` + `test/bake-cli.test.mjs`.
115
+
116
+ ### Phase 2 — One blessed way ✅
117
+ - [x] **F2.1** `layout()` factory (alias of `nested()`) exported from `src/page.ts`; flatten propagates layouts outer → inner.
118
+ - [x] **F2.2** `Guard` type + guard chain in `src/router/manifest.ts`. Verdicts: void / `{ halt: true }` / `{ redirect, replace? }`. Async-aware with sync fast path; throwing guard is treated as `halt` with a `console.error`.
119
+ - [x] **F2.3** `layout`, `Guard`, `GuardResult`, `nested`, `navigate` exported from `src/index.ts`.
120
+ - [x] **F2.4** New starter `starters/admin/` with `layouts/{app,auth}.ts`, `lib/{api,auth}.ts`, `components/{x-button,x-input}.ts`, `pages/{home,login,not-found,admin/{dashboard,orders,order-detail}}.ts`, `styles/global.ts`, `mado.config.json`, `public/favicon.svg`. End-to-end scaffold + typecheck + build verified locally.
121
+ - [x] **F2.5** CLI advertises `--starter admin` (`mado init my-app --starter admin`) and adds it to the help screen.
122
+ - [x] **F2.6** Doc `docs/en/11-layouts.md` (one path + 2 alternatives with caveats).
123
+ - [x] **F2.7** Doc `docs/en/12-auth-and-api.md` (blessed `api`/`auth` recipes, backend contract, dev-proxy hint).
124
+ - [x] **F2.8** `test/guards-layouts.test.mjs` covers the public `layout()` alias, sync pass/halt/redirect verdicts, async guards, parent→page guard order, and throwing-guard fallback (7 tests, all green).
125
+
126
+ ### Phase 3 — Bake first-class + Release pipeline ✅ (core)
127
+ - [x] **F3.1** `mado release` command: typecheck + build + bundle + bake + copy `public/` → `out/` + write `_headers` / `_redirects` (`scripts/cli.mjs`).
128
+ - [x] **F3.2** Deferred to v0.7: `mado dev` serves baked routes inline. Current v1 path is `mado release && mado preview`.
129
+ - [x] **F3.3** `mado preview` reads `mado.config.json`, refuses to auto-build in app-mode (opt in with `PREVIEW_AUTOBUILD=1`), and emulates nginx fallback (`scripts/preview.mjs`).
130
+ - [x] **F3.4** Bake raises a loud, file/route-targeted error on unsupported render values (e.g. `each()` directive objects). Covered by `test/bake-cli.test.mjs`.
131
+ - [x] **F3.5** Deferred to v0.7: `mado check` runs bake-safety scan on `bake:` routes. Current v1 coverage is the loud-error contract from F3.4.
132
+ - [x] **F3.6** Dev-proxy in `server/serve.mjs`: reads `dev.proxy` from `mado.config.json` and forwards matching prefixes to the upstream backend without external deps.
133
+ - [x] **F3.7** `mado release` generates `out/_redirects` (`/* /index.html 200`) and `out/_headers` (immutable for `/assets/*`, no-cache for `/*.html`) when those files do not exist.
134
+ - [x] **F3.8** Doc `docs/en/13-deployment.md` (VPS + nginx, Cloudflare Pages, S3/CloudFront, Netlify, GitHub Pages, CI sketch, cache matrix, troubleshooting).
135
+ - [x] **F3.9** Production `nginx.conf` next to the docs (already shipped, with `gzip_static`, immutable hashed bundles, SPA fallback). Verified referenced from the deployment doc.
136
+ - [x] **F3.10** `test/release-pipeline.test.mjs`: end-to-end CLI test scaffolds an app, runs `mado release`, and asserts `out/index.html`, `out/baked/index.html`, `out/_headers`, `out/_redirects`, public-asset copy, and sitemap. Also `scripts/bundle.mjs` is app-mode aware (no `examples/`-leak when run from a user app).
137
+
138
+ ### Phase 4 — Core hardening
139
+ - [x] **F4.1** Refcount/GC for `computed` in `src/signal.ts` + tests (`computed` releases dep subscriptions after unobserved reads and after the last subscriber is disposed).
140
+ - [x] **F4.2** Cycle-detection in `effect` + `test/signal-cycle.test.mjs`
141
+ - [x] **F4.3** `equals` option on `computed`
142
+ - [x] **F4.4** Directives: `unsafeHTML`, `ref`, `classMap`, `styleMap` in `src/html/bindings.ts` + public exports + `test/html-directives.test.mjs`.
143
+ - [x] **F4.5** `useForm`: async validators (`validateAsync`, field-level `validateAsync`, `validating`) + field arrays (`form.array()`, dotted paths, wildcard schema) + tests.
144
+ - [x] **F4.6** Router: scroll restoration + focus management
145
+ - [x] **F4.7** Router: `errorPage:` in manifest + error boundary
146
+ - [x] **F4.8** `src/head.ts`: guaranteed cleanup on navigation (`data-mado-head` removed before re-applying)
147
+ - [x] **F4.9** Tests for everything above: `test/computed-lazy.test.mjs` (F4.1/F4.3), `test/signal-cycle.test.mjs` (F4.2), `test/html-directives.test.mjs` (F4.4), `test/forms.test.mjs` (F4.5), `test/router-isolation.test.mjs` (F4.6), `test/router-error-boundary.test.mjs` (F4.7), `test/head.test.mjs` (F4.8). Final `typecheck + build + test` pass verified.
148
+
149
+ ### Phase 5 — Documentation (parallel to phases 2-4)
150
+ English docs for project layout, layouts, auth/API and deployment exist now.
151
+ The remaining work is deeper recipes plus translation sync.
152
+
153
+ - [x] **F5.1** `docs/en/10-app-architecture.md` (end-to-end admin)
154
+ - [x] **F5.2** `docs/en/14-testing.md`
155
+ - [x] **F5.3** `docs/en/15-error-handling.md`
156
+ - [x] **F5.4** `docs/en/16-bake-cookbook.md`
157
+ - [x] **F5.5** `AGENTS.md`: section "App architecture for LLM"
158
+ - [x] **F5.6** `llms.txt`: new anchors
159
+ - [x] **F5.7** ru/fr/uk translations for new docs (`10` through `16`)
160
+
161
+ ---
162
+
163
+ ## 5. Working loop
164
+
165
+ 1. Pick the first unchecked box.
166
+ 2. Implement it (small, focused change).
167
+ 3. Run `npm test` (and `npm run typecheck` when touching `src/`).
168
+ 4. Tick the box in this file in the same commit.
169
+ 5. Add a one-line entry under "Unreleased" in `CHANGELOG.md`.
170
+ 6. After each phase finishes, pause and review.
171
+
172
+ ## 6. Context-loss safety
173
+
174
+ - This file = ground truth on disk.
175
+ - `task_progress` in chat = current phase/task.
176
+ - Git commits tagged `[v1 Fx.y]` = time machine.
177
+
178
+ If future work resumes from this plan, treat it as archive context. New tasks
179
+ belong in `ROADMAP.md`, `TODO.md`, or a fresh tracker.
package/README.md CHANGED
@@ -91,12 +91,20 @@ enough for serious admin apps while remaining small and readable.
91
91
  npm exec --package @madojs/mado@latest -- mado init my-app
92
92
  cd my-app
93
93
  npm install
94
- npm run build
95
- npm run serve
94
+ npm run dev
96
95
  ```
97
96
 
98
- Use the CRUD starter when you want a compact admin-style example with
99
- `resource()`, `mutation()`, `useForm()`, `each()` and `queryParam()`:
97
+ Use the admin starter when you want the blessed production shape out of the box:
98
+ layouts, guards, auth/API client, dev proxy, forms and a small admin shell.
99
+
100
+ ```bash
101
+ npm exec --package @madojs/mado@latest -- mado init dashboard --starter admin
102
+ cd dashboard
103
+ npm install
104
+ npm run dev
105
+ ```
106
+
107
+ Use the CRUD starter when you want a compact resource/mutation/forms example:
100
108
 
101
109
  ```bash
102
110
  npm exec --package @madojs/mado@latest -- mado init my-app --starter crud
@@ -151,17 +159,19 @@ The developer convenience CLI is available as `mado`:
151
159
 
152
160
  ```bash
153
161
  mado init my-app
162
+ mado init dashboard --starter admin
154
163
  mado init my-app --starter crud
164
+ mado dev
155
165
  mado build
156
166
  mado typecheck
157
167
  mado test
168
+ mado release
169
+ mado preview
158
170
  mado serve basic
159
171
  mado dev showcase
160
172
  mado examples
161
173
  ```
162
174
 
163
- The CLI is useful before v1, but its command polish may still change.
164
-
165
175
  ## Documentation
166
176
 
167
177
  - [Language index](./docs/README.md)
@@ -181,6 +191,13 @@ Core topics:
181
191
  - [For backenders](./docs/en/06-for-backenders.md)
182
192
  - [LLM pitfalls](./docs/en/07-llm-pitfalls.md)
183
193
  - [Shadow DOM vs Light DOM](./docs/en/09-shadow-vs-light-dom.md)
194
+ - [App architecture](./docs/en/10-app-architecture.md)
195
+ - [Layouts](./docs/en/11-layouts.md)
196
+ - [Auth and API](./docs/en/12-auth-and-api.md)
197
+ - [Deployment](./docs/en/13-deployment.md)
198
+ - [Testing](./docs/en/14-testing.md)
199
+ - [Error handling](./docs/en/15-error-handling.md)
200
+ - [Bake cookbook](./docs/en/16-bake-cookbook.md)
184
201
 
185
202
  AI-agent entrypoints:
186
203
 
@@ -327,7 +344,8 @@ html`
327
344
 
328
345
  Validation is schema-based and intentionally close to native HTML constraints:
329
346
  `required`, `min`, `max`, `pattern`, `type=email/url/number`, plus optional
330
- custom `validate(values)`.
347
+ custom `validate(values)`. Async validators and field arrays are available via
348
+ `validateAsync`, `validateField()` and `form.array("items")`.
331
349
 
332
350
  Only the root import is the stable public API:
333
351
 
@@ -347,16 +365,16 @@ Cloudflare Worker edge-prerender PoC in [`examples/cloudflare`](./examples/cloud
347
365
 
348
366
  ## Production Bundle
349
367
 
350
- Native ESM is the default development and demo path. When a bundled production
351
- artifact is useful, run:
368
+ Native ESM is the default development path. For production, use the one-command
369
+ release pipeline:
352
370
 
353
371
  ```bash
354
- npm run bundle
355
- npm run preview
372
+ mado release
373
+ mado preview
356
374
  ```
357
375
 
358
- `bundle` uses optional `esbuild` for code splitting, SRI, `.gz` and `.br`
359
- outputs. `preview` emulates the provided `nginx.conf` with `node:http`.
376
+ `release` runs typecheck, build, bundle, bake and public asset copy, then writes
377
+ the deployable artifact into `out/`. `preview` serves `out/` like a static host.
360
378
 
361
379
  ## Tests
362
380
 
package/ROADMAP.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Roadmap
2
2
 
3
- Mado is pre-v1. The goal is not to grow sideways, but to keep the runtime small,
4
- readable and reliable under real application pressure.
3
+ Mado is still pre-1.0, but the v0.6 product-surface push is complete. The goal
4
+ from here is not to grow sideways, but to keep the runtime small, readable and
5
+ reliable under real application pressure.
5
6
 
6
7
  ## Current Focus
7
8
 
@@ -12,12 +13,31 @@ readable and reliable under real application pressure.
12
13
  - Keep English as the public/default project language, with localized docs in
13
14
  `docs/ru`, `docs/fr` and `docs/uk`.
14
15
 
15
- ## Before v1
16
+ ## Completed in v0.6
17
+
18
+ - **Phase 1 — Repo-vs-app split.** Kill `examples/`-leakage from CLI and bake;
19
+ introduce `mado.config.json`; app-mode becomes the default for `mado bake`,
20
+ `mado bundle`, `mado preview`.
21
+ - **Phase 2 — One blessed way.** First-class `layout()` + nested manifest;
22
+ `Guard` API with `redirect`/`halt`; blessed `--starter admin` starter with
23
+ blessed `api`/`auth` recipes; docs for layouts and auth-and-api.
24
+ - **Phase 3 — Bake first-class + Release pipeline.** `mado release` as the
25
+ single deploy command (`dist` internal, `out` deployed); `mado dev` serves
26
+ baked routes inline; bake stops silently rendering `[object Object]`;
27
+ deployment doc with VPS / Cloudflare Pages / static-CDN recipes.
28
+ - **Phase 4 — Core hardening.** Computed GC + cycle-detection in `effect`;
29
+ template directives (`unsafeHTML`, `ref`, `classMap`, `styleMap`); async
30
+ validators and field-arrays in `useForm`; scroll restoration, focus
31
+ management and error boundary in the router; head cleanup on navigation.
32
+ - **Phase 5 — Documentation (parallel).** `10-app-architecture.md`,
33
+ `11-layouts.md`, `12-auth-and-api.md`, `13-deployment.md`, `14-testing.md`,
34
+ `15-error-handling.md`, `16-bake-cookbook.md`; AGENTS.md app-architecture
35
+ section; ru/fr/uk translations.
36
+
37
+ The detailed completed tracker lives in [`MADO_V1_PLAN.md`](./MADO_V1_PLAN.md).
38
+
39
+ ## Remaining Before 1.0
16
40
 
17
- - Generated app DX: `mado dev`/`serve`/starter scripts should feel as polished
18
- outside the framework repo as they do inside it.
19
- - Generated app production story: `mado bundle` and `mado preview` should work
20
- from a starter app without repository-only assumptions.
21
41
  - Browser compatibility pass across current Chrome, Edge, Firefox and Safari.
22
42
  - Accessibility pass for examples and common component patterns.
23
43
  - Public API audit: names, warnings, lifecycle rules, docs coverage.
@@ -55,6 +75,7 @@ readable and reliable under real application pressure.
55
75
  | 2026-06-06 | Mado rebrand | Public package/import name `@madojs/mado`, CLI `mado`, brand/docs/examples updated, internal legacy markers cleaned. |
56
76
  | 2026-06-06 | Public polish | English public surface, localized docs, translated code comments/examples/templates/GitHub files. |
57
77
  | 2026-06-07 | First npm release | Published `@madojs/mado@0.5.0` with the `mado` CLI, minimal/crud starters, CI and release workflow. |
78
+ | 2026-06-09 | v0.6 product surface | App-mode CLI/config split, admin starter, release pipeline, core hardening, v1 recipe docs and localized docs. |
58
79
 
59
80
  ## Future Ideas
60
81
 
package/TODO.md ADDED
@@ -0,0 +1,72 @@
1
+ # TODO
2
+
3
+ > The v0.6 product-surface push is complete. The closed tracker is archived in
4
+ > [`MADO_V1_PLAN.md`](./MADO_V1_PLAN.md). The items below are ideas for later
5
+ > releases and are not part of the v0.6 contract.
6
+
7
+ Ideas that are not commitments. Roadmap milestones live in `ROADMAP.md`.
8
+
9
+ ## DX
10
+
11
+ - [ ] `npx mado create my-app` scaffold.
12
+ - [ ] `mado page <name>` / `mado component <name>` wrappers around templates.
13
+ - [ ] Split `scripts/cli.mjs` into small internal modules (`cli/init`,
14
+ `cli/run`, `cli/dev`, `cli/static-server`) before it becomes hard to read.
15
+ - [ ] Make `mado preview` and `mado bundle` work naturally inside generated
16
+ apps, not only inside the framework repository.
17
+ - [ ] Typed navigation inferred from route patterns.
18
+ - [ ] Optional VS Code extension for `html`` / `css`` highlighting.
19
+
20
+ ## Runtime
21
+
22
+ - [ ] Optimistic mutation hook with rollback.
23
+ - [ ] `<x-async>` helper for resource loading/error shells.
24
+ - [ ] `liveResource()` over SSE / WebSocket.
25
+ - [ ] i18n helper once browser-native message formatting is realistic.
26
+ - [ ] Accessibility helpers: focus trap, live region, click outside.
27
+
28
+ ## Styling
29
+
30
+ - [ ] Docs for `::part`, `::slotted()` and `:host-context()`.
31
+ - [ ] Optional tiny utilities stylesheet.
32
+
33
+ ## Operations
34
+
35
+ - [ ] Benchmark against Lit / Solid / Preact.
36
+ - [ ] Decide package exports policy before v1: remove the wildcard export or
37
+ keep it documented as unstable internal deep imports.
38
+ - [ ] Add first-class size reporting for runtime budget (ESM graph,
39
+ bundled/minified, gzip, brotli) without counting docs/starters/package files.
40
+ - [ ] `eslint-plugin-mado` rules for common mistakes.
41
+ - [ ] CSP-friendly style mode.
42
+ - [ ] PWA scaffold.
43
+ - [ ] Schema validation hook for resources.
44
+ - [ ] Timeout / retry options for resource fetchers.
45
+ - [ ] Source-map notes and a minimal dev error overlay.
46
+
47
+ ## Bake / Smart Static
48
+
49
+ - [ ] Webhook re-bake endpoint.
50
+ - [ ] Incremental bake cache.
51
+ - [ ] RSS / Atom feed generator.
52
+ - [ ] Nested-route bake support.
53
+
54
+ ## Community
55
+
56
+ - [ ] Minimal landing site built with Mado.
57
+ - [ ] Case study: real React page → Mado + bake.
58
+ - [ ] Public live demo: CRUD starter and showcase hosted from Mado itself.
59
+ - [ ] Convert contribution-ready TODO items into GitHub issues with labels
60
+ (`good first issue`, `help wanted`, `docs`, `cli`, `ci`) after the first
61
+ public feedback round.
62
+
63
+ ## Release / GitHub
64
+
65
+ - [ ] Configure npm Trusted Publishing for GitHub Actions after verifying the
66
+ first manual publishes.
67
+ - [ ] Decide the release flow: continue manual npm publish for patch releases or
68
+ publish from signed `v*` tags through `.github/workflows/release.yml`.
69
+ - [ ] Improve generated release notes: include PR links/authors when releases
70
+ start going through pull requests.
71
+ - [ ] Add a short maintainer-only release checklist outside public docs if the
72
+ manual flow stays in use.