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,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive prompts for spec-gen CLI
|
|
3
|
+
* Uses @inquirer/prompts (same as OpenSpec)
|
|
4
|
+
*/
|
|
5
|
+
import { select, confirm, input } from '@inquirer/prompts';
|
|
6
|
+
/**
|
|
7
|
+
* Prompt for handling existing spec files
|
|
8
|
+
*/
|
|
9
|
+
export async function promptOverwrite(filePath) {
|
|
10
|
+
return select({
|
|
11
|
+
message: `${filePath} already exists. What would you like to do?`,
|
|
12
|
+
choices: [
|
|
13
|
+
{
|
|
14
|
+
value: 'backup-replace',
|
|
15
|
+
name: 'Backup and replace (recommended)',
|
|
16
|
+
description: 'Backup existing file and write new content',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
value: 'merge',
|
|
20
|
+
name: 'Merge (append generated content)',
|
|
21
|
+
description: 'Add generated content to end of existing file',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
value: 'skip',
|
|
25
|
+
name: 'Skip this file',
|
|
26
|
+
description: 'Keep existing file unchanged',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
value: 'skip-all',
|
|
30
|
+
name: 'Skip all existing files',
|
|
31
|
+
description: 'Keep all existing files unchanged',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Confirm before overwriting multiple files
|
|
38
|
+
*/
|
|
39
|
+
export async function confirmOverwriteAll(count) {
|
|
40
|
+
return confirm({
|
|
41
|
+
message: `This will overwrite ${count} existing spec files. Continue?`,
|
|
42
|
+
default: false,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Confirm before running analysis that will take a while
|
|
47
|
+
*/
|
|
48
|
+
export async function confirmLongAnalysis(fileCount) {
|
|
49
|
+
return confirm({
|
|
50
|
+
message: `About to analyze ${fileCount} files. This may take a while. Continue?`,
|
|
51
|
+
default: true,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Confirm before making API calls
|
|
56
|
+
*/
|
|
57
|
+
export async function confirmGeneration(options) {
|
|
58
|
+
let message = `Ready to generate specs using ${options.model}.`;
|
|
59
|
+
if (options.estimatedTokens) {
|
|
60
|
+
message += ` Estimated ${options.estimatedTokens.toLocaleString()} tokens.`;
|
|
61
|
+
}
|
|
62
|
+
message += ' Continue?';
|
|
63
|
+
return confirm({
|
|
64
|
+
message,
|
|
65
|
+
default: true,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Prompt for API key when not found in environment
|
|
70
|
+
*/
|
|
71
|
+
export async function promptApiKey(provider) {
|
|
72
|
+
const envVar = provider === 'anthropic' ? 'ANTHROPIC_API_KEY' : 'OPENAI_API_KEY';
|
|
73
|
+
const url = provider === 'anthropic'
|
|
74
|
+
? 'https://console.anthropic.com/'
|
|
75
|
+
: 'https://platform.openai.com/api-keys';
|
|
76
|
+
console.log(`\nNo ${envVar} found in environment.`);
|
|
77
|
+
console.log(`Get an API key at: ${url}\n`);
|
|
78
|
+
return input({
|
|
79
|
+
message: `Enter your ${provider} API key:`,
|
|
80
|
+
validate: (value) => {
|
|
81
|
+
if (!value.trim()) {
|
|
82
|
+
return 'API key is required';
|
|
83
|
+
}
|
|
84
|
+
if (provider === 'anthropic' && !value.startsWith('sk-ant-')) {
|
|
85
|
+
return 'Anthropic API keys should start with sk-ant-';
|
|
86
|
+
}
|
|
87
|
+
if (provider === 'openai' && !value.startsWith('sk-')) {
|
|
88
|
+
return 'OpenAI API keys should start with sk-';
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Select LLM provider when multiple are available
|
|
96
|
+
*/
|
|
97
|
+
export async function selectProvider() {
|
|
98
|
+
return select({
|
|
99
|
+
message: 'Multiple API keys found. Which provider would you like to use?',
|
|
100
|
+
choices: [
|
|
101
|
+
{
|
|
102
|
+
value: 'anthropic',
|
|
103
|
+
name: 'Anthropic (Claude)',
|
|
104
|
+
description: 'Recommended for best results',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
value: 'openai',
|
|
108
|
+
name: 'OpenAI (GPT-4)',
|
|
109
|
+
description: 'Alternative provider',
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Select verification sample count
|
|
116
|
+
*/
|
|
117
|
+
export async function selectSampleCount() {
|
|
118
|
+
const answer = await select({
|
|
119
|
+
message: 'How many files would you like to verify?',
|
|
120
|
+
choices: [
|
|
121
|
+
{ value: '3', name: '3 files (quick check)' },
|
|
122
|
+
{ value: '5', name: '5 files (recommended)' },
|
|
123
|
+
{ value: '10', name: '10 files (thorough)' },
|
|
124
|
+
{ value: 'custom', name: 'Custom number' },
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
if (answer === 'custom') {
|
|
128
|
+
const customAnswer = await input({
|
|
129
|
+
message: 'Enter number of files to verify:',
|
|
130
|
+
validate: (value) => {
|
|
131
|
+
const num = parseInt(value, 10);
|
|
132
|
+
if (isNaN(num) || num < 1) {
|
|
133
|
+
return 'Please enter a positive number';
|
|
134
|
+
}
|
|
135
|
+
if (num > 50) {
|
|
136
|
+
return 'Maximum is 50 files';
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
return parseInt(customAnswer, 10);
|
|
142
|
+
}
|
|
143
|
+
return parseInt(answer, 10);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Prompt to continue after partial failure
|
|
147
|
+
*/
|
|
148
|
+
export async function promptContinueAfterError(stage, error) {
|
|
149
|
+
console.log(`\n⚠️ ${stage} encountered an error: ${error}\n`);
|
|
150
|
+
return confirm({
|
|
151
|
+
message: 'Would you like to continue with partial results?',
|
|
152
|
+
default: true,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Select domains to generate
|
|
157
|
+
*/
|
|
158
|
+
export async function selectDomains(availableDomains) {
|
|
159
|
+
// Use a simple confirm + input approach since inquirer checkbox is complex
|
|
160
|
+
const selectAll = await confirm({
|
|
161
|
+
message: `Found ${availableDomains.length} domains. Generate specs for all?`,
|
|
162
|
+
default: true,
|
|
163
|
+
});
|
|
164
|
+
if (selectAll) {
|
|
165
|
+
return availableDomains;
|
|
166
|
+
}
|
|
167
|
+
const selected = await input({
|
|
168
|
+
message: `Enter domains to include (comma-separated):\nAvailable: ${availableDomains.join(', ')}\n`,
|
|
169
|
+
validate: (value) => {
|
|
170
|
+
if (!value.trim()) {
|
|
171
|
+
return 'Please enter at least one domain';
|
|
172
|
+
}
|
|
173
|
+
const domains = value.split(',').map((d) => d.trim());
|
|
174
|
+
const invalid = domains.filter((d) => !availableDomains.includes(d));
|
|
175
|
+
if (invalid.length > 0) {
|
|
176
|
+
return `Unknown domains: ${invalid.join(', ')}`;
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
return selected.split(',').map((d) => d.trim());
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Interactive mode flag - can be disabled for CI/non-interactive environments
|
|
185
|
+
*/
|
|
186
|
+
let interactiveMode = process.stdin.isTTY ?? false;
|
|
187
|
+
/**
|
|
188
|
+
* Check if we're in interactive mode
|
|
189
|
+
*/
|
|
190
|
+
export function isInteractive() {
|
|
191
|
+
return interactiveMode;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Enable/disable interactive mode
|
|
195
|
+
*/
|
|
196
|
+
export function setInteractiveMode(enabled) {
|
|
197
|
+
interactiveMode = enabled;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graceful shutdown handling for spec-gen CLI
|
|
3
|
+
*/
|
|
4
|
+
export interface ShutdownState {
|
|
5
|
+
/** Current phase when interrupted */
|
|
6
|
+
phase: 'init' | 'analyze' | 'generate' | 'verify';
|
|
7
|
+
/** Files that were being processed */
|
|
8
|
+
currentFiles?: string[];
|
|
9
|
+
/** Partial results that were saved */
|
|
10
|
+
savedResults?: string;
|
|
11
|
+
/** Timestamp of interruption */
|
|
12
|
+
timestamp: number;
|
|
13
|
+
}
|
|
14
|
+
type CleanupCallback = () => void | Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Manages graceful shutdown with cleanup callbacks
|
|
17
|
+
*/
|
|
18
|
+
export declare class ShutdownManager {
|
|
19
|
+
private callbacks;
|
|
20
|
+
private isShuttingDown;
|
|
21
|
+
private state;
|
|
22
|
+
private stateFile;
|
|
23
|
+
private handlers;
|
|
24
|
+
private handlersAttached;
|
|
25
|
+
constructor(projectPath?: string, options?: {
|
|
26
|
+
skipHandlers?: boolean;
|
|
27
|
+
});
|
|
28
|
+
private setupHandlers;
|
|
29
|
+
/**
|
|
30
|
+
* Remove all registered signal handlers (for testing)
|
|
31
|
+
*/
|
|
32
|
+
removeHandlers(): void;
|
|
33
|
+
private handleShutdown;
|
|
34
|
+
/**
|
|
35
|
+
* Register a cleanup callback to run on shutdown
|
|
36
|
+
*/
|
|
37
|
+
onCleanup(callback: CleanupCallback): void;
|
|
38
|
+
/**
|
|
39
|
+
* Remove a cleanup callback
|
|
40
|
+
*/
|
|
41
|
+
removeCleanup(callback: CleanupCallback): void;
|
|
42
|
+
/**
|
|
43
|
+
* Set the current state for potential resume
|
|
44
|
+
*/
|
|
45
|
+
setState(state: Partial<ShutdownState>): void;
|
|
46
|
+
/**
|
|
47
|
+
* Clear state (call on successful completion)
|
|
48
|
+
*/
|
|
49
|
+
clearState(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Save state to file for potential resume
|
|
52
|
+
*/
|
|
53
|
+
private saveState;
|
|
54
|
+
/**
|
|
55
|
+
* Load previous shutdown state
|
|
56
|
+
*/
|
|
57
|
+
loadState(): ShutdownState | null;
|
|
58
|
+
/**
|
|
59
|
+
* Check if there's a previous interrupted session
|
|
60
|
+
*/
|
|
61
|
+
hasPreviousState(): boolean;
|
|
62
|
+
private showResumeSuggestion;
|
|
63
|
+
/**
|
|
64
|
+
* Check if shutdown is in progress
|
|
65
|
+
*/
|
|
66
|
+
isInProgress(): boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get or create the global shutdown manager
|
|
70
|
+
*/
|
|
71
|
+
export declare function getShutdownManager(projectPath?: string): ShutdownManager;
|
|
72
|
+
/**
|
|
73
|
+
* Register a cleanup callback with the global manager
|
|
74
|
+
*/
|
|
75
|
+
export declare function onShutdown(callback: CleanupCallback): void;
|
|
76
|
+
/**
|
|
77
|
+
* Set current state for potential resume
|
|
78
|
+
*/
|
|
79
|
+
export declare function setShutdownState(state: Partial<ShutdownState>): void;
|
|
80
|
+
/**
|
|
81
|
+
* Clear shutdown state (call on successful completion)
|
|
82
|
+
*/
|
|
83
|
+
export declare function clearShutdownState(): void;
|
|
84
|
+
/**
|
|
85
|
+
* Create a scope that sets/clears state automatically
|
|
86
|
+
*/
|
|
87
|
+
export declare function withShutdownState<T>(state: Partial<ShutdownState>, fn: () => Promise<T>): Promise<T>;
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=shutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/utils/shutdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAClD,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,eAAe,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElD;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAwD;IACxE,OAAO,CAAC,gBAAgB,CAAS;gBAErB,WAAW,GAAE,MAAsB,EAAE,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE;IAQrF,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,cAAc,IAAI,IAAI;YAQR,cAAc;IA6B5B;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI1C;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAO9C;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAS7C;;OAEG;IACH,UAAU,IAAI,IAAI;IAYlB;;OAEG;YACW,SAAS;IAevB;;OAEG;IACH,SAAS,IAAI,aAAa,GAAG,IAAI;IAYjC;;OAEG;IACH,gBAAgB,IAAI,OAAO;IAI3B,OAAO,CAAC,oBAAoB;IA6B5B;;OAEG;IACH,YAAY,IAAI,OAAO;CAGxB;AAKD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,eAAe,CAKxE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAE1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAEpE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,EAC7B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAOZ"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graceful shutdown handling for spec-gen CLI
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
/**
|
|
7
|
+
* Manages graceful shutdown with cleanup callbacks
|
|
8
|
+
*/
|
|
9
|
+
export class ShutdownManager {
|
|
10
|
+
callbacks = [];
|
|
11
|
+
isShuttingDown = false;
|
|
12
|
+
state = null;
|
|
13
|
+
stateFile;
|
|
14
|
+
handlers = new Map();
|
|
15
|
+
handlersAttached = false;
|
|
16
|
+
constructor(projectPath = process.cwd(), options) {
|
|
17
|
+
this.stateFile = path.join(projectPath, '.spec-gen', 'shutdown-state.json');
|
|
18
|
+
// Skip handlers in test environment or when explicitly disabled
|
|
19
|
+
if (!options?.skipHandlers && process.env.NODE_ENV !== 'test') {
|
|
20
|
+
this.setupHandlers();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
setupHandlers() {
|
|
24
|
+
if (this.handlersAttached)
|
|
25
|
+
return;
|
|
26
|
+
this.handlersAttached = true;
|
|
27
|
+
const sigintHandler = () => this.handleShutdown('SIGINT');
|
|
28
|
+
const sigtermHandler = () => this.handleShutdown('SIGTERM');
|
|
29
|
+
const exceptionHandler = (error) => {
|
|
30
|
+
console.error('\n❌ Uncaught exception:', error.message);
|
|
31
|
+
this.handleShutdown('uncaughtException');
|
|
32
|
+
};
|
|
33
|
+
const rejectionHandler = (reason) => {
|
|
34
|
+
console.error('\n❌ Unhandled rejection:', reason);
|
|
35
|
+
this.handleShutdown('unhandledRejection');
|
|
36
|
+
};
|
|
37
|
+
// Store handlers for potential cleanup
|
|
38
|
+
this.handlers.set('SIGINT', sigintHandler);
|
|
39
|
+
this.handlers.set('SIGTERM', sigtermHandler);
|
|
40
|
+
this.handlers.set('uncaughtException', exceptionHandler);
|
|
41
|
+
this.handlers.set('unhandledRejection', rejectionHandler);
|
|
42
|
+
// Handle Ctrl+C
|
|
43
|
+
process.on('SIGINT', sigintHandler);
|
|
44
|
+
// Handle termination signal
|
|
45
|
+
process.on('SIGTERM', sigtermHandler);
|
|
46
|
+
// Handle uncaught exceptions
|
|
47
|
+
process.on('uncaughtException', exceptionHandler);
|
|
48
|
+
// Handle unhandled promise rejections
|
|
49
|
+
process.on('unhandledRejection', rejectionHandler);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Remove all registered signal handlers (for testing)
|
|
53
|
+
*/
|
|
54
|
+
removeHandlers() {
|
|
55
|
+
for (const [event, handler] of this.handlers) {
|
|
56
|
+
process.removeListener(event, handler);
|
|
57
|
+
}
|
|
58
|
+
this.handlers.clear();
|
|
59
|
+
this.handlersAttached = false;
|
|
60
|
+
}
|
|
61
|
+
async handleShutdown(signal) {
|
|
62
|
+
if (this.isShuttingDown) {
|
|
63
|
+
console.log('\n⚠️ Force quitting...');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
this.isShuttingDown = true;
|
|
67
|
+
console.log('\n\n🛑 Interrupted! Cleaning up...');
|
|
68
|
+
// Save state if we have one
|
|
69
|
+
if (this.state) {
|
|
70
|
+
await this.saveState();
|
|
71
|
+
}
|
|
72
|
+
// Run cleanup callbacks in reverse order
|
|
73
|
+
for (const callback of this.callbacks.reverse()) {
|
|
74
|
+
try {
|
|
75
|
+
await callback();
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error('Cleanup error:', error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Show resume suggestion
|
|
82
|
+
this.showResumeSuggestion();
|
|
83
|
+
process.exit(signal === 'SIGINT' ? 130 : 1);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Register a cleanup callback to run on shutdown
|
|
87
|
+
*/
|
|
88
|
+
onCleanup(callback) {
|
|
89
|
+
this.callbacks.push(callback);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Remove a cleanup callback
|
|
93
|
+
*/
|
|
94
|
+
removeCleanup(callback) {
|
|
95
|
+
const index = this.callbacks.indexOf(callback);
|
|
96
|
+
if (index !== -1) {
|
|
97
|
+
this.callbacks.splice(index, 1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Set the current state for potential resume
|
|
102
|
+
*/
|
|
103
|
+
setState(state) {
|
|
104
|
+
this.state = {
|
|
105
|
+
phase: state.phase ?? 'init',
|
|
106
|
+
currentFiles: state.currentFiles,
|
|
107
|
+
savedResults: state.savedResults,
|
|
108
|
+
timestamp: Date.now(),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Clear state (call on successful completion)
|
|
113
|
+
*/
|
|
114
|
+
clearState() {
|
|
115
|
+
this.state = null;
|
|
116
|
+
// Remove state file if it exists
|
|
117
|
+
try {
|
|
118
|
+
if (fs.existsSync(this.stateFile)) {
|
|
119
|
+
fs.unlinkSync(this.stateFile);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Ignore errors
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Save state to file for potential resume
|
|
128
|
+
*/
|
|
129
|
+
async saveState() {
|
|
130
|
+
if (!this.state)
|
|
131
|
+
return;
|
|
132
|
+
try {
|
|
133
|
+
const dir = path.dirname(this.stateFile);
|
|
134
|
+
if (!fs.existsSync(dir)) {
|
|
135
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
136
|
+
}
|
|
137
|
+
fs.writeFileSync(this.stateFile, JSON.stringify(this.state, null, 2));
|
|
138
|
+
console.log(`📝 State saved to ${this.stateFile}`);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error('Failed to save state:', error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Load previous shutdown state
|
|
146
|
+
*/
|
|
147
|
+
loadState() {
|
|
148
|
+
try {
|
|
149
|
+
if (fs.existsSync(this.stateFile)) {
|
|
150
|
+
const content = fs.readFileSync(this.stateFile, 'utf-8');
|
|
151
|
+
return JSON.parse(content);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Ignore errors
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check if there's a previous interrupted session
|
|
161
|
+
*/
|
|
162
|
+
hasPreviousState() {
|
|
163
|
+
return this.loadState() !== null;
|
|
164
|
+
}
|
|
165
|
+
showResumeSuggestion() {
|
|
166
|
+
if (!this.state)
|
|
167
|
+
return;
|
|
168
|
+
console.log('\n📋 To resume from where you left off:');
|
|
169
|
+
switch (this.state.phase) {
|
|
170
|
+
case 'init':
|
|
171
|
+
console.log(' Run: spec-gen init');
|
|
172
|
+
break;
|
|
173
|
+
case 'analyze':
|
|
174
|
+
console.log(' Run: spec-gen analyze');
|
|
175
|
+
if (this.state.savedResults) {
|
|
176
|
+
console.log(` Partial analysis saved to: ${this.state.savedResults}`);
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case 'generate':
|
|
180
|
+
console.log(' Run: spec-gen generate');
|
|
181
|
+
if (this.state.savedResults) {
|
|
182
|
+
console.log(` Partial specs saved to: ${this.state.savedResults}`);
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
case 'verify':
|
|
186
|
+
console.log(' Run: spec-gen verify');
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
console.log('');
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Check if shutdown is in progress
|
|
193
|
+
*/
|
|
194
|
+
isInProgress() {
|
|
195
|
+
return this.isShuttingDown;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Global shutdown manager instance
|
|
199
|
+
let globalManager = null;
|
|
200
|
+
/**
|
|
201
|
+
* Get or create the global shutdown manager
|
|
202
|
+
*/
|
|
203
|
+
export function getShutdownManager(projectPath) {
|
|
204
|
+
if (!globalManager) {
|
|
205
|
+
globalManager = new ShutdownManager(projectPath);
|
|
206
|
+
}
|
|
207
|
+
return globalManager;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Register a cleanup callback with the global manager
|
|
211
|
+
*/
|
|
212
|
+
export function onShutdown(callback) {
|
|
213
|
+
getShutdownManager().onCleanup(callback);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Set current state for potential resume
|
|
217
|
+
*/
|
|
218
|
+
export function setShutdownState(state) {
|
|
219
|
+
getShutdownManager().setState(state);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Clear shutdown state (call on successful completion)
|
|
223
|
+
*/
|
|
224
|
+
export function clearShutdownState() {
|
|
225
|
+
getShutdownManager().clearState();
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Create a scope that sets/clears state automatically
|
|
229
|
+
*/
|
|
230
|
+
export async function withShutdownState(state, fn) {
|
|
231
|
+
const manager = getShutdownManager();
|
|
232
|
+
manager.setState(state);
|
|
233
|
+
const result = await fn();
|
|
234
|
+
manager.clearState();
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/utils/shutdown.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "spec-gen-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Reverse-engineer OpenSpec specifications from existing codebases",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/api/index.js",
|
|
7
|
+
"types": "dist/api/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/api/index.js",
|
|
11
|
+
"types": "./dist/api/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./cli": {
|
|
14
|
+
"import": "./dist/cli/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"spec-gen": "dist/cli/index.js"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20.0.0"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "tsx watch src/cli/index.ts",
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"start": "node dist/cli/index.js",
|
|
27
|
+
"view": "tsx src/cli/index.ts view",
|
|
28
|
+
"test": "vitest",
|
|
29
|
+
"test:run": "vitest run",
|
|
30
|
+
"test:coverage": "vitest run --coverage",
|
|
31
|
+
"test:openspec-compat": "vitest run --grep 'openspec' || echo 'No OpenSpec compat tests yet'",
|
|
32
|
+
"test:e2e": "vitest run --grep 'e2e' || echo 'No E2E tests yet'",
|
|
33
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
34
|
+
"lint": "eslint src",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"prepublishOnly": "npm run build && npm run test:run"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"openspec",
|
|
40
|
+
"spec-driven",
|
|
41
|
+
"code-analysis",
|
|
42
|
+
"documentation",
|
|
43
|
+
"reverse-engineering",
|
|
44
|
+
"specification",
|
|
45
|
+
"cli"
|
|
46
|
+
],
|
|
47
|
+
"author": "Clay Good",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/clay-good/spec-gen"
|
|
52
|
+
},
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/clay-good/spec-gen/issues"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://github.com/clay-good/spec-gen#readme",
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"dist",
|
|
62
|
+
"!dist/**/*.test.*",
|
|
63
|
+
"src/viewer",
|
|
64
|
+
"README.md",
|
|
65
|
+
"LICENSE"
|
|
66
|
+
],
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"@fission-ai/openspec": ">=0.1.0"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@fission-ai/openspec": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@inquirer/prompts": "^7.2.1",
|
|
77
|
+
"@lancedb/lancedb": "^0.26.2",
|
|
78
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
79
|
+
"apache-arrow": "^21.1.0",
|
|
80
|
+
"chalk": "^5.3.0",
|
|
81
|
+
"commander": "^12.1.0",
|
|
82
|
+
"glob": "^11.0.0",
|
|
83
|
+
"ignore": "^6.0.2",
|
|
84
|
+
"ora": "^8.1.1",
|
|
85
|
+
"react": "^19.1.1",
|
|
86
|
+
"react-dom": "^19.1.1",
|
|
87
|
+
"react-force-graph-2d": "^1.27.0",
|
|
88
|
+
"tree-sitter": "^0.22.4",
|
|
89
|
+
"tree-sitter-go": "^0.23.4",
|
|
90
|
+
"tree-sitter-java": "^0.23.5",
|
|
91
|
+
"tree-sitter-python": "^0.23.6",
|
|
92
|
+
"tree-sitter-ruby": "^0.23.1",
|
|
93
|
+
"tree-sitter-rust": "^0.24.0",
|
|
94
|
+
"tree-sitter-typescript": "^0.23.2",
|
|
95
|
+
"vite": "^7.1.3",
|
|
96
|
+
"yaml": "^2.6.1"
|
|
97
|
+
},
|
|
98
|
+
"optionalDependencies": {
|
|
99
|
+
"@lancedb/lancedb-darwin-x64": "^0.22.3",
|
|
100
|
+
"@lancedb/lancedb-linux-x64-gnu": "^0.22.3"
|
|
101
|
+
},
|
|
102
|
+
"devDependencies": {
|
|
103
|
+
"@eslint/js": "^9.17.0",
|
|
104
|
+
"@types/node": "^22.10.5",
|
|
105
|
+
"@vitejs/plugin-react": "^5.0.2",
|
|
106
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
107
|
+
"eslint": "^9.17.0",
|
|
108
|
+
"memfs": "^4.15.0",
|
|
109
|
+
"tsx": "^4.19.2",
|
|
110
|
+
"typescript": "^5.7.2",
|
|
111
|
+
"typescript-eslint": "^8.19.1",
|
|
112
|
+
"vitest": "^4.0.18"
|
|
113
|
+
}
|
|
114
|
+
}
|