versioncam 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +116 -13
  3. package/dist/cli/commands/doctor.js +39 -2
  4. package/dist/cli/commands/doctor.js.map +1 -1
  5. package/dist/cli/commands/init.js +25 -0
  6. package/dist/cli/commands/init.js.map +1 -1
  7. package/dist/cli/commands/preview.js +10 -1
  8. package/dist/cli/commands/preview.js.map +1 -1
  9. package/dist/cli/commands/render.d.ts +17 -0
  10. package/dist/cli/commands/render.js +78 -21
  11. package/dist/cli/commands/render.js.map +1 -1
  12. package/dist/cli/cwd.d.ts +46 -0
  13. package/dist/cli/cwd.js +102 -0
  14. package/dist/cli/cwd.js.map +1 -0
  15. package/dist/cli/main.js +11 -2
  16. package/dist/cli/main.js.map +1 -1
  17. package/dist/cli/usage.d.ts +3 -2
  18. package/dist/cli/usage.js +9 -4
  19. package/dist/cli/usage.js.map +1 -1
  20. package/dist/config.d.ts +24 -0
  21. package/dist/config.js +25 -0
  22. package/dist/config.js.map +1 -1
  23. package/dist/core/camera-track.d.ts +63 -0
  24. package/dist/core/camera-track.js +230 -0
  25. package/dist/core/camera-track.js.map +1 -0
  26. package/dist/core/camera.d.ts +14 -1
  27. package/dist/core/camera.js +18 -2
  28. package/dist/core/camera.js.map +1 -1
  29. package/dist/core/follow.d.ts +129 -0
  30. package/dist/core/follow.js +151 -0
  31. package/dist/core/follow.js.map +1 -0
  32. package/dist/core/motion-defaults.d.ts +29 -0
  33. package/dist/core/motion-defaults.js +29 -0
  34. package/dist/core/motion-defaults.js.map +1 -1
  35. package/dist/core/timeline.d.ts +10 -2
  36. package/dist/core/timeline.js.map +1 -1
  37. package/dist/driver/session.d.ts +22 -1
  38. package/dist/driver/session.js +48 -12
  39. package/dist/driver/session.js.map +1 -1
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.js +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/loader.d.ts +7 -1
  44. package/dist/loader.js +23 -8
  45. package/dist/loader.js.map +1 -1
  46. package/dist/page/assets/index-fZtacWyp.js +2 -0
  47. package/dist/page/index.html +1 -1
  48. package/dist/render/encode.d.ts +12 -1
  49. package/dist/render/encode.js +94 -35
  50. package/dist/render/encode.js.map +1 -1
  51. package/dist/render/presentation.d.ts +12 -0
  52. package/dist/render/presentation.js +15 -0
  53. package/dist/render/presentation.js.map +1 -1
  54. package/dist/render/render.js +18 -1
  55. package/dist/render/render.js.map +1 -1
  56. package/dist/render/sampling.d.ts +13 -0
  57. package/dist/render/sampling.js +47 -19
  58. package/dist/render/sampling.js.map +1 -1
  59. package/dist/render/scenes.d.ts +16 -0
  60. package/dist/render/scenes.js +108 -0
  61. package/dist/render/scenes.js.map +1 -0
  62. package/dist/render/sequence.d.ts +18 -0
  63. package/dist/render/sequence.js +67 -13
  64. package/dist/render/sequence.js.map +1 -1
  65. package/dist/review/review.js +46 -21
  66. package/dist/review/review.js.map +1 -1
  67. package/dsl.md +37 -0
  68. package/package.json +1 -1
  69. package/plugin/README.md +7 -2
  70. package/plugin/agents/versioncam-reviewer.md +3 -2
  71. package/plugin/skills/versioncam/SKILL.md +60 -14
  72. package/plugin/skills/versioncam/authoring.md +6 -1
  73. package/plugin/skills/versioncam/onboarding.md +17 -17
  74. package/dist/page/assets/index-DUom5amc.js +0 -1
@@ -4,18 +4,40 @@ import { join } from "node:path";
4
4
  import { launchBrowser } from "../../driver/launch.js";
5
5
  import { loadConfig, loadSceneIds } from "../../loader.js";
6
6
  import { renderRecording, renderScene } from "../../render/render.js";
7
+ import { missingScenes } from "../../render/scenes.js";
7
8
  import { buildSequence } from "../../render/sequence.js";
8
- /** Recordings on disk, newest config first, filtered by substring. */
9
- function recordedIds(recordingsDir, only) {
9
+ /** Every recording on disk, by id. */
10
+ function recordedIds(recordingsDir) {
10
11
  if (!existsSync(recordingsDir))
11
12
  return [];
12
13
  return readdirSync(recordingsDir, { withFileTypes: true })
13
14
  .filter((e) => e.isDirectory())
14
15
  .map((e) => e.name)
15
16
  .filter((id) => existsSync(join(recordingsDir, id, "timeline.json")))
16
- .filter((id) => only.length === 0 || only.some((n) => id.includes(n)))
17
17
  .sort();
18
18
  }
19
+ /**
20
+ * What `render` renders, from what there is and what was asked for.
21
+ *
22
+ * Ids are substrings, as everywhere else (`render 05` is the clip with 05 in
23
+ * its id), and they choose among the recordings and the scenes alike. A
24
+ * `--scene` names one scene exactly, and it renders whatever the ids say: it
25
+ * used to be filtered by them as well, so `render 02 04 --scene 01-intro`
26
+ * rendered no scene at all. With no ids, every recording on disk renders,
27
+ * and every scene unless `--scene` named the ones wanted.
28
+ *
29
+ * `unmatched` is the ids that choose nothing.
30
+ */
31
+ export function chooseTargets(recorded, defined, ids, named) {
32
+ const matches = (id) => ids.some((n) => id.includes(n));
33
+ return {
34
+ recordings: ids.length > 0 ? recorded.filter(matches) : recorded,
35
+ scenes: defined.filter((id) => named.includes(id) ||
36
+ (ids.length > 0 ? matches(id) : named.length === 0)),
37
+ unmatched: ids.filter((n) => !recorded.some((id) => id.includes(n)) &&
38
+ !defined.some((id) => id.includes(n))),
39
+ };
40
+ }
19
41
  export async function render(argv) {
20
42
  const { positionals, values } = parseArgs({
21
43
  args: argv,
@@ -27,13 +49,34 @@ export async function render(argv) {
27
49
  allowPositionals: true,
28
50
  });
29
51
  const config = await loadConfig(process.cwd());
30
- const only = positionals;
31
- const wantedScenes = values.scene ?? [];
32
- // With no `--scene`, every scene the app defines is rendered too: a config
33
- // that names a scenes module means those scenes are part of the deliverable.
34
- const sceneIds = wantedScenes.length > 0 ? wantedScenes : await loadSceneIds(config);
35
- const recordings = recordedIds(config.recordingsDir, only);
36
- if (recordings.length === 0 && sceneIds.length === 0) {
52
+ const ids = positionals;
53
+ const named = values.scene ?? [];
54
+ // Everything asked for is checked before anything renders. A render takes
55
+ // minutes, and the output of one missing a clip looks finished: a film
56
+ // stitched from four clips of six says nothing about the other two.
57
+ const defined = await loadSceneIds(config);
58
+ const unknown = named.filter((id) => !defined.includes(id));
59
+ if (unknown.length > 0) {
60
+ process.stderr.write(`${missingScenes(unknown, defined, config.scenes)}\n`);
61
+ return 1;
62
+ }
63
+ const recorded = recordedIds(config.recordingsDir);
64
+ const { recordings, scenes, unmatched } = chooseTargets(recorded, defined, ids, named);
65
+ // An id that chooses nothing is a typo, or a clip not recorded yet.
66
+ if (unmatched.length > 0) {
67
+ for (const id of unmatched) {
68
+ process.stderr.write(`No recording or scene has "${id}" in its id.\n`);
69
+ }
70
+ process.stderr.write(`Recorded, in ${config.recordingsDir}: ` +
71
+ (recorded.length > 0
72
+ ? `${recorded.join(", ")}.\n`
73
+ : "nothing yet. Run `versioncam record` first.\n"));
74
+ if (config.scenes) {
75
+ process.stderr.write(`Scenes, in ${config.scenes}: ${defined.join(", ") || "none"}.\n`);
76
+ }
77
+ return 1;
78
+ }
79
+ if (recordings.length === 0 && scenes.length === 0) {
37
80
  process.stderr.write(`Nothing to render. Run \`versioncam record\` first; recordings live in ${config.recordingsDir}.\n`);
38
81
  return 1;
39
82
  }
@@ -52,9 +95,7 @@ export async function render(argv) {
52
95
  failures.push({ id, error: error });
53
96
  }
54
97
  }
55
- for (const id of sceneIds) {
56
- if (only.length > 0 && !only.some((n) => id.includes(n)))
57
- continue;
98
+ for (const id of scenes) {
58
99
  try {
59
100
  const out = await renderScene(browser, config, id);
60
101
  rendered.push(id);
@@ -68,18 +109,34 @@ export async function render(argv) {
68
109
  finally {
69
110
  await browser.close();
70
111
  }
71
- if (values.sequence && rendered.length >= 2) {
112
+ if (values.sequence) {
72
113
  // The config's order when it states one, since a sequence is an argument
73
114
  // and not an accident of how the directory happens to sort.
74
115
  const order = config.sequence ?? rendered;
75
- const result = await buildSequence(order.filter((id) => rendered.includes(id)), config.outputDir);
76
- process.stdout.write(` sequence: ${result.used.length} clips, ${result.total.toFixed(1)}s\n`);
77
- if (result.missing.length > 0) {
78
- process.stdout.write(` (not rendered: ${result.missing.join(", ")})\n`);
116
+ const stitched = order.filter((id) => rendered.includes(id));
117
+ let unusable = [];
118
+ if (stitched.length >= 2) {
119
+ const result = await buildSequence(stitched, config.outputDir);
120
+ unusable = result.missing;
121
+ process.stdout.write(` sequence: ${result.used.length} clips, ${result.total.toFixed(1)}s\n`);
122
+ }
123
+ else {
124
+ process.stderr.write(" sequence needs at least two rendered clips.\n");
125
+ }
126
+ // What the piece was stitched without, as plainly as what it was
127
+ // stitched from: four clips of six look finished. The config's sequence
128
+ // says what belongs in it, and a run can render less than that, or more.
129
+ const absent = [
130
+ ...order.filter((id) => !rendered.includes(id)),
131
+ ...unusable,
132
+ ];
133
+ if (absent.length > 0) {
134
+ process.stdout.write(` (not rendered: ${absent.join(", ")})\n`);
135
+ }
136
+ const unlisted = rendered.filter((id) => !order.includes(id));
137
+ if (unlisted.length > 0) {
138
+ process.stdout.write(` (not in the config's sequence: ${unlisted.join(", ")})\n`);
79
139
  }
80
- }
81
- else if (values.sequence) {
82
- process.stderr.write(" sequence needs at least two rendered clips.\n");
83
140
  }
84
141
  if (failures.length > 0) {
85
142
  process.stderr.write("\n");
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/cli/commands/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,sEAAsE;AACtE,SAAS,WAAW,CAAC,aAAqB,EAAE,IAAc;IACxD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,OAAO,WAAW,CAAC,aAAa,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SACvD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;SACpE,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;SACrE,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAc;IACzC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzC,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC9B;QACD,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,IAAI,GAAG,WAAuB,CAAC;IACrC,MAAM,YAAY,GAAI,MAAM,CAAC,KAA8B,IAAI,EAAE,CAAC;IAElE,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,QAAQ,GACZ,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAE3D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0EAA0E,MAAM,CAAC,aAAa,KAAK,CACpG,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAmC,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,EAAE,KAAK,GAAG,CAAC,cAAc,cAAc,GAAG,CAAC,GAAG,MAAM;oBACvD,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CACtD,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAAE,SAAS;YACnE,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,EAAE,aAAa,GAAG,CAAC,cAAc,cAAc,GAAG,CAAC,GAAG,OAAO,CACnE,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC5C,yEAAyE;QACzE,4DAA4D;QAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,aAAa,CAChC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAC3C,MAAM,CAAC,SAAS,CACjB,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,eAAe,MAAM,CAAC,IAAI,CAAC,MAAM,WAAW,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CACzE,CAAC;QACF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,QAAQ,EAAE,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/cli/commands/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * `--cwd <dir>`: run a command as if from `<dir>`.
3
+ *
4
+ * Every command works in the directory that holds `versioncam.config.ts`:
5
+ * the config, `.env.recording` and `.env`, `.versioncam/`, and any relative
6
+ * path a command is given or prints are that directory's. In a monorepo the
7
+ * app is one directory among many, and whatever runs versioncam may be
8
+ * somewhere else: a script at the repository root, or an agent whose session
9
+ * started inside the app, below its config, and which may not `cd` out of
10
+ * the directory it started in.
11
+ *
12
+ * Its own module so a test can reach it without running the CLI.
13
+ */
14
+ /**
15
+ * `--cwd <dir>` or `--cwd=<dir>`, taken out of the arguments, from anywhere
16
+ * among them. If it is given twice, the last one counts.
17
+ *
18
+ * Anywhere, not only before the command's name, because what an agent may
19
+ * run is a prefix: the reviewer is allowed `npx versioncam frame *` and
20
+ * nothing else, so its flag has to be able to come after `frame`.
21
+ */
22
+ export declare function takeCwd(argv: string[]): {
23
+ cwd: string | undefined;
24
+ rest: string[];
25
+ };
26
+ /**
27
+ * The versioncam a config in `dir` imports: the first `node_modules/versioncam`
28
+ * from `dir` up, which is where Node looks for a bare `import "versioncam"`.
29
+ * Null where there is none.
30
+ *
31
+ * Resolved through symlinks, so an `npm link` or a pnpm store compares as
32
+ * the directory it really is.
33
+ */
34
+ export declare function versioncamFrom(dir: string): string | null;
35
+ /**
36
+ * Move into `dir` for the rest of the command, or say why not.
37
+ *
38
+ * Only the directory moves, though, and not the versioncam running: `npx`
39
+ * finds the binary in the directory it runs in and in those above it, never
40
+ * below. Run from above an app that has versioncam in its own
41
+ * `node_modules`, it runs another copy, or downloads the latest one, and that
42
+ * copy would record with a Chromium the app never pinned, beside a config
43
+ * that imports the app's own. So a directory whose own versioncam is not the
44
+ * one running is refused, with how to run its own.
45
+ */
46
+ export declare function enterCwd(dir: string): void;
@@ -0,0 +1,102 @@
1
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
2
+ import { dirname, join, relative, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * `--cwd <dir>`: run a command as if from `<dir>`.
6
+ *
7
+ * Every command works in the directory that holds `versioncam.config.ts`:
8
+ * the config, `.env.recording` and `.env`, `.versioncam/`, and any relative
9
+ * path a command is given or prints are that directory's. In a monorepo the
10
+ * app is one directory among many, and whatever runs versioncam may be
11
+ * somewhere else: a script at the repository root, or an agent whose session
12
+ * started inside the app, below its config, and which may not `cd` out of
13
+ * the directory it started in.
14
+ *
15
+ * Its own module so a test can reach it without running the CLI.
16
+ */
17
+ /**
18
+ * `--cwd <dir>` or `--cwd=<dir>`, taken out of the arguments, from anywhere
19
+ * among them. If it is given twice, the last one counts.
20
+ *
21
+ * Anywhere, not only before the command's name, because what an agent may
22
+ * run is a prefix: the reviewer is allowed `npx versioncam frame *` and
23
+ * nothing else, so its flag has to be able to come after `frame`.
24
+ */
25
+ export function takeCwd(argv) {
26
+ let cwd;
27
+ const rest = [];
28
+ for (let i = 0; i < argv.length; i++) {
29
+ const arg = argv[i];
30
+ if (arg !== "--cwd" && !arg.startsWith("--cwd=")) {
31
+ rest.push(arg);
32
+ continue;
33
+ }
34
+ const value = arg === "--cwd" ? argv[++i] : arg.slice("--cwd=".length);
35
+ // A flag where the directory should be is a directory left out, not a
36
+ // directory called `--draft`.
37
+ if (!value || value.startsWith("-")) {
38
+ throw new Error("`--cwd` needs a directory: versioncam <command> --cwd <dir>");
39
+ }
40
+ cwd = value;
41
+ }
42
+ return { cwd, rest };
43
+ }
44
+ /**
45
+ * The versioncam a config in `dir` imports: the first `node_modules/versioncam`
46
+ * from `dir` up, which is where Node looks for a bare `import "versioncam"`.
47
+ * Null where there is none.
48
+ *
49
+ * Resolved through symlinks, so an `npm link` or a pnpm store compares as
50
+ * the directory it really is.
51
+ */
52
+ export function versioncamFrom(dir) {
53
+ for (let at = resolve(dir);; at = dirname(at)) {
54
+ const candidate = join(at, "node_modules", "versioncam");
55
+ if (existsSync(join(candidate, "package.json"))) {
56
+ return realpathSync(candidate);
57
+ }
58
+ if (dirname(at) === at)
59
+ return null;
60
+ }
61
+ }
62
+ /** This package, where it really is: two levels above this file. */
63
+ const RUNNING = realpathSync(resolve(dirname(fileURLToPath(import.meta.url)), "..", ".."));
64
+ /** "versioncam 0.1.3 in <dir>", without the version if it cannot be read. */
65
+ function nameOf(pkg) {
66
+ try {
67
+ const { version } = JSON.parse(readFileSync(join(pkg, "package.json"), "utf8"));
68
+ if (version)
69
+ return `versioncam ${version} in ${pkg}`;
70
+ }
71
+ catch {
72
+ // Named by its directory alone, which is the part that matters.
73
+ }
74
+ return `versioncam in ${pkg}`;
75
+ }
76
+ /**
77
+ * Move into `dir` for the rest of the command, or say why not.
78
+ *
79
+ * Only the directory moves, though, and not the versioncam running: `npx`
80
+ * finds the binary in the directory it runs in and in those above it, never
81
+ * below. Run from above an app that has versioncam in its own
82
+ * `node_modules`, it runs another copy, or downloads the latest one, and that
83
+ * copy would record with a Chromium the app never pinned, beside a config
84
+ * that imports the app's own. So a directory whose own versioncam is not the
85
+ * one running is refused, with how to run its own.
86
+ */
87
+ export function enterCwd(dir) {
88
+ const target = resolve(dir);
89
+ if (!existsSync(target) || !statSync(target).isDirectory()) {
90
+ throw new Error(`\`--cwd ${dir}\`: there is no directory ${target}.`);
91
+ }
92
+ const theirs = versioncamFrom(target);
93
+ if (theirs !== null && theirs !== RUNNING) {
94
+ const shown = relative(process.cwd(), target) || ".";
95
+ throw new Error(`\`--cwd ${dir}\`: that directory has its own ${nameOf(theirs)}, ` +
96
+ `and this is ${nameOf(RUNNING)}.\n` +
97
+ "npx looks for versioncam in the directory it runs in and in those above it, never below.\n" +
98
+ `Run the directory's own instead: cd ${shown}, then the same command without --cwd.`);
99
+ }
100
+ process.chdir(target);
101
+ }
102
+ //# sourceMappingURL=cwd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cwd.js","sourceRoot":"","sources":["../../src/cli/cwd.ts"],"names":[],"mappings":"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"}
package/dist/cli/main.js CHANGED
@@ -16,6 +16,7 @@ import { review } from "./commands/review.js";
16
16
  import { sheet } from "./commands/sheet.js";
17
17
  import { stability } from "./commands/stability.js";
18
18
  import { loadEnvFiles } from "../env.js";
19
+ import { enterCwd, takeCwd } from "./cwd.js";
19
20
  import { USAGE } from "./usage.js";
20
21
  const COMMANDS = {
21
22
  record,
@@ -35,7 +36,9 @@ const COMMANDS = {
35
36
  init,
36
37
  };
37
38
  async function main() {
38
- const argv = process.argv.slice(2);
39
+ // `--cwd` comes out first: it takes a value, which the parsing below would
40
+ // otherwise read as the command's name.
41
+ const { cwd, rest: argv } = takeCwd(process.argv.slice(2));
39
42
  // `--help` is a flag, not a positional, so it never reaches `positionals`.
40
43
  // Asking for help is a success; being given nothing is not.
41
44
  if (argv.some((a) => a === "--help" || a === "-h" || a === "help")) {
@@ -57,8 +60,14 @@ async function main() {
57
60
  process.stderr.write(`Unknown command "${name}".\n\n${USAGE}`);
58
61
  return 1;
59
62
  }
63
+ // Before the environment files, which are that directory's too.
64
+ if (cwd !== undefined)
65
+ enterCwd(cwd);
60
66
  loadEnvFiles(process.cwd());
61
- return command(process.argv.slice(3));
67
+ // The command's own arguments: everything but its name, wherever the name
68
+ // was, which is first unless a flag came before it.
69
+ const at = argv.indexOf(name);
70
+ return command([...argv.slice(0, at), ...argv.slice(at + 1)]);
62
71
  }
63
72
  main().then((code) => {
64
73
  process.exitCode = code;
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,MAAM,QAAQ,GAA4B;IACxC,MAAM;IACN,MAAM;IACN,KAAK;IACL,SAAS;IACT,KAAK;IACL,KAAK;IACL,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,GAAG;IACH,KAAK;IACL,MAAM;IACN,OAAO;IACP,IAAI;CACL,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,2EAA2E;IAC3E,wCAAwC;IACxC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3D,2EAA2E;IAC3E,4DAA4D;IAC5D,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QAChC,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,KAAK;QACb,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,IAAI,SAAS,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,gEAAgE;IAChE,IAAI,GAAG,KAAK,SAAS;QAAE,QAAQ,CAAC,GAAG,CAAC,CAAC;IACrC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAE5B,0EAA0E;IAC1E,oDAAoD;IACpD,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CACT,CAAC,IAAI,EAAE,EAAE;IACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,EACD,CAAC,KAAY,EAAE,EAAE;IACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CACF,CAAC"}
@@ -9,6 +9,7 @@
9
9
  *
10
10
  * Grouped by the stage of the work each command belongs to, in the order a
11
11
  * repository meets them. A flat list of seventeen commands left a newcomer to
12
- * work out that `inspect` comes before `record` and `sheet` after it.
12
+ * work out that `inspect` comes before `record` and `sheet` after it. The
13
+ * last group is not a stage but a way to run any of them.
13
14
  */
14
- 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 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 what has been recorded\n --scene <id> render a designed scene (repeatable)\n --sequence stitch the results into one piece\n\nRun from a directory containing versioncam.config.ts.\n";
15
+ 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 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\nFrom another directory\n versioncam <command> --cwd <dir> as if run in <dir>, which holds versioncam.config.ts\n\nRun from a directory containing versioncam.config.ts, or name it with --cwd.\n";
package/dist/cli/usage.js CHANGED
@@ -9,7 +9,8 @@
9
9
  *
10
10
  * Grouped by the stage of the work each command belongs to, in the order a
11
11
  * repository meets them. A flat list of seventeen commands left a newcomer to
12
- * work out that `inspect` comes before `record` and `sheet` after it.
12
+ * work out that `inspect` comes before `record` and `sheet` after it. The
13
+ * last group is not a stage but a way to run any of them.
13
14
  */
14
15
  export const USAGE = `versioncam: record and render demo clips of a real app
15
16
 
@@ -50,10 +51,14 @@ Review
50
51
  --frame <n> start at this frame
51
52
 
52
53
  Output
53
- versioncam render [id…] composite and encode what has been recorded
54
- --scene <id> render a designed scene (repeatable)
54
+ versioncam render [id…] composite and encode recordings and scenes
55
+ no ids: every one, stale recordings included
56
+ --scene <id> and this scene, whatever the ids say (repeatable)
55
57
  --sequence stitch the results into one piece
56
58
 
57
- Run from a directory containing versioncam.config.ts.
59
+ From another directory
60
+ versioncam <command> --cwd <dir> as if run in <dir>, which holds versioncam.config.ts
61
+
62
+ Run from a directory containing versioncam.config.ts, or name it with --cwd.
58
63
  `;
59
64
  //# sourceMappingURL=usage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CpB,CAAC"}
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDpB,CAAC"}
package/dist/config.d.ts CHANGED
@@ -31,6 +31,25 @@ export type Presentation = {
31
31
  padding?: number;
32
32
  /** "auto" puts it below the app when padded, and over it when not. */
33
33
  caption?: "auto" | "below" | "overlay" | "none";
34
+ /**
35
+ * Where a caption over the app sits: `{ left: n }` or `{ right: n }`,
36
+ * pixels of the video in from that side, which also picks the bottom
37
+ * corner. Default `{ left: 40 }`.
38
+ *
39
+ * An app keeps its own controls in a corner as often as not (an account
40
+ * menu at the foot of a sidebar, a map's legend), and a caption fixed over
41
+ * one hides what a clip may be pointing at. Ignored when the caption sits
42
+ * below the app, where there is nothing of the app to cover.
43
+ */
44
+ captionInset?: CaptionInset;
45
+ };
46
+ /** One side and a distance from it, as CSS's `left` and `right` say it. */
47
+ export type CaptionInset = {
48
+ left: number;
49
+ right?: never;
50
+ } | {
51
+ right: number;
52
+ left?: never;
34
53
  };
35
54
  export type AuthConfig = {
36
55
  storageState: string;
@@ -246,5 +265,10 @@ export type RenderConfig = {
246
265
  presentation: Presentation | null;
247
266
  };
248
267
  motion: Motion;
268
+ /**
269
+ * The scenes module's path. The page is served a bundle of it, and names
270
+ * the file it came from when it cannot read the scenes out of it.
271
+ */
272
+ scenes: string | null;
249
273
  };
250
274
  export declare function renderConfigOf(config: ResolvedConfig): RenderConfig;
package/dist/config.js CHANGED
@@ -13,6 +13,27 @@ function positiveInt(value, field) {
13
13
  }
14
14
  return value;
15
15
  }
16
+ /**
17
+ * A caption inset names one side, and a distance that keeps the caption on
18
+ * the video.
19
+ *
20
+ * Checked because a caption placed off the video fails the way nothing in
21
+ * the presentation layer should: without an error, and without a caption.
22
+ */
23
+ function checkCaptionInset(inset, outputWidth) {
24
+ const field = "theme.presentation.captionInset";
25
+ const given = inset;
26
+ const sides = ["left", "right"].filter((side) => given?.[side] !== undefined);
27
+ if (given === null || sides.length !== 1) {
28
+ fail(field, "must be `{ left: n }` or `{ right: n }`, one side only");
29
+ }
30
+ const px = given[sides[0]];
31
+ if (typeof px !== "number" || !(px >= 0 && px < outputWidth)) {
32
+ // Quoted when it is a string, or `"40"` would read as the 40 it is not.
33
+ const got = typeof px === "string" ? JSON.stringify(px) : String(px);
34
+ fail(`${field}.${sides[0]}`, `must be pixels of the video, from 0 to under its width of ${outputWidth}, got ${got}`);
35
+ }
36
+ }
16
37
  /**
17
38
  * Output dimensions follow the viewport's aspect.
18
39
  *
@@ -90,6 +111,9 @@ export function resolveConfig(config, root) {
90
111
  const outputWidth = config.output?.width ?? 1920;
91
112
  positiveInt(outputWidth, "output.width");
92
113
  const baseUrl = config.baseUrl.replace(/\/+$/, "");
114
+ if (presentation?.captionInset !== undefined) {
115
+ checkCaptionInset(presentation.captionInset, outputWidth);
116
+ }
93
117
  return {
94
118
  root,
95
119
  baseUrl,
@@ -149,6 +173,7 @@ export function renderConfigOf(config) {
149
173
  output: config.output,
150
174
  theme: config.theme,
151
175
  motion: config.motion,
176
+ scenes: config.scenes,
152
177
  };
153
178
  }
154
179
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { Viewport } from "./camera.js";
2
+ import type { FollowSpec } from "./follow.js";
3
+ import type { CameraKey, CursorTrack, Rect, Vec2 } from "./timeline.js";
4
+ /**
5
+ * What a clip asked the camera to do, and when: one per `s.camera.*` call.
6
+ *
7
+ * The session keeps these rather than writing camera keys as it goes,
8
+ * because a camera that follows the cursor depends on where the cursor goes
9
+ * *after* the write, and that is only known once the clip has run. The
10
+ * driver never needs the camera while it records: it captures the whole
11
+ * viewport, and the camera is a crop drawn afterwards.
12
+ */
13
+ export type CameraWrite =
14
+ /** `zoom`, `to` and `reset`: glide to a framing and stay there. */
15
+ {
16
+ t: number;
17
+ kind: "frame";
18
+ rect: Rect;
19
+ durationMs: number;
20
+ }
21
+ /** Follow the cursor, until the next write. */
22
+ | {
23
+ t: number;
24
+ kind: "follow";
25
+ spec: FollowSpec;
26
+ durationMs: number;
27
+ }
28
+ /** Stop following, and come to rest on the framing the follow was heading for. */
29
+ | {
30
+ t: number;
31
+ kind: "release";
32
+ };
33
+ export type TrackContext = {
34
+ viewport: Viewport;
35
+ fps: number;
36
+ durationFrames: number;
37
+ cursor: CursorTrack;
38
+ /** Where the cursor rests before the track's first step. */
39
+ cursorStart: Vec2;
40
+ };
41
+ /**
42
+ * Turn a clip's camera writes into the keys the renderer interpolates.
43
+ *
44
+ * Every write starts from where the camera is, moving or not, and blends
45
+ * from there to where it is going:
46
+ *
47
+ * camera(t) = interpolateRect(before(t), destination(t), minjerk(u))
48
+ *
49
+ * where `before` is the camera as it would have gone on without this write,
50
+ * and `u` runs from 0 to 1 over the write's duration. Min-jerk has no slope
51
+ * at either end, so the camera's velocity is continuous where a blend starts
52
+ * and where it ends: entering a follow from a keyed zoom, leaving it for a
53
+ * reset, or a zoom written while another is still under way. That last one
54
+ * used to wait for the move before it to finish and then run short, because
55
+ * each glide set off from the previous glide's target.
56
+ *
57
+ * A clip that never follows and never writes a move while another is under
58
+ * way gets exactly the keys it always got: a hold where each write starts and
59
+ * a min-jerk key where it ends. Every other clip gets the camera sampled at
60
+ * each frame (the `"linear"` keys), since a blend between two moving framings
61
+ * is no longer a glide between two keys.
62
+ */
63
+ export declare function cameraTrack(writes: readonly CameraWrite[], context: TrackContext): CameraKey[];