dsh-super-code 0.3.0 → 0.3.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/client/index.js CHANGED
@@ -15,10 +15,253 @@ const IconChevronDownOutline14 = icons.IconChevronDownOutlineRegular ?? icons.Ic
15
15
  const IconRefreshOutline16 = icons.IconRefreshOutlineRegular ?? icons.IconRefreshOutline16
16
16
  const { SessionEventStream } = require('@deepseek-ai/dsh-api-session-controller')
17
17
 
18
+ /* Shared controls use public React APIs without host-private dependencies. */
19
+ let selectControlSequence = 0
20
+ function selectControlPlacement(rect, count) {
21
+ const margin = 8, gap = 6, width = Math.min(Math.max(rect.width, 184), window.innerWidth - margin * 2)
22
+ const below = Math.max(0, window.innerHeight - rect.bottom - gap - margin)
23
+ const above = Math.max(0, rect.top - gap - margin)
24
+ const upwards = below < Math.min(count * 32 + 8, 256) && above > below
25
+ return {
26
+ left: Math.max(margin, Math.min(rect.left, window.innerWidth - width - margin)), width,
27
+ maxHeight: Math.min(256, upwards ? above : below),
28
+ ...(upwards ? { bottom: window.innerHeight - rect.top + gap } : { top: rect.bottom + gap }),
29
+ }
30
+ }
31
+ function SelectControl({ id, label, value, choices, onChange, disabled = false }) {
32
+ const identity = useRef('')
33
+ if (!identity.current) identity.current = id || `super-code-select-${++selectControlSequence}`
34
+ const controlId = identity.current, listId = `${controlId}-list`
35
+ const trigger = useRef(null), menu = useRef(null), search = useRef({ text: '', at: 0 })
36
+ const selected = Math.max(0, choices.findIndex(([choice]) => String(choice) === String(value)))
37
+ const [open, setOpen] = useState(false), [active, setActive] = useState(selected), [placement, setPlacement] = useState({})
38
+ const unavailable = disabled || choices.length === 0
39
+ const show = (index = selected) => {
40
+ if (unavailable) return
41
+ setActive(index)
42
+ setPlacement(selectControlPlacement(trigger.current.getBoundingClientRect(), choices.length))
43
+ search.current = { text: '', at: 0 }
44
+ setOpen(true)
45
+ }
46
+ const choose = index => {
47
+ onChange(choices[index][0])
48
+ setOpen(false)
49
+ trigger.current.focus({ preventScroll: true })
50
+ }
51
+ useLayoutEffect(() => {
52
+ if (!open) return
53
+ const place = () => setPlacement(selectControlPlacement(trigger.current.getBoundingClientRect(), choices.length))
54
+ window.addEventListener('resize', place)
55
+ window.addEventListener('scroll', place, true)
56
+ return () => { window.removeEventListener('resize', place); window.removeEventListener('scroll', place, true) }
57
+ }, [open, choices.length])
58
+ useLayoutEffect(() => {
59
+ if (open) menu.current.querySelector(`[data-option-index="${active}"]`)?.scrollIntoView({ block: 'nearest' })
60
+ }, [open, active])
61
+ useEffect(() => {
62
+ if (!open) return
63
+ const inside = target => Boolean(trigger.current?.contains(target) || menu.current?.contains(target))
64
+ let pointerInside = false
65
+ // Dock hosts focus their pane during pointer capture. Observe the pointer
66
+ // before that focus change so an option survives until its click commits.
67
+ const pointerDown = event => { pointerInside = inside(event.target); if (!pointerInside) setOpen(false) }
68
+ const pointerEnd = () => { pointerInside = false }
69
+ const outsideFocus = event => { if (!pointerInside && !inside(event.target)) setOpen(false) }
70
+ // Capture Escape before host shortcuts; Tab keeps its normal focus movement.
71
+ const escape = event => {
72
+ if (event.key !== 'Escape') return
73
+ event.preventDefault(); event.stopImmediatePropagation()
74
+ setOpen(false); trigger.current.focus({ preventScroll: true })
75
+ }
76
+ window.addEventListener('pointerdown', pointerDown, true)
77
+ window.addEventListener('pointerup', pointerEnd, true)
78
+ window.addEventListener('pointercancel', pointerEnd, true)
79
+ document.addEventListener('focusin', outsideFocus, true)
80
+ window.addEventListener('keydown', escape, true)
81
+ return () => {
82
+ window.removeEventListener('pointerdown', pointerDown, true)
83
+ window.removeEventListener('pointerup', pointerEnd, true)
84
+ window.removeEventListener('pointercancel', pointerEnd, true)
85
+ document.removeEventListener('focusin', outsideFocus, true)
86
+ window.removeEventListener('keydown', escape, true)
87
+ }
88
+ }, [open])
89
+ const keyDown = event => {
90
+ if (unavailable || event.isComposing) return
91
+ if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {
92
+ event.preventDefault(); event.stopPropagation()
93
+ const next = event.key === 'Home' ? 0 : event.key === 'End' ? choices.length - 1
94
+ : Math.max(0, Math.min(choices.length - 1, active + (event.key === 'ArrowDown' ? 1 : -1)))
95
+ if (open) setActive(next)
96
+ else show(event.key === 'Home' || event.key === 'End' ? next : selected)
97
+ } else if (event.key === 'Enter' || event.key === ' ') {
98
+ event.preventDefault(); event.stopPropagation()
99
+ if (open) choose(active)
100
+ else show()
101
+ } else if (event.key === 'Tab') setOpen(false)
102
+ else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
103
+ const now = Date.now(), previous = now - search.current.at < 700 ? search.current.text : ''
104
+ const query = (previous + event.key).toLocaleLowerCase()
105
+ const next = choices.findIndex(([, text]) => String(text).toLocaleLowerCase().startsWith(query))
106
+ if (next >= 0) {
107
+ event.preventDefault(); event.stopPropagation()
108
+ if (open) setActive(next)
109
+ else show(next)
110
+ }
111
+ search.current = { text: query, at: now }
112
+ }
113
+ }
114
+ return React.createElement('span', { className: 'dsh-super-code-select' },
115
+ React.createElement(ActionButton, {
116
+ ref: trigger, id: controlId, type: 'button', role: 'combobox', disabled: unavailable,
117
+ 'aria-label': label, 'aria-haspopup': 'listbox', 'aria-expanded': open, 'aria-controls': open ? listId : undefined,
118
+ 'aria-activedescendant': open ? `${listId}-${active}` : undefined, 'data-value': String(value),
119
+ className: 'dsh-super-code-select-trigger', onKeyDown: keyDown, onClick: () => { if (open) setOpen(false); else show() },
120
+ }, React.createElement('span', null, choices[selected]?.[1] || ''),
121
+ React.createElement('svg', { viewBox: '0 0 16 16', fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, 'aria-hidden': true },
122
+ React.createElement('path', { d: 'm4 6 4 4 4-4', strokeLinecap: 'round', strokeLinejoin: 'round' }))),
123
+ open && React.createElement('div', { ref: menu, id: listId, role: 'listbox', 'aria-label': label,
124
+ className: 'dsh-super-code-select-menu', style: placement,
125
+ onPointerDown: event => event.preventDefault(),
126
+ }, choices.map(([choice, text], index) => React.createElement('div', {
127
+ key: choice, id: `${listId}-${index}`, role: 'option', 'aria-selected': String(choice) === String(value),
128
+ 'data-value': String(choice), 'data-option-index': index, 'data-active': index === active,
129
+ className: 'dsh-super-code-select-option', onPointerMove: () => setActive(index), onClick: () => choose(index),
130
+ }, React.createElement('span', null, text),
131
+ React.createElement('svg', { viewBox: '0 0 16 16', fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, 'aria-hidden': true },
132
+ React.createElement('path', { d: 'm3.5 8 3 3 6-6', strokeLinecap: 'round', strokeLinejoin: 'round' }))))))
133
+ }
134
+
135
+
136
+ function Glyph({ type }) {
137
+ const paths = {
138
+ code: 'M8 5 3 10l5 5m8-10 5 5-5 5M14 3l-4 14',
139
+ branch: 'M5 3v8a4 4 0 0 0 4 4h6M5 7h10M5 3h0M15 4v6M15 12v6',
140
+ memory: 'M4 3h12a2 2 0 0 1 2 2v13H6a2 2 0 0 1-2-2V3Zm0 11h14M8 7h6M8 10h4',
141
+ search: 'M13 13l5 5M15 8a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z',
142
+ folder: 'M2 6V4h6l2 2h8v10H2V6Z',
143
+ user: 'M10 10a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm-6 7a6 6 0 0 1 12 0',
144
+ agent: 'm10 2 2.2 5.8L18 10l-5.8 2.2L10 18l-2.2-5.8L2 10l5.8-2.2L10 2Z',
145
+ tool: 'm6 5-4 5 4 5m8-10 4 5-4 5M12 3 8 17',
146
+ context: 'M3 5h14M3 10h14M3 15h9',
147
+ error: 'M10 6v5m0 3h0M10 2l8 15H2L10 2Z',
148
+ chevron: 'm6 8 4 4 4-4',
149
+ arrow: 'M3 10h13m-5-5 5 5-5 5',
150
+ fit: 'M3 7V3h4m6 0h4v4m0 6v4h-4m-6 0H3v-4',
151
+ history: 'M3 4v5h5M3 9a7 7 0 1 1 2 6m5-10v5l3 2',
152
+ organize: 'M8 2h4v4H8zM2 14h4v4H2zm12 0h4v4h-4zM10 6v4m-6 4v-4h12v4'
153
+ }
154
+ return React.createElement('svg', { className: 'dsh-super-code-glyph', viewBox: type === 'code' ? '0 0 24 20' : '0 0 20 20', fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true }, React.createElement('path', { d: paths[type] || paths.code }))
155
+ }
156
+
157
+ function AgentMessage({ record, saved, t, toolName }) {
158
+ const item = record.entry ? detailRecord(record.entry, t) : record
159
+ const eventType = record.entry?.event?.type
160
+ const kind = eventType === 'user/message' ? 'user' : eventType === 'assistant/message' ? 'agent'
161
+ : ['user', 'agent', 'tool', 'context', 'error'].includes(item.kind) ? item.kind : 'context'
162
+ const time = new Date(item.time).toLocaleTimeString(localeCode(t), { hour12: false })
163
+ const label = React.createElement('div', { className: 'dsh-super-code-detail-entry-label' },
164
+ React.createElement('span', null, item.label, toolName && !item.toolName ? ' · ' + toolName : ''), React.createElement('time', { dateTime: new Date(item.time).toISOString() }, time))
165
+ return React.createElement('article', { className: 'dsh-super-code-detail-entry ' + kind, 'data-event-type': eventType },
166
+ React.createElement('span', { className: 'dsh-super-code-detail-avatar', 'aria-hidden': true }, React.createElement(Glyph, { type: kind })),
167
+ React.createElement('div', { className: 'dsh-super-code-detail-message' }, item.collapsed
168
+ ? React.createElement('details', { open: saved.open.has(item.seq), onToggle: event => {
169
+ if (event.currentTarget.open) saved.open.add(item.seq); else saved.open.delete(item.seq)
170
+ } },
171
+ React.createElement('summary', null, label, React.createElement(Glyph, { type: 'chevron' })),
172
+ React.createElement(DetailText, { text: item.text, t }))
173
+ : React.createElement(React.Fragment, null, label, React.createElement(DetailText, { text: item.text, t }))))
174
+ }
175
+
176
+ /* Keep the native button and its refs/events; mount name bubbles outside clipped
177
+ * panels, or in the active dialog's top layer. No host-private UI is needed. */
178
+ let actionTooltipSequence = 0
179
+ let actionTooltipDismiss = () => {}
180
+ function actionButtonText(children) {
181
+ return React.Children.toArray(children).map(child => {
182
+ if (typeof child === 'string' || typeof child === 'number') return String(child)
183
+ if (!React.isValidElement(child) || child.props['aria-hidden']) return ''
184
+ return actionButtonText(child.props.children)
185
+ }).filter(Boolean).join(' ').replace(/\s+/g, ' ').trim()
186
+ }
187
+ const ActionButton = React.forwardRef(function ActionButton({ children, title, ...props }, forwardedRef) {
188
+ const button = useRef(null), pending = useRef(0), cleanup = useRef(() => {})
189
+ const name = props['aria-label'] || title || actionButtonText(children)
190
+ const attach = React.useCallback(node => {
191
+ button.current = node
192
+ if (typeof forwardedRef === 'function') forwardedRef(node)
193
+ else if (forwardedRef) forwardedRef.current = node
194
+ }, [forwardedRef])
195
+ // Event procedures deliberately return no value.
196
+ const hide = () => {
197
+ clearTimeout(pending.current)
198
+ pending.current = 0
199
+ cleanup.current()
200
+ cleanup.current = () => {}
201
+ if (actionTooltipDismiss === hide) actionTooltipDismiss = () => {}
202
+ }
203
+ const show = () => {
204
+ hide()
205
+ actionTooltipDismiss()
206
+ const anchor = button.current
207
+ if (!anchor || !name) return
208
+ const bubble = document.createElement('div'), id = `super-code-tooltip-${++actionTooltipSequence}`
209
+ bubble.id = id
210
+ bubble.className = 'dsh-super-code-tooltip'
211
+ bubble.setAttribute('role', 'tooltip')
212
+ bubble.textContent = name
213
+ bubble.style.visibility = 'hidden'
214
+ ;(anchor.closest('dialog[open]') || document.body).appendChild(bubble)
215
+ const rect = anchor.getBoundingClientRect(), bounds = bubble.getBoundingClientRect(), margin = 8, gap = 8
216
+ const left = Math.max(margin, Math.min(rect.left + rect.width / 2 - bounds.width / 2, window.innerWidth - bounds.width - margin))
217
+ const top = Math.max(margin, rect.top - bounds.height - gap)
218
+ bubble.dataset.side = 'top'
219
+ bubble.style.left = left + 'px'
220
+ bubble.style.top = top + 'px'
221
+ bubble.style.setProperty('--sc-tooltip-arrow-left', Math.max(8, Math.min(bounds.width - 8, rect.left + rect.width / 2 - left)) + 'px')
222
+ bubble.style.visibility = 'visible'
223
+ anchor.setAttribute('aria-describedby', [anchor.getAttribute('aria-describedby'), id].filter(Boolean).join(' '))
224
+ const escape = event => { if (event.key === 'Escape') hide() }
225
+ window.addEventListener('resize', hide)
226
+ window.addEventListener('scroll', hide, true)
227
+ window.addEventListener('keydown', escape, true)
228
+ document.addEventListener('pointerdown', hide, true)
229
+ cleanup.current = () => {
230
+ bubble.remove()
231
+ const remaining = (anchor.getAttribute('aria-describedby') || '').split(/\s+/).filter(value => value && value !== id).join(' ')
232
+ if (remaining) anchor.setAttribute('aria-describedby', remaining)
233
+ else anchor.removeAttribute('aria-describedby')
234
+ window.removeEventListener('resize', hide)
235
+ window.removeEventListener('scroll', hide, true)
236
+ window.removeEventListener('keydown', escape, true)
237
+ document.removeEventListener('pointerdown', hide, true)
238
+ }
239
+ actionTooltipDismiss = hide
240
+ }
241
+ useEffect(() => { hide() }, [name])
242
+ useEffect(() => () => hide(), [])
243
+ return React.createElement('button', {
244
+ ...props, ref: attach, 'data-tooltip-name': name,
245
+ onPointerEnter: event => {
246
+ props.onPointerEnter?.(event)
247
+ if (event.pointerType !== 'touch') { hide(); pending.current = setTimeout(show, 250) }
248
+ },
249
+ onPointerLeave: event => { hide(); props.onPointerLeave?.(event) },
250
+ onPointerCancel: event => { hide(); props.onPointerCancel?.(event) },
251
+ onFocus: event => { props.onFocus?.(event); if (event.currentTarget.matches(':focus-visible')) show() },
252
+ onBlur: event => { hide(); props.onBlur?.(event) },
253
+ onKeyDown: event => { hide(); props.onKeyDown?.(event) },
254
+ }, children)
255
+ })
256
+
18
257
  const LOCALE_NS = 'dshSuperCode'
19
258
  const zh = {
259
+ 'tree.collapsedLabel': '已收起', 'tree.organizeLabel': '自动整理',
260
+ 'detail.toolCall': '工具调用', 'detail.toolResult': '工具结果', 'detail.toolError': '工具失败',
261
+ 'detail.cache': '缓存', 'detail.info': '详情', 'tree.countCompact': '{shown}/{total} · 运行 {running}',
262
+ 'memory.loading': '正在读取记忆…', 'memory.topics': '知识主题', 'memory.allTopics': '全部主题', 'memory.related': '同主题知识', 'preset.configuration': '预设配置',
20
263
  'memory.title': '记忆库', 'memory.project': '当前项目', 'memory.global': '全局偏好', 'memory.search': '搜索主题或记忆',
21
- 'memory.description': '跨对话保留的经验与偏好。按需读取,不会整库塞进上下文。',
264
+ 'memory.description': '知识主题与条目',
22
265
  'memory.empty': '还没有保存的记忆。需要长期保留时,直接告诉 Agent 即可。', 'memory.noMatches': '没有匹配的记忆',
23
266
  'memory.selectSession': '先打开一个对话,查看它所在项目的记忆。', 'memory.error': '暂时无法读取记忆,请刷新重试。',
24
267
  'memory.refresh': '刷新记忆库', 'memory.count': '{count} 条记忆', 'memory.back': '返回列表', 'memory.missing': '这条记忆已删除或更新,请刷新列表。',
@@ -28,13 +271,26 @@ const zh = {
28
271
  'memory.usageEmpty': '尚无记忆读取记录', 'memory.context': '带入上下文', 'memory.read': '读取详情', 'memory.summary': '读取摘要',
29
272
  'memory.remember': '保存', 'memory.forget': '删除', 'memory.omitted': '仅展示最近 100 条不同动作,完整记录保留在会话中。', 'memory.open': '查看记忆库',
30
273
  'preset.title': 'Super Code 模式', 'usage.cacheUnknown': '缓存 —',
31
- 'preset.description': '更快、更省、更聪明的编码模式。', 'preset.refresh': '刷新状态', 'preset.expand': '展开设置', 'preset.collapse': '收起设置',
274
+ 'preset.description': '更快、更省、更聪明的编码模式。', 'preset.refresh': '刷新状态',
32
275
  'preset.state.available': '预设可用', 'preset.state.installed': '用户预设已安装', 'preset.state.conflict': '已有同名预设',
33
276
  'preset.state.missing': '尚未安装', 'preset.state.broken': '预设不可用',
34
- 'preset.availableHint': '可在新对话中选择此预设。升级仅更新未修改的默认名称和描述。',
35
- 'preset.installHint': '安装一份用户预设;已有内容会保留,标识符冲突时请换个标识符。',
277
+ 'preset.availableHint': '可在新对话中选择此预设。',
278
+ 'preset.installHint': '安装 Super Code 预设;已有内容会保留,标识符冲突时请换个标识符。',
36
279
  'preset.userConflict': '用户目录中已有相同标识符的预设,已保留。可更换标识符安装独立副本。',
37
- 'preset.readonly': '此宿主未提供用户预设目录,无法安装副本。',
280
+ 'preset.declaredHint': '此宿主通过预设声明加载 Super Code,可在此安装或确认重装。',
281
+ 'preset.declaredReadonly': '此宿主通过插件声明加载预设,但未开放管理接口。请检查插件启用状态或重启宿主。',
282
+ 'preset.state.declaredInstalled': '预设已安装',
283
+ 'preset.installDeclared': '安装预设',
284
+ 'preset.declaredNameHint': '用于识别预设,通常保留 super-code。以小写字母或数字开头,仅支持小写字母、数字和连字符,最多 64 个字符。',
285
+ 'preset.readonly': '此宿主未开放用户预设目录,无法在此安装或重装副本。',
286
+ 'preset.unavailableHint': '请检查插件是否已启用,然后重启宿主或刷新状态。',
287
+ 'preset.pluginVersion': '插件版本', 'preset.presetVersion': '当前预设版本',
288
+ 'preset.versionUnknown': '未记录版本', 'preset.versionMissing': '未安装',
289
+ 'preset.versionMatches': '预设版本与当前插件一致。',
290
+ 'preset.versionMismatch': '预设版本与当前插件版本不一致。',
291
+ 'preset.versionUnknownHint': '此预设未记录版本,无法确认是否与当前插件一致。',
292
+ 'preset.versionReinstallHint': '如需更新预设,请先保留自定义内容,再确认重新安装。',
293
+ 'preset.versionReloadHint': '请确认插件更新已生效,重启宿主后刷新状态;若仍不一致,请重新安装插件。',
38
294
  'preset.displayName': '显示名称', 'preset.displayNameHint': '支持中文和空格,最多 120 个字符,例如 Super Code 模式。', 'preset.name': '预设标识符', 'preset.nameHint': '用于安装目录,通常保留 super-code 即可。以小写字母或数字开头,仅含小写字母、数字和连字符,最多 64 个字符。',
39
295
  'preset.confirmTitle': '确认重新安装预设',
40
296
  'preset.confirmHint': '以下是通过本插件安装的预设,将会被移除并按照新名称重新安装,旧内容会保留恢复备份。对于需要保留的预设可以手动在列表中移除。',
@@ -46,7 +302,8 @@ const zh = {
46
302
  'preset.error.invalid-display-name': '显示名称不能为空或全为空格,最多 120 个字符;支持中文和空格。',
47
303
  'preset.error.name-taken': '该标识符已被占用,原预设未改动。请更换标识符。',
48
304
  'preset.error.no-user-root': '此宿主没有可写的用户预设目录。',
49
- 'preset.error.install-failed': '安装未完成,请检查预设目录的写入权限后重试。',
305
+ 'preset.error.management-unavailable': '此宿主未开放预设管理接口,请检查插件启用状态或重启宿主。',
306
+ 'preset.error.install-failed': '安装未完成,已尝试恢复原配置。请检查写入权限和宿主日志后重试。',
50
307
  'preset.error.connection': '暂时无法读取预设状态,请刷新重试。',
51
308
  'task.memory': '任务档案', 'task.other': '其他任务', 'task.history': '任务记录',
52
309
  'status.active': '进行中', 'status.paused': '已暂停', 'status.completed': '已完成', 'status.cancelled': '已取消',
@@ -62,8 +319,12 @@ const zh = {
62
319
  'detail.path': 'Agent 路径', 'detail.title': 'Agent 详情', 'detail.refresh': '刷新对话详情', 'detail.task': '任务', 'detail.agent': 'Agent', 'detail.interrupted': 'Agent · 已中断', 'detail.error': '执行错误', 'detail.incomplete': '执行未完成,请稍后重试。', 'detail.input': '输入', 'detail.output': '输出', 'detail.cacheRead': '缓存读取', 'detail.cacheWrite': '缓存写入', 'detail.total': 'Token 总量', 'detail.hitRate': '缓存命中率', 'detail.moreUsage': '用量详情', 'detail.unavailable': '未提供', 'detail.reading': '正在读取对话…', 'detail.read': '读取中…', 'detail.older': '加载更早记录', 'detail.latest': '回到最新', 'detail.empty': '暂无执行内容', 'detail.new': '有新内容 · 查看最新', 'detail.loadError': '对话详情读取失败', 'detail.connection': '连接中断,正在重连', 'detail.historyError': '历史记录读取失败', 'detail.open': '展开全文', 'detail.noAccess': '无法打开详情,请重试', 'tree.loadError': '部分执行记录读取失败,请刷新重试', 'detail.unknown': '用量未知', 'main.agent': '主 Agent', 'tree.open': '点击查看详情', 'tree.expand': '展开', 'tree.collapse': '收起', 'image': '[图片]'
63
320
  }
64
321
  const en = {
322
+ 'tree.collapsedLabel': 'Collapsed', 'tree.organizeLabel': 'Organize',
323
+ 'detail.toolCall': 'Tool call', 'detail.toolResult': 'Tool result', 'detail.toolError': 'Tool failed',
324
+ 'detail.cache': 'Cache', 'detail.info': 'Details', 'tree.countCompact': '{shown}/{total} · Running {running}',
325
+ 'memory.loading': 'Loading memories…', 'memory.topics': 'Knowledge topics', 'memory.allTopics': 'All topics', 'memory.related': 'More in this topic', 'preset.configuration': 'Preset configuration',
65
326
  'memory.title': 'Memory library', 'memory.project': 'This project', 'memory.global': 'Global preferences', 'memory.search': 'Search topics or memories',
66
- 'memory.description': 'Experience and preferences kept across conversations. Details are read on demand, never injected in bulk.',
327
+ 'memory.description': 'Knowledge topics and entries',
67
328
  'memory.empty': 'No saved memories yet. Tell the agent when something is worth keeping.', 'memory.noMatches': 'No matching memories',
68
329
  'memory.selectSession': 'Open a conversation to view memory for its project.', 'memory.error': 'Memory is unavailable. Refresh to try again.',
69
330
  'memory.refresh': 'Refresh memory', 'memory.count': '{count} memories', 'memory.back': 'Back to list', 'memory.missing': 'This memory was removed or changed. Refresh the list.',
@@ -73,13 +334,26 @@ const en = {
73
334
  'memory.usageEmpty': 'No memory reads recorded yet', 'memory.context': 'Added to context', 'memory.read': 'Read details', 'memory.summary': 'Read summary',
74
335
  'memory.remember': 'Saved', 'memory.forget': 'Removed', 'memory.omitted': 'Showing the latest 100 distinct actions. Full records remain in the conversation.', 'memory.open': 'Open memory library',
75
336
  'preset.title': 'Super Code', 'usage.cacheUnknown': 'Cache —',
76
- 'preset.description': 'A faster, more efficient, smarter coding mode.', 'preset.refresh': 'Refresh status', 'preset.expand': 'Show settings', 'preset.collapse': 'Hide settings',
337
+ 'preset.description': 'A faster, more efficient, smarter coding mode.', 'preset.refresh': 'Refresh status',
77
338
  'preset.state.available': 'Preset available', 'preset.state.installed': 'User preset installed', 'preset.state.conflict': 'Preset name already exists',
78
339
  'preset.state.missing': 'Not installed', 'preset.state.broken': 'Preset unavailable',
79
- 'preset.availableHint': 'Select this preset in a new conversation. Upgrades update only unchanged default names and descriptions.',
80
- 'preset.installHint': 'Install a user copy. Existing content is preserved; choose another identifier if it is taken.',
340
+ 'preset.availableHint': 'Select this preset in a new conversation.',
341
+ 'preset.installHint': 'Install the Super Code preset. Existing content is preserved; choose another identifier if it is taken.',
81
342
  'preset.userConflict': 'A user preset with this identifier already exists and was preserved. Choose another identifier for a separate copy.',
82
- 'preset.readonly': 'This host does not provide a user preset directory.',
343
+ 'preset.declaredHint': 'This host loads Super Code through a preset declaration. You can install it here or confirm reinstallation.',
344
+ 'preset.declaredReadonly': 'This host loads plugin preset declarations but does not expose preset management. Check plugin activation or restart the host.',
345
+ 'preset.state.declaredInstalled': 'Preset installed',
346
+ 'preset.installDeclared': 'Install preset',
347
+ 'preset.declaredNameHint': 'Identifies the preset; usually keep super-code. Start with a lowercase letter or digit; use only lowercase letters, digits and hyphens, up to 64 characters.',
348
+ 'preset.readonly': 'This host does not expose a user preset directory for installing or reinstalling copies.',
349
+ 'preset.unavailableHint': 'Check that the plugin is enabled, then restart the host or refresh the status.',
350
+ 'preset.pluginVersion': 'Plugin version', 'preset.presetVersion': 'Current preset version',
351
+ 'preset.versionUnknown': 'Version not recorded', 'preset.versionMissing': 'Not installed',
352
+ 'preset.versionMatches': 'The preset version matches the installed plugin.',
353
+ 'preset.versionMismatch': 'The preset version differs from the installed plugin.',
354
+ 'preset.versionUnknownHint': 'This preset has no recorded version, so its version cannot be compared with the installed plugin.',
355
+ 'preset.versionReinstallHint': 'To update the preset, save any custom content, then confirm reinstallation.',
356
+ 'preset.versionReloadHint': 'Check that the plugin update has taken effect, restart the host and refresh the status. If the versions still differ, reinstall the plugin.',
83
357
  'preset.displayName': 'Display name', 'preset.displayNameHint': 'Supports Chinese characters and spaces, up to 120 characters, e.g. Super Code 模式.', 'preset.name': 'Preset identifier', 'preset.nameHint': 'Used for the installation directory; usually keep super-code. Start with a lowercase letter or digit; use only lowercase letters, digits and hyphens, up to 64 characters.',
84
358
  'preset.confirmTitle': 'Confirm preset reinstallation',
85
359
  'preset.confirmHint': 'These presets were installed by this plugin. They will be removed and reinstalled with the new names shown, and recovery backups will be kept. Remove any preset you want to keep from the list.',
@@ -91,7 +365,8 @@ const en = {
91
365
  'preset.error.invalid-display-name': 'The display name cannot be empty or whitespace-only and must be at most 120 characters. Chinese characters and spaces are supported.',
92
366
  'preset.error.name-taken': 'This identifier is taken. The existing preset was preserved. Choose another identifier.',
93
367
  'preset.error.no-user-root': 'This host has no writable user preset directory.',
94
- 'preset.error.install-failed': 'Installation failed. Check directory write permissions and retry.',
368
+ 'preset.error.management-unavailable': 'This host does not expose preset management. Check plugin activation or restart the host.',
369
+ 'preset.error.install-failed': 'Installation failed and restoration of the original configuration was attempted. Check write permissions and host logs, then retry.',
95
370
  'preset.error.connection': 'Preset status is unavailable. Refresh to try again.',
96
371
  'task.memory': 'Task memory', 'task.other': 'Other tasks', 'task.history': 'Task history',
97
372
  'status.active': 'Active', 'status.paused': 'Paused', 'status.completed': 'Completed', 'status.cancelled': 'Cancelled', 'next': 'Next: ',
@@ -376,9 +651,9 @@ function AgentHistory({ view, hidden, totals, open, t = key => zh[key] || key })
376
651
  else if ((target + 1) * historyRowHeight > element.scrollTop + element.clientHeight) element.scrollTop = (target + 1) * historyRowHeight - element.clientHeight
377
652
  setScroll({ top: element.scrollTop, height: element.clientHeight })
378
653
  }
379
- const select = (key, label, choices) => React.createElement('label', null, label,
380
- React.createElement('select', { value: filters[key], 'aria-label': label, onChange: event => change(key, event.target.value) },
381
- choices.map(([value, text]) => React.createElement('option', { key: value, value }, text))))
654
+ const select = (key, label, choices) => React.createElement('div', { className: 'dsh-super-code-select-field' },
655
+ React.createElement('label', { htmlFor: 'super-code-history-' + key }, label),
656
+ React.createElement(SelectControl, { id: 'super-code-history-' + key, label, value: filters[key], choices, onChange: value => change(key, value) }))
382
657
  return React.createElement('section', { className: 'dsh-super-code-history', 'aria-label': text(t, 'history.aria') },
383
658
  React.createElement('input', { type: 'search', value: filters.query, 'aria-label': text(t, 'history.find'), placeholder: text(t, 'history.search'), onChange: event => change('query', event.target.value) }),
384
659
  React.createElement('div', { className: 'dsh-super-code-history-filters' },
@@ -395,7 +670,7 @@ function AgentHistory({ view, hidden, totals, open, t = key => zh[key] || key })
395
670
  const date = record.time < 0 ? text(t, 'history.unknownTime') : dateFormat.format(record.time)
396
671
  return React.createElement('div', { key: record.id, role: 'listitem', 'aria-posinset': index + 1, 'aria-setsize': records.length,
397
672
  style: { position: 'absolute', top: index * historyRowHeight, height: historyRowHeight, width: '100%' } },
398
- React.createElement('button', { type: 'button', 'data-history-id': record.id, onClick: () => open(record.node), onKeyDown: event => keyDown(event, index),
673
+ React.createElement(ActionButton, { type: 'button', 'data-history-id': record.id, onClick: () => open(record.node), onKeyDown: event => keyDown(event, index),
399
674
  title: `${record.title} · ${record.parent} · ${record.time < 0 ? date : new Date(record.time).toLocaleString(localeCode(t))} · ${record.tokens < 0 ? text(t, 'history.unknownUsage') : record.tokens + ' Token' + (record.partial ? ' (' + text(t, 'usage.partial') + ')' : '')}`,
400
675
  'aria-label': text(t, 'history.view', { title: record.title }) },
401
676
  React.createElement('i', { className: 'dsh-super-code-circle ' + status.tone, 'aria-hidden': true }),
@@ -569,23 +844,24 @@ function AgentTreeBody({ state, view, saved, openDetail, refresh, watchCatalog,
569
844
  return React.createElement('section', { className: 'dsh-super-code-tree', 'data-super-agent-tree': true },
570
845
  watched.map(id => React.createElement(AgentCatalogWatch, { key: id, id, watchCatalog })),
571
846
  React.createElement('header', { className: 'dsh-super-code-tree-header' },
572
- React.createElement('div', null,
573
- React.createElement('strong', null, text(t, 'tree.title')),
574
- React.createElement('span', { className: 'dsh-super-code-tree-count' }, text(t, 'tree.count', { shown: rows.length, total: view.nodes.size, running }))),
575
- React.createElement('button', { type: 'button', className: 'dsh-super-code-icon-button', disabled: busy || !view.root, onClick: reload, title: text(t, 'tree.refresh'), 'aria-label': text(t, 'tree.refresh') }, React.createElement(IconRefreshOutline16))),
847
+ React.createElement('div', { className: 'dsh-super-code-tree-heading' },
848
+ React.createElement('div', { className: 'dsh-super-code-title-line' }, React.createElement(Glyph, { type: 'branch' }), React.createElement('strong', null, text(t, 'tree.title'))),
849
+ React.createElement('span', { className: 'dsh-super-code-tree-count', title: text(t, 'tree.count', { shown: rows.length, total: view.nodes.size, running }) }, text(t, 'tree.countCompact', { shown: rows.length, total: view.nodes.size, running }))),
850
+ React.createElement('div', { className: 'dsh-super-code-tree-toolbar' },
851
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-icon-button', disabled: busy || !view.root, onClick: reload, title: text(t, 'tree.refresh'), 'aria-label': text(t, 'tree.refresh') }, React.createElement(IconRefreshOutline16)),
852
+ React.createElement('div', { className: 'dsh-super-code-graph-controls', 'aria-label': text(t, 'tree.canvas') },
853
+ React.createElement(ActionButton, { type: 'button', title: text(t, 'tree.zoom.out'), 'aria-label': text(t, 'tree.zoom.out'), disabled: zoom <= .4, onClick: () => zoomButton(1 / 1.2) }, '−'),
854
+ React.createElement('span', { 'aria-live': 'polite' }, `${Math.round(zoom * 100)}%`),
855
+ React.createElement(ActionButton, { type: 'button', title: text(t, 'tree.zoom.in'), 'aria-label': text(t, 'tree.zoom.in'), disabled: zoom >= 2, onClick: () => zoomButton(1.2) }, '+')),
856
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'tree.fit'), 'aria-label': text(t, 'tree.fit'), onClick: fit }, React.createElement(Glyph, { type: 'fit' })),
857
+ (display.hidden.length > 0 || expanded.size > 0 || collapsed.size > 0) && React.createElement('div', { className: 'dsh-super-code-history-controls' },
858
+ React.createElement(ActionButton, { type: 'button', title: text(t, 'tree.collapsed', { count: display.hidden.length }), 'aria-label': text(t, 'tree.collapsed', { count: display.hidden.length }), 'aria-expanded': historyOpen, onClick: () => setHistoryOpen(!historyOpen) }, React.createElement(Glyph, { type: 'history' }), React.createElement('span', { className: 'dsh-super-code-action-label' }, text(t, 'tree.collapsedLabel')), React.createElement('span', { className: 'dsh-super-code-action-count' }, display.hidden.length)),
859
+ (expanded.size > 0 || collapsed.size > 0) && React.createElement(ActionButton, { type: 'button', title: text(t, 'tree.organize'), 'aria-label': text(t, 'tree.organize'), onClick: () => { autoFit.current = true; setExpanded(new Set()); setCollapsed(new Set()); setFocused(state.current) } }, React.createElement(Glyph, { type: 'organize' }), React.createElement('span', { className: 'dsh-super-code-action-label' }, text(t, 'tree.organizeLabel'))))),
860
+ React.createElement('div', { className: 'dsh-super-code-graph-legend', 'aria-label': text(t, 'tree.status') },
861
+ ['tree.legend.active', 'tree.legend.idle', 'tree.legend.stopped', 'tree.legend.unavailable'].map((key, index) => React.createElement('span', { key },
862
+ React.createElement('i', { className: 'dsh-super-code-circle ' + ['active', 'idle', 'stopped', 'unavailable'][index], 'aria-hidden': true }), text(t, key))))),
576
863
  (error || catalogError) && React.createElement('p', { role: 'alert', className: 'dsh-super-code-tree-error' }, text(t, error || 'tree.loadError')),
577
- React.createElement('div', { className: 'dsh-super-code-graph-legend', 'aria-label': text(t, 'tree.status') },
578
- ['tree.legend.active', 'tree.legend.idle', 'tree.legend.stopped', 'tree.legend.unavailable'].map((key, index) => React.createElement('span', { key },
579
- React.createElement('i', { className: 'dsh-super-code-circle ' + ['active', 'idle', 'stopped', 'unavailable'][index], 'aria-hidden': true }), text(t, key)))),
580
864
  !view.root && React.createElement('p', { className: 'dsh-super-code-tree-empty' }, text(t, 'tree.empty')),
581
- React.createElement('div', { className: 'dsh-super-code-graph-controls', 'aria-label': text(t, 'tree.canvas') },
582
- React.createElement('button', { type: 'button', 'aria-label': text(t, 'tree.zoom.out'), disabled: zoom <= .4, onClick: () => zoomButton(1 / 1.2) }, '−'),
583
- React.createElement('span', { 'aria-live': 'polite' }, `${Math.round(zoom * 100)}%`),
584
- React.createElement('button', { type: 'button', 'aria-label': text(t, 'tree.zoom.in'), disabled: zoom >= 2, onClick: () => zoomButton(1.2) }, '+'),
585
- React.createElement('button', { type: 'button', onClick: fit }, text(t, 'tree.fit'))),
586
- (display.hidden.length > 0 || expanded.size > 0 || collapsed.size > 0) && React.createElement('div', { className: 'dsh-super-code-history-controls' },
587
- React.createElement('button', { type: 'button', 'aria-expanded': historyOpen, onClick: () => setHistoryOpen(!historyOpen) }, text(t, 'tree.collapsed', { count: display.hidden.length })),
588
- (expanded.size > 0 || collapsed.size > 0) && React.createElement('button', { type: 'button', onClick: () => { autoFit.current = true; setExpanded(new Set()); setCollapsed(new Set()); setFocused(state.current) } }, text(t, 'tree.organize'))),
589
865
  historyOpen && React.createElement(AgentHistory, { view, hidden: display.hidden, totals, open, t }),
590
866
  React.createElement('div', { ref: viewport, className: 'dsh-super-code-graph-scroll',
591
867
  onPointerDown: event => {
@@ -622,7 +898,7 @@ function AgentTreeBody({ state, view, saved, openDetail, refresh, watchCatalog,
622
898
  const number = value => value.toLocaleString(localeCode(t), { notation: 'compact', maximumFractionDigits: 1 })
623
899
  const hasChildren = (view.children.get(row.id) || []).length > 0
624
900
  const isExpanded = (display.view.children.get(row.id) || []).length > 0
625
- return React.createElement(React.Fragment, { key: row.id }, React.createElement('button', {
901
+ return React.createElement(React.Fragment, { key: row.id }, React.createElement(ActionButton, {
626
902
  type: 'button',
627
903
  role: 'treeitem', tabIndex: row.id === focusId ? 0 : -1, 'data-agent-id': row.id,
628
904
  'aria-level': row.level, 'aria-selected': row.id === state.current,
@@ -636,16 +912,17 @@ function AgentTreeBody({ state, view, saved, openDetail, refresh, watchCatalog,
636
912
  React.createElement('span', { className: 'dsh-super-code-circle ' + tone, 'aria-hidden': true }, row.id === view.root ? text(t, 'main.agent').slice(0, 1) : String(rows.findIndex(item => item.id === row.id))),
637
913
  React.createElement('span', { className: 'dsh-super-code-tree-content' },
638
914
  React.createElement('span', { className: 'dsh-super-code-tree-title' }, title),
915
+ React.createElement('span', { className: 'dsh-super-code-node-status', 'data-tone': tone }, React.createElement('i', { 'aria-hidden': true }), status),
639
916
  React.createElement('span', { className: 'dsh-super-code-tree-usage', title: text(t, 'tree.usage', { partial: partial ? text(t, 'usage.incomplete') : '', tokens: usage.tokens.toLocaleString(localeCode(t)), cache: usage.cache.toLocaleString(localeCode(t)), agents: usage.agents }) },
640
917
  React.createElement('span', null, usage.known ? `${number(usage.tokens)} token` : text(t, 'usage.unknown')),
641
918
  React.createElement('span', null, usage.known ? text(t, 'usage.cache', { value: usage.input ? Math.round(usage.cache / usage.input * 100) : 0 }) + (partial ? ` · ${text(t, 'usage.partial')}` : '') : text(t, 'usage.cacheUnknown'))))),
642
- hasChildren && React.createElement('button', { type: 'button', className: 'dsh-super-code-branch-toggle',
919
+ hasChildren && React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-branch-toggle',
643
920
  style: { left: row.x + 21, top: row.y + 25 }, 'aria-label': `${collapsed.has(row.id) || !isExpanded ? text(t, 'tree.expand') : text(t, 'tree.collapse')} ${title}`,
644
921
  title: text(t, 'tree.organize'), onClick: () => toggleBranch(row.id) },
645
922
  React.createElement('svg', { width: 12, height: 12, viewBox: '0 0 12 12', 'aria-hidden': true, style: { transform: collapsed.has(row.id) || !isExpanded ? 'rotate(-90deg)' : undefined } },
646
923
  React.createElement('path', { d: 'M3 4.5 6 7.5 9 4.5', fill: 'none', stroke: 'currentColor', strokeWidth: 1.5 }))))
647
924
  }))),
648
- more && React.createElement('button', { type: 'button', className: 'dsh-super-code-tree-more', onClick: () => setLimit(limit + 200) }, text(t, 'tree.more')))
925
+ more && React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-tree-more', onClick: () => setLimit(limit + 200) }, text(t, 'tree.more')))
649
926
  }
650
927
 
651
928
  function agentDetailAddress(node) {
@@ -695,6 +972,23 @@ function detailRecord(entry, t = key => zh[key] || key) {
695
972
  return { ...base, kind: 'message', label: text(t, 'detail.task'), text: contentText(data.content, t) }
696
973
  }
697
974
  if (event.type === 'assistant/message') return { ...base, kind: 'message', label: data.interrupted ? text(t, 'detail.interrupted') : text(t, 'detail.agent'), text: contentText(data.message?.content, t) }
975
+ if (event.type === 'tool/call' && typeof data.name === 'string' && data.name) {
976
+ let value = typeof data.arguments === 'string' ? data.arguments : JSON.stringify(data.arguments ?? {})
977
+ try { value = JSON.stringify(JSON.parse(value), null, 2) } catch { /* Incomplete arguments remain readable. */ }
978
+ return { ...base, kind: 'tool', collapsed: true, toolName: data.name, callId: data.callId,
979
+ label: text(t, 'detail.toolCall') + ' · ' + data.name, text: value }
980
+ }
981
+ if (event.type === 'tool/result') {
982
+ const blocks = (data.message?.content || []).filter(block => block.type === 'tool-result')
983
+ // Older journals store a direct tool message; newer ones nest its content.
984
+ const direct = data.message?.role === 'tool'
985
+ if (!blocks.length && !direct) return { kind: 'skip' }
986
+ const failed = direct ? data.message.isError : blocks.some(block => block.isError)
987
+ return { ...base, kind: failed ? 'error' : 'tool', collapsed: true,
988
+ callId: direct ? data.message.toolCallId : blocks[0]?.toolCallId,
989
+ label: text(t, failed ? 'detail.toolError' : 'detail.toolResult'),
990
+ text: contentText(direct ? data.message.content : blocks.flatMap(block => block.content || []), t) }
991
+ }
698
992
  if (event.type === 'turn/error') return { ...base, kind: 'error', label: text(t, 'detail.error'), text: data.message || text(t, 'detail.incomplete') }
699
993
  return { kind: 'skip' }
700
994
  }
@@ -770,17 +1064,16 @@ function DetailText({ text: value, t = key => zh[key] || key }) {
770
1064
  const [full, setFull] = useState(false)
771
1065
  return React.createElement(React.Fragment, null,
772
1066
  React.createElement('pre', null, full ? value : value.slice(0, 12000)),
773
- !full && value.length > 12000 && React.createElement('button', { type: 'button', onClick: () => setFull(true) }, text(t, 'detail.open')))
1067
+ !full && value.length > 12000 && React.createElement(ActionButton, { type: 'button', onClick: () => setFull(true) }, text(t, 'detail.open')))
774
1068
  }
775
1069
 
776
1070
  function MemoryActivity({ usage, openMemory, sessionId, t }) {
777
1071
  const rows = [...(usage?.rows || [])].reverse()
778
1072
  return React.createElement('details', { className: 'dsh-super-code-memory-activity' },
779
1073
  React.createElement('summary', null, text(t, 'memory.agentUsage'), rows.length ? ` · ${rows.length}` : ''),
780
- React.createElement('p', { className: 'dsh-super-code-memory-muted' }, text(t, 'memory.usageHint')),
781
1074
  !rows.length && React.createElement('p', null, text(t, 'memory.usageEmpty')),
782
1075
  React.createElement('div', { className: 'dsh-super-code-memory-activity-list' }, rows.map(row =>
783
- React.createElement('button', { key: `${row.scope}/${row.topic}/${row.id}/${row.action}`, type: 'button',
1076
+ React.createElement(ActionButton, { key: `${row.scope}/${row.topic}/${row.id}/${row.action}`, type: 'button',
784
1077
  onClick: () => openMemory(sessionId, row), title: text(t, 'memory.open') },
785
1078
  React.createElement('span', { className: 'dsh-super-code-memory-action', 'data-action': row.action }, text(t, `memory.${row.action}`)),
786
1079
  React.createElement('span', null, row.summary || row.id),
@@ -823,11 +1116,12 @@ function MemoryLibrary({ useTabInfo, useSessions, sessionId: scopeSessionId, api
823
1116
  }, [memoryStates, tab.signal])
824
1117
  const [scope, setScope] = useState(saved.scope || target.scope)
825
1118
  const [query, setQuery] = useState(saved.query || '')
1119
+ const [topicFilter, setTopicFilter] = useState(saved.topicFilter || '')
826
1120
  const [selected, setSelected] = useState(saved.selected || (target.id ? { topic: target.topic, id: target.id } : null))
827
1121
  const [state, setState] = useState({ key: '', items: [], loading: true, error: false })
828
1122
  const [detail, setDetail] = useState(null), [revision, setRevision] = useState(0)
829
1123
  const [viewport, setViewport] = useState({ top: saved.top || 0, height: 600 })
830
- const list = useRef(null), sessionId = target.sessionId
1124
+ const list = useRef(null), detailBody = useRef(null), sessionId = target.sessionId
831
1125
  const key = `${sessionId}/${scope}`, selectionKey = selected ? `${key}/${selected.topic}/${selected.id}` : ''
832
1126
  const visibleState = state.key === key ? state : { items: [], loading: true, error: false }
833
1127
  useEffect(() => {
@@ -858,38 +1152,66 @@ function MemoryLibrary({ useTabInfo, useSessions, sessionId: scopeSessionId, api
858
1152
  return () => observer.disconnect()
859
1153
  }, [selected, key, tab.visible])
860
1154
  const resetScroll = () => { saved.top = 0; if (list.current) list.current.scrollTop = 0; setViewport(value => ({ ...value, top: 0 })) }
861
- const choose = value => { saved.selected = value; setSelected(value) }
862
- const page = useMemo(() => memoryLibraryWindow(visibleState.items, query, viewport.top, viewport.height), [visibleState.items, query, viewport])
1155
+ const choose = value => { if (detailBody.current) detailBody.current.scrollTop = 0; saved.selected = value; setSelected(value) }
1156
+ const changeTopic = value => { saved.topicFilter = value; setTopicFilter(value); resetScroll() }
1157
+ const topics = useMemo(() => {
1158
+ const counts = new Map()
1159
+ for (const item of visibleState.items) counts.set(item.topic, (counts.get(item.topic) || 0) + 1)
1160
+ return [...counts].map(([topic, count]) => ({ topic, count })).sort((a, b) => a.topic.localeCompare(b.topic, localeCode(t)))
1161
+ }, [visibleState.items, t])
1162
+ const topicItems = useMemo(() => topicFilter ? visibleState.items.filter(item => item.topic === topicFilter) : visibleState.items, [visibleState.items, topicFilter])
1163
+ const page = useMemo(() => memoryLibraryWindow(topicItems, query, viewport.top, viewport.height), [topicItems, query, viewport])
863
1164
  const currentDetail = detail?.key === selectionKey ? detail : null
864
1165
  const entry = currentDetail?.kind === 'found' ? currentDetail.entry : null
1166
+ const related = entry ? visibleState.items.filter(item => item.topic === entry.topic && item.id !== entry.id).slice(0, 5) : []
865
1167
  return React.createElement('section', { className: 'dsh-super-code-memory', 'aria-label': text(t, 'memory.title') },
866
1168
  React.createElement('header', null,
867
- React.createElement('div', { className: 'dsh-super-code-memory-heading' }, React.createElement('h2', null, text(t, 'memory.title')),
868
- React.createElement('button', { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'memory.refresh'), 'aria-label': text(t, 'memory.refresh'), onClick: () => setRevision(value => value + 1) }, React.createElement(IconRefreshOutline16))),
869
- React.createElement('p', { className: 'dsh-super-code-memory-muted' }, text(t, 'memory.description')),
1169
+ React.createElement('div', { className: 'dsh-super-code-memory-heading' },
1170
+ React.createElement('div', { className: 'dsh-super-code-title-line' }, React.createElement(Glyph, { type: 'memory' }), React.createElement('h2', null, text(t, 'memory.title'))),
1171
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'memory.refresh'), 'aria-label': text(t, 'memory.refresh'), onClick: () => setRevision(value => value + 1) }, React.createElement(IconRefreshOutline16))),
870
1172
  React.createElement('div', { className: 'dsh-super-code-memory-scopes', role: 'group', 'aria-label': text(t, 'memory.title') },
871
- ['project', 'global'].map(value => React.createElement('button', { key: value, type: 'button', 'aria-pressed': scope === value, onClick: () => { saved.scope = value; setScope(value); choose(null); resetScroll() } }, text(t, `memory.${value}`)))),
872
- !selected && React.createElement('input', { type: 'search', 'aria-label': text(t, 'memory.search'), placeholder: text(t, 'memory.search'), value: query, onChange: event => { saved.query = event.target.value; setQuery(event.target.value); resetScroll() } }),
873
- !selected && React.createElement('small', null, text(t, 'memory.count', { count: page.count }))),
1173
+ ['project', 'global'].map(value => React.createElement(ActionButton, { key: value, type: 'button', 'aria-pressed': scope === value, onClick: () => {
1174
+ saved.scope = value; setScope(value); changeTopic(''); choose(null)
1175
+ } }, text(t, `memory.${value}`)))),
1176
+ !selected && React.createElement('div', { className: 'dsh-super-code-memory-search' }, React.createElement(Glyph, { type: 'search' }),
1177
+ React.createElement('input', { type: 'search', 'aria-label': text(t, 'memory.search'), placeholder: text(t, 'memory.search'), value: query, onChange: event => { saved.query = event.target.value; setQuery(event.target.value); resetScroll() } }))),
874
1178
  !sessionId ? React.createElement('p', { className: 'dsh-super-code-memory-empty' }, text(t, 'memory.selectSession')) : selected
875
- ? React.createElement('div', { className: 'dsh-super-code-memory-body', 'aria-busy': !currentDetail },
876
- React.createElement('button', { type: 'button', className: 'dsh-super-code-view-button', onClick: () => choose(null) }, `← ${text(t, 'memory.back')}`),
1179
+ ? React.createElement('div', { ref: detailBody, className: 'dsh-super-code-memory-body', 'aria-busy': !currentDetail },
1180
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-view-button', onClick: () => choose(null) }, `← ${text(t, 'memory.back')}`),
1181
+ !currentDetail && React.createElement('p', { role: 'status', className: 'dsh-super-code-memory-empty' }, text(t, 'memory.loading')),
877
1182
  currentDetail?.kind === 'error' && React.createElement('p', { role: 'alert' }, text(t, 'memory.error')),
878
1183
  currentDetail?.kind === 'missing' && React.createElement('p', null, text(t, 'memory.missing')),
879
- entry && React.createElement('article', null, React.createElement('small', null, `${entry.topic} · r${entry.revision} · ${text(t, `memory.${entry.kind}`)}`),
1184
+ entry && React.createElement('article', { 'data-kind': entry.kind },
1185
+ React.createElement('div', { className: 'dsh-super-code-memory-detail-meta' },
1186
+ React.createElement('span', null, React.createElement(Glyph, { type: 'folder' }), entry.topic),
1187
+ React.createElement('span', null, text(t, `memory.${entry.kind}`)), React.createElement('span', null, `r${entry.revision}`)),
880
1188
  React.createElement('h3', null, entry.summary), React.createElement('p', { className: 'dsh-super-code-memory-detail' }, entry.detail),
881
- React.createElement('p', { className: 'dsh-super-code-memory-hint' }, text(t, 'memory.historical')),
882
1189
  React.createElement('dl', null, React.createElement('dt', null, text(t, 'memory.source')),
883
1190
  React.createElement('dd', null, `${text(t, `memory.${entry.source.kind}`)} · #${entry.source.eventSeq}`, React.createElement('br'), entry.source.sessionId),
884
- entry.sourceVersion && React.createElement(React.Fragment, null, React.createElement('dt', null, text(t, 'memory.version')), React.createElement('dd', null, entry.sourceVersion)))))
885
- : React.createElement('div', { ref: list, className: 'dsh-super-code-memory-list', role: 'list', 'aria-busy': visibleState.loading, onScroll: event => { saved.top = event.currentTarget.scrollTop; setViewport(value => ({ ...value, top: saved.top })) } },
886
- visibleState.error && React.createElement('p', { role: 'alert' }, text(t, 'memory.error')),
887
- !visibleState.error && !visibleState.loading && !page.count && React.createElement('p', { className: 'dsh-super-code-memory-empty' }, text(t, query ? 'memory.noMatches' : 'memory.empty')),
888
- React.createElement('div', { 'aria-hidden': true, style: { height: page.before } }),
889
- page.rows.map(item => React.createElement('div', { role: 'listitem', key: `${item.topic}/${item.id}` },
890
- React.createElement('button', { type: 'button', className: 'dsh-super-code-memory-row', onClick: () => choose({ topic: item.topic, id: item.id }) },
891
- React.createElement('strong', null, item.summary), React.createElement('span', null, `${item.topic} · ${text(t, `memory.${item.kind}`)}`)))),
892
- React.createElement('div', { 'aria-hidden': true, style: { height: page.after } })))
1191
+ entry.sourceVersion && React.createElement(React.Fragment, null, React.createElement('dt', null, text(t, 'memory.version')), React.createElement('dd', null, entry.sourceVersion))),
1192
+ related.length > 0 && React.createElement('section', { className: 'dsh-super-code-memory-related' },
1193
+ React.createElement('h4', null, text(t, 'memory.related')),
1194
+ related.map(item => React.createElement(ActionButton, { key: item.id, type: 'button', onClick: () => choose({ topic: item.topic, id: item.id }) },
1195
+ React.createElement(Glyph, { type: 'memory' }), React.createElement('span', null, item.summary), React.createElement(Glyph, { type: 'arrow' }))))))
1196
+ : React.createElement('div', { className: 'dsh-super-code-memory-workspace' },
1197
+ React.createElement('nav', { className: 'dsh-super-code-memory-topic-index', 'aria-label': text(t, 'memory.topics') },
1198
+ React.createElement('div', { className: 'dsh-super-code-memory-topic-label' }, text(t, 'memory.topics'), React.createElement('span', null, topics.length)),
1199
+ React.createElement('div', { className: 'dsh-super-code-memory-topic-options' },
1200
+ [{ topic: '', count: visibleState.items.length }, ...topics].map(({ topic, count }) => React.createElement(ActionButton, { key: topic, type: 'button', title: topic || text(t, 'memory.allTopics'), 'data-topic': topic, 'aria-pressed': topicFilter === topic, onClick: () => changeTopic(topic) },
1201
+ React.createElement(Glyph, { type: topic ? 'folder' : 'memory' }), React.createElement('span', null, topic || text(t, 'memory.allTopics')), React.createElement('small', null, count))))),
1202
+ React.createElement('div', { className: 'dsh-super-code-memory-results' },
1203
+ React.createElement('div', { className: 'dsh-super-code-memory-list-heading' }, React.createElement('strong', null, topicFilter || text(t, 'memory.allTopics')), React.createElement('small', null, text(t, 'memory.count', { count: page.count }))),
1204
+ React.createElement('div', { ref: list, className: 'dsh-super-code-memory-list', role: 'list', 'aria-busy': visibleState.loading, onScroll: event => { saved.top = event.currentTarget.scrollTop; setViewport(value => ({ ...value, top: saved.top })) } },
1205
+ visibleState.loading && !visibleState.error && React.createElement('p', { role: 'status', className: 'dsh-super-code-memory-empty' }, text(t, 'memory.loading')),
1206
+ visibleState.error && React.createElement('p', { role: 'alert' }, text(t, 'memory.error')),
1207
+ !visibleState.error && !visibleState.loading && !page.count && React.createElement('p', { className: 'dsh-super-code-memory-empty' }, text(t, query || topicFilter ? 'memory.noMatches' : 'memory.empty')),
1208
+ React.createElement('div', { 'aria-hidden': true, style: { height: page.before } }),
1209
+ page.rows.map(item => React.createElement('div', { role: 'listitem', key: `${item.topic}/${item.id}` },
1210
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-memory-row', 'data-topic': item.topic, 'data-kind': item.kind, onClick: () => choose({ topic: item.topic, id: item.id }) },
1211
+ React.createElement('span', { className: 'dsh-super-code-memory-row-heading' }, React.createElement(Glyph, { type: 'folder' }), React.createElement('span', { className: 'dsh-super-code-memory-row-topic' }, item.topic)),
1212
+ React.createElement('strong', null, item.summary),
1213
+ React.createElement('span', { className: 'dsh-super-code-memory-row-meta' }, React.createElement('span', { className: 'dsh-super-code-memory-row-kind' }, text(t, `memory.${item.kind}`)), React.createElement('span', null, `r${item.revision}`))))),
1214
+ React.createElement('div', { 'aria-hidden': true, style: { height: page.after } })))))
893
1215
  }
894
1216
 
895
1217
  function AgentDetail({ useTabInfo, useSessions, useSessionStatus, sessionId, createInspector, detailStates, openMemory, t = key => zh[key] || key }) {
@@ -942,6 +1264,7 @@ function AgentDetail({ useTabInfo, useSessions, useSessionStatus, sessionId, cre
942
1264
  const input = totals ? (totals.uncachedInputTokens || 0) + (totals.cacheReadTokens || 0) + (totals.cacheWriteTokens || 0) : 0
943
1265
  const format = value => value === undefined ? text(t, 'detail.unavailable') : value.toLocaleString(localeCode(t))
944
1266
  const tasks = projections.superCodeTasks
1267
+ const toolNames = new Map(snapshot.items.filter(item => item.toolName && item.callId).map(item => [item.callId, item.toolName]))
945
1268
  const task = tasks?.current?.kind === 'task' ? tasks.current : undefined
946
1269
  const title = node?.title || node?.displayTitle || text(t, 'detail.title')
947
1270
  const metrics = [
@@ -950,21 +1273,26 @@ function AgentDetail({ useTabInfo, useSessions, useSessionStatus, sessionId, cre
950
1273
  ]
951
1274
  return React.createElement('section', { className: 'dsh-super-code-detail', 'data-agent-detail': id },
952
1275
  React.createElement('header', { className: 'dsh-super-code-detail-header' },
953
- React.createElement('nav', { 'aria-label': text(t, 'detail.path') }, path.map((part, index) => React.createElement('span', { key: part.id }, index > 0 ? ' / ' : '', part.title))),
1276
+ path.length > 1 && React.createElement('nav', { 'aria-label': text(t, 'detail.path'), title: path.map(part => part.title).join(' / ') },
1277
+ path.slice(0, -1).map((part, index) => React.createElement('span', { key: part.id }, index > 0 ? ' / ' : '', part.title))),
954
1278
  React.createElement('div', { className: 'dsh-super-code-detail-heading' },
955
- React.createElement('div', null,
956
- React.createElement('h2', null, title),
957
- React.createElement('span', { className: 'dsh-super-code-detail-status' }, agentExecutionStatus(node, id === view.root, t).label)),
958
- React.createElement('button', { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'detail.refresh'), 'aria-label': text(t, 'detail.refresh'), onClick: latest }, React.createElement(IconRefreshOutline16))),
959
- id !== view.root && task?.goal && task.goal !== title && React.createElement('p', { className: 'dsh-super-code-detail-task' }, task.goal),
960
- id === view.root && React.createElement(TaskMemoryPanel, { state: tasks, t }),
961
- React.createElement(MemoryActivity, { usage: projections.superCodeMemoryUsage, sessionId: id, openMemory, t }),
962
- React.createElement('dl', { className: 'dsh-super-code-detail-metrics' },
963
- React.createElement('div', null, React.createElement('dt', null, text(t, 'detail.total')), React.createElement('dd', null, format(totals ? input + (totals.outputTokens || 0) : undefined))),
964
- React.createElement('div', null, React.createElement('dt', null, text(t, 'detail.hitRate')), React.createElement('dd', null, totals ? (input ? Math.round((totals.cacheReadTokens || 0) / input * 100) : 0) + '%' : text(t, 'detail.unavailable')))),
965
- React.createElement('details', { className: 'dsh-super-code-usage-details', open: saved.open.has('usage'), onToggle: event => { if (event.currentTarget.open) saved.open.add('usage'); else saved.open.delete('usage') } },
966
- React.createElement('summary', null, text(t, 'detail.moreUsage')),
967
- React.createElement('dl', { className: 'dsh-super-code-detail-metrics' }, metrics.map(([label, value]) => React.createElement('div', { key: label }, React.createElement('dt', null, label), React.createElement('dd', null, format(value))))))),
1279
+ React.createElement('h2', { title }, title),
1280
+ React.createElement('span', { className: 'dsh-super-code-detail-status', 'data-tone': agentExecutionStatus(node, id === view.root, t).tone }, agentExecutionStatus(node, id === view.root, t).label),
1281
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'detail.refresh'), 'aria-label': text(t, 'detail.refresh'), onClick: latest }, React.createElement(IconRefreshOutline16))),
1282
+ React.createElement('details', { className: 'dsh-super-code-usage-details', open: saved.open.has('usage'), onToggle: event => {
1283
+ if (event.target !== event.currentTarget) return
1284
+ if (event.currentTarget.open) saved.open.add('usage'); else saved.open.delete('usage')
1285
+ } },
1286
+ React.createElement('summary', null,
1287
+ React.createElement('span', { className: 'dsh-super-code-detail-summary' },
1288
+ React.createElement('span', { title: text(t, 'detail.total') }, React.createElement('span', null, 'Token'), React.createElement('strong', null, format(totals ? input + (totals.outputTokens || 0) : undefined))),
1289
+ React.createElement('span', { title: text(t, 'detail.hitRate') }, React.createElement('span', null, text(t, 'detail.cache')), React.createElement('strong', null, totals ? (input ? Math.round((totals.cacheReadTokens || 0) / input * 100) : 0) + '%' : text(t, 'detail.unavailable')))),
1290
+ React.createElement('span', { className: 'dsh-super-code-detail-info-toggle' }, text(t, 'detail.info'), React.createElement(Glyph, { type: 'chevron' }))),
1291
+ React.createElement('div', { className: 'dsh-super-code-detail-info' },
1292
+ React.createElement('dl', { className: 'dsh-super-code-detail-metrics' }, metrics.map(([label, value]) => React.createElement('div', { key: label }, React.createElement('dt', null, label), React.createElement('dd', null, format(value))))),
1293
+ id !== view.root && task?.goal && task.goal !== title && React.createElement('p', { className: 'dsh-super-code-detail-task' }, task.goal),
1294
+ id === view.root && React.createElement(TaskMemoryPanel, { state: tasks, t }),
1295
+ React.createElement(MemoryActivity, { usage: projections.superCodeMemoryUsage, sessionId: id, openMemory, t })))),
968
1296
  React.createElement('div', { ref: log, className: 'dsh-super-code-detail-log', 'aria-label': text(t, 'tree.title'), onScroll: event => {
969
1297
  const element = event.currentTarget
970
1298
  saved.top = element.scrollTop
@@ -973,21 +1301,11 @@ function AgentDetail({ useTabInfo, useSessions, useSessionStatus, sessionId, cre
973
1301
  } },
974
1302
  snapshot.error && React.createElement('p', { role: 'alert' }, text(t, snapshot.error)),
975
1303
  snapshot.status === 'loading' && React.createElement('p', { role: 'status' }, text(t, 'detail.reading')),
976
- snapshot.hasMore && React.createElement('button', { type: 'button', disabled: snapshot.status === 'paging', onClick: inspector.older }, snapshot.status === 'paging' ? text(t, 'detail.read') : text(t, 'detail.older')),
977
- (snapshot.earlier || snapshot.truncated) && React.createElement('button', { type: 'button', onClick: latest }, text(t, 'detail.latest')),
1304
+ snapshot.hasMore && React.createElement(ActionButton, { type: 'button', disabled: snapshot.status === 'paging', onClick: inspector.older }, snapshot.status === 'paging' ? text(t, 'detail.read') : text(t, 'detail.older')),
1305
+ (snapshot.earlier || snapshot.truncated) && React.createElement(ActionButton, { type: 'button', onClick: latest }, text(t, 'detail.latest')),
978
1306
  snapshot.status === 'ready' && !snapshot.items.length && React.createElement('p', null, text(t, 'detail.empty')),
979
- snapshot.items.map(record => {
980
- const item = record.entry ? detailRecord(record.entry, t) : record
981
- return React.createElement('article', { key: item.seq, className: 'dsh-super-code-detail-entry ' + item.kind },
982
- item.collapsed ? React.createElement('details', { open: saved.open.has(item.seq), onToggle: event => { if (event.currentTarget.open) saved.open.add(item.seq); else saved.open.delete(item.seq) } },
983
- React.createElement('summary', null, item.label),
984
- React.createElement(DetailText, { text: item.text, t }))
985
- : React.createElement(React.Fragment, null,
986
- React.createElement('div', { className: 'dsh-super-code-detail-entry-label' }, item.label,
987
- React.createElement('time', null, new Date(item.time).toLocaleTimeString(localeCode(t), { hour12: false }))),
988
- React.createElement(DetailText, { text: item.text, t })))
989
- }) ),
990
- unread && React.createElement('button', { type: 'button', className: 'dsh-super-code-new-content', onClick: () => {
1307
+ snapshot.items.map(record => React.createElement(AgentMessage, { key: record.seq, record, saved, t, toolName: toolNames.get(record.callId) }))),
1308
+ unread && React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-new-content', onClick: () => {
991
1309
  saved.following = true; log.current.scrollTop = log.current.scrollHeight; markUnread(false)
992
1310
  } }, text(t, 'detail.new')))
993
1311
  }
@@ -1020,9 +1338,12 @@ const memoryRemoteContribution = {
1020
1338
 
1021
1339
  // Old hosts render file metadata. Synchronize through our own Remote, then
1022
1340
  // reload their cached roster only when a managed field actually changed.
1023
- function synchronizePresetDisplay(api, locale, reload, onError) {
1341
+ function synchronizePresetDisplay(api, locale, reload, onError, preferenceScope) {
1024
1342
  let disposed = false, running = false, pending = '', last = '', needsReload = false
1025
1343
  const changed = () => {
1344
+ // A provisional browser locale can precede the host's saved preference.
1345
+ // Do not rewrite the preset or reload while that public scope is loading.
1346
+ if (preferenceScope?.getSnapshot().status === 'loading') return
1026
1347
  pending = locale.getSnapshot().active
1027
1348
  if (running || pending === last) return
1028
1349
  running = true
@@ -1041,16 +1362,18 @@ function synchronizePresetDisplay(api, locale, reload, onError) {
1041
1362
  })()
1042
1363
  }
1043
1364
  const unsubscribe = locale.subscribe(changed)
1365
+ const unsubscribePreference = preferenceScope ? preferenceScope.subscribe(changed) : () => {}
1044
1366
  changed()
1045
- return () => { disposed = true; unsubscribe() }
1367
+ return () => { disposed = true; unsubscribe(); unsubscribePreference() }
1046
1368
  }
1047
1369
 
1048
1370
  function PresetSettings({ api, t }) {
1049
1371
  const [status, setStatus] = useState(null), [customId, setCustomId] = useState(null)
1050
- const name = customId ?? (status?.state === 'installed' ? status.id : 'super-code')
1372
+ const reinstall = status?.reinstallable ?? status?.state === 'installed'
1373
+ const name = customId ?? (reinstall ? status.id : 'super-code')
1051
1374
  const [customDisplayName, setCustomDisplayName] = useState(null)
1052
- const displayName = customDisplayName ?? (status?.state === 'installed' ? status.name || t('preset.title') : t('preset.title'))
1053
- const [busy, setBusy] = useState(true), [error, setError] = useState(''), [open, setOpen] = useState(false)
1375
+ const displayName = customDisplayName ?? (reinstall ? status.name || t('preset.title') : t('preset.title'))
1376
+ const [busy, setBusy] = useState(true), [error, setError] = useState('')
1054
1377
  const [confirmation, setConfirmation] = useState(null)
1055
1378
  const dialog = useRef(null)
1056
1379
  const alive = useRef(false), pending = useRef(false)
@@ -1059,7 +1382,20 @@ function PresetSettings({ api, t }) {
1059
1382
  const element = dialog.current
1060
1383
  element.showModal()
1061
1384
  element.querySelector('[data-super-code-cancel]')?.focus()
1062
- return () => { if (element.open) element.close() }
1385
+ // Removing the focused list row can leave focus outside the native dialog.
1386
+ // Capture Escape before the host's document listener closes Settings too.
1387
+ const target = element.ownerDocument.defaultView
1388
+ const cancel = event => {
1389
+ if (event.key !== 'Escape' || event.isComposing) return
1390
+ event.preventDefault()
1391
+ event.stopPropagation()
1392
+ setConfirmation(null)
1393
+ }
1394
+ target.addEventListener('keydown', cancel, true)
1395
+ return () => {
1396
+ target.removeEventListener('keydown', cancel, true)
1397
+ if (element.open) element.close()
1398
+ }
1063
1399
  }, [confirmation !== null])
1064
1400
  const run = async (install, confirmed = null) => {
1065
1401
  if (pending.current) return
@@ -1089,39 +1425,55 @@ function PresetSettings({ api, t }) {
1089
1425
  useEffect(() => { alive.current = true; run(false); return () => { alive.current = false } }, [api])
1090
1426
  const submit = () => {
1091
1427
  if (busy || pending.current || !displayName.trim() || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name.trim())) return
1092
- if (status?.state === 'installed') {
1428
+ if (reinstall) {
1093
1429
  setConfirmation([{ previousId: status.id, id: name.trim(),
1094
1430
  name: customDisplayName === null && displayName === t('preset.title') ? '' : displayName.trim(), label: displayName.trim() }])
1095
1431
  } else run(true)
1096
1432
  }
1097
1433
  const available = status && ['available', 'installed'].includes(status.state)
1098
- return React.createElement('section', { className: `dsh-super-code-settings${open ? ' dsh-super-code-settings-open' : ''}` },
1099
- React.createElement('button', { type: 'button', className: 'dsh-super-code-settings-header', 'aria-expanded': open,
1100
- 'aria-label': `${t(open ? 'preset.collapse' : 'preset.expand')}: ${t('preset.title')}`, onClick: () => setOpen(!open) },
1101
- React.createElement('span', { className: 'dsh-super-code-settings-head-text' },
1102
- React.createElement('span', { className: 'dsh-super-code-settings-name' }, t('preset.title')),
1103
- React.createElement('span', { className: 'dsh-super-code-settings-description' }, t('preset.description'))),
1104
- React.createElement(IconChevronDownOutline14, { className: `dsh-super-code-settings-chevron${open ? ' dsh-super-code-settings-chevron-open' : ''}`, 'aria-hidden': true })),
1105
- open && React.createElement('div', { className: 'dsh-super-code-settings-body' },
1106
- status && React.createElement('p', { className: 'dsh-super-code-preset-status', role: 'status', 'data-available': available },
1107
- React.createElement('span', { 'aria-hidden': true }, '●'), ' ', t(`preset.state.${status.state}`), ' · ', status.id),
1108
- React.createElement('div', { className: 'dsh-super-code-settings-actions' },
1109
- React.createElement('button', { type: 'button', disabled: busy, onClick: () => run(false), 'aria-label': t('preset.refresh') }, t('preset.refresh'))),
1110
- status && React.createElement('p', null, t(available ? 'preset.availableHint' : 'preset.installHint')),
1111
- status?.state === 'installed' && React.createElement('p', null, t('preset.reinstallHint')),
1112
- status?.userConflict && status.state !== 'conflict' && React.createElement('p', null, t('preset.userConflict')),
1113
- status && !status.authorable && React.createElement('p', { role: 'note' }, t('preset.readonly')),
1434
+ const versionState = status?.presetVersion ? status.presetVersion === status.pluginVersion ? 'match' : 'mismatch' : 'unknown'
1435
+ return React.createElement('section', { className: 'dsh-super-code-settings' },
1436
+ React.createElement('header', { className: 'dsh-super-code-settings-header' },
1437
+ React.createElement('span', { className: 'dsh-super-code-settings-mark', 'aria-hidden': true }, React.createElement(Glyph, { type: 'code' })),
1438
+ React.createElement('div', { className: 'dsh-super-code-settings-head-text' },
1439
+ React.createElement('h2', { className: 'dsh-super-code-settings-name' }, t('preset.title')),
1440
+ React.createElement('p', { className: 'dsh-super-code-settings-description' }, t('preset.description')))),
1441
+ React.createElement('div', { className: 'dsh-super-code-settings-body' },
1442
+ React.createElement('div', { className: 'dsh-super-code-settings-summary' },
1443
+ React.createElement('div', { className: 'dsh-super-code-settings-status-row' },
1444
+ status ? React.createElement('p', { className: 'dsh-super-code-preset-status', role: 'status', 'data-available': available },
1445
+ React.createElement('i', { 'aria-hidden': true }),
1446
+ React.createElement('span', null, t(status.delivery === 'declaration' && status.state === 'installed' ? 'preset.state.declaredInstalled' : `preset.state.${status.state}`)),
1447
+ React.createElement('code', null, status.id))
1448
+ : React.createElement('p', { className: 'dsh-super-code-preset-status', role: 'status' }, busy ? t('preset.working') : t('preset.unavailableHint')),
1449
+ React.createElement('div', { className: 'dsh-super-code-settings-actions' },
1450
+ React.createElement(ActionButton, { type: 'button', disabled: busy, onClick: () => run(false), 'aria-label': t('preset.refresh') },
1451
+ React.createElement(IconRefreshOutline16), t('preset.refresh')))),
1452
+ status && React.createElement('dl', { className: 'dsh-super-code-preset-versions' },
1453
+ React.createElement('div', null, React.createElement('dt', null, t('preset.pluginVersion')), React.createElement('dd', null, status.pluginVersion)),
1454
+ React.createElement('div', null, React.createElement('dt', null, t('preset.presetVersion')), React.createElement('dd', null, status.state === 'missing' ? t('preset.versionMissing') : status.presetVersion || t('preset.versionUnknown')))),
1455
+ status && status.state !== 'missing' && React.createElement('p', { className: 'dsh-super-code-version-hint', role: 'status', 'data-version-state': versionState },
1456
+ t(versionState === 'match' ? 'preset.versionMatches' : versionState === 'mismatch' ? 'preset.versionMismatch' : 'preset.versionUnknownHint'),
1457
+ versionState === 'mismatch' && ` ${t(reinstall && status.authorable ? 'preset.versionReinstallHint' : 'preset.versionReloadHint')}`)),
1114
1458
  status?.authorable && React.createElement('form', { onSubmit: event => { event.preventDefault(); submit() } },
1115
- React.createElement('label', { htmlFor: 'super-code-display-name' }, t('preset.displayName')),
1116
- React.createElement('input', { id: 'super-code-display-name', value: displayName, maxLength: 120, required: true, disabled: busy, 'aria-describedby': 'super-code-display-name-hint', onChange: event => setCustomDisplayName(event.target.value) }),
1117
- React.createElement('small', { id: 'super-code-display-name-hint' }, t('preset.displayNameHint')),
1118
- React.createElement('label', { htmlFor: 'super-code-preset-name' }, t('preset.name')),
1119
- React.createElement('div', { className: 'dsh-super-code-install-row' },
1120
- React.createElement('input', { id: 'super-code-preset-name', value: name, maxLength: 64, disabled: busy,
1459
+ React.createElement('h3', null, t('preset.configuration')),
1460
+ React.createElement('div', { className: 'dsh-super-code-settings-field' },
1461
+ React.createElement('label', { htmlFor: 'super-code-display-name' }, t('preset.displayName')),
1462
+ React.createElement('input', { id: 'super-code-display-name', value: displayName, maxLength: 120, required: true, disabled: busy, 'aria-describedby': 'super-code-display-name-hint', onChange: event => setCustomDisplayName(event.target.value) }),
1463
+ React.createElement('small', { id: 'super-code-display-name-hint' }, t('preset.displayNameHint'))),
1464
+ React.createElement('div', { className: 'dsh-super-code-settings-field' },
1465
+ React.createElement('label', { htmlFor: 'super-code-preset-name' }, t('preset.name')),
1466
+ React.createElement('input', { id: 'super-code-preset-name', className: 'dsh-super-code-technical', value: name, maxLength: 64, disabled: busy,
1121
1467
  pattern: '[a-z0-9][a-z0-9\\-]{0,63}', required: true, autoComplete: 'off', spellCheck: false,
1122
1468
  'aria-describedby': 'super-code-preset-name-hint', onChange: event => setCustomId(event.target.value) }),
1123
- React.createElement('button', { type: 'submit', disabled: busy || !displayName.trim() || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name.trim()) }, t(busy ? 'preset.working' : status?.state === 'installed' ? 'preset.reinstall' : 'preset.install'))),
1124
- React.createElement('small', { id: 'super-code-preset-name-hint' }, t('preset.nameHint'))),
1469
+ React.createElement('small', { id: 'super-code-preset-name-hint' }, t(status?.delivery === 'declaration' ? 'preset.declaredNameHint' : 'preset.nameHint'))),
1470
+ React.createElement('div', { className: 'dsh-super-code-settings-form-actions' },
1471
+ React.createElement(ActionButton, { type: 'submit', className: 'dsh-super-code-primary-button', disabled: busy || !displayName.trim() || !/^[a-z0-9][a-z0-9-]{0,63}$/.test(name.trim()) }, t(busy ? 'preset.working' : reinstall ? 'preset.reinstall' : status?.delivery === 'declaration' ? 'preset.installDeclared' : 'preset.install')))),
1472
+ React.createElement('div', { className: 'dsh-super-code-settings-guidance' },
1473
+ status && !status.authorable && ['missing', 'broken'].includes(status.state) && React.createElement('p', { role: 'note' }, t('preset.unavailableHint')),
1474
+ status?.userConflict && status.state !== 'conflict' && React.createElement('p', null, t('preset.userConflict')),
1475
+ status?.delivery === 'declaration' && !status.authorable && React.createElement('p', { role: 'note' }, t('preset.declaredReadonly')),
1476
+ status?.delivery === 'directory' && !status.authorable && React.createElement('p', { role: 'note' }, t('preset.readonly'))),
1125
1477
  error && React.createElement('p', { role: 'alert' }, t(error))),
1126
1478
  confirmation && React.createElement('dialog', { ref: dialog, className: 'dsh-super-code-confirm',
1127
1479
  'aria-labelledby': 'super-code-confirm-title', 'aria-describedby': 'super-code-confirm-hint',
@@ -1131,13 +1483,15 @@ function PresetSettings({ api, t }) {
1131
1483
  React.createElement('p', { id: 'super-code-confirm-hint' }, t('preset.confirmHint')),
1132
1484
  confirmation.length ? React.createElement('ul', null, ...confirmation.map(item =>
1133
1485
  React.createElement('li', { key: item.previousId },
1134
- React.createElement('span', null, `${item.previousId} → ${item.label} · ${item.id}`),
1135
- React.createElement('button', { type: 'button', 'aria-label': `${t('preset.remove')}: ${item.previousId}`,
1486
+ React.createElement('div', { className: 'dsh-super-code-confirm-item-info' },
1487
+ React.createElement('span', { className: 'dsh-super-code-confirm-previous' }, React.createElement('code', null, item.previousId), ' →'),
1488
+ React.createElement('strong', null, item.label), React.createElement('code', { className: 'dsh-super-code-confirm-new-id' }, item.id)),
1489
+ React.createElement(ActionButton, { type: 'button', 'aria-label': `${t('preset.remove')}: ${item.previousId}`,
1136
1490
  onClick: () => setConfirmation(items => items.filter(row => row.previousId !== item.previousId)) }, t('preset.remove')))))
1137
- : React.createElement('p', { role: 'status' }, t('preset.confirmEmpty')),
1491
+ : React.createElement('p', { className: 'dsh-super-code-confirm-empty', role: 'status' }, t('preset.confirmEmpty')),
1138
1492
  React.createElement('div', { className: 'dsh-super-code-confirm-actions' },
1139
- React.createElement('button', { type: 'button', autoFocus: true, 'data-super-code-cancel': true, onClick: () => setConfirmation(null) }, t('preset.cancel')),
1140
- React.createElement('button', { type: 'button', disabled: busy || !confirmation.length,
1493
+ React.createElement(ActionButton, { type: 'button', autoFocus: true, 'data-super-code-cancel': true, onClick: () => setConfirmation(null) }, t('preset.cancel')),
1494
+ React.createElement(ActionButton, { type: 'button', className: 'dsh-super-code-primary-button', disabled: busy || !confirmation.length,
1141
1495
  onClick: () => {
1142
1496
  if (busy || pending.current || !confirmation.length) return
1143
1497
  const selected = confirmation[0]
@@ -1167,10 +1521,15 @@ function apply(ctx) {
1167
1521
  inject: () => ({ api: ready.remote.superCodeMemory, memoryStates }),
1168
1522
  }, MemoryLibrary))
1169
1523
  })
1170
- ctx.inject(['remote.superCodePresets'], ready => {
1171
- ready.effect(() => synchronizePresetDisplay(ready.remote.superCodePresets, locale,
1172
- () => window.location.reload(), error => console.warn('Super Code preset display:', error)), 'super-code: preset display')
1173
- ready.slots.inject('settings.section', () => ready.slots.register({
1524
+ // Locale already requires its host's preference service. Declare that same
1525
+ // service here: Cordis rejects even optional reads without an injection.
1526
+ const preferenceService = 'configForms' in ctx ? 'configForms' : 'settingsScope'
1527
+ ctx.inject(['remote.superCodePresets', preferenceService], ready => {
1528
+ const preferenceScope = preferenceService === 'configForms'
1529
+ ? ready.configForms.get('locale') : ready.settingsScope.bind({ namespace: 'locale' })
1530
+ ready.effect(() => synchronizePresetDisplay(ready.remote.superCodePresets, locale,
1531
+ () => window.location.reload(), error => console.warn('Super Code preset display:', error), preferenceScope), 'super-code: preset display')
1532
+ ready.slots.inject('settings.section', () => ready.slots.register({
1174
1533
  name: 'settings.section', id: 'super-code', order: 120, label: () => t('preset.title'), locale: LOCALE_NS,
1175
1534
  inject: () => ({ api: ready.remote.superCodePresets }),
1176
1535
  }, PresetSettings))
@@ -1179,167 +1538,352 @@ function apply(ctx) {
1179
1538
  const style = document.createElement('style')
1180
1539
  style.dataset.dshSuperCode = 'true'
1181
1540
  style.textContent = `
1182
- .dsh-super-code-memory{height:100%;min-height:0;display:flex;flex-direction:column;font-size:13px;--agent-muted:var(--dsw-alias-label-secondary,#70757d);--agent-line:var(--dsw-alias-border-l1,#dedfe3)}
1183
- .dsh-super-code-memory>header{padding:18px 18px 12px;border-bottom:1px solid var(--agent-line)}
1184
- .dsh-super-code-memory-heading{display:flex;align-items:center;justify-content:space-between;gap:12px}.dsh-super-code-memory h2{margin:0;font-size:16px;font-weight:600}
1185
- .dsh-super-code-memory-muted{color:var(--agent-muted);font-size:12px;line-height:1.65;margin:10px 0}
1186
- .dsh-super-code-memory-scopes{display:flex;gap:4px;padding:3px;margin:14px 0;border-radius:8px;background:color-mix(in srgb,currentColor 5%,transparent)}
1187
- .dsh-super-code-memory-scopes button{flex:1;border:0;border-radius:6px;padding:7px;background:transparent;color:var(--agent-muted);font:inherit;cursor:pointer}
1188
- .dsh-super-code-memory-scopes button[aria-pressed=true]{background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-color-primary,#3276dc);box-shadow:0 1px 4px #0001}
1189
- .dsh-super-code-memory input{width:100%;box-sizing:border-box;border:1px solid var(--agent-line);border-radius:7px;background:transparent;color:inherit;font:inherit;padding:9px 10px;margin-bottom:10px}
1190
- .dsh-super-code-memory small{font-size:11px;color:var(--agent-muted);overflow-wrap:anywhere}
1191
- .dsh-super-code-memory-list{flex:1;min-height:0;overflow:auto;padding:0 12px}.dsh-super-code-memory-row{display:flex;flex-direction:column;justify-content:center;gap:7px;width:100%;height:76px;box-sizing:border-box;border:0;border-bottom:1px solid var(--agent-line);background:transparent;text-align:left;color:inherit;padding:12px 8px;cursor:pointer;font:inherit}
1192
- .dsh-super-code-memory-row:hover{background:color-mix(in srgb,var(--dsw-color-primary,#3276dc) 5%,transparent)}.dsh-super-code-memory-row strong,.dsh-super-code-memory-row span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsh-super-code-memory-row strong{font-weight:500}.dsh-super-code-memory-row span{font-size:11px;color:var(--agent-muted)}
1193
- .dsh-super-code-memory-body{overflow:auto;flex:1;min-height:0;padding:14px 18px 28px}.dsh-super-code-memory-body article{padding-top:18px}.dsh-super-code-memory-body h3{font-size:15px;line-height:1.6;margin:8px 0 14px;overflow-wrap:anywhere}
1194
- .dsh-super-code-memory-detail{white-space:pre-wrap;line-height:1.8;overflow-wrap:anywhere}.dsh-super-code-memory-hint{border-left:2px solid #b8ac82;padding:8px 12px;background:color-mix(in srgb,#b8ac82 8%,transparent);color:var(--agent-muted);font-size:12px;line-height:1.6;margin:22px 0}
1195
- .dsh-super-code-memory-body dt{font-size:11px;color:var(--agent-muted);margin-top:18px}.dsh-super-code-memory-body dd{margin:6px 0;line-height:1.6;overflow-wrap:anywhere;font-size:12px}.dsh-super-code-memory-empty{padding:20px 6px;line-height:1.8;color:var(--agent-muted)}
1196
- .dsh-super-code-memory-activity{margin-top:14px;font-size:12px}.dsh-super-code-memory-activity summary{cursor:pointer}.dsh-super-code-memory-activity-list{max-height:200px;overflow:auto}.dsh-super-code-memory-activity-list button{display:grid;grid-template-columns:auto 1fr;gap:5px 8px;width:100%;text-align:left;background:transparent;border:0;border-bottom:1px solid var(--agent-line);padding:10px 2px;color:inherit;font:inherit;cursor:pointer}.dsh-super-code-memory-activity-list small{grid-column:2;color:var(--agent-muted);overflow-wrap:anywhere}.dsh-super-code-memory-activity-list span{overflow-wrap:anywhere}
1197
- .dsh-super-code-memory-action{font-size:10px;color:#4d779f}.dsh-super-code-memory-action[data-action=read]{color:#14867b}.dsh-super-code-memory-action[data-action=remember]{color:#927247}.dsh-super-code-memory-action[data-action=forget]{color:var(--agent-muted)}
1198
- .dsh-super-code-memory button:focus-visible,.dsh-super-code-memory input:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:2px}
1199
- .dsh-super-code-settings{list-style:none;border:.5px solid var(--dsw-alias-border-l4,#dedfe3);border-radius:16px;background:var(--dsw-alias-bg-layer-3,transparent);line-height:1.6;font-size:13px;transition:border-color .16s,background .16s}
1200
- .dsh-super-code-settings:hover{border-color:var(--dsw-alias-label-dimmed,#a8abb2)}.dsh-super-code-settings-open{background:var(--dsw-alias-bg-layer-2,transparent);border-color:var(--dsw-alias-label-dimmed,#a8abb2)}
1201
- .dsh-super-code-settings-header{width:100%;appearance:none;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;gap:12px;padding:14px 16px;border-radius:12px}
1202
- .dsh-super-code-settings-head-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.dsh-super-code-settings-name{font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary,inherit)}
1203
- .dsh-super-code-settings-description{font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary,#70757d)}.dsh-super-code-settings-chevron{flex:none;color:var(--dsw-alias-label-tertiary,#70757d);transition:transform .16s}.dsh-super-code-settings-chevron-open{transform:rotate(180deg)}
1204
- .dsh-super-code-confirm{box-sizing:border-box;width:min(560px,calc(100vw - 48px));max-height:80vh;overflow:auto;border:1px solid var(--dsw-alias-border-l2,#dedfe3);border-radius:8px;padding:24px;color:var(--dsw-alias-label-primary,#202126);background:var(--dsw-alias-bg-layer-1,#fff);font-size:13px;line-height:1.6}.dsh-super-code-confirm::backdrop{background:#0006}.dsh-super-code-confirm h3{font-size:16px;margin:0 0 12px}.dsh-super-code-confirm p{margin:0 0 14px}.dsh-super-code-confirm ul{padding:0;margin:0 0 18px;list-style:none}.dsh-super-code-confirm li{display:flex;align-items:center;justify-content:space-between;gap:16px;margin:12px 0;overflow-wrap:anywhere}.dsh-super-code-confirm-actions{display:flex;justify-content:flex-end;gap:8px}.dsh-super-code-confirm button{font:inherit;color:inherit;border:1px solid var(--dsw-alias-border-l1,#dedfe3);border-radius:6px;background:transparent;padding:7px 10px;min-height:34px;cursor:pointer}.dsh-super-code-confirm button:disabled{opacity:.45;cursor:default}.dsh-super-code-confirm button:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:2px}
1205
- .dsh-super-code-settings-body{border-top:.5px solid var(--dsw-alias-border-l2,#dedfe3);margin:0 16px;padding:12px 0 14px}.dsh-super-code-settings-actions{display:flex;justify-content:flex-end}
1206
- .dsh-super-code-settings p{margin:8px 0;color:var(--dsw-alias-label-secondary,#70757d)}
1207
- .dsh-super-code-settings-body button,.dsh-super-code-settings input{font:inherit;color:inherit;border:1px solid var(--dsw-alias-border-l1,#dedfe3);border-radius:7px;background:transparent;padding:7px 10px;min-height:34px}
1208
- .dsh-super-code-settings button{cursor:pointer;white-space:nowrap}.dsh-super-code-settings button:disabled{opacity:.45;cursor:default}
1209
- .dsh-super-code-settings form{margin-top:16px}.dsh-super-code-settings label{display:block;margin-bottom:6px}
1210
- .dsh-super-code-install-row{display:flex;gap:8px;flex-wrap:wrap}.dsh-super-code-install-row input{flex:1;min-width:140px}
1211
- .dsh-super-code-settings small{display:block;margin-top:6px;color:var(--dsw-alias-label-secondary,#70757d)}
1212
- .dsh-super-code-settings .dsh-super-code-preset-status{color:inherit}.dsh-super-code-preset-status span{color:#b87716}.dsh-super-code-preset-status[data-available=true] span{color:#008b78}
1213
- .dsh-super-code-settings [role=alert]{color:var(--dsw-color-text-error,#bd423b)}.dsh-super-code-settings :focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:2px}
1541
+ /* Host aliases remain the source of theme colors. */
1542
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm,.dsh-super-code-select,.dsh-super-code-tooltip){
1543
+ --sc-text:var(--dsw-alias-label-primary,#242831);
1544
+ --sc-muted:var(--dsw-alias-label-secondary,#6a707a);
1545
+ --sc-faint:var(--dsw-alias-label-tertiary,#818793);
1546
+ --sc-bg:var(--dsw-alias-bg-layer-1,#fff);
1547
+ --sc-surface:var(--dsw-alias-bg-layer-2,#f5f6f8);
1548
+ --sc-line:var(--dsw-alias-border-l1,#e2e4e8);
1549
+ --sc-hover:color-mix(in srgb,var(--sc-text) 5%,var(--sc-bg));
1550
+ --sc-selected:color-mix(in srgb,var(--dsw-color-primary,#3e78c5) 7%,var(--sc-bg));
1551
+ --sc-accent:var(--dsw-color-primary,#3e78c5);
1552
+ --sc-success:var(--dsw-color-text-success,#197661);
1553
+ --sc-warning:var(--dsw-color-text-warning,#9c650c);
1554
+ --sc-error:var(--dsw-color-text-error,#bb4545);
1555
+ --sc-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
1556
+ --agent-muted:var(--sc-muted);--agent-line:var(--sc-line);
1557
+ color:var(--sc-text);font-size:14px;line-height:1.55;letter-spacing:0;
1558
+ box-sizing:border-box;min-width:0;
1559
+ }
1560
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm) *{box-sizing:border-box}
1561
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm) :is(button,input,select){font:inherit;color:inherit;min-width:0}
1562
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm) button{cursor:pointer;transition:background-color .12s,border-color .12s;color:inherit}
1563
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm) button:disabled{opacity:.45;cursor:default}
1564
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm) :is(button,input,select,summary):focus-visible{outline:2px solid var(--sc-accent);outline-offset:2px}
1565
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory) :is(input,select){width:100%;height:36px;padding:7px 12px;border:1px solid var(--sc-line);border-radius:8px;background:var(--sc-bg);transition:border-color .12s;outline-offset:2px}
1566
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-memory) input::placeholder{color:var(--sc-faint)}
1567
+ :where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-memory) :is(input,select):hover{border-color:color-mix(in srgb,var(--sc-text) 25%,var(--sc-line))}
1568
+ .dsh-super-code-technical,.dsh-super-code-confirm code,.dsh-super-code-preset-status code{font-family:var(--sc-mono);font-size:12px}
1569
+ .dsh-super-code-title-line{display:flex;align-items:center;gap:8px;min-width:0}
1570
+ .dsh-super-code-glyph{width:18px;height:18px;flex:none;color:var(--sc-muted)}
1571
+ .dsh-super-code-icon-button{display:inline-flex;align-items:center;justify-content:center;flex:none;width:32px;height:32px;border:0;border-radius:8px;padding:0;background:transparent;color:var(--sc-muted)}
1572
+ .dsh-super-code-icon-button:hover,.dsh-super-code-view-button:hover{background:var(--sc-hover);color:var(--sc-text)}
1573
+ .dsh-super-code-icon-button svg{width:16px;height:16px}
1574
+ .dsh-super-code-view-button{display:inline-flex;align-items:center;gap:6px;border:0;border-radius:8px;padding:6px 8px;background:transparent;color:var(--sc-muted);font-size:13px}
1214
1575
 
1215
- .dsh-super-code-tree{--agent-muted:var(--dsw-alias-label-secondary,#70757d);--agent-line:var(--dsw-alias-border-l1,#dedfe3);height:100%;min-width:0;min-height:0;display:flex;flex-direction:column;overflow:auto;font-size:13px;letter-spacing:0;color:inherit}
1216
- .dsh-super-code-tree>header,.dsh-super-code-tree>.dsh-super-code-graph-controls,.dsh-super-code-tree>.dsh-super-code-graph-legend,.dsh-super-code-tree>.dsh-super-code-history-controls{flex-shrink:0}
1217
- .dsh-super-code-tree-header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:20px 18px 16px}
1218
- .dsh-super-code-tree-header strong{display:block;font-size:14px;font-weight:600}
1219
- .dsh-super-code-tree-count{display:block;margin-top:5px;color:var(--agent-muted);font-size:12px}
1220
- .dsh-super-code-graph-controls{display:flex;align-items:center;gap:6px;padding:2px 18px 12px;color:var(--agent-muted);font-size:11px}
1221
- .dsh-super-code-graph-controls button{border:1px solid var(--agent-line);border-radius:5px;background:transparent;color:inherit;padding:3px 8px;min-height:28px;cursor:pointer;font:inherit}
1222
- .dsh-super-code-graph-controls button:disabled{opacity:.4;cursor:default}
1223
- .dsh-super-code-graph-controls span{min-width:38px;text-align:center;font-variant-numeric:tabular-nums}
1224
- .dsh-super-code-history-controls{display:flex;gap:8px;padding:0 18px 10px}
1225
- .dsh-super-code-history-controls button{border:1px solid var(--agent-line);border-radius:14px;background:transparent;color:var(--agent-muted);padding:5px 10px;font:inherit;font-size:11px;cursor:pointer}
1226
- .dsh-super-code-history-controls button[aria-expanded=true]{color:var(--dsw-color-primary,#3276dc);background:color-mix(in srgb,currentColor 5%,transparent)}
1227
- .dsh-super-code-history{display:flex;flex-direction:column;flex-shrink:0;box-sizing:border-box;height:46%;min-height:220px;max-height:400px;margin:0 12px 12px;padding:12px;border:1px solid var(--agent-line);border-radius:12px;background:color-mix(in srgb,var(--agent-muted) 3%,transparent)}
1228
- .dsh-super-code-history>p,.dsh-super-code-history>input,.dsh-super-code-history-filters{flex-shrink:0}
1229
- .dsh-super-code-history p{font-size:11px;color:var(--agent-muted);margin:0 0 10px;line-height:1.6}
1230
- .dsh-super-code-history input,.dsh-super-code-history select{box-sizing:border-box;min-width:0;width:100%;border:1px solid var(--agent-line);border-radius:7px;background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-text-primary,inherit);font:inherit;font-size:12px;padding:7px 8px}
1231
- .dsh-super-code-history>input{margin-bottom:8px}
1232
- .dsh-super-code-history-filters{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:8px;margin-bottom:8px}
1233
- .dsh-super-code-history-filters label{display:flex;flex-direction:column;gap:4px;min-width:0;font-size:10px;color:var(--agent-muted)}
1234
- .dsh-super-code-history-filters select{cursor:pointer}
1235
- .dsh-super-code-history input:focus-visible,.dsh-super-code-history select:focus-visible,.dsh-super-code-history-list button:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:-2px}
1236
- .dsh-super-code-history p.dsh-super-code-history-summary{font-size:10px;margin-bottom:6px}
1237
- .dsh-super-code-history-list{flex:1;min-height:56px;overflow:auto;overflow-anchor:none;overscroll-behavior:contain;scrollbar-gutter:stable}
1238
- .dsh-super-code-history-list button{display:flex;align-items:center;box-sizing:border-box;gap:9px;width:100%;height:56px;text-align:left;border:0;border-radius:7px;padding:9px 5px;background:transparent;color:inherit;cursor:pointer;font:inherit}
1239
- .dsh-super-code-history-list button:hover{background:color-mix(in srgb,currentColor 5%,transparent)}
1240
- .dsh-super-code-history-list button>span{flex:1;min-width:0}.dsh-super-code-history-list strong{display:block;font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1241
- .dsh-super-code-history-list small{font-size:10px;color:var(--agent-muted);line-height:1.6}.dsh-super-code-history-list button>small{white-space:nowrap;font-variant-numeric:tabular-nums}
1242
- .dsh-super-code-history-list button>span>small{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1243
- .dsh-super-code-history-list .dsh-super-code-circle{width:7px;height:7px;box-shadow:none}
1244
- .dsh-super-code-history-empty{padding:14px 5px}
1245
- .dsh-super-code-branch-toggle{position:absolute;display:grid;place-items:center;width:22px;height:22px;padding:0;border:1px solid var(--agent-line);border-radius:50%;background:var(--dsw-alias-bg-base,#fff);color:var(--agent-muted);cursor:pointer;box-shadow:0 1px 3px #0000000a}
1246
- .dsh-super-code-branch-toggle:hover{color:var(--dsw-color-primary,#3276dc);border-color:currentColor}
1247
- .dsh-super-code-graph-scroll{overflow:hidden;padding:0 12px;min-height:180px;flex:1;touch-action:none;cursor:grab;user-select:none}
1248
- .dsh-super-code-graph-scroll.dragging,.dsh-super-code-graph-scroll.dragging *{cursor:grabbing!important}
1249
- .dsh-super-code-graph-legend{display:flex;flex-wrap:wrap;gap:6px 12px;padding:0 18px 8px;color:var(--agent-muted);font-size:10px}
1576
+ /* Settings. */
1577
+ .dsh-super-code-settings{container-type:inline-size;border:1px solid var(--sc-line);border-radius:12px;background:var(--sc-bg);overflow:hidden}
1578
+ .dsh-super-code-settings-header{display:flex;align-items:center;gap:12px;padding:20px 24px;border-bottom:1px solid var(--sc-line)}
1579
+ .dsh-super-code-settings-mark{display:grid;place-items:center;flex:none;width:40px;height:40px;background:var(--sc-surface);border:1px solid var(--sc-line);border-radius:10px}
1580
+ .dsh-super-code-settings-mark svg{width:22px;height:22px;color:var(--sc-text)}
1581
+ .dsh-super-code-settings-head-text{display:grid;gap:4px;min-width:0}
1582
+ .dsh-super-code-settings-name{font-size:16px;font-weight:600;line-height:1.4;margin:0}
1583
+ .dsh-super-code-settings-description{font-size:13px;color:var(--sc-muted);margin:0}
1584
+ .dsh-super-code-settings-body{padding:20px 24px 24px}
1585
+ .dsh-super-code-settings-summary{padding:16px;border-radius:12px;background:var(--sc-surface)}
1586
+ .dsh-super-code-settings-status-row{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}
1587
+ .dsh-super-code-preset-status{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:4px 0;font-size:13px;min-width:0;flex:1}
1588
+ .dsh-super-code-preset-status>i{width:7px;height:7px;flex:none;border-radius:50%;background:var(--sc-warning)}
1589
+ .dsh-super-code-preset-status[data-available=true]>i{background:var(--sc-success)}
1590
+ .dsh-super-code-preset-status>span{font-weight:500}
1591
+ .dsh-super-code-preset-status code{color:var(--sc-muted);overflow-wrap:anywhere}
1592
+ .dsh-super-code-settings-actions{display:flex;flex:none;margin-left:auto}
1593
+ .dsh-super-code-settings-actions button,.dsh-super-code-settings-form-actions button,.dsh-super-code-confirm button{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;border:1px solid var(--sc-line);border-radius:8px;background:var(--sc-bg);padding:5px 10px;font-size:13px}
1594
+ .dsh-super-code-settings-actions button:hover,.dsh-super-code-confirm button:hover{background:var(--sc-hover)}
1595
+ .dsh-super-code-settings-actions svg{width:14px;height:14px}
1596
+ .dsh-super-code-preset-versions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin:16px 0 0;padding-top:16px;border-top:1px solid var(--sc-line)}
1597
+ .dsh-super-code-preset-versions>div+div{border-left:1px solid var(--sc-line);padding-left:16px}
1598
+ .dsh-super-code-preset-versions dt{font-size:12px;color:var(--sc-muted)}
1599
+ .dsh-super-code-preset-versions dd{font-family:var(--sc-mono);font-variant-numeric:tabular-nums;font-size:15px;margin:4px 0 0;overflow-wrap:anywhere}
1600
+ .dsh-super-code-version-hint{font-size:12px;color:var(--sc-muted);margin:12px 0 0;overflow-wrap:anywhere}
1601
+ .dsh-super-code-version-hint[data-version-state=mismatch],.dsh-super-code-version-hint[data-version-state=unknown]{padding:10px 12px;background:color-mix(in srgb,var(--sc-warning) 8%,var(--sc-bg));border-left:2px solid var(--sc-warning);border-radius:0 6px 6px 0;color:var(--sc-text)}
1602
+ .dsh-super-code-settings form{display:grid;gap:16px;margin-top:24px}
1603
+ .dsh-super-code-settings form>h3{margin:0;font-size:14px;font-weight:600}
1604
+ .dsh-super-code-settings-field{display:grid;gap:6px}
1605
+ .dsh-super-code-settings label{font-size:13px;font-weight:500}
1606
+ .dsh-super-code-settings small{display:block;font-size:12px;color:var(--sc-muted);line-height:1.6;overflow-wrap:anywhere}
1607
+ .dsh-super-code-settings-form-actions{display:flex;align-items:center;justify-content:flex-end;flex-wrap:wrap;gap:12px;padding-top:4px}
1608
+ .dsh-super-code-settings-form-actions>small{flex:1;min-width:220px}
1609
+ .dsh-super-code-settings-form-actions>button{margin-left:auto;flex:none}
1610
+ .dsh-super-code-settings .dsh-super-code-primary-button,.dsh-super-code-confirm .dsh-super-code-primary-button{background:var(--sc-text);border-color:var(--sc-text);color:var(--sc-bg);font-weight:500}
1611
+ .dsh-super-code-settings .dsh-super-code-primary-button:hover,.dsh-super-code-confirm .dsh-super-code-primary-button:hover{background:color-mix(in srgb,var(--sc-text) 85%,var(--sc-bg))}
1612
+ .dsh-super-code-settings-guidance:empty{display:none}
1613
+ .dsh-super-code-settings-guidance{margin-top:20px;padding-top:12px;border-top:1px solid var(--sc-line);color:var(--sc-muted);font-size:12px}
1614
+ .dsh-super-code-settings-guidance p{margin:0 0 4px}
1615
+ .dsh-super-code-settings [role=alert],.dsh-super-code-detail [role=alert],.dsh-super-code-tree-error{font-size:13px;color:var(--sc-error);overflow-wrap:anywhere}
1616
+ @container(max-width:420px){.dsh-super-code-settings-header{padding:16px}.dsh-super-code-settings-body{padding:16px}.dsh-super-code-settings-summary{padding:12px}.dsh-super-code-settings-status-row{gap:8px}.dsh-super-code-preset-status{flex-basis:100%}.dsh-super-code-settings-form-actions>small{min-width:0;flex-basis:100%}}
1617
+
1618
+ /* Confirmation. */
1619
+ .dsh-super-code-confirm{width:min(520px,calc(100vw - 32px));max-height:calc(100dvh - 48px);overflow:auto;border:1px solid var(--sc-line);border-radius:16px;padding:24px;background:var(--sc-bg);box-shadow:0 12px 48px #0003}
1620
+ .dsh-super-code-confirm::backdrop{background:#10182066}
1621
+ .dsh-super-code-confirm h3{font-size:16px;font-weight:600;margin:0 0 8px}
1622
+ .dsh-super-code-confirm>p{font-size:13px;color:var(--sc-muted);margin:0 0 16px;line-height:1.7}
1623
+ .dsh-super-code-confirm ul{padding:0;list-style:none;margin:20px 0;background:var(--sc-surface);border-radius:12px;overflow:hidden}
1624
+ .dsh-super-code-confirm li{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px;overflow-wrap:anywhere}
1625
+ .dsh-super-code-confirm li+li{border-top:1px solid var(--sc-line)}
1626
+ .dsh-super-code-confirm li>button{background:transparent;flex:none;font-size:12px}
1627
+ .dsh-super-code-confirm-item-info{display:grid;gap:3px;min-width:0}
1628
+ .dsh-super-code-confirm-item-info strong{font-size:14px;font-weight:500}
1629
+ .dsh-super-code-confirm-previous,.dsh-super-code-confirm-new-id{font-size:12px;color:var(--sc-muted)}
1630
+ .dsh-super-code-confirm-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:20px}
1631
+ .dsh-super-code-confirm .dsh-super-code-confirm-empty{padding:20px 16px;background:var(--sc-surface);border-radius:12px}
1632
+
1633
+ /* Memory library: geometry stays at 76px per row. */
1634
+ .dsh-super-code-memory{height:100%;min-height:0;display:flex;flex-direction:column;container-type:inline-size}
1635
+ .dsh-super-code-memory>header{padding:16px;border-bottom:1px solid var(--sc-line);flex:none}
1636
+ .dsh-super-code-memory-heading{display:flex;align-items:center;justify-content:space-between;gap:8px}
1637
+ .dsh-super-code-memory h2{font-size:16px;font-weight:600;margin:0}
1638
+ .dsh-super-code-memory-muted{font-size:13px;color:var(--sc-muted);line-height:1.65;margin:8px 0}
1639
+ .dsh-super-code-memory-scopes{display:flex;gap:2px;padding:3px;margin:16px 0 12px;border-radius:18px;background:var(--sc-surface)}
1640
+ .dsh-super-code-memory-scopes button{flex:1;min-height:28px;padding:3px 8px;border:0;border-radius:16px;font-size:13px;background:transparent;color:var(--sc-muted)}
1641
+ .dsh-super-code-memory-scopes button[aria-pressed=true]{background:var(--sc-bg);color:var(--sc-text);box-shadow:inset 0 0 0 1px var(--sc-line)}
1642
+ .dsh-super-code-memory-search{position:relative;margin-bottom:8px}
1643
+ .dsh-super-code-memory-search>svg{position:absolute;left:11px;top:9px;width:16px;height:16px;color:var(--sc-muted);pointer-events:none}
1644
+ .dsh-super-code-memory-search input{padding-left:34px}
1645
+ .dsh-super-code-memory small{font-size:12px;color:var(--sc-muted);overflow-wrap:anywhere}
1646
+ .dsh-super-code-memory-workspace{flex:1;display:flex;flex-direction:column;min-height:0;background:var(--sc-surface)}
1647
+ .dsh-super-code-memory-topic-index{display:flex;flex-direction:column;flex:none;gap:8px;min-width:0;padding:12px 16px;border-bottom:1px solid var(--sc-line);background:var(--sc-bg)}
1648
+ .dsh-super-code-memory-topic-label{display:flex;align-items:center;gap:8px;font-size:11px;font-weight:500;color:var(--sc-muted)}
1649
+ .dsh-super-code-memory-topic-label>span{padding:0 5px;border-radius:4px;background:var(--sc-surface);font-variant-numeric:tabular-nums}
1650
+ .dsh-super-code-memory-topic-options{display:flex;gap:6px;overflow:auto;min-width:0;padding:2px 0 5px}
1651
+ .dsh-super-code-memory-topic-index button{flex:none;display:inline-flex;align-items:center;gap:6px;min-height:30px;padding:5px 8px;border:1px solid var(--sc-line);border-radius:8px;background:var(--sc-bg);color:var(--sc-muted);font-size:12px;white-space:nowrap}
1652
+ .dsh-super-code-memory-topic-index button .dsh-super-code-glyph{width:14px;height:14px}
1653
+ .dsh-super-code-memory-topic-index button>span{min-width:0;overflow:hidden;text-overflow:ellipsis}
1654
+ .dsh-super-code-memory-topic-index button small{font-size:11px;line-height:1.3;min-width:16px;text-align:center;padding:1px 4px;border-radius:4px;background:var(--sc-surface);font-variant-numeric:tabular-nums}
1655
+ .dsh-super-code-memory-topic-index button:hover{background:var(--sc-hover);color:var(--sc-text)}
1656
+ .dsh-super-code-memory-topic-index button[aria-pressed=true]{border-color:var(--sc-accent);background:var(--sc-selected);color:var(--sc-text)}
1657
+ .dsh-super-code-memory-results{flex:1;display:flex;flex-direction:column;min-width:0;min-height:0}
1658
+ .dsh-super-code-memory-list-heading{display:flex;align-items:baseline;justify-content:space-between;gap:8px;padding:12px 16px 8px;flex:none}
1659
+ .dsh-super-code-memory-list-heading strong{font-size:12px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1660
+ .dsh-super-code-memory-list-heading small{font-size:11px;flex:none}
1661
+ .dsh-super-code-memory-list{flex:1;min-height:0;overflow:auto;padding:0 12px;background:var(--sc-surface)}
1662
+ .dsh-super-code-memory-list>[role=listitem]{height:76px;padding-bottom:6px}
1663
+ .dsh-super-code-memory-row{position:relative;display:flex;flex-direction:column;justify-content:center;gap:2px;width:100%;height:70px;border:1px solid var(--sc-line);border-radius:10px;padding:6px 12px 6px 16px;text-align:left;background:var(--sc-bg);box-shadow:0 1px 2px #00000008;overflow:hidden}
1664
+ .dsh-super-code-memory-row:before{content:"";position:absolute;left:0;top:10px;bottom:10px;width:3px;border-radius:0 3px 3px 0;background:var(--sc-accent)}
1665
+ .dsh-super-code-memory-row[data-kind=constraint]:before{background:var(--sc-warning)}
1666
+ .dsh-super-code-memory-row[data-kind=fact]:before{background:var(--sc-accent)}
1667
+ .dsh-super-code-memory-row[data-kind=experience]:before{background:var(--sc-success)}
1668
+ .dsh-super-code-memory-row:hover{background:var(--sc-hover);border-color:color-mix(in srgb,var(--sc-accent) 35%,var(--sc-line))}
1669
+ .dsh-super-code-memory-row-heading{display:flex;align-items:center;gap:6px;min-width:0;line-height:14px}
1670
+ .dsh-super-code-memory-row-heading .dsh-super-code-glyph{width:12px;height:12px;color:var(--sc-faint)}
1671
+ .dsh-super-code-memory-row-topic{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--sc-muted);font-size:11px}
1672
+ .dsh-super-code-memory-row-kind{color:var(--sc-muted);white-space:nowrap}
1673
+ .dsh-super-code-memory-row strong{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;line-height:16px}
1674
+ .dsh-super-code-memory-row-meta{display:flex;align-items:center;gap:8px;font-size:10px;color:var(--sc-muted);white-space:nowrap;line-height:12px}
1675
+ .dsh-super-code-memory-row-meta>span+span{border-left:1px solid var(--sc-line);padding-left:8px;font-family:var(--sc-mono)}
1676
+ .dsh-super-code-memory-empty{padding:24px 8px;color:var(--sc-muted);font-size:13px;line-height:1.8}
1677
+ .dsh-super-code-memory-body{flex:1;min-height:0;overflow:auto;padding:16px;background:var(--sc-surface)}
1678
+ .dsh-super-code-memory-body article{padding:16px;border:1px solid var(--sc-line);border-radius:12px;background:var(--sc-bg);box-shadow:0 1px 3px #0000000a}
1679
+ .dsh-super-code-memory-detail-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;color:var(--sc-muted);font-size:11px}
1680
+ .dsh-super-code-memory-detail-meta>span{display:inline-flex;align-items:center;gap:5px;padding:3px 7px;border-radius:6px;background:var(--sc-surface)}
1681
+ .dsh-super-code-memory-detail-meta>span:first-child{background:var(--sc-selected);color:var(--sc-accent)}
1682
+ .dsh-super-code-memory-detail-meta .dsh-super-code-glyph{width:13px;height:13px;color:inherit}
1683
+ .dsh-super-code-memory-body h3{font-size:16px;font-weight:600;line-height:1.6;margin:12px 0 16px;overflow-wrap:anywhere}
1684
+ .dsh-super-code-memory-detail{font-size:14px;white-space:pre-wrap;line-height:1.8;overflow-wrap:anywhere}
1685
+ .dsh-super-code-memory-body dl{padding-top:8px;border-top:1px solid var(--sc-line)}
1686
+ .dsh-super-code-memory-body dt{font-size:12px;color:var(--sc-muted);margin-top:12px}
1687
+ .dsh-super-code-memory-body dd{margin:4px 0;font-size:12px;line-height:1.7;overflow-wrap:anywhere}
1688
+ .dsh-super-code-memory-related{border-top:1px solid var(--sc-line);margin-top:20px;padding-top:12px}
1689
+ .dsh-super-code-memory-related h4{font-size:12px;font-weight:500;color:var(--sc-muted);margin:0 0 6px}
1690
+ .dsh-super-code-memory-related button{display:flex;align-items:center;gap:8px;width:100%;padding:8px 4px;border:0;border-radius:6px;background:transparent;font-size:12px;text-align:left}
1691
+ .dsh-super-code-memory-related button:hover{background:var(--sc-hover)}
1692
+ .dsh-super-code-memory-related button>span{min-width:0;flex:1;overflow-wrap:anywhere}
1693
+ .dsh-super-code-memory-related .dsh-super-code-glyph{width:14px;height:14px}
1694
+ @container(min-width:520px){
1695
+ .dsh-super-code-memory-workspace{display:grid;grid-template-columns:170px minmax(0,1fr)}
1696
+ .dsh-super-code-memory-topic-index{min-height:0;padding:16px 10px;border-bottom:0;border-right:1px solid var(--sc-line)}
1697
+ .dsh-super-code-memory-topic-label{padding:0 6px}
1698
+ .dsh-super-code-memory-topic-options{flex-direction:column;gap:4px;padding:2px;min-height:0;overflow:auto}
1699
+ .dsh-super-code-memory-topic-index button{width:100%;justify-content:space-between;border-color:transparent;background:transparent}
1700
+ .dsh-super-code-memory-topic-index button>span{flex:1;text-align:left}
1701
+ }
1702
+ .dsh-super-code-memory-activity{margin-top:12px;font-size:13px}
1703
+ .dsh-super-code-memory-activity summary{cursor:pointer;color:var(--sc-muted)}
1704
+ .dsh-super-code-memory-activity-list{max-height:200px;overflow:auto}
1705
+ .dsh-super-code-memory-activity-list button{display:grid;grid-template-columns:auto minmax(0,1fr);gap:4px 8px;width:100%;border:0;border-bottom:1px solid var(--sc-line);background:transparent;padding:8px 0;text-align:left;font-size:12px}
1706
+ .dsh-super-code-memory-activity-list small{grid-column:2;color:var(--sc-muted);font-size:11px;overflow-wrap:anywhere}
1707
+ .dsh-super-code-memory-activity-list span{overflow-wrap:anywhere}
1708
+ .dsh-super-code-memory-action{color:var(--sc-muted)}
1709
+ .dsh-super-code-memory-action[data-action=read]{color:var(--sc-accent)}
1710
+ .dsh-super-code-memory-action[data-action=remember]{color:var(--sc-success)}
1711
+
1712
+ /* Graph: preserve 128px node width and layout anchors. */
1713
+ .dsh-super-code-tree{height:100%;min-height:0;display:flex;flex-direction:column;overflow:auto;container-type:inline-size}
1714
+ .dsh-super-code-tree>header,.dsh-super-code-graph-legend,.dsh-super-code-graph-controls,.dsh-super-code-history-controls{flex:none}
1715
+ .dsh-super-code-tree-header{display:flex;flex-direction:column;gap:8px;padding:12px}
1716
+ .dsh-super-code-tree-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0}
1717
+ .dsh-super-code-tree-header strong{font-size:15px;font-weight:600;white-space:nowrap}
1718
+ .dsh-super-code-tree-header .dsh-super-code-title-line{gap:6px;min-width:0}
1719
+ .dsh-super-code-tree-header .dsh-super-code-title-line>.dsh-super-code-glyph{width:16px;height:16px}
1720
+ .dsh-super-code-tree-count{font-size:11px;color:var(--sc-muted);white-space:nowrap;font-variant-numeric:tabular-nums}
1721
+ .dsh-super-code-tree-toolbar{display:flex;align-items:center;gap:6px;min-width:0}
1722
+ .dsh-super-code-tree-toolbar>.dsh-super-code-icon-button{width:28px;height:28px;border-radius:6px}
1723
+ .dsh-super-code-tree-toolbar>.dsh-super-code-icon-button svg{width:16px;height:16px}
1724
+ .dsh-super-code-graph-legend{display:flex;flex-wrap:wrap;gap:6px 12px;font-size:10px;color:var(--sc-muted)}
1250
1725
  .dsh-super-code-graph-legend>span{display:flex;align-items:center;gap:5px}
1251
- .dsh-super-code-graph-legend .dsh-super-code-circle{width:7px;height:7px;box-shadow:none}
1726
+ .dsh-super-code-circle.active{--state-color:#008b78}
1727
+ .dsh-super-code-circle.idle{--state-color:#3971de}
1728
+ .dsh-super-code-circle.stopped{--state-color:#777d87}
1729
+ .dsh-super-code-circle.unavailable{--state-color:#b87716}
1730
+ .dsh-super-code-graph-legend .dsh-super-code-circle,.dsh-super-code-history-list .dsh-super-code-circle{display:block;width:7px;height:7px;flex:none;border-radius:50%;background:var(--state-color)}
1731
+ .dsh-super-code-graph-legend .dsh-super-code-circle.idle{background:transparent;border:1px solid var(--state-color)}
1732
+ .dsh-super-code-graph-controls{display:flex;align-items:center;gap:0;padding:0;border:1px solid var(--sc-line);border-radius:7px;color:var(--sc-muted);font-size:12px;flex:none}
1733
+ .dsh-super-code-graph-controls button,.dsh-super-code-history-controls button{display:inline-flex;align-items:center;justify-content:center;gap:5px;min-height:28px;min-width:28px;padding:3px 6px;border:0;border-radius:6px;background:transparent;font-size:12px}
1734
+ .dsh-super-code-graph-controls button:hover,.dsh-super-code-history-controls button:hover{background:var(--sc-hover)}
1735
+ .dsh-super-code-graph-controls span{min-width:36px;text-align:center;font-family:var(--sc-mono);font-size:11px}
1736
+ .dsh-super-code-history-controls{display:flex;align-items:center;gap:6px;border-left:1px solid var(--sc-line);padding-left:6px}
1737
+ .dsh-super-code-history-controls .dsh-super-code-glyph{width:16px;height:16px}
1738
+ .dsh-super-code-history-controls button{white-space:nowrap}
1739
+ .dsh-super-code-history-controls .dsh-super-code-action-count{font-family:var(--sc-mono);font-size:11px}
1740
+ .dsh-super-code-history-controls button[aria-expanded=true]{background:var(--sc-selected);border-color:var(--sc-accent)}
1741
+ @container(max-width:360px){
1742
+ .dsh-super-code-tree-toolbar{gap:3px}
1743
+ .dsh-super-code-graph-controls button{min-width:26px;padding:3px 4px}
1744
+ .dsh-super-code-graph-controls span{min-width:28px}
1745
+ .dsh-super-code-history-controls{gap:3px;padding-left:3px}
1746
+ .dsh-super-code-history-controls button{gap:3px;padding:3px;font-size:11px}
1747
+ .dsh-super-code-history-controls .dsh-super-code-glyph{display:none}
1748
+ }
1749
+ .dsh-super-code-graph-scroll{flex:1;min-height:180px;overflow:hidden;padding:0 12px;touch-action:none;cursor:grab;user-select:none;border-top:1px solid var(--sc-line);background:var(--sc-surface)}
1750
+ .dsh-super-code-graph-scroll.dragging,.dsh-super-code-graph-scroll.dragging *{cursor:grabbing!important}
1252
1751
  .dsh-super-code-graph{position:relative;transform-origin:0 0}
1253
- .dsh-super-code-graph-edges{position:absolute;inset:0;pointer-events:none;stroke:var(--agent-line);stroke-width:1.5}
1254
- .dsh-super-code-graph-node{position:absolute;width:128px;min-height:100px;display:flex;flex-direction:column;align-items:center;gap:6px;border:0;padding:0 4px;background:transparent;color:inherit;font:inherit;cursor:pointer;border-radius:8px}
1255
- .dsh-super-code-circle{position:relative;display:flex;align-items:center;justify-content:center;flex:none;width:40px;height:40px;border-radius:50%!important;corner-shape:round!important;font-size:13px;font-weight:600;background:var(--state-color);color:#fff}
1256
- .dsh-super-code-circle.active{--state-color:#008b78}.dsh-super-code-circle.idle{--state-color:#3971de}.dsh-super-code-circle.stopped{--state-color:#777d87}.dsh-super-code-circle.unavailable{--state-color:#b87716}
1257
- .dsh-super-code-graph-node .dsh-super-code-circle{background:linear-gradient(145deg,color-mix(in srgb,var(--state-color) 83%,white),var(--state-color));box-shadow:inset 0 1px 1px #ffffff40,0 2px 6px #00000012}
1258
- .dsh-super-code-graph-node .dsh-super-code-circle:after{content:"";position:absolute;inset:-5px;border:1px solid color-mix(in srgb,var(--state-color) 22%,transparent);border-radius:50%;corner-shape:round;pointer-events:none}
1259
- .dsh-super-code-graph-node .dsh-super-code-circle.idle:after{animation:super-agent-breathe 3s ease-in-out infinite}
1260
- .dsh-super-code-graph-node .dsh-super-code-circle.active:after{border-width:2px;border-top-color:var(--state-color);border-right-color:var(--state-color);animation:super-agent-process 1.6s linear infinite}
1261
- .dsh-super-code-graph-node .dsh-super-code-circle.stopped{background:linear-gradient(145deg,#9297a0,#747a84);box-shadow:inset 0 1px 1px #ffffff30}
1262
- .dsh-super-code-graph-node .dsh-super-code-circle.stopped:after{border-color:color-mix(in srgb,var(--state-color) 14%,transparent)}
1263
- .dsh-super-code-graph-node .dsh-super-code-circle.unavailable:after{border-style:dashed;border-color:var(--state-color)}
1264
- .dsh-super-code-graph-node:hover .dsh-super-code-circle{box-shadow:inset 0 1px 1px #ffffff40,0 3px 10px color-mix(in srgb,var(--state-color) 25%,transparent)}
1752
+ .dsh-super-code-graph-edges{position:absolute;inset:0;pointer-events:none;stroke:color-mix(in srgb,var(--sc-muted) 35%,var(--sc-surface));stroke-width:1.25}
1753
+ .dsh-super-code-graph-node{position:absolute;display:flex;align-items:center;flex-direction:column;width:128px;height:105px;gap:4px;padding:0 4px;border:0;border-radius:12px;background:transparent;cursor:pointer}
1754
+ .dsh-super-code-graph-node[aria-disabled]{cursor:default;opacity:.65}
1755
+ .dsh-super-code-graph-node>.dsh-super-code-circle{position:relative;display:grid;place-items:center;flex:none;width:40px;height:40px;border-radius:50%!important;corner-shape:round!important;background:linear-gradient(145deg,color-mix(in srgb,var(--state-color) 83%,white),var(--state-color));box-shadow:inset 0 1px 1px #ffffff40,0 2px 6px #00000012;color:#fff;font-size:13px;font-weight:600}
1756
+ .dsh-super-code-graph-node>.dsh-super-code-circle:after{content:"";position:absolute;inset:-5px;border:1px solid color-mix(in srgb,var(--state-color) 22%,transparent);border-radius:50%;corner-shape:round;pointer-events:none}
1757
+ .dsh-super-code-graph-node>.dsh-super-code-circle.idle:after{animation:super-agent-breathe 3s ease-in-out infinite}
1758
+ .dsh-super-code-graph-node>.dsh-super-code-circle.active:after{border-width:2px;border-top-color:var(--state-color);border-right-color:var(--state-color);animation:super-agent-process 1.6s linear infinite}
1759
+ .dsh-super-code-graph-node>.dsh-super-code-circle.stopped{background:linear-gradient(145deg,#9297a0,#747a84);box-shadow:inset 0 1px 1px #ffffff30}
1760
+ .dsh-super-code-graph-node>.dsh-super-code-circle.stopped:after{border-color:color-mix(in srgb,var(--state-color) 14%,transparent)}
1761
+ .dsh-super-code-graph-node>.dsh-super-code-circle.unavailable:after{border-style:dashed;border-color:var(--state-color)}
1762
+ .dsh-super-code-graph-node:hover>.dsh-super-code-circle{box-shadow:inset 0 1px 1px #ffffff40,0 3px 10px color-mix(in srgb,var(--state-color) 25%,transparent)}
1763
+ .dsh-super-code-graph-node.selected>.dsh-super-code-circle{outline:2px solid var(--sc-accent);outline-offset:7px}
1265
1764
  @keyframes super-agent-breathe{0%,100%{transform:scale(1);opacity:.35}50%{transform:scale(1.12);opacity:.85}}
1266
1765
  @keyframes super-agent-process{to{transform:rotate(360deg)}}
1267
- .dsh-super-code-graph-node:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:4px}
1268
- .dsh-super-code-graph-node[aria-disabled]{cursor:default;opacity:.65}
1269
- .dsh-super-code-graph-node .dsh-super-code-tree-content{width:100%;text-align:center}
1270
- .dsh-super-code-graph-node .dsh-super-code-tree-title{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:18px;height:18px;font-size:12px}
1271
- .dsh-super-code-graph-node .dsh-super-code-tree-usage{justify-content:center;gap:1px 7px;font-size:10px}
1272
- .dsh-super-code-icon-button,.dsh-super-code-tree-toggle{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--agent-muted);cursor:pointer}
1273
- .dsh-super-code-icon-button:hover,.dsh-super-code-tree-toggle:hover{background:color-mix(in srgb,currentColor 9%,transparent)}
1274
- .dsh-super-code-icon-button:disabled{opacity:.45;cursor:default}
1275
- .dsh-super-code-view-button{flex:none;border:0;border-radius:4px;padding:6px 8px;background:transparent;color:var(--agent-muted);font:inherit;font-size:12px;cursor:pointer}
1276
- .dsh-super-code-view-button:hover{background:color-mix(in srgb,currentColor 7%,transparent);color:inherit}
1277
- .dsh-super-code-view-button:disabled{opacity:.45;cursor:default}
1278
- .dsh-super-code-tree-rows{padding:0 12px 20px}
1279
- .dsh-super-code-tree-row{position:relative;display:flex;align-items:center;gap:6px;min-width:0;min-height:64px;padding:10px 8px 10px calc(4px + var(--agent-depth)*14px);border-radius:6px;cursor:default;box-sizing:border-box}
1280
- .dsh-super-code-tree-row[aria-expanded]{cursor:pointer}
1281
- .dsh-super-code-tree-row[aria-level]:not([aria-level="1"]):before{content:"";position:absolute;left:15px;width:calc(var(--agent-depth)*14px);height:100%;top:0;background:repeating-linear-gradient(to right,var(--agent-line) 0,var(--agent-line) 1px,transparent 1px,transparent 14px);pointer-events:none}
1282
- .dsh-super-code-tree-row:hover{background:color-mix(in srgb,currentColor 5%,transparent)}
1283
- .dsh-super-code-tree-row.selected{background:color-mix(in srgb,var(--dsw-color-primary,#3276dc) 6%,transparent)}
1284
- .dsh-super-code-tree-row:focus-visible,.dsh-super-code-tree button:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:-2px}
1285
- .dsh-super-code-tree-row[aria-disabled]{cursor:default;opacity:.7}
1286
- .dsh-super-code-tree-toggle{width:22px;height:26px;z-index:1}
1287
- .dsh-super-code-tree-toggle svg{transition:transform .12s}.dsh-super-code-tree-toggle.expanded svg{transform:rotate(90deg)}
1288
- .dsh-super-code-tree-connector{width:22px;flex:none}
1289
- .dsh-super-code-tree-content{display:grid;gap:4px;flex:1;min-width:0}
1290
- .dsh-super-code-tree-title{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:anywhere;line-height:1.4}
1291
- .dsh-super-code-tree-meta{color:var(--agent-muted);font-size:11px;line-height:1.4;overflow-wrap:anywhere}
1292
- .dsh-super-code-tree-usage{display:flex;flex-wrap:wrap;gap:3px 10px;font-size:10px;line-height:1.6;color:var(--agent-muted);font-variant-numeric:tabular-nums}
1293
- .dsh-super-code-tree-usage>span{white-space:nowrap}
1294
- .dsh-super-code-state{display:inline-flex;align-items:center;gap:5px;padding:2px 6px;border-radius:5px;color:var(--state-color);background:color-mix(in srgb,var(--state-color) 9%,transparent)}
1295
- .dsh-super-code-state:before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor}
1296
- .dsh-super-code-state.active{--state-color:#16877d}
1297
- .dsh-super-code-state.idle{--state-color:#5471bb}
1298
- .dsh-super-code-state.stopped{--state-color:#827299}
1299
- .dsh-super-code-state.unavailable{--state-color:#b77b29}
1300
- @media(prefers-color-scheme:dark){.dsh-super-code-state.active{--state-color:#6bc7b6}.dsh-super-code-state.idle{--state-color:#91b0f4}.dsh-super-code-state.stopped{--state-color:#b9a9cf}.dsh-super-code-state.unavailable{--state-color:#e8b971}}
1301
- .dsh-super-code-tree-status{width:6px;height:6px;border-radius:50%;background:var(--agent-line);flex:none}
1302
- .dsh-super-code-tree-row.running .dsh-super-code-tree-status{background:#168c78}
1303
- .dsh-super-code-tree-status.unavailable{background:#c17e1d}
1304
- .dsh-super-code-tree-note,.dsh-super-code-tree-empty{margin:10px 18px;color:var(--agent-muted);font-size:12px}
1305
- .dsh-super-code-tree-error{margin:12px 14px;color:var(--dsw-color-text-error,#bd423b);font-size:12px;overflow-wrap:anywhere}
1306
- .dsh-super-code-tree-more{display:block;margin:4px auto 14px;padding:6px 12px;border:1px solid var(--agent-line);border-radius:4px;background:transparent;color:inherit;cursor:pointer}
1307
- .dsh-super-code-detail{height:100%;min-width:0;display:flex;flex-direction:column;font-size:13px;letter-spacing:0;--agent-muted:var(--dsw-alias-label-secondary,#70757d);--agent-line:var(--dsw-alias-border-l1,#dedfe3)}
1308
- .dsh-super-code-detail-header{padding:20px 20px 18px;border-bottom:1px solid var(--agent-line);flex:none;max-height:45%;overflow:auto}
1309
- .dsh-super-code-detail-header nav{font-size:11px;line-height:1.5;color:var(--agent-muted);overflow-wrap:anywhere}
1310
- .dsh-super-code-detail-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-top:14px}
1311
- .dsh-super-code-detail-heading>div{min-width:0}
1312
- .dsh-super-code-detail h2{font-size:16px;line-height:1.5;font-weight:600;margin:0;overflow-wrap:anywhere}
1313
- .dsh-super-code-detail-task{font-size:13px;line-height:1.7;margin:12px 0 0;overflow-wrap:anywhere}
1314
- .dsh-super-code-task-memory{margin-top:16px;padding-top:14px;border-top:1px solid var(--agent-line);font-size:12px;line-height:1.7;overflow-wrap:anywhere}
1766
+ .dsh-super-code-tree-content{display:grid;gap:2px;width:100%;min-width:0;text-align:center}
1767
+ .dsh-super-code-tree-title{height:16px;font-size:12px;line-height:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1768
+ .dsh-super-code-node-status{display:flex;align-items:center;justify-content:center;gap:4px;font-size:11px;line-height:14px;color:var(--sc-muted)}
1769
+ .dsh-super-code-node-status>i{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}
1770
+ .dsh-super-code-node-status[data-tone=active]{color:var(--sc-accent)}
1771
+ .dsh-super-code-node-status[data-tone=unavailable]{color:var(--sc-warning)}
1772
+ .dsh-super-code-node-status[data-tone=idle]>i{background:transparent;border:1px solid currentColor}
1773
+ .dsh-super-code-tree-usage{display:flex;flex-direction:column;gap:0;font-size:10px;line-height:12px;color:var(--sc-muted);font-variant-numeric:tabular-nums}
1774
+ .dsh-super-code-tree-usage>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1775
+ .dsh-super-code-branch-toggle{position:absolute;display:grid;place-items:center;width:22px;height:22px;border:1px solid var(--sc-line);border-radius:50%;padding:0;background:var(--sc-bg);color:var(--sc-muted)}
1776
+ .dsh-super-code-branch-toggle:hover{color:var(--sc-accent);border-color:currentColor}
1777
+ .dsh-super-code-tree-empty,.dsh-super-code-tree-error{margin:12px 16px}
1778
+ .dsh-super-code-tree-more{align-self:center;margin:8px 16px;padding:5px 10px;border:1px solid var(--sc-line);border-radius:8px;background:var(--sc-bg);font-size:13px}
1779
+ .dsh-super-code-history{display:flex;flex-direction:column;flex:none;height:46%;min-height:220px;max-height:400px;margin:0 12px 12px;padding:12px;border:1px solid var(--sc-line);border-radius:12px;background:var(--sc-surface)}
1780
+ .dsh-super-code-history>input{flex:none;margin-bottom:8px}
1781
+ .dsh-super-code-history p{flex:none;font-size:12px;color:var(--sc-muted);margin:0 0 8px;line-height:1.6}
1782
+ .dsh-super-code-history-filters{display:grid;flex:none;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-bottom:8px}
1783
+ .dsh-super-code-history-filters :is(label,.dsh-super-code-select-field){display:grid;gap:4px;min-width:0;font-size:12px;color:var(--sc-muted)}
1784
+ .dsh-super-code-history-list{flex:1;min-height:56px;overflow:auto;overflow-anchor:none;overscroll-behavior:contain}
1785
+ .dsh-super-code-history-list button{display:flex;align-items:center;gap:8px;width:100%;height:56px;padding:8px 4px;text-align:left;border:0;border-radius:8px;background:transparent}
1786
+ .dsh-super-code-history-list button:hover{background:var(--sc-hover)}
1787
+ .dsh-super-code-history-list button>span{flex:1;min-width:0}
1788
+ .dsh-super-code-history-list strong{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500}
1789
+ .dsh-super-code-history-list small{font-size:11px;color:var(--sc-muted);white-space:nowrap}
1790
+ .dsh-super-code-history-list button>span>small{display:block;overflow:hidden;text-overflow:ellipsis}
1791
+
1792
+ /* Agent details. */
1793
+ .dsh-super-code-detail{height:100%;min-height:0;display:flex;flex-direction:column}
1794
+ .dsh-super-code-detail-header{flex:none;max-height:40%;overflow:auto;padding:10px 12px;border-bottom:1px solid var(--sc-line)}
1795
+ .dsh-super-code-detail-header nav{font-size:11px;color:var(--sc-muted);line-height:16px;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1796
+ .dsh-super-code-detail-heading{display:flex;align-items:center;gap:8px;min-width:0}
1797
+ .dsh-super-code-detail-heading h2{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:600;line-height:20px;margin:0}
1798
+ .dsh-super-code-detail-heading .dsh-super-code-icon-button{width:28px;height:28px;border-radius:6px}
1799
+ .dsh-super-code-detail-status{display:inline-flex;align-items:center;flex:none;gap:5px;padding:2px 6px;border-radius:5px;font-size:11px;white-space:nowrap;background:var(--sc-surface);color:var(--sc-muted)}
1800
+ .dsh-super-code-detail-status:before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor}
1801
+ .dsh-super-code-detail-status[data-tone=active]{color:var(--sc-accent)}
1802
+ .dsh-super-code-detail-status[data-tone=unavailable]{color:var(--sc-warning)}
1803
+ .dsh-super-code-detail-task{font-size:14px;line-height:1.7;margin:12px 0 0;overflow-wrap:anywhere}
1804
+ .dsh-super-code-task-memory{margin-top:16px;padding-top:12px;border-top:1px solid var(--sc-line);font-size:13px;line-height:1.7;overflow-wrap:anywhere}
1315
1805
  .dsh-super-code-task-heading{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px}
1316
- .dsh-super-code-task-heading strong{font-weight:500;color:inherit}
1317
- .dsh-super-code-task-heading span{color:var(--agent-muted);font-size:11px}
1318
- .dsh-super-code-task-memory p{margin:6px 0 0}
1319
- .dsh-super-code-task-memory details{margin-top:8px;color:var(--agent-muted)}
1806
+ .dsh-super-code-task-heading strong{font-weight:500}
1807
+ .dsh-super-code-task-heading span{font-size:12px;color:var(--sc-muted)}
1808
+ .dsh-super-code-task-memory p{margin:4px 0 0}
1809
+ .dsh-super-code-task-memory details{margin-top:8px;color:var(--sc-muted)}
1320
1810
  .dsh-super-code-task-memory summary{cursor:pointer}
1321
- .dsh-super-code-detail-metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 16px;margin:16px 0 0}
1322
- .dsh-super-code-usage-details{margin-top:14px;font-size:12px;color:var(--agent-muted)}
1323
- .dsh-super-code-usage-details summary{cursor:pointer}
1324
- .dsh-super-code-new-content{align-self:center;flex:none;margin:8px 16px 12px;padding:7px 12px;border:1px solid var(--agent-line);border-radius:6px;background:transparent;color:inherit;font:inherit;font-size:12px;cursor:pointer}
1325
- .dsh-super-code-detail-metrics dt{font-size:11px;color:var(--agent-muted)}
1326
- .dsh-super-code-detail-metrics dd{margin:5px 0 0;font-variant-numeric:tabular-nums;font-size:14px;line-height:1.4;overflow-wrap:anywhere}
1327
- .dsh-super-code-detail-metrics>div:first-child dd{font-weight:600}
1328
- .dsh-super-code-detail-status{display:block;margin-top:5px;font-size:11px;color:var(--agent-muted)}
1329
- .dsh-super-code-detail-log{flex:1;min-height:0;overflow:auto;padding:4px 20px 24px}
1330
- .dsh-super-code-detail-log>button,.dsh-super-code-detail-entry button{border:1px solid var(--agent-line);border-radius:4px;background:transparent;color:inherit;padding:5px 8px;margin:10px 8px 4px 0;font-size:12px;cursor:pointer}
1331
- .dsh-super-code-detail-entry{padding:20px 0;min-width:0}
1332
- .dsh-super-code-detail-entry:has(>details){padding:10px 0;color:var(--agent-muted)}
1333
- .dsh-super-code-detail-entry details[open]{color:inherit;padding-bottom:8px}
1334
- .dsh-super-code-detail-entry-label{display:flex;justify-content:space-between;gap:10px;font-size:12px;font-weight:600}
1335
- .dsh-super-code-detail-entry time{color:var(--agent-muted);font-size:11px;font-weight:400;flex:none}
1336
- .dsh-super-code-detail-entry pre{font:inherit;line-height:1.7;white-space:pre-wrap;overflow-wrap:anywhere;margin:8px 0 0}
1337
- .dsh-super-code-detail-entry summary{cursor:pointer;font-size:12px;overflow-wrap:anywhere}
1338
- .dsh-super-code-detail-entry.context{color:var(--agent-muted)}
1339
- .dsh-super-code-detail-entry.error,.dsh-super-code-detail [role=alert]{color:var(--dsw-color-text-error,#bd423b)}
1340
- .dsh-super-code-detail button:focus-visible,.dsh-super-code-detail summary:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:3px}
1341
- .dsh-super-code-detail-entry summary:hover{color:var(--dsw-alias-label-primary,inherit)}
1342
- @media(prefers-reduced-motion:reduce){.dsh-super-code-tree-toggle svg{transition:none}.dsh-super-code-graph-node .dsh-super-code-circle:after{animation:none!important}}
1811
+ .dsh-super-code-detail-metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 12px;margin:0;padding:10px;border-radius:8px;background:var(--sc-surface)}
1812
+ .dsh-super-code-detail-metrics>div{display:flex;align-items:baseline;justify-content:space-between;gap:6px;min-width:0}
1813
+ .dsh-super-code-detail-metrics dt{font-size:11px;color:var(--sc-muted)}
1814
+ .dsh-super-code-detail-metrics dd{font-size:12px;line-height:1.4;margin:0;font-variant-numeric:tabular-nums;overflow-wrap:anywhere;font-weight:500}
1815
+ .dsh-super-code-usage-details{margin-top:4px;color:var(--sc-muted);font-size:12px}
1816
+ .dsh-super-code-usage-details>summary{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:24px;border-radius:5px;cursor:pointer;list-style:none}
1817
+ .dsh-super-code-usage-details>summary::-webkit-details-marker{display:none}
1818
+ .dsh-super-code-usage-details>summary:hover{background:var(--sc-hover)}
1819
+ .dsh-super-code-detail-summary{display:flex;align-items:center;gap:16px;min-width:0}
1820
+ .dsh-super-code-detail-summary>span{display:inline-flex;align-items:baseline;gap:5px;font-size:11px;white-space:nowrap}
1821
+ .dsh-super-code-detail-summary strong{font-weight:500;font-size:12px;color:var(--sc-text);font-variant-numeric:tabular-nums}
1822
+ .dsh-super-code-detail-info-toggle{display:inline-flex;align-items:center;gap:3px;flex:none;font-size:11px}
1823
+ .dsh-super-code-detail-info-toggle .dsh-super-code-glyph{width:13px;height:13px;transition:transform .12s}
1824
+ .dsh-super-code-usage-details[open]>.dsh-super-code-detail-info-toggle .dsh-super-code-glyph,.dsh-super-code-usage-details[open]>summary .dsh-super-code-detail-info-toggle .dsh-super-code-glyph{transform:rotate(180deg)}
1825
+ .dsh-super-code-detail-info{padding-top:8px;padding-bottom:2px}
1826
+ .dsh-super-code-detail-info .dsh-super-code-memory-activity{margin-top:10px;font-size:12px}
1827
+ .dsh-super-code-detail-info .dsh-super-code-task-memory{margin-top:10px;font-size:12px}
1828
+ .dsh-super-code-detail-log{flex:1;min-height:0;overflow:auto;padding:14px 14px 24px;background:var(--sc-bg)}
1829
+ .dsh-super-code-detail-log>button,.dsh-super-code-detail-entry button{border:1px solid var(--sc-line);border-radius:8px;background:var(--sc-bg);padding:5px 8px;margin:0 8px 10px 0;font-size:12px}
1830
+ .dsh-super-code-detail-entry{display:flex;align-items:flex-start;gap:8px;min-width:0;margin:0 0 16px}
1831
+ .dsh-super-code-detail-avatar{display:grid;place-items:center;flex:none;width:26px;height:26px;margin-top:2px;border-radius:8px;background:var(--sc-surface);color:var(--sc-muted)}
1832
+ .dsh-super-code-detail-avatar .dsh-super-code-glyph{width:16px;height:16px;color:inherit}
1833
+ .dsh-super-code-detail-message{flex:1;min-width:0;padding:10px 12px;border:1px solid var(--sc-line);border-radius:4px 12px 12px 12px;background:var(--sc-bg)}
1834
+ .dsh-super-code-detail-entry.user{flex-direction:row-reverse;margin-left:28px}
1835
+ .dsh-super-code-detail-entry.user .dsh-super-code-detail-avatar{background:var(--sc-accent);color:#fff}
1836
+ .dsh-super-code-detail-entry.user .dsh-super-code-detail-message{border-color:color-mix(in srgb,var(--sc-accent) 22%,var(--sc-line));border-radius:12px 4px 12px 12px;background:var(--sc-selected)}
1837
+ .dsh-super-code-detail-entry.agent .dsh-super-code-detail-avatar{background:color-mix(in srgb,var(--sc-success) 10%,var(--sc-bg));color:var(--sc-success)}
1838
+ .dsh-super-code-detail-entry.tool{margin-bottom:12px}
1839
+ .dsh-super-code-detail-entry.tool .dsh-super-code-detail-message{padding:8px 10px;border-radius:8px;background:var(--sc-surface)}
1840
+ .dsh-super-code-detail-entry.context .dsh-super-code-detail-message{border-style:dotted;color:var(--sc-muted);background:var(--sc-surface)}
1841
+ .dsh-super-code-detail-entry.error .dsh-super-code-detail-avatar{color:var(--sc-error);background:color-mix(in srgb,var(--sc-error) 10%,var(--sc-bg))}
1842
+ .dsh-super-code-detail-entry.error .dsh-super-code-detail-message{border-color:color-mix(in srgb,var(--sc-error) 35%,var(--sc-line));color:var(--sc-error)}
1843
+ .dsh-super-code-detail-entry-label{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0;font-size:11px;font-weight:500;color:var(--sc-muted)}
1844
+ .dsh-super-code-detail-entry-label>span{min-width:0;overflow-wrap:anywhere}
1845
+ .dsh-super-code-detail-entry.user .dsh-super-code-detail-entry-label{color:var(--sc-accent)}
1846
+ .dsh-super-code-detail-entry time{flex:none;font-family:var(--sc-mono);font-size:11px;font-weight:400;color:var(--sc-faint)}
1847
+ .dsh-super-code-detail-entry pre{min-width:0;font:inherit;font-size:14px;line-height:1.75;white-space:pre-wrap;overflow-wrap:anywhere;margin:6px 0 0}
1848
+ .dsh-super-code-detail-entry.tool pre{font-family:var(--sc-mono);font-size:12px;line-height:1.6;color:var(--sc-muted)}
1849
+ .dsh-super-code-detail-message>details{min-width:0;color:var(--sc-muted)}
1850
+ .dsh-super-code-detail-message>details[open]{color:var(--sc-text)}
1851
+ .dsh-super-code-detail-message summary{display:flex;align-items:center;gap:6px;cursor:pointer;overflow-wrap:anywhere;list-style:none}
1852
+ .dsh-super-code-detail-message summary::-webkit-details-marker{display:none}
1853
+ .dsh-super-code-detail-message summary .dsh-super-code-detail-entry-label{flex:1;min-width:0;font-size:12px}
1854
+ .dsh-super-code-detail-message summary>.dsh-super-code-glyph{width:14px;height:14px;transition:transform .12s}
1855
+ .dsh-super-code-detail-message details[open] summary>.dsh-super-code-glyph{transform:rotate(180deg)}
1856
+ .dsh-super-code-detail-message details pre{margin-top:10px;padding:8px 10px;border:1px solid var(--sc-line);border-radius:7px;background:var(--sc-bg)}
1857
+ .dsh-super-code-detail-entry button{margin:8px 0 0}
1858
+ .dsh-super-code-new-content{flex:none;align-self:center;margin:8px 16px 12px;border:1px solid var(--sc-line);border-radius:8px;padding:6px 12px;background:var(--sc-bg);font-size:13px}
1859
+ @media(hover:none) and (pointer:coarse){:where(.dsh-super-code-settings,.dsh-super-code-memory,.dsh-super-code-tree) input{font-size:16px}}
1860
+ @media(prefers-reduced-motion:reduce){:where(.dsh-super-code-settings,.dsh-super-code-tree,.dsh-super-code-detail,.dsh-super-code-memory,.dsh-super-code-confirm,.dsh-super-code-select) *{transition:none!important;animation:none!important}.dsh-super-code-graph-node>.dsh-super-code-circle:after{animation:none!important}}
1861
+
1862
+ /* Same custom trigger and option list for all six dropdowns. Fixed placement
1863
+ * keeps history menus visible outside the clipped graph/sidebar viewport. */
1864
+ .dsh-super-code-select{display:inline-block;min-width:0;width:100%;font-size:12px;vertical-align:middle}
1865
+ .dsh-super-code-select :is(button,div,span,svg){box-sizing:border-box}
1866
+ .dsh-super-code-select .dsh-super-code-select-trigger{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;height:36px;min-width:0;padding:7px 10px;border:1px solid var(--sc-line);border-radius:8px;background:var(--sc-bg);color:var(--sc-text);font:inherit;text-align:left;cursor:pointer;transition:border-color .12s,background-color .12s}
1867
+ .dsh-super-code-select-trigger>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1868
+ .dsh-super-code-select-trigger>svg{flex:none;width:14px;height:14px;color:var(--sc-muted);transition:transform .12s}
1869
+ .dsh-super-code-select-trigger[aria-expanded=true]>svg{transform:rotate(180deg)}
1870
+ .dsh-super-code-select .dsh-super-code-select-trigger:hover{background:var(--sc-hover);border-color:color-mix(in srgb,var(--sc-text) 25%,var(--sc-line))}
1871
+ .dsh-super-code-select .dsh-super-code-select-trigger[aria-expanded=true]{border-color:var(--sc-accent)}
1872
+ .dsh-super-code-select .dsh-super-code-select-trigger:focus-visible{outline:2px solid var(--sc-accent);outline-offset:2px}
1873
+ .dsh-super-code-select-trigger:disabled{opacity:.45;cursor:default}
1874
+ .dsh-super-code-select-menu{position:fixed;z-index:1200;overflow:auto;overscroll-behavior:contain;padding:4px;border:1px solid var(--sc-line);border-radius:10px;background:var(--sc-bg);color:var(--sc-text);box-shadow:0 6px 20px #0002;font-size:12px;line-height:1.5;text-align:left}
1875
+ .dsh-super-code-select-option{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:32px;padding:6px 8px;border-radius:6px;cursor:pointer}
1876
+ .dsh-super-code-select-option>span{min-width:0;overflow-wrap:anywhere}
1877
+ .dsh-super-code-select-option>svg{flex:none;width:14px;height:14px;color:var(--sc-accent);visibility:hidden}
1878
+ .dsh-super-code-select-option[aria-selected=true]{font-weight:500}
1879
+ .dsh-super-code-select-option[aria-selected=true]>svg{visibility:visible}
1880
+ .dsh-super-code-select-option[data-active=true]{background:var(--sc-selected)}
1881
+
1882
+ /* Shared action-name bubble. Fixed outside the panel avoids graph transforms
1883
+ * and scroll clipping; dialog bubbles remain in the modal's top layer. */
1884
+ .dsh-super-code-tooltip{position:fixed;z-index:1400;max-width:min(260px,calc(100vw - 16px));padding:5px 8px;border-radius:6px;background:var(--sc-text);color:var(--sc-bg);box-shadow:0 2px 8px #0002;font-size:12px;line-height:1.5;font-weight:400;text-align:left;overflow-wrap:anywhere;pointer-events:none}
1885
+ .dsh-super-code-tooltip:after{content:"";position:absolute;left:var(--sc-tooltip-arrow-left);width:6px;height:6px;background:inherit;transform:translateX(-50%) rotate(45deg)}
1886
+ .dsh-super-code-tooltip[data-side=top]:after{bottom:-3px}
1343
1887
  `
1344
1888
  document.head.appendChild(style)
1345
1889
  return () => { style.remove() }