Skip to content

About

Rex program status records for the subagents, background tasks, monitors and scheduled checks of Claude Code and Codex agents

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

11 Commits

Folders and files

Repository files navigation

rex-agent-activity

See what your coding agents are still doing after they stop talking.

Rex shows whether an agent is working, blocked, done, or idle. It cannot tell you that a "done" Claude Code session is really waiting on a background shell, tailing a build with a monitor, or will wake itself up at 14:30 to check CI again. These hooks can.

They publish that work as extra records beside the agent's own program status, on the agent's own pane:

 record                       state    title
 (the agent's own)            done
 rsact/bg/bglint01            working  Run the test suite
 rsact/mon/bgwatch2           working  Watch the build log
 rsact/next/1793794440.loop   idle     Check CI

It tracks, per agent session:

  • Background shells started with run_in_background
  • Monitors watching a stream or log
  • Scheduled checks: session crons (CronCreate, /loop) and dynamic ScheduleWakeup loops, with the next fire time
  • Subagents of agents that do not report their own (Codex). Claude Code already reports its subagents to Rex, so they are left to it

It works standalone: there is no daemon and nothing else to install. Any Rex client can read the records (see CONTRACT.md). A Stream Deck plugin or a dashboard may use them to show more, and is optional in both directions: neither needs the other.

Verified against Rex API revision 10, with hook events recorded from Claude Code 2.1.318. Codex 0.166.0 hooks are only known from codex exec; its interactive mode has not been run.

Free to use. MIT. Not an official Rex or Elgato product.

Install

Requires Node.js 20+ on macOS or Linux, and an agent running in a Rex pane. Linux is tested without a Rex server.

npx github:Resilient-Software/rex-agent-activity install

or from a clone:

node bin/cli.mjs install

Restart running agents afterwards so they pick up the hooks.

Codex asks you to review the new hooks once per account on next launch; until then they do not run.

What it edits

Path What
settings.json in every Claude Code home (~/.claude, ~/.claude-N, $CLAUDE_CONFIG_DIR) Hooks, next to your existing ones
hooks.json in every Codex home (~/.codex, ~/.codex-N, $CODEX_HOME) Hooks, next to your existing ones
<file>.bak-rex-agent-activity A copy of each file above as it was before the first edit. Made once, and only if the file existed
${XDG_CONFIG_HOME:-~/.config}/rex-agent-activity/hook.sh The command the hooks run
${XDG_DATA_HOME:-~/.local/share}/rex-agent-activity A copy of this package's runtime
${XDG_STATE_HOME:-~/.local/state}/rex-agent-activity One small JSON file per active session and pane, and a size-capped log. Readable only by you. What a killed agent leaves goes after 30 days

--dry-run prints the files it would edit and changes nothing. --home <dir> limits it to that Claude Code or Codex home, and can be repeated. Both work with install and uninstall. A settings file that is a symlink is refused rather than replaced, and --dry-run reports that too.

Check it

npx github:Resilient-Software/rex-agent-activity doctor

or node bin/cli.mjs doctor from a clone. doctor lists each agent home and its hook count, whether the shim and runtime are in place, and the last lines of the log.

Uninstall

npx github:Resilient-Software/rex-agent-activity uninstall

or node bin/cli.mjs uninstall. This removes the hooks, the shim, the runtime and the state. A settings file you have not otherwise changed is restored byte for byte and its backup removed. If you changed it since, only the hooks are taken out and the backup stays. A file install created goes with its hooks, unless it has since gained something else. A file without these hooks is not touched, and neither are hooks belonging to anything else.

Uninstall cannot reach into a running pane: records already published stay until that agent exits cleanly. An agent that is still running may keep calling the removed hook until you restart it, and those calls fail.

How it works

Claude Code hooks (PostToolUse for background-capable tools, SubagentStart, SubagentStop, Stop, UserPromptSubmit, SessionStart, SessionEnd) feed a small reducer per session. Stop and SubagentStop carry Claude Code's own snapshot of running background tasks and session crons, which the reducer treats as authoritative, so missed events self-correct at the end of every turn. Task-completion notifications end tasks between turns.

The hook finds the agent's pty by walking up its parent processes, and writes OSC 7501 reports to it in writes of at most 512 bytes, never splitting a report. It never calls the rex CLI. A write stuck for 1.5 seconds kills the hook, never the agent, and later events finish what it could not. Hooks always exit 0 without writing to stdout. On Claude Code they run asynchronously and add no latency. On Codex they are not marked asynchronous and take about 200 ms per event on a Mac.

Stop, UserPromptSubmit and SessionStart rewrite every record, because Rex can drop one with no hook knowing. What has been published is tracked per pane, so a /clear, which starts a new session id, still clears the old session's records. On a clean exit Claude Code removes every record itself. An agent killed with SIGKILL can leave records behind; the next agent to start in that pane clears them if it runs these hooks.

The hook stays out of the way when REX_BLOCK is not set, in panes where another terminal multiplexer publishes its own activity, and in an agent started by another agent in the same pane, so a nested agent cannot clear its parent's records. A shell script named like the agent, such as a wrapper at ~/bin/claude, is not counted as another agent. An agent on a pty of its own, such as a worker under tmux or script, inherits REX_BLOCK but counts as a separate pane: it writes to that pty, keeps its own list of what it published, and cannot touch the session of the pane it came from.

Codex exposes fewer hooks: subagents are tracked (SubagentStart / SubagentStop); background shells and schedules are not visible to Codex hooks today. If you run Codex through its shared app-server daemon, its hooks have no pane to report to and do nothing; launch Codex with --no-daemon for per-pane activity. Not yet run under Rex.

There is no daemon, so a recurring check's next time refreshes on the next hook event.

Known limit

Reports reach Rex through the pty, the same way as the agent's own output. While a program floods the terminal with large writes, the kernel can split one of them, and a report can land inside one of its escape sequences and garble a line. In measurements on macOS this took about 1 MB/s or more of sustained output, and hit a few lines per hundred report writes. Hooks write little, mostly when a turn starts or ends, and only for sessions with background work.

Development

npm test
npm run e2e

npm test needs nothing but Node and is what CI runs. npm run e2e runs locally, because it needs a Rex binary and hosted CI cannot get one: it starts a throwaway Rex server on its own socket, runs a fake agent in one of its panes, fires bin/hook.mjs from inside that pane, and reads the records back through rex block call. HOME and the XDG directories point at a temp directory. It finds rex through REX_PATH, PATH or the macOS install location, and puts its files under E2E_TMP (default /tmp), which must be short enough for a unix socket path.

License

MIT © Resilient Software

About

Rex program status records for the subagents, background tasks, monitors and scheduled checks of Claude Code and Codex agents

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages