@scheduler-systems/gal 0.1.1-beta
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/LICENSE +14 -0
- package/README.md +100 -0
- package/dist/index.cjs +2 -0
- package/package.json +103 -0
- package/scripts/postinstall.cjs +694 -0
- package/scripts/preuninstall.cjs +149 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* GAL CLI Preuninstall Script
|
|
4
|
+
* Automatically cleans up GAL files when the CLI is uninstalled via npm
|
|
5
|
+
* This runs before the package is removed
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Remove GAL hook entries from settings.json without deleting the file
|
|
14
|
+
*/
|
|
15
|
+
function removeGalHookEntries(settingsPath) {
|
|
16
|
+
try {
|
|
17
|
+
if (!fs.existsSync(settingsPath)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
22
|
+
|
|
23
|
+
if (!settings.hooks?.UserPromptSubmit) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Filter out GAL hooks
|
|
28
|
+
const originalLength = settings.hooks.UserPromptSubmit.length;
|
|
29
|
+
settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit.filter((entry) => {
|
|
30
|
+
if (!entry.hooks) return true;
|
|
31
|
+
// Keep entry only if it has non-GAL hooks
|
|
32
|
+
entry.hooks = entry.hooks.filter((hook) =>
|
|
33
|
+
!hook.command?.includes('gal-') && !hook.command?.includes('/gal/')
|
|
34
|
+
);
|
|
35
|
+
return entry.hooks.length > 0;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Remove empty hooks array
|
|
39
|
+
if (settings.hooks.UserPromptSubmit.length === 0) {
|
|
40
|
+
delete settings.hooks.UserPromptSubmit;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Remove empty hooks object
|
|
44
|
+
if (Object.keys(settings.hooks).length === 0) {
|
|
45
|
+
delete settings.hooks;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (settings.hooks?.UserPromptSubmit?.length !== originalLength) {
|
|
49
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return false;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Clean up GAL-installed files from user's home directory
|
|
61
|
+
*/
|
|
62
|
+
function cleanupUserLevel() {
|
|
63
|
+
const claudeDir = path.join(os.homedir(), '.claude');
|
|
64
|
+
const hooksDir = path.join(claudeDir, 'hooks');
|
|
65
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
66
|
+
|
|
67
|
+
let removed = [];
|
|
68
|
+
|
|
69
|
+
// Remove GAL hook files
|
|
70
|
+
if (fs.existsSync(hooksDir)) {
|
|
71
|
+
try {
|
|
72
|
+
const files = fs.readdirSync(hooksDir);
|
|
73
|
+
for (const file of files) {
|
|
74
|
+
if (file.startsWith('gal-')) {
|
|
75
|
+
const hookPath = path.join(hooksDir, file);
|
|
76
|
+
try {
|
|
77
|
+
fs.unlinkSync(hookPath);
|
|
78
|
+
removed.push(hookPath);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
// Silent fail
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
// Silent fail
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Remove GAL hook entries from settings.json
|
|
90
|
+
if (removeGalHookEntries(settingsPath)) {
|
|
91
|
+
removed.push(`${settingsPath} (GAL hooks removed)`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return removed;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Clean up GAL config from user's home directory
|
|
99
|
+
*/
|
|
100
|
+
function cleanupGalConfig() {
|
|
101
|
+
const galConfigDir = path.join(os.homedir(), '.gal');
|
|
102
|
+
|
|
103
|
+
if (fs.existsSync(galConfigDir)) {
|
|
104
|
+
try {
|
|
105
|
+
fs.rmSync(galConfigDir, { recursive: true, force: true });
|
|
106
|
+
return [galConfigDir];
|
|
107
|
+
} catch (err) {
|
|
108
|
+
// Silent fail
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Main cleanup function
|
|
118
|
+
*/
|
|
119
|
+
function cleanup() {
|
|
120
|
+
console.log('\n═══════════════════════════════════════════════════');
|
|
121
|
+
console.log(' GAL CLI Uninstall Cleanup');
|
|
122
|
+
console.log('═══════════════════════════════════════════════════\n');
|
|
123
|
+
|
|
124
|
+
const userLevelFiles = cleanupUserLevel();
|
|
125
|
+
const galConfigFiles = cleanupGalConfig();
|
|
126
|
+
const allRemoved = [...userLevelFiles, ...galConfigFiles];
|
|
127
|
+
|
|
128
|
+
if (allRemoved.length > 0) {
|
|
129
|
+
console.log('✓ Cleaned up GAL files:');
|
|
130
|
+
for (const file of allRemoved) {
|
|
131
|
+
console.log(` - ${file}`);
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
console.log('No GAL files found to clean up.');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
console.log('\n═══════════════════════════════════════════════════');
|
|
138
|
+
console.log(' GAL CLI has been uninstalled');
|
|
139
|
+
console.log('═══════════════════════════════════════════════════\n');
|
|
140
|
+
console.log('To reinstall: npm install -g @scheduler-systems/gal-cli\n');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Run cleanup
|
|
144
|
+
try {
|
|
145
|
+
cleanup();
|
|
146
|
+
} catch (error) {
|
|
147
|
+
// Silent fail - don't prevent uninstall
|
|
148
|
+
console.error('GAL cleanup encountered an error, but uninstall will proceed.');
|
|
149
|
+
}
|