wizards 0.2.27 → 0.2.29

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 (69) hide show
  1. package/apps/runtime/dist/authoring/guide.js +8 -2
  2. package/apps/runtime/dist/credits/estimate.js +4 -0
  3. package/apps/runtime/dist/engine/requirements.js +4 -0
  4. package/apps/runtime/dist/engine/steps.js +42 -1
  5. package/apps/runtime/dist/mcp/tools.js +2 -0
  6. package/apps/runtime/dist/routes/marketplace.js +2 -1
  7. package/apps/runtime/dist/services/marketplace.js +35 -4
  8. package/apps/runtime/dist/tools/plugin.js +49 -25
  9. package/apps/web/dist/assets/Account-BaOouMw9.js +1 -0
  10. package/apps/web/dist/assets/{ChangelogDialog-BdZ1SmEd.js → ChangelogDialog-3t_EKUPH.js} +1 -1
  11. package/apps/web/dist/assets/{CreditsDialog-fOYdoev3.js → CreditsDialog-BW-RETl-.js} +1 -1
  12. package/apps/web/dist/assets/EditorPage-DrJhgEHO.js +3 -0
  13. package/apps/web/dist/assets/{FlowPreview-U2AEnKlX.js → FlowPreview-Wu5ovKrU.js} +1 -1
  14. package/apps/web/dist/assets/{Harness-CtDlm_2b.js → Harness-Oh4MEjiK.js} +1 -1
  15. package/apps/web/dist/assets/HomePage-eYqUUwzG.js +1 -0
  16. package/apps/web/dist/assets/{ImportWizard-BMPGjd_t.js → ImportWizard-BSjp83g0.js} +1 -1
  17. package/apps/web/dist/assets/LocalRuntime-CqBfKp8q.js +1 -0
  18. package/apps/web/dist/assets/NewWizardPage-Bpqk-BwW.js +2 -0
  19. package/apps/web/dist/assets/{ProjectPage-_LAtG3tn.js → ProjectPage-SK7e8kxV.js} +2 -2
  20. package/apps/web/dist/assets/PublicRunner-Cu056QMy.js +1 -0
  21. package/apps/web/dist/assets/{RunDrawer-CtQoY3Ha.js → RunDrawer-BdcgNjPZ.js} +3 -3
  22. package/apps/web/dist/assets/RunnerView-JOMD-e27.js +2 -0
  23. package/apps/web/dist/assets/SettingsPage-BSu-2gL5.js +1 -0
  24. package/apps/web/dist/assets/SetupPage-DdWIlUCF.js +1 -0
  25. package/apps/web/dist/assets/SharePage-C5JlCg9u.js +1 -0
  26. package/apps/web/dist/assets/arrow-right-hy38IBRU.js +1 -0
  27. package/apps/web/dist/assets/changelog-C2q3P5lJ.js +1 -0
  28. package/apps/web/dist/assets/{circle-alert-BC6xmJ9r.js → circle-alert-BG9P3ewL.js} +1 -1
  29. package/apps/web/dist/assets/definition-CwX2olVF.js +1 -0
  30. package/apps/web/dist/assets/{esm-FEWi61F_.js → esm-MDvpTvd_.js} +1 -1
  31. package/apps/web/dist/assets/{external-link-wKL1HE6G.js → external-link-BwCtn1nW.js} +1 -1
  32. package/apps/web/dist/assets/{image-BMdSChOR.js → image-DG4q2P1H.js} +1 -1
  33. package/apps/web/dist/assets/index-knnf98Fv.js +78 -0
  34. package/apps/web/dist/assets/{lock-BpqzLMuv.js → lock-DH_BntP_.js} +1 -1
  35. package/apps/web/dist/assets/{meta-BqZ7SlZz.js → meta-cFJejpIa.js} +1 -1
  36. package/apps/web/dist/assets/{pen-line-DM-u0dES.js → pen-line-B1dsy3Sr.js} +1 -1
  37. package/apps/web/dist/assets/{refresh-cw-Bk7HkOIM.js → refresh-cw-B9M1g3SH.js} +1 -1
  38. package/apps/web/dist/assets/{settings-menu-BM_NfZfn.js → settings-menu-DC825gd1.js} +1 -1
  39. package/apps/web/dist/assets/{star-JHzYYl5R.js → star-axQV_3EC.js} +1 -1
  40. package/apps/web/dist/assets/surface-D7bnQtqR.js +56 -0
  41. package/apps/web/dist/assets/{trash-CdLg-Ela.js → trash-3S1_XpVa.js} +1 -1
  42. package/apps/web/dist/assets/{ui-8QmvuC9u.js → ui-BZ01zr3i.js} +1 -1
  43. package/apps/web/dist/assets/{upload-CL1R6shM.js → upload-U0i8fAW3.js} +1 -1
  44. package/apps/web/dist/assets/{video-BioLmXNO.js → video-Db4o719f.js} +1 -1
  45. package/apps/web/dist/assets/{volume-2-_IOfPNCv.js → volume-2-6f7qN_LM.js} +1 -1
  46. package/apps/web/dist/assets/{wand-sparkles-DYtDQSJZ.js → wand-sparkles-MelvBtiK.js} +1 -1
  47. package/apps/web/dist/index.html +3 -3
  48. package/apps/web/dist/mcp/flow.html +49 -49
  49. package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +15 -3
  50. package/node_modules/@engenty-wizards/shared/dist/definition.js +38 -9
  51. package/node_modules/@engenty-wizards/shared/dist/marketplace-search.js +4 -1
  52. package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +38 -1
  53. package/node_modules/@engenty-wizards/shared/dist/marketplace.js +34 -0
  54. package/package.json +1 -1
  55. package/apps/web/dist/assets/Account-DW396ig5.js +0 -1
  56. package/apps/web/dist/assets/EditorPage-CAARFsaI.js +0 -3
  57. package/apps/web/dist/assets/HomePage-Bd-mkLxW.js +0 -1
  58. package/apps/web/dist/assets/LocalRuntime-DjSNCRnV.js +0 -1
  59. package/apps/web/dist/assets/NewWizardPage-DZPcDR9i.js +0 -2
  60. package/apps/web/dist/assets/PublicRunner-6Iqp0DmU.js +0 -1
  61. package/apps/web/dist/assets/RunnerView-BLOCNZaZ.js +0 -2
  62. package/apps/web/dist/assets/SettingsPage-Z6skBf6I.js +0 -1
  63. package/apps/web/dist/assets/SetupPage-4-Lic4pT.js +0 -1
  64. package/apps/web/dist/assets/SharePage-DfdhXxZm.js +0 -1
  65. package/apps/web/dist/assets/arrow-right-BOtqnsA1.js +0 -1
  66. package/apps/web/dist/assets/brand-CCAI9p0f.js +0 -2
  67. package/apps/web/dist/assets/changelog-DQM0oz9S.js +0 -1
  68. package/apps/web/dist/assets/definition-D5V79jHA.js +0 -1
  69. package/apps/web/dist/assets/index-YJMooz0J.js +0 -132
@@ -389,7 +389,11 @@ export declare const pageStepSchema: z.ZodObject<{
389
389
  }, z.core.$strip>;
390
390
  export declare const agentStepSchema: z.ZodObject<{
391
391
  type: z.ZodLiteral<"agent">;
392
- instructions: z.ZodString;
392
+ instructions: z.ZodDefault<z.ZodString>;
393
+ call: z.ZodOptional<z.ZodObject<{
394
+ tool: z.ZodTemplateLiteral<`${string}.${string}`>;
395
+ input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
396
+ }, z.core.$strip>>;
393
397
  tools: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
394
398
  image: "image";
395
399
  web_search: "web_search";
@@ -1059,7 +1063,11 @@ export declare const stepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1059
1063
  }, z.core.$strip>>>;
1060
1064
  }, z.core.$strip>, z.ZodObject<{
1061
1065
  type: z.ZodLiteral<"agent">;
1062
- instructions: z.ZodString;
1066
+ instructions: z.ZodDefault<z.ZodString>;
1067
+ call: z.ZodOptional<z.ZodObject<{
1068
+ tool: z.ZodTemplateLiteral<`${string}.${string}`>;
1069
+ input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1070
+ }, z.core.$strip>>;
1063
1071
  tools: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
1064
1072
  image: "image";
1065
1073
  web_search: "web_search";
@@ -1981,7 +1989,11 @@ export declare const wizardSchema: z.ZodObject<{
1981
1989
  }, z.core.$strip>>>;
1982
1990
  }, z.core.$strip>, z.ZodObject<{
1983
1991
  type: z.ZodLiteral<"agent">;
1984
- instructions: z.ZodString;
1992
+ instructions: z.ZodDefault<z.ZodString>;
1993
+ call: z.ZodOptional<z.ZodObject<{
1994
+ tool: z.ZodTemplateLiteral<`${string}.${string}`>;
1995
+ input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1996
+ }, z.core.$strip>>;
1985
1997
  tools: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
1986
1998
  image: "image";
1987
1999
  web_search: "web_search";
@@ -262,17 +262,30 @@ export const pageStepSchema = z.object({
262
262
  groups: z.array(fieldGroupSchema).max(6).optional(),
263
263
  cta: z.string().optional(),
264
264
  });
265
+ /** A plugin's tool as a step names it: `<plugin>.<tool>`. */
266
+ const pluginToolIdSchema = z.templateLiteral([
267
+ z.string().regex(PLUGIN_ID),
268
+ ".",
269
+ z.string().regex(PLUGIN_TOOL_NAME),
270
+ ]);
265
271
  export const agentStepSchema = z.object({
266
272
  ...stepBase,
267
273
  type: z.literal("agent"),
268
- /** What the agent does. A template: {{field}}, {{steps.id}}, {{brand.name}}. */
269
- instructions: z.string().min(1),
270
- tools: z
271
- .array(z.union([
272
- z.enum(TOOL_IDS),
273
- z.templateLiteral([z.string().regex(PLUGIN_ID), ".", z.string().regex(PLUGIN_TOOL_NAME)]),
274
- ]))
275
- .default([]),
274
+ /** What the agent does. A template: {{field}}, {{steps.id}}, {{brand.name}}. Empty with `call`. */
275
+ instructions: z.string().default(""),
276
+ /**
277
+ * One tool of a plugin, called once with these inputs and no model: its answer is the step's
278
+ * json output, as it is. For data a later page shows unchanged (free appointment times), where
279
+ * a model would only copy it. String inputs are templates; a filled-in whole number or
280
+ * true/false is passed as one, an empty one is left out.
281
+ */
282
+ call: z
283
+ .object({
284
+ tool: pluginToolIdSchema,
285
+ input: z.record(z.string(), z.unknown()).default({}),
286
+ })
287
+ .optional(),
288
+ tools: z.array(z.union([z.enum(TOOL_IDS), pluginToolIdSchema])).default([]),
276
289
  /** Ids of project MCP servers this step may use. */
277
290
  mcp: z.array(z.string()).optional(),
278
291
  /** Ids of wizard connections (the person's accounts) this step may use. */
@@ -477,7 +490,8 @@ export const stepSchema = z.discriminatedUnion("type", [
477
490
  */
478
491
  export function isDecisionStep(step) {
479
492
  const fields = step.output.fields ?? [];
480
- return (step.model === "classifier" &&
493
+ return (!step.call &&
494
+ step.model === "classifier" &&
481
495
  step.output.format === "json" &&
482
496
  fields.length > 0 &&
483
497
  fields.every((f) => f.kind === "yesno" || f.kind === "choice" || f.kind === "score") &&
@@ -918,6 +932,21 @@ export function validateWizard(def, files) {
918
932
  }
919
933
  case "agent":
920
934
  checkTemplate(step, step.instructions);
935
+ if (step.call) {
936
+ checkTemplate(step, JSON.stringify(step.call.input));
937
+ if (step.each) {
938
+ issues.push({ stepId: step.id, message: 'A step with "call" runs once: no "each".' });
939
+ }
940
+ if (step.output.format !== "json") {
941
+ issues.push({
942
+ stepId: step.id,
943
+ message: 'A step with "call" keeps the tool\'s answer: output format "json".',
944
+ });
945
+ }
946
+ }
947
+ else if (!step.instructions.trim()) {
948
+ issues.push({ stepId: step.id, message: "An AI step needs instructions." });
949
+ }
921
950
  for (const c of step.connections ?? []) {
922
951
  if (!connectionIds.has(c)) {
923
952
  issues.push({ stepId: step.id, message: `Step uses unknown connection "${c}".` });
@@ -85,13 +85,15 @@ export function matchesFilters(e, f) {
85
85
  e.industries.includes(f.industry) ||
86
86
  (f.industry !== "any" && e.industries.includes("any"))) &&
87
87
  (!f.format || e.formats.includes(f.format)) &&
88
- (!f.capability || e.capabilities.includes(f.capability)));
88
+ (!f.capability || e.capabilities.includes(f.capability)) &&
89
+ (!f.plan || (e.plan ?? "free") === f.plan));
89
90
  }
90
91
  const FACETS = {
91
92
  useCase: (e) => e.useCases,
92
93
  industry: (e) => e.industries,
93
94
  format: (e) => e.formats,
94
95
  capability: (e) => e.capabilities,
96
+ plan: (e) => [e.plan ?? "free"],
95
97
  };
96
98
  /**
97
99
  * Per option of each filter, the found entries it would leave with the other filters as they
@@ -103,6 +105,7 @@ function facetsOf(all, found, filters) {
103
105
  industry: {},
104
106
  format: {},
105
107
  capability: {},
108
+ plan: {},
106
109
  };
107
110
  for (const key of Object.keys(FACETS)) {
108
111
  const options = new Set(all.flatMap(FACETS[key]));
@@ -1,4 +1,4 @@
1
- import type { WizardDefinition } from "./definition.js";
1
+ import { type WizardDefinition } from "./definition.js";
2
2
  /**
3
3
  * The marketplace: wizards anyone can start from. What an entry is sorted by — formats, industry,
4
4
  * use case — and what follows from its definition: the AI capabilities it needs, how much a
@@ -196,14 +196,34 @@ export declare const COST_TIERS: {
196
196
  };
197
197
  };
198
198
  export type CostTier = keyof typeof COST_TIERS;
199
+ /**
200
+ * The plan a wizard needs. Free runs on what every runtime has; Pro needs plugins, which come
201
+ * with the Pro and Team plans of engenty.ai.
202
+ */
203
+ export declare const MARKETPLACE_PLANS: {
204
+ free: {
205
+ de: string;
206
+ en: string;
207
+ };
208
+ pro: {
209
+ de: string;
210
+ en: string;
211
+ };
212
+ };
213
+ export type MarketplacePlan = keyof typeof MARKETPLACE_PLANS;
199
214
  export declare const ITEM_FORMAT_IDS: ("text" | "image" | "audio" | "video" | "document" | "dashboard" | "table")[];
200
215
  export declare const INDUSTRY_IDS: ("any" | "trades" | "gastronomy" | "hospitality" | "realEstate" | "retail" | "health" | "professional" | "agency" | "events" | "publicSector")[];
201
216
  export declare const USE_CASE_IDS: ("marketing" | "sales" | "accounting" | "service" | "research" | "hr" | "operations" | "website" | "visuals" | "inquiries" | "advice")[];
202
217
  export declare const CAPABILITY_IDS: ("code" | "text" | "image" | "browser" | "video" | "speech" | "film" | "web" | "documents" | "listening" | "connectors")[];
218
+ export declare const MARKETPLACE_PLAN_IDS: ("free" | "pro")[];
203
219
  /** The formats a run hands over, read from what the result step offers. */
204
220
  export declare function formatsOf(def: WizardDefinition): ItemFormat[];
205
221
  /** The capabilities a definition needs, read from its steps. */
206
222
  export declare function capabilitiesOf(def: WizardDefinition): Capability[];
223
+ /** The plugins a definition's steps use, by id: a runtime without one of them cannot run it. */
224
+ export declare function pluginsOf(def: WizardDefinition): string[];
225
+ /** The plan a wizard needs: Pro as soon as it uses a plugin. */
226
+ export declare const planOf: (plugins: readonly string[]) => MarketplacePlan;
207
227
  /** What a person does in a run, and about how long the whole run takes. */
208
228
  export interface Effort {
209
229
  /** Fields to fill in, the required ones of them. */
@@ -249,6 +269,18 @@ export interface MarketplaceSummary {
249
269
  steps: number;
250
270
  /** The definition version the entry's wizard is written in (`DEFINITION_VERSION`). */
251
271
  version: number;
272
+ /**
273
+ * The plugins its wizard uses, by id (`pluginsOf`). A marketplace older than this field leaves
274
+ * it out: read it as none.
275
+ */
276
+ plugins?: string[];
277
+ /** The plan it needs (`planOf`); left out by an older marketplace: free. */
278
+ plan?: MarketplacePlan;
279
+ /**
280
+ * The plugin's own starter this entry shows in the catalog, `<plugin id>.<starter id>`: a
281
+ * runtime with that plugin lists the plugin's starter instead.
282
+ */
283
+ pluginStarter?: string;
252
284
  }
253
285
  /** What a search narrows by, besides its words. */
254
286
  export interface MarketplaceFilters {
@@ -256,6 +288,7 @@ export interface MarketplaceFilters {
256
288
  industry?: Industry;
257
289
  format?: ItemFormat;
258
290
  capability?: Capability;
291
+ plan?: MarketplacePlan;
259
292
  }
260
293
  /** Per option of a filter: the entries it would leave, with the other filters as they are. */
261
294
  export interface MarketplaceFacets {
@@ -264,6 +297,8 @@ export interface MarketplaceFacets {
264
297
  format: Partial<Record<ItemFormat, number>>;
265
298
  /** Optional: a marketplace older than this filter leaves it out. */
266
299
  capability?: Partial<Record<Capability, number>>;
300
+ /** Optional: a marketplace older than this filter leaves it out. */
301
+ plan?: Partial<Record<MarketplacePlan, number>>;
267
302
  }
268
303
  /** A page of a search: the entries, best first, how many there are, and the filters' counts. */
269
304
  export interface MarketplacePage<T extends MarketplaceSummary = MarketplaceSummary> {
@@ -319,4 +354,6 @@ export interface MarketplaceEntry extends MarketplaceSummary {
319
354
  id: string;
320
355
  name: string;
321
356
  };
357
+ /** The plugins it needs that this app does not have: a wizard made from it would not run. */
358
+ needs?: string[];
322
359
  }
@@ -1,3 +1,4 @@
1
+ import { pluginToolOf } from "./definition.js";
1
2
  /**
2
3
  * The marketplace: wizards anyone can start from. What an entry is sorted by — formats, industry,
3
4
  * use case — and what follows from its definition: the AI capabilities it needs, how much a
@@ -63,11 +64,20 @@ export const COST_TIERS = {
63
64
  medium: { de: "mittel", en: "medium cost" },
64
65
  high: { de: "teuer", en: "high cost" },
65
66
  };
67
+ /**
68
+ * The plan a wizard needs. Free runs on what every runtime has; Pro needs plugins, which come
69
+ * with the Pro and Team plans of engenty.ai.
70
+ */
71
+ export const MARKETPLACE_PLANS = {
72
+ free: { de: "Kostenlos", en: "Free" },
73
+ pro: { de: "Pro", en: "Pro" },
74
+ };
66
75
  const keys = (o) => Object.keys(o);
67
76
  export const ITEM_FORMAT_IDS = keys(ITEM_FORMATS);
68
77
  export const INDUSTRY_IDS = keys(INDUSTRIES);
69
78
  export const USE_CASE_IDS = keys(USE_CASES);
70
79
  export const CAPABILITY_IDS = keys(CAPABILITIES);
80
+ export const MARKETPLACE_PLAN_IDS = keys(MARKETPLACE_PLANS);
71
81
  const FORMAT_OF = {
72
82
  pdf: "document",
73
83
  docx: "document",
@@ -119,6 +129,10 @@ export function capabilitiesOf(def) {
119
129
  }
120
130
  }
121
131
  else if (step.type === "agent") {
132
+ // A call runs no model: it needs nothing but its plugin.
133
+ if (step.call) {
134
+ continue;
135
+ }
122
136
  found.add("text");
123
137
  for (const tool of step.tools) {
124
138
  if (tool === "web_search" || tool === "web_fetch") {
@@ -164,6 +178,23 @@ export function capabilitiesOf(def) {
164
178
  }
165
179
  return CAPABILITY_IDS.filter((c) => found.has(c));
166
180
  }
181
+ /** The plugins a definition's steps use, by id: a runtime without one of them cannot run it. */
182
+ export function pluginsOf(def) {
183
+ const found = new Set();
184
+ for (const step of def.steps) {
185
+ if (step.type === "agent") {
186
+ for (const tool of step.call ? [...step.tools, step.call.tool] : step.tools) {
187
+ const of = pluginToolOf(tool);
188
+ if (of) {
189
+ found.add(of.plugin);
190
+ }
191
+ }
192
+ }
193
+ }
194
+ return [...found].sort();
195
+ }
196
+ /** The plan a wizard needs: Pro as soon as it uses a plugin. */
197
+ export const planOf = (plugins) => plugins.length ? "pro" : "free";
167
198
  const WORK_SECONDS = { agent: 25, tools: 70, browser: 150, image: 30, video: 120, voice: 20 };
168
199
  export function effortOf(def) {
169
200
  let fields = 0;
@@ -180,6 +211,9 @@ export function effortOf(def) {
180
211
  reviews += 1;
181
212
  seconds += 30;
182
213
  }
214
+ else if (step.type === "agent" && step.call) {
215
+ seconds += 1;
216
+ }
183
217
  else if (step.type === "agent") {
184
218
  seconds += step.tools.includes("browser")
185
219
  ? WORK_SECONDS.browser
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wizards",
3
- "version": "0.2.27",
3
+ "version": "0.2.29",
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{R as r,p as i}from"./brand-CCAI9p0f.js";import{D as a,G as o,H as s,c,f as l,g as u,h as d,j as f,k as p,n as m,o as h,r as g,s as _,t as v,x as y}from"./ui-8QmvuC9u.js";import{n as b,r as x}from"./upload-CL1R6shM.js";import{t as S}from"./external-link-wKL1HE6G.js";import{J as ee,Q as te,_t as C,et as w,kt as T,nt as E,tt as D,wt as O}from"./index-YJMooz0J.js";import{n as k}from"./LocalRuntime-DjSNCRnV.js";var A={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`}]]};A.node;var j=o(A),M={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`}]]};M.node;var N=o(M),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=o(P),I=e(t(),1),L=e=>[`project-files`,e];function R(e){return i({queryKey:L(e),queryFn:()=>y.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function z(e,t){return a(`/api/studio/projects/${e}/files/${t}/content`)}function B(e,t=!1){let n=r(),[i,a]=(0,I.useState)(!1),[o,s]=(0,I.useState)(null),c=()=>n.invalidateQueries({queryKey:L(e)}),l=async e=>{s(null);try{await e()}catch(e){s(e.message)}finally{await c()}};return{busy:i,error:o,readOnly:t,upload:async(t,n)=>{a(!0),await l(async()=>{for(let r of n)await y.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await c()}),a(!1)},describe:(t,n)=>l(()=>y.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>l(()=>y.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>l(()=>y.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>l(()=>y.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-[0.75rem] text-ink-3`,children:[(0,W.jsx)(l,{className:`size-3`}),` `,f(`project.saving`)]}):n?.state===`saved`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[0.75rem] text-moss`,children:[(0,W.jsx)(s,{className:`size-3.5`}),` `,f(`settings.saved`)]}):null]}),t?(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-snug`,children:t}):null]}),r?(0,W.jsx)(`div`,{className:`shrink-0`,children:r}):null]}),a?o:(0,W.jsxs)(m,{className:`p-3.5 sm: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-[0.875rem] 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)(h,{label:f(t===`list`?`project.viewCards`:`project.viewList`),onClick:n,children:t===`list`?(0,W.jsx)(N,{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)(b,{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-[0.875rem] text-ink outline-none transition placeholder:text-ink-4 focus:border-focus focus:ring-4 focus:ring-focus-glow`}),i?(0,W.jsx)(l,{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:u(`flex cursor-pointer items-center justify-center gap-2 rounded-lg border border-input border-dashed text-[0.875rem] 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-[0.8125rem] text-ink-3`;function Z(e){let t=r(),[n,i]=(0,I.useState)(!1),a=T({mutationFn:e=>y.post(`/api/studio/account/link`,e),onSuccess:({url:e})=>{k(e),i(!0)}});return(0,I.useEffect)(()=>{if(!n)return;let e=setInterval(()=>void t.invalidateQueries({queryKey:[`me`]}),2e3),r=setTimeout(()=>i(!1),3e5);return()=>{clearInterval(e),clearTimeout(r)}},[n,t]),(0,I.useEffect)(()=>{e&&i(!1)},[e]),{link:a,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,W.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:f(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,W.jsx)(l,{className:`size-3.5`}),` `,f(`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)(j,{className:`size-5`})}),(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:f(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:f(`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-[0.9375rem]`,children:f(`account.with`)}),(0,W.jsxs)(`ul`,{className:`mt-2 flex flex-col gap-2 text-[0.875rem] text-ink-2 leading-snug`,children:[(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(x,{className:`mt-0.5 size-4 shrink-0 text-amber`}),f(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),f(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(v,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:f(`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-[0.9375rem]`,children:f(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:f(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(_,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:f(`account.code`),"aria-label":f(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[0.875rem]`}),(0,W.jsx)(v,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:f(`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=r(),n=Z(e.signedIn),i=T({mutationFn:()=>y.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),a=new Intl.DateTimeFormat(p,{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-[0.9375rem]`,children:e.name||e.email}),e.signedIn?(0,W.jsx)(g,{tone:`live`,children:f(`account.linked`)}):null]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.email})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,W.jsxs)(v,{variant:`secondary`,onClick:()=>k(e.url),children:[f(`setup.openAccount`),` `,(0,W.jsx)(S,{className:`size-4`})]}),(0,W.jsxs)(v,{variant:`ghost`,busy:i.isPending,onClick:()=>i.mutate(),children:[(0,W.jsx)(C,{className:`size-4`}),` `,f(`nav.logout`)]})]})]}),e.signedIn?null:(0,W.jsxs)(`div`,{className:`flex flex-col gap-3 py-5`,children:[(0,W.jsx)(`p`,{className:`text-[0.875rem] text-ink-2`,children:f(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(v,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:f(`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-[0.8125rem] text-ink-3`,children:f(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[1.375rem] tabular-nums leading-tight`,children:f(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(v,{variant:`secondary`,onClick:()=>k(`${e.url}/billing`),children:[f(`account.topUp`),` `,(0,W.jsx)(S,{className:`size-4`})]})]}),e.expiring.length?(0,W.jsx)(`ul`,{className:`mt-3 flex flex-col gap-1 text-[0.8125rem] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,W.jsxs)(`li`,{children:[f(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:a.format(new Date(e.expiresAt))}),$[e.kind]?(0,W.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,f($[e.kind])]}):null]},`${e.kind}:${e.expiresAt}`))}):null]}),(0,W.jsxs)(`div`,{className:`flex items-start gap-2.5 py-5 text-[0.875rem] text-ink-2 leading-snug last:pb-0`,children:[(0,W.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:f(`account.cloud`,{host:ee(e.cloudUrl)})})]})]})}function ie({me:e,fromAccount:t}){let n=r(),[i,a]=(0,I.useState)(e.profile),o=e=>a(t=>({...t,...e})),s=H(i,async e=>{await y.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,W.jsx)(K,{title:f(`account.profile`),hint:f(`account.hint`),save:s,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-[1.75rem] 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`}):E(i.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[0.75rem] text-ink-3 leading-snug`,children:f(`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)(c,{children:f(`account.name`)}),(0,W.jsx)(_,{value:i.name,maxLength:80,disabled:t,onChange:e=>o({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:f(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.about`)}),(0,W.jsx)(d,{minRows:3,maxLength:2e3,value:i.about,onChange:e=>o({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:f(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.email`)}),(0,W.jsx)(_,{type:`email`,value:i.email,maxLength:200,disabled:t,onChange:e=>o({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.phone`)}),(0,W.jsx)(_,{type:`tel`,value:i.phone,maxLength:40,onChange:e=>o({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:f(`account.connection`),hint:f(`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-[0.9375rem]`,children:e.user.name}),(0,W.jsx)(g,{tone:`live`,children:f(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(v,{variant:`secondary`,onClick:()=>k(`${e.manageUrl}/account`),children:[f(`setup.openAccount`),` `,(0,W.jsx)(S,{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:f(`account.look`),hint:f(`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-[0.875rem]`,children:f(`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-[0.875rem]`,children:f(`nav.theme`)}),(0,W.jsx)(te,{})]})]})})]})}export{Y as a,K as c,H as d,B as f,N as h,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};