@dsh-workbench/core 0.3.10 → 1.0.0-beta.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 (234) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -105
  3. package/bin/dsh-workbench +132 -31
  4. package/bin/dsh-workbench.cmd +5 -0
  5. package/bin/opencli-isolated +3 -2
  6. package/bin/opencli-isolated.mjs +44 -0
  7. package/bin/opencli-node-mode.cjs +1 -0
  8. package/bin/seed-workshop-windows.mjs +307 -0
  9. package/client.js +8192 -4904
  10. package/cordis.patch.yml +62 -37
  11. package/dist/client/client.body.js +8192 -4904
  12. package/dist/client/index.js +7186 -3898
  13. package/dist/host/index.js +7277 -6956
  14. package/dist/types/app/client.d.ts +3 -1
  15. package/dist/types/app/host.d.ts +2 -1
  16. package/dist/types/app/layouts/approval-detail.d.ts +3 -0
  17. package/dist/types/app/layouts/env-gate/boot-gate.d.ts +1 -12
  18. package/dist/types/app/layouts/env-gate/gate-text.d.ts +2 -1
  19. package/dist/types/app/layouts/market/DiscoverPanel.d.ts +8 -0
  20. package/dist/types/app/layouts/market/add-module-text.d.ts +1 -1
  21. package/dist/types/app/layouts/market/discover-categories.d.ts +8 -0
  22. package/dist/types/app/layouts/market/discover-confirm.d.ts +14 -0
  23. package/dist/types/app/layouts/market/discover-detail.d.ts +12 -0
  24. package/dist/types/app/layouts/market/discover-dialogs.d.ts +7 -0
  25. package/dist/types/app/layouts/market/discover-doc.d.ts +18 -0
  26. package/dist/types/app/layouts/market/discover-init-dialog.d.ts +10 -0
  27. package/dist/types/app/layouts/market/discover-rows.d.ts +24 -0
  28. package/dist/types/app/layouts/market/discover-sources-dialog.d.ts +16 -0
  29. package/dist/types/app/layouts/market/discover-states.d.ts +22 -0
  30. package/dist/types/app/layouts/market/discover-toolbar.d.ts +23 -0
  31. package/dist/types/app/layouts/market/discover-versions.d.ts +9 -0
  32. package/dist/types/app/layouts/market/discover-view.d.ts +38 -0
  33. package/dist/types/app/layouts/market/market-header.d.ts +13 -0
  34. package/dist/types/app/layouts/market/panel.d.ts +1 -1
  35. package/dist/types/app/layouts/market/use-add-module.d.ts +1 -1
  36. package/dist/types/app/layouts/market/use-discover.d.ts +72 -0
  37. package/dist/types/app/layouts/market/use-module-versions.d.ts +6 -2
  38. package/dist/types/app/layouts/rightbar/MarketView.d.ts +6 -3
  39. package/dist/types/app/layouts/rightbar/Rightbar.d.ts +1 -1
  40. package/dist/types/app/layouts/rightbar/board-shape.d.ts +1 -14
  41. package/dist/types/app/layouts/rightbar/market-act.d.ts +6 -3
  42. package/dist/types/app/layouts/rightbar/market-busy.d.ts +0 -22
  43. package/dist/types/app/layouts/rightbar/market-change.d.ts +1 -1
  44. package/dist/types/app/layouts/rightbar/market-hint.d.ts +1 -7
  45. package/dist/types/app/layouts/rightbar/market-plugin-rows.d.ts +0 -7
  46. package/dist/types/app/layouts/rightbar/market-row-icon.d.ts +1 -1
  47. package/dist/types/app/layouts/rightbar/market-row-types.d.ts +2 -2
  48. package/dist/types/app/layouts/rightbar/market-rows.d.ts +1 -1
  49. package/dist/types/app/layouts/rightbar/market-section-icon.d.ts +1 -1
  50. package/dist/types/app/layouts/rightbar/market-settle-hold.d.ts +2 -0
  51. package/dist/types/app/layouts/rightbar/market-settle.d.ts +17 -0
  52. package/dist/types/app/layouts/rightbar/market-shared-rows.d.ts +1 -1
  53. package/dist/types/app/layouts/rightbar/market-update-verdict.d.ts +31 -0
  54. package/dist/types/app/layouts/rightbar/market-view-text.d.ts +8 -1
  55. package/dist/types/app/layouts/rightbar/market-workbench-row.d.ts +1 -1
  56. package/dist/types/app/layouts/rightbar/store.d.ts +2 -0
  57. package/dist/types/app/layouts/sidebar/LongTaskDot.d.ts +6 -0
  58. package/dist/types/app/layouts/sidebar/LongTaskHover.d.ts +6 -0
  59. package/dist/types/app/layouts/sidebar/edition-boot.d.ts +6 -0
  60. package/dist/types/app/layouts/sidebar/edition.d.ts +5 -0
  61. package/dist/types/app/layouts/sidebar/use-attention.d.ts +0 -4
  62. package/dist/types/app/layouts/sidebar/workshop-preset.d.ts +2 -0
  63. package/dist/types/app/layouts/workbench-settings/AdapterSetItem.d.ts +5 -0
  64. package/dist/types/app/layouts/workbench-settings/ConfigSyncItem.d.ts +5 -0
  65. package/dist/types/app/layouts/workbench-settings/ConfigSyncRows.d.ts +11 -0
  66. package/dist/types/app/layouts/workbench-settings/NewWorkbenchItem.d.ts +5 -0
  67. package/dist/types/app/layouts/workbench-settings/SettingsItem.d.ts +8 -0
  68. package/dist/types/app/layouts/workbench-settings/SidebarEditionItem.d.ts +5 -0
  69. package/dist/types/app/layouts/workbench-settings/WorkbenchSettingsSection.d.ts +5 -0
  70. package/dist/types/app/units/manifests.d.ts +1 -1
  71. package/dist/types/{app/units → kernel/client}/registry.d.ts +1 -1
  72. package/dist/types/kernel/contract/bundle-install.d.ts +2 -0
  73. package/dist/types/kernel/contract/config-sync.d.ts +2 -0
  74. package/dist/types/kernel/contract/diy.d.ts +1 -0
  75. package/dist/types/kernel/contract/dsh-plugins.d.ts +2 -0
  76. package/dist/types/kernel/contract/index.d.ts +4 -0
  77. package/dist/types/kernel/contract/long-tasks.d.ts +2 -0
  78. package/dist/types/kernel/contract/market-index.d.ts +2 -0
  79. package/dist/types/kernel/contract/platform.d.ts +1 -0
  80. package/dist/types/kernel/contract/preflight-wake.d.ts +2 -0
  81. package/dist/types/kernel/contract/profile-create.d.ts +2 -0
  82. package/dist/types/kernel/contract/sidebar-edition.d.ts +2 -0
  83. package/dist/types/kernel/contract/unit-manifests.d.ts +2 -0
  84. package/dist/types/{shared/api → kernel}/host/mount-units.d.ts +2 -1
  85. package/dist/types/modules/panels/client.d.ts +1 -1
  86. package/dist/types/modules/panels/model/approval.d.ts +4 -8
  87. package/dist/types/modules/panels/model/diy-browser-tools.d.ts +1 -1
  88. package/dist/types/modules/panels/model/diy-changelog.d.ts +2 -0
  89. package/dist/types/modules/panels/model/diy-context.d.ts +20 -18
  90. package/dist/types/modules/panels/model/diy-page.d.ts +4 -2
  91. package/dist/types/modules/panels/model/diy-record-open.d.ts +0 -15
  92. package/dist/types/modules/panels/model/diy-record-text.d.ts +0 -2
  93. package/dist/types/modules/panels/model/diy-record.d.ts +1 -31
  94. package/dist/types/modules/panels/model/diy-report.d.ts +6 -7
  95. package/dist/types/modules/panels/model/diy-tools.d.ts +1 -0
  96. package/dist/types/modules/panels/model/long-task-tools.d.ts +0 -11
  97. package/dist/types/modules/panels/model/market-dependency-update.d.ts +15 -0
  98. package/dist/types/modules/panels/model/market-dependency.d.ts +15 -10
  99. package/dist/types/modules/panels/model/market-discover-routes.d.ts +3 -0
  100. package/dist/types/modules/panels/model/market-discover.d.ts +33 -0
  101. package/dist/types/modules/panels/model/market-dispatch.d.ts +4 -3
  102. package/dist/types/modules/panels/model/market-env.d.ts +2 -3
  103. package/dist/types/modules/panels/model/market-registry.d.ts +3 -3
  104. package/dist/types/modules/panels/model/market-restart.d.ts +1 -1
  105. package/dist/types/modules/panels/model/market-route.d.ts +5 -3
  106. package/dist/types/modules/panels/model/market-sources-act.d.ts +9 -0
  107. package/dist/types/modules/panels/model/market-types.d.ts +7 -13
  108. package/dist/types/modules/panels/model/market-update-bundle.d.ts +19 -0
  109. package/dist/types/modules/panels/model/market-verify.d.ts +15 -0
  110. package/dist/types/modules/panels/model/market-workbench-update.d.ts +3 -2
  111. package/dist/types/modules/panels/model/market.d.ts +6 -5
  112. package/dist/types/modules/panels/model/plugin-actions.d.ts +2 -1
  113. package/dist/types/modules/panels/model/plugin-section.d.ts +3 -1
  114. package/dist/types/modules/panels/model/publish-preview-routes.d.ts +2 -0
  115. package/dist/types/modules/panels/unit.d.ts +8 -5
  116. package/dist/types/modules/sessions/model/attention.d.ts +0 -11
  117. package/dist/types/modules/sessions/model/session-node.d.ts +0 -10
  118. package/dist/types/shared/api/diy.d.ts +6 -4
  119. package/dist/types/shared/api/host/approval-call.d.ts +0 -9
  120. package/dist/types/shared/api/host/approval-gate.d.ts +26 -0
  121. package/dist/types/shared/api/host/bundle-routes.d.ts +2 -1
  122. package/dist/types/shared/api/host/diy-artifacts.d.ts +3 -0
  123. package/dist/types/shared/api/host/diy-changelog.d.ts +13 -0
  124. package/dist/types/shared/api/host/diy-components.d.ts +2 -3
  125. package/dist/types/shared/api/host/diy-modules.d.ts +25 -0
  126. package/dist/types/shared/api/host/diy-publish-preview.d.ts +4 -0
  127. package/dist/types/shared/api/host/diy-recon-fs.d.ts +2 -2
  128. package/dist/types/shared/api/host/diy-tokens.d.ts +8 -0
  129. package/dist/types/shared/api/host/host-routes.d.ts +10 -0
  130. package/dist/types/shared/api/host/long-task-notice.d.ts +0 -20
  131. package/dist/types/shared/api/host/long-tasks.d.ts +1 -8
  132. package/dist/types/shared/api/host/market-doc.d.ts +21 -0
  133. package/dist/types/shared/api/host/market-index-fetch.d.ts +37 -0
  134. package/dist/types/shared/api/host/market-source-init.d.ts +22 -0
  135. package/dist/types/shared/api/host/market-sources-store.d.ts +15 -0
  136. package/dist/types/shared/api/host/permission-mode.d.ts +4 -0
  137. package/dist/types/shared/api/host/post-channels.d.ts +1 -1
  138. package/dist/types/shared/api/host/sidebar-edition.d.ts +14 -0
  139. package/dist/types/shared/api/host/unit-roster-facts.d.ts +1 -1
  140. package/dist/types/shared/api/host/workspace-root.d.ts +6 -0
  141. package/dist/types/shared/api/platform/client.d.ts +10 -0
  142. package/dist/types/shared/api/unit-board.d.ts +4 -0
  143. package/dist/types/shared/api/write-outcome.d.ts +3 -0
  144. package/dist/types/shared/components/IconModules.d.ts +2 -0
  145. package/dist/types/shared/components/PanelFoot.d.ts +0 -9
  146. package/dist/types/shared/components/blocker-action.d.ts +3 -0
  147. package/dist/types/shared/dev-surface/index.d.ts +5 -0
  148. package/dist/types/shared/dev-surface/types.d.ts +79 -0
  149. package/dist/types/shared/hooks/bundle-queries.d.ts +1 -13
  150. package/dist/types/shared/hooks/fact-transport.d.ts +4 -0
  151. package/dist/types/shared/hooks/fact-transports.d.ts +0 -4
  152. package/dist/types/shared/hooks/market-queries.d.ts +11 -0
  153. package/dist/types/shared/hooks/panel-state-report.d.ts +0 -12
  154. package/dist/types/shared/hooks/sidebar-edition.d.ts +2 -0
  155. package/dist/types/shared/hooks/use-blocker-actions.d.ts +0 -8
  156. package/dist/types/shared/hooks/use-capabilities.d.ts +1 -55
  157. package/dist/types/shared/hooks/use-capability-gate.d.ts +1 -2
  158. package/dist/types/shared/hooks/use-diy-debug.d.ts +0 -13
  159. package/dist/types/shared/hooks/use-diy-record.d.ts +0 -13
  160. package/dist/types/shared/hooks/use-host-write.d.ts +1 -1
  161. package/dist/types/shared/hooks/use-shell-long-tasks.d.ts +1 -7
  162. package/dist/types/shared/hooks/use-unit-board.d.ts +1 -1
  163. package/icon.svg +17 -28
  164. package/package.json +33 -13
  165. package/preset/diy.patch.yml +3 -3
  166. package/profile/isolation.patch.yml +18 -7
  167. package/profile/sandbox.patch.yml +2 -2
  168. package/scripts/clone-profile.mjs +268 -0
  169. package/scripts/create-workbench.mjs +166 -0
  170. package/scripts/seed-profile.sh +22 -10
  171. package/scripts/seed-workshop.sh +17 -19
  172. package/skills/workbench-module-diy/BUILD.md +57 -133
  173. package/skills/workbench-module-diy/COPY.md +89 -0
  174. package/skills/workbench-module-diy/DATASOURCE.md +173 -116
  175. package/skills/workbench-module-diy/DESIGN.md +76 -109
  176. package/skills/workbench-module-diy/FAMILY.md +48 -52
  177. package/skills/workbench-module-diy/KIT.md +78 -133
  178. package/skills/workbench-module-diy/LINKAGE.md +66 -105
  179. package/skills/workbench-module-diy/PANEL.md +81 -171
  180. package/skills/workbench-module-diy/REVIEW.md +67 -81
  181. package/skills/workbench-module-diy/SKILL.md +66 -96
  182. package/skills/workbench-module-diy/STEPS.md +66 -69
  183. package/skills/workbench-module-diy/TOOLS.md +134 -103
  184. package/skills/workbench-module-diy/WIRING.md +64 -84
  185. package/skills/workbench-module-diy/WRITES.md +115 -142
  186. package/dist/types/app/layouts/config-sync/ConfigSyncSection.d.ts +0 -5
  187. package/dist/types/shared/api/bundle-install.d.ts +0 -123
  188. package/dist/types/shared/api/config-sync.d.ts +0 -35
  189. package/dist/types/shared/api/dsh-plugins.d.ts +0 -11
  190. package/dist/types/shared/api/host/bundle-manager.d.ts +0 -11
  191. package/dist/types/shared/api/host/config-sync.d.ts +0 -46
  192. package/dist/types/shared/api/host/diy-preset-health.d.ts +0 -35
  193. package/dist/types/shared/api/host/diy-workshop.d.ts +0 -23
  194. package/dist/types/shared/api/host/dsh-plugins.d.ts +0 -5
  195. package/dist/types/shared/api/host/installed-module.d.ts +0 -54
  196. package/dist/types/shared/api/host/installed-module.test.d.ts +0 -1
  197. package/dist/types/shared/api/host/opencli-command.d.ts +0 -10
  198. package/dist/types/shared/api/host/opencli-command.test.d.ts +0 -1
  199. package/dist/types/shared/api/host/opencli.test.d.ts +0 -1
  200. package/dist/types/shared/api/host/package-content.d.ts +0 -6
  201. package/dist/types/shared/api/host/package-content.test.d.ts +0 -1
  202. package/dist/types/shared/api/host/package-kind.d.ts +0 -21
  203. package/dist/types/shared/api/host/package-kind.test.d.ts +0 -1
  204. package/dist/types/shared/api/host/package-route.d.ts +0 -23
  205. package/dist/types/shared/api/host/package-route.test.d.ts +0 -1
  206. package/dist/types/shared/api/host/plugin-catalog.d.ts +0 -65
  207. package/dist/types/shared/api/host/plugin-login-hint.d.ts +0 -2
  208. package/dist/types/shared/api/host/plugin-tools.d.ts +0 -14
  209. package/dist/types/shared/api/host/plugin-units.d.ts +0 -48
  210. package/dist/types/shared/api/host/preflight-route.d.ts +0 -15
  211. package/dist/types/shared/api/host/preflight.d.ts +0 -75
  212. package/dist/types/shared/api/host/probe-cache.d.ts +0 -6
  213. package/dist/types/shared/api/host/probe-libs.d.ts +0 -11
  214. package/dist/types/shared/api/host/probe-units.d.ts +0 -17
  215. package/dist/types/shared/api/host/probe-verdict.d.ts +0 -7
  216. package/dist/types/shared/api/host/profile-registries.d.ts +0 -21
  217. package/dist/types/shared/api/host/registry-declaration.d.ts +0 -23
  218. package/dist/types/shared/api/host/release.d.ts +0 -24
  219. package/dist/types/shared/api/host/runtime-seed.d.ts +0 -38
  220. package/dist/types/shared/api/host/self-update.d.ts +0 -45
  221. package/dist/types/shared/api/host/version-range.d.ts +0 -2
  222. package/dist/types/shared/api/host/workshop-root.d.ts +0 -16
  223. package/dist/types/shared/api/long-tasks.d.ts +0 -19
  224. package/dist/types/shared/api/unit-manifests.d.ts +0 -6
  225. package/docs/HANDOFF.md +0 -333
  226. package/docs/OPERATIONS.md +0 -229
  227. package/skills/workbench-module-diy/TOOLING.md +0 -55
  228. /package/dist/types/{app/layouts/rightbar/registry.d.ts → kernel/client/board-registry.d.ts} +0 -0
  229. /package/dist/types/{app/layouts/rightbar/registry.test.d.ts → kernel/contract/contracts.test.d.ts} +0 -0
  230. /package/dist/types/{shared/api/host/bundle-manager.test.d.ts → kernel/contract/index.test.d.ts} +0 -0
  231. /package/dist/types/{shared/api → kernel}/host/unit-readiness.d.ts +0 -0
  232. /package/dist/types/{shared/api → kernel}/host/unit-registry.d.ts +0 -0
  233. /package/dist/types/shared/{api/host/diy-workshop.test.d.ts → components/blocker-action.test.d.ts} +0 -0
  234. /package/dist/types/shared/{api/host/dsh-plugins.test.d.ts → dev-surface/install.d.ts} +0 -0
@@ -1,95 +1,82 @@
1
- # 门禁红了怎么办:十三条判据的人话对照表
1
+ # 门禁:判据、修法、取证
2
2
 
3
- 跑 `dsh-wb-module check`(或单跑一条 `--only <名字>`)。**每条红都在讲一件真出过事的事**;红了照下表修,别抛给用户。
3
+ 运行 `dsh-wb-module check` 或 `check --only <判据>`。红即修,不转给用户。
4
4
 
5
- | 判据 | 它防什么 | 怎么修 |
5
+ | 判据 | 检查 | 修法 |
6
6
  |---|---|---|
7
- | `contracts` | dsh 组合期**不校验** `package.json` 声明;清单 ↔ 代码 / 底稿 ↔ 清单漂了没人拦 | 报哪条改哪条:`unit` 撞了换名;`dsh.workbenchFaces` 补两个**源码**入口;四个脚本补全;私有就 `private: true`。`dsh.workbench.tools` 与 `registerTools()` 注册的**不重不漏**;写了 `design.json` 就对**键集合**(只对名字);生成物过期跑 `dsh-wb-module sync` |
8
- | `protocol` | `dsh.workbench` 缺版本 / 形状不对 / **多一个键** —— 外壳会**静默忽略**生字段 | 补 `"apiVersion": 1`;`unit`/`card`/`tools`/`host` 写全(没卡片 `null`、没工具 `[]`);删协议外的键(`faces` 住 `dsh.workbenchFaces`,`scope` **不要写**);字段清单见 module-tools README「协议」 |
9
- | `bundles` | 两个运行时互串:浏览器产物带 node 内置 / 宿主产物带 DOM、react | 各自别 import 对方那侧;只通过服务名相接 |
10
- | `source` | 非种子词的 `@deepseek-ai/*`、宿主侧碰 dsh 浏览器包、`@/` 指到工作台源码 | 宿主侧只用 Node 侧;dsh 的浏览器包(种子词)只在**只被 client 入口可达**的文件里用;`@/` 只指自己 `src/` |
11
- | `primitives` | 声明 `external` 却没产物物证 ⇒ 原语被**内联**成第二份实例 | `dsh.client.external` 里声明;`devDependencies` 精确版对齐外壳钉的那份;产物里要是 `require(...)`(清单:`check --only primitives`) |
12
- | `kit` | 用了 peer 下限那份外壳**还没有**的成员 ⇒ 卡片首帧 `Element type is invalid`,整块面板被卸 | 只用 peer 范围里真有的成员;下限提到你实际用的那档 |
13
- | `cards` | 卡片在外壳侧输入下崩 / 空白 / 变脏(八态 × `zh`/`en` 各一遍;走**真壳**取数) | 五态都画得出(加载 / 空 / 阻断);外套 `kit.components.Card`;`titleKey` 与卡片问过的每个键 `zh`/`en` 都有落点。判据**不断言**画的是哪一态 —— 那归 `plugin.test.ts` |
14
- | `standalone` | "只有工作台源码在场才编得过" ⇒ 发出去就散架 | 别引用工作台源码;`tsconfig` 的 `paths` 用**相对路径**(`"./src/*"`) |
15
- | `markers` | 内网域名 / 企业内部名泄进要公开发布的包 | 别写进包里;要配就落到模块自己的配置面 |
16
- | `alias` | `@/` 伸进工作台源码 ⇒ 装的人手上没那份源码 | `@/` 只许指自己 `src/`;跨包走包名 |
17
- | `style` | 模块定义 `.wb-*` 覆盖外壳类;手写行 / 操作区 / **整张表单**(F1–F4) | 样式走 `*.module.css`(不带 `wb-` 前缀);借外壳类写 `:global(.wb-…)`;行与操作区用 kit 的 `FormRow(s)` / `FormActions`,整张表单用 `Form`([KIT.md](KIT.md) §5)。**F4**:源码里出现裸 `<form`、或手写行槽类(`wb-formRow` / `wb-formRows` / `wb-field`)⇒ 红(口径见 ADR-0068) |
18
- | `arch` | 结构退化(巨文件 / 反向依赖 / 跨运行时 / 表外目录 / 模型层没测试) | 见「第十二条 `arch`」 |
19
- | `lint` | 单文件语法卫生(`as any` / 残留 `console`、`debugger` / 内联颜色、`!important` / react-hooks) | 见「第十三条 `lint`」 |
20
-
21
- ## 第十二条 `arch`:模块自己的分层形状
22
-
23
- **先分清跑没跑**:只跑带 `arch.config.mjs` 的模块;没有那份文件 = `○ 不适用`(skip),**不是红**。上车就在包根加一行工厂:
7
+ | `contracts` | 清单 ↔ 代码 ↔ `design.json` 漂移;dsh 组合期不校验清单 | 按报错改:`unit` 重名换名;`dsh.workbenchFaces` 两个源码入口;六个脚本;`private: true`。`dsh.workbench.tools` 与 `registerTools()` 一致;`design.json` 对键名;生成物过期跑 `sync` |
8
+ | `protocol` | `dsh.workbench` 版本 / 形状 / 多余键(外壳静默忽略生字段) | 补 `"apiVersion": 2`;`unit` / `card` / `tools` / `host` 写全(无卡片 `null`、无工具 `[]`);删协议外键(`faces` 在 `dsh.workbenchFaces`;不写 `scope`) |
9
+ | `bundles` | 运行时互串:浏览器产物含 node 内置 / 宿主产物含 DOM、react | 不 import 对方那侧 |
10
+ | `source` | 非种子 `@deepseek-ai/*`;宿主碰 dsh 浏览器包;`@/` 指外壳;根入口取运行值;客户端引 `/host`;**手写进程 / PATH / 文件锁 / 状态原子写**(import 首选库放行) | 宿主只用 Node 侧;种子词仅在 client 可达文件;`@/` 只指自己 `src/`;运行值:浏览器 `kit`、宿主 `shared/host`;进程/锁/状态写交给外壳 |
11
+ | `primitives` | 声明 `external` 但产物无物证(原语被内联) | `dsh.client.external` 声明;devDependency 精确版对齐;产物中为 `require(...)` |
12
+ | `kit` | 用了 peer 下限外壳没有的成员(首帧 `Element type is invalid`) | 只用 peer 范围内成员;下限抬到实际使用版 |
13
+ | `cards` | 七种外壳侧输入 × `zh` / `en` 下崩溃 / 空白 / 脏值 | 五态可画;外层 `Card`;`titleKey` 与卡片用到的键双语齐。不断言具体态(归 `plugin.test.ts`) |
14
+ | `standalone` | 依赖工作台源码才能构建 | 不引用工作台源码;`tsconfig.paths` 用相对路径 |
15
+ | `markers` | 私有源 / 私网地址 / 内网域名进入公开包 | 不进包;配置落到模块配置面;组织特有的词表由 `DSH_WB_INTERNAL_MARKERS` 提供 |
16
+ | `alias` | `@/` 指向工作台源码 | `@/` 只指自己 `src/` |
17
+ | `style` | 模块定义 `.wb-*`;手写行 / 操作区 / 表单(F1–F4);`--dsw-*` / `--wb-*` 不在现读的令牌清单 | 样式走 `*.module.css`(无 `wb-` 前缀);借外壳类用 `:global(.wb-…)`;行 / 操作区用 `FormRow(s)` / `FormActions`,表单用 `Form`([KIT.md](KIT.md) §5)。F4:裸 `<form` 或手写 `wb-formRow` / `wb-formRows` / `wb-field`。令牌名现查:`workbench_diy_components` `scope: 'tokens'` |
18
+ | `arch` | 结构:巨文件 / 反向依赖 / 跨运行时 / 表外目录 / 模型无测试;依赖白名单(含 execa / which / proper-lockfile / write-file-atomic / dayjs / zod)+ `shell-quote` / `shelljs` / `zx` deny;能力首选 dayjs / structuredClone / URLSearchParams / zod(日期已是硬门禁) | 见「第十二条」 |
19
+ | `lint` | 语法:`as any` / `console` / `debugger` / 颜色字面量 / `!important` / **直接读 `process.platform` / `versions.electron` / `dshDesktop` / `hostOs` / `navigator.userAgent`** / react-hooks | 见「第十三条」 |
20
+
21
+ ## 第十二条 `arch`
22
+
23
+ 只跑带 `arch.config.mjs` 的模块;无文件 = 不适用(skip),不是红。
24
24
 
25
25
  ```js
26
26
  import { moduleArch } from '@dsh-workbench/module-tools/arch';
27
27
  export default moduleArch();
28
28
  ```
29
29
 
30
- **怎么读**:`dsh-wb-module check --only arch`。通过长这样(数字随模块走):
30
+ 报错格式 `<包名>: <文件>:<行> <说明>(<规则>)—— <hint>`;仅 `error` 阻断(`warn` 提示);配置 import / 语法错也红。
31
31
 
32
- ```
33
- ✔ 模块架构(分层 / 边界 / 设计系统) 1/1 个模块包带 arch.config.mjs · 7 个源文件 · 58 条规则在跑
34
- ```
35
-
36
- 红了逐条是 `<包名>: <文件>:<行> <说明>(<规则>) —— <hint>`;括号里那个规则号是下表的键;只有 `error` 挡门禁(`warn` 只提示);配置自己跑不起来(import / 语法错)也判红。
37
-
38
- | 常见红(规则) | 它在说什么 | 怎么修 |
32
+ | 规则 | 含义 | 修法 |
39
33
  |---|---|---|
40
- | `[S01] 文件不在目录契约内` | 文件放到层序表外的目录(如 `src/utils/`) | 挪进 `model/` / `components/`,或用 `layers`/`roles` 明写这一层。`src/messages.ts` / `src/declared-tools.ts` / `src/**/__tests__/**` 已有内置角色 |
41
- | `[S21] 反向依赖` | 底层文件引了更上层(如组件引 `../host`) | 被引的下沉到 `model/`;只许依赖层号 ≤ 自己的 |
42
- | `[S23] 跨运行时走了「client」面` | **宿主侧 import 了 `src/components/**`**(或反过来) | 组件整片算 client 面;两侧只通过服务名相接 |
43
- | `[S16] 文件 N 行,超过上限 200` | 文件太长(默认文件 200 / 函数 80)。**测试文件不吃这条**(`.test.`/`.spec.` 与 `src/**/__tests__/**` 豁免) | 拆;确实该长的传 `fileLines`/`viewLines`/`functionLines`,或给这一个文件开 `exceptions` |
44
- | `[M08] 没有配对测试` | `src/model/**` 有文件却没测试 | 补 `src/model/X.test.ts` |
45
- | `[D12] padding: 13px 不在长度的刻度里` | 手搓了不在刻度上的数值 | 引用 `--dsw-*` 令牌或走刻度(`0` 本来就被跳过) |
46
- | `[D09] … 用了 !important` | `!important` 只许写在 `src/components/vendor/` | 用选择器 / 层级解决 |
47
- | `[D17] 定义的类没人用` | `.module.css` 里定义了没人用的类 | 删掉 |
34
+ | `S01` 表外目录 | 文件不在层序表(如 `src/utils/`) | 移入 `model/` / `components/`,或用 `layers` / `roles` 声明 |
35
+ | `S21` 反向依赖 | 低层引高层(组件引 `../host`) | 被引项下沉 `model/`;只依赖层号 ≤ 自身 |
36
+ | `S23` 跨运行时 | 宿主 import `src/components/**` 或反向 | 组件归 client 面;两侧经服务名 |
37
+ | `S16` 超长 | 文件 >200 行 / 函数 >80(测试豁免) | 拆;或传 `fileLines` / `functionLines`;单文件用 `exceptions` |
38
+ | `M08` 无测试 | `src/model/**` 无配对测试 | 补 `src/model/X.test.ts` |
39
+ | `D12` 刻度外值 | 手写不在刻度的尺寸 | 用 `--dsw-*` 或刻度值 |
40
+ | `D09` `!important` | 只允许 `src/components/vendor/` | 改选择器 / 层级 |
41
+ | `D17` 未使用类 | `*.module.css` 定义未使用 | 删除 |
48
42
 
49
- 要放宽**从参数进**(别改判据):`moduleArch({ fileLines, deps, layers, roles, structure, exceptions })`,`exceptions` 每条**必须写 `reason`**(后缀 / 单文件都行,glob 是 picomatch):
43
+ 放宽从参数进:`moduleArch({ fileLines, deps, layers, roles, structure, exceptions })`;`exceptions` 每条需 `reason`:
50
44
 
51
45
  ```js
52
46
  export default moduleArch({
53
47
  layers: { host: 10 },
54
48
  roles: [{ id: 'lib:platform', pattern: 'src/platform/**', layer: 1 }],
55
- exceptions: [{ rule: 'S16', glob: 'src/host/service.ts', reason: '…为什么这一个该长…' }],
49
+ exceptions: [{ rule: 'S16', glob: 'src/host/service.ts', reason: '…' }],
56
50
  });
57
51
  ```
58
52
 
59
- ⚠️ 层序表与两个面(`dsh.workbenchFaces` 指的那两个文件)不是可调项 —— 改了先红 `contracts`/`source`(换面要整体替换 `structure` 并改清单)。内置已有三条豁免,不必重复声明。
60
-
61
- ## 第十三条 `lint`:模块自己的语法卫生
53
+ 层序表与 `dsh.workbenchFaces` 所指两个面不可调;改动会先红 `contracts` / `source`。
62
54
 
63
- `arch` 管**文件之间**的结构,`lint` 管**文件之内**的写法。
55
+ ## 第十三条 `lint`
64
56
 
65
- **先分清跑没跑**:只跑带 `eslint.config.mjs` 的模块;没有 = 汇总行里 `○ 模块代码卫生(eslint):(不适用)…`(skip),**不是红**。上车就在模块根放一份:
57
+ `arch` 管文件间,`lint` 管文件内。只跑带 `eslint.config.mjs` 的模块;无文件 = 不适用,不是红。
66
58
 
67
59
  ```js
68
60
  import { moduleLint } from '@dsh-workbench/module-tools/lint';
69
61
  export default moduleLint({ rootDir: import.meta.dirname });
70
62
  ```
71
63
 
72
- `rootDir` 把 typescript-eslint 的 `tsconfigRootDir` 钉在这个模块上 —— 本仓根上还有一份配置,多份并存时不传就猜不出来(每个文件报 `No tsconfigRootDir was set…`),所以模板与骨架都带着它。
73
-
74
- **怎么读**:`dsh-wb-module check --only lint`。通过长这样(部分模块上车时多一句 `其余 N 个没有 eslint.config.mjs(不适用)`):
64
+ `rootDir` 钉 typescript-eslint 的 `tsconfigRootDir`(工作区可能有其他 eslint 配置;不传会报
65
+ `No tsconfigRootDir was set…`)。
75
66
 
76
- ```
77
- ✔ 模块代码卫生(eslint):1/1 个模块包带 eslint.config.mjs · 8 个文件 · 0 error · 0 warn
78
- ```
79
-
80
- 红了逐条是 `名字: 文件:行:列 规则 —— 一句话`(压成单行、截 200 字)。**只有 `error` 算红**,`warn` 只计数(单跑时列在 `warn(不挡门禁):` 下);聚合最多列 40 条,`--only lint` 列全;配置跑不起来也判红(同 `arch`)。
67
+ 仅 `error` 算红;`warn` 计数。聚合最多 40 条,`--only lint` 全列;配置跑不起来也红。
81
68
 
82
- | 常见红(规则) | 它在说什么 | 怎么修 |
69
+ | 规则 | 含义 | 修法 |
83
70
  |---|---|---|
84
- | `@typescript-eslint/no-explicit-any` | `as any` / `: any` 绕开契约 | 写得出真类型就写;要放行从 `moduleLint({ rules })` 开口子,或就地 `// eslint-disable-next-line` |
85
- | `no-console` | `src/**` 里留了 `console.log`/`info`/`debug`(`warn`/`error` 放行) | 删掉;`scripts/**` 不判这条 |
86
- | `no-debugger` | 留了 `debugger` | 删掉 |
87
- | `no-restricted-syntax` | 内联颜色字面量(`#ff0000`/`rgb(`/`hsl(`),或字符串里带 `!important` | 外观走 `--dsw-*` 与 `*.module.css`;`!important` 只许 `src/components/vendor/**` |
88
- | `react-hooks/*`(`rules-of-hooks` · `refs` · `exhaustive-deps` · `immutability`) | 条件调 hook / 渲染期写 ref / 漏依赖 | hook 提到顶层、副作用放 `useEffect`、依赖补全 |
89
- | `@typescript-eslint/no-unused-vars` | 死代码(`^_` 开头放行) | 删掉,或改名 `_x` |
90
- | 其余 `recommended` / `react/*` | 语法级那批(`no-unreachable` / 空 `catch` / `jsx-key`…) | 照 eslint 的原话修 |
71
+ | `no-explicit-any` | `as any` / `: any` | 写真实类型;或在 `moduleLint({ rules })` 放行 |
72
+ | `no-console` | `src/**` 的 `console.log` / `info` / `debug`(`warn` / `error` 放行) | 删除;`scripts/**` 不判 |
73
+ | `no-debugger` | 残留 `debugger` | 删除 |
74
+ | `no-restricted-syntax` | 颜色字面量(`#ff0000` / `rgb(` / `hsl(`)、字符串 `!important`、平台原始事实(`process.platform` / `versions.electron` / `dshDesktop` / `hostOs` / `navigator.userAgent`) | 用令牌与 `*.module.css`;平台差异走能力面(`HostSurface` / `ClientSurface`),宿主/浏览器面分开写 |
75
+ | `react-hooks/*` | 条件 hook / 渲染期写 ref / 漏依赖 | 提到顶层;副作用进 `useEffect`;补依赖 |
76
+ | `no-unused-vars` | 死代码(`^_` 放行) | 删除或改 `_x` |
77
+ | 其他 `recommended` / `react/*` | 语法规则 | 按 eslint 原文 |
91
78
 
92
- 要放宽**从命名参数进**(`ignores`/`rules`);按目录细调就展开再追一块:
79
+ 放宽从命名参数(`ignores` / `rules`);按目录追加一块:
93
80
 
94
81
  ```js
95
82
  export default [
@@ -98,31 +85,30 @@ export default [
98
85
  ];
99
86
  ```
100
87
 
101
- ⚠️ **别改方言**:判据拿 `moduleLint()` 产出的**整份 8 块**(`@eslint/js/recommended` · 三块 `typescript-eslint/*` · `dsh-wb/module-lint` 那四块)与你的配置**逐块比**(名字 / `files` / `rules`;`/overrides`、`/root` 不比),全局 ignores 按**超集**比:多忽略可以,少一条点名缺哪条 glob。少一块、同名两次、删一条规则、改一个规则值都当场红;**只抄一个名字**(`[{ name: 'dsh-wb/module-lint', rules: {} }]`)、`export default []`、`moduleLint().filter(…)` 这类筛法也红。**残余只剩一条**:自己 import 方言再照抄整份分不出来 —— 这是抬高门槛、让改动明着写,不是"防住伪造"。
102
-
103
- **`--fix`**:`dsh-wb-module lint --fix`(模块里是 `pnpm lint -- --fix`)写回能自动修的、打印「修了 N 条 / 还剩 M 条」。**`check` 永远不动手改文件**。
104
-
105
- ## 什么时候该怀疑门禁本身
106
-
107
- 判据自己也有正反例,正常不误报。但**骨架刚 `init` 出来、一行没改却红了** —— 那是模板 / 工具坏了,不是你的。
88
+ 不改方言:判据将 `moduleLint()` 的整份 8 块与配置逐块比(名字 / `files` / `rules`;`/overrides`、`/root` 不比),
89
+ 全局 ignores 按超集比。少块、重名、改规则值、只抄名字、`export default []`、`.filter(…)` 均红。
108
90
 
109
- ## 四条"不是判据、但更常踩"的
91
+ `dsh-wb-module lint --fix` 写回可自动修项;`check` 不改文件。
110
92
 
111
- (细节在 [WIRING.md](WIRING.md) / [BUILD.md](BUILD.md))
93
+ ## 怀疑门禁
112
94
 
113
- 1. **装上去没反应** → 先问 `workbench_diy_status`(`unit=…`)。[WIRING.md](WIRING.md) §3
114
- 2. **改完没热换** → 宿主侧秒级热换;客户端刷新页面。[WIRING.md](WIRING.md) §4
115
- 3. **"再装一遍"** → 日常迭代只重建、不重装。[WIRING.md](WIRING.md) §3
116
- 4. **引了 dsh 原语却 `tsc` 报"找不到模块"** → 两处声明 + `pnpm install`([KIT.md](KIT.md) §8)。
95
+ 骨架刚 `init`、未改动却红 → 模板或工具问题,不是模块问题。
117
96
 
118
- ## 用户说"卡片不对"时:四步取证
97
+ ## 卡片故障:四步取证
119
98
 
120
- 他说"一片空白 / 一直转圈 / 数字不对"时,**先取证再改代码**;前一步有结论就停在那儿修:
99
+ 先取证再改代码;某步有结论就停在对应侧修。
121
100
 
122
- 1. **`workbench_diy_panel`** —— 这个工作区面板现在什么样:哪几张卡、每张最后一次取数是读到了还是读不到(带宿主回的码与原文)、崩过没(原因 + 次数)。有答案就别往下走。
123
- 1.5 **看这一张卡**(`workbench_diy_screenshot` / `_html` / `_find` / `_eval`)—— 打的是**用户当前那一页**上工坊那块板里这张卡(`unit=…`;四把的入参与拿回见 [FAMILY.md](FAMILY.md) §2),配合上一步把"看起来不对"说成"哪一处不对"。**这一族(浏览器那 14 把 + `logs_*`)要先 `workbench_diy_debug_start`**(`unit=…`;会请用户点头一次)—— 没有这场约定一律当场拒;不看屏先 `_pause`,收工 `_stop`。(`_panel` / `_status` 不碰他那一屏,不用开;`_find` / `_eval` 带 `read=` 时也不碰。)
124
- 2. **`workbench_diy_status`(`unit=…`)** —— 看"起得来"那一行:模块起不来时原因就在那里(装配抛的错 / 声明被拒的原文)。
125
- 3. **自己把那条读跑一遍**:卡片画的就是模块那条宿主路由的返回值 —— `curl '<工作台地址>/workbench/api/<unit>/<route>'`(默认 `http://127.0.0.1:3081`)。接口对而卡片不对 ⇒ 渲染侧;接口就错 ⇒ 宿主侧(照 [DATASOURCE.md](DATASOURCE.md) 重探)。要**浏览器里那一次**的原文,用 `workbench_diy_eval`(`read=<站点地址>`,脚本里 `fetch` 自己那条读)。
126
- 4. **最后才看用户那一页**:要控制台走三拍 —— `workbench_diy_logs_watch` → 做那件你怀疑会报错的事 → `workbench_diy_logs_read`(读完 `_logs_stop` 卸掉;上限:每页 200 条 / 单条 400 字、随刷新消失)。**别用 `opencli browser <会话> console`** —— 那是个 stub(恒回空数组、还 exit 0)。要在页面里跑自己的代码用 `workbench_diy_eval` 的 `read=` 档;看**用户那一页**有什么可点的用 `workbench_diy_state`。宿主侧热换 / 装载的报错在**起工作台那个终端**里。
101
+ 1. `workbench_diy_panel`:每卡的读取状态(宿主码与原文)、是否崩过(原因、次数)。有结论即止。
102
+ 2. 看卡片:`workbench_diy_screenshot` / `_html` / `_find` / `_eval`,作用于用户当前页的该卡(`unit=…`)。
103
+ 这一族(14 把 + `logs_*`)需先 `workbench_diy_debug_start`(`unit=…`,审批一次),否则拒绝;
104
+ `_panel` / `_status` / `read=` 档不需要。用完 `_pause`,收工 `_stop`。
105
+ 3. `workbench_diy_status`(`unit=…`):看"起得来"行(装配错误 / 声明被拒原文)。
106
+ 4. 直接请求路由:`curl '<工作台地址>/workbench/api/<unit>/<route>'`(默认 `http://127.0.0.1:3081`)。
107
+ 接口对 → 渲染侧;接口错 → 宿主侧(按 [DATASOURCE.md](DATASOURCE.md) 重探)。需要在页面内请求时用
108
+ `_eval`(`read=<站点>`)。控制台:`_logs_watch` → 操作 → `_logs_read`(每页 200 条 / 单条 400 字,
109
+ 刷新即失;用 `_logs_stop` 卸载)。`opencli browser … console` 是空桩(恒空、exit 0),不用。
110
+ 宿主热换 / 装载错误在启动工作台的终端。
127
111
 
128
- 两条纪律:**别让用户截图或替你转述报错**;**验收就是你自己拿这一族走** —— 逐条对着三张表走「打开哪 → 看什么 → 点什么 → 应该看到什么」,`screenshot`/`html`/`find`/`eval` 的读数、动作族的返回、`workbench_diy_network` 的收发包、`logs_*` 的报错都算证据;走通再 `design accept`,走不通的如实说没验过(用户不必在场,也不用请他逐条点头)。工具参数与返回体都是 opencli 的原样(见 [FAMILY.md](FAMILY.md))。面板运行态是**用户那一页自己报上来的**,第 1 步没有内容时,先让他把工作台切到工坊那个工作区、刷新一次页面再看。
112
+ 不要求用户截图或转述报错。验收由 agent 用上述工具逐条走三张表:读数、动作返回、收发包、日志均算证据;
113
+ 走通才 `design accept`,走不通记"未验"。参数与返回为 opencli 原样([FAMILY.md](FAMILY.md))。
114
+ 面板运行态由用户页面上报;第 1 步为空时,先让用户切到该工作区并刷新一次。
@@ -1,113 +1,83 @@
1
1
  ---
2
2
  name: workbench-module-diy
3
- description: 在工作台里凭需求造一个模块(面板上的一块内容 + 它背后的能力)—— 用在「我想在面板上看到 X / 加一块卡」「让 agent 替我读或写某个东西」「agent 动完面板哪一格跟着变」这类话上。用户只说需求,实现由 agent 自己做、自己过门禁、自己在真卡片上逐条验过,最后给他一个能点开看的东西。
3
+ description: 在工作台里把当前面板调明白,或者给它造一块新内容 —— 用在「这块板为什么空白 / 这张卡不对 / 它到底发了什么」「我想在面板上看到 X / 加一块卡」「让 agent 替我读或写某个东西」这类话上。用户只说需求,实现由 agent 自己做、自己验过。
4
4
  ---
5
5
 
6
- # 造一个工作台模块:他说需求,你做完自己验过再交给他
6
+ # workbench-module-diy
7
7
 
8
- 交付物是**面板上能点开的一块内容**,不是一份要他读的技术方案。
8
+ | 触发 | 任务 | 前置 |
9
+ |---|---|---|
10
+ | 「这块板空白 / 这张卡不对 / 数据不对 / 它到底发了什么」 | 调:查现有面板 | `workbench_diy_panel` / `_status`;动屏要调试约定 |
11
+ | 「我想在面板上看到 X / 加一块卡」 | 造:新建模块 | 一个能放代码的包(没有就问用户) |
9
12
 
10
- ## 七步
13
+ 调交付"面板现在怎么样"的事实;造交付面板上能点开的一块内容。不交技术方案。
11
14
 
12
- 1. **判域** —— 先读 [DESIGN.md](DESIGN.md) §0。不是所有需求都该在这里做;判完给他**一句人话 + 下一步**。
13
- 2. **问三张表** —— 见 [STEPS.md](STEPS.md)。只问他看得见、能决定的事;**实现一律不问**。
14
- 这一步的产出是 ASCII 画面 + 三张表,不是文字。三张表当场落进模块里的 `design.json`
15
- (命令与形状:[DESIGN.md](DESIGN.md) §5)—— 只留在对话里等于没定。
16
- 3. **先定数据从哪来** —— [DATASOURCE.md](DATASOURCE.md):干净机器上没有现成 skill 可抄,
17
- 用 `workbench_diy_eval` / `_find` 带 `read=<站点地址>`(跑在 `workbench-read` 上)复用他的登录去探 —— 没在站点上我自己开一次,`not-logged-in` / `not-on-site` 两条码按读线约定归一
18
- 都在那把工具里;探明后**固化成一条读**(`@dsh-workbench/shared/host` 的 `browserRead`)。顺手把三态写掉。
19
- 要 agent **真去改东西**(提交 / 发布 / 建单 / 改配置)的,读完 [WRITES.md](WRITES.md) 再动手:
20
- 四步(现成写命令 → 入参 / 出参来源 → 没有预览档的不许试写 → 写完后回读确认)。
21
- 有写工具就**顺手把审批屏那一屏也画进图里**([DESIGN.md](DESIGN.md) §3 末尾那节 + KIT.md §3):
22
- 标题一句 + `ApprovalPlan` 详情表 —— 那两格的形状是固定的(仓内 ADR-0065,这份指引不链仓内路径)。
23
- 4. **从模板改** —— [BUILD.md](BUILD.md) §1–§2:在工坊里 `dsh-wb-module init` 一个骨架,
24
- 把 `design.json` 里的**三张表与数据源记录先改成你问出来的那份**(`design check` 会点名叫出还空着哪一格),
25
- 再改数据源与渲染。
26
- **不从零写**。
27
- 命令写成 `pnpm exec dsh-wb-module …`(工坊里 PATH 上也有同名入口,但 `pnpm exec` 到处都对)。
28
- `init` 完先在工坊里跑一次 `pnpm install`:模板默认带了 dsh 原语那个 devDependency
29
- ([KIT.md](KIT.md) §8),不装 `pnpm typecheck` 会报"找不到模块"。
30
- 5. **自己过门禁** —— `dsh-wb-module build` + `check` + `design check`;
31
- 红了自己修([REVIEW.md](REVIEW.md) 有对照),不抛给他、也不贴报错给他看。
32
- 6. **装上、上板** —— `workbench_diy_install`(`unit=<单元 id>`)装上:
33
- 它只认工坊里造好的那个模块,装完顺手在**这个项目**的面板上打开(装的是这台机器上的东西;**这一步不问审批**,见 [WIRING.md](WIRING.md) §3 —— 别对他说"请你点一下确认",那一拍不会出现)。
34
- **这一跳永远只走一次**:之后只重建、不重装(宿主侧秒级热换;改了 client.js 刷新一下页面)。
35
- 拿不准它现在走到哪一步(装了没 / 面板认得没 / 这个项目上开着没 / 产物齐不齐 / 源码比产物新没),
36
- 就问工具:`workbench_diy_status`(`unit=<单元 id>`)会把这几件事一次说清并给出下一步 ——
37
- **别自己拼,也别再装一遍**;已经装过只是想上板,用 `workbench_diy_show`。
38
- 7. **自己验收** —— 逐条对着三张表,在**真卡片**上走「打开哪 → 看什么 → 点什么 → 应该看到什么」。
39
- 要看 / 动**他那一屏**(浏览器那 14 把 + `logs_*`)得先开约定:
40
- `workbench_diy_debug_start`(`unit=…`;会请他点头一次,他会被告知「调试中请留在那一屏」)——
41
- **没有这场约定,上面那一族一律当场拒**;不看屏了先 `workbench_diy_debug_pause`,收工 `…_stop`。
42
- (`workbench_diy_panel` / `_status` 不碰他那一屏,不用开;`_find` / `_eval` 带 `read=` 时也**不碰** —— 那走只读线。)
43
- 走法(全表与参数在 [FAMILY.md](FAMILY.md)):
44
- - **这一张卡长什么样**:`workbench_diy_screenshot`(要卡那一块就先 `eval` 量盒子、填 `clip`)+
45
- `workbench_diy_html`(`--as json` 给结构树);
46
- - **元素与语义**:`workbench_diy_find`(`--css '$card …'`、或 `--role` / `--name`)、`workbench_diy_state`;
47
- - **动手**:`workbench_diy_click` / `_hover` / `_type` / `_fill` / `_keys` / `_scroll` / `_wait`。
48
- 吃 CSS 的那几把有 `scope`(默认 `page`,`card` 才是这张卡里);portal 出来的那一层(下拉 / 菜单 /
49
- 模态)要用 `scope: 'page'` + `--role menuitem` 按名字点;
50
- - **派生读数**(对比度 / 被裁 / 可见文本):`workbench_diy_eval`(`in: 'card'` 注入卡根 `root`,脚本自己 `return`);
51
- - **那一次读的收发包**:`workbench_diy_network`(`--follow` 臂上 → 做那件事 → `--detail <key>` 取 body);
52
- - **控制台**:`workbench_diy_logs_watch` → 做那件事 → `workbench_diy_logs_read`。
15
+ > **Desktop**:屏调试不可用(`debug_*`、`logs_*`、不带 `read` 的看/动都不会出现);**站点探索用
16
+ > `read=<地址>`**,**录制 `_record_*` 照旧**,`_panel` / `_status` / build / install 照旧。
17
+ > 验收时别调 `_debug_start`;用 `read` 或录制取证。
53
18
 
54
- 这些工具的参数**原样转发**给 opencli、返回体也是它的原样 —— 不知道某个子命令收什么,就
55
- `args: ['<verb>', '--help']` 问它;事实在 `stdout` 里(`ok` 只管进程)。
56
- 哪一条不对,**先取证再改**(`workbench_diy_panel` 一次看清面板上每张卡是读到了、读不到还是崩了;
57
- 四步取证见 [REVIEW.md](REVIEW.md)),改完再走**同一处**。
58
- 逐条都走通了,再 `dsh-wb-module design accept` 把验收打勾(**没走通的不许打勾**;走不通的如实说没验过)。
59
- 审批那一格是**他的**:模块里要用户点头的写能力,得他真用一次时点 —— 你代不了,清单里写清
60
- 「这条要你真用一次」,别打勾说验过。
61
- 验完把结论告诉他:**装好了、面板上哪一格**(不用请他逐条点头 —— 他随时能自己点开看;
62
- 他说哪不对,回到同一处取证再改)。不给他看 diff、日志、代码。
19
+ ## 流程
63
20
 
64
- ## 每个问题都带推荐答案
21
+ **0. 认路** —— 跑 `workbench_diy_status`,取 `工作区:<dir>`。
65
22
 
66
- 他一个字就能过("就这样")。他不确定就按推荐走并标出来,别卡住。
67
- 必须他拍板的决定,翻译成"**你会看到什么**"再问,不问"用 A 还是 B"。
23
+ **调** —— 用 [REVIEW.md](REVIEW.md) 的四步取证。动屏前 `workbench_diy_debug_start`(`unit` 可省;Desktop 跳过)。
24
+ 抓"点了之后发了什么":`workbench_diy_record_prepare` → 用户操作 → `_record_read`;收工 `_debug_stop` / `_record_stop`。
25
+ 不需要源码、工具链、工坊。
68
26
 
69
- ## 知识索引
27
+ **造** —— 模块落 `<dir>`。那里没有能放代码的包(没 `package.json`,或有但没声明 workspace)时,问用户二选一:
28
+ 在这里建 workspace,还是去工坊那个脚手架工作区。不改用户仓库结构。
29
+ 从「造一个模块」进入的会话已在工坊里,`<dir>` 就是工坊。
70
30
 
71
- | 什么时候读 | 读哪份 |
72
- |---|---|
73
- | 判这个需求该不该在这里做 | [DESIGN.md](DESIGN.md) §0 |
74
- | 两条分工、三张表、怎么用 ASCII 跟他说话 | [DESIGN.md](DESIGN.md) |
75
- | 步骤 1 / 2 / 3 各自问什么、什么时候算做完 | [STEPS.md](STEPS.md) |
76
- | **数据从哪来**(干净机器上怎么找到那一条读) | [DATASOURCE.md](DATASOURCE.md) |
77
- | **要 agent 真去改东西**(提交 / 发布 / 建单 / 改配置:写通道四步) | [WRITES.md](WRITES.md) |
78
- | 面板上该有什么、状态矩阵怎么写、界面习惯 | [PANEL.md](PANEL.md) |
79
- | **要做什么 → 用哪件 kit → 最小写法**(照抄面) | [KIT.md](KIT.md) |
80
- | **kit / dsh 原语里到底有什么、某一件怎么用**(DIY 会话里直接调这把工具) | `workbench_diy_components`(`name=Button` 回它的类型文件与声明;工程域用 `check --only kit` · `--only primitives`)· [KIT.md](KIT.md) §8 |
81
- | **kit 那些 hook 怎么搭**(四个场合、一格卡片怎么拼) | [KIT.md](KIT.md) §4′(逐件的 API 看 `.d.ts` 的 JSDoc 或 `workbench_diy_components`) |
82
- | 能力怎么划、传什么拿回什么、哪几件要点头 | [TOOLS.md](TOOLS.md) |
83
- | **工坊会话里那 33 把的全表**(枚举 opencli 的 14 把 + 看/装/探 + 调试约定 + 录制交接、参数与如实边界) | [FAMILY.md](FAMILY.md) |
84
- | agent 动完面板哪一格变、他正在干的时候看哪儿 | [LINKAGE.md](LINKAGE.md) |
85
- | 落点、文件形状、命令、两个面 | [BUILD.md](BUILD.md) |
86
- | 依赖、会被拦的写法、装、热换、发布 | [WIRING.md](WIRING.md) |
87
- | 门禁红了、装上去没反应、改完没热换 | [REVIEW.md](REVIEW.md) |
88
- | 用户说"卡片不对 / 一片空白 / 一直转圈"(四步取证) | [REVIEW.md](REVIEW.md) 那一节 · `workbench_diy_panel`(``) |
89
- | 哪条纪律已经固化成工具、哪些还留给 agent | [TOOLING.md](TOOLING.md) |
31
+ 1. **判域** —— [DESIGN.md](DESIGN.md) §0。输出一句结论 + 下一步。
32
+ 2. **问三张表** —— 问法见 [STEPS.md](STEPS.md);只问用户能决定的事,实现不问。ASCII 画面 + 三张表当场写进
33
+ `design.json`([DESIGN.md](DESIGN.md) §5)。
34
+ 3. **定数据源** —— [DATASOURCE.md](DATASOURCE.md):探明后落成一条**配方**(`design.json` 的 `key + recipe`
35
+ → `dsh-wb-module sync` → `data.request`),配方盖不住的写 `custom: { why }`;写三态。
36
+ 写操作先读 [WRITES.md](WRITES.md) 四步 + 执行体;有写工具就把审批屏画进 ASCII([DESIGN.md](DESIGN.md) §3 末节)。
37
+ 4. **套模板** —— [BUILD.md](BUILD.md) §1–§2:`pnpm exec dsh-wb-module init <unit> --template diy`,
38
+ 先把 `design.json` 改成问出来的那份,再改数据源与渲染。init 后 `pnpm install`。不从零写。
39
+ 改渲染时文案按 [COPY.md](COPY.md):先判读者(卡片给人 / 描述给 agent / 原始输出进 detail)。
40
+ 5. **过门禁** —— `dsh-wb-module build` + `check` + `design check`;红了自己修([REVIEW.md](REVIEW.md)),
41
+ 不把报错贴给用户。
42
+ 6. **装、上板** —— `workbench_diy_install`(`unit=…`)。只装一次;之后 `dsh-wb-module build` 即可。
43
+ 状态不明问 `workbench_diy_status`(`unit=…`);只缺上板用 `workbench_diy_show`。装不问审批。
44
+ 7. **验收** —— 对着三张表在真卡片上走「打开哪 → 看什么 → 点什么 → 应该看到什么」。
45
+ 看 / 动屏前 `workbench_diy_debug_start`(否则整族拒;Desktop 跳过,改用 `read=` / 录制);`_panel` / `_status` / `read=` 档不用。
46
+ 工具全表 [FAMILY.md](FAMILY.md)。走通才 `dsh-wb-module design accept`;走不通如实记"未验"。
47
+ 审批项标注「要你真用一次」,不打勾。结论只报:已装、在面板哪一格。
48
+ 8. **发布** —— 只在用户说「帮我发布」之后。先确认他已经在真卡片上说过「没问题」(`design accept` 已打勾),
49
+ 并把这一版写进 `CHANGELOG.md`:`workbench_diy_changelog`(`unit=…`,`note=…`;
50
+ 没写这一版 `release` 会拦下),再调 `workbench_diy_publish`(`unit=…`)。只问「给团队用、公开发、还是先给你一个安装包」;
51
+ 不展示 `package.json` / npm / 版本字段,也不要问 token。出口与 `needsUser` 处理见 [WIRING.md](WIRING.md) §5。
52
+
53
+ ## 索引
90
54
 
91
- ## 找不到一件事的时候,按这个顺序找
55
+ | 需要 | 读 |
56
+ |---|---|
57
+ | 判域、三张表、ASCII 规则 | [DESIGN.md](DESIGN.md) |
58
+ | 步骤与完成判据 | [STEPS.md](STEPS.md) |
59
+ | 探测数据源、固化读、错误码 | [DATASOURCE.md](DATASOURCE.md) |
60
+ | 写通道四步、回读、撤销 | [WRITES.md](WRITES.md) |
61
+ | 面板内容、状态矩阵、界面规则 | [PANEL.md](PANEL.md) |
62
+ | 选组件、表单、hooks | [KIT.md](KIT.md) |
63
+ | agent 能力、审批、长任务、外部供给 | [TOOLS.md](TOOLS.md) |
64
+ | 文案:三类读者、主句 / 原文、人 / agent / 开发 | [COPY.md](COPY.md) |
65
+ | DIY 工具族的参数与返回 | [FAMILY.md](FAMILY.md) |
66
+ | 面板何时刷新、事实名 | [LINKAGE.md](LINKAGE.md) |
67
+ | 落点、模板文件、命令、两个面 | [BUILD.md](BUILD.md) |
68
+ | 依赖、禁区、安装、热换、发布 | [WIRING.md](WIRING.md) |
69
+ | 门禁报错、卡片故障取证 | [REVIEW.md](REVIEW.md) |
92
70
 
93
- 1. **先跑门禁**:`dsh-wb-module check --only <那一条>` 的报错原文最准。
94
- 「外壳的 kit 里到底有什么组件 / hooks」「dsh 原语里有什么、某一件怎么用」在工坊会话里直接调
95
- `workbench_diy_components`(不填给清单,`name=Button` 回它的类型文件与声明);工程域用
96
- `check --only kit` · `check --only primitives`(`--all` 全表、`--json` 机器档)。
97
- 2. **再看模板**:已经有一个同形状、能跑的最小实现,比任何描述都准 ——
98
- 在你工坊的 `node_modules/@dsh-workbench/module-tools/template-diy/`(带真数据源的样板)
99
- 与 `template/`(空壳)里,原文都是可读的。
100
- 3. **最后看你装的那份外壳**:`node_modules/@dsh-workbench/core/dist/types/**` 是它的类型面,
101
- `node_modules/@dsh-workbench/core/skills/workbench-module-diy/**` 就是这份指引。
102
- 它的 README 与 `docs/HANDOFF.md` / `docs/OPERATIONS.md` 也在包里。
71
+ ## 查不到时
103
72
 
104
- ⚠️ **你手上就是这两份**:工坊会话里够得到的是 `node_modules/@dsh-workbench/…` ——
105
- 外壳与 `dsh-wb-module` 都在那儿;别处没有。
73
+ 1. `dsh-wb-module check --only <判据>` 的报错原文。
74
+ 2. kit / dsh 原语 / CSS 令牌:`workbench_diy_components`(DIY 会话;令牌给 `scope: 'tokens'`,现读现给);
75
+ 工程域 `check --only kit` / `--only primitives`。
76
+ 3. 模板:`node_modules/@dsh-workbench/module-tools/template-diy/` 与 `template/`。
77
+ 4. 安装包的类型面:`node_modules/@dsh-workbench/core/dist/types/**`;本指引:`node_modules/@dsh-workbench/core/skills/workbench-module-diy/**`。
106
78
 
107
- ## 三条不许松的
79
+ ## 硬约束
108
80
 
109
- - **dsh 已经有的,先从 `kit` 拿**(`@dsh-workbench/core/client`),不许从 DOM + CSS 重画;
110
- 也不直接 import dsh 的包 —— 直接引会被门禁拦,而且那是第二份实例。
111
- - **工坊里的模块一律 `private: true`,不发到任何源。**
112
- - **源码里只许 JSDoc,且贴着导出**(用法住在声明里,tsc 把它搬进 `.d.ts`);`//`、实现里的解释、
113
- 以及 `.css` 里的注释照旧不许有。要说的"为什么"写进模块自己的 `README.md` 或 spec。
81
+ - dsh 已有的从 `kit` 拿(`@dsh-workbench/core/client`);不手搓 DOM + CSS,不直接 import dsh 的包。
82
+ - DIY 模块默认 `private: true`,不发任何源;用户确认后走 `workbench_diy_publish` 发到团队源 / 公网 / 安装包 / git。
83
+ - 源码零注释(`//`、块注释、`.css` 注释都不许);说明写模块 `README.md` 或 spec。
@@ -1,97 +1,94 @@
1
- # 三步:每一步问什么、要定什么、什么时候算做完
1
+ # 三步:问什么、产出什么、何时算完
2
2
 
3
- [DESIGN.md](DESIGN.md) 是三张表的来历,本文是每一步的**问法**与**完成判据**。
3
+ 每一步的结果当场写进 `design.json`:`panel` / `states` / `config` / `capabilities` / `linkage` /
4
+ `datasource` / `reads[]` / `writes[]` / `acceptance`。`design check` 列出空格。
4
5
 
5
- 每一步定下来的东西都**当场落进**模块里的 `design.json`:面板 = `panel` / `states`、配置 = `config`、
6
- 能力 = `capabilities`、联动 = `linkage`、数据源 = `datasource` / `reads[]`、写通道 = `writes[]`(单条可写 `write{}`)、验收 = `acceptance`。
7
- `dsh-wb-module design check` 会把空着的格列出来 —— **只留在对话里等于没定**。
6
+ ## 步骤 1 — 面板
8
7
 
9
- ## 步骤 1 — 面板:他看什么,他配什么
8
+ 一次问一组,每组给推荐答案:
10
9
 
11
- 先问出来(一次问一组,每组带推荐答案):
10
+ - 打开面板第一眼看到什么?拿它做什么决定?
11
+ - 哪些事要能自己配?配完看到什么不同?
12
+ - 哪些事一定会说给 agent 听?原话是什么?
12
13
 
13
- - 打开这块面板,他**第一眼**要看到什么?他拿这个答案去做什么决定?
14
- - 哪些事他要能自己配?配完以后,他看到的会有什么不同?
15
- - 哪些事他一定会说给 agent 听?**那句话原文**是什么?
14
+ 定四件事:
16
15
 
17
- 要定的四件事:
16
+ 1. **展示清单**,每条一句人话:这一格是什么 / 一眼得出什么结论 / 点一下去哪。详情、评论、流转、日志不在面板做。
17
+ 2. **配置清单**:管什么 / 默认 / 候选从哪来 / 选错怎样 / 按项目记 / 何时生效 / 怎么清。
18
+ 3. **分流**:反复做且要动平台的 → 交给 agent;多步、长等、中途要人、失败要续的 → 封成一个动作(按钮 + 交给 agent 的入口);
19
+ 只是看 → 只读。
20
+ 4. **状态矩阵**:每态「看到什么 / 能做什么 / agent 能接着做什么」。
18
21
 
19
- 1. **展示清单**(每条一句人话):这一格是什么、一眼能得出什么结论、点一下可以去哪(去平台看详情 / 交给 agent)。详情、评论、流转、日志这类**零散操作不在面板做**。
20
- 2. **配置清单**:用他的话说清 这管什么 / 默认是什么 / 他能选的值从哪来 / 选错了会怎样 / 按项目分别记 / 他自己按的才生效 / 怎么清掉。
21
- 3. **分流**:他会反复做、要动平台上东西的事 → 交给 agent;一次要动好几下、要等很久、中途要他登录或点头、失败要能接着来的 → 封成一个动作,给他一个按钮(+ 一个交给 agent 的入口);只是看看 → 只读呈现。
22
- 4. **状态矩阵**:每种状态下"屏幕上是什么 + 他能做什么 + agent 能接着做什么"。
22
+ 产出:ASCII 画面(卡片、设置面、每种状态)+ 状态矩阵(左列图号)+ 图例。
23
23
 
24
- **这一步做完要给他看的**:**ASCII 画面** —— 卡片、设置面、每一种状态都画出来 + 状态矩阵(左列图号)与图例。
24
+ 判据:
25
25
 
26
- **完成判据**
26
+ - 用户对着图确认过每种状态,或指出哪格不对。
27
+ - 每格是用户看得见或能操作的事,没有"系统内部会…"。
28
+ - 矩阵每个词都能在图例里指到屏幕;图例不能只是同义词。
29
+ - 每种缺失有一句可照做的话:缺什么、去哪补、谁补。
30
+ - 每个控件对应一句用户会对 agent 说的话,界面上有该句的位置。
31
+ - 真机造不出的状态也有设计。
27
32
 
28
- - 他**对着这些图**看过每一种状态,说过"就这样"或指出了哪一格不对。
29
- - 表里每一格都是他**看得见或能操作**的事,没有一句"系统内部会…"。
30
- - 矩阵里每个词都在图例里指到了屏幕上的样子;没有图例,或图例里只有同义词,都算没写完。
31
- - 每种缺失都有一句**能照做**的话:缺什么、去哪补、谁补(他 / agent / 平台)。
32
- - 每个控件都能翻译成一句他对 agent 说的话,且那句话在界面上有位置。
33
- - 每种状态都有设计 —— 真机上造不出来的那些也要写。
33
+ → [PANEL.md](PANEL.md)
34
34
 
35
- → 清单怎么写、界面习惯、状态话术:[PANEL.md](PANEL.md)
35
+ ## 步骤 2 — agent 能力
36
36
 
37
- ## 步骤 2 — agent:他能替用户做什么,哪几件要用户点头
37
+ 先问:
38
38
 
39
- 先问出来:
39
+ - 用户会怎么说这件事?agent 需要先知道什么?
40
+ - agent 做完,用户需要知道什么?
41
+ - 哪些是真动手、必须先点头?点头时要看到什么?
40
42
 
41
- - 他会怎么跟 agent 说这件事?agent 得先知道什么才不用猜?
42
- - agent 做完,他需要知道什么?
43
- - 哪几件是**真的动手了**、他必须先点头?点头时他想看到什么,才敢点?
43
+ 定五件事:
44
44
 
45
- 要定的五件事:
45
+ 1. **能力清单**:每件事一句"agent 能做什么";说明为何是独立的事,而不是某件事的选项。
46
+ 2. **入参 / 返回**:贴真实调用(参数 JSON)与真实返回正文(照抄)。补默认值、上限(不悄悄截)、
47
+ 取值范围、给错怎么改。
48
+ 3. **全场景**:正常 / 没有 / 分不清是哪一份(不许猜)/ 参数错 / 超上限 / 能力未装好 / 要登录或超时 /
49
+ 还有下一批 / 截断(说清截了什么、多少)/ 没有当前项目。
50
+ 4. **写操作两拍**:先预览(说清将要做什么),再执行。预览让用户判断"要不要做",不是"要不要允许"。
51
+ 5. **点头范围**:改平台 / 改这台机器 / 改面板。点头时展示这次具体发生什么(对象、版本、环境);
52
+ 说不清就不问,停下让 agent 去查。
46
53
 
47
- 1. **能力清单**:每件事一句"agent 能做什么";并说清它为什么是一件独立的事,而不是已有一件事的一个选项。
48
- 2. **传什么 / 拿回什么**:**贴真实的那一段** —— 真实调用(参数 JSON)+ 真实返回正文(**照抄,不转述**),再附默认值(不给等于什么)、上限(要多少给多少,**不悄悄截**)、范围(只认哪几个值)、给错怎么改。凡是"大概是这样的",都不算。
49
- 3. **每件事的全场景**:正常 / 没有 / **说不清是哪一份**(不许猜,让他选)/ 参数不对 / 超出上限 / 能力还没装好 / 平台要登录或超时 / 还有下一批 / 太长截断了(说清截了什么、多少)/ 没有正在做的项目。
50
- 4. **动手的事分两拍**:先预览(说清**将要做什么**,让他确认),再真的做。预览的话要让他能判断"要不要做",不是"要不要允许"。
51
- 5. **哪几件要点头**:会改平台上东西的、会改这台机器的、会改他面板的。
52
- - 点头时他要看到**这次真的会发生什么**(哪一个对象、什么版本、到什么环境),不是"这个操作会写数据"。
53
- - **说不清这次会发生什么就不许问**:停下,把原因告诉 agent 让它去查 —— 用户不该为一个看不清的后果点头。
54
+ 产出:真实调用与返回,逐条贴出。能连平台就真跑;不能就用真实代码输出并标注样例。
54
55
 
55
- **这一步做完要给他看的**:**真实的调用与返回**,一条一条贴出来给他看(不是概述):能打到平台就真跑一遍、把记录贴出来;打不到就用真实代码产出的输出,并标明哪些值是样例。
56
+ 判据:
56
57
 
57
- **完成判据**
58
+ - 每种情况有确定结果;拒绝文案带 agent 可执行的下一步。
59
+ - 入参与返回照抄;边界给真实报错原文。
60
+ - 分不清的那格不许猜、不许退回默认。
61
+ - 截断、越界、分页说清边界与下一批。
62
+ - 点头格写"会发生什么",不写"这是什么操作"。
63
+ - 用户自按入口不点头,但与 agent 同一条链路、同一结果。
58
64
 
59
- - 每件事的每种情况都有确定结果;拒绝的话里带 agent 能照做的下一步。
60
- - 每一件都贴着**真实调用与真实返回**(照抄的正文,不是转述);边界情况给的是**真实的报错原文**。
61
- - "说不清是哪一份"这一格不许猜,也不许悄悄退回默认。
62
- - 截断、越界、分页都说清了边界在哪、下一批怎么拿。
63
- - 点头那一格写的是"会发生什么",不是"这是什么操作";补不齐后果的那条路是**停下**,不是硬问。
64
- - 用户自己按的那个入口不需要点头,但和 agent 走的是同一件事、看到同一个结果。
65
+ → [TOOLS.md](TOOLS.md)
65
66
 
66
- → 能力怎么划、点头全场景、预览怎么写:[TOOLS.md](TOOLS.md)
67
+ ## 步骤 3 — 联动
67
68
 
68
- ## 步骤 3 — 联动:agent 做完,用户看到什么
69
+ 先问:
69
70
 
70
- 先问出来:
71
+ - agent 改完,多久看到、哪一格变?
72
+ - agent 只读,面板是否变、变哪格?(口径 [LINKAGE.md](LINKAGE.md) §1)
73
+ - agent 跑几分钟时,用户看哪?
74
+ - 点"交给 agent"后,agent 拿到什么?
71
75
 
72
- - agent 改完,他需要多久看到、看到哪一格变?
73
- - agent 只是**读**了一下(看一眼),面板该不该动、动哪一格?(口径:读的是这一格 → 这一格变;
74
- 读的是面板上没有的东西 → 不动。见 [LINKAGE.md](LINKAGE.md) §1)
75
- - agent 正在干(要几分钟)的时候,他看哪儿?
76
- - 他点"交给 agent"之后,agent 手上拿到的是什么?
76
+ 定五件事:
77
77
 
78
- 要定的五件事:
78
+ 1. **何时变**:读这一格 → 该格按最窄切片重读,值与对话一致;读面板外的东西(明细 / 日志 / 子集)→ 不变;
79
+ 预览 → 不变;真写 → 该格新值;用户自按 → 立刻变。
80
+ 2. **进行中**:显示到哪步;要登录给链接;失败给原因与原始输出。不画进度条、不画流程控制台。
81
+ 3. **交给 agent 的内容**:哪一类、哪个对象、多少,加一句用哪个能力取明细。
82
+ 4. **收起模块 = 该项目内 agent 也失去该能力**,开始时说明。
83
+ 5. **不陈旧**:切项目、别的窗口在改、程序刚更新,三者要么实时要么说清。
79
84
 
80
- 1. **什么时候面板该动**:agent **读了这一格** → 那一格按最窄切片变(值跟对话里那份一样);读的是面板上没有的东西(明细 / 日志 / 某档子集)→ **不动**;只预览 → **不动**;真的做了 → 那一格变成新值;他自己按的动作 → 那一格立刻变。
81
- 2. **正在干的时候**:显示到哪一步、要登录给他链接、失败给他原因和原始输出;**不画进度条、不画流程控制台**。
82
- 3. **"交给 agent"之后 agent 拿到什么**:哪一类、哪个对象、多少,加一句"该用哪个能力再往下拿"(agent 打不开面板上那个 ↗,明细得靠它自己再问一次)。
83
- 4. **收起模块 = 这个项目里 agent 也做不了这件事**,要在一开始就说清。
84
- 5. **面板凭什么不旧**:切项目、别的窗口也在改、程序刚更新过 —— 这三种都要么实时、要么说清。
85
+ 产出:"变之前 / 变之后"两张 ASCII + 联动表(何时变、哪格变)。
85
86
 
86
- **这一步做完要给他看的**:**"变之前 / 变之后"两张 ASCII 并排** + 一张联动表(每格说清什么时候变、哪一格变)。
87
+ 判据:
87
88
 
88
- **完成判据**
89
+ - 用户对着两张图看过一次真实变化。
90
+ - 每格说清"何时变、哪格变、看到什么";"哪一格"细到"某投影 + 最窄参数"(`inventory/builds?env=dev`)。
91
+ - 面板不停在旧值;允许延迟但要说清。
92
+ - 每个"交给 agent"都说清 agent 收到的内容。
89
93
 
90
- - 他**对着那两张图**看过至少一次真实的变化(agent 做完面板变成什么样)。
91
- - 每一格都说清"什么时候变、哪一格变、用户看到什么",没有"刷新一下"这类模糊说法;
92
- "哪一格"要细到能落成"某条投影 + 最窄那个参数"(`cmdb/builds?env=dev` 这种),
93
- 不然实现的人只会整卡重读([LINKAGE.md](LINKAGE.md) §1 末段)。
94
- - 面板自己永远不会停在旧值上(允许有延迟,但延迟要说清)。
95
- - 每一颗"交给 agent"都说清了进到 agent 眼里的那段话是什么。
96
-
97
- → 联动场景表:[LINKAGE.md](LINKAGE.md)
94
+ → [LINKAGE.md](LINKAGE.md)