@compilr-dev/sdk 0.2.5 → 0.2.7

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.
Files changed (33) hide show
  1. package/dist/index.d.ts +4 -1
  2. package/dist/index.js +13 -1
  3. package/dist/platform/file-anchor-service.d.ts +62 -0
  4. package/dist/platform/file-anchor-service.js +241 -0
  5. package/dist/platform/index.d.ts +2 -0
  6. package/dist/platform/index.js +2 -0
  7. package/dist/project-generator/detection.d.ts +42 -0
  8. package/dist/project-generator/detection.js +401 -0
  9. package/dist/project-generator/generator.d.ts +14 -0
  10. package/dist/project-generator/generator.js +245 -0
  11. package/dist/project-generator/index.d.ts +11 -0
  12. package/dist/project-generator/index.js +13 -0
  13. package/dist/project-generator/templates/coding-standards.d.ts +7 -0
  14. package/dist/project-generator/templates/coding-standards.js +299 -0
  15. package/dist/project-generator/templates/compilr-md-import.d.ts +8 -0
  16. package/dist/project-generator/templates/compilr-md-import.js +241 -0
  17. package/dist/project-generator/templates/compilr-md.d.ts +7 -0
  18. package/dist/project-generator/templates/compilr-md.js +141 -0
  19. package/dist/project-generator/templates/config-json.d.ts +13 -0
  20. package/dist/project-generator/templates/config-json.js +39 -0
  21. package/dist/project-generator/templates/gitignore.d.ts +7 -0
  22. package/dist/project-generator/templates/gitignore.js +85 -0
  23. package/dist/project-generator/templates/index.d.ts +11 -0
  24. package/dist/project-generator/templates/index.js +11 -0
  25. package/dist/project-generator/templates/package-json.d.ts +7 -0
  26. package/dist/project-generator/templates/package-json.js +111 -0
  27. package/dist/project-generator/templates/readme-md.d.ts +7 -0
  28. package/dist/project-generator/templates/readme-md.js +165 -0
  29. package/dist/project-generator/templates/tsconfig.d.ts +7 -0
  30. package/dist/project-generator/templates/tsconfig.js +61 -0
  31. package/dist/project-generator/types.d.ts +95 -0
  32. package/dist/project-generator/types.js +24 -0
  33. package/package.json +1 -1
@@ -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;
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Project Generator
3
+ *
4
+ * Main module for generating project scaffolding.
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import { execSync } from 'child_process';
9
+ import { generateCompilrMd } from './templates/compilr-md.js';
10
+ import { generateCodingStandardsMd } from './templates/coding-standards.js';
11
+ import { generateConfigJson } from './templates/config-json.js';
12
+ import { generateReadmeMd } from './templates/readme-md.js';
13
+ import { generatePackageJson } from './templates/package-json.js';
14
+ import { generateGitignore } from './templates/gitignore.js';
15
+ import { generateTsconfig } from './templates/tsconfig.js';
16
+ // =============================================================================
17
+ // Main Generator
18
+ // =============================================================================
19
+ /**
20
+ * Generate a new project from configuration
21
+ */
22
+ export function generateProject(config, basePath) {
23
+ const filesCreated = [];
24
+ try {
25
+ if (config.repoPattern === 'single') {
26
+ return generateSingleRepoProject(config, basePath, filesCreated);
27
+ }
28
+ else {
29
+ return generateTwoRepoProject(config, basePath, filesCreated);
30
+ }
31
+ }
32
+ catch (error) {
33
+ return {
34
+ success: false,
35
+ projectPath: path.join(basePath, config.name),
36
+ filesCreated,
37
+ error: error instanceof Error ? error.message : String(error),
38
+ };
39
+ }
40
+ }
41
+ // =============================================================================
42
+ // Single Repo Pattern
43
+ // =============================================================================
44
+ function generateSingleRepoProject(config, basePath, filesCreated) {
45
+ const projectPath = path.join(basePath, config.name);
46
+ // Create directory structure
47
+ const dirs = [
48
+ projectPath,
49
+ path.join(projectPath, 'src'),
50
+ path.join(projectPath, '.compilr'),
51
+ path.join(projectPath, '.compilr', 'architecture'),
52
+ path.join(projectPath, '.compilr', 'architecture', 'decisions'),
53
+ path.join(projectPath, '.compilr', 'docs'),
54
+ path.join(projectPath, '.compilr', 'sessions'),
55
+ ];
56
+ for (const dir of dirs) {
57
+ fs.mkdirSync(dir, { recursive: true });
58
+ }
59
+ // Generate and write files
60
+ const files = [
61
+ { path: path.join(projectPath, 'COMPILR.md'), content: generateCompilrMd(config) },
62
+ { path: path.join(projectPath, 'README.md'), content: generateReadmeMd(config) },
63
+ { path: path.join(projectPath, 'package.json'), content: generatePackageJson(config) },
64
+ { path: path.join(projectPath, '.gitignore'), content: generateGitignore(config) },
65
+ { path: path.join(projectPath, 'tsconfig.json'), content: generateTsconfig(config) },
66
+ {
67
+ path: path.join(projectPath, '.compilr', 'config.json'),
68
+ content: generateConfigJson(config, projectPath),
69
+ },
70
+ { path: path.join(projectPath, '.compilr', 'roadmap.md'), content: generateRoadmapMd(config) },
71
+ {
72
+ path: path.join(projectPath, '.compilr', 'architecture', 'coding-standards.md'),
73
+ content: generateCodingStandardsMd(config),
74
+ },
75
+ {
76
+ path: path.join(projectPath, '.compilr', 'docs', 'README.md'),
77
+ content: '# Documentation\n\n*Add your documentation here*\n',
78
+ },
79
+ {
80
+ path: path.join(projectPath, '.compilr', 'sessions', 'README.md'),
81
+ content: '# Session Notes\n\n*Session notes will be auto-generated here*\n',
82
+ },
83
+ ];
84
+ for (const file of files) {
85
+ fs.writeFileSync(file.path, file.content, 'utf-8');
86
+ filesCreated.push(file.path);
87
+ }
88
+ // Initialize git if requested
89
+ if (config.initGit) {
90
+ initGit(projectPath);
91
+ }
92
+ return {
93
+ success: true,
94
+ projectPath,
95
+ filesCreated,
96
+ };
97
+ }
98
+ // =============================================================================
99
+ // Two Repo Pattern
100
+ // =============================================================================
101
+ function generateTwoRepoProject(config, basePath, filesCreated) {
102
+ const projectPath = path.join(basePath, config.name);
103
+ const docsPath = path.join(basePath, `${config.name}-docs`);
104
+ // Create code repo structure
105
+ const codeDirs = [projectPath, path.join(projectPath, 'src')];
106
+ for (const dir of codeDirs) {
107
+ fs.mkdirSync(dir, { recursive: true });
108
+ }
109
+ // Create docs repo structure
110
+ const docsDirs = [
111
+ docsPath,
112
+ path.join(docsPath, '.compilr'),
113
+ path.join(docsPath, '01-planning'),
114
+ path.join(docsPath, '02-architecture'),
115
+ path.join(docsPath, '02-architecture', 'decisions'),
116
+ path.join(docsPath, '03-documentation'),
117
+ path.join(docsPath, '04-session-notes'),
118
+ ];
119
+ for (const dir of docsDirs) {
120
+ fs.mkdirSync(dir, { recursive: true });
121
+ }
122
+ // Generate code repo files
123
+ const codeFiles = [
124
+ { path: path.join(projectPath, 'README.md'), content: generateReadmeMd(config) },
125
+ { path: path.join(projectPath, 'package.json'), content: generatePackageJson(config) },
126
+ { path: path.join(projectPath, '.gitignore'), content: generateGitignore(config) },
127
+ { path: path.join(projectPath, 'tsconfig.json'), content: generateTsconfig(config) },
128
+ ];
129
+ for (const file of codeFiles) {
130
+ fs.writeFileSync(file.path, file.content, 'utf-8');
131
+ filesCreated.push(file.path);
132
+ }
133
+ // Generate docs repo files
134
+ const docsFiles = [
135
+ { path: path.join(docsPath, 'COMPILR.md'), content: generateCompilrMd(config) },
136
+ {
137
+ path: path.join(docsPath, '.compilr', 'config.json'),
138
+ content: generateConfigJson(config, projectPath, docsPath),
139
+ },
140
+ { path: path.join(docsPath, '01-planning', 'roadmap.md'), content: generateRoadmapMd(config) },
141
+ {
142
+ path: path.join(docsPath, '02-architecture', 'coding-standards.md'),
143
+ content: generateCodingStandardsMd(config),
144
+ },
145
+ {
146
+ path: path.join(docsPath, '03-documentation', 'README.md'),
147
+ content: '# Documentation\n\n*Add your documentation here*\n',
148
+ },
149
+ {
150
+ path: path.join(docsPath, '04-session-notes', 'README.md'),
151
+ content: '# Session Notes\n\n*Session notes will be auto-generated here*\n',
152
+ },
153
+ ];
154
+ for (const file of docsFiles) {
155
+ fs.writeFileSync(file.path, file.content, 'utf-8');
156
+ filesCreated.push(file.path);
157
+ }
158
+ // Initialize git if requested
159
+ if (config.initGit) {
160
+ initGit(projectPath);
161
+ initGit(docsPath);
162
+ }
163
+ return {
164
+ success: true,
165
+ projectPath,
166
+ docsPath,
167
+ filesCreated,
168
+ };
169
+ }
170
+ // =============================================================================
171
+ // Helper Functions
172
+ // =============================================================================
173
+ /**
174
+ * Check if git user.name and user.email are configured
175
+ */
176
+ export function isGitConfigured() {
177
+ try {
178
+ const name = execSync('git config --global user.name', {
179
+ encoding: 'utf8',
180
+ stdio: ['pipe', 'pipe', 'pipe'],
181
+ }).trim();
182
+ const email = execSync('git config --global user.email', {
183
+ encoding: 'utf8',
184
+ stdio: ['pipe', 'pipe', 'pipe'],
185
+ }).trim();
186
+ return Boolean(name && email);
187
+ }
188
+ catch {
189
+ return false;
190
+ }
191
+ }
192
+ /**
193
+ * Initialize git repository
194
+ * If git config is not set, only runs git init (skips commit)
195
+ */
196
+ function initGit(projectPath) {
197
+ try {
198
+ execSync('git init', { cwd: projectPath, stdio: 'ignore' });
199
+ execSync('git add .', { cwd: projectPath, stdio: 'ignore' });
200
+ if (isGitConfigured()) {
201
+ execSync('git commit -m "Initial commit from compilr init"', {
202
+ cwd: projectPath,
203
+ stdio: 'ignore',
204
+ });
205
+ }
206
+ }
207
+ catch {
208
+ // Git init failed - not critical
209
+ }
210
+ }
211
+ function generateRoadmapMd(config) {
212
+ return `# Roadmap - ${config.name}
213
+
214
+ ## Vision
215
+
216
+ ${config.description}
217
+
218
+ ---
219
+
220
+ ## Milestones
221
+
222
+ ### Milestone 1: Foundation
223
+ - [ ] Project setup
224
+ - [ ] Development environment
225
+ - [ ] CI/CD pipeline
226
+
227
+ ### Milestone 2: Core Features
228
+ - [ ] *Define your core features*
229
+
230
+ ### Milestone 3: Launch
231
+ - [ ] Testing
232
+ - [ ] Documentation
233
+ - [ ] Deploy to production
234
+
235
+ ---
236
+
237
+ ## Timeline
238
+
239
+ *Add your timeline here*
240
+
241
+ ---
242
+
243
+ *Last Updated: ${new Date().toISOString().split('T')[0]}*
244
+ `;
245
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Project Generator — SDK module for creating and importing projects.
3
+ *
4
+ * Provides template generation, project scaffolding, and project detection
5
+ * shared by CLI and Desktop apps.
6
+ */
7
+ export type { TechStack, CodingStandards, GeneratorRepoPattern, ProjectConfig, GenerationResult, CompilrConfig, DetectedProject, GitInfo, ImportProjectConfig, } from './types.js';
8
+ export { TECH_STACK_LABELS, CODING_STANDARDS_LABELS, REPO_PATTERN_LABELS, WORKFLOW_VERSION, } from './types.js';
9
+ export { generateProject, isGitConfigured } from './generator.js';
10
+ export { generateCompilrMd, generateConfigJson, generateReadmeMd, generateCodingStandardsMd, generatePackageJson, generateTsconfig, generateGitignore, generateCompilrMdForImport, } from './templates/index.js';
11
+ export { detectProjectInfo, detectGitInfo, prettifyName, getLanguageLabel, getFrameworkLabel, validateImportPath, isValidProjectName, projectExists, } from './detection.js';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Project Generator — SDK module for creating and importing projects.
3
+ *
4
+ * Provides template generation, project scaffolding, and project detection
5
+ * shared by CLI and Desktop apps.
6
+ */
7
+ export { TECH_STACK_LABELS, CODING_STANDARDS_LABELS, REPO_PATTERN_LABELS, WORKFLOW_VERSION, } from './types.js';
8
+ // Generator
9
+ export { generateProject, isGitConfigured } from './generator.js';
10
+ // Templates (individual generators for preview/customization)
11
+ export { generateCompilrMd, generateConfigJson, generateReadmeMd, generateCodingStandardsMd, generatePackageJson, generateTsconfig, generateGitignore, generateCompilrMdForImport, } from './templates/index.js';
12
+ // Detection
13
+ export { detectProjectInfo, detectGitInfo, prettifyName, getLanguageLabel, getFrameworkLabel, validateImportPath, isValidProjectName, projectExists, } from './detection.js';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Coding Standards Template Generator
3
+ *
4
+ * Generates the coding standards documentation.
5
+ */
6
+ import type { ProjectConfig } from '../types.js';
7
+ export declare function generateCodingStandardsMd(config: ProjectConfig): string;