spec-gen-cli 1.0.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/LICENSE +21 -0
- package/README.md +1078 -0
- package/dist/api/analyze.d.ts +17 -0
- package/dist/api/analyze.d.ts.map +1 -0
- package/dist/api/analyze.js +109 -0
- package/dist/api/analyze.js.map +1 -0
- package/dist/api/drift.d.ts +21 -0
- package/dist/api/drift.d.ts.map +1 -0
- package/dist/api/drift.js +145 -0
- package/dist/api/drift.js.map +1 -0
- package/dist/api/generate.d.ts +18 -0
- package/dist/api/generate.d.ts.map +1 -0
- package/dist/api/generate.js +251 -0
- package/dist/api/generate.js.map +1 -0
- package/dist/api/index.d.ts +39 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +32 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/init.d.ts +18 -0
- package/dist/api/init.d.ts.map +1 -0
- package/dist/api/init.js +82 -0
- package/dist/api/init.js.map +1 -0
- package/dist/api/run.d.ts +19 -0
- package/dist/api/run.d.ts.map +1 -0
- package/dist/api/run.js +291 -0
- package/dist/api/run.js.map +1 -0
- package/dist/api/specs.d.ts +49 -0
- package/dist/api/specs.d.ts.map +1 -0
- package/dist/api/specs.js +136 -0
- package/dist/api/specs.js.map +1 -0
- package/dist/api/types.d.ts +176 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +9 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/verify.d.ts +20 -0
- package/dist/api/verify.d.ts.map +1 -0
- package/dist/api/verify.js +117 -0
- package/dist/api/verify.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +27 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +485 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/drift.d.ts +9 -0
- package/dist/cli/commands/drift.d.ts.map +1 -0
- package/dist/cli/commands/drift.js +540 -0
- package/dist/cli/commands/drift.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +9 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +633 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +171 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +638 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +574 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/run.d.ts +24 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +546 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/verify.d.ts +9 -0
- package/dist/cli/commands/verify.d.ts.map +1 -0
- package/dist/cli/commands/verify.js +417 -0
- package/dist/cli/commands/verify.js.map +1 -0
- package/dist/cli/commands/view.d.ts +9 -0
- package/dist/cli/commands/view.d.ts.map +1 -0
- package/dist/cli/commands/view.js +511 -0
- package/dist/cli/commands/view.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +83 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/analyzer/architecture-writer.d.ts +67 -0
- package/dist/core/analyzer/architecture-writer.d.ts.map +1 -0
- package/dist/core/analyzer/architecture-writer.js +209 -0
- package/dist/core/analyzer/architecture-writer.js.map +1 -0
- package/dist/core/analyzer/artifact-generator.d.ts +222 -0
- package/dist/core/analyzer/artifact-generator.d.ts.map +1 -0
- package/dist/core/analyzer/artifact-generator.js +726 -0
- package/dist/core/analyzer/artifact-generator.js.map +1 -0
- package/dist/core/analyzer/call-graph.d.ts +83 -0
- package/dist/core/analyzer/call-graph.d.ts.map +1 -0
- package/dist/core/analyzer/call-graph.js +827 -0
- package/dist/core/analyzer/call-graph.js.map +1 -0
- package/dist/core/analyzer/code-shaper.d.ts +33 -0
- package/dist/core/analyzer/code-shaper.d.ts.map +1 -0
- package/dist/core/analyzer/code-shaper.js +149 -0
- package/dist/core/analyzer/code-shaper.js.map +1 -0
- package/dist/core/analyzer/dependency-graph.d.ts +179 -0
- package/dist/core/analyzer/dependency-graph.d.ts.map +1 -0
- package/dist/core/analyzer/dependency-graph.js +574 -0
- package/dist/core/analyzer/dependency-graph.js.map +1 -0
- package/dist/core/analyzer/duplicate-detector.d.ts +52 -0
- package/dist/core/analyzer/duplicate-detector.d.ts.map +1 -0
- package/dist/core/analyzer/duplicate-detector.js +279 -0
- package/dist/core/analyzer/duplicate-detector.js.map +1 -0
- package/dist/core/analyzer/embedding-service.d.ts +50 -0
- package/dist/core/analyzer/embedding-service.d.ts.map +1 -0
- package/dist/core/analyzer/embedding-service.js +104 -0
- package/dist/core/analyzer/embedding-service.js.map +1 -0
- package/dist/core/analyzer/file-walker.d.ts +78 -0
- package/dist/core/analyzer/file-walker.d.ts.map +1 -0
- package/dist/core/analyzer/file-walker.js +531 -0
- package/dist/core/analyzer/file-walker.js.map +1 -0
- package/dist/core/analyzer/import-parser.d.ts +91 -0
- package/dist/core/analyzer/import-parser.d.ts.map +1 -0
- package/dist/core/analyzer/import-parser.js +720 -0
- package/dist/core/analyzer/import-parser.js.map +1 -0
- package/dist/core/analyzer/index.d.ts +10 -0
- package/dist/core/analyzer/index.d.ts.map +1 -0
- package/dist/core/analyzer/index.js +10 -0
- package/dist/core/analyzer/index.js.map +1 -0
- package/dist/core/analyzer/refactor-analyzer.d.ts +80 -0
- package/dist/core/analyzer/refactor-analyzer.d.ts.map +1 -0
- package/dist/core/analyzer/refactor-analyzer.js +339 -0
- package/dist/core/analyzer/refactor-analyzer.js.map +1 -0
- package/dist/core/analyzer/repository-mapper.d.ts +150 -0
- package/dist/core/analyzer/repository-mapper.d.ts.map +1 -0
- package/dist/core/analyzer/repository-mapper.js +731 -0
- package/dist/core/analyzer/repository-mapper.js.map +1 -0
- package/dist/core/analyzer/signature-extractor.d.ts +31 -0
- package/dist/core/analyzer/signature-extractor.d.ts.map +1 -0
- package/dist/core/analyzer/signature-extractor.js +387 -0
- package/dist/core/analyzer/signature-extractor.js.map +1 -0
- package/dist/core/analyzer/significance-scorer.d.ts +79 -0
- package/dist/core/analyzer/significance-scorer.d.ts.map +1 -0
- package/dist/core/analyzer/significance-scorer.js +407 -0
- package/dist/core/analyzer/significance-scorer.js.map +1 -0
- package/dist/core/analyzer/subgraph-extractor.d.ts +43 -0
- package/dist/core/analyzer/subgraph-extractor.d.ts.map +1 -0
- package/dist/core/analyzer/subgraph-extractor.js +129 -0
- package/dist/core/analyzer/subgraph-extractor.js.map +1 -0
- package/dist/core/analyzer/vector-index.d.ts +63 -0
- package/dist/core/analyzer/vector-index.d.ts.map +1 -0
- package/dist/core/analyzer/vector-index.js +169 -0
- package/dist/core/analyzer/vector-index.js.map +1 -0
- package/dist/core/drift/drift-detector.d.ts +102 -0
- package/dist/core/drift/drift-detector.d.ts.map +1 -0
- package/dist/core/drift/drift-detector.js +597 -0
- package/dist/core/drift/drift-detector.js.map +1 -0
- package/dist/core/drift/git-diff.d.ts +55 -0
- package/dist/core/drift/git-diff.d.ts.map +1 -0
- package/dist/core/drift/git-diff.js +356 -0
- package/dist/core/drift/git-diff.js.map +1 -0
- package/dist/core/drift/index.d.ts +12 -0
- package/dist/core/drift/index.d.ts.map +1 -0
- package/dist/core/drift/index.js +9 -0
- package/dist/core/drift/index.js.map +1 -0
- package/dist/core/drift/spec-mapper.d.ts +73 -0
- package/dist/core/drift/spec-mapper.d.ts.map +1 -0
- package/dist/core/drift/spec-mapper.js +353 -0
- package/dist/core/drift/spec-mapper.js.map +1 -0
- package/dist/core/generator/adr-generator.d.ts +32 -0
- package/dist/core/generator/adr-generator.d.ts.map +1 -0
- package/dist/core/generator/adr-generator.js +192 -0
- package/dist/core/generator/adr-generator.js.map +1 -0
- package/dist/core/generator/index.d.ts +9 -0
- package/dist/core/generator/index.d.ts.map +1 -0
- package/dist/core/generator/index.js +12 -0
- package/dist/core/generator/index.js.map +1 -0
- package/dist/core/generator/mapping-generator.d.ts +54 -0
- package/dist/core/generator/mapping-generator.d.ts.map +1 -0
- package/dist/core/generator/mapping-generator.js +239 -0
- package/dist/core/generator/mapping-generator.js.map +1 -0
- package/dist/core/generator/openspec-compat.d.ts +160 -0
- package/dist/core/generator/openspec-compat.d.ts.map +1 -0
- package/dist/core/generator/openspec-compat.js +523 -0
- package/dist/core/generator/openspec-compat.js.map +1 -0
- package/dist/core/generator/openspec-format-generator.d.ts +111 -0
- package/dist/core/generator/openspec-format-generator.d.ts.map +1 -0
- package/dist/core/generator/openspec-format-generator.js +817 -0
- package/dist/core/generator/openspec-format-generator.js.map +1 -0
- package/dist/core/generator/openspec-writer.d.ts +131 -0
- package/dist/core/generator/openspec-writer.d.ts.map +1 -0
- package/dist/core/generator/openspec-writer.js +379 -0
- package/dist/core/generator/openspec-writer.js.map +1 -0
- package/dist/core/generator/prompts.d.ts +35 -0
- package/dist/core/generator/prompts.d.ts.map +1 -0
- package/dist/core/generator/prompts.js +212 -0
- package/dist/core/generator/prompts.js.map +1 -0
- package/dist/core/generator/spec-pipeline.d.ts +94 -0
- package/dist/core/generator/spec-pipeline.d.ts.map +1 -0
- package/dist/core/generator/spec-pipeline.js +474 -0
- package/dist/core/generator/spec-pipeline.js.map +1 -0
- package/dist/core/generator/stages/stage1-survey.d.ts +19 -0
- package/dist/core/generator/stages/stage1-survey.d.ts.map +1 -0
- package/dist/core/generator/stages/stage1-survey.js +105 -0
- package/dist/core/generator/stages/stage1-survey.js.map +1 -0
- package/dist/core/generator/stages/stage2-entities.d.ts +11 -0
- package/dist/core/generator/stages/stage2-entities.d.ts.map +1 -0
- package/dist/core/generator/stages/stage2-entities.js +67 -0
- package/dist/core/generator/stages/stage2-entities.js.map +1 -0
- package/dist/core/generator/stages/stage3-services.d.ts +11 -0
- package/dist/core/generator/stages/stage3-services.d.ts.map +1 -0
- package/dist/core/generator/stages/stage3-services.js +75 -0
- package/dist/core/generator/stages/stage3-services.js.map +1 -0
- package/dist/core/generator/stages/stage4-api.d.ts +11 -0
- package/dist/core/generator/stages/stage4-api.d.ts.map +1 -0
- package/dist/core/generator/stages/stage4-api.js +65 -0
- package/dist/core/generator/stages/stage4-api.js.map +1 -0
- package/dist/core/generator/stages/stage5-architecture.d.ts +10 -0
- package/dist/core/generator/stages/stage5-architecture.d.ts.map +1 -0
- package/dist/core/generator/stages/stage5-architecture.js +62 -0
- package/dist/core/generator/stages/stage5-architecture.js.map +1 -0
- package/dist/core/generator/stages/stage6-adr.d.ts +8 -0
- package/dist/core/generator/stages/stage6-adr.d.ts.map +1 -0
- package/dist/core/generator/stages/stage6-adr.js +41 -0
- package/dist/core/generator/stages/stage6-adr.js.map +1 -0
- package/dist/core/services/chat-agent.d.ts +45 -0
- package/dist/core/services/chat-agent.d.ts.map +1 -0
- package/dist/core/services/chat-agent.js +310 -0
- package/dist/core/services/chat-agent.js.map +1 -0
- package/dist/core/services/chat-tools.d.ts +32 -0
- package/dist/core/services/chat-tools.d.ts.map +1 -0
- package/dist/core/services/chat-tools.js +270 -0
- package/dist/core/services/chat-tools.js.map +1 -0
- package/dist/core/services/config-manager.d.ts +61 -0
- package/dist/core/services/config-manager.d.ts.map +1 -0
- package/dist/core/services/config-manager.js +143 -0
- package/dist/core/services/config-manager.js.map +1 -0
- package/dist/core/services/gitignore-manager.d.ts +29 -0
- package/dist/core/services/gitignore-manager.d.ts.map +1 -0
- package/dist/core/services/gitignore-manager.js +106 -0
- package/dist/core/services/gitignore-manager.js.map +1 -0
- package/dist/core/services/index.d.ts +8 -0
- package/dist/core/services/index.d.ts.map +1 -0
- package/dist/core/services/index.js +8 -0
- package/dist/core/services/index.js.map +1 -0
- package/dist/core/services/llm-service.d.ts +336 -0
- package/dist/core/services/llm-service.d.ts.map +1 -0
- package/dist/core/services/llm-service.js +1155 -0
- package/dist/core/services/llm-service.js.map +1 -0
- package/dist/core/services/mcp-handlers/analysis.d.ts +42 -0
- package/dist/core/services/mcp-handlers/analysis.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/analysis.js +300 -0
- package/dist/core/services/mcp-handlers/analysis.js.map +1 -0
- package/dist/core/services/mcp-handlers/graph.d.ts +65 -0
- package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/graph.js +509 -0
- package/dist/core/services/mcp-handlers/graph.js.map +1 -0
- package/dist/core/services/mcp-handlers/semantic.d.ts +38 -0
- package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/semantic.js +172 -0
- package/dist/core/services/mcp-handlers/semantic.js.map +1 -0
- package/dist/core/services/mcp-handlers/utils.d.ts +21 -0
- package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/utils.js +62 -0
- package/dist/core/services/mcp-handlers/utils.js.map +1 -0
- package/dist/core/services/project-detector.d.ts +32 -0
- package/dist/core/services/project-detector.d.ts.map +1 -0
- package/dist/core/services/project-detector.js +111 -0
- package/dist/core/services/project-detector.js.map +1 -0
- package/dist/core/verifier/index.d.ts +5 -0
- package/dist/core/verifier/index.d.ts.map +1 -0
- package/dist/core/verifier/index.js +5 -0
- package/dist/core/verifier/index.js.map +1 -0
- package/dist/core/verifier/verification-engine.d.ts +226 -0
- package/dist/core/verifier/verification-engine.d.ts.map +1 -0
- package/dist/core/verifier/verification-engine.js +681 -0
- package/dist/core/verifier/verification-engine.js.map +1 -0
- package/dist/types/index.d.ts +252 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/pipeline.d.ts +148 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +5 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/utils/errors.d.ts +51 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +128 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/logger.d.ts +149 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +331 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/progress.d.ts +142 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +280 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/prompts.d.ts +53 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +199 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/shutdown.d.ts +89 -0
- package/dist/utils/shutdown.d.ts.map +1 -0
- package/dist/utils/shutdown.js +237 -0
- package/dist/utils/shutdown.js.map +1 -0
- package/package.json +114 -0
- package/src/viewer/InteractiveGraphViewer.jsx +1486 -0
- package/src/viewer/app/index.html +17 -0
- package/src/viewer/app/main.jsx +13 -0
- package/src/viewer/components/ArchitectureView.jsx +177 -0
- package/src/viewer/components/ChatPanel.jsx +448 -0
- package/src/viewer/components/ClusterGraph.jsx +441 -0
- package/src/viewer/components/FilterBar.jsx +179 -0
- package/src/viewer/components/FlatGraph.jsx +275 -0
- package/src/viewer/components/MicroComponents.jsx +83 -0
- package/src/viewer/hooks/usePanZoom.js +79 -0
- package/src/viewer/utils/constants.js +47 -0
- package/src/viewer/utils/graph-helpers.js +291 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mapping Generator
|
|
3
|
+
*
|
|
4
|
+
* Builds a requirement→function mapping artifact from pipeline results and
|
|
5
|
+
* the dependency graph. Written to .spec-gen/analysis/mapping.json.
|
|
6
|
+
*
|
|
7
|
+
* Enables refactoring workflows: dead code detection, naming normalization.
|
|
8
|
+
*/
|
|
9
|
+
import type { PipelineResult } from './spec-pipeline.js';
|
|
10
|
+
import type { DependencyGraphResult } from '../analyzer/dependency-graph.js';
|
|
11
|
+
import type { SearchResult } from '../analyzer/vector-index.js';
|
|
12
|
+
export interface FunctionRef {
|
|
13
|
+
name: string;
|
|
14
|
+
file: string;
|
|
15
|
+
line: number;
|
|
16
|
+
kind: string;
|
|
17
|
+
confidence: 'llm' | 'semantic' | 'heuristic';
|
|
18
|
+
}
|
|
19
|
+
export interface RequirementMapping {
|
|
20
|
+
requirement: string;
|
|
21
|
+
service: string;
|
|
22
|
+
domain: string;
|
|
23
|
+
specFile: string;
|
|
24
|
+
functions: FunctionRef[];
|
|
25
|
+
}
|
|
26
|
+
export interface MappingArtifact {
|
|
27
|
+
generatedAt: string;
|
|
28
|
+
mappings: RequirementMapping[];
|
|
29
|
+
orphanFunctions: FunctionRef[];
|
|
30
|
+
stats: {
|
|
31
|
+
totalRequirements: number;
|
|
32
|
+
mappedRequirements: number;
|
|
33
|
+
totalExportedFunctions: number;
|
|
34
|
+
orphanCount: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A semantic search function closed over VectorIndex + EmbeddingService + outputDir.
|
|
39
|
+
* Returns ranked results (closest first, score = cosine distance) for a text query.
|
|
40
|
+
*/
|
|
41
|
+
export type SemanticSearchFn = (query: string, limit: number) => Promise<SearchResult[]>;
|
|
42
|
+
export declare class MappingGenerator {
|
|
43
|
+
private rootPath;
|
|
44
|
+
private openspecPath;
|
|
45
|
+
private semanticSearch?;
|
|
46
|
+
constructor(rootPath: string, openspecPath?: string, semanticSearch?: SemanticSearchFn);
|
|
47
|
+
/** Semantic lookup: returns FunctionRefs matched by vector similarity */
|
|
48
|
+
private semanticMatch;
|
|
49
|
+
generate(pipeline: PipelineResult, depGraph: DependencyGraphResult): Promise<MappingArtifact>;
|
|
50
|
+
private write;
|
|
51
|
+
/** Load an existing mapping artifact */
|
|
52
|
+
static load(rootPath: string): Promise<MappingArtifact | null>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=mapping-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapping-generator.d.ts","sourceRoot":"","sources":["../../../src/core/generator/mapping-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAMhE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,KAAK,GAAG,UAAU,GAAG,WAAW,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,KAAK,EAAE;QACL,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,sBAAsB,EAAE,MAAM,CAAC;QAC/B,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AA4CD;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;AAQzF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAC,CAAmB;gBAGxC,QAAQ,EAAE,MAAM,EAChB,YAAY,SAAa,EACzB,cAAc,CAAC,EAAE,gBAAgB;IAOnC,yEAAyE;YAC3D,aAAa;IAyBrB,QAAQ,CACZ,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,qBAAqB,GAC9B,OAAO,CAAC,eAAe,CAAC;YAiKb,KAAK;IAKnB,wCAAwC;WAC3B,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAWrE"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mapping Generator
|
|
3
|
+
*
|
|
4
|
+
* Builds a requirement→function mapping artifact from pipeline results and
|
|
5
|
+
* the dependency graph. Written to .spec-gen/analysis/mapping.json.
|
|
6
|
+
*
|
|
7
|
+
* Enables refactoring workflows: dead code detection, naming normalization.
|
|
8
|
+
*/
|
|
9
|
+
import { writeFile, readFile } from 'node:fs/promises';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// HELPERS
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/** Normalize a name for fuzzy matching: lowercase, alphanumeric only */
|
|
15
|
+
function normalize(name) {
|
|
16
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
17
|
+
}
|
|
18
|
+
/** Split camelCase/PascalCase into tokens for better matching */
|
|
19
|
+
function tokenize(name) {
|
|
20
|
+
return name
|
|
21
|
+
.replace(/([A-Z])/g, ' $1')
|
|
22
|
+
.toLowerCase()
|
|
23
|
+
.split(/[\s_-]+/)
|
|
24
|
+
.filter(Boolean);
|
|
25
|
+
}
|
|
26
|
+
/** Score similarity between an operation name and a function name */
|
|
27
|
+
function similarityScore(operationName, functionName) {
|
|
28
|
+
const opNorm = normalize(operationName);
|
|
29
|
+
const fnNorm = normalize(functionName);
|
|
30
|
+
// Exact normalized match
|
|
31
|
+
if (opNorm === fnNorm)
|
|
32
|
+
return 1.0;
|
|
33
|
+
// Containment
|
|
34
|
+
if (fnNorm.includes(opNorm) || opNorm.includes(fnNorm))
|
|
35
|
+
return 0.8;
|
|
36
|
+
// Token overlap
|
|
37
|
+
const opTokens = new Set(tokenize(operationName));
|
|
38
|
+
const fnTokens = new Set(tokenize(functionName));
|
|
39
|
+
const intersection = [...opTokens].filter(t => fnTokens.has(t)).length;
|
|
40
|
+
const union = new Set([...opTokens, ...fnTokens]).size;
|
|
41
|
+
if (union === 0)
|
|
42
|
+
return 0;
|
|
43
|
+
return (intersection / union) * 0.7;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Maximum cosine distance to accept a semantic match.
|
|
47
|
+
* Equivalent to cosine similarity >= 0.65 (distance = 1 - similarity).
|
|
48
|
+
*/
|
|
49
|
+
const SEMANTIC_MAX_DISTANCE = 0.35;
|
|
50
|
+
export class MappingGenerator {
|
|
51
|
+
rootPath;
|
|
52
|
+
openspecPath;
|
|
53
|
+
semanticSearch;
|
|
54
|
+
constructor(rootPath, openspecPath = 'openspec', semanticSearch) {
|
|
55
|
+
this.rootPath = rootPath;
|
|
56
|
+
this.openspecPath = openspecPath;
|
|
57
|
+
this.semanticSearch = semanticSearch;
|
|
58
|
+
}
|
|
59
|
+
/** Semantic lookup: returns FunctionRefs matched by vector similarity */
|
|
60
|
+
async semanticMatch(query, exportIndex) {
|
|
61
|
+
if (!this.semanticSearch)
|
|
62
|
+
return [];
|
|
63
|
+
let results;
|
|
64
|
+
try {
|
|
65
|
+
results = await this.semanticSearch(query, 5);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const matched = [];
|
|
71
|
+
for (const r of results.filter(r => r.score <= SEMANTIC_MAX_DISTANCE)) {
|
|
72
|
+
const refs = exportIndex.get(r.record.name);
|
|
73
|
+
if (refs && refs.length > 0) {
|
|
74
|
+
for (const ref of refs) {
|
|
75
|
+
matched.push({ ...ref, confidence: 'semantic' });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return matched.slice(0, 2);
|
|
80
|
+
}
|
|
81
|
+
async generate(pipeline, depGraph) {
|
|
82
|
+
// Build export index: name → list of FunctionRef (multiple files can export same name)
|
|
83
|
+
const exportIndex = new Map();
|
|
84
|
+
for (const node of depGraph.nodes) {
|
|
85
|
+
const relPath = node.file.path;
|
|
86
|
+
for (const exp of node.exports) {
|
|
87
|
+
if (exp.isType)
|
|
88
|
+
continue; // skip type-only exports
|
|
89
|
+
const ref = {
|
|
90
|
+
name: exp.name,
|
|
91
|
+
file: relPath,
|
|
92
|
+
line: exp.line,
|
|
93
|
+
kind: exp.kind,
|
|
94
|
+
confidence: 'llm', // placeholder, overwritten below
|
|
95
|
+
};
|
|
96
|
+
const existing = exportIndex.get(exp.name) ?? [];
|
|
97
|
+
existing.push(ref);
|
|
98
|
+
exportIndex.set(exp.name, existing);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const mappings = [];
|
|
102
|
+
const mappedFunctionNames = new Set(); // track name+file combos
|
|
103
|
+
for (const service of pipeline.services) {
|
|
104
|
+
const domain = service.domain || 'core';
|
|
105
|
+
const specFile = `${this.openspecPath}/specs/${domain.toLowerCase()}/spec.md`;
|
|
106
|
+
for (const op of service.operations) {
|
|
107
|
+
const functions = [];
|
|
108
|
+
// 1. LLM-provided functionName — direct lookup
|
|
109
|
+
if (op.functionName && op.functionName.trim()) {
|
|
110
|
+
const refs = exportIndex.get(op.functionName.trim());
|
|
111
|
+
if (refs && refs.length > 0) {
|
|
112
|
+
for (const ref of refs) {
|
|
113
|
+
functions.push({ ...ref, confidence: 'llm' });
|
|
114
|
+
mappedFunctionNames.add(`${ref.name}::${ref.file}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// 2. Semantic fallback — vector similarity on operation name + description
|
|
119
|
+
if (functions.length === 0) {
|
|
120
|
+
const query = op.description ? `${op.name} ${op.description}` : op.name;
|
|
121
|
+
const semanticRefs = await this.semanticMatch(query, exportIndex);
|
|
122
|
+
for (const ref of semanticRefs) {
|
|
123
|
+
functions.push(ref);
|
|
124
|
+
mappedFunctionNames.add(`${ref.name}::${ref.file}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// 3. Heuristic fallback — find best matching export(s)
|
|
128
|
+
if (functions.length === 0) {
|
|
129
|
+
const scored = [];
|
|
130
|
+
for (const [name, refs] of exportIndex) {
|
|
131
|
+
const score = similarityScore(op.name, name);
|
|
132
|
+
if (score >= 0.7) {
|
|
133
|
+
for (const ref of refs) {
|
|
134
|
+
scored.push({ ref, score });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
scored.sort((a, b) => b.score - a.score);
|
|
139
|
+
const top = scored.slice(0, 2); // at most 2 heuristic matches
|
|
140
|
+
for (const { ref } of top) {
|
|
141
|
+
functions.push({ ...ref, confidence: 'heuristic' });
|
|
142
|
+
mappedFunctionNames.add(`${ref.name}::${ref.file}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
mappings.push({
|
|
146
|
+
requirement: op.name,
|
|
147
|
+
service: service.name,
|
|
148
|
+
domain,
|
|
149
|
+
specFile,
|
|
150
|
+
functions,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Sub-spec operations: map each sub-component's operations to its callee function
|
|
154
|
+
for (const sub of service.subSpecs ?? []) {
|
|
155
|
+
// The callee is a direct LLM-identified function name — prefer exact match
|
|
156
|
+
const calleeRefs = exportIndex.get(sub.callee) ?? [];
|
|
157
|
+
for (const op of sub.operations ?? []) {
|
|
158
|
+
const functions = [];
|
|
159
|
+
// 1. LLM-provided callee — direct lookup
|
|
160
|
+
if (calleeRefs.length > 0) {
|
|
161
|
+
for (const ref of calleeRefs) {
|
|
162
|
+
functions.push({ ...ref, confidence: 'llm' });
|
|
163
|
+
mappedFunctionNames.add(`${ref.name}::${ref.file}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// 2. Semantic fallback
|
|
167
|
+
if (functions.length === 0) {
|
|
168
|
+
const query = op.description ? `${op.name} ${op.description}` : op.name;
|
|
169
|
+
const semanticRefs = await this.semanticMatch(query, exportIndex);
|
|
170
|
+
for (const ref of semanticRefs) {
|
|
171
|
+
functions.push(ref);
|
|
172
|
+
mappedFunctionNames.add(`${ref.name}::${ref.file}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// 3. Heuristic fallback on operation name
|
|
176
|
+
if (functions.length === 0) {
|
|
177
|
+
const scored = [];
|
|
178
|
+
for (const [name, refs] of exportIndex) {
|
|
179
|
+
const score = similarityScore(op.name, name);
|
|
180
|
+
if (score >= 0.7) {
|
|
181
|
+
for (const ref of refs)
|
|
182
|
+
scored.push({ ref, score });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
scored.sort((a, b) => b.score - a.score);
|
|
186
|
+
for (const { ref } of scored.slice(0, 2)) {
|
|
187
|
+
functions.push({ ...ref, confidence: 'heuristic' });
|
|
188
|
+
mappedFunctionNames.add(`${ref.name}::${ref.file}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
mappings.push({
|
|
192
|
+
requirement: op.name,
|
|
193
|
+
service: `${service.name}/${sub.name}`,
|
|
194
|
+
domain,
|
|
195
|
+
specFile,
|
|
196
|
+
functions,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Orphan functions: exported, non-type, not referenced in any mapping
|
|
202
|
+
const orphanFunctions = [];
|
|
203
|
+
for (const [name, refs] of exportIndex) {
|
|
204
|
+
for (const ref of refs) {
|
|
205
|
+
if (!mappedFunctionNames.has(`${name}::${ref.file}`)) {
|
|
206
|
+
orphanFunctions.push({ ...ref, confidence: 'heuristic' });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const artifact = {
|
|
211
|
+
generatedAt: new Date().toISOString(),
|
|
212
|
+
mappings,
|
|
213
|
+
orphanFunctions,
|
|
214
|
+
stats: {
|
|
215
|
+
totalRequirements: mappings.length,
|
|
216
|
+
mappedRequirements: mappings.filter(m => m.functions.length > 0).length,
|
|
217
|
+
totalExportedFunctions: [...exportIndex.values()].reduce((s, refs) => s + refs.length, 0),
|
|
218
|
+
orphanCount: orphanFunctions.length,
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
await this.write(artifact);
|
|
222
|
+
return artifact;
|
|
223
|
+
}
|
|
224
|
+
async write(artifact) {
|
|
225
|
+
const outPath = join(this.rootPath, '.spec-gen', 'analysis', 'mapping.json');
|
|
226
|
+
await writeFile(outPath, JSON.stringify(artifact, null, 2), 'utf-8');
|
|
227
|
+
}
|
|
228
|
+
/** Load an existing mapping artifact */
|
|
229
|
+
static async load(rootPath) {
|
|
230
|
+
try {
|
|
231
|
+
const content = await readFile(join(rootPath, '.spec-gen', 'analysis', 'mapping.json'), 'utf-8');
|
|
232
|
+
return JSON.parse(content);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=mapping-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapping-generator.js","sourceRoot":"","sources":["../../../src/core/generator/mapping-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSpec Compatibility Layer
|
|
3
|
+
*
|
|
4
|
+
* Ensures perfect compatibility with OpenSpec's tooling and conventions.
|
|
5
|
+
* Handles config.yaml integration, validation, and context injection.
|
|
6
|
+
*/
|
|
7
|
+
import type { ProjectSurveyResult } from './spec-pipeline.js';
|
|
8
|
+
/**
|
|
9
|
+
* Validation result for specs and config
|
|
10
|
+
*/
|
|
11
|
+
export interface ValidationResult {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
errors: string[];
|
|
14
|
+
warnings: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* OpenSpec config.yaml structure
|
|
18
|
+
*/
|
|
19
|
+
export interface OpenSpecConfig {
|
|
20
|
+
schema?: string;
|
|
21
|
+
context?: string;
|
|
22
|
+
rules?: {
|
|
23
|
+
proposal?: string[];
|
|
24
|
+
specs?: string[];
|
|
25
|
+
design?: string[];
|
|
26
|
+
tasks?: string[];
|
|
27
|
+
};
|
|
28
|
+
'spec-gen'?: SpecGenMetadata;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* spec-gen metadata added to config.yaml
|
|
32
|
+
*/
|
|
33
|
+
export interface SpecGenMetadata {
|
|
34
|
+
version: string;
|
|
35
|
+
generatedAt: string;
|
|
36
|
+
domains: string[];
|
|
37
|
+
confidence: number;
|
|
38
|
+
adrCount?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detected project context for injection
|
|
42
|
+
*/
|
|
43
|
+
export interface DetectedContext {
|
|
44
|
+
techStack: string;
|
|
45
|
+
architecture: string;
|
|
46
|
+
domains: string[];
|
|
47
|
+
patterns: string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Options for context update
|
|
51
|
+
*/
|
|
52
|
+
export interface ContextUpdateOptions {
|
|
53
|
+
preserveUserContext: boolean;
|
|
54
|
+
appendDetectedInfo: boolean;
|
|
55
|
+
version: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* OpenSpec validator for specs and configuration
|
|
59
|
+
*/
|
|
60
|
+
export declare class OpenSpecValidator {
|
|
61
|
+
/**
|
|
62
|
+
* Validate the complete spec structure
|
|
63
|
+
*/
|
|
64
|
+
validateSpecStructure(content: string): ValidationResult;
|
|
65
|
+
/**
|
|
66
|
+
* Validate requirement format follows RFC 2119
|
|
67
|
+
*/
|
|
68
|
+
validateRequirementFormat(requirement: string): ValidationResult;
|
|
69
|
+
/**
|
|
70
|
+
* Validate scenario format (Given/When/Then)
|
|
71
|
+
*/
|
|
72
|
+
validateScenarioFormat(scenario: string): ValidationResult;
|
|
73
|
+
/**
|
|
74
|
+
* Validate config.yaml structure
|
|
75
|
+
*/
|
|
76
|
+
validateConfigYaml(config: unknown): ValidationResult;
|
|
77
|
+
/**
|
|
78
|
+
* Check heading hierarchy is valid (no skipped levels)
|
|
79
|
+
*/
|
|
80
|
+
private checkHeadingHierarchy;
|
|
81
|
+
/**
|
|
82
|
+
* Check for malformed markdown links
|
|
83
|
+
*/
|
|
84
|
+
private checkMarkdownLinks;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* OpenSpec config.yaml manager
|
|
88
|
+
*/
|
|
89
|
+
export declare class OpenSpecConfigManager {
|
|
90
|
+
private configPath;
|
|
91
|
+
private openspecRoot;
|
|
92
|
+
constructor(projectRoot: string);
|
|
93
|
+
/**
|
|
94
|
+
* Check if OpenSpec is initialized
|
|
95
|
+
*/
|
|
96
|
+
isInitialized(): Promise<boolean>;
|
|
97
|
+
/**
|
|
98
|
+
* Check if config.yaml exists
|
|
99
|
+
*/
|
|
100
|
+
hasConfig(): Promise<boolean>;
|
|
101
|
+
/**
|
|
102
|
+
* Read existing config.yaml
|
|
103
|
+
*/
|
|
104
|
+
readConfig(): Promise<OpenSpecConfig | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Write config.yaml, preserving user content
|
|
107
|
+
*/
|
|
108
|
+
writeConfig(config: OpenSpecConfig): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Update config with spec-gen metadata while preserving user content
|
|
111
|
+
*/
|
|
112
|
+
updateWithSpecGenMetadata(metadata: SpecGenMetadata, detectedContext?: DetectedContext, options?: ContextUpdateOptions): Promise<OpenSpecConfig>;
|
|
113
|
+
/**
|
|
114
|
+
* Build context string combining user and detected info
|
|
115
|
+
*/
|
|
116
|
+
private buildContext;
|
|
117
|
+
/**
|
|
118
|
+
* Get existing user context from config
|
|
119
|
+
*/
|
|
120
|
+
getUserContext(): Promise<string | null>;
|
|
121
|
+
/**
|
|
122
|
+
* Get existing domains from specs directory
|
|
123
|
+
*/
|
|
124
|
+
getExistingDomains(): Promise<string[]>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Build detected context from analysis results
|
|
128
|
+
*/
|
|
129
|
+
export declare function buildDetectedContext(survey: ProjectSurveyResult): DetectedContext;
|
|
130
|
+
/**
|
|
131
|
+
* Normalize domain name to OpenSpec conventions
|
|
132
|
+
*/
|
|
133
|
+
export declare function normalizeDomainName(name: string): string;
|
|
134
|
+
/**
|
|
135
|
+
* Check if domain name follows conventions
|
|
136
|
+
*/
|
|
137
|
+
export declare function isValidDomainName(name: string): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Match suggested domains against existing domains
|
|
140
|
+
*/
|
|
141
|
+
export declare function matchExistingDomains(suggestedDomains: string[], existingDomains: string[]): Map<string, string>;
|
|
142
|
+
/**
|
|
143
|
+
* Validate a complete spec file
|
|
144
|
+
*/
|
|
145
|
+
export declare function validateFullSpec(content: string): ValidationResult;
|
|
146
|
+
/**
|
|
147
|
+
* Validate all specs in a directory
|
|
148
|
+
*/
|
|
149
|
+
export declare function validateSpecsDirectory(specsDir: string): Promise<{
|
|
150
|
+
valid: boolean;
|
|
151
|
+
results: Map<string, ValidationResult>;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* Create a new OpenSpec compatibility helper
|
|
155
|
+
*/
|
|
156
|
+
export declare function createOpenSpecCompat(projectRoot: string): {
|
|
157
|
+
validator: OpenSpecValidator;
|
|
158
|
+
configManager: OpenSpecConfigManager;
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=openspec-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openspec-compat.d.ts","sourceRoot":"","sources":["../../../src/core/generator/openspec-compat.ts"],"names":[],"mappings":"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"}
|