@ghl-ai/aw 0.1.35-beta.17 → 0.1.35-beta.18
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/ecc.mjs +40 -73
- package/package.json +1 -1
package/ecc.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
existsSync, readFileSync, readdirSync, renameSync,
|
|
4
|
+
mkdirSync, rmSync, writeFileSync,
|
|
5
5
|
} from "node:fs";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
import { homedir } from "node:os";
|
|
@@ -9,18 +9,16 @@ import * as fmt from "./fmt.mjs";
|
|
|
9
9
|
|
|
10
10
|
const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
|
|
11
11
|
const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
|
|
12
|
-
const AW_ECC_TAG = "v1.
|
|
12
|
+
const AW_ECC_TAG = "v1.2.0";
|
|
13
13
|
const TMP_DIR = "/tmp/aw-ecc";
|
|
14
14
|
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const PLUGIN_KEY = `${PLUGIN_NAME}@${PLUGIN_NAME}`;
|
|
15
|
+
const MARKETPLACE_NAME = "aw-marketplace";
|
|
16
|
+
const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
|
|
18
17
|
|
|
19
|
-
const FILE_COPY_TARGETS = ["cursor", "
|
|
18
|
+
const FILE_COPY_TARGETS = ["cursor", "codex"];
|
|
20
19
|
|
|
21
20
|
const TARGET_STATE = {
|
|
22
21
|
cursor: { state: ".cursor/ecc-install-state.json" },
|
|
23
|
-
claude: { state: ".claude/ecc/install-state.json" },
|
|
24
22
|
codex: { state: ".codex/ecc-install-state.json" },
|
|
25
23
|
};
|
|
26
24
|
|
|
@@ -36,64 +34,20 @@ function cloneRepo(tag, dest) {
|
|
|
36
34
|
}
|
|
37
35
|
}
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function registerClaudePlugin(repoDir) {
|
|
48
|
-
const { cachePath, registryPath } = getPluginPaths();
|
|
49
|
-
|
|
50
|
-
if (existsSync(cachePath)) rmSync(cachePath, { recursive: true, force: true });
|
|
51
|
-
mkdirSync(cachePath, { recursive: true });
|
|
52
|
-
cpSync(repoDir, cachePath, { recursive: true });
|
|
53
|
-
|
|
54
|
-
// Remove .git from the cached copy
|
|
55
|
-
const dotGit = join(cachePath, ".git");
|
|
56
|
-
if (existsSync(dotGit)) rmSync(dotGit, { recursive: true, force: true });
|
|
57
|
-
|
|
58
|
-
let registry = { version: 2, plugins: {} };
|
|
59
|
-
if (existsSync(registryPath)) {
|
|
60
|
-
try { registry = JSON.parse(readFileSync(registryPath, "utf8")); } catch { /* fresh */ }
|
|
37
|
+
// Claude Code: register marketplace + install plugin via CLI
|
|
38
|
+
function installClaudePlugin(repoDir) {
|
|
39
|
+
try {
|
|
40
|
+
run(`claude plugin marketplace add ${repoDir} --scope user`);
|
|
41
|
+
} catch {
|
|
42
|
+
// marketplace may already exist — update it instead
|
|
43
|
+
try { run(`claude plugin marketplace update ${MARKETPLACE_NAME}`); } catch { /* ok */ }
|
|
61
44
|
}
|
|
62
|
-
|
|
63
|
-
let commitSha = "";
|
|
64
|
-
try { commitSha = run("git rev-parse HEAD", { cwd: repoDir }).toString().trim(); } catch { /* ok */ }
|
|
65
|
-
|
|
66
|
-
registry.plugins[PLUGIN_KEY] = [
|
|
67
|
-
{
|
|
68
|
-
scope: "user",
|
|
69
|
-
installPath: cachePath,
|
|
70
|
-
version: PLUGIN_VERSION,
|
|
71
|
-
installedAt: new Date().toISOString(),
|
|
72
|
-
lastUpdated: new Date().toISOString(),
|
|
73
|
-
...(commitSha && { gitCommitSha: commitSha }),
|
|
74
|
-
},
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
writeFileSync(registryPath, JSON.stringify(registry, null, 2));
|
|
45
|
+
run(`claude plugin install ${PLUGIN_KEY} --scope user`);
|
|
78
46
|
}
|
|
79
47
|
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (existsSync(cachePath)) {
|
|
84
|
-
rmSync(cachePath, { recursive: true, force: true });
|
|
85
|
-
pruneEmptyParents(cachePath, join(homedir(), ".claude"));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (existsSync(registryPath)) {
|
|
89
|
-
try {
|
|
90
|
-
const registry = JSON.parse(readFileSync(registryPath, "utf8"));
|
|
91
|
-
if (registry.plugins?.[PLUGIN_KEY]) {
|
|
92
|
-
delete registry.plugins[PLUGIN_KEY];
|
|
93
|
-
writeFileSync(registryPath, JSON.stringify(registry, null, 2));
|
|
94
|
-
}
|
|
95
|
-
} catch { /* best effort */ }
|
|
96
|
-
}
|
|
48
|
+
function uninstallClaudePlugin() {
|
|
49
|
+
try { run(`claude plugin uninstall ${PLUGIN_KEY} --scope user`); } catch { /* not installed */ }
|
|
50
|
+
try { run(`claude plugin marketplace remove ${MARKETPLACE_NAME}`); } catch { /* not registered */ }
|
|
97
51
|
}
|
|
98
52
|
|
|
99
53
|
function namespaceCommands(target) {
|
|
@@ -142,12 +96,16 @@ export async function installAwEcc(
|
|
|
142
96
|
try {
|
|
143
97
|
cloneRepo(AW_ECC_TAG, TMP_DIR);
|
|
144
98
|
|
|
145
|
-
// Claude Code:
|
|
99
|
+
// Claude Code: proper plugin install via marketplace CLI
|
|
146
100
|
if (targets.includes("claude")) {
|
|
147
|
-
|
|
101
|
+
try {
|
|
102
|
+
installClaudePlugin(TMP_DIR);
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (!silent) fmt.logWarn(`Claude plugin install skipped: ${err.message}`);
|
|
105
|
+
}
|
|
148
106
|
}
|
|
149
107
|
|
|
150
|
-
// Cursor + Codex: file-copy
|
|
108
|
+
// Cursor + Codex: file-copy via install-apply.js + namespace commands
|
|
151
109
|
const fileCopyTargets = targets.filter((t) => FILE_COPY_TARGETS.includes(t));
|
|
152
110
|
if (fileCopyTargets.length > 0) {
|
|
153
111
|
run("npm install --no-audit --no-fund --ignore-scripts --loglevel=error", {
|
|
@@ -176,14 +134,16 @@ export function uninstallAwEcc({ silent = false } = {}) {
|
|
|
176
134
|
const HOME = homedir();
|
|
177
135
|
let removed = 0;
|
|
178
136
|
|
|
179
|
-
// Claude Code:
|
|
180
|
-
|
|
181
|
-
|
|
137
|
+
// Claude Code: uninstall plugin + remove marketplace via CLI
|
|
138
|
+
try {
|
|
139
|
+
uninstallClaudePlugin();
|
|
140
|
+
removed++;
|
|
141
|
+
} catch { /* best effort */ }
|
|
182
142
|
|
|
183
143
|
// Cursor + Codex: remove file-copied content via install-state
|
|
184
144
|
for (const cfg of Object.values(TARGET_STATE)) {
|
|
185
145
|
const statePath = join(HOME, cfg.state);
|
|
186
|
-
const ideDir = join(HOME, cfg.state.split("/")[0]);
|
|
146
|
+
const ideDir = join(HOME, "." + cfg.state.split("/")[0].replace(".", ""));
|
|
187
147
|
if (!existsSync(statePath)) continue;
|
|
188
148
|
|
|
189
149
|
try {
|
|
@@ -192,15 +152,15 @@ export function uninstallAwEcc({ silent = false } = {}) {
|
|
|
192
152
|
if (op.destinationPath && existsSync(op.destinationPath)) {
|
|
193
153
|
rmSync(op.destinationPath, { recursive: true, force: true });
|
|
194
154
|
removed++;
|
|
195
|
-
pruneEmptyParents(op.destinationPath,
|
|
155
|
+
pruneEmptyParents(op.destinationPath, join(HOME, cfg.state.split("/")[0]));
|
|
196
156
|
}
|
|
197
157
|
}
|
|
198
158
|
rmSync(statePath, { force: true });
|
|
199
|
-
pruneEmptyParents(statePath,
|
|
159
|
+
pruneEmptyParents(statePath, join(HOME, cfg.state.split("/")[0]));
|
|
200
160
|
} catch { /* corrupted state — skip */ }
|
|
201
161
|
}
|
|
202
162
|
|
|
203
|
-
// Clean leftover claude install-state from older versions
|
|
163
|
+
// Clean leftover claude install-state from older file-copy versions
|
|
204
164
|
const claudeState = join(HOME, ".claude", "ecc", "install-state.json");
|
|
205
165
|
if (existsSync(claudeState)) {
|
|
206
166
|
try {
|
|
@@ -216,6 +176,13 @@ export function uninstallAwEcc({ silent = false } = {}) {
|
|
|
216
176
|
} catch { /* best effort */ }
|
|
217
177
|
}
|
|
218
178
|
|
|
179
|
+
// Clean leftover manual plugin cache from older versions
|
|
180
|
+
const oldCache = join(HOME, ".claude", "plugins", "cache", "aw");
|
|
181
|
+
if (existsSync(oldCache)) {
|
|
182
|
+
rmSync(oldCache, { recursive: true, force: true });
|
|
183
|
+
removed++;
|
|
184
|
+
}
|
|
185
|
+
|
|
219
186
|
if (!silent && removed > 0)
|
|
220
187
|
fmt.logStep(`Removed ${removed} aw-ecc file${removed > 1 ? "s" : ""}`);
|
|
221
188
|
return removed;
|