package controllogic import "strings" // Dialog is a user-facing notification or input request emitted by an // action.dialog node. It is delivered to connected clients whose identity // matches Users/Groups (both empty = everyone). For an "input" dialog the // client's response is written back to Target (a "ds:name" reference, e.g. // "srv:approved") so control logic can read it on a later activation. type Dialog struct { ID string `json:"id"` Kind string `json:"kind"` // "info" | "error" | "input" Title string `json:"title"` Message string `json:"message"` Target string `json:"target,omitempty"` Users []string `json:"users,omitempty"` Groups []string `json:"groups,omitempty"` } // Notifier delivers control-logic dialogs to connected clients. The server // implements it; the engine calls Notify when an action.dialog node runs. // Notify must not block (the hub fans out without waiting on slow clients). type Notifier interface { Notify(Dialog) } // splitCSV parses a comma-separated user/group filter into trimmed, // non-empty tokens. An empty string yields a nil slice (no filter). func splitCSV(s string) []string { var out []string for _, p := range strings.Split(s, ",") { if t := strings.TrimSpace(p); t != "" { out = append(out, t) } } return out }