@axboot-mcp/mcp-server 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/CLAUDE.md +119 -0
- package/MCP_TOOL_PLAN.md +710 -0
- package/MCP_USAGE.md +914 -0
- package/README.md +168 -0
- package/REPOSITORY_CONVENTIONS.md +250 -0
- package/SEARCH_PARAMS_MCP_TOOL_COMPLETE_PLAN.md +646 -0
- package/SEARCH_PARAMS_PLAN.md +2570 -0
- package/STORE_PATTERNS.md +1178 -0
- package/debug-dto.js +72 -0
- package/generate-banner-store.js +62 -0
- package/generation-plan.json +2176 -0
- package/generation-results.json +1817 -0
- package/package.json +45 -0
- package/scripts/batch-generate-all.js +159 -0
- package/scripts/batch-generate-mcp.js +329 -0
- package/scripts/batch-generate-stores-v2.js +272 -0
- package/scripts/batch-generate-stores.js +179 -0
- package/scripts/batch-plan.json +3810 -0
- package/scripts/batch-process.py +90 -0
- package/scripts/batch-regenerate.js +356 -0
- package/scripts/direct-generate.js +227 -0
- package/scripts/execute-batches.js +1911 -0
- package/scripts/generate-all-stores.js +144 -0
- package/scripts/generate-stores-mcp.js +161 -0
- package/scripts/generate-stores-v2.js +450 -0
- package/scripts/generate-stores-v3.js +412 -0
- package/scripts/generate-stores-v4.js +521 -0
- package/scripts/generate-stores.js +382 -0
- package/scripts/repos-to-process.json +1899 -0
- package/src/config/nh-layout-patterns.ts +166 -0
- package/src/docs/HOOK_GENERATION_PLAN.md +2226 -0
- package/src/docs/NH_STORE_PATTERNS.md +297 -0
- package/src/docs/README.md +216 -0
- package/src/docs/index.ts +28 -0
- package/src/docs/loader.ts +568 -0
- package/src/docs/patterns.json +419 -0
- package/src/docs/practical-examples.md +732 -0
- package/src/docs/quick-start.md +257 -0
- package/src/docs/requirements-analysis-guide.md +364 -0
- package/src/docs/rules.json +321 -0
- package/src/docs/store-pattern-analysis.md +664 -0
- package/src/docs/store-patterns-rules.md +1168 -0
- package/src/docs/store-patterns-usage-guide.md +1835 -0
- package/src/docs/troubleshooting.md +544 -0
- package/src/docs/type-selection-guide.md +572 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/AntD-/354/273/264/355/217/254/353/204/214/355/212/270-/354/202/254/354/232/251/353/262/225.md +1515 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/DataGrid-/354/202/254/354/232/251/353/262/225.md +866 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/FormItem-/354/202/254/354/232/251/353/262/225.md +903 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/FormModal-/354/202/254/354/232/251/353/262/225.md +1155 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/MCP-/353/260/224/354/235/264/353/270/214/354/275/224/353/224/251-/352/260/200/354/235/264/353/223/234.md +1133 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/MSW-Mock-/353/215/260/354/235/264/355/204/260-/354/202/254/354/232/251/353/262/225.md +579 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/Search-/354/273/264/355/217/254/353/204/214/355/212/270-/354/202/254/354/232/251/353/262/225.md +738 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/Store-/355/214/250/355/204/264-/354/202/254/354/232/251/353/262/225.md +1135 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/224/353/251/264/352/265/254/354/204/261-/355/203/200/354/236/205/353/263/204-/352/260/234/353/260/234/354/210/234/354/204/234.md +1805 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/224/353/251/264/355/203/200/354/236/205/353/263/204-/352/260/234/353/260/234-/355/224/204/353/241/254/355/224/204/355/212/270-/352/260/200/354/235/264/353/223/234.md +946 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/225/354/236/245/355/231/224/353/251/264/355/203/200/354/236/205/353/263/204-/354/203/201/354/204/270-/355/224/204/353/241/254/355/224/204/355/212/270/352/260/200/354/235/264/353/223/234.md +2422 -0
- package/src/features/store-features.ts +232 -0
- package/src/handlers/analyze-requirements.ts +403 -0
- package/src/handlers/analyze.ts +1373 -0
- package/src/handlers/generate-from-requirements.ts +250 -0
- package/src/handlers/generate-hook.ts +950 -0
- package/src/handlers/generate-interactive.ts +840 -0
- package/src/handlers/generate-listdatagrid.ts +521 -0
- package/src/handlers/generate-multi-stores.ts +577 -0
- package/src/handlers/generate-requirements-from-layout.ts +160 -0
- package/src/handlers/generate-search-params.ts +717 -0
- package/src/handlers/generate.ts +911 -0
- package/src/handlers/list-templates.ts +104 -0
- package/src/handlers/scan-metadata.ts +485 -0
- package/src/handlers/suggest-layout.ts +326 -0
- package/src/index.ts +959 -0
- package/src/prompts/search-params.md +793 -0
- package/src/templates/index.ts +107 -0
- package/src/templates/unified.ts +462 -0
- package/store-generation-error-patterns.md +225 -0
- package/test/useAgentStore.ts +136 -0
- package/test-server.js +78 -0
- package/tsconfig.json +20 -0
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@axboot-mcp/mcp-server",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"description": "Axboot MCP Server - Store 생성 및 다른 기능 확장 가능",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc && npm run copy-assets",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"clean": "rm -rf dist",
|
|
15
|
+
"copy-assets": "npm run copy-docs && npm run copy-prompts",
|
|
16
|
+
"copy-docs": "mkdir -p dist/docs && cp -r src/docs/*.json src/docs/*.md dist/docs/ 2>/dev/null || true",
|
|
17
|
+
"copy-prompts": "mkdir -p dist/prompts && cp -r src/prompts/*.md dist/prompts/ 2>/dev/null || true"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"axboot",
|
|
23
|
+
"zustand",
|
|
24
|
+
"store",
|
|
25
|
+
"generator"
|
|
26
|
+
],
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
31
|
+
"chokidar": "^5.0.0",
|
|
32
|
+
"glob": "^13.0.0",
|
|
33
|
+
"mustache": "^4.2.0",
|
|
34
|
+
"typescript": "^5.7.3"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/chokidar": "^1.7.5",
|
|
38
|
+
"@types/mustache": "^4.2.6",
|
|
39
|
+
"@types/node": "^22.10.5",
|
|
40
|
+
"@typescript-eslint/typescript-estree": "^8.53.0"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const SOURCE_DIR = '/Users/kyle/Desktop/nh-fe-bo/src/services/@interface/repository';
|
|
8
|
+
const OUTPUT_DIR = '/Users/kyle/Desktop/nh-fe-bo/src/pages/resources/NH/test';
|
|
9
|
+
const MCP_SERVER_PATH = '/Users/kyle/work/mcp-axboot/dist/index.js';
|
|
10
|
+
|
|
11
|
+
// Store type detection patterns
|
|
12
|
+
const PATTERNS = {
|
|
13
|
+
TYPE_7: { name: 'Type 7', patterns: [/list/i, /detail|dtl/i, /save/i, /delete|del/i], description: 'Master-Detail + Modal + Delete + Excel' },
|
|
14
|
+
TYPE_2: { name: 'Type 2', patterns: [/list/i, /detail|dtl/i, /save/i, /delete|del/i], description: 'Master-Detail + Modal + Delete' },
|
|
15
|
+
TYPE_1: { name: 'Type 1', patterns: [/list/i, /save/i], description: 'Basic List + Detail' },
|
|
16
|
+
TYPE_5: { name: 'Type 5', patterns: [], description: 'Simple List (default)' }
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Get all repository files
|
|
20
|
+
function getRepositoryFiles() {
|
|
21
|
+
const files = fs.readdirSync(SOURCE_DIR)
|
|
22
|
+
.filter(file => file.endsWith('Repository.ts'));
|
|
23
|
+
return files.map(file => path.join(SOURCE_DIR, file));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Parse repository file to detect store type
|
|
27
|
+
function detectStoreType(filePath) {
|
|
28
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
29
|
+
const methods = content.match(/async\s+(\w+)\s*\(/g) || [];
|
|
30
|
+
const methodNames = methods.map(m => m.match(/async\s+(\w+)/)[1].toLowerCase());
|
|
31
|
+
|
|
32
|
+
// Check for Type 7 (has list + detail + save + delete + excel)
|
|
33
|
+
const hasList = methodNames.some(m => m.includes('list'));
|
|
34
|
+
const hasDetail = methodNames.some(m => m.includes('detail') || m.includes('dtl'));
|
|
35
|
+
const hasSave = methodNames.some(m => m.includes('save'));
|
|
36
|
+
const hasDelete = methodNames.some(m => m.includes('delete') || m.includes('del'));
|
|
37
|
+
const hasExcel = methodNames.some(m => m.includes('excel') || m.includes('download'));
|
|
38
|
+
|
|
39
|
+
if (hasList && hasDetail && hasSave && hasDelete && hasExcel) {
|
|
40
|
+
return 7;
|
|
41
|
+
} else if (hasList && hasDetail && hasSave && hasDelete) {
|
|
42
|
+
return 2;
|
|
43
|
+
} else if (hasList && hasSave) {
|
|
44
|
+
return 1;
|
|
45
|
+
} else {
|
|
46
|
+
return 5; // Default to Type 5 (simple list)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Extract repository name from file path
|
|
51
|
+
function getRepositoryName(filePath) {
|
|
52
|
+
const fileName = path.basename(filePath, 'Repository.ts');
|
|
53
|
+
return fileName;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Generate store name from repository name
|
|
57
|
+
function getStoreName(repositoryName) {
|
|
58
|
+
return `use${repositoryName}ListStore`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Get output path for store file
|
|
62
|
+
function getOutputPath(repositoryName) {
|
|
63
|
+
return path.join(OUTPUT_DIR, `use${repositoryName}ListStore.ts`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Call MCP tool to generate store
|
|
67
|
+
function generateStore(interfacePath, outputPath, storeName, storeType) {
|
|
68
|
+
// This would call the mcp__axboot__generate_store tool
|
|
69
|
+
// For now, we'll track what needs to be generated
|
|
70
|
+
return {
|
|
71
|
+
interfacePath,
|
|
72
|
+
outputPath,
|
|
73
|
+
storeName,
|
|
74
|
+
storeType,
|
|
75
|
+
status: 'pending'
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Main execution
|
|
80
|
+
async function main() {
|
|
81
|
+
console.log('='.repeat(80));
|
|
82
|
+
console.log('Batch Store Generation for NH-FE-BO Repository Files');
|
|
83
|
+
console.log('='.repeat(80));
|
|
84
|
+
console.log(`Source Directory: ${SOURCE_DIR}`);
|
|
85
|
+
console.log(`Output Directory: ${OUTPUT_DIR}`);
|
|
86
|
+
console.log('');
|
|
87
|
+
|
|
88
|
+
const files = getRepositoryFiles();
|
|
89
|
+
console.log(`Found ${files.length} repository files\n`);
|
|
90
|
+
|
|
91
|
+
const results = {
|
|
92
|
+
total: files.length,
|
|
93
|
+
success: 0,
|
|
94
|
+
failed: 0,
|
|
95
|
+
generated: [],
|
|
96
|
+
failedFiles: []
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// Process each file
|
|
100
|
+
for (let i = 0; i < files.length; i++) {
|
|
101
|
+
const filePath = files[i];
|
|
102
|
+
const repositoryName = getRepositoryName(filePath);
|
|
103
|
+
const storeName = getStoreName(repositoryName);
|
|
104
|
+
const outputPath = getOutputPath(repositoryName);
|
|
105
|
+
const storeType = detectStoreType(filePath);
|
|
106
|
+
|
|
107
|
+
console.log(`[${i + 1}/${files.length}] Processing: ${repositoryName}Repository`);
|
|
108
|
+
console.log(` → Store: ${storeName}`);
|
|
109
|
+
console.log(` → Type: ${storeType}`);
|
|
110
|
+
console.log(` → Output: ${outputPath}`);
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
// Check if file already exists
|
|
114
|
+
if (fs.existsSync(outputPath)) {
|
|
115
|
+
console.log(` ⚠️ File already exists, skipping...\n`);
|
|
116
|
+
results.generated.push({ repositoryName, storeName, storeType, status: 'exists' });
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// TODO: Call the actual MCP tool here
|
|
121
|
+
// For now, just track it
|
|
122
|
+
results.generated.push({
|
|
123
|
+
repositoryName,
|
|
124
|
+
storeName,
|
|
125
|
+
storeType,
|
|
126
|
+
interfacePath: filePath,
|
|
127
|
+
outputPath,
|
|
128
|
+
status: 'queued'
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
results.success++;
|
|
132
|
+
console.log(` ✓ Queued for generation\n`);
|
|
133
|
+
|
|
134
|
+
} catch (error) {
|
|
135
|
+
results.failed++;
|
|
136
|
+
results.failedFiles.push({
|
|
137
|
+
repositoryName,
|
|
138
|
+
error: error.message
|
|
139
|
+
});
|
|
140
|
+
console.log(` ✗ Error: ${error.message}\n`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Print summary
|
|
145
|
+
console.log('='.repeat(80));
|
|
146
|
+
console.log('SUMMARY');
|
|
147
|
+
console.log('='.repeat(80));
|
|
148
|
+
console.log(`Total files processed: ${results.total}`);
|
|
149
|
+
console.log(`Successfully queued: ${results.success}`);
|
|
150
|
+
console.log(`Failed: ${results.failed}`);
|
|
151
|
+
console.log('');
|
|
152
|
+
|
|
153
|
+
// Save detailed results
|
|
154
|
+
const resultsPath = path.join(OUTPUT_DIR, 'generation-plan.json');
|
|
155
|
+
fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2));
|
|
156
|
+
console.log(`Detailed plan saved to: ${resultsPath}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawn } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const SOURCE_DIR = '/Users/kyle/Desktop/nh-fe-bo/src/services/@interface/repository';
|
|
8
|
+
const OUTPUT_DIR = '/Users/kyle/Desktop/nh-fe-bo/src/pages/resources/NH/test';
|
|
9
|
+
const MCP_SERVER_PATH = '/Users/kyle/work/mcp-axboot/dist/index.js';
|
|
10
|
+
|
|
11
|
+
// Store type detection patterns
|
|
12
|
+
function detectStoreType(filePath) {
|
|
13
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
14
|
+
const methods = content.match(/async\s+(\w+)\s*\(/g) || [];
|
|
15
|
+
const methodNames = methods.map(m => m.match(/async\s+(\w+)/)[1].toLowerCase());
|
|
16
|
+
|
|
17
|
+
const hasList = methodNames.some(m => m.includes('list'));
|
|
18
|
+
const hasDetail = methodNames.some(m => m.includes('detail') || m.includes('dtl'));
|
|
19
|
+
const hasSave = methodNames.some(m => m.includes('save'));
|
|
20
|
+
const hasDelete = methodNames.some(m => m.includes('delete') || m.includes('del'));
|
|
21
|
+
const hasExcel = methodNames.some(m => m.includes('excel') || m.includes('download') || m.includes('export'));
|
|
22
|
+
|
|
23
|
+
if (hasList && hasDetail && hasSave && hasDelete && hasExcel) {
|
|
24
|
+
return 7;
|
|
25
|
+
} else if (hasList && hasDetail && hasSave && hasDelete) {
|
|
26
|
+
return 2;
|
|
27
|
+
} else if (hasList && hasSave) {
|
|
28
|
+
return 1;
|
|
29
|
+
} else {
|
|
30
|
+
return 5;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Get all repository files
|
|
35
|
+
function getRepositoryFiles() {
|
|
36
|
+
const files = fs.readdirSync(SOURCE_DIR)
|
|
37
|
+
.filter(file => file.endsWith('Repository.ts'));
|
|
38
|
+
return files.map(file => path.join(SOURCE_DIR, file));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Extract repository name
|
|
42
|
+
function getRepositoryName(filePath) {
|
|
43
|
+
return path.basename(filePath, 'Repository.ts');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Generate store name
|
|
47
|
+
function getStoreName(repositoryName) {
|
|
48
|
+
return `use${repositoryName}ListStore`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Get output path
|
|
52
|
+
function getOutputPath(repositoryName) {
|
|
53
|
+
return path.join(OUTPUT_DIR, `use${repositoryName}ListStore.ts`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Call MCP server using the analyze interface first, then generate
|
|
57
|
+
async function analyzeInterface(interfacePath) {
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const mcp = spawn('node', [MCP_SERVER_PATH], {
|
|
60
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const request = {
|
|
64
|
+
jsonrpc: '2.0',
|
|
65
|
+
id: 1,
|
|
66
|
+
method: 'tools/call',
|
|
67
|
+
params: {
|
|
68
|
+
name: 'mcp__axboot__analyze_interface',
|
|
69
|
+
arguments: {
|
|
70
|
+
interfacePath
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
let stdout = '';
|
|
76
|
+
let stderr = '';
|
|
77
|
+
|
|
78
|
+
mcp.stdout.on('data', (data) => {
|
|
79
|
+
stdout += data.toString();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
mcp.stderr.on('data', (data) => {
|
|
83
|
+
stderr += data.toString();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
mcp.stdin.write(JSON.stringify(request) + '\n');
|
|
87
|
+
|
|
88
|
+
setTimeout(() => {
|
|
89
|
+
mcp.kill();
|
|
90
|
+
try {
|
|
91
|
+
const responses = stdout.trim().split('\n').map(line => {
|
|
92
|
+
try {
|
|
93
|
+
return JSON.parse(line);
|
|
94
|
+
} catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}).filter(Boolean);
|
|
98
|
+
|
|
99
|
+
const response = responses.find(r => r.id === 1);
|
|
100
|
+
if (response && response.result) {
|
|
101
|
+
resolve(response.result);
|
|
102
|
+
} else {
|
|
103
|
+
reject(new Error('No valid response from MCP server'));
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
reject(error);
|
|
107
|
+
}
|
|
108
|
+
}, 5000);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Generate store using MCP
|
|
113
|
+
async function callGenerateStore(interfacePath, outputPath, storeType, storeName) {
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
const mcp = spawn('node', [MCP_SERVER_PATH], {
|
|
116
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const request = {
|
|
120
|
+
jsonrpc: '2.0',
|
|
121
|
+
id: 1,
|
|
122
|
+
method: 'tools/call',
|
|
123
|
+
params: {
|
|
124
|
+
name: 'mcp__axboot__generate_store',
|
|
125
|
+
arguments: {
|
|
126
|
+
interfacePath,
|
|
127
|
+
outputPath,
|
|
128
|
+
storeType,
|
|
129
|
+
storeName
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
let stdout = '';
|
|
135
|
+
let stderr = '';
|
|
136
|
+
|
|
137
|
+
mcp.stdout.on('data', (data) => {
|
|
138
|
+
stdout += data.toString();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
mcp.stderr.on('data', (data) => {
|
|
142
|
+
stderr += data.toString();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
mcp.stdin.write(JSON.stringify(request) + '\n');
|
|
146
|
+
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
mcp.kill();
|
|
149
|
+
try {
|
|
150
|
+
const responses = stdout.trim().split('\n').map(line => {
|
|
151
|
+
try {
|
|
152
|
+
return JSON.parse(line);
|
|
153
|
+
} catch {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}).filter(Boolean);
|
|
157
|
+
|
|
158
|
+
const response = responses.find(r => r.id === 1);
|
|
159
|
+
if (response) {
|
|
160
|
+
resolve(response);
|
|
161
|
+
} else {
|
|
162
|
+
reject(new Error('No valid response from MCP server'));
|
|
163
|
+
}
|
|
164
|
+
} catch (error) {
|
|
165
|
+
reject(error);
|
|
166
|
+
}
|
|
167
|
+
}, 8000);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Main execution
|
|
172
|
+
async function main() {
|
|
173
|
+
console.log('='.repeat(80));
|
|
174
|
+
console.log('Batch Store Generation for NH-FE-BO Repository Files');
|
|
175
|
+
console.log('='.repeat(80));
|
|
176
|
+
console.log(`Source Directory: ${SOURCE_DIR}`);
|
|
177
|
+
console.log(`Output Directory: ${OUTPUT_DIR}`);
|
|
178
|
+
console.log('');
|
|
179
|
+
|
|
180
|
+
const files = getRepositoryFiles();
|
|
181
|
+
console.log(`Found ${files.length} repository files\n`);
|
|
182
|
+
|
|
183
|
+
const results = {
|
|
184
|
+
total: files.length,
|
|
185
|
+
success: 0,
|
|
186
|
+
failed: 0,
|
|
187
|
+
skipped: 0,
|
|
188
|
+
generated: [],
|
|
189
|
+
failedFiles: [],
|
|
190
|
+
typeDistribution: {}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Process in batches of 10 to avoid overwhelming
|
|
194
|
+
const batchSize = 10;
|
|
195
|
+
for (let i = 0; i < files.length; i += batchSize) {
|
|
196
|
+
const batch = files.slice(i, i + batchSize);
|
|
197
|
+
console.log(`\nProcessing batch ${Math.floor(i/batchSize) + 1}/${Math.ceil(files.length/batchSize)} (files ${i + 1}-${Math.min(i + batchSize, files.length)})`);
|
|
198
|
+
console.log('-'.repeat(80));
|
|
199
|
+
|
|
200
|
+
for (const filePath of batch) {
|
|
201
|
+
const index = files.indexOf(filePath) + 1;
|
|
202
|
+
const repositoryName = getRepositoryName(filePath);
|
|
203
|
+
const storeName = getStoreName(repositoryName);
|
|
204
|
+
const outputPath = getOutputPath(repositoryName);
|
|
205
|
+
const storeType = detectStoreType(filePath);
|
|
206
|
+
|
|
207
|
+
// Track type distribution
|
|
208
|
+
results.typeDistribution[storeType] = (results.typeDistribution[storeType] || 0) + 1;
|
|
209
|
+
|
|
210
|
+
console.log(`[${index}/${files.length}] ${repositoryName}Repository → Type ${storeType}`);
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
// Check if file already exists
|
|
214
|
+
if (fs.existsSync(outputPath)) {
|
|
215
|
+
console.log(` ⚠️ Already exists, skipping\n`);
|
|
216
|
+
results.skipped++;
|
|
217
|
+
results.generated.push({
|
|
218
|
+
repositoryName,
|
|
219
|
+
storeName,
|
|
220
|
+
storeType,
|
|
221
|
+
status: 'exists',
|
|
222
|
+
outputPath
|
|
223
|
+
});
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Generate store using MCP tool
|
|
228
|
+
console.log(` 🔄 Generating store...`);
|
|
229
|
+
const result = await callGenerateStore(filePath, outputPath, storeType, storeName);
|
|
230
|
+
|
|
231
|
+
if (result.error) {
|
|
232
|
+
throw new Error(result.error.message || 'Unknown error');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Check if file was created
|
|
236
|
+
if (fs.existsSync(outputPath)) {
|
|
237
|
+
results.success++;
|
|
238
|
+
results.generated.push({
|
|
239
|
+
repositoryName,
|
|
240
|
+
storeName,
|
|
241
|
+
storeType,
|
|
242
|
+
status: 'success',
|
|
243
|
+
outputPath
|
|
244
|
+
});
|
|
245
|
+
console.log(` ✓ Generated\n`);
|
|
246
|
+
} else {
|
|
247
|
+
throw new Error('File was not created');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
} catch (error) {
|
|
251
|
+
results.failed++;
|
|
252
|
+
results.failedFiles.push({
|
|
253
|
+
repositoryName,
|
|
254
|
+
storeName,
|
|
255
|
+
error: error.message
|
|
256
|
+
});
|
|
257
|
+
console.log(` ✗ Failed: ${error.message}\n`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Small delay to avoid overwhelming
|
|
261
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Print summary
|
|
266
|
+
console.log('\n' + '='.repeat(80));
|
|
267
|
+
console.log('SUMMARY');
|
|
268
|
+
console.log('='.repeat(80));
|
|
269
|
+
console.log(`Total files processed: ${results.total}`);
|
|
270
|
+
console.log(`Successfully generated: ${results.success}`);
|
|
271
|
+
console.log(`Skipped (already exists): ${results.skipped}`);
|
|
272
|
+
console.log(`Failed: ${results.failed}`);
|
|
273
|
+
console.log('');
|
|
274
|
+
console.log('Type Distribution:');
|
|
275
|
+
Object.entries(results.typeDistribution).sort((a, b) => a[0] - b[0]).forEach(([type, count]) => {
|
|
276
|
+
console.log(` Type ${type}: ${count} files`);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Save detailed results
|
|
280
|
+
const resultsPath = path.join(OUTPUT_DIR, 'generation-results.json');
|
|
281
|
+
fs.writeFileSync(resultsPath, JSON.stringify(results, null, 2));
|
|
282
|
+
console.log(`\nDetailed results saved to: ${resultsPath}`);
|
|
283
|
+
|
|
284
|
+
// Generate markdown report
|
|
285
|
+
const markdownPath = path.join(OUTPUT_DIR, 'generation-results.md');
|
|
286
|
+
const markdown = generateMarkdownReport(results);
|
|
287
|
+
fs.writeFileSync(markdownPath, markdown);
|
|
288
|
+
console.log(`Markdown report saved to: ${markdownPath}`);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function generateMarkdownReport(results) {
|
|
292
|
+
const date = new Date().toISOString();
|
|
293
|
+
|
|
294
|
+
let md = `# Store Generation Results\n\n`;
|
|
295
|
+
md += `**Generated:** ${date}\n\n`;
|
|
296
|
+
md += `## Summary\n\n`;
|
|
297
|
+
md += `- **Total Files:** ${results.total}\n`;
|
|
298
|
+
md += `- **Successfully Generated:** ${results.success}\n`;
|
|
299
|
+
md += `- **Skipped (already exists):** ${results.skipped}\n`;
|
|
300
|
+
md += `- **Failed:** ${results.failed}\n\n`;
|
|
301
|
+
|
|
302
|
+
md += `## Type Distribution\n\n`;
|
|
303
|
+
md += `| Type | Count |\n`;
|
|
304
|
+
md += `|------|-------|\n`;
|
|
305
|
+
Object.entries(results.typeDistribution).sort((a, b) => a[0] - b[0]).forEach(([type, count]) => {
|
|
306
|
+
md += `| ${type} | ${count} |\n`;
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
md += `\n## Generated Stores\n\n`;
|
|
310
|
+
md += `| # | Repository | Store Name | Type | Status |\n`;
|
|
311
|
+
md += `|---|------------|------------|------|--------|\n`;
|
|
312
|
+
results.generated.forEach((item, idx) => {
|
|
313
|
+
const status = item.status === 'success' ? '✓' : '⚠️';
|
|
314
|
+
md += `| ${idx + 1} | ${item.repositoryName}Repository | ${item.storeName} | ${item.storeType} | ${status} |\n`;
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (results.failedFiles.length > 0) {
|
|
318
|
+
md += `\n## Failed Files\n\n`;
|
|
319
|
+
md += `| Repository | Error |\n`;
|
|
320
|
+
md += `|------------|-------|\n`;
|
|
321
|
+
results.failedFiles.forEach(item => {
|
|
322
|
+
md += `| ${item.repositoryName} | ${item.error} |\n`;
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return md;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
main().catch(console.error);
|