@joekytc/dsh-swarm 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/README.md +3 -3
  2. package/README.zh-CN.md +3 -3
  3. package/client/BoardCard.tsx +24 -2
  4. package/client/ConfigSection.tsx +71 -0
  5. package/client/ConfigSelect.tsx +69 -0
  6. package/client/KanbanBoard.tsx +3 -0
  7. package/client/KanbanTab.tsx +4 -3
  8. package/client/TaskDrawer.tsx +2 -26
  9. package/client/WorkflowRail.tsx +3 -1
  10. package/client/config-store.ts +51 -0
  11. package/client/config.css +110 -0
  12. package/client/index.ts +39 -4
  13. package/client/kanban.css +19 -2
  14. package/client/session-bridge.ts +39 -0
  15. package/client/timeline-model.ts +10 -1
  16. package/client/workflow-model.ts +3 -1
  17. package/lib/client.js +358 -53
  18. package/lib/config.d.ts +8 -1
  19. package/lib/config.js +6 -1
  20. package/lib/dispatcher/agent-runner.d.ts +28 -6
  21. package/lib/dispatcher/agent-runner.js +175 -62
  22. package/lib/dispatcher/chain-auditor.js +4 -1
  23. package/lib/dispatcher/dispatcher.d.ts +62 -3
  24. package/lib/dispatcher/dispatcher.js +243 -20
  25. package/lib/dispatcher/session-events.d.ts +11 -15
  26. package/lib/dispatcher/session-events.js +17 -5
  27. package/lib/dispatcher/v-orchestrator.d.ts +42 -9
  28. package/lib/dispatcher/v-orchestrator.js +236 -28
  29. package/lib/domain/config-override.d.ts +38 -0
  30. package/lib/domain/config-override.js +101 -0
  31. package/lib/domain/delivery-contract.d.ts +3 -2
  32. package/lib/domain/delivery-contract.js +28 -16
  33. package/lib/domain/gate-policy.d.ts +26 -0
  34. package/lib/domain/gate-policy.js +44 -0
  35. package/lib/domain/kanban-service.d.ts +16 -3
  36. package/lib/domain/kanban-service.js +41 -6
  37. package/lib/domain/permissions.js +1 -1
  38. package/lib/domain/planning-checklist.d.ts +5 -0
  39. package/lib/domain/planning-checklist.js +80 -6
  40. package/lib/domain/projection.js +2 -1
  41. package/lib/domain/review-evidence.js +1 -1
  42. package/lib/domain/state-machine.js +2 -1
  43. package/lib/domain/types.d.ts +2 -2
  44. package/lib/index.js +19 -21
  45. package/lib/roles/clean-fs-tools.d.ts +22 -0
  46. package/lib/roles/clean-fs-tools.js +118 -0
  47. package/lib/roles/skill-installer.d.ts +6 -0
  48. package/lib/roles/skill-installer.js +32 -0
  49. package/lib/roles/toolsets.d.ts +13 -1
  50. package/lib/roles/toolsets.js +163 -31
  51. package/lib/roles/wiki-worker.d.ts +1 -0
  52. package/lib/roles/wiki-worker.js +10 -2
  53. package/lib/routes/kanban-http.d.ts +5 -2
  54. package/lib/routes/kanban-http.js +36 -3
  55. package/lib/routes/planning-driver.d.ts +3 -1
  56. package/lib/routes/planning-driver.js +10 -6
  57. package/lib/routes/prefix-router.d.ts +16 -0
  58. package/lib/routes/prefix-router.js +37 -2
  59. package/lib/services/config-provider.d.ts +42 -0
  60. package/lib/services/config-provider.js +94 -0
  61. package/lib/services/gate-runner.d.ts +24 -0
  62. package/lib/services/gate-runner.js +87 -0
  63. package/lib/services/kanban-provider.d.ts +5 -1
  64. package/lib/services/kanban-provider.js +40 -2
  65. package/lib/services/llm-catalog.d.ts +35 -0
  66. package/lib/services/llm-catalog.js +19 -0
  67. package/lib/tools/kanban-tools.js +1 -0
  68. package/lib/tools/main-session-tools.d.ts +17 -2
  69. package/lib/tools/main-session-tools.js +88 -21
  70. package/lib/tools/planning-tools.d.ts +4 -0
  71. package/lib/tools/planning-tools.js +39 -12
  72. package/lib/tools/prefetch-tools.js +1 -0
  73. package/lib/tools/spec-card-tools.js +1 -0
  74. package/lib/tools/wiki-tools.js +5 -4
  75. package/lib/wiki/kb-linkage.d.ts +9 -2
  76. package/lib/wiki/kb-linkage.js +3 -3
  77. package/lib/wiki/local-kb-client.d.ts +14 -0
  78. package/lib/wiki/local-kb-client.js +101 -0
  79. package/lib/wiki/local-kb.d.ts +6 -0
  80. package/lib/wiki/local-kb.js +25 -0
  81. package/lib/wiki/memory-recall.d.ts +14 -6
  82. package/lib/wiki/memory-recall.js +17 -13
  83. package/lib/wiki/page-path.d.ts +9 -3
  84. package/lib/wiki/page-path.js +29 -11
  85. package/lib/wiki/wiki-vault-client.d.ts +3 -3
  86. package/lib/wiki/wiki-vault-client.js +6 -6
  87. package/package.json +16 -11
  88. package/personas/kanban-d/preset.yml +1 -1
  89. package/personas/kanban-dt/agent.cordis.yml +2 -2
  90. package/personas/kanban-dt/preset.yml +1 -1
  91. package/personas/kanban-p/agent.cordis.yml +16 -0
  92. package/personas/kanban-p/preset.yml +1 -1
  93. package/personas/kanban-pt/agent.cordis.yml +38 -8
  94. package/personas/kanban-pt/preset.yml +1 -1
  95. package/personas/kanban-w/agent.cordis.yml +35 -16
  96. package/personas/kanban-w/preset.yml +1 -1
  97. package/personas/persona-dt.md +1 -1
  98. package/personas/persona-p.md +4 -1
  99. package/personas/persona-pt.md +13 -6
  100. package/personas/persona-w.md +11 -9
  101. package/skills/grill-me/SKILL.md +71 -0
  102. package/skills/llm-wiki-skill/.mise.toml +2 -0
  103. package/skills/llm-wiki-skill/.nvmrc +1 -0
  104. package/skills/llm-wiki-skill/AGENTS.md +173 -0
  105. package/skills/llm-wiki-skill/CHANGELOG.md +548 -0
  106. package/skills/llm-wiki-skill/CLAUDE.md +152 -0
  107. package/skills/llm-wiki-skill/HERMES.md +44 -0
  108. package/skills/llm-wiki-skill/README.en.md +261 -0
  109. package/skills/llm-wiki-skill/README.md +291 -0
  110. package/skills/llm-wiki-skill/SKILL.md +1133 -0
  111. package/skills/llm-wiki-skill/assets/graph-demo.gif +0 -0
  112. package/skills/llm-wiki-skill/assets/graph-preview.png +0 -0
  113. package/skills/llm-wiki-skill/deps/LICENSE-d3.txt +13 -0
  114. package/skills/llm-wiki-skill/deps/LICENSE-marked.txt +44 -0
  115. package/skills/llm-wiki-skill/deps/LICENSE-purify.txt +568 -0
  116. package/skills/llm-wiki-skill/deps/LICENSE-roughjs.txt +21 -0
  117. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/SKILL.md +261 -0
  118. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/references/config/first-time-setup.md +106 -0
  119. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/cdp.ts +179 -0
  120. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/constants.ts +13 -0
  121. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/defuddle-converter.ts +58 -0
  122. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/html-to-markdown.ts +135 -0
  123. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/legacy-converter.ts +629 -0
  124. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/main.ts +314 -0
  125. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/markdown-conversion-shared.ts +305 -0
  126. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/media-localizer.ts +317 -0
  127. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/package.json +14 -0
  128. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/paths.ts +29 -0
  129. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/package.json +9 -0
  130. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/src/index.test.ts +307 -0
  131. package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/src/index.ts +523 -0
  132. package/skills/llm-wiki-skill/deps/d3.min.js +2 -0
  133. package/skills/llm-wiki-skill/deps/marked.min.js +6 -0
  134. package/skills/llm-wiki-skill/deps/purify.min.js +3 -0
  135. package/skills/llm-wiki-skill/deps/rough.min.js +7 -0
  136. package/skills/llm-wiki-skill/deps/youtube-transcript/SKILL.md +47 -0
  137. package/skills/llm-wiki-skill/deps/youtube-transcript/scripts/get_transcript.py +72 -0
  138. package/skills/llm-wiki-skill/designs/graph-edge-legibility/graph-edge-treatments.html +480 -0
  139. package/skills/llm-wiki-skill/docs/design/oriental-atlas/DESIGN.md +183 -0
  140. package/skills/llm-wiki-skill/docs/design/oriental-atlas/README.md +10 -0
  141. package/skills/llm-wiki-skill/docs/design/oriental-atlas/design-brief.md +170 -0
  142. package/skills/llm-wiki-skill/docs/design/oriental-atlas/oriental-editorial-atlas.html +1908 -0
  143. package/skills/llm-wiki-skill/docs/design/oriental-atlas/reviews/result-review.md +68 -0
  144. package/skills/llm-wiki-skill/docs/graph/2026-06-16-interaction-risk-audit.md +88 -0
  145. package/skills/llm-wiki-skill/docs/graph/2026-06-16-interaction-test-coverage-map.md +212 -0
  146. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-0-2-baseline.md +86 -0
  147. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-1-3-dom-svg-large-baseline.md +85 -0
  148. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-1-4-disposable-validation-gate.md +97 -0
  149. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-2-4-global-renderer-trial-matrix.md +168 -0
  150. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-1-sigma-graphology-trial.md +71 -0
  151. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-2-vis-network-trial.md +78 -0
  152. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-3-aggregation-fallback-trial.md +72 -0
  153. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-4-global-renderer-route-decision.md +94 -0
  154. package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-sigma-global-production-integration-result.md +102 -0
  155. package/skills/llm-wiki-skill/docs/graph/performance/artifacts/2026-06-18-phase-0-2/stage-4.5-offline-dense-wheel.json +9 -0
  156. package/skills/llm-wiki-skill/docs/graph/performance/artifacts/2026-06-18-phase-0-2/stage-4.5-offline-dense-wheel.png +0 -0
  157. package/skills/llm-wiki-skill/docs/graph/performance/artifacts/2026-06-18-phase-0-2/stage-4.5-offline-navigation.png +0 -0
  158. package/skills/llm-wiki-skill/docs/spark/2026-06-15-omp-tool-status-events-design.md +174 -0
  159. package/skills/llm-wiki-skill/docs/spark/2026-06-16-graph-interaction-geometry-design.md +832 -0
  160. package/skills/llm-wiki-skill/docs/spark/2026-06-16-graph-six-layer-architecture-design.md +577 -0
  161. package/skills/llm-wiki-skill/docs/spark/2026-06-17-static-renderer-coordination-split-design.md +172 -0
  162. package/skills/llm-wiki-skill/docs/spark/2026-06-18-large-graph-global-community-design.md +909 -0
  163. package/skills/llm-wiki-skill/docs/spark/2026-06-19-sigma-global-graph-renderer-design.md +360 -0
  164. package/skills/llm-wiki-skill/docs/spark/2026-06-20-paper-ui-port-design.md +162 -0
  165. package/skills/llm-wiki-skill/docs/spark/2026-06-20-paper-ui-v2-shell-alignment-design.md +384 -0
  166. package/skills/llm-wiki-skill/docs/spark/2026-06-21-graph-experience-completion-design.md +534 -0
  167. package/skills/llm-wiki-skill/docs/spark/2026-06-22-chat-auto-scroll-design.md +185 -0
  168. package/skills/llm-wiki-skill/docs/spark/2026-06-22-graph-community-node-visual-design.md +266 -0
  169. package/skills/llm-wiki-skill/docs/spark/2026-06-25-sigma-overlay-refactor-perf-design.md +170 -0
  170. package/skills/llm-wiki-skill/docs/spark/2026-06-26-global-sigma-community-spotlight-design.md +393 -0
  171. package/skills/llm-wiki-skill/docs/spark/mockups/2026-06-18-large-graph-global-community-flow.html +746 -0
  172. package/skills/llm-wiki-skill/install.ps1 +87 -0
  173. package/skills/llm-wiki-skill/install.sh +722 -0
  174. package/skills/llm-wiki-skill/package-lock.json +11171 -0
  175. package/skills/llm-wiki-skill/package.json +24 -0
  176. package/skills/llm-wiki-skill/packages/graph-engine/package.json +37 -0
  177. package/skills/llm-wiki-skill/packages/graph-engine/src/anim/.gitkeep +1 -0
  178. package/skills/llm-wiki-skill/packages/graph-engine/src/anim/index.ts +179 -0
  179. package/skills/llm-wiki-skill/packages/graph-engine/src/architecture.ts +79 -0
  180. package/skills/llm-wiki-skill/packages/graph-engine/src/diff.ts +121 -0
  181. package/skills/llm-wiki-skill/packages/graph-engine/src/facade.ts +1406 -0
  182. package/skills/llm-wiki-skill/packages/graph-engine/src/graph-node.ts +37 -0
  183. package/skills/llm-wiki-skill/packages/graph-engine/src/index.ts +25 -0
  184. package/skills/llm-wiki-skill/packages/graph-engine/src/layout/edge-geometry.ts +17 -0
  185. package/skills/llm-wiki-skill/packages/graph-engine/src/layout/index.ts +16 -0
  186. package/skills/llm-wiki-skill/packages/graph-engine/src/layout/spatial-index.ts +509 -0
  187. package/skills/llm-wiki-skill/packages/graph-engine/src/model/atlas.ts +18 -0
  188. package/skills/llm-wiki-skill/packages/graph-engine/src/model/index.ts +10 -0
  189. package/skills/llm-wiki-skill/packages/graph-engine/src/model/labels.ts +11 -0
  190. package/skills/llm-wiki-skill/packages/graph-engine/src/model/layout.ts +81 -0
  191. package/skills/llm-wiki-skill/packages/graph-engine/src/model/learning.ts +8 -0
  192. package/skills/llm-wiki-skill/packages/graph-engine/src/model/legacy-helpers.ts +1379 -0
  193. package/skills/llm-wiki-skill/packages/graph-engine/src/model/queue.ts +7 -0
  194. package/skills/llm-wiki-skill/packages/graph-engine/src/model/storage.ts +4 -0
  195. package/skills/llm-wiki-skill/packages/graph-engine/src/model/visibility.ts +9 -0
  196. package/skills/llm-wiki-skill/packages/graph-engine/src/render/.gitkeep +1 -0
  197. package/skills/llm-wiki-skill/packages/graph-engine/src/render/adapter.ts +443 -0
  198. package/skills/llm-wiki-skill/packages/graph-engine/src/render/aggregation-containers.ts +64 -0
  199. package/skills/llm-wiki-skill/packages/graph-engine/src/render/community-cloud-geometry.ts +178 -0
  200. package/skills/llm-wiki-skill/packages/graph-engine/src/render/community-wash.ts +238 -0
  201. package/skills/llm-wiki-skill/packages/graph-engine/src/render/community-washes.ts +19 -0
  202. package/skills/llm-wiki-skill/packages/graph-engine/src/render/compat-contract.ts +14 -0
  203. package/skills/llm-wiki-skill/packages/graph-engine/src/render/controller.ts +705 -0
  204. package/skills/llm-wiki-skill/packages/graph-engine/src/render/controls.ts +288 -0
  205. package/skills/llm-wiki-skill/packages/graph-engine/src/render/dom-svg-renderer.ts +180 -0
  206. package/skills/llm-wiki-skill/packages/graph-engine/src/render/edges.ts +51 -0
  207. package/skills/llm-wiki-skill/packages/graph-engine/src/render/geometry.ts +380 -0
  208. package/skills/llm-wiki-skill/packages/graph-engine/src/render/gestures.ts +673 -0
  209. package/skills/llm-wiki-skill/packages/graph-engine/src/render/graph-renderer-root.ts +387 -0
  210. package/skills/llm-wiki-skill/packages/graph-engine/src/render/hit-testing.ts +56 -0
  211. package/skills/llm-wiki-skill/packages/graph-engine/src/render/host-dom.ts +14 -0
  212. package/skills/llm-wiki-skill/packages/graph-engine/src/render/hover-card.ts +37 -0
  213. package/skills/llm-wiki-skill/packages/graph-engine/src/render/index.ts +213 -0
  214. package/skills/llm-wiki-skill/packages/graph-engine/src/render/keyboard.ts +48 -0
  215. package/skills/llm-wiki-skill/packages/graph-engine/src/render/legend.ts +25 -0
  216. package/skills/llm-wiki-skill/packages/graph-engine/src/render/minimap.ts +45 -0
  217. package/skills/llm-wiki-skill/packages/graph-engine/src/render/model.ts +1339 -0
  218. package/skills/llm-wiki-skill/packages/graph-engine/src/render/node-drag-lifecycle.ts +94 -0
  219. package/skills/llm-wiki-skill/packages/graph-engine/src/render/nodes.ts +103 -0
  220. package/skills/llm-wiki-skill/packages/graph-engine/src/render/offline-reader.ts +209 -0
  221. package/skills/llm-wiki-skill/packages/graph-engine/src/render/overlays-presenter.ts +192 -0
  222. package/skills/llm-wiki-skill/packages/graph-engine/src/render/overlays.ts +73 -0
  223. package/skills/llm-wiki-skill/packages/graph-engine/src/render/pin-position.ts +51 -0
  224. package/skills/llm-wiki-skill/packages/graph-engine/src/render/preview.ts +65 -0
  225. package/skills/llm-wiki-skill/packages/graph-engine/src/render/relation-focus.ts +91 -0
  226. package/skills/llm-wiki-skill/packages/graph-engine/src/render/render-context.ts +85 -0
  227. package/skills/llm-wiki-skill/packages/graph-engine/src/render/render-pipeline.ts +871 -0
  228. package/skills/llm-wiki-skill/packages/graph-engine/src/render/render-styles.ts +1405 -0
  229. package/skills/llm-wiki-skill/packages/graph-engine/src/render/renderer-surface.ts +75 -0
  230. package/skills/llm-wiki-skill/packages/graph-engine/src/render/search.ts +57 -0
  231. package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-coordinates.ts +44 -0
  232. package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-global-drag.ts +246 -0
  233. package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-global-renderer.ts +1425 -0
  234. package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-overlay-svg.ts +121 -0
  235. package/skills/llm-wiki-skill/packages/graph-engine/src/render/simulation-bridge.ts +59 -0
  236. package/skills/llm-wiki-skill/packages/graph-engine/src/render/state.ts +262 -0
  237. package/skills/llm-wiki-skill/packages/graph-engine/src/render/toolbar.ts +40 -0
  238. package/skills/llm-wiki-skill/packages/graph-engine/src/render/viewport.ts +336 -0
  239. package/skills/llm-wiki-skill/packages/graph-engine/src/select/.gitkeep +1 -0
  240. package/skills/llm-wiki-skill/packages/graph-engine/src/select/index.ts +189 -0
  241. package/skills/llm-wiki-skill/packages/graph-engine/src/sim/index.ts +372 -0
  242. package/skills/llm-wiki-skill/packages/graph-engine/src/sim/pins.ts +84 -0
  243. package/skills/llm-wiki-skill/packages/graph-engine/src/summary/index.ts +447 -0
  244. package/skills/llm-wiki-skill/packages/graph-engine/src/themes/.gitkeep +1 -0
  245. package/skills/llm-wiki-skill/packages/graph-engine/src/themes/index.ts +8 -0
  246. package/skills/llm-wiki-skill/packages/graph-engine/src/themes/tokens.ts +117 -0
  247. package/skills/llm-wiki-skill/packages/graph-engine/src/types/d3-quadtree.d.ts +22 -0
  248. package/skills/llm-wiki-skill/packages/graph-engine/src/types.ts +531 -0
  249. package/skills/llm-wiki-skill/packages/graph-engine/test/aggregation-fallback-trial-adapter.test.ts +115 -0
  250. package/skills/llm-wiki-skill/packages/graph-engine/test/aggregation-fallback-trial-adapter.ts +222 -0
  251. package/skills/llm-wiki-skill/packages/graph-engine/test/anim.test.ts +121 -0
  252. package/skills/llm-wiki-skill/packages/graph-engine/test/architecture.test.ts +63 -0
  253. package/skills/llm-wiki-skill/packages/graph-engine/test/community-cloud-geometry.test.ts +86 -0
  254. package/skills/llm-wiki-skill/packages/graph-engine/test/community-wash.test.ts +97 -0
  255. package/skills/llm-wiki-skill/packages/graph-engine/test/diff.test.ts +133 -0
  256. package/skills/llm-wiki-skill/packages/graph-engine/test/facade.test.ts +1369 -0
  257. package/skills/llm-wiki-skill/packages/graph-engine/test/geometry.test.ts +147 -0
  258. package/skills/llm-wiki-skill/packages/graph-engine/test/gestures.test.ts +768 -0
  259. package/skills/llm-wiki-skill/packages/graph-engine/test/graph-layout.test.ts +110 -0
  260. package/skills/llm-wiki-skill/packages/graph-engine/test/helpers.test.ts +287 -0
  261. package/skills/llm-wiki-skill/packages/graph-engine/test/interaction-contract.test.ts +106 -0
  262. package/skills/llm-wiki-skill/packages/graph-engine/test/keyboard.test.ts +59 -0
  263. package/skills/llm-wiki-skill/packages/graph-engine/test/large-fixtures.test.ts +47 -0
  264. package/skills/llm-wiki-skill/packages/graph-engine/test/large-graph-fixtures.ts +420 -0
  265. package/skills/llm-wiki-skill/packages/graph-engine/test/learning.test.ts +259 -0
  266. package/skills/llm-wiki-skill/packages/graph-engine/test/node-drag-lifecycle.test.ts +166 -0
  267. package/skills/llm-wiki-skill/packages/graph-engine/test/overlays.test.ts +115 -0
  268. package/skills/llm-wiki-skill/packages/graph-engine/test/preview.test.ts +56 -0
  269. package/skills/llm-wiki-skill/packages/graph-engine/test/queue.test.ts +114 -0
  270. package/skills/llm-wiki-skill/packages/graph-engine/test/relation-focus.test.ts +115 -0
  271. package/skills/llm-wiki-skill/packages/graph-engine/test/render-model.test.ts +1030 -0
  272. package/skills/llm-wiki-skill/packages/graph-engine/test/renderer-adapter-contract.test.ts +271 -0
  273. package/skills/llm-wiki-skill/packages/graph-engine/test/renderer-boundary.test.ts +618 -0
  274. package/skills/llm-wiki-skill/packages/graph-engine/test/renderer-lifecycle.test.ts +1711 -0
  275. package/skills/llm-wiki-skill/packages/graph-engine/test/route-continuity.test.ts +284 -0
  276. package/skills/llm-wiki-skill/packages/graph-engine/test/runtime-state.test.ts +281 -0
  277. package/skills/llm-wiki-skill/packages/graph-engine/test/search-and-legend.test.ts +124 -0
  278. package/skills/llm-wiki-skill/packages/graph-engine/test/select.test.ts +168 -0
  279. package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-coordinates.test.ts +50 -0
  280. package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-global-renderer.test.ts +2210 -0
  281. package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-trial-adapter.test.ts +82 -0
  282. package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-trial-adapter.ts +271 -0
  283. package/skills/llm-wiki-skill/packages/graph-engine/test/sim.test.ts +207 -0
  284. package/skills/llm-wiki-skill/packages/graph-engine/test/simulation-bridge.test.ts +96 -0
  285. package/skills/llm-wiki-skill/packages/graph-engine/test/spatial-index.test.ts +222 -0
  286. package/skills/llm-wiki-skill/packages/graph-engine/test/state.test.ts +189 -0
  287. package/skills/llm-wiki-skill/packages/graph-engine/test/summary-contract.test.ts +422 -0
  288. package/skills/llm-wiki-skill/packages/graph-engine/test/themes.test.ts +62 -0
  289. package/skills/llm-wiki-skill/packages/graph-engine/test/toolbar.test.ts +64 -0
  290. package/skills/llm-wiki-skill/packages/graph-engine/test/viewport.test.ts +213 -0
  291. package/skills/llm-wiki-skill/packages/graph-engine/test/vis-network-trial-adapter.test.ts +82 -0
  292. package/skills/llm-wiki-skill/packages/graph-engine/test/vis-network-trial-adapter.ts +186 -0
  293. package/skills/llm-wiki-skill/packages/graph-engine/tsconfig.json +17 -0
  294. package/skills/llm-wiki-skill/packages/graph-engine/vite.config.ts +15 -0
  295. package/skills/llm-wiki-skill/platforms/claude/CLAUDE.md +37 -0
  296. package/skills/llm-wiki-skill/platforms/claude/companions/llm-wiki-upgrade/SKILL.md +95 -0
  297. package/skills/llm-wiki-skill/platforms/codex/AGENTS.md +23 -0
  298. package/skills/llm-wiki-skill/platforms/hermes/README.md +31 -0
  299. package/skills/llm-wiki-skill/platforms/openclaw/README.md +31 -0
  300. package/skills/llm-wiki-skill/scripts/adapter-state.sh +424 -0
  301. package/skills/llm-wiki-skill/scripts/build-graph-data.sh +395 -0
  302. package/skills/llm-wiki-skill/scripts/build-graph-html.sh +459 -0
  303. package/skills/llm-wiki-skill/scripts/cache.sh +352 -0
  304. package/skills/llm-wiki-skill/scripts/create-source-page.sh +100 -0
  305. package/skills/llm-wiki-skill/scripts/delete-helper.sh +68 -0
  306. package/skills/llm-wiki-skill/scripts/graph-analysis.js +732 -0
  307. package/skills/llm-wiki-skill/scripts/hook-session-start.sh +46 -0
  308. package/skills/llm-wiki-skill/scripts/init-wiki.sh +95 -0
  309. package/skills/llm-wiki-skill/scripts/lib/source-signal-eligibility.js +158 -0
  310. package/skills/llm-wiki-skill/scripts/lint-fix.sh +114 -0
  311. package/skills/llm-wiki-skill/scripts/lint-runner.sh +217 -0
  312. package/skills/llm-wiki-skill/scripts/runtime-context.sh +77 -0
  313. package/skills/llm-wiki-skill/scripts/shared-config.sh +83 -0
  314. package/skills/llm-wiki-skill/scripts/source-record-contract.tsv +10 -0
  315. package/skills/llm-wiki-skill/scripts/source-registry.sh +349 -0
  316. package/skills/llm-wiki-skill/scripts/source-registry.tsv +10 -0
  317. package/skills/llm-wiki-skill/scripts/source-signal-coverage.js +83 -0
  318. package/skills/llm-wiki-skill/scripts/validate-step1.sh +144 -0
  319. package/skills/llm-wiki-skill/scripts/wiki-compat.sh +267 -0
  320. package/skills/llm-wiki-skill/setup.sh +8 -0
  321. package/skills/llm-wiki-skill/templates/entity-template.md +30 -0
  322. package/skills/llm-wiki-skill/templates/graph-styles/wash/footer.html +27 -0
  323. package/skills/llm-wiki-skill/templates/graph-styles/wash/graph-wash-helpers.js +1326 -0
  324. package/skills/llm-wiki-skill/templates/graph-styles/wash/graph-wash.js +1009 -0
  325. package/skills/llm-wiki-skill/templates/graph-styles/wash/header.html +2002 -0
  326. package/skills/llm-wiki-skill/templates/index-en-template.md +51 -0
  327. package/skills/llm-wiki-skill/templates/index-template.md +51 -0
  328. package/skills/llm-wiki-skill/templates/log-en-template.md +11 -0
  329. package/skills/llm-wiki-skill/templates/log-template.md +11 -0
  330. package/skills/llm-wiki-skill/templates/overview-en-template.md +41 -0
  331. package/skills/llm-wiki-skill/templates/overview-template.md +41 -0
  332. package/skills/llm-wiki-skill/templates/purpose-en-template.md +16 -0
  333. package/skills/llm-wiki-skill/templates/purpose-template.md +16 -0
  334. package/skills/llm-wiki-skill/templates/query-template.md +19 -0
  335. package/skills/llm-wiki-skill/templates/schema-template.md +185 -0
  336. package/skills/llm-wiki-skill/templates/source-template.md +51 -0
  337. package/skills/llm-wiki-skill/templates/synthesis-template.md +25 -0
  338. package/skills/llm-wiki-skill/templates/topic-template.md +35 -0
  339. package/skills/llm-wiki-skill/tests/adapter-state.sh +338 -0
  340. package/skills/llm-wiki-skill/tests/browser/graph-aggregation-fallback-trial.ts +737 -0
  341. package/skills/llm-wiki-skill/tests/browser/graph-community-node-map.mjs +255 -0
  342. package/skills/llm-wiki-skill/tests/browser/graph-community-wash-interactions.mjs +170 -0
  343. package/skills/llm-wiki-skill/tests/browser/graph-default-behavior.mjs +630 -0
  344. package/skills/llm-wiki-skill/tests/browser/graph-density-preview.mjs +53 -0
  345. package/skills/llm-wiki-skill/tests/browser/graph-html-insights.mjs +41 -0
  346. package/skills/llm-wiki-skill/tests/browser/graph-large-performance.ts +689 -0
  347. package/skills/llm-wiki-skill/tests/browser/graph-node-slim.mjs +75 -0
  348. package/skills/llm-wiki-skill/tests/browser/graph-offline-phase-6.mjs +660 -0
  349. package/skills/llm-wiki-skill/tests/browser/graph-renderer-trial-shared.ts +291 -0
  350. package/skills/llm-wiki-skill/tests/browser/graph-sigma-global-production.ts +1437 -0
  351. package/skills/llm-wiki-skill/tests/browser/graph-sigma-graphology-trial.ts +949 -0
  352. package/skills/llm-wiki-skill/tests/browser/graph-stage-4-5.mjs +815 -0
  353. package/skills/llm-wiki-skill/tests/browser/graph-vis-network-trial.ts +762 -0
  354. package/skills/llm-wiki-skill/tests/browser/graph-workbench-interactions.mjs +730 -0
  355. package/skills/llm-wiki-skill/tests/browser/validate-graph-trial-result.mjs +149 -0
  356. package/skills/llm-wiki-skill/tests/expected/graph-data-empty.json +60 -0
  357. package/skills/llm-wiki-skill/tests/expected/graph-data-sample.json +396 -0
  358. package/skills/llm-wiki-skill/tests/expected/graph-interactive-basic.html +1736 -0
  359. package/skills/llm-wiki-skill/tests/expected/lint-output.txt +44 -0
  360. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/index.md +1 -0
  361. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Alpha.md +10 -0
  362. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Beta.md +7 -0
  363. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Delta.md +8 -0
  364. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Gamma.md +8 -0
  365. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/queries/20260422-abc.md +10 -0
  366. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/synthesis/Crystal.md +8 -0
  367. package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/topics/Overview.md +9 -0
  368. package/skills/llm-wiki-skill/tests/fixtures/graph-data-empty-wiki/wiki/entities/.gitkeep +0 -0
  369. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/purpose.md +3 -0
  370. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Attention.md +7 -0
  371. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Decoder.md +7 -0
  372. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Encoder.md +7 -0
  373. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/GPT.md +7 -0
  374. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Transformer.md +13 -0
  375. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/sources/paper.md +9 -0
  376. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/topics/arch.md +12 -0
  377. package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/topics/finetune.md +9 -0
  378. package/skills/llm-wiki-skill/tests/fixtures/graph-interactive-basic/wiki/graph-data.json +40 -0
  379. package/skills/llm-wiki-skill/tests/fixtures/graph-interactive-dense/wiki/graph-data.json +3965 -0
  380. package/skills/llm-wiki-skill/tests/fixtures/graph-interactive-multicomm/wiki/graph-data.json +212 -0
  381. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/index.md +14 -0
  382. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/C++.md +6 -0
  383. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/Lonely.md +4 -0
  384. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/Other.md +8 -0
  385. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/Real.md +7 -0
  386. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/sources/2026-01-01-test-source.md +15 -0
  387. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/sources/2026-02-01-inline-img.md +12 -0
  388. package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/topics/AIbasic.md +3 -0
  389. package/skills/llm-wiki-skill/tests/graph-aggregation-fallback-trial.regression-1.sh +46 -0
  390. package/skills/llm-wiki-skill/tests/graph-analysis-helper.regression-1.sh +237 -0
  391. package/skills/llm-wiki-skill/tests/graph-browser-large-performance.regression-1.sh +39 -0
  392. package/skills/llm-wiki-skill/tests/graph-browser-stage-4-5.regression-1.sh +163 -0
  393. package/skills/llm-wiki-skill/tests/graph-build-failures.regression-1.sh +91 -0
  394. package/skills/llm-wiki-skill/tests/graph-community-node-map.regression-1.sh +107 -0
  395. package/skills/llm-wiki-skill/tests/graph-community-wash-interactions.regression-1.sh +35 -0
  396. package/skills/llm-wiki-skill/tests/graph-data-confidence-merge.regression-1.sh +309 -0
  397. package/skills/llm-wiki-skill/tests/graph-data-source-paths.regression-1.sh +49 -0
  398. package/skills/llm-wiki-skill/tests/graph-default-behavior.regression-1.sh +35 -0
  399. package/skills/llm-wiki-skill/tests/graph-html-a11y.regression-1.sh +50 -0
  400. package/skills/llm-wiki-skill/tests/graph-html-brand-link.regression-1.sh +47 -0
  401. package/skills/llm-wiki-skill/tests/graph-html-density.regression-1.sh +228 -0
  402. package/skills/llm-wiki-skill/tests/graph-html-drawer-neighbors.regression-1.sh +47 -0
  403. package/skills/llm-wiki-skill/tests/graph-html-insights.regression-1.sh +80 -0
  404. package/skills/llm-wiki-skill/tests/graph-html-long-label.regression-1.sh +92 -0
  405. package/skills/llm-wiki-skill/tests/graph-html-minimap.regression-1.sh +51 -0
  406. package/skills/llm-wiki-skill/tests/graph-html-mobile.regression-1.sh +48 -0
  407. package/skills/llm-wiki-skill/tests/graph-html-oriental-atlas-contract.regression-1.sh +94 -0
  408. package/skills/llm-wiki-skill/tests/graph-html-oriental-design-contract.regression-1.sh +82 -0
  409. package/skills/llm-wiki-skill/tests/graph-html-search.regression-1.sh +52 -0
  410. package/skills/llm-wiki-skill/tests/graph-html-styles.regression-1.sh +66 -0
  411. package/skills/llm-wiki-skill/tests/graph-html-toolbar.regression-1.sh +62 -0
  412. package/skills/llm-wiki-skill/tests/graph-offline-phase-6.regression-1.sh +51 -0
  413. package/skills/llm-wiki-skill/tests/graph-sigma-global-production.regression-1.sh +64 -0
  414. package/skills/llm-wiki-skill/tests/graph-sigma-graphology-trial.regression-1.sh +46 -0
  415. package/skills/llm-wiki-skill/tests/graph-vis-network-trial.regression-1.sh +46 -0
  416. package/skills/llm-wiki-skill/tests/graph-workbench-interactions.regression-1.sh +151 -0
  417. package/skills/llm-wiki-skill/tests/js/graph-wash-bootstrap.test.js +110 -0
  418. package/skills/llm-wiki-skill/tests/js/graph-wash-helpers.test.js +296 -0
  419. package/skills/llm-wiki-skill/tests/js/graph-wash-learning.test.js +260 -0
  420. package/skills/llm-wiki-skill/tests/js/graph-wash-queue.test.js +115 -0
  421. package/skills/llm-wiki-skill/tests/js/graph-wash-runtime-state.test.js +282 -0
  422. package/skills/llm-wiki-skill/tests/js/source-signal-coverage.test.js +48 -0
  423. package/skills/llm-wiki-skill/tests/js/source-signal-eligibility.test.js +202 -0
  424. package/skills/llm-wiki-skill/tests/lib/graph-html-engine-helpers.sh +110 -0
  425. package/skills/llm-wiki-skill/tests/lint-output.regression-1.sh +32 -0
  426. package/skills/llm-wiki-skill/tests/regression.sh +1754 -0
  427. package/skills/llm-wiki-skill/workbench/AGENTS.md +110 -0
  428. package/skills/llm-wiki-skill/workbench/CLAUDE.md +55 -0
  429. package/skills/llm-wiki-skill/workbench/LICENSE +21 -0
  430. package/skills/llm-wiki-skill/workbench/PRODUCT.md +1353 -0
  431. package/skills/llm-wiki-skill/workbench/README.md +30 -0
  432. package/skills/llm-wiki-skill/workbench/docs/current-kb-retrieval-design.md +587 -0
  433. package/skills/llm-wiki-skill/workbench/docs/graph-evolution-1-design.md +210 -0
  434. package/skills/llm-wiki-skill/workbench/docs/stage-2-design.md +1139 -0
  435. package/skills/llm-wiki-skill/workbench/docs/stage-3-design.md +1269 -0
  436. package/skills/llm-wiki-skill/workbench/docs/stage-3.5-design.md +1164 -0
  437. package/skills/llm-wiki-skill/workbench/docs/stage-4-design.md +504 -0
  438. package/skills/llm-wiki-skill/workbench/docs/stage-4.5-design.md +195 -0
  439. package/skills/llm-wiki-skill/workbench/docs/superpowers/specs/2026-05-28-resizable-preview-layout-design.md +165 -0
  440. package/skills/llm-wiki-skill/workbench/docs/superpowers/specs/2026-05-28-settings-panel-scroll-fix.md +50 -0
  441. package/skills/llm-wiki-skill/workbench/server/package.json +31 -0
  442. package/skills/llm-wiki-skill/workbench/server/src/agent.ts +457 -0
  443. package/skills/llm-wiki-skill/workbench/server/src/artifacts.ts +248 -0
  444. package/skills/llm-wiki-skill/workbench/server/src/auth.ts +164 -0
  445. package/skills/llm-wiki-skill/workbench/server/src/config.ts +130 -0
  446. package/skills/llm-wiki-skill/workbench/server/src/conversations.test.ts +159 -0
  447. package/skills/llm-wiki-skill/workbench/server/src/conversations.ts +270 -0
  448. package/skills/llm-wiki-skill/workbench/server/src/digest/batch.ts +189 -0
  449. package/skills/llm-wiki-skill/workbench/server/src/digest/concurrency.test.ts +36 -0
  450. package/skills/llm-wiki-skill/workbench/server/src/digest/concurrency.ts +31 -0
  451. package/skills/llm-wiki-skill/workbench/server/src/digest/subagent.ts +91 -0
  452. package/skills/llm-wiki-skill/workbench/server/src/extensions/artifacts.ts +81 -0
  453. package/skills/llm-wiki-skill/workbench/server/src/extensions/knowledge-base.ts +263 -0
  454. package/skills/llm-wiki-skill/workbench/server/src/extensions/new-wiki.ts +42 -0
  455. package/skills/llm-wiki-skill/workbench/server/src/extensions/synthesis.ts +172 -0
  456. package/skills/llm-wiki-skill/workbench/server/src/graph-watcher.test.ts +196 -0
  457. package/skills/llm-wiki-skill/workbench/server/src/graph.test.ts +113 -0
  458. package/skills/llm-wiki-skill/workbench/server/src/graph.ts +351 -0
  459. package/skills/llm-wiki-skill/workbench/server/src/index.ts +1148 -0
  460. package/skills/llm-wiki-skill/workbench/server/src/knowledge-bases.test.ts +30 -0
  461. package/skills/llm-wiki-skill/workbench/server/src/knowledge-bases.ts +321 -0
  462. package/skills/llm-wiki-skill/workbench/server/src/pages.test.ts +41 -0
  463. package/skills/llm-wiki-skill/workbench/server/src/pages.ts +160 -0
  464. package/skills/llm-wiki-skill/workbench/server/src/retrieval.test.ts +151 -0
  465. package/skills/llm-wiki-skill/workbench/server/src/retrieval.ts +427 -0
  466. package/skills/llm-wiki-skill/workbench/server/src/tool-status-events.test.ts +363 -0
  467. package/skills/llm-wiki-skill/workbench/server/src/tool-status-events.ts +616 -0
  468. package/skills/llm-wiki-skill/workbench/server/src/wiki-init.test.ts +19 -0
  469. package/skills/llm-wiki-skill/workbench/server/src/wiki-init.ts +188 -0
  470. package/skills/llm-wiki-skill/workbench/server/tsconfig.json +10 -0
  471. package/skills/llm-wiki-skill/workbench/tsconfig.json +20 -0
  472. package/skills/llm-wiki-skill/workbench/web/README.md +73 -0
  473. package/skills/llm-wiki-skill/workbench/web/components.json +21 -0
  474. package/skills/llm-wiki-skill/workbench/web/eslint.config.js +22 -0
  475. package/skills/llm-wiki-skill/workbench/web/index.html +16 -0
  476. package/skills/llm-wiki-skill/workbench/web/package.json +54 -0
  477. package/skills/llm-wiki-skill/workbench/web/src/App.tsx +1195 -0
  478. package/skills/llm-wiki-skill/workbench/web/src/components/AddExternalDialog.tsx +375 -0
  479. package/skills/llm-wiki-skill/workbench/web/src/components/AppearancePanel.tsx +158 -0
  480. package/skills/llm-wiki-skill/workbench/web/src/components/ArtifactView.tsx +15 -0
  481. package/skills/llm-wiki-skill/workbench/web/src/components/BatchDigestPanel.tsx +117 -0
  482. package/skills/llm-wiki-skill/workbench/web/src/components/ChatPanel.tsx +890 -0
  483. package/skills/llm-wiki-skill/workbench/web/src/components/CommandMenu.tsx +75 -0
  484. package/skills/llm-wiki-skill/workbench/web/src/components/ExportButtons.tsx +58 -0
  485. package/skills/llm-wiki-skill/workbench/web/src/components/GraphPanel.tsx +800 -0
  486. package/skills/llm-wiki-skill/workbench/web/src/components/GraphReader.tsx +52 -0
  487. package/skills/llm-wiki-skill/workbench/web/src/components/GraphSelection.tsx +100 -0
  488. package/skills/llm-wiki-skill/workbench/web/src/components/GraphSummaryDrawer.tsx +269 -0
  489. package/skills/llm-wiki-skill/workbench/web/src/components/MainViewTabs.tsx +69 -0
  490. package/skills/llm-wiki-skill/workbench/web/src/components/MarkdownView.tsx +106 -0
  491. package/skills/llm-wiki-skill/workbench/web/src/components/NewWikiDialog.tsx +103 -0
  492. package/skills/llm-wiki-skill/workbench/web/src/components/RefMenu.tsx +44 -0
  493. package/skills/llm-wiki-skill/workbench/web/src/components/RightDrawer.tsx +298 -0
  494. package/skills/llm-wiki-skill/workbench/web/src/components/SearchPanel.tsx +165 -0
  495. package/skills/llm-wiki-skill/workbench/web/src/components/SettingsPanel.tsx +320 -0
  496. package/skills/llm-wiki-skill/workbench/web/src/components/Sidebar.tsx +354 -0
  497. package/skills/llm-wiki-skill/workbench/web/src/components/ToolHistorySummary.tsx +111 -0
  498. package/skills/llm-wiki-skill/workbench/web/src/components/ToolStatusRunway.tsx +70 -0
  499. package/skills/llm-wiki-skill/workbench/web/src/components/TopBar.tsx +348 -0
  500. package/skills/llm-wiki-skill/workbench/web/src/components/renderers/DownloadOnlyRenderer.tsx +88 -0
  501. package/skills/llm-wiki-skill/workbench/web/src/components/renderers/HtmlRenderer.tsx +92 -0
  502. package/skills/llm-wiki-skill/workbench/web/src/components/ui/button.tsx +52 -0
  503. package/skills/llm-wiki-skill/workbench/web/src/components/ui/command.tsx +50 -0
  504. package/skills/llm-wiki-skill/workbench/web/src/components/ui/dialog.tsx +156 -0
  505. package/skills/llm-wiki-skill/workbench/web/src/components/ui/input.tsx +21 -0
  506. package/skills/llm-wiki-skill/workbench/web/src/components/ui/tooltip.tsx +57 -0
  507. package/skills/llm-wiki-skill/workbench/web/src/index.css +4204 -0
  508. package/skills/llm-wiki-skill/workbench/web/src/lib/api.ts +648 -0
  509. package/skills/llm-wiki-skill/workbench/web/src/lib/appearance.ts +114 -0
  510. package/skills/llm-wiki-skill/workbench/web/src/lib/drawer-layout.ts +41 -0
  511. package/skills/llm-wiki-skill/workbench/web/src/lib/drawer-state.ts +168 -0
  512. package/skills/llm-wiki-skill/workbench/web/src/lib/graph-reader.ts +25 -0
  513. package/skills/llm-wiki-skill/workbench/web/src/lib/graph-selection-drawer.ts +35 -0
  514. package/skills/llm-wiki-skill/workbench/web/src/lib/graph-selection.ts +96 -0
  515. package/skills/llm-wiki-skill/workbench/web/src/lib/graph-summary-actions.ts +184 -0
  516. package/skills/llm-wiki-skill/workbench/web/src/lib/legacy-tool-status.ts +113 -0
  517. package/skills/llm-wiki-skill/workbench/web/src/lib/model-roles.ts +20 -0
  518. package/skills/llm-wiki-skill/workbench/web/src/lib/search-filter.ts +104 -0
  519. package/skills/llm-wiki-skill/workbench/web/src/lib/sse.ts +72 -0
  520. package/skills/llm-wiki-skill/workbench/web/src/lib/tool-status-format.ts +170 -0
  521. package/skills/llm-wiki-skill/workbench/web/src/lib/tool-status-model.ts +392 -0
  522. package/skills/llm-wiki-skill/workbench/web/src/lib/utils.ts +10 -0
  523. package/skills/llm-wiki-skill/workbench/web/src/lib/view-status.ts +16 -0
  524. package/skills/llm-wiki-skill/workbench/web/src/lib/wiki-links.ts +32 -0
  525. package/skills/llm-wiki-skill/workbench/web/src/main.tsx +10 -0
  526. package/skills/llm-wiki-skill/workbench/web/test/api.test.ts +61 -0
  527. package/skills/llm-wiki-skill/workbench/web/test/app-shell-drawer-layout.test.tsx +48 -0
  528. package/skills/llm-wiki-skill/workbench/web/test/appearance-panel.test.tsx +121 -0
  529. package/skills/llm-wiki-skill/workbench/web/test/appearance.test.ts +262 -0
  530. package/skills/llm-wiki-skill/workbench/web/test/chat-host-source.test.tsx +22 -0
  531. package/skills/llm-wiki-skill/workbench/web/test/chat-panel-auto-scroll.test.tsx +311 -0
  532. package/skills/llm-wiki-skill/workbench/web/test/chat-panel-bubbles.test.tsx +48 -0
  533. package/skills/llm-wiki-skill/workbench/web/test/chat-panel-composer.test.tsx +86 -0
  534. package/skills/llm-wiki-skill/workbench/web/test/chat-panel-tool-status.test.tsx +26 -0
  535. package/skills/llm-wiki-skill/workbench/web/test/export-batch-paper.test.tsx +101 -0
  536. package/skills/llm-wiki-skill/workbench/web/test/graph-drawer-state.test.ts +257 -0
  537. package/skills/llm-wiki-skill/workbench/web/test/graph-panel-paper.test.tsx +200 -0
  538. package/skills/llm-wiki-skill/workbench/web/test/graph-reader-request.test.ts +32 -0
  539. package/skills/llm-wiki-skill/workbench/web/test/graph-reader.test.ts +62 -0
  540. package/skills/llm-wiki-skill/workbench/web/test/graph-selection-drawer.test.ts +56 -0
  541. package/skills/llm-wiki-skill/workbench/web/test/graph-selection.test.ts +83 -0
  542. package/skills/llm-wiki-skill/workbench/web/test/graph-summary-actions.test.ts +188 -0
  543. package/skills/llm-wiki-skill/workbench/web/test/main-view-tabs.test.tsx +34 -0
  544. package/skills/llm-wiki-skill/workbench/web/test/markdown-view.test.tsx +34 -0
  545. package/skills/llm-wiki-skill/workbench/web/test/popup-menus.test.tsx +85 -0
  546. package/skills/llm-wiki-skill/workbench/web/test/render.test.tsx +30 -0
  547. package/skills/llm-wiki-skill/workbench/web/test/render.tsx +38 -0
  548. package/skills/llm-wiki-skill/workbench/web/test/right-drawer-graph-summary.test.tsx +287 -0
  549. package/skills/llm-wiki-skill/workbench/web/test/right-drawer-interactions.test.tsx +182 -0
  550. package/skills/llm-wiki-skill/workbench/web/test/search-filter.test.ts +65 -0
  551. package/skills/llm-wiki-skill/workbench/web/test/search-panel.test.tsx +155 -0
  552. package/skills/llm-wiki-skill/workbench/web/test/setup-dom.ts +66 -0
  553. package/skills/llm-wiki-skill/workbench/web/test/sidebar-v2-source.test.ts +17 -0
  554. package/skills/llm-wiki-skill/workbench/web/test/sidebar.test.tsx +110 -0
  555. package/skills/llm-wiki-skill/workbench/web/test/tool-history-summary.test.tsx +150 -0
  556. package/skills/llm-wiki-skill/workbench/web/test/tool-status-format.test.ts +107 -0
  557. package/skills/llm-wiki-skill/workbench/web/test/tool-status-model.test.ts +324 -0
  558. package/skills/llm-wiki-skill/workbench/web/test/tool-status-runway.test.ts +159 -0
  559. package/skills/llm-wiki-skill/workbench/web/test/topbar.test.tsx +248 -0
  560. package/skills/llm-wiki-skill/workbench/web/test/visual/paper-ui.ts +898 -0
  561. package/skills/llm-wiki-skill/workbench/web/test/wiki-links.test.ts +23 -0
  562. package/skills/llm-wiki-skill/workbench/web/test-results/paper-ui/actual/.gitkeep +1 -0
  563. package/skills/llm-wiki-skill/workbench/web/test-results/paper-ui/baseline/.gitkeep +1 -0
  564. package/skills/llm-wiki-skill/workbench/web/tsconfig.app.json +30 -0
  565. package/skills/llm-wiki-skill/workbench/web/tsconfig.json +7 -0
  566. package/skills/llm-wiki-skill/workbench/web/tsconfig.node.json +24 -0
  567. package/skills/llm-wiki-skill/workbench/web/vite.config.ts +28 -0
@@ -1,4 +1,4 @@
1
- import { isAllowedWikiPagePath } from '../wiki/page-path.js';
1
+ import { isAllowedWikiPagePath, isLocalKbPagePath, KB_PAGE_NAMESPACES_HINT } from '../wiki/page-path.js';
2
2
  /**
3
3
  * 上游交付契约(R20「上游对下游负责」宗旨):每阶段任务完成交接 metadata 必须产出的键。
4
4
  * key = `${assignee}:${mode}`;仅列出「下游实际读取」的硬交付物——
@@ -40,24 +40,35 @@ export function missingDeliveryKeys(assignee, mode, handoff, kbUrlBase) {
40
40
  if (!handoff)
41
41
  return keys.slice();
42
42
  const m = handoff.metadata ?? {};
43
- const base = kbUrlBase ? kbUrlBase.replace(/\/$/, '') : null;
43
+ // 推导修正(审查 C1):kbUrlBase === undefined 才是宽松;'' local strict
44
+ const hasBase = kbUrlBase !== undefined;
45
+ const base = hasBase ? kbUrlBase.replace(/\/$/, '') : null;
44
46
  const strict = base !== null;
45
47
  const missing = [];
46
48
  for (const k of keys) {
47
49
  if (k === 'pt_decision') {
48
50
  missing.push(...missingPtDecisionKeys(handoff));
51
+ continue;
52
+ }
53
+ const v = m[k];
54
+ if (strict && k === 'kb_url' && base === '') {
55
+ // local 模式(D5):kb_url 必须显式空串(非缺失键)
56
+ if (typeof v !== 'string' || v.trim() !== '')
57
+ missing.push(`${k} (本地模式 kb_url 必须为空串)`);
58
+ continue;
59
+ }
60
+ if (typeof v !== 'string' || v.trim().length === 0) {
61
+ missing.push(k);
62
+ }
63
+ else if (strict && k === 'kb_url' && !v.startsWith(base)) {
64
+ missing.push(`${k} (host 前缀必须为 ${base})`);
65
+ }
66
+ else if (strict && k === 'page_path' && base === '') {
67
+ if (!isLocalKbPagePath(v))
68
+ missing.push(`${k} (本地模式必须为本地库 wiki/** 相对路径)`);
49
69
  }
50
- else {
51
- const v = m[k];
52
- if (typeof v !== 'string' || v.trim().length === 0) {
53
- missing.push(k);
54
- }
55
- else if (strict && k === 'kb_url' && !v.startsWith(base)) {
56
- missing.push(`${k} (host 前缀必须为 ${base})`);
57
- }
58
- else if (strict && k === 'page_path' && !isAllowedWikiPagePath(v)) {
59
- missing.push(`${k} (必须为 projects/checklists/、projects/learnings/、projects/<slug>/learnings/、projects/ch_*/learnings/、projects/ch_*/t_*.md 或 projects/ch_*/review/ 命名空间)`);
60
- }
70
+ else if (strict && k === 'page_path' && !isAllowedWikiPagePath(v)) {
71
+ missing.push(`${k} (必须为 ${KB_PAGE_NAMESPACES_HINT} 命名空间)`);
61
72
  }
62
73
  }
63
74
  return missing;
@@ -65,14 +76,15 @@ export function missingDeliveryKeys(assignee, mode, handoff, kbUrlBase) {
65
76
  export function hasRequiredDelivery(assignee, mode, handoff) {
66
77
  return missingDeliveryKeys(assignee, mode, handoff).length === 0;
67
78
  }
68
- /** 对一组父任务 id 做交付契约校验,返回缺关键交付物的父卡清单(无缺失返回空数组)。 */
69
- export function missingParentDelivery(state, parentIds) {
79
+ /** 对一组父任务 id 做交付契约校验,返回缺关键交付物的父卡清单(无缺失返回空数组)。
80
+ * kbUrlBase 可选透传 missingDeliveryKeys(与 Task 4 的 C1 推导修正配套——local 模式传 '' 走 strict local 分支)。 */
81
+ export function missingParentDelivery(state, parentIds, kbUrlBase) {
70
82
  const out = [];
71
83
  for (const pid of parentIds) {
72
84
  const pt = state.tasks.get(pid);
73
85
  if (!pt)
74
86
  continue;
75
- const missing = missingDeliveryKeys(pt.assignee, pt.mode, state.handoffs.get(pid));
87
+ const missing = missingDeliveryKeys(pt.assignee, pt.mode, state.handoffs.get(pid), kbUrlBase);
76
88
  if (missing.length > 0)
77
89
  out.push({ taskId: pid, assignee: pt.assignee, mode: pt.mode, missing });
78
90
  }
@@ -0,0 +1,26 @@
1
+ export interface GateCommand {
2
+ command: string;
3
+ cwd: string;
4
+ source: 'tdd';
5
+ }
6
+ export interface GatePlan {
7
+ commands: GateCommand[];
8
+ skipped: false;
9
+ }
10
+ export interface GateSkip {
11
+ commands: [];
12
+ skipped: true;
13
+ reason: string;
14
+ }
15
+ export declare function isGatePlan(x: GatePlan | GateSkip): x is GatePlan;
16
+ export declare function branchMatches(current: string | null, declared: unknown): boolean;
17
+ export declare function deriveGatePlan(input: {
18
+ assignee: string;
19
+ mode: string;
20
+ handoff: {
21
+ metadata?: Record<string, unknown>;
22
+ };
23
+ config: {
24
+ enabled: boolean;
25
+ };
26
+ }): GatePlan | GateSkip;
@@ -0,0 +1,44 @@
1
+ // src/domain/gate-policy.ts
2
+ /** kanban_complete 实测闸派生(纯函数,零 IO):
3
+ * 声明来源单层——tdd.test_files 自动派生 npx --no-install vitest run(runner=vitest 为 review-evidence 既有口径)。
4
+ * cwd 一律 metadata.worktree_dir,缺失即 skip(旧卡向后兼容零感知)。
5
+ * test_files 必须相对路径且规范化后无 .. 段(防绝对路径跑主仓库/越界逃逸——跑错代码即闸被绕过),违规整单 skip。
6
+ * branchMatches 供装配层在 git 查询后做分支一致性比对(current=null 视为不匹配,调用方 skip)。 */
7
+ import { isAbsolute } from 'node:path';
8
+ export function isGatePlan(x) {
9
+ return x.skipped === false;
10
+ }
11
+ export function branchMatches(current, declared) {
12
+ return typeof declared === 'string' && declared.trim().length > 0 && current === declared;
13
+ }
14
+ /** 相对路径 + 不得含 .. 段(含 a/../b 形式,一并拒绝,从简从严)。
15
+ * 另限字符 allowlist [A-Za-z0-9._/-]:test_files 会被拼入 `bash -c` 执行(见 gate-runner),
16
+ * 白名单一并拒绝空白与 ; | & $ ` () 等元字符——既防 shell 注入(如 'x || true' 拼成
17
+ * `vitest run x || true`,未跑闸却 exit 0 通过),也防借空白等变体绕 runner 黑名单子串匹配
18
+ * (如 'a;git push' 双空格躲过 includes('git push'))。 */
19
+ const isSafeRelativeTestFile = (f) => /^[A-Za-z0-9._/-]+$/.test(f) && !isAbsolute(f) && !f.split(/[/\\]/).includes('..')
20
+ && !f.startsWith('-'); // 拒绝以 - 开头的条目:防 vitest CLI 旗标注入(如 --passWithNoTests 使 0 tests matched 也 exit 0,空跑绕闸)
21
+ export function deriveGatePlan(input) {
22
+ const m = input.handoff.metadata ?? {};
23
+ if (!input.config.enabled)
24
+ return { commands: [], skipped: true, reason: 'gates disabled' };
25
+ if (!(input.assignee === 'd' && input.mode === 'execute'))
26
+ return { commands: [], skipped: true, reason: 'not d/execute' };
27
+ const wt = m['worktree_dir'];
28
+ if (typeof wt !== 'string' || !wt.trim())
29
+ return { commands: [], skipped: true, reason: 'worktree_dir missing (legacy card)' };
30
+ const tdd = m['tdd'];
31
+ if (tdd?.skipped)
32
+ return { commands: [], skipped: true, reason: 'tdd skipped by declaration' };
33
+ if (!Array.isArray(tdd?.test_files) || tdd.test_files.length === 0)
34
+ return { commands: [], skipped: true, reason: 'no gate commands' };
35
+ const files = tdd.test_files.filter((f) => typeof f === 'string' && f.trim().length > 0);
36
+ if (files.length === 0)
37
+ return { commands: [], skipped: true, reason: 'no gate commands' };
38
+ if (!files.every(isSafeRelativeTestFile))
39
+ return { commands: [], skipped: true, reason: 'invalid test_files path (relative in-worktree required)' };
40
+ return {
41
+ commands: [{ command: `npx --no-install vitest run ${files.join(' ')}`, cwd: wt, source: 'tdd' }],
42
+ skipped: false,
43
+ };
44
+ }
@@ -10,17 +10,23 @@ export declare function buildChainTitle(requirementName: string | null, _openspe
10
10
  export declare class KanbanService {
11
11
  private state;
12
12
  private readonly store;
13
- private readonly kbUrlBase;
13
+ private readonly getKbUrlBase;
14
14
  private emitQueue;
15
15
  private readonly listeners;
16
16
  private onChainCompletedHook;
17
17
  private onTaskCompletedHook;
18
- constructor(store: EventStore, kbUrlBase?: string);
18
+ private gateHook;
19
+ constructor(store: EventStore, getKbUrlBase?: () => string | undefined);
19
20
  private emit;
20
21
  /** D23:注入链完成核对钩子(由调度层设置;仅一个消费者)。 */
21
22
  setOnChainCompleted(hook: (chainId: string) => void | Promise<void>): void;
22
23
  /** Q3&5:注入任务完成互链登记钩子(由调度层设置;仅一个消费者)。 */
23
24
  setOnTaskCompleted(hook: (taskId: string) => void | Promise<void>): void;
25
+ /** P1:注入实测闸钩子(由装配层设置;null=关闭实测闸,行为与旧版逐字节一致)。 */
26
+ setGateHook(hook: ((task: Task, handoff: Handoff) => Promise<{
27
+ ok: boolean;
28
+ detail: string;
29
+ } | null>) | null): void;
24
30
  /** T22:订阅持久化后的看板事件;返回解除订阅函数。listener 异常不影响已落盘状态。 */
25
31
  subscribe(listener: KanbanListener): () => void;
26
32
  /** T22:返回 seq >= 入参 的事件(与 EventStore.readSince 同为 inclusive 语义)。 */
@@ -36,6 +42,9 @@ export declare class KanbanService {
36
42
  createSpecCard(chainId: string, sections: SpecCardSections, actor: Actor): Promise<SpecCard>;
37
43
  editSpecCard(cardId: string, sections: SpecCardSections, actor: Actor): Promise<SpecCard>;
38
44
  approveSpecCard(cardId: string, actor: Actor): Promise<SpecCard>;
45
+ /** 链级停滞终态(防线A,看门狗/V stall 超限专用机械记账):executing → blocked。
46
+ * 非 executing 调用即抛(fail-closed);人工恢复=GUI 删链重跑(blocked 无出边)。 */
47
+ blockChain(chainId: string, reason: string): Promise<void>;
39
48
  createTask(input: {
40
49
  chainId: string;
41
50
  title: string;
@@ -80,7 +89,11 @@ export declare class KanbanService {
80
89
  /** 评审超限放弃:review/gave-up(含证据链信息)。仅 system。 */
81
90
  reviewGaveUp(reviewTaskId: string, targetTaskId: string, reason: string, actor: Actor): Promise<KanbanEvent>;
82
91
  /** 评审失败返工卡创建(评审失败闭环):原任务保持 done(不可变),新建返工卡继承 rework 字段。
83
- * 仅 system(can('create-rework-task')=system);V 建执行卡、system 建返工卡。 */
92
+ * 仅 system(can('create-rework-task')=system);V 建执行卡、system 建返工卡。
93
+ * 语义(2026-09-07 修正):返工=该卡自己的独立会话——resumeSessionId 不继承源卡会话(置 null),
94
+ * 首跑由 runTask create `kbn-<reworkId>`,卡自身失败重试再 resume 该会话;reworkOfTaskId 保留溯源。
95
+ * 旧实现继承 source.sessionId 造成三方错位:runTask 首跑不消费它(hasRunHistory=false→create 新会话)、
96
+ * UI(BoardCard resumeSessionId??sessionId)却跳到源卡会话 → 「返工在后台跑但哪都找不到它」。 */
84
97
  createReworkTask(input: {
85
98
  sourceTaskId: string;
86
99
  reviewTaskId: string;
@@ -23,16 +23,21 @@ export class KanbanService {
23
23
  state;
24
24
  store;
25
25
  // Q4:kb_url host 前缀硬校验基准(config.wikiVault.baseUrl)。null = 不校验前缀(兼容测试/旧调用)。
26
- kbUrlBase;
26
+ // 配置面板热生效(Task 6):改为 getter,每次校验时取最新值——改 baseUrl 无需重建服务。
27
+ getKbUrlBase;
27
28
  emitQueue = Promise.resolve();
28
29
  listeners = new Set();
29
30
  // D23:链完成验收核对钩子(dispatcher 注入:读主会话事件/产物归属核对 → auditWarning)
30
31
  onChainCompletedHook = null;
31
32
  // Q3&5:W2/W3 完成互链登记钩子(dispatcher 注入:拿 page_path → 机械写三方互链,失败不阻塞完成)
32
33
  onTaskCompletedHook = null;
33
- constructor(store, kbUrlBase) {
34
+ // P1:实测闸钩子(装配层注入:gate-policy 派生 + gate-runner 实测执行 + 分支核对)。
35
+ // null=未启用(行为不变);hook 返回 null=跳过(零感知,无 gate 事件)。
36
+ // **无 actor 参数——human 无豁免**(2026-09-02 决议收紧)。
37
+ gateHook = null;
38
+ constructor(store, getKbUrlBase) {
34
39
  this.store = store;
35
- this.kbUrlBase = kbUrlBase ?? null;
40
+ this.getKbUrlBase = getKbUrlBase ?? null;
36
41
  // P0-3:同步重投影,消除"构造后立即调用基于空状态"的竞态
37
42
  this.state = project(store.readAllSync());
38
43
  }
@@ -57,6 +62,10 @@ export class KanbanService {
57
62
  setOnTaskCompleted(hook) {
58
63
  this.onTaskCompletedHook = hook;
59
64
  }
65
+ /** P1:注入实测闸钩子(由装配层设置;null=关闭实测闸,行为与旧版逐字节一致)。 */
66
+ setGateHook(hook) {
67
+ this.gateHook = hook;
68
+ }
60
69
  /** T22:订阅持久化后的看板事件;返回解除订阅函数。listener 异常不影响已落盘状态。 */
61
70
  subscribe(listener) {
62
71
  this.listeners.add(listener);
@@ -127,6 +136,16 @@ export class KanbanService {
127
136
  await this.emit({ chainId: card.chainId, taskId: null, kind: 'chain/executing', payload: {}, author: actor, at: Date.now() });
128
137
  return updated;
129
138
  }
139
+ /** 链级停滞终态(防线A,看门狗/V stall 超限专用机械记账):executing → blocked。
140
+ * 非 executing 调用即抛(fail-closed);人工恢复=GUI 删链重跑(blocked 无出边)。 */
141
+ async blockChain(chainId, reason) {
142
+ const chain = this.state.chains.get(chainId);
143
+ if (!chain)
144
+ throw new Error('unknown chain: ' + chainId);
145
+ if (chain.status !== 'executing')
146
+ throw new Error('blockChain requires executing chain, got: ' + chain.status);
147
+ await this.emit({ chainId, taskId: null, kind: 'chain/blocked', payload: { reason }, author: 'system', at: Date.now() });
148
+ }
130
149
  async createTask(input, actor) {
131
150
  if (!can('create-task', actor, null))
132
151
  throw new Error('permission denied');
@@ -203,7 +222,7 @@ export class KanbanService {
203
222
  // 从源头杜绝 done-but-missing(上游未产出 page_path 就不会成为 done 父卡 → V 不会建 D 卡)。
204
223
  // v2:pt_decision 为 P 卡硬键(needed 布尔必填;needed=true 时 reason 必填),缺则 blocked。
205
224
  {
206
- const missing = missingDeliveryKeys(t.assignee, t.mode, handoff, this.kbUrlBase ?? undefined);
225
+ const missing = missingDeliveryKeys(t.assignee, t.mode, handoff, this.getKbUrlBase?.() ?? undefined);
207
226
  if (missing.length > 0) {
208
227
  await this.emit({ chainId: t.chainId, taskId, kind: 'task/blocked', payload: { reason: 'delivery required: ' + missing.join(', ') }, author: 'system', at: Date.now() });
209
228
  throw new Error('delivery required: ' + missing.join(', '));
@@ -211,6 +230,18 @@ export class KanbanService {
211
230
  }
212
231
  // v2 断代:w:file 交付键随旧 w1 预取阶段移除,manifest 校验块同步删除
213
232
  // (validatePrefetchManifest 仍保留于 prefetch-manifest.ts,供清单 schema 校验复用)。
233
+ // 实测闸(P1):hook 由装配层注入(gate-policy 派生 + gate-runner 实测执行 + 分支核对),
234
+ // hook 返回 null=跳过(未启用/非 D/旧卡/分支不一致)。**无 human 豁免**(2026-09-02 决议收紧);
235
+ // ok=false → gate-failed 事件 + 拒绝 complete(卡留 running,throw 经工具边界回 D 会话)。
236
+ if (this.gateHook) {
237
+ const verdict = await this.gateHook(t, handoff);
238
+ if (verdict !== null) {
239
+ await this.emit({ chainId: t.chainId, taskId, kind: verdict.ok ? 'task/gate-passed' : 'task/gate-failed',
240
+ payload: { detail: verdict.detail }, author: 'system', at: Date.now() });
241
+ if (!verdict.ok)
242
+ throw new Error('gate failed: ' + verdict.detail);
243
+ }
244
+ }
214
245
  await this.emit({ chainId: t.chainId, taskId, kind: 'task/completed', payload: { ...handoff }, author: actor, at: Date.now() });
215
246
  // Q3&5:W2/W3 完成 → 调度层互链登记(拿 page_path 机械写三方互链)。
216
247
  // 仅 w:kb 触发(P/D/PT/DT 不涉 KB 页互链);钩子内异常不阻断 completeTask(登记失败仅记 warning)。
@@ -397,7 +428,11 @@ export class KanbanService {
397
428
  return this.emit({ chainId: t.chainId, taskId: reviewTaskId, kind: 'review/gave-up', payload: { reviewTaskId, targetTaskId, reason }, author: actor, at: Date.now() });
398
429
  }
399
430
  /** 评审失败返工卡创建(评审失败闭环):原任务保持 done(不可变),新建返工卡继承 rework 字段。
400
- * 仅 system(can('create-rework-task')=system);V 建执行卡、system 建返工卡。 */
431
+ * 仅 system(can('create-rework-task')=system);V 建执行卡、system 建返工卡。
432
+ * 语义(2026-09-07 修正):返工=该卡自己的独立会话——resumeSessionId 不继承源卡会话(置 null),
433
+ * 首跑由 runTask create `kbn-<reworkId>`,卡自身失败重试再 resume 该会话;reworkOfTaskId 保留溯源。
434
+ * 旧实现继承 source.sessionId 造成三方错位:runTask 首跑不消费它(hasRunHistory=false→create 新会话)、
435
+ * UI(BoardCard resumeSessionId??sessionId)却跳到源卡会话 → 「返工在后台跑但哪都找不到它」。 */
401
436
  async createReworkTask(input, actor) {
402
437
  if (!can('create-rework-task', actor, null))
403
438
  throw new Error('permission denied');
@@ -411,7 +446,7 @@ export class KanbanService {
411
446
  assignee: source.assignee, status: 'todo', mode: source.mode, priority: 1,
412
447
  parents: [...source.parents], children: [], createdBy: 'auto', // system 自动创建(返工卡)
413
448
  attempts: 0, heartbeats: [],
414
- sessionId: '', reworkOfTaskId: source.id, resumeSessionId: source.sessionId,
449
+ sessionId: '', reworkOfTaskId: source.id, resumeSessionId: null,
415
450
  reviewAttempt: source.reviewAttempt + 1, reviewStatus: 'pending',
416
451
  };
417
452
  task.sessionId = 'kbn-' + task.id;
@@ -31,7 +31,7 @@ export function can(action, actor, task, opts = {}) {
31
31
  // V 挂清单附件到规格卡(/openspec: 建链);human 亦可(GUI 上传)
32
32
  return actor === 'v' || actor === 'human';
33
33
  case 'wiki-write':
34
- // 交付质量链:w 写 KB 正文;dt 仅写 projects/<chain>/review/ 评审命名空间(ToolGuard 层再收窄路径)
34
+ // 交付质量链:w 写 KB 正文;dt 仅写 projects/<repoSlug>/<chain>/review/ 评审命名空间(ToolGuard 层再收窄路径)
35
35
  return actor === 'w' || actor === 'dt';
36
36
  case 'wiki-read':
37
37
  // w/d 读 KB 正文;dt 需读 KB 校验(评审只读);pt 无 wiki 工具面
@@ -13,6 +13,11 @@ export interface PlanningChecklist {
13
13
  resolved: boolean;
14
14
  answer?: string;
15
15
  }>;
16
+ risks?: Array<{
17
+ description: string;
18
+ source: string;
19
+ mitigation: string;
20
+ }>;
16
21
  }
17
22
  /** 需求澄清清单 schema 硬校验:返回错误列表(空数组=合法)。清单缺段即拒绝保存(硬闸,主 agent 会话内修正)。 */
18
23
  export declare function validatePlanningChecklist(raw: unknown): string[];
@@ -26,17 +26,80 @@ export function validatePlanningChecklist(raw) {
26
26
  }
27
27
  }
28
28
  for (const [label, key] of ARR_FIELDS) {
29
- if (!Array.isArray(spec[key]) || spec[key].some((v) => typeof v !== 'string')) {
30
- errors.push(`checklist.spec.${label} must be string[]`);
29
+ const arr = spec[key];
30
+ if (!Array.isArray(arr)) {
31
+ errors.push(`checklist.spec.${label} must be an array of plain strings (got: ${JSON.stringify(arr)})`);
32
+ continue;
33
+ }
34
+ // 校验器错误文案是模型的 prompt(2026-09-04 二次复发:对象数组只回裸文案,模型零回显无法自纠)——
35
+ // 必须带 got: 回显 + 拍平指引。判定逻辑不变:非数组或含非字符串元素即拒。
36
+ const badIdx = arr.findIndex((v) => typeof v !== 'string');
37
+ if (badIdx >= 0) {
38
+ errors.push(`checklist.spec.${label} must be an array of plain strings; element ${badIdx} is not a string (got: ${JSON.stringify(arr[badIdx])}). Flatten objects into one sentence per element, e.g. "As a <role>, I want <capability>, so that <benefit>" for ${label}`);
31
39
  }
32
40
  }
33
41
  }
34
42
  // manifest 复用 PrefetchManifest schema
35
43
  errors.push(...validatePrefetchManifest(c['manifest']).map((e) => 'checklist.' + e));
36
- // 澄清问答/疑问点
37
- for (const key of ['clarifications', 'doubts']) {
38
- if (!Array.isArray(c[key]))
39
- errors.push(`checklist.${key} must be an array`);
44
+ // 澄清问答/疑问点:数组 + 元素形状硬校验。渲染读 qa.q/qa.a——键名错会静默产出 undefined 页面
45
+ //(2026-09-04 事故:模型传 {question,answer} 过闸,落库 9 条全 undefined),故必须锁确切键名。
46
+ const clar = c['clarifications'];
47
+ if (!Array.isArray(clar)) {
48
+ errors.push('checklist.clarifications must be an array');
49
+ }
50
+ else {
51
+ // 硬闸非空(2026-09-04:[] 合法过闸 → KB 页渲染「(无)」→ 澄清问答静默丢失)。
52
+ // 恢复场景(restoreRef 旧页无澄清)走逃生口文案,不加代码分支。
53
+ if (clar.length === 0) {
54
+ errors.push('checklist.clarifications must be a non-empty array — record every clarification Q&A from this planning round. If this checklist genuinely had no clarification round (e.g. rebuilt from a legacy KB page via restoreRef), add one entry {"q": "本轮无澄清(恢复重建)", "a": "<来源页或原因>"}');
55
+ }
56
+ clar.forEach((el, i) => {
57
+ const o = el;
58
+ const ok = typeof o === 'object' && o !== null &&
59
+ typeof o['q'] === 'string' && o['q'].trim().length > 0 &&
60
+ typeof o['a'] === 'string' && o['a'].trim().length > 0;
61
+ if (!ok) {
62
+ const got = typeof o === 'object' && o !== null ? Object.keys(o).join(',') : JSON.stringify(el);
63
+ errors.push(`checklist.clarifications[${i}] must be {"q": string, "a": string} with both non-empty (got keys: ${got}) — use keys "q" and "a", not "question"/"answer"`);
64
+ }
65
+ });
66
+ }
67
+ const dbs = c['doubts'];
68
+ if (!Array.isArray(dbs)) {
69
+ errors.push('checklist.doubts must be an array');
70
+ }
71
+ else {
72
+ dbs.forEach((el, i) => {
73
+ const o = el;
74
+ const ok = typeof o === 'object' && o !== null &&
75
+ typeof o['q'] === 'string' && o['q'].trim().length > 0 &&
76
+ typeof o['resolved'] === 'boolean' &&
77
+ (o['answer'] === undefined || typeof o['answer'] === 'string');
78
+ if (!ok) {
79
+ const got = typeof o === 'object' && o !== null ? Object.keys(o).join(',') : JSON.stringify(el);
80
+ errors.push(`checklist.doubts[${i}] must be {"q": string, "resolved": boolean, "answer"?: string} (got keys: ${got}) — use keys "q", "resolved", "answer"`);
81
+ }
82
+ });
83
+ }
84
+ // 风险点(可选):存在则硬校验三要素键名。渲染读 r.description/r.source/r.mitigation——键名错会静默产出 undefined 行
85
+ const risks = c['risks'];
86
+ if (risks !== undefined) {
87
+ if (!Array.isArray(risks)) {
88
+ errors.push('checklist.risks must be an array when present');
89
+ }
90
+ else {
91
+ risks.forEach((el, i) => {
92
+ const o = el;
93
+ const ok = typeof o === 'object' && o !== null &&
94
+ typeof o['description'] === 'string' && o['description'].trim().length > 0 &&
95
+ typeof o['source'] === 'string' && o['source'].trim().length > 0 &&
96
+ typeof o['mitigation'] === 'string' && o['mitigation'].trim().length > 0;
97
+ if (!ok) {
98
+ const got = typeof o === 'object' && o !== null ? Object.keys(o).join(',') : JSON.stringify(el);
99
+ errors.push(`checklist.risks[${i}] must be {"description": string, "source": string, "mitigation": string} with all non-empty (got keys: ${got}) — use keys "description", "source", "mitigation"`);
100
+ }
101
+ });
102
+ }
40
103
  }
41
104
  return errors;
42
105
  }
@@ -47,6 +110,7 @@ export function buildChecklistTitle(c) {
47
110
  /** 需求澄清清单落库 body:标题【需求】+ 各段可读 markdown(非裸 JSON)。KB 与临时目录两分支共用。 */
48
111
  export function formatChecklistBody(c) {
49
112
  const { spec, manifest, clarifications, doubts } = c;
113
+ const risks = c.risks ?? [];
50
114
  const lines = [`# ${buildChecklistTitle(c)}`, '## Spec', ''];
51
115
  lines.push('### 问题描述 (problem)', spec.problem, '');
52
116
  lines.push('### 解决方案 (solution)', spec.solution, '');
@@ -71,6 +135,16 @@ export function formatChecklistBody(c) {
71
135
  });
72
136
  if (clarifications.length === 0)
73
137
  lines.push('(无)', '');
138
+ lines.push('## 风险点', '');
139
+ if (risks.length === 0) {
140
+ lines.push('(无)', '');
141
+ }
142
+ else {
143
+ for (const r of risks) {
144
+ lines.push(`- ${r.description}(来源: ${r.source};缓解: ${r.mitigation})`);
145
+ }
146
+ lines.push('');
147
+ }
74
148
  lines.push('## 疑问点', '');
75
149
  for (const d of doubts) {
76
150
  lines.push(d.resolved ? `- [x] ${d.q}${d.answer ? ` — ${d.answer}` : ''}` : `- [ ] ${d.q}`);
@@ -12,7 +12,8 @@ export function applyTo(state, ev) {
12
12
  }
13
13
  case 'chain/executing':
14
14
  case 'chain/completed':
15
- case 'chain/aborted': {
15
+ case 'chain/aborted':
16
+ case 'chain/blocked': {
16
17
  const c = state.chains.get(ev.chainId);
17
18
  if (!c)
18
19
  throw new Error('projection: unknown chain ' + ev.chainId);
@@ -24,7 +24,7 @@ export function validateReviewEvidence(role, handoff) {
24
24
  // 计划结构字段:评审须给出被评审计划产物引用(如 artifacts_path/page 结构)——缺则视为证据不足
25
25
  const planRef = ev.reviewPage ?? (handoff.metadata ?? {})['artifacts_path'];
26
26
  if (!planRef)
27
- missing.push('review_evidence.plan (artifacts_path/reviewPage)');
27
+ missing.push('metadata.artifacts_path (被评审计划的 openspec 目录绝对路径,继承被评审 P 卡) 或 review_evidence.reviewPage');
28
28
  }
29
29
  else {
30
30
  // DT:实证校验证据(fail 评审同样必须已实证——test 字段必须存在;仅 pass 要求 exit 0)
@@ -10,7 +10,8 @@ const TASK_TRANSITIONS = {
10
10
  };
11
11
  const CHAIN_TRANSITIONS = {
12
12
  planning: { 'chain/executing': 'executing' },
13
- executing: { 'chain/completed': 'completed', 'chain/aborted': 'aborted' },
13
+ executing: { 'chain/completed': 'completed', 'chain/aborted': 'aborted', 'chain/blocked': 'blocked' },
14
+ blocked: {},
14
15
  completed: {},
15
16
  aborted: {},
16
17
  };
@@ -1,7 +1,7 @@
1
1
  export type Role = 'v' | 'p' | 'w' | 'd' | 'pt' | 'dt';
2
2
  export type TaskMode = 'file' | 'external' | 'kb' | 'openspec' | 'mattpocock' | 'align' | 'execute' | 'review-plan' | 'review-impl';
3
3
  export type TaskStatus = 'triage' | 'todo' | 'ready' | 'running' | 'blocked' | 'done' | 'failed' | 'archived';
4
- export type ChainStatus = 'planning' | 'executing' | 'completed' | 'aborted';
4
+ export type ChainStatus = 'planning' | 'executing' | 'blocked' | 'completed' | 'aborted';
5
5
  export type SpecCardStatus = 'draft' | 'approved';
6
6
  /** 评审状态(交付质量链):not-required 普通卡 / pending 等待评审 / passed 通过 / failed 失败待返工 / gave-up 超限放弃。 */
7
7
  export type ReviewStatus = 'not-required' | 'pending' | 'passed' | 'failed' | 'gave-up';
@@ -40,7 +40,7 @@ export interface ReviewEvidence {
40
40
  kbUrl: string;
41
41
  };
42
42
  }
43
- export type EventKind = 'chain/created' | 'chain/executing' | 'chain/completed' | 'chain/aborted' | 'chain/root-task-set' | 'chain/audit-warning' | 'chain/audit-confirmed' | 'chain/title-updated' | 'spec-card/created' | 'spec-card/edited' | 'spec-card/approved' | 'task/created' | 'task/claimed' | 'task/heartbeat' | 'task/commented' | 'task/completed' | 'task/blocked' | 'task/unblocked' | 'task/archived' | 'task/failed' | 'task/renamed' | 'review/passed' | 'review/failed' | 'review/gave-up';
43
+ export type EventKind = 'chain/created' | 'chain/executing' | 'chain/completed' | 'chain/aborted' | 'chain/blocked' | 'chain/root-task-set' | 'chain/audit-warning' | 'chain/audit-confirmed' | 'chain/title-updated' | 'spec-card/created' | 'spec-card/edited' | 'spec-card/approved' | 'task/created' | 'task/claimed' | 'task/heartbeat' | 'task/commented' | 'task/completed' | 'task/blocked' | 'task/unblocked' | 'task/archived' | 'task/gate-passed' | 'task/gate-failed' | 'task/failed' | 'task/renamed' | 'review/passed' | 'review/failed' | 'review/gave-up';
44
44
  export interface SpecCardSections {
45
45
  problem: string;
46
46
  solution: string;
package/lib/index.js CHANGED
@@ -1,28 +1,15 @@
1
+ import { homedir } from 'node:os';
1
2
  import { KanbanProvider } from './services/kanban-provider.js';
2
3
  import { Config } from './config.js';
3
4
  import { registerMainSessionTools } from './tools/main-session-tools.js';
4
5
  import { installRolePresets } from './roles/preset-installer.js';
6
+ import { installLlWikiSkill } from './roles/skill-installer.js';
5
7
  import { registerKanbanHttp } from './routes/kanban-http.js';
6
8
  import { startDispatcher } from './dispatcher/dispatcher.js';
9
+ import { ConfigProvider } from './services/config-provider.js';
7
10
  export const name = 'dsh-swarm';
8
11
  export { Config };
9
12
  // P1-9:无 inject——KanbanProvider 只用文件系统(FileEventStore),不依赖 ctx.storage 等任何服务。
10
- /** 可选服务延迟装配:插件 apply 时各服务可能尚未提供(cordis 注入顺序),轮询 ctx.get 直至可用再接线。 */
11
- function wireWhenAvailable(ctx, name, fn, timeoutMs = 60000) {
12
- if (ctx.get(name)) {
13
- fn();
14
- return () => { };
15
- }
16
- const timer = setInterval(() => {
17
- if (ctx.get(name)) {
18
- clearInterval(timer);
19
- clearTimeout(to);
20
- fn();
21
- }
22
- }, 500);
23
- const to = setTimeout(() => clearInterval(timer), timeoutMs);
24
- return () => { clearInterval(timer); clearTimeout(to); };
25
- }
26
13
  /** 等待多个服务同时可用后再接线(如 tools 先于 kanban 出现时,单服务轮询会过早执行)。 */
27
14
  function wireAllAvailable(ctx, names, fn, timeoutMs = 60000) {
28
15
  const ready = () => names.every((name) => Boolean(ctx.get(name)));
@@ -42,15 +29,26 @@ function wireAllAvailable(ctx, names, fn, timeoutMs = 60000) {
42
29
  }
43
30
  export function apply(ctx, config) {
44
31
  // cordis 4:Service 构造即注册(super(ctx,'kanban') 调 ctx.reflect.provide),无需手动 provide。
45
- const provider = new KanbanProvider(ctx, config);
32
+ // Task 8:ConfigProvider apply 中创建一次(override 存放于 storageDir,$DSH_HOME 占位符在此解析),
33
+ // 全链路(KanbanProvider/HTTP 桥/主会话工具/调度器)共享同一实例实现配置面板热生效。
34
+ const storageDir = config.storageDir.replace('$DSH_HOME', process.env.DSH_HOME ?? homedir());
35
+ const configProvider = new ConfigProvider(ctx, config, storageDir);
36
+ // Task 6:KanbanProvider 持 ConfigProvider 引用,kb_url base 经 getter 热读取(配置面板改后无需重建)。
37
+ const provider = new KanbanProvider(ctx, config, configProvider);
46
38
  // D22:把包内角色裁剪 preset 组合安装到 $DSH_HOME/.agent-presets/(真实 API 下唯一可发现的自定义根)。
47
39
  const installed = installRolePresets();
40
+ installLlWikiSkill(); // 尽力而为:失败仅告警不阻断(设计 §7)
48
41
  console.info('[dsh-swarm] role presets installed: ' + (installed.length ? installed.join(',') : 'none'));
42
+ // LLM 运行时延迟取用:registerKanbanHttp 内部消费(llm-catalog 枚举),接线时 llm 服务已就绪。
43
+ const llm = () => ctx.get('llm');
49
44
  // 可选服务接线均延迟到服务可用后:
50
- // - Web GUI 数据桥(GET /kanban/board + POST /kanban/action,仅 webServer 存在时挂载)
51
- wireWhenAvailable(ctx, 'webServer', () => registerKanbanHttp(ctx, provider, config));
45
+ // - Web GUI 数据桥(GET /kanban/board + POST /kanban/action + 配置读写 + llm-catalog,仅 webServer 存在时挂载)
46
+ // llm 需在 webServer 就绪且 llm 就绪后取,wireAllAvailable 双服务轮询比单服务更稳。
47
+ wireAllAvailable(ctx, ['webServer', 'llm'], () => registerKanbanHttp(ctx, provider, configProvider, llm(), config));
52
48
  // - P1-3 主会话工具面(spec_card_view/edit/approve + kanban 只读子集 + 前缀路由工具)
53
- wireAllAvailable(ctx, ['tools', 'kanban'], () => registerMainSessionTools(ctx, config));
49
+ // Task 8:收 ConfigProvider,wiki 客户端与全部配置读点经 getEffective() 调用时热读取。
50
+ wireAllAvailable(ctx, ['tools', 'kanban'], () => registerMainSessionTools(ctx, configProvider));
54
51
  // - 调度层:事件唤醒 V(R20)+ 每任务 agent runner + 看门狗(仅 agents 可用时启动)
55
- wireAllAvailable(ctx, ['agents', 'kanban'], () => startDispatcher(ctx, config));
52
+ // Task 7:startDispatcher ConfigProvider(模型链/wiki 热生效)。
53
+ wireAllAvailable(ctx, ['agents', 'kanban'], () => startDispatcher(ctx, configProvider));
56
54
  }
@@ -0,0 +1,22 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ /** 需剥离的带毒参数(dsh-sandbox escalation 配对参数;写死避免依赖宿主内部导出)。 */
3
+ export declare const ESCALATION_PARAM_KEYS: readonly ["sandbox_permissions", "justification"];
4
+ /** 剥离 escalation 参数:净化后新对象返回;本就干净则原对象透传(零拷贝零改写)。 */
5
+ export declare function stripEscalationArgs(args: unknown): unknown;
6
+ /**
7
+ * 给 danger-full-access 会话 shadow 注册去毒版 write/edit/bash。
8
+ *
9
+ * 行为契约:
10
+ * - 干净版 = 宿主定义浅拷贝 + parameters 去掉两带毒字段(JSON 深拷贝后删除,注册表保证 lossless JSON)
11
+ * + execute 换成「剥参 → 转发宿主原工具 execute」。写逻辑零自实现,行为 100% 官方。
12
+ * - 宿主 schema 本就无带毒参数(无沙箱后端的组合,escalationModes 为空)→ 无需 shadow,跳过
13
+ * (最小触碰面:不去盖一个本来就干净的版本)。
14
+ * - 转发失败面(宿主定义不可达 / 缺 execute / 同层注册冲突)→ 该工具不挂 + console.error 显形,
15
+ * 宿主带毒版本保持可见(fail-safe:绝不注册一个自实现写文件的半成品)。
16
+ * - 幂等:setup 重入(live 会话修复路径 resumeOrReuse 会重跑 setup)先以品牌标记识别已挂
17
+ * shadow → 跳过;同层冲突抛错也被捕获显形,不炸 setup(宿主版本继续可见,plan-guard 兜底网仍在)。
18
+ *
19
+ * @param agentCtx agent setup 收到的 scoped ctx(agentCtx.tools 即该 scope 的注册表)
20
+ * @param agent Agent 实例(= dsh-tools scope key,exec.agent 同源;get 的 scope 视角参数)
21
+ */
22
+ export declare function installCleanFsTools(agentCtx: Context, agent: unknown): void;