How `gt nudge` Enables Real-Time Agent Communication in Gas Town
gt nudge sends synchronous text payloads directly to active agent sessions without creating Dolt commits, offering three delivery modes (wait-idle, queue, and immediate) to balance immediacy against interruption.
The gt nudge command is the core real-time messaging primitive in the gastownhall/gastown repository, designed specifically for low-latency coordination between Gas Town agents. Unlike the persistent "mail" system that creates Dolt commits, nudges facilitate instant communication by delivering short text payloads directly to a target agent's active Claude or IDE session.
Architecture of the gt nudge Command
The implementation resides primarily in internal/cmd/nudge.go, where the runNudge function orchestrates the entire flow. When invoked, the command executes a four-phase pipeline: address normalization, Do-Not-Disturb validation, delivery mode selection, and message injection.
Address Parsing and Role Shortcuts
The command accepts multiple addressing schemes. In lines 72-84 of internal/cmd/nudge.go, runNudge normalizes role shortcuts such as mayor, witness, or deacon into concrete tmux session names. It also supports channel syntax (channel:<name>), which expands to a pre-configured list of agents defined in ~/gt/config/messaging.json (lines 107-110).
Do-Not-Disturb Enforcement
Before delivery, the system checks the target's DND (Do-Not-Disturb) status—a per-agent notification level stored in the Beads index. As implemented in lines 52-66, the command aborts the nudge if DND is active unless the --force flag is provided.
The Three Delivery Modes Explained
The delivery strategy is determined by the --mode flag, with definitions located in lines 49-60 of internal/cmd/nudge.go. The deliverNudge function routes messages through one of three distinct paths:
wait-idle (Default)
The sender monitors the target session using tmux.WaitForIdle until the prompt becomes idle, then injects the message directly (lines 98-124). If the timeout expires before idleness is detected, the message falls back to the queue path. This mode prevents interrupting active generations.
queue
The message is written to a per-session file queue via internal/nudge.Enqueue (lines 88-96). The target agent drains this queue at the next turn boundary. This non-blocking approach ensures the sender never interrupts the target's current work.
immediate
The message is sent straight to the tmux pane via tmux.NudgeSessionWithOpts, optionally skipping the Escape keystroke for agents that interpret Escape as cancel (lines 131-139). This guarantees delivery but interrupts any in-flight generation, making it suitable for emergency situations.
Handling ACP Agents
For ACP (automatic-completion-process) agents that lack a tmux pane, deliverNudge forces queue mode regardless of the requested strategy (lines 75-80).
Watcher and Fallback Mechanisms
When operating in wait-idle mode, the watcher continuously polls the target for idleness. The watchAndDeliver and drain functions (lines 96-112) batch-deliver any queued nudges once the session becomes idle, ensuring no messages are lost during busy periods.
Observability and Telemetry
All nudge activity is instrumented through telemetry.RecordNudge and logged to events.LogFeed, creating an audit trail for messaging policy enforcement and system debugging.
Usage Examples
# Basic nudges using default wait-idle mode
gt nudge greenplace/furiosa "Check your mail and start working"
gt nudge mayor "Status update requested"
# Force delivery despite DND settings
gt nudge --force deacon "Emergency: reset needed now"
# Explicit mode selection
gt nudge --mode=immediate greenplace/alpha "Interrupt: abort current task"
gt nudge --mode=queue greenplace/beta "Background work scheduled"
# Multiline input via stdin
gt nudge gastown/alpha --stdin <<'EOF'
Task Report:
- Task 1: complete
- Task 2: in progress
EOF
# Broadcast to predefined channel
gt nudge channel:workers "New priority work available"
Key Implementation Files
internal/cmd/nudge.go: Main CLI implementation, argument parsing, DND checks, and delivery orchestration.internal/nudge/queue.go: Persistent file-queue storage for thequeueandwait-idlefallback paths.internal/tmux/tmux.go: Low-level tmux interactions includingSendKeys,WaitForIdle, andNudgeSessionWithOpts.
Summary
gt nudgeprovides synchronous, real-time messaging between Gas Town agents without Dolt commit overhead.- Three delivery modes (
wait-idle,queue,immediate) let operators balance immediacy against interruption risk. - DND enforcement ensures agents only receive messages when ready, with
--forceavailable for emergencies. - ACP compatibility automatically falls back to queue mode for agents without tmux panes.
- All activity is logged via
telemetry.RecordNudgeandevents.LogFeedfor complete auditability.
Frequently Asked Questions
What is the difference between gt nudge and gt mail?
gt nudge sends ephemeral, synchronous messages directly to an agent's active session without creating persistent storage, while gt mail creates Dolt commits that form a permanent record. Use nudges for real-time coordination and mail for asynchronous, auditable communication.
How does the wait-idle mode know when an agent is busy?
The wait-idle mode calls tmux.WaitForIdle to monitor the target session's prompt state. It waits until the agent's generation completes and the prompt returns to idle before injecting the message, falling back to the queue if a timeout occurs.
Can I send a nudge to multiple agents at once?
Yes. Use the channel syntax (channel:<name>) to broadcast to predefined groups configured in ~/gt/config/messaging.json. The command expands the channel to individual targets before applying DND checks and delivery logic.
What happens if I nudge an ACP agent with immediate mode?
The system automatically forces queue mode for ACP agents (lines 75-80 in internal/cmd/nudge.go) because these automatic-completion-process agents lack tmux panes, making immediate key injection impossible.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →