Show one chip per session, right of the clock

The panel showed a single aggregate: the most urgent session, plus a "+N"
for the others. That answers "what is the worst thing happening", which
is not the question with five projects open -- "what is each of them
doing" needs each of them on screen.

Each session now gets a chip: state glyph plus a three-character project
label, in the centre box just right of the clock. Time in state stays on
the first chip only; five counters side by side are a row of numbers,
not an answer.

Labels are initials for multi-segment names, first letters otherwise.
Initials rather than a prefix, because a prefix collapses dev-skills and
dev-conventions onto the same "dev" -- exactly the pair that has to stay
apart. Collisions, including two sessions in one project where the cwd
is identical, take a digit: ds, ds2, ds3.

Two rules keep a label still, and the feature is worthless without them.
Assignment runs oldest-session-first, so a session starting now takes
the suffix instead of displacing one already on screen; and a label
belongs to its session until it ends, even after whatever forced the
digit has closed. A label that moves under your hand is worse than one
carrying a digit that no longer looks necessary.

The zellij tab name was considered as the label source and dropped. It
arrives asynchronously from dump-layout, so a sticky label would freeze
whatever the project name produced first and never adopt it. Digits
already separate same-project sessions, so the tab name buys nothing
here and stays where it is useful, in the menu.

Menu rows now lead with the same label, so the mapping from "ds" to
dev-skills is read rather than guessed.
This commit is contained in:
av
2026-08-09 18:45:44 +03:00
parent 58409106c3
commit a4e5d653de
8 changed files with 381 additions and 116 deletions
+56 -9
View File
@@ -4,25 +4,70 @@
Code ждёт меня прямо сейчас?**
Когда открыто несколько сессий в разных проектах, дорого не «не знать, чем
каждая занята», а не заметить, что одна из них встала час назад. Панель
называет сессию, а не только состояние.
каждая занята», а не заметить, что одна из них встала час назад.
Справа от часов стоит по чипу на сессию — значок состояния и трёхбуквенное
имя проекта:
```
◉ ds ● dc ● ds2 ○ pps ◌ umb 9:41
│ │ │ │ └ umbar, тихо
│ │ │ └ pet-project-server, работает
│ │ └ вторая сессия в dev-skills, ждёт
│ └ dev-conventions, ждёт
└ dev-skills, упёрлась в разрешение
```
## Состояния
| В панели | Состояние | Что значит |
| Значок | Состояние | Что значит |
|---|---|---|
| диск в кольце | `blocked` | упёрлась в запрос разрешения — без вас не сдвинется |
| закрашенный диск | `waiting` | ход закончен, ждёт вашего ввода |
| кольцо | `busy` | работает |
| тусклое пунктирное кольцо | `idle` | запущена, но ничего не просили, либо ничего не запущено |
| тусклое пунктирное кольцо | `idle` | запущена, но ничего не просили |
`blocked` и `waiting` разведены намеренно. Слитые в одно «требует внимания»,
законченная задача выглядит так же срочно, как заблокированная, — а именно это
различие и решает, переключаться сейчас или после текущей мысли.
Панель показывает **самую приоритетную** сессию и счётчик `+N`, если в том же
состоянии есть другие. Внутри состояния выигрывает **самая давняя**: забывается
та, что ждёт дольше всех, а не последняя.
Чипы идут по срочности, а внутри одного состояния первой стоит **самая
давняя**: забывается та, что ждёт дольше всех, а не последняя. Время в
состоянии показывается только у первого чипа: пять счётчиков рядом — это
ряд чисел, а не ответ на вопрос.
## Метки чипов
Имя проекта сжимается до трёх знаков: если в имени несколько сегментов
(`-`, `_`, camelCase) — инициалы, иначе первые буквы.
| Проект | Чип |
|---|---|
| `dev-skills` | `ds` |
| `dev-conventions` | `dc` |
| `pet-project-server` | `pps` |
| `claude-code-gnome-extension` | `ccg` |
| `jellybit` | `jel` |
Инициалы, а не просто префикс, важны больше, чем кажется: префикс слил бы
`dev-skills` и `dev-conventions` в один `dev` — ровно тот случай, который надо
развести.
При совпадении — включая две сессии в одном проекте, где `cwd` один и тот же —
добавляется цифра по старшинству: `ds`, `ds2`, `ds3`. Цифра съедает базу, а не
удлиняет метку, чтобы ряд не расползался.
Два правила держат метки на месте, и без них вся затея рассыпается:
- Назначение идёт **от самой давней сессии**, так что цифру берёт только что
запущенная, а не та, на которую ты сейчас смотришь.
- Выданная метка закреплена за сессией до её конца — даже после того, как
закрылась сессия, из-за которой появилась цифра. Метка, переехавшая под
рукой, хуже метки с цифрой, которая уже не выглядит нужной.
Сокращение отключается в настройках — тогда в чипах полные имена проектов.
В меню строка начинается с той же метки, чтобы соответствие «`ds` — это
dev-skills» читалось, а не угадывалось.
**Уведомлений на рабочий стол нет** — сознательно. `notify-send` из хука было бы
куда дешевле сделать, но форма неверная: сессия, ждущая двадцать минут, должна
@@ -121,11 +166,13 @@ gnome-extensions enable claude-code-status@git.vakhrushev.me
```sh
gjs -m tests/test-sessions.js # чтение состояния, порядок, живость, слежение
gjs -m tests/test-abbrev.js # метки чипов: сжатие, коллизии, липкость
tests/test-hook.sh # события -> состояния, блокировка, снос файлов
```
`lib/sessions.js` намеренно ничего не импортирует из `resource:///org/gnome/shell`
— именно это позволяет гонять его в обычном `gjs`, вне композитора.
`lib/sessions.js` намеренно ничего не импортирует из `resource:///org/gnome/shell`,
а `lib/abbrev.js` — вообще ничего. Именно это позволяет гонять их вне
композитора — в `gjs`, а `abbrev` и в `node`.
Чтобы посмотреть сырые события хуков, создайте файл-маркер, и каждое событие
будет дописываться в него: