create-sdd-project 0.8.0 → 0.8.1
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/bin/cli.js +8 -22
- package/lib/generator.js +29 -0
- package/lib/upgrade-generator.js +27 -0
- package/package.json +1 -1
- package/template/.claude/settings.local.json +55 -0
- package/template/gitignore +48 -0
package/bin/cli.js
CHANGED
|
@@ -38,9 +38,9 @@ function runDoctorCmd() {
|
|
|
38
38
|
|
|
39
39
|
const cwd = process.cwd();
|
|
40
40
|
|
|
41
|
-
// Validate: must be in
|
|
42
|
-
if (!fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
43
|
-
console.error('Error: No package.json found in current directory.');
|
|
41
|
+
// Validate: must be in a project with SDD installed
|
|
42
|
+
if (!fs.existsSync(path.join(cwd, 'package.json')) && !fs.existsSync(path.join(cwd, 'ai-specs'))) {
|
|
43
|
+
console.error('Error: No package.json or ai-specs/ found in current directory.');
|
|
44
44
|
console.error('The --doctor flag must be run from inside an existing project.');
|
|
45
45
|
process.exit(1);
|
|
46
46
|
}
|
|
@@ -142,13 +142,6 @@ async function runUpgrade() {
|
|
|
142
142
|
|
|
143
143
|
const cwd = process.cwd();
|
|
144
144
|
|
|
145
|
-
// Validate: must be in an existing project
|
|
146
|
-
if (!fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
147
|
-
console.error('Error: No package.json found in current directory.');
|
|
148
|
-
console.error('The --upgrade flag must be run from inside an existing project.');
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
145
|
// Validate: SDD must be installed
|
|
153
146
|
if (!fs.existsSync(path.join(cwd, 'ai-specs'))) {
|
|
154
147
|
console.error('Error: ai-specs/ directory not found.');
|
|
@@ -234,13 +227,6 @@ async function runEject() {
|
|
|
234
227
|
|
|
235
228
|
const cwd = process.cwd();
|
|
236
229
|
|
|
237
|
-
// Validate: must be in an existing project
|
|
238
|
-
if (!fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
239
|
-
console.error('Error: No package.json found in current directory.');
|
|
240
|
-
console.error('The --eject flag must be run from inside an existing project.');
|
|
241
|
-
process.exit(1);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
230
|
// Validate: SDD must be installed
|
|
245
231
|
if (!fs.existsSync(path.join(cwd, 'ai-specs'))) {
|
|
246
232
|
console.error('Error: ai-specs/ directory not found.');
|
|
@@ -292,11 +278,6 @@ async function runDiff() {
|
|
|
292
278
|
|
|
293
279
|
const cwd = process.cwd();
|
|
294
280
|
|
|
295
|
-
if (!fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
296
|
-
console.error('Error: No package.json found in current directory.');
|
|
297
|
-
process.exit(1);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
281
|
if (isEject) {
|
|
301
282
|
// Same validation as --eject
|
|
302
283
|
if (!fs.existsSync(path.join(cwd, 'ai-specs'))) {
|
|
@@ -319,6 +300,11 @@ async function runDiff() {
|
|
|
319
300
|
|
|
320
301
|
if (isInit) {
|
|
321
302
|
// Same validation as --init
|
|
303
|
+
if (!fs.existsSync(path.join(cwd, 'package.json'))) {
|
|
304
|
+
console.error('Error: No package.json found in current directory.');
|
|
305
|
+
console.error('The --init flag must be run from inside an existing project.');
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
322
308
|
if (fs.existsSync(path.join(cwd, 'ai-specs'))) {
|
|
323
309
|
console.error('Error: ai-specs/ directory already exists.');
|
|
324
310
|
console.error('SDD DevFlow appears to already be installed. Use --upgrade --diff instead.');
|
package/lib/generator.js
CHANGED
|
@@ -19,6 +19,16 @@ function generate(config) {
|
|
|
19
19
|
step('Copying template files');
|
|
20
20
|
fs.cpSync(templateDir, dest, { recursive: true });
|
|
21
21
|
|
|
22
|
+
// 1b. Rename gitignore → .gitignore (npm strips .gitignore during publish)
|
|
23
|
+
const gitignoreSrc = path.join(dest, 'gitignore');
|
|
24
|
+
if (fs.existsSync(gitignoreSrc)) {
|
|
25
|
+
fs.renameSync(gitignoreSrc, path.join(dest, '.gitignore'));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 1c. Generate package.json
|
|
29
|
+
step('Generating package.json');
|
|
30
|
+
generatePackageJson(dest, config);
|
|
31
|
+
|
|
22
32
|
// 2. Configure key_facts.md
|
|
23
33
|
step(`Configuring project: ${config.projectName}`);
|
|
24
34
|
updateKeyFacts(dest, config);
|
|
@@ -396,4 +406,23 @@ function adaptCiWorkflow(dest, config) {
|
|
|
396
406
|
// Default (PostgreSQL) — template already has correct services
|
|
397
407
|
}
|
|
398
408
|
|
|
409
|
+
function generatePackageJson(dest, config) {
|
|
410
|
+
const pkg = {
|
|
411
|
+
name: config.projectName,
|
|
412
|
+
version: '0.0.1',
|
|
413
|
+
private: true,
|
|
414
|
+
};
|
|
415
|
+
if (config.description) {
|
|
416
|
+
pkg.description = config.description;
|
|
417
|
+
}
|
|
418
|
+
pkg.scripts = {
|
|
419
|
+
test: 'echo "Error: no test specified" && exit 1',
|
|
420
|
+
};
|
|
421
|
+
fs.writeFileSync(
|
|
422
|
+
path.join(dest, 'package.json'),
|
|
423
|
+
JSON.stringify(pkg, null, 2) + '\n',
|
|
424
|
+
'utf8'
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
399
428
|
module.exports = { generate };
|
package/lib/upgrade-generator.js
CHANGED
|
@@ -467,6 +467,33 @@ function generateUpgrade(config) {
|
|
|
467
467
|
|
|
468
468
|
step('Adapted files for project type and stack');
|
|
469
469
|
|
|
470
|
+
// --- g2) Create package.json if missing (projects created with v0.8.0 bug) ---
|
|
471
|
+
const pkgJsonPath = path.join(dest, 'package.json');
|
|
472
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
473
|
+
const pkg = {
|
|
474
|
+
name: config.projectName,
|
|
475
|
+
version: '0.0.1',
|
|
476
|
+
private: true,
|
|
477
|
+
scripts: {
|
|
478
|
+
test: 'echo "Error: no test specified" && exit 1',
|
|
479
|
+
},
|
|
480
|
+
};
|
|
481
|
+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
482
|
+
step('Created missing package.json');
|
|
483
|
+
replaced++;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// --- g3) Create .gitignore if missing (projects created with v0.8.0 bug) ---
|
|
487
|
+
const gitignorePath = path.join(dest, '.gitignore');
|
|
488
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
489
|
+
const gitignoreSrc = path.join(templateDir, 'gitignore');
|
|
490
|
+
if (fs.existsSync(gitignoreSrc)) {
|
|
491
|
+
fs.copyFileSync(gitignoreSrc, gitignorePath);
|
|
492
|
+
}
|
|
493
|
+
step('Created missing .gitignore');
|
|
494
|
+
replaced++;
|
|
495
|
+
}
|
|
496
|
+
|
|
470
497
|
// --- g) Write version marker ---
|
|
471
498
|
const newVersion = getPackageVersion();
|
|
472
499
|
fs.writeFileSync(path.join(dest, '.sdd-version'), newVersion + '\n', 'utf8');
|
package/package.json
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(npm test:*)",
|
|
5
|
+
"Bash(npm run lint:*)",
|
|
6
|
+
"Bash(npm run build:*)",
|
|
7
|
+
"Bash(git status:*)",
|
|
8
|
+
"Bash(git diff:*)",
|
|
9
|
+
"Bash(git log:*)",
|
|
10
|
+
"Bash(git branch:*)",
|
|
11
|
+
"Bash(git checkout -b:*)",
|
|
12
|
+
"Bash(git add:*)",
|
|
13
|
+
"Bash(git commit:*)",
|
|
14
|
+
"Bash(git push:*)",
|
|
15
|
+
"Bash(npx prisma:*)",
|
|
16
|
+
"Read",
|
|
17
|
+
"Glob",
|
|
18
|
+
"Grep"
|
|
19
|
+
],
|
|
20
|
+
"deny": []
|
|
21
|
+
},
|
|
22
|
+
"hooks": {
|
|
23
|
+
"Notification": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": "permission_prompt",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "osascript -e 'display notification \"Permission needed\" with title \"Claude Code\" with subtitle \"Waiting for approval\"'"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"matcher": "idle_prompt",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "osascript -e 'display notification \"Task finished, waiting for input\" with title \"Claude Code\"'"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"Stop": [
|
|
44
|
+
{
|
|
45
|
+
"matcher": "",
|
|
46
|
+
"hooks": [
|
|
47
|
+
{
|
|
48
|
+
"type": "command",
|
|
49
|
+
"command": "osascript -e 'display notification \"Response complete\" with title \"Claude Code\"'"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
|
|
4
|
+
# Build output
|
|
5
|
+
dist/
|
|
6
|
+
.next/
|
|
7
|
+
out/
|
|
8
|
+
build/
|
|
9
|
+
|
|
10
|
+
# Environment — NEVER commit
|
|
11
|
+
.env
|
|
12
|
+
.env.local
|
|
13
|
+
.env.*.local
|
|
14
|
+
.env.development
|
|
15
|
+
.env.staging
|
|
16
|
+
.env.production
|
|
17
|
+
.npmrc
|
|
18
|
+
|
|
19
|
+
# OS
|
|
20
|
+
.DS_Store
|
|
21
|
+
Thumbs.db
|
|
22
|
+
|
|
23
|
+
# IDE
|
|
24
|
+
.idea/
|
|
25
|
+
.vscode/
|
|
26
|
+
*.swp
|
|
27
|
+
*.swo
|
|
28
|
+
|
|
29
|
+
# Testing
|
|
30
|
+
coverage/
|
|
31
|
+
|
|
32
|
+
# Prisma
|
|
33
|
+
backend/generated/
|
|
34
|
+
|
|
35
|
+
# Logs
|
|
36
|
+
*.log
|
|
37
|
+
npm-debug.log*
|
|
38
|
+
|
|
39
|
+
# Cache
|
|
40
|
+
.turbo/
|
|
41
|
+
.cache/
|
|
42
|
+
|
|
43
|
+
# Secrets and keys
|
|
44
|
+
*.pem
|
|
45
|
+
*.key
|
|
46
|
+
|
|
47
|
+
# Claude Code (local settings are personal — hooks, permissions, notifications)
|
|
48
|
+
.claude/settings.local.json
|