Skip to content

feat: add Codex Desktop hooks integration#245

Open
vybie wants to merge 4 commits into
rohitg00:mainfrom
vybie:codex/codex-desktop-hooks
Open

feat: add Codex Desktop hooks integration#245
vybie wants to merge 4 commits into
rohitg00:mainfrom
vybie:codex/codex-desktop-hooks

Conversation

@vybie
Copy link
Copy Markdown

@vybie vybie commented May 8, 2026

Summary

Adds a Codex integration guide and hook bridge so Codex Desktop / Codex CLI users can use agentmemory in a Claude Code-style workflow.

This documents a two-layer setup:

  • MCP server config for explicit memory tools (memory_save, memory_recall, memory_smart_search, etc.)
  • Codex lifecycle hooks for automatic capture of session starts, prompts, tool calls, tool results, and turn stops

What changed

  • Added integrations/codex/agentmemory-codex-hook.mjs, a best-effort Codex hook bridge that translates Codex hook payloads into agentmemory REST API calls.
  • Added integrations/codex/README.md with end-to-end setup steps for Codex Desktop and Codex CLI.
  • Updated the main README Codex row to point users to the new Codex integration guide.

Setup covered in the guide

  1. Start the full agentmemory server:

    npx -y @agentmemory/agentmemory
  2. Add the MCP server to ~/.codex/config.toml:

    [mcp_servers.agentmemory]
    command = "npx"
    args = ["-y", "@agentmemory/mcp"]
    env = { AGENTMEMORY_TOOLS = "all" }
    startup_timeout_sec = 30
    tool_timeout_sec = 60
    enabled = true
  3. Copy the hook bridge into ~/.codex/hooks/.

  4. Enable Codex hooks:

    [features]
    codex_hooks = true
  5. Register SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, and Stop hooks to call the bridge script.

  6. Verify captured sessions in the viewer at http://localhost:3113 or via GET /agentmemory/export.

Behavior

The bridge maps Codex events to agentmemory observations:

Codex hook agentmemory action
SessionStart Calls /agentmemory/session/start, optionally injects recalled context
UserPromptSubmit Captures prompt_submit observation
PreToolUse Captures pre_tool_use observation
PostToolUse Captures post_tool_use observation
Stop Captures latest assistant message as stop observation

The bridge truncates large tool outputs and never throws or blocks Codex if agentmemory is down.

Validation

  • node --check integrations/codex/agentmemory-codex-hook.mjs
  • Smoke-tested the hook bridge against a local agentmemory server on Windows by sending a fake Codex UserPromptSubmit payload.
  • Separately tested the full Codex Desktop setup locally with MCP plus hooks: Codex saw the MCP server, the hook created sessions, and prompt/tool observations appeared in GET /agentmemory/export.

Notes

Codex hooks currently expose fewer lifecycle events than the Claude Code plugin, so this is not a byte-for-byte replacement. It does cover the main loop users need: automatic capture, session registration, startup context recall, and explicit MCP memory tools.

Summary by CodeRabbit

  • Documentation

    • Main README updated to reference Codex CLI/Desktop and link a new Codex integration guide with setup steps, configuration examples, verification checklist, and limitations.
  • New Features

    • Added Codex lifecycle event integration for agentmemory with optional context injection, configurable capture/truncation limits, and non‑blocking behavior when agentmemory is unavailable.
  • Tests

    • Added tests validating hook event mappings, auth handling, output behavior, and timeout resilience.

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 8, 2026

@codex is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f1f84d35-ff9d-4483-8f50-9ab2d00b0988

📥 Commits

Reviewing files that changed from the base of the PR and between 063c3dc and 4b89df8.

📒 Files selected for processing (1)
  • test/codex-hook.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/codex-hook.test.ts

📝 Walkthrough

Walkthrough

Adds Codex CLI/Desktop integration: a README guide for MCP tools + hook bridge, a Node.js CLI that forwards Codex lifecycle hooks to agentmemory REST endpoints with optional context injection and truncation, and Vitest tests validating mapping, auth, stdout injection, and timeout behavior.

Changes

Codex Integration

Layer / File(s) Summary
Root Documentation Update
README.md
Updated "Other agents" table entry from "Codex CLI" to "Codex CLI / Desktop" with reference to automatic capture guide.
Integration Overview
integrations/codex/README.md (lines 1–12)
Introduced two-layer architecture (MCP tools for explicit memory + hooks for automatic capture) and listed prerequisites.
Prerequisites & API Note
integrations/codex/README.md (lines 13–36)
Listed prerequisites, agentmemory server/viewer endpoints, and API stability/smoke-test note.
MCP Configuration
integrations/codex/README.md (lines 37–52)
Step 1: Added MCP server configuration snippet for ~/.codex/config.toml with enablement, command, env, and timeout settings.
Hook Installation
integrations/codex/README.md (lines 53–70)
Step 2: Provided copy/installation commands for agentmemory-codex-hook.mjs on Unix-like and Windows systems.
Hook Registration
integrations/codex/README.md (lines 71–176)
Step 3: Documented hook registration for SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, and Stop on macOS/Linux and Windows; included restart note.
Hook-to-Observation Mapping
integrations/codex/README.md (lines 178–192)
Mapped Codex hooks to agentmemory observation types; described captured fields and truncation/non-blocking behavior.
Server/Auth Config
integrations/codex/README.md (lines 193–210)
Documented AGENTMEMORY_URL and optional AGENTMEMORY_SECRET and noted the bridge avoids writing debug output to stdout.
Context Injection & Tuning
integrations/codex/README.md (lines 211–226)
Documented AGENTMEMORY_CODEX_INJECT_CONTEXT toggle and env vars for max capture sizes and REST timeout.
Verification & Limitations
integrations/codex/README.md (lines 228–252)
Provided verification checklist and listed feature-flag and lifecycle-coverage limitations.
Hook Script Configuration
integrations/codex/agentmemory-codex-hook.mjs (lines 1–51)
Defined environment-driven runtime configuration (REST URL, auth, inject toggle, char limits) and helper functions for env parsing, auth headers, stdin parsing, project dir resolution, and truncation.
Hook Script API & Dispatcher
integrations/codex/agentmemory-codex-hook.mjs (lines 53–159)
Implemented REST POST with timeout, observe() transformer, sessionStartContext(), main event dispatcher that branches per event type, applies truncation, posts to /agentmemory/session/start or /agentmemory/observe, optionally writes injected context to stdout, and swallows errors.
Tests
test/codex-hook.test.ts
Added Vitest tests that spawn the bridge and use a local capture server to assert /agentmemory/session/start and /agentmemory/observe payloads, Authorization header, stdout injection, mapping for multiple events, and a timeout/stall regression.

Sequence Diagram(s)

sequenceDiagram
  participant Codex
  participant HookBridge
  participant AgentMemory
  participant Viewer
  Codex->>HookBridge: send hook JSON via stdin (lifecycle events)
  HookBridge->>AgentMemory: POST /agentmemory/session/start or /agentmemory/observe
  AgentMemory-->>HookBridge: optional session context
  HookBridge-->>Codex: stdout injection (if enabled)
  AgentMemory->>Viewer: session data available for inspection
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • rohitg00/agentmemory#230: Modifies Codex integration documentation and README table guidance, related through shared Codex CLI setup context.

Poem

🐰 I hop a bridge from Codex to store,
Hooks catch start, prompt, tool, and more,
Trims long outputs, timeouts set neat,
Emits session context back on the beat,
Small rabbit hops keep memories sweet.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a Codex Desktop hooks integration with an agentmemory bridge, MCP server config, and setup documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vybie vybie changed the title Add Codex Desktop hooks integration (feat): add Codex Desktop hooks integration May 8, 2026
@vybie vybie changed the title (feat): add Codex Desktop hooks integration feat : add Codex Desktop hooks integration May 8, 2026
@vybie vybie changed the title feat : add Codex Desktop hooks integration feat: add Codex Desktop hooks integration May 8, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@integrations/codex/agentmemory-codex-hook.mjs`:
- Around line 71-78: The sessionStartContext hook is passing result.context
(likely an object) directly as additionalContext, which must be a string; update
sessionStartContext to ensure additionalContext is always a string by
stringifying non-string inputs (e.g., use JSON.stringify for objects) and
preserve existing string values as-is so the hook outputs
hookSpecificOutput.hookEventName "SessionStart" with additionalContext set to a
plain string.
- Around line 14-19: The constants MAX_TOOL_OUTPUT_CHARS and
MAX_ASSISTANT_MESSAGE_CHARS can become NaN when the env vars are non-numeric
which breaks truncate (slice with NaN -> 0); fix by parsing and validating the
env values when initializing those constants (use parseInt(..., 10) or
Number(...) then check Number.isFinite and >= 0), and fall back to the default
numeric values (8000 and 12000) if the parsed value is invalid; also ensure the
truncate function uses these validated integer values (and optionally
Math.floor/clamp) so slice never receives NaN or negative numbers.
- Around line 60-69: observe() currently falls back to the static "unknown" when
data.session_id is missing, causing observations to be orphaned from the
generated codex_<timestamp> sessionId created in main() (SessionStart); change
observe(sessionData, hookType, observedData) to accept an explicit sessionId (or
pass the computed sessionId as an additional argument), use that sessionId as
the fallback instead of "unknown", and update all call-sites in main() that call
observe(...) so they pass the same sessionId value generated for the
SessionStart event.

In `@README.md`:
- Line 398: Update the ambiguous config path in the README table cell: replace
the project-scoped string ".codex/config.toml" with the user-global path
"~/.codex/config.toml" so it matches integrations/codex/ and the intended MCP
server scope; update the table row containing "Codex CLI / Desktop" (the line
with `codex mcp add agentmemory -- npx -y `@agentmemory/mcp``) to reference
"~/.codex/config.toml" instead of ".codex/config.toml".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bebe0feb-bd44-45e7-a592-83d0c55657a5

📥 Commits

Reviewing files that changed from the base of the PR and between 989e9c0 and 68d3171.

📒 Files selected for processing (3)
  • README.md
  • integrations/codex/README.md
  • integrations/codex/agentmemory-codex-hook.mjs

Comment thread integrations/codex/agentmemory-codex-hook.mjs Outdated
Comment thread integrations/codex/agentmemory-codex-hook.mjs Outdated
Comment thread integrations/codex/agentmemory-codex-hook.mjs
Comment thread README.md Outdated
@rohitg00
Copy link
Copy Markdown
Owner

rohitg00 commented May 9, 2026

Thanks @vybie — Codex Desktop / Codex CLI parity is on the Q3 Breadth roadmap and an early arrival is welcome. The two-layer setup (MCP for explicit tools + lifecycle hooks for auto-capture) is exactly the right shape, mirroring how the Claude Code plugin and the OpenCode plugin work.

What I like:

  • integrations/codex/ follows the same pattern as integrations/openclaw/ and integrations/hermes/ — discoverable, gated install, no automatic activation.
  • Single agentmemory-codex-hook.mjs that dispatches by hook event, instead of one script per event. Less to copy, less to break on rename.
  • Documents Windows path setup and the standalone-MCP fallback for users who can't run the full server (no Docker / no iii.exe).
  • README table entry includes the agentmemory-status / capture distinction so users understand "MCP gives you tools, hooks give you auto-capture" — that nuance is what tripped up the OpenCode users in Docs: setup gaps found during end-to-end OpenCode + Docker + Ollama install #233.

Asks before merge:

1. Test coverage for the hook bridge. The OpenCode plugin (#237) ships with the gap-analysis README; the OpenClaw plugin has its own dispatch. For Codex, please add at least:

2. Codex API stability disclaimer in the integration README. Codex hook event names and payload shape have moved a few times; please add a "tested against Codex Desktop X / Codex CLI Y" note so users know what version this works against. Same pattern as the OpenCode plugin badge.

3. AGENTMEMORY_URL and AGENTMEMORY_SECRET env-var handling. Confirm the hook script reads both when the agentmemory server is not on localhost:3111 and when bearer auth is set — the OpenClaw plugin handles this; please match that pattern so corporate / shared-server deployments work out of the box.

4. Avoid hardcoded console.log. Saw a single console.log in the diff — Codex hooks pipe stdout into the chat surface (per the statusMessage mechanism). Stray logs become user-visible. Should be console.error for any debug output, or guarded behind AGENTMEMORY_DEBUG=true.

Once those land, this is in scope for Q3 and a clean addition. Holding for @rohitg00 to merge.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/codex-hook.test.ts (1)

53-83: ⚡ Quick win

Add a per-process watchdog in runHook to avoid rare full-test stalls.

If the hook process regresses and never exits, this helper can block until Vitest’s global timeout. A local timeout makes failures fast and diagnosable.

Proposed change
 function runHook(
   payload: unknown,
   env: Record<string, string>,
 ): Promise<HookResult> {
   return new Promise((resolve, reject) => {
     const start = Date.now();
     const child = spawn(process.execPath, [HOOK_PATH], {
       env: {
         PATH: process.env["PATH"] ?? "",
         ...env,
       },
       stdio: ["pipe", "pipe", "pipe"],
     });
+    const watchdogMs = 5000;
+    const watchdog = setTimeout(() => {
+      child.kill("SIGKILL");
+      reject(new Error(`hook subprocess timed out after ${watchdogMs}ms`));
+    }, watchdogMs);

     let stdout = "";
     let stderr = "";
     child.stdout.on("data", (chunk) => {
       stdout += chunk.toString();
     });
     child.stderr.on("data", (chunk) => {
       stderr += chunk.toString();
     });
-    child.on("error", reject);
+    child.on("error", (err) => {
+      clearTimeout(watchdog);
+      reject(err);
+    });
     child.on("close", (exitCode) => {
+      clearTimeout(watchdog);
       resolve({ stdout, stderr, exitCode, tookMs: Date.now() - start });
     });

     child.stdin.write(JSON.stringify(payload));
     child.stdin.end();
   });
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/codex-hook.test.ts` around lines 53 - 83, In runHook, add a per-process
watchdog timer so a hung child is killed and the promise settles instead of
stalling the whole test run: start a setTimeout (e.g., WATCHDOG_MS) when
spawning the child, call child.kill() and either reject or resolve with a clear
timeout-specific HookResult (include stderr/stdout/exitCode hint or a distinct
error) if the timer fires, and clearTimeout on normal 'close' or 'error'
handlers; reference the runHook function, the spawned child variable,
child.kill(), and the existing child.on('close')/child.on('error') handlers to
integrate the watchdog and ensure the timer is cleared on normal completion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/codex-hook.test.ts`:
- Around line 53-83: In runHook, add a per-process watchdog timer so a hung
child is killed and the promise settles instead of stalling the whole test run:
start a setTimeout (e.g., WATCHDOG_MS) when spawning the child, call
child.kill() and either reject or resolve with a clear timeout-specific
HookResult (include stderr/stdout/exitCode hint or a distinct error) if the
timer fires, and clearTimeout on normal 'close' or 'error' handlers; reference
the runHook function, the spawned child variable, child.kill(), and the existing
child.on('close')/child.on('error') handlers to integrate the watchdog and
ensure the timer is cleared on normal completion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d19deef9-6edb-4bd4-9ea2-8c5df7900d80

📥 Commits

Reviewing files that changed from the base of the PR and between 5d34378 and 063c3dc.

📒 Files selected for processing (3)
  • integrations/codex/README.md
  • integrations/codex/agentmemory-codex-hook.mjs
  • test/codex-hook.test.ts
✅ Files skipped from review due to trivial changes (1)
  • integrations/codex/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • integrations/codex/agentmemory-codex-hook.mjs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants