sessiontools 0.3.3__tar.gz → 0.4.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.3 → sessiontools-0.4.0}/PKG-INFO +71 -45
- {sessiontools-0.3.3 → sessiontools-0.4.0}/README.md +70 -44
- {sessiontools-0.3.3 → sessiontools-0.4.0}/pyproject.toml +1 -1
- {sessiontools-0.3.3 → sessiontools-0.4.0}/pyproject.toml.orig +1 -1
- sessiontools-0.4.0/src/sessiontools/argv_flags.py +32 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/band.py +43 -21
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/cli.py +70 -15
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/clockline.py +12 -60
- sessiontools-0.4.0/src/sessiontools/commands/__init__.py +110 -0
- sessiontools-0.4.0/src/sessiontools/commands/cli.py +127 -0
- sessiontools-0.4.0/src/sessiontools/commands/shell.py +691 -0
- sessiontools-0.4.0/src/sessiontools/compact_point.py +400 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/completion.py +4 -0
- sessiontools-0.4.0/src/sessiontools/default_model_agent.py +363 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/default_model_cli.py +32 -13
- sessiontools-0.4.0/src/sessiontools/get.py +150 -0
- sessiontools-0.4.0/src/sessiontools/hidden_failure.py +610 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/ledger/transcript.py +7 -3
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/listing.py +7 -1
- sessiontools-0.4.0/src/sessiontools/md_lint.py +262 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/pane_state.py +9 -1
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/pane_state_agent.py +43 -9
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/park.py +51 -8
- sessiontools-0.4.0/src/sessiontools/past.py +158 -0
- sessiontools-0.4.0/src/sessiontools/respawn.py +645 -0
- sessiontools-0.4.0/src/sessiontools/sed_guard.py +294 -0
- sessiontools-0.4.0/src/sessiontools/service_file.py +214 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/settings.py +112 -12
- sessiontools-0.4.0/src/sessiontools/settle.py +357 -0
- sessiontools-0.4.0/src/sessiontools/settle_guard.py +181 -0
- sessiontools-0.4.0/src/sessiontools/settle_settings.py +542 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/sound/service.py +58 -13
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/__init__.py +167 -51
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/agentfile.py +26 -14
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/args.py +11 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/boot_identity.py +46 -92
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/claude_settings.py +56 -23
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/context.py +287 -35
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/default_seat.py +2 -45
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/environment.py +5 -3
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/errors.py +25 -1
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/identity.py +2 -117
- sessiontools-0.4.0/src/sessiontools/start/pane.py +276 -0
- sessiontools-0.4.0/src/sessiontools/start/placement.py +379 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/plan.py +251 -136
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/record.py +212 -19
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/run.py +140 -25
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/secrets.py +5 -3
- sessiontools-0.4.0/src/sessiontools/start/user_memory.py +245 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/vendor.py +32 -33
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/statusline/statusline.sh +6 -1
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/cli.py +65 -6
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/window.py +121 -16
- sessiontools-0.3.3/src/sessiontools/get.py +0 -91
- sessiontools-0.3.3/src/sessiontools/settle.py +0 -230
- sessiontools-0.3.3/src/sessiontools/start/placement.py +0 -272
- {sessiontools-0.3.3 → sessiontools-0.4.0}/LICENSE +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/cli.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/keychain.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/leakscan.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/limits.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/movehome.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/new.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/profile.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/registry.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/setuptoken.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/status.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/tokenfile.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/tokenstore.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/use.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/account/verify.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/busy.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/claude_code.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/boot.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/breakdown.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/hooks.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/nnls.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/render.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/slash_context.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/tools.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/context_parts/transcript.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/default_model.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/default_model_watch.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/identity_block.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/ledger/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/ledger/_tiktoken_child.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/ledger/count.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/ledger/render.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/migrate.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/operator.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/paths.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/procs.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/py.typed +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/reap.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/send.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/session_info.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/snapshot.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/sound/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/sound/engine.swift +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/sound/event.swift +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/agents.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/default_seat.md +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/holders.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/homefolder.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/policy.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/start/resume.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/statusline/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/statusline/sample.json +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/tmux.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/turn.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/verbs.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/__init__.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/auth.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/bind.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/passkey.js +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/passkey.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/proxy.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/rooms.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/server.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/settings_page.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/supervisor.py +0 -0
- {sessiontools-0.3.3 → sessiontools-0.4.0}/src/sessiontools/web/unixhttp.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sessiontools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
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>
|
|
@@ -32,7 +32,7 @@ uv tool install sessiontools
|
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
Python 3.11 to 3.14. Optional: [the Claude Code plugin][plugin] adds
|
|
35
|
-
the `session` skill and
|
|
35
|
+
the `session` skill and five hooks.
|
|
36
36
|
|
|
37
37
|
Shell completion, one line per shell ([shell completion][completion]).
|
|
38
38
|
For zsh, in `~/.zshrc` after compinit:
|
|
@@ -62,12 +62,18 @@ eval "$(session completion bash)"
|
|
|
62
62
|
- `session context --parts`: what filled it: boot, then growth by
|
|
63
63
|
category.
|
|
64
64
|
- `session ledger --short`: each file read and command run, by tokens.
|
|
65
|
+
- `session commands SEAT --since 7d --count`: the programs a seat's
|
|
66
|
+
sessions ran in a week, by how often.
|
|
67
|
+
- `session list --past SEAT`: every session recorded as SEAT on this
|
|
68
|
+
host, oldest first.
|
|
65
69
|
- `session account status`: which Claude account this Mac is on.
|
|
66
70
|
- `session account verify`: which account the API bills for this seat's
|
|
67
71
|
token, from one 1-token request.
|
|
68
72
|
- `session start --list-agents`: the agents it can start.
|
|
69
73
|
- `session reap`: seats idle past 1h, each CLOSE or KEEP, and why. A dry
|
|
70
74
|
run.
|
|
75
|
+
- `session respawn`: the plan to restart this seat in its pane with the
|
|
76
|
+
line it was started with. `--go` acts.
|
|
71
77
|
- `session default-model`: the model every new `claude` starts on, and
|
|
72
78
|
whether a pin keeps it there. Off until you set `model.default`.
|
|
73
79
|
- `session --help`: every verb.
|
|
@@ -151,30 +157,36 @@ it. Each line says what puts it there and what takes it away.
|
|
|
151
157
|
`log.jsonl`, the first time `session default-model enforce` changes
|
|
152
158
|
settings.json.
|
|
153
159
|
- `~/.sessionkit/tools/accounts/`: `session account new` and `use`.
|
|
160
|
+
- `~/.sessionkit/tools/services/`, beside `settings/`: one file per
|
|
161
|
+
service, for `sessionkit service list`. `pane-state.json`:
|
|
162
|
+
`session pane-state agent on|off`. `sound-engine.json`: `session
|
|
163
|
+
sound engine on|off`. `default-model.json`: `session default-model
|
|
164
|
+
agent on|off`. `web.json`: `session web declare`, which installs
|
|
165
|
+
nothing. `off` rewrites a file with `enabled: false` and keeps it.
|
|
154
166
|
- `~/.sessionkit/tools/state/sound/bin/`: `session sound engine on`
|
|
155
167
|
builds the sound engine there with `swiftc` (in
|
|
156
168
|
`~/.local/share/sessiontools/sound/bin/` while that old folder is
|
|
157
169
|
still there).
|
|
158
|
-
- `~/.sessionkit/tools/log/`: the services' logs
|
|
159
|
-
(Logs, below). An older release wrote them elsewhere,
|
|
160
|
-
files stay where they were.
|
|
170
|
+
- `~/.sessionkit/tools/log/`: the services' logs, `reap.log` and
|
|
171
|
+
`respawn.log` (Logs, below). An older release wrote them elsewhere,
|
|
172
|
+
and those files stay where they were.
|
|
161
173
|
- `SESSIONS_DIR`, `SESSION_STATE_DIR` and `SESSIONTOOLS_SOUND_HOME`
|
|
162
174
|
move these folders when set.
|
|
163
175
|
- **Services (launchd agents):** none until you turn one on. Each `on`
|
|
164
176
|
writes a plist in `~/Library/LaunchAgents/` and loads it, and it
|
|
165
177
|
starts again at every login. Each `off` unloads it and deletes the
|
|
166
|
-
plist.
|
|
167
|
-
under its old label: they unload
|
|
168
|
-
names one that is still there, and
|
|
169
|
-
changes nothing.
|
|
178
|
+
plist. For pane-state and the sound engine, `on` and `off` also
|
|
179
|
+
retire a job an older release set up under its old label: they unload
|
|
180
|
+
it and delete its plist. `status` names one that is still there, and
|
|
181
|
+
`--dry-run` lists the retire and changes nothing.
|
|
170
182
|
- `dev.sessionkit.tools.sound-engine`: `session sound engine on`.
|
|
171
183
|
`off --purge` also deletes the engine it built.
|
|
172
184
|
- `dev.sessionkit.tools.pane-state`: `session pane-state agent on`.
|
|
173
185
|
It sets `@session_state` and `@session_state_why` on each seat's
|
|
174
186
|
tmux pane.
|
|
175
|
-
- `dev.sessionkit.tools.default-model`:
|
|
176
|
-
|
|
177
|
-
|
|
187
|
+
- `dev.sessionkit.tools.default-model`: `session default-model agent
|
|
188
|
+
on`. Opt-in: nothing turns it on for you. `session default-model
|
|
189
|
+
unit launchd` prints the same plist for a hand install
|
|
178
190
|
([the default model][default-model]).
|
|
179
191
|
- **Plugin and hooks, optional:** `claude plugin marketplace add` and
|
|
180
192
|
`claude plugin install` ([the Claude Code plugin][plugin]). Claude
|
|
@@ -182,9 +194,10 @@ it. Each line says what puts it there and what takes it away.
|
|
|
182
194
|
(`extraKnownMarketplaces`, `enabledPlugins`), lists them in
|
|
183
195
|
`~/.claude/plugins/`, and keeps a copy in
|
|
184
196
|
`~/.claude/plugins/cache/sessiontools/`. The plugin brings the
|
|
185
|
-
`session` skill and
|
|
186
|
-
PreToolUse, PostToolBatch (three), Stop,
|
|
187
|
-
SessionEnd.
|
|
197
|
+
`session` skill and twelve hook entries: SessionStart (three),
|
|
198
|
+
PreToolUse (two), PostToolBatch (three), PreCompact, Stop,
|
|
199
|
+
UserPromptSubmit and SessionEnd. Most are silent unless set; the sed
|
|
200
|
+
guard is on, and refuses only `sed -i ''` against GNU sed.
|
|
188
201
|
Uninstalling the plugin takes it out of the settings and leaves the
|
|
189
202
|
cached copy.
|
|
190
203
|
- **Settings:** the install writes none, and none are needed.
|
|
@@ -257,6 +270,7 @@ packages keep their files in it too.
|
|
|
257
270
|
- [The `session list` cache][cache]: one computation, many readers
|
|
258
271
|
- [Operator and privileged seats][operator]: who seats ask
|
|
259
272
|
- [Closing idle seats][reap]: `session reap`, a dry run by default
|
|
273
|
+
- [Restarting a seat][respawn]: `session respawn`, a plan unless `--go`
|
|
260
274
|
- [Where tools keeps its state][state-paths]: each folder, old and new,
|
|
261
275
|
the rule, and `session path`, the verb peers ask
|
|
262
276
|
- [Moving tools' state][state-migrate]: `session path migrate`, one host
|
|
@@ -266,7 +280,13 @@ packages keep their files in it too.
|
|
|
266
280
|
- [The Claude Code plugin][plugin]: the skill and the hooks
|
|
267
281
|
- [The settle alert][settle]: one line past a context threshold
|
|
268
282
|
- [The clock line][clock]: the time and the context on every tool batch
|
|
283
|
+
- [The Markdown lint][md-lint]: wide table lines and `shape`, named
|
|
284
|
+
after a `.md` write
|
|
285
|
+
- [The hidden-failure note][hidden-failure]: one line when an agent's test
|
|
286
|
+
run piped into `head` or `tail` exits 0 with failures shown
|
|
269
287
|
- [The busy sound][busy]: a sound while a tool batch runs long
|
|
288
|
+
- [The sed guard][sed-guard]: refuses `sed -i ''` where sed is GNU, and
|
|
289
|
+
names the GNU form
|
|
270
290
|
- [The session-info hooks][session-info]: the short session id as the
|
|
271
291
|
session title, and the session's facts in context, both off by default
|
|
272
292
|
- [The identity block][identity]: who a launched session is, in its
|
|
@@ -317,8 +337,8 @@ be set, and where each one lives ([configuration][configuration]):
|
|
|
317
337
|
- **Upgrade every copy of sessiontools on a host together,** other
|
|
318
338
|
packages' copies included: an older copy writes the old `state`
|
|
319
339
|
folder, and `session path --json` shows `stranded` when one lags.
|
|
320
|
-
- **Environment variables:**
|
|
321
|
-
|
|
340
|
+
- **Environment variables:** `SESSION_SETTLE_AT`, which `session start`
|
|
341
|
+
copies once into the session layer, the hooks' `SESSIONTOOLS_HOOK_*`
|
|
322
342
|
switches (`SESSIONTOOLS_HOOK_CLOCK=on` switches the clock line on), and
|
|
323
343
|
the paths it reads, such as `SESSIONS_DIR` and `SESSION_STATE_DIR`.
|
|
324
344
|
The configuration page lists each one with its default, under the part
|
|
@@ -340,6 +360,8 @@ be set, and where each one lives ([configuration][configuration]):
|
|
|
340
360
|
- **Busy detection:** `~/.sessionkit/tools/log/busy.log`, one line each
|
|
341
361
|
time voice could not be asked where its mouth is, naming why and the
|
|
342
362
|
folder used instead ([the busy sound][busy]).
|
|
363
|
+
- **`session respawn --go`:** `~/.sessionkit/tools/log/respawn.log`, one line
|
|
364
|
+
for each pane it respawned, written before the kill.
|
|
343
365
|
- **Each session's settings at birth:**
|
|
344
366
|
`~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
|
|
345
367
|
start` read into that session's settings: each environment variable
|
|
@@ -364,31 +386,35 @@ Follow one as it grows with `tail -F`, for example
|
|
|
364
386
|
holder. A session you know is running that is not listed is one
|
|
365
387
|
sessiontools cannot see.
|
|
366
388
|
|
|
367
|
-
[verbs]: docs/session.md
|
|
368
|
-
[default-seat]: docs/session.md#the-default-seat
|
|
369
|
-
[start]: docs/session-start-launcher.md
|
|
370
|
-
[credentials]: docs/session-start-launcher.md#credentials-are-never-handed-down
|
|
371
|
-
[account]: docs/account.md
|
|
372
|
-
[cache]: docs/list-snapshot-cache.md
|
|
373
|
-
[operator]: docs/operator-privileged-seats.md
|
|
374
|
-
[reap]: docs/session-reap.md
|
|
375
|
-
[
|
|
376
|
-
[
|
|
377
|
-
[state-
|
|
378
|
-
[
|
|
379
|
-
[
|
|
380
|
-
[
|
|
381
|
-
[
|
|
382
|
-
[
|
|
383
|
-
[
|
|
384
|
-
[
|
|
385
|
-
[
|
|
386
|
-
[
|
|
387
|
-
[
|
|
388
|
-
[
|
|
389
|
-
[
|
|
390
|
-
[
|
|
391
|
-
[
|
|
392
|
-
[
|
|
393
|
-
[
|
|
394
|
-
[
|
|
389
|
+
[verbs]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session.md
|
|
390
|
+
[default-seat]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session.md#the-default-seat
|
|
391
|
+
[start]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-start-launcher.md
|
|
392
|
+
[credentials]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-start-launcher.md#credentials-are-never-handed-down
|
|
393
|
+
[account]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/account.md
|
|
394
|
+
[cache]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/list-snapshot-cache.md
|
|
395
|
+
[operator]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/operator-privileged-seats.md
|
|
396
|
+
[reap]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-reap.md
|
|
397
|
+
[respawn]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-respawn.md
|
|
398
|
+
[completion]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/shell-completion.md
|
|
399
|
+
[state-paths]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/tools-state-paths.md
|
|
400
|
+
[state-migrate]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/tools-state-migrate.md
|
|
401
|
+
[plugin]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/claude-code-plugin.md
|
|
402
|
+
[settle]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/settle-alert-hook.md
|
|
403
|
+
[clock]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/clock-line-hook.md
|
|
404
|
+
[md-lint]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/md-lint-hook.md
|
|
405
|
+
[hidden-failure]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/hidden-failure-hook.md
|
|
406
|
+
[busy]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/busy-sound-hook.md
|
|
407
|
+
[sed-guard]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/sed-guard-hook.md
|
|
408
|
+
[session-info]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-info-hook.md
|
|
409
|
+
[identity]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/identity-block.md
|
|
410
|
+
[engine]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/sound-engine-agent.md
|
|
411
|
+
[status-line]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/status-line-script.md
|
|
412
|
+
[pane-state]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/pane-state-signal.md
|
|
413
|
+
[default-model]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/default-model.md
|
|
414
|
+
[library]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/python-library-api.md
|
|
415
|
+
[building]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/building-and-testing.md
|
|
416
|
+
[dependencies]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/dependencies.md
|
|
417
|
+
[changelog]: https://github.com/sessionkit/sessiontools/blob/HEAD/CHANGELOG.md
|
|
418
|
+
[license]: https://github.com/sessionkit/sessiontools/blob/HEAD/LICENSE
|
|
419
|
+
[configuration]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/configuration.md
|
|
420
|
+
[settings]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/settings.md
|
|
@@ -14,7 +14,7 @@ uv tool install sessiontools
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Python 3.11 to 3.14. Optional: [the Claude Code plugin][plugin] adds
|
|
17
|
-
the `session` skill and
|
|
17
|
+
the `session` skill and five hooks.
|
|
18
18
|
|
|
19
19
|
Shell completion, one line per shell ([shell completion][completion]).
|
|
20
20
|
For zsh, in `~/.zshrc` after compinit:
|
|
@@ -44,12 +44,18 @@ eval "$(session completion bash)"
|
|
|
44
44
|
- `session context --parts`: what filled it: boot, then growth by
|
|
45
45
|
category.
|
|
46
46
|
- `session ledger --short`: each file read and command run, by tokens.
|
|
47
|
+
- `session commands SEAT --since 7d --count`: the programs a seat's
|
|
48
|
+
sessions ran in a week, by how often.
|
|
49
|
+
- `session list --past SEAT`: every session recorded as SEAT on this
|
|
50
|
+
host, oldest first.
|
|
47
51
|
- `session account status`: which Claude account this Mac is on.
|
|
48
52
|
- `session account verify`: which account the API bills for this seat's
|
|
49
53
|
token, from one 1-token request.
|
|
50
54
|
- `session start --list-agents`: the agents it can start.
|
|
51
55
|
- `session reap`: seats idle past 1h, each CLOSE or KEEP, and why. A dry
|
|
52
56
|
run.
|
|
57
|
+
- `session respawn`: the plan to restart this seat in its pane with the
|
|
58
|
+
line it was started with. `--go` acts.
|
|
53
59
|
- `session default-model`: the model every new `claude` starts on, and
|
|
54
60
|
whether a pin keeps it there. Off until you set `model.default`.
|
|
55
61
|
- `session --help`: every verb.
|
|
@@ -133,30 +139,36 @@ it. Each line says what puts it there and what takes it away.
|
|
|
133
139
|
`log.jsonl`, the first time `session default-model enforce` changes
|
|
134
140
|
settings.json.
|
|
135
141
|
- `~/.sessionkit/tools/accounts/`: `session account new` and `use`.
|
|
142
|
+
- `~/.sessionkit/tools/services/`, beside `settings/`: one file per
|
|
143
|
+
service, for `sessionkit service list`. `pane-state.json`:
|
|
144
|
+
`session pane-state agent on|off`. `sound-engine.json`: `session
|
|
145
|
+
sound engine on|off`. `default-model.json`: `session default-model
|
|
146
|
+
agent on|off`. `web.json`: `session web declare`, which installs
|
|
147
|
+
nothing. `off` rewrites a file with `enabled: false` and keeps it.
|
|
136
148
|
- `~/.sessionkit/tools/state/sound/bin/`: `session sound engine on`
|
|
137
149
|
builds the sound engine there with `swiftc` (in
|
|
138
150
|
`~/.local/share/sessiontools/sound/bin/` while that old folder is
|
|
139
151
|
still there).
|
|
140
|
-
- `~/.sessionkit/tools/log/`: the services' logs
|
|
141
|
-
(Logs, below). An older release wrote them elsewhere,
|
|
142
|
-
files stay where they were.
|
|
152
|
+
- `~/.sessionkit/tools/log/`: the services' logs, `reap.log` and
|
|
153
|
+
`respawn.log` (Logs, below). An older release wrote them elsewhere,
|
|
154
|
+
and those files stay where they were.
|
|
143
155
|
- `SESSIONS_DIR`, `SESSION_STATE_DIR` and `SESSIONTOOLS_SOUND_HOME`
|
|
144
156
|
move these folders when set.
|
|
145
157
|
- **Services (launchd agents):** none until you turn one on. Each `on`
|
|
146
158
|
writes a plist in `~/Library/LaunchAgents/` and loads it, and it
|
|
147
159
|
starts again at every login. Each `off` unloads it and deletes the
|
|
148
|
-
plist.
|
|
149
|
-
under its old label: they unload
|
|
150
|
-
names one that is still there, and
|
|
151
|
-
changes nothing.
|
|
160
|
+
plist. For pane-state and the sound engine, `on` and `off` also
|
|
161
|
+
retire a job an older release set up under its old label: they unload
|
|
162
|
+
it and delete its plist. `status` names one that is still there, and
|
|
163
|
+
`--dry-run` lists the retire and changes nothing.
|
|
152
164
|
- `dev.sessionkit.tools.sound-engine`: `session sound engine on`.
|
|
153
165
|
`off --purge` also deletes the engine it built.
|
|
154
166
|
- `dev.sessionkit.tools.pane-state`: `session pane-state agent on`.
|
|
155
167
|
It sets `@session_state` and `@session_state_why` on each seat's
|
|
156
168
|
tmux pane.
|
|
157
|
-
- `dev.sessionkit.tools.default-model`:
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
- `dev.sessionkit.tools.default-model`: `session default-model agent
|
|
170
|
+
on`. Opt-in: nothing turns it on for you. `session default-model
|
|
171
|
+
unit launchd` prints the same plist for a hand install
|
|
160
172
|
([the default model][default-model]).
|
|
161
173
|
- **Plugin and hooks, optional:** `claude plugin marketplace add` and
|
|
162
174
|
`claude plugin install` ([the Claude Code plugin][plugin]). Claude
|
|
@@ -164,9 +176,10 @@ it. Each line says what puts it there and what takes it away.
|
|
|
164
176
|
(`extraKnownMarketplaces`, `enabledPlugins`), lists them in
|
|
165
177
|
`~/.claude/plugins/`, and keeps a copy in
|
|
166
178
|
`~/.claude/plugins/cache/sessiontools/`. The plugin brings the
|
|
167
|
-
`session` skill and
|
|
168
|
-
PreToolUse, PostToolBatch (three), Stop,
|
|
169
|
-
SessionEnd.
|
|
179
|
+
`session` skill and twelve hook entries: SessionStart (three),
|
|
180
|
+
PreToolUse (two), PostToolBatch (three), PreCompact, Stop,
|
|
181
|
+
UserPromptSubmit and SessionEnd. Most are silent unless set; the sed
|
|
182
|
+
guard is on, and refuses only `sed -i ''` against GNU sed.
|
|
170
183
|
Uninstalling the plugin takes it out of the settings and leaves the
|
|
171
184
|
cached copy.
|
|
172
185
|
- **Settings:** the install writes none, and none are needed.
|
|
@@ -239,6 +252,7 @@ packages keep their files in it too.
|
|
|
239
252
|
- [The `session list` cache][cache]: one computation, many readers
|
|
240
253
|
- [Operator and privileged seats][operator]: who seats ask
|
|
241
254
|
- [Closing idle seats][reap]: `session reap`, a dry run by default
|
|
255
|
+
- [Restarting a seat][respawn]: `session respawn`, a plan unless `--go`
|
|
242
256
|
- [Where tools keeps its state][state-paths]: each folder, old and new,
|
|
243
257
|
the rule, and `session path`, the verb peers ask
|
|
244
258
|
- [Moving tools' state][state-migrate]: `session path migrate`, one host
|
|
@@ -248,7 +262,13 @@ packages keep their files in it too.
|
|
|
248
262
|
- [The Claude Code plugin][plugin]: the skill and the hooks
|
|
249
263
|
- [The settle alert][settle]: one line past a context threshold
|
|
250
264
|
- [The clock line][clock]: the time and the context on every tool batch
|
|
265
|
+
- [The Markdown lint][md-lint]: wide table lines and `shape`, named
|
|
266
|
+
after a `.md` write
|
|
267
|
+
- [The hidden-failure note][hidden-failure]: one line when an agent's test
|
|
268
|
+
run piped into `head` or `tail` exits 0 with failures shown
|
|
251
269
|
- [The busy sound][busy]: a sound while a tool batch runs long
|
|
270
|
+
- [The sed guard][sed-guard]: refuses `sed -i ''` where sed is GNU, and
|
|
271
|
+
names the GNU form
|
|
252
272
|
- [The session-info hooks][session-info]: the short session id as the
|
|
253
273
|
session title, and the session's facts in context, both off by default
|
|
254
274
|
- [The identity block][identity]: who a launched session is, in its
|
|
@@ -299,8 +319,8 @@ be set, and where each one lives ([configuration][configuration]):
|
|
|
299
319
|
- **Upgrade every copy of sessiontools on a host together,** other
|
|
300
320
|
packages' copies included: an older copy writes the old `state`
|
|
301
321
|
folder, and `session path --json` shows `stranded` when one lags.
|
|
302
|
-
- **Environment variables:**
|
|
303
|
-
|
|
322
|
+
- **Environment variables:** `SESSION_SETTLE_AT`, which `session start`
|
|
323
|
+
copies once into the session layer, the hooks' `SESSIONTOOLS_HOOK_*`
|
|
304
324
|
switches (`SESSIONTOOLS_HOOK_CLOCK=on` switches the clock line on), and
|
|
305
325
|
the paths it reads, such as `SESSIONS_DIR` and `SESSION_STATE_DIR`.
|
|
306
326
|
The configuration page lists each one with its default, under the part
|
|
@@ -322,6 +342,8 @@ be set, and where each one lives ([configuration][configuration]):
|
|
|
322
342
|
- **Busy detection:** `~/.sessionkit/tools/log/busy.log`, one line each
|
|
323
343
|
time voice could not be asked where its mouth is, naming why and the
|
|
324
344
|
folder used instead ([the busy sound][busy]).
|
|
345
|
+
- **`session respawn --go`:** `~/.sessionkit/tools/log/respawn.log`, one line
|
|
346
|
+
for each pane it respawned, written before the kill.
|
|
325
347
|
- **Each session's settings at birth:**
|
|
326
348
|
`~/.session/sessions/<session-id>/log/settings.jsonl`, what `session
|
|
327
349
|
start` read into that session's settings: each environment variable
|
|
@@ -346,31 +368,35 @@ Follow one as it grows with `tail -F`, for example
|
|
|
346
368
|
holder. A session you know is running that is not listed is one
|
|
347
369
|
sessiontools cannot see.
|
|
348
370
|
|
|
349
|
-
[verbs]: docs/session.md
|
|
350
|
-
[default-seat]: docs/session.md#the-default-seat
|
|
351
|
-
[start]: docs/session-start-launcher.md
|
|
352
|
-
[credentials]: docs/session-start-launcher.md#credentials-are-never-handed-down
|
|
353
|
-
[account]: docs/account.md
|
|
354
|
-
[cache]: docs/list-snapshot-cache.md
|
|
355
|
-
[operator]: docs/operator-privileged-seats.md
|
|
356
|
-
[reap]: docs/session-reap.md
|
|
357
|
-
[
|
|
358
|
-
[
|
|
359
|
-
[state-
|
|
360
|
-
[
|
|
361
|
-
[
|
|
362
|
-
[
|
|
363
|
-
[
|
|
364
|
-
[
|
|
365
|
-
[
|
|
366
|
-
[
|
|
367
|
-
[
|
|
368
|
-
[
|
|
369
|
-
[
|
|
370
|
-
[
|
|
371
|
-
[
|
|
372
|
-
[
|
|
373
|
-
[
|
|
374
|
-
[
|
|
375
|
-
[
|
|
376
|
-
[
|
|
371
|
+
[verbs]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session.md
|
|
372
|
+
[default-seat]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session.md#the-default-seat
|
|
373
|
+
[start]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-start-launcher.md
|
|
374
|
+
[credentials]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-start-launcher.md#credentials-are-never-handed-down
|
|
375
|
+
[account]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/account.md
|
|
376
|
+
[cache]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/list-snapshot-cache.md
|
|
377
|
+
[operator]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/operator-privileged-seats.md
|
|
378
|
+
[reap]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-reap.md
|
|
379
|
+
[respawn]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-respawn.md
|
|
380
|
+
[completion]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/shell-completion.md
|
|
381
|
+
[state-paths]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/tools-state-paths.md
|
|
382
|
+
[state-migrate]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/tools-state-migrate.md
|
|
383
|
+
[plugin]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/claude-code-plugin.md
|
|
384
|
+
[settle]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/settle-alert-hook.md
|
|
385
|
+
[clock]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/clock-line-hook.md
|
|
386
|
+
[md-lint]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/md-lint-hook.md
|
|
387
|
+
[hidden-failure]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/hidden-failure-hook.md
|
|
388
|
+
[busy]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/busy-sound-hook.md
|
|
389
|
+
[sed-guard]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/sed-guard-hook.md
|
|
390
|
+
[session-info]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/session-info-hook.md
|
|
391
|
+
[identity]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/identity-block.md
|
|
392
|
+
[engine]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/sound-engine-agent.md
|
|
393
|
+
[status-line]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/status-line-script.md
|
|
394
|
+
[pane-state]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/pane-state-signal.md
|
|
395
|
+
[default-model]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/default-model.md
|
|
396
|
+
[library]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/python-library-api.md
|
|
397
|
+
[building]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/building-and-testing.md
|
|
398
|
+
[dependencies]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/dependencies.md
|
|
399
|
+
[changelog]: https://github.com/sessionkit/sessiontools/blob/HEAD/CHANGELOG.md
|
|
400
|
+
[license]: https://github.com/sessionkit/sessiontools/blob/HEAD/LICENSE
|
|
401
|
+
[configuration]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/configuration.md
|
|
402
|
+
[settings]: https://github.com/sessionkit/sessiontools/blob/HEAD/docs/settings.md
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Reading a vendor's flags back off an argv, by the vendor's own rule.
|
|
2
|
+
|
|
3
|
+
claude parses a repeated scalar flag by keeping the LAST one, in either
|
|
4
|
+
spelling: `--flag value` or `--flag=value`. Two readers need that rule:
|
|
5
|
+
the settle hook (`compact_point`, reading a recorded launch line) and
|
|
6
|
+
`session start` (`start.user_memory`, reading the argv it is about to
|
|
7
|
+
render). One definition, here, so the two never disagree.
|
|
8
|
+
|
|
9
|
+
Standard library only, and nothing imported at all: the settle hook
|
|
10
|
+
imports `compact_point`, and so this, on every batch, maybe under a bare
|
|
11
|
+
python3 (it must not pull in `sessiontools.start` or PyYAML).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def last_value(argv: list[str], flag: str) -> str | None:
|
|
18
|
+
"""The value of the LAST `FLAG value` or `FLAG=value` in ARGV, or None.
|
|
19
|
+
|
|
20
|
+
The `=` is part of the prefix, so a longer flag that merely starts with
|
|
21
|
+
FLAG's spelling (`--settings-file` for `--settings`) is not FLAG. A
|
|
22
|
+
trailing FLAG with no value after it sets nothing."""
|
|
23
|
+
found = None
|
|
24
|
+
for index, token in enumerate(argv):
|
|
25
|
+
if token == flag and index + 1 < len(argv):
|
|
26
|
+
found = argv[index + 1]
|
|
27
|
+
elif token.startswith(flag + "="):
|
|
28
|
+
found = token[len(flag) + 1:]
|
|
29
|
+
return found
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
__all__ = ["last_value"]
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"""`band`: how close a window is to its seat's settle threshold, as data
|
|
2
2
|
("thresholds belong to session, the sidebar only paints").
|
|
3
3
|
|
|
4
|
-
- OVER: at or past the settle threshold
|
|
5
|
-
read
|
|
4
|
+
- OVER: at or past the settle threshold: the soft line's mark,
|
|
5
|
+
`settle.soft.at`, read through the settings cascade by
|
|
6
|
+
`settle_settings.read` (read-only: no OFF stamp is written here), so
|
|
7
|
+
`session context` and the sidebar agree with the alert. No soft line
|
|
8
|
+
on in any layer: no threshold.
|
|
6
9
|
- NEAR: within NEAR percent under it: `used >= threshold * (1 - NEAR/100)`.
|
|
7
10
|
- OK: below that.
|
|
8
11
|
- None (JSON null): no threshold is set, or `used` is unknown.
|
|
@@ -10,15 +13,16 @@
|
|
|
10
13
|
THE NEAR CUT IS A SETTING, read through the settings cascade
|
|
11
14
|
(`sessiontools.settings`: template, host, agent, seat and session layers),
|
|
12
15
|
under ONE key, NEAR_KEY, of the `session` tool. It is never read from the
|
|
13
|
-
environment: the environment is not a layer
|
|
14
|
-
`SESSION_SETTLE_AT`
|
|
16
|
+
environment: the environment is not a layer, for the threshold either
|
|
17
|
+
(`SESSION_SETTLE_AT` reaches it only as `session start`'s birth copy into
|
|
18
|
+
the session layer, `settle.soft.at`). Unset,
|
|
15
19
|
unreadable or not a number from 0 to 100 is the default, DEFAULT_NEAR_PCT
|
|
16
20
|
(any other default is a one-line change to it).
|
|
17
21
|
|
|
18
22
|
<sessions>/<sid>/settings/session.json {"context": {"near_pct": 10}}
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
The `session` schema `session start` installs (`settle_settings`) names
|
|
25
|
+
the settle keys only, not this one: the cascade reads a key without one.
|
|
22
26
|
|
|
23
27
|
It sits at the top level, not in `context_parts`: importing any
|
|
24
28
|
`context_parts` submodule runs that package's `__init__`, which imports the
|
|
@@ -64,16 +68,25 @@ def _lookup(merged: Mapping, dotted: str) -> Any:
|
|
|
64
68
|
return node
|
|
65
69
|
|
|
66
70
|
|
|
71
|
+
def _sid(sid: str | None, env: Mapping[str, str] | None) -> str | None:
|
|
72
|
+
"""SID as the full id `settings.resolve_sid` makes of a short prefix,
|
|
73
|
+
as `session settings` does: `session_dir` is a literal join, and a
|
|
74
|
+
prefix would otherwise read no session, agent or seat layer and fall
|
|
75
|
+
back without a word. None stays None (template and host layers only).
|
|
76
|
+
An AMBIGUOUS prefix is refused there (SettingsError) and raised here."""
|
|
77
|
+
from sessiontools import settings
|
|
78
|
+
if not sid:
|
|
79
|
+
return None
|
|
80
|
+
sid, _note = settings.resolve_sid(sid, env)
|
|
81
|
+
return sid
|
|
82
|
+
|
|
83
|
+
|
|
67
84
|
def setting(sid: str | None = None, env: Mapping[str, str] | None = None) -> Any:
|
|
68
85
|
"""NEAR_KEY's raw merged value for session SID (None: template and host
|
|
69
86
|
layers only), or None when no layer sets it or a layer cannot be read.
|
|
70
87
|
|
|
71
|
-
SID may be a short prefix
|
|
72
|
-
|
|
73
|
-
and a prefix would otherwise read no session, agent or seat layer and
|
|
74
|
-
fall back to the default without a word. An AMBIGUOUS prefix is refused
|
|
75
|
-
there (SettingsError) and reads as None here, so the default: never a
|
|
76
|
-
guess at which session was meant.
|
|
88
|
+
SID may be a short prefix (`_sid`). An AMBIGUOUS prefix reads as None
|
|
89
|
+
here, so the default: never a guess at which session was meant.
|
|
77
90
|
|
|
78
91
|
`sources` + `merge`, as `busy.values` reads `sounds`: `resolve` would
|
|
79
92
|
also check an installed schema, which imports jsonschema. The agent
|
|
@@ -82,8 +95,8 @@ def setting(sid: str | None = None, env: Mapping[str, str] | None = None) -> Any
|
|
|
82
95
|
from sessiontools import settings
|
|
83
96
|
try:
|
|
84
97
|
agent = seat = None
|
|
98
|
+
sid = _sid(sid, env)
|
|
85
99
|
if sid:
|
|
86
|
-
sid, _note = settings.resolve_sid(sid, env)
|
|
87
100
|
agent, seat = settings.identity(sid, env)
|
|
88
101
|
try:
|
|
89
102
|
srcs = settings.sources(NEAR_TOOL, sid, agent, seat, env)
|
|
@@ -115,16 +128,25 @@ def band(used: float | None, threshold: float | None,
|
|
|
115
128
|
return OK
|
|
116
129
|
|
|
117
130
|
|
|
118
|
-
def threshold(env: Mapping[str, str] | None = None) -> int | None:
|
|
119
|
-
"""
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
def threshold(sid: str | None = None, env: Mapping[str, str] | None = None) -> int | None:
|
|
132
|
+
"""Session SID's settle threshold in tokens: `settle.soft.at`, as the
|
|
133
|
+
alert reads it (`settle_settings.read`, every layer, live), or None
|
|
134
|
+
when no layer turns the soft line on, a layer cannot be read, or SID
|
|
135
|
+
is an ambiguous prefix (never a guess). SID may be a short prefix
|
|
136
|
+
(`_sid`); None reads the template and host layers only. Read-only:
|
|
137
|
+
`read`, not `resolve`, so the OFF stamp is the hook's alone."""
|
|
138
|
+
from sessiontools import settings, settle_settings
|
|
139
|
+
try:
|
|
140
|
+
sid = _sid(sid, env)
|
|
141
|
+
except (settings.SettingsError, OSError, ValueError):
|
|
142
|
+
return None
|
|
143
|
+
found = settle_settings.read(sid, env)
|
|
144
|
+
return None if found is None or found.soft is None else found.soft.at
|
|
124
145
|
|
|
125
146
|
|
|
126
147
|
def band_for(used: float | None, sid: str | None = None,
|
|
127
148
|
env: Mapping[str, str] | None = None) -> str | None:
|
|
128
149
|
"""The band of USED tokens for session SID (a full id or a unique
|
|
129
|
-
prefix):
|
|
130
|
-
|
|
150
|
+
prefix): the soft line's mark and the near cut, both from the settings
|
|
151
|
+
cascade."""
|
|
152
|
+
return band(used, threshold(sid, env), near_pct(sid, env))
|