@ghl-ai/aw 0.1.37-beta.69 → 0.1.37-beta.70
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/integrate.mjs +75 -10
- package/package.json +1 -1
package/integrate.mjs
CHANGED
|
@@ -630,7 +630,7 @@ export function installIdeHooks() {
|
|
|
630
630
|
|
|
631
631
|
writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2) + '\n');
|
|
632
632
|
|
|
633
|
-
// ── Step 3: Cursor — wire
|
|
633
|
+
// ── Step 3: Cursor — wire 4 events (sessionStart, stop, preCompact, sessionEnd) ──
|
|
634
634
|
const cursorDir = join(home, '.cursor');
|
|
635
635
|
mkdirSync(cursorDir, { recursive: true });
|
|
636
636
|
const cursorHooksPath = join(cursorDir, 'hooks.json');
|
|
@@ -641,15 +641,26 @@ export function installIdeHooks() {
|
|
|
641
641
|
}
|
|
642
642
|
if (!cursorHooks.hooks) cursorHooks.hooks = {};
|
|
643
643
|
|
|
644
|
-
//
|
|
645
|
-
const
|
|
646
|
-
|
|
644
|
+
// Cursor uses camelCase event names
|
|
645
|
+
const cursorEventMap = {
|
|
646
|
+
SessionStart: 'sessionStart',
|
|
647
|
+
Stop: 'stop',
|
|
648
|
+
PreCompact: 'preCompact',
|
|
649
|
+
SessionEnd: 'sessionEnd',
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
for (const [event, { cmd, timeout }] of Object.entries(dispatchers)) {
|
|
653
|
+
const cursorEvent = cursorEventMap[event];
|
|
654
|
+
if (!cursorEvent) continue;
|
|
647
655
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
656
|
+
if (!cursorHooks.hooks[cursorEvent]) cursorHooks.hooks[cursorEvent] = [];
|
|
657
|
+
|
|
658
|
+
// Remove old aw entries
|
|
659
|
+
cursorHooks.hooks[cursorEvent] = cursorHooks.hooks[cursorEvent].filter(h =>
|
|
660
|
+
!h.command?.includes('.aw/hooks/') && !h.command?.includes('telemetry-stop.js')
|
|
661
|
+
);
|
|
662
|
+
cursorHooks.hooks[cursorEvent].push({ command: cmd, timeout });
|
|
663
|
+
}
|
|
653
664
|
|
|
654
665
|
// Remove old postToolUse entry from aw
|
|
655
666
|
if (cursorHooks.hooks.postToolUse) {
|
|
@@ -663,7 +674,61 @@ export function installIdeHooks() {
|
|
|
663
674
|
|
|
664
675
|
writeFileSync(cursorHooksPath, JSON.stringify(cursorHooks, null, 2) + '\n');
|
|
665
676
|
|
|
666
|
-
|
|
677
|
+
// ── Step 4: Codex — wire SessionStart + Stop via ~/.codex/hooks.json ──
|
|
678
|
+
// Codex hooks use PascalCase event names and require [features] codex_hooks = true in config.toml
|
|
679
|
+
const codexDir = join(home, '.codex');
|
|
680
|
+
mkdirSync(codexDir, { recursive: true });
|
|
681
|
+
const codexHooksPath = join(codexDir, 'hooks.json');
|
|
682
|
+
|
|
683
|
+
let codexHooks = {};
|
|
684
|
+
if (existsSync(codexHooksPath)) {
|
|
685
|
+
try { codexHooks = JSON.parse(readFileSync(codexHooksPath, 'utf8')); } catch { codexHooks = {}; }
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Codex supports: SessionStart, Stop, PreToolUse, PostToolUse, UserPromptSubmit
|
|
689
|
+
const codexEvents = { SessionStart: dispatchers.SessionStart, Stop: dispatchers.Stop };
|
|
690
|
+
for (const [event, { cmd, timeout }] of Object.entries(codexEvents)) {
|
|
691
|
+
if (!codexHooks[event]) codexHooks[event] = [];
|
|
692
|
+
|
|
693
|
+
// Each entry is a matcher group: { matcher: "*", hooks: [...] }
|
|
694
|
+
// Find existing aw matcher group or create one
|
|
695
|
+
let awGroup = codexHooks[event].find(g =>
|
|
696
|
+
g.hooks?.some(h => h.command?.includes('.aw/hooks/'))
|
|
697
|
+
);
|
|
698
|
+
if (!awGroup) {
|
|
699
|
+
awGroup = { hooks: [] };
|
|
700
|
+
codexHooks[event].push(awGroup);
|
|
701
|
+
}
|
|
702
|
+
// Replace aw hooks in the group
|
|
703
|
+
awGroup.hooks = awGroup.hooks.filter(h => !h.command?.includes('.aw/hooks/'));
|
|
704
|
+
awGroup.hooks.push({
|
|
705
|
+
type: 'command',
|
|
706
|
+
command: cmd,
|
|
707
|
+
timeoutSec: timeout,
|
|
708
|
+
statusMessage: `AW telemetry (${event})`,
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
writeFileSync(codexHooksPath, JSON.stringify(codexHooks, null, 2) + '\n');
|
|
713
|
+
|
|
714
|
+
// Enable codex_hooks feature if not already set
|
|
715
|
+
const codexConfigPath = join(codexDir, 'config.toml');
|
|
716
|
+
if (existsSync(codexConfigPath)) {
|
|
717
|
+
try {
|
|
718
|
+
let toml = readFileSync(codexConfigPath, 'utf8');
|
|
719
|
+
if (!toml.includes('codex_hooks')) {
|
|
720
|
+
// Append under [features] if it exists, or add it
|
|
721
|
+
if (toml.includes('[features]')) {
|
|
722
|
+
toml = toml.replace('[features]', '[features]\ncodex_hooks = true');
|
|
723
|
+
} else {
|
|
724
|
+
toml += '\n[features]\ncodex_hooks = true\n';
|
|
725
|
+
}
|
|
726
|
+
writeFileSync(codexConfigPath, toml);
|
|
727
|
+
}
|
|
728
|
+
} catch { /* best effort */ }
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
fmt.logSuccess('IDE hooks installed — 4 events (Claude + Cursor) + 2 events (Codex) → ~/.aw/hooks/');
|
|
667
732
|
}
|
|
668
733
|
|
|
669
734
|
/** Legacy hook wiring — used as fallback when new dispatchers aren't available */
|