Skip to main content

textsessions

A terminal UI and CLI for managing Claude Code sessions across multiple Git repos.

If you work with Claude across many projects, sessions accumulate fast. textsessions gives you a searchable, filterable view of all of them — with resume, tagging, priority, and cleanup built in.

textsessions view

![TUI showing session list with repo, profile, tags, priority, and last-active columns]

Claude Code only. textsessions is built and tested exclusively with Claude Code. It reads the .jsonl session files that Claude Code writes to disk and is not compatible with other AI coding assistants.


Requirements

  • Python 3.12+
  • fish shell — required for --resume and new session launch
  • Claude Code CLI (claude)

Optional integrations (auto-detected at runtime):

  • textaccounts — profile isolation (separate optional package)
  • textproxy — local token proxy for tracking context consumption

Install

pip install textsessions

With multi-account support (textaccounts):

pip install textsessions[accounts]

Or from source:

git clone https://github.com/paperworlds/textsessions
cd textsessions
pip install -e ".[accounts]"

Quick start

# 1. Detect repos from existing Claude session history
textsessions init

# 2. Build session indexes from .jsonl files
textsessions reindex

# 3. Launch the TUI
textsessions view

TUI

Launch with textsessions view (or alias ts).

Sessions are grouped by repo and sorted by last-active. The right panel shows full detail for the selected session, including token proxy stats if textproxy is running.

When resuming a session inside tmux, the tmux window is automatically renamed to the session name for easy identification across panes.

Keyboard shortcuts

Key Action
Enter Resume session (suspends TUI, launches Claude, returns; renames tmux window)
n New session (profile, repo, optional name)
/ Filter by name, description, or slug
a Toggle: current repo ↔ all repos
t Tag / untag (comma-separated; prefix - to remove)
p Set priority (H0 = urgent, 1–3, or clear)
r Rename (sets a short display name + description)
x Pin / unpin session
y Toggle pinned sessions visibility
d Archive (hidden but recoverable)
D Hard delete (confirmation required)
g Toggle ghosts & orphans only view
s Sort by priority instead of last-active
ctrl+r Reindex current repo
c Open repo config view
? Help
q Quit

CLI reference

View

textsessions view             # launch the TUI
textsessions view --config    # open repo config view

Add repos

textsessions add /path/to/repo                          # auto-label from dirname
textsessions add /path/to/repo --label myrepo           # custom label
textsessions add /path/to/repo --profile work           # assign a profile
textsessions add /path/to/projects --recursive          # scan one level deep

Sessions

# List sessions
textsessions sessions
textsessions sessions --repo mono --tag auth --limit 10

# Resume a session by name (tab-completion supported)
textsessions sessions --resume my-feature-work

# Filter to current folder's repo
textsessions sessions --current-folder

The table shows: Name, Info (description if set, otherwise the auto-generated slug), Repo, Profile, Tags, Priority, Last Active.

Rename and tag

# Rename a session (tab-completes session names)
textsessions rename my-feature-work "Better title for this session"

# Add tags
textsessions tag my-feature-work auth,api

# Remove tags (prefix with -)
textsessions tag my-feature-work -auth

# Add and remove in one shot
textsessions tag my-feature-work api,-old,keep

AI search

textsessions search "add client to privatelink"
textsessions search "auth refactor" --repo mono --limit 5 --json

Sends session metadata to Claude and returns ranked matches. Requires a Claude command to be configured as ui.ai_search_profile (default: claude).

Cleanup

# Dry-run report of ghosts (dead repos) and orphans (throwaway hex-named sessions)
textsessions scan-ghosts

# Archive all (reversible — hides from normal view)
textsessions scan-ghosts --archive

# Bulk archive for one repo without confirmation
textsessions scan-ghosts --repo mono --discard

# Mark a hex-named session as "keep" (exclude from future orphan detection)
textsessions scan-ghosts --keep abc123 --repo mono

# Hard delete (irreversible)
textsessions scan-ghosts --delete --yes

Rename hex-named sessions

Claude auto-names new sessions with a hex ID. When you use /rename inside a session, textsessions can pick that up:

textsessions index auto-rename --dry-run   # preview
textsessions index auto-rename             # apply to all repos

Only renames sessions that have a /rename entry in their .jsonl — never guesses.

Reindex

textsessions reindex             # all configured repos
textsessions reindex --repo mono # one repo

Rebuilds YAML indexes from .jsonl files. Preserves tags, priority, pinned state, and custom names.

Export

textsessions tree                          # YAML tree of all repos + sessions
textsessions tree --format json -o out.json
textsessions tree --repo mono --include-archived

Proxy stats

textsessions proxy    # token usage + cost for today, by model

Reads from textproxy's cache. Shows nothing if textproxy is not running.

Config

textsessions config   # show current config path and repo list

Configuration

~/.config/textsessions/config.toml

[[repos]]
path = "/Users/you/projects/myrepo"
label = "myrepo"
profile = "default"          # maps to a textaccounts profile (optional)

[[repos]]
path = "/Users/you/projects"
label = "personal"
profile = "personal"
recursive = true             # scan all git repos one level deep

[ui]
startup_repo = "current"     # "current" = auto-filter TUI to cwd repo | "all" = show everything
claude_cmd = "claude"        # command to launch Claude; {profile} is substituted if present
                             # e.g. "claude-{profile}" dispatches to fish functions like claude-work
ai_search_profile = "claude" # command used for `textsessions search`

[integrations]
textaccounts = true  # use textaccounts for profile isolation if configured (see below)
textproxy = true     # inject ANTHROPIC_BASE_URL if textproxy is running on :7474

[proxy]
cache_dir = "~/.cache/textproxy"

Profiles and the claude_cmd template

Each repo has a profile. When launching or resuming a session, textsessions resolves the command to run via claude_cmd with {profile} substituted:

claude_cmd = "claude-{profile}"
# mono (profile=work)    → runs: claude-work
# blog (profile=default) → runs: claude-default

This lets you define fish functions (claude-work, claude-personal, etc.) that set environment or flags before calling claude. Useful for routing to different API keys or base URLs without textaccounts, or alongside it.


Integrations

textproxy

textproxy is a companion paperworlds project — a lightweight local MITM proxy that captures token consumption stats from Claude Code API traffic. It gives subscription users (Claude Team, Claude.ai) visibility into how much context window each session is actually consuming, without modifying Claude Code itself.

If textproxy is running on localhost:7474, textsessions automatically sets ANTHROPIC_BASE_URL before launching Claude. Token usage and cost appear in the TUI detail panel and textsessions proxy.

textaccounts

textaccounts is an optional profile manager that isolates Claude accounts by pointing CLAUDE_CONFIG_DIR at separate config directories — keeping sessions, memory, and auth separate per profile.

Install with pip install textsessions[accounts] to enable. When configured, textsessions automatically injects CLAUDE_CONFIG_DIR before launching or resuming any session whose repo profile matches a registered profile name. Without textaccounts, you can still use custom commands (see Custom Commands section above) or a single default account.

Setup flow

1. Install shell integration:

textaccounts install        # writes fish function + completions to ~/.config/fish/

2. Register your existing Claude config dirs — nothing moves, just registers the paths:

textaccounts adopt work ~/.claude-work
textaccounts adopt personal ~/.claude-personal

3. Switch profiles:

textaccounts switch work       # sets CLAUDE_CONFIG_DIR=~/.claude-work in your shell
textaccounts switch personal   # sets CLAUDE_CONFIG_DIR=~/.claude-personal
textaccounts switch default    # unsets CLAUDE_CONFIG_DIR (back to ~/.claude)

4. Wire repos to profiles in your config:

[[repos]]
path = "/Users/you/work/myrepo"
label = "myrepo"
profile = "work"        # textsessions will inject CLAUDE_CONFIG_DIR for this profile

All commands

textaccounts list                        # show all profiles with path, email, session count, size
textaccounts status                      # active profile, env var sync check, session count
textaccounts adopt <name> <path>         # register an existing dir
textaccounts create <name>               # snapshot current config dir into ~/.textaccounts/profiles/
textaccounts create <name> --worker \
  --from <parent>                        # minimal copy: .claude.json + settings.json only
textaccounts switch <name>               # switch profile (sets CLAUDE_CONFIG_DIR)
textaccounts show <name>                 # print the shell command without executing
textaccounts rename <old> <new>          # rename a profile
textaccounts alias <profile> <alias>     # add a short alias
textaccounts view                        # interactive profile view
textaccounts install                     # install shell integration

Set textaccounts = false or textproxy = false under [integrations] to disable either integration.


How it works

Claude Code stores every conversation as a .jsonl file under ~/.claude*/projects/<repo-key>/. textsessions reads these files and builds a lightweight YAML index per repo at ~/.local/state/claude-sessions/<repo-key>.yaml.

The index stores: session name, profile, last-active timestamp, slug, tags, priority, pinned state, and description. It is rebuilt with textsessions reindex and preserves all user-set metadata across rebuilds.


Ask Claude about this tool

If you use Claude Code, you can paste this prompt to get a quick orientation:

Read the file at docs/features.yaml in this repo and tell me:
1. What textsessions does and who it's for
2. Which features are most relevant to my workflow (ask me 2-3 questions first)
3. The first 3 commands I should run to get started

Or for a deeper dive:

Read docs/features.yaml and give me a tour of textsessions.
For each feature, tell me when I'd use it and show me the exact command.
Start with the ones that solve the most common pain points for heavy Claude Code users.

Roadmap

  • Publish to PyPI
  • Upgrade to Python 3.13
  • Bash/zsh shell support (currently fish only)
  • textsessions doctor — validate config, check for stale paths
  • Session export to markdown
  • Refactor config screen from subprocess to pushed Screen (removes brief flash on c key, enables Enter-to-filter)
  • Polish rename flow — reindex now auto-renames hex sessions from /rename, but edge cases remain: TUI r key doesn't update the tmux window name, stale tab-completion names after rename, and auto-rename --dry-run output could be clearer

[!NOTE] Part of Paperworlds

textsessions is part of Paperworlds — an open org building tools and games around AI agents and text interfaces.

License

MIT

Metadata

Release files for textsessions 0.8.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for textsessions 0.8.10
File Size Uploaded Provenance
textsessions-0.8.10.tar.gz 98.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for textsessions 0.8.10
File Interpreter ABI Platform
textsessions-0.8.10-py3-none-any.whl Python 3 none any Details

Total release size: 149.4 kB

Release files / textsessions-0.8.10.tar.gz

Download URL textsessions-0.8.10.tar.gz
Size 98.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3542f9121ff4259159891c374c62eb716d5b4ae2ae64a5f8118878ad2afab551
BLAKE2b-256 checksum
How to use checksums
7af75939fc330fff1af81a72a4ca688c2e755334c06decc6ab3bb9418e2a076b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / textsessions-0.8.10-py3-none-any.whl

Download URL textsessions-0.8.10-py3-none-any.whl
Size 50.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6859cde549af1dfc5312a8477ef6aa412bf18aa05ccd09bd0dc7c7a8ba9c0085
BLAKE2b-256 checksum
How to use checksums
59cb47482c0cbf279f80e7e9728040b789086526618fb69fe07cf3ea038142de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for textsessions 0.8.10

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.8.10 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page