wizards 0.2.20 → 0.2.21

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 (62) hide show
  1. package/apps/runtime/dist/authoring/guide.js +32 -4
  2. package/apps/runtime/dist/engine/prepare.js +37 -2
  3. package/apps/runtime/dist/engine/requirements.js +22 -1
  4. package/apps/runtime/dist/engine/steps.js +8 -1
  5. package/apps/runtime/dist/engine/template.js +8 -0
  6. package/apps/runtime/dist/files/storage.js +8 -1
  7. package/apps/runtime/dist/film/project.js +195 -0
  8. package/apps/runtime/dist/film/skills.js +91 -0
  9. package/apps/runtime/dist/film/sounds.js +122 -0
  10. package/apps/runtime/dist/film/step.js +286 -0
  11. package/apps/runtime/dist/film/tools.js +99 -0
  12. package/apps/runtime/dist/media/transcribe.js +150 -0
  13. package/apps/runtime/dist/models.js +24 -0
  14. package/apps/runtime/dist/render/downloads.js +1 -1
  15. package/apps/runtime/dist/widgets/render.js +20 -3
  16. package/apps/runtime/dist/widgets/runtime.js +2 -1
  17. package/apps/runtime/dist/widgets/step.js +16 -0
  18. package/apps/web/dist/assets/{Account-0f8W571o.js → Account-BxpaLgg6.js} +1 -1
  19. package/apps/web/dist/assets/{ChangelogDialog-BBmJedTW.js → ChangelogDialog-Ds9XgxMP.js} +1 -1
  20. package/apps/web/dist/assets/{ChatPanel-Bi3tnxOD.js → ChatPanel-CGL-SaYv.js} +1 -1
  21. package/apps/web/dist/assets/{CreditsDialog-C_lMgenE.js → CreditsDialog-DZPOim-g.js} +1 -1
  22. package/apps/web/dist/assets/{EditorPage-2-DypFBB.js → EditorPage-DJDTvELx.js} +1 -1
  23. package/apps/web/dist/assets/{FlowPreview-DBroqouz.js → FlowPreview-DObLaWK0.js} +1 -1
  24. package/apps/web/dist/assets/{Harness-Dkw5Zldw.js → Harness-BEIJfBYu.js} +1 -1
  25. package/apps/web/dist/assets/{HomePage-D9f7DKEw.js → HomePage-BxTQiJog.js} +1 -1
  26. package/apps/web/dist/assets/{ImportWizard-Br-Ys-Np.js → ImportWizard-fp4Q1iZ6.js} +1 -1
  27. package/apps/web/dist/assets/{LocalRuntime-CbA3kdFH.js → LocalRuntime-C1izy1g5.js} +1 -1
  28. package/apps/web/dist/assets/NewWizardPage-BDOoKp6y.js +2 -0
  29. package/apps/web/dist/assets/{ProjectPage-CWn7fwSr.js → ProjectPage-Cs86dGVd.js} +1 -1
  30. package/apps/web/dist/assets/{PublicRunner-DFUM0aP5.js → PublicRunner-B53p-hWG.js} +1 -1
  31. package/apps/web/dist/assets/{RunnerView-BAmePlD3.js → RunnerView-CrgDUD9U.js} +2 -2
  32. package/apps/web/dist/assets/SettingsPage-07vGl-P6.js +1 -0
  33. package/apps/web/dist/assets/{SetupPage-GWL_IhbR.js → SetupPage-Ba0WirOM.js} +1 -1
  34. package/apps/web/dist/assets/{SharePage-DZzIMn0m.js → SharePage-J7eD3paN.js} +1 -1
  35. package/apps/web/dist/assets/{api-Byy4NRvQ.js → api-BkWIPEWf.js} +1 -1
  36. package/apps/web/dist/assets/changelog-D4wD3iMl.js +1 -0
  37. package/apps/web/dist/assets/definition-BznNdlhf.js +55 -0
  38. package/apps/web/dist/assets/{esm-WstF63Ly.js → esm-Bk4BRENl.js} +1 -1
  39. package/apps/web/dist/assets/image-CC_2mJd6.js +1 -0
  40. package/apps/web/dist/assets/{index-udMtduDM.js → index-CJuJLvrl.js} +3 -3
  41. package/apps/web/dist/assets/meta-DMOYx_c4.js +1 -0
  42. package/apps/web/dist/assets/{settings-menu-GUFlmH3n.js → settings-menu-BI5cH97k.js} +1 -1
  43. package/apps/web/dist/assets/ui-CiYJabAi.js +1 -0
  44. package/apps/web/dist/assets/volume-2-DE67_rue.js +1 -0
  45. package/apps/web/dist/index.html +3 -3
  46. package/apps/web/dist/mcp/flow.html +53 -53
  47. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +146 -0
  48. package/node_modules/@engenty-wizards/shared/dist/definition.js +101 -0
  49. package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +3 -0
  50. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +6 -1
  51. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +12 -0
  52. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +30 -0
  53. package/node_modules/@engenty-wizards/shared/dist/run.js +18 -0
  54. package/package.json +1 -1
  55. package/apps/web/dist/assets/NewWizardPage-Cvt9fKwq.js +0 -2
  56. package/apps/web/dist/assets/SettingsPage-CLLlnzeS.js +0 -1
  57. package/apps/web/dist/assets/changelog-DMAoeotb.js +0 -1
  58. package/apps/web/dist/assets/definition-Dp0DR2D6.js +0 -55
  59. package/apps/web/dist/assets/image-BShbErBm.js +0 -1
  60. package/apps/web/dist/assets/meta-CUWuppZ0.js +0 -1
  61. package/apps/web/dist/assets/ui-CwU0VR_B.js +0 -1
  62. package/apps/web/dist/assets/volume-2-Bp2tyaKE.js +0 -1
@@ -117,6 +117,7 @@ export declare const fieldSchema: z.ZodObject<{
117
117
  max: z.ZodOptional<z.ZodNumber>;
118
118
  camera: z.ZodOptional<z.ZodBoolean>;
119
119
  video: z.ZodOptional<z.ZodBoolean>;
120
+ listen: z.ZodOptional<z.ZodBoolean>;
120
121
  scan: z.ZodOptional<z.ZodBoolean>;
121
122
  connection: z.ZodOptional<z.ZodString>;
122
123
  list: z.ZodOptional<z.ZodString>;
@@ -201,6 +202,7 @@ export declare const pageStepSchema: z.ZodObject<{
201
202
  max: z.ZodOptional<z.ZodNumber>;
202
203
  camera: z.ZodOptional<z.ZodBoolean>;
203
204
  video: z.ZodOptional<z.ZodBoolean>;
205
+ listen: z.ZodOptional<z.ZodBoolean>;
204
206
  scan: z.ZodOptional<z.ZodBoolean>;
205
207
  connection: z.ZodOptional<z.ZodString>;
206
208
  list: z.ZodOptional<z.ZodString>;
@@ -385,6 +387,60 @@ export declare const widgetStepSchema: z.ZodObject<{
385
387
  goto: z.ZodString;
386
388
  }, z.core.$strip>>>;
387
389
  }, z.core.$strip>;
390
+ /** Formats a film step makes; the composition is drawn for this frame. */
391
+ export declare const FILM_FORMATS: readonly ["16:9", "9:16", "1:1"];
392
+ export type FilmFormat = (typeof FILM_FORMATS)[number];
393
+ export declare const FILM_SIZES: Record<FilmFormat, {
394
+ width: number;
395
+ height: number;
396
+ }>;
397
+ /**
398
+ * A film the AI client installed on this machine makes in a folder of its own: it writes the
399
+ * composition as code (HTML, CSS, JS) with the skills it is given, looks at its frames and fixes
400
+ * them; the runtime renders the MP4. It runs on the person's subscription, never on credits.
401
+ */
402
+ export declare const filmStepSchema: z.ZodObject<{
403
+ type: z.ZodLiteral<"film">;
404
+ brief: z.ZodString;
405
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
406
+ kit: z.ZodOptional<z.ZodString>;
407
+ inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
408
+ format: z.ZodDefault<z.ZodEnum<{
409
+ "1:1": "1:1";
410
+ "16:9": "16:9";
411
+ "9:16": "9:16";
412
+ }>>;
413
+ seconds: z.ZodOptional<z.ZodNumber>;
414
+ model: z.ZodOptional<z.ZodEnum<{
415
+ classifier: "classifier";
416
+ standard: "standard";
417
+ high: "high";
418
+ highest: "highest";
419
+ }>>;
420
+ effort: z.ZodOptional<z.ZodEnum<{
421
+ medium: "medium";
422
+ high: "high";
423
+ low: "low";
424
+ }>>;
425
+ working: z.ZodOptional<z.ZodString>;
426
+ id: z.ZodString;
427
+ title: z.ZodString;
428
+ description: z.ZodOptional<z.ZodString>;
429
+ next: z.ZodOptional<z.ZodArray<z.ZodObject<{
430
+ when: z.ZodObject<{
431
+ field: z.ZodString;
432
+ op: z.ZodEnum<{
433
+ in: "in";
434
+ equals: "equals";
435
+ notEquals: "notEquals";
436
+ notEmpty: "notEmpty";
437
+ empty: "empty";
438
+ }>;
439
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
440
+ }, z.core.$strip>;
441
+ goto: z.ZodString;
442
+ }, z.core.$strip>>>;
443
+ }, z.core.$strip>;
388
444
  export declare const reviewStepSchema: z.ZodObject<{
389
445
  type: z.ZodLiteral<"review">;
390
446
  show: z.ZodArray<z.ZodString>;
@@ -514,6 +570,7 @@ export declare const stepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
514
570
  max: z.ZodOptional<z.ZodNumber>;
515
571
  camera: z.ZodOptional<z.ZodBoolean>;
516
572
  video: z.ZodOptional<z.ZodBoolean>;
573
+ listen: z.ZodOptional<z.ZodBoolean>;
517
574
  scan: z.ZodOptional<z.ZodBoolean>;
518
575
  connection: z.ZodOptional<z.ZodString>;
519
576
  list: z.ZodOptional<z.ZodString>;
@@ -694,6 +751,47 @@ export declare const stepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
694
751
  }, z.core.$strip>;
695
752
  goto: z.ZodString;
696
753
  }, z.core.$strip>>>;
754
+ }, z.core.$strip>, z.ZodObject<{
755
+ type: z.ZodLiteral<"film">;
756
+ brief: z.ZodString;
757
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
758
+ kit: z.ZodOptional<z.ZodString>;
759
+ inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
760
+ format: z.ZodDefault<z.ZodEnum<{
761
+ "1:1": "1:1";
762
+ "16:9": "16:9";
763
+ "9:16": "9:16";
764
+ }>>;
765
+ seconds: z.ZodOptional<z.ZodNumber>;
766
+ model: z.ZodOptional<z.ZodEnum<{
767
+ classifier: "classifier";
768
+ standard: "standard";
769
+ high: "high";
770
+ highest: "highest";
771
+ }>>;
772
+ effort: z.ZodOptional<z.ZodEnum<{
773
+ medium: "medium";
774
+ high: "high";
775
+ low: "low";
776
+ }>>;
777
+ working: z.ZodOptional<z.ZodString>;
778
+ id: z.ZodString;
779
+ title: z.ZodString;
780
+ description: z.ZodOptional<z.ZodString>;
781
+ next: z.ZodOptional<z.ZodArray<z.ZodObject<{
782
+ when: z.ZodObject<{
783
+ field: z.ZodString;
784
+ op: z.ZodEnum<{
785
+ in: "in";
786
+ equals: "equals";
787
+ notEquals: "notEquals";
788
+ notEmpty: "notEmpty";
789
+ empty: "empty";
790
+ }>;
791
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
792
+ }, z.core.$strip>;
793
+ goto: z.ZodString;
794
+ }, z.core.$strip>>>;
697
795
  }, z.core.$strip>, z.ZodObject<{
698
796
  type: z.ZodLiteral<"review">;
699
797
  show: z.ZodArray<z.ZodString>;
@@ -766,6 +864,7 @@ export type AgentStep = z.infer<typeof agentStepSchema>;
766
864
  export declare function isDecisionStep(step: AgentStep): boolean;
767
865
  export type GenerateStep = z.infer<typeof generateStepSchema>;
768
866
  export type WidgetStep = z.infer<typeof widgetStepSchema>;
867
+ export type FilmStep = z.infer<typeof filmStepSchema>;
769
868
  export type ReviewStep = z.infer<typeof reviewStepSchema>;
770
869
  export type ResultStep = z.infer<typeof resultStepSchema>;
771
870
  export type StepType = Step["type"];
@@ -1129,6 +1228,7 @@ export declare const wizardSchema: z.ZodObject<{
1129
1228
  max: z.ZodOptional<z.ZodNumber>;
1130
1229
  camera: z.ZodOptional<z.ZodBoolean>;
1131
1230
  video: z.ZodOptional<z.ZodBoolean>;
1231
+ listen: z.ZodOptional<z.ZodBoolean>;
1132
1232
  scan: z.ZodOptional<z.ZodBoolean>;
1133
1233
  connection: z.ZodOptional<z.ZodString>;
1134
1234
  list: z.ZodOptional<z.ZodString>;
@@ -1309,6 +1409,47 @@ export declare const wizardSchema: z.ZodObject<{
1309
1409
  }, z.core.$strip>;
1310
1410
  goto: z.ZodString;
1311
1411
  }, z.core.$strip>>>;
1412
+ }, z.core.$strip>, z.ZodObject<{
1413
+ type: z.ZodLiteral<"film">;
1414
+ brief: z.ZodString;
1415
+ skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
1416
+ kit: z.ZodOptional<z.ZodString>;
1417
+ inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
1418
+ format: z.ZodDefault<z.ZodEnum<{
1419
+ "1:1": "1:1";
1420
+ "16:9": "16:9";
1421
+ "9:16": "9:16";
1422
+ }>>;
1423
+ seconds: z.ZodOptional<z.ZodNumber>;
1424
+ model: z.ZodOptional<z.ZodEnum<{
1425
+ classifier: "classifier";
1426
+ standard: "standard";
1427
+ high: "high";
1428
+ highest: "highest";
1429
+ }>>;
1430
+ effort: z.ZodOptional<z.ZodEnum<{
1431
+ medium: "medium";
1432
+ high: "high";
1433
+ low: "low";
1434
+ }>>;
1435
+ working: z.ZodOptional<z.ZodString>;
1436
+ id: z.ZodString;
1437
+ title: z.ZodString;
1438
+ description: z.ZodOptional<z.ZodString>;
1439
+ next: z.ZodOptional<z.ZodArray<z.ZodObject<{
1440
+ when: z.ZodObject<{
1441
+ field: z.ZodString;
1442
+ op: z.ZodEnum<{
1443
+ in: "in";
1444
+ equals: "equals";
1445
+ notEquals: "notEquals";
1446
+ notEmpty: "notEmpty";
1447
+ empty: "empty";
1448
+ }>;
1449
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
1450
+ }, z.core.$strip>;
1451
+ goto: z.ZodString;
1452
+ }, z.core.$strip>>>;
1312
1453
  }, z.core.$strip>, z.ZodObject<{
1313
1454
  type: z.ZodLiteral<"review">;
1314
1455
  show: z.ZodArray<z.ZodString>;
@@ -1373,6 +1514,11 @@ export declare const wizardSchema: z.ZodObject<{
1373
1514
  }, z.core.$strip>;
1374
1515
  export type WizardDefinition = z.infer<typeof wizardSchema>;
1375
1516
  export declare const INTERACTIVE: ReadonlySet<StepType>;
1517
+ /**
1518
+ * A wizard with a film step runs only where an AI client is installed and signed in, on the
1519
+ * person's own subscription: one film takes a client many minutes and many tokens.
1520
+ */
1521
+ export declare function needsInstalledClient(def: WizardDefinition): boolean;
1376
1522
  export declare function isInteractive(step: Step): boolean;
1377
1523
  /** Which formats each producing step can be downloaded in. */
1378
1524
  export declare function formatsFor(step: Step): Format[];
@@ -141,6 +141,11 @@ export const fieldSchema = z.object({
141
141
  camera: z.boolean().optional(),
142
142
  /** file: the camera also records short video clips. */
143
143
  video: z.boolean().optional(),
144
+ /**
145
+ * file: a recording (video or audio) is listened to before the next step runs — what is said,
146
+ * piece by piece between pauses, with exact times. Read as {{field.speech}}.
147
+ */
148
+ listen: z.boolean().optional(),
144
149
  /** text: also fill it by scanning a QR code or barcode with the camera. */
145
150
  scan: z.boolean().optional(),
146
151
  /** connection: id of the wizard connection the person connects here. */
@@ -274,6 +279,46 @@ export const widgetStepSchema = z.object({
274
279
  video: z.boolean().optional(),
275
280
  working: z.string().optional(),
276
281
  });
282
+ /** Formats a film step makes; the composition is drawn for this frame. */
283
+ export const FILM_FORMATS = ["16:9", "9:16", "1:1"];
284
+ export const FILM_SIZES = {
285
+ "16:9": { width: 1920, height: 1080 },
286
+ "9:16": { width: 1080, height: 1920 },
287
+ "1:1": { width: 1080, height: 1080 },
288
+ };
289
+ /**
290
+ * A film the AI client installed on this machine makes in a folder of its own: it writes the
291
+ * composition as code (HTML, CSS, JS) with the skills it is given, looks at its frames and fixes
292
+ * them; the runtime renders the MP4. It runs on the person's subscription, never on credits.
293
+ */
294
+ export const filmStepSchema = z.object({
295
+ ...stepBase,
296
+ type: z.literal("film"),
297
+ /** What the film is: story, look, what to use. A template. */
298
+ brief: z.string().min(1),
299
+ /**
300
+ * Skill packages the client reads: platform packages ("hyperframes") or a folder of the
301
+ * workspace with a SKILL.md ("skills/<name>").
302
+ */
303
+ skills: z.array(z.string().min(1)).max(12).default(["hyperframes"]),
304
+ /**
305
+ * A style kit in the workspace — a showreel made once with its rules, helpers and stills, as
306
+ * a .zip — unpacked as `showcase/`: the bar every film of this wizard is made to.
307
+ */
308
+ kit: z.string().optional(),
309
+ /**
310
+ * What the film is made from: name → a field id or "steps.<id>". Files (uploads, voice lines,
311
+ * pictures) are copied into `input/<name>/`, text is written to `input/<name>.md`.
312
+ */
313
+ inputs: z.record(z.string(), z.string()).default({}),
314
+ format: z.enum(FILM_FORMATS).default("16:9"),
315
+ /** About how long the film runs, in seconds. */
316
+ seconds: z.number().int().min(3).max(600).optional(),
317
+ /** The kind of model; default `standard` — the kit carries the craft. */
318
+ model: z.enum(TEXT_CLASSES).optional(),
319
+ effort: z.enum(EFFORTS).optional(),
320
+ working: z.string().optional(),
321
+ });
277
322
  export const reviewStepSchema = z.object({
278
323
  ...stepBase,
279
324
  type: z.literal("review"),
@@ -298,6 +343,7 @@ export const stepSchema = z.discriminatedUnion("type", [
298
343
  agentStepSchema,
299
344
  generateStepSchema,
300
345
  widgetStepSchema,
346
+ filmStepSchema,
301
347
  reviewStepSchema,
302
348
  resultStepSchema,
303
349
  ]);
@@ -366,6 +412,13 @@ export const wizardSchema = z.object({
366
412
  steps: z.array(stepSchema).min(1),
367
413
  });
368
414
  export const INTERACTIVE = new Set(["page", "review", "result"]);
415
+ /**
416
+ * A wizard with a film step runs only where an AI client is installed and signed in, on the
417
+ * person's own subscription: one film takes a client many minutes and many tokens.
418
+ */
419
+ export function needsInstalledClient(def) {
420
+ return def.steps.some((s) => s.type === "film");
421
+ }
369
422
  export function isInteractive(step) {
370
423
  return INTERACTIVE.has(step.type);
371
424
  }
@@ -385,6 +438,9 @@ export function formatsFor(step) {
385
438
  return ["html", "pdf", "png"];
386
439
  }
387
440
  }
441
+ if (step.type === "film") {
442
+ return ["mp4"];
443
+ }
388
444
  if (step.type === "widget") {
389
445
  return step.video ? ["mp4", "png"] : ["html", "png", "pdf", "mp4", "json"];
390
446
  }
@@ -524,6 +580,12 @@ export function validateWizard(def, files) {
524
580
  message: `Field "${field.id}": "scan" fills a text field; kind is "${field.kind}".`,
525
581
  });
526
582
  }
583
+ if (field.listen && field.kind !== "file") {
584
+ issues.push({
585
+ stepId: step.id,
586
+ message: `Field "${field.id}": "listen" belongs to a file field; kind is "${field.kind}".`,
587
+ });
588
+ }
527
589
  if (field.video && field.kind !== "file") {
528
590
  issues.push({
529
591
  stepId: step.id,
@@ -601,6 +663,7 @@ export function validateWizard(def, files) {
601
663
  break;
602
664
  case "generate":
603
665
  checkTemplate(step, step.prompt);
666
+ checkTemplate(step, step.options?.style ?? "");
604
667
  if (step.referenceImage &&
605
668
  !seenFields.has(step.referenceImage) &&
606
669
  !seenSteps.has(step.referenceImage)) {
@@ -648,6 +711,44 @@ export function validateWizard(def, files) {
648
711
  });
649
712
  }
650
713
  break;
714
+ case "film":
715
+ checkTemplate(step, step.brief);
716
+ for (const [name, ref] of Object.entries(step.inputs)) {
717
+ if (!/^[a-z][a-z0-9-]{0,40}$/.test(name)) {
718
+ issues.push({
719
+ stepId: step.id,
720
+ message: `Film input "${name}" is not a folder name (lowercase letters, digits, -).`,
721
+ });
722
+ }
723
+ const r = dataRef(ref);
724
+ if (r.startsWith("steps.")) {
725
+ checkTemplate(step, `{{${r}}}`);
726
+ }
727
+ else if (!seenFields.has(r)) {
728
+ issues.push({
729
+ stepId: step.id,
730
+ message: `Film input "${name}": "${ref}" is not an earlier field or "steps.<id>".`,
731
+ });
732
+ }
733
+ }
734
+ if (step.kit && !step.kit.endsWith(".zip")) {
735
+ issues.push({ stepId: step.id, message: `Film kit "${step.kit}" is a .zip.` });
736
+ }
737
+ else if (files && step.kit && !files.includes(step.kit)) {
738
+ issues.push({
739
+ stepId: step.id,
740
+ message: `Film kit "${step.kit}" is not in the workspace.`,
741
+ });
742
+ }
743
+ for (const skill of step.skills) {
744
+ if (skill.startsWith("skills/") && files && !files.includes(`${skill}/SKILL.md`)) {
745
+ issues.push({
746
+ stepId: step.id,
747
+ message: `Skill "${skill}" has no SKILL.md in the workspace.`,
748
+ });
749
+ }
750
+ }
751
+ break;
651
752
  case "review":
652
753
  for (const ref of step.show) {
653
754
  const list = listRef(ref);
@@ -53,6 +53,9 @@ function resultKind(definition, from) {
53
53
  if (step?.type === "widget") {
54
54
  return step.video ? "video" : "dashboard";
55
55
  }
56
+ if (step?.type === "film") {
57
+ return "video";
58
+ }
56
59
  return step?.type === "agent" && step.output.format === "json" ? "table" : "text";
57
60
  }
58
61
  export function resultsOf(definition) {
@@ -174,6 +174,11 @@ export declare const CAPABILITIES: {
174
174
  de: string;
175
175
  en: string;
176
176
  };
177
+ /** A film the installed client makes: only on a computer with Claude Code, on its subscription. */
178
+ film: {
179
+ de: string;
180
+ en: string;
181
+ };
177
182
  };
178
183
  export type Capability = keyof typeof CAPABILITIES;
179
184
  export declare const COST_TIERS: {
@@ -194,7 +199,7 @@ export type CostTier = keyof typeof COST_TIERS;
194
199
  export declare const ITEM_FORMAT_IDS: ("text" | "image" | "audio" | "video" | "document" | "dashboard" | "table")[];
195
200
  export declare const INDUSTRY_IDS: ("any" | "trades" | "gastronomy" | "hospitality" | "realEstate" | "retail" | "health" | "professional" | "agency" | "events" | "publicSector")[];
196
201
  export declare const USE_CASE_IDS: ("marketing" | "sales" | "accounting" | "service" | "research" | "hr" | "operations" | "website" | "visuals" | "inquiries" | "advice")[];
197
- export declare const CAPABILITY_IDS: ("text" | "code" | "image" | "browser" | "video" | "speech" | "web" | "documents" | "listening" | "connectors")[];
202
+ export declare const CAPABILITY_IDS: ("text" | "code" | "image" | "browser" | "video" | "speech" | "film" | "web" | "documents" | "listening" | "connectors")[];
198
203
  /** The formats a run hands over, read from what the result step offers. */
199
204
  export declare function formatsOf(def: WizardDefinition): ItemFormat[];
200
205
  /** The capabilities a definition needs, read from its steps. */
@@ -52,6 +52,11 @@ export const CAPABILITIES = {
52
52
  listening: { de: "Sprachnotizen verstehen", en: "Understands voice notes" },
53
53
  code: { de: "Code ausführen", en: "Runs code" },
54
54
  connectors: { de: "Verbundene Konten & Systeme", en: "Connected accounts & systems" },
55
+ /** A film the installed client makes: only on a computer with Claude Code, on its subscription. */
56
+ film: {
57
+ de: "Filme mit Claude Code (auf deinem Abo)",
58
+ en: "Films with Claude Code (on your subscription)",
59
+ },
55
60
  };
56
61
  export const COST_TIERS = {
57
62
  low: { de: "günstig", en: "low cost" },
@@ -150,6 +155,9 @@ export function capabilitiesOf(def) {
150
155
  found.add("text");
151
156
  }
152
157
  }
158
+ else if (step.type === "film") {
159
+ found.add("film");
160
+ }
153
161
  }
154
162
  if (def.connections?.length) {
155
163
  found.add("connectors");
@@ -195,6 +203,10 @@ export function effortOf(def) {
195
203
  else if (step.type === "widget" && step.video) {
196
204
  seconds += 60;
197
205
  }
206
+ else if (step.type === "film") {
207
+ // A client writing a film from a style kit: ten minutes to half an hour (2026-10 tests).
208
+ seconds += 25 * 60;
209
+ }
198
210
  }
199
211
  return { fields, required, reviews, minutes: Math.max(1, Math.round(seconds / 60)) };
200
212
  }
@@ -34,6 +34,12 @@ export interface RunState {
34
34
  notes: Record<string, string>;
35
35
  /** Steps that make several results: the entries (from 0) to make again; the others stay. */
36
36
  redo?: Record<string, number[]>;
37
+ /** File fields with `listen`: what is said in the recording, piece by piece with its times. */
38
+ heard?: Record<string, {
39
+ start: number;
40
+ end: number;
41
+ text: string;
42
+ }[]>;
37
43
  }
38
44
  interface AskBase {
39
45
  id: string;
@@ -249,6 +255,30 @@ export declare const RUN_NOTES: {
249
255
  readonly de: "Legt {count} Dateien ab";
250
256
  readonly en: "Filing {count} files";
251
257
  };
258
+ readonly filmSetup: {
259
+ readonly de: "Richtet den Arbeitsordner für den Film ein";
260
+ readonly en: "Setting up the folder for the film";
261
+ };
262
+ readonly filmClient: {
263
+ readonly de: "{client} arbeitet am Film – das dauert meist 10–40 Minuten.";
264
+ readonly en: "{client} is working on the film – this usually takes 10–40 minutes.";
265
+ };
266
+ readonly filmTask: {
267
+ readonly de: "Am Film: {task}";
268
+ readonly en: "On the film: {task}";
269
+ };
270
+ readonly filmLooks: {
271
+ readonly de: "Sieht sich Bilder des Films an";
272
+ readonly en: "Looking at frames of the film";
273
+ };
274
+ readonly filmFix: {
275
+ readonly de: "Der Film ließ sich nicht rendern – Claude Code bessert nach";
276
+ readonly en: "The film did not render – Claude Code is fixing it";
277
+ };
278
+ readonly filmResume: {
279
+ readonly de: "Macht dort weiter, wo der Film stehen geblieben ist";
280
+ readonly en: "Picking the film up where it stopped";
281
+ };
252
282
  };
253
283
  export type RunNoteCode = keyof typeof RUN_NOTES;
254
284
  /** A line of `RUN_NOTES` with what goes into its gaps. */
@@ -66,6 +66,24 @@ export const RUN_NOTES = {
66
66
  },
67
67
  remembers: { de: "Merkt sich {title}", en: "Remembering {title}" },
68
68
  files: { de: "Legt {count} Dateien ab", en: "Filing {count} files" },
69
+ filmSetup: {
70
+ de: "Richtet den Arbeitsordner für den Film ein",
71
+ en: "Setting up the folder for the film",
72
+ },
73
+ filmClient: {
74
+ de: "{client} arbeitet am Film – das dauert meist 10–40 Minuten.",
75
+ en: "{client} is working on the film – this usually takes 10–40 minutes.",
76
+ },
77
+ filmTask: { de: "Am Film: {task}", en: "On the film: {task}" },
78
+ filmLooks: { de: "Sieht sich Bilder des Films an", en: "Looking at frames of the film" },
79
+ filmFix: {
80
+ de: "Der Film ließ sich nicht rendern – Claude Code bessert nach",
81
+ en: "The film did not render – Claude Code is fixing it",
82
+ },
83
+ filmResume: {
84
+ de: "Macht dort weiter, wo der Film stehen geblieben ist",
85
+ en: "Picking the film up where it stopped",
86
+ },
69
87
  };
70
88
  /** A note in a language, its gaps filled. */
71
89
  export function noteText(note, lang) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wizards",
3
- "version": "0.2.20",
3
+ "version": "0.2.21",
4
4
  "description": "Make a wish. Get your wizard. It guides you step by step. Let AI do the work. Runs on your machine, on the AI subscription you already have.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "homepage": "https://engenty.ai",
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/FlowPreview-DBroqouz.js","assets/jsx-runtime-D3jfb0Ew.js","assets/ui-CwU0VR_B.js","assets/esm-WstF63Ly.js","assets/index-udMtduDM.js","assets/api-Byy4NRvQ.js","assets/preload-helper-CNEI7N0N.js","assets/createLucideIcon-q3MZMmnf.js","assets/engenty-Cm8yZLON.js","assets/index-Bwyehu0k.css"])))=>i.map(i=>d[i]);
2
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{A as r,F as i,I as a,K as o,M as s,N as c,O as l,d as u,g as d,j as f,n as p,nt as m,w as h}from"./api-Byy4NRvQ.js";import{t as g}from"./preload-helper-CNEI7N0N.js";import{t as _}from"./createLucideIcon-q3MZMmnf.js";import{t as v}from"./arrow-right-6FyN3e7D.js";import{o as y,s as ee,t as te}from"./meta-CUWuppZ0.js";import{t as ne}from"./check-CUpby_J9.js";import{t as b}from"./chevron-down-DymW-2BP.js";import{n as x,r as S,t as C}from"./volume-2-Bp2tyaKE.js";import{n as re,r as w}from"./upload-DNRENWzQ.js";import{n as ie,t as ae}from"./wand-sparkles-Clj3VRB5.js";import{t as T}from"./image-BShbErBm.js";import{n as oe,t as E}from"./video-9fDPRPCv.js";import{t as se}from"./pen-line-NK46C_nG.js";import{n as D,t as ce}from"./table-2-BdDuBcF2.js";import{l as le,u as ue}from"./engenty-Cm8yZLON.js";import{b as O,d as k,h as A,i as de,m as fe,n as pe,r as j,t as M,v as N}from"./ui-CwU0VR_B.js";import{H as me,I as he,K as P,N as ge,O as _e,P as ve,R as F,U as I,W as ye,j as L,w as be}from"./index-udMtduDM.js";import{t as xe}from"./ImportWizard-Br-Ys-Np.js";var Se=class extends c{constructor(e,t){super(e,t)}bindMethods(){super.bindMethods(),this.fetchNextPage=this.fetchNextPage.bind(this),this.fetchPreviousPage=this.fetchPreviousPage.bind(this)}setOptions(e){e._type=`infinite`,super.setOptions(e)}getOptimisticResult(e){return e._type=`infinite`,super.getOptimisticResult(e)}fetchNextPage(e){return this.fetch({...e,meta:{fetchMore:{direction:`forward`}}})}fetchPreviousPage(e){return this.fetch({...e,meta:{fetchMore:{direction:`backward`}}})}createResult(e,t){let{state:n}=e,r=super.createResult(e,t),{isFetching:o,isRefetching:s,isError:c,isRefetchError:l}=r,u=n.fetchMeta?.fetchMore?.direction,d=c&&u===`forward`,f=o&&u===`forward`,p=c&&u===`backward`,m=o&&u===`backward`;return{...r,fetchNextPage:this.fetchNextPage,fetchPreviousPage:this.fetchPreviousPage,hasNextPage:i(t,n.data),hasPreviousPage:a(t,n.data),isFetchNextPageError:d,isFetchingNextPage:f,isFetchPreviousPageError:p,isFetchingPreviousPage:m,isRefetchError:l&&!d&&!p,isRefetching:s&&!f&&!m}}};function Ce(e,t){return s(e,Se,t)}var R={name:`audio-lines`,size:24,node:[[`path`,{d:`M2 10v3`,key:`1fnikh`}],[`path`,{d:`M6 6v11`,key:`11sgs0`}],[`path`,{d:`M10 3v18`,key:`yhl04a`}],[`path`,{d:`M14 8v7`,key:`3a1oy3`}],[`path`,{d:`M18 5v13`,key:`123xd1`}],[`path`,{d:`M22 10v3`,key:`154ddg`}]]};R.node;var we=_(R),z={name:`chart-column`,size:24,node:[[`path`,{d:`M3 3v16a2 2 0 0 0 2 2h16`,key:`c24i48`}],[`path`,{d:`M18 17V9`,key:`2bz60n`}],[`path`,{d:`M13 17V5`,key:`1frdt8`}],[`path`,{d:`M8 17v-3`,key:`17ska0`}]],aliases:[`bar-chart-3`]};z.node;var B=_(z),Te={name:`circle-dollar-sign`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8`,key:`1h4pet`}],[`path`,{d:`M12 18V6`,key:`zqpxq5`}]]};Te.node;var Ee=_(Te),De={name:`circle-euro`,size:24,node:[[`path`,{d:`M15 9.4a4 4 0 1 0 0 5.2`,key:`1makmb`}],[`path`,{d:`M7 12h5`,key:`gblrwe`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]};De.node;var Oe=_(De),ke={name:`mouse-pointer-click`,size:24,node:[[`path`,{d:`M14 4.1 12 6`,key:`ita8i4`}],[`path`,{d:`m5.1 8-2.9-.8`,key:`1go3kf`}],[`path`,{d:`m6 12-1.9 2`,key:`mnht97`}],[`path`,{d:`M7.2 2.2 8 5.1`,key:`1cfko1`}],[`path`,{d:`M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z`,key:`s0h3yz`}]]};ke.node;var Ae=_(ke),je={name:`scan-text`,size:24,node:[[`path`,{d:`M3 7V5a2 2 0 0 1 2-2h2`,key:`aa7l1z`}],[`path`,{d:`M17 3h2a2 2 0 0 1 2 2v2`,key:`4qcy5o`}],[`path`,{d:`M21 17v2a2 2 0 0 1-2 2h-2`,key:`6vwrx8`}],[`path`,{d:`M7 21H5a2 2 0 0 1-2-2v-2`,key:`ioqczr`}],[`path`,{d:`M7 8h8`,key:`1jbsf9`}],[`path`,{d:`M7 12h10`,key:`b7w52i`}],[`path`,{d:`M7 16h6`,key:`1vyc9m`}]]};je.node;var Me=_(je),Ne={name:`terminal`,size:24,node:[[`path`,{d:`M12 19h8`,key:`baeox8`}],[`path`,{d:`m4 17 6-6-6-6`,key:`1yngyt`}]]};Ne.node;var Pe=_(Ne),V=e(t(),1),H={text:{de:`Text`,en:`Text`},document:{de:`Dokument (PDF, Word)`,en:`Document (PDF, Word)`},table:{de:`Tabelle`,en:`Table`},image:{de:`Bild`,en:`Image`},video:{de:`Video`,en:`Video`},audio:{de:`Audio`,en:`Audio`},dashboard:{de:`Dashboard`,en:`Dashboard`}},Fe={any:{de:`Jede Branche`,en:`Any industry`},trades:{de:`Handwerk`,en:`Trades`},gastronomy:{de:`Gastronomie`,en:`Food service`},hospitality:{de:`Hotel & Tourismus`,en:`Hotels & tourism`},realEstate:{de:`Immobilien`,en:`Real estate`},retail:{de:`Handel`,en:`Retail`},health:{de:`Gesundheit`,en:`Health`},professional:{de:`Kanzlei & Beratung`,en:`Professional services`},agency:{de:`Agentur & Marketing`,en:`Agency & marketing`},events:{de:`Veranstaltungen`,en:`Events`},publicSector:{de:`Vereine & Öffentliches`,en:`Associations & public sector`}},Ie={marketing:{de:`Marketing & Social Media`,en:`Marketing & social media`},sales:{de:`Angebote & Verkauf`,en:`Offers & sales`},accounting:{de:`Buchhaltung & Belege`,en:`Accounting & receipts`},service:{de:`Kundenservice`,en:`Customer service`},research:{de:`Recherche & Analyse`,en:`Research & analysis`},hr:{de:`Personal & Bewerbungen`,en:`HR & applications`},operations:{de:`Planung & Abläufe`,en:`Planning & operations`},website:{de:`Helfer für die Website`,en:`Website helpers`},visuals:{de:`Bilder & Video`,en:`Images & video`},inquiries:{de:`Anfragen & Termine`,en:`Inquiries & bookings`},advice:{de:`Beratung & Preise`,en:`Advice & pricing`}},U={text:{de:`Text schreiben`,en:`Writes text`},web:{de:`Websuche`,en:`Web search`},browser:{de:`Browser bedienen`,en:`Drives a browser`},documents:{de:`Dokumente & Fotos lesen`,en:`Reads documents & photos`},image:{de:`Bilder erzeugen`,en:`Makes images`},video:{de:`Videos erzeugen`,en:`Makes video`},speech:{de:`Sprachausgabe`,en:`Speech output`},listening:{de:`Sprachnotizen verstehen`,en:`Understands voice notes`},code:{de:`Code ausführen`,en:`Runs code`},connectors:{de:`Verbundene Konten & Systeme`,en:`Connected accounts & systems`}},Le={low:{de:`günstig`,en:`low cost`},medium:{de:`mittel`,en:`medium cost`},high:{de:`teuer`,en:`high cost`}},W=e=>Object.keys(e);W(H),W(Fe),W(Ie),W(U);var G=e(n(),1),Re=(0,V.lazy)(()=>g(()=>import(`./FlowPreview-DBroqouz.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9]))),ze={useCase:``,industry:``,format:``,capability:``},K=(e,t)=>e[t]?.[N]??t;function Be(e){if(e<1)return 1;let t=10**Math.floor(Math.log10(e));return Math.round(e/t)*t}function Ve(e){return e.credits?O(`market.credits`,{n:Be(e.credits.credits)}):Le[e.costTier][N]}var He={text:ge,document:F,table:ce,image:T,video:E,audio:we,dashboard:B};function q({format:e,className:t}){let n=He[e],r=K(H,e);return(0,G.jsx)(`span`,{title:r,className:`inline-flex`,children:(0,G.jsx)(n,{className:t,"aria-label":r,role:`img`})})}var J=[`low`,`medium`,`high`];function Y({entry:e}){let t=J.indexOf(e.costTier)+1,n=N===`de`?Oe:Ee;return(0,G.jsxs)(`span`,{title:Ve(e),className:`inline-flex items-center gap-1`,children:[(0,G.jsx)(`span`,{"aria-hidden":`true`,className:`inline-flex shrink-0`,children:J.slice(0,t).map((e,t)=>(0,G.jsx)(`span`,{className:A(`rounded-full bg-(--coin-bg,var(--color-card))`,t>0&&`-ml-1.5`),children:(0,G.jsx)(n,{className:`size-4`})},e))}),Le[e.costTier][N]]})}function Ue({entry:e,onOpen:t}){return(0,G.jsxs)(pe,{role:`button`,tabIndex:0,onClick:t,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),t())},className:A(`relative flex min-h-[124px] cursor-pointer flex-col gap-5 p-4 text-left transition sm:min-h-[136px] sm:p-5 hover:shadow-elevated focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus`,(!e.usable||e.missing.length>0)&&`opacity-60`),children:[(0,G.jsx)(`span`,{className:`-top-4 pointer-events-none absolute right-4`,children:(0,G.jsx)(u,{kind:e.avatar,size:68,interactive:!1})}),(0,G.jsxs)(`div`,{className:`min-w-0 pr-20`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5 font-display font-semibold text-[0.9375rem]`,children:[e.title,e.starred?(0,G.jsx)(D,{className:`size-3.5 shrink-0 fill-amber text-amber`,"aria-label":O(`market.starred`)}):null]}),(0,G.jsx)(`div`,{className:`mt-0.5 text-[0.8125rem] text-ink-3 leading-snug`,children:e.pitch})]}),(0,G.jsx)(`div`,{className:`mt-auto flex flex-wrap items-center gap-x-3 gap-y-1.5 text-[0.75rem] text-ink-3`,children:e.usable&&e.missing.length?(0,G.jsx)(j,{tone:`warn`,children:O(`market.missing`,{list:Z(e.missing)})}):e.usable?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1`,children:[(0,G.jsx)(I,{className:`size-3.5`}),` `,O(`market.minutes`,{n:e.effort.minutes})]}),(0,G.jsx)(Y,{entry:e}),e.optional?.length?(0,G.jsx)(j,{title:O(`market.optionalHint`,{list:Z(e.optional)}),children:O(`market.without`,{list:Z(e.optional)})}):null,(0,G.jsx)(`span`,{className:`ml-auto inline-flex items-center gap-1.5`,children:e.formats.map(e=>(0,G.jsx)(q,{format:e,className:`size-4`},e))})]}):(0,G.jsx)(j,{tone:`warn`,children:O(`market.needsUpdate`)})})]})}function X({title:e,children:t}){return(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`div`,{className:`mb-1.5 font-medium text-[0.75rem] text-ink-3 uppercase tracking-[0.06em]`,children:e}),t]})}var Z=e=>e.map(e=>K(U,e)).join(`, `),We={text:se,web:x,browser:Ae,documents:Me,image:T,video:E,speech:C,listening:oe,code:Pe,connectors:ve};function Ge(e){switch(e.type){case`page`:return he;case`agent`:return ee;case`generate`:return e.asset===`image`?T:e.asset===`video`?E:e.asset===`voice`?C:e.asset===`dashboard`?B:F;case`widget`:return e.video?S:ye;case`review`:return ie;case`result`:return y}return ae}function Ke(e){let t=new Set;for(let[n,r]of e.entries())for(let i of r.branches??[]){let r=i.to===`end`?e.length:e.findIndex(e=>e.id===i.to);for(let i=n+1;i<r;i++)t.add(e[i].id)}return t}function qe(e){let t=Ke(e);return e.map(e=>({id:e.id,title:e.title,icon:Ge(e),tone:te[e.type]??`bg-paper-2 text-ink-2`,optional:t.has(e.id),branches:e.branches}))}function Q({title:e,children:t}){return(0,G.jsx)(`span`,{title:e,className:`inline-flex items-center gap-2 border-border border-l px-4 first:border-l-0 first:pl-0`,children:t})}function $({icon:e,children:t,more:n}){return(0,G.jsxs)(`div`,{className:`flex gap-2.5`,children:[(0,G.jsx)(`span`,{className:`mt-0.5 shrink-0`,children:e}),(0,G.jsxs)(`div`,{className:`min-w-0`,children:[(0,G.jsx)(`div`,{className:`text-[0.875rem] text-ink leading-snug`,children:t}),n?(0,G.jsx)(`div`,{className:`text-[0.75rem] text-ink-3 leading-snug`,children:n}):null]})]})}function Je({className:e,children:t}){let n=(0,V.useRef)(null),[r,i]=(0,V.useState)({above:!1,below:!1});(0,V.useEffect)(()=>{let e=n.current;if(!e)return;let t=()=>{let t=e.scrollTop>1,n=e.scrollTop+e.clientHeight<e.scrollHeight-1;i(e=>e.above===t&&e.below===n?e:{above:t,below:n})};t(),e.addEventListener(`scroll`,t,{passive:!0});let r=new ResizeObserver(t);return r.observe(e),e.firstElementChild&&r.observe(e.firstElementChild),()=>{e.removeEventListener(`scroll`,t),r.disconnect()}},[]);let a=`linear-gradient(to bottom, ${r.above?`transparent`:`black`} 0, black 28px, black calc(100% - 44px), ${r.below?`transparent`:`black`} 100%)`;return(0,G.jsx)(`div`,{ref:n,className:e,style:{maskImage:a,WebkitMaskImage:a},children:(0,G.jsx)(`div`,{children:t})})}function Ye({id:e,fallback:t,onClose:n,onUse:r,busy:i}){let a=m(),o=l(),s=f({queryKey:[`marketplace-entry`,e,N],queryFn:()=>p.get(`/api/studio/marketplace/${encodeURIComponent(e)}?lang=${N}`),enabled:!!e,retry:!1}),c=s.data??t,h=P({mutationFn:t=>{let n=`/api/studio/marketplace/${encodeURIComponent(e)}/star`;return t?p.put(n):p.del(n)},onSuccess:()=>Promise.all([a.invalidateQueries({queryKey:[`marketplace`]}),a.invalidateQueries({queryKey:[`marketplace-entry`,e]})])}),g=d()===`dark`,_=le[ue[c?.avatar||`round`]],v=g?`var(--card)`:`color-mix(in oklch, ${_??`var(--ink-4)`} 14%, var(--paper-2))`;return(0,G.jsx)(de,{open:!!e,onClose:n,wide:!0,bare:!0,children:c?(0,G.jsxs)(`div`,{className:`relative flex max-h-[calc(100dvh-48px)] flex-col rounded-2xl bg-card shadow-overlay max-sm:h-dvh max-sm:max-h-none max-sm:rounded-none`,children:[(0,G.jsx)(`button`,{type:`button`,"aria-label":O(`common.close`),onClick:n,className:`sm:-top-3.5 sm:-right-3.5 absolute top-3 right-3 z-20 flex size-9 items-center justify-center rounded-full bg-card text-ink-2 shadow-elevated ring-1 ring-border-soft transition hover:text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus`,children:(0,G.jsx)(L,{className:`size-4`})}),(0,G.jsxs)(`header`,{className:`relative shrink-0 border-border-soft border-b px-5 pt-5 pb-4 text-ink sm:rounded-t-2xl sm:px-7`,style:{background:v,"--coin-bg":v},children:[(0,G.jsx)(`span`,{"aria-hidden":`true`,className:`pointer-events-none absolute inset-0 overflow-hidden sm:rounded-t-2xl`,children:(0,G.jsx)(`span`,{className:A(`-top-28 -right-10 absolute size-80 rounded-full bg-white blur-3xl`,g?`opacity-[0.14]`:`opacity-80`)})}),(0,G.jsx)(`div`,{className:`-bottom-5 absolute right-9 z-10 max-sm:hidden`,children:(0,G.jsx)(u,{kind:c.avatar,size:104})}),(0,G.jsxs)(`div`,{className:`relative sm:pr-36`,children:[(0,G.jsx)(`h2`,{className:`font-display font-semibold text-[1.375rem] leading-tight tracking-tight max-sm:pr-10`,children:c.title}),(0,G.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-2 leading-snug`,children:s.data?.description||c.pitch})]}),c.usable?(0,G.jsxs)(`div`,{className:`-mx-5 sm:-mx-7 relative mt-3.5 flex flex-wrap items-center gap-y-2 border-border-soft border-t px-5 pt-3 font-medium text-[0.875rem] sm:px-7 sm:pr-40`,children:[(0,G.jsxs)(Q,{title:O(`market.duration`),children:[(0,G.jsx)(I,{className:`size-4 text-ink-3`}),O(`market.minutes`,{n:c.effort.minutes})]}),(0,G.jsx)(Q,{title:O(`market.cost`),children:(0,G.jsx)(Y,{entry:c})}),(0,G.jsx)(Q,{title:O(`market.result`),children:c.formats.map(e=>(0,G.jsx)(q,{format:e,className:`size-4`},e))})]}):null]}),c.usable?(0,G.jsxs)(`div`,{className:`grid min-h-0 flex-1 gap-x-7 gap-y-6 px-5 pt-6 max-sm:overflow-y-auto max-sm:pb-4 sm:grid-cols-[230px_minmax(0,1fr)] sm:grid-rows-[minmax(0,1fr)] sm:px-7`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col gap-5 sm:min-h-0 sm:overflow-y-auto`,children:[(0,G.jsx)(X,{title:O(`market.duration`),children:(0,G.jsx)($,{icon:(0,G.jsx)(I,{className:`size-4 text-moss`}),more:O(`market.durationHint`,{n:c.effort.fields}),children:O(`market.minutes`,{n:c.effort.minutes})})}),(0,G.jsx)(X,{title:O(`market.cost`),children:(0,G.jsx)($,{icon:(0,G.jsx)(w,{className:`size-4 text-amber`}),more:c.credits?O(`market.creditsHint`):void 0,children:(0,G.jsxs)(`span`,{className:`flex flex-wrap items-center gap-x-2`,children:[(0,G.jsx)(Y,{entry:c}),c.credits?(0,G.jsx)(`span`,{className:`text-ink-2`,children:O(`market.creditsRange`,{n:Be(c.credits.credits)})}):null]})})}),(0,G.jsx)(X,{title:O(`market.result`),children:(0,G.jsx)(`div`,{className:`flex flex-col gap-2`,children:(s.data?.results??[]).map(e=>(0,G.jsx)($,{icon:(0,G.jsx)(q,{format:e.kind,className:`size-4 text-ember-strong`}),more:e.formats.map(e=>e.toUpperCase()).join(` · `),children:e.title},e.title))})}),(0,G.jsx)(X,{title:O(`market.needs`),children:(0,G.jsx)(`ul`,{className:`flex flex-col gap-2`,children:c.capabilities.map(e=>{let t=We[e],n=c.missing.includes(e),r=c.optional?.includes(e);return(0,G.jsxs)(`li`,{className:A(`flex items-center gap-2.5 text-[0.875rem]`,n?`text-ink-3`:`text-ink-2`),children:[(0,G.jsx)(t,{className:A(`size-4 shrink-0`,n?`text-rose`:r?`text-amber`:`text-cobalt`)}),K(U,e),n?(0,G.jsx)(`span`,{className:`text-[0.75rem] text-rose`,children:O(`market.unavailable`)}):r?(0,G.jsx)(`span`,{className:`text-[0.75rem] text-amber`,children:O(`market.optional`)}):null]},e)})})})]}),(0,G.jsxs)(`div`,{className:`flex flex-col sm:min-h-0`,children:[(0,G.jsx)(`div`,{className:`mb-1.5 shrink-0 font-medium text-[0.75rem] text-ink-3 uppercase tracking-[0.06em]`,children:O(`market.steps`)}),(0,G.jsx)(Je,{className:`-mr-2 overscroll-contain pt-1 pr-2 pl-1 sm:min-h-0 sm:flex-1 sm:overflow-y-auto`,children:s.isLoading?(0,G.jsx)(k,{className:`size-5 text-ink-3`}):(0,G.jsx)(V.Suspense,{fallback:(0,G.jsx)(k,{className:`size-5 text-ink-3`}),children:(0,G.jsx)(Re,{steps:qe(s.data?.outline??[])})})})]})]}):(0,G.jsx)(`div`,{className:`flex-1 px-5 pt-6 sm:px-7`,children:(0,G.jsx)(`p`,{className:`rounded-lg bg-amber-tint p-3 text-[0.875rem] text-ink-2`,children:O(`market.needsUpdateHint`)})}),(0,G.jsxs)(`div`,{className:`flex shrink-0 justify-end gap-2 px-5 pt-4 pb-5 max-sm:border-border-soft max-sm:border-t sm:px-7 sm:pb-6`,children:[(0,G.jsxs)(M,{variant:`ghost`,className:`mr-auto`,title:O(`market.starHint`),"aria-pressed":c.starred,busy:h.isPending,onClick:()=>h.mutate(!c.starred),children:[(0,G.jsx)(D,{className:A(`size-4`,c.starred&&`fill-amber text-amber`)}),(0,G.jsx)(`span`,{className:`max-sm:sr-only`,children:O(c.starred?`market.starred`:`market.star`)})]}),(0,G.jsx)(M,{variant:`secondary`,onClick:n,children:O(`common.close`)}),c.usable&&c.missing.length?(0,G.jsx)(M,{variant:`secondary`,onClick:()=>o(`/settings/models`),children:O(`editor.models.settings`)}):null,r?(0,G.jsx)(M,{disabled:!c.usable||c.missing.length>0,title:c.missing.length?O(`market.missingHint`,{list:Z(c.missing)}):c.optional?.length?O(`market.optionalHint`,{list:Z(c.optional)}):void 0,busy:i,onClick:()=>r(c),children:O(`market.use`)}):null]})]}):(0,G.jsx)(`div`,{className:`flex min-h-48 flex-col items-center justify-center gap-3 rounded-2xl bg-card p-8 text-[0.875rem] text-ink-2 shadow-overlay`,children:s.isLoading?(0,G.jsx)(k,{className:`size-6 text-ink-3`}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`p`,{children:O(`market.notFound`)}),(0,G.jsx)(M,{variant:`secondary`,onClick:n,children:O(`common.close`)})]})})})}function Xe({name:e,value:t,options:n,onChange:r}){let[i,a]=(0,V.useState)(!1),o=(0,V.useRef)(null);(0,V.useEffect)(()=>{if(!i)return;let e=e=>{o.current?.contains(e.target)||a(!1)},t=e=>{e.key===`Escape`&&a(!1)};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[i]);let s=n.find(e=>e.value===t);return(0,G.jsxs)(`div`,{ref:o,className:`relative`,children:[(0,G.jsxs)(`div`,{className:A(`flex h-8 items-center rounded-full text-[0.8125rem] transition`,s?`bg-ember-tint text-ink`:`text-ink-2 hover:bg-paper-2 hover:text-ink`,i&&!s&&`bg-paper-2 text-ink`),children:[(0,G.jsx)(`button`,{type:`button`,"aria-haspopup":`listbox`,"aria-expanded":i,onClick:()=>a(!i),className:A(`flex h-full items-center gap-1.5 rounded-full pl-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus`,s?`pr-1`:`pr-2.5`),children:s?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`span`,{className:`text-ink-3`,children:e}),(0,G.jsx)(`span`,{className:`font-medium`,children:s.label})]}):(0,G.jsxs)(G.Fragment,{children:[e,(0,G.jsx)(b,{className:A(`size-3.5 transition`,i&&`rotate-180`)})]})}),s?(0,G.jsx)(`button`,{type:`button`,"aria-label":`${e}: ${O(`market.reset`)}`,onClick:()=>r(``),className:`mr-1 flex size-6 items-center justify-center rounded-full text-ink-3 hover:bg-card hover:text-ink`,children:(0,G.jsx)(L,{className:`size-3.5`})}):null]}),i?(0,G.jsx)(`div`,{role:`listbox`,"aria-label":e,className:`absolute top-full left-0 z-30 mt-1.5 max-h-80 min-w-60 overflow-y-auto rounded-xl bg-card p-1.5 shadow-overlay ring-1 ring-border-soft`,children:n.map(e=>(0,G.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":e.value===t,disabled:!e.count||e.unavailable,onClick:()=>{r(e.value===t?``:e.value),a(!1)},className:A(`flex w-full items-center gap-2.5 rounded-lg px-2.5 py-2 text-left text-[0.875rem] transition coarse:py-2.5`,e.count&&!e.unavailable?`text-ink-2 hover:bg-paper-2 hover:text-ink`:`text-ink-4`,e.value===t&&`font-medium text-ink`),children:[e.icon,(0,G.jsx)(`span`,{className:`flex-1 whitespace-nowrap`,children:e.label}),e.value===t?(0,G.jsx)(ne,{className:`size-4 text-ember`}):e.unavailable?(0,G.jsx)(`span`,{className:`whitespace-nowrap text-[0.75rem] text-ink-4`,children:O(`market.unavailable`)}):(0,G.jsx)(`span`,{className:`text-[0.75rem] text-ink-4 tabular-nums`,children:e.count})]},e.value))}):null]})}function Ze(e,t){let[n,r]=(0,V.useState)(e);return(0,V.useEffect)(()=>{let n=setTimeout(()=>r(e),t);return()=>clearTimeout(n)},[e,t]),n}var Qe=60;function $e({onUse:e,busy:t,open:n}){let[r,i]=(0,V.useState)(``),[a,s]=(0,V.useState)(ze),[c,l]=(0,V.useState)(!1),[u,d]=(0,V.useState)(n??null),f=Ze(r.trim(),250),m=Ce({queryKey:[`marketplace`,N,f,a,c],queryFn:({pageParam:e})=>{let t=new URLSearchParams({lang:N,limit:String(Qe),offset:String(e)});f&&t.set(`q`,f);for(let[e,n]of Object.entries(a))n&&t.set(e,n);return c&&t.set(`starred`,`1`),p.get(`/api/studio/marketplace?${t}`)},initialPageParam:0,getNextPageParam:(e,t)=>{let n=t.reduce((e,t)=>e+t.entries.length,0);return n<e.total?n:void 0},placeholderData:o}),h=m.data?.pages[0],g=m.data?.pages.flatMap(e=>e.entries)??[],_=h?.all??0,v=r.trim()!==f||m.isFetching&&!m.isFetchingNextPage,y=(e,t,n)=>Object.keys(t).filter(t=>h?.facets[e]?.[t]!==void 0).map(r=>({value:r,label:K(t,r),icon:n?.(r),count:(h?.facets[e])[r]??0,unavailable:e===`capability`&&ee.has(r)})),ee=new Set(h?.unavailable??[]),te=y(`useCase`,Ie),ne=[{key:`industry`,name:O(`market.industry`),options:y(`industry`,Fe)},{key:`format`,name:O(`market.format`),options:y(`format`,H,e=>(0,G.jsx)(q,{format:e,className:`size-4 text-ink-3`}))},{key:`capability`,name:O(`market.capability`),options:y(`capability`,U,e=>{let t=We[e];return(0,G.jsx)(t,{className:`size-4 text-ink-3`})})}],b=!!r.trim()||c||Object.values(a).some(Boolean),x=()=>{s(ze),i(``),l(!1)};if(m.isLoading)return(0,G.jsx)(`div`,{className:`flex justify-center py-10`,children:(0,G.jsx)(k,{className:`size-6 text-ink-3`})});let S=h?.offline?(0,G.jsxs)(`p`,{className:`mt-4 flex items-center justify-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,G.jsx)(me,{className:`size-4 shrink-0`}),O(`market.offline`)]}):null;if(!_&&!b)return S;let C=r?(0,G.jsx)(`button`,{type:`button`,"aria-label":O(`market.reset`),onClick:()=>i(``),className:`-mr-1.5 flex size-7 shrink-0 items-center justify-center rounded-full text-ink-3 hover:bg-paper-2 hover:text-ink`,children:(0,G.jsx)(L,{className:`size-4`})}):null,w=e=>A(`inline-flex h-7 shrink-0 items-center gap-1 whitespace-nowrap rounded-full px-2.5 text-[0.78125rem] transition`,e?`bg-card font-medium text-ink shadow-soft ring-1 ring-border-soft`:`text-ink-3 hover:bg-card/60 hover:text-ink`);return(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`label`,{className:`relative mx-auto flex h-10 max-w-md items-center gap-2.5 rounded-full bg-card px-4 shadow-soft ring-1 ring-border-soft transition focus-within:ring-2 focus-within:ring-focus sm:h-11`,children:[v?(0,G.jsx)(k,{className:`size-4 shrink-0 text-ink-3`}):(0,G.jsx)(re,{className:`size-4 shrink-0 text-ink-3`}),(0,G.jsx)(`input`,{type:`search`,value:r,onChange:e=>i(e.target.value),placeholder:O(`market.search`),"aria-label":O(`market.search`),className:`min-w-0 flex-1 bg-transparent text-[0.9375rem] outline-none placeholder:text-ink-4 [&::-webkit-search-cancel-button]:hidden`}),C]}),S,(0,G.jsxs)(`div`,{className:`max-sm:-mx-3 mt-4 flex gap-1 max-sm:overflow-x-auto max-sm:px-3 max-sm:[scrollbar-width:none] sm:flex-wrap sm:justify-center max-sm:[&::-webkit-scrollbar]:hidden`,children:[[{value:``,label:O(`market.all`)},...te].map(e=>(0,G.jsx)(`button`,{type:`button`,"aria-pressed":!c&&a.useCase===e.value,onClick:()=>{l(!1),s({...a,useCase:e.value})},className:w(!c&&a.useCase===e.value),children:e.label},e.value)),(0,G.jsxs)(`button`,{type:`button`,"aria-pressed":c,onClick:()=>l(!c),className:w(c),children:[(0,G.jsx)(D,{className:A(`size-3.5`,c&&`fill-amber text-amber`)}),O(`market.starred`)]})]}),(0,G.jsxs)(`div`,{className:`mt-3 flex flex-wrap items-center gap-x-1 gap-y-2 sm:mt-6`,children:[c?null:ne.map(e=>(0,G.jsx)(Xe,{name:e.name,value:a[e.key],options:e.options,onChange:t=>s({...a,[e.key]:t})},e.key)),(0,G.jsxs)(`span`,{className:`ml-auto flex items-center gap-3 whitespace-nowrap pl-2 text-[0.8125rem] text-ink-3`,children:[b?(0,G.jsxs)(`button`,{type:`button`,onClick:x,className:`inline-flex items-center gap-1 text-ember-strong underline-offset-2 hover:underline`,children:[(0,G.jsx)(L,{className:`size-3.5 max-sm:size-4`}),(0,G.jsx)(`span`,{className:`max-sm:sr-only`,children:O(`market.resetShort`)})]}):null,b?(0,G.jsx)(`span`,{className:`tabular-nums sm:hidden`,children:O(`market.countOfShort`,{n:h?.total??0,all:_})}):null,(0,G.jsx)(`span`,{className:A(`tabular-nums`,b&&`max-sm:hidden`),children:b?O(`market.countOf`,{n:h?.total??0,all:_}):O(`market.count`,{n:_})})]})]}),g.length?(0,G.jsx)(`div`,{className:`mt-4 grid gap-4 sm:grid-cols-2 lg:grid-cols-3`,children:g.map(e=>(0,G.jsx)(Ue,{entry:e,onOpen:()=>d(e.id)},e.id))}):(0,G.jsxs)(`div`,{className:`py-10 text-center text-[0.875rem] text-ink-3`,children:[(0,G.jsx)(`p`,{children:O(c?`market.noneStarred`:`market.none`)}),(0,G.jsx)(M,{variant:`ghost`,className:`mt-2`,onClick:x,children:O(`market.reset`)})]}),m.hasNextPage?(0,G.jsx)(`div`,{className:`mt-6 flex justify-center`,children:(0,G.jsx)(M,{variant:`secondary`,busy:m.isFetchingNextPage,onClick:()=>void m.fetchNextPage(),children:O(`market.more`)})}):null,(0,G.jsx)(Ye,{id:u,fallback:g.find(e=>e.id===u)??null,onClose:()=>d(null),onUse:e,busy:t})]})}var et={de:[`Stellenanzeige aus ein paar Stichworten, als PDF und LinkedIn-Post`,`Produktbeschreibung für den Onlineshop mit drei Bildvarianten`,`Wettbewerbsanalyse zu einer Firma mit Quellen`,`Lead aus einem Formular in unser CRM eintragen`],en:[`A job ad from a few keywords, as PDF and LinkedIn post`,`A shop product description with three image variants`,`A competitor analysis for a company, with sources`,`Put a lead from a form into our CRM`]};function tt(){let e=l(),t=m(),{project:n}=be(),i=_e(),[a,o]=(0,V.useState)(``),[s]=r(),c=P({mutationFn:e=>p.post(`/api/studio/wizards`,{projectId:n.id,starterId:e,lang:N}),onSuccess:async({id:n},r)=>{await t.invalidateQueries({queryKey:[`projects`]}),await t.invalidateQueries({queryKey:[`wizards`]}),e(r?`/edit/${n}`:`/edit/${n}?prompt=${encodeURIComponent(a.trim())}`)}}),d=()=>{a.trim()&&n&&c.mutate(void 0)};return!i||n?.readOnly?(0,G.jsx)(h,{to:`/`,replace:!0}):(0,G.jsxs)(`div`,{className:`animate-rise pt-4`,children:[(0,G.jsxs)(`div`,{className:`mx-auto max-w-2xl`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,G.jsx)(u,{kind:`sprout`,size:150,fluffy:!0}),(0,G.jsx)(`h1`,{className:`mt-2 font-display font-semibold text-[2rem] leading-tight tracking-tight sm:text-[2.375rem]`,children:O(`new.title`)})]}),(0,G.jsxs)(`div`,{className:`mt-8 rounded-2xl bg-card p-2 shadow-elevated ring-1 ring-border-soft focus-within:ring-focus`,children:[(0,G.jsx)(fe,{autoFocus:!0,minRows:4,value:a,onChange:e=>o(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&d()},placeholder:O(`new.placeholder`),className:`border-0 bg-transparent text-[1rem] shadow-none focus:ring-0`}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-2 pb-1`,children:[(0,G.jsx)(`span`,{className:`hidden text-[0.75rem] text-ink-4 sm:block`,children:O(`new.hint`)}),(0,G.jsxs)(M,{size:`md`,onClick:d,busy:c.isPending&&!c.variables,disabled:!a.trim(),children:[O(`new.build`),` `,(0,G.jsx)(v,{className:`size-4`})]})]})]}),(0,G.jsx)(`div`,{className:`mt-4 flex flex-wrap justify-center gap-2`,children:et[N].map(e=>(0,G.jsx)(`button`,{type:`button`,onClick:()=>o(e),className:`rounded-full bg-paper-2 px-3.5 py-1.5 text-[0.8125rem] text-ink-2 transition hover:bg-paper-3 hover:text-ink`,children:e},e))})]}),(0,G.jsxs)(`section`,{className:`mx-auto max-w-5xl`,children:[(0,G.jsx)(`h2`,{className:`mt-16 mb-5 text-center font-medium text-[0.8125rem] text-ink-3 uppercase tracking-[0.08em]`,children:O(`new.orStarter`)}),(0,G.jsx)($e,{open:s.get(`starter`),busy:c.isPending&&!!c.variables,onUse:e=>n&&!c.isPending&&c.mutate(e.id)}),c.error?(0,G.jsx)(`p`,{className:`mt-3 text-center text-[0.875rem] text-rose`,children:c.error.message}):null]}),(0,G.jsx)(`div`,{className:`mt-8 flex justify-center`,children:(0,G.jsx)(xe,{variant:`ghost`,label:O(`new.import`)})})]})}export{tt as NewWizardPage};