Conversation
abennett
commented
Feb 7, 2026
- implement a table command
- add tests and update docs for table/add commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an interactive Bubble Tea “table” dashboard command and refactors status/impact parsing into strongly-typed enums, with accompanying tests and documentation updates.
Changes:
- Introduces a Bubble Tea TUI (
ruok table) that concurrently fetches all services and supports drill-down detail view. - Adds
Status/Impactenum types with JSON unmarshaling, plus tests for parsing and summarization logic. - Updates CLI output and README docs to reflect new commands and typed status handling.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tui.go | New Bubble Tea interactive table/dashboard implementation + summarize helper |
| tui_test.go | Unit tests for summarize behavior (counts, skipping rules, worst severity) |
| cli.go | Adds table command and updates printing for typed Status/Impact |
| status.go | Introduces Status enum + JSON unmarshaling + string/name helpers |
| status_test.go | Tests for Status JSON parsing, emoji rendering, and ordering |
| impact.go | Introduces Impact enum + JSON unmarshaling + string/name helpers |
| impact_test.go | Tests for Impact JSON parsing, emoji rendering, and ordering |
| statuspage.go | Removes old icon helpers; switches component/incident fields to typed enums |
| statuspage_test.go | Adds HTTP server tests for components/incidents + config/service resolution |
| registry.go | Removes atlassian built-in entry |
| go.mod | Adds Bubble Tea / Bubbles / Lipgloss dependencies |
| README.md | Documents table and add commands; updates examples accordingly |
| CLAUDE.md | Repo guidance and architecture notes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| cmds = append(cmds, func() tea.Msg { | ||
| sp := StatusPage{ | ||
| URL: r.url, | ||
| Client: &http.Client{Timeout: 10 * time.Second}, | ||
| } | ||
| cmps, err := sp.Components() | ||
| return serviceResult{name: r.name, components: cmps, err: err} |
There was a problem hiding this comment.
This appends commands that close over the r range variable. In Go, the range variable is reused across iterations, so all commands can end up using the last row's values (wrong URL/name). Fix by capturing the loop value inside the loop (e.g., assign r := r before creating the closure, or index the slice and capture m.rows[i]).
| cmds = append(cmds, func() tea.Msg { | |
| sp := StatusPage{ | |
| URL: r.url, | |
| Client: &http.Client{Timeout: 10 * time.Second}, | |
| } | |
| cmps, err := sp.Components() | |
| return serviceResult{name: r.name, components: cmps, err: err} | |
| row := r | |
| cmds = append(cmds, func() tea.Msg { | |
| sp := StatusPage{ | |
| URL: row.url, | |
| Client: &http.Client{Timeout: 10 * time.Second}, | |
| } | |
| cmps, err := sp.Components() | |
| return serviceResult{name: row.name, components: cmps, err: err} |
status.go
Outdated
| case "partial_outage": | ||
| *s = StatusPartial | ||
| case "major_outage": | ||
| *s = StatusCritical |
There was a problem hiding this comment.
StatusMajor is defined (and Status.Name() maps it to major_outage), but UnmarshalJSON maps major_outage to StatusCritical. That makes StatusMajor effectively unreachable for component statuses and will display major outages as 🔴 instead of 🟠. Consider mapping major_outage to StatusMajor, and keeping critical (if desired) mapped to StatusCritical.
| *s = StatusCritical | |
| *s = StatusMajor |