estruyf/claude-agent-watch-mod/tree/main/plugins/agent-watch
agent-watch
一个 Claude Code mod,将运行中的 Claude Code 会话数量控制在上限内,达到或超过上限时在提交提示时发出警告,并显示哪些会话正在等待你或处于空闲状态。
关于这个 mod
Agent Watch 会统计终端和桌面应用中的每个交互式 Claude Code 会话(不包含无头运行),并在其他工作中或等待中的会话达到可配置上限(默认为 3)时,于提交提示时发出警告,还会找出被遗忘的会话。它提供提示框上方的状态带、按等待中、空闲、工作中排序的 /agents-list 面板、/agents-limit <n> 覆盖值,以及根据 idleMinutes 发出的遗忘会话提醒。配置选项包括 limit、idleMinutes、strict、countSubagents 和 name。每个会话都会在 ~/.claude/agent-watch/<session-id>.json 下写入独立的状态文件,每 30s 发送一次心跳;超过 2 分钟的旧文件会被忽略。通过 /plugin marketplace add estruyf/claude-agent-watch-mod 和 /plugin install agent-watch@agent-watch-mod 安装。
安装
请先查看作者 README 确认 marketplace 和插件名称;命令可能随仓库结构改变。
claude plugin marketplace add estruyf/claude-agent-watch-mod claude plugin install agent-watch
原文 / README
Agent Watch
A Claude Code mod that keeps the number of running Claude Code sessions under a limit.
Run a few sessions side by side and it's easy to lose count, or to forget the one that has been sitting on a permission prompt for twenty minutes. Agent Watch:
- Counts every Claude Code session you have open, across terminals and the desktop app. Headless runs (
claude -p, scripts, CI) don't count. - Warns you on prompt submit when you're at or over the limit (default 3):
Hey Elio, be aware you are already running 3 agents. - Shows which sessions are waiting on you or sit idle, so you find the ones you forgot.
Why
AI agents are fast enough that it's tempting to start one more while the last one is still working, and then one more. Before you know it you're juggling five sessions, switching context all the time and no longer reading what they do. I wrote about this in The AI chaos beast in your head. One of the boundaries from that post is to run two or three agents I can actually follow, instead of five I forget about.
Agent Watch is that boundary, built into Claude Code. The default limit is 3, and it doesn't block you unless you turn on strict mode. It reminds you when you're about to start one more, and points at the sessions you've lost track of.
Screenshot
<!-- TODO: replace with a real screenshot: docs/screenshot.png -->Screenshot placeholder. Until there's a real one, here is a live session from testing (terminal, trimmed to fit):
❯ /agents-list
⎿ agent-watch: Agent Watch: 1 working · 1 waiting · 1 idle (limit 2).
╭──────────────────────────────────────────────────────────────────────────╮
│ 2 of 2 running · 1 working · 1 waiting · 1 idle ✕ │
│ ◆ waiting <1m agent-watch │
│ ○ idle <1m docs (this one) │
│ ● working <1m claude-agent-watch-mod │
╰──────────────────────────────────────────────────────────────────────────╯
1 working · 1 waiting · 1 idle (limit 2)
──────────────────────────────────────────────────────────────────────────────
❯
──────────────────────────────────────────────────────────────────────────────
agent-watch: Hey eliostruyf, be aware you are already running 2 agents.
Install
In Claude Code:
/plugin marketplace add estruyf/claude-agent-watch-mod
/plugin install agent-watch@agent-watch-mod
Or from a shell:
claude plugin marketplace add estruyf/claude-agent-watch-mod
claude plugin install agent-watch@agent-watch-mod
Restart your Claude Code sessions afterwards. Every session needs the plugin to be counted, since each session reports itself.
Update
/plugin marketplace update agent-watch-mod
/plugin update agent-watch@agent-watch-mod
Or claude plugin marketplace update agent-watch-mod && claude plugin update agent-watch@agent-watch-mod, then restart your sessions.
Use it
| What | Where |
| --- | --- |
| 3 working · 1 waiting · 2 idle | The band above the prompt, while other sessions are open. It adds (limit 3) in yellow once you reach the limit, and hides when this is your only session or a survey is showing. |
| The warning toast | On prompt submit, when the other sessions that are working or waiting reach the limit. A prompt typed while this session's own turn is already running doesn't warn, since that session is counted already. |
| /agents-list | Opens a pane listing every session with its folder, status and time in that state: waiting first, then idle (longest first), then working. |
| /agents-limit <n> | Overrides the limit for every session (stored in the plugin's store). /agents-limit shows the current limit, /agents-limit reset goes back to the configured one. |
| The forgotten nudge | A toast when another session has been idle or waiting on you longer than idleMinutes, once per session per state change. Only the session you prompted most recently shows it, so you don't get the same toast in every terminal. |
Why
/agents-listand not/agents?/agentsis Claude Code's built-in command for managing subagents, and plugins can't take over a built-in's name.
Session states
| State | When | Counts toward the limit |
| --- | --- | --- |
| Working | A turn is running (prompt.submit, turn.start) | yes |
| Waiting | Blocked on you: a permission prompt (classic.PermissionRequest), a permission notification (classic.Notification) or an AskUserQuestion | yes |
| Idle | turn.complete fired and no new prompt since | no, only shown in the band, the pane and the forgotten nudge |
| Removed | session.end (including /exit and /clear), or no heartbeat for 2 minutes | no |
Headless runs (claude -p) draw on no surface, so they write no status file and are never counted or shown. A desktop session counts from the moment its surface attaches.
Subagent turns don't change the state. A permission prompt raised by a subagent does make the session waiting, because it blocks on you all the same.
Configure
| Option | Default | What it does |
| --- | --- | --- |
| limit | 3 | How many other sessions may be working or waiting before the warning shows. |
| idleMinutes | 30 | When another session counts as forgotten. |
| strict | false | At the limit, hold the prompt instead of only warning. The prompt goes back in the box; press Enter again to send it anyway. |
| countSubagents | false | Also count this session's running background subagents (via $.agent.list()). |
| name | "" | The name the warning greets you with. Empty uses $USER. |
Set them in Claude Code with /plugin configure agent-watch@agent-watch-mod, or from a shell:
claude plugin configure agent-watch@agent-watch-mod # show the options and which are set
echo '{"limit":"4","strict":"true"}' | claude plugin configure agent-watch@agent-watch-mod --values-stdin
Both write pluginConfigs["agent-watch@agent-watch-mod"].options in your user settings. Restart your sessions to apply.
A /agents-limit override wins over the configured limit until you run /agents-limit reset.
How it works
Every session runs its own copy of the mod and writes its own status file:
~/.claude/agent-watch/<session-id>.json (under $CLAUDE_CONFIG_DIR when that is set)
{ "id": "...", "cwd": "/path/to/project", "status": "working", "since": 1790966403720, "heartbeat": 1790966433720, "prompted": 1790966403700 }
prompted is the last time you sent a prompt in that session (left out until you do). All sessions read the same files and pick the same nudger: the live session you prompted last, never one that is forgotten itself.
- One file per session, not a shared store, so sessions never overwrite each other.
- Heartbeat every 30 s (
$.clock.every) rewrites the file. The other sessions' files are read every 10 s so the band stays current. - Files with a heartbeat older than 2 minutes are ignored, so a crashed session drops out by itself.
- On
session.endthe file is markedended.$.fshas no delete, so ended and stale files older than an hour are removed withrm -f(on systems withoutrmthey're only ignored). - Runtime values (the session list, this session's status, the limit, what has been nudged) live in
$.state, so a hot reload keeps them.
Develop
git clone https://github.com/estruyf/claude-agent-watch-mod
cd claude-agent-watch-mod
claude plugin validate plugins/agent-watch # the manifest and the hooks module
claude plugin validate . # the marketplace
claude plugin test plugins/agent-watch # 32 tests
claude --plugin-dir plugins/agent-watch # run it; saving a file hot-reloads it
To try options without touching your settings:
claude --plugin-dir plugins/agent-watch \
--settings '{"pluginConfigs":{"agent-watch@inline":{"options":{"strict":true,"limit":1}}}}'
Layout:
.claude-plugin/marketplace.json the marketplace, listing ./plugins/agent-watch
plugins/agent-watch/
.claude-plugin/plugin.json manifest and userConfig
hooks/hooks.json names the hooks module
hooks/register.tsx every hook: registry, nudge, pane and band
hooks/shared.ts pure helpers (parsing, counting, sorting, formatting)
types/index.d.ts the $.state contract
tests/*.test.ts claude plugin test
.claude-plugin/types/ inside the plugin is written by Claude Code each time it loads the mod and is git-ignored. tsc -p plugins/agent-watch type-checks against it once the mod has loaded once.
License
MIT
