// 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() { go sayStarted() go watchPaused() 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, how long it stays and " + "the answers it offers (actions: token and label each). Answers the notification's id; the answer " + "the operator chooses is said later as the event action-chosen {id, token, machine}. A secret " + "or transient one is kept out of the history.", 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 (, , , ) 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"}, "transient": map[string]any{"type": "boolean", "description": "keep it out of the history (default false)"}, "secret": map[string]any{"type": "boolean", "description": "it carries something shown once, such as a " + "link's code: transient, in the category " + SecretCategory + ", and never in the history (default false)"}, "actions": map[string]any{"type": "array", "description": "at most 4 answers the notification offers, " + "each {token, label}; the chosen token is said as the event action-chosen", "items": map[string]any{"type": "object", "properties": map[string]any{ "token": map[string]any{"type": "string"}, "label": map[string]any{"type": "string"}}}}, }, "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. A secret one (a link's code) is never shown; withheld counts them.", 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_reload", Description: "Make the running notifier read its configuration again now (dunstrc, then dunstrc.d), " + "keeping what is on screen and in the history. The mesh does this by itself when it rewrites " + "dunstrc, for instance after a font-size or width setting changes. Answers the files read and the " + "font, font size and width they set, with the file each came from.", Run: func(map[string]any) (any, error) { return Reload() }, }, { 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() }, }, } }