wizards 0.2.26 → 0.2.27
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.
- package/apps/runtime/dist/agents/project-assistant.js +10 -1
- package/apps/runtime/dist/authoring/guide.js +7 -3
- package/apps/runtime/dist/connectors/plugin-connections.js +248 -0
- package/apps/runtime/dist/db/migrations/tenant/0010_plugin_connection.sql +15 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0010_snapshot.json +2942 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
- package/apps/runtime/dist/db/schema.js +21 -0
- package/apps/runtime/dist/engenty/connections-google/connectors/calendar.js +25 -3
- package/apps/runtime/dist/engenty/connections-microsoft/outlook.js +29 -1
- package/apps/runtime/dist/engine/input.js +10 -1
- package/apps/runtime/dist/mcp/tools.js +3 -2
- package/apps/runtime/dist/plugins/loader.js +22 -1
- package/apps/runtime/dist/plugins/registry.js +10 -0
- package/apps/runtime/dist/routes/runs.js +11 -3
- package/apps/runtime/dist/routes/studio.js +3 -1
- package/apps/runtime/dist/services/marketplace.js +134 -3
- package/apps/runtime/dist/services/runs.js +43 -15
- package/apps/runtime/dist/services/wizards.js +4 -2
- package/apps/runtime/dist/tools/plugin.js +29 -1
- package/apps/web/dist/assets/Account-DW396ig5.js +1 -0
- package/apps/web/dist/assets/{ChangelogDialog-CdtQWq0m.js → ChangelogDialog-BdZ1SmEd.js} +1 -1
- package/apps/web/dist/assets/CreditsDialog-fOYdoev3.js +1 -0
- package/apps/web/dist/assets/EditorPage-CAARFsaI.js +3 -0
- package/apps/web/dist/assets/{FlowPreview-IZcNrBJi.js → FlowPreview-U2AEnKlX.js} +1 -1
- package/apps/web/dist/assets/{Harness-Cj-k02TA.js → Harness-CtDlm_2b.js} +2 -2
- package/apps/web/dist/assets/HomePage-Bd-mkLxW.js +1 -0
- package/apps/web/dist/assets/ImportWizard-BMPGjd_t.js +1 -0
- package/apps/web/dist/assets/LocalRuntime-DjSNCRnV.js +1 -0
- package/apps/web/dist/assets/NewWizardPage-DZPcDR9i.js +2 -0
- package/apps/web/dist/assets/ProjectPage-_LAtG3tn.js +2 -0
- package/apps/web/dist/assets/PublicRunner-6Iqp0DmU.js +1 -0
- package/apps/web/dist/assets/RunDrawer-CtQoY3Ha.js +4 -0
- package/apps/web/dist/assets/RunnerView-BLOCNZaZ.js +2 -0
- package/apps/web/dist/assets/SettingsPage-Z6skBf6I.js +1 -0
- package/apps/web/dist/assets/SetupPage-4-Lic4pT.js +1 -0
- package/apps/web/dist/assets/SharePage-DfdhXxZm.js +1 -0
- package/apps/web/dist/assets/arrow-right-BOtqnsA1.js +1 -0
- package/apps/web/dist/assets/brand-CCAI9p0f.js +2 -0
- package/apps/web/dist/assets/changelog-DQM0oz9S.js +1 -0
- package/apps/web/dist/assets/circle-alert-BC6xmJ9r.js +1 -0
- package/apps/web/dist/assets/definition-D5V79jHA.js +1 -0
- package/apps/web/dist/assets/esm-FEWi61F_.js +7 -0
- package/apps/web/dist/assets/external-link-wKL1HE6G.js +1 -0
- package/apps/web/dist/assets/image-BMdSChOR.js +1 -0
- package/apps/web/dist/assets/index-BOp2fz-2.css +1 -0
- package/apps/web/dist/assets/index-YJMooz0J.js +132 -0
- package/apps/web/dist/assets/lock-BpqzLMuv.js +1 -0
- package/apps/web/dist/assets/meta-BqZ7SlZz.js +1 -0
- package/apps/web/dist/assets/pen-line-DM-u0dES.js +1 -0
- package/apps/web/dist/assets/refresh-cw-Bk7HkOIM.js +1 -0
- package/apps/web/dist/assets/settings-menu-BM_NfZfn.js +1 -0
- package/apps/web/dist/assets/star-JHzYYl5R.js +1 -0
- package/apps/web/dist/assets/trash-CdLg-Ela.js +1 -0
- package/apps/web/dist/assets/ui-8QmvuC9u.js +9 -0
- package/apps/web/dist/assets/upload-CL1R6shM.js +1 -0
- package/apps/web/dist/assets/video-BioLmXNO.js +1 -0
- package/apps/web/dist/assets/volume-2-_IOfPNCv.js +1 -0
- package/apps/web/dist/assets/wand-sparkles-DYtDQSJZ.js +1 -0
- package/apps/web/dist/index.html +4 -5
- package/apps/web/dist/mcp/flow.html +57 -57
- package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +85 -0
- package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +23 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +28 -1
- package/node_modules/@engenty-wizards/shared/dist/definition.js +85 -5
- package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +5 -0
- package/package.json +1 -1
- package/apps/web/dist/assets/Account-Cnksw5Ea.js +0 -1
- package/apps/web/dist/assets/CreditsDialog-Ti43boCN.js +0 -1
- package/apps/web/dist/assets/EditorPage-N7EzlRSj.js +0 -3
- package/apps/web/dist/assets/HomePage-bjdKkt84.js +0 -1
- package/apps/web/dist/assets/ImportWizard-DagFXYPM.js +0 -1
- package/apps/web/dist/assets/LocalRuntime-Boi_zqQJ.js +0 -1
- package/apps/web/dist/assets/NewWizardPage-DO5J8OpZ.js +0 -2
- package/apps/web/dist/assets/ProjectPage-DdG9wYsd.js +0 -2
- package/apps/web/dist/assets/PublicRunner-B4ts9rT6.js +0 -1
- package/apps/web/dist/assets/RunDrawer-LnVfCiYO.js +0 -4
- package/apps/web/dist/assets/RunnerView-DwffK7AA.js +0 -70
- package/apps/web/dist/assets/SettingsPage-Cyx_jTlp.js +0 -1
- package/apps/web/dist/assets/SetupPage-CBDD4rpC.js +0 -1
- package/apps/web/dist/assets/SharePage-70niRKaO.js +0 -1
- package/apps/web/dist/assets/api-C4M6cbpW.js +0 -10
- package/apps/web/dist/assets/arrow-right-6FyN3e7D.js +0 -1
- package/apps/web/dist/assets/changelog-COyL1B5X.js +0 -1
- package/apps/web/dist/assets/check-CUpby_J9.js +0 -1
- package/apps/web/dist/assets/chevron-down-DymW-2BP.js +0 -1
- package/apps/web/dist/assets/circle-alert-D2SCwFT-.js +0 -1
- package/apps/web/dist/assets/createLucideIcon-q3MZMmnf.js +0 -1
- package/apps/web/dist/assets/definition-DoCLtZZL.js +0 -55
- package/apps/web/dist/assets/esm-CfW8Rmtq.js +0 -7
- package/apps/web/dist/assets/external-link-MAL7vJYj.js +0 -1
- package/apps/web/dist/assets/image-CC_2mJd6.js +0 -1
- package/apps/web/dist/assets/index-CJ0YJ5HC.css +0 -1
- package/apps/web/dist/assets/index-DMKXnSf-.js +0 -10
- package/apps/web/dist/assets/lock-DZL2N67v.js +0 -1
- package/apps/web/dist/assets/meta-6jZygxJq.js +0 -1
- package/apps/web/dist/assets/pen-line-NK46C_nG.js +0 -1
- package/apps/web/dist/assets/plus-Du-Jx8aI.js +0 -1
- package/apps/web/dist/assets/refresh-cw-BNtHis1x.js +0 -1
- package/apps/web/dist/assets/settings-menu-Dph4yXbO.js +0 -1
- package/apps/web/dist/assets/star-UHmZXpjA.js +0 -1
- package/apps/web/dist/assets/trash-0IafyhZB.js +0 -1
- package/apps/web/dist/assets/ui-BS348L4M.js +0 -1
- package/apps/web/dist/assets/upload-DNRENWzQ.js +0 -1
- package/apps/web/dist/assets/video-9fDPRPCv.js +0 -1
- package/apps/web/dist/assets/volume-2-DE67_rue.js +0 -1
- package/apps/web/dist/assets/wand-sparkles-IEd4jkyn.js +0 -1
|
@@ -77,8 +77,11 @@ export interface PluginStepContext {
|
|
|
77
77
|
name: string;
|
|
78
78
|
};
|
|
79
79
|
wizard: {
|
|
80
|
+
id: string;
|
|
80
81
|
title: string;
|
|
81
82
|
};
|
|
83
|
+
/** "test": a test run from the studio. Keep what it makes apart from what real runs make. */
|
|
84
|
+
mode: "test" | "live";
|
|
82
85
|
/** Aborted when the run is cancelled. */
|
|
83
86
|
signal: AbortSignal;
|
|
84
87
|
/** Tells the person what the step is doing right now. */
|
|
@@ -453,6 +456,82 @@ export interface PluginPublicRoute {
|
|
|
453
456
|
path: string;
|
|
454
457
|
handler(request: PluginPublicRequest): unknown | Promise<unknown>;
|
|
455
458
|
}
|
|
459
|
+
/** An account a plugin connected for a space: a calendar, a mailbox. */
|
|
460
|
+
export interface PluginConnection {
|
|
461
|
+
id: string;
|
|
462
|
+
/** The space it was connected for. */
|
|
463
|
+
space: string;
|
|
464
|
+
/** The built-in connector behind it: `google-calendar`, `microsoft-outlook`. */
|
|
465
|
+
connector: string;
|
|
466
|
+
/** The account, as the provider names it: an e-mail address. */
|
|
467
|
+
label: string;
|
|
468
|
+
/** The actions it was connected for; the provider granted what they need. */
|
|
469
|
+
actions: string[];
|
|
470
|
+
createdAt: string;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Accounts a plugin connects on its own, for a space rather than for a wizard's run: the
|
|
474
|
+
* runtime's built-in connectors (Google, Microsoft, …), signed in with OAuth. The runtime keeps
|
|
475
|
+
* the tokens sealed, refreshes them, and on a local install connects Google through the linked
|
|
476
|
+
* account's Manage-App, as it does for wizards.
|
|
477
|
+
*/
|
|
478
|
+
export interface PluginConnections {
|
|
479
|
+
/** Of these connector ids, the ones a person can connect on this runtime now, with their names. */
|
|
480
|
+
available(connectors: string[]): Promise<{
|
|
481
|
+
id: string;
|
|
482
|
+
name: string;
|
|
483
|
+
}[]>;
|
|
484
|
+
/**
|
|
485
|
+
* The provider's sign-in page. Open it in a window: when the person is done, the window posts
|
|
486
|
+
* `{ type: "wizards:connected", ok }` to the studio and closes. `actions` are the connector's
|
|
487
|
+
* actions the plugin will call; only the rights they need are asked for.
|
|
488
|
+
*/
|
|
489
|
+
start(input: {
|
|
490
|
+
space: string;
|
|
491
|
+
connector: string;
|
|
492
|
+
actions: string[];
|
|
493
|
+
}): Promise<{
|
|
494
|
+
url: string;
|
|
495
|
+
}>;
|
|
496
|
+
/** What is connected for the space, the newest first. */
|
|
497
|
+
list(space: string): Promise<PluginConnection[]>;
|
|
498
|
+
/** One connection by its id, or null. */
|
|
499
|
+
get(connectionId: string): Promise<PluginConnection | null>;
|
|
500
|
+
/**
|
|
501
|
+
* Runs one of the connector's actions with the connection's account. Throws when the action
|
|
502
|
+
* is not one the connection was made for, or when the provider refuses (the account was
|
|
503
|
+
* disconnected there: connect again).
|
|
504
|
+
*/
|
|
505
|
+
call<T = unknown>(connectionId: string, action: string, input: Record<string, unknown>): Promise<T>;
|
|
506
|
+
/** Forgets the connection and its tokens. */
|
|
507
|
+
remove(connectionId: string): Promise<void>;
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* A wizard a plugin brings as a template: offered beside the marketplace's starters when a
|
|
511
|
+
* wizard is made, and to the assistant and AI apps as an example to copy.
|
|
512
|
+
*/
|
|
513
|
+
export interface PluginStarter {
|
|
514
|
+
/** Lower case, digits and `-`; the starter is known as `<plugin id>.<id>`. */
|
|
515
|
+
id: string;
|
|
516
|
+
title: string;
|
|
517
|
+
/** What it makes, in one or two sentences. */
|
|
518
|
+
description: string;
|
|
519
|
+
/** The language its texts are in. Default: German. */
|
|
520
|
+
language?: "de" | "en";
|
|
521
|
+
/** A complete wizard definition. Checked when it is registered. */
|
|
522
|
+
definition: unknown;
|
|
523
|
+
/** Workspace files it needs (widgets, sample data), by path. */
|
|
524
|
+
files?: Record<string, string | Uint8Array>;
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* What the space assistant is told when the admin talks to it from the plugin's own page (the
|
|
528
|
+
* studio half's `studio.Assistant`): what the page holds now, so it can change it with the
|
|
529
|
+
* plugin's assistant tools.
|
|
530
|
+
*/
|
|
531
|
+
export interface PluginAssistantPage {
|
|
532
|
+
/** Text for the assistant: the state of the page, in a few lines. Cut at 8,000 characters. */
|
|
533
|
+
block(space: PluginSpace): string | null | Promise<string | null>;
|
|
534
|
+
}
|
|
456
535
|
export interface PluginServerApi {
|
|
457
536
|
registerHttpRoute(route: PluginRoute): void;
|
|
458
537
|
registerTool<S extends z.ZodType>(tool: PluginTool<S>): void;
|
|
@@ -460,6 +539,8 @@ export interface PluginServerApi {
|
|
|
460
539
|
registerSpaceContext(context: PluginSpaceContext): void;
|
|
461
540
|
/** A tool of the space assistant. */
|
|
462
541
|
registerAssistantTool<S extends z.ZodType>(tool: PluginAssistantTool<S>): void;
|
|
542
|
+
/** What the space assistant is told when the admin talks to it from the plugin's own page. */
|
|
543
|
+
registerAssistantContext(context: PluginAssistantPage): void;
|
|
463
544
|
registerPublicRoute(route: PluginPublicRoute): void;
|
|
464
545
|
/** The full address of a public route for the current tenant: what to hand to whoever calls it. */
|
|
465
546
|
publicUrl(path: string): Promise<string>;
|
|
@@ -491,6 +572,10 @@ export interface PluginServerApi {
|
|
|
491
572
|
* status 503 and the code `no_model`, which a route passes on as it is.
|
|
492
573
|
*/
|
|
493
574
|
generate<T = undefined>(request: PluginGenerateRequest<T>): Promise<PluginGenerateResult<T>>;
|
|
575
|
+
/** Accounts the plugin connects for a space, through the runtime's built-in connectors. */
|
|
576
|
+
connections: PluginConnections;
|
|
577
|
+
/** A wizard the plugin brings as a template. */
|
|
578
|
+
registerStarter(starter: PluginStarter): void;
|
|
494
579
|
/** Something to undo when the plugin unloads or reloads: a timer, a socket. */
|
|
495
580
|
onUnload(dispose: () => void | Promise<void>): void;
|
|
496
581
|
}
|
|
@@ -80,6 +80,15 @@ export interface StudioSpace {
|
|
|
80
80
|
/** Synced from a local install, or on a runtime where nothing is built: shown, not changed. */
|
|
81
81
|
readOnly: boolean;
|
|
82
82
|
}
|
|
83
|
+
/** The space assistant on a plugin's page: what it says before the first message. */
|
|
84
|
+
export interface StudioAssistantProps {
|
|
85
|
+
title?: string;
|
|
86
|
+
hello?: string;
|
|
87
|
+
/** The input's placeholder: an example of what to ask. */
|
|
88
|
+
placeholder?: string;
|
|
89
|
+
/** The assistant changed something: read the page's data again. */
|
|
90
|
+
onChanged?: () => void;
|
|
91
|
+
}
|
|
83
92
|
export interface StudioMe {
|
|
84
93
|
user: {
|
|
85
94
|
id: string;
|
|
@@ -109,6 +118,20 @@ export interface StudioPluginContext {
|
|
|
109
118
|
* again when the person picks another space.
|
|
110
119
|
*/
|
|
111
120
|
useSpace(): StudioSpace | null;
|
|
121
|
+
/**
|
|
122
|
+
* A hook: where the page stands, as the trail after the logo in the top bar ("Termine /
|
|
123
|
+
* Kalender"), said there instead of a heading of the page's own. Set while the page is shown.
|
|
124
|
+
*/
|
|
125
|
+
useCrumbs(items: {
|
|
126
|
+
label: string;
|
|
127
|
+
to?: string;
|
|
128
|
+
}[]): void;
|
|
129
|
+
/**
|
|
130
|
+
* The space assistant, docked at the lower edge of a page of the plugin, as on the space page.
|
|
131
|
+
* It talks from the plugin's page: it gets what the server half's `registerAssistantContext`
|
|
132
|
+
* says and uses the plugin's assistant tools first. Place it once, anywhere in the page.
|
|
133
|
+
*/
|
|
134
|
+
Assistant: ComponentType<StudioAssistantProps>;
|
|
112
135
|
i18n: {
|
|
113
136
|
/** Takes the plugin's words and gives the function that reads them in the language in effect. */
|
|
114
137
|
register<M extends StudioMessages>(messages: M): (key: keyof M["de"] & string, vars?: Record<string, string | number>) => string;
|
|
@@ -3,7 +3,7 @@ import { type SurfaceComponent } from "./surface.js";
|
|
|
3
3
|
/** The engenty avatars a wizard can wear. Same cast as engenty's ui-core. */
|
|
4
4
|
export declare const ENGENTY_KINDS: readonly ["round", "drop", "dome", "flame", "oval", "bean", "pebble", "sprout", "tower", "wedge"];
|
|
5
5
|
export type EngentyKind = (typeof ENGENTY_KINDS)[number];
|
|
6
|
-
export declare const FIELD_KINDS: readonly ["text", "textarea", "number", "select", "multiselect", "date", "email", "url", "toggle", "color", "image", "file", "items", "connection", "list", "location", "audio", "signature"];
|
|
6
|
+
export declare const FIELD_KINDS: readonly ["text", "textarea", "number", "select", "multiselect", "date", "email", "url", "toggle", "color", "image", "file", "items", "connection", "list", "location", "audio", "signature", "slot"];
|
|
7
7
|
export type FieldKind = (typeof FIELD_KINDS)[number];
|
|
8
8
|
/**
|
|
9
9
|
* What a `location` field holds: where the person stands (from the device), a place they typed,
|
|
@@ -143,6 +143,7 @@ export declare const fieldSchema: z.ZodObject<{
|
|
|
143
143
|
location: "location";
|
|
144
144
|
audio: "audio";
|
|
145
145
|
signature: "signature";
|
|
146
|
+
slot: "slot";
|
|
146
147
|
}>;
|
|
147
148
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
148
149
|
placeholder: z.ZodOptional<z.ZodString>;
|
|
@@ -282,6 +283,7 @@ export declare const pageStepSchema: z.ZodObject<{
|
|
|
282
283
|
location: "location";
|
|
283
284
|
audio: "audio";
|
|
284
285
|
signature: "signature";
|
|
286
|
+
slot: "slot";
|
|
285
287
|
}>;
|
|
286
288
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
287
289
|
placeholder: z.ZodOptional<z.ZodString>;
|
|
@@ -952,6 +954,7 @@ export declare const stepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
952
954
|
location: "location";
|
|
953
955
|
audio: "audio";
|
|
954
956
|
signature: "signature";
|
|
957
|
+
slot: "slot";
|
|
955
958
|
}>;
|
|
956
959
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
957
960
|
placeholder: z.ZodOptional<z.ZodString>;
|
|
@@ -1873,6 +1876,7 @@ export declare const wizardSchema: z.ZodObject<{
|
|
|
1873
1876
|
location: "location";
|
|
1874
1877
|
audio: "audio";
|
|
1875
1878
|
signature: "signature";
|
|
1879
|
+
slot: "slot";
|
|
1876
1880
|
}>;
|
|
1877
1881
|
required: z.ZodOptional<z.ZodBoolean>;
|
|
1878
1882
|
placeholder: z.ZodOptional<z.ZodString>;
|
|
@@ -2563,6 +2567,29 @@ export declare function optionsFromData(ref: string, outputs: Record<string, {
|
|
|
2563
2567
|
cells: Record<string, unknown>;
|
|
2564
2568
|
}[];
|
|
2565
2569
|
}>): string[];
|
|
2570
|
+
/** An offered appointment time read on its own clock: the offset it was written with. */
|
|
2571
|
+
export interface SlotTime {
|
|
2572
|
+
/** The calendar day there: "2026-10-12". */
|
|
2573
|
+
day: string;
|
|
2574
|
+
/** The time of day there: "09:00". */
|
|
2575
|
+
time: string;
|
|
2576
|
+
/** That day and time as if it were UTC — to name the weekday and month without moving it. */
|
|
2577
|
+
wall: Date;
|
|
2578
|
+
}
|
|
2579
|
+
/**
|
|
2580
|
+
* A slot option as day and time in its own offset (the business's time zone, not the reader's).
|
|
2581
|
+
* Null when it is not an ISO 8601 date-time with an offset.
|
|
2582
|
+
*/
|
|
2583
|
+
export declare function slotTime(iso: string): SlotTime | null;
|
|
2584
|
+
/** The weekday and date of a slot's day: "Montag, 12. Oktober" / "Monday, 12 October". */
|
|
2585
|
+
export declare function slotDayText(iso: string, lang?: "de" | "en"): string;
|
|
2586
|
+
/** A chosen slot as a person reads it back: "Di 13.10.2026, 10:30" / "Tue 13/10/2026, 10:30". */
|
|
2587
|
+
export declare function slotText(iso: string, lang?: "de" | "en"): string;
|
|
2588
|
+
/**
|
|
2589
|
+
* The slot among `options` that is the same moment as `value`, written as offered — so an answer
|
|
2590
|
+
* in another offset ("…T07:00:00Z" for "…T09:00:00+02:00") picks the offered time.
|
|
2591
|
+
*/
|
|
2592
|
+
export declare function offeredSlot(value: string, options: string[]): string | undefined;
|
|
2566
2593
|
export interface ItemsTotals {
|
|
2567
2594
|
rows: Record<string, unknown>[];
|
|
2568
2595
|
net: number;
|
|
@@ -34,6 +34,7 @@ export const FIELD_KINDS = [
|
|
|
34
34
|
"location",
|
|
35
35
|
"audio",
|
|
36
36
|
"signature",
|
|
37
|
+
"slot",
|
|
37
38
|
];
|
|
38
39
|
export function isLocationValue(v) {
|
|
39
40
|
if (!v || typeof v !== "object" || Array.isArray(v)) {
|
|
@@ -146,7 +147,10 @@ export const fieldSchema = z.object({
|
|
|
146
147
|
required: z.boolean().optional(),
|
|
147
148
|
placeholder: z.string().optional(),
|
|
148
149
|
help: z.string().optional(),
|
|
149
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Choices for select / multiselect. slot: the appointment times offered, as ISO 8601 date-times
|
|
152
|
+
* with their offset ("2026-10-12T09:00:00+02:00").
|
|
153
|
+
*/
|
|
150
154
|
options: z.array(z.string()).optional(),
|
|
151
155
|
default: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]).optional(),
|
|
152
156
|
/** Line-item columns for `items`. A row's amount is the product of its number and money columns. */
|
|
@@ -185,7 +189,7 @@ export const fieldSchema = z.object({
|
|
|
185
189
|
*/
|
|
186
190
|
when: whenSchema.optional(),
|
|
187
191
|
/**
|
|
188
|
-
* select / multiselect: the choices come from earlier data — a list output
|
|
192
|
+
* select / multiselect / slot: the choices come from earlier data — a list output
|
|
189
193
|
* ("steps.<id>.<key>"), a column of a table output ("steps.<id>.<key>.<column>") or a column
|
|
190
194
|
* of a stored list ("lists.<id>.<column>"). `options` stand in while that data is empty.
|
|
191
195
|
*/
|
|
@@ -659,11 +663,20 @@ export function validateWizard(def, files) {
|
|
|
659
663
|
issues.push({ stepId: step.id, message: `Duplicate field id "${field.id}".` });
|
|
660
664
|
}
|
|
661
665
|
fieldIds.add(field.id);
|
|
662
|
-
if ((field.kind === "select" || field.kind === "multiselect") &&
|
|
666
|
+
if ((field.kind === "select" || field.kind === "multiselect" || field.kind === "slot") &&
|
|
663
667
|
!field.options?.length &&
|
|
664
668
|
!field.optionsFrom) {
|
|
665
669
|
issues.push({ stepId: step.id, message: `Field "${field.id}" needs options.` });
|
|
666
670
|
}
|
|
671
|
+
if (field.kind === "slot") {
|
|
672
|
+
const wrong = (field.options ?? []).find((o) => !slotTime(o));
|
|
673
|
+
if (wrong !== undefined) {
|
|
674
|
+
issues.push({
|
|
675
|
+
stepId: step.id,
|
|
676
|
+
message: `Field "${field.id}": "${wrong}" is not a date and time with its offset, like "2026-10-12T09:00:00+02:00".`,
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
}
|
|
667
680
|
if (field.kind === "items" && !field.columns?.length) {
|
|
668
681
|
issues.push({ stepId: step.id, message: `Field "${field.id}" needs columns.` });
|
|
669
682
|
}
|
|
@@ -880,8 +893,8 @@ export function validateWizard(def, files) {
|
|
|
880
893
|
issues.push(...conditionIssues(step.id, c));
|
|
881
894
|
}
|
|
882
895
|
if (field.optionsFrom) {
|
|
883
|
-
const problem = field.kind !== "select" && field.kind !== "multiselect"
|
|
884
|
-
? `"optionsFrom" fills the choices of a select or
|
|
896
|
+
const problem = field.kind !== "select" && field.kind !== "multiselect" && field.kind !== "slot"
|
|
897
|
+
? `"optionsFrom" fills the choices of a select, multiselect or slot; kind is "${field.kind}".`
|
|
885
898
|
: optionsFromProblem(field.optionsFrom);
|
|
886
899
|
if (problem) {
|
|
887
900
|
issues.push({ stepId: step.id, message: `Field "${field.id}": ${problem}` });
|
|
@@ -1333,6 +1346,73 @@ export function optionsFromData(ref, outputs, lists = {}) {
|
|
|
1333
1346
|
}
|
|
1334
1347
|
return [...seen];
|
|
1335
1348
|
}
|
|
1349
|
+
// ---------------------------------------------------------------------------
|
|
1350
|
+
// Appointment times
|
|
1351
|
+
const SLOT_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?(Z|[+-]\d{2}:\d{2})$/;
|
|
1352
|
+
/**
|
|
1353
|
+
* A slot option as day and time in its own offset (the business's time zone, not the reader's).
|
|
1354
|
+
* Null when it is not an ISO 8601 date-time with an offset.
|
|
1355
|
+
*/
|
|
1356
|
+
export function slotTime(iso) {
|
|
1357
|
+
const m = SLOT_RE.exec(iso.trim());
|
|
1358
|
+
if (!m) {
|
|
1359
|
+
return null;
|
|
1360
|
+
}
|
|
1361
|
+
const [, y, mo, d, h, mi] = m.map(Number);
|
|
1362
|
+
const wall = new Date(Date.UTC(y, mo - 1, d, h, mi));
|
|
1363
|
+
if (wall.getUTCMonth() !== mo - 1 ||
|
|
1364
|
+
wall.getUTCDate() !== d ||
|
|
1365
|
+
h > 23 ||
|
|
1366
|
+
mi > 59 ||
|
|
1367
|
+
!Number.isFinite(Date.parse(iso))) {
|
|
1368
|
+
return null;
|
|
1369
|
+
}
|
|
1370
|
+
return { day: `${m[1]}-${m[2]}-${m[3]}`, time: `${m[4]}:${m[5]}`, wall };
|
|
1371
|
+
}
|
|
1372
|
+
/** The weekday and date of a slot's day: "Montag, 12. Oktober" / "Monday, 12 October". */
|
|
1373
|
+
export function slotDayText(iso, lang = "de") {
|
|
1374
|
+
const slot = slotTime(iso);
|
|
1375
|
+
if (!slot) {
|
|
1376
|
+
return iso;
|
|
1377
|
+
}
|
|
1378
|
+
const locale = LOCALES[lang];
|
|
1379
|
+
const weekday = slot.wall.toLocaleDateString(locale, { weekday: "long", timeZone: "UTC" });
|
|
1380
|
+
const date = slot.wall.toLocaleDateString(locale, {
|
|
1381
|
+
day: "numeric",
|
|
1382
|
+
month: "long",
|
|
1383
|
+
timeZone: "UTC",
|
|
1384
|
+
});
|
|
1385
|
+
return `${weekday}, ${date}`;
|
|
1386
|
+
}
|
|
1387
|
+
/** A chosen slot as a person reads it back: "Di 13.10.2026, 10:30" / "Tue 13/10/2026, 10:30". */
|
|
1388
|
+
export function slotText(iso, lang = "de") {
|
|
1389
|
+
const slot = slotTime(iso);
|
|
1390
|
+
if (!slot) {
|
|
1391
|
+
return iso;
|
|
1392
|
+
}
|
|
1393
|
+
const locale = LOCALES[lang];
|
|
1394
|
+
const weekday = slot.wall
|
|
1395
|
+
.toLocaleDateString(locale, { weekday: "short", timeZone: "UTC" })
|
|
1396
|
+
.replace(/\.$/, "");
|
|
1397
|
+
const date = slot.wall.toLocaleDateString(locale, {
|
|
1398
|
+
day: "2-digit",
|
|
1399
|
+
month: "2-digit",
|
|
1400
|
+
year: "numeric",
|
|
1401
|
+
timeZone: "UTC",
|
|
1402
|
+
});
|
|
1403
|
+
return `${weekday} ${date}, ${slot.time}`;
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* The slot among `options` that is the same moment as `value`, written as offered — so an answer
|
|
1407
|
+
* in another offset ("…T07:00:00Z" for "…T09:00:00+02:00") picks the offered time.
|
|
1408
|
+
*/
|
|
1409
|
+
export function offeredSlot(value, options) {
|
|
1410
|
+
if (options.includes(value)) {
|
|
1411
|
+
return value;
|
|
1412
|
+
}
|
|
1413
|
+
const at = slotTime(value) ? Date.parse(value) : Number.NaN;
|
|
1414
|
+
return Number.isFinite(at) ? options.find((o) => slotTime(o) && Date.parse(o) === at) : undefined;
|
|
1415
|
+
}
|
|
1336
1416
|
export function itemsTotals(field, value, values) {
|
|
1337
1417
|
const rows = Array.isArray(value) ? value : [];
|
|
1338
1418
|
const numeric = (field.columns ?? []).filter((c) => c.kind !== "text");
|
|
@@ -314,4 +314,9 @@ export interface MarketplaceEntry extends MarketplaceSummary {
|
|
|
314
314
|
missing: Capability[];
|
|
315
315
|
/** What only some of its paths need and this runtime has no model for: it runs the other ways. */
|
|
316
316
|
optional: Capability[];
|
|
317
|
+
/** It comes with a plugin of this app, not from the marketplace: the plugin's id and name. */
|
|
318
|
+
plugin?: {
|
|
319
|
+
id: string;
|
|
320
|
+
name: string;
|
|
321
|
+
};
|
|
317
322
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wizards",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.27",
|
|
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-C4M6cbpW.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{c as f,f as p,g as m,h,n as g,o as ee,r as _,s as v,t as y,x as b,y as x}from"./ui-BS348L4M.js";import{F as te,K as S,V as C,f as w,o as T,p as E,u as D,x as O}from"./index-DMKXnSf-.js";import{n as k}from"./LocalRuntime-Boi_zqQJ.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=s(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=s(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=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-[0.75rem] text-ink-3`,children:[(0,W.jsx)(p,{className:`size-3`}),` `,b(`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)(c,{className:`size-3.5`}),` `,b(`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)(g,{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)(ee,{label:b(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)(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-[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)(p,{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:m(`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=o(),[n,r]=(0,I.useState)(!1),i=S({mutationFn:e=>a.post(`/api/studio/account/link`,e),onSuccess:({url:e})=>{k(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-[0.8125rem] text-rose`,children:b(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,W.jsx)(p,{className:`size-3.5`}),` `,b(`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:b(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:b(`account.localText`)})]})]}),E.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:b(`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)(u,{className:`mt-0.5 size-4 shrink-0 text-amber`}),b(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(C,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),b(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(y,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:b(`account.signIn`)})})]}):null,E.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:b(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:b(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(v,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:b(`account.code`),"aria-label":b(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[0.875rem]`}),(0,W.jsx)(y,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:b(`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(x,{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)(_,{tone:`live`,children:b(`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)(y,{variant:`secondary`,onClick:()=>k(e.url),children:[b(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}),(0,W.jsxs)(y,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(te,{className:`size-4`}),` `,b(`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:b(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(y,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:b(`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:b(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[1.375rem] tabular-nums leading-tight`,children:b(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(`${e.url}/billing`),children:[b(`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-[0.8125rem] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,W.jsxs)(`li`,{children:[b(`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:[` · `,b($[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)(C,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:b(`account.cloud`,{host:T(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:b(`account.profile`),hint:b(`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-[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`}):O(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[0.75rem] text-ink-3 leading-snug`,children:b(`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)(f,{children:b(`account.name`)}),(0,W.jsx)(v,{value:r.name,maxLength:80,disabled:t,onChange:e=>s({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:b(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.about`)}),(0,W.jsx)(h,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>s({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:b(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.email`)}),(0,W.jsx)(v,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>s({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.phone`)}),(0,W.jsx)(v,{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:b(`account.connection`),hint:b(`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)(_,{tone:`live`,children:b(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(`${e.manageUrl}/account`),children:[b(`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:b(`account.look`),hint:b(`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:b(`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:b(`nav.theme`)}),(0,W.jsx)(D,{})]})]})})]})}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};
|
|
@@ -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{a,f as o,i as s,s as c,x as l,y as u}from"./ui-BS348L4M.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[u]},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),[u,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=u.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:l(`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)(s,{open:e,onClose:t,title:l(`about.credits`),wide:!0,children:[(0,m.jsx)(`p`,{className:`-mt-3 mb-4 text-[0.875rem] text-ink-3`,children:l(`about.creditsHint`)}),(0,m.jsx)(c,{type:`search`,value:u,placeholder:l(`about.search`),onChange:e=>g(e.target.value)}),C.length>0?(0,m.jsx)(_,{title:l(`about.creditsProduct`),children:(0,m.jsx)(v,{credits:C})}):null,w.length>0?(0,m.jsx)(_,{title:l(`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)(o,{})}):T.length>0?(0,m.jsx)(_,{title:l(`about.creditsDeps`),hint:b?void 0:l(`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)(a,{children:l(`about.noMatches`)}):null]})}export{b as CreditsDialog};
|