@compilr-dev/sdk 0.2.5 → 0.2.6
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/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/project-generator/detection.d.ts +42 -0
- package/dist/project-generator/detection.js +401 -0
- package/dist/project-generator/generator.d.ts +14 -0
- package/dist/project-generator/generator.js +245 -0
- package/dist/project-generator/index.d.ts +11 -0
- package/dist/project-generator/index.js +13 -0
- package/dist/project-generator/templates/coding-standards.d.ts +7 -0
- package/dist/project-generator/templates/coding-standards.js +299 -0
- package/dist/project-generator/templates/compilr-md-import.d.ts +8 -0
- package/dist/project-generator/templates/compilr-md-import.js +241 -0
- package/dist/project-generator/templates/compilr-md.d.ts +7 -0
- package/dist/project-generator/templates/compilr-md.js +141 -0
- package/dist/project-generator/templates/config-json.d.ts +13 -0
- package/dist/project-generator/templates/config-json.js +39 -0
- package/dist/project-generator/templates/gitignore.d.ts +7 -0
- package/dist/project-generator/templates/gitignore.js +85 -0
- package/dist/project-generator/templates/index.d.ts +11 -0
- package/dist/project-generator/templates/index.js +11 -0
- package/dist/project-generator/templates/package-json.d.ts +7 -0
- package/dist/project-generator/templates/package-json.js +111 -0
- package/dist/project-generator/templates/readme-md.d.ts +7 -0
- package/dist/project-generator/templates/readme-md.js +165 -0
- package/dist/project-generator/templates/tsconfig.d.ts +7 -0
- package/dist/project-generator/templates/tsconfig.js +61 -0
- package/dist/project-generator/types.d.ts +95 -0
- package/dist/project-generator/types.js +24 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -65,5 +65,7 @@ export { DEFAULT_PERMISSION_RULES, findMatchingRule, permissionModeLabel, permis
|
|
|
65
65
|
export type { PermissionRule, PermissionMode, PermissionLevel } from './permissions.js';
|
|
66
66
|
export { readMCPConfigFile, writeMCPConfigFile, resolveServerEntry, loadMCPServers, saveMCPServerEntry, deleteMCPServerEntry, getServerNames, } from './mcp-config.js';
|
|
67
67
|
export type { MCPServerEntry, MCPConfigFile, ResolvedMCPServer } from './mcp-config.js';
|
|
68
|
+
export { generateProject, isGitConfigured, generateCompilrMd, generateConfigJson, generateReadmeMd, generateCodingStandardsMd, generatePackageJson, generateTsconfig, generateGitignore, generateCompilrMdForImport, detectProjectInfo, detectGitInfo, prettifyName, getLanguageLabel, getFrameworkLabel, validateImportPath, isValidProjectName, projectExists, TECH_STACK_LABELS, CODING_STANDARDS_LABELS, REPO_PATTERN_LABELS, WORKFLOW_VERSION, } from './project-generator/index.js';
|
|
69
|
+
export type { TechStack, CodingStandards, GeneratorRepoPattern, ProjectConfig, GenerationResult, CompilrConfig, DetectedProject, GitInfo, ImportProjectConfig, } from './project-generator/index.js';
|
|
68
70
|
export { readFileTool, writeFileTool, createBashTool, bashTool, bashOutputTool, killShellTool, grepTool, globTool, editTool, todoWriteTool, todoReadTool, createTodoTools, TodoStore, webFetchTool, suggestTool, } from '@compilr-dev/agents';
|
|
69
71
|
export { gitStatusTool, gitDiffTool, gitLogTool, gitCommitTool, gitBranchTool, gitStashTool, gitBlameTool, gitFileHistoryTool, detectProjectTool, findProjectRootTool, runTestsTool, runLintTool, runBuildTool, runFormatTool, findDefinitionTool, findReferencesTool, findTodosTool, checkOutdatedTool, findVulnerabilitiesTool, analyzeTestCoverageTool, getFileStructureTool, getComplexityTool, allCodingTools, unifiedTools, } from '@compilr-dev/agents-coding';
|
package/dist/index.js
CHANGED
|
@@ -165,6 +165,18 @@ export { DEFAULT_PERMISSION_RULES, findMatchingRule, permissionModeLabel, permis
|
|
|
165
165
|
// =============================================================================
|
|
166
166
|
export { readMCPConfigFile, writeMCPConfigFile, resolveServerEntry, loadMCPServers, saveMCPServerEntry, deleteMCPServerEntry, getServerNames, } from './mcp-config.js';
|
|
167
167
|
// =============================================================================
|
|
168
|
+
// Project Generator (templates, scaffolding, detection)
|
|
169
|
+
// =============================================================================
|
|
170
|
+
export {
|
|
171
|
+
// Generator
|
|
172
|
+
generateProject, isGitConfigured,
|
|
173
|
+
// Templates
|
|
174
|
+
generateCompilrMd, generateConfigJson, generateReadmeMd, generateCodingStandardsMd, generatePackageJson, generateTsconfig, generateGitignore, generateCompilrMdForImport,
|
|
175
|
+
// Detection
|
|
176
|
+
detectProjectInfo, detectGitInfo, prettifyName, getLanguageLabel, getFrameworkLabel, validateImportPath, isValidProjectName, projectExists,
|
|
177
|
+
// Constants
|
|
178
|
+
TECH_STACK_LABELS, CODING_STANDARDS_LABELS, REPO_PATTERN_LABELS, WORKFLOW_VERSION, } from './project-generator/index.js';
|
|
179
|
+
// =============================================================================
|
|
168
180
|
// Individual Tool Re-exports (for consumers that build custom tool registries)
|
|
169
181
|
// =============================================================================
|
|
170
182
|
// Base tools from @compilr-dev/agents
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Detection Utilities
|
|
3
|
+
*
|
|
4
|
+
* Utilities for detecting project information from an existing directory.
|
|
5
|
+
* Used by the import project feature.
|
|
6
|
+
*/
|
|
7
|
+
import type { DetectedProject, GitInfo } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Detect project information from a directory path
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectProjectInfo(projectPath: string): DetectedProject;
|
|
12
|
+
/**
|
|
13
|
+
* Detect git repository information
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectGitInfo(projectPath: string): GitInfo;
|
|
16
|
+
/**
|
|
17
|
+
* Convert kebab-case or snake_case to Title Case
|
|
18
|
+
*/
|
|
19
|
+
export declare function prettifyName(name: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Get a human-readable label for detected language
|
|
22
|
+
*/
|
|
23
|
+
export declare function getLanguageLabel(language: string | null): string;
|
|
24
|
+
/**
|
|
25
|
+
* Get a human-readable label for detected framework
|
|
26
|
+
*/
|
|
27
|
+
export declare function getFrameworkLabel(framework: string | null): string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a path is a valid directory that can be imported
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateImportPath(importPath: string): {
|
|
32
|
+
valid: boolean;
|
|
33
|
+
error?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Validate project name
|
|
37
|
+
*/
|
|
38
|
+
export declare function isValidProjectName(name: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check if project directory already exists
|
|
41
|
+
*/
|
|
42
|
+
export declare function projectExists(name: string, basePath: string): boolean;
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Detection Utilities
|
|
3
|
+
*
|
|
4
|
+
* Utilities for detecting project information from an existing directory.
|
|
5
|
+
* Used by the import project feature.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
const LANGUAGE_MARKERS = [
|
|
11
|
+
// Node.js / JavaScript / TypeScript
|
|
12
|
+
{
|
|
13
|
+
file: 'package.json',
|
|
14
|
+
language: 'node',
|
|
15
|
+
packageManager: 'npm',
|
|
16
|
+
frameworkDetector: (content) => {
|
|
17
|
+
try {
|
|
18
|
+
const pkg = JSON.parse(content);
|
|
19
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
20
|
+
if (deps['next'])
|
|
21
|
+
return 'next';
|
|
22
|
+
if (deps['nuxt'])
|
|
23
|
+
return 'nuxt';
|
|
24
|
+
if (deps['react'])
|
|
25
|
+
return 'react';
|
|
26
|
+
if (deps['vue'])
|
|
27
|
+
return 'vue';
|
|
28
|
+
if (deps['svelte'])
|
|
29
|
+
return 'svelte';
|
|
30
|
+
if (deps['@angular/core'])
|
|
31
|
+
return 'angular';
|
|
32
|
+
if (deps['express'])
|
|
33
|
+
return 'express';
|
|
34
|
+
if (deps['fastify'])
|
|
35
|
+
return 'fastify';
|
|
36
|
+
if (deps['koa'])
|
|
37
|
+
return 'koa';
|
|
38
|
+
if (deps['hono'])
|
|
39
|
+
return 'hono';
|
|
40
|
+
if (deps['electron'])
|
|
41
|
+
return 'electron';
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
nameExtractor: (content) => {
|
|
49
|
+
try {
|
|
50
|
+
const pkg = JSON.parse(content);
|
|
51
|
+
return pkg.name ?? null;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
// Go
|
|
59
|
+
{
|
|
60
|
+
file: 'go.mod',
|
|
61
|
+
language: 'go',
|
|
62
|
+
packageManager: 'go',
|
|
63
|
+
nameExtractor: (content) => {
|
|
64
|
+
const match = content.match(/^module\s+(.+)$/m);
|
|
65
|
+
if (match) {
|
|
66
|
+
const parts = match[1].split('/');
|
|
67
|
+
return parts[parts.length - 1];
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
// Python
|
|
73
|
+
{
|
|
74
|
+
file: 'pyproject.toml',
|
|
75
|
+
language: 'python',
|
|
76
|
+
packageManager: 'pip',
|
|
77
|
+
frameworkDetector: (content) => {
|
|
78
|
+
if (content.includes('fastapi'))
|
|
79
|
+
return 'fastapi';
|
|
80
|
+
if (content.includes('django'))
|
|
81
|
+
return 'django';
|
|
82
|
+
if (content.includes('flask'))
|
|
83
|
+
return 'flask';
|
|
84
|
+
return null;
|
|
85
|
+
},
|
|
86
|
+
nameExtractor: (content) => {
|
|
87
|
+
const match = content.match(/^name\s*=\s*["'](.+)["']/m);
|
|
88
|
+
return match ? match[1] : null;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
file: 'requirements.txt',
|
|
93
|
+
language: 'python',
|
|
94
|
+
packageManager: 'pip',
|
|
95
|
+
frameworkDetector: (content) => {
|
|
96
|
+
if (content.includes('fastapi'))
|
|
97
|
+
return 'fastapi';
|
|
98
|
+
if (content.includes('django'))
|
|
99
|
+
return 'django';
|
|
100
|
+
if (content.includes('flask'))
|
|
101
|
+
return 'flask';
|
|
102
|
+
return null;
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
file: 'setup.py',
|
|
107
|
+
language: 'python',
|
|
108
|
+
packageManager: 'pip',
|
|
109
|
+
},
|
|
110
|
+
// Rust
|
|
111
|
+
{
|
|
112
|
+
file: 'Cargo.toml',
|
|
113
|
+
language: 'rust',
|
|
114
|
+
packageManager: 'cargo',
|
|
115
|
+
nameExtractor: (content) => {
|
|
116
|
+
const match = content.match(/^name\s*=\s*["'](.+)["']/m);
|
|
117
|
+
return match ? match[1] : null;
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
// Java
|
|
121
|
+
{ file: 'pom.xml', language: 'java', packageManager: 'maven' },
|
|
122
|
+
{ file: 'build.gradle', language: 'java', packageManager: 'gradle' },
|
|
123
|
+
{ file: 'build.gradle.kts', language: 'kotlin', packageManager: 'gradle' },
|
|
124
|
+
// PHP
|
|
125
|
+
{
|
|
126
|
+
file: 'composer.json',
|
|
127
|
+
language: 'php',
|
|
128
|
+
packageManager: 'composer',
|
|
129
|
+
frameworkDetector: (content) => {
|
|
130
|
+
try {
|
|
131
|
+
const pkg = JSON.parse(content);
|
|
132
|
+
const deps = pkg.require ?? {};
|
|
133
|
+
if (deps['laravel/framework'])
|
|
134
|
+
return 'laravel';
|
|
135
|
+
if (deps['symfony/framework-bundle'])
|
|
136
|
+
return 'symfony';
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
nameExtractor: (content) => {
|
|
144
|
+
try {
|
|
145
|
+
const pkg = JSON.parse(content);
|
|
146
|
+
if (pkg.name) {
|
|
147
|
+
const parts = pkg.name.split('/');
|
|
148
|
+
return parts[parts.length - 1];
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
// Ruby
|
|
158
|
+
{
|
|
159
|
+
file: 'Gemfile',
|
|
160
|
+
language: 'ruby',
|
|
161
|
+
packageManager: 'bundler',
|
|
162
|
+
frameworkDetector: (content) => {
|
|
163
|
+
if (content.includes("'rails'") || content.includes('"rails"'))
|
|
164
|
+
return 'rails';
|
|
165
|
+
if (content.includes("'sinatra'") || content.includes('"sinatra"'))
|
|
166
|
+
return 'sinatra';
|
|
167
|
+
return null;
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
// .NET
|
|
171
|
+
{ file: '*.csproj', language: 'dotnet', packageManager: 'nuget' },
|
|
172
|
+
{ file: '*.fsproj', language: 'dotnet', packageManager: 'nuget' },
|
|
173
|
+
];
|
|
174
|
+
// =============================================================================
|
|
175
|
+
// Main Detection Functions
|
|
176
|
+
// =============================================================================
|
|
177
|
+
/**
|
|
178
|
+
* Detect project information from a directory path
|
|
179
|
+
*/
|
|
180
|
+
export function detectProjectInfo(projectPath) {
|
|
181
|
+
const folderName = path.basename(projectPath);
|
|
182
|
+
const result = {
|
|
183
|
+
name: folderName,
|
|
184
|
+
displayName: prettifyName(folderName),
|
|
185
|
+
nameSource: 'folder',
|
|
186
|
+
language: null,
|
|
187
|
+
framework: null,
|
|
188
|
+
packageManager: null,
|
|
189
|
+
hasGit: false,
|
|
190
|
+
gitRemote: null,
|
|
191
|
+
gitBranch: null,
|
|
192
|
+
hasCompilrMd: false,
|
|
193
|
+
hasClaudeMd: false,
|
|
194
|
+
};
|
|
195
|
+
// Check for COMPILR.md and CLAUDE.md
|
|
196
|
+
result.hasCompilrMd = fs.existsSync(path.join(projectPath, 'COMPILR.md'));
|
|
197
|
+
result.hasClaudeMd = fs.existsSync(path.join(projectPath, 'CLAUDE.md'));
|
|
198
|
+
// Detect git info
|
|
199
|
+
const gitInfo = detectGitInfo(projectPath);
|
|
200
|
+
result.hasGit = gitInfo.hasGit;
|
|
201
|
+
result.gitRemote = gitInfo.remote;
|
|
202
|
+
result.gitBranch = gitInfo.branch;
|
|
203
|
+
// Detect language and framework from markers
|
|
204
|
+
for (const marker of LANGUAGE_MARKERS) {
|
|
205
|
+
let filePath = null;
|
|
206
|
+
if (marker.file.includes('*')) {
|
|
207
|
+
const pattern = marker.file.replace('*', '');
|
|
208
|
+
try {
|
|
209
|
+
const files = fs.readdirSync(projectPath);
|
|
210
|
+
const match = files.find((f) => f.endsWith(pattern));
|
|
211
|
+
if (match) {
|
|
212
|
+
filePath = path.join(projectPath, match);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
filePath = path.join(projectPath, marker.file);
|
|
221
|
+
}
|
|
222
|
+
if (filePath && fs.existsSync(filePath)) {
|
|
223
|
+
if (!result.language) {
|
|
224
|
+
result.language = marker.language;
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
228
|
+
if (marker.nameExtractor && result.nameSource === 'folder') {
|
|
229
|
+
const extractedName = marker.nameExtractor(content);
|
|
230
|
+
if (extractedName) {
|
|
231
|
+
result.name = extractedName;
|
|
232
|
+
result.displayName = prettifyName(extractedName);
|
|
233
|
+
result.nameSource = marker.file;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (!result.framework && marker.frameworkDetector) {
|
|
237
|
+
result.framework = marker.frameworkDetector(content);
|
|
238
|
+
}
|
|
239
|
+
if (!result.packageManager && marker.packageManager) {
|
|
240
|
+
result.packageManager = marker.packageManager;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
// File read failed, continue
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Detect package manager overrides for Node.js
|
|
249
|
+
if (result.language === 'node') {
|
|
250
|
+
if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
|
|
251
|
+
result.packageManager = 'pnpm';
|
|
252
|
+
}
|
|
253
|
+
else if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
|
|
254
|
+
result.packageManager = 'yarn';
|
|
255
|
+
}
|
|
256
|
+
else if (fs.existsSync(path.join(projectPath, 'bun.lockb'))) {
|
|
257
|
+
result.packageManager = 'bun';
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Detect package manager overrides for Python
|
|
261
|
+
if (result.language === 'python') {
|
|
262
|
+
if (fs.existsSync(path.join(projectPath, 'poetry.lock'))) {
|
|
263
|
+
result.packageManager = 'poetry';
|
|
264
|
+
}
|
|
265
|
+
else if (fs.existsSync(path.join(projectPath, 'pdm.lock'))) {
|
|
266
|
+
result.packageManager = 'pdm';
|
|
267
|
+
}
|
|
268
|
+
else if (fs.existsSync(path.join(projectPath, 'uv.lock'))) {
|
|
269
|
+
result.packageManager = 'uv';
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Detect git repository information
|
|
276
|
+
*/
|
|
277
|
+
export function detectGitInfo(projectPath) {
|
|
278
|
+
const result = {
|
|
279
|
+
hasGit: false,
|
|
280
|
+
remote: null,
|
|
281
|
+
branch: null,
|
|
282
|
+
};
|
|
283
|
+
const gitPath = path.join(projectPath, '.git');
|
|
284
|
+
if (!fs.existsSync(gitPath)) {
|
|
285
|
+
return result;
|
|
286
|
+
}
|
|
287
|
+
result.hasGit = true;
|
|
288
|
+
try {
|
|
289
|
+
const remote = execSync('git remote get-url origin', {
|
|
290
|
+
cwd: projectPath,
|
|
291
|
+
encoding: 'utf8',
|
|
292
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
293
|
+
}).trim();
|
|
294
|
+
if (remote) {
|
|
295
|
+
result.remote = remote;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
// No remote configured
|
|
300
|
+
}
|
|
301
|
+
try {
|
|
302
|
+
const branch = execSync('git branch --show-current', {
|
|
303
|
+
cwd: projectPath,
|
|
304
|
+
encoding: 'utf8',
|
|
305
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
306
|
+
}).trim();
|
|
307
|
+
if (branch) {
|
|
308
|
+
result.branch = branch;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Detached HEAD or git command failed
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
// =============================================================================
|
|
317
|
+
// Helper Functions
|
|
318
|
+
// =============================================================================
|
|
319
|
+
/**
|
|
320
|
+
* Convert kebab-case or snake_case to Title Case
|
|
321
|
+
*/
|
|
322
|
+
export function prettifyName(name) {
|
|
323
|
+
return name.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get a human-readable label for detected language
|
|
327
|
+
*/
|
|
328
|
+
export function getLanguageLabel(language) {
|
|
329
|
+
if (!language)
|
|
330
|
+
return 'Unknown';
|
|
331
|
+
const labels = {
|
|
332
|
+
node: 'Node.js / TypeScript',
|
|
333
|
+
go: 'Go',
|
|
334
|
+
python: 'Python',
|
|
335
|
+
rust: 'Rust',
|
|
336
|
+
java: 'Java',
|
|
337
|
+
kotlin: 'Kotlin',
|
|
338
|
+
php: 'PHP',
|
|
339
|
+
ruby: 'Ruby',
|
|
340
|
+
dotnet: '.NET (C#/F#)',
|
|
341
|
+
};
|
|
342
|
+
return labels[language] ?? language;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Get a human-readable label for detected framework
|
|
346
|
+
*/
|
|
347
|
+
export function getFrameworkLabel(framework) {
|
|
348
|
+
if (!framework)
|
|
349
|
+
return 'Not detected';
|
|
350
|
+
const labels = {
|
|
351
|
+
react: 'React',
|
|
352
|
+
vue: 'Vue.js',
|
|
353
|
+
svelte: 'Svelte',
|
|
354
|
+
angular: 'Angular',
|
|
355
|
+
next: 'Next.js',
|
|
356
|
+
nuxt: 'Nuxt.js',
|
|
357
|
+
express: 'Express.js',
|
|
358
|
+
fastify: 'Fastify',
|
|
359
|
+
koa: 'Koa',
|
|
360
|
+
hono: 'Hono',
|
|
361
|
+
electron: 'Electron',
|
|
362
|
+
fastapi: 'FastAPI',
|
|
363
|
+
django: 'Django',
|
|
364
|
+
flask: 'Flask',
|
|
365
|
+
rails: 'Ruby on Rails',
|
|
366
|
+
sinatra: 'Sinatra',
|
|
367
|
+
laravel: 'Laravel',
|
|
368
|
+
symfony: 'Symfony',
|
|
369
|
+
};
|
|
370
|
+
return labels[framework] ?? framework;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Check if a path is a valid directory that can be imported
|
|
374
|
+
*/
|
|
375
|
+
export function validateImportPath(importPath) {
|
|
376
|
+
if (!fs.existsSync(importPath)) {
|
|
377
|
+
return { valid: false, error: 'Path does not exist' };
|
|
378
|
+
}
|
|
379
|
+
try {
|
|
380
|
+
const stats = fs.statSync(importPath);
|
|
381
|
+
if (!stats.isDirectory()) {
|
|
382
|
+
return { valid: false, error: 'Path is not a directory' };
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
return { valid: false, error: 'Cannot access path' };
|
|
387
|
+
}
|
|
388
|
+
return { valid: true };
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Validate project name
|
|
392
|
+
*/
|
|
393
|
+
export function isValidProjectName(name) {
|
|
394
|
+
return /^[a-z][a-z0-9-]{1,49}$/.test(name);
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Check if project directory already exists
|
|
398
|
+
*/
|
|
399
|
+
export function projectExists(name, basePath) {
|
|
400
|
+
return fs.existsSync(path.join(basePath, name));
|
|
401
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Generator
|
|
3
|
+
*
|
|
4
|
+
* Main module for generating project scaffolding.
|
|
5
|
+
*/
|
|
6
|
+
import type { ProjectConfig, GenerationResult } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Generate a new project from configuration
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateProject(config: ProjectConfig, basePath: string): GenerationResult;
|
|
11
|
+
/**
|
|
12
|
+
* Check if git user.name and user.email are configured
|
|
13
|
+
*/
|
|
14
|
+
export declare function isGitConfigured(): boolean;
|