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 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.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": {