openink 0.1.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 (52) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE +21 -0
  3. package/README.md +164 -0
  4. package/bin/openink.js +4 -0
  5. package/docs/ai-assistants.md +35 -0
  6. package/docs/architecture.md +50 -0
  7. package/docs/blocks.md +604 -0
  8. package/docs/extending.md +86 -0
  9. package/docs/getting-started.md +97 -0
  10. package/docs/spec.md +215 -0
  11. package/package.json +38 -0
  12. package/schema/spec.schema.json +2641 -0
  13. package/src/build.js +82 -0
  14. package/src/cli.js +133 -0
  15. package/src/dev.js +53 -0
  16. package/src/export.js +68 -0
  17. package/src/icons.js +47 -0
  18. package/src/index.js +14 -0
  19. package/src/render/blocks/actions.js +68 -0
  20. package/src/render/blocks/content.js +86 -0
  21. package/src/render/blocks/data.js +24 -0
  22. package/src/render/blocks/feedback.js +29 -0
  23. package/src/render/blocks/forms.js +86 -0
  24. package/src/render/blocks/index.js +42 -0
  25. package/src/render/blocks/layout.js +102 -0
  26. package/src/render/blocks/media.js +65 -0
  27. package/src/render/blocks/navigation.js +67 -0
  28. package/src/render/blocks/overlay.js +18 -0
  29. package/src/render/blocks/shared.js +20 -0
  30. package/src/render/blocks/text.js +49 -0
  31. package/src/render/context.js +63 -0
  32. package/src/render/page.js +76 -0
  33. package/src/runtime/chart.js +85 -0
  34. package/src/runtime/dom.js +21 -0
  35. package/src/runtime/i18n.js +24 -0
  36. package/src/runtime/icon.js +28 -0
  37. package/src/runtime/index.js +64 -0
  38. package/src/runtime/navigation.js +27 -0
  39. package/src/runtime/placeholder.js +88 -0
  40. package/src/spec/docs.js +65 -0
  41. package/src/spec/schema.js +110 -0
  42. package/src/spec/validate.js +219 -0
  43. package/src/styles/openink.css +250 -0
  44. package/src/styles/themes/blueprint.css +31 -0
  45. package/src/styles/themes/color.css +28 -0
  46. package/src/styles/themes/dark.css +31 -0
  47. package/src/styles/themes/pastel.css +26 -0
  48. package/src/themes.js +10 -0
  49. package/templates/starter/AGENTS.md +18 -0
  50. package/templates/starter/README.md +11 -0
  51. package/templates/starter/gitignore +3 -0
  52. package/templates/starter/spec.yaml +55 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses [Semantic Versioning](https://semver.org/).
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [0.1.0]
8
+
9
+ First release.
10
+
11
+ - `openink` CLI: `init`, `build`, `dev` (live reload), `validate`, `pdf`, `png`, `blocks`; `--theme` to try a theme.
12
+ - YAML spec with 48 block types across layout, text, content, media, forms, actions, navigation, feedback, overlays and data.
13
+ - New blocks beyond the basics: `icon` (37 hand-drawn icons, also on buttons, nav and tab-bar items), `avatar`, `hero`, `stat`,
14
+ `rating`, `link`, `video`, `carousel`, `dropzone`, `chart` (line, area, bar, pie, donut), `search`, `alert`, `progress`,
15
+ `breadcrumb`, `pagination`, `steps`, `tabbar`, `accordion`, `device` (phone / tablet / browser frames), `modal`.
16
+ - Colour: themes (`sketch`, `color`, `pastel`, `blueprint`, `dark`), `colors:` token overrides, and `tone:` / `fill:` on any block or screen.
17
+ - Global `modals:` list, opened from any screen with `open:` and closed with `close:`, the X, Escape or a click outside.
18
+ - Hand-drawn look from wired-elements and RoughJS; image, map and generic placeholders.
19
+ - Optional multi-language prototypes (`languages:` + `{ en, de }` text values).
20
+ - Named header nav sets per screen, sticky-note annotations, custom theme CSS, assets folder, screen widths, YAML anchors via `x-*` keys.
21
+ - Spec validation with paths, "did you mean" hints and dead-link detection.
22
+ - JSON Schema (`openink/schema.json`) for editor autocomplete, generated from the block registry.
23
+ - PDF export (one screen per page) and per-screen PNG export.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Open Ink contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ <h1 align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="assets/logo-white.svg">
4
+ <img src="assets/logo-black.svg" alt="Open Ink" width="340">
5
+ </picture>
6
+ </h1>
7
+
8
+ <p align="center"><strong>Describe screens in YAML. Get a clickable, hand-drawn wireframe prototype.</strong></p>
9
+
10
+ Static HTML you can host or open from disk, plus PDF and PNG export. Built on [wired-elements](https://github.com/rough-stuff/wired-elements) and [RoughJS](https://github.com/rough-stuff/rough), so it looks like a sketch and nobody mistakes it for the final design. Keep it plain pencil, or turn on colour for a whole project or just one part.
11
+
12
+ <p>
13
+ <img src="docs/img/photo-feed.png" width="32%" alt="Photo-sharing app: feed with stories, carousel and action icons" />
14
+ <img src="docs/img/photo-mobile.png" width="32%" alt="The same feed inside a phone frame with a tab bar" />
15
+ <img src="docs/img/saas-overview.png" width="32%" alt="SaaS dashboard in the colour theme with stats and charts" />
16
+ </p>
17
+
18
+ ```yaml
19
+ name: Shop
20
+ theme: color # optional: sketch (default) | color | pastel | blueprint | dark
21
+ nav:
22
+ - { icon: home, label: Home, go: home }
23
+ screens:
24
+ - id: home
25
+ title: Home
26
+ blocks:
27
+ - { type: h1, text: Welcome }
28
+ - type: card
29
+ go: product # click → opens the product screen
30
+ children:
31
+ - { type: image, h: 120, label: Photo }
32
+ - { type: h3, text: Blue shirt }
33
+ - { type: rating, value: 4, text: (128 reviews) }
34
+ - id: product
35
+ title: Product
36
+ blocks:
37
+ - { type: button, label: Add to cart, icon: cart, primary: true, open: added }
38
+ modals:
39
+ - id: added
40
+ title: Added to cart
41
+ children:
42
+ - { type: button, label: Keep shopping, close: true, go: home }
43
+ ```
44
+
45
+ ## Why
46
+
47
+ - **Fast to write and change.** A screen is a dozen lines of YAML, not a page of HTML or an hour in a design tool.
48
+ - **Clickable.** Buttons, cards, table rows, tab bars and nav items link between screens; forms, tabs, accordions, modals, chips and toggles respond, so stakeholders can walk through a flow.
49
+ - **Looks like a sketch on purpose.** Feedback goes to structure and flow, not fonts and pixels.
50
+ - **Colour when you want it.** Themes for a whole project, `tone: pink` for one card, `fill: true` for a tinted panel.
51
+ - **Safe for AI to write.** Generate a spec with an assistant; `validate` catches typos, dead links and bad icon names with exact locations. See [docs/ai-assistants.md](docs/ai-assistants.md).
52
+ - **Easy to share.** One static folder, one PDF, or one PNG per screen. Multi-language prototypes are built in.
53
+
54
+ ## Quick start
55
+
56
+ ```bash
57
+ npx openink init my-wireframes
58
+ cd my-wireframes
59
+ npx openink dev # live preview at http://localhost:3000
60
+ ```
61
+
62
+ ```bash
63
+ npx openink validate # check the spec
64
+ npx openink build # static site → dist/
65
+ npx openink pdf # dist/<name>.pdf, one screen per page
66
+ npx openink png # dist/png/<screen>.png
67
+ npx openink blocks # list every block and its props
68
+ npx openink dev --theme dark # try a colour theme without editing the spec
69
+ ```
70
+
71
+ Or install it once and drop the `npx`:
72
+
73
+ ```bash
74
+ npm install -g openink
75
+ openink dev
76
+ ```
77
+
78
+ Requires Node 20+. PDF and PNG export need Chrome, Chromium or Edge installed (set `CHROME_PATH` if it isn't found).
79
+
80
+ ## What you can draw
81
+
82
+ 48 blocks in 10 groups; see the [block reference](docs/blocks.md) and the [gallery example](examples/gallery), which shows every one.
83
+
84
+ | | |
85
+ |---|---|
86
+ | **Layout** | `stack` `row` `grid` `card` `accordion` `device` (phone / tablet / browser frame) `divider` `spacer` |
87
+ | **Text** | `h1` `h2` `h3` `text` `list` `note` `badge` |
88
+ | **Content** | `icon` (37 hand-drawn icons) `avatar` `hero` `stat` `rating` `link` |
89
+ | **Media** | `image` `map` `video` `carousel` `dropzone` `box` `chart` (line, area, bar, pie, donut) |
90
+ | **Forms** | `input` `search` `textarea` `select` `checkbox` `toggle` `radio` `slider` |
91
+ | **Actions** | `button` (with icon) `chips` `tabs` `nextbar` |
92
+ | **Navigation** | `breadcrumb` `pagination` `steps` `tabbar` |
93
+ | **Feedback** | `alert` `progress` |
94
+ | **Overlays** | `modal` (global, opened from any screen) |
95
+ | **Data** | `table` |
96
+
97
+ <p>
98
+ <img src="docs/img/gallery-media.png" width="49%" alt="Media blocks and hand-drawn charts" />
99
+ <img src="docs/img/gallery-colours.png" width="49%" alt="Nine tones on cards" />
100
+ </p>
101
+
102
+ ## Colour
103
+
104
+ Plain pencil is the default. Colour is opt-in, at three levels:
105
+
106
+ | Level | How |
107
+ |---|---|
108
+ | Whole project | `theme: color \| pastel \| blueprint \| dark` and `colors: { accent: "#f97316" }` |
109
+ | One screen | `tone: blue` on the screen |
110
+ | One part | `tone: red` and `fill: true` on any block, e.g. only the "Delete" button, or a highlighted card |
111
+
112
+ <table>
113
+ <tr>
114
+ <td><img src="docs/img/theme-sketch.png" alt="sketch theme" /><br /><sub><code>sketch</code> (default)</sub></td>
115
+ <td><img src="docs/img/theme-color.png" alt="color theme" /><br /><sub><code>color</code></sub></td>
116
+ <td><img src="docs/img/theme-pastel.png" alt="pastel theme" /><br /><sub><code>pastel</code></sub></td>
117
+ </tr>
118
+ <tr>
119
+ <td><img src="docs/img/theme-blueprint.png" alt="blueprint theme" /><br /><sub><code>blueprint</code></sub></td>
120
+ <td><img src="docs/img/theme-dark.png" alt="dark theme" /><br /><sub><code>dark</code></sub></td>
121
+ <td></td>
122
+ </tr>
123
+ </table>
124
+
125
+ Details: [docs/spec.md#colour](docs/spec.md#colour).
126
+
127
+ ## Examples
128
+
129
+ | Example | Shows |
130
+ |---|---|
131
+ | [`photo-sharing`](examples/photo-sharing) | 17 screens: feed, stories, reels, explore, messages, profile, a phone-frame mobile view, global modals, and colour on only a few parts |
132
+ | [`saas-admin`](examples/saas-admin) | The `color` theme: stat cards, area/bar/donut charts, tables, an invite modal |
133
+ | [`rental-portal`](examples/rental-portal) | Two languages and two header nav sets (public vs owner) |
134
+ | [`gallery`](examples/gallery) | Every block on one screen per family; try it with `--theme dark` |
135
+
136
+ ```bash
137
+ npx openink dev examples/photo-sharing
138
+ ```
139
+
140
+ ## Documentation
141
+
142
+ - [Getting started](docs/getting-started.md)
143
+ - [Spec reference](docs/spec.md): screens, colour, modals, navigation, languages, icons
144
+ - [Block reference](docs/blocks.md)
145
+ - [Working with AI assistants](docs/ai-assistants.md)
146
+ - [Extending](docs/extending.md): add a block, change the look, use the API
147
+ - [Architecture](docs/architecture.md)
148
+
149
+ ## Use it from code
150
+
151
+ ```js
152
+ import { build, validate, exportFiles } from "openink";
153
+
154
+ await build({ dir: "./my-project", out: "dist", theme: "dark" });
155
+ await exportFiles({ dir: "./my-project", png: true });
156
+ ```
157
+
158
+ ## Contributing
159
+
160
+ Issues and pull requests are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). Adding a block is one object in `src/render/blocks/`.
161
+
162
+ ## License
163
+
164
+ [MIT](LICENSE)
package/bin/openink.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "../src/cli.js";
3
+
4
+ main();
@@ -0,0 +1,35 @@
1
+ # Working with AI assistants
2
+
3
+ Open Ink is designed so that an assistant (Claude Code, Cursor, Copilot, ChatGPT…) can turn a description into a prototype **without writing HTML**:
4
+
5
+ > "Wireframe a marketplace for used bikes: search with filters, listing page with a contact form, seller dashboard."
6
+
7
+ The assistant writes `spec.yaml`, the tool checks it, and you get a consistent hand-drawn result. Because the spec is small and validated, it is cheap to iterate: "add a second tab to the listing page" is a five-line diff.
8
+
9
+ ## How it works
10
+
11
+ `openink init` puts an `AGENTS.md` in your project. Most assistants read it automatically; it tells them to:
12
+
13
+ 1. Run `npx openink blocks` to learn the available blocks.
14
+ 2. Edit `spec.yaml` only.
15
+ 3. Run `npx openink validate` and fix what it reports.
16
+ 4. Run `npx openink png` and look at `dist/png/*.png` to check the layout.
17
+
18
+ If your assistant uses a different filename (`CLAUDE.md`, `.cursorrules`, …), copy or rename `AGENTS.md`.
19
+
20
+ ## Why validation matters here
21
+
22
+ Assistants make small mistakes: a misspelt prop, a link to a screen they renamed, a translation missing in one language. `validate` reports each with its exact location in the spec and a "did you mean" hint, so the fix-and-retry loop is short and mechanical:
23
+
24
+ ```
25
+ ✗ 2 problems in the spec
26
+ error screens[1].blocks[3].type: Unknown block type "buton". Did you mean "button"?
27
+ error screens[0].blocks[0].go: Links to unknown screen "checkout". Did you mean "check-out"?
28
+ ```
29
+
30
+ ## Tips for good prompts
31
+
32
+ - Name the **users** and their **goals**, not the widgets: "a tenant who wants to find a flat in Zurich".
33
+ - Say which **states** matter (empty, error, paid, unpaid); each becomes a screen or a `note:`.
34
+ - Ask for `note:` on anything a sketch can't show ("results update live, there is no search button").
35
+ - Mention languages up front if you need them.
@@ -0,0 +1,50 @@
1
+ # Architecture
2
+
3
+ ```
4
+ spec.yaml ──► load + parse ──► validate ──► render ──► write dist/
5
+ (yaml) (spec/validate) (render/) │
6
+ ├─ index.html (render/page.js)
7
+ ├─ openink.js (runtime/ bundled by esbuild)
8
+ └─ openink.css (styles/)
9
+
10
+ dist/ ──► puppeteer-core + Chrome/Edge ──► PDF / PNG (export.js)
11
+ dist/ ──► http server + fs.watch + reload poller (dev.js)
12
+ ```
13
+
14
+ ## Design decisions
15
+
16
+ **Spec in, static files out.** The prototype is a single HTML page holding every screen; JavaScript only shows one at a time. That makes the output trivially hostable, printable and shareable by link (`#screen-id`), and it works from `file://`.
17
+
18
+ **One definition per block.** `src/render/blocks/` is the single source of truth. The validator, the JSON Schema, `docs/blocks.md` and `openink blocks` are all generated from it, and tests fail when the generated files are stale. Adding a block is one object.
19
+
20
+ **Validate everything, early.** Assistants and humans both make typos. The validator never throws; it returns `{ errors, warnings }` with a path into the spec and a suggestion, and `build` refuses to write output if there are errors.
21
+
22
+ **Bundled runtime.** wired-elements and RoughJS are bundled into `openink.js` at build time, so a prototype has no CDN dependency (except the Google Fonts stylesheet, which falls back to a system cursive font offline).
23
+
24
+ **No framework in the output.** The runtime is about a hundred lines of plain JavaScript plus the web components from wired-elements.
25
+
26
+ ## Layout
27
+
28
+ ```
29
+ bin/openink.js CLI entry
30
+ src/
31
+ cli.js argument parsing, commands, output formatting
32
+ build.js load spec → validate → write dist
33
+ dev.js dev server with live reload
34
+ export.js PDF / PNG via headless Chrome
35
+ index.js public API
36
+ spec/ validate.js, schema.js, docs.js
37
+ render/ context.js, page.js, blocks/*
38
+ runtime/ browser code (navigation, i18n, placeholder, redraw)
39
+ styles/ openink.css
40
+ templates/starter/ copied by `openink init`
41
+ examples/ example projects (also test fixtures and README screenshots)
42
+ test/ node:test suites
43
+ scripts/ generate.js (docs + schema), screenshots.js
44
+ ```
45
+
46
+ ## Known limitations
47
+
48
+ - wired-elements 3.0 is a release candidate and has not been updated for some time. Its dependency on `roughjs` is pinned to 4.3.1 for that reason (see CONTRIBUTING.md).
49
+ - Form controls are visual only; nothing is validated or submitted.
50
+ - One page per project: very large specs (hundreds of screens) load everything up front.