@ghl-ai/aw 0.1.38-beta.19 → 0.1.38-beta.20
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 +2 -72
- package/package.json +1 -1
package/ecc.mjs
CHANGED
|
@@ -9,7 +9,7 @@ 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.0.8";
|
|
13
13
|
|
|
14
14
|
const MARKETPLACE_NAME = "aw-marketplace";
|
|
15
15
|
const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
|
|
@@ -37,7 +37,7 @@ const PROTECTED_CONFIG_BY_TARGET = {
|
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
function run(cmd, opts = {}) {
|
|
40
|
-
return execSync(cmd, { stdio: "pipe",
|
|
40
|
+
return execSync(cmd, { stdio: "pipe", ...opts });
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function readIfExists(path) {
|
|
@@ -124,57 +124,8 @@ function installClaudePlugin(repoDir) {
|
|
|
124
124
|
// previously-registered path, which may point to a stale/wrong directory.
|
|
125
125
|
try { run(`claude plugin uninstall ${PLUGIN_KEY} --scope user`); } catch { /* not installed */ }
|
|
126
126
|
try { run(`claude plugin marketplace remove ${MARKETPLACE_NAME}`); } catch { /* not registered */ }
|
|
127
|
-
|
|
128
|
-
// Purge stale plugin cache — Claude Code caches by package.json version,
|
|
129
|
-
// so old entries with outdated hooks can shadow a fresh install.
|
|
130
|
-
const cacheDir = join(homedir(), ".claude", "plugins", "cache", MARKETPLACE_NAME);
|
|
131
|
-
if (existsSync(cacheDir)) {
|
|
132
|
-
try { rmSync(cacheDir, { recursive: true, force: true }); } catch { /* best effort */ }
|
|
133
|
-
}
|
|
134
|
-
|
|
135
127
|
run(`claude plugin marketplace add ${repoDir} --scope user`);
|
|
136
128
|
run(`claude plugin install ${PLUGIN_KEY} --scope user`);
|
|
137
|
-
|
|
138
|
-
// Plugin SessionStart hooks have a known issue where Claude Code fires them
|
|
139
|
-
// but silently discards the output. As a workaround, also register the
|
|
140
|
-
// SessionStart hook directly in ~/.claude/settings.json — this path is
|
|
141
|
-
// reliable and bypasses the plugin hook dispatch entirely.
|
|
142
|
-
ensureSessionStartHook(repoDir);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Add a SessionStart hook to ~/.claude/settings.json that calls the
|
|
147
|
-
* using-aw-skills session-start script directly. This is more reliable
|
|
148
|
-
* than the plugin hook path because Claude Code's plugin hook dispatch
|
|
149
|
-
* sometimes silently drops SessionStart output.
|
|
150
|
-
*/
|
|
151
|
-
function ensureSessionStartHook(repoDir) {
|
|
152
|
-
const settingsPath = join(homedir(), ".claude", "settings.json");
|
|
153
|
-
let settings = {};
|
|
154
|
-
try {
|
|
155
|
-
if (existsSync(settingsPath)) {
|
|
156
|
-
settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
157
|
-
}
|
|
158
|
-
} catch { /* start fresh */ }
|
|
159
|
-
|
|
160
|
-
const hookCmd = `bash "$HOME/.aw-ecc/skills/using-aw-skills/hooks/session-start.sh"`;
|
|
161
|
-
|
|
162
|
-
// Check if already present
|
|
163
|
-
const existing = settings.hooks?.SessionStart || [];
|
|
164
|
-
const alreadyHas = existing.some((entry) =>
|
|
165
|
-
entry.hooks?.some((h) => h.command === hookCmd),
|
|
166
|
-
);
|
|
167
|
-
if (alreadyHas) return;
|
|
168
|
-
|
|
169
|
-
if (!settings.hooks) settings.hooks = {};
|
|
170
|
-
if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
|
|
171
|
-
|
|
172
|
-
settings.hooks.SessionStart.push({
|
|
173
|
-
hooks: [{ type: "command", command: hookCmd }],
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
mkdirSync(dirname(settingsPath), { recursive: true });
|
|
177
|
-
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
178
129
|
}
|
|
179
130
|
|
|
180
131
|
function uninstallClaudePlugin() {
|
|
@@ -182,22 +133,6 @@ function uninstallClaudePlugin() {
|
|
|
182
133
|
try { run(`claude plugin marketplace remove ${MARKETPLACE_NAME}`); } catch { /* not registered */ }
|
|
183
134
|
}
|
|
184
135
|
|
|
185
|
-
function removeSessionStartHook() {
|
|
186
|
-
const settingsPath = join(homedir(), ".claude", "settings.json");
|
|
187
|
-
if (!existsSync(settingsPath)) return;
|
|
188
|
-
try {
|
|
189
|
-
const settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
190
|
-
const hooks = settings.hooks?.SessionStart;
|
|
191
|
-
if (!Array.isArray(hooks)) return;
|
|
192
|
-
settings.hooks.SessionStart = hooks.filter((entry) =>
|
|
193
|
-
!entry.hooks?.some((h) => h.command?.includes(".aw-ecc/")),
|
|
194
|
-
);
|
|
195
|
-
if (settings.hooks.SessionStart.length === 0) delete settings.hooks.SessionStart;
|
|
196
|
-
if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
|
|
197
|
-
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
198
|
-
} catch { /* best effort */ }
|
|
199
|
-
}
|
|
200
|
-
|
|
201
136
|
/**
|
|
202
137
|
* Move ecc command files from ~/.cursor/commands/*.md → ~/.cursor/commands/aw/*.md
|
|
203
138
|
* so Cursor exposes them as /aw:tdd, /aw:plan — consistent with Claude Code's plugin namespace.
|
|
@@ -326,11 +261,6 @@ export function uninstallAwEcc({ silent = false } = {}) {
|
|
|
326
261
|
removed++;
|
|
327
262
|
} catch { /* best effort */ }
|
|
328
263
|
|
|
329
|
-
// Remove SessionStart hook from settings.json
|
|
330
|
-
try {
|
|
331
|
-
removeSessionStartHook();
|
|
332
|
-
} catch { /* best effort */ }
|
|
333
|
-
|
|
334
264
|
// Cursor + Codex: remove file-copied content via install-state
|
|
335
265
|
for (const cfg of Object.values(TARGET_STATE)) {
|
|
336
266
|
const statePath = join(HOME, cfg.state);
|