@ghl-ai/aw 0.1.42-beta.1 → 0.1.42-beta.3

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.1";
13
+ export const AW_ECC_TAG = "v1.4.38-beta.3";
14
14
 
15
15
  const MARKETPLACE_NAME = "aw-marketplace";
16
16
  const PLUGIN_KEY = `aw@${MARKETPLACE_NAME}`;
@@ -46,10 +46,27 @@ const CODEX_HOME_PHASE_BLUEPRINTS = {
46
46
  scriptName: 'aw-user-prompt-submit.sh',
47
47
  scriptMarker: '# aw-managed: codex-global-user-prompt-submit',
48
48
  buildScriptContent() {
49
- return buildDelegatingPhaseScript({
50
- marker: this.scriptMarker,
51
- targetPath: '$HOME/.aw-ecc/scripts/hooks/session-start-rules-context.sh',
52
- });
49
+ return `#!/usr/bin/env bash
50
+ ${this.scriptMarker}
51
+ set -euo pipefail
52
+
53
+ # Capture stdin so we can feed it to both the existing delegate and telemetry.
54
+ STDIN=$(cat)
55
+
56
+ # Fire telemetry in background (non-blocking).
57
+ TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-prompt-submit.js"
58
+ if [[ -f "$TELEMETRY_HOOK" ]]; then
59
+ echo "$STDIN" | node "$TELEMETRY_HOOK" >/dev/null 2>&1 &
60
+ fi
61
+
62
+ # Delegate to existing rules-context hook.
63
+ TARGET="$HOME/.aw-ecc/scripts/hooks/session-start-rules-context.sh"
64
+ if [[ -f "$TARGET" ]]; then
65
+ echo "$STDIN" | exec bash "$TARGET"
66
+ fi
67
+
68
+ exit 0
69
+ `;
53
70
  },
54
71
  buildEntry(command) {
55
72
  return {
@@ -88,11 +105,18 @@ const CODEX_HOME_PHASE_BLUEPRINTS = {
88
105
  scriptName: 'aw-post-tool-use.sh',
89
106
  scriptMarker: '# aw-managed: codex-global-post-tool-use',
90
107
  buildScriptContent() {
91
- return buildReservedPhaseScript({
92
- marker: this.scriptMarker,
93
- phase: 'PostToolUse',
94
- harnessLabel: 'Codex home routing',
95
- });
108
+ return `#!/usr/bin/env bash
109
+ ${this.scriptMarker}
110
+ set -euo pipefail
111
+
112
+ # AW PostToolUse phase for Codex — usage telemetry.
113
+ # Codex tool_name is always "Bash" — only PR and aw-push detection works.
114
+ TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-post-tool-use.js"
115
+ if [[ -f "$TELEMETRY_HOOK" ]]; then
116
+ exec node "$TELEMETRY_HOOK"
117
+ fi
118
+ echo '{}'
119
+ `;
96
120
  },
97
121
  buildEntry(command) {
98
122
  return {
@@ -110,11 +134,18 @@ const CODEX_HOME_PHASE_BLUEPRINTS = {
110
134
  scriptName: 'aw-stop.sh',
111
135
  scriptMarker: '# aw-managed: codex-global-stop',
112
136
  buildScriptContent() {
113
- return buildReservedPhaseScript({
114
- marker: this.scriptMarker,
115
- phase: 'Stop',
116
- harnessLabel: 'Codex home routing',
117
- });
137
+ return `#!/usr/bin/env bash
138
+ ${this.scriptMarker}
139
+ set -euo pipefail
140
+
141
+ # AW Stop phase for Codex — usage telemetry.
142
+ # Codex Stop has last_assistant_message, stop_hook_active — no token usage.
143
+ TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-stop.js"
144
+ if [[ -f "$TELEMETRY_HOOK" ]]; then
145
+ exec node "$TELEMETRY_HOOK"
146
+ fi
147
+ echo '{}'
148
+ `;
118
149
  },
119
150
  buildEntry(command) {
120
151
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.42-beta.1",
3
+ "version": "0.1.42-beta.3",
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
@@ -14,6 +14,29 @@ const ENABLED_MODE = 'enabled';
14
14
  const DISABLED_MODE = 'disabled';
15
15
 
16
16
  const CLAUDE_DISABLE_DESCRIPTION = 'AW-managed override: disable automatic AW session routing';
17
+ const CLAUDE_TELEMETRY_DESCRIPTION = 'AW usage telemetry';
18
+ const CLAUDE_TELEMETRY_HOOKS = [
19
+ {
20
+ phase: 'PostToolUse',
21
+ matcher: 'Skill|Agent|Shell|Bash',
22
+ command: 'node "$HOME/.aw-ecc/scripts/hooks/aw-usage-post-tool-use.js"',
23
+ },
24
+ {
25
+ phase: 'Stop',
26
+ matcher: undefined,
27
+ command: 'node "$HOME/.aw-ecc/scripts/hooks/aw-usage-stop.js"',
28
+ },
29
+ {
30
+ phase: 'PostToolUseFailure',
31
+ matcher: undefined,
32
+ command: 'node "$HOME/.aw-ecc/scripts/hooks/aw-usage-post-tool-use-failure.js"',
33
+ },
34
+ {
35
+ phase: 'UserPromptSubmit',
36
+ matcher: undefined,
37
+ command: 'node "$HOME/.aw-ecc/scripts/hooks/aw-usage-prompt-submit.js"',
38
+ },
39
+ ];
17
40
  const CURSOR_SESSION_START_COMMAND = 'node .cursor/hooks/session-start.js';
18
41
  const CURSOR_SESSION_START_DESCRIPTION = 'Load previous context and detect environment';
19
42
  const REPO_CURSOR_SESSION_START_COMMAND = 'bash "$(git rev-parse --show-toplevel)/hooks/aw-session-start"';
@@ -144,6 +167,85 @@ function hasCommandHook(entry, command) {
144
167
  );
145
168
  }
146
169
 
170
+ function isManagedClaudeTelemetryEntry(entry) {
171
+ return entry?.description === CLAUDE_TELEMETRY_DESCRIPTION;
172
+ }
173
+
174
+ function buildClaudeTelemetryEntry(hookDef) {
175
+ const entry = {
176
+ hooks: [
177
+ {
178
+ type: 'command',
179
+ command: hookDef.command,
180
+ },
181
+ ],
182
+ description: CLAUDE_TELEMETRY_DESCRIPTION,
183
+ };
184
+ if (hookDef.matcher) {
185
+ entry.matcher = hookDef.matcher;
186
+ }
187
+ return entry;
188
+ }
189
+
190
+ function enableClaudeTelemetryHooks(homeDir = homedir()) {
191
+ const settingsPath = join(homeDir, '.claude', 'settings.json');
192
+ const config = readJson(settingsPath, {});
193
+ ensureHooksObject(config);
194
+
195
+ let changed = false;
196
+
197
+ for (const hookDef of CLAUDE_TELEMETRY_HOOKS) {
198
+ const current = Array.isArray(config.hooks[hookDef.phase]) ? config.hooks[hookDef.phase] : [];
199
+ // Skip if already present
200
+ if (current.some(isManagedClaudeTelemetryEntry)) continue;
201
+
202
+ config.hooks[hookDef.phase] = [...current, buildClaudeTelemetryEntry(hookDef)];
203
+ changed = true;
204
+ }
205
+
206
+ if (!changed) return [];
207
+
208
+ writeJson(settingsPath, config);
209
+ return [settingsPath];
210
+ }
211
+
212
+ function disableClaudeTelemetryHooks(homeDir = homedir()) {
213
+ const settingsPath = join(homeDir, '.claude', 'settings.json');
214
+ if (!existsSync(settingsPath)) return [];
215
+
216
+ const config = readJson(settingsPath, {});
217
+ if (!isObject(config.hooks)) return [];
218
+
219
+ let changed = false;
220
+
221
+ for (const hookDef of CLAUDE_TELEMETRY_HOOKS) {
222
+ const current = Array.isArray(config.hooks[hookDef.phase]) ? config.hooks[hookDef.phase] : null;
223
+ if (!current) continue;
224
+
225
+ const filtered = current.filter(entry => !isManagedClaudeTelemetryEntry(entry));
226
+ if (filtered.length !== current.length) {
227
+ changed = true;
228
+ if (filtered.length > 0) {
229
+ config.hooks[hookDef.phase] = filtered;
230
+ } else {
231
+ delete config.hooks[hookDef.phase];
232
+ }
233
+ }
234
+ }
235
+
236
+ if (!changed) return [];
237
+
238
+ if (isEmptyObject(config.hooks)) {
239
+ delete config.hooks;
240
+ }
241
+
242
+ if (!pruneEmptySettingsFile(settingsPath, config)) {
243
+ writeJson(settingsPath, config);
244
+ }
245
+
246
+ return [settingsPath];
247
+ }
248
+
147
249
  function isManagedCodexSessionStartEntry(entry) {
148
250
  return isManagedCodexHomeEntry(entry, CODEX_SESSION_START_DEFINITION);
149
251
  }
@@ -490,10 +592,12 @@ export function applyGlobalStartupMode(mode, homeDir = homedir()) {
490
592
 
491
593
  if (normalizedMode === DISABLED_MODE) {
492
594
  updatedFiles.push(...disableClaudeStartup(homeDir));
595
+ updatedFiles.push(...disableClaudeTelemetryHooks(homeDir));
493
596
  updatedFiles.push(...disableCodexStartup(homeDir));
494
597
  updatedFiles.push(...disableCursorStartup(homeDir));
495
598
  } else {
496
599
  updatedFiles.push(...enableClaudeStartup(homeDir));
600
+ updatedFiles.push(...enableClaudeTelemetryHooks(homeDir));
497
601
  updatedFiles.push(...enableCodexStartup(homeDir));
498
602
  updatedFiles.push(...enableCursorStartup(homeDir));
499
603
  }