versioncam 0.1.2 → 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.
- package/CHANGELOG.md +196 -46
- package/README.md +486 -243
- package/bin/versioncam.js +1 -1
- package/dist/app-server.js +2 -2
- package/dist/app-server.js.map +1 -1
- package/dist/cli/commands/doctor.js +41 -4
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/init.js +26 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/preview.js +10 -1
- package/dist/cli/commands/preview.js.map +1 -1
- package/dist/cli/commands/record.js +3 -2
- package/dist/cli/commands/record.js.map +1 -1
- package/dist/cli/commands/render.d.ts +17 -0
- package/dist/cli/commands/render.js +79 -22
- package/dist/cli/commands/render.js.map +1 -1
- package/dist/cli/commands/stability.js +4 -4
- package/dist/cli/commands/stability.js.map +1 -1
- package/dist/cli/cwd.d.ts +46 -0
- package/dist/cli/cwd.js +102 -0
- package/dist/cli/cwd.js.map +1 -0
- package/dist/cli/main.js +11 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/usage.d.ts +10 -5
- package/dist/cli/usage.js +42 -24
- package/dist/cli/usage.js.map +1 -1
- package/dist/config.d.ts +24 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -1
- package/dist/core/camera-track.d.ts +63 -0
- package/dist/core/camera-track.js +230 -0
- package/dist/core/camera-track.js.map +1 -0
- package/dist/core/camera.d.ts +14 -1
- package/dist/core/camera.js +18 -2
- package/dist/core/camera.js.map +1 -1
- package/dist/core/follow.d.ts +129 -0
- package/dist/core/follow.js +151 -0
- package/dist/core/follow.js.map +1 -0
- package/dist/core/motion-defaults.d.ts +29 -0
- package/dist/core/motion-defaults.js +29 -0
- package/dist/core/motion-defaults.js.map +1 -1
- package/dist/core/timeline.d.ts +32 -2
- package/dist/core/timeline.js +10 -0
- package/dist/core/timeline.js.map +1 -1
- package/dist/driver/clip.d.ts +4 -1
- package/dist/driver/clip.js +9 -1
- package/dist/driver/clip.js.map +1 -1
- package/dist/driver/session.d.ts +35 -1
- package/dist/driver/session.js +81 -12
- package/dist/driver/session.js.map +1 -1
- package/dist/driver/settle.js +2 -2
- package/dist/driver/settle.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inspect/inspect.js +1 -1
- package/dist/loader.d.ts +7 -1
- package/dist/loader.js +23 -8
- package/dist/loader.js.map +1 -1
- package/dist/page/assets/index-fZtacWyp.js +2 -0
- package/dist/page/index.html +2 -2
- package/dist/render/encode.d.ts +12 -1
- package/dist/render/encode.js +94 -35
- package/dist/render/encode.js.map +1 -1
- package/dist/render/presentation.d.ts +12 -0
- package/dist/render/presentation.js +15 -0
- package/dist/render/presentation.js.map +1 -1
- package/dist/render/render.js +19 -2
- package/dist/render/render.js.map +1 -1
- package/dist/render/sampling.d.ts +13 -0
- package/dist/render/sampling.js +48 -20
- package/dist/render/sampling.js.map +1 -1
- package/dist/render/scenes.d.ts +16 -0
- package/dist/render/scenes.js +108 -0
- package/dist/render/scenes.js.map +1 -0
- package/dist/render/sequence.d.ts +18 -0
- package/dist/render/sequence.js +67 -13
- package/dist/render/sequence.js.map +1 -1
- package/dist/review/review.js +48 -23
- package/dist/review/review.js.map +1 -1
- package/dsl.md +267 -92
- package/package.json +2 -2
- package/plugin/README.md +58 -47
- package/plugin/agents/versioncam-reviewer.md +3 -2
- package/plugin/skills/versioncam/SKILL.md +60 -14
- package/plugin/skills/versioncam/authoring.md +6 -1
- package/plugin/skills/versioncam/onboarding.md +17 -17
- package/dist/page/assets/index-DUom5amc.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,29 +2,176 @@
|
|
|
2
2
|
|
|
3
3
|
What a user of `versioncam` would want to know about each version, newest
|
|
4
4
|
first. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
5
|
-
and versions follow [semantic versioning](https://semver.org/)
|
|
5
|
+
and versions follow [semantic versioning](https://semver.org/). While the
|
|
6
6
|
major version is 0, a minor version may change the config or the clip DSL,
|
|
7
7
|
and its entry here says how.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 0.2.0 (2026-09-29)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
A minor version: new config fields and new camera methods. A clip whose
|
|
12
|
+
camera moves never overlap records what it did before, to the byte.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `s.camera.follow()` follows the cursor at one scale until the next camera
|
|
17
|
+
line, for a clip that moves around the page: one line instead of a zoom
|
|
18
|
+
before each thing the cursor uses, which zoomed in and out and panned in
|
|
19
|
+
fits and starts. The camera keeps the cursor inside a dead zone in the
|
|
20
|
+
middle of the frame, never shows beyond the page's edge, and moves
|
|
21
|
+
smoothly without overshooting. Its path is worked out from the whole
|
|
22
|
+
cursor track once the clip has run, so it keeps up with a cursor that
|
|
23
|
+
crosses the page. The options are `scale` (1.35, exact rather than a
|
|
24
|
+
ceiling), `deadZone` (0.3 of the frame), `smoothing` (600 milliseconds)
|
|
25
|
+
and `duration` (how long it takes to ease in). Their defaults are new
|
|
26
|
+
fields of the config's `motion`: `followZoom`, `followDeadZone` and
|
|
27
|
+
`followSmoothingMs`. `s.camera.release()` stops following, and the camera
|
|
28
|
+
comes to rest on the framing it was heading for.
|
|
29
|
+
- `versioncam review` warns, under `onscreen`, about a click that lands
|
|
30
|
+
outside what the camera shows: the button changes, and no frame shows it
|
|
31
|
+
pressed.
|
|
32
|
+
- `--cwd <dir>` runs any command as if from `<dir>`: that directory's
|
|
33
|
+
config, `.env.recording` and `.env`, and any relative path the command is
|
|
34
|
+
given or prints. It can go anywhere on the line. It is for a monorepo, run
|
|
35
|
+
from the repository root or from inside the app. `npx` looks for
|
|
36
|
+
versioncam only where it runs and above, so `--cwd` refuses a directory
|
|
37
|
+
whose own versioncam is not the one running, and says to `cd` into it
|
|
38
|
+
instead.
|
|
39
|
+
- `versioncam doctor` reads the scenes module a config names, and lists its
|
|
40
|
+
scene ids, or says what `render` would refuse it for and how to fix it.
|
|
41
|
+
- `theme.presentation.captionInset` moves a caption that sits over the app:
|
|
42
|
+
`{ left: n }` or `{ right: n }`, pixels of the video in from that side,
|
|
43
|
+
and `right` puts it in the bottom-right corner. The default, `{ left: 40 }`,
|
|
44
|
+
is where it always sat, to the byte. It is for an app whose own controls
|
|
45
|
+
are where the caption was, such as an account menu at the foot of a
|
|
46
|
+
sidebar or a map's legend. The README's Configure section has a table of
|
|
47
|
+
every `presentation` field now, which a test holds to the type.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- A camera line written while the camera is still moving starts at once,
|
|
52
|
+
from where the camera is, and takes its whole `duration`. It used to wait
|
|
53
|
+
for the move before it to arrive and then run in whatever time was left,
|
|
54
|
+
so a series of pans stopped and snapped. Two camera lines written at the
|
|
55
|
+
same instant used to glide to the first and cut to the second; now the
|
|
56
|
+
second is the only one. A clip whose camera moves never overlap records
|
|
57
|
+
exactly the camera it did before, to the byte.
|
|
58
|
+
- A recording whose camera follows the cursor, or eases from one move into
|
|
59
|
+
another, keeps its camera as a key a frame, with a new ease, `"linear"`.
|
|
60
|
+
A renderer from an earlier version draws such a recording the same way.
|
|
61
|
+
- `versioncam review` names a camera still moving at the end of a clip once,
|
|
62
|
+
at its last key, rather than once for every key past the end.
|
|
63
|
+
- `versioncam init` below a repository root says where Claude Code finds the
|
|
64
|
+
skill: in a session started in that directory or below it, and from the
|
|
65
|
+
root only after the session has read or edited a file there.
|
|
66
|
+
- `render` checks everything it was asked for before it renders anything.
|
|
67
|
+
An id that matches no recording and no scene, or a `--scene` the scenes
|
|
68
|
+
module does not define, stops it with what there is to render. An id that
|
|
69
|
+
matched nothing used to be passed over without a word.
|
|
70
|
+
- `versioncam --help` and the README say plainly that `render` with no ids
|
|
71
|
+
renders every recording on disk, stale ones from drafts, trial runs and
|
|
72
|
+
renamed clips included.
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- The authoring skill works in a monorepo wherever the session started. It
|
|
77
|
+
looks for `versioncam.config.ts` across the whole repository before
|
|
78
|
+
deciding anything, works in the directory that holds it, and asks which
|
|
79
|
+
when there are several. It used to look only in the directory the session
|
|
80
|
+
was in. Invoked at a repository root with the app below it, it said
|
|
81
|
+
versioncam was not installed, and past that it would have set the root up
|
|
82
|
+
as a second app, with a second config.
|
|
83
|
+
- A scenes module whose scenes are not its default export is refused, with
|
|
84
|
+
the file's name and the shape it should have: a `Record<string, Scene>`
|
|
85
|
+
keyed by scene id. A module whose record was a named export used to count
|
|
86
|
+
as having no scenes, so `render` rendered none, said nothing, and stitched
|
|
87
|
+
a sequence without them. An array, a single scene, or an entry with no
|
|
88
|
+
`draw`, no whole `durationFrames` or no `fps` is refused the same way.
|
|
89
|
+
`render` and `preview --scene` refuse it before a browser starts, and the
|
|
90
|
+
render page refuses it too, for anything that renders a scene without the
|
|
91
|
+
CLI.
|
|
92
|
+
- `render --scene <id>` renders that scene whatever ids come with it. The
|
|
93
|
+
ids used to filter the named scenes as well, so
|
|
94
|
+
`render 02 04 --scene 01-intro --sequence` rendered no scene and stitched
|
|
95
|
+
the recordings without it. Ids still choose among the scenes `--scene`
|
|
96
|
+
does not name.
|
|
97
|
+
- `render --sequence` says what the sequence was stitched without: the ids
|
|
98
|
+
in the config's `sequence` that this run did not render, and the ones it
|
|
99
|
+
rendered that the `sequence` leaves out. The first note was in the code
|
|
100
|
+
and could never print. With fewer than two of the `sequence`'s clips
|
|
101
|
+
rendered, it says a sequence needs two, as it does with fewer than two
|
|
102
|
+
clips at all, rather than failing.
|
|
103
|
+
- `render --sequence` joins clips of different frame rates, such as a
|
|
104
|
+
15 fps draft beside 60 fps recordings, or a scene or a clip with an `fps`
|
|
105
|
+
of its own. Every clip is brought to the highest rate among them, so none
|
|
106
|
+
loses a frame. It used to print ffmpeg's error that the clips' timebases
|
|
107
|
+
or frame rates do not match, and stop without a sequence. Clips that
|
|
108
|
+
share one rate are stitched exactly as before.
|
|
109
|
+
- A sequence that fails in ffmpeg leaves the `sequence.mp4` of an earlier
|
|
110
|
+
run as it was, and says that the one there is an earlier run's. It used
|
|
111
|
+
to leave that file empty, or an empty one where there had been none:
|
|
112
|
+
ffmpeg wrote straight to it, and had emptied it by the time it failed.
|
|
113
|
+
The sequence is now written beside it and takes its place only once it
|
|
114
|
+
is complete.
|
|
115
|
+
- A clip or scene that fails partway through `render` stops it at once, and
|
|
116
|
+
leaves the last good render as it was. A scene that threw at a frame used
|
|
117
|
+
to leave both ffmpeg encoders waiting for frames that would never come:
|
|
118
|
+
`render` printed the error and then never exited, which in CI is a job
|
|
119
|
+
that hangs until it is killed. ffmpeg also wrote straight over the
|
|
120
|
+
finished files, so a playable half-clip, and the failed run's poster, took
|
|
121
|
+
the place of the last good ones. The clip, its webm, its poster and its
|
|
122
|
+
contact sheet are now each written beside the last and take its place only
|
|
123
|
+
once complete, as the sequence is.
|
|
124
|
+
- A contact sheet's evenly spread tiles no longer land in the dissolve the
|
|
125
|
+
renderer draws after a settle, where a tile showed the page before the
|
|
126
|
+
wait ghosting through the page after it. The sheet `render` writes and
|
|
127
|
+
`versioncam sheet` without `--at-marks` move such a tile to the first
|
|
128
|
+
frame after the dissolve, as `--at-marks` already did for its own tiles.
|
|
129
|
+
The example app's first clip had one. A scene's sheet is unchanged, since
|
|
130
|
+
a scene never dissolves. `evenFrames` is exported beside `uniformFrames`
|
|
131
|
+
and `markedFrames`.
|
|
132
|
+
|
|
133
|
+
## 0.1.3 (2026-09-28)
|
|
134
|
+
|
|
135
|
+
### Added
|
|
136
|
+
|
|
137
|
+
- A recording lists the steps its script took: `steps` in `timeline.json`,
|
|
138
|
+
each DSL call the script made and the frame it began on. There is one per
|
|
139
|
+
line of the script: `typeInto` is one step, not also the click it makes, and
|
|
140
|
+
a locator is an argument, not a step. A reader holding the script can say
|
|
141
|
+
which line produced which moment.
|
|
142
|
+
- A recording names the versioncam that made it: `meta.recorder`, the package
|
|
143
|
+
version. A page that shows the recording can print the version that
|
|
144
|
+
recorded it instead of the latest release.
|
|
145
|
+
|
|
146
|
+
### Changed
|
|
147
|
+
|
|
148
|
+
- The DSL reference gives every method its own heading and every option its
|
|
149
|
+
default, and `versioncam dsl` prints it. It used to say `camera.zoom`
|
|
150
|
+
defaults to 1.65. The default is 1.5, as far as the camera goes before
|
|
151
|
+
captured pixels are upscaled.
|
|
152
|
+
- `versioncam --help` groups the commands by stage: set up, write, record,
|
|
153
|
+
review, output.
|
|
154
|
+
- The CLI's messages say things in sentences and brackets rather than
|
|
155
|
+
dashes. `record` says "1 cut" rather than "1 cuts". `stability` separates
|
|
156
|
+
the pair it compared from the result with a `·`, so a script matching its
|
|
157
|
+
output needs the new line.
|
|
158
|
+
|
|
159
|
+
## 0.1.2 (2026-09-28)
|
|
12
160
|
|
|
13
161
|
### Fixed
|
|
14
162
|
|
|
15
163
|
- Typing followed straight away by another action no longer loses its last
|
|
16
|
-
character. `type` and `typeInto` queue keystrokes at a human cadence
|
|
17
|
-
|
|
18
|
-
queued until after the next step
|
|
164
|
+
character. `type` and `typeInto` queue keystrokes at a human cadence.
|
|
165
|
+
Whenever the typing ended between two frames, the last keystroke stayed
|
|
166
|
+
queued until after the next step. So `typeInto(…)` then `press("Enter")`
|
|
19
167
|
sent the text without its last character, which then began the next
|
|
20
168
|
message. Whether a clip was affected depended only on its timing.
|
|
169
|
+
- A point written as `{ x, y }`, the shape a bounding box gives you, fails
|
|
170
|
+
with "A point is [x, y], not { x, y }", which names the fix. It used to
|
|
171
|
+
reach Playwright as if it were a locator and fail as "locator.count is not
|
|
172
|
+
a function". `dsl.md` says that a point is `[x, y]`.
|
|
21
173
|
|
|
22
|
-
|
|
23
|
-
with "A point is [x, y], not { x, y }", naming the fix. It used to reach
|
|
24
|
-
Playwright as if it were a locator and fail as "locator.count is not a
|
|
25
|
-
function". `dsl.md` says that a point is `[x, y]`.
|
|
26
|
-
|
|
27
|
-
## [0.1.1] — 2026-09-28
|
|
174
|
+
## 0.1.1 (2026-09-28)
|
|
28
175
|
|
|
29
176
|
The first version published by the release workflow rather than by hand.
|
|
30
177
|
|
|
@@ -32,77 +179,80 @@ The first version published by the release workflow rather than by hand.
|
|
|
32
179
|
|
|
33
180
|
- Where there is no `versioncam.config.ts`, `doctor` and every other command
|
|
34
181
|
say how to get one: `npx versioncam init`, then `/versioncam`, whose first
|
|
35
|
-
run writes it from the repository
|
|
36
|
-
`defineRecorder()`. They used to offer only the second, which is the
|
|
37
|
-
way round for anyone using the skill.
|
|
182
|
+
run writes it from the repository. Or write it by hand, a default export
|
|
183
|
+
from `defineRecorder()`. They used to offer only the second, which is the
|
|
184
|
+
long way round for anyone using the skill.
|
|
38
185
|
- The skill's plugin manifest links to version.cam, and no longer to a
|
|
39
186
|
repository nobody outside can open.
|
|
40
187
|
|
|
41
|
-
##
|
|
188
|
+
## 0.1.0 (2026-09-25)
|
|
42
189
|
|
|
43
|
-
The first published version
|
|
44
|
-
|
|
190
|
+
The first published version, and no longer on npm: install 0.1.1 or later.
|
|
191
|
+
It was built in work packages before it had a version number, so this entry
|
|
192
|
+
is grouped by them, newest first.
|
|
45
193
|
|
|
46
194
|
### Publishing
|
|
47
195
|
|
|
48
196
|
- Licensed under the Functional Source License 1.1 with Apache 2.0 as the
|
|
49
|
-
future licence (`FSL-1.1-ALv2`)
|
|
50
|
-
CI, commercial work included
|
|
51
|
-
version is also available under Apache 2.0 two years after its
|
|
197
|
+
future licence (`FSL-1.1-ALv2`). Use it on your own apps and in your own
|
|
198
|
+
CI, commercial work included, but not in a competing product or service.
|
|
199
|
+
Each version is also available under Apache 2.0 two years after its
|
|
200
|
+
release.
|
|
52
201
|
- `versioncam install` installs the Chromium that this version's Playwright
|
|
53
|
-
expects
|
|
54
|
-
|
|
202
|
+
expects, and `--with-deps` adds its system libraries on Linux CI. `doctor`
|
|
203
|
+
names it when the browser is missing.
|
|
55
204
|
|
|
56
205
|
### Reproducible on Linux
|
|
57
206
|
|
|
58
207
|
- A draft recording reproduces on Linux. Chromium now repaints whole tiles
|
|
59
|
-
(`--disable-partial-raster`)
|
|
208
|
+
(`--disable-partial-raster`). At a draft's CSS scale, repainting only what
|
|
60
209
|
the page reported as changed had left one pixel of a just-typed letter
|
|
61
210
|
stale in about half of all runs on a CI runner. Full recordings are
|
|
62
211
|
byte-identical with and without it.
|
|
63
|
-
- The page's clock moves only when the recorder moves it
|
|
64
|
-
16 ms a tick while it waits
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
212
|
+
- The page's clock moves only when the recorder moves it: 1/fps a frame, and
|
|
213
|
+
16 ms a tick while it waits. It used to run on real time between frames,
|
|
214
|
+
where one slow screenshot had moved it 840 ms and fired an app's timer
|
|
215
|
+
seven frames early. `offCamera` spends no time on the page's clock. A
|
|
216
|
+
sign-in hook runs with the clock ticking. A target that is not yet on
|
|
68
217
|
screen is waited for in ticks, so it arrives on the same tick every run.
|
|
69
218
|
|
|
70
|
-
### Versioncam
|
|
219
|
+
### Versioncam (2026-09-24)
|
|
71
220
|
|
|
72
221
|
- One name for everything: the package and CLI `versioncam`, the config
|
|
73
222
|
`versioncam.config.ts`, the output directory `.versioncam/`, the skill
|
|
74
223
|
`/versioncam`.
|
|
75
|
-
- `webServer` in the config, Playwright's fields
|
|
76
|
-
the app starts it when nothing answers, and stops everything it
|
|
224
|
+
- `webServer` in the config, with Playwright's fields. Every command that
|
|
225
|
+
drives the app starts it when nothing answers, and stops everything it
|
|
226
|
+
started.
|
|
77
227
|
- `versioncam stability` records a clip twice the same way and says whether
|
|
78
228
|
the app reproduces, with the two pictures behind the first frame that
|
|
79
|
-
differs. `frame --at <label>` renders the frame a beat shows
|
|
80
|
-
says where each name came from
|
|
81
|
-
- One skill and one reviewer file, installed by `versioncam init
|
|
229
|
+
differs. `frame --at <label>` renders the frame a beat shows. `inspect`
|
|
230
|
+
says where each name came from. `measure` prints what each match says.
|
|
231
|
+
- One skill and one reviewer file, installed by `versioncam init`. The
|
|
82
232
|
skill's first run in a repository writes the config and proves the app
|
|
83
233
|
records the same way twice before it writes a clip.
|
|
84
234
|
|
|
85
|
-
### The authoring loop
|
|
235
|
+
### The authoring loop (2026-09-22)
|
|
86
236
|
|
|
87
237
|
- The agent skill: inspect the app, write a clip, record it, have a fresh
|
|
88
|
-
reviewer judge a contact sheet, fix what it finds. No API key
|
|
89
|
-
|
|
90
|
-
- `versioncam review
|
|
91
|
-
sampled at the beats
|
|
92
|
-
their waits (`settles.json`)
|
|
93
|
-
breaks
|
|
94
|
-
|
|
238
|
+
reviewer judge a contact sheet, fix what it finds. No API key: the model is
|
|
239
|
+
whichever agent session runs it.
|
|
240
|
+
- `versioncam review`, the checks that need no eyes. `sheet --at-marks`,
|
|
241
|
+
sampled at the beats. Recordings that describe their beats (`marks`) and
|
|
242
|
+
their waits (`settles.json`). `failure.png` and `failure.json` when a clip
|
|
243
|
+
breaks. `s.drag`. `cursorStart`. Bounds on a clip's length that the app
|
|
244
|
+
sets for review.
|
|
95
245
|
|
|
96
|
-
### Speed
|
|
246
|
+
### Speed (2026-09-21)
|
|
97
247
|
|
|
98
248
|
- Capture on change: a frame is photographed only when the page can have
|
|
99
|
-
changed
|
|
249
|
+
changed. That skips 81% to 95% of frames on the example app and leaves the
|
|
100
250
|
recording identical.
|
|
101
251
|
- `--draft`: fifteen frames a second at CSS scale, for looking at while
|
|
102
252
|
writing a clip.
|
|
103
253
|
- `record` prints where the time went.
|
|
104
254
|
|
|
105
|
-
### The package
|
|
255
|
+
### The package (2026-09-21)
|
|
106
256
|
|
|
107
257
|
- The recorder, extracted from the prototype it grew up in: a config
|
|
108
258
|
boundary (`defineRecorder`), the clip DSL, a renderer with presentation as
|