@joekytc/dsh-swarm 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/client/BoardCard.tsx +24 -2
- package/client/ConfigSection.tsx +71 -0
- package/client/ConfigSelect.tsx +69 -0
- package/client/KanbanBoard.tsx +3 -0
- package/client/KanbanTab.tsx +4 -3
- package/client/TaskDrawer.tsx +31 -31
- package/client/WorkflowRail.tsx +3 -1
- package/client/config-store.ts +51 -0
- package/client/config.css +110 -0
- package/client/index.ts +39 -4
- package/client/kanban.css +134 -2
- package/client/session-bridge.ts +39 -0
- package/client/timeline-model.ts +210 -0
- package/client/workflow-model.ts +3 -1
- package/lib/client.js +549 -64
- package/lib/config.d.ts +19 -4
- package/lib/config.js +18 -3
- package/lib/dispatcher/agent-runner.d.ts +28 -6
- package/lib/dispatcher/agent-runner.js +175 -62
- package/lib/dispatcher/chain-auditor.js +4 -1
- package/lib/dispatcher/dispatcher.d.ts +62 -3
- package/lib/dispatcher/dispatcher.js +243 -20
- package/lib/dispatcher/session-events.d.ts +11 -15
- package/lib/dispatcher/session-events.js +17 -5
- package/lib/dispatcher/v-orchestrator.d.ts +42 -9
- package/lib/dispatcher/v-orchestrator.js +236 -28
- package/lib/domain/config-override.d.ts +38 -0
- package/lib/domain/config-override.js +101 -0
- package/lib/domain/delivery-contract.d.ts +3 -2
- package/lib/domain/delivery-contract.js +28 -16
- package/lib/domain/gate-policy.d.ts +26 -0
- package/lib/domain/gate-policy.js +44 -0
- package/lib/domain/kanban-service.d.ts +16 -3
- package/lib/domain/kanban-service.js +41 -6
- package/lib/domain/memory.d.ts +29 -0
- package/lib/domain/memory.js +145 -0
- package/lib/domain/permissions.js +1 -1
- package/lib/domain/planning-checklist.d.ts +5 -0
- package/lib/domain/planning-checklist.js +80 -6
- package/lib/domain/projection.js +2 -1
- package/lib/domain/review-evidence.js +1 -1
- package/lib/domain/state-machine.js +2 -1
- package/lib/domain/types.d.ts +2 -2
- package/lib/index.js +19 -21
- package/lib/roles/clean-fs-tools.d.ts +22 -0
- package/lib/roles/clean-fs-tools.js +118 -0
- package/lib/roles/skill-installer.d.ts +6 -0
- package/lib/roles/skill-installer.js +32 -0
- package/lib/roles/toolsets.d.ts +13 -1
- package/lib/roles/toolsets.js +163 -31
- package/lib/roles/wiki-worker.d.ts +1 -0
- package/lib/roles/wiki-worker.js +10 -2
- package/lib/routes/kanban-http.d.ts +5 -2
- package/lib/routes/kanban-http.js +36 -3
- package/lib/routes/planning-driver.d.ts +7 -6
- package/lib/routes/planning-driver.js +19 -11
- package/lib/routes/prefix-router.d.ts +28 -13
- package/lib/routes/prefix-router.js +66 -1
- package/lib/services/config-provider.d.ts +42 -0
- package/lib/services/config-provider.js +94 -0
- package/lib/services/gate-runner.d.ts +24 -0
- package/lib/services/gate-runner.js +87 -0
- package/lib/services/kanban-provider.d.ts +5 -1
- package/lib/services/kanban-provider.js +40 -2
- package/lib/services/llm-catalog.d.ts +35 -0
- package/lib/services/llm-catalog.js +19 -0
- package/lib/tools/kanban-tools.js +1 -0
- package/lib/tools/main-session-tools.d.ts +17 -2
- package/lib/tools/main-session-tools.js +112 -25
- package/lib/tools/planning-tools.d.ts +9 -0
- package/lib/tools/planning-tools.js +120 -4
- package/lib/tools/prefetch-tools.js +1 -0
- package/lib/tools/spec-card-tools.js +1 -0
- package/lib/tools/wiki-tools.js +5 -4
- package/lib/wiki/kb-linkage.d.ts +9 -2
- package/lib/wiki/kb-linkage.js +3 -3
- package/lib/wiki/local-kb-client.d.ts +14 -0
- package/lib/wiki/local-kb-client.js +101 -0
- package/lib/wiki/local-kb.d.ts +6 -0
- package/lib/wiki/local-kb.js +25 -0
- package/lib/wiki/memory-recall.d.ts +24 -0
- package/lib/wiki/memory-recall.js +62 -0
- package/lib/wiki/page-path.d.ts +10 -1
- package/lib/wiki/page-path.js +31 -8
- package/lib/wiki/wiki-vault-client.d.ts +4 -3
- package/lib/wiki/wiki-vault-client.js +6 -6
- package/package.json +16 -11
- package/personas/kanban-d/preset.yml +1 -1
- package/personas/kanban-dt/agent.cordis.yml +3 -3
- package/personas/kanban-dt/preset.yml +1 -1
- package/personas/kanban-p/agent.cordis.yml +16 -0
- package/personas/kanban-p/preset.yml +1 -1
- package/personas/kanban-pt/agent.cordis.yml +38 -8
- package/personas/kanban-pt/preset.yml +1 -1
- package/personas/kanban-w/agent.cordis.yml +35 -16
- package/personas/kanban-w/preset.yml +1 -1
- package/personas/persona-dt.md +1 -1
- package/personas/persona-p.md +4 -1
- package/personas/persona-pt.md +13 -6
- package/personas/persona-w.md +11 -9
- package/skills/grill-me/SKILL.md +71 -0
- package/skills/llm-wiki-skill/.mise.toml +2 -0
- package/skills/llm-wiki-skill/.nvmrc +1 -0
- package/skills/llm-wiki-skill/AGENTS.md +173 -0
- package/skills/llm-wiki-skill/CHANGELOG.md +548 -0
- package/skills/llm-wiki-skill/CLAUDE.md +152 -0
- package/skills/llm-wiki-skill/HERMES.md +44 -0
- package/skills/llm-wiki-skill/README.en.md +261 -0
- package/skills/llm-wiki-skill/README.md +291 -0
- package/skills/llm-wiki-skill/SKILL.md +1133 -0
- package/skills/llm-wiki-skill/assets/graph-demo.gif +0 -0
- package/skills/llm-wiki-skill/assets/graph-preview.png +0 -0
- package/skills/llm-wiki-skill/deps/LICENSE-d3.txt +13 -0
- package/skills/llm-wiki-skill/deps/LICENSE-marked.txt +44 -0
- package/skills/llm-wiki-skill/deps/LICENSE-purify.txt +568 -0
- package/skills/llm-wiki-skill/deps/LICENSE-roughjs.txt +21 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/SKILL.md +261 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/references/config/first-time-setup.md +106 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/cdp.ts +179 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/constants.ts +13 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/defuddle-converter.ts +58 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/html-to-markdown.ts +135 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/legacy-converter.ts +629 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/main.ts +314 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/markdown-conversion-shared.ts +305 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/media-localizer.ts +317 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/package.json +14 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/paths.ts +29 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/package.json +9 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/src/index.test.ts +307 -0
- package/skills/llm-wiki-skill/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/src/index.ts +523 -0
- package/skills/llm-wiki-skill/deps/d3.min.js +2 -0
- package/skills/llm-wiki-skill/deps/marked.min.js +6 -0
- package/skills/llm-wiki-skill/deps/purify.min.js +3 -0
- package/skills/llm-wiki-skill/deps/rough.min.js +7 -0
- package/skills/llm-wiki-skill/deps/youtube-transcript/SKILL.md +47 -0
- package/skills/llm-wiki-skill/deps/youtube-transcript/scripts/get_transcript.py +72 -0
- package/skills/llm-wiki-skill/designs/graph-edge-legibility/graph-edge-treatments.html +480 -0
- package/skills/llm-wiki-skill/docs/design/oriental-atlas/DESIGN.md +183 -0
- package/skills/llm-wiki-skill/docs/design/oriental-atlas/README.md +10 -0
- package/skills/llm-wiki-skill/docs/design/oriental-atlas/design-brief.md +170 -0
- package/skills/llm-wiki-skill/docs/design/oriental-atlas/oriental-editorial-atlas.html +1908 -0
- package/skills/llm-wiki-skill/docs/design/oriental-atlas/reviews/result-review.md +68 -0
- package/skills/llm-wiki-skill/docs/graph/2026-06-16-interaction-risk-audit.md +88 -0
- package/skills/llm-wiki-skill/docs/graph/2026-06-16-interaction-test-coverage-map.md +212 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-0-2-baseline.md +86 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-1-3-dom-svg-large-baseline.md +85 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-1-4-disposable-validation-gate.md +97 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-18-phase-2-4-global-renderer-trial-matrix.md +168 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-1-sigma-graphology-trial.md +71 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-2-vis-network-trial.md +78 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-3-aggregation-fallback-trial.md +72 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-phase-6-4-global-renderer-route-decision.md +94 -0
- package/skills/llm-wiki-skill/docs/graph/performance/2026-06-19-sigma-global-production-integration-result.md +102 -0
- package/skills/llm-wiki-skill/docs/graph/performance/artifacts/2026-06-18-phase-0-2/stage-4.5-offline-dense-wheel.json +9 -0
- package/skills/llm-wiki-skill/docs/graph/performance/artifacts/2026-06-18-phase-0-2/stage-4.5-offline-dense-wheel.png +0 -0
- package/skills/llm-wiki-skill/docs/graph/performance/artifacts/2026-06-18-phase-0-2/stage-4.5-offline-navigation.png +0 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-15-omp-tool-status-events-design.md +174 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-16-graph-interaction-geometry-design.md +832 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-16-graph-six-layer-architecture-design.md +577 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-17-static-renderer-coordination-split-design.md +172 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-18-large-graph-global-community-design.md +909 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-19-sigma-global-graph-renderer-design.md +360 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-20-paper-ui-port-design.md +162 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-20-paper-ui-v2-shell-alignment-design.md +384 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-21-graph-experience-completion-design.md +534 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-22-chat-auto-scroll-design.md +185 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-22-graph-community-node-visual-design.md +266 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-25-sigma-overlay-refactor-perf-design.md +170 -0
- package/skills/llm-wiki-skill/docs/spark/2026-06-26-global-sigma-community-spotlight-design.md +393 -0
- package/skills/llm-wiki-skill/docs/spark/mockups/2026-06-18-large-graph-global-community-flow.html +746 -0
- package/skills/llm-wiki-skill/install.ps1 +87 -0
- package/skills/llm-wiki-skill/install.sh +722 -0
- package/skills/llm-wiki-skill/package-lock.json +11171 -0
- package/skills/llm-wiki-skill/package.json +24 -0
- package/skills/llm-wiki-skill/packages/graph-engine/package.json +37 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/anim/.gitkeep +1 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/anim/index.ts +179 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/architecture.ts +79 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/diff.ts +121 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/facade.ts +1406 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/graph-node.ts +37 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/index.ts +25 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/layout/edge-geometry.ts +17 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/layout/index.ts +16 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/layout/spatial-index.ts +509 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/atlas.ts +18 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/index.ts +10 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/labels.ts +11 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/layout.ts +81 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/learning.ts +8 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/legacy-helpers.ts +1379 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/queue.ts +7 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/storage.ts +4 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/model/visibility.ts +9 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/.gitkeep +1 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/adapter.ts +443 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/aggregation-containers.ts +64 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/community-cloud-geometry.ts +178 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/community-wash.ts +238 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/community-washes.ts +19 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/compat-contract.ts +14 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/controller.ts +705 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/controls.ts +288 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/dom-svg-renderer.ts +180 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/edges.ts +51 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/geometry.ts +380 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/gestures.ts +673 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/graph-renderer-root.ts +387 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/hit-testing.ts +56 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/host-dom.ts +14 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/hover-card.ts +37 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/index.ts +213 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/keyboard.ts +48 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/legend.ts +25 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/minimap.ts +45 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/model.ts +1339 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/node-drag-lifecycle.ts +94 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/nodes.ts +103 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/offline-reader.ts +209 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/overlays-presenter.ts +192 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/overlays.ts +73 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/pin-position.ts +51 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/preview.ts +65 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/relation-focus.ts +91 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/render-context.ts +85 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/render-pipeline.ts +871 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/render-styles.ts +1405 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/renderer-surface.ts +75 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/search.ts +57 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-coordinates.ts +44 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-global-drag.ts +246 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-global-renderer.ts +1425 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/sigma-overlay-svg.ts +121 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/simulation-bridge.ts +59 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/state.ts +262 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/toolbar.ts +40 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/render/viewport.ts +336 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/select/.gitkeep +1 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/select/index.ts +189 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/sim/index.ts +372 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/sim/pins.ts +84 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/summary/index.ts +447 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/themes/.gitkeep +1 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/themes/index.ts +8 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/themes/tokens.ts +117 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/types/d3-quadtree.d.ts +22 -0
- package/skills/llm-wiki-skill/packages/graph-engine/src/types.ts +531 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/aggregation-fallback-trial-adapter.test.ts +115 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/aggregation-fallback-trial-adapter.ts +222 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/anim.test.ts +121 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/architecture.test.ts +63 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/community-cloud-geometry.test.ts +86 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/community-wash.test.ts +97 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/diff.test.ts +133 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/facade.test.ts +1369 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/geometry.test.ts +147 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/gestures.test.ts +768 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/graph-layout.test.ts +110 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/helpers.test.ts +287 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/interaction-contract.test.ts +106 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/keyboard.test.ts +59 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/large-fixtures.test.ts +47 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/large-graph-fixtures.ts +420 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/learning.test.ts +259 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/node-drag-lifecycle.test.ts +166 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/overlays.test.ts +115 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/preview.test.ts +56 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/queue.test.ts +114 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/relation-focus.test.ts +115 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/render-model.test.ts +1030 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/renderer-adapter-contract.test.ts +271 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/renderer-boundary.test.ts +618 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/renderer-lifecycle.test.ts +1711 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/route-continuity.test.ts +284 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/runtime-state.test.ts +281 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/search-and-legend.test.ts +124 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/select.test.ts +168 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-coordinates.test.ts +50 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-global-renderer.test.ts +2210 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-trial-adapter.test.ts +82 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/sigma-trial-adapter.ts +271 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/sim.test.ts +207 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/simulation-bridge.test.ts +96 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/spatial-index.test.ts +222 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/state.test.ts +189 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/summary-contract.test.ts +422 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/themes.test.ts +62 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/toolbar.test.ts +64 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/viewport.test.ts +213 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/vis-network-trial-adapter.test.ts +82 -0
- package/skills/llm-wiki-skill/packages/graph-engine/test/vis-network-trial-adapter.ts +186 -0
- package/skills/llm-wiki-skill/packages/graph-engine/tsconfig.json +17 -0
- package/skills/llm-wiki-skill/packages/graph-engine/vite.config.ts +15 -0
- package/skills/llm-wiki-skill/platforms/claude/CLAUDE.md +37 -0
- package/skills/llm-wiki-skill/platforms/claude/companions/llm-wiki-upgrade/SKILL.md +95 -0
- package/skills/llm-wiki-skill/platforms/codex/AGENTS.md +23 -0
- package/skills/llm-wiki-skill/platforms/hermes/README.md +31 -0
- package/skills/llm-wiki-skill/platforms/openclaw/README.md +31 -0
- package/skills/llm-wiki-skill/scripts/adapter-state.sh +424 -0
- package/skills/llm-wiki-skill/scripts/build-graph-data.sh +395 -0
- package/skills/llm-wiki-skill/scripts/build-graph-html.sh +459 -0
- package/skills/llm-wiki-skill/scripts/cache.sh +352 -0
- package/skills/llm-wiki-skill/scripts/create-source-page.sh +100 -0
- package/skills/llm-wiki-skill/scripts/delete-helper.sh +68 -0
- package/skills/llm-wiki-skill/scripts/graph-analysis.js +732 -0
- package/skills/llm-wiki-skill/scripts/hook-session-start.sh +46 -0
- package/skills/llm-wiki-skill/scripts/init-wiki.sh +95 -0
- package/skills/llm-wiki-skill/scripts/lib/source-signal-eligibility.js +158 -0
- package/skills/llm-wiki-skill/scripts/lint-fix.sh +114 -0
- package/skills/llm-wiki-skill/scripts/lint-runner.sh +217 -0
- package/skills/llm-wiki-skill/scripts/runtime-context.sh +77 -0
- package/skills/llm-wiki-skill/scripts/shared-config.sh +83 -0
- package/skills/llm-wiki-skill/scripts/source-record-contract.tsv +10 -0
- package/skills/llm-wiki-skill/scripts/source-registry.sh +349 -0
- package/skills/llm-wiki-skill/scripts/source-registry.tsv +10 -0
- package/skills/llm-wiki-skill/scripts/source-signal-coverage.js +83 -0
- package/skills/llm-wiki-skill/scripts/validate-step1.sh +144 -0
- package/skills/llm-wiki-skill/scripts/wiki-compat.sh +267 -0
- package/skills/llm-wiki-skill/setup.sh +8 -0
- package/skills/llm-wiki-skill/templates/entity-template.md +30 -0
- package/skills/llm-wiki-skill/templates/graph-styles/wash/footer.html +27 -0
- package/skills/llm-wiki-skill/templates/graph-styles/wash/graph-wash-helpers.js +1326 -0
- package/skills/llm-wiki-skill/templates/graph-styles/wash/graph-wash.js +1009 -0
- package/skills/llm-wiki-skill/templates/graph-styles/wash/header.html +2002 -0
- package/skills/llm-wiki-skill/templates/index-en-template.md +51 -0
- package/skills/llm-wiki-skill/templates/index-template.md +51 -0
- package/skills/llm-wiki-skill/templates/log-en-template.md +11 -0
- package/skills/llm-wiki-skill/templates/log-template.md +11 -0
- package/skills/llm-wiki-skill/templates/overview-en-template.md +41 -0
- package/skills/llm-wiki-skill/templates/overview-template.md +41 -0
- package/skills/llm-wiki-skill/templates/purpose-en-template.md +16 -0
- package/skills/llm-wiki-skill/templates/purpose-template.md +16 -0
- package/skills/llm-wiki-skill/templates/query-template.md +19 -0
- package/skills/llm-wiki-skill/templates/schema-template.md +185 -0
- package/skills/llm-wiki-skill/templates/source-template.md +51 -0
- package/skills/llm-wiki-skill/templates/synthesis-template.md +25 -0
- package/skills/llm-wiki-skill/templates/topic-template.md +35 -0
- package/skills/llm-wiki-skill/tests/adapter-state.sh +338 -0
- package/skills/llm-wiki-skill/tests/browser/graph-aggregation-fallback-trial.ts +737 -0
- package/skills/llm-wiki-skill/tests/browser/graph-community-node-map.mjs +255 -0
- package/skills/llm-wiki-skill/tests/browser/graph-community-wash-interactions.mjs +170 -0
- package/skills/llm-wiki-skill/tests/browser/graph-default-behavior.mjs +630 -0
- package/skills/llm-wiki-skill/tests/browser/graph-density-preview.mjs +53 -0
- package/skills/llm-wiki-skill/tests/browser/graph-html-insights.mjs +41 -0
- package/skills/llm-wiki-skill/tests/browser/graph-large-performance.ts +689 -0
- package/skills/llm-wiki-skill/tests/browser/graph-node-slim.mjs +75 -0
- package/skills/llm-wiki-skill/tests/browser/graph-offline-phase-6.mjs +660 -0
- package/skills/llm-wiki-skill/tests/browser/graph-renderer-trial-shared.ts +291 -0
- package/skills/llm-wiki-skill/tests/browser/graph-sigma-global-production.ts +1437 -0
- package/skills/llm-wiki-skill/tests/browser/graph-sigma-graphology-trial.ts +949 -0
- package/skills/llm-wiki-skill/tests/browser/graph-stage-4-5.mjs +815 -0
- package/skills/llm-wiki-skill/tests/browser/graph-vis-network-trial.ts +762 -0
- package/skills/llm-wiki-skill/tests/browser/graph-workbench-interactions.mjs +730 -0
- package/skills/llm-wiki-skill/tests/browser/validate-graph-trial-result.mjs +149 -0
- package/skills/llm-wiki-skill/tests/expected/graph-data-empty.json +60 -0
- package/skills/llm-wiki-skill/tests/expected/graph-data-sample.json +396 -0
- package/skills/llm-wiki-skill/tests/expected/graph-interactive-basic.html +1736 -0
- package/skills/llm-wiki-skill/tests/expected/lint-output.txt +44 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/index.md +1 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Alpha.md +10 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Beta.md +7 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Delta.md +8 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/entities/Gamma.md +8 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/queries/20260422-abc.md +10 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/synthesis/Crystal.md +8 -0
- package/skills/llm-wiki-skill/tests/fixtures/coverage-sample-wiki/wiki/topics/Overview.md +9 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-empty-wiki/wiki/entities/.gitkeep +0 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/purpose.md +3 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Attention.md +7 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Decoder.md +7 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Encoder.md +7 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/GPT.md +7 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/entities/Transformer.md +13 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/sources/paper.md +9 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/topics/arch.md +12 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-data-sample-wiki/wiki/topics/finetune.md +9 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-interactive-basic/wiki/graph-data.json +40 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-interactive-dense/wiki/graph-data.json +3965 -0
- package/skills/llm-wiki-skill/tests/fixtures/graph-interactive-multicomm/wiki/graph-data.json +212 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/index.md +14 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/C++.md +6 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/Lonely.md +4 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/Other.md +8 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/entities/Real.md +7 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/sources/2026-01-01-test-source.md +15 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/sources/2026-02-01-inline-img.md +12 -0
- package/skills/llm-wiki-skill/tests/fixtures/lint-sample-wiki/wiki/topics/AIbasic.md +3 -0
- package/skills/llm-wiki-skill/tests/graph-aggregation-fallback-trial.regression-1.sh +46 -0
- package/skills/llm-wiki-skill/tests/graph-analysis-helper.regression-1.sh +237 -0
- package/skills/llm-wiki-skill/tests/graph-browser-large-performance.regression-1.sh +39 -0
- package/skills/llm-wiki-skill/tests/graph-browser-stage-4-5.regression-1.sh +163 -0
- package/skills/llm-wiki-skill/tests/graph-build-failures.regression-1.sh +91 -0
- package/skills/llm-wiki-skill/tests/graph-community-node-map.regression-1.sh +107 -0
- package/skills/llm-wiki-skill/tests/graph-community-wash-interactions.regression-1.sh +35 -0
- package/skills/llm-wiki-skill/tests/graph-data-confidence-merge.regression-1.sh +309 -0
- package/skills/llm-wiki-skill/tests/graph-data-source-paths.regression-1.sh +49 -0
- package/skills/llm-wiki-skill/tests/graph-default-behavior.regression-1.sh +35 -0
- package/skills/llm-wiki-skill/tests/graph-html-a11y.regression-1.sh +50 -0
- package/skills/llm-wiki-skill/tests/graph-html-brand-link.regression-1.sh +47 -0
- package/skills/llm-wiki-skill/tests/graph-html-density.regression-1.sh +228 -0
- package/skills/llm-wiki-skill/tests/graph-html-drawer-neighbors.regression-1.sh +47 -0
- package/skills/llm-wiki-skill/tests/graph-html-insights.regression-1.sh +80 -0
- package/skills/llm-wiki-skill/tests/graph-html-long-label.regression-1.sh +92 -0
- package/skills/llm-wiki-skill/tests/graph-html-minimap.regression-1.sh +51 -0
- package/skills/llm-wiki-skill/tests/graph-html-mobile.regression-1.sh +48 -0
- package/skills/llm-wiki-skill/tests/graph-html-oriental-atlas-contract.regression-1.sh +94 -0
- package/skills/llm-wiki-skill/tests/graph-html-oriental-design-contract.regression-1.sh +82 -0
- package/skills/llm-wiki-skill/tests/graph-html-search.regression-1.sh +52 -0
- package/skills/llm-wiki-skill/tests/graph-html-styles.regression-1.sh +66 -0
- package/skills/llm-wiki-skill/tests/graph-html-toolbar.regression-1.sh +62 -0
- package/skills/llm-wiki-skill/tests/graph-offline-phase-6.regression-1.sh +51 -0
- package/skills/llm-wiki-skill/tests/graph-sigma-global-production.regression-1.sh +64 -0
- package/skills/llm-wiki-skill/tests/graph-sigma-graphology-trial.regression-1.sh +46 -0
- package/skills/llm-wiki-skill/tests/graph-vis-network-trial.regression-1.sh +46 -0
- package/skills/llm-wiki-skill/tests/graph-workbench-interactions.regression-1.sh +151 -0
- package/skills/llm-wiki-skill/tests/js/graph-wash-bootstrap.test.js +110 -0
- package/skills/llm-wiki-skill/tests/js/graph-wash-helpers.test.js +296 -0
- package/skills/llm-wiki-skill/tests/js/graph-wash-learning.test.js +260 -0
- package/skills/llm-wiki-skill/tests/js/graph-wash-queue.test.js +115 -0
- package/skills/llm-wiki-skill/tests/js/graph-wash-runtime-state.test.js +282 -0
- package/skills/llm-wiki-skill/tests/js/source-signal-coverage.test.js +48 -0
- package/skills/llm-wiki-skill/tests/js/source-signal-eligibility.test.js +202 -0
- package/skills/llm-wiki-skill/tests/lib/graph-html-engine-helpers.sh +110 -0
- package/skills/llm-wiki-skill/tests/lint-output.regression-1.sh +32 -0
- package/skills/llm-wiki-skill/tests/regression.sh +1754 -0
- package/skills/llm-wiki-skill/workbench/AGENTS.md +110 -0
- package/skills/llm-wiki-skill/workbench/CLAUDE.md +55 -0
- package/skills/llm-wiki-skill/workbench/LICENSE +21 -0
- package/skills/llm-wiki-skill/workbench/PRODUCT.md +1353 -0
- package/skills/llm-wiki-skill/workbench/README.md +30 -0
- package/skills/llm-wiki-skill/workbench/docs/current-kb-retrieval-design.md +587 -0
- package/skills/llm-wiki-skill/workbench/docs/graph-evolution-1-design.md +210 -0
- package/skills/llm-wiki-skill/workbench/docs/stage-2-design.md +1139 -0
- package/skills/llm-wiki-skill/workbench/docs/stage-3-design.md +1269 -0
- package/skills/llm-wiki-skill/workbench/docs/stage-3.5-design.md +1164 -0
- package/skills/llm-wiki-skill/workbench/docs/stage-4-design.md +504 -0
- package/skills/llm-wiki-skill/workbench/docs/stage-4.5-design.md +195 -0
- package/skills/llm-wiki-skill/workbench/docs/superpowers/specs/2026-05-28-resizable-preview-layout-design.md +165 -0
- package/skills/llm-wiki-skill/workbench/docs/superpowers/specs/2026-05-28-settings-panel-scroll-fix.md +50 -0
- package/skills/llm-wiki-skill/workbench/server/package.json +31 -0
- package/skills/llm-wiki-skill/workbench/server/src/agent.ts +457 -0
- package/skills/llm-wiki-skill/workbench/server/src/artifacts.ts +248 -0
- package/skills/llm-wiki-skill/workbench/server/src/auth.ts +164 -0
- package/skills/llm-wiki-skill/workbench/server/src/config.ts +130 -0
- package/skills/llm-wiki-skill/workbench/server/src/conversations.test.ts +159 -0
- package/skills/llm-wiki-skill/workbench/server/src/conversations.ts +270 -0
- package/skills/llm-wiki-skill/workbench/server/src/digest/batch.ts +189 -0
- package/skills/llm-wiki-skill/workbench/server/src/digest/concurrency.test.ts +36 -0
- package/skills/llm-wiki-skill/workbench/server/src/digest/concurrency.ts +31 -0
- package/skills/llm-wiki-skill/workbench/server/src/digest/subagent.ts +91 -0
- package/skills/llm-wiki-skill/workbench/server/src/extensions/artifacts.ts +81 -0
- package/skills/llm-wiki-skill/workbench/server/src/extensions/knowledge-base.ts +263 -0
- package/skills/llm-wiki-skill/workbench/server/src/extensions/new-wiki.ts +42 -0
- package/skills/llm-wiki-skill/workbench/server/src/extensions/synthesis.ts +172 -0
- package/skills/llm-wiki-skill/workbench/server/src/graph-watcher.test.ts +196 -0
- package/skills/llm-wiki-skill/workbench/server/src/graph.test.ts +113 -0
- package/skills/llm-wiki-skill/workbench/server/src/graph.ts +351 -0
- package/skills/llm-wiki-skill/workbench/server/src/index.ts +1148 -0
- package/skills/llm-wiki-skill/workbench/server/src/knowledge-bases.test.ts +30 -0
- package/skills/llm-wiki-skill/workbench/server/src/knowledge-bases.ts +321 -0
- package/skills/llm-wiki-skill/workbench/server/src/pages.test.ts +41 -0
- package/skills/llm-wiki-skill/workbench/server/src/pages.ts +160 -0
- package/skills/llm-wiki-skill/workbench/server/src/retrieval.test.ts +151 -0
- package/skills/llm-wiki-skill/workbench/server/src/retrieval.ts +427 -0
- package/skills/llm-wiki-skill/workbench/server/src/tool-status-events.test.ts +363 -0
- package/skills/llm-wiki-skill/workbench/server/src/tool-status-events.ts +616 -0
- package/skills/llm-wiki-skill/workbench/server/src/wiki-init.test.ts +19 -0
- package/skills/llm-wiki-skill/workbench/server/src/wiki-init.ts +188 -0
- package/skills/llm-wiki-skill/workbench/server/tsconfig.json +10 -0
- package/skills/llm-wiki-skill/workbench/tsconfig.json +20 -0
- package/skills/llm-wiki-skill/workbench/web/README.md +73 -0
- package/skills/llm-wiki-skill/workbench/web/components.json +21 -0
- package/skills/llm-wiki-skill/workbench/web/eslint.config.js +22 -0
- package/skills/llm-wiki-skill/workbench/web/index.html +16 -0
- package/skills/llm-wiki-skill/workbench/web/package.json +54 -0
- package/skills/llm-wiki-skill/workbench/web/src/App.tsx +1195 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/AddExternalDialog.tsx +375 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/AppearancePanel.tsx +158 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ArtifactView.tsx +15 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/BatchDigestPanel.tsx +117 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ChatPanel.tsx +890 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/CommandMenu.tsx +75 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ExportButtons.tsx +58 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/GraphPanel.tsx +800 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/GraphReader.tsx +52 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/GraphSelection.tsx +100 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/GraphSummaryDrawer.tsx +269 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/MainViewTabs.tsx +69 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/MarkdownView.tsx +106 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/NewWikiDialog.tsx +103 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/RefMenu.tsx +44 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/RightDrawer.tsx +298 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/SearchPanel.tsx +165 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/SettingsPanel.tsx +320 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/Sidebar.tsx +354 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ToolHistorySummary.tsx +111 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ToolStatusRunway.tsx +70 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/TopBar.tsx +348 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/renderers/DownloadOnlyRenderer.tsx +88 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/renderers/HtmlRenderer.tsx +92 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ui/button.tsx +52 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ui/command.tsx +50 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ui/dialog.tsx +156 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ui/input.tsx +21 -0
- package/skills/llm-wiki-skill/workbench/web/src/components/ui/tooltip.tsx +57 -0
- package/skills/llm-wiki-skill/workbench/web/src/index.css +4204 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/api.ts +648 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/appearance.ts +114 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/drawer-layout.ts +41 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/drawer-state.ts +168 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/graph-reader.ts +25 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/graph-selection-drawer.ts +35 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/graph-selection.ts +96 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/graph-summary-actions.ts +184 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/legacy-tool-status.ts +113 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/model-roles.ts +20 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/search-filter.ts +104 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/sse.ts +72 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/tool-status-format.ts +170 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/tool-status-model.ts +392 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/utils.ts +10 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/view-status.ts +16 -0
- package/skills/llm-wiki-skill/workbench/web/src/lib/wiki-links.ts +32 -0
- package/skills/llm-wiki-skill/workbench/web/src/main.tsx +10 -0
- package/skills/llm-wiki-skill/workbench/web/test/api.test.ts +61 -0
- package/skills/llm-wiki-skill/workbench/web/test/app-shell-drawer-layout.test.tsx +48 -0
- package/skills/llm-wiki-skill/workbench/web/test/appearance-panel.test.tsx +121 -0
- package/skills/llm-wiki-skill/workbench/web/test/appearance.test.ts +262 -0
- package/skills/llm-wiki-skill/workbench/web/test/chat-host-source.test.tsx +22 -0
- package/skills/llm-wiki-skill/workbench/web/test/chat-panel-auto-scroll.test.tsx +311 -0
- package/skills/llm-wiki-skill/workbench/web/test/chat-panel-bubbles.test.tsx +48 -0
- package/skills/llm-wiki-skill/workbench/web/test/chat-panel-composer.test.tsx +86 -0
- package/skills/llm-wiki-skill/workbench/web/test/chat-panel-tool-status.test.tsx +26 -0
- package/skills/llm-wiki-skill/workbench/web/test/export-batch-paper.test.tsx +101 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-drawer-state.test.ts +257 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-panel-paper.test.tsx +200 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-reader-request.test.ts +32 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-reader.test.ts +62 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-selection-drawer.test.ts +56 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-selection.test.ts +83 -0
- package/skills/llm-wiki-skill/workbench/web/test/graph-summary-actions.test.ts +188 -0
- package/skills/llm-wiki-skill/workbench/web/test/main-view-tabs.test.tsx +34 -0
- package/skills/llm-wiki-skill/workbench/web/test/markdown-view.test.tsx +34 -0
- package/skills/llm-wiki-skill/workbench/web/test/popup-menus.test.tsx +85 -0
- package/skills/llm-wiki-skill/workbench/web/test/render.test.tsx +30 -0
- package/skills/llm-wiki-skill/workbench/web/test/render.tsx +38 -0
- package/skills/llm-wiki-skill/workbench/web/test/right-drawer-graph-summary.test.tsx +287 -0
- package/skills/llm-wiki-skill/workbench/web/test/right-drawer-interactions.test.tsx +182 -0
- package/skills/llm-wiki-skill/workbench/web/test/search-filter.test.ts +65 -0
- package/skills/llm-wiki-skill/workbench/web/test/search-panel.test.tsx +155 -0
- package/skills/llm-wiki-skill/workbench/web/test/setup-dom.ts +66 -0
- package/skills/llm-wiki-skill/workbench/web/test/sidebar-v2-source.test.ts +17 -0
- package/skills/llm-wiki-skill/workbench/web/test/sidebar.test.tsx +110 -0
- package/skills/llm-wiki-skill/workbench/web/test/tool-history-summary.test.tsx +150 -0
- package/skills/llm-wiki-skill/workbench/web/test/tool-status-format.test.ts +107 -0
- package/skills/llm-wiki-skill/workbench/web/test/tool-status-model.test.ts +324 -0
- package/skills/llm-wiki-skill/workbench/web/test/tool-status-runway.test.ts +159 -0
- package/skills/llm-wiki-skill/workbench/web/test/topbar.test.tsx +248 -0
- package/skills/llm-wiki-skill/workbench/web/test/visual/paper-ui.ts +898 -0
- package/skills/llm-wiki-skill/workbench/web/test/wiki-links.test.ts +23 -0
- package/skills/llm-wiki-skill/workbench/web/test-results/paper-ui/actual/.gitkeep +1 -0
- package/skills/llm-wiki-skill/workbench/web/test-results/paper-ui/baseline/.gitkeep +1 -0
- package/skills/llm-wiki-skill/workbench/web/tsconfig.app.json +30 -0
- package/skills/llm-wiki-skill/workbench/web/tsconfig.json +7 -0
- package/skills/llm-wiki-skill/workbench/web/tsconfig.node.json +24 -0
- package/skills/llm-wiki-skill/workbench/web/vite.config.ts +28 -0
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
import { Service } from '@deepseek-ai/cordis';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
3
4
|
import { KanbanService } from '../domain/kanban-service.js';
|
|
4
5
|
import { FileEventStore } from '../domain/event-store.js';
|
|
6
|
+
import { deriveGatePlan, isGatePlan, branchMatches } from '../domain/gate-policy.js';
|
|
7
|
+
import { runGateCommands } from './gate-runner.js';
|
|
5
8
|
export class KanbanProvider extends Service {
|
|
6
9
|
service;
|
|
7
10
|
/** T32 fix:GUI retry 的任务执行器(由 startDispatcher 装配后注入;webServer 先于 agents 就绪时可为 null)。 */
|
|
8
11
|
runner = null;
|
|
9
|
-
|
|
12
|
+
/** 整链硬删除后的联动钩子(由 startDispatcher 装配注入):dispatcher 游标同步 + V 编排 entry 清理。
|
|
13
|
+
* purge 物理重排 events seq,若不同步则删链后新建链的可唤醒事件被运行中实例永久跳过。 */
|
|
14
|
+
onChainDeleted = null;
|
|
15
|
+
// Task 6:经 configProvider getter 读 effective 配置——配置面板改 wikiVault.baseUrl 后 kb_url 前缀校验热生效。
|
|
16
|
+
constructor(ctx, config, configProvider) {
|
|
10
17
|
super(ctx, 'kanban');
|
|
11
18
|
const dir = config.storageDir.replace('$DSH_HOME', process.env.DSH_HOME ?? homedir());
|
|
12
|
-
this.service = new KanbanService(new FileEventStore(dir),
|
|
19
|
+
this.service = new KanbanService(new FileEventStore(dir), () => configProvider.getEffective().wikiVault?.baseUrl);
|
|
20
|
+
// P1 实测闸装配(组合根):complete 前派生 GatePlan → 分支一致性核对 → 实测执行。
|
|
21
|
+
// hook 绝不 throw:意外异常记日志并返回 null(零感知 skip,fail-open 与分支不一致语义一致)。
|
|
22
|
+
this.service.setGateHook(async (task, handoff) => {
|
|
23
|
+
try {
|
|
24
|
+
// 热读取(同 wikiVault.baseUrl 先例,getEffective):配置面板改 gates 后无需重建即生效。
|
|
25
|
+
const cfg = configProvider.getEffective().gates ?? { enabled: true, timeoutMs: 600000, forbidden: ['rm -rf /', 'git push'] };
|
|
26
|
+
const plan = deriveGatePlan({ assignee: task.assignee, mode: task.mode, handoff, config: { enabled: cfg.enabled } });
|
|
27
|
+
if (!isGatePlan(plan))
|
|
28
|
+
return null; // skip:disabled/非 D/旧卡/路径违规
|
|
29
|
+
const wt = plan.commands[0].cwd;
|
|
30
|
+
// 分支一致性核对(防报假 worktree 绕闸):查询失败或与 metadata.branch 不一致 → skip 零感知。
|
|
31
|
+
const current = await new Promise((resolve) => {
|
|
32
|
+
const child = spawn('git', ['-C', wt, 'rev-parse', '--abbrev-ref', 'HEAD'], { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
33
|
+
let out = '';
|
|
34
|
+
child.stdout.on('data', (c) => { out += c.toString('utf8'); });
|
|
35
|
+
child.on('error', () => resolve(null));
|
|
36
|
+
child.on('close', (code) => resolve(code === 0 ? out.trim() || null : null));
|
|
37
|
+
});
|
|
38
|
+
if (!branchMatches(current, handoff.metadata?.['branch']))
|
|
39
|
+
return null;
|
|
40
|
+
const report = await runGateCommands(plan.commands, { timeoutMs: cfg.timeoutMs, forbidden: cfg.forbidden });
|
|
41
|
+
const detail = report.ok
|
|
42
|
+
? plan.commands.map((c) => c.command).join(' && ') + ' exit 0'
|
|
43
|
+
: `${report.failure.code}: ${report.failure.command} — ${report.failure.detail}\n${(report.results.at(-1)?.output ?? '').slice(-2000)}`;
|
|
44
|
+
return { ok: report.ok, detail };
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error('[dsh-swarm] gate hook failed (zero-awareness skip): ' + String(error));
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
13
51
|
}
|
|
14
52
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface CatalogProvider {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export interface CatalogModel {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
efforts: Array<{
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export interface LlmCatalog {
|
|
14
|
+
providers: CatalogProvider[];
|
|
15
|
+
models: Record<string, CatalogModel[]>;
|
|
16
|
+
}
|
|
17
|
+
export interface LlmRuntimeLike {
|
|
18
|
+
listProviders(): Array<{
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
}>;
|
|
22
|
+
listModels(provider: string): Promise<Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
}>>;
|
|
26
|
+
resolveModelInfo(provider: string, model: string): Promise<{
|
|
27
|
+
reasoning?: {
|
|
28
|
+
efforts?: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
export declare function buildLlmCatalog(llm: LlmRuntimeLike): Promise<LlmCatalog>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export async function buildLlmCatalog(llm) {
|
|
2
|
+
const providers = llm.listProviders().map((p) => ({ id: p.id, name: p.name }));
|
|
3
|
+
const models = {};
|
|
4
|
+
for (const p of providers) {
|
|
5
|
+
const list = await llm.listModels(p.id);
|
|
6
|
+
const entries = [];
|
|
7
|
+
for (const m of list) {
|
|
8
|
+
let efforts = [];
|
|
9
|
+
try {
|
|
10
|
+
const info = await llm.resolveModelInfo(p.id, m.id);
|
|
11
|
+
efforts = (info.reasoning?.efforts ?? []).map((e) => ({ id: e.id, name: e.name }));
|
|
12
|
+
}
|
|
13
|
+
catch { /* effort 解析失败 → 空 */ }
|
|
14
|
+
entries.push({ id: m.id, name: m.name, efforts });
|
|
15
|
+
}
|
|
16
|
+
models[p.id] = entries;
|
|
17
|
+
}
|
|
18
|
+
return { providers, models };
|
|
19
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PrefixRoutes } from '../config.js';
|
|
3
|
+
import type { ConfigProvider } from '../services/config-provider.js';
|
|
3
4
|
import { type PlanningToolDeps } from './planning-tools.js';
|
|
4
5
|
import type { PlanningChecklist } from '../domain/planning-checklist.js';
|
|
5
6
|
/** v2 规划上下文(/plan: 捕获 → planning_checklist_save 回写 → /openspec: 建链)。模块级内存,随插件进程存活。 */
|
|
@@ -13,8 +14,22 @@ export interface PlanningContext {
|
|
|
13
14
|
requirementName: string | null;
|
|
14
15
|
}
|
|
15
16
|
export declare const planningBySession: Map<string, PlanningContext>;
|
|
17
|
+
export declare const KANBAN_HANDOFF_RULE: (routes: PrefixRoutes) => string;
|
|
18
|
+
/** 防线③:/openspec: 成功后的逐链确定性叙述规则(2026-09-04 mtmgp81q:模型口播 ch_1_mtjrhkrf
|
|
19
|
+
* 与工具结果 ch_1_mtmgp81q 脱节)。逐字引用锚点 + firstCard 成败结论;整包缓存回放仍可能
|
|
20
|
+
* 绕过 prompt 层——最终防线是链级看门狗(防线①)。 */
|
|
21
|
+
export declare function buildOpenspecNarrationRule(r: {
|
|
22
|
+
chainId: string;
|
|
23
|
+
specCardId: string;
|
|
24
|
+
firstCard?: {
|
|
25
|
+
taskId: string;
|
|
26
|
+
status: string;
|
|
27
|
+
} | {
|
|
28
|
+
pending: true;
|
|
29
|
+
};
|
|
30
|
+
}): string;
|
|
16
31
|
export declare function buildSpawnPrefetch(ctx: Context): PlanningToolDeps['spawnPrefetch'] | undefined;
|
|
17
32
|
/** v2 主会话工具面:/plan: 捕获规划上下文(零副作用)→ planning_checklist_save 回写 → /openspec: 用清单建链。
|
|
18
33
|
* 工具面 = kanban_route + 只读 kanban 子集 + spec_card_view + planning 工具;
|
|
19
34
|
* 无 spec_card_edit/approve、无 kanban_create/complete/block(主会话越权写由工具面裁剪 + prefetch 子代理只读护栏双保险)。 */
|
|
20
|
-
export declare function registerMainSessionTools(ctx: Context,
|
|
35
|
+
export declare function registerMainSessionTools(ctx: Context, configProvider: ConfigProvider): void;
|
|
@@ -1,42 +1,66 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
2
|
+
import {} from '@deepseek-ai/dsh-util-values';
|
|
2
3
|
import { tmpdir } from 'node:os';
|
|
3
4
|
import { KanbanProvider } from '../services/kanban-provider.js';
|
|
4
5
|
import { buildKanbanTools } from './kanban-tools.js';
|
|
5
6
|
import { buildSpecCardTools } from './spec-card-tools.js';
|
|
6
7
|
import { buildPlanningTools } from './planning-tools.js';
|
|
7
|
-
import { handlePlanRoute, handleOpenspecRoute } from '../routes/prefix-router.js';
|
|
8
|
-
import {
|
|
8
|
+
import { handlePlanRoute, handleOpenspecRoute, handleLearningRoute } from '../routes/prefix-router.js';
|
|
9
|
+
import { recallMemoryIndex, searchChecklists } from '../wiki/memory-recall.js';
|
|
10
|
+
import { buildPlanningGuidance } from '../routes/planning-driver.js';
|
|
9
11
|
import { attachSessionToWorkspace, resolveOrCreateWorkspace } from '../dispatcher/workspace-attach.js';
|
|
10
12
|
import { PREFETCH_MANIFEST_SCHEMA } from '../domain/prefetch-manifest.js';
|
|
11
13
|
import { WikiVaultClient } from '../wiki/wiki-vault-client.js';
|
|
14
|
+
import { LocalWikiClient } from '../wiki/local-kb-client.js';
|
|
15
|
+
import { ensureLocalKbRoot } from '../wiki/local-kb.js';
|
|
16
|
+
import { LOCAL_CHECKLIST_PREFIX } from '../wiki/page-path.js';
|
|
12
17
|
export const planningBySession = new Map();
|
|
13
|
-
const KANBAN_HANDOFF_RULE = `
|
|
18
|
+
export const KANBAN_HANDOFF_RULE = (routes) => `
|
|
14
19
|
## 主 agent 铁律(看板工作流 v2)
|
|
15
20
|
- 你是计划者:只做需求澄清(grill-me)与最终收尾汇报;绝不执行任务本身。
|
|
16
21
|
- 最高护栏:只读仓库——禁止 git 操作、禁止 write/edit 任何仓库源码;只允许写 KB(planning_checklist_save)与临时目录兜底。
|
|
17
|
-
- 澄清期:调 planning_prefetch(只读子代理)采集仓库事实 → 逐问用户收敛 → 调 planning_checklist_save 存需求澄清清单 → 提醒用户
|
|
18
|
-
-
|
|
22
|
+
- 澄清期:调 planning_prefetch(只读子代理)采集仓库事实 → 逐问用户收敛 → 调 planning_checklist_save 存需求澄清清单 → 提醒用户 ${routes.openspec} 确认。
|
|
23
|
+
- ${routes.openspec} 后链路进入 executing,V 自动串行建卡 p→(pt)→w2→d→dt→w3;你不要自己执行。
|
|
19
24
|
- 用 kanban_show / kanban_list / spec_card_view 观察进度,链完成后向用户汇报产物链接与轨迹入口。
|
|
25
|
+
- 经验沉淀:链路完成后,用户可发 ${routes.learning}(或 ${routes.learning} <chainId>)沉淀本链经验;主 agent 消化机械证据包后调 planning_learning_save 入库。
|
|
26
|
+
- 叙述铁律:回复中的链号/卡号(ch_/sc_/t_ 编号)只能逐字复制自工具结果;建链成败以工具结果字段为准,禁止编造或沿用旧对话里的编号。
|
|
20
27
|
`;
|
|
28
|
+
/** 防线③:/openspec: 成功后的逐链确定性叙述规则(2026-09-04 mtmgp81q:模型口播 ch_1_mtjrhkrf
|
|
29
|
+
* 与工具结果 ch_1_mtmgp81q 脱节)。逐字引用锚点 + firstCard 成败结论;整包缓存回放仍可能
|
|
30
|
+
* 绕过 prompt 层——最终防线是链级看门狗(防线①)。 */
|
|
31
|
+
export function buildOpenspecNarrationRule(r) {
|
|
32
|
+
const firstCardLine = !r.firstCard
|
|
33
|
+
? '- 首卡结果未采集(旧返回体)。汇报前先调 kanban_show 复核链状态,以 kanban_show 复核后再汇报,禁止臆断建卡成功。'
|
|
34
|
+
: 'pending' in r.firstCard
|
|
35
|
+
? `- 首卡尚未创建(等待超时,看门狗接管)。回复必须写明「首卡尚未创建,看门狗接管」,禁止声称建卡成功。`
|
|
36
|
+
: `- 首卡已创建:taskId=${r.firstCard.taskId}(status=${r.firstCard.status})。回复必须写明「首卡已创建」。`;
|
|
37
|
+
return [
|
|
38
|
+
'## 本次建链结果(回复必须逐字引用,禁止改写编号)',
|
|
39
|
+
`- chainId=${r.chainId}`,
|
|
40
|
+
`- specCardId=${r.specCardId}`,
|
|
41
|
+
firstCardLine,
|
|
42
|
+
'- 铁律:回复中的 ch_/sc_/t_ 编号只能逐字复制自本结果;禁止出现本结果之外的任何编号;禁止声称与本结果矛盾的建卡状态。',
|
|
43
|
+
].join('\n');
|
|
44
|
+
}
|
|
21
45
|
// 清单获取只有两条路:内存(路由1)> KB 候选页(路由2,LLM 读页重建)。禁止编造其他原因
|
|
22
46
|
// ("先重试 / 查服务进程是否重启"类诊断是噪声:内存丢失唯一成因是插件重启,重启后按两条路恢复即可)。
|
|
23
|
-
const RECOVERY_KB_GUIDANCE = (candidates) => `
|
|
47
|
+
const RECOVERY_KB_GUIDANCE = (routes, candidates) => `
|
|
24
48
|
插件内存中的需求澄清清单已丢失(插件进程重启所致,属预期情况,按两条获取路由恢复即可,勿猜测其他原因)。
|
|
25
49
|
知识库中检索到候选清单页:
|
|
26
50
|
${candidates.map((c) => '- ' + c).join('\n')}
|
|
27
51
|
恢复步骤(严格顺序):
|
|
28
52
|
1. 读取候选页内容,对照当前需求判定哪一页是本次需求的需求澄清清单(页首行标题为「# 【需求】<需求名>」);
|
|
29
|
-
2. 消化该页内容,重建结构化 PlanningChecklist(spec 六段 + manifest + clarifications + doubts
|
|
53
|
+
2. 消化该页内容,重建结构化 PlanningChecklist(spec 六段 + manifest + clarifications + doubts + risks(风险点,若有),requirementName 取页标题中【需求】后的名称;恢复重建时 clarifications 允许登记单条无澄清说明,如 {"q": "本轮无澄清(恢复重建)", "a": "<来源页或原因>"},其余场景 clarifications 禁止为空);
|
|
30
54
|
3. 调 planning_checklist_save(checklist, restoreRef=<该候选页路径>) 回存(覆盖原页,勿产生重复页);
|
|
31
|
-
4. 回存成功后提示用户重新发送
|
|
55
|
+
4. 回存成功后提示用户重新发送 ${routes.openspec} 确认。
|
|
32
56
|
禁止:跳过恢复直接建链建卡;猜测清单内容;把恢复失败归因于"重试/进程检查"之外的任何原因。
|
|
33
57
|
`;
|
|
34
|
-
const RECOVERY_NONE_GUIDANCE = `
|
|
58
|
+
const RECOVERY_NONE_GUIDANCE = (routes) => `
|
|
35
59
|
两条获取路由均无本需求的需求澄清清单(内存为空,知识库亦无匹配页)。
|
|
36
60
|
处理步骤(严格顺序):
|
|
37
61
|
1. 消化当前对话上下文,判断需求澄清(grill-me 逐问收敛 + planning_prefetch 仓库事实)是否已完成但漏了保存动作;
|
|
38
62
|
2. 若已完成澄清——立即调 planning_checklist_save 保存清单;若尚未完成——先完成澄清(缺仓库事实则先 planning_prefetch),再保存;
|
|
39
|
-
3. 保存成功后提示用户重新发送
|
|
63
|
+
3. 保存成功后提示用户重新发送 ${routes.openspec} 确认。
|
|
40
64
|
禁止:在清单落库前建链建卡;编造"先重试 / 查服务进程是否重启"之类与清单无关的诊断。
|
|
41
65
|
`;
|
|
42
66
|
/** 预取子代理禁用的写能力工具(官方全局工具名;deny = 从 prompt 消失 + 拒绝执行,"one visibility")。 */
|
|
@@ -87,7 +111,7 @@ export function buildSpawnPrefetch(ctx) {
|
|
|
87
111
|
/** v2 主会话工具面:/plan: 捕获规划上下文(零副作用)→ planning_checklist_save 回写 → /openspec: 用清单建链。
|
|
88
112
|
* 工具面 = kanban_route + 只读 kanban 子集 + spec_card_view + planning 工具;
|
|
89
113
|
* 无 spec_card_edit/approve、无 kanban_create/complete/block(主会话越权写由工具面裁剪 + prefetch 子代理只读护栏双保险)。 */
|
|
90
|
-
export function registerMainSessionTools(ctx,
|
|
114
|
+
export function registerMainSessionTools(ctx, configProvider) {
|
|
91
115
|
const registry = ctx.get('tools');
|
|
92
116
|
if (!registry)
|
|
93
117
|
return; // 测试裸 Context 无 tools 服务(P1-9 无 inject 依赖),跳过注册
|
|
@@ -95,9 +119,13 @@ export function registerMainSessionTools(ctx, config) {
|
|
|
95
119
|
if (!provider)
|
|
96
120
|
return;
|
|
97
121
|
const service = provider.service;
|
|
98
|
-
// 生产 wiring(src/index.ts
|
|
99
|
-
//(与 dispatcher
|
|
100
|
-
|
|
122
|
+
// 生产 wiring(src/index.ts)仅保证 tools+kanban 可用,无 wiki 服务 → 经 configProvider 自建
|
|
123
|
+
//(与 dispatcher 构造同源,getEffective() 调用时热读取 baseUrl/pagePrefix);测试经 ctx.get('wiki') 注入 mock 客户端。
|
|
124
|
+
// D3 双模式:local 模式走 LocalWikiClient 本地检索(不发 HTTP),remote 用配置的 WikiVaultClient。
|
|
125
|
+
const kbMode = configProvider.mode;
|
|
126
|
+
const wiki = kbMode === 'local'
|
|
127
|
+
? new LocalWikiClient(ensureLocalKbRoot())
|
|
128
|
+
: (ctx.get('wiki') ?? new WikiVaultClient(() => configProvider.getEffective().wikiVault));
|
|
101
129
|
const caller = () => ({ actor: 'human' });
|
|
102
130
|
// 只读 kanban 子集(无 create/complete/block)
|
|
103
131
|
const readOnly = new Set(['kanban_show', 'kanban_chain', 'kanban_list', 'kanban_comment']);
|
|
@@ -113,11 +141,15 @@ export function registerMainSessionTools(ctx, config) {
|
|
|
113
141
|
}
|
|
114
142
|
// planning 工具(清单落库 + 只读预取)——spawnPrefetch 由模块级 buildSpawnPrefetch 提供(可单测)
|
|
115
143
|
for (const tool of buildPlanningTools({
|
|
116
|
-
service, wiki,
|
|
144
|
+
service, wiki: wiki, // local 模式为 LocalWikiClient(write/read/search 同面,D3 双模式客户端)
|
|
117
145
|
getCaller: caller,
|
|
118
146
|
spawnPrefetch: buildSpawnPrefetch(ctx),
|
|
119
147
|
tempDir: () => `${tmpdir()}/dsh-swarm-checklists`, // KB 不可达时的临时兜底,放系统临时目录(不落插件源码/核心存储目录)
|
|
120
|
-
pagePrefix:
|
|
148
|
+
pagePrefix: configProvider.getEffective().wikiVault?.pagePrefix ?? 'projects/', // 生成的清单页路径保持在该客户端配置的命名空间内(避免 kb-rejected)
|
|
149
|
+
kbMode: configProvider.mode, // D3 双模式:local 时 checklist/learning 落本地库命名空间(wiki/queries/checklists/、wiki/synthesis/learnings/)
|
|
150
|
+
prefixRoutes: configProvider.getEffective().prefixRoutes,
|
|
151
|
+
memoryEnabled: configProvider.getEffective().memory?.enabled ?? true,
|
|
152
|
+
resolveWorkspaceDir: () => planningBySession.get('session_main')?.workspaceDir ?? null,
|
|
121
153
|
ownerSessionId: 'session_main',
|
|
122
154
|
onChecklistSaved({ ref, source, checklist }) {
|
|
123
155
|
const cur = planningBySession.get('session_main') ?? { workspaceDir: null, sessionId: 'session_main', checklist: null, checklistRef: null, checklistSource: null, requirementName: null };
|
|
@@ -125,44 +157,99 @@ export function registerMainSessionTools(ctx, config) {
|
|
|
125
157
|
},
|
|
126
158
|
}))
|
|
127
159
|
registry.register(tool);
|
|
128
|
-
// kanban_route:/plan: 捕获规划上下文;/openspec:
|
|
160
|
+
// kanban_route:/plan: 捕获规划上下文;/openspec: 用清单建链(前缀路由注册时快照,用于工具描述)
|
|
161
|
+
const { plan, openspec, learning } = configProvider.getEffective().prefixRoutes;
|
|
129
162
|
registry.register(defineTool({
|
|
130
163
|
name: 'kanban_route',
|
|
131
|
-
description:
|
|
164
|
+
description: `MUST be called when the human message starts with ${plan}, ${openspec}, or ${learning}. This is dsh-swarm planning, NOT the built-in /plan plan mode. ${plan} = zero side-effect + start grill-me (+ auto KB memory index); ${openspec} = create chain from saved checklist; ${learning} = distill experience from a chain (evidence pack + planning_learning_save).`,
|
|
132
165
|
parameters: { message: { type: 'string', required: true } },
|
|
133
166
|
output: { schema: { type: 'json' }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v) }] },
|
|
134
167
|
async execute(args, exec) {
|
|
135
168
|
// M2(Q5)+归组:仅 /plan: 分支捕获主 agent 工作空间并可能询问注册——/openspec:/none 不触发,
|
|
136
169
|
// 避免死代码副作用多弹一次 ask(/openspec: 实际用的是 planningBySession 已存的 workspaceDir)。
|
|
137
170
|
// header.cwd 缺失或未注册时询问用户注册工作区;仍不可得保持 null(链任务随后 block 'workspace-unknown')。
|
|
138
|
-
const plan = await handlePlanRoute(args.message, service,
|
|
171
|
+
const plan = await handlePlanRoute(args.message, service, configProvider.getEffective().prefixRoutes, 'session_main');
|
|
139
172
|
if (plan.kind === 'plan') {
|
|
140
173
|
const headerCwd = exec?.agent?.session?.header?.cwd ?? null;
|
|
141
174
|
const workspaceDir = await resolveOrCreateWorkspace(ctx, headerCwd, '主 agent 会话');
|
|
142
175
|
planningBySession.set('session_main', { workspaceDir, sessionId: 'session_main', checklist: null, checklistRef: null, checklistSource: null, requirementName: plan.rest });
|
|
143
|
-
|
|
176
|
+
let guidance = buildPlanningGuidance(configProvider.getEffective().prefixRoutes) + KANBAN_HANDOFF_RULE(configProvider.getEffective().prefixRoutes);
|
|
177
|
+
if ((configProvider.getEffective().memory?.enabled ?? true) && workspaceDir) {
|
|
178
|
+
const idx = await recallMemoryIndex(wiki, {
|
|
179
|
+
requirementName: plan.rest || null,
|
|
180
|
+
workspaceDir,
|
|
181
|
+
maxEntries: configProvider.getEffective().memory?.maxIndexEntries ?? 8,
|
|
182
|
+
kbMode,
|
|
183
|
+
});
|
|
184
|
+
if (idx)
|
|
185
|
+
guidance += '\n' + idx;
|
|
186
|
+
}
|
|
187
|
+
return { kind: 'plan', guidance };
|
|
188
|
+
}
|
|
189
|
+
if (plan.kind === 'learning') {
|
|
190
|
+
const r = await handleLearningRoute(args.message, service, configProvider.getEffective().prefixRoutes, 'session_main');
|
|
191
|
+
if (r.error)
|
|
192
|
+
return { kind: 'learning', error: r.error, guidance: r.guidance };
|
|
193
|
+
return { kind: 'learning', chainId: r.chainId, brief: r.brief, guidance: r.guidance };
|
|
144
194
|
}
|
|
145
195
|
if (plan.kind === 'none')
|
|
146
196
|
return { kind: 'none' };
|
|
147
197
|
// 路由1(内存):planningBySession 命中 → 直接建链
|
|
148
198
|
const pctx = planningBySession.get('session_main');
|
|
149
199
|
if (pctx?.checklist && pctx.checklistRef) {
|
|
200
|
+
// 恢复补捕①:内存有清单但 workspaceDir=null(主 agent 重启后清单经 KB 恢复、异常态)→
|
|
201
|
+
// 从 exec.agent.session.header.cwd 捡回工作区,路由1 继续正常建链。已有值绝不重解析
|
|
202
|
+
// (不重复弹 ask,对齐下方 /plan: 分支注释顾虑);解析 null(无 cwd/无通道/用户跳过)保持
|
|
203
|
+
// 现状 → 走 handleOpenspecRoute 的 workspace-unknown fail-fast(不吞错、不猜测路径)。
|
|
204
|
+
if (!pctx.workspaceDir) {
|
|
205
|
+
const headerCwd = exec?.agent?.session?.header?.cwd ?? null;
|
|
206
|
+
const workspaceDir = await resolveOrCreateWorkspace(ctx, headerCwd, '主 agent 会话(/openspec: 恢复)');
|
|
207
|
+
if (workspaceDir) {
|
|
208
|
+
pctx.workspaceDir = workspaceDir;
|
|
209
|
+
planningBySession.set('session_main', pctx);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// 闸2:清单落库的仓库与当前工作区不一致 → 硬拦不建链(KB 页路径带 repoSlug 维度的前提是链与工作区同源)
|
|
213
|
+
const localPath = pctx.checklist.manifest.repo.localPath;
|
|
214
|
+
if (pctx.workspaceDir && localPath !== pctx.workspaceDir) {
|
|
215
|
+
return {
|
|
216
|
+
kind: 'openspec', approved: false, reason: 'workspace-mismatch',
|
|
217
|
+
error: `[workspace-mismatch] 清单 manifest.repo.localPath (${localPath}) 与当前工作区 (${pctx.workspaceDir}) 不一致。请在目标仓库工作区内重新执行 ${configProvider.getEffective().prefixRoutes.plan} 重新澄清落库后再 ${configProvider.getEffective().prefixRoutes.openspec}(不可跳过)。`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
150
220
|
const input = { workspaceDir: pctx.workspaceDir, checklist: pctx.checklist, checklistRef: pctx.checklistRef, requirementName: pctx.requirementName };
|
|
151
|
-
const r = await handleOpenspecRoute(args.message, service,
|
|
152
|
-
|
|
221
|
+
const r = await handleOpenspecRoute(args.message, service, configProvider.getEffective().prefixRoutes, input, 'session_main');
|
|
222
|
+
// 护栏拦截(如 workspace-unknown):透传失败原因与恢复指引,不得伪装成建链成功
|
|
223
|
+
if (r.approved === false || !r.chainId || !r.specCardId) {
|
|
224
|
+
return { kind: 'openspec', approved: false, reason: r.reason ?? 'unknown', guidance: r.guidance };
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
kind: 'openspec', chainId: r.chainId, specCardId: r.specCardId, approved: true, firstCard: r.firstCard,
|
|
228
|
+
guidance: KANBAN_HANDOFF_RULE(configProvider.getEffective().prefixRoutes) + '\n\n' + buildOpenspecNarrationRule({ chainId: r.chainId, specCardId: r.specCardId, firstCard: r.firstCard }),
|
|
229
|
+
};
|
|
153
230
|
}
|
|
154
231
|
// 路由2(知识库):内存丢失(插件重启)→ 搜 KB 候选清单页供 LLM 读页重建;搜不到/不可达 → 两条路皆空
|
|
232
|
+
// 恢复补捕②:无内存条目或工作区未捕获 → 从 header.cwd 捡回,写入 planningBySession(checklist 等
|
|
233
|
+
// 字段保持 cur 或空缺省),后续 planning_checklist_save 触发 onChecklistSaved 的 { ...cur } 展开自然
|
|
234
|
+
// 带上 workspaceDir。解析失败不阻塞恢复 guidance 返回(行为同现状,只是少捕一次)。
|
|
235
|
+
if (!planningBySession.get('session_main')?.workspaceDir) {
|
|
236
|
+
const headerCwd = exec?.agent?.session?.header?.cwd ?? null;
|
|
237
|
+
const workspaceDir = await resolveOrCreateWorkspace(ctx, headerCwd, '主 agent 会话(/openspec: 恢复)');
|
|
238
|
+
if (workspaceDir) {
|
|
239
|
+
const cur = planningBySession.get('session_main') ?? { workspaceDir: null, sessionId: 'session_main', checklist: null, checklistRef: null, checklistSource: null, requirementName: null };
|
|
240
|
+
planningBySession.set('session_main', { ...cur, workspaceDir });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
155
243
|
let candidates = [];
|
|
156
244
|
try {
|
|
157
|
-
|
|
158
|
-
candidates = (await wiki.search('【需求】')).map((r) => r.path).filter((p) => p.startsWith(pagePrefix)).slice(0, 5);
|
|
245
|
+
candidates = await searchChecklists(wiki, kbMode === 'local' ? LOCAL_CHECKLIST_PREFIX : (configProvider.getEffective().wikiVault?.pagePrefix ?? 'projects/'));
|
|
159
246
|
}
|
|
160
247
|
catch { /* KB 不可达/搜索失败 → 候选为空,走两条路皆空分支 */ }
|
|
161
248
|
return {
|
|
162
249
|
kind: 'openspec', approved: false, reason: 'no-checklist',
|
|
163
250
|
recovery: candidates.length > 0 ? 'kb' : 'none',
|
|
164
251
|
checklistCandidates: candidates,
|
|
165
|
-
guidance: candidates.length > 0 ? RECOVERY_KB_GUIDANCE(candidates) : RECOVERY_NONE_GUIDANCE,
|
|
252
|
+
guidance: candidates.length > 0 ? RECOVERY_KB_GUIDANCE(configProvider.getEffective().prefixRoutes, candidates) : RECOVERY_NONE_GUIDANCE(configProvider.getEffective().prefixRoutes),
|
|
166
253
|
};
|
|
167
254
|
},
|
|
168
255
|
}));
|
|
@@ -4,6 +4,7 @@ import type { WikiVaultClient } from '../wiki/wiki-vault-client.js';
|
|
|
4
4
|
import { type PlanningChecklist } from '../domain/planning-checklist.js';
|
|
5
5
|
import type { ToolCaller } from './kanban-tools.js';
|
|
6
6
|
import type { AgentModelOptions } from '../dispatcher/dispatcher.js';
|
|
7
|
+
import type { PrefixRoutes } from '../config.js';
|
|
7
8
|
/** 工具运行时上下文(dsh-tools ToolRunContext 窄型):agent loop 注入调用者 Agent 与取消信号,
|
|
8
9
|
* planning_prefetch 经官方子代理缝启动时需透传(parent + signal)。 */
|
|
9
10
|
export interface PrefetchExecContext {
|
|
@@ -19,7 +20,11 @@ export interface PlanningToolDeps {
|
|
|
19
20
|
spawnPrefetch?(prompt: string, workspaceDir: string, parentAgent?: Agent, signal?: AbortSignal): Promise<string>;
|
|
20
21
|
tempDir(): string;
|
|
21
22
|
pagePrefix?: string;
|
|
23
|
+
/** KB 双模式(D3):local 时 checklist/learning 落本地库命名空间(wiki/queries/checklists/、wiki/synthesis/learnings/),缺省 remote。 */
|
|
24
|
+
kbMode?: 'remote' | 'local';
|
|
22
25
|
ownerSessionId?: string;
|
|
26
|
+
/** 斜杠命令前缀路由(决策12 单一事实源),用于 description 文案派生。 */
|
|
27
|
+
prefixRoutes: PrefixRoutes;
|
|
23
28
|
defaultModel?: AgentModelOptions;
|
|
24
29
|
/** 清单落库成功回调(kb 与 temp 两分支各调一次),供 main-session-tools 回写 planningBySession。 */
|
|
25
30
|
onChecklistSaved?(saved: {
|
|
@@ -27,6 +32,10 @@ export interface PlanningToolDeps {
|
|
|
27
32
|
source: 'kb' | 'temp';
|
|
28
33
|
checklist: PlanningChecklist;
|
|
29
34
|
}): void;
|
|
35
|
+
/** memory.enabled;false 时 planning_memory_recall 返回 disabled 提示(planning_learning_save 不受影响)。 */
|
|
36
|
+
memoryEnabled?: boolean;
|
|
37
|
+
/** 闸1:/plan: 捕获的当前工作区(main-session-tools 注入);非 null 且与清单 localPath 不一致 → 阻断落库。 */
|
|
38
|
+
resolveWorkspaceDir?: () => string | null;
|
|
30
39
|
}
|
|
31
40
|
/** 主 agent 规划期工具:需求澄清清单落库(KB 优先/临时目录兜底)+ 只读仓库预取(子代理)。 */
|
|
32
41
|
export declare function buildPlanningTools(deps: PlanningToolDeps): import("@deepseek-ai/dsh-tools").ToolDefinition[];
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
// src/tools/planning-tools.ts
|
|
2
2
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
3
|
+
import {} from '@deepseek-ai/dsh-util-values';
|
|
3
4
|
import { validatePlanningChecklist, formatChecklistBody } from '../domain/planning-checklist.js';
|
|
4
5
|
import { validatePrefetchManifest } from '../domain/prefetch-manifest.js';
|
|
5
|
-
import { buildChecklistSlug,
|
|
6
|
+
import { buildChecklistSlug, KB_PAGE_NAMESPACES_HINT, LOCAL_CHECKLIST_PREFIX, LOCAL_LEARNING_BASE, assertAllowedWikiPagePath, assertLocalKbPagePath } from '../wiki/page-path.js';
|
|
7
|
+
import { validateLearning, formatLearningBody, buildRepoSlug } from '../domain/memory.js';
|
|
6
8
|
const isWikiError = (e) => e instanceof Error && e.code === 'kb-unreachable';
|
|
7
9
|
/** 主 agent 规划期工具:需求澄清清单落库(KB 优先/临时目录兜底)+ 只读仓库预取(子代理)。 */
|
|
8
10
|
export function buildPlanningTools(deps) {
|
|
11
|
+
const local = deps.kbMode === 'local';
|
|
12
|
+
// checklist 前缀双模式(D3/D5):remote → projects/<repoSlug>/checklists/(repoSlug 段在 pagePath 拼接,workspace 计划 T3);
|
|
13
|
+
// local → wiki/queries/checklists/(local 时 LocalWikiClient.write 仅接受 wiki/** 相对路径,projects/ 会被 kb-rejected——I1 修复)
|
|
9
14
|
const pagePrefix = deps.pagePrefix ?? 'projects/';
|
|
15
|
+
const checklistPrefix = local ? LOCAL_CHECKLIST_PREFIX : pagePrefix;
|
|
10
16
|
const session = deps.ownerSessionId ?? 'session_main';
|
|
11
17
|
return [
|
|
12
18
|
defineTool({
|
|
13
19
|
name: 'planning_checklist_save',
|
|
14
20
|
description: 'Save the converged requirement-clarification checklist (structured schema) to KB, falling back to a temp dir if KB is unreachable. Returns ref/path + authoritative repo path. restoreRef (optional) = existing KB page path to overwrite in place (recovery path when in-memory context was lost); omit for first-time save (creates a new timestamped page).',
|
|
15
|
-
parameters: { checklist: { type: 'json', required: true, description: 'Structured PlanningChecklist: spec
|
|
21
|
+
parameters: { checklist: { type: 'json', required: true, description: 'Structured PlanningChecklist: {requirementName?, spec: {problem, solution, user_stories, impl_decisions, testing, out_of_scope}, manifest, clarifications, doubts: Array<{"q": string, "resolved": boolean, "answer"?: string}>, risks?}. spec.user_stories: array of plain strings — each element ONE sentence "As a <role>, I want <capability>, so that <benefit>"; NEVER objects/nested. spec.impl_decisions: array of plain strings — one decision per element; NEVER objects. clarifications: non-empty required — record every Q&A asked during this planning round; Array<{"q": string, "a": string}> with keys exactly "q"/"a" (NOT "question"/"answer"). risks (optional): Array<{"description": string, "source": string, "mitigation": string}> — register real risks/non-blocking concerns surfaced during clarification; omit or [] when none. checklist.requirementName (optional) = ' + deps.prefixRoutes.plan + ' rest first sentence, used for the checklist page title 【需求】, same source as the task-card title' }, restoreRef: { type: 'string', description: 'Optional KB page path to overwrite in place (recovery path); omit for new save' } },
|
|
16
22
|
output: { schema: { type: 'json' }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v) }] },
|
|
17
23
|
async execute(args) {
|
|
18
24
|
const caller = deps.getCaller();
|
|
@@ -22,9 +28,13 @@ export function buildPlanningTools(deps) {
|
|
|
22
28
|
if (errors.length > 0)
|
|
23
29
|
throw new Error('invalid planning checklist: ' + errors.join('; '));
|
|
24
30
|
const checklist = args.checklist;
|
|
31
|
+
const wsDir = deps.resolveWorkspaceDir?.() ?? null;
|
|
32
|
+
if (wsDir && checklist.manifest.repo.localPath !== wsDir) {
|
|
33
|
+
throw new Error(`[workspace-mismatch] 清单 manifest.repo.localPath (${checklist.manifest.repo.localPath}) 与当前工作区 (${wsDir}) 不一致。请在目标仓库工作区内重新执行 ${deps.prefixRoutes.plan} 重新澄清落库(不可跳过)。`);
|
|
34
|
+
}
|
|
25
35
|
const body = formatChecklistBody(checklist);
|
|
26
36
|
// 恢复路径(内存丢失后重建):传 restoreRef 则覆盖原页,不产生重复页
|
|
27
|
-
if (args.restoreRef && args.restoreRef.startsWith(
|
|
37
|
+
if (args.restoreRef && args.restoreRef.startsWith(checklistPrefix)) {
|
|
28
38
|
try {
|
|
29
39
|
await deps.wiki.write(args.restoreRef, body);
|
|
30
40
|
deps.onChecklistSaved?.({ ref: args.restoreRef, source: 'kb', checklist });
|
|
@@ -36,7 +46,10 @@ export function buildPlanningTools(deps) {
|
|
|
36
46
|
// KB 不可达 → 落临时目录兜底(不覆盖原页),回调仍回填内存
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
|
-
const
|
|
49
|
+
const slug = buildChecklistSlug(checklist.requirementName ?? checklist.spec.problem);
|
|
50
|
+
const pagePath = local
|
|
51
|
+
? `${checklistPrefix}${slug}-${Date.now().toString(36)}.md`
|
|
52
|
+
: `${pagePrefix}${buildRepoSlug(checklist.manifest.repo.localPath)}/checklists/${slug}-${Date.now().toString(36)}.md`;
|
|
40
53
|
try {
|
|
41
54
|
await deps.wiki.write(pagePath, body);
|
|
42
55
|
deps.onChecklistSaved?.({ ref: pagePath, source: 'kb', checklist });
|
|
@@ -83,6 +96,109 @@ export function buildPlanningTools(deps) {
|
|
|
83
96
|
return { ok: true, manifest };
|
|
84
97
|
},
|
|
85
98
|
}),
|
|
99
|
+
defineTool({
|
|
100
|
+
name: 'planning_learning_save',
|
|
101
|
+
description: 'Save a distilled learning (experience) to the knowledge base. Remote KB: scope=chain → projects/<repoSlug>/<chainId>/learnings/ (requirement-level); scope=project → projects/<repoSlug>/learnings/ (repo-level). repoSlug is derived from the chain workspaceDir; both scopes require chain.workspaceDir. Local KB: both scopes → wiki/synthesis/learnings/<chainId|repoSlug>/. Returns ref. Soft-fails {ok:false,reason:"kb-unreachable"} when KB is unreachable (no temp fallback).',
|
|
102
|
+
parameters: {
|
|
103
|
+
learning: { type: 'json', required: true, description: 'LearningEntry: { title (≤80 chars), lesson, evidence (mechanical chain/task id — required), tags: string[] }' },
|
|
104
|
+
scope: { type: 'string', enum: ['chain', 'project'], required: true, description: '"chain" (requirement-level) | "project" (repo-level)' },
|
|
105
|
+
chainId: { type: 'string', required: true, description: 'The chain this learning is distilled from; must exist' },
|
|
106
|
+
},
|
|
107
|
+
output: { schema: { type: 'json' }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v) }] },
|
|
108
|
+
async execute(args) {
|
|
109
|
+
const caller = deps.getCaller();
|
|
110
|
+
if (caller.actor !== 'human')
|
|
111
|
+
throw new Error('permission denied: planning_learning_save');
|
|
112
|
+
const errors = validateLearning(args.learning);
|
|
113
|
+
if (errors.length > 0)
|
|
114
|
+
throw new Error('invalid learning: ' + errors.join('; '));
|
|
115
|
+
if (args.scope !== 'chain' && args.scope !== 'project')
|
|
116
|
+
throw new Error('invalid scope: ' + String(args.scope));
|
|
117
|
+
if (typeof args.chainId !== 'string' || !args.chainId.trim())
|
|
118
|
+
throw new Error('chainId required');
|
|
119
|
+
const state = await deps.service.snapshot();
|
|
120
|
+
const chain = state.chains.get(args.chainId);
|
|
121
|
+
if (!chain)
|
|
122
|
+
throw new Error('unknown chain: ' + args.chainId);
|
|
123
|
+
const entry = args.learning;
|
|
124
|
+
let prefix;
|
|
125
|
+
if (local) {
|
|
126
|
+
// local(D5):scope=chain 直接挂 chainId;scope=project 挂 repoSlug(需 workspaceDir)
|
|
127
|
+
if (args.scope === 'chain') {
|
|
128
|
+
prefix = `${LOCAL_LEARNING_BASE}${args.chainId}/`;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
if (!chain.workspaceDir)
|
|
132
|
+
throw new Error('scope=project requires chain.workspaceDir (target repo) — chain has none');
|
|
133
|
+
prefix = `${LOCAL_LEARNING_BASE}${buildRepoSlug(chain.workspaceDir)}/`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// remote(workspace 计划 T3):两 scope 均要求 chain.workspaceDir,统一挂 projects/<repoSlug>/
|
|
138
|
+
if (!chain.workspaceDir)
|
|
139
|
+
throw new Error('learning save requires chain.workspaceDir (target repo) — chain has none');
|
|
140
|
+
const wsRoot = `${pagePrefix}${buildRepoSlug(chain.workspaceDir)}/`;
|
|
141
|
+
prefix = args.scope === 'chain' ? `${wsRoot}${args.chainId}/learnings/` : `${wsRoot}learnings/`;
|
|
142
|
+
}
|
|
143
|
+
const pagePath = `${prefix}${buildChecklistSlug(entry.title)}-${Date.now().toString(36)}.md`;
|
|
144
|
+
try {
|
|
145
|
+
await deps.wiki.write(pagePath, formatLearningBody(entry));
|
|
146
|
+
return { ok: true, ref: pagePath, scope: args.scope };
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
if (isWikiError(err))
|
|
150
|
+
return { ok: false, reason: 'kb-unreachable' };
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
}),
|
|
155
|
+
defineTool({
|
|
156
|
+
name: 'planning_memory_recall',
|
|
157
|
+
description: 'Recall KB memory for planning. path mode: read a full page truncated to 8000 chars. path mode whitelist: remote = ' + KB_PAGE_NAMESPACES_HINT + '; local = any wiki/** relative path inside the local KB root. query mode: full-text search returning top 5 {path,title,score}. Returns {ok:false,reason:"kb-unreachable"} on KB failure; {ok:false,reason:"disabled"} when memory is disabled.',
|
|
158
|
+
parameters: {
|
|
159
|
+
path: { type: 'string', description: 'KB page path to read in full (mutually exclusive with query). remote mode: projects/ namespace path; local mode: wiki/** relative path inside the local KB root.' },
|
|
160
|
+
query: { type: 'string', description: 'Full-text query; returns top 5 result paths (mutually exclusive with path)' },
|
|
161
|
+
},
|
|
162
|
+
output: { schema: { type: 'json' }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v) }] },
|
|
163
|
+
async execute(args) {
|
|
164
|
+
const caller = deps.getCaller();
|
|
165
|
+
if (caller.actor !== 'human')
|
|
166
|
+
throw new Error('permission denied: planning_memory_recall');
|
|
167
|
+
if (deps.memoryEnabled === false)
|
|
168
|
+
return { ok: false, reason: 'disabled' };
|
|
169
|
+
const hasPath = typeof args.path === 'string' && args.path.trim().length > 0;
|
|
170
|
+
const hasQuery = typeof args.query === 'string' && args.query.trim().length > 0;
|
|
171
|
+
if (hasPath === hasQuery)
|
|
172
|
+
throw new Error('provide exactly one of path|query');
|
|
173
|
+
if (hasPath) {
|
|
174
|
+
// path 白名单按 KB 双模式分支(D3/D9):remote → projects/** 命名空间;local → wiki/**(
|
|
175
|
+
// Task 11 后 local 的 checklist/learning 全落 wiki/ 前缀,用 projects/ 白名单会把 local 读腿全拒)
|
|
176
|
+
if (local)
|
|
177
|
+
assertLocalKbPagePath(args.path);
|
|
178
|
+
else
|
|
179
|
+
assertAllowedWikiPagePath(args.path);
|
|
180
|
+
try {
|
|
181
|
+
const d = await deps.wiki.read(args.path);
|
|
182
|
+
const content = d.rawMd.length > 8000 ? d.rawMd.slice(0, 8000) + '…' : d.rawMd;
|
|
183
|
+
return { ok: true, path: args.path, content };
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
if (isWikiError(err))
|
|
187
|
+
return { ok: false, reason: 'kb-unreachable' };
|
|
188
|
+
throw err;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const results = (await deps.wiki.search(args.query)).slice(0, 5).map((r) => ({ path: r.path, title: r.title, score: r.score }));
|
|
193
|
+
return { ok: true, results };
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
if (isWikiError(err))
|
|
197
|
+
return { ok: false, reason: 'kb-unreachable' };
|
|
198
|
+
throw err;
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
}),
|
|
86
202
|
];
|
|
87
203
|
}
|
|
88
204
|
function parseManifestOutput(output) {
|