screencast-axi 0.1.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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +555 -0
  3. package/dist/bin/screencast-axi.d.ts +2 -0
  4. package/dist/bin/screencast-axi.js +16 -0
  5. package/dist/bin/screencast-axi.js.map +1 -0
  6. package/dist/src/auth/strategies.d.ts +54 -0
  7. package/dist/src/auth/strategies.js +137 -0
  8. package/dist/src/auth/strategies.js.map +1 -0
  9. package/dist/src/auth/types.d.ts +65 -0
  10. package/dist/src/auth/types.js +2 -0
  11. package/dist/src/auth/types.js.map +1 -0
  12. package/dist/src/browser.d.ts +100 -0
  13. package/dist/src/browser.js +168 -0
  14. package/dist/src/browser.js.map +1 -0
  15. package/dist/src/cli.d.ts +2 -0
  16. package/dist/src/cli.js +160 -0
  17. package/dist/src/cli.js.map +1 -0
  18. package/dist/src/commands/auth.d.ts +4 -0
  19. package/dist/src/commands/auth.js +207 -0
  20. package/dist/src/commands/auth.js.map +1 -0
  21. package/dist/src/commands/check.d.ts +12 -0
  22. package/dist/src/commands/check.js +103 -0
  23. package/dist/src/commands/check.js.map +1 -0
  24. package/dist/src/commands/doctor.d.ts +15 -0
  25. package/dist/src/commands/doctor.js +131 -0
  26. package/dist/src/commands/doctor.js.map +1 -0
  27. package/dist/src/commands/guide.d.ts +6 -0
  28. package/dist/src/commands/guide.js +257 -0
  29. package/dist/src/commands/guide.js.map +1 -0
  30. package/dist/src/commands/home.d.ts +12 -0
  31. package/dist/src/commands/home.js +78 -0
  32. package/dist/src/commands/home.js.map +1 -0
  33. package/dist/src/commands/list.d.ts +6 -0
  34. package/dist/src/commands/list.js +128 -0
  35. package/dist/src/commands/list.js.map +1 -0
  36. package/dist/src/commands/record.d.ts +7 -0
  37. package/dist/src/commands/record.js +266 -0
  38. package/dist/src/commands/record.js.map +1 -0
  39. package/dist/src/commands/scaffold.d.ts +4 -0
  40. package/dist/src/commands/scaffold.js +122 -0
  41. package/dist/src/commands/scaffold.js.map +1 -0
  42. package/dist/src/commands/setup.d.ts +14 -0
  43. package/dist/src/commands/setup.js +137 -0
  44. package/dist/src/commands/setup.js.map +1 -0
  45. package/dist/src/config.d.ts +126 -0
  46. package/dist/src/config.js +275 -0
  47. package/dist/src/config.js.map +1 -0
  48. package/dist/src/director.d.ts +217 -0
  49. package/dist/src/director.js +415 -0
  50. package/dist/src/director.js.map +1 -0
  51. package/dist/src/duration.d.ts +33 -0
  52. package/dist/src/duration.js +68 -0
  53. package/dist/src/duration.js.map +1 -0
  54. package/dist/src/encode.d.ts +67 -0
  55. package/dist/src/encode.js +225 -0
  56. package/dist/src/encode.js.map +1 -0
  57. package/dist/src/errors.d.ts +19 -0
  58. package/dist/src/errors.js +27 -0
  59. package/dist/src/errors.js.map +1 -0
  60. package/dist/src/flags.d.ts +39 -0
  61. package/dist/src/flags.js +130 -0
  62. package/dist/src/flags.js.map +1 -0
  63. package/dist/src/forensics.d.ts +51 -0
  64. package/dist/src/forensics.js +107 -0
  65. package/dist/src/forensics.js.map +1 -0
  66. package/dist/src/hooks.d.ts +9 -0
  67. package/dist/src/hooks.js +20 -0
  68. package/dist/src/hooks.js.map +1 -0
  69. package/dist/src/index.d.ts +18 -0
  70. package/dist/src/index.js +18 -0
  71. package/dist/src/index.js.map +1 -0
  72. package/dist/src/inventory.d.ts +45 -0
  73. package/dist/src/inventory.js +89 -0
  74. package/dist/src/inventory.js.map +1 -0
  75. package/dist/src/manifest.d.ts +89 -0
  76. package/dist/src/manifest.js +137 -0
  77. package/dist/src/manifest.js.map +1 -0
  78. package/dist/src/output.d.ts +8 -0
  79. package/dist/src/output.js +2 -0
  80. package/dist/src/output.js.map +1 -0
  81. package/dist/src/overlay.d.ts +105 -0
  82. package/dist/src/overlay.js +302 -0
  83. package/dist/src/overlay.js.map +1 -0
  84. package/dist/src/reference.d.ts +1 -0
  85. package/dist/src/reference.js +108 -0
  86. package/dist/src/reference.js.map +1 -0
  87. package/dist/src/run.d.ts +82 -0
  88. package/dist/src/run.js +321 -0
  89. package/dist/src/run.js.map +1 -0
  90. package/dist/src/skill.d.ts +12 -0
  91. package/dist/src/skill.js +69 -0
  92. package/dist/src/skill.js.map +1 -0
  93. package/dist/src/toolchain.d.ts +62 -0
  94. package/dist/src/toolchain.js +127 -0
  95. package/dist/src/toolchain.js.map +1 -0
  96. package/dist/src/types.d.ts +88 -0
  97. package/dist/src/types.js +18 -0
  98. package/dist/src/types.js.map +1 -0
  99. package/dist/src/version.d.ts +10 -0
  100. package/dist/src/version.js +11 -0
  101. package/dist/src/version.js.map +1 -0
  102. package/package.json +93 -0
  103. package/skills/screencast-axi/SKILL.md +49 -0
@@ -0,0 +1,266 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { isAbsolute, relative, resolve } from "node:path";
3
+ import { loadConfig, loadScenarioFiles, loadScenarios } from "../config.js";
4
+ import { ScreencastError } from "../errors.js";
5
+ import { parseFlags } from "../flags.js";
6
+ import { ScenarioFailure, runScenario } from "../run.js";
7
+ import { parseDuration, solvePace } from "../duration.js";
8
+ import { detectToolchain } from "../toolchain.js";
9
+ const SHARED = {
10
+ config: { kind: "string", description: "Path to a config file", placeholder: "path" },
11
+ "base-url": {
12
+ kind: "string",
13
+ description: "Override the scenario's base URL",
14
+ placeholder: "url",
15
+ },
16
+ pace: { kind: "number", description: "Speed multiplier; lower is faster" },
17
+ device: { kind: "string", description: "Playwright device preset", placeholder: "name" },
18
+ viewport: { kind: "string", description: "Explicit size, e.g. 390x844", placeholder: "WxH" },
19
+ orientation: { kind: "string", description: "portrait or landscape", placeholder: "o" },
20
+ headed: { kind: "boolean", description: "Watch it happen in a real browser window" },
21
+ auth: { kind: "string", description: "Named auth strategy from the config", placeholder: "name" },
22
+ "no-auth": { kind: "boolean", description: "Record signed out" },
23
+ };
24
+ export const RECORD_FLAGS = {
25
+ ...SHARED,
26
+ duration: {
27
+ kind: "string",
28
+ description: "Aim for this length, e.g. 30s (measures first, then solves for pace)",
29
+ placeholder: "30s",
30
+ },
31
+ out: { kind: "string", description: "Output directory", placeholder: "dir" },
32
+ all: { kind: "boolean", description: "Record every scenario the config lists" },
33
+ full: { kind: "boolean", description: "Include the full action log" },
34
+ gif: { kind: "boolean", description: "Also emit a looping GIF" },
35
+ webp: { kind: "boolean", description: "Also emit a looping WebP (half a GIF's size)" },
36
+ "loop-width": { kind: "number", description: "Width of the looping formats" },
37
+ "loop-fps": { kind: "number", description: "Frame rate of the looping formats" },
38
+ "keep-raw": { kind: "boolean", description: "Keep the raw capture for inspection" },
39
+ };
40
+ export const REHEARSE_FLAGS = SHARED;
41
+ /**
42
+ * Resolves ids or file paths to scenarios.
43
+ *
44
+ * A path is accepted as well as an id so a first run needs no config: someone
45
+ * recording one page of a site they do not own should be able to write a file
46
+ * and point at it.
47
+ */
48
+ async function select(targets, config, all) {
49
+ const paths = targets.filter((t) => t.includes("/") || t.endsWith(".ts") || t.endsWith(".mjs"));
50
+ const ids = targets.filter((t) => !paths.includes(t));
51
+ const loaded = [
52
+ ...(paths.length > 0
53
+ ? await loadScenarioFiles(paths.map((p) => (isAbsolute(p) ? p : resolve(process.cwd(), p))))
54
+ : []),
55
+ ...(ids.length > 0 || all ? await loadScenarios(config) : []),
56
+ ];
57
+ if (all)
58
+ return loaded;
59
+ const chosen = [];
60
+ for (const id of ids) {
61
+ const match = loaded.find((l) => l.scenario.id === id);
62
+ if (!match) {
63
+ const known = loaded.map((l) => l.scenario.id);
64
+ throw new ScreencastError(`Unknown scenario: ${id}`, "UNKNOWN_SCENARIO", [
65
+ known.length > 0
66
+ ? `This config knows: ${known.join(", ")}`
67
+ : "No scenarios are configured. Create one with `screencast-axi scaffold <id>`",
68
+ "You can also pass a file path instead of an id",
69
+ ]);
70
+ }
71
+ chosen.push(match);
72
+ }
73
+ for (const path of paths) {
74
+ const absolute = isAbsolute(path) ? path : resolve(process.cwd(), path);
75
+ for (const l of loaded.filter((l) => l.file === absolute))
76
+ chosen.push(l);
77
+ }
78
+ return chosen;
79
+ }
80
+ function viewportOf(value) {
81
+ if (value === undefined)
82
+ return undefined;
83
+ const match = /^(\d+)\s*[x×]\s*(\d+)$/.exec(String(value).trim());
84
+ if (!match) {
85
+ throw new ScreencastError(`--viewport must look like 1280x800`, "VALIDATION_ERROR", [
86
+ "Example: --viewport 390x844",
87
+ 'Or use a device preset: --device "iPhone 13"',
88
+ ]);
89
+ }
90
+ return { width: Number(match[1]), height: Number(match[2]) };
91
+ }
92
+ function orientationOf(value) {
93
+ if (value === undefined)
94
+ return undefined;
95
+ if (value !== "portrait" && value !== "landscape") {
96
+ throw new ScreencastError(`--orientation must be portrait or landscape`, "VALIDATION_ERROR", [
97
+ "Example: --orientation portrait",
98
+ ]);
99
+ }
100
+ return value;
101
+ }
102
+ /**
103
+ * The action log, trimmed for reading.
104
+ *
105
+ * Full detail is behind `--full`: a long tour is dozens of lines, and the
106
+ * point of the short form is that someone can scan it.
107
+ */
108
+ function performed(result, full) {
109
+ const rows = result.performed.map((a) => ({
110
+ at_s: Number((a.atMs / 1000).toFixed(1)),
111
+ did: a.kind,
112
+ ...(a.target ? { target: truncate(a.target, full) } : {}),
113
+ ...(a.detail ? { detail: truncate(a.detail, full) } : {}),
114
+ }));
115
+ return full ? rows : rows.slice(0, 24);
116
+ }
117
+ function truncate(text, full) {
118
+ return full || text.length <= 70 ? text : `${text.slice(0, 67)}...`;
119
+ }
120
+ function describe(result, solution) {
121
+ const files = result.encoded
122
+ ? Object.entries(result.encoded.sizes).map(([name, bytes]) => ({
123
+ file: name,
124
+ kb: Math.round(bytes / 1024),
125
+ }))
126
+ : [];
127
+ return {
128
+ [result.mode === "record" ? "recorded" : "rehearsed"]: result.id,
129
+ duration_s: Number((result.durationMs / 1000).toFixed(1)),
130
+ pace: result.pace,
131
+ viewport: `${result.viewport.viewport.width}x${result.viewport.viewport.height}`,
132
+ ...(solution
133
+ ? {
134
+ target_s: Number((solution.targetMs / 1000).toFixed(1)),
135
+ natural_s: Number((solution.naturalMs / 1000).toFixed(1)),
136
+ ...(solution.warning ? { warning: solution.warning } : {}),
137
+ }
138
+ : {}),
139
+ ...(result.viewport.device ? { device: result.viewport.device } : {}),
140
+ ...(result.identity ? { as: result.identity.label } : {}),
141
+ ...(files.length > 0 ? { files } : {}),
142
+ ...(result.steps.length > 0 ? { steps: result.steps } : {}),
143
+ ...(result.manifestPath ? { manifest: result.manifestPath } : {}),
144
+ };
145
+ }
146
+ export async function recordCommand(args, mode) {
147
+ const specs = mode === "record" ? RECORD_FLAGS : REHEARSE_FLAGS;
148
+ const { positionals, flags } = parseFlags(args, specs);
149
+ const all = flags["all"] === true;
150
+ if (positionals.length === 0 && !all) {
151
+ throw new ScreencastError("Nothing to run", "VALIDATION_ERROR", [
152
+ `Name a scenario: \`screencast-axi ${mode} <id>\``,
153
+ `Or a file: \`screencast-axi ${mode} ./scenarios/tour.ts\``,
154
+ "Or `--all` to run every scenario the config lists",
155
+ ]);
156
+ }
157
+ const config = await loadConfig(flags["config"]);
158
+ const selected = await select(positionals, config, all);
159
+ if (selected.length === 0) {
160
+ return { [mode]: [], totals: "0 scenarios matched", help: ["Run `screencast-axi list`"] };
161
+ }
162
+ // Probed once for the batch rather than per clip, and before any browser
163
+ // opens - a missing ffmpeg should not cost a forty-second take first.
164
+ const toolchain = mode === "record" ? await detectToolchain() : undefined;
165
+ const orientation = orientationOf(flags["orientation"]);
166
+ const viewport = viewportOf(flags["viewport"]);
167
+ const targetMs = flags["duration"] !== undefined ? parseDuration(flags["duration"]) : null;
168
+ // Looping formats are for the places a <video> does not render. They are far
169
+ // heavier than the mp4, so they stay opt-in per run.
170
+ const loops = flags["gif"] === true ||
171
+ flags["webp"] === true ||
172
+ flags["loop-width"] !== undefined ||
173
+ flags["loop-fps"] !== undefined
174
+ ? {
175
+ ...(flags["gif"] === true ? { gif: true } : {}),
176
+ ...(flags["webp"] === true ? { animatedWebp: true } : {}),
177
+ ...(flags["loop-width"] !== undefined ? { gifWidth: flags["loop-width"] } : {}),
178
+ ...(flags["loop-fps"] !== undefined ? { gifFps: flags["loop-fps"] } : {}),
179
+ }
180
+ : null;
181
+ const results = [];
182
+ const solutions = new Map();
183
+ for (const { scenario, file } of selected) {
184
+ const sourceText = await readFile(file, "utf8").catch(() => undefined);
185
+ // Everything except the mode and the pace, which the measuring pass and
186
+ // the real take each set for themselves.
187
+ const base = {
188
+ scenario,
189
+ config,
190
+ ...(sourceText ? { sourceText } : {}),
191
+ ...(flags["base-url"] ? { baseUrl: flags["base-url"] } : {}),
192
+ ...(flags["out"] ? { outDir: resolve(process.cwd(), flags["out"]) } : {}),
193
+ ...(flags["device"] ? { device: flags["device"] } : {}),
194
+ ...(orientation ? { orientation } : {}),
195
+ ...(flags["headed"] === true ? { headed: true } : {}),
196
+ ...(flags["keep-raw"] === true ? { keepRaw: true } : {}),
197
+ ...(flags["no-auth"] === true
198
+ ? { auth: false }
199
+ : flags["auth"]
200
+ ? { auth: flags["auth"] }
201
+ : {}),
202
+ ...(viewport ? { viewport } : {}),
203
+ ...(loops ? { deliverables: loops } : {}),
204
+ ...(toolchain ? { toolchain } : {}),
205
+ // stderr: stdout stays reserved for the final payload.
206
+ log: (message) => void process.stderr.write(`${message}\n`),
207
+ };
208
+ let pace = flags["pace"];
209
+ if (targetMs !== null) {
210
+ // Measured, not assumed: a scenario's length is only roughly linear in
211
+ // pace, because the app's own waits do not scale with it. One no-encode
212
+ // pass is the cheapest honest way to learn the natural length.
213
+ process.stderr.write(`${scenario.id}: measuring for a ${targetMs / 1000}s target\n`);
214
+ const probe = await runScenario({ ...base, mode: "rehearse", pace: 1 });
215
+ const solution = solvePace(probe.durationMs, targetMs, probe.scaledPauseMs);
216
+ solutions.set(scenario.id, solution);
217
+ pace = solution.pace;
218
+ if (solution.warning)
219
+ process.stderr.write(`${scenario.id}: ${solution.warning}\n`);
220
+ }
221
+ results.push(await runScenario({ ...base, mode, ...(pace !== undefined ? { pace } : {}) }));
222
+ }
223
+ if (results.length === 1) {
224
+ const only = results[0];
225
+ const full = flags["full"] === true;
226
+ // A rehearsal is where someone checks what a scenario does before trusting
227
+ // it, so the log is the point of the output rather than an extra.
228
+ const showLog = mode === "rehearse" || full;
229
+ return {
230
+ ...describe(only, solutions.get(only.id)),
231
+ ...(only.hosts.length > 0 ? { hosts: only.hosts } : {}),
232
+ ...(showLog ? { performed: performed(only, full) } : {}),
233
+ help: nextSteps(only, showLog),
234
+ };
235
+ }
236
+ return {
237
+ [mode === "record" ? "recorded" : "rehearsed"]: results.map((r) => ({
238
+ id: r.id,
239
+ duration_s: Number((r.durationMs / 1000).toFixed(1)),
240
+ })),
241
+ totals: `${results.length} scenarios`,
242
+ help: [`Run \`screencast-axi show <id>\` for one clip in full`],
243
+ };
244
+ }
245
+ function nextSteps(result, showedLog = false) {
246
+ if (result.mode === "rehearse") {
247
+ return [
248
+ ...(showedLog
249
+ ? [
250
+ "`performed` above is every action the scenario took - read it before trusting a script you did not write",
251
+ ]
252
+ : []),
253
+ `Selectors and narration hold. Run \`screencast-axi record ${result.id}\` for the real take`,
254
+ "A rehearsal runs faster than a take, so it can trip on an animation a recording would wait out",
255
+ ];
256
+ }
257
+ return [
258
+ ...(showedLog ? [] : ["Add `--full` to see every action the scenario took"]),
259
+ `The clip is ${(result.durationMs / 1000).toFixed(1)}s. Re-cut it with \`screencast-axi record ${result.id} --pace 0.8\` (lower is faster)`,
260
+ result.manifestPath
261
+ ? `Title, description and steps are in ${relative(process.cwd(), result.manifestPath)} for a site to read`
262
+ : "",
263
+ ].filter(Boolean);
264
+ }
265
+ export { ScenarioFailure };
266
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../../src/commands/record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type FlagSpecs } from "../flags.js";
2
+ import type { AxiStructuredOutput } from "../output.js";
3
+ export declare const SCAFFOLD_FLAGS: FlagSpecs;
4
+ export declare function scaffoldCommand(args: string[]): AxiStructuredOutput;
@@ -0,0 +1,122 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { dirname, join, relative, resolve } from "node:path";
3
+ import { ScreencastError } from "../errors.js";
4
+ import { parseFlags } from "../flags.js";
5
+ export const SCAFFOLD_FLAGS = {
6
+ url: { kind: "string", description: "Base URL the scenario opens", placeholder: "url" },
7
+ title: { kind: "string", description: "Human title for the clip", placeholder: "text" },
8
+ dir: { kind: "string", description: "Where to write it", placeholder: "path" },
9
+ tour: { kind: "number", description: "Write an n-stop page walkthrough instead" },
10
+ device: { kind: "string", description: "Playwright device preset", placeholder: "name" },
11
+ };
12
+ const ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
13
+ function titleFrom(id) {
14
+ const words = id.split("-");
15
+ const first = words[0] ?? id;
16
+ return [first.charAt(0).toUpperCase() + first.slice(1), ...words.slice(1)].join(" ");
17
+ }
18
+ /**
19
+ * A scenario skeleton, so the boilerplate is never the thing that goes wrong.
20
+ *
21
+ * This is what makes a TypeScript-only authoring format cheap: the author -
22
+ * often an agent - supplies only the `run()` body and the narration, not the
23
+ * imports, the id or the shape.
24
+ */
25
+ function template(id, title, url, device) {
26
+ return `import { defineScenario } from "screencast-axi";
27
+
28
+ export default defineScenario({
29
+ id: ${JSON.stringify(id)},
30
+ title: ${JSON.stringify(title)},
31
+ description: "TODO: one line describing what this clip shows.",
32
+ baseUrl: ${JSON.stringify(url)},${device ? `\n device: ${JSON.stringify(device)},` : ""}
33
+
34
+ // Each line goes on screen once, in order, via d.step(i). The same array
35
+ // becomes the manifest's step list, so the workflow is readable without
36
+ // watching the video.
37
+ steps: ["TODO: the first beat", "TODO: the second beat"],
38
+
39
+ async run(d) {
40
+ await d.goto("/");
41
+ await d.step(0, 900);
42
+
43
+ // TODO: drive the page. d.click, d.type, d.drag, d.scrollBy, d.waitFor.
44
+ // Reach past them with d.page for anything they do not cover.
45
+
46
+ await d.step(1, 1200);
47
+ },
48
+ });
49
+ `;
50
+ }
51
+ function tourTemplate(id, title, url, stops, device) {
52
+ const paths = ["/", "/pricing", "/docs", "/blog", "/contact"];
53
+ const chosen = Array.from({ length: stops }, (_, i) => paths[i] ?? `/page-${i + 1}`);
54
+ return `import { defineScenario } from "screencast-axi";
55
+
56
+ export default defineScenario({
57
+ id: ${JSON.stringify(id)},
58
+ title: ${JSON.stringify(title)},
59
+ description: "TODO: one line describing what this walkthrough shows.",
60
+ baseUrl: ${JSON.stringify(url)},${device ? `\n device: ${JSON.stringify(device)},` : ""}
61
+
62
+ // One line per stop, in the order they appear.
63
+ steps: [
64
+ ${chosen.map((_, i) => ` "TODO: what stop ${i + 1} shows",`).join("\n")}
65
+ ],
66
+
67
+ async run(d) {
68
+ ${chosen
69
+ .map((path, i) => ` await d.goto(${JSON.stringify(path)});\n` +
70
+ ` await d.step(${i}, 1200);\n` +
71
+ ` await d.scrollBy(500);`)
72
+ .join("\n\n")}
73
+ },
74
+ });
75
+ `;
76
+ }
77
+ export function scaffoldCommand(args) {
78
+ const { positionals, flags } = parseFlags(args, SCAFFOLD_FLAGS);
79
+ const id = positionals[0];
80
+ if (!id) {
81
+ throw new ScreencastError("Name the scenario", "VALIDATION_ERROR", [
82
+ "Run `screencast-axi scaffold <id> --url <url>`",
83
+ "The id is the output file stem, e.g. `product-tour`",
84
+ ]);
85
+ }
86
+ if (!ID_PATTERN.test(id)) {
87
+ // The id is a file stem, so it has to be safe on every filesystem and
88
+ // usable in a URL without escaping.
89
+ throw new ScreencastError(`Invalid id: ${id}`, "VALIDATION_ERROR", [
90
+ "Use lower-case words joined by dashes, e.g. `product-tour`",
91
+ "The id becomes the file name of every deliverable",
92
+ ]);
93
+ }
94
+ const url = flags["url"] ?? "http://localhost:3000";
95
+ const title = flags["title"] ?? titleFrom(id);
96
+ const device = flags["device"];
97
+ const dir = resolve(process.cwd(), flags["dir"] ?? "scenarios");
98
+ const file = join(dir, `${id}.ts`);
99
+ if (existsSync(file)) {
100
+ throw new ScreencastError(`Already exists: ${file}`, "ALREADY_EXISTS", [
101
+ "Edit it, or pick a different id",
102
+ ]);
103
+ }
104
+ const stops = flags["tour"];
105
+ const body = stops !== undefined
106
+ ? tourTemplate(id, title, url, Math.max(1, Math.min(12, Math.round(stops))), device)
107
+ : template(id, title, url, device);
108
+ mkdirSync(dirname(file), { recursive: true });
109
+ writeFileSync(file, body);
110
+ return {
111
+ created: file,
112
+ id,
113
+ help: [
114
+ `Fill in the TODOs in ${relative(process.cwd(), file)}, then run \`screencast-axi rehearse ${relative(process.cwd(), file)}\``,
115
+ "Rehearsing runs the scenario without encoding, so a wrong selector shows up in seconds",
116
+ "Record it once it rehearses clean: `screencast-axi record " +
117
+ relative(process.cwd(), file) +
118
+ "`",
119
+ ],
120
+ };
121
+ }
122
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../../src/commands/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type FlagSpecs } from "../flags.js";
2
+ import type { AxiStructuredOutput } from "../output.js";
3
+ export declare const SETUP_FLAGS: FlagSpecs;
4
+ export declare const INIT_FLAGS: FlagSpecs;
5
+ /**
6
+ * Does what can be done safely, and names what cannot.
7
+ *
8
+ * Downloading a browser is expected and reversible, so it happens. Installing
9
+ * a system package is not something this should do behind anyone's back - a
10
+ * tool that shells out to a package manager inside an agent loop is not one
11
+ * you want - so a missing ffmpeg is reported with the exact command instead.
12
+ */
13
+ export declare function setupCommand(args: string[]): Promise<AxiStructuredOutput>;
14
+ export declare function initCommand(args: string[]): AxiStructuredOutput;
@@ -0,0 +1,137 @@
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join, relative, resolve } from "node:path";
3
+ import { installHooks } from "../hooks.js";
4
+ import { ScreencastError } from "../errors.js";
5
+ import { parseFlags } from "../flags.js";
6
+ import { detectToolchain, installHint, run } from "../toolchain.js";
7
+ import { CONFIG_BASENAMES } from "../config.js";
8
+ export const SETUP_FLAGS = {
9
+ "browsers-only": { kind: "boolean", description: "Install Chromium and stop" },
10
+ scope: { kind: "string", description: "For `setup hooks`: user or project", placeholder: "s" },
11
+ };
12
+ export const INIT_FLAGS = {
13
+ out: { kind: "string", description: "Where clips should be written", placeholder: "dir" },
14
+ url: { kind: "string", description: "Base URL for the site you record", placeholder: "url" },
15
+ force: { kind: "boolean", description: "Overwrite an existing config" },
16
+ };
17
+ /**
18
+ * Does what can be done safely, and names what cannot.
19
+ *
20
+ * Downloading a browser is expected and reversible, so it happens. Installing
21
+ * a system package is not something this should do behind anyone's back - a
22
+ * tool that shells out to a package manager inside an agent loop is not one
23
+ * you want - so a missing ffmpeg is reported with the exact command instead.
24
+ */
25
+ export async function setupCommand(args) {
26
+ const { positionals, flags } = parseFlags(args, SETUP_FLAGS);
27
+ if (positionals[0] === "hooks") {
28
+ return installHooks(flags["scope"]);
29
+ }
30
+ if (positionals[0]) {
31
+ throw new ScreencastError(`Unknown setup target: ${positionals[0]}`, "VALIDATION_ERROR", [
32
+ "`screencast-axi setup` installs the browser and checks the rest",
33
+ "`screencast-axi setup hooks` registers the session integration",
34
+ ]);
35
+ }
36
+ const done = [];
37
+ const manual = [];
38
+ const install = await run("npx", ["--yes", "playwright", "install", "chromium"]);
39
+ if (install.code === 0) {
40
+ done.push("chromium installed (or already present)");
41
+ }
42
+ else {
43
+ manual.push("npx playwright install chromium");
44
+ }
45
+ if (flags["browsers-only"] !== true) {
46
+ const toolchain = await detectToolchain();
47
+ if (toolchain.ffmpeg) {
48
+ done.push(`ffmpeg found at ${toolchain.ffmpeg.path}`);
49
+ }
50
+ else {
51
+ manual.push(installHint("ffmpeg"));
52
+ }
53
+ if (toolchain.posterEncoder === "png") {
54
+ manual.push(`${installHint("cwebp")} # optional: smaller posters, and --webp`);
55
+ }
56
+ }
57
+ return {
58
+ done,
59
+ ...(manual.length > 0 ? { "run yourself": manual } : {}),
60
+ totals: manual.length === 0 ? "ready to record" : `${manual.length} thing(s) need installing by hand`,
61
+ help: manual.length === 0
62
+ ? ["`screencast-axi doctor` confirms it, `scaffold <id>` starts a scenario"]
63
+ : [
64
+ "These are system packages, so they are not installed for you",
65
+ "`screencast-axi doctor` re-checks once they are in place",
66
+ ],
67
+ };
68
+ }
69
+ const TEMPLATE = (outDir, url) => `import { defineConfig } from "screencast-axi";
70
+
71
+ export default defineConfig({
72
+ // Origin only. A baseUrl carrying a path is a trap: \`goto("/")\` resolves
73
+ // against the origin and silently drops the path.
74
+ baseUrl: ${JSON.stringify(url)},
75
+
76
+ scenarios: ["scenarios/*.ts"],
77
+ outDir: ${JSON.stringify(outDir)},
78
+
79
+ viewport: { width: 1440, height: 900 },
80
+
81
+ // Uncomment to record pages behind a login. A person then runs
82
+ // \`screencast-axi auth login --interactive\` once, signs in in the browser
83
+ // window that opens, and every take afterwards reuses the session.
84
+ //
85
+ // browser: { profileDir: ".screencast/profile" },
86
+ // auth: profileAuth({ signedInSelector: "[data-testid=user-menu]" }),
87
+
88
+ overlay: {
89
+ // Page chrome that should never end up in footage.
90
+ hideSelectors: [],
91
+ },
92
+ });
93
+ `;
94
+ const GITIGNORE = `
95
+ # screencast-axi: raw captures, and the profile holding a real session
96
+ .screencast/
97
+ `;
98
+ export function initCommand(args) {
99
+ const { flags } = parseFlags(args, INIT_FLAGS);
100
+ const cwd = process.cwd();
101
+ const existing = CONFIG_BASENAMES.map((n) => join(cwd, n)).find((f) => existsSync(f));
102
+ if (existing && flags["force"] !== true) {
103
+ throw new ScreencastError(`A config is already here: ${existing}`, "ALREADY_EXISTS", [
104
+ "Edit it, or pass `--force` to overwrite it",
105
+ ]);
106
+ }
107
+ const outDir = flags["out"] ?? "screencasts";
108
+ const url = flags["url"] ?? "http://localhost:3000";
109
+ const configPath = join(cwd, "screencast.config.ts");
110
+ writeFileSync(configPath, TEMPLATE(outDir, url));
111
+ mkdirSync(join(cwd, "scenarios"), { recursive: true });
112
+ // Appended rather than created: a project almost always has one already, and
113
+ // the profile directory holds a real signed-in session.
114
+ const gitignore = join(cwd, ".gitignore");
115
+ let ignored = false;
116
+ if (existsSync(gitignore)) {
117
+ const current = readFileSync(gitignore, "utf8");
118
+ if (!current.includes(".screencast/")) {
119
+ appendFileSync(gitignore, GITIGNORE);
120
+ ignored = true;
121
+ }
122
+ }
123
+ else {
124
+ writeFileSync(gitignore, GITIGNORE.trimStart());
125
+ ignored = true;
126
+ }
127
+ return {
128
+ created: relative(cwd, configPath),
129
+ scenarios: relative(cwd, resolve(cwd, "scenarios")),
130
+ ...(ignored ? { gitignored: ".screencast/" } : {}),
131
+ help: [
132
+ `Write your first scenario: \`screencast-axi scaffold <id> --url ${url}\``,
133
+ "`screencast-axi doctor` checks ffmpeg and the browser are in place",
134
+ ],
135
+ };
136
+ }
137
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/commands/setup.ts"],"names":[],"mappings":"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"}