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

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/README.md CHANGED
@@ -206,8 +206,9 @@ errors, and owned/attached identities without reimplementing transcript or capab
206
206
  `projectSessionInventory` performs the corresponding title, latest-preview, activity, path, age,
207
207
  sorting, and row projection for raw machine-wide descriptors; the trusted host supplies only its
208
208
  opaque-key callback and retains the reversible locator map. Its `isWritable` capability callback
209
- is fail-closed: observed sessions remain neutral read-only channels until the host proves a real
210
- send or terminal-control path.
209
+ is fail-closed: unread badges remain neutral until the host proves a real send or terminal-control
210
+ path. Runtime activity remains independent, so a read-only channel can still truthfully show that
211
+ its external agent is working or needs input.
211
212
 
212
213
  ## Modularity contract
213
214
 
package/activity.mjs CHANGED
@@ -784,7 +784,6 @@ function sessionDisplayName(session) {
784
784
  return title && title !== session.name ? title : session.name || "Untitled chat";
785
785
  }
786
786
  function sessionActivity(state, row) {
787
- if (!row.writable) return "observed";
788
787
  if (state.needsInput && row.active) return "needs-input";
789
788
  if (state.busy && row.active) return "working";
790
789
  if (row.runtimeStatus === "busy") return "working";
@@ -802,7 +801,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
802
801
  finished: 30,
803
802
  running: 20,
804
803
  recent: 10,
805
- observed: 0,
806
804
  idle: 0
807
805
  });
808
806
  function activityDetail(activity, preview, pill) {
@@ -813,13 +811,14 @@ function activityDetail(activity, preview, pill) {
813
811
  if (activity === "finished") return "Finished";
814
812
  if (activity === "unseen") return "New reply";
815
813
  if (activity === "running") return "Session is running";
816
- if (activity === "observed") return "Read-only channel";
817
814
  return pill || "Agent chats";
818
815
  }
819
816
  function projectAgentActivity(value) {
820
817
  const state = normalizeUiState(value);
821
818
  const attentionByKey = new Map(state.attention.map((item) => [item.key, item]));
819
+ const sessionsByKey = new Map(state.sessions.map((row) => [row.key, row]));
822
820
  const unreadCount = state.attention.reduce((total, item) => total + (item.unreadCount ?? 1), 0);
821
+ const unreadTone = state.attention.length > 0 && state.attention.every((item) => sessionsByKey.get(item.key)?.writable) ? "attention" : "neutral";
823
822
  const ranked = state.sessions.map((row, index) => {
824
823
  const activity2 = sessionActivity(state, row);
825
824
  return {
@@ -843,7 +842,8 @@ function projectAgentActivity(value) {
843
842
  title: selected ? sessionDisplayName(selected.row) : fallback ? sessionDisplayName(fallback) : "Agent chats",
844
843
  detail: activityDetail(activity, preview, state.pill.label),
845
844
  activity,
846
- unreadCount
845
+ unreadCount,
846
+ unreadTone
847
847
  };
848
848
  }
849
849
  function toolTarget(argumentsText) {
@@ -930,7 +930,7 @@ function AgentActivityLauncher({ state, onOpen, class: className = "", showSumma
930
930
  const Logo = components.HarnessLogo ?? HarnessLogo;
931
931
  const badge = value.unreadCount > 99 ? "99+" : String(value.unreadCount);
932
932
  const label = [value.title, value.detail, value.unreadCount ? `${value.unreadCount} unread` : ""].filter(Boolean).join(" \xB7 ");
933
- return /* @__PURE__ */ jsxs2("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
933
+ return /* @__PURE__ */ jsxs2("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, "data-unread-tone": value.unreadTone, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
934
934
  /* @__PURE__ */ jsxs2("span", { className: "scui-launcher-logo", children: [
935
935
  /* @__PURE__ */ jsx2(Logo, { id: value.harness || "supercode", activity: value.activity, size: 36 }),
936
936
  value.unreadCount ? /* @__PURE__ */ jsx2("b", { "aria-hidden": "true", children: badge }) : null
package/components.mjs CHANGED
@@ -796,7 +796,6 @@ function sessionDisplayName(session) {
796
796
  return title && title !== session.name ? title : session.name || "Untitled chat";
797
797
  }
798
798
  function sessionActivity(state, row) {
799
- if (!row.writable) return "observed";
800
799
  if (state.needsInput && row.active) return "needs-input";
801
800
  if (state.busy && row.active) return "working";
802
801
  if (row.runtimeStatus === "busy") return "working";
@@ -814,7 +813,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
814
813
  finished: 30,
815
814
  running: 20,
816
815
  recent: 10,
817
- observed: 0,
818
816
  idle: 0
819
817
  });
820
818
  function activityDetail(activity, preview, pill) {
@@ -825,13 +823,14 @@ function activityDetail(activity, preview, pill) {
825
823
  if (activity === "finished") return "Finished";
826
824
  if (activity === "unseen") return "New reply";
827
825
  if (activity === "running") return "Session is running";
828
- if (activity === "observed") return "Read-only channel";
829
826
  return pill || "Agent chats";
830
827
  }
831
828
  function projectAgentActivity(value) {
832
829
  const state = normalizeUiState(value);
833
830
  const attentionByKey = new Map(state.attention.map((item) => [item.key, item]));
831
+ const sessionsByKey = new Map(state.sessions.map((row) => [row.key, row]));
834
832
  const unreadCount = state.attention.reduce((total, item) => total + (item.unreadCount ?? 1), 0);
833
+ const unreadTone = state.attention.length > 0 && state.attention.every((item) => sessionsByKey.get(item.key)?.writable) ? "attention" : "neutral";
835
834
  const ranked = state.sessions.map((row, index) => {
836
835
  const activity2 = sessionActivity(state, row);
837
836
  return {
@@ -855,7 +854,8 @@ function projectAgentActivity(value) {
855
854
  title: selected ? sessionDisplayName(selected.row) : fallback ? sessionDisplayName(fallback) : "Agent chats",
856
855
  detail: activityDetail(activity, preview, state.pill.label),
857
856
  activity,
858
- unreadCount
857
+ unreadCount,
858
+ unreadTone
859
859
  };
860
860
  }
861
861
  function filterSessions(rows, query) {
@@ -1643,7 +1643,7 @@ function AgentActivityLauncher({ state, onOpen, class: className = "", showSumma
1643
1643
  const Logo = components.HarnessLogo ?? HarnessLogo;
1644
1644
  const badge = value.unreadCount > 99 ? "99+" : String(value.unreadCount);
1645
1645
  const label = [value.title, value.detail, value.unreadCount ? `${value.unreadCount} unread` : ""].filter(Boolean).join(" \xB7 ");
1646
- return /* @__PURE__ */ jsxs5("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
1646
+ return /* @__PURE__ */ jsxs5("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, "data-unread-tone": value.unreadTone, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
1647
1647
  /* @__PURE__ */ jsxs5("span", { className: "scui-launcher-logo", children: [
1648
1648
  /* @__PURE__ */ jsx5(Logo, { id: value.harness || "supercode", activity: value.activity, size: 36 }),
1649
1649
  value.unreadCount ? /* @__PURE__ */ jsx5("b", { "aria-hidden": "true", children: badge }) : null
package/composer.mjs CHANGED
@@ -77,7 +77,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
77
77
  finished: 30,
78
78
  running: 20,
79
79
  recent: 10,
80
- observed: 0,
81
80
  idle: 0
82
81
  });
83
82
  function canContinueHere(state) {
package/conversation.mjs CHANGED
@@ -439,7 +439,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
439
439
  finished: 30,
440
440
  running: 20,
441
441
  recent: 10,
442
- observed: 0,
443
442
  idle: 0
444
443
  });
445
444
  function groupConversation(entries) {
package/core.mjs CHANGED
@@ -859,9 +859,6 @@ export function sessionDisplayName(session) {
859
859
  }
860
860
 
861
861
  export function sessionActivity(state, row) {
862
- // Runtime activity and interaction authority are deliberately independent. A process may be
863
- // busy in another terminal, but presenting it as this surface's active agent is misleading.
864
- if (!row.writable) return 'observed';
865
862
  if (state.needsInput && row.active) return 'needs-input';
866
863
  if (state.busy && row.active) return 'working';
867
864
  // Unread/finished attention has its own badge. It must not suppress the
@@ -882,7 +879,6 @@ const ACTIVITY_PRIORITY = Object.freeze({
882
879
  finished: 30,
883
880
  running: 20,
884
881
  recent: 10,
885
- observed: 0,
886
882
  idle: 0,
887
883
  });
888
884
 
@@ -894,7 +890,6 @@ function activityDetail(activity, preview, pill) {
894
890
  if (activity === 'finished') return 'Finished';
895
891
  if (activity === 'unseen') return 'New reply';
896
892
  if (activity === 'running') return 'Session is running';
897
- if (activity === 'observed') return 'Read-only channel';
898
893
  return pill || 'Agent chats';
899
894
  }
900
895
 
@@ -902,7 +897,12 @@ function activityDetail(activity, preview, pill) {
902
897
  export function projectAgentActivity(value) {
903
898
  const state = normalizeUiState(value);
904
899
  const attentionByKey = new Map(state.attention.map((item) => [item.key, item]));
900
+ const sessionsByKey = new Map(state.sessions.map((row) => [row.key, row]));
905
901
  const unreadCount = state.attention.reduce((total, item) => total + (item.unreadCount ?? 1), 0);
902
+ const unreadTone = state.attention.length > 0
903
+ && state.attention.every((item) => sessionsByKey.get(item.key)?.writable)
904
+ ? 'attention'
905
+ : 'neutral';
906
906
  const ranked = state.sessions.map((row, index) => {
907
907
  const activity = sessionActivity(state, row);
908
908
  return {
@@ -927,6 +927,7 @@ export function projectAgentActivity(value) {
927
927
  detail: activityDetail(activity, preview, state.pill.label),
928
928
  activity,
929
929
  unreadCount,
930
+ unreadTone,
930
931
  };
931
932
  }
932
933
 
package/embed.mjs CHANGED
@@ -799,7 +799,6 @@ function sessionDisplayName(session) {
799
799
  return title && title !== session.name ? title : session.name || "Untitled chat";
800
800
  }
801
801
  function sessionActivity(state, row) {
802
- if (!row.writable) return "observed";
803
802
  if (state.needsInput && row.active) return "needs-input";
804
803
  if (state.busy && row.active) return "working";
805
804
  if (row.runtimeStatus === "busy") return "working";
@@ -817,7 +816,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
817
816
  finished: 30,
818
817
  running: 20,
819
818
  recent: 10,
820
- observed: 0,
821
819
  idle: 0
822
820
  });
823
821
  function filterSessions(rows, query) {
package/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type ControlStrategy = 'start' | 'resume' | 'attach' | 'branch' | 'reduce
8
8
  export type ExecutionMode = 'headless' | 'terminal';
9
9
  /** @deprecated Use ExecutionMode. */
10
10
  export type ContinuationMode = ExecutionMode;
11
- export type SessionActivity = 'idle' | 'observed' | 'recent' | 'running' | 'working' | 'needs-input' | 'finished' | 'failed' | 'unseen';
11
+ export type SessionActivity = 'idle' | 'recent' | 'running' | 'working' | 'needs-input' | 'finished' | 'failed' | 'unseen';
12
12
 
13
13
  export interface AgentActivityModel {
14
14
  harness: HarnessId | '';
@@ -17,6 +17,7 @@ export interface AgentActivityModel {
17
17
  detail: string;
18
18
  activity: SessionActivity;
19
19
  unreadCount: number;
20
+ unreadTone: 'attention' | 'neutral';
20
21
  }
21
22
 
22
23
  export interface HarnessOption {
package/messenger.mjs CHANGED
@@ -796,7 +796,6 @@ function sessionDisplayName(session) {
796
796
  return title && title !== session.name ? title : session.name || "Untitled chat";
797
797
  }
798
798
  function sessionActivity(state, row) {
799
- if (!row.writable) return "observed";
800
799
  if (state.needsInput && row.active) return "needs-input";
801
800
  if (state.busy && row.active) return "working";
802
801
  if (row.runtimeStatus === "busy") return "working";
@@ -814,7 +813,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
814
813
  finished: 30,
815
814
  running: 20,
816
815
  recent: 10,
817
- observed: 0,
818
816
  idle: 0
819
817
  });
820
818
  function filterSessions(rows, query) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter-ai-dev/supercode-ui",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "type": "module",
5
5
  "description": "Composable default UI kit for Supercode-powered coding-agent experiences",
6
6
  "exports": {
@@ -784,7 +784,6 @@ function sessionDisplayName(session) {
784
784
  return title && title !== session.name ? title : session.name || "Untitled chat";
785
785
  }
786
786
  function sessionActivity(state, row) {
787
- if (!row.writable) return "observed";
788
787
  if (state.needsInput && row.active) return "needs-input";
789
788
  if (state.busy && row.active) return "working";
790
789
  if (row.runtimeStatus === "busy") return "working";
@@ -802,7 +801,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
802
801
  finished: 30,
803
802
  running: 20,
804
803
  recent: 10,
805
- observed: 0,
806
804
  idle: 0
807
805
  });
808
806
  function activityDetail(activity, preview, pill) {
@@ -813,13 +811,14 @@ function activityDetail(activity, preview, pill) {
813
811
  if (activity === "finished") return "Finished";
814
812
  if (activity === "unseen") return "New reply";
815
813
  if (activity === "running") return "Session is running";
816
- if (activity === "observed") return "Read-only channel";
817
814
  return pill || "Agent chats";
818
815
  }
819
816
  function projectAgentActivity(value) {
820
817
  const state = normalizeUiState(value);
821
818
  const attentionByKey = new Map(state.attention.map((item) => [item.key, item]));
819
+ const sessionsByKey = new Map(state.sessions.map((row) => [row.key, row]));
822
820
  const unreadCount = state.attention.reduce((total, item) => total + (item.unreadCount ?? 1), 0);
821
+ const unreadTone = state.attention.length > 0 && state.attention.every((item) => sessionsByKey.get(item.key)?.writable) ? "attention" : "neutral";
823
822
  const ranked = state.sessions.map((row, index) => {
824
823
  const activity2 = sessionActivity(state, row);
825
824
  return {
@@ -843,7 +842,8 @@ function projectAgentActivity(value) {
843
842
  title: selected ? sessionDisplayName(selected.row) : fallback ? sessionDisplayName(fallback) : "Agent chats",
844
843
  detail: activityDetail(activity, preview, state.pill.label),
845
844
  activity,
846
- unreadCount
845
+ unreadCount,
846
+ unreadTone
847
847
  };
848
848
  }
849
849
  function toolTarget(argumentsText) {
@@ -930,7 +930,7 @@ function AgentActivityLauncher({ state, onOpen, class: className = "", showSumma
930
930
  const Logo = components.HarnessLogo ?? HarnessLogo;
931
931
  const badge = value.unreadCount > 99 ? "99+" : String(value.unreadCount);
932
932
  const label = [value.title, value.detail, value.unreadCount ? `${value.unreadCount} unread` : ""].filter(Boolean).join(" \xB7 ");
933
- return /* @__PURE__ */ jsxs2("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
933
+ return /* @__PURE__ */ jsxs2("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, "data-unread-tone": value.unreadTone, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
934
934
  /* @__PURE__ */ jsxs2("span", { className: "scui-launcher-logo", children: [
935
935
  /* @__PURE__ */ jsx2(Logo, { id: value.harness || "supercode", activity: value.activity, size: 36 }),
936
936
  value.unreadCount ? /* @__PURE__ */ jsx2("b", { "aria-hidden": "true", children: badge }) : null
@@ -796,7 +796,6 @@ function sessionDisplayName(session) {
796
796
  return title && title !== session.name ? title : session.name || "Untitled chat";
797
797
  }
798
798
  function sessionActivity(state, row) {
799
- if (!row.writable) return "observed";
800
799
  if (state.needsInput && row.active) return "needs-input";
801
800
  if (state.busy && row.active) return "working";
802
801
  if (row.runtimeStatus === "busy") return "working";
@@ -814,7 +813,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
814
813
  finished: 30,
815
814
  running: 20,
816
815
  recent: 10,
817
- observed: 0,
818
816
  idle: 0
819
817
  });
820
818
  function activityDetail(activity, preview, pill) {
@@ -825,13 +823,14 @@ function activityDetail(activity, preview, pill) {
825
823
  if (activity === "finished") return "Finished";
826
824
  if (activity === "unseen") return "New reply";
827
825
  if (activity === "running") return "Session is running";
828
- if (activity === "observed") return "Read-only channel";
829
826
  return pill || "Agent chats";
830
827
  }
831
828
  function projectAgentActivity(value) {
832
829
  const state = normalizeUiState(value);
833
830
  const attentionByKey = new Map(state.attention.map((item) => [item.key, item]));
831
+ const sessionsByKey = new Map(state.sessions.map((row) => [row.key, row]));
834
832
  const unreadCount = state.attention.reduce((total, item) => total + (item.unreadCount ?? 1), 0);
833
+ const unreadTone = state.attention.length > 0 && state.attention.every((item) => sessionsByKey.get(item.key)?.writable) ? "attention" : "neutral";
835
834
  const ranked = state.sessions.map((row, index) => {
836
835
  const activity2 = sessionActivity(state, row);
837
836
  return {
@@ -855,7 +854,8 @@ function projectAgentActivity(value) {
855
854
  title: selected ? sessionDisplayName(selected.row) : fallback ? sessionDisplayName(fallback) : "Agent chats",
856
855
  detail: activityDetail(activity, preview, state.pill.label),
857
856
  activity,
858
- unreadCount
857
+ unreadCount,
858
+ unreadTone
859
859
  };
860
860
  }
861
861
  function filterSessions(rows, query) {
@@ -1643,7 +1643,7 @@ function AgentActivityLauncher({ state, onOpen, class: className = "", showSumma
1643
1643
  const Logo = components.HarnessLogo ?? HarnessLogo;
1644
1644
  const badge = value.unreadCount > 99 ? "99+" : String(value.unreadCount);
1645
1645
  const label = [value.title, value.detail, value.unreadCount ? `${value.unreadCount} unread` : ""].filter(Boolean).join(" \xB7 ");
1646
- return /* @__PURE__ */ jsxs5("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
1646
+ return /* @__PURE__ */ jsxs5("button", { className: `scui-launcher ${className}`, "data-activity": value.activity, "data-unread-tone": value.unreadTone, type: "button", "aria-label": `Open ${label}`, onClick: () => onOpen?.(value), children: [
1647
1647
  /* @__PURE__ */ jsxs5("span", { className: "scui-launcher-logo", children: [
1648
1648
  /* @__PURE__ */ jsx5(Logo, { id: value.harness || "supercode", activity: value.activity, size: 36 }),
1649
1649
  value.unreadCount ? /* @__PURE__ */ jsx5("b", { "aria-hidden": "true", children: badge }) : null
@@ -77,7 +77,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
77
77
  finished: 30,
78
78
  running: 20,
79
79
  recent: 10,
80
- observed: 0,
81
80
  idle: 0
82
81
  });
83
82
  function canContinueHere(state) {
@@ -439,7 +439,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
439
439
  finished: 30,
440
440
  running: 20,
441
441
  recent: 10,
442
- observed: 0,
443
442
  idle: 0
444
443
  });
445
444
  function groupConversation(entries) {
@@ -796,7 +796,6 @@ function sessionDisplayName(session) {
796
796
  return title && title !== session.name ? title : session.name || "Untitled chat";
797
797
  }
798
798
  function sessionActivity(state, row) {
799
- if (!row.writable) return "observed";
800
799
  if (state.needsInput && row.active) return "needs-input";
801
800
  if (state.busy && row.active) return "working";
802
801
  if (row.runtimeStatus === "busy") return "working";
@@ -814,7 +813,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
814
813
  finished: 30,
815
814
  running: 20,
816
815
  recent: 10,
817
- observed: 0,
818
816
  idle: 0
819
817
  });
820
818
  function filterSessions(rows, query) {
@@ -83,7 +83,6 @@ 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";
87
86
  if (state.needsInput && row.active) return "needs-input";
88
87
  if (state.busy && row.active) return "working";
89
88
  if (row.runtimeStatus === "busy") return "working";
@@ -101,7 +100,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
101
100
  finished: 30,
102
101
  running: 20,
103
102
  recent: 10,
104
- observed: 0,
105
103
  idle: 0
106
104
  });
107
105
  function filterSessions(rows, query) {
@@ -77,7 +77,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
77
77
  finished: 30,
78
78
  running: 20,
79
79
  recent: 10,
80
- observed: 0,
81
80
  idle: 0
82
81
  });
83
82
 
package/sessions.mjs CHANGED
@@ -83,7 +83,6 @@ 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";
87
86
  if (state.needsInput && row.active) return "needs-input";
88
87
  if (state.busy && row.active) return "working";
89
88
  if (row.runtimeStatus === "busy") return "working";
@@ -101,7 +100,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
101
100
  finished: 30,
102
101
  running: 20,
103
102
  recent: 10,
104
- observed: 0,
105
103
  idle: 0
106
104
  });
107
105
  function filterSessions(rows, query) {
package/settings.mjs CHANGED
@@ -77,7 +77,6 @@ var ACTIVITY_PRIORITY = Object.freeze({
77
77
  finished: 30,
78
78
  running: 20,
79
79
  recent: 10,
80
- observed: 0,
81
80
  idle: 0
82
81
  });
83
82
 
package/styles.css CHANGED
@@ -73,7 +73,6 @@
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) }
77
76
  .scui-logo[data-activity="working"] > i,.scui-logo[data-activity="running"] > i { background:var(--scui-positive) }
78
77
  .scui-logo[data-activity="needs-input"] > i { background:var(--scui-warning) }
79
78
  .scui-logo[data-activity="failed"] > i { background:var(--scui-danger) }
@@ -81,6 +80,7 @@
81
80
 
82
81
  .scui-launcher { --scui-bg:#fff; --scui-fg:#191918; --scui-muted:#5f5f5a; --scui-border:#deded9; --scui-positive:#22863a; --scui-warning:#b26a00; --scui-danger:#b4232e; display:inline-flex; min-width:44px; min-height:44px; align-items:center; gap:8px; padding:4px; overflow:visible; border:1px solid var(--scui-border); border-radius:999px; background:color-mix(in srgb,var(--scui-bg) 88%,transparent); color:var(--scui-fg); box-shadow:0 5px 18px rgba(0,0,0,.14); cursor:pointer; font:12px/1.25 var(--scui-font,Inter,ui-sans-serif,system-ui,sans-serif); backdrop-filter:blur(10px) }
83
82
  .scui-launcher-logo { position:relative; display:grid; flex:none; place-items:center }.scui-launcher-logo > b { position:absolute; z-index:1; top:-6px; right:-8px; display:grid; min-width:18px; height:18px; padding:0 4px; place-items:center; border:2px solid var(--scui-bg); border-radius:999px; background:var(--scui-danger); color:#fff; font-size:9px; line-height:1 }
83
+ .scui-launcher[data-unread-tone="neutral"] .scui-launcher-logo > b { background:var(--scui-muted) }
84
84
  .scui-launcher-copy { display:grid; min-width:0; max-width:220px; padding-right:8px; text-align:left }.scui-launcher-copy strong,.scui-launcher-copy small { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }.scui-launcher-copy small { color:var(--scui-muted); font-size:10px }
85
85
  .scui-launcher:hover { border-color:color-mix(in srgb,var(--scui-fg) 28%,var(--scui-border)); box-shadow:0 7px 22px rgba(0,0,0,.18) }.scui-launcher:focus-visible { outline:2px solid currentColor; outline-offset:2px }
86
86
  @media (prefers-color-scheme:dark) { .scui-launcher { --scui-bg:#151515; --scui-fg:#f3f3ef; --scui-muted:#a3a39d; --scui-border:#353532; --scui-positive:#57c26e; --scui-warning:#e8a23a; --scui-danger:#ff747d } }
@@ -108,6 +108,7 @@
108
108
  .scui-session-path { display:flex; min-width:0; overflow:hidden; color:var(--scui-muted); font-size:9.5px; white-space:nowrap }
109
109
  .scui-session-path-leading { flex:0 1 auto; overflow:hidden; text-overflow:ellipsis }.scui-session-path-separator { flex:none }.scui-session-path-trailing { flex:none; max-width:58%; overflow:hidden; direction:rtl; text-align:left; text-overflow:ellipsis; unicode-bidi:plaintext }
110
110
  .scui-session-preview small { flex:1; min-width:0; color:var(--scui-muted); font-size:10.5px }.scui-session-preview b { display:grid; flex:none; min-width:16px; height:16px; padding:0 4px; place-items:center; border-radius:8px; background:var(--scui-accent); color:var(--scui-bg); font-size:9px; line-height:16px }
111
+ .scui-session[data-writable="false"] .scui-session-preview b { background:var(--scui-muted) }
111
112
  .scui-session-copy em { overflow:hidden; color:var(--scui-danger); font-size:10px; font-style:normal; text-overflow:ellipsis; white-space:nowrap }
112
113
  .scui-load { display:block; margin:7px auto; padding:5px 10px; border:1px solid var(--scui-border); border-radius:8px; background:var(--scui-bg-raised); color:var(--scui-muted); cursor:pointer }.scui-load:disabled { opacity:.65; cursor:default }
113
114