sessiontools 0.3.0__tar.gz → 0.3.2__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.
Files changed (95) hide show
  1. {sessiontools-0.3.0 → sessiontools-0.3.2}/PKG-INFO +101 -31
  2. {sessiontools-0.3.0 → sessiontools-0.3.2}/README.md +100 -30
  3. {sessiontools-0.3.0 → sessiontools-0.3.2}/pyproject.toml +1 -1
  4. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/cli.py +52 -13
  5. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/limits.py +6 -4
  6. sessiontools-0.3.2/src/sessiontools/account/profile.py +147 -0
  7. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/status.py +139 -35
  8. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/use.py +26 -6
  9. sessiontools-0.3.2/src/sessiontools/account/verify.py +419 -0
  10. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/band.py +1 -1
  11. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/claude_code.py +1 -1
  12. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/cli.py +82 -2
  13. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/hooks.py +1 -1
  14. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/default_model_cli.py +1 -1
  15. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/default_model_watch.py +6 -3
  16. sessiontools-0.3.2/src/sessiontools/identity_block.py +169 -0
  17. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/listing.py +101 -6
  18. sessiontools-0.3.2/src/sessiontools/migrate.py +572 -0
  19. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/pane_state_agent.py +8 -3
  20. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/park.py +1 -1
  21. sessiontools-0.3.2/src/sessiontools/paths.py +165 -0
  22. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/procs.py +59 -2
  23. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/reap.py +7 -5
  24. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/session_info.py +52 -5
  25. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/settings.py +214 -13
  26. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/snapshot.py +5 -7
  27. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/sound/__init__.py +6 -8
  28. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/sound/engine.swift +1 -1
  29. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/sound/service.py +29 -8
  30. sessiontools-0.3.2/src/sessiontools/start/__init__.py +666 -0
  31. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/agentfile.py +7 -2
  32. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/agents.py +81 -26
  33. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/args.py +23 -11
  34. sessiontools-0.3.2/src/sessiontools/start/boot_identity.py +427 -0
  35. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/claude_settings.py +71 -5
  36. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/context.py +15 -5
  37. sessiontools-0.3.2/src/sessiontools/start/default_seat.md +3 -0
  38. sessiontools-0.3.2/src/sessiontools/start/default_seat.py +537 -0
  39. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/environment.py +37 -1
  40. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/errors.py +3 -0
  41. sessiontools-0.3.2/src/sessiontools/start/holders.py +494 -0
  42. sessiontools-0.3.2/src/sessiontools/start/homefolder.py +220 -0
  43. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/identity.py +4 -2
  44. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/placement.py +64 -7
  45. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/plan.py +128 -41
  46. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/run.py +33 -1
  47. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/vendor.py +13 -1
  48. sessiontools-0.3.0/src/sessiontools/start/__init__.py +0 -151
  49. sessiontools-0.3.0/src/sessiontools/start/holders.py +0 -193
  50. {sessiontools-0.3.0 → sessiontools-0.3.2}/LICENSE +0 -0
  51. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/__init__.py +0 -0
  52. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/__init__.py +0 -0
  53. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/keychain.py +0 -0
  54. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/leakscan.py +0 -0
  55. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/movehome.py +0 -0
  56. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/new.py +0 -0
  57. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/registry.py +0 -0
  58. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/setuptoken.py +0 -0
  59. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/tokenfile.py +0 -0
  60. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/account/tokenstore.py +0 -0
  61. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/busy.py +0 -0
  62. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/clockline.py +0 -0
  63. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/completion.py +0 -0
  64. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/__init__.py +0 -0
  65. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/boot.py +0 -0
  66. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/breakdown.py +0 -0
  67. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/nnls.py +0 -0
  68. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/render.py +0 -0
  69. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/slash_context.py +0 -0
  70. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/tools.py +0 -0
  71. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/context_parts/transcript.py +0 -0
  72. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/default_model.py +0 -0
  73. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/get.py +0 -0
  74. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/ledger/__init__.py +0 -0
  75. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/ledger/_tiktoken_child.py +0 -0
  76. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/ledger/count.py +0 -0
  77. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/ledger/render.py +0 -0
  78. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/ledger/transcript.py +0 -0
  79. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/operator.py +0 -0
  80. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/pane_state.py +0 -0
  81. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/py.typed +0 -0
  82. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/send.py +0 -0
  83. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/settle.py +0 -0
  84. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/sound/event.swift +0 -0
  85. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/policy.py +0 -0
  86. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/record.py +0 -0
  87. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/resume.py +0 -0
  88. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/start/secrets.py +0 -0
  89. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/statusline/__init__.py +0 -0
  90. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/statusline/sample.json +0 -0
  91. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/statusline/statusline.sh +0 -0
  92. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/tmux.py +0 -0
  93. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/turn.py +0 -0
  94. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/verbs.py +0 -0
  95. {sessiontools-0.3.0 → sessiontools-0.3.2}/src/sessiontools/window.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sessiontools
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: The harness layer: sessions, status and idle, one driver per harness - a library first
5
5
  Author: Mike Bailey
6
6
  Author-email: Mike Bailey <mike@sessionkit.ai>
@@ -61,6 +61,8 @@ eval "$(session completion bash)"
61
61
  category.
62
62
  - `session ledger --short`: each file read and command run, by tokens.
63
63
  - `session account status`: which Claude account this Mac is on.
64
+ - `session account verify`: which account the API bills for this seat's
65
+ token, from one 1-token request.
64
66
  - `session start --list-agents`: the agents it can start.
65
67
  - `session reap`: seats idle past 1h, each CLOSE or KEEP, and why. A dry
66
68
  run.
@@ -68,6 +70,16 @@ eval "$(session completion bash)"
68
70
  whether a pin keeps it there. Off until you set `model.default`.
69
71
  - `session --help`: every verb.
70
72
 
73
+ ## Requirements
74
+
75
+ - [x] macOS (tested on macOS 27, Apple silicon)
76
+ - [ ] Linux
77
+ - [ ] WSL
78
+ - [ ] Windows
79
+
80
+ What sessiontools depends on, what needs each one, and how to upgrade
81
+ it: [dependencies][dependencies].
82
+
71
83
  ## Switching accounts
72
84
 
73
85
  `session account use NAME` moves this Mac to another Claude account from
@@ -119,8 +131,10 @@ it. Each line says what puts it there and what takes it away.
119
131
  sessiontools` drops this package's entries, and `uv cache prune` drops
120
132
  the ones nothing uses.
121
133
  - **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`.
134
+ - `~/.sessionkit/tools/state/list/`: the list cache, `snapshot.json`
135
+ and `list.lock`, at the first `session list`. The state folders here
136
+ and below are on a fresh host; a host that still has
137
+ `~/.session/state/` keeps using it until it is moved.
124
138
  - `~/.session/sessions/<session-id>/`: one for each `session start`,
125
139
  holding `launch/`, `log/settings.jsonl` and `session-id`. It also
126
140
  gets `settings/<tool>.d/50-env.json`, one for each tool whose
@@ -129,14 +143,19 @@ it. Each line says what puts it there and what takes it away.
129
143
  `log/settings.jsonl` names each variable it read, never its value.
130
144
  The plugin's hooks and `session park` write only inside a folder
131
145
  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.
146
+ - `~/.sessionkit/tools/state/pane-state/watch.lock`: the pane signal's
147
+ service.
148
+ - `~/.sessionkit/tools/state/default-model/`: `backups/` and
149
+ `log.jsonl`, the first time `session default-model enforce` changes
150
+ settings.json.
136
151
  - `~/.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.
152
+ - `~/.sessionkit/tools/state/sound/bin/`: `session sound engine on`
153
+ builds the sound engine there with `swiftc` (in
154
+ `~/.local/share/sessiontools/sound/bin/` while that old folder is
155
+ still there).
156
+ - `~/.sessionkit/tools/log/`: the services' logs and `reap.log`
157
+ (Logs, below). An older release wrote them elsewhere, and those
158
+ files stay where they were.
140
159
  - `SESSIONS_DIR`, `SESSION_STATE_DIR` and `SESSIONTOOLS_SOUND_HOME`
141
160
  move these folders when set.
142
161
  - **Services (launchd agents):** none until you turn one on. Each `on`
@@ -178,6 +197,12 @@ it. Each line says what puts it there and what takes it away.
178
197
  With `model.default` set, `session default-model enforce` (and the
179
198
  unit or `watch` that runs it) rewrites the top-level `"model"` in
180
199
  `~/.claude/settings.json`, after a backup.
200
+ - **Not changed by an upgrade: a live tmux server.** One born inside the
201
+ default seat by sessiontools 0.3.1 or earlier still hands
202
+ `CLAUDE_CODE_AGENT=claude` to every pane it makes, so a raw `claude`
203
+ there hears the seat's mail. Restarting that server, or running
204
+ `tmux set-environment -g -u CLAUDE_CODE_AGENT` on it, is yours to do
205
+ ([the default seat][default-seat]).
181
206
 
182
207
  ## Uninstall
183
208
 
@@ -198,23 +223,27 @@ uv tool uninstall sessiontools
198
223
  ```
199
224
 
200
225
  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:
226
+ copy and the engine's folder are sessiontools' alone. To delete them:
203
227
 
204
228
  ```bash
205
229
  rm -rf "${HOME:?}/.claude/plugins/cache/sessiontools"
206
- rm -rf "${HOME:?}/Library/Logs/sessiontools"
207
230
  rm -rf "${HOME:?}/.local/share/sessiontools"
231
+ rm -rf "${HOME:?}/.sessionkit/tools/state/sound"
208
232
  ```
209
233
 
234
+ The logs are left in place: the new ones in `~/.sessionkit/tools/log/`,
235
+ and an older release's in `~/Library/Logs/sessiontools/`. Nothing here
236
+ deletes from `~/Library/Logs`.
237
+
210
238
  uv's cache stays too, with the other things uv installed; `uv cache
211
239
  clean sessiontools` drops this package's entries.
212
240
 
213
241
  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.
242
+ `~/.sessionkit/tools/` holds your settings, accounts, state and logs,
243
+ and the accounts folder keeps the backups of every token `session
244
+ account use` replaced. `~/.session/` holds the session folders (and, on
245
+ a host that has not moved it, the old state folder), and the kit's other
246
+ packages keep their files in it too.
218
247
 
219
248
  ## Docs
220
249
 
@@ -226,6 +255,10 @@ and the kit's other packages keep their files in it too.
226
255
  - [The `session list` cache][cache]: one computation, many readers
227
256
  - [Operator and privileged seats][operator]: who seats ask
228
257
  - [Closing idle seats][reap]: `session reap`, a dry run by default
258
+ - [Where tools keeps its state][state-paths]: each folder, old and new,
259
+ the rule, and `session path`, the verb peers ask
260
+ - [Moving tools' state][state-migrate]: `session path migrate`, one host
261
+ at a time, dry run first
229
262
  - [Shell completion][completion]: `session completion bash|zsh`, a static
230
263
  script built from the verbs' own parsers
231
264
  - [The Claude Code plugin][plugin]: the skill and the hooks
@@ -234,6 +267,8 @@ and the kit's other packages keep their files in it too.
234
267
  - [The busy sound][busy]: a sound while a tool batch runs long
235
268
  - [The session-info hooks][session-info]: the short session id as the
236
269
  session title, and the session's facts in context, both off by default
270
+ - [The identity block][identity]: who a launched session is, in its
271
+ context on turn one and from `session identity`
237
272
  - [The sound engine][engine]: the busy sound from one resident process
238
273
  - [The status line][status-line]: `session statusline install` puts it in the
239
274
  kit's claude-code layer, never `~/.claude`. `session start` seats show it;
@@ -243,6 +278,8 @@ and the kit's other packages keep their files in it too.
243
278
  - [The default model][default-model]: `session default-model`, opt-in,
244
279
  puts settings.json's `"model"` back when something rewrites it
245
280
  - [The Python library][library]: `from sessiontools import sessions`
281
+ - [Dependencies][dependencies]: what sessiontools needs, what needs each
282
+ one, and how to upgrade it
246
283
  - [Building and testing][building]: make targets, specs, releases
247
284
  - [CHANGELOG][changelog]; licence AGPL-3.0-or-later ([LICENSE][license])
248
285
 
@@ -254,11 +291,28 @@ be set, and where each one lives ([configuration][configuration]):
254
291
  - **Settings files**, JSON in layers: `~/.sessionkit/tools/settings/session.json`
255
292
  (the operator, the list cache, the pane signal, accounts, a session's
256
293
  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
294
+ `~/.sessionkit/tools/settings/claude-code.json` (the model, effort,
295
+ status line and renderer `session start` passes on). Every key, its default and
259
296
  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`).
297
+ - **Folders of its own:** `~/.sessionkit/tools/accounts/` (`session
298
+ account`), and its state, each leaf with an old and a new folder. A
299
+ fresh host starts `state` and `sound` in the new folder; an existing
300
+ one stays put until it is moved, and a moved one is followed
301
+ ([where tools keeps its state][state-paths]):
302
+ - `state`: `~/.session/state/`, new `~/.sessionkit/tools/state/`.
303
+ - `sessions`, `seats`, `agent` and `backups`: `~/.session/<leaf>/`, new
304
+ `~/.sessionkit/tools/state/<leaf>/`.
305
+ - `sound`: `~/.local/share/sessiontools/sound/`, new
306
+ `~/.sessionkit/tools/state/sound/`.
307
+ - **The rule, per leaf:** its variable when set; else the old folder
308
+ while it is real; else the new one when it exists; else the new one
309
+ for `state` and `sound`, the old one for the rest.
310
+ - **To see what is used:** `session path LEAF`, or `session path --json`.
311
+ - **To move `state` and `sound`:** `session path migrate --dry-run`,
312
+ then a real run with that host's go ([moving tools' state][state-migrate]).
313
+ - **Upgrade every copy of sessiontools on a host together,** other
314
+ packages' copies included: an older copy writes the old `state`
315
+ folder, and `session path --json` shows `stranded` when one lags.
262
316
  - **Environment variables:** the settle alert's `SESSION_SETTLE_AT`, the
263
317
  clock line's `SESSION_CLOCK_WARN_AT`, the hooks' `SESSIONTOOLS_HOOK_*`
264
318
  switches (`SESSIONTOOLS_HOOK_CLOCK=on` switches the clock line on), and
@@ -268,31 +322,43 @@ be set, and where each one lives ([configuration][configuration]):
268
322
 
269
323
  ## Logs
270
324
 
271
- - **The sound engine:** `~/Library/Logs/sessiontools/sound-engine.log`,
325
+ - **The sound engine:** `~/.sessionkit/tools/log/sound-engine.log`,
272
326
  once `session sound engine on` has run.
273
- - **The pane signal's agent:** `~/Library/Logs/sessiontools/pane-state.log`,
327
+ - **The pane signal's agent:** `~/.sessionkit/tools/log/pane-state.log`,
274
328
  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
329
+ - **The default model:** `~/.sessionkit/tools/state/default-model/log.jsonl`
330
+ (`~/.session/state/default-model/log.jsonl` on a Mac that still has
331
+ its old state folder), one line per write to settings.json, and
332
+ `~/.sessionkit/tools/log/default-model.log`, once you have loaded
278
333
  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.
334
+ - **`session reap --yes`:** `~/.sessionkit/tools/log/reap.log`, one line
335
+ for each seat it closed or failed to close.
281
336
  - **Each session's settings at birth:**
282
337
  `~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
283
338
  start` read into that session's settings: each environment variable
284
339
  by name, never its value.
285
340
  - **The status line:** `~/.config/session/statusline-log.jsonl`, one line
286
341
  per render, only when `~/.config/session/` already exists.
342
+ - **Old logs, 0.3.1 and before:** the three services logged to
343
+ `~/Library/Logs/sessiontools/`, and `session reap --yes` to
344
+ `$SESSION_STATE_DIR/reap.log` (`~/.session/state/reap.log`). Those
345
+ files are left in place. A service an older release installed keeps
346
+ writing its old log, at every login too, until its plist is written
347
+ again: `on` for the sound engine and the pane signal, the steps in
348
+ [the default model][default-model] for its agent. The sound engine's
349
+ and the pane signal's `status` name an old log while it is still there.
287
350
 
288
351
  Follow one as it grows with `tail -F`, for example
289
- `tail -F ~/Library/Logs/sessiontools/pane-state.log`.
352
+ `tail -F ~/.sessionkit/tools/log/pane-state.log`.
290
353
 
291
354
  - **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.
355
+ state and context, and SEAT names the seat a session holds: `claude`
356
+ for the default seat, or an agent's name for its hand-launched
357
+ holder. A session you know is running that is not listed is one
358
+ sessiontools cannot see.
294
359
 
295
360
  [verbs]: docs/session.md
361
+ [default-seat]: docs/session.md#the-default-seat
296
362
  [start]: docs/session-start-launcher.md
297
363
  [credentials]: docs/session-start-launcher.md#credentials-are-never-handed-down
298
364
  [account]: docs/account.md
@@ -300,17 +366,21 @@ Follow one as it grows with `tail -F`, for example
300
366
  [operator]: docs/operator-privileged-seats.md
301
367
  [reap]: docs/session-reap.md
302
368
  [completion]: docs/shell-completion.md
369
+ [state-paths]: docs/tools-state-paths.md
370
+ [state-migrate]: docs/tools-state-migrate.md
303
371
  [plugin]: docs/claude-code-plugin.md
304
372
  [settle]: docs/settle-alert-hook.md
305
373
  [clock]: docs/clock-line-hook.md
306
374
  [busy]: docs/busy-sound-hook.md
307
375
  [session-info]: docs/session-info-hook.md
376
+ [identity]: docs/identity-block.md
308
377
  [engine]: docs/sound-engine-agent.md
309
378
  [status-line]: docs/status-line-script.md
310
379
  [pane-state]: docs/pane-state-signal.md
311
380
  [default-model]: docs/default-model.md
312
381
  [library]: docs/python-library-api.md
313
382
  [building]: docs/building-and-testing.md
383
+ [dependencies]: docs/dependencies.md
314
384
  [changelog]: CHANGELOG.md
315
385
  [license]: LICENSE
316
386
  [configuration]: docs/configuration.md
@@ -45,6 +45,8 @@ eval "$(session completion bash)"
45
45
  category.
46
46
  - `session ledger --short`: each file read and command run, by tokens.
47
47
  - `session account status`: which Claude account this Mac is on.
48
+ - `session account verify`: which account the API bills for this seat's
49
+ token, from one 1-token request.
48
50
  - `session start --list-agents`: the agents it can start.
49
51
  - `session reap`: seats idle past 1h, each CLOSE or KEEP, and why. A dry
50
52
  run.
@@ -52,6 +54,16 @@ eval "$(session completion bash)"
52
54
  whether a pin keeps it there. Off until you set `model.default`.
53
55
  - `session --help`: every verb.
54
56
 
57
+ ## Requirements
58
+
59
+ - [x] macOS (tested on macOS 27, Apple silicon)
60
+ - [ ] Linux
61
+ - [ ] WSL
62
+ - [ ] Windows
63
+
64
+ What sessiontools depends on, what needs each one, and how to upgrade
65
+ it: [dependencies][dependencies].
66
+
55
67
  ## Switching accounts
56
68
 
57
69
  `session account use NAME` moves this Mac to another Claude account from
@@ -103,8 +115,10 @@ it. Each line says what puts it there and what takes it away.
103
115
  sessiontools` drops this package's entries, and `uv cache prune` drops
104
116
  the ones nothing uses.
105
117
  - **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`.
118
+ - `~/.sessionkit/tools/state/list/`: the list cache, `snapshot.json`
119
+ and `list.lock`, at the first `session list`. The state folders here
120
+ and below are on a fresh host; a host that still has
121
+ `~/.session/state/` keeps using it until it is moved.
108
122
  - `~/.session/sessions/<session-id>/`: one for each `session start`,
109
123
  holding `launch/`, `log/settings.jsonl` and `session-id`. It also
110
124
  gets `settings/<tool>.d/50-env.json`, one for each tool whose
@@ -113,14 +127,19 @@ it. Each line says what puts it there and what takes it away.
113
127
  `log/settings.jsonl` names each variable it read, never its value.
114
128
  The plugin's hooks and `session park` write only inside a folder
115
129
  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.
130
+ - `~/.sessionkit/tools/state/pane-state/watch.lock`: the pane signal's
131
+ service.
132
+ - `~/.sessionkit/tools/state/default-model/`: `backups/` and
133
+ `log.jsonl`, the first time `session default-model enforce` changes
134
+ settings.json.
120
135
  - `~/.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.
136
+ - `~/.sessionkit/tools/state/sound/bin/`: `session sound engine on`
137
+ builds the sound engine there with `swiftc` (in
138
+ `~/.local/share/sessiontools/sound/bin/` while that old folder is
139
+ still there).
140
+ - `~/.sessionkit/tools/log/`: the services' logs and `reap.log`
141
+ (Logs, below). An older release wrote them elsewhere, and those
142
+ files stay where they were.
124
143
  - `SESSIONS_DIR`, `SESSION_STATE_DIR` and `SESSIONTOOLS_SOUND_HOME`
125
144
  move these folders when set.
126
145
  - **Services (launchd agents):** none until you turn one on. Each `on`
@@ -162,6 +181,12 @@ it. Each line says what puts it there and what takes it away.
162
181
  With `model.default` set, `session default-model enforce` (and the
163
182
  unit or `watch` that runs it) rewrites the top-level `"model"` in
164
183
  `~/.claude/settings.json`, after a backup.
184
+ - **Not changed by an upgrade: a live tmux server.** One born inside the
185
+ default seat by sessiontools 0.3.1 or earlier still hands
186
+ `CLAUDE_CODE_AGENT=claude` to every pane it makes, so a raw `claude`
187
+ there hears the seat's mail. Restarting that server, or running
188
+ `tmux set-environment -g -u CLAUDE_CODE_AGENT` on it, is yours to do
189
+ ([the default seat][default-seat]).
165
190
 
166
191
  ## Uninstall
167
192
 
@@ -182,23 +207,27 @@ uv tool uninstall sessiontools
182
207
  ```
183
208
 
184
209
  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:
210
+ copy and the engine's folder are sessiontools' alone. To delete them:
187
211
 
188
212
  ```bash
189
213
  rm -rf "${HOME:?}/.claude/plugins/cache/sessiontools"
190
- rm -rf "${HOME:?}/Library/Logs/sessiontools"
191
214
  rm -rf "${HOME:?}/.local/share/sessiontools"
215
+ rm -rf "${HOME:?}/.sessionkit/tools/state/sound"
192
216
  ```
193
217
 
218
+ The logs are left in place: the new ones in `~/.sessionkit/tools/log/`,
219
+ and an older release's in `~/Library/Logs/sessiontools/`. Nothing here
220
+ deletes from `~/Library/Logs`.
221
+
194
222
  uv's cache stays too, with the other things uv installed; `uv cache
195
223
  clean sessiontools` drops this package's entries.
196
224
 
197
225
  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.
226
+ `~/.sessionkit/tools/` holds your settings, accounts, state and logs,
227
+ and the accounts folder keeps the backups of every token `session
228
+ account use` replaced. `~/.session/` holds the session folders (and, on
229
+ a host that has not moved it, the old state folder), and the kit's other
230
+ packages keep their files in it too.
202
231
 
203
232
  ## Docs
204
233
 
@@ -210,6 +239,10 @@ and the kit's other packages keep their files in it too.
210
239
  - [The `session list` cache][cache]: one computation, many readers
211
240
  - [Operator and privileged seats][operator]: who seats ask
212
241
  - [Closing idle seats][reap]: `session reap`, a dry run by default
242
+ - [Where tools keeps its state][state-paths]: each folder, old and new,
243
+ the rule, and `session path`, the verb peers ask
244
+ - [Moving tools' state][state-migrate]: `session path migrate`, one host
245
+ at a time, dry run first
213
246
  - [Shell completion][completion]: `session completion bash|zsh`, a static
214
247
  script built from the verbs' own parsers
215
248
  - [The Claude Code plugin][plugin]: the skill and the hooks
@@ -218,6 +251,8 @@ and the kit's other packages keep their files in it too.
218
251
  - [The busy sound][busy]: a sound while a tool batch runs long
219
252
  - [The session-info hooks][session-info]: the short session id as the
220
253
  session title, and the session's facts in context, both off by default
254
+ - [The identity block][identity]: who a launched session is, in its
255
+ context on turn one and from `session identity`
221
256
  - [The sound engine][engine]: the busy sound from one resident process
222
257
  - [The status line][status-line]: `session statusline install` puts it in the
223
258
  kit's claude-code layer, never `~/.claude`. `session start` seats show it;
@@ -227,6 +262,8 @@ and the kit's other packages keep their files in it too.
227
262
  - [The default model][default-model]: `session default-model`, opt-in,
228
263
  puts settings.json's `"model"` back when something rewrites it
229
264
  - [The Python library][library]: `from sessiontools import sessions`
265
+ - [Dependencies][dependencies]: what sessiontools needs, what needs each
266
+ one, and how to upgrade it
230
267
  - [Building and testing][building]: make targets, specs, releases
231
268
  - [CHANGELOG][changelog]; licence AGPL-3.0-or-later ([LICENSE][license])
232
269
 
@@ -238,11 +275,28 @@ be set, and where each one lives ([configuration][configuration]):
238
275
  - **Settings files**, JSON in layers: `~/.sessionkit/tools/settings/session.json`
239
276
  (the operator, the list cache, the pane signal, accounts, a session's
240
277
  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
278
+ `~/.sessionkit/tools/settings/claude-code.json` (the model, effort,
279
+ status line and renderer `session start` passes on). Every key, its default and
243
280
  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`).
281
+ - **Folders of its own:** `~/.sessionkit/tools/accounts/` (`session
282
+ account`), and its state, each leaf with an old and a new folder. A
283
+ fresh host starts `state` and `sound` in the new folder; an existing
284
+ one stays put until it is moved, and a moved one is followed
285
+ ([where tools keeps its state][state-paths]):
286
+ - `state`: `~/.session/state/`, new `~/.sessionkit/tools/state/`.
287
+ - `sessions`, `seats`, `agent` and `backups`: `~/.session/<leaf>/`, new
288
+ `~/.sessionkit/tools/state/<leaf>/`.
289
+ - `sound`: `~/.local/share/sessiontools/sound/`, new
290
+ `~/.sessionkit/tools/state/sound/`.
291
+ - **The rule, per leaf:** its variable when set; else the old folder
292
+ while it is real; else the new one when it exists; else the new one
293
+ for `state` and `sound`, the old one for the rest.
294
+ - **To see what is used:** `session path LEAF`, or `session path --json`.
295
+ - **To move `state` and `sound`:** `session path migrate --dry-run`,
296
+ then a real run with that host's go ([moving tools' state][state-migrate]).
297
+ - **Upgrade every copy of sessiontools on a host together,** other
298
+ packages' copies included: an older copy writes the old `state`
299
+ folder, and `session path --json` shows `stranded` when one lags.
246
300
  - **Environment variables:** the settle alert's `SESSION_SETTLE_AT`, the
247
301
  clock line's `SESSION_CLOCK_WARN_AT`, the hooks' `SESSIONTOOLS_HOOK_*`
248
302
  switches (`SESSIONTOOLS_HOOK_CLOCK=on` switches the clock line on), and
@@ -252,31 +306,43 @@ be set, and where each one lives ([configuration][configuration]):
252
306
 
253
307
  ## Logs
254
308
 
255
- - **The sound engine:** `~/Library/Logs/sessiontools/sound-engine.log`,
309
+ - **The sound engine:** `~/.sessionkit/tools/log/sound-engine.log`,
256
310
  once `session sound engine on` has run.
257
- - **The pane signal's agent:** `~/Library/Logs/sessiontools/pane-state.log`,
311
+ - **The pane signal's agent:** `~/.sessionkit/tools/log/pane-state.log`,
258
312
  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
313
+ - **The default model:** `~/.sessionkit/tools/state/default-model/log.jsonl`
314
+ (`~/.session/state/default-model/log.jsonl` on a Mac that still has
315
+ its old state folder), one line per write to settings.json, and
316
+ `~/.sessionkit/tools/log/default-model.log`, once you have loaded
262
317
  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.
318
+ - **`session reap --yes`:** `~/.sessionkit/tools/log/reap.log`, one line
319
+ for each seat it closed or failed to close.
265
320
  - **Each session's settings at birth:**
266
321
  `~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
267
322
  start` read into that session's settings: each environment variable
268
323
  by name, never its value.
269
324
  - **The status line:** `~/.config/session/statusline-log.jsonl`, one line
270
325
  per render, only when `~/.config/session/` already exists.
326
+ - **Old logs, 0.3.1 and before:** the three services logged to
327
+ `~/Library/Logs/sessiontools/`, and `session reap --yes` to
328
+ `$SESSION_STATE_DIR/reap.log` (`~/.session/state/reap.log`). Those
329
+ files are left in place. A service an older release installed keeps
330
+ writing its old log, at every login too, until its plist is written
331
+ again: `on` for the sound engine and the pane signal, the steps in
332
+ [the default model][default-model] for its agent. The sound engine's
333
+ and the pane signal's `status` name an old log while it is still there.
271
334
 
272
335
  Follow one as it grows with `tail -F`, for example
273
- `tail -F ~/Library/Logs/sessiontools/pane-state.log`.
336
+ `tail -F ~/.sessionkit/tools/log/pane-state.log`.
274
337
 
275
338
  - **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.
339
+ state and context, and SEAT names the seat a session holds: `claude`
340
+ for the default seat, or an agent's name for its hand-launched
341
+ holder. A session you know is running that is not listed is one
342
+ sessiontools cannot see.
278
343
 
279
344
  [verbs]: docs/session.md
345
+ [default-seat]: docs/session.md#the-default-seat
280
346
  [start]: docs/session-start-launcher.md
281
347
  [credentials]: docs/session-start-launcher.md#credentials-are-never-handed-down
282
348
  [account]: docs/account.md
@@ -284,17 +350,21 @@ Follow one as it grows with `tail -F`, for example
284
350
  [operator]: docs/operator-privileged-seats.md
285
351
  [reap]: docs/session-reap.md
286
352
  [completion]: docs/shell-completion.md
353
+ [state-paths]: docs/tools-state-paths.md
354
+ [state-migrate]: docs/tools-state-migrate.md
287
355
  [plugin]: docs/claude-code-plugin.md
288
356
  [settle]: docs/settle-alert-hook.md
289
357
  [clock]: docs/clock-line-hook.md
290
358
  [busy]: docs/busy-sound-hook.md
291
359
  [session-info]: docs/session-info-hook.md
360
+ [identity]: docs/identity-block.md
292
361
  [engine]: docs/sound-engine-agent.md
293
362
  [status-line]: docs/status-line-script.md
294
363
  [pane-state]: docs/pane-state-signal.md
295
364
  [default-model]: docs/default-model.md
296
365
  [library]: docs/python-library-api.md
297
366
  [building]: docs/building-and-testing.md
367
+ [dependencies]: docs/dependencies.md
298
368
  [changelog]: CHANGELOG.md
299
369
  [license]: LICENSE
300
370
  [configuration]: docs/configuration.md
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sessiontools"
3
- version = "0.3.0"
3
+ version = "0.3.2"
4
4
  description = "The harness layer: sessions, status and idle, one driver per harness - a library first"
5
5
  readme = "README.md"
6
6
  license = "AGPL-3.0-or-later"