wizards 0.2.16 → 0.2.17

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 (63) hide show
  1. package/apps/runtime/dist/credits/estimate.js +14 -8
  2. package/apps/runtime/dist/db/migrations/tenant/0008_run_event_note.sql +1 -0
  3. package/apps/runtime/dist/db/migrations/tenant/meta/0008_snapshot.json +2019 -0
  4. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  5. package/apps/runtime/dist/db/schema.js +2 -0
  6. package/apps/runtime/dist/engine/events.js +14 -2
  7. package/apps/runtime/dist/engine/prepare.js +5 -2
  8. package/apps/runtime/dist/engine/requirements.js +108 -0
  9. package/apps/runtime/dist/engine/runner.js +2 -2
  10. package/apps/runtime/dist/engine/steps.js +18 -10
  11. package/apps/runtime/dist/engine/template.js +13 -10
  12. package/apps/runtime/dist/routes/studio.js +2 -2
  13. package/apps/runtime/dist/services/marketplace.js +2 -2
  14. package/apps/runtime/dist/tools/browser.js +12 -6
  15. package/apps/runtime/dist/tools/index.js +12 -6
  16. package/apps/runtime/dist/tools/mail.js +5 -2
  17. package/apps/runtime/dist/tools/pages.js +1 -1
  18. package/apps/runtime/dist/tools/project.js +5 -2
  19. package/apps/runtime/dist/tools/store.js +4 -4
  20. package/apps/runtime/dist/widgets/step.js +10 -4
  21. package/apps/web/dist/assets/{Account-BE_W101C.js → Account-LVXhagaS.js} +1 -1
  22. package/apps/web/dist/assets/{ChangelogDialog-DjKQJAos.js → ChangelogDialog-DM0KAoy6.js} +1 -1
  23. package/apps/web/dist/assets/ChatPanel-CxOQmtv-.js +1 -0
  24. package/apps/web/dist/assets/CreditsDialog-DkW3YT44.js +1 -0
  25. package/apps/web/dist/assets/EditorPage-hbisE1Wf.js +2 -0
  26. package/apps/web/dist/assets/{FlowPreview-DK4RZqTW.js → FlowPreview-v7or29ku.js} +1 -1
  27. package/apps/web/dist/assets/{Harness-DcI94f1U.js → Harness-RZF-bBmb.js} +2 -2
  28. package/apps/web/dist/assets/{HomePage-BBNFgryu.js → HomePage-mxG-a_KU.js} +1 -1
  29. package/apps/web/dist/assets/{ImportWizard-BoYqovdl.js → ImportWizard-CiPyUt3E.js} +1 -1
  30. package/apps/web/dist/assets/LocalRuntime-Dqp9wkN3.js +1 -0
  31. package/apps/web/dist/assets/{NewWizardPage-tKV2S4eK.js → NewWizardPage-DHwRsi0_.js} +2 -2
  32. package/apps/web/dist/assets/ProjectPage-Bb7jN_6n.js +4 -0
  33. package/apps/web/dist/assets/PublicRunner-TGkOwbAP.js +1 -0
  34. package/apps/web/dist/assets/RunnerView-DzHGshZj.js +70 -0
  35. package/apps/web/dist/assets/SettingsPage-CG3Xtfej.js +1 -0
  36. package/apps/web/dist/assets/{SetupPage-qxHvlf87.js → SetupPage-O1GfPlqX.js} +1 -1
  37. package/apps/web/dist/assets/SharePage-CCNUhtry.js +1 -0
  38. package/apps/web/dist/assets/{api-t9_w1XNe.js → api-DB22_B7G.js} +2 -2
  39. package/apps/web/dist/assets/changelog-BkIJdZ7M.js +1 -0
  40. package/apps/web/dist/assets/{esm-D0YVMTdo.js → esm-3TT9i_rv.js} +1 -1
  41. package/apps/web/dist/assets/index-CLe9Wrpu.js +10 -0
  42. package/apps/web/dist/assets/{meta-BJHYbMh7.js → meta-CEsBCPfA.js} +1 -1
  43. package/apps/web/dist/assets/{settings-menu-BqqUAvIY.js → settings-menu-pOcjznGJ.js} +1 -1
  44. package/apps/web/dist/assets/ui-I7QYMX0F.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 +10 -0
  48. package/node_modules/@engenty-wizards/shared/dist/definition.js +25 -0
  49. package/node_modules/@engenty-wizards/shared/dist/run.d.ts +141 -0
  50. package/node_modules/@engenty-wizards/shared/dist/run.js +72 -1
  51. package/package.json +1 -1
  52. package/apps/web/dist/assets/ChatPanel-BWrcDs4s.js +0 -1
  53. package/apps/web/dist/assets/CreditsDialog-DUjR5xkl.js +0 -1
  54. package/apps/web/dist/assets/EditorPage-CrOqikP2.js +0 -2
  55. package/apps/web/dist/assets/LocalRuntime-BD8zGN8w.js +0 -1
  56. package/apps/web/dist/assets/ProjectPage-voR0hvzy.js +0 -4
  57. package/apps/web/dist/assets/PublicRunner-CYZE_hSi.js +0 -1
  58. package/apps/web/dist/assets/RunnerView-D_C7hn81.js +0 -70
  59. package/apps/web/dist/assets/SettingsPage-DguoPF_3.js +0 -1
  60. package/apps/web/dist/assets/SharePage-Cf3i7KB-.js +0 -1
  61. package/apps/web/dist/assets/changelog-kz0DmHY4.js +0 -1
  62. package/apps/web/dist/assets/index-D5w3fW1p.js +0 -10
  63. package/apps/web/dist/assets/ui-BHXO_e0e.js +0 -1
@@ -1429,5 +1429,15 @@ export interface ItemsTotals {
1429
1429
  }
1430
1430
  export declare function itemsTotals(field: Field, value: unknown, values: Record<string, unknown>): ItemsTotals;
1431
1431
  export declare function allFields(def: WizardDefinition): Field[];
1432
+ /**
1433
+ * The language a wizard speaks to people, read from its own words (titles, labels, intro).
1434
+ * A definition carries none; German where it is not clearly English.
1435
+ */
1436
+ export declare function wizardLang(def: WizardDefinition): "de" | "en";
1437
+ /** The locale amounts and dates are written in for a wizard's language. */
1438
+ export declare const LOCALES: {
1439
+ readonly de: "de-DE";
1440
+ readonly en: "en-GB";
1441
+ };
1432
1442
  /** True when this app's schema reads the definition without losing anything of it. */
1433
1443
  export declare function readable(definition: unknown): boolean;
@@ -796,6 +796,31 @@ function round2(n) {
796
796
  export function allFields(def) {
797
797
  return def.steps.flatMap((s) => (s.type === "page" ? s.fields : []));
798
798
  }
799
+ const GERMAN = /\b(und|der|die|das|ist|nicht|für|mit|ein|eine|wird|zu|dein|deine|ihr|wir|was|wie|oder)\b|[äöüß]/gi;
800
+ const ENGLISH = /\b(and|the|is|not|for|with|a|an|your|you|we|what|how|or|to|of)\b/gi;
801
+ /**
802
+ * The language a wizard speaks to people, read from its own words (titles, labels, intro).
803
+ * A definition carries none; German where it is not clearly English.
804
+ */
805
+ export function wizardLang(def) {
806
+ const text = [
807
+ def.title,
808
+ def.description,
809
+ def.intro,
810
+ ...def.steps.flatMap((s) => [
811
+ s.title,
812
+ s.description,
813
+ ...(s.type === "page" ? s.fields.flatMap((f) => [f.label, f.help, f.placeholder]) : []),
814
+ ]),
815
+ ]
816
+ .filter(Boolean)
817
+ .join(" ");
818
+ const de = text.match(GERMAN)?.length ?? 0;
819
+ const en = text.match(ENGLISH)?.length ?? 0;
820
+ return en > de ? "en" : "de";
821
+ }
822
+ /** The locale amounts and dates are written in for a wizard's language. */
823
+ export const LOCALES = { de: "de-DE", en: "en-GB" };
799
824
  // --- can this app read a definition? ---------------------------------------------------------
800
825
  // The schema drops what it does not know. A definition written for a newer app would be read
801
826
  // without complaint and run wrongly, so it counts only when nothing of it is lost.
@@ -112,12 +112,153 @@ export interface ShownList {
112
112
  formats: Format[];
113
113
  label: string | null;
114
114
  }
115
+ /**
116
+ * What a step reports while it works, in words for each language: the runtime writes the German
117
+ * line into the run's log, a runner shows it in the language the person reads.
118
+ */
119
+ export declare const RUN_NOTES: {
120
+ readonly batchDone: {
121
+ readonly de: "{done} von {total} fertig";
122
+ readonly en: "{done} of {total} done";
123
+ };
124
+ readonly editing: {
125
+ readonly de: "Bearbeitet {n} von {total}";
126
+ readonly en: "Editing {n} of {total}";
127
+ };
128
+ readonly filming: {
129
+ readonly de: "Dreht {n} von {total}";
130
+ readonly en: "Filming {n} of {total}";
131
+ };
132
+ readonly clipsRendering: {
133
+ readonly de: "{count} Clips werden gerendert – das dauert einige Minuten.";
134
+ readonly en: "Rendering {count} clips – this takes a few minutes.";
135
+ };
136
+ readonly videoRendering: {
137
+ readonly de: "Das Video wird gerendert – das dauert meist 1–3 Minuten.";
138
+ readonly en: "Rendering the video – this usually takes 1–3 minutes.";
139
+ };
140
+ readonly photo: {
141
+ readonly de: "Sieht sich Foto {n} von {total} an";
142
+ readonly en: "Looking at photo {n} of {total}";
143
+ };
144
+ readonly listen: {
145
+ readonly de: "Hört „{label}“ an …";
146
+ readonly en: "Listening to “{label}” …";
147
+ };
148
+ readonly listenFailed: {
149
+ readonly de: "„{label}“ konnte nicht verschriftlicht werden.";
150
+ readonly en: "“{label}” could not be written down.";
151
+ };
152
+ readonly filmCutting: {
153
+ readonly de: "Der Film wird geschnitten – das dauert etwa eine Minute.";
154
+ readonly en: "Cutting the film – this takes about a minute.";
155
+ };
156
+ readonly filmProgress: {
157
+ readonly de: "{pct} % geschnitten";
158
+ readonly en: "{pct} % cut";
159
+ };
160
+ readonly filmError: {
161
+ readonly de: "Der Film meldet: {detail}";
162
+ readonly en: "The film reports: {detail}";
163
+ };
164
+ readonly widgetError: {
165
+ readonly de: "Das Widget meldet einen Fehler: {detail}";
166
+ readonly en: "The widget reports an error: {detail}";
167
+ };
168
+ readonly mcpConnected: {
169
+ readonly de: "Verbunden mit {names}";
170
+ readonly en: "Connected to {names}";
171
+ };
172
+ readonly mcpUnreachable: {
173
+ readonly de: "MCP-Server nicht erreichbar: {detail}";
174
+ readonly en: "MCP server unreachable: {detail}";
175
+ };
176
+ readonly reads: {
177
+ readonly de: "Liest {name}";
178
+ readonly en: "Reading {name}";
179
+ };
180
+ readonly readsMany: {
181
+ readonly de: "Liest {count} Dokumente";
182
+ readonly en: "Reading {count} documents";
183
+ };
184
+ readonly opens: {
185
+ readonly de: "Öffnet {name}";
186
+ readonly en: "Opening {name}";
187
+ };
188
+ readonly clicks: {
189
+ readonly de: "Klickt im Browser";
190
+ readonly en: "Clicking in the browser";
191
+ };
192
+ readonly types: {
193
+ readonly de: "Tippt im Browser";
194
+ readonly en: "Typing in the browser";
195
+ };
196
+ readonly looksAtPage: {
197
+ readonly de: "Sieht sich die Seite an";
198
+ readonly en: "Looking at the page";
199
+ };
200
+ readonly waitsForSignIn: {
201
+ readonly de: "Wartet auf deine Anmeldung bei {name}";
202
+ readonly en: "Waiting for you to sign in at {name}";
203
+ };
204
+ readonly downloads: {
205
+ readonly de: "Lädt {name} herunter";
206
+ readonly en: "Downloading {name}";
207
+ };
208
+ readonly runs: {
209
+ readonly de: "Führt aus: {command}";
210
+ readonly en: "Running: {command}";
211
+ };
212
+ readonly python: {
213
+ readonly de: "Führt Python aus";
214
+ readonly en: "Running Python";
215
+ };
216
+ readonly drawing: {
217
+ readonly de: "Zeichnet ein Bild";
218
+ readonly en: "Drawing an image";
219
+ };
220
+ readonly writesPage: {
221
+ readonly de: "Schreibt die Seite „{title}“";
222
+ readonly en: "Writing the page “{title}”";
223
+ };
224
+ readonly searchesDocuments: {
225
+ readonly de: "Sucht in den Dokumenten: {query}";
226
+ readonly en: "Searching the documents: {query}";
227
+ };
228
+ readonly searchesMail: {
229
+ readonly de: "Durchsucht {label}";
230
+ readonly en: "Searching {label}";
231
+ };
232
+ readonly savesReceipts: {
233
+ readonly de: "Speichert {count} Belege aus {label}";
234
+ readonly en: "Saving {count} receipts from {label}";
235
+ };
236
+ readonly remembers: {
237
+ readonly de: "Merkt sich {title}";
238
+ readonly en: "Remembering {title}";
239
+ };
240
+ readonly files: {
241
+ readonly de: "Legt {count} Dateien ab";
242
+ readonly en: "Filing {count} files";
243
+ };
244
+ };
245
+ export type RunNoteCode = keyof typeof RUN_NOTES;
246
+ /** A line of `RUN_NOTES` with what goes into its gaps. */
247
+ export interface RunNote {
248
+ code: RunNoteCode;
249
+ params?: Record<string, string | number>;
250
+ }
251
+ /** A note in a language, its gaps filled. */
252
+ export declare function noteText(note: RunNote, lang: "de" | "en"): string;
115
253
  export interface RunEvent {
116
254
  id: number;
117
255
  at: string;
118
256
  stepId: string | null;
119
257
  type: "step_started" | "step_done" | "tool" | "info" | "error";
258
+ /** In German, as the run's log keeps it. */
120
259
  message: string;
260
+ /** The same as a note a runner shows in the person's language; null for free text. */
261
+ note?: RunNote | null;
121
262
  /** A picture of the run this is about (a photo being looked at, an image just made). */
122
263
  asset?: string | null;
123
264
  }
@@ -1 +1,72 @@
1
- export {};
1
+ /**
2
+ * What a step reports while it works, in words for each language: the runtime writes the German
3
+ * line into the run's log, a runner shows it in the language the person reads.
4
+ */
5
+ export const RUN_NOTES = {
6
+ batchDone: { de: "{done} von {total} fertig", en: "{done} of {total} done" },
7
+ editing: { de: "Bearbeitet {n} von {total}", en: "Editing {n} of {total}" },
8
+ filming: { de: "Dreht {n} von {total}", en: "Filming {n} of {total}" },
9
+ clipsRendering: {
10
+ de: "{count} Clips werden gerendert – das dauert einige Minuten.",
11
+ en: "Rendering {count} clips – this takes a few minutes.",
12
+ },
13
+ videoRendering: {
14
+ de: "Das Video wird gerendert – das dauert meist 1–3 Minuten.",
15
+ en: "Rendering the video – this usually takes 1–3 minutes.",
16
+ },
17
+ photo: { de: "Sieht sich Foto {n} von {total} an", en: "Looking at photo {n} of {total}" },
18
+ listen: { de: "Hört „{label}“ an …", en: "Listening to “{label}” …" },
19
+ listenFailed: {
20
+ de: "„{label}“ konnte nicht verschriftlicht werden.",
21
+ en: "“{label}” could not be written down.",
22
+ },
23
+ filmCutting: {
24
+ de: "Der Film wird geschnitten – das dauert etwa eine Minute.",
25
+ en: "Cutting the film – this takes about a minute.",
26
+ },
27
+ filmProgress: { de: "{pct} % geschnitten", en: "{pct} % cut" },
28
+ filmError: { de: "Der Film meldet: {detail}", en: "The film reports: {detail}" },
29
+ widgetError: {
30
+ de: "Das Widget meldet einen Fehler: {detail}",
31
+ en: "The widget reports an error: {detail}",
32
+ },
33
+ mcpConnected: { de: "Verbunden mit {names}", en: "Connected to {names}" },
34
+ mcpUnreachable: {
35
+ de: "MCP-Server nicht erreichbar: {detail}",
36
+ en: "MCP server unreachable: {detail}",
37
+ },
38
+ reads: { de: "Liest {name}", en: "Reading {name}" },
39
+ readsMany: { de: "Liest {count} Dokumente", en: "Reading {count} documents" },
40
+ opens: { de: "Öffnet {name}", en: "Opening {name}" },
41
+ clicks: { de: "Klickt im Browser", en: "Clicking in the browser" },
42
+ types: { de: "Tippt im Browser", en: "Typing in the browser" },
43
+ looksAtPage: { de: "Sieht sich die Seite an", en: "Looking at the page" },
44
+ waitsForSignIn: {
45
+ de: "Wartet auf deine Anmeldung bei {name}",
46
+ en: "Waiting for you to sign in at {name}",
47
+ },
48
+ downloads: { de: "Lädt {name} herunter", en: "Downloading {name}" },
49
+ runs: { de: "Führt aus: {command}", en: "Running: {command}" },
50
+ python: { de: "Führt Python aus", en: "Running Python" },
51
+ drawing: { de: "Zeichnet ein Bild", en: "Drawing an image" },
52
+ writesPage: { de: "Schreibt die Seite „{title}“", en: "Writing the page “{title}”" },
53
+ searchesDocuments: {
54
+ de: "Sucht in den Dokumenten: {query}",
55
+ en: "Searching the documents: {query}",
56
+ },
57
+ searchesMail: { de: "Durchsucht {label}", en: "Searching {label}" },
58
+ savesReceipts: {
59
+ de: "Speichert {count} Belege aus {label}",
60
+ en: "Saving {count} receipts from {label}",
61
+ },
62
+ remembers: { de: "Merkt sich {title}", en: "Remembering {title}" },
63
+ files: { de: "Legt {count} Dateien ab", en: "Filing {count} files" },
64
+ };
65
+ /** A note in a language, its gaps filled. */
66
+ export function noteText(note, lang) {
67
+ const line = RUN_NOTES[note.code];
68
+ if (!line) {
69
+ return "";
70
+ }
71
+ return line[lang].replace(/\{(\w+)\}/g, (gap, key) => note.params?.[key] === undefined ? gap : String(note.params[key]));
72
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wizards",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
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,d as i,i as a,n as o,nt as s}from"./api-t9_w1XNe.js";import{t as c}from"./createLucideIcon-q3MZMmnf.js";import{g as l,i as u,l as d,p as f,u as p}from"./RunnerView-D_C7hn81.js";import{t as m}from"./chevron-down-DymW-2BP.js";import{t as h}from"./plus-Du-Jx8aI.js";import{n as g}from"./video-9fDPRPCv.js";import{_,d as v,h as y,o as b,y as x}from"./ui-BHXO_e0e.js";import{j as S,k as C}from"./index-D5w3fW1p.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-[0.75rem] text-ink-2`,children:[(0,M.jsx)(f,{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-[0.75rem] 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-[0.875rem] 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-[0.8125rem] 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-[0.875rem] 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-[0.875rem]`,children:[n.source===`mcp`?(0,M.jsxs)(`div`,{className:`mb-1 inline-flex items-center gap-1.5 text-[0.75rem] text-ink-3`,children:[(0,M.jsx)(S,{className:`size-3`}),` `,x(`editor.viaClient`,{client:n.client??`MCP`})]}):null,n.content?(0,M.jsx)(u,{text:n.content,className:`text-[0.875rem]`}):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-[0.8125rem] 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-[0.75rem] text-ember-strong`,children:[(0,M.jsx)(p,{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-[0.8125rem] text-rose`,children:e.error}):null]}),c?(0,M.jsx)(`p`,{className:`m-3 rounded-xl bg-paper-2 px-4 py-3 text-[0.8125rem] 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-[0.75rem] text-ink-2`,children:[(0,M.jsx)(f,{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-[0.875rem] outline-none placeholder:truncate 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)(d,{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)(l,{className:`size-4`})})]})]}),z.error?(0,M.jsx)(`p`,{className:`mt-2 px-1 text-[0.75rem] 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};
@@ -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{t as i}from"./external-link-MAL7vJYj.js";import{_ as a,a as o,d as s,i as c,s as l,y as u}from"./ui-BHXO_e0e.js";var d=e(t(),1),f=[{name:`engenty wizards`,description:{de:`KI-Wizards aus einer Beschreibung, mit einem Link geteilt.`,en:`AI wizards built from a description, shared with a link.`},homepage:`https://github.com/engenty/engenty-wizards`,license:`FSL-1.1-MIT`},{name:`engenty`,description:{de:`Konnektoren, Datentabellen, Suche und die Engenties stammen aus dem engenty-Framework.`,en:`Connectors, data tables, search and the engenties come from the engenty framework.`},homepage:`https://github.com/engenty/engenty`,license:`FSL-1.1-MIT`}],p=[{name:`Mastra`,description:{de:`Agent-Framework hinter den KI-Schritten.`,en:`Agent framework behind the AI steps.`},homepage:`https://github.com/mastra-ai/mastra`,license:`Apache-2.0`},{name:`AI SDK`,description:{de:`Modell-Aufrufe für Text, Bild, Video und Sprache.`,en:`Model calls for text, image, video and speech.`},homepage:`https://github.com/vercel/ai`,license:`Apache-2.0`},{name:`Model Context Protocol`,description:{de:`MCP-Server zum Bauen von Wizards, MCP-Client für Werkzeuge der Schritte.`,en:`MCP server for building wizards, MCP client for the steps' tools.`},homepage:`https://github.com/modelcontextprotocol/typescript-sdk`,license:`MIT`},{name:`Hono`,description:{de:`HTTP-API der Runtime.`,en:`The runtime's HTTP API.`},homepage:`https://github.com/honojs/hono`,license:`MIT`},{name:`Drizzle ORM`,description:{de:`Schema und Migrationen der Datenbanken.`,en:`Schema and migrations of the databases.`},homepage:`https://github.com/drizzle-team/drizzle-orm`,license:`Apache-2.0`},{name:`libSQL`,description:{de:`Eine Datenbank je Mandant, lokal als Datei oder bei Turso.`,en:`One database per tenant, a local file or at Turso.`},homepage:`https://github.com/tursodatabase/libsql`,license:`MIT`},{name:`Playwright`,description:{de:`Browser-Schritte sowie PDF- und PNG-Export.`,en:`Browser steps and the PDF and PNG export.`},homepage:`https://github.com/microsoft/playwright`,license:`Apache-2.0`},{name:`agentOS`,description:{de:`Sandbox für Code-Schritte ohne Docker.`,en:`Sandbox for code steps without Docker.`},homepage:`https://github.com/rivet-dev/agentos`,license:`Apache-2.0`},{name:`React`,description:{de:`UI-Bibliothek der Web-App.`,en:`UI library of the web app.`},homepage:`https://github.com/facebook/react`,license:`MIT`},{name:`Vite`,description:{de:`Build-Werkzeug der Web-App.`,en:`Build tool of the web app.`},homepage:`https://github.com/vitejs/vite`,license:`MIT`},{name:`Tailwind CSS`,description:{de:`Styling der Oberfläche.`,en:`Styling of the interface.`},homepage:`https://github.com/tailwindlabs/tailwindcss`,license:`MIT`},{name:`React Flow`,description:{de:`Das Diagramm der Schritte im Editor.`,en:`The diagram of steps in the editor.`},homepage:`https://github.com/xyflow/xyflow`,license:`MIT`},{name:`TanStack Query`,description:{de:`Server-Daten in der Web-App.`,en:`Server data in the web app.`},homepage:`https://github.com/TanStack/query`,license:`MIT`},{name:`xterm.js`,description:{de:`Das Terminal auf der Seite, in dem sich KI-Clients anmelden.`,en:`The terminal on the page where AI clients sign in.`},homepage:`https://github.com/xtermjs/xterm.js`,license:`MIT`},{name:`Lucide`,description:{de:`Icons.`,en:`Icons.`},homepage:`https://github.com/lucide-icons/lucide`,license:`ISC`},{name:`Geist & Geist Mono`,description:{de:`Schrift der Oberfläche.`,en:`Typeface of the interface.`},homepage:`https://github.com/vercel/geist-font`,license:`OFL-1.1`},{name:`Space Grotesk`,description:{de:`Schrift der Überschriften.`,en:`Typeface of the headings.`},homepage:`https://github.com/floriankarsten/space-grotesk`,license:`OFL-1.1`},{name:`git-cliff`,description:{de:`Erzeugt den Changelog aus den Commits.`,en:`Generates the changelog from the commits.`},homepage:`https://github.com/orhun/git-cliff`,license:`MIT OR Apache-2.0`}],m=e(n(),1),h=(e,...t)=>t.some(t=>t?.toLowerCase().includes(e));function g({name:e,homepage:t,version:n,license:r,description:a}){return(0,m.jsxs)(`li`,{className:`py-2.5`,children:[(0,m.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2.5 gap-y-0.5`,children:[t?(0,m.jsxs)(`a`,{href:t,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 font-medium text-[0.875rem] text-ink underline-offset-4 hover:underline`,children:[e,(0,m.jsx)(i,{"aria-hidden":!0,className:`size-3 text-ink-4`})]}):(0,m.jsx)(`span`,{className:`font-medium text-[0.875rem] text-ink`,children:e}),n?(0,m.jsx)(`span`,{className:`text-[0.75rem] text-ink-3 tabular-nums`,children:n}):null,(0,m.jsx)(`span`,{className:`text-[0.75rem] text-ink-3`,children:r})]}),a?(0,m.jsx)(`p`,{className:`mt-0.5 text-[0.8125rem] text-ink-3`,children:a}):null]})}function _({title:e,hint:t,children:n}){return(0,m.jsxs)(`section`,{className:`mt-6`,children:[(0,m.jsx)(`h3`,{className:`border-border-soft border-b pb-2 font-display font-semibold text-[1rem]`,children:e}),t?(0,m.jsx)(`p`,{className:`mt-2 text-[0.8125rem] text-ink-3`,children:t}):null,n]})}function v({credits:e}){return(0,m.jsx)(`ul`,{className:`divide-y divide-border-soft`,children:e.map(e=>(0,m.jsx)(g,{name:e.name,homepage:e.homepage,license:e.license,description:e.description[a]},e.name))})}function y({label:e,packages:t}){return(0,m.jsxs)(`div`,{className:`mt-4`,children:[(0,m.jsx)(`h4`,{className:`font-medium text-[0.75rem] text-ink-3 tracking-wide`,children:e}),(0,m.jsx)(`ul`,{className:`divide-y divide-border-soft`,children:t.map(e=>(0,m.jsx)(g,{...e},e.name))})]})}function b({open:e,onClose:t}){let[n,i]=(0,d.useState)(null),[a,g]=(0,d.useState)(``);(0,d.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./oss-credits-CIxnNZor.js`).then(e=>{t||i(e.default)}),[]),()=>{t=!0}},[e,n]),(0,d.useEffect)(()=>{e||g(``)},[e]);let b=a.trim().toLowerCase(),x=e=>b?e.filter(e=>h(b,e.name,e.license,e.description.de,e.description.en)):e,S=e=>b?e.filter(e=>h(b,e.name,e.license,e.version)):e,C=x(f),w=x(p),T=n?[{id:`shared`,label:u(`about.creditsShared`),packages:S(n.shared)},...n.groups.map(e=>({id:e.id,label:e.label,packages:S(e.packages)}))].filter(e=>e.packages.length>0):[],E=C.length===0&&w.length===0&&T.length===0;return(0,m.jsxs)(c,{open:e,onClose:t,title:u(`about.credits`),wide:!0,children:[(0,m.jsx)(`p`,{className:`-mt-3 mb-4 text-[0.875rem] text-ink-3`,children:u(`about.creditsHint`)}),(0,m.jsx)(l,{type:`search`,value:a,placeholder:u(`about.search`),onChange:e=>g(e.target.value)}),C.length>0?(0,m.jsx)(_,{title:u(`about.creditsProduct`),children:(0,m.jsx)(v,{credits:C})}):null,w.length>0?(0,m.jsx)(_,{title:u(`about.creditsBuiltWith`),children:(0,m.jsx)(v,{credits:w})}):null,n===null?(0,m.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,m.jsx)(s,{})}):T.length>0?(0,m.jsx)(_,{title:u(`about.creditsDeps`),hint:b?void 0:u(`about.creditsDepsHint`),children:T.map(e=>(0,m.jsx)(y,{label:e.label,packages:e.packages},e.id))}):null,n!==null&&E?(0,m.jsx)(o,{children:u(`about.noMatches`)}):null]})}export{b as CreditsDialog};