https://github.com/gfarb/copilot-session-manager
Browse, search, resume, and clean up your GitHub Copilot CLI sessions from a terminal UI.
https://github.com/gfarb/copilot-session-manager
copilot copilot-cli
Last synced: about 1 month ago
JSON representation
Browse, search, resume, and clean up your GitHub Copilot CLI sessions from a terminal UI.
- Host: GitHub
- URL: https://github.com/gfarb/copilot-session-manager
- Owner: gfarb
- License: mit
- Created: 2026-06-05T17:30:06.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-07T20:31:04.000Z (about 1 month ago)
- Last Synced: 2026-06-07T22:20:47.850Z (about 1 month ago)
- Topics: copilot, copilot-cli
- Language: Go
- Homepage:
- Size: 1.61 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
# 🗂️ `csm`
### Copilot Session Manager
***Browse, search, resume, and clean up your GitHub Copilot CLI sessions from a terminal UI.***

> [!TIP]
> `csm` → fuzzy-search your sessions → enter to resume → o to open files → d to delete.
---
## Why this exists
Copilot CLI stores every session locally on disk: a SQLite database plus per-session folders with event logs, generated artifacts, checkpoints, and plan files.
There's no built-in way to browse any of it. `csm` gives you:
| | |
|---|---|
| 🔍 **Find** | Fuzzy-search across summaries, repos, branches, file paths, refs, and messages |
| 📂 **Browse** | Files the assistant touched, parsed from `events.jsonl` |
| 🎨 **Open** | Artifacts, plans, and checkpoints directly from the TUI |
| ⏪ **Resume** | One keystroke, correct cwd, clean handoff to `copilot --resume` |
| 🗑️ **Delete** | Hard-delete with safety checks (refuses to delete active sessions) |
| 🚀 **Integrate** | `/session-manager` slash command launches `csm` from inside Copilot CLI |
---
## Install
```sh
curl -fsSL https://raw.githubusercontent.com/gfarb/copilot-session-manager/main/scripts/install.sh | bash
```
The installer downloads the latest release binary and the `/session-manager` slash command extension:
| What | Where |
|---|---|
| `csm` binary | `~/.local/bin/csm` (override with `INSTALL_DIR`) |
| Slash command | `~/.copilot/extensions/csm/extension.mjs` |
> [!IMPORTANT]
> Make sure `~/.local/bin` is on your `PATH`. The installer verifies the download against a published `sha256` sidecar.
Build from source
Requires **Go 1.26+**.
```sh
git clone https://github.com/gfarb/copilot-session-manager
cd copilot-session-manager
go build -o ~/.local/bin/csm .
# (optional) slash command
mkdir -p ~/.copilot/extensions/csm
cp extension/extension.mjs ~/.copilot/extensions/csm/extension.mjs
```
Verify it works:
```sh
csm -h
csm list | head -3
```
---
## Keyboard Shortcuts
Two-pane layout: session list on the left, tabbed preview on the right.
#### Navigation
| Key | Action |
|---|---|
| ↑ ↓ / j k | Move through the list |
| / | Fuzzy filter (searches summary, repo, branch, cwd, file paths, refs, and user messages) |
| enter | **Resume** the session (`chdir` + `copilot --resume`) |
| d | **Delete** the session (confirm with y) |
| c / C | Copy session **id** / **cwd** to clipboard |
| 1 2 3 4 | Jump to tab |
| [ / ] | Cycle tabs |
| tab | Swap focus between list and preview |
| ? | Toggle key hints |
| q / ctrl-c | Quit |
#### Files tab
Files found in session metadata and tool events:
| Badge | Meaning |
|---|---|
| `[plan]` | Session plan (`plan.md`) |
| `[artifact]` | Generated files in `files/` |
| `[checkpoint]` | Checkpoint files |
| `[view]` `[edit]` `[create]` | Workspace files parsed from `events.jsonl` |
Paths are displayed relative to the session's cwd when possible:
```text
./pkg/quota/limiter.go <- inside the session's cwd
~/other-repo/foo.go <- outside cwd, inside $HOME
/etc/hosts <- absolute path
files/dashboard.json <- session artifact
```
| Key | Action |
|---|---|
| o | Open with macOS default app |
| O | Reveal in Finder |
| v | Open in VS Code |
| e | Open in `$EDITOR` (TUI suspends, resumes on exit) |
| y | Copy full path |
#### Refs tab
PRs, issues, commits, and other GitHub URLs mentioned in the session, parsed from `events.jsonl`.
| Key | Action |
|---|---|
| o | Open URL in browser |
| y | Copy URL |
#### Overview & Turns
- **Overview** (1): IDs, dates, summary, first/last user message
- **Turns** (4): Scrollable conversation history with timestamps
---
## `/session-manager` Slash Command
Type this inside any live Copilot CLI session:
```
/session-manager
```
`csm` opens in a new terminal window (Ghostty, iTerm, or Terminal.app, detected via `TERM_PROGRAM`). Your active session keeps running undisturbed.
Pass args through:
```
/session-manager --print
```
---
## CLI Subcommands
```sh
csm # interactive TUI (default)
csm --print # TUI, but enter prints "\t" to stdout
csm list # TSV dump: id, display-line, search-blob
csm preview # human-readable session detail
csm -h # help
```
`--print` is useful for shell scripts:
```sh
read -r CWD ID < <(csm --print)
echo "picked $ID in $CWD"
```
---
## Configuration
All optional. Everything works out of the box.
| Env var | Default | What it does |
|---|---|---|
| `CSM_DB` | `~/.copilot/session-store.db` | Session database path |
| `CSM_SESSION_STATE` | `/session-state` | Session state directory |
| `CSM_BIN` | `csm` | Binary the slash command launches |
| `EDITOR` | `vi` | Editor for the e action |
| `INSTALL_DIR` | `~/.local/bin` | Where the installer puts the binary |
| `CSM_VERSION` | `latest` | Pin a specific release tag |
---
## How it works
- **SQLite** - reads from `~/.copilot/session-store.db` via [`modernc.org/sqlite`](https://gitlab.com/cznic/sqlite) (pure Go, no CGo). A read-only connection handles queries; a separate writable connection is opened only for deletes.
- **Events parser** - scans `events.jsonl` line by line so multi-megabyte payloads don't silently truncate.
- **Resume** - on enter, the TUI exits, `os.Chdir`s to the session's cwd, then `syscall.Exec`s `copilot --resume=`. The process is replaced in one move. `chdir` failure is fatal to prevent resuming in the wrong directory.
- **Delete** - a single transaction across all session tables, then `os.RemoveAll` on the session-state folder. Refuses if `inuse.*.lock` is present. Tolerates schema drift across Copilot CLI versions.
---
## Development
```sh
go build -o csm . && go test ./...
./csm
```
Iterating on the extension:
```sh
# Edit extension/extension.mjs, then:
cp extension/extension.mjs ~/.copilot/extensions/csm/extension.mjs
# In your live Copilot CLI session, /clear forces extension reload.
```
Cutting a release: push a `v*` tag. The workflow at `.github/workflows/release.yml` cross-compiles darwin arm64/amd64 and attaches the archives to a GitHub Release.
```sh
git tag v0.1.0
git push origin v0.1.0
```