@sanqianx/project-knowledge 5.0.24 → 5.0.25
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/.agents/plugins/marketplace.json +20 -20
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +1361 -1353
- package/LICENSE +201 -201
- package/NOTICE +5 -5
- package/README.md +349 -349
- package/_modules/knowledge-engine/package.json +1 -1
- package/_modules/knowledge-engine/src/coordinator.js +48 -3
- package/_modules/knowledge-engine/src/runtime/automation-config.js +140 -140
- package/_modules/knowledge-engine/src/runtime/commit-conversation-binder.js +238 -238
- package/_modules/knowledge-engine/src/runtime/commit-processing-ledger.js +26 -26
- package/_modules/knowledge-engine/src/runtime/commit-prompt.js +193 -193
- package/_modules/knowledge-engine/src/runtime/commit-reconciler.js +394 -394
- package/_modules/knowledge-engine/src/runtime/contracts.js +282 -282
- package/_modules/knowledge-engine/src/runtime/conversation-store.js +389 -389
- package/_modules/knowledge-engine/src/runtime/evidence-bundle.js +228 -228
- package/_modules/knowledge-engine/src/runtime/git-runner.js +62 -62
- package/_modules/knowledge-engine/src/runtime/knowledge-promotion.js +505 -505
- package/_modules/knowledge-engine/src/runtime/knowledge-retrieval-service.js +400 -400
- package/_modules/knowledge-engine/src/runtime/markdown-knowledge-indexer.js +171 -171
- package/_modules/knowledge-engine/src/runtime/scanner.js +298 -298
- package/_modules/knowledge-engine/ui/app.js +23 -2
- package/_site/README.md +30 -30
- package/_site/_test/agent-capture-mcp-ui-test.js +68 -68
- package/_site/_test/agent-capture-ui-test.js +101 -101
- package/_site/_test/ai-profile-resolver-test.js +137 -137
- package/_site/_test/ai-profile-test.js +75 -75
- package/_site/_test/ai-vendor-presets-test.js +91 -91
- package/_site/_test/automatic-context-test.js +70 -70
- package/_site/_test/automation-queue-test.js +14 -14
- package/_site/_test/automation-ui-test.js +40 -40
- package/_site/_test/background-task-registry-test.js +43 -43
- package/_site/_test/baseline-schema-test.js +91 -91
- package/_site/_test/bin-cli-test.js +230 -230
- package/_site/_test/bridge-adapter-test.js +95 -95
- package/_site/_test/bridge-consumer-service-test.js +310 -310
- package/_site/_test/candidate-bin-content-test.js +35 -35
- package/_site/_test/candidate-product-assets-test.js +13 -13
- package/_site/_test/candidate-release-contract-test.js +14 -14
- package/_site/_test/capture-hook-dedup-test.js +158 -158
- package/_site/_test/cdp-browser-failure-test.js +103 -103
- package/_site/_test/chat-claudecodeui-match-test.js +92 -92
- package/_site/_test/claude-executable-discovery-test.js +90 -90
- package/_site/_test/claude-session-lifecycle-sweep-test.js +252 -252
- package/_site/_test/claude-workbench-test.js +174 -174
- package/_site/_test/cli-instance-management-test.js +62 -62
- package/_site/_test/client-capture-restart-e2e-test.js +189 -189
- package/_site/_test/codex-conversation-projection-test.js +60 -60
- package/_site/_test/codex-marketplace-scoped-path-test.js +186 -186
- package/_site/_test/codex-notify-capture-e2e-test.js +101 -101
- package/_site/_test/codex-notify-fanout-test.js +141 -134
- package/_site/_test/codex-notify-upgrade-test.js +253 -253
- package/_site/_test/commit-boundary-freeze-test.js +147 -147
- package/_site/_test/commit-conversation-binding-test.js +99 -99
- package/_site/_test/commit-evidence-test.js +110 -110
- package/_site/_test/configuration-generation-test.js +22 -22
- package/_site/_test/context-pack-test.js +200 -200
- package/_site/_test/conversation-api-test.js +119 -119
- package/_site/_test/conversation-origin-test.js +15 -15
- package/_site/_test/conversation-store-test.js +138 -138
- package/_site/_test/cross-repo-isolation-e2e-test.js +187 -187
- package/_site/_test/desktop-browser-compat-test.js +28 -28
- package/_site/_test/desktop-hook-runtime-regression-test.js +204 -204
- package/_site/_test/embedding-config-test.js +32 -32
- package/_site/_test/explicit-commit-processor-test.js +37 -37
- package/_site/_test/fixtures/fake-browser-exit.js +10 -10
- package/_site/_test/fixtures/fake-browser-hang.js +10 -10
- package/_site/_test/fixtures/integration-busy-worker.cjs +6 -6
- package/_site/_test/fixtures/make-git-repos.js +92 -92
- package/_site/_test/fixtures/retrieval-gold-queries.json +32 -32
- package/_site/_test/folder-picker-output-test.js +19 -19
- package/_site/_test/fresh-hook-reimport-test.js +53 -53
- package/_site/_test/fresh-product-data-test.js +56 -56
- package/_site/_test/full-integration-e2e-test.js +167 -167
- package/_site/_test/git-path-compatibility-test.js +80 -80
- package/_site/_test/git-validation-test.js +81 -81
- package/_site/_test/glm-ui-refresh-review-test.js +313 -404
- package/_site/_test/harness-isolation-test.js +138 -0
- package/_site/_test/helpers/cdp-browser.js +383 -0
- package/_site/_test/helpers/cdp-network-capture.js +66 -0
- package/_site/_test/helpers/find-chrome.js +34 -0
- package/_site/_test/helpers/free-port.js +8 -0
- package/_site/_test/helpers/logging-ui-fixture.js +131 -0
- package/_site/_test/helpers/module-fixture.js +282 -0
- package/_site/_test/helpers/parallel-engine-advanced-engine-child.js +45 -0
- package/_site/_test/helpers/parallel-engine-advanced-fault-writer.js +171 -0
- package/_site/_test/helpers/parallel-engine-advanced-harness.js +245 -0
- package/_site/_test/helpers/parallel-engine-advanced-standin-analyzer.js +80 -0
- package/_site/_test/helpers/parallel-engine-advanced-ui-host.js +177 -0
- package/_site/_test/helpers/parallel-engine-final-harness.js +314 -0
- package/_site/_test/helpers/parallel-engine-final-standin-analyzer.js +159 -0
- package/_site/_test/helpers/parallel-knowledge-fixture.js +255 -0
- package/_site/_test/helpers/parallel-logging-acceptance-fixture.js +111 -0
- package/_site/_test/helpers/parallel-logging-acceptance-proxy.js +106 -0
- package/_site/_test/helpers/parallel-logging-fix-r2-proxy.js +205 -0
- package/_site/_test/helpers/parallel-logging-integration-5025-env.js +432 -0
- package/_site/_test/helpers/parallel-memory-analyzer.js +81 -0
- package/_site/_test/helpers/parallel-memory-event-bridge.js +128 -0
- package/_site/_test/helpers/parallel-memory-shell.js +470 -0
- package/_site/_test/helpers/parallel-nav-isolation-env.js +389 -0
- package/_site/_test/helpers/parallel-nav-module-ui.js +186 -0
- package/_site/_test/helpers/parallel-nav-proxy.js +148 -0
- package/_site/_test/helpers/parallel-nav-shell.js +361 -0
- package/_site/_test/helpers/parallel-qa-engine-endpoint-guard.js +206 -0
- package/_site/_test/helpers/parallel-qa-engine-endpoint-isolate.js +257 -0
- package/_site/_test/helpers/parallel-retrieval-followup-corpus.js +293 -0
- package/_site/_test/helpers/parallel-retrieval-followup-next-session.js +70 -0
- package/_site/_test/helpers/parallel-retrieval-followup-r2-shell.js +737 -0
- package/_site/_test/helpers/parallel-retrieval-followup-r2-wb-host.js +82 -0
- package/_site/_test/helpers/parallel-retrieval-followup-shell.js +279 -0
- package/_site/_test/helpers/parallel-workbench-fixture.js +371 -0
- package/_site/_test/helpers/parallel-workbench-host.js +80 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-fixture.js +408 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-harness.js +593 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-host.js +70 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-launcher.js +240 -0
- package/_site/_test/helpers/parallel-workbench-integration-5025-runtime-harness.js +630 -0
- package/_site/_test/helpers/parallel-workbench-source-map.js +196 -0
- package/_site/_test/helpers/spawn-server.js +106 -0
- package/_site/_test/helpers/version-visibility-fixture.js +251 -0
- package/_site/_test/hook-runtime-endpoint-test.js +88 -88
- package/_site/_test/hook-status-repair-api-test.js +152 -152
- package/_site/_test/hook-trigger-test.js +85 -85
- package/_site/_test/hook-worktree-test.js +42 -42
- package/_site/_test/import-preflight-api-test.js +234 -234
- package/_site/_test/index-builder-test.js +41 -41
- package/_site/_test/index-error-display-contract-test.js +10 -10
- package/_site/_test/index-writer-concurrency-test.js +135 -135
- package/_site/_test/integration-adapters-test.js +262 -262
- package/_site/_test/integration-auto-repair-test.js +113 -113
- package/_site/_test/integration-capture-setup-test.js +118 -118
- package/_site/_test/integration-intent-test.js +81 -81
- package/_site/_test/integration-runtime-binding-a2-test.js +566 -566
- package/_site/_test/integration-runtime-binding-a3-test.js +227 -227
- package/_site/_test/integration-runtime-binding-test.js +473 -473
- package/_site/_test/integration-status-scan-test.js +29 -29
- package/_site/_test/integration-surface-coverage-test.js +164 -164
- package/_site/_test/kb-framework-test.js +57 -57
- package/_site/_test/kbpath-follow-test.js +63 -63
- package/_site/_test/knowledge-db-test.js +144 -144
- package/_site/_test/knowledge-engine-client-test.js +120 -109
- package/_site/_test/knowledge-language-control-test.js +170 -170
- package/_site/_test/knowledge-maintenance-test.js +40 -40
- package/_site/_test/knowledge-promotion-recovery-test.js +260 -260
- package/_site/_test/knowledge-query-test.js +54 -54
- package/_site/_test/knowledge-retrieval-service-test.js +77 -77
- package/_site/_test/knowledge-scopes-test.js +37 -37
- package/_site/_test/knowledge-storage-location-test.js +28 -28
- package/_site/_test/knowledge-storage-startup-test.js +52 -52
- package/_site/_test/knowledge-store-logs-supervision-test.js +89 -89
- package/_site/_test/launcher-readiness-test.js +80 -80
- package/_site/_test/legacy-claude-session-alias-test.js +106 -106
- package/_site/_test/legacy-routes-removed-test.js +47 -47
- package/_site/_test/legacy-workbench-exclusion-test.js +92 -92
- package/_site/_test/live-gateway-test.js +48 -48
- package/_site/_test/local-marketplace-test.js +16 -16
- package/_site/_test/log-redaction-test.js +58 -58
- package/_site/_test/logging-api-test.js +89 -89
- package/_site/_test/logging-sse-no-gap-test.js +88 -88
- package/_site/_test/logging-ui-test.js +107 -107
- package/_site/_test/markdown-delta-overlay-test.js +85 -85
- package/_site/_test/markdown-maintenance-api-test.js +75 -75
- package/_site/_test/markdown-maintenance-test.js +11 -11
- package/_site/_test/mcp-server-test.js +149 -149
- package/_site/_test/model-context-windows-test.js +89 -89
- package/_site/_test/module-agent-start-proxy-test.js +65 -65
- package/_site/_test/module-artifact-integrity-test.js +27 -27
- package/_site/_test/module-boundary-test.js +30 -30
- package/_site/_test/module-bridge-eventbridge-test.js +202 -202
- package/_site/_test/module-dynamic-port-test.js +118 -118
- package/_site/_test/module-index-proxy-test.js +33 -33
- package/_site/_test/module-model-configuration-test.js +44 -44
- package/_site/_test/module-process-lifecycle-test.js +35 -35
- package/_site/_test/module-stream-proxy-test.js +34 -34
- package/_site/_test/module-terminal-restart-test.js +63 -63
- package/_site/_test/module-wiring-unbind-race-test.js +59 -59
- package/_site/_test/native-context-integrations-test.js +86 -86
- package/_site/_test/non-release-ci-test.js +34 -34
- package/_site/_test/offline-boundary-isolation-test.js +32 -32
- package/_site/_test/orphaned-claim-recovery-test.js +80 -80
- package/_site/_test/package-boundary-test.js +43 -43
- package/_site/_test/package-startup-test.js +56 -56
- package/_site/_test/packaged-ui-smoke-test.js +88 -88
- package/_site/_test/parallel-ci-r9-posix-socket-budget-test.js +156 -0
- package/_site/_test/parallel-engine-advanced-eng005-test.js +136 -0
- package/_site/_test/parallel-engine-advanced-eng006-test.js +171 -0
- package/_site/_test/parallel-engine-advanced-eng007-reconcile-test.js +231 -0
- package/_site/_test/parallel-engine-advanced-eng009-test.js +208 -0
- package/_site/_test/parallel-engine-advanced-eng010-test.js +213 -0
- package/_site/_test/parallel-engine-advanced-eng011-ui-probe.js +459 -0
- package/_site/_test/parallel-engine-final-eng002-test.js +255 -0
- package/_site/_test/parallel-engine-final-eng007-test.js +269 -0
- package/_site/_test/parallel-engine-final-eng011-test.js +197 -0
- package/_site/_test/parallel-engine-final-eng012-test.js +354 -0
- package/_site/_test/parallel-knowledge-client-error-code-test.js +184 -0
- package/_site/_test/parallel-knowledge-engine-test.js +353 -0
- package/_site/_test/parallel-knowledge-retrieval-test.js +292 -0
- package/_site/_test/parallel-knowledge-vector-test.js +168 -0
- package/_site/_test/parallel-linux-ci-r7-log007-day-test.js +110 -0
- package/_site/_test/parallel-logging-acceptance-log003-test.js +224 -0
- package/_site/_test/parallel-logging-acceptance-log004-test.js +231 -0
- package/_site/_test/parallel-logging-acceptance-log005-test.js +208 -0
- package/_site/_test/parallel-logging-acceptance-log006-test.js +214 -0
- package/_site/_test/parallel-logging-acceptance-log007-test.js +223 -0
- package/_site/_test/parallel-logging-acceptance-log008-test.js +180 -0
- package/_site/_test/parallel-logging-fix-r2-crash-probe.js +271 -0
- package/_site/_test/parallel-logging-fix-r2-gap-test.js +294 -0
- package/_site/_test/parallel-logging-fix-r2-normalhook-test.js +330 -0
- package/_site/_test/parallel-logging-integration-5025-portability-test.js +554 -0
- package/_site/_test/parallel-memory-candidate-test.js +301 -0
- package/_site/_test/parallel-memory-manual-test.js +197 -0
- package/_site/_test/parallel-memory-scope-test.js +228 -0
- package/_site/_test/parallel-memory-source-test.js +227 -0
- package/_site/_test/parallel-memory-sync-test.js +238 -0
- package/_site/_test/parallel-memory-view-r8-reload-gate-test.js +123 -0
- package/_site/_test/parallel-nav-failure-test.js +119 -0
- package/_site/_test/parallel-nav-isolation-test.js +308 -0
- package/_site/_test/parallel-nav-isolation-vector-path-test.js +90 -0
- package/_site/_test/parallel-nav-offline-test.js +272 -0
- package/_site/_test/parallel-nav-operability-test.js +257 -0
- package/_site/_test/parallel-nav-switch-test.js +247 -0
- package/_site/_test/parallel-nav-theme-test.js +130 -0
- package/_site/_test/parallel-nav-viewport-test.js +310 -0
- package/_site/_test/parallel-qa-engine-endpoint-guard-test.js +273 -0
- package/_site/_test/parallel-retrieval-followup-citation-test.js +219 -0
- package/_site/_test/parallel-retrieval-followup-corpus-test.js +287 -0
- package/_site/_test/parallel-workbench-independent-host.js +262 -0
- package/_site/_test/parallel-workbench-integration-5025-abort-probe.js +340 -0
- package/_site/_test/parallel-workbench-integration-5025-drafts-probe.js +588 -0
- package/_site/_test/parallel-workbench-integration-5025-env-check.js +317 -0
- package/_site/_test/parallel-workbench-integration-5025-model-probe.js +342 -0
- package/_site/_test/parallel-workbench-integration-5025-ordering-probe.js +326 -0
- package/_site/_test/parallel-workbench-model-probe.js +336 -0
- package/_site/_test/parallel-workbench-offline-test.js +169 -0
- package/_site/_test/parallel-workbench-provenance-trace.js +134 -0
- package/_site/_test/parallel-workbench-source-match.js +206 -0
- package/_site/_test/parallel-workbench-standalone-turn.js +349 -0
- package/_site/_test/path-consistency-test.js +151 -151
- package/_site/_test/pending-sweep-test.js +9 -9
- package/_site/_test/post-commit-automation-test.js +87 -87
- package/_site/_test/pr-consumer-contract-test.js +55 -55
- package/_site/_test/product-brand-contract-test.js +25 -25
- package/_site/_test/product-diagnostics-ui-test.js +93 -93
- package/_site/_test/product-empty-state-test.js +148 -0
- package/_site/_test/product-import-ui-test.js +219 -104
- package/_site/_test/product-navigation-test.js +152 -0
- package/_site/_test/product-progress-status-test.js +84 -84
- package/_site/_test/project-delete-recovery-test.js +64 -64
- package/_site/_test/project-domain-create-test.js +91 -0
- package/_site/_test/project-domain-scope-retrieval-test.js +214 -0
- package/_site/_test/project-git-init-confirm-test.js +115 -0
- package/_site/_test/project-goal-editor-test.js +144 -144
- package/_site/_test/project-import-duplicate-alias-test.js +134 -0
- package/_site/_test/project-import-unicode-restart-test.js +140 -0
- package/_site/_test/project-lifecycle-transaction-test.js +106 -106
- package/_site/_test/project-module-partial-recovery-test.js +222 -0
- package/_site/_test/project-remove-running-guard-test.js +79 -79
- package/_site/_test/project-store-test.js +90 -90
- package/_site/_test/project-unbind-late-read-ui-test.js +250 -0
- package/_site/_test/project-unbind-writer-guard-test.js +231 -0
- package/_site/_test/prompt-settings-test.js +115 -115
- package/_site/_test/protected-architecture-gate-test.js +122 -122
- package/_site/_test/refactor-characterization-test.js +36 -36
- package/_site/_test/registry-events-test.js +38 -38
- package/_site/_test/release-version-sync-test.js +115 -115
- package/_site/_test/requirement-binding-test.js +113 -113
- package/_site/_test/requirement-recorder-test.js +173 -173
- package/_site/_test/run-all-tests.js +173 -161
- package/_site/_test/runtime-endpoint-test.js +64 -64
- package/_site/_test/scanner-test.js +83 -83
- package/_site/_test/server-security-test.js +96 -96
- package/_site/_test/sessions-stream-test.js +93 -93
- package/_site/_test/shared-contracts-test.js +58 -58
- package/_site/_test/shared-scope-root-binding-test.js +74 -67
- package/_site/_test/simple-import-test.js +98 -98
- package/_site/_test/startup-analysis-disabled-test.js +16 -16
- package/_site/_test/storage-foundation-test.js +78 -78
- package/_site/_test/structured-logger-test.js +101 -101
- package/_site/_test/t07b-cln-005-coverage-test.js +212 -0
- package/_site/_test/team-knowledge-store-sparse-checkout-test.js +196 -196
- package/_site/_test/team-knowledge-store-test.js +132 -132
- package/_site/_test/test-server-cleanup-test.js +35 -35
- package/_site/_test/test-server-module-isolation-test.js +37 -37
- package/_site/_test/tracking-start-test.js +144 -144
- package/_site/_test/vector-storage-root-test.js +75 -75
- package/_site/_test/version-visibility-browser-probe.js +249 -0
- package/_site/_test/version-visibility-test.js +92 -0
- package/_site/_test/workbench-context-receipts-test.js +22 -22
- package/_site/_test/workbench-permission-test.js +117 -117
- package/_site/_test/zcode-capture-integration-test.js +112 -112
- package/_site/lib/ai-profile-resolver.js +78 -78
- package/_site/lib/ai-vendor-presets.js +83 -83
- package/_site/lib/ai-workspace.js +104 -104
- package/_site/lib/atomic-file.js +204 -204
- package/_site/lib/automation-config.js +140 -140
- package/_site/lib/bridge-adapter.js +260 -260
- package/_site/lib/bridge-consumer-service.js +402 -402
- package/_site/lib/capture-hook-config.js +108 -108
- package/_site/lib/claude-cli-runner.js +1599 -1599
- package/_site/lib/cli-instances.js +43 -43
- package/_site/lib/codex-context-status.js +17 -17
- package/_site/lib/codex-notify-config.js +193 -193
- package/_site/lib/commit-conversation-binder.js +247 -247
- package/_site/lib/commit-processing-ledger.js +27 -27
- package/_site/lib/commit-prompt.js +202 -202
- package/_site/lib/commit-reconciler.js +444 -444
- package/_site/lib/context-pack-builder.js +299 -299
- package/_site/lib/contracts.js +291 -291
- package/_site/lib/conversation-exclusions.js +204 -204
- package/_site/lib/conversation-query-service.js +161 -161
- package/_site/lib/conversation-store.js +387 -387
- package/_site/lib/data-dir.js +13 -13
- package/_site/lib/embedding-service.js +85 -85
- package/_site/lib/engine-connection.js +93 -93
- package/_site/lib/engine-knowledge-client.js +76 -72
- package/_site/lib/evidence-bundle.js +228 -228
- package/_site/lib/folder-picker-output.js +24 -24
- package/_site/lib/git-path.js +14 -14
- package/_site/lib/git-runner.js +62 -62
- package/_site/lib/github-team-store.js +1175 -1175
- package/_site/lib/hook-manager.js +203 -203
- package/_site/lib/index-builder.js +157 -157
- package/_site/lib/index-service.js +173 -173
- package/_site/lib/integration-auto-repair.js +77 -77
- package/_site/lib/integration-installer.js +1240 -1240
- package/_site/lib/integration-intent.js +88 -88
- package/_site/lib/integration-status-scan.js +99 -99
- package/_site/lib/integration-status-worker.js +14 -14
- package/_site/lib/kb-framework.js +191 -191
- package/_site/lib/kb-validator.js +124 -124
- package/_site/lib/knowledge-db.js +363 -363
- package/_site/lib/knowledge-promotion.js +435 -435
- package/_site/lib/knowledge-retrieval-service.js +401 -401
- package/_site/lib/knowledge-schema.js +121 -121
- package/_site/lib/knowledge-tool-runtime.js +366 -366
- package/_site/lib/live-gateway.js +78 -78
- package/_site/lib/llm-client.js +173 -173
- package/_site/lib/markdown-knowledge-indexer.js +230 -230
- package/_site/lib/model-context-windows.js +82 -82
- package/_site/lib/module-bridge.js +874 -874
- package/_site/lib/module-port-resolver.js +57 -57
- package/_site/lib/post-commit-automation.js +141 -141
- package/_site/lib/product-data.js +35 -35
- package/_site/lib/project-lifecycle-service.js +554 -554
- package/_site/lib/project-registry-store.js +129 -129
- package/_site/lib/project-store.js +268 -268
- package/_site/lib/prompt-registry.js +148 -148
- package/_site/lib/public-version-info.js +37 -0
- package/_site/lib/registry-events.js +16 -16
- package/_site/lib/requirement-adapters.js +10 -10
- package/_site/lib/requirement-binder.js +112 -112
- package/_site/lib/requirement-recorder.js +278 -278
- package/_site/lib/runtime-control.js +89 -89
- package/_site/lib/runtime-endpoint.js +160 -160
- package/_site/lib/scanner.js +298 -298
- package/_site/lib/server-app.js +1672 -1664
- package/_site/lib/settings-store.js +153 -153
- package/_site/lib/storage-layout.js +166 -166
- package/_site/lib/structured-logger.js +574 -574
- package/_site/lib/zcode-context-integration.js +60 -60
- package/_site/scripts/codex-notify-fanout.cjs +95 -95
- package/_site/scripts/folder-picker.ps1 +156 -156
- package/_site/scripts/hook-trigger.js +158 -158
- package/_site/scripts/install-module-candidates.js +69 -69
- package/_site/scripts/pack-module-candidates.js +89 -89
- package/_site/scripts/sync-product-content.js +28 -28
- package/_site/scripts/sync-release-version.js +164 -164
- package/_site/scripts/vendor-modules.js +49 -49
- package/_site/scripts/verify-module-runtime.js +50 -50
- package/_site/scripts/verify-product-runtime.js +36 -36
- package/_site/scripts/verify-retrieval-gold.js +83 -83
- package/_site/server.js +15 -15
- package/_site/start.bat +26 -26
- package/_site/stop.bat +11 -11
- package/bin/project-knowledge-integrations.js +254 -254
- package/bin/project-knowledge-kb.js +67 -67
- package/bin/project-knowledge-mcp.js +201 -201
- package/bin/project-knowledge.js +269 -170
- package/claude-prompts.json +21 -21
- package/docs/README.zh-CN.md +207 -205
- package/docs/assets/architecture.svg +181 -181
- package/docs/assets/logo.svg +49 -49
- package/docs/fresh-v5-start.md +44 -44
- package/docs/leader-glm-workbench-playbook.md +122 -122
- package/docs/project-registry-schema.md +33 -33
- package/docs/release-5.0.16-acceptance.md +176 -176
- package/docs/release-5.0.17-acceptance.md +117 -117
- package/docs/release-5.0.19-acceptance.md +39 -39
- package/docs/team-knowledge-mode-a-plan.md +73 -73
- package/docs/testing-strategy.md +33 -33
- package/module-runtime-manifest.json +66 -63
- package/package.json +113 -110
- package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.mcp.json +1 -1
- package/templates/change.md +30 -30
- package/templates/project-readme.md +52 -52
- package/ui/index.html +3 -2
- package/ui/version-info.css +44 -0
- package/ui/version-info.js +24 -0
- package/vendor-manifest.json +55 -55
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Lane-owned fixture helpers for the Workbench provenance batch.
|
|
3
|
+
//
|
|
4
|
+
// Isolation contract (the batch is allowed to touch nothing of the real
|
|
5
|
+
// product):
|
|
6
|
+
// * every directory is created below the shared temp root, never inside
|
|
7
|
+
// the repository;
|
|
8
|
+
// * the Workbench data directory, the Bridge home, the knowledge data
|
|
9
|
+
// directory and HOME/USERPROFILE/CLAUDE_CONFIG_DIR are all isolated, so
|
|
10
|
+
// the spawned Claude Code CLI cannot read or write the developer's
|
|
11
|
+
// ~/.claude, its credentials, its memory or its trust store;
|
|
12
|
+
// * the live product ports are refused;
|
|
13
|
+
// * the ambient module addresses and every ambient Anthropic credential
|
|
14
|
+
// variable are dropped, so a call can only reach the profile the test
|
|
15
|
+
// injects.
|
|
16
|
+
//
|
|
17
|
+
// Credential contract: the original subscription credential is read from its
|
|
18
|
+
// real location READ-ONLY and stays in memory. It is never written to a
|
|
19
|
+
// file, a log, a report or a clone, and the profile store handed to the host
|
|
20
|
+
// refuses every write method.
|
|
21
|
+
const fs = require('node:fs');
|
|
22
|
+
const os = require('node:os');
|
|
23
|
+
const path = require('node:path');
|
|
24
|
+
const http = require('node:http');
|
|
25
|
+
const net = require('node:net');
|
|
26
|
+
const crypto = require('node:crypto');
|
|
27
|
+
const { spawn } = require('node:child_process');
|
|
28
|
+
|
|
29
|
+
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
30
|
+
|
|
31
|
+
// The developer's live surfaces. A test may never bind or talk to them.
|
|
32
|
+
const FORBIDDEN_PORTS = new Set([5757, 5760, 5789, 5790, 8787, 8790]);
|
|
33
|
+
|
|
34
|
+
// Ambient module addresses that would point a test at a live instance.
|
|
35
|
+
const AMBIENT_MODULE_URLS = [
|
|
36
|
+
'KB_KNOWLEDGE_ENGINE_URL',
|
|
37
|
+
'KB_VECTORHUB_URL',
|
|
38
|
+
'KB_TERMINAL_URL',
|
|
39
|
+
'KB_EVENTBRIDGE_URL',
|
|
40
|
+
'KB_EVENT_BRIDGE_URL',
|
|
41
|
+
'KB_WORKBENCH_RUNTIME_TOKEN',
|
|
42
|
+
'KB_MODULES_AUTOSTART',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// Ambient Anthropic credentials: a test must only ever use the credential it
|
|
46
|
+
// injects itself, never one that happens to sit in the shell.
|
|
47
|
+
const AMBIENT_MODEL_ENV = [
|
|
48
|
+
'ANTHROPIC_API_KEY',
|
|
49
|
+
'ANTHROPIC_AUTH_TOKEN',
|
|
50
|
+
'ANTHROPIC_BASE_URL',
|
|
51
|
+
'ANTHROPIC_MODEL',
|
|
52
|
+
'ANTHROPIC_DEFAULT_THINKING_MODEL',
|
|
53
|
+
'ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
54
|
+
'ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
55
|
+
'ANTHROPIC_DEFAULT_OPUS_MODEL',
|
|
56
|
+
'API_TIMEOUT_MS',
|
|
57
|
+
'CLAUDE_CODE_OAUTH_TOKEN',
|
|
58
|
+
'CLAUDE_CODE_USE_BEDROCK',
|
|
59
|
+
'CLAUDE_CODE_USE_VERTEX',
|
|
60
|
+
'CLAUDE_CODE_USE_FOUNDRY',
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
// Captured before any isolation changes HOME.
|
|
64
|
+
const REAL_HOME = os.homedir();
|
|
65
|
+
const REAL_USERPROFILE = process.env.USERPROFILE || REAL_HOME;
|
|
66
|
+
|
|
67
|
+
function isInside(candidate, parent) {
|
|
68
|
+
const relative = path.relative(parent, candidate);
|
|
69
|
+
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function resolveTempRoot() {
|
|
73
|
+
// The batch contract pins a shared temp root next to the repositories;
|
|
74
|
+
// it is honoured when it exists, and everything else falls through so the
|
|
75
|
+
// helper stays portable.
|
|
76
|
+
const sharedRoot = path.join(path.dirname(REPO_ROOT), '.project-knowledge-test-temp');
|
|
77
|
+
const candidates = [
|
|
78
|
+
process.env.PK_TEST_TEMP_ROOT,
|
|
79
|
+
fs.existsSync(sharedRoot) ? sharedRoot : null,
|
|
80
|
+
process.env.TEMP,
|
|
81
|
+
process.env.TMP,
|
|
82
|
+
process.env.TMPDIR,
|
|
83
|
+
];
|
|
84
|
+
const chosen = candidates.find(value => value && String(value).trim());
|
|
85
|
+
const root = path.resolve(chosen ? String(chosen).trim() : os.tmpdir());
|
|
86
|
+
if (isInside(root, REPO_ROOT)) throw new Error(`refusing to use a temp root inside the repository: ${root}`);
|
|
87
|
+
return root;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function ensureTempRoot() {
|
|
91
|
+
const root = resolveTempRoot();
|
|
92
|
+
fs.mkdirSync(root, { recursive: true });
|
|
93
|
+
return root;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function makeTempDir(prefix = 'parallel-workbench') {
|
|
97
|
+
const root = ensureTempRoot();
|
|
98
|
+
const dir = fs.mkdtempSync(path.join(root, `${prefix}-`));
|
|
99
|
+
if (isInside(dir, REPO_ROOT)) throw new Error(`refusing to create a fixture inside the repository: ${dir}`);
|
|
100
|
+
return dir;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function removeTree(dir) {
|
|
104
|
+
if (!dir) return;
|
|
105
|
+
fs.rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function freePort() {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const server = net.createServer();
|
|
111
|
+
server.unref();
|
|
112
|
+
server.on('error', reject);
|
|
113
|
+
server.listen(0, '127.0.0.1', () => {
|
|
114
|
+
const { port } = server.address();
|
|
115
|
+
server.close(() => {
|
|
116
|
+
if (FORBIDDEN_PORTS.has(Number(port))) { reject(new Error(`refusing to use the live port ${port}`)); return; }
|
|
117
|
+
resolve(Number(port));
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function assertAllowedEndpoint(url, what = 'endpoint') {
|
|
124
|
+
const parsed = new URL(String(url));
|
|
125
|
+
const port = parsed.port ? Number(parsed.port) : (parsed.protocol === 'https:' ? 443 : 80);
|
|
126
|
+
if (FORBIDDEN_PORTS.has(port)) throw new Error(`refusing to contact the live ${what} ${url}`);
|
|
127
|
+
return url;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function waitForHttp(url, timeoutMs = 30000) {
|
|
131
|
+
assertAllowedEndpoint(url, 'service');
|
|
132
|
+
const until = Date.now() + timeoutMs;
|
|
133
|
+
let lastError = null;
|
|
134
|
+
while (Date.now() < until) {
|
|
135
|
+
try {
|
|
136
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(2000) });
|
|
137
|
+
if (response.ok) return true;
|
|
138
|
+
lastError = new Error(`HTTP ${response.status}`);
|
|
139
|
+
} catch (error) { lastError = error; }
|
|
140
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
141
|
+
}
|
|
142
|
+
throw new Error(`Timed out waiting for ${url}: ${lastError && lastError.message}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function sanitizedEnv(extra = {}) {
|
|
146
|
+
const env = { ...process.env, ...extra };
|
|
147
|
+
for (const key of AMBIENT_MODULE_URLS) delete env[key];
|
|
148
|
+
for (const key of AMBIENT_MODEL_ENV) delete env[key];
|
|
149
|
+
return env;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function spawnNode(args, env = {}) {
|
|
153
|
+
const child = spawn(process.execPath, args, {
|
|
154
|
+
env: sanitizedEnv(env),
|
|
155
|
+
windowsHide: true,
|
|
156
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
157
|
+
});
|
|
158
|
+
const output = { stdout: '', stderr: '' };
|
|
159
|
+
child.stdout.on('data', chunk => { output.stdout += chunk; });
|
|
160
|
+
child.stderr.on('data', chunk => { output.stderr += chunk; });
|
|
161
|
+
const exited = new Promise(resolve => child.once('close', code => resolve({ code, ...output })));
|
|
162
|
+
return { child, exited, output };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// --- the isolation directories of one host -------------------------------
|
|
166
|
+
function createIsolationLayout(prefix = 'parallel-workbench') {
|
|
167
|
+
const root = makeTempDir(prefix);
|
|
168
|
+
const layout = {
|
|
169
|
+
root,
|
|
170
|
+
dataDir: path.join(root, 'workbench-data'),
|
|
171
|
+
knowledgeDataDir: path.join(root, 'knowledge-data'),
|
|
172
|
+
bridgeHome: path.join(root, 'bridge-home'),
|
|
173
|
+
home: path.join(root, 'home'),
|
|
174
|
+
claudeConfigDir: path.join(root, 'claude-config'),
|
|
175
|
+
workspace: path.join(root, 'workspace'),
|
|
176
|
+
temp: path.join(root, 'temp'),
|
|
177
|
+
};
|
|
178
|
+
for (const dir of Object.values(layout)) {
|
|
179
|
+
if (typeof dir === 'string') fs.mkdirSync(dir, { recursive: true });
|
|
180
|
+
}
|
|
181
|
+
fs.writeFileSync(path.join(layout.workspace, 'README.md'), '# Workbench fixture workspace\n', 'utf8');
|
|
182
|
+
return layout;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// The environment a host child may inherit.
|
|
186
|
+
function hostEnv(layout, extra = {}) {
|
|
187
|
+
const parsed = path.parse(layout.home);
|
|
188
|
+
return sanitizedEnv({
|
|
189
|
+
// The real profile directory is passed explicitly: the child's isolated
|
|
190
|
+
// HOME would otherwise hide it, and the read-only profile facade needs
|
|
191
|
+
// the original location.
|
|
192
|
+
PK_WB_REAL_PROFILE_DIR: realWorkbenchProfileDir(),
|
|
193
|
+
HOME: layout.home,
|
|
194
|
+
USERPROFILE: layout.home,
|
|
195
|
+
HOMEDRIVE: parsed.root,
|
|
196
|
+
HOMEPATH: parsed.root === path.sep ? layout.home.slice(1) : layout.home.slice(parsed.root.length),
|
|
197
|
+
CLAUDE_CONFIG_DIR: layout.claudeConfigDir,
|
|
198
|
+
TEMP: layout.temp,
|
|
199
|
+
TMP: layout.temp,
|
|
200
|
+
TMPDIR: layout.temp,
|
|
201
|
+
KB_DATA_DIR: layout.knowledgeDataDir,
|
|
202
|
+
KB_KNOWLEDGE_DATA_DIR: layout.knowledgeDataDir,
|
|
203
|
+
AI_CODING_EVENT_BRIDGE_HOME: layout.bridgeHome,
|
|
204
|
+
AGENT_TERMINAL_DATA_DIR: layout.dataDir,
|
|
205
|
+
CLAUDE_AI_WORKBENCH_DATA_DIR: layout.dataDir,
|
|
206
|
+
KB_MODULES_AUTOSTART: '0',
|
|
207
|
+
...extra,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// --- the real (read-only) profile source ---------------------------------
|
|
212
|
+
// Where the product keeps its profiles. Resolved from the real home, never
|
|
213
|
+
// from an isolated one.
|
|
214
|
+
function realWorkbenchProfileDir() {
|
|
215
|
+
const override = String(process.env.PK_WB_REAL_PROFILE_DIR || '').trim();
|
|
216
|
+
if (override) return path.resolve(override);
|
|
217
|
+
return path.join(REAL_HOME, '.project-knowledge-v5', 'workbench');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Byte-level snapshot of a flat directory. The SHA256 digests stay in the
|
|
221
|
+
// process memory: only counts and file NAMES ever leave compareDigests, so a
|
|
222
|
+
// digest of a credential file is never printed, logged or persisted.
|
|
223
|
+
function digestDirectory(dir) {
|
|
224
|
+
if (!dir || !fs.existsSync(dir)) return null;
|
|
225
|
+
const entries = {};
|
|
226
|
+
for (const name of fs.readdirSync(dir)) {
|
|
227
|
+
try {
|
|
228
|
+
const file = path.join(dir, name);
|
|
229
|
+
if (!fs.statSync(file).isFile()) continue;
|
|
230
|
+
entries[name] = crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
|
231
|
+
} catch { entries[name] = null; }
|
|
232
|
+
}
|
|
233
|
+
return entries;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function compareDigests(before, after) {
|
|
237
|
+
const names = new Set([...Object.keys(before || {}), ...Object.keys(after || {})]);
|
|
238
|
+
const changed = [];
|
|
239
|
+
const added = [];
|
|
240
|
+
const removed = [];
|
|
241
|
+
const unreadable = [];
|
|
242
|
+
for (const name of names) {
|
|
243
|
+
const a = before ? before[name] : undefined;
|
|
244
|
+
const b = after ? after[name] : undefined;
|
|
245
|
+
if (a === undefined && b !== undefined) added.push(name);
|
|
246
|
+
else if (a !== undefined && b === undefined) removed.push(name);
|
|
247
|
+
else if (a === null || b === null) unreadable.push(name);
|
|
248
|
+
else if (a !== b) changed.push(name);
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
count: names.size,
|
|
252
|
+
byteIdentical: changed.length === 0 && added.length === 0 && removed.length === 0 && unreadable.length === 0,
|
|
253
|
+
changedFiles: changed,
|
|
254
|
+
addedFiles: added,
|
|
255
|
+
removedFiles: removed,
|
|
256
|
+
unreadableFiles: unreadable,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// A profile store that reads the original profiles and credentials but
|
|
261
|
+
// refuses every write. The credential stays in memory: it is never written
|
|
262
|
+
// anywhere by this lane.
|
|
263
|
+
function createReadOnlyProfileStore(moduleRoot, layout, options = {}) {
|
|
264
|
+
const profileDir = options.profileDir || realWorkbenchProfileDir();
|
|
265
|
+
const profileFile = path.join(profileDir, 'profiles.v2.json');
|
|
266
|
+
const credentialFile = path.join(profileDir, 'credentials.v1.json');
|
|
267
|
+
if (!fs.existsSync(profileFile)) throw new Error(`the original profile file is missing: ${profileFile}`);
|
|
268
|
+
const { ProfileStore } = require(path.join(moduleRoot, 'packages', 'server', 'lib', 'profile-store.js'));
|
|
269
|
+
const store = new ProfileStore({ dataDir: layout.dataDir, profileFile, credentialFile });
|
|
270
|
+
const WRITE_METHODS = new Set(['save', 'delete', 'setCredential', 'setEmbeddingConfig', 'setMaintenanceDefault', 'importLegacy', 'importEmbedding']);
|
|
271
|
+
return new Proxy(store, {
|
|
272
|
+
get(target, property) {
|
|
273
|
+
if (WRITE_METHODS.has(property)) {
|
|
274
|
+
return () => { throw Object.assign(new Error('the profile store of this fixture is read-only'), { status: 409 }); };
|
|
275
|
+
}
|
|
276
|
+
const value = target[property];
|
|
277
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// --- the controlled integration fixture ----------------------------------
|
|
283
|
+
// A local knowledge-engine stand-in. It is a FIXTURE: it proves that the
|
|
284
|
+
// module consumes an integration context over its documented contract, and
|
|
285
|
+
// it is never counted as real knowledge, real retrieval or a real model.
|
|
286
|
+
function startIntegrationFixture(options = {}) {
|
|
287
|
+
const requests = [];
|
|
288
|
+
const marker = options.marker || 'WB-INTEGRATION-FIXTURE';
|
|
289
|
+
const server = http.createServer((req, res) => {
|
|
290
|
+
let body = '';
|
|
291
|
+
req.on('data', chunk => { body += chunk; });
|
|
292
|
+
req.on('end', () => {
|
|
293
|
+
let parsed = null;
|
|
294
|
+
try { parsed = body ? JSON.parse(body) : null; } catch { parsed = null; }
|
|
295
|
+
requests.push({ method: req.method, url: req.url, body: parsed });
|
|
296
|
+
if (req.method === 'POST' && req.url === '/api/context') {
|
|
297
|
+
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
298
|
+
res.end(JSON.stringify({
|
|
299
|
+
ok: true,
|
|
300
|
+
status: 'ready',
|
|
301
|
+
projectId: 'fixture-project',
|
|
302
|
+
scope: 'fixture',
|
|
303
|
+
references: [{ uri: 'fixture/doc.md', title: 'Fixture reference', score: 0.5 }],
|
|
304
|
+
memories: [{ id: 'fixture-memory', text: `${marker} memory` }],
|
|
305
|
+
memoryCount: 1,
|
|
306
|
+
memoryStatus: 'ready',
|
|
307
|
+
truncated: false,
|
|
308
|
+
requestId: `fixture-request-${requests.length}`,
|
|
309
|
+
prompt: `\n\n${marker}: controlled integration context`,
|
|
310
|
+
}));
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
314
|
+
res.end(JSON.stringify({ ok: false, error: 'not found' }));
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
return new Promise(resolve => {
|
|
318
|
+
server.listen(0, '127.0.0.1', async () => {
|
|
319
|
+
const { port } = server.address();
|
|
320
|
+
if (FORBIDDEN_PORTS.has(Number(port))) { server.close(); throw new Error(`refusing to use the live port ${port}`); }
|
|
321
|
+
resolve({
|
|
322
|
+
port,
|
|
323
|
+
url: `http://127.0.0.1:${port}`,
|
|
324
|
+
marker,
|
|
325
|
+
requests,
|
|
326
|
+
close: () => new Promise(done => server.close(() => done())),
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// The module that is hosted: the copy the installed product ships, unless
|
|
333
|
+
// the caller pins another one explicitly.
|
|
334
|
+
function resolveHostModuleRoot(options = {}) {
|
|
335
|
+
const override = String(options.moduleRoot || process.env.PK_WB_MODULE_ROOT || '').trim();
|
|
336
|
+
if (override) return path.resolve(override);
|
|
337
|
+
const appData = String(process.env.APPDATA || '').trim();
|
|
338
|
+
if (appData) {
|
|
339
|
+
const candidate = path.join(appData, 'npm', 'node_modules', '@sanqianx', 'project-knowledge', 'node_modules', 'claude-ai-workbench');
|
|
340
|
+
if (fs.existsSync(path.join(candidate, 'packages', 'server', 'package.json'))) return candidate;
|
|
341
|
+
}
|
|
342
|
+
const repoPin = path.join(REPO_ROOT, 'node_modules', 'claude-ai-workbench');
|
|
343
|
+
if (fs.existsSync(path.join(repoPin, 'packages', 'server', 'package.json'))) return repoPin;
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
module.exports = {
|
|
348
|
+
REPO_ROOT,
|
|
349
|
+
FORBIDDEN_PORTS,
|
|
350
|
+
AMBIENT_MODULE_URLS,
|
|
351
|
+
AMBIENT_MODEL_ENV,
|
|
352
|
+
REAL_HOME,
|
|
353
|
+
REAL_USERPROFILE,
|
|
354
|
+
resolveTempRoot,
|
|
355
|
+
ensureTempRoot,
|
|
356
|
+
makeTempDir,
|
|
357
|
+
removeTree,
|
|
358
|
+
freePort,
|
|
359
|
+
assertAllowedEndpoint,
|
|
360
|
+
waitForHttp,
|
|
361
|
+
sanitizedEnv,
|
|
362
|
+
spawnNode,
|
|
363
|
+
createIsolationLayout,
|
|
364
|
+
hostEnv,
|
|
365
|
+
realWorkbenchProfileDir,
|
|
366
|
+
digestDirectory,
|
|
367
|
+
compareDigests,
|
|
368
|
+
createReadOnlyProfileStore,
|
|
369
|
+
startIntegrationFixture,
|
|
370
|
+
resolveHostModuleRoot,
|
|
371
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Lane-owned standalone host for the Workbench provenance batch (WB002/WB003).
|
|
3
|
+
//
|
|
4
|
+
// This child process hosts the REAL claude-ai-workbench module — the copy the
|
|
5
|
+
// installed product ships — as an independent process with an isolated data
|
|
6
|
+
// directory, workspace, HOME and Claude config. It is started by the lane
|
|
7
|
+
// tests and speaks the module's real HTTP contract.
|
|
8
|
+
//
|
|
9
|
+
// Modes:
|
|
10
|
+
// standalone no knowledge engine, no profiles beyond the empty isolated
|
|
11
|
+
// store — proves the module needs no knowledge-base business
|
|
12
|
+
// objects to work;
|
|
13
|
+
// integration KB_KNOWLEDGE_ENGINE_URL points at the controlled integration
|
|
14
|
+
// fixture, so the module consumes an integration context that
|
|
15
|
+
// this lane controls and can observe.
|
|
16
|
+
//
|
|
17
|
+
// Profile source:
|
|
18
|
+
// none the isolated ProfileStore (empty) is used;
|
|
19
|
+
// real-readonly the ORIGINAL profile store of the product is wrapped in a
|
|
20
|
+
// read-only facade: profiles and credentials are read from
|
|
21
|
+
// their real location, every write method refuses. The
|
|
22
|
+
// credential stays in this process's memory and is never
|
|
23
|
+
// written anywhere.
|
|
24
|
+
//
|
|
25
|
+
// Environment (all set by the parent):
|
|
26
|
+
// PK_WB_MODULE_ROOT the claude-ai-workbench package root to host
|
|
27
|
+
// PK_WB_HOST_PORT port to listen on (127.0.0.1)
|
|
28
|
+
// PK_WB_HOST_DATA_DIR isolated workbench data directory
|
|
29
|
+
// PK_WB_HOST_WORKSPACE isolated workspace directory
|
|
30
|
+
// PK_WB_HOST_MODE standalone | integration
|
|
31
|
+
// PK_WB_ENGINE_URL the controlled integration fixture URL (integration)
|
|
32
|
+
// PK_WB_PROFILE_SOURCE none | real-readonly
|
|
33
|
+
const path = require('node:path');
|
|
34
|
+
|
|
35
|
+
const moduleRoot = String(process.env.PK_WB_MODULE_ROOT || '').trim();
|
|
36
|
+
const port = Number(process.env.PK_WB_HOST_PORT || 0);
|
|
37
|
+
const dataDir = String(process.env.PK_WB_HOST_DATA_DIR || '').trim();
|
|
38
|
+
const workspace = String(process.env.PK_WB_HOST_WORKSPACE || '').trim();
|
|
39
|
+
const mode = String(process.env.PK_WB_HOST_MODE || 'standalone');
|
|
40
|
+
const engineUrl = String(process.env.PK_WB_ENGINE_URL || '').trim();
|
|
41
|
+
const profileSource = String(process.env.PK_WB_PROFILE_SOURCE || 'none');
|
|
42
|
+
|
|
43
|
+
if (!moduleRoot || !port || !dataDir || !workspace) {
|
|
44
|
+
console.error('parallel-workbench-host: PK_WB_MODULE_ROOT, PK_WB_HOST_PORT, PK_WB_HOST_DATA_DIR and PK_WB_HOST_WORKSPACE are required');
|
|
45
|
+
process.exit(2);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Same contract as the module's own bin: the legacy runtime resolves its
|
|
49
|
+
// data directory from these.
|
|
50
|
+
process.env.CLAUDE_AI_WORKBENCH_DATA_DIR = dataDir;
|
|
51
|
+
process.env.KB_DATA_DIR = dataDir;
|
|
52
|
+
if (mode === 'integration' && engineUrl) process.env.KB_KNOWLEDGE_ENGINE_URL = engineUrl;
|
|
53
|
+
|
|
54
|
+
const { createWorkbenchServer } = require(path.join(moduleRoot, 'packages', 'server'));
|
|
55
|
+
|
|
56
|
+
function buildOptions() {
|
|
57
|
+
const options = { dataDir, workspaces: { 'wb-fixture': workspace } };
|
|
58
|
+
if (profileSource === 'real-readonly') {
|
|
59
|
+
const fixture = require('./parallel-workbench-fixture');
|
|
60
|
+
options.profiles = fixture.createReadOnlyProfileStore(moduleRoot, { dataDir });
|
|
61
|
+
}
|
|
62
|
+
return options;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const app = createWorkbenchServer(buildOptions());
|
|
66
|
+
app.server.listen(port, '127.0.0.1', () => {
|
|
67
|
+
process.stdout.write(`WORKBENCH_HOST_READY http://127.0.0.1:${port} mode=${mode} module=${moduleRoot} data=${dataDir}\n`);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
let stopping = false;
|
|
71
|
+
async function shutdown() {
|
|
72
|
+
if (stopping) return;
|
|
73
|
+
stopping = true;
|
|
74
|
+
setTimeout(() => process.exit(1), 10000).unref();
|
|
75
|
+
try { await app.service.destroy(); } catch { process.exitCode = 1; }
|
|
76
|
+
app.server.closeAllConnections?.();
|
|
77
|
+
app.server.close(() => process.exit(process.exitCode || 0));
|
|
78
|
+
}
|
|
79
|
+
process.on('SIGINT', shutdown);
|
|
80
|
+
process.on('SIGTERM', shutdown);
|