@cs4alhaider/screenbook 0.1.0 → 0.2.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.
Files changed (66) hide show
  1. package/AGENTS.md +147 -0
  2. package/CLAUDE.md +4 -184
  3. package/README.md +146 -163
  4. package/bridge.js +16 -2
  5. package/cli/postinstall.js +34 -0
  6. package/cli/screenbook.js +84 -34
  7. package/cli/templates.js +54 -1
  8. package/core/browser.js +22 -7
  9. package/core/project.js +28 -7
  10. package/core/serve.js +22 -7
  11. package/docs/README.md +25 -14
  12. package/docs/brand/logo-mark.png +0 -0
  13. package/docs/brand/logo-transparent.png +0 -0
  14. package/docs/brand/logo.png +0 -0
  15. package/docs/brand/readme-header.png +0 -0
  16. package/docs/contributing/architecture.md +153 -0
  17. package/{TESTING.md → docs/contributing/testing.md} +13 -8
  18. package/docs/{app-mode-guide.md → guides/app-mode.md} +17 -10
  19. package/docs/{authoring-guide.md → guides/authoring.md} +43 -17
  20. package/docs/guides/getting-started.md +84 -0
  21. package/docs/{studio-guide.md → guides/studio.md} +3 -2
  22. package/docs/{troubleshooting.md → guides/troubleshooting.md} +11 -8
  23. package/docs/{cli.md → reference/cli.md} +15 -10
  24. package/docs/{mcp-agents.md → reference/mcp-agents.md} +3 -3
  25. package/docs/shots/android-dark.png +0 -0
  26. package/docs/shots/android-light.png +0 -0
  27. package/docs/shots/app-mode-dark.png +0 -0
  28. package/docs/shots/app-mode-light.png +0 -0
  29. package/docs/shots/hero-studio-dark.png +0 -0
  30. package/docs/shots/hero-studio-light.png +0 -0
  31. package/docs/shots/review-mode-dark.png +0 -0
  32. package/docs/shots/review-mode-light.png +0 -0
  33. package/docs/shots/rtl-arabic-dark.png +0 -0
  34. package/docs/shots/rtl-arabic-light.png +0 -0
  35. package/docs/shots/theme-lab-dark.png +0 -0
  36. package/docs/shots/theme-lab-light.png +0 -0
  37. package/docs/shots/theming-noir-dark.png +0 -0
  38. package/docs/shots/theming-noir-light.png +0 -0
  39. package/docs/shots/web-dashboard-dark.png +0 -0
  40. package/docs/shots/web-dashboard-light.png +0 -0
  41. package/examples/qahwa/features/order/screens/010-menu.html +1 -1
  42. package/examples/qahwa/features/order/screens/020-drink.html +1 -1
  43. package/examples/qahwa/features/order/screens/030-cart.html +1 -1
  44. package/examples/qahwa/features/order/screens/040-status.html +1 -1
  45. package/examples/qahwa/features/order/screens/050-status-android.html +1 -1
  46. package/examples/qahwa/features/roastery/screens/010-orders.html +1 -1
  47. package/examples/qahwa/features/roastery/screens/020-menu-editor.html +1 -1
  48. package/examples/spa-demo/app/index.html +1 -1
  49. package/examples/tokens-lab/features/lab/screens/010-swatches.html +1 -1
  50. package/examples/tokens-lab/features/lab/screens/020-typography.html +1 -1
  51. package/mcp/server.js +4 -2
  52. package/package.json +7 -6
  53. package/shell/screenhost.js +4 -1
  54. package/shell/selftest.js +18 -2
  55. package/shell/shell.css +17 -9
  56. package/shell/store.js +2 -0
  57. package/skill/SKILL.md +1 -1
  58. package/skill/references/cli-mcp.md +1 -1
  59. package/skill/references/screen-contract.md +1 -1
  60. package/docs/getting-started.md +0 -88
  61. package/docs/shots/app-mode.png +0 -0
  62. package/docs/shots/hero-studio.png +0 -0
  63. package/docs/shots/rtl-arabic.png +0 -0
  64. package/docs/shots/theme-lab.png +0 -0
  65. package/docs/shots/theming-noir.png +0 -0
  66. package/docs/shots/web-dashboard.png +0 -0
package/AGENTS.md ADDED
@@ -0,0 +1,147 @@
1
+ # ScreenBook — authoring contract (for AI agents and humans)
2
+
3
+ > **Read `brief.md` (next to this file) FIRST** — it holds the product requirements this
4
+ > prototype must serve. When the brief and an instruction conflict, ask via a review
5
+ > comment instead of guessing.
6
+
7
+ You are authoring **screens, mock data, themes, strings and flows** for a ScreenBook
8
+ prototype. Everything you touch lives in this `.screenbook/` folder — the project's design
9
+ source of truth. You never need to read or edit ScreenBook's own runtime; everything you
10
+ can do is defined here (and available as MCP tools).
11
+
12
+ ## What this is
13
+
14
+ ScreenBook is a local, no-build prototype studio. `screenbook serve` (run in the project)
15
+ renders these files as a navigable, device-framed gallery with data scenarios, themes,
16
+ dark/RTL toggles, guided flows, review comments and a self-test.
17
+
18
+ ## Layout (paths below are relative to `.screenbook/`)
19
+
20
+ ```
21
+ brief.md ← the requirements. Read first, always.
22
+ app.config.json product name, feature order, devices, themes, languages
23
+ AGENTS.md this contract (CLAUDE.md is just a pointer here)
24
+ themes/default.json design tokens (light + dark) → CSS variables
25
+ features/<feature-id>/
26
+ feature.json { id, title, icon, description, order, group? }
27
+ manifest.json DERIVED index — never edit; regenerate via CLI/MCP
28
+ flows.json guided walkthroughs (optional)
29
+ i18n.json strings for Engine.t (optional, key-first)
30
+ data/seed.json the feature's mock data
31
+ data/scenarios.json named overlays over the seed
32
+ screens/
33
+ shared.css / shared.js optional feature-wide look/helpers (opt-in per screen)
34
+ 010-home.html one file = one screen; numeric prefix orders the sidebar
35
+ review/comments.json pinned human feedback — read, fix, resolve
36
+ ```
37
+
38
+ ## The screen contract
39
+
40
+ ```html
41
+ <!DOCTYPE html>
42
+ <html lang="en">
43
+ <head>
44
+ <meta charset="UTF-8">
45
+ <meta name="viewport" content="width=device-width, initial-scale=1">
46
+ <title>Home</title>
47
+ <script type="application/json" id="screen-meta">
48
+ { "title": "Home", "description": "Entry point.", "order": 10,
49
+ "device": "ios", "status": "draft", "tags": ["core"] }
50
+ </script>
51
+ <script src="../../../screenbook/bridge.js"></script>
52
+ </head>
53
+ <body>
54
+ <button data-go="020-detail">Open detail</button>
55
+ <script>
56
+ Engine.ready(function (data) { /* seed ⊕ active scenario, dates resolved */ });
57
+ </script>
58
+ </body>
59
+ </html>
60
+ ```
61
+
62
+ Rules:
63
+ - The meta block is **required** (`title` at minimum). `device`: `ios` 393×852 ·
64
+ `android` 412×915 · `web` 1280×760 · `none`. Optional: `devices` (variant array — one
65
+ screen rendered in several frames), `status` (draft/wip/ready/review), `tags`, `group`
66
+ (sidebar section), `statusBar` (`light`|`dark` ink override for full-bleed art),
67
+ `updated` (auto-stamped on save; manual override kept).
68
+ - Exactly one runtime include: `<script src="../../../screenbook/bridge.js"></script>`.
69
+ - Style with theme tokens (`var(--color-accent)`, `--font-*`, `--radius-*`, `--space-*`)
70
+ and pad with `var(--safe-top)` / `var(--safe-bottom)` — never draw device hardware.
71
+ - Screens must render sensibly with **empty** data and state; guard every binding.
72
+ - Sheets/modals live INSIDE the screen that opens them, as hidden markup.
73
+ - Markup duplication across screens is normal; shared look goes in `shared.css`/`shared.js`.
74
+ - CDN libraries are allowed; zero-JS screens are allowed.
75
+
76
+ ## The bridge API (inside screens)
77
+
78
+ | API | Behavior |
79
+ |-----|----------|
80
+ | `Engine.ready(cb)` | `cb(data)` after tokens + data injected. |
81
+ | `Engine.data` | Frozen seed ⊕ scenario; `{{today±N}}` date tokens resolved. |
82
+ | `Engine.state` | Cross-screen KV: `get/set/subscribe/keys`; shell has a reset. |
83
+ | `Engine.go(id)` / `data-go` | Navigate within the feature. |
84
+ | `Engine.t(key, {vars})` | Strings from `i18n.json` — lang → default → key; `{name}` interpolation. Language switches reload the screen. |
85
+ | `Engine.toast(msg)` | Transient toast. |
86
+ | `Engine.env` | `{ mode, dir, lang, device, scenario, theme }`; mirrored on `<html>` attributes. |
87
+
88
+ ## Data scenarios · themes · strings · flows
89
+
90
+ - **Scenarios** (`data/scenarios.json`): `{ "list": [{ id, icon, title, description,
91
+ patch?, remove? }] }` — `remove` deletes dot-paths, then `patch` deep-merges (arrays
92
+ replace). Keep an `id:"default"`. Model lifecycle states from the brief.
93
+ - **Themes** (`themes/<id>.json`): `{ modes: { light: {color/font/radius/space}, dark: {…} } }`
94
+ — flattened to CSS vars (`color.ink-2` → `--color-ink-2`); dark is a delta. Humans edit
95
+ live in the 🎨 Theme Lab — re-read theme files before changing them.
96
+ - **Strings** (`i18n.json`, optional): key-first — `{ "slide1.title": { "en": "…",
97
+ "ar": "…" } }`. Missing translations are validate WARNINGS, never blockers.
98
+ - **Flows** (`flows.json`): `{ "list": [{ id, title, icon, description,
99
+ steps: [{ screen, note?, scenario? }] }] }` — presenter-voice notes, 3–7 steps.
100
+
101
+ ## Embedded apps (app mode)
102
+
103
+ `"type": "app"` features embed a whole single-page app: `src` (use `project/<path>` for
104
+ files in the user's project), `device`, `chrome: "self"|"engine"`, optional injected
105
+ `driver.js` for sealed apps (`AppBridge.register({screens, go, current?, set?,
106
+ scenarios?})`). Register via `screenbook app add <src>` or the `add_app` tool.
107
+
108
+ ## Review comments
109
+
110
+ Humans pin comments in the studio; each carries screen, scenario, theme, mode, direction
111
+ and the clicked element's CSS path. Workflow: `get_review_comments {unresolvedOnly:true}`
112
+ → fix the screens → `resolve_comment`. Never delete comments.
113
+
114
+ ## Doing the work
115
+
116
+ Prefer the MCP tools — they lint the contract, stamp dates, regenerate manifests, and
117
+ write atomically: `list_features · list_screens · get_screen · add_screen · update_screen ·
118
+ remove_screen · add_feature · add_app · get_data · set_data · get_theme · set_theme ·
119
+ get_flows · set_flows · get_review_comments · resolve_comment · validate · screenshot`.
120
+
121
+ Editing files directly is fine too; afterwards run `screenbook manifest` and validate.
122
+
123
+ **Definition of done: `screenbook validate` is GREEN** — zero static errors, every screen
124
+ renders in every theme × light/dark × LTR/RTL with zero console errors, embedded apps
125
+ survive a visit to every screen. Check unresolved review comments too.
126
+
127
+ Hard rules: never edit `manifest.json` (derived) · never edit ScreenBook's runtime ·
128
+ never rename a screen that others `data-go` to without fixing references + flows.
129
+
130
+ ## Connect your agent (MCP — 18 tools)
131
+
132
+ ```bash
133
+ # Claude Code
134
+ claude mcp add screenbook -- npx -y @cs4alhaider/screenbook mcp --root .
135
+
136
+ # Codex CLI — ~/.codex/config.toml
137
+ [mcp_servers.screenbook]
138
+ command = "npx"
139
+ args = ["-y", "@cs4alhaider/screenbook", "mcp", "--root", "."]
140
+
141
+ # Cursor — .cursor/mcp.json
142
+ { "mcpServers": { "screenbook": {
143
+ "command": "npx", "args": ["-y", "@cs4alhaider/screenbook", "mcp", "--root", "."] } } }
144
+
145
+ # Gemini CLI
146
+ gemini mcp add screenbook npx -- -y @cs4alhaider/screenbook mcp --root .
147
+ ```
package/CLAUDE.md CHANGED
@@ -1,185 +1,5 @@
1
- # ScreenBook — authoring contract
1
+ # ScreenBook
2
2
 
3
- > This file ships with ScreenBook and is scaffolded into consumer projects by `init` (it is the
4
- > contract from EN-22/EN-32). You are authoring **screens, data, themes and flows** for a
5
- > ScreenBook prototype project. You never need to read or edit anything under `engine/` —
6
- > everything you can do is defined here. Engine developers: see `engine/ENGINE-BRIEF.md` instead.
7
-
8
- ## What this is
9
-
10
- ScreenBook is a static, no-build prototype studio. A project is just folders of standalone HTML
11
- screens plus JSON files. The shell (`engine/index.html`) turns them into a navigable,
12
- device-framed gallery with data scenarios, themes, dark/RTL toggles, guided flows, review
13
- comments and a self-test.
14
-
15
- ## Project layout (convention over configuration)
16
-
17
- ```
18
- app.config.json ← name, features order, devices, themes, languages
19
- themes/default.json ← design tokens (light + dark), flattened to CSS vars
20
- features/<feature-id>/
21
- feature.json ← { id, title, icon, description, order }
22
- manifest.json ← DERIVED index — never edit; CLI/MCP regenerates it
23
- flows.json ← named walkthroughs: { list: [{id, title, icon, steps: […]}] }
24
- data/seed.json ← mock data for the feature
25
- data/scenarios.json ← named overlays over the seed (empty states, mid-trip, …)
26
- screens/
27
- shared.css / shared.js ← optional feature-wide look/helpers (screens opt in per file)
28
- 010-home.html ← one file = one screen; numeric prefix = sidebar order fallback
29
- review/comments.json ← Review-Mode pins from humans (read them, fix, resolve)
30
- engine/ ← the studio itself — NEVER edit
31
- ```
32
-
33
- ## The screen contract (the whole truth in one file)
34
-
35
- ```html
36
- <!DOCTYPE html>
37
- <html lang="en">
38
- <head>
39
- <meta charset="UTF-8">
40
- <meta name="viewport" content="width=device-width, initial-scale=1">
41
- <title>Home</title>
42
- <script type="application/json" id="screen-meta">
43
- {
44
- "title": "Trips home",
45
- "description": "Entry point — active trip hero, drafts, memories.",
46
- "order": 10,
47
- "device": "ios",
48
- "status": "draft",
49
- "tags": ["core"]
50
- }
51
- </script>
52
- <script src="../../../engine/bridge.js"></script>
53
- </head>
54
- <body>
55
- <button data-go="020-wizard">Plan a trip</button>
56
- <script>
57
- Engine.ready(function (data) { /* seed ⊕ active scenario, dates resolved */ });
58
- </script>
59
- </body>
60
- </html>
61
- ```
62
-
63
- Rules:
64
- - The meta block is **required** (`title` at minimum) — the self-test fails without it.
65
- `device`: `ios` (393×852) · `android` (412×915) · `web` (1280×760) · `none` (bare).
66
- Optional: `devices` (variant array, e.g. `["ios","android"]` — one file rendered in each
67
- listed frame; self-test covers all of them), `status` (draft/wip/ready/review), `tags`,
68
- `group` (sidebar section), `statusBar` (`light`|`dark` — overrides status-bar/home-bar
69
- ink on full-bleed art), `updated` (stamped automatically on save; manual override kept).
70
- - Exactly one bridge include: `<script src="../../../engine/bridge.js"></script>`.
71
- - Screens must render sensibly with **empty** `Engine.data` and `Engine.state`.
72
- - Static screens with zero JS are perfectly legal.
73
- - Sheets/modals live **inside** the screen that opens them (hidden markup until triggered).
74
- - Markup duplication across screens is normal — there is no templating system. Shared look
75
- goes in `screens/shared.css` + `shared.js`, included explicitly per screen.
76
- - Screens may pull any library via CDN (`<script src="https://…">`) — iframe isolation makes
77
- that safe. Keep it inside the screen.
78
- - Never draw device hardware (status bar, notch, home bar) — the shell's frame owns it.
79
- Pad with `var(--safe-top)` / `var(--safe-bottom)` instead.
80
-
81
- ## Bridge API (everything a screen can use)
82
-
83
- | API | Behavior |
84
- |-----|----------|
85
- | `Engine.ready(cb)` | `cb(data)` after theme + data are injected. Late registration still fires. |
86
- | `Engine.data` | Frozen merged mock data: seed ⊕ active scenario, `{{today±N}}` resolved. |
87
- | `Engine.state` | Shared KV across screens: `get(k, fallback)` / `set(k, v)` / `subscribe(k, cb)` / `keys()`. Survives screen switches; shell has a reset button. |
88
- | `Engine.go(id)` / `data-go="id"` | Navigate to a sibling screen. Standalone fallback: plain `<id>.html` link. |
89
- | `Engine.toast(msg)` | Transient toast inside the frame. |
90
- | `Engine.env` | `{ mode, dir, lang, device, scenario, theme, embedded }`. |
91
- | `Engine.meta` | This screen's parsed meta block. |
92
- | CSS vars | Active theme flattened to `--color-*`, `--font-*`, `--radius-*`, `--space-*` on `:root`, plus `--safe-top` / `--safe-bottom`. The bridge also sets `data-mode="light|dark"`, `data-device`, `dir`, `lang` on `<html>`. |
93
-
94
- Dark mode: style with tokens and they flip automatically; for bespoke dark rules use
95
- `html[data-mode="dark"] .thing { … }`. RTL: layout flips via `dir` — use logical CSS
96
- (`margin-inline-start`, `inset-inline-end`) instead of left/right when possible.
97
-
98
- Opened standalone (no shell), a screen self-loads the default theme + seed and accepts
99
- `?scenario=…&mode=dark&dir=rtl&lang=ar&theme=…` query params.
100
-
101
- ## Data scenarios (`data/scenarios.json`)
102
-
103
- ```json
104
- { "list": [
105
- { "id": "default", "icon": "🧪", "title": "Full demo", "description": "Baseline seed." },
106
- { "id": "new-user", "icon": "🆕", "title": "Brand-new user",
107
- "remove": ["trips"], "patch": { "user": { "isNew": true } } } ] }
108
- ```
109
-
110
- `patch` deep-merges over the seed (arrays replace), `remove` deletes dot-paths first.
111
- Date tokens `{{today}}`, `{{today+3}}`, `{{today-2}}` resolve to real ISO dates at injection —
112
- "mid-trip today" is literally today. Always keep a `default` entry.
113
-
114
- ## Themes (`themes/<id>.json`)
115
-
116
- ```json
117
- { "id": "default", "title": "Warm",
118
- "modes": {
119
- "light": { "color": { "accent": "#BF5B24", "bg": "#F7F2EA", "ink": "#241C13", "ink-2": "#6E6152" },
120
- "font": { "sans": "-apple-system, sans-serif" }, "radius": { "card": "20px" } },
121
- "dark": { "color": { "accent": "#E1793B", "bg": "#171108", "ink": "#F4EBDD" } } } }
122
- ```
123
-
124
- Flattening: `color.ink-2` → `--color-ink-2` (nested paths join with `-`). `dark` deep-merges
125
- over `light`, so only list what changes. Style screens **with tokens**, not hard-coded colors,
126
- and the whole project can be re-themed from JSON — humans do exactly that in the shell's
127
- 🎨 **Theme Lab** (live token editing; Save writes `themes/<id>.json` under `engine serve`),
128
- so a theme file may change without an agent touching it. Re-read before editing.
129
-
130
- ## Strings (`i18n.json` + `Engine.t`) — optional per feature
131
-
132
- Key-first: `{ "slide1.title": { "en": "…", "ar": "…" } }`. Screens call
133
- `Engine.t('slide1.title')` (placeholders: `Engine.t('greet', {name})`). Fallback: active
134
- language → `defaultLanguage` → the key. Language switches reload the screen, so ready-time
135
- binding is always right. Missing translations are validate WARNINGS, never blockers.
136
- Features without i18n.json simply own their text inline — also fine.
137
-
138
- ## Flows (`flows.json`)
139
-
140
- ```json
141
- { "list": [ { "id": "create-trip", "title": "Create a trip", "icon": "✨",
142
- "description": "From empty home to a planned trip.",
143
- "steps": [
144
- { "screen": "010-home", "note": "Start here — empty state invites planning." },
145
- { "screen": "020-wizard", "note": "Seven questions.", "scenario": "new-user" } ] } ] }
146
- ```
147
-
148
- The shell plays these as guided stakeholder walkthroughs (prev/next + note captions).
149
- A step may pin a `scenario` (and `mode`). Steps must reference existing screens.
150
-
151
- ## Embedded apps (app mode)
152
-
153
- A feature with `"type": "app"` embeds a WHOLE single-page app: `src` (project-relative entry
154
- HTML), `device`, `chrome: "self"|"engine"` (self = the app draws its own status bars), and
155
- optionally `driver: "driver.js"` — a project-owned script injected into the app that calls
156
- `AppBridge.register({screens, go, current?, set?, scenarios?})` so sealed apps stay untouched.
157
- Cooperative apps include `engine/app-bridge.js` themselves. Register via CLI
158
- (`screenbook app add <src>`) or MCP (`add_app`). Full contract: the skill's
159
- `references/app-mode.md`. Validation boots the app and visits every reported screen.
160
-
161
- ## Review comments
162
-
163
- Humans pin comments on screens in Review Mode; they land in `review/comments.json` with full
164
- context (screen, scenario, theme, mode, dir, CSS path of the clicked element). Workflow:
165
- read them (`get_review_comments`), fix the screens, then `resolve_comment` — don't delete.
166
-
167
- ## Doing the work
168
-
169
- Prefer the MCP tools (`add_screen`, `update_screen`, `set_data`, `validate`, `screenshot`, …) —
170
- they validate the contract, stamp `updated`, regenerate manifests and write atomically.
171
- Editing screen files directly is fine too; afterwards run:
172
-
173
- ```
174
- node engine/cli/screenbook.js manifest # rescan → manifest.json
175
- node engine/cli/screenbook.js validate # static checks + headless render of every screen
176
- ```
177
-
178
- While `node engine/cli/screenbook.js serve` runs (http://127.0.0.1:4600), every save
179
- live-reloads the browser and manifests regenerate automatically — no cache-busting, ever.
180
-
181
- **Definition of done: `validate` is green** — zero static errors, every screen renders in
182
- every theme × light/dark × ltr/rtl with zero console errors. Check review comments too.
183
-
184
- Hard rules: never edit `manifest.json` (derived) · never edit `engine/` · never rename a
185
- screen that other screens `data-go` to (or fix the references + flows in the same change).
3
+ The authoring contract for this prototype lives in **[AGENTS.md](AGENTS.md)** (same
4
+ folder) read that, plus **brief.md** for the product requirements, before creating or
5
+ changing any screen.