| Age | Commit message (Collapse) | Author |
|
red until seen
|
|
the menu
|
|
replies once
|
|
crash or restore
|
|
menu item and reload-agents
|
|
the ! was the color of the name, read as part of it, and pushed high
names two characters out of line. it is now peach (herdr's palette, no
status uses it) in a fixed-width column every row has, so names line up.
a low agent's name is dimmed to 0.5 (0.7 was hard to see).
|
|
like "mark as unread" in mail: an agent you have seen (idle) becomes done
again, last among done agents of its importance, with no sound or
notification. it stays done until you come back to it: leave its tmux
window and return, or jump to it. marked while you look at it, it holds
until you look away (`held`); a new turn clears it. only idle agents can
be marked.
- daemon: `pane.mark_unread` on the hook socket; the watcher applies it
after the tick's observations (mark_unread, advance's hold rule).
- `dingger unread [--pane]`: refuses done, working, blocked, and panes
without an agent; returns once the agent shows as done.
- pi: /unread (refused while the agent works or is blocked).
- panel: right-click an idle agent in the full list, "Mark as unread".
- search: ⌘U or right-click marks the selected idle agent; the footer
offers ⌘U when it applies; search stays open.
tests: unit (hold, jump, new turn, idle only), e2e step 22 (queue
position, hold, look away and back, jump, refusals, no sound, menu, the
extension), pi-live in real pi 1.4 (a mark, not a turn: an unknown
command would also end done), swift selftest (menu only for idle, footer).
|
|
within a status, more important agents are listed first, and so jumped to
first; status stays first. a high agent shows a bold ! before its name, a
low agent's name is lightly dimmed with "low" on its second line, and it
makes no sound (it still notifies and waits in line).
in pi, /importance high|normal|low (completes the levels; none once one is
typed out, so Enter runs it). the extension saves it in the session as a
custom entry (dingger-importance), so /reload, restarts, /resume and
restore bring it back; /new starts at normal. it shows a level other than
normal in pi's footer, emits dingger:importance { level } for other
extensions, and sends it with every report. for other agents, `dingger
importance [level] [--pane]`; it refuses a pi that reports itself, whose
saved level would win.
the daemon stays the one writer of pane state: it writes
@dingger_importance (unset for normal), which goes with the agent and
survives a daemon restart. `dingger status` marks high and low.
tests: e2e step 21 (order, the option, no sound for low, the menu bar,
the command, the extension through a harness that now matches pi's
extension API), a DINGGER_SOUND seam so sounds are observable, and a
status-line check that read the counts once (flaky) now polls.
pi-live: /importance in real pi 1.4, its footer and session entry, and the
level after a restore; every pi there now uses the test's agent directory
(a restored pi read the user's). negative controls fail each part.
|
|
a pane in several sessions (a session group, `new-session -t`, or a
linked window) was listed once per session: every agent of a group showed
twice in the menu, panel, search, `dingger status`, and the counts. and
snapshots saved each session of a group with its own copy of the windows,
so restore would have rebuilt them twice and resumed each agent twice on
one session file.
- a pane keeps its first listing (tmux lists sessions by name) and is
attended if the user looks at it through any session of the group.
- snapshots keep the first session of each group; the others are not
restored.
e2e step 19 covers both; the previous binaries fail it. two checks (step
11's and this one) waited for idle after a turn that started from idle,
which passed before the turn was even processed: they now wait for
working first, and the negative control for group attendance fails as it
should. step 18 now waits for the snapshot it later restores from.
|
|
within a status, the menu, panel, search, and `dingger status` listed done
and blocked agents oldest first (the queue), and the rest by place. now
working and idle agents are most recent first: the first idle row is the
agent that finished, or that the user looked at, last.
@dingger_since now means when the pane entered its current status, for
every status (it was set only while the pane needed the user), and
survives a daemon restart. the queue selects done and blocked panes by
status, no longer by having a stamp. one ordering rule each in Rust
(watcher::list_order) and Swift (listedBefore), with tests that fail on
the old order; e2e step 11 makes an agent finish while watched and checks
it moves to the top of the idle rows.
agents idle since before this change share one stamp and keep their place
order until they next change.
|
|
when tmux stops (and its sessions are missing from the running server, or
no server runs), the daemon publishes the restore offer: offer.json for the
menu bar app and @dingger_restore for the status line, withdrawn once
restored or dismissed.
- panel: a first row "↺ Restore 9 sessions · 22 agents" with when it was
saved and how many agents were mid-turn; clicking restores, "Not now"
dismisses. an offer shows the panel like a waiting agent; off stays off.
- menu: the offer on top; restore all, one session, or not now.
- status line: a clickable blue ↺N before the clock.
- restore runs through the user's login shell, as a terminal starts tmux,
so restored panes get a real environment, not launchd's; --report writes
restore.log and notifies a summary. restore --dismiss.
- commands log only warnings by default; SIGPIPE ends them quietly.
e2e: the offer through the real menu bar binary, the summary notification,
the offer clearing, a restore with no tmux running, and not now staying
dismissed when a terminal starts tmux. the second test daemon is started
directly (it leaked through a function's $! before, and dozens of leaked
daemons fought over the test socket and loaded the machine); each run uses
its own socket and checks its daemons stop.
|
|
a centered, non-activating key panel that lists every agent and jumps to
the chosen one through the same dingger focus path as a row click.
- fzf-style matching: each word must match one of name, session, window,
harness, status, or directory, letters in order; the best alignment wins
(word starts and consecutive runs score higher), matched title letters
are highlighted.
- empty query keeps the menu's order, so enter jumps to the top waiting
agent.
- the selection follows the agent, not the position, as states change;
the list scrolls to keep it visible.
- keys: arrows, ctrl+n/p, ctrl+j/k, enter, esc, ctrl+u; the shortcut again
or clicking elsewhere closes it.
- search_hotkey setting; an unedited config file is upgraded. menu item
"Search Agents...". rows carry the pane's directory.
- --print-search and --snapshot-search debug flags; the panel's background
and snapshot code are shared.
selftest covers matching, ranking, highlighting, and selection; e2e step
15 checks queries through the real binary (fails when search only looks at
titles). e2e resolves relative binary paths, which tmux hooks need.
|
|
launchd starts the menu bar app with PATH=/usr/bin:/bin:/usr/sbin:/sbin,
so the `dingger focus` it runs for every click (panel rows, menu rows, the
jump shortcut) could not find homebrew's tmux and failed with a misleading
"no tmux client attached"; the app discarded the error. dingger now finds
tmux on PATH or in the usual install locations (DINGGER_TMUX overrides),
reports a missing tmux as such, and the app logs failed jumps.
also: panel rows own every click inside them (labels took the clicks and
counted as window-drag background).
e2e step 14 repeats the menu bar row click and dingger focus under
launchd's environment; both fail with the previous binaries.
|
|
- contrast: the summary used attributed-string colors (never vibrant) and
the subtitles a vibrant system color, so they blended differently over
light and dark desktops. the panel now uses herdr's mocha colors
explicitly over a dark tint, identical on any background.
- layout: compact in "when agents are waiting"; in "always" a show all /
show less toggle switches to the full list (waiting, separator, rest).
- rows are single-line with a trailing ellipsis instead of wrapping.
- render only when the content changes, and log each render, instead of
rebuilding every view every second.
- --snapshot-panel renders the real panel offscreen over white and black
after a different first render (stale content would show).
- jump shortcut ctrl+opt+cmd+u (jump_hotkey) runs dingger focus; shortcuts
are registered by id. an unedited first config file is upgraded.
selftest covers the layout rules and content; e2e step 13 checks the full
list, its separator, and the toggle labels.
|
|
a non-activating HUD panel (every Space, over full-screen apps, never takes
focus) listing the agents waiting for you, with working and idle summarized
on one line; rows jump to the agent, drag moves the panel and it remembers
its place. modes: when agents are waiting (default), always, off; ctrl+opt+
cmd+e shows or hides it on top of the mode, and a manual hide lasts until
another agent starts waiting. the shortcut is a carbon hotkey (no
accessibility permission; clashes are reported in the menu) configured in
~/.config/dingger/config.toml, reloaded on save. the menu bar app is split
into model, panel, hotkey and main.
tested: --selftest checks the visibility rules (it fails if a newly waiting
agent no longer re-shows a dismissed panel); e2e step 13 checks the panel
content through the real binary.
|