@plaintake/scenario 1.23.0 → 1.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.js +819 -440
- package/dist/schema/baseline.d.ts +182 -0
- package/dist/schema/errors.d.ts +1 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/manifest.d.ts +1 -0
- package/dist/schema/narration-index.d.ts +1 -1
- package/dist/schema/render-plan.d.ts +174 -17
- package/dist/schema/results.d.ts +118 -9
- package/dist/schema/scenario.d.ts +62 -0
- package/dist/types.d.ts +94 -36
- package/package.json +1 -1
package/dist/schema/results.d.ts
CHANGED
|
@@ -15,6 +15,13 @@ export declare const ValidationResultSchema: z.ZodObject<{
|
|
|
15
15
|
session: "session";
|
|
16
16
|
}>>;
|
|
17
17
|
sha256: z.ZodString;
|
|
18
|
+
terminal: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
19
|
+
cols: z.ZodNumber;
|
|
20
|
+
rows: z.ZodNumber;
|
|
21
|
+
shell: z.ZodString;
|
|
22
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
23
|
+
browser: z.ZodOptional<z.ZodLiteral<true>>;
|
|
24
|
+
}, z.core.$strip>>>;
|
|
18
25
|
}, z.core.$strip>>;
|
|
19
26
|
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
20
27
|
kind: z.ZodLiteral<"validate">;
|
|
@@ -48,6 +55,34 @@ export declare const RunCommandResultSchema: z.ZodObject<{
|
|
|
48
55
|
bytes: z.ZodNumber;
|
|
49
56
|
}, z.core.$strip>>;
|
|
50
57
|
archivedPath: z.ZodOptional<z.ZodString>;
|
|
58
|
+
baseline: z.ZodOptional<z.ZodObject<{
|
|
59
|
+
path: z.ZodString;
|
|
60
|
+
status: z.ZodEnum<{
|
|
61
|
+
match: "match";
|
|
62
|
+
drift: "drift";
|
|
63
|
+
"scenario-changed": "scenario-changed";
|
|
64
|
+
absent: "absent";
|
|
65
|
+
skipped: "skipped";
|
|
66
|
+
updated: "updated";
|
|
67
|
+
}>;
|
|
68
|
+
differences: z.ZodArray<z.ZodObject<{
|
|
69
|
+
category: z.ZodEnum<{
|
|
70
|
+
step: "step";
|
|
71
|
+
assertion: "assertion";
|
|
72
|
+
"target-name": "target-name";
|
|
73
|
+
"target-role": "target-role";
|
|
74
|
+
"target-bounds": "target-bounds";
|
|
75
|
+
timing: "timing";
|
|
76
|
+
caption: "caption";
|
|
77
|
+
actor: "actor";
|
|
78
|
+
}>;
|
|
79
|
+
severity: z.ZodEnum<{
|
|
80
|
+
fail: "fail";
|
|
81
|
+
report: "report";
|
|
82
|
+
}>;
|
|
83
|
+
detail: z.ZodString;
|
|
84
|
+
}, z.core.$strip>>;
|
|
85
|
+
}, z.core.$strip>>;
|
|
51
86
|
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
52
87
|
kind: z.ZodLiteral<"run">;
|
|
53
88
|
ok: z.ZodBoolean;
|
|
@@ -72,6 +107,34 @@ export declare const CheckCommandResultSchema: z.ZodObject<{
|
|
|
72
107
|
cueId: z.ZodString;
|
|
73
108
|
detail: z.ZodString;
|
|
74
109
|
}, z.core.$strip>>;
|
|
110
|
+
baseline: z.ZodOptional<z.ZodObject<{
|
|
111
|
+
path: z.ZodString;
|
|
112
|
+
status: z.ZodEnum<{
|
|
113
|
+
match: "match";
|
|
114
|
+
drift: "drift";
|
|
115
|
+
"scenario-changed": "scenario-changed";
|
|
116
|
+
absent: "absent";
|
|
117
|
+
skipped: "skipped";
|
|
118
|
+
updated: "updated";
|
|
119
|
+
}>;
|
|
120
|
+
differences: z.ZodArray<z.ZodObject<{
|
|
121
|
+
category: z.ZodEnum<{
|
|
122
|
+
step: "step";
|
|
123
|
+
assertion: "assertion";
|
|
124
|
+
"target-name": "target-name";
|
|
125
|
+
"target-role": "target-role";
|
|
126
|
+
"target-bounds": "target-bounds";
|
|
127
|
+
timing: "timing";
|
|
128
|
+
caption: "caption";
|
|
129
|
+
actor: "actor";
|
|
130
|
+
}>;
|
|
131
|
+
severity: z.ZodEnum<{
|
|
132
|
+
fail: "fail";
|
|
133
|
+
report: "report";
|
|
134
|
+
}>;
|
|
135
|
+
detail: z.ZodString;
|
|
136
|
+
}, z.core.$strip>>;
|
|
137
|
+
}, z.core.$strip>>;
|
|
75
138
|
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
76
139
|
kind: z.ZodLiteral<"check">;
|
|
77
140
|
ok: z.ZodBoolean;
|
|
@@ -244,12 +307,18 @@ export declare const DiffCommandResultSchema: z.ZodObject<{
|
|
|
244
307
|
identical: z.ZodBoolean;
|
|
245
308
|
differences: z.ZodArray<z.ZodObject<{
|
|
246
309
|
category: z.ZodEnum<{
|
|
247
|
-
assertion: "assertion";
|
|
248
|
-
target: "target";
|
|
249
|
-
actor: "actor";
|
|
250
310
|
step: "step";
|
|
311
|
+
assertion: "assertion";
|
|
312
|
+
"target-name": "target-name";
|
|
313
|
+
"target-role": "target-role";
|
|
314
|
+
"target-bounds": "target-bounds";
|
|
251
315
|
timing: "timing";
|
|
252
316
|
caption: "caption";
|
|
317
|
+
actor: "actor";
|
|
318
|
+
}>;
|
|
319
|
+
severity: z.ZodEnum<{
|
|
320
|
+
fail: "fail";
|
|
321
|
+
report: "report";
|
|
253
322
|
}>;
|
|
254
323
|
detail: z.ZodString;
|
|
255
324
|
}, z.core.$strip>>;
|
|
@@ -461,11 +530,10 @@ export declare const DoctorResultSchema: z.ZodObject<{
|
|
|
461
530
|
voices: z.ZodArray<z.ZodString>;
|
|
462
531
|
notes: z.ZodArray<z.ZodString>;
|
|
463
532
|
}, z.core.$strip>;
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}, z.core.$strip>;
|
|
533
|
+
terminal: z.ZodOptional<z.ZodObject<{
|
|
534
|
+
ready: z.ZodBoolean;
|
|
535
|
+
notes: z.ZodArray<z.ZodString>;
|
|
536
|
+
}, z.core.$strip>>;
|
|
469
537
|
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
470
538
|
kind: z.ZodLiteral<"doctor">;
|
|
471
539
|
ok: z.ZodBoolean;
|
|
@@ -533,6 +601,7 @@ export declare const PublishResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
533
601
|
"hash-mismatch": "hash-mismatch";
|
|
534
602
|
"length-mismatch": "length-mismatch";
|
|
535
603
|
conflict: "conflict";
|
|
604
|
+
"taken-down": "taken-down";
|
|
536
605
|
}>;
|
|
537
606
|
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
538
607
|
kind: z.ZodLiteral<"publish">;
|
|
@@ -542,6 +611,7 @@ export declare const PublishResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
542
611
|
videoId: z.ZodString;
|
|
543
612
|
url: z.ZodString;
|
|
544
613
|
uploaded: z.ZodBoolean;
|
|
614
|
+
restored: z.ZodDefault<z.ZodBoolean>;
|
|
545
615
|
remembered: z.ZodOptional<z.ZodBoolean>;
|
|
546
616
|
expiresAt: z.ZodOptional<z.ZodString>;
|
|
547
617
|
captions: z.ZodBoolean;
|
|
@@ -551,6 +621,44 @@ export declare const PublishResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
551
621
|
kind: z.ZodLiteral<"publish">;
|
|
552
622
|
problems: z.ZodArray<z.ZodString>;
|
|
553
623
|
}, z.core.$strip>], "ok">;
|
|
624
|
+
/**
|
|
625
|
+
* A share taken down, or not. The service tombstones: the link answers 410 at once and
|
|
626
|
+
* the bytes stay until `purgeAfter`, so publishing the same bundle again before then
|
|
627
|
+
* restores it. Discriminated on `ok` for the same reason as `PublishResultSchema`.
|
|
628
|
+
*/
|
|
629
|
+
export declare const UnpublishResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
630
|
+
ok: z.ZodLiteral<false>;
|
|
631
|
+
reason: z.ZodEnum<{
|
|
632
|
+
"not-found": "not-found";
|
|
633
|
+
"unexpected-response": "unexpected-response";
|
|
634
|
+
"no-endpoint": "no-endpoint";
|
|
635
|
+
"no-key": "no-key";
|
|
636
|
+
"invalid-store": "invalid-store";
|
|
637
|
+
"not-a-bundle": "not-a-bundle";
|
|
638
|
+
unauthorized: "unauthorized";
|
|
639
|
+
unreachable: "unreachable";
|
|
640
|
+
"invalid-target": "invalid-target";
|
|
641
|
+
"endpoint-mismatch": "endpoint-mismatch";
|
|
642
|
+
forbidden: "forbidden";
|
|
643
|
+
}>;
|
|
644
|
+
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
645
|
+
kind: z.ZodLiteral<"unpublish">;
|
|
646
|
+
problems: z.ZodArray<z.ZodString>;
|
|
647
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
648
|
+
ok: z.ZodLiteral<true>;
|
|
649
|
+
videoId: z.ZodString;
|
|
650
|
+
url: z.ZodString;
|
|
651
|
+
deletedAt: z.ZodString;
|
|
652
|
+
deletedBy: z.ZodEnum<{
|
|
653
|
+
producer: "producer";
|
|
654
|
+
admin: "admin";
|
|
655
|
+
expired: "expired";
|
|
656
|
+
}>;
|
|
657
|
+
purgeAfter: z.ZodString;
|
|
658
|
+
schema: z.ZodLiteral<"agent-demo.result/v1">;
|
|
659
|
+
kind: z.ZodLiteral<"unpublish">;
|
|
660
|
+
problems: z.ZodArray<z.ZodString>;
|
|
661
|
+
}, z.core.$strip>], "ok">;
|
|
554
662
|
export type ArtifactRef = z.infer<typeof ArtifactRefSchema>;
|
|
555
663
|
export type ValidationResult = z.infer<typeof ValidationResultSchema>;
|
|
556
664
|
export type RunCommandResult = z.infer<typeof RunCommandResultSchema>;
|
|
@@ -568,7 +676,8 @@ export type DoctorResult = z.infer<typeof DoctorResultSchema>;
|
|
|
568
676
|
export type ActivateResult = z.infer<typeof ActivateResultSchema>;
|
|
569
677
|
export type LicenceResult = z.infer<typeof LicenceResultSchema>;
|
|
570
678
|
export type PublishResult = z.infer<typeof PublishResultSchema>;
|
|
571
|
-
export type
|
|
679
|
+
export type UnpublishResult = z.infer<typeof UnpublishResultSchema>;
|
|
680
|
+
export type DemoResult = ValidationResult | RunCommandResult | CheckCommandResult | RenderCommandResult | VerificationReport | WarmCommandResult | DiffCommandResult | CompareCommandResult | InitResult | PruneCommandResult | ImportCommandResult | InspectResult | DoctorResult | ActivateResult | LicenceResult | PublishResult | UnpublishResult;
|
|
572
681
|
/**
|
|
573
682
|
* Renders a filesystem location for display in a result, relative to `root` when it
|
|
574
683
|
* lies inside it.
|
|
@@ -23,6 +23,22 @@ export declare const ScenarioIntroSchema: z.ZodObject<{
|
|
|
23
23
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
24
24
|
}, z.core.$strip>;
|
|
25
25
|
export type ScenarioIntro = z.infer<typeof ScenarioIntroSchema>;
|
|
26
|
+
/**
|
|
27
|
+
* The hook: a line or two of text over the top band of a portrait video for its first seconds
|
|
28
|
+
* (`HookSchema` in the render plan says what it is and is not). A string, or `{ text,
|
|
29
|
+
* durationMs }` to hold it for other than the default 3 s.
|
|
30
|
+
*
|
|
31
|
+
* `text` is author-chosen and never generated. A `\n` in it is a line break the author chose;
|
|
32
|
+
* otherwise a long hook is balanced onto two lines at the hook's measured width. Whether every
|
|
33
|
+
* character can be drawn, and whether it fits on two lines, depends on the bundled fonts, which
|
|
34
|
+
* this package cannot see — `validate` checks both (`hookProblems`, `apps/cli`), before a browser
|
|
35
|
+
* opens, and `run` refuses with exit 2 on the same grounds.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ScenarioHookSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
38
|
+
text: z.ZodString;
|
|
39
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
}, z.core.$strip>]>;
|
|
41
|
+
export type ScenarioHook = z.infer<typeof ScenarioHookSchema>;
|
|
26
42
|
/**
|
|
27
43
|
* Per-scenario camera framing, for the demos whose pages the defaults do not suit.
|
|
28
44
|
*
|
|
@@ -78,6 +94,28 @@ export declare const ScenarioSpeechSchema: z.ZodObject<{
|
|
|
78
94
|
voices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
79
95
|
}, z.core.$strip>;
|
|
80
96
|
export type ScenarioSpeech = z.infer<typeof ScenarioSpeechSchema>;
|
|
97
|
+
export declare const TerminalMetaSchema: z.ZodObject<{
|
|
98
|
+
shell: z.ZodDefault<z.ZodEnum<{
|
|
99
|
+
bash: "bash";
|
|
100
|
+
zsh: "zsh";
|
|
101
|
+
sh: "sh";
|
|
102
|
+
}>>;
|
|
103
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
104
|
+
cols: z.ZodDefault<z.ZodNumber>;
|
|
105
|
+
rows: z.ZodDefault<z.ZodNumber>;
|
|
106
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
107
|
+
env: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
108
|
+
secrets: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
109
|
+
browser: z.ZodOptional<z.ZodBoolean>;
|
|
110
|
+
label: z.ZodOptional<z.ZodString>;
|
|
111
|
+
transition: z.ZodOptional<z.ZodEnum<{
|
|
112
|
+
cut: "cut";
|
|
113
|
+
card: "card";
|
|
114
|
+
}>>;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
export type TerminalMeta = z.infer<typeof TerminalMetaSchema>;
|
|
117
|
+
/** What an author writes: every defaulted field (`shell`, `cols`, `rows`, `env`, `secrets`) optional. */
|
|
118
|
+
export type TerminalMetaInput = z.input<typeof TerminalMetaSchema>;
|
|
81
119
|
export declare const ScenarioMetaSchema: z.ZodObject<{
|
|
82
120
|
schema: z.ZodLiteral<"agent-demo.scenario/v1">;
|
|
83
121
|
id: z.ZodString;
|
|
@@ -88,6 +126,7 @@ export declare const ScenarioMetaSchema: z.ZodObject<{
|
|
|
88
126
|
height: z.ZodLiteral<1080>;
|
|
89
127
|
deviceScaleFactor: z.ZodLiteral<1>;
|
|
90
128
|
}, z.core.$strip>;
|
|
129
|
+
uiScale: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<1.5>, z.ZodLiteral<2>]>>;
|
|
91
130
|
locale: z.ZodLiteral<"en-US">;
|
|
92
131
|
timezoneId: z.ZodLiteral<"UTC">;
|
|
93
132
|
colorScheme: z.ZodLiteral<"light">;
|
|
@@ -104,6 +143,10 @@ export declare const ScenarioMetaSchema: z.ZodObject<{
|
|
|
104
143
|
narration: z.ZodOptional<z.ZodString>;
|
|
105
144
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
106
145
|
}, z.core.$strip>>;
|
|
146
|
+
hook: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
147
|
+
text: z.ZodString;
|
|
148
|
+
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
149
|
+
}, z.core.$strip>]>>;
|
|
107
150
|
camera: z.ZodOptional<z.ZodObject<{
|
|
108
151
|
maxZoom: z.ZodOptional<z.ZodNumber>;
|
|
109
152
|
margin: z.ZodOptional<z.ZodNumber>;
|
|
@@ -114,6 +157,25 @@ export declare const ScenarioMetaSchema: z.ZodObject<{
|
|
|
114
157
|
speed: z.ZodOptional<z.ZodNumber>;
|
|
115
158
|
voices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
116
159
|
}, z.core.$strip>>;
|
|
160
|
+
terminal: z.ZodOptional<z.ZodObject<{
|
|
161
|
+
shell: z.ZodDefault<z.ZodEnum<{
|
|
162
|
+
bash: "bash";
|
|
163
|
+
zsh: "zsh";
|
|
164
|
+
sh: "sh";
|
|
165
|
+
}>>;
|
|
166
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
167
|
+
cols: z.ZodDefault<z.ZodNumber>;
|
|
168
|
+
rows: z.ZodDefault<z.ZodNumber>;
|
|
169
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
170
|
+
env: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
171
|
+
secrets: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
172
|
+
browser: z.ZodOptional<z.ZodBoolean>;
|
|
173
|
+
label: z.ZodOptional<z.ZodString>;
|
|
174
|
+
transition: z.ZodOptional<z.ZodEnum<{
|
|
175
|
+
cut: "cut";
|
|
176
|
+
card: "card";
|
|
177
|
+
}>>;
|
|
178
|
+
}, z.core.$strip>>;
|
|
117
179
|
pronunciations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
118
180
|
}, z.core.$strip>;
|
|
119
181
|
/** Which phase, if any, hands the browser over. Read by the recorder and the surfaces. */
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ScenarioMeta } from './schema/index.js';
|
|
1
|
+
import type { ScenarioMeta, TerminalMetaInput } from './schema/index.js';
|
|
2
2
|
import type { BrowserContextOptions, Locator, Page } from 'playwright-core';
|
|
3
3
|
/**
|
|
4
4
|
* What kind of interaction `run()` performs, declared rather than observed. Like
|
|
@@ -217,10 +217,10 @@ export type ExplainConnection = {
|
|
|
217
217
|
to: string;
|
|
218
218
|
label?: string;
|
|
219
219
|
};
|
|
220
|
-
/** One side of a `comparison` explain scene: what this alternative is called, and
|
|
220
|
+
/** One side of a `comparison` explain scene: what this alternative is called, and two to six short items. */
|
|
221
221
|
export type ExplainColumn = {
|
|
222
222
|
heading: string;
|
|
223
|
-
|
|
223
|
+
items: string[];
|
|
224
224
|
};
|
|
225
225
|
/** A named group of imported svg parts a `diagram` scene's cue can target as one thing. */
|
|
226
226
|
export type ExplainRegion = {
|
|
@@ -228,16 +228,16 @@ export type ExplainRegion = {
|
|
|
228
228
|
of: string[];
|
|
229
229
|
};
|
|
230
230
|
/**
|
|
231
|
-
* The five motion-graphics scenes an explain cut-away can be, mirroring
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
231
|
+
* The five motion-graphics scenes an explain cut-away can be, mirroring the scene registry in
|
|
232
|
+
* `@plaintake/motion` prop-for-prop (`title`/`process`/`comparison`/`diagram`/`recap`). This
|
|
233
|
+
* package is types only — each scene is compiled and drawn after capture and spliced into the
|
|
234
|
+
* recording as a frozen segment — so this union is a structural mirror of those scene schemas,
|
|
235
|
+
* and the deep validation (character caps, list bounds, phrase resolution) belongs to the
|
|
236
|
+
* compile at run time, not to this package's types. What `validate` checks without a
|
|
237
237
|
* browser is the shape around the scene: id, narration, a known `type`.
|
|
238
238
|
*
|
|
239
239
|
* Geometry is deliberately absent. Where a pixel appears is the scene layout's decision,
|
|
240
|
-
* exactly as it is in
|
|
240
|
+
* exactly as it is in any motion-graphics scene; an author says what exists and what the
|
|
241
241
|
* narration points at, and nothing about inches.
|
|
242
242
|
*/
|
|
243
243
|
export type ExplainScene = {
|
|
@@ -273,7 +273,7 @@ export type ExplainScene = {
|
|
|
273
273
|
items: string[];
|
|
274
274
|
};
|
|
275
275
|
/**
|
|
276
|
-
* What a cue does to the viewer's attention. The same vocabulary
|
|
276
|
+
* What a cue does to the viewer's attention. The same vocabulary the explain compile defines —
|
|
277
277
|
* deliberately small, and deliberately not easing curves or tween internals: an author says
|
|
278
278
|
* what should happen; how that is expressed is the renderer's job.
|
|
279
279
|
*/
|
|
@@ -281,7 +281,7 @@ export type ExplainCueAction = 'reveal' | 'hide' | 'emphasize' | 'deemphasize' |
|
|
|
281
281
|
/**
|
|
282
282
|
* When a cue fires: bound to words in the narration, resolved against the timings the speech
|
|
283
283
|
* model measures. Rewriting a sentence moves the animation with it instead of silently
|
|
284
|
-
* desynchronising — which is why there is no numeric `at` offset here the way
|
|
284
|
+
* desynchronising — which is why there is no numeric `at` offset here the way the compile's
|
|
285
285
|
* own cue schema allows one. An explain scene always speaks (its narration is the scene's
|
|
286
286
|
* clock), so a phrase is the only anchor that survives a rewording, and an offset that could
|
|
287
287
|
* not is not offered.
|
|
@@ -296,22 +296,23 @@ export type ExplainCue = {
|
|
|
296
296
|
};
|
|
297
297
|
/**
|
|
298
298
|
* A full-frame motion-graphics cut-away in the middle of a browser demo — "explain while
|
|
299
|
-
* demoing". `demo.explain()` stops the screencast, splices in a
|
|
299
|
+
* demoing". `demo.explain()` stops the screencast, splices in a rendered motion-graphics scene
|
|
300
300
|
* (`title`/`process`/`comparison`/`diagram`/`recap`), and resumes the recording on the same
|
|
301
301
|
* page: the cut-away is a boundary on the timeline, the same mechanism a multi-actor `turn`
|
|
302
302
|
* uses, so nothing about the recording's determinism or re-renderability changes. The scene
|
|
303
303
|
* is compiled and rendered after capture finishes, from a generated one-scene project — the
|
|
304
304
|
* only inputs that matter are the ones right here.
|
|
305
305
|
*
|
|
306
|
-
* Free on every tier, like every authoring verb.
|
|
307
|
-
*
|
|
308
|
-
*
|
|
306
|
+
* Free on every tier, like every authoring verb. Always narrated — the narration is the
|
|
307
|
+
* scene's clock — so it needs the voice model installed at record time even when speech is
|
|
308
|
+
* off (`plaintake doctor` reports whether it is there); a bundle that carries an explain
|
|
309
|
+
* segment re-renders without it, the same way it re-renders without a browser.
|
|
309
310
|
*/
|
|
310
311
|
export type DemoExplain = {
|
|
311
312
|
/**
|
|
312
313
|
* Stable, authored — the same rule every other id here follows. It becomes the directory
|
|
313
|
-
* the frozen artifacts live in (`explain/<id>/segment.mp4` and its
|
|
314
|
-
* the generated scene's own id, so it must read as
|
|
314
|
+
* the frozen artifacts live in (`explain/<id>/segment.mp4` and its frozen plan) and
|
|
315
|
+
* the generated scene's own id, so it must read as scene ids do: lower-case
|
|
315
316
|
* alphanumeric and hyphens, starting alphanumeric. Checked at run time, with the offending
|
|
316
317
|
* id named.
|
|
317
318
|
*/
|
|
@@ -320,7 +321,7 @@ export type DemoExplain = {
|
|
|
320
321
|
title: string;
|
|
321
322
|
/**
|
|
322
323
|
* What the scene says. The source of truth for both the audio and the caption — there is
|
|
323
|
-
* no separate caption field, for the same reason
|
|
324
|
+
* no separate caption field, for the same reason a motion-graphics scene has none: two strings that
|
|
324
325
|
* are supposed to say the same thing will eventually disagree, and the one the viewer
|
|
325
326
|
* hears is the one that matters. The measured speech is also the scene's duration: the
|
|
326
327
|
* cut-away lasts exactly as long as it takes to say this, plus its lead-in and lead-out.
|
|
@@ -387,6 +388,53 @@ export type ActorStepMeta = {
|
|
|
387
388
|
*/
|
|
388
389
|
paddingPx?: number;
|
|
389
390
|
};
|
|
391
|
+
/**
|
|
392
|
+
* `ActorStepMeta` for a `TermHandle` verb, plus the one thing a terminal step can mean that a
|
|
393
|
+
* browser step cannot: `expectExit: true` says the terminal process exiting during this step is
|
|
394
|
+
* the point of it (a `quit`, an `exit`), not a capture failure.
|
|
395
|
+
*/
|
|
396
|
+
export type TermStepMeta = ActorStepMeta & {
|
|
397
|
+
expectExit?: boolean;
|
|
398
|
+
};
|
|
399
|
+
/** A rectangle of terminal cells: zero-based `row`/`col` of its top-left cell, size in cells. */
|
|
400
|
+
export type TermCells = {
|
|
401
|
+
row: number;
|
|
402
|
+
col: number;
|
|
403
|
+
width: number;
|
|
404
|
+
height: number;
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* The live terminal a scenario declaring `terminal` drives, handed to `run()` as `term`. Each
|
|
408
|
+
* verb records `step.start`/`step.finish` through the same bracket `Actor` verbs use, so
|
|
409
|
+
* captions, narration, cursor, camera, highlight and chapters work unchanged.
|
|
410
|
+
*/
|
|
411
|
+
export type TermHandle = {
|
|
412
|
+
/**
|
|
413
|
+
* The terminal as an actor, to turn back to it with `demo.turn(term.actor)`. Only with
|
|
414
|
+
* `terminal.browser: true`; reading it otherwise throws (exit 2).
|
|
415
|
+
*/
|
|
416
|
+
readonly actor: Actor;
|
|
417
|
+
/** Types `line`, then Enter. Records a step whose target is the prompt line. */
|
|
418
|
+
run(line: string, meta?: TermStepMeta): Promise<void>;
|
|
419
|
+
/** Types at a fixed per-character delay — part of the timeline, never wall-clock driven. */
|
|
420
|
+
type(text: string, meta?: TermStepMeta): Promise<void>;
|
|
421
|
+
/** `'Enter'`, `'Ctrl+C'`, or a space-separated sequence such as `'Ctrl+B c'`. */
|
|
422
|
+
press(keys: string, meta?: TermStepMeta): Promise<void>;
|
|
423
|
+
/** Same bounds and timeout semantics as `demo.waitFor`. */
|
|
424
|
+
waitForText(pattern: RegExp | string, opts?: {
|
|
425
|
+
timeoutMs?: number;
|
|
426
|
+
id?: string;
|
|
427
|
+
title?: string;
|
|
428
|
+
}): Promise<void>;
|
|
429
|
+
/** A locator over the first match on the visible screen. */
|
|
430
|
+
getByText(pattern: RegExp | string): Locator;
|
|
431
|
+
/** A locator over a rectangle of cells, refused when it is outside the grid. */
|
|
432
|
+
cells(r: TermCells): Locator;
|
|
433
|
+
/** The visible screen, one line per row. */
|
|
434
|
+
screenText(): Promise<string>;
|
|
435
|
+
/** Reuses `DemoAssertion` verbatim, recorded against the default actor like `demo.assert`. */
|
|
436
|
+
assert(assertion: DemoAssertion): Promise<void>;
|
|
437
|
+
};
|
|
390
438
|
/**
|
|
391
439
|
* A named participant in a multi-actor demo: its own Playwright `BrowserContext`, its own
|
|
392
440
|
* page, and a handle of verbs that each perform a Playwright action *and* record the
|
|
@@ -539,20 +587,14 @@ export interface DemoContext extends PreflightContext {
|
|
|
539
587
|
* `opts.card`, when given, plays a full-frame transition card between the two actors'
|
|
540
588
|
* segments — the `lines` it names, an optional spoken `narration`, held for `durationMs`.
|
|
541
589
|
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
* is synthesised at render time as `Now: <label>`, naming the
|
|
545
|
-
* it was given to `demo.actor()`, held for the
|
|
546
|
-
*
|
|
547
|
-
* either way; `opts.card` only ever changes whether that hand-off also gets a full-frame beat
|
|
548
|
-
* of its own, and what it says.
|
|
590
|
+
* `opts.card: false` is a hard cut: no card and no gap. With no `opts.card` the scenario
|
|
591
|
+
* default applies: a cut for a `terminal.browser` scenario unless `terminal.transition` is
|
|
592
|
+
* `'card'`; otherwise the card is synthesised at render time as `Now: <label>`, naming the
|
|
593
|
+
* incoming actor by the `label` it was given to `demo.actor()`, held for the default
|
|
594
|
+
* duration. The persistent corner badge names the active actor throughout either way.
|
|
549
595
|
*/
|
|
550
596
|
turn(actor: Actor, opts?: {
|
|
551
|
-
card?:
|
|
552
|
-
lines: string[];
|
|
553
|
-
narration?: string;
|
|
554
|
-
durationMs?: number;
|
|
555
|
-
};
|
|
597
|
+
card?: TurnCard | false;
|
|
556
598
|
}): Promise<void>;
|
|
557
599
|
/**
|
|
558
600
|
* Cuts away from the browser recording to a full-frame motion-graphics scene — a diagram
|
|
@@ -561,10 +603,10 @@ export interface DemoContext extends PreflightContext {
|
|
|
561
603
|
* a `turn` does minus the actor switch, so the cut-away occupies its own slot on the
|
|
562
604
|
* timeline and nothing it covers is ever captured.
|
|
563
605
|
*
|
|
564
|
-
* The scene is not drawn live: it is compiled and rendered
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
606
|
+
* The scene is not drawn live: it is compiled and rendered in process after capture
|
|
607
|
+
* finishes, from the request's own fields, and spliced in at render time as a frozen
|
|
608
|
+
* 1920×1080@30 segment — which is what keeps the bundle re-renderable without a voice
|
|
609
|
+
* model, without a browser, and byte-identically. Its narration is spoken by the
|
|
568
610
|
* same engine as the rest of the recording (`--speech on`), lands in the same caption
|
|
569
611
|
* track, and is the scene's clock: the cut-away lasts exactly as long as it takes to say.
|
|
570
612
|
*
|
|
@@ -574,10 +616,25 @@ export interface DemoContext extends PreflightContext {
|
|
|
574
616
|
*/
|
|
575
617
|
explain(request: DemoExplain): Promise<void>;
|
|
576
618
|
}
|
|
619
|
+
/** An explicit transition card for `demo.turn`. */
|
|
620
|
+
export type TurnCard = {
|
|
621
|
+
lines: string[];
|
|
622
|
+
narration?: string;
|
|
623
|
+
durationMs?: number;
|
|
624
|
+
};
|
|
625
|
+
/**
|
|
626
|
+
* `term` is present only when the scenario declares `terminal`; a scenario without one is
|
|
627
|
+
* handed no `term` key at all.
|
|
628
|
+
*
|
|
629
|
+
* `page` is the terminal page in a terminal scenario. `baseURL` is the web target (`--base-url`
|
|
630
|
+
* or the fixture) when `terminal.browser` is set; without it, in a terminal scenario, it is the
|
|
631
|
+
* terminal page's URL.
|
|
632
|
+
*/
|
|
577
633
|
export type DemoRunArgs = {
|
|
578
634
|
page: Page;
|
|
579
635
|
demo: DemoContext;
|
|
580
636
|
baseURL: string;
|
|
637
|
+
term?: TermHandle;
|
|
581
638
|
};
|
|
582
639
|
/** Same property names as `DemoRunArgs`, so moving code between phases changes nothing else. */
|
|
583
640
|
export type PreflightArgs = {
|
|
@@ -625,7 +682,8 @@ export type DemoDefinition = ScenarioMeta & {
|
|
|
625
682
|
* field is one edit here instead of two that can drift apart.
|
|
626
683
|
*/
|
|
627
684
|
type Defaulted = 'language' | 'allowedConsoleErrors' | 'handoff' | 'handoffTimeoutMs';
|
|
628
|
-
export type DemoDefinitionInput = Omit<ScenarioMeta, Defaulted> & Partial<Pick<ScenarioMeta, Defaulted>> & {
|
|
685
|
+
export type DemoDefinitionInput = Omit<ScenarioMeta, Defaulted | 'terminal'> & Partial<Pick<ScenarioMeta, Defaulted>> & {
|
|
686
|
+
terminal?: TerminalMetaInput;
|
|
629
687
|
run(args: DemoRunArgs): Promise<void>;
|
|
630
688
|
} & PreflightHook & WarmupHook;
|
|
631
689
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plaintake/scenario",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "Authoring SDK for PlainTake demo scenarios: defineDemo and the scenario DSL types. Install for editor autocomplete; the PlainTake binary ships a runtime fallback.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|