sessionview 0.3.1__tar.gz → 0.3.3__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.3}/PKG-INFO +71 -30
- {sessionview-0.3.1 → sessionview-0.3.3}/README.md +70 -29
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview +8 -5
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-autostart +6 -1
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-frame +35 -10
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-install +13 -7
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-messages +25 -10
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-session +93 -33
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/tmux-send-agent +4 -3
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/tmux-sidebar +426 -77
- sessionview-0.3.3/changelog.d/README.md +102 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/config/README.md +16 -6
- {sessionview-0.3.1 → sessionview-0.3.3}/config/config.json +8 -4
- {sessionview-0.3.1 → sessionview-0.3.3}/docs/configuration.md +28 -8
- sessionview-0.3.3/docs/decisions/state-and-log-home.md +557 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/docs/dependencies.md +5 -5
- {sessionview-0.3.1 → sessionview-0.3.3}/docs/sessionview.md +16 -7
- {sessionview-0.3.1 → sessionview-0.3.3}/docs/settings.md +5 -2
- sessionview-0.3.3/lib/landing.sh +67 -0
- sessionview-0.3.3/lib/pane-menu.sh +56 -0
- sessionview-0.3.3/lib/state.sh +99 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/macos/SessionView.applescript +57 -5
- {sessionview-0.3.1 → sessionview-0.3.3}/pyproject.toml +1 -1
- {sessionview-0.3.1 → sessionview-0.3.3}/src/sessionview/__init__.py +1 -1
- sessionview-0.3.3/tmux/agent-menu.conf +95 -0
- sessionview-0.3.1/lib/state.sh +0 -13
- sessionview-0.3.1/tmux/agent-menu.conf +0 -33
- {sessionview-0.3.1 → sessionview-0.3.3}/.gitignore +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/LICENSE +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-app-install +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-config +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-from +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-newtab +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-send +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-sidebar-toggle +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-terminal +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/bin/sessionview-usermail +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/config/keys.md +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/config/neomuttrc +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/lib/client.sh +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/lib/python.sh +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/lib/sessionview-config-screen +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/macos/dreamcatcher.icns +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/plugins/session/plugin.toml +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/plugins/session/start-agent +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/plugins/taskmaster/plugin.toml +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/plugins/taskmaster/tasks-tab +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/plugins/voicemode/plugin.toml +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/plugins/voicemode/speak +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/skills/tmux/SKILL.md +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/skills/tmux/scripts/tmux-peek +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/skills/tmux/scripts/tmux-show +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/skills/tmux/scripts/tmux-type +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/skills/tmux/scripts/tmux-where +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/tmux/frame.conf +0 -0
- {sessionview-0.3.1 → sessionview-0.3.3}/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.3
|
|
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
|
|
@@ -261,7 +285,9 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
261
285
|
- **Services (launchd agents):** none. sessionview runs no daemon and
|
|
262
286
|
writes nothing in `~/Library/LaunchAgents/`. While a frame is open it
|
|
263
287
|
runs a tmux server of its own, `sessionview-frame`, beside yours; the
|
|
264
|
-
server exits when the last frame closes.
|
|
288
|
+
server exits when the last frame closes. With `pane_menu` on, an
|
|
289
|
+
Option + right-click on that server's pane that holds your tmux goes
|
|
290
|
+
through to yours.
|
|
265
291
|
- **Plugin and skills, optional:** `claude plugin marketplace add` and
|
|
266
292
|
`claude plugin install` ([Install](#install)). Claude Code names the
|
|
267
293
|
marketplace and the plugin in `~/.claude/settings.json`
|
|
@@ -286,9 +312,10 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
286
312
|
mouse bindings on the status line (`MouseDown1Status`,
|
|
287
313
|
`MouseDown1StatusRight`, `MouseDrag1Status`). It gives each session it
|
|
288
314
|
opens the sessionview look, with options set on that session only.
|
|
289
|
-
With `pane_menu` on, it also binds
|
|
290
|
-
(`MouseDown3Pane`
|
|
291
|
-
|
|
315
|
+
With `pane_menu` on, it also binds both right-clicks in a pane
|
|
316
|
+
(`MouseDown3Pane`, and `M-MouseDown3Pane` for Option + right-click),
|
|
317
|
+
in place of yours, and sets two global `@sessionview_agent_menu_`
|
|
318
|
+
options. Nothing is written to
|
|
292
319
|
`~/.tmux.conf`: these last until that tmux server exits.
|
|
293
320
|
- **Outside these folders, only on a verb:** with `fullscreen` on, the
|
|
294
321
|
Dock app on Terminal.app needs the Accessibility permission you grant
|
|
@@ -320,21 +347,25 @@ rm ~/.local/bin/sessionview ~/.local/bin/sessionview-* ~/.local/bin/tmux-sidebar
|
|
|
320
347
|
```
|
|
321
348
|
|
|
322
349
|
That leaves what the verbs made, listed above. The Dock app, the
|
|
323
|
-
plugin's cached copy and the state
|
|
324
|
-
delete them:
|
|
350
|
+
plugin's cached copy, and the state and log folders are sessionview's
|
|
351
|
+
alone. To delete them:
|
|
325
352
|
|
|
326
353
|
```bash
|
|
327
354
|
rm -rf "${HOME:?}/Applications/SessionView.app"
|
|
328
355
|
rm -rf "${HOME:?}/.claude/plugins/cache/sessionview"
|
|
356
|
+
rm -rf "${HOME:?}/.sessionkit/view/state" "${HOME:?}/.sessionkit/view/log"
|
|
329
357
|
rm -rf "${HOME:?}/.local/state/sessionview"
|
|
330
358
|
```
|
|
331
359
|
|
|
360
|
+
The last line is for an upgrade from an earlier release: it removes the
|
|
361
|
+
old state folder, with the old log in it.
|
|
362
|
+
|
|
332
363
|
uv's cache stays too, with the other things uv installed; `uv cache
|
|
333
364
|
clean sessionview` drops this package's entries. The key bindings go
|
|
334
365
|
when your tmux server next exits.
|
|
335
366
|
|
|
336
367
|
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
|
|
368
|
+
`~/.sessionkit/view/settings/` holds your settings, and the kit's other packages
|
|
338
369
|
keep theirs beside it in `~/.sessionkit/`.
|
|
339
370
|
|
|
340
371
|
## Keys and clicks
|
|
@@ -344,17 +375,20 @@ keep theirs beside it in `~/.sessionkit/`.
|
|
|
344
375
|
picker (type to filter, ↑↓, enter); `+` at the bottom → start an
|
|
345
376
|
agent; the store name → that store's session and store view, its `⋯`
|
|
346
377
|
(or `s`) → Switch store, right-click → Kick; `all · grouped` on the agents
|
|
347
|
-
heading are toggles; drag the border to resize; `q` reloads, `Q`
|
|
378
|
+
heading are toggles (the first cycles all / store / project); drag the border to resize; `q` reloads, `Q`
|
|
348
379
|
quits, esc backs out of any view
|
|
349
380
|
- tab bar: `◧` at the far left hides/shows the sidebar; click selects,
|
|
350
381
|
drag reorders, `+` new tab (the picker); a close `×`, on by default;
|
|
351
382
|
`tmux set -g @sessionview_tab_close 0` turns it off
|
|
352
383
|
- menu: ↑↓ / j k move, the letter or enter picks, esc or a click
|
|
353
384
|
anywhere else closes
|
|
354
|
-
- agent panes (opt-in): right-click an agent's
|
|
355
|
-
Read Clipboard, Park or Succeed; each mails
|
|
356
|
-
|
|
357
|
-
|
|
385
|
+
- agent panes (opt-in): right-click or Option + right-click an agent's
|
|
386
|
+
pane for Speak, Continue, Read Clipboard, Park or Succeed; each mails
|
|
387
|
+
that agent. It opens even on an agent whose program uses the mouse, as
|
|
388
|
+
Claude Code does. An agent's pane is one whose title is
|
|
389
|
+
`<glyph> <address>`. Turn it on with
|
|
390
|
+
`sessionview-config set pane_menu true`. It replaces your own tmux
|
|
391
|
+
right-click menus, which is why it is off by default. Using tmux without session view? Add
|
|
358
392
|
`source-file -q /path/to/sessionview/tmux/agent-menu.conf` to
|
|
359
393
|
`~/.tmux.conf` and reload.
|
|
360
394
|
|
|
@@ -380,8 +414,9 @@ The look follows herdr's; its colours were matched from herdr's own window.
|
|
|
380
414
|
- **Environment:** `SESSIONVIEW_CONFIG` (another file for yours),
|
|
381
415
|
`SESSIONVIEW_FROM` (the name mail is sent as, else `mail_from`, else
|
|
382
416
|
`$USER`; `sessionview from` prints the name in effect), `SESSIONVIEW_STATE`
|
|
383
|
-
(state, default `~/.
|
|
384
|
-
|
|
417
|
+
(state, default `~/.sessionkit/view/state`), `SESSIONVIEW_LOG` (the log
|
|
418
|
+
file, default `~/.sessionkit/view/log/sessionview.log`),
|
|
419
|
+
`SESSIONVIEW_PLUGINS` (another plugin directory).
|
|
385
420
|
- sessionview does not read the kit's settings cascade today, only these.
|
|
386
421
|
|
|
387
422
|
Every file, variable and tmux option is in
|
|
@@ -391,19 +426,25 @@ and every key in
|
|
|
391
426
|
|
|
392
427
|
## Logs
|
|
393
428
|
|
|
394
|
-
- `~/.
|
|
429
|
+
- `~/.sessionkit/view/log/sessionview.log`: what went wrong, one
|
|
395
430
|
entry each, starting with the time (a failed tmux call, an uncaught
|
|
396
431
|
error with its traceback). Follow it with
|
|
397
|
-
`tail -f ~/.
|
|
432
|
+
`tail -f ~/.sessionkit/view/log/sessionview.log` when a click
|
|
398
433
|
seems to do nothing.
|
|
434
|
+
- **After an upgrade:** the log of earlier releases,
|
|
435
|
+
`~/.local/state/sessionview/sessionview.log`, stays where it is and
|
|
436
|
+
is never moved. Its last line names the new log, and the new log's
|
|
437
|
+
first line names the old one.
|
|
399
438
|
- **Levels:** `log_level` in your settings (or `$SESSIONVIEW_LOG_LEVEL`
|
|
400
439
|
for one run). `error`, the default, logs only what went wrong.
|
|
401
440
|
`timing` adds a line per click or key with its milliseconds, and each
|
|
402
441
|
command that took 50 ms or more, so a slow click names its slow part.
|
|
403
442
|
`debug` adds every command and every mouse event (what the old
|
|
404
443
|
`sidebar-mouse.log` held).
|
|
405
|
-
-
|
|
406
|
-
|
|
444
|
+
- `$SESSIONVIEW_LOG` names another log file. Without it, a
|
|
445
|
+
`$SESSIONVIEW_STATE` that names another folder keeps the log there, as
|
|
446
|
+
`sessionview.log`. It is not rotated: turn `timing` or `debug` on
|
|
447
|
+
while you look, then back to `error`.
|
|
407
448
|
- **Health:** `sessionview install --check`: exit 0 and `ready` when
|
|
408
449
|
every requirement is present, exit 1 with each MISSING one named
|
|
409
450
|
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
|
|
@@ -244,7 +268,9 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
244
268
|
- **Services (launchd agents):** none. sessionview runs no daemon and
|
|
245
269
|
writes nothing in `~/Library/LaunchAgents/`. While a frame is open it
|
|
246
270
|
runs a tmux server of its own, `sessionview-frame`, beside yours; the
|
|
247
|
-
server exits when the last frame closes.
|
|
271
|
+
server exits when the last frame closes. With `pane_menu` on, an
|
|
272
|
+
Option + right-click on that server's pane that holds your tmux goes
|
|
273
|
+
through to yours.
|
|
248
274
|
- **Plugin and skills, optional:** `claude plugin marketplace add` and
|
|
249
275
|
`claude plugin install` ([Install](#install)). Claude Code names the
|
|
250
276
|
marketplace and the plugin in `~/.claude/settings.json`
|
|
@@ -269,9 +295,10 @@ beside it. Each line says what puts it there and what takes it away.
|
|
|
269
295
|
mouse bindings on the status line (`MouseDown1Status`,
|
|
270
296
|
`MouseDown1StatusRight`, `MouseDrag1Status`). It gives each session it
|
|
271
297
|
opens the sessionview look, with options set on that session only.
|
|
272
|
-
With `pane_menu` on, it also binds
|
|
273
|
-
(`MouseDown3Pane`
|
|
274
|
-
|
|
298
|
+
With `pane_menu` on, it also binds both right-clicks in a pane
|
|
299
|
+
(`MouseDown3Pane`, and `M-MouseDown3Pane` for Option + right-click),
|
|
300
|
+
in place of yours, and sets two global `@sessionview_agent_menu_`
|
|
301
|
+
options. Nothing is written to
|
|
275
302
|
`~/.tmux.conf`: these last until that tmux server exits.
|
|
276
303
|
- **Outside these folders, only on a verb:** with `fullscreen` on, the
|
|
277
304
|
Dock app on Terminal.app needs the Accessibility permission you grant
|
|
@@ -303,21 +330,25 @@ rm ~/.local/bin/sessionview ~/.local/bin/sessionview-* ~/.local/bin/tmux-sidebar
|
|
|
303
330
|
```
|
|
304
331
|
|
|
305
332
|
That leaves what the verbs made, listed above. The Dock app, the
|
|
306
|
-
plugin's cached copy and the state
|
|
307
|
-
delete them:
|
|
333
|
+
plugin's cached copy, and the state and log folders are sessionview's
|
|
334
|
+
alone. To delete them:
|
|
308
335
|
|
|
309
336
|
```bash
|
|
310
337
|
rm -rf "${HOME:?}/Applications/SessionView.app"
|
|
311
338
|
rm -rf "${HOME:?}/.claude/plugins/cache/sessionview"
|
|
339
|
+
rm -rf "${HOME:?}/.sessionkit/view/state" "${HOME:?}/.sessionkit/view/log"
|
|
312
340
|
rm -rf "${HOME:?}/.local/state/sessionview"
|
|
313
341
|
```
|
|
314
342
|
|
|
343
|
+
The last line is for an upgrade from an earlier release: it removes the
|
|
344
|
+
old state folder, with the old log in it.
|
|
345
|
+
|
|
315
346
|
uv's cache stays too, with the other things uv installed; `uv cache
|
|
316
347
|
clean sessionview` drops this package's entries. The key bindings go
|
|
317
348
|
when your tmux server next exits.
|
|
318
349
|
|
|
319
350
|
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
|
|
351
|
+
`~/.sessionkit/view/settings/` holds your settings, and the kit's other packages
|
|
321
352
|
keep theirs beside it in `~/.sessionkit/`.
|
|
322
353
|
|
|
323
354
|
## Keys and clicks
|
|
@@ -327,17 +358,20 @@ keep theirs beside it in `~/.sessionkit/`.
|
|
|
327
358
|
picker (type to filter, ↑↓, enter); `+` at the bottom → start an
|
|
328
359
|
agent; the store name → that store's session and store view, its `⋯`
|
|
329
360
|
(or `s`) → Switch store, right-click → Kick; `all · grouped` on the agents
|
|
330
|
-
heading are toggles; drag the border to resize; `q` reloads, `Q`
|
|
361
|
+
heading are toggles (the first cycles all / store / project); drag the border to resize; `q` reloads, `Q`
|
|
331
362
|
quits, esc backs out of any view
|
|
332
363
|
- tab bar: `◧` at the far left hides/shows the sidebar; click selects,
|
|
333
364
|
drag reorders, `+` new tab (the picker); a close `×`, on by default;
|
|
334
365
|
`tmux set -g @sessionview_tab_close 0` turns it off
|
|
335
366
|
- menu: ↑↓ / j k move, the letter or enter picks, esc or a click
|
|
336
367
|
anywhere else closes
|
|
337
|
-
- agent panes (opt-in): right-click an agent's
|
|
338
|
-
Read Clipboard, Park or Succeed; each mails
|
|
339
|
-
|
|
340
|
-
|
|
368
|
+
- agent panes (opt-in): right-click or Option + right-click an agent's
|
|
369
|
+
pane for Speak, Continue, Read Clipboard, Park or Succeed; each mails
|
|
370
|
+
that agent. It opens even on an agent whose program uses the mouse, as
|
|
371
|
+
Claude Code does. An agent's pane is one whose title is
|
|
372
|
+
`<glyph> <address>`. Turn it on with
|
|
373
|
+
`sessionview-config set pane_menu true`. It replaces your own tmux
|
|
374
|
+
right-click menus, which is why it is off by default. Using tmux without session view? Add
|
|
341
375
|
`source-file -q /path/to/sessionview/tmux/agent-menu.conf` to
|
|
342
376
|
`~/.tmux.conf` and reload.
|
|
343
377
|
|
|
@@ -363,8 +397,9 @@ The look follows herdr's; its colours were matched from herdr's own window.
|
|
|
363
397
|
- **Environment:** `SESSIONVIEW_CONFIG` (another file for yours),
|
|
364
398
|
`SESSIONVIEW_FROM` (the name mail is sent as, else `mail_from`, else
|
|
365
399
|
`$USER`; `sessionview from` prints the name in effect), `SESSIONVIEW_STATE`
|
|
366
|
-
(state, default `~/.
|
|
367
|
-
|
|
400
|
+
(state, default `~/.sessionkit/view/state`), `SESSIONVIEW_LOG` (the log
|
|
401
|
+
file, default `~/.sessionkit/view/log/sessionview.log`),
|
|
402
|
+
`SESSIONVIEW_PLUGINS` (another plugin directory).
|
|
368
403
|
- sessionview does not read the kit's settings cascade today, only these.
|
|
369
404
|
|
|
370
405
|
Every file, variable and tmux option is in
|
|
@@ -374,19 +409,25 @@ and every key in
|
|
|
374
409
|
|
|
375
410
|
## Logs
|
|
376
411
|
|
|
377
|
-
- `~/.
|
|
412
|
+
- `~/.sessionkit/view/log/sessionview.log`: what went wrong, one
|
|
378
413
|
entry each, starting with the time (a failed tmux call, an uncaught
|
|
379
414
|
error with its traceback). Follow it with
|
|
380
|
-
`tail -f ~/.
|
|
415
|
+
`tail -f ~/.sessionkit/view/log/sessionview.log` when a click
|
|
381
416
|
seems to do nothing.
|
|
417
|
+
- **After an upgrade:** the log of earlier releases,
|
|
418
|
+
`~/.local/state/sessionview/sessionview.log`, stays where it is and
|
|
419
|
+
is never moved. Its last line names the new log, and the new log's
|
|
420
|
+
first line names the old one.
|
|
382
421
|
- **Levels:** `log_level` in your settings (or `$SESSIONVIEW_LOG_LEVEL`
|
|
383
422
|
for one run). `error`, the default, logs only what went wrong.
|
|
384
423
|
`timing` adds a line per click or key with its milliseconds, and each
|
|
385
424
|
command that took 50 ms or more, so a slow click names its slow part.
|
|
386
425
|
`debug` adds every command and every mouse event (what the old
|
|
387
426
|
`sidebar-mouse.log` held).
|
|
388
|
-
-
|
|
389
|
-
|
|
427
|
+
- `$SESSIONVIEW_LOG` names another log file. Without it, a
|
|
428
|
+
`$SESSIONVIEW_STATE` that names another folder keeps the log there, as
|
|
429
|
+
`sessionview.log`. It is not rotated: turn `timing` or `debug` on
|
|
430
|
+
while you look, then back to `error`.
|
|
390
431
|
- **Health:** `sessionview install --check`: exit 0 and `ready` when
|
|
391
432
|
every requirement is present, exit 1 with each MISSING one named
|
|
392
433
|
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}"
|
|
@@ -107,12 +119,16 @@ FRESH_WIN=""
|
|
|
107
119
|
# global config is untouched (a normal tmux session keeps its bar at the
|
|
108
120
|
# bottom).
|
|
109
121
|
sh -c 'S="$1"; L="$3"; tmux() { command tmux -L "$L" "$@"; }; . "$2"' sh "$SESSION" "$SESSIONVIEW_ROOT/tmux/frame.conf" "$SOCK"
|
|
110
|
-
# the agent pane menu (right-click an agent's pane:
|
|
111
|
-
# the user turned it on. Opt-in:
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
|
|
122
|
+
# the agent pane menu (right-click or Option + right-click an agent's pane:
|
|
123
|
+
# Speak / Continue / ...), IF the user turned it on. Opt-in: its two bind-keys
|
|
124
|
+
# are global to the server and replace both of the user's own right-click
|
|
125
|
+
# bindings (MouseDown3Pane, M-MouseDown3Pane). Sourced into the running
|
|
126
|
+
# server, so it works whether or not tmux was already up. Fails open, like the
|
|
127
|
+
# rest of the frame's setup. See tmux/agent-menu.conf. Read once: the frame's
|
|
128
|
+
# own server acts on the same answer below (the Option + right-click
|
|
129
|
+
# pass-through).
|
|
130
|
+
PANE_MENU="$("$SESSIONVIEW_ROOT/bin/sessionview-config" get pane_menu 2>/dev/null || true)"
|
|
131
|
+
if [ "$PANE_MENU" = true ]; then
|
|
116
132
|
"$TMUX_BIN" -L "$SOCK" source-file "$SESSIONVIEW_ROOT/tmux/agent-menu.conf" 2>/dev/null || true
|
|
117
133
|
fi
|
|
118
134
|
# the chosen agent, if the user has one - asked once, remembered, started in
|
|
@@ -182,6 +198,13 @@ o set -w -t "=$F:0" pane-active-border-style "fg=#3a3f4d,bg=#21252e"
|
|
|
182
198
|
o set -w -t "=$F:0" pane-border-lines single
|
|
183
199
|
o bind-key -T root MouseDown1Border "resize-pane -M"
|
|
184
200
|
o bind-key -T root MouseDrag1Border "resize-pane -M"
|
|
201
|
+
# with pane_menu on, an Option + right-click on the client pane goes through to
|
|
202
|
+
# your tmux and its agent menu; the frame's other panes keep the binding this
|
|
203
|
+
# server had. Here, after new-session: before it this server may not exist.
|
|
204
|
+
# Off, nothing is touched. Fails open. See lib/pane-menu.sh.
|
|
205
|
+
if [ "$PANE_MENU" = true ]; then
|
|
206
|
+
{ . "$SESSIONVIEW_ROOT/lib/pane-menu.sh" && sv_frame_option_forward "$FRAME_SOCK"; } >/dev/null 2>&1 || true
|
|
207
|
+
fi
|
|
185
208
|
MAIN="$(o split-window -h -P -F '#{pane_id}' -t "$SIDE" -e "TMUX=" \
|
|
186
209
|
"exec \"$TMUX_BIN\" -L \"$SOCK\" attach -t \"=$SESSION\"")"
|
|
187
210
|
# the frame publishes its own panes, so the sidebar process (which cannot see
|
|
@@ -209,7 +232,9 @@ o resize-pane -t "$SIDE" -x "$WIDTH"
|
|
|
209
232
|
TTY="$(tty 2>/dev/null || echo none)"
|
|
210
233
|
o set-hook -g "client-detached[$$]" "if -F '#{==:#{hook_client},$TTY}' 'kill-session -t =$F'"
|
|
211
234
|
o select-pane -t "$MAIN"
|
|
212
|
-
# pin = the client pane's tty: that is the client the sidebar may move
|
|
213
|
-
|
|
235
|
+
# pin = the client pane's tty: that is the client the sidebar may move. Made
|
|
236
|
+
# 0600: the umask is the subshell's alone, never this script's, which starts
|
|
237
|
+
# the user's tmux server (a server keeps its umask for every pane it opens).
|
|
238
|
+
( umask 077; o display-message -p -t "$MAIN" '#{pane_tty}' >"$PIN" )
|
|
214
239
|
o attach -t "=$F"
|
|
215
240
|
cleanup
|
|
@@ -157,22 +157,28 @@ 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
|
-
# rows are every mail to NAME+ask, with no error
|
|
171
|
+
# rows are every mail to NAME+ask, with no error. Asked of sessionmail's notmuch profile
|
|
172
|
+
# when `message path --notmuch-config` names one (sessionmail 0.3.3), as the tab does;
|
|
173
|
+
# no message, an older one or no profile: notmuch's own default config.
|
|
170
174
|
if command -v notmuch >/dev/null 2>&1; then
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
NMCFG="$(message path --notmuch-config 2>/dev/null)" || NMCFG=""
|
|
176
|
+
NM="notmuch${NMCFG:+ --config=$NMCFG}"
|
|
177
|
+
if [ "$(notmuch ${NMCFG:+"--config=$NMCFG"} config get index.header.Type 2>/dev/null)" = Type ] &&
|
|
178
|
+
[ "$(notmuch ${NMCFG:+"--config=$NMCFG"} config get index.header.Project 2>/dev/null)" = Project ]; then
|
|
179
|
+
say PASS "notmuch indexes Type and Project${NMCFG:+ ($NMCFG)}"
|
|
174
180
|
else
|
|
175
|
-
say WARN "notmuch does not index Type and Project - the Asks rows show every mail to NAME+ask:
|
|
181
|
+
say WARN "notmuch${NMCFG:+ ($NMCFG)} does not index Type and Project - the Asks rows show every mail to NAME+ask: $NM config set index.header.Type Type; $NM config set index.header.Project Project; $NM reindex '*'"
|
|
176
182
|
fi
|
|
177
183
|
else say WARN "notmuch not on PATH - the messages tab has no sidebar (brew install notmuch)"; fi
|
|
178
184
|
# optional
|