diff --git a/.gitignore b/.gitignore index f549001..1176b49 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,9 @@ docs/ .worktrees/ .fellowship/ cli/fellowship +.DS_Store +.fastembed_cache/ +.shire/ +.superpowers/ +scripts/ +shire.toml diff --git a/cli/cmd/fellowship/main.go b/cli/cmd/fellowship/main.go index 96cd454..8322715 100644 --- a/cli/cmd/fellowship/main.go +++ b/cli/cmd/fellowship/main.go @@ -913,7 +913,7 @@ func runDashboard(d *db.DB, args []string) int { poll := fs.Int("poll", 5, "Poll interval in seconds") fs.Parse(args) - srv := dashboard.NewServer(d, *poll) + srv := dashboard.NewServer(d, gitRootOrCwd(), *poll) addr := fmt.Sprintf("localhost:%d", *port) url := fmt.Sprintf("http://%s", addr) diff --git a/cli/go.mod b/cli/go.mod index 182035b..47c4030 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -2,7 +2,10 @@ module github.com/justinjdev/fellowship/cli go 1.25.5 -require zombiezen.com/go/sqlite v1.4.2 +require ( + github.com/gorilla/websocket v1.5.3 + zombiezen.com/go/sqlite v1.4.2 +) require ( github.com/dustin/go-humanize v1.0.1 // indirect diff --git a/cli/go.sum b/cli/go.sum index 56f4fe4..23c5814 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -4,6 +4,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= diff --git a/cli/internal/dashboard/commands.go b/cli/internal/dashboard/commands.go new file mode 100644 index 0000000..2a9d71a --- /dev/null +++ b/cli/internal/dashboard/commands.go @@ -0,0 +1,120 @@ +package dashboard + +import ( + "encoding/json" + "net/http" + "time" +) + +type SpawnQuestRequest struct { + Task string `json:"task"` + Branch string `json:"branch,omitempty"` + Company string `json:"company,omitempty"` +} + +type SpawnScoutRequest struct { + Question string `json:"question"` +} + +type QuestIDRequest struct { + QuestID string `json:"quest_id"` +} + +type QueuedResponse struct { + Queued bool `json:"queued"` + CommandID string `json:"command_id"` +} + +func (s *Server) handleSpawnQuest(w http.ResponseWriter, r *http.Request) { + var req SpawnQuestRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + if req.Task == "" { + http.Error(w, "task is required", http.StatusBadRequest) + return + } + params, _ := json.Marshal(req) + cmd, err := EnqueueCommand(s.gitRoot, ActionSpawnQuest, params) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + s.hub.Broadcast(WSEvent{Type: "command-queued", CommandID: cmd.ID, Timestamp: time.Now().Unix()}) + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(QueuedResponse{Queued: true, CommandID: cmd.ID}) +} + +func (s *Server) handleSpawnScout(w http.ResponseWriter, r *http.Request) { + var req SpawnScoutRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + if req.Question == "" { + http.Error(w, "question is required", http.StatusBadRequest) + return + } + params, _ := json.Marshal(req) + cmd, err := EnqueueCommand(s.gitRoot, ActionSpawnScout, params) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + s.hub.Broadcast(WSEvent{Type: "command-queued", CommandID: cmd.ID, Timestamp: time.Now().Unix()}) + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(QueuedResponse{Queued: true, CommandID: cmd.ID}) +} + +func (s *Server) handleKillQuest(w http.ResponseWriter, r *http.Request) { + var req QuestIDRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + if req.QuestID == "" { + http.Error(w, "quest_id is required", http.StatusBadRequest) + return + } + params, _ := json.Marshal(req) + cmd, err := EnqueueCommand(s.gitRoot, ActionKillQuest, params) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + s.hub.Broadcast(WSEvent{Type: "command-queued", CommandID: cmd.ID, Timestamp: time.Now().Unix()}) + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(QueuedResponse{Queued: true, CommandID: cmd.ID}) +} + +func (s *Server) handleRestartQuest(w http.ResponseWriter, r *http.Request) { + var req QuestIDRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + if req.QuestID == "" { + http.Error(w, "quest_id is required", http.StatusBadRequest) + return + } + params, _ := json.Marshal(req) + cmd, err := EnqueueCommand(s.gitRoot, ActionRestartQuest, params) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + s.hub.Broadcast(WSEvent{Type: "command-queued", CommandID: cmd.ID, Timestamp: time.Now().Unix()}) + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(QueuedResponse{Queued: true, CommandID: cmd.ID}) +} + +func (s *Server) handleCommands(w http.ResponseWriter, r *http.Request) { + q, err := LoadCommandQueue(s.gitRoot) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(q.Commands) +} diff --git a/cli/internal/dashboard/data.go b/cli/internal/dashboard/data.go new file mode 100644 index 0000000..0b85d72 --- /dev/null +++ b/cli/internal/dashboard/data.go @@ -0,0 +1,168 @@ +package dashboard + +import ( + "context" + "encoding/json" + "net/http" + "os" + "path/filepath" + "strings" + + "github.com/justinjdev/fellowship/cli/internal/autopsy" + "github.com/justinjdev/fellowship/cli/internal/db" + "github.com/justinjdev/fellowship/cli/internal/tome" +) + +// GET /api/autopsies — list all autopsy records +// GET /api/autopsies/ — single autopsy detail +func (s *Server) handleAutopsies(w http.ResponseWriter, r *http.Request) { + suffix := strings.TrimPrefix(r.URL.Path, "/api/autopsies") + suffix = strings.TrimPrefix(suffix, "/") + + // Individual autopsy lookup not supported via SQLite API; scan all and filter. + var records []autopsy.Autopsy + err := s.db.WithConn(context.Background(), func(conn *db.Conn) error { + var loadErr error + records, loadErr = autopsy.Scan(conn, autopsy.ScanOptions{}, autopsy.DefaultExpiryDays) + return loadErr + }) + + if suffix != "" { + // Filter to matching record by quest name + for _, r := range records { + if r.Quest == suffix { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(r) + return + } + } + http.Error(w, "autopsy not found", http.StatusNotFound) + return + } + if err != nil { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode([]interface{}{}) + return + } + if records == nil { + records = []autopsy.Autopsy{} + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(records) +} + +// GET /api/tome/ — quest tome (CV) +func (s *Server) handleTome(w http.ResponseWriter, r *http.Request) { + questName := strings.TrimPrefix(r.URL.Path, "/api/tome/") + if questName == "" { + http.Error(w, "quest name required", http.StatusBadRequest) + return + } + + var t *tome.QuestTome + err := s.db.WithConn(context.Background(), func(conn *db.Conn) error { + var loadErr error + t, loadErr = tome.Load(conn, questName) + return loadErr + }) + if err != nil || t == nil { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]interface{}{ + "quest_name": questName, + "phases_completed": []interface{}{}, + "gate_history": []interface{}{}, + "files_touched": []string{}, + }) + return + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(t) +} + +// GET /api/config — read fellowship config +func (s *Server) handleConfigRead(w http.ResponseWriter, r *http.Request) { + result := map[string]interface{}{ + "global": nil, + "project": nil, + } + + if home, err := os.UserHomeDir(); err == nil { + globalPath := filepath.Join(home, ".claude", "fellowship.json") + if data, err := os.ReadFile(globalPath); err == nil { + var global interface{} + if json.Unmarshal(data, &global) == nil { + result["global"] = global + } + } + } // silently skip global config if home directory unavailable + + projectPath := filepath.Join(s.gitRoot, ".fellowship", "config.json") + if data, err := os.ReadFile(projectPath); err == nil { + var project interface{} + if json.Unmarshal(data, &project) == nil { + result["project"] = project + } + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(result) +} + +type ConfigWriteRequest struct { + Key string `json:"key"` + Value interface{} `json:"value"` + Scope string `json:"scope"` +} + +func (s *Server) handleConfigWrite(w http.ResponseWriter, r *http.Request) { + var req ConfigWriteRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + http.Error(w, "invalid request body", http.StatusBadRequest) + return + } + + var configPath string + switch req.Scope { + case "global": + home, _ := os.UserHomeDir() + configPath = filepath.Join(home, ".claude", "fellowship.json") + case "project": + configPath = filepath.Join(s.gitRoot, ".fellowship", "config.json") + default: + http.Error(w, "scope must be 'global' or 'project'", http.StatusBadRequest) + return + } + + existing := make(map[string]interface{}) + if data, err := os.ReadFile(configPath); err == nil { + if err := json.Unmarshal(data, &existing); err != nil { + http.Error(w, "existing config file contains invalid JSON", http.StatusInternalServerError) + return + } + } + + existing[req.Key] = req.Value + + if err := os.MkdirAll(filepath.Dir(configPath), 0755); err != nil { + http.Error(w, "failed to create config directory", http.StatusInternalServerError) + return + } + data, err := json.MarshalIndent(existing, "", " ") + if err != nil { + http.Error(w, "failed to marshal config", http.StatusInternalServerError) + return + } + tmp := configPath + ".tmp" + if err := os.WriteFile(tmp, data, 0644); err != nil { + http.Error(w, "failed to write config", http.StatusInternalServerError) + return + } + if err := os.Rename(tmp, configPath); err != nil { + os.Remove(tmp) // best-effort cleanup + http.Error(w, "failed to save config", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]bool{"ok": true}) +} diff --git a/cli/internal/dashboard/embed.go b/cli/internal/dashboard/embed.go index 14f8653..4b76577 100644 --- a/cli/internal/dashboard/embed.go +++ b/cli/internal/dashboard/embed.go @@ -2,5 +2,5 @@ package dashboard import "embed" -//go:embed static +//go:embed all:static var staticFiles embed.FS diff --git a/cli/internal/dashboard/queue.go b/cli/internal/dashboard/queue.go new file mode 100644 index 0000000..9f764b0 --- /dev/null +++ b/cli/internal/dashboard/queue.go @@ -0,0 +1,108 @@ +package dashboard + +import ( + "crypto/rand" + "encoding/hex" + "encoding/json" + "fmt" + "os" + "path/filepath" + "sync" + "time" +) + +var queueMu sync.Mutex + +type CommandAction string + +const ( + ActionSpawnQuest CommandAction = "spawn-quest" + ActionSpawnScout CommandAction = "spawn-scout" + ActionKillQuest CommandAction = "kill-quest" + ActionRestartQuest CommandAction = "restart-quest" +) + +type CommandStatus string + +const ( + StatusPending CommandStatus = "pending" + StatusCompleted CommandStatus = "completed" + StatusFailed CommandStatus = "failed" +) + +type Command struct { + ID string `json:"id"` + Action CommandAction `json:"action"` + Status CommandStatus `json:"status"` + Params json.RawMessage `json:"params"` + Timestamp int64 `json:"timestamp"` + Result string `json:"result,omitempty"` +} + +type CommandQueue struct { + Commands []Command `json:"commands"` +} + +func commandQueuePath(gitRoot string) string { + return filepath.Join(gitRoot, ".fellowship", "command-queue.json") +} + +func generateID() string { + b := make([]byte, 8) + rand.Read(b) + return hex.EncodeToString(b) +} + +func LoadCommandQueue(gitRoot string) (*CommandQueue, error) { + path := commandQueuePath(gitRoot) + data, err := os.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + return &CommandQueue{}, nil + } + return nil, err + } + var q CommandQueue + if err := json.Unmarshal(data, &q); err != nil { + return nil, fmt.Errorf("corrupt command queue %s: %w", path, err) + } + return &q, nil +} + +func SaveCommandQueue(gitRoot string, q *CommandQueue) error { + path := commandQueuePath(gitRoot) + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + data, err := json.MarshalIndent(q, "", " ") + if err != nil { + return err + } + tmp := path + ".tmp" + if err := os.WriteFile(tmp, data, 0644); err != nil { + return err + } + return os.Rename(tmp, path) +} + +func EnqueueCommand(gitRoot string, action CommandAction, params json.RawMessage) (*Command, error) { + queueMu.Lock() + defer queueMu.Unlock() + + q, err := LoadCommandQueue(gitRoot) + if err != nil { + return nil, err + } + cmd := Command{ + ID: generateID(), + Action: action, + Status: StatusPending, + Params: params, + Timestamp: time.Now().Unix(), + } + q.Commands = append(q.Commands, cmd) + if err := SaveCommandQueue(gitRoot, q); err != nil { + return nil, err + } + return &cmd, nil +} diff --git a/cli/internal/dashboard/queue_test.go b/cli/internal/dashboard/queue_test.go new file mode 100644 index 0000000..6bba10c --- /dev/null +++ b/cli/internal/dashboard/queue_test.go @@ -0,0 +1,44 @@ +package dashboard + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" +) + +func TestEnqueueCommand(t *testing.T) { + dir := t.TempDir() + os.MkdirAll(filepath.Join(dir, ".fellowship"), 0755) + + params, _ := json.Marshal(map[string]string{"task": "test task"}) + cmd, err := EnqueueCommand(dir, ActionSpawnQuest, params) + if err != nil { + t.Fatalf("EnqueueCommand failed: %v", err) + } + if cmd.ID == "" { + t.Error("expected non-empty command ID") + } + if cmd.Status != StatusPending { + t.Errorf("expected status pending, got %s", cmd.Status) + } + + q, err := LoadCommandQueue(dir) + if err != nil { + t.Fatalf("LoadCommandQueue failed: %v", err) + } + if len(q.Commands) != 1 { + t.Errorf("expected 1 command, got %d", len(q.Commands)) + } +} + +func TestLoadCommandQueueEmpty(t *testing.T) { + dir := t.TempDir() + q, err := LoadCommandQueue(dir) + if err != nil { + t.Fatalf("LoadCommandQueue failed: %v", err) + } + if len(q.Commands) != 0 { + t.Errorf("expected 0 commands, got %d", len(q.Commands)) + } +} diff --git a/cli/internal/dashboard/server.go b/cli/internal/dashboard/server.go index b1e8889..1f1532f 100644 --- a/cli/internal/dashboard/server.go +++ b/cli/internal/dashboard/server.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" iofs "io/fs" + "log" "net/http" "strings" "time" @@ -25,15 +26,20 @@ type gateRequest struct { type Server struct { mux *http.ServeMux db *db.DB + gitRoot string pollInterval int + hub *Hub } -func NewServer(d *db.DB, pollInterval int) *Server { +func NewServer(d *db.DB, gitRoot string, pollInterval int) *Server { s := &Server{ mux: http.NewServeMux(), db: d, + gitRoot: gitRoot, pollInterval: pollInterval, + hub: NewHub(), } + s.mux.HandleFunc("GET /ws", s.hub.HandleWS) s.mux.HandleFunc("GET /api/status", s.handleStatus) s.mux.HandleFunc("GET /api/eagles", s.handleEagles) s.mux.HandleFunc("GET /api/herald", s.handleHerald) @@ -43,16 +49,49 @@ func NewServer(d *db.DB, pollInterval int) *Server { s.mux.HandleFunc("POST /api/company/", s.handleCompanyApprove) s.mux.HandleFunc("GET /api/errand/", s.handleErrand) s.mux.HandleFunc("GET /api/bulletin", s.handleBulletin) - - staticFS, _ := iofs.Sub(staticFiles, "static") - s.mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticFS)))) - s.mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path != "/" { + s.mux.HandleFunc("POST /api/quest/spawn", s.handleSpawnQuest) + s.mux.HandleFunc("POST /api/quest/kill", s.handleKillQuest) + s.mux.HandleFunc("POST /api/quest/restart", s.handleRestartQuest) + s.mux.HandleFunc("POST /api/scout/spawn", s.handleSpawnScout) + s.mux.HandleFunc("GET /api/commands", s.handleCommands) + s.mux.HandleFunc("GET /api/autopsies/", s.handleAutopsies) + s.mux.HandleFunc("GET /api/autopsies", s.handleAutopsies) + s.mux.HandleFunc("GET /api/tome/", s.handleTome) + s.mux.HandleFunc("GET /api/config", s.handleConfigRead) + s.mux.HandleFunc("POST /api/config", s.handleConfigWrite) + + staticFS, err := iofs.Sub(staticFiles, "static") + if err != nil { + log.Fatalf("dashboard: failed to load static assets: %v", err) + } + fileServer := http.FileServer(http.FS(staticFS)) + s.mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, "/api/") || r.URL.Path == "/ws" { http.NotFound(w, r) return } + + // Try to serve static file first + path := strings.TrimPrefix(r.URL.Path, "/") + if path == "" { + path = "index.html" + } + if f, err := staticFS.Open(path); err == nil { + stat, statErr := f.Stat() + f.Close() + if statErr == nil && !stat.IsDir() { + fileServer.ServeHTTP(w, r) + return + } + } + + // SPA fallback: serve index.html for client-side routes data, _ := staticFiles.ReadFile("static/index.html") - w.Header().Set("Content-Type", "text/html") + if data == nil { + http.NotFound(w, r) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write(data) }) return s @@ -150,15 +189,20 @@ func (s *Server) handleGateApprove(w http.ResponseWriter, r *http.Request) { return } + now := time.Now().UTC() + ts := now.Unix() + s.hub.Broadcast(WSEvent{Type: "gate-resolved", QuestID: result.Name, Action: "approved", Timestamp: ts}) + s.hub.Broadcast(WSEvent{Type: "quest-changed", QuestID: result.Name, Timestamp: ts}) + // Best-effort herald announcements after tx commits. s.db.WithConn(context.Background(), func(conn *db.Conn) error { - now := time.Now().UTC().Format(time.RFC3339) + nowStr := now.Format(time.RFC3339) herald.Announce(conn, herald.Tiding{ - Timestamp: now, Quest: result.Name, Type: herald.GateApproved, + Timestamp: nowStr, Quest: result.Name, Type: herald.GateApproved, Phase: prevPhase, Detail: fmt.Sprintf("Gate approved for %s", prevPhase), }) herald.Announce(conn, herald.Tiding{ - Timestamp: now, Quest: result.Name, Type: herald.PhaseTransition, + Timestamp: nowStr, Quest: result.Name, Type: herald.PhaseTransition, Phase: result.Phase, Detail: fmt.Sprintf("Phase advanced from %s to %s", prevPhase, result.Phase), }) return nil @@ -226,10 +270,14 @@ func (s *Server) handleGateReject(w http.ResponseWriter, r *http.Request) { return } + rejectTS := time.Now().UTC() + s.hub.Broadcast(WSEvent{Type: "gate-resolved", QuestID: result.Name, Action: "rejected", Timestamp: rejectTS.Unix()}) + s.hub.Broadcast(WSEvent{Type: "quest-changed", QuestID: result.Name, Timestamp: rejectTS.Unix()}) + // Best-effort herald announcement after tx commits. s.db.WithConn(context.Background(), func(conn *db.Conn) error { herald.Announce(conn, herald.Tiding{ - Timestamp: time.Now().UTC().Format(time.RFC3339), + Timestamp: rejectTS.Format(time.RFC3339), Quest: result.Name, Type: herald.GateRejected, Phase: result.Phase, Detail: fmt.Sprintf("Gate rejected for %s", result.Phase), }) @@ -275,7 +323,7 @@ func (s *Server) handleCompanyApprove(w http.ResponseWriter, r *http.Request) { return fmt.Errorf("company not found: %s", name) } - approved, errs := batchApproveCompany(conn, *target, fs) + approved, errs := batchApproveCompany(conn, *target, fs, s.hub) resp.Approved = approved if resp.Approved == nil { resp.Approved = []string{} @@ -299,7 +347,7 @@ func (s *Server) handleCompanyApprove(w http.ResponseWriter, r *http.Request) { } // batchApproveCompany approves all pending gates within a company. -func batchApproveCompany(conn *db.Conn, c CompanyEntry, fs *FellowshipState) (approved []string, errs []error) { +func batchApproveCompany(conn *db.Conn, c CompanyEntry, fs *FellowshipState, hub *Hub) (approved []string, errs []error) { for _, qName := range c.Quests { // Find worktree from fellowship quests var wt string @@ -349,6 +397,12 @@ func batchApproveCompany(conn *db.Conn, c CompanyEntry, fs *FellowshipState) (ap Phase: nextPhase, Detail: fmt.Sprintf("Phase advanced from %s to %s", prevPhase, nextPhase), }) + if hub != nil { + batchTS := time.Now().Unix() + hub.Broadcast(WSEvent{Type: "gate-resolved", QuestID: qName, Action: "approved", Timestamp: batchTS}) + hub.Broadcast(WSEvent{Type: "quest-changed", QuestID: qName, Timestamp: batchTS}) + } + _ = wt // worktree used for context but not needed for DB operations approved = append(approved, qName) } diff --git a/cli/internal/dashboard/server_test.go b/cli/internal/dashboard/server_test.go index b45afd7..f4421ec 100644 --- a/cli/internal/dashboard/server_test.go +++ b/cli/internal/dashboard/server_test.go @@ -51,7 +51,7 @@ func setupTestDB(t *testing.T) (*db.DB, string) { func TestAPIStatus(t *testing.T) { d, _ := setupTestDB(t) - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) req := httptest.NewRequest("GET", "/api/status", nil) w := httptest.NewRecorder() @@ -98,7 +98,7 @@ func TestAPIStatus(t *testing.T) { func TestAPIGateApprove(t *testing.T) { d, worktreeDir := setupTestDB(t) - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) body := strings.NewReader(fmt.Sprintf(`{"dir":%q}`, worktreeDir)) req := httptest.NewRequest("POST", "/api/gate/approve", body) @@ -127,7 +127,7 @@ func TestAPIGateApprove(t *testing.T) { func TestAPIGateReject(t *testing.T) { d, worktreeDir := setupTestDB(t) - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) body := strings.NewReader(fmt.Sprintf(`{"dir":%q}`, worktreeDir)) req := httptest.NewRequest("POST", "/api/gate/reject", body) @@ -170,7 +170,7 @@ func TestAPIGateApprove_NoPending(t *testing.T) { t.Fatal(err) } - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) body := strings.NewReader(fmt.Sprintf(`{"dir":%q}`, worktreeDir)) req := httptest.NewRequest("POST", "/api/gate/approve", body) @@ -184,7 +184,7 @@ func TestAPIGateApprove_NoPending(t *testing.T) { func TestAPIGateApprove_HeraldLogging(t *testing.T) { d, worktreeDir := setupTestDB(t) - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) body := strings.NewReader(fmt.Sprintf(`{"dir":%q}`, worktreeDir)) req := httptest.NewRequest("POST", "/api/gate/approve", body) @@ -228,7 +228,7 @@ func TestAPIGateApprove_HeraldLogging(t *testing.T) { func TestAPIGateReject_HeraldLogging(t *testing.T) { d, worktreeDir := setupTestDB(t) - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) body := strings.NewReader(fmt.Sprintf(`{"dir":%q}`, worktreeDir)) req := httptest.NewRequest("POST", "/api/gate/reject", body) @@ -261,7 +261,7 @@ func TestAPIGateReject_HeraldLogging(t *testing.T) { func TestAPIStatus_NotFound(t *testing.T) { d, _ := setupTestDB(t) - srv := NewServer(d, 5) + srv := NewServer(d, "", 5) req := httptest.NewRequest("GET", "/api/nonexistent", nil) w := httptest.NewRecorder() diff --git a/cli/internal/dashboard/static/_app/env.js b/cli/internal/dashboard/static/_app/env.js new file mode 100644 index 0000000..f5427da --- /dev/null +++ b/cli/internal/dashboard/static/_app/env.js @@ -0,0 +1 @@ +export const env={} \ No newline at end of file diff --git a/cli/internal/dashboard/static/_app/immutable/assets/0.B4Tu4Ui9.css b/cli/internal/dashboard/static/_app/immutable/assets/0.B4Tu4Ui9.css new file mode 100644 index 0000000..9f1e27d --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/0.B4Tu4Ui9.css @@ -0,0 +1 @@ +:root{--bg-base: #0c0f14;--bg-surface: #10131a;--bg-raised: #14171e;--bg-overlay: rgba(0, 0, 0, .6);--border: #15181f;--border-hover: #1e222d;--border-active: #2a2e38;--text-primary: #e8ecf2;--text-secondary: #c4c9d4;--text-muted: #4a5060;--text-faint: #3a3f4d;--accent-gold: #d4a843;--accent-gold-dim: #d4a84333;--accent-gold-glow: rgba(212, 168, 67, .08);--accent-green: #2ea043;--accent-green-dim: #1a3a24;--accent-green-text: #3fb950;--accent-red: #f85149;--accent-red-dim: #3a1a1a;--accent-blue: #5b9fc1;--accent-blue-dim: #1a2a3a;--accent-purple: #8b5ec4;--accent-purple-dim: #2a1a3a;--font-brand: "Cinzel", serif;--font-heading: "Outfit", sans-serif;--font-body: "DM Sans", sans-serif;--font-mono: "JetBrains Mono", monospace;--space-xs: 4px;--space-sm: 8px;--space-md: 16px;--space-lg: 24px;--space-xl: 32px;--space-2xl: 48px;--radius-sm: 4px;--radius-md: 6px;--radius-lg: 8px;--radius-xl: 12px;--transition-fast: .15s ease;--transition-normal: .25s ease;--sidebar-width-collapsed: 56px;--sidebar-width-expanded: 220px}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html,body{height:100%;background:var(--bg-base);color:var(--text-secondary);font-family:var(--font-body);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}a{color:var(--accent-gold);text-decoration:none}a:hover{text-decoration:underline}button{font-family:var(--font-body);cursor:pointer;border:none;background:none;color:inherit}input,textarea,select{font-family:var(--font-body);font-size:inherit;color:var(--text-primary);background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-sm) var(--space-md)}input:focus,textarea:focus,select:focus{outline:none;border-color:var(--accent-gold)}code{font-family:var(--font-mono);font-size:.9em}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--border-hover);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--border-active)}.mono{font-family:var(--font-mono)}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sidebar.svelte-129hoe0{width:var(--sidebar-width-expanded);background:#0a0c10;border-right:1px solid var(--border);display:flex;flex-direction:column;transition:width var(--transition-normal);overflow:hidden;flex-shrink:0}.sidebar.collapsed.svelte-129hoe0{width:var(--sidebar-width-collapsed)}.sidebar-header.svelte-129hoe0{padding:16px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;min-height:56px}.logo-mark.svelte-129hoe0{width:28px;height:28px;background:linear-gradient(135deg,var(--accent-gold),#a67c2e);border-radius:6px;display:flex;align-items:center;justify-content:center;font-family:var(--font-brand);font-size:14px;font-weight:700;color:#0a0c10;flex-shrink:0}.logo-text.svelte-129hoe0{font-family:var(--font-brand);font-size:15px;font-weight:600;color:var(--accent-gold);letter-spacing:.05em;white-space:nowrap}.sidebar-nav.svelte-129hoe0{flex:1;padding:12px 8px;display:flex;flex-direction:column;gap:2px}.nav-item.svelte-129hoe0{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--radius-md);font-size:13px;color:var(--text-muted);text-decoration:none;transition:all var(--transition-fast);white-space:nowrap}.nav-item.svelte-129hoe0:hover{color:var(--text-secondary);background:var(--bg-raised);text-decoration:none}.nav-item.active.svelte-129hoe0{color:var(--text-secondary);background:var(--bg-raised)}.nav-icon.svelte-129hoe0{width:20px;text-align:center;font-size:14px;flex-shrink:0}.sidebar-toggle.svelte-129hoe0{padding:12px;border-top:1px solid var(--border);color:var(--text-faint);font-size:16px;text-align:center;transition:color var(--transition-fast)}.sidebar-toggle.svelte-129hoe0:hover{color:var(--text-muted)}.overlay.svelte-wh9uu8{position:fixed;inset:0;background:var(--bg-overlay, rgba(0, 0, 0, .6));-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);display:flex;align-items:flex-start;justify-content:center;padding-top:20vh;z-index:1000}.panel.svelte-wh9uu8{background:var(--bg-surface, #1e1e2e);border:1px solid var(--border, #333);border-radius:12px;max-width:560px;width:100%;overflow:hidden;box-shadow:0 16px 48px #0006}.search-input.svelte-wh9uu8{width:100%;padding:14px 16px;background:transparent;border:none;border-bottom:1px solid var(--border, #333);color:var(--text, #e0e0e0);font-size:16px;outline:none;box-sizing:border-box}.search-input.svelte-wh9uu8::placeholder{color:var(--text-faint, #666)}.input-mode-header.svelte-wh9uu8{padding:10px 16px 0;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint, #666)}.action-list.svelte-wh9uu8{max-height:360px;overflow-y:auto;padding:8px 0}.category-header.svelte-wh9uu8{padding:8px 16px 4px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-faint, #666)}.action-item.svelte-wh9uu8{display:block;width:100%;padding:8px 16px;background:transparent;border:none;color:var(--text, #e0e0e0);font-size:14px;text-align:left;cursor:pointer;transition:background .1s}.action-item.svelte-wh9uu8:hover,.action-item.selected.svelte-wh9uu8{background:var(--bg-raised, #2a2a3e)}.no-results.svelte-wh9uu8{padding:16px;text-align:center;color:var(--text-faint, #666);font-size:14px}.shell.svelte-w96i92{display:flex;height:100vh;overflow:hidden}.main-content.svelte-w96i92{flex:1;overflow-y:auto;overflow-x:hidden} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/3.CVgNbBqn.css b/cli/internal/dashboard/static/_app/immutable/assets/3.CVgNbBqn.css new file mode 100644 index 0000000..bc08966 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/3.CVgNbBqn.css @@ -0,0 +1 @@ +.autopsies-view.svelte-1c2edl6{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-md);height:100%}.view-header.svelte-1c2edl6{display:flex;align-items:baseline;gap:var(--space-md)}.view-header.svelte-1c2edl6 h1:where(.svelte-1c2edl6){font-family:var(--font-heading);font-size:18px;font-weight:600;color:var(--text-primary)}.count.svelte-1c2edl6{font-family:var(--font-mono);font-size:12px;color:var(--text-muted)}.search-bar.svelte-1c2edl6{display:flex}.search-input.svelte-1c2edl6{flex:1;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md);padding:8px 12px;font-family:var(--font-body);font-size:13px;color:var(--text-primary);outline:none;transition:border-color var(--transition-fast)}.search-input.svelte-1c2edl6::placeholder{color:var(--text-faint)}.search-input.svelte-1c2edl6:focus{border-color:var(--border-active)}.list-scroll.svelte-1c2edl6{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.autopsy-row.svelte-1c2edl6{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:0;cursor:pointer;text-align:left;width:100%;font-family:var(--font-body);color:var(--text-primary);transition:border-color var(--transition-fast)}.autopsy-row.svelte-1c2edl6:hover{border-color:var(--border-hover)}.autopsy-row.expanded.svelte-1c2edl6{border-color:var(--border-active)}.autopsy-summary.svelte-1c2edl6{display:flex;align-items:center;gap:var(--space-md);padding:12px var(--space-md)}.autopsy-quest.svelte-1c2edl6{font-size:13px;font-weight:500;color:var(--accent-red);min-width:120px;flex-shrink:0}.autopsy-date.svelte-1c2edl6{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);min-width:140px;flex-shrink:0}.autopsy-failure.svelte-1c2edl6{flex:1;font-size:12px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.autopsy-trigger.svelte-1c2edl6{font-family:var(--font-mono);font-size:11px;color:var(--text-muted);background:var(--bg-raised);padding:2px 8px;border-radius:var(--radius-sm);flex-shrink:0}.expand-icon.svelte-1c2edl6{color:var(--text-faint);font-size:14px;flex-shrink:0;width:16px;text-align:center}.autopsy-detail.svelte-1c2edl6{padding:0 var(--space-md) var(--space-md);border-top:1px solid var(--border);margin-top:0;display:flex;flex-direction:column;gap:var(--space-sm);padding-top:var(--space-md)}.detail-section.svelte-1c2edl6{display:flex;gap:var(--space-md)}.detail-label.svelte-1c2edl6{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);min-width:80px;flex-shrink:0;padding-top:2px}.detail-value.svelte-1c2edl6{font-size:12px;color:var(--text-secondary);line-height:1.5}.detail-resolution.svelte-1c2edl6{white-space:pre-wrap}.file-path.svelte-1c2edl6{display:block;font-family:var(--font-mono);font-size:11px;color:var(--accent-blue);padding:1px 0}.tag-list.svelte-1c2edl6{display:flex;gap:var(--space-xs);flex-wrap:wrap}.tag.svelte-1c2edl6{font-size:11px;padding:2px 8px;border-radius:var(--radius-sm);background:var(--accent-purple-dim);color:var(--accent-purple)}.empty-state.svelte-1c2edl6{text-align:center;padding:var(--space-2xl);color:var(--text-muted);font-size:13px}.empty-state.error.svelte-1c2edl6{color:var(--accent-red)} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/4.DUdybRxg.css b/cli/internal/dashboard/static/_app/immutable/assets/4.DUdybRxg.css new file mode 100644 index 0000000..03c2afa --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/4.DUdybRxg.css @@ -0,0 +1 @@ +.banner.svelte-1etvnwu{background:var(--accent-red-dim);color:var(--accent-red);text-align:center;padding:6px;font-size:12px;font-weight:500}.stat.svelte-1em4u7y{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px 16px;flex:1}.stat-value.svelte-1em4u7y{font-family:var(--font-heading);font-size:28px;font-weight:600;line-height:1}.stat-label.svelte-1em4u7y{font-size:11px;color:var(--text-muted);margin-top:4px;text-transform:uppercase;letter-spacing:.05em}.quest-card.svelte-1cd3txo{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px 16px;display:flex;flex-direction:column;gap:10px;cursor:pointer;transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.quest-card.svelte-1cd3txo:hover{border-color:var(--border-hover)}.quest-card.gate-pending.svelte-1cd3txo{border-color:var(--accent-gold-dim);box-shadow:0 0 12px var(--accent-gold-glow)}.card-header.svelte-1cd3txo{display:flex;align-items:center;justify-content:space-between}.quest-name.svelte-1cd3txo{font-size:13px;font-weight:500;color:var(--text-primary)}.health-badge.svelte-1cd3txo{font-size:10px;padding:1px 8px;border-radius:10px;font-weight:500}.health-badge.working.svelte-1cd3txo{background:var(--accent-green-dim);color:var(--accent-green-text)}.health-badge.stalled.svelte-1cd3txo{background:var(--accent-gold-dim);color:var(--accent-gold)}.health-badge.zombie.svelte-1cd3txo{background:var(--accent-red-dim);color:var(--accent-red)}.health-badge.idle.svelte-1cd3txo{background:var(--bg-raised);color:var(--text-muted)}.health-badge.complete.svelte-1cd3txo{background:var(--accent-green-dim);color:var(--accent-green-text)}.card-meta.svelte-1cd3txo{display:flex;gap:12px;font-size:11px;color:var(--text-muted)}.phase-label.svelte-1cd3txo{color:var(--text-secondary)}.gate-row.svelte-1cd3txo{border-top:1px solid var(--border);padding-top:8px}.command-view.svelte-1x14rpa{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-lg);height:100%}.view-header.svelte-1x14rpa h1:where(.svelte-1x14rpa){font-family:var(--font-heading);font-size:18px;font-weight:600;color:var(--text-primary)}.stats-row.svelte-1x14rpa{display:flex;gap:12px}.content-split.svelte-1x14rpa{display:flex;gap:var(--space-lg);flex:1;min-height:0}.quest-grid.svelte-1x14rpa{flex:2;display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px;align-content:start}.herald-panel.svelte-1x14rpa{flex:1;min-width:240px;max-width:320px;background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px;overflow-y:auto}.panel-header.svelte-1x14rpa{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);margin-bottom:12px}.scout-card.svelte-1x14rpa{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px 16px;display:flex;flex-direction:column;gap:6px}.scout-header.svelte-1x14rpa{display:flex;align-items:center;gap:8px}.scout-name.svelte-1x14rpa{font-size:13px;font-weight:500;color:var(--accent-blue)}.scout-question.svelte-1x14rpa{font-size:12px;color:var(--text-muted);line-height:1.4}.empty-state.svelte-1x14rpa{grid-column:1 / -1;text-align:center;padding:var(--space-2xl);color:var(--text-muted)} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/5.BgjiOm-S.css b/cli/internal/dashboard/static/_app/immutable/assets/5.BgjiOm-S.css new file mode 100644 index 0000000..4dac521 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/5.BgjiOm-S.css @@ -0,0 +1 @@ +.config-view.svelte-1gp6n77{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-lg);height:100%}.view-header.svelte-1gp6n77 h1:where(.svelte-1gp6n77){font-family:var(--font-heading);font-size:18px;font-weight:600;color:var(--text-primary)}.config-sections.svelte-1gp6n77{display:flex;flex-direction:column;gap:var(--space-lg);overflow-y:auto;flex:1}.config-section.svelte-1gp6n77{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-md)}.section-header.svelte-1gp6n77{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);margin-bottom:var(--space-md)}.settings-list.svelte-1gp6n77{display:flex;flex-direction:column;gap:2px}.setting-row.svelte-1gp6n77{display:flex;align-items:center;justify-content:space-between;padding:10px var(--space-sm);border-radius:var(--radius-md);transition:background var(--transition-fast)}.setting-row.svelte-1gp6n77:hover{background:var(--bg-raised)}.setting-info.svelte-1gp6n77{display:flex;align-items:baseline;gap:var(--space-sm)}.setting-label.svelte-1gp6n77{font-size:13px;font-weight:500;color:var(--text-primary)}.setting-scope.svelte-1gp6n77{font-family:var(--font-mono);font-size:10px;color:var(--text-faint);background:var(--bg-raised);padding:1px 6px;border-radius:var(--radius-sm)}.setting-control.svelte-1gp6n77{display:flex;align-items:center;gap:var(--space-sm)}.toggle-btn.svelte-1gp6n77{font-family:var(--font-mono);font-size:11px;font-weight:600;padding:4px 14px;border-radius:var(--radius-md);background:var(--bg-raised);color:var(--text-muted);border:1px solid var(--border);cursor:pointer;transition:all var(--transition-fast);min-width:52px}.toggle-btn.active.svelte-1gp6n77{background:var(--accent-green-dim);color:var(--accent-green-text);border-color:var(--accent-green-dim)}.toggle-btn.svelte-1gp6n77:hover:not(:disabled){border-color:var(--border-hover)}.toggle-btn.svelte-1gp6n77:disabled{opacity:.5;cursor:not-allowed}.setting-input.svelte-1gp6n77{background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md);padding:5px 10px;font-family:var(--font-mono);font-size:12px;color:var(--text-primary);outline:none;width:180px;transition:border-color var(--transition-fast)}.setting-input.svelte-1gp6n77:focus{border-color:var(--border-active)}.setting-select.svelte-1gp6n77{background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md);padding:5px 10px;font-family:var(--font-mono);font-size:12px;color:var(--text-primary);outline:none;cursor:pointer}.setting-select.svelte-1gp6n77 option:where(.svelte-1gp6n77){background:var(--bg-raised);color:var(--text-primary)}.save-indicator.svelte-1gp6n77{font-size:11px;color:var(--accent-green-text);animation:svelte-1gp6n77-fadeIn .15s ease}.save-indicator.error.svelte-1gp6n77{color:var(--accent-red)}@keyframes svelte-1gp6n77-fadeIn{0%{opacity:0}to{opacity:1}}.raw-json.svelte-1gp6n77{font-family:var(--font-mono);font-size:12px;color:var(--text-secondary);background:var(--bg-raised);padding:var(--space-md);border-radius:var(--radius-md);overflow-x:auto;line-height:1.5;margin:0}.empty-state.svelte-1gp6n77{text-align:center;padding:var(--space-2xl);color:var(--text-muted);font-size:13px} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/6.DrszQgHF.css b/cli/internal/dashboard/static/_app/immutable/assets/6.DrszQgHF.css new file mode 100644 index 0000000..afb4aa6 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/6.DrszQgHF.css @@ -0,0 +1 @@ +.herald-view.svelte-11xttp7{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-md);height:100%}.view-header.svelte-11xttp7{display:flex;align-items:baseline;gap:var(--space-md)}.view-header.svelte-11xttp7 h1:where(.svelte-11xttp7){font-family:var(--font-heading);font-size:18px;font-weight:600;color:var(--text-primary)}.tiding-count.svelte-11xttp7{font-family:var(--font-mono);font-size:12px;color:var(--text-muted)}.filters.svelte-11xttp7{display:flex;flex-direction:column;gap:var(--space-sm);padding:var(--space-md);background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg)}.filter-row.svelte-11xttp7{display:flex;gap:var(--space-sm)}.search-input.svelte-11xttp7{flex:1;background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md);padding:8px 12px;font-family:var(--font-body);font-size:13px;color:var(--text-primary);outline:none;transition:border-color var(--transition-fast)}.search-input.svelte-11xttp7::placeholder{color:var(--text-faint)}.search-input.svelte-11xttp7:focus{border-color:var(--border-active)}.quest-select.svelte-11xttp7{background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-md);padding:8px 12px;font-family:var(--font-body);font-size:13px;color:var(--text-primary);outline:none;min-width:160px;cursor:pointer}.quest-select.svelte-11xttp7:focus-visible{outline:2px solid var(--accent-gold);outline-offset:2px}.quest-select.svelte-11xttp7 option:where(.svelte-11xttp7){background:var(--bg-raised);color:var(--text-primary)}.type-filters.svelte-11xttp7{display:flex;gap:var(--space-md);flex-wrap:wrap}.type-checkbox.svelte-11xttp7{display:flex;align-items:center;gap:var(--space-xs);cursor:pointer}.type-checkbox.svelte-11xttp7 input[type=checkbox]:where(.svelte-11xttp7){accent-color:var(--accent-gold);cursor:pointer}.type-label.svelte-11xttp7{font-size:12px;color:var(--text-secondary);-webkit-user-select:none;user-select:none}.feed-scroll.svelte-11xttp7{flex:1;overflow-y:auto;background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-md)}.empty-state.svelte-11xttp7{text-align:center;padding:var(--space-2xl);color:var(--text-muted);font-size:13px} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/7.Ctb9NTgd.css b/cli/internal/dashboard/static/_app/immutable/assets/7.Ctb9NTgd.css new file mode 100644 index 0000000..5fb7450 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/7.Ctb9NTgd.css @@ -0,0 +1 @@ +.errand-list.svelte-6y5tqw{display:flex;flex-direction:column;gap:4px}.errand-item.svelte-6y5tqw{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-md);font-size:13px}.errand-check.svelte-6y5tqw{width:18px;height:18px;border-radius:var(--radius-sm);border:1.5px solid var(--border-active);display:flex;align-items:center;justify-content:center;font-size:10px;flex-shrink:0}.errand-check.done.svelte-6y5tqw{background:var(--accent-green-dim);border-color:var(--accent-green);color:var(--accent-green-text)}.errand-check.active.svelte-6y5tqw{border-color:var(--accent-gold-dim);background:#d4a8431a;color:var(--accent-gold)}.errand-text.svelte-6y5tqw{color:var(--text-muted)}.errand-text.done.svelte-6y5tqw{color:var(--text-faint);text-decoration:line-through}.errand-text.active.svelte-6y5tqw{color:var(--text-primary)}.detail-view.svelte-1ysin3l{display:flex;flex-direction:column;height:100%}.detail-header.svelte-1ysin3l{padding:var(--space-md) var(--space-lg) 0;border-bottom:1px solid var(--border)}.breadcrumb.svelte-1ysin3l{font-size:12px;color:var(--text-muted);margin-bottom:10px}.breadcrumb.svelte-1ysin3l a:where(.svelte-1ysin3l){color:var(--text-faint)}.sep.svelte-1ysin3l{margin:0 6px;color:var(--border-active)}.title-row.svelte-1ysin3l{display:flex;align-items:center;gap:12px;margin-bottom:14px}.title-row.svelte-1ysin3l h1:where(.svelte-1ysin3l){font-family:var(--font-heading);font-size:18px;font-weight:600;color:var(--text-primary)}.phase-badge.svelte-1ysin3l{padding:3px 10px;border-radius:12px;font-size:11px;font-weight:500;background:var(--accent-green-dim);color:var(--accent-green-text)}.health-dot.svelte-1ysin3l{width:7px;height:7px;border-radius:50%;margin-left:auto}.health-dot.working.svelte-1ysin3l{background:var(--accent-green-text)}.health-dot.stalled.svelte-1ysin3l{background:var(--accent-gold)}.health-dot.zombie.svelte-1ysin3l{background:var(--accent-red)}.health-label.svelte-1ysin3l{font-size:12px;color:var(--accent-green-text)}.phase-steps.svelte-1ysin3l{display:flex;margin-bottom:-1px}.phase-step.svelte-1ysin3l{flex:1;text-align:center;padding:10px 0 12px;font-size:11px;color:var(--text-faint);border-bottom:2px solid transparent}.phase-step.done.svelte-1ysin3l{color:var(--text-muted);border-bottom-color:var(--accent-green)}.phase-step.current.svelte-1ysin3l{color:var(--accent-gold);border-bottom-color:var(--accent-gold)}.tabs.svelte-1ysin3l{display:flex;padding:0 var(--space-lg);border-bottom:1px solid var(--border)}.tab.svelte-1ysin3l{padding:10px 16px;font-size:12px;color:var(--text-muted);border-bottom:2px solid transparent;margin-bottom:-1px;transition:all var(--transition-fast)}.tab.active.svelte-1ysin3l{color:var(--text-secondary);border-bottom-color:var(--accent-gold)}.tab-badge.svelte-1ysin3l{font-size:10px;padding:0 5px;border-radius:8px;background:var(--accent-gold-dim);color:var(--accent-gold);margin-left:5px}.detail-body.svelte-1ysin3l{flex:1;display:flex;gap:var(--space-lg);padding:var(--space-lg);overflow:hidden}.detail-content.svelte-1ysin3l{flex:2;overflow-y:auto}.detail-meta.svelte-1ysin3l{flex:1;max-width:280px}.meta-card.svelte-1ysin3l{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:14px}.meta-title.svelte-1ysin3l{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-faint);margin-bottom:10px}.meta-row.svelte-1ysin3l{display:flex;justify-content:space-between;font-size:12px;padding:5px 0;color:var(--text-muted);border-bottom:1px solid var(--border)}.meta-row.svelte-1ysin3l:last-child{border-bottom:none}.meta-value.svelte-1ysin3l{color:var(--text-secondary);font-size:11px;max-width:160px}.meta-value.working.svelte-1ysin3l{color:var(--accent-green-text)}.meta-value.stalled.svelte-1ysin3l{color:var(--accent-gold)}.files-list.svelte-1ysin3l{display:flex;flex-direction:column;gap:4px}.file-item.svelte-1ysin3l{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);padding:6px 10px;background:var(--bg-surface);border-radius:var(--radius-sm)}.tome-content.svelte-1ysin3l h3:where(.svelte-1ysin3l){font-family:var(--font-heading);font-size:14px;color:var(--text-primary);margin-bottom:var(--space-md)}.tome-entry.svelte-1ysin3l{display:flex;gap:12px;padding:8px 0;border-bottom:1px solid var(--border);font-size:12px}.tome-action.svelte-1ysin3l{font-weight:500;width:70px}.tome-action.approved.svelte-1ysin3l{color:var(--accent-green-text)}.tome-action.rejected.svelte-1ysin3l{color:var(--accent-red)}.tome-action.submitted.svelte-1ysin3l{color:var(--accent-gold)}.tome-phase.svelte-1ysin3l{color:var(--text-secondary)}.tome-time.svelte-1ysin3l{color:var(--text-faint);font-family:var(--font-mono);font-size:11px;margin-left:auto}.empty.svelte-1ysin3l{color:var(--text-muted);text-align:center;padding:var(--space-xl)} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/8.CA8t3wJx.css b/cli/internal/dashboard/static/_app/immutable/assets/8.CA8t3wJx.css new file mode 100644 index 0000000..960694c --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/8.CA8t3wJx.css @@ -0,0 +1 @@ +.gantt-chart.svelte-t05lje{display:flex;flex-direction:column;gap:6px}.gantt-row.svelte-t05lje{display:flex;align-items:center;gap:var(--space-md)}.gantt-label.svelte-t05lje{min-width:140px;max-width:140px;font-size:12px;font-weight:500;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-shrink:0}.gantt-track.svelte-t05lje{flex:1;position:relative;height:28px;background:var(--bg-raised);border-radius:var(--radius-sm);overflow:hidden}.gantt-bar.svelte-t05lje{position:absolute;top:2px;bottom:2px;border-radius:3px;min-width:4px;cursor:default;transition:opacity var(--transition-fast)}.gantt-bar.svelte-t05lje:hover{opacity:.85}.gantt-tooltip.svelte-t05lje{position:fixed;background:var(--bg-surface);border:1px solid var(--border-active);border-radius:var(--radius-md);padding:6px 10px;display:flex;gap:var(--space-sm);align-items:baseline;pointer-events:none;z-index:1000;box-shadow:0 4px 12px #0006}.tooltip-phase.svelte-t05lje{font-size:12px;font-weight:500;color:var(--text-primary)}.tooltip-dur.svelte-t05lje{font-family:var(--font-mono);font-size:11px;color:var(--text-muted)}.timeline-view.svelte-1fjec68{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-lg);height:100%}.view-header.svelte-1fjec68 h1:where(.svelte-1fjec68){font-family:var(--font-heading);font-size:18px;font-weight:600;color:var(--text-primary)}.chart-area.svelte-1fjec68{flex:1;background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-lg);overflow-y:auto}.empty-state.svelte-1fjec68{text-align:center;padding:var(--space-2xl);color:var(--text-muted);font-size:13px} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/GateActions.DvbP5nIs.css b/cli/internal/dashboard/static/_app/immutable/assets/GateActions.DvbP5nIs.css new file mode 100644 index 0000000..5e0e17e --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/GateActions.DvbP5nIs.css @@ -0,0 +1 @@ +.timeline.svelte-16oavfg{display:flex;gap:3px}.phase-bar.svelte-16oavfg{flex:1;height:4px;border-radius:2px;background:var(--border);transition:background var(--transition-fast)}.phase-bar.done.svelte-16oavfg{background:var(--accent-green)}.phase-bar.current.svelte-16oavfg{background:var(--accent-gold)}.compact.svelte-16oavfg .phase-bar:where(.svelte-16oavfg){height:3px}.gate-actions.svelte-1fnxfh2{display:flex;gap:6px}.gate-btn.svelte-1fnxfh2{padding:4px 12px;border-radius:var(--radius-sm);font-size:11px;font-weight:500;transition:opacity var(--transition-fast)}.gate-btn.svelte-1fnxfh2:disabled{opacity:.5}.approve.svelte-1fnxfh2{background:var(--accent-green-dim);color:var(--accent-green-text)}.reject.svelte-1fnxfh2{background:var(--accent-red-dim);color:var(--accent-red)} diff --git a/cli/internal/dashboard/static/_app/immutable/assets/HeraldFeed.D75iUDfw.css b/cli/internal/dashboard/static/_app/immutable/assets/HeraldFeed.D75iUDfw.css new file mode 100644 index 0000000..0cf9bf8 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/assets/HeraldFeed.D75iUDfw.css @@ -0,0 +1 @@ +.herald-feed.svelte-1lw2g4q{display:flex;flex-direction:column}.herald-item.svelte-1lw2g4q{display:flex;align-items:baseline;gap:8px;padding:8px 0;border-bottom:1px solid var(--border);font-size:12px}.herald-item.svelte-1lw2g4q:last-child{border-bottom:none}.herald-icon.svelte-1lw2g4q{flex-shrink:0;width:14px;text-align:center}.herald-text.svelte-1lw2g4q{flex:1;color:var(--text-muted)}.herald-time.svelte-1lw2g4q{font-family:var(--font-mono);font-size:10px;color:var(--text-faint);flex-shrink:0} diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/537vdszY.js b/cli/internal/dashboard/static/_app/immutable/chunks/537vdszY.js new file mode 100644 index 0000000..3a64057 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/537vdszY.js @@ -0,0 +1 @@ +import{aq as m,ax as c,ar as b,a3 as u,ai as _,q as k,w as o,ad as v,aw as g,ak as w,a4 as y,a8 as x,az as A,a9 as F,ab as M,a6 as E,ac as p}from"./CFIQ5hjj.js";class T{anchor;#t=new Map;#s=new Map;#e=new Map;#a=new Set;#i=!0;constructor(t,s=!0){this.anchor=t,this.#i=s}#r=t=>{if(this.#t.has(t)){var s=this.#t.get(t),e=this.#s.get(s);if(e)m(e),this.#a.delete(s);else{var r=this.#e.get(s);r&&(this.#s.set(s,r.effect),this.#e.delete(s),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),e=r.effect)}for(const[i,f]of this.#t){if(this.#t.delete(i),i===t)break;const a=this.#e.get(f);a&&(c(a.effect),this.#e.delete(f))}for(const[i,f]of this.#s){if(i===s||this.#a.has(i))continue;const a=()=>{if(Array.from(this.#t.values()).includes(i)){var h=document.createDocumentFragment();g(f,h),h.append(u()),this.#e.set(i,{effect:f,fragment:h})}else c(f);this.#a.delete(i),this.#s.delete(i)};this.#i||!e?(this.#a.add(i),b(f,a,!1)):a()}}};#f=t=>{this.#t.delete(t);const s=Array.from(this.#t.values());for(const[e,r]of this.#e)s.includes(e)||(c(r.effect),this.#e.delete(e))};ensure(t,s){var e=k,r=w();if(s&&!this.#s.has(t)&&!this.#e.has(t))if(r){var i=document.createDocumentFragment(),f=u();i.append(f),this.#e.set(t,{effect:_(()=>s(f)),fragment:i})}else this.#s.set(t,_(()=>s(this.anchor)));if(this.#t.set(e,t),r){for(const[a,n]of this.#s)a===t?e.unskip_effect(n):e.skip_effect(n);for(const[a,n]of this.#e)a===t?e.unskip_effect(n.effect):e.skip_effect(n.effect);e.oncommit(this.#r),e.ondiscard(this.#f)}else o&&(this.anchor=v),this.#r(e)}}function B(d,t,s=!1){var e;o&&(e=v,x());var r=new T(d),i=s?A:0;function f(a,n){if(o){var h=F(e);if(a!==parseInt(h.substring(1))){var l=M();E(l),r.anchor=l,p(!1),r.ensure(a,n),p(!0);return}}r.ensure(a,n)}y(()=>{var a=!1;t((n,h=0)=>{a=!0,f(h,n)}),a||f(-1,null)},i)}export{T as B,B as i}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/69_IOA4Y.js b/cli/internal/dashboard/static/_app/immutable/chunks/69_IOA4Y.js new file mode 100644 index 0000000..e9a5a01 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/69_IOA4Y.js @@ -0,0 +1 @@ +import{e}from"./DIeogL5L.js";e(); diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/BUApaBEI.js b/cli/internal/dashboard/static/_app/immutable/chunks/BUApaBEI.js new file mode 100644 index 0000000..efff340 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/BUApaBEI.js @@ -0,0 +1 @@ +class o{constructor(s,t){this.status=s,typeof t=="string"?this.body={message:t}:t?this.body=t:this.body={message:`Error: ${s}`}}toString(){return JSON.stringify(this.body)}}class i{constructor(s,t){this.status=s,this.location=t}}class n extends Error{constructor(s,t,e){super(e),this.status=s,this.text=t}}new TextEncoder;new TextDecoder;function c(r){const s=atob(r),t=new Uint8Array(s.length);for(let e=0;e(S&&(S=!1,n=E?U(s):s),n);let u;if(v){var m=q in r||w in r;u=A(r,a)?.set??(m&&a in r?e=>r[a]=e:void 0)}var _,o=!1;v?[_,o]=z(()=>r[a]):_=r[a],_===void 0&&s!==void 0&&(_=I(),u&&(f&&L(),u(_)));var i;if(f?i=()=>{var e=r[a];return e===void 0?I():(S=!0,e)}:i=()=>{var e=r[a];return e!==void 0&&(n=void 0),e===void 0?n:e},f&&(t&T)===0)return i;if(u){var O=r.$$legacy;return(function(e,l){return arguments.length>0?((!f||!l||O||o)&&u(l?i():e),e):i()})}var c=!1,d=((t&x)!==0?C:G)(()=>(c=!1,i()));v&&P(d);var R=M;return(function(e,l){if(arguments.length>0){const g=l?P(d):f&&v?B(e):e;return D(d,g),c=!0,n!==void 0&&(n=g),e}return b&&c||(R.f&N)!==0?d.v:P(d)})}export{Z as p}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/ByVGy8qs.js b/cli/internal/dashboard/static/_app/immutable/chunks/ByVGy8qs.js new file mode 100644 index 0000000..f1d0805 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/ByVGy8qs.js @@ -0,0 +1,2 @@ +import{aC as se,l as G,r as ae,u as ne,aD as V,U as N,ao as J,ad as d,w as _,a as g,aE as $,a4 as ie,a8 as K,aa as oe,aF as q,ai as m,a3 as R,ar as F,q as U,aw as fe,aG as z,aH as le,aI as he,aJ as ue,aK as O,aL as x,aM as X,aN as de,aO as ce,aP as Q,c as Z,ag as _e,ax as I,a6 as A,aQ as pe,ab as ve,aR as S,az as ge,aS as ye,aT as me,aU as be,X as Te,x as Ee,aV as we,aW as Ne,a7 as C,aX as Re,aY as Ae,aZ as Se,a_ as De,a$ as Me,b0 as Oe,b1 as H,ae as ee,aA as xe,ay as Le,b2 as P,ac as D,b3 as Fe,av as Ie,b4 as Ce,al as He,p as Pe,af as Ye,b5 as ke,b as We}from"./CFIQ5hjj.js";function Be(r){let e=0,t=J(0),a;return()=>{se()&&(G(t),ae(()=>(e===0&&(a=ne(()=>r(()=>V(t)))),e+=1,()=>{N(()=>{e-=1,e===0&&(a?.(),a=void 0,V(t))})})))}}var Ve=ge|ye;function $e(r,e,t,a){new qe(r,e,t,a)}class qe{parent;is_pending=!1;transform_error;#t;#v=_?d:null;#a;#l;#e;#n=null;#r=null;#s=null;#i=null;#h=0;#f=0;#u=!1;#d=new Set;#c=new Set;#o=null;#m=Be(()=>(this.#o=J(this.#h),()=>{this.#o=null}));constructor(e,t,a,n){this.#t=e,this.#a=t,this.#l=s=>{var i=g;i.b=this,i.f|=$,a(s)},this.parent=g.b,this.transform_error=n??this.parent?.transform_error??(s=>s),this.#e=ie(()=>{if(_){const s=this.#v;K();const i=s.data===oe;if(s.data.startsWith(q)){const o=JSON.parse(s.data.slice(q.length));this.#T(o)}else i?this.#E():this.#b()}else this.#g()},Ve),_&&(this.#t=d)}#b(){try{this.#n=m(()=>this.#l(this.#t))}catch(e){this.error(e)}}#T(e){const t=this.#a.failed;t&&(this.#s=m(()=>{t(this.#t,()=>e,()=>()=>{})}))}#E(){const e=this.#a.pending;if(e){this.is_pending=!0,this.#r=m(()=>e(this.#t));var t=U;N(()=>{var a=this.#i=document.createDocumentFragment(),n=R();a.append(n),this.#n=this.#p(()=>m(()=>this.#l(n))),this.#f===0&&(this.#t.before(a),this.#i=null,F(this.#r,()=>{this.#r=null}),this.#_(t))})}}#g(){var e=U;try{if(this.is_pending=this.has_pending_snippet(),this.#f=0,this.#h=0,this.#n=m(()=>{this.#l(this.#t)}),this.#f>0){var t=this.#i=document.createDocumentFragment();fe(this.#n,t);const a=this.#a.pending;this.#r=m(()=>a(this.#t))}else this.#_(e)}catch(a){this.error(a)}}#_(e){this.is_pending=!1;for(const t of this.#d)z(t,le),e.schedule(t);for(const t of this.#c)z(t,he),e.schedule(t);this.#d.clear(),this.#c.clear()}defer_effect(e){ue(e,this.#d,this.#c)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#a.pending}#p(e){var t=g,a=Q,n=Z;O(this.#e),x(this.#e),X(this.#e.ctx);try{return de.ensure(),e()}catch(s){return ce(s),null}finally{O(t),x(a),X(n)}}#y(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#y(e,t);return}this.#f+=e,this.#f===0&&(this.#_(t),this.#r&&F(this.#r,()=>{this.#r=null}),this.#i&&(this.#t.before(this.#i),this.#i=null))}update_pending_count(e,t){this.#y(e,t),this.#h+=e,!(!this.#o||this.#u)&&(this.#u=!0,N(()=>{this.#u=!1,this.#o&&_e(this.#o,this.#h)}))}get_effect_pending(){return this.#m(),G(this.#o)}error(e){var t=this.#a.onerror;let a=this.#a.failed;if(!t&&!a)throw e;this.#n&&(I(this.#n),this.#n=null),this.#r&&(I(this.#r),this.#r=null),this.#s&&(I(this.#s),this.#s=null),_&&(A(this.#v),pe(),A(ve()));var n=!1,s=!1;const i=()=>{if(n){be();return}n=!0,s&&me(),this.#s!==null&&F(this.#s,()=>{this.#s=null}),this.#p(()=>{this.#g()})},c=o=>{try{s=!0,t?.(o,i),s=!1}catch(f){S(f,this.#e&&this.#e.parent)}a&&(this.#s=this.#p(()=>{try{return m(()=>{var f=g;f.b=this,f.f|=$,a(this.#t,()=>o,()=>i)})}catch(f){return S(f,this.#e.parent),null}}))};N(()=>{var o;try{o=this.transform_error(e)}catch(f){S(f,this.#e&&this.#e.parent);return}o!==null&&typeof o=="object"&&typeof o.then=="function"?o.then(c,f=>S(f,this.#e&&this.#e.parent)):c(o)})}}const Ue=["touchstart","touchmove"];function ze(r){return Ue.includes(r)}const w=Symbol("events"),te=new Set,Y=new Set;function Xe(r,e,t,a={}){function n(s){if(a.capture||k.call(e,s),!s.cancelBubble)return we(()=>t?.call(this,s))}return r.startsWith("pointer")||r.startsWith("touch")||r==="wheel"?N(()=>{e.addEventListener(r,n,a)}):e.addEventListener(r,n,a),n}function Ze(r,e,t,a,n){var s={capture:a,passive:n},i=Xe(r,e,t,s);(e===document.body||e===window||e===document||e instanceof HTMLMediaElement)&&Ee(()=>{e.removeEventListener(r,i,s)})}function et(r,e,t){(e[w]??={})[r]=t}function tt(r){for(var e=0;e{throw p});throw v}}finally{r[w]=e,delete r.currentTarget,x(b),O(E)}}}const je=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:r=>r});function Ge(r){return je?.createHTML(r)??r}function Je(r){var e=Ne("template");return e.innerHTML=Ge(r.replaceAll("","")),e.content}function y(r,e){var t=g;t.nodes===null&&(t.nodes={start:r,end:e,a:null,t:null})}function rt(r,e){var t=(e&Ae)!==0,a=(e&Se)!==0,n,s=!r.startsWith("");return()=>{if(_)return y(d,null),d;n===void 0&&(n=Je(s?r:""+r),t||(n=C(n)));var i=a||Re?document.importNode(n,!0):n.cloneNode(!0);if(t){var c=C(i),o=i.lastChild;y(c,o)}else y(i,i);return i}}function st(r=""){if(!_){var e=R(r+"");return y(e,e),e}var t=d;return t.nodeType!==Me?(t.before(t=R()),A(t)):Oe(t),y(t,t),t}function at(){if(_)return y(d,null),d;var r=document.createDocumentFragment(),e=document.createComment(""),t=R();return r.append(e,t),y(e,t),r}function nt(r,e){if(_){var t=g;((t.f&De)===0||t.nodes.end===null)&&(t.nodes.end=d),K();return}r!==null&&r.before(e)}function it(r,e){var t=e==null?"":typeof e=="object"?`${e}`:e;t!==(r.__t??=r.nodeValue)&&(r.__t=t,r.nodeValue=`${t}`)}function Ke(r,e){return re(r,e)}function ot(r,e){H(),e.intro=e.intro??!1;const t=e.target,a=_,n=d;try{for(var s=C(t);s&&(s.nodeType!==ee||s.data!==xe);)s=Le(s);if(!s)throw P;D(!0),A(s);const i=re(r,{...e,anchor:s});return D(!1),i}catch(i){if(i instanceof Error&&i.message.split(` +`).some(c=>c.startsWith("https://svelte.dev/e/")))throw i;return i!==P&&console.warn("Failed to hydrate: ",i),e.recover===!1&&Fe(),H(),Ie(t),D(!1),Ke(r,e)}finally{D(a),A(n)}}const M=new Map;function re(r,{target:e,anchor:t,props:a={},events:n,context:s,intro:i=!0,transformError:c}){H();var o=void 0,f=Ce(()=>{var b=t??e.appendChild(R());$e(b,{pending:()=>{}},h=>{Pe({});var l=Z;if(s&&(l.c=s),n&&(a.$$events=n),_&&y(h,null),o=r(h,a)||{},_&&(g.nodes.end=d,d===null||d.nodeType!==ee||d.data!==Ye))throw ke(),P;We()},c);var E=new Set,v=h=>{for(var l=0;l{for(var h of E)for(const p of[e,document]){var l=M.get(p),u=l.get(h);--u==0?(p.removeEventListener(h,k),l.delete(h),l.size===0&&M.delete(p)):l.set(h,u)}Y.delete(v),b!==t&&b.parentNode?.removeChild(b)}});return W.set(o,f),o}let W=new WeakMap;function ft(r,e){const t=W.get(r);return t?(W.delete(r),t(e)):Promise.resolve()}export{nt as a,et as b,at as c,tt as d,Ze as e,rt as f,ot as h,Ke as m,it as s,st as t,ft as u}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/C67DyfnJ.js b/cli/internal/dashboard/static/_app/immutable/chunks/C67DyfnJ.js new file mode 100644 index 0000000..d470229 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/C67DyfnJ.js @@ -0,0 +1 @@ +async function s(a){const t=await fetch("/api/gate/approve",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dir:a})});if(!t.ok)throw new Error(`Gate approve failed: ${t.status}`)}async function r(a){const t=await fetch("/api/gate/reject",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({dir:a})});if(!t.ok)throw new Error(`Gate reject failed: ${t.status}`)}async function i(a,t,n){const e=await fetch("/api/quest/spawn",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({task:a,branch:t,company:n})});if(!e.ok)throw new Error(`Spawn quest failed: ${e.status}`);return(await e.json()).command_id}async function c(a){const t=await fetch("/api/scout/spawn",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({question:a})});if(!t.ok)throw new Error(`Spawn scout failed: ${t.status}`);return(await t.json()).command_id}async function f(a){const t=await fetch("/api/quest/kill",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({quest_id:a})});if(!t.ok)throw new Error(`Kill quest failed: ${t.status}`);return(await t.json()).command_id}async function u(a){const t=await fetch("/api/quest/restart",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({quest_id:a})});if(!t.ok)throw new Error(`Restart quest failed: ${t.status}`);return(await t.json()).command_id}async function d(a){try{const t=btoa(String.fromCharCode(...new TextEncoder().encode(a))).replace(/\+/g,"-").replace(/\//g,"_"),n=await fetch(`/api/errand/${t}`);return n.ok?n.json():null}catch{return null}}async function p(a){try{const t=await fetch(`/api/tome/${encodeURIComponent(a)}`);return t.ok?t.json():null}catch{return null}}async function h(){try{const a=await fetch("/api/autopsies");return a.ok?a.json():[]}catch{return[]}}async function l(){try{const a=await fetch("/api/config");return a.ok?a.json():{global:null,project:null}}catch{return{global:null,project:null}}}async function w(a,t,n){const e=await fetch("/api/config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:a,value:t,scope:n})});if(!e.ok)throw new Error(`Save config failed: ${e.status}`)}export{l as a,s as b,d as c,p as d,i as e,h as f,c as g,u as h,f as k,r,w as s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/CFIQ5hjj.js b/cli/internal/dashboard/static/_app/immutable/chunks/CFIQ5hjj.js new file mode 100644 index 0000000..9677edb --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/CFIQ5hjj.js @@ -0,0 +1 @@ +import{l as Ne,t as Vn}from"./DIeogL5L.js";const Gn=!1;var zn=Array.isArray,Kn=Array.prototype.indexOf,ie=Array.prototype.includes,Vt=Array.from,Gt=Object.defineProperty,de=Object.getOwnPropertyDescriptor,$n=Object.getOwnPropertyDescriptors,Xn=Object.prototype,Zn=Array.prototype,on=Object.getPrototypeOf,We=Object.isExtensible;const Wn=()=>{};function zt(e){return e()}function Jn(e){for(var n=0;n{e=r,n=s});return{promise:t,resolve:e,reject:n}}const g=2,le=4,we=8,cn=1<<24,G=16,M=32,J=64,Qn=128,O=512,m=1024,T=2048,F=4096,P=8192,C=16384,re=32768,Je=1<<25,Ae=65536,Qe=1<<17,et=1<<18,ye=1<<19,_n=1<<20,Kt=1<<25,Q=65536,Ce=1<<21,He=1<<22,q=1<<23,Z=Symbol("$state"),$t=Symbol("legacy props"),Xt=Symbol(""),Y=new class extends Error{name="StaleReactionError";message="The reaction that called `getAbortSignal()` was re-run or destroyed"},Wt=!!globalThis.document?.contentType&&globalThis.document.contentType.includes("xml"),ke=3,vn=8;function dn(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function nt(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function Jt(e,n,t){throw new Error("https://svelte.dev/e/each_key_duplicate")}function tt(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function rt(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function st(e){throw new Error("https://svelte.dev/e/effect_orphan")}function it(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Qt(){throw new Error("https://svelte.dev/e/hydration_failed")}function er(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function lt(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function at(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function ft(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function nr(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const tr=1,rr=2,sr=4,ir=8,lr=16,ar=1,fr=2,or=4,ur=8,cr=16,_r=1,vr=2,ot="[",ut="[!",dr="[?",ct="]",qe={},b=Symbol(),_t="http://www.w3.org/1999/xhtml";function Ue(e){console.warn("https://svelte.dev/e/hydration_mismatch")}function hr(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function pr(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}let ee=!1;function wr(e){ee=e}let S;function ae(e){if(e===null)throw Ue(),qe;return S=e}function yr(){return ae(z(S))}function Er(e){if(ee){if(z(S)!==null)throw Ue(),qe;S=e}}function mr(e=1){if(ee){for(var n=e,t=S;n--;)t=z(t);S=t}}function gr(e=!0){for(var n=0,t=S;;){if(t.nodeType===vn){var r=t.data;if(r===ct){if(n===0)return t;n-=1}else(r===ot||r===ut||r[0]==="["&&!isNaN(Number(r.slice(1))))&&(n+=1)}var s=z(t);e&&t.remove(),t=s}}function br(e){if(!e||e.nodeType!==vn)throw Ue(),qe;return e.data}function hn(e){return e===this.v}function vt(e,n){return e!=e?n==n:e!==n||e!==null&&typeof e=="object"||typeof e=="function"}function pn(e){return!vt(e,this.v)}let E=null;function Se(e){E=e}function Tr(e,n=!1,t){E={p:E,i:!1,c:null,e:null,s:e,x:null,r:d,l:Ne&&!n?{s:null,u:null,$:[]}:null}}function Ar(e){var n=E,t=n.e;if(t!==null){n.e=null;for(var r of t)In(r)}return n.i=!0,E=n.p,{}}function Ee(){return!Ne||E!==null&&E.l===null}let $=[];function wn(){var e=$;$=[],Jn(e)}function en(e){if($.length===0&&!he){var n=$;queueMicrotask(()=>{n===$&&wn()})}$.push(e)}function dt(){for(;$.length>0;)wn()}function ht(e){var n=d;if(n===null)return v.f|=q,e;if((n.f&re)===0&&(n.f&le)===0)throw e;Re(e,n)}function Re(e,n){for(;n!==null;){if((n.f&Qn)!==0){if((n.f&re)===0)throw e;try{n.b.error(e);return}catch(t){e=t}}n=n.parent}throw e}const pt=-7169;function y(e,n){e.f=e.f&pt|n}function Be(e){(e.f&O)!==0||e.deps===null?y(e,m):y(e,F)}function yn(e){if(e!==null)for(const n of e)(n.f&g)===0||(n.f&Q)===0||(n.f^=Q,yn(n.deps))}function wt(e,n,t){(e.f&T)!==0?n.add(e):(e.f&F)!==0&&t.add(e),yn(e.deps),y(e,m)}const ce=new Set;let p=null,I=null,Me=null,he=!1,De=!1,se=null,be=null;var nn=0;let yt=1;class B{id=yt++;current=new Map;previous=new Map;#r=new Set;#s=new Set;#i=0;#l=0;#o=null;#e=[];#a=new Set;#t=new Set;#n=new Map;is_fork=!1;#f=!1;#u(){return this.is_fork||this.#l>0}skip_effect(n){this.#n.has(n)||this.#n.set(n,{d:[],m:[]})}unskip_effect(n){var t=this.#n.get(n);if(t){this.#n.delete(n);for(var r of t.d)y(r,T),this.schedule(r);for(r of t.m)y(r,F),this.schedule(r)}}#c(){nn++>1e3&&mt();const n=this.#e;this.#e=[],this.apply();var t=se=[],r=[],s=be=[];for(const l of n)this.#_(l,t,r);if(p=null,s.length>0){var i=B.ensure();for(const l of s)i.schedule(l)}if(se=null,be=null,this.#u()){this.#v(r),this.#v(t);for(const[l,a]of this.#n)gn(l,a)}else{this.#a.clear(),this.#t.clear();for(const l of this.#r)l(this);this.#r.clear(),tn(r),tn(t),this.#i===0&&this.#d(),this.#o?.resolve()}var o=p;if(this.#e.length>0){const l=o??=this;l.#e.push(...this.#e.filter(a=>!l.#e.includes(a)))}o!==null&&(ce.add(o),o.#c())}#_(n,t,r){n.f^=m;for(var s=n.first;s!==null;){var i=s.f,o=(i&(M|J))!==0,l=o&&(i&m)!==0,a=l||(i&P)!==0||this.#n.has(s);if(!a&&s.fn!==null){o?s.f^=m:(i&le)!==0?t.push(s):me(s)&&((i&G)!==0&&this.#t.add(s),oe(s));var f=s.first;if(f!==null){s=f;continue}}for(;s!==null;){var u=s.next;if(u!==null){s=u;break}s=s.parent}}}#v(n){for(var t=0;t1){this.previous.clear();var n=p,t=I,r=!0;for(const s of ce){if(s===this){r=!1;continue}const i=[];for(const[l,a]of this.current){if(s.current.has(l))if(r&&a!==s.current.get(l))s.current.set(l,a);else continue;i.push(l)}if(i.length===0)continue;const o=[...s.current.keys()].filter(l=>!this.current.has(l));if(o.length>0){s.activate();const l=new Set,a=new Map;for(const f of i)En(f,o,l,a);if(s.#e.length>0){s.apply();for(const f of s.#e)s.#_(f,[],[])}s.deactivate()}}p=n,I=t}this.#n.clear(),ce.delete(this)}increment(n){this.#i+=1,n&&(this.#l+=1)}decrement(n,t){this.#i-=1,n&&(this.#l-=1),!(this.#f||t)&&(this.#f=!0,en(()=>{this.#f=!1,this.flush()}))}oncommit(n){this.#r.add(n)}ondiscard(n){this.#s.add(n)}settled(){return(this.#o??=un()).promise}static ensure(){if(p===null){const n=p=new B;De||(ce.add(p),he||en(()=>{p===n&&n.flush()}))}return p}apply(){}schedule(n){if(Me=n,n.b?.is_pending&&(n.f&(le|we|cn))!==0&&(n.f&re)===0){n.b.defer_effect(n);return}for(var t=n;t.parent!==null;){t=t.parent;var r=t.f;if(se!==null&&t===d&&(v===null||(v.f&g)===0))return;if((r&(J|M))!==0){if((r&m)===0)return;t.f^=m}}this.#e.push(t)}}function Et(e){var n=he;he=!0;try{for(var t;;){if(dt(),p===null)return t;p.flush()}}finally{he=n}}function mt(){try{it()}catch(e){Re(e,Me)}}let j=null;function tn(e){var n=e.length;if(n!==0){for(var t=0;t0)){U.clear();for(const s of j){if((s.f&(C|P))!==0)continue;const i=[s];let o=s.parent;for(;o!==null;)j.has(o)&&(j.delete(o),i.push(o)),o=o.parent;for(let l=i.length-1;l>=0;l--){const a=i[l];(a.f&(C|P))===0&&oe(a)}}j.clear()}}j=null}}function En(e,n,t,r){if(!t.has(e)&&(t.add(e),e.reactions!==null))for(const s of e.reactions){const i=s.f;(i&g)!==0?En(s,n,t,r):(i&(He|G))!==0&&(i&T)===0&&mn(s,n,r)&&(y(s,T),Ve(s))}}function mn(e,n,t){const r=t.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const s of e.deps){if(ie.call(n,s))return!0;if((s.f&g)!==0&&mn(s,n,t))return t.set(s,!0),!0}return t.set(e,!1),!1}function Ve(e){p.schedule(e)}function gn(e,n){if(!((e.f&M)!==0&&(e.f&m)!==0)){(e.f&T)!==0?n.d.push(e):(e.f&F)!==0&&n.m.push(e),y(e,m);for(var t=e.first;t!==null;)gn(t,n),t=t.next}}function gt(e,n,t,r){const s=Ee()?Ge:At;var i=e.filter(c=>!c.settled);if(t.length===0&&i.length===0){r(n.map(s));return}var o=d,l=bt(),a=i.length===1?i[0].promise:i.length>1?Promise.all(i.map(c=>c.promise)):null;function f(c){l();try{r(c)}catch(w){(o.f&C)===0&&Re(w,o)}xe()}if(t.length===0){a.then(()=>f(n.map(s)));return}var u=bn();function _(){Promise.all(t.map(c=>Tt(c))).then(c=>f([...n.map(s),...c])).catch(c=>Re(c,o)).finally(()=>u())}a?a.then(()=>{l(),_(),xe()}):_()}function bt(){var e=d,n=v,t=E,r=p;return function(i=!0){fe(e),V(n),Se(t),i&&(e.f&C)===0&&(r?.activate(),r?.apply())}}function xe(e=!0){fe(null),V(null),Se(null),e&&p?.deactivate()}function bn(){var e=d.b,n=p,t=e.is_rendered();return e.update_pending_count(1,n),n.increment(t),(r=!1)=>{e.update_pending_count(-1,n),n.decrement(t,r)}}function Ge(e){var n=g|T,t=v!==null&&(v.f&g)!==0?v:null;return d!==null&&(d.f|=ye),{ctx:E,deps:null,effects:null,equals:hn,f:n,fn:e,reactions:null,rv:0,v:b,wv:0,parent:t??d,ac:null}}function Tt(e,n,t){let r=d;r===null&&nt();var s=void 0,i=Ke(b),o=!v,l=new Map;return Mt(()=>{var a=d,f=un();s=f.promise;try{Promise.resolve(e()).then(f.resolve,f.reject).finally(xe)}catch(w){f.reject(w),xe()}var u=p;if(o){if((a.f&re)!==0)var _=bn();if(r.b.is_rendered())l.get(u)?.reject(Y),l.delete(u);else{for(const w of l.values())w.reject(Y);l.clear()}l.set(u,f)}const c=(w,h=void 0)=>{if(_){var k=h===Y;_(k)}if(!(h===Y||(a.f&C)!==0)){if(u.activate(),h)i.f|=q,Le(i,h);else{(i.f&q)!==0&&(i.f^=q),Le(i,w);for(const[ue,ge]of l){if(l.delete(ue),ue===u)break;ge.reject(Y)}}u.deactivate()}};f.promise.then(c,w=>c(null,w||"unknown"))}),Pt(()=>{for(const a of l.values())a.reject(Y)}),new Promise(a=>{function f(u){function _(){u===s?a(i):f(s)}u.then(_,_)}f(s)})}function Sr(e){const n=Ge(e);return Fn(n),n}function At(e){const n=Ge(e);return n.equals=pn,n}function St(e){var n=e.effects;if(n!==null){e.effects=null;for(var t=0;t0&&!Sn&&Ot()}return n}function Ot(){Sn=!1;for(const e of Fe)(e.f&m)!==0&&y(e,F),me(e)&&oe(e);Fe.clear()}function Pe(e){K(e,e.v+1)}function Rn(e,n,t){var r=e.reactions;if(r!==null)for(var s=Ee(),i=r.length,o=0;o{if(W===i)return l();var a=v,f=W;V(null),fn(i);var u=l();return V(a),fn(f),u};return r&&t.set("length",H(e.length)),new Proxy(e,{defineProperty(l,a,f){(!("value"in f)||f.configurable===!1||f.enumerable===!1||f.writable===!1)&<();var u=t.get(a);return u===void 0?o(()=>{var _=H(f.value);return t.set(a,_),_}):K(u,f.value,!0),!0},deleteProperty(l,a){var f=t.get(a);if(f===void 0){if(a in l){const u=o(()=>H(b));t.set(a,u),Pe(s)}}else K(f,b),Pe(s);return!0},get(l,a,f){if(a===Z)return e;var u=t.get(a),_=a in l;if(u===void 0&&(!_||de(l,a)?.writable)&&(u=o(()=>{var w=_e(_?l[a]:b),h=H(w);return h}),t.set(a,u)),u!==void 0){var c=ve(u);return c===b?void 0:c}return Reflect.get(l,a,f)},getOwnPropertyDescriptor(l,a){var f=Reflect.getOwnPropertyDescriptor(l,a);if(f&&"value"in f){var u=t.get(a);u&&(f.value=ve(u))}else if(f===void 0){var _=t.get(a),c=_?.v;if(_!==void 0&&c!==b)return{enumerable:!0,configurable:!0,value:c,writable:!0}}return f},has(l,a){if(a===Z)return!0;var f=t.get(a),u=f!==void 0&&f.v!==b||Reflect.has(l,a);if(f!==void 0||d!==null&&(!u||de(l,a)?.writable)){f===void 0&&(f=o(()=>{var c=u?_e(l[a]):b,w=H(c);return w}),t.set(a,f));var _=ve(f);if(_===b)return!1}return u},set(l,a,f,u){var _=t.get(a),c=a in l;if(r&&a==="length")for(var w=f;w<_.v;w+=1){var h=t.get(w+"");h!==void 0?K(h,b):w in l&&(h=o(()=>H(b)),t.set(w+"",h))}if(_===void 0)(!c||de(l,a)?.writable)&&(_=o(()=>H(void 0)),K(_,_e(f)),t.set(a,_));else{c=_.v!==b;var k=o(()=>_e(f));K(_,k)}var ue=Reflect.getOwnPropertyDescriptor(l,a);if(ue?.set&&ue.set.call(u,f),!c){if(r&&typeof a=="string"){var ge=t.get("length"),Ie=Number(a);Number.isInteger(Ie)&&Ie>=ge.v&&K(ge,Ie+1)}Pe(s)}return!0},ownKeys(l){ve(s);var a=Reflect.ownKeys(l).filter(_=>{var c=t.get(_);return c===void 0||c.v!==b});for(var[f,u]of t)u.v!==b&&!(f in l)&&a.push(f);return a},setPrototypeOf(){at()}})}function rn(e){try{if(e!==null&&typeof e=="object"&&Z in e)return e[Z]}catch{}return e}function xr(e,n){return Object.is(rn(e),rn(n))}var sn,Nt,kt,xn,On;function Or(){if(sn===void 0){sn=window,Nt=document,kt=/Firefox/.test(navigator.userAgent);var e=Element.prototype,n=Node.prototype,t=Text.prototype;xn=de(n,"firstChild").get,On=de(n,"nextSibling").get,We(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),We(t)&&(t.__t=void 0)}}function Oe(e=""){return document.createTextNode(e)}function je(e){return xn.call(e)}function z(e){return On.call(e)}function Nr(e,n){if(!ee)return je(e);var t=je(S);if(t===null)t=S.appendChild(Oe());else if(n&&t.nodeType!==ke){var r=Oe();return t?.before(r),ae(r),r}return n&&$e(t),ae(t),t}function kr(e,n=!1){if(!ee){var t=je(e);return t instanceof Comment&&t.data===""?z(t):t}if(n){if(S?.nodeType!==ke){var r=Oe();return S?.before(r),ae(r),r}$e(S)}return S}function Ir(e,n=1,t=!1){let r=ee?S:e;for(var s;n--;)s=r,r=z(r);if(!ee)return r;if(t){if(r?.nodeType!==ke){var i=Oe();return r===null?s?.after(i):r.before(i),ae(i),i}$e(r)}return ae(r),r}function Dr(e){e.textContent=""}function Pr(){return!1}function Cr(e,n,t){return document.createElementNS(_t,e,void 0)}function $e(e){if(e.nodeValue.length<65536)return;let n=e.nextSibling;for(;n!==null&&n.nodeType===ke;)n.remove(),e.nodeValue+=n.nodeValue,n=e.nextSibling}let ln=!1;function It(){ln||(ln=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(const n of e.target.elements)n.__on_r?.()})},{capture:!0}))}function Xe(e){var n=v,t=d;V(null),fe(null);try{return e()}finally{V(n),fe(t)}}function Mr(e,n,t,r=t){e.addEventListener(n,()=>Xe(t));const s=e.__on_r;s?e.__on_r=()=>{s(),r(!0)}:e.__on_r=()=>r(!0),It()}function Nn(e){d===null&&(v===null&&st(),rt()),te&&tt()}function Dt(e,n){var t=n.last;t===null?n.last=n.first=e:(t.next=e,e.prev=t,n.last=e)}function L(e,n){var t=d;t!==null&&(t.f&P)!==0&&(e|=P);var r={ctx:E,deps:null,nodes:null,f:e|T|O,first:null,fn:n,last:null,next:null,parent:t,b:t&&t.b,prev:null,teardown:null,wv:0,ac:null},s=r;if((e&le)!==0)se!==null?se.push(r):B.ensure().schedule(r);else if(n!==null){try{oe(r)}catch(o){throw ne(r),o}s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&ye)===0&&(s=s.first,(e&G)!==0&&(e&Ae)!==0&&s!==null&&(s.f|=Ae))}if(s!==null&&(s.parent=t,t!==null&&Dt(s,t),v!==null&&(v.f&g)!==0&&(e&J)===0)){var i=v;(i.effects??=[]).push(s)}return r}function kn(){return v!==null&&!D}function Pt(e){const n=L(we,null);return y(n,m),n.teardown=e,n}function Ct(e){Nn();var n=d.f,t=!v&&(n&M)!==0&&(n&re)===0;if(t){var r=E;(r.e??=[]).push(e)}else return In(e)}function In(e){return L(le|_n,e)}function Fr(e){return Nn(),L(we|_n,e)}function Lr(e){B.ensure();const n=L(J|ye,e);return(t={})=>new Promise(r=>{t.outro?jt(n,()=>{ne(n),r(void 0)}):(ne(n),r(void 0))})}function jr(e){return L(le,e)}function Mt(e){return L(He|ye,e)}function Yr(e,n=0){return L(we|n,e)}function Hr(e,n=[],t=[],r=[]){gt(r,n,t,s=>{L(we,()=>e(...s.map(ve)))})}function qr(e,n=0){var t=L(G|n,e);return t}function Ur(e){return L(M|ye,e)}function Dn(e){var n=e.teardown;if(n!==null){const t=te,r=v;an(!0),V(null);try{n.call(null)}finally{an(t),V(r)}}}function Ze(e,n=!1){var t=e.first;for(e.first=e.last=null;t!==null;){const s=t.ac;s!==null&&Xe(()=>{s.abort(Y)});var r=t.next;(t.f&J)!==0?t.parent=null:ne(t,n),t=r}}function Ft(e){for(var n=e.first;n!==null;){var t=n.next;(n.f&M)===0&&ne(n),n=t}}function ne(e,n=!0){var t=!1;(n||(e.f&et)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(Lt(e.nodes.start,e.nodes.end),t=!0),y(e,Je),Ze(e,n&&!t),pe(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const i of r)i.stop();Dn(e),e.f^=Je,e.f|=C;var s=e.parent;s!==null&&s.first!==null&&Pn(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function Lt(e,n){for(;e!==null;){var t=e===n?null:z(e);e.remove(),e=t}}function Pn(e){var n=e.parent,t=e.prev,r=e.next;t!==null&&(t.next=r),r!==null&&(r.prev=t),n!==null&&(n.first===e&&(n.first=r),n.last===e&&(n.last=t))}function jt(e,n,t=!0){var r=[];Cn(e,r,!0);var s=()=>{t&&ne(e),n&&n()},i=r.length;if(i>0){var o=()=>--i||s();for(var l of r)l.out(o)}else s()}function Cn(e,n,t){if((e.f&P)===0){e.f^=P;var r=e.nodes&&e.nodes.t;if(r!==null)for(const l of r)(l.is_global||t)&&n.push(l);for(var s=e.first;s!==null;){var i=s.next,o=(s.f&Ae)!==0||(s.f&M)!==0&&(e.f&G)!==0;Cn(s,n,o?t:!1),s=i}}}function Br(e){Mn(e,!0)}function Mn(e,n){if((e.f&P)!==0){e.f^=P,(e.f&m)===0&&(y(e,T),B.ensure().schedule(e));for(var t=e.first;t!==null;){var r=t.next,s=(t.f&Ae)!==0||(t.f&M)!==0;Mn(t,s?n:!1),t=r}var i=e.nodes&&e.nodes.t;if(i!==null)for(const o of i)(o.is_global||n)&&o.in()}}function Vr(e,n){if(e.nodes)for(var t=e.nodes.start,r=e.nodes.end;t!==null;){var s=t===r?null:z(t);n.append(t),t=s}}let Te=!1,te=!1;function an(e){te=e}let v=null,D=!1;function V(e){v=e}let d=null;function fe(e){d=e}let N=null;function Fn(e){v!==null&&(N===null?N=[e]:N.push(e))}let A=null,R=0,x=null;function Yt(e){x=e}let Ln=1,X=0,W=X;function fn(e){W=e}function jn(){return++Ln}function me(e){var n=e.f;if((n&T)!==0)return!0;if(n&g&&(e.f&=~Q),(n&F)!==0){for(var t=e.deps,r=t.length,s=0;se.wv)return!0}(n&O)!==0&&I===null&&y(e,m)}return!1}function Yn(e,n,t=!0){var r=e.reactions;if(r!==null&&!(N!==null&&ie.call(N,e)))for(var s=0;s{e.ac.abort(Y)}),e.ac=null);try{e.f|=Ce;var u=e.fn,_=u();e.f|=re;var c=e.deps,w=p?.is_fork;if(A!==null){var h;if(w||pe(e,R),c!==null&&R>0)for(c.length=R+A.length,h=0;h{const n=Bn(e);if(typeof n=="function")return n})}function $r(e){E===null&&dn(),qt(()=>()=>Bn(e))}function Ut(e){var n=e.l;return n.u??={a:[],b:[],m:[]}}export{qt as $,xr as A,de as B,er as C,Je as D,_e as E,K as F,te as G,C as H,ur as I,fr as J,ar as K,At as L,cr as M,$t as N,Xt as O,or as P,_t as Q,Wt as R,Z as S,on as T,en as U,It as V,$n as W,Gt as X,Wn as Y,Rr as Z,H as _,d as a,ke as a$,Sr as a0,$r as a1,vt as a2,Oe as a3,qr as a4,sr as a5,ae as a6,je as a7,yr as a8,br as a9,ot as aA,Et as aB,kn as aC,Pe as aD,Qn as aE,dr as aF,y as aG,T as aH,F as aI,wt as aJ,fe as aK,V as aL,Se as aM,B as aN,ht as aO,v as aP,mr as aQ,Re as aR,ye as aS,nr as aT,pr as aU,Xe as aV,Cr as aW,kt as aX,_r as aY,vr as aZ,re as a_,ut as aa,gr as ab,wr as ac,S as ad,vn as ae,ct as af,Le as ag,Kt as ah,Ur as ai,Jt as aj,Pr as ak,Vt as al,tr as am,lr as an,Ke as ao,rr as ap,Br as aq,jt as ar,P as as,M as at,ir as au,Dr as av,Vr as aw,ne as ax,z as ay,Ae as az,Ar as b,$e as b0,Or as b1,qe as b2,Qt as b3,Lr as b4,Ue as b5,et as b6,Nt as b7,zr as b8,E as c,Nr as d,jr as e,kr as f,Er as g,Fr as h,Ct as i,Jn as j,zt as k,ve as l,Kr as m,Ge as n,Mr as o,Tr as p,p as q,Yr as r,Ir as s,Hr as t,Bn as u,Gr as v,ee as w,Pt as x,zn as y,hr as z}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/CJ8mMi92.js b/cli/internal/dashboard/static/_app/immutable/chunks/CJ8mMi92.js new file mode 100644 index 0000000..4915482 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/CJ8mMi92.js @@ -0,0 +1 @@ +import{$ as Ne,_ as U,l as A,F as P,v as ee,b8 as gt}from"./CFIQ5hjj.js";import{w as ke}from"./Dv0Hwark.js";import{b as mt,H as Re,S as Se,R as Ee}from"./BUApaBEI.js";new URL("sveltekit-internal://");function _t(e,t){return e==="/"||t==="ignore"?e:t==="never"?e.endsWith("/")?e.slice(0,-1):e:t==="always"&&!e.endsWith("/")?e+"/":e}function vt(e){return e.split("%25").map(decodeURI).join("%25")}function wt(e){for(const t in e)e[t]=decodeURIComponent(e[t]);return e}function he({href:e}){return e.split("#")[0]}function yt(e,t,n,a=!1){const r=new URL(e);Object.defineProperty(r,"searchParams",{value:new Proxy(r.searchParams,{get(s,o){if(o==="get"||o==="getAll"||o==="has")return(c,...d)=>(n(c),s[o](c,...d));t();const l=Reflect.get(s,o);return typeof l=="function"?l.bind(s):l}}),enumerable:!0,configurable:!0});const i=["href","pathname","search","toString","toJSON"];a&&i.push("hash");for(const s of i)Object.defineProperty(r,s,{get(){return t(),e[s]},enumerable:!0,configurable:!0});return r}function bt(...e){let t=5381;for(const n of e)if(typeof n=="string"){let a=n.length;for(;a;)t=t*33^n.charCodeAt(--a)}else if(ArrayBuffer.isView(n)){const a=new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let r=a.length;for(;r;)t=t*33^a[--r]}else throw new TypeError("value must be a string or TypedArray");return(t>>>0).toString(36)}const kt=window.fetch;window.fetch=(e,t)=>((e instanceof Request?e.method:t?.method||"GET")!=="GET"&&G.delete(xe(e)),kt(e,t));const G=new Map;function Rt(e,t){const n=xe(e,t),a=document.querySelector(n);if(a?.textContent){a.remove();let{body:r,...i}=JSON.parse(a.textContent);const s=a.getAttribute("data-ttl");return s&&G.set(n,{body:r,init:i,ttl:1e3*Number(s)}),a.getAttribute("data-b64")!==null&&(r=mt(r)),Promise.resolve(new Response(r,i))}return window.fetch(e,t)}function St(e,t,n){if(G.size>0){const a=xe(e,n),r=G.get(a);if(r){if(performance.now(){const r=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(a);if(r)return t.push({name:r[1],matcher:r[2],optional:!1,rest:!0,chained:!0}),"(?:/([^]*))?";const i=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(a);if(i)return t.push({name:i[1],matcher:i[2],optional:!0,rest:!1,chained:!0}),"(?:/([^/]+))?";if(!a)return;const s=a.split(/\[(.+?)\](?!\])/);return"/"+s.map((l,c)=>{if(c%2){if(l.startsWith("x+"))return pe(String.fromCharCode(parseInt(l.slice(2),16)));if(l.startsWith("u+"))return pe(String.fromCharCode(...l.slice(2).split("-").map(v=>parseInt(v,16))));const d=Et.exec(l),[,p,f,u,h]=d;return t.push({name:u,matcher:h,optional:!!p,rest:!!f,chained:f?c===1&&s[0]==="":!1}),f?"([^]*?)":p?"([^/]*)?":"([^/]+?)"}return pe(l)}).join("")}).join("")}/?$`),params:t}}function Lt(e){return e!==""&&!/^\([^)]+\)$/.test(e)}function Ut(e){return e.slice(1).split("/").filter(Lt)}function At(e,t,n){const a={},r=e.slice(1),i=r.filter(o=>o!==void 0);let s=0;for(let o=0;od).join("/"),s=0),c===void 0)if(l.rest)c="";else continue;if(!l.matcher||n[l.matcher](c)){a[l.name]=c;const d=t[o+1],p=r[o+1];d&&!d.rest&&d.optional&&p&&l.chained&&(s=0),!d&&!p&&Object.keys(a).length===i.length&&(s=0);continue}if(l.optional&&l.chained){s++;continue}return}if(!s)return a}function pe(e){return e.normalize().replace(/[[\]]/g,"\\$&").replace(/%/g,"%25").replace(/\//g,"%2[Ff]").replace(/\?/g,"%3[Ff]").replace(/#/g,"%23").replace(/[.*+?^${}()|\\]/g,"\\$&")}function Pt({nodes:e,server_loads:t,dictionary:n,matchers:a}){const r=new Set(t);return Object.entries(n).map(([o,[l,c,d]])=>{const{pattern:p,params:f}=xt(o),u={id:o,exec:h=>{const v=p.exec(h);if(v)return At(v,f,a)},errors:[1,...d||[]].map(h=>e[h]),layouts:[0,...c||[]].map(s),leaf:i(l)};return u.errors.length=u.layouts.length=Math.max(u.errors.length,u.layouts.length),u});function i(o){const l=o<0;return l&&(o=~o),[l,e[o]]}function s(o){return o===void 0?o:[r.has(o),e[o]]}}function Me(e,t=JSON.parse){try{return t(sessionStorage[e])}catch{}}function qe(e,t,n=JSON.stringify){const a=n(t);try{sessionStorage[e]=a}catch{}}const x=globalThis.__sveltekit_6ooad6?.base??"",Tt=globalThis.__sveltekit_6ooad6?.assets??x??"",It="1773281563336",We="sveltekit:snapshot",Ye="sveltekit:scroll",ze="sveltekit:states",Ot="sveltekit:pageurl",B="sveltekit:history",M="sveltekit:navigation",j={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},ce=location.origin;function Le(e){if(e instanceof URL)return e;let t=document.baseURI;if(!t){const n=document.getElementsByTagName("base");t=n.length?n[0].href:document.URL}return new URL(e,t)}function q(){return{x:pageXOffset,y:pageYOffset}}function V(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const De={...j,"":j.hover};function Je(e){let t=e.assignedSlot??e.parentNode;return t?.nodeType===11&&(t=t.host),t}function Xe(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=Je(e)}}function _e(e,t,n){let a;try{if(a=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI),n&&a.hash.match(/^#[^/]/)){const o=location.hash.split("#")[1]||"/";a.hash=`#${o}${a.hash}`}}catch{}const r=e instanceof SVGAElement?e.target.baseVal:e.target,i=!a||!!r||ue(a,t,n)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),s=a?.origin===ce&&e.hasAttribute("download");return{url:a,external:i,target:r,download:s}}function te(e){let t=null,n=null,a=null,r=null,i=null,s=null,o=e;for(;o&&o!==document.documentElement;)a===null&&(a=V(o,"preload-code")),r===null&&(r=V(o,"preload-data")),t===null&&(t=V(o,"keepfocus")),n===null&&(n=V(o,"noscroll")),i===null&&(i=V(o,"reload")),s===null&&(s=V(o,"replacestate")),o=Je(o);function l(c){switch(c){case"":case"true":return!0;case"off":case"false":return!1;default:return}}return{preload_code:De[a??"off"],preload_data:De[r??"off"],keepfocus:l(t),noscroll:l(n),reload:l(i),replace_state:l(s)}}function Ve(e){const t=ke(e);let n=!0;function a(){n=!0,t.update(s=>s)}function r(s){n=!1,t.set(s)}function i(s){let o;return t.subscribe(l=>{(o===void 0||n&&l!==o)&&s(o=l)})}return{notify:a,set:r,subscribe:i}}const Qe={v:()=>{}};function $t(){const{set:e,subscribe:t}=ke(!1);let n;async function a(){clearTimeout(n);try{const r=await fetch(`${Tt}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!r.ok)return!1;const s=(await r.json()).version!==It;return s&&(e(!0),Qe.v(),clearTimeout(n)),s}catch{return!1}}return{subscribe:t,check:a}}function ue(e,t,n){return e.origin!==ce||!e.pathname.startsWith(t)?!0:n?e.pathname!==location.pathname:!1}function cn(e){}const Ze=new Set(["load","prerender","csr","ssr","trailingSlash","config"]);[...Ze];const Ct=new Set([...Ze]);[...Ct];function jt(e){return e.filter(t=>t!=null)}function Ue(e){return e instanceof Re||e instanceof Se?e.status:500}function Nt(e){return e instanceof Se?e.text:"Internal Error"}let k,W,ge;const qt=Ne.toString().includes("$$")||/function \w+\(\) \{\}/.test(Ne.toString());qt?(k={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL("https://example.com")},W={current:null},ge={current:!1}):(k=new class{#e=U({});get data(){return A(this.#e)}set data(t){P(this.#e,t)}#t=U(null);get form(){return A(this.#t)}set form(t){P(this.#t,t)}#n=U(null);get error(){return A(this.#n)}set error(t){P(this.#n,t)}#a=U({});get params(){return A(this.#a)}set params(t){P(this.#a,t)}#r=U({id:null});get route(){return A(this.#r)}set route(t){P(this.#r,t)}#o=U({});get state(){return A(this.#o)}set state(t){P(this.#o,t)}#s=U(-1);get status(){return A(this.#s)}set status(t){P(this.#s,t)}#i=U(new URL("https://example.com"));get url(){return A(this.#i)}set url(t){P(this.#i,t)}},W=new class{#e=U(null);get current(){return A(this.#e)}set current(t){P(this.#e,t)}},ge=new class{#e=U(!1);get current(){return A(this.#e)}set current(t){P(this.#e,t)}},Qe.v=()=>ge.current=!0);function Dt(e){Object.assign(k,e)}const Be={spanContext(){return Vt},setAttribute(){return this},setAttributes(){return this},addEvent(){return this},setStatus(){return this},updateName(){return this},end(){return this},isRecording(){return!1},recordException(){return this},addLink(){return this},addLinks(){return this}},Vt={traceId:"",spanId:"",traceFlags:0},Bt=new Set(["icon","shortcut icon","apple-touch-icon"]),C=Me(Ye)??{},Y=Me(We)??{},$={url:Ve({}),page:Ve({}),navigating:ke(null),updated:$t()};function Ae(e){C[e]=q()}function Ft(e,t){let n=e+1;for(;C[n];)delete C[n],n+=1;for(n=t+1;Y[n];)delete Y[n],n+=1}function z(e,t=!1){return t?location.replace(e.href):location.href=e.href,new Promise(()=>{})}async function et(){if("serviceWorker"in navigator){const e=await navigator.serviceWorker.getRegistration(x||"/");e&&await e.update()}}function Fe(){}let Pe,ve,ne,T,we,w;const ae=[],re=[];let L=null;function ye(){L?.fork?.then(e=>e?.discard()),L=null}const Z=new Map,tt=new Set,Kt=new Set,H=new Set;let _={branch:[],error:null,url:null},nt=!1,oe=!1,Ke=!0,J=!1,K=!1,at=!1,Te=!1,rt,y,E,N;const se=new Set,Ge=new Map;async function hn(e,t,n){globalThis.__sveltekit_6ooad6?.data&&globalThis.__sveltekit_6ooad6.data,document.URL!==location.href&&(location.href=location.href),w=e,await e.hooks.init?.(),Pe=Pt(e),T=document.documentElement,we=t,ve=e.nodes[0],ne=e.nodes[1],ve(),ne(),y=history.state?.[B],E=history.state?.[M],y||(y=E=Date.now(),history.replaceState({...history.state,[B]:y,[M]:E},""));const a=C[y];function r(){a&&(history.scrollRestoration="manual",scrollTo(a.x,a.y))}n?(r(),await tn(we,n)):(await F({type:"enter",url:Le(w.hash?rn(new URL(location.href)):location.href),replace_state:!0}),r()),en()}function Gt(){ae.length=0,Te=!1}function ot(e){re.some(t=>t?.snapshot)&&(Y[e]=re.map(t=>t?.snapshot?.capture()))}function st(e){Y[e]?.forEach((t,n)=>{re[n]?.snapshot?.restore(t)})}function He(){Ae(y),qe(Ye,C),ot(E),qe(We,Y)}async function it(e,t,n,a){let r;t.invalidateAll&&ye(),await F({type:"goto",url:Le(e),keepfocus:t.keepFocus,noscroll:t.noScroll,replace_state:t.replaceState,state:t.state,redirect_count:n,nav_token:a,accept:()=>{t.invalidateAll&&(Te=!0,r=[...Ge.keys()]),t.invalidate&&t.invalidate.forEach(Zt)}}),t.invalidateAll&&ee().then(ee).then(()=>{Ge.forEach(({resource:i},s)=>{r?.includes(s)&&i.refresh?.()})})}async function Ht(e){if(e.id!==L?.id){ye();const t={};se.add(t),L={id:e.id,token:t,promise:ut({...e,preload:t}).then(n=>(se.delete(t),n.type==="loaded"&&n.state.error&&ye(),n)),fork:null}}return L.promise}async function me(e){const t=(await fe(e,!1))?.route;t&&await Promise.all([...t.layouts,t.leaf].filter(Boolean).map(n=>n[1]()))}async function lt(e,t,n){_=e.state;const a=document.querySelector("style[data-sveltekit]");if(a&&a.remove(),Object.assign(k,e.props.page),rt=new w.root({target:t,props:{...e.props,stores:$,components:re},hydrate:n,sync:!1}),await Promise.resolve(),st(E),n){const r={from:null,to:{params:_.params,route:{id:_.route?.id??null},url:new URL(location.href),scroll:C[y]??q()},willUnload:!1,type:"enter",complete:Promise.resolve()};H.forEach(i=>i(r))}oe=!0}function ie({url:e,params:t,branch:n,status:a,error:r,route:i,form:s}){let o="never";if(x&&(e.pathname===x||e.pathname===x+"/"))o="always";else for(const u of n)u?.slash!==void 0&&(o=u.slash);e.pathname=_t(e.pathname,o),e.search=e.search;const l={type:"loaded",state:{url:e,params:t,branch:n,error:r,route:i},props:{constructors:jt(n).map(u=>u.node.component),page:je(k)}};s!==void 0&&(l.props.form=s);let c={},d=!k,p=0;for(let u=0;u(o&&(l.route=!0),f[u])}),params:new Proxy(a,{get:(f,u)=>(o&&l.params.add(u),f[u])}),data:i?.data??null,url:yt(n,()=>{o&&(l.url=!0)},f=>{o&&l.search_params.add(f)},w.hash),async fetch(f,u){f instanceof Request&&(u={body:f.method==="GET"||f.method==="HEAD"?void 0:await f.blob(),cache:f.cache,credentials:f.credentials,headers:[...f.headers].length>0?f?.headers:void 0,integrity:f.integrity,keepalive:f.keepalive,method:f.method,mode:f.mode,redirect:f.redirect,referrer:f.referrer,referrerPolicy:f.referrerPolicy,signal:f.signal,...u});const{resolved:h,promise:v}=ct(f,u,n);return o&&d(h.href),v},setHeaders:()=>{},depends:d,parent(){return o&&(l.parent=!0),t()},untrack(f){o=!1;try{return f()}finally{o=!0}}};s=await c.universal.load.call(null,p)??null}return{node:c,loader:e,server:i,universal:c.universal?.load?{type:"data",data:s,uses:l}:null,data:s??i?.data??null,slash:c.universal?.trailingSlash??i?.slash}}function ct(e,t,n){let a=e instanceof Request?e.url:e;const r=new URL(a,n);r.origin===n.origin&&(a=r.href.slice(n.origin.length));const i=oe?St(a,r.href,t):Rt(a,t);return{resolved:r,promise:i}}function Mt(e,t,n,a,r,i){if(Te)return!0;if(!r)return!1;if(r.parent&&e||r.route&&t||r.url&&n)return!0;for(const s of r.search_params)if(a.has(s))return!0;for(const s of r.params)if(i[s]!==_.params[s])return!0;for(const s of r.dependencies)if(ae.some(o=>o(new URL(s))))return!0;return!1}function Oe(e,t){return e?.type==="data"?e:e?.type==="skip"?t??null:null}function Wt(e,t){if(!e)return new Set(t.searchParams.keys());const n=new Set([...e.searchParams.keys(),...t.searchParams.keys()]);for(const a of n){const r=e.searchParams.getAll(a),i=t.searchParams.getAll(a);r.every(s=>i.includes(s))&&i.every(s=>r.includes(s))&&n.delete(a)}return n}function Yt({error:e,url:t,route:n,params:a}){return{type:"loaded",state:{error:e,url:t,route:n,params:a,branch:[]},props:{page:je(k),constructors:[]}}}async function ut({id:e,invalidating:t,url:n,params:a,route:r,preload:i}){if(L?.id===e)return se.delete(L.token),L.promise;const{errors:s,layouts:o,leaf:l}=r,c=[...o,l];s.forEach(m=>m?.().catch(()=>{})),c.forEach(m=>m?.[1]().catch(()=>{}));const d=_.url?e!==le(_.url):!1,p=_.route?r.id!==_.route.id:!1,f=Wt(_.url,n);let u=!1;const h=c.map(async(m,g)=>{if(!m)return;const R=_.branch[g];return m[1]===R?.loader&&!Mt(u,p,d,f,R.universal?.uses,a)?R:(u=!0,Ie({loader:m[1],url:n,params:a,route:r,parent:async()=>{const I={};for(let O=0;O{});const v=[];for(let m=0;mPromise.resolve({}),server_data_node:Oe(i)}),o={node:await ne(),loader:ne,universal:null,server:null,data:null};return ie({url:n,params:r,branch:[s,o],status:e,error:t,route:null})}catch(s){if(s instanceof Ee)return it(new URL(s.location,location.href),{},0);throw s}}async function Jt(e){const t=e.href;if(Z.has(t))return Z.get(t);let n;try{const a=(async()=>{let r=await w.hooks.reroute({url:new URL(e),fetch:async(i,s)=>ct(i,s,e).promise})??e;if(typeof r=="string"){const i=new URL(e);w.hash?i.hash=r:i.pathname=r,r=i}return r})();Z.set(t,a),n=await a}catch{Z.delete(t);return}return n}async function fe(e,t){if(e&&!ue(e,x,w.hash)){const n=await Jt(e);if(!n)return;const a=Xt(n);for(const r of Pe){const i=r.exec(a);if(i)return{id:le(e),invalidating:t,route:r,params:wt(i),url:e}}}}function Xt(e){return vt(w.hash?e.hash.replace(/^#/,"").replace(/[?#].+/,""):e.pathname.slice(x.length))||"/"}function le(e){return(w.hash?e.hash.replace(/^#/,""):e.pathname)+e.search}function ft({url:e,type:t,intent:n,delta:a,event:r,scroll:i}){let s=!1;const o=Ce(_,n,e,t,i??null);a!==void 0&&(o.navigation.delta=a),r!==void 0&&(o.navigation.event=r);const l={...o.navigation,cancel:()=>{s=!0,o.reject(new Error("navigation cancelled"))}};return J||tt.forEach(c=>c(l)),s?null:o}async function F({type:e,url:t,popped:n,keepfocus:a,noscroll:r,replace_state:i,state:s={},redirect_count:o=0,nav_token:l={},accept:c=Fe,block:d=Fe,event:p}){const f=N;N=l;const u=await fe(t,!1),h=e==="enter"?Ce(_,u,t,e):ft({url:t,type:e,delta:n?.delta,intent:u,scroll:n?.scroll,event:p});if(!h){d(),N===l&&(N=f);return}const v=y,m=E;c(),J=!0,oe&&h.navigation.type!=="enter"&&$.navigating.set(W.current=h.navigation);let g=u&&await ut(u);if(!g){if(ue(t,x,w.hash))return await z(t,i);g=await dt(t,{id:null},await X(new Se(404,"Not Found",`Not found: ${t.pathname}`),{url:t,params:{},route:{id:null}}),404,i)}if(t=u?.url||t,N!==l)return h.reject(new Error("navigation aborted")),!1;if(g.type==="redirect"){if(o<20){await F({type:e,url:new URL(g.location,t),popped:n,keepfocus:a,noscroll:r,replace_state:i,state:s,redirect_count:o+1,nav_token:l}),h.fulfil(void 0);return}g=await $e({status:500,error:await X(new Error("Redirect loop"),{url:t,params:{},route:{id:null}}),url:t,route:{id:null}})}else g.props.page.status>=400&&await $.updated.check()&&(await et(),await z(t,i));if(Gt(),Ae(v),ot(m),g.props.page.url.pathname!==t.pathname&&(t.pathname=g.props.page.url.pathname),s=n?n.state:s,!n){const b=i?0:1,Q={[B]:y+=b,[M]:E+=b,[ze]:s};(i?history.replaceState:history.pushState).call(history,Q,"",t),i||Ft(y,E)}const R=u&&L?.id===u.id?L.fork:null;L=null,g.props.page.state=s;let S;if(oe){const b=(await Promise.all(Array.from(Kt,D=>D(h.navigation)))).filter(D=>typeof D=="function");if(b.length>0){let D=function(){b.forEach(de=>{H.delete(de)})};b.push(D),b.forEach(de=>{H.add(de)})}_=g.state,g.props.page&&(g.props.page.url=t);const Q=R&&await R;Q?S=Q.commit():(rt.$set(g.props),Dt(g.props.page),S=gt?.()),at=!0}else await lt(g,we,!1);const{activeElement:I}=document;await S,await ee(),await ee();let O=null;if(Ke){const b=n?n.scroll:r?q():null;b?scrollTo(b.x,b.y):(O=t.hash&&document.getElementById(ht(t)))?O.scrollIntoView():scrollTo(0,0)}const pt=document.activeElement!==I&&document.activeElement!==document.body;!a&&!pt&&an(t,!O),Ke=!0,g.props.page&&Object.assign(k,g.props.page),J=!1,e==="popstate"&&st(E),h.fulfil(void 0),h.navigation.to&&(h.navigation.to.scroll=q()),H.forEach(b=>b(h.navigation)),$.navigating.set(W.current=null)}async function dt(e,t,n,a,r){return e.origin===ce&&e.pathname===location.pathname&&!nt?await $e({status:a,error:n,url:e,route:t}):await z(e,r)}function Qt(){let e,t={element:void 0,href:void 0},n;T.addEventListener("mousemove",o=>{const l=o.target;clearTimeout(e),e=setTimeout(()=>{i(l,j.hover)},20)});function a(o){o.defaultPrevented||i(o.composedPath()[0],j.tap)}T.addEventListener("mousedown",a),T.addEventListener("touchstart",a,{passive:!0});const r=new IntersectionObserver(o=>{for(const l of o)l.isIntersecting&&(me(new URL(l.target.href)),r.unobserve(l.target))},{threshold:0});async function i(o,l){const c=Xe(o,T),d=c===t.element&&c?.href===t.href&&l>=n;if(!c||d)return;const{url:p,external:f,download:u}=_e(c,x,w.hash);if(f||u)return;const h=te(c),v=p&&le(_.url)===le(p);if(!(h.reload||v))if(l<=h.preload_data){t={element:c,href:c.href},n=j.tap;const m=await fe(p,!1);if(!m)return;Ht(m)}else l<=h.preload_code&&(t={element:c,href:c.href},n=l,me(p))}function s(){r.disconnect();for(const o of T.querySelectorAll("a")){const{url:l,external:c,download:d}=_e(o,x,w.hash);if(c||d)continue;const p=te(o);p.reload||(p.preload_code===j.viewport&&r.observe(o),p.preload_code===j.eager&&me(l))}}H.add(s),s()}function X(e,t){if(e instanceof Re)return e.body;const n=Ue(e),a=Nt(e);return w.hooks.handleError({error:e,event:t,status:n,message:a})??{message:a}}function pn(e,t={}){return e=new URL(Le(e)),e.origin!==ce?Promise.reject(new Error("goto: invalid URL")):it(e,t,0)}function Zt(e){if(typeof e=="function")ae.push(e);else{const{href:t}=new URL(e,location.href);ae.push(n=>n.href===t)}}function en(){history.scrollRestoration="manual",addEventListener("beforeunload",t=>{let n=!1;if(He(),!J){const a=Ce(_,void 0,null,"leave"),r={...a.navigation,cancel:()=>{n=!0,a.reject(new Error("navigation cancelled"))}};tt.forEach(i=>i(r))}n?(t.preventDefault(),t.returnValue=""):history.scrollRestoration="auto"}),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&He()}),navigator.connection?.saveData||Qt(),T.addEventListener("click",async t=>{if(t.button||t.which!==1||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.defaultPrevented)return;const n=Xe(t.composedPath()[0],T);if(!n)return;const{url:a,external:r,target:i,download:s}=_e(n,x,w.hash);if(!a)return;if(i==="_parent"||i==="_top"){if(window.parent!==window)return}else if(i&&i!=="_self")return;const o=te(n);if(!(n instanceof SVGAElement)&&a.protocol!==location.protocol&&!(a.protocol==="https:"||a.protocol==="http:")||s)return;const[c,d]=(w.hash?a.hash.replace(/^#/,""):a.href).split("#"),p=c===he(location);if(r||o.reload&&(!p||!d)){ft({url:a,type:"link",event:t})?J=!0:t.preventDefault();return}if(d!==void 0&&p){const[,f]=_.url.href.split("#");if(f===d){if(t.preventDefault(),d===""||d==="top"&&n.ownerDocument.getElementById("top")===null)scrollTo({top:0});else{const u=n.ownerDocument.getElementById(decodeURIComponent(d));u&&(u.scrollIntoView(),u.focus())}return}if(K=!0,Ae(y),e(a),!o.replace_state)return;K=!1}t.preventDefault(),await new Promise(f=>{requestAnimationFrame(()=>{setTimeout(f,0)}),setTimeout(f,100)}),await F({type:"link",url:a,keepfocus:o.keepfocus,noscroll:o.noscroll,replace_state:o.replace_state??a.href===location.href,event:t})}),T.addEventListener("submit",t=>{if(t.defaultPrevented)return;const n=HTMLFormElement.prototype.cloneNode.call(t.target),a=t.submitter;if((a?.formTarget||n.target)==="_blank"||(a?.formMethod||n.method)!=="get")return;const s=new URL(a?.hasAttribute("formaction")&&a?.formAction||n.action);if(ue(s,x,!1))return;const o=t.target,l=te(o);if(l.reload)return;t.preventDefault(),t.stopPropagation();const c=new FormData(o,a);s.search=new URLSearchParams(c).toString(),F({type:"form",url:s,keepfocus:l.keepfocus,noscroll:l.noscroll,replace_state:l.replace_state??s.href===location.href,event:t})}),addEventListener("popstate",async t=>{if(!be){if(t.state?.[B]){const n=t.state[B];if(N={},n===y)return;const a=C[n],r=t.state[ze]??{},i=new URL(t.state[Ot]??location.href),s=t.state[M],o=_.url?he(location)===he(_.url):!1;if(s===E&&(at||o)){r!==k.state&&(k.state=r),e(i),C[y]=q(),a&&scrollTo(a.x,a.y),y=n;return}const c=n-y;await F({type:"popstate",url:i,popped:{state:r,scroll:a,delta:c},accept:()=>{y=n,E=s},block:()=>{history.go(-c)},nav_token:N,event:t})}else if(!K){const n=new URL(location.href);e(n),w.hash&&location.reload()}}}),addEventListener("hashchange",()=>{K&&(K=!1,history.replaceState({...history.state,[B]:++y,[M]:E},"",location.href))});for(const t of document.querySelectorAll("link"))Bt.has(t.rel)&&(t.href=t.href);addEventListener("pageshow",t=>{t.persisted&&$.navigating.set(W.current=null)});function e(t){_.url=k.url=t,$.page.set(je(k)),$.page.notify()}}async function tn(e,{status:t=200,error:n,node_ids:a,params:r,route:i,server_route:s,data:o,form:l}){nt=!0;const c=new URL(location.href);let d;({params:r={},route:i={id:null}}=await fe(c,!1)||{}),d=Pe.find(({id:u})=>u===i.id);let p,f=!0;try{const u=a.map(async(v,m)=>{const g=o[m];return g?.uses&&(g.uses=nn(g.uses)),Ie({loader:w.nodes[v],url:c,params:r,route:i,parent:async()=>{const R={};for(let S=0;S{const o=history.state;be=!0,location.replace(new URL(`#${a}`,location.href)),history.replaceState(o,"",e),t&&scrollTo(i,s),be=!1})}else{const i=document.body,s=i.getAttribute("tabindex");i.tabIndex=-1,i.focus({preventScroll:!0,focusVisible:!1}),s!==null?i.setAttribute("tabindex",s):i.removeAttribute("tabindex")}const r=getSelection();if(r&&r.type!=="None"){const i=[];for(let s=0;s{if(r.rangeCount===i.length){for(let s=0;s{i=c,s=d});return o.catch(()=>{}),{navigation:{from:{params:e.params,route:{id:e.route?.id??null},url:e.url,scroll:q()},to:n&&{params:t?.params??null,route:{id:t?.route?.id??null},url:n,scroll:r},willUnload:!t,type:a,complete:o},fulfil:i,reject:s}}function je(e){return{data:e.data,error:e.error,form:e.form,params:e.params,route:e.route,state:e.state,status:e.status,url:e.url}}function rn(e){const t=new URL(e);return t.hash=decodeURIComponent(e.hash),t}function ht(e){let t;if(w.hash){const[,,n]=e.hash.split("#",3);t=n??""}else t=e.hash.slice(1);return decodeURIComponent(t)}export{hn as a,pn as g,cn as l,k as p,$ as s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/CMrUtYuQ.js b/cli/internal/dashboard/static/_app/immutable/chunks/CMrUtYuQ.js new file mode 100644 index 0000000..74f1fa1 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/CMrUtYuQ.js @@ -0,0 +1 @@ +import"./DsnmJJEf.js";import{p as m,d as i,g as l,s as g,t as x,l as e,b as h,_ as y,F as r}from"./CFIQ5hjj.js";import{d as _,s as f,b as c,a as k,f as j}from"./ByVGy8qs.js";import{b as w,r as G}from"./C67DyfnJ.js";var A=j('
');function B(u,n){m(n,!0);let t=y(!1);async function p(){if(!e(t)){r(t,!0);try{await w(n.worktree)}finally{r(t,!1)}}}async function v(){if(!e(t)){r(t,!0);try{await G(n.worktree)}finally{r(t,!1)}}}var o=A(),a=i(o),d=i(a,!0);l(a);var s=g(a,2),b=i(s,!0);l(s),l(o),x(()=>{a.disabled=e(t),f(d,e(t)?"...":"Approve"),s.disabled=e(t),f(b,e(t)?"...":"Reject")}),c("click",a,p),c("click",s,v),k(u,o),h()}_(["click"]);export{B as G}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/CQvy7xpd.js b/cli/internal/dashboard/static/_app/immutable/chunks/CQvy7xpd.js new file mode 100644 index 0000000..eea011e --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/CQvy7xpd.js @@ -0,0 +1 @@ +import{t as b}from"./zKsXIgWY.js";import{w as g}from"./CFIQ5hjj.js";function A(i,h,t,N,f,r){var o=i.__className;if(g||o!==t||o===void 0){var a=b(t,N,r);(!g||a!==i.getAttribute("class"))&&(a==null?i.removeAttribute("class"):i.className=a),i.__className=t}else if(r&&f!==r)for(var l in r){var u=!!r[l];(f==null||u!==!!f[l])&&i.classList.toggle(l,u)}return r}export{A as s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/CSXl7R3t.js b/cli/internal/dashboard/static/_app/immutable/chunks/CSXl7R3t.js new file mode 100644 index 0000000..489ccf2 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/CSXl7R3t.js @@ -0,0 +1 @@ +import{c as w,e as S,r as e,u as h,a as o,D as T,S as b}from"./CFIQ5hjj.js";function n(r,s){return r===s||r?.[b]===s}function x(r={},s,i,l){var c=w.r,d=o;return S(()=>{var f,a;return e(()=>{f=a,a=[],h(()=>{r!==i(...a)&&(s(r,...a),f&&n(i(...f),r)&&s(null,...f))})}),()=>{let t=d;for(;t!==c&&t.parent!==null&&t.parent.f&T;)t=t.parent;const p=()=>{a&&n(i(...a),r)&&s(null,...a)},u=t.teardown;t.teardown=()=>{p(),u?.()}}}),r}export{x as b}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/CaohEQ9u.js b/cli/internal/dashboard/static/_app/immutable/chunks/CaohEQ9u.js new file mode 100644 index 0000000..2a95e0f --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/CaohEQ9u.js @@ -0,0 +1 @@ +import{o as _,q as v,e as o,x as c,y as b,z as m,A as h}from"./CFIQ5hjj.js";function s(e,r,f=!1){if(e.multiple){if(r==null)return;if(!b(r))return m();for(var a of e.options)a.selected=r.includes(i(a));return}for(a of e.options){var t=i(a);if(h(t,r)){a.selected=!0;return}}(!f||r!==void 0)&&(e.selectedIndex=-1)}function y(e){var r=new MutationObserver(()=>{s(e,e.__value)});r.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),c(()=>{r.disconnect()})}function S(e,r,f=r){var a=new WeakSet,t=!0;_(e,"change",u=>{var l=u?"[selected]":":checked",n;if(e.multiple)n=[].map.call(e.querySelectorAll(l),i);else{var d=e.querySelector(l)??e.querySelector("option:not([disabled])");n=d&&i(d)}f(n),v!==null&&a.add(v)}),o(()=>{var u=r();if(e===document.activeElement){var l=v;if(a.has(l))return}if(s(e,u,t),t&&u===void 0){var n=e.querySelector(":checked");n!==null&&(u=i(n),f(u))}e.__value=u,t=!1}),y(e)}function i(e){return"__value"in e?e.__value:e.value}export{S as b,y as i,s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DIeogL5L.js b/cli/internal/dashboard/static/_app/immutable/chunks/DIeogL5L.js new file mode 100644 index 0000000..e8eaa2e --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DIeogL5L.js @@ -0,0 +1 @@ +let e=!1,a=!1;function l(){e=!0}export{l as e,e as l,a as t}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DLS4WeON.js b/cli/internal/dashboard/static/_app/immutable/chunks/DLS4WeON.js new file mode 100644 index 0000000..bf007c9 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DLS4WeON.js @@ -0,0 +1 @@ +import{s as f,g as l}from"./Dv0Hwark.js";import{x as c,X as b,Y as a,Z as _,F as p,l as d}from"./CFIQ5hjj.js";let u=!1,t=Symbol();function v(e,r,n){const s=n[r]??={store:null,source:_(void 0),unsubscribe:a};if(s.store!==e&&!(t in n))if(s.unsubscribe(),s.store=e??null,e==null)s.source.v=void 0,s.unsubscribe=a;else{var i=!0;s.unsubscribe=f(e,o=>{i?s.source.v=o:p(s.source,o)}),i=!1}return e&&t in n?l(e):d(s.source)}function y(){const e={};function r(){c(()=>{for(var n in e)e[n].unsubscribe();b(e,t,{enumerable:!1,value:!0})})}return[e,r]}function x(e){var r=u;try{return u=!1,[e(),u]}finally{u=r}}export{v as a,x as c,y as s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DdAmTr_Q.js b/cli/internal/dashboard/static/_app/immutable/chunks/DdAmTr_Q.js new file mode 100644 index 0000000..9f46bf9 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DdAmTr_Q.js @@ -0,0 +1 @@ +import{w as i,O as u,Q as v,R as f,T as h,U as g,V as A,W as S}from"./CFIQ5hjj.js";const l=Symbol("is custom element"),T=Symbol("is html"),p=f?"link":"LINK",N=f?"progress":"PROGRESS";function M(r){if(i){var s=!1,e=()=>{if(!s){if(s=!0,r.hasAttribute("value")){var o=r.value;_(r,"value",null),r.value=o}if(r.hasAttribute("checked")){var a=r.checked;_(r,"checked",null),r.checked=a}}};r.__on_r=e,g(e),A()}}function k(r,s){var e=n(r);e.value===(e.value=s??void 0)||r.value===s&&(s!==0||r.nodeName!==N)||(r.value=s??"")}function _(r,s,e,o){var a=n(r);i&&(a[s]=r.getAttribute(s),s==="src"||s==="srcset"||s==="href"&&r.nodeName===p)||a[s]!==(a[s]=e)&&(s==="loading"&&(r[u]=e),e==null?r.removeAttribute(s):typeof e!="string"&&E(r).includes(s)?r[s]=e:r.setAttribute(s,e))}function n(r){return r.__attributes??={[l]:r.nodeName.includes("-"),[T]:r.namespaceURI===v}}var c=new Map;function E(r){var s=r.getAttribute("is")||r.nodeName,e=c.get(s);if(e)return e;c.set(s,e=[]);for(var o,a=r,d=Element.prototype;d!==a;){o=S(a);for(var t in o)o[t].set&&e.push(t);a=h(a)}return e}export{_ as a,M as r,k as s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DeY8KYDG.js b/cli/internal/dashboard/static/_app/immutable/chunks/DeY8KYDG.js new file mode 100644 index 0000000..ec74926 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DeY8KYDG.js @@ -0,0 +1 @@ +import{w as M}from"./Dv0Hwark.js";import{l as N,d as P}from"./DmL0_esv.js";import"./DsnmJJEf.js";import{p as k,b as E,d as c,g as o,s as g,t as F,l as n,a0 as I}from"./CFIQ5hjj.js";import{a as h,f as q,s as m}from"./ByVGy8qs.js";import{e as z,i as A}from"./zKsXIgWY.js";import{p as B}from"./BVGfD6Eb.js";const C=M([]);async function _(){try{const t=await fetch("/api/herald");t.ok&&C.set(await t.json())}catch{}}let l=null;function V(){l||(_(),l=N.subscribe(t=>{t&&(t.type==="herald-event"||t.type==="gate-resolved"||t.type==="quest-changed")&&_()}))}function W(){l?.(),l=null}var G=q('
'),J=q('
');function X(t,d){k(d,!0);let w=B(d,"limit",3,20);const b={gate_submitted:{icon:"◆",color:"var(--accent-gold)"},gate_approved:{icon:"✓",color:"var(--accent-green-text)"},gate_rejected:{icon:"✗",color:"var(--accent-red)"},phase_transition:{icon:"→",color:"var(--accent-green-text)"},lembas_completed:{icon:"◎",color:"var(--accent-blue)"},metadata_updated:{icon:"◎",color:"var(--text-muted)"},quest_held:{icon:"⏸",color:"var(--accent-gold)"},quest_unheld:{icon:"▶",color:"var(--accent-green-text)"}};function x(e){const s=new Date(e);if(isNaN(s.getTime()))return"?";const i=Date.now()-s.getTime(),a=Math.floor(i/6e4);if(a<1)return"now";if(a<60)return`${a}m`;const r=Math.floor(a/60);return r<24?`${r}h`:`${Math.floor(r/24)}d`}function y(e){switch(e.type){case"gate_submitted":return`${e.quest} submitted ${e.phase} gate`;case"gate_approved":return`${e.quest} ${e.phase} gate approved`;case"gate_rejected":return`${e.quest} ${e.phase} gate rejected`;case"phase_transition":return`${e.quest} entered ${e.phase}`;default:return e.detail||`${e.quest} ${e.type}`}}var p=J();z(p,21,()=>d.tidings.slice(0,w()),A,(e,s)=>{const i=I(()=>b[n(s).type]??{icon:"·",color:"var(--text-muted)"});var a=G(),r=c(a);let f;var $=c(r,!0);o(r);var u=g(r,2),j=c(u,!0);o(u);var v=g(u,2),H=c(v,!0);o(v),o(a),F((T,D)=>{f=P(r,"",f,{color:n(i).color}),m($,n(i).icon),m(j,T),m(H,D)},[()=>y(n(s)),()=>x(n(s).timestamp)]),h(e,a)}),o(p),h(t,p),E()}export{X as H,W as a,V as s,C as t}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DgDK1e17.js b/cli/internal/dashboard/static/_app/immutable/chunks/DgDK1e17.js new file mode 100644 index 0000000..ce230f7 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DgDK1e17.js @@ -0,0 +1 @@ +import{s as e,p as r}from"./CJ8mMi92.js";const t={get error(){return r.error},get params(){return r.params},get status(){return r.status},get url(){return r.url}};e.updated.check;const a=t;export{a as p}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DmL0_esv.js b/cli/internal/dashboard/static/_app/immutable/chunks/DmL0_esv.js new file mode 100644 index 0000000..9871b69 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DmL0_esv.js @@ -0,0 +1 @@ +import{a as v}from"./zKsXIgWY.js";import{w}from"./CFIQ5hjj.js";import{w as r,d as p}from"./Dv0Hwark.js";function h(t,e={},s,a){for(var o in s){var c=s[o];e[o]!==c&&(s[o]==null?t.style.removeProperty(o):t.style.setProperty(o,c,a))}}function M(t,e,s,a){var o=t.__style;if(w||o!==e){var c=v(e,a);(!w||c!==t.getAttribute("style"))&&(c==null?t.removeAttribute("style"):t.style.cssText=c),t.__style=e}else a&&(Array.isArray(a)?(h(t,s?.[0],a[0]),h(t,s?.[1],a[1],"important")):h(t,s,a));return a}const b=r(!1),y=r(null);let n=null,i=1e3;const A=3e4;let u=!0;function P(){return`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/ws`}function m(){if(n?.readyState===WebSocket.OPEN)return;let t;try{t=new WebSocket(P())}catch{d();return}n=t,t.onopen=()=>{n===t&&(b.set(!0),i=1e3)},t.onclose=()=>{n===t&&(b.set(!1),n=null,u&&d())},t.onerror=()=>{t.close()},t.onmessage=e=>{try{const s=JSON.parse(e.data);y.set(s)}catch{}}}function d(){setTimeout(()=>{u&&m()},i),i=Math.min(i*2,A)}function N(){u=!0,m()}function O(){u=!1,n?.close()}const f=r(null),k=r([]),q=r([]),R=p(f,t=>t?.quests.filter(e=>e.status==="active")??[]),T=p(f,t=>t?.quests.filter(e=>e.gate_pending)??[]),$=p(f,t=>t?.scouts??[]);async function W(){try{const t=await fetch("/api/status");t.ok&&f.set(await t.json())}catch{}}async function j(){try{const t=await fetch("/api/eagles");t.ok&&k.set(await t.json())}catch{}}async function S(){try{const t=await fetch("/api/herald/problems");t.ok&&q.set(await t.json())}catch{}}async function g(){await Promise.all([W(),j(),S()])}let l=null;function G(){l||(g(),l=y.subscribe(t=>{if(t)switch(t.type){case"quest-changed":case"gate-submitted":case"gate-resolved":case"command-completed":g();break;case"alert":S();break}}))}function J(){l?.(),l=null}export{G as a,O as b,J as c,M as d,f as e,b as f,R as g,$ as h,q as i,y as l,T as p,k as q,N as s}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/DsnmJJEf.js b/cli/internal/dashboard/static/_app/immutable/chunks/DsnmJJEf.js new file mode 100644 index 0000000..ca27dc7 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/DsnmJJEf.js @@ -0,0 +1 @@ +typeof window<"u"&&((window.__svelte??={}).v??=new Set).add("5"); diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/Dv0Hwark.js b/cli/internal/dashboard/static/_app/immutable/chunks/Dv0Hwark.js new file mode 100644 index 0000000..329e36d --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/Dv0Hwark.js @@ -0,0 +1 @@ +import{Y as b,u as m,a2 as q,j as x}from"./CFIQ5hjj.js";function _(e,t,n){if(e==null)return t(void 0),n&&n(void 0),b;const r=m(()=>e.subscribe(t,n));return r.unsubscribe?()=>r.unsubscribe():r}const f=[];function z(e,t){return{subscribe:A(e,t).subscribe}}function A(e,t=b){let n=null;const r=new Set;function i(u){if(q(e,u)&&(e=u,n)){const o=!f.length;for(const s of r)s[1](),f.push(s,e);if(o){for(let s=0;s{r.delete(s),r.size===0&&n&&(n(),n=null)}}return{set:i,update:a,subscribe:l}}function k(e,t,n){const r=!Array.isArray(e),i=r?[e]:e;if(!i.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const a=t.length<2;return z(n,(l,u)=>{let o=!1;const s=[];let d=0,p=b;const y=()=>{if(d)return;p();const c=t(r?s[0]:s,l,u);a?l(c):p=typeof c=="function"?c:b},h=i.map((c,g)=>_(c,w=>{s[g]=w,d&=~(1<{d|=1<t=n)(),t}export{k as d,B as g,_ as s,A as w}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/Nm4YapQn.js b/cli/internal/dashboard/static/_app/immutable/chunks/Nm4YapQn.js new file mode 100644 index 0000000..92d8d20 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/Nm4YapQn.js @@ -0,0 +1 @@ +import{c as d,h as m,i,u as g,j as l,k as b,l as p,m as h,n as k}from"./CFIQ5hjj.js";function x(n=!1){const s=d,e=s.l.u;if(!e)return;let r=()=>h(s.s);if(n){let o=0,t={};const _=k(()=>{let c=!1;const a=s.s;for(const f in a)a[f]!==t[f]&&(t[f]=a[f],c=!0);return c&&o++,o});r=()=>p(_)}e.b.length&&m(()=>{u(s,r),l(e.b)}),i(()=>{const o=g(()=>e.m.map(b));return()=>{for(const t of o)typeof t=="function"&&t()}}),e.a.length&&i(()=>{u(s,r),l(e.a)})}function u(n,s){if(n.l.s)for(const e of n.l.s)p(e);s()}export{x as i}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/jKnW4BRh.js b/cli/internal/dashboard/static/_app/immutable/chunks/jKnW4BRh.js new file mode 100644 index 0000000..d90bf52 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/jKnW4BRh.js @@ -0,0 +1 @@ +import{o as k,q as f,v as m,u as t,r as _,w as b}from"./CFIQ5hjj.js";function i(e,a,v=a){var c=new WeakSet;k(e,"input",async r=>{var l=r?e.defaultValue:e.value;if(l=s(e)?u(l):l,v(l),f!==null&&c.add(f),await m(),l!==(l=a())){var n=e.selectionStart,d=e.selectionEnd,h=e.value.length;if(e.value=l??"",d!==null){var o=e.value.length;n===d&&d===h&&o>h?(e.selectionStart=o,e.selectionEnd=o):(e.selectionStart=n,e.selectionEnd=Math.min(d,o))}}}),(b&&e.defaultValue!==e.value||t(a)==null&&e.value)&&(v(s(e)?u(e.value):e.value),f!==null&&c.add(f)),_(()=>{var r=a();if(e===document.activeElement){var l=f;if(c.has(l))return}s(e)&&r===u(e.value)||e.type==="date"&&!r&&!e.value||r!==e.value&&(e.value=r??"")})}function E(e,a,v=a){k(e,"change",c=>{var r=c?e.defaultChecked:e.checked;v(r)}),(b&&e.defaultChecked!==e.checked||t(a)==null)&&v(e.checked),_(()=>{var c=a();e.checked=!!c})}function s(e){var a=e.type;return a==="number"||a==="range"}function u(e){return e===""?null:+e}export{E as a,i as b}; diff --git a/cli/internal/dashboard/static/_app/immutable/chunks/zKsXIgWY.js b/cli/internal/dashboard/static/_app/immutable/chunks/zKsXIgWY.js new file mode 100644 index 0000000..727c90d --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/chunks/zKsXIgWY.js @@ -0,0 +1,2 @@ +import{a3 as F,a4 as ee,a5 as Q,w as b,a6 as z,a7 as re,a8 as ne,l as V,a9 as ae,aa as fe,ab as X,ac as L,ad as k,ae as ie,af as ue,ag as Z,q as le,ah as A,ai as Y,aj as se,ak as oe,L as te,y as ve,al as U,am as de,an as ce,Z as pe,ao as G,ap as ge,H as he,aq as W,ar as $,as as q,U as _e,at as Ee,au as me,av as Te,aw as Ae,ax as Se,ay as Ce}from"./CFIQ5hjj.js";function Oe(e,a){return a}function we(e,a,f){for(var n=[],s=a.length,u,i=a.length,t=0;t{if(u){if(u.pending.delete(_),u.done.add(_),u.pending.size===0){var d=e.outrogroups;B(e,U(u.done)),d.delete(u),d.size===0&&(e.outrogroups=null)}}else i-=1},!1)}if(i===0){var o=n.length===0&&f!==null;if(o){var p=f,l=p.parentNode;Te(l),l.append(p),e.items.clear()}B(e,a,!o)}else u={pending:new Set(a),done:new Set},(e.outrogroups??=new Set).add(u)}function B(e,a,f=!0){var n;if(e.pending.size>0){n=new Set;for(const i of e.pending.values())for(const t of i)n.add(e.items.get(t).e)}for(var s=0;s{var c=f();return ve(c)?c:c==null?[]:U(c)}),d,E=new Map,m=!0;function N(c){(C.effect.f&he)===0&&(C.pending.delete(c),C.fallback=l,xe(C,d,i,a,n),l!==null&&(d.length===0?(l.f&A)===0?W(l):(l.f^=A,R(l,null,i)):$(l,()=>{l=null})))}function r(c){C.pending.delete(c)}var v=ee(()=>{d=V(_);var c=d.length;let h=!1;if(b){var H=ae(i)===fe;H!==(c===0)&&(i=X(),z(i),L(!1),h=!0)}for(var w=new Set,g=le,O=oe(),x=0;xu(i)):(l=Y(()=>u(J??=F())),l.f|=A)),c>w.size&&se(),b&&c>0&&z(X()),!m)if(E.set(g,w),O){for(const[j,y]of t)w.has(j)||g.skip_effect(y.e);g.oncommit(N),g.ondiscard(r)}else N(g);h&&L(!0),V(_)}),C={effect:v,items:t,pending:E,outrogroups:null,fallback:l};m=!1,b&&(i=k)}function D(e){for(;e!==null&&(e.f&Ee)===0;)e=e.next;return e}function xe(e,a,f,n,s){var u=(n&me)!==0,i=a.length,t=e.items,o=D(e.effect.first),p,l=null,_,d=[],E=[],m,N,r,v;if(u)for(v=0;v0){var x=(n&Q)!==0&&i===0?f:null;if(u){for(v=0;v{if(_!==void 0)for(r of _)r.nodes?.a?.apply()})}function Ie(e,a,f,n,s,u,i,t){var o=(i&de)!==0?(i&ce)===0?pe(f,!1,!1):G(f):null,p=(i&ge)!==0?G(s):null;return{v:o,i:p,e:Y(()=>(u(a,o??f,p??s,t),()=>{e.delete(n)}))}}function R(e,a,f){if(e.nodes)for(var n=e.nodes.start,s=e.nodes.end,u=a&&(a.f&A)===0?a.nodes.start:f;n!==null;){var i=Ce(n);if(u.before(n),n===s)return;n=i}}function I(e,a,f){a===null?e.effect.first=f:a.next=f,f===null?e.effect.last=a:f.prev=a}const K=[...` +\r\f \v\uFEFF`];function De(e,a,f){var n=e==null?"":""+e;if(a&&(n=n?n+" "+a:a),f){for(var s of Object.keys(f))if(f[s])n=n?n+" "+s:s;else if(n.length)for(var u=s.length,i=0;(i=n.indexOf(s,i))>=0;){var t=i+u;(i===0||K.includes(n[i-1]))&&(t===n.length||K.includes(n[t]))?n=(i===0?"":n.substring(0,i))+n.substring(t+1):i=t}}return n===""?null:n}function P(e,a=!1){var f=a?" !important;":";",n="";for(var s of Object.keys(e)){var u=e[s];u!=null&&u!==""&&(n+=" "+s+": "+u+f)}return n}function Re(e,a){if(a){var f="",n,s;return Array.isArray(a)?(n=a[0],s=a[1]):n=a,n&&(f+=P(n)),s&&(f+=P(s,!0)),f=f.trim(),f===""?null:f}return String(e)}export{Re as a,be as e,Oe as i,De as t}; diff --git a/cli/internal/dashboard/static/_app/immutable/entry/app.BdcOekXH.js b/cli/internal/dashboard/static/_app/immutable/entry/app.BdcOekXH.js new file mode 100644 index 0000000..38400ac --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/entry/app.BdcOekXH.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../nodes/0.DBOxo5Wb.js","../chunks/DsnmJJEf.js","../chunks/CFIQ5hjj.js","../chunks/DIeogL5L.js","../chunks/ByVGy8qs.js","../chunks/537vdszY.js","../chunks/zKsXIgWY.js","../chunks/DdAmTr_Q.js","../chunks/CQvy7xpd.js","../chunks/BVGfD6Eb.js","../chunks/DLS4WeON.js","../chunks/Dv0Hwark.js","../chunks/DgDK1e17.js","../chunks/CJ8mMi92.js","../chunks/BUApaBEI.js","../chunks/jKnW4BRh.js","../chunks/CSXl7R3t.js","../chunks/C67DyfnJ.js","../assets/0.B4Tu4Ui9.css","../nodes/1.ByZ8u1CK.js","../chunks/69_IOA4Y.js","../chunks/Nm4YapQn.js","../nodes/2.EjT9vOq6.js","../nodes/3.Dot0CBpK.js","../assets/3.CVgNbBqn.css","../nodes/4.4T6CzQcj.js","../chunks/DmL0_esv.js","../chunks/DeY8KYDG.js","../assets/HeraldFeed.D75iUDfw.css","../chunks/CMrUtYuQ.js","../assets/GateActions.DvbP5nIs.css","../assets/4.DUdybRxg.css","../nodes/5.VZsWOulv.js","../chunks/CaohEQ9u.js","../assets/5.BgjiOm-S.css","../nodes/6.BzB38D4G.js","../assets/6.DrszQgHF.css","../nodes/7.C5EwJyeT.js","../assets/7.Ctb9NTgd.css","../nodes/8.BFyONnpl.js","../assets/8.CA8t3wJx.css"])))=>i.map(i=>d[i]); +import{w as j,a8 as z,a4 as G,az as H,a9 as W,ab as X,a6 as Z,ac as C,aA as J,ad as K,F as T,N as Q,l as f,aB as $,X as tt,Z as et,p as rt,h as st,i as at,$ as nt,v as ot,f as A,s as it,b as ct,_ as w,d as ut,g as lt,t as mt,a0 as L}from"../chunks/CFIQ5hjj.js";import{h as dt,m as ft,u as _t,a as P,c as k,f as B,t as ht,s as vt}from"../chunks/ByVGy8qs.js";import"../chunks/DsnmJJEf.js";import{B as gt,i as x}from"../chunks/537vdszY.js";import{b as S}from"../chunks/CSXl7R3t.js";import{p as D}from"../chunks/BVGfD6Eb.js";function I(o,t,s){var u;j&&(u=K,z());var i=new gt(o);G(()=>{var e=t()??null;if(j){var r=W(u),a=r===J,b=e!==null;if(a!==b){var _=X();Z(_),i.anchor=_,C(!1),i.ensure(e,e&&(n=>s(n,e))),C(!0);return}}i.ensure(e,e&&(n=>s(n,e)))},H)}function Et(o){return class extends yt{constructor(t){super({component:o,...t})}}}class yt{#e;#t;constructor(t){var s=new Map,u=(e,r)=>{var a=et(r,!1,!1);return s.set(e,a),a};const i=new Proxy({...t.props||{},$$events:{}},{get(e,r){return f(s.get(r)??u(r,Reflect.get(e,r)))},has(e,r){return r===Q?!0:(f(s.get(r)??u(r,Reflect.get(e,r))),Reflect.has(e,r))},set(e,r,a){return T(s.get(r)??u(r,a),a),Reflect.set(e,r,a)}});this.#t=(t.hydrate?dt:ft)(t.component,{target:t.target,anchor:t.anchor,props:i,context:t.context,intro:t.intro??!1,recover:t.recover,transformError:t.transformError}),(!t?.props?.$$host||t.sync===!1)&&$(),this.#e=i.$$events;for(const e of Object.keys(this.#t))e==="$set"||e==="$destroy"||e==="$on"||tt(this,e,{get(){return this.#t[e]},set(r){this.#t[e]=r},enumerable:!0});this.#t.$set=e=>{Object.assign(i,e)},this.#t.$destroy=()=>{_t(this.#t)}}$set(t){this.#t.$set(t)}$on(t,s){this.#e[t]=this.#e[t]||[];const u=(...i)=>s.call(this,...i);return this.#e[t].push(u),()=>{this.#e[t]=this.#e[t].filter(i=>i!==u)}}$destroy(){this.#t.$destroy()}}const bt="modulepreload",pt=function(o,t){return new URL(o,t).href},N={},d=function(t,s,u){let i=Promise.resolve();if(s&&s.length>0){let _=function(n){return Promise.all(n.map(m=>Promise.resolve(m).then(h=>({status:"fulfilled",value:h}),h=>({status:"rejected",reason:h}))))};const r=document.getElementsByTagName("link"),a=document.querySelector("meta[property=csp-nonce]"),b=a?.nonce||a?.getAttribute("nonce");i=_(s.map(n=>{if(n=pt(n,u),n in N)return;N[n]=!0;const m=n.endsWith(".css"),h=m?'[rel="stylesheet"]':"";if(u)for(let v=r.length-1;v>=0;v--){const c=r[v];if(c.href===n&&(!m||c.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${n}"]${h}`))return;const l=document.createElement("link");if(l.rel=m?"stylesheet":bt,m||(l.as="script"),l.crossOrigin="",l.href=n,b&&l.setAttribute("nonce",b),document.head.appendChild(l),m)return new Promise((v,c)=>{l.addEventListener("load",v),l.addEventListener("error",()=>c(new Error(`Unable to preload CSS for ${n}`)))})}))}function e(r){const a=new Event("vite:preloadError",{cancelable:!0});if(a.payload=r,window.dispatchEvent(a),!a.defaultPrevented)throw r}return i.then(r=>{for(const a of r||[])a.status==="rejected"&&e(a.reason);return t().catch(e)})},It={};var Pt=B('
'),Rt=B(" ",1);function Ot(o,t){rt(t,!0);let s=D(t,"components",23,()=>[]),u=D(t,"data_0",3,null),i=D(t,"data_1",3,null);st(()=>t.stores.page.set(t.page)),at(()=>{t.stores,t.page,t.constructors,s(),t.form,u(),i(),t.stores.page.notify()});let e=w(!1),r=w(!1),a=w(null);nt(()=>{const c=t.stores.page.subscribe(()=>{f(e)&&(T(r,!0),ot().then(()=>{T(a,document.title||"untitled page",!0)}))});return T(e,!0),c});const b=L(()=>t.constructors[1]);var _=Rt(),n=A(_);{var m=c=>{const g=L(()=>t.constructors[0]);var E=k(),R=A(E);I(R,()=>f(g),(y,p)=>{S(p(y,{get data(){return u()},get form(){return t.form},get params(){return t.page.params},children:(O,Tt)=>{var V=k(),q=A(V);I(q,()=>f(b),(F,U)=>{S(U(F,{get data(){return i()},get form(){return t.form},get params(){return t.page.params}}),Y=>s()[1]=Y,()=>s()?.[1])}),P(O,V)},$$slots:{default:!0}}),O=>s()[0]=O,()=>s()?.[0])}),P(c,E)},h=c=>{const g=L(()=>t.constructors[0]);var E=k(),R=A(E);I(R,()=>f(g),(y,p)=>{S(p(y,{get data(){return u()},get form(){return t.form},get params(){return t.page.params}}),O=>s()[0]=O,()=>s()?.[0])}),P(c,E)};x(n,c=>{t.constructors[1]?c(m):c(h,-1)})}var l=it(n,2);{var v=c=>{var g=Pt(),E=ut(g);{var R=y=>{var p=ht();mt(()=>vt(p,f(a))),P(y,p)};x(E,y=>{f(r)&&y(R)})}lt(g),P(c,g)};x(l,c=>{f(e)&&c(v)})}P(o,_),ct()}const Vt=Et(Ot),jt=[()=>d(()=>import("../nodes/0.DBOxo5Wb.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]),import.meta.url),()=>d(()=>import("../nodes/1.ByZ8u1CK.js"),__vite__mapDeps([19,1,20,3,2,4,21,12,13,11,14]),import.meta.url),()=>d(()=>import("../nodes/2.EjT9vOq6.js"),__vite__mapDeps([22,14,1,20,3]),import.meta.url),()=>d(()=>import("../nodes/3.Dot0CBpK.js"),__vite__mapDeps([23,1,2,3,4,5,6,7,8,15,17,24]),import.meta.url),()=>d(()=>import("../nodes/4.4T6CzQcj.js"),__vite__mapDeps([25,1,20,3,2,10,11,4,5,6,21,26,27,9,28,8,13,14,7,29,17,30,31]),import.meta.url),()=>d(()=>import("../nodes/5.VZsWOulv.js"),__vite__mapDeps([32,1,2,3,4,5,6,7,8,33,17,34]),import.meta.url),()=>d(()=>import("../nodes/6.BzB38D4G.js"),__vite__mapDeps([35,1,2,3,4,10,11,5,6,7,15,33,26,27,9,28,36]),import.meta.url),()=>d(()=>import("../nodes/7.C5EwJyeT.js"),__vite__mapDeps([37,1,2,3,10,11,4,5,6,7,8,12,13,14,26,17,29,30,27,9,28,38]),import.meta.url),()=>d(()=>import("../nodes/8.BFyONnpl.js"),__vite__mapDeps([39,1,2,3,10,11,4,5,26,6,17,40]),import.meta.url)],Ct=[],Nt={"/":[2],"/autopsies":[3],"/command":[4],"/config":[5],"/herald":[6],"/quest/[id]":[7],"/timeline":[8]},M={handleError:(({error:o})=>{console.error(o)}),reroute:(()=>{}),transport:{}},At=Object.fromEntries(Object.entries(M.transport).map(([o,t])=>[o,t.decode])),Bt=Object.fromEntries(Object.entries(M.transport).map(([o,t])=>[o,t.encode])),Mt=!1,qt=(o,t)=>At[o](t);export{qt as decode,At as decoders,Nt as dictionary,Bt as encoders,Mt as hash,M as hooks,It as matchers,jt as nodes,Vt as root,Ct as server_loads}; diff --git a/cli/internal/dashboard/static/_app/immutable/entry/start.B5-0ZWIv.js b/cli/internal/dashboard/static/_app/immutable/entry/start.B5-0ZWIv.js new file mode 100644 index 0000000..3fcefc6 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/entry/start.B5-0ZWIv.js @@ -0,0 +1 @@ +import{l as o,a as r}from"../chunks/CJ8mMi92.js";export{o as load_css,r as start}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/0.DBOxo5Wb.js b/cli/internal/dashboard/static/_app/immutable/nodes/0.DBOxo5Wb.js new file mode 100644 index 0000000..c7d28c3 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/0.DBOxo5Wb.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import{a4 as ue,az as ye,a3 as we,b6 as be,aS as ke,w as B,ae as Ce,ay as ae,ac as se,a6 as le,ad as Ee,a7 as xe,p as Y,t as T,b as Z,d as p,s as b,g as u,l as e,i as oe,F as n,$ as ve,_ as D,f as O,a0 as U,a1 as Se,e as De,b7 as qe}from"../chunks/CFIQ5hjj.js";import{d as de,b as M,a as h,f as y,s as I,e as Qe,c as Pe}from"../chunks/ByVGy8qs.js";import{B as Fe,i as R}from"../chunks/537vdszY.js";import{e as V,i as W}from"../chunks/zKsXIgWY.js";import{a as J,r as ne}from"../chunks/DdAmTr_Q.js";import{s as X}from"../chunks/CQvy7xpd.js";import{p as Ne}from"../chunks/BVGfD6Eb.js";import{p as re}from"../chunks/DgDK1e17.js";import{b as ie}from"../chunks/jKnW4BRh.js";import{b as ce}from"../chunks/CSXl7R3t.js";import{g as K}from"../chunks/CJ8mMi92.js";import{e as Te,g as Ie,k as Ae,h as Ke}from"../chunks/C67DyfnJ.js";function pe(g,o,...l){var c=new Fe(g);ue(()=>{const s=o()??null;c.ensure(s,s&&(t=>s(t,...l)))},ye)}function Me(g,o){let l=null,c=B;var s;if(B){l=Ee;for(var t=xe(document.head);t!==null&&(t.nodeType!==Ce||t.data!==g);)t=ae(t);if(t===null)se(!1);else{var r=ae(t);t.remove(),le(r)}}B||(s=document.head.appendChild(we()));try{ue(()=>o(s),be|ke)}finally{c&&(se(!0),le(l))}}const Oe=!1,Re=!1,pt=Object.freeze(Object.defineProperty({__proto__:null,prerender:Oe,ssr:Re},Symbol.toStringTag,{value:"Module"}));var Ge=y('Fellowship'),Le=y(' '),He=y(' '),je=y('');function ze(g,o){Y(o,!0);let l=Ne(o,"collapsed",15,!1);const c=[{path:"/command",label:"Command",icon:"⚔"},{path:"/herald",label:"Herald",icon:"📜"},{path:"/autopsies",label:"Autopsies",icon:"◆"},{path:"/timeline",label:"Timeline",icon:"▰"},{path:"/config",label:"Config",icon:"⚙"}];function s(w){return re.url.pathname===w||re.url.pathname.startsWith(w+"/")}var t=je();let r;var _=p(t),k=b(p(_),2);{var f=w=>{var C=Ge();h(w,C)};R(k,w=>{l()||w(f)})}u(_);var q=b(_,2);V(q,21,()=>c,W,(w,C)=>{var m=He();let F;var A=p(m),L=p(A,!0);u(A);var H=b(A,2);{var a=d=>{var i=Le(),S=p(i,!0);u(i),T(()=>I(S,e(C).label)),h(d,i)};R(H,d=>{l()||d(a)})}u(m),T(d=>{J(m,"href",e(C).path),F=X(m,1,"nav-item svelte-129hoe0",null,F,d),J(m,"title",l()?e(C).label:void 0),I(L,e(C).icon)},[()=>({active:s(e(C).path)})]),h(w,m)}),u(q);var Q=b(q,2),v=p(Q,!0);u(Q),u(t),T(()=>{r=X(t,1,"sidebar svelte-129hoe0",null,r,{collapsed:l()}),I(v,l()?"›":"‹")}),M("click",Q,()=>l(!l())),h(g,t),Z()}de(["click"]);var Be=y('
',1),Ue=y(""),Ve=y('
',1),We=y('
No matching commands
'),Je=y('
',1),Xe=y('
');function Ye(g,o){Y(o,!0);const l=[{label:"Spawn Quest",category:"Quest Control",action:()=>{n(t,"spawn-quest")},inputPlaceholder:"Enter task description..."},{label:"Spawn Scout",category:"Quest Control",action:()=>{n(t,"spawn-scout")},inputPlaceholder:"Enter question..."},{label:"Kill Quest",category:"Quest Control",action:()=>{n(t,"kill-quest")},inputPlaceholder:"Enter quest ID..."},{label:"Restart Quest",category:"Quest Control",action:()=>{n(t,"restart-quest")},inputPlaceholder:"Enter quest ID..."},{label:"Go to Command",category:"Navigation",action:()=>{K("/command"),o.onClose()}},{label:"Go to Herald",category:"Navigation",action:()=>{K("/herald"),o.onClose()}},{label:"Go to Autopsies",category:"Navigation",action:()=>{K("/autopsies"),o.onClose()}},{label:"Go to Timeline",category:"Navigation",action:()=>{K("/timeline"),o.onClose()}},{label:"Go to Config",category:"Navigation",action:()=>{K("/config"),o.onClose()}}];let c=D(""),s=D(0),t=D(null),r=D(""),_=D(void 0),k=D(void 0),f=U(()=>e(c)?l.filter(a=>a.label.toLowerCase().includes(e(c).toLowerCase())):l),q=U(()=>{const a=[],d=new Set;for(const i of e(f))d.has(i.category)||(d.add(i.category),a.push({category:i.category,items:[]})),a.find(S=>S.category===i.category).items.push(i);return a});function Q(){return e(f)}function v(){const a=Q();a[e(s)]&&a[e(s)].action()}async function w(){if(e(r).trim())try{e(t)==="spawn-quest"?await Te(e(r).trim()):e(t)==="spawn-scout"?await Ie(e(r).trim()):e(t)==="kill-quest"?await Ae(e(r).trim()):e(t)==="restart-quest"&&await Ke(e(r).trim()),n(t,null),n(r,""),o.onClose()}catch{}}function C(a){if(e(t)){a.key==="Escape"?(a.preventDefault(),n(t,null),n(r,""),e(_)?.focus()):a.key==="Enter"&&(a.preventDefault(),w());return}a.key==="Escape"?(a.preventDefault(),o.onClose()):a.key==="ArrowDown"?(a.preventDefault(),e(f).length>0&&n(s,(e(s)+1)%e(f).length)):a.key==="ArrowUp"?(a.preventDefault(),e(f).length>0&&n(s,(e(s)-1+e(f).length)%e(f).length)):a.key==="Enter"&&(a.preventDefault(),v())}oe(()=>{e(c),n(s,0)}),oe(()=>{e(t)&&e(k)&&e(k).focus()}),ve(()=>{e(_)?.focus()});var m=Xe(),F=p(m),A=p(F);{var L=a=>{var d=Be(),i=O(d),S=p(i,!0);u(i);var P=b(i,2);ne(P),ce(P,E=>n(k,E),()=>e(k)),T(E=>{I(S,e(t)==="spawn-quest"?"Spawn Quest":e(t)==="spawn-scout"?"Spawn Scout":e(t)==="kill-quest"?"Kill Quest":"Restart Quest"),J(P,"placeholder",E)},[()=>l.find(E=>E.label.toLowerCase().replace(/\s+/g,"-")===e(t)?.replace("spawn-","spawn-").replace("kill-","kill-").replace("restart-","restart-"))?.inputPlaceholder??"Enter value..."]),ie(P,()=>e(r),E=>n(r,E)),h(a,d)},H=a=>{var d=Je(),i=O(d);ne(i),ce(i,x=>n(_,x),()=>e(_));var S=b(i,2),P=p(S);V(P,17,()=>e(q),W,(x,G)=>{var $=Ve(),j=O($),me=p(j,!0);u(j);var he=b(j,2);V(he,17,()=>e(G).items,W,(ge,z)=>{const ee=U(()=>e(f).indexOf(e(z)));var N=Ue();let te;var _e=p(N,!0);u(N),T(()=>{te=X(N,1,"action-item svelte-wh9uu8",null,te,{selected:e(ee)===e(s)}),I(_e,e(z).label)}),Qe("mouseenter",N,()=>n(s,e(ee),!0)),M("click",N,()=>e(z).action()),h(ge,N)}),T(()=>I(me,e(G).category)),h(x,$)});var E=b(P,2);{var fe=x=>{var G=We();h(x,G)};R(E,x=>{e(f).length===0&&x(fe)})}u(S),ie(i,()=>e(c),x=>n(c,x)),h(a,d)};R(A,a=>{e(t)?a(L):a(H,-1)})}u(F),u(m),M("keydown",m,C),M("click",m,function(...a){o.onClose?.apply(this,a)}),M("click",F,a=>a.stopPropagation()),h(g,m),Z()}de(["keydown","click"]);var Ze=y('
',1);function $e(g,o){Y(o,!0);let l=D(!1),c=D(!1);function s(v){v.key==="k"&&(v.metaKey||v.ctrlKey)&&(v.preventDefault(),n(c,!e(c)))}ve(()=>{window.addEventListener("keydown",s)}),Se(()=>{window.removeEventListener("keydown",s)});var t=Ze(),r=O(t),_=p(r);ze(_,{get collapsed(){return e(l)},set collapsed(v){n(l,v,!0)}});var k=b(_,2),f=p(k);pe(f,()=>o.children),u(k),u(r);var q=b(r,2);{var Q=v=>{Ye(v,{onClose:()=>n(c,!1)})};R(q,v=>{e(c)&&v(Q)})}h(g,t),Z()}function ft(g,o){Me("12qhfyh",l=>{De(()=>{qe.title="Fellowship Dashboard"})}),$e(g,{children:(l,c)=>{var s=Pe(),t=O(s);pe(t,()=>o.children),h(l,s)},$$slots:{default:!0}})}export{ft as component,pt as universal}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/1.ByZ8u1CK.js b/cli/internal/dashboard/static/_app/immutable/nodes/1.ByZ8u1CK.js new file mode 100644 index 0000000..4d37376 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/1.ByZ8u1CK.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import"../chunks/69_IOA4Y.js";import{p as h,f as l,t as v,b as c,d as s,g as e,s as g}from"../chunks/CFIQ5hjj.js";import{a as u,f as _,s as o}from"../chunks/ByVGy8qs.js";import{i as d}from"../chunks/Nm4YapQn.js";import{p}from"../chunks/DgDK1e17.js";var x=_("

",1);function y(m,i){h(i,!1),d();var t=x(),r=l(t),f=s(r,!0);e(r);var a=g(r,2),n=s(a,!0);e(a),v(()=>{o(f,p.status),o(n,p.error?.message)}),u(m,t),c()}export{y as component}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/2.EjT9vOq6.js b/cli/internal/dashboard/static/_app/immutable/nodes/2.EjT9vOq6.js new file mode 100644 index 0000000..f2c38ef --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/2.EjT9vOq6.js @@ -0,0 +1 @@ +import{R as t}from"../chunks/BUApaBEI.js";import"../chunks/DsnmJJEf.js";import"../chunks/69_IOA4Y.js";function n(o,e){throw new t(o,e.toString())}function r(){n(302,"/command")}const p=Object.freeze(Object.defineProperty({__proto__:null,load:r},Symbol.toStringTag,{value:"Module"}));function m(o){}export{m as component,p as universal}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/3.Dot0CBpK.js b/cli/internal/dashboard/static/_app/immutable/nodes/3.Dot0CBpK.js new file mode 100644 index 0000000..bd96b7c --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/3.Dot0CBpK.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import{p as De,_ as b,E as Fe,$ as Se,t as p,l as e,b as Te,d as s,F as y,s as l,g as a,a0 as je,f as Ae}from"../chunks/CFIQ5hjj.js";import{d as Ce,a as i,f as o,s as d,c as Ee,b as Ie}from"../chunks/ByVGy8qs.js";import{i as k}from"../chunks/537vdszY.js";import{e as U,i as $}from"../chunks/zKsXIgWY.js";import{r as Me}from"../chunks/DdAmTr_Q.js";import{s as Ne}from"../chunks/CQvy7xpd.js";import{b as Pe}from"../chunks/jKnW4BRh.js";import{f as Re}from"../chunks/C67DyfnJ.js";var Ue=o('
Loading autopsies...
'),$e=o('
Failed to load autopsies. Is the server running?
'),ze=o('
No autopsies found.
'),Be=o(' '),Ge=o('
Files
'),He=o('
Modules
'),Je=o(' '),Ke=o('
Tags
'),Oe=o('
Task
Phase
Resolution
'),Qe=o(''),Ve=o('

Autopsies

');function va(ae,te){De(te,!0);let z=b(Fe([])),w=b(""),f=b(null),B=b(!0),G=b(!1),L=je(()=>e(z).filter(t=>{if(!e(w))return!0;const n=e(w).toLowerCase();return`${t.quest} ${t.task} ${t.what_failed} ${t.trigger} ${(t.tags??[]).join(" ")}`.toLowerCase().includes(n)}));function se(t){try{return new Date(t).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return t}}function le(t){y(f,e(f)===t?null:t,!0)}Se(async()=>{try{y(z,await Re(),!0)}catch{y(G,!0)}finally{y(B,!1)}});var D=Ve(),F=s(D),H=l(s(F),2),ve=s(H);a(H),a(F);var S=l(F,2),J=s(S);Me(J),a(S);var K=l(S,2),ie=s(K);{var de=t=>{var n=Ue();i(t,n)},re=t=>{var n=$e();i(t,n)},ce=t=>{var n=ze();i(t,n)},oe=t=>{var n=Ee(),O=Ae(n);U(O,17,()=>e(L),$,(ne,v,q)=>{var m=Qe();let Q;var T=s(m),j=s(T),ue=s(j,!0);a(j);var A=l(j,2),_e=s(A,!0);a(A);var C=l(A,2),pe=s(C,!0);a(C);var E=l(C,2),fe=s(E,!0);a(E);var V=l(E,2),me=s(V,!0);a(V),a(T);var ge=l(T,2);{var he=g=>{var I=Oe(),M=s(I),W=l(s(M),2),xe=s(W,!0);a(W),a(M);var N=l(M,2),X=l(s(N),2),be=s(X,!0);a(X),a(N);var P=l(N,2),Y=l(s(P),2),ye=s(Y,!0);a(Y),a(P);var Z=l(P,2);{var ke=r=>{var c=Ge(),u=l(s(c),2);U(u,21,()=>e(v).files,$,(h,x)=>{var _=Be(),R=s(_,!0);a(_),p(()=>d(R,e(x))),i(h,_)}),a(u),a(c),i(r,c)};k(Z,r=>{e(v).files.length>0&&r(ke)})}var ee=l(Z,2);{var we=r=>{var c=He(),u=l(s(c),2),h=s(u,!0);a(u),a(c),p(x=>d(h,x),[()=>e(v).modules.join(", ")]),i(r,c)};k(ee,r=>{e(v).modules.length>0&&r(we)})}var qe=l(ee,2);{var Le=r=>{var c=Ke(),u=l(s(c),2);U(u,21,()=>e(v).tags,$,(h,x)=>{var _=Je(),R=s(_,!0);a(_),p(()=>d(R,e(x))),i(h,_)}),a(u),a(c),i(r,c)};k(qe,r=>{e(v).tags.length>0&&r(Le)})}a(I),p(()=>{d(xe,e(v).task),d(be,e(v).phase),d(ye,e(v).resolution)}),i(g,I)};k(ge,g=>{e(f)===q&&g(he)})}a(m),p(g=>{Q=Ne(m,1,"autopsy-row svelte-1c2edl6",null,Q,{expanded:e(f)===q}),d(ue,e(v).quest),d(_e,g),d(pe,e(v).what_failed),d(fe,e(v).trigger),d(me,e(f)===q?"−":"+")},[()=>se(e(v).ts)]),Ie("click",m,()=>le(q)),i(ne,m)}),i(t,n)};k(ie,t=>{e(B)?t(de):e(G)?t(re,1):e(L).length===0?t(ce,2):t(oe,-1)})}a(K),a(D),p(()=>d(ve,`${e(L).length??""} records`)),Pe(J,()=>e(w),t=>y(w,t)),i(ae,D),Te()}Ce(["click"]);export{va as component}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/4.4T6CzQcj.js b/cli/internal/dashboard/static/_app/immutable/nodes/4.4T6CzQcj.js new file mode 100644 index 0000000..a8f340c --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/4.4T6CzQcj.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import"../chunks/69_IOA4Y.js";import{f as F,t as y,d as a,g as t,s as r,l as h,a0 as ne,p as K,b as N,$ as oe,a1 as ve,L as J}from"../chunks/CFIQ5hjj.js";import{s as V,a as q}from"../chunks/DLS4WeON.js";import{c as ie,a as p,f as m,s as k,d as le,b as E}from"../chunks/ByVGy8qs.js";import{i as A}from"../chunks/537vdszY.js";import{e as L,i as de}from"../chunks/zKsXIgWY.js";import{i as ce}from"../chunks/Nm4YapQn.js";import{f as ue,d as pe,s as me,a as _e,c as ge,g as fe,p as he,h as xe,i as be,e as qe,b as ke,q as we}from"../chunks/DmL0_esv.js";import{H as ye,s as Se,a as He,t as Pe}from"../chunks/DeY8KYDG.js";import{p as X}from"../chunks/BVGfD6Eb.js";import{s as T}from"../chunks/CQvy7xpd.js";import{g as Ce}from"../chunks/CJ8mMi92.js";import{a as Ge}from"../chunks/DdAmTr_Q.js";import{G as Qe}from"../chunks/CMrUtYuQ.js";var $e=m('');function Ae(f){const e=()=>q(ue,"$connected",_),[_,s]=V();var l=ie(),v=F(l);{var c=n=>{var u=$e();p(n,u)};A(v,n=>{e()||n(c)})}p(f,l),s()}var Ie=m('
');function D(f,e){let _=X(e,"color",3,"var(--text-primary)");var s=Ie(),l=a(s);let v;var c=a(l,!0);t(l);var n=r(l,2),u=a(n,!0);t(n),t(s),y(()=>{v=pe(l,"",v,{color:_()}),k(c,e.value),k(u,e.label)}),p(f,s)}var Oe=m("
"),Re=m("
");function We(f,e){let _=X(e,"compact",3,!1);const s=["Onboard","Research","Plan","Implement","Review","Complete"];function l(n){const u=s.indexOf(e.phase),d=s.indexOf(n);return ds,de,(n,u)=>{const d=ne(()=>l(h(u)));var x=Oe();y(()=>{T(x,1,`phase-bar ${h(d)??""}`,"svelte-16oavfg"),Ge(x,"title",h(u))}),p(n,x)}),t(v),y(()=>c=T(v,1,"timeline svelte-16oavfg",null,c,{compact:_()})),p(f,v)}var De=m(" "),Te=m(' '),Be=m('
'),Ee=m('
');function Fe(f,e){K(e,!0);function _(){Ce(`/quest/${encodeURIComponent(e.quest.name)}`)}var s=Ee();let l;var v=a(s),c=a(v),n=a(c,!0);t(c);var u=r(c,2);{var d=o=>{var i=De(),b=a(i,!0);t(i),y(()=>{T(i,1,`health-badge ${e.health.health??""}`,"svelte-1cd3txo"),k(b,e.health.health)}),p(o,i)};A(u,o=>{e.health&&o(d)})}t(v);var x=r(v,2);We(x,{get phase(){return e.quest.phase},compact:!0});var P=r(x,2),S=a(P),I=a(S,!0);t(S);var O=r(S,2);{var C=o=>{var i=Te(),b=a(i);t(i),y(()=>k(b,`${e.quest.errands_done??""}/${e.quest.errands_total??""} errands`)),p(o,i)};A(O,o=>{e.quest.errands_total>0&&o(C)})}t(P);var R=r(P,2);{var W=o=>{var i=Be(),b=a(i);Qe(b,{get worktree(){return e.quest.worktree}}),t(i),E("click",i,G=>G.stopPropagation()),p(o,i)};A(R,o=>{e.quest.gate_pending&&o(W)})}t(s),y(()=>{l=T(s,1,"quest-card svelte-1cd3txo",null,l,{"gate-pending":e.quest.gate_pending}),k(n,e.quest.name),k(I,e.quest.phase)}),E("click",s,_),E("keydown",s,o=>o.key==="Enter"&&_()),p(f,s),N()}le(["click","keydown"]);var Le=m('
📡

'),Me=m(" ",1),Ue=m('

Waiting for fellowship data...

'),je=m('

Command

Herald
',1);function vt(f,e){K(e,!1);const _=()=>q(we,"$questHealths",d),s=()=>q(fe,"$activeQuests",d),l=()=>q(he,"$pendingGates",d),v=()=>q(xe,"$activeScouts",d),c=()=>q(be,"$problems",d),n=()=>q(qe,"$dashboardStatus",d),u=()=>q(Pe,"$tidings",d),[d,x]=V();oe(()=>{me(),_e(),Se()}),ve(()=>{ke(),ge(),He()});function P(g){return _().find(H=>H.name===g)}ce();var S=je(),I=F(S);Ae(I);var O=r(I,2),C=r(a(O),2),R=a(C);D(R,{get value(){return s().length},label:"Active Quests",color:"var(--accent-green-text)"});var W=r(R,2);D(W,{get value(){return l().length},label:"Gates Pending",color:"var(--accent-gold)"});var o=r(W,2);D(o,{get value(){return v().length},label:"Scouts Active",color:"var(--accent-blue)"});var i=r(o,2);{let g=J(()=>c().length>0?"var(--accent-red)":"var(--accent-purple)");D(i,{get value(){return c().length},label:"Alerts",get color(){return h(g)}})}t(C);var b=r(C,2),G=a(b),Y=a(G);{var Z=g=>{var H=Me(),U=F(H);L(U,1,()=>n().quests,w=>w.name,(w,Q)=>{{let $=J(()=>P(h(Q).name));Fe(w,{get quest(){return h(Q)},get health(){return h($)}})}});var ae=r(U,2);L(ae,1,()=>n().scouts,w=>w.name,(w,Q)=>{var $=Le(),B=a($),j=r(a(B),2),se=a(j,!0);t(j),t(B);var z=r(B,2),re=a(z,!0);t(z),t($),y(()=>{k(se,h(Q).name),k(re,h(Q).question)}),p(w,$)}),p(g,H)},ee=g=>{var H=Ue();p(g,H)};A(Y,g=>{n()?g(Z):g(ee,-1)})}t(G);var M=r(G,2),te=r(a(M),2);ye(te,{get tidings(){return u()}}),t(M),t(b),t(O),p(f,S),N(),x()}export{vt as component}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/5.VZsWOulv.js b/cli/internal/dashboard/static/_app/immutable/nodes/5.VZsWOulv.js new file mode 100644 index 0000000..2ebfd58 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/5.VZsWOulv.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import{p as ye,_ as C,E as H,$ as me,b as he,F as _,s as g,d as r,l as e,g as o,t as b,a0 as F}from"../chunks/CFIQ5hjj.js";import{d as we,a as p,f as d,s as w,b as I,e as ke}from"../chunks/ByVGy8qs.js";import{i as E}from"../chunks/537vdszY.js";import{e as Q,i as U}from"../chunks/zKsXIgWY.js";import{r as xe,s as je}from"../chunks/DdAmTr_Q.js";import{s as X}from"../chunks/CQvy7xpd.js";import{i as Se,s as Oe}from"../chunks/CaohEQ9u.js";import{a as Ce,s as Ee}from"../chunks/C67DyfnJ.js";var Pe=d('
Loading configuration...
'),Fe=d(""),Ge=d(''),Ke=d(''),Ne=d(''),Te=d(" "),Ae=d('
'),Je=d('
Global Config (raw)
 
'),Me=d('
Project Config (raw)
 
'),Be=d('
Settings
'),De=d('

Config

');function Ue(Y,Z){ye(Z,!0);let k=C(H({})),y=C(H({})),M=C(!0),j=C(null),m=C(null);const G=[{key:"gate_auto_approve",label:"Gate Auto-Approve",type:"boolean"},{key:"branch_prefix",label:"Branch Prefix",type:"text"},{key:"pr_draft",label:"PR Draft Mode",type:"boolean"},{key:"palantir_enabled",label:"Palantir Enabled",type:"boolean"},{key:"worktree_strategy",label:"Worktree Strategy",type:"select",options:["auto","manual"]}];function B(t){if(t in e(y))return e(y)[t];if(t in e(k))return e(k)[t]}function P(t){return t in e(y)?"project":"global"}function D(){const t=new Set(G.map(n=>n.key));return Object.keys(e(k)).filter(n=>!t.has(n))}function L(){const t=new Set(G.map(n=>n.key));return Object.keys(e(y)).filter(n=>!t.has(n))}async function K(t,n,v){_(j,t,!0);try{await Ee(t,n,v),v==="project"?e(y)[t]=n:e(k)[t]=n,_(m,{key:t,ok:!0},!0)}catch{_(m,{key:t,ok:!1},!0)}_(j,null),setTimeout(()=>{e(m)?.key===t&&_(m,null)},2e3)}async function $(t){const n=B(t),v=P(t);await K(t,!n,v)}async function ee(t,n){const v=n.target,x=P(t);await K(t,v.value,x)}async function te(t,n){const v=n.target,x=P(t);await K(t,v.value,x)}me(async()=>{try{const t=await Ce();_(k,t.global??{},!0),_(y,t.project??{},!0)}catch{}finally{_(M,!1)}});var N=De(),ae=g(r(N),2);{var se=t=>{var n=Pe();p(t,n)},ne=t=>{var n=Be(),v=r(n),x=g(r(v),2);Q(x,21,()=>G,U,(f,s)=>{const c=F(()=>B(e(s).key)),S=F(()=>P(e(s).key));var l=Ae(),T=r(l),A=r(T),ce=r(A,!0);o(A);var V=g(A,2),pe=r(V,!0);o(V),o(T);var W=g(T,2),q=r(W);{var de=i=>{var a=Fe();let u;var h=r(a,!0);o(a),b(()=>{u=X(a,1,"toggle-btn svelte-1gp6n77",null,u,{active:!!e(c)}),a.disabled=e(j)===e(s).key,w(h,e(c)?"ON":"OFF")}),I("click",a,()=>$(e(s).key)),p(i,a)},ue=i=>{var a=Ge();xe(a),b(()=>{je(a,e(c)??""),a.disabled=e(j)===e(s).key}),ke("blur",a,u=>ee(e(s).key,u)),p(i,a)},fe=i=>{var a=Ne();Q(a,21,()=>e(s).options??[],U,(h,J)=>{var O=Ke(),be=r(O,!0);o(O);var z={};b(()=>{w(be,e(J)),z!==(z=e(J))&&(O.value=(O.__value=e(J))??"")}),p(h,O)}),o(a);var u;Se(a),b(()=>{a.disabled=e(j)===e(s).key,u!==(u=e(c)??e(s).options?.[0])&&(a.value=(a.__value=e(c)??e(s).options?.[0])??"",Oe(a,e(c)??e(s).options?.[0]))}),I("change",a,h=>te(e(s).key,h)),p(i,a)};E(q,i=>{e(s).type==="boolean"?i(de):e(s).type==="text"?i(ue,1):e(s).type==="select"&&i(fe,2)})}var ge=g(q,2);{var _e=i=>{var a=Te();let u;var h=r(a,!0);o(a),b(()=>{u=X(a,1,"save-indicator svelte-1gp6n77",null,u,{error:!e(m).ok}),w(h,e(m).ok?"Saved":"Error")}),p(i,a)};E(ge,i=>{e(m)?.key===e(s).key&&i(_e)})}o(W),o(l),b(()=>{w(ce,e(s).label),w(pe,e(S))}),p(f,l)}),o(x),o(v);var R=g(v,2);{var oe=f=>{var s=Je(),c=g(r(s),2),S=r(c,!0);o(c),o(s),b(l=>w(S,l),[()=>JSON.stringify(Object.fromEntries(D().map(l=>[l,e(k)[l]])),null,2)]),p(f,s)},re=F(()=>D().length>0);E(R,f=>{e(re)&&f(oe)})}var le=g(R,2);{var ie=f=>{var s=Me(),c=g(r(s),2),S=r(c,!0);o(c),o(s),b(l=>w(S,l),[()=>JSON.stringify(Object.fromEntries(L().map(l=>[l,e(y)[l]])),null,2)]),p(f,s)},ve=F(()=>L().length>0);E(le,f=>{e(ve)&&f(ie)})}o(n),p(t,n)};E(ae,t=>{e(M)?t(se):t(ne,-1)})}o(N),p(Y,N),he()}we(["click","change"]);export{Ue as component}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/6.BzB38D4G.js b/cli/internal/dashboard/static/_app/immutable/nodes/6.BzB38D4G.js new file mode 100644 index 0000000..e67c940 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/6.BzB38D4G.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import{p as K,E as V,$ as X,a1 as Y,t as q,l as t,b as Z,d as r,s as i,F as P,_ as S,g as a,a0 as $}from"../chunks/CFIQ5hjj.js";import{a as u,f as _,s as k}from"../chunks/ByVGy8qs.js";import{s as ee,a as te}from"../chunks/DLS4WeON.js";import{i as se}from"../chunks/537vdszY.js";import{e as L,i as Q}from"../chunks/zKsXIgWY.js";import{r as C}from"../chunks/DdAmTr_Q.js";import{b as ae,a as le}from"../chunks/jKnW4BRh.js";import{b as re}from"../chunks/CaohEQ9u.js";import{s as ie,a as oe,b as pe,c as de}from"../chunks/DmL0_esv.js";import{s as ne,a as ve,t as ce,H as ue}from"../chunks/DeY8KYDG.js";var _e=_(''),me=_(''),fe=_('

No tidings match the current filters.

'),ge=_('

Herald

');function Pe(E,G){K(G,!0);const A=()=>te(ce,"$tidings",B),[B,F]=ee();let d=S(""),n=S(""),v=V({gate_submitted:!0,gate_approved:!0,gate_rejected:!0,phase_transition:!0});const M=["gate_submitted","gate_approved","gate_rejected","phase_transition","lembas_completed","metadata_updated","quest_held","quest_unheld"],N={gate_submitted:"Gate Submitted",gate_approved:"Gate Approved",gate_rejected:"Gate Rejected",phase_transition:"Phase Transition",lembas_completed:"Lembas Completed",metadata_updated:"Metadata Updated",quest_held:"Quest Held",quest_unheld:"Quest Unheld"};let T=$(A),U=$(()=>[...new Set(t(T).map(e=>e.quest))].filter(Boolean).sort()),c=$(()=>t(T).filter(e=>{if(t(n)&&e.quest!==t(n)||Object.values(v).some(Boolean)&&!v[e.type])return!1;if(t(d)){const s=t(d).toLowerCase();if(!`${e.quest} ${e.type} ${e.phase} ${e.detail}`.toLowerCase().includes(s))return!1}return!0}));X(()=>{ie(),oe(),ne()}),Y(()=>{pe(),de(),ve()});var m=ge(),f=r(m),w=i(r(f),2),W=r(w);a(w),a(f);var g=i(f,2),h=r(g),b=r(h);C(b);var x=i(b,2),y=r(x);y.value=y.__value="";var D=i(y);L(D,17,()=>t(U),Q,(e,l)=>{var s=_e(),o=r(s,!0);a(s);var p={};q(()=>{k(o,t(l)),p!==(p=t(l))&&(s.value=(s.__value=t(l))??"")}),u(e,s)}),a(x),a(h);var H=i(h,2);L(H,21,()=>M,Q,(e,l)=>{var s=me(),o=r(s);C(o);var p=i(o,2),I=r(p,!0);a(p),a(s),q(()=>k(I,N[t(l)])),le(o,()=>v[t(l)],J=>v[t(l)]=J),u(e,s)}),a(H),a(g);var j=i(g,2),O=r(j);{var R=e=>{ue(e,{get tidings(){return t(c)},get limit(){return t(c).length}})},z=e=>{var l=fe();u(e,l)};se(O,e=>{t(c).length>0?e(R):e(z,-1)})}a(j),a(m),q(()=>k(W,`${t(c).length??""} tidings`)),ae(b,()=>t(d),e=>P(d,e)),re(x,()=>t(n),e=>P(n,e)),u(E,m),Z(),F()}export{Pe as component}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/7.C5EwJyeT.js b/cli/internal/dashboard/static/_app/immutable/nodes/7.C5EwJyeT.js new file mode 100644 index 0000000..08a1348 --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/7.C5EwJyeT.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import{d as a,l as e,g as t,s as r,t as x,p as Ce,i as Ge,F as y,b as Oe,a0 as M,_ as N,f as fe}from"../chunks/CFIQ5hjj.js";import{s as Ie,a as le}from"../chunks/DLS4WeON.js";import{s as p,a as o,t as he,f as c,d as Ne,b as D}from"../chunks/ByVGy8qs.js";import{i as H}from"../chunks/537vdszY.js";import{e as Q,i as re}from"../chunks/zKsXIgWY.js";import{a as Pe}from"../chunks/DdAmTr_Q.js";import{s as b}from"../chunks/CQvy7xpd.js";import{p as We}from"../chunks/DgDK1e17.js";import{e as Ae,q as Be}from"../chunks/DmL0_esv.js";import{c as De,d as Me}from"../chunks/C67DyfnJ.js";import{G as Qe}from"../chunks/CMrUtYuQ.js";import{H as Ue,t as je}from"../chunks/DeY8KYDG.js";var ze=c('
'),Je=c('
');function Ke(U,j){var P=Je();Q(P,21,()=>j.errands,W=>W.id,(W,S)=>{var E=ze(),O=a(E),F=a(O);{var v=m=>{var i=he("✓");o(m,i)},k=m=>{var i=he("●");o(m,i)};H(F,m=>{e(S).status==="done"?m(v):e(S).status==="active"&&m(k,1)})}t(O);var A=r(O,2),q=a(A,!0);t(A),t(E),x(()=>{b(O,1,`errand-check ${e(S).status??""}`,"svelte-6y5tqw"),b(A,1,`errand-text ${e(S).status??""}`,"svelte-6y5tqw"),p(q,e(S).description)}),o(W,E)}),t(P),o(U,P)}var Ve=c(' ',1),Xe=c('
'),Ye=c('

',1),Ze=c(' '),es=c('
'),ss=c('
'),ts=c('
'),as=c('

Gate History

'),ls=c('

Quest logs not yet available. Raw output logging is a future enhancement.

'),rs=c('

No data available

'),is=c('
Eagles
'),vs=c('
Metadata
Branch
Worktree
Status
'),ns=c('
');function ws(U,j){Ce(j,!0);const P=()=>le(Ae,"$dashboardStatus",E),W=()=>le(Be,"$questHealths",E),S=()=>le(je,"$tidings",E),[E,O]=Ie();let F=M(()=>decodeURIComponent(We.params.id)),v=M(()=>P()?.quests.find(s=>s.name===e(F))),k=M(()=>W().find(s=>s.name===e(F))),A=M(()=>S().filter(s=>s.quest===e(F))),q=N(null),m=N(null),i=N("errands");const z=["Onboard","Research","Plan","Implement","Review","Complete"];let ie=N(!1),ve=N(!1),J=N(!1);Ge(()=>{if(e(v)&&!e(ie)&&!e(ve)&&!e(J)){y(J,!0);const s=e(v).worktree;Promise.all([De(s),Me(e(F))]).then(([l,n])=>{y(q,l,!0),y(m,n,!0),y(ie,!0)}).catch(()=>{y(ve,!0)}).finally(()=>{y(J,!1)})}});function ye(s){if(!e(v))return"pending";const l=z.indexOf(e(v).phase);if(l===-1)return"pending";const n=z.indexOf(s);return n{var l=Ye(),n=fe(l),d=a(n),_=a(d,!0);t(d);var f=r(d,2),g=a(f,!0);t(f);var $=r(f,2);{var L=h=>{Qe(h,{get worktree(){return e(v).worktree}})};H($,h=>{e(v).gate_pending&&h(L)})}var R=r($,2);{var T=h=>{var C=Ve(),u=fe(C),w=r(u,2),G=a(w,!0);t(w),x(()=>{b(u,1,`health-dot ${e(k).health??""}`,"svelte-1ysin3l"),p(G,e(k).health)}),o(h,C)};H(R,h=>{e(k)&&h(T)})}t(n);var I=r(n,2);Q(I,21,()=>z,re,(h,C)=>{var u=Xe(),w=a(u),G=a(w,!0);t(w),t(u),x(ae=>{b(u,1,`phase-step ${ae??""}`,"svelte-1ysin3l"),p(G,e(C))},[()=>ye(e(C))]),o(h,u)}),t(I),x(()=>{p(_,e(v).name),p(g,e(v).phase)}),o(s,l)};H(ge,s=>{e(v)&&s(xe)})}t(V);var Y=r(V,2),B=a(Y);let oe;var we=r(a(B));{var ke=s=>{var l=Ze(),n=a(l);t(l),x(d=>p(n,`${d??""}/${e(q).items.length??""}`),[()=>e(q).items.filter(d=>d.status==="done").length]),o(s,l)};H(we,s=>{e(q)&&s(ke)})}t(B);var Z=r(B,2);let de;var ee=r(Z,2);let pe;var se=r(ee,2);let ce;var _e=r(se,2);let ue;t(Y);var me=r(Y,2),te=a(me),qe=a(te);{var $e=s=>{Ke(s,{get errands(){return e(q).items}})},He=s=>{var l=ss();Q(l,21,()=>e(m).files_touched,re,(n,d)=>{var _=es(),f=a(_,!0);t(_),x(()=>p(f,e(d))),o(n,_)}),t(l),o(s,l)},Se=s=>{var l=as(),n=r(a(l),2);Q(n,17,()=>e(m).gate_history,re,(d,_)=>{var f=ts(),g=a(f),$=a(g,!0);t(g);var L=r(g,2),R=a(L,!0);t(L);var T=r(L,2),I=a(T,!0);t(T),t(f),x(()=>{b(g,1,`tome-action ${e(_).action??""}`,"svelte-1ysin3l"),p($,e(_).action),p(R,e(_).phase),p(I,e(_).timestamp)}),o(d,f)}),t(l),o(s,l)},Ee=s=>{Ue(s,{get tidings(){return e(A)},limit:50})},Fe=s=>{var l=ls();o(s,l)},Le=s=>{var l=rs();o(s,l)};H(qe,s=>{e(i)==="errands"&&e(q)?s($e):e(i)==="files"&&e(m)?s(He,1):e(i)==="tome"&&e(m)?s(Se,2):e(i)==="herald"?s(Ee,3):e(i)==="logs"?s(Fe,4):s(Le,-1)})}t(te);var Re=r(te,2);{var Te=s=>{var l=vs(),n=a(l),d=r(a(n),2),_=r(a(d),2),f=a(_,!0);t(_),t(d);var g=r(d,2),$=r(a(g),2),L=a($,!0);t($),t(g);var R=r(g,2),T=r(a(R),2),I=a(T,!0);t(T),t(R);var h=r(R,2);{var C=u=>{var w=is(),G=r(a(w),2),ae=a(G,!0);t(G),t(w),x(()=>{b(G,1,`meta-value ${e(k).health??""}`,"svelte-1ysin3l"),p(ae,e(k).health)}),o(u,w)};H(h,u=>{e(k)&&u(C)})}t(n),t(l),x(u=>{p(f,u),Pe($,"title",e(v).worktree),p(L,e(v).worktree),p(I,e(v).status)},[()=>e(v).worktree.replace(/\\/g,"/").split("/").pop()||e(v).worktree]),o(s,l)};H(Re,s=>{e(v)&&s(Te)})}t(me),t(K),x(()=>{p(be,e(F)),oe=b(B,1,"tab svelte-1ysin3l",null,oe,{active:e(i)==="errands"}),de=b(Z,1,"tab svelte-1ysin3l",null,de,{active:e(i)==="files"}),pe=b(ee,1,"tab svelte-1ysin3l",null,pe,{active:e(i)==="tome"}),ce=b(se,1,"tab svelte-1ysin3l",null,ce,{active:e(i)==="herald"}),ue=b(_e,1,"tab svelte-1ysin3l",null,ue,{active:e(i)==="logs"})}),D("click",B,()=>y(i,"errands")),D("click",Z,()=>y(i,"files")),D("click",ee,()=>y(i,"tome")),D("click",se,()=>y(i,"herald")),D("click",_e,()=>y(i,"logs")),o(U,K),Oe(),O()}Ne(["click"]);export{ws as component}; diff --git a/cli/internal/dashboard/static/_app/immutable/nodes/8.BFyONnpl.js b/cli/internal/dashboard/static/_app/immutable/nodes/8.BFyONnpl.js new file mode 100644 index 0000000..b71380d --- /dev/null +++ b/cli/internal/dashboard/static/_app/immutable/nodes/8.BFyONnpl.js @@ -0,0 +1 @@ +import"../chunks/DsnmJJEf.js";import{p as F,f as Y,d as p,g as d,s as q,l as n,t as k,b as G,a0 as z,_ as y,F as x,E as A,$ as B,a1 as H}from"../chunks/CFIQ5hjj.js";import{s as J,a as K}from"../chunks/DLS4WeON.js";import{e as R,a as f,s as C,f as h}from"../chunks/ByVGy8qs.js";import{i as X}from"../chunks/537vdszY.js";import{d as L,s as Q,a as U,e as E,b as V,c as Z}from"../chunks/DmL0_esv.js";import{d as tt}from"../chunks/C67DyfnJ.js";import{e as O,i as W}from"../chunks/zKsXIgWY.js";var et=h('
'),at=h('
'),st=h('
'),rt=h('
',1);function nt(T,g){F(g,!0);const S={Onboard:"var(--accent-blue-dim)",Research:"var(--accent-purple-dim)",Plan:"var(--accent-gold-dim)",Implement:"var(--accent-green-dim)",Review:"var(--accent-gold)",Complete:"var(--accent-green)"},D={Onboard:"var(--accent-blue)",Research:"var(--accent-purple)",Plan:"var(--accent-gold)",Implement:"var(--accent-green-text)",Review:"var(--accent-gold)",Complete:"var(--accent-green-text)"};function P(a){const e=Math.floor(a/6e4);if(e<60)return`${e}m`;const s=Math.floor(e/60);return s<24?`${s}h ${e%60}m`:`${Math.floor(s/24)}d ${s%24}h`}let _=z(()=>{if(g.quests.length===0)return[];let a=1/0,e=-1/0;for(const i of g.quests){for(const r of i.phases_completed){const l=new Date(r.timestamp).getTime();isNaN(l)||(le&&(e=l))}const o=new Date(i.created_at).getTime();!isNaN(o)&&onew Date(c.timestamp).getTime()-new Date(u.timestamp).getTime());if(o.length===0)continue;const r=[],l=new Date(i.created_at).getTime();for(let c=0;cn(_),W,(a,e)=>{var s=at(),t=p(s),i=p(t,!0);d(t);var o=q(t,2);O(o,21,()=>n(e).segments,W,(r,l)=>{var c=et();let u;k(()=>u=L(c,"",u,{left:`${n(l).startPct??""}%`,width:`${n(l).widthPct??""}%`,background:S[n(l).phase]??"var(--bg-raised)",color:D[n(l).phase]??"var(--text-muted)"})),R("mouseenter",c,N=>w(N,n(e).name,n(l))),R("mouseleave",c,$),f(r,c)}),d(o),d(s),k(()=>C(i,n(e).name)),f(a,s)}),d(m);var j=q(m,2);{var M=a=>{var e=st();let s;var t=p(e),i=p(t,!0);d(t);var o=q(t,2),r=p(o,!0);d(o),d(e),k(()=>{s=L(e,"",s,{left:`${n(v).x+12}px`,top:`${n(v).y-8}px`}),C(i,n(v).phase),C(r,n(v).duration)}),f(a,e)};X(j,a=>{n(v)&&a(M)})}f(T,b),G()}var ot=h('
Loading quest timeline data...
'),it=h('
No quest timeline data available.
'),lt=h('

Timeline

');function gt(T,g){F(g,!0);const S=()=>K(E,"$dashboardStatus",D),[D,P]=J();let _=y(A([])),v=y(!0),w=y(!1);async function $(){const t=S();if(!t)return;x(w,!0);const i=t.quests.map(r=>r.name),o=await Promise.allSettled(i.map(r=>tt(r)));x(_,o.filter(r=>r.status==="fulfilled").map(r=>r.value).filter(r=>r!=null),!0),x(v,!1)}let b=null;B(()=>{Q(),U(),b=E.subscribe(t=>{t&&!n(w)&&$()})}),H(()=>{V(),Z(),b?.()});var m=lt(),j=q(p(m),2),M=p(j);{var a=t=>{var i=ot();f(t,i)},e=t=>{var i=it();f(t,i)},s=t=>{nt(t,{get quests(){return n(_)}})};X(M,t=>{n(v)?t(a):n(_).length===0?t(e,1):t(s,-1)})}d(j),d(m),f(T,m),G(),P()}export{gt as component}; diff --git a/cli/internal/dashboard/static/_app/version.json b/cli/internal/dashboard/static/_app/version.json new file mode 100644 index 0000000..50c8ef3 --- /dev/null +++ b/cli/internal/dashboard/static/_app/version.json @@ -0,0 +1 @@ +{"version":"1773281563336"} \ No newline at end of file diff --git a/cli/internal/dashboard/static/app.js b/cli/internal/dashboard/static/app.js deleted file mode 100644 index 01cd486..0000000 --- a/cli/internal/dashboard/static/app.js +++ /dev/null @@ -1,620 +0,0 @@ -(function () { - "use strict"; - - const PHASES = ["Onboard", "Research", "Plan", "Implement", "Review", "Complete"]; - - let prevStatus = null; - let pollTimer = null; - let eaglesData = null; - - // ── Bootstrap ────────────────────────────────── - - async function init() { - try { - const data = await fetchStatus(); - eaglesData = await fetchEagles(); - render(data); - await fetchAndRenderTidings(); - await fetchAndRenderBulletin(); - await fetchAndRenderProblems(); - const interval = (data.poll_interval || 5) * 1000; - pollTimer = setInterval(poll, interval); - } catch (err) { - addActivity("Failed to connect: " + err.message); - } - } - - async function fetchStatus() { - const res = await fetch("/api/status"); - if (!res.ok) throw new Error("status " + res.status); - return res.json(); - } - - async function fetchEagles() { - try { - const res = await fetch("/api/eagles"); - if (!res.ok) return null; - return res.json(); - } catch (err) { - return null; - } - } - - // ── Polling ──────────────────────────────────── - - async function poll() { - const dot = document.getElementById("poll-indicator"); - dot.classList.add("active"); - try { - const data = await fetchStatus(); - eaglesData = await fetchEagles(); - detectChanges(data); - render(data); - await fetchAndRenderTidings(); - await fetchAndRenderBulletin(); - await fetchAndRenderProblems(); - } catch (err) { - addActivity("Poll error: " + err.message); - } - setTimeout(() => dot.classList.remove("active"), 1000); - } - - // ── Render ───────────────────────────────────── - - function render(status) { - // Header - document.getElementById("fellowship-name").textContent = status.name || "Fellowship"; - - const quests = status.quests || []; - const scouts = status.scouts || []; - var activeQuests = quests.filter(function (q) { return q.status !== "completed" && q.status !== "cancelled"; }); - var doneQuests = quests.filter(function (q) { return q.status === "completed" || q.status === "cancelled"; }); - var questCountText = quests.length + " quest" + (quests.length !== 1 ? "s" : ""); - if (doneQuests.length > 0) { - questCountText += " (" + doneQuests.length + " done)"; - } - document.getElementById("quest-count").textContent = questCountText; - document.getElementById("scout-count").textContent = scouts.length + " scout" + (scouts.length !== 1 ? "s" : ""); - - // Quest cards — group by company - const container = document.getElementById("quest-cards"); - container.innerHTML = ""; - var companies = status.companies || []; - var rendered = {}; - - companies.forEach(function (c) { - var companyQuests = activeQuests.filter(function (q) { - return c.quests && c.quests.indexOf(q.name) !== -1; - }); - var companyScouts = scouts.filter(function (s) { - return c.scouts && c.scouts.indexOf(s.name) !== -1; - }); - if (companyQuests.length === 0 && companyScouts.length === 0) return; - - container.appendChild(renderCompanyHeader(c, companyQuests)); - - companyQuests.forEach(function (q) { - container.appendChild(renderCard(q)); - rendered[q.name] = true; - }); - companyScouts.forEach(function (s) { - container.appendChild(renderScoutCard(s)); - rendered[s.name] = true; - }); - }); - - // Ungrouped active quests and scouts - var ungroupedQuests = activeQuests.filter(function (q) { return !rendered[q.name]; }); - var ungroupedScouts = scouts.filter(function (s) { return !rendered[s.name]; }); - if (ungroupedQuests.length > 0 || ungroupedScouts.length > 0) { - if (companies.length > 0) { - var ungroupedHeader = document.createElement("div"); - ungroupedHeader.className = "company-header"; - ungroupedHeader.innerHTML = "

Ungrouped

"; - container.appendChild(ungroupedHeader); - } - ungroupedQuests.forEach(function (q) { - container.appendChild(renderCard(q)); - }); - ungroupedScouts.forEach(function (s) { - container.appendChild(renderScoutCard(s)); - }); - } - - // Done quests section - if (doneQuests.length > 0) { - var doneSection = document.createElement("div"); - doneSection.className = "done-section"; - - var doneHeader = document.createElement("div"); - doneHeader.className = "done-section-header"; - doneHeader.innerHTML = "

Done

" + - '' + doneQuests.length + " quest" + (doneQuests.length !== 1 ? "s" : "") + ""; - doneHeader.style.cursor = "pointer"; - - var doneCards = document.createElement("div"); - doneCards.className = "done-cards"; - - doneQuests.forEach(function (q) { - doneCards.appendChild(renderCard(q)); - }); - - doneHeader.addEventListener("click", function () { - doneCards.classList.toggle("collapsed"); - doneHeader.classList.toggle("collapsed"); - }); - - doneSection.appendChild(doneHeader); - doneSection.appendChild(doneCards); - container.appendChild(doneSection); - } - - prevStatus = status; - } - - function renderCompanyHeader(company, companyQuests) { - var header = document.createElement("div"); - header.className = "company-header"; - - var implementPlus = 0; - var total = (company.quests || []).length + (company.scouts || []).length; - var hasPending = false; - - companyQuests.forEach(function (q) { - var idx = PHASES.indexOf(q.phase); - if (idx >= 3) implementPlus++; // Implement+ - if (q.gate_pending) hasPending = true; - }); - - var summary = implementPlus + "/" + total + " quests in Implement+"; - header.innerHTML = "

" + escapeHTML(company.name) + "

" + - '' + escapeHTML(summary) + ""; - - if (hasPending) { - var approveAllBtn = document.createElement("button"); - approveAllBtn.className = "btn btn-approve"; - approveAllBtn.textContent = "Approve All"; - approveAllBtn.addEventListener("click", function () { - window.__approveCompany(company.name); - }); - header.appendChild(approveAllBtn); - } - - return header; - } - - function renderCard(quest) { - const card = document.createElement("div"); - var isDone = quest.status === "completed" || quest.status === "cancelled"; - card.className = "quest-card" + (quest.gate_pending ? " pending" : "") + (isDone ? " " + quest.status : ""); - - const phaseIndex = PHASES.indexOf(quest.phase); - - // Progress bar segments - let progressHTML = '
'; - for (let i = 0; i < PHASES.length; i++) { - progressHTML += '
'; - } - progressHTML += "
"; - - var eaglesHealth = getQuestHealth(quest.worktree); - var badgeHTML = eaglesHealth ? " " + renderHealthBadge(eaglesHealth.health) : ""; - - var statusBadgeHTML = ""; - if (isDone) { - var statusLabel = quest.status === "completed" ? "completed" : "cancelled"; - var statusClass = quest.status === "completed" ? "status-done" : "status-blocked"; - statusBadgeHTML = ' ' + escapeHTML(statusLabel) + ""; - } - - var errandProgressHTML = ""; - if (quest.errands_total > 0) { - errandProgressHTML = '
' + - quest.errands_done + "/" + quest.errands_total + " errands done" + - "
"; - } - - card.innerHTML = - "

" + escapeHTML(quest.name || quest.worktree) + badgeHTML + statusBadgeHTML + "

" + - '
' + escapeHTML(quest.phase || "Unknown") + "
" + - progressHTML + - errandProgressHTML; - - if (quest.errands_total > 0) { - var errandDetails = document.createElement("div"); - errandDetails.className = "errand-details"; - errandDetails.style.display = "none"; - card.appendChild(errandDetails); - - card.style.cursor = "pointer"; - card.addEventListener("click", function (e) { - if (e.target.tagName === "BUTTON") return; - var details = card.querySelector(".errand-details"); - if (details.style.display === "none") { - details.style.display = "block"; - loadErrandItems(quest.worktree, details); - } else { - details.style.display = "none"; - } - }); - } - - if (quest.gate_pending) { - var actions = document.createElement("div"); - actions.className = "gate-actions"; - - var approveBtn = document.createElement("button"); - approveBtn.className = "btn btn-approve"; - approveBtn.textContent = "Approve"; - approveBtn.addEventListener("click", function () { window.__approve(quest.worktree); }); - - var rejectBtn = document.createElement("button"); - rejectBtn.className = "btn btn-reject"; - rejectBtn.textContent = "Reject"; - - actions.appendChild(approveBtn); - actions.appendChild(rejectBtn); - card.appendChild(actions); - - var confirmDiv = document.createElement("div"); - confirmDiv.className = "reject-confirm"; - - var span = document.createElement("span"); - span.textContent = "Are you sure?"; - confirmDiv.appendChild(span); - - var confirmBtn = document.createElement("button"); - confirmBtn.className = "btn btn-confirm-reject"; - confirmBtn.textContent = "Confirm Reject"; - confirmBtn.addEventListener("click", function () { window.__reject(quest.worktree); }); - confirmDiv.appendChild(confirmBtn); - - var cancelBtn = document.createElement("button"); - cancelBtn.className = "btn btn-cancel"; - cancelBtn.textContent = "Cancel"; - cancelBtn.addEventListener("click", function () { confirmDiv.classList.remove("visible"); }); - confirmDiv.appendChild(cancelBtn); - - rejectBtn.addEventListener("click", function () { confirmDiv.classList.add("visible"); }); - - card.appendChild(confirmDiv); - } - - return card; - } - - function renderScoutCard(scout) { - const card = document.createElement("div"); - card.className = "quest-card"; - card.innerHTML = - "

" + escapeHTML(scout.name || scout.worktree) + '

' + - '
Scout
'; - return card; - } - - // ── Gate Actions ─────────────────────────────── - - window.__approve = async function (dir) { - try { - const res = await fetch("/api/gate/approve", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ dir: dir }), - }); - if (!res.ok) throw new Error("status " + res.status); - addActivity("Approved gate for " + dir); - poll(); - } catch (err) { - addActivity("Approve failed: " + err.message); - } - }; - - window.__approveCompany = async function (name) { - try { - var res = await fetch("/api/company/" + encodeURIComponent(name) + "/approve", { - method: "POST", - headers: { "Content-Type": "application/json" }, - }); - if (!res.ok) throw new Error("status " + res.status); - var data = await res.json(); - addActivity("Company '" + name + "': approved " + data.approved.length + " gate(s)"); - poll(); - } catch (err) { - addActivity("Company approve failed: " + err.message); - } - }; - - window.__reject = async function (dir) { - try { - const res = await fetch("/api/gate/reject", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ dir: dir }), - }); - if (!res.ok) throw new Error("status " + res.status); - addActivity("Rejected gate for " + dir); - poll(); - } catch (err) { - addActivity("Reject failed: " + err.message); - } - }; - - // ── Activity Feed ────────────────────────────── - - function addActivity(msg) { - const feed = document.getElementById("activity-feed"); - const li = document.createElement("li"); - const time = new Date().toLocaleTimeString(); - li.textContent = time + " — " + msg; - feed.prepend(li); - // Keep feed manageable - while (feed.children.length > 100) { - feed.removeChild(feed.lastChild); - } - } - - function detectChanges(newStatus) { - if (!prevStatus) return; - - const oldQuests = {}; - (prevStatus.quests || []).forEach(function (q) { oldQuests[q.worktree] = q; }); - - (newStatus.quests || []).forEach(function (q) { - const old = oldQuests[q.worktree]; - if (!old) { - addActivity("New quest: " + (q.name || q.worktree)); - return; - } - if (old.phase !== q.phase) { - addActivity((q.name || q.worktree) + ": " + old.phase + " → " + q.phase); - } - if (!old.gate_pending && q.gate_pending) { - addActivity((q.name || q.worktree) + ": gate approval requested"); - } - if (old.gate_pending && !q.gate_pending) { - addActivity((q.name || q.worktree) + ": gate resolved"); - } - if (q.errands_total > 0 && old.errands_done !== q.errands_done) { - addActivity((q.name || q.worktree) + ": errand progress " + q.errands_done + "/" + q.errands_total); - } - }); - } - - // ── Eagles Helpers ───────────────────────────── - - var HEALTH_COLORS = { - working: "#5a8a5a", - stalled: "#c8a84e", - zombie: "#8a4a4a", - idle: "#6a6a6a", - complete: "#5a8a5a" - }; - - var HEALTH_BG = { - working: "rgba(90, 138, 90, 0.2)", - stalled: "rgba(200, 168, 78, 0.2)", - zombie: "rgba(138, 74, 74, 0.2)", - idle: "rgba(106, 106, 106, 0.2)", - complete: "rgba(90, 138, 90, 0.15)" - }; - - function getQuestHealth(worktree) { - if (!eaglesData || !eaglesData.quests) return null; - for (var i = 0; i < eaglesData.quests.length; i++) { - if (eaglesData.quests[i].worktree === worktree) { - return eaglesData.quests[i]; - } - } - return null; - } - - function renderHealthBadge(health) { - if (!health) return ""; - var color = HEALTH_COLORS[health] || "#6a6a6a"; - var bg = HEALTH_BG[health] || "rgba(106, 106, 106, 0.2)"; - return '' + escapeHTML(health) + ""; - } - - // ── Errands ────────────────────────────────── - - async function loadErrandItems(worktree, container) { - try { - var encoded = btoa(worktree).replace(/\+/g, '-').replace(/\//g, '_'); - var res = await fetch("/api/errand/" + encoded); - if (!res.ok) { - container.innerHTML = "

No errands available.

"; - return; - } - var data = await res.json(); - var items = data.items || []; - if (items.length === 0) { - container.innerHTML = "

No errands.

"; - return; - } - var html = '
    '; - for (var i = 0; i < items.length; i++) { - var item = items[i]; - var badge = '' + escapeHTML(item.status) + ""; - html += "
  • " + badge + " " + escapeHTML(item.id) + " " + escapeHTML(item.description) + "
  • "; - } - html += "
"; - container.innerHTML = html; - } catch (err) { - container.innerHTML = "

Failed to load errands.

"; - } - } - - // ── Bulletin Board ─────────────────────────────── - - async function fetchAndRenderBulletin() { - try { - var res = await fetch("/api/bulletin"); - if (!res.ok) { - renderBulletin([]); - return; - } - var entries = await res.json(); - renderBulletin(entries); - } catch (err) { - renderBulletin([]); - } - } - - function renderBulletin(entries) { - var container = document.getElementById("bulletin-entries"); - var section = document.getElementById("bulletin-section"); - if (!container || !section) return; - - if (!entries || entries.length === 0) { - section.style.display = "none"; - return; - } - section.style.display = "block"; - container.innerHTML = ""; - - // Group by topic - var byTopic = {}; - entries.forEach(function (e) { - var topic = e.topic || "general"; - if (!byTopic[topic]) byTopic[topic] = []; - byTopic[topic].push(e); - }); - - Object.keys(byTopic).forEach(function (topic) { - var group = document.createElement("div"); - group.className = "bulletin-topic-group"; - - var header = document.createElement("div"); - header.className = "bulletin-topic-header"; - header.textContent = topic; - group.appendChild(header); - - byTopic[topic].forEach(function (e) { - var item = document.createElement("div"); - item.className = "bulletin-item"; - - var timeStr = e.ts; - try { - var d = new Date(e.ts); - if (!isNaN(d.getTime())) timeStr = d.toLocaleTimeString(); - } catch (err) {} - - var filesStr = ""; - if (e.files && e.files.length > 0) { - filesStr = ' ' + escapeHTML(e.files.join(", ")) + ""; - } - - item.innerHTML = - '' + escapeHTML(timeStr) + " " + - '' + escapeHTML(e.quest || "") + " " + - '' + escapeHTML(e.discovery || "") + "" + - filesStr; - group.appendChild(item); - }); - - container.appendChild(group); - }); - } - - // ── Event Stream ───────────────────────────────── - - var EVENT_TYPE_CLASSES = { - gate_approved: "event-approved", - phase_transition: "event-approved", - gate_submitted: "event-submitted", - lembas_completed: "event-submitted", - metadata_updated: "event-submitted", - gate_rejected: "event-rejected", - file_modified: "event-neutral", - }; - - async function fetchAndRenderTidings() { - try { - var res = await fetch("/api/herald"); - if (!res.ok) return; - var evts = await res.json(); - renderEventStream(evts); - } catch (err) { - // silently ignore event fetch errors - } - } - - function renderEventStream(evts) { - var container = document.getElementById("event-stream"); - if (!container) return; - container.innerHTML = ""; - if (!evts || evts.length === 0) { - var li = document.createElement("li"); - li.className = "event-item event-neutral"; - li.textContent = "No tidings recorded yet."; - container.appendChild(li); - return; - } - evts.forEach(function (evt) { - var li = document.createElement("li"); - var cls = EVENT_TYPE_CLASSES[evt.type] || "event-neutral"; - li.className = "event-item " + cls; - - var timeStr = evt.timestamp; - try { - timeStr = new Date(evt.timestamp).toLocaleTimeString(); - } catch (e) {} - - var typeLabel = (evt.type || "").replace(/_/g, " "); - li.innerHTML = - '' + escapeHTML(timeStr) + " " + - '' + escapeHTML(evt.quest || "") + " " + - '' + escapeHTML(typeLabel) + "" + - (evt.detail ? ' ' + escapeHTML(evt.detail) + "" : ""); - container.appendChild(li); - }); - } - - // ── Problems Banner ──────────────────────────── - - async function fetchAndRenderProblems() { - try { - var res = await fetch("/api/herald/problems"); - if (!res.ok) return; - var problems = await res.json(); - renderProblems(problems); - } catch (err) { - // silently ignore - } - } - - function renderProblems(problems) { - var banner = document.getElementById("problems-banner"); - if (!banner) return; - banner.innerHTML = ""; - if (!problems || problems.length === 0) { - banner.style.display = "none"; - return; - } - banner.style.display = "block"; - problems.forEach(function (p) { - var badge = document.createElement("div"); - badge.className = "problem-badge problem-" + p.severity; - badge.innerHTML = - '' + escapeHTML(p.severity) + " " + - '' + escapeHTML(p.quest) + ": " + - '' + escapeHTML(p.message) + ""; - banner.appendChild(badge); - }); - } - - // ── Helpers ──────────────────────────────────── - - function escapeHTML(str) { - var div = document.createElement("div"); - div.textContent = str; - return div.innerHTML; - } - - // ── Start ────────────────────────────────────── - - document.addEventListener("DOMContentLoaded", init); -})(); diff --git a/cli/internal/dashboard/static/fonts/cinzel-400.ttf b/cli/internal/dashboard/static/fonts/cinzel-400.ttf new file mode 100644 index 0000000..4213977 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/cinzel-400.ttf differ diff --git a/cli/internal/dashboard/static/fonts/cinzel-600.ttf b/cli/internal/dashboard/static/fonts/cinzel-600.ttf new file mode 100644 index 0000000..1204104 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/cinzel-600.ttf differ diff --git a/cli/internal/dashboard/static/fonts/cinzel-700.ttf b/cli/internal/dashboard/static/fonts/cinzel-700.ttf new file mode 100644 index 0000000..1018a08 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/cinzel-700.ttf differ diff --git a/cli/internal/dashboard/static/fonts/dm-sans-300.ttf b/cli/internal/dashboard/static/fonts/dm-sans-300.ttf new file mode 100644 index 0000000..842166b Binary files /dev/null and b/cli/internal/dashboard/static/fonts/dm-sans-300.ttf differ diff --git a/cli/internal/dashboard/static/fonts/dm-sans-400.ttf b/cli/internal/dashboard/static/fonts/dm-sans-400.ttf new file mode 100644 index 0000000..6c789ea Binary files /dev/null and b/cli/internal/dashboard/static/fonts/dm-sans-400.ttf differ diff --git a/cli/internal/dashboard/static/fonts/dm-sans-500.ttf b/cli/internal/dashboard/static/fonts/dm-sans-500.ttf new file mode 100644 index 0000000..dc44754 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/dm-sans-500.ttf differ diff --git a/cli/internal/dashboard/static/fonts/dm-sans-600.ttf b/cli/internal/dashboard/static/fonts/dm-sans-600.ttf new file mode 100644 index 0000000..ec5dcf3 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/dm-sans-600.ttf differ diff --git a/cli/internal/dashboard/static/fonts/fonts.css b/cli/internal/dashboard/static/fonts/fonts.css new file mode 100644 index 0000000..b23d8f2 --- /dev/null +++ b/cli/internal/dashboard/static/fonts/fonts.css @@ -0,0 +1,105 @@ +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/cinzel-400.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/fonts/cinzel-600.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/fonts/cinzel-700.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(/fonts/dm-sans-300.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/dm-sans-400.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/fonts/dm-sans-500.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/fonts/dm-sans-600.ttf) format('truetype'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(/fonts/jetbrains-mono-300.ttf) format('truetype'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/jetbrains-mono-400.ttf) format('truetype'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/fonts/jetbrains-mono-500.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(/fonts/outfit-300.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/outfit-400.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/fonts/outfit-500.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/fonts/outfit-600.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/fonts/outfit-700.ttf) format('truetype'); +} diff --git a/cli/internal/dashboard/static/fonts/jetbrains-mono-300.ttf b/cli/internal/dashboard/static/fonts/jetbrains-mono-300.ttf new file mode 100644 index 0000000..333f19c Binary files /dev/null and b/cli/internal/dashboard/static/fonts/jetbrains-mono-300.ttf differ diff --git a/cli/internal/dashboard/static/fonts/jetbrains-mono-400.ttf b/cli/internal/dashboard/static/fonts/jetbrains-mono-400.ttf new file mode 100644 index 0000000..129e882 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/jetbrains-mono-400.ttf differ diff --git a/cli/internal/dashboard/static/fonts/jetbrains-mono-500.ttf b/cli/internal/dashboard/static/fonts/jetbrains-mono-500.ttf new file mode 100644 index 0000000..51ccd91 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/jetbrains-mono-500.ttf differ diff --git a/cli/internal/dashboard/static/fonts/outfit-300.ttf b/cli/internal/dashboard/static/fonts/outfit-300.ttf new file mode 100644 index 0000000..25b080c Binary files /dev/null and b/cli/internal/dashboard/static/fonts/outfit-300.ttf differ diff --git a/cli/internal/dashboard/static/fonts/outfit-400.ttf b/cli/internal/dashboard/static/fonts/outfit-400.ttf new file mode 100644 index 0000000..0b0a0d7 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/outfit-400.ttf differ diff --git a/cli/internal/dashboard/static/fonts/outfit-500.ttf b/cli/internal/dashboard/static/fonts/outfit-500.ttf new file mode 100644 index 0000000..0ba786a Binary files /dev/null and b/cli/internal/dashboard/static/fonts/outfit-500.ttf differ diff --git a/cli/internal/dashboard/static/fonts/outfit-600.ttf b/cli/internal/dashboard/static/fonts/outfit-600.ttf new file mode 100644 index 0000000..52e25bc Binary files /dev/null and b/cli/internal/dashboard/static/fonts/outfit-600.ttf differ diff --git a/cli/internal/dashboard/static/fonts/outfit-700.ttf b/cli/internal/dashboard/static/fonts/outfit-700.ttf new file mode 100644 index 0000000..0389ff2 Binary files /dev/null and b/cli/internal/dashboard/static/fonts/outfit-700.ttf differ diff --git a/cli/internal/dashboard/static/index.html b/cli/internal/dashboard/static/index.html index 5c303ff..ae825aa 100644 --- a/cli/internal/dashboard/static/index.html +++ b/cli/internal/dashboard/static/index.html @@ -1,48 +1,42 @@ - - - - Fellowship Dashboard - - - - - - - + + + + + + + + + + + + + + + + + + + + +
+ - + Promise.all([ + import("/_app/immutable/entry/start.B5-0ZWIv.js"), + import("/_app/immutable/entry/app.BdcOekXH.js") + ]).then(([kit, app]) => { + kit.start(app, element); + }); + } + +
+ diff --git a/cli/internal/dashboard/static/style.css b/cli/internal/dashboard/static/style.css deleted file mode 100644 index 1be9af8..0000000 --- a/cli/internal/dashboard/static/style.css +++ /dev/null @@ -1,583 +0,0 @@ -:root { - --bg-deep: #1a1510; - --bg-card: #2a2118; - --bg-card-pending: #2e2214; - --text-primary: #d4c4a8; - --text-secondary: #8a7d6b; - --gold: #c8a84e; - --gold-dim: #8a7a3e; - --amber-glow: rgba(200, 168, 78, 0.15); - --green: #5a8a5a; - --red: #8a4a4a; - --font-heading: 'Cinzel', serif; - --font-body: 'Crimson Text', serif; -} - -*, *::before, *::after { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -body { - background: var(--bg-deep); - color: var(--text-primary); - font-family: var(--font-body); - font-size: 17px; - line-height: 1.6; - min-height: 100vh; - padding: 0 1rem 2rem; -} - -/* ── Header ─────────────────────────────────────── */ - -header { - padding: 1.5rem 0 1rem; - border-bottom: 2px solid var(--gold-dim); - border-image: repeating-linear-gradient( - 90deg, - var(--gold-dim) 0px, - var(--gold-dim) 8px, - transparent 8px, - transparent 14px, - var(--gold) 14px, - var(--gold) 16px, - transparent 16px, - transparent 22px - ) 2; - margin-bottom: 1.5rem; - position: relative; -} - -.header-inner { - max-width: 720px; - margin: 0 auto; - position: relative; -} - -header h1 { - font-family: var(--font-heading); - font-weight: 600; - font-size: 1.6rem; - color: var(--gold); - letter-spacing: 0.08em; -} - -.header-stats { - margin-top: 0.25rem; - font-size: 0.95rem; - color: var(--text-secondary); -} - -.stat-sep { - margin: 0 0.4rem; - opacity: 0.5; -} - -/* Poll indicator */ - -.poll-dot { - position: absolute; - top: 0.25rem; - right: 0; - width: 8px; - height: 8px; - border-radius: 50%; - background: var(--gold-dim); - transition: background 0.3s; -} - -.poll-dot.active { - background: var(--gold); - animation: pulse 1s ease-in-out; -} - -@keyframes pulse { - 0%, 100% { box-shadow: 0 0 0 0 rgba(200, 168, 78, 0.4); } - 50% { box-shadow: 0 0 0 6px rgba(200, 168, 78, 0); } -} - -/* ── Main / Cards ───────────────────────────────── */ - -main { - max-width: 720px; - margin: 0 auto; -} - -.cards-container { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.quest-card { - background: var(--bg-card); - border: 1px solid #3a3028; - border-radius: 8px; - padding: 1.25rem 1.5rem; - transition: border-color 0.3s, box-shadow 0.3s; -} - -.quest-card.pending { - background: var(--bg-card-pending); - border-color: var(--gold-dim); - box-shadow: 0 0 16px var(--amber-glow), 0 0 4px var(--amber-glow); -} - -.quest-card h3 { - font-family: var(--font-heading); - font-size: 1.05rem; - font-weight: 600; - color: var(--text-primary); - margin-bottom: 0.5rem; -} - -.quest-phase { - font-size: 0.9rem; - color: var(--text-secondary); - margin-bottom: 0.75rem; -} - -/* Progress bar */ - -.progress-bar { - display: flex; - gap: 3px; - height: 6px; - margin-bottom: 0.75rem; -} - -.progress-segment { - flex: 1; - background: #332a1e; - border-radius: 3px; - transition: background 0.3s; -} - -.progress-segment.filled { - background: var(--gold); -} - -/* Gate buttons */ - -.gate-actions { - display: flex; - gap: 0.5rem; - margin-top: 0.5rem; -} - -.btn { - font-family: var(--font-body); - font-size: 0.9rem; - padding: 0.4rem 1rem; - border: 1px solid; - border-radius: 4px; - cursor: pointer; - transition: background 0.2s, border-color 0.2s; -} - -.btn-approve { - background: rgba(90, 138, 90, 0.2); - border-color: var(--green); - color: #8aba8a; -} - -.btn-approve:hover { - background: rgba(90, 138, 90, 0.35); -} - -.btn-reject { - background: rgba(138, 74, 74, 0.15); - border-color: var(--red); - color: #b07070; -} - -.btn-reject:hover { - background: rgba(138, 74, 74, 0.3); -} - -/* Reject confirmation */ - -.reject-confirm { - display: none; - align-items: center; - gap: 0.5rem; - margin-top: 0.5rem; - font-size: 0.9rem; - color: var(--text-secondary); -} - -.reject-confirm.visible { - display: flex; -} - -.btn-confirm-reject { - background: rgba(138, 74, 74, 0.3); - border-color: var(--red); - color: #c07070; -} - -.btn-cancel { - background: transparent; - border-color: var(--text-secondary); - color: var(--text-secondary); -} - -/* ── Done Quests ───────────────────────────────── */ - -.quest-card.completed { - opacity: 0.6; - border-color: var(--green); -} - -.quest-card.completed .progress-segment.filled { - background: var(--green); -} - -.quest-card.cancelled { - opacity: 0.6; - border-color: #4a4a4a; -} - -.quest-card.cancelled .progress-segment.filled { - background: #6a6a6a; -} - -.done-section { - margin-top: 1.5rem; -} - -.done-section-header { - display: flex; - align-items: center; - gap: 0.75rem; - padding: 0.5rem 0; - border-bottom: 1px solid #3a3028; - margin-bottom: 0.75rem; -} - -.done-section-header h2 { - font-family: var(--font-heading); - font-size: 1rem; - font-weight: 600; - color: var(--text-secondary); - letter-spacing: 0.06em; -} - -.done-section-header::before { - content: "▾"; - color: var(--text-secondary); - font-size: 0.8rem; -} - -.done-section-header.collapsed::before { - content: "▸"; -} - -.done-count { - font-size: 0.85rem; - color: var(--text-secondary); -} - -.done-cards { - display: flex; - flex-direction: column; - gap: 0.75rem; -} - -.done-cards.collapsed { - display: none; -} - -/* ── Errands ───────────────────────────────────── */ - -.errand-progress { - font-family: var(--font-body); - font-size: 0.85rem; - color: var(--gold-dim); - margin-top: 0.5rem; -} - -.errand-details { - margin-top: 0.75rem; - border-top: 1px solid rgba(58, 48, 40, 0.5); - padding-top: 0.5rem; -} - -.errand-item-list { - list-style: none; - font-size: 0.85rem; - color: var(--text-secondary); -} - -.errand-item-list li { - padding: 0.25rem 0; -} - -.status-badge { - display: inline-block; - font-size: 0.7rem; - padding: 0.1rem 0.4rem; - border-radius: 3px; - text-transform: uppercase; - letter-spacing: 0.04em; - font-family: var(--font-body); -} - -.status-pending { - background: rgba(138, 125, 107, 0.2); - color: var(--text-secondary); -} - -.status-active { - background: rgba(200, 168, 78, 0.2); - color: var(--gold); -} - -.status-done { - background: rgba(90, 138, 90, 0.2); - color: var(--green); -} - -.status-blocked { - background: rgba(138, 74, 74, 0.2); - color: #c07070; -} - -/* ── Activity Feed ──────────────────────────────── */ - -#activity-section { - max-width: 720px; - margin: 2rem auto 0; -} - -#activity-section h2 { - font-family: var(--font-heading); - font-size: 1rem; - font-weight: 600; - color: var(--gold-dim); - letter-spacing: 0.06em; - margin-bottom: 0.5rem; -} - -#activity-feed { - list-style: none; - max-height: 240px; - overflow-y: auto; - font-size: 0.85rem; - color: var(--text-secondary); - line-height: 1.5; -} - -#activity-feed li { - padding: 0.2rem 0; - border-bottom: 1px solid rgba(58, 48, 40, 0.5); -} - -#activity-feed::-webkit-scrollbar { - width: 4px; -} - -#activity-feed::-webkit-scrollbar-thumb { - background: #3a3028; - border-radius: 2px; -} - -/* ── Problems Banner ────────────────────────────── */ - -#problems-banner { - max-width: 720px; - margin: 0 auto 1rem; - display: none; -} - -.problem-badge { - padding: 0.5rem 0.75rem; - border-radius: 6px; - margin-bottom: 0.4rem; - font-size: 0.85rem; - line-height: 1.4; -} - -.problem-warning { - background: rgba(200, 168, 78, 0.15); - border: 1px solid var(--gold-dim); - color: var(--gold); -} - -.problem-critical { - background: rgba(138, 74, 74, 0.2); - border: 1px solid var(--red); - color: #c07070; -} - -.problem-severity { - text-transform: uppercase; - font-weight: 600; - font-size: 0.75rem; - letter-spacing: 0.05em; -} - -.problem-quest { - font-family: var(--font-heading); - font-weight: 600; -} - -/* ── Bulletin Board ────────────────────────────── */ - -#bulletin-section { - max-width: 720px; - margin: 2rem auto 0; - display: none; -} - -#bulletin-section h2 { - font-family: var(--font-heading); - font-size: 1rem; - font-weight: 600; - color: var(--gold-dim); - letter-spacing: 0.06em; - margin-bottom: 0.5rem; -} - -.bulletin-topic-group { - margin-bottom: 0.75rem; -} - -.bulletin-topic-header { - font-family: var(--font-heading); - font-size: 0.85rem; - font-weight: 600; - color: var(--gold); - text-transform: uppercase; - letter-spacing: 0.06em; - padding: 0.3rem 0; - border-bottom: 1px solid rgba(200, 168, 78, 0.25); - margin-bottom: 0.25rem; -} - -.bulletin-item { - padding: 0.3rem 0.5rem; - border-bottom: 1px solid rgba(58, 48, 40, 0.5); - border-left: 3px solid var(--gold-dim); - font-size: 0.85rem; - line-height: 1.5; -} - -.bulletin-time { - color: var(--text-secondary); - margin-right: 0.3rem; -} - -.bulletin-quest { - font-family: var(--font-heading); - font-size: 0.8rem; - color: var(--text-primary); - margin-right: 0.3rem; -} - -.bulletin-discovery { - color: var(--text-primary); -} - -.bulletin-files { - display: block; - font-size: 0.75rem; - color: var(--text-secondary); - font-style: italic; - margin-top: 0.1rem; -} - -/* ── Event Stream ──────────────────────────────── */ - -#event-stream-section { - max-width: 720px; - margin: 2rem auto 0; -} - -#event-stream-section h2 { - font-family: var(--font-heading); - font-size: 1rem; - font-weight: 600; - color: var(--gold-dim); - letter-spacing: 0.06em; - margin-bottom: 0.5rem; -} - -#event-stream { - list-style: none; - max-height: 300px; - overflow-y: auto; - font-size: 0.85rem; - line-height: 1.5; -} - -.event-item { - padding: 0.3rem 0.5rem; - border-bottom: 1px solid rgba(58, 48, 40, 0.5); - border-left: 3px solid transparent; -} - -.event-approved { - border-left-color: var(--green); -} - -.event-submitted { - border-left-color: var(--gold-dim); -} - -.event-rejected { - border-left-color: var(--red); -} - -.event-neutral { - border-left-color: var(--text-secondary); -} - -.event-time { - color: var(--text-secondary); - margin-right: 0.3rem; -} - -.event-quest { - font-family: var(--font-heading); - font-size: 0.8rem; - color: var(--text-primary); - margin-right: 0.3rem; -} - -.event-type-label { - color: var(--gold-dim); - font-size: 0.8rem; -} - -.event-detail { - color: var(--text-secondary); - font-style: italic; -} - -#event-stream::-webkit-scrollbar { - width: 4px; -} - -#event-stream::-webkit-scrollbar-thumb { - background: #3a3028; - border-radius: 2px; -} - -/* ── Responsive ─────────────────────────────────── */ - -@media (max-width: 600px) { - body { - font-size: 15px; - padding: 0 0.75rem 1.5rem; - } - - header h1 { - font-size: 1.3rem; - } - - .quest-card { - padding: 1rem 1.1rem; - } -} diff --git a/cli/internal/dashboard/ws.go b/cli/internal/dashboard/ws.go new file mode 100644 index 0000000..7bcef70 --- /dev/null +++ b/cli/internal/dashboard/ws.go @@ -0,0 +1,90 @@ +package dashboard + +import ( + "encoding/json" + "log" + "net/http" + "sync" + "time" + + "github.com/gorilla/websocket" +) + +// WSEvent is a notification pushed to all connected dashboard clients. +type WSEvent struct { + Type string `json:"type"` + QuestID string `json:"quest_id,omitempty"` + Phase string `json:"phase,omitempty"` + Action string `json:"action,omitempty"` + AlertType string `json:"alert_type,omitempty"` + Quests []string `json:"quests,omitempty"` + CommandID string `json:"command_id,omitempty"` + Timestamp int64 `json:"timestamp"` +} + +var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { return true }, // allow all origins (dashboard is localhost-only by design) +} + +// Hub manages WebSocket connections and broadcasts events. +type Hub struct { + mu sync.RWMutex + conns map[*websocket.Conn]struct{} +} + +func NewHub() *Hub { + return &Hub{conns: make(map[*websocket.Conn]struct{})} +} + +func (h *Hub) Add(conn *websocket.Conn) { + h.mu.Lock() + h.conns[conn] = struct{}{} + h.mu.Unlock() +} + +func (h *Hub) Remove(conn *websocket.Conn) { + h.mu.Lock() + delete(h.conns, conn) + h.mu.Unlock() + conn.Close() +} + +func (h *Hub) Broadcast(event WSEvent) { + if event.Timestamp == 0 { + event.Timestamp = time.Now().Unix() + } + data, err := json.Marshal(event) + if err != nil { + log.Printf("ws: marshal error: %v", err) + return + } + + h.mu.Lock() + defer h.mu.Unlock() + for conn := range h.conns { + conn.SetWriteDeadline(time.Now().Add(5 * time.Second)) + if err := conn.WriteMessage(websocket.TextMessage, data); err != nil { + delete(h.conns, conn) + conn.Close() + } + } +} + +func (h *Hub) HandleWS(w http.ResponseWriter, r *http.Request) { + conn, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Printf("ws: upgrade error: %v", err) + return + } + h.Add(conn) + + // Read pump — just drain pings/pongs, we don't expect client messages + go func() { + defer h.Remove(conn) + for { + if _, _, err := conn.ReadMessage(); err != nil { + break + } + } + }() +} diff --git a/cli/internal/dashboard/ws_test.go b/cli/internal/dashboard/ws_test.go new file mode 100644 index 0000000..83b0e84 --- /dev/null +++ b/cli/internal/dashboard/ws_test.go @@ -0,0 +1,11 @@ +package dashboard + +import ( + "testing" + "time" +) + +func TestHubBroadcast(t *testing.T) { + hub := NewHub() + hub.Broadcast(WSEvent{Type: "test", Timestamp: time.Now().Unix()}) +} diff --git a/dashboard/.gitignore b/dashboard/.gitignore new file mode 100644 index 0000000..ce4f9d0 --- /dev/null +++ b/dashboard/.gitignore @@ -0,0 +1,3 @@ +node_modules +.svelte-kit +build diff --git a/dashboard/build.sh b/dashboard/build.sh new file mode 100755 index 0000000..79f3db0 --- /dev/null +++ b/dashboard/build.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +echo "Building dashboard..." +npm run build + +echo "Copying to Go embed directory..." +rm -rf ../cli/internal/dashboard/static/* +cp -r build/* ../cli/internal/dashboard/static/ + +echo "✓ Dashboard built and copied" diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json new file mode 100644 index 0000000..60b5245 --- /dev/null +++ b/dashboard/package-lock.json @@ -0,0 +1,1619 @@ +{ + "name": "fellowship-dashboard", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fellowship-dashboard", + "version": "0.0.1", + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.50.2", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "svelte": "^5.51.0", + "svelte-check": "^4.0.0", + "typescript": "^5.9.3", + "vite": "^7.3.1" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz", + "integrity": "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz", + "integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.53.4", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.53.4.tgz", + "integrity": "sha512-iAIPEahFgDJJyvz8g0jP08KvqnM6JvdW8YfsygZ+pMeMvyM2zssWMltcsotETvjSZ82G3VlitgDtBIvpQSZrTA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", + "cookie": "^0.6.0", + "devalue": "^5.6.3", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "set-cookie-parser": "^3.0.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.3.3", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.4.tgz", + "integrity": "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", + "deepmerge": "^4.3.1", + "magic-string": "^0.30.21", + "obug": "^2.1.0", + "vitefu": "^1.1.1" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.2.tgz", + "integrity": "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "obug": "^2.1.0" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", + "svelte": "^5.0.0", + "vite": "^6.3.0 || ^7.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devalue": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.3.tgz", + "integrity": "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.3.tgz", + "integrity": "sha512-8fOS+GIGCQZl/ZIlhl59htOlms6U8NvX6ZYgYHpRU/b6tVSh3uHkOHZikl3D4cMbYM0JlpBe+p/BkZEi8J9XIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true, + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz", + "integrity": "sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "5.53.10", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.53.10.tgz", + "integrity": "sha512-UcNfWzbrjvYXYSk+U2hME25kpb87oq6/WVLeBF4khyQrb3Ob/URVlN23khal+RbdCUTMfg4qWjI9KZjCNFtYMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", + "acorn": "^8.12.1", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.6.3", + "esm-env": "^1.2.1", + "esrap": "^2.2.2", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-check": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.5.tgz", + "integrity": "sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.2.tgz", + "integrity": "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/dashboard/package.json b/dashboard/package.json new file mode 100644 index 0000000..98ac9e2 --- /dev/null +++ b/dashboard/package.json @@ -0,0 +1,21 @@ +{ + "name": "fellowship-dashboard", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json" + }, + "devDependencies": { + "@sveltejs/adapter-static": "^3.0.10", + "@sveltejs/kit": "^2.50.2", + "@sveltejs/vite-plugin-svelte": "^6.2.4", + "svelte": "^5.51.0", + "svelte-check": "^4.0.0", + "typescript": "^5.9.3", + "vite": "^7.3.1" + } +} diff --git a/dashboard/src/app.html b/dashboard/src/app.html new file mode 100644 index 0000000..8d71495 --- /dev/null +++ b/dashboard/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/dashboard/src/lib/api.ts b/dashboard/src/lib/api.ts new file mode 100644 index 0000000..da9480a --- /dev/null +++ b/dashboard/src/lib/api.ts @@ -0,0 +1,123 @@ +export async function approveGate(dir: string): Promise { + const res = await fetch('/api/gate/approve', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ dir }), + }); + if (!res.ok) throw new Error(`Gate approve failed: ${res.status}`); +} + +export async function rejectGate(dir: string): Promise { + const res = await fetch('/api/gate/reject', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ dir }), + }); + if (!res.ok) throw new Error(`Gate reject failed: ${res.status}`); +} + +export async function spawnQuest(task: string, branch?: string, company?: string): Promise { + const res = await fetch('/api/quest/spawn', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ task, branch, company }), + }); + if (!res.ok) throw new Error(`Spawn quest failed: ${res.status}`); + const data = await res.json(); + return data.command_id; +} + +export async function spawnScout(question: string): Promise { + const res = await fetch('/api/scout/spawn', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ question }), + }); + if (!res.ok) throw new Error(`Spawn scout failed: ${res.status}`); + const data = await res.json(); + return data.command_id; +} + +export async function killQuest(questId: string): Promise { + const res = await fetch('/api/quest/kill', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ quest_id: questId }), + }); + if (!res.ok) throw new Error(`Kill quest failed: ${res.status}`); + const data = await res.json(); + return data.command_id; +} + +export async function restartQuest(questId: string): Promise { + const res = await fetch('/api/quest/restart', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ quest_id: questId }), + }); + if (!res.ok) throw new Error(`Restart quest failed: ${res.status}`); + const data = await res.json(); + return data.command_id; +} + +export async function fetchErrands(worktree: string): Promise { + try { + const encoded = btoa(String.fromCharCode(...new TextEncoder().encode(worktree))) + .replace(/\+/g, '-') + .replace(/\//g, '_'); + const res = await fetch(`/api/errand/${encoded}`); + if (res.ok) return res.json(); + return null; + } catch { + return null; + } +} + +export async function fetchTome(questName: string): Promise { + try { + const res = await fetch(`/api/tome/${encodeURIComponent(questName)}`); + if (res.ok) return res.json(); + return null; + } catch { + return null; + } +} + +export async function fetchAutopsies(): Promise { + try { + const res = await fetch('/api/autopsies'); + if (res.ok) return res.json(); + return []; + } catch { + return []; + } +} + +export async function fetchConfig(): Promise<{ global: unknown; project: unknown }> { + try { + const res = await fetch('/api/config'); + if (res.ok) return res.json(); + return { global: null, project: null }; + } catch { + return { global: null, project: null }; + } +} + +export async function saveConfig(key: string, value: unknown, scope: 'global' | 'project'): Promise { + const res = await fetch('/api/config', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ key, value, scope }), + }); + if (!res.ok) throw new Error(`Save config failed: ${res.status}`); +} + +export async function fetchCommands(): Promise { + try { + const res = await fetch('/api/commands'); + if (res.ok) return res.json(); + return []; + } catch { + return []; + } +} diff --git a/dashboard/src/lib/components/CommandPalette.svelte b/dashboard/src/lib/components/CommandPalette.svelte new file mode 100644 index 0000000..d0952c1 --- /dev/null +++ b/dashboard/src/lib/components/CommandPalette.svelte @@ -0,0 +1,340 @@ + + + +
+ + +
e.stopPropagation()}> + {#if inputMode} +
+ {inputMode === 'spawn-quest' + ? 'Spawn Quest' + : inputMode === 'spawn-scout' + ? 'Spawn Scout' + : inputMode === 'kill-quest' + ? 'Kill Quest' + : 'Restart Quest'} +
+ + a.label.toLowerCase().replace(/\s+/g, '-') === + inputMode?.replace('spawn-', 'spawn-').replace('kill-', 'kill-').replace('restart-', 'restart-') + )?.inputPlaceholder ?? 'Enter value...'} + type="text" + /> + {:else} + +
+ {#each grouped as group} +
{group.category}
+ {#each group.items as item} + {@const idx = filtered.indexOf(item)} + + {/each} + {/each} + {#if filtered.length === 0} +
No matching commands
+ {/if} +
+ {/if} +
+
+ + diff --git a/dashboard/src/lib/components/ConnectionBanner.svelte b/dashboard/src/lib/components/ConnectionBanner.svelte new file mode 100644 index 0000000..79389f8 --- /dev/null +++ b/dashboard/src/lib/components/ConnectionBanner.svelte @@ -0,0 +1,20 @@ + + +{#if !$connected} + +{/if} + + diff --git a/dashboard/src/lib/components/ErrandList.svelte b/dashboard/src/lib/components/ErrandList.svelte new file mode 100644 index 0000000..34f13cb --- /dev/null +++ b/dashboard/src/lib/components/ErrandList.svelte @@ -0,0 +1,72 @@ + + +
+ {#each errands as errand (errand.id)} +
+
+ {#if errand.status === 'done'}✓{:else if errand.status === 'active'}●{/if} +
+ {errand.description} +
+ {/each} +
+ + diff --git a/dashboard/src/lib/components/GanttChart.svelte b/dashboard/src/lib/components/GanttChart.svelte new file mode 100644 index 0000000..2c5a373 --- /dev/null +++ b/dashboard/src/lib/components/GanttChart.svelte @@ -0,0 +1,214 @@ + + +
+ {#each rows as row} +
+
{row.name}
+
+ {#each row.segments as seg} + +
onSegmentEnter(e, row.name, seg)} + onmouseleave={onSegmentLeave} + >
+ {/each} +
+
+ {/each} +
+ +{#if hoveredSegment} +
+ {hoveredSegment.phase} + {hoveredSegment.duration} +
+{/if} + + diff --git a/dashboard/src/lib/components/GateActions.svelte b/dashboard/src/lib/components/GateActions.svelte new file mode 100644 index 0000000..2631cb4 --- /dev/null +++ b/dashboard/src/lib/components/GateActions.svelte @@ -0,0 +1,64 @@ + + +
+ + +
+ + diff --git a/dashboard/src/lib/components/HeraldFeed.svelte b/dashboard/src/lib/components/HeraldFeed.svelte new file mode 100644 index 0000000..df08b60 --- /dev/null +++ b/dashboard/src/lib/components/HeraldFeed.svelte @@ -0,0 +1,87 @@ + + +
+ {#each tidings.slice(0, limit) as tiding} + {@const meta = typeIcons[tiding.type] ?? { icon: '·', color: 'var(--text-muted)' }} +
+ {meta.icon} + {formatDetail(tiding)} + {formatTime(tiding.timestamp)} +
+ {/each} +
+ + diff --git a/dashboard/src/lib/components/PhaseTimeline.svelte b/dashboard/src/lib/components/PhaseTimeline.svelte new file mode 100644 index 0000000..b8e5024 --- /dev/null +++ b/dashboard/src/lib/components/PhaseTimeline.svelte @@ -0,0 +1,47 @@ + + +
+ {#each phases as p} + {@const status = getStatus(p)} +
+ {/each} +
+ + diff --git a/dashboard/src/lib/components/QuestCard.svelte b/dashboard/src/lib/components/QuestCard.svelte new file mode 100644 index 0000000..b074284 --- /dev/null +++ b/dashboard/src/lib/components/QuestCard.svelte @@ -0,0 +1,101 @@ + + + +
e.key === 'Enter' && navigateToQuest()} role="link" tabindex="0"> +
+ {quest.name} + {#if health} + {health.health} + {/if} +
+ + + +
+ {quest.phase} + {#if quest.errands_total > 0} + {quest.errands_done}/{quest.errands_total} errands + {/if} +
+ + {#if quest.gate_pending} +
e.stopPropagation()}> + +
+ {/if} +
+ + diff --git a/dashboard/src/lib/components/Shell.svelte b/dashboard/src/lib/components/Shell.svelte new file mode 100644 index 0000000..9d4688c --- /dev/null +++ b/dashboard/src/lib/components/Shell.svelte @@ -0,0 +1,50 @@ + + +
+ +
+ {@render children()} +
+
+ +{#if paletteOpen} + (paletteOpen = false)} /> +{/if} + + diff --git a/dashboard/src/lib/components/Sidebar.svelte b/dashboard/src/lib/components/Sidebar.svelte new file mode 100644 index 0000000..f00f46d --- /dev/null +++ b/dashboard/src/lib/components/Sidebar.svelte @@ -0,0 +1,148 @@ + + + + + diff --git a/dashboard/src/lib/components/StatCounter.svelte b/dashboard/src/lib/components/StatCounter.svelte new file mode 100644 index 0000000..c238ea1 --- /dev/null +++ b/dashboard/src/lib/components/StatCounter.svelte @@ -0,0 +1,37 @@ + + +
+
{value}
+
{label}
+
+ + diff --git a/dashboard/src/lib/stores/herald.ts b/dashboard/src/lib/stores/herald.ts new file mode 100644 index 0000000..bb305dc --- /dev/null +++ b/dashboard/src/lib/stores/herald.ts @@ -0,0 +1,30 @@ +import { writable } from 'svelte/store'; +import { lastEvent } from './websocket'; +import type { Tiding } from '$lib/types'; + +export const tidings = writable([]); + +export async function fetchTidings() { + try { + const res = await fetch('/api/herald'); + if (res.ok) tidings.set(await res.json()); + } catch { /* offline */ } +} + +let unsubscribe: (() => void) | null = null; + +export function startHeraldPolling() { + if (unsubscribe) return; + fetchTidings(); + unsubscribe = lastEvent.subscribe((event) => { + if (!event) return; + if (event.type === 'herald-event' || event.type === 'gate-resolved' || event.type === 'quest-changed') { + fetchTidings(); + } + }); +} + +export function stopHeraldPolling() { + unsubscribe?.(); + unsubscribe = null; +} diff --git a/dashboard/src/lib/stores/quests.ts b/dashboard/src/lib/stores/quests.ts new file mode 100644 index 0000000..abe34df --- /dev/null +++ b/dashboard/src/lib/stores/quests.ts @@ -0,0 +1,72 @@ +import { writable, derived } from 'svelte/store'; +import { lastEvent } from './websocket'; +import type { DashboardStatus, QuestHealth, Problem } from '$lib/types'; + +export const dashboardStatus = writable(null); +export const questHealths = writable([]); +export const problems = writable([]); + +export const activeQuests = derived(dashboardStatus, ($status) => + $status?.quests.filter((q) => q.status === 'active') ?? [] +); + +export const pendingGates = derived(dashboardStatus, ($status) => + $status?.quests.filter((q) => q.gate_pending) ?? [] +); + +export const activeScouts = derived(dashboardStatus, ($status) => + $status?.scouts ?? [] +); + +async function fetchStatus() { + try { + const res = await fetch('/api/status'); + if (res.ok) dashboardStatus.set(await res.json()); + } catch { /* offline */ } +} + +async function fetchHealth() { + try { + const res = await fetch('/api/eagles'); + if (res.ok) questHealths.set(await res.json()); + } catch { /* offline */ } +} + +async function fetchProblems() { + try { + const res = await fetch('/api/herald/problems'); + if (res.ok) problems.set(await res.json()); + } catch { /* offline */ } +} + +export async function refreshAll() { + await Promise.all([fetchStatus(), fetchHealth(), fetchProblems()]); +} + +let unsubscribe: (() => void) | null = null; + +export function startPolling() { + if (unsubscribe) return; + refreshAll(); + unsubscribe = lastEvent.subscribe((event) => { + if (!event) return; + switch (event.type) { + case 'quest-changed': + case 'gate-submitted': + case 'gate-resolved': + case 'command-completed': + refreshAll(); + break; + case 'alert': + fetchProblems(); + break; + case 'herald-event': + break; + } + }); +} + +export function stopPolling() { + unsubscribe?.(); + unsubscribe = null; +} diff --git a/dashboard/src/lib/stores/websocket.ts b/dashboard/src/lib/stores/websocket.ts new file mode 100644 index 0000000..1470290 --- /dev/null +++ b/dashboard/src/lib/stores/websocket.ts @@ -0,0 +1,90 @@ +import { writable } from 'svelte/store'; + +export type WSEventType = + | 'quest-changed' + | 'gate-submitted' + | 'gate-resolved' + | 'herald-event' + | 'alert' + | 'command-queued' + | 'command-completed'; + +export interface WSEvent { + type: WSEventType; + quest_id?: string; + phase?: string; + action?: string; + alert_type?: string; + quests?: string[]; + command_id?: string; + timestamp: number; +} + +export const connected = writable(false); +export const lastEvent = writable(null); + +let ws: WebSocket | null = null; +let reconnectDelay = 1000; +const MAX_DELAY = 30000; +let shouldReconnect = true; + +function getWSUrl(): string { + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + return `${protocol}//${window.location.host}/ws`; +} + +function connect() { + if (ws?.readyState === WebSocket.OPEN) return; + + let socket: WebSocket; + try { + socket = new WebSocket(getWSUrl()); + } catch { + scheduleReconnect(); + return; + } + ws = socket; + + socket.onopen = () => { + if (ws !== socket) return; + connected.set(true); + reconnectDelay = 1000; + }; + + socket.onclose = () => { + if (ws !== socket) return; + connected.set(false); + ws = null; + if (shouldReconnect) scheduleReconnect(); + }; + + socket.onerror = () => { + socket.close(); + }; + + socket.onmessage = (event) => { + try { + const data: WSEvent = JSON.parse(event.data); + lastEvent.set(data); + } catch { + // ignore malformed messages + } + }; +} + +function scheduleReconnect() { + setTimeout(() => { + if (shouldReconnect) connect(); + }, reconnectDelay); + reconnectDelay = Math.min(reconnectDelay * 2, MAX_DELAY); +} + +export function startWebSocket() { + shouldReconnect = true; + connect(); +} + +export function stopWebSocket() { + shouldReconnect = false; + ws?.close(); +} diff --git a/dashboard/src/lib/styles/global.css b/dashboard/src/lib/styles/global.css new file mode 100644 index 0000000..7aa9797 --- /dev/null +++ b/dashboard/src/lib/styles/global.css @@ -0,0 +1,82 @@ +@import './tokens.css'; + +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html, body { + height: 100%; + background: var(--bg-base); + color: var(--text-secondary); + font-family: var(--font-body); + font-size: 14px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +a { + color: var(--accent-gold); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +button { + font-family: var(--font-body); + cursor: pointer; + border: none; + background: none; + color: inherit; +} + +input, textarea, select { + font-family: var(--font-body); + font-size: inherit; + color: var(--text-primary); + background: var(--bg-surface); + border: 1px solid var(--border); + border-radius: var(--radius-md); + padding: var(--space-sm) var(--space-md); +} + +input:focus, textarea:focus, select:focus { + outline: none; + border-color: var(--accent-gold); +} + +code { + font-family: var(--font-mono); + font-size: 0.9em; +} + +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: var(--border-hover); + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--border-active); +} + +.mono { + font-family: var(--font-mono); +} + +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/dashboard/src/lib/styles/tokens.css b/dashboard/src/lib/styles/tokens.css new file mode 100644 index 0000000..89f0f57 --- /dev/null +++ b/dashboard/src/lib/styles/tokens.css @@ -0,0 +1,60 @@ +:root { + /* Backgrounds */ + --bg-base: #0c0f14; + --bg-surface: #10131a; + --bg-raised: #14171e; + --bg-overlay: rgba(0, 0, 0, 0.6); + + /* Borders */ + --border: #15181f; + --border-hover: #1e222d; + --border-active: #2a2e38; + + /* Text */ + --text-primary: #e8ecf2; + --text-secondary: #c4c9d4; + --text-muted: #4a5060; + --text-faint: #3a3f4d; + + /* Accent */ + --accent-gold: #d4a843; + --accent-gold-dim: #d4a84333; + --accent-gold-glow: rgba(212, 168, 67, 0.08); + --accent-green: #2ea043; + --accent-green-dim: #1a3a24; + --accent-green-text: #3fb950; + --accent-red: #f85149; + --accent-red-dim: #3a1a1a; + --accent-blue: #5b9fc1; + --accent-blue-dim: #1a2a3a; + --accent-purple: #8b5ec4; + --accent-purple-dim: #2a1a3a; + + /* Typography */ + --font-brand: 'Cinzel', serif; + --font-heading: 'Outfit', sans-serif; + --font-body: 'DM Sans', sans-serif; + --font-mono: 'JetBrains Mono', monospace; + + /* Spacing */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 16px; + --space-lg: 24px; + --space-xl: 32px; + --space-2xl: 48px; + + /* Radius */ + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 8px; + --radius-xl: 12px; + + /* Transitions */ + --transition-fast: 150ms ease; + --transition-normal: 250ms ease; + + /* Sidebar */ + --sidebar-width-collapsed: 56px; + --sidebar-width-expanded: 220px; +} diff --git a/dashboard/src/lib/types.ts b/dashboard/src/lib/types.ts new file mode 100644 index 0000000..f382cef --- /dev/null +++ b/dashboard/src/lib/types.ts @@ -0,0 +1,111 @@ +export interface QuestStatus { + name: string; + worktree: string; + phase: string; + status: string; + gate_pending: boolean; + gate_id: string | null; + lembas_completed: boolean; + metadata_updated: boolean; + errands_done: number; + errands_total: number; +} + +export interface ScoutEntry { + name: string; + question: string; + task_id: string; +} + +export interface CompanyEntry { + name: string; + quests: string[]; + scouts: string[]; +} + +export interface DashboardStatus { + name: string; + quests: QuestStatus[]; + scouts: ScoutEntry[]; + companies: CompanyEntry[]; + poll_interval: number; +} + +export interface QuestHealth { + name: string; + worktree: string; + phase: string; + health: 'working' | 'stalled' | 'zombie' | 'idle' | 'complete'; + gate_pending_sec: number; + has_checkpoint: boolean; + last_activity: string; + action: string; +} + +export interface Tiding { + timestamp: string; + quest: string; + type: string; + phase: string; + detail: string; +} + +export interface Problem { + type: string; + quest: string; + detail: string; + severity: string; +} + +export interface Autopsy { + version: number; + ts: string; + quest: string; + task: string; + phase: string; + trigger: string; + files: string[]; + modules: string[]; + what_failed: string; + resolution: string; + tags: string[]; +} + +export interface Errand { + id: string; + description: string; + status: 'pending' | 'active' | 'done' | 'blocked'; + phase: string; + depends_on: string[]; + created_at: string; + updated_at: string; +} + +export interface QuestErrandList { + version: number; + quest_name: string; + task: string; + items: Errand[]; +} + +export interface QuestTome { + version: number; + quest_name: string; + created_at: string; + updated_at: string; + task: string; + phases_completed: { phase: string; timestamp: string }[]; + gate_history: { phase: string; action: string; timestamp: string; reason?: string }[]; + files_touched: string[]; + respawns: number; + status: string; +} + +export interface Command { + id: string; + action: string; + status: 'pending' | 'completed' | 'failed'; + params: Record; + timestamp: number; + result?: string; +} diff --git a/dashboard/src/routes/+layout.js b/dashboard/src/routes/+layout.js new file mode 100644 index 0000000..ae88a27 --- /dev/null +++ b/dashboard/src/routes/+layout.js @@ -0,0 +1,2 @@ +export const prerender = false; +export const ssr = false; diff --git a/dashboard/src/routes/+layout.svelte b/dashboard/src/routes/+layout.svelte new file mode 100644 index 0000000..23d6842 --- /dev/null +++ b/dashboard/src/routes/+layout.svelte @@ -0,0 +1,14 @@ + + + + Fellowship Dashboard + + + + {@render children()} + diff --git a/dashboard/src/routes/+page.js b/dashboard/src/routes/+page.js new file mode 100644 index 0000000..44d22d8 --- /dev/null +++ b/dashboard/src/routes/+page.js @@ -0,0 +1,5 @@ +import { redirect } from '@sveltejs/kit'; + +export function load() { + redirect(302, '/command'); +} diff --git a/dashboard/src/routes/+page.svelte b/dashboard/src/routes/+page.svelte new file mode 100644 index 0000000..e69de29 diff --git a/dashboard/src/routes/autopsies/+page.svelte b/dashboard/src/routes/autopsies/+page.svelte new file mode 100644 index 0000000..26be213 --- /dev/null +++ b/dashboard/src/routes/autopsies/+page.svelte @@ -0,0 +1,331 @@ + + +
+
+

Autopsies

+ {filtered.length} records +
+ + + +
+ {#if loading} +
Loading autopsies...
+ {:else if loadError} +
Failed to load autopsies. Is the server running?
+ {:else if filtered.length === 0} +
No autopsies found.
+ {:else} + {#each filtered as autopsy, idx} + + {/each} + {/if} +
+
+ + diff --git a/dashboard/src/routes/command/+page.svelte b/dashboard/src/routes/command/+page.svelte new file mode 100644 index 0000000..4602975 --- /dev/null +++ b/dashboard/src/routes/command/+page.svelte @@ -0,0 +1,161 @@ + + + + +
+
+

Command

+
+ +
+ + + + 0 ? 'var(--accent-red)' : 'var(--accent-purple)'} /> +
+ +
+
+ {#if $dashboardStatus} + {#each $dashboardStatus.quests as quest (quest.name)} + + {/each} + {#each $dashboardStatus.scouts as scout (scout.name)} +
+
+ 📡 + {scout.name} +
+

{scout.question}

+
+ {/each} + {:else} +
+

Waiting for fellowship data...

+
+ {/if} +
+ +
+
Herald
+ +
+
+
+ + diff --git a/dashboard/src/routes/config/+page.svelte b/dashboard/src/routes/config/+page.svelte new file mode 100644 index 0000000..c82dabf --- /dev/null +++ b/dashboard/src/routes/config/+page.svelte @@ -0,0 +1,357 @@ + + +
+
+

Config

+
+ + {#if loading} +
Loading configuration...
+ {:else} +
+
+
Settings
+
+ {#each knownKeys as setting} + {@const val = getEffectiveValue(setting.key)} + {@const scope = getScope(setting.key)} +
+
+ {setting.label} + {scope} +
+
+ {#if setting.type === 'boolean'} + + {:else if setting.type === 'text'} + handleText(setting.key, e)} + /> + {:else if setting.type === 'select'} + + {/if} + {#if saveStatus?.key === setting.key} + + {saveStatus.ok ? 'Saved' : 'Error'} + + {/if} +
+
+ {/each} +
+
+ + {#if unknownGlobalKeys().length > 0} +
+
Global Config (raw)
+
{JSON.stringify(
+						Object.fromEntries(unknownGlobalKeys().map((k) => [k, globalConfig[k]])),
+						null,
+						2
+					)}
+
+ {/if} + + {#if unknownProjectKeys().length > 0} +
+
Project Config (raw)
+
{JSON.stringify(
+						Object.fromEntries(unknownProjectKeys().map((k) => [k, projectConfig[k]])),
+						null,
+						2
+					)}
+
+ {/if} +
+ {/if} +
+ + diff --git a/dashboard/src/routes/herald/+page.svelte b/dashboard/src/routes/herald/+page.svelte new file mode 100644 index 0000000..1ad9bdd --- /dev/null +++ b/dashboard/src/routes/herald/+page.svelte @@ -0,0 +1,237 @@ + + +
+
+

Herald

+ {filtered.length} tidings +
+ +
+
+ + + +
+ +
+ {#each eventTypes as etype} + + {/each} +
+
+ +
+ {#if filtered.length > 0} + + {:else} +
+

No tidings match the current filters.

+
+ {/if} +
+
+ + diff --git a/dashboard/src/routes/quest/[id]/+page.svelte b/dashboard/src/routes/quest/[id]/+page.svelte new file mode 100644 index 0000000..a942fbf --- /dev/null +++ b/dashboard/src/routes/quest/[id]/+page.svelte @@ -0,0 +1,373 @@ + + +
+
+ + + {#if quest} +
+

{quest.name}

+ {quest.phase} + {#if quest.gate_pending} + + {/if} + {#if health} + + {health.health} + {/if} +
+ +
+ {#each phases as p} +
+ {p} +
+ {/each} +
+ {/if} +
+ +
+ + + + + +
+ +
+
+ {#if activeTab === 'errands' && errandList} + + {:else if activeTab === 'files' && tomeData} +
+ {#each tomeData.files_touched as file} +
{file}
+ {/each} +
+ {:else if activeTab === 'tome' && tomeData} +
+

Gate History

+ {#each tomeData.gate_history as gate} +
+ {gate.action} + {gate.phase} + {gate.timestamp} +
+ {/each} +
+ {:else if activeTab === 'herald'} + + {:else if activeTab === 'logs'} +
+

Quest logs not yet available. Raw output logging is a future enhancement.

+
+ {:else} +

No data available

+ {/if} +
+ + {#if quest} +
+
+
Metadata
+
+ Branch + {quest.worktree.replace(/\\/g, '/').split('/').pop() || quest.worktree} +
+
+ Worktree + {quest.worktree} +
+
+ Status + {quest.status} +
+ {#if health} +
+ Eagles + {health.health} +
+ {/if} +
+
+ {/if} +
+
+ + diff --git a/dashboard/src/routes/timeline/+page.svelte b/dashboard/src/routes/timeline/+page.svelte new file mode 100644 index 0000000..df6aca3 --- /dev/null +++ b/dashboard/src/routes/timeline/+page.svelte @@ -0,0 +1,92 @@ + + +
+
+

Timeline

+
+ +
+ {#if loading} +
Loading quest timeline data...
+ {:else if tomes.length === 0} +
No quest timeline data available.
+ {:else} + + {/if} +
+
+ + diff --git a/dashboard/static/fonts/cinzel-400.ttf b/dashboard/static/fonts/cinzel-400.ttf new file mode 100644 index 0000000..4213977 Binary files /dev/null and b/dashboard/static/fonts/cinzel-400.ttf differ diff --git a/dashboard/static/fonts/cinzel-600.ttf b/dashboard/static/fonts/cinzel-600.ttf new file mode 100644 index 0000000..1204104 Binary files /dev/null and b/dashboard/static/fonts/cinzel-600.ttf differ diff --git a/dashboard/static/fonts/cinzel-700.ttf b/dashboard/static/fonts/cinzel-700.ttf new file mode 100644 index 0000000..1018a08 Binary files /dev/null and b/dashboard/static/fonts/cinzel-700.ttf differ diff --git a/dashboard/static/fonts/dm-sans-300.ttf b/dashboard/static/fonts/dm-sans-300.ttf new file mode 100644 index 0000000..842166b Binary files /dev/null and b/dashboard/static/fonts/dm-sans-300.ttf differ diff --git a/dashboard/static/fonts/dm-sans-400.ttf b/dashboard/static/fonts/dm-sans-400.ttf new file mode 100644 index 0000000..6c789ea Binary files /dev/null and b/dashboard/static/fonts/dm-sans-400.ttf differ diff --git a/dashboard/static/fonts/dm-sans-500.ttf b/dashboard/static/fonts/dm-sans-500.ttf new file mode 100644 index 0000000..dc44754 Binary files /dev/null and b/dashboard/static/fonts/dm-sans-500.ttf differ diff --git a/dashboard/static/fonts/dm-sans-600.ttf b/dashboard/static/fonts/dm-sans-600.ttf new file mode 100644 index 0000000..ec5dcf3 Binary files /dev/null and b/dashboard/static/fonts/dm-sans-600.ttf differ diff --git a/dashboard/static/fonts/fonts.css b/dashboard/static/fonts/fonts.css new file mode 100644 index 0000000..b23d8f2 --- /dev/null +++ b/dashboard/static/fonts/fonts.css @@ -0,0 +1,105 @@ +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/cinzel-400.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/fonts/cinzel-600.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/fonts/cinzel-700.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(/fonts/dm-sans-300.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/dm-sans-400.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/fonts/dm-sans-500.ttf) format('truetype'); +} +@font-face { + font-family: 'DM Sans'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/fonts/dm-sans-600.ttf) format('truetype'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(/fonts/jetbrains-mono-300.ttf) format('truetype'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/jetbrains-mono-400.ttf) format('truetype'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/fonts/jetbrains-mono-500.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url(/fonts/outfit-300.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(/fonts/outfit-400.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url(/fonts/outfit-500.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(/fonts/outfit-600.ttf) format('truetype'); +} +@font-face { + font-family: 'Outfit'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(/fonts/outfit-700.ttf) format('truetype'); +} diff --git a/dashboard/static/fonts/jetbrains-mono-300.ttf b/dashboard/static/fonts/jetbrains-mono-300.ttf new file mode 100644 index 0000000..333f19c Binary files /dev/null and b/dashboard/static/fonts/jetbrains-mono-300.ttf differ diff --git a/dashboard/static/fonts/jetbrains-mono-400.ttf b/dashboard/static/fonts/jetbrains-mono-400.ttf new file mode 100644 index 0000000..129e882 Binary files /dev/null and b/dashboard/static/fonts/jetbrains-mono-400.ttf differ diff --git a/dashboard/static/fonts/jetbrains-mono-500.ttf b/dashboard/static/fonts/jetbrains-mono-500.ttf new file mode 100644 index 0000000..51ccd91 Binary files /dev/null and b/dashboard/static/fonts/jetbrains-mono-500.ttf differ diff --git a/dashboard/static/fonts/outfit-300.ttf b/dashboard/static/fonts/outfit-300.ttf new file mode 100644 index 0000000..25b080c Binary files /dev/null and b/dashboard/static/fonts/outfit-300.ttf differ diff --git a/dashboard/static/fonts/outfit-400.ttf b/dashboard/static/fonts/outfit-400.ttf new file mode 100644 index 0000000..0b0a0d7 Binary files /dev/null and b/dashboard/static/fonts/outfit-400.ttf differ diff --git a/dashboard/static/fonts/outfit-500.ttf b/dashboard/static/fonts/outfit-500.ttf new file mode 100644 index 0000000..0ba786a Binary files /dev/null and b/dashboard/static/fonts/outfit-500.ttf differ diff --git a/dashboard/static/fonts/outfit-600.ttf b/dashboard/static/fonts/outfit-600.ttf new file mode 100644 index 0000000..52e25bc Binary files /dev/null and b/dashboard/static/fonts/outfit-600.ttf differ diff --git a/dashboard/static/fonts/outfit-700.ttf b/dashboard/static/fonts/outfit-700.ttf new file mode 100644 index 0000000..0389ff2 Binary files /dev/null and b/dashboard/static/fonts/outfit-700.ttf differ diff --git a/dashboard/svelte.config.js b/dashboard/svelte.config.js new file mode 100644 index 0000000..ce73410 --- /dev/null +++ b/dashboard/svelte.config.js @@ -0,0 +1,18 @@ +import adapter from '@sveltejs/adapter-static'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + kit: { + adapter: adapter({ + pages: 'build', + assets: 'build', + fallback: 'index.html', + precompress: false, + strict: false + }) + } +}; + +export default config; diff --git a/dashboard/tsconfig.json b/dashboard/tsconfig.json new file mode 100644 index 0000000..4344710 --- /dev/null +++ b/dashboard/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } +} diff --git a/dashboard/vite.config.ts b/dashboard/vite.config.ts new file mode 100644 index 0000000..1608bba --- /dev/null +++ b/dashboard/vite.config.ts @@ -0,0 +1,15 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + plugins: [sveltekit()], + server: { + proxy: { + '/api': 'http://localhost:3000', + '/ws': { + target: 'ws://localhost:3000', + ws: true + } + } + } +}); diff --git a/plugin/commands/rekindle.md b/plugin/commands/rekindle.md index ff86e98..992438f 100644 --- a/plugin/commands/rekindle.md +++ b/plugin/commands/rekindle.md @@ -23,7 +23,7 @@ Reconstructs fellowship state from on-disk artifacts after a session crash and t Run the CLI to discover fellowship artifacts: ```bash -fellowship status --json +~/.claude/fellowship/bin/fellowship status --json ``` This scans all git worktrees for `.fellowship/quest-state.json` files, checks for checkpoints (`.fellowship/checkpoint.md`), detects merged branches, and reads `.fellowship/fellowship-state.json` from the main repo. @@ -38,7 +38,8 @@ Each quest gets one classification: |---|---|---| | **Complete** | Branch merged into main | Skip — already shipped | | **Resumable** | Has `.fellowship/checkpoint.md` | Continue from current phase with checkpoint context | -| **Stale** | No checkpoint | Restart current phase from scratch | +| **Stale** | No checkpoint, quest-state.json exists | Restart current phase from scratch | +| **Zombie** | No quest-state.json (corrupted/missing) | Write autopsy, clean up worktree | ### Step 3: Present Recovery Dashboard @@ -67,7 +68,7 @@ On user confirmation, transition into Gandalf coordinator mode: 1. **Load config:** Read `~/.claude/fellowship.json` if it exists (same as `/fellowship`) 2. **Create team:** `TeamCreate` with name `fellowship-{timestamp}` 3. **Write fellowship state:** Write `.fellowship/fellowship-state.json` with recovered quest list (same as `/fellowship` startup) -4. **Write autopsies for dead quests:** Before respawning, run `~/.claude/fellowship/bin/fellowship autopsy infer --dir --repo ` for each quest classified as `stale`. This preserves failure knowledge from the crashed session for future quests to learn from. +4. **Write autopsies for dead quests:** Before respawning, run `~/.claude/fellowship/bin/fellowship autopsy infer --dir --repo ` for each quest classified as `stale` or `zombie`. This preserves failure knowledge from the crashed session for future quests to learn from. 5. **For each non-complete quest:** a. `TaskCreate` with the original task description (from `fellowship-state.json` or inferred from quest name) b. Spawn a quest runner teammate with the **resume spawn prompt** (see below) @@ -91,7 +92,7 @@ INSTRUCTIONS: 1. Run /quest to resume this task 2. In Phase 0 (Onboard), detect the RESUME CONTEXT block above and: - Skip worktree creation — you are already in your worktree - - Run `fellowship init` to reset gate state (clears gate_pending, preserves phase) + - Run `~/.claude/fellowship/bin/fellowship init` to reset gate state (clears gate_pending, preserves phase) - Store your worktree path in task metadata: TaskUpdate(taskId: "{task_id}", metadata: {"worktree_path": "{worktree_path}"}) - If checkpoint exists, load .fellowship/checkpoint.md as your initial context - Skip /council — checkpoint replaces orientation @@ -150,7 +151,7 @@ CONTEXT: | Placeholder | Source | |---|---| -| `{worktree_path}` | From `fellowship status --json` output | +| `{worktree_path}` | From `~/.claude/fellowship/bin/fellowship status --json` output | | `{phase}` | From quest state file | | `{classification}` | "resumable" or "stale" | diff --git a/plugin/skills/fellowship/SKILL.md b/plugin/skills/fellowship/SKILL.md index d987190..c7d730a 100644 --- a/plugin/skills/fellowship/SKILL.md +++ b/plugin/skills/fellowship/SKILL.md @@ -196,7 +196,7 @@ When the user says "wrap up" or "disband": 1. Send `shutdown_request` to all active teammates (including palantir) 2. Synthesize a summary: quests completed, PR URLs, any open items -3. **Clear the bulletin board:** Run `fellowship bulletin clear` to remove ephemeral discoveries +3. **Clear the bulletin board:** Run `~/.claude/fellowship/bin/fellowship bulletin clear` to remove ephemeral discoveries 4. **Suggest retrospective (optional):** Mention to the user: "Consider running `/retro` for a retrospective analysis of this fellowship — it identifies patterns across quests and can recommend configuration improvements." This is a suggestion only — the user can skip it and proceed directly to cleanup. 5. Run `TeamDelete` to clean up @@ -263,7 +263,7 @@ Keep it brief — one line, not a monologue. Functional information always comes - **Quest fails:** Report to user with context (which phase, what went wrong). Before respawning, write an autopsy to preserve failure knowledge for future quests: ```bash - fellowship autopsy infer --dir --repo + ~/.claude/fellowship/bin/fellowship autopsy infer --dir --repo ``` This reconstructs a best-effort failure record from the quest's tome, herald, and eagles data. Then offer to respawn. Worktree is preserved. - **Respawn procedure:** Spawn a new teammate with the same task description, but add to the spawn prompt: `"You are resuming a failed quest. Your working directory is already set to the existing worktree at {worktree_path}. Skip worktree creation in quest Phase 0 — you're already isolated. Check .fellowship/checkpoint.md for a checkpoint from the previous attempt."` Set the new teammate's working directory to the failed quest's worktree path. diff --git a/site/src/lib/styles/theme.css b/site/src/lib/styles/theme.css index 5917cdb..577c642 100644 --- a/site/src/lib/styles/theme.css +++ b/site/src/lib/styles/theme.css @@ -39,17 +39,17 @@ --color-text: #3d2b1f; --color-text-secondary: #5a4a3a; --color-heading: #6b4c1e; - --color-accent: #8b6914; - --color-accent-hover: #a07a1a; + --color-accent: #7a5a0e; + --color-accent-hover: #8b6914; --color-border: #d4c4a0; --color-code-bg: #efe3c0; --color-link: #6b4c1e; - --color-link-hover: #8b6914; - --color-focus: #8b6914; + --color-link-hover: #7a5a0e; + --color-focus: #7a5a0e; --color-surface: #fff8e7; --color-error-bg: rgba(139, 37, 0, 0.08); - --color-scout: #4a8a9e; - --color-monitor: #7b6ea4; + --color-scout: #377080; + --color-monitor: #635599; } @media (prefers-reduced-motion: reduce) {