Run real CLI agent workflows from your phone without giving up terminal power.
AI Traffic Control is a mobile-first control plane for people who rely on Codex/Claude/Gemini in the CLI and want the same operational control away from their desk.
For many users, agent workflows routed through chat apps (for example Telegram/WhatsApp bridges) break down when sessions become long-running, stateful, or tool-heavy.
Common failure modes:
- Message delivery != reliable execution state.
- Plugin/channel glitches can block or delay responses.
- Rich CLI ergonomics (shell tooling, structured logs, tight loops) are hard to preserve inside IM UX.
The usual model is: open mobile terminal app -> reconnect -> SSH -> attach tmux -> inspect each session manually.
That creates friction:
- High context-switch cost to understand "what needs attention now".
- No single operator dashboard across multiple agent sessions.
- Limited workflow customization for hot-starting repeatable agent tasks.
AI Traffic Control combines a browser terminal surface (xterm.js + ttyd + tmux) with an operator dashboard.
Core capabilities:
- Fleet view of AI sessions with lifecycle states (
active,idle,unborn). - In-browser terminal control for each slot from mobile or desktop.
- Provider usage telemetry (Codex/Claude/Gemini) for 5-hour and weekly usage awareness where available.
- Hot-dial agents for one-tap launches of specialized workflows.
- Intent modal with provider/template/persona/workdir controls before spawn.
- Session title summarization from recent transcript context.
Outcome: you can steer serious CLI work on the go, instead of running a degraded “chat bot” version of your workflow.
| Workflow Model | Common Friction | AI Traffic Control Difference |
|---|---|---|
| IM-based agent bridge | Message transport and execution state can diverge; limited CLI ergonomics | Keeps you in terminal-native workflows with direct session control |
| Mobile terminal app only | Reconnect and inspect sessions one-by-one; limited fleet visibility | Unified dashboard + slot state + telemetry for fast triage |
| Raw tmux over SSH | Powerful but high manual overhead from phone | One-tap hot-dials, guided spawn flow, and browser terminal UX |
AI Traffic Control is a control plane for mobile CLI agent operations, not a chat wrapper.
- Builders running multiple long-lived AI coding/research sessions.
- Operators who need fast intervention loops from phone + desktop.
- Individuals optimizing subscription quota windows across providers.
- Users who want deep customization over session launch and runtime behavior.
This view shows:
- Provider usage cards for Codex/Claude/Gemini.
- Hot-dial agents at the top of the fleet panel.
- Active scientist cards with current task/workdir context.
GIF walkthrough: coming soon.
This view shows:
- The in-browser terminal used to drive a live CLI session from mobile/desktop.
- Command output stream and prompt loop inside the managed terminal surface.
- How AI Traffic Control lets you operate terminal sessions without opening a separate terminal app.
GIF walkthrough: coming soon.
This view shows:
- Provider selection with live usage context.
- Template and persona controls.
- Working directory and recent-directory shortcuts before launch.
GIF walkthrough: coming soon.
This view shows:
- Mixed scientist lifecycle states at once (
active,idle,unborn). - Fast triage context per scientist (task, workdir, turns, and recency).
- How to identify sessions that need intervention vs. sessions ready to start.
GIF walkthrough: coming soon.
- Persona hat/badge deep-dive screenshots: coming soon.
Required tools on the host machine:
node(tested in this repo with modern Node;node@22is used in some scripts)tmuxttydnginx(default path assumed by scripts:/opt/homebrew/opt/nginx/bin/nginx)jq(for one health-check command)codexbar(used for provider usage telemetry from Codex/Claude/Gemini)
cd ~/Code/AiTrafficControl
./dashboard/scripts/start-all.shWhat this does:
- Starts the dashboard server on
:1111in tmux sessiondashboard-1111(no-op if already running). - Regenerates+reloads the nginx session proxy (
700x -> 800xport mapping). - Non-destructive: preserves live
800xttyd backends and existingdashboard/state/sessions-state.json.
Open:
- Dashboard:
http://127.0.0.1:1111 - Mobile/slot endpoints:
http://127.0.0.1:7001...:7004(fromdashboard/sessions.json)
Scientist 800x ttyd backends are spawned on demand when you tap an idle scientist card in the dashboard UI; this script intentionally does not start them.
The one-click script is just a thin wrapper. Run the steps separately when you only need one of them:
# Dashboard server only (:1111)
./dashboard/scripts/start-dashboard.sh
# Nginx session proxy only (700x -> 800x), non-destructive
./dashboard/scripts/start-ttyd-sessions.sh
# Destructive: kill live 800x ttyd backends and reset slot state to idle
./dashboard/scripts/reset-ttyd-sessions.shlsof -nP -iTCP -sTCP:LISTEN | rg ':(7001|7002|7003|7004|8001|8002|8003|8004|1111)\b'
tmux ls | rg 'dashboard-1111'
curl -sS http://127.0.0.1:1111/api/sessions | jq '{count: (.sessions|length), hasRecentWorkdirs: has("recentWorkdirs")}'Typical access model:
- Dashboard runs locally on the host.
- Remote phone/laptop access is commonly handled through a private VPN (for example Tailscale).
Security posture:
- Nothing is publicly exposed by default.
- Slot endpoints and dashboard remain inside your private network boundary.
- Main operational risks are in your own agent permissions, tool access, and execution policy.
The dashboard can auto-update each slot title (taskTitle) based on the latest CLI conversation direction.
Main knobs:
ATC_SUMMARY_TRIGGER_INTERVAL(default1; run summarizer every prompt)ATC_SUMMARIZER_CMD(defaultgemini)ATC_SUMMARIZER_MODEL(defaultgemini-3.1-flash-lite-preview)ATC_SUMMARY_TRANSCRIPT_LINES(default10)ATC_SUMMARY_TIMEOUT_MS(default180000)ATC_NO_SUMMARIZER=1to disable
Implementation reference:
dashboard/scripts/shell-hook-writer.mjsdashboard/scripts/summarize-title.mjsdashboard/runtime/logs/summarizer.log
cd ~/Code/AiTrafficControl/dashboard
npm install
npm testOr from repo root:
./dashboard/scripts/test-dashboard.shEdit:
dashboard/sessions.json
Then regenerate session proxy:
cd ~/Code/AiTrafficControl
./dashboard/scripts/start-ttyd-sessions.shcd ~/Code/AiTrafficControl/nginx-ttyd
./scripts/start.shDefault endpoint: http://127.0.0.1:7680
dashboard/: Web dashboard, API, slot orchestration, telemetry ingest, tests.nginx-ttyd/: Standalone mobile ttyd + nginx overlay stack.personas/: Persona prompt docs used by session tooling.data/: Local data files used by runtime features.agents.md: Agent runbook with required post-change operational checks.HANDOFF.md: Current operational notes and change context.
Dashboard-managed path:
- Browser opens dashboard on
:1111. - Dashboard manages slot lifecycle and metadata.
- Session nginx proxy serves public slot ports (
:700x) and forwards to slot backends (:800x). - Backends attach to
tmux-backed shells throughttyd. - Shell/Codex/Claude hooks write events under
dashboard/runtime/slots/<slot>/current/.
Standalone path:
- Browser opens
nginx-ttydon:7680. - Nginx forwards to ttyd on
127.0.0.1:7682. - Ttyd attaches to a persistent tmux session.
dashboard/scripts/start-ttyd-sessions.shis safe for template/nginx reloads and does not tear down live scientist sessions.dashboard/scripts/reset-ttyd-sessions.shintentionally resets slot state to idle and rewritesdashboard/state/sessions-state.json.- Changing injected toolbar HTML requires regenerating/reloading nginx configs, not just a browser refresh.
- If only
nginx-ttyd/ttyd-mobile.cssornginx-ttyd/ttyd-mobile.jschanges, a hard refresh is usually enough (or bump?v=in nginx config if cached).
- Dashboard details:
dashboard/README.md - Mobile ttyd overlay details:
nginx-ttyd/README.md - Agent operation checklist:
agents.md - Current handoff notes:
HANDOFF.md