elliot-stack 1.0.20 → 1.0.22
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/install.cjs +71 -7
- package/package.json +1 -1
package/bin/install.cjs
CHANGED
|
@@ -11,13 +11,74 @@ const readline = require('readline');
|
|
|
11
11
|
const HOME = os.homedir();
|
|
12
12
|
const CLAUDE_DIR = path.join(HOME, '.claude');
|
|
13
13
|
const SKILLS_DIR = path.join(CLAUDE_DIR, 'skills');
|
|
14
|
-
const BACKUP_DIR = path.join(
|
|
14
|
+
const BACKUP_DIR = path.join(HOME, '.estack-backup');
|
|
15
15
|
const CHECKSUMS_FILE = path.join(CLAUDE_DIR, '.estack-checksums.json');
|
|
16
16
|
const SETTINGS_FILE = path.join(CLAUDE_DIR, 'settings.json');
|
|
17
17
|
const PACKAGE_SKILLS_DIR = path.join(__dirname, '..', 'skills');
|
|
18
18
|
const HOOKS_DIR = path.join(CLAUDE_DIR, 'hooks');
|
|
19
19
|
const PACKAGE_HOOKS_DIR = path.join(__dirname, '..', 'hooks');
|
|
20
20
|
|
|
21
|
+
// ── Migrate backup dir from old location (inside .claude) to user root ──────
|
|
22
|
+
(function migrateBackupDir() {
|
|
23
|
+
const OLD_BACKUP_DIR = path.join(CLAUDE_DIR, '.estack-backup');
|
|
24
|
+
if (!fs.existsSync(OLD_BACKUP_DIR)) return;
|
|
25
|
+
if (fs.existsSync(BACKUP_DIR)) return; // new location already exists, leave both alone
|
|
26
|
+
const silent = process.argv.includes('--silent');
|
|
27
|
+
const isDryRun = process.argv.includes('--dry-run') ||
|
|
28
|
+
(!__dirname.includes('node_modules') && !process.argv.includes('--install'));
|
|
29
|
+
if (isDryRun) {
|
|
30
|
+
if (!silent) {
|
|
31
|
+
process.stderr.write(
|
|
32
|
+
'estack: [dry run] Would move backup dir from ~/.claude/.estack-backup/ to ~/.estack-backup/\n'
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
fs.renameSync(OLD_BACKUP_DIR, BACKUP_DIR);
|
|
39
|
+
if (!silent) {
|
|
40
|
+
process.stderr.write(
|
|
41
|
+
'estack: moved backup dir from ~/.claude/.estack-backup/ to ~/.estack-backup/\n'
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
} catch (e) {
|
|
45
|
+
// rename across drives/filesystems — fall back to copy+delete
|
|
46
|
+
try {
|
|
47
|
+
copyDirRaw(OLD_BACKUP_DIR, BACKUP_DIR);
|
|
48
|
+
removeDirRaw(OLD_BACKUP_DIR);
|
|
49
|
+
if (!silent) {
|
|
50
|
+
process.stderr.write(
|
|
51
|
+
'estack: migrated backup dir from ~/.claude/.estack-backup/ to ~/.estack-backup/\n'
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
} catch (e2) {
|
|
55
|
+
process.stderr.write(
|
|
56
|
+
'estack: WARNING — could not migrate backup dir from ' + OLD_BACKUP_DIR +
|
|
57
|
+
' to ' + BACKUP_DIR + ': ' + e2.message + '\n'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
|
|
63
|
+
function copyDirRaw(src, dest) {
|
|
64
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
65
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
66
|
+
const s = path.join(src, entry.name);
|
|
67
|
+
const d = path.join(dest, entry.name);
|
|
68
|
+
if (entry.isDirectory()) copyDirRaw(s, d);
|
|
69
|
+
else fs.copyFileSync(s, d);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function removeDirRaw(dir) {
|
|
74
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
75
|
+
const full = path.join(dir, entry.name);
|
|
76
|
+
if (entry.isDirectory()) removeDirRaw(full);
|
|
77
|
+
else fs.unlinkSync(full);
|
|
78
|
+
}
|
|
79
|
+
fs.rmdirSync(dir);
|
|
80
|
+
}
|
|
81
|
+
|
|
21
82
|
// ── Flags ──────────────────────────────────────────────────────────────────
|
|
22
83
|
const SILENT = process.argv.includes('--silent');
|
|
23
84
|
const STARTUP = process.argv.includes('--startup');
|
|
@@ -37,6 +98,9 @@ const DEPRECATED_SKILLS = [
|
|
|
37
98
|
|
|
38
99
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
39
100
|
|
|
101
|
+
const HASH_IGNORE_DIRS = new Set(['__pycache__', '.git', 'node_modules']);
|
|
102
|
+
const HASH_IGNORE_EXTS = new Set(['.pyc', '.pyo']);
|
|
103
|
+
|
|
40
104
|
function walkDir(dir, base) {
|
|
41
105
|
base = base || dir;
|
|
42
106
|
const entries = fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) =>
|
|
@@ -46,8 +110,8 @@ function walkDir(dir, base) {
|
|
|
46
110
|
for (const entry of entries) {
|
|
47
111
|
const full = path.join(dir, entry.name);
|
|
48
112
|
if (entry.isDirectory()) {
|
|
49
|
-
files.push(...walkDir(full, base));
|
|
50
|
-
} else {
|
|
113
|
+
if (!HASH_IGNORE_DIRS.has(entry.name)) files.push(...walkDir(full, base));
|
|
114
|
+
} else if (!HASH_IGNORE_EXTS.has(path.extname(entry.name))) {
|
|
51
115
|
files.push(path.relative(base, full));
|
|
52
116
|
}
|
|
53
117
|
}
|
|
@@ -560,7 +624,7 @@ async function main() {
|
|
|
560
624
|
if (modifiedAction === 'merge') {
|
|
561
625
|
if (!DRY_RUN) backupSkill(name);
|
|
562
626
|
mergedSkills.push(name);
|
|
563
|
-
console.log((DRY_RUN ? ' [dry run] Would back up ' : ' Backed up ') + name + ' → ~/.
|
|
627
|
+
console.log((DRY_RUN ? ' [dry run] Would back up ' : ' Backed up ') + name + ' → ~/.estack-backup/' + name);
|
|
564
628
|
}
|
|
565
629
|
// overwrite or merge — fall through to install
|
|
566
630
|
} else if (!needsUpdate.includes(name) && fs.existsSync(path.join(SKILLS_DIR, name))) {
|
|
@@ -595,7 +659,7 @@ async function main() {
|
|
|
595
659
|
if (modifiedAction === 'merge') {
|
|
596
660
|
if (!DRY_RUN) backupHook(filename);
|
|
597
661
|
mergedHooks.push(filename);
|
|
598
|
-
console.log((DRY_RUN ? ' [dry run] Would back up hook ' : ' Backed up hook ') + filename + ' → ~/.
|
|
662
|
+
console.log((DRY_RUN ? ' [dry run] Would back up hook ' : ' Backed up hook ') + filename + ' → ~/.estack-backup/hooks/' + filename);
|
|
599
663
|
}
|
|
600
664
|
// overwrite or merge — fall through to install
|
|
601
665
|
} else if (!hooksNeedingUpdate.includes(filename) && fs.existsSync(path.join(HOOKS_DIR, filename))) {
|
|
@@ -647,12 +711,12 @@ async function main() {
|
|
|
647
711
|
if (mergedSkills.length > 0) {
|
|
648
712
|
console.log('\nLocal changes backed up for: ' + mergedSkills.join(', '));
|
|
649
713
|
console.log('Ask Claude to merge your changes:');
|
|
650
|
-
console.log(' "Merge my estack changes from ~/.
|
|
714
|
+
console.log(' "Merge my estack changes from ~/.estack-backup/"');
|
|
651
715
|
}
|
|
652
716
|
|
|
653
717
|
if (mergedHooks.length > 0) {
|
|
654
718
|
console.log('\nLocal hook changes backed up for: ' + mergedHooks.join(', '));
|
|
655
|
-
console.log('Backed up to ~/.
|
|
719
|
+
console.log('Backed up to ~/.estack-backup/hooks/');
|
|
656
720
|
}
|
|
657
721
|
|
|
658
722
|
if (DRY_RUN) {
|