dsh-plugin-prompt-tool 2.1.0 → 3.0.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.
Files changed (204) hide show
  1. package/README.md +100 -233
  2. package/engine/actions/append-context.mjs +3 -24
  3. package/engine/actions/assembly.mjs +70 -94
  4. package/engine/actions/catalog.mjs +65 -28
  5. package/engine/actions/content.mjs +8 -152
  6. package/engine/actions/examples.mjs +8 -4
  7. package/engine/actions/inbox-prepend.mjs +4 -5
  8. package/engine/actions/index.mjs +17 -9
  9. package/engine/actions/inject-text.mjs +24 -4
  10. package/engine/actions/pre-step-filter.mjs +3 -4
  11. package/engine/actions/registration.mjs +20 -28
  12. package/engine/actions/request-params.mjs +21 -1
  13. package/engine/actions/shared.mjs +22 -13
  14. package/engine/actions/stream-output.mjs +26 -0
  15. package/engine/actions/tool-gate.mjs +31 -0
  16. package/engine/actions/tool-result.mjs +36 -0
  17. package/engine/actions/tool-visibility.mjs +248 -0
  18. package/engine/agent-capability.mjs +67 -0
  19. package/engine/anchor-match.mjs +14 -21
  20. package/engine/audience.d.mts +2 -0
  21. package/engine/audience.mjs +102 -0
  22. package/engine/branch.d.mts +4 -0
  23. package/engine/branch.mjs +61 -18
  24. package/engine/compaction-epoch.d.mts +25 -0
  25. package/engine/compaction-epoch.mjs +27 -4
  26. package/engine/compositions/source/local/filesystem-editor.yml +3 -3
  27. package/engine/compositions/source/local/instruction-hint.yml +2 -4
  28. package/engine/compositions/source/local/module-file-tools.yml +2 -0
  29. package/engine/compositions/source/local/module-import-tools.yml +4 -0
  30. package/engine/compositions/source/local/module-manifest-tools.yml +2 -0
  31. package/engine/compositions/source/local/module-rule-tools.yml +5 -0
  32. package/engine/compositions/source/local/module-variable-tools.yml +5 -0
  33. package/engine/compositions/source/local/present-as.yml +26 -0
  34. package/engine/compositions/source/local/tool-config-engine.yml +2 -3
  35. package/engine/compositions/source/local/tool-search.yml +11 -0
  36. package/engine/condition-facts.mjs +84 -0
  37. package/engine/conditions/anchor.mjs +63 -23
  38. package/engine/conditions/availability.mjs +1 -1
  39. package/engine/conditions/composite.mjs +3 -3
  40. package/engine/conditions/count.mjs +42 -11
  41. package/engine/conditions/evaluation.mjs +74 -19
  42. package/engine/conditions/examples.mjs +2 -1
  43. package/engine/conditions/index.d.mts +15 -0
  44. package/engine/conditions/index.mjs +23 -9
  45. package/engine/conditions/operators.mjs +4 -0
  46. package/engine/conditions/phase.mjs +9 -3
  47. package/engine/conditions/preset.mjs +1 -1
  48. package/engine/conditions/session.mjs +8 -2
  49. package/engine/conditions/subject.mjs +144 -65
  50. package/engine/conditions/text.mjs +26 -8
  51. package/engine/conditions/variable.mjs +83 -0
  52. package/engine/context-activation.d.mts +11 -0
  53. package/engine/{st-world-book.mjs → context-activation.mjs} +104 -64
  54. package/engine/delivery.d.mts +2 -0
  55. package/engine/delivery.mjs +93 -0
  56. package/engine/discovery.d.mts +38 -0
  57. package/engine/discovery.mjs +146 -0
  58. package/engine/env-safety.mjs +14 -0
  59. package/engine/executor.d.mts +28 -0
  60. package/engine/executor.mjs +290 -205
  61. package/engine/fillers.mjs +39 -8
  62. package/engine/fixed-registration.mjs +12 -0
  63. package/engine/history.mjs +71 -0
  64. package/engine/instruction-blocks.d.mts +13 -0
  65. package/engine/instruction-blocks.mjs +21 -0
  66. package/engine/instruction-files.d.mts +5 -0
  67. package/engine/instruction-files.mjs +97 -0
  68. package/engine/instruction-hint.mjs +69 -103
  69. package/engine/interpolate.d.mts +7 -0
  70. package/engine/interpolate.mjs +44 -13
  71. package/engine/layers.mjs +163 -227
  72. package/engine/machine-paths.mjs +40 -0
  73. package/engine/module-file-tools.mjs +8 -0
  74. package/engine/module-import-tools.mjs +10 -0
  75. package/engine/module-manifest-tools.mjs +8 -0
  76. package/engine/module-rule-tools.mjs +10 -0
  77. package/engine/module-variable-tools.mjs +10 -0
  78. package/engine/order.d.mts +14 -0
  79. package/engine/order.mjs +0 -3
  80. package/engine/path-safety.d.mts +2 -0
  81. package/engine/path-safety.mjs +58 -0
  82. package/engine/pre-step-source.d.mts +69 -0
  83. package/engine/pre-step-source.mjs +103 -0
  84. package/engine/present-as.mjs +77 -0
  85. package/engine/promotion-pool.d.mts +9 -0
  86. package/engine/promotion-pool.mjs +69 -0
  87. package/engine/record.mjs +2 -0
  88. package/engine/rule-engine.mjs +3 -2
  89. package/engine/rule-facts.d.mts +11 -0
  90. package/engine/rule-facts.mjs +60 -0
  91. package/engine/rule-runtime.d.mts +46 -0
  92. package/engine/rule-runtime.mjs +98 -13
  93. package/engine/rule-spec.d.mts +106 -0
  94. package/engine/rule-spec.mjs +301 -27
  95. package/engine/run-code-env.mjs +73 -19
  96. package/engine/schema.mjs +165 -243
  97. package/engine/sdk-strip.mjs +2 -2
  98. package/engine/service-names.d.mts +10 -0
  99. package/engine/service-names.mjs +10 -0
  100. package/engine/shared.d.mts +21 -0
  101. package/engine/shared.mjs +46 -13
  102. package/engine/skill-search.mjs +125 -53
  103. package/engine/source-kind.d.mts +9 -0
  104. package/engine/source-kind.mjs +16 -0
  105. package/engine/strategy-ids.mjs +5 -0
  106. package/engine/template-evaluation.d.mts +16 -0
  107. package/engine/template-evaluation.mjs +178 -0
  108. package/engine/template-frame.d.mts +16 -0
  109. package/engine/template-frame.mjs +69 -0
  110. package/engine/tool-config-engine.mjs +38 -34
  111. package/engine/tool-definition.d.mts +4 -0
  112. package/engine/tool-definition.mjs +5 -1
  113. package/engine/tool-git-bash.mjs +5 -1
  114. package/engine/tool-scope.mjs +22 -0
  115. package/engine/{dev-tool-search.mjs → tool-search.mjs} +63 -65
  116. package/engine/trigger.mjs +15 -270
  117. package/engine/vendor/yaml/dist/compose/resolve-flow-scalar.js +19 -18
  118. package/engine/vendor/yaml/dist/nodes/Alias.js +25 -23
  119. package/engine/vendor/yaml/package.json +1 -1
  120. package/lib/client.js +8312 -6724
  121. package/lib/client.js.map +1 -1
  122. package/lib/index.d.mts +16 -2120
  123. package/lib/index.mjs +26914 -5816
  124. package/modules/ponytail/module.yml +83 -203
  125. package/modules/ptc-mode/module.yml +45 -0
  126. package/modules/soul/assets/core-hard.md +6 -0
  127. package/modules/soul/assets/criteria.md +12 -0
  128. package/modules/soul/assets/echo.md +12 -0
  129. package/modules/soul/assets/layers.md +11 -0
  130. package/modules/soul/assets/ledger.md +9 -0
  131. package/modules/soul/assets/manifest.yml +20 -0
  132. package/modules/soul/assets/reference/00-layers.md +27 -0
  133. package/modules/soul/assets/reference/01-criteria.md +32 -0
  134. package/modules/soul/assets/reference/02-echo.md +158 -0
  135. package/modules/soul/assets/reference/03-vital.md +183 -0
  136. package/modules/soul/assets/reference/04-manifest.json +106 -0
  137. package/modules/soul/assets/reference/05-doctor.md +67 -0
  138. package/modules/soul/assets/reference/06-reference.md +189 -0
  139. package/modules/soul/assets/reference/07-bundle.json +431 -0
  140. package/modules/soul/assets/reference/08-/350/270/251/345/235/221/345/256/236/345/275/225.md +59 -0
  141. package/modules/soul/assets/reference/09-dev-workflow.md +109 -0
  142. package/modules/soul/assets/reference/10-echo-anatomy.md +100 -0
  143. package/modules/soul/assets/reference/11-self.md +80 -0
  144. package/modules/soul/assets/reference/12-ledger.md +159 -0
  145. package/modules/soul/assets/reference/README.md +10 -0
  146. package/modules/soul/assets/templates/agents-template.md +6 -0
  147. package/modules/soul/assets/vital.md +9 -0
  148. package/modules/soul/module.yml +311 -0
  149. package/modules/superpowers/module.yml +122 -0
  150. package/modules/tool-surface/module.yml +51 -47
  151. package/package.json +37 -40
  152. package/skills/dsh-module/SKILL.md +67 -147
  153. package/skills/dsh-module/reference.md +113 -86
  154. package/templates/10-pre-step.yml +2 -3
  155. package/templates/14-first-turn-anchor.yml +10 -14
  156. package/templates/15-guide-auto.yml +32 -28
  157. package/templates/16-custom-fallback.yml +33 -21
  158. package/templates/20-system-section.yml +1 -4
  159. package/templates/50-llm-stream.yml +4 -10
  160. package/templates/60-tool-pipeline.yml +12 -10
  161. package/templates/63-append-context.yml +4 -6
  162. package/templates/65-turn-stop.yml +2 -2
  163. package/templates/67-inbox-prepend.yml +2 -2
  164. package/templates/70-subagent-maintenance.yml +9 -10
  165. package/templates/75-subagent-end.yml +2 -2
  166. package/templates/80-tool-surface.yml +41 -57
  167. package/templates/tools/40-delegate-module-import.yml +22 -0
  168. package/templates/tools/50-delegate-module-rules.yml +14 -0
  169. package/templates/tools/60-delegate-module-variables.yml +17 -0
  170. package/templates/tools/70-delegate-module-rules-edit.yml +31 -0
  171. package/engine/actions/decision.mjs +0 -54
  172. package/engine/actions/guard.mjs +0 -80
  173. package/engine/actions/sdk-strip.mjs +0 -30
  174. package/engine/character-tools.mjs +0 -8
  175. package/engine/classify-task.mjs +0 -53
  176. package/engine/compositions/source/local/character-tools.yml +0 -5
  177. package/engine/compositions/source/local/dev-tool-search.yml +0 -11
  178. package/engine/compositions/source/local/session-var-tools.yml +0 -5
  179. package/engine/compositions/source/local/subagent-tool-policy.yml +0 -21
  180. package/engine/compositions/source/local/world-book-tools.yml +0 -5
  181. package/engine/condition.mjs +0 -96
  182. package/engine/declared-triggers.mjs +0 -93
  183. package/engine/session-var-tools.mjs +0 -8
  184. package/engine/session-vars.mjs +0 -54
  185. package/engine/st-macros.d.mts +0 -22
  186. package/engine/st-macros.mjs +0 -208
  187. package/engine/st-render.mjs +0 -109
  188. package/engine/st-world-book.d.mts +0 -10
  189. package/engine/subagent-tool-policy-core.mjs +0 -400
  190. package/engine/subagent-tool-policy.mjs +0 -352
  191. package/engine/trigger-spec.mjs +0 -173
  192. package/engine/world-book-tools.mjs +0 -8
  193. package/lib/migrate-rules.d.mts +0 -1
  194. package/lib/migrate-rules.mjs +0 -610
  195. package/lib/module-package-DqJZaE71.mjs +0 -2
  196. package/lib/module-package-q2gDRu9H.mjs +0 -2869
  197. package/lib/rule-builder-DMrJten6.mjs +0 -14767
  198. package/templates/61-deny-tools-presentation.yml +0 -27
  199. package/templates/62-guard-deny-tools.yml +0 -20
  200. package/templates/policies/legacy-defaults.yml +0 -34
  201. package/templates/tools/40-delegate-character.yml +0 -15
  202. package/templates/tools/50-delegate-worldbook.yml +0 -15
  203. package/templates/tools/60-delegate-session-var.yml +0 -15
  204. package/templates/tools/70-delegate-worldbook-upsert.yml +0 -36
package/README.md CHANGED
@@ -1,296 +1,163 @@
1
- # dsh-plugin-prompt-tool — 层级提示词注入器
1
+ # dsh-plugin-prompt-tool — 提示词注入引擎
2
2
 
3
- > 一切皆可注入:把 DSH 官方开放的全部注入层级收敛为一个可配置提示词注入引擎——注入什么、注入到哪一层、何时注入,全由提示词配置决定。
3
+ 通过普通模块声明注入内容、插入点、时机、受众与动作。规则统一走 `compileRules → mountRuleSources`,对接九个独立官方插入点;六层可注入,agent-request、llm-stream、tool-pipeline 分别使用请求、流输出与工具动作。模块与官方会话预设分开,不分发或替换官方预设。
4
4
 
5
- DSH 生态的提示词注入层:`rule-engine.mjs` 按「条件触发 → 执行动作」对接九个官方插入点。每张配置卡对应一条独立规则,可组合多条件与多动作;提示词注入也是动作。包内模块库提供复制起点;模块不注册为官方会话预设。
6
-
7
- > 能力来源:工具目录锚定与晋升门控移植自 [dsh-anchored-standard](https://github.com/xiaobright/dsh-anchored-standard)(MIT,上游已于 2026-09-10 冻结),近距离引导参考 [dsh-router-standard](https://github.com/yjh051108/dsh-router-standard),缓存铁律参考 [dsh-super-injector](https://github.com/yjh051108/dsh-super-injector)。**本项目只移植引擎能力,不再分发上游预设**:锚定/深思链路由模块与规则按需声明。
5
+ 能力来源包括 [dsh-anchored-standard](https://github.com/xiaobright/dsh-anchored-standard)(MIT)、[dsh-router-standard](https://github.com/yjh051108/dsh-router-standard) 与 [dsh-super-injector](https://github.com/yjh051108/dsh-super-injector)。锚定、晋升、PTC 与模型增强保持可选,不作为默认工作流。
8
6
 
9
7
  ## 安装
10
8
 
9
+ 通过 DSH 官方插件管理流程安装。新 profile 可从 web 模板初始化;已有 profile 跳过初始化:
10
+
11
11
  ```bash
12
- # 1) 新建 profile:从官方 web 模板初始化(仅用于尚不存在的 profile,已存在的 profile 请跳过)
13
12
  dsh --profile prompt-tool --from-default-profile web
14
-
15
- # 2) 安装插件
16
- dsh plugin --profile prompt-tool add dsh-plugin-prompt-tool # npm 安装
17
- dsh plugin --profile prompt-tool add link:<本仓库绝对路径> # 本地源码(link 覆盖 registry)
18
-
19
- # 3) 启动
13
+ dsh plugin --profile prompt-tool add dsh-plugin-prompt-tool
20
14
  dsh --profile prompt-tool
21
15
  ```
22
16
 
23
- 从 web 模板初始化会让 profile 自带 `@deepseek-ai/dsh-base` 与 `@deepseek-ai/dsh-web-app` 两层,无需额外的 Web 自愈步骤。`--from-default-profile` 只在 profile 不存在时创建,不要对既有 profile 反复执行;已初始化的 profile 不会被改写。
24
-
25
- 技能**留在各自的来源目录里**(项目 `.dsh/skills`、项目 `.agents/skills`、你添加的技能文件夹、`$DSH_HOME/skills`、`~/.agents/skills`、官方内置)。引用目录复用官方 filesystem provider 发现与监听;管理页按当前会话快照标注生效、同名遮蔽和未确认状态。用户根与显式引用目录中的普通技能均可开关、删除;删除移入对应来源根的回收站,保留资源和恢复记录。插件随包分发内置技能(`skills/dsh-module`),安装与每次启动按「只补缺失」补建到 `$DSH_HOME/skills`——已有同名目录保持原样,用户改过或删过的不会被铺回来;新增技能可创建或复制导入,同名导入先确认,成功后不保存技能历史版本。
26
-
27
- **停用 = 改写技能文件的调用策略**:模型端写 `disable-model-invocation`、用户端写 `user-invocable`。单端开关只修改该端,保留另一端的最新状态;正文、注释和未知字段保留,提交前校验原文并原子替换。官方工具与可选 `skill_search/skill_load` 都执行调用策略。状态文件 `$DSH_HOME/skills/.system/prompt-tool/skills.yml` 只保存引用目录 `folders`(v4);技能清单与调用策略均不进入 settings。详见 [docs/skills-management.md](docs/skills-management.md)。
28
-
29
- ### 当前格式与宿主要求
30
-
31
- module.yml 保存模块完整定义,支持 UI 自动保存和直接手改完整文件;rules/ 是校验后供 UI 与运行时使用的切片,手改切片或校验失配会从完整定义恢复。旧 promptConfigs、triggers、模型路由与锚定快捷参数须先离线迁移;运行时不自动双读。共享能力参数归 layerSettings,指令正文保持独立权限通道。
32
-
33
- 升级旧模块前,由用户停止相关 DSH 服务,再使用安装包提供的 `prompt-tool-migrate-rules`,或在已构建仓库中执行:
34
-
35
- ```powershell
36
- $Repo = 'D:/AI/GitHub/dsh-plugin-prompt-tool'
37
- pnpm --dir $Repo migrate:rules -- --root '<DSH_HOME>/.prompt-tool/modules' --characters-root '<DSH_HOME>/.prompt-tool/.characters' --check
38
- pnpm --dir $Repo migrate:rules -- --root '<DSH_HOME>/.prompt-tool/modules' --characters-root '<DSH_HOME>/.prompt-tool/.characters' --apply
39
- # 需要恢复时,保持服务停止,并用相同目录执行 --rollback
40
- ```
41
-
42
- 目录必须显式指定为存在的绝对路径;没有角色库时省略 `--characters-root`。先全量预检,再生成完整候选、校验来源版本并原子替换;原文件保留在各根的 `.rules-migration-backup`。重复应用无改动,回滚只覆盖仍与迁移产物一致的目录。无法证明等价的手写组合、互斥多启用冲突、失效旧参数或自定义策略目录会拒绝迁移,要求先整理。迁移完成后由用户重新启动 DSH。
17
+ 本地开发可将安装来源换为 `link:<本仓库绝对路径>`。插件只诊断缺失的 Web 能力,不改 profile manifest、包链接或重启服务。Node 与官方包版本要求见 [package.json](package.json);宿主接入以实际安装的公开包验证,不能仅凭 peer 范围推断所有未来版本已验收。
43
18
 
44
- 技能调用策略只接受官方 frontmatter 键,状态文件只接受 v4;不提供旧布局迁移、回滚或备份脚本。
19
+ **升级代码、bundle 或 cordis.patch.yml 后,需要用户重启 DSH 服务。** 人设由主插件在会话作用域管理,不改变官方服务的启动依赖:在每个 Agent 自己的 scope 注册同名段,遮蔽部署人设与预设 persona 行,不接管任何官方 fiber。AgentSetup 窗口内注册的同层声明会被撤换(插件人设优先),窗口外的同层声明撤不掉时装配失败并保留旧装配。
45
20
 
46
- 只有 `dsh-base` 的 profile 缺少 Web 能力时,插件仅报告诊断;所需 bundle 由官方插件管理流程装配,插件不改写 profile 或重启服务。
47
-
48
- 需要 DSH `0.2.0-rc.1+`(Cordis `4.0.4`):设置接入 ConfigForms,模块定义与物化文件保存在插件自己的存储根 `$DSH_HOME/.prompt-tool/`(宿主从不扫描该目录),运行时装配由插件的配装通道在每个 Agent 的 scope 里完成,**按存储根 `config.yml` 的启用表逐模块装配**。官方组合模块快照随包分发(`engine/compositions/library/`),不再从官方预设同步——那套生成器已随内置预设目录退场。Node 需要 `^22.19.0 || >=24.0.0`,与官方宿主一致。升级后需要用户重启 DSH 服务。
49
-
50
- `peerDependencies` 里的 `@deepseek-ai/dsh-*` 声明为 `>=0.2.0-rc.1`(无上界):宿主在加载插件时会逐条校验这些 peer,范围写死到某个次版本会让每次宿主升版都判为不兼容;这个范围覆盖 0.2.0 及以上,同时把已知不兼容的更早版本挡在外面。实际锁定的版本以 `pnpm-lock.yaml` 为准。`minimumReleaseAgeExclude` 由 pnpm 维护——安装时 pnpm 会把 lockfile 拿去比对供应链策略,因此升级 DSH 后跑一次 `pnpm install` 即可,不要手工逐条增删。
51
-
52
- ## 特性
53
-
54
- - 🔌 **九个官方插入点按需接线**:一个引擎接入声明所需的插入点,共享同一套过滤与降级语义
55
- - ✍️ **一切皆可配置**:`layer / strategy / position / promotion / audience / modelScope / mergeMode / order / text / texts / fill / variables / params` 全开放
56
- - 🧑‍🤝‍🧑 **消息受众三态**:`audience: main / subagent`,省略 `audience` 表示公用;身份类提示词可只注入子代理
57
- - 🗂️ **完整定义与校验切片**:module.yml 保存完整行为,rules/<id>.yml 保存正文,_settings.yml 保存顺序和启停,variables.yml 保存模板变量;失配单向恢复,不生成旧宿主装配产物。
58
- - 🧩 **显式互斥**:同模块同组中任一卡声明互斥时,启用目标卡会原子关闭同组其他卡的总开关;重排不改变启用状态。
59
- - 🖥️ **可拖动悬浮工作台入口**:工作台经官方 `shell.overlay` 渲染悬浮触发器与 body portal 抽屉;按钮可拖动、位置存插件自己的 localStorage、窗口变化自动夹回可见区(不读宿主布局树,已移除 `sidebar.footer.action` 几何探针);五页(主会话/子代理/工具预览/技能设置/模块)在抽屉内渲染,抽屉用 fixed + z-index 置顶,不被宿主导航栏遮挡
60
- - 🧪 **条件与内容分离**:`if` 支持组合判断(另有 `else` 分支);注入动作支持 `static / first-turn-anchor / guide-auto / anchor-notice / placeholder / world-book`。旧 `custom-fallback` 拆为锚点条件与通知内容。
61
- - 🛡️ **失败不伤会话**:单条失败跳过 + `warnOnce`;配置错误挂载时 fail loud;`dedupe: session` 持久幂等
62
- - 🧭 **通用 instruction-hint 引擎**:模块可通过 `strategy: placeholder` 与 `fill: instruction-hint` 提示指令文件存在;实现位于 `engine/instruction-hint.mjs`。`layerSettings.pre-step.instructionHint` 可启用该能力,按模型可见 surface 去重,重挂不重复,被压缩遮蔽后才再次提示
63
- - 📦 **Bridge 载荷**:JSON 请求统一 32 MiB 硬上限并明确返回 413;角色卡原始图片走 64 MiB 流式通道,按 PNG 魔数识别。
64
- - 📂 **技能管理**:官方发现与会话快照统一技能来源、生效和遮蔽状态;单端开关写回技能文件。支持目录包与直属 Markdown 技能、创建、两种复制导入,以及用户根和引用根的可恢复删除;技能局部刷新保留其他页面草稿。
65
- - 🎭 **SillyTavern 导入**:JSON 预设、角色卡和独立世界书转换为本地预设——按官方顺序表保留启停,赋值模板运行时求值;不等价能力明确报告,采样参数由宿主管理
66
- - 🎴 **角色卡导入**:PNG/JSON/YAML 角色来源经统一预览后成为普通模块;PNG 保留原图,更新保留模块记忆与用户资产。
67
- - 📦 **预设交换**:文件夹、ZIP、原生 JSON/YAML 与 ST 来源共用识别、预览和完整候选安装;导出可选完整 ZIP 或仅定义 YAML。资源、覆盖及分享边界见 [资产交换文档](docs/asset-transfer.md)。
68
- - 📚 **世界书**:`character_book` 转 world-book 策略配置(`keys` 命中触发 / `constant` 常驻 / 正则键自动检测 / `selectiveLogic` 组合逻辑),与模块卡片同一存储与编辑(模块列表「世界书」过滤 + 批量启用/禁用)
69
- - 🛠️ **自定义工具**:module.yml `customTools` 段声明式定义模型工具(执行器 shell/http/delegate/fs/ask-user,`{{args.x}}` 参数插值);参数与输出经官方 `dsh-tools` 转换器物化为标准 JSON Schema,非法参数产生标准工具错误,delegate 经 `ctx.tools.execute` 嵌套调度走完整官方工具管线;`customTools.scope` 暂不支持(显式拒绝)
70
- - 🛡️ **子代理工具策略**:module.yml 顶层 `subagentToolPolicy` 段(opt-in)声明 ceiling、profiles、角色卡绑定、有序任务规则与受控模型扩权;`subagent` 固定走 spawn、`subagent_fork` 固定走 fork,按官方 `SubagentRun`/continuable 契约创建并在窗口内冻结 toolFilter;模型选择器和扩权参数在工具 body 前校验,模型路由经过 LLM preflight;UI 从官方 sessions snapshot 读取当前会话,并可编辑、停用、预览策略及查询存活 Agent 工具面
71
- - ♻️ **Session 日志读取**:引擎冷启动与幂等扫描统一走官方 `session.snapshotEvents()`(DSH `0.1.2-alpha.4+`),不再读取已移除的 `session.events` 数组。
72
- - 🧩 **模板变量**:顶层 `variables` 提供 `{{key}}` 插值,注入动作的 `config.variables` 可局部覆盖。正文、匹配词、分类阈值与模型偏好由规则或模板显式提供;业务配置为空就不生成对应内容,引擎不内藏默认锚句。
73
- - 💬 **会话变量工具**:`session_var`(list/get/set/clear)——模型维护角色状态(`{{心情}}` 等),会话级覆盖预设默认;ST 运行时宏(`{{lastusermessage}}` / `{{lastcharmessage}}`)从会话事件提取
74
- - 🧩 **工具按模块装配**:角色卡、世界书、会话变量、自定义工具分别由 `character-tools` / `world-book-tools` / `session-var-tools` / `tool-config-engine` 模块提供;不再维护重复的顶层工具开关
75
- - 📐 **显式按需装配**:空模块不自动附加增强能力;模块人设来自顶层 `persona`,官方工具与普通委派仍由会话原有预设提供。首轮门控、来源过滤、工具名单、深思门与进度节拍统一由 `rules` 声明;总入口负责编译调度,`engine/conditions/` 判断,`engine/actions/` 执行。
76
-
77
- ## Web 客户端结构
78
-
79
- 每条配置保留一张卡,复用原卡壳、折叠箭头和拖拽样式,指令文件卡置顶。卡内通过“规则 / JSON / 设置”平级侧边导航编辑,窄屏改为横向页签。**规则面板按条件作用域组织**:规则级 `if` 是一张条件卡,它管住的 `then` 节点在一段竖线作用域里各自成卡——动作卡与分支卡(卡头即「当 ⟨条件⟩ → ⟨动作⟩」);每张卡默认收起、卡头单行省略给出「条件 → 动作」一览,展开才编辑,`×` 删除整张卡,`then`/`else` 里的分支节点 `{if, then, else}` 可展开编辑、可继续嵌套。上移、下移与拖拽按钮位于卡头总开关旁。Linear 风格统一桌面控件为 28px、按钮与下拉为胶囊;短输入按字符宽度收紧,下拉按最长选项文案限宽,数字 96px,正文与 JSON 保留完整编辑宽度。粗指针的 44px 触控目标扩大控件本体,不覆盖外部空白。
80
-
81
- 规则编辑器通过 `/rules` 保存局部修改与完整文件版本,保留在途新输入、未知字段和未完成 JSON 草稿。动态注入支持 `if` / `then` / `else`(旧名 `when` / `do` 已退役,撞上会显式报错);固定注册的独占、抑制及安全守卫拒绝不支持的动态条件。具体支持范围见 [引擎复用指南](docs/engine-reuse.md#声明的条件与动作边界)。
82
-
83
- Web 客户端按四层组织:
21
+ ## 模块与工作台
84
22
 
85
23
  ```text
86
- src/client/
87
- ├─ app/ # SlotRegistry owner、工作台壳与五页组合
88
- ├─ data/ # typed bridge、Fields、状态 facade、保存与脏检测纯逻辑
89
- ├─ features/ # prompts / tools / subagents / skills / presets / characters
90
- └─ ui/ # 仅 props/callback 的共享交互与 CSS Modules
24
+ $DSH_HOME/.prompt-tool/
25
+ ├─ config.yml # 规则模块启用集合与主/子人设来源 ID
26
+ ├─ variables.yml # 全局变量,variables 映射
27
+ ├─ instructions.yml # 独立指令策略
28
+ └─ modules/<id>/
29
+ ├─ module.yml # 唯一完整定义
30
+ ├─ rules/ # 已验证的物化切片
31
+ ├─ memory.md # 模块私有记忆,按需读取
32
+ └─ data/ # 模块私有用户数据(账本等):不导出、覆盖保留
91
33
  ```
92
34
 
93
- 依赖方向固定为 `app → features → data/ui → shared contract`:跨领域组合只在 `app/workspace/pages/`,feature 不导入其他 feature 内部实现。控件由插件持有,不运行时加载 Harness Client 包;官方能力通过 Cordis 服务与 slot 接入,类型依赖保留。Client bridge 使用 `src/shared/bridge-contract.ts` 的 endpoint key 与 request/value map。样式按 owner 拆分,只共享 `--dsw-alias-*` 主题颜色,安装和释放随插件生命周期。
94
-
95
- 角色卡与世界书模型工具写入**该执行 Agent 实际配装的提示词层**(启用表 ∩ 磁盘,多个时取启用表第一个),不查询会话绑定的官方预设。保存等待物化完成;已保存但未生效会明确返回失败。失败定义保留诊断,方便修复。
96
- 完整的当前目录、slot 生命周期、状态边界、可访问性和维护约束见 [Web 客户端 UI 结构框架](docs/ui-architecture.md)。
97
-
98
- ### 配置卡与工具预览
99
-
100
- - 五页工作台保留搜索、展开和滚动位置;工具、人设、策略以及非法 JSON/数字输入可跨页继续编辑。存在未保存草稿时,模块切换会提示先处理,不会无声覆盖。
101
- - 配置保存与校验位于长列表操作区,失败就近显示;低频卡片操作收进菜单,删除和丢弃文件草稿需明确确认。窄容器自动换行,键盘操作、明暗主题和减弱动效均沿用宿主规范。
102
-
103
- - 参数在所属规则的动作中编辑,主/子代理模型参数使用 `request-params` 动作与受众条件。共享能力仍按实际 `modules` 装配显示,当前会话模型继续使用官方选择控件。
104
- - 「指令提示」统一通过「前置步骤 → 内容策略:动态填充 → 填充来源:指令提示」编辑,不再作为独立策略入口。指令文件正文和授权保存仍归独立文件通道,不复制进预设。
105
- - AGENTS.md / CLAUDE.md 这类指令文件复用普通配置卡组件,保留名称、路径、正文和后续官方注入的启停;位置、顺序、晋升、受众与模型范围由官方负责,不提供文件卡控制项。名称和启停落独立指令策略,正文就地编辑、**焦点离开卡片时自动写回原文件**(版本冲突保留草稿并提供「重新读取」,没有单独的保存按钮)。
106
- - 创建菜单始终提供全部层级模板、工具和可添加能力,不受当前列表筛选限制。创建后只展开目标卡片(当它落在当前筛选视野内),不改动层级筛选与搜索词;同一提示词模板可重复创建,自动分配不重复标识。空内容不等于删除,保存和后台刷新保留未完成草稿;工具草稿在层级/世界书筛选往返时不丢失。
107
- - 插件装配自身工具能力,官方文件系统与编辑工具仍由宿主预设提供。自定义模型工具经「添加能力 / 工具模块 → 添加工具模板 / 新建空白工具」配置名称、描述、参数、输出与执行器,保存前完整校验;不安装、连接或管理外部 MCP/DSH 插件。
108
- - 「工具预览」是独立顶层页,参照官方插件目录:顶部统一搜索、可折叠分组、右侧预设选择、双列展开详情卡,窄屏单列。卡片显示「模型可见」,不伪造插件运行状态。当前会话与所选预设分别读取:既有会话仍使用冻结 generation,修改预设只影响后续 generation;不会隐藏同名自定义工具或自动恢复会话。
109
- - 在工具链的 `tool-config-engine` 能力卡中配置哪些自定义执行器需要用户批准;缺少批准服务时拒绝执行。生成目录保持只读,仍由预设重建产生。
35
+ module.yml 支持 UI 保存与直接手改。rules/ 从完整定义分解,手改或失配会单向恢复;无效完整定义拒绝加载,不以切片反写。未知用户资产保留,模块关闭只撤回贡献。
110
36
 
111
- ## 项目架构
37
+ 工作台由官方悬浮入口(shell.overlay)或左侧栏「提示词工具」入口(sidebar.panellist 行点击直接打开)打开——两个入口打开同一个常驻抽屉,包含主会话、子代理、工具预览、技能设置和模块五页。模块页统一新建、启停、复制、导出、导入和删除。编辑模块通过请求头选择,不切换官方会话预设。
112
38
 
113
- 本项目的 Archify 交互式架构图保存在 [`project-architecture/`](project-architecture/):覆盖 React 工作台、loopback settings bridge、Plugin Runtime、Preset Compiler、Engine & Composition、Skills 与领域扩展以及 DSH Host 的运行链路。
39
+ 在 dsh-tui 中,`/settings` 的「常规」页有一节「提示词工具」,只含模块运行总开关(settings 文档里唯一的部署轴);模块参数、规则与技能仍走 `/prompt-tool` 命令或工作台。
114
40
 
115
- - [打开最终交互式架构图(v2)](project-architecture/project-architecture-v2.html)
116
- - [查看 Archify JSON 源规格](project-architecture/project-architecture-v2.json)
117
- - [查看本轮视觉检查收据](project-architecture/project-architecture-v2.visual-check.json)
41
+ 删除模块先在同卷隐藏 stage 里 rename,锁外再清理:rename 失败时原目录完整保留;清理失败时模块已移出,提示里会给出残留目录路径(清理未完成,内容可能不完整),刷新失败只影响列表、删除仍按成功处理。内置模块的用户副本删除后,重启会按缺失补建,这不是删除失败。若进程在 rename 后、清理前退出,隐藏残留目录会留在磁盘上,不会自动过期。
118
42
 
119
- `v2` 已按当前 `app / data / features / ui` 客户端结构更新,并通过 showcase 9/9 校验;无 `v2` 后缀的文件保留为首轮构图记录。本轮已使用 Microsoft Edge 完成 visual-check:containment/captures 均通过,保留 1440×900 与 2048×1320 的明暗截图及联系页;自动收据的 `visualReview` 仍为 `pending`,仅表示需要人工查看截图,不代表渲染失败。
43
+ 每张规则卡编辑完整条件树与动作;then/else 可嵌套,未知事实不当成否定成立。正文、状态分别做 CAS,后台刷新和请求期间的新输入保留。跨模块规则按配置序号排列,同组互斥由显式启用事务决定,排序不替作者选赢家。
120
44
 
45
+ 工具、人设、变量、策略沿用各自的共享草稿与保存边界。布局、无障碍、locale 和 typed bridge 规范见 [UI 框架](docs/ui-architecture.md)。
121
46
 
122
- ## 模块参数体系
47
+ ## 原生模块格式
123
48
 
124
- 初始化从包内 modules/ 补建缺失模块,已有目录不覆盖。包内内置模块三个:`ponytail`(懒惰资深工程师行为规则)、`tool-surface`(工具面收窄到常驻核心集,其余按需解锁)、`skill-surface`(拦掉全量技能目录注入,改按需发现)——后两个默认不启用,需在「模块」页启用并重启。materializeModule 原地校验恢复 rules/,只清理已知旧产物,保留记忆、技能、正文与用户资产。工具和子代理策略从完整定义内联装配。
125
-
126
- 部署 Config 使用 modulesEnabled 作为模块运行总闸:关闭仅撤回贡献,不清空文件。旧 writePreset 仅作输入兼容,双键冲突拒绝。编辑目标通过 x-module-id 传递,不切换或跟随官方会话预设。
127
-
128
- 模块行为由一份 `module.yml` 下发,参数所有者各自独立:
129
-
130
- | 层 | 职责 |
131
- |---|---|
132
- | `layerSettings.<层名>` | 模块共享参数;磁盘归属由参数目录的 `storageLayer` 固定,不随 UI 分组改变 |
133
- | `moduleConfigs` | 行级 config 直写通道(参数桥未覆盖的键:超时/环境白名单/ST 导入等),不锁定覆盖 UI 可管理参数 |
134
- | `rules` | 独立身份、条件树 `if` 与动作数组 `then` / `else`;注入正文与参数归相应动作 |
135
- | `configOrder` | 规则 ID 到序号的完整定义映射;运行切片中为 _settings.yml.rules[id].order,文件名不带序号 |
136
-
137
- ### 共享参数一览(全部可选,缺省按对应模块解释)
138
-
139
- | 分类 | 键 |
140
- |---|---|
141
- | 策略深度 | `maxDepth`,只约束已启用的插件子代理工具策略;普通官方委派由宿主管理 |
142
- | 指令提示 | `instructionHint`,默认关闭 |
143
- | 工具 | `toolGitBashEnabled` `customToolRequireApproval` |
144
-
145
- 以上共 4 个公开共享参数。模型参数属于 `request-params` 动作,主/子代理由条件区分;旧模型键与 15 个锚定/引导快捷键只供离线迁移读取,不再提供在线保存入口。无法等价承接的旧值明确拒迁,不丢弃也不静默激活。编辑器输出上限 `strReplaceEditorMaxOutputChars` 由宿主工具配置负责。
49
+ ```yaml
50
+ id: project-rules
51
+ name: 项目规则
52
+ modules: [rule-engine]
53
+ variables: {}
54
+ rules:
55
+ - id: project-context
56
+ enabled: false
57
+ then:
58
+ - id: inject
59
+ kind: inject-text
60
+ config:
61
+ layer: pre-step
62
+ strategy: static
63
+ position: after-user
64
+ dedupe: session
65
+ text: 请依据用户确认的项目约束执行。
66
+ ```
146
67
 
147
- > 首轮工具面与输出封顶、pre-step 来源名单、常驻工具白/黑名单、锚句、深思门与进度节拍通过 `rules` 声明(示例见 [engine 复用指南](docs/engine-reuse.md));子代理工具面仍由 `subagentToolPolicy` 实例策略授权。
68
+ 规则是唯一行为源;共享模型与能力参数保存于 layerSettings,人设、变量与自定义工具各有独立顶层段。根 [module.yml](module.yml) 从权威目录生成九层及27个共享参数参考,示例默认关闭。
148
69
 
149
- AGENTS.md 走「文件即真相」:文件集合、正文与版本不物化进生成目录,而是由宿主按本会话工作区现场解析(`$DSH_HOME/AGENTS.md` + 工作区 cwd→项目根链的 AGENTS.md/CLAUDE.md/AGENTS.local.md/CLAUDE.local.md);工作台中的文件卡指向原文件,卡片定义与正文都不进 `module.yml`。插件不写常驻受管块。
70
+ - 条件使用 if,动作用 then,另有 else;动作身份在完整规则树中唯一。
71
+ - 注入正文策略为 static、placeholder、context-activation;文本与长度分类、确认、工具名和受众由通用条件承担,正文、投递、请求与流控制由动作组合。
72
+ - 工具提示通过 tool-catalog 只读引用同规则工具可见面声明,自动列出常驻名单与发现工具;提示正文和投递由模块规则控制。
73
+ - 九个插入点没有跨层全局顺序;order 属于该官方位置,configOrder 管同点跨模块顺序。
74
+ - `dedupe: session` 看当前模型可见上下文,旧消息被压缩/替换遮蔽后可再次注入。
75
+ - 主/子模型卡各有5个路由/采样参数,在装配时生成受众限定请求规则;也可显式编辑 request-params,不回写宿主全局默认。
150
76
 
151
- 官方指令注入与逐文件开关:
77
+ 字段、空值、保存和安全边界见 [参数框架](docs/architecture-params.md),通道与生命周期见 [引擎指南](docs/engine-reuse.md) 和 [九层契约](docs/injection-point-contracts.md)。
152
78
 
153
- - 官方 `@deepseek-ai/dsh-agent-instructions` 负责发现、读取、预算、更新与压缩恢复,预设须保留官方指令行;插件只在消息进入会话前过滤,不再自行注入文件正文。文件可读不代表已经注入。
154
- - 指令文件卡保留名称、正文编辑和启停;关闭只拦截该文件**后续**的官方注入,历史正文不撤回,重新开启不强制重放。首次请求前关闭即可阻止可识别文件进入新历史;开关不阻止官方读取文件。
155
- - `$DSH_HOME/.prompt-tool/instructions.yml` 只保存 `files[fileId].enabled` 与 `name`,跨预设共享,**默认放行**。不再提供「独立指令文件来源」总开关或文件级位置、顺序、晋升、受众、模型范围;自定义消息仍用普通前置步骤配置。
156
- - 旧策略顶层 `enabled` / `defaults` 及文件级注入参数读取时忽略、下一次成功保存时清理;旧顶层关闭不会转换为逐文件关闭。`module.yml#agentsHints` 仍不生效,策略缺失不因读取自动创建。
157
- - 过滤覆盖官方基线、附加、更新和移除消息,并同步对应 `source.changes`。无法可靠分段的官方内容原样放行并诊断;不识别的文件身份也保持官方内容,不新增远程来源管理。已被官方预算省略的内容不由插件补回。
158
- - 预设级 `instructionHint` 保持可选、默认关闭;启用后先过滤,再把剩余符合条件的官方全文转换为路径提示。它不替换已经进入历史的全文。决策边界见 [ADR-0004](docs/adr/0004-official-instruction-filter.md)。
79
+ 需要“先发锚句、确认后注入正文”时,在同规则中用 `anchor.after.action` 引用锚句动作;确认只读取实际投递后的当前可见输出。默认持续等待、下次正常请求再注入;兜底次数和续跑均须显式声明。示例见 [模板16](templates/16-custom-fallback.yml),直接匹配本批用户消息见 [模板14](templates/14-first-turn-anchor.yml)。旧专用策略与参数已直接替换,不提供兼容入口,也不自动改写已有用户模块。
159
80
 
160
- 指令文件正文属于用户自己的文件,不受预设生命周期管辖。工作台按**打开时解析出的会话工作区**读取文件快照(正文 + 文件身份 + 字节版本 + 读取状态一次取回),正文在**焦点离开卡片**(或列表「保存」)时写回原文件:
81
+ ## 两级持久变量
161
82
 
162
- - 未修改的文件不写盘;预设的 debounce 自动保存与预设切换都不写文件,切换预设只保留文件草稿。
163
- - 每个请求带读取时的 `expectedRevision` 与工作区 `contextId`;外部改动或工作区变化返回 409,草稿保留并提示「重新读取」,不静默覆盖磁盘新版本。
164
- - 读取失败(不可读/超限/文件消失)与「读取成功的空文件」严格区分:前者不可编辑、不可保存,不用空正文掩盖错误。
165
- - 原子写入(tmp + rename,保留原权限),失败保留原文件并清理临时文件;正文不受预设变量插值影响。
83
+ 模块 variables 覆盖同一 DSH_HOME 的全局变量。空字符串是有效值,删除模块键才回落全局。同模块的主会话与子代理共享,结束会话、压缩、卸载或重挂不清空。变量内容更新不重挂 Agent,下一求值读取新快照。
166
84
 
167
- 模型参数按模块独立保存,不自动回写宿主全局默认。主模型参数作用于主会话请求;子模型 provider/name 与采样参数作用于本地子代理的实际请求,不改写普通官方委派的 spawn 预检。
85
+ **普通规则手动建立变量;ST 导入才自动登记缺失裸引用为空占位。** 模板 WHO、stateKeys 等需在变量卡建立;动作 config.variables 已退役。全局值不随模块导出。
168
86
 
169
- | 段 | 键 |
170
- |---|---|
171
- | `layerSettings.agent-request`(主对话) | `modelProvider` `modelName` `modelReasoningEffort` `modelTemperature` `modelMaxTokens` |
172
- | `layerSettings.subagent-start`(子代理) | `subagentModelProvider` `subagentModelName` `subagentReasoningEffort` `subagentTemperature` `subagentMaxTokens` `maxDepth` |
87
+ 需要赋值时显式设置 `params.templateEvaluation: true`,使用 module/global 的 set/get/add/inc/dec。一张模板可读两域但只写一域,所有实际读取域都校验版本。资格、解析和预算检查先于提交;同一次真实执行跨 assembly/pre-step/重挂不重复自增。发布失败只重试发布,不承诺任意跨进程崩溃后的 exactly-once。
173
88
 
174
- 读取当前结构后展平到内部 EngineParams,保存只更新 `storageLayer` 指定的层。旧顶层 `params` / 模型段不参与运行参数,规则快捷键的兼容范围见[参数框架](docs/architecture-params.md)。人设独立写在顶层 `persona` 段,由模块配装通道在 Agent scope 注册。示例:
89
+ ## 独立人设
175
90
 
176
91
  ```yaml
177
92
  persona:
178
- prefix: You are a coding agent powered by the {{model}} model.
179
- suffix: Your working directory is {{cwd}}.
180
- # complete: true # prefix 独占整个 system prompt
181
- # includeRuntimeContext: false # 抑制该 scope 的动态 runtime-context 快照
93
+ main:
94
+ prefix: 你是项目助手。
95
+ complete: false
96
+ subagent:
97
+ suffix: 返回可核验的结果。
182
98
  ```
183
99
 
184
- 工作台「模型路由」卡顶部另有**当前会话**区(仅主对话作用域):显示活动会话的模型/思维程度(会话 `modelSelection` 投影,缺省回退宿主默认),模型下拉展示全部可用模型并按服务商分组,选择模型时自动回写对应服务商;切换走官方 `session.selectModel`——对当前会话立即生效并被宿主持久化为新会话默认,与官方模型选择器双向同源;子代理会话与宿主默认场景不支持会话级切换。预设参数非空时按请求覆盖会话选择(参数桥优先级不变)。
185
-
186
- 模块编辑选择与官方会话预设独立。切换编辑模块只改变请求目标;未指定目标时由服务端解析默认目录,bootstrap 的模块身份、参数、变量与配置卡来自同一目录。启用哪些模块由 `config.yml.enabled` 决定。
100
+ 人设卡为主会话和子代理各提供一个来源下拉,默认“官方”,也可分别选择一个模块。正文仍保存在各模块的 persona.main/subagent;config.yml 的 personaSources 只保存两个来源模块 ID,选择人设不自动启用该模块的 rules。
187
101
 
188
- > 根目录 [module.yml](module.yml) 覆盖 4 个公开共享参数与九层规则。`pnpm rebuild:preset-template` 从权威契约重建;规则默认关闭,共享参数按需取消注释。
102
+ 运行时只读取所选模块对应受众的字段,不跨模块逐字段合并。选中字段省略时继承已有声明(同层被接住的声明、祖先的官方 persona 行,最后是根部署人设),显式空文本清空,complete:false 解除人设独占;includeRuntimeContext:false 单独抑制动态上下文。人设不进入 rules 数组或排序,rules/_settings.yml 只保存其校验投影。人设与启用规则的 complete 冲突仍在撤旧之前检查,失败保留上次有效配装。自定义文本读取所选来源模块的变量,继承官方正文不重新执行为模板。
189
103
 
190
- ## 提示词配置(九个官方插入点)
104
+ ## 按需工具
191
105
 
192
- | `layer` | 官方通道 | 关键参数 |
193
- |---|---|---|
194
- | `pre-step` | `agent/pre-step` 消息批(默认层) | `position / dedupe / promotion / audience / modelScope / strategy` |
195
- | `system-section` | `ctx.systemPrompt.section` 静态段 | `order / text / templateFile / variables / params.complete / params.sectionName` |
196
- | `runtime-context` | `ctx.systemPrompt.context` 动态快照 | `order / text / variables / params.contextName` |
197
- | `agent-request` | `agent/request`(LlmCallConfig) | `params.patch`(浅合并)/ `params.replace`(整体替换) |
198
- | `llm-stream` | `llm/stream`(流包装) | `params.mode=pass\|replace` |
199
- | `tool-pipeline` | `tools/*`(pre/execute/post) | `params.toolNames`、`preDecision=allow\|deny\|ask`、`postAction=accept\|replace\|block` |
200
- | `turn-stop` | `agent/turn-stopping` | 条件命中后通过 steer 继续;每轮1次、每会话3次上限 |
201
- | `subagent-start` | `subagent/start` + `Agent.inject` | 子代理事件匹配与注入文本;模型/深度在卡内共享设置 |
202
- | `subagent-end` | `subagent/end` + 可选 `Agent.inject` | `params.action=observe\|inject-main`,后者投递到所属主会话 |
203
-
204
- 九个插入点彼此独立,没有跨层全局运行顺序。模块配置在同一插入点、位置内按 `configOrder` 序号排列;`system-section` 与 `runtime-context` 的 `order` 保留官方定位语义。
205
- UI / 写盘按上表分组;这是展示顺序,不是模型提示词优先级。详细支持字段、限制与官方依据见[九层对照](docs/injection-point-contracts.md)。
206
- 模型实际收到的提示词文本顺序更接近 `system-section → runtime-context → pre-step`;`agent-request` / `llm-stream` / `tool-pipeline` 是控制通道。
207
-
208
- 主会话与子代理的配置列表沿用原模块页的拖拽按钮样式,也可聚焦按钮后用上下方向键移动。“当前模块”范围保留配置编辑与本模块排序;点击“跨模块排序”后,同一列表显示已启用模块中符合当前受众和筛选的配置摘要,支持跨模块拖拽和上下移,隐藏配置保留原有槽位。进入前保存当前模块配置草稿,字段等草稿未完成时拒绝切换;返回当前模块时重新读取。模块页不再另设排序区。服务端按模块 ID+配置 ID 写回轻量序号,拒绝未知、重复身份和过期版本,不接收正文或任意序号。新启用模块的未编号或冲突配置接在尾部,重复启用保序,详见 [排序决策](docs/adr/0006-module-config-order.md)。
209
-
210
- - `mergeMode`:`separate`(默认)同位置多条为独立消息;`merged` 同位置拼接为一条
211
- - `order`:官方 system/context 位置、无模块来源的独立引擎与触发器、ST 世界书预算仍保留各自语义,不由排序界面改写
212
- - 文本插值:`{{key}}` 全层支持——配置/预设 `variables` 优先,ST 运行时宏(lastusermessage 等)次之,内置 `{{DSH_HOME}}/{{WORKSPACE}}/{{CWD}}` 兜底,未注册保留字面(system-section 注册期无会话时运行时宏替换为空,不残留)
106
+ | 能力 | 工具 |
107
+ |---|---|
108
+ | module-rule-tools | module_rules_read / module_rules_edit |
109
+ | module-variable-tools | module_variables |
110
+ | module-file-tools | module_file_read / module_file_append |
111
+ | module-manifest-tools | module_manifest |
112
+ | module-import-tools | module_import |
113
+ | tool-config-engine | customTools 中的实际工具 |
213
114
 
115
+ 完整规则工具先读原始树与版本,再提交合法完整候选;删除整规则需显式 rule:null。变量工具提供 global/module 的 list/get/set/delete,set 必须显式字符串。模块私有文件(memory.md、assets/ 只读、data/ 只追加)由 module_file_read/append 读写,不自动注入;module_manifest 按 assets/manifest.yml 做 next/check/apply,只写 data/、不覆盖。
214
116
 
215
- ## SillyTavern 导入
117
+ 工具目录仅注册已声明能力,晚到 provider 与 disposer 按原生命周期处理。模块工具的主语由**这次调用显式声明的 `moduleId`** 决定:不传即没有目标、直接拒绝,不回退装配记录首项或包内默认模块;执行 Agent 已启用的规则模块只作拒绝文案里的候选提示,不是目标(人设来源是独立引用,同样不决定写入目标)。`expectedModuleId` 是桥端对请求头声明的一致性复核,与工具侧的主语选择是两套独立判据。工具只能读写模块存储根下 `module.yml` 所在的既有模块;模块内文件限定 memory.md、assets/(只读)、data/(只追加),不访问任意路径。自定义工具继续支持 shell/http/delegate/fs/ask-user,并保留官方批准、拒绝与取消管线。
216
118
 
217
- 工作台「模块」页按内容识别原生模块与 SillyTavern 来源;ST JSON/YAML 预设卡片经预览确认后,按注入层级映射为本地模块:
119
+ ## SillyTavern 与资产交换
218
120
 
219
- - `prompts[]` → `rules[].do` 中的注入动作:system 角色进入 `system-section`,其余进入 `pre-step`;官方 `prompt_order[].order[]` 决定启停与相对顺序,深度位置保留来源并报告降级
220
- - 采样参数(`temperature` / `openai_max_tokens` / `reasoning_effort`)**剥离**——模型参数统一由「模型设置」UI / 宿主默认管理
221
- - ST 变量:保留可启停的赋值模板,在运行时顺序求值;声明变量在合并和角色卡应用时保持局部绑定
222
- - ST 管理工具:始终装配 `character-tools`、`session-var-tools` 与 `tool-config-engine`
223
- - `enable_web_search`:`true` → 本插件**不再组装 web 工具行**(`tool-web` 已随预设解耦从模块库退役,联网能力由会话原有预设提供),只在转换报告里如实提示;`false` → 产出三条规则(`assembly` 呈现剔除 + `sdk-strip` 裁 `tools:sdk` 正文 + `guard` 执行层拒绝,共用同一份 `deny: [web_search, web_fetch]`),PTC 下同样生效
224
- - 含有效 `character_book` 条目时自动追加 `world-book-tools` 模块,使导入预设可直接调用世界书管理工具
225
- - 世界书条目级条件:`delayUntilRecursion`(延迟到递归扫描的层级池)、`useGroupScoring`(组内评分淘汰)、`matchCreatorNotes` / `matchCharacterDepthPrompt`(按需扫描卡片备注与深度提示词)按 ST 语义求值;`characterFilter`(角色/标签过滤)、`automationId`(STscript 自动化)、`outletName` 与向量检索**不实现**,只保留来源事实并在预览卡里逐条告警
226
- - 触发键里的 ST 宏(例如只存在于 ST 全局 persona 的 `{{user}}`)登记为「模板变量」空占位并产出诊断:未赋值时该键不参与匹配(不会退化成字面量误判),在模板变量里赋值后按既有匹配路径生效
227
- - 角色卡 `extensions.depth_prompt` 保留为一条**默认禁用**的 pre-step 配置(ST 只在群聊自动注入),可在工作台手动启用
228
- - `modules` 按需装配:`rule-engine` 与上述 ST 管理工具承接转换产物;含 system-section 时补 `persona`(`complete: false` 允许 system 段生效);含有效世界书条目时补 `world-book-tools`
121
+ ST JSON 预设、PNG/JSON 角色卡和独立世界书,经统一预览/确认/原子候选安装成为普通模块。默认同名另存,不自动启用。来源变化、目标变化或预览过期须重读,不能重放旧确认。
229
122
 
230
- 转换结果是一个普通模块(id 由文件名生成),可在工作台「模块」页的模块列表中直接启用。字段级参数对照与完整示例见 [SillyTavern.md](docs/SillyTavern.md)。
123
+ 世界书生成 context-activation,显式 batch/history 扫描、具名副键逻辑、概率、候选组、递归及时间窗;来源字段只在 source.original 记录。ST 变量宏转为原生模板操作,导入期不执行赋值。
231
124
 
232
- ### 角色卡(PNG / JSON)导入
125
+ outlet/vectorized/triggers 不能等价执行,相关规则禁用并报告;角色过滤、自动化、深度插入、预算、群聊和脚本都有明确限制。完整映射及报告边界见 [SillyTavern 导入](docs/SillyTavern.md)。
233
126
 
234
- 工作台「模块」页将角色卡作为来源导入普通 `.prompt-tool/modules/<id>/`:
127
+ 模块导出分享完整定义和允许的附件,不分享全局变量或私有 memory.md。旧私有记忆标记必须显式处理,不靠删除标记继续导出。路径、链接、体积、覆盖和备份边界见 [资产交换](docs/asset-transfer.md)。
235
128
 
236
- - **PNG**:`ccv3` 优先 / `chara` 兜底;按魔数识别并受限解码,原始文件先暂存、预览确认后入库,保留原图。
237
- - **JSON/YAML**:支持 ST 角色数据和自包含原生角色片段。批次逐张预览,不把多份来源合并成一张角色卡;所有大小的文件都先预览再提交。
238
- - 正文映射:`first_mes` → 开场白(`dedupe: session`)、`alternate_greetings` → 备用开场白、
239
- `description/personality/scenario` → 角色设定;采样参数剥离(模型设置 UI 管理)
240
- - **统一模块身份**:人设、开场白和世界书写完整 module.yml,规则切片与其他模块一致;没有角色专属目录、前缀或登记
241
- - **模块记忆**:memory.md 属于模块,更新保留本地记忆和用户资产;world_book_read_memory 按需读取,不自动注入
129
+ ## 升级与旧格式
242
130
 
243
- ### 世界书(world-book 策略)
131
+ 原生格式是破坏性切换:旧 world-book/ST 运行字段、动作局部变量、旧工具能力和扁平 persona 明确拒绝。重新导入原始标准来源,或使用内置 [dsh-module 技能](skills/dsh-module/SKILL.md) 在用户授权下显式转换。插件不扫描改写用户目录、不恢复旧会话变量、不提供自动迁移器。其它历史参数的白名单边界见 [旧格式与显式转换](docs/architecture-params.md#旧格式与显式转换)。
244
132
 
245
- `character_book` 条目转 world-book 策略配置(与普通模块同一存储/编辑):
133
+ ## 技能与指令文件
246
134
 
247
- - **ST 注入语义**:常驻候选或主键命中,再按副键逻辑、概率、分组与时序筛选;非常驻无主键不注入;原生手写 world-book 约定保持不变
248
- - **匹配选项**:`caseSensitive` / `wholeWords`;只有 `/pattern/flags` 形式识别为正则,其余为字面键
249
- - **管理**:模块列表顶部下拉选「世界书」过滤(完整模块卡片编辑 + 批量启用/禁用);
250
- 模型工具 world_book_list/upsert/delete(note 追加模块记忆)与 world_book_read_memory(按需读取)
251
- - **ST 变量**:赋值不在导入时执行;local/global 分表但只在会话内有效,嵌套宏有循环与大小保护。
252
- 深度历史位置、system 角色、token 预算和 ST 扩展脚本不具备完整等价性,详见兼容边界
253
- - **会话变量**:`session_var` 工具(list/get/set/clear)维护角色状态(会话级覆盖预设默认,
254
- 结束即失);跨会话文本通过 note 保存在模块 memory.md,读取失败会明确报错
135
+ 技能保留在实际官方/用户来源目录。管理页复用官方发现与监听,按会话快照显示生效、遮蔽和未确认状态;开关写官方 frontmatter 调用策略,单端修改保留另一端和未知字段。创建、引用、导入及可恢复删除见 [技能管理](docs/skills-management.md)。
255
136
 
256
- 详细转换规则见 [SillyTavern.md](docs/SillyTavern.md)。
137
+ AGENTS.md/CLAUDE.md 及 local 变体正文属于用户文件。编辑需上下文白名单、用户授权和字节版本一致;读取失败不能当空文件覆盖。显示名和后续注入开关归独立策略,关闭只拦未来可识别官方消息,不撤历史、不补官方预算,不复制正文到模块。
257
138
 
258
139
  ## 开发与验证
259
140
 
260
- ```sh
261
- pnpm install && pnpm build
262
- pnpm test # 全量契约与行为测试(隔离 cwd 运行):参数契约/注入装配/六插入点/生成链路/引擎语义/组合重建/模型路由/UI 契约/安全边界
263
- pnpm typecheck && pnpm lint
264
- pnpm verify:host # 官方包范围、安装版本、解析目标、类型/运行时依赖与 Client 模块边界
265
- pnpm sync:yaml # 刷新 engine/vendor/yaml(生成目录运行时 YAML 解析器)
266
- ```
267
-
268
- 测试由 `scripts/run-tests.mjs` 启动:先跑 build,再以独立临时 cwd 与 TEMP/TMP 启动 Node 内置 test runner,用例路径为绝对路径,避免相对 cwd 的测试污染仓库。
141
+ 在本仓库按 AGENTS.md 从隔离目录启动命令:
269
142
 
270
- 依赖升级后的验证顺序:`pnpm install` → `pnpm verify:host` → `pnpm typecheck && pnpm lint` → `pnpm test`。官方源码联调请使用不入库的显式本地 override,不要恢复 `pnpm-workspace.yaml` 里的 `link:` 默认配置。
271
-
272
- 发布类型声明通过 `deps.dts.neverBundle` 引用官方 SDK,不内联其品牌类型与相对模块扩充;公开类型引用的包须声明为生产或 peer 依赖,不能仅存在于 devDependencies。`deps.onlyBundle` 显式约束内联依赖(服务端为空,客户端仅 `clsx`),新增依赖需重新核对打包边界。客户端仍保留宿主 loader 要求的 CJS 协议,不为消除通用 ESM 建议而切换格式。
273
-
274
- ## 排障:插件未加载时
275
-
276
- 启动日志出现 `dsh: skipping profile bundle "dsh-plugin-prompt-tool"` 时,插件整体未加载,预设种子补建也不会运行。插件启动只诊断缺失 Web 能力,不写 profile manifest 或修复包链接。按顺序检查:
277
-
278
- 1. **看 bundles 列表**:`<DSH_HOME>/profiles/<name>/package.json` 的 `dsh.profile.bundles` 是否含 `dsh-plugin-prompt-tool`。
279
- 2. **体检依赖链接**(只读、零写入):
143
+ ```powershell
144
+ $Repo = 'D:\AI\GitHub\dsh-plugin-prompt-tool'
145
+ Set-Location 'D:\AI\workspase\_temp'
146
+ pnpm --dir $Repo typecheck
147
+ pnpm --dir $Repo lint
148
+ pnpm --dir $Repo test
149
+ pnpm --dir $Repo build
150
+ git -C $Repo diff --check
151
+ ```
280
152
 
281
- ```powershell
282
- pnpm repair:profile -- --profile web --dry-run
283
- ```
153
+ 涉及分发或宿主接入另执行 verify:host、verify:pack;参考模板用 rebuild:module-template,追加 `-- --check` 检查漂移。test 脚本先 build,再以独立 cwd/TEMP/TMP/DSH_HOME 运行 Node 测试。
284
154
 
285
- 它按 dsh 同一口径(`createRequire(<profile>/package.json).resolve.paths`)逐项判定,并额外报出**链接目标是否存在**——「链接在、目标不在」的悬空链接正是最常见的失败形态(例如相对深度算错一层)。
286
- 3. **修复**:体检命令始终只读。缺失依赖或链接交给官方插件管理器;在 Harness 中使用 `plugin_manager` 安装或管理 bundle,CLI 的依赖修复入口为:
155
+ 源文件通过 package scripts 生成 lib 和 YAML vendor 快照,不手改构建产物。永久测试仅保留注入行为、写盘语义、bridge 载荷、安全拒绝的公共接口回归,期望来自独立真值;临时探针及纯旧名消失检查不进入测试套件。
287
156
 
288
- ```powershell
289
- dsh plugin --profile web install
290
- ```
157
+ ## 排障
291
158
 
292
- 替换已安装包后需要用户重启 DSH;插件不自动重启服务。
159
+ `skipping profile bundle` 表示插件未加载,补建和工作台也不会运行。先检查官方插件清单与依赖解析;`pnpm --dir $Repo repair:profile -- --profile <name> --dry-run` 只做体检,修复走官方插件管理器。插件不会自行改 manifest、包链接、停止或重启服务。
293
160
 
294
161
  ## 许可
295
162
 
296
- 插件本体 MIT(Czerror)。`engine/` 中移植自 [dsh-anchored-standard](https://github.com/xiaobright/dsh-anchored-standard) 的模块,其上游版权与 MIT 许可保存在 [engine/THIRD_PARTY_LICENSES](engine/THIRD_PARTY_LICENSES),随包发布并由组合行的包名说明符直接引用(不再物化到预设根);`preset/` 下 cordis 模板与脚本基于 DeepSeek Harness 官方 Standard 等预设修改。上游预设本体不再随本包分发。
163
+ 插件本体 MIT(Czerror)。移植能力的上游版权和许可保存在 [engine/THIRD_PARTY_LICENSES](engine/THIRD_PARTY_LICENSES),随包发布。上游预设本体不随本包分发。
@@ -1,32 +1,11 @@
1
1
  import { labelOf, requireString } from './shared.mjs'
2
- import { createTurnStopBudget, pluginMessage } from '../layers.mjs'
2
+ import { pluginMessage } from '../layers.mjs'
3
+ import { pluginKind } from '../source-kind.mjs'
3
4
 
4
5
  export function prepareAppendContext(action, plugin) {
5
6
  const label = labelOf(action)
6
7
  const text = requireString(action.text, `${label}.text`, plugin)
7
8
  if (text.length === 0) return
8
- if (action.mode === 'continue') {
9
- return (_ctx, { warnOnce, on, collect, take }) => {
10
- const budget = createTurnStopBudget()
11
- collect(on('agent/turn-stopping', ({ agent, turn } = {}) => {
12
- try {
13
- if (typeof action.match === 'function' && action.match(agent, turn) !== true) return
14
- const session = agent?.session
15
- if (session?.id === undefined || typeof agent.steer !== 'function') return
16
- const entry = budget.entry(session.id, turn)
17
- if (!budget.available(entry, turn) || !take({ agent })) return
18
- // 计数在 steer 之前落账:steer 抛错也不允许下一步重试越过预算。
19
- budget.claim(entry, turn)
20
- // 身份归本动作:复用 pluginMessage 的形状,但 source.plugin 必须是动作命名空间
21
- // (层模块的 pluginMessage 用 layers 自己的身份,那不是本动作的名字)。
22
- const message = pluginMessage(`action-${label}`, text, `${label} continue`)
23
- agent.steer({ ...message, source: { ...message.source, plugin: label } })
24
- } catch (error) {
25
- warnOnce(`${plugin}: append-context(continue) action ${label} failed: ${String(error?.message ?? error)}`)
26
- }
27
- }))
28
- }
29
- }
30
9
  // 追加上下文:只回 user 角色的 durable 通知(宿主把 additionalContexts 落成 user 消息)。
31
10
  return (_ctx, { warnOnce, on, collect, take }) => collect(on('tools/post-execute', async (exec, result, next) => {
32
11
  const decision = await next()
@@ -37,7 +16,7 @@ export function prepareAppendContext(action, plugin) {
37
16
  // 裸 `plugin` 会被会话格式校验拒绝,这条 durable user 通知就落不了盘。
38
17
  const notice = {
39
18
  ...pluginMessage(`action-${label}`, text, `${label} context`),
40
- source: { kind: `plugin:${label}`, plugin: label, form: 'notice', summary: `${label} context` },
19
+ source: { kind: pluginKind(label), plugin: label, form: 'notice', summary: `${label} context` },
41
20
  }
42
21
  const updated = { ...decision, additionalContexts: [...(decision.additionalContexts ?? []), notice] }
43
22
  return take(exec) ? updated : decision