@ghl-ai/aw 0.1.42-beta.2 → 0.1.42-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 CHANGED
@@ -10,7 +10,7 @@ import { applyStoredStartupPreferences } from "./startup.mjs";
10
10
 
11
11
  const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
12
12
  const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
13
- export const AW_ECC_TAG = "v1.4.38-beta.2";
13
+ export const AW_ECC_TAG = "v1.4.38-beta.19";
14
14
 
15
15
  const MARKETPLACE_NAME = "aw-marketplace";
16
16
  const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
package/hooks.mjs CHANGED
@@ -95,6 +95,16 @@ if [ -f ".aw/.git" ] && command -v aw >/dev/null 2>&1; then
95
95
  AW_TRIGGER=hook:post-commit aw link >/dev/null 2>&1 &
96
96
  fi
97
97
 
98
+ # Fire commit_created telemetry if commit has AW co-author trailer
99
+ if git log -1 --format='%b' HEAD 2>/dev/null | grep -qF "Co-Authored-By: AW"; then
100
+ TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-commit-created.js"
101
+ if command -v node >/dev/null 2>&1 && [ -f "$TELEMETRY_HOOK" ]; then
102
+ COMMIT_HASH="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
103
+ BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
104
+ node "$TELEMETRY_HOOK" "$COMMIT_HASH" "$BRANCH" >/dev/null 2>&1
105
+ fi
106
+ fi
107
+
98
108
  # Chain to previous hooksPath
99
109
  PREV_PATH_FILE="$HOME/.aw/hooks/.previous-hooks-path"
100
110
  if [ -f "$PREV_PATH_FILE" ]; then
@@ -258,10 +268,31 @@ fi
258
268
  exit 0
259
269
  `;
260
270
 
271
+ // Standalone post-commit for local .git/hooks/ installation.
272
+ // Fires commit_created telemetry when the commit has AW co-author trailer.
273
+ const LOCAL_POST_COMMIT = `#!/bin/sh
274
+ # aw: local post-commit hook (installed by aw init)
275
+
276
+ # Skip aw temp dirs
277
+ case "$(pwd)" in /tmp/aw-*|/var/folders/*/aw-*|*/.aw|*/.aw/*) exit 0 ;; esac
278
+
279
+ # Fire commit_created telemetry if commit has AW co-author trailer
280
+ if git log -1 --format='%b' HEAD 2>/dev/null | grep -qF "Co-Authored-By: AW"; then
281
+ TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-commit-created.js"
282
+ if command -v node >/dev/null 2>&1 && [ -f "$TELEMETRY_HOOK" ]; then
283
+ COMMIT_HASH="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)"
284
+ BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
285
+ node "$TELEMETRY_HOOK" "$COMMIT_HASH" "$BRANCH" >/dev/null 2>&1
286
+ fi
287
+ fi
288
+
289
+ exit 0
290
+ `;
291
+
261
292
  /**
262
- * Install prepare-commit-msg hook into a project's local .git/hooks/.
263
- * This covers repos where another tool (e.g. Claude Code) sets a local
264
- * core.hooksPath that overrides the global one.
293
+ * Install prepare-commit-msg and post-commit hooks into a project's local
294
+ * .git/hooks/. This covers repos where another tool (e.g. Claude Code) sets
295
+ * a local core.hooksPath that overrides the global one.
265
296
  *
266
297
  * @param {string} projectDir — root of the project (must contain .git/)
267
298
  */
@@ -297,6 +328,15 @@ export function installLocalCommitHook(projectDir) {
297
328
 
298
329
  writeFileSync(hookPath, LOCAL_PREPARE_COMMIT_MSG);
299
330
  chmodSync(hookPath, '755');
331
+
332
+ // Also install post-commit for commit_created telemetry
333
+ const postCommitPath = join(hooksDir, 'post-commit');
334
+ const shouldWritePostCommit = !existsSync(postCommitPath)
335
+ || readFileSync(postCommitPath, 'utf8').includes('aw:');
336
+ if (shouldWritePostCommit) {
337
+ writeFileSync(postCommitPath, LOCAL_POST_COMMIT);
338
+ chmodSync(postCommitPath, '755');
339
+ }
300
340
  } catch { /* best effort */ }
301
341
  }
302
342
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.42-beta.2",
3
+ "version": "0.1.42-beta.20",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": {
package/startup.mjs CHANGED
@@ -16,6 +16,11 @@ const DISABLED_MODE = 'disabled';
16
16
  const CLAUDE_DISABLE_DESCRIPTION = 'AW-managed override: disable automatic AW session routing';
17
17
  const CLAUDE_TELEMETRY_DESCRIPTION = 'AW usage telemetry';
18
18
  const CLAUDE_TELEMETRY_HOOKS = [
19
+ {
20
+ phase: 'SessionStart',
21
+ matcher: undefined,
22
+ command: 'node "$HOME/.aw-ecc/scripts/hooks/aw-usage-session-start.js"',
23
+ },
19
24
  {
20
25
  phase: 'PostToolUse',
21
26
  matcher: 'Skill|Agent|Shell|Bash',
@@ -168,7 +173,10 @@ function hasCommandHook(entry, command) {
168
173
  }
169
174
 
170
175
  function isManagedClaudeTelemetryEntry(entry) {
171
- return entry?.description === CLAUDE_TELEMETRY_DESCRIPTION;
176
+ if (entry?.description === CLAUDE_TELEMETRY_DESCRIPTION) return true;
177
+ // Also match legacy entries (no description) by command pattern
178
+ const cmds = Array.isArray(entry?.hooks) ? entry.hooks.map(h => h?.command || '') : [];
179
+ return cmds.some(c => c.includes('aw-usage-'));
172
180
  }
173
181
 
174
182
  function buildClaudeTelemetryEntry(hookDef) {
@@ -196,10 +204,14 @@ function enableClaudeTelemetryHooks(homeDir = homedir()) {
196
204
 
197
205
  for (const hookDef of CLAUDE_TELEMETRY_HOOKS) {
198
206
  const current = Array.isArray(config.hooks[hookDef.phase]) ? config.hooks[hookDef.phase] : [];
199
- // Skip if already present
200
- if (current.some(isManagedClaudeTelemetryEntry)) continue;
207
+ const managed = current.filter(isManagedClaudeTelemetryEntry);
208
+
209
+ // If exactly one properly described entry exists, nothing to do
210
+ if (managed.length === 1 && managed[0].description === CLAUDE_TELEMETRY_DESCRIPTION) continue;
201
211
 
202
- config.hooks[hookDef.phase] = [...current, buildClaudeTelemetryEntry(hookDef)];
212
+ // Remove all legacy/duplicate telemetry entries, then add the canonical one
213
+ const cleaned = current.filter(e => !isManagedClaudeTelemetryEntry(e));
214
+ config.hooks[hookDef.phase] = [...cleaned, buildClaudeTelemetryEntry(hookDef)];
203
215
  changed = true;
204
216
  }
205
217