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