Skip to content

feat(hooks): native Codex hooks name a Codex pane's session on herdr-core - #727

Open
evrimalacan wants to merge 2 commits into
AltanS:mainfrom
evrimalacan:feat/codex-native-session-herdr-core
Open

evrimalacan wants to merge 2 commits into
AltanS:mainfrom
evrimalacan:feat/codex-native-session-herdr-core

Conversation

@evrimalacan

Copy link
Copy Markdown

Codex panes on herdr-core have no session, so the phone shows no Chat or History for them. Claude panes get theirs from the hook (M74, and #647 on macOS). This does the same for Codex with Codex's own lifecycle hooks.

What it does:

  • collie hooks install codex --native adds Collie's entries to $CODEX_HOME/hooks.json for SessionStart, UserPromptSubmit, Stop and SessionEnd. Other handlers stay, and uninstall removes only Collie's. The notify install is unchanged.
  • Each entry runs collie beacon codex-hook. It finds the Codex TUI that runs the hook, reads the pane markers from its environment, writes hook edges, and outside the Herdr TUI also a beacon with harness codex and the session id.
  • If the host is the shared codex app-server daemon or codex exec, it writes nothing, because that environment names no pane or the wrong one. So Chat needs codex --no-daemon, and the docs say so.
  • bridge/beacon-io.ts: the hooks-installed probe also reads Codex's hooks.json, so a host with only Codex hooks still joins beacons.
  • collie doctor gets a beacon-hooks-codex row. On herdr-core, the hint for a Codex pane now points at this install, not at herdr integration install codex.

Relation to #596: this takes the lifecycle hook part of #596 by @djbclark (co-author on the commit), without the permission broker and Moshi, as you suggested there. #596 writes edges only. That is enough on the Herdr TUI, which names the session itself, but on the core nothing names it, so this adds the beacon.

Tested live on macOS 27.0.1 arm64, herdr-app 0.1.11, hc 0.1.16, Codex 0.167.0, with a 1.26.4 bridge:

  • a codex --no-daemon pane wrote a beacon with its own session id and pane, collie sessions showed SESSION yes, and the phone showed Chat for it
  • after /new, SessionStart fired at the next prompt with the new id, and the beacon followed it
  • a spawned sub-agent fired no hooks, so it cannot take over the pane

Not tested live: tmux, zellij and Linux.

Base branch — see CONTRIBUTING.md:

  • Opened against main — there is one line of development, and main is it

Checks

  • bun run typecheck (root and web/), bun run lint, bun test ./bridge ./cli ./scripts, cd web && bun run test all pass
    • Both typechecks, lint and cd web && bun run test pass.
    • bun test ./cli (11), ./bridge (263) and ./scripts (2) fail only tests that fail the same way on main on this Mac: the /var symlink, the Keychain wording, and pi's examples folder.
  • CHANGELOG entry added under ## [Unreleased], below one of ### Added / ### Changed /
    ### Fixed / ### Packaging / ### Docs, opening with a bold lead sentence
    (- **The lead sentence.** the detail …), no commit hash. A fork PR or a docs-only
    change is exempt, the maintainer picks the version there
    • Fork PR, so no entry. Proposed line:
      - **Codex panes on herdr-core get Chat and History.** \collie hooks install codex --native` adds Collie's entries to Codex's own `hooks.json`, and each one names its pane's Codex session. Start Codex as `codex --no-daemon` and trust the hooks when Codex asks; `collie doctor` reports them in `beacon-hooks-codex`. Thanks @djbclark (feat(hooks): native Codex hooks and macOS process probing #596).`

Written with Claude Code and reviewed with Codex.

evrimalacan and others added 2 commits November 6, 2026 14:59
…core

herdr-core knows that a terminal runs Codex, but not which conversation.
So a Codex pane there had no Chat and no History. Claude panes have both,
because Collie's Claude hook writes a beacon that names the session.

`collie hooks install codex --native` adds Collie's entries to Codex's own
$CODEX_HOME/hooks.json, for SessionStart, UserPromptSubmit, Stop and
SessionEnd. Each entry runs `collie beacon codex-hook`. The verb writes a
hook edge for the pane and, outside the Herdr TUI, a beacon with harness
codex and the session id. It prints nothing and always exits 0.

The verb finds its host by climbing past shells to the parent, then reads
the host's arguments. Only a Codex window counts. Plain `codex` runs hooks
in its shared app-server, with that process's environment, so a hook from
there writes nothing. Codex has to run as `codex --no-daemon`.

The install keeps every other handler, appends its own, is idempotent, and
the uninstall removes only Collie's entries. `hooks status`, a new doctor
row `beacon-hooks-codex` and the bridge's "hooks installed" probe read the
file too. On herdr-core the doctor note for a Codex pane with no session
now points at the native install and --no-daemon, not at Herdr's
integration.

The notify install (`hooks install codex`) stays as it is.

Co-authored-by: Daniel JB Clark <djbclark@gmail.com>
…erdr-core

A new section, Codex native hooks: the install, the "Hooks need review"
trust step, why Codex must run as `codex --no-daemon`, the four events,
how the install treats hooks.json, and the limits. The herdr-core notes,
the troubleshooting page and the Chat table in configure.md name the
Codex install beside the Claude one.
@github-actions github-actions Bot added documentation Improvements or additions to documentation area: bridge Bun/TS bridge — Herdr socket, state engine, polling, REST area: web Phone PWA — UI, mirror, composer, service worker area: harness Per-agent adapters and send guards (claude/codex/pi/omp) area: install bin/collie verbs, Herdr plugin lifecycle, update, tailscale serve enhancement New feature or request labels Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: bridge Bun/TS bridge — Herdr socket, state engine, polling, REST area: harness Per-agent adapters and send guards (claude/codex/pi/omp) area: install bin/collie verbs, Herdr plugin lifecycle, update, tailscale serve area: web Phone PWA — UI, mirror, composer, service worker documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant