stilo-editor 0.0.0-stage → 0.2.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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -2
  3. package/dist/characters--8h5uTeF.js +854 -0
  4. package/dist/content.css +398 -0
  5. package/dist/core/drop.d.ts +6 -0
  6. package/dist/core/editor.d.ts +120 -0
  7. package/dist/core/errors.d.ts +6 -0
  8. package/dist/core/events.d.ts +19 -0
  9. package/dist/core/extension-manager.d.ts +57 -0
  10. package/dist/core/extension.d.ts +48 -0
  11. package/dist/core/helpers/active.d.ts +33 -0
  12. package/dist/core/helpers/block-style.d.ts +25 -0
  13. package/dist/core/helpers/input-rules.d.ts +28 -0
  14. package/dist/core/helpers/lists.d.ts +20 -0
  15. package/dist/core/helpers/marks.d.ts +52 -0
  16. package/dist/core/helpers/nodes.d.ts +26 -0
  17. package/dist/core/helpers/parse-rules.d.ts +8 -0
  18. package/dist/core/helpers/word-count.d.ts +14 -0
  19. package/dist/core/html/css.d.ts +106 -0
  20. package/dist/core/html/parse.d.ts +7 -0
  21. package/dist/core/html/paste/base-styles.d.ts +7 -0
  22. package/dist/core/html/paste/google-docs.d.ts +7 -0
  23. package/dist/core/html/paste/index.d.ts +9 -0
  24. package/dist/core/html/paste/table-widths.d.ts +7 -0
  25. package/dist/core/html/paste/word.d.ts +8 -0
  26. package/dist/core/html/sanitize.d.ts +49 -0
  27. package/dist/core/html/serialize.d.ts +31 -0
  28. package/dist/core/types.d.ts +107 -0
  29. package/dist/extensions/blockquote/index.d.ts +15 -0
  30. package/dist/extensions/bold/index.d.ts +17 -0
  31. package/dist/extensions/bullet-list/index.d.ts +9 -0
  32. package/dist/extensions/clear-formatting/index.d.ts +12 -0
  33. package/dist/extensions/code/index.d.ts +15 -0
  34. package/dist/extensions/code-block/index.d.ts +24 -0
  35. package/dist/extensions/default-extensions/index.d.ts +57 -0
  36. package/dist/extensions/document/index.d.ts +17 -0
  37. package/dist/extensions/drop-cursor/index.d.ts +15 -0
  38. package/dist/extensions/gap-cursor/index.d.ts +6 -0
  39. package/dist/extensions/hard-break/index.d.ts +11 -0
  40. package/dist/extensions/heading/index.d.ts +25 -0
  41. package/dist/extensions/highlight/index.d.ts +24 -0
  42. package/dist/extensions/history/index.d.ts +21 -0
  43. package/dist/extensions/horizontal-rule/index.d.ts +11 -0
  44. package/dist/extensions/image/image-view.d.ts +27 -0
  45. package/dist/extensions/image/index.d.ts +29 -0
  46. package/dist/extensions/index.d.ts +36 -0
  47. package/dist/extensions/italic/index.d.ts +16 -0
  48. package/dist/extensions/line-height/index.d.ts +18 -0
  49. package/dist/extensions/link/index.d.ts +23 -0
  50. package/dist/extensions/list-item/index.d.ts +16 -0
  51. package/dist/extensions/move-block/index.d.ts +17 -0
  52. package/dist/extensions/ordered-list/index.d.ts +12 -0
  53. package/dist/extensions/paragraph/index.d.ts +14 -0
  54. package/dist/extensions/placeholder/index.d.ts +13 -0
  55. package/dist/extensions/search/index.d.ts +55 -0
  56. package/dist/extensions/strike/index.d.ts +16 -0
  57. package/dist/extensions/subscript/index.d.ts +16 -0
  58. package/dist/extensions/superscript/index.d.ts +17 -0
  59. package/dist/extensions/table/index.d.ts +70 -0
  60. package/dist/extensions/task-item/index.d.ts +24 -0
  61. package/dist/extensions/task-item/task-item-view.d.ts +24 -0
  62. package/dist/extensions/task-list/index.d.ts +11 -0
  63. package/dist/extensions/text/index.d.ts +12 -0
  64. package/dist/extensions/text-align/index.d.ts +18 -0
  65. package/dist/extensions/text-case/index.d.ts +14 -0
  66. package/dist/extensions/text-style/font-size.d.ts +21 -0
  67. package/dist/extensions/text-style/index.d.ts +30 -0
  68. package/dist/extensions/underline/index.d.ts +15 -0
  69. package/dist/index.d.ts +14 -0
  70. package/dist/index.js +1 -0
  71. package/dist/src-CV6pgfTS.js +2662 -0
  72. package/dist/style.css +1395 -0
  73. package/dist/ui/components/character-picker.d.ts +22 -0
  74. package/dist/ui/components/characters.d.ts +10 -0
  75. package/dist/ui/components/color-button.d.ts +23 -0
  76. package/dist/ui/components/dropdown.d.ts +34 -0
  77. package/dist/ui/components/find-bar.d.ts +24 -0
  78. package/dist/ui/components/font-size-input.d.ts +21 -0
  79. package/dist/ui/components/icon-menu.d.ts +20 -0
  80. package/dist/ui/components/icon.d.ts +3 -0
  81. package/dist/ui/components/link-bubble.d.ts +19 -0
  82. package/dist/ui/components/link-popover.d.ts +20 -0
  83. package/dist/ui/components/popover.d.ts +27 -0
  84. package/dist/ui/components/shortcut.d.ts +11 -0
  85. package/dist/ui/components/status-bar.d.ts +19 -0
  86. package/dist/ui/components/table-actions.d.ts +25 -0
  87. package/dist/ui/components/table-handles.d.ts +16 -0
  88. package/dist/ui/components/table-menu.d.ts +21 -0
  89. package/dist/ui/i18n/en.d.ts +3 -0
  90. package/dist/ui/i18n/it.d.ts +3 -0
  91. package/dist/ui/i18n/types.d.ts +4 -0
  92. package/dist/ui/index.d.ts +23 -0
  93. package/dist/ui/toolbar/fonts.d.ts +8 -0
  94. package/dist/ui/toolbar/items.d.ts +33 -0
  95. package/dist/ui/toolbar/palette.d.ts +6 -0
  96. package/dist/ui/toolbar/toolbar.d.ts +28 -0
  97. package/dist/ui/toolbar/types.d.ts +150 -0
  98. package/dist/ui.css +996 -0
  99. package/dist/ui.js +2350 -0
  100. package/package.json +96 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alessio Coggiola
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 CHANGED
@@ -1,3 +1,227 @@
1
- # Temporary Holding Version
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/logo-dark.svg">
4
+ <img src="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/logo.svg" alt="Stilo" width="300">
5
+ </picture>
6
+ </p>
2
7
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/stilo-editor"><img src="https://img.shields.io/npm/v/stilo-editor" alt="npm version"></a>
10
+ <a href="LICENSE"><img src="https://img.shields.io/npm/l/stilo-editor" alt="MIT license"></a>
11
+ <img src="https://img.shields.io/npm/types/stilo-editor" alt="TypeScript types included">
12
+ </p>
13
+
14
+ Open-source HTML5 WYSIWYG editor built on [ProseMirror](https://prosemirror.net).
15
+ Clean HTML in and out, headless core, no paid tiers.
16
+
17
+ <p align="center">
18
+ <img src="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/screenshot.png" alt="Stilo with the default toolbar: formatted text, a checklist, a table and the link popover open" width="800">
19
+ </p>
20
+
21
+ <h2 align="center">
22
+ <a href="https://kojak8791.github.io/stilo-editor/">See it in action: try the live demo →</a>
23
+ </h2>
24
+
25
+ > [!WARNING]
26
+ > **Preview release.** Versions `0.x` are early previews: the editor works, but APIs may change
27
+ > in any minor version until `1.0.0`. Read the release notes before updating.
28
+
29
+ ## Why Stilo
30
+
31
+ - **Built for very large documents.** Typing stays immediate in a document longer than most
32
+ novels (see [Large documents](https://github.com/kojak8791/stilo-editor#large-documents)).
33
+ Measured in a real browser, checked against budgets, not assumed.
34
+ - **Entirely open source (MIT).** Aiming at the feature level of the established rich text
35
+ editors, with no paid tiers and no closed "pro" extensions.
36
+ - **HTML is the public format.** Content goes in as HTML and comes out as clean, semantic,
37
+ self-contained HTML, with a strict allowlist for tags, attributes and inline styles.
38
+ - **Headless core, optional UI.** The core works without any UI; the default toolbar and menus are
39
+ a separate, replaceable module.
40
+ - **Extensible by design.** Every feature is an extension with the same shape.
41
+ - **Framework-agnostic.** Vanilla TypeScript first; React/Vue wrappers later as thin layers.
42
+
43
+ ## Large documents
44
+
45
+ Stilo is made for long documents: contracts, manuals, books, reports. Typing feels immediate in
46
+ a document of 10,000 paragraphs — about 400,000 words, longer than most novels — and the editor
47
+ stays usable at five times that size, without pagination tricks and without splitting the
48
+ content. Formatting, search and selection keep up with the size of the text.
49
+
50
+ This is measured, not promised. A benchmark drives the editor in a real browser on generated
51
+ documents and times everything from loading and exporting the HTML down to the milliseconds
52
+ between a key press and the character on screen; every change is checked against performance
53
+ budgets. What it means in practice, the numbers and the limits:
54
+ [Performance](docs/PERFORMANCE.md).
55
+
56
+ ## Features
57
+
58
+ What the editor does today, with `defaultExtensions` and the default toolbar. On macOS, use
59
+ <kbd>⌘</kbd> for <kbd>Ctrl</kbd> and <kbd>Option</kbd> for <kbd>Alt</kbd>. The *Markdown*
60
+ column is what you type to get the format as you write.
61
+
62
+ | Feature | Keyboard | Markdown | Notes |
63
+ |---|---|---|---|
64
+ | **Text** | | | |
65
+ | Bold | <kbd>Ctrl</kbd>+<kbd>B</kbd> | `**text**` | |
66
+ | Italic | <kbd>Ctrl</kbd>+<kbd>I</kbd> | `*text*` `_text_` | |
67
+ | Underline | <kbd>Ctrl</kbd>+<kbd>U</kbd> | | |
68
+ | Strikethrough | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>S</kbd> | `~~text~~` | |
69
+ | Inline code | <kbd>Ctrl</kbd>+<kbd>E</kbd> | `` `text` `` | |
70
+ | Subscript | <kbd>Ctrl</kbd>+<kbd>,</kbd> | | Subscript and superscript exclude each other |
71
+ | Superscript | <kbd>Ctrl</kbd>+<kbd>.</kbd> | | |
72
+ | Font family | | | Toolbar dropdown: generic families (sans serif, serif, monospace) and common fonts, each shown in its own font; a font that is not in the list (e.g. pasted from Word) is still shown |
73
+ | Font size | | | − and + change the size by one point; the field between them shows the size, takes a typed one and opens a list. Unit pt by default (px or rem as an option) |
74
+ | Text color | | | The button applies the last color; its arrow opens a palette, "No color" and a custom color |
75
+ | Highlight | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>H</kbd> | `==text==` | Same button as text color; the shortcut applies the default highlight |
76
+ | Clear formatting | <kbd>Ctrl</kbd>+<kbd>\\</kbd> | | Links stay |
77
+ | Text case | | | A menu: UPPERCASE, lowercase, Title Case, Sentence case, tOGGLE cASE; the letters change, the formatting stays |
78
+ | **Links** | | | |
79
+ | Link | <kbd>Ctrl</kbd>+<kbd>K</kbd> | | A popover sets the URL and "open in new tab"; on a link, a small bubble offers open, edit and remove |
80
+ | **Blocks** | | | |
81
+ | Paragraph | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>0</kbd> | | |
82
+ | Headings 1–6 | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>1</kbd>…<kbd>6</kbd> | `# ` … `###### ` | Also in the toolbar dropdown |
83
+ | Quote | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>B</kbd> | `> ` | |
84
+ | Code block | <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>C</kbd> | ```` ``` ```` + space, ```` ```js ```` + space for a language | Plain text in a monospace font, no formatting; the selected paragraphs become one block, a line each, and back. <kbd>Enter</kbd> on an empty last line, or <kbd>Ctrl</kbd>+<kbd>Enter</kbd>, leaves it. The language is written as `class="language-js"` for syntax highlighters |
85
+ | Horizontal line | | `---` | |
86
+ | Line break | <kbd>Shift</kbd>+<kbd>Enter</kbd> | | New line in the same paragraph |
87
+ | Align left / center / right / justify | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>L</kbd> / <kbd>E</kbd> / <kbd>R</kbd> / <kbd>J</kbd> | | Paragraphs and headings; the toolbar button opens the four alignments; changing the block type (also with `# `) keeps the alignment |
88
+ | Line spacing | | | Paragraphs and headings; the toolbar menu offers Default, 1, 1.15, 1.5 and 2; changing the block type keeps it |
89
+ | Move block up / down | <kbd>Alt</kbd>+<kbd>↑</kbd> / <kbd>Alt</kbd>+<kbd>↓</kbd> | | The block or list item at the cursor, or all the selected ones; sub-items move along |
90
+ | **Lists** | | | |
91
+ | Bulleted list | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>8</kbd> | `- ` `* ` `+ ` | |
92
+ | Numbered list | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>7</kbd> | `1. ` | Starts from the number you type |
93
+ | Checklist | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>9</kbd> | `[ ] ` `[x] ` | Click a checkbox, or press <kbd>Ctrl</kbd>+<kbd>Enter</kbd> to check the selected items; checked items are struck through |
94
+ | Indent / outdent item | <kbd>Tab</kbd> / <kbd>Shift</kbd>+<kbd>Tab</kbd> | | |
95
+ | **Tables** | | | |
96
+ | Insert a table | | | Toolbar grid up to 10 × 8, with or without a header row |
97
+ | Rows, columns, cells | | | With the cursor in a table, the same button opens: insert or delete rows and columns, merge and split cells, header row and column, delete table |
98
+ | Table handles | | | Handles on the row and column under the mouse select them and open their menu (insert, delete); a corner handle opens merge, split and delete table |
99
+ | Move between cells | <kbd>Tab</kbd> / <kbd>Shift</kbd>+<kbd>Tab</kbd> | | <kbd>Tab</kbd> in the last cell adds a row |
100
+ | Select cells | | | Drag across cells |
101
+ | Resize a column | | | Drag the border of a column; the width is kept in the HTML |
102
+ | **Images** | | | |
103
+ | Paste an image | <kbd>Ctrl</kbd>+<kbd>V</kbd> | | A copied image or screenshot is embedded in the HTML (PNG, JPEG, GIF, WebP, up to 5 MB by default); an image copied from a web page keeps its address |
104
+ | Resize an image | | | Select it and drag one of its side handles; the proportions stay |
105
+ | **Insert** | | | |
106
+ | Special characters and emoji | | | A popover with search, symbols and emoji; it stays open to insert several in a row |
107
+ | **Editing** | | | |
108
+ | Undo | <kbd>Ctrl</kbd>+<kbd>Z</kbd> | | <kbd>Backspace</kbd> right after a Markdown shortcut undoes it |
109
+ | Redo | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd> or <kbd>Ctrl</kbd>+<kbd>Y</kbd> | | |
110
+ | Paste | <kbd>Ctrl</kbd>+<kbd>V</kbd> | | HTML is cleaned up; plain text lines become paragraphs. From Word and Google Docs the body font, size and color are dropped (text that differs keeps them) and Word lists become real lists; tables keep their column widths |
111
+ | Paste as plain text | <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd> | | Only the text, without formatting |
112
+ | Find and replace | <kbd>Ctrl</kbd>+<kbd>F</kbd> | | A bar under the toolbar: match case, whole word, previous and next match, replace one or all; the matches are counted exactly and the first 1,000 are highlighted; <kbd>Enter</kbd> / <kbd>Shift</kbd>+<kbd>Enter</kbd> go to the next / previous match, <kbd>Esc</kbd> closes it |
113
+ | Word and character count | | | Optional status bar under the editor; also `getWordCount()` in the API |
114
+
115
+ <table>
116
+ <tr>
117
+ <td width="50%"><img src="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/screenshot-find.png" alt="The find bar under the toolbar: five matches of espresso highlighted, the current one in orange, and ristretto in the replace field" width="400"></td>
118
+ <td width="50%"><img src="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/screenshot-table.png" alt="A coffee menu table with a row selected by its handle and the row menu open: insert row above, insert row below, delete row" width="400"></td>
119
+ </tr>
120
+ <tr>
121
+ <td>Find and replace: match case, whole word, an exact count of the matches.</td>
122
+ <td>Tables: handles on rows and columns open their menu.</td>
123
+ </tr>
124
+ <tr>
125
+ <td width="50%"><img src="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/screenshot-fonts.png" alt="The font dropdown open on a Times New Roman text, each font drawn in its own font" width="400"></td>
126
+ <td width="50%"><img src="https://raw.githubusercontent.com/kojak8791/stilo-editor/main/assets/screenshot-color.png" alt="The text color palette open, with No color, the color grid and a custom color field" width="400"></td>
127
+ </tr>
128
+ <tr>
129
+ <td>Fonts and sizes: the toolbar shows the font and the size at the cursor.</td>
130
+ <td>Text color and highlight: a palette, the last color one click away, a custom color.</td>
131
+ </tr>
132
+ </table>
133
+
134
+ **Keyboard and accessibility.** Most shortcuts are the ones of Google Docs; the others follow
135
+ the usual conventions of web editors, and every toolbar tooltip shows its shortcut. The toolbar
136
+ follows the WAI-ARIA *Toolbar* pattern: <kbd>Alt</kbd>+<kbd>F10</kbd> moves the focus from the
137
+ text to the toolbar, the arrow keys move between buttons, <kbd>Esc</kbd> goes back to the text.
138
+ Every popover works with the keyboard alone and <kbd>Esc</kbd> closes it.
139
+
140
+ ## Usage
141
+
142
+ ```sh
143
+ npm install stilo-editor
144
+ ```
145
+
146
+ ```ts
147
+ import 'stilo-editor/style.css';
148
+ import { Editor, defaultExtensions } from 'stilo-editor';
149
+ import { createToolbar } from 'stilo-editor/ui';
150
+
151
+ const editor = new Editor({
152
+ element: document.querySelector<HTMLElement>('#editor')!,
153
+ extensions: [defaultExtensions()],
154
+ content: '<p>Hello <strong>world</strong></p>',
155
+ });
156
+
157
+ createToolbar(editor, { container: document.querySelector<HTMLElement>('#toolbar')! });
158
+
159
+ editor.getHTML(); // '<p>Hello <strong>world</strong></p>'
160
+ ```
161
+
162
+ Options, commands, events, extensions and the toolbar: **[API reference](docs/API.md)**.
163
+ Without the default toolbar, import `stilo-editor/content.css` instead of `style.css` and build
164
+ your own controls on the same API.
165
+
166
+ ## Support
167
+
168
+ - **Bugs and feature requests:** open an
169
+ [issue](https://github.com/kojak8791/stilo-editor/issues/new/choose); the forms ask for what
170
+ is needed to reproduce a bug (steps, Stilo version, browser).
171
+ - **Questions:** open an issue too, with a short title that says what you are trying to do.
172
+ - **Security vulnerabilities:** never in a public issue; report them privately as described in
173
+ [SECURITY.md](SECURITY.md).
174
+
175
+ Contributions are welcome: start from [CONTRIBUTING.md](CONTRIBUTING.md).
176
+
177
+ ## Roadmap
178
+
179
+ | Milestone | Content | Status |
180
+ |---|---|---|
181
+ | M0 — Foundations | Docs, scaffolding, core contracts, HTML pipeline, test helpers, `Bold` reference extension | Done |
182
+ | M1 — MVP | Core editing, history, basic marks and blocks, lists, paste cleanup, default toolbar, demo, benchmarks | Done |
183
+ | M2 — v1.0 | Preview releases `0.x` on npm, then tables, images, fonts and colors, productivity tools up to `1.0.0` | In progress |
184
+ | M3 — Later | Real-time collaboration (Yjs), framework wrappers, embeds | Planned |
185
+
186
+ Full feature list and priorities in [docs/SPEC.md](docs/SPEC.md).
187
+
188
+ ## How it is built
189
+
190
+ Stilo is designed and owned by Alessio Coggiola and developed with AI assistance
191
+ ([Claude](https://claude.com/claude-code)). Every decision is written down before the code
192
+ ([docs/](docs/), [ADRs](docs/decisions/)), every change goes through the quality gate
193
+ (typecheck, lint, about 950 unit tests including XSS vectors) and is tried in the demo before
194
+ it is merged, and performance is measured against explicit budgets (`npm run bench`).
195
+
196
+ | Document | Content |
197
+ |---|---|
198
+ | [API.md](docs/API.md) | API reference for applications |
199
+ | [VISION.md](docs/VISION.md) | Why and what |
200
+ | [SPEC.md](docs/SPEC.md) | Features, non-functional requirements, roadmap |
201
+ | [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Stack, file layout, extension API, HTML contract |
202
+ | [UI.md](docs/UI.md) | Design of the default UI |
203
+ | [PERFORMANCE.md](docs/PERFORMANCE.md) | Performance in practice, how it is measured, limits |
204
+ | [BACKLOG.md](docs/BACKLOG.md) | Tasks done and planned |
205
+ | [AGENTS.md](AGENTS.md) | Rules for contributors and coding agents |
206
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | How to report bugs and propose changes |
207
+ | [SECURITY.md](SECURITY.md) | How to report a vulnerability |
208
+
209
+ ## Development
210
+
211
+ Requires Node.js 22 or later.
212
+
213
+ ```sh
214
+ npm install
215
+ npm run check # typecheck + lint + unit tests
216
+ npm run dev # demo page
217
+ npm run site # public site (published on GitHub Pages from main)
218
+ npm run bench # performance benchmarks (needs: npx playwright install chromium)
219
+ npm run test:e2e # E2E tests in Chromium, Firefox and WebKit (needs: npx playwright install)
220
+ ```
221
+
222
+ ## License
223
+
224
+ [MIT](LICENSE) © 2026 Alessio Coggiola
225
+
226
+ The logo wordmark is drawn from [IBM Plex](https://github.com/IBM/plex), licensed under the
227
+ [SIL Open Font License 1.1](https://openfontlicense.org).