Skip to content

cookbook: add copilot-session-resume recipe - #469

Open
rychkov wants to merge 1 commit into
umputun:masterfrom
rychkov:cookbook-add-copilot-session-resume-recipe
Open

cookbook: add copilot-session-resume recipe#469
rychkov wants to merge 1 commit into
umputun:masterfrom
rychkov:cookbook-add-copilot-session-resume-recipe

Conversation

@rychkov

@rychkov rychkov commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Add a cookbook recipe wrapping the copilot command so each agterm tab reopens its own Copilot CLI session after a restart. Copilot's --session-id flag both creates and resumes a session under a given id, so the function needs no mapping file or existence check: it always pins the tab's AGTERM_SESSION_ID as the session id unless the invocation should pass through untouched (subcommand, explicit --resume/--session-id/--continue, headless -p, etc).

The script is strict POSIX sh, verified with sh -n/bash -n/zsh -n/ dash -n, and functionally tested with a stub copilot binary across sh, bash, dash and zsh for passthrough, injection, and restore-replay cases, with no variable leakage into the sourcing shell.

Co-authored-by: Copilot

Add a cookbook recipe wrapping the copilot command so each agterm tab
reopens its own Copilot CLI session after a restart. Copilot's
--session-id flag both creates and resumes a session under a given
id, so the function needs no mapping file or existence check: it
always pins the tab's AGTERM_SESSION_ID as the session id unless the
invocation should pass through untouched (subcommand, explicit
--resume/--session-id/--continue, headless -p, etc).

The script is strict POSIX sh, verified with sh -n/bash -n/zsh -n/
dash -n, and functionally tested with a stub copilot binary across
sh, bash, dash and zsh for passthrough, injection, and restore-replay
cases, with no variable leakage into the sourcing shell.

Co-authored-by: Copilot
@rychkov
rychkov requested a review from umputun as a code owner August 20, 2026 16:04

@umputun umputun left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one blocker, three smaller fixes, one note.

the function always returns 0. every path in copilot() runs unset after command copilot, and POSIX return with no argument yields the status of the last command, which is that unset. So the wrapper reports success whatever copilot did: copilot -p "..." && git commit commits after a failed prompt, a || fallback never fires, and an exit-status prompt segment stays green after a crash. With copilot not installed the shell prints command not found and the function still returns 0.

the three sibling recipes keep the status, but they use local, which you deliberately avoid to stay POSIX so the file works in bash. rc=$?; return $rc does not work here either, since the helper has to be unset and the unset is what destroys the status. What keeps your POSIX property is making command copilot "$@" the last statement on every path, with each unset moved in front of its invocation and the pinned argv built first:

set -- --session-id "$_copilot_resume_sid" "$@"
unset _copilot_resume_sid
command copilot "$@"

a function's positional parameters are restored on return, so set -- inside copilot() leaves the caller's alone.

the passthrough list misses the documented long form of --prompt. it carries --session-id=*, --resume=* and --connect=*, but only the bare --prompt. GitHub's current command reference spells that option -p PROMPT, --prompt=PROMPT, and documents no space form for the long flag, so the list covers a spelling the docs do not have and misses the one they do. copilot --prompt="..." runs as copilot --session-id <tab-id> --prompt=..., writing a scripted one-shot into that tab's pinned interactive conversation, which Limits says cannot happen. Adding --prompt=* to the case covers it.

setup points bash users at the wrong file. line 23 says the function has to go in ~/.zshrc or ~/.bashrc and calls .bash_profile too early. agterm's panes run a login shell, and a login bash reads ~/.bash_profile, ~/.bash_login or ~/.profile, not ~/.bashrc. The /etc/profile to /etc/bashrc chain on macOS does not bridge that. So the documented install does nothing in bash, which is the shell this recipe adds over the three zsh-only ones. Point bash users at ~/.bash_profile, or at the usual stanza that sources ~/.bashrc from it.

the check on line 50 cannot pass. it says to run copilot, say a few words, quit it, then restart the terminal. Quitting copilot first is what breaks it: agterm captures the pane's foreground command at quit, and a pane sitting at its shell prompt captures nothing, so the tab comes back as a plain shell and a correct install reads as broken. Line 60 already describes it correctly. Drop the quit step, and quit agterm while copilot is still the pane's foreground job.

minor, non-blocking: subcommand names are matched in every argument position, so copilot -C help treats the directory value as the help subcommand and skips pinning. Not worth a full argument parser, just noting it.

everything else checks out: the subcommand set matches the reference exactly, and --session-id's documented conflicts (--resume, --continue, --connect) all already pass through, so the pinning never competes with another session selector.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants