@volter-ai-dev/supercode-ui 0.1.44 → 0.1.46

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.
@@ -566,6 +566,7 @@ function readSessions(value) {
566
566
  updatedAt: nullableNumber(row.updatedAt),
567
567
  messages: nullableNumber(row.messages),
568
568
  active: row.active === true,
569
+ writable: row.writable === true,
569
570
  live: row.live === true,
570
571
  runtimeStatus: row.runtimeStatus === "running" || row.runtimeStatus === "busy" || row.runtimeStatus === "idle" ? row.runtimeStatus : null
571
572
  }];
@@ -750,7 +751,7 @@ function normalizeUiState(value) {
750
751
  if (!item || typeof item.id !== "string") return [];
751
752
  const startable = item.startable === true;
752
753
  const launchModes = Array.isArray(item.launchModes) ? [...new Set(item.launchModes.filter((mode) => mode === "headless" || mode === "terminal"))] : startable ? ["headless"] : [];
753
- const preferredLaunchMode = launchModes.includes(item.preferredLaunchMode) ? item.preferredLaunchMode : launchModes[0] ?? null;
754
+ const preferredLaunchMode = launchModes.includes(item.preferredLaunchMode) ? item.preferredLaunchMode : launchModes.includes("terminal") ? "terminal" : launchModes[0] ?? null;
754
755
  const capabilities = record(item.capabilities);
755
756
  return [{
756
757
  id: item.id,
@@ -795,6 +796,7 @@ function sessionDisplayName(session) {
795
796
  return title && title !== session.name ? title : session.name || "Untitled chat";
796
797
  }
797
798
  function sessionActivity(state, row) {
799
+ if (!row.writable) return "observed";
798
800
  if (state.needsInput && row.active) return "needs-input";
799
801
  if (state.busy && row.active) return "working";
800
802
  if (row.runtimeStatus === "busy") return "working";
@@ -812,6 +814,7 @@ var ACTIVITY_PRIORITY = Object.freeze({
812
814
  finished: 30,
813
815
  running: 20,
814
816
  recent: 10,
817
+ observed: 0,
815
818
  idle: 0
816
819
  });
817
820
  function filterSessions(rows, query) {
@@ -1257,13 +1260,23 @@ function useAutosizeTextarea(ref, value) {
1257
1260
  // src/composer.jsx
1258
1261
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1259
1262
  var composerMemory = /* @__PURE__ */ new Map();
1263
+ function ExecutionModeSelect({ modes = [], value, onChange, disabled = false, label = "Run in" }) {
1264
+ if (modes.length < 2) return null;
1265
+ return /* @__PURE__ */ jsxs3("label", { className: "scui-execution-mode", title: disabled ? void 0 : `${label}: ${value}`, children: [
1266
+ /* @__PURE__ */ jsx3("span", { children: label }),
1267
+ /* @__PURE__ */ jsx3("select", { "aria-label": label, value, disabled, onChange: (event) => onChange?.(event.currentTarget.value), children: modes.map((mode) => /* @__PURE__ */ jsx3("option", { value: mode, children: mode === "terminal" ? "Terminal" : "Headless" }, mode)) })
1268
+ ] });
1269
+ }
1260
1270
  function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1271
+ const continuationModes = state.continuationModes?.length ? state.continuationModes : ["headless"];
1272
+ const [selection, setSelection] = useState2({ key: null, mode: null });
1273
+ const requestedMode = selection.key === state.attached?.key ? selection.mode : null;
1274
+ const executionMode = continuationModes.includes(requestedMode) ? requestedMode : continuationModes.includes("terminal") ? "terminal" : continuationModes[0];
1261
1275
  if (state.mode !== "mirror" || state.canSend) return null;
1262
1276
  const attached = state.attached;
1263
1277
  const row = attached?.key ? state.sessions.find((item) => item.key === attached.key) : null;
1264
1278
  const activeElsewhere = row?.runtimeStatus === "running" || row?.runtimeStatus === "busy" || row?.runtimeStatus === "idle";
1265
1279
  const resume = canContinueHere(state);
1266
- const terminal = resume && state.continuationModes?.includes("terminal");
1267
1280
  const join = state.canAttach;
1268
1281
  const branch = state.canBranch;
1269
1282
  if (!resume && !join && !branch) return /* @__PURE__ */ jsx3("div", { className: "scui-continuation", children: /* @__PURE__ */ jsxs3("span", { children: [
@@ -1276,8 +1289,8 @@ function ContinuationBar({ state, adapter, labels = DEFAULT_LABELS }) {
1276
1289
  /* @__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." })
1277
1290
  ] }),
1278
1291
  /* @__PURE__ */ jsxs3("span", { className: "scui-continuation-actions", children: [
1279
- /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: "headless" } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere }),
1280
- terminal ? /* @__PURE__ */ jsx3("button", { type: "button", className: "scui-secondary", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, { action: "resume", mode: "terminal" }), children: labels.continueWithTerminal ?? DEFAULT_LABELS.continueWithTerminal }) : null
1292
+ !join && resume ? /* @__PURE__ */ jsx3(ExecutionModeSelect, { modes: continuationModes, value: executionMode, disabled: Boolean(state.operation), onChange: (mode) => setSelection({ key: state.attached?.key ?? null, mode }) }) : null,
1293
+ /* @__PURE__ */ jsx3("button", { type: "button", disabled: Boolean(state.operation), onClick: () => dispatchConfirmedIntent(adapter, join ? { action: "join" } : resume ? { action: "resume", mode: executionMode } : { action: "branch" }), children: join ? labels.joinLive : resume ? labels.continueHere : labels.forkHere })
1281
1294
  ] })
1282
1295
  ] });
1283
1296
  }
@@ -2206,7 +2219,7 @@ function SessionRow({ row, state, onOpen, now = Date.now() }) {
2206
2219
  const unreadCount = attention?.unreadCount ?? 0;
2207
2220
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
2208
2221
  const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
2209
- return /* @__PURE__ */ jsxs6("button", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
2222
+ return /* @__PURE__ */ jsxs6("button", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${row.writable ? "" : " \xB7 Read-only"}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
2210
2223
  /* @__PURE__ */ jsx7(HarnessLogo, { id: row.harness, activity, size: 34 }),
2211
2224
  /* @__PURE__ */ jsxs6("span", { className: "scui-session-copy", children: [
2212
2225
  /* @__PURE__ */ jsxs6("span", { className: "scui-session-title", children: [
@@ -2787,7 +2800,8 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
2787
2800
  const Readiness = components.HarnessReadiness ?? HarnessReadiness;
2788
2801
  const launchModes = selectedHarness?.launchModes?.length ? selectedHarness.launchModes : ["headless"];
2789
2802
  const rememberedMode = modes[harness];
2790
- const mode = launchModes.includes(rememberedMode) ? rememberedMode : launchModes.includes(selectedHarness?.preferredLaunchMode) ? selectedHarness.preferredLaunchMode : launchModes[0];
2803
+ const requestedMode = launchModes.includes(rememberedMode) ? rememberedMode : launchModes.includes(selectedHarness?.preferredLaunchMode) ? selectedHarness.preferredLaunchMode : launchModes[0];
2804
+ const mode = (context.length > 0 || images.length > 0) && launchModes.includes("headless") ? "headless" : requestedMode;
2791
2805
  const terminalAttachments = mode === "terminal" && (context.length > 0 || images.length > 0);
2792
2806
  const remember = (overrides = {}) => boundedSet(newChatMemory, memoryKey, { harness, draft, context, images, modes, ...overrides });
2793
2807
  useAutosizeTextarea(textarea, draft);
@@ -2829,7 +2843,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
2829
2843
  lastComposerCommand.current = composerCommand.id;
2830
2844
  if (composerCommand.action === "attach") {
2831
2845
  if (mode === "terminal" && !launchModes.includes("headless")) {
2832
- setPickerError("Terminal starts currently accept text only. Choose Chat to attach context or images.");
2846
+ setPickerError("Terminal starts currently accept text only. Choose Headless to attach context or images.");
2833
2847
  } else {
2834
2848
  try {
2835
2849
  const attachments = partitionAttachments(composerCommand.attachments);
@@ -2837,12 +2851,10 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
2837
2851
  if (images.length + attachments.images.length > MAX_IMAGE_ITEMS) throw new Error(`Attach at most ${MAX_IMAGE_ITEMS} images.`);
2838
2852
  const nextContext = mergeContext(context, attachments.context);
2839
2853
  const nextImages = mergeImages(images, attachments.images);
2840
- const nextModes = mode === "terminal" ? { ...modes, [harness]: "headless" } : modes;
2841
- if (nextModes !== modes) setModes(nextModes);
2842
2854
  setContext(nextContext);
2843
2855
  setImages(nextImages);
2844
2856
  setPickerError(null);
2845
- remember({ context: nextContext, images: nextImages, modes: nextModes });
2857
+ remember({ context: nextContext, images: nextImages });
2846
2858
  } catch (error) {
2847
2859
  setPickerError(error instanceof Error ? error.message : "Could not attach context.");
2848
2860
  }
@@ -2883,7 +2895,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
2883
2895
  const allFiles = Array.from(value ?? []);
2884
2896
  if (!allFiles.length) return false;
2885
2897
  if (mode === "terminal") {
2886
- setPickerError("Terminal starts currently accept text only. Choose Chat to attach context or images.");
2898
+ setPickerError("Terminal starts currently accept text only. Choose Headless to attach context or images.");
2887
2899
  return true;
2888
2900
  }
2889
2901
  const files = allFiles.filter((file) => file.type.startsWith("image/"));
@@ -2948,21 +2960,6 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
2948
2960
  ] }),
2949
2961
  /* @__PURE__ */ jsxs8("div", { className: "scui-compose", children: [
2950
2962
  /* @__PURE__ */ jsx9(Readiness, { harnesses: state.harnesses, state, adapter }),
2951
- launchModes.length > 1 ? /* @__PURE__ */ jsxs8("fieldset", { className: "scui-launch-modes", disabled: Boolean(starting), children: [
2952
- /* @__PURE__ */ jsx9("legend", { children: "Run as" }),
2953
- launchModes.map((item) => /* @__PURE__ */ jsxs8("label", { children: [
2954
- /* @__PURE__ */ jsx9("input", { type: "radio", name: `launch-mode-${memoryKey}`, value: item, checked: mode === item, onChange: () => {
2955
- const next = { ...modes, [harness]: item };
2956
- setModes(next);
2957
- setPickerError(null);
2958
- remember({ modes: next });
2959
- } }),
2960
- /* @__PURE__ */ jsxs8("span", { children: [
2961
- /* @__PURE__ */ jsx9("strong", { children: item === "terminal" ? "Terminal" : "Chat" }),
2962
- /* @__PURE__ */ jsx9("small", { children: item === "terminal" ? "Interactive tmux session" : "Managed here" })
2963
- ] })
2964
- ] }, item))
2965
- ] }) : null,
2966
2963
  mode !== "terminal" ? /* @__PURE__ */ jsx9(ContextCandidates, { items: contextCandidates, context, images, state, adapter, onAttach: attachCandidate, component: components.ContextCandidate }) : null,
2967
2964
  /* @__PURE__ */ jsx9(ImageTray, { items: images, onRemove: (index) => setImages((items) => {
2968
2965
  const next = items.filter((_, itemIndex) => itemIndex !== index);
@@ -2974,7 +2971,7 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
2974
2971
  remember({ context: next });
2975
2972
  return next;
2976
2973
  }) }),
2977
- terminalAttachments ? /* @__PURE__ */ jsx9("small", { className: "scui-context-error", role: "alert", children: "Terminal starts currently accept text only. Remove attachments or choose Chat." }) : pickerError ? /* @__PURE__ */ jsx9("small", { className: "scui-context-error", role: "alert", children: pickerError }) : null,
2974
+ terminalAttachments ? /* @__PURE__ */ jsx9("small", { className: "scui-context-error", role: "alert", children: "Terminal starts currently accept text only. Remove attachments or choose Headless." }) : pickerError ? /* @__PURE__ */ jsx9("small", { className: "scui-context-error", role: "alert", children: pickerError }) : null,
2978
2975
  /* @__PURE__ */ jsxs8("div", { className: `scui-envelope scui-new-envelope${dragging ? " scui-drop-target" : ""}`, onDragEnter: (event) => {
2979
2976
  if (Array.from(event.dataTransfer?.types ?? []).includes("Files")) {
2980
2977
  event.preventDefault();
@@ -3001,7 +2998,13 @@ function NewChat({ state, adapter, onBack, onClose, onStarted, labels, memoryKey
3001
2998
  setHarness(value);
3002
2999
  remember({ harness: value });
3003
3000
  } }),
3004
- /* @__PURE__ */ jsx9("span", { children: /* @__PURE__ */ jsx9("button", { type: "button", className: "scui-send", "aria-label": mode === "terminal" ? "Start terminal session" : "Start chat", disabled: !draft.trim() && !images.length || !harness || Boolean(starting) || terminalAttachments || mode === "terminal" && !draft.trim(), onClick: send, children: starting ? /* @__PURE__ */ jsx9("i", { className: "scui-control-spinner" }) : /* @__PURE__ */ jsx9(UiIcon, { name: "send", size: 17 }) }) })
3001
+ /* @__PURE__ */ jsx9(ExecutionModeSelect, { modes: launchModes, value: mode, disabled: Boolean(starting) || mode !== requestedMode, onChange: (item) => {
3002
+ const next = { ...modes, [harness]: item };
3003
+ setModes(next);
3004
+ setPickerError(null);
3005
+ remember({ modes: next });
3006
+ } }),
3007
+ /* @__PURE__ */ jsx9("span", { children: /* @__PURE__ */ jsx9("button", { type: "button", className: "scui-send", "aria-label": mode === "terminal" ? "Start terminal session" : "Start headless session", disabled: !draft.trim() && !images.length || !harness || Boolean(starting) || terminalAttachments || mode === "terminal" && !draft.trim(), onClick: send, children: starting ? /* @__PURE__ */ jsx9("i", { className: "scui-control-spinner" }) : /* @__PURE__ */ jsx9(UiIcon, { name: "send", size: 17 }) }) })
3005
3008
  ] })
3006
3009
  ] })
3007
3010
  ] })
@@ -83,6 +83,7 @@ function sessionDisplayName(session) {
83
83
  return title && title !== session.name ? title : session.name || "Untitled chat";
84
84
  }
85
85
  function sessionActivity(state, row) {
86
+ if (!row.writable) return "observed";
86
87
  if (state.needsInput && row.active) return "needs-input";
87
88
  if (state.busy && row.active) return "working";
88
89
  if (row.runtimeStatus === "busy") return "working";
@@ -100,6 +101,7 @@ var ACTIVITY_PRIORITY = Object.freeze({
100
101
  finished: 30,
101
102
  running: 20,
102
103
  recent: 10,
104
+ observed: 0,
103
105
  idle: 0
104
106
  });
105
107
  function filterSessions(rows, query) {
@@ -332,7 +334,7 @@ function SessionRow({ row, state, onOpen, now = Date.now() }) {
332
334
  const unreadCount = attention?.unreadCount ?? 0;
333
335
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
334
336
  const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
335
- return /* @__PURE__ */ jsxs5("button", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
337
+ return /* @__PURE__ */ jsxs5("button", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${row.writable ? "" : " \xB7 Read-only"}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
336
338
  /* @__PURE__ */ jsx6(HarnessLogo, { id: row.harness, activity, size: 34 }),
337
339
  /* @__PURE__ */ jsxs5("span", { className: "scui-session-copy", children: [
338
340
  /* @__PURE__ */ jsxs5("span", { className: "scui-session-title", children: [
@@ -77,6 +77,7 @@ var ACTIVITY_PRIORITY = Object.freeze({
77
77
  finished: 30,
78
78
  running: 20,
79
79
  recent: 10,
80
+ observed: 0,
80
81
  idle: 0
81
82
  });
82
83
 
package/sessions.mjs CHANGED
@@ -83,6 +83,7 @@ function sessionDisplayName(session) {
83
83
  return title && title !== session.name ? title : session.name || "Untitled chat";
84
84
  }
85
85
  function sessionActivity(state, row) {
86
+ if (!row.writable) return "observed";
86
87
  if (state.needsInput && row.active) return "needs-input";
87
88
  if (state.busy && row.active) return "working";
88
89
  if (row.runtimeStatus === "busy") return "working";
@@ -100,6 +101,7 @@ var ACTIVITY_PRIORITY = Object.freeze({
100
101
  finished: 30,
101
102
  running: 20,
102
103
  recent: 10,
104
+ observed: 0,
103
105
  idle: 0
104
106
  });
105
107
  function filterSessions(rows, query) {
@@ -332,7 +334,7 @@ function SessionRow({ row, state, onOpen, now = Date.now() }) {
332
334
  const unreadCount = attention?.unreadCount ?? 0;
333
335
  const unreadLabel = unreadCount > 99 ? "99+" : String(unreadCount);
334
336
  const age = relativeAge(row.previewUpdatedAt ?? row.updatedAt, now) || row.age;
335
- return /* @__PURE__ */ jsxs5("button", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
337
+ return /* @__PURE__ */ jsxs5("button", { className: "scui-session", "data-active": row.active, "data-activity": activity, "data-writable": row.writable, "data-session-key": row.key, type: "button", "aria-label": `${title} \xB7 ${harnessDisplayName(row.harness)}${row.writable ? "" : " \xB7 Read-only"}${working ? " \xB7 Working" : ""}${path.complete ? ` \xB7 ${path.complete}` : ""}${preview ? ` \xB7 ${preview}` : ""}${unreadCount ? ` \xB7 ${unreadCount} unread` : ""}${age ? ` \xB7 ${age}` : ""}`, "aria-current": row.active ? "true" : void 0, onClick: () => onOpen(row), children: [
336
338
  /* @__PURE__ */ jsx6(HarnessLogo, { id: row.harness, activity, size: 34 }),
337
339
  /* @__PURE__ */ jsxs5("span", { className: "scui-session-copy", children: [
338
340
  /* @__PURE__ */ jsxs5("span", { className: "scui-session-title", children: [
package/settings.mjs CHANGED
@@ -77,6 +77,7 @@ var ACTIVITY_PRIORITY = Object.freeze({
77
77
  finished: 30,
78
78
  running: 20,
79
79
  recent: 10,
80
+ observed: 0,
80
81
  idle: 0
81
82
  });
82
83
 
package/styles.css CHANGED
@@ -73,6 +73,7 @@
73
73
  .scui-logo[data-harness="pi"] { color:#111; background:#efefeb }
74
74
  .scui-logo[data-harness="supercode"] { background:#111923 }
75
75
  .scui-logo > i { position:absolute; right:-5%; bottom:-5%; width:32%; height:32%; border:2px solid var(--scui-bg); border-radius:50%; background:var(--scui-muted) }
76
+ .scui-logo[data-activity="observed"] > i { background:var(--scui-muted) }
76
77
  .scui-logo[data-activity="working"] > i,.scui-logo[data-activity="running"] > i { background:var(--scui-positive) }
77
78
  .scui-logo[data-activity="needs-input"] > i { background:var(--scui-warning) }
78
79
  .scui-logo[data-activity="failed"] > i { background:var(--scui-danger) }
@@ -185,7 +186,7 @@
185
186
  .scui-plan > summary { display:flex; justify-content:space-between; padding:6px 8px; border:1px solid var(--scui-border); border-radius:7px; background:var(--scui-bg-raised) }.scui-plan ol { display:grid; gap:4px; box-sizing:border-box; max-height:140px; margin:5px 0 0; padding:7px 8px 7px 25px; overflow:auto; border:1px solid var(--scui-border); border-radius:7px }.scui-plan li[data-status="completed"] { color:var(--scui-fg); text-decoration:line-through }
186
187
  .scui-working { display:flex; align-items:center; gap:4px; color:var(--scui-muted) }.scui-working > span { color:var(--scui-accent) }.scui-working > i { width:4px; height:4px; border-radius:50%; background:currentColor; animation:scui-dots 1.2s infinite }.scui-working > i:nth-of-type(2) { animation-delay:.15s }.scui-working > i:nth-of-type(3) { animation-delay:.3s }
187
188
 
188
- .scui-continuation { display:flex; align-items:center; gap:8px; padding:7px 9px; border-top:1px solid var(--scui-border); background:var(--scui-bg-raised) }.scui-continuation > span:not(.scui-continuation-actions) { display:grid; flex:1 }.scui-continuation small { color:var(--scui-muted); font-size:10px }.scui-continuation-actions { display:flex; align-items:center; gap:5px; flex-wrap:wrap; justify-content:flex-end }.scui-continuation button { padding:5px 8px; border:1px solid var(--scui-accent); border-radius:7px; background:transparent; color:var(--scui-accent); cursor:pointer; white-space:nowrap }.scui-continuation button.scui-secondary { border-color:var(--scui-border-strong); color:var(--scui-fg) }
189
+ .scui-continuation { display:flex; align-items:center; gap:8px; padding:7px 9px; border-top:1px solid var(--scui-border); background:var(--scui-bg-raised) }.scui-continuation > span:not(.scui-continuation-actions) { display:grid; flex:1 }.scui-continuation small { color:var(--scui-muted); font-size:10px }.scui-continuation-actions { display:flex; align-items:center; gap:5px; flex-wrap:wrap; justify-content:flex-end }.scui-continuation button { padding:5px 8px; border:1px solid var(--scui-accent); border-radius:7px; background:transparent; color:var(--scui-accent); cursor:pointer; white-space:nowrap }
189
190
  .scui-compose { flex:none; padding:8px; border-top:1px solid var(--scui-border); background:var(--scui-bg-raised) }
190
191
  .scui-context-candidates { display:flex; gap:5px; margin-bottom:6px; overflow-x:auto; padding:1px; scrollbar-width:thin }.scui-context-candidates > button { display:grid; grid-template-columns:auto minmax(0,1fr) auto; flex:0 0 auto; width:min(180px,55vw); min-height:34px; align-items:center; gap:6px; padding:4px 6px; border:1px solid var(--scui-border); border-radius:7px; background:var(--scui-bg); color:var(--scui-fg); text-align:left; cursor:pointer }.scui-context-candidates > button:hover:not(:disabled) { border-color:var(--scui-border-strong); background:var(--scui-fill) }.scui-context-candidates > button:disabled { cursor:default; opacity:.58 }.scui-context-candidates img { width:24px; height:24px; border-radius:4px; object-fit:cover }.scui-context-candidates span { display:grid; min-width:0 }.scui-context-candidates strong,.scui-context-candidates small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-context-candidates strong { font-size:10px }.scui-context-candidates small { color:var(--scui-muted); font-size:8.5px }
191
192
  .scui-envelope { display:flex; align-items:flex-end; gap:7px; padding:7px; border:1px solid var(--scui-border-strong); border-radius:16px; background:var(--scui-bg) }.scui-envelope textarea { flex:1; min-width:0; min-height:34px; max-height:150px; resize:none; overflow-y:hidden; border:0; outline:0; background:transparent; color:var(--scui-fg) }.scui-envelope > span { display:flex; gap:4px }
@@ -199,11 +200,11 @@
199
200
  .scui-queue-send { display:grid; width:29px; height:29px; padding:0; place-items:center; border:0; border-radius:8px; background:transparent; color:var(--scui-muted); cursor:pointer }.scui-queue-send:hover { background:var(--scui-fill); color:var(--scui-fg) }
200
201
  .scui-queue { display:grid; gap:4px; max-height:85px; margin-bottom:6px; overflow:auto; font-size:10.5px }.scui-queue > span { display:flex; gap:6px; padding:4px 6px; border-radius:5px; background:var(--scui-fill) }.scui-queue > span > span { display:grid; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-queue small { color:var(--scui-muted) }.scui-queue > span button { margin-left:auto; border:0; background:transparent }
201
202
  .scui-new-envelope { display:grid; align-items:stretch; gap:3px; padding:7px }.scui-new-envelope textarea { box-sizing:border-box; width:100%; min-height:54px; padding:2px 3px }.scui-new-envelope-controls { display:flex; min-width:0; align-items:center; gap:3px }.scui-new-envelope-controls > span { display:flex; margin-left:auto }.scui-new-envelope-controls .scui-attach { flex-basis:29px; width:29px; height:29px }
203
+ .scui-execution-mode { position:relative; display:flex; flex:none; height:29px; align-items:center; border-radius:8px; color:var(--scui-muted) }.scui-execution-mode > span { position:absolute; overflow:hidden; width:1px; height:1px; clip:rect(0 0 0 0); white-space:nowrap }.scui-execution-mode select { max-width:92px; height:29px; padding:0 19px 0 7px; border:0; border-radius:8px; outline:0; background:transparent; color:var(--scui-muted); cursor:pointer; font:inherit; font-size:10px }.scui-execution-mode select:hover:not(:disabled),.scui-execution-mode select:focus-visible { background-color:var(--scui-fill); color:var(--scui-fg) }.scui-execution-mode select:focus-visible { box-shadow:0 0 0 2px color-mix(in srgb,var(--scui-accent) 35%,transparent) }.scui-execution-mode select:disabled { cursor:default; opacity:.55 }.scui-continuation .scui-execution-mode { height:27px }.scui-continuation .scui-execution-mode select { height:27px; border:1px solid var(--scui-border); background-color:var(--scui-bg) }
202
204
  .scui-harness-menu { position:relative; min-width:0 }.scui-harness-trigger { display:flex; max-width:170px; height:29px; align-items:center; gap:6px; padding:3px 7px 3px 4px; border:0; border-radius:8px; background:transparent; color:var(--scui-fg); cursor:pointer }.scui-harness-trigger:hover:not(:disabled),.scui-harness-trigger:focus-visible,.scui-harness-trigger[aria-expanded="true"] { background:var(--scui-fill) }.scui-harness-trigger:disabled { cursor:default; opacity:.55 }.scui-harness-trigger > strong { min-width:0; overflow:hidden; font-size:10.5px; font-weight:600; text-overflow:ellipsis; white-space:nowrap }.scui-harness-trigger > .scui-icon { flex:none; color:var(--scui-muted); transform:rotate(90deg); transition:transform 120ms }.scui-harness-trigger[aria-expanded="true"] > .scui-icon { transform:rotate(-90deg) }
203
205
  .scui-harness-popover { position:absolute; z-index:25; bottom:calc(100% + 7px); left:0; display:grid; box-sizing:border-box; width:min(250px,calc(100vw - 24px)); max-height:min(330px,calc(100dvh - 90px)); overflow:auto; padding:5px; border:1px solid var(--scui-border-strong); border-radius:10px; background:var(--scui-bg-raised); box-shadow:0 12px 34px rgba(0,0,0,.2) }.scui-harness-popover-title { padding:5px 7px; color:var(--scui-muted); font-size:8.5px; font-weight:650; letter-spacing:.055em; text-transform:uppercase }.scui-harness-options { display:grid; gap:1px }.scui-harness-options > button { display:grid; grid-template-columns:auto minmax(0,1fr) 18px; width:100%; min-height:36px; align-items:center; gap:8px; padding:5px 7px; border:0; border-radius:7px; background:transparent; color:var(--scui-fg); text-align:left; cursor:pointer }.scui-harness-options > button:hover,.scui-harness-options > button:focus-visible { background:var(--scui-fill) }.scui-harness-options > button[aria-selected="true"] { background:color-mix(in srgb,var(--scui-accent) 8%,var(--scui-bg-raised)) }.scui-harness-options > button > strong { min-width:0; overflow:hidden; font-size:11px; font-weight:600; text-overflow:ellipsis; white-space:nowrap }.scui-harness-options > button > span { display:grid; color:var(--scui-accent); place-items:center }
204
206
  .scui-harness-manage { margin-top:4px; padding-top:4px; border-top:1px solid var(--scui-border) }.scui-harness-manage > summary { padding:6px 7px; color:var(--scui-muted); cursor:pointer; font-size:9.5px }.scui-harness-manage > div { display:grid; gap:1px }.scui-harness-manage section { display:grid; grid-template-columns:auto minmax(0,1fr) auto; min-height:36px; align-items:center; gap:8px; padding:5px 7px }.scui-harness-manage section > span { display:grid; min-width:0 }.scui-harness-manage section strong,.scui-harness-manage section small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-harness-manage section strong { font-size:10.5px; font-weight:600 }.scui-harness-manage section small { color:var(--scui-muted); font-size:8.5px }.scui-harness-manage section > button { padding:4px 6px; border:1px solid var(--scui-border); border-radius:6px; background:transparent; color:var(--scui-muted); cursor:pointer; font-size:8.5px }.scui-harness-manage section > button:hover { border-color:var(--scui-border-strong); color:var(--scui-fg) }
205
207
  .scui-readiness { margin:0 0 7px; border:1px solid var(--scui-border); border-radius:7px; background:var(--scui-bg) }.scui-readiness > summary { padding:6px 8px; color:var(--scui-muted); cursor:pointer; font-size:10px }.scui-readiness > div { display:grid; border-top:1px solid var(--scui-border) }.scui-readiness section { display:grid; grid-template-columns:auto minmax(0,1fr) auto; align-items:center; gap:7px; padding:7px 8px }.scui-readiness section + section { border-top:1px solid var(--scui-border) }.scui-readiness section > span { display:grid; min-width:0 }.scui-readiness section strong,.scui-readiness section small,.scui-readiness section em { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-readiness section small { color:var(--scui-muted); font-size:9px }.scui-readiness section em { color:var(--scui-muted); font-size:8px; font-style:normal }.scui-readiness section button { padding:4px 6px; border:1px solid var(--scui-border); border-radius:6px; background:transparent; cursor:pointer; font-size:9px }
206
- .scui-launch-modes { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:5px; margin:0 0 7px; padding:0; border:0 }.scui-launch-modes legend { position:absolute; overflow:hidden; width:1px; height:1px; clip:rect(0 0 0 0); white-space:nowrap }.scui-launch-modes label { position:relative; min-width:0; cursor:pointer }.scui-launch-modes input { position:absolute; opacity:0; pointer-events:none }.scui-launch-modes label > span { display:flex; min-height:42px; flex-direction:column; justify-content:center; padding:6px 9px; border:1px solid var(--scui-border); border-radius:7px; background:var(--scui-bg); transition:border-color .14s ease,background .14s ease }.scui-launch-modes strong { font-size:11px; font-weight:650 }.scui-launch-modes small { overflow:hidden; color:var(--scui-muted); font-size:9px; text-overflow:ellipsis; white-space:nowrap }.scui-launch-modes input:checked + span { border-color:color-mix(in srgb,var(--scui-accent) 58%,var(--scui-border)); background:color-mix(in srgb,var(--scui-accent) 8%,var(--scui-bg)) }.scui-launch-modes input:focus-visible + span { outline:2px solid var(--scui-accent); outline-offset:1px }.scui-launch-modes:disabled label { cursor:default; opacity:.62 }
207
208
  .scui-new { display:grid; justify-items:center; gap:5px; margin:auto; padding:20px; color:var(--scui-muted); text-align:center }.scui-new > span { color:var(--scui-accent); font-size:28px }.scui-new strong { color:var(--scui-fg) }
208
209
  .scui-opening { position:absolute; z-index:30; inset:49px 0 0; display:flex; align-items:center; justify-content:center; gap:10px; padding:20px; background:var(--scui-bg) }.scui-opening > span { display:grid }.scui-opening small { color:var(--scui-muted) }.scui-opening > i { width:16px; height:16px; border:2px solid var(--scui-border); border-top-color:var(--scui-accent); border-radius:50%; animation:scui-spin .8s linear infinite }
209
210