wizards 0.2.26 → 0.2.28
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 +5 -2
- package/apps/runtime/dist/plugins/loader.js +22 -1
- package/apps/runtime/dist/plugins/registry.js +10 -0
- package/apps/runtime/dist/routes/marketplace.js +2 -1
- 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 +167 -5
- 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-CVMSZTCv.js +1 -0
- package/apps/web/dist/assets/{ChangelogDialog-CdtQWq0m.js → ChangelogDialog-3N1CgtWP.js} +1 -1
- package/apps/web/dist/assets/CreditsDialog-BW-RETl-.js +1 -0
- package/apps/web/dist/assets/EditorPage-DnuHM3nW.js +3 -0
- package/apps/web/dist/assets/{FlowPreview-IZcNrBJi.js → FlowPreview-Ds6ul7-N.js} +1 -1
- package/apps/web/dist/assets/{Harness-Cj-k02TA.js → Harness-D-QoXcSe.js} +2 -2
- package/apps/web/dist/assets/HomePage-Ch0HlwVX.js +1 -0
- package/apps/web/dist/assets/ImportWizard-DVcYcB6l.js +1 -0
- package/apps/web/dist/assets/LocalRuntime-D7bzT40S.js +1 -0
- package/apps/web/dist/assets/NewWizardPage-DvA6AX7D.js +2 -0
- package/apps/web/dist/assets/ProjectPage-BWAISSfX.js +2 -0
- package/apps/web/dist/assets/PublicRunner-D2bd95TR.js +1 -0
- package/apps/web/dist/assets/RunDrawer-DkOCgXAR.js +4 -0
- package/apps/web/dist/assets/RunnerView-DF5uW_95.js +2 -0
- package/apps/web/dist/assets/SettingsPage-CMTGFXit.js +1 -0
- package/apps/web/dist/assets/SetupPage-BaT-VqIc.js +1 -0
- package/apps/web/dist/assets/{SharePage-70niRKaO.js → SharePage-COKOsuvD.js} +1 -1
- package/apps/web/dist/assets/arrow-right-hy38IBRU.js +1 -0
- package/apps/web/dist/assets/changelog-C8wFW63z.js +1 -0
- package/apps/web/dist/assets/circle-alert-BG9P3ewL.js +1 -0
- package/apps/web/dist/assets/definition-BiUSuZN5.js +1 -0
- package/apps/web/dist/assets/esm-0rdZWuyu.js +7 -0
- package/apps/web/dist/assets/external-link-BwCtn1nW.js +1 -0
- package/apps/web/dist/assets/image-DG4q2P1H.js +1 -0
- package/apps/web/dist/assets/index-BOp2fz-2.css +1 -0
- package/apps/web/dist/assets/index-DHM9S48l.js +78 -0
- package/apps/web/dist/assets/lock-DH_BntP_.js +1 -0
- package/apps/web/dist/assets/meta-DI0ahJ_z.js +1 -0
- package/apps/web/dist/assets/pen-line-B1dsy3Sr.js +1 -0
- package/apps/web/dist/assets/refresh-cw-B9M1g3SH.js +1 -0
- package/apps/web/dist/assets/settings-menu-DOjgaq6J.js +1 -0
- package/apps/web/dist/assets/star-axQV_3EC.js +1 -0
- package/apps/web/dist/assets/surface-BE-3Z1DP.js +56 -0
- package/apps/web/dist/assets/trash-3S1_XpVa.js +1 -0
- package/apps/web/dist/assets/ui-BZ01zr3i.js +9 -0
- package/apps/web/dist/assets/upload-U0i8fAW3.js +1 -0
- package/apps/web/dist/assets/video-Db4o719f.js +1 -0
- package/apps/web/dist/assets/volume-2-6f7qN_LM.js +1 -0
- package/apps/web/dist/assets/wand-sparkles-MelvBtiK.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-search.js +4 -1
- package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +43 -1
- package/node_modules/@engenty-wizards/shared/dist/marketplace.js +27 -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/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");
|
|
@@ -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
|
|
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> {
|
|
@@ -314,4 +349,11 @@ export interface MarketplaceEntry extends MarketplaceSummary {
|
|
|
314
349
|
missing: Capability[];
|
|
315
350
|
/** What only some of its paths need and this runtime has no model for: it runs the other ways. */
|
|
316
351
|
optional: Capability[];
|
|
352
|
+
/** It comes with a plugin of this app, not from the marketplace: the plugin's id and name. */
|
|
353
|
+
plugin?: {
|
|
354
|
+
id: string;
|
|
355
|
+
name: string;
|
|
356
|
+
};
|
|
357
|
+
/** The plugins it needs that this app does not have: a wizard made from it would not run. */
|
|
358
|
+
needs?: string[];
|
|
317
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",
|
|
@@ -164,6 +174,23 @@ export function capabilitiesOf(def) {
|
|
|
164
174
|
}
|
|
165
175
|
return CAPABILITY_IDS.filter((c) => found.has(c));
|
|
166
176
|
}
|
|
177
|
+
/** The plugins a definition's steps use, by id: a runtime without one of them cannot run it. */
|
|
178
|
+
export function pluginsOf(def) {
|
|
179
|
+
const found = new Set();
|
|
180
|
+
for (const step of def.steps) {
|
|
181
|
+
if (step.type === "agent") {
|
|
182
|
+
for (const tool of step.tools) {
|
|
183
|
+
const of = pluginToolOf(tool);
|
|
184
|
+
if (of) {
|
|
185
|
+
found.add(of.plugin);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return [...found].sort();
|
|
191
|
+
}
|
|
192
|
+
/** The plan a wizard needs: Pro as soon as it uses a plugin. */
|
|
193
|
+
export const planOf = (plugins) => plugins.length ? "pro" : "free";
|
|
167
194
|
const WORK_SECONDS = { agent: 25, tools: 70, browser: 150, image: 30, video: 120, voice: 20 };
|
|
168
195
|
export function effortOf(def) {
|
|
169
196
|
let fields = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wizards",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
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};
|