helmd v2: Go-server som styr agent i tmux — REST+SSE, frågedetektor, fildelning, ntfy, CI-release
- tmux som sanningskälla (agentoberoende, överlever omstart via adoption) - API: sessions, prompt, question/answer, keys, mode, config, shares, notify, events - frågedetektor testad mot riktiga agy 1.1.9-dumpar + mock - integrationstest: 26 tester i isolerad debian-container (scripts/run-integration.sh) - e2e-verifierad mot riktig agy (trust-fråga -> svar -> prompt) - .gitea/workflows/helmd-release.yaml -> rullande helmd-latest (x64+arm64) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
68
helmd/ntfy.go
Normal file
68
helmd/ntfy.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Ntfy struct {
|
||||
cfg *NtfyConfig
|
||||
}
|
||||
|
||||
// Publish posts a message to the configured ntfy server. Errors are
|
||||
// logged, never fatal — notifications must not take the server down.
|
||||
func (n *Ntfy) Publish(topic, title, message, priority string) error {
|
||||
if !n.cfg.Enabled || n.cfg.Server == "" {
|
||||
return nil
|
||||
}
|
||||
if topic == "" {
|
||||
topic = n.cfg.Topic
|
||||
}
|
||||
url := strings.TrimRight(n.cfg.Server, "/") + "/" + topic
|
||||
req, err := http.NewRequest("POST", url, strings.NewReader(message))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if title != "" {
|
||||
req.Header.Set("X-Title", title)
|
||||
}
|
||||
if priority != "" {
|
||||
req.Header.Set("X-Priority", priority)
|
||||
}
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Printf("ntfy: %v", err)
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 300 {
|
||||
err := fmt.Errorf("ntfy: %s -> %s", topic, resp.Status)
|
||||
log.Print(err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Ntfy) Question(session string, q *Question) {
|
||||
if !n.cfg.NotifyOnQuestion {
|
||||
return
|
||||
}
|
||||
var b strings.Builder
|
||||
b.WriteString(q.Text)
|
||||
for i, o := range q.Options {
|
||||
b.WriteString("\n")
|
||||
if o.Num > 0 {
|
||||
fmt.Fprintf(&b, "%d. %s", o.Num, o.Label)
|
||||
} else {
|
||||
fmt.Fprintf(&b, "- %s", o.Label)
|
||||
}
|
||||
if i == q.Selected {
|
||||
b.WriteString(" ←")
|
||||
}
|
||||
}
|
||||
n.Publish("", "helm: "+session+" väntar på svar", b.String(), "high")
|
||||
}
|
||||
Reference in New Issue
Block a user