@volter-ai-dev/supercode-ui 0.1.1 → 0.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter-ai-dev/supercode-ui",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "description": "Composable default UI kit for Supercode-powered coding-agent experiences",
6
6
  "exports": {
@@ -9,7 +9,7 @@
9
9
  "import": "./index.mjs"
10
10
  },
11
11
  "./core": {
12
- "types": "./index.d.ts",
12
+ "types": "./core.d.ts",
13
13
  "import": "./core.mjs"
14
14
  },
15
15
  "./controller": {
@@ -17,31 +17,31 @@
17
17
  "import": "./controller.mjs"
18
18
  },
19
19
  "./preact": {
20
- "types": "./index.d.ts",
20
+ "types": "./components.d.ts",
21
21
  "import": "./components.mjs"
22
22
  },
23
23
  "./preact/logo": {
24
- "types": "./index.d.ts",
24
+ "types": "./logo.d.ts",
25
25
  "import": "./logo.mjs"
26
26
  },
27
27
  "./preact/conversation": {
28
- "types": "./index.d.ts",
28
+ "types": "./conversation.d.ts",
29
29
  "import": "./conversation.mjs"
30
30
  },
31
31
  "./preact/sessions": {
32
- "types": "./index.d.ts",
32
+ "types": "./sessions.d.ts",
33
33
  "import": "./sessions.mjs"
34
34
  },
35
35
  "./preact/composer": {
36
- "types": "./index.d.ts",
36
+ "types": "./composer.d.ts",
37
37
  "import": "./composer.mjs"
38
38
  },
39
39
  "./preact/messenger": {
40
- "types": "./index.d.ts",
40
+ "types": "./messenger.d.ts",
41
41
  "import": "./messenger.mjs"
42
42
  },
43
43
  "./embed": {
44
- "types": "./index.d.ts",
44
+ "types": "./embed.d.ts",
45
45
  "import": "./embed.mjs"
46
46
  },
47
47
  "./styles.css": "./styles.css"
@@ -49,15 +49,23 @@
49
49
  "types": "./index.d.ts",
50
50
  "files": [
51
51
  "core.mjs",
52
+ "core.d.ts",
52
53
  "controller.mjs",
53
54
  "controller.d.ts",
54
55
  "components.mjs",
56
+ "components.d.ts",
55
57
  "logo.mjs",
58
+ "logo.d.ts",
56
59
  "conversation.mjs",
60
+ "conversation.d.ts",
57
61
  "sessions.mjs",
62
+ "sessions.d.ts",
58
63
  "composer.mjs",
64
+ "composer.d.ts",
59
65
  "messenger.mjs",
66
+ "messenger.d.ts",
60
67
  "embed.mjs",
68
+ "embed.d.ts",
61
69
  "index.mjs",
62
70
  "index.d.ts",
63
71
  "styles.css",
@@ -68,14 +76,16 @@
68
76
  "build:fixture": "esbuild test/browser-entry.jsx --bundle --format=esm --platform=browser --jsx=automatic --jsx-import-source=preact --outfile=test/browser-bundle.mjs",
69
77
  "storybook": "npm run build && storybook dev -p 6006",
70
78
  "build:storybook": "npm run build && storybook build",
71
- "test:storybook": "vitest --run",
72
- "test": "node --test test/*.test.mjs"
79
+ "test:storybook": "npm run build && vitest --run",
80
+ "typecheck": "tsc -p tsconfig.json && tsc -p test/tsconfig.json",
81
+ "test": "node --test test/*.test.mjs",
82
+ "prepack": "npm run build && npm run typecheck && npm test && npm run test:storybook"
73
83
  },
74
84
  "dependencies": {
75
85
  "markdown-it": "^14.1.0"
76
86
  },
77
87
  "peerDependencies": {
78
- "@volter-ai-dev/supercode-client": ">=0.3.8",
88
+ "@volter-ai-dev/supercode-client": ">=0.3.9 <0.4.0",
79
89
  "preact": ">=10.19.0 <11"
80
90
  },
81
91
  "peerDependenciesMeta": {
@@ -96,6 +106,7 @@
96
106
  "preact": "^10.19.0",
97
107
  "preact-render-to-string": "^6.5.0",
98
108
  "storybook": "10.5.9",
109
+ "typescript": "5.6.3",
99
110
  "vite": "7.3.6",
100
111
  "vitest": "4.1.10"
101
112
  },
package/sessions.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type {
2
+ MessengerComponents,
3
+ MessengerLabels,
4
+ SessionRowModel,
5
+ SessionRowProps,
6
+ SupercodeUiState,
7
+ UiAdapter,
8
+ } from './index.js';
9
+ export { LoadingStatus, SessionList, SessionRow } from './index.js';
package/sessions.mjs CHANGED
@@ -1,11 +1,11 @@
1
- // src/components.jsx
2
- import MarkdownIt from "markdown-it";
3
- import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
1
+ // src/sessions.jsx
2
+ import { useState as useState2 } from "preact/hooks";
4
3
 
5
4
  // core.mjs
6
5
  var HARNESS_NAMES = Object.freeze({
7
6
  "claude-code": "Claude Code",
8
7
  codex: "Codex",
8
+ gemini: "Gemini CLI",
9
9
  opencode: "OpenCode",
10
10
  pi: "Pi",
11
11
  grok: "Grok"
@@ -80,8 +80,13 @@ function filterSessions(rows, query) {
80
80
  return rows.filter((row) => [row.name, row.title, row.cwd, row.harness, harnessDisplayName(row.harness)].some((value) => value.toLocaleLowerCase().includes(needle)));
81
81
  }
82
82
 
83
- // src/components.jsx
84
- import { jsx, jsxs } from "preact/jsx-runtime";
83
+ // src/conversation.jsx
84
+ import { useEffect, useId, useLayoutEffect, useRef, useState } from "preact/hooks";
85
+
86
+ // src/markdown.jsx
87
+ import MarkdownIt from "markdown-it";
88
+ import { useMemo } from "preact/hooks";
89
+ import { jsx } from "preact/jsx-runtime";
85
90
  var markdown = new MarkdownIt({ html: false, linkify: true, breaks: false });
86
91
  var defaultLinkOpen = markdown.renderer.rules.link_open;
87
92
  markdown.renderer.rules.link_open = (tokens, index, options, env, self) => {
@@ -89,6 +94,29 @@ markdown.renderer.rules.link_open = (tokens, index, options, env, self) => {
89
94
  tokens[index]?.attrSet("rel", "noreferrer noopener");
90
95
  return defaultLinkOpen ? defaultLinkOpen(tokens, index, options, env, self) : self.renderToken(tokens, index, options);
91
96
  };
97
+
98
+ // src/conversation.jsx
99
+ import { jsx as jsx2, jsxs } from "preact/jsx-runtime";
100
+ function LoadingStatus({ state, compact = false }) {
101
+ const copy = {
102
+ connecting: ["Connecting to coding agents", "Checking installed harnesses and capabilities.", 0],
103
+ starting: [`Starting ${harnessDisplayName(state.harness) || "coding agent"}`, "Opening a controlled session in this workspace.", 1],
104
+ discovering: ["Loading recent sessions", "Scanning native session stores without loading full transcripts.", 2],
105
+ ready: ["Ready", "Coding sessions are up to date.", 3]
106
+ }[state.startup];
107
+ return /* @__PURE__ */ jsxs("div", { class: `scui-loading${compact ? " scui-loading-compact" : ""}`, role: "status", "aria-busy": state.startup !== "ready", children: [
108
+ /* @__PURE__ */ jsx2("span", { class: "scui-orbit", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("i", {}) }),
109
+ /* @__PURE__ */ jsxs("span", { class: "scui-loading-copy", children: [
110
+ /* @__PURE__ */ jsx2("strong", { children: copy[0] }),
111
+ /* @__PURE__ */ jsx2("small", { children: copy[1] })
112
+ ] }),
113
+ /* @__PURE__ */ jsx2("span", { class: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx2("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
114
+ ] });
115
+ }
116
+
117
+ // src/logo.jsx
118
+ import { useEffect as useEffect2 } from "preact/hooks";
119
+ import { jsx as jsx3, jsxs as jsxs2 } from "preact/jsx-runtime";
92
120
  var LOGOS = {
93
121
  "claude-code": {
94
122
  viewBox: "-1 3.5 26 18",
@@ -102,6 +130,10 @@ var LOGOS = {
102
130
  ["path", { "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z" }]
103
131
  ]
104
132
  },
133
+ gemini: {
134
+ viewBox: "0 0 24 24",
135
+ paths: [["path", { d: "M12 24C12 17.373 6.627 12 0 12 6.627 12 12 6.627 12 0c0 6.627 5.373 12 12 12-6.627 0-12 5.373-12 12z" }]]
136
+ },
105
137
  grok: {
106
138
  viewBox: "-1 -1 26 26",
107
139
  paths: [["path", { d: "M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815" }]]
@@ -117,80 +149,66 @@ var LOGOS = {
117
149
  };
118
150
  function HarnessLogo({ id, activity, size = 28, onMissingLogo }) {
119
151
  const logo = LOGOS[id];
120
- useEffect(() => {
152
+ useEffect2(() => {
121
153
  if (!logo) onMissingLogo?.(id);
122
154
  }, [id, logo, onMissingLogo]);
123
155
  if (!logo) return null;
124
- return /* @__PURE__ */ jsxs("span", { class: "scui-logo", "data-harness": id, "data-activity": activity, style: `--scui-logo-size:${size}px`, "aria-hidden": "true", children: [
125
- /* @__PURE__ */ jsx("svg", { viewBox: logo.viewBox, focusable: "false", children: logo.paths.map(([Tag, props], index) => /* @__PURE__ */ jsx(Tag, { ...props }, index)) }),
126
- activity && activity !== "idle" ? /* @__PURE__ */ jsx("i", {}) : null
127
- ] });
128
- }
129
- function LoadingStatus({ state, compact = false }) {
130
- const copy = {
131
- connecting: ["Connecting to coding agents", "Checking installed harnesses and capabilities.", 0],
132
- starting: [`Starting ${harnessDisplayName(state.harness) || "coding agent"}`, "Opening a controlled session in this workspace.", 1],
133
- discovering: ["Loading recent sessions", "Scanning native session stores without loading full transcripts.", 2],
134
- ready: ["Ready", "Coding sessions are up to date.", 3]
135
- }[state.startup];
136
- return /* @__PURE__ */ jsxs("div", { class: `scui-loading${compact ? " scui-loading-compact" : ""}`, role: "status", "aria-busy": state.startup !== "ready", children: [
137
- /* @__PURE__ */ jsx("span", { class: "scui-orbit", "aria-hidden": "true", children: /* @__PURE__ */ jsx("i", {}) }),
138
- /* @__PURE__ */ jsxs("span", { class: "scui-loading-copy", children: [
139
- /* @__PURE__ */ jsx("strong", { children: copy[0] }),
140
- /* @__PURE__ */ jsx("small", { children: copy[1] })
141
- ] }),
142
- /* @__PURE__ */ jsx("span", { class: "scui-progress", "aria-hidden": "true", children: [1, 2, 3].map((step) => /* @__PURE__ */ jsx("i", { "data-progress": step <= copy[2] ? "done" : step === copy[2] + 1 ? "current" : "waiting" }, step)) })
156
+ return /* @__PURE__ */ jsxs2("span", { class: "scui-logo", "data-harness": id, "data-activity": activity, style: `--scui-logo-size:${size}px`, "aria-hidden": "true", children: [
157
+ /* @__PURE__ */ jsx3("svg", { viewBox: logo.viewBox, preserveAspectRatio: "xMidYMid meet", focusable: "false", children: logo.paths.map(([Tag, props], index) => /* @__PURE__ */ jsx3(Tag, { ...props }, index)) }),
158
+ activity && activity !== "idle" ? /* @__PURE__ */ jsx3("i", {}) : null
143
159
  ] });
144
160
  }
161
+
162
+ // src/sessions.jsx
163
+ import { jsx as jsx4, jsxs as jsxs3 } from "preact/jsx-runtime";
145
164
  function SessionRow({ row, state, onOpen }) {
146
165
  const activity = sessionActivity(state, row);
147
166
  const preview = state.attention.find((item) => item.key === row.key)?.preview;
148
- return /* @__PURE__ */ jsxs("button", { class: "scui-session", "data-active": row.active, "data-activity": activity, type: "button", onClick: () => onOpen(row), children: [
149
- /* @__PURE__ */ jsx(HarnessLogo, { id: row.harness, activity, size: 34 }),
150
- /* @__PURE__ */ jsxs("span", { class: "scui-session-copy", children: [
151
- /* @__PURE__ */ jsxs("span", { children: [
152
- /* @__PURE__ */ jsx("strong", { children: sessionDisplayName(row) }),
153
- /* @__PURE__ */ jsx("small", { children: row.age })
167
+ return /* @__PURE__ */ jsxs3("button", { class: "scui-session", "data-active": row.active, "data-activity": activity, type: "button", onClick: () => onOpen(row), children: [
168
+ /* @__PURE__ */ jsx4(HarnessLogo, { id: row.harness, activity, size: 34 }),
169
+ /* @__PURE__ */ jsxs3("span", { class: "scui-session-copy", children: [
170
+ /* @__PURE__ */ jsxs3("span", { children: [
171
+ /* @__PURE__ */ jsx4("strong", { children: sessionDisplayName(row) }),
172
+ /* @__PURE__ */ jsx4("small", { children: row.age })
154
173
  ] }),
155
- /* @__PURE__ */ jsxs("span", { children: [
156
- /* @__PURE__ */ jsx("b", { children: harnessDisplayName(row.harness) }),
157
- /* @__PURE__ */ jsx("small", { children: preview || row.cwd || row.name })
174
+ /* @__PURE__ */ jsxs3("span", { children: [
175
+ /* @__PURE__ */ jsx4("b", { children: harnessDisplayName(row.harness) }),
176
+ /* @__PURE__ */ jsx4("small", { children: preview || row.cwd || row.name })
158
177
  ] }),
159
- state.attachError?.key === row.key ? /* @__PURE__ */ jsx("em", { children: state.attachError.message }) : null
178
+ state.attachError?.key === row.key ? /* @__PURE__ */ jsx4("em", { children: state.attachError.message }) : null
160
179
  ] })
161
180
  ] });
162
181
  }
163
182
  function SessionList({ state, adapter, onOpen, onNew, onClose, components = {}, labels = DEFAULT_LABELS }) {
164
- const [query, setQuery] = useState("");
183
+ const [query, setQuery] = useState2("");
165
184
  const rows = filterSessions(state.sessions, query);
166
185
  const Row = components.SessionRow ?? SessionRow;
167
- return /* @__PURE__ */ jsxs("section", { class: "scui-list", children: [
168
- /* @__PURE__ */ jsxs("header", { class: "scui-head", children: [
169
- /* @__PURE__ */ jsxs("span", { children: [
170
- /* @__PURE__ */ jsx("strong", { children: labels.chats }),
171
- /* @__PURE__ */ jsxs("small", { children: [
186
+ return /* @__PURE__ */ jsxs3("section", { class: "scui-list", children: [
187
+ /* @__PURE__ */ jsxs3("header", { class: "scui-head", children: [
188
+ /* @__PURE__ */ jsxs3("span", { class: "scui-head-copy", children: [
189
+ /* @__PURE__ */ jsx4("strong", { children: labels.chats }),
190
+ /* @__PURE__ */ jsxs3("small", { children: [
172
191
  state.sessions.length,
173
192
  " recent conversations"
174
193
  ] })
175
194
  ] }),
176
- /* @__PURE__ */ jsx("button", { type: "button", "aria-label": labels.newChat, disabled: !state.harnesses.some((item) => item.startable), onClick: onNew, children: "\uFF0B" }),
177
- onClose ? /* @__PURE__ */ jsx("button", { type: "button", "aria-label": "Close", onClick: onClose, children: "\xD7" }) : null
195
+ /* @__PURE__ */ jsx4("button", { type: "button", "aria-label": labels.newChat, disabled: !state.harnesses.some((item) => item.startable), onClick: onNew, children: "\uFF0B" }),
196
+ onClose ? /* @__PURE__ */ jsx4("button", { type: "button", "aria-label": "Close", onClick: onClose, children: "\xD7" }) : null
178
197
  ] }),
179
- state.startup !== "ready" ? /* @__PURE__ */ jsx(LoadingStatus, { state, compact: rows.length > 0 }) : null,
180
- state.sessions.length > 4 ? /* @__PURE__ */ jsxs("label", { class: "scui-search", children: [
181
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2315" }),
182
- /* @__PURE__ */ jsx("input", { type: "search", "aria-label": labels.searchChats, placeholder: labels.searchChats, value: query, onInput: (event) => setQuery(event.currentTarget.value) }),
183
- /* @__PURE__ */ jsx("small", { children: rows.length })
198
+ state.startup !== "ready" ? /* @__PURE__ */ jsx4(LoadingStatus, { state, compact: rows.length > 0 }) : null,
199
+ state.sessions.length > 4 ? /* @__PURE__ */ jsxs3("label", { class: "scui-search", children: [
200
+ /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: "\u2315" }),
201
+ /* @__PURE__ */ jsx4("input", { type: "search", "aria-label": labels.searchChats, placeholder: labels.searchChats, value: query, onInput: (event) => setQuery(event.currentTarget.value) }),
202
+ /* @__PURE__ */ jsx4("small", { children: rows.length })
184
203
  ] }) : null,
185
- /* @__PURE__ */ jsxs("div", { class: "scui-session-rows", children: [
186
- !rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx("div", { class: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
187
- rows.map((row) => /* @__PURE__ */ jsx(Row, { value: row, row, state, adapter, onOpen }, row.key)),
188
- state.history.hasMoreSessions ? /* @__PURE__ */ jsx("button", { class: "scui-load", type: "button", onClick: () => adapter.onIntent({ action: "loadSessions" }), children: "Load older chats" }) : null
204
+ /* @__PURE__ */ jsxs3("div", { class: "scui-session-rows", children: [
205
+ !rows.length && state.startup === "ready" ? /* @__PURE__ */ jsx4("div", { class: "scui-empty", children: query ? "No chats match your search." : state.error ?? "No coding chats found." }) : null,
206
+ rows.map((row) => /* @__PURE__ */ jsx4(Row, { value: row, row, state, adapter, onOpen }, row.key)),
207
+ state.history.hasMoreSessions ? /* @__PURE__ */ jsx4("button", { class: "scui-load", type: "button", onClick: () => adapter.onIntent({ action: "loadSessions" }), children: "Load older chats" }) : null
189
208
  ] })
190
209
  ] });
191
210
  }
192
211
  export {
193
- LoadingStatus,
194
212
  SessionList,
195
213
  SessionRow
196
214
  };
package/styles.css CHANGED
@@ -52,7 +52,7 @@
52
52
 
53
53
  .scui-list,.scui-chat { display:flex; flex:1; min-width:0; min-height:0; flex-direction:column }
54
54
  .scui-head { display:flex; flex:none; align-items:center; gap:8px; min-height:49px; padding:7px 8px 7px 12px; border-bottom:1px solid var(--scui-border); background:var(--scui-bg-raised) }
55
- .scui-head > span { display:grid; flex:1; min-width:0 }
55
+ .scui-head > .scui-head-copy { display:grid; flex:1; min-width:0 }
56
56
  .scui-head strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px }
57
57
  .scui-head small { overflow:hidden; color:var(--scui-muted); font-size:10.5px; text-overflow:ellipsis; white-space:nowrap }
58
58
  .scui-head > button,.scui-menu > summary { display:grid; place-items:center; width:30px; height:30px; padding:0; border:0; border-radius:8px; background:transparent; cursor:pointer; font-size:18px; list-style:none }
@@ -63,10 +63,11 @@
63
63
  .scui-menu button { padding:8px; border:0; border-radius:6px; background:transparent; text-align:left; cursor:pointer }
64
64
  .scui-menu button:hover { background:var(--scui-fill) }
65
65
 
66
- .scui-logo { position:relative; display:inline-grid; place-items:center; width:var(--scui-logo-size); height:var(--scui-logo-size); flex:none; border:1px solid var(--scui-border); border-radius:50%; background:#111; color:#f7f7f5 }
67
- .scui-logo svg { width:70%; height:70%; fill:currentColor }
66
+ .scui-logo { position:relative; display:inline-grid; place-items:center; box-sizing:border-box; width:var(--scui-logo-size); height:var(--scui-logo-size); flex:none; border:1px solid var(--scui-border); border-radius:50%; background:#111; color:#f7f7f5 }
67
+ .scui-logo svg { display:block; width:70%; height:70%; overflow:visible; fill:currentColor }
68
68
  .scui-logo[data-harness="claude-code"] { color:#d97757 }
69
69
  .scui-logo[data-harness="codex"] { color:#111; background:#f7f7f5 }
70
+ .scui-logo[data-harness="gemini"] { color:#6e79dc; background:#f7f7f5 }
70
71
  .scui-logo[data-harness="pi"] { color:#111; background:#efefeb }
71
72
  .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) }
72
73
  .scui-logo[data-activity="working"] > i { background:var(--scui-accent); animation:scui-breathe 1.4s ease-in-out infinite }
@@ -135,7 +136,7 @@
135
136
  .scui-tool-detail { padding:0 7px 7px }.scui-tool-detail pre { max-height:220px; margin:0 0 5px; padding:7px; overflow:auto; border-radius:6px; background:var(--scui-bg); font:10px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace; white-space:pre-wrap }.scui-tool-detail pre[data-error="true"] { color:var(--scui-danger) }
136
137
  .scui-request { padding:9px; border:1px solid var(--scui-warning); border-radius:9px; background:color-mix(in srgb,var(--scui-warning) 8%,var(--scui-bg)) }.scui-request-actions { display:flex; flex-wrap:wrap; gap:5px }.scui-request-actions button { padding:5px 8px; border:1px solid var(--scui-border-strong); border-radius:6px; background:var(--scui-bg); cursor:pointer }
137
138
  .scui-request-done { color:var(--scui-muted); font-size:10.5px }
138
- .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; 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"] { text-decoration:line-through; opacity:.65 }
139
+ .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 }
139
140
  .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 }
140
141
 
141
142
  .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 { display:grid; flex:1 }.scui-continuation small { color:var(--scui-muted); font-size:10px }.scui-continuation button { padding:5px 8px; border:1px solid var(--scui-accent); border-radius:7px; background:transparent; color:var(--scui-accent); cursor:pointer }