Configuration
Zero configuration by default. Environment variables for power users.
Philosophy
Irrlicht is designed to work with zero configuration. Install and run — sessions are discovered automatically. These options exist for power users who need to customize behavior.
Environment Variables
| Variable | Type | Default | Description |
|---|---|---|---|
IRRLICHT_MAX_SESSION_AGE |
Duration | 120h (5 days) |
Maximum age for transcript sessions before pruning |
GT_BIN |
Path | $PATH lookup |
Override path to Gas Town gt CLI binary |
IRRLICHT_UI_DIR |
Path | auto-detect | Directory containing the dashboard's index.html; escape hatch when auto-detection fails (see When to use these) |
IRRLICHT_BIND_ADDR |
host:port | 127.0.0.1:7837 |
Override the daemon's TCP bind — use 0.0.0.0:7837 to expose on the LAN |
IRRLICHT_MDNS |
Boolean (1/0) | unset | Advertise _irrlicht._tcp via Bonjour so other devices on the LAN can discover the daemon |
IRRLICHT_DEBUG |
Boolean (1/0) | unset | macOS app dumps session state to ~/.irrlicht/debug-state.json on every update |
PI_CODING_AGENT_SESSION_DIR |
Absolute path | ~/.pi/coding-agent/sessions |
Relocate the Pi adapter's transcript root. Read once at daemon startup; restart required after changing. Non-absolute values are rejected with a log warning |
CLAUDE_CONFIG_DIR |
Absolute path | ~/.claude |
Relocate the Claude Code adapter's transcript root (the daemon appends /projects). PID-metadata directory at ~/.claude/sessions/ remains hardcoded |
CODEX_HOME |
Absolute path | ~/.codex |
Relocate the Codex adapter's transcript root (the daemon appends /sessions) |
When to use these
The defaults work for solo, single-machine use. Reach for these overrides when one of the following describes you:
I want to peek at sessions from my phone on the same WiFi
If you run irrlichd yourself from a terminal, set both vars inline:
IRRLICHT_BIND_ADDR=0.0.0.0:7837 IRRLICHT_MDNS=1 irrlichd
If the macOS app auto-spawns the daemon for you (the default for DMG / Homebrew installs), shell env vars never reach it. Set them in the per-user launchd context first, then relaunch the app:
launchctl setenv IRRLICHT_BIND_ADDR 0.0.0.0:7837
launchctl setenv IRRLICHT_MDNS 1
# quit Irrlicht.app from the menu bar, then reopen it
Either way, then open http://<hostname>.local:7837 in any browser on the same network. mDNS lets the phone find the host without you typing an IP.
Security note: the daemon has no authentication today. Anyone on the network you bind to can read all your transcripts. Only do this on networks you trust (your home LAN, your tailnet) — never on a coffee-shop WiFi. See SECURITY.md for the full posture.
Future: these two knobs will be replaced by a single explicit hub mode. See the Relay Server design for the planned consolidation.
The dashboard returned "Dashboard UI not found"
The daemon resolves the dashboard's location in this order (first hit wins):
$IRRLICHT_UI_DIR— escape hatch (what this recipe sets)<exe>/../Resources/web/— production.appbundle layout~/.local/share/irrlicht/web/— daemon-only curl install- Walking up from the executable for
platforms/web/index.html— dev checkout
If the three auto-detect paths (2–4) all miss — custom install layout, fork with a moved UI, broken symlink — set the env var so it takes precedence:
IRRLICHT_UI_DIR=/path/to/dir/containing/index.html irrlichd
The macOS app is misbehaving and I want to see its session state
Env vars set in your shell do not reach a GUI app launched via open -a — LaunchServices spawns the app without inheriting them. Use one of these instead:
# Most reliable: invoke the binary directly
IRRLICHT_DEBUG=1 /Applications/Irrlicht.app/Contents/MacOS/Irrlicht
# Or, on macOS 13+: forward via open's --env flag
open -a Irrlicht --env IRRLICHT_DEBUG=1
# Or, persist for the launchd session and relaunch normally
launchctl setenv IRRLICHT_DEBUG 1
# quit Irrlicht.app, then reopen it
The current session list, connection state, and history buckets are written to ~/.irrlicht/debug-state.json on every update. Useful when filing a bug report.
Filesystem Paths
Daemon
- Session instances:
~/Library/Application Support/Irrlicht/instances/ - Logs:
~/Library/Application Support/Irrlicht/logs/ - Unix socket:
~/.local/share/irrlicht/irrlichd.sock
macOS App
- Session order:
~/Library/Application Support/Irrlicht/session-order.json
Transcript Locations
- Claude Code:
~/.claude/projects/<project>/<session-id>.jsonl - Codex:
~/.codex/sessions/YYYY/MM/DD/<session-id>.jsonl - Pi:
~/.pi/agent/sessions/--<cwd-dashed>--/<session-id>.jsonl - Aider:
<cwd>/.aider.chat.history.md(markdown, per-CWD) - OpenCode:
~/.local/share/opencode/storage/opencode.db(single SQLite WAL, watched viaopencode.db-wal)
App Settings
The macOS app has a Settings panel accessible via the gear icon:
Session TTL
- Controls auto-deletion of idle ready sessions
- Options: Never, 15 minutes, 30 minutes (default), 1 hour, 4 hours
- Stored in
@AppStorage("sessionTTLMinutes")
Notifications
- Three events —
ready,waiting, and context pressure (80% / 95%) — each has its own enable toggle and sound picker in Preferences - Built-in sounds: Ping, Chime, Funk, Whoosh, Sosumi; defaults Ready=Funk, Waiting=Ping, Context=Sosumi
- None — the banner still appears but plays no sound
- Speak aloud — routes the title and body through
AVSpeechSynthesizer(pinned to en-US) with three voice variants: Default, Zoe-Premium (female), Jamie-Premium (male). If a premium voice isn't installed, the row deep-links to System Settings → Accessibility → Spoken Content - Custom — imports
aiff/wav/mp3/m4a/caffrom disk into~/Library/Sounds/, transcodingmp3/m4ato LPCM-in-CAF soUNNotificationSoundcan play them - Requires macOS notification permission (requested on launch)
Logging
- Format: Structured JSON
- Location:
~/Library/Application Support/Irrlicht/logs/ - Files:
events.log(current),events.log.1through.5(rotated) - Max size: 10MB per file, 5 files retained
- Log event types:
startup,shutdown,session-detector,process-watcher,process-exit
Network
- TCP:
localhost:7837(HTTP API + WebSocket + Web UI) - Unix socket:
~/.local/share/irrlicht/irrlichd.sock - mDNS:
_irrlicht._tcp(Bonjour/Zeroconf discovery)
Daemon Lifecycle
The daemon (irrlichd) is embedded inside Irrlicht.app and managed automatically. When you launch the app, the daemon starts; when you quit, it stops. If the daemon crashes, the app restarts it with exponential backoff.
If an external daemon is already running (e.g. from a development build), the app detects it and uses the existing instance instead of spawning a new one.
Terminal hosts
Clicking a session in the menu bar or web UI brings the originating terminal's window — and where possible the exact tab — to the front. Most terminals work out of the box. Kitty needs one extra config line for precise tab focus.
Kitty
Kitty's inter-process control is opt-in. Without it, Irrlicht can raise the kitty window but cannot switch to the tab that owns the clicked session — the last-focused tab stays visible. Enable remote control in ~/.config/kitty/kitty.conf:
allow_remote_control yes
listen_on unix:/tmp/kitty-{kitty_pid}
Restart kitty after editing — a config reload alone has no effect. New sessions started inside kitty will then have KITTY_LISTEN_ON set, and clicks land on the exact tab via kitten @ focus-window. (Note: macOS does not support Linux-style abstract sockets, so a filesystem path is required.)