sessionview 0.3.1__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.
- {sessionview-0.3.1 → sessionview-0.3.2}/PKG-INFO +56 -21
- {sessionview-0.3.1 → sessionview-0.3.2}/README.md +55 -20
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview +8 -5
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-autostart +6 -1
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-frame +18 -4
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-install +4 -2
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-messages +8 -3
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-session +93 -33
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/tmux-sidebar +286 -54
- sessionview-0.3.2/changelog.d/README.md +102 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/config/README.md +12 -3
- {sessionview-0.3.1 → sessionview-0.3.2}/config/config.json +6 -2
- {sessionview-0.3.1 → sessionview-0.3.2}/docs/configuration.md +18 -4
- sessionview-0.3.2/docs/decisions/state-and-log-home.md +557 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/docs/dependencies.md +5 -5
- {sessionview-0.3.1 → sessionview-0.3.2}/docs/sessionview.md +16 -7
- {sessionview-0.3.1 → sessionview-0.3.2}/docs/settings.md +4 -1
- sessionview-0.3.2/lib/landing.sh +67 -0
- sessionview-0.3.2/lib/state.sh +99 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/macos/SessionView.applescript +31 -5
- {sessionview-0.3.1 → sessionview-0.3.2}/pyproject.toml +1 -1
- {sessionview-0.3.1 → sessionview-0.3.2}/src/sessionview/__init__.py +1 -1
- sessionview-0.3.1/lib/state.sh +0 -13
- {sessionview-0.3.1 → sessionview-0.3.2}/.gitignore +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/LICENSE +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-app-install +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-config +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-from +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-newtab +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-send +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-sidebar-toggle +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-terminal +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/sessionview-usermail +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/bin/tmux-send-agent +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/config/keys.md +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/config/neomuttrc +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/lib/client.sh +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/lib/python.sh +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/lib/sessionview-config-screen +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/macos/dreamcatcher.icns +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/plugins/session/plugin.toml +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/plugins/session/start-agent +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/plugins/taskmaster/plugin.toml +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/plugins/taskmaster/tasks-tab +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/plugins/voicemode/plugin.toml +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/plugins/voicemode/speak +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/skills/tmux/SKILL.md +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/skills/tmux/scripts/tmux-peek +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/skills/tmux/scripts/tmux-show +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/skills/tmux/scripts/tmux-type +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/skills/tmux/scripts/tmux-where +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/tmux/agent-menu.conf +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/tmux/frame.conf +0 -0
- {sessionview-0.3.1 → sessionview-0.3.2}/tmux/tabs-top.conf +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sessionview
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: A sidebar for tmux: your projects (sessions) and your agents, here and on remote hosts.
|
|
5
5
|
Project-URL: Homepage, https://github.com/sessionkit/sessionview
|
|
6
6
|
Project-URL: Repository, https://github.com/sessionkit/sessionview
|
|
@@ -26,8 +26,11 @@ Install from PyPI: `uv tool install sessionview` (see [Install](#install)).
|
|
|
26
26
|
|
|
27
27
|
sessionview
|
|
28
28
|
|
|
29
|
-
In this terminal, that puts the sidebar on the left and
|
|
30
|
-
|
|
29
|
+
In this terminal, that puts the sidebar on the left and a tmux session
|
|
30
|
+
on the right; a private outer tmux holds the two panes. The session is
|
|
31
|
+
one tmux already has: your default assistant's, else the one you last
|
|
32
|
+
attached, else the newest. Only when tmux has no session at all does
|
|
33
|
+
sessionview make one, named `main`.
|
|
31
34
|
`sessionview NAME` attaches the session NAME instead, which must exist.
|
|
32
35
|
In any tmux client, `prefix H` opens the same sidebar as a popup.
|
|
33
36
|
Every verb, its form and an example: [the sessionview command](docs/sessionview.md).
|
|
@@ -92,8 +95,12 @@ agents, or the menu): the names `session start` knows, pinned ones first.
|
|
|
92
95
|
not start. An agent already running is never started twice.
|
|
93
96
|
- *Agents have a home* — an agent's own file says where it wakes
|
|
94
97
|
(`start: directory:`); a project's menu starts it in the project.
|
|
95
|
-
- *Consent on first open* —
|
|
96
|
-
|
|
98
|
+
- *Consent on first open* — the first time it opens, sessionview asks
|
|
99
|
+
which agent to start whenever it opens, and remembers the answer. It
|
|
100
|
+
says *sessionview can start an agent for you each time it opens*, lists
|
|
101
|
+
your agents by number and asks `Which? (number, name, or "n")`. When it cannot get the
|
|
102
|
+
list it asks `Which agent? (a name, or "no" to never ask again)`. `n` or
|
|
103
|
+
`no` means never; `autostart_agent` in Settings changes it later.
|
|
97
104
|
|
|
98
105
|
**Settings** — every setting, its default, its note and where its value
|
|
99
106
|
comes from, in a small screen (project menu → Settings); the rows come
|
|
@@ -135,7 +142,8 @@ hand. Blink Shell on iPad is wanted and not yet connecting.
|
|
|
135
142
|
claude-code: short, safe driving skills with tools
|
|
136
143
|
|
|
137
144
|
Paths resolve from the checkout (`SESSIONVIEW_ROOT`); state lives in
|
|
138
|
-
`~/.
|
|
145
|
+
`~/.sessionkit/view/state` (`SESSIONVIEW_STATE`) and the log in
|
|
146
|
+
`~/.sessionkit/view/log` (`SESSIONVIEW_LOG`). Its direct dependencies:
|
|
139
147
|
[dependencies](docs/dependencies.md).
|
|
140
148
|
|
|
141
149
|
## Install
|
|
@@ -235,14 +243,13 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
235
243
|
sessionview` drops this package's entries, and `uv cache prune` drops
|
|
236
244
|
the ones nothing uses.
|
|
237
245
|
- **Folders, each made by a verb you run:**
|
|
238
|
-
- `~/.
|
|
239
|
-
`sessionview` opens (or `sessionview session` or
|
|
240
|
-
messages` runs). `SESSIONVIEW_STATE`
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
- `~/.sessionkit/view/state/`: the state folder, mode 0700, made the
|
|
247
|
+
first time `sessionview` opens (or `sessionview session` or
|
|
248
|
+
`sessionview messages` runs). `SESSIONVIEW_STATE` names another
|
|
249
|
+
folder instead. Each file sessionview makes in it is private (mode
|
|
250
|
+
0600). In it:
|
|
243
251
|
- `frame-PID.tty`, one while each frame is open. The frame deletes
|
|
244
252
|
it when it closes; a frame killed outright can leave it behind.
|
|
245
|
-
- `sessionview.log`, the log ([Logs](#logs)).
|
|
246
253
|
- `recent.tsv`, a line each time `sessionview session` opens a
|
|
247
254
|
project, for the picker's order.
|
|
248
255
|
- `picker-order`, when you flip the picker's sort.
|
|
@@ -254,6 +261,23 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
254
261
|
- `sidebar-remote-HOST.json`, what the sidebar last saw from each
|
|
255
262
|
host in your `remotes` setting.
|
|
256
263
|
- `mutt/`, an rc file for each box `sessionview messages` opens.
|
|
264
|
+
- `~/.sessionkit/view/log/`: the log folder, mode 0700, made at the
|
|
265
|
+
same time. It holds `sessionview.log` ([Logs](#logs)).
|
|
266
|
+
`SESSIONVIEW_LOG` names another log file. When `SESSIONVIEW_STATE`
|
|
267
|
+
is set, the log is `sessionview.log` in that folder instead.
|
|
268
|
+
- `~/.local/state/sessionview/`: the state folder of releases before
|
|
269
|
+
this one. Nothing new is made there. On an upgrade, the first start
|
|
270
|
+
hard-links `recent.tsv`, `picker-order`, `sidebar-mail.txt` and each
|
|
271
|
+
file in `mutt/` into the new state folder. The old names are kept,
|
|
272
|
+
so the two names are one file, and a sidebar still running from
|
|
273
|
+
before the upgrade stays correct. The old folder is left in place,
|
|
274
|
+
with the old `sessionview.log`, `sidebar-mouse.log`, the frame pins
|
|
275
|
+
and the plugin and remote files, which are not carried over. One
|
|
276
|
+
line is added to the end of the old log, naming the new one. Each
|
|
277
|
+
start sets the old folder to mode 0700, so the old names are private
|
|
278
|
+
too; the files in it keep their modes. An
|
|
279
|
+
older release's `~/.local/state/herd/` is renamed to this folder
|
|
280
|
+
first, when only the herd one exists.
|
|
257
281
|
- `~/Applications/SessionView.app`: `sessionview install --app` (or
|
|
258
282
|
`make app` in a checkout), or in `DEST` when that is set. It is
|
|
259
283
|
built in a temporary folder that is deleted after, and a rebuild
|
|
@@ -320,21 +344,25 @@ rm ~/.local/bin/sessionview ~/.local/bin/sessionview-* ~/.local/bin/tmux-sidebar
|
|
|
320
344
|
```
|
|
321
345
|
|
|
322
346
|
That leaves what the verbs made, listed above. The Dock app, the
|
|
323
|
-
plugin's cached copy and the state
|
|
324
|
-
delete them:
|
|
347
|
+
plugin's cached copy, and the state and log folders are sessionview's
|
|
348
|
+
alone. To delete them:
|
|
325
349
|
|
|
326
350
|
```bash
|
|
327
351
|
rm -rf "${HOME:?}/Applications/SessionView.app"
|
|
328
352
|
rm -rf "${HOME:?}/.claude/plugins/cache/sessionview"
|
|
353
|
+
rm -rf "${HOME:?}/.sessionkit/view/state" "${HOME:?}/.sessionkit/view/log"
|
|
329
354
|
rm -rf "${HOME:?}/.local/state/sessionview"
|
|
330
355
|
```
|
|
331
356
|
|
|
357
|
+
The last line is for an upgrade from an earlier release: it removes the
|
|
358
|
+
old state folder, with the old log in it.
|
|
359
|
+
|
|
332
360
|
uv's cache stays too, with the other things uv installed; `uv cache
|
|
333
361
|
clean sessionview` drops this package's entries. The key bindings go
|
|
334
362
|
when your tmux server next exits.
|
|
335
363
|
|
|
336
364
|
The rest is your data: delete it by hand only if you want it gone.
|
|
337
|
-
`~/.sessionkit/view/` holds your settings, and the kit's other packages
|
|
365
|
+
`~/.sessionkit/view/settings/` holds your settings, and the kit's other packages
|
|
338
366
|
keep theirs beside it in `~/.sessionkit/`.
|
|
339
367
|
|
|
340
368
|
## Keys and clicks
|
|
@@ -380,8 +408,9 @@ The look follows herdr's; its colours were matched from herdr's own window.
|
|
|
380
408
|
- **Environment:** `SESSIONVIEW_CONFIG` (another file for yours),
|
|
381
409
|
`SESSIONVIEW_FROM` (the name mail is sent as, else `mail_from`, else
|
|
382
410
|
`$USER`; `sessionview from` prints the name in effect), `SESSIONVIEW_STATE`
|
|
383
|
-
(state, default `~/.
|
|
384
|
-
|
|
411
|
+
(state, default `~/.sessionkit/view/state`), `SESSIONVIEW_LOG` (the log
|
|
412
|
+
file, default `~/.sessionkit/view/log/sessionview.log`),
|
|
413
|
+
`SESSIONVIEW_PLUGINS` (another plugin directory).
|
|
385
414
|
- sessionview does not read the kit's settings cascade today, only these.
|
|
386
415
|
|
|
387
416
|
Every file, variable and tmux option is in
|
|
@@ -391,19 +420,25 @@ and every key in
|
|
|
391
420
|
|
|
392
421
|
## Logs
|
|
393
422
|
|
|
394
|
-
- `~/.
|
|
423
|
+
- `~/.sessionkit/view/log/sessionview.log`: what went wrong, one
|
|
395
424
|
entry each, starting with the time (a failed tmux call, an uncaught
|
|
396
425
|
error with its traceback). Follow it with
|
|
397
|
-
`tail -f ~/.
|
|
426
|
+
`tail -f ~/.sessionkit/view/log/sessionview.log` when a click
|
|
398
427
|
seems to do nothing.
|
|
428
|
+
- **After an upgrade:** the log of earlier releases,
|
|
429
|
+
`~/.local/state/sessionview/sessionview.log`, stays where it is and
|
|
430
|
+
is never moved. Its last line names the new log, and the new log's
|
|
431
|
+
first line names the old one.
|
|
399
432
|
- **Levels:** `log_level` in your settings (or `$SESSIONVIEW_LOG_LEVEL`
|
|
400
433
|
for one run). `error`, the default, logs only what went wrong.
|
|
401
434
|
`timing` adds a line per click or key with its milliseconds, and each
|
|
402
435
|
command that took 50 ms or more, so a slow click names its slow part.
|
|
403
436
|
`debug` adds every command and every mouse event (what the old
|
|
404
437
|
`sidebar-mouse.log` held).
|
|
405
|
-
-
|
|
406
|
-
|
|
438
|
+
- `$SESSIONVIEW_LOG` names another log file. Without it, a
|
|
439
|
+
`$SESSIONVIEW_STATE` that names another folder keeps the log there, as
|
|
440
|
+
`sessionview.log`. It is not rotated: turn `timing` or `debug` on
|
|
441
|
+
while you look, then back to `error`.
|
|
407
442
|
- **Health:** `sessionview install --check`: exit 0 and `ready` when
|
|
408
443
|
every requirement is present, exit 1 with each MISSING one named
|
|
409
444
|
otherwise. It checks the machine, not a running sidebar.
|
|
@@ -9,8 +9,11 @@ Install from PyPI: `uv tool install sessionview` (see [Install](#install)).
|
|
|
9
9
|
|
|
10
10
|
sessionview
|
|
11
11
|
|
|
12
|
-
In this terminal, that puts the sidebar on the left and
|
|
13
|
-
|
|
12
|
+
In this terminal, that puts the sidebar on the left and a tmux session
|
|
13
|
+
on the right; a private outer tmux holds the two panes. The session is
|
|
14
|
+
one tmux already has: your default assistant's, else the one you last
|
|
15
|
+
attached, else the newest. Only when tmux has no session at all does
|
|
16
|
+
sessionview make one, named `main`.
|
|
14
17
|
`sessionview NAME` attaches the session NAME instead, which must exist.
|
|
15
18
|
In any tmux client, `prefix H` opens the same sidebar as a popup.
|
|
16
19
|
Every verb, its form and an example: [the sessionview command](docs/sessionview.md).
|
|
@@ -75,8 +78,12 @@ agents, or the menu): the names `session start` knows, pinned ones first.
|
|
|
75
78
|
not start. An agent already running is never started twice.
|
|
76
79
|
- *Agents have a home* — an agent's own file says where it wakes
|
|
77
80
|
(`start: directory:`); a project's menu starts it in the project.
|
|
78
|
-
- *Consent on first open* —
|
|
79
|
-
|
|
81
|
+
- *Consent on first open* — the first time it opens, sessionview asks
|
|
82
|
+
which agent to start whenever it opens, and remembers the answer. It
|
|
83
|
+
says *sessionview can start an agent for you each time it opens*, lists
|
|
84
|
+
your agents by number and asks `Which? (number, name, or "n")`. When it cannot get the
|
|
85
|
+
list it asks `Which agent? (a name, or "no" to never ask again)`. `n` or
|
|
86
|
+
`no` means never; `autostart_agent` in Settings changes it later.
|
|
80
87
|
|
|
81
88
|
**Settings** — every setting, its default, its note and where its value
|
|
82
89
|
comes from, in a small screen (project menu → Settings); the rows come
|
|
@@ -118,7 +125,8 @@ hand. Blink Shell on iPad is wanted and not yet connecting.
|
|
|
118
125
|
claude-code: short, safe driving skills with tools
|
|
119
126
|
|
|
120
127
|
Paths resolve from the checkout (`SESSIONVIEW_ROOT`); state lives in
|
|
121
|
-
`~/.
|
|
128
|
+
`~/.sessionkit/view/state` (`SESSIONVIEW_STATE`) and the log in
|
|
129
|
+
`~/.sessionkit/view/log` (`SESSIONVIEW_LOG`). Its direct dependencies:
|
|
122
130
|
[dependencies](docs/dependencies.md).
|
|
123
131
|
|
|
124
132
|
## Install
|
|
@@ -218,14 +226,13 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
218
226
|
sessionview` drops this package's entries, and `uv cache prune` drops
|
|
219
227
|
the ones nothing uses.
|
|
220
228
|
- **Folders, each made by a verb you run:**
|
|
221
|
-
- `~/.
|
|
222
|
-
`sessionview` opens (or `sessionview session` or
|
|
223
|
-
messages` runs). `SESSIONVIEW_STATE`
|
|
224
|
-
|
|
225
|
-
|
|
229
|
+
- `~/.sessionkit/view/state/`: the state folder, mode 0700, made the
|
|
230
|
+
first time `sessionview` opens (or `sessionview session` or
|
|
231
|
+
`sessionview messages` runs). `SESSIONVIEW_STATE` names another
|
|
232
|
+
folder instead. Each file sessionview makes in it is private (mode
|
|
233
|
+
0600). In it:
|
|
226
234
|
- `frame-PID.tty`, one while each frame is open. The frame deletes
|
|
227
235
|
it when it closes; a frame killed outright can leave it behind.
|
|
228
|
-
- `sessionview.log`, the log ([Logs](#logs)).
|
|
229
236
|
- `recent.tsv`, a line each time `sessionview session` opens a
|
|
230
237
|
project, for the picker's order.
|
|
231
238
|
- `picker-order`, when you flip the picker's sort.
|
|
@@ -237,6 +244,23 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
237
244
|
- `sidebar-remote-HOST.json`, what the sidebar last saw from each
|
|
238
245
|
host in your `remotes` setting.
|
|
239
246
|
- `mutt/`, an rc file for each box `sessionview messages` opens.
|
|
247
|
+
- `~/.sessionkit/view/log/`: the log folder, mode 0700, made at the
|
|
248
|
+
same time. It holds `sessionview.log` ([Logs](#logs)).
|
|
249
|
+
`SESSIONVIEW_LOG` names another log file. When `SESSIONVIEW_STATE`
|
|
250
|
+
is set, the log is `sessionview.log` in that folder instead.
|
|
251
|
+
- `~/.local/state/sessionview/`: the state folder of releases before
|
|
252
|
+
this one. Nothing new is made there. On an upgrade, the first start
|
|
253
|
+
hard-links `recent.tsv`, `picker-order`, `sidebar-mail.txt` and each
|
|
254
|
+
file in `mutt/` into the new state folder. The old names are kept,
|
|
255
|
+
so the two names are one file, and a sidebar still running from
|
|
256
|
+
before the upgrade stays correct. The old folder is left in place,
|
|
257
|
+
with the old `sessionview.log`, `sidebar-mouse.log`, the frame pins
|
|
258
|
+
and the plugin and remote files, which are not carried over. One
|
|
259
|
+
line is added to the end of the old log, naming the new one. Each
|
|
260
|
+
start sets the old folder to mode 0700, so the old names are private
|
|
261
|
+
too; the files in it keep their modes. An
|
|
262
|
+
older release's `~/.local/state/herd/` is renamed to this folder
|
|
263
|
+
first, when only the herd one exists.
|
|
240
264
|
- `~/Applications/SessionView.app`: `sessionview install --app` (or
|
|
241
265
|
`make app` in a checkout), or in `DEST` when that is set. It is
|
|
242
266
|
built in a temporary folder that is deleted after, and a rebuild
|
|
@@ -303,21 +327,25 @@ rm ~/.local/bin/sessionview ~/.local/bin/sessionview-* ~/.local/bin/tmux-sidebar
|
|
|
303
327
|
```
|
|
304
328
|
|
|
305
329
|
That leaves what the verbs made, listed above. The Dock app, the
|
|
306
|
-
plugin's cached copy and the state
|
|
307
|
-
delete them:
|
|
330
|
+
plugin's cached copy, and the state and log folders are sessionview's
|
|
331
|
+
alone. To delete them:
|
|
308
332
|
|
|
309
333
|
```bash
|
|
310
334
|
rm -rf "${HOME:?}/Applications/SessionView.app"
|
|
311
335
|
rm -rf "${HOME:?}/.claude/plugins/cache/sessionview"
|
|
336
|
+
rm -rf "${HOME:?}/.sessionkit/view/state" "${HOME:?}/.sessionkit/view/log"
|
|
312
337
|
rm -rf "${HOME:?}/.local/state/sessionview"
|
|
313
338
|
```
|
|
314
339
|
|
|
340
|
+
The last line is for an upgrade from an earlier release: it removes the
|
|
341
|
+
old state folder, with the old log in it.
|
|
342
|
+
|
|
315
343
|
uv's cache stays too, with the other things uv installed; `uv cache
|
|
316
344
|
clean sessionview` drops this package's entries. The key bindings go
|
|
317
345
|
when your tmux server next exits.
|
|
318
346
|
|
|
319
347
|
The rest is your data: delete it by hand only if you want it gone.
|
|
320
|
-
`~/.sessionkit/view/` holds your settings, and the kit's other packages
|
|
348
|
+
`~/.sessionkit/view/settings/` holds your settings, and the kit's other packages
|
|
321
349
|
keep theirs beside it in `~/.sessionkit/`.
|
|
322
350
|
|
|
323
351
|
## Keys and clicks
|
|
@@ -363,8 +391,9 @@ The look follows herdr's; its colours were matched from herdr's own window.
|
|
|
363
391
|
- **Environment:** `SESSIONVIEW_CONFIG` (another file for yours),
|
|
364
392
|
`SESSIONVIEW_FROM` (the name mail is sent as, else `mail_from`, else
|
|
365
393
|
`$USER`; `sessionview from` prints the name in effect), `SESSIONVIEW_STATE`
|
|
366
|
-
(state, default `~/.
|
|
367
|
-
|
|
394
|
+
(state, default `~/.sessionkit/view/state`), `SESSIONVIEW_LOG` (the log
|
|
395
|
+
file, default `~/.sessionkit/view/log/sessionview.log`),
|
|
396
|
+
`SESSIONVIEW_PLUGINS` (another plugin directory).
|
|
368
397
|
- sessionview does not read the kit's settings cascade today, only these.
|
|
369
398
|
|
|
370
399
|
Every file, variable and tmux option is in
|
|
@@ -374,19 +403,25 @@ and every key in
|
|
|
374
403
|
|
|
375
404
|
## Logs
|
|
376
405
|
|
|
377
|
-
- `~/.
|
|
406
|
+
- `~/.sessionkit/view/log/sessionview.log`: what went wrong, one
|
|
378
407
|
entry each, starting with the time (a failed tmux call, an uncaught
|
|
379
408
|
error with its traceback). Follow it with
|
|
380
|
-
`tail -f ~/.
|
|
409
|
+
`tail -f ~/.sessionkit/view/log/sessionview.log` when a click
|
|
381
410
|
seems to do nothing.
|
|
411
|
+
- **After an upgrade:** the log of earlier releases,
|
|
412
|
+
`~/.local/state/sessionview/sessionview.log`, stays where it is and
|
|
413
|
+
is never moved. Its last line names the new log, and the new log's
|
|
414
|
+
first line names the old one.
|
|
382
415
|
- **Levels:** `log_level` in your settings (or `$SESSIONVIEW_LOG_LEVEL`
|
|
383
416
|
for one run). `error`, the default, logs only what went wrong.
|
|
384
417
|
`timing` adds a line per click or key with its milliseconds, and each
|
|
385
418
|
command that took 50 ms or more, so a slow click names its slow part.
|
|
386
419
|
`debug` adds every command and every mouse event (what the old
|
|
387
420
|
`sidebar-mouse.log` held).
|
|
388
|
-
-
|
|
389
|
-
|
|
421
|
+
- `$SESSIONVIEW_LOG` names another log file. Without it, a
|
|
422
|
+
`$SESSIONVIEW_STATE` that names another folder keeps the log there, as
|
|
423
|
+
`sessionview.log`. It is not rotated: turn `timing` or `debug` on
|
|
424
|
+
while you look, then back to `error`.
|
|
390
425
|
- **Health:** `sessionview install --check`: exit 0 and `ready` when
|
|
391
426
|
every requirement is present, exit 1 with each MISSING one named
|
|
392
427
|
otherwise. It checks the machine, not a running sidebar.
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
# sessionview --help | --version
|
|
7
7
|
#
|
|
8
8
|
# sessionview [SESSION] the frame: sidebar on the left, SESSION attached on
|
|
9
|
-
# the right (default
|
|
9
|
+
# the right (default: one the server has, else main;
|
|
10
|
+
# a named SESSION must exist).
|
|
10
11
|
# --sock names its tmux server; --width, columns.
|
|
11
12
|
# sessionview config settings: no verb opens the screen (get/set/list ...)
|
|
12
13
|
# sessionview session NAME open a project session with its standard tabs
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
#
|
|
23
24
|
# Also: prefix H in any tmux client opens the sidebar as a popup.
|
|
24
25
|
# Config: ~/.sessionkit/view/settings/view.json over the shipped config/config.json.
|
|
25
|
-
# State: ~/.
|
|
26
|
+
# State: ~/.sessionkit/view/state (SESSIONVIEW_STATE=). Log: ~/.sessionkit/view/log (SESSIONVIEW_LOG=).
|
|
26
27
|
# (end of usage)
|
|
27
28
|
# Ghostty was stripped out so this works in any terminal with only tmux. It
|
|
28
29
|
# started as ghostty-herd; the Ghostty launcher, the split hook and cmd+d
|
|
@@ -66,7 +67,7 @@ case "${1:-}" in
|
|
|
66
67
|
"$SESSIONVIEW_ROOT/bin/tmux-sidebar" --help >&2
|
|
67
68
|
exit 2
|
|
68
69
|
fi
|
|
69
|
-
|
|
70
|
+
. "$SESSIONVIEW_ROOT/lib/state.sh"; . "$SESSIONVIEW_ROOT/lib/python.sh"; export SESSIONVIEW_ROOT SESSIONVIEW_STATE
|
|
70
71
|
# The supervisor: q = exit 0 = reload (picks up an edited tmux-sidebar or
|
|
71
72
|
# sidebar.toml), Q = exit 3 = quit. A CRASH IS NOT A QUIT: any other exit
|
|
72
73
|
# holds the error on screen and waits (one undefined name once took the
|
|
@@ -86,7 +87,9 @@ esac
|
|
|
86
87
|
# (--sock, else this tmux's own server when run inside one, else default):
|
|
87
88
|
# a typo or a probe word must not mean "open a frame on a new session named
|
|
88
89
|
# after it". Read-only check; on a miss, usage and exit 2, nothing touched.
|
|
89
|
-
# A new named session is `sessionview session NAME`. No word
|
|
90
|
+
# A new named session is `sessionview session NAME`. No word: the frame picks
|
|
91
|
+
# a session the server already has, and makes main only when it has none
|
|
92
|
+
# (lib/landing.sh).
|
|
90
93
|
word=""; sock=""; prev=""
|
|
91
94
|
for a in "$@"; do
|
|
92
95
|
case "$prev" in --sock) sock="$a"; prev=""; continue;; --width) prev=""; continue;; esac
|
|
@@ -110,5 +113,5 @@ if [ -n "$word" ]; then
|
|
|
110
113
|
# the frame looks where this checked: inside tmux, the caller's own server
|
|
111
114
|
[ -n "$extra" ] && set -- "$@" --sock "$sock"
|
|
112
115
|
fi
|
|
113
|
-
|
|
116
|
+
. "$SESSIONVIEW_ROOT/lib/state.sh"; . "$SESSIONVIEW_ROOT/lib/python.sh"; export SESSIONVIEW_ROOT SESSIONVIEW_STATE
|
|
114
117
|
exec "$SESSIONVIEW_ROOT/bin/sessionview-frame" "$@"
|
|
@@ -116,9 +116,14 @@ sys.exit(1)' "$1"
|
|
|
116
116
|
# that then fails to start. Empty output, missing command, any error: the
|
|
117
117
|
# free-text question below still works, so this fails open like everything
|
|
118
118
|
# else in this file.
|
|
119
|
+
#
|
|
120
|
+
# Each line is NAME, then a TAB and a mark (`claude<TAB>built in`), or the
|
|
121
|
+
# NAME alone. Only the field before the first TAB is a name: the mark can hold
|
|
122
|
+
# a space, and splitting the whole output on whitespace offered "built" and
|
|
123
|
+
# "in" as agents.
|
|
119
124
|
agent_list() {
|
|
120
125
|
command -v session >/dev/null 2>&1 || return 0
|
|
121
|
-
session start --list-agents 2>/dev/null
|
|
126
|
+
session start --list-agents 2>/dev/null | awk -F '\t' '$1 != "" { print $1 }'
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
# Discard every byte waiting to be read on the terminal. ask() calls this once
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
#
|
|
8
8
|
# sessionview-frame [SESSION] [--sock SOCKET] [--width N]
|
|
9
9
|
#
|
|
10
|
-
# SESSION what the right pane attaches (default:
|
|
10
|
+
# SESSION what the right pane attaches (default: a session the server
|
|
11
|
+
# already has: the default seat's, else the last attached, else
|
|
12
|
+
# the newest; main, made, only when the server has none)
|
|
11
13
|
# --sock the tmux server SESSION lives on (default: default; a store's is
|
|
12
14
|
# tm-store-NAME)
|
|
13
15
|
# --width sidebar columns (default: config width via sessionview-config, else 34)
|
|
@@ -32,7 +34,7 @@ while [ $# -gt 0 ]; do case "$1" in
|
|
|
32
34
|
*) SESSION="$1"; GIVEN=1;;
|
|
33
35
|
esac; shift; done
|
|
34
36
|
# The state dir and the Python only after the flags: -h touches nothing.
|
|
35
|
-
|
|
37
|
+
. "$SESSIONVIEW_ROOT/lib/state.sh"; . "$SESSIONVIEW_ROOT/lib/python.sh"; export SESSIONVIEW_ROOT SESSIONVIEW_STATE
|
|
36
38
|
# The frame takes over the terminal it runs in, so it needs one: a script or
|
|
37
39
|
# an agent's shell (stdin/stdout not a tty) is refused and nothing is touched.
|
|
38
40
|
# Every refusal is one line on stderr, exit 2.
|
|
@@ -72,11 +74,21 @@ if [ -n "${TMUX:-}" ]; then
|
|
|
72
74
|
# (measured: SESSIONVIEW_FRAME_SOCK set here did not reach the frame,
|
|
73
75
|
# which landed on the default frame server) - carry what matters by hand.
|
|
74
76
|
cmd="SESSIONVIEW_ROOT=$(q "$SESSIONVIEW_ROOT") SESSIONVIEW_STATE=$(q "$SESSIONVIEW_STATE") SESSIONVIEW_PYTHON=$(q "${SESSIONVIEW_PYTHON:-}")"
|
|
77
|
+
# A log the user gave goes too; a derived one never does (lib/state.sh).
|
|
78
|
+
if [ -n "${SESSIONVIEW_LOG:-}" ]; then cmd="$cmd SESSIONVIEW_LOG=$(q "$SESSIONVIEW_LOG")"; fi
|
|
75
79
|
cmd="$cmd SESSIONVIEW_FRAME_SOCK=$(q "$FRAME_SOCK") TMUX="
|
|
76
80
|
cmd="$cmd exec $(q "$0") $(q "$SESSION") --sock $(q "$SOCK")"
|
|
77
81
|
[ -n "$WIDTH" ] && cmd="$cmd --width $(q "$WIDTH")"
|
|
78
82
|
exec tmux -S "$here_path" detach-client -t "$ctty" -E "$cmd"
|
|
79
83
|
fi
|
|
84
|
+
# Outside tmux with no SESSION named: land in a session the server already
|
|
85
|
+
# has (the default seat's, else the last attached, else the newest; the rule
|
|
86
|
+
# and its reasons are in lib/landing.sh). `main` is made below only when the
|
|
87
|
+
# server has no session at all.
|
|
88
|
+
if [ -z "$GIVEN" ]; then
|
|
89
|
+
. "$SESSIONVIEW_ROOT/lib/landing.sh"
|
|
90
|
+
if sv_landing "$SOCK"; then SESSION="$SV_LANDING"; fi
|
|
91
|
+
fi
|
|
80
92
|
if [ -z "$WIDTH" ]; then
|
|
81
93
|
WIDTH="$("$SESSIONVIEW_ROOT/bin/sessionview-config" get width 2>/dev/null || true)"
|
|
82
94
|
WIDTH="${WIDTH:-34}"
|
|
@@ -209,7 +221,9 @@ o resize-pane -t "$SIDE" -x "$WIDTH"
|
|
|
209
221
|
TTY="$(tty 2>/dev/null || echo none)"
|
|
210
222
|
o set-hook -g "client-detached[$$]" "if -F '#{==:#{hook_client},$TTY}' 'kill-session -t =$F'"
|
|
211
223
|
o select-pane -t "$MAIN"
|
|
212
|
-
# pin = the client pane's tty: that is the client the sidebar may move
|
|
213
|
-
|
|
224
|
+
# pin = the client pane's tty: that is the client the sidebar may move. Made
|
|
225
|
+
# 0600: the umask is the subshell's alone, never this script's, which starts
|
|
226
|
+
# the user's tmux server (a server keeps its umask for every pane it opens).
|
|
227
|
+
( umask 077; o display-message -p -t "$MAIN" '#{pane_tty}' >"$PIN" )
|
|
214
228
|
o attach -t "=$F"
|
|
215
229
|
cleanup
|
|
@@ -157,13 +157,15 @@ fi
|
|
|
157
157
|
if command -v session >/dev/null 2>&1; then say PASS "session on PATH"
|
|
158
158
|
else say WARN "session not on PATH - the sidebar lists tmux sessions without it, but no agent rows, so no agent menu (Message, Settle, ...), and no 'Start an agent' (uv tool install sessiontools)"; fi
|
|
159
159
|
# neomutt - the messages tab (bin/sessionview-messages runs `neomutt -R`, exit 2 without
|
|
160
|
-
# it).
|
|
160
|
+
# it). A WARN, not MISSING: that tab is made only when sessionmail, which is optional,
|
|
161
|
+
# is installed, so sessionview runs without neomutt and the check still says ready.
|
|
162
|
+
# (It was MISSING until 2026-10-28, when neomutt was ruled optional for the check.)
|
|
161
163
|
if command -v neomutt >/dev/null 2>&1; then
|
|
162
164
|
nv="$(neomutt -v 2>/dev/null | sed -n 's/^NeoMutt \([0-9]*\).*/\1/p' | head -1)"
|
|
163
165
|
if neomutt -v 2>/dev/null | grep -q '+notmuch'; then say PASS "neomutt ${nv:-?} with notmuch"
|
|
164
166
|
else say WARN "neomutt ${nv:-?} built without notmuch - the messages tab opens, with no sidebar (brew install neomutt)"; fi
|
|
165
167
|
else
|
|
166
|
-
|
|
168
|
+
say WARN "neomutt not on PATH - the messages tab, which sessionview makes only when sessionmail is installed, cannot open (brew install neomutt)"
|
|
167
169
|
fi
|
|
168
170
|
# notmuch - the messages tab's sidebar queries Type: and Project:; unindexed, the Asks
|
|
169
171
|
# rows are every mail to NAME+ask, with no error
|
|
@@ -108,16 +108,21 @@ if command -v notmuch >/dev/null 2>&1; then
|
|
|
108
108
|
*) SIDEBAR_WHY="$FOLDER is not under notmuch database.path $DB";;
|
|
109
109
|
esac; fi
|
|
110
110
|
else SIDEBAR_WHY="no notmuch on PATH (brew install notmuch)"; fi
|
|
111
|
-
|
|
111
|
+
. "$SESSIONVIEW_ROOT/lib/state.sh"; STATE="$SESSIONVIEW_STATE/mutt"; mkdir -p -m 700 "$STATE"
|
|
112
112
|
RC="$STATE/${BOX//\//-}.rc"
|
|
113
|
-
|
|
113
|
+
# Written IN PLACE (> truncates the same file), never a temp file renamed over
|
|
114
|
+
# it: the rc may have a second name, a hard link in the old state dir's mutt/
|
|
115
|
+
# (docs/decisions/state-and-log-home.md, section 3). Made 0600 when it is new:
|
|
116
|
+
# the umask is the subshell's alone, never this script's, which execs neomutt;
|
|
117
|
+
# an existing rc keeps its mode.
|
|
118
|
+
( umask 077; {
|
|
114
119
|
printf 'set mbox_type=Maildir\nset folder="%s"\nset spoolfile=+\nset mark_old=no\n' "$FOLDER"
|
|
115
120
|
[ -n "$SIDEBAR_WHY" ] && printf '# sidebar: %s\n' "$SIDEBAR_WHY"
|
|
116
121
|
[ -n "$SIDEBAR" ] && printf '%s\n' "$SIDEBAR"
|
|
117
122
|
printf 'source "%s"\n' "$SESSIONVIEW_ROOT/config/neomuttrc"
|
|
118
123
|
[ -z "$SIDEBAR" ] && printf 'set sidebar_visible=no\n'
|
|
119
124
|
[ -f "$VIEW_SETTINGS/neomuttrc" ] && printf 'source "%s"\n' "$VIEW_SETTINGS/neomuttrc"
|
|
120
|
-
} >"$RC"
|
|
125
|
+
} >"$RC" )
|
|
121
126
|
if [ "$PRINT" = 1 ]; then
|
|
122
127
|
echo "box=$BOX folder=$FOLDER rc=$RC"
|
|
123
128
|
if [ -n "$SIDEBAR" ]; then echo "sidebar=$NAME, Asks, Asks · threads${SIDEBAR_WHY:+ ($SIDEBAR_WHY)}"
|