sessiontools
session: one command for the coding-agent sessions on this machine.
Which are live, whether each is busy or idle, how full its context is,
and how to start one from an agent file. For anyone running several
Claude Code sessions side by side, and for the tools that watch them.
Install
This puts session on the PATH:
uv tool install sessiontools
Python 3.11 to 3.14. Optional: the Claude Code plugin adds
the session skill and four hooks.
Shell completion, one line per shell (shell completion).
For zsh, in ~/.zshrc after compinit:
eval "$(session completion zsh)"
For bash with the bash-completion package (2.x), once:
session completion bash > ~/.local/share/bash-completion/completions/session
For bash 3.2, or any bash without that package, in ~/.bashrc:
eval "$(session completion bash)"
Quick start
session list: the live sessions, with their panes, state and context.session get state: this session's state: busy, idle with children, or idle.session context: how full this session's context window is.session context --parts: what filled it: boot, then growth by category.session ledger --short: each file read and command run, by tokens.session account status: which Claude account this Mac is on.session start --list-agents: the agents it can start.session reap: seats idle past 1h, each CLOSE or KEEP, and why. A dry run.session default-model: the model every newclaudestarts on, and whether a pin keeps it there. Off until you setmodel.default.session --help: every verb.
Switching accounts
session account use NAME moves this Mac to another Claude account from
a token you already hold: no browser, no restart, and it never prints a
token. On a Keychain host it moves every seat, not one:
| route | moves | cache cost | reversible by | gate |
|---|---|---|---|---|
account use (Keychain) |
every seat on the Mac with no env token, within ~50 s | the sum of their contexts (2.07M / 1.10M measured) | use back, or restore from the backup |
witness, --yes, preflight, backup |
account use (token file) |
no live seat; each one that relaunches from a shell that reads the file | none now; each seat's context when it restarts | use back, or restore from the backup |
witness, --yes, preflight, backup |
A host whose shell exports CLAUDE_CODE_OAUTH_TOKEN from a file names it
in the session setting account.token_file, and use swaps the file.
A seat session start launches does not follow the file unless its agent
file says inherit: [CLAUDE_CODE_OAUTH_TOKEN].
Without --yes, use shows the plan and writes nothing. To add an
account, session account new NAME --email E signs in through claude setup-token, saves the token to passage, reads it back and registers
it; the token is never shown. See Switching Claude accounts.
If you sign in by token, CLAUDE_CODE_OAUTH_TOKEN in your shell, a
session session start launches does not get it by default. To carry
it, name it under inherit: in the agent file (credentials are never
handed down). A /login sign-in needs nothing:
environment:
inherit:
- CLAUDE_CODE_OAUTH_TOKEN
What an install changes
uv tool install sessiontools changes two places and fills uv's own
cache, and it touches no shell startup file and nothing in ~/.claude.
Everything else below appears only when you run the verb named beside
it. Each line says what puts it there and what takes it away.
- PATH:
~/.local/bin/session, the one command, or inUV_TOOL_BIN_DIRwhen that is set. uv says so if the folder is not on your PATH, and edits no shell file.uv tool uninstallremoves it. - The program:
~/.local/share/uv/tools/sessiontools/, its own Python environment with PyYAML and jsonschema, or inUV_TOOL_DIR.uv tool uninstallremoves it. - uv's cache: the install fills it with what it downloaded and
built. It is uv's, shared by everything uv installs, not sessiontools'.
uv cache dirprints where it is (~/.cache/uvby default, orUV_CACHE_DIR).uv tool uninstallleaves it;uv cache clean sessiontoolsdrops this package's entries, anduv cache prunedrops the ones nothing uses. - Folders, each made by a verb you run:
~/.session/state/list/: the list cache,snapshot.jsonandlist.lock, at the firstsession list.~/.session/sessions/<session-id>/: one for eachsession start, holdinglaunch/,log/settings.jsonlandsession-id. It also getssettings/<tool>.d/50-env.json, one for each tool whose settings name a variable that is set when the session starts. Each is written once, so a resumed session keeps its file, andlog/settings.jsonlnames each variable it read, never its value. The plugin's hooks andsession parkwrite only inside a folder that is already there.~/.session/state/reap.log:session reap --yes.~/.session/state/pane-state/watch.lock: the pane signal's service.~/.session/state/default-model/:backups/andlog.jsonl, the first timesession default-model enforcechanges settings.json.~/.sessionkit/tools/accounts/:session account newanduse.~/.local/share/sessiontools/sound/bin/:session sound engine onbuilds the sound engine there withswiftc.~/Library/Logs/sessiontools/: the two services' logs.SESSIONS_DIR,SESSION_STATE_DIRandSESSIONTOOLS_SOUND_HOMEmove these folders when set.
- Services (launchd agents): none until you turn one on. Each
onwrites a plist in~/Library/LaunchAgents/and loads it, and it starts again at every login. Eachoffunloads it and deletes the plist. Bothonandoffalso retire a job an older release set up under its old label: they unload it and delete its plist.statusnames one that is still there, and--dry-runlists the retire and changes nothing.dev.sessionkit.tools.sound-engine:session sound engine on.off --purgealso deletes the engine it built.dev.sessionkit.tools.pane-state:session pane-state agent on. It sets@session_stateand@session_state_whyon each seat's tmux pane.dev.sessionkit.tools.default-model: no verb writes or loads it.session default-model unit launchdprints it, and it is there only if you save and load it yourself (the default model).
- Plugin and hooks, optional:
claude plugin marketplace addandclaude plugin install(the Claude Code plugin). Claude Code names the marketplace and the plugin in~/.claude/settings.json(extraKnownMarketplaces,enabledPlugins), lists them in~/.claude/plugins/, and keeps a copy in~/.claude/plugins/cache/sessiontools/. The plugin brings thesessionskill and nine hook entries: SessionStart (two), PreToolUse, PostToolBatch (three), Stop, UserPromptSubmit and SessionEnd. Each is silent unless set. Uninstalling the plugin takes it out of the settings and leaves the cached copy. - Settings: the install writes none, and none are needed.
session statusline installwritesstatusline.shandclaude-code.d/50-statusline.jsonin~/.sessionkit/tools/settings/; with--forceit first keeps a.bak-<stamp>copy of each file it replaces. Any other file there is one you wrote. - Outside these folders, only on a verb:
session account use NAME --yesreplaces the Keychain itemClaude Code-credentials, or the token file named byaccount.token_file, after a backup in the accounts folder.session account newsaves a token to passage. Withmodel.defaultset,session default-model enforce(and the unit orwatchthat runs it) rewrites the top-level"model"in~/.claude/settings.json, after a backup.
Uninstall
Turn off any service you turned on first: the pane signal's service
and the default model's agent run the session command that the last
line removes. Then remove the
plugin, if you installed it, and the command. Skip the lines for what
you never installed:
session pane-state agent off
session sound engine off --purge
launchctl bootout gui/$(id -u)/dev.sessionkit.tools.default-model
rm ~/Library/LaunchAgents/dev.sessionkit.tools.default-model.plist
claude plugin uninstall sessiontools@sessiontools
claude plugin marketplace remove sessiontools
uv tool uninstall sessiontools
That leaves what the verbs made, listed above. The plugin's cached copy, the services' logs and the engine's folder are sessiontools' alone. To delete them:
rm -rf "${HOME:?}/.claude/plugins/cache/sessiontools"
rm -rf "${HOME:?}/Library/Logs/sessiontools"
rm -rf "${HOME:?}/.local/share/sessiontools"
uv's cache stays too, with the other things uv installed; uv cache clean sessiontools drops this package's entries.
The rest is your data: delete it by hand only if you want it gone.
~/.sessionkit/tools/ holds your settings and accounts, and the
accounts folder keeps the backups of every token session account use
replaced. ~/.session/ holds the session folders and the list cache,
and the kit's other packages keep their files in it too.
Docs
- The
sessioncommand: what it does, every verb, and an example of each - Starting a session: agent files, flags, tmux, one holder
- Switching Claude accounts:
session account, its blast radius, andnew, which adds an account - The
session listcache: one computation, many readers - Operator and privileged seats: who seats ask
- Closing idle seats:
session reap, a dry run by default - Shell completion:
session completion bash|zsh, a static script built from the verbs' own parsers - The Claude Code plugin: the skill and the hooks
- The settle alert: one line past a context threshold
- The clock line: the time and the context on every tool batch
- The busy sound: a sound while a tool batch runs long
- The session-info hooks: the short session id as the session title, and the session's facts in context, both off by default
- The sound engine: the busy sound from one resident process
- The status line:
session statusline installputs it in the kit's claude-code layer, never~/.claude.session startseats show it; a bareclaudedoes not (alias claude='session start -') - The pane signal: BUSY / FREE on each seat's tmux pane,
and
session pane-state agent, the launchd agent that publishes it - The default model:
session default-model, opt-in, puts settings.json's"model"back when something rewrites it - The Python library:
from sessiontools import sessions - Building and testing: make targets, specs, releases
- CHANGELOG; licence AGPL-3.0-or-later (LICENSE)
Configuration
Nothing needs configuring: unset, every part uses its default. What can be set, and where each one lives (configuration):
- Settings files, JSON in layers:
~/.sessionkit/tools/settings/session.json(the operator, the list cache, the pane signal, accounts, a session's home, the default model),~/.sessionkit/tools/settings/sounds.json(the busy sound), and~/.sessionkit/tools/settings/claude-code.json(the model, effort and status linesession startpasses on). Every key, its default and which layers it is read from: settings. - Folders of its own:
~/.session/(sessions, seats, agent files, the state dir) and~/.sessionkit/tools/accounts/(session account). - Environment variables: the settle alert's
SESSION_SETTLE_AT, the clock line'sSESSION_CLOCK_WARN_AT, the hooks'SESSIONTOOLS_HOOK_*switches (SESSIONTOOLS_HOOK_CLOCK=onswitches the clock line on), and the paths it reads, such asSESSIONS_DIRandSESSION_STATE_DIR. The configuration page lists each one with its default, under the part that reads it.
Logs
- The sound engine:
~/Library/Logs/sessiontools/sound-engine.log, oncesession sound engine onhas run. - The pane signal's agent:
~/Library/Logs/sessiontools/pane-state.log, oncesession pane-state agent onhas run. - The default model:
~/.session/state/default-model/log.jsonl, one line per write to settings.json, and~/Library/Logs/sessiontools/default-model.log, once you have loaded the launchd agentsession default-model unit launchdprints. session reap --yes:~/.session/state/reap.log, one line for each seat it closed or failed to close.- Each session's settings at birth:
~/.session/sessions/<session-id>/log/settings.jsonl, whatsession startread into that session's settings: each environment variable by name, never its value. - The status line:
~/.config/session/statusline-log.jsonl, one line per render, only when~/.config/session/already exists.
Follow one as it grows with tail -F, for example
tail -F ~/Library/Logs/sessiontools/pane-state.log.
- Health:
session listprints a row for each live session, with its state and context. A session you know is running that is not listed is one sessiontools cannot see.
Metadata
Release files for sessiontools 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sessiontools-0.3.0.tar.gz | 428.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sessiontools-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 905.8 kB
Release files / sessiontools-0.3.0.tar.gz
| Download URL | sessiontools-0.3.0.tar.gz |
|---|---|
| Size | 428.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a07b1cd0fa5e00565533c1b894d9d62c0b43cb785252cd37624ff7387b1c69d
|
|
BLAKE2b-256 checksum How to use checksums |
6b1511a985682327014ba707bf26b85e2379d3b18f6fc8e45fb2ec568c8feb5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","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 / sessiontools-0.3.0-py3-none-any.whl
| Download URL | sessiontools-0.3.0-py3-none-any.whl |
|---|---|
| Size | 477.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8d0896995cb0b0a84b1773b552e6f7a91a9c57c4144df47b0fbfb79858add21e
|
|
BLAKE2b-256 checksum How to use checksums |
12aa3e169af45280b40f917e4c76c15af5dcee024e69caa238d69d266990b797
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","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 sessiontools 0.3.0
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.