A terminal UI for browsing and launching GitHub Copilot CLI sessions.
Dispatch reads your local Copilot CLI session store and presents every past session in a searchable, sortable, groupable TUI. Full-text search, conversation previews, directory filtering, five built-in themes, and four launch modes — all without leaving the terminal.
- Full-text search (
/) — FTS5 full-text search with BM25 ranking when available, falling back to LIKE for older CLI versions. Two-tier: quick search (summaries, branches, repos, directories) returns results instantly; deep search (turns, checkpoints, files, refs) kicks in after 300ms. Searching a number (e.g. "42", "#42", "PR42") also matches session refs (PRs, issues, commits) - Directory filtering (
f) — hierarchical tree panel for toggling directory exclusion, persisted to config - Word filtering (Settings panel) — comma-separated list of words to exclude sessions by content. Sessions whose name or conversation turns contain any excluded word (case-insensitive) are hidden from the list
- Sorting (
s/S) — 7 fields (updated, created, turns, name, folder, attention, frecency) with toggleable direction. Sort applies to both sessions and group ordering - Grouping modes (
Tab) — list, folder, repo, branch, date, host. Displayed as collapsible trees with session counts - Time range filtering (
1–4) — 1 hour, 1 day, 7 days, all - Preview panel (
p) — metadata, chat-style conversation bubbles, checkpoints (up to 5), files (up to 5), refs (up to 5), scroll indicators. Toggle conversation sort order witho. Presszto view the preview fullscreen. Click the session ID row to copy it to clipboard - Copy session ID (
c) — copy the selected session's ID to the system clipboard. Also available by clicking the ID row in the preview pane - Copy resume command (
Y) — copy the selected session's full resume command to the system clipboard. With a multi-select active, copies one resume command per selected session, one per line - Open working directory (
O) — open the selected session's working directory in the system file manager (Explorer on Windows, Finder on macOS, the default file manager on Linux) - Open linked reference (
b) — open the selected session's linked pull request, issue, or commit on github.com in your browser. Picks the pull request first, then the issue, then the commit - Git status overlay (
i) — show the git status of the folder the selected session is mapped to: current branch and upstream, push/pull stats (commits ahead to push, behind to pull), working-tree counts (staged, modified, untracked, deleted, conflicts), and a scrollable list of changed files. The same push/pull stats also appear inline on each session row and in the preview pane's git section - Four launch modes (
Enter/t/w/e) — in-place, new tab, new window, split pane (Windows Terminal, or tmux when running inside a tmux session) with per-session overrides - Multi-session open (
Space/L/a/d) — select multiple sessions with Space, launch all at once with L, select/deselect all with a/d. Shift+↑/↓ for range selection, Ctrl+click and Shift+click for mouse selection. With a selection active,h(hide),*(favorite), andY(copy resume command) apply to every selected session at once - Attention indicators — colored dots showing real-time session status: working (blue, executing tools), thinking (cyan, generating response), compacting (magenta, context compaction), waiting (purple), active (green), stale (yellow), interrupted (orange ⚡), idle (gray). Jump to next waiting session with
n, resume interrupted sessions withR, filter by status with! - Host type icons — sessions display an icon indicating their origin: CLI (desktop), Cloud (cloud), or Actions (gear)
- Incremental auto-refresh — the session list auto-refreshes within 2 seconds when the Copilot CLI writes new data (WAL file polling when focused). No manual reindex needed for normal use. Tune the interval or turn it off with
auto_refresh_seconds - Plan indicator (
v) — a dot next to sessions that have aplan.mdfile (~/.copilot/session-state/{session-id}/plan.md). Pressvto view the plan in the preview pane. Filter sessions with plans via the!status picker - Work status detection — analyzes
plan.mdfiles to identify sessions with incomplete planned work. Colored dots show completion status in the session list and preview panel. PressRto explicitly scan work status. Filter by work completion via the!status picker. Supports AI-powered analysis via Copilot SDKanalyze_completiontool - Session hiding (
h/H) — hide sessions from the list, toggle visibility of hidden sessions, persistent state - Session favorites (
*) — star sessions as favorites. Filter to show only favorites via the!status picker - Session tags (
#) — attach comma-separated tags to sessions and filter to a tag with thetag:search token - Session aliases (
A) — give a session a short, memorable alias and resume it from the CLI withdispatch open <alias>instead of the full session ID - Settings panel (
,) — 19 fields: Yolo Mode, Agent, Model, Launch Mode, Pane Direction, Terminal, Shell, Custom Command, Theme, Crash Recovery, Preview Position, Redact Secrets, Excluded Words, Auto Refresh, Notify On Waiting, and column toggles for Repo, Folder, Turns, and Host - Configurable list columns (
,settings) — choose which optional columns (repo, folder, turns, host) appear in the session list. Defaults show every column, and the session name and attention indicator are always visible - Shell picker — auto-detects installed shells, modal picker when multiple available
- 5 built-in themes — Dispatch Dark, Dispatch Light, Campbell, One Half Dark, One Half Light + custom via Windows Terminal JSON
- Help overlay (
?) — two-column grouped keyboard shortcuts - Mouse support — click, double-click, Ctrl+double-click (window), Shift+double-click (tab), pane-aware scroll wheel
- Nerd Font detection — auto-detects Nerd Fonts and uses rich icons, falls back to ASCII
- Windows Terminal theme detection — inherits the active terminal color scheme
- Refresh (
r) — reload the session store without restarting - Demo mode —
dispatch --demowith synthetic data for experimentation - Self-update —
dispatch updatechecks GitHub Releases and upgrades in-place; background update check notifies on new versions - Maintenance —
--reindex(manual rebuild of the session index via Copilot CLI PTY — repair action only),--clear-cache(reset config) - Cross-platform — Windows (amd64/arm64), macOS (amd64/arm64), Linux (amd64/arm64)
| Search & Preview | Grouping & Filtering |
|---|---|
![]() |
![]() |
![]() |
![]() |
| Multi-Select | Attention Indicators |
|---|---|
![]() |
![]() |
| Settings | Help Overlay |
|---|---|
![]() |
![]() |
- GitHub Copilot CLI installed and used at least once (so the session store exists)
- Go 1.26+ — only required when building from source; binary releases have no dependencies
curl -fsSL https://raw.githubusercontent.com/jongio/dispatch/main/install.sh | shTo install a specific version:
curl -fsSL https://raw.githubusercontent.com/jongio/dispatch/main/install.sh | sh -s -- v0.1.0irm https://raw.githubusercontent.com/jongio/dispatch/main/install.ps1 | iexTo install a specific version:
$v="v0.1.0"; irm https://raw.githubusercontent.com/jongio/dispatch/main/install.ps1 | iexRequires Go 1.26+:
go install github.com/jongio/dispatch/cmd/dispatch@latestOr clone and build locally:
git clone https://github.com/jongio/dispatch.git
cd dispatch
go install ./cmd/dispatch/The installer also creates a disp alias automatically.
dispatchPass a search term to open with the search box pre-filled and the list already filtered:
dispatch auth
dispatch fix auth bugLaunch straight into the sessions for a repo, branch, or folder without typing in the search box. The filters seed the first query and show up in the search header.
dispatch --current # current git repo and branch (read from the working dir)
dispatch --repo owner/repo # one repository (owner/repo form)
dispatch --branch main # one branch
dispatch --cwd ~/code/app # sessions under a folder
dispatch --repo owner/repo --branch main --query auth # combine filters and free text--current reads the git repository and branch from the current directory, or from --cwd <path> when given. Explicit --repo and --branch flags take precedence over the detected values. A non-git directory or a missing --cwd path prints an error and does not start the TUI.
Bind dispatch --current to a shell alias to jump to the sessions for the repo you are already working in:
alias dc='dispatch --current'- Run
dispatch(ordisp) in your terminal - Press
/to search for previous sessions — try a keyword like "auth" or "refactor" - Navigate with arrow keys or
j/k - Press
pto toggle the preview pane and read the conversation - Press
Enterto resume the selected session (opens in a new tab by default) - Use
Tabto cycle grouping modes (folder → repo → branch → date → flat) - Press
sto cycle sort fields,Sto flip direction - Press
,to open settings — change theme, launch mode, model, and more
Resume a session without opening the TUI:
dispatch open <session-id> # resume a specific session by ID
dispatch open --last # resume the most recently active sessionBoth accept --mode to override the launch mode for that one resume (inplace, tab, window, pane):
dispatch open --last --mode windowUse --print to write the resume command to stdout instead of launching it. This is handy for scripting, dry runs, or piping the command elsewhere:
dispatch open <session-id> --printOverride the agent, model, or yolo mode for a single resume without changing your saved config with --agent, --model, and --yolo:
dispatch open <session-id> --agent coder --model gpt-5
dispatch open --last --yolo
dispatch open <session-id> --yolo=false # force off even if config enables itThese flags apply to every launch mode and to --print. When omitted, the saved config values are used.
Resume the most recent session matching a repository, branch, or folder instead of specifying an ID:
dispatch open --repo jongio/dispatch
dispatch open --branch feature/auth
dispatch open --repo jongio/dispatch --branch main
dispatch open --folder ~/projects/api
dispatch open --current # auto-detect repo and branch from cwdScope flags cannot be combined with --last, --stdin, or a session ID.
Start a brand-new Copilot session from the command line without opening the TUI:
dispatch new # start in the current directory
dispatch new ~/code/app # start in a specific directory
dispatch new --mode tab # override the launch mode (inplace, tab, window, pane)
dispatch new --agent coder --model gpt-5 # override agent/model for this session
dispatch new --yolo # start with yolo mode on for this session onlyThe session uses the same agent, model, and launch settings as the TUI unless you pass --agent, --model, or --yolo to override them for that one launch. When no directory is given, the current working directory is used.
Print completion scripts for supported shells:
dispatch completion bash
dispatch completion zsh
dispatch completion fish
dispatch completion powershellOnce the script is sourced, completion covers dynamic values too: dispatch open <TAB> completes your configured session aliases, dispatch config get <TAB> (and set/unset) completes config keys, and dispatch completion <TAB> completes the supported shells. These come from your local config and static lists, so completion stays fast.
Run dispatch doctor to print setup checks for the config file, session store, session-state directory, and Copilot CLI binary. It also reports the detected Copilot CLI version and the number of stored sessions.
Add --json (dispatch doctor --json) to print the same checks as a single JSON object for scripts and CI.
Run dispatch stats to print session totals and breakdowns by repository, branch, and host type.
dispatch stats
dispatch stats --json
dispatch stats --csv
dispatch stats --markdown
dispatch stats --calendar
dispatch stats --repo jongio/dispatch --since 2026-01-01
dispatch stats --tag work
dispatch stats --top 5Flags:
--jsonprints the summary as a single JSON object.--markdownprints the summary as Markdown tables for reports and issue comments.--calendaradds a GitHub-style activity heatmap of sessions per day, with an intensity legend. It honors the--repo,--branch,--since, and--untilfilters.--repo,--branch,--folder,--tag,--since, and--untilnarrow which sessions are counted.--top <n>caps each repository, branch, and host breakdown to the first N entries.
Run dispatch tags to list every tag in use with the number of sessions that carry it, ordered by count.
dispatch tags
dispatch tags --jsonTags come from sessions you have tagged in the TUI. Counts are taken against the current session store, so tags left on sessions that no longer exist are not counted. Use --json for scripting.
Manage session notes from the command line without editing config.json directly:
dispatch notes
dispatch notes --json
dispatch notes get 0a1b2c3d
dispatch notes set 0a1b2c3d "follow up after review"
printf 'line one\nline two\n' | dispatch notes set 0a1b2c3d --stdin
dispatch notes clear 0a1b2c3ddispatch notes lists notes for sessions that still exist in the session store. set, get, and clear operate on one session ID and use the same notes shown in the TUI preview. Use --stdin to set a multiline note without shell quoting.
List named views and switch the active view from scripts:
dispatch views
dispatch views --json
dispatch views use Work
dispatch views use defaultNamed views come from the views array in config.json. dispatch views use <name> sets active_view, and dispatch views use default clears it so the TUI opens with the normal filters.
Save a full session (metadata and the complete conversation) to a file with dispatch export <id>:
dispatch export 0a1b2c3d
dispatch export 0a1b2c3d --format json
dispatch export 0a1b2c3d --format html
dispatch export 0a1b2c3d --format text
dispatch export 0a1b2c3d --stdout
dispatch export 0a1b2c3d --redact --stdout
dispatch export 0a1b2c3d --out ./exportsBy default the session is written as Markdown to the exports directory. Use --format json for machine-readable output, --format html for a self-contained web page you can open in a browser, or --format text for plain text. Use --stdout to print to the terminal instead of writing a file, --out <dir> to choose the destination directory, and --redact to mask common secret patterns before writing. --stdout and --out cannot be combined.
Export all sessions matching a scope filter at once:
dispatch export --repo jongio/dispatch
dispatch export --repo jongio/dispatch --format json --out ./backup
dispatch export --repo jongio/dispatch --format text --out ./backup
dispatch export --branch main --since 2026-01-01 --until 2026-07-01
dispatch export --query "auth fix" --redact
dispatch export --tag work --out ./work-sessionsFilter flags (--query, --repo, --branch, --folder, --tag, --since, --until) replace the session ID. Each matching session is exported to its own file in the output directory. --stdout is not supported in batch mode.
Compare two sessions side by side with dispatch compare:
dispatch compare 0a1b2c3d 9f8e7d6c
dispatch compare 0a1b2c3d 9f8e7d6c --jsonThe output shows metadata differences (summary, branch, turn count), files that appear in only one session, ref differences, and checkpoint title lists. Use --json for machine-readable output. Session IDs accept the same prefix shorthand as open and export.
Print a concise summary of one session with dispatch info <id>:
dispatch info 0a1b2c3d
dispatch info 0a1b2c3d --json
dispatch info 0a1b2c3d --refsThe summary covers the session's repository, branch, working directory, host type, saved alias, tags, note, turn and file counts, timestamps, and linked ref counts. Use --refs to include linked commit, PR, and issue values, or --json for scripting. The session ID accepts the same prefix shorthand as open.
Print only a session's working directory so you can change into it from a subshell:
cd "$(dispatch path 0a1b2c3d)" # by ID or short prefix
cd "$(dispatch path my-alias)" # by alias
cd "$(dispatch path --last)" # most recently active session
cd "$(dispatch path --current)" # match the current repo and branchpath writes a single line (the absolute directory) and nothing else, so it drops straight into cd. It resolves the session the same way open does. It exits with an error if the session has no recorded directory or if that directory no longer exists, so cd "$(...)" fails loudly instead of landing somewhere wrong.
List every session alias with dispatch aliases:
dispatch aliases
dispatch aliases --jsonEach entry shows the alias, the target session ID, summary, and repository. Aliases whose target session is no longer in the store are marked as orphaned. Use --json for scripting.
Set or remove a single session alias from the command line, completing the parity that tag and notes already have:
dispatch alias <id> review # assign or reassign an alias
dispatch alias <id> --clear # remove the alias on a session
dispatch alias --remove review # remove an alias by its name
dispatch alias <id> review --jsonThe <id> accepts the same short prefix that dispatch open does. Alias names are lowercased and must be unique, so dispatch open <alias> keeps resolving to one session.
Manage tags on a single session from the command line:
dispatch tag <id> # list current tags
dispatch tag <id> --add work,api # add tags
dispatch tag <id> --remove api # remove tags
dispatch tag <id> --set a,b # replace all tags
dispatch tag <id> --json # print result as JSONA session alias can be used in place of the ID. Tags are deduplicated and stored in sorted order.
Clean up config entries that reference sessions no longer in the store:
dispatch prune # dry run: report what would be removed
dispatch prune --apply # remove stale entries
dispatch prune --json # machine-readable summary
dispatch prune --apply --json # remove and print JSON summaryScans aliases, tags, notes, favorites, hidden sessions, and launch stats. By default it only reports; --apply performs the cleanup.
Monitor session attention state without opening the TUI:
dispatch watch --once # one-shot snapshot
dispatch watch --once --json # JSON snapshot
dispatch watch # stream transitions (Ctrl-C to stop)
dispatch watch --interval 10s # custom poll interval
dispatch watch --once --repo jongio/dispatch # filter by repo
dispatch watch --once --status waiting # filter by attention status
dispatch watch --exec 'notify-send "$DISPATCH_SESSION_STATE"' # run a hook on each transitionThe terminal bell rings when a session transitions to waiting or interrupted. Use --repo, --branch, --folder, or --status waiting|working|thinking|active|stale|compacting|interrupted|idle to limit which sessions are monitored.
--exec <cmd> runs a command every time a session changes attention state while streaming (it cannot be combined with --once). The command runs through your shell, so pipelines and quoting work as usual. Session context is passed as environment variables, never interpolated into the command string:
| Variable | Value |
|---|---|
DISPATCH_SESSION_ID |
Full session ID |
DISPATCH_SESSION_STATE |
New attention state (waiting, working, gone, ...) |
DISPATCH_SESSION_PREV_STATE |
Prior state, or none for a newly seen session |
DISPATCH_SESSION_REPO |
Repository |
DISPATCH_SESSION_BRANCH |
Branch |
DISPATCH_SESSION_FOLDER |
Working directory |
DISPATCH_SESSION_SUMMARY |
Session summary |
Hook output and non-zero exits are written to stderr, and a slow or failing command never stops the watch loop. Example that posts to a webhook when a session starts waiting for input:
dispatch watch --exec '[ "$DISPATCH_SESSION_STATE" = waiting ] && \
curl -s -X POST "$WEBHOOK_URL" -d "session=$DISPATCH_SESSION_ID needs input"'Query the session store from scripts without opening the TUI. dispatch search prints matching sessions as a JSON array by default:
dispatch search auth
dispatch search --query "fix login" --repo jongio/dispatch
dispatch search --branch main --since 2026-01-01 --limit 20
dispatch search --tag work --ids
dispatch search --sort turns --order desc --limit 10
dispatch search --deep refactor --json
dispatch search auth --format ids
dispatch search auth --ids
dispatch search auth --table
dispatch search auth --csvThe query can be passed as a positional argument or with --query. Filters mirror the interactive search and the stats command:
--repo,--branch,--folder,--hostnarrow by session metadata.--tag <tag>narrows by tags stored in Dispatch config.--since/--untilacceptYYYY-MM-DDor full RFC3339 timestamps.--deepalso searches turns, checkpoints, touched files, and refs.--sort updated|created|turns|name|folderand--order asc|desccontrol result order.--limit <n>caps the result count (default 50,0for no limit).--format json|csv|ids|tablechooses JSON output, CSV output, one session ID per line, or a readable table.--csv,--ids, and--tableare shortcuts.
Each JSON or CSV result includes id, summary, cwd, repository, branch, created_at, updated_at, turn_count, and file_count. No JSON matches prints []; no ID matches prints nothing. CSV always prints a header row. Invalid flags or an unreadable store exit non-zero with a message on stderr.
Generate a roff man page for dispatch with dispatch man and write it wherever your system keeps manual pages:
dispatch man > dispatch.1
man ./dispatch.1The page targets section 1 (user commands) and mirrors the built-in usage: commands, flags, environment variables, and examples. It takes no flags and writes to standard output.
| Key | Action |
|---|---|
↑ / k |
Move up |
↓ / j |
Move down |
g / Home |
Jump to top |
G / End |
Jump to bottom |
← |
Collapse group |
→ |
Expand group |
| Key | Action |
|---|---|
Enter |
Launch selected session (or toggle folder) |
w |
Launch in new window |
t |
Launch in new tab |
e |
Launch in split pane (Windows Terminal, or tmux inside a tmux session) |
| Key | Action |
|---|---|
Space |
Toggle selection on current session |
Shift+↑ |
Extend selection upward (range select) |
Shift+↓ |
Extend selection downward (range select) |
L |
Launch all selected sessions (or all in folder) |
a |
Select all visible sessions |
d |
Deselect all |
| Key | Action |
|---|---|
n |
Jump to next waiting session |
N |
Resume all interrupted sessions |
R |
Scan work status across sessions with plans |
! |
Filter by attention status, plans, favorites, and work completion |
h |
Hide/unhide current session |
H |
Toggle visibility of hidden sessions |
* |
Toggle favorite on current session |
# |
Add or edit tags on current session |
A |
Set or clear a short alias on current session |
| Key | Action |
|---|---|
/ |
Focus search bar |
Esc |
Clear search / close overlay |
f |
Open filter panel |
Search tokens narrow results without opening the filter panel. Type them in the search bar alongside free text:
| Token | Matches |
|---|---|
repo:<name> |
Sessions in a repository (use quotes for names with spaces: repo:"my repo") |
branch:<name> |
Sessions on a branch |
folder:<path> |
Sessions under a working directory |
host:<type> |
Sessions by host type (cli, cloud, actions) |
status:<state> |
Sessions by attention state (waiting, active, stale, idle, interrupted, working, thinking, compacting) |
has:plan |
Sessions that have a plan |
is:favorite |
Favorited sessions |
is:hidden |
Hidden sessions |
after:<date> |
Sessions active on or after a date |
before:<date> |
Sessions active on or before a date |
Dates accept YYYY-MM-DD or full RFC3339 timestamps (e.g. after:2024-01-15 or
before:2024-03-01T12:00:00Z), matching the --since / --until flags on
dispatch stats. While an after: token is active it takes precedence over the
1-4 time-range shortcuts. Clearing the search restores the selected range.
| Key | Action |
|---|---|
s |
Cycle sort field |
S |
Toggle sort direction |
Tab |
Cycle grouping mode |
p |
Toggle preview panel |
P |
Cycle preview position (right → bottom → left → top) |
z |
Toggle fullscreen preview |
v |
View plan in preview pane |
o |
Toggle conversation sort order (oldest/newest first) |
c |
Copy session ID to clipboard |
Y |
Copy resume command to clipboard |
PgUp / PgDn |
Scroll preview |
r |
Refresh session store |
, |
Open settings panel |
| Key | Action |
|---|---|
i |
Git status overlay for the selected session's folder |
b |
Open linked PR, issue, or commit in browser |
O |
Open working directory in file manager |
F |
Open a file the session touched |
D |
Compare two selected sessions |
T |
Activity timeline in the preview pane |
V |
Switch named view |
X |
Export selected sessions to Markdown |
m |
Edit note on current session |
C |
Copy working directory path to clipboard |
y |
Copy preview text to clipboard |
x |
Expand or collapse all groups |
: |
Open the command palette |
| Key | Action |
|---|---|
1 |
Last 1 hour |
2 |
Last 1 day |
3 |
Last 7 days |
4 |
All time |
| Key | Action |
|---|---|
? |
Show help overlay |
q |
Quit |
Ctrl+C |
Force quit |
Keys inside overlays (filter, settings, shell picker, help):
| Key | Action |
|---|---|
↑ / k, ↓ / j |
Navigate |
Enter |
Select / apply / toggle |
Esc |
Close overlay |
Space |
Toggle checkbox (filter panel) |
← / → |
Collapse / expand (filter panel) |
| Action | Effect |
|---|---|
| Click session | Select it |
| Click folder header | Expand or collapse |
| Double-click session | Launch it |
| Ctrl + click session | Toggle selection without opening |
| Shift + click session | Range select from last click |
| Double-click (with selections) | Open all selected sessions |
| Double-click folder | Launch new session in that directory |
| Ctrl + double-click | Force new window |
| Shift + double-click | Force new tab |
| Scroll wheel (list) | Scroll session list |
| Scroll wheel (preview) | Scroll preview pane |
| Click header elements | Interact with search, time range, sort, pivot |
| Click session ID in preview | Copy session ID to clipboard |
| Click conversation sort arrow | Toggle conversation sort order |
Configuration is stored in the platform-specific config directory:
- Linux:
~/.config/dispatch/config.json - macOS:
~/Library/Application Support/dispatch/config.json - Windows:
%APPDATA%\dispatch\config.json
Set DISPATCH_CONFIG to an absolute file path to use a different config file, for example to keep separate work and personal profiles. config path, config get/set/edit, and doctor all follow the override. A relative or UNC value is ignored and the default location is used.
Read and change settings without opening the TUI or editing JSON by hand:
dispatch config list # print every setting and its value
dispatch config list --json # same, as a single JSON object
dispatch config get launch_mode # print one value
dispatch config set launch_mode window
dispatch config unset launch_mode # reset one setting to its default
dispatch config edit # open the config file in your editor
dispatch config path # print the config file pathset validates the value and writes through the same save path the TUI uses, so migrations and checks still run. unset resets one key to its default through that same save path. Unknown keys and invalid values exit non-zero with a clear message. The keys match the option names in the table below. Set auto_refresh_seconds to default to clear it back to unset. edit opens the file in $VISUAL or $EDITOR (falling back to a platform default) and re-checks it after you save, which is handy for list and map settings that set does not cover.
| Key | Type | Default | Description |
|---|---|---|---|
default_shell |
string | "" |
Preferred shell (bash, zsh, pwsh, cmd.exe). Empty = auto-detect |
default_terminal |
string | "" |
Terminal emulator. Empty = auto-detect |
default_time_range |
string | "1d" |
Time filter: 1h, 1d, 7d, all |
default_sort |
string | "updated" |
Sort field: updated, created, turns, name, folder, frecency |
default_sort_order |
string | "desc" |
Sort direction: asc, desc |
default_pivot |
string | "folder" |
Grouping: none, folder, repo, branch, date, host |
default_collapsed |
bool | false |
Start group headers collapsed (single-line) |
show_preview |
bool | true |
Show preview pane on startup |
preview_position |
string | "right" |
Position of the preview pane: right, bottom, left, top |
redact_preview_secrets |
bool | false |
Mask common secret patterns (bearer tokens, GitHub PATs, connection strings, .env secrets) with [redacted] in the preview pane. Rendering only; stored session data is never modified |
conversation_newest_first |
bool | true |
Show newest conversation turns first in preview |
max_sessions |
int | 100 |
Maximum sessions to load |
yoloMode |
bool | false |
Pass --allow-all to Copilot CLI (auto-confirm commands) |
agent |
string | "" |
Pass --agent <name> to Copilot CLI |
model |
string | "" |
Pass --model <name> to Copilot CLI |
launch_mode |
string | "tab" |
How to open sessions: in-place, tab, window, pane |
pane_direction |
string | "auto" |
Split direction for pane mode: auto, right, down, left, up (see note below) |
custom_command |
string | "" |
Custom launch command ({sessionId} is replaced) |
excluded_dirs |
array | [] |
Directory paths to hide from session list |
excluded_words |
array | [] |
Comma-separated words; sessions containing any word are hidden |
attention_threshold |
string | "15m" |
Duration after which an inactive running session is marked stale |
notify_on_waiting |
bool | false |
Ring the terminal bell and show a footer message when a session enters the waiting state |
auto_refresh_seconds |
int | (unset) | Session-list poll interval in seconds. Unset uses the default (2s); 0 disables polling; a positive value sets the interval (minimum 1s). Applies on next launch |
theme |
string | "auto" |
Color scheme: auto or a named scheme |
workspace_recovery |
bool | true |
Detect sessions interrupted by crash/reboot |
ai_search |
bool | false |
Enable Copilot SDK-powered AI semantic search |
hiddenSessions |
array | [] |
Session IDs hidden from the main list |
favoriteSessions |
array | [] |
Session IDs starred as favorites |
keybindings |
object | {} |
Remap keyboard shortcuts. Keys are action names, values are comma-separated key lists (see Customizing Keybindings) |
sessionTags |
object | {} |
Map of session ID to a list of user-defined tags |
sessionAliases |
object | {} |
Map of session ID to a unique short alias for dispatch open <alias> |
views |
array | [] |
Named search, sort, pivot, and filter presets |
active_view |
string | "" |
Name of the named view to apply on startup. Empty means default filters |
hidden_columns |
array | [] |
Optional session-list columns to hide (repo, folder, turns, host); empty shows all |
When launch_mode is "pane", the pane_direction value maps to Windows Terminal's -H / -V split-pane flags:
| Direction | WT Flag | Meaning |
|---|---|---|
down |
-H |
Horizontal split — divider runs horizontally, new pane below |
up |
-H |
Horizontal split — WT controls actual placement (closest available) |
right |
-V |
Vertical split — divider runs vertically, new pane to the right |
left |
-V |
Vertical split — WT controls actual placement (closest available) |
auto |
(none) | Windows Terminal decides automatically |
Note:
-Hand-Vcontrol split orientation only (the direction the divider runs). Windows Terminal decides actual pane placement based on available space.
When you run dispatch inside a tmux session (the TMUX environment variable is set), pane mode splits the current tmux window with tmux split-window instead of opening a new terminal emulator. The pane_direction value maps to tmux flags:
| Direction | tmux Flag | Meaning |
|---|---|---|
right / left |
-h |
Vertical divider — new pane to the right |
down / up |
-v |
Horizontal divider — new pane below |
auto |
(none) | tmux uses its default (a pane below) |
The split starts in the session's working directory (-c) and runs the resume command in your shell. Outside tmux, pane mode behaves as before.
{
"default_shell": "",
"default_terminal": "",
"default_time_range": "1d",
"default_sort": "updated",
"default_pivot": "folder",
"show_preview": true,
"preview_position": "right",
"max_sessions": 100,
"yoloMode": false,
"agent": "",
"model": "",
"launch_mode": "tab",
"pane_direction": "auto",
"custom_command": "",
"excluded_dirs": [],
"theme": "auto",
"workspace_recovery": true,
"notify_on_waiting": false,
"ai_search": false,
"hiddenSessions": [],
"favoriteSessions": [],
"keybindings": {}
}Set custom_command to replace the default Copilot CLI launch entirely. Use {sessionId} as the placeholder. When set, Agent, Model, and Yolo Mode fields are ignored.
"custom_command": "my-tool resume {sessionId}"Set keybindings in config.json to remap keyboard shortcuts. Each key is an
action name and each value is a comma-separated list of keys that trigger it.
Listed actions replace their default keys; any action you do not list keeps its
default. Unknown action names are ignored, and if a remap collides with a key
another action already uses, that remap is dropped and the default is kept.
"keybindings": {
"search": "/,ctrl+f",
"cmd_palette": "ctrl+k",
"quit": "q"
}Key names follow Bubble Tea conventions: single characters (a, /, ?),
named keys (up, down, left, right, enter, esc, tab, space,
pgup, pgdown), and modifier combinations (ctrl+f, alt+left, shift+tab).
Available action names:
up, down, jump_top, jump_bottom, left, right, enter, space,
quit, force_quit, search, escape, filter, sort, sort_order,
pivot, pivot_order, preview, preview_fullscreen, reindex, help,
config, time_range_1, time_range_2, time_range_3, time_range_4,
hide, toggle_hidden, star, launch_window, launch_tab, launch_pane,
preview_scroll_up, preview_scroll_down, jump_next_attention,
filter_attention, launch_all, select_all, deselect_all,
conversation_sort, preview_position, resume_interrupted, view_plan,
copy_id, copy_path, copy_resume_command, copy_preview,
expand_collapse_all, scan_work_status, export, note, tags, alias,
shift_up, shift_down, view_switch, open_file, open_dir, open_ref,
timeline, compare, git_status, cmd_palette.
Five built-in color schemes:
- Dispatch Dark
- Dispatch Light
- Campbell
- One Half Dark
- One Half Light
| Dispatch Dark | Dispatch Light | Campbell |
|---|---|---|
![]() |
![]() |
![]() |
| One Half Dark | One Half Light |
|---|---|
![]() |
![]() |
Set theme to "auto" (default) for automatic light/dark detection based on your terminal background. Or set it to any built-in scheme name.
Add custom color schemes using Windows Terminal JSON format in the schemes array of your config file. Each scheme name becomes available in the settings theme selector.
| Flag | Description |
|---|---|
--help, -h, help |
Show usage information |
--version, -v, version |
Print the version and exit. Add --json for script output |
update |
Update dispatch to the latest release |
--demo |
Load a demo database with synthetic sessions |
--reindex |
Full chronicle reindex via Copilot CLI (falls back to FTS5 rebuild) |
--clear-cache |
Reset all configuration to defaults |
--current |
Filter the list to the current git repo and branch |
--cwd <path> |
Filter to sessions under a folder (base dir for --current) |
--repo <name> |
Filter to a repository (owner/repo) |
--branch <name> |
Filter to a branch |
--query <text> |
Pre-fill the search box with free text |
A background update check runs on every launch and notifies you when a new version is available. Set DISPATCH_NO_UPDATE_CHECK=1 to skip that check.
Unknown flags print an error message with usage help and exit with code 1.
| Variable | Description |
|---|---|
DISPATCH_CONFIG |
Override the path to the config file. Must be an absolute, non-UNC path; a relative or UNC value is ignored and the default location is used |
DISPATCH_DB |
Override the path to the Copilot CLI session store database |
DISPATCH_SESSION_STATE |
Override the path to the Copilot CLI session state directory |
DISPATCH_LOG |
Path to a log file (enables debug logging) |
DISPATCH_NO_UPDATE_CHECK |
Skip the background release check when set to 1, true, yes, or on |
The installer creates a disp shorthand automatically. To add it manually:
# bash / zsh
alias disp="dispatch"# PowerShell
Set-Alias -Name disp -Value dispatch"dispatch: command not found"
- Ensure
$GOPATH/bin(or the install directory) is in yourPATH - Restart your terminal after installation
"session store not found"
- Copilot CLI must have been used at least once to create the session database
- Check that
~/.copilot/session-store.dbexists (or the platform equivalent) - Override with the
DISPATCH_DBenvironment variable if your database is elsewhere
Sessions not appearing
- Check your time range filter — the default shows only the last day
- Use
/to search by keyword - Check
excluded_dirsin your config - Try
dispatch --reindexto rebuild the session index (or pressrinside the TUI)
git clone https://github.com/jongio/dispatch.git
cd dispatch
go build ./cmd/dispatch/Build Targets (via Mage)
| Target | Command | Description |
|---|---|---|
| Install | mage install |
Test → kill stale → build → ensure PATH → verify |
| Test | mage test |
go test with race detector + shuffle |
| TestWSL | mage testWSL |
Run tests under WSL Linux for Unix code path coverage |
| CoverageReport | mage coverageReport |
Generate coverage.html with atomic coverage profile |
| Preflight | mage preflight |
Full CI check (11 steps — see below) |
| Vet | mage vet |
go vet ./... |
| Lint | mage lint |
golangci-lint (falls back to go vet) |
| Fmt | mage fmt |
Format all Go source files |
| Build | mage build |
Compile dev binary with version info |
| Clean | mage clean |
Remove bin/ directory |
| Contributors | mage contributors |
Regenerate CONTRIBUTORS.md from git history |
mage preflight runs the same checks as CI — if preflight passes, CI will pass:
Step 1/11 gofmt — Auto-format source files
Step 2/11 go mod tidy — Clean up module dependencies
Step 3/11 go vet — Static analysis
Step 4/11 golangci-lint — Extended linter suite (20+ linters)
Step 5/11 go build — Compile all packages
Step 6/11 go test — Unit & integration tests (shuffled, race-detected)
Step 7/11 go test -race — Race detection (requires gcc / CGO)
Step 8/11 WSL tests — Unix code path coverage (skipped if WSL unavailable)
Step 9/11 govulncheck — Known vulnerability scan
Step 10/11 gofumpt — Strict formatting enforcement
Step 11/11 deadcode — Unreachable code detection
Every push and PR runs on GitHub Actions:
| Check | Description |
|---|---|
go build |
Compilation gate |
golangci-lint |
Static analysis with extended linters |
go vet |
Go's built-in static analyzer |
go test |
Full test suite |
go test -race |
Race condition detection (CGO enabled) |
govulncheck |
Known vulnerability scan |
| Cross-compile | Verify darwin/amd64, darwin/arm64, windows/amd64, windows/arm64 |
| Metric | Value |
|---|---|
| Test packages | 7/7 passing |
| Coverage | ~79% overall (styles 99%, components 90%, config 88%) |
| Test files | 39 test files for 44 source files |
| Test:source ratio | 1.9:1 lines |
| Test patterns | Table-driven, t.Helper(), standard library only |
| Race detector | ✅ CI + local (when gcc available) |
| Shuffle | ✅ Randomized test order |
| Benchmarks | SQLite queries, theme derivation, session list rendering |
| WSL cross-test | ✅ Unix code paths via mage testWSL |
These enhance the local development experience. All skip gracefully if not installed:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest # Extended linting
go install golang.org/x/vuln/cmd/govulncheck@latest # Vulnerability scanning
go install mvdan.cc/gofumpt@latest # Strict formatting
go install golang.org/x/tools/cmd/deadcode@latest # Dead code detectionSee CONTRIBUTING.md for development setup and guidelines.
See SECURITY.md for the security policy and vulnerability reporting.
- Bubble Tea — TUI framework
- Lip Gloss — Terminal styling
- Bubbles — TUI components
- modernc SQLite — Pure-Go SQLite driver












