cc-session-alias (command ccsa) gives Claude Code sessions human-memorable aliases so you can list, search, and resume them without recalling UUIDs.
简体中文 · English
Claude Code session IDs are hard-to-remember UUIDs; the native --name flag can only be set at startup, and the interactive --resume picker is scoped to the current directory. ccsa adds after-the-fact, cross-project, semantic alias management: name any session, then resume it with the shortest possible command.
# From source (recommended) — go install names the binary cc-session-alias;
# link it as ccsa so it is on PATH under the short name:
go install github.com/bigwhite/cc-session-alias@latest
ln -s "$(go env GOPATH)/bin/cc-session-alias" "$(go env GOPATH)/bin/ccsa"
# Manual build (produces ccsa directly)
git clone https://github.com/bigwhite/cc-session-alias
cd cc-session-alias && make build
sudo mv ccsa /usr/local/bin/Single binary, zero runtime dependencies, CGO_ENABLED=0. Cross-compile all four targets (linux/darwin × amd64/arm64):
make release # produces ccsa-<os>-<arch> in the repo rootNine commands (plus version and cobra's default completion/help). Examples match the cmd/*.go implementation.
Set an alias for a session. Without --id, the most recent session in the current working directory is auto-discovered (two-layer scan of ~/.claude/sessions/*.json and ~/.claude/projects/<encoded>/*.jsonl).
$ ccsa set frontend-auth
✓ Alias "frontend-auth" → session 198d4193 (cc-gateway, 2026-08-01)
$ ccsa set debug-tmp --id 198d4193-3a16-4051-8dfa-a9dac573c933 --force
✓ Alias "debug-tmp" → session 198d4193 (cc-gateway, 2026-08-01)Alias rule ^[a-zA-Z0-9_-]+$, length 1–64; --id must be UUID v4 format. When an alias already exists, an interactive terminal (stdout is a TTY) prompts for confirmation; in non-interactive contexts --force is required to overwrite, otherwise it errors out (exit 1).
Print the full session UUID for an alias (UUID only, one line), for pipe composition.
$ ccsa get frontend-auth
198d4193-3a16-4051-8dfa-a9dac573c933
$ claude --resume $(ccsa get frontend-auth)If the alias does not exist, an error is printed to stderr and exit 1.
List all aliases in a four-column table: ALIAS / SESSION ID (first 8 chars) / PROJECT (last path segment) / CREATED (YYYY-MM-DD).
$ ccsa list
ALIAS SESSION ID PROJECT CREATED
frontend-auth 198d4193 cc-gateway 2026-08-01
backend-api e347569c startup-ideas 2026-07-31--project supports two match modes; either one matching outputs the row: (1) full-path prefix match; (2) path-suffix shorthand (<path> ends with /<filter> or equals <filter>). The suffix mode enforces a full path-component boundary, so --project startup does not match startup-ideas.
$ ccsa list --project startup-ideas
ALIAS SESSION ID PROJECT CREATED
backend-api e347569c startup-ideas 2026-07-31With no aliases or no matches, prints No aliases found. and exits 0.
Print alias details and the session's live state.
$ ccsa info frontend-auth
Alias: frontend-auth
Session ID: 198d4193-3a16-4051-8dfa-a9dac573c933
Project: /root/go/src/github.com/bigwhite/cc-gateway
Created: 2026-08-01 14:30:00
Updated: 2026-08-01 14:30:00
Status: active (idle)Status values: active (idle) / active (busy) / exited / gone. If the alias does not exist, exit 1.
Rename an alias. The associated session, project, and creation time are preserved; only Updated is refreshed.
$ ccsa rename frontend-auth fe-auth
✓ Renamed "frontend-auth" → "fe-auth"new must match the alias rule and not collide with an existing alias, otherwise exit 1.
Remove an alias; the session itself is unaffected.
$ ccsa rm debug-tmp
✓ Alias "debug-tmp" removedIf the alias does not exist, exit 1.
Clean up stale aliases pointing to sessions that have fully disappeared (Status gone).
$ ccsa prune --dry-run
Would remove:
old-feat → a1b2c3d4 (session not found)
$ ccsa prune
✓ Removed 1 stale aliasWith nothing to prune, prints Nothing to prune. and exits 0. --dry-run only lists; without --dry-run it deletes and persists. For multiple results the count uses stale alias (1) or stale aliases (≠1).
One-shot resume: resolve alias → UUID, then replace the current process with claude --resume <uuid> [args...].
$ ccsa r frontend-auth --model fable
# process replaced by claude --resume 198d4193-... --model fableBefore launching, r auto-cd's into the session's recorded project directory (the cwd captured when the alias was set). Claude Code scopes session-ID lookup to the current project directory and its worktrees, so resuming a UUID from an unrelated directory would otherwise report "No conversation found with session ID" — the auto-cd is what makes ccsa r <alias> work from any directory for any project's session. If the recorded directory no longer exists, r prints a warning and resumes in the current directory instead of aborting.
The r subcommand enables DisableFlagParsing; all arguments after the alias are passed through to claude verbatim (e.g. --model, --print). The claude binary is resolved via exec.LookPath("claude"); if not found, it errors out (exit 1). If the alias does not exist, exit 1. ccsa r -h / ccsa r --help still prints the usage line (cobra's automatic help is disabled in this mode; r handles it itself).
Install/remove the optional shell wrapper (zsh → ~/.zshrc, bash → ~/.bashrc, auto-detected from $SHELL).
$ ccsa install-hook
✓ Shell wrapper installed in /home/user/.zshrc
$ ccsa uninstall-hook
✓ Shell wrapper removed from /home/user/.zshrcRepeated installs are idempotent (skipped if the marker block is detected); removal only deletes the marker block and preserves the rest of the file; if the rc file or marker block is absent, prints Shell wrapper not installed and exits 0.
Print the build version. make build/make release stamp it from git describe (e.g. v0.1.1); go install without ldflags prints dev.
$ ccsa version
ccsa version v0.1.1The claude() shell function injected by install-hook intercepts only the first argument of --resume/-r: if that argument is not UUID-format (does not match ^[0-9a-f]{8}-), it tries ccsa get to resolve it; on success it calls the real claude --resume with the UUID, on failure it passes the original argument through. UUID-format first arguments are passed through with zero overhead, without forking ccsa. Any other claude usage (e.g. claude -p ...) is never intercepted.
ccsa install-hook # inject the wrapper
source ~/.zshrc # or reopen the terminal
claude --resume frontend-auth # equivalent to claude --resume <uuid>
claude --resume 198d4193-3a16-4051-8dfa-a9dac573c933 # zero-overhead passthrough
ccsa uninstall-hook # remove the wrapper# Name the most recent active session in the current project dir
ccsa set agent-evolution
# Cross-project overview
ccsa list
# Inspect details and live state
ccsa info agent-evolution
# One-shot resume (--model passed through to claude)
ccsa r agent-evolution --model fable
# Clean up stale aliases
ccsa prune --dry-run
ccsa pruneThree ways to resume a session:
ccsa r <alias>— shortest command, process replacement.claude --resume <alias>— after installing the wrapper, keep the native muscle memory.claude --resume $(ccsa get <alias>)— without the wrapper, explicit pipe composition.
- Aliases are persisted in
~/.cc-session-alias/aliases.json: directory mode0700, file mode0600, atomic writes (writealiases.json.tmpthenos.Rename). - On JSON corruption, the file is backed up as
aliases.json.bak, an empty store is initialized, a warning is printed to stderr, and execution continues. ccsadoes not browse or search session contents, does not create sessions, and does not replaceclaude --resume— it only maintains the alias-to-UUID mapping and resolves it before invokingclaude.
A Makefile wraps the common workflows (make help lists all targets):
make all # build + test + vet
make cover # core coverage: store + discovery (target >= 80%)
make bench # benchmarks with -benchmem
make clean # remove built artifactsThe underlying go commands, if you prefer:
go build ./...
go vet ./...
go test ./...
go test -cover ./internal/store ./internal/discovery # core coverage >= 80%
go test -bench=. ./...Layered architecture (dependency injection, no global state):
cmd/ argument parsing, interaction, output formatting
→ internal/store alias JSON CRUD (pure interface)
→ internal/discovery two-layer session scan
→ internal/claude claude binary resolution and process replacement
→ internal/model plain structs and validation
internal/* is not importable externally. Commit messages follow Conventional Commits.
If you find ccsa useful, consider buying me a coffee!
WeChat Pay / Alipay:

