refacil-sdd-ai 5.2.2 → 5.2.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/bin/cli.js +33 -0
- package/bin/postinstall.js +20 -0
- package/lib/hooks.js +6 -0
- package/lib/installer.js +7 -0
- package/package.json +2 -1
package/bin/cli.js
CHANGED
|
@@ -382,6 +382,39 @@ function checkUpdate() {
|
|
|
382
382
|
|
|
383
383
|
cleanLegacySettingsHooks(projectRoot);
|
|
384
384
|
|
|
385
|
+
// Self-healing: if selected-ides.json exists but global skills/hooks are missing, restore them
|
|
386
|
+
// Covers the case where the Claude Code desktop app overwrites settings.json and wipes SDD hooks,
|
|
387
|
+
// or where skills were deleted by any means while the package is still installed.
|
|
388
|
+
try {
|
|
389
|
+
const home = os.homedir();
|
|
390
|
+
const sddSelectedIDEs = readSelectedIDEs(home);
|
|
391
|
+
if (sddSelectedIDEs && sddSelectedIDEs.length > 0) {
|
|
392
|
+
const dirMap = {
|
|
393
|
+
'.claude': globalClaudeDir(home),
|
|
394
|
+
'.cursor': globalCursorDir(home),
|
|
395
|
+
'.opencode': globalOpenCodeDir(home),
|
|
396
|
+
'.codex': globalCodexDir(home),
|
|
397
|
+
};
|
|
398
|
+
const missingSkills = sddSelectedIDEs.some(
|
|
399
|
+
(ide) => dirMap[ide] && !fs.existsSync(path.join(dirMap[ide], 'skills')),
|
|
400
|
+
);
|
|
401
|
+
if (missingSkills) {
|
|
402
|
+
installSkills(packageRoot, home, sddSelectedIDEs);
|
|
403
|
+
installAgents(packageRoot, home, sddSelectedIDEs);
|
|
404
|
+
writeGlobalVersion(getPackageVersion(packageRoot));
|
|
405
|
+
process.stdout.write('[refacil-sdd-ai] Self-healed: global skills and agents restored.\n');
|
|
406
|
+
}
|
|
407
|
+
// Always verify hooks are present for all selected IDEs — idempotent, only writes if missing
|
|
408
|
+
for (const ide of ['.claude', '.cursor', '.opencode', '.codex']) {
|
|
409
|
+
if (sddSelectedIDEs.includes(ide)) {
|
|
410
|
+
installHooks(ide, home, projectRoot);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
} catch (_) {
|
|
415
|
+
// Tolerant — self-healing must never break session startup
|
|
416
|
+
}
|
|
417
|
+
|
|
385
418
|
// Step 1: update the global package if a newer version is available on npm
|
|
386
419
|
try {
|
|
387
420
|
const latest = execSync('npm view refacil-sdd-ai version', {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
// Only auto-reinstall if a previous `init` was done — indicated by selected-ides.json
|
|
9
|
+
const selPath = path.join(os.homedir(), '.refacil-sdd-ai', 'selected-ides.json');
|
|
10
|
+
if (!fs.existsSync(selPath)) process.exit(0);
|
|
11
|
+
|
|
12
|
+
const { execFileSync } = require('child_process');
|
|
13
|
+
try {
|
|
14
|
+
execFileSync(process.execPath, [path.join(__dirname, 'cli.js'), 'update'], {
|
|
15
|
+
stdio: 'inherit',
|
|
16
|
+
timeout: 120000,
|
|
17
|
+
});
|
|
18
|
+
} catch (_) {
|
|
19
|
+
// Non-fatal: postinstall must never break npm install
|
|
20
|
+
}
|
package/lib/hooks.js
CHANGED
|
@@ -326,6 +326,12 @@ function uninstallOpenCodePlugin(homeDir) {
|
|
|
326
326
|
* @param {string} projectRoot
|
|
327
327
|
*/
|
|
328
328
|
function removeProjectLevelHooks(projectRoot) {
|
|
329
|
+
// Safety guard: never strip hooks from the global ~/.claude/settings.json.
|
|
330
|
+
// If projectRoot is the home directory (findProjectRoot() fallback), skip entirely.
|
|
331
|
+
const resolvedRoot = require('path').resolve(projectRoot);
|
|
332
|
+
const resolvedHome = require('path').resolve(require('os').homedir());
|
|
333
|
+
if (resolvedRoot === resolvedHome) return;
|
|
334
|
+
|
|
329
335
|
const sddMarkers = ['_sdd', '_sdd_compact', '_sdd_review', '_sdd_notify'];
|
|
330
336
|
|
|
331
337
|
// .claude/settings.json
|
package/lib/installer.js
CHANGED
|
@@ -300,6 +300,13 @@ function installAgents(packageRoot, homeDir, ideDirs) {
|
|
|
300
300
|
* @param {string} projectRoot
|
|
301
301
|
*/
|
|
302
302
|
function removeProjectLevelArtifacts(projectRoot) {
|
|
303
|
+
// Safety guard: never remove artifacts from the home directory itself.
|
|
304
|
+
// If projectRoot resolves to home (e.g. findProjectRoot() fallback when cwd is ~),
|
|
305
|
+
// projectRoot/.claude/ would be ~/ .claude/ — i.e. the global installation dirs.
|
|
306
|
+
const resolvedRoot = path.resolve(projectRoot);
|
|
307
|
+
const resolvedHome = path.resolve(os.homedir());
|
|
308
|
+
if (resolvedRoot === resolvedHome) return 0;
|
|
309
|
+
|
|
303
310
|
const ideDirs = ['.claude', '.cursor', '.opencode'];
|
|
304
311
|
const subDirs = ['skills', 'agents'];
|
|
305
312
|
let removed = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "refacil-sdd-ai",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.3",
|
|
4
4
|
"description": "SDD-AI: Specification-Driven Development with AI — development methodology using AI with Claude Code, Cursor, OpenCode and Codex",
|
|
5
5
|
"bin": {
|
|
6
6
|
"refacil-sdd-ai": "./bin/cli.js"
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"node": ">=20.0.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
|
+
"postinstall": "node ./bin/postinstall.js",
|
|
41
42
|
"test": "node --test test/hooks.test.js test/installer.test.js test/ignore-files.test.js test/methodology-migration-pending.test.js test/sdd.test.js test/config.test.js test/refactor-integrar-openspec-nativo.test.js test/refactor-rutas-refacil-sdd.test.js test/refactor-agents-english.test.js test/remove-openspec-legacy.test.js test/find-project-root.test.js test/opencode-installer.test.js test/opencode-plugin.test.js test/toml-converter.test.js test/testing-policy-sync.test.js test/session-repo-sync.test.js"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|