[Feature Request] Periodic silent execution primitive for autonomous agents
Related Anthropic Feedback ID: 8dd67e96-63ea-4a22-b687-d26a1b2d0add
Problem
Claude Code has no mechanism to execute periodic tool calls silently — without rendering them in the terminal transcript. CronCreate and /loop are the only periodic mechanisms, and every fire produces a visible ⎿ Bash(command) + output block plus a "Running scheduled task" marker. For autonomous-agent infrastructure that needs to self-poll external state between user turns, this scales linearly with polling frequency — at 5-minute intervals, an 8-hour interactive session produces ~100 visible "no-op" renders.
Hooks, by contrast, already run silently and already inject into agent context via additionalContext. The primitive we need is not a new "silent mode" for agent turns — it's a periodic trigger that fires a hook-style execution. Today, the periodic mechanisms (CronCreate, /loop) fire agent turns, and the silent mechanisms (hooks) are event-driven only. Nothing combines silent + periodic + agent-context-aware.
Steps to Reproduce
- Schedule a polling cron in an interactive Claude Code session:
\\\\
CronCreate({ cron: "*/5 * * * *", prompt: "check dispatches", recurring: true })
\\
- Leave the session idle for one hour without typing.
- Observe ~12 visible \
Running scheduled task → Bash(...) → output\blocks accumulate in the transcript.
Expected: Silent periodic execution with agent context updated if state changed.
Actual: Every fire renders, polluting the interactive session.
Diagnostic Evidence
Catalog of existing Claude Code mechanisms and their coverage (verified via two independent rounds of documentation and settings-schema review):
| Mechanism | Silent | Periodic | Injects agent context |
|-----------|--------|----------|----------------------|
| SessionStart / UserPromptSubmit / Stop hooks | ✅ | ❌ (event-driven) | ✅ (\additionalContext\) |
| Async hooks (\"async": true\) | ✅ | ❌ | Partial |
| Status line command (\statusLine: {type: "command"}\) | ✅ | ✅ (UI tick) | ❌ (footer only) |
| Subagent execution internals | ✅ | ❌ | Returns-only |
| \CronCreate\ / \/loop\ | ❌ | ✅ | ✅ |
| \Bash(run_in_background: true)\ detached loop | Partial | ✅ | ❌ (file-gated) |
No row combines silent + periodic + agent-context-aware. That combination is the gap.
Workarounds attempted and their failure modes:
- Delta-suppression in a hook — works for notification, but the hook only fires on user events. Fails in autonomous operation.
- Empty-output bash tool — the \
Bash(command)\line still renders even with empty stdout. Rendering is triggered by the tool call itself, not its output. - Status line polling — silent and periodic, but status line output renders only in the footer UI; it does not inject into the agent's next-turn context. Good for display, not for notification.
- Background detached bash loop (\
while true; do … sleep 300; done &\) — polling runs silently after initial spawn, but the agent's turn still needs a hook event to read the state file and act. Hook-gated notification lag defeats the autonomous-operation purpose. - Async hooks — silent, but not periodic.
Root Cause
Architectural separation between two classes of execution:
- Agent turns (rendered) — \
CronCreate\, \/loop\, user prompts, manual tool calls - Hook executions (silent) — SessionStart, UserPromptSubmit, Stop, PostToolUse, async hooks, status line
Periodic scheduling lives in the first class; silent execution with \additionalContext\ injection lives in the second. There is no bridge.
Requested Behavior
Any one of the following would close the gap. Ranked by what appears to be the smallest change to existing architecture:
Option 1 (preferred) — \Periodic\ hook type in \settings.json\
\\\json\
{
"hooks": {
"Periodic": [
{ "interval": "5m", "command": ".claude/tools/mail-check" }
]
}
}
\\
Timer-based hook with the same silent execution and \additionalContext\ injection as existing event-driven hooks. Reuses all existing hook infrastructure (JSON output contract, silent stdout/stderr handling, \additionalContext\ injection). Minimal new surface area — hook-based analogue of cron jobs.
Option 2 — \hook:\ parameter on \CronCreate\
\\\typescript\
CronCreate({
cron: "*/5 * * * *",
hook: ".claude/tools/mail-check",
recurring: true,
})
\\
Rather than scheduling a \prompt\ (which fires a visible agent turn), let \CronCreate\ schedule a hook-style command. The fire runs as a hook — silent by design, same \additionalContext\ plumbing. No new hook type needed; only a new scheduler variant. Potentially the cleanest implementation.
Open question: does the existing scheduler have the plumbing to invoke a hook-style command instead of a turn? If yes, Option 2 is almost certainly the smaller change. If no, Option 1 is the simpler path.
Option 3 (fallback)
Document the status line command as the canonical silent periodic polling path for display-only use cases, and be explicit in the docs that it cannot inject agent context. This doesn't close the gap, but it surfaces the partial solution for users building status indicators.
Why This Matters
The Claude Code docs emphasize autonomous operation, scheduled tasks, and hooks as composable building blocks. The missing primitive is periodic silent self-awareness — the ability for an agent to observe external state between user turns without producing visual noise in the interactive session.
Concrete use cases already blocked by this gap:
- Multi-agent frameworks (the-agency, https://github.com/the-agency-ai/the-agency) where agents coordinate via a SQLite-backed inter-session communication protocol. Agents need to notice incoming dispatches from other agents within ~5 minutes so they can respond to directives, reviews, and escalations while the principal is away.
- Background sync agents keeping a local state file aligned with a remote (databases, issue trackers, git remotes).
- Monitoring agents watching logs, CI runs, or deploy status.
- Long-running autonomous patterns where the agent is observer rather than prompt-responder.
A native solution unblocks an entire class of agent infrastructure that the Claude Code platform is uniquely positioned to enable. We have shipped what we can in userspace — hook delta suppression, background pollers, status line indicators — but we cannot close the silent + periodic + agent-context-aware gap from outside the harness.
---
Reporter: Jordan Dea-Mattson (@jordandm, @jordan-of)
Framework: https://github.com/the-agency-ai/the-agency
Environment: macOS 26 (Tahoe), Ghostty terminal
Anthropic Feedback ID: 8dd67e96-63ea-4a22-b687-d26a1b2d0add
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗