teapot-coding-agent 0.2.0 → 0.4.0

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.
@@ -63,6 +63,7 @@ export class Agent {
63
63
  contextTokenBudget: 96_000,
64
64
  restoreSession: true,
65
65
  globalSkillsDir: "",
66
+ provider: "",
66
67
  ...opts,
67
68
  };
68
69
  this.log = new EventLog(opts.logFile, opts.id);
@@ -112,6 +113,14 @@ export class Agent {
112
113
  get workspace() {
113
114
  return this.opts.workspace;
114
115
  }
116
+ /** current LLM settings (read-only view) */
117
+ get llm() {
118
+ return this.opts.llm;
119
+ }
120
+ /** Swap LLM settings mid-flight; the next turn picks them up. */
121
+ setLlmConfig(llm) {
122
+ this.opts.llm = llm;
123
+ }
115
124
  async init() {
116
125
  await this.log.load();
117
126
  await fs.mkdir(this.workspace, { recursive: true });
@@ -280,6 +289,7 @@ export class Agent {
280
289
  latestProgress: this.latestProgress,
281
290
  stats: { ...this.stats },
282
291
  model: this.opts.llm.model,
292
+ provider: this.opts.provider,
283
293
  };
284
294
  }
285
295
  /** Queue a user prompt; wakes the loop if needed. Returns immediately. */
package/dist/master.js CHANGED
@@ -123,6 +123,8 @@ function printAgentEvent(e) {
123
123
  line = `${c("33", "🗜 compact")} tokens ${d.tokensBefore}→${d.tokensAfter} (${d.mode})`;
124
124
  else if (d.event === "session-restored")
125
125
  line = `${c("33", "⟲ restore")} branch ${d.branch}, ${d.messages} messages`;
126
+ else if (d.event === "model-changed")
127
+ line = `${c("33", "🧦 model")} → ${d.model} (${d.provider})`;
126
128
  break;
127
129
  }
128
130
  default:
@@ -218,6 +220,7 @@ export class Master {
218
220
  autoContinue: true,
219
221
  ...(this.config.contextTokenBudget ? { contextTokenBudget: this.config.contextTokenBudget } : {}),
220
222
  globalSkillsDir: path.join(CONFIG_DIR, "skills"),
223
+ provider: provName,
221
224
  });
222
225
  agent.log.onEvent = (e) => printAgentEvent(e);
223
226
  await agent.init();
@@ -237,6 +240,54 @@ export class Master {
237
240
  this.config.agents = this.config.agents.filter((a) => a.id !== id);
238
241
  this.saveConfig();
239
242
  }
243
+ /**
244
+ * Switch a running agent's model/provider mid-session.
245
+ * With provider: use that named provider's baseUrl/key (+ model override).
246
+ * Without: keep the current endpoint, swap only the model name.
247
+ * The choice is persisted on the agent config so it survives restarts.
248
+ */
249
+ setAgentModel(id, providerName, model) {
250
+ const agent = this.agents.get(id);
251
+ if (!agent)
252
+ throw new Error(`no such agent: ${id}`);
253
+ let llm;
254
+ let effectiveProvider = providerName ?? "";
255
+ if (providerName) {
256
+ const prov = this.config.providers?.[providerName];
257
+ if (!prov?.baseUrl)
258
+ throw new Error(`unknown provider: ${providerName}`);
259
+ llm = {
260
+ baseUrl: prov.baseUrl,
261
+ apiKey: prov.apiKey ?? "",
262
+ model: model || prov.model || "",
263
+ timeoutMs: 120_000,
264
+ };
265
+ }
266
+ else {
267
+ llm = { ...agent.llm };
268
+ if (model)
269
+ llm.model = model;
270
+ const ac = this.config.agents.find((a) => a.id === id);
271
+ effectiveProvider = ac?.provider ?? this.config.defaultProvider ?? "";
272
+ }
273
+ if (!llm.model)
274
+ throw new Error("no model resolved (pass model or set one on the provider)");
275
+ if (!llm.baseUrl)
276
+ throw new Error("no baseUrl resolved");
277
+ agent.setLlmConfig(llm);
278
+ const ac = this.config.agents.find((a) => a.id === id);
279
+ if (ac && providerName)
280
+ ac.provider = providerName;
281
+ if (ac)
282
+ ac.model = llm.model;
283
+ this.saveConfig();
284
+ void agent.log.append("system_note", agent.currentSession, agent.currentBranch, {
285
+ event: "model-changed",
286
+ provider: effectiveProvider,
287
+ model: llm.model,
288
+ });
289
+ return { provider: effectiveProvider, model: llm.model };
290
+ }
240
291
  /** 4 ticks/min; each tick is a few integer compares per task. */
241
292
  tick() {
242
293
  const now = new Date();
@@ -2,7 +2,8 @@
2
2
  * REST + SSE API on Hono, plus static file serving for the web UI.
3
3
  */
4
4
  import { Hono } from "hono";
5
- import { serve } from "@hono/node-server";
5
+ import { serve, upgradeWebSocket } from "@hono/node-server";
6
+ import { WebSocketServer } from "ws";
6
7
  import { readFileSync } from "node:fs";
7
8
  import { promises as fs } from "node:fs";
8
9
  import { fileURLToPath } from "node:url";
@@ -12,6 +13,45 @@ import { bus } from "../bus.js";
12
13
  import { readEvents } from "../log/events.js";
13
14
  export function buildApp(master) {
14
15
  const app = new Hono();
16
+ // ---- realtime events over WebSocket (replaces SSE for the web UI) ----
17
+ app.get("/api/ws", upgradeWebSocket(() => {
18
+ let onUpdate = null;
19
+ let ka = null;
20
+ return {
21
+ onOpen(_evt, ws) {
22
+ const send = (data) => {
23
+ try {
24
+ ws.send(JSON.stringify(data));
25
+ }
26
+ catch {
27
+ /* client gone */
28
+ }
29
+ };
30
+ send({ kind: "hello", agents: [...master.agents.values()].map((a) => a.snapshot()) });
31
+ onUpdate = (ev) => send(ev);
32
+ bus.on("update", onUpdate);
33
+ // app-level liveness ping every 30s
34
+ ka = setInterval(() => send({ kind: "ping" }), 30_000);
35
+ },
36
+ onMessage(evt, ws) {
37
+ // clients may send {"kind":"ping"} — nothing else to do today
38
+ try {
39
+ const m = JSON.parse(String(evt.data));
40
+ if (m?.kind === "ping")
41
+ ws.send(JSON.stringify({ kind: "pong" }));
42
+ }
43
+ catch {
44
+ /* ignore junk */
45
+ }
46
+ },
47
+ onClose() {
48
+ if (ka)
49
+ clearInterval(ka);
50
+ if (onUpdate)
51
+ bus.off("update", onUpdate);
52
+ },
53
+ };
54
+ }));
15
55
  // ---- agents ----
16
56
  app.get("/api/agents", (c) => c.json({ agents: [...master.agents.values()].map((a) => a.snapshot()) }));
17
57
  // create + start an agent on an arbitrary directory
@@ -138,6 +178,50 @@ export function buildApp(master) {
138
178
  a.start("api start");
139
179
  return c.json({ ok: true });
140
180
  });
181
+ // ---- providers & models (for the session panel's model switcher) ----
182
+ app.get("/api/providers", (c) => c.json({
183
+ providers: Object.entries(master.config.providers ?? {}).map(([name, p]) => ({
184
+ name,
185
+ baseUrl: p.baseUrl,
186
+ hasKey: !!p.apiKey,
187
+ model: p.model,
188
+ })),
189
+ defaultProvider: master.config.defaultProvider,
190
+ }));
191
+ // OpenAI-compatible upstream model listing (GET /v1/models)
192
+ app.get("/api/models", async (c) => {
193
+ const provName = c.req.query("provider") || master.config.defaultProvider || "";
194
+ const prov = master.config.providers?.[provName];
195
+ if (!prov?.baseUrl)
196
+ return c.json({ error: `unknown provider: ${provName}` }, 400);
197
+ try {
198
+ const res = await fetch(`${prov.baseUrl.replace(/\/+$/, "")}/models`, {
199
+ headers: prov.apiKey ? { authorization: `Bearer ${prov.apiKey}` } : {},
200
+ signal: AbortSignal.timeout(15_000),
201
+ });
202
+ if (!res.ok)
203
+ return c.json({ error: `upstream ${res.status}` }, 502);
204
+ const j = (await res.json());
205
+ const models = (j.data ?? []).map((m) => m.id).filter((x) => !!x).sort();
206
+ return c.json({ provider: provName, models });
207
+ }
208
+ catch (err) {
209
+ return c.json({ error: `model list failed: ${err.message}` }, 502);
210
+ }
211
+ });
212
+ // switch a running session's model/provider
213
+ app.post("/api/agents/:id/model", async (c) => {
214
+ const body = await c.req.json().catch(() => null);
215
+ if (!body)
216
+ return c.json({ error: "invalid JSON" }, 400);
217
+ try {
218
+ const r = master.setAgentModel(c.req.param("id"), body.provider, body.model);
219
+ return c.json({ ok: true, ...r });
220
+ }
221
+ catch (err) {
222
+ return c.json({ error: err.message }, 400);
223
+ }
224
+ });
141
225
  app.post("/api/agents/:id/stop", (c) => {
142
226
  const a = master.agents.get(c.req.param("id"));
143
227
  if (!a)
@@ -247,13 +331,22 @@ export function buildApp(master) {
247
331
  ".svg": "image/svg+xml",
248
332
  ".ico": "image/x-icon",
249
333
  };
250
- app.get("/", (c) => {
334
+ const indexHtml = () => {
251
335
  try {
252
- return c.html(readFileSync(path.join(webRoot, "index.html"), "utf8"));
336
+ return readFileSync(path.join(webRoot, "index.html"), "utf8");
253
337
  }
254
338
  catch {
255
- return c.text("web UI not built — run: pnpm build-web", 404);
339
+ return null;
256
340
  }
341
+ };
342
+ app.get("/", (c) => {
343
+ const html = indexHtml();
344
+ return html ? c.html(html) : c.text("web UI not built — run: pnpm build-web", 404);
345
+ });
346
+ // SPA deep links: /session/<agentId> serves the app; the client routes it
347
+ app.get("/session/*", (c) => {
348
+ const html = indexHtml();
349
+ return html ? c.html(html) : c.text("web UI not built — run: pnpm build-web", 404);
257
350
  });
258
351
  app.get("/assets/*", (c) => {
259
352
  const rel = c.req.path.replace("/assets/", "");
@@ -270,7 +363,8 @@ export function buildApp(master) {
270
363
  return app;
271
364
  }
272
365
  export function serveApp(app, port) {
273
- serve({ fetch: app.fetch, port }, (info) => {
366
+ const wss = new WebSocketServer({ noServer: true });
367
+ serve({ fetch: app.fetch, port, websocket: { server: wss } }, (info) => {
274
368
  console.log(`[teapot] master listening on http://localhost:${info.port}`);
275
369
  });
276
370
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teapot-coding-agent",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "A lightweight, always-on multi-agent harness for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-or-later",
@@ -38,12 +38,14 @@
38
38
  "test": "node --test test/*.test.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@hono/node-server": "^1.14.0",
41
+ "@hono/node-server": "^2.1.1",
42
42
  "hono": "^4.7.0",
43
- "openai": "^5.0.0"
43
+ "openai": "^5.0.0",
44
+ "ws": "^8.21.3"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@types/node": "^24.0.0",
48
+ "@types/ws": "^8.18.1",
47
49
  "solid-js": "^1.9.15",
48
50
  "typescript": "^5.8.0",
49
51
  "vite": "^8.2.2",
@@ -0,0 +1 @@
1
+ :root{--bg-darkest:#1a1c22;--bg-dark:#232630;--bg-mid:#2b2e39;--bg-light:#343845;--fg:#dcdee4;--dim:#9298a5;--line:#1d2027;--acc:#5865f2;--ok:#3ba55d;--warn:#faa81a;--err:#ed4245;--tool:#3ba0c9;font-family:gg sans,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--bg-dark);color:var(--fg);font-size:15px}.layout{grid-template-columns:250px 1fr 300px;height:100dvh;display:grid;overflow:hidden}.layout.right-hidden{grid-template-columns:250px 1fr}.layout.right-hidden .rightbar{display:none}@media (width<=1100px){.layout,.layout.right-hidden{grid-template-columns:220px 1fr}.layout.right-hidden .rightbar{display:block}.rightbar{z-index:5;width:min(320px,88vw);transition:transform .18s;position:fixed;top:0;bottom:0;right:0;transform:translate(100%);box-shadow:-8px 0 24px #0007}.rightbar.open{transform:none}}.sidebar{background:var(--bg-darkest);flex-direction:column;padding:10px 8px;display:flex;overflow-y:auto}.sidebar h1{color:var(--fg);flex-shrink:0;margin:0;padding:4px 8px 10px;font-size:14px}.agent-list{flex:1;min-height:0;overflow-y:auto}.agent-item{cursor:pointer;color:var(--dim);border-radius:6px;align-items:center;gap:8px;margin-bottom:2px;padding:7px 10px;display:flex}.agent-item:hover{background:var(--bg-mid)}.agent-item.sel{background:var(--bg-mid);color:var(--fg)}.dot{border-radius:50%;flex-shrink:0;width:9px;height:9px}.dot.running{background:var(--ok);box-shadow:0 0 6px var(--ok)}.dot.idle{background:var(--warn)}.dot.stopped{background:var(--dim)}.dot.error{background:var(--err);box-shadow:0 0 6px var(--err)}.sidebar .metrics{color:var(--dim);border-top:1px solid var(--line);margin-top:12px;padding:8px 10px;font-size:11px;line-height:1.7}.channel{flex-direction:column;min-width:0;min-height:0;display:flex;position:relative;overflow:hidden}.chan-head{border-bottom:2px solid var(--line);background:var(--bg-dark);flex-shrink:0;align-items:center;gap:10px;padding:10px 16px;display:flex}.chan-head .hash{color:var(--dim);font-size:20px}.chan-head .title{font-weight:700}.chan-head .sub{color:var(--dim);text-overflow:ellipsis;white-space:nowrap;margin-left:8px;font-size:12px;overflow:hidden}.badge{background:var(--bg-light);vertical-align:middle;border-radius:10px;padding:1px 8px;font-size:11px}.badge.running{color:var(--ok)}.badge.error{color:var(--err)}.badge.idle{color:var(--warn)}.badge.done{color:var(--acc)}.feed{overscroll-behavior:contain;flex:1;min-height:0;padding:14px 0 8px;overflow-y:auto}.msg{gap:14px;padding:3px 18px;display:flex}.msg:hover{background:#ffffff08}.msg.grouped{padding-top:0}.avatar{border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:38px;height:38px;margin-top:2px;font-size:17px;display:flex}.msg-body{flex:1;min-width:0}.msg-head{align-items:baseline;gap:8px;display:flex}.author{font-size:14.5px;font-weight:600}.ts{color:var(--dim);font-size:11px}.content{white-space:pre-wrap;word-break:break-word;line-height:1.45}.content p{margin:2px 0}.content pre{background:var(--bg-darkest);border-radius:6px;padding:8px;overflow-x:auto}.content code{background:var(--bg-darkest);border-radius:4px;padding:1px 4px;font-size:13px}.content h1,.content h2,.content h3,.content h4{margin:8px 0 2px;font-size:15px}.embed{border-left:3px solid var(--tool);background:var(--bg-darkest);border-radius:4px;margin-top:3px;padding:6px 10px;font-size:13.5px}.embed.fail{border-color:var(--err)}.embed summary{cursor:pointer;-webkit-user-select:none;user-select:none;list-style-position:outside}.embed summary::marker{color:var(--dim)}.embed[open] summary{margin-bottom:4px}.embed .mono{white-space:pre-wrap;word-break:break-word;max-height:340px;font-family:ui-monospace,Menlo,monospace;font-size:12.5px;overflow-y:auto}.embed .meta{color:var(--dim);margin-top:3px;font-size:11px}.reasoning{border-left:3px dashed var(--bg-light);color:var(--dim);background:#ffffff05;border-radius:4px;margin:2px 0;padding:2px 10px;font-size:12.5px}.reasoning summary{cursor:pointer;-webkit-user-select:none;user-select:none;opacity:.75}.reasoning summary:hover{opacity:1;color:var(--fg)}.reasoning[open] summary{margin-bottom:4px}.reasoning .mono{white-space:pre-wrap;word-break:break-word;max-height:260px;overflow-y:auto}.msg.live .avatar{animation:1.6s ease-in-out infinite pulse}.cursor{color:var(--acc);animation:1s step-end infinite blink}@keyframes blink{50%{opacity:0}}@keyframes pulse{50%{opacity:.55}}.conn{background:var(--err);vertical-align:middle;width:8px;height:8px;box-shadow:0 0 6px var(--err);border-radius:50%;margin-left:8px;display:inline-block}.conn.ok{background:var(--ok);box-shadow:0 0 6px var(--ok)}.copybtn{border:1px solid var(--bg-light);color:var(--dim);cursor:pointer;background:0 0;border-radius:4px;flex-shrink:0;padding:0 5px;font-size:11px;line-height:16px}.copybtn:hover{color:var(--fg);filter:brightness(1.3)}.embed summary{align-items:center;gap:6px;display:flex}.msgfoot{color:var(--dim);align-items:center;gap:6px;margin-top:4px;font-size:11px;display:flex}.jump{background:var(--acc);color:#fff;cursor:pointer;z-index:2;border:none;border-radius:999px;padding:6px 14px;font-size:12.5px;font-weight:600;position:absolute;bottom:86px;left:50%;transform:translate(-50%);box-shadow:0 4px 14px #0008}.divider-msg{color:var(--dim);align-items:center;gap:10px;padding:4px 18px;font-size:11.5px;display:flex}.divider-msg:before,.divider-msg:after{content:"";background:var(--line);flex:1;height:1px}.divider-msg.err{color:var(--err)}.day-divider{align-items:center;gap:10px;padding:14px 18px 6px;display:flex}.day-divider:before,.day-divider:after{content:"";background:var(--bg-light);flex:1;height:1px}.day-divider span{color:var(--dim);font-size:11px}.composer{padding:0 16px 18px}.composer form{background:var(--bg-light);border-radius:10px;align-items:center;gap:8px;padding:10px 12px;display:flex}.composer input[type=text]{color:var(--fg);font:inherit;background:0 0;border:none;outline:none;flex:1}.composer button{background:var(--acc);color:#fff;cursor:pointer;border:none;border-radius:8px;padding:7px 14px;font-weight:600}.composer button:hover{opacity:.9}.composer label{color:var(--dim);white-space:nowrap;align-items:center;gap:4px;font-size:12px;display:flex}.hint{color:var(--dim);margin-top:5px;font-size:11px}.rightbar{background:var(--bg-dark);border-left:2px solid var(--line);flex-direction:column;min-height:0;padding:14px;font-size:13px;display:flex;overflow-y:auto}.rightbar h3{text-transform:uppercase;letter-spacing:.04em;color:var(--dim);margin:14px 0 6px;font-size:11px}.rightbar h3:first-child{margin-top:0}.card{background:var(--bg-darkest);white-space:pre-wrap;word-break:break-word;border-radius:8px;max-height:200px;padding:10px;overflow-y:auto}.muted{color:var(--dim)}.branch-row{color:var(--dim);cursor:pointer;justify-content:space-between;padding:3px 0;font-size:12px;display:flex}.branch-row:hover,.branch-row.cur{color:var(--fg)}.sesscard{flex-direction:column;gap:6px;font-size:12.5px;display:flex}.sessrow{align-items:center;gap:8px;display:flex}.sessrow .k{color:var(--dim);text-transform:uppercase;letter-spacing:.05em;flex-shrink:0;width:74px;font-size:10px}.ellip{text-overflow:ellipsis;white-space:nowrap;text-align:left;direction:rtl;overflow:hidden}.modelbox{background:var(--bg-darkest);border-radius:8px;flex-direction:column;gap:6px;padding:10px;display:flex}.modelbox select,.modelbox input[type=text]{background:var(--bg-mid);color:var(--fg);font:inherit;border:none;border-radius:6px;outline:none;min-width:0;padding:6px 8px}.modelbox button{background:var(--acc);color:#fff;cursor:pointer;white-space:nowrap;border:none;border-radius:6px;padding:6px 10px;font-size:12.5px;font-weight:600}.modelbox button:hover{opacity:.9}.modelbox .meta{color:var(--dim);font-size:11px}.btnrow{gap:6px;margin:8px 0;display:flex}.btnrow button{background:var(--bg-light);color:var(--fg);cursor:pointer;border:none;border-radius:6px;padding:6px 10px;font-size:13px}.btnrow button:hover{filter:brightness(1.2)}.iconbtn{background:var(--bg-light);color:var(--fg);cursor:pointer;border:none;border-radius:6px;width:26px;height:24px;font-size:13px}.iconbtn:hover{filter:brightness(1.3)}.overlay{z-index:10;background:#0009;place-items:center;display:grid;position:fixed;inset:0}.modal{background:var(--bg-mid);border-radius:10px;width:min(620px,92vw);max-height:88vh;padding:16px 18px;overflow-y:auto}.modal-head{justify-content:space-between;align-items:center;margin-bottom:12px;font-size:16px;display:flex}.modal label{color:var(--dim);flex-direction:column;gap:4px;font-size:12.5px;display:flex}.modal input[type=text],.modal input[type=number],.modal select,.modal textarea{background:var(--bg-darkest);color:var(--fg);font:inherit;border:none;border-radius:6px;outline:none;padding:7px 9px}.modal textarea{resize:vertical}.w100{width:100%}.mono{font-family:ui-monospace,Menlo,monospace;font-size:13px}.dirlist{background:var(--bg-darkest);border-radius:6px;max-height:160px;padding:4px;overflow-y:auto}.direntry{cursor:pointer;border-radius:4px;padding:4px 8px;font-size:14px}.direntry:hover{background:var(--bg-light)}
@@ -0,0 +1,8 @@
1
+ (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return t(this.context.count)},getNextContextId(){return t(this.context.count++)}};function t(t){let n=String(t),r=n.length-1;return e.context.id+(r?String.fromCharCode(96+r):``)+n}function n(t){e.context=t}var r=(e,t)=>e===t,i=Symbol(`solid-track`),a={equals:r},o=null,s=oe,c=1,l=2,u={owned:null,cleanups:null,context:null,owner:null},d=null,f=null,p=null,m=null,h=null,g=0;function _(e,t){let n=p,r=d,i=e.length===0,a=t===void 0?r:t,o=i?u:{owned:null,cleanups:null,context:a?a.context:null,owner:a},s=i?e:()=>e(()=>S(()=>N(o)));d=o,p=null;try{return A(s,!0)}finally{p=n,d=r}}function v(e,t){t=t?Object.assign({},a,t):a;let n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0};return[E.bind(n),e=>(typeof e==`function`&&(e=f&&f.running&&f.sources.has(n)?e(n.tValue):e(n.value)),re(n,e))]}function y(e,t,n){D(O(e,t,!1,c))}function b(e,t,n){s=se;let r=O(e,t,!1,c),i=ne&&te(ne);i&&(r.suspense=i),(!n||!n.render)&&(r.user=!0),h?h.push(r):D(r)}function x(e,t,n){n=n?Object.assign({},a,n):a;let r=O(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,D(r),E.bind(r)}function S(e){if(p===null)return e();let t=p;p=null;try{return e()}finally{p=t}}function ee(e){b(()=>S(e))}function C(e){return d===null||(d.cleanups===null?d.cleanups=[e]:d.cleanups.push(e)),e}var[w,T]=v(!1);function te(e){let t;return d&&d.context&&(t=d.context[e.id])!==void 0?t:e.defaultValue}var ne;function E(){let e=f&&f.running;if(this.sources&&(e?this.tState:this.state)){if((e?this.tState:this.state)===c)D(this);else{let e=m;m=null,A(()=>j(this),!1),m=e}}if(p){let e=this.observers;if(!e||e[e.length-1]!==p){let t=e?e.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(t)):(p.sources=[this],p.sourceSlots=[t]),e?(e.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}}return e&&f.sources.has(this)?this.tValue:this.value}function re(e,t,n){let r=f&&f.running&&f.sources.has(e)?e.tValue:e.value;if(!e.comparator||!e.comparator(r,t)){if(f){let r=f.running;(r||!n&&f.sources.has(e))&&(f.sources.add(e),e.tValue=t),r||(e.value=t)}else e.value=t;e.observers&&e.observers.length&&A(()=>{for(let t=0;t<e.observers.length;t+=1){let n=e.observers[t],r=f&&f.running;r&&f.disposed.has(n)||((r?!n.tState:!n.state)&&(n.pure?m.push(n):h.push(n),n.observers&&M(n)),r?n.tState=c:n.state=c)}if(m.length>1e6)throw m=[],Error()},!1)}return t}function D(e){if(!e.fn)return;N(e);let t=g;ie(e,f&&f.running&&f.sources.has(e)?e.tValue:e.value,t),f&&!f.running&&f.sources.has(e)&&queueMicrotask(()=>{A(()=>{f&&(f.running=!0),p=d=e,ie(e,e.tValue,t),p=d=null},!1)})}function ie(e,t,n){let r,i=d,a=p;p=d=e;try{r=e.fn(t)}catch(t){return e.pure&&(f&&f.running?(e.tState=c,e.tOwned&&e.tOwned.forEach(N),e.tOwned=void 0):(e.state=c,e.owned&&e.owned.forEach(N),e.owned=null)),e.updatedAt=n+1,I(t)}finally{p=a,d=i}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&`observers`in e?re(e,r,!0):f&&f.running&&e.pure?(f.sources.has(e)||(e.value=r),f.sources.add(e),e.tValue=r):e.value=r,e.updatedAt=n)}function O(e,t,n,r=c,i){let a={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:d,context:d?d.context:null,pure:n};return f&&f.running&&(a.state=0,a.tState=r),d===null||d!==u&&(f&&f.running&&d.pure?d.tOwned?d.tOwned.push(a):d.tOwned=[a]:d.owned?d.owned.push(a):d.owned=[a]),a}function k(e){let t=f&&f.running;if((t?e.tState:e.state)===0)return;if((t?e.tState:e.state)===l)return j(e);if(e.suspense&&S(e.suspense.inFallback))return e.suspense.effects.push(e);let n=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<g);){if(t&&f.disposed.has(e))return;(t?e.tState:e.state)&&n.push(e)}for(let r=n.length-1;r>=0;r--){if(e=n[r],t){let t=e,i=n[r+1];for(;(t=t.owner)&&t!==i;)if(f.disposed.has(t))return}if((t?e.tState:e.state)===c)D(e);else if((t?e.tState:e.state)===l){let t=m;m=null,A(()=>j(e,n[0]),!1),m=t}}}function A(e,t){if(m)return e();let n=!1;t||(m=[]),h?n=!0:h=[],g++;try{let t=e();return ae(n),t}catch(e){n||(h=null),m=null,I(e)}}function ae(e){if(m&&=(oe(m),null),e)return;let t;if(f){if(!f.promises.size&&!f.queue.size){let e=f.sources,n=f.disposed;h.push.apply(h,f.effects),t=f.resolve;for(let e of h)`tState`in e&&(e.state=e.tState),delete e.tState;f=null,A(()=>{for(let e of n)N(e);for(let t of e){if(t.value=t.tValue,t.owned)for(let e=0,n=t.owned.length;e<n;e++)N(t.owned[e]);t.tOwned&&(t.owned=t.tOwned),delete t.tValue,delete t.tOwned,t.tState=0}T(!1)},!1)}else if(f.running){f.running=!1,f.effects.push.apply(f.effects,h),h=null,T(!0);return}}let n=h;h=null,n.length&&A(()=>s(n),!1),t&&t()}function oe(e){for(let t=0;t<e.length;t++)k(e[t])}function se(t){let r,i=0;for(r=0;r<t.length;r++){let e=t[r];e.user?t[i++]=e:k(e)}if(e.context){if(e.count){e.effects||=[],e.effects.push(...t.slice(0,i));return}n()}for(e.effects&&(e.done||!e.count)&&(t=[...e.effects,...t],i+=e.effects.length,delete e.effects),r=0;r<i;r++)k(t[r])}function j(e,t){let n=f&&f.running;n?e.tState=0:e.state=0;for(let r=0;r<e.sources.length;r+=1){let i=e.sources[r];if(i.sources){let e=n?i.tState:i.state;e===c?i!==t&&(!i.updatedAt||i.updatedAt<g)&&k(i):e===l&&j(i,t)}}}function M(e){let t=f&&f.running;for(let n=0;n<e.observers.length;n+=1){let r=e.observers[n];(t?!r.tState:!r.state)&&(t?r.tState=l:r.state=l,r.pure?m.push(r):h.push(r),r.observers&&M(r))}}function N(e){let t;if(e.sources)for(;e.sources.length;){let t=e.sources.pop(),n=e.sourceSlots.pop(),r=t.observers;if(r&&r.length){let e=r.pop(),i=t.observerSlots.pop();n<r.length&&(e.sourceSlots[i]=n,r[n]=e,t.observerSlots[n]=i)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)N(e.tOwned[t]);delete e.tOwned}if(f&&f.running&&e.pure)P(e,!0);else if(e.owned){for(t=e.owned.length-1;t>=0;t--)N(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}f&&f.running?e.tState=0:e.state=0}function P(e,t){if(t||(e.tState=0,f.disposed.add(e)),e.owned)for(let t=0;t<e.owned.length;t++)P(e.owned[t])}function ce(e){return e instanceof Error?e:Error(typeof e==`string`?e:`Unknown error`,{cause:e})}function F(e,t,n){try{for(let n of t)n(e)}catch(e){I(e,n&&n.owner||null)}}function I(e,t=d){let n=o&&t&&t.context&&t.context[o],r=ce(e);if(!n)throw r;h?h.push({fn(){F(r,n,t)},state:c}):F(r,n,t)}var L=Symbol(`fallback`);function R(e){for(let t=0;t<e.length;t++)e[t]()}function le(e,t,n={}){let r=[],a=[],o=[],s=0,c=t.length>1?[]:null;return C(()=>R(o)),()=>{let l=e()||[],u=l.length,d,f;return l[i],S(()=>{let e,t,i,m,h,g,v,y,b;if(u===0)s!==0&&(R(o),o=[],r=[],a=[],s=0,c&&=[]),n.fallback&&(r=[L],a[0]=_(e=>(o[0]=e,n.fallback())),s=1);else if(s===0){for(a=Array(u),f=0;f<u;f++)r[f]=l[f],a[f]=_(p);s=u}else{for(i=Array(u),m=Array(u),c&&(h=Array(u)),g=0,v=Math.min(s,u);g<v&&r[g]===l[g];g++);for(v=s-1,y=u-1;v>=g&&y>=g&&r[v]===l[y];v--,y--)i[y]=a[v],m[y]=o[v],c&&(h[y]=c[v]);for(e=new Map,t=Array(y+1),f=y;f>=g;f--)b=l[f],d=e.get(b),t[f]=d===void 0?-1:d,e.set(b,f);for(d=g;d<=v;d++)b=r[d],f=e.get(b),f!==void 0&&f!==-1?(i[f]=a[d],m[f]=o[d],c&&(h[f]=c[d]),f=t[f],e.set(b,f)):o[d]();for(f=g;f<u;f++)f in i?(a[f]=i[f],o[f]=m[f],c&&(c[f]=h[f],c[f](f))):a[f]=_(p);a=a.slice(0,s=u),r=l.slice(0)}return a});function p(e){if(o[f]=e,c){let[e,n]=v(f);return c[f]=n,t(l[f],e)}return t(l[f])}}}function z(e,t){return S(()=>e(t||{}))}var ue=e=>`Stale read from <${e}>.`;function B(e){let t=`fallback`in e&&{fallback:()=>e.fallback};return x(le(()=>e.each,e.children,t||void 0))}function V(e){let t=e.keyed,n=x(()=>e.when,void 0,void 0),r=t?n:x(n,void 0,{equals:(e,t)=>!e==!t});return x(()=>{let i=r();if(i){let a=e.children;return typeof a==`function`&&a.length>0?S(()=>a(t?i:()=>{if(!S(r))throw ue(`Show`);return n()})):a}return e.fallback},void 0,void 0)}var H=e=>x(()=>e());function de(e,t,n){let r=n.length,i=t.length,a=r,o=0,s=0,c=t[i-1].nextSibling,l=null;for(;o<i||s<a;){if(t[o]===n[s]){o++,s++;continue}for(;t[i-1]===n[a-1];)i--,a--;if(i===o){let t=a<r?s?n[s-1].nextSibling:n[a-s]:c;for(;s<a;)e.insertBefore(n[s++],t)}else if(a===s)for(;o<i;)(!l||!l.has(t[o]))&&t[o].remove(),o++;else if(t[o]===n[a-1]&&n[s]===t[i-1]){let r=t[--i].nextSibling;e.insertBefore(n[s++],t[o++].nextSibling),e.insertBefore(n[--a],r),t[i]=n[a]}else{if(!l){l=new Map;let e=s;for(;e<a;)l.set(n[e],e++)}let r=l.get(t[o]);if(r!=null){if(s<r&&r<a){let c=o,u=1,d;for(;++c<i&&c<a&&(d=l.get(t[c]))!=null&&d===r+u;)u++;if(u>r-s){let i=t[o];for(;s<r;)e.insertBefore(n[s++],i)}else e.replaceChild(n[s++],t[o++])}else o++}else t[o++].remove()}}}var U=`_$DX_DELEGATE`;function W(e,t,n,r={}){let i;return _(r=>{i=r,t===document?e():Y(t,e(),t.firstChild?null:void 0,n)},r.owner),()=>{i(),t.textContent=``}}function G(e,t,n,r){let i,a=()=>{let t=r?document.createElementNS(`http://www.w3.org/1998/Math/MathML`,`template`):document.createElement(`template`);return t.innerHTML=e,n?t.content.firstChild.firstChild:r?t.firstChild:t.content.firstChild},o=t?()=>S(()=>document.importNode(i||=a(),!0)):()=>(i||=a()).cloneNode(!0);return o.cloneNode=o,o}function fe(e,t=window.document){let n=t[U]||(t[U]=new Set);for(let r=0,i=e.length;r<i;r++){let i=e[r];n.has(i)||(n.add(i),t.addEventListener(i,me))}}function K(e,t,n){X(e)||(n==null?e.removeAttribute(t):e.setAttribute(t,n))}function q(e,t){X(e)||(t==null?e.removeAttribute(`class`):e.className=t)}function pe(e,t,n,r){if(r)Array.isArray(n)?(e[`$$${t}`]=n[0],e[`$$${t}Data`]=n[1]):e[`$$${t}`]=n;else if(Array.isArray(n)){let r=n[0];e.addEventListener(t,n[0]=t=>r.call(e,n[1],t))}else e.addEventListener(t,n,typeof n!=`function`&&n)}function J(e,t,n){n==null?e.style.removeProperty(t):e.style.setProperty(t,n)}function Y(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!=`function`)return Z(e,t,r,n);y(r=>Z(e,t(),r,n),r)}function X(t){return!!e.context&&!e.done&&(!t||t.isConnected)}function me(t){if(e.registry&&e.events&&e.events.find(([e,n])=>n===t))return;let n=t.target,r=`$$${t.type}`,i=t.target,a=t.currentTarget,o=e=>Object.defineProperty(t,"target",{configurable:!0,value:e}),s=()=>{let e=n[r];if(e&&!n.disabled){let i=n[`${r}Data`];if(i===void 0?e.call(n,t):e.call(n,i,t),t.cancelBubble)return}return n.host&&typeof n.host!=`string`&&!n.host._$host&&n.contains(t.target)&&o(n.host),!0},c=()=>{for(;s()&&(n=n._$host||n.parentNode||n.host););};if(Object.defineProperty(t,"currentTarget",{configurable:!0,get(){return n||document}}),e.registry&&!e.done&&(e.done=_$HY.done=!0),t.composedPath){let e=t.composedPath();o(e[0]);for(let t=0;t<e.length-2&&(n=e[t],s());t++){if(n._$host){n=n._$host,c();break}if(n.parentNode===a)break}}else c();o(i)}function Z(e,t,n,r,i){let a=X(e);if(a){!n&&(n=[...e.childNodes]);let t=[];for(let e=0;e<n.length;e++){let r=n[e];r.nodeType===8&&r.data.slice(0,2)===`!$`?r.remove():t.push(r)}n=t}for(;typeof n==`function`;)n=n();if(t===n)return n;let o=typeof t,s=r!==void 0;if(e=s&&n[0]&&n[0].parentNode||e,o===`string`||o===`number`){if(a||o===`number`&&(t=t.toString(),t===n))return n;if(s){let i=n[0];i&&i.nodeType===3?i.data!==t&&(i.data=t):i=document.createTextNode(t),n=Q(e,n,r,i)}else n=n!==``&&typeof n==`string`?e.firstChild.data=t:e.textContent=t}else if(t==null||o===`boolean`){if(a)return n;n=Q(e,n,r)}else if(o===`function`)return y(()=>{let i=t();for(;typeof i==`function`;)i=i();n=Z(e,i,n,r)}),()=>n;else if(Array.isArray(t)){let o=[],c=n&&Array.isArray(n);if(he(o,t,n,i))return y(()=>n=Z(e,o,n,r,!0)),()=>n;if(a){if(!o.length)return n;if(r===void 0)return n=[...e.childNodes];let t=o[0];if(t.parentNode!==e)return n;let i=[t];for(;(t=t.nextSibling)!==r;)i.push(t);return n=i}if(o.length===0){if(n=Q(e,n,r),s)return n}else c?n.length===0?ge(e,o,r):de(e,n,o):(n&&Q(e),ge(e,o));n=o}else if(t.nodeType){if(a&&t.parentNode)return n=s?[t]:t;if(Array.isArray(n)){if(s)return n=Q(e,n,r,t);Q(e,n,null,t)}else n==null||n===``||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}return n}function he(e,t,n,r){let i=!1;for(let a=0,o=t.length;a<o;a++){let o=t[a],s=n&&n[e.length],c;if(o!=null&&o!==!0&&o!==!1){if((c=typeof o)==`object`&&o.nodeType)e.push(o);else if(Array.isArray(o))i=he(e,o,s)||i;else if(c===`function`){if(r){for(;typeof o==`function`;)o=o();i=he(e,Array.isArray(o)?o:[o],Array.isArray(s)?s:[s])||i}else e.push(o),i=!0}else{let t=String(o);s&&s.nodeType===3&&s.data===t?e.push(s):e.push(document.createTextNode(t))}}}return i}function ge(e,t,n=null){for(let r=0,i=t.length;r<i;r++)e.insertBefore(t[r],n)}function Q(e,t,n,r){if(n===void 0)return e.textContent=``;let i=r||document.createTextNode(``);if(t.length){let r=!1;for(let a=t.length-1;a>=0;a--){let o=t[a];if(i!==o){let t=o.parentNode===e;!r&&!a?t?e.replaceChild(i,o):e.insertBefore(i,n):t&&o.remove()}else r=!0}}else e.insertBefore(i,n);return[i]}function _e(e){let t=ve(e.replace(/\r\n/g,`
2
+ `)).split(`
3
+ `),n=[],r=0;for(;r<t.length;){let e=t[r];if(/^```\w*\s*$/.test(e)){let e=[];for(r++;r<t.length&&!/^```\s*$/.test(t[r]);)e.push(t[r++]);r++,n.push(`<pre><code>${e.join(`
4
+ `)}</code></pre>`);continue}let a=e.match(/^(#{1,4})\s+(.*)$/);if(a){n.push(`<h${a[1].length}>${i(a[2])}</h${a[1].length}>`),r++;continue}let o=/^\s*\d+[.)]\s+/.test(e);if(o||/^\s*[-*]\s+/.test(e)){let e=[];for(;r<t.length;){let n=t[r].match(/^\s*[-*]\s+(.*)$/)??(o?t[r].match(/^\s*\d+[.)]\s+(.*)$/):null);if(!n)break;e.push(`<li>${i(n[1])}</li>`),r++}n.push(o?`<ol>${e.join(``)}</ol>`:`<ul>${e.join(``)}</ul>`);continue}if(/^\s*$/.test(e)){r++;continue}let s=[];for(;r<t.length&&!/^\s*$/.test(t[r])&&!/^#{1,4}\s/.test(t[r])&&!/^```/.test(t[r])&&!/^\s*([-*]|\d+[.)])\s/.test(t[r]);)s.push(t[r++]);n.push(`<p>${s.map(i).join(`<br>`)}</p>`)}return n.join(`
5
+ `);function i(e){return e.replace(/`([^`]+)`/g,`<code>$1</code>`).replace(/\*\*([^*]+)\*\*/g,`<strong>$1</strong>`).replace(/(^|\W)\*([^*]+)\*(?=\W|$)/g,`$1<em>$2</em>`).replace(/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,`<a href="$2" rel="noopener noreferrer" target="_blank">$1</a>`)}}function ve(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}var ye=G(`<br>`),be=G(`<span class=sub>ℹ`),xe=G(`<header class=chan-head><span class=hash>#</span><span class=title></span><span></span><span class=sub> · <!>/<!> · turns <!> · tools </span><span style=margin-left:auto;display:flex;gap:4px><button class=iconbtn title="toggle details panel (d)">▤`),Se=G(`<details class=reasoning><summary>💭 reasoning</summary><div class=mono>`),Ce=G(`<div class=content><span class=cursor>▍`),we=G(`<div class="msg live"><div class=avatar style="background:#5865f233;border:1px solid #5865f266">🫖</div><div class=msg-body><div class=msg-head><span class=author style=color:var(--acc)>agent</span><span class=ts>streaming…`),Te=G(`<div class=feed>`),Ee=G(`<button class=jump>↓ `),De=G(`<div class=composer><form><input type=text><label><input type=checkbox>auto-start</label><button type=submit>send</button></form><div class=hint>enter send · ↑↓ sessions · / focus · d panel · esc stop · prompts queue while the agent works`),Oe=G(`<h3>🎛 session`),ke=G(`<div class="card sesscard"><div class=sessrow><span class=k>agent</span><b></b><span></span></div><div class=sessrow><span class=k>workspace</span><span class="mono ellip"></span></div><div class=sessrow><span class=k>session</span><span class=mono>/`),Ae=G(`<h3>🧦 model`),je=G(`<div class=modelbox><select title="provider (OpenAI-compatible endpoint)"></select><div style=display:flex;gap:4px><input type=text list=model-list style=flex:1;min-width:0><datalist id=model-list></datalist><button title="apply model to this session">apply</button></div><div class=meta>current: `),Me=G(`<h3>⏯ controls`),Ne=G(`<div class=btnrow><button title="run toward the goal">▶ start</button><button title="interrupt after the current tool finishes">■ stop</button><button>⑂ fork</button><button title="remove agent">🗑`),Pe=G(`<h3>🎯 goal <span>`),Fe=G(`<form style=display:flex;gap:4px;margin-bottom:6px><input id=goal-input type=text placeholder="set new goal…"style="flex:1;background:var(--bg-darkest);border:none;border-radius:6px;padding:6px 8px;color:var(--fg);font:inherit"><button type=submit style="background:var(--acc);border:none;border-radius:6px;color:#fff;padding:0 10px;cursor:pointer">✓`),Ie=G(`<div class=card>`),Le=G(`<h3>📈 progress`),Re=G(`<div class=card>
6
+ <!>
7
+ <span class=muted>`),ze=G(`<h3>📊 runtime`),Be=G(`<div class="card muted">turns <!> · tools <!> · compacted <!>
8
+ tokens in/out <!>/`),Ve=G(`<h3>🌿 branches`),He=G(`<div><nav class=sidebar><h1>🫖 teapot<span></span><span style=float:right;display:flex;gap:4px><button class=iconbtn title="new agent">+</button><button class=iconbtn title=settings>⚙</button></span></h1><div class=agent-list></div><div class=metrics></div></nav><section class=channel></section><aside>`),Ue=G(`<span title="goal done">✓`),We=G(`<div><span></span><span>`),Ge=G(`<div class=muted style=display:grid;place-items:center;height:100%>select an agent`),Ke=G(`<div class=muted style=display:grid;place-items:center;height:100%>no events yet — say something or press ▶ start`),qe=G(`<div class="content muted">thinking…`),Je=G(`<option>`),Ye=G(`<div class=muted>none yet`),Xe=G(`<div><span>`),Ze=G(`<div> → `),Qe=G(`<div class=avatar>`),$e=G(`<div class=msg-head><span class=author></span><span class=ts></span><span class=ts>`),et=G(`<div><div class=msg-body>`),tt=G(`<span style=width:38px>`),nt=G(`<div class=content>`),rt=G(`<div class=msgfoot><span>copy summary`),it=G(`<details class=embed><summary><b>⚙ </b> <span class=meta></span></summary><div class=mono>`),at=G(`<details><summary><span class=meta></span></summary><div class=mono></div><div class=meta>ms`),ot=G(`<div class=meta>`),st=G(`<div class=meta>⚠ `),ct=G(`<div class=meta>→ `),lt=G(`<div class=embed style=border-color:var(--ok)><div>📈 `),ut=G(`<div class="embed fail"><div class=mono>⚠ `),dt=G(`<div class="content muted">`),ft=G(`<button class=copybtn title="copy to clipboard">`),pt=G(`<div class=overlay><div class=modal><div class=modal-head><b></b><button class=iconbtn>✕`),mt=G(`<span style=color:var(--err);font-size:13px>`),ht=G(`<form style=display:flex;flex-direction:column;gap:10px><label>workspace directory<div style=display:flex;gap:6px><input type=text class="w100 mono"><button type=button>go</button><button type=button>↑</button></div></label><div class=dirlist></div><div style=display:flex;gap:10px><label style=flex:1>agent name <input type=text placeholder="(directory name)"></label><label>provider<select></select></label><label style=flex:1>model <input type=text placeholder="(provider default)"></label></div><button type=submit style=align-self:flex-end>create & start`),gt=G(`<div class=direntry>📁 `),_t=G(`<form style=display:flex;flex-direction:column;gap:10px><label>providers (<!>)<textarea rows=8 class="mono w100"></textarea></label><div style=display:flex;gap:10px><label style=flex:1>default provider <input type=text></label><label>progress interval (min) <input type=number min=1 style=width:90px></label></div><label>scheduled tasks (JSON array)<textarea rows=7 class="mono w100"></textarea></label><button type=submit style=align-self:flex-end>save`),vt={user:{name:`you`,icon:`🧑`,color:`#faa81a`},message:{name:`agent`,icon:`🫖`,color:`#5865f2`},tool_call:{name:`tool`,icon:`🔧`,color:`#3ba0c9`},progress:{name:`progress`,icon:`📈`,color:`#3ba55d`}},yt=e=>vt[e.type]??{name:e.type,icon:`•`,color:`#9298a5`},bt=new Set([`user`,`message`,`prompt`,`tool_call`,`tool_result`,`progress`]),xt=e=>bt.has(e.type),St=e=>{let t=new Date(e);return`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`};async function $(e,t){let n=await fetch(e,t);if(!n.ok)throw Error(`${e}: ${n.status}`);return n.json()}function Ct(){let[e,t]=v([]),[n,r]=v(null),[i,a]=v([]),[o,s]=v([]),[c,l]=v(null),[u,d]=v(``),[f,p]=v(!0),[m,h]=v({providers:{}}),[g,_]=v(!1),[S,w]=v(!1),[T,te]=v(localStorage.getItem(`teapot.panel`)===null?window.innerWidth>1100:localStorage.getItem(`teapot.panel`)===`1`),ne=()=>{te(!T()),localStorage.setItem(`teapot.panel`,T()?`1`:`0`)},[E,re]=v(``),[D,ie]=v(``),[O,k]=v([]),A=()=>Object.keys(m().providers??{});async function ae(e){if(e)try{let t=await $(`/api/models?provider=${encodeURIComponent(e)}`);k(t.models??[])}catch{k([])}}b(()=>{let e=I();e&&(re(e.provider||m().defaultProvider||A()[0]||``),ie(``),ae(E()))});let[oe,se]=v(!0),[j,M]=v(0),[N,P]=v(null),ce=x(()=>i().filter(xt)),F=()=>$(`/api/config`).then(h).catch(()=>{}),I=x(()=>e().find(e=>e.id===n())),L=()=>$(`/api/agents`).then(e=>t(e.agents)).catch(()=>{}),R=()=>$(`/api/metrics`).then(l).catch(()=>{});async function le(e){try{let[t,n]=await Promise.all([$(`/api/agents/${e}/events?limit=300`),$(`/api/agents/${e}/branches`)]);a(t.events),s(n.branches)}catch{}}function ue(){return document.querySelector(`.feed`)}function de(){let e=ue();return!e||e.scrollHeight-e.scrollTop-e.clientHeight<80}function U(e=!1){let t=ue();t&&(e||oe())&&(t.scrollTop=t.scrollHeight,M(0))}async function W(e,t=!0){r(e),P(null),localStorage.setItem(`teapot.session`,e),he(e,t),await le(e),requestAnimationFrame(()=>U(!0))}let[G,fe]=v(!1),J=null,X=null;C(()=>J?.close());function me(){let e=location.protocol===`https:`?`wss://`:`ws://`;J=new WebSocket(`${e}${location.host}/api/ws`),J.onopen=()=>fe(!0),J.onclose=()=>{fe(!1),setTimeout(me,1500)},J.onerror=()=>J?.close(),J.onmessage=e=>{let t=JSON.parse(e.data);if(t.kind!==`ping`&&t.kind!==`pong`){if(t.kind===`llm-delta`){t.agentId===n()&&P({text:t.text??``,reasoning:t.reasoning??``});return}X||=setTimeout(async()=>{if(X=null,await L(),await R(),n()){let e=i().length;await le(n()),i().length!==e&&(P(null),de()?U(!0):M(j()+(i().length-e)))}},400)}}}let Z=()=>decodeURIComponent(location.pathname.split(`/`)[2]??``);function he(e,t=!0){let n=`/session/${encodeURIComponent(e)}`;t?history.pushState(null,``,n):history.replaceState(null,``,n)}window.addEventListener(`popstate`,()=>{let t=Z();t&&e().some(e=>e.id===t)&&t!==n()&&W(t,!1)}),b(()=>{let e=I();document.title=e?`${e.status===`running`?`▶ `:e.status===`error`?`⚠ `:``}${e.id} · teapot`:`teapot`}),window.addEventListener(`keydown`,t=>{let r=t.target;if(r&&(r.tagName===`INPUT`||r.tagName===`TEXTAREA`||r.isContentEditable)){t.key===`Escape`&&r.blur();return}if(t.key===`Escape`){if(g()){_(!1);return}if(S()){w(!1);return}let e=I();if(e?.status===`running`){$(`/api/agents/${e.id}/stop`,{method:`POST`}).then(L);return}T()&&window.innerWidth<=1100&&te(!1);return}if(!(g()||S())){if(t.key===`/`)t.preventDefault(),document.querySelector(`.composer input[type=text]`)?.focus();else if(t.key===`d`)ne();else if(t.key===`ArrowDown`||t.key===`ArrowUp`){let r=e();if(r.length===0)return;t.preventDefault();let i=r.findIndex(e=>e.id===n()),a=t.key===`ArrowDown`?Math.min(i+1,r.length-1):Math.max(i-1,0);a!==i&&W(r[a].id)}}}),ee(()=>{F(),L().then(()=>{let t=Z()||localStorage.getItem(`teapot.session`)||``,n=e().find(e=>e.id===t)??e()[0];n&&W(n.id,!1)}),R(),me(),setInterval(R,3e4)});let ge=async e=>{if(e.preventDefault(),!n()||!u().trim())return;let t=u();d(``),await $(`/api/agents/${n()}/prompt`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({text:t,start:f()})})},Q=e=>()=>n()&&$(`/api/agents/${n()}${e}`,{method:`POST`}).then(L),_e=async e=>{e.preventDefault();let t=document.getElementById(`goal-input`);!n()||!t.value.trim()||(await $(`/api/agents/${n()}/goal`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({text:t.value})}),t.value=``,L())};return[(()=>{var i=He(),a=i.firstChild,s=a.firstChild,l=s.firstChild.nextSibling,h=l.nextSibling.firstChild,g=h.nextSibling,v=s.nextSibling,b=v.nextSibling,x=a.nextSibling,S=x.nextSibling;return h.$$click=()=>{F(),_(!0)},g.$$click=()=>{F(),w(!0)},Y(v,z(B,{get each(){return e()},children:e=>(()=>{var t=We(),r=t.firstChild,i=r.nextSibling;return t.$$click=()=>W(e.id),Y(i,()=>e.id),Y(t,z(V,{get when(){return e.goal.status===`done`},get children(){return Ue()}}),null),y(i=>{var a=`agent-item`+(e.id===n()?` sel`:``),o=`dot ${e.status}`;return a!==i.e&&q(t,i.e=a),o!==i.t&&q(r,i.t=o),i},{e:void 0,t:void 0}),t})()})),Y(b,z(V,{get when(){return c()},get children(){return[`master rss `,H(()=>c().rssMb),`MB · heap `,H(()=>c().heapUsedMb),`MB`,ye(),`load1 `,H(()=>c().loadavg1),` · up `,H(()=>Math.floor(c().uptimeSec/60)),`m`]}})),Y(x,z(V,{get when(){return I()},get fallback(){return Ge()},get children(){return[(()=>{var e=xe(),t=e.firstChild.nextSibling,n=t.nextSibling,r=n.nextSibling,i=r.firstChild,a=i.nextSibling,o=a.nextSibling.nextSibling,s=o.nextSibling.nextSibling;s.nextSibling;var c=r.nextSibling,l=c.firstChild;return Y(t,()=>I().id),Y(n,()=>I().status),Y(r,()=>I().model,i),Y(r,()=>I().session,a),Y(r,()=>I().branch,o),Y(r,()=>I().stats.turns,s),Y(r,()=>I().stats.toolCalls,null),Y(c,z(V,{get when(){return I().statusReason},get children(){var e=be();return y(()=>K(e,`title`,I().statusReason)),e}}),l),l.$$click=ne,y(()=>q(n,`badge ${I().status}`)),e})(),(()=>{var e=Te();return e.addEventListener(`scroll`,()=>{let e=de();e&&j()&&M(0),se(e)}),Y(e,z(V,{get when(){return ce().length>0},get fallback(){return Ke()},get children(){return[z(B,{get each(){return ce()},children:(e,t)=>z(wt,{e,get prev(){return ce()[t()-1]}})}),z(V,{get when(){return N()},get children(){var e=we(),t=e.firstChild.nextSibling;return t.firstChild,Y(t,z(V,{get when(){return N().reasoning},get children(){var e=Se(),t=e.firstChild.nextSibling;return Y(t,()=>N().reasoning),e}}),null),Y(t,z(V,{get when(){return N().text},get fallback(){return qe()},get children(){var e=Ce(),t=e.firstChild;return Y(e,()=>N().text,t),e}}),null),e}})]}})),e})(),z(V,{get when(){return!oe()||j()>0},get children(){var e=Ee();return e.firstChild,e.$$click=()=>U(!0),Y(e,(()=>{var e=H(()=>j()>0);return()=>e()?`${j()} new message${j()>1?`s`:``}`:`jump to present`})(),null),e}}),(()=>{var e=De(),t=e.firstChild,n=t.firstChild,r=n.nextSibling.firstChild;return t.addEventListener(`submit`,ge),n.$$input=e=>d(e.currentTarget.value),r.addEventListener(`change`,e=>p(e.currentTarget.checked)),y(()=>K(n,`placeholder`,`message #${I().id}`)),y(()=>n.value=u()),y(()=>r.checked=f()),e})()]}})),Y(S,z(V,{get when(){return I()},get children(){return[Oe(),(()=>{var e=ke(),t=e.firstChild,n=t.firstChild.nextSibling,r=n.nextSibling,i=t.nextSibling,a=i.firstChild.nextSibling,o=i.nextSibling.firstChild.nextSibling,s=o.firstChild;return Y(n,()=>I().id),Y(r,()=>I().status),Y(a,()=>I().workspace),Y(o,()=>I().session,s),Y(o,()=>I().branch,null),y(e=>{var t=`badge ${I().status}`,n=I().workspace;return t!==e.e&&q(r,e.e=t),n!==e.t&&K(a,`title`,e.t=n),e},{e:void 0,t:void 0}),e})(),Ae(),(()=>{var e=je(),t=e.firstChild,r=t.nextSibling,i=r.firstChild,a=i.nextSibling,o=a.nextSibling,s=r.nextSibling;return s.firstChild,t.addEventListener(`change`,e=>{re(e.currentTarget.value),ae(e.currentTarget.value)}),Y(t,z(B,{get each(){return A()},children:e=>(()=>{var t=Je();return t.value=e,Y(t,e,null),Y(t,()=>e===m().defaultProvider?` ★`:``,null),t})()})),i.$$input=e=>ie(e.currentTarget.value),Y(a,z(B,{get each(){return O()},children:e=>(()=>{var t=Je();return t.value=e,t})()})),o.$$click=async()=>{n()&&(await $(`/api/agents/${n()}/model`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({provider:E(),model:D().trim()||void 0})}),L())},Y(s,()=>I().model,null),Y(s,z(V,{get when(){return O().length},get children(){return[` · `,H(()=>O().length),` models loaded`]}}),null),y(()=>K(i,`placeholder`,I().model)),y(()=>t.value=E()),y(()=>i.value=D()),e})(),Me(),(()=>{var n=Ne(),i=n.firstChild,a=i.nextSibling,o=a.nextSibling,s=o.nextSibling;return pe(i,`click`,Q(`/start`),!0),pe(a,`click`,Q(`/stop`),!0),o.$$click=()=>$(`/api/agents/${I().id}/fork`,{method:`POST`,headers:{"content-type":`application/json`},body:`{}`}).then(()=>W(I().id)),s.$$click=async()=>{confirm(`remove agent ${I().id}? (log is kept)`)&&(await $(`/api/agents/${I().id}`,{method:`DELETE`}),r(null),t(e().filter(e=>e.id!==I().id)))},n})(),(()=>{var e=Pe(),t=e.firstChild.nextSibling;return Y(t,()=>I().goal.status),y(()=>q(t,`badge ${I().goal.status===`done`?`done`:``}`)),e})(),(()=>{var e=Fe();return e.addEventListener(`submit`,_e),e})(),(()=>{var e=Ie();return Y(e,()=>I().goal.text||`no goal set`),e})(),Le(),z(V,{get when(){return I().latestProgress},get fallback(){return Ye()},get children(){var e=Re(),t=e.firstChild,n=t.nextSibling,r=n.nextSibling.nextSibling;return Y(e,()=>I().latestProgress.doing,t),Y(e,()=>I().latestProgress.recent??``,n),Y(r,()=>I().latestProgress.ts),e}}),ze(),(()=>{var e=Be(),t=e.firstChild.nextSibling,n=t.nextSibling.nextSibling,r=n.nextSibling.nextSibling,i=r.nextSibling.nextSibling;return i.nextSibling,Y(e,()=>I().stats.turns,t),Y(e,()=>I().stats.toolCalls,n),Y(e,()=>I().stats.compactions??0,r),Y(e,()=>I().stats.inputTokens,i),Y(e,()=>I().stats.outputTokens,null),e})(),Ve(),z(B,{get each(){return o()},children:e=>(()=>{var t=Xe(),n=t.firstChild;return Y(t,()=>e.branch,n),Y(n,()=>e.events),y(()=>q(t,`branch-row`+(e.branch===I().branch?` cur`:``))),t})()})]}})),y(e=>{var t=`layout`+(T()?``:` right-hidden`),n=`conn`+(G()?` ok`:``),r=G()?`live (websocket)`:`reconnecting…`,a=`rightbar`+(T()?` open`:``);return t!==e.e&&q(i,e.e=t),n!==e.t&&q(l,e.t=n),r!==e.a&&K(l,`title`,e.a=r),a!==e.o&&q(S,e.o=a),e},{e:void 0,t:void 0,a:void 0,o:void 0}),i})(),z(V,{get when(){return g()},get children(){return z(At,{get providers(){return Object.keys(m().providers??{})},onClose:()=>_(!1),onCreated:e=>{_(!1),L(),W(e)}})}}),z(V,{get when(){return S()},get children(){return z(jt,{get cfg(){return m()},onClose:()=>w(!1),onSaved:F})}})]}function wt(e){let t=e.e,n=yt(t),r=e.prev&&e.prev.type===t.type&&t.session===e.prev.session&&t.branch===e.prev.branch;return t.type===`state`?t.data.from===t.data.to?null:(()=>{var e=Ze(),n=e.firstChild;return Y(e,()=>t.data.from,n),Y(e,()=>t.data.to,null),Y(e,(()=>{var e=H(()=>!!t.data.reason);return()=>e()?` — ${t.data.reason}`:``})(),null),y(()=>q(e,`divider-msg`+(t.data.to===`error`?` err`:``))),e})():(()=>{var e=et(),i=e.firstChild;return q(e,`msg`+(r?` grouped`:``)),Y(e,z(V,{when:!r,get fallback(){return tt()},get children(){var e=Qe();return Y(e,()=>n.icon),y(t=>{var r=n.color+`33`,i=`1px solid ${n.color}66`;return r!==t.e&&J(e,`background`,t.e=r),i!==t.t&&J(e,`border`,t.t=i),t},{e:void 0,t:void 0}),e}}),i),Y(i,z(V,{when:!r,get children(){var e=$e(),r=e.firstChild,i=r.nextSibling,a=i.nextSibling;return Y(r,()=>n.name),Y(i,()=>St(t.ts)),Y(a,()=>t.branch),y(e=>J(r,`color`,n.color)),e}}),null),Y(i,z(Tt,{e:t}),null),e})()}function Tt(e){let t=e.e;switch(t.type){case`prompt`:return(()=>{var e=nt();return y(()=>e.innerHTML=_e(String(t.data.text??``))),e})();case`message`:return[z(V,{get when(){return H(()=>typeof t.data.reasoning==`string`)()&&t.data.reasoning.trim()},get children(){var e=Se(),n=e.firstChild.nextSibling;return Y(n,()=>String(t.data.reasoning)),e}}),(()=>{var e=nt();return y(()=>e.innerHTML=_e(String(t.data.content??``))),e})(),z(V,{get when(){return t.data.final},get children(){var e=rt(),n=e.firstChild;return Y(e,z(Ot,{get text(){return String(t.data.content??``)}}),n),e}})];case`tool_call`:{let e=JSON.stringify(t.data.args,null,1),n=Dt(JSON.stringify(t.data.args??{}),110);return(()=>{var r=it(),i=r.firstChild,a=i.firstChild;a.firstChild;var o=a.nextSibling.nextSibling,s=i.nextSibling;return Y(a,()=>String(t.data.name),null),Y(o,n),Y(s,e),r})()}case`tool_result`:{let e=String(t.data.result);return(()=>{var n=at(),r=n.firstChild,i=r.firstChild,a=r.nextSibling,o=a.nextSibling,s=o.firstChild;return Y(i,()=>Dt(e,120)),Y(r,z(Ot,{text:e}),null),Y(a,()=>Et(e,4e3)),Y(o,()=>t.data.durationMs,s),Y(o,()=>t.data.ok?``:` · FAILED`,null),y(()=>q(n,`embed`+(t.data.ok?``:` fail`))),n})()}case`progress`:return(()=>{var e=lt(),n=e.firstChild;return n.firstChild,Y(n,()=>String(t.data.doing??``),null),Y(e,z(V,{get when(){return t.data.recent},get children(){var e=ot();return Y(e,()=>String(t.data.recent)),e}}),null),Y(e,z(V,{get when(){return t.data.problems},get children(){var e=st();return e.firstChild,Y(e,()=>String(t.data.problems),null),e}}),null),Y(e,z(V,{get when(){return t.data.next},get children(){var e=ct();return e.firstChild,Y(e,()=>String(t.data.next),null),e}}),null),e})();case`error`:return(()=>{var e=ut(),n=e.firstChild;return n.firstChild,Y(n,()=>String(t.data.message??``),null),e})();default:return(()=>{var e=dt();return Y(e,()=>Et(JSON.stringify(t.data),200)),e})()}}function Et(e,t){return e.length>t?e.slice(0,t)+` …`:e}function Dt(e,t){return Et(e.replace(/\s+/g,` `).trim(),t)}function Ot(e){let[t,n]=v(!1);return(()=>{var r=ft();return r.$$click=t=>{t.stopPropagation(),navigator.clipboard.writeText(e.text).then(()=>{n(!0),setTimeout(()=>n(!1),900)})},Y(r,()=>t()?`✓`:`⧉`),r})()}function kt(e){return(()=>{var t=pt(),n=t.firstChild,r=n.firstChild.firstChild,i=r.nextSibling;return t.$$click=t=>t.target===t.currentTarget&&e.onClose(),Y(r,()=>e.title),pe(i,`click`,e.onClose,!0),Y(n,()=>e.children,null),t})()}function At(e){let[t,n]=v(`~`),[r,i]=v([]),[a,o]=v(``),[s,c]=v(e.providers[0]??``),[l,u]=v(``),[d,f]=v(``);async function p(e){let t=await $(`/api/fs${e?`?path=${encodeURIComponent(e)}`:``}`);n(t.path),i(t.entries)}ee(()=>p(t()));let m=async n=>{n.preventDefault(),f(``);try{let n=await $(`/api/agents`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({workspace:t(),id:a(),provider:s()||void 0,model:l()||void 0})});e.onCreated(n.agent.id)}catch(e){f(String(e.message))}};return z(kt,{title:`new agent`,get onClose(){return e.onClose},get children(){var i=ht(),f=i.firstChild,h=f.firstChild.nextSibling.firstChild,g=h.nextSibling,_=g.nextSibling,v=f.nextSibling,b=v.nextSibling,x=b.firstChild,S=x.firstChild.nextSibling,ee=x.nextSibling,C=ee.firstChild.nextSibling,w=ee.nextSibling.firstChild.nextSibling,T=b.nextSibling;return i.addEventListener(`submit`,m),h.$$input=e=>n(e.currentTarget.value),g.$$click=()=>p(t()),_.$$click=()=>p(`..`),Y(v,z(B,{get each(){return r()},children:e=>(()=>{var n=gt();return n.firstChild,n.$$click=()=>p(`${t()}/${e}`.replace(/\/+/g,`/`)),Y(n,e,null),n})()})),S.$$input=e=>o(e.currentTarget.value),C.addEventListener(`change`,e=>c(e.currentTarget.value)),Y(C,z(B,{get each(){return e.providers},children:e=>(()=>{var t=Je();return Y(t,e),t})()})),w.$$input=e=>u(e.currentTarget.value),Y(i,z(V,{get when(){return d()},get children(){var e=mt();return Y(e,d),e}}),T),y(()=>h.value=t()),y(()=>S.value=a()),y(()=>C.value=s()),y(()=>w.value=l()),i}})}function jt(e){let[t,n]=v(JSON.stringify(Object.fromEntries(Object.entries(e.cfg.providers??{}).map(([e,t])=>[e,{baseUrl:t.baseUrl,apiKey:t.apiKey??``,model:t.model??``}])),null,2)),[r,i]=v(e.cfg.defaultProvider??Object.keys(e.cfg.providers??{})[0]??``),[a,o]=v(Math.round((e.cfg.progressIntervalMs??6e5)/6e4)),[s,c]=v(JSON.stringify(e.cfg.tasks??[],null,2)),[l,u]=v(``),d=async n=>{n.preventDefault(),u(``);let i,o;try{i=JSON.parse(t())}catch{return u(`providers: invalid JSON`)}try{o=JSON.parse(s())}catch{return u(`tasks: invalid JSON`)}try{await $(`/api/config`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({providers:i,defaultProvider:r(),progressIntervalMs:Math.max(1,a())*6e4,tasks:o})}),e.onSaved(),e.onClose()}catch(e){u(String(e.message))}};return z(kt,{title:`settings`,get onClose(){return e.onClose},get children(){var u=_t(),f=u.firstChild,p=f.firstChild.nextSibling,m=p.nextSibling.nextSibling,h=f.nextSibling,g=h.firstChild,_=g.firstChild.nextSibling,v=g.nextSibling.firstChild.nextSibling,b=h.nextSibling,x=b.firstChild.nextSibling,S=b.nextSibling;return u.addEventListener(`submit`,d),Y(f,()=>e.cfg.configPath,p),m.$$input=e=>n(e.currentTarget.value),_.$$input=e=>i(e.currentTarget.value),v.$$input=e=>o(Number(e.currentTarget.value)),x.$$input=e=>c(e.currentTarget.value),Y(u,z(V,{get when(){return l()},get children(){var e=mt();return Y(e,l),e}}),S),y(()=>m.value=t()),y(()=>_.value=r()),y(()=>v.value=a()),y(()=>x.value=s()),u}})}fe([`click`,`input`]),W(()=>z(Ct,{}),document.getElementById(`root`));
package/public/index.html CHANGED
@@ -4,8 +4,8 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>teapot</title>
7
- <script type="module" crossorigin src="/assets/index-BnXTX56y.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-DMV4C8AE.css">
7
+ <script type="module" crossorigin src="/assets/index-CN4J99YT.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-CHlf4zTW.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -1,9 +0,0 @@
1
- (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e={context:void 0,registry:void 0,effects:void 0,done:!1,getContextId(){return t(this.context.count)},getNextContextId(){return t(this.context.count++)}};function t(t){let n=String(t),r=n.length-1;return e.context.id+(r?String.fromCharCode(96+r):``)+n}function n(t){e.context=t}var r=(e,t)=>e===t,i=Symbol(`solid-track`),a={equals:r},o=null,s=F,c=1,l=2,u={owned:null,cleanups:null,context:null,owner:null},d=null,f=null,p=null,m=null,h=null,g=0;function _(e,t){let n=p,r=d,i=e.length===0,a=t===void 0?r:t,o=i?u:{owned:null,cleanups:null,context:a?a.context:null,owner:a},s=i?e:()=>e(()=>S(()=>R(o)));d=o,p=null;try{return N(s,!0)}finally{p=n,d=r}}function v(e,t){t=t?Object.assign({},a,t):a;let n={value:e,observers:null,observerSlots:null,comparator:t.equals||void 0};return[D.bind(n),e=>(typeof e==`function`&&(e=f&&f.running&&f.sources.has(n)?e(n.tValue):e(n.value)),O(n,e))]}function y(e,t,n){k(j(e,t,!1,c))}function b(e,t,n){s=ne;let r=j(e,t,!1,c),i=E&&te(E);i&&(r.suspense=i),(!n||!n.render)&&(r.user=!0),h?h.push(r):k(r)}function x(e,t,n){n=n?Object.assign({},a,n):a;let r=j(e,t,!0,0);return r.observers=null,r.observerSlots=null,r.comparator=n.equals||void 0,k(r),D.bind(r)}function S(e){if(p===null)return e();let t=p;p=null;try{return e()}finally{p=t}}function C(e){b(()=>S(e))}function w(e){return d===null||(d.cleanups===null?d.cleanups=[e]:d.cleanups.push(e)),e}var[ee,T]=v(!1);function te(e){let t;return d&&d.context&&(t=d.context[e.id])!==void 0?t:e.defaultValue}var E;function D(){let e=f&&f.running;if(this.sources&&(e?this.tState:this.state)){if((e?this.tState:this.state)===c)k(this);else{let e=m;m=null,N(()=>I(this),!1),m=e}}if(p){let e=this.observers;if(!e||e[e.length-1]!==p){let t=e?e.length:0;p.sources?(p.sources.push(this),p.sourceSlots.push(t)):(p.sources=[this],p.sourceSlots=[t]),e?(e.push(p),this.observerSlots.push(p.sources.length-1)):(this.observers=[p],this.observerSlots=[p.sources.length-1])}}return e&&f.sources.has(this)?this.tValue:this.value}function O(e,t,n){let r=f&&f.running&&f.sources.has(e)?e.tValue:e.value;if(!e.comparator||!e.comparator(r,t)){if(f){let r=f.running;(r||!n&&f.sources.has(e))&&(f.sources.add(e),e.tValue=t),r||(e.value=t)}else e.value=t;e.observers&&e.observers.length&&N(()=>{for(let t=0;t<e.observers.length;t+=1){let n=e.observers[t],r=f&&f.running;r&&f.disposed.has(n)||((r?!n.tState:!n.state)&&(n.pure?m.push(n):h.push(n),n.observers&&L(n)),r?n.tState=c:n.state=c)}if(m.length>1e6)throw m=[],Error()},!1)}return t}function k(e){if(!e.fn)return;R(e);let t=g;A(e,f&&f.running&&f.sources.has(e)?e.tValue:e.value,t),f&&!f.running&&f.sources.has(e)&&queueMicrotask(()=>{N(()=>{f&&(f.running=!0),p=d=e,A(e,e.tValue,t),p=d=null},!1)})}function A(e,t,n){let r,i=d,a=p;p=d=e;try{r=e.fn(t)}catch(t){return e.pure&&(f&&f.running?(e.tState=c,e.tOwned&&e.tOwned.forEach(R),e.tOwned=void 0):(e.state=c,e.owned&&e.owned.forEach(R),e.owned=null)),e.updatedAt=n+1,H(t)}finally{p=a,d=i}(!e.updatedAt||e.updatedAt<=n)&&(e.updatedAt!=null&&`observers`in e?O(e,r,!0):f&&f.running&&e.pure?(f.sources.has(e)||(e.value=r),f.sources.add(e),e.tValue=r):e.value=r,e.updatedAt=n)}function j(e,t,n,r=c,i){let a={fn:e,state:r,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:d,context:d?d.context:null,pure:n};return f&&f.running&&(a.state=0,a.tState=r),d===null||d!==u&&(f&&f.running&&d.pure?d.tOwned?d.tOwned.push(a):d.tOwned=[a]:d.owned?d.owned.push(a):d.owned=[a]),a}function M(e){let t=f&&f.running;if((t?e.tState:e.state)===0)return;if((t?e.tState:e.state)===l)return I(e);if(e.suspense&&S(e.suspense.inFallback))return e.suspense.effects.push(e);let n=[e];for(;(e=e.owner)&&(!e.updatedAt||e.updatedAt<g);){if(t&&f.disposed.has(e))return;(t?e.tState:e.state)&&n.push(e)}for(let r=n.length-1;r>=0;r--){if(e=n[r],t){let t=e,i=n[r+1];for(;(t=t.owner)&&t!==i;)if(f.disposed.has(t))return}if((t?e.tState:e.state)===c)k(e);else if((t?e.tState:e.state)===l){let t=m;m=null,N(()=>I(e,n[0]),!1),m=t}}}function N(e,t){if(m)return e();let n=!1;t||(m=[]),h?n=!0:h=[],g++;try{let t=e();return P(n),t}catch(e){n||(h=null),m=null,H(e)}}function P(e){if(m&&=(F(m),null),e)return;let t;if(f){if(!f.promises.size&&!f.queue.size){let e=f.sources,n=f.disposed;h.push.apply(h,f.effects),t=f.resolve;for(let e of h)`tState`in e&&(e.state=e.tState),delete e.tState;f=null,N(()=>{for(let e of n)R(e);for(let t of e){if(t.value=t.tValue,t.owned)for(let e=0,n=t.owned.length;e<n;e++)R(t.owned[e]);t.tOwned&&(t.owned=t.tOwned),delete t.tValue,delete t.tOwned,t.tState=0}T(!1)},!1)}else if(f.running){f.running=!1,f.effects.push.apply(f.effects,h),h=null,T(!0);return}}let n=h;h=null,n.length&&N(()=>s(n),!1),t&&t()}function F(e){for(let t=0;t<e.length;t++)M(e[t])}function ne(t){let r,i=0;for(r=0;r<t.length;r++){let e=t[r];e.user?t[i++]=e:M(e)}if(e.context){if(e.count){e.effects||=[],e.effects.push(...t.slice(0,i));return}n()}for(e.effects&&(e.done||!e.count)&&(t=[...e.effects,...t],i+=e.effects.length,delete e.effects),r=0;r<i;r++)M(t[r])}function I(e,t){let n=f&&f.running;n?e.tState=0:e.state=0;for(let r=0;r<e.sources.length;r+=1){let i=e.sources[r];if(i.sources){let e=n?i.tState:i.state;e===c?i!==t&&(!i.updatedAt||i.updatedAt<g)&&M(i):e===l&&I(i,t)}}}function L(e){let t=f&&f.running;for(let n=0;n<e.observers.length;n+=1){let r=e.observers[n];(t?!r.tState:!r.state)&&(t?r.tState=l:r.state=l,r.pure?m.push(r):h.push(r),r.observers&&L(r))}}function R(e){let t;if(e.sources)for(;e.sources.length;){let t=e.sources.pop(),n=e.sourceSlots.pop(),r=t.observers;if(r&&r.length){let e=r.pop(),i=t.observerSlots.pop();n<r.length&&(e.sourceSlots[i]=n,r[n]=e,t.observerSlots[n]=i)}}if(e.tOwned){for(t=e.tOwned.length-1;t>=0;t--)R(e.tOwned[t]);delete e.tOwned}if(f&&f.running&&e.pure)z(e,!0);else if(e.owned){for(t=e.owned.length-1;t>=0;t--)R(e.owned[t]);e.owned=null}if(e.cleanups){for(t=e.cleanups.length-1;t>=0;t--)e.cleanups[t]();e.cleanups=null}f&&f.running?e.tState=0:e.state=0}function z(e,t){if(t||(e.tState=0,f.disposed.add(e)),e.owned)for(let t=0;t<e.owned.length;t++)z(e.owned[t])}function B(e){return e instanceof Error?e:Error(typeof e==`string`?e:`Unknown error`,{cause:e})}function V(e,t,n){try{for(let n of t)n(e)}catch(e){H(e,n&&n.owner||null)}}function H(e,t=d){let n=o&&t&&t.context&&t.context[o],r=B(e);if(!n)throw r;h?h.push({fn(){V(r,n,t)},state:c}):V(r,n,t)}var re=Symbol(`fallback`);function ie(e){for(let t=0;t<e.length;t++)e[t]()}function ae(e,t,n={}){let r=[],a=[],o=[],s=0,c=t.length>1?[]:null;return w(()=>ie(o)),()=>{let l=e()||[],u=l.length,d,f;return l[i],S(()=>{let e,t,i,m,h,g,v,y,b;if(u===0)s!==0&&(ie(o),o=[],r=[],a=[],s=0,c&&=[]),n.fallback&&(r=[re],a[0]=_(e=>(o[0]=e,n.fallback())),s=1);else if(s===0){for(a=Array(u),f=0;f<u;f++)r[f]=l[f],a[f]=_(p);s=u}else{for(i=Array(u),m=Array(u),c&&(h=Array(u)),g=0,v=Math.min(s,u);g<v&&r[g]===l[g];g++);for(v=s-1,y=u-1;v>=g&&y>=g&&r[v]===l[y];v--,y--)i[y]=a[v],m[y]=o[v],c&&(h[y]=c[v]);for(e=new Map,t=Array(y+1),f=y;f>=g;f--)b=l[f],d=e.get(b),t[f]=d===void 0?-1:d,e.set(b,f);for(d=g;d<=v;d++)b=r[d],f=e.get(b),f!==void 0&&f!==-1?(i[f]=a[d],m[f]=o[d],c&&(h[f]=c[d]),f=t[f],e.set(b,f)):o[d]();for(f=g;f<u;f++)f in i?(a[f]=i[f],o[f]=m[f],c&&(c[f]=h[f],c[f](f))):a[f]=_(p);a=a.slice(0,s=u),r=l.slice(0)}return a});function p(e){if(o[f]=e,c){let[e,n]=v(f);return c[f]=n,t(l[f],e)}return t(l[f])}}}function U(e,t){return S(()=>e(t||{}))}var oe=e=>`Stale read from <${e}>.`;function W(e){let t=`fallback`in e&&{fallback:()=>e.fallback};return x(ae(()=>e.each,e.children,t||void 0))}function G(e){let t=e.keyed,n=x(()=>e.when,void 0,void 0),r=t?n:x(n,void 0,{equals:(e,t)=>!e==!t});return x(()=>{let i=r();if(i){let a=e.children;return typeof a==`function`&&a.length>0?S(()=>a(t?i:()=>{if(!S(r))throw oe(`Show`);return n()})):a}return e.fallback},void 0,void 0)}var K=e=>x(()=>e());function se(e,t,n){let r=n.length,i=t.length,a=r,o=0,s=0,c=t[i-1].nextSibling,l=null;for(;o<i||s<a;){if(t[o]===n[s]){o++,s++;continue}for(;t[i-1]===n[a-1];)i--,a--;if(i===o){let t=a<r?s?n[s-1].nextSibling:n[a-s]:c;for(;s<a;)e.insertBefore(n[s++],t)}else if(a===s)for(;o<i;)(!l||!l.has(t[o]))&&t[o].remove(),o++;else if(t[o]===n[a-1]&&n[s]===t[i-1]){let r=t[--i].nextSibling;e.insertBefore(n[s++],t[o++].nextSibling),e.insertBefore(n[--a],r),t[i]=n[a]}else{if(!l){l=new Map;let e=s;for(;e<a;)l.set(n[e],e++)}let r=l.get(t[o]);if(r!=null){if(s<r&&r<a){let c=o,u=1,d;for(;++c<i&&c<a&&(d=l.get(t[c]))!=null&&d===r+u;)u++;if(u>r-s){let i=t[o];for(;s<r;)e.insertBefore(n[s++],i)}else e.replaceChild(n[s++],t[o++])}else o++}else t[o++].remove()}}}var ce=`_$DX_DELEGATE`;function le(e,t,n,r={}){let i;return _(r=>{i=r,t===document?e():X(t,e(),t.firstChild?null:void 0,n)},r.owner),()=>{i(),t.textContent=``}}function q(e,t,n,r){let i,a=()=>{let t=r?document.createElementNS(`http://www.w3.org/1998/Math/MathML`,`template`):document.createElement(`template`);return t.innerHTML=e,n?t.content.firstChild.firstChild:r?t.firstChild:t.content.firstChild},o=t?()=>S(()=>document.importNode(i||=a(),!0)):()=>(i||=a()).cloneNode(!0);return o.cloneNode=o,o}function ue(e,t=window.document){let n=t[ce]||(t[ce]=new Set);for(let r=0,i=e.length;r<i;r++){let i=e[r];n.has(i)||(n.add(i),t.addEventListener(i,me))}}function de(e,t,n){pe(e)||(n==null?e.removeAttribute(t):e.setAttribute(t,n))}function J(e,t){pe(e)||(t==null?e.removeAttribute(`class`):e.className=t)}function Y(e,t,n,r){if(r)Array.isArray(n)?(e[`$$${t}`]=n[0],e[`$$${t}Data`]=n[1]):e[`$$${t}`]=n;else if(Array.isArray(n)){let r=n[0];e.addEventListener(t,n[0]=t=>r.call(e,n[1],t))}else e.addEventListener(t,n,typeof n!=`function`&&n)}function fe(e,t,n){n==null?e.style.removeProperty(t):e.style.setProperty(t,n)}function X(e,t,n,r){if(n!==void 0&&!r&&(r=[]),typeof t!=`function`)return Z(e,t,r,n);y(r=>Z(e,t(),r,n),r)}function pe(t){return!!e.context&&!e.done&&(!t||t.isConnected)}function me(t){if(e.registry&&e.events&&e.events.find(([e,n])=>n===t))return;let n=t.target,r=`$$${t.type}`,i=t.target,a=t.currentTarget,o=e=>Object.defineProperty(t,"target",{configurable:!0,value:e}),s=()=>{let e=n[r];if(e&&!n.disabled){let i=n[`${r}Data`];if(i===void 0?e.call(n,t):e.call(n,i,t),t.cancelBubble)return}return n.host&&typeof n.host!=`string`&&!n.host._$host&&n.contains(t.target)&&o(n.host),!0},c=()=>{for(;s()&&(n=n._$host||n.parentNode||n.host););};if(Object.defineProperty(t,"currentTarget",{configurable:!0,get(){return n||document}}),e.registry&&!e.done&&(e.done=_$HY.done=!0),t.composedPath){let e=t.composedPath();o(e[0]);for(let t=0;t<e.length-2&&(n=e[t],s());t++){if(n._$host){n=n._$host,c();break}if(n.parentNode===a)break}}else c();o(i)}function Z(e,t,n,r,i){let a=pe(e);if(a){!n&&(n=[...e.childNodes]);let t=[];for(let e=0;e<n.length;e++){let r=n[e];r.nodeType===8&&r.data.slice(0,2)===`!$`?r.remove():t.push(r)}n=t}for(;typeof n==`function`;)n=n();if(t===n)return n;let o=typeof t,s=r!==void 0;if(e=s&&n[0]&&n[0].parentNode||e,o===`string`||o===`number`){if(a||o===`number`&&(t=t.toString(),t===n))return n;if(s){let i=n[0];i&&i.nodeType===3?i.data!==t&&(i.data=t):i=document.createTextNode(t),n=Q(e,n,r,i)}else n=n!==``&&typeof n==`string`?e.firstChild.data=t:e.textContent=t}else if(t==null||o===`boolean`){if(a)return n;n=Q(e,n,r)}else if(o===`function`)return y(()=>{let i=t();for(;typeof i==`function`;)i=i();n=Z(e,i,n,r)}),()=>n;else if(Array.isArray(t)){let o=[],c=n&&Array.isArray(n);if(he(o,t,n,i))return y(()=>n=Z(e,o,n,r,!0)),()=>n;if(a){if(!o.length)return n;if(r===void 0)return n=[...e.childNodes];let t=o[0];if(t.parentNode!==e)return n;let i=[t];for(;(t=t.nextSibling)!==r;)i.push(t);return n=i}if(o.length===0){if(n=Q(e,n,r),s)return n}else c?n.length===0?ge(e,o,r):se(e,n,o):(n&&Q(e),ge(e,o));n=o}else if(t.nodeType){if(a&&t.parentNode)return n=s?[t]:t;if(Array.isArray(n)){if(s)return n=Q(e,n,r,t);Q(e,n,null,t)}else n==null||n===``||!e.firstChild?e.appendChild(t):e.replaceChild(t,e.firstChild);n=t}return n}function he(e,t,n,r){let i=!1;for(let a=0,o=t.length;a<o;a++){let o=t[a],s=n&&n[e.length],c;if(o!=null&&o!==!0&&o!==!1){if((c=typeof o)==`object`&&o.nodeType)e.push(o);else if(Array.isArray(o))i=he(e,o,s)||i;else if(c===`function`){if(r){for(;typeof o==`function`;)o=o();i=he(e,Array.isArray(o)?o:[o],Array.isArray(s)?s:[s])||i}else e.push(o),i=!0}else{let t=String(o);s&&s.nodeType===3&&s.data===t?e.push(s):e.push(document.createTextNode(t))}}}return i}function ge(e,t,n=null){for(let r=0,i=t.length;r<i;r++)e.insertBefore(t[r],n)}function Q(e,t,n,r){if(n===void 0)return e.textContent=``;let i=r||document.createTextNode(``);if(t.length){let r=!1;for(let a=t.length-1;a>=0;a--){let o=t[a];if(i!==o){let t=o.parentNode===e;!r&&!a?t?e.replaceChild(i,o):e.insertBefore(i,n):t&&o.remove()}else r=!0}}else e.insertBefore(i,n);return[i]}function _e(e){let t=ve(e.replace(/\r\n/g,`
2
- `)).split(`
3
- `),n=[],r=0;for(;r<t.length;){let e=t[r];if(/^```\w*\s*$/.test(e)){let e=[];for(r++;r<t.length&&!/^```\s*$/.test(t[r]);)e.push(t[r++]);r++,n.push(`<pre><code>${e.join(`
4
- `)}</code></pre>`);continue}let a=e.match(/^(#{1,4})\s+(.*)$/);if(a){n.push(`<h${a[1].length}>${i(a[2])}</h${a[1].length}>`),r++;continue}let o=/^\s*\d+[.)]\s+/.test(e);if(o||/^\s*[-*]\s+/.test(e)){let e=[];for(;r<t.length;){let n=t[r].match(/^\s*[-*]\s+(.*)$/)??(o?t[r].match(/^\s*\d+[.)]\s+(.*)$/):null);if(!n)break;e.push(`<li>${i(n[1])}</li>`),r++}n.push(o?`<ol>${e.join(``)}</ol>`:`<ul>${e.join(``)}</ul>`);continue}if(/^\s*$/.test(e)){r++;continue}let s=[];for(;r<t.length&&!/^\s*$/.test(t[r])&&!/^#{1,4}\s/.test(t[r])&&!/^```/.test(t[r])&&!/^\s*([-*]|\d+[.)])\s/.test(t[r]);)s.push(t[r++]);n.push(`<p>${s.map(i).join(`<br>`)}</p>`)}return n.join(`
5
- `);function i(e){return e.replace(/`([^`]+)`/g,`<code>$1</code>`).replace(/\*\*([^*]+)\*\*/g,`<strong>$1</strong>`).replace(/(^|\W)\*([^*]+)\*(?=\W|$)/g,`$1<em>$2</em>`).replace(/\[([^\]]+)\]\((https?:\/\/[^)\s]+)\)/g,`<a href="$2" rel="noopener noreferrer" target="_blank">$1</a>`)}}function ve(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}var ye=q(`<br>`),be=q(`<span class=sub>ℹ`),xe=q(`<header class=chan-head><span class=hash>#</span><span class=title></span><span></span><span class=sub> · <!>/<!> · turns <!> · tools </span><span style=margin-left:auto;display:flex;gap:4px><button class=iconbtn title="toggle details panel">▤`),Se=q(`<details class=reasoning><summary>💭 reasoning</summary><div class=mono>`),Ce=q(`<div class=content><span class=cursor>▍`),we=q(`<div class="msg live"><div class=avatar style="background:#5865f233;border:1px solid #5865f266">🫖</div><div class=msg-body><div class=msg-head><span class=author style=color:var(--acc)>agent</span><span class=ts>streaming…`),Te=q(`<div class=feed>`),Ee=q(`<button class=jump>↓ `),De=q(`<div class=composer><form><input type=text><label><input type=checkbox>auto-start</label><button type=submit>send</button></form><div class=hint>enter to send · prompts are appended to the conversation and the agent keeps working toward its goal`),Oe=q(`<h3>controls`),ke=q(`<div class=btnrow><button>▶ start</button><button>■ stop</button><button>⑂ fork</button><button title="remove agent">🗑`),Ae=q(`<h3>goal <span>`),je=q(`<form style=display:flex;gap:4px;margin-bottom:6px><input id=goal-input type=text placeholder="set new goal…"style="flex:1;background:var(--bg-darkest);border:none;border-radius:6px;padding:6px 8px;color:var(--fg);font:inherit"><button type=submit style="background:var(--acc);border:none;border-radius:6px;color:#fff;padding:0 10px;cursor:pointer">✓`),Me=q(`<div class=card>`),Ne=q(`<h3>latest progress`),Pe=q(`<div class=card>
6
- <!>
7
- <span class=muted>`),Fe=q(`<h3>branches`),Ie=q(`<h3>runtime`),Le=q(`<div class="card muted">turns <!> · tools <!>
8
- tokens in/out <!>/<!>
9
- `),Re=q(`<div class=layout><nav class=sidebar><h1>🫖 teapot<span style=float:right;display:flex;gap:4px><button class=iconbtn title="new agent">+</button><button class=iconbtn title=settings>⚙</button></span></h1><div class=agent-list></div><div class=metrics></div></nav><section class=channel></section><aside>`),ze=q(`<span title="goal done">✓`),Be=q(`<div><span></span><span>`),Ve=q(`<div class=muted style=display:grid;place-items:center;height:100%>select an agent`),He=q(`<div class=muted style=display:grid;place-items:center;height:100%>no events yet — say something or press ▶ start`),Ue=q(`<div class="content muted">thinking…`),We=q(`<div class=muted>none yet`),Ge=q(`<div><span>`),Ke=q(`<div> → `),qe=q(`<div class=avatar>`),Je=q(`<div class=msg-head><span class=author></span><span class=ts></span><span class=ts>`),Ye=q(`<div><div class=msg-body>`),Xe=q(`<span style=width:38px>`),Ze=q(`<div class=content>`),Qe=q(`<details class=embed><summary><b>⚙ </b> <span class=meta></span></summary><div class=mono>`),$e=q(`<details><summary><span class=meta></span></summary><div class=mono></div><div class=meta>ms`),et=q(`<div class=meta>`),tt=q(`<div class=meta>⚠ `),nt=q(`<div class=meta>→ `),rt=q(`<div class=embed style=border-color:var(--ok)><div>📈 `),it=q(`<div class="embed fail"><div class=mono>⚠ `),at=q(`<div class="content muted">`),ot=q(`<div class=overlay><div class=modal><div class=modal-head><b></b><button class=iconbtn>✕`),st=q(`<span style=color:var(--err);font-size:13px>`),ct=q(`<form style=display:flex;flex-direction:column;gap:10px><label>workspace directory<div style=display:flex;gap:6px><input type=text class="w100 mono"><button type=button>go</button><button type=button>↑</button></div></label><div class=dirlist></div><div style=display:flex;gap:10px><label style=flex:1>agent name <input type=text placeholder="(directory name)"></label><label>provider<select></select></label><label style=flex:1>model <input type=text placeholder="(provider default)"></label></div><button type=submit style=align-self:flex-end>create & start`),lt=q(`<div class=direntry>📁 `),ut=q(`<option>`),dt=q(`<form style=display:flex;flex-direction:column;gap:10px><label>providers (<!>)<textarea rows=8 class="mono w100"></textarea></label><div style=display:flex;gap:10px><label style=flex:1>default provider <input type=text></label><label>progress interval (min) <input type=number min=1 style=width:90px></label></div><label>scheduled tasks (JSON array)<textarea rows=7 class="mono w100"></textarea></label><button type=submit style=align-self:flex-end>save`),ft={user:{name:`you`,icon:`🧑`,color:`#faa81a`},message:{name:`agent`,icon:`🫖`,color:`#5865f2`},tool_call:{name:`tool`,icon:`🔧`,color:`#3ba0c9`},progress:{name:`progress`,icon:`📈`,color:`#3ba55d`}},pt=e=>ft[e.type]??{name:e.type,icon:`•`,color:`#9298a5`},mt=new Set([`user`,`message`,`prompt`,`tool_call`,`tool_result`,`progress`]),ht=e=>mt.has(e.type),gt=e=>{let t=new Date(e);return`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`};async function $(e,t){let n=await fetch(e,t);if(!n.ok)throw Error(`${e}: ${n.status}`);return n.json()}function _t(){let[e,t]=v([]),[n,r]=v(null),[i,a]=v([]),[o,s]=v([]),[c,l]=v(null),[u,d]=v(``),[f,p]=v(!0),[m,h]=v({providers:{}}),[g,_]=v(!1),[b,S]=v(!1),[w,ee]=v(!1),[T,te]=v(!0),[E,D]=v(0),[O,k]=v(null),A=x(()=>i().filter(ht)),j=()=>$(`/api/config`).then(h).catch(()=>{}),M=x(()=>e().find(e=>e.id===n())),N=()=>$(`/api/agents`).then(e=>t(e.agents)).catch(()=>{}),P=()=>$(`/api/metrics`).then(l).catch(()=>{});async function F(e){try{let[t,n]=await Promise.all([$(`/api/agents/${e}/events?limit=300`),$(`/api/agents/${e}/branches`)]);a(t.events),s(n.branches)}catch{}}function ne(){return document.querySelector(`.feed`)}function I(){let e=ne();return!e||e.scrollHeight-e.scrollTop-e.clientHeight<80}function L(e=!1){let t=ne();t&&(e||T())&&(t.scrollTop=t.scrollHeight,D(0))}async function R(e){r(e),k(null),await F(e),requestAnimationFrame(()=>L(!0))}C(()=>{j(),N().then(()=>e()[0]&&R(e()[0].id)),P();let t=null;new EventSource(`/api/events`).onmessage=e=>{let r=JSON.parse(e.data);if(r.kind===`llm-delta`){r.agentId===n()&&k({text:r.text??``,reasoning:r.reasoning??``});return}t||=setTimeout(async()=>{if(t=null,await N(),await P(),n()){let e=i().length;await F(n()),i().length!==e&&(k(null),I()?L(!0):D(E()+(i().length-e)))}},400)},setInterval(P,3e4)});let z=async e=>{if(e.preventDefault(),!n()||!u().trim())return;let t=u();d(``),await $(`/api/agents/${n()}/prompt`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({text:t,start:f()})})},B=e=>()=>n()&&$(`/api/agents/${n()}${e}`,{method:`POST`}).then(N),V=async e=>{e.preventDefault();let t=document.getElementById(`goal-input`);!n()||!t.value.trim()||(await $(`/api/agents/${n()}/goal`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({text:t.value})}),t.value=``,N())};return[(()=>{var i=Re(),a=i.firstChild,s=a.firstChild,l=s.firstChild.nextSibling.firstChild,m=l.nextSibling,h=s.nextSibling,g=h.nextSibling,v=a.nextSibling,b=v.nextSibling;return l.$$click=()=>{j(),_(!0)},m.$$click=()=>{j(),S(!0)},X(h,U(W,{get each(){return e()},children:e=>(()=>{var t=Be(),r=t.firstChild,i=r.nextSibling;return t.$$click=()=>R(e.id),X(i,()=>e.id),X(t,U(G,{get when(){return e.goal.status===`done`},get children(){return ze()}}),null),y(i=>{var a=`agent-item`+(e.id===n()?` sel`:``),o=`dot ${e.status}`;return a!==i.e&&J(t,i.e=a),o!==i.t&&J(r,i.t=o),i},{e:void 0,t:void 0}),t})()})),X(g,U(G,{get when(){return c()},get children(){return[`master rss `,K(()=>c().rssMb),`MB · heap `,K(()=>c().heapUsedMb),`MB`,ye(),`load1 `,K(()=>c().loadavg1),` · up `,K(()=>Math.floor(c().uptimeSec/60)),`m`]}})),X(v,U(G,{get when(){return M()},get fallback(){return Ve()},get children(){return[(()=>{var e=xe(),t=e.firstChild.nextSibling,n=t.nextSibling,r=n.nextSibling,i=r.firstChild,a=i.nextSibling,o=a.nextSibling.nextSibling,s=o.nextSibling.nextSibling;s.nextSibling;var c=r.nextSibling,l=c.firstChild;return X(t,()=>M().id),X(n,()=>M().status),X(r,()=>M().model,i),X(r,()=>M().session,a),X(r,()=>M().branch,o),X(r,()=>M().stats.turns,s),X(r,()=>M().stats.toolCalls,null),X(c,U(G,{get when(){return M().statusReason},get children(){var e=be();return y(()=>de(e,`title`,M().statusReason)),e}}),l),l.$$click=()=>ee(!w()),y(()=>J(n,`badge ${M().status}`)),e})(),(()=>{var e=Te();return e.addEventListener(`scroll`,()=>{let e=I();e&&E()&&D(0),te(e)}),X(e,U(G,{get when(){return A().length>0},get fallback(){return He()},get children(){return[U(W,{get each(){return A()},children:(e,t)=>U(vt,{e,get prev(){return A()[t()-1]}})}),U(G,{get when(){return O()},get children(){var e=we(),t=e.firstChild.nextSibling;return t.firstChild,X(t,U(G,{get when(){return O().reasoning},get children(){var e=Se(),t=e.firstChild.nextSibling;return X(t,()=>O().reasoning),e}}),null),X(t,U(G,{get when(){return O().text},get fallback(){return Ue()},get children(){var e=Ce(),t=e.firstChild;return X(e,()=>O().text,t),e}}),null),e}})]}})),e})(),U(G,{get when(){return!T()||E()>0},get children(){var e=Ee();return e.firstChild,e.$$click=()=>L(!0),X(e,(()=>{var e=K(()=>E()>0);return()=>e()?`${E()} new message${E()>1?`s`:``}`:`jump to present`})(),null),e}}),(()=>{var e=De(),t=e.firstChild,n=t.firstChild,r=n.nextSibling.firstChild;return t.addEventListener(`submit`,z),n.$$input=e=>d(e.currentTarget.value),r.addEventListener(`change`,e=>p(e.currentTarget.checked)),y(()=>de(n,`placeholder`,`message #${M().id}`)),y(()=>n.value=u()),y(()=>r.checked=f()),e})()]}})),X(b,U(G,{get when(){return M()},get children(){return[Oe(),(()=>{var n=ke(),i=n.firstChild,a=i.nextSibling,o=a.nextSibling,s=o.nextSibling;return Y(i,`click`,B(`/start`),!0),Y(a,`click`,B(`/stop`),!0),o.$$click=()=>$(`/api/agents/${M().id}/fork`,{method:`POST`,headers:{"content-type":`application/json`},body:`{}`}).then(()=>R(M().id)),s.$$click=async()=>{confirm(`remove agent ${M().id}? (log is kept)`)&&(await $(`/api/agents/${M().id}`,{method:`DELETE`}),r(null),t(e().filter(e=>e.id!==M().id)))},n})(),(()=>{var e=Ae(),t=e.firstChild.nextSibling;return X(t,()=>M().goal.status),y(()=>J(t,`badge ${M().goal.status===`done`?`done`:``}`)),e})(),(()=>{var e=je();return e.addEventListener(`submit`,V),e})(),(()=>{var e=Me();return X(e,()=>M().goal.text||`no goal set`),e})(),Ne(),U(G,{get when(){return M().latestProgress},get fallback(){return We()},get children(){var e=Pe(),t=e.firstChild,n=t.nextSibling,r=n.nextSibling.nextSibling;return X(e,()=>M().latestProgress.doing,t),X(e,()=>M().latestProgress.recent??``,n),X(r,()=>M().latestProgress.ts),e}}),Fe(),U(W,{get each(){return o()},children:e=>(()=>{var t=Ge(),n=t.firstChild;return X(t,()=>e.branch,n),X(n,()=>e.events),y(()=>J(t,`branch-row`+(e.branch===M().branch?` cur`:``))),t})()}),Ie(),(()=>{var e=Le(),t=e.firstChild.nextSibling,n=t.nextSibling.nextSibling,r=n.nextSibling.nextSibling,i=r.nextSibling.nextSibling;return i.nextSibling,X(e,()=>M().stats.turns,t),X(e,()=>M().stats.toolCalls,n),X(e,()=>M().stats.inputTokens,r),X(e,()=>M().stats.outputTokens,i),X(e,()=>M().workspace,null),e})()]}})),y(()=>J(b,`rightbar`+(w()?` open`:``))),i})(),U(G,{get when(){return g()},get children(){return U(Ct,{get providers(){return Object.keys(m().providers??{})},onClose:()=>_(!1),onCreated:e=>{_(!1),N(),R(e)}})}}),U(G,{get when(){return b()},get children(){return U(wt,{get cfg(){return m()},onClose:()=>S(!1),onSaved:j})}})]}function vt(e){let t=e.e,n=pt(t),r=e.prev&&e.prev.type===t.type&&t.session===e.prev.session&&t.branch===e.prev.branch;return t.type===`state`?t.data.from===t.data.to?null:(()=>{var e=Ke(),n=e.firstChild;return X(e,()=>t.data.from,n),X(e,()=>t.data.to,null),X(e,(()=>{var e=K(()=>!!t.data.reason);return()=>e()?` — ${t.data.reason}`:``})(),null),y(()=>J(e,`divider-msg`+(t.data.to===`error`?` err`:``))),e})():(()=>{var e=Ye(),i=e.firstChild;return J(e,`msg`+(r?` grouped`:``)),X(e,U(G,{when:!r,get fallback(){return Xe()},get children(){var e=qe();return X(e,()=>n.icon),y(t=>{var r=n.color+`33`,i=`1px solid ${n.color}66`;return r!==t.e&&fe(e,`background`,t.e=r),i!==t.t&&fe(e,`border`,t.t=i),t},{e:void 0,t:void 0}),e}}),i),X(i,U(G,{when:!r,get children(){var e=Je(),r=e.firstChild,i=r.nextSibling,a=i.nextSibling;return X(r,()=>n.name),X(i,()=>gt(t.ts)),X(a,()=>t.branch),y(e=>fe(r,`color`,n.color)),e}}),null),X(i,U(yt,{e:t}),null),e})()}function yt(e){let t=e.e;switch(t.type){case`prompt`:return(()=>{var e=Ze();return y(()=>e.innerHTML=_e(String(t.data.text??``))),e})();case`message`:return[U(G,{get when(){return K(()=>typeof t.data.reasoning==`string`)()&&t.data.reasoning.trim()},get children(){var e=Se(),n=e.firstChild.nextSibling;return X(n,()=>String(t.data.reasoning)),e}}),(()=>{var e=Ze();return y(()=>e.innerHTML=_e(String(t.data.content??``))),e})()];case`tool_call`:{let e=JSON.stringify(t.data.args,null,1),n=xt(JSON.stringify(t.data.args??{}),110);return(()=>{var r=Qe(),i=r.firstChild,a=i.firstChild;a.firstChild;var o=a.nextSibling.nextSibling,s=i.nextSibling;return X(a,()=>String(t.data.name),null),X(o,n),X(s,e),r})()}case`tool_result`:{let e=String(t.data.result);return(()=>{var n=$e(),r=n.firstChild,i=r.firstChild,a=r.nextSibling,o=a.nextSibling,s=o.firstChild;return X(i,()=>xt(e,120)),X(a,()=>bt(e,4e3)),X(o,()=>t.data.durationMs,s),X(o,()=>t.data.ok?``:` · FAILED`,null),y(()=>J(n,`embed`+(t.data.ok?``:` fail`))),n})()}case`progress`:return(()=>{var e=rt(),n=e.firstChild;return n.firstChild,X(n,()=>String(t.data.doing??``),null),X(e,U(G,{get when(){return t.data.recent},get children(){var e=et();return X(e,()=>String(t.data.recent)),e}}),null),X(e,U(G,{get when(){return t.data.problems},get children(){var e=tt();return e.firstChild,X(e,()=>String(t.data.problems),null),e}}),null),X(e,U(G,{get when(){return t.data.next},get children(){var e=nt();return e.firstChild,X(e,()=>String(t.data.next),null),e}}),null),e})();case`error`:return(()=>{var e=it(),n=e.firstChild;return n.firstChild,X(n,()=>String(t.data.message??``),null),e})();default:return(()=>{var e=at();return X(e,()=>bt(JSON.stringify(t.data),200)),e})()}}function bt(e,t){return e.length>t?e.slice(0,t)+` …`:e}function xt(e,t){return bt(e.replace(/\s+/g,` `).trim(),t)}function St(e){return(()=>{var t=ot(),n=t.firstChild,r=n.firstChild.firstChild,i=r.nextSibling;return t.$$click=t=>t.target===t.currentTarget&&e.onClose(),X(r,()=>e.title),Y(i,`click`,e.onClose,!0),X(n,()=>e.children,null),t})()}function Ct(e){let[t,n]=v(`~`),[r,i]=v([]),[a,o]=v(``),[s,c]=v(e.providers[0]??``),[l,u]=v(``),[d,f]=v(``);async function p(e){let t=await $(`/api/fs${e?`?path=${encodeURIComponent(e)}`:``}`);n(t.path),i(t.entries)}C(()=>p(t()));let m=async n=>{n.preventDefault(),f(``);try{let n=await $(`/api/agents`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({workspace:t(),id:a(),provider:s()||void 0,model:l()||void 0})});e.onCreated(n.agent.id)}catch(e){f(String(e.message))}};return U(St,{title:`new agent`,get onClose(){return e.onClose},get children(){var i=ct(),f=i.firstChild,h=f.firstChild.nextSibling.firstChild,g=h.nextSibling,_=g.nextSibling,v=f.nextSibling,b=v.nextSibling,x=b.firstChild,S=x.firstChild.nextSibling,C=x.nextSibling,w=C.firstChild.nextSibling,ee=C.nextSibling.firstChild.nextSibling,T=b.nextSibling;return i.addEventListener(`submit`,m),h.$$input=e=>n(e.currentTarget.value),g.$$click=()=>p(t()),_.$$click=()=>p(`..`),X(v,U(W,{get each(){return r()},children:e=>(()=>{var n=lt();return n.firstChild,n.$$click=()=>p(`${t()}/${e}`.replace(/\/+/g,`/`)),X(n,e,null),n})()})),S.$$input=e=>o(e.currentTarget.value),w.addEventListener(`change`,e=>c(e.currentTarget.value)),X(w,U(W,{get each(){return e.providers},children:e=>(()=>{var t=ut();return X(t,e),t})()})),ee.$$input=e=>u(e.currentTarget.value),X(i,U(G,{get when(){return d()},get children(){var e=st();return X(e,d),e}}),T),y(()=>h.value=t()),y(()=>S.value=a()),y(()=>w.value=s()),y(()=>ee.value=l()),i}})}function wt(e){let[t,n]=v(JSON.stringify(Object.fromEntries(Object.entries(e.cfg.providers??{}).map(([e,t])=>[e,{baseUrl:t.baseUrl,apiKey:t.apiKey??``,model:t.model??``}])),null,2)),[r,i]=v(e.cfg.defaultProvider??Object.keys(e.cfg.providers??{})[0]??``),[a,o]=v(Math.round((e.cfg.progressIntervalMs??6e5)/6e4)),[s,c]=v(JSON.stringify(e.cfg.tasks??[],null,2)),[l,u]=v(``),d=async n=>{n.preventDefault(),u(``);let i,o;try{i=JSON.parse(t())}catch{return u(`providers: invalid JSON`)}try{o=JSON.parse(s())}catch{return u(`tasks: invalid JSON`)}try{await $(`/api/config`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify({providers:i,defaultProvider:r(),progressIntervalMs:Math.max(1,a())*6e4,tasks:o})}),e.onSaved(),e.onClose()}catch(e){u(String(e.message))}};return U(St,{title:`settings`,get onClose(){return e.onClose},get children(){var u=dt(),f=u.firstChild,p=f.firstChild.nextSibling,m=p.nextSibling.nextSibling,h=f.nextSibling,g=h.firstChild,_=g.firstChild.nextSibling,v=g.nextSibling.firstChild.nextSibling,b=h.nextSibling,x=b.firstChild.nextSibling,S=b.nextSibling;return u.addEventListener(`submit`,d),X(f,()=>e.cfg.configPath,p),m.$$input=e=>n(e.currentTarget.value),_.$$input=e=>i(e.currentTarget.value),v.$$input=e=>o(Number(e.currentTarget.value)),x.$$input=e=>c(e.currentTarget.value),X(u,U(G,{get when(){return l()},get children(){var e=st();return X(e,l),e}}),S),y(()=>m.value=t()),y(()=>_.value=r()),y(()=>v.value=a()),y(()=>x.value=s()),u}})}ue([`click`,`input`]),le(()=>U(_t,{}),document.getElementById(`root`));
@@ -1 +0,0 @@
1
- :root{--bg-darkest:#1a1c22;--bg-dark:#232630;--bg-mid:#2b2e39;--bg-light:#343845;--fg:#dcdee4;--dim:#9298a5;--line:#1d2027;--acc:#5865f2;--ok:#3ba55d;--warn:#faa81a;--err:#ed4245;--tool:#3ba0c9;font-family:gg sans,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--bg-dark);color:var(--fg);font-size:15px}.layout{grid-template-columns:250px 1fr 300px;height:100dvh;display:grid;overflow:hidden}@media (width<=1100px){.layout{grid-template-columns:220px 1fr}.rightbar{z-index:5;width:min(320px,88vw);transition:transform .18s;position:fixed;top:0;bottom:0;right:0;transform:translate(100%);box-shadow:-8px 0 24px #0007}.rightbar.open{transform:none}}.sidebar{background:var(--bg-darkest);flex-direction:column;padding:10px 8px;display:flex;overflow-y:auto}.sidebar h1{color:var(--fg);flex-shrink:0;margin:0;padding:4px 8px 10px;font-size:14px}.agent-list{flex:1;min-height:0;overflow-y:auto}.agent-item{cursor:pointer;color:var(--dim);border-radius:6px;align-items:center;gap:8px;margin-bottom:2px;padding:7px 10px;display:flex}.agent-item:hover{background:var(--bg-mid)}.agent-item.sel{background:var(--bg-mid);color:var(--fg)}.dot{border-radius:50%;flex-shrink:0;width:9px;height:9px}.dot.running{background:var(--ok);box-shadow:0 0 6px var(--ok)}.dot.idle{background:var(--warn)}.dot.stopped{background:var(--dim)}.dot.error{background:var(--err);box-shadow:0 0 6px var(--err)}.sidebar .metrics{color:var(--dim);border-top:1px solid var(--line);margin-top:12px;padding:8px 10px;font-size:11px;line-height:1.7}.channel{flex-direction:column;min-width:0;min-height:0;display:flex;position:relative;overflow:hidden}.chan-head{border-bottom:2px solid var(--line);background:var(--bg-dark);flex-shrink:0;align-items:center;gap:10px;padding:10px 16px;display:flex}.chan-head .hash{color:var(--dim);font-size:20px}.chan-head .title{font-weight:700}.chan-head .sub{color:var(--dim);text-overflow:ellipsis;white-space:nowrap;margin-left:8px;font-size:12px;overflow:hidden}.badge{background:var(--bg-light);vertical-align:middle;border-radius:10px;padding:1px 8px;font-size:11px}.badge.running{color:var(--ok)}.badge.error{color:var(--err)}.badge.idle{color:var(--warn)}.badge.done{color:var(--acc)}.feed{overscroll-behavior:contain;flex:1;min-height:0;padding:14px 0 8px;overflow-y:auto}.msg{gap:14px;padding:3px 18px;display:flex}.msg:hover{background:#ffffff08}.msg.grouped{padding-top:0}.avatar{border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:38px;height:38px;margin-top:2px;font-size:17px;display:flex}.msg-body{flex:1;min-width:0}.msg-head{align-items:baseline;gap:8px;display:flex}.author{font-size:14.5px;font-weight:600}.ts{color:var(--dim);font-size:11px}.content{white-space:pre-wrap;word-break:break-word;line-height:1.45}.content p{margin:2px 0}.content pre{background:var(--bg-darkest);border-radius:6px;padding:8px;overflow-x:auto}.content code{background:var(--bg-darkest);border-radius:4px;padding:1px 4px;font-size:13px}.content h1,.content h2,.content h3,.content h4{margin:8px 0 2px;font-size:15px}.embed{border-left:3px solid var(--tool);background:var(--bg-darkest);border-radius:4px;margin-top:3px;padding:6px 10px;font-size:13.5px}.embed.fail{border-color:var(--err)}.embed summary{cursor:pointer;-webkit-user-select:none;user-select:none;list-style-position:outside}.embed summary::marker{color:var(--dim)}.embed[open] summary{margin-bottom:4px}.embed .mono{white-space:pre-wrap;word-break:break-word;max-height:340px;font-family:ui-monospace,Menlo,monospace;font-size:12.5px;overflow-y:auto}.embed .meta{color:var(--dim);margin-top:3px;font-size:11px}.reasoning{border-left:3px dashed var(--bg-light);color:var(--dim);background:#ffffff05;border-radius:4px;margin:2px 0;padding:2px 10px;font-size:12.5px}.reasoning summary{cursor:pointer;-webkit-user-select:none;user-select:none;opacity:.75}.reasoning summary:hover{opacity:1;color:var(--fg)}.reasoning[open] summary{margin-bottom:4px}.reasoning .mono{white-space:pre-wrap;word-break:break-word;max-height:260px;overflow-y:auto}.msg.live .avatar{animation:1.6s ease-in-out infinite pulse}.cursor{color:var(--acc);animation:1s step-end infinite blink}@keyframes blink{50%{opacity:0}}@keyframes pulse{50%{opacity:.55}}.jump{background:var(--acc);color:#fff;cursor:pointer;z-index:2;border:none;border-radius:999px;padding:6px 14px;font-size:12.5px;font-weight:600;position:absolute;bottom:86px;left:50%;transform:translate(-50%);box-shadow:0 4px 14px #0008}.divider-msg{color:var(--dim);align-items:center;gap:10px;padding:4px 18px;font-size:11.5px;display:flex}.divider-msg:before,.divider-msg:after{content:"";background:var(--line);flex:1;height:1px}.divider-msg.err{color:var(--err)}.day-divider{align-items:center;gap:10px;padding:14px 18px 6px;display:flex}.day-divider:before,.day-divider:after{content:"";background:var(--bg-light);flex:1;height:1px}.day-divider span{color:var(--dim);font-size:11px}.composer{padding:0 16px 18px}.composer form{background:var(--bg-light);border-radius:10px;align-items:center;gap:8px;padding:10px 12px;display:flex}.composer input[type=text]{color:var(--fg);font:inherit;background:0 0;border:none;outline:none;flex:1}.composer button{background:var(--acc);color:#fff;cursor:pointer;border:none;border-radius:8px;padding:7px 14px;font-weight:600}.composer button:hover{opacity:.9}.composer label{color:var(--dim);white-space:nowrap;align-items:center;gap:4px;font-size:12px;display:flex}.hint{color:var(--dim);margin-top:5px;font-size:11px}.rightbar{background:var(--bg-dark);border-left:2px solid var(--line);flex-direction:column;min-height:0;padding:14px;font-size:13px;display:flex;overflow-y:auto}.rightbar h3{text-transform:uppercase;letter-spacing:.04em;color:var(--dim);margin:14px 0 6px;font-size:11px}.rightbar h3:first-child{margin-top:0}.card{background:var(--bg-darkest);white-space:pre-wrap;word-break:break-word;border-radius:8px;max-height:200px;padding:10px;overflow-y:auto}.muted{color:var(--dim)}.branch-row{color:var(--dim);cursor:pointer;justify-content:space-between;padding:3px 0;font-size:12px;display:flex}.branch-row:hover,.branch-row.cur{color:var(--fg)}.btnrow{gap:6px;margin:8px 0;display:flex}.btnrow button{background:var(--bg-light);color:var(--fg);cursor:pointer;border:none;border-radius:6px;padding:6px 10px;font-size:13px}.btnrow button:hover{filter:brightness(1.2)}.iconbtn{background:var(--bg-light);color:var(--fg);cursor:pointer;border:none;border-radius:6px;width:26px;height:24px;font-size:13px}.iconbtn:hover{filter:brightness(1.3)}.overlay{z-index:10;background:#0009;place-items:center;display:grid;position:fixed;inset:0}.modal{background:var(--bg-mid);border-radius:10px;width:min(620px,92vw);max-height:88vh;padding:16px 18px;overflow-y:auto}.modal-head{justify-content:space-between;align-items:center;margin-bottom:12px;font-size:16px;display:flex}.modal label{color:var(--dim);flex-direction:column;gap:4px;font-size:12.5px;display:flex}.modal input[type=text],.modal input[type=number],.modal select,.modal textarea{background:var(--bg-darkest);color:var(--fg);font:inherit;border:none;border-radius:6px;outline:none;padding:7px 9px}.modal textarea{resize:vertical}.w100{width:100%}.mono{font-family:ui-monospace,Menlo,monospace;font-size:13px}.dirlist{background:var(--bg-darkest);border-radius:6px;max-height:160px;padding:4px;overflow-y:auto}.direntry{cursor:pointer;border-radius:4px;padding:4px 8px;font-size:14px}.direntry:hover{background:var(--bg-light)}