versioncam 0.5.1 → 0.5.2

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,29 @@ 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.2 (2026-10-29)
10
+
11
+ A patch version: the config and the clip DSL are as they were. The README
12
+ now speaks to coding agents, the skill installs from the repository's own
13
+ marketplace, and the browser install is a third of what it was.
14
+
15
+ ### Changed
16
+
17
+ - The README has a section for coding agents: when versioncam fits, the exact
18
+ commands, and what to tell the person about the licence. Bugs and
19
+ questions go to github.com/versioncam/versioncam, where the source is
20
+ public since 2026-10-28.
21
+ - The skill installs as a Claude Code plugin from that repository's own
22
+ marketplace, `/plugin install versioncam --marketplace versioncam/versioncam`,
23
+ beside `versioncam init` and `--plugin-dir`; the plugin's manifest carries
24
+ the package's version.
25
+ - `versioncam install` fetches the headless shell alone, the Chromium that
26
+ records: 190 MB on a Mac, where both builds were 528. `login` and `preview`,
27
+ the two commands that open a window, fetch the full browser the first time
28
+ they run and say so first; `versioncam install --full` fetches both at once.
29
+ `doctor` reports the shell as `chromium`, and under `window` whether the
30
+ full browser is there, which is never a failure.
31
+
9
32
  ## 0.5.1 (2026-10-11)
10
33
 
11
34
  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
@@ -904,7 +945,8 @@ The words these pages use in a particular sense.
904
945
  ## Help
905
946
 
906
947
  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).
948
+ [github.com/versioncam/versioncam](https://github.com/versioncam/versioncam/issues),
949
+ where the source is.
908
950
  A clip that will not reproduce is easiest to help with alongside the two
909
951
  pictures `versioncam stability` saves.
910
952
 
@@ -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":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EACL,SAAS,EACT,cAAc,EACd,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AAIzB,MAAM,WAAW,GACf,yFAAyF,CAAC;AAE5F;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,QAAQ,CAAC,GAAW;IACjC,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,KAAK;YACX,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,wBAAyB,KAAe,CAAC,OAAO,EAAE;YAC1D,GAAG,EAAE,6DAA6D;SACnE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC,EAAE;YACd,CAAC,CAAC;gBACE,IAAI,EAAE,KAAK;gBACX,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,sBAAsB,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,MAAM,GAAG;aACvE;YACH,CAAC,CAAC;gBACE,IAAI,EAAE,KAAK;gBACX,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE;gBAC7C,GAAG,EAAE,WAAW;aACjB,CAAC;IACR,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO;YACL,IAAI,EAAE,KAAK;YACX,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;SACnE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oEAAoE;QACpE,gDAAgD;QAChD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAI,KAAe,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACzE,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,EAAE;SAChE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uEAAuE;QACvE,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAI,KAAe,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5E,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,MAAM;QACZ,EAAE,EAAE,KAAK,IAAI,EAAE;QACf,MAAM,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;QACnC,GAAG,EAAE,2BAA2B;KACjC,CAAC,CAAC;IAEH,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,YAAY,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,YAAY,GAAG,EAAE,CAAC;IACpB,CAAC;IACD,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,UAAU;QAChB,EAAE,EAAE,YAAY,KAAK,EAAE,IAAI,UAAU,CAAC,YAAY,CAAC;QACnD,MAAM,EAAE,YAAY,IAAI,eAAe;QACvC,GAAG,EAAE,wBAAwB;KAC9B,CAAC,CAAC;IAEH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;IAC3C,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,QAAQ;QACd,EAAE,EAAE,MAAM,KAAK,IAAI;QACnB,MAAM,EAAE,MAAM,IAAI,WAAW;QAC7B,GAAG,EAAE,8CAA8C;KACpD,CAAC,CAAC;IACH,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,OAAO,KAAK,IAAI;QACpB,MAAM,EAAE,OAAO,IAAI,WAAW;QAC9B,GAAG,EAAE,0DAA0D;KAChE,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,QAAQ;QACd,EAAE,EAAE,MAAM,KAAK,IAAI;QACnB,MAAM,EAAE,MAAM,IAAI,8BAA8B,OAAO,CAAC,GAAG,EAAE,EAAE;QAC/D,GAAG,EAAE,SAAS;KACf,CAAC,CAAC;IAEH,2EAA2E;IAC3E,2BAA2B;IAC3B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CACpE,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -17,17 +17,56 @@ 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
+ /** Playwright's installer, with its output on this terminal; its exit code. */
50
+ export declare function runInstaller(command: string, args: string[]): Promise<number>;
51
+ /** What `ensureFullBrowser` touches, so a test can stand in for all of it. */
52
+ export type InstallerIO = {
53
+ has: () => boolean;
54
+ run: (command: string, args: string[]) => Promise<number>;
55
+ write: (text: string) => void;
56
+ };
57
+ /**
58
+ * Before a command opens a window: the full browser, fetched once if `install`
59
+ * left it out. It says what it is doing first, since a download of a third of
60
+ * a gigabyte with no word on the terminal looks like a hang.
61
+ */
62
+ export declare function ensureFullBrowser(io?: InstallerIO): Promise<boolean>;
25
63
  /**
26
64
  * Install the Chromium this version of versioncam records with.
27
65
  *
28
66
  * `--with-deps` adds the system libraries Chromium needs on a bare Linux
29
67
  * 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.
68
+ * `--full` adds the browser `login` and `preview` open. The command it runs
69
+ * is printed first: in a CI log, which Playwright installed which browser is
70
+ * the first question when something differs.
32
71
  */
33
72
  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,102 @@ 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
+ /** Playwright's installer, with its output on this terminal; its exit code. */
69
+ export function runInstaller(command, args) {
70
+ return new Promise((resolve) => {
71
+ const child = spawn(command, args, { stdio: "inherit" });
72
+ child.on("error", (error) => {
73
+ process.stderr.write(`Could not run the installer: ${error.message}\n`);
74
+ resolve(1);
75
+ });
76
+ child.on("exit", (code) => resolve(code ?? 1));
77
+ });
78
+ }
79
+ /**
80
+ * Before a command opens a window: the full browser, fetched once if `install`
81
+ * left it out. It says what it is doing first, since a download of a third of
82
+ * a gigabyte with no word on the terminal looks like a hang.
83
+ */
84
+ export async function ensureFullBrowser(io = {
85
+ has: () => browserPaths().full !== null,
86
+ run: runInstaller,
87
+ write: (text) => process.stdout.write(text),
88
+ }) {
89
+ if (io.has())
90
+ return true;
91
+ const playwright = pinnedPlaywright();
92
+ const [command, ...args] = fullBrowserArgv(process.execPath, playwright.cli);
93
+ io.write("This opens a window, which needs the full Chromium; `versioncam install` " +
94
+ "fetched only the headless shell that records.\n" +
95
+ `Fetching it once, for Playwright ${playwright.version}:\n` +
96
+ ` ${[command, ...args].join(" ")}\n`);
97
+ return (await io.run(command, args)) === 0;
98
+ }
39
99
  /**
40
100
  * Install the Chromium this version of versioncam records with.
41
101
  *
42
102
  * `--with-deps` adds the system libraries Chromium needs on a bare Linux
43
103
  * 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.
104
+ * `--full` adds the browser `login` and `preview` open. The command it runs
105
+ * is printed first: in a CI log, which Playwright installed which browser is
106
+ * the first question when something differs.
46
107
  */
47
108
  export async function install(argv) {
48
109
  const { values } = parseArgs({
49
110
  args: argv,
50
- options: { "with-deps": { type: "boolean" } },
111
+ options: { "with-deps": { type: "boolean" }, full: { type: "boolean" } },
51
112
  strict: false,
52
113
  });
53
114
  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` +
56
- ` ${[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));
115
+ const full = values.full === true;
116
+ const [command, ...args] = installArgv(process.execPath, playwright.cli, {
117
+ withDeps: values["with-deps"] === true,
118
+ full,
64
119
  });
120
+ process.stdout.write((full
121
+ ? `Both Chromium builds for Playwright ${playwright.version}: the headless shell versioncam records with, and the browser login and preview open:\n`
122
+ : `The headless Chromium versioncam records with, for Playwright ${playwright.version}:\n`) +
123
+ ` ${[command, ...args].join(" ")}\n`);
124
+ return runInstaller(command, args);
65
125
  }
66
126
  //# 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":"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"}
@@ -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.2",
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.2",
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
  ```