Files
mesh-catalog/modules/dunst/cmd/dunst-tools/main.go
T
jochen 8bbea4a2ad dunst: the notifier as a module, claiming node-notifier and serving send and history (hq ADR 0208)
Owns one dunstrc (the laptop's, in the interface face, its menu on the seat's
dmenu command) and the dunstrc.d directory for other modules' rules; D-Bus
starts it, so nothing else does. Go tools over the session bus.
2026-10-04 13:15:39 +02:00

92 lines
3.6 KiB
Go

// dunst's Go tools bundle (novox/hq ADR 0188, ADR 0193, ADR 0208): its implementation of
// node-notifier's verbs `send` and `history`, and its own tools, served by the node's runtime as the
// operator account. Everything here goes over the account's session bus; none of it needs the screen.
package main
import (
"fmt"
"os"
stdio "git.novox.be/novox/mesh-sdk/go"
)
func main() {
if err := stdio.Serve("", tools()); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func tools() []stdio.Tool {
return []stdio.Tool{
{
Name: "node-notifier.send",
Description: "Show a notification on the operator's desktop: a title, a body, an urgency (low, " +
"normal, critical), and optionally the sending application's name, an icon and how long it stays. " +
"Answers the notification's id.",
Input: map[string]any{
"type": "object",
"properties": map[string]any{
"summary": map[string]any{"type": "string", "description": "the title"},
"body": map[string]any{"type": "string", "description": "the text; simple markup (<b>, <i>, <u>, <a href>) is shown"},
"urgency": map[string]any{"type": "string", "enum": urgencies, "description": "default normal"},
"app_name": map[string]any{"type": "string", "description": "who it is from (default: mesh); a notifier rule can match it"},
"icon": map[string]any{"type": "string", "description": "an icon name from the icon theme, or a file"},
"expire_ms": map[string]any{"type": "integer", "description": "how long it stays; 0 until dismissed (default: the urgency's own)"},
"category": map[string]any{"type": "string", "description": "a notification category, e.g. email.arrived"},
"replace_id": map[string]any{"type": "integer", "description": "replace the notification with this id instead of adding one"},
},
"required": []string{"summary"},
},
Run: func(args map[string]any) (any, error) {
n, err := notificationOf(args)
if err != nil {
return nil, err
}
return Send(n)
},
},
{
Name: "node-notifier.history",
Description: "The notifications the operator was shown, newest first: id, application, title, " +
"body, urgency and how long ago.",
Input: map[string]any{
"limit": map[string]any{"type": "integer", "description": "at most this many (default 20, at most 200)"},
},
Run: func(args map[string]any) (any, error) {
limit, err := whole(args, "limit", 20, 1, 200)
if err != nil {
return nil, err
}
return History(limit)
},
},
{
Name: "dunst_pause",
Description: "Do not disturb: hold every new notification back until resumed. They are shown then, not lost.",
Run: func(map[string]any) (any, error) { return SetPaused(true) },
},
{
Name: "dunst_resume",
Description: "End do-not-disturb: notifications held back are shown.",
Run: func(map[string]any) (any, error) { return SetPaused(false) },
},
{
Name: "dunst_close_all",
Description: "Close every notification on screen. They stay in the history.",
Run: func(map[string]any) (any, error) { return CloseAll() },
},
{
Name: "dunst_rules",
Description: "The notifier's rules in force — each rule's name, whether it is enabled, what it " +
"matches and what it sets — and the files they come from (the mesh's dunstrc, then dunstrc.d).",
Run: func(map[string]any) (any, error) { return Rules() },
},
{
Name: "dunst_count",
Description: "How many notifications are shown, waiting and in the history, and whether do-not-disturb is on.",
Run: func(map[string]any) (any, error) { return Count() },
},
}
}