- Hook handler now loads .env.daemon for proper config (plugin URL/secret, bot user ID) - Hook logs to /tmp/status-watcher.log instead of /dev/null - Added .env.daemon config file (.gitignored - contains tokens) - Added start-daemon.sh convenience script - Plugin mode: mobile fallback updates post message field with formatted markdown - Fixed unbounded lines array in status-watcher (capped at 50) - Added session marker to formatter output for restart recovery - Go plugin: added updatePostMessageForMobile() for dual-render strategy (webapp gets custom React component, mobile gets markdown in message field) Fixes: daemon silently dying, no plugin connection, mobile showing blank posts
39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
// broadcastUpdate sends a WebSocket event to all clients viewing the given channel.
|
|
// The event is auto-prefixed by the SDK to "custom_com.openclaw.livestatus_update".
|
|
// All values must be gob-serializable primitives (string, int64, []string, etc.).
|
|
// Complex types like []SessionData must be JSON-encoded to a string first.
|
|
func (p *Plugin) broadcastUpdate(channelID string, data SessionData) {
|
|
// Serialize children to JSON string — gob cannot encode []SessionData
|
|
var childrenJSON string
|
|
if len(data.Children) > 0 {
|
|
b, err := json.Marshal(data.Children)
|
|
if err == nil {
|
|
childrenJSON = string(b)
|
|
}
|
|
}
|
|
|
|
payload := map[string]interface{}{
|
|
"post_id": data.PostID,
|
|
"session_key": data.SessionKey,
|
|
"agent_id": data.AgentID,
|
|
"status": data.Status,
|
|
"lines": data.Lines,
|
|
"elapsed_ms": data.ElapsedMs,
|
|
"token_count": data.TokenCount,
|
|
"children_json": childrenJSON,
|
|
"start_time_ms": data.StartTimeMs,
|
|
}
|
|
|
|
p.API.PublishWebSocketEvent("update", payload, &model.WebsocketBroadcast{
|
|
ChannelId: channelID,
|
|
})
|
|
}
|