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

18 KiB

devops-tui - MVP Specifikation

En terminal user interface (TUI) för Azure DevOps Boards, inspirerad av jira-cli och JiraTUI.

Ö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

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

# 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):

-- 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)

{
  "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 - Go/Bubble Tea, tabellbaserad
  • JiraTUI - Python/Textual, panel-baserad
  • lazygit - Go/gocui, panel-layout
  • k9s - Go/tview, Kubernetes TUI

Dokumentation

Azure DevOps Go Libraries