castle-web-cli 0.4.107 → 0.4.108

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/dist/agent.js CHANGED
@@ -26,7 +26,7 @@ import { checkOpenrouterKey, checkOpenrouterModel, openrouterCatalogEntry, prime
26
26
  import { classifyProviderError, failureCopy, setReaderTimeZone, } from "./agent-failures.js";
27
27
  import { fetchBudget, meteringHeaders, newAgentSessionId, reportCursorRun, withCustomHeaders, } from "./metering.js";
28
28
  import { anthropicKeyHelperCommand, claudeHasSavedLogin, cursorAuthPath, cursorHasUserLogin, resolveAnthropicAuth, userKey, ANTHROPIC_CREDENTIAL_ENV, ANTHROPIC_PROXY_ENV, CASTLE_USER_KEYS_PATH, } from "./byo-auth.js";
29
- import { accountsSnapshot, loginProviderFor, writeCredential, } from "./byo-accounts.js";
29
+ import { accountsSnapshot, loginProviderFor, watchCredentials, writeCredential, } from "./byo-accounts.js";
30
30
  import { cancelLogin, logout, startLogin, submitLoginCode, } from "./byo-login.js";
31
31
  import { runAgentNative } from "./native/loop.js";
32
32
  import { createPlaytestBrowserManager } from "./native/playtest-browser.js";
@@ -3022,25 +3022,73 @@ function applyAgentSettings(incoming, ctx) {
3022
3022
  ctx.broadcast({ type: "settings", settings });
3023
3023
  void broadcastSettingsWarnings(ctx);
3024
3024
  }
3025
- // Store or remove one BYO credential for the editor's Accounts rows. Unlike a
3026
- // settings change this persists nothing itself -- byo-accounts owns the file --
3027
- // and it always answers with a fresh snapshot, including on a rejected write,
3028
- // so a client that sent something invalid learns why instead of watching its
3029
- // input silently do nothing. The snapshot carries presence and a hint only; no
3030
- // frame from here ever moves a key value toward a browser.
3031
- function broadcastAccounts(broadcast, error) {
3032
- broadcast({
3033
- type: "accounts",
3034
- accounts: accountsSnapshot(),
3035
- ...(error ? { accountsError: error } : {}),
3036
- });
3025
+ // Belt to watchCredentials' braces: a directory that didn't exist at boot has
3026
+ // no watcher on it, and an inotify watch can be lost. Slow, because the watch is
3027
+ // what makes this feel live -- this only has to stop a miss from lasting.
3028
+ const ACCOUNTS_POLL_MS = 15_000;
3029
+ // The editor's view of which credentials exist, kept live. Unlike settings --
3030
+ // which nothing outside this process writes -- a credential changes behind the
3031
+ // editor's back all the time: `claude /login` or `cursor-agent logout` in the
3032
+ // terminal panel, a hand-edited user-keys.json, an agent run that refreshes an
3033
+ // OAuth token. Push those, or the popover reports whatever was true when the
3034
+ // page loaded and a terminal sign-in reads as having done nothing.
3035
+ //
3036
+ // The snapshot carries presence and a hint only; no frame from here ever moves
3037
+ // a key value toward a browser.
3038
+ function createAccountsFeed(opts) {
3039
+ let last = "";
3040
+ // Tracked apart from the whole snapshot so a sign-in's phase transitions
3041
+ // (starting -> awaiting-code -> ...) don't each cost a budget fetch: they
3042
+ // move `login`, never a credential.
3043
+ let lastProviders = "";
3044
+ function push(error) {
3045
+ const accounts = accountsSnapshot();
3046
+ const serialized = JSON.stringify(accounts);
3047
+ const providers = JSON.stringify(accounts.providers);
3048
+ if (providers !== lastProviders) {
3049
+ lastProviders = providers;
3050
+ opts.onCredentialChange();
3051
+ }
3052
+ // A refusal always goes out. It is the only answer a rejected write gets,
3053
+ // and a rejected write leaves the snapshot identical by definition -- so
3054
+ // deduping on the snapshot alone would swallow exactly the frame that
3055
+ // carries the reason.
3056
+ if (serialized === last && !error)
3057
+ return;
3058
+ last = serialized;
3059
+ opts.broadcast({
3060
+ type: "accounts",
3061
+ accounts,
3062
+ ...(error ? { accountsError: error } : {}),
3063
+ });
3064
+ }
3065
+ function snapshot() {
3066
+ const accounts = accountsSnapshot();
3067
+ last = JSON.stringify(accounts);
3068
+ lastProviders = JSON.stringify(accounts.providers);
3069
+ return accounts;
3070
+ }
3071
+ const stopWatch = watchCredentials(() => push());
3072
+ const timer = setInterval(() => {
3073
+ if (opts.hasClients())
3074
+ push();
3075
+ }, ACCOUNTS_POLL_MS);
3076
+ timer.unref?.();
3077
+ return {
3078
+ snapshot,
3079
+ push,
3080
+ stop: () => {
3081
+ stopWatch();
3082
+ clearInterval(timer);
3083
+ },
3084
+ };
3037
3085
  }
3038
3086
  function applyCredentialChange(msg, ctx) {
3039
3087
  const clearing = msg.type === "clear-credential";
3040
3088
  if (!clearing && typeof msg.value !== "string")
3041
3089
  return;
3042
3090
  const result = writeCredential(msg.id, clearing ? null : msg.value);
3043
- broadcastAccounts(ctx.broadcast, result.ok
3091
+ ctx.pushAccounts(result.ok
3044
3092
  ? undefined
3045
3093
  : { id: typeof msg.id === "string" ? msg.id : "", message: result.message });
3046
3094
  }
@@ -3518,6 +3566,11 @@ export function createAgentServer(opts) {
3518
3566
  hasClients: () => clients.size > 0,
3519
3567
  castlePaid: () => anyRoleIsCastlePaid(settings),
3520
3568
  });
3569
+ const accountsFeed = createAccountsFeed({
3570
+ broadcast,
3571
+ hasClients: () => clients.size > 0,
3572
+ onCredentialChange: () => usageFeed.refresh(),
3573
+ });
3521
3574
  const applySettings = (incoming) => {
3522
3575
  applyAgentSettings(incoming, { settings, settingsPath, broadcast });
3523
3576
  // A backend switch can change who pays (a cursor role always spends
@@ -3595,7 +3648,7 @@ export function createAgentServer(opts) {
3595
3648
  running: routerQueue.isRunning(),
3596
3649
  queued: routerQueue.queuedSnippets(),
3597
3650
  usage: usageFeed.latest(),
3598
- accounts: accountsSnapshot(),
3651
+ accounts: accountsFeed.snapshot(),
3599
3652
  };
3600
3653
  socket.send(JSON.stringify(hello));
3601
3654
  // A newly attached client is the one moment the cached value may be stale
@@ -3638,12 +3691,12 @@ export function createAgentServer(opts) {
3638
3691
  }
3639
3692
  else if (msg.type === "set-credential" ||
3640
3693
  msg.type === "clear-credential") {
3641
- applyCredentialChange(msg, { broadcast });
3694
+ applyCredentialChange(msg, { pushAccounts: accountsFeed.push });
3642
3695
  }
3643
3696
  else if (msg.type === "account-login") {
3644
3697
  const provider = loginProviderFor(msg.id);
3645
3698
  if (provider)
3646
- startLogin(provider, () => broadcastAccounts(broadcast));
3699
+ startLogin(provider, () => accountsFeed.push());
3647
3700
  }
3648
3701
  else if (msg.type === "account-login-code" && typeof msg.value === "string") {
3649
3702
  submitLoginCode(msg.value);
@@ -3654,7 +3707,7 @@ export function createAgentServer(opts) {
3654
3707
  else if (msg.type === "account-logout") {
3655
3708
  const provider = loginProviderFor(msg.id);
3656
3709
  if (provider)
3657
- logout(provider, () => broadcastAccounts(broadcast));
3710
+ logout(provider, () => accountsFeed.push());
3658
3711
  }
3659
3712
  else if (msg.type === "client-timezone" && typeof msg.timeZone === "string") {
3660
3713
  setReaderTimeZone(msg.timeZone);
@@ -3690,6 +3743,7 @@ export function createAgentServer(opts) {
3690
3743
  }
3691
3744
  stopChildRegistry();
3692
3745
  usageFeed.stop();
3746
+ accountsFeed.stop();
3693
3747
  wss.close();
3694
3748
  void playtestBrowserManager.shutdown();
3695
3749
  }
@@ -18,6 +18,23 @@ export interface AccountsState {
18
18
  login: LoginState | null;
19
19
  }
20
20
  export declare function accountsSnapshot(): AccountsState;
21
+ /**
22
+ * Call `onChange` when a credential this module reports on changes on disk.
23
+ *
24
+ * The editor is not the only writer: `claude /login` and `cursor-agent login`
25
+ * in the terminal panel, an agent run that refreshes an OAuth token, and a
26
+ * hand-edited `user-keys.json` all change the answer behind its back. Without
27
+ * this the account state is whatever was true when the page loaded, so a
28
+ * terminal sign-in looks like it did nothing until a reload.
29
+ *
30
+ * Directories, never the credential files themselves: the CLIs replace those by
31
+ * rename, which leaves a file watch holding the old inode and silently deaf --
32
+ * the same reason castle-sandboxes persists these paths as directory symlinks.
33
+ * A directory that doesn't exist yet (no `~/.castle` until the first key) simply
34
+ * isn't watched; the caller's poll is what covers that, and losing a watcher
35
+ * costs freshness, never correctness.
36
+ */
37
+ export declare function watchCredentials(onChange: () => void): () => void;
21
38
  export type CredentialWriteResult = {
22
39
  ok: true;
23
40
  changed: boolean;
@@ -4,13 +4,13 @@
4
4
  //
5
5
  // Split from byo-auth.ts deliberately. That module is the RESOLVER -- pure,
6
6
  // read-only, and imported by the terminal shim's helper on EVERY `claude` run
7
- // (see installClaudeShim), so it must stay free of anything stateful. This one
7
+ // (see installCliShims), so it must stay free of anything stateful. This one
8
8
  // is allowed to write. The login subprocesses live in byo-login.ts; this module
9
9
  // only reports their state as part of one snapshot.
10
10
  import * as fs from "fs";
11
11
  import * as os from "os";
12
12
  import * as path from "path";
13
- import { CASTLE_USER_KEYS_PATH, claudeHasSavedLogin, cursorHasUserLogin, readUserKeys, } from "./byo-auth.js";
13
+ import { CASTLE_USER_KEYS_PATH, claudeCredentialsPath, claudeHasSavedLogin, cursorAuthPath, cursorHasUserLogin, readUserKeys, } from "./byo-auth.js";
14
14
  import { activeLogin } from "./byo-login.js";
15
15
  import { inCastleSandbox } from "./metering.js";
16
16
  // Providers, not credentials: Anthropic is reachable by EITHER a key or a
@@ -90,6 +90,60 @@ export function accountsSnapshot() {
90
90
  login: activeLogin(),
91
91
  };
92
92
  }
93
+ // Several events land for one credential change (a rename is a delete plus a
94
+ // create, and the CLIs write neighbouring files in the same breath); one
95
+ // snapshot after the burst is what the editor wants.
96
+ const WATCH_DEBOUNCE_MS = 250;
97
+ /**
98
+ * Call `onChange` when a credential this module reports on changes on disk.
99
+ *
100
+ * The editor is not the only writer: `claude /login` and `cursor-agent login`
101
+ * in the terminal panel, an agent run that refreshes an OAuth token, and a
102
+ * hand-edited `user-keys.json` all change the answer behind its back. Without
103
+ * this the account state is whatever was true when the page loaded, so a
104
+ * terminal sign-in looks like it did nothing until a reload.
105
+ *
106
+ * Directories, never the credential files themselves: the CLIs replace those by
107
+ * rename, which leaves a file watch holding the old inode and silently deaf --
108
+ * the same reason castle-sandboxes persists these paths as directory symlinks.
109
+ * A directory that doesn't exist yet (no `~/.castle` until the first key) simply
110
+ * isn't watched; the caller's poll is what covers that, and losing a watcher
111
+ * costs freshness, never correctness.
112
+ */
113
+ export function watchCredentials(onChange) {
114
+ const dirs = new Set([
115
+ claudeCredentialsPath(),
116
+ cursorAuthPath(os.homedir()),
117
+ CASTLE_USER_KEYS_PATH,
118
+ ].map((p) => path.dirname(p)));
119
+ let timer = null;
120
+ const fire = () => {
121
+ if (timer)
122
+ clearTimeout(timer);
123
+ timer = setTimeout(onChange, WATCH_DEBOUNCE_MS);
124
+ timer.unref?.();
125
+ };
126
+ const watchers = [];
127
+ for (const dir of dirs) {
128
+ try {
129
+ const w = fs.watch(dir, fire);
130
+ // A watch that dies later (the directory is removed, inotify runs out)
131
+ // must not take the serve with it -- fs.watch reports those as an error
132
+ // event, which is fatal when nothing is listening.
133
+ w.on("error", () => undefined);
134
+ watchers.push(w);
135
+ }
136
+ catch {
137
+ /* not watchable here */
138
+ }
139
+ }
140
+ return () => {
141
+ if (timer)
142
+ clearTimeout(timer);
143
+ for (const w of watchers)
144
+ w.close();
145
+ };
146
+ }
93
147
  // Generous -- provider key formats are not ours to predict -- but bounded, so a
94
148
  // stray paste of a whole file can't land in the credential store.
95
149
  const MAX_KEY_LENGTH = 500;
@@ -17,6 +17,7 @@ export type OpenrouterAuth = {
17
17
  mode: "proxy";
18
18
  key: string;
19
19
  };
20
+ export declare function claudeCredentialsPath(): string;
20
21
  export declare function claudeHasSavedLogin(): boolean;
21
22
  export declare function cursorAuthPath(home: string): string;
22
23
  export declare function cursorHasUserLogin(home: string): boolean;
@@ -25,5 +26,10 @@ export declare const ANTHROPIC_CREDENTIAL_ENV: readonly ["ANTHROPIC_API_KEY", "A
25
26
  export declare const ANTHROPIC_PROXY_ENV: readonly ["ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_CUSTOM_HEADERS", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN_HELPER", "CLAUDE_CODE_OAUTH_TOKEN"];
26
27
  export declare function anthropicKeyHelperCommand(): string;
27
28
  export declare function envForUserShell(base: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
28
- export declare function claudeShellEnvScript(env: NodeJS.ProcessEnv, shimDir: string): string;
29
- export declare function installClaudeShim(deckDir: string): string | null;
29
+ export declare const SHIMMED_CLIS: readonly ["claude", "cursor-agent"];
30
+ export type ShimmedCli = (typeof SHIMMED_CLIS)[number];
31
+ export declare function claudeShellEnvScript(env: NodeJS.ProcessEnv, args?: readonly string[]): string;
32
+ export declare function cursorShellEnvScript(env: NodeJS.ProcessEnv): string;
33
+ export declare function shimEnvScript(cli: string, env: NodeJS.ProcessEnv, shimDir: string, args?: readonly string[]): string;
34
+ export declare function ensureClaudeOnboarded(): void;
35
+ export declare function installCliShims(deckDir: string): string | null;
package/dist/byo-auth.js CHANGED
@@ -14,6 +14,7 @@ import * as fs from "fs";
14
14
  import * as os from "os";
15
15
  import * as path from "path";
16
16
  import { fileURLToPath } from "url";
17
+ import { inCastleSandbox } from "./metering.js";
17
18
  const DIST_DIR = path.dirname(fileURLToPath(import.meta.url));
18
19
  // A user's OWN provider credentials, kept SEPARATE from Castle's keys.json so
19
20
  // castle-www's per-serve re-sync of keys.json (cloudSandbox.ts syncCastleKeys)
@@ -55,23 +56,43 @@ export function userKey(envName) {
55
56
  const trimmed = v.trim();
56
57
  return trimmed ? trimmed : null;
57
58
  }
59
+ // CLAUDE_CONFIG_DIR moves BOTH of claude's own files, and the sandbox sets it
60
+ // (castle-sandboxes points it at the directory it persists, so `.claude.json` --
61
+ // which holds the account record and the onboarding state -- lands inside the
62
+ // symlink alongside the credential rather than beside it). Reading os.homedir()
63
+ // unconditionally would mean reading a path claude has been told not to use.
64
+ function claudeConfigDir() {
65
+ const dir = process.env.CLAUDE_CONFIG_DIR?.trim();
66
+ return dir ? dir : null;
67
+ }
68
+ // CASTLE_CLAUDE_CREDENTIALS_PATH overrides the location so the QA battery can
69
+ // isolate from a developer's REAL ~/.claude login -- which, since this gates
70
+ // proxy-vs-direct routing, would otherwise flip every plain-claude scenario to
71
+ // "direct" on a logged-in machine. Mirrors the CASTLE_KEYS_PATH seam.
72
+ export function claudeCredentialsPath() {
73
+ const override = process.env.CASTLE_CLAUDE_CREDENTIALS_PATH;
74
+ if (override !== undefined)
75
+ return override;
76
+ const dir = claudeConfigDir();
77
+ return dir
78
+ ? path.join(dir, ".credentials.json")
79
+ : path.join(os.homedir(), ".claude", ".credentials.json");
80
+ }
58
81
  // KNOWN GAP (macOS): a false negative for most logged-in users. `claude /login`
59
82
  // stores credentials in the KEYCHAIN there, not in ~/.claude/.credentials.json,
60
83
  // so this returns false and the run stays on Castle's proxy even though the
61
84
  // user has a perfectly good subscription login the CLI would have used. Left
62
- // alone deliberately -- reading the Keychain (`security find-generic-password`)
63
- // changes who pays for a run, which is a product decision, not a cleanup. In a
64
- // Linux sandbox (the case that matters for BYO routing) the file IS
65
- // authoritative, so the gap doesn't bite.
85
+ // alone deliberately -- reading the Keychain changes who pays for a run, which
86
+ // is a product decision, not a cleanup. In a Linux sandbox (the case that
87
+ // matters for BYO routing) the file IS authoritative, so the gap doesn't bite.
66
88
  //
67
- // CASTLE_CLAUDE_CREDENTIALS_PATH overrides the location so the QA battery can
68
- // isolate from a developer's REAL ~/.claude login -- which, since this gates
69
- // proxy-vs-direct routing, would otherwise flip every plain-claude scenario to
70
- // "direct" on a logged-in machine. Mirrors the CASTLE_KEYS_PATH seam.
89
+ // `claude auth status --json` would close it: it reads the Keychain and reports
90
+ // `authMethod` ("claude.ai" for a real login, "oauth_token" for an env
91
+ // ANTHROPIC_AUTH_TOKEN -- so it means nothing unless Castle's pair is stripped
92
+ // first). It is a subprocess, and this is called per `claude` run and per
93
+ // account snapshot, so taking it costs a spawn on both.
71
94
  export function claudeHasSavedLogin() {
72
- const credPath = process.env.CASTLE_CLAUDE_CREDENTIALS_PATH ??
73
- path.join(os.homedir(), ".claude", ".credentials.json");
74
- return fs.existsSync(credPath);
95
+ return fs.existsSync(claudeCredentialsPath());
75
96
  }
76
97
  // cursor-agent rewrites ~/.config/cursor/auth.json on every successful run,
77
98
  // including Castle's own CURSOR_API_KEY runs -- so the file existing does NOT
@@ -149,12 +170,12 @@ function shellQuote(value) {
149
170
  export function anthropicKeyHelperCommand() {
150
171
  return `${shellQuote(process.execPath)} ${shellQuote(path.join(DIST_DIR, "anthropic-key-helper.js"))}`;
151
172
  }
152
- // Where the shell's inherited proxy pair goes when a credential of the user's
153
- // own displaces it. envForUserShell answers "whose credential" once, but
154
- // claudeShellEnvScript re-answers it per `claude` run and may need to put
155
- // Castle's routing BACK (the user deleted their key mid-session) -- which it
156
- // can only do if the values survived somewhere. Nothing reads these names by
157
- // accident, so stashing doesn't weaken the guarantee below.
173
+ // Where the shell's inherited Castle credential goes when one of the user's own
174
+ // displaces it. envForUserShell answers "whose credential" once, but the shims
175
+ // re-answer it per run and may need to put Castle's back (the user deleted their
176
+ // key, or signed out, mid-session) -- which they can only do if the values
177
+ // survived somewhere. Nothing reads these names by accident, so stashing doesn't
178
+ // weaken the guarantee below.
158
179
  const PROXY_STASH_PREFIX = "CASTLE_PTY_";
159
180
  // Env for the editor's PTY terminal. The container env the serve inherits
160
181
  // carries the llm-proxy pair, and Claude Code ranks ANTHROPIC_AUTH_TOKEN ABOVE
@@ -163,8 +184,8 @@ const PROXY_STASH_PREFIX = "CASTLE_PTY_";
163
184
  // ANTHROPIC_API_KEY or another auth source is set", their login unused and
164
185
  // their session billed to Castle.
165
186
  //
166
- // This is the shell's STARTING state only; the per-run answer is the shim's
167
- // (see installClaudeShim). It still matters on its own, because anything else
187
+ // This is the shell's STARTING state only; the per-run answer is the shims'
188
+ // (see installCliShims). It still matters on its own, because anything else
168
189
  // the user runs in that terminal -- a script that calls claude by absolute
169
190
  // path, an SDK program reading ANTHROPIC_API_KEY -- must not find Castle's
170
191
  // token sitting in the environment while the user has a credential of their own.
@@ -175,17 +196,26 @@ const PROXY_STASH_PREFIX = "CASTLE_PTY_";
175
196
  // person is there to answer it.
176
197
  export function envForUserShell(base) {
177
198
  const env = { ...base };
199
+ const stash = (name) => {
200
+ const inherited = env[name];
201
+ if (inherited !== undefined)
202
+ env[PROXY_STASH_PREFIX + name] = inherited;
203
+ delete env[name];
204
+ };
178
205
  const anthropic = resolveAnthropicAuth();
179
206
  if (anthropic.mode !== "proxy") {
180
- for (const name of ANTHROPIC_PROXY_ENV) {
181
- const inherited = env[name];
182
- if (inherited !== undefined)
183
- env[PROXY_STASH_PREFIX + name] = inherited;
184
- delete env[name];
185
- }
207
+ for (const name of ANTHROPIC_PROXY_ENV)
208
+ stash(name);
186
209
  if (anthropic.mode === "user-key")
187
210
  env.ANTHROPIC_API_KEY = anthropic.key;
188
211
  }
212
+ // The same withholding envForAgentSpawn does for a cursor run: Castle's key
213
+ // would let cursor-agent consider itself authenticated and never look at the
214
+ // user's own OAuth session, so their terminal would keep spending Castle's
215
+ // budget after they signed in. Cursor has no key of its own to put back --
216
+ // user-keys.json's CURSOR_API_KEY is described but not yet injected anywhere.
217
+ if (cursorHasUserLogin(os.homedir()))
218
+ stash("CURSOR_API_KEY");
189
219
  const openrouter = userKey("OPENROUTER_API_KEY");
190
220
  if (openrouter) {
191
221
  env.OPENROUTER_API_KEY = openrouter;
@@ -205,10 +235,10 @@ export function envForUserShell(base) {
205
235
  // still prints "claude.ai connectors are disabled...". Restarting claude, or
206
236
  // the panel, changed nothing -- only restarting the serve did.
207
237
  //
208
- // So the decision moves to a `claude` shim first on the terminal's PATH: it
209
- // resolves the credential at invocation time, fixes up the environment, and
210
- // execs the real binary. A login taken thirty seconds ago applies to the very
211
- // next run, in the same shell.
238
+ // So the decision moves to a shim first on the terminal's PATH -- one per CLI
239
+ // that has a credential to decide: it resolves at invocation time, fixes up the
240
+ // environment, and execs the real binary. A login taken thirty seconds ago
241
+ // applies to the very next run, in the same shell.
212
242
  //
213
243
  // Caveat: PATH ordering is not ours to guarantee. A login shell can reorder it
214
244
  // (macOS /etc/zprofile runs path_helper, which demotes an inherited entry below
@@ -224,15 +254,18 @@ function realpath(p) {
224
254
  return path.resolve(p);
225
255
  }
226
256
  }
227
- // The `claude` the shim should exec: the first executable one on `pathValue`
257
+ // The CLIs a shim is installed for. Both take a credential from the environment
258
+ // that Castle may be supplying, so both need the decision re-made per run.
259
+ export const SHIMMED_CLIS = ["claude", "cursor-agent"];
260
+ // The real binary the shim should exec: the first executable one on `pathValue`
228
261
  // that isn't the shim itself. Skipping by resolved directory (not by string) is
229
262
  // what keeps the shim from exec'ing itself forever.
230
- function findRealClaude(pathValue, shimDir) {
263
+ function findRealBin(pathValue, shimDir, name) {
231
264
  const shimReal = realpath(shimDir);
232
265
  for (const entry of (pathValue ?? "").split(path.delimiter)) {
233
266
  if (!entry || realpath(entry) === shimReal)
234
267
  continue;
235
- const candidate = path.join(entry, "claude");
268
+ const candidate = path.join(entry, name);
236
269
  try {
237
270
  fs.accessSync(candidate, fs.constants.X_OK);
238
271
  if (fs.statSync(candidate).isFile())
@@ -244,14 +277,30 @@ function findRealClaude(pathValue, shimDir) {
244
277
  }
245
278
  return null;
246
279
  }
280
+ // `claude /login` -- the slash command as an ARGUMENT, which Claude Code runs at
281
+ // startup. This run is about signing in, so it is given no credential of
282
+ // Castle's at all: measured, an inherited ANTHROPIC_AUTH_TOKEN outranks whatever
283
+ // the login stores, so the session that just signed in would still spend
284
+ // Castle's budget and still print "claude.ai connectors are disabled" -- the
285
+ // thing the user ran /login to stop. Stripped, the run opens "Not logged in",
286
+ // the login lands with nothing above it, and that same session is on the user's
287
+ // account.
288
+ //
289
+ // Only reachable for `claude X` typed as a command. A `/login` typed INSIDE a
290
+ // running claude cannot be helped by anything out here: its environment was
291
+ // fixed at exec and no one can change it from outside, so that session stays on
292
+ // whatever it started with and the NEXT run picks the login up.
293
+ function isLoginRun(args) {
294
+ return args.some((a) => a.trim() === "/login");
295
+ }
247
296
  // Shell statements the shim evals before exec'ing claude: the environment that
248
297
  // makes THIS run use the credential resolveAnthropicAuth picks right now.
249
298
  // Emitting `unset` rather than an empty value matters -- Claude Code treats an
250
299
  // empty ANTHROPIC_BASE_URL as configured and fails to reach anything.
251
- export function claudeShellEnvScript(env, shimDir) {
300
+ export function claudeShellEnvScript(env, args = []) {
252
301
  const lines = [];
253
302
  const auth = resolveAnthropicAuth();
254
- if (auth.mode === "proxy") {
303
+ if (auth.mode === "proxy" && !isLoginRun(args)) {
255
304
  for (const name of ANTHROPIC_PROXY_ENV) {
256
305
  const stashed = env[PROXY_STASH_PREFIX + name];
257
306
  if (stashed !== undefined && env[name] === undefined) {
@@ -262,55 +311,133 @@ export function claudeShellEnvScript(env, shimDir) {
262
311
  else {
263
312
  for (const name of ANTHROPIC_PROXY_ENV)
264
313
  lines.push(`unset ${name}`);
265
- if (auth.mode === "user-key") {
314
+ // Not on a login run: a key sitting in the environment is one more thing
315
+ // ranked above the login being made, and this run exists to make it.
316
+ if (auth.mode === "user-key" && !isLoginRun(args)) {
266
317
  lines.push(`ANTHROPIC_API_KEY=${shellQuote(auth.key)}; export ANTHROPIC_API_KEY`);
267
318
  }
268
319
  }
269
- const real = findRealClaude(env.PATH, shimDir);
270
- if (real)
271
- lines.push(`CASTLE_REAL_CLAUDE=${shellQuote(real)}`);
272
- return lines.length > 0 ? lines.join("\n") + "\n" : "";
320
+ return lines.join("\n");
273
321
  }
274
- // The baked CASTLE_REAL_CLAUDE is a fallback, not the answer: if the helper
275
- // runs, its own resolution (against the SHELL's PATH, which a login shell may
276
- // have rewritten) replaces it. It only survives when the helper failed to run
277
- // at all, and then it is the difference between the old static behavior and a
278
- // terminal where `claude` is suddenly missing.
279
- function shimScript(shimDir) {
322
+ // The cursor half. Simpler, because there is one credential and no proxy pair:
323
+ // Castle's CURSOR_API_KEY is either withheld (the user has their own OAuth
324
+ // session, which cursor-agent would otherwise never look at) or put back from
325
+ // the stash when they sign out again.
326
+ export function cursorShellEnvScript(env) {
327
+ if (cursorHasUserLogin(os.homedir()))
328
+ return "unset CURSOR_API_KEY";
329
+ const stashed = env[PROXY_STASH_PREFIX + "CURSOR_API_KEY"];
330
+ if (stashed !== undefined && env.CURSOR_API_KEY === undefined) {
331
+ return `CURSOR_API_KEY=${shellQuote(stashed)}; export CURSOR_API_KEY`;
332
+ }
333
+ return "";
334
+ }
335
+ export function shimEnvScript(cli, env, shimDir, args = []) {
336
+ const lines = cli === "cursor-agent"
337
+ ? cursorShellEnvScript(env)
338
+ : claudeShellEnvScript(env, args);
339
+ const real = findRealBin(env.PATH, shimDir, cli);
340
+ const all = [lines, real ? `CASTLE_REAL_BIN=${shellQuote(real)}` : ""].filter((l) => l !== "");
341
+ return all.length > 0 ? all.join("\n") + "\n" : "";
342
+ }
343
+ // The baked CASTLE_REAL_BIN is a fallback, not the answer: if the helper runs,
344
+ // its own resolution (against the SHELL's PATH, which a login shell may have
345
+ // rewritten) replaces it. It only survives when the helper failed to run at all,
346
+ // and then it is the difference between the old static behavior and a terminal
347
+ // where the CLI is suddenly missing.
348
+ //
349
+ // "$@" reaches the helper so it can see arguments the decision turns on --
350
+ // `claude /login` (see isLoginRun). The shell expands it into separate words
351
+ // inside the substitution, so nothing in it is re-parsed.
352
+ function shimScript(shimDir, cli) {
280
353
  const helper = [
281
354
  shellQuote(process.execPath),
282
- shellQuote(path.join(DIST_DIR, "claude-shim-env.js")),
355
+ shellQuote(path.join(DIST_DIR, "cli-shim-env.js")),
283
356
  shellQuote(shimDir),
357
+ shellQuote(cli),
284
358
  ].join(" ");
285
359
  return [
286
360
  "#!/bin/sh",
287
- "# Generated by `castle-web serve` -- see installClaudeShim in castle-web-cli.",
288
- `CASTLE_REAL_CLAUDE=${shellQuote(findRealClaude(process.env.PATH, shimDir) ?? "")}`,
289
- `eval "$(${helper})"`,
290
- 'if [ -z "$CASTLE_REAL_CLAUDE" ]; then',
291
- ' echo "castle-web: claude is not installed on this PATH" >&2',
361
+ "# Generated by `castle-web serve` -- see installCliShims in castle-web-cli.",
362
+ `CASTLE_REAL_BIN=${shellQuote(findRealBin(process.env.PATH, shimDir, cli) ?? "")}`,
363
+ `eval "$(${helper} "$@")"`,
364
+ 'if [ -z "$CASTLE_REAL_BIN" ]; then',
365
+ ` echo "castle-web: ${cli} is not installed on this PATH" >&2`,
292
366
  " exit 127",
293
367
  "fi",
294
- 'exec "$CASTLE_REAL_CLAUDE" "$@"',
368
+ 'exec "$CASTLE_REAL_BIN" "$@"',
295
369
  "",
296
370
  ].join("\n");
297
371
  }
372
+ // Claude Code's first-run onboarding asks for a login even when one is already
373
+ // stored. Measured against 2.1.220 through a real pty: with onboarding
374
+ // incomplete, a `.credentials.json` -- with or without a matching `oauthAccount`
375
+ // in `.claude.json` -- still lands on "Select login method", while the same
376
+ // credential with onboarding complete goes straight through. What normally
377
+ // carries a sandbox past that step is Castle's injected ANTHROPIC_AUTH_TOKEN, an
378
+ // env credential, which is exactly what this shim takes away the moment the user
379
+ // has one of their own. So a user who signs in from the editor BEFORE ever
380
+ // opening the terminal is asked by their first `claude` to sign in again, and
381
+ // pays a second OAuth round trip for a login they already completed.
382
+ //
383
+ // Marking onboarding done is what makes claude accept the stored login --
384
+ // `hasCompletedOnboarding` alone is enough, measured, so no version flag is
385
+ // written and there is nothing to drift. Kept narrow deliberately: only in a
386
+ // sandbox, only once the user actually has a credential of their own, only when
387
+ // onboarding has not already run. A developer's own machine is never touched,
388
+ // and neither is claude's first-run experience for anyone on Castle's account.
389
+ export function ensureClaudeOnboarded() {
390
+ if (!inCastleSandbox())
391
+ return;
392
+ if (resolveAnthropicAuth().mode === "proxy")
393
+ return;
394
+ const dir = claudeConfigDir();
395
+ const file = dir
396
+ ? path.join(dir, ".claude.json")
397
+ : path.join(os.homedir(), ".claude.json");
398
+ let config = {};
399
+ try {
400
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
401
+ // Not ours to repair: a file we can't read is one claude may still be able
402
+ // to, and replacing it wholesale would cost the user their project history.
403
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
404
+ return;
405
+ config = parsed;
406
+ }
407
+ catch {
408
+ /* no file yet -- the normal case in a sandbox nobody has run claude in */
409
+ }
410
+ if (config.hasCompletedOnboarding === true)
411
+ return;
412
+ config.hasCompletedOnboarding = true;
413
+ try {
414
+ fs.mkdirSync(path.dirname(file), { recursive: true });
415
+ const staged = `${file}.castle-staged`;
416
+ fs.writeFileSync(staged, JSON.stringify(config, null, 2) + "\n");
417
+ fs.renameSync(staged, file);
418
+ }
419
+ catch {
420
+ /* claude asks again; nothing else depends on this */
421
+ }
422
+ }
298
423
  // Returns the directory to put first on the terminal's PATH, or null when there
299
- // is no shim to install -- a failure here costs the per-run re-resolution, so it
424
+ // is none to install -- a failure here costs the per-run re-resolution, so it
300
425
  // degrades to envForUserShell's spawn-time answer rather than breaking the shell.
301
- export function installClaudeShim(deckDir) {
426
+ export function installCliShims(deckDir) {
302
427
  if (process.platform === "win32")
303
428
  return null;
304
429
  const dir = path.join(deckDir, ".castle", "shims");
305
430
  try {
306
431
  fs.mkdirSync(dir, { recursive: true });
307
- // Write-then-rename, because /bin/sh reads a script incrementally: a second
308
- // serve reinstalling over this deck while a claude is running through the
309
- // shim would otherwise pull the file out from under that sh mid-read.
310
- const staged = path.join(dir, "claude.staged");
311
- fs.writeFileSync(staged, shimScript(dir));
312
- fs.chmodSync(staged, 0o755);
313
- fs.renameSync(staged, path.join(dir, "claude"));
432
+ for (const cli of SHIMMED_CLIS) {
433
+ // Write-then-rename, because /bin/sh reads a script incrementally: a
434
+ // second serve reinstalling over this deck while a run is going through
435
+ // the shim would otherwise pull the file out from under that sh mid-read.
436
+ const staged = path.join(dir, `${cli}.staged`);
437
+ fs.writeFileSync(staged, shimScript(dir, cli));
438
+ fs.chmodSync(staged, 0o755);
439
+ fs.renameSync(staged, path.join(dir, cli));
440
+ }
314
441
  return dir;
315
442
  }
316
443
  catch {
@@ -0,0 +1,13 @@
1
+ // Printed for the editor terminal's shims to eval: the environment this
2
+ // particular run of this particular CLI should have, plus the real binary to
3
+ // exec (see installCliShims in byo-auth.ts for why the decision can't live in
4
+ // the shell's own environment).
5
+ //
6
+ // argv is `<shimDir> <cli> [the run's own arguments...]`.
7
+ import { ensureClaudeOnboarded, shimEnvScript } from "./byo-auth.js";
8
+ const [shimDir = "", cli = "", ...args] = process.argv.slice(2);
9
+ // Its own call rather than a side effect of building the script: this WRITES,
10
+ // and shimEnvScript is read-only by contract.
11
+ if (cli === "claude")
12
+ ensureClaudeOnboarded();
13
+ process.stdout.write(shimEnvScript(cli, process.env, shimDir, args));
package/dist/ide.js CHANGED
@@ -15,7 +15,7 @@ import headlessPkg from "@xterm/headless";
15
15
  import { SerializeAddon } from "@xterm/addon-serialize";
16
16
  import { WebSocketServer } from "ws";
17
17
  import { IMPORTS_DIR, importStatuses, updateImport } from "./imports.js";
18
- import { envForUserShell, installClaudeShim } from "./byo-auth.js";
18
+ import { envForUserShell, installCliShims } from "./byo-auth.js";
19
19
  const HeadlessTerminal = headlessPkg.Terminal;
20
20
  const DIST_DIR = path.dirname(fileURLToPath(import.meta.url));
21
21
  // The bundled shell app (vite build output). `/` serves its index.html and
@@ -651,7 +651,7 @@ export function createIdeServer(opts) {
651
651
  let session = null;
652
652
  function spawnSession() {
653
653
  const { command, args } = defaultShell();
654
- const shimDir = installClaudeShim(deckDir);
654
+ const shimDir = installCliShims(deckDir);
655
655
  const screen = new HeadlessTerminal({
656
656
  allowProposedApi: true,
657
657
  cols: INITIAL_COLS,
@@ -72,7 +72,7 @@ ${e}</tr>
72
72
  `}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${Wi(e,!0)}</code>`}br(e){return`<br>`}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=Gi(e);if(i===null)return r;e=i;let a=`<a href="`+e+`"`;return t&&(a+=` title="`+Wi(t)+`"`),a+=`>`+r+`</a>`,a}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=Gi(e);if(i===null)return Wi(n);e=i;let a=`<img src="${e}" alt="${Wi(n)}"`;return t&&(a+=` title="${Wi(t)}"`),a+=`>`,a}text(e){return`tokens`in e&&e.tokens?this.parser.parseInline(e.tokens):`escaped`in e&&e.escaped?e.text:Wi(e.text)}},ta=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return``+e}image({text:e}){return``+e}br(){return``}checkbox({raw:e}){return e}},na=class e{options;renderer;textRenderer;constructor(e){this.options=e||Ar,this.options.renderer=this.options.renderer||new ea,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new ta}static parse(t,n){return new e(n).parse(t)}static parseInline(t,n){return new e(n).parseInline(t)}parse(e){this.renderer.parser=this;let t=``;for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let e=r,n=this.options.extensions.renderers[e.type].call({parser:this},e);if(n!==!1||![`space`,`hr`,`heading`,`code`,`table`,`blockquote`,`list`,`html`,`def`,`paragraph`,`text`].includes(e.type)){t+=n||``;continue}}let i=r;switch(i.type){case`space`:t+=this.renderer.space(i);break;case`hr`:t+=this.renderer.hr(i);break;case`heading`:t+=this.renderer.heading(i);break;case`code`:t+=this.renderer.code(i);break;case`table`:t+=this.renderer.table(i);break;case`blockquote`:t+=this.renderer.blockquote(i);break;case`list`:t+=this.renderer.list(i);break;case`checkbox`:t+=this.renderer.checkbox(i);break;case`html`:t+=this.renderer.html(i);break;case`def`:t+=this.renderer.def(i);break;case`paragraph`:t+=this.renderer.paragraph(i);break;case`text`:t+=this.renderer.text(i);break;default:{let e=`Token with "`+i.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n=``;for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let e=this.options.extensions.renderers[i.type].call({parser:this},i);if(e!==!1||![`escape`,`html`,`link`,`image`,`strong`,`em`,`codespan`,`br`,`del`,`text`].includes(i.type)){n+=e||``;continue}}let a=i;switch(a.type){case`escape`:n+=t.text(a);break;case`html`:n+=t.html(a);break;case`link`:n+=t.link(a);break;case`image`:n+=t.image(a);break;case`checkbox`:n+=t.checkbox(a);break;case`strong`:n+=t.strong(a);break;case`em`:n+=t.em(a);break;case`codespan`:n+=t.codespan(a);break;case`br`:n+=t.br(a);break;case`del`:n+=t.del(a);break;case`text`:n+=t.text(a);break;default:{let e=`Token with "`+a.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return n}},ra=class{options;block;constructor(e){this.options=e||Ar}static passThroughHooks=new Set([`preprocess`,`postprocess`,`processAllTokens`,`emStrongMask`]);static passThroughHooksRespectAsync=new Set([`preprocess`,`postprocess`,`processAllTokens`]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?F.lex:F.lexInline}provideParser(e=this.block){return e?na.parse:na.parseInline}},ia=new class{defaults=kr();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=na;Renderer=ea;TextRenderer=ta;Lexer=F;Tokenizer=$i;Hooks=ra;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case`table`:{let e=r;for(let r of e.header)n=n.concat(this.walkTokens(r.tokens,t));for(let r of e.rows)for(let e of r)n=n.concat(this.walkTokens(e.tokens,t));break}case`list`:{let e=r;n=n.concat(this.walkTokens(e.items,t));break}default:{let e=r;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(r=>{let i=e[r].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{let n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw Error(`extension name required`);if(`renderer`in e){let n=t.renderers[e.name];n?t.renderers[e.name]=function(...t){let r=e.renderer.apply(this,t);return r===!1&&(r=n.apply(this,t)),r}:t.renderers[e.name]=e.renderer}if(`tokenizer`in e){if(!e.level||e.level!==`block`&&e.level!==`inline`)throw Error(`extension level must be 'block' or 'inline'`);let n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&(e.level===`block`?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:e.level===`inline`&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}`childTokens`in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)}),n.extensions=t),e.renderer){let t=this.defaults.renderer||new ea(this.defaults);for(let n in e.renderer){if(!(n in t))throw Error(`renderer '${n}' does not exist`);if([`options`,`parser`].includes(n))continue;let r=n,i=e.renderer[r],a=t[r];t[r]=(...e)=>{let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n||``}}n.renderer=t}if(e.tokenizer){let t=this.defaults.tokenizer||new $i(this.defaults);for(let n in e.tokenizer){if(!(n in t))throw Error(`tokenizer '${n}' does not exist`);if([`options`,`rules`,`lexer`].includes(n))continue;let r=n,i=e.tokenizer[r],a=t[r];t[r]=(...e)=>{let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){let t=this.defaults.hooks||new ra;for(let n in e.hooks){if(!(n in t))throw Error(`hook '${n}' does not exist`);if([`options`,`block`].includes(n))continue;let r=n,i=e.hooks[r],a=t[r];ra.passThroughHooks.has(n)?t[r]=e=>{if(this.defaults.async&&ra.passThroughHooksRespectAsync.has(n))return(async()=>{let n=await i.call(t,e);return a.call(t,n)})();let r=i.call(t,e);return a.call(t,r)}:t[r]=(...e)=>{if(this.defaults.async)return(async()=>{let n=await i.apply(t,e);return n===!1&&(n=await a.apply(t,e)),n})();let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){let t=this.defaults.walkTokens,r=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(r.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return F.lex(e,t??this.defaults)}parser(e,t){return na.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{let r={...n},i={...this.defaults,...r},a=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return a(Error(`marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.`));if(typeof t>`u`||t===null)return a(Error(`marked(): input parameter is undefined or null`));if(typeof t!=`string`)return a(Error(`marked(): input parameter is of type `+Object.prototype.toString.call(t)+`, string expected`));if(i.hooks&&(i.hooks.options=i,i.hooks.block=e),i.async)return(async()=>{let n=i.hooks?await i.hooks.preprocess(t):t,r=await(i.hooks?await i.hooks.provideLexer(e):e?F.lex:F.lexInline)(n,i),a=i.hooks?await i.hooks.processAllTokens(r):r;i.walkTokens&&await Promise.all(this.walkTokens(a,i.walkTokens));let o=await(i.hooks?await i.hooks.provideParser(e):e?na.parse:na.parseInline)(a,i);return i.hooks?await i.hooks.postprocess(o):o})().catch(a);try{i.hooks&&(t=i.hooks.preprocess(t));let n=(i.hooks?i.hooks.provideLexer(e):e?F.lex:F.lexInline)(t,i);i.hooks&&(n=i.hooks.processAllTokens(n)),i.walkTokens&&this.walkTokens(n,i.walkTokens);let r=(i.hooks?i.hooks.provideParser(e):e?na.parse:na.parseInline)(n,i);return i.hooks&&(r=i.hooks.postprocess(r)),r}catch(e){return a(e)}}}onError(e,t){return n=>{if(n.message+=`
73
73
  Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error occurred:</p><pre>`+Wi(n.message+``,!0)+`</pre>`;return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}};function I(e,t){return ia.parse(e,t)}I.options=I.setOptions=function(e){return ia.setOptions(e),I.defaults=ia.defaults,jr(I.defaults),I},I.getDefaults=kr,I.defaults=Ar,I.use=function(...e){return ia.use(...e),I.defaults=ia.defaults,jr(I.defaults),I},I.walkTokens=function(e,t){return ia.walkTokens(e,t)},I.parseInline=ia.parseInline,I.Parser=na,I.parser=na.parse,I.Renderer=ea,I.TextRenderer=ta,I.Lexer=F,I.lexer=F.lex,I.Tokenizer=$i,I.Hooks=ra,I.parse=I,I.options,I.setOptions,I.use,I.walkTokens,I.parseInline,na.parse,F.lex;var aa=o((e=>{var t=u(),n=Symbol.for(`react.element`),r=Symbol.for(`react.fragment`),i=Object.prototype.hasOwnProperty,a=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function s(e,t,r){var s,c={},l=null,u=null;for(s in r!==void 0&&(l=``+r),t.key!==void 0&&(l=``+t.key),t.ref!==void 0&&(u=t.ref),t)i.call(t,s)&&!o.hasOwnProperty(s)&&(c[s]=t[s]);if(e&&e.defaultProps)for(s in t=e.defaultProps,t)c[s]===void 0&&(c[s]=t[s]);return{$$typeof:n,type:e,key:l,ref:u,props:c,_owner:a.current}}e.Fragment=r,e.jsx=s,e.jsxs=s})),L=o(((e,t)=>{t.exports=aa()}))(),oa=/```ask[ \t]*\n([\s\S]*?)```/g;function sa(e){let t;try{t=JSON.parse(e)}catch{return null}if(!t||!Array.isArray(t.questions))return null;let n=[];return t.questions.forEach((e,t)=>{let r=e;if(!r||typeof r.q!=`string`||!Array.isArray(r.options))return;let i=r.options.filter(e=>typeof e==`string`&&e.trim()!==``);if(i.length===0)return;let a=typeof r.id==`string`&&r.id.trim()?r.id.trim():`q${t}`;n.push({id:a,q:r.q,options:i,multi:r.multi===!0})}),n.length===0?null:{questions:n}}function ca(e){let t=!1;if((e.split("```").length-1)%2==1){let n=e.lastIndexOf("```"),r=e.slice(n+3),i=r.indexOf(`
74
74
  `),a=(i===-1?r:r.slice(0,i)).trim();i===-1?a===``?e=e.slice(0,n):`ask`.startsWith(a)&&(e=e.slice(0,n),t=!0):a===`ask`&&(e=e.slice(0,n),t=!0)}let n=[],r=0,i;for(oa.lastIndex=0;(i=oa.exec(e))!==null;){let t=sa(i[1]);t&&(i.index>r&&n.push({kind:`md`,text:e.slice(r,i.index)}),n.push({kind:`ask`,spec:t}),r=i.index+i[0].length)}return r<e.length&&n.push({kind:`md`,text:e.slice(r)}),n.length===0&&!t&&n.push({kind:`md`,text:e}),t&&n.push({kind:`ask-pending`}),n}function la(e,t){let n=[];for(let r of e.questions){let e=(t[r.id]??[]).filter(e=>r.options.includes(e));e.length!==0&&n.push(`- ${r.q} \u2192 ${e.join(`, `)}`)}return n.length?`Here's what I picked:\n${n.join(`
75
- `)}`:``}var ua=`/__castle/agent/attachments/`,da={lightbulb:{w:352,d:`M96.06 454.35c.01 6.29 1.87 12.45 5.36 17.69l17.09 25.69a31.99 31.99 0 0 0 26.64 14.28h61.71a31.99 31.99 0 0 0 26.64-14.28l17.09-25.69a31.989 31.989 0 0 0 5.36-17.69l.04-38.35H96.01l.05 38.35zM0 176c0 44.37 16.45 84.85 43.56 115.78 16.52 18.85 42.36 58.23 52.21 91.45.04.26.07.52.11.78h160.24c.04-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45C335.55 260.85 352 220.37 352 176 352 78.61 272.91-.3 175.45 0 73.44.31 0 82.97 0 176zm176-80c-44.11 0-80 35.89-80 80 0 8.84-7.16 16-16 16s-16-7.16-16-16c0-61.76 50.24-112 112-112 8.84 0 16 7.16 16 16s-7.16 16-16 16z`},book:{w:448,d:`M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z`},hammer:{w:576,d:`M571.31 193.94l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31-28.9-28.9c5.63-21.31.36-44.9-16.35-61.61l-45.25-45.25c-62.48-62.48-163.79-62.48-226.28 0l90.51 45.25v18.75c0 16.97 6.74 33.25 18.75 45.25l49.14 49.14c16.71 16.71 40.3 21.98 61.61 16.35l28.9 28.9-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l90.51-90.51c6.23-6.24 6.23-16.37-.02-22.62zm-286.72-15.2c-3.7-3.7-6.84-7.79-9.85-11.95L19.64 404.96c-25.57 23.88-26.26 64.19-1.53 88.93s65.05 24.05 88.93-1.53l238.13-255.07c-3.96-2.91-7.9-5.87-11.44-9.41l-49.14-49.14z`},pencil:{w:512,d:`M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z`},gamepad:{w:640,d:`M480.07 96H160a160 160 0 1 0 114.24 272h91.52A160 160 0 1 0 480.07 96zM248 268a12 12 0 0 1-12 12h-52v52a12 12 0 0 1-12 12h-24a12 12 0 0 1-12-12v-52H84a12 12 0 0 1-12-12v-24a12 12 0 0 1 12-12h52v-52a12 12 0 0 1 12-12h24a12 12 0 0 1 12 12v52h52a12 12 0 0 1 12 12zm216 76a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm64-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40z`},check:{w:512,d:`M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z`},times:{w:352,d:`M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z`},stop:{w:448,d:`M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z`}};function fa({glyph:e}){return(0,L.jsx)(`svg`,{className:`avatar-icon`,viewBox:`0 0 ${e.w} 512`,fill:`currentColor`,"aria-hidden":`true`,children:(0,L.jsx)(`path`,{d:e.d})})}var pa={thinking:(0,L.jsx)(fa,{glyph:da.lightbulb}),reading:(0,L.jsx)(fa,{glyph:da.book}),building:(0,L.jsx)(fa,{glyph:da.hammer}),painting:(0,L.jsx)(fa,{glyph:da.pencil}),playing:(0,L.jsx)(fa,{glyph:da.gamepad})},ma={thinking:`Thinking`,reading:`Reading files`,building:`Editing logic`,painting:`Editing art`,playing:`Playtesting`},ha={thinking:`#FFC826`,reading:`#FFC826`,building:`#FFEB57`,painting:`#FFEB57`,playing:`#D3FC7E`};function ga(e){if(e.status===`done`)return{icon:(0,L.jsx)(fa,{glyph:da.check}),color:`#5AC54F`};if(e.status===`failed`)return{icon:(0,L.jsx)(fa,{glyph:da.times}),color:`#F5545D`};if(e.status===`interrupted`)return{icon:(0,L.jsx)(fa,{glyph:da.stop}),color:`#B4B4B4`};if(e.status===`blocked`)return{icon:(0,L.jsx)(fa,{glyph:da.stop}),color:`#F5A623`};let t=e.avatar&&pa[e.avatar]?e.avatar:`thinking`;return{icon:pa[t],color:ha[t]}}function _a(e){let t=Math.max(1,Math.round((e??0)/1e3));if(t<60)return`Thought for ${t}s`;let n=Math.floor(t/60),r=t%60;return r===0?`Thought for ${n}m`:`Thought for ${n}m ${r}s`}function va(e){try{return{__html:I.parse(e,{breaks:!0,async:!1})}}catch{return{__html:``}}}var ya=(0,L.jsx)(`svg`,{viewBox:`0 0 512 512`,width:12,height:12,"aria-hidden":`true`,children:(0,L.jsx)(`path`,{d:`M470.3 271.15 43.16 447.31a7.83 7.83 0 0 1-11.16-7V327a8 8 0 0 1 6.51-7.86l247.62-47c17.36-3.29 17.36-28.15 0-31.44l-247.63-47a8 8 0 0 1-6.5-7.85V72.59c0-5.74 5.88-10.26 11.16-8L470.3 241.76a16 16 0 0 1 0 29.39`,fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:32})}),ba=(0,L.jsx)(`svg`,{viewBox:`0 0 512 512`,width:12,height:12,"aria-hidden":`true`,children:(0,L.jsx)(`rect`,{x:128,y:128,width:256,height:256,rx:36,fill:`currentColor`})}),xa=(0,L.jsx)(`svg`,{viewBox:`0 0 24 24`,width:10,height:10,fill:`none`,stroke:`currentColor`,strokeWidth:2.4,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,className:`mode-caret`,children:(0,L.jsx)(`path`,{d:`M6 9l6 6 6-6`})}),Sa=`/__castle/ide/operator.png`,Ca=(0,L.jsx)(`svg`,{viewBox:`0 0 512 512`,width:20,height:20,"aria-hidden":`true`,children:(0,L.jsx)(`path`,{d:`M408 64H104a56.16 56.16 0 0 0-56 56v192a56.16 56.16 0 0 0 56 56h40v80l93.72-78.14a8 8 0 0 1 5.13-1.86H408a56.16 56.16 0 0 0 56-56V120a56.16 56.16 0 0 0-56-56z`,fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:32})}),wa=[{value:`claude`,label:`Claude`},{value:`cursor`,label:`Cursor`},{value:`smith`,label:`Smith`}],Ta=[{value:`opus`,label:`Opus`},{value:`sonnet`,label:`Sonnet`},{value:`fable`,label:`Fable`},{value:`openrouter`,label:`OpenRouter`}];function Ea(e,t){return e===`smith`||e===`claude`&&t===`openrouter`}function Da(e){if(!e||!e.trim())return null;let t=e.trim(),n=t.lastIndexOf(`/`);return n>=0?t.slice(n+1):t}function Oa(e,t,n){let r=wa.find(t=>t.value===e)?.label??e??`?`;if(e===`claude`){if(t===`openrouter`){let e=Da(n);return e?`${r} (${e})`:`${r} (OpenRouter)`}let e=Ta.find(e=>e.value===t)?.label??t;return e?`${r} (${e})`:r}if(e===`smith`){let e=Da(n);return e?`${r} (${e})`:r}return r}function ka(e){return`${Oa(e.router,e.routerClaudeModel,e.routerOpenrouterModel)} → ${Oa(e.tasks,e.tasksClaudeModel,e.tasksOpenrouterModel)}`}var Aa=`/__castle/agent/model-caps`,ja=[{value:`balanced`,label:`Balanced`},{value:`nitro`,label:`Nitro`},{value:`exacto`,label:`Exacto`},{value:`floor`,label:`Floor`}],Ma=[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],Na={none:`None`,minimal:`Minimal`,low:`Low`,medium:`Medium`,high:`High`,xhigh:`XHigh`,max:`Max`};function Pa(e){let t=e?.reasoningEfforts;if(!t||t.length===0)return null;let n=new Set(t);return Ma.filter(e=>n.has(e)).map(e=>({value:e,label:Na[e]??e}))}var Fa={openai:`OpenAI`,azure:`Azure`,anthropic:`Anthropic`,google:`Google`,"google-vertex":`Vertex`,deepinfra:`DeepInfra`,fireworks:`Fireworks`,together:`Together`,groq:`Groq`,cerebras:`Cerebras`,baseten:`Baseten`},Ia={flex:`Flex`,priority:`Priority`,standard:`Standard`,eu:`EU`};function La(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function Ra(e){let[t,n]=e.split(`/`),r=Fa[t]??La(t);return n?`${r} ${Ia[n]??La(n)}`:r}function za(e){let t=e?.providerTiers;return!t||t.length<2?null:[{value:``,label:`Auto`},...t.map(e=>({value:e,label:Ra(e)}))]}function Ba(e,t,n){let r=e===`router`,i=r?`routerClaudeModel`:`tasksClaudeModel`,a=[{type:`enum`,key:e,label:r?`Operator`:`Tasks`,options:wa},{type:`enum`,key:i,label:`Model`,options:Ta,showWhen:t=>t[e]===`claude`},{type:`text`,key:r?`routerOpenrouterModel`:`tasksOpenrouterModel`,label:`OpenRouter model`,placeholder:r?`openai/gpt-5.6-sol`:`openai/gpt-5.6-terra`,showWhen:t=>Ea(t[e],t[i])}];if(t[e]===`smith`){let e=Pa(n);e&&a.push({type:`select`,key:r?`routerReasoningEffort`:`tasksReasoningEffort`,label:`Reasoning`,options:e}),a.push({type:`select`,key:r?`routerRouting`:`tasksRouting`,label:`Routing`,options:ja});let t=za(n);t&&a.push({type:`select`,key:r?`routerProviderTier`:`tasksProviderTier`,label:`Provider`,options:t})}return a}function Va(e){let{label:t,placeholder:n,value:r,warning:i,onCommit:a}=e,[o,s]=g.useState(r);g.useEffect(()=>s(r),[r]);let c=()=>{let e=o.trim();e&&e!==r?a(e):s(r)},l=e=>{s(e),a(e)};return(0,L.jsxs)(`div`,{className:`settings-row settings-row-stack`,children:[(0,L.jsxs)(`div`,{className:`settings-row-main`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:t}),(0,L.jsx)(`input`,{type:`text`,className:`settings-text${i?` settings-text-warn`:``}`,value:o,placeholder:n,onChange:e=>s(e.target.value),onBlur:c,onKeyDown:e=>{e.key===`Enter`&&(c(),e.target.blur())}})]}),i?(0,L.jsxs)(`div`,{className:`settings-warning`,children:[`⚠ `,i.message,i.suggestion?(0,L.jsxs)(L.Fragment,{children:[` `,`Did you mean`,` `,(0,L.jsx)(`button`,{type:`button`,className:`settings-warning-suggest`,onMouseDown:e=>{e.preventDefault(),l(i.suggestion)},children:i.suggestion}),`?`]}):null]}):null]})}function Ha(e,t,n){let r=e?.[t];if(!(!r||!n||r.model!==n))return{message:r.message,suggestion:r.suggestion}}function Ua(e){return!e||e.limitMicros===null||e.limitMicros<=0?null:Math.min(1,e.usedMicros/e.limitMicros)}function Wa(e){let t=Ua(e);return t===null?``:e?.blocked?` usage-blocked`:t>=.8?` usage-warn`:``}function Ga(e){let t=Ua(e.usage);if(t===null)return null;let n=e.usage.resetAtMs?new Date(e.usage.resetAtMs).toLocaleTimeString([],{hour:`numeric`,minute:`2-digit`}):``;return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`settings-row`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:`Daily AI usage`}),(0,L.jsx)(`span`,{className:`settings-usage-text`,children:e.usage.blocked?`Limit reached`:`${Math.round(t*100)}%${n?` \u00b7 resets ${n}`:``}`})]}),(0,L.jsx)(`div`,{className:`settings-usage-bar`,children:(0,L.jsx)(`div`,{className:`settings-usage-fill`+(e.usage.blocked?` blocked`:``),style:{width:`${t*100}%`}})})]})}function Ka(e){return(0,L.jsx)(`button`,{type:`button`,className:`settings-account-open`,onClick:e.onOpen,children:e.anyStored?`Manage your account`:`Use your own account`})}function qa(e){let{login:t}=e,[n,r]=g.useState(``),i=()=>{n.trim()&&e.onSubmitCode(n.trim())};return(0,L.jsxs)(L.Fragment,{children:[t.url?(0,L.jsxs)(`div`,{className:`castle-key-login`,children:[(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Open this link to sign in, then come back here.`}),(0,L.jsx)(`a`,{className:`castle-key-url`,href:t.url,target:`_blank`,rel:`noreferrer noopener`,children:t.url})]}):(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Starting sign-in…`}),t.phase===`awaiting-code`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Paste the code the browser shows you:`}),(0,L.jsx)(`input`,{className:`castle-key-input`,autoFocus:!0,spellCheck:!1,autoComplete:`off`,value:n,placeholder:`code`,onChange:e=>r(e.target.value),onKeyDown:e=>{e.key===`Enter`&&i()}}),t.message?(0,L.jsx)(`div`,{className:`castle-key-error`,children:t.message}):null]}):null,t.phase===`verifying`?(0,L.jsx)(`div`,{className:`castle-key-stored`,children:`Finishing sign-in…`}):null,t.phase===`error`?(0,L.jsx)(`div`,{className:`castle-key-error`,children:t.message}):null,(0,L.jsxs)(`div`,{className:`castle-modal-actions`,children:[(0,L.jsx)(`button`,{type:`button`,onClick:e.onCancel,children:t.phase===`error`?`Close`:`Cancel`}),t.phase===`awaiting-code`?(0,L.jsx)(`button`,{type:`button`,onClick:i,disabled:!n.trim(),children:`Submit`}):null]})]})}function Ja(e){let t=e.accounts.providers,n=e.accounts.login,[r,i]=g.useState(()=>(t.find(e=>e.key?.present||e.login?.loggedIn)??t[0])?.id??``),[a,o]=g.useState(``),[s,c]=g.useState(null),l=(n?t.find(e=>e.login?.provider===n.provider):null)??t.find(e=>e.id===r)??t[0]??null,u=g.useRef(e.onClose);u.current=e.onClose;let d=n!==null;if(g.useEffect(()=>{let e=e=>{e.key===`Escape`&&!d&&u.current()};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[d]),!l)return null;let f=!!l.login?.loggedIn,p=!!l.key?.present,m=f||p,h=()=>{let t=a.trim();if(t){if(t.length>500){c(`That key is too long.`);return}if([...t].some(e=>{let t=e.codePointAt(0)??0;return t<32||t===127})){c(`That key contains invalid characters.`);return}e.onSave(l.id,t),e.onClose()}};return(0,Qn.createPortal)((0,L.jsx)(`div`,{className:`castle-modal-scrim`,onMouseDown:n?void 0:e.onClose,children:(0,L.jsxs)(`div`,{className:`castle-modal`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`div`,{className:`castle-key-heading`,children:n?`Sign in to ${l.label}`:`Your account`}),n?null:(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Run the operator on your own account and bypass Castle's daily limit.`}),t.length>1&&!n?(0,L.jsx)(`div`,{className:`castle-key-tabs`,children:t.map(e=>(0,L.jsx)(`button`,{type:`button`,className:`castle-key-tab`+(e.id===l.id?` active`:``),onClick:()=>{i(e.id),o(``),c(null)},children:e.label},e.id))}):null,n?(0,L.jsx)(qa,{login:n,onSubmitCode:e.onSubmitCode,onCancel:e.onCancelLogin}):(0,L.jsxs)(L.Fragment,{children:[m?(0,L.jsxs)(L.Fragment,{children:[f?(0,L.jsxs)(`div`,{className:`castle-key-row`,children:[(0,L.jsxs)(`span`,{children:[`Signed in with your `,l.label,` account.`]}),(0,L.jsx)(`button`,{type:`button`,onClick:()=>{e.onLogout(l.id),e.onClose()},children:`Sign out`})]}):null,p?(0,L.jsxs)(`div`,{className:`castle-key-row`,children:[(0,L.jsxs)(`span`,{children:[`API key saved (`,l.key?.hint,`).`]}),(0,L.jsx)(`button`,{type:`button`,onClick:()=>{e.onRemove(l.id),e.onClose()},children:`Remove`})]}):null]}):(0,L.jsxs)(L.Fragment,{children:[l.login?(0,L.jsxs)(`button`,{type:`button`,className:`castle-key-signin`,onClick:()=>e.onStartLogin(l.id),children:[`Sign in with your `,l.label,` account`]}):null,l.login&&l.key?(0,L.jsx)(`div`,{className:`castle-key-or`,children:`or`}):null,l.key?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`castle-key-field-label`,children:`Add API key`}),(0,L.jsx)(`input`,{type:`password`,className:`castle-key-input`,autoFocus:!0,spellCheck:!1,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,value:a,placeholder:l.key.placeholder,onChange:e=>{o(e.target.value),c(null)},onKeyDown:e=>{e.key===`Enter`&&h()}}),s?(0,L.jsx)(`div`,{className:`castle-key-error`,children:s}):null]}):null]}),(0,L.jsxs)(`div`,{className:`castle-modal-actions`,children:[(0,L.jsx)(`button`,{type:`button`,onClick:e.onClose,children:`Cancel`}),!m&&l.key?(0,L.jsx)(`button`,{type:`button`,onClick:h,disabled:!a.trim(),children:`Save`}):null]})]})]})}),document.body)}function Ya(e){let{settings:t,onSetSetting:n,onClose:r}=e,i=Ua(e.usage)!==null,a=e.accounts.providers.some(e=>e.key?.present||e.login?.loggedIn),o=e.accounts.providers.length>0&&(i||a),s=g.useRef(null),[c,l]=g.useState({}),u=t.routerOpenrouterModel?.trim()??``,d=t.tasksOpenrouterModel?.trim()??``,f=t.router===`smith`,p=t.tasks===`smith`;g.useEffect(()=>{let e=new Set;f&&u&&e.add(u),p&&d&&e.add(d);let t=!1;for(let n of e)fetch(`${Aa}?model=${encodeURIComponent(n)}`).then(e=>e.ok?e.json():null).then(e=>{!t&&e&&l(t=>({...t,[n]:e}))}).catch(()=>{});return()=>{t=!0}},[f,u,p,d]);let m=[Ba(`router`,t,c[u]),Ba(`tasks`,t,c[d])];return g.useEffect(()=>{let e=e=>{s.current&&!s.current.contains(e.target)&&r()},t=e=>{e.key===`Escape`&&r()};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[r]),(0,L.jsxs)(`div`,{className:`settings-popover`,ref:s,onMouseDown:e=>e.stopPropagation(),children:[i||o?(0,L.jsxs)(`div`,{className:`settings-group`,children:[i&&e.usage?(0,L.jsx)(Ga,{usage:e.usage}):null,o?(0,L.jsx)(Ka,{anyStored:a,onOpen:e.onOpenKeys}):null]}):null,m.map((r,i)=>(0,L.jsx)(`div`,{className:`settings-group`,children:r.filter(e=>!e.showWhen||e.showWhen(t)).map(r=>{if(r.type===`text`)return(0,L.jsx)(Va,{label:r.label,placeholder:r.placeholder,value:t[r.key]??``,warning:Ha(e.warnings,r.key,t[r.key]),onCommit:e=>n(r.key,e)},r.key);if(r.type===`select`)return(0,L.jsxs)(`div`,{className:`settings-row`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:r.label}),(0,L.jsx)(`select`,{className:`settings-select`,value:t[r.key]??``,onChange:e=>n(r.key,e.target.value),children:r.options.map(e=>(0,L.jsx)(`option`,{value:e.value,children:e.label},e.value))})]},r.key);let i=t[r.key];return(0,L.jsxs)(`div`,{className:`settings-row`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:r.label}),(0,L.jsx)(`div`,{className:`settings-seg`,children:r.options.map(e=>(0,L.jsx)(`button`,{type:`button`,tabIndex:-1,className:`settings-opt`+(i===e.value?` active`:``),onClick:()=>n(r.key,e.value),children:e.label},e.value))})]},r.key)})},i))]})}function Xa(e){let{spec:t,interactive:n,answers:r,onSubmit:i}=e,[a,o]=g.useState({}),s=n?a:r??{},c=(e,t,r)=>{n&&o(n=>{let i=n[e]??[];if(r){let r=i.includes(t)?i.filter(e=>e!==t):[...i,t];return{...n,[e]:r}}return{...n,[e]:i[0]===t?[]:[t]}})};return(0,L.jsxs)(`div`,{className:`picker${n?``:` picker-locked`}`,children:[t.questions.map(e=>(0,L.jsxs)(`fieldset`,{className:`picker-q`,disabled:!n,children:[(0,L.jsx)(`legend`,{className:`picker-q-label`,children:e.q}),(0,L.jsx)(`div`,{className:`picker-options`,children:e.options.map(t=>{let r=(s[e.id]??[]).includes(t);return(0,L.jsxs)(`label`,{className:`picker-option${r?` is-checked`:``}`,children:[(0,L.jsx)(`input`,{type:e.multi?`checkbox`:`radio`,name:e.id,checked:r,disabled:!n,onChange:()=>c(e.id,t,e.multi)}),(0,L.jsx)(`span`,{children:t})]},t)})})]},e.id)),n?(0,L.jsx)(`div`,{className:`picker-actions`,children:(0,L.jsx)(`button`,{className:`picker-submit`,type:`button`,onClick:()=>{let e=la(t,a);e&&i(a,e)},children:`Submit`})}):null]})}function Za(){return(0,L.jsxs)(`div`,{className:`picker picker-skeleton`,"aria-hidden":`true`,children:[(0,L.jsx)(`span`,{className:`picker-skeleton-hint`,children:`preparing options…`}),(0,L.jsxs)(`div`,{className:`picker-q`,children:[(0,L.jsx)(`div`,{className:`picker-skeleton-line picker-skeleton-label`}),(0,L.jsxs)(`div`,{className:`picker-options`,children:[(0,L.jsx)(`span`,{className:`picker-skeleton-chip`,style:{width:84}}),(0,L.jsx)(`span`,{className:`picker-skeleton-chip`,style:{width:116}}),(0,L.jsx)(`span`,{className:`picker-skeleton-chip`,style:{width:72}})]})]})]})}function Qa(e){let t=/^\[Editing (.+)\]$/,n=/^\[Reading (.+)\]$/,r=new Set;for(let n of e){let e=t.exec(n.trim());if(e)for(let t of e[1].split(`, `))r.add(t)}let i=[];for(let t of e){let e=n.exec(t.trim());if(e){let t=e[1].split(`, `).filter(e=>!r.has(e));if(t.length===0)continue;i.push(`[Reading ${t.join(`, `)}]`);continue}i.push(t)}return i}function $a(e){let t=/^\[([A-Za-z]+)\s+(.+)\]$/,n=[];for(let r of e){let e=t.exec(r.trim());if(e){let r=n.length?t.exec(n[n.length-1].trim()):null;if(r&&r[1]===e[1]){r[2].split(`, `).includes(e[2])||(n[n.length-1]=`[${e[1]} ${r[2]}, ${e[2]}]`);continue}}n.push(r)}return n}function eo(e){return e.detail?(0,L.jsxs)(`details`,{className:`msg-error-detail`,children:[(0,L.jsx)(`summary`,{children:`Details (full text in the browser console)`}),(0,L.jsx)(`pre`,{children:e.detail})]}):null}function to(e){let t=g.useRef(null);return g.useLayoutEffect(()=>{let e=t.current;e&&(e.scrollTop=e.scrollHeight)},[e.lines]),(0,L.jsx)(`div`,{className:`task-feed`,ref:t,onClick:e=>e.stopPropagation(),children:$a(Qa(e.lines)).map((e,t)=>{let n=/^\[(.+)\]$/.exec(e.trim());return n?(0,L.jsx)(`div`,{className:`task-feed-tool`,children:n[1]},t):(0,L.jsx)(`div`,{className:`task-feed-msg`,dangerouslySetInnerHTML:va(e)},t)})})}function no(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/60),r=t%60;return n>0?`${n}m ${r}s`:`${r}s`}function ro(e){let{task:t,onAck:n}=e,r=e.onToggle!==void 0,[i,a]=g.useState(!1),o=r?e.open===!0:i,s=()=>{r?e.onToggle?.():a(e=>!e)},[c,l]=g.useState(()=>Date.now());g.useEffect(()=>{if(t.status!==`running`)return;let e=setInterval(()=>l(Date.now()),1e3);return()=>clearInterval(e)},[t.status]);let u=t.startedAt?Date.parse(t.startedAt):null,d=t.finishedAt?Date.parse(t.finishedAt):null,f=Er.includes(t.status),p=t.status===`done`?100:f?t.progress:Math.min(t.progress,95),m=t.notes.trim()||(t.status===`failed`?t.errorCopy?.trim():void 0)||t.resultSummary?.trim()||``,h=ga(t),_=t.status===`running`?t.phase?.trim()||ma[t.avatar??``]||`Working`:t.status===`waiting`?`Queued`:t.status===`blocked`?`Blocked`:t.status===`done`?`Done`:t.status===`failed`?`Failed`:t.status===`interrupted`?`Interrupted`:t.status;return(0,L.jsx)(`div`,{className:`task${o?` open`:``}`,onClick:s,children:(0,L.jsxs)(`div`,{className:`task-row`,children:[(0,L.jsx)(`div`,{className:`pie`,style:{background:`conic-gradient(#fff ${p*3.6}deg, #333 0deg)`},children:(0,L.jsx)(`div`,{className:`avatar`,style:{background:h.color},children:(0,L.jsx)(`span`,{className:`avatar-icon-wrap`,"aria-hidden":`true`,children:h.icon})})}),(0,L.jsxs)(`div`,{className:`task-meta`,children:[(0,L.jsxs)(`div`,{className:`task-head`,children:[(0,L.jsxs)(`div`,{className:`task-text`,children:[(0,L.jsxs)(`div`,{className:`task-name`,children:[(0,L.jsx)(`span`,{className:`tn`,children:t.title}),`: `,_]}),(0,L.jsx)(`div`,{className:`task-sub`,children:t.status===`running`&&u!=null?no(c-u):f&&u!=null&&d!=null?(0,L.jsxs)(L.Fragment,{children:[`Worked for `,no(d-u)]}):null})]}),f?(0,L.jsx)(`button`,{className:`task-dismiss`,type:`button`,onClick:e=>{e.stopPropagation(),n(t.id,!1)},children:`Dismiss`}):null]}),(0,L.jsxs)(`div`,{className:`task-body`,children:[o&&t.status===`running`&&e.feed&&e.feed.length>0?(0,L.jsx)(to,{lines:e.feed}):null,o&&t.status!==`running`&&m?(0,L.jsx)(`div`,{className:`task-notes`,dangerouslySetInnerHTML:va(m)}):null,o&&t.status===`failed`?(0,L.jsx)(eo,{detail:t.errorDetail}):null,o?(0,L.jsx)(io,{frames:t.playtestFrames}):null]})]})]})})}function io(e){let t=e.frames??[];return t.length===0?null:(0,L.jsxs)(`div`,{className:`task-playtest-frames`,children:[(0,L.jsxs)(`div`,{className:`task-playtest-frames-label`,children:[`Playtest frames (`,t.length,`)`]}),(0,L.jsx)(`div`,{className:`task-playtest-frames-row`,children:t.map(e=>(0,L.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),children:(0,L.jsx)(`img`,{className:`task-playtest-frame`,src:e,alt:`playtest frame`})},e))})]})}function ao(e){return e.filter(e=>!(e.acknowledged&&Er.includes(e.status)))}function oo(e){let t=g.useRef(null),n=g.useRef(!0),r=g.useRef(0),[i,a]=g.useState(!1),o=ao(e.tasks);g.useLayoutEffect(()=>{let e=t.current;e&&n.current&&(e.scrollTop=e.scrollHeight)},[e.tasks]),g.useEffect(()=>()=>window.clearTimeout(r.current),[]);let s=()=>{let e=t.current;e&&(n.current=e.scrollHeight-e.scrollTop-e.clientHeight<24,a(!0),window.clearTimeout(r.current),r.current=window.setTimeout(()=>a(!1),900))};if(o.length===0)return null;let c=o.filter(e=>Er.includes(e.status));return(0,L.jsxs)(`div`,{id:`task-board`,className:`task-stack${i?` scrolling`:``}`,ref:t,onScroll:s,children:[(0,L.jsxs)(`div`,{className:`task-board-header`,children:[(0,L.jsxs)(`div`,{className:`task-board-heading`,children:[(0,L.jsx)(`span`,{className:`task-board-title`,children:`Tasks`}),(0,L.jsxs)(`span`,{className:`task-board-status`,children:[c.length,`/`,o.length,` completed`]})]}),c.length>0?(0,L.jsx)(`button`,{type:`button`,className:`task-clear-completed`,onClick:()=>{for(let t of c)e.onAck(t.id,!1)},children:`Clear completed`}):null]}),o.map(t=>(0,L.jsx)(ro,{task:t,feed:e.feeds[t.id],onAck:e.onAck},t.id))]})}function so(e){let{msg:t,onPickerSubmit:n,fading:r,interactive:i=!1}=e,a=r?` fading`:``;if(t.role===`log`)return(0,L.jsx)(`div`,{className:`msg toolline`,children:t.text});if(t.role===`user`)return(0,L.jsxs)(`div`,{className:`msg user`+a,children:[(t.attachments??[]).map(e=>(0,L.jsx)(`img`,{className:`msg-image`,src:`${ua}${e}`,alt:``},e)),t.text?(0,L.jsx)(`span`,{children:t.text}):null]});let o=t.status===`streaming`,s=ca(t.text),c=s.some(e=>e.kind===`ask`||e.kind===`ask-pending`||e.kind===`md`&&e.text.trim()!==``);if(!o&&!c)return null;let l=!o&&!t.pickerAnswers&&i,u=-1;s.forEach((e,t)=>{e.kind===`md`&&e.text.trim()!==``&&(u=t)});let d=s.some(e=>e.kind===`ask`||e.kind===`ask-pending`),f=o&&u===-1&&!d,p=!!(t.thinking&&t.thinking.trim());return(0,L.jsxs)(`div`,{className:`assistant-turn`+a,children:[s.map((e,r)=>{if(e.kind===`ask-pending`)return(0,L.jsx)(Za,{},r);if(e.kind===`ask`)return(0,L.jsx)(Xa,{spec:e.spec,interactive:l,answers:t.pickerAnswers,onSubmit:(e,r)=>n(t,e,r)},r);if(!e.text.trim())return null;let i=[`msg`,`assistant`,`md`];return o&&r===u&&i.push(`streaming`),t.status===`error`&&i.push(`errbubble`),(0,L.jsx)(`div`,{className:i.join(` `),dangerouslySetInnerHTML:va(e.text)},r)}),p?(0,L.jsxs)(`details`,{className:`msg-thinking`,children:[(0,L.jsxs)(`summary`,{"aria-label":t.activity??`Thinking`,children:[(0,L.jsx)(`span`,{className:`thinking-caret`,"aria-hidden":`true`}),f?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`span`,{className:`thinking-dots`,"aria-hidden":`true`,children:[(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{})]}),(0,L.jsx)(`span`,{className:`thinking-label`,children:t.activity??`Thinking`})]}):(0,L.jsx)(`span`,{className:`thinking-label`,children:_a(t.thinkingMs)})]}),(0,L.jsx)(`div`,{className:`msg-thinking-body`,dangerouslySetInnerHTML:va(t.thinking??``)})]}):f?(0,L.jsxs)(`div`,{className:`msg-thinking`,"aria-label":t.activity??`thinking`,children:[(0,L.jsxs)(`span`,{className:`thinking-dots`,"aria-hidden":`true`,children:[(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{})]}),t.activity?(0,L.jsx)(`span`,{className:`thinking-label`,children:t.activity}):null]}):o&&t.activity?(0,L.jsxs)(`div`,{className:`msg-activity`,children:[t.activity,`...`]}):null,o?null:(0,L.jsx)(eo,{detail:t.errorDetail}),t.interrupted?(0,L.jsx)(`div`,{className:`msg-interrupted`,children:`interrupted by your next message`}):null]})}function co(e){let t=g.useRef(null),n=g.useRef(null),r=g.useRef(0),i=g.useRef(!0),a=g.useRef(0),[o,s]=g.useState(!1),c=g.useCallback(()=>{let e=t.current;e&&(e.scrollHeight-e.clientHeight-e.scrollTop<=1||(a.current=typeof performance<`u`?performance.now():Date.now(),e.scrollTop=e.scrollHeight))},[]),l=g.useCallback(()=>{c();let e=t.current;e&&e.clientHeight>0&&s(!0)},[c]);g.useLayoutEffect(()=>{if(!i.current)return;l();let e=requestAnimationFrame(l),t=window.setTimeout(l,250),n=window.setTimeout(()=>s(!0),500);return()=>{cancelAnimationFrame(e),clearTimeout(t),clearTimeout(n)}},[e.messages,l]),g.useEffect(()=>{let e=t.current;if(!e)return;let a=new ResizeObserver(()=>{i.current?l():e.scrollTop=e.scrollHeight-e.clientHeight-r.current});return a.observe(e),n.current&&a.observe(n.current,{box:`border-box`}),()=>a.disconnect()},[l]);let u=()=>{let e=t.current;e&&((typeof performance<`u`?performance.now():Date.now())-a.current<200||(r.current=e.scrollHeight-e.scrollTop-e.clientHeight,i.current=r.current<48))},d=go(e.messages);return(0,L.jsx)(`div`,{id:`chat-messages`,className:`chat-scroll`,ref:t,onScroll:u,children:(0,L.jsxs)(`div`,{className:`chat-thread`+(o?` ready`:``),ref:n,children:[e.messages.length===0?(0,L.jsx)(`div`,{id:`chat-empty`,children:`Tell the agent what you want to make.`}):null,e.messages.map(t=>(0,L.jsx)(so,{msg:t,interactive:t.id===d,onPickerSubmit:e.onPickerSubmit},t.id))]})})}var lo=550,uo=4;function fo(e){let t=1500+e.trim().length/18*1e3;return Math.min(12e3,Math.max(2500,t))}function po(){return typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}function mo(e){return e.role===`user`?(e.text??``).trim()!==``||(e.attachments?.length??0)>0:e.role===`assistant`?e.status===`streaming`?!0:ca(e.text).some(e=>e.kind===`ask`||e.kind===`ask-pending`||e.kind===`md`&&e.text.trim()!==``):!1}function ho(e){return e.role!==`assistant`||e.pickerAnswers?!1:ca(e.text).some(e=>e.kind===`ask`)}function go(e){for(let t=e.length-1;t>=0;t--)if(ho(e[t]))return e[t].id;return null}function _o(e,t){let n=e.map((e,t)=>({msg:e,idx:t})).filter(e=>mo(e.msg)),r=n.filter(e=>e.idx>=t),i=new Set(r.slice(-uo).map(e=>e.idx));return n.filter(e=>i.has(e.idx)||ho(e.msg))}function vo(e){let{messages:t,running:n,composerActive:r,booted:i,onPickerSubmit:a}=e,o=g.useRef(null),s=g.useRef(null);s.current===null&&i&&(s.current=t.length);let c=s.current??t.length,[l,u]=g.useState(!1),[d,f]=g.useState(()=>new Set),[p,m]=g.useState(()=>new Set),h=g.useRef(new Map),_=_o(t,c),v=_.filter(e=>ho(e.msg)||!p.has(e.msg.id)),y=l||r||n,b=g.useCallback(e=>{if(po()){h.current.delete(e),m(t=>new Set(t).add(e));return}f(t=>new Set(t).add(e)),h.current.set(e,setTimeout(()=>{h.current.delete(e),m(t=>new Set(t).add(e)),f(t=>{let n=new Set(t);return n.delete(e),n})},lo))},[]),x=t.length-1,S=_.map(e=>e.msg.id).join(`,`),C=_.filter(e=>e.msg.role===`assistant`?!(e.idx===x&&e.msg.status===`streaming`):!0).map(e=>e.msg.id).join(`,`),w=_.filter(e=>ho(e.msg)).map(e=>e.msg.id).join(`,`);g.useEffect(()=>{let e=_o(t,c),n=new Set(e.map(e=>e.msg.id));for(let e of[...h.current.keys()])n.has(e)||(clearTimeout(h.current.get(e)),h.current.delete(e));if(y){for(let e of h.current.values())clearTimeout(e);h.current.clear(),f(e=>e.size?new Set:e);return}let r=t.length-1;for(let t of e)ho(t.msg)||p.has(t.msg.id)||d.has(t.msg.id)||h.current.has(t.msg.id)||(t.msg.role!==`assistant`||!(t.idx===r&&t.msg.status===`streaming`))&&h.current.set(t.msg.id,setTimeout(()=>b(t.msg.id),fo(t.msg.text??``)))},[S,C,w,y,p,d,n,b]),g.useEffect(()=>()=>{for(let e of h.current.values())clearTimeout(e);h.current.clear()},[]),g.useEffect(()=>{let e=o.current;e&&(e.scrollTop=e.scrollHeight)},[t.length,n,v.length]);let T=go(t);return(0,L.jsx)(`div`,{id:`chat-messages`,className:`chat-scroll`,ref:o,children:(0,L.jsx)(`div`,{className:`chat-bubbles`,onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),children:v.map(e=>(0,L.jsx)(so,{msg:e.msg,fading:d.has(e.msg.id),interactive:ho(e.msg)&&e.msg.id===T,onPickerSubmit:a},e.msg.id))})})}function yo(e,t){for(let n of Array.from(e)){if(!n.type.startsWith(`image/`))continue;let e=new FileReader;e.onload=()=>{typeof e.result==`string`&&t({name:n.name,dataUrl:e.result})},e.readAsDataURL(n)}}function bo(e){return e.pending.length===0?null:(0,L.jsx)(`div`,{id:`chat-pending`,children:e.pending.map((t,n)=>(0,L.jsx)(`img`,{src:t.dataUrl,alt:t.name,title:`remove`,onClick:()=>e.onRemove(n)},`${t.name}-${n}`))})}function xo(e){return e.queued.length===0?null:(0,L.jsx)(`div`,{className:`chat-queue`,onMouseDown:e=>e.preventDefault(),children:e.queued.map((t,n)=>(0,L.jsxs)(`div`,{className:`queue-row`,children:[(0,L.jsx)(`span`,{className:`queue-snippet`,children:t.length>60?`${t.slice(0,60)}\u2026`:t}),(0,L.jsx)(`button`,{className:`queue-send-now`,type:`button`,tabIndex:-1,title:`Send now — interrupts the turn`,onClick:e.onInterrupt,children:`send now`}),(0,L.jsx)(`button`,{className:`queue-remove`,type:`button`,tabIndex:-1,title:`Remove from queue`,onClick:()=>e.onCancelQueued(n),children:`✕`})]},n))})}function So(e){let{running:t,queued:n,floating:r,expanded:i,revealed:a}=e,[o,s]=g.useState(``),[c,l]=g.useState(!1),[u,d]=g.useState(!1),[f,p]=g.useState([]),[m,h]=g.useState(!1);g.useEffect(()=>{t||h(!1)},[t]);let _=g.useRef(null),v=g.useRef(null),y=r&&!i,b=g.useCallback(()=>{let e=_.current;if(!e)return;e.style.height=`auto`;let t=Number.parseFloat(window.getComputedStyle(e).lineHeight),n=Number.isFinite(t)?Math.ceil(t):21,r=o.length===0?n:Math.min(e.scrollHeight,120);e.style.height=r>0?`${r}px`:``},[o]);g.useLayoutEffect(b,[b]),g.useLayoutEffect(()=>{y||(b(),requestAnimationFrame(()=>{b(),r&&i&&_.current?.focus()}))},[b,y,r,i]),g.useLayoutEffect(()=>{let e=v.current,t=e?.closest(`.shell-root`)??null;if(!e||!t)return;if(r){t.style.removeProperty(`--composer-reserve`);return}let n=()=>{t.style.setProperty(`--composer-reserve`,`${e.offsetHeight+7}px`)};n();let i=new ResizeObserver(n);return i.observe(e),()=>{i.disconnect(),t.style.removeProperty(`--composer-reserve`)}},[r]);let x=e=>{p(t=>t.length>=6?t:[...t,e])},S=()=>{let t=o.trim();!t&&f.length===0||(e.onSend(t,f),s(``),p([]))},C=o.trim().length>0||f.length>0,w=()=>{y&&e.onExpand()},T=()=>{r&&setTimeout(()=>{v.current?.contains(document.activeElement)||o.trim().length===0&&f.length===0&&e.onCollapse()},0)},ee=t&&!C;return(0,L.jsxs)(g.Fragment,{children:[(0,L.jsx)(bo,{pending:f,onRemove:e=>p(t=>t.filter((t,n)=>n!==e))}),(0,L.jsxs)(`div`,{className:`chat-input`+(y?` collapsed`:``)+(a?` revealed`:``),ref:v,onMouseEnter:r?e.onHoverEnter:void 0,onMouseLeave:r?e.onHoverLeave:void 0,children:[(0,L.jsx)(xo,{queued:n,onInterrupt:e.onInterrupt,onCancelQueued:e.onCancelQueued}),(0,L.jsxs)(`div`,{className:`ta`,onClick:w,children:[(0,L.jsx)(`span`,{className:`collapse-icon`,"aria-hidden":`true`,children:Ca}),(0,L.jsx)(`textarea`,{id:`chat-input`,className:`ta-text`,ref:_,rows:1,placeholder:t?`Queue a message…`:`Message the operator`,value:o,onBlur:T,onChange:e=>s(e.target.value),onPaste:e=>{let t=e.clipboardData?.files;t&&t.length>0&&(e.preventDefault(),yo(t,x))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!e.metaKey&&!e.altKey&&(e.preventDefault(),S())}}),(0,L.jsxs)(`div`,{className:`ta-bottom`,onMouseDown:e=>e.preventDefault(),children:[(0,L.jsxs)(`div`,{className:`composer-settings`,children:[(0,L.jsxs)(`button`,{className:`composer-pill`+(c?` active`:``)+Wa(e.usage),type:`button`,tabIndex:-1,title:`Agent & model settings`,"aria-label":`Agent & model settings`,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onClick:()=>l(e=>!e),children:[(0,L.jsx)(`span`,{className:`composer-pill-label`,children:ka(e.settings)}),xa]}),c?(0,L.jsx)(Ya,{settings:e.settings,warnings:e.settingsWarnings,usage:e.usage,accounts:e.accounts,onSetSetting:e.onSetSetting,onOpenKeys:()=>d(!0),onClose:()=>l(!1)}):null,u?(0,L.jsx)(Ja,{accounts:e.accounts,onSave:e.onSetCredential,onRemove:e.onClearCredential,onStartLogin:e.onStartLogin,onSubmitCode:e.onSubmitLoginCode,onCancelLogin:e.onCancelLogin,onLogout:e.onLogout,onClose:()=>d(!1)}):null]}),(0,L.jsx)(`button`,{id:`chat-send`,className:`send${ee?` stop`:``}`,type:`button`,tabIndex:-1,title:ee?m?`Stopping…`:`Stop`:`Send`,disabled:!ee&&!C||ee&&m,onClick:()=>{ee?(h(!0),e.onInterrupt()):S()},children:ee?ba:ya})]})]})]})]})}function Co(e){let t=ao(e.tasks);return t.length===0?null:(0,L.jsx)(`div`,{className:`operator-gutter`,onMouseEnter:e.onHoverEnter,onMouseLeave:e.onHoverLeave,children:(0,L.jsx)(`div`,{className:`task-stack`,children:t.map(t=>(0,L.jsx)(ro,{task:t,feed:e.feeds[t.id],onAck:e.onAck,open:e.openTasks.has(t.id),onToggle:()=>e.onToggleTask(t.id)},t.id))})})}function wo(e){let t=g.useRef(null),n=g.useCallback(()=>{t.current!==null&&(clearTimeout(t.current),t.current=null)},[]),r=g.useCallback(()=>{n(),e(!0)},[n,e]),i=g.useCallback(()=>{n(),t.current=window.setTimeout(()=>e(!1),300)},[n,e]);return g.useEffect(()=>()=>n(),[n]),{revealEnter:r,revealLeave:i}}var To=100;function Eo(e,t,n){return g.useCallback(r=>{r.preventDefault();let i=r.currentTarget,a=r.pointerId;try{i.setPointerCapture(a)}catch{}let o=new AbortController,s=()=>{o.abort();try{i.releasePointerCapture(a)}catch{}document.body.classList.remove(`operator-resizing`)};i.addEventListener(`pointermove`,r=>{if(r.clientX<t){s(),n();return}e(r.clientX)},{signal:o.signal}),i.addEventListener(`pointerup`,s,{signal:o.signal}),i.addEventListener(`pointercancel`,s,{signal:o.signal}),document.body.classList.add(`operator-resizing`)},[e,t,n])}function Do(e){let{floating:t}=e;return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`button`,{className:`operator-avatar`+(e.hasActiveTasks?` active`:``),type:`button`,tabIndex:-1,title:t?`Dock the chat panel`:`Float the chat panel`,"aria-label":`Toggle chat layout`,onClick:()=>e.setFloating(!t),onMouseEnter:t?e.onHoverEnter:void 0,onMouseLeave:t?e.onHoverLeave:void 0,children:(0,L.jsx)(`img`,{className:`operator-avatar-img`,src:Sa,alt:``,"aria-hidden":`true`,draggable:!1})}),t?null:(0,L.jsx)(`div`,{className:`operator-resize`,role:`separator`,"aria-label":`Resize chat panel`,"aria-orientation":`vertical`,"aria-valuenow":e.columnWidth,"aria-valuemin":e.minWidth,"aria-valuemax":e.maxWidth,onPointerDown:e.onStartResize})]})}function Oo(e){let{agent:t,floating:n,setFloating:r,columnWidth:i,setColumnWidth:a,minWidth:o,maxWidth:s}=e,{messages:c,tasks:l,feeds:u,settings:d,running:f,queued:p,booted:m}=t,[h,_]=g.useState(!1),[v,y]=g.useState(!1),[b,x]=g.useState(!1),[S,C]=g.useState(()=>new Set);g.useEffect(()=>{n&&(_(!1),y(!1),x(!1),C(new Set))},[n]);let w=b||S.size>0,{revealEnter:T,revealLeave:ee}=wo(y),E=g.useCallback(e=>{C(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),te=g.useCallback(()=>{_(!0),C(new Set)},[]),D=g.useCallback(()=>r(!0),[r]),O=Eo(a,o-To,D),k=(e,n,r)=>{t.submitPicker(e.id,n,r)},ne=l.some(e=>e.status===`running`);return(0,L.jsxs)(`div`,{id:`chat-host`,className:[n&&w?`rail-engaged`:``,n&&h?`chat-expanded`:``].filter(Boolean).join(` `),children:[n?(0,L.jsx)(vo,{messages:c,running:f,composerActive:h,booted:m,onPickerSubmit:k}):(0,L.jsxs)(`div`,{className:`operator-inset`,children:[(0,L.jsx)(oo,{tasks:l,feeds:u,onAck:t.ackTask}),ao(l).length>0?(0,L.jsx)(`div`,{className:`chat-divider`,"aria-hidden":`true`}):null,(0,L.jsx)(co,{messages:c,onPickerSubmit:k})]}),(0,L.jsx)(So,{running:f,queued:p,onSend:t.sendUserMessage,onInterrupt:t.interrupt,onCancelQueued:t.cancelQueued,floating:n,expanded:h,revealed:v,onExpand:te,onCollapse:()=>_(!1),onHoverEnter:T,onHoverLeave:ee,settings:d,settingsWarnings:t.settingsWarnings,usage:t.usage,accounts:t.accounts,onSetSetting:t.setSetting,onSetCredential:t.setCredential,onClearCredential:t.clearCredential,onStartLogin:t.startLogin,onSubmitLoginCode:t.submitLoginCode,onCancelLogin:t.cancelLogin,onLogout:t.logout}),n?(0,L.jsx)(Co,{tasks:l,feeds:u,openTasks:S,onToggleTask:E,onAck:t.ackTask,onHoverEnter:()=>x(!0),onHoverLeave:()=>x(!1)}):null,(0,L.jsx)(Do,{floating:n,setFloating:r,hasActiveTasks:ne,onHoverEnter:T,onHoverLeave:ee,columnWidth:i,minWidth:o,maxWidth:s,onStartResize:O})]})}var ko=class extends g.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e){console.error(`[panel error]`,e)}render(){return this.state.error?(0,L.jsxs)(`div`,{className:`panel-error`,children:[(0,L.jsx)(`div`,{className:`panel-error-title`,children:`this panel hit an error`}),(0,L.jsx)(`pre`,{className:`panel-error-msg`,children:this.state.error.message}),(0,L.jsx)(`button`,{type:`button`,className:`panel-error-retry`,onClick:()=>this.setState({error:null}),children:`retry`})]}):this.props.children}};function Ao(e){return function(t){return(0,L.jsx)(ko,{children:(0,L.jsx)(e,{...t})})}}var jo=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`,Mo=(e=21)=>{let t=``,n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+=jo[n[e]&63];return t},No={width:15,height:15,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},Po=(0,L.jsxs)(`svg`,{...No,children:[(0,L.jsx)(`polyline`,{points:`4 17 10 11 4 5`}),(0,L.jsx)(`line`,{x1:`12`,y1:`19`,x2:`20`,y2:`19`})]}),Fo=(0,L.jsx)(`svg`,{...No,children:(0,L.jsx)(`path`,{d:`M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`})}),Io=(0,L.jsx)(`svg`,{...No,children:(0,L.jsx)(`polygon`,{points:`6 4 20 12 6 20 6 4`})}),Lo=(0,L.jsxs)(`svg`,{...No,width:16,height:16,children:[(0,L.jsx)(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`}),(0,L.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`})]}),Ro=(0,L.jsxs)(`svg`,{...No,width:15,height:15,children:[(0,L.jsx)(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`}),(0,L.jsx)(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`})]}),zo=[{label:`Files`,icon:Fo,kind:`files`,mode:`singleton`,title:`Files`},{label:`Play`,icon:Io,kind:`playtest`,mode:`singleton`,title:`Play`},{label:`Terminal`,icon:Po,kind:`terminal`,mode:`spawn`,title:`Terminal`}];function Bo(e,t,n){if(t.mode===`singleton`){let r=e.getPanel(t.kind);if(r){r.api.setActive();return}e.addPanel({id:t.kind,component:t.kind,title:t.title??t.label,position:n?{referenceGroup:n}:void 0});return}let r=t.title??t.label,i=e.panels.filter(e=>e.id===t.kind||e.id.startsWith(`${t.kind}-`)),a=0;for(let e of i){let t=e.title??``;if(t===r)a=Math.max(a,1);else if(t.startsWith(`${r} `)){let e=Number.parseInt(t.slice(r.length+1),10);Number.isFinite(e)&&(a=Math.max(a,e))}}let o=a+1,s=o>1?`${r} ${o}`:r;e.addPanel({id:`${t.kind}-${Mo(6)}`,component:t.kind,title:s,position:n?{referenceGroup:n}:void 0})}function Vo(e){let[t,n]=g.useState(!1),r=g.useRef(null),i=g.useRef(null),[a,o]=g.useState({top:0,left:0}),s=g.useCallback(()=>{let e=r.current?.getBoundingClientRect();e&&o({top:e.bottom+4,left:e.right}),n(e=>!e)},[]);g.useEffect(()=>{if(!t)return;let e=e=>{r.current?.contains(e.target)||i.current?.contains(e.target)||n(!1)},a=e=>{e.key===`Escape`&&n(!1)};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,a),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,a)}},[t]);let c=t=>{Bo(e.containerApi,t,e.group),n(!1)},[,l]=g.useReducer(e=>e+1,0);return g.useEffect(()=>{let t=e.containerApi.onDidLayoutChange(()=>l());return()=>t.dispose()},[e.containerApi]),(0,L.jsxs)(`div`,{className:`dv-add-panel`,children:[e.group.panels.length===0?(0,L.jsx)(`button`,{type:`button`,className:`dv-add-panel-btn`,title:`Close group`,"aria-label":`Close group`,onClick:()=>e.group.api.close(),children:Ro}):null,(0,L.jsx)(`button`,{ref:r,type:`button`,className:`dv-add-panel-btn`,title:`New panel`,"aria-label":`New panel`,"aria-haspopup":`menu`,"aria-expanded":t,onClick:s,children:Lo}),t&&(0,Qn.createPortal)((0,L.jsx)(`div`,{ref:i,className:`dv-add-panel-menu`,role:`menu`,style:{top:a.top,left:a.left},children:zo.map(e=>(0,L.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`dv-add-panel-item`,onClick:()=>c(e),children:[(0,L.jsx)(`span`,{className:`dv-add-panel-item-icon`,children:e.icon}),(0,L.jsx)(`span`,{className:`dv-add-panel-item-label`,children:e.label})]},e.label))}),document.body)]})}var Ho=`/__castle/files/`,Uo=null;function Wo(e){Uo=e}function Go(){return Uo?.fileTypes??null}function Ko(){return Uo?.defaultPlayFile??null}var qo={deckId:null,kitEditorExtensions:[],fileTypes:null,defaultPlayFile:null,initialPanels:null};async function Jo(){try{let e=await fetch(`${Ho}info`);if(!e.ok)return qo;let t=await e.json(),n=t.kitEditorExtensions;return{deckId:typeof t.deckId==`string`&&t.deckId.length>0?t.deckId:null,kitEditorExtensions:Array.isArray(n)&&n.every(e=>typeof e==`string`)?n:[],fileTypes:Array.isArray(t.fileTypes)?t.fileTypes:null,defaultPlayFile:typeof t.defaultPlayFile==`string`&&t.defaultPlayFile?t.defaultPlayFile:null,initialPanels:Array.isArray(t.initialPanels)?t.initialPanels:null}}catch{return qo}}function Yo(e){return e===`imports`||e.startsWith(`imports/`)}async function Xo(){try{let e=await fetch(`${Ho}imports`);return e.ok?(await e.json()).imports??[]:[]}catch{return[]}}async function Zo(e){let t=await fetch(`${Ho}update-import`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({alias:e})});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`Update failed (${t.status})`)}}function Qo(e){let t=e.split(`/`).pop()??e;if(!Yo(e))return t;let n=e.split(`/`)[1];return n?`${n}:${t}`:t}async function $o(e=!1){let t=await fetch(`${Ho}list${e?`?all=1`:``}`);if(!t.ok)throw Error(`list failed: ${t.status}`);let n=await t.json();return Array.isArray(n.files)?n.files:[]}async function es(e){await as(`mkdir`,{path:e})}async function ts(e){let t=await fetch(`${Ho}read?path=${encodeURIComponent(e)}`);if(t.status===404)throw new cs(e);if(!t.ok)throw Error(`read failed: ${t.status}`);let n=await t.json();return typeof n.contents==`string`?n.contents:``}async function ns(e,t){let n=await fetch(`${Ho}write`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({path:e,contents:t})});if(!n.ok){let e=`write failed: ${n.status}`;try{let t=await n.json();typeof t.error==`string`&&(e=t.error)}catch{}throw Error(e)}}async function rs(e,t){await as(`rename`,{from:e,to:t})}async function is(e){await as(`delete`,{path:e})}async function as(e,t){let n=await fetch(`${Ho}${e}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let t=`${e} failed: ${n.status}`;try{let e=await n.json();typeof e.error==`string`&&(t=e.error)}catch{}throw Error(t)}}function os(e){let t=(e.split(`/`).pop()??e).replace(/\.[^.]+$/,``);switch(ls(e)){case`.scene`:return`${JSON.stringify({background:`#1a1932`,actors:[],name:t||`Scene`},null,2)}\n`;case`.pxart`:return`${JSON.stringify({format:`full`,resolution:{width:16,height:16},palette:[],frames:[{}],layers:[{id:`layer-0`,name:`Layer 1`,visible:!0,opacity:1,blendMode:`normal`,kind:`pixel`,cells:[null]}]},null,2)}\n`;case`.jsx`:return ss(t);default:return``}}function ss(e){let t=/^[A-Za-z_$][\w$]*$/.test(e)?e:`Behavior`;return[`export class ${t} {`,` static behaviorName = '${t}';`,``,` static defaultProps = {};`,``,` constructor(props) {`,` this.props = props;`,` }`,``,` // Called every frame in play mode. dt is seconds.`,` update(actor, scene, dt) {}`,`}`,``].join(`
75
+ `)}`:``}var ua=`/__castle/agent/attachments/`,da={lightbulb:{w:352,d:`M96.06 454.35c.01 6.29 1.87 12.45 5.36 17.69l17.09 25.69a31.99 31.99 0 0 0 26.64 14.28h61.71a31.99 31.99 0 0 0 26.64-14.28l17.09-25.69a31.989 31.989 0 0 0 5.36-17.69l.04-38.35H96.01l.05 38.35zM0 176c0 44.37 16.45 84.85 43.56 115.78 16.52 18.85 42.36 58.23 52.21 91.45.04.26.07.52.11.78h160.24c.04-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45C335.55 260.85 352 220.37 352 176 352 78.61 272.91-.3 175.45 0 73.44.31 0 82.97 0 176zm176-80c-44.11 0-80 35.89-80 80 0 8.84-7.16 16-16 16s-16-7.16-16-16c0-61.76 50.24-112 112-112 8.84 0 16 7.16 16 16s-7.16 16-16 16z`},book:{w:448,d:`M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z`},hammer:{w:576,d:`M571.31 193.94l-22.63-22.63c-6.25-6.25-16.38-6.25-22.63 0l-11.31 11.31-28.9-28.9c5.63-21.31.36-44.9-16.35-61.61l-45.25-45.25c-62.48-62.48-163.79-62.48-226.28 0l90.51 45.25v18.75c0 16.97 6.74 33.25 18.75 45.25l49.14 49.14c16.71 16.71 40.3 21.98 61.61 16.35l28.9 28.9-11.31 11.31c-6.25 6.25-6.25 16.38 0 22.63l22.63 22.63c6.25 6.25 16.38 6.25 22.63 0l90.51-90.51c6.23-6.24 6.23-16.37-.02-22.62zm-286.72-15.2c-3.7-3.7-6.84-7.79-9.85-11.95L19.64 404.96c-25.57 23.88-26.26 64.19-1.53 88.93s65.05 24.05 88.93-1.53l238.13-255.07c-3.96-2.91-7.9-5.87-11.44-9.41l-49.14-49.14z`},pencil:{w:512,d:`M497.9 142.1l-46.1 46.1c-4.7 4.7-12.3 4.7-17 0l-111-111c-4.7-4.7-4.7-12.3 0-17l46.1-46.1c18.7-18.7 49.1-18.7 67.9 0l60.1 60.1c18.8 18.7 18.8 49.1 0 67.9zM284.2 99.8L21.6 362.4.4 483.9c-2.9 16.4 11.4 30.6 27.8 27.8l121.5-21.3 262.6-262.6c4.7-4.7 4.7-12.3 0-17l-111-111c-4.8-4.7-12.4-4.7-17.1 0zM124.1 339.9c-5.5-5.5-5.5-14.3 0-19.8l154-154c5.5-5.5 14.3-5.5 19.8 0s5.5 14.3 0 19.8l-154 154c-5.5 5.5-14.3 5.5-19.8 0zM88 424h48v36.3l-64.5 11.3-31.1-31.1L51.7 376H88v48z`},gamepad:{w:640,d:`M480.07 96H160a160 160 0 1 0 114.24 272h91.52A160 160 0 1 0 480.07 96zM248 268a12 12 0 0 1-12 12h-52v52a12 12 0 0 1-12 12h-24a12 12 0 0 1-12-12v-52H84a12 12 0 0 1-12-12v-24a12 12 0 0 1 12-12h52v-52a12 12 0 0 1 12-12h24a12 12 0 0 1 12 12v52h52a12 12 0 0 1 12 12zm216 76a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm64-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40z`},check:{w:512,d:`M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z`},times:{w:352,d:`M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z`},stop:{w:448,d:`M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z`}};function fa({glyph:e}){return(0,L.jsx)(`svg`,{className:`avatar-icon`,viewBox:`0 0 ${e.w} 512`,fill:`currentColor`,"aria-hidden":`true`,children:(0,L.jsx)(`path`,{d:e.d})})}var pa={thinking:(0,L.jsx)(fa,{glyph:da.lightbulb}),reading:(0,L.jsx)(fa,{glyph:da.book}),building:(0,L.jsx)(fa,{glyph:da.hammer}),painting:(0,L.jsx)(fa,{glyph:da.pencil}),playing:(0,L.jsx)(fa,{glyph:da.gamepad})},ma={thinking:`Thinking`,reading:`Reading files`,building:`Editing logic`,painting:`Editing art`,playing:`Playtesting`},ha={thinking:`#FFC826`,reading:`#FFC826`,building:`#FFEB57`,painting:`#FFEB57`,playing:`#D3FC7E`};function ga(e){if(e.status===`done`)return{icon:(0,L.jsx)(fa,{glyph:da.check}),color:`#5AC54F`};if(e.status===`failed`)return{icon:(0,L.jsx)(fa,{glyph:da.times}),color:`#F5545D`};if(e.status===`interrupted`)return{icon:(0,L.jsx)(fa,{glyph:da.stop}),color:`#B4B4B4`};if(e.status===`blocked`)return{icon:(0,L.jsx)(fa,{glyph:da.stop}),color:`#F5A623`};let t=e.avatar&&pa[e.avatar]?e.avatar:`thinking`;return{icon:pa[t],color:ha[t]}}function _a(e){let t=Math.max(1,Math.round((e??0)/1e3));if(t<60)return`Thought for ${t}s`;let n=Math.floor(t/60),r=t%60;return r===0?`Thought for ${n}m`:`Thought for ${n}m ${r}s`}function va(e){try{return{__html:I.parse(e,{breaks:!0,async:!1})}}catch{return{__html:``}}}var ya=(0,L.jsx)(`svg`,{viewBox:`0 0 512 512`,width:12,height:12,"aria-hidden":`true`,children:(0,L.jsx)(`path`,{d:`M470.3 271.15 43.16 447.31a7.83 7.83 0 0 1-11.16-7V327a8 8 0 0 1 6.51-7.86l247.62-47c17.36-3.29 17.36-28.15 0-31.44l-247.63-47a8 8 0 0 1-6.5-7.85V72.59c0-5.74 5.88-10.26 11.16-8L470.3 241.76a16 16 0 0 1 0 29.39`,fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:32})}),ba=(0,L.jsx)(`svg`,{viewBox:`0 0 512 512`,width:12,height:12,"aria-hidden":`true`,children:(0,L.jsx)(`rect`,{x:128,y:128,width:256,height:256,rx:36,fill:`currentColor`})}),xa=(0,L.jsx)(`svg`,{viewBox:`0 0 24 24`,width:10,height:10,fill:`none`,stroke:`currentColor`,strokeWidth:2.4,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,className:`mode-caret`,children:(0,L.jsx)(`path`,{d:`M6 9l6 6 6-6`})}),Sa=`/__castle/ide/operator.png`,Ca=(0,L.jsx)(`svg`,{viewBox:`0 0 512 512`,width:20,height:20,"aria-hidden":`true`,children:(0,L.jsx)(`path`,{d:`M408 64H104a56.16 56.16 0 0 0-56 56v192a56.16 56.16 0 0 0 56 56h40v80l93.72-78.14a8 8 0 0 1 5.13-1.86H408a56.16 56.16 0 0 0 56-56V120a56.16 56.16 0 0 0-56-56z`,fill:`none`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:32})}),wa=[{value:`claude`,label:`Claude`},{value:`cursor`,label:`Cursor`},{value:`smith`,label:`Smith`}],Ta=[{value:`opus`,label:`Opus`},{value:`sonnet`,label:`Sonnet`},{value:`fable`,label:`Fable`},{value:`openrouter`,label:`OpenRouter`}];function Ea(e,t){return e===`smith`||e===`claude`&&t===`openrouter`}function Da(e){if(!e||!e.trim())return null;let t=e.trim(),n=t.lastIndexOf(`/`);return n>=0?t.slice(n+1):t}function Oa(e,t,n){let r=wa.find(t=>t.value===e)?.label??e??`?`;if(e===`claude`){if(t===`openrouter`){let e=Da(n);return e?`${r} (${e})`:`${r} (OpenRouter)`}let e=Ta.find(e=>e.value===t)?.label??t;return e?`${r} (${e})`:r}if(e===`smith`){let e=Da(n);return e?`${r} (${e})`:r}return r}function ka(e){return`${Oa(e.router,e.routerClaudeModel,e.routerOpenrouterModel)} → ${Oa(e.tasks,e.tasksClaudeModel,e.tasksOpenrouterModel)}`}var Aa=`/__castle/agent/model-caps`,ja=[{value:`balanced`,label:`Balanced`},{value:`nitro`,label:`Nitro`},{value:`exacto`,label:`Exacto`},{value:`floor`,label:`Floor`}],Ma=[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],Na={none:`None`,minimal:`Minimal`,low:`Low`,medium:`Medium`,high:`High`,xhigh:`XHigh`,max:`Max`};function Pa(e){let t=e?.reasoningEfforts;if(!t||t.length===0)return null;let n=new Set(t);return Ma.filter(e=>n.has(e)).map(e=>({value:e,label:Na[e]??e}))}var Fa={openai:`OpenAI`,azure:`Azure`,anthropic:`Anthropic`,google:`Google`,"google-vertex":`Vertex`,deepinfra:`DeepInfra`,fireworks:`Fireworks`,together:`Together`,groq:`Groq`,cerebras:`Cerebras`,baseten:`Baseten`},Ia={flex:`Flex`,priority:`Priority`,standard:`Standard`,eu:`EU`};function La(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function Ra(e){let[t,n]=e.split(`/`),r=Fa[t]??La(t);return n?`${r} ${Ia[n]??La(n)}`:r}function za(e){let t=e?.providerTiers;return!t||t.length<2?null:[{value:``,label:`Auto`},...t.map(e=>({value:e,label:Ra(e)}))]}function Ba(e,t,n){let r=e===`router`,i=r?`routerClaudeModel`:`tasksClaudeModel`,a=[{type:`enum`,key:e,label:r?`Operator`:`Tasks`,options:wa},{type:`enum`,key:i,label:`Model`,options:Ta,showWhen:t=>t[e]===`claude`},{type:`text`,key:r?`routerOpenrouterModel`:`tasksOpenrouterModel`,label:`OpenRouter model`,placeholder:r?`openai/gpt-5.6-sol`:`openai/gpt-5.6-terra`,showWhen:t=>Ea(t[e],t[i])}];if(t[e]===`smith`){let e=Pa(n);e&&a.push({type:`select`,key:r?`routerReasoningEffort`:`tasksReasoningEffort`,label:`Reasoning`,options:e}),a.push({type:`select`,key:r?`routerRouting`:`tasksRouting`,label:`Routing`,options:ja});let t=za(n);t&&a.push({type:`select`,key:r?`routerProviderTier`:`tasksProviderTier`,label:`Provider`,options:t})}return a}function Va(e){let{label:t,placeholder:n,value:r,warning:i,onCommit:a}=e,[o,s]=g.useState(r);g.useEffect(()=>s(r),[r]);let c=()=>{let e=o.trim();e&&e!==r?a(e):s(r)},l=e=>{s(e),a(e)};return(0,L.jsxs)(`div`,{className:`settings-row settings-row-stack`,children:[(0,L.jsxs)(`div`,{className:`settings-row-main`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:t}),(0,L.jsx)(`input`,{type:`text`,className:`settings-text${i?` settings-text-warn`:``}`,value:o,placeholder:n,onChange:e=>s(e.target.value),onBlur:c,onKeyDown:e=>{e.key===`Enter`&&(c(),e.target.blur())}})]}),i?(0,L.jsxs)(`div`,{className:`settings-warning`,children:[`⚠ `,i.message,i.suggestion?(0,L.jsxs)(L.Fragment,{children:[` `,`Did you mean`,` `,(0,L.jsx)(`button`,{type:`button`,className:`settings-warning-suggest`,onMouseDown:e=>{e.preventDefault(),l(i.suggestion)},children:i.suggestion}),`?`]}):null]}):null]})}function Ha(e,t,n){let r=e?.[t];if(!(!r||!n||r.model!==n))return{message:r.message,suggestion:r.suggestion}}function Ua(e){return!e||e.limitMicros===null||e.limitMicros<=0?null:Math.min(1,e.usedMicros/e.limitMicros)}function Wa(e){let t=Ua(e);return t===null?``:e?.blocked?` usage-blocked`:t>=.8?` usage-warn`:``}function Ga(e){let t=Ua(e.usage);if(t===null)return null;let n=e.usage.resetAtMs?new Date(e.usage.resetAtMs).toLocaleTimeString([],{hour:`numeric`,minute:`2-digit`}):``;return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`settings-row`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:`Daily AI usage`}),(0,L.jsx)(`span`,{className:`settings-usage-text`,children:e.usage.blocked?`Limit reached`:`${Math.round(t*100)}%${n?` \u00b7 resets ${n}`:``}`})]}),(0,L.jsx)(`div`,{className:`settings-usage-bar`,children:(0,L.jsx)(`div`,{className:`settings-usage-fill`+(e.usage.blocked?` blocked`:``),style:{width:`${t*100}%`}})})]})}function Ka(e){return(0,L.jsx)(`button`,{type:`button`,className:`settings-account-open`,onClick:e.onOpen,children:e.anyStored?`Manage your account`:`Use your own account`})}function qa(e){let{login:t}=e,[n,r]=g.useState(``),i=()=>{n.trim()&&e.onSubmitCode(n.trim())};return(0,L.jsxs)(L.Fragment,{children:[t.url?(0,L.jsxs)(`div`,{className:`castle-key-login`,children:[(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Open this link to sign in, then come back here.`}),(0,L.jsx)(`a`,{className:`castle-key-url`,href:t.url,target:`_blank`,rel:`noreferrer noopener`,children:t.url})]}):(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Starting sign-in…`}),t.phase===`awaiting-code`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Paste the code the browser shows you:`}),(0,L.jsx)(`input`,{className:`castle-key-input`,autoFocus:!0,spellCheck:!1,autoComplete:`off`,value:n,placeholder:`code`,onChange:e=>r(e.target.value),onKeyDown:e=>{e.key===`Enter`&&i()}}),t.message?(0,L.jsx)(`div`,{className:`castle-key-error`,children:t.message}):null]}):null,t.phase===`verifying`?(0,L.jsx)(`div`,{className:`castle-key-stored`,children:`Finishing sign-in…`}):null,t.phase===`error`?(0,L.jsx)(`div`,{className:`castle-key-error`,children:t.message}):null,(0,L.jsxs)(`div`,{className:`castle-modal-actions`,children:[(0,L.jsx)(`button`,{type:`button`,onClick:e.onCancel,children:t.phase===`error`?`Close`:`Cancel`}),t.phase===`awaiting-code`?(0,L.jsx)(`button`,{type:`button`,onClick:i,disabled:!n.trim(),children:`Submit`}):null]})]})}function Ja(e){let t=e.accounts.providers,n=e.accounts.login,[r,i]=g.useState(()=>(t.find(e=>e.key?.present||e.login?.loggedIn)??t[0])?.id??``),[a,o]=g.useState(``),[s,c]=g.useState(null),l=(n?t.find(e=>e.login?.provider===n.provider):null)??t.find(e=>e.id===r)??t[0]??null,u=g.useRef(e.onClose);u.current=e.onClose;let d=n!==null;g.useEffect(()=>{let e=e=>{e.key===`Escape`&&!d&&u.current()};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[d]);let f=g.useRef(null);if(g.useEffect(()=>{if(n){f.current=n.provider;return}let e=f.current;e!==null&&(f.current=null,t.find(t=>t.login?.provider===e)?.login?.loggedIn&&u.current())}),!l)return null;let p=!!l.login?.loggedIn,m=!!l.key?.present,h=p||m,_=()=>{let t=a.trim();if(t){if(t.length>500){c(`That key is too long.`);return}if([...t].some(e=>{let t=e.codePointAt(0)??0;return t<32||t===127})){c(`That key contains invalid characters.`);return}e.onSave(l.id,t),e.onClose()}};return(0,Qn.createPortal)((0,L.jsx)(`div`,{className:`castle-modal-scrim`,onMouseDown:n?void 0:e.onClose,children:(0,L.jsxs)(`div`,{className:`castle-modal`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`div`,{className:`castle-key-heading`,children:n?`Sign in to ${l.label}`:`Your account`}),n?null:(0,L.jsx)(`div`,{className:`castle-key-subtitle`,children:`Run the operator on your own account and bypass Castle's daily limit.`}),t.length>1&&!n?(0,L.jsx)(`div`,{className:`castle-key-tabs`,children:t.map(e=>(0,L.jsx)(`button`,{type:`button`,className:`castle-key-tab`+(e.id===l.id?` active`:``),onClick:()=>{i(e.id),o(``),c(null)},children:e.label},e.id))}):null,n?(0,L.jsx)(qa,{login:n,onSubmitCode:e.onSubmitCode,onCancel:e.onCancelLogin}):(0,L.jsxs)(L.Fragment,{children:[h?(0,L.jsxs)(L.Fragment,{children:[p?(0,L.jsxs)(`div`,{className:`castle-key-row`,children:[(0,L.jsxs)(`span`,{children:[`Signed in with your `,l.label,` account.`]}),(0,L.jsx)(`button`,{type:`button`,onClick:()=>{e.onLogout(l.id),e.onClose()},children:`Sign out`})]}):null,m?(0,L.jsxs)(`div`,{className:`castle-key-row`,children:[(0,L.jsxs)(`span`,{children:[`API key saved (`,l.key?.hint,`).`]}),(0,L.jsx)(`button`,{type:`button`,onClick:()=>{e.onRemove(l.id),e.onClose()},children:`Remove`})]}):null]}):(0,L.jsxs)(L.Fragment,{children:[l.login?(0,L.jsxs)(`button`,{type:`button`,className:`castle-key-signin`,onClick:()=>e.onStartLogin(l.id),children:[`Sign in with your `,l.label,` account`]}):null,l.login&&l.key?(0,L.jsx)(`div`,{className:`castle-key-or`,children:`or`}):null,l.key?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`castle-key-field-label`,children:`Add API key`}),(0,L.jsx)(`input`,{type:`password`,className:`castle-key-input`,autoFocus:!0,spellCheck:!1,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,value:a,placeholder:l.key.placeholder,onChange:e=>{o(e.target.value),c(null)},onKeyDown:e=>{e.key===`Enter`&&_()}}),s?(0,L.jsx)(`div`,{className:`castle-key-error`,children:s}):null]}):null]}),(0,L.jsxs)(`div`,{className:`castle-modal-actions`,children:[(0,L.jsx)(`button`,{type:`button`,onClick:e.onClose,children:`Cancel`}),!h&&l.key?(0,L.jsx)(`button`,{type:`button`,onClick:_,disabled:!a.trim(),children:`Save`}):null]})]})]})}),document.body)}function Ya(e){let{settings:t,onSetSetting:n,onClose:r}=e,i=Ua(e.usage)!==null,a=e.accounts.providers.some(e=>e.key?.present||e.login?.loggedIn),o=e.accounts.providers.length>0&&(i||a),s=g.useRef(null),[c,l]=g.useState({}),u=t.routerOpenrouterModel?.trim()??``,d=t.tasksOpenrouterModel?.trim()??``,f=t.router===`smith`,p=t.tasks===`smith`;g.useEffect(()=>{let e=new Set;f&&u&&e.add(u),p&&d&&e.add(d);let t=!1;for(let n of e)fetch(`${Aa}?model=${encodeURIComponent(n)}`).then(e=>e.ok?e.json():null).then(e=>{!t&&e&&l(t=>({...t,[n]:e}))}).catch(()=>{});return()=>{t=!0}},[f,u,p,d]);let m=[Ba(`router`,t,c[u]),Ba(`tasks`,t,c[d])];return g.useEffect(()=>{let e=e=>{s.current&&!s.current.contains(e.target)&&r()},t=e=>{e.key===`Escape`&&r()};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,t),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,t)}},[r]),(0,L.jsxs)(`div`,{className:`settings-popover`,ref:s,onMouseDown:e=>e.stopPropagation(),children:[i||o?(0,L.jsxs)(`div`,{className:`settings-group`,children:[i&&e.usage?(0,L.jsx)(Ga,{usage:e.usage}):null,o?(0,L.jsx)(Ka,{anyStored:a,onOpen:e.onOpenKeys}):null]}):null,m.map((r,i)=>(0,L.jsx)(`div`,{className:`settings-group`,children:r.filter(e=>!e.showWhen||e.showWhen(t)).map(r=>{if(r.type===`text`)return(0,L.jsx)(Va,{label:r.label,placeholder:r.placeholder,value:t[r.key]??``,warning:Ha(e.warnings,r.key,t[r.key]),onCommit:e=>n(r.key,e)},r.key);if(r.type===`select`)return(0,L.jsxs)(`div`,{className:`settings-row`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:r.label}),(0,L.jsx)(`select`,{className:`settings-select`,value:t[r.key]??``,onChange:e=>n(r.key,e.target.value),children:r.options.map(e=>(0,L.jsx)(`option`,{value:e.value,children:e.label},e.value))})]},r.key);let i=t[r.key];return(0,L.jsxs)(`div`,{className:`settings-row`,children:[(0,L.jsx)(`span`,{className:`settings-label`,children:r.label}),(0,L.jsx)(`div`,{className:`settings-seg`,children:r.options.map(e=>(0,L.jsx)(`button`,{type:`button`,tabIndex:-1,className:`settings-opt`+(i===e.value?` active`:``),onClick:()=>n(r.key,e.value),children:e.label},e.value))})]},r.key)})},i))]})}function Xa(e){let{spec:t,interactive:n,answers:r,onSubmit:i}=e,[a,o]=g.useState({}),s=n?a:r??{},c=(e,t,r)=>{n&&o(n=>{let i=n[e]??[];if(r){let r=i.includes(t)?i.filter(e=>e!==t):[...i,t];return{...n,[e]:r}}return{...n,[e]:i[0]===t?[]:[t]}})};return(0,L.jsxs)(`div`,{className:`picker${n?``:` picker-locked`}`,children:[t.questions.map(e=>(0,L.jsxs)(`fieldset`,{className:`picker-q`,disabled:!n,children:[(0,L.jsx)(`legend`,{className:`picker-q-label`,children:e.q}),(0,L.jsx)(`div`,{className:`picker-options`,children:e.options.map(t=>{let r=(s[e.id]??[]).includes(t);return(0,L.jsxs)(`label`,{className:`picker-option${r?` is-checked`:``}`,children:[(0,L.jsx)(`input`,{type:e.multi?`checkbox`:`radio`,name:e.id,checked:r,disabled:!n,onChange:()=>c(e.id,t,e.multi)}),(0,L.jsx)(`span`,{children:t})]},t)})})]},e.id)),n?(0,L.jsx)(`div`,{className:`picker-actions`,children:(0,L.jsx)(`button`,{className:`picker-submit`,type:`button`,onClick:()=>{let e=la(t,a);e&&i(a,e)},children:`Submit`})}):null]})}function Za(){return(0,L.jsxs)(`div`,{className:`picker picker-skeleton`,"aria-hidden":`true`,children:[(0,L.jsx)(`span`,{className:`picker-skeleton-hint`,children:`preparing options…`}),(0,L.jsxs)(`div`,{className:`picker-q`,children:[(0,L.jsx)(`div`,{className:`picker-skeleton-line picker-skeleton-label`}),(0,L.jsxs)(`div`,{className:`picker-options`,children:[(0,L.jsx)(`span`,{className:`picker-skeleton-chip`,style:{width:84}}),(0,L.jsx)(`span`,{className:`picker-skeleton-chip`,style:{width:116}}),(0,L.jsx)(`span`,{className:`picker-skeleton-chip`,style:{width:72}})]})]})]})}function Qa(e){let t=/^\[Editing (.+)\]$/,n=/^\[Reading (.+)\]$/,r=new Set;for(let n of e){let e=t.exec(n.trim());if(e)for(let t of e[1].split(`, `))r.add(t)}let i=[];for(let t of e){let e=n.exec(t.trim());if(e){let t=e[1].split(`, `).filter(e=>!r.has(e));if(t.length===0)continue;i.push(`[Reading ${t.join(`, `)}]`);continue}i.push(t)}return i}function $a(e){let t=/^\[([A-Za-z]+)\s+(.+)\]$/,n=[];for(let r of e){let e=t.exec(r.trim());if(e){let r=n.length?t.exec(n[n.length-1].trim()):null;if(r&&r[1]===e[1]){r[2].split(`, `).includes(e[2])||(n[n.length-1]=`[${e[1]} ${r[2]}, ${e[2]}]`);continue}}n.push(r)}return n}function eo(e){return e.detail?(0,L.jsxs)(`details`,{className:`msg-error-detail`,children:[(0,L.jsx)(`summary`,{children:`Details (full text in the browser console)`}),(0,L.jsx)(`pre`,{children:e.detail})]}):null}function to(e){let t=g.useRef(null);return g.useLayoutEffect(()=>{let e=t.current;e&&(e.scrollTop=e.scrollHeight)},[e.lines]),(0,L.jsx)(`div`,{className:`task-feed`,ref:t,onClick:e=>e.stopPropagation(),children:$a(Qa(e.lines)).map((e,t)=>{let n=/^\[(.+)\]$/.exec(e.trim());return n?(0,L.jsx)(`div`,{className:`task-feed-tool`,children:n[1]},t):(0,L.jsx)(`div`,{className:`task-feed-msg`,dangerouslySetInnerHTML:va(e)},t)})})}function no(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/60),r=t%60;return n>0?`${n}m ${r}s`:`${r}s`}function ro(e){let{task:t,onAck:n}=e,r=e.onToggle!==void 0,[i,a]=g.useState(!1),o=r?e.open===!0:i,s=()=>{r?e.onToggle?.():a(e=>!e)},[c,l]=g.useState(()=>Date.now());g.useEffect(()=>{if(t.status!==`running`)return;let e=setInterval(()=>l(Date.now()),1e3);return()=>clearInterval(e)},[t.status]);let u=t.startedAt?Date.parse(t.startedAt):null,d=t.finishedAt?Date.parse(t.finishedAt):null,f=Er.includes(t.status),p=t.status===`done`?100:f?t.progress:Math.min(t.progress,95),m=t.notes.trim()||(t.status===`failed`?t.errorCopy?.trim():void 0)||t.resultSummary?.trim()||``,h=ga(t),_=t.status===`running`?t.phase?.trim()||ma[t.avatar??``]||`Working`:t.status===`waiting`?`Queued`:t.status===`blocked`?`Blocked`:t.status===`done`?`Done`:t.status===`failed`?`Failed`:t.status===`interrupted`?`Interrupted`:t.status;return(0,L.jsx)(`div`,{className:`task${o?` open`:``}`,onClick:s,children:(0,L.jsxs)(`div`,{className:`task-row`,children:[(0,L.jsx)(`div`,{className:`pie`,style:{background:`conic-gradient(#fff ${p*3.6}deg, #333 0deg)`},children:(0,L.jsx)(`div`,{className:`avatar`,style:{background:h.color},children:(0,L.jsx)(`span`,{className:`avatar-icon-wrap`,"aria-hidden":`true`,children:h.icon})})}),(0,L.jsxs)(`div`,{className:`task-meta`,children:[(0,L.jsxs)(`div`,{className:`task-head`,children:[(0,L.jsxs)(`div`,{className:`task-text`,children:[(0,L.jsxs)(`div`,{className:`task-name`,children:[(0,L.jsx)(`span`,{className:`tn`,children:t.title}),`: `,_]}),(0,L.jsx)(`div`,{className:`task-sub`,children:t.status===`running`&&u!=null?no(c-u):f&&u!=null&&d!=null?(0,L.jsxs)(L.Fragment,{children:[`Worked for `,no(d-u)]}):null})]}),f?(0,L.jsx)(`button`,{className:`task-dismiss`,type:`button`,onClick:e=>{e.stopPropagation(),n(t.id,!1)},children:`Dismiss`}):null]}),(0,L.jsxs)(`div`,{className:`task-body`,children:[o&&t.status===`running`&&e.feed&&e.feed.length>0?(0,L.jsx)(to,{lines:e.feed}):null,o&&t.status!==`running`&&m?(0,L.jsx)(`div`,{className:`task-notes`,dangerouslySetInnerHTML:va(m)}):null,o&&t.status===`failed`?(0,L.jsx)(eo,{detail:t.errorDetail}):null,o?(0,L.jsx)(io,{frames:t.playtestFrames}):null]})]})]})})}function io(e){let t=e.frames??[];return t.length===0?null:(0,L.jsxs)(`div`,{className:`task-playtest-frames`,children:[(0,L.jsxs)(`div`,{className:`task-playtest-frames-label`,children:[`Playtest frames (`,t.length,`)`]}),(0,L.jsx)(`div`,{className:`task-playtest-frames-row`,children:t.map(e=>(0,L.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),children:(0,L.jsx)(`img`,{className:`task-playtest-frame`,src:e,alt:`playtest frame`})},e))})]})}function ao(e){return e.filter(e=>!(e.acknowledged&&Er.includes(e.status)))}function oo(e){let t=g.useRef(null),n=g.useRef(!0),r=g.useRef(0),[i,a]=g.useState(!1),o=ao(e.tasks);g.useLayoutEffect(()=>{let e=t.current;e&&n.current&&(e.scrollTop=e.scrollHeight)},[e.tasks]),g.useEffect(()=>()=>window.clearTimeout(r.current),[]);let s=()=>{let e=t.current;e&&(n.current=e.scrollHeight-e.scrollTop-e.clientHeight<24,a(!0),window.clearTimeout(r.current),r.current=window.setTimeout(()=>a(!1),900))};if(o.length===0)return null;let c=o.filter(e=>Er.includes(e.status));return(0,L.jsxs)(`div`,{id:`task-board`,className:`task-stack${i?` scrolling`:``}`,ref:t,onScroll:s,children:[(0,L.jsxs)(`div`,{className:`task-board-header`,children:[(0,L.jsxs)(`div`,{className:`task-board-heading`,children:[(0,L.jsx)(`span`,{className:`task-board-title`,children:`Tasks`}),(0,L.jsxs)(`span`,{className:`task-board-status`,children:[c.length,`/`,o.length,` completed`]})]}),c.length>0?(0,L.jsx)(`button`,{type:`button`,className:`task-clear-completed`,onClick:()=>{for(let t of c)e.onAck(t.id,!1)},children:`Clear completed`}):null]}),o.map(t=>(0,L.jsx)(ro,{task:t,feed:e.feeds[t.id],onAck:e.onAck},t.id))]})}function so(e){let{msg:t,onPickerSubmit:n,fading:r,interactive:i=!1}=e,a=r?` fading`:``;if(t.role===`log`)return(0,L.jsx)(`div`,{className:`msg toolline`,children:t.text});if(t.role===`user`)return(0,L.jsxs)(`div`,{className:`msg user`+a,children:[(t.attachments??[]).map(e=>(0,L.jsx)(`img`,{className:`msg-image`,src:`${ua}${e}`,alt:``},e)),t.text?(0,L.jsx)(`span`,{children:t.text}):null]});let o=t.status===`streaming`,s=ca(t.text),c=s.some(e=>e.kind===`ask`||e.kind===`ask-pending`||e.kind===`md`&&e.text.trim()!==``);if(!o&&!c)return null;let l=!o&&!t.pickerAnswers&&i,u=-1;s.forEach((e,t)=>{e.kind===`md`&&e.text.trim()!==``&&(u=t)});let d=s.some(e=>e.kind===`ask`||e.kind===`ask-pending`),f=o&&u===-1&&!d,p=!!(t.thinking&&t.thinking.trim());return(0,L.jsxs)(`div`,{className:`assistant-turn`+a,children:[s.map((e,r)=>{if(e.kind===`ask-pending`)return(0,L.jsx)(Za,{},r);if(e.kind===`ask`)return(0,L.jsx)(Xa,{spec:e.spec,interactive:l,answers:t.pickerAnswers,onSubmit:(e,r)=>n(t,e,r)},r);if(!e.text.trim())return null;let i=[`msg`,`assistant`,`md`];return o&&r===u&&i.push(`streaming`),t.status===`error`&&i.push(`errbubble`),(0,L.jsx)(`div`,{className:i.join(` `),dangerouslySetInnerHTML:va(e.text)},r)}),p?(0,L.jsxs)(`details`,{className:`msg-thinking`,children:[(0,L.jsxs)(`summary`,{"aria-label":t.activity??`Thinking`,children:[(0,L.jsx)(`span`,{className:`thinking-caret`,"aria-hidden":`true`}),f?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`span`,{className:`thinking-dots`,"aria-hidden":`true`,children:[(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{})]}),(0,L.jsx)(`span`,{className:`thinking-label`,children:t.activity??`Thinking`})]}):(0,L.jsx)(`span`,{className:`thinking-label`,children:_a(t.thinkingMs)})]}),(0,L.jsx)(`div`,{className:`msg-thinking-body`,dangerouslySetInnerHTML:va(t.thinking??``)})]}):f?(0,L.jsxs)(`div`,{className:`msg-thinking`,"aria-label":t.activity??`thinking`,children:[(0,L.jsxs)(`span`,{className:`thinking-dots`,"aria-hidden":`true`,children:[(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{}),(0,L.jsx)(`i`,{})]}),t.activity?(0,L.jsx)(`span`,{className:`thinking-label`,children:t.activity}):null]}):o&&t.activity?(0,L.jsxs)(`div`,{className:`msg-activity`,children:[t.activity,`...`]}):null,o?null:(0,L.jsx)(eo,{detail:t.errorDetail}),t.interrupted?(0,L.jsx)(`div`,{className:`msg-interrupted`,children:`interrupted by your next message`}):null]})}function co(e){let t=g.useRef(null),n=g.useRef(null),r=g.useRef(0),i=g.useRef(!0),a=g.useRef(0),[o,s]=g.useState(!1),c=g.useCallback(()=>{let e=t.current;e&&(e.scrollHeight-e.clientHeight-e.scrollTop<=1||(a.current=typeof performance<`u`?performance.now():Date.now(),e.scrollTop=e.scrollHeight))},[]),l=g.useCallback(()=>{c();let e=t.current;e&&e.clientHeight>0&&s(!0)},[c]);g.useLayoutEffect(()=>{if(!i.current)return;l();let e=requestAnimationFrame(l),t=window.setTimeout(l,250),n=window.setTimeout(()=>s(!0),500);return()=>{cancelAnimationFrame(e),clearTimeout(t),clearTimeout(n)}},[e.messages,l]),g.useEffect(()=>{let e=t.current;if(!e)return;let a=new ResizeObserver(()=>{i.current?l():e.scrollTop=e.scrollHeight-e.clientHeight-r.current});return a.observe(e),n.current&&a.observe(n.current,{box:`border-box`}),()=>a.disconnect()},[l]);let u=()=>{let e=t.current;e&&((typeof performance<`u`?performance.now():Date.now())-a.current<200||(r.current=e.scrollHeight-e.scrollTop-e.clientHeight,i.current=r.current<48))},d=go(e.messages);return(0,L.jsx)(`div`,{id:`chat-messages`,className:`chat-scroll`,ref:t,onScroll:u,children:(0,L.jsxs)(`div`,{className:`chat-thread`+(o?` ready`:``),ref:n,children:[e.messages.length===0?(0,L.jsx)(`div`,{id:`chat-empty`,children:`Tell the agent what you want to make.`}):null,e.messages.map(t=>(0,L.jsx)(so,{msg:t,interactive:t.id===d,onPickerSubmit:e.onPickerSubmit},t.id))]})})}var lo=550,uo=4;function fo(e){let t=1500+e.trim().length/18*1e3;return Math.min(12e3,Math.max(2500,t))}function po(){return typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(prefers-reduced-motion: reduce)`).matches}function mo(e){return e.role===`user`?(e.text??``).trim()!==``||(e.attachments?.length??0)>0:e.role===`assistant`?e.status===`streaming`?!0:ca(e.text).some(e=>e.kind===`ask`||e.kind===`ask-pending`||e.kind===`md`&&e.text.trim()!==``):!1}function ho(e){return e.role!==`assistant`||e.pickerAnswers?!1:ca(e.text).some(e=>e.kind===`ask`)}function go(e){for(let t=e.length-1;t>=0;t--)if(ho(e[t]))return e[t].id;return null}function _o(e,t){let n=e.map((e,t)=>({msg:e,idx:t})).filter(e=>mo(e.msg)),r=n.filter(e=>e.idx>=t),i=new Set(r.slice(-uo).map(e=>e.idx));return n.filter(e=>i.has(e.idx)||ho(e.msg))}function vo(e){let{messages:t,running:n,composerActive:r,booted:i,onPickerSubmit:a}=e,o=g.useRef(null),s=g.useRef(null);s.current===null&&i&&(s.current=t.length);let c=s.current??t.length,[l,u]=g.useState(!1),[d,f]=g.useState(()=>new Set),[p,m]=g.useState(()=>new Set),h=g.useRef(new Map),_=_o(t,c),v=_.filter(e=>ho(e.msg)||!p.has(e.msg.id)),y=l||r||n,b=g.useCallback(e=>{if(po()){h.current.delete(e),m(t=>new Set(t).add(e));return}f(t=>new Set(t).add(e)),h.current.set(e,setTimeout(()=>{h.current.delete(e),m(t=>new Set(t).add(e)),f(t=>{let n=new Set(t);return n.delete(e),n})},lo))},[]),x=t.length-1,S=_.map(e=>e.msg.id).join(`,`),C=_.filter(e=>e.msg.role===`assistant`?!(e.idx===x&&e.msg.status===`streaming`):!0).map(e=>e.msg.id).join(`,`),w=_.filter(e=>ho(e.msg)).map(e=>e.msg.id).join(`,`);g.useEffect(()=>{let e=_o(t,c),n=new Set(e.map(e=>e.msg.id));for(let e of[...h.current.keys()])n.has(e)||(clearTimeout(h.current.get(e)),h.current.delete(e));if(y){for(let e of h.current.values())clearTimeout(e);h.current.clear(),f(e=>e.size?new Set:e);return}let r=t.length-1;for(let t of e)ho(t.msg)||p.has(t.msg.id)||d.has(t.msg.id)||h.current.has(t.msg.id)||(t.msg.role!==`assistant`||!(t.idx===r&&t.msg.status===`streaming`))&&h.current.set(t.msg.id,setTimeout(()=>b(t.msg.id),fo(t.msg.text??``)))},[S,C,w,y,p,d,n,b]),g.useEffect(()=>()=>{for(let e of h.current.values())clearTimeout(e);h.current.clear()},[]),g.useEffect(()=>{let e=o.current;e&&(e.scrollTop=e.scrollHeight)},[t.length,n,v.length]);let T=go(t);return(0,L.jsx)(`div`,{id:`chat-messages`,className:`chat-scroll`,ref:o,children:(0,L.jsx)(`div`,{className:`chat-bubbles`,onMouseEnter:()=>u(!0),onMouseLeave:()=>u(!1),children:v.map(e=>(0,L.jsx)(so,{msg:e.msg,fading:d.has(e.msg.id),interactive:ho(e.msg)&&e.msg.id===T,onPickerSubmit:a},e.msg.id))})})}function yo(e,t){for(let n of Array.from(e)){if(!n.type.startsWith(`image/`))continue;let e=new FileReader;e.onload=()=>{typeof e.result==`string`&&t({name:n.name,dataUrl:e.result})},e.readAsDataURL(n)}}function bo(e){return e.pending.length===0?null:(0,L.jsx)(`div`,{id:`chat-pending`,children:e.pending.map((t,n)=>(0,L.jsx)(`img`,{src:t.dataUrl,alt:t.name,title:`remove`,onClick:()=>e.onRemove(n)},`${t.name}-${n}`))})}function xo(e){return e.queued.length===0?null:(0,L.jsx)(`div`,{className:`chat-queue`,onMouseDown:e=>e.preventDefault(),children:e.queued.map((t,n)=>(0,L.jsxs)(`div`,{className:`queue-row`,children:[(0,L.jsx)(`span`,{className:`queue-snippet`,children:t.length>60?`${t.slice(0,60)}\u2026`:t}),(0,L.jsx)(`button`,{className:`queue-send-now`,type:`button`,tabIndex:-1,title:`Send now — interrupts the turn`,onClick:e.onInterrupt,children:`send now`}),(0,L.jsx)(`button`,{className:`queue-remove`,type:`button`,tabIndex:-1,title:`Remove from queue`,onClick:()=>e.onCancelQueued(n),children:`✕`})]},n))})}function So(e){let{running:t,queued:n,floating:r,expanded:i,revealed:a}=e,[o,s]=g.useState(``),[c,l]=g.useState(!1),[u,d]=g.useState(!1),[f,p]=g.useState([]),[m,h]=g.useState(!1);g.useEffect(()=>{t||h(!1)},[t]);let _=g.useRef(null),v=g.useRef(null),y=r&&!i,b=g.useCallback(()=>{let e=_.current;if(!e)return;e.style.height=`auto`;let t=Number.parseFloat(window.getComputedStyle(e).lineHeight),n=Number.isFinite(t)?Math.ceil(t):21,r=o.length===0?n:Math.min(e.scrollHeight,120);e.style.height=r>0?`${r}px`:``},[o]);g.useLayoutEffect(b,[b]),g.useLayoutEffect(()=>{y||(b(),requestAnimationFrame(()=>{b(),r&&i&&_.current?.focus()}))},[b,y,r,i]),g.useLayoutEffect(()=>{let e=v.current,t=e?.closest(`.shell-root`)??null;if(!e||!t)return;if(r){t.style.removeProperty(`--composer-reserve`);return}let n=()=>{t.style.setProperty(`--composer-reserve`,`${e.offsetHeight+7}px`)};n();let i=new ResizeObserver(n);return i.observe(e),()=>{i.disconnect(),t.style.removeProperty(`--composer-reserve`)}},[r]);let x=e=>{p(t=>t.length>=6?t:[...t,e])},S=()=>{let t=o.trim();!t&&f.length===0||(e.onSend(t,f),s(``),p([]))},C=o.trim().length>0||f.length>0,w=()=>{y&&e.onExpand()},T=()=>{r&&setTimeout(()=>{v.current?.contains(document.activeElement)||o.trim().length===0&&f.length===0&&e.onCollapse()},0)},ee=t&&!C;return(0,L.jsxs)(g.Fragment,{children:[(0,L.jsx)(bo,{pending:f,onRemove:e=>p(t=>t.filter((t,n)=>n!==e))}),(0,L.jsxs)(`div`,{className:`chat-input`+(y?` collapsed`:``)+(a?` revealed`:``),ref:v,onMouseEnter:r?e.onHoverEnter:void 0,onMouseLeave:r?e.onHoverLeave:void 0,children:[(0,L.jsx)(xo,{queued:n,onInterrupt:e.onInterrupt,onCancelQueued:e.onCancelQueued}),(0,L.jsxs)(`div`,{className:`ta`,onClick:w,children:[(0,L.jsx)(`span`,{className:`collapse-icon`,"aria-hidden":`true`,children:Ca}),(0,L.jsx)(`textarea`,{id:`chat-input`,className:`ta-text`,ref:_,rows:1,placeholder:t?`Queue a message…`:`Message the operator`,value:o,onBlur:T,onChange:e=>s(e.target.value),onPaste:e=>{let t=e.clipboardData?.files;t&&t.length>0&&(e.preventDefault(),yo(t,x))},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!e.metaKey&&!e.altKey&&(e.preventDefault(),S())}}),(0,L.jsxs)(`div`,{className:`ta-bottom`,onMouseDown:e=>e.preventDefault(),children:[(0,L.jsxs)(`div`,{className:`composer-settings`,children:[(0,L.jsxs)(`button`,{className:`composer-pill`+(c?` active`:``)+Wa(e.usage),type:`button`,tabIndex:-1,title:`Agent & model settings`,"aria-label":`Agent & model settings`,onMouseDown:e=>{e.preventDefault(),e.stopPropagation()},onClick:()=>l(e=>!e),children:[(0,L.jsx)(`span`,{className:`composer-pill-label`,children:ka(e.settings)}),xa]}),c?(0,L.jsx)(Ya,{settings:e.settings,warnings:e.settingsWarnings,usage:e.usage,accounts:e.accounts,onSetSetting:e.onSetSetting,onOpenKeys:()=>d(!0),onClose:()=>l(!1)}):null,u?(0,L.jsx)(Ja,{accounts:e.accounts,onSave:e.onSetCredential,onRemove:e.onClearCredential,onStartLogin:e.onStartLogin,onSubmitCode:e.onSubmitLoginCode,onCancelLogin:e.onCancelLogin,onLogout:e.onLogout,onClose:()=>d(!1)}):null]}),(0,L.jsx)(`button`,{id:`chat-send`,className:`send${ee?` stop`:``}`,type:`button`,tabIndex:-1,title:ee?m?`Stopping…`:`Stop`:`Send`,disabled:!ee&&!C||ee&&m,onClick:()=>{ee?(h(!0),e.onInterrupt()):S()},children:ee?ba:ya})]})]})]})]})}function Co(e){let t=ao(e.tasks);return t.length===0?null:(0,L.jsx)(`div`,{className:`operator-gutter`,onMouseEnter:e.onHoverEnter,onMouseLeave:e.onHoverLeave,children:(0,L.jsx)(`div`,{className:`task-stack`,children:t.map(t=>(0,L.jsx)(ro,{task:t,feed:e.feeds[t.id],onAck:e.onAck,open:e.openTasks.has(t.id),onToggle:()=>e.onToggleTask(t.id)},t.id))})})}function wo(e){let t=g.useRef(null),n=g.useCallback(()=>{t.current!==null&&(clearTimeout(t.current),t.current=null)},[]),r=g.useCallback(()=>{n(),e(!0)},[n,e]),i=g.useCallback(()=>{n(),t.current=window.setTimeout(()=>e(!1),300)},[n,e]);return g.useEffect(()=>()=>n(),[n]),{revealEnter:r,revealLeave:i}}var To=100;function Eo(e,t,n){return g.useCallback(r=>{r.preventDefault();let i=r.currentTarget,a=r.pointerId;try{i.setPointerCapture(a)}catch{}let o=new AbortController,s=()=>{o.abort();try{i.releasePointerCapture(a)}catch{}document.body.classList.remove(`operator-resizing`)};i.addEventListener(`pointermove`,r=>{if(r.clientX<t){s(),n();return}e(r.clientX)},{signal:o.signal}),i.addEventListener(`pointerup`,s,{signal:o.signal}),i.addEventListener(`pointercancel`,s,{signal:o.signal}),document.body.classList.add(`operator-resizing`)},[e,t,n])}function Do(e){let{floating:t}=e;return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`button`,{className:`operator-avatar`+(e.hasActiveTasks?` active`:``),type:`button`,tabIndex:-1,title:t?`Dock the chat panel`:`Float the chat panel`,"aria-label":`Toggle chat layout`,onClick:()=>e.setFloating(!t),onMouseEnter:t?e.onHoverEnter:void 0,onMouseLeave:t?e.onHoverLeave:void 0,children:(0,L.jsx)(`img`,{className:`operator-avatar-img`,src:Sa,alt:``,"aria-hidden":`true`,draggable:!1})}),t?null:(0,L.jsx)(`div`,{className:`operator-resize`,role:`separator`,"aria-label":`Resize chat panel`,"aria-orientation":`vertical`,"aria-valuenow":e.columnWidth,"aria-valuemin":e.minWidth,"aria-valuemax":e.maxWidth,onPointerDown:e.onStartResize})]})}function Oo(e){let{agent:t,floating:n,setFloating:r,columnWidth:i,setColumnWidth:a,minWidth:o,maxWidth:s}=e,{messages:c,tasks:l,feeds:u,settings:d,running:f,queued:p,booted:m}=t,[h,_]=g.useState(!1),[v,y]=g.useState(!1),[b,x]=g.useState(!1),[S,C]=g.useState(()=>new Set);g.useEffect(()=>{n&&(_(!1),y(!1),x(!1),C(new Set))},[n]);let w=b||S.size>0,{revealEnter:T,revealLeave:ee}=wo(y),E=g.useCallback(e=>{C(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),te=g.useCallback(()=>{_(!0),C(new Set)},[]),D=g.useCallback(()=>r(!0),[r]),O=Eo(a,o-To,D),k=(e,n,r)=>{t.submitPicker(e.id,n,r)},ne=l.some(e=>e.status===`running`);return(0,L.jsxs)(`div`,{id:`chat-host`,className:[n&&w?`rail-engaged`:``,n&&h?`chat-expanded`:``].filter(Boolean).join(` `),children:[n?(0,L.jsx)(vo,{messages:c,running:f,composerActive:h,booted:m,onPickerSubmit:k}):(0,L.jsxs)(`div`,{className:`operator-inset`,children:[(0,L.jsx)(oo,{tasks:l,feeds:u,onAck:t.ackTask}),ao(l).length>0?(0,L.jsx)(`div`,{className:`chat-divider`,"aria-hidden":`true`}):null,(0,L.jsx)(co,{messages:c,onPickerSubmit:k})]}),(0,L.jsx)(So,{running:f,queued:p,onSend:t.sendUserMessage,onInterrupt:t.interrupt,onCancelQueued:t.cancelQueued,floating:n,expanded:h,revealed:v,onExpand:te,onCollapse:()=>_(!1),onHoverEnter:T,onHoverLeave:ee,settings:d,settingsWarnings:t.settingsWarnings,usage:t.usage,accounts:t.accounts,onSetSetting:t.setSetting,onSetCredential:t.setCredential,onClearCredential:t.clearCredential,onStartLogin:t.startLogin,onSubmitLoginCode:t.submitLoginCode,onCancelLogin:t.cancelLogin,onLogout:t.logout}),n?(0,L.jsx)(Co,{tasks:l,feeds:u,openTasks:S,onToggleTask:E,onAck:t.ackTask,onHoverEnter:()=>x(!0),onHoverLeave:()=>x(!1)}):null,(0,L.jsx)(Do,{floating:n,setFloating:r,hasActiveTasks:ne,onHoverEnter:T,onHoverLeave:ee,columnWidth:i,minWidth:o,maxWidth:s,onStartResize:O})]})}var ko=class extends g.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e){console.error(`[panel error]`,e)}render(){return this.state.error?(0,L.jsxs)(`div`,{className:`panel-error`,children:[(0,L.jsx)(`div`,{className:`panel-error-title`,children:`this panel hit an error`}),(0,L.jsx)(`pre`,{className:`panel-error-msg`,children:this.state.error.message}),(0,L.jsx)(`button`,{type:`button`,className:`panel-error-retry`,onClick:()=>this.setState({error:null}),children:`retry`})]}):this.props.children}};function Ao(e){return function(t){return(0,L.jsx)(ko,{children:(0,L.jsx)(e,{...t})})}}var jo=`useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict`,Mo=(e=21)=>{let t=``,n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+=jo[n[e]&63];return t},No={width:15,height:15,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},Po=(0,L.jsxs)(`svg`,{...No,children:[(0,L.jsx)(`polyline`,{points:`4 17 10 11 4 5`}),(0,L.jsx)(`line`,{x1:`12`,y1:`19`,x2:`20`,y2:`19`})]}),Fo=(0,L.jsx)(`svg`,{...No,children:(0,L.jsx)(`path`,{d:`M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`})}),Io=(0,L.jsx)(`svg`,{...No,children:(0,L.jsx)(`polygon`,{points:`6 4 20 12 6 20 6 4`})}),Lo=(0,L.jsxs)(`svg`,{...No,width:16,height:16,children:[(0,L.jsx)(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`}),(0,L.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`})]}),Ro=(0,L.jsxs)(`svg`,{...No,width:15,height:15,children:[(0,L.jsx)(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`}),(0,L.jsx)(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`})]}),zo=[{label:`Files`,icon:Fo,kind:`files`,mode:`singleton`,title:`Files`},{label:`Play`,icon:Io,kind:`playtest`,mode:`singleton`,title:`Play`},{label:`Terminal`,icon:Po,kind:`terminal`,mode:`spawn`,title:`Terminal`}];function Bo(e,t,n){if(t.mode===`singleton`){let r=e.getPanel(t.kind);if(r){r.api.setActive();return}e.addPanel({id:t.kind,component:t.kind,title:t.title??t.label,position:n?{referenceGroup:n}:void 0});return}let r=t.title??t.label,i=e.panels.filter(e=>e.id===t.kind||e.id.startsWith(`${t.kind}-`)),a=0;for(let e of i){let t=e.title??``;if(t===r)a=Math.max(a,1);else if(t.startsWith(`${r} `)){let e=Number.parseInt(t.slice(r.length+1),10);Number.isFinite(e)&&(a=Math.max(a,e))}}let o=a+1,s=o>1?`${r} ${o}`:r;e.addPanel({id:`${t.kind}-${Mo(6)}`,component:t.kind,title:s,position:n?{referenceGroup:n}:void 0})}function Vo(e){let[t,n]=g.useState(!1),r=g.useRef(null),i=g.useRef(null),[a,o]=g.useState({top:0,left:0}),s=g.useCallback(()=>{let e=r.current?.getBoundingClientRect();e&&o({top:e.bottom+4,left:e.right}),n(e=>!e)},[]);g.useEffect(()=>{if(!t)return;let e=e=>{r.current?.contains(e.target)||i.current?.contains(e.target)||n(!1)},a=e=>{e.key===`Escape`&&n(!1)};return document.addEventListener(`mousedown`,e),document.addEventListener(`keydown`,a),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`keydown`,a)}},[t]);let c=t=>{Bo(e.containerApi,t,e.group),n(!1)},[,l]=g.useReducer(e=>e+1,0);return g.useEffect(()=>{let t=e.containerApi.onDidLayoutChange(()=>l());return()=>t.dispose()},[e.containerApi]),(0,L.jsxs)(`div`,{className:`dv-add-panel`,children:[e.group.panels.length===0?(0,L.jsx)(`button`,{type:`button`,className:`dv-add-panel-btn`,title:`Close group`,"aria-label":`Close group`,onClick:()=>e.group.api.close(),children:Ro}):null,(0,L.jsx)(`button`,{ref:r,type:`button`,className:`dv-add-panel-btn`,title:`New panel`,"aria-label":`New panel`,"aria-haspopup":`menu`,"aria-expanded":t,onClick:s,children:Lo}),t&&(0,Qn.createPortal)((0,L.jsx)(`div`,{ref:i,className:`dv-add-panel-menu`,role:`menu`,style:{top:a.top,left:a.left},children:zo.map(e=>(0,L.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`dv-add-panel-item`,onClick:()=>c(e),children:[(0,L.jsx)(`span`,{className:`dv-add-panel-item-icon`,children:e.icon}),(0,L.jsx)(`span`,{className:`dv-add-panel-item-label`,children:e.label})]},e.label))}),document.body)]})}var Ho=`/__castle/files/`,Uo=null;function Wo(e){Uo=e}function Go(){return Uo?.fileTypes??null}function Ko(){return Uo?.defaultPlayFile??null}var qo={deckId:null,kitEditorExtensions:[],fileTypes:null,defaultPlayFile:null,initialPanels:null};async function Jo(){try{let e=await fetch(`${Ho}info`);if(!e.ok)return qo;let t=await e.json(),n=t.kitEditorExtensions;return{deckId:typeof t.deckId==`string`&&t.deckId.length>0?t.deckId:null,kitEditorExtensions:Array.isArray(n)&&n.every(e=>typeof e==`string`)?n:[],fileTypes:Array.isArray(t.fileTypes)?t.fileTypes:null,defaultPlayFile:typeof t.defaultPlayFile==`string`&&t.defaultPlayFile?t.defaultPlayFile:null,initialPanels:Array.isArray(t.initialPanels)?t.initialPanels:null}}catch{return qo}}function Yo(e){return e===`imports`||e.startsWith(`imports/`)}async function Xo(){try{let e=await fetch(`${Ho}imports`);return e.ok?(await e.json()).imports??[]:[]}catch{return[]}}async function Zo(e){let t=await fetch(`${Ho}update-import`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({alias:e})});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`Update failed (${t.status})`)}}function Qo(e){let t=e.split(`/`).pop()??e;if(!Yo(e))return t;let n=e.split(`/`)[1];return n?`${n}:${t}`:t}async function $o(e=!1){let t=await fetch(`${Ho}list${e?`?all=1`:``}`);if(!t.ok)throw Error(`list failed: ${t.status}`);let n=await t.json();return Array.isArray(n.files)?n.files:[]}async function es(e){await as(`mkdir`,{path:e})}async function ts(e){let t=await fetch(`${Ho}read?path=${encodeURIComponent(e)}`);if(t.status===404)throw new cs(e);if(!t.ok)throw Error(`read failed: ${t.status}`);let n=await t.json();return typeof n.contents==`string`?n.contents:``}async function ns(e,t){let n=await fetch(`${Ho}write`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({path:e,contents:t})});if(!n.ok){let e=`write failed: ${n.status}`;try{let t=await n.json();typeof t.error==`string`&&(e=t.error)}catch{}throw Error(e)}}async function rs(e,t){await as(`rename`,{from:e,to:t})}async function is(e){await as(`delete`,{path:e})}async function as(e,t){let n=await fetch(`${Ho}${e}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify(t)});if(!n.ok){let t=`${e} failed: ${n.status}`;try{let e=await n.json();typeof e.error==`string`&&(t=e.error)}catch{}throw Error(t)}}function os(e){let t=(e.split(`/`).pop()??e).replace(/\.[^.]+$/,``);switch(ls(e)){case`.scene`:return`${JSON.stringify({background:`#1a1932`,actors:[],name:t||`Scene`},null,2)}\n`;case`.pxart`:return`${JSON.stringify({format:`full`,resolution:{width:16,height:16},palette:[],frames:[{}],layers:[{id:`layer-0`,name:`Layer 1`,visible:!0,opacity:1,blendMode:`normal`,kind:`pixel`,cells:[null]}]},null,2)}\n`;case`.jsx`:return ss(t);default:return``}}function ss(e){let t=/^[A-Za-z_$][\w$]*$/.test(e)?e:`Behavior`;return[`export class ${t} {`,` static behaviorName = '${t}';`,``,` static defaultProps = {};`,``,` constructor(props) {`,` this.props = props;`,` }`,``,` // Called every frame in play mode. dt is seconds.`,` update(actor, scene, dt) {}`,`}`,``].join(`
76
76
  `)}var cs=class extends Error{constructor(e){super(`Not found: ${e}`),this.name=`FileNotFound`}};function ls(e){let t=e.split(`/`).pop()??e,n=t.lastIndexOf(`.`);return n<=0?``:t.slice(n).toLowerCase()}function us(e){return e.split(`/`).pop()??e}function ds(e){let t=e.lastIndexOf(`/`);return t<0?``:e.slice(0,t)}function fs(e,t){return e?`${e}/${t}`:t}var ps=[{type:`files`},{type:`playtest`}],ms=230,hs=300;function gs(e){return Array.isArray(e.tabs)}function _s(e){return Array.isArray(e.column)}function vs(e){return gs(e)?e.tabs??[]:[e]}function ys(e){switch(e.type){case`files`:return{id:`files`,component:`files`,title:`Files`};case`playtest`:return{id:`playtest`,component:`playtest`,title:`Play`};case`terminal`:return{id:`terminal`,component:`terminal`,title:`Terminal`};case`editor`:return e.file?{id:`editor:${e.file}`,component:`editor`,title:Qo(e.file),params:{file:e.file}}:null;default:return null}}function bs(e,t){return typeof t==`number`&&t>0?t:e.some(e=>vs(e).some(e=>e.type===`files`))?ms:void 0}function xs(e,t,n,r,i){let a=null;for(let o of vs(t)){let t=ys(o);if(!t||e.getPanel(t.id))continue;let s=a===null,c=s?n:{referencePanel:a,direction:`within`},l=s&&r!==void 0?{minimumWidth:r,maximumWidth:r}:{},u=e.addPanel({...t,...l,position:c});a||=u.id,i(u,o)}return a}function Ss(e,t){let n=t.map(e=>_s(e)?{cells:e.column??[],width:e.width}:{cells:[e],width:void 0}),r=null,i=(e,t)=>{(!r||t.type===`editor`&&!r.startsWith(`editor:`))&&(r=e.id)},a=n.map(()=>null),o=[],s=null;n.forEach((t,n)=>{if(t.cells.length===0)return;let r=s?{referencePanel:s,direction:`right`}:void 0,c=bs(t.cells,t.width),l=xs(e,t.cells[0],r,c,i);a[n]=l,l&&(s=l,c!==void 0&&o.push(l))}),n.forEach((t,n)=>{let r=a[n];for(let n=1;n<t.cells.length&&r;n++){let a=xs(e,t.cells[n],{referencePanel:r,direction:`below`},void 0,i);a&&(r=a)}}),r&&e.getPanel(r)?.api.setActive(),Cs(e,o)}function Cs(e,t){if(t.length===0)return;let n=null,r=!1,i=null,a=()=>{if(!r){r=!0,n&&clearTimeout(n),i?.dispose();for(let n of t)e.getPanel(n)?.group.api.setConstraints({minimumWidth:150,maximumWidth:2**53-1})}},o=()=>{r||e.width<=0||(n&&clearTimeout(n),n=setTimeout(a,hs))};i=e.onDidLayoutChange(o),typeof requestAnimationFrame==`function`?requestAnimationFrame(o):setTimeout(o,0)}function ws(e){e.getPanel(`files`)?.group.api.setConstraints({minimumWidth:150,maximumWidth:2**53-1})}function Ts(e,t){let n=`editor:${t}`,r=e.getPanel(n);if(r){r.api.setActive();return}let i={id:n,component:`editor`,title:Qo(t),params:{file:t}},a=e.activeGroup;if(a&&a.panels.length===0){e.addPanel({...i,position:{referenceGroup:a,direction:`within`}});return}let o=e.panels.find(e=>e.id.startsWith(`editor:`));e.addPanel({...i,position:o?{referencePanel:o.id,direction:`within`}:void 0})}function Es(e,t){let n={files:`Files`,playtest:`Play`,terminal:`Terminal`},r=e.activeGroup,i=!!r&&r.panels.length===0,a=e.panels.find(e=>e.id===t||e.id.startsWith(`${t}-`));if(!i&&a){a.api.setActive();return}let o=a?`${t}-${Mo(6)}`:t;e.addPanel({id:o,component:t,title:n[t]??t,position:i&&r?{referenceGroup:r,direction:`within`}:void 0})}function Ds(e,t){let n=!t||t===`scenes/main.scene`,r=n?`playtest`:`playtest:${t}`,i=e.getPanel(r);if(i){i.api.setActive();return}let a=e.panels.find(e=>e.id===`playtest`||e.id.startsWith(`playtest`));e.addPanel({id:r,component:`playtest`,title:n?`Play`:`Play: ${us(t)}`,params:n?{}:{scene:t},position:a?{referencePanel:a.id,direction:`within`}:void 0})}function Os(e,t){e.getPanel(`editor:${t}`)?.api.close()}var ks=2e3,As=new Set,js=null,Ms=null;function Ns(e){return As.add(e),Ps(),()=>As.delete(e)}function Ps(){if(js||Ms)return;let e=location.protocol===`https:`?`wss:`:`ws:`,t=new WebSocket(`${e}//${location.host}/__castle/ws`);js=t,t.onmessage=e=>{try{Fs(JSON.parse(e.data))}catch{}},t.onclose=()=>{js=null,Ms=setTimeout(()=>{Ms=null,As.size>0&&Ps()},ks)},t.onerror=()=>t.close()}function Fs(e){if(e.type!==`files_changed`||!Array.isArray(e.changes))return;let t=[];for(let n of e.changes){if(typeof n?.path!=`string`)continue;let e=n.event;e!==`add`&&e!==`change`&&e!==`delete`||t.push({path:n.path,event:e,affected:Array.isArray(n.affected)?n.affected.filter(e=>typeof e==`string`):[]})}if(t.length===0)return;let n={changes:t,affected:Array.isArray(e.affected)?e.affected.filter(e=>typeof e==`string`):[]};for(let e of As)try{e(n)}catch{}}var Is=g.createContext(null),Ls=Is.Provider;function Rs(){let e=g.useContext(Is);if(!e)throw Error(`PanelHostContext missing`);return e}var zs={prefix:`fas`,iconName:`arrow-circle-up`,icon:[512,512,[],`f0aa`,`M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm143.6 28.9l72.4-75.5V392c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V209.4l72.4 75.5c9.3 9.7 24.8 9.9 34.3.4l10.9-11c9.4-9.4 9.4-24.6 0-33.9L273 107.7c-9.4-9.4-24.6-9.4-33.9 0L106.3 240.4c-9.4 9.4-9.4 24.6 0 33.9l10.9 11c9.6 9.5 25.1 9.3 34.4-.4z`]},Bs={prefix:`fas`,iconName:`arrow-right`,icon:[448,512,[],`f061`,`M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z`]},Vs={prefix:`fas`,iconName:`chevron-down`,icon:[448,512,[],`f078`,`M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z`]},Hs={prefix:`fas`,iconName:`chevron-right`,icon:[320,512,[],`f054`,`M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z`]},Us={prefix:`fas`,iconName:`clone`,icon:[512,512,[],`f24d`,`M464 0c26.51 0 48 21.49 48 48v288c0 26.51-21.49 48-48 48H176c-26.51 0-48-21.49-48-48V48c0-26.51 21.49-48 48-48h288M176 416c-44.112 0-80-35.888-80-80V128H48c-26.51 0-48 21.49-48 48v288c0 26.51 21.49 48 48 48h288c26.51 0 48-21.49 48-48v-48H176z`]},Ws={prefix:`fas`,iconName:`code`,icon:[640,512,[],`f121`,`M278.9 511.5l-61-17.7c-6.4-1.8-10-8.5-8.2-14.9L346.2 8.7c1.8-6.4 8.5-10 14.9-8.2l61 17.7c6.4 1.8 10 8.5 8.2 14.9L293.8 503.3c-1.9 6.4-8.5 10.1-14.9 8.2zm-114-112.2l43.5-46.4c4.6-4.9 4.3-12.7-.8-17.2L117 256l90.6-79.7c5.1-4.5 5.5-12.3.8-17.2l-43.5-46.4c-4.5-4.8-12.1-5.1-17-.5L3.8 247.2c-5.1 4.7-5.1 12.8 0 17.5l144.1 135.1c4.9 4.6 12.5 4.4 17-.5zm327.2.6l144.1-135.1c5.1-4.7 5.1-12.8 0-17.5L492.1 112.1c-4.8-4.5-12.4-4.3-17 .5L431.6 159c-4.6 4.9-4.3 12.7.8 17.2L523 256l-90.6 79.7c-5.1 4.5-5.5 12.3-.8 17.2l43.5 46.4c4.5 4.9 12.1 5.1 17 .6z`]},Gs={prefix:`fas`,iconName:`eye`,icon:[576,512,[],`f06e`,`M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z`]},Ks={prefix:`fas`,iconName:`file`,icon:[384,512,[],`f15b`,`M224 136V0H24C10.7 0 0 10.7 0 24v464c0 13.3 10.7 24 24 24h336c13.3 0 24-10.7 24-24V160H248c-13.2 0-24-10.8-24-24zm160-14.1v6.1H256V0h6.1c6.4 0 12.5 2.5 17 7l97.9 98c4.5 4.5 7 10.6 7 16.9z`]},qs={prefix:`fas`,iconName:`folder`,icon:[512,512,[],`f07b`,`M464 128H272l-64-64H48C21.49 64 0 85.49 0 112v288c0 26.51 21.49 48 48 48h416c26.51 0 48-21.49 48-48V176c0-26.51-21.49-48-48-48z`]},Js={prefix:`fas`,iconName:`folder-plus`,icon:[512,512,[],`f65e`,`M464,128H272L208,64H48A48,48,0,0,0,0,112V400a48,48,0,0,0,48,48H464a48,48,0,0,0,48-48V176A48,48,0,0,0,464,128ZM359.5,296a16,16,0,0,1-16,16h-64v64a16,16,0,0,1-16,16h-16a16,16,0,0,1-16-16V312h-64a16,16,0,0,1-16-16V280a16,16,0,0,1,16-16h64V200a16,16,0,0,1,16-16h16a16,16,0,0,1,16,16v64h64a16,16,0,0,1,16,16Z`]},Ys={prefix:`fas`,iconName:`globe`,icon:[496,512,[],`f0ac`,`M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z`]},Xs={prefix:`fas`,iconName:`layer-group`,icon:[512,512,[],`f5fd`,`M12.41 148.02l232.94 105.67c6.8 3.09 14.49 3.09 21.29 0l232.94-105.67c16.55-7.51 16.55-32.52 0-40.03L266.65 2.31a25.607 25.607 0 0 0-21.29 0L12.41 107.98c-16.55 7.51-16.55 32.53 0 40.04zm487.18 88.28l-58.09-26.33-161.64 73.27c-7.56 3.43-15.59 5.17-23.86 5.17s-16.29-1.74-23.86-5.17L70.51 209.97l-58.1 26.33c-16.55 7.5-16.55 32.5 0 40l232.94 105.59c6.8 3.08 14.49 3.08 21.29 0L499.59 276.3c16.55-7.5 16.55-32.5 0-40zm0 127.8l-57.87-26.23-161.86 73.37c-7.56 3.43-15.59 5.17-23.86 5.17s-16.29-1.74-23.86-5.17L70.29 337.87 12.41 364.1c-16.55 7.5-16.55 32.5 0 40l232.94 105.59c6.8 3.08 14.49 3.08 21.29 0L499.59 404.1c16.55-7.5 16.55-32.5 0-40z`]},Zs={prefix:`fas`,iconName:`pen`,icon:[512,512,[],`f304`,`M290.74 93.24l128.02 128.02-277.99 277.99-114.14 12.6C11.35 513.54-1.56 500.62.14 485.34l12.7-114.22 277.9-277.88zm207.2-19.06l-60.11-60.11c-18.75-18.75-49.16-18.75-67.91 0l-56.55 56.55 128.02 128.02 56.55-56.55c18.75-18.76 18.75-49.16 0-67.91z`]},Qs={prefix:`fas`,iconName:`plus`,icon:[448,512,[],`f067`,`M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z`]},$s={prefix:`fas`,iconName:`sync-alt`,icon:[512,512,[],`f2f1`,`M370.72 133.28C339.458 104.008 298.888 87.962 255.848 88c-77.458.068-144.328 53.178-162.791 126.85-1.344 5.363-6.122 9.15-11.651 9.15H24.103c-7.498 0-13.194-6.807-11.807-14.176C33.933 94.924 134.813 8 256 8c66.448 0 126.791 26.136 171.315 68.685L463.03 40.97C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.749zM32 296h134.059c21.382 0 32.09 25.851 16.971 40.971l-41.75 41.75c31.262 29.273 71.835 45.319 114.876 45.28 77.418-.07 144.315-53.144 162.787-126.849 1.344-5.363 6.122-9.15 11.651-9.15h57.304c7.498 0 13.194 6.807 11.807 14.176C478.067 417.076 377.187 504 256 504c-66.448 0-126.791-26.136-171.315-68.685L48.97 471.03C33.851 486.149 8 475.441 8 454.059V320c0-13.255 10.745-24 24-24z`]},ec={prefix:`fas`,iconName:`trash`,icon:[448,512,[],`f1f8`,`M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z`]};function tc(...e){return e.filter(Boolean).join(` `)}var nc={fileBrowserBare:`fileBrowserBare`,fileTree:`fileTree`,fileBranch:`fileBranch`,fileDirRow:`fileDirRow`,fileRow:`fileRow`,fileRowSelected:`fileRowSelected`,fileRowImported:`fileRowImported`,fileImportUpdate:`fileImportUpdate`,fileLabel:`fileLabel`,fileIcon:`fileIcon`,fileDisclosure:`fileDisclosure`,mainEditor:`mainEditor`,editorBody:`editorBody`,codeEditor:`codeEditor`,codeMirrorHost:`codeMirrorHost`},rc={"arrow-circle-up":zs,"arrow-right":Bs,"chevron-down":Vs,"chevron-right":Hs,clone:Us,code:Ws,eye:Gs,file:Ks,folder:qs,"folder-plus":Js,globe:Ys,"layer-group":Xs,pen:Zs,plus:Qs,trash:ec};function ic(e){let t=rc[e.name];if(!t)return null;let[n,r,,,i]=t.icon,a=Array.isArray(i)?i.join(` `):i;return(0,L.jsx)(`svg`,{viewBox:`0 0 ${n} ${r}`,"aria-hidden":`true`,style:{width:`1em`,height:`1em`,display:`inline-block`,fill:`currentColor`},children:(0,L.jsx)(`path`,{d:a})})}function ac(e){return Yo(e)&&e.split(`/`).length<=2}function oc(e){return new Set(gc(e).filter(e=>!ac(e)))}function sc(e){let{files:t,selectedPath:n,onSelect:r,onContextMenu:i,edit:a,outdatedImports:o}=e,{onUpdateImport:s}=e,c=a?.mode===`create`&&a.dir?a.dir:null,l=g.useMemo(()=>fc(Object.keys(t),c),[t,c]),[u,d]=g.useState(()=>oc(l)),f=g.useRef(new Set(gc(l)));g.useEffect(()=>{let e=gc(l);d(t=>{let n=!1,r=new Set(t);for(let t of e)!f.current.has(t)&&!ac(t)&&(r.add(t),n=!0);return f.current=new Set(e),n?r:t})},[l]),g.useEffect(()=>{a?.mode===`create`&&a.dir&&d(e=>e.has(a.dir)?e:new Set(e).add(a.dir))},[a]);function p(e){d(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})}let m=a?.mode===`create`?a:null;return(0,L.jsx)(`div`,{className:nc.fileBrowserBare,onContextMenu:e=>{i?.(e,{type:`root`,path:``})},children:(0,L.jsxs)(`div`,{className:nc.fileTree,children:[(l.children??[]).map(e=>(0,L.jsx)(cc,{node:e,depth:0,expanded:u,selectedPath:n,onSelect:r,onToggle:p,onContextMenu:i,edit:a,outdatedImports:o,onUpdateImport:s},e.path)),m&&m.dir===``?(0,L.jsx)(lc,{depth:0,initial:``,edit:m}):null]})})}function cc(e){let{node:t,depth:n,expanded:r,selectedPath:i,onSelect:a,onToggle:o,onContextMenu:s,edit:c}=e,{outdatedImports:l,onUpdateImport:u}=e,d={"--file-depth":n};if(t.type===`directory`){let e=r.has(t.path),f=c?.mode===`create`&&c.dir===t.path;return(0,L.jsxs)(`div`,{className:nc.fileBranch,children:[(0,L.jsx)(`button`,{className:nc.fileDirRow,style:d,onClick:()=>o(t.path),onContextMenu:e=>{e.stopPropagation(),!Yo(t.path)&&s?.(e,{type:`directory`,path:t.path})},children:(0,L.jsxs)(`span`,{className:nc.fileLabel,children:[(0,L.jsx)(`span`,{className:tc(nc.fileIcon,nc.fileDisclosure),children:(0,L.jsx)(ic,{name:e?`chevron-down`:`chevron-right`})}),(0,L.jsx)(`span`,{children:t.name}),l?.has(uc(t.path))?(0,L.jsx)(`span`,{role:`button`,tabIndex:0,className:nc.fileImportUpdate,title:`A newer version has been published -- click to update`,onClick:e=>{e.stopPropagation(),u?.(uc(t.path))},onKeyDown:e=>{e.key!==`Enter`&&e.key!==` `||(e.preventDefault(),e.stopPropagation(),u?.(uc(t.path)))},children:(0,L.jsx)(ic,{name:`arrow-circle-up`})}):null]})}),e?(0,L.jsxs)(`div`,{children:[(t.children??[]).map(e=>(0,L.jsx)(cc,{node:e,depth:n+1,expanded:r,selectedPath:i,onSelect:a,onToggle:o,onContextMenu:s,edit:c,outdatedImports:l,onUpdateImport:u},e.path)),f?(0,L.jsx)(lc,{depth:n+1,initial:``,edit:c}):null]}):null]})}if(c?.mode===`rename`&&c.path===t.path)return(0,L.jsx)(lc,{depth:n,initial:us(t.path),edit:c});let f=Yo(t.path);return(0,L.jsx)(`button`,{className:tc(nc.fileRow,i===t.path&&nc.fileRowSelected,f&&nc.fileRowImported),style:d,onClick:()=>a(t.path),onContextMenu:e=>{e.stopPropagation(),!f&&s?.(e,{type:`file`,path:t.path})},children:(0,L.jsxs)(`span`,{className:nc.fileLabel,children:[(0,L.jsx)(`span`,{className:nc.fileIcon,children:(0,L.jsx)(ic,{name:dc(t.path)})}),(0,L.jsx)(`span`,{children:us(t.path)})]})})}function lc(e){let{depth:t,initial:n,edit:r}=e,[i,a]=g.useState(n),o=g.useRef(null),s=g.useRef(!1),c={"--file-depth":t};return g.useEffect(()=>{let e=o.current;if(!e)return;e.focus();let t=e.value.lastIndexOf(`.`);t>0?e.setSelectionRange(0,t):e.select()},[]),g.useEffect(()=>{r.error&&o.current?.focus()},[r.error]),(0,L.jsxs)(`div`,{className:tc(nc.fileRow,`fileEditRow`),style:c,children:[(0,L.jsxs)(`span`,{className:nc.fileLabel,children:[(0,L.jsx)(`span`,{className:nc.fileIcon,children:(0,L.jsx)(ic,{name:r.mode===`rename`?`pen`:`file`})}),(0,L.jsx)(`input`,{ref:o,className:`fileEditInput`,value:i,spellCheck:!1,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`Enter`?(e.preventDefault(),r.onCommit(i)):e.key===`Escape`&&(e.preventDefault(),s.current=!0,r.onCancel())},onBlur:()=>{s.current||r.onCommit(i)}}),r.suffix?(0,L.jsx)(`span`,{className:`fileEditSuffix`,children:r.suffix}):null]}),r.error?(0,L.jsx)(`span`,{className:`fileEditError`,children:r.error}):null]})}function uc(e){let t=e.split(`/`);return t.length===2&&Yo(e)?t[1]:``}function dc(e){return e.endsWith(`.pxart`)?`layer-group`:e.endsWith(`.scene`)?`globe`:e.endsWith(`.jsx`)?`code`:`file`}function fc(e,t){let n={type:`directory`,name:``,path:``,children:[],childMap:new Map};for(let t of e){let e=t.split(`/`),r=n;for(let t=0;t<e.length;t++){let n=e[t],i=e.slice(0,t+1).join(`/`),a=t===e.length-1;if(!r.childMap?.has(n)){let e=a?{type:`file`,name:n,path:i}:{type:`directory`,name:n,path:i,children:[],childMap:new Map};r.childMap?.set(n,e),r.children?.push(e)}let o=r.childMap?.get(n);if(!o||o.type!==`directory`)break;r=o}}return t&&pc(n,t),mc(n),hc(n),n}function pc(e,t){let n=e,r=t.split(`/`);for(let e=0;e<r.length;e++){let t=r[e],i=r.slice(0,e+1).join(`/`),a=n.childMap?.get(t);if(a||(a={type:`directory`,name:t,path:i,children:[],childMap:new Map},n.childMap?.set(t,a),n.children?.push(a)),a.type!==`directory`)return;n=a}}function mc(e){if(e.type===`directory`){for(let t of e.children??[])mc(t);delete e.childMap}}function hc(e){let t=e=>e===`imports`?0:e===`drawings`?1:e===`scenes`?2:e===`behaviors`?3:4;e.children?.sort((e,n)=>t(e.name)-t(n.name)||e.name.localeCompare(n.name))}function gc(e){return e.type===`directory`?[...e.path?[e.path]:[],...(e.children??[]).flatMap(e=>gc(e))]:[]}function _c(e,t){g.useEffect(()=>{let n=n=>{e.current?.contains(n.target)||t()},r=e=>{e.key===`Escape`&&t()};return document.addEventListener(`mousedown`,n),document.addEventListener(`keydown`,r),()=>{document.removeEventListener(`mousedown`,n),document.removeEventListener(`keydown`,r)}},[e,t])}var vc=8;function yc(e,t,n=[]){let[r,i]=g.useState({top:t.y,left:t.x});return g.useLayoutEffect(()=>{let n=e.current;if(!n)return;let r=n.getBoundingClientRect(),a=vc,{x:o,y:s}=t;o+r.width>window.innerWidth-a&&(o=Math.max(a,window.innerWidth-r.width-a)),s+r.height>window.innerHeight-a&&(s=Math.max(a,window.innerHeight-r.height-a)),i({top:s,left:o})},[e,t.x,t.y,...n]),r}var bc={label:`New file`,icon:`file`,ext:``};function xc(){let e=Go();return e?[bc,...e.filter(e=>typeof e.new==`string`&&e.new).map(e=>({label:e.new,icon:e.icon??`file`,ext:e.ext}))]:[bc]}function Sc(e){let t=Rs(),[n,r]=g.useState(null),[i,a]=g.useState(null),[o,s]=g.useState(``),[c,l]=g.useState(!1),[u,d]=g.useState(new Set),[f,p]=g.useState(null),[m,h]=g.useState(null),_=g.useRef([]);_.current=n??[];let v=g.useRef(!1);v.current=c;let y=g.useCallback(()=>{$o(v.current).then(e=>{r(e),a(null)}).catch(e=>a(e instanceof Error?e.message:String(e))),Xo().then(e=>d(new Set(e.filter(e=>e.updateAvailable).map(e=>e.alias))))},[]),b=g.useCallback(()=>{v.current=!v.current,l(v.current),y()},[y]),{lifecycle:x}=e;g.useEffect(()=>{y();let e=x.onDidVisibilityChange(e=>{e&&y()}),t=Ns(e=>{e.changes.some(e=>e.event!==`change`)&&y()});return()=>{e(),t()}},[y,x]),g.useEffect(()=>{s(t.activeEditorPath??``)},[t.activeEditorPath]);let S=g.useCallback(e=>{s(e),t.openFile(e)},[t]),C=Tc({closeEditor:e=>t.closeEditor(e),refresh:y,onOpen:S,filesRef:_,selected:o,clearSelected:()=>s(``)}),w=g.useMemo(()=>Object.fromEntries((n??[]).map(e=>[e,``])),[n]),T=g.useMemo(()=>kc(n??[]),[n]);return(0,L.jsxs)(`div`,{className:`castle-file-panel`,children:[(0,L.jsxs)(`div`,{className:`castle-file-toolbar`,children:[(0,L.jsxs)(`button`,{type:`button`,className:`castle-file-new-btn`,onClick:C.openNewMenu,title:`New file`,children:[(0,L.jsx)(ic,{name:`plus`}),(0,L.jsx)(`span`,{children:`New`})]}),(0,L.jsx)(`button`,{type:`button`,className:tc(`castle-file-icon-btn`,c&&`active`),onClick:b,"aria-pressed":c,title:c?`Hide hidden files & folders`:`Show hidden files & folders`,children:(0,L.jsx)(ic,{name:`eye`})})]}),C.actionError?(0,L.jsxs)(`div`,{className:`castle-file-action-error`,role:`alert`,children:[(0,L.jsx)(`span`,{children:C.actionError}),(0,L.jsx)(`button`,{type:`button`,onClick:()=>C.setActionError(null),"aria-label":`Dismiss`,children:`×`})]}):null,i?(0,L.jsxs)(`div`,{className:`castle-code-overlay castle-code-error`,children:[`could not list files: `,i]}):(0,L.jsx)(sc,{files:w,selectedPath:o,onSelect:S,onContextMenu:C.onContextMenu,edit:C.edit,outdatedImports:u,onUpdateImport:p}),C.menu?(0,L.jsx)(R,{menu:C.menu,folders:T,showHidden:c,onClose:C.closeMenu,onCreate:C.startCreate,onMove:C.moveTo,onRename:C.startRename,onDuplicate:C.duplicate,onConfirmDelete:C.confirmDelete,onMakeFolder:C.makeFolder,onToggleHidden:b}):null,f?(0,L.jsx)(wc,{alias:f,busy:m===f,onCancel:()=>p(null),onConfirm:()=>{let e=f;h(e),Zo(e).then(()=>{p(null),y(),Cc()}).catch(e=>a(e instanceof Error?e.message:String(e))).finally(()=>h(null))}}):null]})}function Cc(){for(let e of Array.from(document.querySelectorAll(`iframe.deck-frame`))){let t=e;try{t.contentWindow?.location.reload()}catch{t.src=t.src}}}function wc(e){return(0,Qn.createPortal)((0,L.jsx)(`div`,{className:`castle-modal-scrim`,onClick:e.busy?void 0:e.onCancel,children:(0,L.jsxs)(`div`,{className:`castle-modal`,onClick:e=>e.stopPropagation(),children:[(0,L.jsxs)(`div`,{className:`castle-modal-text`,children:[`Update `,(0,L.jsx)(`b`,{children:e.alias}),` to the latest version?`]}),(0,L.jsxs)(`div`,{className:`castle-modal-actions`,children:[(0,L.jsx)(`button`,{type:`button`,onClick:e.onCancel,disabled:e.busy,children:`Cancel`}),(0,L.jsx)(`button`,{type:`button`,onClick:e.onConfirm,disabled:e.busy,children:e.busy?`Updating…`:`Update`})]})]})}),document.body)}function Tc(e){let{closeEditor:t,refresh:n,onOpen:r,filesRef:i,selected:a,clearSelected:o}=e,[s,c]=g.useState(null),[l,u]=g.useState(null),[d,f]=g.useState(null),p=g.useCallback((e,t,a)=>{let o=a.trim();if(!o)return u(null);let s=t&&!o.endsWith(t)?`${o}${t}`:o,c=fs(e,s);if(i.current.includes(c))return u(e=>e&&{...e,error:`“${s}” already exists`});ns(c,os(c)).then(()=>{u(null),n(),r(c)}).catch(e=>u(t=>t&&{...t,error:Oc(e)}))},[n,r,i]),m=g.useCallback((e,a)=>{let o=a.trim();if(!o||o===us(e))return u(null);let s=fs(ds(e),o);if(s.toLowerCase()!==e.toLowerCase()&&i.current.includes(s))return u(e=>e&&{...e,error:`“${o}” already exists`});rs(e,s).then(()=>{u(null),n(),t(e),r(s)}).catch(e=>u(t=>t&&{...t,error:Oc(e)}))},[n,r,i,t]),h=g.useCallback((e,t)=>{f(null),c(null),u({mode:`create`,dir:t,suffix:e.ext,error:null,onCommit:n=>p(t,e.ext,n),onCancel:()=>u(null)})},[p]),_=g.useCallback(e=>{f(null),c(null),u({mode:`rename`,dir:ds(e),path:e,suffix:``,error:null,onCommit:t=>m(e,t),onCancel:()=>u(null)})},[m]),v=g.useCallback(e=>{f(null),c(null),ts(e).then(t=>{let a=Ac(e,i.current);return ns(a,t).then(()=>{n(),r(a)})}).catch(e=>c(Oc(e)))},[n,r,i]),y=g.useCallback((e,a)=>{f(null),c(null);let o=fs(a,us(e));if(o!==e){if(i.current.includes(o))return c(`“${us(e)}” already exists in ${a||`root`}`);rs(e,o).then(()=>{n(),t(e),r(o)}).catch(e=>c(Oc(e)))}},[n,r,i,t]),b=g.useCallback(e=>{c(null),is(e).then(()=>{f(null),n(),t(e),a===e&&o()}).catch(e=>{f(null),c(Oc(e))})},[n,a,t,o]),x=g.useCallback(async e=>{await es(e),n()},[n]),S=g.useCallback((e,t)=>{e.preventDefault(),u(null),f({x:e.clientX,y:e.clientY,target:t,fromToolbar:!1})},[]),C=g.useCallback(e=>{let t=e.currentTarget.getBoundingClientRect();u(null),f({x:t.left,y:t.bottom+4,target:{type:`root`,path:``},fromToolbar:!0})},[]);return{edit:l,menu:d,actionError:s,setActionError:c,closeMenu:g.useCallback(()=>f(null),[]),startCreate:h,startRename:_,duplicate:v,moveTo:y,confirmDelete:b,makeFolder:x,onContextMenu:S,openNewMenu:C}}function R(e){let{menu:t,folders:n,showHidden:r,onClose:i}=e,a=g.useRef(null),[o,s]=g.useState(`default`),c=g.useRef(null);_c(a,i);let l=yc(a,t,[o]),u=t=>{let n=c.current;n?.action===`create`?e.onCreate(n.type,t):n?.action===`move`&&e.onMove(n.file,t),i()},d=n=>{t.target.type===`directory`?(e.onCreate(n,t.target.path),i()):(c.current={action:`create`,type:n},s(`pickFolder`))},f;if(o===`pickFolder`)f=(0,L.jsx)(Ec,{folders:n,purpose:c.current,onChoose:u,onMakeFolder:e.onMakeFolder});else if(t.target.type===`file`){let n=t.target.path;f=o===`confirmDelete`?(0,L.jsxs)(`div`,{className:`castle-file-menu-confirm`,children:[(0,L.jsxs)(`div`,{className:`castle-file-menu-confirm-text`,children:[`Delete “`,us(n),`”?`]}),(0,L.jsxs)(`div`,{className:`castle-file-menu-confirm-actions`,children:[(0,L.jsx)(`button`,{type:`button`,onClick:i,children:`Cancel`}),(0,L.jsx)(`button`,{type:`button`,className:`danger`,onClick:()=>e.onConfirmDelete(n),children:`Delete`})]})]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(Dc,{icon:`clone`,label:`Duplicate`,onClick:()=>e.onDuplicate(n)}),(0,L.jsx)(Dc,{icon:`pen`,label:`Rename`,onClick:()=>e.onRename(n)}),(0,L.jsx)(Dc,{icon:`arrow-right`,label:`Move to…`,onClick:()=>{c.current={action:`move`,file:n},s(`pickFolder`)}}),(0,L.jsx)(Dc,{icon:`trash`,label:`Delete`,danger:!0,onClick:()=>s(`confirmDelete`)})]})}else f=(0,L.jsxs)(L.Fragment,{children:[xc().map(e=>(0,L.jsx)(Dc,{icon:e.icon,label:e.label,onClick:()=>d(e)},e.label)),t.target.type===`root`&&!t.fromToolbar?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`castle-file-menu-sep`}),(0,L.jsx)(Dc,{icon:`eye`,label:`Show hidden files & folders`,checked:r,onClick:()=>{e.onToggleHidden(),i()}})]}):null]});return(0,Qn.createPortal)((0,L.jsx)(`div`,{ref:a,className:`castle-file-menu`,role:`menu`,style:l,children:f}),document.body)}function Ec(e){let{folders:t,purpose:n,onChoose:r,onMakeFolder:i}=e,[a,o]=g.useState(!1),[s,c]=g.useState(``),[l,u]=g.useState(!1),[d,f]=g.useState(null),p=g.useRef(null);g.useEffect(()=>{a&&p.current?.focus()},[a]);let m=n?.action===`move`?`Move “${us(n.file)}” to…`:`Create in folder…`,h=()=>{let e=s.trim();e&&(u(!0),f(null),i(e).then(()=>r(e)).catch(e=>{f(Oc(e)),u(!1)}))};return(0,L.jsxs)(`div`,{className:`castle-file-picker`,children:[(0,L.jsx)(`div`,{className:`castle-file-menu-header`,children:m}),t.map(e=>(0,L.jsx)(Dc,{icon:`folder`,label:e,onClick:()=>r(e)},e)),(0,L.jsx)(`div`,{className:`castle-file-menu-sep`}),a?(0,L.jsxs)(`div`,{className:`castle-file-newfolder`,children:[(0,L.jsx)(`input`,{ref:p,className:`fileEditInput`,placeholder:`folder name`,spellCheck:!1,value:s,onChange:e=>c(e.target.value),onKeyDown:e=>{e.key===`Enter`?(e.preventDefault(),h()):e.key===`Escape`&&(o(!1),c(``))}}),(0,L.jsx)(`button`,{type:`button`,className:`castle-file-newfolder-btn`,disabled:l,onClick:h,children:`Create`})]}):(0,L.jsx)(Dc,{icon:`folder-plus`,label:`New folder…`,onClick:()=>o(!0)}),d?(0,L.jsx)(`div`,{className:`castle-file-menu-error`,children:d}):null]})}function Dc(e){return(0,L.jsxs)(`button`,{type:`button`,role:`menuitem`,className:tc(`castle-file-menu-item`,e.danger&&`danger`),onClick:e.onClick,children:[(0,L.jsx)(`span`,{className:`castle-file-menu-item-icon`,children:(0,L.jsx)(ic,{name:e.icon})}),(0,L.jsx)(`span`,{className:`castle-file-menu-item-label`,children:e.label}),e.checked?(0,L.jsx)(`span`,{className:`castle-file-menu-check`,children:`✓`}):null]})}function Oc(e){return e instanceof Error?e.message:String(e)}function kc(e){let t=new Set;for(let n of e){if(Yo(n))continue;let e=n.split(`/`);for(let n=1;n<e.length;n++)t.add(e.slice(0,n).join(`/`))}return[...t].sort()}function Ac(e,t){let n=ds(e),r=us(e),i=r.lastIndexOf(`.`),a=i>0?r.slice(0,i):r,o=i>0?r.slice(i):``,s=new Set(t);for(let e=1;;e++){let t=fs(n,`${a} ${e===1?`copy`:`copy ${e}`}${o}`);if(!s.has(t))return t}}var jc=typeof navigator<`u`&&/mac|iphone|ipad/i.test(navigator.userAgentData?.platform??navigator.platform??``);function Mc(e){return typeof e==`string`?e:jc?e.mac:e.win}function Nc(e){let t=e.split(`+`),n={meta:!1,ctrl:!1,shift:!1,alt:!1,key:Fc(t[t.length-1])};for(let e of t.slice(0,-1))e===`Mod`?jc?n.meta=!0:n.ctrl=!0:e===`Cmd`||e===`Meta`?n.meta=!0:e===`Ctrl`?n.ctrl=!0:e===`Shift`?n.shift=!0:(e===`Alt`||e===`Opt`||e===`Option`)&&(n.alt=!0);return n}function Pc(e){return e?Mc(e).split(` `).filter(Boolean).map(Nc):[]}function Fc(e){let t=e.toLowerCase();return t===`space`||t===` `?` `:t===`esc`||t===`escape`?`escape`:t}function Ic(e){let t=e.code;return t.startsWith(`Key`)?t.slice(3).toLowerCase():t.startsWith(`Digit`)?t.slice(5):t===`Backquote`?"`":t===`Backslash`?`\\`:t===`Space`?` `:t===`Escape`?`escape`:t.startsWith(`Arrow`)?t.toLowerCase():e.key.toLowerCase()}function Lc(e,t){return t.metaKey===e.meta&&t.ctrlKey===e.ctrl&&t.shiftKey===e.shift&&t.altKey===e.alt&&Ic(t)===e.key}function Rc(e){return e.key===`Meta`||e.key===`Control`||e.key===`Shift`||e.key===`Alt`}function zc(e){let t=[];jc?(e.ctrl&&t.push(`⌃`),e.alt&&t.push(`⌥`),e.shift&&t.push(`⇧`),e.meta&&t.push(`⌘`)):(e.ctrl&&t.push(`Ctrl`),e.alt&&t.push(`Alt`),e.shift&&t.push(`Shift`),e.meta&&t.push(`Win`));let n=e.key===` `?`Space`:e.key.length===1?e.key.toUpperCase():e.key;return jc?[...t,n].join(``):[...t,n].join(`+`)}function Bc(e){return Pc(e).map(zc).join(` `)}function Vc(){let e=document.activeElement,t=e?.tagName,n=t===`INPUT`||t===`TEXTAREA`||(e?.isContentEditable??!1)||!!e?.closest?.(`.cm-editor`);return{editorFocused:!!e?.closest?.(`.cm-editor`),inputFocused:n}}function Hc(e){let t=new Set,n=n=>{if(!(!n||t.has(n)))try{n.addEventListener(`keydown`,e,!0),t.add(n)}catch{}},r=()=>{document.querySelectorAll(`iframe.deck-frame`).forEach(e=>{n(e.contentWindow)})};n(window),r();let i=e=>{e.target?.matches?.(`iframe.deck-frame`)&&r()};document.addEventListener(`load`,i,!0);let a=new MutationObserver(r);return a.observe(document.body,{childList:!0,subtree:!0}),()=>{t.forEach(t=>{try{t.removeEventListener(`keydown`,e,!0)}catch{}}),document.removeEventListener(`load`,i,!0),a.disconnect()}}var Uc=2500;function Wc(e){let t=g.useRef(e);t.current=e;let[n,r]=g.useState(null);return g.useEffect(()=>{let e=null,n=null,i=()=>{e=null,n&&clearTimeout(n),n=null,r(null)},a=t=>{e=t,r(zc(t)),n&&clearTimeout(n),n=setTimeout(i,Uc)},o=Hc(n=>{if(Rc(n))return;let r=t.current();if(e){for(let t of r){let r=Pc(t.keys);if(r.length===2&&Gc(r[0],e)&&Lc(r[1],n)){n.preventDefault(),n.stopPropagation(),i(),t.run();return}}n.preventDefault(),i();return}for(let e of r){let t=Pc(e.keys);if(t.length===1&&Lc(t[0],n)){if(e.when&&!e.when(Vc()))continue;n.preventDefault(),n.stopPropagation(),e.run();return}}for(let e of r){let t=Pc(e.keys);if(t.length===2&&Lc(t[0],n)){n.preventDefault(),n.stopPropagation(),a(t[0]);return}}});return()=>{o(),n&&clearTimeout(n)}},[]),n}function Gc(e,t){return e.meta===t.meta&&e.ctrl===t.ctrl&&e.shift===t.shift&&e.alt===t.alt&&e.key===t.key}var Kc=null;function qc(e){Kc=e}function Jc(e=`file`){Kc?.(e)}var Yc=50,Xc=[{kind:`files`,label:`Files Panel`},{kind:`playtest`,label:`Play Panel`},{kind:`terminal`,label:`Terminal`}];function Zc(e){let[t,n]=g.useState(!1),[r,i]=g.useState(``),[a,o]=g.useState([]),[s,c]=g.useState([]),[l,u]=g.useState(0),d=g.useRef(null),f=g.useRef(null),p=g.useRef(!1),m=g.useRef(``);p.current=t,m.current=r,g.useEffect(()=>Hc(e=>{let t=e.key===`p`||e.key===`P`;if(!(e.metaKey||e.ctrlKey)||e.altKey||!t)return;e.preventDefault();let r=e.shiftKey,a=m.current.startsWith(`>`);if(p.current&&a===r){n(!1);return}i(r?`>`:``),u(0),n(!0)}),[]),g.useEffect(()=>(qc(e=>{i(e===`command`?`>`:``),u(0),n(!0)}),()=>qc(null)),[]),g.useEffect(()=>{let e=e=>{e.data?.type===`castle-quick-open`&&(i(e.data.mode===`command`?`>`:``),u(0),n(!0))};return window.addEventListener(`message`,e),()=>window.removeEventListener(`message`,e)},[]),g.useEffect(()=>{if(!t)return;c(e.getCommands()),$o(!0).then(o,()=>o([]));let n=requestAnimationFrame(()=>d.current?.focus());return()=>cancelAnimationFrame(n)},[t]);let h=r.startsWith(`>`),_=g.useMemo(()=>{if(h)return[];let e=r.trim().toLowerCase(),t=Xc.filter(t=>e===``||el(e,t.label)!==null).map(e=>({type:`panel`,kind:e.kind,label:e.label})),n=Qc(a,r).slice(0,Yc).map(e=>({type:`file`,path:e}));return[...t,...n]},[a,r,h]),v=g.useMemo(()=>h?$c(s,r.slice(1)).slice(0,Yc):[],[s,r,h]),y=h?v.length:_.length;if(g.useEffect(()=>u(0),[r]),g.useEffect(()=>{f.current?.querySelector(`.quick-open-item.active`)?.scrollIntoView({block:`nearest`})},[l,y]),!t)return null;let b=(t=l)=>{if(h)v[t]?.run();else{let n=_[t],r=e.getApi();n&&r&&(n.type===`panel`?Es(r,n.kind):Ts(r,n.path))}n(!1)};return(0,Qn.createPortal)((0,L.jsx)(`div`,{className:`quick-open-backdrop`,onMouseDown:()=>n(!1),children:(0,L.jsxs)(`div`,{className:`quick-open`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`input`,{ref:d,className:`quick-open-input`,placeholder:h?`Type a command…`:`Go to file… (type > for commands)`,spellCheck:!1,value:r,onChange:e=>i(e.target.value),onKeyDown:e=>{e.key===`Escape`?(e.preventDefault(),n(!1)):e.key===`ArrowDown`?(e.preventDefault(),u(e=>Math.min(y-1,e+1))):e.key===`ArrowUp`?(e.preventDefault(),u(e=>Math.max(0,e-1))):e.key===`Enter`&&(e.preventDefault(),b())}}),(0,L.jsx)(`div`,{className:`quick-open-list`,ref:f,children:y===0?(0,L.jsx)(`div`,{className:`quick-open-empty`,children:h?`No matching commands`:`No matching files`}):h?v.map((e,t)=>(0,L.jsxs)(`button`,{type:`button`,className:`quick-open-item${t===l?` active`:``}`,onMouseEnter:()=>u(t),onClick:()=>b(t),children:[(0,L.jsx)(`span`,{className:`quick-open-name`,children:e.title}),e.group?(0,L.jsx)(`span`,{className:`quick-open-dir`,children:e.group}):null,e.keys?(0,L.jsx)(`span`,{className:`quick-open-keys`,children:Bc(e.keys)}):null]},e.id)):_.map((e,t)=>(0,L.jsx)(`button`,{type:`button`,className:`quick-open-item${t===l?` active`:``}`,onMouseEnter:()=>u(t),onClick:()=>b(t),children:e.type===`panel`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`span`,{className:`quick-open-name`,children:e.label}),(0,L.jsx)(`span`,{className:`quick-open-dir`,children:`Panel`})]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`span`,{className:`quick-open-name`,children:us(e.path)}),(0,L.jsx)(`span`,{className:`quick-open-dir`,children:ds(e.path)})]})},e.type===`panel`?`panel:${e.kind}`:e.path))})]})}),document.body)}function Qc(e,t){let n=t.trim().toLowerCase();if(!n)return e;let r=[];for(let t of e){let e=el(n,t);e!==null&&r.push({path:t,score:e})}return r.sort((e,t)=>t.score-e.score||e.path.localeCompare(t.path)),r.map(e=>e.path)}function $c(e,t){let n=e.filter(e=>!e.hidden),r=t.trim().toLowerCase();if(!r)return n;let i=[];for(let e of n){let t=el(r,`${e.group??``} ${e.title}`.toLowerCase());t!==null&&i.push({cmd:e,score:t})}return i.sort((e,t)=>t.score-e.score||e.cmd.title.localeCompare(t.cmd.title)),i.map(e=>e.cmd)}function el(e,t){let n=t.toLowerCase(),r=0,i=0,a=0,o=-2;for(let t=0;t<n.length&&r<e.length;t++)n[t]===e[r]&&(a=o===t-1?a+1:0,i+=1+a*2,o=t,r++);if(r<e.length)return null;let s=(t.split(`/`).pop()??t).toLowerCase();return s.includes(e)&&(i+=20),s.startsWith(e)&&(i+=10),i-t.length*.01}function tl(e){let t=e.file.split(`/`);return(0,L.jsxs)(`span`,{className:`dv-default-tab-content`,children:[(0,L.jsxs)(`span`,{className:`castle-tab-import`,children:[t[1],`:`]}),t[t.length-1]]})}function nl(){return(0,L.jsx)(`svg`,{height:`11`,width:`11`,viewBox:`0 0 28 28`,"aria-hidden":`false`,focusable:!1,className:`dv-svg`,children:(0,L.jsx)(`path`,{d:`M2.1 27.3L0 25.2L11.55 13.65L0 2.1L2.1 0L13.65 11.55L25.2 0L27.3 2.1L15.75 13.65L27.3 25.2L25.2 27.3L13.65 15.75L2.1 27.3Z`})})}function rl(e){let[t,n]=g.useState(null),r=typeof e.params?.file==`string`?e.params.file:null,i=e=>{e.preventDefault(),n({x:e.clientX,y:e.clientY})};return r&&Yo(r)?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{"data-testid":`dockview-dv-default-tab`,className:`dv-default-tab`,onContextMenu:i,onAuxClick:t=>{t.button===1&&(t.preventDefault(),e.api.close())},children:[(0,L.jsx)(tl,{file:r}),(0,L.jsx)(`div`,{className:`dv-default-tab-action`,onPointerDown:e=>e.preventDefault(),onClick:t=>{t.preventDefault(),e.api.close()},children:(0,L.jsx)(nl,{})})]}),t?(0,L.jsx)(il,{props:e,pos:t,onClose:()=>n(null)}):null]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(gr,{...e,onContextMenu:e=>{e.preventDefault(),n({x:e.clientX,y:e.clientY})},onAuxClick:t=>{t.button===1&&(t.preventDefault(),e.api.close())}}),t?(0,L.jsx)(il,{props:e,pos:t,onClose:()=>n(null)}):null]})}function il(e){let{props:t,pos:n,onClose:r}=e,i=g.useRef(null);_c(i,r);let a=yc(i,n),o=t.api.group,s=o.panels,c=s.findIndex(e=>e.id===t.api.id),l=typeof t.params?.file==`string`?t.params.file:null,u=s.length>1,d=c>=0&&c<s.length-1,f=e=>()=>{e(),r()},p=e=>e.slice().forEach(e=>e.api.close());return(0,Qn.createPortal)((0,L.jsxs)(`div`,{ref:i,className:`castle-file-menu castle-tab-menu`,role:`menu`,style:a,children:[(0,L.jsx)(al,{label:`Close`,shortcut:Bc(`Mod+Alt+W`),onClick:f(()=>t.api.close())}),(0,L.jsx)(al,{label:`Close Others`,disabled:!u,onClick:f(()=>p(s.filter(e=>e.id!==t.api.id)))}),(0,L.jsx)(al,{label:`Close to the Right`,disabled:!d,onClick:f(()=>p(s.slice(c+1)))}),(0,L.jsx)(al,{label:`Close All`,onClick:f(()=>p(s))}),(0,L.jsx)(`div`,{className:`castle-file-menu-sep`}),(0,L.jsx)(al,{label:`Split Right`,disabled:!u,onClick:f(()=>t.api.moveTo({group:o,position:`right`}))}),(0,L.jsx)(al,{label:`Split Down`,disabled:!u,onClick:f(()=>t.api.moveTo({group:o,position:`bottom`}))}),l?(0,L.jsx)(al,{label:`Copy Path`,onClick:f(()=>void navigator.clipboard?.writeText(l))}):null]}),document.body)}function al(e){return(0,L.jsxs)(`button`,{className:`castle-file-menu-item`,role:`menuitem`,type:`button`,disabled:e.disabled,onClick:e.onClick,children:[(0,L.jsx)(`span`,{className:`castle-file-menu-item-label`,children:e.label}),e.shortcut?(0,L.jsx)(`span`,{className:`castle-file-menu-keys`,children:e.shortcut}):null]})}function ol(e){return e.element}function sl(e){let[t,n]=g.useState(null);if(g.useEffect(()=>{let t=t=>{let r=t.target;if(r.closest(`.dv-tab`))return;let i=r.closest(`.dv-tabs-and-actions-container`),a=r.closest(`.empty-dock-state`);if(!i&&!a)return;let o=r.closest(`.dv-groupview`),s=e.getApi();if(!s||!o)return;let c=s.groups.find(e=>ol(e)===o);c&&(t.preventDefault(),n({x:t.clientX,y:t.clientY,group:c}))};return document.addEventListener(`contextmenu`,t,!0),()=>document.removeEventListener(`contextmenu`,t,!0)},[e]),!t)return null;let r=e.getApi();return r?(0,L.jsx)(cl,{api:r,menu:t,onClose:()=>n(null)}):null}function cl(e){let{api:t,menu:n,onClose:r}=e,i=g.useRef(null);_c(i,r);let a=yc(i,n),o=e=>()=>{e(),r()},s=n.group.panels.length>0;return(0,Qn.createPortal)((0,L.jsxs)(`div`,{ref:i,className:`castle-file-menu castle-tab-menu`,role:`menu`,style:a,children:[(0,L.jsx)(`div`,{className:`castle-file-menu-header`,children:`New panel`}),zo.map(e=>(0,L.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`castle-file-menu-item`,onClick:o(()=>Bo(t,e,n.group)),children:[(0,L.jsx)(`span`,{className:`castle-file-menu-item-icon`,children:e.icon}),(0,L.jsx)(`span`,{className:`castle-file-menu-item-label`,children:e.label})]},e.label)),(0,L.jsx)(`div`,{className:`castle-file-menu-sep`}),(0,L.jsx)(`button`,{type:`button`,role:`menuitem`,className:`castle-file-menu-item`,disabled:!s,onClick:o(()=>n.group.panels.slice().forEach(e=>e.api.close())),children:(0,L.jsx)(`span`,{className:`castle-file-menu-item-label`,children:`Close All Tabs`})}),(0,L.jsx)(`button`,{type:`button`,role:`menuitem`,className:`castle-file-menu-item`,onClick:o(()=>n.group.api.close()),children:(0,L.jsx)(`span`,{className:`castle-file-menu-item-label`,children:`Close Group`})})]}),document.body)}var ll=25,ul=[];function dl(e){let t=ul.indexOf(e);t!==-1&&ul.splice(t,1),ul.push(e),ul.length>ll&&ul.shift()}function fl(){return ul.pop()}var pl=new Map;function ml(e,t){pl.set(e,t)}function hl(e){pl.delete(e)}function gl(e){pl.get(e)?.()}function _l(e){let t=zo.find(t=>t.kind===e);if(!t)throw Error(`no panel menu item for ${e}`);return t}function vl(e){return e===`terminal`||e.startsWith(`terminal-`)}function yl(e){e&&(e.api.setActive(),requestAnimationFrame(()=>gl(e.id)))}function bl(e){let t=e=>e.element;return[...e.groups].sort((e,n)=>{let r=t(e).getBoundingClientRect(),i=t(n).getBoundingClientRect();return r.left-i.left||r.top-i.top})}function xl(e,t){yl(bl(e)[t-1]?.activePanel)}function Sl(e,t){yl(e.activeGroup?.panels[t-1])}function Cl(e){let t=bl(e),n=t[t.length-1];if(!n){e.addGroup().api.setActive();return}let r=e=>e.element,i=r(n).closest(`.shell-dockview`)?.getBoundingClientRect().width??1/0,a=r(n).getBoundingClientRect().width>i*.9;e.addGroup({referenceGroup:n,direction:a?`below`:`right`}).api.setActive(),Jc(`file`)}function wl(){document.getElementById(`chat-input`)?.focus()}function Tl(e,t){let n=e.activePanel;n&&n.api.group.panels.length>1&&n.api.moveTo({group:n.api.group,position:t})}function El(e,t){let n=e.getPanel(t);n?n.api.close():Bo(e,_l(t))}function Dl(e){let t=e.panels.filter(e=>vl(e.id)),n=e.activePanel;n&&vl(n.id)?n.api.close():t.length>0?t[0].api.setActive():Bo(e,_l(`terminal`))}function Ol(e){let t=t=>()=>{let n=e();n&&t(n)};return()=>{let n=e(),r=n?n.groups.length:0,i=[];for(let e=1;e<=r;e++)i.push({id:`view.group${e}`,group:`View`,title:`Focus Group ${e}`,keys:e<=9?`Mod+K ${e}`:void 0,run:t(t=>xl(t,e))});r+1<=9&&i.push({id:`view.newGroup`,group:`View`,title:`New Editor Group`,keys:`Mod+K ${r+1}`,run:t(Cl)});let a=[];for(let e=1;e<=9;e++)a.push({id:`view.tab${e}`,group:`View`,title:`Focus Tab ${e} in Group`,keys:`Mod+K Shift+${e}`,hidden:!0,run:t(t=>Sl(t,e))});return[{id:`view.files`,group:`View`,title:`Toggle Files Panel`,keys:`Mod+B`,run:t(e=>El(e,`files`))},{id:`view.play`,group:`View`,title:`Toggle Play Panel`,keys:`Mod+J`,run:t(e=>El(e,`playtest`))},{id:`view.terminal`,group:`View`,title:`Toggle Terminal`,keys:"Ctrl+`",run:t(Dl)},{id:`view.operator`,group:`View`,title:`Focus Operator`,run:wl},{id:`view.closeGroup`,group:`View`,title:`Close Group`,run:t(e=>e.activeGroup?.api.close())},...i,...a,{id:`tabs.splitRight`,group:`Tabs`,title:`Split Right`,run:t(e=>Tl(e,`right`))},{id:`tabs.splitDown`,group:`Tabs`,title:`Split Down`,run:t(e=>Tl(e,`bottom`))},{id:`tabs.close`,group:`Tabs`,title:`Close Tab`,keys:`Mod+Alt+W`,run:t(e=>e.activePanel?.api.close())},{id:`tabs.reopen`,group:`Tabs`,title:`Reopen Closed Tab`,keys:`Mod+Shift+Alt+W`,run:t(e=>{let t=fl();t&&Ts(e,t)})}]}}var kl=`castle-dock-layout:`;function Al(e){return e?`${kl}${e}`:null}function jl(e){let t=Al(e);if(!t)return null;try{let e=localStorage.getItem(t);if(!e)return null;let n=JSON.parse(e);return n.version!==1||!n.layout||typeof n.layout!=`object`||!n.layout.panels||typeof n.layout.panels!=`object`||!n.layout.grid||typeof n.layout.grid!=`object`?null:n.layout}catch{return null}}function Ml(e,t){let n=Al(e);if(n)try{let e={version:1,layout:t};localStorage.setItem(n,JSON.stringify(e))}catch{}}function Nl(e){if(!e.startsWith(`editor:`))return null;let t=e.slice(7);return t.length>0?t:null}function Pl(e,t){return e.filter(e=>!t.has(e))}function Fl(e,t){let n=Pl(e.views??[],t);if(n.length===0)return null;let r=e.activeView&&n.includes(e.activeView)?e.activeView:n[0];return{...e,views:n,activeView:r}}function Il(e,t){if(e.type===`leaf`){let n=e.data,r=Fl(n,t);return r?{...e,data:r}:null}let n=e.data.map(e=>Il(e,t)).filter(e=>e!==null);return n.length===0?null:{...e,data:n}}function Ll(e,t){let n=new Set;for(let r of Object.keys(e.panels)){let e=Nl(r);e!==null&&!t.has(e)&&n.add(r)}if(n.size===0)return e;let r={...e.panels};for(let e of n)delete r[e];let i=Il(e.grid.root,n);if(!i)return null;let a=e.floatingGroups?.map(e=>{let t=Fl(e.data,n);return t?{...e,data:t}:null}).filter(e=>e!==null),o=e.popoutGroups?.map(e=>{let t=Fl(e.data,n);return t?{...e,data:t}:null}).filter(e=>e!==null),s=e.activeGroup&&Rl(i,e.activeGroup)?e.activeGroup:zl(i);return{...e,panels:r,grid:{...e.grid,root:i},activeGroup:s,floatingGroups:a?.length?a:void 0,popoutGroups:o?.length?o:void 0}}function Rl(e,t){return e.type===`leaf`?e.data.id===t:e.data.some(e=>Rl(e,t))}function zl(e){if(e.type===`leaf`)return e.data.id;for(let t of e.data){let e=zl(t);if(e)return e}}function Bl(e){return Object.keys(e.panels).length>0}var Vl=`(max-width: 768px)`,Hl=`castle-layout-engine`,Ul=`dock`;function Wl(e){return e===`dock`||e===`flow`}function Gl(){try{return window.matchMedia(Vl).matches}catch{return!1}}function Kl(){try{let e=new URLSearchParams(window.location.search).get(`layout`);return Wl(e)?e:null}catch{return null}}function ql(){try{let e=localStorage.getItem(Hl);return Wl(e)?e:null}catch{return null}}function Jl(e){if(!Gl())try{localStorage.setItem(Hl,e)}catch{}}function Yl(){return Gl()?`flow`:Kl()??ql()??Ul}function Xl({onChange:e}){let t=t=>{let n=t.data;!n||n.type!==`castle-set-layout`||Wl(n.engine)&&(Jl(n.engine),e(Gl()?`flow`:n.engine))};window.addEventListener(`message`,t);let n=null,r=()=>e(Yl());try{n=window.matchMedia(Vl),n.addEventListener(`change`,r)}catch{n=null}return()=>{window.removeEventListener(`message`,t),n?.removeEventListener(`change`,r)}}var Zl=0;function Ql(e=`id`){return Zl+=1,`${e}-${Zl}`}function $l(e){return e.endsWith(`.scene`)?`scene`:e.endsWith(`.pxart`)?`pxart`:`code`}function eu(e){return e===`pxart`?300:650}function tu(e){switch(e.kind){case`operator`:return 480;case`files`:return 400;case`terminal`:return 300;case`play`:return 360;case`editor`:return eu($l(e.path??``));default:return 320}}function nu(e){return e.split(`/`).pop()||e}function ru(e,t){return e===`editor`?nu(t??``):e===`operator`?`Operator`:e===`files`?`Files`:e===`play`?`Play`:`Terminal`}function iu(e,t){return{id:Ql(`tab`),kind:e,label:ru(e,t),path:t}}function au(e,t,n,r=520){return{id:Ql(`grp`),w:t,h:r,activeTabId:n??e[0]?.id??``,tabs:e}}function ou(e){let t=new Map,n=e.groups.map(e=>{let n=Ql(`grp`);t.set(e.id,n);let r=new Map,i=e.tabs.map(e=>{let t=Ql(`tab`);return r.set(e.id,t),{...e,id:t}});return{...e,id:n,tabs:i,activeTabId:r.get(e.activeTabId)??i[0]?.id??``}}),r=e=>e===null?null:t.get(e)??null;return{groups:n,activeGroupId:r(e.activeGroupId),pinnedGroupId:r(e.pinnedGroupId),maximizedGroupId:r(e.maximizedGroupId)}}function su(e,t){return t===null?-1:e.groups.findIndex(e=>e.id===t)}function cu(e,t){let n=su(e,t);return n<0?null:e.groups[n]}function lu(e,t){for(let n of e.groups){let e=n.tabs.find(e=>e.kind===`editor`&&e.path===t);if(e)return{group:n,tab:e}}return null}function uu(e,t){return{...e,...t}}function du(e,t,n){return{...e,groups:e.groups.map(e=>e.id===t?n:e)}}function fu(e,t,n){let r=e.groups.slice();return r.splice(Math.max(0,Math.min(t,r.length)),0,n),{...e,groups:r,activeGroupId:n.id}}function pu(e,t){return su(e,t)<0?e:{...e,activeGroupId:t}}function mu(e,t,n){let r=e.groups.slice();r.splice(t,1);let i=e.activeGroupId===n?r[Math.min(t,r.length-1)]?.id??null:e.activeGroupId,a=e.pinnedGroupId===n?null:e.pinnedGroupId,o=e.maximizedGroupId===n?null:e.maximizedGroupId;return{...e,groups:r,activeGroupId:i,pinnedGroupId:a,maximizedGroupId:o}}function hu(e,t,n){let r=su(e,t);if(r<0)return e;let i=e.groups[r],a=i.tabs.findIndex(e=>e.id===n);if(a<0)return e;let o=i.tabs.slice();return o.splice(a,1),o.length===0?mu(e,r,t):du(e,t,uu(i,{tabs:o,activeTabId:i.activeTabId===n?o[Math.min(a,o.length-1)].id:i.activeTabId}))}var gu=new Set([`operator`,`files`]);function _u(e,t,n){if(t===`editor`&&n){let t=lu(e,n);if(t)return pu(e,t.group.id)}if(gu.has(t)){let n=e.groups.find(e=>e.tabs[0]?.kind===t);if(n)return pu(e,n.id)}let r=iu(t,n),i=au([r],tu(r)),a=su(e,e.activeGroupId);return fu(e,a<0?e.groups.length:a+1,i)}function vu(e,t,n,r){let i=cu(e,t);if(!i)return e;if(gu.has(n)){let r=e.groups.find(e=>e.id!==t&&e.tabs[0]?.kind===n);if(r)return pu(e,r.id)}let a=iu(n,r);return du(e,t,uu(i,{tabs:[a],activeTabId:a.id}))}function yu(e,t){let n=su(e,t);return n<0?e:mu(e,n,t)}function bu(e,t,n){let r=su(e,t);if(r<0)return e;let i=e.groups.slice(),[a]=i.splice(r,1);return i.splice(Math.max(0,Math.min(n,i.length)),0,a),{...e,groups:i}}function xu(e,t){if(su(e,t)<0)return e;let n=e.pinnedGroupId===t?null:t;return{...e,pinnedGroupId:n}}function Su(e,t){if(su(e,t)<0)return e;let n=e.maximizedGroupId===t?null:t;return{...e,maximizedGroupId:n,activeGroupId:t}}function Cu(e,t,n){let r=cu(e,t);return r?du(e,t,uu(r,{w:Math.max(200,n)})):e}function wu(e,t,n){let r=cu(e,t);return r?du(e,t,uu(r,{h:Math.max(160,n)})):e}var Tu=`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEKSURBVHgB7dpLDoMwDEXRR8X+t9wyYRI1aj52Yup7hoA8MOYFESQAmR3lgfdFA47Lt+Oj9bzqlvVeSu6snah1vtR6J1rredWt1Us/ATRAyZ0yMpv2q+vemABN6k333XVLhKCSIwNaL/ROY2utGcIEqNOqdB7VO6mEoJIjAzRp9+owm0lMgIysXh2sJo8QVHJkgJxYrw5eGcMEyNnsneOboDMaoOTcM6D065le/UbJBGiTKF+WCEElRwZokyj7DEyAFou2r0AIKjkyQM6i7yozAXISfRf5RggquW2vwrOubDV5xML/KertiRNg2uiwf4quwiqg5MJngFXa13Q34KlpXxN5Av6q0QBi+gCRhFSWys93vQAAAABJRU5ErkJggg==`,Eu={width:15,height:15,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},Du=(0,L.jsxs)(`svg`,{...Eu,children:[(0,L.jsx)(`rect`,{x:`4`,y:`8`,width:`16`,height:`12`,rx:`2`}),(0,L.jsx)(`path`,{d:`M12 8V4`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`14`,r:`1`}),(0,L.jsx)(`circle`,{cx:`15`,cy:`14`,r:`1`})]}),Ou=(0,L.jsx)(`svg`,{...Eu,children:(0,L.jsx)(`path`,{d:`M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`})}),ku=(0,L.jsx)(`svg`,{...Eu,children:(0,L.jsx)(`polygon`,{points:`6 4 20 12 6 20 6 4`})}),Au=(0,L.jsxs)(`svg`,{...Eu,children:[(0,L.jsx)(`polyline`,{points:`4 17 10 11 4 5`}),(0,L.jsx)(`line`,{x1:`12`,y1:`19`,x2:`20`,y2:`19`})]}),ju=(0,L.jsxs)(`svg`,{...Eu,children:[(0,L.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`16`,rx:`2`}),(0,L.jsx)(`circle`,{cx:`8`,cy:`9`,r:`1.5`}),(0,L.jsx)(`path`,{d:`M3 16l5-4 4 3 3-2 6 5`})]}),Mu=(0,L.jsxs)(`svg`,{...Eu,children:[(0,L.jsx)(`rect`,{x:`4`,y:`4`,width:`7`,height:`7`}),(0,L.jsx)(`rect`,{x:`13`,y:`4`,width:`7`,height:`7`}),(0,L.jsx)(`rect`,{x:`4`,y:`13`,width:`7`,height:`7`}),(0,L.jsx)(`rect`,{x:`13`,y:`13`,width:`7`,height:`7`})]}),Nu=(0,L.jsxs)(`svg`,{...Eu,children:[(0,L.jsx)(`polyline`,{points:`16 18 22 12 16 6`}),(0,L.jsx)(`polyline`,{points:`8 6 2 12 8 18`})]}),Pu={scene:ju,pxart:Mu,code:Nu};function Fu(e,t){switch(e){case`operator`:return Du;case`files`:return Ou;case`play`:return ku;case`terminal`:return Au;case`editor`:return Pu[$l(t??``)];default:return Nu}}var Iu=(0,L.jsx)(`svg`,{...Eu,width:16,height:16,children:(0,L.jsx)(`path`,{d:`M12 5v14M5 12h14`})}),Lu=(0,L.jsx)(`svg`,{...Eu,width:13,height:13,children:(0,L.jsx)(`path`,{d:`M6 6l12 12M18 6L6 18`})}),Ru=(0,L.jsx)(`svg`,{...Eu,width:15,height:15,children:(0,L.jsx)(`path`,{d:`M4 7h16M4 12h16M4 17h16`})}),zu=(0,L.jsx)(`svg`,{...Eu,width:14,height:14,children:(0,L.jsx)(`path`,{d:`M9 3h6l-1 5 3 3v2H7v-2l3-3-1-5zM12 15v6`})}),Bu=(0,L.jsx)(`img`,{src:Tu,alt:`Castle`,draggable:!1,style:{width:26,height:26,objectFit:`contain`,display:`block`}}),Vu=(0,L.jsxs)(`svg`,{...Eu,width:14,height:14,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,L.jsx)(`path`,{d:`M3 12h18M12 3c2.5 2.5 2.5 15.5 0 18M12 3c-2.5 2.5-2.5 15.5 0 18`})]}),Hu=(0,L.jsxs)(`svg`,{...Eu,width:14,height:14,children:[(0,L.jsx)(`path`,{d:`M10 13a5 5 0 0 0 7 0l2-2a5 5 0 0 0-7-7l-1 1`}),(0,L.jsx)(`path`,{d:`M14 11a5 5 0 0 0-7 0l-2 2a5 5 0 0 0 7 7l1-1`})]}),Uu=(0,L.jsxs)(`svg`,{...Eu,width:14,height:14,children:[(0,L.jsx)(`rect`,{x:`5`,y:`11`,width:`14`,height:`10`,rx:`2`}),(0,L.jsx)(`path`,{d:`M8 11V7a4 4 0 0 1 8 0v4`})]}),Wu=(0,L.jsx)(`svg`,{...Eu,width:14,height:14,fill:`currentColor`,stroke:`none`,children:(0,L.jsx)(`path`,{d:`M6 3l14 9-14 9z`})}),Gu=(0,L.jsx)(`svg`,{...Eu,width:13,height:13,children:(0,L.jsx)(`path`,{d:`M6 9l6 6 6-6`})}),Ku=(0,L.jsx)(`svg`,{...Eu,width:13,height:13,children:(0,L.jsx)(`path`,{d:`M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7`})}),qu=(0,L.jsx)(`svg`,{...Eu,width:13,height:13,children:(0,L.jsx)(`path`,{d:`M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7`})}),Ju=`castle-deck-meta-request`,Yu=`castle-nav`,Xu=()=>typeof window<`u`&&window.parent&&window.parent!==window;function Zu(e){Xu()&&window.parent.postMessage({type:Yu,action:e},`*`)}function Qu(e){let t=e;if(!t||t.type!==`castle-deck-meta`)return null;let n=t.visibility===`public`||t.visibility===`unlisted`?t.visibility:`private`,r=t.saving===`working`||t.saving===`done`?t.saving:`idle`;return{title:typeof t.title==`string`?t.title:``,visibility:n,castleDeckId:typeof t.castleDeckId==`string`?t.castleDeckId:null,shareUrl:typeof t.shareUrl==`string`?t.shareUrl:null,saving:r}}function $u(){let[e,t]=g.useState(null);return g.useEffect(()=>{let e=e=>{let n=Qu(e.data);n&&t(n)};return window.addEventListener(`message`,e),Xu()&&window.parent.postMessage({type:Ju},`*`),()=>window.removeEventListener(`message`,e)},[]),e}var ed=[],td=[];(()=>{let e=`lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o`.split(`,`).map(e=>e?parseInt(e,36):1);for(let t=0,n=0;t<e.length;t++)(t%2?td:ed).push(n+=e[t])})();function nd(e){if(e<768)return!1;for(let t=0,n=ed.length;;){let r=t+n>>1;if(e<ed[r])n=r;else if(e>=td[r])t=r+1;else return!0;if(t==n)return!1}}function rd(e){return e>=127462&&e<=127487}var id=8205;function ad(e,t,n=!0,r=!0){return(n?od:sd)(e,t,r)}function od(e,t,n){if(t==e.length)return t;t&&ld(e.charCodeAt(t))&&ud(e.charCodeAt(t-1))&&t--;let r=cd(e,t);for(t+=dd(r);t<e.length;){let i=cd(e,t);if(r==id||i==id||n&&nd(i))t+=dd(i),r=i;else if(rd(i)){let n=0,r=t-2;for(;r>=0&&rd(cd(e,r));)n++,r-=2;if(n%2==0)break;t+=2}else break}return t}function sd(e,t,n){for(;t>1;){let r=od(e,t-2,n);if(r<t)return r;t--}return 0}function cd(e,t){let n=e.charCodeAt(t);if(!ud(n)||t+1==e.length)return n;let r=e.charCodeAt(t+1);return ld(r)?(n-55296<<10)+(r-56320)+65536:n}function ld(e){return e>=56320&&e<57344}function ud(e){return e>=55296&&e<56320}function dd(e){return e<65536?1:2}var fd=class e{lineAt(e){if(e<0||e>this.length)throw RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,n){[e,t]=Sd(this,e,t);let r=[];return this.decompose(0,e,r,2),n.length&&n.decompose(0,n.length,r,3),this.decompose(t,this.length,r,1),md.from(r,this.length-(t-e)+n.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=Sd(this,e,t);let n=[];return this.decompose(e,t,n,0),md.from(n,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),n=this.length-this.scanIdentical(e,-1),r=new vd(this),i=new vd(e);for(let e=t,a=t;;){if(r.next(e),i.next(e),e=0,r.lineBreak!=i.lineBreak||r.done!=i.done||r.value!=i.value)return!1;if(a+=r.value.length,r.done||a>=n)return!0}}iter(e=1){return new vd(this,e)}iterRange(e,t=this.length){return new yd(this,e,t)}iterLines(e,t){let n;if(e==null)n=this.iter();else{t??=this.lines+1;let r=this.line(e).from;n=this.iterRange(r,Math.max(r,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new bd(n)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(t){if(t.length==0)throw RangeError(`A document must have at least one line`);return t.length==1&&!t[0]?e.empty:t.length<=32?new pd(t):md.from(pd.split(t,[]))}},pd=class e extends fd{constructor(e,t=hd(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,n,r){for(let i=0;;i++){let a=this.text[i],o=r+a.length;if((t?n:o)>=e)return new xd(r,o,n,a);r=o+1,n++}}decompose(t,n,r,i){let a=t<=0&&n>=this.length?this:new e(_d(this.text,t,n),Math.min(n,this.length)-Math.max(0,t));if(i&1){let t=r.pop(),n=gd(a.text,t.text.slice(),0,a.length);if(n.length<=32)r.push(new e(n,t.length+a.length));else{let t=n.length>>1;r.push(new e(n.slice(0,t)),new e(n.slice(t)))}}else r.push(a)}replace(t,n,r){if(!(r instanceof e))return super.replace(t,n,r);[t,n]=Sd(this,t,n);let i=gd(this.text,gd(r.text,_d(this.text,0,t)),n),a=this.length+r.length-(n-t);return i.length<=32?new e(i,a):md.from(e.split(i,[]),a)}sliceString(e,t=this.length,n=`
77
77
  `){[e,t]=Sd(this,e,t);let r=``;for(let i=0,a=0;i<=t&&a<this.text.length;a++){let o=this.text[a],s=i+o.length;i>e&&a&&(r+=n),e<s&&t>i&&(r+=o.slice(Math.max(0,e-i),t-i)),i=s+1}return r}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(t,n){let r=[],i=-1;for(let a of t)r.push(a),i+=a.length+1,r.length==32&&(n.push(new e(r,i)),r=[],i=-1);return i>-1&&n.push(new e(r,i)),n}},md=class e extends fd{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let t of e)this.lines+=t.lines}lineInner(e,t,n,r){for(let i=0;;i++){let a=this.children[i],o=r+a.length,s=n+a.lines-1;if((t?s:o)>=e)return a.lineInner(e,t,n,r);r=o+1,n=s+1}}decompose(e,t,n,r){for(let i=0,a=0;a<=t&&i<this.children.length;i++){let o=this.children[i],s=a+o.length;if(e<=s&&t>=a){let i=r&((a<=e?1:0)|(s>=t?2:0));a>=e&&s<=t&&!i?n.push(o):o.decompose(e-a,t-a,n,i)}a=s+1}}replace(t,n,r){if([t,n]=Sd(this,t,n),r.lines<this.lines)for(let i=0,a=0;i<this.children.length;i++){let o=this.children[i],s=a+o.length;if(t>=a&&n<=s){let c=o.replace(t-a,n-a,r),l=this.lines-o.lines+c.lines;if(c.lines<l>>4&&c.lines>l>>6){let a=this.children.slice();return a[i]=c,new e(a,this.length-(n-t)+r.length)}return super.replace(a,s,c)}a=s+1}return super.replace(t,n,r)}sliceString(e,t=this.length,n=`
78
78
  `){[e,t]=Sd(this,e,t);let r=``;for(let i=0,a=0;i<this.children.length&&a<=t;i++){let o=this.children[i],s=a+o.length;a>e&&i&&(r+=n),e<s&&t>a&&(r+=o.sliceString(e-a,t-a,n)),a=s+1}return r}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(t,n){if(!(t instanceof e))return 0;let r=0,[i,a,o,s]=n>0?[0,0,this.children.length,t.children.length]:[this.children.length-1,t.children.length-1,-1,-1];for(;;i+=n,a+=n){if(i==o||a==s)return r;let e=this.children[i],c=t.children[a];if(e!=c)return r+e.scanIdentical(c,n);r+=e.length+1}}static from(t,n=t.reduce((e,t)=>e+t.length+1,-1)){let r=0;for(let e of t)r+=e.lines;if(r<32){let e=[];for(let n of t)n.flatten(e);return new pd(e,n)}let i=Math.max(32,r>>5),a=i<<1,o=i>>1,s=[],c=0,l=-1,u=[];function d(t){let n;if(t.lines>a&&t instanceof e)for(let e of t.children)d(e);else t.lines>o&&(c>o||!c)?(f(),s.push(t)):t instanceof pd&&c&&(n=u[u.length-1])instanceof pd&&t.lines+n.lines<=32?(c+=t.lines,l+=t.length+1,u[u.length-1]=new pd(n.text.concat(t.text),n.length+1+t.length)):(c+t.lines>i&&f(),c+=t.lines,l+=t.length+1,u.push(t))}function f(){c!=0&&(s.push(u.length==1?u[0]:e.from(u,l)),l=-1,c=u.length=0)}for(let e of t)d(e);return f(),s.length==1?s[0]:new e(s,n)}};fd.empty=new pd([``],0);function hd(e){let t=-1;for(let n of e)t+=n.length+1;return t}function gd(e,t,n=0,r=1e9){for(let i=0,a=0,o=!0;a<e.length&&i<=r;a++){let s=e[a],c=i+s.length;c>=n&&(c>r&&(s=s.slice(0,r-i)),i<n&&(s=s.slice(n-i)),o?(t[t.length-1]+=s,o=!1):t.push(s)),i=c+1}return t}function _d(e,t,n){return gd(e,[``],t,n)}var vd=class{constructor(e,t=1){this.dir=t,this.done=!1,this.lineBreak=!1,this.value=``,this.nodes=[e],this.offsets=[t>0?1:(e instanceof pd?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let n=this.nodes.length-1,r=this.nodes[n],i=this.offsets[n],a=i>>1,o=r instanceof pd?r.text.length:r.children.length;if(a==(t>0?o:0)){if(n==0)return this.done=!0,this.value=``,this;t>0&&this.offsets[n-1]++,this.nodes.pop(),this.offsets.pop()}else if((i&1)==(t>0?0:1)){if(this.offsets[n]+=t,e==0)return this.lineBreak=!0,this.value=`
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>Castle Editor</title>
7
- <script type="module" crossorigin src="/__castle/ide/assets/index-B5mHPsrX.js"></script>
7
+ <script type="module" crossorigin src="/__castle/ide/assets/index-BU9_JpPe.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/__castle/ide/assets/index-wU4ol--C.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-cli",
3
- "version": "0.4.107",
3
+ "version": "0.4.108",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "castle-web": "./dist/index.js"
@@ -1,6 +0,0 @@
1
- // Printed for the editor terminal's `claude` shim to eval: the environment this
2
- // particular run should have, plus the real binary to exec (see
3
- // installClaudeShim in byo-auth.ts for why the decision can't live in the
4
- // shell's own environment).
5
- import { claudeShellEnvScript } from "./byo-auth.js";
6
- process.stdout.write(claudeShellEnvScript(process.env, process.argv[2] ?? ""));