@markmo/europacore-session-ui 0.3.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.
Files changed (51) hide show
  1. package/dist/ArtifactsPage-BxaqShTv.js +1178 -0
  2. package/dist/{BoardPage-DDcf5vup.js → BoardPage-DH7p5o99.js} +54 -54
  3. package/dist/{CardDetail-D0TLVhf7.js → CardDetail-LfDCJQhS.js} +26 -26
  4. package/dist/{ComparePage-C32hPOqV.js → ComparePage-CrbCyu4u.js} +33 -33
  5. package/dist/MemoriesPage-BRA53Hlb.js +679 -0
  6. package/dist/{OverviewPage-BkeuYg6d.js → OverviewPage-BSBqY83_.js} +31 -31
  7. package/dist/{RegisterPage-Dawr26jh.js → RegisterPage-64yGl9E-.js} +75 -75
  8. package/dist/SessionPage-C4hSlxWQ.js +906 -0
  9. package/dist/api/agentClient.d.ts +62 -1
  10. package/dist/api/wire.d.ts +461 -4
  11. package/dist/features/artifacts/ArtifactDetail.d.ts +15 -0
  12. package/dist/features/artifacts/ArtifactDialogs.d.ts +29 -0
  13. package/dist/features/artifacts/ArtifactLedger.d.ts +11 -0
  14. package/dist/features/artifacts/ArtifactStats.d.ts +9 -0
  15. package/dist/features/artifacts/ArtifactsPage.d.ts +1 -0
  16. package/dist/features/artifacts/artifactsCommands.d.ts +3 -0
  17. package/dist/features/artifacts/artifactsStore.d.ts +27 -0
  18. package/dist/features/artifacts/artifactsUi.d.ts +33 -0
  19. package/dist/features/bootstrap.d.ts +1 -0
  20. package/dist/features/chat/model/artifactAccess.d.ts +50 -0
  21. package/dist/features/chat/model/artifactCsv.d.ts +11 -0
  22. package/dist/features/chat/model/artifactExport.d.ts +45 -0
  23. package/dist/features/chat/model/artifactStats.d.ts +79 -0
  24. package/dist/features/chat/model/artifacts.d.ts +151 -0
  25. package/dist/features/chat/model/claims.d.ts +102 -0
  26. package/dist/features/chat/model/contextSources.d.ts +41 -0
  27. package/dist/features/chat/model/entries.d.ts +32 -2
  28. package/dist/features/chat/model/format.d.ts +6 -0
  29. package/dist/features/chat/model/memoryRecords.d.ts +79 -0
  30. package/dist/features/chat/model/monitors.d.ts +11 -0
  31. package/dist/features/chat/model/progress.d.ts +73 -0
  32. package/dist/features/chat/model/tasks.d.ts +1 -1
  33. package/dist/features/chat/panels/ProgressPanel.d.ts +8 -0
  34. package/dist/features/chat/session/SessionController.d.ts +3 -2
  35. package/dist/features/chat/session/useFileMentions.d.ts +18 -5
  36. package/dist/features/chat/transcript/ArtifactCard.d.ts +8 -0
  37. package/dist/features/chat/transcript/Rows.d.ts +12 -1
  38. package/dist/features/memories/MemoriesPage.d.ts +1 -0
  39. package/dist/features/memories/memoriesCommands.d.ts +3 -0
  40. package/dist/features/memories/memoriesController.d.ts +81 -0
  41. package/dist/features/workspace/claimsCommands.d.ts +26 -0
  42. package/dist/features/workspace/collisionsWatcher.d.ts +7 -0
  43. package/dist/features/workspace/useSessionPageHooks.d.ts +1 -1
  44. package/dist/{index-B0hmy2Cw.js → index-CMPf-3JZ.js} +4412 -3293
  45. package/dist/index.d.ts +2 -0
  46. package/dist/index.js +86 -82
  47. package/dist/lib/paths.d.ts +12 -0
  48. package/dist/lib/zip.d.ts +14 -0
  49. package/dist/{promptHistory-DQyt2Br0.js → promptHistory-BR0NpLCI.js} +14 -14
  50. package/package.json +1 -1
  51. package/dist/SessionPage-68nDek9w.js +0 -881
@@ -1,881 +0,0 @@
1
- import { jsxs as g, jsx as t } from "react/jsx-runtime";
2
- import { useMemo as B, useEffect as M, useRef as z, useState as S, useCallback as H, useLayoutEffect as te, memo as He, useId as Ce, useSyncExternalStore as Be } from "react";
3
- import { useParams as je, useSearchParams as qe, useNavigate as se } from "react-router";
4
- import { Sparkles as Ve, ArrowDown as Ge, CircleSlash as We, X as Ee, ImagePlus as Je, ListPlus as Qe, Square as Ye, ArrowUp as Xe, RefreshCw as Ze, Loader2 as et, Pause as tt, MessageSquareDashed as pe, PanelRightClose as nt, PanelRight as st } from "lucide-react";
5
- import { c as W, s as Ie, i as he, u as O, C as D, a as R, L as P, t as at, U as rt, D as it, b as ot, A as ct, W as lt, T as ut, R as dt, d as mt, S as ft, N as pt, e as ht, f as gt, B as xt, r as wt, g as Ae, h as bt, j as yt, m as kt, k as vt, l as Nt, I as ne, p as St, n as ge, o as Dt, q as xe, v as Me, w as X, x as Ct, y as A, z as J, E as Et, F as we, G as Te, H as It, J as At, K as Mt, M as Tt, O as $t, P as Pt, Q as Rt, V as zt, X as be, Y as Ft, Z as ye, _ as Kt } from "./index-B0hmy2Cw.js";
6
- import { p as ae, w as _t, P as Lt } from "./promptHistory-DQyt2Br0.js";
7
- function Ot({ onPick: e }) {
8
- const n = (Ie().userName() || "").split(" ")[0];
9
- return /* @__PURE__ */ g("div", { className: "mx-auto flex w-full max-w-3xl flex-1 flex-col justify-center px-4 py-10 sm:px-6", children: [
10
- /* @__PURE__ */ g("div", { className: "mb-7 flex flex-col items-start gap-3", children: [
11
- /* @__PURE__ */ t("span", { className: "flex h-10 w-10 items-center justify-center rounded-xl bg-accent text-on-accent", children: /* @__PURE__ */ t(Ve, { size: 19 }) }),
12
- /* @__PURE__ */ t("h1", { className: "text-[26px] leading-tight font-semibold text-ink", children: n ? `How can I help, ${n}?` : "How can I help?" }),
13
- /* @__PURE__ */ t("p", { className: "text-[13.5px] text-muted", children: "Ask anything. The assistant can use tools, and it will ask before doing anything with side effects." })
14
- ] }),
15
- /* @__PURE__ */ t("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: W.suggestions.map((r) => /* @__PURE__ */ g(
16
- "button",
17
- {
18
- type: "button",
19
- onClick: () => e(r.prompt),
20
- className: "rounded-xl border border-line bg-surface px-3.5 py-3 text-left transition-colors hover:border-accent hover:bg-accent-soft focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40",
21
- children: [
22
- /* @__PURE__ */ t("div", { className: "text-[13.5px] font-semibold text-ink", children: r.title }),
23
- r.description && /* @__PURE__ */ t("div", { className: "mt-0.5 text-[12.5px] text-muted", children: r.description })
24
- ]
25
- },
26
- r.title
27
- )) })
28
- ] });
29
- }
30
- function $e(e) {
31
- const n = B(() => [...new Set(he().flatMap((r) => r.keys ?? []))], []);
32
- return O(e, D.session, D.reset, D.workspace, D.fleet, ...n), he().filter((r) => r.available(e));
33
- }
34
- function ke({
35
- controller: e,
36
- tab: n,
37
- onTab: r,
38
- className: i
39
- }) {
40
- const m = $e(e), o = m.find((c) => c.id === n) ?? m[0];
41
- if (M(() => {
42
- o && o.id !== n && r(o.id);
43
- }, [o, n, r]), !o) return null;
44
- const a = o.Component;
45
- return /* @__PURE__ */ g("div", { className: R("flex min-h-0 flex-col", i), children: [
46
- /* @__PURE__ */ t("div", { role: "tablist", "aria-label": "Session panels", className: "flex shrink-0 gap-0.5 overflow-x-auto border-b border-line px-2 pt-1.5", children: m.map((c) => {
47
- const d = c.icon, l = c.badge?.(e) ?? null, f = c.id === o.id;
48
- return /* @__PURE__ */ g(
49
- "button",
50
- {
51
- type: "button",
52
- role: "tab",
53
- "aria-selected": f,
54
- onClick: () => r(c.id),
55
- className: R(
56
- "-mb-px inline-flex h-9 shrink-0 items-center gap-1.5 border-b-2 px-2.5 text-[12.5px] font-semibold transition-colors",
57
- f ? "border-accent text-ink" : "border-transparent text-muted hover:text-ink"
58
- ),
59
- children: [
60
- /* @__PURE__ */ t(d, { size: 14 }),
61
- c.label,
62
- l !== null && /* @__PURE__ */ t("span", { className: "rounded-full bg-accent-soft px-1.5 text-[10.5px] text-accent tabular-nums", children: l })
63
- ]
64
- },
65
- c.id
66
- );
67
- }) }),
68
- /* @__PURE__ */ t("div", { role: "tabpanel", className: "min-h-0 flex-1 overflow-y-auto p-3", children: /* @__PURE__ */ t(a, { controller: e }) })
69
- ] });
70
- }
71
- const Ut = 80, Ht = He(function({
72
- controller: n,
73
- block: r,
74
- live: i
75
- }) {
76
- const m = ot(r.items), o = r.items.find((d) => d.kind === "entry" && d.entry.kind === "run-end"), a = o?.kind === "entry" && o.entry.kind === "run-end" && o.entry.outcome === "cancelled", c = m ? n.store.get(m) : void 0;
77
- return /* @__PURE__ */ t("div", { className: "group", children: /* @__PURE__ */ g(
78
- ct,
79
- {
80
- header: a ? /* @__PURE__ */ g(xt, { children: [
81
- /* @__PURE__ */ t(We, { size: 11 }),
82
- " Stopped"
83
- ] }) : void 0,
84
- children: [
85
- r.wake && /* @__PURE__ */ t(lt, { entry: r.wake }),
86
- r.items.map((d) => {
87
- if (d.kind === "tools") return /* @__PURE__ */ t(ut, { controller: n, entries: d.entries }, d.key);
88
- const l = d.entry;
89
- switch (l.kind) {
90
- case "assistant":
91
- return /* @__PURE__ */ t(ht, { controller: n, entry: l, answer: l.key === m }, l.key);
92
- case "notice":
93
- return /* @__PURE__ */ t(pt, { entry: l }, l.key);
94
- case "steer":
95
- return /* @__PURE__ */ t(ft, { controller: n, entry: l }, l.key);
96
- case "decision":
97
- return /* @__PURE__ */ t(mt, { controller: n, entry: l }, l.key);
98
- case "run-end":
99
- return /* @__PURE__ */ t(dt, { entry: l }, l.key);
100
- default:
101
- return null;
102
- }
103
- }),
104
- !i && c?.kind === "assistant" && c.text && /* @__PURE__ */ t("div", { className: "-mt-1 -ml-1.5 flex items-center gap-0.5 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100 max-sm:opacity-100", children: /* @__PURE__ */ t(gt, { text: c.text, label: "Copy answer" }) })
105
- ]
106
- }
107
- ) });
108
- });
109
- function Bt({
110
- controller: e,
111
- onEdit: n,
112
- footer: r,
113
- renderDiff: i
114
- }) {
115
- const m = O(e, P.list, D.run), o = e.store.state.entries, a = B(() => at(o), [m, o]), c = e.running(), d = e.store.state.run?.id ?? null, l = z(null), f = z(null), x = z(!0), k = z(0), [p, b] = S(!1), y = H((w = "auto") => {
116
- const h = l.current;
117
- h && h.scrollTo({ top: h.scrollHeight, behavior: w });
118
- }, []), C = () => {
119
- const w = l.current;
120
- if (!w) return;
121
- const h = w.scrollHeight - w.scrollTop - w.clientHeight < Ut, T = w.scrollTop < k.current - 2;
122
- k.current = w.scrollTop, h ? x.current = !0 : T && (x.current = !1), b(!x.current);
123
- };
124
- M(() => {
125
- const w = f.current;
126
- if (!w || typeof ResizeObserver > "u") return;
127
- const h = new ResizeObserver(() => {
128
- x.current && y();
129
- });
130
- return h.observe(w), () => h.disconnect();
131
- }, [y]);
132
- const F = a[a.length - 1];
133
- return te(() => {
134
- F?.kind === "user" && (x.current = !0, b(!1)), x.current && y();
135
- }, [F?.key, F?.kind, y]), te(() => {
136
- x.current = !0, b(!1), y();
137
- }, [e, y]), /* @__PURE__ */ g("div", { className: "relative min-h-0 flex-1", children: [
138
- /* @__PURE__ */ t("div", { ref: l, onScroll: C, className: "h-full overflow-y-auto overscroll-contain", children: /* @__PURE__ */ g(
139
- "div",
140
- {
141
- ref: f,
142
- role: "log",
143
- "aria-live": "polite",
144
- "aria-relevant": "additions",
145
- "aria-label": "Conversation",
146
- className: "mx-auto flex w-full max-w-3xl flex-col gap-5 px-4 pt-6 pb-8 sm:px-6",
147
- children: [
148
- a.map((w) => w.kind === "user" ? /* @__PURE__ */ t(rt, { controller: e, entry: w.entry, onEdit: c ? void 0 : n }, w.key) : w.kind === "diff" ? /* @__PURE__ */ t(it, { entry: w.entry, renderDiff: i }, w.key) : /* @__PURE__ */ t(Ht, { controller: e, block: w, live: c && w.runId === d }, w.key)),
149
- r
150
- ]
151
- }
152
- ) }),
153
- p && /* @__PURE__ */ g(
154
- "button",
155
- {
156
- type: "button",
157
- onClick: () => {
158
- x.current = !0, b(!1), y("smooth");
159
- },
160
- className: "absolute bottom-3 left-1/2 inline-flex -translate-x-1/2 items-center gap-1.5 rounded-full border border-line bg-surface px-3 py-1.5 text-[12px] font-semibold text-ink shadow-pop hover:bg-surface-hover",
161
- children: [
162
- /* @__PURE__ */ t(Ge, { size: 13 }),
163
- " Jump to latest"
164
- ]
165
- }
166
- )
167
- ] });
168
- }
169
- const jt = 1536, qt = /^image\/(png|jpe?g|gif|webp)$/;
170
- function ve(e) {
171
- return qt.test(e.type);
172
- }
173
- async function Vt(e, n = jt) {
174
- const r = await new Promise((c, d) => {
175
- const l = new FileReader();
176
- l.onload = () => c(String(l.result)), l.onerror = () => d(l.error), l.readAsDataURL(e);
177
- });
178
- if (e.type === "image/gif") return { kind: "image", name: e.name, url: r };
179
- const i = await new Promise((c, d) => {
180
- const l = new Image();
181
- l.onload = () => c(l), l.onerror = d, l.src = r;
182
- }), m = Math.min(1, n / Math.max(i.width, i.height));
183
- if (m === 1 && e.size < 15e5) return { kind: "image", name: e.name, url: r };
184
- const o = document.createElement("canvas");
185
- o.width = Math.round(i.width * m), o.height = Math.round(i.height * m), o.getContext("2d").drawImage(i, 0, 0, o.width, o.height);
186
- const a = e.type === "image/png" ? "image/png" : "image/jpeg";
187
- return { kind: "image", name: e.name, url: o.toDataURL(a, 0.88) };
188
- }
189
- function Ne(e, n, r) {
190
- return r === 0 ? 0 : (e + n + r) % r;
191
- }
192
- const Gt = 200;
193
- function Wt(e, n, r) {
194
- const i = z(null);
195
- M(() => {
196
- const a = i.current;
197
- a && a.list[a.index] !== e && (i.current = null);
198
- }, [e]);
199
- const m = (a, c) => {
200
- n(a), requestAnimationFrame(() => {
201
- const d = r.current;
202
- if (!d) return;
203
- const l = c ? 0 : a.length;
204
- d.setSelectionRange(l, l);
205
- });
206
- };
207
- return { onKeyDown: (a) => {
208
- if (a.altKey || a.ctrlKey || a.metaKey || a.shiftKey || a.key !== "ArrowUp" && a.key !== "ArrowDown") return !1;
209
- const c = a.currentTarget;
210
- if (c.selectionStart !== c.selectionEnd) return !1;
211
- const d = c.value.slice(0, c.selectionStart), l = c.value.slice(c.selectionEnd);
212
- if (a.key === "ArrowUp") {
213
- if (d.includes(`
214
- `)) return !1;
215
- const x = i.current ?? { list: ae.recent(), index: -1, draft: e }, k = x.index === -1 ? x.list.length - 1 : x.index - 1;
216
- return k < 0 ? !1 : (i.current = { ...x, index: k }, a.preventDefault(), m(x.list[k], !0), !0);
217
- }
218
- const f = i.current;
219
- return !f || l.includes(`
220
- `) ? !1 : (a.preventDefault(), f.index + 1 >= f.list.length ? (i.current = null, m(f.draft, !1)) : (i.current = { ...f, index: f.index + 1 }, m(f.list[f.index + 1], !1)), !0);
221
- }, reset: () => {
222
- i.current = null;
223
- } };
224
- }
225
- function Jt({ workspace: e, onPick: n, onClose: r }) {
226
- const [i, m] = S(""), [o, a] = S(0), c = B(() => ae.search("", e).slice(0, Gt), [e]), d = i.toLowerCase().split(/\s+/).filter(Boolean), l = c.filter((p) => d.every((b) => p.text.toLowerCase().includes(b))), f = Math.min(o, Math.max(0, l.length - 1)), x = (p) => {
227
- const b = l[p];
228
- b && n(b.text);
229
- }, k = Ce();
230
- return /* @__PURE__ */ g("div", { className: "absolute bottom-full left-0 z-20 mb-2 w-full rounded-xl border border-line bg-surface p-1.5 shadow-pop", children: [
231
- /* @__PURE__ */ t(
232
- "input",
233
- {
234
- autoFocus: !0,
235
- value: i,
236
- onChange: (p) => {
237
- m(p.target.value), a(0);
238
- },
239
- onKeyDown: (p) => {
240
- p.key === "ArrowDown" || p.key === "r" && p.ctrlKey ? (p.preventDefault(), a(Math.min(l.length - 1, f + 1))) : p.key === "ArrowUp" ? (p.preventDefault(), a(Math.max(0, f - 1))) : p.key === "Enter" ? (p.preventDefault(), x(f)) : p.key === "Escape" && (p.preventDefault(), r());
241
- },
242
- onBlur: r,
243
- placeholder: "Search the prompts you have sent",
244
- "aria-label": "Search prompt history",
245
- "aria-controls": l.length ? k : void 0,
246
- "aria-activedescendant": l.length ? `${k}-${f}` : void 0,
247
- "aria-autocomplete": "list",
248
- className: "mb-1 h-8 w-full rounded-md border border-line bg-surface px-2 text-[13px] text-ink placeholder:text-faint focus:border-accent focus:outline-none"
249
- }
250
- ),
251
- l.length === 0 ? /* @__PURE__ */ t("p", { className: "px-2.5 py-2 text-[12.5px] text-muted", children: c.length ? "No prompt has those words." : "No prompts sent yet." }) : /* @__PURE__ */ t("div", { id: k, role: "listbox", "aria-label": "Prompt history", className: "max-h-64 overflow-y-auto", children: l.map((p, b) => (
252
- // biome-ignore lint/a11y/useFocusableInteractive: a combobox option; focus stays in the search box (aria-activedescendant)
253
- /* @__PURE__ */ g(
254
- "div",
255
- {
256
- id: `${k}-${b}`,
257
- role: "option",
258
- "aria-selected": b === f,
259
- onMouseDown: (y) => {
260
- y.preventDefault(), x(b);
261
- },
262
- onMouseEnter: () => a(b),
263
- className: R("flex cursor-pointer items-baseline gap-2 rounded-md px-2.5 py-1.5 text-[13px]", b === f && "bg-accent-soft"),
264
- children: [
265
- /* @__PURE__ */ t("span", { className: "min-w-0 flex-1 truncate text-ink", children: p.text.replace(/\s+/g, " ") }),
266
- /* @__PURE__ */ g("span", { className: "shrink-0 text-[11px] text-faint", children: [
267
- wt(new Date(p.at).toISOString()),
268
- p.workspace && p.workspace !== e ? ` · ${p.workspace.split("/").pop()}` : ""
269
- ] })
270
- ]
271
- },
272
- `${p.at}-${b}`
273
- )
274
- )) })
275
- ] });
276
- }
277
- function Qt(e) {
278
- const n = /(?:^|\s)@([^\s@]*)$/.exec(e);
279
- return n ? n[1] : null;
280
- }
281
- function Yt(e, n) {
282
- return e.replace(/@([^\s@]*)$/, `@${n} `);
283
- }
284
- function Xt(e, n) {
285
- const [r, i] = S([]), m = Ie().workspaces, o = n !== null && e.hasWorkspace() && m !== null;
286
- return M(() => {
287
- if (!o) {
288
- i([]);
289
- return;
290
- }
291
- let a = !1;
292
- const c = setTimeout(() => {
293
- m.files(e.id, n ?? "").then((d) => !a && i(d.slice(0, 30))).catch(() => !a && i([]));
294
- }, 120);
295
- return () => {
296
- a = !0, clearTimeout(c);
297
- };
298
- }, [e, o, n, m]), o ? r : [];
299
- }
300
- function Zt(e) {
301
- const n = /^\/([\w.:-]*)$/.exec(e);
302
- return n ? n[1].toLowerCase() : null;
303
- }
304
- function en({ controller: e, commandContext: n, disabled: r, autoFocus: i, registerHandle: m }) {
305
- const { toast: o } = Ae(), a = O(e, P.commands);
306
- O(e, D.run, D.pause, P.images, P.draft, P.followUps), Be(bt, yt);
307
- const c = e.running(), d = e.agent?.accepts_images ?? !0, l = d ? Math.min(e.agent?.image_limits?.max_count ?? W.maxImages, W.maxImages) : 0, f = e.images, [x, k] = S(e.draft), [p, b] = S(!1), [y, C] = S(0), [F, w] = S(!1), [h, T] = S(!1), v = z(null), q = z(null), K = Ce(), E = H(
308
- (s) => {
309
- k(s), e.setDraft(s);
310
- },
311
- [e]
312
- ), Pe = e.version(P.draft);
313
- M(() => {
314
- k(e.draft);
315
- }, [e, Pe]), te(() => {
316
- const s = v.current;
317
- s && (s.style.height = "auto", s.style.height = `${Math.min(s.scrollHeight, 240)}px`);
318
- }, [x]);
319
- const _ = B(
320
- () => ({
321
- ...n,
322
- controller: e,
323
- setComposer: (s) => {
324
- E(s), requestAnimationFrame(() => {
325
- const u = v.current;
326
- u && (u.focus(), u.setSelectionRange(u.value.length, u.value.length));
327
- });
328
- },
329
- pickImages: () => q.current?.click()
330
- }),
331
- [n, e, E]
332
- );
333
- M(() => (m?.({ setText: _.setComposer, pickImages: _.pickImages, focus: () => v.current?.focus() }), () => m?.(null)), [_, m]);
334
- const re = Wt(x, E, v), ie = e.session?.workspace ?? e.newSession.workspace?.path ?? null, Q = F ? null : Zt(x), $ = B(
335
- () => Q === null ? [] : kt([...vt(_), ...Nt(e)], Q).slice(0, 40),
336
- [Q, _, e, a]
337
- ), U = $.length > 0, Re = U || F ? null : Qt(x), L = Xt(e, Re), V = !U && L.length > 0, oe = (s) => {
338
- const u = L[Math.min(s, L.length - 1)];
339
- u && (E(Yt(x, u)), C(0), requestAnimationFrame(() => v.current?.focus()));
340
- }, Y = H(
341
- async (s) => {
342
- const u = s.filter(ve);
343
- if (s.length && !u.length) {
344
- o("Only PNG, JPEG, GIF and WebP images can be attached.", "danger");
345
- return;
346
- }
347
- if (!d) {
348
- o(`${e.agent?.name ?? "This agent"} doesn't take images.`, "danger");
349
- return;
350
- }
351
- const N = l - e.images.length;
352
- u.length > N && o(`Up to ${l} images per message.`, "danger");
353
- const Oe = (await Promise.all(u.slice(0, Math.max(0, N)).map((j) => Vt(j)))).map((j, Ue) => {
354
- const fe = /^data:([^;,]+);base64,(.*)$/s.exec(j.url);
355
- return { name: j.name ?? `image ${Ue + 1}`, url: j.url, image: { media_type: fe?.[1] ?? "image/png", data: fe?.[2] ?? "" } };
356
- });
357
- e.setImages([...e.images, ...Oe].slice(0, l));
358
- },
359
- [d, e, l, o]
360
- ), I = x.trim(), ce = !r && !!(I || f.length && !c), G = async (s = !1) => {
361
- if (!ce) return;
362
- re.reset(), I && ae.record(I, ie);
363
- const u = St(I);
364
- if (u && e.serverCommand(u.raw) && !ge(u.name)) {
365
- E(""), await e.runServerCommand(I);
366
- return;
367
- }
368
- if (u && ge(u.name)) {
369
- E("");
370
- try {
371
- await Dt(_, I);
372
- } catch (N) {
373
- o(N instanceof Error ? N.message : String(N), "danger");
374
- }
375
- return;
376
- }
377
- if (E(""), s && c) {
378
- e.queueFollowUp(I);
379
- return;
380
- }
381
- await e.submit(I);
382
- }, le = (s) => {
383
- const u = $[Math.min(s, $.length - 1)];
384
- if (u) {
385
- if (C(0), u.needsArgs) {
386
- E(`/${u.name} `), requestAnimationFrame(() => v.current?.focus());
387
- return;
388
- }
389
- E(""), Promise.resolve(u.run(_, "")).catch((N) => o(N instanceof Error ? N.message : String(N), "danger"));
390
- }
391
- }, ze = (s) => {
392
- if (!s.nativeEvent.isComposing) {
393
- if (V) {
394
- if (s.key === "ArrowDown" || s.key === "ArrowUp") {
395
- s.preventDefault(), C((u) => Ne(u, s.key === "ArrowDown" ? 1 : -1, L.length));
396
- return;
397
- }
398
- if (s.key === "Tab" || s.key === "Enter" && !s.shiftKey) {
399
- s.preventDefault(), oe(y);
400
- return;
401
- }
402
- if (s.key === "Escape") {
403
- s.preventDefault(), w(!0);
404
- return;
405
- }
406
- }
407
- if (U) {
408
- if (s.key === "ArrowDown" || s.key === "ArrowUp") {
409
- s.preventDefault(), C((u) => Ne(u, s.key === "ArrowDown" ? 1 : -1, $.length));
410
- return;
411
- }
412
- if (s.key === "Tab") {
413
- s.preventDefault();
414
- const u = $[Math.min(y, $.length - 1)];
415
- u && E(`/${u.name} `);
416
- return;
417
- }
418
- if (s.key === "Enter" && !s.shiftKey) {
419
- s.preventDefault(), le(y);
420
- return;
421
- }
422
- if (s.key === "Escape") {
423
- s.preventDefault(), w(!0);
424
- return;
425
- }
426
- }
427
- if (s.key === "r" && s.ctrlKey && !s.altKey && !s.metaKey) {
428
- s.preventDefault(), T(!0);
429
- return;
430
- }
431
- if (!re.onKeyDown(s)) {
432
- if (s.key === "Escape" && c && !I) {
433
- s.preventDefault(), e.cancelRun();
434
- return;
435
- }
436
- if (s.key === "Enter" && s.altKey) {
437
- s.preventDefault(), G(!0);
438
- return;
439
- }
440
- s.key === "Enter" && !s.shiftKey && (s.preventDefault(), G());
441
- }
442
- }
443
- }, Fe = (s) => {
444
- const u = Array.from(s.clipboardData.files);
445
- u.some(ve) && (s.preventDefault(), Y(u));
446
- }, Ke = (s) => {
447
- s.preventDefault(), b(!1), Y(Array.from(s.dataTransfer.files));
448
- }, ue = e.store.state.pause, de = W.ComposerFooter, _e = e.isWorker(), Le = c ? "Steer the turn in progress… (Alt+Enter queues it for after)" : ue?.kind === "question" ? "Answer in your own words…" : ue?.kind === "flow_input" ? "Reply to the flow…" : _e ? "Steer this task through its fleet…" : `Message ${e.agent?.name ?? "the agent"}… (/ for commands)`;
449
- return /* @__PURE__ */ g("div", { className: "relative", children: [
450
- h && /* @__PURE__ */ t(
451
- Jt,
452
- {
453
- workspace: ie,
454
- onPick: (s) => {
455
- T(!1), _.setComposer(s);
456
- },
457
- onClose: () => {
458
- T(!1), requestAnimationFrame(() => v.current?.focus());
459
- }
460
- }
461
- ),
462
- U && !h && /* @__PURE__ */ t(
463
- "div",
464
- {
465
- id: K,
466
- role: "listbox",
467
- "aria-label": "Commands",
468
- className: "absolute bottom-full left-0 z-20 mb-2 max-h-72 w-full overflow-y-auto rounded-xl border border-line bg-surface p-1.5 shadow-pop",
469
- children: $.map((s, u) => (
470
- // biome-ignore lint/a11y/useFocusableInteractive: a combobox option; focus stays in the textarea (aria-activedescendant)
471
- /* @__PURE__ */ g(
472
- "div",
473
- {
474
- id: `${K}-${u}`,
475
- role: "option",
476
- "aria-selected": u === Math.min(y, $.length - 1),
477
- onMouseDown: (N) => {
478
- N.preventDefault(), le(u);
479
- },
480
- onMouseEnter: () => C(u),
481
- className: R(
482
- "flex cursor-pointer items-baseline gap-2 rounded-md px-2.5 py-1.5 text-[13px]",
483
- u === Math.min(y, $.length - 1) ? "bg-accent-soft" : ""
484
- ),
485
- children: [
486
- /* @__PURE__ */ g("span", { className: R("shrink-0 font-mono font-semibold", u === y ? "text-accent" : "text-ink"), children: [
487
- "/",
488
- s.name
489
- ] }),
490
- s.args && /* @__PURE__ */ t("span", { className: "shrink-0 font-mono text-[11.5px] text-faint", children: s.args }),
491
- /* @__PURE__ */ t("span", { className: "min-w-0 truncate text-muted", children: s.description })
492
- ]
493
- },
494
- s.name
495
- )
496
- ))
497
- }
498
- ),
499
- V && /* @__PURE__ */ t(
500
- "div",
501
- {
502
- id: `${K}-files`,
503
- role: "listbox",
504
- "aria-label": "Files",
505
- className: "absolute bottom-full left-0 z-20 mb-2 max-h-72 w-full overflow-y-auto rounded-xl border border-line bg-surface p-1.5 shadow-pop",
506
- children: L.map((s, u) => (
507
- // biome-ignore lint/a11y/useFocusableInteractive: a combobox option; focus stays in the textarea (aria-activedescendant)
508
- /* @__PURE__ */ t(
509
- "div",
510
- {
511
- id: `${K}-files-${u}`,
512
- role: "option",
513
- "aria-selected": u === Math.min(y, L.length - 1),
514
- onMouseDown: (N) => {
515
- N.preventDefault(), oe(u);
516
- },
517
- onMouseEnter: () => C(u),
518
- className: R(
519
- "cursor-pointer truncate rounded-md px-2.5 py-1.5 font-mono text-[12.5px] text-ink",
520
- u === Math.min(y, L.length - 1) && "bg-accent-soft text-accent"
521
- ),
522
- children: s
523
- },
524
- s
525
- )
526
- ))
527
- }
528
- ),
529
- /* @__PURE__ */ g(
530
- "div",
531
- {
532
- onDragOver: (s) => {
533
- s.dataTransfer.types.includes("Files") && (s.preventDefault(), b(!0));
534
- },
535
- onDragLeave: () => b(!1),
536
- onDrop: Ke,
537
- className: R(
538
- "rounded-2xl border bg-surface p-1.5 shadow-sm transition-colors",
539
- "focus-within:border-accent focus-within:ring-2 focus-within:ring-accent/20",
540
- p ? "border-accent bg-accent-soft" : "border-line",
541
- r && "opacity-60"
542
- ),
543
- children: [
544
- f.length > 0 && /* @__PURE__ */ t("div", { className: "flex flex-wrap gap-2 px-1.5 pt-1 pb-2", children: f.map((s, u) => (
545
- // biome-ignore lint/suspicious/noArrayIndexKey: stateless thumbnails, removed by position
546
- /* @__PURE__ */ g("div", { className: "relative", children: [
547
- /* @__PURE__ */ t("img", { src: s.url, alt: s.name, className: "h-16 w-16 rounded-lg border border-line-soft object-cover" }),
548
- /* @__PURE__ */ t(
549
- "button",
550
- {
551
- type: "button",
552
- "aria-label": `Remove ${s.name}`,
553
- onClick: () => e.setImages(f.filter((N, me) => me !== u)),
554
- className: "absolute -top-1.5 -right-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-ink text-surface shadow",
555
- children: /* @__PURE__ */ t(Ee, { size: 11 })
556
- }
557
- )
558
- ] }, u)
559
- )) }),
560
- /* @__PURE__ */ g("div", { className: "flex items-end gap-1", children: [
561
- /* @__PURE__ */ t(
562
- ne,
563
- {
564
- label: "Attach images",
565
- disabled: r || !d || f.length >= l,
566
- onClick: () => q.current?.click(),
567
- className: "mb-0.5 h-9 w-9 rounded-full",
568
- children: /* @__PURE__ */ t(Je, { size: 17 })
569
- }
570
- ),
571
- /* @__PURE__ */ t(
572
- "input",
573
- {
574
- ref: q,
575
- type: "file",
576
- accept: "image/png,image/jpeg,image/gif,image/webp",
577
- multiple: !0,
578
- hidden: !0,
579
- onChange: (s) => {
580
- Y(Array.from(s.target.files ?? [])), s.target.value = "";
581
- }
582
- }
583
- ),
584
- /* @__PURE__ */ t(
585
- "textarea",
586
- {
587
- ref: v,
588
- value: x,
589
- onChange: (s) => {
590
- E(s.target.value), w(!1), C(0);
591
- },
592
- onKeyDown: ze,
593
- onPaste: Fe,
594
- rows: 1,
595
- autoFocus: i,
596
- disabled: r,
597
- placeholder: Le,
598
- "aria-label": "Message",
599
- "aria-controls": U ? K : V ? `${K}-files` : void 0,
600
- "aria-activedescendant": U ? `${K}-${Math.min(y, $.length - 1)}` : V ? `${K}-files-${Math.min(y, L.length - 1)}` : void 0,
601
- "aria-autocomplete": "list",
602
- enterKeyHint: "send",
603
- className: "max-h-[240px] min-h-10 flex-1 resize-none bg-transparent px-1.5 py-2.5 text-[16px] leading-snug text-ink outline-none placeholder:truncate placeholder:text-faint disabled:cursor-not-allowed sm:text-[14.5px]"
604
- }
605
- ),
606
- c && I && /* @__PURE__ */ t(ne, { label: "Queue for after this turn (Alt+Enter)", className: "mb-0.5 h-9 w-9 rounded-full", onClick: () => {
607
- G(!0);
608
- }, children: /* @__PURE__ */ t(Qe, { size: 17 }) }),
609
- c && !I ? /* @__PURE__ */ t(
610
- "button",
611
- {
612
- type: "button",
613
- onClick: () => {
614
- e.cancelRun();
615
- },
616
- "aria-label": "Stop the turn (Esc)",
617
- title: "Stop the turn (Esc)",
618
- className: "mb-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-ink text-surface transition-opacity hover:opacity-85",
619
- children: /* @__PURE__ */ t(Ye, { size: 13, fill: "currentColor" })
620
- }
621
- ) : /* @__PURE__ */ t(
622
- "button",
623
- {
624
- type: "button",
625
- onClick: () => {
626
- G();
627
- },
628
- disabled: !ce,
629
- "aria-label": c ? "Steer the turn in progress" : "Send",
630
- title: c ? "Steer the turn in progress (Enter)" : "Send (Enter)",
631
- className: "mb-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent text-on-accent transition-opacity hover:bg-accent-hover disabled:opacity-35",
632
- children: /* @__PURE__ */ t(Xe, { size: 18 })
633
- }
634
- )
635
- ] }),
636
- de && /* @__PURE__ */ t("div", { className: "px-1.5 pt-1", children: /* @__PURE__ */ t(de, { conversationId: e.id }) })
637
- ]
638
- }
639
- )
640
- ] });
641
- }
642
- const tn = 1e4, nn = 6e4, sn = {
643
- queued: "queued",
644
- thinking: "thinking",
645
- writing: "writing",
646
- tool: "running",
647
- compacting: "compacting context",
648
- retrying: "retrying"
649
- };
650
- function an({ controller: e }) {
651
- O(e, D.run, D.pause, D.connection, P.followUps);
652
- const n = e.store.state, [, r] = S(0), i = n.connection === "reconnecting";
653
- if (M(() => {
654
- if (!n.run && !i) return;
655
- const o = setInterval(() => r((a) => a + 1), 1e3);
656
- return () => clearInterval(o);
657
- }, [n.run, i]), i) {
658
- const o = n.reconnectingSince ? Date.now() - n.reconnectingSince : 0, a = o >= tn ? ` for ${xe(o)}` : "";
659
- return /* @__PURE__ */ g("output", { className: R("flex items-center gap-1.5 text-[12px]", o >= nn ? "text-danger" : "text-warn"), children: [
660
- /* @__PURE__ */ t(Ze, { size: 12, className: "animate-spin" }),
661
- " Reconnecting",
662
- a,
663
- n.connectionDetail ? ` (${n.connectionDetail})` : "…"
664
- ] });
665
- }
666
- if (n.run) {
667
- const a = [n.run.activity === "tool" && n.run.toolName ? `running ${n.run.toolName}` : sn[n.run.activity]];
668
- return n.run.step !== null && a.push(`step ${n.run.step + 1}`), a.push(xe(Date.now() - n.run.startedAt) ?? "0s"), e.followUps.length && a.push(`${e.followUps.length} queued`), /* @__PURE__ */ g("output", { className: "flex items-center gap-1.5 text-[12px] text-accent", children: [
669
- /* @__PURE__ */ t(et, { size: 12, className: "animate-spin" }),
670
- " ",
671
- a.join(" · ")
672
- ] });
673
- }
674
- if (n.pause && n.pause.kind !== "fork_seed" && e.deferredPauseId === n.pause.pending_tool_call_id) return null;
675
- if (n.pause && n.pause.kind !== "fork_seed") {
676
- const o = n.pause.task_id ? `${n.pause.task_id}: ` : "";
677
- return /* @__PURE__ */ g("output", { className: "flex items-center gap-1.5 text-[12px] text-warn", children: [
678
- /* @__PURE__ */ t(tt, { size: 12 }),
679
- " ",
680
- o,
681
- _t(n.pause)
682
- ] });
683
- }
684
- const m = e.fleetParent();
685
- return m ? /* @__PURE__ */ g("div", { className: "text-[12px] text-faint", children: [
686
- "Fleet worker · read-only · typing steers ",
687
- m.taskId,
688
- " through its fleet"
689
- ] }) : null;
690
- }
691
- const Z = "ecui.session.inspector", Se = "ecui.session.tab";
692
- function De(e, n) {
693
- try {
694
- return localStorage.getItem(e) ?? n;
695
- } catch {
696
- return n;
697
- }
698
- }
699
- function ee(e, n) {
700
- try {
701
- localStorage.setItem(e, n);
702
- } catch {
703
- }
704
- }
705
- function rn({ activeId: e }) {
706
- Me();
707
- const n = se(), r = A.attached().filter((i) => i.started || i.id === e);
708
- return r.length < 2 ? null : /* @__PURE__ */ t("nav", { className: "flex h-9 shrink-0 items-end gap-0.5 overflow-x-auto border-b border-line bg-surface-alt px-2", "aria-label": "Open sessions", children: r.map((i) => {
709
- const m = Mt(i.store.state, { key: i.id, agent: i.agent?.name ?? null, attention: null, draft: "", createdAt: i.createdAt }), o = i.id === e;
710
- return /* @__PURE__ */ g(
711
- "div",
712
- {
713
- className: R(
714
- "group flex h-8 max-w-[14rem] shrink-0 items-center gap-1.5 rounded-t-md border border-b-0 pr-1 pl-2.5 text-[12.5px]",
715
- o ? "border-line bg-bg font-semibold text-ink" : "border-transparent text-muted hover:bg-surface-hover hover:text-ink"
716
- ),
717
- children: [
718
- /* @__PURE__ */ g("button", { type: "button", className: "flex min-w-0 items-center gap-1.5", "aria-current": o ? "page" : void 0, onClick: () => n(J(i.id)), children: [
719
- /* @__PURE__ */ t(Tt, { row: m }),
720
- /* @__PURE__ */ t("span", { className: "truncate", children: i.title() })
721
- ] }),
722
- /* @__PURE__ */ t(
723
- "button",
724
- {
725
- type: "button",
726
- "aria-label": `Stop following ${i.title()}`,
727
- onClick: () => {
728
- if (A.detach(i.id), o) {
729
- const a = A.attached().find((c) => c.started);
730
- n(a ? J(a.id) : $t());
731
- }
732
- },
733
- className: "flex h-5 w-5 shrink-0 items-center justify-center rounded text-faint opacity-0 group-hover:opacity-100 hover:bg-surface-hover hover:text-ink focus:opacity-100 max-md:opacity-100",
734
- children: /* @__PURE__ */ t(Ee, { size: 12 })
735
- }
736
- )
737
- ]
738
- },
739
- i.id
740
- );
741
- }) });
742
- }
743
- function on({ controller: e }) {
744
- O(e, D.session, P.list);
745
- const [n, r] = S(!1), [i, m] = S(""), o = z(null), a = e.title();
746
- return n ? /* @__PURE__ */ t(
747
- "input",
748
- {
749
- ref: o,
750
- autoFocus: !0,
751
- value: i,
752
- onChange: (c) => m(c.target.value),
753
- onBlur: () => {
754
- r(!1), i.trim() && i.trim() !== a && e.setTitle(i.trim());
755
- },
756
- onKeyDown: (c) => {
757
- c.key === "Enter" && c.target.blur(), c.key === "Escape" && r(!1);
758
- },
759
- "aria-label": "Session title",
760
- className: "h-7 min-w-0 flex-1 rounded-md border border-accent bg-surface px-2 text-[13.5px] font-semibold text-ink outline-none"
761
- }
762
- ) : /* @__PURE__ */ t("h1", { className: "min-w-[6rem] flex-1 truncate text-[13.5px] font-semibold text-ink", children: /* @__PURE__ */ t(
763
- "button",
764
- {
765
- type: "button",
766
- disabled: !e.started,
767
- onClick: () => {
768
- m(a), r(!0);
769
- },
770
- className: "max-w-full truncate rounded px-1 text-left hover:bg-surface-hover disabled:hover:bg-transparent",
771
- title: e.started ? "Rename" : void 0,
772
- children: a
773
- }
774
- ) });
775
- }
776
- function cn({ controller: e }) {
777
- O(e, D.reset, D.session, P.list, P.draft);
778
- const n = se(), { toast: r } = Ae(), [i, m] = S(() => De(Z, "1") === "1"), [o, a] = S(!1), [c, d] = S(() => De(Se, "brief")), l = $e(e), f = H((h) => {
779
- d(h), ee(Se, h);
780
- }, []), x = z(null), k = H((h) => {
781
- x.current = h;
782
- }, []), p = B(
783
- () => ({ navigate: (h) => n(h), toast: r, openDialog: Pt }),
784
- [n, r]
785
- ), b = H(
786
- async (h) => {
787
- const T = h.key.slice(2);
788
- try {
789
- const v = await Rt.forkSession(e.id, { before_message: T, title: e.session?.title ?? null });
790
- A.attach(v.id).seedDraft(h.text), r("Editing in a copy of the session from before that message. The original is kept.", "info"), n(J(v.id));
791
- } catch (v) {
792
- r(`Couldn't edit: ${zt(v)}`, "danger");
793
- }
794
- },
795
- [e, n, r]
796
- );
797
- M(() => {
798
- const h = (v) => {
799
- f(String(v.detail)), window.matchMedia("(min-width: 1280px)").matches ? (m(!0), ee(Z, "1")) : a(!0);
800
- }, T = () => y();
801
- return window.addEventListener("ecui:inspector", h), window.addEventListener("ecui:toggle-inspector", T), () => {
802
- window.removeEventListener("ecui:inspector", h), window.removeEventListener("ecui:toggle-inspector", T);
803
- };
804
- });
805
- const y = () => {
806
- window.matchMedia("(min-width: 1280px)").matches ? m((h) => (ee(Z, h ? "0" : "1"), !h)) : a(!0);
807
- }, C = e.store.state.entries, F = !e.loading && C.length === 0 && !e.running(), w = l.length > 0;
808
- return /* @__PURE__ */ g("div", { className: "flex min-h-0 flex-1", children: [
809
- /* @__PURE__ */ g("section", { className: "flex min-w-0 flex-1 flex-col bg-bg", children: [
810
- /* @__PURE__ */ g("div", { className: "flex h-11 shrink-0 items-center gap-1.5 border-b border-line bg-surface px-2 sm:px-3", children: [
811
- /* @__PURE__ */ t(on, { controller: e }),
812
- /* @__PURE__ */ t("div", { className: "hidden min-w-0 md:block", children: /* @__PURE__ */ t(be, { controller: e }) }),
813
- /* @__PURE__ */ t(Ft, { controller: e }),
814
- w && /* @__PURE__ */ g(ne, { label: i ? "Hide panels" : "Show panels", onClick: y, children: [
815
- i ? /* @__PURE__ */ t(nt, { size: 17, className: "max-xl:hidden" }) : null,
816
- /* @__PURE__ */ t(st, { size: 17, className: R(i && "xl:hidden") })
817
- ] })
818
- ] }),
819
- /* @__PURE__ */ t("div", { className: "flex shrink-0 items-center border-b border-line bg-surface px-2 py-1 md:hidden", children: /* @__PURE__ */ t(be, { controller: e }) }),
820
- e.loading && !C.length ? /* @__PURE__ */ t(Te, {}) : F ? /* @__PURE__ */ t(Ot, { onPick: (h) => {
821
- e.submit(h);
822
- } }) : /* @__PURE__ */ t(Bt, { controller: e, onEdit: e.isWorker() ? void 0 : (h) => {
823
- b(h);
824
- }, renderDiff: ye.renderDiff }),
825
- /* @__PURE__ */ t("div", { className: "shrink-0 px-3 pb-[max(0.75rem,env(safe-area-inset-bottom))] sm:px-6 sm:pb-4", children: /* @__PURE__ */ g("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-2", children: [
826
- /* @__PURE__ */ t(Lt, { controller: e, collisions: ye.collisions }),
827
- /* @__PURE__ */ t(an, { controller: e }),
828
- /* @__PURE__ */ t(en, { controller: e, commandContext: p, autoFocus: !0, registerHandle: k })
829
- ] }) })
830
- ] }),
831
- w && i && /* @__PURE__ */ t("aside", { className: "hidden w-[22rem] shrink-0 border-l border-line bg-surface xl:flex", "aria-label": "Session panels", children: /* @__PURE__ */ t(ke, { controller: e, tab: c, onTab: f, className: "w-full" }) }),
832
- /* @__PURE__ */ t(Kt, { open: o, onClose: () => a(!1), title: "Session", side: "right", widthClass: "w-[min(24rem,100vw)]", children: /* @__PURE__ */ t(ke, { controller: e, tab: c, onTab: f, className: "h-full" }) })
833
- ] });
834
- }
835
- function hn() {
836
- const { sessionId: e } = je(), [n] = qe(), r = se();
837
- Me();
838
- const i = X((f) => f.agents), m = X((f) => f.features), o = X((f) => f.status === "ready" || f.status === "error"), a = Ct(i, m), c = e === "new" && o && a.length === 0;
839
- M(() => {
840
- if (e !== "new" || !o || a.length === 0) return;
841
- const f = n.get("agent"), x = a.find((b) => b.name === f) ?? a.find((b) => b.name === "chat") ?? a[0] ?? null, k = n.get("workspace"), p = A.create({
842
- agent: x,
843
- model: n.get("model"),
844
- permissionMode: n.get("mode"),
845
- workspace: k ? { path: k, worktree: n.get("worktree") !== "0" } : null
846
- });
847
- r(J(p.id), { replace: !0 });
848
- }, [e, o]);
849
- const d = Et(e && e !== "new" ? e : null), l = !!d?.started;
850
- return M(() => {
851
- l && d?.loadExtras();
852
- }, [d, l]), M(() => {
853
- if (!(!e || e === "new"))
854
- return A.get(e) || A.attach(e), A.show(e), () => {
855
- A.activeId === e && A.show(null);
856
- };
857
- }, [e]), c ? /* @__PURE__ */ t(we, { icon: /* @__PURE__ */ t(pe, { size: 20 }), title: "No agent to start a session with here", children: "Sessions here start from elsewhere in the app." }) : !d || e === "new" ? /* @__PURE__ */ t(Te, {}) : d.missing ? /* @__PURE__ */ t(
858
- we,
859
- {
860
- icon: /* @__PURE__ */ t(pe, { size: 20 }),
861
- title: "Session not found",
862
- action: a.length > 0 ? /* @__PURE__ */ t(
863
- It,
864
- {
865
- variant: "primary",
866
- onClick: () => {
867
- A.detach(d.id), r(At());
868
- },
869
- children: "Start a new session"
870
- }
871
- ) : void 0,
872
- children: "It may have been deleted, or it belongs to another account."
873
- }
874
- ) : /* @__PURE__ */ g("div", { className: "flex h-full min-h-0 flex-col", children: [
875
- /* @__PURE__ */ t(rn, { activeId: d.id }),
876
- /* @__PURE__ */ t(cn, { controller: d }, d.id)
877
- ] });
878
- }
879
- export {
880
- hn as default
881
- };