refacil-sdd-ai 4.4.0 → 4.5.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/agents/validator.md +1 -1
- package/bin/cli.js +229 -41
- package/lib/commands/sdd.js +233 -16
- package/lib/hooks.js +43 -7
- package/lib/ignore-files.js +2 -1
- package/lib/installer.js +181 -17
- package/lib/opencode-plugin/index.js +262 -0
- package/package.json +7 -3
- package/skills/apply/SKILL.md +9 -10
- package/skills/archive/SKILL.md +15 -23
- package/skills/prereqs/METHODOLOGY-CONTRACT.md +10 -7
- package/skills/propose/SKILL.md +7 -7
- package/skills/review/SKILL.md +28 -7
- package/skills/test/SKILL.md +12 -13
- package/skills/verify/SKILL.md +1 -4
package/agents/validator.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: refacil-validator
|
|
3
|
-
description: Validates implementation against SDD specs (CA/CR) and tests. Delegated by /refacil:verify — do not invoke directly.
|
|
3
|
+
description: Validates implementation against SDD specs (CA/CR) and tests. Delegated by /refacil:verify — do not invoke directly. Never modifies files.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
package/bin/cli.js
CHANGED
|
@@ -12,7 +12,9 @@ const compactBash = require('../lib/compact/bash');
|
|
|
12
12
|
const {
|
|
13
13
|
installSkills,
|
|
14
14
|
installAgents,
|
|
15
|
+
installOpenCodeJson,
|
|
15
16
|
removeSkills,
|
|
17
|
+
removeOpenCodeArtifacts,
|
|
16
18
|
removeOpenspecLegacyAssets,
|
|
17
19
|
createClaudeMd,
|
|
18
20
|
createCursorRules,
|
|
@@ -22,15 +24,15 @@ const {
|
|
|
22
24
|
checkNodeVersion,
|
|
23
25
|
checkClaudeCodeVersion,
|
|
24
26
|
} = require('../lib/installer');
|
|
25
|
-
const { installHooks, uninstallHooks, cleanLegacySettingsHooks } = require('../lib/hooks');
|
|
27
|
+
const { installHooks, uninstallHooks, cleanLegacySettingsHooks, installOpenCodePlugin, uninstallOpenCodePlugin } = require('../lib/hooks');
|
|
26
28
|
const { handleCompact } = require('../lib/commands/compact');
|
|
27
29
|
const { handleBus } = require('../lib/commands/bus');
|
|
28
|
-
const { handleSdd, autoMigrateOpenspec } = require('../lib/commands/sdd');
|
|
30
|
+
const { handleSdd, autoMigrateOpenspec, findProjectRoot } = require('../lib/commands/sdd');
|
|
29
31
|
const { syncIgnoreFiles } = require('../lib/ignore-files');
|
|
30
32
|
const { methodologyMigrationPending } = require('../lib/methodology-migration-pending');
|
|
31
33
|
|
|
32
34
|
const packageRoot = path.resolve(__dirname, '..');
|
|
33
|
-
const projectRoot =
|
|
35
|
+
const projectRoot = findProjectRoot();
|
|
34
36
|
|
|
35
37
|
// --- check-update (SessionStart) + notify-update (UserPromptSubmit) ---
|
|
36
38
|
|
|
@@ -119,10 +121,108 @@ function notifyUpdate() {
|
|
|
119
121
|
function repoIsInitialized() {
|
|
120
122
|
return (
|
|
121
123
|
fs.existsSync(path.join(projectRoot, '.claude', 'skills')) ||
|
|
122
|
-
fs.existsSync(path.join(projectRoot, '.cursor', 'skills'))
|
|
124
|
+
fs.existsSync(path.join(projectRoot, '.cursor', 'skills')) ||
|
|
125
|
+
fs.existsSync(path.join(projectRoot, '.opencode', 'skills'))
|
|
123
126
|
);
|
|
124
127
|
}
|
|
125
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Inline readline-based multi-select for IDE targets.
|
|
131
|
+
* Shows a checklist of available IDEs and returns the selected ones.
|
|
132
|
+
* Falls back to all IDEs if stdin is not a TTY.
|
|
133
|
+
* @param {Array<{label: string, value: string, selected: boolean}>} options
|
|
134
|
+
* @returns {Promise<string[]>} selected values
|
|
135
|
+
*/
|
|
136
|
+
function readlineMultiSelect(options) {
|
|
137
|
+
return new Promise((resolve) => {
|
|
138
|
+
const readline = require('readline');
|
|
139
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
140
|
+
|
|
141
|
+
const selected = options.map((o) => o.selected);
|
|
142
|
+
let renderCount = 0;
|
|
143
|
+
|
|
144
|
+
function render() {
|
|
145
|
+
if (renderCount > 0) {
|
|
146
|
+
process.stdout.write(`\x1B[${options.length + 7}A\x1B[J`);
|
|
147
|
+
}
|
|
148
|
+
renderCount++;
|
|
149
|
+
console.log('\n Select IDEs to install refacil-sdd-ai into:');
|
|
150
|
+
console.log(' (space = toggle, enter = confirm, a = toggle all)\n');
|
|
151
|
+
for (let i = 0; i < options.length; i++) {
|
|
152
|
+
const check = selected[i] ? '[x]' : '[ ]';
|
|
153
|
+
console.log(` ${check} ${options[i].label}`);
|
|
154
|
+
}
|
|
155
|
+
console.log('\n Enter numbers to toggle (e.g. 1,2,3) or "a" for all, then Enter to confirm:');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
render();
|
|
159
|
+
|
|
160
|
+
rl.on('line', (line) => {
|
|
161
|
+
const input = line.trim().toLowerCase();
|
|
162
|
+
if (input === '') {
|
|
163
|
+
rl.close();
|
|
164
|
+
resolve(options.filter((_, i) => selected[i]).map((o) => o.value));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (input === 'a') {
|
|
168
|
+
const anySelected = selected.some(Boolean);
|
|
169
|
+
for (let i = 0; i < selected.length; i++) selected[i] = !anySelected;
|
|
170
|
+
} else {
|
|
171
|
+
const nums = input.split(/[\s,]+/).map(Number).filter((n) => !isNaN(n) && n >= 1 && n <= options.length);
|
|
172
|
+
for (const n of nums) selected[n - 1] = !selected[n - 1];
|
|
173
|
+
}
|
|
174
|
+
render();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
rl.on('close', () => {
|
|
178
|
+
resolve(options.filter((_, i) => selected[i]).map((o) => o.value));
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Show interactive IDE selector if TTY and --all not in args.
|
|
185
|
+
* Pre-selects IDEs by folder presence.
|
|
186
|
+
* Returns selected IDE dirs (e.g. ['.claude', '.cursor', '.opencode']).
|
|
187
|
+
*/
|
|
188
|
+
async function selectIDEs() {
|
|
189
|
+
const allFlag = process.argv.includes('--all');
|
|
190
|
+
const allIDEs = ['.claude', '.cursor', '.opencode'];
|
|
191
|
+
|
|
192
|
+
// --all or non-TTY: install all three
|
|
193
|
+
if (allFlag || !process.stdout.isTTY) {
|
|
194
|
+
return allIDEs;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const options = [
|
|
198
|
+
{ label: 'Claude Code (.claude/)', value: '.claude', selected: fs.existsSync(path.join(projectRoot, '.claude')) },
|
|
199
|
+
{ label: 'Cursor (.cursor/)', value: '.cursor', selected: fs.existsSync(path.join(projectRoot, '.cursor')) },
|
|
200
|
+
{ label: 'OpenCode (.opencode/)', value: '.opencode', selected: fs.existsSync(path.join(projectRoot, '.opencode')) },
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
// Try @clack/prompts first, fall back to inline readline
|
|
204
|
+
let selected;
|
|
205
|
+
try {
|
|
206
|
+
// @clack/prompts is an optional peer dep — try to load it without crashing if absent
|
|
207
|
+
const clack = require('@clack/prompts');
|
|
208
|
+
const result = await clack.multiselect({
|
|
209
|
+
message: 'Select IDEs to install refacil-sdd-ai into:',
|
|
210
|
+
options: options.map((o) => ({ label: o.label, value: o.value, selected: o.selected })),
|
|
211
|
+
required: false,
|
|
212
|
+
});
|
|
213
|
+
if (clack.isCancel(result)) {
|
|
214
|
+
console.log('\n Installation cancelled.\n');
|
|
215
|
+
process.exit(0);
|
|
216
|
+
}
|
|
217
|
+
selected = result;
|
|
218
|
+
} catch (_) {
|
|
219
|
+
// @clack/prompts not available — use inline readline fallback
|
|
220
|
+
selected = await readlineMultiSelect(options);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return selected;
|
|
224
|
+
}
|
|
225
|
+
|
|
126
226
|
function semverGt(a, b) {
|
|
127
227
|
if (!a || !b) return false;
|
|
128
228
|
const pa = a.split('.').map(Number);
|
|
@@ -297,7 +397,7 @@ function checkReview() {
|
|
|
297
397
|
|
|
298
398
|
// --- High-level commands ---
|
|
299
399
|
|
|
300
|
-
function init() {
|
|
400
|
+
async function init() {
|
|
301
401
|
console.log('\n refacil-sdd-ai: Initializing SDD-AI methodology...\n');
|
|
302
402
|
|
|
303
403
|
const nodeOk = checkNodeVersion();
|
|
@@ -313,35 +413,67 @@ function init() {
|
|
|
313
413
|
console.log(' Update with: npm install -g @anthropic-ai/claude-code\n');
|
|
314
414
|
}
|
|
315
415
|
|
|
316
|
-
|
|
317
|
-
|
|
416
|
+
// Select target IDEs (interactive selector or --all / non-TTY)
|
|
417
|
+
const selectedIDEs = await selectIDEs();
|
|
418
|
+
|
|
419
|
+
if (selectedIDEs.length === 0) {
|
|
420
|
+
console.log('\n No IDEs selected. Nothing installed.\n');
|
|
421
|
+
console.log(' Re-run with: refacil-sdd-ai init --all to install for all IDEs');
|
|
422
|
+
process.exit(0);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const installClaude = selectedIDEs.includes('.claude');
|
|
427
|
+
const installCursor = selectedIDEs.includes('.cursor');
|
|
428
|
+
const installOpenCode = selectedIDEs.includes('.opencode');
|
|
318
429
|
|
|
319
|
-
const
|
|
430
|
+
const count = installSkills(packageRoot, projectRoot, selectedIDEs);
|
|
431
|
+
const ideList = selectedIDEs.map((d) => `${d}/skills/`).join(', ');
|
|
432
|
+
console.log(` ${count} skills installed in ${ideList}`);
|
|
433
|
+
|
|
434
|
+
const agentsCount = installAgents(packageRoot, projectRoot, selectedIDEs);
|
|
320
435
|
if (agentsCount > 0) {
|
|
321
|
-
|
|
436
|
+
const agentList = selectedIDEs.map((d) => `${d}/agents/`).join(', ');
|
|
437
|
+
console.log(` ${agentsCount} sub-agents installed in ${agentList}`);
|
|
322
438
|
}
|
|
323
439
|
|
|
324
440
|
writeRepoVersion(projectRoot, getPackageVersion(packageRoot));
|
|
325
441
|
|
|
326
|
-
if (
|
|
327
|
-
|
|
442
|
+
if (installClaude) {
|
|
443
|
+
if (createClaudeMd(packageRoot, projectRoot)) console.log(' CLAUDE.md OK');
|
|
444
|
+
if (installHooks('.claude', projectRoot)) {
|
|
445
|
+
console.log(' Hook check-update added to .claude/settings.json');
|
|
446
|
+
}
|
|
447
|
+
}
|
|
328
448
|
|
|
329
|
-
if (
|
|
330
|
-
console.log('
|
|
449
|
+
if (installCursor) {
|
|
450
|
+
if (createCursorRules(packageRoot, projectRoot)) console.log(' .cursorrules OK');
|
|
451
|
+
if (installHooks('.cursor', projectRoot)) {
|
|
452
|
+
console.log(' Hook check-update added to .cursor/hooks.json');
|
|
453
|
+
}
|
|
331
454
|
}
|
|
332
|
-
|
|
333
|
-
|
|
455
|
+
|
|
456
|
+
if (installOpenCode) {
|
|
457
|
+
try {
|
|
458
|
+
installOpenCodeJson(projectRoot);
|
|
459
|
+
console.log(' .opencode/opencode.json created/updated');
|
|
460
|
+
} catch (err) {
|
|
461
|
+
console.error(` Warning: could not create opencode.json: ${err.message}`);
|
|
462
|
+
}
|
|
463
|
+
if (installHooks('.opencode', projectRoot)) {
|
|
464
|
+
console.log(' OpenCode plugin installed to .opencode/plugins/refacil-hooks.js');
|
|
465
|
+
}
|
|
334
466
|
}
|
|
335
467
|
|
|
336
468
|
try {
|
|
337
469
|
const ignoreResult = syncIgnoreFiles(projectRoot);
|
|
338
470
|
const s = ignoreResult.claude;
|
|
339
471
|
if (s.status === 'created') {
|
|
340
|
-
console.log(' .claudeignore and .
|
|
472
|
+
console.log(' .claudeignore, .cursorignore and .opencodeignore created');
|
|
341
473
|
} else if (s.status === 'updated') {
|
|
342
|
-
console.log(` .claudeignore and .
|
|
474
|
+
console.log(` .claudeignore, .cursorignore and .opencodeignore updated (${s.added} entries added)`);
|
|
343
475
|
} else {
|
|
344
|
-
console.log(' .claudeignore and .
|
|
476
|
+
console.log(' .claudeignore, .cursorignore and .opencodeignore are up to date');
|
|
345
477
|
}
|
|
346
478
|
} catch (err) {
|
|
347
479
|
console.error(` Warning: could not sync ignore files: ${err.message}`);
|
|
@@ -359,7 +491,7 @@ function init() {
|
|
|
359
491
|
}
|
|
360
492
|
|
|
361
493
|
console.log('\n Next steps:\n');
|
|
362
|
-
console.log(' 1. RESTART your
|
|
494
|
+
console.log(' 1. RESTART your IDE session');
|
|
363
495
|
console.log(' (new skills are not detected until the session is restarted)\n');
|
|
364
496
|
console.log(' 2. Run: /refacil:setup');
|
|
365
497
|
console.log(' (generates AGENTS.md for your project)\n');
|
|
@@ -368,12 +500,29 @@ function init() {
|
|
|
368
500
|
function update() {
|
|
369
501
|
console.log('\n refacil-sdd-ai: Updating skills...\n');
|
|
370
502
|
|
|
371
|
-
|
|
372
|
-
|
|
503
|
+
// Detect installed IDEs by folder presence
|
|
504
|
+
const hasClaudeDir = fs.existsSync(path.join(projectRoot, '.claude'));
|
|
505
|
+
const hasCursorDir = fs.existsSync(path.join(projectRoot, '.cursor'));
|
|
506
|
+
const hasOpenCodeDir = fs.existsSync(path.join(projectRoot, '.opencode'));
|
|
507
|
+
|
|
508
|
+
const detectedIDEs = [
|
|
509
|
+
hasClaudeDir && '.claude',
|
|
510
|
+
hasCursorDir && '.cursor',
|
|
511
|
+
hasOpenCodeDir && '.opencode',
|
|
512
|
+
].filter(Boolean);
|
|
513
|
+
|
|
514
|
+
const count = installSkills(packageRoot, projectRoot, detectedIDEs);
|
|
515
|
+
const installedDirs = detectedIDEs.map((d) => `${d}/skills/`);
|
|
516
|
+
console.log(` ${count} skills updated in ${installedDirs.join(', ') || '(none detected)'}`);
|
|
373
517
|
|
|
374
|
-
const agentsCount = installAgents(packageRoot, projectRoot);
|
|
518
|
+
const agentsCount = installAgents(packageRoot, projectRoot, detectedIDEs);
|
|
375
519
|
if (agentsCount > 0) {
|
|
376
|
-
|
|
520
|
+
const agentDirs = [
|
|
521
|
+
hasClaudeDir && '.claude/agents/',
|
|
522
|
+
hasCursorDir && '.cursor/agents/',
|
|
523
|
+
hasOpenCodeDir && '.opencode/agents/',
|
|
524
|
+
].filter(Boolean);
|
|
525
|
+
console.log(` ${agentsCount} sub-agents updated in ${agentDirs.join(', ')}`);
|
|
377
526
|
}
|
|
378
527
|
|
|
379
528
|
try {
|
|
@@ -387,25 +536,40 @@ function update() {
|
|
|
387
536
|
|
|
388
537
|
writeRepoVersion(projectRoot, getPackageVersion(packageRoot));
|
|
389
538
|
|
|
390
|
-
|
|
391
|
-
|
|
539
|
+
if (hasClaudeDir) {
|
|
540
|
+
createClaudeMd(packageRoot, projectRoot);
|
|
541
|
+
if (installHooks('.claude', projectRoot)) {
|
|
542
|
+
console.log(' Hook check-update added to .claude/settings.json');
|
|
543
|
+
}
|
|
544
|
+
}
|
|
392
545
|
|
|
393
|
-
if (
|
|
394
|
-
|
|
546
|
+
if (hasCursorDir) {
|
|
547
|
+
createCursorRules(packageRoot, projectRoot);
|
|
548
|
+
if (installHooks('.cursor', projectRoot)) {
|
|
549
|
+
console.log(' Hook check-update added to .cursor/hooks.json');
|
|
550
|
+
}
|
|
395
551
|
}
|
|
396
|
-
|
|
397
|
-
|
|
552
|
+
|
|
553
|
+
if (hasOpenCodeDir) {
|
|
554
|
+
try {
|
|
555
|
+
installOpenCodeJson(projectRoot);
|
|
556
|
+
} catch (err) {
|
|
557
|
+
console.error(` Warning: could not update opencode.json: ${err.message}`);
|
|
558
|
+
}
|
|
559
|
+
if (installHooks('.opencode', projectRoot)) {
|
|
560
|
+
console.log(' OpenCode plugin updated at .opencode/plugins/refacil-hooks.js');
|
|
561
|
+
}
|
|
398
562
|
}
|
|
399
563
|
|
|
400
564
|
try {
|
|
401
565
|
const ignoreResult = syncIgnoreFiles(projectRoot);
|
|
402
566
|
const s = ignoreResult.claude;
|
|
403
567
|
if (s.status === 'created') {
|
|
404
|
-
console.log(' .claudeignore and .
|
|
568
|
+
console.log(' .claudeignore, .cursorignore and .opencodeignore created');
|
|
405
569
|
} else if (s.status === 'updated') {
|
|
406
|
-
console.log(` .claudeignore and .
|
|
570
|
+
console.log(` .claudeignore, .cursorignore and .opencodeignore updated (${s.added} entries added)`);
|
|
407
571
|
} else {
|
|
408
|
-
console.log(' .claudeignore and .
|
|
572
|
+
console.log(' .claudeignore, .cursorignore and .opencodeignore are up to date');
|
|
409
573
|
}
|
|
410
574
|
} catch (err) {
|
|
411
575
|
console.error(` Warning: could not sync ignore files: ${err.message}`);
|
|
@@ -422,7 +586,7 @@ function update() {
|
|
|
422
586
|
console.error(` Warning: could not sync compact-guidance: ${err.message}`);
|
|
423
587
|
}
|
|
424
588
|
|
|
425
|
-
console.log('\n RESTART your
|
|
589
|
+
console.log('\n RESTART your IDE session to apply the changes.\n');
|
|
426
590
|
}
|
|
427
591
|
|
|
428
592
|
function clean() {
|
|
@@ -440,6 +604,19 @@ function clean() {
|
|
|
440
604
|
console.log(' SDD-AI hooks removed from .cursor/settings.json');
|
|
441
605
|
}
|
|
442
606
|
|
|
607
|
+
// Clean OpenCode artifacts if .opencode/ directory is present
|
|
608
|
+
if (fs.existsSync(path.join(projectRoot, '.opencode'))) {
|
|
609
|
+
try {
|
|
610
|
+
removeOpenCodeArtifacts(projectRoot);
|
|
611
|
+
console.log(' OpenCode skills and agents removed from .opencode/');
|
|
612
|
+
} catch (err) {
|
|
613
|
+
console.error(` Warning: could not remove OpenCode artifacts: ${err.message}`);
|
|
614
|
+
}
|
|
615
|
+
if (uninstallOpenCodePlugin(projectRoot)) {
|
|
616
|
+
console.log(' OpenCode plugin removed from .opencode/plugins/');
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
443
620
|
try {
|
|
444
621
|
const result = removeCompactGuidance(projectRoot);
|
|
445
622
|
if (result.status === 'removed') {
|
|
@@ -460,8 +637,10 @@ function help() {
|
|
|
460
637
|
refacil-sdd-ai — SDD-AI Methodology
|
|
461
638
|
|
|
462
639
|
Commands:
|
|
463
|
-
init Install skills in .claude/ and .
|
|
464
|
-
|
|
640
|
+
init Install skills in .claude/, .cursor/ and/or .opencode/ (interactive IDE selector).
|
|
641
|
+
Use --all to install for all three IDEs without prompting.
|
|
642
|
+
Creates CLAUDE.md, .cursorrules and .opencode/opencode.json as appropriate.
|
|
643
|
+
update Re-copy skills for all detected IDEs (.claude/, .cursor/, .opencode/)
|
|
465
644
|
migration-pending Same validation as hooks/notify-update: list migrations (exit 1 if any; --json)
|
|
466
645
|
check-update Sync skills and compact-guidance at session start (SessionStart hook)
|
|
467
646
|
notify-update Notify methodology migration only if applicable (UserPromptSubmit hook)
|
|
@@ -496,18 +675,24 @@ function help() {
|
|
|
496
675
|
sdd mark-reviewed <name> Write .review-passed (requires --verdict and --summary)
|
|
497
676
|
sdd tasks-update <name> Mark task N as completed (--task N --done)
|
|
498
677
|
sdd validate-name <name> Validate change name format
|
|
499
|
-
clean Remove skills and SDD-AI hooks from
|
|
678
|
+
clean Remove skills and SDD-AI hooks from all detected IDEs
|
|
679
|
+
(.claude/settings.json, .cursor/hooks.json, .opencode/plugins/)
|
|
500
680
|
help Show this help
|
|
501
681
|
|
|
502
682
|
Full flow:
|
|
503
683
|
1. npm install -g refacil-sdd-ai
|
|
504
684
|
2. refacil-sdd-ai init
|
|
505
|
-
3. RESTART
|
|
685
|
+
3. RESTART your IDE session (Claude Code, Cursor, or OpenCode)
|
|
506
686
|
4. Run: /refacil:setup (generates AGENTS.md for your project)
|
|
507
687
|
|
|
688
|
+
IDE support:
|
|
689
|
+
- Claude Code: .claude/skills/, .claude/agents/, .claude/settings.json hooks
|
|
690
|
+
- Cursor: .cursor/skills/, .cursor/agents/, .cursor/hooks.json hooks
|
|
691
|
+
- OpenCode: .opencode/skills/, .opencode/agents/, .opencode/plugins/refacil-hooks.js
|
|
692
|
+
|
|
508
693
|
Requirements:
|
|
509
|
-
- Node.js >= 20.
|
|
510
|
-
- Claude Code >= 2.1.89 (required by compact-bash for silent rewrite) or
|
|
694
|
+
- Node.js >= 20.0.0
|
|
695
|
+
- Claude Code >= 2.1.89 (required by compact-bash for silent rewrite), Cursor, or OpenCode
|
|
511
696
|
`);
|
|
512
697
|
}
|
|
513
698
|
|
|
@@ -522,7 +707,10 @@ if (command === '--version' || command === '-v') {
|
|
|
522
707
|
|
|
523
708
|
switch (command) {
|
|
524
709
|
case 'init':
|
|
525
|
-
init()
|
|
710
|
+
init().catch((err) => {
|
|
711
|
+
console.error(` Error during init: ${err.message}`);
|
|
712
|
+
process.exit(1);
|
|
713
|
+
});
|
|
526
714
|
break;
|
|
527
715
|
case 'update':
|
|
528
716
|
update();
|
|
@@ -549,7 +737,7 @@ switch (command) {
|
|
|
549
737
|
handleBus(process.argv[3], process.argv.slice(4), packageRoot);
|
|
550
738
|
break;
|
|
551
739
|
case 'sdd':
|
|
552
|
-
handleSdd(process.argv[3], process.argv.slice(4));
|
|
740
|
+
handleSdd(process.argv[3], process.argv.slice(4), projectRoot);
|
|
553
741
|
break;
|
|
554
742
|
case 'clean':
|
|
555
743
|
clean();
|