---
title: "Live status for every AI agent session with lifecycle hooks"
description: "Monitor Claude Code sessions with four states from lifecycle hooks, one command to wire them, and a live AI agent status dashboard right in your terminal."
date: 2026-07-22
reading_time: "6 min"
keywords: ["Claude Code hooks status","monitor Claude Code sessions","AI agent status dashboard terminal","AI agent lifecycle hooks"]
canonical: https://magent.now/blog/ai-agent-status-lifecycle-hooks
markdown: https://magent.now/blog/ai-agent-status-lifecycle-hooks.md
site: https://magent.now
publisher: DevinoSolutions
---

# Live status for every AI agent session with lifecycle hooks

Run more than two or three agent sessions at once and they turn opaque. Each terminal looks busy, but “busy” hides the difference between an agent grinding through a task and an agent that has been sitting on a question for ten minutes. So you do one of two bad things: alt-tab through every window on a loop, or miss the exact moment a session got blocked and wonder later why nothing moved.

The fix is not more discipline. It is a status signal that comes from the agents themselves, collected into one place you can watch. This post covers where that signal comes from, the one command that wires it up, and the two ways to consume it — a live table for you and a JSON feed for your scripts.

## Four states, straight from the agent

Every session sits in one of four states: `working`, `needs-input`, `done`, or `error`. The important detail is where those come from. They are **not** scraped off the screen by watching the terminal for prompts — screen-scraping is fragile and lies the moment an agent’s output format shifts. Instead they come from the agents’ own lifecycle hooks: the events Claude Code and Codex already emit as they start work, pause for input, finish, or fail.

That makes the state authoritative. When a session reports `needs-input`, it is because the agent itself said it is waiting on you — not because a heuristic guessed from the last line of text. And it means the same four states mean the same thing in both tools, so a mixed fleet reads as one board instead of two dialects.

## One command to wire the hooks

You do not configure each tool’s hooks by hand. [mAgent](https://magent.now/) (installed as `magent`) ships a setup step that wires the lifecycle hooks into Claude Code and hands you the one-line Codex recipe, in one shot:

```
magent hooks install
```

It is idempotent and leaves your existing hooks alone. Restart your agents after it runs so they pick up the new hooks. From then on, each session reports its own state changes as they happen — no polling, no scraping, no per-project config to maintain.

## The live table

With the hooks in place, `magent watch` renders every session in one table, sorted most-urgent first so the sessions that need you float to the top:

```
$ magent watch
#  project   tool     state
1  web       claude   needs-input
2  infra     codex    error
3  api       claude   working
4  worker    codex    done
```

The ordering is the point. You never scan the whole list — a `needs-input` or `error` row is always at the top, and a screen full of `working` means there is genuinely nothing for you to do. On Windows, pressing a row number jumps focus straight to that window, so acting on a blocked session is one keystroke, not a hunt through tiled terminals.

The other two states change your review rhythm just as much. A cluster of `done` rows is a signal to batch your diff reviews instead of interrupting yourself the instant each task finishes, and an `error` row that appears while you are heads-down on another window is the one thing you genuinely cannot afford to miss. Because the table encodes all four states rather than a binary busy/idle, it tells you not just _that_ something changed but _which_ kind of attention it wants.

> On Windows you can skip the table entirely. Run `pip install magent-multi-ai-agents-manager[toast]` and mAgent raises a desktop toast the moment any session flips to `needs-input`. Leave `watch` closed, keep working in another app, and let the notification pull you back only when an agent is actually stuck.

## Status for scripts and CI

The same signal is available as data. `magent status --json` prints the current state of every session in machine-readable form, and the command sets its exit code from the health of the fleet: `0` when everything is healthy, `3` when something is degraded. That pair — structured output plus a meaningful exit code — is enough to gate on:

```
# machine-readable snapshot of every session
magent status --json

# the exit code alone is enough to gate on
magent status || echo "fleet degraded (exit $?)"
```

Because the exit code carries the verdict on its own, the simplest use needs no JSON parsing at all — `magent status` in a script either passes or trips the degraded code, and you branch on that. When you do want detail, the JSON gives you per-session state to filter however you like.

## Where this fits, and how to get set up

Live status is the connective tissue for the rest of a many-session setup. It is what makes [running multiple Claude Code sessions in parallel](https://magent.now/blog/run-multiple-claude-code-sessions) sustainable instead of chaotic, and it is the signal that tells you to reach for your phone when you are away from the desk — see [controlling your AI coding agents from your phone](https://magent.now/blog/control-ai-coding-agents-from-your-phone) for how a `needs-input` state turns into a notification you can act on remotely.

The full walkthrough — installing `magent`, running the hook setup, and checking everything with `magent doctor` — is in the [install guide](https://magent.now/install). Once the hooks are wired, the table stops being a thing you build and starts being a thing you glance at. After a reboot, the same setup lets you [resume a Claude Code session after a restart](https://magent.now/blog/resume-claude-code-session-after-restart) in every project at once, with the status table back as soon as the agents are up.
