sessiontools 0.1.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sessiontools-0.3.0/PKG-INFO +317 -0
- sessiontools-0.3.0/README.md +301 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/pyproject.toml +21 -16
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/__init__.py +18 -4
- sessiontools-0.3.0/src/sessiontools/account/__init__.py +15 -0
- sessiontools-0.3.0/src/sessiontools/account/cli.py +372 -0
- sessiontools-0.3.0/src/sessiontools/account/keychain.py +318 -0
- sessiontools-0.3.0/src/sessiontools/account/leakscan.py +190 -0
- sessiontools-0.3.0/src/sessiontools/account/limits.py +248 -0
- sessiontools-0.3.0/src/sessiontools/account/movehome.py +312 -0
- sessiontools-0.3.0/src/sessiontools/account/new.py +458 -0
- sessiontools-0.3.0/src/sessiontools/account/registry.py +589 -0
- sessiontools-0.3.0/src/sessiontools/account/setuptoken.py +1373 -0
- sessiontools-0.3.0/src/sessiontools/account/status.py +647 -0
- sessiontools-0.3.0/src/sessiontools/account/tokenfile.py +385 -0
- sessiontools-0.3.0/src/sessiontools/account/tokenstore.py +462 -0
- sessiontools-0.3.0/src/sessiontools/account/use.py +831 -0
- sessiontools-0.3.0/src/sessiontools/band.py +130 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/busy.py +468 -80
- sessiontools-0.3.0/src/sessiontools/claude_code.py +457 -0
- sessiontools-0.3.0/src/sessiontools/cli.py +805 -0
- sessiontools-0.3.0/src/sessiontools/clockline.py +180 -0
- sessiontools-0.3.0/src/sessiontools/completion.py +400 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/__init__.py +50 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/boot.py +534 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/breakdown.py +218 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/hooks.py +269 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/nnls.py +112 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/render.py +478 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/slash_context.py +137 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/tools.py +118 -0
- sessiontools-0.3.0/src/sessiontools/context_parts/transcript.py +401 -0
- sessiontools-0.3.0/src/sessiontools/default_model.py +480 -0
- sessiontools-0.3.0/src/sessiontools/default_model_cli.py +280 -0
- sessiontools-0.3.0/src/sessiontools/default_model_watch.py +314 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/get.py +6 -4
- sessiontools-0.3.0/src/sessiontools/ledger/__init__.py +338 -0
- sessiontools-0.3.0/src/sessiontools/ledger/_tiktoken_child.py +65 -0
- sessiontools-0.3.0/src/sessiontools/ledger/count.py +176 -0
- sessiontools-0.3.0/src/sessiontools/ledger/render.py +262 -0
- sessiontools-0.3.0/src/sessiontools/ledger/transcript.py +268 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/listing.py +71 -18
- sessiontools-0.3.0/src/sessiontools/operator.py +223 -0
- sessiontools-0.3.0/src/sessiontools/pane_state.py +663 -0
- sessiontools-0.3.0/src/sessiontools/pane_state_agent.py +522 -0
- sessiontools-0.3.0/src/sessiontools/park.py +1359 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/procs.py +46 -8
- sessiontools-0.3.0/src/sessiontools/reap.py +925 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/send.py +2 -2
- sessiontools-0.3.0/src/sessiontools/session_info.py +174 -0
- sessiontools-0.3.0/src/sessiontools/settings.py +1526 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/settle.py +85 -5
- sessiontools-0.3.0/src/sessiontools/snapshot.py +324 -0
- sessiontools-0.3.0/src/sessiontools/sound/__init__.py +117 -0
- sessiontools-0.3.0/src/sessiontools/sound/engine.swift +2020 -0
- sessiontools-0.3.0/src/sessiontools/sound/event.swift +248 -0
- sessiontools-0.3.0/src/sessiontools/sound/service.py +596 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/__init__.py +11 -12
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/agentfile.py +44 -13
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/agents.py +10 -14
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/args.py +19 -16
- sessiontools-0.3.0/src/sessiontools/start/claude_settings.py +333 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/context.py +101 -29
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/environment.py +133 -14
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/errors.py +2 -2
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/holders.py +6 -6
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/identity.py +83 -18
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/placement.py +19 -8
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/plan.py +342 -72
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/policy.py +65 -56
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/record.py +15 -16
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/resume.py +17 -15
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/run.py +26 -13
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/secrets.py +110 -4
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/start/vendor.py +19 -6
- sessiontools-0.3.0/src/sessiontools/statusline/__init__.py +1195 -0
- sessiontools-0.3.0/src/sessiontools/statusline/sample.json +20 -0
- sessiontools-0.3.0/src/sessiontools/statusline/statusline.sh +185 -0
- sessiontools-0.3.0/src/sessiontools/tmux.py +178 -0
- sessiontools-0.3.0/src/sessiontools/turn.py +191 -0
- sessiontools-0.3.0/src/sessiontools/verbs.py +67 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/window.py +90 -15
- sessiontools-0.1.0/PKG-INFO +0 -11
- sessiontools-0.1.0/src/sessiontools/claude_code.py +0 -179
- sessiontools-0.1.0/src/sessiontools/cli.py +0 -347
- sessiontools-0.1.0/src/sessiontools/settings.py +0 -764
- sessiontools-0.1.0/src/sessiontools/tmux.py +0 -90
- {sessiontools-0.1.0 → sessiontools-0.3.0}/LICENSE +0 -0
- {sessiontools-0.1.0 → sessiontools-0.3.0}/src/sessiontools/py.typed +0 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sessiontools
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: The harness layer: sessions, status and idle, one driver per harness - a library first
|
|
5
|
+
Author: Mike Bailey
|
|
6
|
+
Author-email: Mike Bailey <mike@sessionkit.ai>
|
|
7
|
+
License-Expression: AGPL-3.0-or-later
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Requires-Dist: pyyaml>=6
|
|
11
|
+
Requires-Dist: jsonschema>=4
|
|
12
|
+
Requires-Python: >=3.11, <3.15
|
|
13
|
+
Project-URL: Homepage, https://github.com/sessionkit/sessiontools
|
|
14
|
+
Project-URL: Repository, https://github.com/sessionkit/sessiontools
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# sessiontools
|
|
18
|
+
|
|
19
|
+
`session`: one command for the coding-agent sessions on this machine.
|
|
20
|
+
Which are live, whether each is busy or idle, how full its context is,
|
|
21
|
+
and how to start one from an agent file. For anyone running several
|
|
22
|
+
Claude Code sessions side by side, and for the tools that watch them.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
This puts `session` on the PATH:
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
uv tool install sessiontools
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Python 3.11 to 3.14. Optional: [the Claude Code plugin][plugin] adds
|
|
33
|
+
the `session` skill and four hooks.
|
|
34
|
+
|
|
35
|
+
Shell completion, one line per shell ([shell completion][completion]).
|
|
36
|
+
For zsh, in `~/.zshrc` after compinit:
|
|
37
|
+
|
|
38
|
+
```console
|
|
39
|
+
eval "$(session completion zsh)"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
For bash with the bash-completion package (2.x), once:
|
|
43
|
+
|
|
44
|
+
```console
|
|
45
|
+
session completion bash > ~/.local/share/bash-completion/completions/session
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For bash 3.2, or any bash without that package, in `~/.bashrc`:
|
|
49
|
+
|
|
50
|
+
```console
|
|
51
|
+
eval "$(session completion bash)"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
- `session list`: the live sessions, with their panes, state and context.
|
|
57
|
+
- `session get state`: this session's state: busy, idle with children,
|
|
58
|
+
or idle.
|
|
59
|
+
- `session context`: how full this session's context window is.
|
|
60
|
+
- `session context --parts`: what filled it: boot, then growth by
|
|
61
|
+
category.
|
|
62
|
+
- `session ledger --short`: each file read and command run, by tokens.
|
|
63
|
+
- `session account status`: which Claude account this Mac is on.
|
|
64
|
+
- `session start --list-agents`: the agents it can start.
|
|
65
|
+
- `session reap`: seats idle past 1h, each CLOSE or KEEP, and why. A dry
|
|
66
|
+
run.
|
|
67
|
+
- `session default-model`: the model every new `claude` starts on, and
|
|
68
|
+
whether a pin keeps it there. Off until you set `model.default`.
|
|
69
|
+
- `session --help`: every verb.
|
|
70
|
+
|
|
71
|
+
## Switching accounts
|
|
72
|
+
|
|
73
|
+
`session account use NAME` moves this Mac to another Claude account from
|
|
74
|
+
a token you already hold: no browser, no restart, and it never prints a
|
|
75
|
+
token. On a Keychain host it moves **every** seat, not one:
|
|
76
|
+
|
|
77
|
+
| route | moves | cache cost | reversible by | gate |
|
|
78
|
+
|---|---|---|---|---|
|
|
79
|
+
| `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 |
|
|
80
|
+
| `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 |
|
|
81
|
+
|
|
82
|
+
A host whose shell exports `CLAUDE_CODE_OAUTH_TOKEN` from a file names it
|
|
83
|
+
in the `session` setting `account.token_file`, and `use` swaps the file.
|
|
84
|
+
A seat `session start` launches does not follow the file unless its agent
|
|
85
|
+
file says `inherit: [CLAUDE_CODE_OAUTH_TOKEN]`.
|
|
86
|
+
Without `--yes`, `use` shows the plan and writes nothing. To add an
|
|
87
|
+
account, `session account new NAME --email E` signs in through `claude
|
|
88
|
+
setup-token`, saves the token to passage, reads it back and registers
|
|
89
|
+
it; the token is never shown. See [Switching Claude accounts][account].
|
|
90
|
+
|
|
91
|
+
If you sign in by token, `CLAUDE_CODE_OAUTH_TOKEN` in your shell, a
|
|
92
|
+
session `session start` launches does not get it by default. To carry
|
|
93
|
+
it, name it under `inherit:` in the agent file ([credentials are never
|
|
94
|
+
handed down][credentials]). A `/login` sign-in needs nothing:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
environment:
|
|
98
|
+
inherit:
|
|
99
|
+
- CLAUDE_CODE_OAUTH_TOKEN
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## What an install changes
|
|
103
|
+
|
|
104
|
+
`uv tool install sessiontools` changes two places and fills uv's own
|
|
105
|
+
cache, and it touches no shell startup file and nothing in `~/.claude`.
|
|
106
|
+
Everything else below appears only when you run the verb named beside
|
|
107
|
+
it. Each line says what puts it there and what takes it away.
|
|
108
|
+
|
|
109
|
+
- **PATH:** `~/.local/bin/session`, the one command, or in
|
|
110
|
+
`UV_TOOL_BIN_DIR` when that is set. uv says so if the folder is not
|
|
111
|
+
on your PATH, and edits no shell file. `uv tool uninstall` removes it.
|
|
112
|
+
- **The program:** `~/.local/share/uv/tools/sessiontools/`, its own
|
|
113
|
+
Python environment with PyYAML and jsonschema, or in `UV_TOOL_DIR`.
|
|
114
|
+
`uv tool uninstall` removes it.
|
|
115
|
+
- **uv's cache:** the install fills it with what it downloaded and
|
|
116
|
+
built. It is uv's, shared by everything uv installs, not sessiontools'.
|
|
117
|
+
`uv cache dir` prints where it is (`~/.cache/uv` by default, or
|
|
118
|
+
`UV_CACHE_DIR`). `uv tool uninstall` leaves it; `uv cache clean
|
|
119
|
+
sessiontools` drops this package's entries, and `uv cache prune` drops
|
|
120
|
+
the ones nothing uses.
|
|
121
|
+
- **Folders, each made by a verb you run:**
|
|
122
|
+
- `~/.session/state/list/`: the list cache, `snapshot.json` and
|
|
123
|
+
`list.lock`, at the first `session list`.
|
|
124
|
+
- `~/.session/sessions/<session-id>/`: one for each `session start`,
|
|
125
|
+
holding `launch/`, `log/settings.jsonl` and `session-id`. It also
|
|
126
|
+
gets `settings/<tool>.d/50-env.json`, one for each tool whose
|
|
127
|
+
settings name a variable that is set when the session starts. Each
|
|
128
|
+
is written once, so a resumed session keeps its file, and
|
|
129
|
+
`log/settings.jsonl` names each variable it read, never its value.
|
|
130
|
+
The plugin's hooks and `session park` write only inside a folder
|
|
131
|
+
that is already there.
|
|
132
|
+
- `~/.session/state/reap.log`: `session reap --yes`.
|
|
133
|
+
- `~/.session/state/pane-state/watch.lock`: the pane signal's service.
|
|
134
|
+
- `~/.session/state/default-model/`: `backups/` and `log.jsonl`, the
|
|
135
|
+
first time `session default-model enforce` changes settings.json.
|
|
136
|
+
- `~/.sessionkit/tools/accounts/`: `session account new` and `use`.
|
|
137
|
+
- `~/.local/share/sessiontools/sound/bin/`: `session sound engine on`
|
|
138
|
+
builds the sound engine there with `swiftc`.
|
|
139
|
+
- `~/Library/Logs/sessiontools/`: the two services' logs.
|
|
140
|
+
- `SESSIONS_DIR`, `SESSION_STATE_DIR` and `SESSIONTOOLS_SOUND_HOME`
|
|
141
|
+
move these folders when set.
|
|
142
|
+
- **Services (launchd agents):** none until you turn one on. Each `on`
|
|
143
|
+
writes a plist in `~/Library/LaunchAgents/` and loads it, and it
|
|
144
|
+
starts again at every login. Each `off` unloads it and deletes the
|
|
145
|
+
plist. Both `on` and `off` also retire a job an older release set up
|
|
146
|
+
under its old label: they unload it and delete its plist. `status`
|
|
147
|
+
names one that is still there, and `--dry-run` lists the retire and
|
|
148
|
+
changes nothing.
|
|
149
|
+
- `dev.sessionkit.tools.sound-engine`: `session sound engine on`.
|
|
150
|
+
`off --purge` also deletes the engine it built.
|
|
151
|
+
- `dev.sessionkit.tools.pane-state`: `session pane-state agent on`.
|
|
152
|
+
It sets `@session_state` and `@session_state_why` on each seat's
|
|
153
|
+
tmux pane.
|
|
154
|
+
- `dev.sessionkit.tools.default-model`: no verb writes or loads it.
|
|
155
|
+
`session default-model unit launchd` prints it, and it is there only
|
|
156
|
+
if you save and load it yourself
|
|
157
|
+
([the default model][default-model]).
|
|
158
|
+
- **Plugin and hooks, optional:** `claude plugin marketplace add` and
|
|
159
|
+
`claude plugin install` ([the Claude Code plugin][plugin]). Claude
|
|
160
|
+
Code names the marketplace and the plugin in `~/.claude/settings.json`
|
|
161
|
+
(`extraKnownMarketplaces`, `enabledPlugins`), lists them in
|
|
162
|
+
`~/.claude/plugins/`, and keeps a copy in
|
|
163
|
+
`~/.claude/plugins/cache/sessiontools/`. The plugin brings the
|
|
164
|
+
`session` skill and nine hook entries: SessionStart (two),
|
|
165
|
+
PreToolUse, PostToolBatch (three), Stop, UserPromptSubmit and
|
|
166
|
+
SessionEnd. Each is silent unless set.
|
|
167
|
+
Uninstalling the plugin takes it out of the settings and leaves the
|
|
168
|
+
cached copy.
|
|
169
|
+
- **Settings:** the install writes none, and none are needed.
|
|
170
|
+
`session statusline install` writes `statusline.sh` and
|
|
171
|
+
`claude-code.d/50-statusline.json` in `~/.sessionkit/tools/settings/`;
|
|
172
|
+
with `--force` it first keeps a `.bak-<stamp>` copy of each file it
|
|
173
|
+
replaces. Any other file there is one you wrote.
|
|
174
|
+
- **Outside these folders, only on a verb:** `session account use NAME
|
|
175
|
+
--yes` replaces the Keychain item `Claude Code-credentials`, or the
|
|
176
|
+
token file named by `account.token_file`, after a backup in the
|
|
177
|
+
accounts folder. `session account new` saves a token to passage.
|
|
178
|
+
With `model.default` set, `session default-model enforce` (and the
|
|
179
|
+
unit or `watch` that runs it) rewrites the top-level `"model"` in
|
|
180
|
+
`~/.claude/settings.json`, after a backup.
|
|
181
|
+
|
|
182
|
+
## Uninstall
|
|
183
|
+
|
|
184
|
+
Turn off any service you turned on first: the pane signal's service
|
|
185
|
+
and the default model's agent run the `session` command that the last
|
|
186
|
+
line removes. Then remove the
|
|
187
|
+
plugin, if you installed it, and the command. Skip the lines for what
|
|
188
|
+
you never installed:
|
|
189
|
+
|
|
190
|
+
```console
|
|
191
|
+
session pane-state agent off
|
|
192
|
+
session sound engine off --purge
|
|
193
|
+
launchctl bootout gui/$(id -u)/dev.sessionkit.tools.default-model
|
|
194
|
+
rm ~/Library/LaunchAgents/dev.sessionkit.tools.default-model.plist
|
|
195
|
+
claude plugin uninstall sessiontools@sessiontools
|
|
196
|
+
claude plugin marketplace remove sessiontools
|
|
197
|
+
uv tool uninstall sessiontools
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
That leaves what the verbs made, listed above. The plugin's cached
|
|
201
|
+
copy, the services' logs and the engine's folder are sessiontools'
|
|
202
|
+
alone. To delete them:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
rm -rf "${HOME:?}/.claude/plugins/cache/sessiontools"
|
|
206
|
+
rm -rf "${HOME:?}/Library/Logs/sessiontools"
|
|
207
|
+
rm -rf "${HOME:?}/.local/share/sessiontools"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
uv's cache stays too, with the other things uv installed; `uv cache
|
|
211
|
+
clean sessiontools` drops this package's entries.
|
|
212
|
+
|
|
213
|
+
The rest is your data: delete it by hand only if you want it gone.
|
|
214
|
+
`~/.sessionkit/tools/` holds your settings and accounts, and the
|
|
215
|
+
accounts folder keeps the backups of every token `session account use`
|
|
216
|
+
replaced. `~/.session/` holds the session folders and the list cache,
|
|
217
|
+
and the kit's other packages keep their files in it too.
|
|
218
|
+
|
|
219
|
+
## Docs
|
|
220
|
+
|
|
221
|
+
- [The `session` command][verbs]: what it does, every verb, and an
|
|
222
|
+
example of each
|
|
223
|
+
- [Starting a session][start]: agent files, flags, tmux, one holder
|
|
224
|
+
- [Switching Claude accounts][account]: `session account`, its blast
|
|
225
|
+
radius, and `new`, which adds an account
|
|
226
|
+
- [The `session list` cache][cache]: one computation, many readers
|
|
227
|
+
- [Operator and privileged seats][operator]: who seats ask
|
|
228
|
+
- [Closing idle seats][reap]: `session reap`, a dry run by default
|
|
229
|
+
- [Shell completion][completion]: `session completion bash|zsh`, a static
|
|
230
|
+
script built from the verbs' own parsers
|
|
231
|
+
- [The Claude Code plugin][plugin]: the skill and the hooks
|
|
232
|
+
- [The settle alert][settle]: one line past a context threshold
|
|
233
|
+
- [The clock line][clock]: the time and the context on every tool batch
|
|
234
|
+
- [The busy sound][busy]: a sound while a tool batch runs long
|
|
235
|
+
- [The session-info hooks][session-info]: the short session id as the
|
|
236
|
+
session title, and the session's facts in context, both off by default
|
|
237
|
+
- [The sound engine][engine]: the busy sound from one resident process
|
|
238
|
+
- [The status line][status-line]: `session statusline install` puts it in the
|
|
239
|
+
kit's claude-code layer, never `~/.claude`. `session start` seats show it;
|
|
240
|
+
a bare `claude` does not (`alias claude='session start -'`)
|
|
241
|
+
- [The pane signal][pane-state]: BUSY / FREE on each seat's tmux pane,
|
|
242
|
+
and `session pane-state agent`, the launchd agent that publishes it
|
|
243
|
+
- [The default model][default-model]: `session default-model`, opt-in,
|
|
244
|
+
puts settings.json's `"model"` back when something rewrites it
|
|
245
|
+
- [The Python library][library]: `from sessiontools import sessions`
|
|
246
|
+
- [Building and testing][building]: make targets, specs, releases
|
|
247
|
+
- [CHANGELOG][changelog]; licence AGPL-3.0-or-later ([LICENSE][license])
|
|
248
|
+
|
|
249
|
+
## Configuration
|
|
250
|
+
|
|
251
|
+
Nothing needs configuring: unset, every part uses its default. What can
|
|
252
|
+
be set, and where each one lives ([configuration][configuration]):
|
|
253
|
+
|
|
254
|
+
- **Settings files**, JSON in layers: `~/.sessionkit/tools/settings/session.json`
|
|
255
|
+
(the operator, the list cache, the pane signal, accounts, a session's
|
|
256
|
+
home, the default model), `~/.sessionkit/tools/settings/sounds.json` (the busy sound), and
|
|
257
|
+
`~/.sessionkit/tools/settings/claude-code.json` (the model, effort
|
|
258
|
+
and status line `session start` passes on). Every key, its default and
|
|
259
|
+
which layers it is read from: [settings][settings].
|
|
260
|
+
- **Folders of its own:** `~/.session/` (sessions, seats, agent files, the
|
|
261
|
+
state dir) and `~/.sessionkit/tools/accounts/` (`session account`).
|
|
262
|
+
- **Environment variables:** the settle alert's `SESSION_SETTLE_AT`, the
|
|
263
|
+
clock line's `SESSION_CLOCK_WARN_AT`, the hooks' `SESSIONTOOLS_HOOK_*`
|
|
264
|
+
switches (`SESSIONTOOLS_HOOK_CLOCK=on` switches the clock line on), and
|
|
265
|
+
the paths it reads, such as `SESSIONS_DIR` and `SESSION_STATE_DIR`.
|
|
266
|
+
The configuration page lists each one with its default, under the part
|
|
267
|
+
that reads it.
|
|
268
|
+
|
|
269
|
+
## Logs
|
|
270
|
+
|
|
271
|
+
- **The sound engine:** `~/Library/Logs/sessiontools/sound-engine.log`,
|
|
272
|
+
once `session sound engine on` has run.
|
|
273
|
+
- **The pane signal's agent:** `~/Library/Logs/sessiontools/pane-state.log`,
|
|
274
|
+
once `session pane-state agent on` has run.
|
|
275
|
+
- **The default model:** `~/.session/state/default-model/log.jsonl`, one
|
|
276
|
+
line per write to settings.json, and
|
|
277
|
+
`~/Library/Logs/sessiontools/default-model.log`, once you have loaded
|
|
278
|
+
the launchd agent `session default-model unit launchd` prints.
|
|
279
|
+
- **`session reap --yes`:** `~/.session/state/reap.log`, one line for each
|
|
280
|
+
seat it closed or failed to close.
|
|
281
|
+
- **Each session's settings at birth:**
|
|
282
|
+
`~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
|
|
283
|
+
start` read into that session's settings: each environment variable
|
|
284
|
+
by name, never its value.
|
|
285
|
+
- **The status line:** `~/.config/session/statusline-log.jsonl`, one line
|
|
286
|
+
per render, only when `~/.config/session/` already exists.
|
|
287
|
+
|
|
288
|
+
Follow one as it grows with `tail -F`, for example
|
|
289
|
+
`tail -F ~/Library/Logs/sessiontools/pane-state.log`.
|
|
290
|
+
|
|
291
|
+
- **Health:** `session list` prints a row for each live session, with its
|
|
292
|
+
state and context. A session you know is running that is not listed is
|
|
293
|
+
one sessiontools cannot see.
|
|
294
|
+
|
|
295
|
+
[verbs]: docs/session.md
|
|
296
|
+
[start]: docs/session-start-launcher.md
|
|
297
|
+
[credentials]: docs/session-start-launcher.md#credentials-are-never-handed-down
|
|
298
|
+
[account]: docs/account.md
|
|
299
|
+
[cache]: docs/list-snapshot-cache.md
|
|
300
|
+
[operator]: docs/operator-privileged-seats.md
|
|
301
|
+
[reap]: docs/session-reap.md
|
|
302
|
+
[completion]: docs/shell-completion.md
|
|
303
|
+
[plugin]: docs/claude-code-plugin.md
|
|
304
|
+
[settle]: docs/settle-alert-hook.md
|
|
305
|
+
[clock]: docs/clock-line-hook.md
|
|
306
|
+
[busy]: docs/busy-sound-hook.md
|
|
307
|
+
[session-info]: docs/session-info-hook.md
|
|
308
|
+
[engine]: docs/sound-engine-agent.md
|
|
309
|
+
[status-line]: docs/status-line-script.md
|
|
310
|
+
[pane-state]: docs/pane-state-signal.md
|
|
311
|
+
[default-model]: docs/default-model.md
|
|
312
|
+
[library]: docs/python-library-api.md
|
|
313
|
+
[building]: docs/building-and-testing.md
|
|
314
|
+
[changelog]: CHANGELOG.md
|
|
315
|
+
[license]: LICENSE
|
|
316
|
+
[configuration]: docs/configuration.md
|
|
317
|
+
[settings]: docs/settings.md
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# sessiontools
|
|
2
|
+
|
|
3
|
+
`session`: one command for the coding-agent sessions on this machine.
|
|
4
|
+
Which are live, whether each is busy or idle, how full its context is,
|
|
5
|
+
and how to start one from an agent file. For anyone running several
|
|
6
|
+
Claude Code sessions side by side, and for the tools that watch them.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
This puts `session` on the PATH:
|
|
11
|
+
|
|
12
|
+
```console
|
|
13
|
+
uv tool install sessiontools
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Python 3.11 to 3.14. Optional: [the Claude Code plugin][plugin] adds
|
|
17
|
+
the `session` skill and four hooks.
|
|
18
|
+
|
|
19
|
+
Shell completion, one line per shell ([shell completion][completion]).
|
|
20
|
+
For zsh, in `~/.zshrc` after compinit:
|
|
21
|
+
|
|
22
|
+
```console
|
|
23
|
+
eval "$(session completion zsh)"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
For bash with the bash-completion package (2.x), once:
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
session completion bash > ~/.local/share/bash-completion/completions/session
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For bash 3.2, or any bash without that package, in `~/.bashrc`:
|
|
33
|
+
|
|
34
|
+
```console
|
|
35
|
+
eval "$(session completion bash)"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
- `session list`: the live sessions, with their panes, state and context.
|
|
41
|
+
- `session get state`: this session's state: busy, idle with children,
|
|
42
|
+
or idle.
|
|
43
|
+
- `session context`: how full this session's context window is.
|
|
44
|
+
- `session context --parts`: what filled it: boot, then growth by
|
|
45
|
+
category.
|
|
46
|
+
- `session ledger --short`: each file read and command run, by tokens.
|
|
47
|
+
- `session account status`: which Claude account this Mac is on.
|
|
48
|
+
- `session start --list-agents`: the agents it can start.
|
|
49
|
+
- `session reap`: seats idle past 1h, each CLOSE or KEEP, and why. A dry
|
|
50
|
+
run.
|
|
51
|
+
- `session default-model`: the model every new `claude` starts on, and
|
|
52
|
+
whether a pin keeps it there. Off until you set `model.default`.
|
|
53
|
+
- `session --help`: every verb.
|
|
54
|
+
|
|
55
|
+
## Switching accounts
|
|
56
|
+
|
|
57
|
+
`session account use NAME` moves this Mac to another Claude account from
|
|
58
|
+
a token you already hold: no browser, no restart, and it never prints a
|
|
59
|
+
token. On a Keychain host it moves **every** seat, not one:
|
|
60
|
+
|
|
61
|
+
| route | moves | cache cost | reversible by | gate |
|
|
62
|
+
|---|---|---|---|---|
|
|
63
|
+
| `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 |
|
|
64
|
+
| `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 |
|
|
65
|
+
|
|
66
|
+
A host whose shell exports `CLAUDE_CODE_OAUTH_TOKEN` from a file names it
|
|
67
|
+
in the `session` setting `account.token_file`, and `use` swaps the file.
|
|
68
|
+
A seat `session start` launches does not follow the file unless its agent
|
|
69
|
+
file says `inherit: [CLAUDE_CODE_OAUTH_TOKEN]`.
|
|
70
|
+
Without `--yes`, `use` shows the plan and writes nothing. To add an
|
|
71
|
+
account, `session account new NAME --email E` signs in through `claude
|
|
72
|
+
setup-token`, saves the token to passage, reads it back and registers
|
|
73
|
+
it; the token is never shown. See [Switching Claude accounts][account].
|
|
74
|
+
|
|
75
|
+
If you sign in by token, `CLAUDE_CODE_OAUTH_TOKEN` in your shell, a
|
|
76
|
+
session `session start` launches does not get it by default. To carry
|
|
77
|
+
it, name it under `inherit:` in the agent file ([credentials are never
|
|
78
|
+
handed down][credentials]). A `/login` sign-in needs nothing:
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
environment:
|
|
82
|
+
inherit:
|
|
83
|
+
- CLAUDE_CODE_OAUTH_TOKEN
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## What an install changes
|
|
87
|
+
|
|
88
|
+
`uv tool install sessiontools` changes two places and fills uv's own
|
|
89
|
+
cache, and it touches no shell startup file and nothing in `~/.claude`.
|
|
90
|
+
Everything else below appears only when you run the verb named beside
|
|
91
|
+
it. Each line says what puts it there and what takes it away.
|
|
92
|
+
|
|
93
|
+
- **PATH:** `~/.local/bin/session`, the one command, or in
|
|
94
|
+
`UV_TOOL_BIN_DIR` when that is set. uv says so if the folder is not
|
|
95
|
+
on your PATH, and edits no shell file. `uv tool uninstall` removes it.
|
|
96
|
+
- **The program:** `~/.local/share/uv/tools/sessiontools/`, its own
|
|
97
|
+
Python environment with PyYAML and jsonschema, or in `UV_TOOL_DIR`.
|
|
98
|
+
`uv tool uninstall` removes it.
|
|
99
|
+
- **uv's cache:** the install fills it with what it downloaded and
|
|
100
|
+
built. It is uv's, shared by everything uv installs, not sessiontools'.
|
|
101
|
+
`uv cache dir` prints where it is (`~/.cache/uv` by default, or
|
|
102
|
+
`UV_CACHE_DIR`). `uv tool uninstall` leaves it; `uv cache clean
|
|
103
|
+
sessiontools` drops this package's entries, and `uv cache prune` drops
|
|
104
|
+
the ones nothing uses.
|
|
105
|
+
- **Folders, each made by a verb you run:**
|
|
106
|
+
- `~/.session/state/list/`: the list cache, `snapshot.json` and
|
|
107
|
+
`list.lock`, at the first `session list`.
|
|
108
|
+
- `~/.session/sessions/<session-id>/`: one for each `session start`,
|
|
109
|
+
holding `launch/`, `log/settings.jsonl` and `session-id`. It also
|
|
110
|
+
gets `settings/<tool>.d/50-env.json`, one for each tool whose
|
|
111
|
+
settings name a variable that is set when the session starts. Each
|
|
112
|
+
is written once, so a resumed session keeps its file, and
|
|
113
|
+
`log/settings.jsonl` names each variable it read, never its value.
|
|
114
|
+
The plugin's hooks and `session park` write only inside a folder
|
|
115
|
+
that is already there.
|
|
116
|
+
- `~/.session/state/reap.log`: `session reap --yes`.
|
|
117
|
+
- `~/.session/state/pane-state/watch.lock`: the pane signal's service.
|
|
118
|
+
- `~/.session/state/default-model/`: `backups/` and `log.jsonl`, the
|
|
119
|
+
first time `session default-model enforce` changes settings.json.
|
|
120
|
+
- `~/.sessionkit/tools/accounts/`: `session account new` and `use`.
|
|
121
|
+
- `~/.local/share/sessiontools/sound/bin/`: `session sound engine on`
|
|
122
|
+
builds the sound engine there with `swiftc`.
|
|
123
|
+
- `~/Library/Logs/sessiontools/`: the two services' logs.
|
|
124
|
+
- `SESSIONS_DIR`, `SESSION_STATE_DIR` and `SESSIONTOOLS_SOUND_HOME`
|
|
125
|
+
move these folders when set.
|
|
126
|
+
- **Services (launchd agents):** none until you turn one on. Each `on`
|
|
127
|
+
writes a plist in `~/Library/LaunchAgents/` and loads it, and it
|
|
128
|
+
starts again at every login. Each `off` unloads it and deletes the
|
|
129
|
+
plist. Both `on` and `off` also retire a job an older release set up
|
|
130
|
+
under its old label: they unload it and delete its plist. `status`
|
|
131
|
+
names one that is still there, and `--dry-run` lists the retire and
|
|
132
|
+
changes nothing.
|
|
133
|
+
- `dev.sessionkit.tools.sound-engine`: `session sound engine on`.
|
|
134
|
+
`off --purge` also deletes the engine it built.
|
|
135
|
+
- `dev.sessionkit.tools.pane-state`: `session pane-state agent on`.
|
|
136
|
+
It sets `@session_state` and `@session_state_why` on each seat's
|
|
137
|
+
tmux pane.
|
|
138
|
+
- `dev.sessionkit.tools.default-model`: no verb writes or loads it.
|
|
139
|
+
`session default-model unit launchd` prints it, and it is there only
|
|
140
|
+
if you save and load it yourself
|
|
141
|
+
([the default model][default-model]).
|
|
142
|
+
- **Plugin and hooks, optional:** `claude plugin marketplace add` and
|
|
143
|
+
`claude plugin install` ([the Claude Code plugin][plugin]). Claude
|
|
144
|
+
Code names the marketplace and the plugin in `~/.claude/settings.json`
|
|
145
|
+
(`extraKnownMarketplaces`, `enabledPlugins`), lists them in
|
|
146
|
+
`~/.claude/plugins/`, and keeps a copy in
|
|
147
|
+
`~/.claude/plugins/cache/sessiontools/`. The plugin brings the
|
|
148
|
+
`session` skill and nine hook entries: SessionStart (two),
|
|
149
|
+
PreToolUse, PostToolBatch (three), Stop, UserPromptSubmit and
|
|
150
|
+
SessionEnd. Each is silent unless set.
|
|
151
|
+
Uninstalling the plugin takes it out of the settings and leaves the
|
|
152
|
+
cached copy.
|
|
153
|
+
- **Settings:** the install writes none, and none are needed.
|
|
154
|
+
`session statusline install` writes `statusline.sh` and
|
|
155
|
+
`claude-code.d/50-statusline.json` in `~/.sessionkit/tools/settings/`;
|
|
156
|
+
with `--force` it first keeps a `.bak-<stamp>` copy of each file it
|
|
157
|
+
replaces. Any other file there is one you wrote.
|
|
158
|
+
- **Outside these folders, only on a verb:** `session account use NAME
|
|
159
|
+
--yes` replaces the Keychain item `Claude Code-credentials`, or the
|
|
160
|
+
token file named by `account.token_file`, after a backup in the
|
|
161
|
+
accounts folder. `session account new` saves a token to passage.
|
|
162
|
+
With `model.default` set, `session default-model enforce` (and the
|
|
163
|
+
unit or `watch` that runs it) rewrites the top-level `"model"` in
|
|
164
|
+
`~/.claude/settings.json`, after a backup.
|
|
165
|
+
|
|
166
|
+
## Uninstall
|
|
167
|
+
|
|
168
|
+
Turn off any service you turned on first: the pane signal's service
|
|
169
|
+
and the default model's agent run the `session` command that the last
|
|
170
|
+
line removes. Then remove the
|
|
171
|
+
plugin, if you installed it, and the command. Skip the lines for what
|
|
172
|
+
you never installed:
|
|
173
|
+
|
|
174
|
+
```console
|
|
175
|
+
session pane-state agent off
|
|
176
|
+
session sound engine off --purge
|
|
177
|
+
launchctl bootout gui/$(id -u)/dev.sessionkit.tools.default-model
|
|
178
|
+
rm ~/Library/LaunchAgents/dev.sessionkit.tools.default-model.plist
|
|
179
|
+
claude plugin uninstall sessiontools@sessiontools
|
|
180
|
+
claude plugin marketplace remove sessiontools
|
|
181
|
+
uv tool uninstall sessiontools
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
That leaves what the verbs made, listed above. The plugin's cached
|
|
185
|
+
copy, the services' logs and the engine's folder are sessiontools'
|
|
186
|
+
alone. To delete them:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
rm -rf "${HOME:?}/.claude/plugins/cache/sessiontools"
|
|
190
|
+
rm -rf "${HOME:?}/Library/Logs/sessiontools"
|
|
191
|
+
rm -rf "${HOME:?}/.local/share/sessiontools"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
uv's cache stays too, with the other things uv installed; `uv cache
|
|
195
|
+
clean sessiontools` drops this package's entries.
|
|
196
|
+
|
|
197
|
+
The rest is your data: delete it by hand only if you want it gone.
|
|
198
|
+
`~/.sessionkit/tools/` holds your settings and accounts, and the
|
|
199
|
+
accounts folder keeps the backups of every token `session account use`
|
|
200
|
+
replaced. `~/.session/` holds the session folders and the list cache,
|
|
201
|
+
and the kit's other packages keep their files in it too.
|
|
202
|
+
|
|
203
|
+
## Docs
|
|
204
|
+
|
|
205
|
+
- [The `session` command][verbs]: what it does, every verb, and an
|
|
206
|
+
example of each
|
|
207
|
+
- [Starting a session][start]: agent files, flags, tmux, one holder
|
|
208
|
+
- [Switching Claude accounts][account]: `session account`, its blast
|
|
209
|
+
radius, and `new`, which adds an account
|
|
210
|
+
- [The `session list` cache][cache]: one computation, many readers
|
|
211
|
+
- [Operator and privileged seats][operator]: who seats ask
|
|
212
|
+
- [Closing idle seats][reap]: `session reap`, a dry run by default
|
|
213
|
+
- [Shell completion][completion]: `session completion bash|zsh`, a static
|
|
214
|
+
script built from the verbs' own parsers
|
|
215
|
+
- [The Claude Code plugin][plugin]: the skill and the hooks
|
|
216
|
+
- [The settle alert][settle]: one line past a context threshold
|
|
217
|
+
- [The clock line][clock]: the time and the context on every tool batch
|
|
218
|
+
- [The busy sound][busy]: a sound while a tool batch runs long
|
|
219
|
+
- [The session-info hooks][session-info]: the short session id as the
|
|
220
|
+
session title, and the session's facts in context, both off by default
|
|
221
|
+
- [The sound engine][engine]: the busy sound from one resident process
|
|
222
|
+
- [The status line][status-line]: `session statusline install` puts it in the
|
|
223
|
+
kit's claude-code layer, never `~/.claude`. `session start` seats show it;
|
|
224
|
+
a bare `claude` does not (`alias claude='session start -'`)
|
|
225
|
+
- [The pane signal][pane-state]: BUSY / FREE on each seat's tmux pane,
|
|
226
|
+
and `session pane-state agent`, the launchd agent that publishes it
|
|
227
|
+
- [The default model][default-model]: `session default-model`, opt-in,
|
|
228
|
+
puts settings.json's `"model"` back when something rewrites it
|
|
229
|
+
- [The Python library][library]: `from sessiontools import sessions`
|
|
230
|
+
- [Building and testing][building]: make targets, specs, releases
|
|
231
|
+
- [CHANGELOG][changelog]; licence AGPL-3.0-or-later ([LICENSE][license])
|
|
232
|
+
|
|
233
|
+
## Configuration
|
|
234
|
+
|
|
235
|
+
Nothing needs configuring: unset, every part uses its default. What can
|
|
236
|
+
be set, and where each one lives ([configuration][configuration]):
|
|
237
|
+
|
|
238
|
+
- **Settings files**, JSON in layers: `~/.sessionkit/tools/settings/session.json`
|
|
239
|
+
(the operator, the list cache, the pane signal, accounts, a session's
|
|
240
|
+
home, the default model), `~/.sessionkit/tools/settings/sounds.json` (the busy sound), and
|
|
241
|
+
`~/.sessionkit/tools/settings/claude-code.json` (the model, effort
|
|
242
|
+
and status line `session start` passes on). Every key, its default and
|
|
243
|
+
which layers it is read from: [settings][settings].
|
|
244
|
+
- **Folders of its own:** `~/.session/` (sessions, seats, agent files, the
|
|
245
|
+
state dir) and `~/.sessionkit/tools/accounts/` (`session account`).
|
|
246
|
+
- **Environment variables:** the settle alert's `SESSION_SETTLE_AT`, the
|
|
247
|
+
clock line's `SESSION_CLOCK_WARN_AT`, the hooks' `SESSIONTOOLS_HOOK_*`
|
|
248
|
+
switches (`SESSIONTOOLS_HOOK_CLOCK=on` switches the clock line on), and
|
|
249
|
+
the paths it reads, such as `SESSIONS_DIR` and `SESSION_STATE_DIR`.
|
|
250
|
+
The configuration page lists each one with its default, under the part
|
|
251
|
+
that reads it.
|
|
252
|
+
|
|
253
|
+
## Logs
|
|
254
|
+
|
|
255
|
+
- **The sound engine:** `~/Library/Logs/sessiontools/sound-engine.log`,
|
|
256
|
+
once `session sound engine on` has run.
|
|
257
|
+
- **The pane signal's agent:** `~/Library/Logs/sessiontools/pane-state.log`,
|
|
258
|
+
once `session pane-state agent on` has run.
|
|
259
|
+
- **The default model:** `~/.session/state/default-model/log.jsonl`, one
|
|
260
|
+
line per write to settings.json, and
|
|
261
|
+
`~/Library/Logs/sessiontools/default-model.log`, once you have loaded
|
|
262
|
+
the launchd agent `session default-model unit launchd` prints.
|
|
263
|
+
- **`session reap --yes`:** `~/.session/state/reap.log`, one line for each
|
|
264
|
+
seat it closed or failed to close.
|
|
265
|
+
- **Each session's settings at birth:**
|
|
266
|
+
`~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
|
|
267
|
+
start` read into that session's settings: each environment variable
|
|
268
|
+
by name, never its value.
|
|
269
|
+
- **The status line:** `~/.config/session/statusline-log.jsonl`, one line
|
|
270
|
+
per render, only when `~/.config/session/` already exists.
|
|
271
|
+
|
|
272
|
+
Follow one as it grows with `tail -F`, for example
|
|
273
|
+
`tail -F ~/Library/Logs/sessiontools/pane-state.log`.
|
|
274
|
+
|
|
275
|
+
- **Health:** `session list` prints a row for each live session, with its
|
|
276
|
+
state and context. A session you know is running that is not listed is
|
|
277
|
+
one sessiontools cannot see.
|
|
278
|
+
|
|
279
|
+
[verbs]: docs/session.md
|
|
280
|
+
[start]: docs/session-start-launcher.md
|
|
281
|
+
[credentials]: docs/session-start-launcher.md#credentials-are-never-handed-down
|
|
282
|
+
[account]: docs/account.md
|
|
283
|
+
[cache]: docs/list-snapshot-cache.md
|
|
284
|
+
[operator]: docs/operator-privileged-seats.md
|
|
285
|
+
[reap]: docs/session-reap.md
|
|
286
|
+
[completion]: docs/shell-completion.md
|
|
287
|
+
[plugin]: docs/claude-code-plugin.md
|
|
288
|
+
[settle]: docs/settle-alert-hook.md
|
|
289
|
+
[clock]: docs/clock-line-hook.md
|
|
290
|
+
[busy]: docs/busy-sound-hook.md
|
|
291
|
+
[session-info]: docs/session-info-hook.md
|
|
292
|
+
[engine]: docs/sound-engine-agent.md
|
|
293
|
+
[status-line]: docs/status-line-script.md
|
|
294
|
+
[pane-state]: docs/pane-state-signal.md
|
|
295
|
+
[default-model]: docs/default-model.md
|
|
296
|
+
[library]: docs/python-library-api.md
|
|
297
|
+
[building]: docs/building-and-testing.md
|
|
298
|
+
[changelog]: CHANGELOG.md
|
|
299
|
+
[license]: LICENSE
|
|
300
|
+
[configuration]: docs/configuration.md
|
|
301
|
+
[settings]: docs/settings.md
|
|
@@ -1,38 +1,43 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sessiontools"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "The harness layer: sessions, status and idle, one driver per harness - a library first"
|
|
5
|
+
readme = "README.md"
|
|
5
6
|
license = "AGPL-3.0-or-later"
|
|
6
7
|
license-files = ["LICENSE"]
|
|
7
8
|
authors = [
|
|
8
|
-
{ name = "
|
|
9
|
+
{ name = "Mike Bailey", email = "mike@sessionkit.ai" }
|
|
10
|
+
]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
9
13
|
]
|
|
10
14
|
# >=3.11, not the recipe's >=3.13: sessionmail (the first consumer) declares
|
|
11
15
|
# >=3.11, and uv resolves for EVERY version a project allows, so a stricter
|
|
12
|
-
# floor here made sessionmail's `uv sync` unsatisfiable
|
|
13
|
-
#
|
|
14
|
-
# the tree needs 3.13.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
16
|
+
# floor here made sessionmail's `uv sync` unsatisfiable.
|
|
17
|
+
# Measured: the suite passes on 3.11, 3.12 and 3.13; nothing in
|
|
18
|
+
# the tree needs 3.13. The ceiling, <3.15, makes 3.14 the newest supported
|
|
19
|
+
# version.
|
|
20
|
+
requires-python = ">=3.11,<3.15"
|
|
21
|
+
# TWO runtime dependencies. The FIRST, PyYAML, for agent front matter, which
|
|
22
|
+
# is YAML (the same YAML Claude Code reads itself), and `session start`
|
|
23
|
+
# may pull in the YAML library for itself alone. So PyYAML is declared here and imported by exactly one module,
|
|
20
24
|
# `sessiontools.start.agentfile`; `import sessiontools` (the library
|
|
21
25
|
# sessionmail depends on) still imports nothing outside the standard library.
|
|
22
26
|
# tests/test_cli.py pins both halves.
|
|
23
27
|
# The SECOND: jsonschema, for `session settings` alone - each tool ships a
|
|
24
28
|
# JSON Schema and the reader checks the merged result against it. No
|
|
25
|
-
# configuration library for the layering
|
|
26
|
-
# Cora /RULINGS 4600); imported inside `sessiontools.settings.check_schema`,
|
|
29
|
+
# configuration library for the layering, by design; imported inside `sessiontools.settings.check_schema`,
|
|
27
30
|
# so `import sessiontools` still reaches nothing outside the standard library.
|
|
28
31
|
dependencies = ["PyYAML>=6", "jsonschema>=4"]
|
|
29
32
|
|
|
30
|
-
# THE `session` COMMAND -
|
|
31
|
-
#
|
|
32
|
-
# ("Ah, yes, it should"), same verbs, ported as package code ("port it
|
|
33
|
-
# nicely"), superseding his 12:18 Thu 2026-09-17 "not on our path today".
|
|
33
|
+
# THE `session` COMMAND - settled at the cutover, when the session repo moved
|
|
34
|
+
# aside: sessiontools provides it, same verbs, ported as package code.
|
|
34
35
|
# Exactly one package owns `session` on the PATH; from here it is this one.
|
|
35
36
|
# argparse and the library; PyYAML for `session start` alone (above).
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/sessionkit/sessiontools"
|
|
39
|
+
Repository = "https://github.com/sessionkit/sessiontools"
|
|
40
|
+
|
|
36
41
|
[project.scripts]
|
|
37
42
|
session = "sessiontools.cli:main"
|
|
38
43
|
|