Agent Deck v1.16.28
Terminal session manager for AI coding agents.
Installation
Homebrew (recommended):
brew install asheshgoplani/tap/agent-deckQuick Install:
curl -fsSL https://raw.githubusercontent.com/asheshgoplani/agent-deck/main/install.sh | bashGo Install:
go install github.com/asheshgoplani/agent-deck/cmd/agent-deck@v1.16.28What's new in 1.16.28
Security and toolchain
- Release binaries are built with Go 1.26.9 and
golang.org/x/netv0.60.0. This clears the 13 advisories govulncheck reported against 1.16.27: GO-2026-6617 (HTTP/2 server crash from an HPACK encoder race), GO-2026-6612, GO-2026-6611, GO-2026-6610 and GO-2026-6603 (HTTP/2, fixed in x/net v0.60.0 and Go 1.26.9), and GO-2026-6613, GO-2026-6609, GO-2026-6605, GO-2026-6608, GO-2026-6607, GO-2026-6604, GO-2026-6600 and GO-2026-6599 (net/http, net/textproto, crypto/tls, os and html/template, fixed in Go 1.26.9). agent-deck serves no HTTP/2, so GO-2026-6617 was not reachable in practice; 1.16.27 listed it as a known issue. The dependency updates from #2428 (thanks @dependabot) are included.
Fixes
- The embedded terminal holds an incomplete key sequence until the rest of it arrives, so held arrow keys in application cursor mode and modified keys such as Ctrl+Right reach the pane as one key instead of a stray
ESC Oor a partial CSI. A lone Escape is still sent after the short quiet period (#2551, thanks @yalp). - The web terminal attaches with
TERM=xterm-256colorandCOLORTERM=truecolorinstead of the launching terminal's TERM, so tmux no longer sends colon-form RGB (for example under Ghostty) that the browser terminal draws in the wrong colours, and the terminal background matches its frame. Exact RGB needs tmux 3.6 or newer; older tmux sends the nearest 256-colour shade (#2553, thanks @dtvillafana). - The footer's tmux budget warning no longer flashes after Ctrl+Q: status bar refreshes for attached clients and the cache refreshes after an attach are not charged to the status pass, the warning needs three consecutive breaches like the duration warning, and
healthanddoctorno longer flag samples taken with zero sessions (#2554, thanks @dtvillafana). - The web sidebar can rename a group again: press
ron a selected group or use the new rename button on the group header. A rename that moves the group to a new path keeps it selected, and on a read-only server the button is hidden andrshows the usual notice (#2555, reported by @bautrey). [shell] exit_to_shellnow applies to pi and Oh My Pi (omp) sessions:/exitleaves the pane in your shell, and pi forks keep working with the setting on (#2556, reported by @Djeeteg007).update --checkandupdate --check --jsontell a TUI that is attached to a session apart from a hung one: each TUI reportsattachedandattached_since, and the line reads "attached to a session since HH:MM: auto-update resumes on detach". After an unattended update by the notify daemon, its own launch agent no longer stays listed as pending once the daemon runs the new build.- Every explicit help request (
--help,-h,-help, andfile help) prints the whole usage on stdout with exit 0. About 50 older commands used to split their help across stdout and stderr or print all of it on stderr, andfile helpexited 1. This also covers the commands added in this release, such assession image-upload --help, locally and throughremote <name>. Usage printed for a usage error stays on stderr with a non-zero exit. - A session restart no longer fails with a
tool_data.last_activity_atconflict when a status write lands at the same moment: the later of the two timestamps is kept. A cleared or malformed value still conflicts (#2550, thanks @arnzchen). - Recall ingest of large Gemini transcripts uses less memory: the reader reuses one scan buffer instead of growing a new one for every long value.
Features
[mcps.NAME.oauth]gives Claude a pre-registered OAuth client for an HTTP or SSE MCP:client_id,callback_port,auth_server_metadata_urlandscopesmap onto Claude Code'soauthsettings in every MCP scope agent-deck writes. The client secret stays in Claude's keychain; complete the login once with/mcp. Codex, Cursor and OpenCode configs are unchanged (#2552, reported by @BenjaminTanguay).events follow --read-onlyandevents stats --read-onlywatch a profile's event bus without side effects (no writer, no log repair, no demand lease, no queued send recovery);remote <name> events followforwards the flag.[performance] status_interval_seconds(1 to 10, default 2) sets how often the TUI refreshes session status.session show --jsonincludesopencode_session_idfor OpenCode sessions (#2550, thanks @arnzchen).
Status line and usage
usage statusline --session <id|title> --jsonreturns the last status-line record of a Claude session: model, working directory, context use and tokens, the 5h and 7d limits, andaccountandpermission_modewhen known. Each update is also published as ausage.statuslineevent. Only these fields are stored; prompt text and transcript content never are.limits --jsonandremote <name> limits --jsonlist the default Claude login (~/.claudeor the resolvedCLAUDE_CONFIG_DIR) when no[profiles.<name>.claude]slot owns it, nameddefaultand marked"default": true, with the 5h and 7d windows its statusLine feed caches. Without a feed it is listed with theno feed: run agent-deck hooks installerror. A login that a slot owns is listed once, under the slot, and no slot is created.hooks installwraps the statusLine of the active Claude config and of every configured account slot withusage statusline-wrap, which records the payload and then runs your previous command with the same output. Without a previous statusLine, a short default line (model, context, 5h, 7d) is shown.hooks uninstallrestores the original from a backup next tosettings.json. Opt out with[claude] statusline_feed = false.
Sending
session send --require-input-prompttypes only into a ready input prompt. An open menu or picker is refused withmenu_openand a missing prompt withcomposer_blocked, both before any key is typed; a menu that withholds Enter after typing is reported astyped_not_submitted. Queued sends keep the guard, andremote <name> session sendrefuses the flag against a remote that does not support it.- Menu detection needs real picker evidence (two or more selectable choices, or a picker instruction), so menu words in the input box or in a delivered message no longer read as an open menu. Plain sends see fewer false
interactive-menusubstates andmenu_openrefusals too. session queue list <session>,session queue release <id>andsession queue cancel <id>show, send now or drop a durable queued send. Release is a guarded send that skips only the wait; a busy Codex, Pi, shell or unknown target is still refused without typing. Every answer carries anoutcome,session show --jsonlists the session'squeue, andremote <name> session queue ...works on the remote's own queue.
Sessions
session image-upload <id> --name <file> [--json]stages an attachment read from stdin (png, jpg, gif, webp or pdf, up to 20 MiB) in an owner-only folder on the host that owns the session, never overwrites an existing file, and prints its absolute path. Staged files are removed with the session and pruned after 7 days.remote <name> session image-uploadforwards stdin, andsession send --imageaccepts pdf.- A tracked command started with
add -cmdorlaunch -cmdreports theprocess-exitedsubstate and itsexit_codewhen it ends, inlist --json,status -v --json,session show --json, remote rows and status events. Exit 0 reads idle, any other code reads error. - A Claude session running a tool in a turn it started itself shows running instead of waiting:
hooks installadds a synchronous PreToolUse hook, one short handler run per tool call. agent-deck open <file|url> [--session <id|title>]asks the macOS app to show a report or page in its Browser panel for that session, local or remote (macapp.openevent, answered withmacapp.open.ack).agent-deck file bundle <dir|file> --session <id>streams a folder as an uncompressed tar for the app to fetch.
Remotes
remote <name> recall timeline,recall follow,events followandsession send-statusrun on the remote host in one ssh round trip each, on their own channel. A remote without them answersunsupported remote commandwith its version.- A forwarded follow (
remote <name> events follow,remote <name> recall follow) runs while its stdin stays open and ends with exit 0 when stdin closes; started with stdin from/dev/nullit ends within seconds with no output. This was always the design;remote --helpand the docs now say so. Long-lived consumers should hold a pipe on stdin and close it to stop. Local follows ignore stdin. remote <name> limits [--json]returns the remote's ownlimitsoutput.recall timeline --before <cursor> --limit Npages back through older entries, and snapshots carrybefore_cursor.events followaccepts--jsonland--sinceas aliases of--jsonand--after.list --json,list --all --jsonandremote sessions --jsonrows carrytranscript_pathandclaude_session_id, pluscodex_session_idin all-profile and remote rows. Remote rows carry"favorite": truefor favourite sessions.
Costs
costs daily,costs sessions,costs models,costs groupsandcosts budgets(with--json) return the data behind the costs dashboard.sessions,modelsandgroupstake--period today|7d|30d|all|week|month, and the web costs endpoints accept?period=.[costs] enabled = false, globally or under[profiles.<name>.costs], turns cost tracking off.
Maintenance
- Dead code and repo hygiene: unused helpers, wrappers, widgets, test helpers and fixtures are removed, stray files at the repo root and stale diagram copies are gone, broken conductor doc links are fixed, and
install-useranduninstallare declared phony in the Makefile. Two removals are hardening: an unused self-update path that installed a downloaded binary without checksum verification, and an unused entry point that ran the worktree destruction hook without the consent check. Neither had a caller. - CI and contributor tooling: a guard keeps every Go toolchain pin in step with go.mod (and the golangci-lint and gotestsum versions in step across files); superseded PR runs are cancelled and every job has a timeout; govulncheck reports one annotation and summary row per advisory and uploads SARIF; the comms matrix and native SSH jobs run only for Go-relevant changes; the stalled-CI notifier fires on runs that wait for approval; the PR and issue notifiers are hardened and documented as disabled; the PR intake check parses headings tolerantly and exempts maintainers and bots (still observe-only); a maintainer script approves held fork runs on live heads (dry run by default);
testutil.SkipIfRootskips permission tests that cannot hold as root;scripts/verify-docker.shandmake verify-dockerreproduce the CI Go checks in Docker; and the contributor docs match the self-check container guard and the intake gate.
Upgrading
- Building from source needs Go 1.26.9; with the default
GOTOOLCHAIN=auto, Go downloads it on first use. Locally builtagentdeck-funccheckandagentdeck-benchimages get new tags and are rebuilt on first use. - Status line: if agent-deck's Claude hooks are installed, the next
hooks install(or the automatic hook repair at start) wraps the statusLine of the active Claude config, or adds the default line when there is none. Your existing status line prints exactly what it printed before. Opt out with[claude] statusline_feed = false, which also stops wiring named account slots. Runagent-deck hooks uninstallbefore downgrading, so the original statusLine is restored. If 1.16.27 and 1.16.28 are installed side by side (for example a local build next to the released one), runhooks installfrom one of them only: switching back and forth can wrap the statusLine twice.hooks uninstallfrom the version that installed it restores the original. - Hooks:
hooks installadds a synchronous PreToolUse entry. Upgrade each host, remotes included, and runagent-deck hooks installthere; runagent-deck hooks uninstallbefore downgrading. An AskUserQuestion picker in a turn Claude started itself now reads as running, as it already did in typed turns. - Tracked commands: an
add -cmdorlaunch -cmdcommand now runs as the pane's first process under non-interactivebash -c, so interactive rc files are not loaded; an alias or an rc-only PATH entry can make it exit 127 (use a full path or a script). When the command exits or is interrupted, the pane stays closed instead of returning to a shell, andsession restartruns it again. Shell sessions with a command created from the TUI are not tracked yet. - Sending:
--require-input-promptis opt-in, but the stricter menu detection applies to every send, and a queue release is always a guarded send. - Costs: with
[costs] enabled = false,costs summarynow exits 1 withcost tracking is off in this profileinstead of printing stored totals, and a remote with tracking off shows no costs. - File bundle: a file argument exports its whole folder (up to 20 MiB; symlinks and special files are refused). Keep reports for
agent-deck openin a folder of their own. - Help output:
<command> --helpnow prints on stdout. A script that read help from stderr should read stdout (2>&1covers both). - Limits: on installs with account slots,
limits --jsongains one entry for the default login when it exists and no slot owns it. Treat entries with"default": trueas the default account. - Known issue:
harness list --jsoncan reportlimit_reached: falsefor Claude while every configured account slot is at 100%, when the default login (no slot owns it) has a stale status-line record. Its stale windows count as not reached and mask the slots. A fix is planned for the next release; until then, read the per account windows inlimits --json. - Update status: fleet watches that alert on
ticking: falseinupdate --check --jsoncan skip TUIs withattached: true. - Web: the service worker cache version moves to v23, so installed web clients load the new assets once.
- Remote reads and actions: forwarded
recall,events follow,session send-status,session queue,limits,session image-uploadand the guarded send need the remote to run 1.16.28 as well. Update it withagent-deck remote update <name>; until then the remote answers with an update hint.
Thanks to @yalp, @dtvillafana and @arnzchen for their pull requests, to @BenjaminTanguay, @bautrey and @Djeeteg007 for their reports, and to @dependabot for the dependency updates.
Full Changelog: v1.16.27...v1.16.28