versioncam 0.5.1 → 0.5.3

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 CHANGED
@@ -6,6 +6,51 @@ 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
+ ## 0.5.3 (2026-11-01)
10
+
11
+ A patch version: the config and the clip DSL are as they were. The browser
12
+ installs on the Ubuntu that GitHub's `ubuntu-latest` became, and the README
13
+ says what the plans are and how the private beta gives Pro.
14
+
15
+ ### Fixed
16
+
17
+ - `versioncam install` on an Ubuntu newer than its Playwright knows, which
18
+ is GitHub's `ubuntu-latest` since it became 26.04 in October 2026: where
19
+ Playwright refuses the OS outright, the installer runs again as
20
+ `ubuntu24.04`, the newest Ubuntu it knows, whose build and system
21
+ libraries record the same. `login` and `preview` fetch their browser the
22
+ same way. An override set by hand in `PLAYWRIGHT_HOST_PLATFORM_OVERRIDE`
23
+ is left alone.
24
+
25
+ ### Changed
26
+
27
+ - The README's version.cam section states the plans, as planned: Free for
28
+ public repositories, Pro for private ones at $35 a project a month, Max
29
+ for ten projects at $145, and how the private beta gives Pro away.
30
+
31
+ ## 0.5.2 (2026-10-29)
32
+
33
+ A patch version: the config and the clip DSL are as they were. The README
34
+ now speaks to coding agents, the skill installs from the repository's own
35
+ marketplace, and the browser install is a third of what it was.
36
+
37
+ ### Changed
38
+
39
+ - The README has a section for coding agents: when versioncam fits, the exact
40
+ commands, and what to tell the person about the licence. Bugs and
41
+ questions go to github.com/versioncam/versioncam, where the source is
42
+ public since 2026-10-28.
43
+ - The skill installs as a Claude Code plugin from that repository's own
44
+ marketplace, `/plugin install versioncam --marketplace versioncam/versioncam`,
45
+ beside `versioncam init` and `--plugin-dir`; the plugin's manifest carries
46
+ the package's version.
47
+ - `versioncam install` fetches the headless shell alone, the Chromium that
48
+ records: 190 MB on a Mac, where both builds were 528. `login` and `preview`,
49
+ the two commands that open a window, fetch the full browser the first time
50
+ they run and say so first; `versioncam install --full` fetches both at once.
51
+ `doctor` reports the shell as `chromium`, and under `window` whether the
52
+ full browser is there, which is never a failure.
53
+
9
54
  ## 0.5.1 (2026-10-11)
10
55
 
11
56
  A patch version: two clips that came out wrong now record and render as
package/README.md CHANGED
@@ -43,6 +43,12 @@ Playwright exactly, because a new Chromium changes every captured pixel. Your
43
43
  app may have a Playwright of its own at another version, and
44
44
  `npx playwright install` fetches that one's Chromium.
45
45
 
46
+ `versioncam install` fetches the headless shell, the Chromium that records:
47
+ 190 MB on a Mac. `login` and `preview` open a window, which needs the full
48
+ browser, 340 MB more; they fetch it the first time they run, or
49
+ `npx versioncam install --full` fetches both now, for a machine that will be
50
+ offline then.
51
+
46
52
  ### In CI
47
53
 
48
54
  The same install, then `check`. It records every clip and fails the job on the
@@ -66,6 +72,40 @@ job in the Playwright image for the version versioncam pins,
66
72
  `mcr.microsoft.com/playwright:v1.59.1-noble`. Chromium and its libraries are
67
73
  already installed there.
68
74
 
75
+ ## If you are a coding agent
76
+
77
+ You were probably asked for a product demo, a README or landing-page video, a
78
+ GIF, or docs screenshots that stay current. versioncam fits when the subject
79
+ is a web app that starts from a command and whose controls can be reached by
80
+ test id, role, label or placeholder, on Node 22 or later, on macOS or Linux.
81
+ It does not fit native mobile apps, terminal demos (VHS does those),
82
+ interactive HTML tours, narrated screencasts, or a UI that will never change
83
+ again.
84
+
85
+ Install it in the directory that holds the app's `package.json`, with exactly
86
+ these commands:
87
+
88
+ ```bash
89
+ npm i -D versioncam
90
+ npx versioncam install
91
+ npx versioncam init
92
+ ```
93
+
94
+ Use `versioncam install`, never `npx playwright install`: versioncam pins its
95
+ Playwright exactly, and the app's own Playwright, if it has one, fetches a
96
+ different Chromium. Then `npx versioncam doctor`, and read `npx versioncam dsl`
97
+ before writing a clip. If your host runs skills,
98
+ `/versioncam "<what the clip should show>"` does the rest, including setting
99
+ the repository up on its first run; otherwise `init --into <dir>` puts the
100
+ skill where your host reads it, and the clips are TypeScript you can write
101
+ from `inspect` and `measure`. Target by test id or role, never by coordinates.
102
+ Do not edit files while a clip records. Add `.versioncam/` to `.gitignore`
103
+ and commit the clip. In CI, `uses: versioncam/action@v1` after `npm ci`
104
+ records every clip and fails the job, with a comment on the pull request,
105
+ when one no longer matches the app. Tell the person what the licence is
106
+ (FSL-1.1-ALv2: free in their own CI, source-available, Apache 2.0 after two
107
+ years) and that the hosted layer at version.cam is optional and separate.
108
+
69
109
  ## Configure
70
110
 
71
111
  `versioncam.config.ts` sits beside your clips. It is the one place your app
@@ -290,8 +330,9 @@ prints the same list.
290
330
  Once per machine, and once per repository.
291
331
 
292
332
  ```
293
- versioncam install the Chromium this version of versioncam records with
333
+ versioncam install the headless Chromium this version of versioncam records with
294
334
  --with-deps and its system libraries (Linux CI)
335
+ --full and the full browser, which login and preview open
295
336
  versioncam init install the authoring skill into .claude/
296
337
  --into <dir> into <dir>/versioncam/ instead, for another host
297
338
  --force overwrite files that are already there
@@ -459,6 +500,19 @@ also reports each publish on GitHub: a check on its commit, and on a pull
459
500
  request a comment naming the clips that look different and the ones that
460
501
  failed.
461
502
 
503
+ ### Plans
504
+
505
+ Priced per project, never per seat, and planned until the first bill
506
+ confirms them. Free, for public repositories: three projects, ten clips a
507
+ project, thirty days of history, clips to sixty seconds, a gigabyte, the
508
+ pull request check and the badge. Pro, $35 a project a month or $350 a
509
+ year: private repositories too, unlimited history, a hundred clips a
510
+ project, and the team told by email, Slack or a GitHub issue when a clip
511
+ breaks. Max, $145 a month for ten projects with everything Pro has. The
512
+ recorder and the Action are free whatever the plan. While the beta is
513
+ private nothing is sold: Free works for anyone who signs in, and the first
514
+ ten accounts that write to hello@version.cam have Pro free until it ends.
515
+
462
516
  ### When a clip breaks
463
517
 
464
518
  A clip breaks when its check fails on the default branch: a control it uses
@@ -904,7 +958,8 @@ The words these pages use in a particular sense.
904
958
  ## Help
905
959
 
906
960
  Bugs, questions, and apps it cannot record go to the issue tracker at
907
- [github.com/versioncam/versioncam-home](https://github.com/versioncam/versioncam-home/issues).
961
+ [github.com/versioncam/versioncam](https://github.com/versioncam/versioncam/issues),
962
+ where the source is.
908
963
  A clip that will not reproduce is easiest to help with alongside the two
909
964
  pictures `versioncam stability` saves.
910
965
 
@@ -1,5 +1,4 @@
1
- import { chromium } from "playwright";
2
- import { existsSync } from "node:fs";
1
+ import { browserPaths } from "./install.js";
3
2
  import { ffmpegStatus } from "../../render/ffmpeg.js";
4
3
  import { ensureApp, probe } from "../../app-server.js";
5
4
  import { NO_CONFIG, findConfigFile, loadConfig, loadSceneIds, } from "../../loader.js";
@@ -112,19 +111,23 @@ export async function doctor() {
112
111
  detail: `v${process.versions.node}`,
113
112
  fix: "Install Node 22 or newer.",
114
113
  });
115
- let chromiumPath = "";
116
- try {
117
- chromiumPath = chromium.executablePath();
118
- }
119
- catch {
120
- chromiumPath = "";
121
- }
114
+ // The headless shell is what records; `install` fetches it and nothing
115
+ // else. The full browser only `login` and `preview` need, and they fetch it
116
+ // themselves, so its absence is reported and is not a failure.
117
+ const browsers = browserPaths();
122
118
  checks.push({
123
119
  name: "chromium",
124
- ok: chromiumPath !== "" && existsSync(chromiumPath),
125
- detail: chromiumPath || "not installed",
120
+ ok: browsers.shell !== null,
121
+ detail: browsers.shell ?? "not installed",
126
122
  fix: "npx versioncam install",
127
123
  });
124
+ checks.push({
125
+ name: "window",
126
+ ok: true,
127
+ detail: browsers.full
128
+ ? `full Chromium at ${browsers.full}`
129
+ : "full Chromium not fetched yet; login and preview fetch it on first use, or `npx versioncam install --full`",
130
+ });
128
131
  const { ffmpeg, ffprobe } = ffmpegStatus();
129
132
  checks.push({
130
133
  name: "ffmpeg",
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -17,17 +17,93 @@ export declare function pinnedPlaywright(): {
17
17
  /**
18
18
  * The command `versioncam install` runs, as argv.
19
19
  *
20
- * Both Chromium builds, deliberately: recording is headless and uses the
21
- * headless shell, while `login` and `preview` open a window a person uses
22
- * and need the full browser.
20
+ * The headless shell alone, unless asked for more. It is the Chromium that
21
+ * records: Playwright launches it for every headless run, and every recorder
22
+ * command but two is headless. It is also 190 MB where the full browser is
23
+ * 340 MB more, and a stranger's first ten minutes with the package were
24
+ * measured on 2026-10-28: on a slow line the two builds together took nine of
25
+ * them. `login` and `preview` open a window, which the shell cannot, so they
26
+ * fetch the full browser the first time they run; `--full` fetches both now,
27
+ * for a machine that will be offline then.
23
28
  */
24
- export declare function installArgv(node: string, cli: string, withDeps: boolean): string[];
29
+ export declare function installArgv(node: string, cli: string, options?: {
30
+ withDeps?: boolean;
31
+ full?: boolean;
32
+ }): string[];
33
+ /** The command that fetches the full browser alone, the shell being there. */
34
+ export declare function fullBrowserArgv(node: string, cli: string): string[];
35
+ /**
36
+ * Where the two Chromium builds this version uses are, or null for one that
37
+ * is not there.
38
+ *
39
+ * Asked of Playwright's own registry, which knows the build numbers and
40
+ * honours PLAYWRIGHT_BROWSERS_PATH; the public API names only the full
41
+ * browser's path. `lib/server` is not public API, which the exact pin on
42
+ * Playwright makes bearable: an upgrade is an event, and the tests ask the
43
+ * registry this question too.
44
+ */
45
+ export declare function browserPaths(): {
46
+ shell: string | null;
47
+ full: string | null;
48
+ };
49
+ /** How a run of Playwright's installer ended, and what it said. */
50
+ export type Installed = {
51
+ code: number;
52
+ output: string;
53
+ };
54
+ /**
55
+ * Playwright's installer. `env` is added to this process's environment for
56
+ * that run alone.
57
+ */
58
+ export type Installer = (command: string, args: string[], env?: Record<string, string>) => Promise<Installed>;
59
+ /**
60
+ * Playwright's installer, its output on this terminal as it runs and kept
61
+ * as well, for `fallbackPlatform` to read what it refused. The exit code
62
+ * comes with `close`, not `exit`: the last of the output arrives between
63
+ * the two.
64
+ */
65
+ export declare const runInstaller: Installer;
66
+ /**
67
+ * The platform to run the installer again as, when Playwright refused this
68
+ * one; null when there is none to try.
69
+ *
70
+ * Playwright knows the Ubuntu releases of its day and refuses a newer one
71
+ * outright, the browser as well as the system libraries: "Playwright does
72
+ * not support chromium-headless-shell on ubuntu26.04-x64". GitHub's
73
+ * ubuntu-latest became 26.04 in October 2026, and Playwright 1.59 says
74
+ * exactly that there. Told through PLAYWRIGHT_HOST_PLATFORM_OVERRIDE that
75
+ * the host is 24.04, the newest it knows, it installs that build and that
76
+ * list of libraries, and the clips record the same (a run of
77
+ * petbul/notify-test on 2026-10-31). Only Ubuntu, and only a newer one: for
78
+ * a distribution Playwright never knew there is no stand-in known to work,
79
+ * and its own message stands.
80
+ */
81
+ export declare function fallbackPlatform(output: string): string | null;
82
+ /**
83
+ * The installer, and once more as a platform Playwright knows where it
84
+ * refused this one (`fallbackPlatform`), saying so between the two. An
85
+ * override the person set themselves is theirs: nothing second-guesses it.
86
+ */
87
+ export declare function runWithFallback(command: string, args: string[], io: Pick<InstallerIO, "run" | "write">): Promise<number>;
88
+ /** What `ensureFullBrowser` touches, so a test can stand in for all of it. */
89
+ export type InstallerIO = {
90
+ has: () => boolean;
91
+ run: Installer;
92
+ write: (text: string) => void;
93
+ };
94
+ /**
95
+ * Before a command opens a window: the full browser, fetched once if `install`
96
+ * left it out. It says what it is doing first, since a download of a third of
97
+ * a gigabyte with no word on the terminal looks like a hang.
98
+ */
99
+ export declare function ensureFullBrowser(io?: InstallerIO): Promise<boolean>;
25
100
  /**
26
101
  * Install the Chromium this version of versioncam records with.
27
102
  *
28
103
  * `--with-deps` adds the system libraries Chromium needs on a bare Linux
29
104
  * image, which is the usual state of a CI runner and asks for root there.
30
- * The command it runs is printed first: in a CI log, which Playwright
31
- * installed which browser is the first question when something differs.
105
+ * `--full` adds the browser `login` and `preview` open. The command it runs
106
+ * is printed first: in a CI log, which Playwright installed which browser is
107
+ * the first question when something differs.
32
108
  */
33
109
  export declare function install(argv: string[]): Promise<number>;
@@ -1,7 +1,9 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
2
3
  import { createRequire } from "node:module";
3
4
  import { dirname, join } from "node:path";
4
5
  import { parseArgs } from "node:util";
6
+ import { registry } from "playwright-core/lib/server";
5
7
  /**
6
8
  * The Playwright this package drives: its version, and the CLI that ships
7
9
  * with it.
@@ -23,44 +25,157 @@ export function pinnedPlaywright() {
23
25
  /**
24
26
  * The command `versioncam install` runs, as argv.
25
27
  *
26
- * Both Chromium builds, deliberately: recording is headless and uses the
27
- * headless shell, while `login` and `preview` open a window a person uses
28
- * and need the full browser.
28
+ * The headless shell alone, unless asked for more. It is the Chromium that
29
+ * records: Playwright launches it for every headless run, and every recorder
30
+ * command but two is headless. It is also 190 MB where the full browser is
31
+ * 340 MB more, and a stranger's first ten minutes with the package were
32
+ * measured on 2026-10-28: on a slow line the two builds together took nine of
33
+ * them. `login` and `preview` open a window, which the shell cannot, so they
34
+ * fetch the full browser the first time they run; `--full` fetches both now,
35
+ * for a machine that will be offline then.
29
36
  */
30
- export function installArgv(node, cli, withDeps) {
37
+ export function installArgv(node, cli, options = {}) {
31
38
  return [
32
39
  node,
33
40
  cli,
34
41
  "install",
35
- ...(withDeps ? ["--with-deps"] : []),
42
+ ...(options.withDeps ? ["--with-deps"] : []),
43
+ ...(options.full ? [] : ["--only-shell"]),
36
44
  "chromium",
37
45
  ];
38
46
  }
47
+ /** The command that fetches the full browser alone, the shell being there. */
48
+ export function fullBrowserArgv(node, cli) {
49
+ return [node, cli, "install", "--no-shell", "chromium"];
50
+ }
51
+ /**
52
+ * Where the two Chromium builds this version uses are, or null for one that
53
+ * is not there.
54
+ *
55
+ * Asked of Playwright's own registry, which knows the build numbers and
56
+ * honours PLAYWRIGHT_BROWSERS_PATH; the public API names only the full
57
+ * browser's path. `lib/server` is not public API, which the exact pin on
58
+ * Playwright makes bearable: an upgrade is an event, and the tests ask the
59
+ * registry this question too.
60
+ */
61
+ export function browserPaths() {
62
+ const where = (name) => {
63
+ const found = registry.findExecutable(name)?.executablePath();
64
+ return found && existsSync(found) ? found : null;
65
+ };
66
+ return { shell: where("chromium-headless-shell"), full: where("chromium") };
67
+ }
68
+ /**
69
+ * Playwright's installer, its output on this terminal as it runs and kept
70
+ * as well, for `fallbackPlatform` to read what it refused. The exit code
71
+ * comes with `close`, not `exit`: the last of the output arrives between
72
+ * the two.
73
+ */
74
+ export const runInstaller = (command, args, env = {}) => new Promise((resolve) => {
75
+ let output = "";
76
+ const child = spawn(command, args, {
77
+ stdio: ["inherit", "pipe", "pipe"],
78
+ env: { ...process.env, ...env },
79
+ });
80
+ const tee = (to) => (chunk) => {
81
+ output += chunk.toString();
82
+ to.write(chunk);
83
+ };
84
+ child.stdout?.on("data", tee(process.stdout));
85
+ child.stderr?.on("data", tee(process.stderr));
86
+ child.on("error", (error) => {
87
+ process.stderr.write(`Could not run the installer: ${error.message}\n`);
88
+ resolve({ code: 1, output });
89
+ });
90
+ child.on("close", (code) => resolve({ code: code ?? 1, output }));
91
+ });
92
+ /**
93
+ * The platform to run the installer again as, when Playwright refused this
94
+ * one; null when there is none to try.
95
+ *
96
+ * Playwright knows the Ubuntu releases of its day and refuses a newer one
97
+ * outright, the browser as well as the system libraries: "Playwright does
98
+ * not support chromium-headless-shell on ubuntu26.04-x64". GitHub's
99
+ * ubuntu-latest became 26.04 in October 2026, and Playwright 1.59 says
100
+ * exactly that there. Told through PLAYWRIGHT_HOST_PLATFORM_OVERRIDE that
101
+ * the host is 24.04, the newest it knows, it installs that build and that
102
+ * list of libraries, and the clips record the same (a run of
103
+ * petbul/notify-test on 2026-10-31). Only Ubuntu, and only a newer one: for
104
+ * a distribution Playwright never knew there is no stand-in known to work,
105
+ * and its own message stands.
106
+ */
107
+ export function fallbackPlatform(output) {
108
+ const refused = /does not support \S+ on ubuntu(\d+)\.(\d+)-([a-z0-9]+)/.exec(output);
109
+ if (!refused)
110
+ return null;
111
+ const [, major, minor, arch] = refused;
112
+ const newer = Number(major) > 24 || (Number(major) === 24 && Number(minor) > 4);
113
+ return newer ? `ubuntu24.04-${arch}` : null;
114
+ }
115
+ /**
116
+ * The installer, and once more as a platform Playwright knows where it
117
+ * refused this one (`fallbackPlatform`), saying so between the two. An
118
+ * override the person set themselves is theirs: nothing second-guesses it.
119
+ */
120
+ export async function runWithFallback(command, args, io) {
121
+ const first = await io.run(command, args);
122
+ if (first.code === 0 || process.env.PLAYWRIGHT_HOST_PLATFORM_OVERRIDE)
123
+ return first.code;
124
+ const as = fallbackPlatform(first.output);
125
+ if (as === null)
126
+ return first.code;
127
+ io.write(`Playwright ${pinnedPlaywright().version} does not know this OS yet. Installing as ${as}, the newest Ubuntu it does, whose build and libraries record the same here:\n` +
128
+ ` PLAYWRIGHT_HOST_PLATFORM_OVERRIDE=${as} ${[command, ...args].join(" ")}\n`);
129
+ return (await io.run(command, args, { PLAYWRIGHT_HOST_PLATFORM_OVERRIDE: as })).code;
130
+ }
131
+ /**
132
+ * Before a command opens a window: the full browser, fetched once if `install`
133
+ * left it out. It says what it is doing first, since a download of a third of
134
+ * a gigabyte with no word on the terminal looks like a hang.
135
+ */
136
+ export async function ensureFullBrowser(io = {
137
+ has: () => browserPaths().full !== null,
138
+ run: runInstaller,
139
+ write: (text) => process.stdout.write(text),
140
+ }) {
141
+ if (io.has())
142
+ return true;
143
+ const playwright = pinnedPlaywright();
144
+ const [command, ...args] = fullBrowserArgv(process.execPath, playwright.cli);
145
+ io.write("This opens a window, which needs the full Chromium; `versioncam install` " +
146
+ "fetched only the headless shell that records.\n" +
147
+ `Fetching it once, for Playwright ${playwright.version}:\n` +
148
+ ` ${[command, ...args].join(" ")}\n`);
149
+ return (await runWithFallback(command, args, io)) === 0;
150
+ }
39
151
  /**
40
152
  * Install the Chromium this version of versioncam records with.
41
153
  *
42
154
  * `--with-deps` adds the system libraries Chromium needs on a bare Linux
43
155
  * image, which is the usual state of a CI runner and asks for root there.
44
- * The command it runs is printed first: in a CI log, which Playwright
45
- * installed which browser is the first question when something differs.
156
+ * `--full` adds the browser `login` and `preview` open. The command it runs
157
+ * is printed first: in a CI log, which Playwright installed which browser is
158
+ * the first question when something differs.
46
159
  */
47
160
  export async function install(argv) {
48
161
  const { values } = parseArgs({
49
162
  args: argv,
50
- options: { "with-deps": { type: "boolean" } },
163
+ options: { "with-deps": { type: "boolean" }, full: { type: "boolean" } },
51
164
  strict: false,
52
165
  });
53
166
  const playwright = pinnedPlaywright();
54
- const [command, ...args] = installArgv(process.execPath, playwright.cli, values["with-deps"] === true);
55
- process.stdout.write(`Chromium for Playwright ${playwright.version}, the version versioncam records with:\n` +
167
+ const full = values.full === true;
168
+ const [command, ...args] = installArgv(process.execPath, playwright.cli, {
169
+ withDeps: values["with-deps"] === true,
170
+ full,
171
+ });
172
+ process.stdout.write((full
173
+ ? `Both Chromium builds for Playwright ${playwright.version}: the headless shell versioncam records with, and the browser login and preview open:\n`
174
+ : `The headless Chromium versioncam records with, for Playwright ${playwright.version}:\n`) +
56
175
  ` ${[command, ...args].join(" ")}\n`);
57
- return new Promise((resolve) => {
58
- const child = spawn(command, args, { stdio: "inherit" });
59
- child.on("error", (error) => {
60
- process.stderr.write(`Could not run the installer: ${error.message}\n`);
61
- resolve(1);
62
- });
63
- child.on("exit", (code) => resolve(code ?? 1));
176
+ return runWithFallback(command, args, {
177
+ run: runInstaller,
178
+ write: (text) => process.stdout.write(text),
64
179
  });
65
180
  }
66
181
  //# sourceMappingURL=install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAC5D,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAwB,CAAC;IAC7D,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,GAAW,EACX,QAAiB;IAEjB,OAAO;QACL,IAAI;QACJ,GAAG;QACH,SAAS;QACT,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpC,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAC1C,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;QAC7C,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,gBAAgB,EAAE,CAAC;IACtC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,WAAW,CACpC,OAAO,CAAC,QAAQ,EAChB,UAAU,CAAC,GAAG,EACd,MAAM,CAAC,WAAW,CAAC,KAAK,IAAI,CAC7B,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2BAA2B,UAAU,CAAC,OAAO,0CAA0C;QACrF,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CACxC,CAAC;IACF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACzD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACxE,OAAO,CAAC,CAAC,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { launchBrowser } from "../../driver/launch.js";
2
+ import { ensureFullBrowser } from "./install.js";
2
3
  import { mkdir } from "node:fs/promises";
3
4
  import { dirname } from "node:path";
4
5
  import { loadConfig } from "../../loader.js";
@@ -21,6 +22,10 @@ export async function login() {
21
22
  return 1;
22
23
  }
23
24
  const storageState = auth.storageState;
25
+ // A window needs the full browser, which `install` leaves to the first
26
+ // command that opens one; fetched before the app is started, not under it.
27
+ if (!(await ensureFullBrowser()))
28
+ return 1;
24
29
  return drivingApp(config, async () => {
25
30
  const browser = await launchBrowser({ headless: false });
26
31
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAEzB,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2EAA2E;YACzE,wEAAwE,CAC3E,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACvC,OAAO,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEhC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,MAAM,CAAC,OAAO,+BAA+B;gBACzD,sCAAsC,CACzC,CAAC;YACF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;oBAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBACtB,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QACrD,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,YAAY,IAAI,CAAC,CAAC;QACjE,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAEzB,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2EAA2E;YACzE,wEAAwE,CAC3E,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACvC,uEAAuE;IACvE,2EAA2E;IAC3E,IAAI,CAAC,CAAC,MAAM,iBAAiB,EAAE,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEhC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,MAAM,CAAC,OAAO,+BAA+B;gBACzD,sCAAsC,CACzC,CAAC;YACF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;oBAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBACtB,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QACrD,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,YAAY,IAAI,CAAC,CAAC;QACjE,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -2,6 +2,7 @@ import { parseArgs } from "node:util";
2
2
  import { existsSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { launchBrowser } from "../../driver/launch.js";
5
+ import { ensureFullBrowser } from "./install.js";
5
6
  import { loadConfig } from "../../loader.js";
6
7
  import { renderConfigOf } from "../../config.js";
7
8
  import { bundleScenes, loadSceneIds } from "../../loader.js";
@@ -41,6 +42,11 @@ export async function preview(argv) {
41
42
  return 1;
42
43
  }
43
44
  }
45
+ // A window needs the full browser, which `install` leaves to the first
46
+ // command that opens one; after the checks above, so nothing is fetched
47
+ // for a recording that is not there.
48
+ if (!(await ensureFullBrowser()))
49
+ return 1;
44
50
  const browser = await launchBrowser({ headless: false });
45
51
  const context = await browser.newContext({
46
52
  viewport: { width: 1400, height: 1000 },
@@ -1 +1 @@
1
- {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/cli/commands/preview.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"preview.js","sourceRoot":"","sources":["../../../src/cli/commands/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAC1C,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACjE,MAAM,EAAE,KAAK;QACb,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,KAA2B,CAAC;IACnD,MAAM,EAAE,GAAG,OAAO,IAAK,WAAW,CAAC,CAAC,CAAwB,CAAC;IAC7D,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACxE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,sEAAsE;IACtE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CACxD,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,wEAAwE;IACxE,qCAAqC;IACrC,IAAI,CAAC,CAAC,MAAM,iBAAiB,EAAE,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC;QACvC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QACvC,iBAAiB,EAAE,CAAC;KACrB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IAErC,MAAM,mBAAmB,CAAC,IAAI,EAAE;QAC9B,OAAO,EAAE,WAAW,EAAE;QACtB,YAAY,EAAE,cAAc,CAAC,MAAM,CAAC;QACpC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG;QACvC,YAAY,EAAE,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,SAAS;KACxD,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,aAAa,KAAK,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC;IAEtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACrE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -13,4 +13,4 @@
13
13
  * is what comes after publishing: `versioncam cloud`, whose own usage is that
14
14
  * group. The last group is not a stage but a way to run any of them.
15
15
  */
16
- export declare const USAGE = "versioncam: record and render demo clips of a real app\n\nSet up\n versioncam install the Chromium this version of versioncam records with\n --with-deps and its system libraries (Linux CI)\n versioncam init install the authoring skill into .claude/\n --into <dir> into <dir>/versioncam/ instead, for another host\n --force overwrite files that are already there\n versioncam doctor check this machine can record, and that the app starts\n versioncam login sign in once and save the browser session\n\nWrite\n versioncam inspect <path> what a clip can click, and where each name came from\n --json machine-readable\n versioncam measure <path> <sel> where a selector's matches are, and what they say\n versioncam dsl the clip DSL: every method, its options and defaults\n\nRecord\n versioncam record [id\u2026] drive the app and capture frames\n --draft 15fps at CSS scale: cheap, for writing clips\n versioncam check [id\u2026] record every clip; exit 1 if any breaks\n --report <file> and write each clip's result there, as JSON\n versioncam stability [id\u2026] record each clip twice the same way; stable or not\n --runs <n> how many times (default 2)\n --full at full quality rather than draft\n\nReview\n versioncam sheet <id> an eight-frame contact sheet\n --at-marks sample the beats instead of even spacing\n versioncam frame <id> <n> one frame at output size, to a png\n --t <seconds> pick the frame by time instead\n --at <label> or by the beat it shows\n versioncam review <id> the checks that need no eyes; PASS/FAIL, exit 0/1\n --beats <file> [{ label, expect }] the clip promised\n --min <s> --max <s> duration bounds (default 9 and 11)\n versioncam preview <id> open the scrubber in a real browser\n --scene <id> preview a scene instead\n --frame <n> start at this frame\n\nOutput\n versioncam render [id\u2026] composite and encode recordings and scenes\n no ids: every one, stale recordings included\n --scene <id> and this scene, whatever the ids say (repeatable)\n --sequence stitch the results into one piece\n --report <file> and write what it made there, as JSON\n\nPublish\n versioncam publish [id\u2026] send the recordings and their checks to version.cam\n --dry-run print what would be sent, and send nothing\n --report <file> and write the living URLs there, as JSON\n\nManage\n versioncam cloud login sign in to version.cam, with a code you approve in a browser\n --label <name> what the approval page calls this machine\n versioncam cloud logout sign out: revoke the token, and delete it\n versioncam cloud status [project] each clip, current or broken, and what plays meanwhile\n versioncam cloud failure <clip> why a clip broke, and its picture, into .versioncam/failures/\n versioncam cloud ack <clip> \"I know, keep the old one\": the reminders stop\n versioncam cloud embed <clip> the snippets that embed a clip, and its files\n versioncam cloud set <name> <val> change a setting, once you approve it in a browser:\n visibility public|unlisted|private, retention <days>|off,\n viewers on|off, alerts email|slack <address>|off,\n alerts issues on|off\n versioncam cloud plan [account] the plan, and the pages to upgrade and pay on\n --project <owner/repo> which project, when not this repository's\n --json machine-readable, for status, failure, embed and plan\n\nFrom another directory\n versioncam <command> --cwd <dir> as if run in <dir>, which holds versioncam.config.ts\n versioncam --version which versioncam this is\n\nRun from a directory containing versioncam.config.ts, or name it with --cwd.\n";
16
+ export declare const USAGE = "versioncam: record and render demo clips of a real app\n\nSet up\n versioncam install the headless Chromium this version of versioncam records with\n --with-deps and its system libraries (Linux CI)\n --full and the full browser, which login and preview open\n versioncam init install the authoring skill into .claude/\n --into <dir> into <dir>/versioncam/ instead, for another host\n --force overwrite files that are already there\n versioncam doctor check this machine can record, and that the app starts\n versioncam login sign in once and save the browser session\n\nWrite\n versioncam inspect <path> what a clip can click, and where each name came from\n --json machine-readable\n versioncam measure <path> <sel> where a selector's matches are, and what they say\n versioncam dsl the clip DSL: every method, its options and defaults\n\nRecord\n versioncam record [id\u2026] drive the app and capture frames\n --draft 15fps at CSS scale: cheap, for writing clips\n versioncam check [id\u2026] record every clip; exit 1 if any breaks\n --report <file> and write each clip's result there, as JSON\n versioncam stability [id\u2026] record each clip twice the same way; stable or not\n --runs <n> how many times (default 2)\n --full at full quality rather than draft\n\nReview\n versioncam sheet <id> an eight-frame contact sheet\n --at-marks sample the beats instead of even spacing\n versioncam frame <id> <n> one frame at output size, to a png\n --t <seconds> pick the frame by time instead\n --at <label> or by the beat it shows\n versioncam review <id> the checks that need no eyes; PASS/FAIL, exit 0/1\n --beats <file> [{ label, expect }] the clip promised\n --min <s> --max <s> duration bounds (default 9 and 11)\n versioncam preview <id> open the scrubber in a real browser\n --scene <id> preview a scene instead\n --frame <n> start at this frame\n\nOutput\n versioncam render [id\u2026] composite and encode recordings and scenes\n no ids: every one, stale recordings included\n --scene <id> and this scene, whatever the ids say (repeatable)\n --sequence stitch the results into one piece\n --report <file> and write what it made there, as JSON\n\nPublish\n versioncam publish [id\u2026] send the recordings and their checks to version.cam\n --dry-run print what would be sent, and send nothing\n --report <file> and write the living URLs there, as JSON\n\nManage\n versioncam cloud login sign in to version.cam, with a code you approve in a browser\n --label <name> what the approval page calls this machine\n versioncam cloud logout sign out: revoke the token, and delete it\n versioncam cloud status [project] each clip, current or broken, and what plays meanwhile\n versioncam cloud failure <clip> why a clip broke, and its picture, into .versioncam/failures/\n versioncam cloud ack <clip> \"I know, keep the old one\": the reminders stop\n versioncam cloud embed <clip> the snippets that embed a clip, and its files\n versioncam cloud set <name> <val> change a setting, once you approve it in a browser:\n visibility public|unlisted|private, retention <days>|off,\n viewers on|off, alerts email|slack <address>|off,\n alerts issues on|off\n versioncam cloud plan [account] the plan, and the pages to upgrade and pay on\n --project <owner/repo> which project, when not this repository's\n --json machine-readable, for status, failure, embed and plan\n\nFrom another directory\n versioncam <command> --cwd <dir> as if run in <dir>, which holds versioncam.config.ts\n versioncam --version which versioncam this is\n\nRun from a directory containing versioncam.config.ts, or name it with --cwd.\n";
package/dist/cli/usage.js CHANGED
@@ -16,8 +16,9 @@
16
16
  export const USAGE = `versioncam: record and render demo clips of a real app
17
17
 
18
18
  Set up
19
- versioncam install the Chromium this version of versioncam records with
19
+ versioncam install the headless Chromium this version of versioncam records with
20
20
  --with-deps and its system libraries (Linux CI)
21
+ --full and the full browser, which login and preview open
21
22
  versioncam init install the authoring skill into .claude/
22
23
  --into <dir> into <dir>/versioncam/ instead, for another host
23
24
  --force overwrite files that are already there
@@ -1 +1 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwEpB,CAAC"}
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyEpB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "versioncam",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "type": "module",
5
5
  "description": "Record demo clips of a real web app: scripted, deterministic, re-recorded on every push.",
6
6
  "license": "FSL-1.1-ALv2",
@@ -11,7 +11,7 @@
11
11
  "url": "git+https://github.com/versioncam/versioncam.git",
12
12
  "directory": "packages/recorder"
13
13
  },
14
- "bugs": "https://github.com/versioncam/versioncam-home/issues",
14
+ "bugs": "https://github.com/versioncam/versioncam/issues",
15
15
  "keywords": [
16
16
  "demo",
17
17
  "video",
@@ -64,7 +64,8 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "esbuild": "^0.25.0",
67
- "playwright": "1.59.1"
67
+ "playwright": "1.59.1",
68
+ "playwright-core": "1.59.1"
68
69
  },
69
70
  "optionalDependencies": {
70
71
  "ffmpeg-static": "^5.2.0"
@@ -1,9 +1,15 @@
1
1
  {
2
2
  "name": "versioncam",
3
+ "version": "0.5.3",
3
4
  "description": "Record a short, true demo clip of a web app from one sentence: a skill that sets the repository up on its first run, writes the clip, and has a reviewer pass it from a contact sheet.",
4
5
  "author": {
5
6
  "name": "Peter Bulovec"
6
7
  },
7
8
  "homepage": "https://version.cam",
8
- "keywords": ["demo", "recording", "playwright", "screencast"]
9
+ "keywords": [
10
+ "demo",
11
+ "recording",
12
+ "playwright",
13
+ "screencast"
14
+ ]
9
15
  }
package/plugin/README.md CHANGED
@@ -30,6 +30,17 @@ Or, without copying anything, load the plugin directory as it is:
30
30
  claude --plugin-dir node_modules/versioncam/plugin
31
31
  ```
32
32
 
33
+ Or install it as a plugin from the repository's own marketplace, in a Claude
34
+ Code session (2.1.275 or later):
35
+
36
+ ```
37
+ /plugin install versioncam --marketplace versioncam/versioncam
38
+ ```
39
+
40
+ Loaded either of these two ways, the skill carries the plugin's name as a
41
+ prefix: `/versioncam:versioncam "<intent>"`. Installed by `init`, it is
42
+ `/versioncam`, as the examples below write it.
43
+
33
44
  ## Run it
34
45
 
35
46
  ```