sessiontools 0.1.0__tar.gz → 0.2.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.2.0/PKG-INFO +166 -0
- sessiontools-0.2.0/README.md +150 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/pyproject.toml +21 -16
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/__init__.py +18 -4
- sessiontools-0.2.0/src/sessiontools/account/__init__.py +15 -0
- sessiontools-0.2.0/src/sessiontools/account/cli.py +369 -0
- sessiontools-0.2.0/src/sessiontools/account/keychain.py +318 -0
- sessiontools-0.2.0/src/sessiontools/account/leakscan.py +190 -0
- sessiontools-0.2.0/src/sessiontools/account/limits.py +248 -0
- sessiontools-0.2.0/src/sessiontools/account/movehome.py +312 -0
- sessiontools-0.2.0/src/sessiontools/account/new.py +458 -0
- sessiontools-0.2.0/src/sessiontools/account/registry.py +589 -0
- sessiontools-0.2.0/src/sessiontools/account/setuptoken.py +1373 -0
- sessiontools-0.2.0/src/sessiontools/account/status.py +618 -0
- sessiontools-0.2.0/src/sessiontools/account/tokenfile.py +365 -0
- sessiontools-0.2.0/src/sessiontools/account/tokenstore.py +462 -0
- sessiontools-0.2.0/src/sessiontools/account/use.py +814 -0
- sessiontools-0.2.0/src/sessiontools/band.py +130 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/busy.py +206 -63
- sessiontools-0.2.0/src/sessiontools/claude_code.py +457 -0
- sessiontools-0.2.0/src/sessiontools/cli.py +792 -0
- sessiontools-0.2.0/src/sessiontools/completion.py +400 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/__init__.py +50 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/boot.py +534 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/breakdown.py +218 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/hooks.py +269 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/nnls.py +112 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/render.py +478 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/slash_context.py +137 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/tools.py +118 -0
- sessiontools-0.2.0/src/sessiontools/context_parts/transcript.py +401 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/get.py +6 -4
- sessiontools-0.2.0/src/sessiontools/ledger/__init__.py +338 -0
- sessiontools-0.2.0/src/sessiontools/ledger/_tiktoken_child.py +65 -0
- sessiontools-0.2.0/src/sessiontools/ledger/count.py +176 -0
- sessiontools-0.2.0/src/sessiontools/ledger/render.py +262 -0
- sessiontools-0.2.0/src/sessiontools/ledger/transcript.py +268 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/listing.py +71 -18
- sessiontools-0.2.0/src/sessiontools/operator.py +156 -0
- sessiontools-0.2.0/src/sessiontools/pane_state.py +663 -0
- sessiontools-0.2.0/src/sessiontools/pane_state_agent.py +522 -0
- sessiontools-0.2.0/src/sessiontools/park.py +1359 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/procs.py +46 -8
- sessiontools-0.2.0/src/sessiontools/reap.py +925 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/send.py +2 -2
- sessiontools-0.2.0/src/sessiontools/settings.py +1506 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/settle.py +3 -5
- sessiontools-0.2.0/src/sessiontools/snapshot.py +324 -0
- sessiontools-0.2.0/src/sessiontools/sound/__init__.py +117 -0
- sessiontools-0.2.0/src/sessiontools/sound/engine.swift +2020 -0
- sessiontools-0.2.0/src/sessiontools/sound/event.swift +248 -0
- sessiontools-0.2.0/src/sessiontools/sound/service.py +596 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/__init__.py +9 -10
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/agentfile.py +44 -13
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/agents.py +10 -14
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/args.py +12 -12
- sessiontools-0.2.0/src/sessiontools/start/claude_settings.py +333 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/context.py +74 -23
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/environment.py +128 -14
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/errors.py +2 -2
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/holders.py +6 -6
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/identity.py +83 -18
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/placement.py +19 -8
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/plan.py +300 -68
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/policy.py +59 -53
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/record.py +15 -16
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/resume.py +11 -11
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/run.py +26 -13
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/secrets.py +110 -4
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/start/vendor.py +19 -6
- sessiontools-0.2.0/src/sessiontools/statusline/__init__.py +1195 -0
- sessiontools-0.2.0/src/sessiontools/statusline/sample.json +20 -0
- sessiontools-0.2.0/src/sessiontools/statusline/statusline.sh +185 -0
- sessiontools-0.2.0/src/sessiontools/tmux.py +178 -0
- sessiontools-0.2.0/src/sessiontools/turn.py +191 -0
- sessiontools-0.2.0/src/sessiontools/verbs.py +67 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/window.py +81 -14
- 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.2.0}/LICENSE +0 -0
- {sessiontools-0.1.0 → sessiontools-0.2.0}/src/sessiontools/py.typed +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sessiontools
|
|
3
|
+
Version: 0.2.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
|
+
```console
|
|
27
|
+
uv tool install sessiontools # puts `session` on the PATH
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Python 3.11 to 3.14. Optional: [the Claude Code plugin][plugin] adds
|
|
31
|
+
the `session` skill and two hooks.
|
|
32
|
+
|
|
33
|
+
Shell completion, one line per shell ([shell completion][completion]):
|
|
34
|
+
|
|
35
|
+
```console
|
|
36
|
+
eval "$(session completion zsh)" # zsh: in ~/.zshrc, after compinit
|
|
37
|
+
session completion bash > ~/.local/share/bash-completion/completions/session # bash with bash-completion 2
|
|
38
|
+
eval "$(session completion bash)" # bash 3.2 or any bash without it: in ~/.bashrc
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
```console
|
|
44
|
+
session list # the live sessions: panes, state, context
|
|
45
|
+
session get state # this session: busy, idle with children, idle
|
|
46
|
+
session context # how full this session's context window is
|
|
47
|
+
session context --parts # what filled it: boot, then growth by category
|
|
48
|
+
session ledger --short # each file read and command run, by tokens
|
|
49
|
+
session account status # which Claude account this Mac is on
|
|
50
|
+
session start --list-agents # the agents it can start
|
|
51
|
+
session reap # seats idle past 1h: CLOSE or KEEP, and why (a dry run)
|
|
52
|
+
session --help # every verb
|
|
53
|
+
```
|
|
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
|
+
Without `--yes`, `use` shows the plan and writes nothing. To add an
|
|
69
|
+
account, `session account new NAME --email E` signs in through `claude
|
|
70
|
+
setup-token`, saves the token to passage, reads it back and registers
|
|
71
|
+
it; the token is never shown. See [Switching Claude accounts][account].
|
|
72
|
+
|
|
73
|
+
## Uninstall
|
|
74
|
+
|
|
75
|
+
```console
|
|
76
|
+
uv tool uninstall sessiontools
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
It leaves `~/.session/` (session dirs, the list cache) and
|
|
80
|
+
`~/.sessionkit/tools/settings/`; remove them by hand to leave nothing
|
|
81
|
+
behind.
|
|
82
|
+
|
|
83
|
+
## Docs
|
|
84
|
+
|
|
85
|
+
- [The `session` verbs][verbs]: list, get, context, ledger, account,
|
|
86
|
+
settings, operator, reap
|
|
87
|
+
- [Starting a session][start]: agent files, flags, tmux, one holder
|
|
88
|
+
- [Switching Claude accounts][account]: `session account`, its blast
|
|
89
|
+
radius, and `new`, which adds an account
|
|
90
|
+
- [The `session list` cache][cache]: one computation, many readers
|
|
91
|
+
- [Operator and privileged seats][operator]: who seats ask
|
|
92
|
+
- [Closing idle seats][reap]: `session reap`, a dry run by default
|
|
93
|
+
- [Shell completion][completion]: `session completion bash|zsh`, a static
|
|
94
|
+
script built from the verbs' own parsers
|
|
95
|
+
- [The Claude Code plugin][plugin]: the skill and the hooks
|
|
96
|
+
- [The settle alert][settle]: one line past a context threshold
|
|
97
|
+
- [The busy sound][busy]: a sound while a tool batch runs long
|
|
98
|
+
- [The sound engine][engine]: the busy sound from one resident process
|
|
99
|
+
- [The status line][status-line]: `session statusline install` puts it in the
|
|
100
|
+
kit's claude-code layer, never `~/.claude`. `session start` seats show it;
|
|
101
|
+
a bare `claude` does not (`alias claude='session start -'`)
|
|
102
|
+
- [The pane signal][pane-state]: BUSY / FREE on each seat's tmux pane,
|
|
103
|
+
and `session pane-state agent`, the launchd agent that publishes it
|
|
104
|
+
- [The Python library][library]: `from sessiontools import sessions`
|
|
105
|
+
- [Building and testing][building]: make targets, specs, releases
|
|
106
|
+
- [CHANGELOG][changelog]; licence AGPL-3.0-or-later ([LICENSE][license])
|
|
107
|
+
|
|
108
|
+
## Configuration
|
|
109
|
+
|
|
110
|
+
Nothing needs configuring: unset, every part uses its default. What can
|
|
111
|
+
be set, and where each one lives ([configuration][configuration]):
|
|
112
|
+
|
|
113
|
+
- **Settings files**, JSON in layers: `~/.sessionkit/tools/settings/session.json`
|
|
114
|
+
(the operator, the list cache, the pane signal, accounts, a session's
|
|
115
|
+
home), `~/.sessionkit/tools/settings/sounds.json` (the busy sound), and
|
|
116
|
+
`~/.sessionkit/tools/settings/claude-code.json` (the model, effort
|
|
117
|
+
and status line `session start` passes on). Every key, its default and
|
|
118
|
+
which layers it is read from: [settings][settings].
|
|
119
|
+
- **Folders of its own:** `~/.session/` (sessions, seats, agent files, the
|
|
120
|
+
state dir) and `~/.sessionkit/tools/accounts/` (`session account`).
|
|
121
|
+
- **Environment variables:** the settle alert's `SESSION_SETTLE_AT`, the
|
|
122
|
+
hooks' `SESSIONTOOLS_HOOK_*` switches, and the paths it reads, such as
|
|
123
|
+
`SESSIONS_DIR` and `SESSION_STATE_DIR`. The configuration page lists
|
|
124
|
+
each one with its default, under the part that reads it.
|
|
125
|
+
|
|
126
|
+
## Logs
|
|
127
|
+
|
|
128
|
+
- **The sound engine:** `~/Library/Logs/sessiontools/sound-engine.log`,
|
|
129
|
+
once `session sound engine on` has run.
|
|
130
|
+
- **The pane signal's agent:** `~/Library/Logs/sessiontools/pane-state.log`,
|
|
131
|
+
once `session pane-state agent on` has run.
|
|
132
|
+
- **`session reap --yes`:** `~/.session/state/reap.log`, one line for each
|
|
133
|
+
seat it closed or failed to close.
|
|
134
|
+
- **Each session's settings at birth:**
|
|
135
|
+
`~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
|
|
136
|
+
start` read into that session's settings: each environment variable
|
|
137
|
+
by name, never its value.
|
|
138
|
+
- **The status line:** `~/.config/session/statusline-log.jsonl`, one line
|
|
139
|
+
per render, only when `~/.config/session/` already exists.
|
|
140
|
+
|
|
141
|
+
Follow one as it grows with `tail -F`, for example
|
|
142
|
+
`tail -F ~/Library/Logs/sessiontools/pane-state.log`.
|
|
143
|
+
|
|
144
|
+
- **Health:** `session list` prints a row for each live session, with its
|
|
145
|
+
state and context. A session you know is running that is not listed is
|
|
146
|
+
one sessiontools cannot see.
|
|
147
|
+
|
|
148
|
+
[verbs]: docs/session-command-verbs.md
|
|
149
|
+
[start]: docs/session-start-launcher.md
|
|
150
|
+
[account]: docs/account.md
|
|
151
|
+
[cache]: docs/list-snapshot-cache.md
|
|
152
|
+
[operator]: docs/operator-privileged-seats.md
|
|
153
|
+
[reap]: docs/session-reap.md
|
|
154
|
+
[completion]: docs/shell-completion.md
|
|
155
|
+
[plugin]: docs/claude-code-plugin.md
|
|
156
|
+
[settle]: docs/settle-alert-hook.md
|
|
157
|
+
[busy]: docs/busy-sound-hook.md
|
|
158
|
+
[engine]: docs/sound-engine-agent.md
|
|
159
|
+
[status-line]: docs/status-line-script.md
|
|
160
|
+
[pane-state]: docs/pane-state-signal.md
|
|
161
|
+
[library]: docs/python-library-api.md
|
|
162
|
+
[building]: docs/building-and-testing.md
|
|
163
|
+
[changelog]: CHANGELOG.md
|
|
164
|
+
[license]: LICENSE
|
|
165
|
+
[configuration]: docs/configuration.md
|
|
166
|
+
[settings]: docs/settings.md
|
|
@@ -0,0 +1,150 @@
|
|
|
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
|
+
```console
|
|
11
|
+
uv tool install sessiontools # puts `session` on the PATH
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Python 3.11 to 3.14. Optional: [the Claude Code plugin][plugin] adds
|
|
15
|
+
the `session` skill and two hooks.
|
|
16
|
+
|
|
17
|
+
Shell completion, one line per shell ([shell completion][completion]):
|
|
18
|
+
|
|
19
|
+
```console
|
|
20
|
+
eval "$(session completion zsh)" # zsh: in ~/.zshrc, after compinit
|
|
21
|
+
session completion bash > ~/.local/share/bash-completion/completions/session # bash with bash-completion 2
|
|
22
|
+
eval "$(session completion bash)" # bash 3.2 or any bash without it: in ~/.bashrc
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```console
|
|
28
|
+
session list # the live sessions: panes, state, context
|
|
29
|
+
session get state # this session: busy, idle with children, idle
|
|
30
|
+
session context # how full this session's context window is
|
|
31
|
+
session context --parts # what filled it: boot, then growth by category
|
|
32
|
+
session ledger --short # each file read and command run, by tokens
|
|
33
|
+
session account status # which Claude account this Mac is on
|
|
34
|
+
session start --list-agents # the agents it can start
|
|
35
|
+
session reap # seats idle past 1h: CLOSE or KEEP, and why (a dry run)
|
|
36
|
+
session --help # every verb
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Switching accounts
|
|
40
|
+
|
|
41
|
+
`session account use NAME` moves this Mac to another Claude account from
|
|
42
|
+
a token you already hold: no browser, no restart, and it never prints a
|
|
43
|
+
token. On a Keychain host it moves **every** seat, not one:
|
|
44
|
+
|
|
45
|
+
| route | moves | cache cost | reversible by | gate |
|
|
46
|
+
|---|---|---|---|---|
|
|
47
|
+
| `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 |
|
|
48
|
+
| `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 |
|
|
49
|
+
|
|
50
|
+
A host whose shell exports `CLAUDE_CODE_OAUTH_TOKEN` from a file names it
|
|
51
|
+
in the `session` setting `account.token_file`, and `use` swaps the file.
|
|
52
|
+
Without `--yes`, `use` shows the plan and writes nothing. To add an
|
|
53
|
+
account, `session account new NAME --email E` signs in through `claude
|
|
54
|
+
setup-token`, saves the token to passage, reads it back and registers
|
|
55
|
+
it; the token is never shown. See [Switching Claude accounts][account].
|
|
56
|
+
|
|
57
|
+
## Uninstall
|
|
58
|
+
|
|
59
|
+
```console
|
|
60
|
+
uv tool uninstall sessiontools
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
It leaves `~/.session/` (session dirs, the list cache) and
|
|
64
|
+
`~/.sessionkit/tools/settings/`; remove them by hand to leave nothing
|
|
65
|
+
behind.
|
|
66
|
+
|
|
67
|
+
## Docs
|
|
68
|
+
|
|
69
|
+
- [The `session` verbs][verbs]: list, get, context, ledger, account,
|
|
70
|
+
settings, operator, reap
|
|
71
|
+
- [Starting a session][start]: agent files, flags, tmux, one holder
|
|
72
|
+
- [Switching Claude accounts][account]: `session account`, its blast
|
|
73
|
+
radius, and `new`, which adds an account
|
|
74
|
+
- [The `session list` cache][cache]: one computation, many readers
|
|
75
|
+
- [Operator and privileged seats][operator]: who seats ask
|
|
76
|
+
- [Closing idle seats][reap]: `session reap`, a dry run by default
|
|
77
|
+
- [Shell completion][completion]: `session completion bash|zsh`, a static
|
|
78
|
+
script built from the verbs' own parsers
|
|
79
|
+
- [The Claude Code plugin][plugin]: the skill and the hooks
|
|
80
|
+
- [The settle alert][settle]: one line past a context threshold
|
|
81
|
+
- [The busy sound][busy]: a sound while a tool batch runs long
|
|
82
|
+
- [The sound engine][engine]: the busy sound from one resident process
|
|
83
|
+
- [The status line][status-line]: `session statusline install` puts it in the
|
|
84
|
+
kit's claude-code layer, never `~/.claude`. `session start` seats show it;
|
|
85
|
+
a bare `claude` does not (`alias claude='session start -'`)
|
|
86
|
+
- [The pane signal][pane-state]: BUSY / FREE on each seat's tmux pane,
|
|
87
|
+
and `session pane-state agent`, the launchd agent that publishes it
|
|
88
|
+
- [The Python library][library]: `from sessiontools import sessions`
|
|
89
|
+
- [Building and testing][building]: make targets, specs, releases
|
|
90
|
+
- [CHANGELOG][changelog]; licence AGPL-3.0-or-later ([LICENSE][license])
|
|
91
|
+
|
|
92
|
+
## Configuration
|
|
93
|
+
|
|
94
|
+
Nothing needs configuring: unset, every part uses its default. What can
|
|
95
|
+
be set, and where each one lives ([configuration][configuration]):
|
|
96
|
+
|
|
97
|
+
- **Settings files**, JSON in layers: `~/.sessionkit/tools/settings/session.json`
|
|
98
|
+
(the operator, the list cache, the pane signal, accounts, a session's
|
|
99
|
+
home), `~/.sessionkit/tools/settings/sounds.json` (the busy sound), and
|
|
100
|
+
`~/.sessionkit/tools/settings/claude-code.json` (the model, effort
|
|
101
|
+
and status line `session start` passes on). Every key, its default and
|
|
102
|
+
which layers it is read from: [settings][settings].
|
|
103
|
+
- **Folders of its own:** `~/.session/` (sessions, seats, agent files, the
|
|
104
|
+
state dir) and `~/.sessionkit/tools/accounts/` (`session account`).
|
|
105
|
+
- **Environment variables:** the settle alert's `SESSION_SETTLE_AT`, the
|
|
106
|
+
hooks' `SESSIONTOOLS_HOOK_*` switches, and the paths it reads, such as
|
|
107
|
+
`SESSIONS_DIR` and `SESSION_STATE_DIR`. The configuration page lists
|
|
108
|
+
each one with its default, under the part that reads it.
|
|
109
|
+
|
|
110
|
+
## Logs
|
|
111
|
+
|
|
112
|
+
- **The sound engine:** `~/Library/Logs/sessiontools/sound-engine.log`,
|
|
113
|
+
once `session sound engine on` has run.
|
|
114
|
+
- **The pane signal's agent:** `~/Library/Logs/sessiontools/pane-state.log`,
|
|
115
|
+
once `session pane-state agent on` has run.
|
|
116
|
+
- **`session reap --yes`:** `~/.session/state/reap.log`, one line for each
|
|
117
|
+
seat it closed or failed to close.
|
|
118
|
+
- **Each session's settings at birth:**
|
|
119
|
+
`~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
|
|
120
|
+
start` read into that session's settings: each environment variable
|
|
121
|
+
by name, never its value.
|
|
122
|
+
- **The status line:** `~/.config/session/statusline-log.jsonl`, one line
|
|
123
|
+
per render, only when `~/.config/session/` already exists.
|
|
124
|
+
|
|
125
|
+
Follow one as it grows with `tail -F`, for example
|
|
126
|
+
`tail -F ~/Library/Logs/sessiontools/pane-state.log`.
|
|
127
|
+
|
|
128
|
+
- **Health:** `session list` prints a row for each live session, with its
|
|
129
|
+
state and context. A session you know is running that is not listed is
|
|
130
|
+
one sessiontools cannot see.
|
|
131
|
+
|
|
132
|
+
[verbs]: docs/session-command-verbs.md
|
|
133
|
+
[start]: docs/session-start-launcher.md
|
|
134
|
+
[account]: docs/account.md
|
|
135
|
+
[cache]: docs/list-snapshot-cache.md
|
|
136
|
+
[operator]: docs/operator-privileged-seats.md
|
|
137
|
+
[reap]: docs/session-reap.md
|
|
138
|
+
[completion]: docs/shell-completion.md
|
|
139
|
+
[plugin]: docs/claude-code-plugin.md
|
|
140
|
+
[settle]: docs/settle-alert-hook.md
|
|
141
|
+
[busy]: docs/busy-sound-hook.md
|
|
142
|
+
[engine]: docs/sound-engine-agent.md
|
|
143
|
+
[status-line]: docs/status-line-script.md
|
|
144
|
+
[pane-state]: docs/pane-state-signal.md
|
|
145
|
+
[library]: docs/python-library-api.md
|
|
146
|
+
[building]: docs/building-and-testing.md
|
|
147
|
+
[changelog]: CHANGELOG.md
|
|
148
|
+
[license]: LICENSE
|
|
149
|
+
[configuration]: docs/configuration.md
|
|
150
|
+
[settings]: docs/settings.md
|
|
@@ -1,38 +1,43 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sessiontools"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.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
|
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
"""sessiontools - the harness layer: sessions, their status, and how long
|
|
2
2
|
they have been idle - one driver per harness, a library first.
|
|
3
3
|
|
|
4
|
-
Import it, or use the command it ships: `session` (
|
|
5
|
-
|
|
4
|
+
Import it, or use the command it ships: `session` (since
|
|
5
|
+
2030-07-29, when the session repo was retired). `session list` and
|
|
6
6
|
`session get` are built on the functions below; `session start` is its own
|
|
7
|
-
package, `sessiontools.start`; `session send` is disabled (
|
|
7
|
+
package, `sessiontools.start`; `session send` is disabled (2030-07-30).
|
|
8
8
|
|
|
9
9
|
from sessiontools import sessions, live, find, idle_seconds
|
|
10
10
|
from sessiontools import session_id, current, SESSION_ID_VARS
|
|
11
|
+
from sessiontools import read_operator, Operator # who asks, who is privileged
|
|
11
12
|
|
|
12
13
|
Every function speaks OUR words - busy, not busy, unknown - never a
|
|
13
|
-
harness's.
|
|
14
|
+
harness's. `Session.state` is one of three: `busy`, `idle with children`
|
|
15
|
+
(the turn is over, a background agent runs) or `idle`. The first driver is
|
|
16
|
+
`claude_code`; the day a harness changes a
|
|
14
17
|
status word, that driver changes and nothing above it does.
|
|
15
18
|
"""
|
|
16
19
|
|
|
@@ -19,8 +22,12 @@ from __future__ import annotations
|
|
|
19
22
|
from importlib.metadata import PackageNotFoundError, version
|
|
20
23
|
|
|
21
24
|
from sessiontools.claude_code import (
|
|
25
|
+
BUSY,
|
|
26
|
+
IDLE,
|
|
27
|
+
IDLE_WITH_CHILDREN,
|
|
22
28
|
SESSION_ID_VARS,
|
|
23
29
|
SIDECAR_DIR_ENV,
|
|
30
|
+
STATES,
|
|
24
31
|
Session,
|
|
25
32
|
current,
|
|
26
33
|
find,
|
|
@@ -30,6 +37,7 @@ from sessiontools.claude_code import (
|
|
|
30
37
|
sessions,
|
|
31
38
|
sidecar_dir,
|
|
32
39
|
)
|
|
40
|
+
from sessiontools.operator import Operator, read_operator
|
|
33
41
|
|
|
34
42
|
try:
|
|
35
43
|
__version__ = version("sessiontools")
|
|
@@ -37,14 +45,20 @@ except PackageNotFoundError: # a checkout that is not installed
|
|
|
37
45
|
__version__ = "0+unknown"
|
|
38
46
|
|
|
39
47
|
__all__ = [
|
|
48
|
+
"BUSY",
|
|
49
|
+
"IDLE",
|
|
50
|
+
"IDLE_WITH_CHILDREN",
|
|
40
51
|
"SESSION_ID_VARS",
|
|
41
52
|
"SIDECAR_DIR_ENV",
|
|
53
|
+
"STATES",
|
|
54
|
+
"Operator",
|
|
42
55
|
"Session",
|
|
43
56
|
"__version__",
|
|
44
57
|
"current",
|
|
45
58
|
"find",
|
|
46
59
|
"idle_seconds",
|
|
47
60
|
"live",
|
|
61
|
+
"read_operator",
|
|
48
62
|
"session_id",
|
|
49
63
|
"sessions",
|
|
50
64
|
"sidecar_dir",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""`session account`: which of the user's Claude accounts the host is on, and
|
|
2
|
+
the switch between them.
|
|
3
|
+
|
|
4
|
+
session account list | status | use NAME | add NAME | remove NAME
|
|
5
|
+
|
|
6
|
+
`main(argv)` is the group (`cli`). The pieces are each their own module:
|
|
7
|
+
the registry of names (`registry`), the Keychain seam (`keychain`), `use`
|
|
8
|
+
(`use`), `status` and `list` (`status`), `add`/`remove` and the argparse
|
|
9
|
+
group (`cli`), and the token-leak scan (`leakscan`). Nothing here prints,
|
|
10
|
+
logs or stores a token.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from sessiontools.account.cli import main
|
|
14
|
+
|
|
15
|
+
__all__ = ["main"]
|