Files
devops-tui/SPEC.md
T
Samuel Enocsson 2555afce19 Initial commit: Azure DevOps TUI client
A terminal-based user interface for browsing and managing Azure DevOps
work items. Features include:

- Browse work items with filtering by area, iteration, state, and type
- View work item details with markdown rendering
- Open work items in browser
- Create git branches from work items
- Update work item state
- Keyboard-driven navigation

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 09:56:11 +01:00

448 lines
18 KiB
Markdown

# devops-tui - MVP Specifikation
> En terminal user interface (TUI) för Azure DevOps Boards, inspirerad av [jira-cli](https://github.com/ankitpokhrel/jira-cli) och [JiraTUI](https://jiratui.sh/).
## Översikt
**devops-tui** är ett terminalbaserat verktyg för att navigera och granska Azure DevOps work items direkt från kommandoraden. MVP:n fokuserar på read-only boards-funktionalitet med en panel-baserad layout inspirerad av Lazygit.
### Mål
- Snabb överblick av work items utan att lämna terminalen
- Vim-inspirerad navigation för effektivt arbetsflöde
- Enkel installation via single binary (Go)
### Avgränsningar (MVP)
| Inkluderat | Exkluderat |
|------------|------------|
| Boards (work items) | Pipelines/Builds |
| Read-only visning | Skapa/redigera items |
| Fasta filter (Sprint/State/Assigned) | WIQL-queries |
| Ett konfigurerat projekt | Projekt-switcher |
| Personal Access Token auth | OAuth/SSO |
---
## Tech Stack
```
┌─────────────────────────────────────────┐
│ devops-tui │
├─────────────────────────────────────────┤
│ UI Layer │
│ ├─ Bubble Tea (TUI framework) │
│ ├─ Bubbles (komponenter) │
│ └─ Lip Gloss (styling) │
├─────────────────────────────────────────┤
│ Data Layer │
│ ├─ Azure DevOps REST API v7.1 │
│ └─ HTTP client (net/http) │
├─────────────────────────────────────────┤
│ Config │
│ ├─ Viper (konfiguration) │
│ └─ YAML config file │
└─────────────────────────────────────────┘
```
### Varför Go + Bubble Tea?
1. **Single binary** - Enkel distribution, inga runtime-beroenden
2. **Cross-platform** - Windows, macOS, Linux utan extra arbete
3. **Beprövat** - Används av GitHub CLI, lazygit, och jira-cli
4. **Bra ekosystem** - Charm.sh har kompletterande bibliotek
### Dependencies
```go
require (
github.com/charmbracelet/bubbletea // TUI framework
github.com/charmbracelet/bubbles // UI komponenter
github.com/charmbracelet/lipgloss // Styling
github.com/spf13/viper // Konfiguration
)
```
---
## UI Design
### Layout (3-panel)
```
┌─ devops-tui ──────────────────────────────────────────────────┐
│ │
│ ┌─ FILTER ──────────┐ ┌─ WORK ITEMS ────────────────────────┐ │
│ │ │ │ │ │
│ │ Sprint │ │ ID TYPE STATE TITLE │ │
│ │ ───────────── │ │ ───────────────────────────────── │ │
│ │ ▸ Sprint 42 │ │ #1234 Story Active Implement │ │
│ │ Sprint 41 │ │▸ #1235 Task Active Create lo │ │
│ │ Sprint 40 │ │ #1236 Task New Add JWT m │ │
│ │ Backlog │ │ #1237 Bug Active Fix token │ │
│ │ │ │ #1238 Task Resolved Setup CI │ │
│ ├───────────────────┤ │ │ │
│ │ State │ │ │ │
│ │ ───────────── │ │ │ │
│ │ ● All │ │ │ │
│ │ ○ New │ └─────────────────────────────────────┘ │
│ │ ○ Active │ ┌─ DETAILS ───────────────────────────┐ │
│ │ ○ Resolved │ │ │ │
│ │ ○ Closed │ │ #1235 Create login component │ │
│ ├───────────────────┤ │ │ │
│ │ Assigned │ │ Type: Task State: Active │ │
│ │ ───────────── │ │ Assigned: Samuel Sprint: 42 │ │
│ │ ● All │ │ Area: Frontend Priority: 2 │ │
│ │ ○ Me │ │ │ │
│ │ │ │ Parent: #1234 Implement auth flow │ │
│ └───────────────────┘ │ │ │
│ │ ─── Description ─── │ │
│ │ Create a React login component │ │
│ │ with email/password fields... │ │
│ │ │ │
│ │ ─── Tags ─── │ │
│ │ frontend · react · auth │ │
│ │ │ │
│ └─────────────────────────────────────┘ │
│ │
├───────────────────────────────────────────────────────────────┤
│ Tab Panel j/k Navigate g/G Top/Bottom Enter Open ? Help │
└───────────────────────────────────────────────────────────────┘
```
### Paneler
| Panel | Bredd | Innehåll | Interaktion |
|-------|-------|----------|-------------|
| **Filter** | ~20% | Sprint, State, Assigned filter | Välj filter med Enter/Space |
| **Work Items** | ~80% (topp) | Tabell med work items | Navigera med j/k, öppna med Enter |
| **Details** | ~80% (botten) | Detaljer för valt item | Automatiskt uppdaterad |
### Fullskärms-detaljvy
När användaren trycker `v` på ett work item:
```
┌─ #1235 Create login component ────────────────────────────────┐
│ │
│ ┌─ METADATA ───────────────────────────────────────────────┐ │
│ │ │ │
│ │ Type: Task ID: #1235 │ │
│ │ State: Active Created: 2024-01-15 │ │
│ │ Assigned: Samuel Enocsson Updated: 2024-01-18 │ │
│ │ Sprint: Sprint 42 Priority: 2 │ │
│ │ Area: Frontend │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ PARENT ─────────────────────────────────────────────────┐ │
│ │ #1234 User Story: Implement authentication flow │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ DESCRIPTION ────────────────────────────────────────────┐ │
│ │ │ │
│ │ Create a React login component with the following: │ │
│ │ │ │
│ │ - Email input field with validation │ │
│ │ - Password input field │ │
│ │ - "Remember me" checkbox │ │
│ │ - Submit button with loading state │ │
│ │ - Error message display │ │
│ │ │ │
│ │ The component should follow our design system and │ │
│ │ integrate with the existing auth context. │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ TAGS ───────────────────────────────────────────────────┐ │
│ │ frontend · react · auth · ui │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
├───────────────────────────────────────────────────────────────┤
│ Esc Back Enter Open in browser j/k Scroll │
└───────────────────────────────────────────────────────────────┘
```
---
## Keyboard Shortcuts
### Globala
| Key | Beskrivning |
|-----|-------------|
| `Tab` | Byt till nästa panel |
| `Shift+Tab` | Byt till föregående panel |
| `?` | Visa/dölj hjälp |
| `Ctrl+r` | Ladda om data |
| `q` / `Ctrl+c` | Avsluta |
### Filter-panel
| Key | Beskrivning |
|-----|-------------|
| `j` / `↓` | Nästa filter/val |
| `k` / `↑` | Föregående filter/val |
| `Enter` / `Space` | Välj filter |
| `g` | Gå till första |
| `G` | Gå till sista |
### Work Items-panel
| Key | Beskrivning |
|-----|-------------|
| `j` / `↓` | Nästa work item |
| `k` / `↑` | Föregående work item |
| `g` | Gå till första |
| `G` | Gå till sista |
| `Enter` | Öppna i webbläsare |
| `v` | Visa fullskärms-detaljer |
| `/` | Sök (filter by text) |
### Detaljvy (fullskärm)
| Key | Beskrivning |
|-----|-------------|
| `Esc` / `q` | Tillbaka till huvudvy |
| `Enter` | Öppna i webbläsare |
| `j` / `k` | Scrolla beskrivning |
---
## Konfiguration
### Config-fil
Placering: `~/.config/devops-tui/config.yaml`
```yaml
# Azure DevOps-anslutning
organization: "my-organization"
project: "my-project"
# Autentisering
# PAT kan anges här eller via miljövariabel AZURE_DEVOPS_PAT
pat: ""
# UI-inställningar
theme: "default" # default, dark, light
# Standardfilter vid uppstart
defaults:
sprint: "current" # "current", "all", eller specifikt namn
state: "all" # "all", "new", "active", "resolved", "closed"
assigned: "me" # "all", "me"
```
### Miljövariabler
| Variabel | Beskrivning |
|----------|-------------|
| `AZURE_DEVOPS_PAT` | Personal Access Token (rekommenderat) |
| `AZURE_DEVOPS_ORG` | Organisation (override config) |
| `AZURE_DEVOPS_PROJECT` | Projekt (override config) |
### PAT-behörigheter
Personal Access Token behöver följande scope:
- `Work Items (Read)` - Läsa work items
- `Project and Team (Read)` - Lista sprints/iterationer
---
## Azure DevOps API
### Endpoints som används
```
Base URL: https://dev.azure.com/{organization}/{project}/_apis
Work Items:
GET /wit/wiql # Kör WIQL-query
GET /wit/workitems/{id} # Hämta enskilt work item
GET /wit/workitems?ids={ids} # Hämta flera work items
Iterationer (Sprints):
GET /work/teamsettings/iterations # Lista iterationer
Team:
GET /teams # Lista teams
```
### WIQL-queries
För att hämta work items använder vi WIQL (Work Item Query Language):
```sql
-- Alla items i current sprint, tilldelade mig
SELECT [System.Id], [System.Title], [System.State], [System.WorkItemType]
FROM WorkItems
WHERE [System.TeamProject] = @project
AND [System.IterationPath] = @currentIteration
AND [System.AssignedTo] = @me
ORDER BY [System.ChangedDate] DESC
-- Alla aktiva items
SELECT [System.Id], [System.Title], [System.State], [System.WorkItemType]
FROM WorkItems
WHERE [System.TeamProject] = @project
AND [System.State] = 'Active'
ORDER BY [System.ChangedDate] DESC
```
### Response-struktur (Work Item)
```json
{
"id": 1235,
"rev": 5,
"fields": {
"System.Id": 1235,
"System.Title": "Create login component",
"System.State": "Active",
"System.WorkItemType": "Task",
"System.AssignedTo": {
"displayName": "Samuel Enocsson",
"uniqueName": "samuel@example.com"
},
"System.IterationPath": "MyProject\\Sprint 42",
"System.AreaPath": "MyProject\\Frontend",
"System.Description": "<div>Create a React login...</div>",
"System.Tags": "frontend; react; auth",
"System.Parent": 1234,
"Microsoft.VSTS.Common.Priority": 2,
"System.CreatedDate": "2024-01-15T10:00:00Z",
"System.ChangedDate": "2024-01-18T14:30:00Z"
},
"url": "https://dev.azure.com/org/project/_apis/wit/workItems/1235"
}
```
---
## Projektstruktur
```
devops-tui/
├── main.go # Entry point
├── go.mod
├── go.sum
├── README.md
├── SPEC.md # Denna fil
├── cmd/
│ └── root.go # CLI setup (cobra om vi vill ha subcommands)
├── internal/
│ ├── config/
│ │ └── config.go # Viper config loading
│ │
│ ├── api/
│ │ ├── client.go # Azure DevOps HTTP client
│ │ ├── workitems.go # Work item queries
│ │ └── iterations.go # Sprint/iteration queries
│ │
│ ├── ui/
│ │ ├── app.go # Bubble Tea main model
│ │ ├── styles.go # Lip Gloss styles
│ │ ├── keys.go # Keyboard bindings
│ │ │
│ │ ├── components/
│ │ │ ├── filter.go # Filter panel
│ │ │ ├── workitems.go # Work items list
│ │ │ ├── details.go # Details panel
│ │ │ ├── detailview.go # Fullscreen detail view
│ │ │ └── help.go # Help overlay
│ │ │
│ │ └── views/
│ │ ├── main.go # Main 3-panel view
│ │ └── detail.go # Fullscreen detail view
│ │
│ └── models/
│ ├── workitem.go # Work item domain model
│ ├── iteration.go # Sprint/iteration model
│ └── filter.go # Filter state model
└── pkg/
└── browser/
└── open.go # Cross-platform browser open
```
---
## Implementation - Milstolpar
### Fas 1: Grundstruktur
- [ ] Initiera Go-modul
- [ ] Sätt upp projektstruktur
- [ ] Konfigurera Bubble Tea scaffold
- [ ] Implementera config-laddning (Viper)
### Fas 2: Azure DevOps API
- [ ] HTTP-klient med PAT-auth
- [ ] Hämta iterationer (sprints)
- [ ] Kör WIQL-queries
- [ ] Hämta work items med detaljer
### Fas 3: UI - Paneler
- [ ] Filter-panel (sprint, state, assigned)
- [ ] Work items-lista med tabell
- [ ] Details-panel med preview
- [ ] Panel-navigation (Tab)
### Fas 4: UI - Interaktion
- [ ] Vim-navigation (j/k/g/G)
- [ ] Filter-val påverkar work items
- [ ] Öppna i browser (Enter)
- [ ] Fullskärms-detaljvy (v)
### Fas 5: Polish
- [ ] Hjälp-overlay (?)
- [ ] Refresh (Ctrl+r)
- [ ] Felhantering och loading states
- [ ] Färgtema och styling
---
## Framtida features (post-MVP)
Dessa features är medvetet exkluderade från MVP men kan läggas till senare:
### Prioritet 1 (nästa iteration)
- [ ] Pipelines/Builds-vy
- [ ] Pull Requests-vy
- [ ] Projekt-switcher
### Prioritet 2
- [ ] Skapa work items
- [ ] Redigera work items (state, assigned)
- [ ] WIQL query editor
- [ ] Kommentarer
### Prioritet 3
- [ ] Kanban board-vy
- [ ] Notifications
- [ ] Offline cache
- [ ] Themes (dark/light/custom)
---
## Referenser
### Inspiration
- [jira-cli](https://github.com/ankitpokhrel/jira-cli) - Go/Bubble Tea, tabellbaserad
- [JiraTUI](https://jiratui.sh/) - Python/Textual, panel-baserad
- [lazygit](https://github.com/jesseduffield/lazygit) - Go/gocui, panel-layout
- [k9s](https://github.com/derailed/k9s) - Go/tview, Kubernetes TUI
### Dokumentation
- [Bubble Tea](https://github.com/charmbracelet/bubbletea)
- [Bubbles](https://github.com/charmbracelet/bubbles)
- [Lip Gloss](https://github.com/charmbracelet/lipgloss)
- [Azure DevOps REST API](https://learn.microsoft.com/en-us/rest/api/azure/devops/)
- [WIQL Syntax](https://learn.microsoft.com/en-us/azure/devops/boards/queries/wiql-syntax)
### Azure DevOps Go Libraries
- [microsoft/azure-devops-go-api](https://github.com/microsoft/azure-devops-go-api) - Officiellt men begränsat
- REST API direkt rekommenderas för enklare implementation