wizards 0.1.11 → 0.2.1
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/README.md +3 -0
- package/apps/runtime/dist/agents/architect.js +6 -4
- package/apps/runtime/dist/app.js +38 -4
- package/apps/runtime/dist/auth/local-ticket.js +8 -5
- package/apps/runtime/dist/authoring/guide.js +10 -2
- package/apps/runtime/dist/cli/connect.js +531 -0
- package/apps/runtime/dist/cli/environment.js +8 -1
- package/apps/runtime/dist/cli/home.js +1 -0
- package/apps/runtime/dist/cli/main.js +17 -0
- package/apps/runtime/dist/cli/mcp.js +175 -0
- package/apps/runtime/dist/cli/setup.js +49 -0
- package/apps/runtime/dist/db/client.js +13 -0
- package/apps/runtime/dist/engine/runner.js +3 -0
- package/apps/runtime/dist/env.js +18 -4
- package/apps/runtime/dist/index.js +3 -0
- package/apps/runtime/dist/mcp/auth.js +26 -0
- package/apps/runtime/dist/mcp/flow-app.js +94 -0
- package/apps/runtime/dist/mcp/handler.js +15 -5
- package/apps/runtime/dist/mcp/seen.js +65 -0
- package/apps/runtime/dist/mcp/tools.js +158 -5
- package/apps/runtime/dist/plugins/discovery.js +144 -0
- package/apps/runtime/dist/plugins/events.js +40 -0
- package/apps/runtime/dist/plugins/loader.js +277 -0
- package/apps/runtime/dist/plugins/migrations.js +69 -0
- package/apps/runtime/dist/plugins/registry.js +105 -0
- package/apps/runtime/dist/routes/plugins.js +160 -0
- package/apps/runtime/dist/routes/runs.js +7 -3
- package/apps/runtime/dist/routes/studio.js +20 -0
- package/apps/runtime/dist/secrets/signing.js +21 -3
- package/apps/runtime/dist/services/runs.js +190 -28
- package/apps/runtime/dist/services/wizards.js +30 -4
- package/apps/runtime/dist/tools/index.js +2 -0
- package/apps/runtime/dist/tools/plugin.js +43 -0
- package/apps/web/dist/assets/ChangelogDialog-Co_9fs61.js +1 -0
- package/apps/web/dist/assets/ChatPanel-Br3nYkUc.js +1 -0
- package/apps/web/dist/assets/CreditsDialog-D3fZRqXH.js +1 -0
- package/apps/web/dist/assets/EditorPage-BSjQC6FE.js +2 -0
- package/apps/web/dist/assets/FlowPreview-CjUK5046.js +1 -0
- package/apps/web/dist/assets/HomePage-8v4HqIbP.js +1 -0
- package/apps/web/dist/assets/ImportWizard-DiV62Uno.js +1 -0
- package/apps/web/dist/assets/{LocalRuntime-DKqEzptp.js → LocalRuntime-CTyLGC98.js} +2 -2
- package/apps/web/dist/assets/NewWizardPage-BBL2yenw.js +2 -0
- package/apps/web/dist/assets/PublicRunner-BwtoEVlE.js +1 -0
- package/apps/web/dist/assets/RunnerView-DOizlTad.js +2 -0
- package/apps/web/dist/assets/SettingsPage-CBDv04YS.js +2 -0
- package/apps/web/dist/assets/SetupPage-CfXTOaIm.js +1 -0
- package/apps/web/dist/assets/SharePage-CgByqrAF.js +1 -0
- package/apps/web/dist/assets/api-KMi35npD.js +10 -0
- package/apps/web/dist/assets/{arrow-left-UpjOBfQp.js → arrow-left-hTN1VoH1.js} +1 -1
- package/apps/web/dist/assets/{arrow-right-CucQycEy.js → arrow-right-6FyN3e7D.js} +1 -1
- package/apps/web/dist/assets/changelog-03JgixQA.js +1 -0
- package/apps/web/dist/assets/check-CUpby_J9.js +1 -0
- package/apps/web/dist/assets/{createLucideIcon-DBu2Ovxj.js → createLucideIcon-q3MZMmnf.js} +1 -1
- package/apps/web/dist/assets/definition-DndaH5Ow.js +55 -0
- package/apps/web/dist/assets/engenty-Cm8yZLON.js +1 -0
- package/apps/web/dist/assets/esm-rJY59Ixx.js +7 -0
- package/apps/web/dist/assets/{external-link-CRg6DVdO.js → external-link-MAL7vJYj.js} +1 -1
- package/apps/web/dist/assets/{fluffy-engenty-CJ3wCQgT.js → fluffy-engenty-D7rFrNcJ.js} +2 -2
- package/apps/web/dist/assets/index-B9YVjvVY.css +1 -0
- package/apps/web/dist/assets/index-BmpnE7IO.js +10 -0
- package/apps/web/dist/assets/jsx-runtime-D3jfb0Ew.js +1 -0
- package/apps/web/dist/assets/meta-4R1Lnr25.js +1 -0
- package/apps/web/dist/assets/{mic-CeqQ89Dj.js → mic-Bvz4mA2j.js} +1 -1
- package/apps/web/dist/assets/oss-credits-roB62QJu.js +1 -0
- package/apps/web/dist/assets/{outputs-CHe6KRLc.js → outputs-COE_nvAw.js} +2 -2
- package/apps/web/dist/assets/plug-CLjyCoHB.js +1 -0
- package/apps/web/dist/assets/{plus-HA210wXA.js → plus-Du-Jx8aI.js} +1 -1
- package/apps/web/dist/assets/react-dom-DenslgJm.js +1 -0
- package/apps/web/dist/assets/session-B6-6VomQ.js +1 -0
- package/apps/web/dist/assets/type-Bj9H3eOK.js +1 -0
- package/apps/web/dist/assets/ui-Cs6lpsmj.js +1 -0
- package/apps/web/dist/assets/{upload-DsgLfQ3U.js → upload--J5bZhEM.js} +1 -1
- package/apps/web/dist/assets/{video-Dk1fuTDl.js → video-CjgmvRDk.js} +1 -1
- package/apps/web/dist/assets/{wand-sparkles-Bf97fs8T.js → wand-sparkles-CKxArWPY.js} +1 -1
- package/apps/web/dist/index.html +10 -7
- package/apps/web/dist/mcp/flow.html +748 -0
- package/modules/README.md +15 -0
- package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +144 -0
- package/node_modules/@engenty-wizards/plugin-sdk/dist/index.js +4 -0
- package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +80 -0
- package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.js +4 -0
- package/node_modules/@engenty-wizards/plugin-sdk/package.json +10 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +18 -6
- package/node_modules/@engenty-wizards/shared/dist/definition.js +22 -1
- package/package.json +6 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/skills/use-wizard/SKILL.md +18 -0
- package/apps/web/dist/assets/ChangelogDialog-DURK75KD.js +0 -1
- package/apps/web/dist/assets/ChatPanel-DZhZJZCP.js +0 -1
- package/apps/web/dist/assets/CreditsDialog-CLUOVBLG.js +0 -1
- package/apps/web/dist/assets/EditorPage-PGCEQdiC.js +0 -2
- package/apps/web/dist/assets/FlowPreview-CqJUNW13.js +0 -1
- package/apps/web/dist/assets/HomePage-CRkDMNM2.js +0 -1
- package/apps/web/dist/assets/ImportWizard-DX1YtFPv.js +0 -1
- package/apps/web/dist/assets/NewWizardPage-BPJrYi2m.js +0 -2
- package/apps/web/dist/assets/PublicRunner-B3T244Ry.js +0 -1
- package/apps/web/dist/assets/RunnerView-DgYaOHIH.js +0 -2
- package/apps/web/dist/assets/SettingsPage-LBVqEwXs.js +0 -2
- package/apps/web/dist/assets/SetupPage-DAyJs-hK.js +0 -1
- package/apps/web/dist/assets/SharePage-oKGavxJt.js +0 -1
- package/apps/web/dist/assets/api-DbPn6Dge.js +0 -10
- package/apps/web/dist/assets/changelog-BJkYErYt.js +0 -1
- package/apps/web/dist/assets/check-Bjx41xbB.js +0 -1
- package/apps/web/dist/assets/definition-cy7uvY5L.js +0 -55
- package/apps/web/dist/assets/engenty-CWIFpgKq.js +0 -1
- package/apps/web/dist/assets/esm-ZHEGGS6s.js +0 -7
- package/apps/web/dist/assets/index-BRy5sz4a.js +0 -10
- package/apps/web/dist/assets/index-CQ_q9iMO.css +0 -1
- package/apps/web/dist/assets/jsx-runtime-Dk72oS4N.js +0 -1
- package/apps/web/dist/assets/meta-2YMHa2hT.js +0 -1
- package/apps/web/dist/assets/oss-credits-cPuZUFHD.js +0 -1
- package/apps/web/dist/assets/type-BzYgVWKL.js +0 -1
- package/apps/web/dist/assets/ui-tO4ZXbfh.js +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Modules
|
|
2
|
+
|
|
3
|
+
Plugins that ship with engenty wizards: every runtime loads what is in this folder, in a
|
|
4
|
+
checkout, in the npm package and in the Docker image. Each is a folder with an
|
|
5
|
+
`engenty.plugin.json`, as [docs/plugins.md](../docs/plugins.md) describes.
|
|
6
|
+
|
|
7
|
+
A module here is part of the open product. A plugin that is not goes into a folder of
|
|
8
|
+
`PLUGINS_DIR` instead.
|
|
9
|
+
|
|
10
|
+
- A module's server half may import what the runtime hands every plugin (the plugin SDK, `zod`,
|
|
11
|
+
`drizzle-orm`) and its own files. It has no `node_modules` of its own where it is installed.
|
|
12
|
+
- A module with a studio half is a workspace package whose `build` script is
|
|
13
|
+
`node ../../scripts/build-plugin.mjs .`, so `pnpm build` builds its `dist/`.
|
|
14
|
+
`apps/runtime/Dockerfile` copies each workspace package's `package.json` before it installs:
|
|
15
|
+
add the module's there.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { LibSQLDatabase } from "drizzle-orm/libsql";
|
|
2
|
+
import type { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* What the runtime hands a plugin's server half. A plugin is a file or a folder the runtime finds
|
|
5
|
+
* at start (docs/plugins.md); its default export is a factory that registers what it adds. The
|
|
6
|
+
* runtime remembers every registration under the plugin's id and takes it back when the plugin
|
|
7
|
+
* unloads or reloads.
|
|
8
|
+
*/
|
|
9
|
+
/** `engenty.plugin.json`, the file an engenty module has too. A plugin of one file has none. */
|
|
10
|
+
export interface PluginManifest {
|
|
11
|
+
/** Lower case, digits and `-`: part of the plugin's addresses and of its tools' ids. */
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
version: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
kind?: string;
|
|
17
|
+
provides?: string[];
|
|
18
|
+
requires?: string[];
|
|
19
|
+
/** The server half, from the plugin's folder. Default `src/plugin.ts`. */
|
|
20
|
+
server?: string;
|
|
21
|
+
/** The studio half, built. Default `dist/client.js`. */
|
|
22
|
+
studio?: string;
|
|
23
|
+
/** The studio half's styles, built. Default `dist/client.css`. */
|
|
24
|
+
styles?: string;
|
|
25
|
+
}
|
|
26
|
+
export type PluginRole = "owner" | "admin" | "member";
|
|
27
|
+
/** The signed-in person a request acts as. */
|
|
28
|
+
export interface PluginPrincipal {
|
|
29
|
+
id: string;
|
|
30
|
+
tenantId: string;
|
|
31
|
+
role: PluginRole;
|
|
32
|
+
name: string;
|
|
33
|
+
email: string;
|
|
34
|
+
}
|
|
35
|
+
export interface PluginRequest {
|
|
36
|
+
/** The web request as it came in. */
|
|
37
|
+
request: Request;
|
|
38
|
+
/** The address below the plugin's own: `/` for `/api/studio/plugins/<id>/`. */
|
|
39
|
+
path: string;
|
|
40
|
+
/** What `:name` parts of the route's path matched. */
|
|
41
|
+
params: Record<string, string>;
|
|
42
|
+
query: URLSearchParams;
|
|
43
|
+
user: PluginPrincipal;
|
|
44
|
+
/** The body as JSON; an empty body is `{}`. */
|
|
45
|
+
json<T = unknown>(): Promise<T>;
|
|
46
|
+
}
|
|
47
|
+
export type PluginHttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
48
|
+
/** A route below `/api/studio/plugins/<id>`: signed in, inside the person's tenant. */
|
|
49
|
+
export interface PluginRoute {
|
|
50
|
+
method: PluginHttpMethod;
|
|
51
|
+
/** `/`, `/items`, `/items/:id`. */
|
|
52
|
+
path: string;
|
|
53
|
+
/** `admin`: owners and admins only. Default: every member. */
|
|
54
|
+
role?: "member" | "admin";
|
|
55
|
+
/**
|
|
56
|
+
* Answers with a `Response`, or with a value that goes out as JSON. An error thrown with a
|
|
57
|
+
* `status` and a `code` goes out as `{ error, code }` with that status.
|
|
58
|
+
*/
|
|
59
|
+
handler(request: PluginRequest): unknown | Promise<unknown>;
|
|
60
|
+
}
|
|
61
|
+
/** What a tool knows about the step that calls it. */
|
|
62
|
+
export interface PluginStepContext {
|
|
63
|
+
runId: string;
|
|
64
|
+
stepId: string;
|
|
65
|
+
tenantId: string;
|
|
66
|
+
project: {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
};
|
|
70
|
+
wizard: {
|
|
71
|
+
title: string;
|
|
72
|
+
};
|
|
73
|
+
/** Aborted when the run is cancelled. */
|
|
74
|
+
signal: AbortSignal;
|
|
75
|
+
/** Tells the person what the step is doing right now. */
|
|
76
|
+
emit(message: string): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
/** A tool for agent steps. A step allowlists it as `<plugin id>.<name>`. */
|
|
79
|
+
export interface PluginTool<S extends z.ZodType = z.ZodType> {
|
|
80
|
+
/** Lower case, digits and `_`. */
|
|
81
|
+
name: string;
|
|
82
|
+
/** What the editor calls it; default: the name. */
|
|
83
|
+
title?: string;
|
|
84
|
+
/** For the model: what the tool does and when to use it. */
|
|
85
|
+
description: string;
|
|
86
|
+
inputSchema: S;
|
|
87
|
+
execute(input: z.infer<S>, ctx: PluginStepContext): unknown | Promise<unknown>;
|
|
88
|
+
}
|
|
89
|
+
/** A run that reached its end. It fires again when a finished run is redone and ends again. */
|
|
90
|
+
export interface PluginRunEvent {
|
|
91
|
+
run: {
|
|
92
|
+
id: string;
|
|
93
|
+
wizardId: string;
|
|
94
|
+
mode: "test" | "live";
|
|
95
|
+
status: "done" | "failed" | "cancelled";
|
|
96
|
+
};
|
|
97
|
+
wizard: {
|
|
98
|
+
id: string;
|
|
99
|
+
title: string;
|
|
100
|
+
projectId: string;
|
|
101
|
+
};
|
|
102
|
+
/** What the person answered, by field id. */
|
|
103
|
+
values: Record<string, unknown>;
|
|
104
|
+
}
|
|
105
|
+
export interface PluginEvents {
|
|
106
|
+
"run.done": PluginRunEvent;
|
|
107
|
+
"run.failed": PluginRunEvent;
|
|
108
|
+
"run.cancelled": PluginRunEvent;
|
|
109
|
+
}
|
|
110
|
+
/** The tenant's database. A plugin reads and writes its own tables with it. */
|
|
111
|
+
export type PluginDb = LibSQLDatabase<Record<string, never>>;
|
|
112
|
+
export interface PluginServerApi {
|
|
113
|
+
registerHttpRoute(route: PluginRoute): void;
|
|
114
|
+
registerTool<S extends z.ZodType>(tool: PluginTool<S>): void;
|
|
115
|
+
/**
|
|
116
|
+
* A folder of `.sql` files with the plugin's own tables. Every tenant database gets each file
|
|
117
|
+
* once, in the order of the file names. Nothing is taken back when the plugin unloads.
|
|
118
|
+
*/
|
|
119
|
+
registerMigrations(folder: string): void;
|
|
120
|
+
/** The listener runs inside the tenant the event belongs to. */
|
|
121
|
+
on<E extends keyof PluginEvents>(event: E, listener: (payload: PluginEvents[E]) => void | Promise<void>): void;
|
|
122
|
+
/** The database of the tenant the current request, step or event belongs to. */
|
|
123
|
+
getTenantDb(): PluginDb;
|
|
124
|
+
/** Something to undo when the plugin unloads or reloads: a timer, a socket. */
|
|
125
|
+
onUnload(dispose: () => void | Promise<void>): void;
|
|
126
|
+
}
|
|
127
|
+
export interface WizardsPluginApi {
|
|
128
|
+
plugin: PluginManifest;
|
|
129
|
+
server: PluginServerApi;
|
|
130
|
+
/** Settings of this install: its `.env`. Name them after the plugin (`NOTIFY_URL`). */
|
|
131
|
+
config: {
|
|
132
|
+
get(key: string): string | undefined;
|
|
133
|
+
};
|
|
134
|
+
log: {
|
|
135
|
+
info(...args: unknown[]): void;
|
|
136
|
+
warn(...args: unknown[]): void;
|
|
137
|
+
error(...args: unknown[]): void;
|
|
138
|
+
};
|
|
139
|
+
/** A file of the plugin as an absolute path. */
|
|
140
|
+
resolvePath(relative: string): string;
|
|
141
|
+
}
|
|
142
|
+
export type WizardsPluginFactory = (wizards: WizardsPluginApi) => void | Promise<void>;
|
|
143
|
+
/** Types the factory; it does nothing else. */
|
|
144
|
+
export declare function definePlugin(factory: WizardsPluginFactory): WizardsPluginFactory;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* What the studio hands a plugin's studio half: the built `client.js` the studio loads after
|
|
4
|
+
* sign-in. Its default export registers pages, entries of the top bar and sections of the
|
|
5
|
+
* settings. React, the router and the studio's own components come from the studio
|
|
6
|
+
* (docs/plugins.md), so the page a plugin draws is part of the same app.
|
|
7
|
+
*/
|
|
8
|
+
export type StudioLang = "de" | "en";
|
|
9
|
+
/** A plugin's words. `de` is the source: a key missing in `en` shows the German. */
|
|
10
|
+
export type StudioMessages = Record<StudioLang, Record<string, string>>;
|
|
11
|
+
type Icon = ComponentType<{
|
|
12
|
+
className?: string;
|
|
13
|
+
}>;
|
|
14
|
+
export interface StudioPage {
|
|
15
|
+
/** An address of the studio: `/contacts`, `/contacts/:id`. */
|
|
16
|
+
path: string;
|
|
17
|
+
component: ComponentType;
|
|
18
|
+
/** The page lays out columns of its own and takes the screen's width. */
|
|
19
|
+
wide?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** An icon in the top bar that opens a page. */
|
|
22
|
+
export interface StudioNavEntry {
|
|
23
|
+
to: string;
|
|
24
|
+
/** A function: the language can change while the studio is open. */
|
|
25
|
+
label: () => string;
|
|
26
|
+
icon: Icon;
|
|
27
|
+
}
|
|
28
|
+
export interface StudioSettingsSection {
|
|
29
|
+
/** Its address is `/settings/<id>`. */
|
|
30
|
+
id: string;
|
|
31
|
+
label: () => string;
|
|
32
|
+
icon: Icon;
|
|
33
|
+
component: ComponentType;
|
|
34
|
+
/** The user menu links to it directly. */
|
|
35
|
+
menu?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface StudioMe {
|
|
38
|
+
user: {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
email: string;
|
|
42
|
+
};
|
|
43
|
+
tenant: {
|
|
44
|
+
id: string;
|
|
45
|
+
role: "owner" | "admin" | "member";
|
|
46
|
+
};
|
|
47
|
+
/** `managed`: signed in at the Manage-App. `local`: the runtime runs alone. */
|
|
48
|
+
mode: "managed" | "local";
|
|
49
|
+
}
|
|
50
|
+
export interface StudioPluginContext {
|
|
51
|
+
plugin: {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
version: string;
|
|
55
|
+
};
|
|
56
|
+
registerPage(page: StudioPage): void;
|
|
57
|
+
registerNav(entry: StudioNavEntry): void;
|
|
58
|
+
registerSettingsSection(section: StudioSettingsSection): void;
|
|
59
|
+
i18n: {
|
|
60
|
+
/** Takes the plugin's words and gives the function that reads them in the language in effect. */
|
|
61
|
+
register<M extends StudioMessages>(messages: M): (key: keyof M["de"] & string, vars?: Record<string, string | number>) => string;
|
|
62
|
+
lang(): StudioLang;
|
|
63
|
+
};
|
|
64
|
+
/** The plugin's own routes: `get("/")` asks `/api/studio/plugins/<id>/`. */
|
|
65
|
+
api: {
|
|
66
|
+
get<T>(path: string): Promise<T>;
|
|
67
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
68
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
69
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
70
|
+
del<T>(path: string): Promise<T>;
|
|
71
|
+
};
|
|
72
|
+
/** The signed-in person. */
|
|
73
|
+
me(): StudioMe;
|
|
74
|
+
/** Something to undo when the plugin reloads. */
|
|
75
|
+
onUnload(dispose: () => void): void;
|
|
76
|
+
}
|
|
77
|
+
export type StudioPlugin = (studio: StudioPluginContext) => void;
|
|
78
|
+
/** Types the plugin; it does nothing else. */
|
|
79
|
+
export declare function defineStudioPlugin(plugin: StudioPlugin): StudioPlugin;
|
|
80
|
+
export {};
|
|
@@ -29,6 +29,18 @@ export declare function locationText(v: LocationValue): string;
|
|
|
29
29
|
/** A field takes at most this many files. */
|
|
30
30
|
export declare const MAX_FILES = 30;
|
|
31
31
|
export declare const TOOL_IDS: readonly ["web_search", "web_fetch", "browser", "sandbox", "image", "http"];
|
|
32
|
+
/**
|
|
33
|
+
* A tool a plugin of the runtime adds: `<plugin id>.<tool name>`. A wizard that names one runs
|
|
34
|
+
* only where that plugin is installed.
|
|
35
|
+
*/
|
|
36
|
+
export declare const PLUGIN_ID: RegExp;
|
|
37
|
+
export declare const PLUGIN_TOOL_NAME: RegExp;
|
|
38
|
+
export type PluginToolId = `${string}.${string}`;
|
|
39
|
+
/** The plugin and the tool a step's tool id names, or null for one of the built-in tools. */
|
|
40
|
+
export declare function pluginToolOf(id: string): {
|
|
41
|
+
plugin: string;
|
|
42
|
+
tool: string;
|
|
43
|
+
} | null;
|
|
32
44
|
/**
|
|
33
45
|
* The kinds of model a step can ask for. A step names a class; which model serves it is bound
|
|
34
46
|
* outside the wizard (the model-gateway, or the settings of a runtime that runs alone).
|
|
@@ -216,14 +228,14 @@ export declare const pageStepSchema: z.ZodObject<{
|
|
|
216
228
|
export declare const agentStepSchema: z.ZodObject<{
|
|
217
229
|
type: z.ZodLiteral<"agent">;
|
|
218
230
|
instructions: z.ZodString;
|
|
219
|
-
tools: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
231
|
+
tools: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
|
|
220
232
|
image: "image";
|
|
221
233
|
web_search: "web_search";
|
|
222
234
|
web_fetch: "web_fetch";
|
|
223
235
|
browser: "browser";
|
|
224
236
|
sandbox: "sandbox";
|
|
225
237
|
http: "http";
|
|
226
|
-
}>>>;
|
|
238
|
+
}>, z.ZodTemplateLiteral<`${string}.${string}`>]>>>;
|
|
227
239
|
mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
228
240
|
connections: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
229
241
|
output: z.ZodDefault<z.ZodObject<{
|
|
@@ -527,14 +539,14 @@ export declare const stepSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
527
539
|
}, z.core.$strip>, z.ZodObject<{
|
|
528
540
|
type: z.ZodLiteral<"agent">;
|
|
529
541
|
instructions: z.ZodString;
|
|
530
|
-
tools: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
542
|
+
tools: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
|
|
531
543
|
image: "image";
|
|
532
544
|
web_search: "web_search";
|
|
533
545
|
web_fetch: "web_fetch";
|
|
534
546
|
browser: "browser";
|
|
535
547
|
sandbox: "sandbox";
|
|
536
548
|
http: "http";
|
|
537
|
-
}>>>;
|
|
549
|
+
}>, z.ZodTemplateLiteral<`${string}.${string}`>]>>>;
|
|
538
550
|
mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
539
551
|
connections: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
540
552
|
output: z.ZodDefault<z.ZodObject<{
|
|
@@ -1139,14 +1151,14 @@ export declare const wizardSchema: z.ZodObject<{
|
|
|
1139
1151
|
}, z.core.$strip>, z.ZodObject<{
|
|
1140
1152
|
type: z.ZodLiteral<"agent">;
|
|
1141
1153
|
instructions: z.ZodString;
|
|
1142
|
-
tools: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
1154
|
+
tools: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
|
|
1143
1155
|
image: "image";
|
|
1144
1156
|
web_search: "web_search";
|
|
1145
1157
|
web_fetch: "web_fetch";
|
|
1146
1158
|
browser: "browser";
|
|
1147
1159
|
sandbox: "sandbox";
|
|
1148
1160
|
http: "http";
|
|
1149
|
-
}>>>;
|
|
1161
|
+
}>, z.ZodTemplateLiteral<`${string}.${string}`>]>>>;
|
|
1150
1162
|
mcp: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1151
1163
|
connections: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1152
1164
|
output: z.ZodDefault<z.ZodObject<{
|
|
@@ -59,6 +59,22 @@ export function locationText(v) {
|
|
|
59
59
|
/** A field takes at most this many files. */
|
|
60
60
|
export const MAX_FILES = 30;
|
|
61
61
|
export const TOOL_IDS = ["web_search", "web_fetch", "browser", "sandbox", "image", "http"];
|
|
62
|
+
/**
|
|
63
|
+
* A tool a plugin of the runtime adds: `<plugin id>.<tool name>`. A wizard that names one runs
|
|
64
|
+
* only where that plugin is installed.
|
|
65
|
+
*/
|
|
66
|
+
export const PLUGIN_ID = /^[a-z][a-z0-9-]{0,39}$/;
|
|
67
|
+
export const PLUGIN_TOOL_NAME = /^[a-z][a-z0-9_]{0,39}$/;
|
|
68
|
+
/** The plugin and the tool a step's tool id names, or null for one of the built-in tools. */
|
|
69
|
+
export function pluginToolOf(id) {
|
|
70
|
+
const [plugin, tool, ...rest] = id.split(".");
|
|
71
|
+
return tool !== undefined &&
|
|
72
|
+
rest.length === 0 &&
|
|
73
|
+
PLUGIN_ID.test(plugin) &&
|
|
74
|
+
PLUGIN_TOOL_NAME.test(tool)
|
|
75
|
+
? { plugin, tool }
|
|
76
|
+
: null;
|
|
77
|
+
}
|
|
62
78
|
/**
|
|
63
79
|
* The kinds of model a step can ask for. A step names a class; which model serves it is bound
|
|
64
80
|
* outside the wizard (the model-gateway, or the settings of a runtime that runs alone).
|
|
@@ -170,7 +186,12 @@ export const agentStepSchema = z.object({
|
|
|
170
186
|
type: z.literal("agent"),
|
|
171
187
|
/** What the agent does. A template: {{field}}, {{steps.id}}, {{brand.name}}. */
|
|
172
188
|
instructions: z.string().min(1),
|
|
173
|
-
tools: z
|
|
189
|
+
tools: z
|
|
190
|
+
.array(z.union([
|
|
191
|
+
z.enum(TOOL_IDS),
|
|
192
|
+
z.templateLiteral([z.string().regex(PLUGIN_ID), ".", z.string().regex(PLUGIN_TOOL_NAME)]),
|
|
193
|
+
]))
|
|
194
|
+
.default([]),
|
|
174
195
|
/** Ids of project MCP servers this step may use. */
|
|
175
196
|
mcp: z.array(z.string()).optional(),
|
|
176
197
|
/** Ids of wizard connections (the person's accounts) this step may use. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wizards",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"apps",
|
|
20
20
|
"bin",
|
|
21
|
+
"modules",
|
|
21
22
|
"plugin"
|
|
22
23
|
],
|
|
23
24
|
"dependencies": {
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"@ai-sdk/gateway": "4.0.82",
|
|
26
27
|
"@ai-sdk/openai": "4.0.67",
|
|
27
28
|
"@clack/prompts": "1.8.1",
|
|
29
|
+
"@engenty-wizards/plugin-sdk": "0.1.0",
|
|
28
30
|
"@engenty-wizards/shared": "0.1.0",
|
|
29
31
|
"@executor-js/plugin-openapi": "1.6.8",
|
|
30
32
|
"@hono/node-server": "2.1.3",
|
|
@@ -33,6 +35,7 @@
|
|
|
33
35
|
"@mastra/docker": "0.8.0",
|
|
34
36
|
"@mastra/mcp": "2.1.2",
|
|
35
37
|
"@modelcontextprotocol/client": "2.2.0",
|
|
38
|
+
"@modelcontextprotocol/ext-apps": "2.0.3",
|
|
36
39
|
"@modelcontextprotocol/server": "2.2.0",
|
|
37
40
|
"@turbodocx/html-to-docx": "1.23.1",
|
|
38
41
|
"ai": "7.0.102",
|
|
@@ -44,6 +47,7 @@
|
|
|
44
47
|
"fflate": "0.8.3",
|
|
45
48
|
"hono": "4.13.12",
|
|
46
49
|
"imapflow": "2.2.1",
|
|
50
|
+
"jiti": "2.7.0",
|
|
47
51
|
"jose": "6.2.12",
|
|
48
52
|
"mammoth": "1.13.0",
|
|
49
53
|
"marked": "18.0.14",
|
|
@@ -57,6 +61,7 @@
|
|
|
57
61
|
"zod": "4.6.5"
|
|
58
62
|
},
|
|
59
63
|
"bundleDependencies": [
|
|
64
|
+
"@engenty-wizards/plugin-sdk",
|
|
60
65
|
"@engenty-wizards/shared"
|
|
61
66
|
]
|
|
62
67
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "engenty-wizards",
|
|
3
3
|
"displayName": "engenty wizards",
|
|
4
4
|
"version": "{{VERSION}}",
|
|
5
|
-
"description": "Build page-by-page AI wizards that people open on a shared link — designed, tested and published from Claude Code.",
|
|
5
|
+
"description": "Build page-by-page AI wizards that people open on a shared link — designed, tested and published from Claude Code — and run your published ones right in the chat.",
|
|
6
6
|
"author": { "name": "engenty" },
|
|
7
7
|
"homepage": "{{APP_URL}}",
|
|
8
8
|
"keywords": ["wizards", "forms", "ai-workflows", "mcp"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: use-wizard
|
|
3
|
+
description: Run one of the person's published engenty wizards here in the chat — a social post with an image, a research briefing, an offer, a video ad … page by page, with its review and its downloads. Use when the person wants something one of their wizards makes, names a wizard, or asks what their wizards can do.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Use an engenty wizard
|
|
7
|
+
|
|
8
|
+
You work with the `engenty-wizards` MCP tools. The person you talk to runs the wizard; their answers fill its pages.
|
|
9
|
+
|
|
10
|
+
1. **Find it.** `list_wizards` lists the person's wizards; only `published` ones run. `show_wizard` only when the person wants to see a wizard before running it: apps that show MCP Apps show it as it greets a person, with its flow one click away.
|
|
11
|
+
2. **Start it.** `run_wizard` straight away; apps that show MCP Apps show the wizard itself, page by page, and the person may answer there. What the person already said for the first page goes in with `answer_page`, using the field ids in `waitingFor`. Runs spend credits like any run of the wizard.
|
|
12
|
+
3. **Follow `waitingFor`.**
|
|
13
|
+
- `page`: ask for the fields with `inChat: true`, in the person's words, then `answer_page`. Fields with `inChat: false` (files, recordings, signatures, line items) need the run page: hand over `browserUrl`.
|
|
14
|
+
- `review`: show the outputs (texts, image links), then `review_step`: accept, or regenerate one with the person's note.
|
|
15
|
+
- `ask`: a step wants to change something in a connected account. Ask the person, then `answer_ask` with `allow` or `skip`. A sign-in happens on the run page (`browserUrl`).
|
|
16
|
+
- Nothing, status `running`: `get_run` with `waitSeconds: 45`, again until it changes.
|
|
17
|
+
4. **In a widget.** When the app shows the run as a widget, the person may answer there instead of in the chat. Call `get_run` before you ask again, so you never ask for a page that is already answered.
|
|
18
|
+
5. **Hand over.** When the status is `done`, give the outputs and their download links (valid one hour). `failed`: say what went wrong; `control_run` with `retry` tries the step again.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e,n as t,t as n}from"./jsx-runtime-Dk72oS4N.js";import{t as r}from"./preload-helper-CNEI7N0N.js";import{a as i,d as a,h as o,i as s,s as c,v as l}from"./ui-tO4ZXbfh.js";var u=e(t(),1),d=n();function f(e){switch(e.group){case`Added`:return{label:`NEW`,dot:`bg-moss`};case`Fixed`:return{label:`FIXED`,dot:`bg-amber`};case`Changed`:return{label:`CHANGED`,dot:`bg-cobalt`};case`Performance`:return{label:`PERFORMANCE`,dot:`bg-ember`};case`Deploy`:return{label:`DEPLOY`,dot:`bg-ink-4`};case`Docs`:return{label:`DOCS`,dot:`bg-ink-4`};default:return{label:`OTHER`,dot:`bg-ink-4`}}}var p=e=>e.version?e.version.replace(/^v/,``):l(`about.unreleased`),m=e=>e.timestamp?new Date(e.timestamp*1e3).toISOString().slice(0,10):``,h=e=>e.charAt(0).toUpperCase()+e.slice(1);function g(e,t){let n=t.trim().toLowerCase();if(!n)return e;let r=[];for(let t of e){if(`${p(t)} ${m(t)}`.toLowerCase().includes(n)){r.push(t);continue}let e=t.commits.filter(e=>`${f(e).label} ${e.scope??``} ${e.message}`.toLowerCase().includes(n));e.length>0&&r.push({...t,commits:e})}return r}function _({open:e,onClose:t}){let[n,_]=(0,u.useState)(null),[v,y]=(0,u.useState)(``);(0,u.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./changelog-BJkYErYt.js`).then(e=>{t||_(e.default)}),[]),()=>{t=!0}},[e,n]),(0,u.useEffect)(()=>{e||y(``)},[e]);let b=n?g(n,v):[];return(0,d.jsxs)(s,{open:e,onClose:t,title:l(`about.changelog`),wide:!0,children:[(0,d.jsx)(`p`,{className:`-mt-3 mb-4 text-[14px] text-ink-3`,children:l(`about.changelogHint`)}),n===null?(0,d.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,d.jsx)(a,{})}):n.length===0?(0,d.jsx)(i,{children:l(`about.changelogEmpty`)}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(c,{type:`search`,value:v,placeholder:l(`about.search`),onChange:e=>y(e.target.value)}),b.length===0?(0,d.jsx)(i,{children:l(`about.noMatches`)}):null,b.map(e=>(0,d.jsxs)(`section`,{className:`mt-6`,children:[(0,d.jsxs)(`h3`,{className:`flex items-baseline gap-3 border-border-soft border-b pb-2 font-display font-semibold text-[16px]`,children:[p(e),(0,d.jsx)(`span`,{className:`font-normal font-sans text-[13px] text-ink-3 tabular-nums`,children:m(e)})]}),(0,d.jsx)(`ul`,{className:`mt-3 flex flex-col gap-2`,children:e.commits.map(e=>{let t=f(e);return(0,d.jsxs)(`li`,{className:`flex items-start gap-2.5 text-[14px]`,children:[(0,d.jsx)(`span`,{className:o(`mt-[7px] size-1.5 shrink-0 rounded-full`,t.dot)}),(0,d.jsxs)(`span`,{className:`min-w-0 text-ink-2`,children:[(0,d.jsxs)(`span`,{className:`font-semibold text-[12px] text-ink tracking-wide`,children:[t.label,e.scope?` [${e.scope}]`:``]}),` `,h(e.message),e.breaking?(0,d.jsx)(`span`,{className:`ml-1.5 rounded-full bg-rose-tint px-1.5 py-0.5 font-medium text-[12px] text-rose`,children:l(`about.breaking`)}):null]})]},e.id)})})]},e.version??`unreleased`))]})]})}export{_ as ChangelogDialog};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e,n as t,t as n}from"./jsx-runtime-Dk72oS4N.js";import{c as r,d as i,i as a,n as o,tt as s}from"./api-DbPn6Dge.js";import{t as c}from"./createLucideIcon-DBu2Ovxj.js";import{S as l,g as u,h as d,r as f,v as p}from"./outputs-CHe6KRLc.js";import{r as m}from"./wand-sparkles-Bf97fs8T.js";import{t as h}from"./plus-HA210wXA.js";import{t as g}from"./mic-CeqQ89Dj.js";import{d as _,g as v,h as y,o as b,v as x}from"./ui-tO4ZXbfh.js";import{d as S,u as C}from"./index-BRy5sz4a.js";var w={name:`chevron-up`,size:24,node:[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]};w.node;var T=c(w),E=e(t(),1),D=!1;function O(){if(!(typeof window>`u`||D))return window.SpeechRecognition??window.webkitSpeechRecognition}var k=typeof navigator<`u`&&!!navigator.mediaDevices?.getUserMedia&&typeof MediaRecorder<`u`;function A(e,t){let n=e.trimEnd(),r=t.trim();return n&&r?`${n} ${r}`:n||r}function j(e,t){let[n,r]=(0,E.useState)(!1),[i,a]=(0,E.useState)(!1),[s,c]=(0,E.useState)(null),l=(0,E.useRef)(e);l.current=e;let u=(0,E.useRef)(t);u.current=t;let d=(0,E.useRef)(null);(0,E.useEffect)(()=>()=>d.current?.stop(),[]);let f=async()=>{let e=l.current,t;try{t=await navigator.mediaDevices.getUserMedia({audio:!0})}catch{c(`denied`);return}let n=[],i=new MediaRecorder(t);i.ondataavailable=e=>e.data.size&&n.push(e.data),i.onstop=async()=>{for(let e of t.getTracks())e.stop();d.current=null,r(!1);let s=(i.mimeType||`audio/webm`).split(`;`)[0],l=new File(n,`dictation`,{type:s});if(l.size){a(!0);try{let{text:t}=await o.upload(`/api/studio/transcribe`,l);t.trim()&&u.current(A(e,t))}catch(e){c(e.message)}finally{a(!1)}}},d.current={stop:()=>i.state!==`inactive`&&i.stop()},i.start(),r(!0)},p=e=>{let t=l.current,n=``,i=new e;i.continuous=!0,i.interimResults=!0,i.lang=v===`de`?`de-DE`:`en-US`,i.onresult=e=>{let r=``;for(let t=Math.max(0,e.resultIndex);t<e.results.length;t++){let i=e.results[t],a=i[0]?.transcript??``;i.isFinal?n=A(n,a):r+=a}u.current(A(t,A(n,r)))},i.onerror=e=>{if(e.error!==`aborted`&&e.error!==`no-speech`){if(e.error===`not-allowed`){c(`denied`);return}D=!0,k&&!n?(i.onend=null,d.current=null,f()):c(e.error)}},i.onend=()=>{d.current=null,r(!1)},d.current={stop:()=>i.stop()},i.start(),r(!0)};return{supported:!!O()||k,listening:n,processing:i,error:s,toggle:()=>{if(i)return;if(d.current){d.current.stop();return}c(null);let e=O();e?p(e):f()}}}var M=n(),N=/\.(png|jpe?g|gif|webp|avif|svg)$/i;function P(e){let t=e.filter(e=>e.type.startsWith(`image/`));return t.length?Object.fromEntries(t.map(e=>[e.name,URL.createObjectURL(e)])):void 0}function F(e){let t=e.match(/(?:^|\n\n)(?:Angehängt|Attached): ([^\n]+)$/);return t?{text:e.slice(0,t.index).trim(),names:t[1].split(`, `).filter(Boolean)}:{text:e,names:[]}}function I(e,t){if(e.name&&e.name!==`image.png`)return e;let n=e.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`,r=new Date().toISOString().slice(0,19).replace(/[-:]/g,``).replace(`T`,`-`);return new File([e],`paste-${r}${t?`-${t+1}`:``}.${n}`,{type:e.type})}function L({url:e,label:t,children:n}){return(0,M.jsxs)(`div`,{className:`group relative`,title:t,children:[(0,M.jsx)(`img`,{src:e,alt:t,width:64,height:64,className:`size-16 rounded-lg bg-paper-2 object-cover ring-1 ring-border`}),n]})}function R({names:e,previews:t,fileUrl:n}){let r=e.filter(e=>t?.[e]||n&&N.test(e)),i=e.filter(e=>!r.includes(e));return(0,M.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5`,children:[r.map(e=>{let r=t?.[e]??n?.(e)??``;return(0,M.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer`,title:e,children:(0,M.jsx)(`img`,{src:r,alt:e,className:`max-h-60 w-auto max-w-full rounded-xl bg-paper-2 object-contain ring-1 ring-border`})},e)}),i.length?(0,M.jsx)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:i.map(e=>(0,M.jsxs)(`span`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 px-2.5 py-1 text-[12px] text-ink-2`,children:[(0,M.jsx)(p,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e})]},e))}):null]})}function z(e,t){let n=s(),[i,o]=(0,E.useState)([]),[c,l]=(0,E.useState)(`idle`),[u,d]=(0,E.useState)(null),[f,p]=(0,E.useState)(null),[m,h]=(0,E.useState)(null),[g,_]=(0,E.useState)(null),v=(0,E.useRef)(null);return(0,E.useEffect)(()=>{if(e){if(v.current!==e.id){v.current=e.id,o(e.messages);return}c===`idle`&&o(t=>e.messages.length>=t.length?e.messages:t)}},[e,c]),{messages:i,phase:c,activity:f,thought:m,startedAt:g,error:u,send:async(i,s=[])=>{if(!e||!(i.trim()||s.length)||c!==`idle`)return!1;if(d(null),_(Date.now()),h(null),s.length){l(`thinking`);try{for(let t of s){let n=await fetch(r(`/api/studio/wizards/${e.id}/files/${encodeURIComponent(t.name)}`),{method:`PUT`,credentials:`include`,headers:{"content-type":t.type||`application/octet-stream`},body:t});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??n.statusText)}}}catch(t){return d(t.message),l(`idle`),_(null),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),!1}let t=`${x(`editor.attached`)}: ${s.map(e=>e.name).join(`, `)}`;i=i.trim()?`${i}\n\n${t}`:t}let u=`p-${Date.now()}`;o(e=>[...e,{id:`u-${Date.now()}`,role:`user`,content:i,previews:P(s)},{id:u,role:`assistant`,content:``,pending:!0}]),l(`thinking`),p(null);let f=!1;try{await a(`/api/studio/wizards/${e.id}/chat`,{message:i},(e,n)=>{if(e===`text`){let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:t.content+e}:t))}else if(e===`activity`)p(JSON.parse(n));else if(e===`thought`)h(JSON.parse(n));else if(e===`building`)l(`building`);else if(e===`done`){f=!0;let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:e.reply,changed:e.changed,pending:!1}:t)),e.changed&&t(e.draft,e.revision)}else e===`error`&&(f=!0,d(JSON.parse(n).message))}),f||d(x(`editor.chatBroken`))}catch(e){d(e.message)}finally{p(null),h(null),_(null),o(e=>e.filter(e=>!(e.id===u&&!e.content)).map(e=>({...e,pending:!1}))),l(`idle`),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),await n.invalidateQueries({queryKey:[`me`]})}return!0},fileUrl:t=>r(`/api/studio/wizards/${e?.id}/files/${encodeURIComponent(t)}`)}}function B(e){let[t,n]=(0,E.useState)(()=>Date.now());return(0,E.useEffect)(()=>{if(e===null)return;n(Date.now());let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),e===null?null:Math.max(0,Math.floor((t-e)/1e3))}function V(e){return e<60?`${e} s`:`${Math.floor(e/60)}:${String(e%60).padStart(2,`0`)} min`}function H({chat:e,thought:t,className:n,spinner:r=`size-3.5`}){let i=B(e.startedAt);return(0,M.jsxs)(`div`,{className:y(`min-w-0`,n),children:[(0,M.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,M.jsx)(_,{className:y(`shrink-0`,r)}),(0,M.jsx)(`span`,{className:`min-w-0 truncate`,children:e.activity??(e.phase===`building`?x(`editor.building`):x(`editor.thinking`))}),i===null?null:(0,M.jsx)(`span`,{className:`shrink-0 text-ink-4 tabular-nums`,children:V(i)})]}),t&&e.thought?(0,M.jsx)(`p`,{className:`mt-0.5 truncate pl-5.5 text-[12px] text-ink-4`,children:e.thought}):null]})}function U({message:e,fileUrl:t}){let{text:n,names:r}=F(e.content);return(0,M.jsxs)(`div`,{className:`ml-8 flex flex-col items-end gap-1.5 self-end`,children:[r.length?(0,M.jsx)(R,{names:r,previews:e.previews,fileUrl:t}):null,n?(0,M.jsx)(`div`,{className:`rounded-xl rounded-br-md bg-paper-2 px-4 py-2.5 text-[14px] leading-relaxed`,children:(0,M.jsx)(`span`,{className:`whitespace-pre-wrap`,children:n})}):null]})}function W({chat:e,avatar:t,hello:n=x(`editor.chatHello`),placeholder:r=x(`editor.composer`),changedLabel:a=`Ablauf aktualisiert`,compact:o,intro:s}){let[c,v]=(0,E.useState)(!1),[w,D]=(0,E.useState)(``),[O,k]=(0,E.useState)([]),A=(0,E.useRef)(null),N=(0,E.useRef)(null),P=(0,E.useRef)(null),F=j(w,D);(0,E.useEffect)(()=>{A.current?.scrollTo({top:A.current.scrollHeight,behavior:`smooth`})},[e.messages,e.phase]),(0,E.useEffect)(()=>{let e=N.current;e&&(e.style.height=`auto`,e.style.height=`${Math.min(e.scrollHeight,200)}px`)},[w]);let R=(w.trim()||O.length>0)&&e.phase===`idle`,z=e=>k(t=>[...t.filter(t=>!e.some(e=>e.name===t.name)),...e]),[B,V]=(0,E.useState)(new Map);(0,E.useEffect)(()=>{let e=new Map(O.filter(e=>e.type.startsWith(`image/`)).map(e=>[e,URL.createObjectURL(e)]));return V(e),()=>{for(let t of e.values())URL.revokeObjectURL(t)}},[O]);let W=async()=>{if(!R)return;F.listening&&F.toggle();let t={text:w,files:O};D(``),k([]),await e.send(t.text.trim(),t.files)||(D(t.text),k(t.files))},G=!o||c,K=e.messages.at(-1);return(0,M.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[o&&(K||e.error)?(0,M.jsxs)(`button`,{type:`button`,"aria-expanded":c,"aria-label":x(`editor.thread`),onClick:()=>v(e=>!e),className:`flex items-center gap-2 px-4 pt-2.5 pb-0.5 text-left text-[13px] text-ink-3 transition hover:text-ink`,children:[!(e.error||c)&&K?.pending?(0,M.jsx)(H,{chat:e,className:`flex-1`}):(0,M.jsx)(`span`,{className:y(`min-w-0 flex-1 truncate`,e.error&&`text-rose`),children:e.error??(c?x(`editor.thread`):K?.content)}),c?(0,M.jsx)(m,{className:`size-4 shrink-0`}):(0,M.jsx)(T,{className:`size-4 shrink-0`})]}):null,(0,M.jsxs)(`div`,{ref:A,className:y(`min-h-0 flex-1 overflow-y-auto px-5 py-5`,!G&&`hidden`),children:[e.messages.length===0?s??(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(i,{kind:t,size:32,interactive:!1}),(0,M.jsx)(`p`,{className:`pt-1 text-[14px] text-ink-2 leading-relaxed`,children:n})]}):null,(0,M.jsx)(`div`,{className:`flex flex-col gap-4`,children:e.messages.map(n=>n.role===`user`?(0,M.jsx)(U,{message:n,fileUrl:e.fileUrl},n.id):(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(`div`,{className:`shrink-0`,children:(0,M.jsx)(i,{kind:t,size:28,interactive:!1})}),(0,M.jsxs)(`div`,{className:`min-w-0 pt-0.5 text-[14px]`,children:[n.source===`mcp`?(0,M.jsxs)(`div`,{className:`mb-1 inline-flex items-center gap-1.5 text-[12px] text-ink-3`,children:[(0,M.jsx)(S,{className:`size-3`}),` `,x(`editor.viaClient`,{client:n.client??`MCP`})]}):null,n.content?(0,M.jsx)(f,{text:n.content,className:`text-[14px]`}):null,n.pending?(0,M.jsx)(H,{chat:e,thought:!0,className:`mt-1 text-[13px] text-ink-3`}):null,n.changed?(0,M.jsxs)(`div`,{className:`mt-2 inline-flex items-center gap-1.5 rounded-full bg-ember-tint px-2.5 py-0.5 text-[12px] text-ember-strong`,children:[(0,M.jsx)(u,{className:`size-3`}),` `,a]}):null]})]},n.id))}),e.error?(0,M.jsx)(`div`,{className:`mt-4 rounded-lg bg-rose-tint px-3 py-2 text-[13px] text-rose`,children:e.error}):null]}),(0,M.jsxs)(`div`,{className:o?`p-2`:`p-3`,children:[(0,M.jsxs)(`div`,{className:`rounded-xl bg-card p-1.5 shadow-soft ring-1 ring-border focus-within:ring-focus`,children:[B.size?(0,M.jsx)(`div`,{className:`flex flex-wrap gap-2 px-1 pt-1 pb-1.5`,children:O.map((e,t)=>{let n=B.get(e);return n?(0,M.jsx)(L,{url:n,label:e.name,children:(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>k(e=>e.filter((e,n)=>n!==t)),className:`-top-1.5 -right-1.5 absolute flex size-5 items-center justify-center rounded-full bg-ink text-paper opacity-0 shadow-soft transition focus-visible:opacity-100 group-hover:opacity-100`,children:(0,M.jsx)(C,{className:`size-3`})})},`${e.name}-${t}`):null})}):null,O.some(e=>!B.has(e))?(0,M.jsx)(`ul`,{className:`flex flex-wrap gap-1.5 px-1 pt-1 pb-1.5`,children:O.map((e,t)=>B.has(e)?null:(0,M.jsxs)(`li`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 py-1 pr-1 pl-2.5 text-[12px] text-ink-2`,children:[(0,M.jsx)(p,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e.name}),(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>k(e=>e.filter((e,n)=>n!==t)),className:`inline-flex size-5 shrink-0 items-center justify-center rounded-full text-ink-3 hover:bg-paper-3 hover:text-ink`,children:(0,M.jsx)(C,{className:`size-3`})})]},`${e.name}-${t}`))}):null,(0,M.jsxs)(`div`,{className:`flex items-end gap-1`,children:[(0,M.jsx)(b,{label:x(`editor.attach`),onClick:()=>P.current?.click(),children:(0,M.jsx)(h,{className:`size-4`})}),(0,M.jsx)(`input`,{ref:P,type:`file`,multiple:!0,hidden:!0,onChange:e=>{let t=Array.from(e.target.files??[]);e.target.value=``,z(t)}}),(0,M.jsx)(`textarea`,{ref:N,rows:1,value:w,onChange:e=>D(e.target.value),onPaste:e=>{let t=Array.from(e.clipboardData.files);t.length&&(e.preventDefault(),z(t.map(I)))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),W())},placeholder:F.listening?x(`editor.listening`):r,className:`max-h-[200px] min-h-[40px] flex-1 resize-none bg-transparent px-1.5 py-2 text-[14px] outline-none placeholder:text-ink-4`}),F.supported?(0,M.jsx)(b,{label:F.processing?x(`editor.transcribing`):F.listening?x(`editor.voiceStop`):x(`editor.voice`),"aria-pressed":F.listening,disabled:F.processing,onClick:F.toggle,className:y(F.listening&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`),children:F.processing?(0,M.jsx)(_,{className:`size-4`}):F.listening?(0,M.jsx)(d,{className:`size-3.5 animate-pulse-dot fill-current`}):(0,M.jsx)(g,{className:`size-4`})}):null,(0,M.jsx)(`button`,{type:`button`,onClick:()=>void W(),disabled:!R,className:y(`inline-flex size-9 shrink-0 items-center justify-center rounded-full transition`,R?`bg-primary text-primary-foreground`:`bg-paper-2 text-ink-4`),"aria-label":`Send`,children:(0,M.jsx)(l,{className:`size-4`})})]})]}),F.error?(0,M.jsx)(`p`,{className:`mt-2 px-1 text-[12px] text-rose`,children:F.error===`denied`?x(`editor.micDenied`):F.error}):null]})]})}export{z as i,H as n,P as r,W as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e,n as t,t as n}from"./jsx-runtime-Dk72oS4N.js";import{t as r}from"./preload-helper-CNEI7N0N.js";import{t as i}from"./external-link-CRg6DVdO.js";import{a,d as o,g as s,i as c,s as l,v as u}from"./ui-tO4ZXbfh.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=n(),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-[14px] 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-[14px] text-ink`,children:e}),n?(0,m.jsx)(`span`,{className:`text-[12px] text-ink-3 tabular-nums`,children:n}):null,(0,m.jsx)(`span`,{className:`text-[12px] text-ink-3`,children:r})]}),a?(0,m.jsx)(`p`,{className:`mt-0.5 text-[13px] 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-[16px]`,children:e}),t?(0,m.jsx)(`p`,{className:`mt-2 text-[13px] 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[s]},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-[12px] 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),[s,g]=(0,d.useState)(``);(0,d.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./oss-credits-cPuZUFHD.js`).then(e=>{t||i(e.default)}),[]),()=>{t=!0}},[e,n]),(0,d.useEffect)(()=>{e||g(``)},[e]);let b=s.trim().toLowerCase(),x=e=>b?e.filter(e=>h(b,e.name,e.license,e.description.de,e.description.en)):e,S=e=>b?e.filter(e=>h(b,e.name,e.license,e.version)):e,C=x(f),w=x(p),T=n?[{id:`shared`,label:u(`about.creditsShared`),packages:S(n.shared)},...n.groups.map(e=>({id:e.id,label:e.label,packages:S(e.packages)}))].filter(e=>e.packages.length>0):[],E=C.length===0&&w.length===0&&T.length===0;return(0,m.jsxs)(c,{open:e,onClose:t,title:u(`about.credits`),wide:!0,children:[(0,m.jsx)(`p`,{className:`-mt-3 mb-4 text-[14px] text-ink-3`,children:u(`about.creditsHint`)}),(0,m.jsx)(l,{type:`search`,value:s,placeholder:u(`about.search`),onChange:e=>g(e.target.value)}),C.length>0?(0,m.jsx)(_,{title:u(`about.creditsProduct`),children:(0,m.jsx)(v,{credits:C})}):null,w.length>0?(0,m.jsx)(_,{title:u(`about.creditsBuiltWith`),children:(0,m.jsx)(v,{credits:w})}):null,n===null?(0,m.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,m.jsx)(o,{})}):T.length>0?(0,m.jsx)(_,{title:u(`about.creditsDeps`),hint:b?void 0:u(`about.creditsDepsHint`),children:T.map(e=>(0,m.jsx)(y,{label:e.label,packages:e.packages},e.id))}):null,n!==null&&E?(0,m.jsx)(a,{children:u(`about.noMatches`)}):null]})}export{b as CreditsDialog};
|