Keep AI coding agents productive. When Codex, Claude Code, or Gemini CLI finishes a task in tmux and stops to wait for input, nudge automatically sends "continue" to keep them going.
Nudge also supports bd_epic sessions: instead of nudging a raw agent pane, it
can supervise a repo-local epic runner that drains a bd epic and reports
structured NUDGE_STATUS lines back to the daemon.
This makes Nudge more agent-friendly for long-running project work: one layer keeps the session alive, and another layer knows what “the next real unit of work” actually is.
The highest-leverage setup is:
- put a tiny
nudge.jsoncontract in the target repo - run
~/scripts/nudge-epic.sh doctor /path/to/repo - run
~/scripts/nudge-epic.sh bootstrap <session> /path/to/repo <epic-id> --start - use
~/scripts/nudge-status.shfor the dashboard and~/scripts/nudge-attention.shwhen you only want the sessions that need a human
That keeps Nudge simple:
- Nudge owns supervision
- the target repo owns task selection
- the repo contract removes setup guesswork for agents
A Ralph loop is a useful generic pattern: run an agent, let it stop, then restart it with a fresh prompt or fresh context until the broader objective is done.
Nudge is solving a different layer of the problem. It is the supervisor for
real tmux-based agent sessions, and in bd_epic mode it can supervise a
repo-local runner that already knows how to pick the next ready unit of work.
| Dimension | Ralph loop | Nudge |
|---|---|---|
| Main job | Repeat/restart an autonomy loop | Supervise long-running tmux agent sessions |
| Repo awareness | Usually generic | Generic by default, repo-aware via bd_epic |
| tmux visibility | Usually minimal/custom | Built in: dashboard, logs, pause/resume, kick |
| Blocked / human states | Custom per setup | First-class in bd_epic mode |
| Best for | Broad “keep going” loops | Operational reliability for real sessions |
Use a Ralph loop when:
- you want a generic repeat-until-done pattern
- the repo does not yet have a deterministic runner
- fresh-context restart behavior matters more than session supervision
Use Nudge when:
- you already run agents in tmux
- you want a daemon, dashboard, logs, and pause/resume controls
- you want explicit runtime states like
running,waiting_blocked, andwaiting_human - you want to supervise a repo-local runner instead of blindly replaying
continue
Use both when:
- you want fresh-context iteration plus operational supervision
- the target repo has a deterministic runner and you still want an outer watchdog
Nudge is not trying to replace the Ralph loop idea. It gives long-running agent
work a real supervisor, and bd_epic mode adds tracker-aware orchestration
when the target repo supports it.
AI coding agents (OpenAI Codex, Claude Code, Gemini CLI) frequently pause after completing a task, waiting for human input before moving on. If you're running multiple agents across tmux sessions on long-running work, you end up babysitting them — checking back every few minutes to type "continue."
A lightweight daemon watches your tmux sessions every 3 minutes and:
- Detects which agent is running (Codex, Claude Code, Gemini, or generic shell)
- Determines the agent's state: working, idle, asking a question, stuck in a loop, rate-limited, or done
- Sends "continue" only when the agent is genuinely idle and waiting for input
- Stays quiet when the agent is actively working, asking a question, or rate-limited
Unlike a blind watch loop that spams Enter, nudge:
- Detects agent type from prompt patterns and working indicators
- Debounces — requires 2 consecutive idle checks (~6 min) before nudging
- Detects loops — if output is unchanged for 3+ cycles, stops nudging (agent is stuck, not idle)
- Respects questions — won't nudge if the agent is asking you something
- Tracks intent — knows what each session is supposed to be working on
- Logs everything — full audit trail of every decision
- Understands epic runners — if a pane emits
NUDGE_STATUS, nudge records the structured runtime state instead of treating it like a generic idle shell
git clone https://github.com/silverstein/nudge.git
cd nudge
./install.shThis installs:
~/scripts/nudge.sh— the daemon script~/Library/LaunchAgents/com.nudge.daemon.plist— launchd agent (macOS, runs every 3 min)~/.nudge/— config, snapshots, and logs- Claude Code plugin (symlinked, gives you the
/nudgecommand)
- tmux — sessions must be in tmux
- jq — JSON processing (
brew install jq) - macOS or Linux (macOS uses launchd, Linux needs a cron job)
On Linux, the install script skips launchd and prints a cron command:
*/3 * * * * ~/scripts/nudge.shbash scripts/check-contract-flow.shThis exercises the contract-based doctor, bootstrap, start, runtime
status capture, status, attention, and auto-restart flow against a
temporary repo.
If you point Codex or Claude Code at this repo and ask it to set up Nudge for long-running Codex project work, the agent should be able to do the whole job without guessing.
- Install Nudge:
git clone https://github.com/silverstein/nudge.git
cd nudge
./install.sh- Verify the local prerequisites:
tmux -V
jq --version
codex --help- Register a
bd_epicsession for the target repo:
~/scripts/nudge-epic.sh doctor /abs/path/to/repo
~/scripts/nudge-epic.sh bootstrap dojo /abs/path/to/repo epic-id --start
~/scripts/nudge-epic.sh status dojo- Confirm the daemon is tracking the session:
/nudge
tail -50 ~/.nudge/nudge.logTo make Codex actually keep moving through a long-running project, the target repo needs a deterministic runner. Nudge is the supervisor, not the project planner.
The target repo should provide a root nudge.json file:
{
"version": 1,
"session_modes": {
"bd_epic": {
"runner_interface": "codex_epic_v1",
"runner": "node scripts/codex_epic_runner.mjs",
"default_agent_bin": "codex",
"default_agent_args": ["--full-auto"],
"default_taskmaster": false,
"status_file_env": "NUDGE_STATUS_FILE",
"states": [
"running",
"waiting_no_ready",
"waiting_blocked",
"waiting_human",
"complete",
"crashed"
],
"required_commands": ["node", "codex", "bd"],
"required_files": ["scripts/codex_epic_runner.mjs"]
}
}
}The target repo should also provide a runner that implements the
codex_epic_v1 interface:
- a command that can drain the next ready unit of work
- structured status updates via
NUDGE_STATUS {...} - a sidecar status file via
NUDGE_STATUS_FILE - explicit pause states such as
running,waiting_no_ready,waiting_blocked,waiting_human,complete, andcrashed
Example runner launch:
cd /abs/path/to/repo
NUDGE_STATUS_FILE="$HOME/.nudge/runtime/dojo.json" node scripts/codex_epic_runner.mjs epic-id -- --full-autoThat split is intentional:
- Nudge owns tmux supervision, daemon scheduling, restart visibility, and dashboard state
- the target repo owns tracker-aware work selection and per-task Codex prompts
- Do not assume every repo uses
bd;bd_epicis a pattern, not a universal standard. - Do not assume pane scraping alone is reliable; wrapped terminal output can corrupt JSON lines.
- Do not assume
continueis the right control signal forbd_epicsessions; prefer the runner status and only use/nudge kickas a fallback. - Do not assume the target repo already has a runner; if it does not, the agent should build or ask for one first.
# In Claude Code:
/nudge add my-session "Working on the auth refactor"
# Or edit ~/.nudge/sessions.json directly~/scripts/nudge-epic.sh doctor /Users/silverbook/Sites/minutes
~/scripts/nudge-epic.sh bootstrap dojo /Users/silverbook/Sites/minutes minutes-ylql.2 --startWith Taskmaster as the per-bead engine:
~/scripts/nudge-epic.sh bootstrap dojo /Users/silverbook/Sites/minutes minutes-ylql.2 --start --taskmaster --agent-arg=--sandbox --agent-arg=danger-full-access --agent-arg=-a --agent-arg=never/nudge # Dashboard with all sessions
/nudge log # Recent activity log
/nudge eval # AI-powered deep evaluation of all sessions
~/scripts/nudge-status.sh # Attention first, then session summary
/nudge pause design # Temporarily stop nudging
/nudge resume design # Resume nudging
/nudge done design # Mark as complete
/nudge reset design # Clear state, restart monitoring
/nudge remove design # Remove entirely
/nudge kick design # Immediately send "continue" (skip daemon wait)
~/scripts/nudge-epic.sh status dojo # Show raw bd_epic config + runtime state
~/scripts/nudge-attention.sh # Show only sessions that need a human
~/scripts/nudge-status.sh # Attention section + full session summary
bd_epic sessions write structured runner state to ~/.nudge/runtime/<session>.json
via NUDGE_STATUS_FILE, so the daemon can track epic progress without relying
only on wrapped tmux pane text.
bd_epic mode is meant for repos that already have a deterministic work runner,
not for arbitrary shell sessions.
The target repo should provide:
- a runner command that can drain the next ready unit of work
- structured status updates via
NUDGE_STATUS {...} - a sidecar status file via
NUDGE_STATUS_FILE - explicit pause reasons like
waiting_no_ready,waiting_blocked, andwaiting_human
That split is intentional:
nudgeowns tmux supervision, daemon scheduling, and dashboard state- the target repo owns tracker-aware work selection and per-task agent prompts
This keeps nudge general-purpose while still making it useful for bd-driven
agent workflows.
You can start from examples/nudge.json
and copy it into the target repo root as nudge.json.
/nudge intent design "Migrating settings pages to new design system"
/nudge help
The daemon examines the last 40 lines of each tmux pane and matches against known patterns:
| Agent | Identified by |
|---|---|
| Codex | Working (, Thinking (, › prompt, gpt-* status |
| Claude Code | Cogitated, Imagining, ❯ prompt, ⏵⏵ status bar |
| Gemini CLI | Gemini, gemini-* model strings |
| Generic | Falls back to common shell prompts ($, %, >) |
| State | Meaning | Action |
|---|---|---|
| working | Agent is actively processing | Skip |
| idle | Agent finished, waiting for input | Nudge (after 2 checks) |
| asking | Agent is asking a question | Skip |
| looping | Same output for 3+ cycles | Skip + log |
| done | Completion phrases detected | Mark complete |
| ratelimited | Rate/usage limit hit | Mark stopped |
| blocked | Agent says it's blocked | Skip + log |
Every cycle, the daemon hashes the last 20 non-blank lines of each pane. If the hash is identical for 3 consecutive cycles (9+ minutes), the session is marked as looping — the agent is stuck, and sending "continue" won't help.
Edit ~/.nudge/sessions.json:
{
"sessions": {
"my-session": {
"intent": "Working on feature X",
"active": true,
"paused": false,
"nudgeCount": 0,
"lastNudge": null,
"completedAt": null,
"depletedAt": null
}
},
"config": {
"nudgeMessage": "continue",
"cooldownNudges": 20,
"completionPhrases": ["all tasks complete", "nothing left to do"],
"blockedPhrases": ["I am blocked", "waiting for your input"]
}
}| Config key | Default | Description |
|---|---|---|
nudgeMessage |
"continue" |
Text sent to the agent |
cooldownNudges |
20 |
Max nudges before stopping (prevents runaway) |
completionPhrases |
(see default) | Phrases that trigger auto-complete |
blockedPhrases |
(see default) | Phrases that prevent nudging |
# View recent activity
tail -50 ~/.nudge/nudge.log
# Or in Claude Code:
/nudge log 50Log format:
2024-03-19 08:32:58 [NUDGE] design2: sent 'continue' (nudge #4, agent=codex)
2024-03-19 08:35:58 [IDLE] design2: marked idle — will nudge on next check if still idle (agent=codex)
2024-03-19 08:38:59 [LOOP] design2: identical output for 3 cycles — not nudging (agent=codex)
cd nudge
./install.sh --uninstallMIT