Skip to main content

Codex Integration

Pad-Lattice has three Codex CLI integration paths:

InterfaceConnectionControls
Desktop (recommended for interactive use)Existing local app-server threadSingle-request Approve/Reject and turn-specific Stop
Python CLIScoped lifecycle hooksPermissionRequest Approve/Reject
Non-interactive CLIcodex exec --json streamStop the selected task

Desktop connections need no hooks or terminal restart. See Desktop Architecture for discovery, attachment, and request routing. The rest of this page covers the independent CLI paths, which work without the desktop app.

Launch with Scoped Hooks​

Start Codex through the Pad-Lattice launcher:

pad-lattice codex --label implementation

The launcher passes seven lifecycle handlers to that child Codex process using session configuration. It does not modify ~/.codex/hooks.json, so ordinary codex sessions neither run Pad-Lattice hooks nor ask users to review them. Run /hooks in the first Pad-Lattice-launched session to review and explicitly trust the commands. A materially changed definition requires another review.

Codex hookPad-Lattice state
SessionStartidle (Ready)
UserPromptSubmitrunning
PermissionRequestwaiting_for_approval; wait for a surface decision
PostToolUserunning
Stopsuccess, then idle (Ready)
Interruptcancelled
SessionEndRemove the session

The hook forwards session_id as the stable agent identity. Working directory, model, and label are display metadata, never identity keys. Simultaneous sessions occupy separate slots; an update from an unselected session changes only its compact status indicator.

Integrated Launcher​

Use the Pad-Lattice launcher for labeled terminals and reliable cleanup:

pad-lattice codex --label implementation
pad-lattice codex --label docs -- resume <SESSION_ID>

Everything after -- is passed to Codex unchanged when an explicit separator is useful:

pad-lattice codex --label review -- --ask-for-approval on-request

This is a thin process launcher, not a terminal emulator. Codex inherits the real stdin, stdout, and stderr. The launcher keeps a reconnecting Unix-socket lease open and sets a terminal title such as [S2 MAGENTA] docs. Closing or terminating the child closes the lease, clears its Scene, and never silently selects another agent.

--no-terminal-title leaves Codex's normal title behavior unchanged. Without --label, the hook uses the Codex working-directory name.

Use the live screen legend when several agents are active:

pad-lattice status --watch

The legend matches Scene number and accent to label, project, state, short session ID, and lease status.

Surface Approval and Rejection​

For a Codex permission request:

  1. The requesting session changes to the amber approval state.
  2. Select its right-side Agent Scene if it is not already selected.
  3. Press or tap the lit green Approve or red Reject control.
  4. The hook returns a one-request allow or deny decision directly to Codex.

Each pending request has a unique request ID. One press reaches exactly one selected request; concurrent requests for the same agent are handled in arrival order and actions are never broadcast. Approve does not create a persistent permission rule.

The hook waits 60 seconds. A timeout, unavailable daemon, or disconnected surface returns control to Codex's normal keyboard approval prompt. Action controls are completely dark when no live request can consume them.

This path uses Codex's supported PermissionRequest hook output. It does not scrape terminals or inject synthetic keys.

Plain Codex Sessions​

Plain codex and codex resume sessions do not load Pad-Lattice hooks. Desktop can connect them explicitly through the app-server. For CLI-only surface control, start or resume through pad-lattice codex:

pad-lattice codex --label docs -- resume <SESSION_ID>

Hook Action Boundary​

PermissionRequest provides a supported decision point for Approve and Reject. Interactive Stop, Retry, and ordinary yes/no chat replies are not permission decisions and remain unavailable through hooks. Desktop's app-server connection provides turn-specific Stop, but not Retry or ordinary replies.

Hooks do not expose individual keystrokes, so live user_typing state is also unavailable.

Non-Interactive Tasks​

Use codex-exec for a real Codex CLI run with JSON-line events:

pad-lattice codex-exec "summarize this repository"

The adapter maps these events:

Codex eventPad-Lattice state
thread.startedrunning
turn.startedrunning
item.startedrunning
turn.completedsuccess
turn.failederror
errorerror

Each invocation generates a unique agent identity and subscribes only to Stop. After selecting that task on a surface, the common top-rail Stop control (mapped to CC 98 on Launchpads) terminates that process without affecting another concurrent codex-exec task.

Hook Trust and Scope​

Codex records trust against the exact hook definition. Pad-Lattice emits the same deterministic definition for the same executable, socket, and timeout, so an accepted definition is reusable by later Pad-Lattice-launched sessions. The hooks remain scoped to those sessions.

Use --socket PATH when the daemon runs on a non-default socket. The launcher passes the same resolved path to its hook commands:

pad-lattice codex --socket /tmp/pad-lattice.sock --label docs

Set a different surface-decision wait on the launcher:

pad-lattice codex --approval-timeout 90 --label implementation

The Codex handler timeout includes a five-second shutdown margin. Changing the socket, timeout, or executable changes the exact definition and may require a new review.

Early Pad-Lattice alpha builds installed global hooks. Remove only those legacy entries, while preserving unrelated hooks, with:

pad-lattice uninstall-codex-hooks