@volter-ai-dev/supercode-ui 0.1.17 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/embed.mjs CHANGED
@@ -119,6 +119,12 @@ function sourceString(source, keys) {
119
119
  const match = new RegExp(`(?:^|[,{\\s])["']?(?:${names})["']?\\s*:\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
120
120
  return decodedLiteral(match?.[1]);
121
121
  }
122
+ function assignedString(source, keys) {
123
+ if (!source) return "";
124
+ const names = keys.join("|");
125
+ const match = new RegExp(`\\b(?:${names})\\s*=\\s*("(?:\\\\.|[^"\\\\])*"|'(?:\\\\.|[^'\\\\])*'|\`(?:\\\\.|[^\`\\\\])*\`)`).exec(source);
126
+ return decodedLiteral(match?.[1]);
127
+ }
122
128
  function callArgumentSource(source, open) {
123
129
  let depth = 1;
124
130
  let quote = "";
@@ -260,6 +266,13 @@ function planItems(args) {
260
266
  return [{ label: boundedString(label, 300), status: firstString(value, ["status"]) }];
261
267
  }).slice(0, 12);
262
268
  }
269
+ function agentItems(name, resultText) {
270
+ if (!/list.?agents/i.test(name)) return [];
271
+ return (resultText ?? "").split("\n").flatMap((line) => {
272
+ const parts = line.trim().split(/\s+·\s+/).filter(Boolean);
273
+ return parts.length > 1 ? [{ label: boundedString(parts[0], 120), status: boundedString(parts.slice(1).join(" \xB7 "), 180) }] : [];
274
+ }).slice(0, 12);
275
+ }
263
276
  function editPreview(args, resultText, source) {
264
277
  const direct = firstString(args, ["patch", "diff"]);
265
278
  if (direct) return direct;
@@ -277,7 +290,19 @@ function editPreview(args, resultText, source) {
277
290
  }
278
291
  function toolResultEnvelope(resultText) {
279
292
  const match = /^Script (?:completed|failed)\r?\nWall time ([0-9.]+) seconds\r?\nOutput:\r?\n([\s\S]*)$/.exec(resultText ?? "");
280
- if (!match) return { preview: resultText ?? "", value: null, durationMs: null };
293
+ if (!match) {
294
+ try {
295
+ const value = JSON.parse(resultText ?? "");
296
+ const object = record(value);
297
+ return {
298
+ preview: typeof value === "string" ? value : firstString(object, ["output", "message", "text", "summary", "result"]) || resultText || "",
299
+ value: object,
300
+ durationMs: null
301
+ };
302
+ } catch {
303
+ return { preview: resultText ?? "", value: null, durationMs: null };
304
+ }
305
+ }
281
306
  const durationMs = Number(match[1]) * 1e3;
282
307
  try {
283
308
  const value = record(JSON.parse(match[2]));
@@ -290,6 +315,15 @@ function toolResultEnvelope(resultText) {
290
315
  return { preview: match[2], value: null, durationMs: Number.isFinite(durationMs) ? durationMs : null };
291
316
  }
292
317
  }
318
+ function semanticAgentPreview(name, status, outcome) {
319
+ const normalized = name.toLocaleLowerCase();
320
+ if (status === "error") return outcome.preview;
321
+ if (/^(?:agent|task)$|spawn.?agent/.test(normalized) && outcome.preview) return "Agent is working in the background.";
322
+ if (/send.?message|followup.?task/.test(normalized) && outcome.preview) {
323
+ return /resumed from transcript|resumedAgentId/i.test(outcome.preview) ? "Agent resumed in the background." : "Message delivered.";
324
+ }
325
+ return outcome.preview;
326
+ }
293
327
  function verificationCommand(command) {
294
328
  let shell = "";
295
329
  let quote = "";
@@ -322,12 +356,13 @@ function verificationCommand(command) {
322
356
  function classifyTool(name, command) {
323
357
  const normalized = name.toLocaleLowerCase();
324
358
  if (/write_stdin|^wait$/.test(normalized)) return "command";
325
- if (/update.?plan|todo|checklist|taskcreate|taskupdate/.test(normalized)) return "plan";
359
+ if (/update.?plan|todo|checklist|taskcreate|taskupdate|create.?goal|update.?goal/.test(normalized)) return "plan";
326
360
  if (/search.?replace|edit|write|patch|replace|create_file|apply_patch/.test(normalized)) return "edit";
327
361
  if (/read|view|open_file|list_dir/.test(normalized)) return "read";
362
+ if (/web.?search|web.?fetch|fetch.?url/.test(normalized)) return "web";
328
363
  if (/search|find|grep|glob|toolsearch/.test(normalized)) return "search";
329
364
  if (/browser|web|fetch|url/.test(normalized)) return "web";
330
- if (/agent|subagent|sendmessage|delegate|^task$/.test(normalized)) return "agent";
365
+ if (/agent|subagent|send.?message|delegate|followup.?task|taskstop|taskoutput|^task$/.test(normalized)) return "agent";
331
366
  if (/test|typecheck|lint|build/.test(normalized)) return "test";
332
367
  if (/terminal|bash|shell|command|exec|write_stdin|^wait$/.test(normalized)) return verificationCommand(command) ? "test" : "command";
333
368
  return "other";
@@ -336,9 +371,17 @@ function toolAction(status, category, name, tools) {
336
371
  const position = status === "pending" ? 0 : status === "error" ? 2 : 1;
337
372
  if (tools.length > 1) return [`Running ${tools.length} actions`, `Ran ${tools.length} actions`, `${tools.length} actions failed`][position];
338
373
  const normalized = name.toLocaleLowerCase();
339
- if (/sendmessage/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
340
- if (/kill_command_or_subagent/.test(normalized)) return ["Stopping", "Stopped", "Stop failed"][position];
374
+ if (/send.?message|followup.?task/.test(normalized)) return ["Messaging agent", "Messaged agent", "Agent message failed"][position];
375
+ if (/taskstop|interrupt.?agent|kill_command_or_subagent/.test(normalized)) return ["Stopping agent", "Stopped agent", "Stop failed"][position];
376
+ if (/list.?agents|taskoutput|wait.?agent/.test(normalized)) return ["Checking agents", "Checked agents", "Agent check failed"][position];
341
377
  if (/get_command_or_subagent_output|write_stdin|^wait$/.test(normalized)) return ["Waiting for", "Checked", "Check failed"][position];
378
+ if (/web.?search/.test(normalized)) return ["Searching web", "Searched web", "Web search failed"][position];
379
+ if (/web.?fetch|fetch.?url/.test(normalized)) return ["Fetching page", "Fetched page", "Page fetch failed"][position];
380
+ if (/^skill$|use.?skill|load.?skill/.test(normalized)) return ["Loading skill", "Loaded skill", "Skill load failed"][position];
381
+ if (/taskcreate/.test(normalized)) return ["Adding task", "Added task", "Task creation failed"][position];
382
+ if (/taskupdate/.test(normalized)) return ["Updating task", "Updated task", "Task update failed"][position];
383
+ if (/create.?goal/.test(normalized)) return ["Creating goal", "Created goal", "Goal creation failed"][position];
384
+ if (/update.?goal/.test(normalized)) return ["Updating goal", "Updated goal", "Goal update failed"][position];
342
385
  const actions = {
343
386
  read: ["Reading", "Read", "Read failed"],
344
387
  search: ["Searching", "Searched", "Search failed"],
@@ -355,18 +398,21 @@ function createToolPresentation(entry) {
355
398
  const envelope = toolEnvelope(entry);
356
399
  const args = envelope.args;
357
400
  const outcome = toolResultEnvelope(entry.resultText);
401
+ const patchSource = assignedString(envelope.source, ["patch"]) || envelope.source;
358
402
  const command = firstString(args, ["command", "cmd"]) || sourceString(envelope.callSource, ["command", "cmd"]);
359
403
  const category = classifyTool(envelope.name, command || envelope.source || entry.arguments || "");
360
- const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(envelope.source);
404
+ const path = firstString(args, ["file_path", "target_file", "target_directory", "path"]) || sourceString(envelope.callSource, ["file_path", "target_file", "target_directory", "path"]) || patchPath(patchSource);
361
405
  const query = firstString(args, ["query", "pattern"]) || sourceString(envelope.callSource, ["query", "pattern", "q"]);
362
406
  const url = firstString(args, ["url"]) || sourceString(envelope.callSource, ["url", "ref_id"]);
363
- const subject = firstString(args, ["subject", "description", "summary", "task", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "prompt"]);
407
+ const subject = firstString(args, ["subject", "description", "summary", "task", "objective", "prompt"]) || sourceString(envelope.callSource, ["subject", "description", "summary", "task", "objective", "prompt"]);
408
+ const agentTarget = category === "agent" ? firstString(record(outcome.value), ["command", "name"]) || firstString(args, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) || sourceString(envelope.callSource, ["target", "task_name", "taskId", "task_id", "agentId", "agent_id", "resume", "team_name"]) : "";
409
+ const skillTarget = /^skill$|use.?skill|load.?skill/i.test(envelope.name) ? firstString(args, ["skill", "name"]) || sourceString(envelope.callSource, ["skill", "name"]) : "";
364
410
  const background = /get_command_or_subagent_output|kill_command_or_subagent/i.test(envelope.name) ? "background task" : /write_stdin|^wait$/i.test(envelope.name) ? "background command" : "";
365
- const items = planItems(args);
411
+ const items = category === "agent" ? agentItems(envelope.name, outcome.preview) : planItems(args);
366
412
  const taskId = firstString(args, ["taskId", "task_id"]);
367
413
  const planTarget = category === "plan" ? items.length ? `${items.length} ${items.length === 1 ? "item" : "items"}` : taskId ? `task ${taskId}` : "" : "";
368
- const target = path || command || query || url || subject || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
369
- const previewSource = category === "edit" ? editPreview(args, outcome.preview, envelope.source) : outcome.preview;
414
+ const target = path || command || query || url || subject || agentTarget || skillTarget || background || planTarget || (envelope.tools.length > 1 ? `${envelope.tools.length} coordinated actions` : toolTarget(entry.arguments));
415
+ const previewSource = category === "edit" ? editPreview(args, outcome.preview, patchSource) : category === "agent" ? semanticAgentPreview(envelope.name, entry.status ?? "completed", outcome) : outcome.preview;
370
416
  const result = record(entry.resultContent);
371
417
  const metadata = record(entry.metadata);
372
418
  const resultMetadata = record(result?.metadata);
@@ -638,7 +684,7 @@ function sessionActivity(state, row) {
638
684
  function filterSessions(rows, query) {
639
685
  const needle = query.trim().toLocaleLowerCase();
640
686
  if (!needle) return [...rows];
641
- return rows.filter((row) => [row.name, row.title, row.cwd, row.harness, harnessDisplayName(row.harness)].some((value) => value.toLocaleLowerCase().includes(needle)));
687
+ return rows.filter((row) => [row.name, row.title, row.preview, row.cwd, row.harness, harnessDisplayName(row.harness)].some((value) => typeof value === "string" && value.toLocaleLowerCase().includes(needle)));
642
688
  }
643
689
  function groupConversation(entries) {
644
690
  const blocks = [];
@@ -718,6 +764,7 @@ function boundedSet(map, key, value) {
718
764
  // src/icon.jsx
719
765
  import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
720
766
  var ICONS = {
767
+ attach: () => /* @__PURE__ */ jsx("path", { d: "M6.25 9.75 10.6 5.4a2.1 2.1 0 0 1 2.97 2.97l-5.4 5.4a3.3 3.3 0 0 1-4.67-4.66l5.52-5.52" }),
721
768
  back: () => /* @__PURE__ */ jsx("path", { d: "m11.5 4.5-4.5 4.5 4.5 4.5" }),
722
769
  check: () => /* @__PURE__ */ jsx("path", { d: "m4 9 3.25 3.25L14 5.5" }),
723
770
  chevron: () => /* @__PURE__ */ jsx("path", { d: "m7 4.5 4.5 4.5L7 13.5" }),
@@ -758,6 +805,44 @@ function UiIcon({ name, size = 16, class: className = "" }) {
758
805
  return /* @__PURE__ */ jsx("svg", { class: `scui-icon ${className}`, style: { "--scui-icon-size": `${size}px` }, viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Glyph, {}) });
759
806
  }
760
807
 
808
+ // src/context.jsx
809
+ import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
810
+ var MAX_CONTEXT_ITEMS = 32;
811
+ function normalizeContext(value) {
812
+ return (Array.isArray(value) ? value : value ? [value] : []).flatMap((item) => {
813
+ if (!item || typeof item.label !== "string" || typeof item.detail !== "string") return [];
814
+ const label = item.label.trim().slice(0, 200);
815
+ const detail = item.detail.slice(0, 2e4);
816
+ if (!label || !detail) return [];
817
+ return [{
818
+ ...typeof item.id === "string" && item.id ? { id: item.id.slice(0, 2e3) } : {},
819
+ ...typeof item.kind === "string" && item.kind ? { kind: item.kind.slice(0, 100) } : {},
820
+ label,
821
+ detail
822
+ }];
823
+ }).slice(0, MAX_CONTEXT_ITEMS);
824
+ }
825
+ function mergeContext(current, picked) {
826
+ const next = [...current];
827
+ const seen = new Set(current.map((item) => item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`));
828
+ for (const item of normalizeContext(picked)) {
829
+ const key = item.id ? `id:${item.id}` : `value:${item.kind ?? ""}\0${item.label}\0${item.detail}`;
830
+ if (seen.has(key)) continue;
831
+ seen.add(key);
832
+ next.push(item);
833
+ if (next.length === MAX_CONTEXT_ITEMS) break;
834
+ }
835
+ return next;
836
+ }
837
+ function ContextTray({ items, onRemove }) {
838
+ if (!items.length) return null;
839
+ return /* @__PURE__ */ jsx2("div", { class: "scui-compose-context", "aria-label": "Attached context", children: items.map((item, index) => /* @__PURE__ */ jsxs2("span", { children: [
840
+ /* @__PURE__ */ jsx2(UiIcon, { name: "attach", size: 12 }),
841
+ /* @__PURE__ */ jsx2("strong", { children: item.label }),
842
+ /* @__PURE__ */ jsx2("button", { type: "button", "aria-label": `Remove context ${item.label}`, onClick: () => onRemove(index), children: /* @__PURE__ */ jsx2(UiIcon, { name: "close", size: 12 }) })
843
+ ] }, item.id ?? `${item.label}:${index}`)) });
844
+ }
845
+
761
846
  // src/textarea.js
762
847
  import { useLayoutEffect } from "preact/hooks";
763
848
  function useAutosizeTextarea(ref, value) {
@@ -773,7 +858,7 @@ function useAutosizeTextarea(ref, value) {
773
858
  }
774
859
 
775
860
  // src/composer.jsx
776
- import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
861
+ import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
777
862
  var composerMemory = /* @__PURE__ */ new Map();
778
863
  function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
779
864
  if (state.mode !== "mirror" || state.canSend) return null;
@@ -783,29 +868,32 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
783
868
  const resume = canContinueHere(state);
784
869
  const join = state.canAttach;
785
870
  const branch = state.canBranch;
786
- if (!resume && !join && !branch) return /* @__PURE__ */ jsx2("div", { class: "scui-continuation", children: /* @__PURE__ */ jsxs2("span", { children: [
787
- /* @__PURE__ */ jsx2("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
788
- /* @__PURE__ */ jsx2("small", { children: "This session cannot be continued by an available harness." })
871
+ if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { class: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
872
+ /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
873
+ /* @__PURE__ */ jsx3("small", { children: "This session cannot be continued by an available harness." })
789
874
  ] }) });
790
- return /* @__PURE__ */ jsxs2("div", { class: "scui-continuation", children: [
791
- /* @__PURE__ */ jsxs2("span", { children: [
792
- /* @__PURE__ */ jsx2("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
793
- /* @__PURE__ */ jsx2("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
875
+ return /* @__PURE__ */ jsxs3("div", { class: "scui-continuation", children: [
876
+ /* @__PURE__ */ jsxs3("span", { children: [
877
+ /* @__PURE__ */ jsx3("strong", { children: activeElsewhere ? "Active elsewhere" : "Read-only" }),
878
+ /* @__PURE__ */ jsx3("small", { children: join ? "Join the proven live runtime without taking it over." : resume ? `Resume this ${harnessDisplayName(state.harness)} session here.` : "Start an independent continuation." })
794
879
  ] }),
795
- /* @__PURE__ */ jsx2("button", { type: "button", disabled: Boolean(state.operation), onClick: () => adapter.onIntent(join ? { action: "join" } : resume ? { action: "resume" } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
880
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => adapter.onIntent(join ? { action: "join" } : resume ? { action: "resume" } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
796
881
  ] });
797
882
  }
798
883
  function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`, pendingStatus = null, restoreDraft = null, onPending, onDraftRestored }) {
799
- const remembered = composerMemory.get(memoryKey) ?? { draft: state.savedDraft, queue: [] };
884
+ const remembered = composerMemory.get(memoryKey) ?? { draft: state.savedDraft, context: [], queue: [] };
800
885
  const [draft, setDraft] = useState(remembered.draft);
886
+ const [context, setContext] = useState(remembered.context);
801
887
  const [queue, setQueue] = useState(remembered.queue);
802
888
  const [dispatching, setDispatching] = useState(false);
889
+ const [picking, setPicking] = useState(false);
890
+ const [pickerError, setPickerError] = useState(null);
803
891
  const textarea = useRef(null);
804
892
  useAutosizeTextarea(textarea, draft);
805
- const remember = (nextDraft, nextQueue) => boundedSet(composerMemory, memoryKey, { draft: nextDraft, queue: nextQueue });
893
+ const remember = (nextDraft, nextContext, nextQueue) => boundedSet(composerMemory, memoryKey, { draft: nextDraft, context: nextContext, queue: nextQueue });
806
894
  const updateQueue = (update) => setQueue((items) => {
807
895
  const next = update(items);
808
- remember(draft, next);
896
+ remember(draft, context, next);
809
897
  return next;
810
898
  });
811
899
  const queueBlocked = state.busy || pendingStatus !== null || dispatching;
@@ -815,9 +903,9 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
815
903
  const [next, ...rest] = queue;
816
904
  setDispatching(true);
817
905
  setQueue(rest);
818
- remember(draft, rest);
819
- onPending?.(next);
820
- adapter.onIntent({ action: "send", text: next });
906
+ remember(draft, context, rest);
907
+ onPending?.(next.text, next.context);
908
+ adapter.onIntent({ action: "send", text: next.text, ...next.context.length ? { context: next.context } : {} });
821
909
  }
822
910
  }, [adapter, draft, memoryKey, onPending, queue, queueBlocked, state.canSend]);
823
911
  useEffect(() => {
@@ -829,7 +917,9 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
829
917
  useEffect(() => {
830
918
  if (!restoreDraft) return;
831
919
  setDraft(restoreDraft.text);
832
- remember(restoreDraft.text, queue);
920
+ const restoredContext = normalizeContext(restoreDraft.context);
921
+ setContext(restoredContext);
922
+ remember(restoreDraft.text, restoredContext, queue);
833
923
  textarea.current?.focus({ preventScroll: true });
834
924
  onDraftRestored?.(restoreDraft.id);
835
925
  }, [onDraftRestored, restoreDraft?.id]);
@@ -837,43 +927,70 @@ function Composer({ state, adapter, labels = DEFAULT_LABELS, memoryKey = state.a
837
927
  const timer = setTimeout(() => adapter.onIntent({ action: "draft", text: draft }), 250);
838
928
  return () => clearTimeout(timer);
839
929
  }, [adapter, draft]);
930
+ const pickContext = () => {
931
+ if (!adapter.pickContext || state.mode !== "control" || picking || context.length >= MAX_CONTEXT_ITEMS) return;
932
+ setPicking(true);
933
+ setPickerError(null);
934
+ Promise.resolve().then(() => adapter.pickContext()).then((picked) => {
935
+ setContext((current) => {
936
+ const next = mergeContext(current, picked);
937
+ remember(draft, next, queue);
938
+ return next;
939
+ });
940
+ }, (error) => setPickerError(error instanceof Error ? error.message : "Could not attach context.")).finally(() => setPicking(false));
941
+ };
840
942
  const send = () => {
841
943
  const text = draft.trim();
842
944
  if (!text) return;
843
- if (queuesNewMessage) updateQueue((items) => [...items, text]);
945
+ const message = { text, context };
946
+ if (queuesNewMessage) updateQueue((items) => [...items, message]);
844
947
  else if (state.canSend) {
845
948
  if (onPending) setDispatching(true);
846
- onPending?.(text);
847
- adapter.onIntent({ action: "send", text });
949
+ onPending?.(text, context);
950
+ adapter.onIntent({ action: "send", text, ...context.length ? { context } : {} });
848
951
  } else return;
849
952
  setDraft("");
850
- remember("", queuesNewMessage ? [...queue, text] : queue);
953
+ setContext([]);
954
+ remember("", [], queuesNewMessage ? [...queue, message] : queue);
851
955
  };
852
- return /* @__PURE__ */ jsxs2("div", { class: "scui-compose", children: [
853
- queue.length ? /* @__PURE__ */ jsxs2("div", { class: "scui-queue", children: [
854
- /* @__PURE__ */ jsxs2("strong", { children: [
956
+ return /* @__PURE__ */ jsxs3("div", { class: "scui-compose", children: [
957
+ queue.length ? /* @__PURE__ */ jsxs3("div", { class: "scui-queue", children: [
958
+ /* @__PURE__ */ jsxs3("strong", { children: [
855
959
  queue.length,
856
960
  " queued"
857
961
  ] }),
858
- queue.map((item, index) => /* @__PURE__ */ jsxs2("span", { children: [
859
- item,
860
- /* @__PURE__ */ jsx2("button", { type: "button", "aria-label": `Remove queued message ${index + 1}`, onClick: () => updateQueue((items) => items.filter((_, itemIndex) => itemIndex !== index)), children: /* @__PURE__ */ jsx2(UiIcon, { name: "close", size: 13 }) })
861
- ] }, `${index}:${item}`))
962
+ queue.map((item, index) => /* @__PURE__ */ jsxs3("span", { children: [
963
+ /* @__PURE__ */ jsxs3("span", { children: [
964
+ item.text,
965
+ item.context.length ? /* @__PURE__ */ jsxs3("small", { children: [
966
+ item.context.length,
967
+ " attached"
968
+ ] }) : null
969
+ ] }),
970
+ /* @__PURE__ */ jsx3("button", { type: "button", "aria-label": `Remove queued message ${index + 1}`, onClick: () => updateQueue((items) => items.filter((_, itemIndex) => itemIndex !== index)), children: /* @__PURE__ */ jsx3(UiIcon, { name: "close", size: 13 }) })
971
+ ] }, `${index}:${item.text}`))
862
972
  ] }) : null,
863
- /* @__PURE__ */ jsxs2("div", { class: "scui-envelope", children: [
864
- /* @__PURE__ */ jsx2("textarea", { ref: textarea, rows: 1, "aria-label": `Message ${harnessDisplayName(state.harness) || "agent"}`, placeholder: state.startup !== "ready" ? "Connecting\u2026" : pendingStatus === "failed" ? "Retry or edit the unsent message\u2026" : pendingStatus === "editing" ? "Edit and resend\u2026" : queueBlocked ? "Queue a follow-up\u2026" : labels.askAgent, value: draft, disabled: state.mode !== "control" && !state.canSend, onInput: (event) => {
973
+ /* @__PURE__ */ jsx3(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
974
+ const next = items.filter((_, itemIndex) => itemIndex !== index);
975
+ remember(draft, next, queue);
976
+ return next;
977
+ }) }),
978
+ pickerError ? /* @__PURE__ */ jsx3("small", { class: "scui-context-error", role: "alert", children: pickerError }) : null,
979
+ /* @__PURE__ */ jsxs3("div", { class: "scui-envelope", children: [
980
+ adapter.pickContext && state.mode === "control" ? /* @__PURE__ */ jsx3("button", { class: "scui-attach", type: "button", "aria-label": "Attach context", disabled: picking || context.length >= MAX_CONTEXT_ITEMS, onClick: pickContext, children: picking ? /* @__PURE__ */ jsx3("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx3(UiIcon, { name: "attach", size: 17 }) }) : null,
981
+ /* @__PURE__ */ jsx3("textarea", { ref: textarea, rows: 1, "aria-label": `Message ${harnessDisplayName(state.harness) || "agent"}`, placeholder: state.startup !== "ready" ? "Connecting\u2026" : pendingStatus === "failed" ? "Retry or edit the unsent message\u2026" : pendingStatus === "editing" ? "Edit and resend\u2026" : queueBlocked ? "Queue a follow-up\u2026" : labels.askAgent, value: draft, disabled: state.mode !== "control" && !state.canSend, onInput: (event) => {
865
982
  const value = event.currentTarget.value;
866
983
  setDraft(value);
867
- remember(value, queue);
984
+ remember(value, context, queue);
868
985
  }, onKeyDown: (event) => {
869
986
  if (isSendKey(event)) {
870
987
  event.preventDefault();
871
988
  send();
872
989
  }
873
990
  } }),
874
- /* @__PURE__ */ jsxs2("span", { children: [
875
- state.busy ? /* @__PURE__ */ jsx2("button", { class: "scui-stop", type: "button", "aria-label": "Stop agent", disabled: !state.canInterrupt, onClick: () => adapter.onIntent({ action: "interrupt" }), children: /* @__PURE__ */ jsx2(UiIcon, { name: "stop", size: 15 }) }) : null,
876
- /* @__PURE__ */ jsx2("button", { class: "scui-send", type: "button", "aria-label": queuesNewMessage ? "Queue message" : "Send message", disabled: !draft.trim() || !queuesNewMessage && !state.canSend, onClick: send, children: /* @__PURE__ */ jsx2(UiIcon, { name: queuesNewMessage ? "plus" : "send", size: 17 }) })
991
+ /* @__PURE__ */ jsxs3("span", { children: [
992
+ state.busy ? /* @__PURE__ */ jsx3("button", { class: "scui-stop", type: "button", "aria-label": "Stop agent", disabled: !state.canInterrupt, onClick: () => adapter.onIntent({ action: "interrupt" }), children: /* @__PURE__ */ jsx3(UiIcon, { name: "stop", size: 15 }) }) : null,
993
+ /* @__PURE__ */ jsx3("button", { class: "scui-send", type: "button", "aria-label": queuesNewMessage ? "Queue message" : "Send message", disabled: !draft.trim() || !queuesNewMessage && !state.canSend, onClick: send, children: /* @__PURE__ */ jsx3(UiIcon, { name: queuesNewMessage ? "plus" : "send", size: 17 }) })
877
994
  ] })
878
995
  ] })
879
996
  ] });
@@ -886,7 +1003,7 @@ import { useEffect as useEffect3, useId, useLayoutEffect as useLayoutEffect2, us
886
1003
  // src/markdown.jsx
887
1004
  import MarkdownIt from "markdown-it";
888
1005
  import { useEffect as useEffect2, useMemo, useRef as useRef2 } from "preact/hooks";
889
- import { jsx as jsx3 } from "preact/jsx-runtime";
1006
+ import { jsx as jsx4 } from "preact/jsx-runtime";
890
1007
  var markdown = new MarkdownIt({ html: false, linkify: true, breaks: false });
891
1008
  var LANGUAGE_LABELS = {
892
1009
  bash: "Shell",
@@ -973,11 +1090,11 @@ function Markdown({ value, copyText }) {
973
1090
  }, 1500);
974
1091
  resets.current.set(button, timer);
975
1092
  };
976
- return /* @__PURE__ */ jsx3("div", { class: "scui-markdown", "data-copyable": Boolean(copyText), onClick: copyCode, dangerouslySetInnerHTML: { __html: html } });
1093
+ return /* @__PURE__ */ jsx4("div", { class: "scui-markdown", "data-copyable": Boolean(copyText), onClick: copyCode, dangerouslySetInnerHTML: { __html: html } });
977
1094
  }
978
1095
 
979
1096
  // src/conversation.jsx
980
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "preact/jsx-runtime";
1097
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "preact/jsx-runtime";
981
1098
  function LoadingStatus({ state, compact = false }) {
982
1099
  const copy = {
983
1100
  connecting: ["Connecting to coding agents", "Checking installed harnesses and capabilities.", 0],
@@ -985,43 +1102,43 @@ function LoadingStatus({ state, compact = false }) {
985
1102
  discovering: ["Loading recent sessions", "Scanning native session stores without loading full transcripts.", 2],
986
1103
  ready: ["Ready", "Coding sessions are up to date.", 3]
987
1104
  }[state.startup];
988
- return /* @__PURE__ */ jsxs3("div", { class: `scui-loading${compact ? " scui-loading-compact" : ""}`, role: "status", "aria-busy": state.startup !== "ready", children: [
989
- /* @__PURE__ */ jsx4("span", { class: "scui-orbit", "aria-hidden": "true", children: /* @__PURE__ */ jsx4("i", {}) }),
990
- /* @__PURE__ */ jsxs3("span", { class: "scui-loading-copy", children: [
991
- /* @__PURE__ */ jsx4("strong", { children: copy[0] }),
992
- /* @__PURE__ */ jsx4("small", { children: copy[1] })
1105
+ return /* @__PURE__ */ jsxs4("div", { class: `scui-loading${compact ? " scui-loading-compact" : ""}`, role: "status", "aria-busy": state.startup !== "ready", children: [
1106
+ /* @__PURE__ */ jsx5("span", { class: "scui-orbit", "aria-hidden": "true", children: /* @__PURE__ */ jsx5("i", {}) }),
1107
+ /* @__PURE__ */ jsxs4("span", { class: "scui-loading-copy", children: [
1108
+ /* @__PURE__ */ jsx5("strong", { children: copy[0] }),
1109
+ /* @__PURE__ */ jsx5("small", { children: copy[1] })
993
1110
  ] }),
994
- /* @__PURE__ */ jsx4("span", { class: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx4("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
1111
+ /* @__PURE__ */ jsx5("span", { class: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx5("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
995
1112
  ] });
996
1113
  }
997
1114
  function RequestCard({ entry, adapter, canRespond }) {
998
1115
  const request = entry.request;
999
1116
  if (!request) return null;
1000
1117
  if (request.status === "responded") {
1001
- return /* @__PURE__ */ jsxs3("div", { class: "scui-request-done", children: [
1118
+ return /* @__PURE__ */ jsxs4("div", { class: "scui-request-done", children: [
1002
1119
  "\u2713 Request answered \xB7 ",
1003
1120
  request.resolution?.name ?? request.requestKind
1004
1121
  ] });
1005
1122
  }
1006
- return /* @__PURE__ */ jsxs3("section", { class: "scui-request", role: "alert", "aria-label": `${request.requestKind} needs input`, children: [
1007
- /* @__PURE__ */ jsx4("strong", { children: "Agent needs input" }),
1008
- /* @__PURE__ */ jsx4(Markdown, { value: request.payloadText || entry.text, copyText: adapter?.copyText }),
1009
- /* @__PURE__ */ jsxs3("div", { class: "scui-request-actions", children: [
1010
- request.options.map((option) => /* @__PURE__ */ jsx4("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: option.optionId }), children: option.name }, option.optionId)),
1011
- request.cancellable ? /* @__PURE__ */ jsx4("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: null }), children: "Cancel" }) : null
1123
+ return /* @__PURE__ */ jsxs4("section", { class: "scui-request", role: "alert", "aria-label": `${request.requestKind} needs input`, children: [
1124
+ /* @__PURE__ */ jsx5("strong", { children: "Agent needs input" }),
1125
+ /* @__PURE__ */ jsx5(Markdown, { value: request.payloadText || entry.text, copyText: adapter?.copyText }),
1126
+ /* @__PURE__ */ jsxs4("div", { class: "scui-request-actions", children: [
1127
+ request.options.map((option) => /* @__PURE__ */ jsx5("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: option.optionId }), children: option.name }, option.optionId)),
1128
+ request.cancellable ? /* @__PURE__ */ jsx5("button", { type: "button", disabled: !canRespond, onClick: () => adapter.onIntent({ action: "respond", requestId: request.requestId, optionId: null }), children: "Cancel" }) : null
1012
1129
  ] })
1013
1130
  ] });
1014
1131
  }
1015
1132
  function ContextDisclosure({ context }) {
1016
1133
  if (!context?.length) return null;
1017
- return /* @__PURE__ */ jsxs3("details", { class: "scui-context", children: [
1018
- /* @__PURE__ */ jsxs3("summary", { children: [
1134
+ return /* @__PURE__ */ jsxs4("details", { class: "scui-context", children: [
1135
+ /* @__PURE__ */ jsxs4("summary", { children: [
1019
1136
  "Context \xB7 ",
1020
1137
  context.length
1021
1138
  ] }),
1022
- /* @__PURE__ */ jsx4("div", { children: context.map((item, index) => /* @__PURE__ */ jsxs3("p", { children: [
1023
- /* @__PURE__ */ jsx4("strong", { children: item.label }),
1024
- /* @__PURE__ */ jsx4("span", { children: item.detail })
1139
+ /* @__PURE__ */ jsx5("div", { children: context.map((item, index) => /* @__PURE__ */ jsxs4("p", { children: [
1140
+ /* @__PURE__ */ jsx5("strong", { children: item.label }),
1141
+ /* @__PURE__ */ jsx5("span", { children: item.detail })
1025
1142
  ] }, item.id ?? index)) })
1026
1143
  ] });
1027
1144
  }
@@ -1043,46 +1160,46 @@ function MessageMeta({ entry, adapter }) {
1043
1160
  reset.current = setTimeout(() => setCopyState2("idle"), 1500);
1044
1161
  };
1045
1162
  const copyLabel = copyState === "copied" ? "Message copied" : copyState === "failed" ? "Copy failed \xB7 retry" : "Copy message";
1046
- return /* @__PURE__ */ jsxs3("footer", { class: "scui-message-meta", children: [
1047
- validDate ? /* @__PURE__ */ jsx4("time", { dateTime: validDate.toISOString(), title: validDate.toLocaleString(), children: validDate.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }) : null,
1048
- adapter?.copyText && entry.text ? /* @__PURE__ */ jsx4("button", { type: "button", "aria-label": copyLabel, title: copyLabel, onClick: copy, "data-status": copyState, children: /* @__PURE__ */ jsx4(UiIcon, { name: "copy", size: 13 }) }) : null
1163
+ return /* @__PURE__ */ jsxs4("footer", { class: "scui-message-meta", children: [
1164
+ validDate ? /* @__PURE__ */ jsx5("time", { dateTime: validDate.toISOString(), title: validDate.toLocaleString(), children: validDate.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) }) : null,
1165
+ adapter?.copyText && entry.text ? /* @__PURE__ */ jsx5("button", { type: "button", "aria-label": copyLabel, title: copyLabel, onClick: copy, "data-status": copyState, children: /* @__PURE__ */ jsx5(UiIcon, { name: "copy", size: 13 }) }) : null
1049
1166
  ] });
1050
1167
  }
1051
1168
  var TOOL_ICONS = {
1052
- read: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1053
- /* @__PURE__ */ jsx4("path", { d: "M5 2.75h7.25L15 5.5v7.75A1.75 1.75 0 0 1 13.25 15h-8.5A1.75 1.75 0 0 1 3 13.25v-8.5A2 2 0 0 1 5 2.75Z" }),
1054
- /* @__PURE__ */ jsx4("path", { d: "M12 2.9v3h2.85M6 9h6M6 12h4" })
1169
+ read: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1170
+ /* @__PURE__ */ jsx5("path", { d: "M5 2.75h7.25L15 5.5v7.75A1.75 1.75 0 0 1 13.25 15h-8.5A1.75 1.75 0 0 1 3 13.25v-8.5A2 2 0 0 1 5 2.75Z" }),
1171
+ /* @__PURE__ */ jsx5("path", { d: "M12 2.9v3h2.85M6 9h6M6 12h4" })
1055
1172
  ] }),
1056
- search: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1057
- /* @__PURE__ */ jsx4("circle", { cx: "8", cy: "8", r: "4.5" }),
1058
- /* @__PURE__ */ jsx4("path", { d: "m11.5 11.5 3 3" })
1173
+ search: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1174
+ /* @__PURE__ */ jsx5("circle", { cx: "8", cy: "8", r: "4.5" }),
1175
+ /* @__PURE__ */ jsx5("path", { d: "m11.5 11.5 3 3" })
1059
1176
  ] }),
1060
- edit: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1061
- /* @__PURE__ */ jsx4("path", { d: "m11.75 3.25 3 3-8.5 8.5-3.75.75.75-3.75 8.5-8.5Z" }),
1062
- /* @__PURE__ */ jsx4("path", { d: "m10 5 3 3" })
1177
+ edit: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1178
+ /* @__PURE__ */ jsx5("path", { d: "m11.75 3.25 3 3-8.5 8.5-3.75.75.75-3.75 8.5-8.5Z" }),
1179
+ /* @__PURE__ */ jsx5("path", { d: "m10 5 3 3" })
1063
1180
  ] }),
1064
- command: () => /* @__PURE__ */ jsx4(Fragment3, { children: /* @__PURE__ */ jsx4("path", { d: "m3 5 3 3-3 3M8 12h6" }) }),
1065
- test: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1066
- /* @__PURE__ */ jsx4("path", { d: "M6 2.5v3L3 12a2 2 0 0 0 1.8 3h8.4a2 2 0 0 0 1.8-3l-3-6.5v-3M5 9h8" }),
1067
- /* @__PURE__ */ jsx4("path", { d: "M5 2.5h8" })
1181
+ command: () => /* @__PURE__ */ jsx5(Fragment3, { children: /* @__PURE__ */ jsx5("path", { d: "m3 5 3 3-3 3M8 12h6" }) }),
1182
+ test: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1183
+ /* @__PURE__ */ jsx5("path", { d: "M6 2.5v3L3 12a2 2 0 0 0 1.8 3h8.4a2 2 0 0 0 1.8-3l-3-6.5v-3M5 9h8" }),
1184
+ /* @__PURE__ */ jsx5("path", { d: "M5 2.5h8" })
1068
1185
  ] }),
1069
- web: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1070
- /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "9", r: "6.5" }),
1071
- /* @__PURE__ */ jsx4("path", { d: "M2.75 9h12.5M9 2.5c2 1.8 3 4 3 6.5s-1 4.7-3 6.5c-2-1.8-3-4-3-6.5s1-4.7 3-6.5Z" })
1186
+ web: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1187
+ /* @__PURE__ */ jsx5("circle", { cx: "9", cy: "9", r: "6.5" }),
1188
+ /* @__PURE__ */ jsx5("path", { d: "M2.75 9h12.5M9 2.5c2 1.8 3 4 3 6.5s-1 4.7-3 6.5c-2-1.8-3-4-3-6.5s1-4.7 3-6.5Z" })
1072
1189
  ] }),
1073
- agent: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1074
- /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "6", r: "2.5" }),
1075
- /* @__PURE__ */ jsx4("path", { d: "M4 15c.4-3 2-4.5 5-4.5s4.6 1.5 5 4.5" })
1190
+ agent: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1191
+ /* @__PURE__ */ jsx5("circle", { cx: "9", cy: "6", r: "2.5" }),
1192
+ /* @__PURE__ */ jsx5("path", { d: "M4 15c.4-3 2-4.5 5-4.5s4.6 1.5 5 4.5" })
1076
1193
  ] }),
1077
- plan: () => /* @__PURE__ */ jsx4(Fragment3, { children: /* @__PURE__ */ jsx4("path", { d: "m3 5 1 1 2-2M3 9l1 1 2-2M3 13l1 1 2-2M8 5h7M8 9h7M8 13h7" }) }),
1078
- other: () => /* @__PURE__ */ jsxs3(Fragment3, { children: [
1079
- /* @__PURE__ */ jsx4("path", { d: "M9 2.5v3M9 12.5v3M2.5 9h3M12.5 9h3" }),
1080
- /* @__PURE__ */ jsx4("circle", { cx: "9", cy: "9", r: "3.5" })
1194
+ plan: () => /* @__PURE__ */ jsx5(Fragment3, { children: /* @__PURE__ */ jsx5("path", { d: "m3 5 1 1 2-2M3 9l1 1 2-2M3 13l1 1 2-2M8 5h7M8 9h7M8 13h7" }) }),
1195
+ other: () => /* @__PURE__ */ jsxs4(Fragment3, { children: [
1196
+ /* @__PURE__ */ jsx5("path", { d: "M9 2.5v3M9 12.5v3M2.5 9h3M12.5 9h3" }),
1197
+ /* @__PURE__ */ jsx5("circle", { cx: "9", cy: "9", r: "3.5" })
1081
1198
  ] })
1082
1199
  };
1083
1200
  function ToolIcon({ category }) {
1084
1201
  const Glyph = TOOL_ICONS[category] ?? TOOL_ICONS.other;
1085
- return /* @__PURE__ */ jsx4("svg", { class: "scui-tool-icon", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", "stroke-width": "1.35", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx4(Glyph, {}) });
1202
+ return /* @__PURE__ */ jsx5("svg", { class: "scui-tool-icon", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", "stroke-width": "1.35", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(Glyph, {}) });
1086
1203
  }
1087
1204
  function toolAction2(entry, category, presentation) {
1088
1205
  if (presentation?.action) return presentation.action;
@@ -1137,7 +1254,7 @@ function ToolMetrics({ presentation }) {
1137
1254
  presentation.exitCode === null ? "" : `exit ${presentation.exitCode}`,
1138
1255
  formatDuration(presentation.durationMs)
1139
1256
  ].filter(Boolean);
1140
- return metrics.length ? /* @__PURE__ */ jsx4("div", { class: "scui-tool-metrics", children: metrics.map((metric) => /* @__PURE__ */ jsx4("span", { children: metric }, metric)) }) : null;
1257
+ return metrics.length ? /* @__PURE__ */ jsx5("div", { class: "scui-tool-metrics", children: metrics.map((metric) => /* @__PURE__ */ jsx5("span", { children: metric }, metric)) }) : null;
1141
1258
  }
1142
1259
  function PendingElapsed({ now }) {
1143
1260
  const clock = now ?? Date.now;
@@ -1147,71 +1264,74 @@ function PendingElapsed({ now }) {
1147
1264
  const timer = setInterval(() => setElapsed(Math.max(0, clock() - started.current)), 1e3);
1148
1265
  return () => clearInterval(timer);
1149
1266
  }, [clock]);
1150
- return /* @__PURE__ */ jsx4("small", { class: "scui-tool-elapsed", children: elapsed < 1e3 ? "now" : formatDuration(elapsed) });
1267
+ return /* @__PURE__ */ jsx5("small", { class: "scui-tool-elapsed", children: elapsed < 1e3 ? "now" : formatDuration(elapsed) });
1151
1268
  }
1152
1269
  function LinePreview({ value, kind }) {
1153
1270
  if (!value) return null;
1154
- return /* @__PURE__ */ jsx4("ol", { class: "scui-code-preview", "data-kind": kind, children: stripAnsi(value).split("\n").map((line, index) => {
1271
+ return /* @__PURE__ */ jsx5("ol", { class: "scui-code-preview", "data-kind": kind, children: stripAnsi(value).split("\n").map((line, index) => {
1155
1272
  const tone = kind === "diff" ? line.startsWith("+") && !line.startsWith("+++") ? "add" : line.startsWith("-") && !line.startsWith("---") ? "remove" : line.startsWith("@@") ? "hunk" : "plain" : "plain";
1156
- return /* @__PURE__ */ jsxs3("li", { "data-tone": tone, children: [
1157
- /* @__PURE__ */ jsx4("span", { children: index + 1 }),
1158
- /* @__PURE__ */ jsx4("code", { children: line || " " })
1273
+ return /* @__PURE__ */ jsxs4("li", { "data-tone": tone, children: [
1274
+ /* @__PURE__ */ jsx5("span", { children: index + 1 }),
1275
+ /* @__PURE__ */ jsx5("code", { children: line || " " })
1159
1276
  ] }, index);
1160
1277
  }) });
1161
1278
  }
1162
1279
  function TerminalPreview({ presentation, pending, failed }) {
1163
- return /* @__PURE__ */ jsxs3("section", { class: "scui-terminal", children: [
1164
- /* @__PURE__ */ jsxs3("header", { children: [
1165
- /* @__PURE__ */ jsxs3("span", { "aria-hidden": "true", children: [
1166
- /* @__PURE__ */ jsx4("i", {}),
1167
- /* @__PURE__ */ jsx4("i", {}),
1168
- /* @__PURE__ */ jsx4("i", {})
1280
+ return /* @__PURE__ */ jsxs4("section", { class: "scui-terminal", children: [
1281
+ /* @__PURE__ */ jsxs4("header", { children: [
1282
+ /* @__PURE__ */ jsxs4("span", { "aria-hidden": "true", children: [
1283
+ /* @__PURE__ */ jsx5("i", {}),
1284
+ /* @__PURE__ */ jsx5("i", {}),
1285
+ /* @__PURE__ */ jsx5("i", {})
1169
1286
  ] }),
1170
- /* @__PURE__ */ jsx4("code", { children: presentation.command ? `$ ${presentation.command}` : "Terminal" })
1287
+ /* @__PURE__ */ jsx5("code", { children: presentation.command ? `$ ${presentation.command}` : "Terminal" })
1171
1288
  ] }),
1172
- presentation.preview ? /* @__PURE__ */ jsx4("pre", { "data-error": failed, children: stripAnsi(presentation.preview) }) : pending ? /* @__PURE__ */ jsxs3("div", { class: "scui-terminal-wait", children: [
1173
- /* @__PURE__ */ jsx4("i", {}),
1289
+ presentation.preview ? /* @__PURE__ */ jsx5("pre", { "data-error": failed, children: stripAnsi(presentation.preview) }) : pending ? /* @__PURE__ */ jsxs4("div", { class: "scui-terminal-wait", children: [
1290
+ /* @__PURE__ */ jsx5("i", {}),
1174
1291
  " Waiting for output"
1175
- ] }) : /* @__PURE__ */ jsx4("div", { class: "scui-terminal-empty", children: "No output" })
1292
+ ] }) : /* @__PURE__ */ jsx5("div", { class: "scui-terminal-empty", children: "No output" })
1176
1293
  ] });
1177
1294
  }
1178
1295
  function SearchPreview({ presentation }) {
1179
1296
  const lines = stripAnsi(presentation.preview).split("\n").filter(Boolean);
1180
- return /* @__PURE__ */ jsxs3("section", { class: "scui-search-preview", children: [
1181
- presentation.query ? /* @__PURE__ */ jsxs3("header", { children: [
1182
- /* @__PURE__ */ jsx4("span", { children: "Search" }),
1183
- /* @__PURE__ */ jsx4("code", { children: presentation.query })
1297
+ return /* @__PURE__ */ jsxs4("section", { class: "scui-search-preview", children: [
1298
+ presentation.query ? /* @__PURE__ */ jsxs4("header", { children: [
1299
+ /* @__PURE__ */ jsx5("span", { children: "Search" }),
1300
+ /* @__PURE__ */ jsx5("code", { children: presentation.query })
1184
1301
  ] }) : null,
1185
- lines.length ? /* @__PURE__ */ jsx4("ol", { children: lines.map((line, index) => {
1302
+ lines.length ? /* @__PURE__ */ jsx5("ol", { children: lines.map((line, index) => {
1186
1303
  const match = /^(.*?):(\d+)(?::(\d+))?:(.*)$/.exec(line);
1187
- return /* @__PURE__ */ jsx4("li", { children: match ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
1188
- /* @__PURE__ */ jsx4("code", { children: match[1] }),
1189
- /* @__PURE__ */ jsxs3("small", { children: [
1304
+ return /* @__PURE__ */ jsx5("li", { children: match ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1305
+ /* @__PURE__ */ jsx5("code", { children: match[1] }),
1306
+ /* @__PURE__ */ jsxs4("small", { children: [
1190
1307
  match[2],
1191
1308
  match[3] ? `:${match[3]}` : ""
1192
1309
  ] }),
1193
- /* @__PURE__ */ jsx4("span", { children: match[4] })
1194
- ] }) : /* @__PURE__ */ jsx4("span", { children: line }) }, index);
1195
- }) }) : /* @__PURE__ */ jsx4("p", { children: "No textual results" })
1310
+ /* @__PURE__ */ jsx5("span", { children: match[4] })
1311
+ ] }) : /* @__PURE__ */ jsx5("span", { children: line }) }, index);
1312
+ }) }) : /* @__PURE__ */ jsx5("p", { children: "No textual results" })
1196
1313
  ] });
1197
1314
  }
1198
1315
  function ToolPreview({ presentation, entry }) {
1199
1316
  const pending = entry.status === "pending";
1200
1317
  const failed = entry.status === "error";
1201
- if (presentation.detail === "terminal") return /* @__PURE__ */ jsx4(TerminalPreview, { presentation, pending, failed });
1202
- if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */ jsx4(LinePreview, { value: presentation.preview, kind: "diff" }) : /* @__PURE__ */ jsx4("div", { class: "scui-tool-empty", children: "Edit completed without a textual diff" });
1203
- if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */ jsx4(LinePreview, { value: presentation.preview, kind: "file" }) : /* @__PURE__ */ jsx4("div", { class: "scui-tool-empty", children: "File contents were not included in this event" });
1204
- if (presentation.detail === "matches") return /* @__PURE__ */ jsx4(SearchPreview, { presentation });
1205
- if (presentation.detail === "web") return /* @__PURE__ */ jsxs3("section", { class: "scui-web-preview", children: [
1206
- presentation.url ? /* @__PURE__ */ jsx4("code", { children: presentation.url }) : null,
1207
- presentation.preview ? /* @__PURE__ */ jsx4("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
1318
+ if (presentation.detail === "terminal") return /* @__PURE__ */ jsx5(TerminalPreview, { presentation, pending, failed });
1319
+ if (presentation.detail === "diff") return presentation.preview ? /* @__PURE__ */ jsx5(LinePreview, { value: presentation.preview, kind: "diff" }) : /* @__PURE__ */ jsx5("div", { class: "scui-tool-empty", children: "Edit completed without a textual diff" });
1320
+ if (presentation.detail === "file") return presentation.preview ? /* @__PURE__ */ jsx5(LinePreview, { value: presentation.preview, kind: "file" }) : /* @__PURE__ */ jsx5("div", { class: "scui-tool-empty", children: "File contents were not included in this event" });
1321
+ if (presentation.detail === "matches") return /* @__PURE__ */ jsx5(SearchPreview, { presentation });
1322
+ if (presentation.detail === "web") return /* @__PURE__ */ jsxs4("section", { class: "scui-web-preview", children: [
1323
+ presentation.url ? /* @__PURE__ */ jsx5("code", { children: presentation.url }) : null,
1324
+ presentation.preview ? /* @__PURE__ */ jsx5("p", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx5("small", { children: pending ? "Waiting for the page" : "No page summary returned" })
1208
1325
  ] });
1209
- if (presentation.detail === "agent") return /* @__PURE__ */ jsx4("section", { class: "scui-agent-preview", children: presentation.preview ? /* @__PURE__ */ jsx4("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx4("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
1210
- if (presentation.detail === "plan") return /* @__PURE__ */ jsx4("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs3("li", { "data-status": item.status, children: [
1211
- /* @__PURE__ */ jsx4("i", { "aria-hidden": "true" }),
1212
- /* @__PURE__ */ jsx4("span", { children: item.label })
1326
+ if (presentation.detail === "agent") return /* @__PURE__ */ jsx5("section", { class: "scui-agent-preview", children: presentation.items?.length ? /* @__PURE__ */ jsx5("ol", { class: "scui-agent-roster", children: presentation.items.map((item, index) => /* @__PURE__ */ jsxs4("li", { children: [
1327
+ /* @__PURE__ */ jsx5("strong", { children: item.label }),
1328
+ /* @__PURE__ */ jsx5("small", { children: item.status })
1329
+ ] }, `${item.label}:${index}`)) }) : presentation.preview ? /* @__PURE__ */ jsx5("pre", { children: stripAnsi(presentation.preview) }) : /* @__PURE__ */ jsx5("small", { children: pending ? "Agent is working" : "No textual handoff returned" }) });
1330
+ if (presentation.detail === "plan") return /* @__PURE__ */ jsx5("ol", { class: "scui-plan-preview", children: presentation.items?.map((item, index) => /* @__PURE__ */ jsxs4("li", { "data-status": item.status, children: [
1331
+ /* @__PURE__ */ jsx5("i", { "aria-hidden": "true" }),
1332
+ /* @__PURE__ */ jsx5("span", { children: item.label })
1213
1333
  ] }, `${item.label}:${index}`)) });
1214
- return presentation.preview ? /* @__PURE__ */ jsx4("pre", { class: "scui-tool-output", "data-error": failed, children: stripAnsi(presentation.preview) }) : null;
1334
+ return presentation.preview ? /* @__PURE__ */ jsx5("pre", { class: "scui-tool-output", "data-error": failed, children: stripAnsi(presentation.preview) }) : null;
1215
1335
  }
1216
1336
  function ToolActions({ presentation, adapter }) {
1217
1337
  const [copied, setCopied] = useState2(false);
@@ -1225,27 +1345,27 @@ function ToolActions({ presentation, adapter }) {
1225
1345
  clearTimeout(reset.current);
1226
1346
  reset.current = setTimeout(() => setCopied(false), 1500);
1227
1347
  };
1228
- return action ? /* @__PURE__ */ jsx4("div", { class: "scui-tool-actions", children: /* @__PURE__ */ jsx4("button", { type: "button", onClick: copy, children: copied ? "Copied" : action[0] }) }) : null;
1348
+ return action ? /* @__PURE__ */ jsx5("div", { class: "scui-tool-actions", children: /* @__PURE__ */ jsx5("button", { type: "button", onClick: copy, children: copied ? "Copied" : action[0] }) }) : null;
1229
1349
  }
1230
1350
  function ToolStack({ tools }) {
1231
1351
  if (tools.length < 2) return null;
1232
- return /* @__PURE__ */ jsx4("div", { class: "scui-tool-stack", "aria-label": "Coordinated tools", children: tools.map((tool) => /* @__PURE__ */ jsx4("span", { children: tool.replaceAll("__", " \xB7 ").replaceAll("_", " ") }, tool)) });
1352
+ return /* @__PURE__ */ jsx5("div", { class: "scui-tool-stack", "aria-label": "Coordinated tools", children: tools.map((tool) => /* @__PURE__ */ jsx5("span", { children: tool.replaceAll("__", " \xB7 ").replaceAll("_", " ") }, tool)) });
1233
1353
  }
1234
1354
  function TechnicalDetails({ entry }) {
1235
1355
  if (!entry.arguments && !entry.resultText) return null;
1236
- return /* @__PURE__ */ jsxs3("details", { class: "scui-tool-technical", children: [
1237
- /* @__PURE__ */ jsx4("summary", { children: "Technical details" }),
1238
- /* @__PURE__ */ jsxs3("div", { children: [
1239
- entry.arguments ? /* @__PURE__ */ jsxs3("section", { children: [
1240
- /* @__PURE__ */ jsx4("strong", { children: "Native arguments" }),
1241
- /* @__PURE__ */ jsx4("dl", { children: argumentRows(entry.arguments).map((row) => /* @__PURE__ */ jsxs3("div", { children: [
1242
- /* @__PURE__ */ jsx4("dt", { children: row.label }),
1243
- /* @__PURE__ */ jsx4("dd", { children: /* @__PURE__ */ jsx4("pre", { children: row.value }) })
1356
+ return /* @__PURE__ */ jsxs4("details", { class: "scui-tool-technical", children: [
1357
+ /* @__PURE__ */ jsx5("summary", { children: "Technical details" }),
1358
+ /* @__PURE__ */ jsxs4("div", { children: [
1359
+ entry.arguments ? /* @__PURE__ */ jsxs4("section", { children: [
1360
+ /* @__PURE__ */ jsx5("strong", { children: "Native arguments" }),
1361
+ /* @__PURE__ */ jsx5("dl", { children: argumentRows(entry.arguments).map((row) => /* @__PURE__ */ jsxs4("div", { children: [
1362
+ /* @__PURE__ */ jsx5("dt", { children: row.label }),
1363
+ /* @__PURE__ */ jsx5("dd", { children: /* @__PURE__ */ jsx5("pre", { children: row.value }) })
1244
1364
  ] }, row.key)) })
1245
1365
  ] }) : null,
1246
- entry.resultText ? /* @__PURE__ */ jsxs3("section", { children: [
1247
- /* @__PURE__ */ jsx4("strong", { children: "Native result" }),
1248
- /* @__PURE__ */ jsxs3("pre", { "data-error": entry.status === "error", children: [
1366
+ entry.resultText ? /* @__PURE__ */ jsxs4("section", { children: [
1367
+ /* @__PURE__ */ jsx5("strong", { children: "Native result" }),
1368
+ /* @__PURE__ */ jsxs4("pre", { "data-error": entry.status === "error", children: [
1249
1369
  entry.resultText,
1250
1370
  entry.truncated ? "\n[truncated]" : ""
1251
1371
  ] })
@@ -1254,19 +1374,19 @@ function TechnicalDetails({ entry }) {
1254
1374
  ] });
1255
1375
  }
1256
1376
  function TranscriptEntry({ entry, state, adapter }) {
1257
- if (entry.role === "request") return /* @__PURE__ */ jsx4(RequestCard, { entry, adapter, canRespond: state.canRespond });
1377
+ if (entry.role === "request") return /* @__PURE__ */ jsx5(RequestCard, { entry, adapter, canRespond: state.canRespond });
1258
1378
  if (entry.role === "reasoning") {
1259
- return /* @__PURE__ */ jsxs3("details", { class: "scui-reasoning", open: entry.streaming, children: [
1260
- /* @__PURE__ */ jsx4("summary", { children: entry.streaming ? "Reasoning\u2026" : "Reasoning" }),
1261
- /* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText })
1379
+ return /* @__PURE__ */ jsxs4("details", { class: "scui-reasoning", open: entry.streaming, children: [
1380
+ /* @__PURE__ */ jsx5("summary", { children: entry.streaming ? "Reasoning\u2026" : "Reasoning" }),
1381
+ /* @__PURE__ */ jsx5(Markdown, { value: entry.text, copyText: adapter?.copyText })
1262
1382
  ] });
1263
1383
  }
1264
- if (entry.role === "notice" || entry.role === "system") return /* @__PURE__ */ jsx4("div", { class: "scui-notice", "data-code": entry.code, children: entry.text });
1265
- return /* @__PURE__ */ jsxs3("article", { class: "scui-message", "data-role": entry.role, "aria-label": `${entry.role === "user" ? "Your" : "Assistant"} message`, children: [
1266
- /* @__PURE__ */ jsx4(Markdown, { value: entry.text, copyText: adapter?.copyText }),
1267
- /* @__PURE__ */ jsx4(ContextDisclosure, { context: entry.context }),
1268
- entry.truncated ? /* @__PURE__ */ jsx4("small", { class: "scui-truncated", children: "Entry truncated by host \xB7 load native session for the complete value" }) : null,
1269
- /* @__PURE__ */ jsx4(MessageMeta, { entry, adapter })
1384
+ if (entry.role === "notice" || entry.role === "system") return /* @__PURE__ */ jsx5("div", { class: "scui-notice", "data-code": entry.code, children: entry.text });
1385
+ return /* @__PURE__ */ jsxs4("article", { class: "scui-message", "data-role": entry.role, "aria-label": `${entry.role === "user" ? "Your" : "Assistant"} message`, children: [
1386
+ /* @__PURE__ */ jsx5(Markdown, { value: entry.text, copyText: adapter?.copyText }),
1387
+ /* @__PURE__ */ jsx5(ContextDisclosure, { context: entry.context }),
1388
+ entry.truncated ? /* @__PURE__ */ jsx5("small", { class: "scui-truncated", children: "Entry truncated by host \xB7 load native session for the complete value" }) : null,
1389
+ /* @__PURE__ */ jsx5(MessageMeta, { entry, adapter })
1270
1390
  ] });
1271
1391
  }
1272
1392
  function ToolRow({ entry, workspace, open = false, adapter }) {
@@ -1278,102 +1398,102 @@ function ToolRow({ entry, workspace, open = false, adapter }) {
1278
1398
  const target = compactToolTarget(presentation.target, workspace);
1279
1399
  const hasDetail = Boolean(entry.arguments || entry.resultText || presentation.preview || presentation.fields.length);
1280
1400
  const category = presentation.category ?? toolCategory(entry);
1281
- const summary = /* @__PURE__ */ jsxs3(Fragment3, { children: [
1282
- /* @__PURE__ */ jsx4(ToolIcon, { category }),
1283
- /* @__PURE__ */ jsx4("strong", { children: toolAction2(entry, category, presentation) }),
1284
- target ? /* @__PURE__ */ jsx4("code", { class: "scui-tool-target", title: presentation.target, children: target }) : null,
1285
- /* @__PURE__ */ jsx4("span", { class: "scui-spacer" }),
1286
- entry.status === "pending" ? /* @__PURE__ */ jsx4(PendingElapsed, { now: adapter?.now }) : null,
1287
- /* @__PURE__ */ jsx4("span", { class: "scui-tool-status", role: "status", "data-status": entry.status ?? "completed", "aria-label": entry.status ?? "completed", children: entry.status === "pending" ? /* @__PURE__ */ jsx4("i", {}) : /* @__PURE__ */ jsx4(UiIcon, { name: entry.status === "error" ? "close" : "check", size: 12 }) }),
1288
- hasDetail ? /* @__PURE__ */ jsx4(UiIcon, { name: "chevron", size: 14, class: "scui-tool-chevron" }) : null
1401
+ const summary = /* @__PURE__ */ jsxs4(Fragment3, { children: [
1402
+ /* @__PURE__ */ jsx5(ToolIcon, { category }),
1403
+ /* @__PURE__ */ jsx5("strong", { children: toolAction2(entry, category, presentation) }),
1404
+ target ? /* @__PURE__ */ jsx5("code", { class: "scui-tool-target", title: presentation.target, children: target }) : null,
1405
+ /* @__PURE__ */ jsx5("span", { class: "scui-spacer" }),
1406
+ entry.status === "pending" ? /* @__PURE__ */ jsx5(PendingElapsed, { now: adapter?.now }) : null,
1407
+ /* @__PURE__ */ jsx5("span", { class: "scui-tool-status", role: "status", "data-status": entry.status ?? "completed", "aria-label": entry.status ?? "completed", children: entry.status === "pending" ? /* @__PURE__ */ jsx5("i", {}) : /* @__PURE__ */ jsx5(UiIcon, { name: entry.status === "error" ? "close" : "check", size: 12 }) }),
1408
+ hasDetail ? /* @__PURE__ */ jsx5(UiIcon, { name: "chevron", size: 14, class: "scui-tool-chevron" }) : null
1289
1409
  ] });
1290
- if (!hasDetail) return /* @__PURE__ */ jsx4("div", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, children: /* @__PURE__ */ jsx4("div", { class: "scui-tool-head", children: summary }) });
1291
- return /* @__PURE__ */ jsxs3("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open: expanded, onToggle: (event) => setExpanded(event.currentTarget.open), children: [
1292
- /* @__PURE__ */ jsx4("summary", { class: "scui-tool-head", children: summary }),
1293
- /* @__PURE__ */ jsxs3("div", { class: "scui-tool-detail", children: [
1294
- /* @__PURE__ */ jsx4(ToolMetrics, { presentation }),
1295
- /* @__PURE__ */ jsx4(ToolStack, { tools: presentation.tools ?? [] }),
1296
- /* @__PURE__ */ jsx4(ToolPreview, { presentation, entry }),
1297
- presentation.fields.length ? /* @__PURE__ */ jsx4("dl", { class: "scui-tool-fields", children: presentation.fields.map((field) => /* @__PURE__ */ jsxs3("div", { children: [
1298
- /* @__PURE__ */ jsx4("dt", { children: field.label }),
1299
- /* @__PURE__ */ jsx4("dd", { children: field.value })
1410
+ if (!hasDetail) return /* @__PURE__ */ jsx5("div", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, children: /* @__PURE__ */ jsx5("div", { class: "scui-tool-head", children: summary }) });
1411
+ return /* @__PURE__ */ jsxs4("details", { class: "scui-tool", "data-status": entry.status ?? "completed", "data-category": category, open: expanded, onToggle: (event) => setExpanded(event.currentTarget.open), children: [
1412
+ /* @__PURE__ */ jsx5("summary", { class: "scui-tool-head", children: summary }),
1413
+ /* @__PURE__ */ jsxs4("div", { class: "scui-tool-detail", children: [
1414
+ /* @__PURE__ */ jsx5(ToolMetrics, { presentation }),
1415
+ /* @__PURE__ */ jsx5(ToolStack, { tools: presentation.tools ?? [] }),
1416
+ /* @__PURE__ */ jsx5(ToolPreview, { presentation, entry }),
1417
+ presentation.fields.length ? /* @__PURE__ */ jsx5("dl", { class: "scui-tool-fields", children: presentation.fields.map((field) => /* @__PURE__ */ jsxs4("div", { children: [
1418
+ /* @__PURE__ */ jsx5("dt", { children: field.label }),
1419
+ /* @__PURE__ */ jsx5("dd", { children: field.value })
1300
1420
  ] }, field.label)) }) : null,
1301
- /* @__PURE__ */ jsx4(ToolActions, { presentation, adapter }),
1302
- /* @__PURE__ */ jsx4(TechnicalDetails, { entry })
1421
+ /* @__PURE__ */ jsx5(ToolActions, { presentation, adapter }),
1422
+ /* @__PURE__ */ jsx5(TechnicalDetails, { entry })
1303
1423
  ] })
1304
1424
  ] });
1305
1425
  }
1306
1426
  function ActivityGroup({ entries, state, adapter }) {
1307
- if (entries.length === 1) return /* @__PURE__ */ jsx4("section", { class: "scui-activity", "data-single": "true", children: /* @__PURE__ */ jsx4(ToolRow, { entry: entries[0], workspace: state.workspace, adapter }) });
1427
+ if (entries.length === 1) return /* @__PURE__ */ jsx5("section", { class: "scui-activity", "data-single": "true", children: /* @__PURE__ */ jsx5(ToolRow, { entry: entries[0], workspace: state.workspace, adapter }) });
1308
1428
  const active = entries.some((entry) => entry.status === "pending");
1309
1429
  const [open, setOpen] = useState2(active);
1310
1430
  const id = useId();
1311
1431
  useEffect3(() => {
1312
1432
  if (active) setOpen(true);
1313
1433
  }, [active]);
1314
- return /* @__PURE__ */ jsxs3("section", { class: "scui-activity", children: [
1315
- /* @__PURE__ */ jsxs3("button", { class: "scui-activity-head", type: "button", "aria-expanded": open, "aria-controls": id, onClick: () => setOpen((value) => !value), children: [
1316
- /* @__PURE__ */ jsx4("span", { class: "scui-fold", "data-open": open, children: /* @__PURE__ */ jsx4(UiIcon, { name: "chevron", size: 14 }) }),
1317
- /* @__PURE__ */ jsx4("strong", { children: activitySummary(entries) }),
1318
- /* @__PURE__ */ jsx4("span", { class: "scui-spacer" }),
1319
- /* @__PURE__ */ jsxs3("small", { children: [
1434
+ return /* @__PURE__ */ jsxs4("section", { class: "scui-activity", children: [
1435
+ /* @__PURE__ */ jsxs4("button", { class: "scui-activity-head", type: "button", "aria-expanded": open, "aria-controls": id, onClick: () => setOpen((value) => !value), children: [
1436
+ /* @__PURE__ */ jsx5("span", { class: "scui-fold", "data-open": open, children: /* @__PURE__ */ jsx5(UiIcon, { name: "chevron", size: 14 }) }),
1437
+ /* @__PURE__ */ jsx5("strong", { children: activitySummary(entries) }),
1438
+ /* @__PURE__ */ jsx5("span", { class: "scui-spacer" }),
1439
+ /* @__PURE__ */ jsxs4("small", { children: [
1320
1440
  entries.filter((entry) => entry.status !== "pending").length,
1321
1441
  "/",
1322
1442
  entries.length
1323
1443
  ] })
1324
1444
  ] }),
1325
- open ? /* @__PURE__ */ jsx4("div", { id, children: entries.map((entry) => /* @__PURE__ */ jsx4(ToolRow, { entry, workspace: state.workspace, adapter }, entry.id)) }) : null
1445
+ open ? /* @__PURE__ */ jsx5("div", { id, children: entries.map((entry) => /* @__PURE__ */ jsx5(ToolRow, { entry, workspace: state.workspace, adapter }, entry.id)) }) : null
1326
1446
  ] });
1327
1447
  }
1328
1448
  function TaskPlan({ plan }) {
1329
1449
  if (!plan.items.length) return null;
1330
1450
  const complete = plan.items.filter((item) => item.status === "completed" || item.status === "cancelled").length;
1331
- return /* @__PURE__ */ jsxs3("details", { class: "scui-plan", children: [
1332
- /* @__PURE__ */ jsxs3("summary", { children: [
1333
- /* @__PURE__ */ jsx4("span", { children: "Plan" }),
1334
- /* @__PURE__ */ jsxs3("small", { children: [
1451
+ return /* @__PURE__ */ jsxs4("details", { class: "scui-plan", children: [
1452
+ /* @__PURE__ */ jsxs4("summary", { children: [
1453
+ /* @__PURE__ */ jsx5("span", { children: "Plan" }),
1454
+ /* @__PURE__ */ jsxs4("small", { children: [
1335
1455
  complete,
1336
1456
  "/",
1337
1457
  plan.items.length
1338
1458
  ] })
1339
1459
  ] }),
1340
- /* @__PURE__ */ jsx4("ol", { tabIndex: 0, "aria-label": "Task plan steps", children: plan.items.map((item) => /* @__PURE__ */ jsxs3("li", { "data-status": item.status, children: [
1341
- /* @__PURE__ */ jsx4("i", { "aria-hidden": "true" }),
1460
+ /* @__PURE__ */ jsx5("ol", { tabIndex: 0, "aria-label": "Task plan steps", children: plan.items.map((item) => /* @__PURE__ */ jsxs4("li", { "data-status": item.status, children: [
1461
+ /* @__PURE__ */ jsx5("i", { "aria-hidden": "true" }),
1342
1462
  " ",
1343
- /* @__PURE__ */ jsx4("span", { children: item.title })
1463
+ /* @__PURE__ */ jsx5("span", { children: item.title })
1344
1464
  ] }, item.id)) })
1345
1465
  ] });
1346
1466
  }
1347
1467
  function SessionDetails({ semantics }) {
1348
1468
  if (!semantics.fidelity && !semantics.residueCount && !semantics.parseErrors && !semantics.subagents.length) return null;
1349
- return /* @__PURE__ */ jsxs3("details", { class: "scui-details", children: [
1350
- /* @__PURE__ */ jsx4("summary", { children: "Session details" }),
1351
- /* @__PURE__ */ jsxs3("div", { children: [
1352
- semantics.fidelity ? /* @__PURE__ */ jsxs3("p", { children: [
1353
- /* @__PURE__ */ jsx4("strong", { children: "Fidelity" }),
1354
- /* @__PURE__ */ jsx4("span", { children: semantics.fidelity.replaceAll("_", " ") })
1469
+ return /* @__PURE__ */ jsxs4("details", { class: "scui-details", children: [
1470
+ /* @__PURE__ */ jsx5("summary", { children: "Session details" }),
1471
+ /* @__PURE__ */ jsxs4("div", { children: [
1472
+ semantics.fidelity ? /* @__PURE__ */ jsxs4("p", { children: [
1473
+ /* @__PURE__ */ jsx5("strong", { children: "Fidelity" }),
1474
+ /* @__PURE__ */ jsx5("span", { children: semantics.fidelity.replaceAll("_", " ") })
1355
1475
  ] }) : null,
1356
- /* @__PURE__ */ jsxs3("p", { children: [
1357
- /* @__PURE__ */ jsx4("strong", { children: "Native records" }),
1358
- /* @__PURE__ */ jsx4("span", { children: semantics.rawRecords })
1476
+ /* @__PURE__ */ jsxs4("p", { children: [
1477
+ /* @__PURE__ */ jsx5("strong", { children: "Native records" }),
1478
+ /* @__PURE__ */ jsx5("span", { children: semantics.rawRecords })
1359
1479
  ] }),
1360
- semantics.residueCount ? /* @__PURE__ */ jsxs3("p", { children: [
1361
- /* @__PURE__ */ jsx4("strong", { children: "Residue" }),
1362
- /* @__PURE__ */ jsxs3("span", { children: [
1480
+ semantics.residueCount ? /* @__PURE__ */ jsxs4("p", { children: [
1481
+ /* @__PURE__ */ jsx5("strong", { children: "Residue" }),
1482
+ /* @__PURE__ */ jsxs4("span", { children: [
1363
1483
  semantics.residueCount,
1364
1484
  " retained"
1365
1485
  ] })
1366
1486
  ] }) : null,
1367
- semantics.parseErrors ? /* @__PURE__ */ jsxs3("p", { children: [
1368
- /* @__PURE__ */ jsx4("strong", { children: "Parse diagnostics" }),
1369
- /* @__PURE__ */ jsx4("span", { children: semantics.parseErrors })
1487
+ semantics.parseErrors ? /* @__PURE__ */ jsxs4("p", { children: [
1488
+ /* @__PURE__ */ jsx5("strong", { children: "Parse diagnostics" }),
1489
+ /* @__PURE__ */ jsx5("span", { children: semantics.parseErrors })
1370
1490
  ] }) : null,
1371
- semantics.subagents.map((agent) => /* @__PURE__ */ jsxs3("p", { children: [
1372
- /* @__PURE__ */ jsxs3("strong", { children: [
1491
+ semantics.subagents.map((agent) => /* @__PURE__ */ jsxs4("p", { children: [
1492
+ /* @__PURE__ */ jsxs4("strong", { children: [
1373
1493
  agent.source,
1374
1494
  " subagent"
1375
1495
  ] }),
1376
- /* @__PURE__ */ jsxs3("span", { children: [
1496
+ /* @__PURE__ */ jsxs4("span", { children: [
1377
1497
  agent.messages,
1378
1498
  " messages \xB7 ",
1379
1499
  agent.fidelity.replaceAll("_", " ")
@@ -1392,7 +1512,7 @@ function ConversationAnnouncements({ state }) {
1392
1512
  }
1393
1513
  previousBusy.current = state.busy;
1394
1514
  }, [state.busy, state.error, state.harness]);
1395
- return /* @__PURE__ */ jsx4("span", { class: "scui-sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement });
1515
+ return /* @__PURE__ */ jsx5("span", { class: "scui-sr-only", role: "status", "aria-live": "polite", "aria-atomic": "true", children: announcement });
1396
1516
  }
1397
1517
  function Conversation({ state, adapter, components = {}, slots = {}, memoryKey = state.attached?.key || `${state.harness}:${state.workspace}`, pending = null, unreadAfterMessages = null }) {
1398
1518
  const scroller = useRef3(null);
@@ -1424,65 +1544,71 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
1424
1544
  const element = scroller.current;
1425
1545
  if (!element) return;
1426
1546
  const anchor = earlierAnchor.current;
1427
- if (anchor && state.transcript.length > anchor.entries) {
1428
- element.scrollTop = anchor.top + (element.scrollHeight - anchor.height);
1429
- earlierAnchor.current = null;
1430
- remember({ top: element.scrollTop, atBottom: false });
1431
- return;
1547
+ if (anchor) {
1548
+ if (state.operation === "loadEarlier") anchor.seenOperation = true;
1549
+ const prepended = state.transcript.length > anchor.entries && state.transcript[0]?.id !== anchor.firstId;
1550
+ if (prepended) {
1551
+ element.scrollTop = anchor.top + (element.scrollHeight - anchor.height);
1552
+ earlierAnchor.current = null;
1553
+ remember({ top: element.scrollTop, atBottom: false });
1554
+ return;
1555
+ }
1556
+ if (state.error || anchor.seenOperation && state.operation !== "loadEarlier") earlierAnchor.current = null;
1432
1557
  }
1433
1558
  if (!restored.current) {
1434
1559
  restored.current = true;
1435
1560
  if (remembered.top !== null && !remembered.atBottom) element.scrollTop = remembered.top;
1436
1561
  else pin();
1437
1562
  } else if (atBottom) pin();
1438
- }, [memoryKey, state.transcript, state.busy, state.operation, pendingMessage?.text, pendingMessage?.status]);
1439
- return /* @__PURE__ */ jsxs3("div", { class: "scui-conversation-wrap", children: [
1440
- /* @__PURE__ */ jsx4(ConversationAnnouncements, { state }),
1441
- /* @__PURE__ */ jsx4("div", { class: "scui-conversation", ref: scroller, tabIndex: 0, "aria-label": "Conversation", onScroll: (event) => {
1563
+ }, [memoryKey, state.transcript, state.busy, state.operation, state.error, pendingMessage?.text, pendingMessage?.status]);
1564
+ return /* @__PURE__ */ jsxs4("div", { class: "scui-conversation-wrap", children: [
1565
+ /* @__PURE__ */ jsx5(ConversationAnnouncements, { state }),
1566
+ /* @__PURE__ */ jsx5("div", { class: "scui-conversation", ref: scroller, tabIndex: 0, "aria-label": "Conversation", onScroll: (event) => {
1442
1567
  const element = event.currentTarget;
1443
1568
  const bottom = element.scrollHeight - element.scrollTop - element.clientHeight <= 64;
1444
1569
  setAtBottom(bottom);
1445
1570
  remember({ top: element.scrollTop, atBottom: bottom });
1446
- }, children: /* @__PURE__ */ jsxs3("div", { children: [
1447
- Before ? /* @__PURE__ */ jsx4(Before, { state, adapter, value: null }) : null,
1448
- /* @__PURE__ */ jsx4(Plan, { plan: state.taskPlan, value: state.taskPlan, state, adapter }),
1449
- /* @__PURE__ */ jsx4(SessionDetails, { semantics: state.semantics }),
1450
- state.history.hasEarlier ? /* @__PURE__ */ jsx4("button", { class: "scui-load", type: "button", disabled: Boolean(state.operation), onClick: () => {
1571
+ }, children: /* @__PURE__ */ jsxs4("div", { children: [
1572
+ Before ? /* @__PURE__ */ jsx5(Before, { state, adapter, value: null }) : null,
1573
+ /* @__PURE__ */ jsx5(Plan, { plan: state.taskPlan, value: state.taskPlan, state, adapter }),
1574
+ /* @__PURE__ */ jsx5(SessionDetails, { semantics: state.semantics }),
1575
+ state.history.hasEarlier ? /* @__PURE__ */ jsx5("button", { class: "scui-load", type: "button", disabled: Boolean(state.operation), onClick: () => {
1451
1576
  const element = scroller.current;
1452
- if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length };
1577
+ if (element) earlierAnchor.current = { height: element.scrollHeight, top: element.scrollTop, entries: state.transcript.length, firstId: state.transcript[0]?.id, seenOperation: false };
1453
1578
  setAtBottom(false);
1454
1579
  adapter.onIntent({ action: "loadEarlier" });
1455
1580
  }, children: "Load earlier messages" }) : null,
1456
- !blocks.length && state.startup !== "ready" ? /* @__PURE__ */ jsx4(LoadingStatus, { state }) : null,
1457
- !blocks.length && state.startup === "ready" ? Empty ? /* @__PURE__ */ jsx4(Empty, { state, adapter, value: null }) : /* @__PURE__ */ jsx4("div", { class: "scui-empty", children: state.error ?? (state.harness ? `${harnessDisplayName(state.harness)} is listening. Say something.` : "No transcript yet.") }) : null,
1458
- blocks.map((block, index) => /* @__PURE__ */ jsxs3(Fragment2, { children: [
1459
- index === unreadBlock ? /* @__PURE__ */ jsx4("div", { class: "scui-unread-divider", role: "separator", "aria-label": "New messages", children: /* @__PURE__ */ jsx4("span", { children: "New" }) }) : null,
1460
- block.kind === "activity" ? /* @__PURE__ */ jsx4(Group, { value: block.entries, entries: block.entries, state, adapter }) : /* @__PURE__ */ jsx4(Entry, { value: block.entry, entry: block.entry, state, adapter })
1581
+ !blocks.length && state.startup !== "ready" ? /* @__PURE__ */ jsx5(LoadingStatus, { state }) : null,
1582
+ !blocks.length && state.startup === "ready" ? Empty ? /* @__PURE__ */ jsx5(Empty, { state, adapter, value: null }) : /* @__PURE__ */ jsx5("div", { class: "scui-empty", children: state.error ?? (state.harness ? `${harnessDisplayName(state.harness)} is listening. Say something.` : "No transcript yet.") }) : null,
1583
+ blocks.map((block, index) => /* @__PURE__ */ jsxs4(Fragment2, { children: [
1584
+ index === unreadBlock ? /* @__PURE__ */ jsx5("div", { class: "scui-unread-divider", role: "separator", "aria-label": "New messages", children: /* @__PURE__ */ jsx5("span", { children: "New" }) }) : null,
1585
+ block.kind === "activity" ? /* @__PURE__ */ jsx5(Group, { value: block.entries, entries: block.entries, state, adapter }) : /* @__PURE__ */ jsx5(Entry, { value: block.entry, entry: block.entry, state, adapter })
1461
1586
  ] }, block.id)),
1462
- pendingMessage ? /* @__PURE__ */ jsxs3("article", { class: "scui-message scui-pending", "data-role": "user", "data-status": pendingMessage.status, "aria-label": "Your pending message", children: [
1463
- /* @__PURE__ */ jsx4(Markdown, { value: pendingMessage.text, copyText: adapter?.copyText }),
1464
- /* @__PURE__ */ jsxs3("footer", { children: [
1465
- /* @__PURE__ */ jsx4("small", { children: pendingMessage.status === "failed" ? "Not sent" : "Sending\u2026" }),
1466
- pendingMessage.status === "failed" ? /* @__PURE__ */ jsxs3("span", { children: [
1467
- /* @__PURE__ */ jsx4("button", { type: "button", onClick: pendingMessage.onRetry, children: "Retry" }),
1468
- /* @__PURE__ */ jsx4("button", { type: "button", onClick: pendingMessage.onEdit, children: "Edit" })
1587
+ pendingMessage ? /* @__PURE__ */ jsxs4("article", { class: "scui-message scui-pending", "data-role": "user", "data-status": pendingMessage.status, "aria-label": "Your pending message", children: [
1588
+ /* @__PURE__ */ jsx5(Markdown, { value: pendingMessage.text, copyText: adapter?.copyText }),
1589
+ /* @__PURE__ */ jsx5(ContextDisclosure, { context: pendingMessage.context }),
1590
+ /* @__PURE__ */ jsxs4("footer", { children: [
1591
+ /* @__PURE__ */ jsx5("small", { children: pendingMessage.status === "failed" ? "Not sent" : "Sending\u2026" }),
1592
+ pendingMessage.status === "failed" ? /* @__PURE__ */ jsxs4("span", { children: [
1593
+ /* @__PURE__ */ jsx5("button", { type: "button", onClick: pendingMessage.onRetry, children: "Retry" }),
1594
+ /* @__PURE__ */ jsx5("button", { type: "button", onClick: pendingMessage.onEdit, children: "Edit" })
1469
1595
  ] }) : null
1470
1596
  ] })
1471
1597
  ] }) : null,
1472
- state.busy ? /* @__PURE__ */ jsxs3("div", { class: "scui-working", role: "status", children: [
1473
- /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: "\u2726" }),
1474
- /* @__PURE__ */ jsx4("i", {}),
1475
- /* @__PURE__ */ jsx4("i", {}),
1476
- /* @__PURE__ */ jsx4("i", {}),
1477
- /* @__PURE__ */ jsxs3("small", { children: [
1598
+ state.busy ? /* @__PURE__ */ jsxs4("div", { class: "scui-working", role: "status", children: [
1599
+ /* @__PURE__ */ jsx5("span", { "aria-hidden": "true", children: "\u2726" }),
1600
+ /* @__PURE__ */ jsx5("i", {}),
1601
+ /* @__PURE__ */ jsx5("i", {}),
1602
+ /* @__PURE__ */ jsx5("i", {}),
1603
+ /* @__PURE__ */ jsxs4("small", { children: [
1478
1604
  harnessDisplayName(state.harness),
1479
1605
  " is working"
1480
1606
  ] })
1481
1607
  ] }) : null,
1482
- After ? /* @__PURE__ */ jsx4(After, { state, adapter, value: null }) : null
1608
+ After ? /* @__PURE__ */ jsx5(After, { state, adapter, value: null }) : null
1483
1609
  ] }) }),
1484
- !atBottom ? /* @__PURE__ */ jsxs3("button", { class: "scui-latest", type: "button", onClick: pin, children: [
1485
- /* @__PURE__ */ jsx4(UiIcon, { name: "down", size: 13 }),
1610
+ !atBottom ? /* @__PURE__ */ jsxs4("button", { class: "scui-latest", type: "button", onClick: pin, children: [
1611
+ /* @__PURE__ */ jsx5(UiIcon, { name: "down", size: 13 }),
1486
1612
  " Latest"
1487
1613
  ] }) : null
1488
1614
  ] });
@@ -1490,7 +1616,7 @@ function Conversation({ state, adapter, components = {}, slots = {}, memoryKey =
1490
1616
 
1491
1617
  // src/logo.jsx
1492
1618
  import { useEffect as useEffect4 } from "preact/hooks";
1493
- import { jsx as jsx5, jsxs as jsxs4 } from "preact/jsx-runtime";
1619
+ import { jsx as jsx6, jsxs as jsxs5 } from "preact/jsx-runtime";
1494
1620
  var LOGOS = {
1495
1621
  "claude-code": {
1496
1622
  viewBox: "-1 3.5 26 18",
@@ -1541,30 +1667,30 @@ function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
1541
1667
  if (!logo) onMissingLogo?.(id);
1542
1668
  }, [id, logo, onMissingLogo]);
1543
1669
  if (!logo) return null;
1544
- return /* @__PURE__ */ jsxs4("span", { class: "scui-logo", "data-harness": id, "data-activity": activity, style: `--scui-logo-size:${size}px`, "aria-hidden": "true", children: [
1545
- /* @__PURE__ */ jsx5("svg", { viewBox: logo.viewBox, preserveAspectRatio: "xMidYMid meet", focusable: "false", children: logo.paths.map(([Tag, props], index) => /* @__PURE__ */ jsx5(Tag, { ...props }, index)) }),
1546
- activity && activity !== "idle" ? /* @__PURE__ */ jsx5("i", {}) : null
1670
+ return /* @__PURE__ */ jsxs5("span", { class: "scui-logo", "data-harness": id, "data-activity": activity, style: `--scui-logo-size:${size}px`, "aria-hidden": "true", children: [
1671
+ /* @__PURE__ */ jsx6("svg", { viewBox: logo.viewBox, preserveAspectRatio: "xMidYMid meet", focusable: "false", children: logo.paths.map(([Tag, props], index) => /* @__PURE__ */ jsx6(Tag, { ...props }, index)) }),
1672
+ activity && activity !== "idle" ? /* @__PURE__ */ jsx6("i", {}) : null
1547
1673
  ] });
1548
1674
  }
1549
1675
 
1550
1676
  // src/sessions.jsx
1551
1677
  import { useEffect as useEffect5, useLayoutEffect as useLayoutEffect3, useRef as useRef4, useState as useState3 } from "preact/hooks";
1552
- import { jsx as jsx6, jsxs as jsxs5 } from "preact/jsx-runtime";
1678
+ import { jsx as jsx7, jsxs as jsxs6 } from "preact/jsx-runtime";
1553
1679
  var sessionListMemory = /* @__PURE__ */ new Map();
1554
1680
  function SessionRow({ row, state, onOpen }) {
1555
1681
  const activity = sessionActivity(state, row);
1556
1682
  const attentionPreview = state.attention.find((item) => item.key === row.key)?.preview;
1557
1683
  const title = sessionDisplayName(row);
1558
1684
  const detail = attentionPreview || row.preview || (row.name && row.name !== title ? row.name : row.cwd);
1559
- return /* @__PURE__ */ jsxs5("button", { class: "scui-session", "data-active": row.active, "data-activity": activity, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${row.age ? ` \xB7 ${row.age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
1560
- /* @__PURE__ */ jsx6(HarnessLogo, { id: row.harness, activity, size: 34 }),
1561
- /* @__PURE__ */ jsxs5("span", { class: "scui-session-copy", children: [
1562
- /* @__PURE__ */ jsxs5("span", { children: [
1563
- /* @__PURE__ */ jsx6("strong", { children: title }),
1564
- /* @__PURE__ */ jsx6("small", { children: row.age })
1685
+ return /* @__PURE__ */ jsxs6("button", { class: "scui-session", "data-active": row.active, "data-activity": activity, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${detail ? ` \xB7 ${detail}` : ""}${row.age ? ` \xB7 ${row.age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
1686
+ /* @__PURE__ */ jsx7(HarnessLogo, { id: row.harness, activity, size: 34 }),
1687
+ /* @__PURE__ */ jsxs6("span", { class: "scui-session-copy", children: [
1688
+ /* @__PURE__ */ jsxs6("span", { children: [
1689
+ /* @__PURE__ */ jsx7("strong", { children: title }),
1690
+ /* @__PURE__ */ jsx7("small", { children: row.age })
1565
1691
  ] }),
1566
- detail ? /* @__PURE__ */ jsx6("span", { children: /* @__PURE__ */ jsx6("small", { title: row.cwd, children: detail }) }) : null,
1567
- state.attachError?.key === row.key ? /* @__PURE__ */ jsx6("em", { children: state.attachError.message }) : null
1692
+ detail ? /* @__PURE__ */ jsx7("span", { children: /* @__PURE__ */ jsx7("small", { title: row.cwd, children: detail }) }) : null,
1693
+ state.attachError?.key === row.key ? /* @__PURE__ */ jsx7("em", { children: state.attachError.message }) : null
1568
1694
  ] })
1569
1695
  ] });
1570
1696
  }
@@ -1595,48 +1721,48 @@ function SessionList({ state, adapter, onOpen, onNew, onClose, components = {},
1595
1721
  Promise.resolve(result).then(() => setLoadingMore(false), () => setLoadingMore(false));
1596
1722
  }
1597
1723
  };
1598
- return /* @__PURE__ */ jsxs5("section", { class: "scui-list", ref: root, children: [
1599
- /* @__PURE__ */ jsxs5("header", { class: "scui-head", children: [
1600
- /* @__PURE__ */ jsxs5("span", { class: "scui-head-copy", children: [
1601
- /* @__PURE__ */ jsx6("strong", { children: labels.chats }),
1602
- /* @__PURE__ */ jsxs5("small", { children: [
1724
+ return /* @__PURE__ */ jsxs6("section", { class: "scui-list", ref: root, children: [
1725
+ /* @__PURE__ */ jsxs6("header", { class: "scui-head", children: [
1726
+ /* @__PURE__ */ jsxs6("span", { class: "scui-head-copy", children: [
1727
+ /* @__PURE__ */ jsx7("strong", { children: labels.chats }),
1728
+ /* @__PURE__ */ jsxs6("small", { children: [
1603
1729
  state.sessions.length,
1604
1730
  " recent conversations"
1605
1731
  ] })
1606
1732
  ] }),
1607
- /* @__PURE__ */ jsx6("button", { type: "button", "data-list-focus": "new", "aria-label": labels.newChat, disabled: !state.harnesses.some((item) => item.startable), onClick: onNew, children: /* @__PURE__ */ jsx6(UiIcon, { name: "plus", size: 18 }) }),
1608
- onClose ? /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx6(UiIcon, { name: "close", size: 18 }) }) : null
1733
+ /* @__PURE__ */ jsx7("button", { type: "button", "data-list-focus": "new", "aria-label": labels.newChat, disabled: !state.harnesses.some((item) => item.startable), onClick: onNew, children: /* @__PURE__ */ jsx7(UiIcon, { name: "plus", size: 18 }) }),
1734
+ onClose ? /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx7(UiIcon, { name: "close", size: 18 }) }) : null
1609
1735
  ] }),
1610
- state.startup !== "ready" ? /* @__PURE__ */ jsx6(LoadingStatus, { state, compact: rows.length > 0 }) : null,
1611
- state.sessions.length > 4 ? /* @__PURE__ */ jsxs5("label", { class: "scui-search", children: [
1612
- /* @__PURE__ */ jsx6(UiIcon, { name: "search", size: 15 }),
1613
- /* @__PURE__ */ jsx6("input", { type: "search", "aria-label": labels.searchChats, placeholder: labels.searchChats, value: query, onInput: (event) => {
1736
+ state.startup !== "ready" ? /* @__PURE__ */ jsx7(LoadingStatus, { state, compact: rows.length > 0 }) : null,
1737
+ state.sessions.length > 4 ? /* @__PURE__ */ jsxs6("label", { class: "scui-search", children: [
1738
+ /* @__PURE__ */ jsx7(UiIcon, { name: "search", size: 15 }),
1739
+ /* @__PURE__ */ jsx7("input", { type: "search", "aria-label": labels.searchChats, placeholder: labels.searchChats, value: query, onInput: (event) => {
1614
1740
  const value = event.currentTarget.value;
1615
1741
  setQuery(value);
1616
1742
  boundedSet(sessionListMemory, memoryKey, { query: value, top: 0 });
1617
1743
  if (rowScroller.current) rowScroller.current.scrollTop = 0;
1618
1744
  } }),
1619
- /* @__PURE__ */ jsx6("small", { children: rows.length })
1745
+ /* @__PURE__ */ jsx7("small", { children: rows.length })
1620
1746
  ] }) : null,
1621
- /* @__PURE__ */ jsxs5("div", { class: "scui-session-rows", ref: rowScroller, onScroll: (event) => boundedSet(sessionListMemory, memoryKey, { query, top: event.currentTarget.scrollTop }), children: [
1622
- !rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx6("div", { class: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
1623
- rows.map((row) => /* @__PURE__ */ jsx6(Row, { value: row, row, state, adapter, onOpen }, row.key)),
1624
- state.history.hasMoreSessions ? /* @__PURE__ */ jsx6("button", { class: "scui-load", type: "button", disabled: loadingMore, onClick: loadMore, children: loadingMore ? "Loading older chats\u2026" : "Load older chats" }) : null
1747
+ /* @__PURE__ */ jsxs6("div", { class: "scui-session-rows", ref: rowScroller, onScroll: (event) => boundedSet(sessionListMemory, memoryKey, { query, top: event.currentTarget.scrollTop }), children: [
1748
+ !rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx7("div", { class: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
1749
+ rows.map((row) => /* @__PURE__ */ jsx7(Row, { value: row, row, state, adapter, onOpen }, row.key)),
1750
+ state.history.hasMoreSessions ? /* @__PURE__ */ jsx7("button", { class: "scui-load", type: "button", disabled: loadingMore, onClick: loadMore, children: loadingMore ? "Loading older chats\u2026" : "Load older chats" }) : null
1625
1751
  ] })
1626
1752
  ] });
1627
1753
  }
1628
1754
 
1629
1755
  // src/messenger.jsx
1630
- import { jsx as jsx7, jsxs as jsxs6 } from "preact/jsx-runtime";
1756
+ import { jsx as jsx8, jsxs as jsxs7 } from "preact/jsx-runtime";
1631
1757
  var pendingMessageMemory = /* @__PURE__ */ new Map();
1632
1758
  var messengerViewMemory = /* @__PURE__ */ new Map();
1633
1759
  var newChatMemory = /* @__PURE__ */ new Map();
1634
1760
  var TRACKED_ACTIONS = /* @__PURE__ */ new Set(["resume", "join", "detach", "branch", "reduce", "terminal", "export", "interrupt", "respond", "refresh", "loadEarlier", "loadSessions"]);
1635
1761
  function Receipt({ state, adapter }) {
1636
1762
  const receipt = state.reductionReceipt;
1637
- if (receipt) return /* @__PURE__ */ jsx7("div", { class: "scui-receipt", children: /* @__PURE__ */ jsxs6("span", { children: [
1638
- /* @__PURE__ */ jsx7("strong", { children: "Reduced and verified" }),
1639
- /* @__PURE__ */ jsxs6("small", { children: [
1763
+ if (receipt) return /* @__PURE__ */ jsx8("div", { class: "scui-receipt", children: /* @__PURE__ */ jsxs7("span", { children: [
1764
+ /* @__PURE__ */ jsx8("strong", { children: "Reduced and verified" }),
1765
+ /* @__PURE__ */ jsxs7("small", { children: [
1640
1766
  receipt.sourceTokens.toLocaleString(),
1641
1767
  " \u2192 ",
1642
1768
  receipt.reducedTokens.toLocaleString(),
@@ -1645,27 +1771,27 @@ function Receipt({ state, adapter }) {
1645
1771
  "\xD7 \xB7 reversible"
1646
1772
  ] })
1647
1773
  ] }) });
1648
- if (state.exportReceipt) return /* @__PURE__ */ jsxs6("div", { class: "scui-receipt", children: [
1649
- /* @__PURE__ */ jsxs6("span", { children: [
1650
- /* @__PURE__ */ jsxs6("strong", { children: [
1774
+ if (state.exportReceipt) return /* @__PURE__ */ jsxs7("div", { class: "scui-receipt", children: [
1775
+ /* @__PURE__ */ jsxs7("span", { children: [
1776
+ /* @__PURE__ */ jsxs7("strong", { children: [
1651
1777
  "Lossless export ready \xB7 ",
1652
1778
  harnessDisplayName(state.exportReceipt.targetHarness)
1653
1779
  ] }),
1654
- /* @__PURE__ */ jsxs6("small", { children: [
1780
+ /* @__PURE__ */ jsxs7("small", { children: [
1655
1781
  state.exportReceipt.path,
1656
1782
  " \xB7 ",
1657
1783
  state.exportReceipt.files,
1658
1784
  " files"
1659
1785
  ] })
1660
1786
  ] }),
1661
- /* @__PURE__ */ jsx7("button", { type: "button", onClick: () => adapter.copyText?.(state.exportReceipt.path), children: "Copy path" })
1787
+ /* @__PURE__ */ jsx8("button", { type: "button", onClick: () => adapter.copyText?.(state.exportReceipt.path), children: "Copy path" })
1662
1788
  ] });
1663
- if (state.terminalHandoff) return /* @__PURE__ */ jsxs6("div", { class: "scui-receipt", children: [
1664
- /* @__PURE__ */ jsxs6("span", { children: [
1665
- /* @__PURE__ */ jsx7("strong", { children: "Terminal handoff ready" }),
1666
- /* @__PURE__ */ jsx7("small", { children: state.terminalHandoff.cwd })
1789
+ if (state.terminalHandoff) return /* @__PURE__ */ jsxs7("div", { class: "scui-receipt", children: [
1790
+ /* @__PURE__ */ jsxs7("span", { children: [
1791
+ /* @__PURE__ */ jsx8("strong", { children: "Terminal handoff ready" }),
1792
+ /* @__PURE__ */ jsx8("small", { children: state.terminalHandoff.cwd })
1667
1793
  ] }),
1668
- /* @__PURE__ */ jsx7("button", { type: "button", onClick: () => adapter.copyText?.(terminalCommand(state.terminalHandoff)), children: "Copy command" })
1794
+ /* @__PURE__ */ jsx8("button", { type: "button", onClick: () => adapter.copyText?.(terminalCommand(state.terminalHandoff)), children: "Copy command" })
1669
1795
  ] });
1670
1796
  return null;
1671
1797
  }
@@ -1733,13 +1859,13 @@ function ConversationActions({ state, adapter, actionPending }) {
1733
1859
  const index = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : event.key === "ArrowDown" ? (current + 1) % items.length : (current <= 0 ? items.length : current) - 1;
1734
1860
  items[index].focus({ preventScroll: true });
1735
1861
  };
1736
- return /* @__PURE__ */ jsxs6("div", { class: "scui-menu", ref: root, onBlur: (event) => {
1862
+ return /* @__PURE__ */ jsxs7("div", { class: "scui-menu", ref: root, onBlur: (event) => {
1737
1863
  if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) setOpen(false);
1738
1864
  }, children: [
1739
- /* @__PURE__ */ jsx7("button", { ref: trigger, class: "scui-menu-trigger", type: "button", "aria-label": "Conversation actions", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? menuId : void 0, onClick: () => setOpen((value) => !value), children: /* @__PURE__ */ jsx7(UiIcon, { name: "menu", size: 18 }) }),
1740
- open ? /* @__PURE__ */ jsx7("div", { ref: panel, id: menuId, class: "scui-menu-panel", role: "menu", "aria-label": "Conversation actions", onKeyDown: navigate, children: groups.map((group) => /* @__PURE__ */ jsxs6("section", { role: "group", "aria-label": group.label, children: [
1741
- /* @__PURE__ */ jsx7("strong", { children: group.label }),
1742
- group.items.map((item) => /* @__PURE__ */ jsx7("button", { role: "menuitem", type: "button", disabled: actionPending, onClick: () => dispatch(item.intent), children: item.label }, item.key))
1865
+ /* @__PURE__ */ jsx8("button", { ref: trigger, class: "scui-menu-trigger", type: "button", "aria-label": "Conversation actions", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? menuId : void 0, onClick: () => setOpen((value) => !value), children: /* @__PURE__ */ jsx8(UiIcon, { name: "menu", size: 18 }) }),
1866
+ open ? /* @__PURE__ */ jsx8("div", { ref: panel, id: menuId, class: "scui-menu-panel", role: "menu", "aria-label": "Conversation actions", onKeyDown: navigate, children: groups.map((group) => /* @__PURE__ */ jsxs7("section", { role: "group", "aria-label": group.label, children: [
1867
+ /* @__PURE__ */ jsx8("strong", { children: group.label }),
1868
+ group.items.map((item) => /* @__PURE__ */ jsx8("button", { role: "menuitem", type: "button", disabled: actionPending, onClick: () => dispatch(item.intent), children: item.label }, item.key))
1743
1869
  ] }, group.label)) }) : null
1744
1870
  ] });
1745
1871
  }
@@ -1752,20 +1878,20 @@ function ChatHeader({ state, adapter, pendingStatus, actionPending, onBack, onNe
1752
1878
  useEffect6(() => {
1753
1879
  if (state.mode === "mirror" && !state.canSend) back.current?.focus({ preventScroll: true });
1754
1880
  }, []);
1755
- return /* @__PURE__ */ jsxs6("header", { class: "scui-head scui-chat-head", children: [
1756
- /* @__PURE__ */ jsx7("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx7(UiIcon, { name: "back", size: 18 }) }),
1757
- /* @__PURE__ */ jsx7(HarnessLogo, { id: harness, size: 28 }),
1758
- /* @__PURE__ */ jsxs6("span", { class: "scui-head-copy", children: [
1759
- /* @__PURE__ */ jsx7("strong", { children: title }),
1760
- /* @__PURE__ */ jsxs6("small", { children: [
1881
+ return /* @__PURE__ */ jsxs7("header", { class: "scui-head scui-chat-head", children: [
1882
+ /* @__PURE__ */ jsx8("button", { ref: back, type: "button", "aria-label": "Back to chats", onClick: onBack, children: /* @__PURE__ */ jsx8(UiIcon, { name: "back", size: 18 }) }),
1883
+ /* @__PURE__ */ jsx8(HarnessLogo, { id: harness, size: 28 }),
1884
+ /* @__PURE__ */ jsxs7("span", { class: "scui-head-copy", children: [
1885
+ /* @__PURE__ */ jsx8("strong", { children: title }),
1886
+ /* @__PURE__ */ jsxs7("small", { children: [
1761
1887
  harnessDisplayName(harness),
1762
1888
  " \xB7 ",
1763
1889
  status
1764
1890
  ] })
1765
1891
  ] }),
1766
- menu ? /* @__PURE__ */ jsx7(ConversationActions, { state, adapter, actionPending }) : null,
1767
- /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ jsx7(UiIcon, { name: "plus", size: 18 }) }),
1768
- onClose ? /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx7(UiIcon, { name: "close", size: 18 }) }) : null
1892
+ menu ? /* @__PURE__ */ jsx8(ConversationActions, { state, adapter, actionPending }) : null,
1893
+ /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ jsx8(UiIcon, { name: "plus", size: 18 }) }),
1894
+ onClose ? /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx8(UiIcon, { name: "close", size: 18 }) }) : null
1769
1895
  ] });
1770
1896
  }
1771
1897
  function Chat({ state, adapter, onBack, onNew, onClose, components, slots, labels }) {
@@ -1797,8 +1923,9 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
1797
1923
  if (pending.status === "sending" && state.busy && !pending.seenBusy) setPending({ ...pending, seenBusy: true });
1798
1924
  else if (pending.status === "sending" && state.error && !state.busy && !state.operation && (pending.seenBusy || state.error !== pending.initialError)) setPending({ ...pending, status: "failed" });
1799
1925
  }, [pending, state.busy, state.error, state.operation, state.transcript]);
1800
- const beginPending = (text) => setPending({
1926
+ const beginPending = (text, context = []) => setPending({
1801
1927
  text,
1928
+ context,
1802
1929
  status: "sending",
1803
1930
  initialError: state.error,
1804
1931
  seenBusy: state.busy,
@@ -1806,13 +1933,13 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
1806
1933
  });
1807
1934
  const retryPending = () => {
1808
1935
  if (!pending) return;
1809
- adapter.onIntent({ action: "send", text: pending.text });
1936
+ adapter.onIntent({ action: "send", text: pending.text, ...pending.context?.length ? { context: pending.context } : {} });
1810
1937
  setPending({ ...pending, status: "sending", initialError: state.error, seenBusy: state.busy });
1811
1938
  };
1812
1939
  const editPending = () => {
1813
1940
  if (!pending) return;
1814
1941
  restoreSequence.current += 1;
1815
- setRestoreDraft({ id: restoreSequence.current, text: pending.text });
1942
+ setRestoreDraft({ id: restoreSequence.current, text: pending.text, context: pending.context });
1816
1943
  setPending({ ...pending, status: "editing" });
1817
1944
  };
1818
1945
  useEffect6(() => {
@@ -1858,34 +1985,37 @@ function Chat({ state, adapter, onBack, onNew, onClose, components, slots, label
1858
1985
  setPendingAction(null);
1859
1986
  }
1860
1987
  }, [pendingAction, state.error, state.operation]);
1861
- const pendingMessage = pending && pending.status !== "editing" ? { text: pending.text, status: pending.status, onRetry: retryPending, onEdit: editPending } : null;
1988
+ const pendingMessage = pending && pending.status !== "editing" ? { text: pending.text, context: pending.context, status: pending.status, onRetry: retryPending, onEdit: editPending } : null;
1862
1989
  const action = state.operation || pendingAction?.action || null;
1863
1990
  const actionLabel = operationLabel(action);
1864
1991
  const actionState = action ? { ...state, operation: action, canInterrupt: false, canRespond: false } : state;
1865
1992
  const unreadAfterMessages = state.attention.find((item) => item.key === state.attached?.key)?.afterMessages ?? null;
1866
- return /* @__PURE__ */ jsxs6("section", { class: "scui-chat", children: [
1867
- Header ? /* @__PURE__ */ jsx7(Header, { state: actionState, adapter: trackedAdapter, value: null }) : /* @__PURE__ */ jsx7(ChatHeader, { state: actionState, adapter: trackedAdapter, pendingStatus: pending?.status ?? null, actionPending: Boolean(action), onBack, onNew, onClose }),
1868
- actionLabel ? /* @__PURE__ */ jsxs6("div", { class: "scui-operation", role: "status", children: [
1869
- /* @__PURE__ */ jsx7("i", {}),
1993
+ return /* @__PURE__ */ jsxs7("section", { class: "scui-chat", children: [
1994
+ Header ? /* @__PURE__ */ jsx8(Header, { state: actionState, adapter: trackedAdapter, value: null }) : /* @__PURE__ */ jsx8(ChatHeader, { state: actionState, adapter: trackedAdapter, pendingStatus: pending?.status ?? null, actionPending: Boolean(action), onBack, onNew, onClose }),
1995
+ actionLabel ? /* @__PURE__ */ jsxs7("div", { class: "scui-operation", role: "status", children: [
1996
+ /* @__PURE__ */ jsx8("i", {}),
1870
1997
  actionLabel
1871
1998
  ] }) : null,
1872
- state.error ? /* @__PURE__ */ jsxs6("div", { class: "scui-error", role: "alert", children: [
1873
- /* @__PURE__ */ jsx7("span", { children: state.error }),
1874
- state.recoverable ? /* @__PURE__ */ jsx7("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
1999
+ state.error ? /* @__PURE__ */ jsxs7("div", { class: "scui-error", role: "alert", children: [
2000
+ /* @__PURE__ */ jsx8("span", { children: state.error }),
2001
+ state.recoverable ? /* @__PURE__ */ jsx8("button", { type: "button", disabled: Boolean(action), onClick: () => trackedAdapter.onIntent({ action: "refresh" }), children: "Retry" }) : null
1875
2002
  ] }) : null,
1876
- /* @__PURE__ */ jsx7(Receipt, { state, adapter }),
1877
- /* @__PURE__ */ jsx7(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
1878
- /* @__PURE__ */ jsx7(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
1879
- state.mode !== "mirror" || state.canSend ? /* @__PURE__ */ jsx7(Composer, { state: actionState, adapter: trackedAdapter, labels, memoryKey, pendingStatus: pending?.status ?? null, restoreDraft, onDraftRestored: (id) => setRestoreDraft((value) => value?.id === id ? null : value), onPending: beginPending }, memoryKey) : null
2003
+ /* @__PURE__ */ jsx8(Receipt, { state, adapter }),
2004
+ /* @__PURE__ */ jsx8(Conversation, { state: actionState, adapter: trackedAdapter, components, slots, memoryKey, pending: pendingMessage, unreadAfterMessages }, memoryKey),
2005
+ /* @__PURE__ */ jsx8(ContinuationBar, { state: actionState, adapter: trackedAdapter, labels }),
2006
+ state.mode !== "mirror" || state.canSend ? /* @__PURE__ */ jsx8(Composer, { state: actionState, adapter: trackedAdapter, labels, memoryKey, pendingStatus: pending?.status ?? null, restoreDraft, onDraftRestored: (id) => setRestoreDraft((value) => value?.id === id ? null : value), onPending: beginPending }, memoryKey) : null
1880
2007
  ] });
1881
2008
  }
1882
2009
  function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey }) {
1883
2010
  const startable = state.harnesses.filter((item) => item.startable);
1884
2011
  const startableKey = startable.map((item) => item.id).join("\0");
1885
- const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "" };
2012
+ const remembered = newChatMemory.get(memoryKey) ?? { harness: startable[0]?.id ?? "", draft: "", context: [] };
1886
2013
  const [harness, setHarness] = useState4(remembered.harness);
1887
2014
  const [draft, setDraft] = useState4(remembered.draft);
2015
+ const [context, setContext] = useState4(remembered.context);
1888
2016
  const [starting, setStarting] = useState4(null);
2017
+ const [picking, setPicking] = useState4(false);
2018
+ const [pickerError, setPickerError] = useState4(null);
1889
2019
  const startSequence = useRef5(0);
1890
2020
  const textarea = useRef5(null);
1891
2021
  useAutosizeTextarea(textarea, draft);
@@ -1893,7 +2023,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
1893
2023
  if (startable.some((item) => item.id === harness)) return;
1894
2024
  const next = startable[0]?.id ?? "";
1895
2025
  setHarness(next);
1896
- boundedSet(newChatMemory, memoryKey, { harness: next, draft });
2026
+ boundedSet(newChatMemory, memoryKey, { harness: next, draft, context });
1897
2027
  }, [harness, startableKey]);
1898
2028
  useEffect6(() => {
1899
2029
  if (!starting) return;
@@ -1909,60 +2039,79 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
1909
2039
  useEffect6(() => {
1910
2040
  textarea.current?.focus({ preventScroll: true });
1911
2041
  }, []);
2042
+ const pickContext = () => {
2043
+ if (!adapter.pickContext || picking || context.length >= MAX_CONTEXT_ITEMS) return;
2044
+ setPicking(true);
2045
+ setPickerError(null);
2046
+ Promise.resolve().then(() => adapter.pickContext()).then((picked) => {
2047
+ setContext((current) => {
2048
+ const next = mergeContext(current, picked);
2049
+ boundedSet(newChatMemory, memoryKey, { harness, draft, context: next });
2050
+ return next;
2051
+ });
2052
+ }, (error) => setPickerError(error instanceof Error ? error.message : "Could not attach context.")).finally(() => setPicking(false));
2053
+ };
1912
2054
  const send = () => {
1913
2055
  const text = draft.trim();
1914
2056
  if (!text || !harness || starting) return;
1915
2057
  const id = startSequence.current + 1;
1916
2058
  startSequence.current = id;
1917
2059
  setStarting({ id, attachedKey: state.attached?.key ?? null, busy: state.busy, initialError: state.error });
1918
- const result = adapter.onIntent({ action: "new", harness, text });
2060
+ const result = adapter.onIntent({ action: "new", harness, text, ...context.length ? { context } : {} });
1919
2061
  if (result && typeof result.then === "function") {
1920
2062
  Promise.resolve(result).catch(() => setStarting((current) => current?.id === id ? null : current));
1921
2063
  }
1922
2064
  };
1923
- return /* @__PURE__ */ jsxs6("section", { class: "scui-chat", children: [
1924
- /* @__PURE__ */ jsxs6("header", { class: "scui-head", children: [
1925
- /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Back", onClick: onBack, children: /* @__PURE__ */ jsx7(UiIcon, { name: "back", size: 18 }) }),
1926
- /* @__PURE__ */ jsxs6("span", { class: "scui-head-copy", children: [
1927
- /* @__PURE__ */ jsx7("strong", { children: labels.newChat }),
1928
- /* @__PURE__ */ jsx7("small", { children: "No session is created until you send" })
2065
+ return /* @__PURE__ */ jsxs7("section", { class: "scui-chat", children: [
2066
+ /* @__PURE__ */ jsxs7("header", { class: "scui-head", children: [
2067
+ /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Back", onClick: onBack, children: /* @__PURE__ */ jsx8(UiIcon, { name: "back", size: 18 }) }),
2068
+ /* @__PURE__ */ jsxs7("span", { class: "scui-head-copy", children: [
2069
+ /* @__PURE__ */ jsx8("strong", { children: labels.newChat }),
2070
+ /* @__PURE__ */ jsx8("small", { children: "No session is created until you send" })
1929
2071
  ] }),
1930
- onClose ? /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx7(UiIcon, { name: "close", size: 18 }) }) : null
2072
+ onClose ? /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Close", onClick: onClose, children: /* @__PURE__ */ jsx8(UiIcon, { name: "close", size: 18 }) }) : null
1931
2073
  ] }),
1932
- starting ? /* @__PURE__ */ jsxs6("div", { class: "scui-operation", role: "status", children: [
1933
- /* @__PURE__ */ jsx7("i", {}),
2074
+ starting ? /* @__PURE__ */ jsxs7("div", { class: "scui-operation", role: "status", children: [
2075
+ /* @__PURE__ */ jsx8("i", {}),
1934
2076
  operationLabel("start")
1935
2077
  ] }) : null,
1936
- /* @__PURE__ */ jsxs6("div", { class: "scui-new", children: [
1937
- /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u2726" }),
1938
- /* @__PURE__ */ jsx7("strong", { children: "What should the agent build or fix?" }),
1939
- /* @__PURE__ */ jsx7("small", { children: "Choose a coding harness and send the first message." })
2078
+ /* @__PURE__ */ jsxs7("div", { class: "scui-new", children: [
2079
+ /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: "\u2726" }),
2080
+ /* @__PURE__ */ jsx8("strong", { children: "What should the agent build or fix?" }),
2081
+ /* @__PURE__ */ jsx8("small", { children: "Choose a coding harness and send the first message." })
1940
2082
  ] }),
1941
- /* @__PURE__ */ jsxs6("div", { class: "scui-compose", children: [
1942
- /* @__PURE__ */ jsxs6("label", { class: "scui-harness-picker", children: [
1943
- /* @__PURE__ */ jsx7(HarnessLogo, { id: harness, size: 24 }),
1944
- /* @__PURE__ */ jsx7("span", { children: "Coding harness" }),
1945
- /* @__PURE__ */ jsx7("select", { value: harness, disabled: Boolean(starting), onChange: (event) => {
2083
+ /* @__PURE__ */ jsxs7("div", { class: "scui-compose", children: [
2084
+ /* @__PURE__ */ jsxs7("label", { class: "scui-harness-picker", children: [
2085
+ /* @__PURE__ */ jsx8(HarnessLogo, { id: harness, size: 24 }),
2086
+ /* @__PURE__ */ jsx8("span", { children: "Coding harness" }),
2087
+ /* @__PURE__ */ jsx8("select", { value: harness, disabled: Boolean(starting), onChange: (event) => {
1946
2088
  const value = event.currentTarget.value;
1947
2089
  setHarness(value);
1948
- boundedSet(newChatMemory, memoryKey, { harness: value, draft });
1949
- }, children: state.harnesses.map((item) => /* @__PURE__ */ jsxs6("option", { value: item.id, disabled: !item.startable, children: [
2090
+ boundedSet(newChatMemory, memoryKey, { harness: value, draft, context });
2091
+ }, children: state.harnesses.map((item) => /* @__PURE__ */ jsxs7("option", { value: item.id, disabled: !item.startable, children: [
1950
2092
  item.label,
1951
2093
  item.startable ? "" : " \xB7 unavailable"
1952
2094
  ] }, item.id)) })
1953
2095
  ] }),
1954
- /* @__PURE__ */ jsxs6("div", { class: "scui-envelope", children: [
1955
- /* @__PURE__ */ jsx7("textarea", { ref: textarea, rows: 3, "aria-label": "Message coding agent", placeholder: startable.length ? "What should the agent do?" : "No coding harness is available", value: draft, disabled: !startable.length || Boolean(starting), onInput: (event) => {
2096
+ /* @__PURE__ */ jsx8(ContextTray, { items: context, onRemove: (index) => setContext((items) => {
2097
+ const next = items.filter((_, itemIndex) => itemIndex !== index);
2098
+ boundedSet(newChatMemory, memoryKey, { harness, draft, context: next });
2099
+ return next;
2100
+ }) }),
2101
+ pickerError ? /* @__PURE__ */ jsx8("small", { class: "scui-context-error", role: "alert", children: pickerError }) : null,
2102
+ /* @__PURE__ */ jsxs7("div", { class: "scui-envelope", children: [
2103
+ adapter.pickContext ? /* @__PURE__ */ jsx8("button", { class: "scui-attach", type: "button", "aria-label": "Attach context", disabled: picking || context.length >= MAX_CONTEXT_ITEMS || Boolean(starting), onClick: pickContext, children: picking ? /* @__PURE__ */ jsx8("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx8(UiIcon, { name: "attach", size: 17 }) }) : null,
2104
+ /* @__PURE__ */ jsx8("textarea", { ref: textarea, rows: 3, "aria-label": "Message coding agent", placeholder: startable.length ? "What should the agent do?" : "No coding harness is available", value: draft, disabled: !startable.length || Boolean(starting), onInput: (event) => {
1956
2105
  const value = event.currentTarget.value;
1957
2106
  setDraft(value);
1958
- boundedSet(newChatMemory, memoryKey, { harness, draft: value });
2107
+ boundedSet(newChatMemory, memoryKey, { harness, draft: value, context });
1959
2108
  }, onKeyDown: (event) => {
1960
2109
  if (isSendKey(event)) {
1961
2110
  event.preventDefault();
1962
2111
  send();
1963
2112
  }
1964
2113
  } }),
1965
- /* @__PURE__ */ jsx7("span", { children: /* @__PURE__ */ jsx7("button", { type: "button", class: "scui-send", "aria-label": "Start chat", disabled: !draft.trim() || !harness || Boolean(starting), onClick: send, children: starting ? /* @__PURE__ */ jsx7("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx7(UiIcon, { name: "send", size: 17 }) }) })
2114
+ /* @__PURE__ */ jsx8("span", { children: /* @__PURE__ */ jsx8("button", { type: "button", class: "scui-send", "aria-label": "Start chat", disabled: !draft.trim() || !harness || Boolean(starting), onClick: send, children: starting ? /* @__PURE__ */ jsx8("i", { class: "scui-control-spinner" }) : /* @__PURE__ */ jsx8(UiIcon, { name: "send", size: 17 }) }) })
1966
2115
  ] })
1967
2116
  ] })
1968
2117
  ] });
@@ -1994,40 +2143,40 @@ function SupercodeMessenger({ state: stateInput, adapter, class: className = "",
1994
2143
  };
1995
2144
  const close = () => adapter.onClose?.();
1996
2145
  const Footer = slots.footer;
1997
- return /* @__PURE__ */ jsxs6("main", { class: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
1998
- view === "list" ? /* @__PURE__ */ jsx7(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
2146
+ return /* @__PURE__ */ jsxs7("main", { class: `scui-root ${className}`, "data-view": view, "data-mode": state.mode, "aria-label": "Supercode messenger", children: [
2147
+ view === "list" ? /* @__PURE__ */ jsx8(SessionList, { state, adapter, focusKey: listFocus, onOpen: open, onNew: () => {
1999
2148
  setListFocus("@new");
2000
2149
  setView("new");
2001
2150
  }, onClose: adapter.onClose ? close : void 0, components, labels: copy, memoryKey }) : null,
2002
- view === "new" ? /* @__PURE__ */ jsx7(NewChat, { state, adapter, onBack: () => setView("list"), onClose: adapter.onClose ? close : void 0, onStarted: () => setView("chat"), labels: copy, memoryKey }) : null,
2003
- view === "chat" ? /* @__PURE__ */ jsx7(Chat, { state, adapter, onBack: () => {
2151
+ view === "new" ? /* @__PURE__ */ jsx8(NewChat, { state, adapter, onBack: () => setView("list"), onClose: adapter.onClose ? close : void 0, onStarted: () => setView("chat"), labels: copy, memoryKey }) : null,
2152
+ view === "chat" ? /* @__PURE__ */ jsx8(Chat, { state, adapter, onBack: () => {
2004
2153
  setListFocus(state.attached?.key ?? listFocus);
2005
2154
  setView("list");
2006
2155
  }, onNew: () => {
2007
2156
  setListFocus("@new");
2008
2157
  setView("new");
2009
2158
  }, onClose: adapter.onClose ? close : void 0, components, slots, labels: copy }) : null,
2010
- opening ? /* @__PURE__ */ jsxs6("div", { class: "scui-opening", role: "status", "aria-busy": "true", children: [
2011
- /* @__PURE__ */ jsx7(HarnessLogo, { id: opening.harness, size: 34 }),
2012
- /* @__PURE__ */ jsxs6("span", { children: [
2013
- /* @__PURE__ */ jsxs6("strong", { children: [
2159
+ opening ? /* @__PURE__ */ jsxs7("div", { class: "scui-opening", role: "status", "aria-busy": "true", children: [
2160
+ /* @__PURE__ */ jsx8(HarnessLogo, { id: opening.harness, size: 34 }),
2161
+ /* @__PURE__ */ jsxs7("span", { children: [
2162
+ /* @__PURE__ */ jsxs7("strong", { children: [
2014
2163
  "Opening ",
2015
2164
  sessionDisplayName(opening)
2016
2165
  ] }),
2017
- /* @__PURE__ */ jsx7("small", { children: "Loading the latest transcript window\u2026" })
2166
+ /* @__PURE__ */ jsx8("small", { children: "Loading the latest transcript window\u2026" })
2018
2167
  ] }),
2019
- /* @__PURE__ */ jsx7("i", {})
2168
+ /* @__PURE__ */ jsx8("i", {})
2020
2169
  ] }) : null,
2021
- Footer ? /* @__PURE__ */ jsx7(Footer, { state, adapter, value: copy }) : null
2170
+ Footer ? /* @__PURE__ */ jsx8(Footer, { state, adapter, value: copy }) : null
2022
2171
  ] });
2023
2172
  }
2024
2173
 
2025
2174
  // src/embed.jsx
2026
- import { jsx as jsx8 } from "preact/jsx-runtime";
2175
+ import { jsx as jsx9 } from "preact/jsx-runtime";
2027
2176
  function mountSupercodeMessenger(element, options) {
2028
2177
  if (!(element instanceof Element)) throw new TypeError("mountSupercodeMessenger requires an Element");
2029
2178
  let state = options.state;
2030
- const draw = () => render(/* @__PURE__ */ jsx8(SupercodeMessenger, { ...options, state }), element);
2179
+ const draw = () => render(/* @__PURE__ */ jsx9(SupercodeMessenger, { ...options, state }), element);
2031
2180
  options.adapter.onIntent({ action: "mounted" });
2032
2181
  draw();
2033
2182
  return {