@eskoubar95/spec 0.1.0 → 0.1.3
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/commands/help.d.ts +5 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +23 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +30 -14
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.d.ts +5 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +88 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/update.d.ts +5 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +72 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/workspace.d.ts +5 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +17 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.js +42 -9
- package/dist/index.js.map +1 -1
- package/dist/lib/backup-cursor.d.ts +16 -0
- package/dist/lib/backup-cursor.d.ts.map +1 -0
- package/dist/lib/backup-cursor.js +50 -0
- package/dist/lib/backup-cursor.js.map +1 -0
- package/dist/lib/copy-template.d.ts +9 -1
- package/dist/lib/copy-template.d.ts.map +1 -1
- package/dist/lib/copy-template.js +94 -3
- package/dist/lib/copy-template.js.map +1 -1
- package/dist/lib/cursor-detection.d.ts +6 -0
- package/dist/lib/cursor-detection.d.ts.map +1 -0
- package/dist/lib/cursor-detection.js +31 -0
- package/dist/lib/cursor-detection.js.map +1 -0
- package/dist/lib/detection.d.ts +25 -0
- package/dist/lib/detection.d.ts.map +1 -0
- package/dist/lib/detection.js +186 -0
- package/dist/lib/detection.js.map +1 -0
- package/dist/lib/install-existing.d.ts +6 -0
- package/dist/lib/install-existing.d.ts.map +1 -0
- package/dist/lib/install-existing.js +63 -0
- package/dist/lib/install-existing.js.map +1 -0
- package/dist/lib/project-name.d.ts +7 -0
- package/dist/lib/project-name.d.ts.map +1 -0
- package/dist/lib/project-name.js +13 -0
- package/dist/lib/project-name.js.map +1 -0
- package/dist/lib/prompts.d.ts +6 -5
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +114 -0
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/version-check.d.ts +21 -0
- package/dist/lib/version-check.d.ts.map +1 -0
- package/dist/lib/version-check.js +49 -0
- package/dist/lib/version-check.js.map +1 -0
- package/dist/lib/workspace.d.ts +7 -0
- package/dist/lib/workspace.d.ts.map +1 -0
- package/dist/lib/workspace.js +38 -0
- package/dist/lib/workspace.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -2
- package/template/.cursor/commands/_shared/activation.md +220 -0
- package/template/.cursor/commands/_shared/coderabbit-integration.md +278 -0
- package/template/.cursor/commands/_shared/command-stacks.md +124 -0
- package/template/.cursor/commands/_shared/deployment-detection.md +294 -0
- package/template/.cursor/commands/_shared/detection.md +277 -0
- package/template/.cursor/commands/_shared/documentation-lookup.md +321 -0
- package/template/.cursor/commands/_shared/git-workflow.md +288 -0
- package/template/.cursor/commands/_shared/github-helpers.md +337 -0
- package/template/.cursor/commands/_shared/github-workflows.md +351 -0
- package/template/.cursor/commands/_shared/helper-metadata.md +481 -0
- package/template/.cursor/commands/_shared/linear-automation.md +388 -0
- package/template/.cursor/commands/_shared/linear-helpers.md +254 -0
- package/template/.cursor/commands/_shared/performance-monitoring.md +369 -0
- package/template/.cursor/commands/_shared/pr-description.md +279 -0
- package/template/.cursor/commands/_shared/retrospective-spec-creation.md +977 -0
- package/template/.cursor/commands/_shared/scaling.md +264 -0
- package/template/.cursor/commands/_shared/state-assertions.md +174 -0
- package/template/.cursor/commands/_shared/test-automation.md +388 -0
- package/template/.cursor/commands/_shared/verification-checkpoints.md +145 -0
- package/template/.cursor/commands/spec/audit.md +240 -0
- package/template/.cursor/commands/spec/evolve.md +163 -0
- package/template/.cursor/commands/spec/sync.md +196 -0
- package/template/.cursor/commands/tools/refactor.md +555 -0
- package/template/.cursor/rules/10-engineering.mdc +149 -0
- package/template/.cursor/rules/11-design.mdc +129 -0
- package/template/.cursor/rules/12-business.mdc +132 -0
- package/template/.cursor/rules/20-nextjs.mdc +146 -0
- package/template/.cursor/rules/21-api-design.mdc +176 -0
- package/template/.cursor/rules/30-database.mdc +183 -0
- package/template/.cursor/rules/31-testing.mdc +191 -0
- package/template/.cursor/scripts/validate-helpers.js +254 -0
- package/template/.sdd/detection-cache.json +1 -0
- package/template/.sdd/install-info.json +1 -0
- package/template/.sdd/version +1 -0
- package/template/spec/00-root-spec.md +8 -1
- package/template/work/backlog/tasks.local.md +92 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
+
import { backupCursorFolder, checkCursorFolder } from './backup-cursor.js';
|
|
4
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
5
6
|
const __dirname = path.dirname(__filename);
|
|
6
7
|
/**
|
|
@@ -26,18 +27,108 @@ async function getTemplateDir() {
|
|
|
26
27
|
}
|
|
27
28
|
/**
|
|
28
29
|
* Copies the template directory to the destination
|
|
30
|
+
* @param destPath - Destination path
|
|
31
|
+
* @param allowOverwrite - Allow overwriting existing directory (for install mode)
|
|
29
32
|
*/
|
|
30
|
-
export async function copyTemplate(destPath) {
|
|
33
|
+
export async function copyTemplate(destPath, allowOverwrite = false) {
|
|
31
34
|
const templateDir = await getTemplateDir();
|
|
32
35
|
if (!(await fs.pathExists(templateDir))) {
|
|
33
36
|
throw new Error(`Template directory not found: ${templateDir}`);
|
|
34
37
|
}
|
|
35
38
|
// Check if destination exists
|
|
36
39
|
if (await fs.pathExists(destPath)) {
|
|
37
|
-
|
|
40
|
+
if (!allowOverwrite) {
|
|
41
|
+
throw new Error(`Destination already exists: ${destPath}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Create destination if it doesn't exist
|
|
46
|
+
await fs.ensureDir(destPath);
|
|
38
47
|
}
|
|
39
48
|
// Copy template to destination
|
|
40
|
-
await fs.copy(templateDir, destPath
|
|
49
|
+
await fs.copy(templateDir, destPath, {
|
|
50
|
+
overwrite: allowOverwrite,
|
|
51
|
+
filter: (src, dest) => {
|
|
52
|
+
// Skip .git if exists in template
|
|
53
|
+
if (path.basename(src) === '.git') {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Installs template to existing project with backup/merge support
|
|
62
|
+
* @param projectPath - Path to the existing project
|
|
63
|
+
* @param backupStrategy - 'backup' or 'merge'
|
|
64
|
+
*/
|
|
65
|
+
export async function installTemplate(projectPath, backupStrategy = 'backup') {
|
|
66
|
+
const templateDir = await getTemplateDir();
|
|
67
|
+
if (!(await fs.pathExists(templateDir))) {
|
|
68
|
+
throw new Error(`Template directory not found: ${templateDir}`);
|
|
69
|
+
}
|
|
70
|
+
// Check if .cursor folder exists
|
|
71
|
+
const { hasCursorFolder, hasContent } = await checkCursorFolder(projectPath);
|
|
72
|
+
if (hasCursorFolder && hasContent && backupStrategy === 'backup') {
|
|
73
|
+
// Backup existing .cursor folder
|
|
74
|
+
const backupPath = await backupCursorFolder(projectPath);
|
|
75
|
+
console.log(` Backed up .cursor folder to: ${path.basename(backupPath)}`);
|
|
76
|
+
}
|
|
77
|
+
// Copy .cursor folder from template (will overwrite if backup was done, merge otherwise)
|
|
78
|
+
const templateCursorPath = path.join(templateDir, '.cursor');
|
|
79
|
+
const destCursorPath = path.join(projectPath, '.cursor');
|
|
80
|
+
if (await fs.pathExists(templateCursorPath)) {
|
|
81
|
+
if (backupStrategy === 'merge' && hasCursorFolder) {
|
|
82
|
+
// Merge: Copy only files that don't exist
|
|
83
|
+
const mergeCursorFolder = async (src, dest) => {
|
|
84
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
85
|
+
for (const entry of entries) {
|
|
86
|
+
const srcPath = path.join(src, entry.name);
|
|
87
|
+
const destPath = path.join(dest, entry.name);
|
|
88
|
+
if (entry.isDirectory()) {
|
|
89
|
+
if (!(await fs.pathExists(destPath))) {
|
|
90
|
+
await fs.copy(srcPath, destPath);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
await mergeCursorFolder(srcPath, destPath);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Only copy if file doesn't exist in destination
|
|
98
|
+
if (!(await fs.pathExists(destPath))) {
|
|
99
|
+
await fs.copy(srcPath, destPath);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.log(` Preserved existing file: .cursor/${entry.name}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
await fs.ensureDir(destCursorPath);
|
|
108
|
+
await mergeCursorFolder(templateCursorPath, destCursorPath);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// Backup strategy or no existing .cursor: Copy all
|
|
112
|
+
await fs.copy(templateCursorPath, destCursorPath, { overwrite: true });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Copy spec/ and work/ folders if they don't exist
|
|
116
|
+
const specPath = path.join(projectPath, 'spec');
|
|
117
|
+
const workPath = path.join(projectPath, 'work');
|
|
118
|
+
const templateSpecPath = path.join(templateDir, 'spec');
|
|
119
|
+
const templateWorkPath = path.join(templateDir, 'work');
|
|
120
|
+
if (await fs.pathExists(templateSpecPath) && !(await fs.pathExists(specPath))) {
|
|
121
|
+
await fs.copy(templateSpecPath, specPath);
|
|
122
|
+
}
|
|
123
|
+
if (await fs.pathExists(templateWorkPath) && !(await fs.pathExists(workPath))) {
|
|
124
|
+
await fs.copy(templateWorkPath, workPath);
|
|
125
|
+
}
|
|
126
|
+
// Copy .sdd/ folder
|
|
127
|
+
const sddPath = path.join(projectPath, '.sdd');
|
|
128
|
+
const templateSddPath = path.join(templateDir, '.sdd');
|
|
129
|
+
if (await fs.pathExists(templateSddPath)) {
|
|
130
|
+
await fs.copy(templateSddPath, sddPath, { overwrite: true });
|
|
131
|
+
}
|
|
41
132
|
}
|
|
42
133
|
/**
|
|
43
134
|
* Creates the linear sync config file if mode is linear
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-template.js","sourceRoot":"","sources":["../../src/lib/copy-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"copy-template.js","sourceRoot":"","sources":["../../src/lib/copy-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE3E,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;;GAGG;AACH,KAAK,UAAU,cAAc;IAC3B,iDAAiD;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAE7D,kCAAkC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACxD,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAEvD,oCAAoC;IACpC,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC3C,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IACD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACxC,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,wEAAwE;IACxE,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,iBAA0B,KAAK;IAClF,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAE3C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,WAAW,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,8BAA8B;IAC9B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,yCAAyC;QACzC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,+BAA+B;IAC/B,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE;QACnC,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;YACpB,kCAAkC;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC;gBAClC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,iBAAqC,QAAQ;IAE7C,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;IAE3C,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,iCAAiC,WAAW,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,iCAAiC;IACjC,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAE7E,IAAI,eAAe,IAAI,UAAU,IAAI,cAAc,KAAK,QAAQ,EAAE,CAAC;QACjE,iCAAiC;QACjC,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,yFAAyF;IACzF,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEzD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC5C,IAAI,cAAc,KAAK,OAAO,IAAI,eAAe,EAAE,CAAC;YAClD,0CAA0C;YAC1C,MAAM,iBAAiB,GAAG,KAAK,EAAE,GAAW,EAAE,IAAY,EAAE,EAAE;gBAC5D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBAE7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;wBACxB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;4BACrC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;wBACnC,CAAC;6BAAM,CAAC;4BACN,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;wBAC7C,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,iDAAiD;wBACjD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;4BACrC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;wBACnC,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,GAAG,CAAC,uCAAuC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;wBACnE,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;YACnC,MAAM,iBAAiB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,mDAAmD;YACnD,MAAM,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAExD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC9E,MAAM,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC9E,MAAM,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,oBAAoB;IACpB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAEvD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,WAAmB;IAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IAE1D,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-detection.d.ts","sourceRoot":"","sources":["../../src/lib/cursor-detection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CA+B3C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects if the CLI is running from within Cursor IDE terminal
|
|
3
|
+
* @returns true if running in Cursor, false otherwise
|
|
4
|
+
*/
|
|
5
|
+
export function isRunningInCursor() {
|
|
6
|
+
// Check environment variables
|
|
7
|
+
const env = process.env;
|
|
8
|
+
// Check for Cursor-specific variables (will check below)
|
|
9
|
+
// Check for VS Code variables (Cursor is based on VS Code)
|
|
10
|
+
if (env.VSCODE_PID !== undefined || env.VSCODE_INJECTION !== undefined) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
// Check TERM_PROGRAM
|
|
14
|
+
if (env.TERM_PROGRAM === 'cursor' || env.TERM_PROGRAM === 'vscode') {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
// Check for CURSOR_* pattern in environment
|
|
18
|
+
const cursorVars = Object.keys(env).filter(key => key.startsWith('CURSOR_'));
|
|
19
|
+
if (cursorVars.length > 0) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
// Check parent process name (if available)
|
|
23
|
+
if (env._) {
|
|
24
|
+
const processPath = env._.toLowerCase();
|
|
25
|
+
if (processPath.includes('cursor') || processPath.includes('cursor.app')) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=cursor-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-detection.js","sourceRoot":"","sources":["../../src/lib/cursor-detection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,8BAA8B;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAExB,yDAAyD;IAEzD,2DAA2D;IAC3D,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,GAAG,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qBAAqB;IACrB,IAAI,GAAG,CAAC,YAAY,KAAK,QAAQ,IAAI,GAAG,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4CAA4C;IAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7E,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2CAA2C;IAC3C,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC;QACV,MAAM,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DetectionResults {
|
|
2
|
+
projectType: string;
|
|
3
|
+
projectSize: 'small' | 'medium' | 'large' | 'enterprise';
|
|
4
|
+
technologies: string[];
|
|
5
|
+
phase?: 'initialization' | 'expansion' | 'maintenance' | 'migration' | 'legacy';
|
|
6
|
+
}
|
|
7
|
+
export interface ProjectInfo {
|
|
8
|
+
hasCursorFolder: boolean;
|
|
9
|
+
hasCodebase: boolean;
|
|
10
|
+
projectType?: string;
|
|
11
|
+
techStack?: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Checks if a path is an existing project (has files, manifests, etc.)
|
|
15
|
+
*/
|
|
16
|
+
export declare function isExistingProject(projectPath: string): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* Detects existing project info (for installation context)
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectExistingProject(projectPath: string): Promise<ProjectInfo>;
|
|
21
|
+
/**
|
|
22
|
+
* Runs simplified detection matching detection helper logic
|
|
23
|
+
*/
|
|
24
|
+
export declare function runDetection(projectPath: string): Promise<DetectionResults>;
|
|
25
|
+
//# sourceMappingURL=detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../src/lib/detection.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IACzD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,gBAAgB,GAAG,WAAW,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;CACjF;AAED,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAyB7E;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA+CrF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuGjF"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a path is an existing project (has files, manifests, etc.)
|
|
5
|
+
*/
|
|
6
|
+
export async function isExistingProject(projectPath) {
|
|
7
|
+
if (!(await fs.pathExists(projectPath))) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const files = await fs.readdir(projectPath).catch(() => []);
|
|
11
|
+
// Check for project manifests
|
|
12
|
+
const hasManifest = files.some(file => ['package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml', 'requirements.txt'].includes(file));
|
|
13
|
+
// Check for source directories
|
|
14
|
+
const hasSourceDirs = files.some(file => ['src', 'app', 'lib', 'pages', 'components'].includes(file));
|
|
15
|
+
// Check for git repository
|
|
16
|
+
const hasGit = files.some(file => file === '.git');
|
|
17
|
+
// Has content (not empty)
|
|
18
|
+
const hasContent = files.length > 0;
|
|
19
|
+
// It's a project if it has manifest OR (has source dirs AND has content) OR has git
|
|
20
|
+
return hasManifest || (hasSourceDirs && hasContent) || hasGit;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Detects existing project info (for installation context)
|
|
24
|
+
*/
|
|
25
|
+
export async function detectExistingProject(projectPath) {
|
|
26
|
+
const cursorPath = path.join(projectPath, '.cursor');
|
|
27
|
+
const hasCursorFolder = await fs.pathExists(cursorPath);
|
|
28
|
+
const hasCodebase = await isExistingProject(projectPath);
|
|
29
|
+
let projectType;
|
|
30
|
+
let techStack = [];
|
|
31
|
+
if (hasCodebase) {
|
|
32
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
33
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
34
|
+
try {
|
|
35
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
36
|
+
// Detect technologies from dependencies
|
|
37
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
38
|
+
if (deps.next)
|
|
39
|
+
techStack.push('nextjs');
|
|
40
|
+
if (deps.react)
|
|
41
|
+
techStack.push('react');
|
|
42
|
+
if (deps.vue)
|
|
43
|
+
techStack.push('vue');
|
|
44
|
+
if (deps.express)
|
|
45
|
+
techStack.push('express');
|
|
46
|
+
if (deps.fastapi || deps.flask)
|
|
47
|
+
techStack.push('python-api');
|
|
48
|
+
if (deps['@nestjs/core'])
|
|
49
|
+
techStack.push('nestjs');
|
|
50
|
+
if (deps.typeorm || deps.prisma)
|
|
51
|
+
techStack.push('database-orm');
|
|
52
|
+
// Detect project type
|
|
53
|
+
if (packageJson.bin) {
|
|
54
|
+
projectType = 'cli-tool';
|
|
55
|
+
}
|
|
56
|
+
else if (deps.next || deps.react || deps.vue) {
|
|
57
|
+
projectType = 'web-app';
|
|
58
|
+
}
|
|
59
|
+
else if (deps.express || deps['@nestjs/core']) {
|
|
60
|
+
projectType = 'api-service';
|
|
61
|
+
}
|
|
62
|
+
else if (packageJson.exports || packageJson.types) {
|
|
63
|
+
projectType = 'library';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Ignore JSON parse errors
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
hasCursorFolder,
|
|
73
|
+
hasCodebase,
|
|
74
|
+
projectType,
|
|
75
|
+
techStack,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Runs simplified detection matching detection helper logic
|
|
80
|
+
*/
|
|
81
|
+
export async function runDetection(projectPath) {
|
|
82
|
+
const technologies = [];
|
|
83
|
+
let projectType = 'unknown';
|
|
84
|
+
let projectSize = 'small';
|
|
85
|
+
// Check for package.json
|
|
86
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
87
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
88
|
+
try {
|
|
89
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
90
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
91
|
+
// Detect technologies
|
|
92
|
+
if (deps.next) {
|
|
93
|
+
technologies.push('Next.js');
|
|
94
|
+
projectType = 'web-app';
|
|
95
|
+
}
|
|
96
|
+
if (deps.react)
|
|
97
|
+
technologies.push('React');
|
|
98
|
+
if (deps.vue) {
|
|
99
|
+
technologies.push('Vue');
|
|
100
|
+
if (!projectType || projectType === 'unknown')
|
|
101
|
+
projectType = 'web-app';
|
|
102
|
+
}
|
|
103
|
+
if (deps.express) {
|
|
104
|
+
technologies.push('Express');
|
|
105
|
+
if (projectType === 'unknown')
|
|
106
|
+
projectType = 'api-service';
|
|
107
|
+
}
|
|
108
|
+
if (deps.fastapi || deps.flask) {
|
|
109
|
+
technologies.push('Python');
|
|
110
|
+
if (projectType === 'unknown')
|
|
111
|
+
projectType = 'api-service';
|
|
112
|
+
}
|
|
113
|
+
if (deps.typeorm || deps.prisma)
|
|
114
|
+
technologies.push('ORM');
|
|
115
|
+
if (deps.mongodb || deps.pg)
|
|
116
|
+
technologies.push('Database');
|
|
117
|
+
// Check for CLI tool
|
|
118
|
+
if (packageJson.bin) {
|
|
119
|
+
projectType = 'cli-tool';
|
|
120
|
+
}
|
|
121
|
+
// Check for library
|
|
122
|
+
if ((packageJson.exports || packageJson.types) && !packageJson.bin) {
|
|
123
|
+
if (projectType === 'unknown')
|
|
124
|
+
projectType = 'library';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Ignore JSON parse errors
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Check for Python project
|
|
132
|
+
const pyprojectPath = path.join(projectPath, 'pyproject.toml');
|
|
133
|
+
if (await fs.pathExists(pyprojectPath)) {
|
|
134
|
+
technologies.push('Python');
|
|
135
|
+
if (projectType === 'unknown')
|
|
136
|
+
projectType = 'api-service';
|
|
137
|
+
}
|
|
138
|
+
// Count files (simplified)
|
|
139
|
+
let fileCount = 0;
|
|
140
|
+
try {
|
|
141
|
+
const countFiles = async (dir) => {
|
|
142
|
+
let count = 0;
|
|
143
|
+
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
const fullPath = path.join(dir, entry.name);
|
|
146
|
+
// Skip ignored directories
|
|
147
|
+
if (['node_modules', '.git', 'dist', 'build', '.next', '.cursor'].includes(entry.name)) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (entry.isDirectory()) {
|
|
151
|
+
count += await countFiles(fullPath);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
count++;
|
|
155
|
+
}
|
|
156
|
+
// Limit counting to avoid performance issues
|
|
157
|
+
if (count > 1000)
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
return count;
|
|
161
|
+
};
|
|
162
|
+
fileCount = await countFiles(projectPath);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Ignore errors
|
|
166
|
+
}
|
|
167
|
+
// Determine project size
|
|
168
|
+
if (fileCount < 50) {
|
|
169
|
+
projectSize = 'small';
|
|
170
|
+
}
|
|
171
|
+
else if (fileCount < 200) {
|
|
172
|
+
projectSize = 'medium';
|
|
173
|
+
}
|
|
174
|
+
else if (fileCount < 1000) {
|
|
175
|
+
projectSize = 'large';
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
projectSize = 'enterprise';
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
projectType,
|
|
182
|
+
projectSize,
|
|
183
|
+
technologies,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detection.js","sourceRoot":"","sources":["../../src/lib/detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates spec/00-root-spec.md for existing projects with frontmatter marking
|
|
3
|
+
* @param projectPath - Path to the project
|
|
4
|
+
*/
|
|
5
|
+
export declare function createSpecForExistingProject(projectPath: string): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=install-existing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-existing.d.ts","sourceRoot":"","sources":["../../src/lib/install-existing.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DrF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Creates spec/00-root-spec.md for existing projects with frontmatter marking
|
|
5
|
+
* @param projectPath - Path to the project
|
|
6
|
+
*/
|
|
7
|
+
export async function createSpecForExistingProject(projectPath) {
|
|
8
|
+
const specPath = path.join(projectPath, 'spec', '00-root-spec.md');
|
|
9
|
+
// Check if spec already exists
|
|
10
|
+
if (await fs.pathExists(specPath)) {
|
|
11
|
+
return; // Don't overwrite existing spec
|
|
12
|
+
}
|
|
13
|
+
// Ensure spec directory exists
|
|
14
|
+
await fs.ensureDir(path.dirname(specPath));
|
|
15
|
+
// Get current date
|
|
16
|
+
const installationDate = new Date().toISOString().split('T')[0];
|
|
17
|
+
// Create spec file with frontmatter marking for existing projects
|
|
18
|
+
const specContent = `---
|
|
19
|
+
sdd_version: 0.1.0
|
|
20
|
+
installed_in_existing_project: true
|
|
21
|
+
installation_date: ${installationDate}
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Project Root Specification
|
|
25
|
+
|
|
26
|
+
## 1. Idea Overview
|
|
27
|
+
Describe the idea in broad terms.
|
|
28
|
+
What problem does this project aim to solve?
|
|
29
|
+
|
|
30
|
+
## 2. Motivation
|
|
31
|
+
Why does this project exist?
|
|
32
|
+
What makes it worth building?
|
|
33
|
+
|
|
34
|
+
## 3. Target Users
|
|
35
|
+
Who is this for?
|
|
36
|
+
(Keep it high-level; personas can come later.)
|
|
37
|
+
|
|
38
|
+
## 4. Core Value
|
|
39
|
+
What is the main value delivered to users?
|
|
40
|
+
|
|
41
|
+
## 5. Initial Scope
|
|
42
|
+
What feels in-scope right now?
|
|
43
|
+
What explicitly feels out-of-scope?
|
|
44
|
+
|
|
45
|
+
## 6. Open Questions
|
|
46
|
+
List uncertainties, assumptions, or things that need clarification.
|
|
47
|
+
|
|
48
|
+
## 7. Early Risks & Concerns
|
|
49
|
+
Only include risks that are already visible at this stage.
|
|
50
|
+
|
|
51
|
+
## 8. Notes
|
|
52
|
+
Anything else discovered during discussion or research.
|
|
53
|
+
|
|
54
|
+
## 9. Related Specifications
|
|
55
|
+
If applicable, reference:
|
|
56
|
+
- \`spec/01-prd.md\` (if PRD was created)
|
|
57
|
+
- \`spec/02-architecture.md\` (if architecture is documented)
|
|
58
|
+
- \`spec/07-design-system.md\` (if design is critical)
|
|
59
|
+
- \`spec/08-infrastructure.md\` (if infrastructure is critical)
|
|
60
|
+
`;
|
|
61
|
+
await fs.writeFile(specPath, specContent, 'utf-8');
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=install-existing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-existing.js","sourceRoot":"","sources":["../../src/lib/install-existing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,WAAmB;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAEnE,+BAA+B;IAC/B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,gCAAgC;IAC1C,CAAC;IAED,+BAA+B;IAC/B,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE3C,mBAAmB;IACnB,MAAM,gBAAgB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEhE,kEAAkE;IAClE,MAAM,WAAW,GAAG;;;qBAGD,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCpC,CAAC;IAEA,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes project name by converting spaces to hyphens and lowercase
|
|
3
|
+
* @param name - The project name to normalize
|
|
4
|
+
* @returns Normalized project name
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeProjectName(name: string): string;
|
|
7
|
+
//# sourceMappingURL=project-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-name.d.ts","sourceRoot":"","sources":["../../src/lib/project-name.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMzD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes project name by converting spaces to hyphens and lowercase
|
|
3
|
+
* @param name - The project name to normalize
|
|
4
|
+
* @returns Normalized project name
|
|
5
|
+
*/
|
|
6
|
+
export function normalizeProjectName(name) {
|
|
7
|
+
return name
|
|
8
|
+
.trim()
|
|
9
|
+
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
10
|
+
.toLowerCase()
|
|
11
|
+
.replace(/[<>:"/\\|?*]/g, ''); // Remove invalid characters (should already be validated, but extra safety)
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=project-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-name.js","sourceRoot":"","sources":["../../src/lib/project-name.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI;SACR,IAAI,EAAE;SACN,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,8BAA8B;SACnD,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,4EAA4E;AAC/G,CAAC"}
|
package/dist/lib/prompts.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
taskMode: 'local' | 'linear';
|
|
4
|
-
gitInit: boolean;
|
|
5
|
-
}
|
|
1
|
+
import type { InitAnswers, InstallAnswers } from '../types.js';
|
|
2
|
+
export type { InitAnswers, InstallAnswers };
|
|
6
3
|
/**
|
|
7
4
|
* Prompts the user for project initialization options
|
|
8
5
|
*/
|
|
9
6
|
export declare function promptInit(): Promise<InitAnswers>;
|
|
7
|
+
/**
|
|
8
|
+
* Prompts the user for installation options
|
|
9
|
+
*/
|
|
10
|
+
export declare function promptInstall(projectPath: string): Promise<InstallAnswers>;
|
|
10
11
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG/D,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AAE5C;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CA4EvD;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA4EhF"}
|