wizards 0.2.31 → 0.2.33
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/cli/main.js +26 -5
- package/apps/runtime/dist/cli/mcp.js +6 -33
- package/apps/runtime/dist/cli/menu.js +144 -0
- package/apps/runtime/dist/cli/start.js +56 -12
- package/apps/runtime/dist/cli/status.js +56 -10
- package/apps/runtime/dist/cli/update.js +1 -1
- package/apps/runtime/dist/index.js +6 -1
- package/apps/web/dist/assets/{Account-v7Iqkep5.js → Account-DoBENv2J.js} +1 -1
- package/apps/web/dist/assets/{ChangelogDialog-CnYW-DMa.js → ChangelogDialog-D_a-50dd.js} +1 -1
- package/apps/web/dist/assets/{CreditsDialog-BtID6slV.js → CreditsDialog-DZaYayDL.js} +1 -1
- package/apps/web/dist/assets/{EditorPage-UqOALINq.js → EditorPage-B5CnSoeU.js} +1 -1
- package/apps/web/dist/assets/{FlowPreview-CxBGhnMi.js → FlowPreview-CrfwITiJ.js} +1 -1
- package/apps/web/dist/assets/{Harness-BBUVWLMx.js → Harness-DxuzPSzJ.js} +1 -1
- package/apps/web/dist/assets/{HomePage-E2kbDAWI.js → HomePage-DugTpas_.js} +1 -1
- package/apps/web/dist/assets/{ImportWizard-DBxxe467.js → ImportWizard-hVYpY1mj.js} +1 -1
- package/apps/web/dist/assets/{LocalRuntime-DMU_dzV1.js → LocalRuntime-D0L3FtDm.js} +1 -1
- package/apps/web/dist/assets/{NewWizardPage-B9rqko-D.js → NewWizardPage-DFTdNRsX.js} +2 -2
- package/apps/web/dist/assets/{ProjectPage-cqeSCfvy.js → ProjectPage-WIHBuHQV.js} +1 -1
- package/apps/web/dist/assets/{PublicRunner-CrRc-QgY.js → PublicRunner-DTmJ9EH4.js} +1 -1
- package/apps/web/dist/assets/{RunDrawer-DRKc8Bm5.js → RunDrawer-ttQUshZU.js} +1 -1
- package/apps/web/dist/assets/{RunnerView-BH2sXBlx.js → RunnerView-BhiFqDrn.js} +1 -1
- package/apps/web/dist/assets/{SettingsPage-DeehkMtv.js → SettingsPage-xjsNjJ78.js} +1 -1
- package/apps/web/dist/assets/{SetupPage-D13qI_dd.js → SetupPage-DhkkLaOp.js} +1 -1
- package/apps/web/dist/assets/{SharePage-8ji9ACWJ.js → SharePage-CM6L7Z26.js} +1 -1
- package/apps/web/dist/assets/arrow-right-CXu8-CPy.js +1 -0
- package/apps/web/dist/assets/{changelog-D536XAHL.js → changelog-DCBBW4Ql.js} +1 -1
- package/apps/web/dist/assets/{circle-alert-CN6dFS0d.js → circle-alert-Czg98m49.js} +1 -1
- package/apps/web/dist/assets/{definition-Cx9uG0KU.js → definition-DMIWA8dM.js} +1 -1
- package/apps/web/dist/assets/{esm-CSQNLh1s.js → esm-NnqfyT_X.js} +1 -1
- package/apps/web/dist/assets/{external-link-DvkH63pi.js → external-link-CbxUCKS8.js} +1 -1
- package/apps/web/dist/assets/{image-BUbtvL1h.js → image-BuCJ3Peh.js} +1 -1
- package/apps/web/dist/assets/{index-CYZmm7HU.js → index-KVvpYi_r.js} +4 -4
- package/apps/web/dist/assets/{lock-COAprdab.js → lock-B_LTwWO5.js} +1 -1
- package/apps/web/dist/assets/{meta-Daw62MfH.js → meta-DiSekcZt.js} +1 -1
- package/apps/web/dist/assets/{pen-line-JsP-r_aH.js → pen-line-D0OKCmpB.js} +1 -1
- package/apps/web/dist/assets/{refresh-cw-DLXaS3Ri.js → refresh-cw-LyAykaPl.js} +1 -1
- package/apps/web/dist/assets/{settings-menu-br026gwt.js → settings-menu-NtPzTC97.js} +1 -1
- package/apps/web/dist/assets/{star-CpnGQZXD.js → star-C9ADb1bK.js} +1 -1
- package/apps/web/dist/assets/{surface-BFwNWkx9.js → surface-CywgBXMy.js} +1 -1
- package/apps/web/dist/assets/{trash-CQZuqdcu.js → trash-CGJ09WWJ.js} +1 -1
- package/apps/web/dist/assets/{ui-BTkH_7CG.js → ui-DyazyiaK.js} +1 -1
- package/apps/web/dist/assets/{upload-Dok4YeXQ.js → upload-Dl_w8YOa.js} +1 -1
- package/apps/web/dist/assets/{video-BjQoPIsn.js → video-DDj7eGwZ.js} +1 -1
- package/apps/web/dist/assets/{volume-2-D-Bn77h4.js → volume-2-dg1-eKM_.js} +1 -1
- package/apps/web/dist/assets/{wand-sparkles-D3sDsFFG.js → wand-sparkles-Bmg2IFLf.js} +1 -1
- package/apps/web/dist/index.html +3 -3
- package/apps/web/dist/mcp/flow.html +32 -31
- package/package.json +1 -1
- package/apps/web/dist/assets/arrow-right-CzoY677S.js +0 -1
|
@@ -2,18 +2,21 @@ import { apps, connectCommand } from "./connect.js";
|
|
|
2
2
|
import { layout, packageVersion, readInstallNote } from "./home.js";
|
|
3
3
|
import { CLIENTS, nodeIsCurrent } from "./machine.js";
|
|
4
4
|
import { mcp } from "./mcp.js";
|
|
5
|
+
import { menu } from "./menu.js";
|
|
5
6
|
import { command, setup } from "./setup.js";
|
|
6
7
|
import { open, start } from "./start.js";
|
|
7
|
-
import { autostart, status, stop } from "./status.js";
|
|
8
|
+
import { autostart, restart, status, stop } from "./status.js";
|
|
8
9
|
import { update } from "./update.js";
|
|
9
10
|
const HELP = `engenty wizards ${packageVersion()}
|
|
10
11
|
|
|
11
|
-
${command()}
|
|
12
|
+
${command()} what runs, and a menu: start, stop, update …; the first time, the setup runs first
|
|
13
|
+
${command()} start start it and open the studio
|
|
12
14
|
${command()} setup guided setup: an AI client to think with, ffmpeg, start at login
|
|
13
15
|
${command()} open let this browser into the running studio (--print: only show the link)
|
|
14
16
|
${command()} status what is installed and what runs
|
|
15
17
|
${command()} doctor status, and what is wrong
|
|
16
18
|
${command()} stop stop it; the data is kept
|
|
19
|
+
${command()} restart stop it and start it again (after an update: the new version)
|
|
17
20
|
${command()} update the newest version
|
|
18
21
|
${command()} autostart start it at login: on, off (macOS: a LaunchAgent; Linux: a systemd service)
|
|
19
22
|
${command()} connect your wizards in your AI apps: every app found, or name them —
|
|
@@ -26,6 +29,7 @@ const HELP = `engenty wizards ${packageVersion()}
|
|
|
26
29
|
--yes, -y ask nothing and install nothing optional
|
|
27
30
|
--client <name> install this AI client without asking: ${CLIENTS.map((c) => c.id).join(", ")}
|
|
28
31
|
--no-open start without opening the browser
|
|
32
|
+
--service, -s start as a service, detached from this terminal; \`wizards stop\` stops it
|
|
29
33
|
--version, --help
|
|
30
34
|
|
|
31
35
|
Everything lives in ~/.engenty/wizards (ENGENTY_HOME moves it); settings go into its .env.
|
|
@@ -37,6 +41,7 @@ function parse(argv) {
|
|
|
37
41
|
apps: [],
|
|
38
42
|
yes: false,
|
|
39
43
|
open: true,
|
|
44
|
+
service: false,
|
|
40
45
|
print: false,
|
|
41
46
|
clients: [],
|
|
42
47
|
};
|
|
@@ -48,6 +53,9 @@ function parse(argv) {
|
|
|
48
53
|
else if (arg === "--no-open") {
|
|
49
54
|
args.open = false;
|
|
50
55
|
}
|
|
56
|
+
else if (arg === "--service" || arg === "-s") {
|
|
57
|
+
args.service = true;
|
|
58
|
+
}
|
|
51
59
|
else if (arg === "--print") {
|
|
52
60
|
args.print = true;
|
|
53
61
|
}
|
|
@@ -80,7 +88,6 @@ function parse(argv) {
|
|
|
80
88
|
args.command = arg;
|
|
81
89
|
}
|
|
82
90
|
}
|
|
83
|
-
args.command ||= "start";
|
|
84
91
|
return args;
|
|
85
92
|
}
|
|
86
93
|
async function main(argv) {
|
|
@@ -91,6 +98,14 @@ async function main(argv) {
|
|
|
91
98
|
}
|
|
92
99
|
const paths = layout();
|
|
93
100
|
const setupOptions = { yes: args.yes, clients: args.clients };
|
|
101
|
+
if (!args.command) {
|
|
102
|
+
// On a terminal, without options: the menu. Anywhere else it starts, as it always did.
|
|
103
|
+
const plain = argv.length === 0 && process.stdin.isTTY && process.stdout.isTTY;
|
|
104
|
+
if (plain) {
|
|
105
|
+
return menu(paths, setupOptions, HELP);
|
|
106
|
+
}
|
|
107
|
+
args.command = "start";
|
|
108
|
+
}
|
|
94
109
|
switch (args.command) {
|
|
95
110
|
case "help":
|
|
96
111
|
console.log(HELP);
|
|
@@ -107,11 +122,15 @@ async function main(argv) {
|
|
|
107
122
|
return next === null ? 130 : 0;
|
|
108
123
|
}
|
|
109
124
|
}
|
|
110
|
-
return start(paths, { open: args.open });
|
|
125
|
+
return start(paths, { open: args.open, background: args.service });
|
|
111
126
|
}
|
|
112
127
|
case "setup": {
|
|
113
128
|
const next = await setup(paths, setupOptions);
|
|
114
|
-
return next === "start"
|
|
129
|
+
return next === "start"
|
|
130
|
+
? start(paths, { open: args.open, background: args.service })
|
|
131
|
+
: next === null
|
|
132
|
+
? 130
|
|
133
|
+
: 0;
|
|
115
134
|
}
|
|
116
135
|
case "open":
|
|
117
136
|
return open(paths, args.print);
|
|
@@ -121,6 +140,8 @@ async function main(argv) {
|
|
|
121
140
|
return status(paths, true);
|
|
122
141
|
case "stop":
|
|
123
142
|
return stop(paths);
|
|
143
|
+
case "restart":
|
|
144
|
+
return restart(paths);
|
|
124
145
|
case "update":
|
|
125
146
|
return update(paths);
|
|
126
147
|
case "autostart":
|
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { mkdirSync, openSync, readFileSync } from "node:fs";
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
3
2
|
import { join } from "node:path";
|
|
4
3
|
import { createInterface } from "node:readline";
|
|
5
4
|
import { LOCAL_CLIENT_HEADER, LOCAL_MCP_HEADER, mintLocalTicket } from "../auth/local-ticket.js";
|
|
6
|
-
import { runningRuntime, settings } from "./start.js";
|
|
7
|
-
/**
|
|
8
|
-
* `wizards mcp`: this install's MCP server over stdio, for AI clients that start their
|
|
9
|
-
* servers as a command — Claude Desktop, Cursor, Codex and the ChatGPT app, VS Code, Windsurf,
|
|
10
|
-
* Gemini CLI, Goose, OpenClaw, LM Studio. Each message goes on to the running runtime's
|
|
11
|
-
* `/api/mcp`, signed with the data folder's secret, so no client's config holds a key and a new
|
|
12
|
-
* port after a restart changes nothing. When nothing runs, the runtime is started.
|
|
13
|
-
*
|
|
14
|
-
* stdout carries only MCP messages; everything else goes to stderr.
|
|
15
|
-
*/
|
|
16
|
-
const START_TIMEOUT_MS = 60_000;
|
|
5
|
+
import { runningRuntime, settings, startInBackground } from "./start.js";
|
|
17
6
|
/** The JSON-RPC messages of a response: a JSON body (one or a batch) or a server-sent stream. */
|
|
18
7
|
export function messagesOf(contentType, body) {
|
|
19
8
|
if (!body.trim()) {
|
|
@@ -48,17 +37,6 @@ function readSecret(paths, dataDir) {
|
|
|
48
37
|
return null;
|
|
49
38
|
}
|
|
50
39
|
}
|
|
51
|
-
/** Starts the runtime in the background, the way `wizards start --no-open` would. */
|
|
52
|
-
function startInBackground(paths) {
|
|
53
|
-
mkdirSync(paths.logs, { recursive: true });
|
|
54
|
-
const log = openSync(join(paths.logs, "runtime.log"), "a");
|
|
55
|
-
const child = spawn(process.execPath, [process.argv[1], "start", "--no-open"], {
|
|
56
|
-
detached: true,
|
|
57
|
-
stdio: ["ignore", log, log],
|
|
58
|
-
env: process.env,
|
|
59
|
-
});
|
|
60
|
-
child.unref();
|
|
61
|
-
}
|
|
62
40
|
export async function mcp(paths) {
|
|
63
41
|
const { dataDir } = settings(paths);
|
|
64
42
|
let running = null;
|
|
@@ -71,16 +49,11 @@ export async function mcp(paths) {
|
|
|
71
49
|
return found;
|
|
72
50
|
}
|
|
73
51
|
process.stderr.write("engenty wizards is not running; starting it …\n");
|
|
74
|
-
startInBackground(paths);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
await new Promise((wait) => setTimeout(wait, 300));
|
|
78
|
-
const started = await runningRuntime(dataDir);
|
|
79
|
-
if (started) {
|
|
80
|
-
return started;
|
|
81
|
-
}
|
|
52
|
+
const started = await startInBackground(paths);
|
|
53
|
+
if (started) {
|
|
54
|
+
return started;
|
|
82
55
|
}
|
|
83
|
-
throw new Error(`engenty wizards did not start
|
|
56
|
+
throw new Error(`engenty wizards did not start; see ${join(paths.logs, "runtime.log")}.`);
|
|
84
57
|
})();
|
|
85
58
|
running.catch(() => {
|
|
86
59
|
running = null;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { updateStatus } from "../update.js";
|
|
3
|
+
import { autostartState, setAutostart } from "./autostart.js";
|
|
4
|
+
import { connectCommand } from "./connect.js";
|
|
5
|
+
import { packageVersion, readInstallNote } from "./home.js";
|
|
6
|
+
import { command, setup } from "./setup.js";
|
|
7
|
+
import { open, runningRuntime, settings, start } from "./start.js";
|
|
8
|
+
import { restart, status, stop } from "./status.js";
|
|
9
|
+
import { badge, cyan, dim, no, ok } from "./ui.js";
|
|
10
|
+
import { update } from "./update.js";
|
|
11
|
+
async function look(paths) {
|
|
12
|
+
const { dataDir } = settings(paths);
|
|
13
|
+
const [running, atLogin, release] = await Promise.all([
|
|
14
|
+
runningRuntime(dataDir),
|
|
15
|
+
autostartState(paths),
|
|
16
|
+
updateStatus().catch(() => null),
|
|
17
|
+
]);
|
|
18
|
+
return { running, atLogin, release };
|
|
19
|
+
}
|
|
20
|
+
function report({ running, atLogin, release }) {
|
|
21
|
+
const lines = [
|
|
22
|
+
running
|
|
23
|
+
? `${ok} running ${cyan(running.url)} ${dim(`pid ${running.pid}, since ${new Date(running.startedAt).toLocaleString()}`)}`
|
|
24
|
+
: `${no} not running`,
|
|
25
|
+
];
|
|
26
|
+
if (!("unavailable" in atLogin)) {
|
|
27
|
+
lines.push(atLogin.on ? `${ok} starts at login` : `${no} does not start at login`);
|
|
28
|
+
}
|
|
29
|
+
if (release?.newer) {
|
|
30
|
+
lines.push(`${cyan("↑")} ${release.latest} is out ${dim(`(you have ${release.current})`)}`);
|
|
31
|
+
}
|
|
32
|
+
return lines.join("\n");
|
|
33
|
+
}
|
|
34
|
+
function choices({ running, atLogin, release }) {
|
|
35
|
+
const options = running
|
|
36
|
+
? [
|
|
37
|
+
{ value: "open", label: "Open the studio", hint: "in your browser" },
|
|
38
|
+
{ value: "restart", label: "Restart" },
|
|
39
|
+
{ value: "stop", label: "Stop", hint: "the data is kept" },
|
|
40
|
+
]
|
|
41
|
+
: [
|
|
42
|
+
{ value: "start", label: "Start", hint: "in the background, opens the studio" },
|
|
43
|
+
{ value: "foreground", label: "Start here", hint: "in this terminal; Ctrl-C stops it" },
|
|
44
|
+
];
|
|
45
|
+
options.push({
|
|
46
|
+
value: "update",
|
|
47
|
+
label: "Update",
|
|
48
|
+
hint: release?.newer
|
|
49
|
+
? `${release.latest} is out`
|
|
50
|
+
: release?.latest
|
|
51
|
+
? "you have the newest"
|
|
52
|
+
: undefined,
|
|
53
|
+
});
|
|
54
|
+
if (!("unavailable" in atLogin)) {
|
|
55
|
+
options.push({
|
|
56
|
+
value: "autostart",
|
|
57
|
+
label: atLogin.on ? "Don't start at login" : "Start at login",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
options.push({ value: "connect", label: "Connect AI apps", hint: "your wizards in Claude, Cursor, Codex …" }, { value: "status", label: "Status", hint: "what is installed, and what is wrong" }, { value: "setup", label: "Setup", hint: "AI client, ffmpeg, start at login" }, { value: "help", label: "Help", hint: "every command" }, { value: "quit", label: "Quit", hint: running ? "it keeps running" : undefined });
|
|
61
|
+
return options;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* `wizards` on a terminal: what runs, and a menu of what the commands do. The first time, the
|
|
65
|
+
* setup runs first. Returns the exit code; "Start here" ends it with the runtime in the
|
|
66
|
+
* foreground.
|
|
67
|
+
*/
|
|
68
|
+
export async function menu(paths, setupOptions, help) {
|
|
69
|
+
if (!readInstallNote(paths).setupAt) {
|
|
70
|
+
const next = await setup(paths, setupOptions);
|
|
71
|
+
if (next === null) {
|
|
72
|
+
return 130;
|
|
73
|
+
}
|
|
74
|
+
if (next === "start") {
|
|
75
|
+
await start(paths, { open: true, background: true });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
p.intro(`${badge("engenty wizards")} ${dim(packageVersion())}`);
|
|
79
|
+
for (;;) {
|
|
80
|
+
const spinner = p.spinner();
|
|
81
|
+
spinner.start("Looking at what runs");
|
|
82
|
+
const state = await look(paths);
|
|
83
|
+
spinner.stop(report(state));
|
|
84
|
+
const action = await p.select({ message: "What now?", options: choices(state) });
|
|
85
|
+
if (p.isCancel(action) || action === "quit") {
|
|
86
|
+
p.outro(dim(`${command()} opens this again; ${command()} help lists every command.`));
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
switch (action) {
|
|
90
|
+
case "start":
|
|
91
|
+
await start(paths, { open: true, background: true });
|
|
92
|
+
break;
|
|
93
|
+
case "foreground":
|
|
94
|
+
p.outro("Starting engenty wizards here");
|
|
95
|
+
return start(paths, { open: true });
|
|
96
|
+
case "open":
|
|
97
|
+
await open(paths, false);
|
|
98
|
+
break;
|
|
99
|
+
case "restart":
|
|
100
|
+
await restart(paths);
|
|
101
|
+
break;
|
|
102
|
+
case "stop":
|
|
103
|
+
await stop(paths);
|
|
104
|
+
break;
|
|
105
|
+
case "update": {
|
|
106
|
+
if ((await update(paths)) !== 0) {
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
// This menu is still the old version: what runs restarts into the new one, then it ends.
|
|
110
|
+
if (state.running) {
|
|
111
|
+
await restart(paths);
|
|
112
|
+
}
|
|
113
|
+
p.outro(`Updated. ${cyan(command())} opens the new version.`);
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
case "autostart":
|
|
117
|
+
if (!("unavailable" in state.atLogin)) {
|
|
118
|
+
try {
|
|
119
|
+
await setAutostart(paths, !state.atLogin.on);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
p.log.warn(`Starting at login could not be switched: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
break;
|
|
126
|
+
case "connect":
|
|
127
|
+
await connectCommand(paths, [], false);
|
|
128
|
+
break;
|
|
129
|
+
case "status":
|
|
130
|
+
await status(paths, true);
|
|
131
|
+
break;
|
|
132
|
+
case "setup": {
|
|
133
|
+
const next = await setup(paths, setupOptions);
|
|
134
|
+
if (next === "start" && !state.running) {
|
|
135
|
+
await start(paths, { open: true, background: true });
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case "help":
|
|
140
|
+
console.log(help);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
3
|
+
import { existsSync, mkdirSync, openSync, readFileSync } from "node:fs";
|
|
4
4
|
import { createServer } from "node:net";
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
6
6
|
import { styleText } from "node:util";
|
|
@@ -96,9 +96,48 @@ function show(url, entry, open) {
|
|
|
96
96
|
console.log(styleText("dim", " The link lets one browser in and works once."));
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
+
/** The command of this install, as it is on disk now: `wizards <args>`. */
|
|
100
|
+
function spawnCommand(paths, args, options) {
|
|
101
|
+
const wrapper = join(paths.bin, "wizards");
|
|
102
|
+
return existsSync(wrapper)
|
|
103
|
+
? spawn(wrapper, args, options)
|
|
104
|
+
: spawn(process.execPath, [join(packageRoot, "bin/wizards.mjs"), ...args], options);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* `wizards start --no-open` detached from this terminal, its output in logs/runtime.log; the
|
|
108
|
+
* runtime once it answers, or null when it ended or did not answer within a minute.
|
|
109
|
+
*/
|
|
110
|
+
export async function startInBackground(paths) {
|
|
111
|
+
const { dataDir } = settings(paths);
|
|
112
|
+
mkdirSync(paths.logs, { recursive: true });
|
|
113
|
+
const log = openSync(join(paths.logs, "runtime.log"), "a");
|
|
114
|
+
const child = spawnCommand(paths, ["start", "--no-open"], {
|
|
115
|
+
cwd: paths.home,
|
|
116
|
+
detached: true,
|
|
117
|
+
stdio: ["ignore", log, log],
|
|
118
|
+
});
|
|
119
|
+
let exited = false;
|
|
120
|
+
child.on("error", () => {
|
|
121
|
+
exited = true;
|
|
122
|
+
});
|
|
123
|
+
child.on("exit", () => {
|
|
124
|
+
exited = true;
|
|
125
|
+
});
|
|
126
|
+
child.unref();
|
|
127
|
+
const began = Date.now();
|
|
128
|
+
while (!exited && Date.now() - began < START_TIMEOUT_MS) {
|
|
129
|
+
await new Promise((wait) => setTimeout(wait, 300));
|
|
130
|
+
const started = await runningRuntime(dataDir);
|
|
131
|
+
if (started) {
|
|
132
|
+
return started;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
99
137
|
/**
|
|
100
|
-
* Starts the runtime of this install
|
|
101
|
-
*
|
|
138
|
+
* Starts the runtime of this install and opens the studio: in the foreground, or with
|
|
139
|
+
* `background` detached from this terminal. If one already runs on the same data folder
|
|
140
|
+
* (another terminal, the desktop app), that one is opened instead.
|
|
102
141
|
*/
|
|
103
142
|
export async function start(paths, options) {
|
|
104
143
|
const { fileEnv, dataDir, port: wanted, appUrl } = settings(paths);
|
|
@@ -110,6 +149,16 @@ export async function start(paths, options) {
|
|
|
110
149
|
console.log(styleText("dim", " It was already running; stop it with `wizards stop`."));
|
|
111
150
|
return 0;
|
|
112
151
|
}
|
|
152
|
+
if (options.background) {
|
|
153
|
+
const started = await startInBackground(paths);
|
|
154
|
+
if (!started) {
|
|
155
|
+
console.error(`engenty wizards did not start; see ${join(paths.logs, "runtime.log")}.`);
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
show(started.url, entryUrl(started, dataDir), options.open);
|
|
159
|
+
console.log(styleText("dim", ` It runs in the background; stop it with \`wizards stop\`. Its log: ${join(paths.logs, "runtime.log")}`));
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
113
162
|
const port = wanted ?? (await freePort());
|
|
114
163
|
if (!wanted && port !== DEFAULT_PORT) {
|
|
115
164
|
console.log(styleText("dim", ` Port ${DEFAULT_PORT} is taken, using ${port}.`));
|
|
@@ -160,15 +209,10 @@ export async function start(paths, options) {
|
|
|
160
209
|
if (code !== RESTART_EXIT) {
|
|
161
210
|
return code;
|
|
162
211
|
}
|
|
163
|
-
// Updated
|
|
164
|
-
// under the login item, which keeps waiting on this process.
|
|
165
|
-
console.log(styleText("dim", "
|
|
166
|
-
|
|
167
|
-
current = existsSync(wrapper)
|
|
168
|
-
? spawn(wrapper, ["start", "--no-open"], { stdio: "inherit" })
|
|
169
|
-
: spawn(process.execPath, [join(packageRoot, "bin/wizards.mjs"), "start", "--no-open"], {
|
|
170
|
-
stdio: "inherit",
|
|
171
|
-
});
|
|
212
|
+
// Updated or `wizards restart`: the command as it is on disk now starts it again, in this
|
|
213
|
+
// terminal or under the login item, which keeps waiting on this process.
|
|
214
|
+
console.log(styleText("dim", " Starting it again."));
|
|
215
|
+
current = spawnCommand(paths, ["start", "--no-open"], { stdio: "inherit" });
|
|
172
216
|
return new Promise((done) => {
|
|
173
217
|
current.on("error", () => done(1));
|
|
174
218
|
current.on("exit", (exit) => done(exit ?? 0));
|
|
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { autostartState, setAutostart } from "./autostart.js";
|
|
4
4
|
import { installedByScript, isCheckout, packageRoot, packageVersion } from "./home.js";
|
|
5
5
|
import { detectClients, findChrome, findFfmpeg, nodeIsCurrent } from "./machine.js";
|
|
6
|
-
import { runningRuntime, settings } from "./start.js";
|
|
6
|
+
import { entryUrl, runningRuntime, settings, startInBackground } from "./start.js";
|
|
7
7
|
import { bad, badge, cyan, dim, no, ok, tilde } from "./ui.js";
|
|
8
8
|
/**
|
|
9
9
|
* What is installed and what runs. With `checks` (`doctor`) it also says what is wrong and
|
|
@@ -68,6 +68,19 @@ export async function status(paths, checks) {
|
|
|
68
68
|
console.log("");
|
|
69
69
|
return problems.length ? 1 : 0;
|
|
70
70
|
}
|
|
71
|
+
/** Waits for a process to end; false when it still runs after `ms`. */
|
|
72
|
+
async function ended(pid, ms) {
|
|
73
|
+
for (let waited = 0; waited < ms; waited += 100) {
|
|
74
|
+
try {
|
|
75
|
+
process.kill(pid, 0);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
await new Promise((wait) => setTimeout(wait, 100));
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
71
84
|
/** Stops the runtime that runs on this install's data folder. */
|
|
72
85
|
export async function stop(paths) {
|
|
73
86
|
const { dataDir } = settings(paths);
|
|
@@ -77,19 +90,52 @@ export async function stop(paths) {
|
|
|
77
90
|
return 0;
|
|
78
91
|
}
|
|
79
92
|
process.kill(running.pid, "SIGTERM");
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
console.log(`Stopped (pid ${running.pid}). Your data is kept.`);
|
|
86
|
-
return 0;
|
|
87
|
-
}
|
|
88
|
-
await new Promise((wait) => setTimeout(wait, 100));
|
|
93
|
+
if (await ended(running.pid, 8000)) {
|
|
94
|
+
console.log(`Stopped (pid ${running.pid}). Your data is kept.`);
|
|
95
|
+
return 0;
|
|
89
96
|
}
|
|
90
97
|
console.error(`The runtime (pid ${running.pid}) did not stop within 8 seconds.`);
|
|
91
98
|
return 1;
|
|
92
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Stops the runtime and starts it again, the version on disk now. One the command started (a
|
|
102
|
+
* terminal, the login item) is started again by that command, where it ran; any other is
|
|
103
|
+
* stopped and started in the background. When nothing runs, it is started in the background.
|
|
104
|
+
*/
|
|
105
|
+
export async function restart(paths) {
|
|
106
|
+
const { dataDir } = settings(paths);
|
|
107
|
+
const running = await runningRuntime(dataDir);
|
|
108
|
+
if (running?.restarts && process.platform !== "win32") {
|
|
109
|
+
process.kill(running.pid, "SIGUSR2");
|
|
110
|
+
for (let waited = 0; waited < 60_000; waited += 300) {
|
|
111
|
+
await new Promise((wait) => setTimeout(wait, 300));
|
|
112
|
+
const again = await runningRuntime(dataDir);
|
|
113
|
+
if (again && again.pid !== running.pid) {
|
|
114
|
+
console.log(`${ok} Restarted: ${cyan(again.url)} ${dim(`pid ${again.pid}`)}`);
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
console.error("engenty wizards did not start again within a minute.");
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
if (running) {
|
|
122
|
+
process.kill(running.pid, "SIGTERM");
|
|
123
|
+
if (!(await ended(running.pid, 8000))) {
|
|
124
|
+
console.error(`The runtime (pid ${running.pid}) did not stop within 8 seconds.`);
|
|
125
|
+
return 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const started = await startInBackground(paths);
|
|
129
|
+
if (!started) {
|
|
130
|
+
console.error(`engenty wizards did not start; see ${join(paths.logs, "runtime.log")}.`);
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
console.log(`${ok} ${running ? "Restarted" : "Started"}: ${cyan(started.url)} ${dim(`pid ${started.pid}, in the background`)}`);
|
|
134
|
+
if (!running) {
|
|
135
|
+
console.log(` Open the studio: ${entryUrl(started, dataDir)}`);
|
|
136
|
+
}
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
93
139
|
/** `autostart [on|off]`: whether it starts at login, and the switch. */
|
|
94
140
|
export async function autostart(paths, value) {
|
|
95
141
|
if (value && value !== "on" && value !== "off") {
|
|
@@ -52,7 +52,7 @@ export async function update(paths) {
|
|
|
52
52
|
rmSync(tmp, { recursive: true, force: true });
|
|
53
53
|
}
|
|
54
54
|
if (await runningRuntime(settings(paths).dataDir)) {
|
|
55
|
-
console.log(` The runtime that is running is still the old one. Restart it: ${cyan("wizards
|
|
55
|
+
console.log(` The runtime that is running is still the old one. Restart it: ${cyan("wizards restart")}`);
|
|
56
56
|
}
|
|
57
57
|
return 0;
|
|
58
58
|
}
|
|
@@ -15,7 +15,7 @@ import { syncMarketplace } from "./services/marketplace.js";
|
|
|
15
15
|
import { purgeExpiredRuns } from "./services/shares.js";
|
|
16
16
|
import { purgeUnusedStores } from "./store/index.js";
|
|
17
17
|
import { LOCAL_TENANT } from "./tenants/tenant.js";
|
|
18
|
-
import { onRestart } from "./update.js";
|
|
18
|
+
import { onRestart, RESTART_EXIT } from "./update.js";
|
|
19
19
|
await migrateControlDb();
|
|
20
20
|
// What the linked account's plan confirmed last: the Pro modules it includes load with the rest.
|
|
21
21
|
await loadEntitlement();
|
|
@@ -61,6 +61,7 @@ const server = serve({ fetch: withoutBasePath, port: env.port, hostname: env.hos
|
|
|
61
61
|
port: info.port,
|
|
62
62
|
url: env.appUrl,
|
|
63
63
|
startedAt: new Date().toISOString(),
|
|
64
|
+
restarts: process.env.ENGENTY_WIZARDS_RESTARTS === "1",
|
|
64
65
|
});
|
|
65
66
|
}
|
|
66
67
|
});
|
|
@@ -90,3 +91,7 @@ async function shutdown(code = 0) {
|
|
|
90
91
|
process.on("SIGINT", () => shutdown());
|
|
91
92
|
process.on("SIGTERM", () => shutdown());
|
|
92
93
|
onRestart((code) => void shutdown(code));
|
|
94
|
+
// `wizards restart`: the command that started it starts it again, where it ran.
|
|
95
|
+
if (process.env.ENGENTY_WIZARDS_RESTARTS === "1" && process.platform !== "win32") {
|
|
96
|
+
process.on("SIGUSR2", () => shutdown(RESTART_EXIT));
|
|
97
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,n as t,t as n}from"./jsx-runtime-D3jfb0Ew.js";import{D as r,Q as i}from"./surface-BFwNWkx9.js";import{D as a,G as o,H as s,c,f as l,g as u,h as d,j as f,k as p,n as ee,o as m,r as h,s as g,t as _,x as v}from"./ui-BTkH_7CG.js";import{n as y,r as b}from"./upload-Dok4YeXQ.js";import{t as x}from"./external-link-DvkH63pi.js";import{B as te,H as S,I as C,U as w,W as T,_t as E,at as D,ft as O}from"./index-CYZmm7HU.js";import{n as k}from"./LocalRuntime-DMU_dzV1.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=o(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=o(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=o(P),I=e(t(),1),L=e=>[`project-files`,e];function R(e){return r({queryKey:L(e),queryFn:()=>v.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function z(e,t){return a(`/api/studio/projects/${e}/files/${t}/content`)}function B(e,t=!1){let n=i(),[r,a]=(0,I.useState)(!1),[o,s]=(0,I.useState)(null),c=()=>n.invalidateQueries({queryKey:L(e)}),l=async e=>{s(null);try{await e()}catch(e){s(e.message)}finally{await c()}};return{busy:r,error:o,readOnly:t,upload:async(t,n)=>{a(!0),await l(async()=>{for(let r of n)await v.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await c()}),a(!1)},describe:(t,n)=>l(()=>v.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>l(()=>v.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>l(()=>v.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>l(()=>v.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)(l,{className:`size-3`}),` `,f(`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)(s,{className:`size-3.5`}),` `,f(`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)(ee,{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)(m,{label:f(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)(y,{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)(l,{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:u(`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=i(),[n,r]=(0,I.useState)(!1),a=E({mutationFn:e=>v.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:a,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,W.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:f(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,W.jsx)(l,{className:`size-3.5`}),` `,f(`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:f(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:f(`account.localText`)})]})]}),w.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:f(`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)(b,{className:`mt-0.5 size-4 shrink-0 text-amber`}),f(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),f(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(_,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:f(`account.signIn`)})})]}):null,w.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:f(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:f(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(g,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:f(`account.code`),"aria-label":f(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[0.875rem]`}),(0,W.jsx)(_,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:f(`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=i(),n=Z(e.signedIn),r=E({mutationFn:()=>v.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),a=new Intl.DateTimeFormat(p,{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)(h,{tone:`live`,children:f(`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)(_,{variant:`secondary`,onClick:()=>k(e.url),children:[f(`setup.openAccount`),` `,(0,W.jsx)(x,{className:`size-4`})]}),(0,W.jsxs)(_,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(D,{className:`size-4`}),` `,f(`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:f(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(_,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:f(`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:f(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[1.375rem] tabular-nums leading-tight`,children:f(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(_,{variant:`secondary`,onClick:()=>k(`${e.url}/billing`),children:[f(`account.topUp`),` `,(0,W.jsx)(x,{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:[f(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:a.format(new Date(e.expiresAt))}),$[e.kind]?(0,W.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,f($[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)(O,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:f(`account.cloud`,{host:C(e.cloudUrl)})})]})]})}function ie({me:e,fromAccount:t}){let n=i(),[r,a]=(0,I.useState)(e.profile),o=e=>a(t=>({...t,...e})),s=H(r,async e=>{await v.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,W.jsx)(K,{title:f(`account.profile`),hint:f(`account.hint`),save:s,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`}):T(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[0.75rem] text-ink-3 leading-snug`,children:f(`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)(c,{children:f(`account.name`)}),(0,W.jsx)(g,{value:r.name,maxLength:80,disabled:t,onChange:e=>o({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:f(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.about`)}),(0,W.jsx)(d,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>o({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:f(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.email`)}),(0,W.jsx)(g,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>o({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.phone`)}),(0,W.jsx)(g,{type:`tel`,value:r.phone,maxLength:40,onChange:e=>o({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:f(`account.connection`),hint:f(`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)(h,{tone:`live`,children:f(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(_,{variant:`secondary`,onClick:()=>k(`${e.manageUrl}/account`),children:[f(`setup.openAccount`),` `,(0,W.jsx)(x,{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:f(`account.look`),hint:f(`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:f(`nav.language`)}),(0,W.jsx)(S,{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:f(`nav.theme`)}),(0,W.jsx)(te,{})]})]})})]})}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{D as r,Q as i}from"./surface-CywgBXMy.js";import{D as a,G as o,H as s,c,f as l,g as u,h as d,j as f,k as p,n as ee,o as m,r as h,s as g,t as _,x as v}from"./ui-DyazyiaK.js";import{n as y,r as b}from"./upload-Dl_w8YOa.js";import{t as x}from"./external-link-CbxUCKS8.js";import{B as te,H as S,I as C,U as w,W as T,_t as E,at as D,ft as O}from"./index-KVvpYi_r.js";import{n as k}from"./LocalRuntime-D0L3FtDm.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=o(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=o(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=o(P),I=e(t(),1),L=e=>[`project-files`,e];function R(e){return r({queryKey:L(e),queryFn:()=>v.get(`/api/studio/projects/${e}/files`),refetchInterval:e=>e.state.data?.files.some(e=>e.status===`pending`)?2e3:!1})}function z(e,t){return a(`/api/studio/projects/${e}/files/${t}/content`)}function B(e,t=!1){let n=i(),[r,a]=(0,I.useState)(!1),[o,s]=(0,I.useState)(null),c=()=>n.invalidateQueries({queryKey:L(e)}),l=async e=>{s(null);try{await e()}catch(e){s(e.message)}finally{await c()}};return{busy:r,error:o,readOnly:t,upload:async(t,n)=>{a(!0),await l(async()=>{for(let r of n)await v.upload(`/api/studio/projects/${e}/files?kind=${t}`,r),await c()}),a(!1)},describe:(t,n)=>l(()=>v.patch(`/api/studio/projects/${e}/files/${t}`,{description:n})),remove:t=>l(()=>v.del(`/api/studio/projects/${e}/files/${t}`)),reindex:t=>l(()=>v.post(`/api/studio/projects/${e}/files/${t}/reindex`)),order:(t,n)=>l(()=>v.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)(l,{className:`size-3`}),` `,f(`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)(s,{className:`size-3.5`}),` `,f(`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)(ee,{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)(m,{label:f(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)(y,{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)(l,{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:u(`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=i(),[n,r]=(0,I.useState)(!1),a=E({mutationFn:e=>v.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:a,waiting:n}}function Q({link:e,waiting:t}){return e.isError?(0,W.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:f(`local.accountFailed`)}):t?(0,W.jsxs)(`p`,{className:`flex items-center gap-2 text-[0.8125rem] text-ink-3`,children:[(0,W.jsx)(l,{className:`size-3.5`}),` `,f(`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:f(`account.local`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:f(`account.localText`)})]})]}),w.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:f(`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)(b,{className:`mt-0.5 size-4 shrink-0 text-amber`}),f(`account.withCredits`)]}),(0,W.jsxs)(`li`,{className:`flex items-start gap-2.5`,children:[(0,W.jsx)(O,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),f(`account.withCloud`)]})]})]}),(0,W.jsx)(`div`,{children:(0,W.jsx)(_,{busy:t.isPending&&!t.variables?.signup,onClick:()=>t.mutate({}),children:f(`account.signIn`)})})]}):null,w.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:f(`account.new`)}),(0,W.jsx)(`p`,{className:`mt-1 text-[0.875rem] text-ink-3 leading-relaxed`,children:f(`account.newHint`)})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,W.jsx)(g,{value:n,maxLength:64,autoComplete:`off`,spellCheck:!1,placeholder:f(`account.code`),"aria-label":f(`account.code`),onChange:e=>r(e.target.value),className:`w-56 font-mono text-[0.875rem]`}),(0,W.jsx)(_,{type:`submit`,variant:`secondary`,className:`h-11`,busy:t.isPending&&!!t.variables?.signup,children:f(`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=i(),n=Z(e.signedIn),r=E({mutationFn:()=>v.del(`/api/studio/account`),onSuccess:()=>t.invalidateQueries({queryKey:[`me`]})}),a=new Intl.DateTimeFormat(p,{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)(h,{tone:`live`,children:f(`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)(_,{variant:`secondary`,onClick:()=>k(e.url),children:[f(`setup.openAccount`),` `,(0,W.jsx)(x,{className:`size-4`})]}),(0,W.jsxs)(_,{variant:`ghost`,busy:r.isPending,onClick:()=>r.mutate(),children:[(0,W.jsx)(D,{className:`size-4`}),` `,f(`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:f(`local.accountExpired`)}),(0,W.jsx)(`div`,{children:(0,W.jsx)(_,{busy:n.link.isPending,onClick:()=>n.link.mutate({}),children:f(`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:f(`account.credits`)}),(0,W.jsx)(`div`,{className:`font-display font-semibold text-[1.375rem] tabular-nums leading-tight`,children:f(`nav.credits`,{n:Math.floor(e.credits).toLocaleString()})})]}),(0,W.jsxs)(_,{variant:`secondary`,onClick:()=>k(`${e.url}/billing`),children:[f(`account.topUp`),` `,(0,W.jsx)(x,{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:[f(`account.expires`,{n:Math.floor(e.credits).toLocaleString(),date:a.format(new Date(e.expiresAt))}),$[e.kind]?(0,W.jsxs)(`span`,{className:`text-ink-4`,children:[` · `,f($[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)(O,{className:`mt-0.5 size-4 shrink-0 text-cobalt`}),(0,W.jsx)(`p`,{children:f(`account.cloud`,{host:C(e.cloudUrl)})})]})]})}function ie({me:e,fromAccount:t}){let n=i(),[r,a]=(0,I.useState)(e.profile),o=e=>a(t=>({...t,...e})),s=H(r,async e=>{await v.put(`/api/studio/profile`,e),await n.invalidateQueries({queryKey:[`me`]})});return(0,W.jsx)(K,{title:f(`account.profile`),hint:f(`account.hint`),save:s,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`}):T(r.name)||`?`}),(0,W.jsx)(`p`,{className:`text-center text-[0.75rem] text-ink-3 leading-snug`,children:f(`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)(c,{children:f(`account.name`)}),(0,W.jsx)(g,{value:r.name,maxLength:80,disabled:t,onChange:e=>o({name:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:f(t?`account.fromAccount`:`account.nameHint`)})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.about`)}),(0,W.jsx)(d,{minRows:3,maxLength:2e3,value:r.about,onChange:e=>o({about:e.target.value})}),(0,W.jsx)(`p`,{className:X,children:f(`account.aboutHint`)})]}),(0,W.jsxs)(`div`,{className:`grid gap-5 sm:grid-cols-2`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.email`)}),(0,W.jsx)(g,{type:`email`,value:r.email,maxLength:200,disabled:t,onChange:e=>o({email:e.target.value})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(c,{children:f(`account.phone`)}),(0,W.jsx)(g,{type:`tel`,value:r.phone,maxLength:40,onChange:e=>o({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:f(`account.connection`),hint:f(`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)(h,{tone:`live`,children:f(`account.linked`)})]}),(0,W.jsx)(`div`,{className:`truncate text-[0.875rem] text-ink-3`,children:e.user.email})]}),e.manageUrl?(0,W.jsxs)(_,{variant:`secondary`,onClick:()=>k(`${e.manageUrl}/account`),children:[f(`setup.openAccount`),` `,(0,W.jsx)(x,{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:f(`account.look`),hint:f(`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:f(`nav.language`)}),(0,W.jsx)(S,{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:f(`nav.theme`)}),(0,W.jsx)(te,{})]})]})})]})}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 +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,f as a,g as o,i as s,j as c,s as l}from"./ui-
|
|
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,f as a,g as o,i as s,j as c,s as l}from"./ui-DyazyiaK.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/,``):c(`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}async function _(e){if(e)try{let t=await fetch(`https://raw.githubusercontent.com/engenty/engenty-wizards/v${e}/apps/web/src/about/changelog.json`,{signal:AbortSignal.timeout(5e3)});if(t.ok)return await t.json()}catch{}return(await r(async()=>{let{default:e}=await import(`./changelog-DCBBW4Ql.js`);return{default:e}},[])).default}function v({open:e,onClose:t,version:n}){let[r,v]=(0,u.useState)(null),[y,b]=(0,u.useState)(``);(0,u.useEffect)(()=>{if(!e||r)return;let t=!1;return _(n).then(e=>{t||v(e)}),()=>{t=!0}},[e,r,n]),(0,u.useEffect)(()=>{e||b(``)},[e]);let x=r?g(r,y):[];return(0,d.jsxs)(s,{open:e,onClose:t,title:c(`about.changelog`),wide:!0,children:[(0,d.jsx)(`p`,{className:`-mt-3 mb-4 text-[0.875rem] text-ink-3`,children:c(`about.changelogHint`)}),r===null?(0,d.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,d.jsx)(a,{})}):r.length===0?(0,d.jsx)(i,{children:c(`about.changelogEmpty`)}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(l,{type:`search`,value:y,placeholder:c(`about.search`),onChange:e=>b(e.target.value)}),x.length===0?(0,d.jsx)(i,{children:c(`about.noMatches`)}):null,x.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-[1rem]`,children:[p(e),(0,d.jsx)(`span`,{className:`font-normal font-sans text-[0.8125rem] 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-[0.875rem]`,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-[0.75rem] 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-[0.75rem] text-rose`,children:c(`about.breaking`)}):null]})]},e.id)})})]},e.version??`unreleased`))]})]})}export{v as ChangelogDialog};
|