@ghl-ai/aw 0.1.37-beta.79 → 0.1.37-beta.80
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 +62 -13
- package/package.json +1 -1
package/integrate.mjs
CHANGED
|
@@ -489,6 +489,8 @@ No active tasks. Tasks are created during workflow execution.
|
|
|
489
489
|
export function installIdeHooks() {
|
|
490
490
|
const home = homedir();
|
|
491
491
|
const hooksDir = join(home, '.aw', 'hooks');
|
|
492
|
+
const codexHooksDir = join(hooksDir, 'codex');
|
|
493
|
+
const nodeExec = process.execPath;
|
|
492
494
|
|
|
493
495
|
// ── Step 0: Write ~/.aw/config.json with API URL ───────────────────
|
|
494
496
|
const awDir = join(home, '.aw');
|
|
@@ -511,7 +513,7 @@ export function installIdeHooks() {
|
|
|
511
513
|
const pkgHooksDir = join(dirname(fileURLToPath(import.meta.url)), 'hooks');
|
|
512
514
|
|
|
513
515
|
// New dispatcher-based hooks (Phase 1)
|
|
514
|
-
const newHookDirs = ['shared', 'capabilities'];
|
|
516
|
+
const newHookDirs = ['shared', 'capabilities', 'codex'];
|
|
515
517
|
const newHookFiles = [
|
|
516
518
|
'manifest.mjs',
|
|
517
519
|
'shared/dispatch.mjs',
|
|
@@ -544,6 +546,55 @@ export function installIdeHooks() {
|
|
|
544
546
|
try { chmodSync(dest, 0o755); } catch { /* best effort */ }
|
|
545
547
|
}
|
|
546
548
|
|
|
549
|
+
const codexWrapperScripts = {
|
|
550
|
+
'session-start.sh': `#!/usr/bin/env bash
|
|
551
|
+
set -euo pipefail
|
|
552
|
+
|
|
553
|
+
NODE_BIN=${JSON.stringify(nodeExec)}
|
|
554
|
+
TARGET=${JSON.stringify(join(hooksDir, 'shared', 'session-start.mjs'))}
|
|
555
|
+
LOG_FILE=${JSON.stringify(join(home, '.aw', 'telemetry', 'codex-hook-errors.log'))}
|
|
556
|
+
|
|
557
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
558
|
+
|
|
559
|
+
if ! output="$("$NODE_BIN" "$TARGET" 2>>"$LOG_FILE")"; then
|
|
560
|
+
printf '%s\\n' '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":""}}'
|
|
561
|
+
exit 0
|
|
562
|
+
fi
|
|
563
|
+
|
|
564
|
+
if [[ -n "$output" ]]; then
|
|
565
|
+
printf '%s\\n' "$output"
|
|
566
|
+
else
|
|
567
|
+
printf '%s\\n' '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":""}}'
|
|
568
|
+
fi
|
|
569
|
+
`,
|
|
570
|
+
'stop.sh': `#!/usr/bin/env bash
|
|
571
|
+
set -euo pipefail
|
|
572
|
+
|
|
573
|
+
NODE_BIN=${JSON.stringify(nodeExec)}
|
|
574
|
+
TARGET=${JSON.stringify(join(hooksDir, 'shared', 'stop.mjs'))}
|
|
575
|
+
LOG_FILE=${JSON.stringify(join(home, '.aw', 'telemetry', 'codex-hook-errors.log'))}
|
|
576
|
+
|
|
577
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
578
|
+
|
|
579
|
+
if ! output="$("$NODE_BIN" "$TARGET" 2>>"$LOG_FILE")"; then
|
|
580
|
+
printf '%s\\n' '{}'
|
|
581
|
+
exit 0
|
|
582
|
+
fi
|
|
583
|
+
|
|
584
|
+
if [[ -n "$output" ]]; then
|
|
585
|
+
printf '%s\\n' "$output"
|
|
586
|
+
else
|
|
587
|
+
printf '%s\\n' '{}'
|
|
588
|
+
fi
|
|
589
|
+
`,
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
for (const [file, content] of Object.entries(codexWrapperScripts)) {
|
|
593
|
+
const dest = join(codexHooksDir, file);
|
|
594
|
+
writeFileSync(dest, content);
|
|
595
|
+
try { chmodSync(dest, 0o755); } catch { /* best effort */ }
|
|
596
|
+
}
|
|
597
|
+
|
|
547
598
|
// Dispatcher commands — one per hook event
|
|
548
599
|
const dispatchers = {
|
|
549
600
|
SessionStart: { cmd: `node "${join(hooksDir, 'shared', 'session-start.mjs')}"`, timeout: 10 },
|
|
@@ -552,6 +603,10 @@ export function installIdeHooks() {
|
|
|
552
603
|
PreCompact: { cmd: `node "${join(hooksDir, 'shared', 'pre-compact.mjs')}"`, timeout: 20 },
|
|
553
604
|
SessionEnd: { cmd: `node "${join(hooksDir, 'shared', 'session-end.mjs')}"`, timeout: 20 },
|
|
554
605
|
};
|
|
606
|
+
const codexDispatchers = {
|
|
607
|
+
SessionStart: { cmd: `bash "${join(codexHooksDir, 'session-start.sh')}"`, timeout: 10 },
|
|
608
|
+
Stop: { cmd: `bash "${join(codexHooksDir, 'stop.sh')}"`, timeout: 15 },
|
|
609
|
+
};
|
|
555
610
|
|
|
556
611
|
// ── Step 2: Claude Code — wire 4 events (merge, don't replace) ────
|
|
557
612
|
const claudeDir = join(home, '.claude');
|
|
@@ -665,7 +720,7 @@ export function installIdeHooks() {
|
|
|
665
720
|
if (!codexHooksFile.hooks) codexHooksFile.hooks = {};
|
|
666
721
|
|
|
667
722
|
// Codex supports: SessionStart, Stop, PreToolUse, PostToolUse, UserPromptSubmit
|
|
668
|
-
const codexEvents = { SessionStart:
|
|
723
|
+
const codexEvents = { SessionStart: codexDispatchers.SessionStart, Stop: codexDispatchers.Stop };
|
|
669
724
|
for (const [event, { cmd, timeout }] of Object.entries(codexEvents)) {
|
|
670
725
|
if (!codexHooksFile.hooks[event]) codexHooksFile.hooks[event] = [];
|
|
671
726
|
|
|
@@ -710,20 +765,14 @@ export function installIdeHooks() {
|
|
|
710
765
|
|
|
711
766
|
writeFileSync(codexHooksPath, JSON.stringify(codexHooksFile, null, 2) + '\n');
|
|
712
767
|
|
|
713
|
-
// Enable codex_hooks feature if not already set
|
|
714
768
|
const codexConfigPath = join(codexDir, 'config.toml');
|
|
715
769
|
if (existsSync(codexConfigPath)) {
|
|
716
770
|
try {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
} else {
|
|
723
|
-
toml += '\n[features]\ncodex_hooks = true\n';
|
|
724
|
-
}
|
|
725
|
-
writeFileSync(codexConfigPath, toml);
|
|
726
|
-
}
|
|
771
|
+
const toml = readFileSync(codexConfigPath, 'utf8');
|
|
772
|
+
const cleaned = toml
|
|
773
|
+
.replace(/^\s*codex_hooks\s*=\s*(true|false)\s*$(\r?\n)?/m, '')
|
|
774
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
775
|
+
if (cleaned !== toml) writeFileSync(codexConfigPath, cleaned);
|
|
727
776
|
} catch { /* best effort */ }
|
|
728
777
|
}
|
|
729
778
|
|