storyink 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +56 -3
- package/THIRD_PARTY_NOTICES.md +7 -0
- package/dist/chunks/{index-1x789mr9.js → index-6h5ajcgs.js} +868 -79
- package/dist/chunks/{index-cbjmgtv7.js → index-b50m4vmv.js} +74 -4
- package/dist/cli.js +938 -89
- package/dist/core/index.js +26 -2
- package/dist/index.js +58 -5
- package/dist/node/index.js +10 -2
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/render/App.d.ts +12 -0
- package/dist/types/core/render/Diagram.d.ts +6 -2
- package/dist/types/core/render/Story.d.ts +2 -1
- package/dist/types/core/render/smil.d.ts +45 -0
- package/dist/types/core/spec.d.ts +10 -1
- package/dist/types/core/story/state.d.ts +32 -0
- package/dist/types/core/story/types.d.ts +8 -0
- package/dist/types/generated/meta.d.ts +1 -1
- package/dist/types/generated/viewer.d.ts +1 -1
- package/dist/types/node/index.d.ts +30 -1
- package/dist/types/node/snapshot.d.ts +18 -0
- package/docs/spec.md +82 -1
- package/package.json +5 -2
- package/schema/storyink.schema.json +158 -142
- package/skill/SKILL.md +19 -1
- /package/dist/chunks/{index-90zf42zn.js → index-8fbs7b39.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
- **Fix: Play did nothing under reduced motion.** With Reduce Motion on (OS or `#motion=reduced`),
|
|
6
|
+
Play now walks the story step by step ("Play steps"): each step's settled state at once (reveals,
|
|
7
|
+
landed pulses, counters, the whole caption), held for its reading time (caption read time or
|
|
8
|
+
1.5 s), then the next, ending on the final frame. No pulses, trails, glows or tweens. Pause, ←/→,
|
|
9
|
+
Shift+←/→, R (restart from step 1, no rewind) and the scrubber work on settled steps. The page
|
|
10
|
+
loads on the final frame with a static play button; `autoplay` is ignored.
|
|
11
|
+
- **`story.motion`: `"full"` (default) | `"reduced"` | `"system"`.** Full motion is the default and
|
|
12
|
+
**ignores the reader's OS reduced-motion setting**; `"system"` restores the 0.3.0 behaviour
|
|
13
|
+
(follow `prefers-reduced-motion`), `"reduced"` always steps. Auto stories:
|
|
14
|
+
`{ "steps": "auto", "motion": … }`, `render --motion …`, tool `storyink_render` `motion`.
|
|
15
|
+
Precedence: `#motion=` > the reader's toolbar choice > `story.motion` > OS (only for `"system"`).
|
|
16
|
+
- Viewer toolbar: **Motion: full / reduced** toggle (`aria-pressed`, shortcut `M`), saved in
|
|
17
|
+
`localStorage`; `#motion=` still wins. Switching mid-playback continues from the current step.
|
|
18
|
+
- Core: `steppedSchedule`, `steppedTime`, `steppedIndex`, `steppedStop`, `STEP_BEAT` and
|
|
19
|
+
`storyState(…, { stepped: true })`.
|
|
20
|
+
- Snapshot: `--motion reduced` (tool `motion`) captures stepped `at` frames; new gate `reduced=stepped`.
|
|
21
|
+
- Fix: live counter reels were placed at the node-local position (top-left of the diagram) and
|
|
22
|
+
shown before their node was revealed; they now sit on their node and follow its reveal.
|
|
23
|
+
`bun run verify:viewer` checks this in headless Chrome (full play, reduced → full, reload,
|
|
24
|
+
resize, theme toggle) along with stepped playback.
|
|
25
|
+
|
|
26
|
+
## 0.3.0
|
|
27
|
+
|
|
28
|
+
- **Animated SVG (SMIL):** the story plays inside a plain `<img>`, so in GitHub READMEs and PR
|
|
29
|
+
comments (camo), docs and chat previews, where no script runs.
|
|
30
|
+
- `renderAnimatedSvg(spec, { theme, once, font, hold, reset, fps })` / `animatedSvg()` in
|
|
31
|
+
`storyink/core`; `writeAnimatedSvg()` and `pictureSnippet()` in `storyink/node`.
|
|
32
|
+
- CLI: `storyink render x.json --animated-svg x.svg [--theme light|dark|both] [--once] [--font system|embed]`;
|
|
33
|
+
`both` writes `.light.svg` + `.dark.svg` and prints the `<picture>` snippet. Specs without a
|
|
34
|
+
story use the auto story (with a warning).
|
|
35
|
+
- Plugin: `storyink_render` takes `animatedSvg: true | "both"`, `animatedSvgPath`, `once`, `font`.
|
|
36
|
+
- Built by sampling `storyState(t)` (the viewer's frame function) and compressing each track
|
|
37
|
+
to SMIL keyframes; one shared cycle (story, 3 s hold, 0.4 s reset) or `once` (freeze).
|
|
38
|
+
Base values are the final frame. Theme-pinned, no custom properties, deterministic.
|
|
39
|
+
- `bun run gallery:animated`, `bun run verify:smil` (frame parity PSNR, `<img>` playback, font).
|
|
40
|
+
- `Frame` pulse trail segments carry `k`, `s0`, `s1`; captions carry their index `i`.
|
|
41
|
+
- `screenshotPage()` in `storyink/node`: screenshot any local page.
|
|
42
|
+
|
|
3
43
|
## 0.2.1
|
|
4
44
|
|
|
5
45
|
- **Fix:** `storyink_snapshot` no longer inlines the full-resolution contact sheet. Tall beat
|
package/README.md
CHANGED
|
@@ -6,6 +6,19 @@ Mermaid) into **one offline HTML file** (a React + Motion viewer over server-ren
|
|
|
6
6
|
|
|
7
7
|
One package, four ways to use it: library, CLI, OpenCode plugin, and a skill for other agents.
|
|
8
8
|
|
|
9
|
+
<picture>
|
|
10
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/grenaad/storyink/main/docs/gallery/checkout.architecture.animated.dark.svg">
|
|
11
|
+
<img alt="Checkout platform, animated story" src="https://raw.githubusercontent.com/grenaad/storyink/main/docs/gallery/checkout.architecture.animated.light.svg">
|
|
12
|
+
</picture>
|
|
13
|
+
|
|
14
|
+
<picture>
|
|
15
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.jsdelivr.net/gh/grenaad/storyink@main/docs/gallery/oauth.sequence.animated.dark.svg">
|
|
16
|
+
<img alt="OAuth sequence, animated story" src="https://cdn.jsdelivr.net/gh/grenaad/storyink@main/docs/gallery/oauth.sequence.animated.light.svg">
|
|
17
|
+
</picture>
|
|
18
|
+
|
|
19
|
+
*Animated SVGs (SMIL, no script): they play inside a plain `<img>`, so in a README or a PR
|
|
20
|
+
comment too. See [Animated SVG](#animated-svg-readmes-and-prs).*
|
|
21
|
+
|
|
9
22
|
```sh
|
|
10
23
|
npx storyink render examples/checkout.architecture.json -o checkout.html --svg checkout.svg
|
|
11
24
|
```
|
|
@@ -35,10 +48,11 @@ both and has the OpenCode plugin as its default export. Runs on Node ≥ 20 and
|
|
|
35
48
|
|
|
36
49
|
```
|
|
37
50
|
storyink render <in.json|in.mmd|-> [-o out.html] [--svg out.svg] [--theme light|dark] [--story auto]
|
|
51
|
+
[--animated-svg out.svg [--theme light|dark|both] [--once] [--font system|embed]]
|
|
38
52
|
storyink mermaid <in.mmd> [-o out.json]
|
|
39
53
|
storyink validate <in> [--json]
|
|
40
54
|
storyink snapshot <out.html> [--theme light,dark] [--width N] [--sheet [themes|beats]|--no-sheet] [--at 0.5,1.2,end] [--scale 2] [-o dir] [--json]
|
|
41
|
-
[--preview out.jpg [--preview-size 1024]]
|
|
55
|
+
[--preview out.jpg [--preview-size 1024]] [--motion reduced]
|
|
42
56
|
storyink skill
|
|
43
57
|
```
|
|
44
58
|
|
|
@@ -108,7 +122,15 @@ Add a `story` to play a diagram as a sequence of beats in the HTML viewer:
|
|
|
108
122
|
|
|
109
123
|
`"story": "auto"` (or `--story auto`) derives the beats from the graph or message order. Playback
|
|
110
124
|
has a click-to-play gate, play/pause, a tape-rewind replay and a scrubber with step and chapter
|
|
111
|
-
ticks. Space, ←/→ and R control it.
|
|
125
|
+
ticks. Space, ←/→ and R control it.
|
|
126
|
+
|
|
127
|
+
Motion is **full by default, even when the reader's system asks for reduced motion**. Authors can
|
|
128
|
+
set `"story": { "motion": "reduced" }` (always step by step) or `"motion": "system"` (follow
|
|
129
|
+
`prefers-reduced-motion`); `--motion full|reduced|system` on `render` does the same, including
|
|
130
|
+
for auto stories. Readers switch with the toolbar's **Motion** toggle (`M`, remembered), and
|
|
131
|
+
`#motion=full|reduced` overrides everything. In reduced mode Play walks the story step by step:
|
|
132
|
+
each step's settled state shown at once and held for its reading time, with no travelling pulses
|
|
133
|
+
or tweens, and the page opens on the final frame.
|
|
112
134
|
|
|
113
135
|
The final frame is always the static diagram. Every frame is a pure function of time
|
|
114
136
|
(`storyState(scene, timeline, t)`), so `#t=2.5` seeks exactly and
|
|
@@ -118,10 +140,41 @@ receipt gates check that the end frame and the reduced-motion page match the sta
|
|
|
118
140
|
|
|
119
141
|

|
|
120
142
|
|
|
143
|
+
## Animated SVG (READMEs and PRs)
|
|
144
|
+
|
|
145
|
+
GitHub shows images in READMEs and PR comments as a plain `<img>` through its camo proxy, so no
|
|
146
|
+
script runs and nothing outside the file loads. `--animated-svg` compiles the story into **SMIL**
|
|
147
|
+
inside one self-contained SVG that plays there:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
storyink render examples/checkout.architecture.json --animated-svg docs/checkout.svg --theme both
|
|
151
|
+
# wrote docs/checkout.light.svg, docs/checkout.dark.svg and prints:
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```html
|
|
155
|
+
<picture>
|
|
156
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/checkout.dark.svg">
|
|
157
|
+
<img alt="Checkout platform" src="docs/checkout.light.svg">
|
|
158
|
+
</picture>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- An SVG image doesn't follow the page theme, so each file is **pinned** to one theme; the
|
|
162
|
+
`<picture>` picks one. `--theme light|dark` writes a single file.
|
|
163
|
+
- It loops: story, a 3 s hold on the final frame, a 0.4 s reset. `--once` plays once and freezes.
|
|
164
|
+
- The attributes' base values are the final frame, so viewers without SMIL show the static diagram.
|
|
165
|
+
- Fonts: `--font system` (default) uses the system mono stack; `--font embed` embeds Commit Mono
|
|
166
|
+
(+~127 KB) for the exact look. See the size table in [docs/spec.md](docs/spec.md#animated-svg).
|
|
167
|
+
- No story in the spec? The auto story is used (with a warning).
|
|
168
|
+
- Library: `renderAnimatedSvg(spec, { theme, once, font })` from `storyink/core`; plugin:
|
|
169
|
+
`storyink_render` with `animatedSvg: true | "both"`, `once`, `font`.
|
|
170
|
+
- GitHub's image proxy caches by URL: when a diagram changes, give it a new file name (or URL).
|
|
171
|
+
|
|
121
172
|
## Gallery
|
|
122
173
|
|
|
123
174
|
`bun run gallery` renders every example and Mermaid sample and writes one light and one dark PNG per
|
|
124
|
-
example to `docs/gallery/`.
|
|
175
|
+
example to `docs/gallery/`. `bun run gallery:animated` writes the animated SVGs of the story
|
|
176
|
+
examples (`*.animated.light.svg` / `*.animated.dark.svg`); `bun run verify:smil` checks them in
|
|
177
|
+
headless Chrome (frame parity with the viewer's frames, `<img>` playback, embedded font).
|
|
125
178
|
|
|
126
179
|
| | |
|
|
127
180
|
| --- | --- |
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -48,3 +48,10 @@ site are included. Serif headings use system fonts ("Iowan Old Style", Charter,
|
|
|
48
48
|
|
|
49
49
|
storyink parses a subset of Mermaid syntax with its own hand-written parsers; no Mermaid
|
|
50
50
|
or merman code is included.
|
|
51
|
+
|
|
52
|
+
## PR Lens (patterns only)
|
|
53
|
+
|
|
54
|
+
The animated SVG export follows the constraints and SMIL patterns of PR Lens's GitHub-safe SVG
|
|
55
|
+
renderer (<https://github.com/coldteadotai/pr-lens>, MIT License, Copyright (c) 2026 Coldtea AI):
|
|
56
|
+
self-contained files, no script or custom properties, animation as SMIL so it plays inside an
|
|
57
|
+
`<img>` behind GitHub's image proxy. No PR Lens code is included.
|