spectra-cli 4.1.1 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/.spectra-build-meta.json +9 -0
- 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 +42 -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 +168 -61
- 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 +74 -5
- package/dist/batch/batch-orchestrator.d.ts.map +1 -1
- package/dist/batch/batch-orchestrator.js +583 -70
- 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 +21 -28
- package/dist/batch/delta-regenerator.js.map +1 -1
- package/dist/batch/module-grouper.d.ts +9 -2
- package/dist/batch/module-grouper.d.ts.map +1 -1
- package/dist/batch/module-grouper.js +3 -1
- package/dist/batch/module-grouper.js.map +1 -1
- package/dist/batch/regen-plan.d.ts +78 -0
- package/dist/batch/regen-plan.d.ts.map +1 -0
- package/dist/batch/regen-plan.js +93 -0
- package/dist/batch/regen-plan.js.map +1 -0
- package/dist/cli/commands/batch.d.ts.map +1 -1
- package/dist/cli/commands/batch.js +36 -8
- package/dist/cli/commands/batch.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/commands/scaffold-kb.d.ts +9 -0
- package/dist/cli/commands/scaffold-kb.d.ts.map +1 -0
- package/dist/cli/commands/scaffold-kb.js +179 -0
- package/dist/cli/commands/scaffold-kb.js.map +1 -0
- package/dist/cli/index.js +33 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/error-handler.d.ts +0 -6
- package/dist/cli/utils/error-handler.d.ts.map +1 -1
- package/dist/cli/utils/error-handler.js +0 -13
- package/dist/cli/utils/error-handler.js.map +1 -1
- package/dist/cli/utils/parse-args.d.ts +55 -3
- package/dist/cli/utils/parse-args.d.ts.map +1 -1
- package/dist/cli/utils/parse-args.js +176 -13
- package/dist/cli/utils/parse-args.js.map +1 -1
- package/dist/cli/version-meta.d.ts +16 -0
- package/dist/cli/version-meta.d.ts.map +1 -0
- package/dist/cli/version-meta.js +28 -0
- package/dist/cli/version-meta.js.map +1 -0
- package/dist/core/ast-analyzer.d.ts.map +1 -1
- package/dist/core/ast-analyzer.js +75 -5
- package/dist/core/ast-analyzer.js.map +1 -1
- package/dist/core/import-resolver.d.ts +93 -0
- package/dist/core/import-resolver.d.ts.map +1 -0
- package/dist/core/import-resolver.js +414 -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 +21 -0
- package/dist/core/single-spec-orchestrator.d.ts.map +1 -1
- package/dist/core/single-spec-orchestrator.js +187 -23
- package/dist/core/single-spec-orchestrator.js.map +1 -1
- package/dist/core/skeleton-hash.d.ts +33 -0
- package/dist/core/skeleton-hash.d.ts.map +1 -0
- package/dist/core/skeleton-hash.js +76 -0
- package/dist/core/skeleton-hash.js.map +1 -0
- package/dist/core/tree-sitter-analyzer.d.ts +7 -0
- package/dist/core/tree-sitter-analyzer.d.ts.map +1 -1
- package/dist/core/tree-sitter-analyzer.js +32 -1
- package/dist/core/tree-sitter-analyzer.js.map +1 -1
- package/dist/core/tree-sitter-fallback.d.ts +12 -4
- package/dist/core/tree-sitter-fallback.d.ts.map +1 -1
- package/dist/core/tree-sitter-fallback.js +160 -12
- package/dist/core/tree-sitter-fallback.js.map +1 -1
- package/dist/extraction/extraction-types.d.ts +25 -25
- package/dist/extraction/image-extractor.d.ts.map +1 -1
- package/dist/extraction/image-extractor.js +3 -1
- package/dist/extraction/image-extractor.js.map +1 -1
- package/dist/extraction/markdown-extractor.d.ts.map +1 -1
- package/dist/extraction/markdown-extractor.js +3 -1
- package/dist/extraction/markdown-extractor.js.map +1 -1
- package/dist/generator/frontmatter.d.ts +5 -0
- package/dist/generator/frontmatter.d.ts.map +1 -1
- package/dist/generator/frontmatter.js +4 -0
- package/dist/generator/frontmatter.js.map +1 -1
- 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/kb-mcp/index.d.ts +14 -0
- package/dist/kb-mcp/index.d.ts.map +1 -0
- package/dist/kb-mcp/index.js +24 -0
- package/dist/kb-mcp/index.js.map +1 -0
- package/dist/kb-mcp/lib/kb-error.d.ts +21 -0
- package/dist/kb-mcp/lib/kb-error.d.ts.map +1 -0
- package/dist/kb-mcp/lib/kb-error.js +28 -0
- package/dist/kb-mcp/lib/kb-error.js.map +1 -0
- package/dist/kb-mcp/lib/kb-locator.d.ts +58 -0
- package/dist/kb-mcp/lib/kb-locator.d.ts.map +1 -0
- package/dist/kb-mcp/lib/kb-locator.js +85 -0
- package/dist/kb-mcp/lib/kb-locator.js.map +1 -0
- package/dist/kb-mcp/lib/result-merger.d.ts +35 -0
- package/dist/kb-mcp/lib/result-merger.d.ts.map +1 -0
- package/dist/kb-mcp/lib/result-merger.js +64 -0
- package/dist/kb-mcp/lib/result-merger.js.map +1 -0
- package/dist/kb-mcp/server.d.ts +12 -0
- package/dist/kb-mcp/server.d.ts.map +1 -0
- package/dist/kb-mcp/server.js +29 -0
- package/dist/kb-mcp/server.js.map +1 -0
- package/dist/kb-mcp/tools/kb-api-lookup.d.ts +28 -0
- package/dist/kb-mcp/tools/kb-api-lookup.d.ts.map +1 -0
- package/dist/kb-mcp/tools/kb-api-lookup.js +237 -0
- package/dist/kb-mcp/tools/kb-api-lookup.js.map +1 -0
- package/dist/kb-mcp/tools/kb-doc-lookup.d.ts +20 -0
- package/dist/kb-mcp/tools/kb-doc-lookup.d.ts.map +1 -0
- package/dist/kb-mcp/tools/kb-doc-lookup.js +92 -0
- package/dist/kb-mcp/tools/kb-doc-lookup.js.map +1 -0
- package/dist/kb-mcp/tools/kb-search.d.ts +23 -0
- package/dist/kb-mcp/tools/kb-search.d.ts.map +1 -0
- package/dist/kb-mcp/tools/kb-search.js +126 -0
- package/dist/kb-mcp/tools/kb-search.js.map +1 -0
- 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 +39 -0
- package/dist/knowledge-graph/import-resolver.d.ts.map +1 -0
- package/dist/knowledge-graph/import-resolver.js +214 -0
- package/dist/knowledge-graph/import-resolver.js.map +1 -0
- package/dist/knowledge-graph/incremental.d.ts +131 -0
- package/dist/knowledge-graph/incremental.d.ts.map +1 -0
- package/dist/knowledge-graph/incremental.js +432 -0
- package/dist/knowledge-graph/incremental.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +85 -0
- package/dist/knowledge-graph/index.d.ts.map +1 -0
- package/dist/knowledge-graph/index.js +198 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/knowledge-graph/module-derivation.d.ts +252 -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 +310 -0
- package/dist/knowledge-graph/persistence.d.ts.map +1 -0
- package/dist/knowledge-graph/persistence.js +280 -0
- package/dist/knowledge-graph/persistence.js.map +1 -0
- package/dist/knowledge-graph/query-helpers.d.ts +191 -0
- package/dist/knowledge-graph/query-helpers.d.ts.map +1 -0
- package/dist/knowledge-graph/query-helpers.js +559 -0
- package/dist/knowledge-graph/query-helpers.js.map +1 -0
- package/dist/knowledge-graph/relativize.d.ts +51 -0
- package/dist/knowledge-graph/relativize.d.ts.map +1 -0
- package/dist/knowledge-graph/relativize.js +104 -0
- package/dist/knowledge-graph/relativize.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 +53 -0
- package/dist/mcp/agent-context-tools.d.ts.map +1 -0
- package/dist/mcp/agent-context-tools.js +806 -0
- package/dist/mcp/agent-context-tools.js.map +1 -0
- package/dist/mcp/file-nav-tools.d.ts +42 -0
- package/dist/mcp/file-nav-tools.d.ts.map +1 -0
- package/dist/mcp/file-nav-tools.js +318 -0
- package/dist/mcp/file-nav-tools.js.map +1 -0
- package/dist/mcp/graph-tools.d.ts +22 -0
- package/dist/mcp/graph-tools.d.ts.map +1 -1
- package/dist/mcp/graph-tools.js +204 -133
- package/dist/mcp/graph-tools.js.map +1 -1
- package/dist/mcp/lib/file-nav-helpers.d.ts +128 -0
- package/dist/mcp/lib/file-nav-helpers.d.ts.map +1 -0
- package/dist/mcp/lib/file-nav-helpers.js +305 -0
- package/dist/mcp/lib/file-nav-helpers.js.map +1 -0
- 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/lib/telemetry.d.ts +69 -0
- package/dist/mcp/lib/telemetry.d.ts.map +1 -0
- package/dist/mcp/lib/telemetry.js +113 -0
- package/dist/mcp/lib/telemetry.js.map +1 -0
- package/dist/mcp/lib/tool-response.d.ts +46 -0
- package/dist/mcp/lib/tool-response.d.ts.map +1 -0
- package/dist/mcp/lib/tool-response.js +83 -0
- package/dist/mcp/lib/tool-response.js.map +1 -0
- package/dist/mcp/server.d.ts +14 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +216 -158
- 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 +80 -6
- package/dist/models/code-skeleton.d.ts.map +1 -1
- package/dist/models/code-skeleton.js +30 -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 +173 -94
- package/dist/models/module-spec.d.ts.map +1 -1
- package/dist/models/module-spec.js +6 -0
- package/dist/models/module-spec.js.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 +15 -2
- package/dist/panoramic/builders/doc-graph-builder.d.ts.map +1 -1
- package/dist/panoramic/builders/doc-graph-builder.js +20 -0
- 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 +72 -2
- package/dist/panoramic/graph/graph-builder.d.ts.map +1 -1
- package/dist/panoramic/graph/graph-builder.js +330 -46
- 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 +49 -2
- package/dist/panoramic/graph/graph-query.d.ts.map +1 -1
- package/dist/panoramic/graph/graph-query.js +117 -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/graph/index.d.ts +2 -1
- package/dist/panoramic/graph/index.d.ts.map +1 -1
- package/dist/panoramic/graph/index.js +1 -1
- package/dist/panoramic/graph/index.js.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/adr-evidence-verifier.d.ts.map +1 -1
- package/dist/panoramic/pipelines/adr-evidence-verifier.js +1 -29
- package/dist/panoramic/pipelines/adr-evidence-verifier.js.map +1 -1
- 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/query.d.ts +1 -0
- package/dist/panoramic/query.d.ts.map +1 -1
- package/dist/panoramic/query.js +5 -0
- package/dist/panoramic/query.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/scaffold-kb/api-entities-serializer.d.ts +12 -0
- package/dist/scaffold-kb/api-entities-serializer.d.ts.map +1 -0
- package/dist/scaffold-kb/api-entities-serializer.js +144 -0
- package/dist/scaffold-kb/api-entities-serializer.js.map +1 -0
- package/dist/scaffold-kb/arbitration.d.ts +44 -0
- package/dist/scaffold-kb/arbitration.d.ts.map +1 -0
- package/dist/scaffold-kb/arbitration.js +144 -0
- package/dist/scaffold-kb/arbitration.js.map +1 -0
- package/dist/scaffold-kb/chunk-splitter.d.ts +20 -0
- package/dist/scaffold-kb/chunk-splitter.d.ts.map +1 -0
- package/dist/scaffold-kb/chunk-splitter.js +309 -0
- package/dist/scaffold-kb/chunk-splitter.js.map +1 -0
- package/dist/scaffold-kb/doc-graph-builder.d.ts +26 -0
- package/dist/scaffold-kb/doc-graph-builder.d.ts.map +1 -0
- package/dist/scaffold-kb/doc-graph-builder.js +72 -0
- package/dist/scaffold-kb/doc-graph-builder.js.map +1 -0
- package/dist/scaffold-kb/entity-extractor.d.ts +40 -0
- package/dist/scaffold-kb/entity-extractor.d.ts.map +1 -0
- package/dist/scaffold-kb/entity-extractor.js +0 -0
- package/dist/scaffold-kb/entity-extractor.js.map +1 -0
- package/dist/scaffold-kb/entity-heuristic.d.ts +14 -0
- package/dist/scaffold-kb/entity-heuristic.d.ts.map +1 -0
- package/dist/scaffold-kb/entity-heuristic.js +107 -0
- package/dist/scaffold-kb/entity-heuristic.js.map +1 -0
- package/dist/scaffold-kb/entity-matcher.d.ts +20 -0
- package/dist/scaffold-kb/entity-matcher.d.ts.map +1 -0
- package/dist/scaffold-kb/entity-matcher.js +53 -0
- package/dist/scaffold-kb/entity-matcher.js.map +1 -0
- package/dist/scaffold-kb/entity-util.d.ts +11 -0
- package/dist/scaffold-kb/entity-util.d.ts.map +1 -0
- package/dist/scaffold-kb/entity-util.js +23 -0
- package/dist/scaffold-kb/entity-util.js.map +1 -0
- package/dist/scaffold-kb/evidence-envelope.d.ts +17 -0
- package/dist/scaffold-kb/evidence-envelope.d.ts.map +1 -0
- package/dist/scaffold-kb/evidence-envelope.js +32 -0
- package/dist/scaffold-kb/evidence-envelope.js.map +1 -0
- package/dist/scaffold-kb/index.d.ts +20 -0
- package/dist/scaffold-kb/index.d.ts.map +1 -0
- package/dist/scaffold-kb/index.js +102 -0
- package/dist/scaffold-kb/index.js.map +1 -0
- package/dist/scaffold-kb/ingest/ingest-core.d.ts +47 -0
- package/dist/scaffold-kb/ingest/ingest-core.d.ts.map +1 -0
- package/dist/scaffold-kb/ingest/ingest-core.js +231 -0
- package/dist/scaffold-kb/ingest/ingest-core.js.map +1 -0
- package/dist/scaffold-kb/ingest/office-parser.d.ts +33 -0
- package/dist/scaffold-kb/ingest/office-parser.d.ts.map +1 -0
- package/dist/scaffold-kb/ingest/office-parser.js +187 -0
- package/dist/scaffold-kb/ingest/office-parser.js.map +1 -0
- package/dist/scaffold-kb/ingest/url-fetcher.d.ts +43 -0
- package/dist/scaffold-kb/ingest/url-fetcher.d.ts.map +1 -0
- package/dist/scaffold-kb/ingest/url-fetcher.js +245 -0
- package/dist/scaffold-kb/ingest/url-fetcher.js.map +1 -0
- package/dist/scaffold-kb/ingester.d.ts +38 -0
- package/dist/scaffold-kb/ingester.d.ts.map +1 -0
- package/dist/scaffold-kb/ingester.js +261 -0
- package/dist/scaffold-kb/ingester.js.map +1 -0
- package/dist/scaffold-kb/injection-format.d.ts +25 -0
- package/dist/scaffold-kb/injection-format.d.ts.map +1 -0
- package/dist/scaffold-kb/injection-format.js +55 -0
- package/dist/scaffold-kb/injection-format.js.map +1 -0
- package/dist/scaffold-kb/kb-writer.d.ts +13 -0
- package/dist/scaffold-kb/kb-writer.d.ts.map +1 -0
- package/dist/scaffold-kb/kb-writer.js +69 -0
- package/dist/scaffold-kb/kb-writer.js.map +1 -0
- package/dist/scaffold-kb/keyword-extract.d.ts +16 -0
- package/dist/scaffold-kb/keyword-extract.d.ts.map +1 -0
- package/dist/scaffold-kb/keyword-extract.js +49 -0
- package/dist/scaffold-kb/keyword-extract.js.map +1 -0
- package/dist/scaffold-kb/query-sanitizer.d.ts +28 -0
- package/dist/scaffold-kb/query-sanitizer.d.ts.map +1 -0
- package/dist/scaffold-kb/query-sanitizer.js +38 -0
- package/dist/scaffold-kb/query-sanitizer.js.map +1 -0
- package/dist/scaffold-kb/recall-eval.d.ts +48 -0
- package/dist/scaffold-kb/recall-eval.d.ts.map +1 -0
- package/dist/scaffold-kb/recall-eval.js +55 -0
- package/dist/scaffold-kb/recall-eval.js.map +1 -0
- package/dist/scaffold-kb/schema-compat.d.ts +22 -0
- package/dist/scaffold-kb/schema-compat.d.ts.map +1 -0
- package/dist/scaffold-kb/schema-compat.js +32 -0
- package/dist/scaffold-kb/schema-compat.js.map +1 -0
- package/dist/scaffold-kb/search-core.d.ts +42 -0
- package/dist/scaffold-kb/search-core.d.ts.map +1 -0
- package/dist/scaffold-kb/search-core.js +89 -0
- package/dist/scaffold-kb/search-core.js.map +1 -0
- package/dist/scaffold-kb/sqlite-engine.d.ts +58 -0
- package/dist/scaffold-kb/sqlite-engine.d.ts.map +1 -0
- package/dist/scaffold-kb/sqlite-engine.js +61 -0
- package/dist/scaffold-kb/sqlite-engine.js.map +1 -0
- package/dist/scaffold-kb/sqlite-writer.d.ts +18 -0
- package/dist/scaffold-kb/sqlite-writer.d.ts.map +1 -0
- package/dist/scaffold-kb/sqlite-writer.js +76 -0
- package/dist/scaffold-kb/sqlite-writer.js.map +1 -0
- package/dist/scaffold-kb/tokenizer.d.ts +26 -0
- package/dist/scaffold-kb/tokenizer.d.ts.map +1 -0
- package/dist/scaffold-kb/tokenizer.js +97 -0
- package/dist/scaffold-kb/tokenizer.js.map +1 -0
- package/dist/scaffold-kb/types.d.ts +157 -0
- package/dist/scaffold-kb/types.d.ts.map +1 -0
- package/dist/scaffold-kb/types.js +5 -0
- package/dist/scaffold-kb/types.js.map +1 -0
- package/dist/utils/file-scanner.d.ts +15 -0
- package/dist/utils/file-scanner.d.ts.map +1 -1
- package/dist/utils/file-scanner.js +18 -1
- package/dist/utils/file-scanner.js.map +1 -1
- package/dist/utils/string-distance.d.ts +20 -0
- package/dist/utils/string-distance.d.ts.map +1 -0
- package/dist/utils/string-distance.js +38 -0
- package/dist/utils/string-distance.js.map +1 -0
- package/package.json +22 -3
- package/plugins/demo-kb-en/.claude-plugin/plugin.json +11 -0
- package/plugins/demo-kb-en/.mcp.json +8 -0
- package/plugins/demo-kb-en/FIXTURE.json +23 -0
- package/plugins/demo-kb-en/FIXTURE.md +53 -0
- package/plugins/demo-kb-en/ingest-samples/meeting-notes.md +13 -0
- package/plugins/demo-kb-en/kb/api-entities.json +3445 -0
- package/plugins/demo-kb-en/kb/chunks.sqlite +0 -0
- package/plugins/demo-kb-en/kb/doc-graph.json +113 -0
- package/plugins/demo-kb-zh/.claude-plugin/plugin.json +11 -0
- package/plugins/demo-kb-zh/.mcp.json +8 -0
- package/plugins/demo-kb-zh/FIXTURE.json +23 -0
- package/plugins/demo-kb-zh/FIXTURE.md +63 -0
- package/plugins/demo-kb-zh/ingest-samples/meeting-notes.md +13 -0
- package/plugins/demo-kb-zh/kb/api-entities.json +990 -0
- package/plugins/demo-kb-zh/kb/chunks.sqlite +0 -0
- package/plugins/demo-kb-zh/kb/doc-graph.json +113 -0
- package/plugins/spec-driver/.claude-plugin/plugin.json +1 -1
- package/plugins/spec-driver/README.md +50 -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 +108 -1
- package/plugins/spec-driver/config/orchestration.yaml +39 -31
- package/plugins/spec-driver/contracts/orchestration-overrides-contract.yaml +27 -0
- package/plugins/spec-driver/contracts/orchestration-schema.mjs +272 -227
- package/plugins/spec-driver/contracts/wrapper-source-of-truth.yaml +3 -0
- package/plugins/spec-driver/docs/customization.md +134 -0
- package/plugins/spec-driver/docs/spectra-mcp-integration.md +165 -0
- package/plugins/spec-driver/hooks/hooks.json +9 -0
- package/plugins/spec-driver/hooks/stop-fix-compliance-check.sh +36 -0
- package/plugins/spec-driver/lib/delegation-contract.mjs +84 -0
- package/plugins/spec-driver/lib/orchestration-resolver.mjs +49 -0
- package/plugins/spec-driver/lib/orchestrator.mjs +29 -1
- package/plugins/spec-driver/lib/preference-rules.mjs +96 -0
- package/plugins/spec-driver/scripts/codex-skills.sh +28 -28
- package/plugins/spec-driver/scripts/dev/spike-fix-compliance-e2e.mjs +130 -0
- package/plugins/spec-driver/scripts/fix-compliance-judge.mjs +415 -0
- package/plugins/spec-driver/scripts/generate-adoption-insights.mjs +48 -1
- package/plugins/spec-driver/scripts/goal-loop-cli.mjs +307 -0
- package/plugins/spec-driver/scripts/init-project.sh +56 -0
- package/plugins/spec-driver/scripts/kb-prequery.mjs +125 -0
- package/plugins/spec-driver/scripts/lib/config-schema.mjs +200 -94
- package/plugins/spec-driver/scripts/lib/ensure-gitignore.sh +277 -0
- package/plugins/spec-driver/scripts/lib/extract-wrapper-body.mjs +136 -0
- package/plugins/spec-driver/scripts/lib/fix-compliance-core.mjs +434 -0
- package/plugins/spec-driver/scripts/lib/fix-compliance-io.mjs +335 -0
- package/plugins/spec-driver/scripts/lib/goal-loop-core.mjs +783 -0
- package/plugins/spec-driver/scripts/lib/init-project-output.sh +28 -0
- package/plugins/spec-driver/scripts/lib/load-zod.mjs +62 -0
- package/plugins/spec-driver/scripts/lib/project-profile-resolver.mjs +141 -49
- package/plugins/spec-driver/scripts/lib/project-profile-schema.mjs +88 -54
- package/plugins/spec-driver/scripts/postinstall.sh +13 -1
- package/plugins/spec-driver/scripts/record-workflow-run.mjs +75 -0
- package/plugins/spec-driver/scripts/sync-delegation-contract.mjs +187 -0
- package/plugins/spec-driver/scripts/sync-preference-rules.mjs +148 -0
- package/plugins/spec-driver/scripts/validate-orchestrator-models.mjs +156 -0
- package/plugins/spec-driver/scripts/validate-wrapper-sources.mjs +46 -1
- package/plugins/spec-driver/skills/spec-driver-feature/SKILL.md +302 -0
- package/plugins/spec-driver/skills/spec-driver-fix/SKILL.md +97 -8
- package/plugins/spec-driver/skills/spec-driver-implement/SKILL.md +18 -0
- package/plugins/spec-driver/skills/spec-driver-refactor/SKILL.md +10 -0
- package/plugins/spec-driver/skills/spec-driver-resume/SKILL.md +12 -1
- package/plugins/spec-driver/skills/spec-driver-story/SKILL.md +30 -0
- package/plugins/spec-driver/templates/delegation-contract.md +27 -0
- package/plugins/spec-driver/templates/goal-loop-override-template.yaml +284 -0
- package/plugins/spec-driver/templates/preference-rules.md +39 -0
- package/plugins/spec-driver/templates/specify-base/project-context-template.yaml +10 -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/module-spec.hbs +1 -0
- package/templates/product-overview.hbs +1 -1
|
@@ -18,6 +18,14 @@ import { readJsonArtifact, writeJsonArtifact, writeMarkdownArtifact } from './li
|
|
|
18
18
|
const SCHEMA_VERSION = 1;
|
|
19
19
|
const PRODUCT_ID = 'spec-driver';
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* 已知的非 summary 事件类型白名单(Feature 208,data-model.md §9)。
|
|
23
|
+
* 这些事件与 workflow-run-summary 共存于同一 .specify/runs/*.jsonl,但不参与 adoption 统计。
|
|
24
|
+
* why 需要白名单:normalizeRunEvent 对非 summary 行返回 null → 原逻辑会计入 invalidLineCount 并
|
|
25
|
+
* 产生"忽略无效 run event"warning,污染 adoption 报告 invalid 统计。白名单命中者静默 skip。
|
|
26
|
+
*/
|
|
27
|
+
const KNOWN_NON_SUMMARY_EVENT_TYPES = new Set(['fix-compliance-verdict']);
|
|
28
|
+
|
|
21
29
|
function parseArgs(argv) {
|
|
22
30
|
const args = {
|
|
23
31
|
projectRoot: process.cwd(),
|
|
@@ -126,6 +134,10 @@ function readRunLogs(projectRoot) {
|
|
|
126
134
|
const line = lines[index];
|
|
127
135
|
try {
|
|
128
136
|
const parsed = JSON.parse(line);
|
|
137
|
+
// 已知非 summary 事件类型(如 fix-compliance-verdict)静默 skip:不计 invalid、不产生 warning
|
|
138
|
+
if (isObject(parsed) && KNOWN_NON_SUMMARY_EVENT_TYPES.has(parsed.eventType)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
129
141
|
const normalized = normalizeRunEvent(parsed);
|
|
130
142
|
if (normalized) {
|
|
131
143
|
events.push(normalized);
|
|
@@ -181,12 +193,47 @@ function normalizeRunEvent(entry) {
|
|
|
181
193
|
};
|
|
182
194
|
}
|
|
183
195
|
|
|
196
|
+
// 同一 (workflowId, runId) 可能出现多条终态事件:Feature 211 的 compliant-reset 语义下,
|
|
197
|
+
// 同一 session 后续再次耗尽额度降级会重写 workflow-run-summary 终态事件(每个"阻断周期"一条)。
|
|
198
|
+
// JSONL 是 append-only 审计日志,原始事件全部保留;此处仅在统计聚合前按 (workflowId, runId)
|
|
199
|
+
// 去重,取时间最晚的一条作为该 run 的最终结果,避免同一 run 被重复计入 totalRuns 等指标。
|
|
200
|
+
// runId 缺失的事件在 normalizeRunEvent 阶段已被判为无效(不进入本函数),故无需在此特殊处理。
|
|
201
|
+
function dedupeRunEvents(events) {
|
|
202
|
+
const latestByRun = new Map();
|
|
203
|
+
const order = [];
|
|
204
|
+
for (const event of events) {
|
|
205
|
+
const key = `${event.workflowId}\u0000${event.runId}`;
|
|
206
|
+
const existing = latestByRun.get(key);
|
|
207
|
+
if (!existing) {
|
|
208
|
+
latestByRun.set(key, event);
|
|
209
|
+
order.push(key);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
// 时间可比时取更晚者;时间相等或缺失时取文件内后出现者(append-only 天然有序)
|
|
213
|
+
const newMs = eventRecencyMs(event);
|
|
214
|
+
const existingMs = eventRecencyMs(existing);
|
|
215
|
+
if (newMs === null || existingMs === null || newMs >= existingMs) {
|
|
216
|
+
latestByRun.set(key, event);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return order.map((key) => latestByRun.get(key));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 终态事件的"新近度":取 recordedAt / finishedAt 中可解析的最晚时间戳(ms),均缺失则返回 null
|
|
223
|
+
function eventRecencyMs(event) {
|
|
224
|
+
const candidates = [event.recordedAt, event.finishedAt]
|
|
225
|
+
.map((value) => (value ? Date.parse(value) : Number.NaN))
|
|
226
|
+
.filter((value) => !Number.isNaN(value));
|
|
227
|
+
return candidates.length > 0 ? Math.max(...candidates) : null;
|
|
228
|
+
}
|
|
229
|
+
|
|
184
230
|
function calculateMetrics(events, workflowDefs) {
|
|
185
231
|
const workflowMap = new Map(
|
|
186
232
|
(Array.isArray(workflowDefs) ? workflowDefs : [])
|
|
187
233
|
.filter((workflow) => isObject(workflow) && typeof workflow.id === 'string')
|
|
188
234
|
.map((workflow) => [workflow.id, workflow]),
|
|
189
235
|
);
|
|
236
|
+
const dedupedEvents = dedupeRunEvents(events);
|
|
190
237
|
const grouped = new Map();
|
|
191
238
|
const rerunPhaseCounts = new Map();
|
|
192
239
|
const gatePauseCounts = new Map();
|
|
@@ -194,7 +241,7 @@ function calculateMetrics(events, workflowDefs) {
|
|
|
194
241
|
const phaseDurationCounts = new Map();
|
|
195
242
|
let runsWithPhaseDurations = 0;
|
|
196
243
|
|
|
197
|
-
for (const event of
|
|
244
|
+
for (const event of dedupedEvents) {
|
|
198
245
|
if (!grouped.has(event.workflowId)) {
|
|
199
246
|
grouped.set(event.workflowId, []);
|
|
200
247
|
}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* goal-loop-cli.mjs
|
|
5
|
+
* Feature 201 — goal_loop core 的薄 CLI 包装(仿 orchestrator-cli.mjs)
|
|
6
|
+
*
|
|
7
|
+
* 设计契约(plan §1.1 / tasks T018,修正 Codex C-02):
|
|
8
|
+
* 所有"需要复杂结构输入"的子命令一律接受**单个 JSON payload**(文件路径),
|
|
9
|
+
* 输出 JSON 到 stdout;简单标量子命令用位置参数。SKILL.md 散文必须按本契约调用。
|
|
10
|
+
*
|
|
11
|
+
* 用法:
|
|
12
|
+
* node goal-loop-cli.mjs parse-report <reportJsonFile>
|
|
13
|
+
* node goal-loop-cli.mjs classify-command <cmdJsonFile>
|
|
14
|
+
* node goal-loop-cli.mjs decide-stop <payloadJsonFile> # payload={report,round,config,prevReports,rollbackResult}
|
|
15
|
+
* node goal-loop-cli.mjs plan-snapshot <isClean:true|false>
|
|
16
|
+
* node goal-loop-cli.mjs plan-rollback <snapshotJsonFile> # snapshot={clean,ref}
|
|
17
|
+
* node goal-loop-cli.mjs select-verify-mode <round> <max> <aboutToExit:true|false>
|
|
18
|
+
* node goal-loop-cli.mjs decide-dispatch <phaseId> <agentMode>
|
|
19
|
+
* node goal-loop-cli.mjs interpret-impact <mcpResultJsonFile>
|
|
20
|
+
* node goal-loop-cli.mjs format-iteration-log-entry <entryJsonFile> # 输出 markdown 块到 stdout
|
|
21
|
+
* node goal-loop-cli.mjs assess-preserved-config-safety <porcelainFile|-(stdin)>
|
|
22
|
+
* # 输入 = `git status --porcelain --untracked-files=all -- <PRESERVED_CONFIG_PATHSPECS>` 原始 stdout
|
|
23
|
+
* # (MUST 带 --untracked-files=all:避免 untracked 目录折叠成 `?? .specify/` 漏检 preserved 文件)
|
|
24
|
+
* # CLI 内部 parsePreservedConfigStates(porcelain, PRESERVED_CONFIG_PATHSPECS) → assessPreservedConfigSafety
|
|
25
|
+
* node goal-loop-cli.mjs is-clean-excluding-preserved <porcelainFile|-(stdin)>
|
|
26
|
+
* # 输入 = **全仓** `git status --porcelain --untracked-files=all` 原始 stdout(不带 -- pathspec)
|
|
27
|
+
* # (MUST 带 --untracked-files=all:默认会把 untracked 目录折叠成 `?? .specify/`,折叠形式喂入
|
|
28
|
+
* # 会使 isClean 误判 false → 空 stash 抓无关旧 stash,CRITICAL-7 漏网根因)
|
|
29
|
+
* # 输出 {isClean:boolean}:排除 PRESERVED_CONFIG_PATHSPECS 后是否干净(F203 CRITICAL-7)
|
|
30
|
+
* node goal-loop-cli.mjs acquire-lock <lockPath>
|
|
31
|
+
* node goal-loop-cli.mjs release-lock <lockPath>
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import fs from 'node:fs';
|
|
35
|
+
import { fileURLToPath } from 'node:url';
|
|
36
|
+
import {
|
|
37
|
+
classifyCommand,
|
|
38
|
+
decideStop,
|
|
39
|
+
decideDispatch,
|
|
40
|
+
selectVerifyMode,
|
|
41
|
+
planSnapshotCommands,
|
|
42
|
+
planRollbackCommands,
|
|
43
|
+
parseReport,
|
|
44
|
+
interpretImpactResult,
|
|
45
|
+
formatIterationLogEntry,
|
|
46
|
+
assessPreservedConfigSafety,
|
|
47
|
+
parsePreservedConfigStates,
|
|
48
|
+
isCleanExcludingPreserved,
|
|
49
|
+
PRESERVED_CONFIG_PATHSPECS,
|
|
50
|
+
} from './lib/goal-loop-core.mjs';
|
|
51
|
+
|
|
52
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
53
|
+
// I/O 边界:单实例文件锁(FR-018)—— 非纯函数,故放 CLI 不放纯 core
|
|
54
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 写锁 payload 到已打开的 fd 并关闭
|
|
58
|
+
* @param {number} fd
|
|
59
|
+
*/
|
|
60
|
+
function writeLockPayload(fd) {
|
|
61
|
+
const payload = JSON.stringify({ pid: process.pid, start_time: new Date().toISOString() });
|
|
62
|
+
try {
|
|
63
|
+
fs.writeSync(fd, payload);
|
|
64
|
+
} finally {
|
|
65
|
+
fs.closeSync(fd);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 判定现有锁是否为 stale(仅当持锁进程已不存在 或 锁内容损坏)(Codex W3 / Phase B 复审修正)
|
|
71
|
+
*
|
|
72
|
+
* 关键不变量(FR-018 单实例保证):**持锁 PID 存活时永不视为 stale**,无论锁多老。
|
|
73
|
+
* 早期版本曾用 TTL(30min)兜底接管"超龄但存活"的锁,但真实 goal_loop 跑满
|
|
74
|
+
* max_iterations × max_verify_seconds 很容易超 30min,会导致新实例强抢活锁、破坏单实例保证。
|
|
75
|
+
* 因此移除 TTL 接管路径:接管只发生在"持有者证明已死"或"锁文件损坏无法证明存活"两种情况。
|
|
76
|
+
*
|
|
77
|
+
* 已知罕见残留:PID 复用——死 goal_loop 的 PID 被无关进程复用后,process.kill(pid,0) 误判存活,
|
|
78
|
+
* 锁将无法自动接管,需人工清理 .lock 文件。我们接受这个罕见 case,不引入 TTL 接管活锁的
|
|
79
|
+
* 更大风险(误杀正在跑的长任务)来换取它。
|
|
80
|
+
* @param {string} lockPath
|
|
81
|
+
* @returns {{ stale: boolean, holderPid: number|null, reason: string }}
|
|
82
|
+
*/
|
|
83
|
+
function inspectLock(lockPath) {
|
|
84
|
+
let payload;
|
|
85
|
+
try {
|
|
86
|
+
payload = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
87
|
+
} catch {
|
|
88
|
+
// 锁内容损坏/不可解析 → 无法证明持有者存活,视为 stale 可接管
|
|
89
|
+
return { stale: true, holderPid: null, reason: 'lock_payload_unreadable' };
|
|
90
|
+
}
|
|
91
|
+
const holderPid = typeof payload.pid === 'number' ? payload.pid : null;
|
|
92
|
+
|
|
93
|
+
// 进程存活探测:process.kill(pid, 0) 不发信号,仅校验进程存在;ESRCH = 进程不存在
|
|
94
|
+
if (holderPid !== null) {
|
|
95
|
+
try {
|
|
96
|
+
process.kill(holderPid, 0);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
if (err.code === 'ESRCH') {
|
|
99
|
+
return { stale: true, holderPid, reason: 'holder_process_gone' };
|
|
100
|
+
}
|
|
101
|
+
// EPERM = 进程存在但无权限发信号 → 持有者存活(保守),非 stale
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
// payload 缺合法 pid 字段 → 无法证明存活,视为 stale 可接管
|
|
105
|
+
return { stale: true, holderPid: null, reason: 'lock_payload_unreadable' };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 走到这里:holderPid 存活(kill 未抛 ESRCH)→ 永不接管,无论锁龄
|
|
109
|
+
return { stale: false, holderPid, reason: 'holder_alive' };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 单实例文件锁:以 O_EXCL 原子创建 .lock(FR-018)
|
|
114
|
+
*
|
|
115
|
+
* stale 恢复(Codex W3 / Phase B 复审修正):遇 EEXIST 时校验现有锁——仅当持锁进程不存在(ESRCH)
|
|
116
|
+
* 或锁文件损坏无法证明持有者存活时,原子清理 stale 锁后重试一次获取;否则(持有者存活)返回
|
|
117
|
+
* lock_exists(含 holder pid)。不再用 TTL 接管"超龄但存活"的活锁(见 inspectLock 注释)。
|
|
118
|
+
* @param {string} lockPath
|
|
119
|
+
* @returns {{ acquired: true }|{ acquired: false, reason: string, holderPid?: number|null }}
|
|
120
|
+
*/
|
|
121
|
+
export function acquireLock(lockPath) {
|
|
122
|
+
let fd;
|
|
123
|
+
try {
|
|
124
|
+
// 'wx' = O_CREAT | O_EXCL | O_WRONLY:文件已存在则抛 EEXIST(原子,防竞态)
|
|
125
|
+
fd = fs.openSync(lockPath, 'wx');
|
|
126
|
+
} catch (err) {
|
|
127
|
+
if (err.code === 'EEXIST') {
|
|
128
|
+
const info = inspectLock(lockPath);
|
|
129
|
+
if (!info.stale) {
|
|
130
|
+
return { acquired: false, reason: 'lock_exists', holderPid: info.holderPid };
|
|
131
|
+
}
|
|
132
|
+
// stale 锁:原子清理后重试一次获取。
|
|
133
|
+
// 用第二个 'wx' 而非先 unlink 再 open,避免清理与重建之间的竞态(仅重试一次防活锁)。
|
|
134
|
+
try {
|
|
135
|
+
fs.unlinkSync(lockPath);
|
|
136
|
+
} catch (unlinkErr) {
|
|
137
|
+
if (unlinkErr.code !== 'ENOENT') throw unlinkErr;
|
|
138
|
+
// ENOENT:他人已抢先清理,继续尝试创建
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
fd = fs.openSync(lockPath, 'wx');
|
|
142
|
+
} catch (retryErr) {
|
|
143
|
+
if (retryErr.code === 'EEXIST') {
|
|
144
|
+
// 清理后被其他进程抢占 → 让对方持有,返回 lock_exists
|
|
145
|
+
const after = inspectLock(lockPath);
|
|
146
|
+
return { acquired: false, reason: 'lock_exists', holderPid: after.holderPid };
|
|
147
|
+
}
|
|
148
|
+
throw retryErr;
|
|
149
|
+
}
|
|
150
|
+
writeLockPayload(fd);
|
|
151
|
+
return { acquired: true };
|
|
152
|
+
}
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
writeLockPayload(fd);
|
|
156
|
+
return { acquired: true };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 释放单实例文件锁(FR-018)
|
|
161
|
+
* @param {string} lockPath
|
|
162
|
+
* @returns {{ released: boolean }}
|
|
163
|
+
*/
|
|
164
|
+
export function releaseLock(lockPath) {
|
|
165
|
+
try {
|
|
166
|
+
fs.unlinkSync(lockPath);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
if (err.code === 'ENOENT') {
|
|
169
|
+
// 锁不存在视为已释放(幂等)
|
|
170
|
+
return { released: true };
|
|
171
|
+
}
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
return { released: true };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
178
|
+
// CLI dispatch
|
|
179
|
+
// ──────────────────────────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
function output(data) {
|
|
182
|
+
console.log(JSON.stringify(data, null, 2));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function fail(message) {
|
|
186
|
+
console.error(JSON.stringify({ success: false, error: message }, null, 2));
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function readJsonFile(filePath) {
|
|
191
|
+
if (!filePath) {
|
|
192
|
+
fail('缺少 JSON payload 文件路径参数');
|
|
193
|
+
}
|
|
194
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** 同步读取 stdin(fd 0)全部内容为 UTF-8 文本 */
|
|
198
|
+
function readStdin() {
|
|
199
|
+
return fs.readFileSync(0, 'utf-8');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function parseBool(value, name) {
|
|
203
|
+
if (value === 'true') return true;
|
|
204
|
+
if (value === 'false') return false;
|
|
205
|
+
fail(`参数 ${name} 必须为 true|false,实际为 "${value}"`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function main(argv) {
|
|
209
|
+
const [subcommand, ...args] = argv;
|
|
210
|
+
|
|
211
|
+
switch (subcommand) {
|
|
212
|
+
case 'parse-report': {
|
|
213
|
+
// parseReport 接受原始文本(含可能非法 JSON),故直接读文本不预解析
|
|
214
|
+
const filePath = args[0];
|
|
215
|
+
if (!filePath) fail('parse-report 需要 <reportJsonFile>');
|
|
216
|
+
const text = fs.readFileSync(filePath, 'utf-8');
|
|
217
|
+
output(parseReport(text));
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
case 'classify-command': {
|
|
221
|
+
output({ status: classifyCommand(readJsonFile(args[0])) });
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
case 'decide-stop': {
|
|
225
|
+
const payload = readJsonFile(args[0]);
|
|
226
|
+
output(
|
|
227
|
+
decideStop({
|
|
228
|
+
report: payload.report,
|
|
229
|
+
round: payload.round,
|
|
230
|
+
config: payload.config,
|
|
231
|
+
prevReports: payload.prevReports ?? [],
|
|
232
|
+
rollbackResult: payload.rollbackResult ?? null,
|
|
233
|
+
}),
|
|
234
|
+
);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
case 'plan-snapshot': {
|
|
238
|
+
output({ commands: planSnapshotCommands(parseBool(args[0], 'isClean')) });
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
case 'plan-rollback': {
|
|
242
|
+
output({ commands: planRollbackCommands(readJsonFile(args[0])) });
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
case 'select-verify-mode': {
|
|
246
|
+
const round = Number(args[0]);
|
|
247
|
+
const max = Number(args[1]);
|
|
248
|
+
const aboutToExit = parseBool(args[2], 'aboutToExit');
|
|
249
|
+
if (Number.isNaN(round) || Number.isNaN(max)) {
|
|
250
|
+
fail('select-verify-mode 需要数字 <round> <max>');
|
|
251
|
+
}
|
|
252
|
+
output({ mode: selectVerifyMode(round, max, aboutToExit) });
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
case 'decide-dispatch': {
|
|
256
|
+
if (args.length < 2) fail('decide-dispatch 需要 <phaseId> <agentMode>');
|
|
257
|
+
output(decideDispatch(args[0], args[1]));
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
case 'interpret-impact': {
|
|
261
|
+
output(interpretImpactResult(readJsonFile(args[0])));
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case 'format-iteration-log-entry': {
|
|
265
|
+
// 输出 markdown 块(含内嵌 ```json 围栏)到 stdout,供编排器直接追加写入 iteration-log.md。
|
|
266
|
+
// 与其它子命令不同:本子命令输出原始 markdown 文本,而非 JSON.stringify 包裹(散文直接拼日志)。
|
|
267
|
+
if (!args[0]) fail('format-iteration-log-entry 需要 <entryJsonFile>');
|
|
268
|
+
process.stdout.write(formatIterationLogEntry(readJsonFile(args[0])));
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
case 'assess-preserved-config-safety': {
|
|
272
|
+
// 吃原始 `git status --porcelain` 文本(解析在 core,编排器零解析):
|
|
273
|
+
// porcelain → state 由 parsePreservedConfigStates;state → 安全 由 assessPreservedConfigSafety。
|
|
274
|
+
if (!args[0]) fail('assess-preserved-config-safety 需要 <porcelainFile|-(stdin)>');
|
|
275
|
+
const porcelain = args[0] === '-' ? readStdin() : fs.readFileSync(args[0], 'utf-8');
|
|
276
|
+
const entries = parsePreservedConfigStates(porcelain, PRESERVED_CONFIG_PATHSPECS);
|
|
277
|
+
output(assessPreservedConfigSafety(entries));
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
case 'is-clean-excluding-preserved': {
|
|
281
|
+
// 吃**全仓** `git status --porcelain` 文本(不带 pathspec),排除 PRESERVED_CONFIG_PATHSPECS
|
|
282
|
+
// 后判 isClean——杜绝"唯一 dirty 是 preserved override 却按全仓判 false → 空 stash 抓无关旧
|
|
283
|
+
// stash"的 CRITICAL-7 危险路径。解析全在已单测 core。
|
|
284
|
+
if (!args[0]) fail('is-clean-excluding-preserved 需要 <porcelainFile|-(stdin)>');
|
|
285
|
+
const porcelainAll = args[0] === '-' ? readStdin() : fs.readFileSync(args[0], 'utf-8');
|
|
286
|
+
output({ isClean: isCleanExcludingPreserved(porcelainAll, PRESERVED_CONFIG_PATHSPECS) });
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
case 'acquire-lock': {
|
|
290
|
+
if (!args[0]) fail('acquire-lock 需要 <lockPath>');
|
|
291
|
+
output(acquireLock(args[0]));
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'release-lock': {
|
|
295
|
+
if (!args[0]) fail('release-lock 需要 <lockPath>');
|
|
296
|
+
output(releaseLock(args[0]));
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
default:
|
|
300
|
+
fail(`未知子命令: ${subcommand ?? '(空)'}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// 仅当作为入口脚本直接运行时执行 dispatch(被 import 时不触发,便于单测)
|
|
305
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === fs.realpathSync(process.argv[1])) {
|
|
306
|
+
main(process.argv.slice(2));
|
|
307
|
+
}
|
|
@@ -46,6 +46,7 @@ ALT_CONFIG_FILE="${SPECIFY_DIR}/spec-driver.config.yaml"
|
|
|
46
46
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
47
47
|
PLUGIN_DIR="$(dirname "$SCRIPT_DIR")"
|
|
48
48
|
source "${SCRIPT_DIR}/lib/init-project-output.sh"
|
|
49
|
+
source "${SCRIPT_DIR}/lib/ensure-gitignore.sh"
|
|
49
50
|
SPECIFY_BASE_TEMPLATES_DIR="${PLUGIN_DIR}/templates/specify-base"
|
|
50
51
|
FALLBACK_SPECIFY_TEMPLATES_DIR="${PLUGIN_DIR}/../../.specify/templates"
|
|
51
52
|
DEFAULT_SCORECARD_DIR="${PLUGIN_DIR}/scorecards"
|
|
@@ -291,8 +292,63 @@ detect_spec_driver_skills() {
|
|
|
291
292
|
fi
|
|
292
293
|
}
|
|
293
294
|
|
|
295
|
+
# 步骤 1a: 确保 Spec Driver 落盘产物的 ignore 规则就位(Feature 207,分层防线)
|
|
296
|
+
# 分两条防线:
|
|
297
|
+
# (1) .git/info/exclude — 非 tracked 的主防线(零 diff 污染),仅 .git 为目录时执行
|
|
298
|
+
# (2) .gitignore — 团队共享配置(.git/info/exclude 无法共享的兜底,覆盖 worktree/非 git 场景)
|
|
299
|
+
# 防御:吞掉共享库的非零返回(极端只读文件系统等),只记录信号,绝不 exit 中断初始化
|
|
300
|
+
ensure_gitignore_step() {
|
|
301
|
+
# 主防线:.git/info/exclude(非 git / worktree 场景返回 skipped)
|
|
302
|
+
local exclude_result
|
|
303
|
+
exclude_result="$(ensure_spec_driver_git_exclude "$PROJECT_ROOT")" || {
|
|
304
|
+
INIT_RESULTS+=("git_exclude:skip_error")
|
|
305
|
+
exclude_result="__handled__"
|
|
306
|
+
}
|
|
307
|
+
if [[ "$exclude_result" != "__handled__" ]]; then
|
|
308
|
+
case "$exclude_result" in
|
|
309
|
+
created:*) INIT_RESULTS+=("git_exclude:created:${exclude_result#created:}") ;;
|
|
310
|
+
appended:*) INIT_RESULTS+=("git_exclude:injected:${exclude_result#appended:}") ;;
|
|
311
|
+
ready:*) INIT_RESULTS+=("git_exclude:ready") ;;
|
|
312
|
+
failed:*) INIT_RESULTS+=("git_exclude:skip_error") ;;
|
|
313
|
+
skipped:*) INIT_RESULTS+=("git_exclude:skipped") ;;
|
|
314
|
+
*) INIT_RESULTS+=("git_exclude:unknown") ;;
|
|
315
|
+
esac
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
# 兜底防线:.gitignore(团队共享配置)
|
|
319
|
+
local result
|
|
320
|
+
result="$(ensure_spec_driver_gitignore "$PROJECT_ROOT")" || {
|
|
321
|
+
INIT_RESULTS+=("gitignore:skip_error")
|
|
322
|
+
return 0
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
case "$result" in
|
|
326
|
+
created:*)
|
|
327
|
+
INIT_RESULTS+=("gitignore:created:${result#created:}")
|
|
328
|
+
;;
|
|
329
|
+
appended:*)
|
|
330
|
+
INIT_RESULTS+=("gitignore:injected:${result#appended:}")
|
|
331
|
+
;;
|
|
332
|
+
ready:*)
|
|
333
|
+
INIT_RESULTS+=("gitignore:ready")
|
|
334
|
+
;;
|
|
335
|
+
failed:*)
|
|
336
|
+
# 写入失败(只读 FS 等)→ 复用既有 skip_error 文本分支
|
|
337
|
+
INIT_RESULTS+=("gitignore:skip_error")
|
|
338
|
+
;;
|
|
339
|
+
skipped:*)
|
|
340
|
+
# 并发会话持锁 → 本次跳过检查,下次会话自然补齐(不等同 ready,勿撒谎为已就位)
|
|
341
|
+
INIT_RESULTS+=("gitignore:lock_skipped")
|
|
342
|
+
;;
|
|
343
|
+
*)
|
|
344
|
+
INIT_RESULTS+=("gitignore:unknown")
|
|
345
|
+
;;
|
|
346
|
+
esac
|
|
347
|
+
}
|
|
348
|
+
|
|
294
349
|
run_init_checks() {
|
|
295
350
|
init_specify_dir
|
|
351
|
+
ensure_gitignore_step
|
|
296
352
|
sync_specify_templates
|
|
297
353
|
sync_scorecard_defaults
|
|
298
354
|
ensure_project_context
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* F191 kb-prequery — spec-driver 编排器在 specify 阶段前的 KB 预查(确定性脚本)。
|
|
4
|
+
*
|
|
5
|
+
* 读 resolved knowledge_sources → bin 发现 + 能力探测 → shell out `spectra scaffold-kb query`
|
|
6
|
+
* → 注入块透传 stdout。退出**始终 0**(不阻断 spec-driver 流程);降级原因写 stderr。
|
|
7
|
+
* keyword 提取 / 检索 / 格式化 / 字符 cap 全在 spectra query 侧(本脚本只薄编排)。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { spawnSync } from 'node:child_process';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const PROBE_SENTINEL = 'scaffold-kb-query:1';
|
|
17
|
+
const SPAWN_TIMEOUT_MS = 10_000;
|
|
18
|
+
const MAX_BUFFER = 4 * 1024 * 1024;
|
|
19
|
+
|
|
20
|
+
function parseArgs(argv) {
|
|
21
|
+
const out = {};
|
|
22
|
+
for (let i = 0; i < argv.length; i++) {
|
|
23
|
+
if (argv[i] === '--requirement') out.requirement = argv[++i];
|
|
24
|
+
else if (argv[i] === '--project-root') out.projectRoot = argv[++i];
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function diag(reason) {
|
|
30
|
+
process.stderr.write(`[kb-prequery] ${reason}\n`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 经 resolve-project-context.mjs --json 读取 resolvedProfile.knowledgeSources */
|
|
34
|
+
function resolveKnowledgeSources(projectRoot) {
|
|
35
|
+
const resolver = join(__dirname, 'resolve-project-context.mjs');
|
|
36
|
+
const r = spawnSync('node', [resolver, '--project-root', projectRoot, '--json'], {
|
|
37
|
+
encoding: 'utf-8',
|
|
38
|
+
timeout: SPAWN_TIMEOUT_MS,
|
|
39
|
+
maxBuffer: MAX_BUFFER,
|
|
40
|
+
});
|
|
41
|
+
if (r.status !== 0 || typeof r.stdout !== 'string') return null;
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(r.stdout).resolvedProfile?.knowledgeSources ?? null;
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** bin 发现(覆盖优先):$SPECTRA_BIN → 项目 node_modules/.bin → PATH */
|
|
50
|
+
function discoverSpectraBin(projectRoot) {
|
|
51
|
+
const envBin = process.env['SPECTRA_BIN'];
|
|
52
|
+
if (envBin && existsSync(envBin)) return envBin;
|
|
53
|
+
const local = join(projectRoot, 'node_modules', '.bin', 'spectra');
|
|
54
|
+
if (existsSync(local)) return local;
|
|
55
|
+
return 'spectra'; // 交给 PATH;不存在则 spawnSync ENOENT
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 能力探测:区分 ok / missing(bin 不存在 ENOENT)/ too-old(能跑但无 sentinel = 旧版无 query)。
|
|
60
|
+
* 修 Codex W2:原实现全归 spectra-unavailable,无法区分缺 bin 与旧版。
|
|
61
|
+
*/
|
|
62
|
+
function probeBin(bin) {
|
|
63
|
+
const r = spawnSync(bin, ['scaffold-kb', 'query', '--probe'], {
|
|
64
|
+
encoding: 'utf-8',
|
|
65
|
+
timeout: SPAWN_TIMEOUT_MS,
|
|
66
|
+
maxBuffer: MAX_BUFFER,
|
|
67
|
+
});
|
|
68
|
+
if (r.error && r.error.code === 'ENOENT') return 'missing';
|
|
69
|
+
if (r.status === 0 && typeof r.stdout === 'string' && r.stdout.includes(PROBE_SENTINEL)) return 'ok';
|
|
70
|
+
return 'too-old';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function main() {
|
|
74
|
+
const { requirement, projectRoot = process.cwd() } = parseArgs(process.argv.slice(2));
|
|
75
|
+
if (!requirement) {
|
|
76
|
+
diag('no-requirement');
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const ks = resolveKnowledgeSources(projectRoot);
|
|
81
|
+
if (!ks || ks.enabled !== true || !ks.vendorKb) {
|
|
82
|
+
diag('disabled-or-unconfigured');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const bin = discoverSpectraBin(projectRoot);
|
|
87
|
+
const probeResult = probeBin(bin);
|
|
88
|
+
if (probeResult === 'missing') {
|
|
89
|
+
diag(`spectra-unavailable (bin=${bin}; 未安装 spectra)`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (probeResult === 'too-old') {
|
|
93
|
+
diag(`spectra-too-old (bin=${bin}; 版本过旧,无 scaffold-kb query 子命令)`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const args = [
|
|
98
|
+
'scaffold-kb', 'query',
|
|
99
|
+
'--requirement', requirement,
|
|
100
|
+
'--vendor-kb', ks.vendorKb,
|
|
101
|
+
'--top-k', String(ks.topK ?? 3),
|
|
102
|
+
'--max-inject-chars', String(ks.maxInjectChars ?? 6000),
|
|
103
|
+
'--format', 'markdown',
|
|
104
|
+
];
|
|
105
|
+
if (ks.projectKb) args.push('--project-kb', ks.projectKb);
|
|
106
|
+
|
|
107
|
+
const q = spawnSync(bin, args, {
|
|
108
|
+
encoding: 'utf-8',
|
|
109
|
+
timeout: SPAWN_TIMEOUT_MS,
|
|
110
|
+
maxBuffer: MAX_BUFFER,
|
|
111
|
+
});
|
|
112
|
+
if (q.status !== 0) {
|
|
113
|
+
diag(`query-failed (status=${q.status}): ${(q.stderr ?? '').trim()}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const block = (q.stdout ?? '').trim();
|
|
117
|
+
if (block.length === 0) {
|
|
118
|
+
// 透传 query 自身的结构化降级原因(kb-missing / no-hit / no-query),不再一律标 no-hit(修 Codex W2)
|
|
119
|
+
diag(`no-injection: ${(q.stderr ?? 'no-hit').trim()}`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
process.stdout.write(`${block}\n`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
main();
|