# How `gt nudge` Enables Real-Time Agent Communication in Gas Town

> Learn how gt nudge enables real-time agent communication in Gas Town. Send synchronous text payloads directly to active sessions for instant updates without Dolt commits.

- Repository: [Gas Town Hall/gastown](https://github.com/gastownhall/gastown)
- Tags: how-to-guide
- Published: 2026-07-07

---

**`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`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/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`](https://github.com/gastownhall/gastown/blob/main/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

```bash

# 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`](https://github.com/gastownhall/gastown/blob/main/internal/cmd/nudge.go)**: Main CLI implementation, argument parsing, DND checks, and delivery orchestration.
- **[`internal/nudge/queue.go`](https://github.com/gastownhall/gastown/blob/main/internal/nudge/queue.go)**: Persistent file-queue storage for the `queue` and `wait-idle` fallback paths.
- **[`internal/tmux/tmux.go`](https://github.com/gastownhall/gastown/blob/main/internal/tmux/tmux.go)**: Low-level tmux interactions including `SendKeys`, `WaitForIdle`, and `NudgeSessionWithOpts`.

## Summary

- **`gt nudge`** provides 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 `--force` available for emergencies.
- **ACP compatibility** automatically falls back to queue mode for agents without tmux panes.
- All activity is logged via `telemetry.RecordNudge` and `events.LogFeed` for 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`](https://github.com/gastownhall/gastown/blob/main/internal/cmd/nudge.go)) because these automatic-completion-process agents lack tmux panes, making immediate key injection impossible.