dsh-super-code 0.1.4 → 0.2.0
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 +43 -31
- package/client/index.js +253 -20
- package/docs/Changelog.md +38 -0
- package/docs/Compatibility.md +57 -0
- package/docs/EvaluationResults.md +66 -0
- package/docs/UsageGuide.md +110 -0
- 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/core/host-messages.d.ts +11 -0
- package/lib/core/host-messages.d.ts.map +1 -0
- package/lib/core/host-messages.js +13 -0
- package/lib/core/host-messages.js.map +1 -0
- package/lib/core/task-memory.d.ts +6 -0
- package/lib/core/task-memory.d.ts.map +1 -1
- package/lib/core/task-memory.js +13 -4
- package/lib/core/task-memory.js.map +1 -1
- package/lib/core/tool-evidence.d.ts.map +1 -1
- package/lib/core/tool-evidence.js +9 -9
- package/lib/core/tool-evidence.js.map +1 -1
- package/lib/dsh/index.d.ts +1 -1
- package/lib/dsh/index.d.ts.map +1 -1
- package/lib/dsh/index.js +23 -1
- package/lib/dsh/index.js.map +1 -1
- package/lib/dsh/memory-library.d.ts +45 -0
- package/lib/dsh/memory-library.d.ts.map +1 -0
- package/lib/dsh/memory-library.js +106 -0
- package/lib/dsh/memory-library.js.map +1 -0
- package/lib/dsh/preset-files.d.ts +26 -0
- package/lib/dsh/preset-files.d.ts.map +1 -0
- package/lib/dsh/preset-files.js +44 -0
- package/lib/dsh/preset-files.js.map +1 -0
- package/lib/dsh/preset-installation.d.ts +2 -2
- package/lib/dsh/preset-installation.d.ts.map +1 -1
- package/lib/dsh/preset-installation.js +5 -8
- package/lib/dsh/preset-installation.js.map +1 -1
- package/lib/dsh/preset-metadata.js +1 -1
- package/lib/dsh/preset-metadata.js.map +1 -1
- package/lib/dsh/super-code.d.ts.map +1 -1
- package/lib/dsh/super-code.js +159 -3
- package/lib/dsh/super-code.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/long-memory.d.ts +75 -0
- package/lib/long-memory.d.ts.map +1 -0
- package/lib/long-memory.js +126 -0
- package/lib/long-memory.js.map +1 -0
- package/lib/memory-usage-projection.d.ts +46 -0
- package/lib/memory-usage-projection.d.ts.map +1 -0
- package/lib/memory-usage-projection.js +111 -0
- package/lib/memory-usage-projection.js.map +1 -0
- package/lib/task-memory-projection.d.ts +7 -0
- package/lib/task-memory-projection.d.ts.map +1 -1
- package/lib/task-memory-projection.js +4 -2
- package/lib/task-memory-projection.js.map +1 -1
- package/lib/task-memory-store.js +1 -1
- package/lib/task-memory-store.js.map +1 -1
- package/package.json +26 -12
package/README.md
CHANGED
|
@@ -1,66 +1,78 @@
|
|
|
1
1
|
# dsh-super-code
|
|
2
2
|
|
|
3
|
-
一个更快、更节省、更聪明的 DeepSeek Harness
|
|
3
|
+
一个更快、更节省、更聪明的 DeepSeek Harness 编码插件。简单任务直接做,复杂任务按需组织专业 Agent;任务状态和有来源的经验可以留到后续对话,不必反复交代。
|
|
4
4
|
|
|
5
|
-
A faster, more efficient
|
|
5
|
+
A faster, more efficient coding plugin for DeepSeek Harness. It handles straightforward tasks directly, brings in specialist Agents when useful, and keeps sourced knowledge available for later conversations.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
在同一组 SWE-bench Pro hard-100 的校正结果中,0.2.0 分层记忆候选相比官方 minimal,平均回答耗时减少 **41%**、每题总 token 减少 **20%**,通过率从 **44% 提高到 52%**。[完整结果与限制](docs/EvaluationResults.md)
|
|
8
8
|
|
|
9
|
-
On the
|
|
9
|
+
On the same SWE-bench Pro hard-100 set, the corrected results for the 0.2.0 memory-hierarchy candidate show **41% less response time**, **20% fewer total tokens**, and a pass rate of **52% versus 44%** for official minimal. [Full results and limitations](docs/EvaluationResults.md)
|
|
10
|
+
|
|
11
|
+
## 0.2.0 候选 · What's New
|
|
12
|
+
|
|
13
|
+
- **分层记忆:** 区分本次任务、当前项目和全局偏好;只自动带入少量相关摘要,需要时再读详情。
|
|
14
|
+
**Layered memory:** Separates task state, project knowledge, and global preferences. Only a few relevant summaries enter context; details are read when needed.
|
|
15
|
+
- **记忆库:** 在右侧新标签查看和搜索记忆;Agent 详情中能看到带入上下文、读取、保存和删除记录。
|
|
16
|
+
**Memory library:** Browse and search memories in a sidebar tab, and see each Agent's recorded context, reads, saves, and removals in its details.
|
|
17
|
+
- **宿主兼容:** 保留旧版目录预设,并适配新版声明式预设及消息格式。具体版本和验收范围见[兼容矩阵](docs/Compatibility.md)。
|
|
18
|
+
**Host compatibility:** Keeps directory presets on older hosts and supports newer declarative presets and message formats. See the [verified versions and scope](docs/Compatibility.md).
|
|
19
|
+
|
|
20
|
+
0.2.0 当前为候选,尚未发布到 npm;发布前请使用候选安装包。效果数据来自已冻结的分层记忆实验,不是新增 UI 和兼容改动后的又一轮 100 题评测。
|
|
21
|
+
|
|
22
|
+
Version 0.2.0 is a candidate, not yet published to npm; use the candidate package before release. Its quality results belong to the frozen memory-hierarchy experiment, not a new 100-task run of the integrated UI and compatibility changes.
|
|
10
23
|
|
|
11
24
|
## 开始使用 · Get Started
|
|
12
25
|
|
|
13
|
-
需要
|
|
26
|
+
需要 Node.js 22 或更高版本,以及[已验证的 Harness 版本](docs/Compatibility.md)。
|
|
14
27
|
|
|
15
|
-
|
|
28
|
+
Use Node.js 22 or later and a [verified Harness version](docs/Compatibility.md).
|
|
16
29
|
|
|
17
|
-
1.
|
|
30
|
+
1. **安装:** 在插件市场搜索 `dsh-super-code`,或运行以下命令安装 npm 已发布版。
|
|
18
31
|
|
|
19
|
-
**Install
|
|
32
|
+
**Install:** Search for `dsh-super-code` in the plugin marketplace, or install the published npm version:
|
|
20
33
|
|
|
21
34
|
```bash
|
|
22
35
|
dsh plugin --profile web add dsh-super-code
|
|
23
36
|
```
|
|
24
37
|
|
|
25
|
-
|
|
38
|
+
候选包可用 `dsh plugin --profile web add ./dsh-super-code-0.2.0.tgz` 安装。
|
|
39
|
+
For the candidate, use `dsh plugin --profile web add ./dsh-super-code-0.2.0.tgz`.
|
|
26
40
|
|
|
27
|
-
|
|
41
|
+
2. **选中预设:** 打开“设置”→“Agent 预设”,选择 `super-code`。
|
|
28
42
|
|
|
29
|
-
|
|
43
|
+
**Select the preset:** Open “Settings” → “Agent Presets” and choose `super-code`.
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
3. **开始对话:** 新建会话,描述你要完成的编码任务。模型、推理等级、权限和工具沿用 Harness 的设置;子 Agent 默认继承父 Agent 的模型,不用另配模型池。
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
**Start a conversation:** Open a new session and describe the task. Models, reasoning effort, permissions, and tools come from Harness; child Agents inherit the parent's model by default.
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
没看到预设?在“设置”→ **Super Code** 查看状态;旧插件版本的入口在“插件配置”中。[安装与排查](docs/UsageGuide.md)
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
模型、推理等级、权限和工具沿用 Harness 的设置;子 Agent 默认继承父 Agent 的模型选择,不用再配置一套。
|
|
51
|
+
Can't find the preset? Open “Settings” → **Super Code**. Older plugin versions place this under “Plugin configuration”. [Setup and troubleshooting](docs/UsageGuide.md)
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
[](docs/images/preset-settings.png)
|
|
42
54
|
|
|
43
|
-
|
|
55
|
+
右侧执行树显示各 Agent 的状态、用量和缓存率。拖动平移、滚轮缩放;点节点查看详情,不切换主对话。右侧新标签页中的“记忆库”可以查看当前项目和全局偏好。[界面与记忆说明](docs/UsageGuide.md)
|
|
44
56
|
|
|
45
|
-
|
|
57
|
+
The Agent tree shows status, usage, and cache hit rate. Drag to pan, scroll to zoom, and click a node for details without leaving the main conversation. Open “Memory library” from the sidebar's new-tab page to view project knowledge and global preferences. [Interface and memory guide](docs/UsageGuide.md)
|
|
46
58
|
|
|
47
59
|
[](docs/images/agent-tree.png)
|
|
48
60
|
|
|
49
61
|
## 效果 · Results
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
同一组 100 题,均完成官方评分;评分环境异常已使用原补丁复核。时间不含官方评分,token 包含缓存输入,并不等于费用。
|
|
52
64
|
|
|
53
|
-
|
|
65
|
+
All four versions received official scores for the same 100 tasks. Grading anomalies were rechecked with the original patches. Time excludes grading; tokens include cache reads and are not a monetary cost estimate.
|
|
54
66
|
|
|
55
|
-
| 指标 / Metric |
|
|
56
|
-
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
67
|
+
| 指标 / Metric | 官方 minimal | 0.0.9 | 0.1.2 | 0.2.0 分层记忆 |
|
|
68
|
+
|---|---:|---:|---:|---:|
|
|
69
|
+
| 通过 / Passed | 44/100 | 48/100 | 52/100 | **52/100** |
|
|
70
|
+
| 平均耗时 / Minutes per task | 25.69 | 16.46 | 16.01 | **15.15** |
|
|
71
|
+
| 平均总 token / Tokens per task | 11,578,047 | 9,623,217 | 9,938,176 | **9,299,094** |
|
|
72
|
+
| 模型调用/题 / Model calls | 124.85 | 92.78 | 99.78 | 93.83 |
|
|
61
73
|
|
|
62
|
-
|
|
74
|
+
0.2.0 与 0.1.2 通过数相同,但有 6 题改善、6 题回退,不代表每道题都更好。这是已用于诊断的历史题集,各轮宿主版本也不同,不能把全部差异归因于插件或记忆功能。[多维指标、逐题证据与统计口径](docs/EvaluationResults.md)
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
Version 0.2.0 ties 0.1.2 overall, with six gains and six regressions—not an improvement on every task. This is a historically exposed diagnostic set, and host revisions differ between runs; the results do not isolate the effect of the plugin or memory alone. [Detailed metrics, per-task evidence, and methodology](docs/EvaluationResults.md)
|
|
65
77
|
|
|
66
|
-
[使用说明 · Usage
|
|
78
|
+
[使用说明 · Usage](docs/UsageGuide.md) · [兼容性 · Compatibility](docs/Compatibility.md) · [版本记录 · Changelog](docs/Changelog.md)
|
package/client/index.js
CHANGED
|
@@ -9,11 +9,24 @@
|
|
|
9
9
|
;(globalThis.window || globalThis).__ModuleLoader__.load({ id: 'dsh-super-code', factory: (require) => {
|
|
10
10
|
const React = require('react')
|
|
11
11
|
const { useEffect, useLayoutEffect, useRef, useMemo, useState, useSyncExternalStore } = React
|
|
12
|
-
const
|
|
12
|
+
const icons = require('@deepseek-ai/dsh-client-ui-primitives')
|
|
13
|
+
// Harness 0.2 names shared artwork by weight instead of its nominal size.
|
|
14
|
+
const IconChevronDownOutline14 = icons.IconChevronDownOutlineRegular ?? icons.IconChevronDownOutline14
|
|
15
|
+
const IconRefreshOutline16 = icons.IconRefreshOutlineRegular ?? icons.IconRefreshOutline16
|
|
13
16
|
const { SessionEventStream } = require('@deepseek-ai/dsh-api-session-controller')
|
|
14
17
|
|
|
15
18
|
const LOCALE_NS = 'dshSuperCode'
|
|
16
19
|
const zh = {
|
|
20
|
+
'memory.title': '记忆库', 'memory.project': '当前项目', 'memory.global': '全局偏好', 'memory.search': '搜索主题或记忆',
|
|
21
|
+
'memory.description': '跨对话保留的经验与偏好。按需读取,不会整库塞进上下文。',
|
|
22
|
+
'memory.empty': '还没有保存的记忆。需要长期保留时,直接告诉 Agent 即可。', 'memory.noMatches': '没有匹配的记忆',
|
|
23
|
+
'memory.selectSession': '先打开一个对话,查看它所在项目的记忆。', 'memory.error': '暂时无法读取记忆,请刷新重试。',
|
|
24
|
+
'memory.refresh': '刷新记忆库', 'memory.count': '{count} 条记忆', 'memory.back': '返回列表', 'memory.missing': '这条记忆已删除或更新,请刷新列表。',
|
|
25
|
+
'memory.historical': '历史记录,不代表当前代码仍然如此;以本次需求和实际验证为准。',
|
|
26
|
+
'memory.constraint': '用户约定', 'memory.fact': '项目事实', 'memory.experience': '实践经验', 'memory.source': '来源', 'memory.version': '记录时版本',
|
|
27
|
+
'memory.user': '用户消息', 'memory.tool': '工具结果', 'memory.agentUsage': '记忆使用记录', 'memory.usageHint': '只展示已记录的上下文与工具动作,不代表模型已理解或遵守。',
|
|
28
|
+
'memory.usageEmpty': '尚无记忆读取记录', 'memory.context': '带入上下文', 'memory.read': '读取详情', 'memory.summary': '读取摘要',
|
|
29
|
+
'memory.remember': '保存', 'memory.forget': '删除', 'memory.omitted': '仅展示最近 100 条不同动作,完整记录保留在会话中。', 'memory.open': '查看记忆库',
|
|
17
30
|
'preset.title': 'Super Code 模式', 'usage.cacheUnknown': '缓存 —',
|
|
18
31
|
'preset.description': '更快、更省、更聪明的编码模式。', 'preset.refresh': '刷新状态', 'preset.expand': '展开设置', 'preset.collapse': '收起设置',
|
|
19
32
|
'preset.state.available': '预设可用', 'preset.state.installed': '用户预设已安装', 'preset.state.conflict': '已有同名预设',
|
|
@@ -49,6 +62,16 @@ const zh = {
|
|
|
49
62
|
'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': '[图片]'
|
|
50
63
|
}
|
|
51
64
|
const en = {
|
|
65
|
+
'memory.title': 'Memory library', 'memory.project': 'This project', 'memory.global': 'Global preferences', 'memory.search': 'Search topics or memories',
|
|
66
|
+
'memory.description': 'Experience and preferences kept across conversations. Details are read on demand, never injected in bulk.',
|
|
67
|
+
'memory.empty': 'No saved memories yet. Tell the agent when something is worth keeping.', 'memory.noMatches': 'No matching memories',
|
|
68
|
+
'memory.selectSession': 'Open a conversation to view memory for its project.', 'memory.error': 'Memory is unavailable. Refresh to try again.',
|
|
69
|
+
'memory.refresh': 'Refresh memory', 'memory.count': '{count} memories', 'memory.back': 'Back to list', 'memory.missing': 'This memory was removed or changed. Refresh the list.',
|
|
70
|
+
'memory.historical': 'A historical record, not proof of the current code. Follow the current request and verify changing facts.',
|
|
71
|
+
'memory.constraint': 'User agreement', 'memory.fact': 'Project fact', 'memory.experience': 'Experience', 'memory.source': 'Source', 'memory.version': 'Recorded version',
|
|
72
|
+
'memory.user': 'User message', 'memory.tool': 'Tool result', 'memory.agentUsage': 'Memory activity', 'memory.usageHint': 'Recorded context and tool actions only; not proof the model understood or followed them.',
|
|
73
|
+
'memory.usageEmpty': 'No memory reads recorded yet', 'memory.context': 'Added to context', 'memory.read': 'Read details', 'memory.summary': 'Read summary',
|
|
74
|
+
'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',
|
|
52
75
|
'preset.title': 'Super Code', 'usage.cacheUnknown': 'Cache —',
|
|
53
76
|
'preset.description': 'A faster, more efficient, smarter coding mode.', 'preset.refresh': 'Refresh status', 'preset.expand': 'Show settings', 'preset.collapse': 'Hide settings',
|
|
54
77
|
'preset.state.available': 'Preset available', 'preset.state.installed': 'User preset installed', 'preset.state.conflict': 'Preset name already exists',
|
|
@@ -80,6 +103,21 @@ function formatText(template, values = {}) { return template.replace(/\{(\w+)\}/
|
|
|
80
103
|
function text(t, key, values) { return formatText(t(key), values) }
|
|
81
104
|
function localeCode(t) { return text(t, 'status.active') === en['status.active'] ? 'en-US' : 'zh-CN' }
|
|
82
105
|
|
|
106
|
+
// The registry captures a fallback title when a tab opens. Title slots receive
|
|
107
|
+
// live locale updates, including for tabs whose bodies are not currently shown.
|
|
108
|
+
function LocalizedTabTitle({ titleKey, t }) { return t(titleKey) }
|
|
109
|
+
|
|
110
|
+
function agentTabTitle(state, address, t) {
|
|
111
|
+
const target = agentDetailTarget(address), id = target.childSessionId || target.sessionId
|
|
112
|
+
const node = buildAgentView(agentSessionState(state, id)).nodes.get(id)
|
|
113
|
+
return node?.title || node?.displayTitle || t('detail.title')
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function AgentDetailTitle({ useTabInfo, useSessions, t }) {
|
|
117
|
+
const { tab } = useTabInfo(), state = useSessions(value => value)
|
|
118
|
+
return agentTabTitle(state, tab.contentId, t)
|
|
119
|
+
}
|
|
120
|
+
|
|
83
121
|
function TaskMemoryPanel({ state, t = key => zh[key] || key }) {
|
|
84
122
|
const tasks = state?.tasks || []
|
|
85
123
|
if (!tasks.length) return null
|
|
@@ -98,6 +136,29 @@ function TaskMemoryPanel({ state, t = key => zh[key] || key }) {
|
|
|
98
136
|
)
|
|
99
137
|
}
|
|
100
138
|
|
|
139
|
+
/** Normalize the two published host catalog shapes, without opening Agents. */
|
|
140
|
+
function agentSessionState(state, sessionId, statuses) {
|
|
141
|
+
const current = sessionId || state.current
|
|
142
|
+
if (state.subagentsByParent) return { ...state, current }
|
|
143
|
+
const snapshots = state.projectionsBySession || {}, byId = { ...state.byId }, catalogs = {}
|
|
144
|
+
for (const [id, snapshot] of Object.entries(snapshots)) {
|
|
145
|
+
byId[id] = { ...byId[id], id, projectionValues: snapshot.values,
|
|
146
|
+
running: statuses?.get(id)?.running ?? byId[id]?.running }
|
|
147
|
+
}
|
|
148
|
+
for (const [parentId, snapshot] of Object.entries(snapshots)) {
|
|
149
|
+
const entries = snapshot.values.subagentCatalog || []
|
|
150
|
+
catalogs[parentId] = { state: snapshot.state === 'idle' ? snapshot.values.subagentCatalog === undefined ? 'loading' : 'ready' : snapshot.state,
|
|
151
|
+
entries: entries.map(entry => {
|
|
152
|
+
const child = byId[entry.id], children = snapshots[entry.id]?.values.subagentCatalog
|
|
153
|
+
const running = statuses?.get(entry.id)?.running ?? child?.running
|
|
154
|
+
return { ...entry, hasChildren: children === undefined || children.length > 0,
|
|
155
|
+
kind: entry.mode === 'unknown' ? 'diagnostic' : 'child',
|
|
156
|
+
...(typeof running === 'boolean' ? { activity: running ? 'running' : 'inactive' } : {}) }
|
|
157
|
+
}) }
|
|
158
|
+
}
|
|
159
|
+
return { ...state, current, byId, subagentsByParent: catalogs }
|
|
160
|
+
}
|
|
161
|
+
|
|
101
162
|
/** Join host catalogs without leaking agents from unrelated conversations. */
|
|
102
163
|
function buildAgentView(state) {
|
|
103
164
|
const nodes = new Map(Object.values(state.byId || {}).map(node => [node.id, { ...node }]))
|
|
@@ -109,7 +170,7 @@ function buildAgentView(state) {
|
|
|
109
170
|
nodes.set(entry.id, { ...summary, id: entry.id, parentId,
|
|
110
171
|
title: entry.label || summary?.title || summary?.displayTitle || entry.id,
|
|
111
172
|
mode: entry.mode, hasChildren: entry.hasChildren, createdAt: created.get(entry.id),
|
|
112
|
-
running: summary?.running ?? entry.activity === 'running',
|
|
173
|
+
running: summary?.running ?? (entry.activity === undefined ? undefined : entry.activity === 'running'),
|
|
113
174
|
unavailable: entry.kind === 'diagnostic',
|
|
114
175
|
})
|
|
115
176
|
}
|
|
@@ -344,8 +405,10 @@ function AgentHistory({ view, hidden, totals, open, t = key => zh[key] || key })
|
|
|
344
405
|
!records.length && React.createElement('p', { className: 'dsh-super-code-history-empty' }, text(t, 'history.empty'))))
|
|
345
406
|
}
|
|
346
407
|
|
|
347
|
-
function AgentTree({ useSessions, useTabInfo, treeStates, openDetail, refresh, watchCatalog, t = key => zh[key] || key }) {
|
|
348
|
-
const
|
|
408
|
+
function AgentTree({ useSessions, useSessionStatus, sessionId, useTabInfo, treeStates, openDetail, refresh, watchCatalog, t = key => zh[key] || key }) {
|
|
409
|
+
const catalog = useSessions(s => s)
|
|
410
|
+
const statuses = useSessionStatus ? useSessionStatus(s => s) : undefined
|
|
411
|
+
const state = useMemo(() => agentSessionState(catalog, sessionId, statuses), [catalog, sessionId, statuses])
|
|
349
412
|
const { tab } = useTabInfo()
|
|
350
413
|
const view = useMemo(() => buildAgentView(state), [state.byId, state.subagentsByParent, state.current, state.currentAddress])
|
|
351
414
|
const saved = useMemo(() => {
|
|
@@ -710,9 +773,130 @@ function DetailText({ text: value, t = key => zh[key] || key }) {
|
|
|
710
773
|
!full && value.length > 12000 && React.createElement('button', { type: 'button', onClick: () => setFull(true) }, text(t, 'detail.open')))
|
|
711
774
|
}
|
|
712
775
|
|
|
713
|
-
function
|
|
776
|
+
function MemoryActivity({ usage, openMemory, sessionId, t }) {
|
|
777
|
+
const rows = [...(usage?.rows || [])].reverse()
|
|
778
|
+
return React.createElement('details', { className: 'dsh-super-code-memory-activity' },
|
|
779
|
+
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
|
+
!rows.length && React.createElement('p', null, text(t, 'memory.usageEmpty')),
|
|
782
|
+
React.createElement('div', { className: 'dsh-super-code-memory-activity-list' }, rows.map(row =>
|
|
783
|
+
React.createElement('button', { key: `${row.scope}/${row.topic}/${row.id}/${row.action}`, type: 'button',
|
|
784
|
+
onClick: () => openMemory(sessionId, row), title: text(t, 'memory.open') },
|
|
785
|
+
React.createElement('span', { className: 'dsh-super-code-memory-action', 'data-action': row.action }, text(t, `memory.${row.action}`)),
|
|
786
|
+
React.createElement('span', null, row.summary || row.id),
|
|
787
|
+
React.createElement('small', null, `${text(t, `memory.${row.scope}`)} · ${row.topic} · r${row.revision}`)))),
|
|
788
|
+
usage?.omitted > 0 && React.createElement('p', { className: 'dsh-super-code-memory-muted' }, text(t, 'memory.omitted')))
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
function memoryLibraryAddress(sessionId, row = {}) {
|
|
792
|
+
const url = new URL(`dsh-resource://super-code-memory/${encodeURIComponent(sessionId)}`)
|
|
793
|
+
for (const key of ['scope', 'topic', 'id']) if (row[key]) url.searchParams.set(key, row[key])
|
|
794
|
+
return url.href
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
function memoryLibraryTarget(address, current) {
|
|
798
|
+
try {
|
|
799
|
+
const url = new URL(address)
|
|
800
|
+
if (url.protocol === 'dsh-resource:' && url.host === 'super-code-memory') return {
|
|
801
|
+
sessionId: decodeURIComponent(url.pathname.slice(1)) || current, scope: url.searchParams.get('scope') === 'global' ? 'global' : 'project',
|
|
802
|
+
topic: url.searchParams.get('topic') || '', id: url.searchParams.get('id') || '',
|
|
803
|
+
}
|
|
804
|
+
} catch {}
|
|
805
|
+
return { sessionId: current, scope: 'project', topic: '', id: '' }
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/** A fixed-height index keeps large libraries cheap; entry bodies load on click. */
|
|
809
|
+
function memoryLibraryWindow(items, query, top, height) {
|
|
810
|
+
const search = query.trim().toLocaleLowerCase()
|
|
811
|
+
const matches = items.filter(item => !search || `${item.topic} ${item.id} ${item.summary}`.toLocaleLowerCase().includes(search))
|
|
812
|
+
const start = Math.min(Math.max(0, Math.floor(top / 76) - 3), Math.max(0, matches.length - 1))
|
|
813
|
+
const end = Math.min(matches.length, start + Math.ceil(height / 76) + 7)
|
|
814
|
+
return { rows: matches.slice(start, end), count: matches.length, before: start * 76, after: (matches.length - end) * 76 }
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
function MemoryLibrary({ useTabInfo, useSessions, sessionId: scopeSessionId, api, memoryStates, t = key => zh[key] || key }) {
|
|
818
|
+
const { tab } = useTabInfo(), current = useSessions(state => scopeSessionId || state.current)
|
|
819
|
+
const target = memoryLibraryTarget(tab.contentId, current)
|
|
820
|
+
const saved = useMemo(() => {
|
|
821
|
+
if (!memoryStates.has(tab.signal)) memoryStates.set(tab.signal, {})
|
|
822
|
+
return memoryStates.get(tab.signal)
|
|
823
|
+
}, [memoryStates, tab.signal])
|
|
824
|
+
const [scope, setScope] = useState(saved.scope || target.scope)
|
|
825
|
+
const [query, setQuery] = useState(saved.query || '')
|
|
826
|
+
const [selected, setSelected] = useState(saved.selected || (target.id ? { topic: target.topic, id: target.id } : null))
|
|
827
|
+
const [state, setState] = useState({ key: '', items: [], loading: true, error: false })
|
|
828
|
+
const [detail, setDetail] = useState(null), [revision, setRevision] = useState(0)
|
|
829
|
+
const [viewport, setViewport] = useState({ top: saved.top || 0, height: 600 })
|
|
830
|
+
const list = useRef(null), sessionId = target.sessionId
|
|
831
|
+
const key = `${sessionId}/${scope}`, selectionKey = selected ? `${key}/${selected.topic}/${selected.id}` : ''
|
|
832
|
+
const visibleState = state.key === key ? state : { items: [], loading: true, error: false }
|
|
833
|
+
useEffect(() => {
|
|
834
|
+
if (!tab.visible || !sessionId) return
|
|
835
|
+
let cancelled = false
|
|
836
|
+
setState(previous => ({ ...previous, loading: true, error: false }))
|
|
837
|
+
api.list(sessionId, scope).then(result => {
|
|
838
|
+
if (!cancelled) setState({ key, items: result.ok ? result.value.items : [], loading: false, error: !result.ok })
|
|
839
|
+
}).catch(() => { if (!cancelled) setState({ key, items: [], loading: false, error: true }) })
|
|
840
|
+
return () => { cancelled = true }
|
|
841
|
+
}, [api, tab.visible, sessionId, scope, revision])
|
|
842
|
+
useEffect(() => {
|
|
843
|
+
if (!tab.visible || !sessionId || !selected) return
|
|
844
|
+
let cancelled = false
|
|
845
|
+
setDetail(null)
|
|
846
|
+
api.read(sessionId, scope, selected.topic, selected.id).then(result => {
|
|
847
|
+
if (!cancelled) setDetail({ key: selectionKey, ...(result.ok ? result.value : { kind: 'error' }) })
|
|
848
|
+
}).catch(() => { if (!cancelled) setDetail({ key: selectionKey, kind: 'error' }) })
|
|
849
|
+
return () => { cancelled = true }
|
|
850
|
+
}, [api, tab.visible, sessionId, scope, selectionKey, revision])
|
|
851
|
+
useLayoutEffect(() => {
|
|
852
|
+
const element = list.current
|
|
853
|
+
if (!element) return
|
|
854
|
+
element.scrollTop = saved.top || 0
|
|
855
|
+
const resize = () => setViewport({ top: element.scrollTop, height: element.clientHeight || 600 })
|
|
856
|
+
resize()
|
|
857
|
+
const observer = new ResizeObserver(resize); observer.observe(element)
|
|
858
|
+
return () => observer.disconnect()
|
|
859
|
+
}, [selected, key, tab.visible])
|
|
860
|
+
const resetScroll = () => { saved.top = 0; if (list.current) list.current.scrollTop = 0; setViewport(value => ({ ...value, top: 0 })) }
|
|
861
|
+
const choose = value => { saved.selected = value; setSelected(value) }
|
|
862
|
+
const page = useMemo(() => memoryLibraryWindow(visibleState.items, query, viewport.top, viewport.height), [visibleState.items, query, viewport])
|
|
863
|
+
const currentDetail = detail?.key === selectionKey ? detail : null
|
|
864
|
+
const entry = currentDetail?.kind === 'found' ? currentDetail.entry : null
|
|
865
|
+
return React.createElement('section', { className: 'dsh-super-code-memory', 'aria-label': text(t, 'memory.title') },
|
|
866
|
+
React.createElement('header', null,
|
|
867
|
+
React.createElement('div', { className: 'dsh-super-code-memory-heading' }, React.createElement('h2', null, text(t, 'memory.title')),
|
|
868
|
+
React.createElement('button', { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'memory.refresh'), 'aria-label': text(t, 'memory.refresh'), onClick: () => setRevision(value => value + 1) }, React.createElement(IconRefreshOutline16))),
|
|
869
|
+
React.createElement('p', { className: 'dsh-super-code-memory-muted' }, text(t, 'memory.description')),
|
|
870
|
+
React.createElement('div', { className: 'dsh-super-code-memory-scopes', role: 'group', 'aria-label': text(t, 'memory.title') },
|
|
871
|
+
['project', 'global'].map(value => React.createElement('button', { key: value, type: 'button', 'aria-pressed': scope === value, onClick: () => { saved.scope = value; setScope(value); choose(null); resetScroll() } }, text(t, `memory.${value}`)))),
|
|
872
|
+
!selected && React.createElement('input', { type: 'search', 'aria-label': text(t, 'memory.search'), placeholder: text(t, 'memory.search'), value: query, onChange: event => { saved.query = event.target.value; setQuery(event.target.value); resetScroll() } }),
|
|
873
|
+
!selected && React.createElement('small', null, text(t, 'memory.count', { count: page.count }))),
|
|
874
|
+
!sessionId ? React.createElement('p', { className: 'dsh-super-code-memory-empty' }, text(t, 'memory.selectSession')) : selected
|
|
875
|
+
? React.createElement('div', { className: 'dsh-super-code-memory-body', 'aria-busy': !currentDetail },
|
|
876
|
+
React.createElement('button', { type: 'button', className: 'dsh-super-code-view-button', onClick: () => choose(null) }, `← ${text(t, 'memory.back')}`),
|
|
877
|
+
currentDetail?.kind === 'error' && React.createElement('p', { role: 'alert' }, text(t, 'memory.error')),
|
|
878
|
+
currentDetail?.kind === 'missing' && React.createElement('p', null, text(t, 'memory.missing')),
|
|
879
|
+
entry && React.createElement('article', null, React.createElement('small', null, `${entry.topic} · r${entry.revision} · ${text(t, `memory.${entry.kind}`)}`),
|
|
880
|
+
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
|
+
React.createElement('dl', null, React.createElement('dt', null, text(t, 'memory.source')),
|
|
883
|
+
React.createElement('dd', null, `${text(t, `memory.${entry.source.kind}`)} · #${entry.source.eventSeq}`, React.createElement('br'), entry.source.sessionId),
|
|
884
|
+
entry.sourceVersion && React.createElement(React.Fragment, null, React.createElement('dt', null, text(t, 'memory.version')), React.createElement('dd', null, entry.sourceVersion)))))
|
|
885
|
+
: React.createElement('div', { ref: list, className: 'dsh-super-code-memory-list', role: 'list', 'aria-busy': visibleState.loading, onScroll: event => { saved.top = event.currentTarget.scrollTop; setViewport(value => ({ ...value, top: saved.top })) } },
|
|
886
|
+
visibleState.error && React.createElement('p', { role: 'alert' }, text(t, 'memory.error')),
|
|
887
|
+
!visibleState.error && !visibleState.loading && !page.count && React.createElement('p', { className: 'dsh-super-code-memory-empty' }, text(t, query ? 'memory.noMatches' : 'memory.empty')),
|
|
888
|
+
React.createElement('div', { 'aria-hidden': true, style: { height: page.before } }),
|
|
889
|
+
page.rows.map(item => React.createElement('div', { role: 'listitem', key: `${item.topic}/${item.id}` },
|
|
890
|
+
React.createElement('button', { type: 'button', className: 'dsh-super-code-memory-row', onClick: () => choose({ topic: item.topic, id: item.id }) },
|
|
891
|
+
React.createElement('strong', null, item.summary), React.createElement('span', null, `${item.topic} · ${text(t, `memory.${item.kind}`)}`)))),
|
|
892
|
+
React.createElement('div', { 'aria-hidden': true, style: { height: page.after } })))
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function AgentDetail({ useTabInfo, useSessions, useSessionStatus, sessionId, createInspector, detailStates, openMemory, t = key => zh[key] || key }) {
|
|
714
896
|
const { tab } = useTabInfo()
|
|
715
|
-
const
|
|
897
|
+
const catalog = useSessions(s => s)
|
|
898
|
+
const statuses = useSessionStatus ? useSessionStatus(s => s) : undefined
|
|
899
|
+
const state = useMemo(() => agentSessionState(catalog, sessionId, statuses), [catalog, sessionId, statuses])
|
|
716
900
|
const saved = useMemo(() => {
|
|
717
901
|
if (!detailStates.has(tab.signal)) detailStates.set(tab.signal, { top: 0, following: true, open: new Set(), snapshot: undefined })
|
|
718
902
|
return detailStates.get(tab.signal)
|
|
@@ -753,7 +937,7 @@ function AgentDetail({ useTabInfo, useSessions, createInspector, detailStates, t
|
|
|
753
937
|
const target = agentDetailTarget(tab.contentId), id = target.childSessionId || target.sessionId
|
|
754
938
|
const view = buildAgentView(state), node = view.nodes.get(id)
|
|
755
939
|
const path = agentPath(view, id)
|
|
756
|
-
const projections = state.byId[id]?.projectionValues
|
|
940
|
+
const projections = { ...snapshot.projections, ...state.byId[id]?.projectionValues }
|
|
757
941
|
const totals = projections.superAgentUsage?.totals || projections.tokenUsage
|
|
758
942
|
const input = totals ? (totals.uncachedInputTokens || 0) + (totals.cacheReadTokens || 0) + (totals.cacheWriteTokens || 0) : 0
|
|
759
943
|
const format = value => value === undefined ? text(t, 'detail.unavailable') : value.toLocaleString(localeCode(t))
|
|
@@ -774,6 +958,7 @@ function AgentDetail({ useTabInfo, useSessions, createInspector, detailStates, t
|
|
|
774
958
|
React.createElement('button', { type: 'button', className: 'dsh-super-code-icon-button', title: text(t, 'detail.refresh'), 'aria-label': text(t, 'detail.refresh'), onClick: latest }, React.createElement(IconRefreshOutline16))),
|
|
775
959
|
id !== view.root && task?.goal && task.goal !== title && React.createElement('p', { className: 'dsh-super-code-detail-task' }, task.goal),
|
|
776
960
|
id === view.root && React.createElement(TaskMemoryPanel, { state: tasks, t }),
|
|
961
|
+
React.createElement(MemoryActivity, { usage: projections.superCodeMemoryUsage, sessionId: id, openMemory, t }),
|
|
777
962
|
React.createElement('dl', { className: 'dsh-super-code-detail-metrics' },
|
|
778
963
|
React.createElement('div', null, React.createElement('dt', null, text(t, 'detail.total')), React.createElement('dd', null, format(totals ? input + (totals.outputTokens || 0) : undefined))),
|
|
779
964
|
React.createElement('div', null, React.createElement('dt', null, text(t, 'detail.hitRate')), React.createElement('dd', null, totals ? (input ? Math.round((totals.cacheReadTokens || 0) / input * 100) : 0) + '%' : text(t, 'detail.unavailable')))),
|
|
@@ -808,12 +993,13 @@ function AgentDetail({ useTabInfo, useSessions, createInspector, detailStates, t
|
|
|
808
993
|
}
|
|
809
994
|
|
|
810
995
|
// Explicit public Remote contribution; no model tools or private transport hooks.
|
|
811
|
-
const
|
|
996
|
+
const remoteStringSchema = {
|
|
812
997
|
parse(value) {
|
|
813
998
|
if (typeof value !== 'string') throw new TypeError('Expected a string')
|
|
814
999
|
return value
|
|
815
1000
|
},
|
|
816
|
-
}
|
|
1001
|
+
}
|
|
1002
|
+
const remoteStringCodec = { mode: 'strict', typeSymbol: 'string', schema: remoteStringSchema, create: () => remoteStringSchema }
|
|
817
1003
|
const presetRemoteContribution = {
|
|
818
1004
|
package: 'dsh-super-code',
|
|
819
1005
|
descriptors: ['status', 'installPreset', 'reinstallPreset', 'synchronize'].map(method => ({
|
|
@@ -825,6 +1011,12 @@ const presetRemoteContribution = {
|
|
|
825
1011
|
result: { mode: 'src-json' },
|
|
826
1012
|
})),
|
|
827
1013
|
}
|
|
1014
|
+
const memoryRemoteContribution = {
|
|
1015
|
+
package: 'dsh-super-code', descriptors: ['list', 'read'].map(method => ({
|
|
1016
|
+
id: `dsh-super-code:superCodeMemory/${method}`, service: 'superCodeMemory', namespace: 'superCodeMemory', method, invocation: { kind: 'direct' },
|
|
1017
|
+
parameters: (method === 'list' ? ['sessionId', 'scope'] : ['sessionId', 'scope', 'topic', 'id']).map(name => ({ name, wire: name, source: 'json', codec: remoteStringCodec })), result: { mode: 'src-json' },
|
|
1018
|
+
})),
|
|
1019
|
+
}
|
|
828
1020
|
|
|
829
1021
|
// Old hosts render file metadata. Synchronize through our own Remote, then
|
|
830
1022
|
// reload their cached roster only when a managed field actually changed.
|
|
@@ -903,7 +1095,7 @@ function PresetSettings({ api, t }) {
|
|
|
903
1095
|
} else run(true)
|
|
904
1096
|
}
|
|
905
1097
|
const available = status && ['available', 'installed'].includes(status.state)
|
|
906
|
-
return React.createElement('
|
|
1098
|
+
return React.createElement('section', { className: `dsh-super-code-settings${open ? ' dsh-super-code-settings-open' : ''}` },
|
|
907
1099
|
React.createElement('button', { type: 'button', className: 'dsh-super-code-settings-header', 'aria-expanded': open,
|
|
908
1100
|
'aria-label': `${t(open ? 'preset.collapse' : 'preset.expand')}: ${t('preset.title')}`, onClick: () => setOpen(!open) },
|
|
909
1101
|
React.createElement('span', { className: 'dsh-super-code-settings-head-text' },
|
|
@@ -965,12 +1157,21 @@ function apply(ctx) {
|
|
|
965
1157
|
const t = locale.bind(LOCALE_NS)
|
|
966
1158
|
// $mount creates a lifecycle effect on this same fiber; awaiting it from
|
|
967
1159
|
// another effect would stall the namespace and the settings contribution.
|
|
968
|
-
void ctx.remote.$mount(
|
|
1160
|
+
void ctx.remote.$mount({ package: 'dsh-super-code', descriptors: [
|
|
1161
|
+
...presetRemoteContribution.descriptors, ...memoryRemoteContribution.descriptors,
|
|
1162
|
+
] }).catch(error => console.warn('Super Code Remote:', error))
|
|
1163
|
+
const memoryStates = new WeakMap()
|
|
1164
|
+
ctx.inject(['remote.superCodeMemory'], ready => {
|
|
1165
|
+
ready.slots.inject('sidebar.right.pane.tab', () => ready.slots.register({
|
|
1166
|
+
name: 'sidebar.right.pane.tab', key: 'dsh-super-code-memory', locale: LOCALE_NS,
|
|
1167
|
+
inject: () => ({ api: ready.remote.superCodeMemory, memoryStates }),
|
|
1168
|
+
}, MemoryLibrary))
|
|
1169
|
+
})
|
|
969
1170
|
ctx.inject(['remote.superCodePresets'], ready => {
|
|
970
1171
|
ready.effect(() => synchronizePresetDisplay(ready.remote.superCodePresets, locale,
|
|
971
1172
|
() => window.location.reload(), error => console.warn('Super Code preset display:', error)), 'super-code: preset display')
|
|
972
|
-
|
|
973
|
-
name: 'settings.
|
|
1173
|
+
ready.slots.inject('settings.section', () => ready.slots.register({
|
|
1174
|
+
name: 'settings.section', id: 'super-code', order: 120, label: () => t('preset.title'), locale: LOCALE_NS,
|
|
974
1175
|
inject: () => ({ api: ready.remote.superCodePresets }),
|
|
975
1176
|
}, PresetSettings))
|
|
976
1177
|
})
|
|
@@ -978,6 +1179,23 @@ function apply(ctx) {
|
|
|
978
1179
|
const style = document.createElement('style')
|
|
979
1180
|
style.dataset.dshSuperCode = 'true'
|
|
980
1181
|
style.textContent = `
|
|
1182
|
+
.dsh-super-code-memory{height:100%;min-height:0;display:flex;flex-direction:column;font-size:13px;--agent-muted:var(--dsw-alias-label-secondary,#70757d);--agent-line:var(--dsw-alias-border-l1,#dedfe3)}
|
|
1183
|
+
.dsh-super-code-memory>header{padding:18px 18px 12px;border-bottom:1px solid var(--agent-line)}
|
|
1184
|
+
.dsh-super-code-memory-heading{display:flex;align-items:center;justify-content:space-between;gap:12px}.dsh-super-code-memory h2{margin:0;font-size:16px;font-weight:600}
|
|
1185
|
+
.dsh-super-code-memory-muted{color:var(--agent-muted);font-size:12px;line-height:1.65;margin:10px 0}
|
|
1186
|
+
.dsh-super-code-memory-scopes{display:flex;gap:4px;padding:3px;margin:14px 0;border-radius:8px;background:color-mix(in srgb,currentColor 5%,transparent)}
|
|
1187
|
+
.dsh-super-code-memory-scopes button{flex:1;border:0;border-radius:6px;padding:7px;background:transparent;color:var(--agent-muted);font:inherit;cursor:pointer}
|
|
1188
|
+
.dsh-super-code-memory-scopes button[aria-pressed=true]{background:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-color-primary,#3276dc);box-shadow:0 1px 4px #0001}
|
|
1189
|
+
.dsh-super-code-memory input{width:100%;box-sizing:border-box;border:1px solid var(--agent-line);border-radius:7px;background:transparent;color:inherit;font:inherit;padding:9px 10px;margin-bottom:10px}
|
|
1190
|
+
.dsh-super-code-memory small{font-size:11px;color:var(--agent-muted);overflow-wrap:anywhere}
|
|
1191
|
+
.dsh-super-code-memory-list{flex:1;min-height:0;overflow:auto;padding:0 12px}.dsh-super-code-memory-row{display:flex;flex-direction:column;justify-content:center;gap:7px;width:100%;height:76px;box-sizing:border-box;border:0;border-bottom:1px solid var(--agent-line);background:transparent;text-align:left;color:inherit;padding:12px 8px;cursor:pointer;font:inherit}
|
|
1192
|
+
.dsh-super-code-memory-row:hover{background:color-mix(in srgb,var(--dsw-color-primary,#3276dc) 5%,transparent)}.dsh-super-code-memory-row strong,.dsh-super-code-memory-row span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsh-super-code-memory-row strong{font-weight:500}.dsh-super-code-memory-row span{font-size:11px;color:var(--agent-muted)}
|
|
1193
|
+
.dsh-super-code-memory-body{overflow:auto;flex:1;min-height:0;padding:14px 18px 28px}.dsh-super-code-memory-body article{padding-top:18px}.dsh-super-code-memory-body h3{font-size:15px;line-height:1.6;margin:8px 0 14px;overflow-wrap:anywhere}
|
|
1194
|
+
.dsh-super-code-memory-detail{white-space:pre-wrap;line-height:1.8;overflow-wrap:anywhere}.dsh-super-code-memory-hint{border-left:2px solid #b8ac82;padding:8px 12px;background:color-mix(in srgb,#b8ac82 8%,transparent);color:var(--agent-muted);font-size:12px;line-height:1.6;margin:22px 0}
|
|
1195
|
+
.dsh-super-code-memory-body dt{font-size:11px;color:var(--agent-muted);margin-top:18px}.dsh-super-code-memory-body dd{margin:6px 0;line-height:1.6;overflow-wrap:anywhere;font-size:12px}.dsh-super-code-memory-empty{padding:20px 6px;line-height:1.8;color:var(--agent-muted)}
|
|
1196
|
+
.dsh-super-code-memory-activity{margin-top:14px;font-size:12px}.dsh-super-code-memory-activity summary{cursor:pointer}.dsh-super-code-memory-activity-list{max-height:200px;overflow:auto}.dsh-super-code-memory-activity-list button{display:grid;grid-template-columns:auto 1fr;gap:5px 8px;width:100%;text-align:left;background:transparent;border:0;border-bottom:1px solid var(--agent-line);padding:10px 2px;color:inherit;font:inherit;cursor:pointer}.dsh-super-code-memory-activity-list small{grid-column:2;color:var(--agent-muted);overflow-wrap:anywhere}.dsh-super-code-memory-activity-list span{overflow-wrap:anywhere}
|
|
1197
|
+
.dsh-super-code-memory-action{font-size:10px;color:#4d779f}.dsh-super-code-memory-action[data-action=read]{color:#14867b}.dsh-super-code-memory-action[data-action=remember]{color:#927247}.dsh-super-code-memory-action[data-action=forget]{color:var(--agent-muted)}
|
|
1198
|
+
.dsh-super-code-memory button:focus-visible,.dsh-super-code-memory input:focus-visible{outline:2px solid var(--dsw-color-primary,#3276dc);outline-offset:2px}
|
|
981
1199
|
.dsh-super-code-settings{list-style:none;border:.5px solid var(--dsw-alias-border-l4,#dedfe3);border-radius:16px;background:var(--dsw-alias-bg-layer-3,transparent);line-height:1.6;font-size:13px;transition:border-color .16s,background .16s}
|
|
982
1200
|
.dsh-super-code-settings:hover{border-color:var(--dsw-alias-label-dimmed,#a8abb2)}.dsh-super-code-settings-open{background:var(--dsw-alias-bg-layer-2,transparent);border-color:var(--dsw-alias-label-dimmed,#a8abb2)}
|
|
983
1201
|
.dsh-super-code-settings-header{width:100%;appearance:none;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;gap:12px;padding:14px 16px;border-radius:12px}
|
|
@@ -1134,22 +1352,36 @@ function apply(ctx) {
|
|
|
1134
1352
|
title: () => t('tree.aria'),
|
|
1135
1353
|
guide: [{ order: 40, title: () => t('tree.aria'), description: () => t('tree.canvas') }],
|
|
1136
1354
|
})
|
|
1355
|
+
const disposeMemoryType = ctx.sidebarRightTabs.register({ id: 'dsh-super-code-memory', kind: 'super-code-memory',
|
|
1356
|
+
patterns: ['dsh-resource://super-code-memory/**'], title: () => t('memory.title'),
|
|
1357
|
+
guide: [{ order: 41, title: () => t('memory.title'), description: () => t('memory.description') }],
|
|
1358
|
+
})
|
|
1359
|
+
const openMemory = (sessionId, row) => ctx.sidebarRight.openResource(memoryLibraryAddress(sessionId, row), { kind: 'super-code-memory' })
|
|
1137
1360
|
const treeActions = {
|
|
1138
1361
|
// The host unmounts hidden bodies; tab signals live until close/unload.
|
|
1139
1362
|
treeStates: new WeakMap(),
|
|
1140
|
-
refresh: id => ctx.sessions.refreshSubagents(id),
|
|
1141
|
-
watchCatalog: (id, open) =>
|
|
1363
|
+
refresh: id => ctx.sessions.refreshSubagents ? ctx.sessions.refreshSubagents(id) : ctx.sessions.refreshProjections(id),
|
|
1364
|
+
watchCatalog: (id, open) => {
|
|
1365
|
+
if (ctx.sessions.setSubagentCatalogOpen) ctx.sessions.setSubagentCatalogOpen(id, open)
|
|
1366
|
+
else if (open) void ctx.sessions.refreshProjections(id).catch(error => console.warn('Super Code projections:', error))
|
|
1367
|
+
},
|
|
1142
1368
|
openDetail: child => ctx.sidebarRight.openResource(agentDetailAddress(child), { kind: 'super-agent-detail' }),
|
|
1143
1369
|
}
|
|
1144
1370
|
const disposeDetailType = ctx.sidebarRightTabs.register({
|
|
1145
1371
|
id: 'dsh-super-code-detail', kind: 'super-agent-detail', patterns: ['dsh-resource://super-agent/**'],
|
|
1146
1372
|
title: address => {
|
|
1147
|
-
|
|
1148
|
-
const node = buildAgentView(state).nodes.get(target.childSessionId || target.sessionId)
|
|
1149
|
-
return node?.title || node?.displayTitle || t('detail.title')
|
|
1373
|
+
return agentTabTitle(ctx.sessions.list.getSnapshot(), address, t)
|
|
1150
1374
|
},
|
|
1151
1375
|
})
|
|
1152
|
-
|
|
1376
|
+
ctx.slots.inject('sidebar.right.pane.tab.title', function* () {
|
|
1377
|
+
for (const [key, titleKey] of [[treeId, 'tree.aria'], ['dsh-super-code-memory', 'memory.title']]) {
|
|
1378
|
+
yield ctx.slots.register({ name: 'sidebar.right.pane.tab.title', key, locale: LOCALE_NS,
|
|
1379
|
+
inject: () => ({ titleKey }),
|
|
1380
|
+
}, LocalizedTabTitle)
|
|
1381
|
+
}
|
|
1382
|
+
yield ctx.slots.register({ name: 'sidebar.right.pane.tab.title', key: 'dsh-super-code-detail', locale: LOCALE_NS }, AgentDetailTitle)
|
|
1383
|
+
})
|
|
1384
|
+
const detailActions = { openMemory, detailStates: new WeakMap(), createInspector: (address, initial) => createAgentInspector(
|
|
1153
1385
|
(target, options) => new SessionEventStream(ctx.remote, target, options), address,
|
|
1154
1386
|
(request, signal) => ctx.remote.session.page(request, signal), initial, t) }
|
|
1155
1387
|
ctx.slots.inject('sidebar.right.pane.tab', () => ctx.slots.register({
|
|
@@ -1163,7 +1395,8 @@ function apply(ctx) {
|
|
|
1163
1395
|
}, AgentTree))
|
|
1164
1396
|
ctx.effect(() => disposeTreeType, 'super-code: Agent tree tab')
|
|
1165
1397
|
ctx.effect(() => disposeDetailType, 'super-code: Agent detail tab')
|
|
1398
|
+
ctx.effect(() => disposeMemoryType, 'super-code: memory library tab')
|
|
1166
1399
|
}
|
|
1167
1400
|
|
|
1168
|
-
return { inject, apply, synchronizePresetDisplay, buildAgentView, visibleAgentRows, agentTreeDisplay, agentTreeTotals, agentTreeLayout, agentExecutionStatus, agentDetailAddress, agentDetailTarget, agentPath, detailRecord, createAgentInspector, agentHistoryRange, agentHistoryRows, agentHistoryWindow }
|
|
1401
|
+
return { inject, apply, synchronizePresetDisplay, agentSessionState, buildAgentView, visibleAgentRows, agentTreeDisplay, agentTreeTotals, agentTreeLayout, agentExecutionStatus, agentDetailAddress, agentDetailTarget, agentPath, detailRecord, createAgentInspector, agentHistoryRange, agentHistoryRows, agentHistoryWindow, memoryLibraryAddress, memoryLibraryTarget, memoryLibraryWindow }
|
|
1169
1402
|
} })
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 版本记录 · Changelog
|
|
2
|
+
|
|
3
|
+
- **0.2.0 候选**:合入分层任务记忆,新增记忆库和每个 Agent 的记忆使用记录,tab 标题和界面文案跟随中英文切换,补齐 Harness 0.1.5-alpha.1 至 0.2.0-rc.2 的宿主兼容适配并完成官方 Desktop 原生窗口验收。
|
|
4
|
+
**0.2.0 candidate**: Integrates hierarchical task memory, adds the memory library and per-Agent memory activity, keeps tab titles and interface labels in sync with the Chinese/English language setting, and adapts the host boundary from Harness 0.1.5-alpha.1 through 0.2.0-rc.2, including checks in the official Desktop native window.
|
|
5
|
+
|
|
6
|
+
- **0.1.4**:适配 Harness 的目录与声明式预设机制:旧宿主保留目录安装,新宿主通过 bundle 声明 Super Code,设置页按宿主能力显示状态;声明式路径不提供目录副本安装、重命名、重装或名称语言同步。扩展 Harness peer 依赖范围,补齐中英文发布说明、使用指南及 npm 包内公开文档。`zod` 保留为运行时依赖,不内嵌其文件。
|
|
7
|
+
Adapts directory and declarative Harness presets: older hosts retain directory installation, while newer hosts use a Super Code bundle declaration and capability-specific status. The declarative path does not install, rename, reinstall, or synchronize localized names for directory copies. Expands Harness peer dependency ranges and includes bilingual release notes, usage guidance, and public documentation in the npm package. `zod` remains a runtime dependency without bundling its files.
|
|
8
|
+
已验证 `0.1.5-rc.3`、`0.1.6-alpha.1`、`0.1.6-alpha.2`、`0.1.7-alpha.1`、`0.1.7-alpha.2`、`0.1.7-rc.1`、`0.1.7-rc.2`;仅代表固定依赖的隔离 Web/CLI 与确定性模型冒烟,不代表原生 Desktop、外部模型、完整升级回归或新的 SWE-bench 成绩。[兼容范围与安装限制](Compatibility.md)
|
|
9
|
+
Verified `0.1.5-rc.3`, `0.1.6-alpha.1`, `0.1.6-alpha.2`, `0.1.7-alpha.1`, `0.1.7-alpha.2`, `0.1.7-rc.1`, and `0.1.7-rc.2` in pinned, isolated Web/CLI smoke checks using a deterministic model—not native Desktop, external models, complete upgrade regression, or new SWE-bench results. [Compatibility scope and installation limitations](Compatibility.md)
|
|
10
|
+
- **0.1.3**:插件配置和预设的默认名称、描述跟随中英文语言设置;升级仅更新未被用户修改的字段。安装名称支持中文和空格。已安装副本可在确认清单后按新名称与标识符重装,旧目录保留恢复备份,并严格校验副本归属。[使用说明](UsageGuide.md)
|
|
11
|
+
Plugin settings and default preset names and descriptions follow the Chinese/English interface language; upgrades update only untouched fields. Installation names support Chinese characters and spaces. Owned copies can be reinstalled with a new name and identifier after confirmation, while the old directory is retained as a recovery backup. [Usage guide](UsageGuide.md)
|
|
12
|
+
- **0.1.2**:优化按需专业指导、故障诊断与状态恢复验证,保留预设安装修复,最低支持 Harness 0.1.5-alpha.1。
|
|
13
|
+
Improves on-demand guidance, failure diagnosis, and state recovery checks; retains the preset installation fix and supports Harness 0.1.5-alpha.1 or later.
|
|
14
|
+
- **0.1.1**:修复部分宿主安装后预设不可见的问题,新增可折叠的安装状态与自定义名称安装入口,兼容 Harness 0.1.5-rc.1。
|
|
15
|
+
Fixes presets missing on some hosts after installation and adds a collapsible status panel with custom-name installation; supports Harness 0.1.5-rc.1.
|
|
16
|
+
- **0.1.0**:发布统一 Super Code 编码预设,提供多 Agent 执行树、任务记忆与用量展示。
|
|
17
|
+
Introduces the unified Super Code coding preset, with an Agent tree, task memory, and usage display.
|
|
18
|
+
- **0.0.9**:包名改为 `dsh-super-code`,使用 Harness 原生任务记忆和按需专业指导,简化旧工作流并完善执行树状态。
|
|
19
|
+
Renames the package to `dsh-super-code`, adopts Harness-native task memory and on-demand specialist guidance, simplifies earlier workflows, and improves Agent tree state.
|
|
20
|
+
|
|
21
|
+
更早版本以 `dsh-super-agent` 包名开发和发布;以下条目记录该项目的前身,不代表 `dsh-super-code` 曾以这些版本号发布。历史中没有 0.0.8 发布提交。
|
|
22
|
+
|
|
23
|
+
Earlier versions were developed and released as `dsh-super-agent`. The entries below describe that predecessor, not releases of the `dsh-super-code` package. The repository history has no 0.0.8 release commit.
|
|
24
|
+
|
|
25
|
+
- **0.0.7**:引入统一 Super Code 预设、Agent 执行图和精简任务上下文。
|
|
26
|
+
Introduces the unified Super Code preset, Agent graph, and compact task context.
|
|
27
|
+
- **0.0.6**:完成统一预设的初版集成,改进编程任务规划与模型选择;Harness 包改为 peer dependencies。
|
|
28
|
+
Integrates the first unified preset, improves programming planning and model selection, and declares Harness packages as peer dependencies.
|
|
29
|
+
- **0.0.5**:完成 Harness Web 适配、宿主界面集成和模型池路由,并让简单任务按需规划。
|
|
30
|
+
Completes Harness Web adaptation, host UI integration, and model-pool routing, with adaptive planning for straightforward tasks.
|
|
31
|
+
- **0.0.4**:加入有界多轮任务上下文、验证失败修复提示与评测聚合,限制停滞修复和历史内存增长。
|
|
32
|
+
Adds bounded multi-turn task context, verifier repair hints, and evaluation aggregation, while limiting stalled repairs and history growth.
|
|
33
|
+
- **0.0.3**:整理插件文档并采用 Apache-2.0 许可。
|
|
34
|
+
Refines plugin documentation and adopts the Apache-2.0 license.
|
|
35
|
+
- **0.0.2**:补齐类型化任务和指标协议,建立初版评测工具。
|
|
36
|
+
Adds typed task and metric protocols and an initial evaluation tool.
|
|
37
|
+
- **0.0.1**:提供场景预设及可安装的 DSH 插件包。
|
|
38
|
+
Provides scenario presets and an installable DSH plugin package.
|