Files
mesh-catalog/modules/slack/cmd/slack-tools/main.go
T
jochen 75f25fca21 Add slack and jetbrains-toolbox: one start each, the apps kept as found
Slack comes from the AUR and Toolbox from JetBrains' self-updating tarball,
so neither is declared: the host installs official packages only, and a
pinned archive would fight Toolbox's own updates. Slack's start and the
operator's i3 window rules become one node-display-session contribution,
because Slack's own launch-on-login is a symlink in ~/.config/autostart.
Toolbox keeps its own autostart entry as its one start. The shared
desktop.go header now names all four bundles.
2026-10-05 15:05:55 +02:00

85 lines
3.5 KiB
Go

// The slack module's Go tools bundle (novox/hq ADR 0188, ADR 0193, ADR 0208): the Slack desktop app
// in the operator's session, served by the node's runtime as the operator account. The module holds
// no seat, so every tool is its own.
//
// Slack's sessions are the operator's: the tools never read its cookies, local storage or the key in
// Local State, and no answer carries a token, a cookie, a message, or the name of a person, channel
// or workspace. Accounts and workspaces are counted, never named.
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)
}
}
var machine = NewMachine()
func tools() []stdio.Tool {
return []stdio.Tool{
{
Name: "slack_status",
Description: "Slack: whether it runs (the main process's pid, since, and the scope it runs in; how " +
"many helper processes), the installed version and whether it is outside the official " +
"repositories, where its output goes, whether its icon sits in a tray, who shows its " +
"notifications, its launch and tray switches and notification method, how many accounts and " +
"workspaces it is signed in to (counted, never named), and what starts it at login. (r)",
Run: func(map[string]any) (any, error) { return machine.Status() },
},
{
Name: "slack_log",
Description: "The last lines of Slack's own log: source browser (the main process, the default) or " +
"webapp (the web app's console). With problems, only error and warn entries. Tokens, cookies, " +
"message and notification text, and the names of people, channels and workspaces are " +
"replaced by <hidden>. (r)",
Input: map[string]any{
"lines": map[string]any{"type": "integer", "description": "how many lines (default 100, at most 2000)"},
"source": map[string]any{"type": "string", "enum": []string{"browser", "webapp"}, "description": "browser (default) or webapp"},
"problems": map[string]any{"type": "boolean", "description": "only error and warn entries (default false)"},
},
Run: func(args map[string]any) (any, error) {
n, err := whole(args, "lines", 100, 1, 2000)
if err != nil {
return nil, err
}
source, err := text(args, "source", false)
if err != nil {
return nil, err
}
if source == "" {
source = "browser"
}
problems, err := flag(args, "problems", false)
if err != nil {
return nil, err
}
return machine.Log(source, n, problems)
},
},
{
Name: "slack_restart",
Description: "End Slack (asked first, then forced after 8 s) and start it again to the tray in the " +
"operator's desktop session, under the account's service manager, its output in the journal. " +
"Answers the pids ended and the new main process. Needs someone logged in to the desktop. (a)",
Run: func(map[string]any) (any, error) { return machine.Restart() },
},
{
Name: "slack_check",
Description: "Check what the module promises: Slack is installed; it has exactly one start (the " +
"module's line in i3's configuration; no XDG autostart entry, no other exec); the window rules " +
"are the module's, not repeated in a file of the operator's; one Slack runs in the session with " +
"its output read (a pipe nobody reads makes its writes fail with EPIPE); its icon is in a tray; " +
"a notifier owns the session bus's notification name. Answers ok and each finding with what to do. (r)",
Run: func(map[string]any) (any, error) { return machine.Check() },
},
}
}