wizards 0.2.12 → 0.2.14

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 (86) hide show
  1. package/apps/runtime/dist/authoring/guide.js +8 -2
  2. package/apps/runtime/dist/db/migrations/tenant/0007_space_data.sql +43 -0
  3. package/apps/runtime/dist/db/migrations/tenant/meta/0007_snapshot.json +2012 -0
  4. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  5. package/apps/runtime/dist/db/schema.js +55 -0
  6. package/apps/runtime/dist/engine/runner.js +1 -1
  7. package/apps/runtime/dist/routes/api.js +14 -1
  8. package/apps/runtime/dist/routes/runs.js +13 -7
  9. package/apps/runtime/dist/routes/studio.js +89 -1
  10. package/apps/runtime/dist/services/cloud.js +62 -2
  11. package/apps/runtime/dist/services/runs.js +69 -1
  12. package/apps/runtime/dist/services/space-data.js +361 -0
  13. package/apps/runtime/dist/services/spaces.js +95 -1
  14. package/apps/runtime/dist/store/errors.js +3 -0
  15. package/apps/runtime/dist/store/index.js +19 -5
  16. package/apps/runtime/dist/store/shared-lists.js +124 -0
  17. package/apps/runtime/dist/tools/index.js +4 -0
  18. package/apps/runtime/dist/tools/pages.js +51 -0
  19. package/apps/runtime/dist/tools/store.js +3 -3
  20. package/apps/web/dist/assets/Account-CbcLDgwW.js +1 -0
  21. package/apps/web/dist/assets/ChangelogDialog-CPaoAyWM.js +1 -0
  22. package/apps/web/dist/assets/ChatPanel-DzIGwA0b.js +1 -0
  23. package/apps/web/dist/assets/{CreditsDialog-DSjsgLoo.js → CreditsDialog-o9h0Nrui.js} +1 -1
  24. package/apps/web/dist/assets/EditorPage-BPL4_GlP.js +2 -0
  25. package/apps/web/dist/assets/FlowPreview-DdZKsXNh.js +1 -0
  26. package/apps/web/dist/assets/{Harness-DEGZ-_YL.js → Harness-CKcyJvtw.js} +2 -2
  27. package/apps/web/dist/assets/HomePage-DVPGy7jW.js +1 -0
  28. package/apps/web/dist/assets/{ImportWizard-pZCs65kL.js → ImportWizard-CK9fXKct.js} +1 -1
  29. package/apps/web/dist/assets/LocalRuntime-Cjftoi3j.js +1 -0
  30. package/apps/web/dist/assets/NewWizardPage-0GHmokBt.js +2 -0
  31. package/apps/web/dist/assets/ProjectPage-DURhRvUm.js +4 -0
  32. package/apps/web/dist/assets/PublicRunner-BCHg6lbj.js +1 -0
  33. package/apps/web/dist/assets/RunnerView-a_2EqHPo.js +70 -0
  34. package/apps/web/dist/assets/SettingsPage-DPHW6HRz.js +1 -0
  35. package/apps/web/dist/assets/SetupPage-r6tj7oTr.js +1 -0
  36. package/apps/web/dist/assets/SharePage-2Q8SoJLs.js +1 -0
  37. package/apps/web/dist/assets/{api-u3nydnnp.js → api-DTLkC0ge.js} +2 -2
  38. package/apps/web/dist/assets/changelog-5ArxeGsu.js +1 -0
  39. package/apps/web/dist/assets/circle-alert-D2SCwFT-.js +1 -0
  40. package/apps/web/dist/assets/{definition-Co2Mg1qo.js → definition-Dp0DR2D6.js} +1 -1
  41. package/apps/web/dist/assets/{esm-CvV3man4.js → esm-Buv7Ma3z.js} +1 -1
  42. package/apps/web/dist/assets/index-C5pRB5Ah.js +10 -0
  43. package/apps/web/dist/assets/index-DMwk_afK.css +1 -0
  44. package/apps/web/dist/assets/lock-DZL2N67v.js +1 -0
  45. package/apps/web/dist/assets/meta-CDimdOlV.js +1 -0
  46. package/apps/web/dist/assets/refresh-cw-BNtHis1x.js +1 -0
  47. package/apps/web/dist/assets/settings-menu-D1tMZ82V.js +1 -0
  48. package/apps/web/dist/assets/{type-BqbppSsp.js → table-2-BdDuBcF2.js} +1 -1
  49. package/apps/web/dist/assets/ui-CHX2gEQl.js +1 -0
  50. package/apps/web/dist/assets/video-9fDPRPCv.js +1 -0
  51. package/apps/web/dist/index.html +4 -4
  52. package/apps/web/dist/mcp/flow.html +5 -5
  53. package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +12 -4
  54. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +6 -1
  55. package/node_modules/@engenty-wizards/shared/dist/definition.js +36 -2
  56. package/node_modules/@engenty-wizards/shared/dist/space-data.d.ts +69 -0
  57. package/node_modules/@engenty-wizards/shared/dist/space-data.js +46 -0
  58. package/node_modules/@engenty-wizards/shared/dist/store.d.ts +2 -0
  59. package/package.json +1 -1
  60. package/apps/web/dist/assets/Account-BK8Q-U-8.js +0 -1
  61. package/apps/web/dist/assets/ChangelogDialog-BZ8s1isE.js +0 -1
  62. package/apps/web/dist/assets/ChatPanel-CMf1PS2N.js +0 -1
  63. package/apps/web/dist/assets/EditorPage-Bpgiq7aR.js +0 -2
  64. package/apps/web/dist/assets/FlowPreview-B5HrjouC.js +0 -1
  65. package/apps/web/dist/assets/HomePage-DIDJ8Jw1.js +0 -1
  66. package/apps/web/dist/assets/LocalRuntime-DQW6CLg-.js +0 -1
  67. package/apps/web/dist/assets/NewWizardPage-uhIbKcwn.js +0 -2
  68. package/apps/web/dist/assets/ProjectPage-CAMddxGu.js +0 -2
  69. package/apps/web/dist/assets/PublicRunner-jOAbZd2P.js +0 -1
  70. package/apps/web/dist/assets/ReadOnly-B0-ReU_0.js +0 -1
  71. package/apps/web/dist/assets/RunnerView-BThdhY7S.js +0 -2
  72. package/apps/web/dist/assets/SettingsPage-D_6hzTLJ.js +0 -1
  73. package/apps/web/dist/assets/SetupPage-Cvpg9Jyh.js +0 -1
  74. package/apps/web/dist/assets/SharePage-CRSnOm0Z.js +0 -1
  75. package/apps/web/dist/assets/arrow-left-hTN1VoH1.js +0 -1
  76. package/apps/web/dist/assets/changelog-BJqo0vwQ.js +0 -1
  77. package/apps/web/dist/assets/circle-alert-B76z9TWZ.js +0 -1
  78. package/apps/web/dist/assets/index-CQQD8QNR.css +0 -1
  79. package/apps/web/dist/assets/index-CTM5iDwf.js +0 -10
  80. package/apps/web/dist/assets/lock-CzNXAYdi.js +0 -1
  81. package/apps/web/dist/assets/meta-CzzuBWbK.js +0 -1
  82. package/apps/web/dist/assets/mic-Bvz4mA2j.js +0 -1
  83. package/apps/web/dist/assets/outputs-CYynzGBS.js +0 -69
  84. package/apps/web/dist/assets/refresh-cw-Cmk7VCe0.js +0 -1
  85. package/apps/web/dist/assets/ui-gGAdXx-P.js +0 -1
  86. package/apps/web/dist/assets/video-DBmwF1Jm.js +0 -1
@@ -36,13 +36,21 @@ export interface StudioSettingsSection {
36
36
  menu?: boolean;
37
37
  }
38
38
  /**
39
- * A section of the space page, below the space's own sections. The studio draws its heading and
40
- * hint above it, and its entry in the page's menu under the plugin's name; the component draws
41
- * the rest, usually a `Card`.
39
+ * The parts of the space page: `info` (who the space is, its logos, colours, assets and facts),
40
+ * `knowledge` (its documents and what its steps search), `data` (what its wizards keep) and
41
+ * `results` (what its runs produced).
42
+ */
43
+ export type StudioSpaceGroup = "info" | "knowledge" | "data" | "results";
44
+ /**
45
+ * A section of the space page, in one of its parts, below the part's own sections. The studio
46
+ * draws its heading and hint above it, and its entry in the part's menu under the plugin's name;
47
+ * the component draws the rest, usually a `Card`.
42
48
  */
43
49
  export interface StudioSpaceSection {
44
- /** Its anchor on the page: `/space#<id>`. */
50
+ /** Its anchor: `/space/<group>#<id>`. Unique on the whole space page. */
45
51
  id: string;
52
+ /** The part it stands in; `knowledge` when left out. */
53
+ group?: StudioSpaceGroup;
46
54
  label: () => string;
47
55
  /** One line under the heading: what the section is for. */
48
56
  hint?: () => string;
@@ -28,7 +28,7 @@ export declare function isAudioValue(v: unknown): v is AudioValue;
28
28
  export declare function locationText(v: LocationValue): string;
29
29
  /** A field takes at most this many files. */
30
30
  export declare const MAX_FILES = 30;
31
- export declare const TOOL_IDS: readonly ["web_search", "web_fetch", "browser", "sandbox", "image", "http"];
31
+ export declare const TOOL_IDS: readonly ["web_search", "web_fetch", "browser", "sandbox", "image", "http", "pages"];
32
32
  /**
33
33
  * A tool a plugin of the runtime adds: `<plugin id>.<tool name>`. A wizard that names one runs
34
34
  * only where that plugin is installed.
@@ -235,6 +235,7 @@ export declare const agentStepSchema: z.ZodObject<{
235
235
  browser: "browser";
236
236
  sandbox: "sandbox";
237
237
  http: "http";
238
+ pages: "pages";
238
239
  }>, z.ZodTemplateLiteral<`${string}.${string}`>]>>>;
239
240
  mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
240
241
  connections: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -546,6 +547,7 @@ export declare const stepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
546
547
  browser: "browser";
547
548
  sandbox: "sandbox";
548
549
  http: "http";
550
+ pages: "pages";
549
551
  }>, z.ZodTemplateLiteral<`${string}.${string}`>]>>>;
550
552
  mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
551
553
  connections: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -897,6 +899,7 @@ export declare const listSchema: z.ZodObject<{
897
899
  file: z.ZodOptional<z.ZodString>;
898
900
  status: z.ZodOptional<z.ZodString>;
899
901
  }, z.core.$strip>>;
902
+ shared: z.ZodOptional<z.ZodBoolean>;
900
903
  }, z.core.$strip>;
901
904
  export declare const connectionSchema: z.ZodObject<{
902
905
  id: z.ZodString;
@@ -1061,6 +1064,7 @@ export declare const wizardSchema: z.ZodObject<{
1061
1064
  file: z.ZodOptional<z.ZodString>;
1062
1065
  status: z.ZodOptional<z.ZodString>;
1063
1066
  }, z.core.$strip>>;
1067
+ shared: z.ZodOptional<z.ZodBoolean>;
1064
1068
  }, z.core.$strip>>>;
1065
1069
  connections: z.ZodOptional<z.ZodArray<z.ZodObject<{
1066
1070
  id: z.ZodString;
@@ -1158,6 +1162,7 @@ export declare const wizardSchema: z.ZodObject<{
1158
1162
  browser: "browser";
1159
1163
  sandbox: "sandbox";
1160
1164
  http: "http";
1165
+ pages: "pages";
1161
1166
  }>, z.ZodTemplateLiteral<`${string}.${string}`>]>>>;
1162
1167
  mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
1163
1168
  connections: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -58,7 +58,15 @@ export function locationText(v) {
58
58
  }
59
59
  /** A field takes at most this many files. */
60
60
  export const MAX_FILES = 30;
61
- export const TOOL_IDS = ["web_search", "web_fetch", "browser", "sandbox", "image", "http"];
61
+ export const TOOL_IDS = [
62
+ "web_search",
63
+ "web_fetch",
64
+ "browser",
65
+ "sandbox",
66
+ "image",
67
+ "http",
68
+ "pages",
69
+ ];
62
70
  /**
63
71
  * A tool a plugin of the runtime adds: `<plugin id>.<tool name>`. A wizard that names one runs
64
72
  * only where that plugin is installed.
@@ -322,6 +330,12 @@ export const listSchema = z.object({
322
330
  * answers — the first one means "not looked at yet".
323
331
  */
324
332
  check: z.object({ file: z.string().optional(), status: z.string().optional() }).optional(),
333
+ /**
334
+ * The list is the wizard's, not one person's: every run reads and writes the same rows, and
335
+ * the studio shows it under Space → Daten. It is never shown to the person running the wizard,
336
+ * who would see what others gave.
337
+ */
338
+ shared: z.boolean().optional(),
325
339
  });
326
340
  export const connectionSchema = z.object({
327
341
  id,
@@ -345,7 +359,7 @@ export const wizardSchema = z.object({
345
359
  avatar: z.enum(ENGENTY_KINDS).default("round"),
346
360
  /** Shown on the first page above the first question. */
347
361
  intro: z.string().optional(),
348
- /** Tabular data the wizard keeps between runs, per person. */
362
+ /** Tabular data the wizard keeps between runs, per person — or for all runs (`shared`). */
349
363
  lists: z.array(listSchema).max(12).optional(),
350
364
  /** Accounts the person connects; kept between runs, per person. */
351
365
  connections: z.array(connectionSchema).max(12).optional(),
@@ -415,12 +429,20 @@ export function validateWizard(def, files) {
415
429
  const seenSteps = new Set();
416
430
  const seenFields = new Set();
417
431
  const listIds = new Set();
432
+ const sharedLists = new Set();
418
433
  const connectionIds = new Set();
434
+ const notShown = (id) => `List "${id}" is shared: every run writes it, so the person running the wizard never sees it.`;
419
435
  for (const list of def.lists ?? []) {
420
436
  if (listIds.has(list.id)) {
421
437
  issues.push({ message: `Duplicate list id "${list.id}".` });
422
438
  }
423
439
  listIds.add(list.id);
440
+ if (list.shared) {
441
+ sharedLists.add(list.id);
442
+ if (list.check) {
443
+ issues.push({ message: `${notShown(list.id)} It cannot be checked row by row.` });
444
+ }
445
+ }
424
446
  if (list.key && !list.columns.some((c) => c.id === list.key)) {
425
447
  issues.push({ message: `List "${list.id}": key "${list.key}" is not one of its columns.` });
426
448
  }
@@ -476,6 +498,12 @@ export function validateWizard(def, files) {
476
498
  message: `Field "${field.id}" needs "list": the id of one of the wizard's lists.`,
477
499
  });
478
500
  }
501
+ else if (field.kind === "list" && sharedLists.has(field.list ?? "")) {
502
+ issues.push({
503
+ stepId: step.id,
504
+ message: `Field "${field.id}": ${notShown(field.list ?? "")}`,
505
+ });
506
+ }
479
507
  if (field.min !== undefined || field.max !== undefined) {
480
508
  if ((field.kind !== "image" && field.kind !== "file") || !field.multiple) {
481
509
  issues.push({
@@ -629,6 +657,9 @@ export function validateWizard(def, files) {
629
657
  message: `Review shows unknown ${list ? "list" : "step"} "${ref}".`,
630
658
  });
631
659
  }
660
+ else if (list && sharedLists.has(list)) {
661
+ issues.push({ stepId: step.id, message: notShown(list) });
662
+ }
632
663
  }
633
664
  break;
634
665
  case "result":
@@ -640,6 +671,9 @@ export function validateWizard(def, files) {
640
671
  message: `Deliverable from unknown ${list ? "list" : "step"} "${d.from}".`,
641
672
  });
642
673
  }
674
+ else if (list && sharedLists.has(list)) {
675
+ issues.push({ stepId: step.id, message: notShown(list) });
676
+ }
643
677
  }
644
678
  break;
645
679
  }
@@ -0,0 +1,69 @@
1
+ import { type TableColumn } from "./engenty/data-tables/index.js";
2
+ /**
3
+ * What a space keeps as data: tables (typed columns, rows of cells, as engenty's data tables)
4
+ * and pages (a title and markdown). Each belongs to the space, or to one of its wizards.
5
+ */
6
+ export interface SpaceTableInfo {
7
+ id: string;
8
+ /** The wizard it belongs to; null: the space's own. */
9
+ wizardId: string | null;
10
+ /** The wizard's shared list it keeps; its columns come from the wizard. */
11
+ list: string | null;
12
+ title: string;
13
+ rows: number;
14
+ updatedAt: string;
15
+ }
16
+ export interface SpacePageInfo {
17
+ id: string;
18
+ wizardId: string | null;
19
+ title: string;
20
+ updatedAt: string;
21
+ }
22
+ /** The space's tables and pages, and its wizards to name whose they are. */
23
+ export interface SpaceData {
24
+ tables: SpaceTableInfo[];
25
+ pages: SpacePageInfo[];
26
+ wizards: {
27
+ id: string;
28
+ title: string;
29
+ }[];
30
+ }
31
+ export interface SpaceTableRow {
32
+ id: string;
33
+ cells: Record<string, unknown>;
34
+ updatedAt: string;
35
+ }
36
+ export interface SpaceTable {
37
+ id: string;
38
+ projectId: string;
39
+ wizardId: string | null;
40
+ list: string | null;
41
+ title: string;
42
+ columns: TableColumn[];
43
+ rows: SpaceTableRow[];
44
+ /** The space is not changed here: a local install's, or nothing is built on this runtime. */
45
+ readOnly: boolean;
46
+ }
47
+ export interface SpacePage {
48
+ id: string;
49
+ projectId: string;
50
+ wizardId: string | null;
51
+ title: string;
52
+ markdown: string;
53
+ updatedAt: string;
54
+ readOnly: boolean;
55
+ }
56
+ export declare const SPACE_DATA_LIMITS: {
57
+ tables: number;
58
+ pages: number;
59
+ rowsPerTable: number;
60
+ pageChars: number;
61
+ };
62
+ /**
63
+ * Cells a person typed, as stored: each value checked against its column. A blank cell is kept
64
+ * empty even where the column is required, so a row can be filled one cell at a time; cells of
65
+ * columns that no longer exist are dropped.
66
+ */
67
+ export declare function editCells(columns: readonly TableColumn[], current: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown>;
68
+ /** A column id from its name: a lowercase slug, not one of `taken`. */
69
+ export declare function columnIdOf(name: string, taken: readonly string[]): string;
@@ -0,0 +1,46 @@
1
+ import { coerceColumnValue, TableColumnValueError, } from "./engenty/data-tables/index.js";
2
+ export const SPACE_DATA_LIMITS = {
3
+ tables: 200,
4
+ pages: 500,
5
+ rowsPerTable: 5000,
6
+ pageChars: 200_000,
7
+ };
8
+ /**
9
+ * Cells a person typed, as stored: each value checked against its column. A blank cell is kept
10
+ * empty even where the column is required, so a row can be filled one cell at a time; cells of
11
+ * columns that no longer exist are dropped.
12
+ */
13
+ export function editCells(columns, current, patch) {
14
+ const byId = new Map(columns.map((c) => [c.id, c]));
15
+ const next = {};
16
+ for (const [id, value] of Object.entries(current)) {
17
+ if (byId.has(id)) {
18
+ next[id] = value;
19
+ }
20
+ }
21
+ for (const [id, value] of Object.entries(patch)) {
22
+ const column = byId.get(id);
23
+ if (!column) {
24
+ throw new TableColumnValueError(id, `unknown column "${id}"`);
25
+ }
26
+ next[id] = coerceColumnValue({ ...column, required: false }, value);
27
+ }
28
+ return next;
29
+ }
30
+ /** A column id from its name: a lowercase slug, not one of `taken`. */
31
+ export function columnIdOf(name, taken) {
32
+ const base = name
33
+ .normalize("NFKD")
34
+ .replace(/[̀-ͯ]/g, "")
35
+ .toLowerCase()
36
+ .replace(/[^a-z0-9]+/g, "_")
37
+ .replace(/^_+|_+$/g, "")
38
+ .replace(/^[^a-z]+/, "")
39
+ .slice(0, 48) || "column";
40
+ let id = base;
41
+ let i = 2;
42
+ while (taken.includes(id)) {
43
+ id = `${base}_${i++}`;
44
+ }
45
+ return id;
46
+ }
@@ -20,6 +20,8 @@ export interface ListDef {
20
20
  file?: string;
21
21
  status?: string;
22
22
  };
23
+ /** Every run reads and writes the same rows; kept as a table of the space, not per person. */
24
+ shared?: boolean;
23
25
  }
24
26
  export interface ListRow {
25
27
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wizards",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
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 +0,0 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,j as i,n as a,nt as o}from"./api-u3nydnnp.js";import{t as s}from"./createLucideIcon-q3MZMmnf.js";import{t as c}from"./check-CUpby_J9.js";import{n as l,r as u}from"./upload-DNRENWzQ.js";import{t as d}from"./external-link-MAL7vJYj.js";import{_ as f,c as p,d as m,h,m as g,n as ee,o as _,r as v,s as y,t as b,y as x}from"./ui-gGAdXx-P.js";import{I as S,O as C,f as w,j as T,o as E,p as D,u as O,v as k}from"./index-CTM5iDwf.js";import{n as A}from"./LocalRuntime-DQW6CLg-.js";var j={name:`hard-drive`,size:24,node:[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]};j.node;var M=s(j),N={name:`layout-grid`,size:24,node:[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]};N.node;var te=s(N),P={name:`list`,size:24,node:[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]};P.node;var F=s(P),I=e(t(),1),L=e=>[`project-files`,e];function R(e){return i({queryKey:L(e),queryFn:()=>a.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function z(e,t){return r(`/api/studio/projects/${e}/files/${t}/content`)}function B(e,t=!1){let n=o(),[r,i]=(0,I.useState)(!1),[s,c]=(0,I.useState)(null),l=()=>n.invalidateQueries({queryKey:L(e)}),u=async e=>{c(null);try{await e()}catch(e){c(e.message)}finally{await l()}};return{busy:r,error:s,readOnly:t,upload:async(t,n)=>{i(!0),await u(async()=>{for(let r of n)await a.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await l()}),i(!1)},describe:(t,n)=>u(()=>a.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>u(()=>a.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>u(()=>a.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>u(()=>a.put(`/api/studio/projects/${e}/files/order`,{kind:t,ids:n}))}}function V(e,t){let n=`wz.layout.${e}`,[r,i]=(0,I.useState)(()=>{try{let e=localStorage.getItem(n);return e===`list`||e===`cards`?e:t}catch{return t}});return[r,()=>i(e=>{let t=e===`list`?`cards`:`list`;try{localStorage.setItem(n,t)}catch{}return t})]}function H(e,t,n=700){let[r,i]=(0,I.useState)(`idle`),[a,o]=(0,I.useState)(null),s=JSON.stringify(e),c=(0,I.useRef)(s),l=(0,I.useRef)({value:e,json:s,save:t});l.current={value:e,json:s,save:t};let u=(0,I.useRef)(Promise.resolve()),d=(0,I.useCallback)(()=>{let e=l.current;e.json!==c.current&&(c.current=e.json,i(`saving`),u.current=u.current.then(async()=>{try{await e.save(e.value),o(null),i(`saved`)}catch(e){c.current=``,o(e.message),i(`error`)}}))},[]);return(0,I.useEffect)(()=>{if(s===c.current)return;let e=setTimeout(d,n);return()=>clearTimeout(e)},[s,n,d]),(0,I.useEffect)(()=>d,[d]),{state:r,error:a}}function U(e){return e<1e6?`${Math.max(1,Math.round(e/1e3))} KB`:`${(e/1e6).toFixed(1)} MB`}var W=e(n(),1);function G({id:e,children:t}){return(0,W.jsx)(`div`,{id:e,className:`scroll-mt-24 max-md:scroll-mt-36`,children:t})}function K({title:e,hint:t,save:n,action:r,locked:i,plain:a,children:o}){return(0,W.jsxs)(`section`,{className:`flex flex-col gap-2.5`,children:[(0,W.jsxs)(`div`,{className:`flex items-start justify-between gap-4 px-1`,children:[(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,W.jsx)(`h2`,{className:`font-display font-semibold text-lg leading-tight`,children:e}),n?.state===`saving`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[12px] text-ink-3`,children:[(0,W.jsx)(m,{className:`size-3`}),` `,x(`project.saving`)]}):n?.state===`saved`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[12px] text-moss`,children:[(0,W.jsx)(c,{className:`size-3.5`}),` `,x(`settings.saved`)]}):null]}),t?(0,W.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-snug`,children:t}):null]}),r?(0,W.jsx)(`div`,{className:`shrink-0`,children:r}):null]}),a?o:(0,W.jsxs)(ee,{className:`p-5`,children:[i?(0,W.jsx)(`fieldset`,{disabled:!0,className:`min-w-0`,children:o}):o,n?.state===`error`&&n.error?(0,W.jsx)(`p`,{className:`mt-4 text-[14px] text-rose`,children:n.error}):null]})]})}function q({children:e,layout:t,onToggle:n}){return(0,W.jsxs)(`div`,{className:`mb-3 flex items-start gap-2`,children:[(0,W.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,W.jsx)(`div`,{className:`w-56 max-w-full transition-[width] duration-200 focus-within:w-full has-[input:not(:placeholder-shown)]:w-full`,children:e})}),(0,W.jsx)(_,{label:x(t===`list`?`project.viewCards`:`project.viewList`),onClick:n,children:t===`list`?(0,W.jsx)(te,{className:`size-4`}):(0,W.jsx)(F,{className:`size-4`})})]})}function J({value:e,onChange:t,onEnter:n,placeholder:r,busy:i}){return(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(l,{className:`-translate-y-1/2 pointer-events-none absolute top-1/2 left-3 size-4 text-ink-4`}),(0,W.jsx)(`input`,{type:`search`,value:e,placeholder:r,onChange:e=>t(e.target.value),onKeyDown:e=>e.key===`Enter`&&n?.(),className:`h-9 w-full rounded-lg border border-input bg-card pr-3 pl-9 text-[14px] text-ink outline-none transition placeholder:text-ink-4 focus:border-focus focus:ring-4 focus:ring-focus-glow`}),i?(0,W.jsx)(m,{className:`-translate-y-1/2 absolute top-1/2 right-3 size-4 text-ink-3`}):null]})}function Y({onFiles:e,accept:t,multiple:n=!0,className:r,children:i}){return(0,W.jsxs)(`label`,{onDragOver:e=>{e.preventDefault(),e.currentTarget.dataset.over=`1`},onDragLeave:e=>{delete e.currentTarget.dataset.over},onDrop:t=>{t.preventDefault(),delete t.currentTarget.dataset.over;let r=Array.from(t.dataTransfer.files);r.length&&e(n?r:r.slice(0,1))},className:h(`flex cursor-pointer items-center justify-center gap-2 rounded-lg border border-input border-dashed text-[14px] text-ink-3 transition focus-within:border-focus focus-within:ring-4 focus-within:ring-focus-glow hover:border-ink-4 hover:text-ink data-[over]:border-focus data-[over]:bg-paper-2 data-[over]:text-ink`,r),children:[i,(0,W.jsx)(`input`,{className:`sr-only`,type:`file`,accept:t,multiple:n,onChange:t=>{let n=Array.from(t.target.files??[]);t.target.value=``,n.length&&e(n)}})]})}var X=`mt-1.5 text-[13px] text-ink-3`;function Z(e){let t=o(),[n,r]=(0,I.useState)(!1),i=S({mutationFn:e=>a.post(`/api/studio/account/link`,e),onSuccess:({url:e})=>{A(e),r(!0)}});return(0,I.useEffect)(()=>{if(!n)return;let e=setInterval(()=>void t.invalidateQueries({queryKey:[`me`]}),2e3),i=setTimeout(()=>r(!1),3e5);return()=>{clearInterval(e),clearTimeout(i)}},[n,t]),(0,I.useEffect)(()=>{e&&r(!1)},[e]),{link:i,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,W.jsx)(`p`,{className:`text-[13px] text-rose`,children:x(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[13px] text-ink-3`,children:[(0,W.jsx)(m,{className:`size-3.5`}),` `,x(`local.accountWaiting`)]}):null}function ne(){let e=Z(!1),{link:t}=e,[n,r]=(0,I.useState)(``);return(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex items-start gap-4 py-5 first:pt-0 last:pb-0`,children:[(0,W.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-full bg-paper-2 text-ink-2`,children:(0,W.jsx)(M,{className:`size-5`})}),(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsx)(`div`,{className:`font-medium text-[15px]`,children:x(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-relaxed`,children:x(`account.localText`)})]})]}),D.account?(0,W.jsxs)(`div`,{className:`flex flex-col gap-4 py-5 last:pb-0`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[15px]`,children:x(`account.with`)}),(0,W.jsxs)(`ul`,{className:`mt-2 flex flex-col gap-2 text-[14px] text-ink-2 leading-snug`,children:[(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(u,{className:`mt-0.5 size-4 shrink-0 text-amber`}),x(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(T,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),x(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(b,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:x(`account.signIn`)})})]}):null,D.account?(0,W.jsxs)(`form`,{className:`flex flex-col gap-3 py-5 last:pb-0`,onSubmit:e=>{e.preventDefault(),t.mutate({signup:!0,code:n.trim()||void 0})},children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[15px]`,children:x(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-relaxed`,children:x(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(y,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:x(`account.code`),"aria-label":x(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[14px]`}),(0,W.jsx)(b,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:x(`account.create`)})]}),(0,W.jsx)(Q,{...e})]}):null]})}var $={start:`account.kind.start`,monthly:`account.kind.monthly`,gift:`account.kind.gift`};function re({account:e}){let t=o(),n=Z(e.signedIn),r=S({mutationFn:()=>a.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),i=new Intl.DateTimeFormat(f,{dateStyle:`medium`});return(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3 py-5 first:pt-0`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`truncate font-medium text-[15px]`,children:e.name||e.email}),e.signedIn?(0,W.jsx)(v,{tone:`live`,children:x(`account.linked`)}):null]}),(0,W.jsx)(`div`,{className:`truncate text-[14px] text-ink-3`,children:e.email})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,W.jsxs)(b,{variant:`secondary`,onClick:()=>A(e.url),children:[x(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}),(0,W.jsxs)(b,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(C,{className:`size-4`}),` `,x(`nav.logout`)]})]})]}),e.signedIn?null:(0,W.jsxs)(`div`,{className:`flex flex-col gap-3 py-5`,children:[(0,W.jsx)(`p`,{className:`text-[14px] text-ink-2`,children:x(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(b,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:x(`account.signInAgain`)})}),(0,W.jsx)(Q,{...n})]}),e.credits===null?null:(0,W.jsxs)(`div`,{className:`py-5`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsx)(`div`,{className:`text-[13px] text-ink-3`,children:x(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[22px] tabular-nums leading-tight`,children:x(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(b,{variant:`secondary`,onClick:()=>A(`${e.url}/billing`),children:[x(`account.topUp`),` `,(0,W.jsx)(d,{className:`size-4`})]})]}),e.expiring.length?(0,W.jsx)(`ul`,{className:`mt-3 flex flex-col gap-1 text-[13px] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,W.jsxs)(`li`,{children:[x(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:i.format(new Date(e.expiresAt))}),$[e.kind]?(0,W.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,x($[e.kind])]}):null]},`${e.kind}:${e.expiresAt}`))}):null]}),(0,W.jsxs)(`div`,{className:`flex items-start gap-2.5 py-5 text-[14px] text-ink-2 leading-snug last:pb-0`,children:[(0,W.jsx)(T,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:x(`account.cloud`,{host:E(e.cloudUrl)})})]})]})}function ie({me:e,fromAccount:t}){let n=o(),[r,i]=(0,I.useState)(e.profile),s=e=>i(t=>({...t,...e})),c=H(r,async e=>{await a.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,W.jsx)(K,{title:x(`account.profile`),hint:x(`account.hint`),save:c,children:(0,W.jsxs)(`div`,{className:`flex flex-col gap-6 sm:flex-row sm:gap-8`,children:[(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col items-center gap-2 sm:w-32`,children:[(0,W.jsx)(`div`,{className:`flex size-20 items-center justify-center overflow-hidden rounded-full bg-ember-tint font-semibold text-[28px] text-ember-strong ring-1 ring-border-soft`,children:e.user.image?(0,W.jsx)(`img`,{src:e.user.image,alt:``,className:`size-full object-cover`}):k(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[12px] text-ink-3 leading-snug`,children:x(`account.initials`)})]}),(0,W.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-5`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.name`)}),(0,W.jsx)(y,{value:r.name,maxLength:80,disabled:t,onChange:e=>s({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:x(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.about`)}),(0,W.jsx)(g,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>s({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:x(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.email`)}),(0,W.jsx)(y,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>s({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.phone`)}),(0,W.jsx)(y,{type:`tel`,value:r.phone,maxLength:40,onChange:e=>s({phone:e.target.value})})]})]})]})]})})}function ae({me:e}){let t=e.mode===`managed`,n=t||!!e.account;return(0,W.jsxs)(`div`,{className:`flex flex-col gap-9`,children:[(0,W.jsx)(K,{title:x(`account.connection`),hint:x(`account.connectionHint`),children:t?(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`truncate font-medium text-[15px]`,children:e.user.name}),(0,W.jsx)(v,{tone:`live`,children:x(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[14px] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(b,{variant:`secondary`,onClick:()=>A(`${e.manageUrl}/account`),children:[x(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}):null]}):e.account?(0,W.jsx)(re,{account:e.account}):(0,W.jsx)(ne,{})}),(0,W.jsx)(ie,{me:e,fromAccount:n},n?`account`:`own`),(0,W.jsx)(K,{title:x(`account.look`),hint:x(`account.lookHint`),children:(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pb-4`,children:[(0,W.jsx)(`span`,{className:`font-medium text-[14px]`,children:x(`nav.language`)}),(0,W.jsx)(w,{tone:`surface`})]}),(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pt-4`,children:[(0,W.jsx)(`span`,{className:`font-medium text-[14px]`,children:x(`nav.theme`)}),(0,W.jsx)(O,{})]})]})})]})}export{Y as a,K as c,H as d,B as f,G as i,U as l,R as m,Q as n,q as o,V as p,Z as r,J as s,ae as t,z as u};
@@ -1 +0,0 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{t as r}from"./preload-helper-CNEI7N0N.js";import{a as i,d as a,h as o,i as s,s as c,y as l}from"./ui-gGAdXx-P.js";var u=e(t(),1),d=e(n(),1);function f(e){switch(e.group){case`Added`:return{label:`NEW`,dot:`bg-moss`};case`Fixed`:return{label:`FIXED`,dot:`bg-amber`};case`Changed`:return{label:`CHANGED`,dot:`bg-cobalt`};case`Performance`:return{label:`PERFORMANCE`,dot:`bg-ember`};case`Deploy`:return{label:`DEPLOY`,dot:`bg-ink-4`};case`Docs`:return{label:`DOCS`,dot:`bg-ink-4`};default:return{label:`OTHER`,dot:`bg-ink-4`}}}var p=e=>e.version?e.version.replace(/^v/,``):l(`about.unreleased`),m=e=>e.timestamp?new Date(e.timestamp*1e3).toISOString().slice(0,10):``,h=e=>e.charAt(0).toUpperCase()+e.slice(1);function g(e,t){let n=t.trim().toLowerCase();if(!n)return e;let r=[];for(let t of e){if(`${p(t)} ${m(t)}`.toLowerCase().includes(n)){r.push(t);continue}let e=t.commits.filter(e=>`${f(e).label} ${e.scope??``} ${e.message}`.toLowerCase().includes(n));e.length>0&&r.push({...t,commits:e})}return r}function _({open:e,onClose:t}){let[n,_]=(0,u.useState)(null),[v,y]=(0,u.useState)(``);(0,u.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./changelog-BJqo0vwQ.js`).then(e=>{t||_(e.default)}),[]),()=>{t=!0}},[e,n]),(0,u.useEffect)(()=>{e||y(``)},[e]);let b=n?g(n,v):[];return(0,d.jsxs)(s,{open:e,onClose:t,title:l(`about.changelog`),wide:!0,children:[(0,d.jsx)(`p`,{className:`-mt-3 mb-4 text-[14px] text-ink-3`,children:l(`about.changelogHint`)}),n===null?(0,d.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,d.jsx)(a,{})}):n.length===0?(0,d.jsx)(i,{children:l(`about.changelogEmpty`)}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(c,{type:`search`,value:v,placeholder:l(`about.search`),onChange:e=>y(e.target.value)}),b.length===0?(0,d.jsx)(i,{children:l(`about.noMatches`)}):null,b.map(e=>(0,d.jsxs)(`section`,{className:`mt-6`,children:[(0,d.jsxs)(`h3`,{className:`flex items-baseline gap-3 border-border-soft border-b pb-2 font-display font-semibold text-[16px]`,children:[p(e),(0,d.jsx)(`span`,{className:`font-normal font-sans text-[13px] text-ink-3 tabular-nums`,children:m(e)})]}),(0,d.jsx)(`ul`,{className:`mt-3 flex flex-col gap-2`,children:e.commits.map(e=>{let t=f(e);return(0,d.jsxs)(`li`,{className:`flex items-start gap-2.5 text-[14px]`,children:[(0,d.jsx)(`span`,{className:o(`mt-[7px] size-1.5 shrink-0 rounded-full`,t.dot)}),(0,d.jsxs)(`span`,{className:`min-w-0 text-ink-2`,children:[(0,d.jsxs)(`span`,{className:`font-semibold text-[12px] text-ink tracking-wide`,children:[t.label,e.scope?` [${e.scope}]`:``]}),` `,h(e.message),e.breaking?(0,d.jsx)(`span`,{className:`ml-1.5 rounded-full bg-rose-tint px-1.5 py-0.5 font-medium text-[12px] text-rose`,children:l(`about.breaking`)}):null]})]},e.id)})})]},e.version??`unreleased`))]})]})}export{_ as ChangelogDialog};
@@ -1 +0,0 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,d as i,i as a,n as o,nt as s}from"./api-u3nydnnp.js";import{t as c}from"./createLucideIcon-q3MZMmnf.js";import{S as l,T as u,b as d,r as f,y as p}from"./outputs-CYynzGBS.js";import{t as m}from"./chevron-down-DymW-2BP.js";import{t as h}from"./plus-Du-Jx8aI.js";import{t as g}from"./mic-Bvz4mA2j.js";import{_,d as v,h as y,o as b,y as x}from"./ui-gGAdXx-P.js";import{D as S,E as C}from"./index-CTM5iDwf.js";var w={name:`chevron-up`,size:24,node:[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]};w.node;var T=c(w),E=e(t(),1),D=!1;function O(){if(!(typeof window>`u`||D))return window.SpeechRecognition??window.webkitSpeechRecognition}var k=typeof navigator<`u`&&!!navigator.mediaDevices?.getUserMedia&&typeof MediaRecorder<`u`;function A(e,t){let n=e.trimEnd(),r=t.trim();return n&&r?`${n} ${r}`:n||r}function j(e,t){let[n,r]=(0,E.useState)(!1),[i,a]=(0,E.useState)(!1),[s,c]=(0,E.useState)(null),l=(0,E.useRef)(e);l.current=e;let u=(0,E.useRef)(t);u.current=t;let d=(0,E.useRef)(null);(0,E.useEffect)(()=>()=>d.current?.stop(),[]);let f=async()=>{let e=l.current,t;try{t=await navigator.mediaDevices.getUserMedia({audio:!0})}catch{c(`denied`);return}let n=[],i=new MediaRecorder(t);i.ondataavailable=e=>e.data.size&&n.push(e.data),i.onstop=async()=>{for(let e of t.getTracks())e.stop();d.current=null,r(!1);let s=(i.mimeType||`audio/webm`).split(`;`)[0],l=new File(n,`dictation`,{type:s});if(l.size){a(!0);try{let{text:t}=await o.upload(`/api/studio/transcribe`,l);t.trim()&&u.current(A(e,t))}catch(e){c(e.message)}finally{a(!1)}}},d.current={stop:()=>i.state!==`inactive`&&i.stop()},i.start(),r(!0)},p=e=>{let t=l.current,n=``,i=new e;i.continuous=!0,i.interimResults=!0,i.lang=_===`de`?`de-DE`:`en-US`,i.onresult=e=>{let r=``;for(let t=Math.max(0,e.resultIndex);t<e.results.length;t++){let i=e.results[t],a=i[0]?.transcript??``;i.isFinal?n=A(n,a):r+=a}u.current(A(t,A(n,r)))},i.onerror=e=>{if(e.error!==`aborted`&&e.error!==`no-speech`){if(e.error===`not-allowed`){c(`denied`);return}D=!0,k&&!n?(i.onend=null,d.current=null,f()):c(e.error)}},i.onend=()=>{d.current=null,r(!1)},d.current={stop:()=>i.stop()},i.start(),r(!0)};return{supported:!!O()||k,listening:n,processing:i,error:s,toggle:()=>{if(i)return;if(d.current){d.current.stop();return}c(null);let e=O();e?p(e):f()}}}var M=e(n(),1),N=/\.(png|jpe?g|gif|webp|avif|svg)$/i;function P(e){let t=e.filter(e=>e.type.startsWith(`image/`));return t.length?Object.fromEntries(t.map(e=>[e.name,URL.createObjectURL(e)])):void 0}function F(e){let t=e.match(/(?:^|\n\n)(?:Angehängt|Attached): ([^\n]+)$/);return t?{text:e.slice(0,t.index).trim(),names:t[1].split(`, `).filter(Boolean)}:{text:e,names:[]}}function I(e,t){if(e.name&&e.name!==`image.png`)return e;let n=e.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`,r=new Date().toISOString().slice(0,19).replace(/[-:]/g,``).replace(`T`,`-`);return new File([e],`paste-${r}${t?`-${t+1}`:``}.${n}`,{type:e.type})}function L({url:e,label:t,children:n}){return(0,M.jsxs)(`div`,{className:`group relative`,title:t,children:[(0,M.jsx)(`img`,{src:e,alt:t,width:64,height:64,className:`size-16 rounded-lg bg-paper-2 object-cover ring-1 ring-border`}),n]})}function R({names:e,previews:t,fileUrl:n}){let r=e.filter(e=>t?.[e]||n&&N.test(e)),i=e.filter(e=>!r.includes(e));return(0,M.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5`,children:[r.map(e=>{let r=t?.[e]??n?.(e)??``;return(0,M.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer`,title:e,children:(0,M.jsx)(`img`,{src:r,alt:e,className:`max-h-60 w-auto max-w-full rounded-xl bg-paper-2 object-contain ring-1 ring-border`})},e)}),i.length?(0,M.jsx)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:i.map(e=>(0,M.jsxs)(`span`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 px-2.5 py-1 text-[12px] text-ink-2`,children:[(0,M.jsx)(l,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e})]},e))}):null]})}function z(e,t){let n=s(),[i,o]=(0,E.useState)([]),[c,l]=(0,E.useState)(`idle`),[u,d]=(0,E.useState)(null),[f,p]=(0,E.useState)(null),[m,h]=(0,E.useState)(null),[g,_]=(0,E.useState)(null),v=(0,E.useRef)(null);return(0,E.useEffect)(()=>{if(e){if(v.current!==e.id){v.current=e.id,o(e.messages);return}c===`idle`&&o(t=>e.messages.length>=t.length?e.messages:t)}},[e,c]),{messages:i,phase:c,activity:f,thought:m,startedAt:g,error:u,send:async(i,s=[])=>{if(!e||!(i.trim()||s.length)||c!==`idle`)return!1;if(d(null),_(Date.now()),h(null),s.length){l(`thinking`);try{for(let t of s){let n=await fetch(r(`/api/studio/wizards/${e.id}/files/${encodeURIComponent(t.name)}`),{method:`PUT`,credentials:`include`,headers:{"content-type":t.type||`application/octet-stream`},body:t});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??n.statusText)}}}catch(t){return d(t.message),l(`idle`),_(null),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),!1}let t=`${x(`editor.attached`)}: ${s.map(e=>e.name).join(`, `)}`;i=i.trim()?`${i}\n\n${t}`:t}let u=`p-${Date.now()}`;o(e=>[...e,{id:`u-${Date.now()}`,role:`user`,content:i,previews:P(s)},{id:u,role:`assistant`,content:``,pending:!0}]),l(`thinking`),p(null);let f=!1;try{await a(`/api/studio/wizards/${e.id}/chat`,{message:i},(e,n)=>{if(e===`text`){let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:t.content+e}:t))}else if(e===`activity`)p(JSON.parse(n));else if(e===`thought`)h(JSON.parse(n));else if(e===`building`)l(`building`);else if(e===`done`){f=!0;let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:e.reply,changed:e.changed,pending:!1}:t)),e.changed&&t(e.draft,e.revision)}else e===`error`&&(f=!0,d(JSON.parse(n).message))}),f||d(x(`editor.chatBroken`))}catch(e){d(e.message)}finally{p(null),h(null),_(null),o(e=>e.filter(e=>!(e.id===u&&!e.content)).map(e=>({...e,pending:!1}))),l(`idle`),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),await n.invalidateQueries({queryKey:[`me`]})}return!0},fileUrl:t=>r(`/api/studio/wizards/${e?.id}/files/${encodeURIComponent(t)}`)}}function B(e){let[t,n]=(0,E.useState)(()=>Date.now());return(0,E.useEffect)(()=>{if(e===null)return;n(Date.now());let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),e===null?null:Math.max(0,Math.floor((t-e)/1e3))}function V(e){return e<60?`${e} s`:`${Math.floor(e/60)}:${String(e%60).padStart(2,`0`)} min`}function H({chat:e,thought:t,className:n,spinner:r=`size-3.5`}){let i=B(e.startedAt);return(0,M.jsxs)(`div`,{className:y(`min-w-0`,n),children:[(0,M.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,M.jsx)(v,{className:y(`shrink-0`,r)}),(0,M.jsx)(`span`,{className:`min-w-0 truncate`,children:e.activity??(e.phase===`building`?x(`editor.building`):x(`editor.thinking`))}),i===null?null:(0,M.jsx)(`span`,{className:`shrink-0 text-ink-4 tabular-nums`,children:V(i)})]}),t&&e.thought?(0,M.jsx)(`p`,{className:`mt-0.5 truncate pl-5.5 text-[12px] text-ink-4`,children:e.thought}):null]})}function U({message:e,fileUrl:t}){let{text:n,names:r}=F(e.content);return(0,M.jsxs)(`div`,{className:`ml-8 flex flex-col items-end gap-1.5 self-end`,children:[r.length?(0,M.jsx)(R,{names:r,previews:e.previews,fileUrl:t}):null,n?(0,M.jsx)(`div`,{className:`rounded-xl rounded-br-md bg-paper-2 px-4 py-2.5 text-[14px] leading-relaxed`,children:(0,M.jsx)(`span`,{className:`whitespace-pre-wrap`,children:n})}):null]})}function W({chat:e,avatar:t,hello:n=x(`editor.chatHello`),placeholder:r=x(`editor.composer`),changedLabel:a=`Ablauf aktualisiert`,compact:o,intro:s,closed:c,card:_}){let[w,D]=(0,E.useState)(!1),[O,k]=(0,E.useState)(``),[A,N]=(0,E.useState)([]),P=(0,E.useRef)(null),F=(0,E.useRef)(null),R=(0,E.useRef)(null),z=j(O,k);(0,E.useEffect)(()=>{P.current?.scrollTo({top:P.current.scrollHeight,behavior:`smooth`})},[e.messages,e.phase]),(0,E.useEffect)(()=>{let e=F.current;if(!e)return;let t=()=>{e.style.height=`auto`,e.style.height=O?`${Math.min(e.scrollHeight,200)}px`:``};t();let n=e.clientWidth,r=new ResizeObserver(()=>{e.clientWidth!==n&&(n=e.clientWidth,t())});return r.observe(e),()=>r.disconnect()},[O]);let B=(O.trim()||A.length>0)&&e.phase===`idle`,V=e=>N(t=>[...t.filter(t=>!e.some(e=>e.name===t.name)),...e]),[W,G]=(0,E.useState)(new Map);(0,E.useEffect)(()=>{let e=new Map(A.filter(e=>e.type.startsWith(`image/`)).map(e=>[e,URL.createObjectURL(e)]));return G(e),()=>{for(let t of e.values())URL.revokeObjectURL(t)}},[A]);let K=async()=>{if(!B)return;z.listening&&z.toggle();let t={text:O,files:A};k(``),N([]),await e.send(t.text.trim(),t.files)||(k(t.text),N(t.files))},q=!o||w,J=e.messages.at(-1);return(0,M.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[o&&(J||e.error)?(0,M.jsxs)(`button`,{type:`button`,"aria-expanded":w,"aria-label":x(`editor.thread`),onClick:()=>D(e=>!e),className:`flex items-center gap-2 px-4 pt-2.5 pb-0.5 text-left text-[13px] text-ink-3 transition hover:text-ink`,children:[!(e.error||w)&&J?.pending?(0,M.jsx)(H,{chat:e,className:`flex-1`}):(0,M.jsx)(`span`,{className:y(`min-w-0 flex-1 truncate`,e.error&&`text-rose`),children:e.error??(w?x(`editor.thread`):J?.content)}),w?(0,M.jsx)(m,{className:`size-4 shrink-0`}):(0,M.jsx)(T,{className:`size-4 shrink-0`})]}):null,(0,M.jsxs)(`div`,{ref:P,className:y(`min-h-0 flex-1 overflow-y-auto px-5 py-5`,!q&&`hidden`),children:[e.messages.length===0&&!c?s??(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(i,{kind:t,size:32,interactive:!1}),(0,M.jsx)(`p`,{className:`pt-1 text-[14px] text-ink-2 leading-relaxed`,children:n})]}):null,(0,M.jsx)(`div`,{className:`flex flex-col gap-4`,children:e.messages.map(n=>n.role===`user`?(0,M.jsx)(U,{message:n,fileUrl:e.fileUrl},n.id):(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(`div`,{className:`shrink-0`,children:(0,M.jsx)(i,{kind:t,size:28,interactive:!1})}),(0,M.jsxs)(`div`,{className:`min-w-0 pt-0.5 text-[14px]`,children:[n.source===`mcp`?(0,M.jsxs)(`div`,{className:`mb-1 inline-flex items-center gap-1.5 text-[12px] text-ink-3`,children:[(0,M.jsx)(S,{className:`size-3`}),` `,x(`editor.viaClient`,{client:n.client??`MCP`})]}):null,n.content?(0,M.jsx)(f,{text:n.content,className:`text-[14px]`}):null,_&&n.cards?.length?(0,M.jsx)(`div`,{className:`mt-2 flex flex-col gap-2`,children:n.cards.map(e=>(0,M.jsx)(E.Fragment,{children:_(e)},e.id))}):null,n.pending?(0,M.jsx)(H,{chat:e,thought:!0,className:`mt-1 text-[13px] text-ink-3`}):null,n.changed?(0,M.jsxs)(`div`,{className:`mt-2 inline-flex items-center gap-1.5 rounded-full bg-ember-tint px-2.5 py-0.5 text-[12px] text-ember-strong`,children:[(0,M.jsx)(d,{className:`size-3`}),` `,a]}):null]})]},n.id))}),e.error?(0,M.jsx)(`div`,{className:`mt-4 rounded-lg bg-rose-tint px-3 py-2 text-[13px] text-rose`,children:e.error}):null]}),c?(0,M.jsx)(`p`,{className:`m-3 rounded-xl bg-paper-2 px-4 py-3 text-[13px] text-ink-2 leading-relaxed`,children:c}):(0,M.jsxs)(`div`,{className:o?`p-2`:`p-3`,children:[(0,M.jsxs)(`div`,{className:`rounded-xl bg-card p-1.5 shadow-soft ring-1 ring-border focus-within:ring-focus`,children:[W.size?(0,M.jsx)(`div`,{className:`flex flex-wrap gap-2 px-1 pt-1 pb-1.5`,children:A.map((e,t)=>{let n=W.get(e);return n?(0,M.jsx)(L,{url:n,label:e.name,children:(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>N(e=>e.filter((e,n)=>n!==t)),className:`-top-1.5 -right-1.5 absolute flex size-5 items-center justify-center rounded-full bg-ink text-paper opacity-0 shadow-soft transition focus-visible:opacity-100 group-hover:opacity-100`,children:(0,M.jsx)(C,{className:`size-3`})})},`${e.name}-${t}`):null})}):null,A.some(e=>!W.has(e))?(0,M.jsx)(`ul`,{className:`flex flex-wrap gap-1.5 px-1 pt-1 pb-1.5`,children:A.map((e,t)=>W.has(e)?null:(0,M.jsxs)(`li`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 py-1 pr-1 pl-2.5 text-[12px] text-ink-2`,children:[(0,M.jsx)(l,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e.name}),(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>N(e=>e.filter((e,n)=>n!==t)),className:`inline-flex size-5 shrink-0 items-center justify-center rounded-full text-ink-3 hover:bg-paper-3 hover:text-ink`,children:(0,M.jsx)(C,{className:`size-3`})})]},`${e.name}-${t}`))}):null,(0,M.jsxs)(`div`,{className:`flex items-end gap-1`,children:[(0,M.jsx)(b,{label:x(`editor.attach`),onClick:()=>R.current?.click(),children:(0,M.jsx)(h,{className:`size-4`})}),(0,M.jsx)(`input`,{ref:R,type:`file`,multiple:!0,hidden:!0,onChange:e=>{let t=Array.from(e.target.files??[]);e.target.value=``,V(t)}}),(0,M.jsx)(`textarea`,{ref:F,rows:1,value:O,onChange:e=>k(e.target.value),onPaste:e=>{let t=Array.from(e.clipboardData.files);t.length&&(e.preventDefault(),V(t.map(I)))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),K())},placeholder:z.listening?x(`editor.listening`):r,className:`max-h-[200px] min-h-[40px] flex-1 resize-none bg-transparent px-1.5 py-2 text-[14px] outline-none placeholder:text-ink-4`}),z.supported?(0,M.jsx)(b,{label:z.processing?x(`editor.transcribing`):z.listening?x(`editor.voiceStop`):x(`editor.voice`),"aria-pressed":z.listening,disabled:z.processing,onClick:z.toggle,className:y(z.listening&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`),children:z.processing?(0,M.jsx)(v,{className:`size-4`}):z.listening?(0,M.jsx)(p,{className:`size-3.5 animate-pulse-dot fill-current`}):(0,M.jsx)(g,{className:`size-4`})}):null,(0,M.jsx)(`button`,{type:`button`,onClick:()=>void K(),disabled:!B,className:y(`inline-flex size-9 shrink-0 items-center justify-center rounded-full transition`,B?`bg-primary text-primary-foreground`:`bg-paper-2 text-ink-4`),"aria-label":`Send`,children:(0,M.jsx)(u,{className:`size-4`})})]})]}),z.error?(0,M.jsx)(`p`,{className:`mt-2 px-1 text-[12px] text-rose`,children:z.error===`denied`?x(`editor.micDenied`):z.error}):null]})]})}export{z as i,H as n,P as r,W as t};