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/README.md +23 -2
- package/client/index.js +825 -281
- package/cordis.patch.yml +3 -0
- package/docs/Changelog.md +10 -0
- package/docs/Compatibility.md +72 -2
- package/docs/UsageGuide.md +37 -16
- package/docs/images/agent-tree-preview.png +0 -0
- package/docs/images/agent-tree.png +0 -0
- package/docs/images/preset-settings-preview.png +0 -0
- package/docs/images/preset-settings.png +0 -0
- package/lib/dsh/preset-declaration.d.ts +75 -0
- package/lib/dsh/preset-declaration.d.ts.map +1 -0
- package/lib/dsh/preset-declaration.js +313 -0
- package/lib/dsh/preset-declaration.js.map +1 -0
- package/lib/dsh/preset-installation.d.ts +18 -9
- package/lib/dsh/preset-installation.d.ts.map +1 -1
- package/lib/dsh/preset-installation.js +57 -7
- package/lib/dsh/preset-installation.js.map +1 -1
- package/lib/dsh/preset-version.d.ts +7 -0
- package/lib/dsh/preset-version.d.ts.map +1 -0
- package/lib/dsh/preset-version.js +36 -0
- package/lib/dsh/preset-version.js.map +1 -0
- package/lib/dsh/super-code.d.ts +2 -0
- package/lib/dsh/super-code.d.ts.map +1 -1
- package/lib/dsh/super-code.js +2 -0
- package/lib/dsh/super-code.js.map +1 -1
- package/package.json +3 -3
- package/presets/super-code/agent.cordis.yml +2 -0
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': '刷新状态',
|
|
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.
|
|
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.
|
|
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': '
|
|
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',
|
|
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.
|
|
80
|
-
'preset.installHint': 'Install
|
|
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.
|
|
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.
|
|
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('
|
|
380
|
-
React.createElement('
|
|
381
|
-
|
|
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(
|
|
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',
|
|
573
|
-
React.createElement('strong', null, text(t, 'tree.title')),
|
|
574
|
-
React.createElement('span', { className: 'dsh-super-code-tree-count' }, text(t, 'tree.
|
|
575
|
-
React.createElement('
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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' },
|
|
868
|
-
React.createElement('
|
|
869
|
-
|
|
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(
|
|
872
|
-
|
|
873
|
-
|
|
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(
|
|
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',
|
|
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
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
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')
|
|
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('
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
React.createElement('
|
|
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(
|
|
977
|
-
(snapshot.earlier || snapshot.truncated) && React.createElement(
|
|
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
|
-
|
|
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
|
|
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 ?? (
|
|
1053
|
-
const [busy, setBusy] = useState(true), [error, setError] = useState('')
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
React.createElement('span', { className: 'dsh-super-code-settings-
|
|
1102
|
-
|
|
1103
|
-
React.createElement('
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
React.createElement('
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
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('
|
|
1116
|
-
React.createElement('
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
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('
|
|
1124
|
-
React.createElement('
|
|
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('
|
|
1135
|
-
|
|
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(
|
|
1140
|
-
React.createElement(
|
|
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
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
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
|
-
.
|
|
1183
|
-
.dsh-super-code-memory
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
.dsh-super-code-settings-
|
|
1202
|
-
.dsh-super-code-settings-
|
|
1203
|
-
.dsh-super-code-settings-
|
|
1204
|
-
|
|
1205
|
-
.dsh-super-code-settings-
|
|
1206
|
-
.dsh-super-code-settings
|
|
1207
|
-
.dsh-super-code-settings-
|
|
1208
|
-
.dsh-super-code-settings
|
|
1209
|
-
.dsh-super-code-
|
|
1210
|
-
.dsh-super-code-
|
|
1211
|
-
.dsh-super-code-
|
|
1212
|
-
.dsh-super-code-
|
|
1213
|
-
.dsh-super-code-
|
|
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
|
-
.
|
|
1216
|
-
.dsh-super-code-
|
|
1217
|
-
.dsh-super-code-
|
|
1218
|
-
.dsh-super-code-
|
|
1219
|
-
.dsh-super-code-
|
|
1220
|
-
.dsh-super-code-
|
|
1221
|
-
.dsh-super-code-
|
|
1222
|
-
.dsh-super-code-
|
|
1223
|
-
.dsh-super-code-
|
|
1224
|
-
.dsh-super-code-
|
|
1225
|
-
.dsh-super-code-
|
|
1226
|
-
.dsh-super-code-
|
|
1227
|
-
.dsh-super-code-
|
|
1228
|
-
.dsh-super-code-
|
|
1229
|
-
.dsh-super-code-
|
|
1230
|
-
.dsh-super-code-
|
|
1231
|
-
.dsh-super-code-
|
|
1232
|
-
.dsh-super-code-
|
|
1233
|
-
.dsh-super-code-
|
|
1234
|
-
.dsh-super-code-
|
|
1235
|
-
.dsh-super-code-
|
|
1236
|
-
.dsh-super-code-
|
|
1237
|
-
.dsh-super-code-
|
|
1238
|
-
.dsh-super-code-
|
|
1239
|
-
.dsh-super-code-
|
|
1240
|
-
.dsh-super-code-
|
|
1241
|
-
.dsh-super-code-
|
|
1242
|
-
.dsh-super-code-
|
|
1243
|
-
.dsh-super-code-
|
|
1244
|
-
.dsh-super-code-
|
|
1245
|
-
.dsh-super-code-
|
|
1246
|
-
.dsh-super-code-
|
|
1247
|
-
.dsh-super-code-
|
|
1248
|
-
.dsh-super-code-
|
|
1249
|
-
.dsh-super-code-
|
|
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-
|
|
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(--
|
|
1254
|
-
.dsh-super-code-graph-node{position:absolute;
|
|
1255
|
-
.dsh-super-code-
|
|
1256
|
-
.dsh-super-code-
|
|
1257
|
-
.dsh-super-code-graph-node
|
|
1258
|
-
.dsh-super-code-graph-node
|
|
1259
|
-
.dsh-super-code-graph-node
|
|
1260
|
-
.dsh-super-code-graph-node
|
|
1261
|
-
.dsh-super-code-graph-node
|
|
1262
|
-
.dsh-super-code-graph-node
|
|
1263
|
-
.dsh-super-code-graph-node
|
|
1264
|
-
.dsh-super-code-graph-node
|
|
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-
|
|
1268
|
-
.dsh-super-code-
|
|
1269
|
-
.dsh-super-code-
|
|
1270
|
-
.dsh-super-code-
|
|
1271
|
-
.dsh-super-code-
|
|
1272
|
-
.dsh-super-code-
|
|
1273
|
-
.dsh-super-code-
|
|
1274
|
-
.dsh-super-code-
|
|
1275
|
-
.dsh-super-code-
|
|
1276
|
-
.dsh-super-code-
|
|
1277
|
-
.dsh-super-code-
|
|
1278
|
-
.dsh-super-code-tree-
|
|
1279
|
-
.dsh-super-code-tree-
|
|
1280
|
-
.dsh-super-code-
|
|
1281
|
-
.dsh-super-code-
|
|
1282
|
-
.dsh-super-code-
|
|
1283
|
-
.dsh-super-code-
|
|
1284
|
-
.dsh-super-code-
|
|
1285
|
-
.dsh-super-code-
|
|
1286
|
-
.dsh-super-code-
|
|
1287
|
-
.dsh-super-code-
|
|
1288
|
-
.dsh-super-code-
|
|
1289
|
-
.dsh-super-code-
|
|
1290
|
-
.dsh-super-code-
|
|
1291
|
-
.dsh-super-code-
|
|
1292
|
-
|
|
1293
|
-
.
|
|
1294
|
-
.dsh-super-code-
|
|
1295
|
-
.dsh-super-code-
|
|
1296
|
-
.dsh-super-code-
|
|
1297
|
-
.dsh-super-code-
|
|
1298
|
-
.dsh-super-code-
|
|
1299
|
-
.dsh-super-code-
|
|
1300
|
-
|
|
1301
|
-
.dsh-super-code-
|
|
1302
|
-
.dsh-super-code-
|
|
1303
|
-
.dsh-super-code-
|
|
1304
|
-
.dsh-super-code-
|
|
1305
|
-
.dsh-super-code-
|
|
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
|
|
1317
|
-
.dsh-super-code-task-heading span{color:var(--
|
|
1318
|
-
.dsh-super-code-task-memory p{margin:
|
|
1319
|
-
.dsh-super-code-task-memory details{margin-top:8px;color:var(--
|
|
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:
|
|
1322
|
-
.dsh-super-code-
|
|
1323
|
-
.dsh-super-code-
|
|
1324
|
-
.dsh-super-code-
|
|
1325
|
-
.dsh-super-code-
|
|
1326
|
-
.dsh-super-code-
|
|
1327
|
-
.dsh-super-code-
|
|
1328
|
-
.dsh-super-code-
|
|
1329
|
-
.dsh-super-code-detail-
|
|
1330
|
-
.dsh-super-code-detail-
|
|
1331
|
-
.dsh-super-code-detail-
|
|
1332
|
-
.dsh-super-code-detail-
|
|
1333
|
-
.dsh-super-code-detail-
|
|
1334
|
-
.dsh-super-code-detail-
|
|
1335
|
-
.dsh-super-code-detail-
|
|
1336
|
-
.dsh-super-code-detail-
|
|
1337
|
-
.dsh-super-code-detail-
|
|
1338
|
-
.dsh-super-code-detail-
|
|
1339
|
-
.dsh-super-code-detail-
|
|
1340
|
-
.dsh-super-code-detail
|
|
1341
|
-
.dsh-super-code-detail-
|
|
1342
|
-
|
|
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() }
|