Add comprehensive Claude Code monitoring and realtime streaming to the K8s dashboard. Includes API endpoints for health, stats, summary, inventory, and live event streaming. Frontend provides overview, usage, inventory, debug, and live feed views.
80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/will/k8s-agent-dashboard/internal/claude"
|
|
)
|
|
|
|
type BacklogResponse struct {
|
|
Limit int `json:"limit"`
|
|
Events []claude.Event `json:"events"`
|
|
}
|
|
|
|
func GetClaudeLiveBacklog(loader ClaudeLoader) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
limit := 200
|
|
if l := r.URL.Query().Get("limit"); l != "" {
|
|
if n, err := strconv.Atoi(l); err == nil && n > 0 {
|
|
limit = n
|
|
if limit > 1000 {
|
|
limit = 1000
|
|
}
|
|
}
|
|
}
|
|
|
|
historyPath := filepath.Join(loader.ClaudeDir(), "history.jsonl")
|
|
lines, err := claude.TailLastNLines(historyPath, limit)
|
|
if err != nil {
|
|
respondError(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
events := make([]claude.Event, 0, len(lines))
|
|
for _, line := range lines {
|
|
ev := parseHistoryLine(line)
|
|
events = append(events, ev)
|
|
}
|
|
|
|
respondJSON(w, http.StatusOK, BacklogResponse{
|
|
Limit: limit,
|
|
Events: events,
|
|
})
|
|
}
|
|
}
|
|
|
|
func parseHistoryLine(line string) claude.Event {
|
|
data := map[string]any{
|
|
"rawLine": line,
|
|
}
|
|
|
|
var jsonData map[string]any
|
|
if err := json.Unmarshal([]byte(line), &jsonData); err != nil {
|
|
data["parseError"] = err.Error()
|
|
} else {
|
|
data["json"] = jsonData
|
|
|
|
summary := map[string]string{}
|
|
if v, ok := jsonData["sessionId"].(string); ok {
|
|
summary["sessionId"] = v
|
|
}
|
|
if v, ok := jsonData["project"].(string); ok {
|
|
summary["project"] = v
|
|
}
|
|
if v, ok := jsonData["display"].(string); ok {
|
|
summary["display"] = v
|
|
}
|
|
data["summary"] = summary
|
|
}
|
|
|
|
return claude.Event{
|
|
TS: time.Now(),
|
|
Type: claude.EventTypeHistoryAppend,
|
|
Data: data,
|
|
}
|
|
}
|