@ghl-ai/aw 0.1.35-beta.11 → 0.1.35-beta.12
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/commands/nuke.mjs +13 -8
- package/ecc.mjs +45 -3
- package/package.json +1 -1
package/commands/nuke.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import { execSync } from 'node:child_process';
|
|
|
9
9
|
import * as fmt from '../fmt.mjs';
|
|
10
10
|
import { chalk } from '../fmt.mjs';
|
|
11
11
|
import { removeGlobalHooks } from '../hooks.mjs';
|
|
12
|
+
import { uninstallAwEcc } from '../ecc.mjs';
|
|
12
13
|
|
|
13
14
|
const HOME = homedir();
|
|
14
15
|
const GLOBAL_AW_DIR = join(HOME, '.aw_registry');
|
|
@@ -243,28 +244,31 @@ export function nukeCommand(args) {
|
|
|
243
244
|
// 2. Remove IDE symlinks (only those pointing to .aw_registry)
|
|
244
245
|
removeIdeSymlinks();
|
|
245
246
|
|
|
246
|
-
// 3. Remove
|
|
247
|
+
// 3. Remove aw-ecc installed files (agents, commands, rules, skills, hooks)
|
|
248
|
+
uninstallAwEcc();
|
|
249
|
+
|
|
250
|
+
// 4. Remove .aw_registry symlinks from ALL project directories
|
|
247
251
|
removeProjectSymlinks();
|
|
248
252
|
|
|
249
|
-
//
|
|
253
|
+
// 5. Remove git hooks (core.hooksPath + legacy template)
|
|
250
254
|
removeGitHooks(manifest);
|
|
251
255
|
|
|
252
|
-
//
|
|
256
|
+
// 6. Remove IDE auto-init tasks
|
|
253
257
|
removeIdeTasks();
|
|
254
258
|
|
|
255
|
-
//
|
|
259
|
+
// Remove upgrade lock/log (inside .aw_registry, must happen before dir removal)
|
|
256
260
|
for (const p of [join(GLOBAL_AW_DIR, '.aw-upgrade.lock'), join(GLOBAL_AW_DIR, '.aw-upgrade.log')]) {
|
|
257
261
|
try { if (existsSync(p)) rmSync(p, { recursive: true, force: true }); } catch { /* best effort */ }
|
|
258
262
|
}
|
|
259
263
|
|
|
260
|
-
//
|
|
264
|
+
// 7. Remove ~/.aw_docs/
|
|
261
265
|
const awDocs = join(HOME, '.aw_docs');
|
|
262
266
|
if (existsSync(awDocs)) {
|
|
263
267
|
rmSync(awDocs, { recursive: true, force: true });
|
|
264
268
|
fmt.logStep('Removed ~/.aw_docs/');
|
|
265
269
|
}
|
|
266
270
|
|
|
267
|
-
//
|
|
271
|
+
// 8. Remove any manual `aw` symlinks (e.g. ~/.local/bin/aw)
|
|
268
272
|
const manualBins = [
|
|
269
273
|
join(HOME, '.local', 'bin', 'aw'),
|
|
270
274
|
join(HOME, 'bin', 'aw'),
|
|
@@ -278,7 +282,7 @@ export function nukeCommand(args) {
|
|
|
278
282
|
} catch { /* doesn't exist */ }
|
|
279
283
|
}
|
|
280
284
|
|
|
281
|
-
//
|
|
285
|
+
// 9. Uninstall npm global package (skip if already in npm uninstall lifecycle)
|
|
282
286
|
if (!process.env.npm_lifecycle_event) {
|
|
283
287
|
try {
|
|
284
288
|
execSync('npm uninstall -g @ghl-ai/aw', { stdio: 'pipe', timeout: 15000 });
|
|
@@ -286,7 +290,7 @@ export function nukeCommand(args) {
|
|
|
286
290
|
} catch { /* not installed via npm or no permissions */ }
|
|
287
291
|
}
|
|
288
292
|
|
|
289
|
-
//
|
|
293
|
+
// 10. Remove ~/.aw_registry/ itself (source of truth — last!)
|
|
290
294
|
rmSync(GLOBAL_AW_DIR, { recursive: true, force: true });
|
|
291
295
|
fmt.logStep('Removed ~/.aw_registry/');
|
|
292
296
|
|
|
@@ -295,6 +299,7 @@ export function nukeCommand(args) {
|
|
|
295
299
|
'',
|
|
296
300
|
` ${chalk.green('✓')} Generated files cleaned`,
|
|
297
301
|
` ${chalk.green('✓')} IDE symlinks cleaned`,
|
|
302
|
+
` ${chalk.green('✓')} aw-ecc engine removed`,
|
|
298
303
|
` ${chalk.green('✓')} Project symlinks cleaned`,
|
|
299
304
|
` ${chalk.green('✓')} Git hooks removed`,
|
|
300
305
|
` ${chalk.green('✓')} IDE auto-sync tasks removed`,
|
package/ecc.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
|
-
import { existsSync, rmSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
4
5
|
import * as fmt from "./fmt.mjs";
|
|
5
6
|
|
|
6
7
|
const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
|
|
7
8
|
const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
|
|
8
9
|
const AW_ECC_TAG = "v1.0.0";
|
|
9
10
|
const TMP_DIR = "/tmp/aw-ecc";
|
|
11
|
+
const STATE_FILE = "ecc-install-state.json";
|
|
10
12
|
|
|
11
13
|
function run(cmd, opts = {}) {
|
|
12
14
|
return execSync(cmd, { stdio: "pipe", ...opts });
|
|
@@ -39,7 +41,7 @@ export async function installAwEcc(
|
|
|
39
41
|
{ cwd },
|
|
40
42
|
);
|
|
41
43
|
} catch {
|
|
42
|
-
// Target not supported on this system
|
|
44
|
+
// Target not supported on this system — skip silently
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -50,3 +52,43 @@ export async function installAwEcc(
|
|
|
50
52
|
if (existsSync(TMP_DIR)) rmSync(TMP_DIR, { recursive: true, force: true });
|
|
51
53
|
}
|
|
52
54
|
}
|
|
55
|
+
|
|
56
|
+
export function uninstallAwEcc({ silent = false } = {}) {
|
|
57
|
+
const HOME = homedir();
|
|
58
|
+
const ideDirs = [".cursor", ".claude", ".codex"].map((d) => join(HOME, d));
|
|
59
|
+
let removed = 0;
|
|
60
|
+
|
|
61
|
+
for (const ideDir of ideDirs) {
|
|
62
|
+
const statePath = join(ideDir, STATE_FILE);
|
|
63
|
+
if (!existsSync(statePath)) continue;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
const state = JSON.parse(readFileSync(statePath, "utf8"));
|
|
67
|
+
for (const op of state.operations || []) {
|
|
68
|
+
if (op.destinationPath && existsSync(op.destinationPath)) {
|
|
69
|
+
rmSync(op.destinationPath, { recursive: true, force: true });
|
|
70
|
+
removed++;
|
|
71
|
+
pruneEmptyParents(op.destinationPath, ideDir);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
rmSync(statePath, { force: true });
|
|
75
|
+
} catch { /* corrupted state — skip */ }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!silent && removed > 0) fmt.logStep(`Removed ${removed} aw-ecc file${removed > 1 ? "s" : ""}`);
|
|
79
|
+
return removed;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function pruneEmptyParents(filePath, stopAt) {
|
|
83
|
+
let dir = dirname(filePath);
|
|
84
|
+
while (dir !== stopAt && dir.startsWith(stopAt)) {
|
|
85
|
+
try {
|
|
86
|
+
if (readdirSync(dir).length === 0) {
|
|
87
|
+
rmSync(dir);
|
|
88
|
+
dir = dirname(dir);
|
|
89
|
+
} else {
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
} catch { break; }
|
|
93
|
+
}
|
|
94
|
+
}
|