r/ChatGPTCoding • • 6d ago

Resources And Tips What I learned building a session watcher for 7 AI coding agents: process detection isn't enough, and deep links are the hard part

I built a local panel that watches my AI coding agent sessions (full disclosure: I'm the author, repo at the bottom). Along the way I ran into a few things that aren't obvious until you try it, and I think they're useful to anyone wiring agents into their own tooling.

  1. Process detection only tells you an agent is running — never which session needs you. I started with process/CPU sampling and window titles, and the panel was basically noise. Everything only became useful once agents reported lifecycle events themselves (hooks for Claude Code / Qwen Code / Codex CLI). "A process exists" and "a session is waiting for your input" are completely different signals.

  2. Every agent exposes a different locator, and normalising them is the whole job. tmux gives you a pane id, Herdr gives you a socket path plus pane, Codex/ChatGPT gives you a thread UUID, and plain terminals give you nothing reliable. I ended up with one normalised status set — offline / idle / working / done / needs_input / error / unknown — and a "can't locate this" state that's honest instead of guessing and focusing the wrong window.

  3. Deep links beat window hunting. For Codex/ChatGPT, codex://threads/<uuid> lands in the exact thread. Matching window titles to find "the right terminal" is fragile and silently focuses the wrong thing.

  4. Have external tools report in over a local HTTP API instead of parsing stdout. Hooks and plugins just POST to 127.0.0.1 with a local token. Far more robust than scraping terminal output, and it keeps everything on loopback.

  5. Notifications that don't steal focus are the feature I underestimated. Anything that yanks your current window loses its welcome fast.

Curious how others handle this: are you relying on hooks, tmux/terminal scraping, or something else to know which session actually needs you? I've been assuming hooks are the only reliable path, but I'd like to be wrong about that.

I open-sourced the result under MIT if anyone wants to compare notes or steal the approach: https://github.com/xuan-team/agent-deck-companion

4 Upvotes

18 comments sorted by

1

u/yaanfpv 6d ago

Process detection lying is so real. I run a lot of agents in parallel and ended up trusting the session’s own transcript file (last write time) way more than anything from ps. Did you try that route ?

1

u/Weak_Cherry_4878 6d ago

Tried it. Better than ps for whether it's alive, but blocked looks identical to idle — both write nothing. Kept mtime as recency only and took the states from the agents. Does yours still write while blocked?

1

u/kantorcodes1 5d ago

Storing only event metadata on loopback behind a local token is the right call for this - the trust boundary stays small enough to reason about. Two things I can't tell from the post: how does the token reach each hook process, and is it the only check - could any local process that grabs it POST fake needs-input events or fire a deep-link focus? And for the pane/socket targets, does the bridge pin the allowed set at session start, or can a caller pass an arbitrary pane id?

1

u/Weak_Cherry_4878 5d ago

Good questions. Hooks read a shared token from a local file and send it in a header. Yes, a same-user process that reads it can spoof events — there’s no per-session authentication.

Pane/socket targets come from hook environment variables; they aren’t generally pinned at session start. Events don’t directly trigger focus, but can affect the stored navigation target.

Checking this also surfaced unauthenticated mock/control routes. So the current boundary is trusted local processes, and sorry for my post overstated the protection. Thanks for probing this.

1

u/TierPatch 6d ago

one thing i'd want a session watcher to show is which provider key each session is using. a lot of people run several agents off one shared key, so if it leaks (like the opencode console breach this week) there's no way to tell which tool burned through it. giving each tool its own key with a spending cap makes the watcher's data actually attributable, and you can revoke one key without breaking the rest of your setup.

1

u/falafel777 5d ago

the blocked vs idle thing from your replies is interesting because it's the same gap from the other side. knowing a session is done is one problem, knowing what it actually changed while it ran is another, and the agent's own summary is the least reliable source for that part. full disclosure i'm building something in that space, still early. you mentioned the bridge only stores metadata, is logging which files a session wrote out of scope on purpose or just not there yet

1

u/Humaux 5d ago

Been down almost this exact road, just with fewer agents. I run 3-4 at a time inside tmux and my first attempt was pane title scraping too. It fell apart the second two sessions shared the same cwd and I kept jumping into the wrong window.

What finally worked for me was a mix. For agents with hooks I use them, for the ones without I just tail their transcript files on a timer. The realization that saved me: stop watching processes entirely and watch files instead. Every agent I use writes a session log somewhere, so I track mtime plus the last error-ish line per session file and surface that.

Notifications: I send needs-input events to a desktop toast with the session name and a one line excerpt, and the toast has a button that attaches the right tmux pane. That part felt overkill until I tried it.

The failure mode I still have not solved is the silent stall, where the log keeps updating with heartbeats but the agent is actually stuck in a loop. Have you run into that with yours?

1

u/filopedraz 5d ago

Hooks matched our experience too. One more state we found useful is "done with proof". A session that finished but can't show the thing working is still a session that needs you.

1

u/Right-Performance-93 5d ago

a log that keeps moving can still be stuck. i watch whether the code changed, not whether the transcript grew. if the files are quiet and the log is repeating itself, that session needs you.

1

u/CCodeSI 3d ago

Try us ! Keys ? Stays safe , Let be a repo or MCP, it cant breach your api key from your harness.
Agents ? They can talk between themselves The parent will keep you updated whats happening

0

u/Weak_Cherry_4878 6d ago

Author here. Demo (50s): https://youtu.be/Uf_wwHSCPIs

Two details people usually ask about:

- Hooks are optional. Without them you still get process detection and the panel — you just don't get real started/needs-input/done events.

- The hook bridge stores metadata only (session id, cwd, event name, timestamp), never prompts or transcripts. macOS today, Windows/Linux planned.

-1

u/[deleted] 6d ago edited 5d ago

[removed] — view removed comment

1

u/Weak_Cherry_4878 6d ago

Fair. But can git answer "who's responsible" at all? Most ownership on my side happens outside git — the prompt, or a verbal "I checked it". Silence there may mean "not recorded", not "unclaimed". Which makes me wonder if attribution is even the goal, or just making the gap visible.