@codefilm/recorder 3.0.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.
@@ -0,0 +1,916 @@
1
+ import { parseFilmScript as _ } from "./FilmRecorder.js";
2
+ class I extends Error {
3
+ trace;
4
+ constructor(t, n) {
5
+ super(t), this.name = "AppFilmGenerationError", this.cause = n?.cause, this.trace = n?.trace;
6
+ }
7
+ }
8
+ const $ = /^\s*#\s*setup\s+([A-Za-z0-9_.:-]+)\s*:\s*(.*)$/;
9
+ function y(e, t = "") {
10
+ const n = [];
11
+ for (const s of e.split(/\r?\n/)) {
12
+ const o = $.exec(s);
13
+ o && n.push({
14
+ type: o[1],
15
+ value: re(o[2].trim())
16
+ });
17
+ }
18
+ return { appId: t, entries: n };
19
+ }
20
+ function g(e) {
21
+ return e.split(/\r?\n/).filter((t) => !$.test(t)).join(`
22
+ `).replace(/^\s+/, "");
23
+ }
24
+ function H(e) {
25
+ return e.entries.map((t) => `# setup ${t.type}: ${se(t.value)}`).join(`
26
+ `);
27
+ }
28
+ function ve(e, t = {}) {
29
+ const n = e.trim(), s = oe(t.app) || t.setup?.appId || "", o = y(n, s), r = ae(o, t.setup, s), a = g(n).trim(), l = n.split(/\r?\n/).filter((p) => $.test(p)).join(`
30
+ `), c = t.stripSetupForDisplay ?? !0, u = t.stripSetupForPlayback ?? !0;
31
+ return {
32
+ isFilmScript: /^\s*film\s+/i.test(a),
33
+ fullScript: n,
34
+ displayScript: c ? a : n,
35
+ runnableScript: u ? a : n,
36
+ setup: r,
37
+ setupComments: l,
38
+ filmBody: a
39
+ };
40
+ }
41
+ function b(e, t) {
42
+ const n = T(
43
+ y(e, t.id),
44
+ t
45
+ ), s = _(g(e)), o = [];
46
+ s.length === 0 && o.push({
47
+ line: 1,
48
+ scene: null,
49
+ commandIndex: null,
50
+ message: "No film script scenes were found."
51
+ });
52
+ const r = le(n), a = Object.values(t.selectors);
53
+ for (const l of s)
54
+ l.commands.forEach((c, u) => {
55
+ if (!c.selector) return;
56
+ const i = a.find(
57
+ (p) => p.selector === c.selector
58
+ );
59
+ if (!i) {
60
+ o.push({
61
+ line: c.sourceLine ?? 1,
62
+ scene: l.name,
63
+ commandIndex: u,
64
+ message: `Selector "${c.selector}" is not declared in app profile "${t.id}".`
65
+ });
66
+ return;
67
+ }
68
+ for (const p of i.requiresSetup ?? [])
69
+ r.has(p) || o.push({
70
+ line: c.sourceLine ?? 1,
71
+ scene: l.name,
72
+ commandIndex: u,
73
+ message: `Selector "${c.selector}" requires setup "${p}", but that setup was not provided.`
74
+ });
75
+ });
76
+ return ue(n, t, o), de(g(e), n, t, o), {
77
+ valid: o.length === 0,
78
+ scenes: s,
79
+ diagnostics: o
80
+ };
81
+ }
82
+ async function we(e) {
83
+ W(e.signal);
84
+ const t = F(e.trace);
85
+ try {
86
+ let n, s = [];
87
+ const o = [];
88
+ if (Y(e)) {
89
+ n = await K(e, t);
90
+ const i = E(n, e.app);
91
+ s = i.diagnostics, o.push(...i.warnings), S(t, "intent", {
92
+ diagnostics: i.diagnostics,
93
+ warnings: i.warnings
94
+ });
95
+ }
96
+ const r = await v(
97
+ "script",
98
+ {
99
+ instructions: O(e.app, n),
100
+ input: A(e.input, n),
101
+ tools: [C(e.app)],
102
+ toolChoice: "required",
103
+ signal: e.signal
104
+ },
105
+ e.complete,
106
+ t
107
+ ), a = G(r);
108
+ if (n = n ?? a.intent, a.intent) {
109
+ const i = E(a.intent, e.app);
110
+ s.push(...i.diagnostics), o.push(...i.warnings);
111
+ }
112
+ let l = T(
113
+ ce(
114
+ a.setup ?? y(a.script, e.app.id),
115
+ n,
116
+ e.app
117
+ ),
118
+ e.app
119
+ ), c = j(a.script, l), u = b(c, e.app);
120
+ if (o.push(...a.warnings ?? []), S(t, "script", {
121
+ diagnostics: [...s, ...u.diagnostics],
122
+ warnings: o
123
+ }), (s.length > 0 || !u.valid) && e.repair) {
124
+ const i = await x(
125
+ c,
126
+ {
127
+ app: e.app,
128
+ input: A(e.input, n),
129
+ complete: e.complete,
130
+ signal: e.signal,
131
+ diagnostics: [...s, ...u.diagnostics]
132
+ },
133
+ t
134
+ );
135
+ c = i.script, l = i.setup, u = {
136
+ valid: i.diagnostics.length === 0,
137
+ scenes: _(g(i.script)),
138
+ diagnostics: i.diagnostics
139
+ }, o.push(...i.warnings);
140
+ }
141
+ return N(
142
+ {
143
+ intent: n,
144
+ script: c,
145
+ setup: l,
146
+ diagnostics: [...s, ...u.diagnostics],
147
+ warnings: o
148
+ },
149
+ t
150
+ );
151
+ } catch (n) {
152
+ q(n, t);
153
+ }
154
+ }
155
+ async function Te(e, t) {
156
+ W(t.signal);
157
+ const n = F(t.trace);
158
+ return x(e, t, n);
159
+ }
160
+ async function x(e, t, n) {
161
+ try {
162
+ const s = t.diagnostics ?? b(e, t.app).diagnostics, o = await v(
163
+ "repair",
164
+ {
165
+ instructions: Z(t.app, s),
166
+ input: [
167
+ t.input ? `User request:
168
+ ${t.input}` : "",
169
+ `Invalid script:
170
+ ${e}`,
171
+ `Diagnostics:
172
+ ${s.map((u) => u.message).join(`
173
+ `)}`
174
+ ].filter(Boolean).join(`
175
+
176
+ `),
177
+ tools: [C(t.app)],
178
+ toolChoice: "required",
179
+ signal: t.signal
180
+ },
181
+ t.complete,
182
+ n
183
+ ), r = G(o), a = T(
184
+ r.setup ?? y(r.script, t.app.id),
185
+ t.app
186
+ ), l = j(r.script, a), c = b(l, t.app);
187
+ return S(n, "repair", {
188
+ diagnostics: c.diagnostics,
189
+ warnings: r.warnings ?? []
190
+ }), N(
191
+ {
192
+ script: l,
193
+ setup: a,
194
+ diagnostics: c.diagnostics,
195
+ warnings: r.warnings ?? []
196
+ },
197
+ n
198
+ );
199
+ } catch (s) {
200
+ q(s, n);
201
+ }
202
+ }
203
+ async function K(e, t) {
204
+ const n = await v(
205
+ "intent",
206
+ {
207
+ instructions: Q(e.app),
208
+ input: e.input,
209
+ tools: [ie(e.app)],
210
+ toolChoice: "required",
211
+ signal: e.signal
212
+ },
213
+ e.complete,
214
+ t
215
+ );
216
+ return ye(
217
+ he(n),
218
+ e.app
219
+ );
220
+ }
221
+ function Y(e) {
222
+ return e.intentMode !== "off" && (e.app.intents?.length ?? 0) > 0;
223
+ }
224
+ function O(e, t) {
225
+ return [
226
+ `You generate code.film scripts for ${e.name}.`,
227
+ e.description ? `App description: ${e.description}` : "",
228
+ "Return the result by calling the create_film_script tool.",
229
+ "Do not return prose outside the tool call.",
230
+ "Use only selectors declared in the app profile.",
231
+ "Honor any approval or permission-mode guidance declared by the app profile; do not invent older permission labels.",
232
+ "Include setup entries for every selector that requires setup.",
233
+ "Prefer the smallest meaningful camera scope unless the user asks for page chrome, navigation, sidebars, collections, or multiple regions.",
234
+ t ? "Follow the resolved intent exactly. Only submit a prompt when resolvedIntent.submitPrompt is true." : "",
235
+ t ? `Resolved intent:
236
+ ${JSON.stringify(t, null, 2)}` : "",
237
+ "Preserve setup comments at the top of the script for compatibility.",
238
+ "",
239
+ M(e)
240
+ ].filter(Boolean).join(`
241
+ `);
242
+ }
243
+ function Z(e, t) {
244
+ return [
245
+ O(e),
246
+ "",
247
+ "Repair the script so validation passes.",
248
+ "Keep the user intent, but add missing setup or switch to valid selectors as needed.",
249
+ "Validation diagnostics:",
250
+ t.map((n) => `- ${n.message}`).join(`
251
+ `)
252
+ ].join(`
253
+ `);
254
+ }
255
+ function Q(e) {
256
+ return [
257
+ `Resolve user film requests for ${e.name}.`,
258
+ e.description ? `App description: ${e.description}` : "",
259
+ "Return the result by calling the resolve_film_intent tool.",
260
+ "Do not return prose outside the tool call.",
261
+ "Choose exactly one declared intent recipe.",
262
+ "Use examples, synonyms, and negative examples as model context, not as literal substring rules.",
263
+ "Do not assume a short prompt should be submitted to the app. Only set submitPrompt true when the chosen intent requires app prompt submission.",
264
+ "When prompt tools or attachments are needed, return them as structured promptTools or attachments.",
265
+ "",
266
+ M(e)
267
+ ].filter(Boolean).join(`
268
+ `);
269
+ }
270
+ function A(e, t) {
271
+ return t ? [
272
+ `User request:
273
+ ${e}`,
274
+ `Resolved intent:
275
+ ${JSON.stringify(t, null, 2)}`
276
+ ].join(`
277
+
278
+ `) : e;
279
+ }
280
+ function F(e) {
281
+ const t = X(e);
282
+ return {
283
+ options: t,
284
+ trace: t.enabled ? { calls: [] } : void 0
285
+ };
286
+ }
287
+ function X(e) {
288
+ return e ? e === !0 ? {
289
+ enabled: !0,
290
+ includeInstructions: !0,
291
+ includeRaw: !1
292
+ } : {
293
+ enabled: e.enabled !== !1,
294
+ includeInstructions: e.includeInstructions ?? !0,
295
+ includeRaw: e.includeRaw ?? !1,
296
+ redact: e.redact
297
+ } : {
298
+ enabled: !1,
299
+ includeInstructions: !1,
300
+ includeRaw: !1
301
+ };
302
+ }
303
+ async function v(e, t, n, s) {
304
+ if (!s.trace)
305
+ return n(t);
306
+ const o = Date.now(), r = {
307
+ phase: e,
308
+ request: ee(t, s.options),
309
+ startedAt: new Date(o).toISOString()
310
+ };
311
+ s.trace.calls.push(r);
312
+ try {
313
+ const a = await n(t);
314
+ return r.response = te(a, s.options), P(r, o), R(s, r), a;
315
+ } catch (a) {
316
+ throw r.error = ne(a), P(r, o), R(s, r), a;
317
+ }
318
+ }
319
+ function ee(e, t) {
320
+ return {
321
+ instructions: t.includeInstructions ? e.instructions : void 0,
322
+ input: e.input,
323
+ tools: e.tools,
324
+ toolChoice: e.toolChoice
325
+ };
326
+ }
327
+ function te(e, t) {
328
+ return {
329
+ toolName: e.toolName,
330
+ arguments: e.arguments,
331
+ raw: t.includeRaw ? e.raw : void 0
332
+ };
333
+ }
334
+ function P(e, t) {
335
+ const n = Date.now();
336
+ e.finishedAt = new Date(n).toISOString(), e.durationMs = n - t;
337
+ }
338
+ function S(e, t, n) {
339
+ if (!e.trace) return;
340
+ const s = [...e.trace.calls].reverse().find((o) => o.phase === t);
341
+ s && (n.diagnostics && (s.diagnostics = n.diagnostics), n.warnings && (s.warnings = n.warnings));
342
+ }
343
+ function R(e, t) {
344
+ if (!e.trace || !e.options.redact) return;
345
+ const n = e.trace.calls.indexOf(t);
346
+ n !== -1 && (e.trace.calls[n] = e.options.redact(t));
347
+ }
348
+ function N(e, t) {
349
+ return t.trace ? {
350
+ ...e,
351
+ trace: t.trace
352
+ } : e;
353
+ }
354
+ function q(e, t) {
355
+ throw t.trace ? e instanceof I ? (e.trace = e.trace ?? t.trace, e) : new I(D(e), {
356
+ cause: e,
357
+ trace: t.trace
358
+ }) : e;
359
+ }
360
+ function ne(e) {
361
+ return {
362
+ message: D(e),
363
+ name: e instanceof Error ? e.name : void 0
364
+ };
365
+ }
366
+ function D(e) {
367
+ return e instanceof Error ? e.message : String(e);
368
+ }
369
+ function M(e) {
370
+ const t = Object.entries(e.selectors).map(([i, p]) => {
371
+ const L = p.requiresSetup?.length ? ` Requires setup: ${p.requiresSetup.join(", ")}.` : "";
372
+ return `- ${i}: ${p.selector} (${p.role ?? "component"}) - ${p.description}.${L}`;
373
+ }).join(`
374
+ `), n = Object.entries(e.pages).map(
375
+ ([i, p]) => `- ${i}: ${p.description}; container ${p.containerSelector}` + (p.defaultScopeSelector ? `; default scope ${p.defaultScopeSelector}` : "")
376
+ ).join(`
377
+ `), s = e.setupCapabilities.map((i) => `- ${i}`).join(`
378
+ `), o = (e.rules ?? []).map((i) => `- ${i}`).join(`
379
+ `), r = Object.entries(e.vocabulary ?? {}).map(([i, p]) => `- ${i}: ${p.join(", ")}`).join(`
380
+ `), a = (e.examples ?? []).map(
381
+ (i) => `User: ${i.input}
382
+ Script:
383
+ ${j(
384
+ i.script,
385
+ i.setup ?? y(i.script, e.id)
386
+ )}`
387
+ ).join(`
388
+
389
+ `), l = (e.intents ?? []).map((i) => [
390
+ `- ${i.id}: ${i.description}`,
391
+ ` Page: ${i.page}; submitPrompt: ${i.submitPrompt}`,
392
+ i.defaultScopeSelector ? ` Default scope: ${i.defaultScopeSelector}` : "",
393
+ i.examples.length ? ` Examples: ${i.examples.join("; ")}` : "",
394
+ i.synonyms?.length ? ` Synonyms: ${i.synonyms.join("; ")}` : "",
395
+ i.negativeExamples?.length ? ` Negative examples: ${i.negativeExamples.join("; ")}` : "",
396
+ i.requiredSetup?.length ? ` Required setup: ${i.requiredSetup.join(", ")}` : "",
397
+ i.scriptGuidance ? ` Script guidance: ${i.scriptGuidance}` : ""
398
+ ].filter(Boolean).join(`
399
+ `)).join(`
400
+ `), c = (e.promptTools ?? []).map((i) => {
401
+ const p = i.installed === !1 ? "uninstalled" : "installed";
402
+ return [
403
+ `- ${i.id}: ${i.name} (${i.mention}, ${p}) - ${i.description}`,
404
+ i.aliases?.length ? ` Aliases: ${i.aliases.join("; ")}` : "",
405
+ i.examples?.length ? ` Examples: ${i.examples.join("; ")}` : ""
406
+ ].filter(Boolean).join(`
407
+ `);
408
+ }).join(`
409
+ `), u = (e.attachmentTypes ?? []).map(
410
+ (i) => [
411
+ `- ${i.id}: ${i.label}`,
412
+ i.aliases?.length ? ` Aliases: ${i.aliases.join("; ")}` : "",
413
+ i.examples?.length ? ` Examples: ${i.examples.join("; ")}` : ""
414
+ ].filter(Boolean).join(`
415
+ `)
416
+ ).join(`
417
+ `);
418
+ return [
419
+ "Selectors:",
420
+ t,
421
+ "",
422
+ "Pages:",
423
+ n,
424
+ "",
425
+ "Setup capabilities:",
426
+ s,
427
+ e.defaults ? `
428
+ Generation defaults:
429
+ ${JSON.stringify(e.defaults, null, 2)}` : "",
430
+ l ? `
431
+ Intent recipes:
432
+ ${l}` : "",
433
+ c ? `
434
+ Prompt tools:
435
+ ${c}` : "",
436
+ u ? `
437
+ Attachment types:
438
+ ${u}` : "",
439
+ o ? `
440
+ Rules:
441
+ ${o}` : "",
442
+ r ? `
443
+ Vocabulary:
444
+ ${r}` : "",
445
+ a ? `
446
+ Examples:
447
+ ${a}` : ""
448
+ ].join(`
449
+ `);
450
+ }
451
+ function ie(e) {
452
+ const t = (e.intents ?? []).map((r) => r.id), n = Object.keys(e.pages), s = (e.promptTools ?? []).map((r) => r.id), o = (e.attachmentTypes ?? []).map(
453
+ (r) => r.id
454
+ );
455
+ return {
456
+ type: "function",
457
+ name: "resolve_film_intent",
458
+ description: "Resolve a user film request into one declared app intent.",
459
+ strict: !0,
460
+ parameters: {
461
+ type: "object",
462
+ properties: {
463
+ intentId: h(t),
464
+ confidence: w({ type: "number" }),
465
+ page: h(n),
466
+ scopeSelector: m(),
467
+ submitPrompt: { type: "boolean" },
468
+ promptText: m(),
469
+ promptTools: {
470
+ anyOf: [
471
+ { type: "array", items: J(s) },
472
+ { type: "null" }
473
+ ]
474
+ },
475
+ attachments: {
476
+ anyOf: [
477
+ { type: "array", items: k(o) },
478
+ { type: "null" }
479
+ ]
480
+ },
481
+ setupNeeded: {
482
+ anyOf: [
483
+ { type: "array", items: { type: "string" } },
484
+ { type: "null" }
485
+ ]
486
+ },
487
+ rationale: { type: "string" }
488
+ },
489
+ required: [
490
+ "intentId",
491
+ "confidence",
492
+ "page",
493
+ "scopeSelector",
494
+ "submitPrompt",
495
+ "promptText",
496
+ "promptTools",
497
+ "attachments",
498
+ "setupNeeded",
499
+ "rationale"
500
+ ],
501
+ additionalProperties: !1
502
+ }
503
+ };
504
+ }
505
+ function C(e) {
506
+ const t = (e.promptTools ?? []).map((s) => s.id), n = (e.attachmentTypes ?? []).map(
507
+ (s) => s.id
508
+ );
509
+ return {
510
+ type: "function",
511
+ name: "create_film_script",
512
+ description: "Create a code.film script and structured setup for a host app.",
513
+ strict: !0,
514
+ parameters: {
515
+ type: "object",
516
+ properties: {
517
+ intent: {
518
+ anyOf: [
519
+ {
520
+ type: "object",
521
+ properties: {
522
+ id: { type: "string" },
523
+ confidence: w({ type: "number" }),
524
+ page: { type: "string" },
525
+ scopeSelector: m(),
526
+ submitPrompt: { type: "boolean" },
527
+ promptText: m(),
528
+ promptTools: {
529
+ anyOf: [
530
+ { type: "array", items: J(t) },
531
+ { type: "null" }
532
+ ]
533
+ },
534
+ attachments: {
535
+ anyOf: [
536
+ { type: "array", items: k(n) },
537
+ { type: "null" }
538
+ ]
539
+ },
540
+ setupNeeded: {
541
+ anyOf: [
542
+ { type: "array", items: { type: "string" } },
543
+ { type: "null" }
544
+ ]
545
+ },
546
+ rationale: m()
547
+ },
548
+ required: [
549
+ "id",
550
+ "confidence",
551
+ "page",
552
+ "scopeSelector",
553
+ "submitPrompt",
554
+ "promptText",
555
+ "promptTools",
556
+ "attachments",
557
+ "setupNeeded",
558
+ "rationale"
559
+ ],
560
+ additionalProperties: !1
561
+ },
562
+ { type: "null" }
563
+ ]
564
+ },
565
+ script: {
566
+ type: "string",
567
+ description: "Complete code.film script. Include setup comments at the top when setup is required."
568
+ },
569
+ setup: {
570
+ type: "object",
571
+ properties: {
572
+ appId: { type: "string", enum: [e.id] },
573
+ entries: {
574
+ type: "array",
575
+ items: {
576
+ type: "object",
577
+ properties: {
578
+ type: { type: "string" },
579
+ value: {
580
+ type: "string",
581
+ description: "Setup value as JSON text for objects/arrays/strings, or plain text for simple values."
582
+ }
583
+ },
584
+ required: ["type", "value"],
585
+ additionalProperties: !1
586
+ }
587
+ }
588
+ },
589
+ required: ["appId", "entries"],
590
+ additionalProperties: !1
591
+ },
592
+ warnings: {
593
+ type: "array",
594
+ items: { type: "string" }
595
+ }
596
+ },
597
+ required: ["intent", "script", "setup", "warnings"],
598
+ additionalProperties: !1
599
+ }
600
+ };
601
+ }
602
+ function h(e = []) {
603
+ return e.length > 0 ? { type: "string", enum: e } : { type: "string" };
604
+ }
605
+ function m() {
606
+ return w({ type: "string" });
607
+ }
608
+ function w(e) {
609
+ return { anyOf: [e, { type: "null" }] };
610
+ }
611
+ function J(e = []) {
612
+ return {
613
+ type: "object",
614
+ properties: {
615
+ id: h(e),
616
+ mention: { type: "string" },
617
+ label: m(),
618
+ reason: m()
619
+ },
620
+ required: ["id", "mention", "label", "reason"],
621
+ additionalProperties: !1
622
+ };
623
+ }
624
+ function k(e = []) {
625
+ return {
626
+ type: "object",
627
+ properties: {
628
+ type: h(e),
629
+ name: m(),
630
+ label: m(),
631
+ reason: m()
632
+ },
633
+ required: ["type", "name", "label", "reason"],
634
+ additionalProperties: !1
635
+ };
636
+ }
637
+ function re(e) {
638
+ if (e === "") return "";
639
+ try {
640
+ return JSON.parse(e);
641
+ } catch {
642
+ return e;
643
+ }
644
+ }
645
+ function se(e) {
646
+ return typeof e == "string" ? e : JSON.stringify(e);
647
+ }
648
+ function T(e, t) {
649
+ return {
650
+ appId: e.appId || t.id,
651
+ entries: e.entries.map((n) => ({
652
+ type: t.setupAliases?.[n.type] ?? n.type,
653
+ value: n.value
654
+ }))
655
+ };
656
+ }
657
+ function oe(e) {
658
+ return e ? typeof e == "string" ? e : e.id : "";
659
+ }
660
+ function ae(e, t, n) {
661
+ const s = [...e.entries];
662
+ for (const o of t?.entries ?? [])
663
+ s.some((r) => pe(r, o)) || s.push(o);
664
+ return {
665
+ appId: n || e.appId || t?.appId || "",
666
+ entries: s
667
+ };
668
+ }
669
+ function pe(e, t) {
670
+ return e.type === t.type && JSON.stringify(e.value) === JSON.stringify(t.value);
671
+ }
672
+ function ce(e, t, n) {
673
+ if (!t) return e;
674
+ const s = n.intents?.find((r) => r.id === t.id), o = [...e.entries];
675
+ for (const r of s?.setup ?? [])
676
+ o.some((a) => a.type === r.type) || o.push(r);
677
+ for (const r of t.promptTools ?? [])
678
+ o.some((a) => B(a, r)) || o.push({ type: "promptTool", value: r });
679
+ for (const r of t.attachments ?? [])
680
+ o.some((a) => me(a, r)) || o.push({ type: "attachment", value: r });
681
+ return { ...e, entries: o };
682
+ }
683
+ function le(e) {
684
+ const t = /* @__PURE__ */ new Set();
685
+ for (const n of e.entries)
686
+ t.add(n.type), d(n.value) && (typeof n.value.type == "string" && t.add(`${n.type}:${n.value.type}`), typeof n.value.id == "string" && t.add(`${n.type}:${n.value.id}`));
687
+ return t;
688
+ }
689
+ function ue(e, t, n) {
690
+ const s = new Set(t.setupCapabilities), o = new Set(
691
+ t.setupCapabilities.map((r) => r.split(":")[0])
692
+ );
693
+ for (const r of e.entries)
694
+ !(s.has(r.type) || d(r.value) && typeof r.value.type == "string" && s.has(`${r.type}:${r.value.type}`)) && !o.has(r.type) && n.push({
695
+ line: 1,
696
+ scene: null,
697
+ commandIndex: null,
698
+ message: `Setup "${r.type}" is not declared in app profile "${t.id}".`
699
+ });
700
+ }
701
+ function de(e, t, n, s) {
702
+ for (const o of n.promptTools ?? []) {
703
+ if (!e.includes(o.mention)) continue;
704
+ t.entries.some(
705
+ (a) => B(a, {
706
+ id: o.id,
707
+ mention: o.mention
708
+ })
709
+ ) || s.push(
710
+ f(
711
+ `Script uses prompt tool mention "${o.mention}" without matching promptTool setup.`
712
+ )
713
+ );
714
+ }
715
+ }
716
+ function B(e, t) {
717
+ return e.type !== "promptTool" || !d(e.value) ? !1 : e.value.id === t.id || e.value.mention === t.mention;
718
+ }
719
+ function me(e, t) {
720
+ return e.type !== "attachment" || !d(e.value) ? !1 : e.value.type === t.type && (t.name === void 0 || e.value.name === t.name);
721
+ }
722
+ function fe(e, t) {
723
+ const n = new Set(t.setupCapabilities), s = new Set(
724
+ t.setupCapabilities.map((o) => o.split(":")[0])
725
+ );
726
+ return n.has(e) || s.has(e.split(":")[0]);
727
+ }
728
+ function E(e, t) {
729
+ const n = [], s = [], o = t.intents?.find((r) => r.id === e.id);
730
+ o || n.push(
731
+ f(
732
+ `Resolved intent "${e.id}" is not declared in app profile "${t.id}".`
733
+ )
734
+ ), t.pages[e.page] || n.push(
735
+ f(
736
+ `Resolved intent page "${e.page}" is not declared in app profile "${t.id}".`
737
+ )
738
+ ), e.scopeSelector && !ge(e.scopeSelector, t) && n.push(
739
+ f(
740
+ `Resolved intent scope selector "${e.scopeSelector}" is not declared in app profile "${t.id}".`
741
+ )
742
+ );
743
+ for (const r of e.setupNeeded ?? [])
744
+ fe(r, t) || n.push(
745
+ f(
746
+ `Resolved intent setup "${r}" is not declared in app profile "${t.id}".`
747
+ )
748
+ );
749
+ for (const r of e.promptTools ?? []) {
750
+ const a = t.promptTools?.find((l) => l.id === r.id);
751
+ if (!a) {
752
+ n.push(
753
+ f(
754
+ `Resolved prompt tool "${r.id}" is not declared in app profile "${t.id}".`
755
+ )
756
+ );
757
+ continue;
758
+ }
759
+ r.mention !== a.mention && n.push(
760
+ f(
761
+ `Resolved prompt tool "${r.id}" mention "${r.mention}" does not match declared mention "${a.mention}".`
762
+ )
763
+ ), a.installed === !1 && s.push(`Prompt tool "${a.name}" is declared but not installed.`);
764
+ }
765
+ for (const r of e.attachments ?? [])
766
+ t.attachmentTypes?.some((a) => a.id === r.type) || n.push(
767
+ f(
768
+ `Resolved attachment type "${r.type}" is not declared in app profile "${t.id}".`
769
+ )
770
+ );
771
+ return o && e.submitPrompt !== o.submitPrompt && s.push(
772
+ `Resolved intent "${e.id}" changed submitPrompt from recipe default ${o.submitPrompt} to ${e.submitPrompt}.`
773
+ ), { diagnostics: n, warnings: s };
774
+ }
775
+ function ge(e, t) {
776
+ return Object.values(t.selectors).some((n) => n.selector === e) ? !0 : Object.values(t.pages).some(
777
+ (n) => n.containerSelector === e || n.defaultScopeSelector === e
778
+ );
779
+ }
780
+ function f(e) {
781
+ return {
782
+ line: 1,
783
+ scene: null,
784
+ commandIndex: null,
785
+ message: e
786
+ };
787
+ }
788
+ function ye(e, t) {
789
+ const n = t.intents?.find((s) => s.id === e.intentId);
790
+ return {
791
+ id: e.intentId,
792
+ confidence: e.confidence,
793
+ page: e.page || n?.page || "",
794
+ scopeSelector: e.scopeSelector ?? n?.defaultScopeSelector,
795
+ submitPrompt: e.submitPrompt,
796
+ promptText: e.promptText,
797
+ promptTools: e.promptTools,
798
+ attachments: e.attachments,
799
+ setupNeeded: e.setupNeeded ?? n?.requiredSetup,
800
+ rationale: e.rationale
801
+ };
802
+ }
803
+ function he(e) {
804
+ if (e.toolName !== "resolve_film_intent")
805
+ throw new Error(
806
+ `[code-film] Expected resolve_film_intent tool call, received "${e.toolName}".`
807
+ );
808
+ if (!d(e.arguments))
809
+ throw new Error("[code-film] resolve_film_intent arguments must be an object.");
810
+ if (typeof e.arguments.intentId != "string")
811
+ throw new Error("[code-film] resolve_film_intent.intentId must be a string.");
812
+ if (typeof e.arguments.page != "string")
813
+ throw new Error("[code-film] resolve_film_intent.page must be a string.");
814
+ if (typeof e.arguments.submitPrompt != "boolean")
815
+ throw new Error("[code-film] resolve_film_intent.submitPrompt must be a boolean.");
816
+ if (typeof e.arguments.rationale != "string")
817
+ throw new Error("[code-film] resolve_film_intent.rationale must be a string.");
818
+ return {
819
+ intentId: e.arguments.intentId,
820
+ confidence: typeof e.arguments.confidence == "number" ? e.arguments.confidence : void 0,
821
+ page: e.arguments.page,
822
+ scopeSelector: typeof e.arguments.scopeSelector == "string" ? e.arguments.scopeSelector : void 0,
823
+ submitPrompt: e.arguments.submitPrompt,
824
+ promptText: typeof e.arguments.promptText == "string" ? e.arguments.promptText : void 0,
825
+ promptTools: U(e.arguments.promptTools),
826
+ attachments: z(e.arguments.attachments),
827
+ setupNeeded: V(e.arguments.setupNeeded),
828
+ rationale: e.arguments.rationale
829
+ };
830
+ }
831
+ function G(e) {
832
+ if (e.toolName !== "create_film_script")
833
+ throw new Error(
834
+ `[code-film] Expected create_film_script tool call, received "${e.toolName}".`
835
+ );
836
+ if (!d(e.arguments))
837
+ throw new Error("[code-film] create_film_script arguments must be an object.");
838
+ if (typeof e.arguments.script != "string")
839
+ throw new Error("[code-film] create_film_script.script must be a string.");
840
+ return {
841
+ intent: be(e.arguments.intent),
842
+ script: e.arguments.script,
843
+ setup: Se(e.arguments.setup) ? e.arguments.setup : void 0,
844
+ warnings: Array.isArray(e.arguments.warnings) ? e.arguments.warnings.filter(
845
+ (t) => typeof t == "string"
846
+ ) : []
847
+ };
848
+ }
849
+ function be(e) {
850
+ if (d(e) && !(typeof e.id != "string" || typeof e.page != "string" || typeof e.submitPrompt != "boolean"))
851
+ return {
852
+ id: e.id,
853
+ confidence: typeof e.confidence == "number" ? e.confidence : void 0,
854
+ page: e.page,
855
+ scopeSelector: typeof e.scopeSelector == "string" ? e.scopeSelector : void 0,
856
+ submitPrompt: e.submitPrompt,
857
+ promptText: typeof e.promptText == "string" ? e.promptText : void 0,
858
+ promptTools: U(e.promptTools),
859
+ attachments: z(e.attachments),
860
+ setupNeeded: V(e.setupNeeded),
861
+ rationale: typeof e.rationale == "string" ? e.rationale : void 0
862
+ };
863
+ }
864
+ function U(e) {
865
+ if (Array.isArray(e))
866
+ return e.filter(d).flatMap((t) => typeof t.id != "string" || typeof t.mention != "string" ? [] : [
867
+ {
868
+ id: t.id,
869
+ mention: t.mention,
870
+ label: typeof t.label == "string" ? t.label : void 0,
871
+ reason: typeof t.reason == "string" ? t.reason : void 0
872
+ }
873
+ ]);
874
+ }
875
+ function z(e) {
876
+ if (Array.isArray(e))
877
+ return e.filter(d).flatMap((t) => typeof t.type != "string" ? [] : [
878
+ {
879
+ type: t.type,
880
+ name: typeof t.name == "string" ? t.name : void 0,
881
+ label: typeof t.label == "string" ? t.label : void 0,
882
+ reason: typeof t.reason == "string" ? t.reason : void 0
883
+ }
884
+ ]);
885
+ }
886
+ function V(e) {
887
+ if (Array.isArray(e))
888
+ return e.filter((t) => typeof t == "string");
889
+ }
890
+ function j(e, t) {
891
+ const n = g(e);
892
+ return t.entries.length === 0 ? n : `${H(t)}
893
+ ${n}`;
894
+ }
895
+ function d(e) {
896
+ return typeof e == "object" && e !== null && !Array.isArray(e);
897
+ }
898
+ function Se(e) {
899
+ return d(e) && typeof e.appId == "string" && Array.isArray(e.entries) && e.entries.every(
900
+ (t) => d(t) && typeof t.type == "string" && "value" in t
901
+ );
902
+ }
903
+ function W(e) {
904
+ if (e?.aborted)
905
+ throw new DOMException("Aborted", "AbortError");
906
+ }
907
+ export {
908
+ I as AppFilmGenerationError,
909
+ we as generateAppFilmScript,
910
+ y as parseAppFilmSetup,
911
+ ve as prepareAppFilmScript,
912
+ Te as repairAppFilmScript,
913
+ H as serializeAppFilmSetup,
914
+ g as stripAppFilmSetup,
915
+ b as validateAppFilmScript
916
+ };