@joekytc/dsh-swarm 0.1.2 → 0.3.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 +177 -140
- package/README.zh-CN.md +173 -126
- package/client/BoardCard.tsx +24 -2
- package/client/ConfigSection.tsx +162 -0
- package/client/ConfigSelect.tsx +71 -0
- package/client/KanbanBoard.tsx +3 -0
- package/client/KanbanTab.tsx +4 -3
- package/client/TaskDrawer.tsx +4 -26
- package/client/WorkflowRail.tsx +3 -1
- package/client/config-store.ts +92 -0
- package/client/config.css +110 -0
- package/client/index.ts +39 -4
- package/client/kanban.css +88 -2
- package/client/session-bridge.ts +39 -0
- package/client/timeline-model.ts +12 -1
- package/client/workflow-model.ts +3 -1
- package/lib/client.js +519 -56
- package/lib/config.d.ts +26 -2
- package/lib/config.js +20 -1
- package/lib/dispatcher/agent-runner.d.ts +37 -7
- package/lib/dispatcher/agent-runner.js +239 -86
- package/lib/dispatcher/chain-auditor.d.ts +4 -4
- package/lib/dispatcher/chain-auditor.js +14 -9
- package/lib/dispatcher/dispatcher.d.ts +69 -10
- package/lib/dispatcher/dispatcher.js +281 -42
- package/lib/dispatcher/event-waker.d.ts +1 -1
- package/lib/dispatcher/event-waker.js +2 -2
- package/lib/dispatcher/git-credentials.d.ts +2 -2
- package/lib/dispatcher/git-credentials.js +2 -2
- package/lib/dispatcher/model-candidates.d.ts +1 -1
- package/lib/dispatcher/model-candidates.js +1 -1
- package/lib/dispatcher/session-events.d.ts +12 -16
- package/lib/dispatcher/session-events.js +18 -6
- package/lib/dispatcher/target-repo.d.ts +2 -2
- package/lib/dispatcher/target-repo.js +3 -3
- package/lib/dispatcher/v-orchestrator.d.ts +44 -11
- package/lib/dispatcher/v-orchestrator.js +257 -49
- package/lib/dispatcher/watchdog.d.ts +1 -1
- package/lib/dispatcher/watchdog.js +2 -2
- package/lib/domain/config-override.d.ts +52 -0
- package/lib/domain/config-override.js +138 -0
- package/lib/domain/delivery-contract.d.ts +4 -3
- package/lib/domain/delivery-contract.js +30 -18
- package/lib/domain/delivery-evidence.d.ts +1 -1
- package/lib/domain/delivery-evidence.js +1 -1
- package/lib/domain/event-store.js +1 -1
- package/lib/domain/gate-policy.d.ts +26 -0
- package/lib/domain/gate-policy.js +44 -0
- package/lib/domain/im-message.d.ts +15 -0
- package/lib/domain/im-message.js +149 -0
- package/lib/domain/kanban-service.d.ts +28 -12
- package/lib/domain/kanban-service.js +73 -30
- package/lib/domain/memory.js +1 -1
- package/lib/domain/ocr-review.d.ts +47 -0
- package/lib/domain/ocr-review.js +105 -0
- package/lib/domain/permissions.js +6 -6
- package/lib/domain/planning-checklist.d.ts +5 -0
- package/lib/domain/planning-checklist.js +80 -6
- package/lib/domain/projection.js +8 -7
- package/lib/domain/review-evidence.js +1 -1
- package/lib/domain/state-machine.js +3 -2
- package/lib/domain/task-parents.js +1 -1
- package/lib/domain/types.d.ts +5 -5
- package/lib/index.js +28 -25
- package/lib/roles/clean-fs-tools.d.ts +22 -0
- package/lib/roles/clean-fs-tools.js +117 -0
- package/lib/roles/preset-installer.js +3 -3
- package/lib/roles/skill-installer.d.ts +6 -0
- package/lib/roles/skill-installer.js +32 -0
- package/lib/roles/toolsets.d.ts +71 -15
- package/lib/roles/toolsets.js +418 -68
- package/lib/roles/wiki-worker.d.ts +1 -0
- package/lib/roles/wiki-worker.js +12 -4
- package/lib/routes/kanban-http.d.ts +28 -2
- package/lib/routes/kanban-http.js +199 -6
- package/lib/routes/kanban-sse.d.ts +1 -1
- package/lib/routes/kanban-sse.js +1 -1
- package/lib/routes/planning-driver.d.ts +6 -2
- package/lib/routes/planning-driver.js +15 -7
- package/lib/routes/prefix-router.d.ts +19 -3
- package/lib/routes/prefix-router.js +40 -3
- package/lib/services/config-provider.d.ts +38 -0
- package/lib/services/config-provider.js +92 -0
- package/lib/services/gate-runner.d.ts +24 -0
- package/lib/services/gate-runner.js +87 -0
- package/lib/services/im-delivery.d.ts +94 -0
- package/lib/services/im-delivery.js +263 -0
- package/lib/services/kanban-provider.d.ts +6 -2
- package/lib/services/kanban-provider.js +41 -3
- package/lib/services/llm-catalog.d.ts +35 -0
- package/lib/services/llm-catalog.js +19 -0
- package/lib/services/ocr-cli.d.ts +35 -0
- package/lib/services/ocr-cli.js +128 -0
- package/lib/tools/kanban-tools.d.ts +2 -2
- package/lib/tools/kanban-tools.js +2 -1
- package/lib/tools/main-session-tools.d.ts +22 -3
- package/lib/tools/main-session-tools.js +135 -30
- package/lib/tools/ocr-review-tools.d.ts +11 -0
- package/lib/tools/ocr-review-tools.js +63 -0
- package/lib/tools/planning-tools.d.ts +8 -1
- package/lib/tools/planning-tools.js +44 -15
- package/lib/tools/prefetch-tools.js +1 -0
- package/lib/tools/spec-card-tools.js +1 -0
- package/lib/tools/wiki-tools.js +6 -5
- 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 +14 -6
- package/lib/wiki/memory-recall.js +17 -13
- package/lib/wiki/page-path.d.ts +9 -3
- package/lib/wiki/page-path.js +33 -12
- package/lib/wiki/wiki-vault-client.d.ts +3 -3
- package/lib/wiki/wiki-vault-client.js +6 -6
- package/package.json +16 -11
- package/personas/kanban-d/agent.cordis.yml +5 -5
- package/personas/kanban-d/preset.yml +1 -1
- package/personas/kanban-dt/agent.cordis.yml +25 -7
- package/personas/kanban-dt/preset.yml +1 -1
- package/personas/kanban-p/agent.cordis.yml +19 -3
- package/personas/kanban-p/preset.yml +1 -1
- package/personas/kanban-pt/agent.cordis.yml +39 -9
- package/personas/kanban-pt/preset.yml +1 -1
- package/personas/kanban-v/agent.cordis.yml +3 -3
- package/personas/kanban-w/agent.cordis.yml +37 -18
- package/personas/kanban-w/preset.yml +1 -1
- package/personas/persona-d.md +1 -1
- package/personas/persona-dt.md +13 -5
- package/personas/persona-p.md +5 -2
- package/personas/persona-pt.md +13 -6
- package/personas/persona-v.md +2 -2
- package/personas/persona-w.md +11 -9
- package/personas/swarm/agent.cordis.yml +43 -0
- package/personas/swarm/preset.yml +5 -0
- 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,8 +1,9 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ConfigProvider } from '../services/config-provider.js';
|
|
3
3
|
import { EventWaker } from './event-waker.js';
|
|
4
4
|
import { Watchdog } from './watchdog.js';
|
|
5
5
|
import type { KanbanService } from '../domain/kanban-service.js';
|
|
6
|
+
import type { Task } from '../domain/types.js';
|
|
6
7
|
export interface AgentModelOptions {
|
|
7
8
|
provider: string;
|
|
8
9
|
model: string;
|
|
@@ -18,16 +19,35 @@ export interface DispatcherDeps {
|
|
|
18
19
|
waker: EventWaker;
|
|
19
20
|
watchdog: Watchdog;
|
|
20
21
|
maxRetries: number;
|
|
21
|
-
/** lastSeq
|
|
22
|
+
/** lastSeq 持久化文件(与事件日志同目录)。 */
|
|
22
23
|
stateFile: string;
|
|
23
|
-
/**
|
|
24
|
+
/** 调度器运行日志文件(storageDir/dispatcher.log)。 */
|
|
24
25
|
logFile: string;
|
|
26
|
+
/** 宿主 agents 注册表(ctx.get('agents'))——启动 reconcile 判别 kbn-<taskId>
|
|
27
|
+
* 会话是否仍 live(插件热重载豁免);缺省/无 get 方法时按原行为收敛(保守)。 */
|
|
28
|
+
agents?: unknown;
|
|
29
|
+
/** 防线①:链级停滞探针(生产传 VOrchestrator;测试传桩)。缺省=看门狗关闭(行为同旧)。 */
|
|
30
|
+
stallProbe?: {
|
|
31
|
+
orchestrationOf(chainId: string): {
|
|
32
|
+
phase: string;
|
|
33
|
+
} | null;
|
|
34
|
+
isWakeInFlight(chainId: string): boolean;
|
|
35
|
+
wake(chainId: string): Promise<void>;
|
|
36
|
+
};
|
|
25
37
|
}
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
38
|
+
/** wakeImpl 装配(防线②,2026-09-04 mtmgp81q 死法教训):wakeV 异常必须落盘 dispatcher.log——
|
|
39
|
+
* 原实现仅 console.error,无控制台运行时零痕迹(排障最大障碍)。吞异常是为防 withTimeout
|
|
40
|
+
* 超时后迟到的 rejection 变 unhandledRejection;onSettled(saveOrchs)无论成败都执行。 */
|
|
41
|
+
export declare function makeWakeImpl(wakeV: (chainId: string) => Promise<void>, logFile: string, onSettled: () => void): (chainId: string) => Promise<void>;
|
|
42
|
+
/** 防线①:链级进度看门狗阈值。tick=2000ms × 45 ticks = 90s 无进展即重唤醒。 */
|
|
43
|
+
export declare const STALL_WATCHDOG_TICKS = 45;
|
|
44
|
+
/** 防线①:链级重唤醒上限(超限 [create-failed] + chain/blocked)。 */
|
|
45
|
+
export declare const STALL_WATCHDOG_REWAKE_LIMIT = 3;
|
|
46
|
+
/** 调度器:事件唤醒 V(逐阶段建卡)+ 每任务一次性角色 agent + 心跳看门狗。
|
|
47
|
+
* - failed 且 attempts<maxRetries 的任务重派(claim→running,AgentRunner resume 同一会话);
|
|
28
48
|
* attempts≥maxRetries 熔断 blocked(gave_up)。
|
|
29
|
-
* -
|
|
30
|
-
* -
|
|
49
|
+
* - lastSeq 持久化,重启后仅唤醒 lastSeq 之后的事件。
|
|
50
|
+
* - inFlight 互斥,防止慢 tick 与下一轮并发重复派发同一任务。 */
|
|
31
51
|
export declare class Dispatcher {
|
|
32
52
|
private readonly kanban;
|
|
33
53
|
private readonly runner;
|
|
@@ -36,15 +56,54 @@ export declare class Dispatcher {
|
|
|
36
56
|
private readonly maxRetries;
|
|
37
57
|
private readonly stateFile;
|
|
38
58
|
private readonly logFile;
|
|
59
|
+
private readonly agents;
|
|
60
|
+
private readonly stallProbe;
|
|
39
61
|
private lastSeq;
|
|
62
|
+
private orphanReconciled;
|
|
40
63
|
private inFlight;
|
|
64
|
+
private stallState;
|
|
41
65
|
private timer;
|
|
42
66
|
constructor(deps: DispatcherDeps);
|
|
43
67
|
private ensureLastSeq;
|
|
44
68
|
tick(): Promise<void>;
|
|
69
|
+
/** 防线①:链级进度看门狗(与 wakeVInner 内建 stall 互补,后者挂在 wakeVInner 内部,
|
|
70
|
+
* 异常退出/挂起/未触发时失效——2026-09-04 mtmgp81q)。只看最终事实:
|
|
71
|
+
* executing 非 summary + 链上零非终态任务卡 + 无在途唤醒 + 本链无新看板事件,
|
|
72
|
+
* 持续 STALL_WATCHDOG_TICKS 个 tick → 重唤醒(≤STALL_WATCHDOG_REWAKE_LIMIT 次)→
|
|
73
|
+
* 仍停滞 → [create-failed] 评论(有锚点卡时)+ blockChain 终态(人工恢复=删链重跑)。 */
|
|
74
|
+
private chainStallWatchdog;
|
|
45
75
|
start(intervalMs: number): void;
|
|
76
|
+
/** 整链硬删除联动:purge 物理重排 events.jsonl seq,游标必须同步钳到当前 maxSeq。
|
|
77
|
+
* 否则删链后新建链的可唤醒事件(seq < 旧内存游标)被运行中实例永久跳过——启动时自愈,
|
|
78
|
+
* 覆盖不了运行中删链场景(2026-09-02 残留审计结论)。 */
|
|
79
|
+
onPurge(): Promise<void>;
|
|
46
80
|
stop(): void;
|
|
47
81
|
}
|
|
48
|
-
/** 调度层装配:事件唤醒 V
|
|
49
|
-
* 仅在 agents 与 kanban 服务同时可用时由插件入口调用(不依赖可能已错过的 ready 事件)。
|
|
50
|
-
|
|
82
|
+
/** 调度层装配:事件唤醒 V(逐阶段建卡)+ 每任务一次性角色 agent + 心跳看门狗。
|
|
83
|
+
* 仅在 agents 与 kanban 服务同时可用时由插件入口调用(不依赖可能已错过的 ready 事件)。
|
|
84
|
+
* 收 ConfigProvider——storageDir 取启动时快照;wiki/模型链经 getEffective() 调用时热读取。 */
|
|
85
|
+
/** 启动 reconcile:剔除事件流中已不存在的链的编排 entry(历史残留/外部 purge)。
|
|
86
|
+
* 原地删除并返回被移除的 chainId 列表(调用方负责持久化与日志)。 */
|
|
87
|
+
export declare function reconcileOrchestrations<T>(orch: Map<string, T>, chains: Set<string>): string[];
|
|
88
|
+
/** 启动 reconcile:进程重启会杀死 runner 的 whenIdle 协程,上次遗留的 running 卡无人收尾,
|
|
89
|
+
* 看门狗默认 4h(staleTimeoutSeconds=14400)才回收——重启后立即把 running 孤儿卡收敛为 blocked
|
|
90
|
+
* (system comment + blockTask),中断显形且可重派续跑(重派将 resume 同一会话,进度保留)。
|
|
91
|
+
* 状态机注:TaskStatus 无独立 'claimed' 态——claimTask 发 task/claimed 事件后投影即为 running,
|
|
92
|
+
* 扫描 running 即覆盖「claimed 未收尾」;todo/ready/triage 从未派发,done/blocked/failed/archived
|
|
93
|
+
* 已有归属或终态(且 failed 的处置归重派/熔断管辖),均不动。
|
|
94
|
+
* 热重载兼容,双重判据:收敛每张 running 卡前先查宿主 agents 注册表
|
|
95
|
+
* ctx.get('agents').get('kbn-<taskId>')(session id 构造同 AgentRunner.resumeOrReuse)。
|
|
96
|
+
* 两个世界的分野:
|
|
97
|
+
* - 进程重启:agents 注册表随宿主进程消亡,新进程内 kbn-<taskId> 必然查不到(undefined)
|
|
98
|
+
* → 会话已死 → 全部收敛,语义与修复前一致;
|
|
99
|
+
* - 插件热重载:宿主进程未死,dsh 插件重载重跑 startDispatcherInner → orphanReconciled 闸复位,
|
|
100
|
+
* 但宿主 agent 会话仍 live(注册表命中)→ 本进程真在跑,不是孤儿 → 跳过该卡,
|
|
101
|
+
* 避免把合法 running 卡误收敛为 blocked。
|
|
102
|
+
* agents 服务缺失 / 无 get 方法(测试桩/异常宿主)→ 无法证明 live,按原行为收敛(保守)。
|
|
103
|
+
* 调用位置必须在游标自愈(ensureLastSeq)之后、事件消费之前:游标 rewind 会全量重放旧事件,
|
|
104
|
+
* 先收敛孤儿可保证本次 tick 消费的重放事件面对的是已收敛状态,且孤儿产生的 block 事件天然
|
|
105
|
+
* 落在本轮快照之外(下一轮才被消费唤醒 V 走阻塞复核),不与启动重放交错。
|
|
106
|
+
* 幂等:仅启动执行一次(调用方置闸);对同一卡重复调用时状态机拒绝 running→blocked 之外的
|
|
107
|
+
* 非法转换,comment/block 失败均 try/catch 记日志跳过不抛(单卡失败不阻断其余收敛)。 */
|
|
108
|
+
export declare function reconcileOrphanRunningTasks(kanban: KanbanService, tasks: Iterable<Task>, logFile: string, agents?: unknown): Promise<string[]>;
|
|
109
|
+
export declare function startDispatcher(ctx: Context, configProvider: ConfigProvider): void;
|
|
@@ -2,13 +2,15 @@ import { readFileSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { KanbanProvider } from '../services/kanban-provider.js';
|
|
4
4
|
import { WikiVaultClient } from '../wiki/wiki-vault-client.js';
|
|
5
|
+
import { LocalWikiClient } from '../wiki/local-kb-client.js';
|
|
6
|
+
import { ensureLocalKbRoot } from '../wiki/local-kb.js';
|
|
5
7
|
import { EventWaker } from './event-waker.js';
|
|
6
8
|
import { VOrchestrator } from './v-orchestrator.js';
|
|
7
9
|
import { AgentRunner } from './agent-runner.js';
|
|
8
10
|
import { Watchdog } from './watchdog.js';
|
|
9
11
|
import { ChainAuditor } from './chain-auditor.js';
|
|
10
12
|
import { mergeDAfterReview } from './merge-gate.js';
|
|
11
|
-
import { buildSubagentTreeGuard } from '../roles/toolsets.js';
|
|
13
|
+
import { buildSubagentTreeGuard, buildSwarmSessionGuard, buildStandaloneDtGuard, registerStandaloneReviewerTools } from '../roles/toolsets.js';
|
|
12
14
|
import { syncKbLinks } from '../wiki/kb-linkage.js';
|
|
13
15
|
/** 读取部署默认模型(settings 的 agent-default-model 优先,其次 dsh-agent-default-model),角色未单独配置时回退使用。 */
|
|
14
16
|
export function resolveDefaultModel(ctx) {
|
|
@@ -39,7 +41,7 @@ function parentsDone(task, state) {
|
|
|
39
41
|
return parent !== undefined && (parent.status === 'done' || parent.status === 'archived');
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
|
-
/**
|
|
44
|
+
/** 从状态文件恢复 lastSeq;无文件时回退到事件日志尾行(不重放旧事件重复唤醒 V)。 */
|
|
43
45
|
function loadLastSeq(stateFile) {
|
|
44
46
|
try {
|
|
45
47
|
const raw = JSON.parse(readFileSync(stateFile, 'utf8'));
|
|
@@ -55,25 +57,44 @@ function saveLastSeq(stateFile, lastSeq) {
|
|
|
55
57
|
}
|
|
56
58
|
catch { /* 忽略写失败:事件日志仍是事实源 */ }
|
|
57
59
|
}
|
|
58
|
-
/**
|
|
60
|
+
/** 把 [dsh-swarm] 关键事件追加到 storageDir/dispatcher.log,便于无控制台时观测调度器状态。 */
|
|
59
61
|
function logToFile(file, msg) {
|
|
60
62
|
try {
|
|
61
63
|
writeFileSync(file, new Date().toISOString() + ' ' + msg + '\n', { flag: 'a' });
|
|
62
64
|
}
|
|
63
65
|
catch { /* 忽略写失败 */ }
|
|
64
66
|
}
|
|
65
|
-
/**
|
|
67
|
+
/** wakeImpl 装配(防线②,2026-09-04 mtmgp81q 死法教训):wakeV 异常必须落盘 dispatcher.log——
|
|
68
|
+
* 原实现仅 console.error,无控制台运行时零痕迹(排障最大障碍)。吞异常是为防 withTimeout
|
|
69
|
+
* 超时后迟到的 rejection 变 unhandledRejection;onSettled(saveOrchs)无论成败都执行。 */
|
|
70
|
+
export function makeWakeImpl(wakeV, logFile, onSettled) {
|
|
71
|
+
return async (chainId) => {
|
|
72
|
+
try {
|
|
73
|
+
await wakeV(chainId);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
console.error('[dsh-swarm][debug] wakeV error chain=' + chainId + ': ' + String(err));
|
|
77
|
+
logToFile(logFile, '[wakeV] error chain=' + chainId + ': ' + String(err));
|
|
78
|
+
}
|
|
79
|
+
onSettled();
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** 单次异步操作加超时护栏——一个挂起的 V 编排会话不得卡死整个调度器 tick。 */
|
|
66
83
|
function withTimeout(p, ms, label) {
|
|
67
84
|
return Promise.race([
|
|
68
85
|
p,
|
|
69
86
|
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout: ' + label)), ms)),
|
|
70
87
|
]);
|
|
71
88
|
}
|
|
72
|
-
/**
|
|
73
|
-
|
|
89
|
+
/** 防线①:链级进度看门狗阈值。tick=2000ms × 45 ticks = 90s 无进展即重唤醒。 */
|
|
90
|
+
export const STALL_WATCHDOG_TICKS = 45;
|
|
91
|
+
/** 防线①:链级重唤醒上限(超限 [create-failed] + chain/blocked)。 */
|
|
92
|
+
export const STALL_WATCHDOG_REWAKE_LIMIT = 3;
|
|
93
|
+
/** 调度器:事件唤醒 V(逐阶段建卡)+ 每任务一次性角色 agent + 心跳看门狗。
|
|
94
|
+
* - failed 且 attempts<maxRetries 的任务重派(claim→running,AgentRunner resume 同一会话);
|
|
74
95
|
* attempts≥maxRetries 熔断 blocked(gave_up)。
|
|
75
|
-
* -
|
|
76
|
-
* -
|
|
96
|
+
* - lastSeq 持久化,重启后仅唤醒 lastSeq 之后的事件。
|
|
97
|
+
* - inFlight 互斥,防止慢 tick 与下一轮并发重复派发同一任务。 */
|
|
77
98
|
export class Dispatcher {
|
|
78
99
|
kanban;
|
|
79
100
|
runner;
|
|
@@ -82,8 +103,12 @@ export class Dispatcher {
|
|
|
82
103
|
maxRetries;
|
|
83
104
|
stateFile;
|
|
84
105
|
logFile;
|
|
106
|
+
agents; // 宿主 agents 注册表(热重载豁免判据)
|
|
107
|
+
stallProbe;
|
|
85
108
|
lastSeq = null; // null=尚未加载(首轮 tick 从状态文件/事件日志尾行恢复)
|
|
109
|
+
orphanReconciled = false; // 启动 reconcile 一次性闸:仅首轮 tick 执行孤儿收敛
|
|
86
110
|
inFlight = false;
|
|
111
|
+
stallState = new Map();
|
|
87
112
|
timer = null;
|
|
88
113
|
constructor(deps) {
|
|
89
114
|
this.kanban = deps.kanban;
|
|
@@ -93,23 +118,42 @@ export class Dispatcher {
|
|
|
93
118
|
this.maxRetries = deps.maxRetries;
|
|
94
119
|
this.stateFile = deps.stateFile;
|
|
95
120
|
this.logFile = deps.logFile;
|
|
121
|
+
this.agents = deps.agents;
|
|
122
|
+
this.stallProbe = deps.stallProbe;
|
|
96
123
|
}
|
|
97
124
|
async ensureLastSeq(state) {
|
|
98
125
|
if (this.lastSeq !== null)
|
|
99
126
|
return;
|
|
100
|
-
//
|
|
101
|
-
// chain/created / spec-card/approved 等可唤醒事件导致 V
|
|
102
|
-
// 重放安全:VOrchestrator.wakeV
|
|
103
|
-
|
|
127
|
+
// 无状态文件(首次启动)时从 -1 起处理全部事件,避免跳过已存在的
|
|
128
|
+
// chain/created / spec-card/approved 等可唤醒事件导致 V 永不建卡。
|
|
129
|
+
// 重放安全:VOrchestrator.wakeV 的幂等(已有匹配卡则跳过)保证不重复建卡。
|
|
130
|
+
let loaded = loadLastSeq(this.stateFile) ?? -1;
|
|
131
|
+
// 游标自愈:purge/renumber(整链硬删除物理重排 events.jsonl seq)或外部修复会把
|
|
132
|
+
// 新事件 seq 压到旧游标之下,若不钳回,spec-card/approved 等可唤醒事件将被永久
|
|
133
|
+
// 跳过 → V 永不建卡(2026-09-02 实测事故)。游标超前即视为状态文件失效,回退
|
|
134
|
+
// 全量重放;重复唤醒由 wakeV 幂等与 done 卡不可变兜底。
|
|
135
|
+
const maxSeq = state.events.length > 0 ? state.events[state.events.length - 1].seq : -1;
|
|
136
|
+
if (loaded > maxSeq) {
|
|
137
|
+
logToFile(this.logFile, '[tick] lastSeq=' + loaded + ' > maxSeq=' + maxSeq + ' (post-purge cursor skew) → rewind to -1 and replay');
|
|
138
|
+
loaded = -1;
|
|
139
|
+
}
|
|
140
|
+
this.lastSeq = loaded;
|
|
104
141
|
logToFile(this.logFile, '[tick] initial lastSeq=' + this.lastSeq);
|
|
105
142
|
}
|
|
106
143
|
async tick() {
|
|
107
144
|
if (this.inFlight)
|
|
108
|
-
return; //
|
|
145
|
+
return; // 防重叠 tick 并发派发同一任务
|
|
109
146
|
this.inFlight = true;
|
|
110
147
|
try {
|
|
111
148
|
const state = await this.kanban.snapshot();
|
|
112
149
|
await this.ensureLastSeq(state);
|
|
150
|
+
// 启动 reconcile:仅首轮执行,位置在游标自愈之后、正常事件消费之前——
|
|
151
|
+
// 游标 rewind 可能全量重放旧事件,必须先把上次进程遗留的 running 孤儿卡收敛为 blocked,
|
|
152
|
+
// 消除「进程重启 → whenIdle 协程死亡 → 卡 running 悬挂到看门狗 4h」的口子。
|
|
153
|
+
if (!this.orphanReconciled) {
|
|
154
|
+
this.orphanReconciled = true;
|
|
155
|
+
await reconcileOrphanRunningTasks(this.kanban, state.tasks.values(), this.logFile, this.agents);
|
|
156
|
+
}
|
|
113
157
|
let advanced = false;
|
|
114
158
|
for (const ev of state.events) {
|
|
115
159
|
if (ev.seq > this.lastSeq) {
|
|
@@ -132,15 +176,16 @@ export class Dispatcher {
|
|
|
132
176
|
await this.runner.runTask(t.id);
|
|
133
177
|
}
|
|
134
178
|
else if (t.status === 'failed' && t.attempts < this.maxRetries) {
|
|
135
|
-
//
|
|
179
|
+
// failed 重派——AgentRunner 内 claim→running + resume 同一会话
|
|
136
180
|
await this.runner.runTask(t.id);
|
|
137
181
|
}
|
|
138
182
|
else if (t.status === 'failed') {
|
|
139
|
-
//
|
|
183
|
+
// attempts≥maxRetries 熔断 blocked(gave_up),人工介入
|
|
140
184
|
await this.kanban.blockTask(t.id, 'gave_up: max retries', 'system');
|
|
141
185
|
}
|
|
142
186
|
}
|
|
143
187
|
await this.watchdog.tick();
|
|
188
|
+
await this.chainStallWatchdog(state);
|
|
144
189
|
}
|
|
145
190
|
catch (e) {
|
|
146
191
|
console.error('[dsh-swarm][debug] tick error: ' + String(e));
|
|
@@ -150,10 +195,103 @@ export class Dispatcher {
|
|
|
150
195
|
this.inFlight = false;
|
|
151
196
|
}
|
|
152
197
|
}
|
|
198
|
+
/** 防线①:链级进度看门狗(与 wakeVInner 内建 stall 互补,后者挂在 wakeVInner 内部,
|
|
199
|
+
* 异常退出/挂起/未触发时失效——2026-09-04 mtmgp81q)。只看最终事实:
|
|
200
|
+
* executing 非 summary + 链上零非终态任务卡 + 无在途唤醒 + 本链无新看板事件,
|
|
201
|
+
* 持续 STALL_WATCHDOG_TICKS 个 tick → 重唤醒(≤STALL_WATCHDOG_REWAKE_LIMIT 次)→
|
|
202
|
+
* 仍停滞 → [create-failed] 评论(有锚点卡时)+ blockChain 终态(人工恢复=删链重跑)。 */
|
|
203
|
+
async chainStallWatchdog(state) {
|
|
204
|
+
if (!this.stallProbe)
|
|
205
|
+
return;
|
|
206
|
+
for (const chain of state.chains.values()) {
|
|
207
|
+
if (chain.status !== 'executing') {
|
|
208
|
+
this.stallState.delete(chain.id);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const orch = this.stallProbe.orchestrationOf(chain.id);
|
|
212
|
+
if (!orch || orch.phase === 'summary') {
|
|
213
|
+
this.stallState.delete(chain.id);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const seen = this.stallState.get(chain.id) ?? { ticks: 0, rewakes: 0, lastSeq: -1 };
|
|
217
|
+
const set = () => this.stallState.set(chain.id, seen);
|
|
218
|
+
// 本链最新事件 seq:有新事件 = 链有活动(任何 kind,含评论/心跳)。
|
|
219
|
+
// 重置计数后不 continue:无新事件的首个观测 tick 即停滞计数起点(否则 45 tick 只累计 44,
|
|
220
|
+
// 与 brief 测试「STALL_WATCHDOG_TICKS 个 tick → 重唤醒」差一拍——实测 2026-09-04)。
|
|
221
|
+
let chainMaxSeq = -1;
|
|
222
|
+
for (let i = state.events.length - 1; i >= 0; i--) {
|
|
223
|
+
const e = state.events[i];
|
|
224
|
+
if (e.chainId === chain.id) {
|
|
225
|
+
chainMaxSeq = e.seq;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (chainMaxSeq > seen.lastSeq) {
|
|
230
|
+
seen.lastSeq = chainMaxSeq;
|
|
231
|
+
seen.ticks = 0;
|
|
232
|
+
set();
|
|
233
|
+
}
|
|
234
|
+
if (this.stallProbe.isWakeInFlight(chain.id)) {
|
|
235
|
+
seen.ticks = 0;
|
|
236
|
+
set();
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const chainTasks = [...state.tasks.values()].filter((t) => t.chainId === chain.id);
|
|
240
|
+
if (chainTasks.some((t) => t.status !== 'done' && t.status !== 'archived')) {
|
|
241
|
+
seen.ticks = 0;
|
|
242
|
+
set();
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
seen.ticks += 1;
|
|
246
|
+
if (seen.ticks < STALL_WATCHDOG_TICKS) {
|
|
247
|
+
set();
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (seen.rewakes < STALL_WATCHDOG_REWAKE_LIMIT) {
|
|
251
|
+
seen.rewakes += 1;
|
|
252
|
+
seen.ticks = 0;
|
|
253
|
+
set();
|
|
254
|
+
logToFile(this.logFile, `[stall-watchdog] zero-progress chain=${chain.id} phase=${orch.phase} → rewake ${seen.rewakes}/${STALL_WATCHDOG_REWAKE_LIMIT}`);
|
|
255
|
+
this.stallProbe.wake(chain.id).catch((err) => logToFile(this.logFile, '[stall-watchdog] wake failed chain=' + chain.id + ': ' + String(err)));
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
// 终态显形
|
|
259
|
+
const anchor = chainTasks.at(-1);
|
|
260
|
+
if (anchor) {
|
|
261
|
+
const already = state.events.some((e) => e.taskId === anchor.id && e.kind === 'task/commented' && String(e.payload['body'] ?? '').startsWith('[create-failed]'));
|
|
262
|
+
if (!already) {
|
|
263
|
+
try {
|
|
264
|
+
await this.kanban.comment(anchor.id, `[create-failed] 看门狗:链持续无进展且自动重唤醒 ${STALL_WATCHDOG_REWAKE_LIMIT} 次未建卡(phase=${orch.phase}),已置 blocked,请人工处理。`, 'system');
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
logToFile(this.logFile, '[stall-watchdog] comment failed chain=' + chain.id + ': ' + String(err));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
await this.kanban.blockChain(chain.id, `[stall-watchdog] phase=${orch.phase} 持续无进展,重唤醒 ${STALL_WATCHDOG_REWAKE_LIMIT} 次未建卡`);
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
logToFile(this.logFile, '[stall-watchdog] blockChain failed chain=' + chain.id + ': ' + String(err));
|
|
276
|
+
}
|
|
277
|
+
logToFile(this.logFile, `[stall-watchdog] chain=${chain.id} → blocked`);
|
|
278
|
+
this.stallState.delete(chain.id);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
153
281
|
start(intervalMs) {
|
|
154
282
|
this.stop();
|
|
155
283
|
this.timer = setInterval(() => { void this.tick(); }, intervalMs);
|
|
156
284
|
}
|
|
285
|
+
/** 整链硬删除联动:purge 物理重排 events.jsonl seq,游标必须同步钳到当前 maxSeq。
|
|
286
|
+
* 否则删链后新建链的可唤醒事件(seq < 旧内存游标)被运行中实例永久跳过——启动时自愈,
|
|
287
|
+
* 覆盖不了运行中删链场景(2026-09-02 残留审计结论)。 */
|
|
288
|
+
async onPurge() {
|
|
289
|
+
const state = await this.kanban.snapshot();
|
|
290
|
+
const maxSeq = state.events.length > 0 ? state.events[state.events.length - 1].seq : -1;
|
|
291
|
+
this.lastSeq = maxSeq;
|
|
292
|
+
saveLastSeq(this.stateFile, maxSeq);
|
|
293
|
+
logToFile(this.logFile, '[onPurge] cursor synced to maxSeq=' + maxSeq);
|
|
294
|
+
}
|
|
157
295
|
stop() {
|
|
158
296
|
if (this.timer) {
|
|
159
297
|
clearInterval(this.timer);
|
|
@@ -161,10 +299,71 @@ export class Dispatcher {
|
|
|
161
299
|
}
|
|
162
300
|
}
|
|
163
301
|
}
|
|
164
|
-
/** 调度层装配:事件唤醒 V
|
|
165
|
-
* 仅在 agents 与 kanban 服务同时可用时由插件入口调用(不依赖可能已错过的 ready 事件)。
|
|
166
|
-
|
|
167
|
-
|
|
302
|
+
/** 调度层装配:事件唤醒 V(逐阶段建卡)+ 每任务一次性角色 agent + 心跳看门狗。
|
|
303
|
+
* 仅在 agents 与 kanban 服务同时可用时由插件入口调用(不依赖可能已错过的 ready 事件)。
|
|
304
|
+
* 收 ConfigProvider——storageDir 取启动时快照;wiki/模型链经 getEffective() 调用时热读取。 */
|
|
305
|
+
/** 启动 reconcile:剔除事件流中已不存在的链的编排 entry(历史残留/外部 purge)。
|
|
306
|
+
* 原地删除并返回被移除的 chainId 列表(调用方负责持久化与日志)。 */
|
|
307
|
+
export function reconcileOrchestrations(orch, chains) {
|
|
308
|
+
const removed = [...orch.keys()].filter((k) => !chains.has(k));
|
|
309
|
+
for (const k of removed)
|
|
310
|
+
orch.delete(k);
|
|
311
|
+
return removed;
|
|
312
|
+
}
|
|
313
|
+
/** 启动 reconcile:进程重启会杀死 runner 的 whenIdle 协程,上次遗留的 running 卡无人收尾,
|
|
314
|
+
* 看门狗默认 4h(staleTimeoutSeconds=14400)才回收——重启后立即把 running 孤儿卡收敛为 blocked
|
|
315
|
+
* (system comment + blockTask),中断显形且可重派续跑(重派将 resume 同一会话,进度保留)。
|
|
316
|
+
* 状态机注:TaskStatus 无独立 'claimed' 态——claimTask 发 task/claimed 事件后投影即为 running,
|
|
317
|
+
* 扫描 running 即覆盖「claimed 未收尾」;todo/ready/triage 从未派发,done/blocked/failed/archived
|
|
318
|
+
* 已有归属或终态(且 failed 的处置归重派/熔断管辖),均不动。
|
|
319
|
+
* 热重载兼容,双重判据:收敛每张 running 卡前先查宿主 agents 注册表
|
|
320
|
+
* ctx.get('agents').get('kbn-<taskId>')(session id 构造同 AgentRunner.resumeOrReuse)。
|
|
321
|
+
* 两个世界的分野:
|
|
322
|
+
* - 进程重启:agents 注册表随宿主进程消亡,新进程内 kbn-<taskId> 必然查不到(undefined)
|
|
323
|
+
* → 会话已死 → 全部收敛,语义与修复前一致;
|
|
324
|
+
* - 插件热重载:宿主进程未死,dsh 插件重载重跑 startDispatcherInner → orphanReconciled 闸复位,
|
|
325
|
+
* 但宿主 agent 会话仍 live(注册表命中)→ 本进程真在跑,不是孤儿 → 跳过该卡,
|
|
326
|
+
* 避免把合法 running 卡误收敛为 blocked。
|
|
327
|
+
* agents 服务缺失 / 无 get 方法(测试桩/异常宿主)→ 无法证明 live,按原行为收敛(保守)。
|
|
328
|
+
* 调用位置必须在游标自愈(ensureLastSeq)之后、事件消费之前:游标 rewind 会全量重放旧事件,
|
|
329
|
+
* 先收敛孤儿可保证本次 tick 消费的重放事件面对的是已收敛状态,且孤儿产生的 block 事件天然
|
|
330
|
+
* 落在本轮快照之外(下一轮才被消费唤醒 V 走阻塞复核),不与启动重放交错。
|
|
331
|
+
* 幂等:仅启动执行一次(调用方置闸);对同一卡重复调用时状态机拒绝 running→blocked 之外的
|
|
332
|
+
* 非法转换,comment/block 失败均 try/catch 记日志跳过不抛(单卡失败不阻断其余收敛)。 */
|
|
333
|
+
export async function reconcileOrphanRunningTasks(kanban, tasks, logFile, agents) {
|
|
334
|
+
const orphans = [...tasks].filter((t) => t.status === 'running');
|
|
335
|
+
const agentsSvc = agents;
|
|
336
|
+
const handled = [];
|
|
337
|
+
for (const t of orphans) {
|
|
338
|
+
const live = typeof agentsSvc?.get === 'function' ? agentsSvc.get('kbn-' + t.id) : undefined;
|
|
339
|
+
if (live) {
|
|
340
|
+
// 宿主注册表命中 → 会话仍 live(热重载世界),本进程真在跑,跳过不收敛
|
|
341
|
+
logToFile(logFile, '[orphan-reconcile] skip live session task=' + t.id + ' (host reload, session alive)');
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
await kanban.comment(t.id, '[runner-interrupted] dsh 重启中断会话,置为阻塞以便重派续跑(进度保留,重派将 resume 同会话)', 'system');
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
// comment 无状态语义且恒放行,失败仅可能是存储层异常——记日志后仍继续 block
|
|
349
|
+
logToFile(logFile, '[orphan-reconcile] comment failed task=' + t.id + ': ' + String(err));
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
await kanban.blockTask(t.id, 'runner-interrupted: 进程重启,会话中断', 'system');
|
|
353
|
+
handled.push(t.id);
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
// 防御:状态机拒绝(卡恰被并发流转/已收敛)→ 记日志跳过,不抛
|
|
357
|
+
logToFile(logFile, '[orphan-reconcile] block failed task=' + t.id + ': ' + String(err));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (handled.length > 0) {
|
|
361
|
+
logToFile(logFile, '[orphan-reconcile] reconciled orphan running tasks: ' + handled.join(','));
|
|
362
|
+
}
|
|
363
|
+
return handled;
|
|
364
|
+
}
|
|
365
|
+
export function startDispatcher(ctx, configProvider) {
|
|
366
|
+
const storageDir = configProvider.getEffective().storageDir.replace('$DSH_HOME', process.env.DSH_HOME ?? process.cwd());
|
|
168
367
|
const logFile = join(storageDir, 'dispatcher.log');
|
|
169
368
|
const provider = ctx.get('kanban');
|
|
170
369
|
const agents = ctx.get('agents');
|
|
@@ -174,17 +373,24 @@ export function startDispatcher(ctx, config) {
|
|
|
174
373
|
return;
|
|
175
374
|
}
|
|
176
375
|
try {
|
|
177
|
-
startDispatcherInner(ctx,
|
|
376
|
+
startDispatcherInner(ctx, configProvider, storageDir, logFile, provider, agents);
|
|
178
377
|
}
|
|
179
378
|
catch (err) {
|
|
180
379
|
logToFile(logFile, '[startDispatcher] FAILED: ' + String(err));
|
|
181
380
|
console.error('[dsh-swarm][debug] startDispatcher failed: ' + String(err));
|
|
182
381
|
}
|
|
183
382
|
}
|
|
184
|
-
/** 调度器装配主体(startDispatcher 的容错包裹内执行,异常落盘不阻断插件加载)。
|
|
185
|
-
|
|
383
|
+
/** 调度器装配主体(startDispatcher 的容错包裹内执行,异常落盘不阻断插件加载)。
|
|
384
|
+
* config = 启动时快照,仅喂静态依赖(EventWaker/Watchdog/maxRetries);
|
|
385
|
+
* wiki 与模型链读点走 configProvider.getEffective() 热生效。 */
|
|
386
|
+
function startDispatcherInner(ctx, configProvider, storageDir, logFile, provider, agents) {
|
|
387
|
+
const config = configProvider.getEffective();
|
|
186
388
|
const kanban = provider.service;
|
|
187
|
-
|
|
389
|
+
// 双模式:local 走 LocalWikiClient(互链读写落本地库),remote 用配置的 WikiVaultClient(同款分支)。
|
|
390
|
+
// 消费方(AgentRunner/VOrchestrator)字段仍标 WikiVaultClient——local 为 LocalWikiClient(read/write/search 同面),同款断言。
|
|
391
|
+
const wiki = (configProvider.mode === 'local'
|
|
392
|
+
? new LocalWikiClient(ensureLocalKbRoot())
|
|
393
|
+
: new WikiVaultClient(() => configProvider.getEffective().wikiVault));
|
|
188
394
|
const defaultModel = resolveDefaultModel(ctx);
|
|
189
395
|
console.info('[dsh-swarm] role default model = ' + (defaultModel ? defaultModel.provider + '/' + defaultModel.model : 'none'));
|
|
190
396
|
const orchFile = join(storageDir, 'orchestration.json');
|
|
@@ -201,8 +407,8 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
201
407
|
}
|
|
202
408
|
catch { /* 忽略写失败 */ }
|
|
203
409
|
};
|
|
204
|
-
const vOrch = new VOrchestrator(ctx, kanban, agents,
|
|
205
|
-
//
|
|
410
|
+
const vOrch = new VOrchestrator(ctx, kanban, agents, configProvider, orchestrations, wiki, defaultModel);
|
|
411
|
+
// 链完成验收核对——Chain(completed) 时核对主会话是否越权写工作区产物;
|
|
206
412
|
// 发现越权 → chain/audit-warning,阻塞最终汇报直至用户 GUI 确认(chain/audit-confirmed)。
|
|
207
413
|
const auditor = new ChainAuditor({
|
|
208
414
|
kanban,
|
|
@@ -210,7 +416,7 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
210
416
|
listLiveAgents: () => (ctx.get('agents')?.list?.() ?? []),
|
|
211
417
|
});
|
|
212
418
|
kanban.setOnChainCompleted(async (chainId) => {
|
|
213
|
-
//
|
|
419
|
+
// 传入本链发起工作区(Chain.workspaceDir),审计仅扫描该工作区内的会话,排除其他项目主会话
|
|
214
420
|
const chainState = await kanban.snapshot();
|
|
215
421
|
const workspaceDir = chainState.chains.get(chainId)?.workspaceDir ?? null;
|
|
216
422
|
const evidence = await auditor.check(chainId, workspaceDir);
|
|
@@ -218,7 +424,7 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
218
424
|
console.warn('[dsh-swarm] chain audit warning: ' + chainId + ' evidence=' + evidence.length);
|
|
219
425
|
await kanban.auditWarning(chainId, evidence, 'system');
|
|
220
426
|
}
|
|
221
|
-
//
|
|
427
|
+
// 合入门控:DT 通过后由 system 合入 TARGET_BRANCH;D 不再提前 merge/push。
|
|
222
428
|
// 解析失败软跳过([merge-skip]),合入失败记录 [merge-failed],均不阻断收尾(坏代码未被合入 = 方向安全)。
|
|
223
429
|
try {
|
|
224
430
|
const r = await mergeDAfterReview(kanban, chainId, storageDir);
|
|
@@ -230,7 +436,7 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
230
436
|
logToFile(logFile, '[merge-gate] error chain=' + chainId + ' ' + String(err));
|
|
231
437
|
}
|
|
232
438
|
});
|
|
233
|
-
//
|
|
439
|
+
// W2/W3(w:kb) 完成 → 机械互链登记(清单页 ↔ 计划页 ↔ 结果页)。
|
|
234
440
|
// syncKbLinks 内部对 wiki 读写全容错,失败不阻塞完成;钩子本身再包一层 try(防御未来改动抛错)。
|
|
235
441
|
kanban.setOnTaskCompleted(async (taskId) => {
|
|
236
442
|
try {
|
|
@@ -242,16 +448,9 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
242
448
|
}
|
|
243
449
|
});
|
|
244
450
|
const waker = new EventWaker(ctx, config);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
catch (err) {
|
|
250
|
-
console.error('[dsh-swarm][debug] wakeV error chain=' + chainId + ': ' + String(err));
|
|
251
|
-
}
|
|
252
|
-
saveOrchs();
|
|
253
|
-
});
|
|
254
|
-
// 0.1.0 delegation(spec FR2):全局子代理写护栏——普通插件 ctx 上注册的 guard 全局
|
|
451
|
+
vOrch.onOrchChange = saveOrchs; // stall re-wake 路径绕过 EventWaker,orch 变化自行落盘
|
|
452
|
+
waker.setWakeImpl(makeWakeImpl(vOrch.wakeV.bind(vOrch), logFile, saveOrchs));
|
|
453
|
+
// 0.1.0 delegation:全局子代理写护栏——普通插件 ctx 上注册的 guard 全局
|
|
255
454
|
// 生效(dsh-tools:普通上下文守卫全局生效,agent.ctx 守卫仅对该 agent 生效)。
|
|
256
455
|
// guard 内部仅对 kanban-dt 系会话收紧;DT 父会话自身仍由 agent-runner 的 agent.ctx
|
|
257
456
|
// guard 双保险。dispose 时注销。
|
|
@@ -260,8 +459,24 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
260
459
|
if (unguardSubagents) {
|
|
261
460
|
ctx.on('dispose', unguardSubagents);
|
|
262
461
|
}
|
|
263
|
-
|
|
264
|
-
|
|
462
|
+
// 蜂群模式硬闸:header.agentPreset==='swarm' 时只读+git 反选拦截;
|
|
463
|
+
// 内部对其余会话恒放行。dispose 时注销(与 subagent guard 同款)。
|
|
464
|
+
const unguardSwarm = toolsSvc?.guard?.(buildSwarmSessionGuard());
|
|
465
|
+
if (unguardSwarm) {
|
|
466
|
+
ctx.on('dispose', unguardSwarm);
|
|
467
|
+
}
|
|
468
|
+
// 独立评审硬闸:header.agentPreset==='kanban-dt' 且未经角色组合(session id 非 kbn-
|
|
469
|
+
// 前缀)时收紧(看板写工具拒、bash/run_code 仅只读 git+clone/fetch、wiki_write 仅
|
|
470
|
+
// reviews 命名空间);wiki_write 对非评审会话全局收紧(链上组合会话放行)。dispose
|
|
471
|
+
// 时注销(与 subagent/swarm guard 同款)。
|
|
472
|
+
const unguardStandalone = toolsSvc?.guard?.(buildStandaloneDtGuard());
|
|
473
|
+
if (unguardStandalone) {
|
|
474
|
+
ctx.on('dispose', unguardStandalone);
|
|
475
|
+
}
|
|
476
|
+
// 独立评审工具全局注册:ocr_review + wiki 三原语(wiki_write 会话级收紧由上 guard 完成)。
|
|
477
|
+
registerStandaloneReviewerTools(ctx, configProvider);
|
|
478
|
+
const runner = new AgentRunner(ctx, kanban, configProvider, wiki, defaultModel);
|
|
479
|
+
provider.runner = runner; // HTTP retry 复用同一执行器(failed→claim→spawn/resume)
|
|
265
480
|
const watchdog = new Watchdog(kanban, config.dispatcher);
|
|
266
481
|
const dispatcher = new Dispatcher({
|
|
267
482
|
kanban,
|
|
@@ -269,12 +484,36 @@ function startDispatcherInner(ctx, config, storageDir, logFile, provider, agents
|
|
|
269
484
|
waker,
|
|
270
485
|
watchdog,
|
|
271
486
|
maxRetries: config.dispatcher.maxRetries,
|
|
272
|
-
stateFile: join(dirname(orchFile), 'dispatcher-state.json'), //
|
|
487
|
+
stateFile: join(dirname(orchFile), 'dispatcher-state.json'), // 与事件日志同目录
|
|
273
488
|
logFile,
|
|
489
|
+
agents, // 启动 reconcile 热重载豁免判据(宿主 agents 注册表)
|
|
490
|
+
stallProbe: vOrch, // 防线①:链级停滞探针(orchestrationOf/isWakeInFlight/wake)
|
|
274
491
|
});
|
|
275
|
-
ctx.on('dispose', () => { dispatcher.stop(); watchdog.stop(); });
|
|
492
|
+
ctx.on('dispose', () => { dispatcher.stop(); watchdog.stop(); vOrch.dispose(); });
|
|
276
493
|
dispatcher.start(2000);
|
|
277
494
|
watchdog.start(config.dispatcher.heartbeatIntervalSeconds * 1000);
|
|
278
495
|
logToFile(logFile, '[startDispatcher] dispatcher started (tick=2000ms)');
|
|
279
496
|
void dispatcher.tick();
|
|
497
|
+
// 整链硬删除联动:purge 物理重排事件 seq → 游标同步钳回(运行中实例不重启发跳过);
|
|
498
|
+
// V 编排 entry 同步剔除。kanban-http 的 delete 分支调用 provider.onChainDeleted。
|
|
499
|
+
provider.onChainDeleted = async (chainId) => {
|
|
500
|
+
await dispatcher.onPurge();
|
|
501
|
+
orchestrations.delete(chainId);
|
|
502
|
+
saveOrchs();
|
|
503
|
+
logToFile(logFile, '[chain-deleted] cursor synced + orch entry removed chain=' + chainId);
|
|
504
|
+
};
|
|
505
|
+
// 启动 reconcile:历史残留/外部 purge 留下的死链编排 entry,按事件流存活链剔除
|
|
506
|
+
void (async () => {
|
|
507
|
+
try {
|
|
508
|
+
const snap = await kanban.snapshot();
|
|
509
|
+
const removed = reconcileOrchestrations(orchestrations, new Set(snap.chains.keys()));
|
|
510
|
+
if (removed.length > 0) {
|
|
511
|
+
saveOrchs();
|
|
512
|
+
logToFile(logFile, '[orch-reconcile] removed dead entries: ' + removed.join(','));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
catch (err) {
|
|
516
|
+
logToFile(logFile, '[orch-reconcile] failed: ' + String(err));
|
|
517
|
+
}
|
|
518
|
+
})();
|
|
280
519
|
}
|
|
@@ -6,7 +6,7 @@ export declare class EventWaker {
|
|
|
6
6
|
private inFlight;
|
|
7
7
|
private wakeImpl;
|
|
8
8
|
constructor(_ctx: unknown, _config: KanbanConfig);
|
|
9
|
-
/** 注入真实唤醒实现(
|
|
9
|
+
/** 注入真实唤醒实现(VOrchestrator.wakeV——创建/恢复 V 编排 agent 会话,按阶段序列建卡)。 */
|
|
10
10
|
setWakeImpl(impl: WakeImpl): void;
|
|
11
11
|
onEvent(ev: KanbanEvent): Promise<void>;
|
|
12
12
|
}
|
|
@@ -3,10 +3,10 @@ export class EventWaker {
|
|
|
3
3
|
inFlight = new Set();
|
|
4
4
|
wakeImpl = async () => { };
|
|
5
5
|
constructor(_ctx, _config) { }
|
|
6
|
-
/** 注入真实唤醒实现(
|
|
6
|
+
/** 注入真实唤醒实现(VOrchestrator.wakeV——创建/恢复 V 编排 agent 会话,按阶段序列建卡)。 */
|
|
7
7
|
setWakeImpl(impl) { this.wakeImpl = impl; }
|
|
8
8
|
async onEvent(ev) {
|
|
9
|
-
//
|
|
9
|
+
// V 仅在规格卡批准后(spec-card/approved)或任务完成/阻塞(驱动阶段推进)时唤醒;
|
|
10
10
|
// chain/created 不再唤醒 V(V 不再处理旧 w1 预取阶段,等 /openspec: 建卡 + 批准后再行动)。
|
|
11
11
|
const wakeable = (ev.kind === 'task/completed' || ev.kind === 'task/blocked' || ev.kind === 'spec-card/approved');
|
|
12
12
|
if (!wakeable)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* D(execute) git 凭据注入:使 D 会话的 git ls-remote/push 可用。
|
|
3
3
|
*
|
|
4
4
|
* 机制:D 会话的 bash 每次调用都是新 shell(无环境持久),故 env 变量不可跨调用。
|
|
5
5
|
* 采用 repo-local http extraheader(AUTHORIZATION: basic),写入 <repo>/.git/config——
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* 鉴权按托管方区分:
|
|
9
9
|
* - GitLab PAT(glpat- 前缀)→ basic base64("oauth2:<PAT>")(GitLab 规范,实测 ls-remote 通过);
|
|
10
10
|
* - 其余(GitHub 等)→ basic base64("x-access-token:<PAT>")。
|
|
11
|
-
* D 会话为 danger-full-access
|
|
11
|
+
* D 会话为 danger-full-access(用户决策),HOME 可写,故 git 的 credential.helper
|
|
12
12
|
* (store/osxkeychain 等)不再触发 "credential storage lock",无需中和。
|
|
13
13
|
*
|
|
14
14
|
* PAT 来源(按优先级):DSH 凭据服务 ctx.credentials($DSH_HOME/.credentials.yaml 的
|