Parity gaps: the finished-reply notice (bell and OSC 9 while unfocused; notify: false), /rename, /search over this machine's sessions, /memory shows the server's memory
ci / check (push) Waiting to run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
HomerandClaude Opus 5.5 committed 2026-11-10 12:23:17 +00:00
1 parent a4027d5626
commit a3e9a43dd6
11 files changed
+256 -13

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
// The finished-reply notice: when a reply finishes, or the agent waits for an answer, while the
// terminal is not focused, the bell rings and the terminal is asked for a desktop notification
// (OSC 9 — iTerm2, WezTerm, kitty, Windows Terminal, foot and others show it; the rest ignore it).
// It names the session and what happened, never what the reply says: a desktop notification may
// be seen by anyone near the screen. `notify: false` turns it off.
/** The words of the notice: the session's title (or "LLeMbas") and what happened. */
export function noticeText(title: string | undefined, what: "finished" | "waiting" | "failed"): string {
const name = (title ?? "").replace(/[\u0000-\u001f\u007f-\u009f]/g, " ").replace(/\s+/g, " ").trim().slice(0, 80) || "LLeMbas"
const said = what === "finished" ? "finished" : what === "waiting" ? "waits for you" : "stopped with an error"
return `${name}: ${said}`
}
/** The bytes sent to the terminal: OSC 9 with the text, then the bell. */
export function noticeSequence(text: string): string {
return `\x1b]9;${text.replace(/[\u0000-\u001f\u007f-\u009f;]/g, " ")}\x07\x07`
}
/** Follows the terminal's focus (OpenTUI's focus and blur events, from focus reporting) and says
* whether a notice is due: only once the terminal has said it lost focus — a terminal that
* reports nothing is taken as focused, so it never rings for nothing. */
export class FocusWatch {
focused = true
constructor(on?: (event: "focus" | "blur", fn: () => void) => void) {
on?.("focus", () => (this.focused = true))
on?.("blur", () => (this.focused = false))
}
}