wizards 0.2.24 → 0.2.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/runtime/dist/agents/architect.js +5 -0
- package/apps/runtime/dist/authoring/guide.js +55 -6
- package/apps/runtime/dist/connectors/builtin.js +17 -1
- package/apps/runtime/dist/connectors/imap.js +46 -2
- package/apps/runtime/dist/connectors/index.js +52 -18
- package/apps/runtime/dist/connectors/via-account.js +63 -0
- package/apps/runtime/dist/credits/estimate.js +12 -2
- package/apps/runtime/dist/engine/decide.js +82 -0
- package/apps/runtime/dist/engine/input.js +12 -5
- package/apps/runtime/dist/engine/requirements.js +80 -15
- package/apps/runtime/dist/engine/runner.js +252 -6
- package/apps/runtime/dist/engine/steps.js +206 -18
- package/apps/runtime/dist/engine/surface.js +90 -0
- package/apps/runtime/dist/render/downloads.js +7 -0
- package/apps/runtime/dist/routes/runs.js +18 -5
- package/apps/runtime/dist/services/relevance.js +17 -49
- package/apps/runtime/dist/tools/pages.js +31 -6
- package/apps/web/dist/assets/{Account-thPW7H4A.js → Account-Cnksw5Ea.js} +1 -1
- package/apps/web/dist/assets/{ChangelogDialog-mCszGL5_.js → ChangelogDialog-CdtQWq0m.js} +1 -1
- package/apps/web/dist/assets/{CreditsDialog-Com2Y3g8.js → CreditsDialog-Ti43boCN.js} +1 -1
- package/apps/web/dist/assets/EditorPage-N7EzlRSj.js +3 -0
- package/apps/web/dist/assets/{FlowPreview-CRsxtwhV.js → FlowPreview-IZcNrBJi.js} +1 -1
- package/apps/web/dist/assets/{Harness-CfgVRYpr.js → Harness-Cj-k02TA.js} +1 -1
- package/apps/web/dist/assets/{HomePage-DYKF3C1U.js → HomePage-bjdKkt84.js} +1 -1
- package/apps/web/dist/assets/{ImportWizard-BTp7XTsF.js → ImportWizard-DagFXYPM.js} +1 -1
- package/apps/web/dist/assets/{LocalRuntime-CYhPXwAv.js → LocalRuntime-Boi_zqQJ.js} +1 -1
- package/apps/web/dist/assets/NewWizardPage-DO5J8OpZ.js +2 -0
- package/apps/web/dist/assets/ProjectPage-DdG9wYsd.js +2 -0
- package/apps/web/dist/assets/{PublicRunner-ClB2-2EF.js → PublicRunner-B4ts9rT6.js} +1 -1
- package/apps/web/dist/assets/RunDrawer-LnVfCiYO.js +4 -0
- package/apps/web/dist/assets/RunnerView-DwffK7AA.js +70 -0
- package/apps/web/dist/assets/{SettingsPage-qDqiZ7th.js → SettingsPage-Cyx_jTlp.js} +1 -1
- package/apps/web/dist/assets/{SetupPage-BeBReYLP.js → SetupPage-CBDD4rpC.js} +1 -1
- package/apps/web/dist/assets/{SharePage-Cv8toByB.js → SharePage-70niRKaO.js} +1 -1
- package/apps/web/dist/assets/{api-rJBQEu1G.js → api-C4M6cbpW.js} +1 -1
- package/apps/web/dist/assets/changelog-COyL1B5X.js +1 -0
- package/apps/web/dist/assets/definition-DoCLtZZL.js +55 -0
- package/apps/web/dist/assets/{esm-DFNBMDKB.js → esm-CfW8Rmtq.js} +1 -1
- package/apps/web/dist/assets/index-CJ0YJ5HC.css +1 -0
- package/apps/web/dist/assets/{index-CoTWrikR.js → index-DMKXnSf-.js} +3 -3
- package/apps/web/dist/assets/meta-6jZygxJq.js +1 -0
- package/apps/web/dist/assets/{settings-menu-bsLDpw56.js → settings-menu-Dph4yXbO.js} +1 -1
- package/apps/web/dist/assets/{table-2-BdDuBcF2.js → star-UHmZXpjA.js} +1 -1
- package/apps/web/dist/assets/ui-BS348L4M.js +1 -0
- package/apps/web/dist/assets/wand-sparkles-IEd4jkyn.js +1 -0
- package/apps/web/dist/index.html +4 -4
- package/apps/web/dist/mcp/flow.html +60 -60
- package/node_modules/@engenty-wizards/shared/dist/decision.d.ts +76 -0
- package/node_modules/@engenty-wizards/shared/dist/decision.js +147 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +1048 -50
- package/node_modules/@engenty-wizards/shared/dist/definition.js +516 -43
- package/node_modules/@engenty-wizards/shared/dist/marketplace-entry.js +19 -2
- package/node_modules/@engenty-wizards/shared/dist/marketplace.d.ts +1 -1
- package/node_modules/@engenty-wizards/shared/dist/run.d.ts +55 -0
- package/node_modules/@engenty-wizards/shared/dist/run.js +3 -0
- package/node_modules/@engenty-wizards/shared/dist/surface.d.ts +89 -0
- package/node_modules/@engenty-wizards/shared/dist/surface.js +198 -0
- package/package.json +1 -1
- package/apps/web/dist/assets/EditorPage-Dwg-K4UI.js +0 -2
- package/apps/web/dist/assets/NewWizardPage-BgnrGN8A.js +0 -2
- package/apps/web/dist/assets/ProjectPage-Cfco8MIG.js +0 -5
- package/apps/web/dist/assets/RunDrawer-B50sCUSw.js +0 -1
- package/apps/web/dist/assets/RunnerView-CFCmOmJI.js +0 -70
- package/apps/web/dist/assets/changelog-BmS3l433.js +0 -1
- package/apps/web/dist/assets/definition-BznNdlhf.js +0 -55
- package/apps/web/dist/assets/index-BZs1IxAk.css +0 -1
- package/apps/web/dist/assets/meta-DJta2rA3.js +0 -1
- package/apps/web/dist/assets/ui-DJOZSSKo.js +0 -1
- package/apps/web/dist/assets/wand-sparkles-Clj3VRB5.js +0 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { pOf } from "@engenty-wizards/shared/decision";
|
|
1
2
|
import { allFields, dataRef, isDecisionStep, LOCALES, templateRefs, wizardLang, } from "@engenty-wizards/shared/definition";
|
|
3
|
+
import { SURFACE_GUIDE, validateSurface, } from "@engenty-wizards/shared/surface";
|
|
2
4
|
import { Agent } from "@mastra/core/agent";
|
|
3
5
|
import { generateText, Output } from "ai";
|
|
4
6
|
import { z } from "zod";
|
|
@@ -12,7 +14,9 @@ import { buildStepTools } from "../tools/index.js";
|
|
|
12
14
|
import { spaceContextOf } from "../tools/plugin.js";
|
|
13
15
|
import { personUploads } from "../tools/store.js";
|
|
14
16
|
import { runWidgetStep } from "../widgets/step.js";
|
|
17
|
+
import { decide } from "./decide.js";
|
|
15
18
|
import { prepareInputs } from "./prepare.js";
|
|
19
|
+
import { runSurfaceStep } from "./surface.js";
|
|
16
20
|
import { answersAsText, colorLine, factLines, renderTemplate, resolveRef, } from "./template.js";
|
|
17
21
|
import { StepError } from "./types.js";
|
|
18
22
|
/** Today's date as the wizard's people write it. */
|
|
@@ -51,7 +55,12 @@ async function previousResult(ctx, stepId) {
|
|
|
51
55
|
async function revisionBlock(ctx, stepId) {
|
|
52
56
|
const note = ctx.state.notes[stepId];
|
|
53
57
|
if (!note) {
|
|
54
|
-
|
|
58
|
+
// A branch back to this step (a loop) runs it again: it builds on what it made last time.
|
|
59
|
+
const looped = Object.entries(ctx.state.loops ?? {}).some(([key, n]) => n > 0 && key.endsWith(`→${stepId}`));
|
|
60
|
+
const prev = looped ? await previousResult(ctx, stepId) : "";
|
|
61
|
+
return prev
|
|
62
|
+
? `# EARLIER ATTEMPT\nA later step sent the run back to this step. What it made last time — improve on it with what is known now:\n"""\n${prev}\n"""`
|
|
63
|
+
: "";
|
|
55
64
|
}
|
|
56
65
|
const prev = await previousResult(ctx, stepId);
|
|
57
66
|
return `# REVISION REQUEST\nThe person reviewed the previous result and asked for this change:\n"""${note}"""\n\n${prev ? `Previous result:\n"""\n${prev}\n"""` : ""}`;
|
|
@@ -88,6 +97,11 @@ function outputSchema(step) {
|
|
|
88
97
|
case "choice":
|
|
89
98
|
shape[f.id] = z.enum(f.options).describe(d);
|
|
90
99
|
break;
|
|
100
|
+
case "score":
|
|
101
|
+
shape[f.id] = z
|
|
102
|
+
.enum(f.options)
|
|
103
|
+
.describe(`${d} (lowest to highest)`);
|
|
104
|
+
break;
|
|
91
105
|
case "table":
|
|
92
106
|
shape[f.id] = f.columns?.length
|
|
93
107
|
? z
|
|
@@ -148,7 +162,186 @@ async function seenPhotos(step, ctx, resolved, uploads) {
|
|
|
148
162
|
}
|
|
149
163
|
return out;
|
|
150
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* A decision step: its yes/no, choice and score fields are the questions, its prompt the state,
|
|
167
|
+
* answered in one call through decide() — with probabilities where a decision model answers.
|
|
168
|
+
*/
|
|
169
|
+
async function decideStep(step, prompt, ctx) {
|
|
170
|
+
const fields = step.output.fields ?? [];
|
|
171
|
+
const questions = {};
|
|
172
|
+
for (const f of fields) {
|
|
173
|
+
const instructions = f.description ?? f.id;
|
|
174
|
+
if (f.kind === "yesno") {
|
|
175
|
+
questions[f.id] = { type: "noul", instructions };
|
|
176
|
+
}
|
|
177
|
+
else if (f.kind === "choice") {
|
|
178
|
+
questions[f.id] = {
|
|
179
|
+
type: "choice",
|
|
180
|
+
instructions,
|
|
181
|
+
criteria: Object.fromEntries((f.options ?? []).map((o) => [o, null])),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
else if (f.kind === "score") {
|
|
185
|
+
questions[f.id] = { type: "score", instructions, criteria: f.options ?? [] };
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const decision = await decide({
|
|
189
|
+
state: prompt,
|
|
190
|
+
questions,
|
|
191
|
+
call: ctx.call,
|
|
192
|
+
signal: ctx.signal,
|
|
193
|
+
charge: ctx.chargeUsd,
|
|
194
|
+
});
|
|
195
|
+
const json = {};
|
|
196
|
+
const decided = {};
|
|
197
|
+
for (const [id, answer] of Object.entries(decision.answers)) {
|
|
198
|
+
json[id] =
|
|
199
|
+
answer.type === "noul"
|
|
200
|
+
? answer.noul >= 0.5
|
|
201
|
+
: answer.type === "choice"
|
|
202
|
+
? answer.choice
|
|
203
|
+
: answer.label;
|
|
204
|
+
decided[id] = Math.round(pOf(answer) * 1000) / 1000;
|
|
205
|
+
}
|
|
206
|
+
const text = fields
|
|
207
|
+
.map((f) => {
|
|
208
|
+
const value = json[f.id];
|
|
209
|
+
return `${f.description ?? f.id}: ${value === true ? "ja" : value === false ? "nein" : String(value)}`;
|
|
210
|
+
})
|
|
211
|
+
.join("\n");
|
|
212
|
+
return { text, json, decided, at: new Date().toISOString() };
|
|
213
|
+
}
|
|
214
|
+
/** The JSON array in a model's answer, fenced or not. */
|
|
215
|
+
function jsonArrayIn(text) {
|
|
216
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/)?.[1] ?? text;
|
|
217
|
+
const start = fenced.indexOf("[");
|
|
218
|
+
const end = fenced.lastIndexOf("]");
|
|
219
|
+
if (start < 0 || end <= start) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
try {
|
|
223
|
+
return JSON.parse(fenced.slice(start, end + 1));
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The view an agent step composes of its result: the standard class writes components from the
|
|
231
|
+
* surface catalog bound to the step's fields, the catalog's validator checks them, and one try
|
|
232
|
+
* with the issues follows. Without a valid view the plain result shows: the step never fails
|
|
233
|
+
* for its view.
|
|
234
|
+
*/
|
|
235
|
+
async function composeSurface(step, json, ctx) {
|
|
236
|
+
const keys = Object.keys(json);
|
|
237
|
+
const fields = (step.output.fields ?? [])
|
|
238
|
+
.map((f) => `- /${f.id} (${f.kind}${f.columns ? `: ${f.columns.join(", ")}` : ""}): ${f.description ?? ""}`)
|
|
239
|
+
.join("\n");
|
|
240
|
+
const sample = JSON.stringify(json).slice(0, 4000);
|
|
241
|
+
try {
|
|
242
|
+
const writer = await textModel("standard", ctx.call);
|
|
243
|
+
let issues = [];
|
|
244
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
245
|
+
const result = await generateText({
|
|
246
|
+
model: writer.model,
|
|
247
|
+
abortSignal: ctx.signal,
|
|
248
|
+
prompt: [
|
|
249
|
+
`Compose a view of this result for the person who ran "${ctx.def.title}". Answer with the JSON array of components only.`,
|
|
250
|
+
SURFACE_GUIDE,
|
|
251
|
+
`# THE DATA (bind by path, never copy values)\n${fields}\n\nSample: ${sample}`,
|
|
252
|
+
issues.length
|
|
253
|
+
? `# YOUR LAST ANSWER HAD THESE PROBLEMS — fix them\n${issues.join("\n")}`
|
|
254
|
+
: "",
|
|
255
|
+
]
|
|
256
|
+
.filter(Boolean)
|
|
257
|
+
.join("\n\n"),
|
|
258
|
+
});
|
|
259
|
+
await ctx.chargeUsd(costOf(writer, result.usage));
|
|
260
|
+
const components = jsonArrayIn(result.text);
|
|
261
|
+
issues = validateSurface(components, keys).map((i) => i.message);
|
|
262
|
+
if (!issues.length) {
|
|
263
|
+
return { components: components, data: json };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
console.warn(`[step ${step.id}] no valid view:`, issues.join("; "));
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
if (ctx.signal.aborted) {
|
|
270
|
+
throw err;
|
|
271
|
+
}
|
|
272
|
+
console.warn(`[step ${step.id}] view not composed:`, err.message);
|
|
273
|
+
}
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
/** An agent step runs this many times at most with `each`; more entries are left out. */
|
|
277
|
+
const MAX_AGENT_ENTRIES = 20;
|
|
278
|
+
/** The entries an agent step with `each` runs for: rows of a table, entries of a list, list rows. */
|
|
279
|
+
function agentEntries(step, ctx) {
|
|
280
|
+
const ref = dataRef(step.each ?? "");
|
|
281
|
+
const list = ref.match(/^lists\.([a-zA-Z][a-zA-Z0-9_]*)$/)?.[1];
|
|
282
|
+
const value = list
|
|
283
|
+
? (ctx.scope.lists?.[list]?.rows ?? []).map((r) => r.cells)
|
|
284
|
+
: resolveRef(ref, ctx.scope);
|
|
285
|
+
return (Array.isArray(value) ? value : []).slice(0, MAX_AGENT_ENTRIES);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* An agent step with `each`: the step once per entry, one after the other, each reading its
|
|
289
|
+
* entry as {{item}}. The results become one table — the entry's columns and the step's output
|
|
290
|
+
* fields — and one text with a heading per entry.
|
|
291
|
+
*/
|
|
292
|
+
async function runAgentEach(step, ctx) {
|
|
293
|
+
const entries = agentEntries(step, ctx);
|
|
294
|
+
if (!entries.length) {
|
|
295
|
+
throw new StepError("Es gibt keine Einträge, für die dieser Schritt arbeiten könnte.");
|
|
296
|
+
}
|
|
297
|
+
// The view, if any, is composed once over the table of all entries.
|
|
298
|
+
const single = {
|
|
299
|
+
...step,
|
|
300
|
+
each: undefined,
|
|
301
|
+
output: { ...step.output, surface: false },
|
|
302
|
+
};
|
|
303
|
+
const rows = [];
|
|
304
|
+
const texts = [];
|
|
305
|
+
const assets = [];
|
|
306
|
+
for (const [index, item] of entries.entries()) {
|
|
307
|
+
await ctx.emit("info", { code: "entry", params: { n: index + 1, total: entries.length } });
|
|
308
|
+
const scope = { ...ctx.scope, entry: { item, index, count: entries.length } };
|
|
309
|
+
const out = await runAgentStep(single, { ...ctx, scope });
|
|
310
|
+
const own = item && typeof item === "object" ? item : { item };
|
|
311
|
+
const json = out.json && typeof out.json === "object" ? out.json : {};
|
|
312
|
+
rows.push({ ...own, ...json });
|
|
313
|
+
const title = Object.values(own).find((v) => typeof v === "string") ?? `${index + 1}`;
|
|
314
|
+
texts.push(`## ${String(title)}\n\n${out.text ?? ""}`.trim());
|
|
315
|
+
assets.push(...(out.assets ?? []));
|
|
316
|
+
}
|
|
317
|
+
const json = { rows };
|
|
318
|
+
const surface = step.output.surface
|
|
319
|
+
? await composeSurface({
|
|
320
|
+
...step,
|
|
321
|
+
output: {
|
|
322
|
+
...step.output,
|
|
323
|
+
fields: [
|
|
324
|
+
{
|
|
325
|
+
id: "rows",
|
|
326
|
+
kind: "table",
|
|
327
|
+
description: "One row per entry: its columns and the step's fields",
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
}, json, ctx)
|
|
332
|
+
: undefined;
|
|
333
|
+
return {
|
|
334
|
+
text: texts.join("\n\n"),
|
|
335
|
+
json,
|
|
336
|
+
...(surface ? { surface } : {}),
|
|
337
|
+
assets: assets.length ? assets : undefined,
|
|
338
|
+
at: new Date().toISOString(),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
151
341
|
export async function runAgentStep(step, ctx) {
|
|
342
|
+
if (step.each) {
|
|
343
|
+
return runAgentEach(step, ctx);
|
|
344
|
+
}
|
|
152
345
|
const resolved = await textModel(step.model ?? "high", { ...ctx.call, effort: step.effort });
|
|
153
346
|
const uploads = await personUploads(ctx);
|
|
154
347
|
const { tools, assets, close } = await buildStepTools(step, ctx, resolved, uploads);
|
|
@@ -192,22 +385,7 @@ export async function runAgentStep(step, ctx) {
|
|
|
192
385
|
.join("\n\n");
|
|
193
386
|
// A decision needs no agent: its questions go to the classifier class in one call.
|
|
194
387
|
if (isDecisionStep(step) && uploads.length === 0) {
|
|
195
|
-
|
|
196
|
-
const decision = await generateText({
|
|
197
|
-
model: resolved.model,
|
|
198
|
-
abortSignal: ctx.signal,
|
|
199
|
-
output: Output.object({ schema }),
|
|
200
|
-
prompt,
|
|
201
|
-
});
|
|
202
|
-
await ctx.chargeUsd(costOf(resolved, decision.usage));
|
|
203
|
-
const json = decision.output;
|
|
204
|
-
const text = fields
|
|
205
|
-
.map((f) => {
|
|
206
|
-
const value = json[f.id];
|
|
207
|
-
return `${f.description ?? f.id}: ${value === true ? "ja" : value === false ? "nein" : String(value)}`;
|
|
208
|
-
})
|
|
209
|
-
.join("\n");
|
|
210
|
-
return { text, json, at: new Date().toISOString() };
|
|
388
|
+
return decideStep(step, prompt, ctx);
|
|
211
389
|
}
|
|
212
390
|
const agent = new Agent({
|
|
213
391
|
id: `step-${step.id}`,
|
|
@@ -260,7 +438,14 @@ export async function runAgentStep(step, ctx) {
|
|
|
260
438
|
});
|
|
261
439
|
await ctx.chargeUsd(costOf(structurer, structured.usage));
|
|
262
440
|
const json = tablesToRecords(structured.output, fields);
|
|
263
|
-
|
|
441
|
+
const surface = step.output.surface ? await composeSurface(step, json, ctx) : undefined;
|
|
442
|
+
return {
|
|
443
|
+
text,
|
|
444
|
+
json,
|
|
445
|
+
...(surface ? { surface } : {}),
|
|
446
|
+
assets: assets.length ? assets : undefined,
|
|
447
|
+
at: new Date().toISOString(),
|
|
448
|
+
};
|
|
264
449
|
}
|
|
265
450
|
finally {
|
|
266
451
|
await close();
|
|
@@ -604,5 +789,8 @@ export async function runAutomaticStep(step, ctx) {
|
|
|
604
789
|
if (step.type === "film") {
|
|
605
790
|
return runFilmStep(step, ctx);
|
|
606
791
|
}
|
|
792
|
+
if (step.type === "surface") {
|
|
793
|
+
return runSurfaceStep(step, ctx);
|
|
794
|
+
}
|
|
607
795
|
throw new StepError(`Step ${step.id} is not automatic.`);
|
|
608
796
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { assembleSurface, dataRef, listRef, } from "@engenty-wizards/shared/definition";
|
|
2
|
+
import { validateSurface } from "@engenty-wizards/shared/surface";
|
|
3
|
+
import { decide } from "./decide.js";
|
|
4
|
+
import { answersAsText, resolveRef } from "./template.js";
|
|
5
|
+
import { StepError } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* A surface step: its data read from the run (answers, outputs, stored lists; the pictures a
|
|
8
|
+
* step made as asset ids), its components written once — or, for a decided surface, the pieces
|
|
9
|
+
* one decision keeps. Checked against the catalog before it is shown.
|
|
10
|
+
*/
|
|
11
|
+
export async function runSurfaceStep(step, ctx) {
|
|
12
|
+
const data = surfaceData(step.data, ctx);
|
|
13
|
+
const components = step.components ?? (await decidedComponents(step, ctx));
|
|
14
|
+
const issues = validateSurface(components, Object.keys(data));
|
|
15
|
+
if (issues.length) {
|
|
16
|
+
throw new StepError(`Die Ansicht ist fehlerhaft: ${issues.map((i) => i.message).join(" ")}`);
|
|
17
|
+
}
|
|
18
|
+
return { surface: { components, data }, at: new Date().toISOString() };
|
|
19
|
+
}
|
|
20
|
+
/** What a surface reads: key → a field, a step's output or one of its fields, a stored list. */
|
|
21
|
+
export function surfaceData(refs, ctx) {
|
|
22
|
+
const out = {};
|
|
23
|
+
for (const [key, raw] of Object.entries(refs)) {
|
|
24
|
+
const ref = dataRef(raw);
|
|
25
|
+
const list = listRef(ref);
|
|
26
|
+
if (list) {
|
|
27
|
+
out[key] = (ctx.scope.lists?.[list]?.rows ?? []).map((r) => r.cells);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const source = ctx.def.steps.find((s) => `steps.${s.id}` === ref);
|
|
31
|
+
if (source && (source.type === "generate" || source.type === "widget")) {
|
|
32
|
+
// Pictures and clips by asset id: the runner shows them from the run's files.
|
|
33
|
+
const ids = (ctx.state.outputs[source.id]?.assets ?? []).map((a) => a.id);
|
|
34
|
+
out[key] = source.type === "generate" && source.each ? ids : (ids[0] ?? null);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const output = source ? ctx.state.outputs[source.id] : undefined;
|
|
38
|
+
out[key] = output ? (output.json ?? output.text ?? null) : (resolveRef(ref, ctx.scope) ?? null);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
/** The pieces of a decided surface one decision keeps: required ones always. */
|
|
43
|
+
async function decidedComponents(step, ctx) {
|
|
44
|
+
const candidates = step.candidates ?? [];
|
|
45
|
+
const questions = {};
|
|
46
|
+
for (const c of candidates) {
|
|
47
|
+
if (!c.required && !c.group) {
|
|
48
|
+
questions[`p_${c.id}`] = {
|
|
49
|
+
type: "noul",
|
|
50
|
+
instructions: `Should the view show this: ${c.description}`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (const g of step.groups ?? []) {
|
|
55
|
+
const members = candidates.filter((c) => c.group === g.id && !c.required);
|
|
56
|
+
if (members.length) {
|
|
57
|
+
questions[`g_${g.id}`] = {
|
|
58
|
+
type: "choice",
|
|
59
|
+
instructions: g.instructions,
|
|
60
|
+
criteria: {
|
|
61
|
+
...Object.fromEntries(members.map((c) => [c.id, c.description])),
|
|
62
|
+
...(g.optional ? { none: "None of these." } : {}),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const kept = new Set(candidates.filter((c) => c.required).map((c) => c.id));
|
|
68
|
+
if (Object.keys(questions).length) {
|
|
69
|
+
const results = Object.fromEntries(ctx.def.steps
|
|
70
|
+
.map((s) => [s.title, ctx.state.outputs[s.id]?.text ?? ""])
|
|
71
|
+
.filter(([, text]) => text)
|
|
72
|
+
.map(([title, text]) => [title, text.slice(0, 6000)]));
|
|
73
|
+
const decision = await decide({
|
|
74
|
+
state: { answers: answersAsText(ctx.scope), results },
|
|
75
|
+
questions,
|
|
76
|
+
call: ctx.call,
|
|
77
|
+
signal: ctx.signal,
|
|
78
|
+
charge: ctx.chargeUsd,
|
|
79
|
+
});
|
|
80
|
+
for (const [name, answer] of Object.entries(decision.answers)) {
|
|
81
|
+
if (answer.type === "noul" && answer.noul >= 0.5) {
|
|
82
|
+
kept.add(name.slice(2));
|
|
83
|
+
}
|
|
84
|
+
else if (answer.type === "choice" && answer.choice !== "none") {
|
|
85
|
+
kept.add(answer.choice);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return assembleSurface(candidates, kept);
|
|
90
|
+
}
|
|
@@ -69,6 +69,13 @@ export async function renderDownload(step, output, format, baseName) {
|
|
|
69
69
|
? { data: new Uint8Array(found.data), mime: found.row.mime, filename: file(format) }
|
|
70
70
|
: null;
|
|
71
71
|
}
|
|
72
|
+
if (step.type === "surface") {
|
|
73
|
+
return {
|
|
74
|
+
data: JSON.stringify(output.surface ?? {}, null, 2),
|
|
75
|
+
mime: MIME.json,
|
|
76
|
+
filename: file("json"),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
72
79
|
if (step.type === "widget") {
|
|
73
80
|
const source = output.assets?.find((a) => a.mime === "text/html");
|
|
74
81
|
if (format === "json") {
|
|
@@ -558,8 +558,16 @@ export const runRoutes = new Hono()
|
|
|
558
558
|
if (!run || !connection) {
|
|
559
559
|
return c.json({ error: "not found" }, 404);
|
|
560
560
|
}
|
|
561
|
-
|
|
562
|
-
|
|
561
|
+
try {
|
|
562
|
+
const url = await startOAuth(scopeOf(run), await projectIdOf(run), run.id, connection, c.req.param("connectorId"));
|
|
563
|
+
return c.json({ url });
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
if (err instanceof ConnectError) {
|
|
567
|
+
return c.json({ error: err.message }, 422);
|
|
568
|
+
}
|
|
569
|
+
throw err;
|
|
570
|
+
}
|
|
563
571
|
})
|
|
564
572
|
.post("/:id/connections/:connectionId/credentials/:connectorId", async (c) => {
|
|
565
573
|
const run = await accessibleRun(c, c.req.param("id"));
|
|
@@ -780,13 +788,18 @@ function sendDownload(c, download) {
|
|
|
780
788
|
*/
|
|
781
789
|
export const connectCallback = new Hono().get("/callback", async (c) => {
|
|
782
790
|
const code = c.req.query("code");
|
|
791
|
+
// Connected through the account's Manage-App: a ticket instead of a code.
|
|
792
|
+
const ticket = c.req.query("ticket");
|
|
783
793
|
const state = c.req.query("state");
|
|
784
794
|
let ok = false;
|
|
785
|
-
let message = "
|
|
795
|
+
let message = c.req.query("error") === "exchange_failed"
|
|
796
|
+
? "Verbinden hat nicht geklappt. Bitte noch einmal versuchen."
|
|
797
|
+
: "Verbinden wurde abgebrochen.";
|
|
786
798
|
const tenant = state ? await tenantOfRun(oauthStateRun(state) ?? "") : null;
|
|
787
|
-
|
|
799
|
+
const answer = ticket ? { ticket } : code ? { code } : null;
|
|
800
|
+
if (answer && state && tenant) {
|
|
788
801
|
try {
|
|
789
|
-
const done = await withTenant(tenant, () => finishOAuth(
|
|
802
|
+
const done = await withTenant(tenant, () => finishOAuth(answer, state));
|
|
790
803
|
signalChanged(done.runId);
|
|
791
804
|
ok = true;
|
|
792
805
|
message = "Verbunden. Du kannst dieses Fenster schließen.";
|
|
@@ -1,32 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { decide } from "../engine/decide.js";
|
|
2
2
|
/**
|
|
3
3
|
* The last step of a search of Wissen: does each candidate the index found help answer the
|
|
4
|
-
* question?
|
|
5
|
-
* on its own
|
|
6
|
-
*
|
|
4
|
+
* question? One yes/no question per candidate, all in one decision: a decision model (Jev)
|
|
5
|
+
* answers each on its own with P(yes); without one the classifier class's language model
|
|
6
|
+
* answers yes or no. What falls under MIN_RELEVANCE goes; the rest is ranked by it. As
|
|
7
|
+
* engenty-pro's knowledge base checks its hits.
|
|
7
8
|
*/
|
|
8
9
|
export const MIN_RELEVANCE = 0.5;
|
|
9
10
|
/** A search waits for a person: a classifier that cannot answer in this time is left out. */
|
|
10
11
|
const TIMEOUT_MS = 4000;
|
|
11
|
-
const ATTEMPTS = 2;
|
|
12
12
|
const TEXT_CHARS = 1200;
|
|
13
13
|
const clip = (value, max) => {
|
|
14
14
|
const s = value.replace(/\s+/g, " ").trim();
|
|
15
15
|
return s.length > max ? `${s.slice(0, max - 1)}…` : s;
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
|
-
* P(relevant) for each candidate, in their order
|
|
19
|
-
*
|
|
20
|
-
* the order the index gave.
|
|
18
|
+
* P(relevant) for each candidate, in their order. Null for all of them when no way decided in
|
|
19
|
+
* time: the search then keeps the order the index gave.
|
|
21
20
|
*/
|
|
22
21
|
export async function judgeRelevance(query, candidates, signal) {
|
|
23
22
|
if (!candidates.length) {
|
|
24
23
|
return [];
|
|
25
24
|
}
|
|
26
|
-
const access = await systemOneAccess().catch(() => null);
|
|
27
|
-
if (!access) {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
25
|
const questions = {};
|
|
31
26
|
const state = {
|
|
32
27
|
query: clip(query, 600),
|
|
@@ -49,42 +44,15 @@ export async function judgeRelevance(query, candidates, signal) {
|
|
|
49
44
|
};
|
|
50
45
|
}),
|
|
51
46
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
body,
|
|
63
|
-
signal: signal
|
|
64
|
-
? AbortSignal.any([signal, AbortSignal.timeout(TIMEOUT_MS)])
|
|
65
|
-
: AbortSignal.timeout(TIMEOUT_MS),
|
|
66
|
-
});
|
|
67
|
-
if (!res.ok) {
|
|
68
|
-
if ([429, 503, 529].includes(res.status) && attempt < ATTEMPTS) {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
console.warn(`[relevance] the classifier answered ${res.status}`);
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
const answer = (await res.json());
|
|
75
|
-
return candidates.map((_, index) => {
|
|
76
|
-
const a = answer.answers?.[`c${index}`];
|
|
77
|
-
return a?.type === "noul" && typeof a.noul === "number" && Number.isFinite(a.noul)
|
|
78
|
-
? Math.round(a.noul * 1000) / 1000
|
|
79
|
-
: null;
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
if (signal?.aborted || attempt >= ATTEMPTS) {
|
|
84
|
-
console.warn("[relevance] the classifier did not answer:", err.message);
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
47
|
+
try {
|
|
48
|
+
const decision = await decide({ state, questions, signal, deadlineMs: TIMEOUT_MS });
|
|
49
|
+
return candidates.map((_, index) => {
|
|
50
|
+
const a = decision.answers[`c${index}`];
|
|
51
|
+
return a?.type === "noul" ? Math.round(a.noul * 1000) / 1000 : null;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
console.warn("[relevance] no decision:", err.message);
|
|
56
|
+
return null;
|
|
88
57
|
}
|
|
89
|
-
return null;
|
|
90
58
|
}
|
|
@@ -5,12 +5,24 @@ import { pageReadInput, readKnowledgePage } from "./project.js";
|
|
|
5
5
|
import { attempt, clip } from "./shared.js";
|
|
6
6
|
/**
|
|
7
7
|
* Pages for a step that lists "pages": Markdown its wizard keeps for every run — notes, a log, a
|
|
8
|
-
* summary that grows — shown in the studio under Space → Daten. Its
|
|
9
|
-
* pages of Wissen, by path.
|
|
8
|
+
* summary that grows — its memory, shown in the studio's Memory tab and under Space → Daten. Its
|
|
9
|
+
* page_read also reads the pages of Wissen, by path. A test run reads the wizard's pages but
|
|
10
|
+
* writes into a copy of its own in the run's state, which goes with the run.
|
|
10
11
|
*/
|
|
11
12
|
export function pageTools(ctx) {
|
|
12
13
|
const projectId = ctx.project.id;
|
|
13
14
|
const wizardId = ctx.store.wizardId;
|
|
15
|
+
/** The wizard's pages as this run sees them: a test run's own writes over the real ones. */
|
|
16
|
+
const pages = async () => {
|
|
17
|
+
const real = await runPages(projectId, wizardId);
|
|
18
|
+
const copy = ctx.test ? (ctx.state.memory ?? {}) : {};
|
|
19
|
+
const lower = (t) => t.toLowerCase();
|
|
20
|
+
const written = Object.entries(copy).map(([title, markdown]) => ({ title, markdown }));
|
|
21
|
+
return [
|
|
22
|
+
...real.filter((p) => !written.some((w) => lower(w.title) === lower(p.title))),
|
|
23
|
+
...written,
|
|
24
|
+
].sort((a, b) => a.title.localeCompare(b.title));
|
|
25
|
+
};
|
|
14
26
|
return {
|
|
15
27
|
page_read: createTool({
|
|
16
28
|
id: "page_read",
|
|
@@ -26,13 +38,13 @@ export function pageTools(ctx) {
|
|
|
26
38
|
return readKnowledgePage(ctx, { path, section, from });
|
|
27
39
|
}
|
|
28
40
|
return attempt(async () => {
|
|
29
|
-
const
|
|
41
|
+
const all = await pages();
|
|
30
42
|
if (!title?.trim()) {
|
|
31
|
-
return { pages:
|
|
43
|
+
return { pages: all.map((p) => ({ title: p.title, chars: p.markdown.length })) };
|
|
32
44
|
}
|
|
33
|
-
const page =
|
|
45
|
+
const page = all.find((p) => p.title.toLowerCase() === title.trim().toLowerCase());
|
|
34
46
|
if (!page) {
|
|
35
|
-
return { error: `No page "${title}".`, pages:
|
|
47
|
+
return { error: `No page "${title}".`, pages: all.map((p) => p.title) };
|
|
36
48
|
}
|
|
37
49
|
return { title: page.title, markdown: clip(page.markdown, 40_000) };
|
|
38
50
|
});
|
|
@@ -47,6 +59,19 @@ export function pageTools(ctx) {
|
|
|
47
59
|
append: z.boolean().optional(),
|
|
48
60
|
}),
|
|
49
61
|
execute: (input) => attempt(async () => {
|
|
62
|
+
if (ctx.test) {
|
|
63
|
+
const title = input.title.trim();
|
|
64
|
+
const before = (await pages()).find((p) => p.title.toLowerCase() === title.toLowerCase());
|
|
65
|
+
const markdown = before && input.append
|
|
66
|
+
? `${before.markdown.trimEnd()}\n\n${input.markdown.trim()}`
|
|
67
|
+
: input.markdown;
|
|
68
|
+
ctx.state.memory = { ...ctx.state.memory, [before?.title ?? title]: markdown };
|
|
69
|
+
await ctx.emit("tool", {
|
|
70
|
+
code: "writesPage",
|
|
71
|
+
params: { title: before?.title ?? title },
|
|
72
|
+
});
|
|
73
|
+
return { title: before?.title ?? title, chars: markdown.length, test: true };
|
|
74
|
+
}
|
|
50
75
|
const page = await writeRunPage(projectId, wizardId, input);
|
|
51
76
|
await ctx.emit("tool", { code: "writesPage", params: { title: page.title } });
|
|
52
77
|
return page;
|
|
@@ -1 +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-rJBQEu1G.js";import{t as s}from"./createLucideIcon-q3MZMmnf.js";import{t as c}from"./check-CUpby_J9.js";import{n as l,r as u}from"./upload-DNRENWzQ.js";import{t as d}from"./external-link-MAL7vJYj.js";import{c as f,f as p,g as m,h,n as g,o as ee,r as _,s as v,t as y,x as b,y as x}from"./ui-DJOZSSKo.js";import{F as te,K as S,V as C,f as w,o as T,p as E,u as D,x as O}from"./index-CoTWrikR.js";import{n as k}from"./LocalRuntime-CYhPXwAv.js";var A={name:`hard-drive`,size:24,node:[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]};A.node;var j=s(A),M={name:`layout-grid`,size:24,node:[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]};M.node;var N=s(M),P={name:`list`,size:24,node:[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]};P.node;var F=s(P),I=e(t(),1),L=e=>[`project-files`,e];function R(e){return i({queryKey:L(e),queryFn:()=>a.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function z(e,t){return r(`/api/studio/projects/${e}/files/${t}/content`)}function B(e,t=!1){let n=o(),[r,i]=(0,I.useState)(!1),[s,c]=(0,I.useState)(null),l=()=>n.invalidateQueries({queryKey:L(e)}),u=async e=>{c(null);try{await e()}catch(e){c(e.message)}finally{await l()}};return{busy:r,error:s,readOnly:t,upload:async(t,n)=>{i(!0),await u(async()=>{for(let r of n)await a.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await l()}),i(!1)},describe:(t,n)=>u(()=>a.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>u(()=>a.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>u(()=>a.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>u(()=>a.put(`/api/studio/projects/${e}/files/order`,{kind:t,ids:n}))}}function V(e,t){let n=`wz.layout.${e}`,[r,i]=(0,I.useState)(()=>{try{let e=localStorage.getItem(n);return e===`list`||e===`cards`?e:t}catch{return t}});return[r,()=>i(e=>{let t=e===`list`?`cards`:`list`;try{localStorage.setItem(n,t)}catch{}return t})]}function H(e,t,n=700){let[r,i]=(0,I.useState)(`idle`),[a,o]=(0,I.useState)(null),s=JSON.stringify(e),c=(0,I.useRef)(s),l=(0,I.useRef)({value:e,json:s,save:t});l.current={value:e,json:s,save:t};let u=(0,I.useRef)(Promise.resolve()),d=(0,I.useCallback)(()=>{let e=l.current;e.json!==c.current&&(c.current=e.json,i(`saving`),u.current=u.current.then(async()=>{try{await e.save(e.value),o(null),i(`saved`)}catch(e){c.current=``,o(e.message),i(`error`)}}))},[]);return(0,I.useEffect)(()=>{if(s===c.current)return;let e=setTimeout(d,n);return()=>clearTimeout(e)},[s,n,d]),(0,I.useEffect)(()=>d,[d]),{state:r,error:a}}function U(e){return e<1e6?`${Math.max(1,Math.round(e/1e3))} KB`:`${(e/1e6).toFixed(1)} MB`}var W=e(n(),1);function G({id:e,children:t}){return(0,W.jsx)(`div`,{id:e,className:`scroll-mt-24 max-md:scroll-mt-36`,children:t})}function K({title:e,hint:t,save:n,action:r,locked:i,plain:a,children:o}){return(0,W.jsxs)(`section`,{className:`flex flex-col gap-2.5`,children:[(0,W.jsxs)(`div`,{className:`flex items-start justify-between gap-4 px-1`,children:[(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,W.jsx)(`h2`,{className:`font-display font-semibold text-lg leading-tight`,children:e}),n?.state===`saving`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[0.75rem] text-ink-3`,children:[(0,W.jsx)(p,{className:`size-3`}),` `,b(`project.saving`)]}):n?.state===`saved`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[0.75rem] text-moss`,children:[(0,W.jsx)(c,{className:`size-3.5`}),` `,b(`settings.saved`)]}):null]}),t?(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-snug`,children:t}):null]}),r?(0,W.jsx)(`div`,{className:`shrink-0`,children:r}):null]}),a?o:(0,W.jsxs)(g,{className:`p-3.5 sm:p-5`,children:[i?(0,W.jsx)(`fieldset`,{disabled:!0,className:`min-w-0`,children:o}):o,n?.state===`error`&&n.error?(0,W.jsx)(`p`,{className:`mt-4 text-[0.875rem] text-rose`,children:n.error}):null]})]})}function q({children:e,layout:t,onToggle:n}){return(0,W.jsxs)(`div`,{className:`mb-3 flex items-start gap-2`,children:[(0,W.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,W.jsx)(`div`,{className:`w-56 max-w-full transition-[width] duration-200 focus-within:w-full has-[input:not(:placeholder-shown)]:w-full`,children:e})}),(0,W.jsx)(ee,{label:b(t===`list`?`project.viewCards`:`project.viewList`),onClick:n,children:t===`list`?(0,W.jsx)(N,{className:`size-4`}):(0,W.jsx)(F,{className:`size-4`})})]})}function J({value:e,onChange:t,onEnter:n,placeholder:r,busy:i}){return(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(l,{className:`-translate-y-1/2 pointer-events-none absolute top-1/2 left-3 size-4 text-ink-4`}),(0,W.jsx)(`input`,{type:`search`,value:e,placeholder:r,onChange:e=>t(e.target.value),onKeyDown:e=>e.key===`Enter`&&n?.(),className:`h-9 w-full rounded-lg border border-input bg-card pr-3 pl-9 text-[0.875rem] text-ink outline-none transition placeholder:text-ink-4 focus:border-focus focus:ring-4 focus:ring-focus-glow`}),i?(0,W.jsx)(p,{className:`-translate-y-1/2 absolute top-1/2 right-3 size-4 text-ink-3`}):null]})}function Y({onFiles:e,accept:t,multiple:n=!0,className:r,children:i}){return(0,W.jsxs)(`label`,{onDragOver:e=>{e.preventDefault(),e.currentTarget.dataset.over=`1`},onDragLeave:e=>{delete e.currentTarget.dataset.over},onDrop:t=>{t.preventDefault(),delete t.currentTarget.dataset.over;let r=Array.from(t.dataTransfer.files);r.length&&e(n?r:r.slice(0,1))},className:m(`flex cursor-pointer items-center justify-center gap-2 rounded-lg border border-input border-dashed text-[0.875rem] text-ink-3 transition focus-within:border-focus focus-within:ring-4 focus-within:ring-focus-glow hover:border-ink-4 hover:text-ink data-[over]:border-focus data-[over]:bg-paper-2 data-[over]:text-ink`,r),children:[i,(0,W.jsx)(`input`,{className:`sr-only`,type:`file`,accept:t,multiple:n,onChange:t=>{let n=Array.from(t.target.files??[]);t.target.value=``,n.length&&e(n)}})]})}var X=`mt-1.5 text-[0.8125rem] text-ink-3`;function Z(e){let t=o(),[n,r]=(0,I.useState)(!1),i=S({mutationFn:e=>a.post(`/api/studio/account/link`,e),onSuccess:({url:e})=>{k(e),r(!0)}});return(0,I.useEffect)(()=>{if(!n)return;let e=setInterval(()=>void t.invalidateQueries({queryKey:[`me`]}),2e3),i=setTimeout(()=>r(!1),3e5);return()=>{clearInterval(e),clearTimeout(i)}},[n,t]),(0,I.useEffect)(()=>{e&&r(!1)},[e]),{link:i,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,W.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:b(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,W.jsx)(p,{className:`size-3.5`}),` `,b(`local.accountWaiting`)]}):null}function ne(){let e=Z(!1),{link:t}=e,[n,r]=(0,I.useState)(``);return(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex items-start gap-4 py-5 first:pt-0 last:pb-0`,children:[(0,W.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-full bg-paper-2 text-ink-2`,children:(0,W.jsx)(j,{className:`size-5`})}),(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:b(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:b(`account.localText`)})]})]}),E.account?(0,W.jsxs)(`div`,{className:`flex flex-col gap-4 py-5 last:pb-0`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:b(`account.with`)}),(0,W.jsxs)(`ul`,{className:`mt-2 flex flex-col gap-2 text-[0.875rem] text-ink-2 leading-snug`,children:[(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(u,{className:`mt-0.5 size-4 shrink-0 text-amber`}),b(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(C,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),b(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(y,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:b(`account.signIn`)})})]}):null,E.account?(0,W.jsxs)(`form`,{className:`flex flex-col gap-3 py-5 last:pb-0`,onSubmit:e=>{e.preventDefault(),t.mutate({signup:!0,code:n.trim()||void 0})},children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:b(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:b(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(v,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:b(`account.code`),"aria-label":b(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[0.875rem]`}),(0,W.jsx)(y,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:b(`account.create`)})]}),(0,W.jsx)(Q,{...e})]}):null]})}var $={start:`account.kind.start`,monthly:`account.kind.monthly`,gift:`account.kind.gift`};function re({account:e}){let t=o(),n=Z(e.signedIn),r=S({mutationFn:()=>a.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),i=new Intl.DateTimeFormat(x,{dateStyle:`medium`});return(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3 py-5 first:pt-0`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`truncate font-medium text-[0.9375rem]`,children:e.name||e.email}),e.signedIn?(0,W.jsx)(_,{tone:`live`,children:b(`account.linked`)}):null]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.email})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(e.url),children:[b(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}),(0,W.jsxs)(y,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(te,{className:`size-4`}),` `,b(`nav.logout`)]})]})]}),e.signedIn?null:(0,W.jsxs)(`div`,{className:`flex flex-col gap-3 py-5`,children:[(0,W.jsx)(`p`,{className:`text-[0.875rem] text-ink-2`,children:b(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(y,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:b(`account.signInAgain`)})}),(0,W.jsx)(Q,{...n})]}),e.credits===null?null:(0,W.jsxs)(`div`,{className:`py-5`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsx)(`div`,{className:`text-[0.8125rem] text-ink-3`,children:b(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[1.375rem] tabular-nums leading-tight`,children:b(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(`${e.url}/billing`),children:[b(`account.topUp`),` `,(0,W.jsx)(d,{className:`size-4`})]})]}),e.expiring.length?(0,W.jsx)(`ul`,{className:`mt-3 flex flex-col gap-1 text-[0.8125rem] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,W.jsxs)(`li`,{children:[b(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:i.format(new Date(e.expiresAt))}),$[e.kind]?(0,W.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,b($[e.kind])]}):null]},`${e.kind}:${e.expiresAt}`))}):null]}),(0,W.jsxs)(`div`,{className:`flex items-start gap-2.5 py-5 text-[0.875rem] text-ink-2 leading-snug last:pb-0`,children:[(0,W.jsx)(C,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:b(`account.cloud`,{host:T(e.cloudUrl)})})]})]})}function ie({me:e,fromAccount:t}){let n=o(),[r,i]=(0,I.useState)(e.profile),s=e=>i(t=>({...t,...e})),c=H(r,async e=>{await a.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,W.jsx)(K,{title:b(`account.profile`),hint:b(`account.hint`),save:c,children:(0,W.jsxs)(`div`,{className:`flex flex-col gap-6 sm:flex-row sm:gap-8`,children:[(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col items-center gap-2 sm:w-32`,children:[(0,W.jsx)(`div`,{className:`flex size-20 items-center justify-center overflow-hidden rounded-full bg-ember-tint font-semibold text-[1.75rem] text-ember-strong ring-1 ring-border-soft`,children:e.user.image?(0,W.jsx)(`img`,{src:e.user.image,alt:``,className:`size-full object-cover`}):O(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[0.75rem] text-ink-3 leading-snug`,children:b(`account.initials`)})]}),(0,W.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-5`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.name`)}),(0,W.jsx)(v,{value:r.name,maxLength:80,disabled:t,onChange:e=>s({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:b(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.about`)}),(0,W.jsx)(h,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>s({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:b(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.email`)}),(0,W.jsx)(v,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>s({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.phone`)}),(0,W.jsx)(v,{type:`tel`,value:r.phone,maxLength:40,onChange:e=>s({phone:e.target.value})})]})]})]})]})})}function ae({me:e}){let t=e.mode===`managed`,n=t||!!e.account;return(0,W.jsxs)(`div`,{className:`flex flex-col gap-9`,children:[(0,W.jsx)(K,{title:b(`account.connection`),hint:b(`account.connectionHint`),children:t?(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`truncate font-medium text-[0.9375rem]`,children:e.user.name}),(0,W.jsx)(_,{tone:`live`,children:b(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(`${e.manageUrl}/account`),children:[b(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}):null]}):e.account?(0,W.jsx)(re,{account:e.account}):(0,W.jsx)(ne,{})}),(0,W.jsx)(ie,{me:e,fromAccount:n},n?`account`:`own`),(0,W.jsx)(K,{title:b(`account.look`),hint:b(`account.lookHint`),children:(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pb-4`,children:[(0,W.jsx)(`span`,{className:`font-medium text-[0.875rem]`,children:b(`nav.language`)}),(0,W.jsx)(w,{tone:`surface`})]}),(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pt-4`,children:[(0,W.jsx)(`span`,{className:`font-medium text-[0.875rem]`,children:b(`nav.theme`)}),(0,W.jsx)(D,{})]})]})})]})}export{Y as a,K as c,H as d,B as f,N as h,G as i,U as l,R as m,Q as n,q as o,V as p,Z as r,J as s,ae as t,z as u};
|
|
1
|
+
import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{c as r,j as i,n as a,nt as o}from"./api-C4M6cbpW.js";import{t as s}from"./createLucideIcon-q3MZMmnf.js";import{t as c}from"./check-CUpby_J9.js";import{n as l,r as u}from"./upload-DNRENWzQ.js";import{t as d}from"./external-link-MAL7vJYj.js";import{c as f,f as p,g as m,h,n as g,o as ee,r as _,s as v,t as y,x as b,y as x}from"./ui-BS348L4M.js";import{F as te,K as S,V as C,f as w,o as T,p as E,u as D,x as O}from"./index-DMKXnSf-.js";import{n as k}from"./LocalRuntime-Boi_zqQJ.js";var A={name:`hard-drive`,size:24,node:[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]};A.node;var j=s(A),M={name:`layout-grid`,size:24,node:[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]};M.node;var N=s(M),P={name:`list`,size:24,node:[[`path`,{d:`M3 5h.01`,key:`18ugdj`}],[`path`,{d:`M3 12h.01`,key:`nlz23k`}],[`path`,{d:`M3 19h.01`,key:`noohij`}],[`path`,{d:`M8 5h13`,key:`1pao27`}],[`path`,{d:`M8 12h13`,key:`1za7za`}],[`path`,{d:`M8 19h13`,key:`m83p4d`}]]};P.node;var F=s(P),I=e(t(),1),L=e=>[`project-files`,e];function R(e){return i({queryKey:L(e),queryFn:()=>a.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function z(e,t){return r(`/api/studio/projects/${e}/files/${t}/content`)}function B(e,t=!1){let n=o(),[r,i]=(0,I.useState)(!1),[s,c]=(0,I.useState)(null),l=()=>n.invalidateQueries({queryKey:L(e)}),u=async e=>{c(null);try{await e()}catch(e){c(e.message)}finally{await l()}};return{busy:r,error:s,readOnly:t,upload:async(t,n)=>{i(!0),await u(async()=>{for(let r of n)await a.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await l()}),i(!1)},describe:(t,n)=>u(()=>a.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>u(()=>a.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>u(()=>a.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>u(()=>a.put(`/api/studio/projects/${e}/files/order`,{kind:t,ids:n}))}}function V(e,t){let n=`wz.layout.${e}`,[r,i]=(0,I.useState)(()=>{try{let e=localStorage.getItem(n);return e===`list`||e===`cards`?e:t}catch{return t}});return[r,()=>i(e=>{let t=e===`list`?`cards`:`list`;try{localStorage.setItem(n,t)}catch{}return t})]}function H(e,t,n=700){let[r,i]=(0,I.useState)(`idle`),[a,o]=(0,I.useState)(null),s=JSON.stringify(e),c=(0,I.useRef)(s),l=(0,I.useRef)({value:e,json:s,save:t});l.current={value:e,json:s,save:t};let u=(0,I.useRef)(Promise.resolve()),d=(0,I.useCallback)(()=>{let e=l.current;e.json!==c.current&&(c.current=e.json,i(`saving`),u.current=u.current.then(async()=>{try{await e.save(e.value),o(null),i(`saved`)}catch(e){c.current=``,o(e.message),i(`error`)}}))},[]);return(0,I.useEffect)(()=>{if(s===c.current)return;let e=setTimeout(d,n);return()=>clearTimeout(e)},[s,n,d]),(0,I.useEffect)(()=>d,[d]),{state:r,error:a}}function U(e){return e<1e6?`${Math.max(1,Math.round(e/1e3))} KB`:`${(e/1e6).toFixed(1)} MB`}var W=e(n(),1);function G({id:e,children:t}){return(0,W.jsx)(`div`,{id:e,className:`scroll-mt-24 max-md:scroll-mt-36`,children:t})}function K({title:e,hint:t,save:n,action:r,locked:i,plain:a,children:o}){return(0,W.jsxs)(`section`,{className:`flex flex-col gap-2.5`,children:[(0,W.jsxs)(`div`,{className:`flex items-start justify-between gap-4 px-1`,children:[(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,W.jsx)(`h2`,{className:`font-display font-semibold text-lg leading-tight`,children:e}),n?.state===`saving`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[0.75rem] text-ink-3`,children:[(0,W.jsx)(p,{className:`size-3`}),` `,b(`project.saving`)]}):n?.state===`saved`?(0,W.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-[0.75rem] text-moss`,children:[(0,W.jsx)(c,{className:`size-3.5`}),` `,b(`settings.saved`)]}):null]}),t?(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-snug`,children:t}):null]}),r?(0,W.jsx)(`div`,{className:`shrink-0`,children:r}):null]}),a?o:(0,W.jsxs)(g,{className:`p-3.5 sm:p-5`,children:[i?(0,W.jsx)(`fieldset`,{disabled:!0,className:`min-w-0`,children:o}):o,n?.state===`error`&&n.error?(0,W.jsx)(`p`,{className:`mt-4 text-[0.875rem] text-rose`,children:n.error}):null]})]})}function q({children:e,layout:t,onToggle:n}){return(0,W.jsxs)(`div`,{className:`mb-3 flex items-start gap-2`,children:[(0,W.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,W.jsx)(`div`,{className:`w-56 max-w-full transition-[width] duration-200 focus-within:w-full has-[input:not(:placeholder-shown)]:w-full`,children:e})}),(0,W.jsx)(ee,{label:b(t===`list`?`project.viewCards`:`project.viewList`),onClick:n,children:t===`list`?(0,W.jsx)(N,{className:`size-4`}):(0,W.jsx)(F,{className:`size-4`})})]})}function J({value:e,onChange:t,onEnter:n,placeholder:r,busy:i}){return(0,W.jsxs)(`div`,{className:`relative`,children:[(0,W.jsx)(l,{className:`-translate-y-1/2 pointer-events-none absolute top-1/2 left-3 size-4 text-ink-4`}),(0,W.jsx)(`input`,{type:`search`,value:e,placeholder:r,onChange:e=>t(e.target.value),onKeyDown:e=>e.key===`Enter`&&n?.(),className:`h-9 w-full rounded-lg border border-input bg-card pr-3 pl-9 text-[0.875rem] text-ink outline-none transition placeholder:text-ink-4 focus:border-focus focus:ring-4 focus:ring-focus-glow`}),i?(0,W.jsx)(p,{className:`-translate-y-1/2 absolute top-1/2 right-3 size-4 text-ink-3`}):null]})}function Y({onFiles:e,accept:t,multiple:n=!0,className:r,children:i}){return(0,W.jsxs)(`label`,{onDragOver:e=>{e.preventDefault(),e.currentTarget.dataset.over=`1`},onDragLeave:e=>{delete e.currentTarget.dataset.over},onDrop:t=>{t.preventDefault(),delete t.currentTarget.dataset.over;let r=Array.from(t.dataTransfer.files);r.length&&e(n?r:r.slice(0,1))},className:m(`flex cursor-pointer items-center justify-center gap-2 rounded-lg border border-input border-dashed text-[0.875rem] text-ink-3 transition focus-within:border-focus focus-within:ring-4 focus-within:ring-focus-glow hover:border-ink-4 hover:text-ink data-[over]:border-focus data-[over]:bg-paper-2 data-[over]:text-ink`,r),children:[i,(0,W.jsx)(`input`,{className:`sr-only`,type:`file`,accept:t,multiple:n,onChange:t=>{let n=Array.from(t.target.files??[]);t.target.value=``,n.length&&e(n)}})]})}var X=`mt-1.5 text-[0.8125rem] text-ink-3`;function Z(e){let t=o(),[n,r]=(0,I.useState)(!1),i=S({mutationFn:e=>a.post(`/api/studio/account/link`,e),onSuccess:({url:e})=>{k(e),r(!0)}});return(0,I.useEffect)(()=>{if(!n)return;let e=setInterval(()=>void t.invalidateQueries({queryKey:[`me`]}),2e3),i=setTimeout(()=>r(!1),3e5);return()=>{clearInterval(e),clearTimeout(i)}},[n,t]),(0,I.useEffect)(()=>{e&&r(!1)},[e]),{link:i,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,W.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:b(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,W.jsx)(p,{className:`size-3.5`}),` `,b(`local.accountWaiting`)]}):null}function ne(){let e=Z(!1),{link:t}=e,[n,r]=(0,I.useState)(``);return(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex items-start gap-4 py-5 first:pt-0 last:pb-0`,children:[(0,W.jsx)(`div`,{className:`flex size-11 shrink-0 items-center justify-center rounded-full bg-paper-2 text-ink-2`,children:(0,W.jsx)(j,{className:`size-5`})}),(0,W.jsxs)(`div`,{className:`min-w-0`,children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:b(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:b(`account.localText`)})]})]}),E.account?(0,W.jsxs)(`div`,{className:`flex flex-col gap-4 py-5 last:pb-0`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:b(`account.with`)}),(0,W.jsxs)(`ul`,{className:`mt-2 flex flex-col gap-2 text-[0.875rem] text-ink-2 leading-snug`,children:[(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(u,{className:`mt-0.5 size-4 shrink-0 text-amber`}),b(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(C,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),b(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(y,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:b(`account.signIn`)})})]}):null,E.account?(0,W.jsxs)(`form`,{className:`flex flex-col gap-3 py-5 last:pb-0`,onSubmit:e=>{e.preventDefault(),t.mutate({signup:!0,code:n.trim()||void 0})},children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`font-medium text-[0.9375rem]`,children:b(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:b(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(v,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:b(`account.code`),"aria-label":b(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[0.875rem]`}),(0,W.jsx)(y,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:b(`account.create`)})]}),(0,W.jsx)(Q,{...e})]}):null]})}var $={start:`account.kind.start`,monthly:`account.kind.monthly`,gift:`account.kind.gift`};function re({account:e}){let t=o(),n=Z(e.signedIn),r=S({mutationFn:()=>a.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),i=new Intl.DateTimeFormat(x,{dateStyle:`medium`});return(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3 py-5 first:pt-0`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`truncate font-medium text-[0.9375rem]`,children:e.name||e.email}),e.signedIn?(0,W.jsx)(_,{tone:`live`,children:b(`account.linked`)}):null]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.email})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(e.url),children:[b(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}),(0,W.jsxs)(y,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(te,{className:`size-4`}),` `,b(`nav.logout`)]})]})]}),e.signedIn?null:(0,W.jsxs)(`div`,{className:`flex flex-col gap-3 py-5`,children:[(0,W.jsx)(`p`,{className:`text-[0.875rem] text-ink-2`,children:b(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(y,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:b(`account.signInAgain`)})}),(0,W.jsx)(Q,{...n})]}),e.credits===null?null:(0,W.jsxs)(`div`,{className:`py-5`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-3`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsx)(`div`,{className:`text-[0.8125rem] text-ink-3`,children:b(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[1.375rem] tabular-nums leading-tight`,children:b(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(`${e.url}/billing`),children:[b(`account.topUp`),` `,(0,W.jsx)(d,{className:`size-4`})]})]}),e.expiring.length?(0,W.jsx)(`ul`,{className:`mt-3 flex flex-col gap-1 text-[0.8125rem] text-ink-3 tabular-nums`,children:e.expiring.map(e=>(0,W.jsxs)(`li`,{children:[b(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:i.format(new Date(e.expiresAt))}),$[e.kind]?(0,W.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,b($[e.kind])]}):null]},`${e.kind}:${e.expiresAt}`))}):null]}),(0,W.jsxs)(`div`,{className:`flex items-start gap-2.5 py-5 text-[0.875rem] text-ink-2 leading-snug last:pb-0`,children:[(0,W.jsx)(C,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:b(`account.cloud`,{host:T(e.cloudUrl)})})]})]})}function ie({me:e,fromAccount:t}){let n=o(),[r,i]=(0,I.useState)(e.profile),s=e=>i(t=>({...t,...e})),c=H(r,async e=>{await a.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,W.jsx)(K,{title:b(`account.profile`),hint:b(`account.hint`),save:c,children:(0,W.jsxs)(`div`,{className:`flex flex-col gap-6 sm:flex-row sm:gap-8`,children:[(0,W.jsxs)(`div`,{className:`flex shrink-0 flex-col items-center gap-2 sm:w-32`,children:[(0,W.jsx)(`div`,{className:`flex size-20 items-center justify-center overflow-hidden rounded-full bg-ember-tint font-semibold text-[1.75rem] text-ember-strong ring-1 ring-border-soft`,children:e.user.image?(0,W.jsx)(`img`,{src:e.user.image,alt:``,className:`size-full object-cover`}):O(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[0.75rem] text-ink-3 leading-snug`,children:b(`account.initials`)})]}),(0,W.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col gap-5`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.name`)}),(0,W.jsx)(v,{value:r.name,maxLength:80,disabled:t,onChange:e=>s({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:b(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.about`)}),(0,W.jsx)(h,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>s({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:b(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.email`)}),(0,W.jsx)(v,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>s({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(f,{children:b(`account.phone`)}),(0,W.jsx)(v,{type:`tel`,value:r.phone,maxLength:40,onChange:e=>s({phone:e.target.value})})]})]})]})]})})}function ae({me:e}){let t=e.mode===`managed`,n=t||!!e.account;return(0,W.jsxs)(`div`,{className:`flex flex-col gap-9`,children:[(0,W.jsx)(K,{title:b(`account.connection`),hint:b(`account.connectionHint`),children:t?(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,W.jsx)(`span`,{className:`truncate font-medium text-[0.9375rem]`,children:e.user.name}),(0,W.jsx)(_,{tone:`live`,children:b(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(y,{variant:`secondary`,onClick:()=>k(`${e.manageUrl}/account`),children:[b(`setup.openAccount`),` `,(0,W.jsx)(d,{className:`size-4`})]}):null]}):e.account?(0,W.jsx)(re,{account:e.account}):(0,W.jsx)(ne,{})}),(0,W.jsx)(ie,{me:e,fromAccount:n},n?`account`:`own`),(0,W.jsx)(K,{title:b(`account.look`),hint:b(`account.lookHint`),children:(0,W.jsxs)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pb-4`,children:[(0,W.jsx)(`span`,{className:`font-medium text-[0.875rem]`,children:b(`nav.language`)}),(0,W.jsx)(w,{tone:`surface`})]}),(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-4 pt-4`,children:[(0,W.jsx)(`span`,{className:`font-medium text-[0.875rem]`,children:b(`nav.theme`)}),(0,W.jsx)(D,{})]})]})})]})}export{Y as a,K as c,H as d,B as f,N as h,G as i,U as l,R as m,Q as n,q as o,V as p,Z as r,J as s,ae as t,z as u};
|