dsh-prompt-customizer 0.9.2 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +49 -234
- package/README.md +45 -310
- package/build.mjs +27 -10
- package/client/client.js +2446 -1364
- package/client/client.js.map +4 -4
- package/docs/adr/0001-remove-catalog-pool.md +27 -0
- package/docs/adr/0002-hide-identity-name-source.md +23 -0
- package/docs/adr/0003-destructive-updates-allowed.md +18 -0
- package/docs/adr/0004-generalized-filter-model.md +17 -0
- package/docs/adr/0005-universal-prompt-takeover.md +109 -0
- package/docs/design/prompt-control-consensus.md +103 -0
- package/docs/guide.md +280 -0
- package/docs/images/prompt.png +0 -0
- package/docs/images/tool.png +0 -0
- package/docs/testing/feature-matrix.md +142 -0
- package/docs/upgrades/1.0.0-sqlite-breaking.md +26 -0
- package/docs/upgrades/1.4.0-generalized-model.md +23 -0
- package/docs/upgrades/1.4.1-web-preview-fixes.md +15 -0
- package/docs/upgrades/2.0.0-remove-workspace-level.md +16 -0
- package/docs/upgrades/2.0.1-context-fixes.md +6 -0
- package/docs/upgrades/2.0.10-import-and-skill.md +6 -0
- package/docs/upgrades/2.0.11-regression-fixes.md +7 -0
- package/docs/upgrades/2.0.12-generative-tool-tests.md +5 -0
- package/docs/upgrades/2.0.13-runtime-contract.md +8 -0
- package/docs/upgrades/2.0.14-tool-execution-guard.md +5 -0
- package/docs/upgrades/2.0.15-mask-pool-regression.md +5 -0
- package/docs/upgrades/2.0.16-regression-cleanup.md +6 -0
- package/docs/upgrades/2.0.17-unhide-source.md +5 -0
- package/docs/upgrades/2.0.18-unhide-cleanup.md +4 -0
- package/docs/upgrades/2.0.19-mcp-json-edit.md +4 -0
- package/docs/upgrades/2.0.2-generic-context-filter.md +6 -0
- package/docs/upgrades/2.0.20-preset-isolation.md +4 -0
- package/docs/upgrades/2.0.21-isolation-restore-test.md +4 -0
- package/docs/upgrades/2.0.22-source-immutability.md +3 -0
- package/docs/upgrades/2.0.3-skill-summary.md +6 -0
- package/docs/upgrades/2.0.4-tool-draft.md +5 -0
- package/docs/upgrades/2.0.5-tool-catalog-robustness.md +13 -0
- package/docs/upgrades/2.0.6-tool-restrict.md +6 -0
- package/docs/upgrades/2.0.7-tool-stability.md +5 -0
- package/docs/upgrades/2.0.8-catalog-row-stability.md +4 -0
- package/docs/upgrades/2.0.9-tool-and-write.md +8 -0
- package/docs/upgrades/2.1.0-universal-prompt-takeover.md +41 -0
- package/docs/upgrades/2.1.1-tool-shadow-detection.md +48 -0
- package/docs/upgrades/2.1.2-tool-catalog-scope.md +55 -0
- package/docs/upgrades/README.md +298 -0
- package/docs/upgrades/dsh-0.2.2-rc1.md +49 -0
- package/docs/upgrades/rc2-migration.md +70 -0
- package/lib/index.js +4697 -1701
- package/lib/index.js.map +4 -4
- package/package.json +7 -5
- package/scripts/e2e-report.json +221 -0
- package/scripts/e2e-terminal.mjs +210 -0
- package/scripts/simulate-rescan.mjs +184 -0
- package/scripts/smoke-host.mjs +1 -1
- package/scripts/verify-apply-all.mjs +64 -0
- package/scripts/verify-effect.mjs +153 -0
- package/scripts/verify-mcp-edit-ext.mjs +48 -0
- package/scripts/verify-mcp-edit.mjs +45 -0
- package/scripts/verify-panel-browser.mjs +298 -0
- package/scripts/verify-workspace-mcp.mjs +62 -0
- package/scripts/test-mcp-layering.mjs +0 -441
- package/scripts/test-mcp-tool-disable.mjs +0 -420
- package/scripts/test-rc2-runtime.mjs +0 -42
- package/scripts/test-skill-toggles.mjs +0 -100
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>DeepSeek Harness 的能力台:提示词定制 + 技能集合管理 + MCP Server 接入。<br>
|
|
9
|
-
|
|
9
|
+
在侧边栏的「能力」面板里完成提示词段管理、技能导入与开关、MCP 接入与分层遮蔽。</strong>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -15,19 +15,17 @@
|
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
18
|
+
<a href="#这是什么">这是什么</a> •
|
|
19
|
+
<a href="#核心能力">核心能力</a> •
|
|
18
20
|
<a href="#安装">安装</a> •
|
|
19
|
-
<a href="
|
|
20
|
-
<a href="
|
|
21
|
-
<a href="#工作原理">工作原理</a> •
|
|
22
|
-
<a href="#已知限制">已知限制</a>
|
|
21
|
+
<a href="#快速上手">快速上手</a> •
|
|
22
|
+
<a href="#文档">文档</a>
|
|
23
23
|
</p>
|
|
24
24
|
|
|
25
25
|
<p align="center">
|
|
26
|
-
<a href="https://github.com/DreamsTOF/dsh-prompt-customizer/releases"><img src="https://img.shields.io/
|
|
26
|
+
<a href="https://github.com/DreamsTOF/dsh-prompt-customizer/releases"><img src="https://img.shields.io/npm/v/dsh-prompt-customizer" alt="npm version"></a>
|
|
27
27
|
<a href="https://github.com/DreamsTOF/dsh-prompt-customizer/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT License"></a>
|
|
28
28
|
<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/DeepSeek_Harness-Plugin-blueviolet.svg" alt="DeepSeek Harness Plugin"></a>
|
|
29
|
-
<a href="https://www.npmjs.com/package/dsh-prompt-customizer"><img src="https://img.shields.io/npm/v/dsh-prompt-customizer" alt="npm version"></a>
|
|
30
|
-
<a href="https://www.npmjs.com/package/dsh-prompt-customizer"><img src="https://img.shields.io/npm/dm/dsh-prompt-customizer" alt="npm downloads"></a>
|
|
31
29
|
<a href="https://github.com/DreamsTOF/dsh-prompt-customizer/stargazers"><img src="https://img.shields.io/github/stars/DreamsTOF/dsh-prompt-customizer?style=social" alt="GitHub Stars"></a>
|
|
32
30
|
</p>
|
|
33
31
|
|
|
@@ -41,344 +39,89 @@
|
|
|
41
39
|
|
|
42
40
|
---
|
|
43
41
|
|
|
44
|
-
##
|
|
42
|
+
## 这是什么
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(dsh)插件。它在侧边栏提供一个独立的「能力」面板,把三件平时要改配置、翻源码才能完成的事集中到可视化界面:
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- 在线版:<https://dreamstof.github.io/dsh-prompt-customizer/>(站点源在 [`gh-pages`](https://github.com/DreamsTOF/dsh-prompt-customizer/tree/gh-pages) 分支)
|
|
53
|
-
- 本地版:克隆 `gh-pages` 单分支后在目录里起一个静态服务器,例如 `python -m http.server 8000`,再打开 `http://localhost:8000`
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (dsh) 插件,让你在侧边栏的独立面板里控制**系统提示词**和**工具目录**(仿宿主能力管理页:顶部 agent 预设 Tab、左栏勾选列表 + 底部三态过滤、右栏实时预览)。
|
|
58
|
-
|
|
59
|
-
其他插件注入的提示词段可能污染你的系统提示词。本插件让你按名称**屏蔽**、**替换**、**注入**、**排序**提示词段,并把工具从**模型可见目录**里隐藏 —— 全程实时生效,不需要改动任何其他插件。
|
|
60
|
-
|
|
61
|
-
两件事贯穿整个设计:
|
|
62
|
-
|
|
63
|
-
- **按会话阶段分层**:引导期(未晋级)/ 常驻期(晋级后)/ 压缩受控期(压缩后仍未晋级)各有**独立的屏蔽名单、独立的排序空间、独立的工具目录**。同一个预设可以做到首轮只给模型 1 个工具和几段提示词,晋级后放开全套。
|
|
64
|
-
- **按 agent 预设分层**:顶部预设 Tab 选中某个 agent 预设后,改动只对该预设生效;**0.9.0 起「全部 Agent」全局层停用**——提示词必须按具体预设修改,预设未定制的字段 = 官方默认(旧全局层数据保留在 config.yaml 里不再生效,可手编回滚)。
|
|
65
|
-
|
|
66
|
-
## 0.9.2:按模式预设修正 rc.2 适配
|
|
46
|
+
- **提示词定制**:按名字 + 来源屏蔽、替换、注入、排序系统提示词段;
|
|
47
|
+
- **技能集合管理**:导入、归组、开关技能;
|
|
48
|
+
- **MCP Server 接入**:添加 MCP Server,并按预设或工具粒度做遮蔽与启停。
|
|
67
49
|
|
|
68
|
-
|
|
69
|
-
- 顶部模式 Tab 决定提示词、工具和排序的编辑目标。同名提示词在不同模式下的正文分别来自各自作用域,不能拿另一个模式或旧会话替代。
|
|
70
|
-
- 预设预览中的 `{{model}}`、`{{cwd}}` 等未绑定变量保留为模板引用,并显示非致命说明;目录和草稿编辑不因此失败。真正对话中的严格插值行为不变。
|
|
71
|
-
- 独立展示 `contexts`(user-role 运行时快照、只读)。纯预设作用域无法得到依赖真实会话状态的贡献;这不允许把另一个对话的数据当成当前模式定义。
|
|
72
|
-
- 三阶段模拟本插件的独立规则;已有对话的模式绑定不被编辑目标切换改变。此预览不是完整历史 LLM 请求回放。
|
|
50
|
+
所有改动都通过插件自身的扩展点生效,不修改 DSH 源码;提示词与工具目录在保存后实时作用于模型。
|
|
73
51
|
|
|
74
|
-
|
|
52
|
+
## 核心能力
|
|
75
53
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
<table>
|
|
85
|
-
<tr align="center">
|
|
86
|
-
<td width="28%"><b>① 会话开始</b><br><code>bootstrap</code><br><b>引导期</b></td>
|
|
87
|
-
<td width="6%">→</td>
|
|
88
|
-
<td width="28%"><b>② 首个 durable 信号</b><br><code>tool/call</code> · <code>assistant/message</code><br><b>常驻期</b> <code>active</code></td>
|
|
89
|
-
<td width="6%">→</td>
|
|
90
|
-
<td width="32%"><b>③ 一次压缩</b><br><code>compaction/end</code><br><b>压缩受控期</b> <code>compaction</code></td>
|
|
91
|
-
</tr>
|
|
92
|
-
<tr>
|
|
93
|
-
<td colspan="5" align="center">
|
|
94
|
-
④ 压缩后再来一个 durable 信号 → <b>回到常驻期</b>;只要再来一次压缩,又会落回压缩受控期
|
|
95
|
-
</td>
|
|
96
|
-
</tr>
|
|
97
|
-
</table>
|
|
98
|
-
|
|
99
|
-
完整的转移关系(引导期也能不经常驻期直接进压缩受控期):
|
|
100
|
-
|
|
101
|
-
| 当前阶段 | 事件 | 去向 |
|
|
102
|
-
| ---------- | ---------------------------------------------- | -------------- |
|
|
103
|
-
| 引导期 | 首个 durable `tool/call` / `assistant/message` | **常驻期** |
|
|
104
|
-
| 引导期 | `compaction/end` | **压缩受控期** |
|
|
105
|
-
| 常驻期 | `compaction/end`(晋级复位) | **压缩受控期** |
|
|
106
|
-
| 压缩受控期 | 压缩之后新的 durable 信号 | **常驻期** |
|
|
107
|
-
| 任意 | 子代理会话(`delegationDepth > 0`) | 恒为**常驻期** |
|
|
108
|
-
| 任意 | 无会话的读取(清单、预览) | 恒为**常驻期** |
|
|
109
|
-
|
|
110
|
-
每个阶段各解析出什么 —— 面板的三个部分与配置字段一一对应:
|
|
111
|
-
|
|
112
|
-
| 面板里的部分 | 生效的段屏蔽 | 注入段的 `phase` | 生效的工具黑名单 |
|
|
113
|
-
| ------------------------- | -------------------- | -------------------------- | ---------------------------------------------------------- |
|
|
114
|
-
| 引导期提示词 / 引导期工具 | `sectionsBootstrap` | `bootstrap`(+ `always`) | `tools.bootstrap.exclude`,未配置则回落静态 |
|
|
115
|
-
| 常驻期提示词 / 常驻期工具 | `sections` | `active`(+ `always`) | `tools.exclude`(静态) |
|
|
116
|
-
| 压缩受控期提示词 / 工具 | `sectionsCompaction` | `compaction`(+ `always`) | `tools.compaction.exclude`,未配置则回落引导期,再回落静态 |
|
|
117
|
-
|
|
118
|
-
两点容易踩:
|
|
119
|
-
|
|
120
|
-
- **`always` 注入段三个阶段都在**,且各阶段的排序空间独立 —— 所以本插件产出的阶段条目排在 `always` 组之后(运行时按数组序后写覆盖前写,阶段序才压得住全局序)。
|
|
121
|
-
- **阶段视图是"这个状态会解析成什么",不是"会话曾经是什么"**。预设原生的阶段规则(zero-tool bootstrap、warmup 等)在同一时刻也在生效,并且可能在其它插件之后改动结果 —— 见[已知限制](#已知限制)。
|
|
54
|
+
- **提示词段管理**:屏蔽 / 替换 / 注入 / 拖动排序提示词段,右栏实时预览模型最终看到的系统提示词;**全域接管**:任何插件在任意作用域(含 `agent/created` 里动态注册的会话级段)注入的系统提示词段,都会出现在可编辑清单里并可被屏蔽 / 替换 / 排序。宿主侧另有 `/api/prompt-customizer/session` 只读路由,按最新活动根会话自己的 agent 作用域展示真实提示词与工具目录(面板本身不单独开「当前会话」Tab)。
|
|
55
|
+
- **阶段与预设分层**:引导期、常驻期、压缩受控期各有独立的段名单、排序空间与工具目录;顶部按 agent 预设切换编辑目标,某个预设的定制只对该预设生效。
|
|
56
|
+
- **单预设编辑(2.0.0)**:提示词 / 工具定制只按 **agent 预设** 保存与生效;工作区级提示词/工具层已移除(源码归档、数据休眠,不读不写不备份)。工作区概念仍用于 MCP / 技能 / cwd。
|
|
57
|
+
- **工具目录**:按阶段隐藏或加回工具,面板同时显示「模型可见 / 注册表总数」,PTC / Code Mode 的 `run_code` 包装也能正确对照。
|
|
58
|
+
- **工具提示词段**:工具页显示 `tool:*` 提示词段与工具组的关联(如 `tool:jobs` → `job_kill/job_list/job_output`),提示词页可独立屏蔽 / 替换 / 排序;工具 description 只读展示,JSON Schema 不纳入提示词编辑。
|
|
59
|
+
- **技能管理**:技能包归组、ZIP / 文件夹导入、全局 / 预设两层开关、技能根与成员一致性体检。
|
|
60
|
+
- **MCP 管理**:粘贴 JSON / YAML 接入、预设专属 Server 行、全局 / 预设双层遮蔽、工具级启停、推荐配置模板。
|
|
61
|
+
- **提示词变量**:内置日期、主机、环境等变量,支持 `process.env` 映射与密钥黑名单。
|
|
122
62
|
|
|
123
63
|
## 界面
|
|
124
64
|
|
|
125
|
-
侧边栏点 **能力**
|
|
126
|
-
|
|
127
|
-
下面两张图是**提示词 tab**(截图截于 0.6.0 之前:顶部预设行当时还是纯文字 Tab,功能一致;SKILL / MCP 两个 tab 的截图待补)。
|
|
128
|
-
|
|
129
|
-
以下为**提示词 tab** 的细节 —— 侧边栏点 **能力 → 提示词** 打开独立面板。**第一行是 agent 预设 chips**(0.9.0 起无「全部 Agent」),每枚带图标、名称与该预设的定制项数(橙色数字 = 这个预设单独改过东西),点一下即切换编辑目标,进入面板时默认选中第一个可用预设。**第二行是定制头部**:模式切换(提示词 / 工具 / 配置)+ 阶段 Tab(引导期 / 压缩受控期 / 常驻期,左右两栏联动)+ 三态同步与中文提示词开关 + 保存 / 刷新 / 关闭。
|
|
130
|
-
|
|
131
|
-
**提示词模式**:左栏当前阶段的勾选列表(屏蔽 / 替换 / 注入 / 排序,底部三态过滤),右栏实时预览装配后的最终系统提示词:
|
|
65
|
+
侧边栏点 **能力** 打开面板,顶部三个 tab:**SKILL**、**MCP**、**提示词**。
|
|
132
66
|
|
|
133
67
|

|
|
134
68
|
|
|
135
|
-
**工具模式**:左栏该阶段的工具目录勾选列表,「本系统全部工具」池可把注册表里仍有的工具加回该阶段;右栏是模型可见目录(含「模型可见 / 注册表总数」对照):
|
|
136
|
-
|
|
137
69
|

|
|
138
70
|
|
|
139
|
-
## 功能特性
|
|
140
|
-
|
|
141
|
-
### 技能集合管理(SKILL tab)
|
|
142
|
-
|
|
143
|
-
- **技能包**:把散装技能归组(账本 `.bundles.json` 记规范名与目录名两套写法,目录名不一致也能命中);包可以有分类(最多 8 个、每个 ≤24 字符),改名会同步 `SKILL.md` frontmatter 里的 `name`,删除按规范名走,成员悬空时如实上报。
|
|
144
|
-
- **导入**:拖入 / 选择 ZIP 或文件夹,自动剥掉顶层文件夹、落成 `<技能根>/<名称>/SKILL.md`,并立刻归组到目标技能包;重名给明确错误,不带路径分隔的名字一律拒绝(不越界读技能根外的文件)。
|
|
145
|
-
- **开关(全局 / 预设两层)**:单个技能与整个技能包都能开关,预设层写自己那份账(规范名条目),只对该 agent 预设生效 —— 与「全局」层互不覆盖。
|
|
146
|
-
- **技能健康**:`/api/skill-health` 给出技能根的可读性与成员一致性体检。
|
|
147
|
-
- **与内核分工**:会话里的 `/` 技能源与技能工具行由 DSH 内核的 `@deepseek-ai/dsh-client-ui-skill` 负责,本插件不重复注册(重复注册会让内核 apply 抛错并拖垮整条客户端插件加载链);本插件提供的是「能力」面板里的管理面(导入 / 归组 / 开关 / 体检)与它背后的宿主路由。
|
|
148
|
-
|
|
149
|
-
### MCP Server 接入(MCP tab)
|
|
150
|
-
|
|
151
|
-
- **一键接入**:粘贴 JSON / DSH 原生 YAML(`mcpServers` 形态)/ `mcp-client` 行片段,面板先给待写入预览,再写进预设组合或 profile patch —— **写前备份**,重名 server 跳过,非法 serverName / 非布尔 `enabled` 直接拒绝。
|
|
152
|
-
- **预设专属 Server 行**:直接在面板里新增 / 删除某个 agent 预设自带的 Server 行(写进该预设声明行的 `config.plugins`,经 DSH 的 `configEditor` 落盘 profile patch)。
|
|
153
|
-
- **分层遮蔽**:全局行 + 预设层两本账(预设层分「继承全局」与「自带」两侧,各记各的账);预设自带的同名 Server 优先于继承条目;全局关闭 = 一票否决,预设层不能反开(返回 409 并给出说明)。
|
|
154
|
-
- **工具级启停**:按最长匹配把工具归到所属 Server(`my` 与 `my_server` 各自成组),可整台 Server 关掉,也可只关其中几个工具;装配过滤、状态路由、原生目录三处同源。
|
|
155
|
-
- **推荐清单**:`/api/mcp-recommended` 给出常见 MCP Server 的配置模板,照抄即可接入。
|
|
156
|
-
|
|
157
|
-
### 提示词段
|
|
158
|
-
|
|
159
|
-
- **屏蔽**:按名称从装配结果里移除该段。被屏蔽的行不会消失,仍可编辑、恢复 —— 屏蔽只意味着不注入模型。
|
|
160
|
-
- **替换**:编辑该段文本,编辑框预填当前生效文本(动态段会尽力解析出真实内容再回显)。
|
|
161
|
-
- **注入**:每个阶段里「+ 注入」展开表单,按名称 + 文本新建一段,带 `手动` 徽标,随时可删除。
|
|
162
|
-
- **排序**:行首抓手拖动排序,或用行内 ↑/↓ 箭头逐格挪。顺序以 0 起始的连续虚拟下标存储,不会出现重复或小数 order,也不需要手填数字。
|
|
163
|
-
- **拖拽**:把「本系统全部提示词」池里的行拖进列表 = 加入当前阶段(带上池里原文);把行拖回池 = 从当前阶段移除(注入进来的撤销注入,原生段转为屏蔽);把行拖到头部某个**阶段按钮**上 = 复制到那个阶段。拖动中有插入位置提示(行上下的蓝色线),投放区高亮;列表比视口长时,把指针拖到列表上/下边缘会自动滚动(越靠边越快),所以池在折叠区里、目标行在视口外也照样能拖到。
|
|
164
|
-
- **每阶段独立**:引导期屏蔽写 `sectionsBootstrap`,压缩受控期写 `sectionsCompaction`,常驻期写 `sections`;三份名单互不继承、互不影响,排序空间也互不干扰,因此「引导期只留 5 段、常驻期全开」可以分别表达 —— 在一个阶段屏蔽 / 恢复某段,绝不会改变它在其它阶段的状态。从「本系统全部提示词」池把段**拖入**当前阶段即成为当前阶段的独立副本(带原文写入本阶段注入条目)—— 加入阶段只有拖拽这一条路径,池里的行不再挂按钮,界面因此干净一半。(勾选「三态同步」后三态共用同一份列表,见下。)
|
|
165
|
-
- **强制覆盖(`forceSections`,默认开)**:包装宿主的装配入口,最终提示词段直接从注册表原始段重建 —— 预设插件自身的阶段裁段(如 liangshen 引导期 20→1)与 persona 的 `complete: true` 整段接管都无法再改写本插件的屏蔽 / 替换 / 注入 / 排序结果;工具目录与动态上下文保持预设与宿主行为。设为 `false` 退回瀑布流内过滤(此时完整段接管仍会压制段级定制)。
|
|
166
|
-
- **中文提示词开关(面板头部工具栏,刷新按钮旁)**:开启 = 把名字对得上内置译本(`lib/zh/`,25 条目)的段一次性覆盖为中文;关闭 = 清掉这些段的替换文本,回归英文原文。两个方向都写入编辑草稿,与手动编辑同一条保存路径;开关状态从配置探测,不新增字段。自定义段与对不上名字的段不受影响,段数与注入不增不减。`{{...}}` 提示词变量(如 persona 的 `{{model}}` / `{{cwd}}`)、机器路径与代码块逐字保留;`tools:sdk` 只替换前导散文,TS 代码块取自原文。**`tools:sdk` 与 `context:file-reference` 是函数译本**:按该行原文决定译不译(原文为空 = 该段的守卫已把它抹掉,就放弃替换,绝不用译本把一段被守卫消掉的内容复活);开关开启时从「本系统全部提示词」池把段拖进某阶段,也优先取译本 —— 加入即中文,一步接管。
|
|
167
|
-
- **三态同步(头部开关,默认关)**:勾选瞬间即把另外两态覆写为**常驻期的并集行集**(写入编辑草稿,点「保存」生效),之后三个阶段共用同一份段列表与文本 —— 增加 / 删除 / 排序 / 勾选 / 编辑文本都一次写全三个阶段,不再逐阶段各点一遍。行序以常驻期为骨架,只存在于另外两态的段追加在尾部并补进常驻期(同名段以它原生所在那一阶段的行为准);三份屏蔽名单也统一为同一份。动态段(运行时才生成正文,取不到原文)无法凭空建进别的阶段,列表里会给出说明。工具两栏的隐藏 / 显示与加回同样对三个阶段一起生效(只作用于同名的那一项)。
|
|
168
|
-
|
|
169
|
-
### 工具目录
|
|
170
|
-
|
|
171
|
-
- **勾选 = 该阶段对模型可见**(`exclude`):取消勾选即在**该阶段**隐藏这个工具,勾回来就恢复,被隐藏的行半透明原位保留。没有白名单模式 —— 它会让 `exclude` 整体失效,一次勾选就能悄悄关掉该阶段其它所有工具,而表达能力并不比反选更多。
|
|
172
|
-
- **「加回」名单(`add`)**:被该阶段裁掉、但**注册表里仍有**的工具,可从「本系统全部工具」池加入该阶段 —— 装配时在过滤**之后**从注册表查回 schema 追加(`exclude` 优先:同一名字两边都在 = 隐藏)。注册表里根本没有的工具(别的预设独有)加不进来,界面会明确说明。
|
|
173
|
-
- **阶段目录**:引导期与压缩受控期各有独立的 exclude / add 名单,运行时优先级为 **压缩受控期 > 引导期 > 静态** —— 压缩后仍未晋级且配了压缩目录就用它,否则未晋级时用引导目录,其余情况用静态过滤。
|
|
174
|
-
- **拖拽**:把池里的工具拖进列表 = 让它在当前阶段出现(加回或从黑名单放出来);把行拖回池 = 从当前阶段拿掉(已加回的撤销加回,原生工具则该阶段隐藏);拖到头部某个**阶段按钮**上 = 复制到那个阶段,**隐藏 / 启用状态一起带过去**,源阶段不动。加回阶段同样只有拖拽这一条路径。
|
|
175
|
-
- **扩充的天花板是注册表**:只能把注册表里已有的工具加回某个阶段;要让一个全新工具出现,得改预设的组成,不是这里。
|
|
176
|
-
- 只影响面向模型的目录;工具本身与路由照常工作。
|
|
177
|
-
|
|
178
|
-
### 模型视角预览
|
|
179
|
-
|
|
180
|
-
预览常驻面板右栏:提示词模式看最终系统提示词,工具模式看模型可见目录(右栏可切提示词 / 工具子视图),随头部阶段 Tab 联动切换。它展示经过**所有插件**过滤后的最终装配结果,所见即模型所见。工具视图给出「模型可见 / 注册表总数」的对照 —— PTC、Code Mode 这类预设会把整套目录包装成单个 `run_code`,只看注册表会误判。
|
|
181
|
-
|
|
182
|
-
### 提示词变量
|
|
183
|
-
|
|
184
|
-
宿主只注册 `provider` / `model` / `cwd` 三个变量,段文本里引用别的 `{{name}}` 会直接让整次装配失败。本插件经官方扩展点追加两类变量:
|
|
185
|
-
|
|
186
|
-
- **内置系统事实**:`date` / `time` / `datetime` / `weekday` / `hostname` / `platform` / `arch` / `username` / `home` / `shell` / `locale` / `node_version`,每次装配现算。
|
|
187
|
-
- **全量环境变量**:`process.env` 的每个键映射为 `env_<小写,非法字符归并为 _>`,如 `PATH` → `{{env_path}}`、`USER.NAME` → `{{env_user_name}}`。
|
|
188
|
-
|
|
189
|
-
**黑名单(`envBlocklist`)**:env 里常有密钥,进了提示词就会随请求发给模型,所以命中黑名单的键不注册。预填条目覆盖常见凭据类键(含 `SECRET` / `TOKEN` / `PASSWORD` / `API_KEY` / `*_DSN` 等),条目支持 `*` 通配、大小写不敏感;面板的环境变量黑名单卡片可随时增删,卡里的折叠列表给出当前实际注册的变量清单。黑名单变化在下次装配生效(面板改动或直接改 `config.yaml` 都一样)。
|
|
190
|
-
|
|
191
|
-
**导出 / 导入随行**:导出预设时当前黑名单随行写入文件;导入端按并集并入(只增不减),与快照库语义一致。
|
|
192
|
-
|
|
193
|
-
严格渲染的代价:段里引用了一个未注册的名字(如被黑名单挡下的键),**整段装配失败**而不是留空 —— 面板清单里没列出的名字不要用。
|
|
194
|
-
|
|
195
|
-
### 配置快照与 agent 预设
|
|
196
|
-
|
|
197
|
-
- **保存当前配置**:把当前作用域的完整定制(含每阶段屏蔽名单、每阶段排序、阶段工具目录)存成一份可复用的配置快照。
|
|
198
|
-
- **应用**:同名段被覆盖、快照名单之外的当前段被默认屏蔽;快照里当前系统匹配不上的段默认跳过(跨系统导入不凭空建段),快照里没有的阶段字段保留你当前的值,不会被抹掉。同一时间只有一份在用。
|
|
199
|
-
- **导出 / 导入**:配置快照以 JSON 往返(Tauri 桌面走原生对话框,Web 走下载 / 文件选择),同名预设会被跳过。顺序以相对形式存储(每段记住它跟随谁),快照因此可跨不同段集合移植。
|
|
200
|
-
- **存为 agent 预设**:整体**复制**当前编辑目标的预设目录(组成文件、伴生脚本、技能目录一并带走)到用户预设根,再把当前定制写进它的覆盖项。新预设随即出现在头部预设 Tab 里 —— 它是一个真正可切换的 agent 预设,而不只是一份配置副本。
|
|
201
|
-
|
|
202
|
-
### 跨预设的注册表池
|
|
203
|
-
|
|
204
|
-
「本系统全部提示词 / 本系统全部工具」不随编辑目标切换:它是一个**跨预设、只增不减的并集**(同名后见到者赢,新名追加),存放在 `catalog.yaml` 这个派生缓存里,删掉会自行重建。
|
|
205
|
-
|
|
206
|
-
池子的内容来自三处,**面板一打开就成立**:
|
|
207
|
-
|
|
208
|
-
- **当前 scope 的注册表**(你正在编辑的那个预设);
|
|
209
|
-
- **agent 作用域里注册的段**:有一批段是插件按 agent 动态 `section()` 的(例如 `tool:subagent`、`context:file-reference`),它们既不进全局层也不进任何预设 scope,只在真实会话装配里出现。它们是「每个 agent 都成立」的段、**不是某个模式独有的**,所以清单在请求时就按 agent 作用域现 merge 出来 —— 打开面板就能看到,不必先跑一轮会话;
|
|
210
|
-
- **浏览过的其它预设**:只在某个预设里注册的段 / 工具(如 `tools:ptc-only`、`raw-html-v2:vcp`)随你切换编辑目标逐步并进来 —— 这部分按需增长,是本插件的取舍(逐个挂载预设 tree 慢到十几秒,不值得每次开面板都跑)。
|
|
211
|
-
|
|
212
|
-
真实会话装配那次也会把看到的段 / 工具并进登记表,作为没有活 agent 时的兜底。
|
|
213
|
-
|
|
214
|
-
## 工作原理
|
|
215
|
-
|
|
216
|
-
一次改动从面板到模型的完整链路:
|
|
217
|
-
|
|
218
|
-
<table>
|
|
219
|
-
<tr align="center">
|
|
220
|
-
<td width="19%"><b>① 侧边栏面板</b><br>左栏勾选列表 / 右栏预览<br><i>只改内存草稿</i></td>
|
|
221
|
-
<td width="3%">→</td>
|
|
222
|
-
<td width="19%"><b>② 插件自有路由</b><br><code>/config</code> · <code>/config/apply</code><br><code>/preview</code> · <code>/inventory</code> · <code>/presets</code></td>
|
|
223
|
-
<td width="3%">→</td>
|
|
224
|
-
<td width="19%"><b>③ config.yaml</b><br>全局字段 + <code>overrides[预设]</code><br><i>mtime 懒加载,手改即时生效</i></td>
|
|
225
|
-
<td width="3%">→</td>
|
|
226
|
-
<td width="34%"><b>④ 装配瀑布流</b><br><code>system-prompt/assemble</code> 钩子按会话推导阶段,<br>解析出生效配置并过滤</td>
|
|
227
|
-
</tr>
|
|
228
|
-
<tr>
|
|
229
|
-
<td colspan="9" align="center"><b>④ 内部依次是</b>:<code>effectiveConfig(overrides[会话所属预设])</code>(0.9.0 起无全局基底)→ 段:屏蔽 → 替换 → 注入 → 按 order 排序;工具:<code>pickToolsFilter</code>(压缩 > 引导 > 静态)→ <code>applyToolFilter</code></td>
|
|
230
|
-
</tr>
|
|
231
|
-
<tr>
|
|
232
|
-
<td colspan="9" align="center">
|
|
233
|
-
<b>⑤ 交卷前还有一手</b>:宿主在瀑布流<b>之后</b>,若存在 <code>complete: true</code> 的段就把整份 sections 还原成那一条 —— 这就是面板会对这类预设亮黄标的原因(工具目录不受影响;<code>forceSections</code> 开启时本插件已在装配入口重建 sections,接管被绕过,不再亮黄标)
|
|
234
|
-
</td>
|
|
235
|
-
</tr>
|
|
236
|
-
<tr>
|
|
237
|
-
<td colspan="9" align="center"><b>⑥ 模型收到</b>:最终系统提示词 + 可见工具目录;右栏预览读的就是这一份结果</td>
|
|
238
|
-
</tr>
|
|
239
|
-
</table>
|
|
240
|
-
|
|
241
|
-
代码地图:
|
|
242
|
-
|
|
243
|
-
| 路径 | 作用 |
|
|
244
|
-
| --------------------------------- | -------------------------------------------------------------------------------- |
|
|
245
|
-
| `lib/index.js` | 宿主端:装配钩子、五条 HTTP 路由、agent 预设 fork、遗留字段一次性清理 |
|
|
246
|
-
| `lib/effective.js` | 纯函数:字段级 override 合并、阶段选取(注入段 / 工具目录)、黑名单过滤 |
|
|
247
|
-
| `lib/promotion.js` | 由 durable 事件推导 `{promoted, boundary}`,压缩复位、子代理恒已晋级 |
|
|
248
|
-
| `lib/vars.js` | 提示词变量:内置系统事实 + env 全量映射 / 黑名单,装配入口按签名懒同步 |
|
|
249
|
-
| `lib/sectionOps.mjs` | **面板与单测共用**的阶段状态纯函数(名单写回目标、注入身份、重排、逐阶段持久化) |
|
|
250
|
-
| `lib/store.js` / `lib/catalog.js` | 原子写 + last-good 回落的配置存储;跨预设段/工具累积登记表 |
|
|
251
|
-
| `src/client/` | 面板(React,无 JSX 语法糖依赖,`h()` 直写),构建进 `client/client.js` |
|
|
252
|
-
|
|
253
|
-
关键约定:阶段逻辑只有一份实现 —— `lib/sectionOps.mjs` 既被 tsdown 打进浏览器包,也被
|
|
254
|
-
`node --test` 直接 import 跑单测,所以「测试通过」和「界面行为」之间不存在第二套代码。
|
|
255
|
-
|
|
256
71
|
## 安装
|
|
257
72
|
|
|
73
|
+
Web profile:
|
|
74
|
+
|
|
258
75
|
```bash
|
|
259
76
|
dsh plugin --profile web add dsh-prompt-customizer
|
|
260
77
|
```
|
|
261
78
|
|
|
262
|
-
|
|
79
|
+
桌面端(DeepSeek Harness Desktop):
|
|
263
80
|
|
|
264
81
|
```bash
|
|
265
|
-
dsh plugin --profile
|
|
82
|
+
dsh plugin --profile desktop add dsh-prompt-customizer
|
|
266
83
|
```
|
|
267
84
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
当前版本(0.9.0)对齐 **DSH 0.2.0-rc.2**(`peerDependencies` 为 `^0.2.0-rc.2`)。
|
|
271
|
-
|
|
272
|
-
**0.9.0 行为变更:全局层停用。** 提示词必须按具体 agent 预设修改——「全部 Agent」
|
|
273
|
-
编辑入口移除,`/config/apply` 无 `target` 一律 400,`/config/set|unset` 拒绝六个
|
|
274
|
-
提示词字段;运行时生效配置 = 该会话所属预设的 `overrides[id]`,未定制的字段 =
|
|
275
|
-
官方默认。config.yaml 顶层的旧全局层数据**保留不再生效**(可手编回滚;0.8.x 及
|
|
276
|
-
以前的行为请用 0.8.1)。
|
|
277
|
-
0.1.7 起的图标代际(`IconXxxOutlineRegular/Medium`,尺寸由 `size` 属性给)在
|
|
278
|
-
0.2.0 沿用,本插件的宿主接触面(`system-prompt` 装配 waterfall、`agentPresets`、
|
|
279
|
-
`configEditor`、`tools.restrict/schemas`、`webServer.register`、客户端模块加载缝)
|
|
280
|
-
在 0.1.7-rc.1 → 0.2.0-rc.2 走廊内均无破坏性变更,故客户端 bundle 与 0.7.x 同代。
|
|
281
|
-
不支持 0.1.7 之前的主机(旧宿主会按 DSH 的插件兼容性策略拒绝加载,而不是半静默
|
|
282
|
-
地坏掉)。需要旧版的请用 0.6.x。
|
|
283
|
-
|
|
284
|
-
0.8.1 起 MCP 全局 Server 的管理目标(`/api/triad/mcp-status` / `mcp-config` 读写
|
|
285
|
-
的 `cordis.patch.yml`)随宿主 `profileContext` 解析——Web 端(profile `web`)与
|
|
286
|
-
**桌面端**(profile `desktop`,默认端口 19387)各管各的 profile,不再写死 `web`。
|
|
287
|
-
宿主面缺失时按 `DSH_DESKTOP_PROFILE` 环境变量回落(桌面壳 v4 形态),最后回落
|
|
288
|
-
`web` 保持旧行为。注意桌面 profile 没有 `patchReload: live`:切换 / 粘贴 / 删除
|
|
289
|
-
MCP Server 写盘成功后需**重启桌面端**才生效(Web 端热重载语义不变)。
|
|
290
|
-
|
|
291
|
-
预设专属 MCP Server 的存储位置自 0.1.7 起:预设不再是磁盘上的组合
|
|
292
|
-
文件,而是声明式插件行(`name: '@deepseek-ai/dsh-agent-preset'`),专属 Server
|
|
293
|
-
写在它的 `config.plugins` 里;本插件经 DSH 的 `configEditor` 把改动写回 profile
|
|
294
|
-
的 `cordis.patch.yml`(首次改动会整份覆盖该预设行的 plugins,此后该预设不再跟随
|
|
295
|
-
DSH 升级更新 —— 与 DSH 自带编辑器同一语义,面板上有提示)。
|
|
296
|
-
|
|
297
|
-
### 桌面端(DeepSeek Harness Desktop)
|
|
298
|
-
|
|
299
|
-
桌面端是 Electron 壳包着同一套 dsh Web 应用,宿主 profile 固定为 `desktop`
|
|
300
|
-
(默认端口 19387,与 Web 的 3080 互不相扰)。安装走同一条官方命令,只是 profile
|
|
301
|
-
名不同:
|
|
85
|
+
也可从本地检出安装:
|
|
302
86
|
|
|
303
87
|
```bash
|
|
304
|
-
dsh plugin --profile
|
|
88
|
+
dsh plugin --profile web add /path/to/dsh-prompt-customizer
|
|
305
89
|
```
|
|
306
90
|
|
|
307
|
-
|
|
308
|
-
Web 端一致(桌面端经 `dsh-app://` 协议转发请求并附带认证 cookie,插件全部使用
|
|
309
|
-
相对路径请求,无需任何特判)。唯一语义差异是上文提到的:桌面 profile 不做
|
|
310
|
-
`patchReload: live`,MCP 全局 Server 变更需要重启桌面端。
|
|
91
|
+
当前版本 **2.1.2**(单预设编辑;**全域系统提示词接管**:清单与预览并入同预设活动 agent 的真实装配,插件动态注入的会话级段可枚举、可屏蔽;**工具目录与真实会话同源**:右栏可见工具目录改用 `ctx.tools.schemas(agent)`,不再只显示预设层;**同名遮蔽探测**:被插件同名工具顶掉的原生工具无条件进入只读遮蔽池,插件纯新增的会话级工具也如实列出;工具屏蔽池、工作区技能状态、汇总缓存和写队列回归已补齐;MCP 全局编辑支持 JSON/YAML;活跃 Agent 预设按 `composedPreset` 精确归位;A/B 预设提示词与工具隔离、卸载恢复及原文不可变回归)。版本对应关系、逐版变更和适配记录见 [docs/upgrades/README.md](docs/upgrades/README.md)。
|
|
311
92
|
|
|
312
|
-
|
|
93
|
+
## 快速上手
|
|
313
94
|
|
|
314
|
-
|
|
95
|
+
1. 打开 dsh Web UI,侧边栏点 **能力**。
|
|
96
|
+
2. 选择 **提示词** tab,在顶部选择要编辑的 agent 预设。
|
|
97
|
+
3. 在提示词 / 工具 / 配置三种模式里调整,点 **保存** 生效;右栏预览会实时显示模型最终收到的内容。
|
|
315
98
|
|
|
316
|
-
|
|
99
|
+
提示词与工具支持按「引导期 / 压缩受控期 / 常驻期」分别配置;切换阶段 Tab 即可看到该阶段独立的勾选状态与预览。
|
|
317
100
|
|
|
318
|
-
|
|
101
|
+
## 配置位置
|
|
319
102
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
- **勾选框**:该阶段是否注入模型(`未屏蔽` / `已屏蔽` 徽标);被停用的行半透明原位保留,随时勾回
|
|
323
|
-
- **编辑**:按阶段替换该段文本,替换过的行带 `已替换` 徽标与「还原」按钮
|
|
324
|
-
- **↑/↓**:调整该阶段内的顺序;`#N` 是它当前的虚拟下标
|
|
325
|
-
- `系统` / `手动` 徽标标明段的来源,只有 `手动` 段可以删除
|
|
326
|
-
- **「+ 注入」**:展开表单按名称 + 文本新建一段(阶段锁定为当前 Tab)
|
|
327
|
-
- **底部三态过滤**:全部 / 已启用 / 已停用,只统计当前阶段
|
|
328
|
-
|
|
329
|
-
「本系统全部提示词」只读池收在列表末尾的折叠区:**把行拖进上面的列表**即加入当前阶段,**拖到头部阶段按钮**即加入那个阶段(行上不再有按钮)。右栏实时预览当前阶段装配后的最终系统提示词 —— 编辑草稿的效果同步呈现,面板会标注「预览尚未保存草稿」。
|
|
330
|
-
|
|
331
|
-
勾选头部的**三态同步**后,三个阶段共用同一份段列表与文本(常驻期为骨架,另外两态独有的段追加在尾部并补进常驻期):切哪个阶段 Tab 看到的都是同一份列表,增删 / 排序 / 勾选 / 编辑文本一次写全三态 —— 适合「三个阶段要一样的提示词」;不勾选则三态各管各的,适合「引导期只留几段、晋级后全开」。
|
|
332
|
-
|
|
333
|
-
### 工具模式
|
|
334
|
-
|
|
335
|
-
左栏列出该阶段进入过滤的目录 ∪ 你加回的工具:勾选 = 该阶段对模型可见,取消 = 在该阶段隐藏。「本系统全部工具」池收在折叠区:**把行拖进列表**即让它在当前阶段出现,**拖到阶段按钮**即复制到那个阶段(隐藏状态一起带过去),**拖回池**即从当前阶段拿掉。想看模型真正拿到几个工具,看右栏预览的「模型可见 / 注册表总数」对照。
|
|
336
|
-
|
|
337
|
-
### 配置模式
|
|
338
|
-
|
|
339
|
-
左栏是**配置快照库**(保存当前配置 / 导入 / 应用 / 导出 / 删除,正在使用的那份带「使用中」标记);右栏是**存为 agent 预设**(整体 fork 当前编辑目标的预设目录并写入当前定制)与**全局设置**:强制覆盖开关、环境变量黑名单(增删条目、查看当前实际注册的变量清单)、提示词变量参考、恢复初始状态(清空全部定制并关闭 `forceSections`,与卸载插件等效,无需重启,点击需二次确认)。
|
|
340
|
-
|
|
341
|
-
### 编辑目标与保存
|
|
342
|
-
|
|
343
|
-
预设 Tab 决定改动落在哪。提示词与工具模式共享同一份未保存草稿,**保存**按钮一次落盘;切到配置模式或切换编辑目标会丢弃草稿(脏草稿先弹确认)。也就是说:写坏的东西不点保存就不会进文件。
|
|
344
|
-
|
|
345
|
-
## 配置存放位置
|
|
346
|
-
|
|
347
|
-
- `~/.dsh/prompt-customizer/config.yaml` —— 唯一权威配置。首次启动时若该文件不存在而旧版 `settings.yaml` 里有对应段落,会自动迁移一次(主文档原样保留,可回滚)。手工编辑即时生效,无需重启。
|
|
348
|
-
- `~/.dsh/prompt-customizer/catalog.yaml` —— 跨预设的段 / 工具累积登记表,纯派生缓存,删掉会随浏览重建。
|
|
349
|
-
- 技能侧:技能根目录下的 `.bundles.json`(技能包账本,记规范名与目录名两套写法)与技能开关账本(全局层 + 各预设层)。
|
|
350
|
-
- MCP 侧:`$DSH_HOME` 下本插件目录里的 `preset-masks.json`(分层遮蔽账本)与 `tool-disable.json`(工具级启停账本);预设自带 Server 行写在该 agent 预设声明行的 `config.plugins` 里,由 DSH 的 `configEditor` 原子写回 profile 的 `cordis.patch.yml`(全局 Server 仍由本插件直接编辑该 patch,写前备份)。
|
|
351
|
-
|
|
352
|
-
## 已知限制
|
|
353
|
-
|
|
354
|
-
下面都是实测结论。面板在相关情况下会直接给出黄色警示,不需要你猜:
|
|
355
|
-
|
|
356
|
-
- **有些预设的提示词不由段组成。** 若某个段以 `complete: true` 注册(dsh-persona 的「整段接管」),宿主会在装配瀑布流**之后**把整份 sections 还原成那一条段。`forceSections`(默认开)已在装配入口绕开该机制,段级定制照常生效;只有把它设为 `false` 时,本插件的屏蔽 / 替换 / 注入 / 排序才会对这类预设无效(工具过滤不受影响),面板会写明「最终系统提示词由 `deployment:persona` 段整段接管」。
|
|
357
|
-
- **丢弃段的原因不止一种**。除了 `complete` 接管,也存在预设用自己的规则在特定阶段裁段(实测某预设引导期 20 段 → 1 段,而注册表里并没有 complete 段)。所以面板还做了一次机制无关的比对:把本插件产出的段名与最终装配逐名核对,不符时提示「产出 N 段,模型只见 M 段」。
|
|
358
|
-
- **预览的伪会话可能降级**。阶段视图由一次合成会话驱动,个别预设插件会在这种会话上抛错;此时该阶段回退为无会话装配并标注「已降级」,即那个阶段看到的是不带原生阶段裁剪的结果。
|
|
359
|
-
- **替换动态生成的段会固定其内容**。像 `app:web-surface` 这类段在装配时实时生成(嵌入当前 Web 端口等)。替换后文本冻结为你编辑时的值,不再跟随运行时变化;想保持跟随请改用屏蔽。
|
|
360
|
-
- **动态段文本解析是尽力而为**。面板读取动态段时会尝试调用其生成函数(只传最小上下文)来回显真实内容;依赖更复杂上下文、一调就抛的段会显示 `<动态生成>`,其余功能不受影响。另外,带 `{{model}}` / `{{cwd}}` 之类变量的段在列表里显示的是**未替换的模板**,右栏预览里才是替换后的最终文本。
|
|
361
|
-
- **导出依赖宿主允许下载**。Web 回退走浏览器下载:若宿主 webview 静默丢弃下载,面板仍会提示「导出成功」而文件没有落地。导入(文件选择)不受影响。
|
|
362
|
-
- **池子是「见过才知道」的并集**。当前 scope 与 agent 作用域的段当场就能列出来,但**只在别的预设里注册**的段 / 工具要等你切到那个编辑目标才进池(逐个挂载预设 tree 太慢,不做预热)。池子对「某个名字属于哪个阶段」没有权威信息 —— 加入阶段时按当前 Tab 落,之后可以随意拖动改位置。
|
|
363
|
-
- **工具目录的扩充以注册表为天花板**,见前文「扩充的天花板是注册表」。
|
|
103
|
+
- **统一为单文件 SQLite**:`~/.dsh/prompt-customizer/prompt-customizer.db`(WAL,使用 Node 内建 `node:sqlite`,无外部依赖)。预设定制、MCP 与技能各账本都在这一个库里;工作区级提示词/工具数据作为休眠字段保留但不读不写。宿主配置文件(`cordis.patch.yml` / `.mcp.json`)与技能根下的 `.bundles.json` 仍保持文件。
|
|
104
|
+
- **破坏式更新(1.0.0)**:旧版 `config.yaml` / `catalog.yaml` 及各 JSON 账本**不再读取、不迁移**(文件原样保留);升级到 1.0.0 需**重新配置**。详见 [docs/upgrades/1.0.0-sqlite-breaking.md](docs/upgrades/1.0.0-sqlite-breaking.md)。
|
|
364
105
|
|
|
365
106
|
## 开发
|
|
366
107
|
|
|
367
108
|
```bash
|
|
368
109
|
npm install
|
|
369
|
-
npm run check #
|
|
110
|
+
npm run check # 构建 + 全量单测 + 宿主 / 客户端 smoke
|
|
370
111
|
```
|
|
371
112
|
|
|
372
|
-
|
|
113
|
+
构建产物:`lib/index.js`(宿主半身)与 `client/client.js`(浏览器半身)。
|
|
373
114
|
|
|
374
|
-
|
|
375
|
-
- `client/client.js` —— 浏览器半身,`__ModuleLoader__` factory bundle;`react*` 与 `@deepseek-ai/*` 走宿主模块表,其余全部内联。
|
|
115
|
+
## 文档
|
|
376
116
|
|
|
377
|
-
|
|
117
|
+
- [完整使用与实现指南](docs/guide.md)
|
|
118
|
+
- [版本升级与适配记录](docs/upgrades/README.md)
|
|
119
|
+
- [DSH 0.2.2-rc.1 适配记录](docs/upgrades/dsh-0.2.2-rc1.md)
|
|
120
|
+
- [DSH 0.2.1-rc.2 适配记录](docs/upgrades/rc2-migration.md)
|
|
378
121
|
|
|
379
122
|
## 致谢
|
|
380
123
|
|
|
381
|
-
- 技能(SKILL)与 MCP
|
|
124
|
+
- 技能(SKILL)与 MCP 两块的界面与宿主模块参考 [Kr-ATG/dsh-triad](https://github.com/Kr-ATG/dsh-triad)。
|
|
382
125
|
- 提示词面板派生自本仓库 0.5.x 的独立实现。
|
|
383
126
|
|
|
384
127
|
## License
|
|
@@ -387,12 +130,4 @@ npm run check # typecheck + build + 全量单测
|
|
|
387
130
|
|
|
388
131
|
---
|
|
389
132
|
|
|
390
|
-
## Star History
|
|
391
|
-
|
|
392
133
|
[](https://star-history.com/#DreamsTOF/dsh-prompt-customizer&Date)
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
<p align="center">
|
|
397
|
-
<strong>⭐ 如果这个插件让你的系统提示词更干净、工具目录更听话,就给它一个 star 吧!</strong>
|
|
398
|
-
</p>
|
package/build.mjs
CHANGED
|
@@ -27,15 +27,29 @@ import { fileURLToPath } from 'node:url'
|
|
|
27
27
|
|
|
28
28
|
const HERE = dirname(fileURLToPath(import.meta.url))
|
|
29
29
|
// 可选:指向一份 DSH 检出,用于在没装 esbuild 时借用它 pnpm store 里的副本。
|
|
30
|
-
//
|
|
30
|
+
// 缺省时自动探测同级的 `deepseek-harness` 检出与其它同级目录(开发机便利)。
|
|
31
31
|
const DSH_CHECKOUT = process.env.DSH_CHECKOUT ?? ''
|
|
32
32
|
const PLUGIN_ID = 'dsh-prompt-customizer'
|
|
33
33
|
|
|
34
|
+
/** 可能含 pnpm store 的检出根:显式 env、同级 deepseek-harness、同级其它目录。 */
|
|
35
|
+
function checkoutCandidates() {
|
|
36
|
+
const parent = resolve(HERE, '..')
|
|
37
|
+
const roots = []
|
|
38
|
+
if (DSH_CHECKOUT !== '') roots.push(DSH_CHECKOUT)
|
|
39
|
+
roots.push(join(parent, 'deepseek-harness'))
|
|
40
|
+
try {
|
|
41
|
+
for (const entry of readdirSync(parent, { withFileTypes: true })) {
|
|
42
|
+
if (entry.isDirectory()) roots.push(join(parent, entry.name))
|
|
43
|
+
}
|
|
44
|
+
} catch { /* 无同级目录 */ }
|
|
45
|
+
return [...new Set(roots)]
|
|
46
|
+
}
|
|
47
|
+
|
|
34
48
|
/**
|
|
35
49
|
* Resolve esbuild.
|
|
36
50
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
51
|
+
* Tiers, in order — the first two keep this plugin buildable both for a
|
|
52
|
+
* fresh clone (`pnpm install` puts esbuild in node_modules) and for a
|
|
39
53
|
* contributor hacking inside a DSH checkout:
|
|
40
54
|
*
|
|
41
55
|
* 1. the plugin's own `node_modules` (normal install path; esbuild is a
|
|
@@ -56,23 +70,26 @@ function loadEsbuild() {
|
|
|
56
70
|
// Not installed locally; fall through to the checkout scan.
|
|
57
71
|
}
|
|
58
72
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
for (const root of checkoutCandidates()) {
|
|
74
|
+
const store = join(root, 'node_modules', '.pnpm')
|
|
75
|
+
if (!existsSync(store)) continue
|
|
76
|
+
const candidates = []
|
|
62
77
|
for (const entry of readdirSync(store)) {
|
|
63
78
|
if (!entry.startsWith('esbuild@')) continue
|
|
64
79
|
candidates.push(join(store, entry, 'node_modules', 'esbuild'))
|
|
65
80
|
}
|
|
66
|
-
|
|
67
|
-
if (candidates.length > 0) {
|
|
81
|
+
if (candidates.length === 0) continue
|
|
68
82
|
const pick = candidates.sort().at(-1)
|
|
69
|
-
|
|
83
|
+
try {
|
|
84
|
+
return createRequire(resolve(pick, 'package.json'))(pick)
|
|
85
|
+
} catch { /* store 里没有可用的平台二进制:试下一个根 */ }
|
|
70
86
|
}
|
|
71
87
|
|
|
72
88
|
throw new Error(
|
|
73
89
|
'dsh-prompt-customizer: cannot find esbuild.\n'
|
|
74
90
|
+ ' Run `pnpm install` in this directory (esbuild is a devDependency).\n'
|
|
75
|
-
+
|
|
91
|
+
+ ' Or set DSH_CHECKOUT to a DSH checkout to borrow its copy.\n'
|
|
92
|
+
+ ` Checked: ${checkoutCandidates().join(', ')}`,
|
|
76
93
|
)
|
|
77
94
|
}
|
|
78
95
|
|