spectra-cli 4.1.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/adapters/go-adapter.d.ts.map +1 -1
- package/dist/adapters/go-adapter.js +2 -0
- package/dist/adapters/go-adapter.js.map +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/java-adapter.d.ts.map +1 -1
- package/dist/adapters/java-adapter.js +2 -0
- package/dist/adapters/java-adapter.js.map +1 -1
- package/dist/adapters/language-adapter.d.ts +47 -9
- package/dist/adapters/language-adapter.d.ts.map +1 -1
- package/dist/adapters/python-adapter.d.ts +34 -6
- package/dist/adapters/python-adapter.d.ts.map +1 -1
- package/dist/adapters/python-adapter.js +157 -59
- package/dist/adapters/python-adapter.js.map +1 -1
- package/dist/adapters/ts-js-adapter.d.ts +13 -5
- package/dist/adapters/ts-js-adapter.d.ts.map +1 -1
- package/dist/adapters/ts-js-adapter.js +55 -14
- package/dist/adapters/ts-js-adapter.js.map +1 -1
- package/dist/batch/batch-orchestrator.d.ts +30 -4
- package/dist/batch/batch-orchestrator.d.ts.map +1 -1
- package/dist/batch/batch-orchestrator.js +284 -7
- package/dist/batch/batch-orchestrator.js.map +1 -1
- package/dist/batch/delta-regenerator.d.ts +2 -2
- package/dist/batch/delta-regenerator.d.ts.map +1 -1
- package/dist/batch/delta-regenerator.js.map +1 -1
- package/dist/batch/module-grouper.d.ts +2 -2
- package/dist/batch/module-grouper.d.ts.map +1 -1
- package/dist/batch/module-grouper.js +1 -1
- package/dist/batch/module-grouper.js.map +1 -1
- package/dist/cli/commands/graph.js +1 -1
- package/dist/cli/commands/graph.js.map +1 -1
- package/dist/cli/commands/index.d.ts +8 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +274 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/query.d.ts.map +1 -1
- package/dist/cli/commands/query.js +3 -1
- package/dist/cli/commands/query.js.map +1 -1
- package/dist/cli/index.js +9 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/parse-args.d.ts +13 -1
- package/dist/cli/utils/parse-args.d.ts.map +1 -1
- package/dist/cli/utils/parse-args.js +79 -2
- package/dist/cli/utils/parse-args.js.map +1 -1
- package/dist/core/ast-analyzer.d.ts.map +1 -1
- package/dist/core/ast-analyzer.js +79 -5
- package/dist/core/ast-analyzer.js.map +1 -1
- package/dist/core/import-resolver.d.ts +90 -0
- package/dist/core/import-resolver.d.ts.map +1 -0
- package/dist/core/import-resolver.js +273 -0
- package/dist/core/import-resolver.js.map +1 -0
- package/dist/core/query-mappers/base-mapper.d.ts +13 -0
- package/dist/core/query-mappers/base-mapper.d.ts.map +1 -1
- package/dist/core/query-mappers/go-mapper.d.ts +68 -0
- package/dist/core/query-mappers/go-mapper.d.ts.map +1 -1
- package/dist/core/query-mappers/go-mapper.js +421 -0
- package/dist/core/query-mappers/go-mapper.js.map +1 -1
- package/dist/core/query-mappers/java-mapper.d.ts +196 -0
- package/dist/core/query-mappers/java-mapper.d.ts.map +1 -1
- package/dist/core/query-mappers/java-mapper.js +600 -0
- package/dist/core/query-mappers/java-mapper.js.map +1 -1
- package/dist/core/query-mappers/python-mapper.d.ts +55 -0
- package/dist/core/query-mappers/python-mapper.d.ts.map +1 -1
- package/dist/core/query-mappers/python-mapper.js +273 -0
- package/dist/core/query-mappers/python-mapper.js.map +1 -1
- package/dist/core/query-mappers/typescript-mapper.d.ts +102 -0
- package/dist/core/query-mappers/typescript-mapper.d.ts.map +1 -1
- package/dist/core/query-mappers/typescript-mapper.js +470 -0
- package/dist/core/query-mappers/typescript-mapper.js.map +1 -1
- package/dist/core/single-spec-orchestrator.d.ts.map +1 -1
- package/dist/core/single-spec-orchestrator.js +146 -9
- package/dist/core/single-spec-orchestrator.js.map +1 -1
- package/dist/core/tree-sitter-analyzer.d.ts +6 -0
- package/dist/core/tree-sitter-analyzer.d.ts.map +1 -1
- package/dist/core/tree-sitter-analyzer.js +33 -1
- package/dist/core/tree-sitter-analyzer.js.map +1 -1
- package/dist/core/tree-sitter-fallback.d.ts +7 -4
- package/dist/core/tree-sitter-fallback.d.ts.map +1 -1
- package/dist/core/tree-sitter-fallback.js +157 -12
- package/dist/core/tree-sitter-fallback.js.map +1 -1
- package/dist/extraction/extraction-types.d.ts +25 -25
- package/dist/generator/index-generator.d.ts +3 -3
- package/dist/generator/index-generator.d.ts.map +1 -1
- package/dist/generator/index-generator.js +1 -1
- package/dist/generator/index-generator.js.map +1 -1
- package/dist/graph/directory-graph.d.ts +14 -4
- package/dist/graph/directory-graph.d.ts.map +1 -1
- package/dist/graph/directory-graph.js +71 -128
- package/dist/graph/directory-graph.js.map +1 -1
- package/dist/graph/mermaid-renderer.d.ts +8 -5
- package/dist/graph/mermaid-renderer.d.ts.map +1 -1
- package/dist/graph/mermaid-renderer.js +3 -3
- package/dist/graph/mermaid-renderer.js.map +1 -1
- package/dist/graph/topological-sort.d.ts +13 -6
- package/dist/graph/topological-sort.d.ts.map +1 -1
- package/dist/graph/topological-sort.js +2 -2
- package/dist/graph/topological-sort.js.map +1 -1
- package/dist/knowledge-graph/call-resolver.d.ts +64 -0
- package/dist/knowledge-graph/call-resolver.d.ts.map +1 -0
- package/dist/knowledge-graph/call-resolver.js +323 -0
- package/dist/knowledge-graph/call-resolver.js.map +1 -0
- package/dist/knowledge-graph/import-resolver.d.ts +114 -0
- package/dist/knowledge-graph/import-resolver.d.ts.map +1 -0
- package/dist/knowledge-graph/import-resolver.js +537 -0
- package/dist/knowledge-graph/import-resolver.js.map +1 -0
- package/dist/knowledge-graph/incremental.d.ts +110 -0
- package/dist/knowledge-graph/incremental.d.ts.map +1 -0
- package/dist/knowledge-graph/incremental.js +410 -0
- package/dist/knowledge-graph/incremental.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +74 -0
- package/dist/knowledge-graph/index.d.ts.map +1 -0
- package/dist/knowledge-graph/index.js +156 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/knowledge-graph/module-derivation.d.ts +238 -0
- package/dist/knowledge-graph/module-derivation.d.ts.map +1 -0
- package/dist/knowledge-graph/module-derivation.js +418 -0
- package/dist/knowledge-graph/module-derivation.js.map +1 -0
- package/dist/knowledge-graph/persistence.d.ts +270 -0
- package/dist/knowledge-graph/persistence.d.ts.map +1 -0
- package/dist/knowledge-graph/persistence.js +226 -0
- package/dist/knowledge-graph/persistence.js.map +1 -0
- package/dist/knowledge-graph/query-helpers.d.ts +164 -0
- package/dist/knowledge-graph/query-helpers.d.ts.map +1 -0
- package/dist/knowledge-graph/query-helpers.js +394 -0
- package/dist/knowledge-graph/query-helpers.js.map +1 -0
- package/dist/knowledge-graph/unified-graph.d.ts +310 -0
- package/dist/knowledge-graph/unified-graph.d.ts.map +1 -0
- package/dist/knowledge-graph/unified-graph.js +182 -0
- package/dist/knowledge-graph/unified-graph.js.map +1 -0
- package/dist/mcp/agent-context-tools.d.ts +104 -0
- package/dist/mcp/agent-context-tools.d.ts.map +1 -0
- package/dist/mcp/agent-context-tools.js +854 -0
- package/dist/mcp/agent-context-tools.js.map +1 -0
- package/dist/mcp/graph-tools.d.ts +20 -0
- package/dist/mcp/graph-tools.d.ts.map +1 -1
- package/dist/mcp/graph-tools.js +71 -11
- package/dist/mcp/graph-tools.js.map +1 -1
- package/dist/mcp/lib/response-helpers.d.ts +67 -0
- package/dist/mcp/lib/response-helpers.d.ts.map +1 -0
- package/dist/mcp/lib/response-helpers.js +103 -0
- package/dist/mcp/lib/response-helpers.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +9 -10
- package/dist/mcp/server.js.map +1 -1
- package/dist/models/call-site.d.ts +68 -0
- package/dist/models/call-site.d.ts.map +1 -0
- package/dist/models/call-site.js +60 -0
- package/dist/models/call-site.js.map +1 -0
- package/dist/models/code-skeleton.d.ts +78 -6
- package/dist/models/code-skeleton.d.ts.map +1 -1
- package/dist/models/code-skeleton.js +29 -0
- package/dist/models/code-skeleton.js.map +1 -1
- package/dist/models/drift-item.d.ts +4 -4
- package/dist/models/module-spec.d.ts +155 -94
- package/dist/models/module-spec.d.ts.map +1 -1
- package/dist/panoramic/adr-decision-pipeline.d.ts +53 -0
- package/dist/panoramic/adr-decision-pipeline.d.ts.map +1 -0
- package/dist/panoramic/adr-decision-pipeline.js +685 -0
- package/dist/panoramic/adr-decision-pipeline.js.map +1 -0
- package/dist/panoramic/api-surface-generator.d.ts +56 -0
- package/dist/panoramic/api-surface-generator.d.ts.map +1 -0
- package/dist/panoramic/api-surface-generator.js +1671 -0
- package/dist/panoramic/api-surface-generator.js.map +1 -0
- package/dist/panoramic/architecture-ir-builder.d.ts +19 -0
- package/dist/panoramic/architecture-ir-builder.d.ts.map +1 -0
- package/dist/panoramic/architecture-ir-builder.js +561 -0
- package/dist/panoramic/architecture-ir-builder.js.map +1 -0
- package/dist/panoramic/architecture-ir-exporters.d.ts +7 -0
- package/dist/panoramic/architecture-ir-exporters.d.ts.map +1 -0
- package/dist/panoramic/architecture-ir-exporters.js +183 -0
- package/dist/panoramic/architecture-ir-exporters.js.map +1 -0
- package/dist/panoramic/architecture-ir-generator.d.ts +36 -0
- package/dist/panoramic/architecture-ir-generator.d.ts.map +1 -0
- package/dist/panoramic/architecture-ir-generator.js +51 -0
- package/dist/panoramic/architecture-ir-generator.js.map +1 -0
- package/dist/panoramic/architecture-ir-mermaid-adapter.d.ts +6 -0
- package/dist/panoramic/architecture-ir-mermaid-adapter.d.ts.map +1 -0
- package/dist/panoramic/architecture-ir-mermaid-adapter.js +98 -0
- package/dist/panoramic/architecture-ir-mermaid-adapter.js.map +1 -0
- package/dist/panoramic/architecture-ir-model.d.ts +87 -0
- package/dist/panoramic/architecture-ir-model.d.ts.map +1 -0
- package/dist/panoramic/architecture-ir-model.js +20 -0
- package/dist/panoramic/architecture-ir-model.js.map +1 -0
- package/dist/panoramic/architecture-narrative.d.ts +68 -0
- package/dist/panoramic/architecture-narrative.d.ts.map +1 -0
- package/dist/panoramic/architecture-narrative.js +401 -0
- package/dist/panoramic/architecture-narrative.js.map +1 -0
- package/dist/panoramic/architecture-overview-generator.d.ts +31 -0
- package/dist/panoramic/architecture-overview-generator.d.ts.map +1 -0
- package/dist/panoramic/architecture-overview-generator.js +454 -0
- package/dist/panoramic/architecture-overview-generator.js.map +1 -0
- package/dist/panoramic/architecture-overview-model.d.ts +77 -0
- package/dist/panoramic/architecture-overview-model.d.ts.map +1 -0
- package/dist/panoramic/architecture-overview-model.js +31 -0
- package/dist/panoramic/architecture-overview-model.js.map +1 -0
- package/dist/panoramic/batch-project-docs.d.ts.map +1 -1
- package/dist/panoramic/batch-project-docs.js +4 -2
- package/dist/panoramic/batch-project-docs.js.map +1 -1
- package/dist/panoramic/builders/component-view-builder.d.ts +25 -1
- package/dist/panoramic/builders/component-view-builder.d.ts.map +1 -1
- package/dist/panoramic/builders/component-view-builder.js +83 -3
- package/dist/panoramic/builders/component-view-builder.js.map +1 -1
- package/dist/panoramic/builders/doc-graph-builder.d.ts +2 -2
- package/dist/panoramic/builders/doc-graph-builder.d.ts.map +1 -1
- package/dist/panoramic/builders/doc-graph-builder.js.map +1 -1
- package/dist/panoramic/component-view-builder.d.ts +17 -0
- package/dist/panoramic/component-view-builder.d.ts.map +1 -0
- package/dist/panoramic/component-view-builder.js +652 -0
- package/dist/panoramic/component-view-builder.js.map +1 -0
- package/dist/panoramic/component-view-model.d.ts +127 -0
- package/dist/panoramic/component-view-model.d.ts.map +1 -0
- package/dist/panoramic/component-view-model.js +65 -0
- package/dist/panoramic/component-view-model.js.map +1 -0
- package/dist/panoramic/config-reference-generator.d.ts +78 -0
- package/dist/panoramic/config-reference-generator.d.ts.map +1 -0
- package/dist/panoramic/config-reference-generator.js +199 -0
- package/dist/panoramic/config-reference-generator.js.map +1 -0
- package/dist/panoramic/coverage-auditor.d.ts +95 -0
- package/dist/panoramic/coverage-auditor.d.ts.map +1 -0
- package/dist/panoramic/coverage-auditor.js +290 -0
- package/dist/panoramic/coverage-auditor.js.map +1 -0
- package/dist/panoramic/cross-package-analyzer.d.ts +112 -0
- package/dist/panoramic/cross-package-analyzer.d.ts.map +1 -0
- package/dist/panoramic/cross-package-analyzer.js +258 -0
- package/dist/panoramic/cross-package-analyzer.js.map +1 -0
- package/dist/panoramic/data-model-generator.d.ts +528 -0
- package/dist/panoramic/data-model-generator.d.ts.map +1 -0
- package/dist/panoramic/data-model-generator.js +647 -0
- package/dist/panoramic/data-model-generator.js.map +1 -0
- package/dist/panoramic/doc-graph-builder.d.ts +80 -0
- package/dist/panoramic/doc-graph-builder.d.ts.map +1 -0
- package/dist/panoramic/doc-graph-builder.js +352 -0
- package/dist/panoramic/doc-graph-builder.js.map +1 -0
- package/dist/panoramic/docs-bundle-manifest-reader.d.ts +26 -0
- package/dist/panoramic/docs-bundle-manifest-reader.d.ts.map +1 -0
- package/dist/panoramic/docs-bundle-manifest-reader.js +106 -0
- package/dist/panoramic/docs-bundle-manifest-reader.js.map +1 -0
- package/dist/panoramic/docs-bundle-orchestrator.d.ts +14 -0
- package/dist/panoramic/docs-bundle-orchestrator.d.ts.map +1 -0
- package/dist/panoramic/docs-bundle-orchestrator.js +538 -0
- package/dist/panoramic/docs-bundle-orchestrator.js.map +1 -0
- package/dist/panoramic/docs-bundle-profiles.d.ts +4 -0
- package/dist/panoramic/docs-bundle-profiles.d.ts.map +1 -0
- package/dist/panoramic/docs-bundle-profiles.js +82 -0
- package/dist/panoramic/docs-bundle-profiles.js.map +1 -0
- package/dist/panoramic/docs-bundle-types.d.ts +94 -0
- package/dist/panoramic/docs-bundle-types.d.ts.map +1 -0
- package/dist/panoramic/docs-bundle-types.js +10 -0
- package/dist/panoramic/docs-bundle-types.js.map +1 -0
- package/dist/panoramic/docs-quality-evaluator.d.ts +31 -0
- package/dist/panoramic/docs-quality-evaluator.d.ts.map +1 -0
- package/dist/panoramic/docs-quality-evaluator.js +941 -0
- package/dist/panoramic/docs-quality-evaluator.js.map +1 -0
- package/dist/panoramic/docs-quality-model.d.ts +125 -0
- package/dist/panoramic/docs-quality-model.d.ts.map +1 -0
- package/dist/panoramic/docs-quality-model.js +166 -0
- package/dist/panoramic/docs-quality-model.js.map +1 -0
- package/dist/panoramic/dynamic-scenarios-builder.d.ts +18 -0
- package/dist/panoramic/dynamic-scenarios-builder.d.ts.map +1 -0
- package/dist/panoramic/dynamic-scenarios-builder.js +316 -0
- package/dist/panoramic/dynamic-scenarios-builder.js.map +1 -0
- package/dist/panoramic/event-surface-generator.d.ts +52 -0
- package/dist/panoramic/event-surface-generator.d.ts.map +1 -0
- package/dist/panoramic/event-surface-generator.js +507 -0
- package/dist/panoramic/event-surface-generator.js.map +1 -0
- package/dist/panoramic/generator-registry.d.ts +1 -1
- package/dist/panoramic/generator-registry.d.ts.map +1 -1
- package/dist/panoramic/generator-registry.js +5 -2
- package/dist/panoramic/generator-registry.js.map +1 -1
- package/dist/panoramic/generators/cross-package-analyzer.d.ts +5 -5
- package/dist/panoramic/generators/cross-package-analyzer.d.ts.map +1 -1
- package/dist/panoramic/generators/cross-package-analyzer.js +1 -1
- package/dist/panoramic/generators/cross-package-analyzer.js.map +1 -1
- package/dist/panoramic/generators/data-model-generator.d.ts +27 -27
- package/dist/panoramic/graph/confidence-mapper.d.ts +18 -0
- package/dist/panoramic/graph/confidence-mapper.d.ts.map +1 -1
- package/dist/panoramic/graph/confidence-mapper.js +26 -0
- package/dist/panoramic/graph/confidence-mapper.js.map +1 -1
- package/dist/panoramic/graph/graph-builder.d.ts.map +1 -1
- package/dist/panoramic/graph/graph-builder.js +78 -0
- package/dist/panoramic/graph/graph-builder.js.map +1 -1
- package/dist/panoramic/graph/graph-paths.d.ts +8 -0
- package/dist/panoramic/graph/graph-paths.d.ts.map +1 -1
- package/dist/panoramic/graph/graph-paths.js +10 -0
- package/dist/panoramic/graph/graph-paths.js.map +1 -1
- package/dist/panoramic/graph/graph-query.d.ts +33 -2
- package/dist/panoramic/graph/graph-query.d.ts.map +1 -1
- package/dist/panoramic/graph/graph-query.js +69 -19
- package/dist/panoramic/graph/graph-query.js.map +1 -1
- package/dist/panoramic/graph/graph-types.d.ts +32 -3
- package/dist/panoramic/graph/graph-types.d.ts.map +1 -1
- package/dist/panoramic/hyperedges/schema.d.ts +6 -6
- package/dist/panoramic/interface-surface-generator.d.ts +50 -0
- package/dist/panoramic/interface-surface-generator.d.ts.map +1 -0
- package/dist/panoramic/interface-surface-generator.js +388 -0
- package/dist/panoramic/interface-surface-generator.js.map +1 -0
- package/dist/panoramic/interfaces.d.ts +2 -2
- package/dist/panoramic/mock-readme-generator.d.ts +90 -0
- package/dist/panoramic/mock-readme-generator.d.ts.map +1 -0
- package/dist/panoramic/mock-readme-generator.js +111 -0
- package/dist/panoramic/mock-readme-generator.js.map +1 -0
- package/dist/panoramic/models/component-view-model.d.ts +1 -1
- package/dist/panoramic/models/component-view-model.d.ts.map +1 -1
- package/dist/panoramic/models/component-view-model.js.map +1 -1
- package/dist/panoramic/narrative-provenance-adapter.d.ts +8 -0
- package/dist/panoramic/narrative-provenance-adapter.d.ts.map +1 -0
- package/dist/panoramic/narrative-provenance-adapter.js +99 -0
- package/dist/panoramic/narrative-provenance-adapter.js.map +1 -0
- package/dist/panoramic/parser-registry.d.ts +1 -1
- package/dist/panoramic/parser-registry.js +1 -1
- package/dist/panoramic/parsers/types.d.ts +6 -6
- package/dist/panoramic/pattern-hints-generator.d.ts +28 -0
- package/dist/panoramic/pattern-hints-generator.d.ts.map +1 -0
- package/dist/panoramic/pattern-hints-generator.js +218 -0
- package/dist/panoramic/pattern-hints-generator.js.map +1 -0
- package/dist/panoramic/pattern-hints-model.d.ts +89 -0
- package/dist/panoramic/pattern-hints-model.d.ts.map +1 -0
- package/dist/panoramic/pattern-hints-model.js +61 -0
- package/dist/panoramic/pattern-hints-model.js.map +1 -0
- package/dist/panoramic/pattern-knowledge-base.d.ts +31 -0
- package/dist/panoramic/pattern-knowledge-base.d.ts.map +1 -0
- package/dist/panoramic/pattern-knowledge-base.js +407 -0
- package/dist/panoramic/pattern-knowledge-base.js.map +1 -0
- package/dist/panoramic/pipelines/coverage-auditor.d.ts.map +1 -1
- package/dist/panoramic/pipelines/coverage-auditor.js +4 -2
- package/dist/panoramic/pipelines/coverage-auditor.js.map +1 -1
- package/dist/panoramic/pipelines/docs-bundle-orchestrator.js +13 -6
- package/dist/panoramic/pipelines/docs-bundle-orchestrator.js.map +1 -1
- package/dist/panoramic/pipelines/product-ux-docs.d.ts +5 -0
- package/dist/panoramic/pipelines/product-ux-docs.d.ts.map +1 -1
- package/dist/panoramic/pipelines/product-ux-docs.js +34 -6
- package/dist/panoramic/pipelines/product-ux-docs.js.map +1 -1
- package/dist/panoramic/product-ux-docs.d.ts +104 -0
- package/dist/panoramic/product-ux-docs.d.ts.map +1 -0
- package/dist/panoramic/product-ux-docs.js +817 -0
- package/dist/panoramic/product-ux-docs.js.map +1 -0
- package/dist/panoramic/qa/__tests__/citation.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/citation.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/citation.test.js +193 -0
- package/dist/panoramic/qa/__tests__/citation.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/debt-context.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/debt-context.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/debt-context.test.js +154 -0
- package/dist/panoramic/qa/__tests__/debt-context.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/graph-retriever.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/graph-retriever.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/graph-retriever.test.js +148 -0
- package/dist/panoramic/qa/__tests__/graph-retriever.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/index.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/index.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/index.test.js +246 -0
- package/dist/panoramic/qa/__tests__/index.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/llm-caller.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/llm-caller.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/llm-caller.test.js +168 -0
- package/dist/panoramic/qa/__tests__/llm-caller.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/prompt-builder.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/prompt-builder.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/prompt-builder.test.js +150 -0
- package/dist/panoramic/qa/__tests__/prompt-builder.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/qa-integration.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/qa-integration.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/qa-integration.test.js +296 -0
- package/dist/panoramic/qa/__tests__/qa-integration.test.js.map +1 -0
- package/dist/panoramic/qa/__tests__/rag-reranker.test.d.ts +2 -0
- package/dist/panoramic/qa/__tests__/rag-reranker.test.d.ts.map +1 -0
- package/dist/panoramic/qa/__tests__/rag-reranker.test.js +136 -0
- package/dist/panoramic/qa/__tests__/rag-reranker.test.js.map +1 -0
- package/dist/panoramic/qa/index.d.ts.map +1 -1
- package/dist/panoramic/qa/index.js +10 -3
- package/dist/panoramic/qa/index.js.map +1 -1
- package/dist/panoramic/runtime-topology-generator.d.ts +77 -0
- package/dist/panoramic/runtime-topology-generator.d.ts.map +1 -0
- package/dist/panoramic/runtime-topology-generator.js +676 -0
- package/dist/panoramic/runtime-topology-generator.js.map +1 -0
- package/dist/panoramic/runtime-topology-model.d.ts +145 -0
- package/dist/panoramic/runtime-topology-model.d.ts.map +1 -0
- package/dist/panoramic/runtime-topology-model.js +300 -0
- package/dist/panoramic/runtime-topology-model.js.map +1 -0
- package/dist/panoramic/troubleshooting-generator.d.ts +51 -0
- package/dist/panoramic/troubleshooting-generator.d.ts.map +1 -0
- package/dist/panoramic/troubleshooting-generator.js +451 -0
- package/dist/panoramic/troubleshooting-generator.js.map +1 -0
- package/dist/panoramic/utils/text-segmenter.d.ts +15 -0
- package/dist/panoramic/utils/text-segmenter.d.ts.map +1 -1
- package/dist/panoramic/utils/text-segmenter.js +38 -0
- package/dist/panoramic/utils/text-segmenter.js.map +1 -1
- package/dist/panoramic/workspace-index-generator.d.ts +148 -0
- package/dist/panoramic/workspace-index-generator.d.ts.map +1 -0
- package/dist/panoramic/workspace-index-generator.js +497 -0
- package/dist/panoramic/workspace-index-generator.js.map +1 -0
- package/dist/runtime-bootstrap.d.ts +9 -0
- package/dist/runtime-bootstrap.d.ts.map +1 -0
- package/dist/runtime-bootstrap.js +33 -0
- package/dist/runtime-bootstrap.js.map +1 -0
- package/dist/utils/file-scanner.js +1 -1
- package/dist/utils/file-scanner.js.map +1 -1
- package/package.json +12 -2
- package/plugins/spec-driver/.claude-plugin/plugin.json +1 -1
- package/plugins/spec-driver/README.md +18 -1
- package/plugins/spec-driver/agents/implement.md +20 -1
- package/plugins/spec-driver/agents/plan.md +20 -1
- package/plugins/spec-driver/agents/quality-review.md +20 -1
- package/plugins/spec-driver/agents/spec-review.md +20 -1
- package/plugins/spec-driver/agents/verify.md +20 -1
- package/plugins/spec-driver/docs/customization.md +134 -0
- package/plugins/spec-driver/docs/spectra-mcp-integration.md +165 -0
- package/plugins/spec-driver/lib/preference-rules.mjs +96 -0
- package/plugins/spec-driver/scripts/postinstall.sh +1 -1
- package/plugins/spec-driver/scripts/sync-preference-rules.mjs +148 -0
- package/plugins/spec-driver/skills/spec-driver-feature/SKILL.md +10 -0
- package/plugins/spec-driver/skills/spec-driver-fix/SKILL.md +10 -0
- package/plugins/spec-driver/skills/spec-driver-implement/SKILL.md +10 -0
- package/plugins/spec-driver/skills/spec-driver-refactor/SKILL.md +10 -0
- package/plugins/spec-driver/skills/spec-driver-story/SKILL.md +10 -0
- package/plugins/spec-driver/templates/preference-rules.md +39 -0
- package/plugins/spectra/.claude-plugin/plugin.json +1 -1
- package/plugins/spectra/README.md +48 -1
- package/plugins/spectra/hooks/post-commit.sh +40 -0
- package/templates/product-overview.hbs +1 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Spectra MCP 集成指引
|
|
2
|
+
|
|
3
|
+
本文档说明如何将 **Spectra** 和 **Spec Driver** 两个 Claude Code plugin 协同部署,让 spec-driver 的 sub-agent 能够调用 spectra 的 MCP 工具(`impact` / `context` / `detect_changes`)。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 一、为什么需要协同部署
|
|
8
|
+
|
|
9
|
+
Spec Driver 的核心 sub-agent(`plan` / `implement` / `verify` / `spec-review` / `quality-review`)在工作时需要感知代码库的符号依赖关系。这些能力由 Spectra 的 MCP 工具提供:
|
|
10
|
+
|
|
11
|
+
| Spectra MCP 工具 | 用途 |
|
|
12
|
+
|-----------------|------|
|
|
13
|
+
| `mcp__plugin_spectra_spectra__context` | 获取指定符号的 360° 上下文(定义 + 调用方 + 被调用方 + 相关 spec) |
|
|
14
|
+
| `mcp__plugin_spectra_spectra__impact` | blast radius 分析 — 反向 BFS 找受影响的所有符号 |
|
|
15
|
+
| `mcp__plugin_spectra_spectra__detect_changes` | git diff → changedSymbols → impact 链 |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 二、为什么 namespace 是 `mcp__plugin_spectra_spectra__*`
|
|
20
|
+
|
|
21
|
+
Claude Code plugin 系统会根据以下规则自动生成 MCP 工具的命名空间:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
mcp__plugin_{plugin-name}_{mcp-server-name}__{tool-name}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
对于 spectra plugin:
|
|
28
|
+
- **plugin-name**: `spectra`(`plugin.json` 中的 `name` 字段)
|
|
29
|
+
- **mcp-server-name**: `spectra`(`.mcp.json` 中的 server key)
|
|
30
|
+
- **tool-name**: `context` / `impact` / `detect_changes`
|
|
31
|
+
|
|
32
|
+
因此完整 namespace 为 `mcp__plugin_spectra_spectra__context` 等。
|
|
33
|
+
|
|
34
|
+
> **长期 follow-up**: Anthropic 正在讨论 plugin `namespaceStrategy` RFC,未来可能允许插件声明简洁 namespace(如 `mcp__spectra__*`)。RFC 落地后可将 sub-agent frontmatter 改回简洁版本。
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 三、2 步开箱即用部署
|
|
39
|
+
|
|
40
|
+
### Step 1: 安装两个 plugin
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
claude plugin install spectra
|
|
44
|
+
claude plugin install spec-driver
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
或从本仓库本地安装:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
claude plugin install ./plugins/spectra
|
|
51
|
+
claude plugin install ./plugins/spec-driver
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Step 2: 验证安装
|
|
55
|
+
|
|
56
|
+
在 Claude Code 中运行:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
/spec-driver:spec-driver-feature 描述一个简单需求
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
如果 `plan` sub-agent 能够在分析时调用 `mcp__plugin_spectra_spectra__context`,则集成成功。
|
|
63
|
+
|
|
64
|
+
无需任何额外配置——sub-agent 的 frontmatter 已预置正确 plugin namespace。
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 四、故障排查
|
|
69
|
+
|
|
70
|
+
### 问题 1: `plugin:spectra:spectra:failed` 或 MCP server 启动失败
|
|
71
|
+
|
|
72
|
+
**可能原因**:
|
|
73
|
+
- spectra-cli 版本过旧(< 4.2.0),缺少 Feature 155 agent-context tools
|
|
74
|
+
- volta / node 版本不兼容
|
|
75
|
+
|
|
76
|
+
**排查步骤**:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# 检查当前安装版本
|
|
80
|
+
spectra --version
|
|
81
|
+
|
|
82
|
+
# 应为 4.2.0+,否则更新
|
|
83
|
+
npm install -g spectra-cli@latest
|
|
84
|
+
|
|
85
|
+
# 验证 agent-context-tools 已包含
|
|
86
|
+
ls $(npm root -g)/spectra-cli/dist/mcp/agent-context-tools.js
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 问题 2: sub-agent 提示"工具 mcp__plugin_spectra_spectra__context 不可用"
|
|
90
|
+
|
|
91
|
+
**可能原因**:
|
|
92
|
+
1. spectra plugin 未安装 → 执行 Step 1 安装
|
|
93
|
+
2. spectra MCP server 启动失败 → 查看 `claude plugin status spectra`
|
|
94
|
+
3. 当前项目没有 spectra graph 缓存 → 先运行 `spectra run .` 生成 graph
|
|
95
|
+
|
|
96
|
+
**快速验证**:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# 确认 spectra plugin 正常
|
|
100
|
+
claude plugin status spectra
|
|
101
|
+
|
|
102
|
+
# 手动生成 graph(首次使用需要)
|
|
103
|
+
spectra run .
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 问题 3: fork 了 spectra plugin,namespace 不一致
|
|
107
|
+
|
|
108
|
+
如果你 fork 了 spectra plugin 并改名(如 `my-spectra-fork`),sub-agent 需要使用不同的 namespace。
|
|
109
|
+
|
|
110
|
+
详见 [customization.md](./customization.md)。
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 五、验证矩阵
|
|
115
|
+
|
|
116
|
+
| 验证项 | 命令 | 预期结果 |
|
|
117
|
+
|--------|------|----------|
|
|
118
|
+
| spectra 版本 | `spectra --version` | `4.2.0` |
|
|
119
|
+
| agent-context-tools 存在 | `ls $(npm root -g)/spectra-cli/dist/mcp/` | 含 `agent-context-tools.js` |
|
|
120
|
+
| spectra plugin 状态 | `claude plugin status spectra` | `active` |
|
|
121
|
+
| spec-driver sub-agent namespace | grep frontmatter | 含 `mcp__plugin_spectra_spectra__` |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 七、Driver 偏好引导设计(F170d)
|
|
126
|
+
|
|
127
|
+
### 为什么需要这层引导
|
|
128
|
+
|
|
129
|
+
F170c 实测(host shell N=10×4 轮)发现:driver(Claude Sonnet 4.6)在「评估 symbol 改动影响」类任务上 **0/10 主动调用** spectra `impact`,而是默认 1 Read + 6 Grep。即使把 tool description 升级到 100-500 字 + 4 要素 + 显式 chained usage,主动调用率仍是 **0%**。
|
|
130
|
+
|
|
131
|
+
**业务洞察**:tool description 只提供「理论可用性」(这个工具能做什么),不能改变 driver 的工具选择**偏好**。Grep 是 Anthropic 训练数据中 caller-analysis 的默认工具,cognitive overhead 更低。要改变偏好,必须在 **prompt level** 提供「任务匹配性」引导——明确告诉 driver「什么任务该用什么工具」。
|
|
132
|
+
|
|
133
|
+
F170d 因此在两处注入引导:
|
|
134
|
+
1. **5 个 sub-agent**(plan / implement / verify / spec-review / quality-review)的 prompt body 内嵌「工具优先使用规则」表(按各 agent frontmatter `tools` 过滤)。agent body 即 Claude Code 子代理的 system prompt,故引导随子代理上下文抵达 driver。
|
|
135
|
+
2. **5 个主编排器 SKILL.md** 的「子代理调度时的工具优先级提示」块,要求编排器 dispatch 时在 `Task()` prompt 中显式带上工具优先级提示。
|
|
136
|
+
|
|
137
|
+
### 单一事实源与一致性守护
|
|
138
|
+
|
|
139
|
+
引导文案的 canonical source 是 [`templates/preference-rules.md`](../templates/preference-rules.md)(R1-R4 规则 + 关键原则,anchor 标记)。三处消费方(agent 文件 / SKILL 提示 / F170d harness 注入)都从它派生:
|
|
140
|
+
|
|
141
|
+
- **生成**:`node plugins/spec-driver/scripts/sync-preference-rules.mjs --write` 按各 agent `tools` 过滤渲染并写入 `<!-- BEGIN/END preference-rules -->` 之间。
|
|
142
|
+
- **守护**:`npm run repo:check` 的 `preference-rules:agent-block-sync` 检测漂移(同 `--check`),保证 5 个 agent 块永不与单一源脱节。
|
|
143
|
+
|
|
144
|
+
### 度量诚实声明(guided vs spontaneous)
|
|
145
|
+
|
|
146
|
+
F170d 的 SC-002 度量命名为 **guided active-call rate**:它测的是「引导送达 driver 后,driver 是否遵循引导改用 MCP」,**不等于** F170c 测的「spontaneous preference(内在偏好)」。0%(无引导)→ ≥50%(有引导)的对比意义是 **「prompt 层引导能驱动 driver 改用 MCP」**,不宣称「模型内在偏好被改变」。
|
|
147
|
+
|
|
148
|
+
### fork 用户自定义(override 机制)
|
|
149
|
+
|
|
150
|
+
fork 用户想调整引导文案(增删规则行、改语气 SHOULD↔MUST、换工具优先级):
|
|
151
|
+
|
|
152
|
+
1. 编辑 `plugins/spec-driver/templates/preference-rules.md` 的 `block-start`/`block-end` 之间内容(保持 anchor 契约 `<!-- preference-rules:R# tool=xxx -->`)。
|
|
153
|
+
2. 跑 `node plugins/spec-driver/scripts/sync-preference-rules.mjs --write` 重新生成 5 个 agent 块(按各自 tools 自动过滤)。
|
|
154
|
+
3. 跑 `npm run repo:check` 确认 `preference-rules:agent-block-sync` 通过。
|
|
155
|
+
|
|
156
|
+
无需改任何脚本逻辑——template 是唯一需要编辑的文件。
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 八、相关资源
|
|
161
|
+
|
|
162
|
+
- [Spectra MCP Server 源码](../../src/mcp/server.ts)
|
|
163
|
+
- [fork 用户定制指引](./customization.md)
|
|
164
|
+
- [Milestone M7 设计文档](../../docs/design/milestone-M7-spectra-mcp-productization.md)
|
|
165
|
+
- [F170d spec](../../specs/170d-driver-preference-shaping/spec.md) · [preference-rules 单一源](../templates/preference-rules.md)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* preference-rules — 「工具优先使用规则」渲染核心(plugin-owned,自包含,无 root 依赖)
|
|
3
|
+
*
|
|
4
|
+
* canonical 渲染逻辑:从 templates/preference-rules.md 的 canonical 块按 agent frontmatter
|
|
5
|
+
* tools 过滤规则行。被三处消费:
|
|
6
|
+
* - plugins/spec-driver/scripts/sync-preference-rules.mjs(生成 agent 块)
|
|
7
|
+
* - scripts/feature-170d-driver-preference.mjs(harness 注入,经 driver-eval-core 复用)
|
|
8
|
+
* - tests(经 driver-eval-core re-export)
|
|
9
|
+
*
|
|
10
|
+
* 设计意图:plugin 必须自包含(发布后不依赖仓库 root scripts/),故渲染逻辑落在 plugin lib。
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const NS = 'mcp__plugin_spectra_spectra__';
|
|
14
|
+
export const BEGIN_MARKER = '<!-- BEGIN preference-rules (generated from templates/preference-rules.md; do not edit) -->';
|
|
15
|
+
export const END_MARKER = '<!-- END preference-rules -->';
|
|
16
|
+
|
|
17
|
+
const ROW_ANCHOR_RE = /<!--\s*preference-rules:(R\d)\s+tool=([a-z_]+)\s*-->/;
|
|
18
|
+
const ROWS_END_RE = /<!--\s*\/preference-rules:rows\s*-->/;
|
|
19
|
+
const SKIP_MARKER_RE = /<!--\s*preference-rules:(block-start|block-end|meta\b[^>]*)\s*-->/;
|
|
20
|
+
const BLOCK_START_RE = /<!--\s*preference-rules:block-start\s*-->/;
|
|
21
|
+
const BLOCK_END_RE = /<!--\s*preference-rules:block-end\s*-->/;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 提取 canonical 块文本:若含 block-start/block-end marker 则取其间内容;
|
|
25
|
+
* 否则原样返回(兼容仅传 block 内容的调用,如单测合成 TPL)。
|
|
26
|
+
*/
|
|
27
|
+
export function extractCanonicalBlock(templateText) {
|
|
28
|
+
const lines = String(templateText ?? '').split('\n');
|
|
29
|
+
const start = lines.findIndex((l) => BLOCK_START_RE.test(l));
|
|
30
|
+
if (start < 0) return String(templateText ?? '');
|
|
31
|
+
let end = -1;
|
|
32
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
33
|
+
if (BLOCK_END_RE.test(lines[i])) { end = i; break; }
|
|
34
|
+
}
|
|
35
|
+
// fail-loud(codex C3):有 block-start 却无 block-end → template 损坏,禁止静默截断到 EOF
|
|
36
|
+
if (end < 0) {
|
|
37
|
+
throw new Error('[preference-rules] template 含 block-start 但缺 block-end,拒绝静默截断');
|
|
38
|
+
}
|
|
39
|
+
return lines.slice(start + 1, end).join('\n');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** 从 fully-qualified agentTools 提取 toolKey 集合(impact/context/detect_changes)。 */
|
|
43
|
+
export function toolKeysFromAgentTools(agentTools) {
|
|
44
|
+
const keys = new Set();
|
|
45
|
+
for (const t of agentTools || []) {
|
|
46
|
+
if (typeof t === 'string' && t.startsWith(NS)) keys.add(t.slice(NS.length));
|
|
47
|
+
}
|
|
48
|
+
return keys;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** 解析 agent .md frontmatter 的 tools: 行,返回 fully-qualified spectra MCP 工具数组。 */
|
|
52
|
+
export function parseFrontmatterTools(agentText) {
|
|
53
|
+
const m = String(agentText ?? '').match(/^tools:\s*\[(.*)\]/m);
|
|
54
|
+
if (!m) return [];
|
|
55
|
+
const re = new RegExp(`${NS}\\w+`, 'g');
|
|
56
|
+
return m[1].match(re) ?? [];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 纯函数:按 agentTools 过滤 canonical 块的规则行,渲染「工具优先使用规则」块。
|
|
61
|
+
* 入参可为完整 template 文本(含 block-start/block-end)或仅 block 内容;二者皆可。
|
|
62
|
+
* 输出不含任何 anchor / block 注释。
|
|
63
|
+
* @param {string} templateText
|
|
64
|
+
* @param {string[]} agentTools 形如 ['mcp__plugin_spectra_spectra__impact', ...]
|
|
65
|
+
* @returns {string}
|
|
66
|
+
*/
|
|
67
|
+
export function renderInjectionBlock(templateText, agentTools) {
|
|
68
|
+
const keys = toolKeysFromAgentTools(agentTools);
|
|
69
|
+
// 先抽取 canonical 块(丢弃 template 文件的人类文档头),再过滤规则行
|
|
70
|
+
const lines = extractCanonicalBlock(templateText).split('\n');
|
|
71
|
+
const out = [];
|
|
72
|
+
let inRows = false;
|
|
73
|
+
|
|
74
|
+
for (let i = 0; i < lines.length; i++) {
|
|
75
|
+
const line = lines[i];
|
|
76
|
+
if (SKIP_MARKER_RE.test(line)) continue;
|
|
77
|
+
const anchor = line.match(ROW_ANCHOR_RE);
|
|
78
|
+
if (anchor) {
|
|
79
|
+
inRows = true;
|
|
80
|
+
const tool = anchor[2];
|
|
81
|
+
const rowLine = lines[i + 1] ?? '';
|
|
82
|
+
if (keys.has(tool)) out.push(rowLine);
|
|
83
|
+
i++;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (ROWS_END_RE.test(line)) { inRows = false; continue; }
|
|
87
|
+
if (inRows) continue;
|
|
88
|
+
out.push(line);
|
|
89
|
+
}
|
|
90
|
+
return out.join('\n').replace(/\n{3,}/g, '\n\n').trim() + '\n';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** 将渲染块包裹 BEGIN/END marker(供 agent 文件嵌入)。 */
|
|
94
|
+
export function wrapWithMarkers(renderedBlock) {
|
|
95
|
+
return `${BEGIN_MARKER}\n${renderedBlock.trimEnd()}\n${END_MARKER}`;
|
|
96
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sync-preference-rules — 从 templates/preference-rules.md 单一事实源,按各 agent frontmatter
|
|
4
|
+
* tools 过滤渲染「工具优先使用规则」块,写入 5 个 agent 文件的 BEGIN/END marker 之间。
|
|
5
|
+
*
|
|
6
|
+
* 用法:
|
|
7
|
+
* node plugins/spec-driver/scripts/sync-preference-rules.mjs --write # 生成/更新(默认)
|
|
8
|
+
* node plugins/spec-driver/scripts/sync-preference-rules.mjs --check # 漂移检测(CI/repo:check)
|
|
9
|
+
*
|
|
10
|
+
* 插入锚点(首次):`## 角色` 段之后、下一个 `## ` 标题之前;无 `## 角色` 则首个 `## ` 前。
|
|
11
|
+
* 已有 marker:仅替换 marker 之间内容(锚点不移动)。
|
|
12
|
+
*
|
|
13
|
+
* 退出码:0 = 无漂移 / 写入完成;1 = --check 检测到漂移。
|
|
14
|
+
*/
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import path from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
import {
|
|
19
|
+
renderInjectionBlock,
|
|
20
|
+
parseFrontmatterTools,
|
|
21
|
+
wrapWithMarkers,
|
|
22
|
+
BEGIN_MARKER,
|
|
23
|
+
END_MARKER,
|
|
24
|
+
} from '../lib/preference-rules.mjs';
|
|
25
|
+
|
|
26
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
const PLUGIN_DIR = path.resolve(__dirname, '..');
|
|
28
|
+
const TEMPLATE_PATH = path.join(PLUGIN_DIR, 'templates/preference-rules.md');
|
|
29
|
+
const AGENTS = ['plan', 'implement', 'verify', 'spec-review', 'quality-review'];
|
|
30
|
+
|
|
31
|
+
/** 计算 agent 文件应有的内容(插入或替换 marker 块)。 */
|
|
32
|
+
export function computeExpectedAgentContent(agentText, templateText) {
|
|
33
|
+
const tools = parseFrontmatterTools(agentText);
|
|
34
|
+
const rendered = renderInjectionBlock(templateText, tools);
|
|
35
|
+
const wrapped = wrapWithMarkers(rendered);
|
|
36
|
+
|
|
37
|
+
const beginIdx = agentText.indexOf(BEGIN_MARKER);
|
|
38
|
+
// 在 BEGIN 之后查找 END,避免匹配到文档引用里的字面 marker
|
|
39
|
+
const endIdx = beginIdx >= 0 ? agentText.indexOf(END_MARKER, beginIdx + BEGIN_MARKER.length) : -1;
|
|
40
|
+
if (beginIdx >= 0 && endIdx > beginIdx) {
|
|
41
|
+
// 替换现有 marker 区(含 marker 本身)
|
|
42
|
+
const before = agentText.slice(0, beginIdx);
|
|
43
|
+
const after = agentText.slice(endIdx + END_MARKER.length);
|
|
44
|
+
return before + wrapped + after;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 首次插入:定位锚点
|
|
48
|
+
const lines = agentText.split('\n');
|
|
49
|
+
const roleIdx = lines.findIndex((l) => /^##\s+角色/.test(l));
|
|
50
|
+
let insertAt;
|
|
51
|
+
if (roleIdx >= 0) {
|
|
52
|
+
insertAt = lines.findIndex((l, i) => i > roleIdx && /^##\s/.test(l));
|
|
53
|
+
if (insertAt < 0) insertAt = lines.length; // 角色 是最后一段
|
|
54
|
+
} else {
|
|
55
|
+
insertAt = lines.findIndex((l) => /^##\s/.test(l));
|
|
56
|
+
if (insertAt < 0) insertAt = lines.length;
|
|
57
|
+
}
|
|
58
|
+
const head = lines.slice(0, insertAt).join('\n').replace(/\n+$/, '');
|
|
59
|
+
const tail = lines.slice(insertAt).join('\n').replace(/^\n+/, '');
|
|
60
|
+
return `${head}\n\n${wrapped}\n\n${tail}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function agentPath(name, pluginDir = PLUGIN_DIR) {
|
|
64
|
+
return path.join(pluginDir, 'agents', `${name}.md`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 供 repo:check(repo-maintenance-core)复用的漂移校验:
|
|
69
|
+
* 返回 { checks, warnings, errors },与 aggregateValidation 契约一致。
|
|
70
|
+
*/
|
|
71
|
+
export function validatePreferenceRules({ projectRoot } = {}) {
|
|
72
|
+
const root = projectRoot ? path.resolve(projectRoot) : path.resolve(PLUGIN_DIR, '../..');
|
|
73
|
+
const pluginDir = path.join(root, 'plugins/spec-driver');
|
|
74
|
+
const templatePath = path.join(pluginDir, 'templates/preference-rules.md');
|
|
75
|
+
const errors = [];
|
|
76
|
+
const drifted = [];
|
|
77
|
+
|
|
78
|
+
if (!fs.existsSync(templatePath)) {
|
|
79
|
+
return { checks: [{ id: 'agent-block-sync', title: 'preference-rules 单一源同步', status: 'fail', evidence: { reason: 'template 缺失' } }], warnings: [], errors: ['template 缺失: templates/preference-rules.md'] };
|
|
80
|
+
}
|
|
81
|
+
const templateText = fs.readFileSync(templatePath, 'utf-8');
|
|
82
|
+
for (const agent of AGENTS) {
|
|
83
|
+
const p = agentPath(agent, pluginDir);
|
|
84
|
+
if (!fs.existsSync(p)) { drifted.push(`${agent}(缺失)`); errors.push(`agent 文件缺失: ${agent}.md`); continue; }
|
|
85
|
+
const actual = fs.readFileSync(p, 'utf-8');
|
|
86
|
+
if (actual !== computeExpectedAgentContent(actual, templateText)) {
|
|
87
|
+
drifted.push(agent);
|
|
88
|
+
errors.push(`${agent}.md preference-rules 块与 template 漂移;运行 sync-preference-rules.mjs --write`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const status = drifted.length > 0 ? 'fail' : 'pass';
|
|
92
|
+
return {
|
|
93
|
+
checks: [{ id: 'agent-block-sync', title: '5 agent preference-rules 块与单一源一致', status, evidence: { drifted } }],
|
|
94
|
+
warnings: [],
|
|
95
|
+
errors,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 计算 plugin/template/agent 路径(projectRoot 可选,默认 module-relative)。 */
|
|
100
|
+
function resolvePaths(projectRoot) {
|
|
101
|
+
const root = projectRoot ? path.resolve(projectRoot) : path.resolve(PLUGIN_DIR, '../..');
|
|
102
|
+
const pluginDir = path.join(root, 'plugins/spec-driver');
|
|
103
|
+
return { pluginDir, templatePath: path.join(pluginDir, 'templates/preference-rules.md') };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 程序化写入(repo:sync 复用):按 template 重新生成 5 agent 的 preference-rules 块。
|
|
108
|
+
* 返回 { written: string[] }。
|
|
109
|
+
*/
|
|
110
|
+
export function syncPreferenceRules({ projectRoot } = {}) {
|
|
111
|
+
const { pluginDir, templatePath } = resolvePaths(projectRoot);
|
|
112
|
+
if (!fs.existsSync(templatePath)) {
|
|
113
|
+
throw new Error(`[sync-preference-rules] template 不存在: ${templatePath}`);
|
|
114
|
+
}
|
|
115
|
+
const templateText = fs.readFileSync(templatePath, 'utf-8');
|
|
116
|
+
const written = [];
|
|
117
|
+
for (const agent of AGENTS) {
|
|
118
|
+
const p = agentPath(agent, pluginDir);
|
|
119
|
+
if (!fs.existsSync(p)) throw new Error(`[sync-preference-rules] agent 文件不存在: ${p}`);
|
|
120
|
+
const actual = fs.readFileSync(p, 'utf-8');
|
|
121
|
+
const expected = computeExpectedAgentContent(actual, templateText);
|
|
122
|
+
if (actual !== expected) { fs.writeFileSync(p, expected, 'utf-8'); written.push(agent); }
|
|
123
|
+
}
|
|
124
|
+
return { written };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function run(mode) {
|
|
128
|
+
if (mode === 'check') {
|
|
129
|
+
const result = validatePreferenceRules({});
|
|
130
|
+
if (result.errors.length > 0) {
|
|
131
|
+
result.errors.forEach((e) => console.error(`[sync-preference-rules] ${e}`));
|
|
132
|
+
console.error(' 运行 `node plugins/spec-driver/scripts/sync-preference-rules.mjs --write` 重新同步');
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
console.log('[sync-preference-rules] 无漂移 ✅');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const { written } = syncPreferenceRules({});
|
|
139
|
+
written.forEach((a) => console.log(`[sync-preference-rules] 已更新 ${a}.md`));
|
|
140
|
+
console.log(`[sync-preference-rules] 完成(更新 ${written.length} 个 agent 文件)`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const isCliEntry = process.argv[1] != null
|
|
144
|
+
&& path.resolve(process.argv[1]).endsWith('sync-preference-rules.mjs');
|
|
145
|
+
if (isCliEntry) {
|
|
146
|
+
const mode = process.argv.includes('--check') ? 'check' : 'write';
|
|
147
|
+
run(mode);
|
|
148
|
+
}
|
|
@@ -122,6 +122,16 @@ done
|
|
|
122
122
|
|
|
123
123
|
---
|
|
124
124
|
|
|
125
|
+
## 子代理调度时的工具优先级提示
|
|
126
|
+
|
|
127
|
+
主编排器在 dispatch 子代理时,**显式在 `Task()` prompt 中包含**以下提示(理由见各 sub-agent frontmatter 的「工具优先使用规则」章节,单一事实源:`plugins/spec-driver/templates/preference-rules.md`):
|
|
128
|
+
|
|
129
|
+
> 提示:本任务可能涉及 caller analysis / impact 评估 / git diff 影响分析。
|
|
130
|
+
> **优先使用 `mcp__plugin_spectra_spectra__*` 工具**(`impact` / `context` / `detect_changes`)而非默认 Read/Grep——
|
|
131
|
+
> 它们提供 transitive 依赖深度、BFS 受影响 symbol 列表与 nextStepHint 链式引导;Grep 仅作 MCP 不可用(graph-not-built)时的 fallback。
|
|
132
|
+
|
|
133
|
+
该提示与 5 个 sub-agent prompt body 的「工具优先使用规则」表共享单一事实源(`templates/preference-rules.md`),由 `scripts/sync-preference-rules.mjs` 守护一致性。
|
|
134
|
+
|
|
125
135
|
## 并行执行策略
|
|
126
136
|
|
|
127
137
|
本编排流程使用以下并行组(通过 `orchestration.yaml` 定义):
|
|
@@ -139,6 +139,16 @@ Gate 行为表由 `orchestration.yaml` + `spec-driver.config.yaml` 联合决定
|
|
|
139
139
|
|
|
140
140
|
---
|
|
141
141
|
|
|
142
|
+
## 子代理调度时的工具优先级提示
|
|
143
|
+
|
|
144
|
+
主编排器在 dispatch 子代理时,**显式在 `Task()` prompt 中包含**以下提示(理由见各 sub-agent frontmatter 的「工具优先使用规则」章节,单一事实源:`plugins/spec-driver/templates/preference-rules.md`):
|
|
145
|
+
|
|
146
|
+
> 提示:本任务可能涉及 caller analysis / impact 评估 / git diff 影响分析。
|
|
147
|
+
> **优先使用 `mcp__plugin_spectra_spectra__*` 工具**(`impact` / `context` / `detect_changes`)而非默认 Read/Grep——
|
|
148
|
+
> 它们提供 transitive 依赖深度、BFS 受影响 symbol 列表与 nextStepHint 链式引导;Grep 仅作 MCP 不可用(graph-not-built)时的 fallback。
|
|
149
|
+
|
|
150
|
+
该提示与 5 个 sub-agent prompt body 的「工具优先使用规则」表共享单一事实源(`templates/preference-rules.md`),由 `scripts/sync-preference-rules.mjs` 守护一致性。
|
|
151
|
+
|
|
142
152
|
## 并行执行策略
|
|
143
153
|
|
|
144
154
|
本编排流程在以下阶段使用并行调度以缩短总耗时:
|
|
@@ -241,6 +241,16 @@ implement:
|
|
|
241
241
|
|
|
242
242
|
---
|
|
243
243
|
|
|
244
|
+
## 子代理调度时的工具优先级提示
|
|
245
|
+
|
|
246
|
+
主编排器在 dispatch 子代理时,**显式在 `Task()` prompt 中包含**以下提示(理由见各 sub-agent frontmatter 的「工具优先使用规则」章节,单一事实源:`plugins/spec-driver/templates/preference-rules.md`):
|
|
247
|
+
|
|
248
|
+
> 提示:本任务可能涉及 caller analysis / impact 评估 / git diff 影响分析。
|
|
249
|
+
> **优先使用 `mcp__plugin_spectra_spectra__*` 工具**(`impact` / `context` / `detect_changes`)而非默认 Read/Grep——
|
|
250
|
+
> 它们提供 transitive 依赖深度、BFS 受影响 symbol 列表与 nextStepHint 链式引导;Grep 仅作 MCP 不可用(graph-not-built)时的 fallback。
|
|
251
|
+
|
|
252
|
+
该提示与 5 个 sub-agent prompt body 的「工具优先使用规则」表共享单一事实源(`templates/preference-rules.md`),由 `scripts/sync-preference-rules.mjs` 守护一致性。
|
|
253
|
+
|
|
244
254
|
## 工作流定义
|
|
245
255
|
|
|
246
256
|
### 6 阶段聚焦实施流程
|
|
@@ -93,6 +93,16 @@ done
|
|
|
93
93
|
|
|
94
94
|
---
|
|
95
95
|
|
|
96
|
+
## 子代理调度时的工具优先级提示
|
|
97
|
+
|
|
98
|
+
主编排器在 dispatch 子代理时,**显式在 `Task()` prompt 中包含**以下提示(理由见各 sub-agent frontmatter 的「工具优先使用规则」章节,单一事实源:`plugins/spec-driver/templates/preference-rules.md`):
|
|
99
|
+
|
|
100
|
+
> 提示:本任务可能涉及 caller analysis / impact 评估 / git diff 影响分析。
|
|
101
|
+
> **优先使用 `mcp__plugin_spectra_spectra__*` 工具**(`impact` / `context` / `detect_changes`)而非默认 Read/Grep——
|
|
102
|
+
> 它们提供 transitive 依赖深度、BFS 受影响 symbol 列表与 nextStepHint 链式引导;Grep 仅作 MCP 不可用(graph-not-built)时的 fallback。
|
|
103
|
+
|
|
104
|
+
该提示与 5 个 sub-agent prompt body 的「工具优先使用规则」表共享单一事实源(`templates/preference-rules.md`),由 `scripts/sync-preference-rules.mjs` 守护一致性。
|
|
105
|
+
|
|
96
106
|
## 工作流定义(5 阶段)
|
|
97
107
|
|
|
98
108
|
### Phase 1: 影响分析 [1/5]
|
|
@@ -211,6 +211,16 @@ prompt_source[verify] = "$PLUGIN_DIR/agents/verify.md"
|
|
|
211
211
|
|
|
212
212
|
---
|
|
213
213
|
|
|
214
|
+
## 子代理调度时的工具优先级提示
|
|
215
|
+
|
|
216
|
+
主编排器在 dispatch 子代理时,**显式在 `Task()` prompt 中包含**以下提示(理由见各 sub-agent frontmatter 的「工具优先使用规则」章节,单一事实源:`plugins/spec-driver/templates/preference-rules.md`):
|
|
217
|
+
|
|
218
|
+
> 提示:本任务可能涉及 caller analysis / impact 评估 / git diff 影响分析。
|
|
219
|
+
> **优先使用 `mcp__plugin_spectra_spectra__*` 工具**(`impact` / `context` / `detect_changes`)而非默认 Read/Grep——
|
|
220
|
+
> 它们提供 transitive 依赖深度、BFS 受影响 symbol 列表与 nextStepHint 链式引导;Grep 仅作 MCP 不可用(graph-not-built)时的 fallback。
|
|
221
|
+
|
|
222
|
+
该提示与 5 个 sub-agent prompt body 的「工具优先使用规则」表共享单一事实源(`templates/preference-rules.md`),由 `scripts/sync-preference-rules.mjs` 守护一致性。
|
|
223
|
+
|
|
214
224
|
## 并行执行策略
|
|
215
225
|
|
|
216
226
|
本编排流程在以下阶段使用并行调度以缩短总耗时:
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Preference Rules — 工具优先使用规则(单一事实源,M7 F170d)
|
|
2
|
+
|
|
3
|
+
> **本文件是 spec-driver「工具优先使用规则」引导文案的 canonical source。**
|
|
4
|
+
>
|
|
5
|
+
> 消费方(三处,禁止各自手写漂移):
|
|
6
|
+
> 1. **5 个 sub-agent**(`agents/{plan,implement,verify,spec-review,quality-review}.md`)——由 `scripts/sync-preference-rules.mjs --write` 按各 agent frontmatter `tools` **过滤渲染**后嵌入 `<!-- BEGIN preference-rules -->` / `<!-- END preference-rules -->` 之间。
|
|
7
|
+
> 2. **5 个主编排器 SKILL.md**——「子代理调度时的工具优先级提示」块引用本文件路径。
|
|
8
|
+
> 3. **F170d harness**(`scripts/feature-170d-driver-preference.mjs`)——`--append-system-prompt` 注入时读取本块并按目标 agent 的 tools 过滤。
|
|
9
|
+
>
|
|
10
|
+
> **修改流程**:改下方 `block-start`/`block-end` 之间的内容 → 跑 `node plugins/spec-driver/scripts/sync-preference-rules.mjs --write` → 跑 `npm run repo:check`(含 `preference-rules:agent-block-sync` 漂移检测)。
|
|
11
|
+
>
|
|
12
|
+
> **anchor 契约**:`<!-- preference-rules:<ruleId> tool=<toolKey> -->`,`ruleId ∈ {R1..R4}`(身份),`toolKey ∈ {impact,context,detect_changes}`(按 agent tools 过滤的键)。R1、R2 同为 `tool=impact`。
|
|
13
|
+
>
|
|
14
|
+
> **背景**:F170c SC-002 实测 driver(Claude Sonnet 4.6)在 caller-analysis 任务上 0/10 主动调用 spectra MCP;仅靠 tool description 升级无法改变。本引导在 prompt level 提供「任务→工具」匹配性引导。详见 `docs/spectra-mcp-integration.md` §七。
|
|
15
|
+
|
|
16
|
+
<!-- preference-rules:block-start -->
|
|
17
|
+
## 工具优先使用规则(M7 F170d)
|
|
18
|
+
|
|
19
|
+
当面对以下类任务时,**优先调用 spectra MCP 工具而非 Read/Grep**:
|
|
20
|
+
|
|
21
|
+
| 任务关键词 | 优先工具 | 理由 |
|
|
22
|
+
|----------|---------|------|
|
|
23
|
+
<!-- preference-rules:R1 tool=impact -->
|
|
24
|
+
| "找 caller" / "谁调用了 X" / "caller analysis" | `mcp__plugin_spectra_spectra__impact` (direction=upstream) | 提供 transitive caller chain + confidence score,Grep 仅文本匹配无依赖深度 |
|
|
25
|
+
<!-- preference-rules:R2 tool=impact -->
|
|
26
|
+
| "评估改动影响" / "blast radius" / "影响面" | `mcp__plugin_spectra_spectra__impact` | 提供 BFS 受影响 symbol 列表 + summary |
|
|
27
|
+
<!-- preference-rules:R3 tool=context -->
|
|
28
|
+
| "找 callee" / "X 调用了什么" / "依赖什么" | `mcp__plugin_spectra_spectra__context` | 提供 symbol 360° 上下文 (definition + callers + callees + imports) |
|
|
29
|
+
<!-- preference-rules:R4 tool=detect_changes -->
|
|
30
|
+
| "git diff 影响" / "改了哪些 symbol" / "PR review 范围" | `mcp__plugin_spectra_spectra__detect_changes` | 从 diff 派生 changedSymbols + impact 链 |
|
|
31
|
+
<!-- /preference-rules:rows -->
|
|
32
|
+
|
|
33
|
+
### 关键原则
|
|
34
|
+
|
|
35
|
+
- **Grep 仍是 fallback**:当 Spectra MCP 工具返回 graph-not-built / 不可用时退回 Grep
|
|
36
|
+
- **不能省略调用**:不要因为"觉得 Grep 够用"跳过 MCP — 即使任务可以用 Grep 解决,MCP 提供的 transitive 数据更可信
|
|
37
|
+
- **chained 使用**:detect_changes → impact → context 是典型链路,按 nextStepHint 引导继续调用
|
|
38
|
+
- **不要 N+1**:单次 impact 调用即可拿到 BFS 全 list,不需要多次 Grep 累计
|
|
39
|
+
<!-- preference-rules:block-end -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Spectra — Claude Code Plugin
|
|
2
2
|
|
|
3
|
-
> 当前发布版本: v4.
|
|
3
|
+
> 当前发布版本: v4.2.0
|
|
4
4
|
|
|
5
5
|
通过 AST 静态分析 + LLM 混合流水线,将遗留源代码逆向工程为结构化 Spec 文档。
|
|
6
6
|
|
|
@@ -123,6 +123,53 @@ Plugin 安装后,`.mcp.json` 自动配置 MCP server:
|
|
|
123
123
|
/spectra-diff specs/auth.spec.md src/auth/
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
## Spectra Index — UnifiedGraph 索引(Feature 156)
|
|
127
|
+
|
|
128
|
+
`spectra index` 把整个项目索引为 `.spectra/unified-graph.json` snapshot,
|
|
129
|
+
供下游 panoramic / spectra batch / IDE 工具消费同一份图。
|
|
130
|
+
|
|
131
|
+
### 三种模式
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# 1. 全量索引(首次使用 / corruption 自愈)
|
|
135
|
+
spectra index
|
|
136
|
+
|
|
137
|
+
# 2. 一次性增量更新(基于 git diff + caller expansion)
|
|
138
|
+
spectra index --incremental
|
|
139
|
+
|
|
140
|
+
# 3. 持续监听模式(chokidar + 批量 incremental,进程不退出,Ctrl+C 退出)
|
|
141
|
+
spectra index --watch
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### post-commit hook 自动触发(可选,FR-15)
|
|
145
|
+
|
|
146
|
+
每次 `git commit` 完成后自动跑一次 `spectra index --incremental`,
|
|
147
|
+
保持 `.spectra/unified-graph.json` 与代码库同步。**不会** 阻塞 commit 流程
|
|
148
|
+
(脚本后台异步触发)。
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# 手动安装:拷贝脚本到 .git/hooks/ 并赋可执行权限
|
|
152
|
+
cp plugins/spectra/hooks/post-commit.sh .git/hooks/post-commit
|
|
153
|
+
chmod +x .git/hooks/post-commit
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
行为说明(FR-16):
|
|
157
|
+
- 仅在仓库根存在 `.spectra/` 时触发;未启用用户不受影响
|
|
158
|
+
- 后台异步调用,输出到 `.spectra/index-hook.log`(已被 `.gitignore` 涵盖)
|
|
159
|
+
- 任何失败不影响 commit 退出码(hook 始终 exit 0)
|
|
160
|
+
|
|
161
|
+
不通过 npm postinstall / install --git-hook 子命令自动安装(保持非破坏性)。
|
|
162
|
+
|
|
163
|
+
### 验证
|
|
164
|
+
|
|
165
|
+
`scripts/verify-feature-156.mjs` 提供端到端验证:跑 full → 改动 1 个文件 →
|
|
166
|
+
跑 incremental → canonical sort 后对比 `depends-on / calls / cross-module` 三类边
|
|
167
|
+
diff = 0(AC-3a / AC-3b)。
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
node scripts/verify-feature-156.mjs --project-root <dir>
|
|
171
|
+
```
|
|
172
|
+
|
|
126
173
|
## 许可证
|
|
127
174
|
|
|
128
175
|
MIT
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Feature 156 — Spectra incremental index 自动触发(post-commit hook)
|
|
3
|
+
#
|
|
4
|
+
# 用户手动安装:
|
|
5
|
+
# cp plugins/spectra/hooks/post-commit.sh .git/hooks/post-commit
|
|
6
|
+
# chmod +x .git/hooks/post-commit
|
|
7
|
+
#
|
|
8
|
+
# 行为:
|
|
9
|
+
# 1. 仅在仓库根目录已存在 .spectra/ 时触发(用户已显式跑过一次 spectra index)
|
|
10
|
+
# 2. 后台异步调用 spectra index --incremental,避免阻塞 commit 流程
|
|
11
|
+
# 3. 输出重定向到 .spectra/index-hook.log(已被 .gitignore 涵盖)
|
|
12
|
+
# 4. 任何失败都不会回退到 commit 失败(exit 0 总是返回)
|
|
13
|
+
#
|
|
14
|
+
# 设计决策(clarify Q4):
|
|
15
|
+
# - 不新增 spectra install --git-hook 子命令,仅提供脚本文件 + README 安装步骤
|
|
16
|
+
# - 不通过 npm postinstall 自动注入,保持非破坏性(FR-16)
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
# 取仓库根目录(如果不在 git 仓库内则静默退出)
|
|
21
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
|
|
22
|
+
if [ -z "$REPO_ROOT" ]; then
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# .spectra/ 不存在 → 用户尚未启用 spectra index,跳过(FR-16)
|
|
27
|
+
if [ ! -d "$REPO_ROOT/.spectra" ]; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# 后台异步触发 incremental,使用 ORIG_HEAD HEAD(post-commit 上下文标准 ref)
|
|
32
|
+
# 输出 redirect 到 .spectra/index-hook.log,避免污染 git commit terminal
|
|
33
|
+
(
|
|
34
|
+
cd "$REPO_ROOT"
|
|
35
|
+
npx spectra index --incremental --git-range "ORIG_HEAD HEAD" \
|
|
36
|
+
>> .spectra/index-hook.log 2>&1
|
|
37
|
+
) &
|
|
38
|
+
|
|
39
|
+
# 立即 exit 0;不等待后台进程,不阻塞 commit
|
|
40
|
+
exit 0
|