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