wizards 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/apps/runtime/dist/agents/project-assistant.js +16 -2
  2. package/apps/runtime/dist/agents/website.js +48 -10
  3. package/apps/runtime/dist/app.js +2 -0
  4. package/apps/runtime/dist/db/control-schema.js +18 -1
  5. package/apps/runtime/dist/db/migrations/control/0007_common_the_hand.sql +15 -0
  6. package/apps/runtime/dist/db/migrations/control/meta/0007_snapshot.json +460 -0
  7. package/apps/runtime/dist/db/migrations/control/meta/_journal.json +7 -0
  8. package/apps/runtime/dist/db/migrations/tenant/0006_hard_war_machine.sql +30 -0
  9. package/apps/runtime/dist/db/migrations/tenant/meta/0006_snapshot.json +1696 -0
  10. package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
  11. package/apps/runtime/dist/db/schema.js +12 -6
  12. package/apps/runtime/dist/engine/steps.js +3 -0
  13. package/apps/runtime/dist/env.js +6 -0
  14. package/apps/runtime/dist/index.js +2 -0
  15. package/apps/runtime/dist/media/generate.js +2 -2
  16. package/apps/runtime/dist/media/transcribe.js +18 -6
  17. package/apps/runtime/dist/models.js +566 -218
  18. package/apps/runtime/dist/plugins/events.js +37 -14
  19. package/apps/runtime/dist/plugins/jobs.js +64 -0
  20. package/apps/runtime/dist/plugins/loader.js +67 -4
  21. package/apps/runtime/dist/plugins/public.js +31 -0
  22. package/apps/runtime/dist/plugins/registry.js +5 -0
  23. package/apps/runtime/dist/routes/plugin-public.js +59 -0
  24. package/apps/runtime/dist/routes/plugins.js +1 -1
  25. package/apps/runtime/dist/routes/studio.js +155 -10
  26. package/apps/runtime/dist/services/project-files.js +4 -0
  27. package/apps/runtime/dist/services/project-index.js +69 -9
  28. package/apps/runtime/dist/services/projects.js +7 -1
  29. package/apps/runtime/dist/services/spaces.js +2 -0
  30. package/apps/runtime/dist/tools/index.js +3 -2
  31. package/apps/runtime/dist/tools/plugin.js +89 -17
  32. package/apps/runtime/dist/tools/project.js +39 -31
  33. package/apps/web/dist/assets/Account-ZAqYVN9S.js +1 -0
  34. package/apps/web/dist/assets/{ChangelogDialog-DEfZRDK3.js → ChangelogDialog-CzdNuUMU.js} +1 -1
  35. package/apps/web/dist/assets/{ChatPanel-CNiFyu_w.js → ChatPanel-CDkHMh5g.js} +1 -1
  36. package/apps/web/dist/assets/{CreditsDialog-CUvc2iPM.js → CreditsDialog-DSjsgLoo.js} +1 -1
  37. package/apps/web/dist/assets/EditorPage-D4mertxP.js +2 -0
  38. package/apps/web/dist/assets/{FlowPreview-BC25OUH0.js → FlowPreview-DWYKllel.js} +1 -1
  39. package/apps/web/dist/assets/Harness-WJ0jpIl3.js +16 -0
  40. package/apps/web/dist/assets/HomePage-2Zn7et7Z.js +1 -0
  41. package/apps/web/dist/assets/ImportWizard-Dn7AiRgV.js +1 -0
  42. package/apps/web/dist/assets/LocalRuntime-BggRFDJt.js +1 -0
  43. package/apps/web/dist/assets/NewWizardPage-k-xPHAwe.js +2 -0
  44. package/apps/web/dist/assets/ProjectPage-CZgR1dQj.js +2 -0
  45. package/apps/web/dist/assets/{PublicRunner-BCrmXPkr.js → PublicRunner-BsvhBQMD.js} +1 -1
  46. package/apps/web/dist/assets/{ReadOnly-CvmN9XW4.js → ReadOnly-B0-ReU_0.js} +1 -1
  47. package/apps/web/dist/assets/RunnerView-0srHaE2T.js +2 -0
  48. package/apps/web/dist/assets/SettingsPage-CNsK0n6L.js +1 -0
  49. package/apps/web/dist/assets/SetupPage-BXQ6wfWP.js +1 -0
  50. package/apps/web/dist/assets/{SharePage-BqwqI3Ga.js → SharePage-CA8uuk9K.js} +1 -1
  51. package/apps/web/dist/assets/{api-Bf-l9Sd8.js → api-u3nydnnp.js} +1 -1
  52. package/apps/web/dist/assets/changelog-D7O5icPX.js +1 -0
  53. package/apps/web/dist/assets/circle-alert-B76z9TWZ.js +1 -0
  54. package/apps/web/dist/assets/definition-Co2Mg1qo.js +55 -0
  55. package/apps/web/dist/assets/esm-BbARZ7EE.js +7 -0
  56. package/apps/web/dist/assets/image-BShbErBm.js +1 -0
  57. package/apps/web/dist/assets/index-BQQihL4r.js +10 -0
  58. package/apps/web/dist/assets/index-CQQD8QNR.css +1 -0
  59. package/apps/web/dist/assets/meta-Dsb9LZTu.js +1 -0
  60. package/apps/web/dist/assets/oss-credits-CIxnNZor.js +1 -0
  61. package/apps/web/dist/assets/{outputs-CsESg-Eg.js → outputs-C806GWxt.js} +1 -1
  62. package/apps/web/dist/assets/{video-CjgmvRDk.js → pen-line-NK46C_nG.js} +1 -1
  63. package/apps/web/dist/assets/refresh-cw-Cmk7VCe0.js +1 -0
  64. package/apps/web/dist/assets/ui-gGAdXx-P.js +1 -0
  65. package/apps/web/dist/assets/video-DBmwF1Jm.js +1 -0
  66. package/apps/web/dist/assets/volume-2-Bp2tyaKE.js +1 -0
  67. package/apps/web/dist/index.html +4 -7
  68. package/apps/web/dist/mcp/flow.html +2 -2
  69. package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +183 -0
  70. package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +48 -3
  71. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +7 -1
  72. package/node_modules/@engenty-wizards/shared/dist/providers.d.ts +75 -0
  73. package/node_modules/@engenty-wizards/shared/dist/providers.js +339 -0
  74. package/package.json +5 -1
  75. package/apps/web/dist/assets/Account-DLLeEwJL.js +0 -1
  76. package/apps/web/dist/assets/EditorPage-CZuCz7lB.js +0 -2
  77. package/apps/web/dist/assets/HomePage-DQKuhMFZ.js +0 -1
  78. package/apps/web/dist/assets/ImportWizard-BockXJXm.js +0 -1
  79. package/apps/web/dist/assets/LocalRuntime-C199bg_B.js +0 -16
  80. package/apps/web/dist/assets/NewWizardPage-C4cde8FO.js +0 -2
  81. package/apps/web/dist/assets/ProjectPage-DJC1K4w_.js +0 -2
  82. package/apps/web/dist/assets/RunnerView-CCe8-k9Q.js +0 -2
  83. package/apps/web/dist/assets/SettingsPage-BuocMkLt.js +0 -1
  84. package/apps/web/dist/assets/SetupPage-o6Jim2Pu.js +0 -1
  85. package/apps/web/dist/assets/changelog-CFeEzKqb.js +0 -1
  86. package/apps/web/dist/assets/cloud-off-D--dZLDw.js +0 -1
  87. package/apps/web/dist/assets/definition-DndaH5Ow.js +0 -55
  88. package/apps/web/dist/assets/esm-rJY59Ixx.js +0 -7
  89. package/apps/web/dist/assets/globe-ffVj8XwO.js +0 -1
  90. package/apps/web/dist/assets/index-B8n2AYO0.css +0 -1
  91. package/apps/web/dist/assets/index-BR5ELbeZ.js +0 -10
  92. package/apps/web/dist/assets/meta-CKE9QceT.js +0 -1
  93. package/apps/web/dist/assets/oss-credits-C-U2Tlpn.js +0 -1
  94. package/apps/web/dist/assets/react-dom-DenslgJm.js +0 -1
  95. package/apps/web/dist/assets/session-C7LDDcj7.js +0 -1
  96. package/apps/web/dist/assets/ui-BT0Y_Hci.js +0 -1
  97. /package/apps/web/dist/assets/{LocalRuntime-BrP-ENHg.css → Harness-BrP-ENHg.css} +0 -0
@@ -1,10 +1,13 @@
1
1
  import { embedMany } from "ai";
2
- import { eq, inArray, sql } from "drizzle-orm";
2
+ import { and, eq, inArray, sql } from "drizzle-orm";
3
3
  import { db, schema } from "../db/client.js";
4
4
  import { parseDocument } from "../documents/parse.js";
5
5
  import { createSearchChunks } from "../engenty/search-index/chunks.js";
6
6
  import { getBlob, putBlob } from "../files/blobs.js";
7
7
  import { embeddingModel } from "../models.js";
8
+ import { pluginIdsOf } from "../plugins/registry.js";
9
+ import { currentTenant } from "../tenants/tenant.js";
10
+ import { ServiceError } from "./errors.js";
8
11
  const CHUNK = { mode: "paragraph", max_chunk_length: 1200, overlap: 120 };
9
12
  /** Passages of one document; a longer one keeps its start. */
10
13
  const MAX_CHUNKS = 2000;
@@ -53,6 +56,51 @@ export async function indexDocument(file, data) {
53
56
  text,
54
57
  };
55
58
  }
59
+ /** Puts a plugin's text into the space's index, in the place of what its key held. */
60
+ export async function putIndexEntry(plugin, entry) {
61
+ const space = await db.query.project.findFirst({ where: eq(schema.project.id, entry.space) });
62
+ if (!space) {
63
+ throw new ServiceError("not_found", `There is no space "${entry.space}".`);
64
+ }
65
+ const text = `${entry.title.trim()}\n\n${entry.text.trim()}`;
66
+ const chunks = createSearchChunks({ doc_id: `${plugin}:${entry.key}`, text, ...CHUNK }).slice(0, MAX_CHUNKS);
67
+ const embedded = await embed(chunks.map((c) => c.text)).catch((err) => {
68
+ console.error("[project-index] embedding failed", err);
69
+ return null;
70
+ });
71
+ await removeIndexEntries(plugin, entry.space, entry.key);
72
+ for (let i = 0; i < chunks.length; i += 100) {
73
+ await db.insert(schema.projectChunk).values(chunks.slice(i, i + 100).map((c, j) => ({
74
+ projectId: entry.space,
75
+ plugin,
76
+ ref: entry.key,
77
+ title: entry.title.trim().slice(0, 300),
78
+ link: entry.link ?? null,
79
+ idx: c.chunk_index,
80
+ text: c.text,
81
+ embedding: embedded ? vectorBytes(embedded.vectors[i + j]) : null,
82
+ model: embedded?.model ?? null,
83
+ })));
84
+ }
85
+ }
86
+ /** Takes a plugin's text out of the space's index; without a key, all of the plugin's texts. */
87
+ export async function removeIndexEntries(plugin, space, key) {
88
+ await db
89
+ .delete(schema.projectChunk)
90
+ .where(and(eq(schema.projectChunk.projectId, space), eq(schema.projectChunk.plugin, plugin), key === undefined ? undefined : eq(schema.projectChunk.ref, key)));
91
+ }
92
+ /** Whether a plugin the tenant has put a text into the space's index. */
93
+ export async function hasIndexEntries(projectId) {
94
+ const plugins = [...(await pluginIdsOf(currentTenant()))];
95
+ if (!plugins.length) {
96
+ return false;
97
+ }
98
+ const found = await db.query.projectChunk.findFirst({
99
+ columns: { id: true },
100
+ where: and(eq(schema.projectChunk.projectId, projectId), inArray(schema.projectChunk.plugin, plugins)),
101
+ });
102
+ return Boolean(found);
103
+ }
56
104
  export async function documentText(file) {
57
105
  return file.textHash ? (await getBlob(file.textHash)).toString("utf8") : "";
58
106
  }
@@ -64,23 +112,32 @@ function keywordQuery(query) {
64
112
  .slice(0, 16);
65
113
  return words.length ? words.map((w) => `"${w}"*`).join(" OR ") : null;
66
114
  }
67
- /** The passages of the project's documents that fit a question best. */
115
+ /** A passage of a document, or of a plugin's text while the tenant has that plugin. */
116
+ function searchable(plugins, alias = "") {
117
+ const column = sql.raw(`${alias}plugin`);
118
+ return plugins.length
119
+ ? sql `(${column} IS NULL OR ${column} IN (${sql.join(plugins.map((p) => sql `${p}`), sql `, `)}))`
120
+ : sql `${column} IS NULL`;
121
+ }
122
+ /** The passages of the project's documents, and of the texts its plugins put in, that fit a question best. */
68
123
  export async function searchProject(projectId, query, limit = 6) {
124
+ const plugins = [...(await pluginIdsOf(currentTenant()))];
69
125
  const lists = [];
70
126
  const keywords = keywordQuery(query);
71
127
  if (keywords) {
72
128
  lists.push(await db.all(sql `
73
- SELECT c.id, c.file_id, c.idx, c.text
129
+ SELECT c.id, c.file_id, c.plugin, c.ref, c.title, c.link, c.idx, c.text
74
130
  FROM project_chunk_fts f JOIN project_chunk c ON c.id = f.rowid
75
131
  WHERE project_chunk_fts MATCH ${keywords} AND c.project_id = ${projectId}
132
+ AND ${searchable(plugins, "c.")}
76
133
  ORDER BY bm25(project_chunk_fts) LIMIT 24`));
77
134
  }
78
135
  const embedded = await embed([query]).catch(() => null);
79
136
  if (embedded) {
80
137
  lists.push(await db.all(sql `
81
- SELECT id, file_id, idx, text
138
+ SELECT id, file_id, plugin, ref, title, link, idx, text
82
139
  FROM project_chunk
83
- WHERE project_id = ${projectId} AND model = ${embedded.model}
140
+ WHERE project_id = ${projectId} AND model = ${embedded.model} AND ${searchable(plugins)}
84
141
  ORDER BY vector_distance_cos(embedding, ${vectorBytes(embedded.vectors[0])}) LIMIT 24`));
85
142
  }
86
143
  // Reciprocal rank fusion: a passage both lists rank high comes first.
@@ -96,12 +153,15 @@ export async function searchProject(projectId, query, limit = 6) {
96
153
  if (!top.length) {
97
154
  return [];
98
155
  }
99
- const files = await db.query.projectFile.findMany({
100
- where: inArray(schema.projectFile.id, [...new Set(top.map((t) => t.hit.file_id))]),
101
- });
156
+ const fileIds = [...new Set(top.map((t) => t.hit.file_id).filter((id) => id !== null))];
157
+ const files = fileIds.length
158
+ ? await db.query.projectFile.findMany({ where: inArray(schema.projectFile.id, fileIds) })
159
+ : [];
102
160
  return top.map(({ hit, score }) => ({
103
161
  fileId: hit.file_id,
104
- name: files.find((f) => f.id === hit.file_id)?.name ?? "",
162
+ plugin: hit.plugin,
163
+ name: hit.file_id ? (files.find((f) => f.id === hit.file_id)?.name ?? "") : (hit.title ?? ""),
164
+ link: hit.link,
105
165
  index: hit.idx,
106
166
  text: hit.text,
107
167
  score: Math.round(score * 10_000) / 10_000,
@@ -5,6 +5,7 @@ import { z } from "zod";
5
5
  import { db, schema } from "../db/client.js";
6
6
  import { env } from "../env.js";
7
7
  import { managed, tenantInfo } from "../manage.js";
8
+ import { spaceChanged } from "../plugins/events.js";
8
9
  import { currentTenant } from "../tenants/tenant.js";
9
10
  import { mayBuild, requireBuild, requireWritable } from "./access.js";
10
11
  import { notFound, ServiceError } from "./errors.js";
@@ -73,9 +74,11 @@ const synced = () => and(eq(schema.project.tenantId, currentTenant()), eq(schema
73
74
  async function ensureProject() {
74
75
  const any = await db.query.project.findFirst({ where: madeHere() });
75
76
  if (!any) {
77
+ const id = nanoid(12);
76
78
  await db
77
79
  .insert(schema.project)
78
- .values({ id: nanoid(12), tenantId: currentTenant(), name: "Meine Wizards" });
80
+ .values({ id, tenantId: currentTenant(), name: "Meine Wizards" });
81
+ spaceChanged("space.created", id);
79
82
  }
80
83
  }
81
84
  /**
@@ -144,6 +147,7 @@ export async function createProject(_userId, name) {
144
147
  await db
145
148
  .insert(schema.project)
146
149
  .values({ id, tenantId: currentTenant(), name, brand: {}, mcpServers: [] });
150
+ spaceChanged("space.created", id);
147
151
  return { id };
148
152
  }
149
153
  export async function updateProject(userId, projectId, patch) {
@@ -172,6 +176,7 @@ export async function updateProject(userId, projectId, patch) {
172
176
  updatedAt: new Date(),
173
177
  })
174
178
  .where(eq(schema.project.id, p.id));
179
+ spaceChanged("space.updated", p.id);
175
180
  }
176
181
  export function projectProfile(p) {
177
182
  return {
@@ -202,4 +207,5 @@ export async function removeProject(projectId) {
202
207
  await db
203
208
  .delete(schema.project)
204
209
  .where(and(eq(schema.project.id, projectId), eq(schema.project.tenantId, currentTenant())));
210
+ spaceChanged("space.deleted", projectId);
205
211
  }
@@ -7,6 +7,7 @@ import { z } from "zod";
7
7
  import { db, inTransaction, schema } from "../db/client.js";
8
8
  import { missingModels, unavoidableSteps } from "../engine/requirements.js";
9
9
  import { env } from "../env.js";
10
+ import { spaceChanged } from "../plugins/events.js";
10
11
  import { codeOf, putLink } from "../tenants/control.js";
11
12
  import { currentTenant } from "../tenants/tenant.js";
12
13
  import { asSync, mayBuild } from "./access.js";
@@ -218,6 +219,7 @@ async function syncSpace(spaceId, space) {
218
219
  ...values,
219
220
  });
220
221
  }
222
+ spaceChanged(existing ? "space.updated" : "space.created", spaceId);
221
223
  const project = await syncedProject(spaceId);
222
224
  if (!project) {
223
225
  throw notFound();
@@ -13,7 +13,7 @@ import { browserTools } from "./browser.js";
13
13
  import { connectorTools } from "./connector.js";
14
14
  import { mailTools } from "./mail.js";
15
15
  import { assertPublicUrl, safeFetch } from "./net-guard.js";
16
- import { pluginTools } from "./plugin.js";
16
+ import { pluginTools, spaceContextOf } from "./plugin.js";
17
17
  import { projectTools } from "./project.js";
18
18
  import { clip, FileKeeper } from "./shared.js";
19
19
  import { storeTools } from "./store.js";
@@ -93,10 +93,11 @@ export async function buildStepTools(step, ctx, resolved, uploads) {
93
93
  // The wizard's lists and files, the documents the person gave and the project's documents are
94
94
  // always at hand.
95
95
  Object.assign(tools, storeTools(ctx, uploads, files));
96
- Object.assign(tools, projectTools(ctx));
96
+ Object.assign(tools, await projectTools(ctx));
97
97
  Object.assign(tools, mailTools(step, ctx, files));
98
98
  Object.assign(tools, await connectorTools(step, ctx, files));
99
99
  Object.assign(tools, await pluginTools(step, ctx));
100
+ Object.assign(tools, (await spaceContextOf(ctx)).tools);
100
101
  const sandbox = sandboxCapabilities();
101
102
  if (allowed.has("sandbox") && sandbox) {
102
103
  const timeoutMs = (seconds) => Math.min((seconds ?? 120) * 1000, 600_000);
@@ -1,12 +1,32 @@
1
1
  import { pluginToolOf } from "@engenty-wizards/shared/definition";
2
2
  import { createTool } from "@mastra/core/tools";
3
3
  import { StepError } from "../engine/types.js";
4
- import { loadedPlugin, pluginIdsOf } from "../plugins/registry.js";
5
- import { attempt } from "./shared.js";
4
+ import { loadedPlugin, pluginIdsOf, pluginsOf } from "../plugins/registry.js";
5
+ import { attempt, clip } from "./shared.js";
6
6
  /** The model's name of a plugin's tool: `<plugin>_<tool>`, since a tool name takes no dot. */
7
7
  export function pluginToolName(plugin, tool) {
8
8
  return `${plugin.replaceAll("-", "_")}_${tool}`;
9
9
  }
10
+ /** A plugin's tool as an agent step calls it. */
11
+ function stepTool(plugin, tool, ctx) {
12
+ const id = pluginToolName(plugin, tool.name);
13
+ const space = { id: ctx.project.id, name: ctx.project.name };
14
+ return createTool({
15
+ id,
16
+ description: tool.description,
17
+ inputSchema: tool.inputSchema,
18
+ execute: (input) => attempt(async () => tool.execute(input, {
19
+ runId: ctx.runId,
20
+ stepId: ctx.stepId,
21
+ tenantId: ctx.tenantId,
22
+ space,
23
+ project: space,
24
+ wizard: { title: ctx.def.title },
25
+ signal: ctx.signal,
26
+ emit: (message) => ctx.emit("tool", message),
27
+ })),
28
+ });
29
+ }
10
30
  /**
11
31
  * The tools of plugins a step allowlists as `<plugin>.<tool>`. A step that names a tool this
12
32
  * tenant does not have fails: the wizard was written for a runtime with that plugin.
@@ -23,21 +43,73 @@ export async function pluginTools(step, ctx) {
23
43
  if (!found) {
24
44
  throw new StepError(`Dieser Schritt braucht das Werkzeug „${plugin}.${tool}“. Das Plugin „${plugin}“ ist hier nicht installiert.`);
25
45
  }
26
- const id = pluginToolName(plugin, tool);
27
- tools[id] = createTool({
28
- id,
29
- description: found.description,
30
- inputSchema: found.inputSchema,
31
- execute: (input) => attempt(async () => found.execute(input, {
32
- runId: ctx.runId,
33
- stepId: ctx.stepId,
34
- tenantId: ctx.tenantId,
35
- project: { id: ctx.project.id, name: ctx.project.name },
36
- wizard: { title: ctx.def.title },
37
- signal: ctx.signal,
38
- emit: (message) => ctx.emit("tool", message),
39
- })),
40
- });
46
+ tools[pluginToolName(plugin, tool)] = stepTool(plugin, found, ctx);
47
+ }
48
+ return tools;
49
+ }
50
+ /** A block of a plugin is cut here: the step's instructions stay the step's. */
51
+ const MAX_BLOCK = 8000;
52
+ const contexts = new WeakMap();
53
+ /**
54
+ * What the tenant's plugins add to an agent step of a space's wizard (`registerSpaceContext`):
55
+ * asked once per step, for its instructions and for its tools. A context that fails adds nothing.
56
+ */
57
+ export function spaceContextOf(ctx) {
58
+ let found = contexts.get(ctx);
59
+ if (!found) {
60
+ found = gather(ctx);
61
+ contexts.set(ctx, found);
62
+ }
63
+ return found;
64
+ }
65
+ async function gather(ctx) {
66
+ const space = { id: ctx.project.id, name: ctx.project.name };
67
+ const result = { blocks: [], tools: {} };
68
+ for (const plugin of await pluginsOf(ctx.tenantId)) {
69
+ for (const context of plugin.contexts) {
70
+ const block = await Promise.resolve()
71
+ .then(() => context.block(space))
72
+ .catch((err) => {
73
+ console.error(`[plugin ${plugin.source.id}] space context:`, err);
74
+ return null;
75
+ });
76
+ if (!block?.trim()) {
77
+ continue;
78
+ }
79
+ result.blocks.push(clip(block.trim(), MAX_BLOCK));
80
+ for (const tool of context.tools ?? []) {
81
+ result.tools[pluginToolName(plugin.source.id, tool.name)] = stepTool(plugin.source.id, tool, ctx);
82
+ }
83
+ }
84
+ }
85
+ return result;
86
+ }
87
+ /** The tenant's plugins' tools of the space assistant (`registerAssistantTool`). */
88
+ export async function assistantToolsOf(turn) {
89
+ const tools = {};
90
+ for (const plugin of await pluginsOf(turn.tenantId)) {
91
+ for (const tool of plugin.assistantTools.values()) {
92
+ const id = pluginToolName(plugin.source.id, tool.name);
93
+ tools[id] = createTool({
94
+ id,
95
+ description: tool.description,
96
+ inputSchema: tool.inputSchema,
97
+ execute: (input) => attempt(async () => {
98
+ const result = await tool.execute(input, {
99
+ tenantId: turn.tenantId,
100
+ space: turn.space,
101
+ userId: turn.userId,
102
+ signal: turn.signal,
103
+ emit: turn.emit,
104
+ changed: turn.changed,
105
+ });
106
+ if (tool.card) {
107
+ turn.card({ plugin: plugin.source.id, tool: tool.name, data: result ?? null });
108
+ }
109
+ return result;
110
+ }),
111
+ });
112
+ }
41
113
  }
42
114
  return tools;
43
115
  }
@@ -1,17 +1,21 @@
1
1
  import { createTool } from "@mastra/core/tools";
2
2
  import { z } from "zod";
3
- import { documentText, searchProject } from "../services/project-index.js";
3
+ import { documentText, hasIndexEntries, searchProject } from "../services/project-index.js";
4
4
  import { attempt, clip } from "./shared.js";
5
- /** The project's documents, for every agent step of its wizards: search the index, read one whole. */
6
- export function projectTools(ctx) {
5
+ /**
6
+ * The project's documents, for every agent step of its wizards: search the index, read one
7
+ * whole. The search also finds what the space's plugins put into the index.
8
+ */
9
+ export async function projectTools(ctx) {
7
10
  const docs = ctx.projectFiles.filter((f) => f.kind === "document");
8
- if (!docs.length) {
11
+ const entries = await hasIndexEntries(ctx.project.id);
12
+ if (!(docs.length || entries)) {
9
13
  return {};
10
14
  }
11
- return {
15
+ const tools = {
12
16
  project_search: createTool({
13
17
  id: "project_search",
14
- description: "Search the project's documents (the knowledge its owner gave for all wizards) and get the passages that fit best. Ask in the documents' language, with the words they would use.",
18
+ description: "Search the project's documents and what its plugins keep for all wizards (wiki pages, questions and answers), and get the passages that fit best. Ask in their language, with the words they would use.",
15
19
  inputSchema: z.object({
16
20
  query: z.string().describe("What to look for: a question or keywords"),
17
21
  limit: z.number().int().min(1).max(12).optional(),
@@ -24,30 +28,34 @@ export function projectTools(ctx) {
24
28
  };
25
29
  }),
26
30
  }),
27
- project_document: createTool({
28
- id: "project_document",
29
- description: "Read one of the project's documents as text. Long documents come in parts: pass `from` to continue.",
30
- inputSchema: z.object({
31
- name: z.string().describe("The document's name, as listed"),
32
- from: z.number().int().min(0).optional().describe("Character to start at"),
33
- }),
34
- execute: ({ name, from }) => attempt(async () => {
35
- const doc = docs.find((d) => d.name === name) ??
36
- docs.find((d) => d.name.toLowerCase().includes(name.toLowerCase()));
37
- if (!doc) {
38
- throw new Error(`No document "${name}". There are: ${docs.map((d) => d.name).join(", ")}`);
39
- }
40
- await ctx.emit("tool", `Liest ${doc.name}`);
41
- const text = await documentText(doc);
42
- const start = Math.min(from ?? 0, text.length);
43
- const part = text.slice(start, start + 12_000);
44
- return {
45
- document: doc.name,
46
- text: clip(part, 12_000),
47
- next: start + part.length < text.length ? start + part.length : null,
48
- length: text.length,
49
- };
50
- }),
51
- }),
52
31
  };
32
+ if (!docs.length) {
33
+ return tools;
34
+ }
35
+ tools.project_document = createTool({
36
+ id: "project_document",
37
+ description: "Read one of the project's documents as text. Long documents come in parts: pass `from` to continue.",
38
+ inputSchema: z.object({
39
+ name: z.string().describe("The document's name, as listed"),
40
+ from: z.number().int().min(0).optional().describe("Character to start at"),
41
+ }),
42
+ execute: ({ name, from }) => attempt(async () => {
43
+ const doc = docs.find((d) => d.name === name) ??
44
+ docs.find((d) => d.name.toLowerCase().includes(name.toLowerCase()));
45
+ if (!doc) {
46
+ throw new Error(`No document "${name}". There are: ${docs.map((d) => d.name).join(", ")}`);
47
+ }
48
+ await ctx.emit("tool", `Liest ${doc.name}`);
49
+ const text = await documentText(doc);
50
+ const start = Math.min(from ?? 0, text.length);
51
+ const part = text.slice(start, start + 12_000);
52
+ return {
53
+ document: doc.name,
54
+ text: clip(part, 12_000),
55
+ next: start + part.length < text.length ? start + part.length : null,
56
+ length: text.length,
57
+ };
58
+ }),
59
+ });
60
+ return tools;
53
61
  }
@@ -0,0 +1 @@
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-u3nydnnp.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{_ as f,c as p,d as m,h,m as g,n as ee,o as _,r as v,s as y,t as b,y as x}from"./ui-gGAdXx-P.js";import{I as S,O as C,f as w,j as T,o as E,p as D,u as O,v as k}from"./index-BQQihL4r.js";import{n as A}from"./LocalRuntime-BggRFDJt.js";var j={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`}]]};j.node;var M=s(j),N={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`}]]};N.node;var te=s(N),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-[12px] text-ink-3`,children:[(0,W.jsx)(m,{className:`size-3`}),` `,x(`project.saving`)]}):n?.state===`saved`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[12px] text-moss`,children:[(0,W.jsx)(c,{className:`size-3.5`}),` `,x(`settings.saved`)]}):null]}),t?(0,W.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-snug`,children:t}):null]}),r?(0,W.jsx)(`div`,{className:`shrink-0`,children:r}):null]}),a?o:(0,W.jsxs)(ee,{className:`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-[14px] 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)(_,{label:x(t===`list`?`project.viewCards`:`project.viewList`),onClick:n,children:t===`list`?(0,W.jsx)(te,{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-[14px] text-ink outline-none transition placeholder:text-ink-4 focus:border-focus focus:ring-4 focus:ring-focus-glow`}),i?(0,W.jsx)(m,{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:h(`flex cursor-pointer items-center justify-center gap-2 rounded-lg border border-input border-dashed text-[14px] 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-[13px] 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})=>{A(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-[13px] text-rose`,children:x(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[13px] text-ink-3`,children:[(0,W.jsx)(m,{className:`size-3.5`}),` `,x(`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)(M,{className:`size-5`})}),(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsx)(`div`,{className:`font-medium text-[15px]`,children:x(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-relaxed`,children:x(`account.localText`)})]})]}),D.account?(0,W.jsxs)(`div`,{className:`flex flex-col gap-4 py-5 last:pb-0`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[15px]`,children:x(`account.with`)}),(0,W.jsxs)(`ul`,{className:`mt-2 flex flex-col gap-2 text-[14px] 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`}),x(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(T,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),x(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(b,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:x(`account.signIn`)})})]}):null,D.account?(0,W.jsxs)(`form`,{className:`flex flex-col gap-3 py-5 last:pb-0`,onSubmit:e=>{e.preventDefault(),t.mutate({signup:!0,code:n.trim()||void 0})},children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[15px]`,children:x(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[14px] text-ink-3 leading-relaxed`,children:x(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(y,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:x(`account.code`),"aria-label":x(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[14px]`}),(0,W.jsx)(b,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:x(`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(f,{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-[15px]`,children:e.name||e.email}),e.signedIn?(0,W.jsx)(v,{tone:`live`,children:x(`account.linked`)}):null]}),(0,W.jsx)(`div`,{className:`truncate text-[14px] text-ink-3`,children:e.email})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,W.jsxs)(b,{variant:`secondary`,onClick:()=>A(e.url),children:[x(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}),(0,W.jsxs)(b,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(C,{className:`size-4`}),` `,x(`nav.logout`)]})]})]}),e.signedIn?null:(0,W.jsxs)(`div`,{className:`flex flex-col gap-3 py-5`,children:[(0,W.jsx)(`p`,{className:`text-[14px] text-ink-2`,children:x(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(b,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:x(`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-[13px] text-ink-3`,children:x(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[22px] tabular-nums leading-tight`,children:x(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(b,{variant:`secondary`,onClick:()=>A(`${e.url}/billing`),children:[x(`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-[13px] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,W.jsxs)(`li`,{children:[x(`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:[` · `,x($[e.kind])]}):null]},`${e.kind}:${e.expiresAt}`))}):null]}),(0,W.jsxs)(`div`,{className:`flex items-start gap-2.5 py-5 text-[14px] text-ink-2 leading-snug last:pb-0`,children:[(0,W.jsx)(T,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:x(`account.cloud`,{host:E(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:x(`account.profile`),hint:x(`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-[28px] 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`}):k(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[12px] text-ink-3 leading-snug`,children:x(`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)(p,{children:x(`account.name`)}),(0,W.jsx)(y,{value:r.name,maxLength:80,disabled:t,onChange:e=>s({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:x(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.about`)}),(0,W.jsx)(g,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>s({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:x(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.email`)}),(0,W.jsx)(y,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>s({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(p,{children:x(`account.phone`)}),(0,W.jsx)(y,{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:x(`account.connection`),hint:x(`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-[15px]`,children:e.user.name}),(0,W.jsx)(v,{tone:`live`,children:x(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[14px] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(b,{variant:`secondary`,onClick:()=>A(`${e.manageUrl}/account`),children:[x(`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:x(`account.look`),hint:x(`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-[14px]`,children:x(`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-[14px]`,children:x(`nav.theme`)}),(0,W.jsx)(O,{})]})]})})]})}export{Y as a,K as c,H as d,B as f,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 +1 @@
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{a as i,d as a,h as o,i as s,s as c,y as l}from"./ui-BT0Y_Hci.js";var u=e(t(),1),d=e(n(),1);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-CFeEzKqb.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
+ 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{a as i,d as a,h as o,i as s,s as c,y as l}from"./ui-gGAdXx-P.js";var u=e(t(),1),d=e(n(),1);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-D7O5icPX.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 +1 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,d as i,i as a,n as o,nt as s}from"./api-Bf-l9Sd8.js";import{t as c}from"./createLucideIcon-q3MZMmnf.js";import{S as l,T as u,b as d,r as f,y as p}from"./outputs-CsESg-Eg.js";import{t as m}from"./chevron-down-DymW-2BP.js";import{t as h}from"./plus-Du-Jx8aI.js";import{t as g}from"./mic-Bvz4mA2j.js";import{_,d as v,h as y,o as b,y as x}from"./ui-BT0Y_Hci.js";import{g as S,h as C}from"./index-BR5ELbeZ.js";var w={name:`chevron-up`,size:24,node:[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]};w.node;var T=c(w),E=e(t(),1),D=!1;function O(){if(!(typeof window>`u`||D))return window.SpeechRecognition??window.webkitSpeechRecognition}var k=typeof navigator<`u`&&!!navigator.mediaDevices?.getUserMedia&&typeof MediaRecorder<`u`;function A(e,t){let n=e.trimEnd(),r=t.trim();return n&&r?`${n} ${r}`:n||r}function j(e,t){let[n,r]=(0,E.useState)(!1),[i,a]=(0,E.useState)(!1),[s,c]=(0,E.useState)(null),l=(0,E.useRef)(e);l.current=e;let u=(0,E.useRef)(t);u.current=t;let d=(0,E.useRef)(null);(0,E.useEffect)(()=>()=>d.current?.stop(),[]);let f=async()=>{let e=l.current,t;try{t=await navigator.mediaDevices.getUserMedia({audio:!0})}catch{c(`denied`);return}let n=[],i=new MediaRecorder(t);i.ondataavailable=e=>e.data.size&&n.push(e.data),i.onstop=async()=>{for(let e of t.getTracks())e.stop();d.current=null,r(!1);let s=(i.mimeType||`audio/webm`).split(`;`)[0],l=new File(n,`dictation`,{type:s});if(l.size){a(!0);try{let{text:t}=await o.upload(`/api/studio/transcribe`,l);t.trim()&&u.current(A(e,t))}catch(e){c(e.message)}finally{a(!1)}}},d.current={stop:()=>i.state!==`inactive`&&i.stop()},i.start(),r(!0)},p=e=>{let t=l.current,n=``,i=new e;i.continuous=!0,i.interimResults=!0,i.lang=_===`de`?`de-DE`:`en-US`,i.onresult=e=>{let r=``;for(let t=Math.max(0,e.resultIndex);t<e.results.length;t++){let i=e.results[t],a=i[0]?.transcript??``;i.isFinal?n=A(n,a):r+=a}u.current(A(t,A(n,r)))},i.onerror=e=>{if(e.error!==`aborted`&&e.error!==`no-speech`){if(e.error===`not-allowed`){c(`denied`);return}D=!0,k&&!n?(i.onend=null,d.current=null,f()):c(e.error)}},i.onend=()=>{d.current=null,r(!1)},d.current={stop:()=>i.stop()},i.start(),r(!0)};return{supported:!!O()||k,listening:n,processing:i,error:s,toggle:()=>{if(i)return;if(d.current){d.current.stop();return}c(null);let e=O();e?p(e):f()}}}var M=e(n(),1),N=/\.(png|jpe?g|gif|webp|avif|svg)$/i;function P(e){let t=e.filter(e=>e.type.startsWith(`image/`));return t.length?Object.fromEntries(t.map(e=>[e.name,URL.createObjectURL(e)])):void 0}function F(e){let t=e.match(/(?:^|\n\n)(?:Angehängt|Attached): ([^\n]+)$/);return t?{text:e.slice(0,t.index).trim(),names:t[1].split(`, `).filter(Boolean)}:{text:e,names:[]}}function I(e,t){if(e.name&&e.name!==`image.png`)return e;let n=e.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`,r=new Date().toISOString().slice(0,19).replace(/[-:]/g,``).replace(`T`,`-`);return new File([e],`paste-${r}${t?`-${t+1}`:``}.${n}`,{type:e.type})}function L({url:e,label:t,children:n}){return(0,M.jsxs)(`div`,{className:`group relative`,title:t,children:[(0,M.jsx)(`img`,{src:e,alt:t,width:64,height:64,className:`size-16 rounded-lg bg-paper-2 object-cover ring-1 ring-border`}),n]})}function R({names:e,previews:t,fileUrl:n}){let r=e.filter(e=>t?.[e]||n&&N.test(e)),i=e.filter(e=>!r.includes(e));return(0,M.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5`,children:[r.map(e=>{let r=t?.[e]??n?.(e)??``;return(0,M.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer`,title:e,children:(0,M.jsx)(`img`,{src:r,alt:e,className:`max-h-60 w-auto max-w-full rounded-xl bg-paper-2 object-contain ring-1 ring-border`})},e)}),i.length?(0,M.jsx)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:i.map(e=>(0,M.jsxs)(`span`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 px-2.5 py-1 text-[12px] text-ink-2`,children:[(0,M.jsx)(l,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e})]},e))}):null]})}function z(e,t){let n=s(),[i,o]=(0,E.useState)([]),[c,l]=(0,E.useState)(`idle`),[u,d]=(0,E.useState)(null),[f,p]=(0,E.useState)(null),[m,h]=(0,E.useState)(null),[g,_]=(0,E.useState)(null),v=(0,E.useRef)(null);return(0,E.useEffect)(()=>{if(e){if(v.current!==e.id){v.current=e.id,o(e.messages);return}c===`idle`&&o(t=>e.messages.length>=t.length?e.messages:t)}},[e,c]),{messages:i,phase:c,activity:f,thought:m,startedAt:g,error:u,send:async(i,s=[])=>{if(!e||!(i.trim()||s.length)||c!==`idle`)return!1;if(d(null),_(Date.now()),h(null),s.length){l(`thinking`);try{for(let t of s){let n=await fetch(r(`/api/studio/wizards/${e.id}/files/${encodeURIComponent(t.name)}`),{method:`PUT`,credentials:`include`,headers:{"content-type":t.type||`application/octet-stream`},body:t});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??n.statusText)}}}catch(t){return d(t.message),l(`idle`),_(null),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),!1}let t=`${x(`editor.attached`)}: ${s.map(e=>e.name).join(`, `)}`;i=i.trim()?`${i}\n\n${t}`:t}let u=`p-${Date.now()}`;o(e=>[...e,{id:`u-${Date.now()}`,role:`user`,content:i,previews:P(s)},{id:u,role:`assistant`,content:``,pending:!0}]),l(`thinking`),p(null);let f=!1;try{await a(`/api/studio/wizards/${e.id}/chat`,{message:i},(e,n)=>{if(e===`text`){let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:t.content+e}:t))}else if(e===`activity`)p(JSON.parse(n));else if(e===`thought`)h(JSON.parse(n));else if(e===`building`)l(`building`);else if(e===`done`){f=!0;let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:e.reply,changed:e.changed,pending:!1}:t)),e.changed&&t(e.draft,e.revision)}else e===`error`&&(f=!0,d(JSON.parse(n).message))}),f||d(x(`editor.chatBroken`))}catch(e){d(e.message)}finally{p(null),h(null),_(null),o(e=>e.filter(e=>!(e.id===u&&!e.content)).map(e=>({...e,pending:!1}))),l(`idle`),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),await n.invalidateQueries({queryKey:[`me`]})}return!0},fileUrl:t=>r(`/api/studio/wizards/${e?.id}/files/${encodeURIComponent(t)}`)}}function B(e){let[t,n]=(0,E.useState)(()=>Date.now());return(0,E.useEffect)(()=>{if(e===null)return;n(Date.now());let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),e===null?null:Math.max(0,Math.floor((t-e)/1e3))}function V(e){return e<60?`${e} s`:`${Math.floor(e/60)}:${String(e%60).padStart(2,`0`)} min`}function H({chat:e,thought:t,className:n,spinner:r=`size-3.5`}){let i=B(e.startedAt);return(0,M.jsxs)(`div`,{className:y(`min-w-0`,n),children:[(0,M.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,M.jsx)(v,{className:y(`shrink-0`,r)}),(0,M.jsx)(`span`,{className:`min-w-0 truncate`,children:e.activity??(e.phase===`building`?x(`editor.building`):x(`editor.thinking`))}),i===null?null:(0,M.jsx)(`span`,{className:`shrink-0 text-ink-4 tabular-nums`,children:V(i)})]}),t&&e.thought?(0,M.jsx)(`p`,{className:`mt-0.5 truncate pl-5.5 text-[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,closed:c}){let[_,w]=(0,E.useState)(!1),[D,O]=(0,E.useState)(``),[k,A]=(0,E.useState)([]),N=(0,E.useRef)(null),P=(0,E.useRef)(null),F=(0,E.useRef)(null),R=j(D,O);(0,E.useEffect)(()=>{N.current?.scrollTo({top:N.current.scrollHeight,behavior:`smooth`})},[e.messages,e.phase]),(0,E.useEffect)(()=>{let e=P.current;if(!e)return;let t=()=>{e.style.height=`auto`,e.style.height=D?`${Math.min(e.scrollHeight,200)}px`:``};t();let n=e.clientWidth,r=new ResizeObserver(()=>{e.clientWidth!==n&&(n=e.clientWidth,t())});return r.observe(e),()=>r.disconnect()},[D]);let z=(D.trim()||k.length>0)&&e.phase===`idle`,B=e=>A(t=>[...t.filter(t=>!e.some(e=>e.name===t.name)),...e]),[V,W]=(0,E.useState)(new Map);(0,E.useEffect)(()=>{let e=new Map(k.filter(e=>e.type.startsWith(`image/`)).map(e=>[e,URL.createObjectURL(e)]));return W(e),()=>{for(let t of e.values())URL.revokeObjectURL(t)}},[k]);let G=async()=>{if(!z)return;R.listening&&R.toggle();let t={text:D,files:k};O(``),A([]),await e.send(t.text.trim(),t.files)||(O(t.text),A(t.files))},K=!o||_,q=e.messages.at(-1);return(0,M.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[o&&(q||e.error)?(0,M.jsxs)(`button`,{type:`button`,"aria-expanded":_,"aria-label":x(`editor.thread`),onClick:()=>w(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||_)&&q?.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??(_?x(`editor.thread`):q?.content)}),_?(0,M.jsx)(m,{className:`size-4 shrink-0`}):(0,M.jsx)(T,{className:`size-4 shrink-0`})]}):null,(0,M.jsxs)(`div`,{ref:N,className:y(`min-h-0 flex-1 overflow-y-auto px-5 py-5`,!K&&`hidden`),children:[e.messages.length===0&&!c?s??(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(i,{kind:t,size:32,interactive:!1}),(0,M.jsx)(`p`,{className:`pt-1 text-[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)(d,{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]}),c?(0,M.jsx)(`p`,{className:`m-3 rounded-xl bg-paper-2 px-4 py-3 text-[13px] text-ink-2 leading-relaxed`,children:c}):(0,M.jsxs)(`div`,{className:o?`p-2`:`p-3`,children:[(0,M.jsxs)(`div`,{className:`rounded-xl bg-card p-1.5 shadow-soft ring-1 ring-border focus-within:ring-focus`,children:[V.size?(0,M.jsx)(`div`,{className:`flex flex-wrap gap-2 px-1 pt-1 pb-1.5`,children:k.map((e,t)=>{let n=V.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:()=>A(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,k.some(e=>!V.has(e))?(0,M.jsx)(`ul`,{className:`flex flex-wrap gap-1.5 px-1 pt-1 pb-1.5`,children:k.map((e,t)=>V.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)(l,{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:()=>A(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:()=>F.current?.click(),children:(0,M.jsx)(h,{className:`size-4`})}),(0,M.jsx)(`input`,{ref:F,type:`file`,multiple:!0,hidden:!0,onChange:e=>{let t=Array.from(e.target.files??[]);e.target.value=``,B(t)}}),(0,M.jsx)(`textarea`,{ref:P,rows:1,value:D,onChange:e=>O(e.target.value),onPaste:e=>{let t=Array.from(e.clipboardData.files);t.length&&(e.preventDefault(),B(t.map(I)))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),G())},placeholder:R.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`}),R.supported?(0,M.jsx)(b,{label:R.processing?x(`editor.transcribing`):R.listening?x(`editor.voiceStop`):x(`editor.voice`),"aria-pressed":R.listening,disabled:R.processing,onClick:R.toggle,className:y(R.listening&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`),children:R.processing?(0,M.jsx)(v,{className:`size-4`}):R.listening?(0,M.jsx)(p,{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 G(),disabled:!z,className:y(`inline-flex size-9 shrink-0 items-center justify-center rounded-full transition`,z?`bg-primary text-primary-foreground`:`bg-paper-2 text-ink-4`),"aria-label":`Send`,children:(0,M.jsx)(u,{className:`size-4`})})]})]}),R.error?(0,M.jsx)(`p`,{className:`mt-2 px-1 text-[12px] text-rose`,children:R.error===`denied`?x(`editor.micDenied`):R.error}):null]})]})}export{z as i,H as n,P as r,W as t};
1
+ import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,d as i,i as a,n as o,nt as s}from"./api-u3nydnnp.js";import{t as c}from"./createLucideIcon-q3MZMmnf.js";import{S as l,T as u,b as d,r as f,y as p}from"./outputs-C806GWxt.js";import{t as m}from"./chevron-down-DymW-2BP.js";import{t as h}from"./plus-Du-Jx8aI.js";import{t as g}from"./mic-Bvz4mA2j.js";import{_,d as v,h as y,o as b,y as x}from"./ui-gGAdXx-P.js";import{D as S,E as C}from"./index-BQQihL4r.js";var w={name:`chevron-up`,size:24,node:[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]};w.node;var T=c(w),E=e(t(),1),D=!1;function O(){if(!(typeof window>`u`||D))return window.SpeechRecognition??window.webkitSpeechRecognition}var k=typeof navigator<`u`&&!!navigator.mediaDevices?.getUserMedia&&typeof MediaRecorder<`u`;function A(e,t){let n=e.trimEnd(),r=t.trim();return n&&r?`${n} ${r}`:n||r}function j(e,t){let[n,r]=(0,E.useState)(!1),[i,a]=(0,E.useState)(!1),[s,c]=(0,E.useState)(null),l=(0,E.useRef)(e);l.current=e;let u=(0,E.useRef)(t);u.current=t;let d=(0,E.useRef)(null);(0,E.useEffect)(()=>()=>d.current?.stop(),[]);let f=async()=>{let e=l.current,t;try{t=await navigator.mediaDevices.getUserMedia({audio:!0})}catch{c(`denied`);return}let n=[],i=new MediaRecorder(t);i.ondataavailable=e=>e.data.size&&n.push(e.data),i.onstop=async()=>{for(let e of t.getTracks())e.stop();d.current=null,r(!1);let s=(i.mimeType||`audio/webm`).split(`;`)[0],l=new File(n,`dictation`,{type:s});if(l.size){a(!0);try{let{text:t}=await o.upload(`/api/studio/transcribe`,l);t.trim()&&u.current(A(e,t))}catch(e){c(e.message)}finally{a(!1)}}},d.current={stop:()=>i.state!==`inactive`&&i.stop()},i.start(),r(!0)},p=e=>{let t=l.current,n=``,i=new e;i.continuous=!0,i.interimResults=!0,i.lang=_===`de`?`de-DE`:`en-US`,i.onresult=e=>{let r=``;for(let t=Math.max(0,e.resultIndex);t<e.results.length;t++){let i=e.results[t],a=i[0]?.transcript??``;i.isFinal?n=A(n,a):r+=a}u.current(A(t,A(n,r)))},i.onerror=e=>{if(e.error!==`aborted`&&e.error!==`no-speech`){if(e.error===`not-allowed`){c(`denied`);return}D=!0,k&&!n?(i.onend=null,d.current=null,f()):c(e.error)}},i.onend=()=>{d.current=null,r(!1)},d.current={stop:()=>i.stop()},i.start(),r(!0)};return{supported:!!O()||k,listening:n,processing:i,error:s,toggle:()=>{if(i)return;if(d.current){d.current.stop();return}c(null);let e=O();e?p(e):f()}}}var M=e(n(),1),N=/\.(png|jpe?g|gif|webp|avif|svg)$/i;function P(e){let t=e.filter(e=>e.type.startsWith(`image/`));return t.length?Object.fromEntries(t.map(e=>[e.name,URL.createObjectURL(e)])):void 0}function F(e){let t=e.match(/(?:^|\n\n)(?:Angehängt|Attached): ([^\n]+)$/);return t?{text:e.slice(0,t.index).trim(),names:t[1].split(`, `).filter(Boolean)}:{text:e,names:[]}}function I(e,t){if(e.name&&e.name!==`image.png`)return e;let n=e.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`,r=new Date().toISOString().slice(0,19).replace(/[-:]/g,``).replace(`T`,`-`);return new File([e],`paste-${r}${t?`-${t+1}`:``}.${n}`,{type:e.type})}function L({url:e,label:t,children:n}){return(0,M.jsxs)(`div`,{className:`group relative`,title:t,children:[(0,M.jsx)(`img`,{src:e,alt:t,width:64,height:64,className:`size-16 rounded-lg bg-paper-2 object-cover ring-1 ring-border`}),n]})}function R({names:e,previews:t,fileUrl:n}){let r=e.filter(e=>t?.[e]||n&&N.test(e)),i=e.filter(e=>!r.includes(e));return(0,M.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5`,children:[r.map(e=>{let r=t?.[e]??n?.(e)??``;return(0,M.jsx)(`a`,{href:r,target:`_blank`,rel:`noreferrer`,title:e,children:(0,M.jsx)(`img`,{src:r,alt:e,className:`max-h-60 w-auto max-w-full rounded-xl bg-paper-2 object-contain ring-1 ring-border`})},e)}),i.length?(0,M.jsx)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:i.map(e=>(0,M.jsxs)(`span`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 px-2.5 py-1 text-[12px] text-ink-2`,children:[(0,M.jsx)(l,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e})]},e))}):null]})}function z(e,t){let n=s(),[i,o]=(0,E.useState)([]),[c,l]=(0,E.useState)(`idle`),[u,d]=(0,E.useState)(null),[f,p]=(0,E.useState)(null),[m,h]=(0,E.useState)(null),[g,_]=(0,E.useState)(null),v=(0,E.useRef)(null);return(0,E.useEffect)(()=>{if(e){if(v.current!==e.id){v.current=e.id,o(e.messages);return}c===`idle`&&o(t=>e.messages.length>=t.length?e.messages:t)}},[e,c]),{messages:i,phase:c,activity:f,thought:m,startedAt:g,error:u,send:async(i,s=[])=>{if(!e||!(i.trim()||s.length)||c!==`idle`)return!1;if(d(null),_(Date.now()),h(null),s.length){l(`thinking`);try{for(let t of s){let n=await fetch(r(`/api/studio/wizards/${e.id}/files/${encodeURIComponent(t.name)}`),{method:`PUT`,credentials:`include`,headers:{"content-type":t.type||`application/octet-stream`},body:t});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error??n.statusText)}}}catch(t){return d(t.message),l(`idle`),_(null),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),!1}let t=`${x(`editor.attached`)}: ${s.map(e=>e.name).join(`, `)}`;i=i.trim()?`${i}\n\n${t}`:t}let u=`p-${Date.now()}`;o(e=>[...e,{id:`u-${Date.now()}`,role:`user`,content:i,previews:P(s)},{id:u,role:`assistant`,content:``,pending:!0}]),l(`thinking`),p(null);let f=!1;try{await a(`/api/studio/wizards/${e.id}/chat`,{message:i},(e,n)=>{if(e===`text`){let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:t.content+e}:t))}else if(e===`activity`)p(JSON.parse(n));else if(e===`thought`)h(JSON.parse(n));else if(e===`building`)l(`building`);else if(e===`done`){f=!0;let e=JSON.parse(n);o(t=>t.map(t=>t.id===u?{...t,content:e.reply,changed:e.changed,pending:!1}:t)),e.changed&&t(e.draft,e.revision)}else e===`error`&&(f=!0,d(JSON.parse(n).message))}),f||d(x(`editor.chatBroken`))}catch(e){d(e.message)}finally{p(null),h(null),_(null),o(e=>e.filter(e=>!(e.id===u&&!e.content)).map(e=>({...e,pending:!1}))),l(`idle`),await n.invalidateQueries({queryKey:[`wizard`,e.id]}),await n.invalidateQueries({queryKey:[`me`]})}return!0},fileUrl:t=>r(`/api/studio/wizards/${e?.id}/files/${encodeURIComponent(t)}`)}}function B(e){let[t,n]=(0,E.useState)(()=>Date.now());return(0,E.useEffect)(()=>{if(e===null)return;n(Date.now());let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),e===null?null:Math.max(0,Math.floor((t-e)/1e3))}function V(e){return e<60?`${e} s`:`${Math.floor(e/60)}:${String(e%60).padStart(2,`0`)} min`}function H({chat:e,thought:t,className:n,spinner:r=`size-3.5`}){let i=B(e.startedAt);return(0,M.jsxs)(`div`,{className:y(`min-w-0`,n),children:[(0,M.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,M.jsx)(v,{className:y(`shrink-0`,r)}),(0,M.jsx)(`span`,{className:`min-w-0 truncate`,children:e.activity??(e.phase===`building`?x(`editor.building`):x(`editor.thinking`))}),i===null?null:(0,M.jsx)(`span`,{className:`shrink-0 text-ink-4 tabular-nums`,children:V(i)})]}),t&&e.thought?(0,M.jsx)(`p`,{className:`mt-0.5 truncate pl-5.5 text-[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,closed:c,card:_}){let[w,D]=(0,E.useState)(!1),[O,k]=(0,E.useState)(``),[A,N]=(0,E.useState)([]),P=(0,E.useRef)(null),F=(0,E.useRef)(null),R=(0,E.useRef)(null),z=j(O,k);(0,E.useEffect)(()=>{P.current?.scrollTo({top:P.current.scrollHeight,behavior:`smooth`})},[e.messages,e.phase]),(0,E.useEffect)(()=>{let e=F.current;if(!e)return;let t=()=>{e.style.height=`auto`,e.style.height=O?`${Math.min(e.scrollHeight,200)}px`:``};t();let n=e.clientWidth,r=new ResizeObserver(()=>{e.clientWidth!==n&&(n=e.clientWidth,t())});return r.observe(e),()=>r.disconnect()},[O]);let B=(O.trim()||A.length>0)&&e.phase===`idle`,V=e=>N(t=>[...t.filter(t=>!e.some(e=>e.name===t.name)),...e]),[W,G]=(0,E.useState)(new Map);(0,E.useEffect)(()=>{let e=new Map(A.filter(e=>e.type.startsWith(`image/`)).map(e=>[e,URL.createObjectURL(e)]));return G(e),()=>{for(let t of e.values())URL.revokeObjectURL(t)}},[A]);let K=async()=>{if(!B)return;z.listening&&z.toggle();let t={text:O,files:A};k(``),N([]),await e.send(t.text.trim(),t.files)||(k(t.text),N(t.files))},q=!o||w,J=e.messages.at(-1);return(0,M.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[o&&(J||e.error)?(0,M.jsxs)(`button`,{type:`button`,"aria-expanded":w,"aria-label":x(`editor.thread`),onClick:()=>D(e=>!e),className:`flex items-center gap-2 px-4 pt-2.5 pb-0.5 text-left text-[13px] text-ink-3 transition hover:text-ink`,children:[!(e.error||w)&&J?.pending?(0,M.jsx)(H,{chat:e,className:`flex-1`}):(0,M.jsx)(`span`,{className:y(`min-w-0 flex-1 truncate`,e.error&&`text-rose`),children:e.error??(w?x(`editor.thread`):J?.content)}),w?(0,M.jsx)(m,{className:`size-4 shrink-0`}):(0,M.jsx)(T,{className:`size-4 shrink-0`})]}):null,(0,M.jsxs)(`div`,{ref:P,className:y(`min-h-0 flex-1 overflow-y-auto px-5 py-5`,!q&&`hidden`),children:[e.messages.length===0&&!c?s??(0,M.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,M.jsx)(i,{kind:t,size:32,interactive:!1}),(0,M.jsx)(`p`,{className:`pt-1 text-[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.cards?.length?(0,M.jsx)(`div`,{className:`mt-2 flex flex-col gap-2`,children:n.cards.map(e=>(0,M.jsx)(E.Fragment,{children:_(e)},e.id))}):null,n.pending?(0,M.jsx)(H,{chat:e,thought:!0,className:`mt-1 text-[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)(d,{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]}),c?(0,M.jsx)(`p`,{className:`m-3 rounded-xl bg-paper-2 px-4 py-3 text-[13px] text-ink-2 leading-relaxed`,children:c}):(0,M.jsxs)(`div`,{className:o?`p-2`:`p-3`,children:[(0,M.jsxs)(`div`,{className:`rounded-xl bg-card p-1.5 shadow-soft ring-1 ring-border focus-within:ring-focus`,children:[W.size?(0,M.jsx)(`div`,{className:`flex flex-wrap gap-2 px-1 pt-1 pb-1.5`,children:A.map((e,t)=>{let n=W.get(e);return n?(0,M.jsx)(L,{url:n,label:e.name,children:(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>N(e=>e.filter((e,n)=>n!==t)),className:`-top-1.5 -right-1.5 absolute flex size-5 items-center justify-center rounded-full bg-ink text-paper opacity-0 shadow-soft transition focus-visible:opacity-100 group-hover:opacity-100`,children:(0,M.jsx)(C,{className:`size-3`})})},`${e.name}-${t}`):null})}):null,A.some(e=>!W.has(e))?(0,M.jsx)(`ul`,{className:`flex flex-wrap gap-1.5 px-1 pt-1 pb-1.5`,children:A.map((e,t)=>W.has(e)?null:(0,M.jsxs)(`li`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-full bg-paper-2 py-1 pr-1 pl-2.5 text-[12px] text-ink-2`,children:[(0,M.jsx)(l,{className:`size-3 shrink-0 text-ink-4`}),(0,M.jsx)(`span`,{className:`truncate`,children:e.name}),(0,M.jsx)(`button`,{type:`button`,"aria-label":x(`editor.detach`),onClick:()=>N(e=>e.filter((e,n)=>n!==t)),className:`inline-flex size-5 shrink-0 items-center justify-center rounded-full text-ink-3 hover:bg-paper-3 hover:text-ink`,children:(0,M.jsx)(C,{className:`size-3`})})]},`${e.name}-${t}`))}):null,(0,M.jsxs)(`div`,{className:`flex items-end gap-1`,children:[(0,M.jsx)(b,{label:x(`editor.attach`),onClick:()=>R.current?.click(),children:(0,M.jsx)(h,{className:`size-4`})}),(0,M.jsx)(`input`,{ref:R,type:`file`,multiple:!0,hidden:!0,onChange:e=>{let t=Array.from(e.target.files??[]);e.target.value=``,V(t)}}),(0,M.jsx)(`textarea`,{ref:F,rows:1,value:O,onChange:e=>k(e.target.value),onPaste:e=>{let t=Array.from(e.clipboardData.files);t.length&&(e.preventDefault(),V(t.map(I)))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),K())},placeholder:z.listening?x(`editor.listening`):r,className:`max-h-[200px] min-h-[40px] flex-1 resize-none bg-transparent px-1.5 py-2 text-[14px] outline-none placeholder:text-ink-4`}),z.supported?(0,M.jsx)(b,{label:z.processing?x(`editor.transcribing`):z.listening?x(`editor.voiceStop`):x(`editor.voice`),"aria-pressed":z.listening,disabled:z.processing,onClick:z.toggle,className:y(z.listening&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`),children:z.processing?(0,M.jsx)(v,{className:`size-4`}):z.listening?(0,M.jsx)(p,{className:`size-3.5 animate-pulse-dot fill-current`}):(0,M.jsx)(g,{className:`size-4`})}):null,(0,M.jsx)(`button`,{type:`button`,onClick:()=>void K(),disabled:!B,className:y(`inline-flex size-9 shrink-0 items-center justify-center rounded-full transition`,B?`bg-primary text-primary-foreground`:`bg-paper-2 text-ink-4`),"aria-label":`Send`,children:(0,M.jsx)(u,{className:`size-4`})})]})]}),z.error?(0,M.jsx)(`p`,{className:`mt-2 px-1 text-[12px] text-rose`,children:z.error===`denied`?x(`editor.micDenied`):z.error}):null]})]})}export{z as i,H as n,P as r,W as t};
@@ -1 +1 @@
1
- import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{t as r}from"./preload-helper-CNEI7N0N.js";import{t as i}from"./external-link-MAL7vJYj.js";import{_ as a,a as o,d as s,i as c,s as l,y as u}from"./ui-BT0Y_Hci.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-[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[a]},e.name))})}function y({label:e,packages:t}){return(0,m.jsxs)(`div`,{className:`mt-4`,children:[(0,m.jsx)(`h4`,{className:`font-medium text-[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),[a,g]=(0,d.useState)(``);(0,d.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./oss-credits-C-U2Tlpn.js`).then(e=>{t||i(e.default)}),[]),()=>{t=!0}},[e,n]),(0,d.useEffect)(()=>{e||g(``)},[e]);let b=a.trim().toLowerCase(),x=e=>b?e.filter(e=>h(b,e.name,e.license,e.description.de,e.description.en)):e,S=e=>b?e.filter(e=>h(b,e.name,e.license,e.version)):e,C=x(f),w=x(p),T=n?[{id:`shared`,label:u(`about.creditsShared`),packages:S(n.shared)},...n.groups.map(e=>({id:e.id,label:e.label,packages:S(e.packages)}))].filter(e=>e.packages.length>0):[],E=C.length===0&&w.length===0&&T.length===0;return(0,m.jsxs)(c,{open:e,onClose:t,title:u(`about.credits`),wide:!0,children:[(0,m.jsx)(`p`,{className:`-mt-3 mb-4 text-[14px] text-ink-3`,children:u(`about.creditsHint`)}),(0,m.jsx)(l,{type:`search`,value:a,placeholder:u(`about.search`),onChange:e=>g(e.target.value)}),C.length>0?(0,m.jsx)(_,{title:u(`about.creditsProduct`),children:(0,m.jsx)(v,{credits:C})}):null,w.length>0?(0,m.jsx)(_,{title:u(`about.creditsBuiltWith`),children:(0,m.jsx)(v,{credits:w})}):null,n===null?(0,m.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,m.jsx)(s,{})}):T.length>0?(0,m.jsx)(_,{title:u(`about.creditsDeps`),hint:b?void 0:u(`about.creditsDepsHint`),children:T.map(e=>(0,m.jsx)(y,{label:e.label,packages:e.packages},e.id))}):null,n!==null&&E?(0,m.jsx)(o,{children:u(`about.noMatches`)}):null]})}export{b as CreditsDialog};
1
+ import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{t as r}from"./preload-helper-CNEI7N0N.js";import{t as i}from"./external-link-MAL7vJYj.js";import{_ as a,a as o,d as s,i as c,s as l,y as u}from"./ui-gGAdXx-P.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-[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[a]},e.name))})}function y({label:e,packages:t}){return(0,m.jsxs)(`div`,{className:`mt-4`,children:[(0,m.jsx)(`h4`,{className:`font-medium text-[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),[a,g]=(0,d.useState)(``);(0,d.useEffect)(()=>{if(!e||n)return;let t=!1;return r(()=>import(`./oss-credits-CIxnNZor.js`).then(e=>{t||i(e.default)}),[]),()=>{t=!0}},[e,n]),(0,d.useEffect)(()=>{e||g(``)},[e]);let b=a.trim().toLowerCase(),x=e=>b?e.filter(e=>h(b,e.name,e.license,e.description.de,e.description.en)):e,S=e=>b?e.filter(e=>h(b,e.name,e.license,e.version)):e,C=x(f),w=x(p),T=n?[{id:`shared`,label:u(`about.creditsShared`),packages:S(n.shared)},...n.groups.map(e=>({id:e.id,label:e.label,packages:S(e.packages)}))].filter(e=>e.packages.length>0):[],E=C.length===0&&w.length===0&&T.length===0;return(0,m.jsxs)(c,{open:e,onClose:t,title:u(`about.credits`),wide:!0,children:[(0,m.jsx)(`p`,{className:`-mt-3 mb-4 text-[14px] text-ink-3`,children:u(`about.creditsHint`)}),(0,m.jsx)(l,{type:`search`,value:a,placeholder:u(`about.search`),onChange:e=>g(e.target.value)}),C.length>0?(0,m.jsx)(_,{title:u(`about.creditsProduct`),children:(0,m.jsx)(v,{credits:C})}):null,w.length>0?(0,m.jsx)(_,{title:u(`about.creditsBuiltWith`),children:(0,m.jsx)(v,{credits:w})}):null,n===null?(0,m.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,m.jsx)(s,{})}):T.length>0?(0,m.jsx)(_,{title:u(`about.creditsDeps`),hint:b?void 0:u(`about.creditsDepsHint`),children:T.map(e=>(0,m.jsx)(y,{label:e.label,packages:e.packages},e.id))}):null,n!==null&&E?(0,m.jsx)(o,{children:u(`about.noMatches`)}):null]})}export{b as CreditsDialog};