How do you stay aware of what your AI coding agents are doing?

by

I've been running Claude Code, Cursor, and Codex pretty heavily for the last few months and I keep hitting the same loop:

1. Start a task in one agent

2. Switch to something else (Slack, Twitter, another terminal)

3. Come back 30-40 minutes later

4. Agent finished 35 minutes ago. Or worse, it's been waiting for my approval the entire time.

The more agents I run, the worse it gets. There's no unified way to know what's happening across them.

Curious what other people's setups look like:

- Do you just keep terminals visible and check manually?

- Built any custom notification scripts?

- Use something like ntfy or Pushover?

- Just... accept the wasted time?

I've been building something in this space (push notifications + approval flows for AI agents) and I'm trying to understand if everyone's workflow is as janky as mine, or if some of you have figured out something clever.

Would love to hear what's working and what's not.

5.1K views

Add a comment

Replies

Best

I feel this problem a lot. The painful part is not only "notify me when it is done"; it is the ambient state in between: is Claude Code still working, did Codex stop for input, did a session stall, or am I just wasting attention checking terminals?

Pushary's phone/approval direction makes sense for teams and cross-device workflows. I built a smaller local-first version for my own Mac workflow: Agent Island sits in the Mac top bar/notch for Claude Code + Codex, shows live state, rings when it is your turn, and keeps usage/cost/reset clocks visible.

Different surface, same underlying problem: agent runs should not own your attention.

If useful for Mac users, I put it here:

 

"Agent runs should not own your attention" is the cleanest one-line statement of the whole problem I've seen, and Agent Island is a sharp take on it. Putting live state in the notch is the right instinct, ambient awareness your eyes catch for free instead of another thing you have to actively check. That's the move.

We landed on the same split from different ends: you're solving the at-desk, different-window case with something glanceable, I'm solving the away-from-keyboard case with push. The honest read is those are complementary, not competing. The notch is perfect while you're at the machine and can't help you the moment you walk away, and a phone push is overkill when the terminal's six inches from your eyes. Same underlying belief, two different distances from the screen.

The "rings when it's your turn" part is the one I'd dig into, because that's the hard bit, since a stalled agent and a thinking agent look identical from outside. Curious how you're detecting "your turn" for Claude Code and Codex, native hooks, or watching the output? That detection is where I keep finding the real work is. Nice build, genuinely.

How do you stay aware of what your AI coding agents are doing?


 

just use pushary and you get the ping on your phone when your agents need you

I've found that treating AI coding agents like junior developers works best. One thing I've learned is that the biggest risk isn't usually syntax errors—it's when the AI confidently changes business logic or makes assumptions about how the application should behave.

 

You've named the failure that actually hurts, and the word carrying it is "confidently." Syntax errors are loud, they don't compile, they get caught, they're cheap. Confident business-logic changes are silent, they run fine, they pass, they look intentional, and they're wrong in a way only someone who knows the domain would spot. The dangerous failure isn't the one that breaks, it's the one that works while doing the wrong thing.

And your junior-developer framing explains why. A junior makes exactly this mistake, does something technically correct that violates an unwritten rule about how the business is supposed to behave, because they don't have the context yet. The difference is a junior gains that context over time and an agent starts fresh every session, so it never accumulates the domain sense that would stop it. It's a permanent junior, which means the guardrails can't be temporary training wheels, they're the permanent substitute for judgment it won't develop on its own.

The practical problem is these changes hide precisely because they look reasonable. A diff that alters business logic reads as plausible, so it slips past a tired review, and the agent won't flag it because it thinks it's helping. That's what makes it worth catching mechanically: the agent stating what it intended versus what it actually touched, so a change to logic you didn't ask it to touch surfaces as a deviation instead of blending into a green-looking diff.

Curious, when it does confidently change business logic on you, is it usually because your instruction was ambiguous enough to leave room, or does it invent an assumption even when you were fairly specific? Those need different fixes, and I keep going back and forth on which one bites people more.

I've been hitting the same thing with Claude Code and Codex. The time loss is annoying, but the bigger cost is coming back after 30 minutes and losing the mental context of what I asked the agent to do.

The setup that feels healthiest to me is: notify only when blocked or done, include the exact question plus a tiny diff/log snippet, and require explicit approval for risky actions. Otherwise every agent just becomes another inbox.

Curious if Pushary is thinking more about interruption quality, not just faster pings.

 

Direct answer: yes, interruption quality is the whole bet, and "otherwise every agent just becomes another inbox" is exactly the failure I'm trying to avoid. Faster pings without better payload just means you get overwhelmed sooner. A ping is only worth sending if it saves more attention than it costs, and most notification tools quietly cost more than they save.

The context loss you named is the sharper half, and I think it's underrated. The wasted 30 minutes is the visible cost. The reload, coming back and reconstructing what you even asked for, is the expensive one, because it's not just time, it's getting back into the headspace you left. A bare "done" ping fails precisely here: it pulls you back and abandons you to the scramble. That's why the payload has to carry the reload, the question plus the intent plus a tiny diff, so you pick up where you were instead of rebuilding it. The notification's real job is killing the reload, not announcing the finish.

And your rule set is basically the spec: notify only on blocked or done, carry the exact question and a snippet, gate only the risky stuff. The "only risky" part is what keeps it from becoming an inbox, gate everything and you train people to rubber-stamp, and then the channel is dead.

Curious about your "include the exact question plus a tiny diff" line, when you come back, do you trust the snippet enough to answer from it, or do you still open the full thing before you say yes? I'm trying to figure out how much people will actually decide from the payload versus treat it as a nudge to go look.

our setup ended up being a Slack webhook per agent session, posted to a channel only that agent writes to. sounds basic but the key part was making the notification say WHY it's waiting (needs approval vs finished vs blocked on an error) instead of just "done" - that one change cut our check-in time a lot because you can triage from the notification itself instead of tabbing back in every time. the 30-40 min context switch cost you're describing is real, most of it isn't the waiting, it's re-loading what the agent was even doing when you come back.

 

The Slack-webhook-per-session-in-its-own-channel setup is smarter than it sounds, because the channel-per-agent gives you a persistent per-agent thread for free, so you're not reconstructing history, it's just there in scrollback. You routed around half the problem with infrastructure you already had.

But the change you flagged is the actual insight, and it's bigger than it looks: making the notification say why it's waiting is what turns a ping into a triage. "Done" makes you tab back to find out what "done" means. "Needs approval vs finished vs blocked on error" lets you decide before you move. That's the difference between a notification that relocates the work and one that carries the decision. The three-state why is doing all the work.

And your last line is the thing most people miss entirely. The 30-40 minutes isn't mostly the waiting, it's the reload, rebuilding what the agent was even doing when you come back. Which means the fix isn't a faster ping, it's a ping that carries enough context to skip the reload. The why-state gets you the triage; the next step up is a line of what-changed so you don't just know why it stopped but where it was, and you pick up cold instead of scrambling.

Curious, with the per-agent channels, did you ever want to answer from Slack, approve the thing right there, or was it purely one-way and you still tabbed back to the terminal to act? That send-vs-respond line is the one I keep poking at.

 Honestly, mostly one-way still. We did add a "yes/approve" button for the narrow case where the ask is literally binary (run this migration, y/n), and that works fine from Slack. But the moment approving means actually looking at a diff or reasoning about what changed, a button in a notification isn't enough context to decide responsibly, so we end up back at the terminal anyway. What we changed instead was making sure the terminal state was exactly where we left it, not re-deriving it, so the trip back is fast even if it still happens. Trying to force real judgment calls into a Slack reply felt like it was going to produce worse approvals just to save the extra click.

 

You landed exactly where I did, and for the right reason: forcing a real judgment call into a Slack reply produces worse approvals just to save a click. The binary stuff (run the migration, y/n) is fine from a button. The moment it needs a diff, a button is just rubber-stamping with extra steps. So the bet isn't "approve everything from your phone," it's make the trip back cheap when it has to happen, which is basically what you did by preserving terminal state instead of re-deriving it. Same instinct.

Couple of things Pushary does around this that might land for you. It logs which dev approved which permission, so the postmortem isn't guesswork later. There's a detection autopilot that flags when an agent touches a file it wasn't supposed to, surfaced in the audit trail rather than discovered three commits deep. And yeah, there's a native Slack plugin, so the per-channel setup you already built isn't something you'd have to throw away.

Curious about your "keep the terminal state exactly where we left it" bit, is that something you rigged yourself, or a property of the tools you're running? Because fast-trip-back is underrated and I'd love to know how you're actually holding that state.

I have been running Claude Code and Codex in parallel for a few months. The loop you described is real. Start a task. Switch to something else. Come back. The agent finished 35 minutes ago, or it has been waiting for approval the whole time.

Here is what I have learned.

The terminal is not a good notification system. You cannot keep it visible on another screen. You cannot rely on visual memory. If you look away for five minutes, you lose track. The only reliable way is an external ping.

We built a simple Slack integration. Each agent sends a message when it starts, when it finishes, and when it needs approval. It is not sophisticated. It is just consistent. It saves the cognitive load of checking every terminal.

We also started logging agent activity. Not just the output. The decisions. The prompts. The reasoning. It helps when you come back and need to understand what happened while you were away.

The worst failure mode is the silent wait. The agent finishes. It does not notify you. It sits idle for 30 minutes. The next task gets delayed. The cost compounds across multiple agents.

The approval flow is the hardest part. Agents that wait for human input break the async workflow. We are experimenting with a "pending approval" queue that surfaces all open requests in one place.

The more agents you run, the worse it gets. The solution is not fewer agents. It is better orchestration.

What is your current setup for agent notifications?

Imed Radhouani
Founder & CTO – Rankfender

 

"The terminal is not a good notification system" should be the first line of the spec, and you're right about why: it demands active looking, and the whole premise of running agents is that you've looked away. A notification system you have to watch isn't one. The external ping isn't a nice-to-have, it's the only thing that survives the fact that your attention is legitimately elsewhere.

Your Slack setup being "not sophisticated, just consistent" is the actual lesson, and it's the one most people skip past chasing features. Consistency beats cleverness here because the value is trust, if it pings reliably on start/finish/approval every time, you stop checking terminals, and that's the whole win. A fancy notifier that fires 90% of the time is worse than a dumb one that fires 100%, because the 10% gap puts you right back to babysitting.

The activity logging is the part I'd underline, because you logged the right thing: not just output, but decisions, prompts, reasoning. Output tells you what changed. The reasoning tells you why, and the why is what you actually need when you come back cold, because reconstructing intent from a diff is the expensive part. Most people log the cheap half.

Your pending-approval queue is the piece I'd push furthest on, because it's where per-agent notifications stop scaling and orchestration begins. One inbox of all open requests across every agent is the difference between N notification streams and one control surface, and it's exactly right that the answer to more agents is better orchestration, not fewer agents.

To your question: consistent state-change pings (done/blocked/needs-input) with a payload that carries the why, plus that unified approval queue, is basically the setup, we're building the detection and the cross-tool inbox as the core. Genuine one back, since your queue is further along than most: when a request sits in the pending queue, do you order it by anything, urgency, how long it's been waiting, risk of the action, or is it just chronological? Because that prioritization is the thing I keep chewing on, a queue that treats "approve a file write" the same as "approve a prod migration" loses the plot fast, and I'm curious whether you've hit that yet.

With (launched today!) my workflow is to setup git worktrees with my mono-repo, and have terminal tabs in rotation one by one, whenever task finishes I clear the tab for future use. If it is still ongoing I skip.

Good sides:
- I never interrupt my thinking based on agent timeline (does not work for me)
- Can have 6-7 parallel agents with the size of tasks I give
- With modular repository, rarely huge merge conflicts, I merge locally mostly as a solo dev

Bad:
- maxmimum context swithing
- Agents are waiting many times as I have 5 more agents to guide first
- reviewing the output is somewhat hard, hard to use with regular code editors (manageable though)

 

This is a genuinely well-tuned setup, and the part I respect most is that you optimized for the thing most people sacrifice first: "I never interrupt my thinking based on agent timeline." You built the whole workflow around protecting your focus rather than the agents' idle time, which is the right priority for a solo dev. The worktree-per-task plus tab rotation plus modular repo is a coherent system, each piece is solving a real failure (collisions, merge hell, focus fragmentation), and it clearly holds at 6-7 agents, which most people can't say.

But look at your own three "bad" points, because they're not really three problems, they're one problem wearing three hats: you are the scheduler. Maximum context switching, agents waiting while you guide the other five, hard-to-review output, all of it traces back to you being the single serial resource that every agent has to queue behind. The rotation is you hand-executing round-robin, and a human round-robin has a hard ceiling: throughput is capped by how fast you can cycle, and every agent that finishes or blocks while you're on a different tab is idle until your rotation comes back to it. Your system scales the agents beautifully and doesn't scale you, which is why the pain shows up as your context-switching cost.

The interesting bit is that your "I skip if it's ongoing, clear if it's done" check is already a state-poll, you're manually reading done-vs-running every rotation. That's the exact signal worth pushing to you instead of polling for. If "done" and "blocked" tapped you rather than you tabbing through to discover them, the rotation stops being mandatory and becomes on-demand: you only visit the tab that actually needs you, which collapses the context-switching from "cycle all 7 every loop" to "handle the one that pinged." Same setup, minus you being the polling loop.

Your hardest "bad," though, is the review one, and it's the deepest: reviewing output across 6-7 worktrees is hard because the diffs are scattered and you're reconstructing what each agent did from cold context every time you land on its tab. That's the reload tax, and it's separate from the notification problem. A ping tells you when to look; it doesn't make the looking fast. The thing that'd actually help there is each agent handing you a tight what-changed summary at finish, so landing on a done tab is a ten-second scan instead of re-deriving the session.

Congrats on the ScreenCI launch today, by the way. Genuine question, since you've run this longer than most: when an agent finishes and you're deep in guiding another, do you lose more time to the switch itself, or to reloading what the finished agent was even doing when you get to it? Because those point at different fixes, and your setup is the best real-world test I've seen of which one actually dominates.

we went with a persistent feed panel — the loop agent posts status lines into it via a /notify endpoint as it works, so you can glance from any page without switching to a terminal. works well when you're at the desk. your push approach clearly wins when you're away. what's the latency on the approval ping — does it reach you fast enough before the agent times out waiting?

 

Direct answer to the latency question first, since it's the real one: the ping itself is near-instant, the agent hits a blocked state and the push is out in a second or two, that part's easy. The actual constraint isn't delivery speed, it's the agent's timeout window, and the honest answer is that "before it times out" only works if the agent is configured to wait indefinitely on a blocked approval rather than auto-proceeding or failing after N seconds. A push that arrives in two seconds is useless if the agent gave up after thirty and the human takes five minutes to surface from something else. So the real design isn't "make the ping faster than the timeout," it's "remove the timeout from the equation", the agent parks and holds, blocked, until an answer comes back, however long that takes. The ping's job is speed; the hold is what makes speed not matter.

Which is why the hook quality matters more than the network latency. If you're intercepting the agent's native approval event (Codex exposes this cleanly), the agent is genuinely paused waiting for a response, not on a countdown, so there's no race against a timeout at all. The failure mode you're worried about, ping arrives after the agent already moved on, comes from scraping or inferring the block rather than catching the real pause, because then you're reacting to a state the agent doesn't consider blocking. Catch the real approval event and the timeout question mostly dissolves.

Your persistent feed panel is the right call for the at-desk case, and I think we've independently drawn the same line you did: your /notify feed is glanceable-while-present, the push is for when you're away, and those genuinely are complementary rather than competing. The feed panel actually has one advantage push doesn't, it's ambient, you catch it in peripheral vision without an interruption, which is strictly nicer than a notification when you're already at the machine. Push is overkill six inches from the screen. So the ideal is probably both surfaces fed by the same state events, feed when present, push when absent.

Genuine question back, since your feed is already taking structured status lines: do those lines include the blocked-waiting-for-approval state, or mostly progress and done? Because if your /notify endpoint is already receiving "I'm blocked," you're one route away from that same event firing a push for the away case, and the interesting bit is whether your agent emits blocked as a distinct status or just goes quiet, which is the exact detection seam I keep hitting.

  yes — blocked-waiting-for-approval is a distinct event in the feed, tagged with its own kind marker so it's visually different from progress lines. the agent pushes it explicitly when it needs input, not inferred. so the event is there and cleanly identifiable. the "goes quiet" failure mode you described is the real edge case — if the agent bypasses the notify call entirely it just disappears, which is why the hook level is ultimately more reliable than application-level signaling for that detection seam.

 

That's the whole thing right there, and you've correctly identified why your setup is one step away from bulletproof rather than actually bulletproof. Blocked being an explicit tagged event the agent pushes, not inferred from silence, means you've solved the detection problem in the happy path, the agent tells you, you don't guess. That's already better than most of what's in this thread.

But the failure mode you named is the exact one that matters, and it's subtle: application-level signaling can only report the states the agent remembers to report. If the agent bypasses the notify call, errors before it, or stalls in a way that never reaches the /notify line, it just vanishes, and a vanished agent looks identical to a working one. The gap isn't in your event schema, it's that the schema depends on the agent's cooperation, and the moment you most need the blocked signal, something went wrong, is exactly when you can least trust the agent to have fired it.

Which is why you landed on the right conclusion: the hook level is more reliable because it's outside the agent's control flow. A hook fires because the runtime is about to do a thing, whether or not the agent's logic remembered to announce it. Application-signaling trusts the agent to narrate itself; hook-level observes the agent from a layer it can't skip. For the happy path they're equivalent, and for the silent-failure edge case, only the hook survives, because it doesn't ask permission from the code that might be broken.

The honest tradeoff, and the reason I've ended up hook-first on the tools that expose them: hooks are per-runtime and a pain, you get a clean one from Codex, a partial one from Cursor, so you're maintaining N adapters instead of one notify contract. Application-level is portable and easy and lies to you at the worst moment; hook-level is fragmented and annoying and tells the truth. Curious whether, for your feed, you'd consider a belt-and-suspenders setup, keep the explicit notify for the rich payload, add a hook purely as the liveness backstop that catches the disappearances, or whether the per-runtime cost isn't worth it for your use case.

For me, it's not just knowing when an agent finishes it's knowing what happened while I was away.

By the time I come back, I've often lost the reasoning, decisions, or useful context from the session, especially if I'm jumping between ChatGPT, Claude, Cursor, and Codex. Instead of only tracking notifications, I want preserve the conversations and context across different AI tools (including temporary chats), so I can pick up where I left off without relying on each tool's own history.

 

You've named the second half of the problem, and it's the one that survives even after notifications are solved. Knowing when an agent finished gets you back to the desk. It does nothing for the fact that the reasoning, the decisions, the why behind what happened evaporated while you were gone. The notification fixes timing. It doesn't fix amnesia. You can be pinged the instant something finishes and still land in a session with no memory of how it got there.

And the cross-tool angle is what makes it genuinely hard, because you've spotted that context doesn't just evaporate over time, it fragments across tools. Each of ChatGPT, Claude, Cursor, Codex keeps its own history in its own silo, so even the memory that does persist is scattered into four places that don't talk to each other. Your context isn't one thread you lost, it's four half-threads in four apps, and reconstructing what actually happened means stitching them back together by hand. Relying on each tool's own history means there's no your history, only theirs, partial and locked in.

The distinction I'd draw, because it's where this splits from the notification problem: what you're describing is a memory-and-continuity layer, and it's a different substrate than a state-and-approval layer. One is "tap me when I'm needed," yours is "let me resume as if I never left." They're complementary, not the same product, a ping with no preserved context just teleports you back into a wall of scrollback, and preserved context with no ping means you never know when to come back. The complete thing is both, but they're genuinely different builds, and the memory one is arguably the deeper problem because it's about reconstructing meaning, not just detecting events.

The hard part I keep hitting on the memory side, and I'd ask since you're clearly building toward it: capturing the conversations across tools is the tractable half, but unifying them is the hard half, because the same entity gets referred to differently in each tool, and a decision made in Claude that a Cursor session later depends on has no shared id linking them. So how are you thinking about correlation, do you unify on the actual content, on time ordering, on the project, or something the user tags? Because a pile of preserved chats from four tools is only continuity if you can reconstruct which context feeds which, and that threading across silos is the thing I can't see a clean answer to. Curious where you've landed, since it's the exact problem that decides whether it's a memory vault or a memory timeline.

I just stalk them to be honest. I have 4 agents running at one, keep an eye on them, and review their code / actions while they execute it.

I also make sure the AI learns from its mistakes, and puts it in the Analyse knowledge base!

 

Stalking four agents in real time and reviewing their code as it executes is the highest-control version of this, and for four agents it genuinely works, you never hit the silent-wait problem because you're watching, and you catch the confidently-wrong changes at the moment they happen instead of three commits later. If you've got the attention for it, live review beats any notification, because nothing gets past you in the first place.

The tradeoff you're paying, and you clearly know it, is that you are the scheduler. Four agents that all have to queue behind your eyes means your attention is the throughput cap, and the moment you'd want a fifth or sixth, the stalking stops scaling, because you can't watch six things execute at once. Works beautifully right up to the number of agents you can personally hold in your head.

The part I actually want to poke at is the Analyse knowledge base, because that's the rarer and harder thing. Making the AI learn from its mistakes and persist them is exactly the "stop being a perpetually-new employee" problem most people never touch, everyone re-teaches through the prompt every session. The hard bit isn't writing the lesson down, it's trusting it later: a mistake-turned-lesson can be captured wrong, or be right once and wrong in the next context, so the knowledge base can quietly accumulate confident bad rules that are worse than no memory.

Curious how you handle that, when the agent logs a lesson into Analyse, do you review what it learned before it becomes a rule it acts on, or does it write freely and you correct later if it misfires? Because that write-path is where a learning knowledge base either compounds real trust or compounds confident nonsense, and I keep going back and forth on which side needs the human gate.

 For the rules, I have a specific page agents write to. I give each agent an ID (right now I have 4 unique ids), then every few hrs when I want a break, I go for coffee then when I come back I first go through it, check if it did all right with a clear mind, edit / remove things from it, then continue working. Its quiete a unique workflow, and I more started it just to test my knowledge base for Analyse (since I build it), and now I found out this works perfectly for me.

Even tho Analyse itself isn't really build for it, Analyse itself is more a Analytics + SEO improvement system with a knowledge base, AI copilot & mcp connector. But I thought, why not now I have it use it.

 

The coffee-break-then-review-with-a-clear-mind cadence is the smart part, and it's smarter than it probably felt when you stumbled into it. Reviewing what the agents wrote after stepping away means you're auditing with fresh eyes instead of the tunnel vision you had while guiding them, and that gap matters, because the mistakes an agent logs are exactly the ones you're most likely to wave through if you review them in the same headspace that produced them. Batching the review to the break isn't just convenient, it's a better quality of review. You accidentally designed the human gate correctly.

And you've landed on the thing most people miss about a learning knowledge base: it needs a human between "agent wrote a lesson" and "lesson becomes a rule it acts on." You edit and remove before continuing, which means confident-but-wrong entries get caught before they compound. That's the whole difference between a knowledge base that accrues real trust and one that quietly accrues nonsense the agent then defends as established fact. The per-agent IDs are the other quietly-right call, because now a bad rule is traceable to which agent produced it, so you can see if one of the four is consistently the one writing junk.

The funny part is you built Analyse as an analytics-plus-SEO tool with a knowledge base bolted on, and the knowledge base turned out to be the reusable primitive. That happens more than people admit, the thing you built for one job is secretly a general-purpose memory layer, and agent-lessons is just another thing to store and retrieve. It's not that Analyse was built for this, it's that a good knowledge base doesn't care what kind of knowledge it holds.

Genuine question, since you're both the user and the builder here: when you edit or remove a lesson, does the agent ever re-learn the thing you deleted, write it back a session later because it hit the same situation again? Because that's the failure I'd worry about in a review-and-prune workflow, you correct it Monday, it re-derives the same wrong lesson Wednesday, and now you're playing whack-a-mole. Curious whether you've hit that, or whether your edits actually stick.

First
Previous
•••
111213
•••
Next