Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .kiro/docs/architecture-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,29 @@ unic init --force # Overwrite existing config file
|---------|---------|--------|
| EC2 | SSM Session Manager (connect to EC2 instances) | ✅ Implemented |
| VPC | VPC Browser (VPCs → subnets → available IPs) | ✅ Implemented |
| RDS | ListDBInstances | 🚧 Coming Soon |
| RDS | RDS Browser (list, detail, start/stop/failover) | ✅ Implemented |
| Route53 | ListHostedZones | 🚧 Coming Soon |
| IAM | ListUsers | 🚧 Coming Soon |

## Planned Improvements

### M5 — UI Beautification (Charmbracelet Ecosystem)

- **File extraction**: Split `internal/app/app.go` (~1700 lines) into `styles.go`, `views.go`, `commands.go`, `filter.go`
- **bubbles components**: Add `bubbles/textinput` (filter input), `bubbles/spinner` (loading), `bubbles/table` (context picker)
- **Enhanced styles**: Bordered list views, full-width status bar, consistent label alignment, styled help bar
- Dependency: `github.com/charmbracelet/bubbles`

### M6 — Search/Filter for Long Lists

- **Fuzzy matching**: Replace `strings.Contains` with `sahilm/fuzzy` for scored fuzzy search
- **Match highlighting**: Bold + orange on matched characters in list items
- **Universal filter**: Add "/" filter to all list views (VPC list and subnet list currently missing)
- **Unified architecture**: `Filterable` interface + generic `applyFuzzyFilter[T]()` to eliminate per-screen duplication
- Dependency: `github.com/sahilm/fuzzy`

See `PLAN.md` for full milestone details and implementation order.

## New Feature Addition Checklist

1. `internal/domain/model.go` → Add `AwsService` and `FeatureKind` string constants
Expand Down
21 changes: 20 additions & 1 deletion .kiro/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,29 @@ unic init --force # 기존 설정 파일 덮어쓰기
|--------|------|------|
| EC2 | SSM Session Manager (EC2 인스턴스 접속) | ✅ 구현 완료 |
| VPC | VPC Browser (VPC → 서브넷 → 가용 IP) | ✅ 구현 완료 |
| RDS | ListDBInstances | 🚧 Coming Soon |
| RDS | RDS Browser (목록, 상세, 시작/중지/장애조치) | ✅ 구현 완료 |
| Route53 | ListHostedZones | 🚧 Coming Soon |
| IAM | ListUsers | 🚧 Coming Soon |

## 계획된 개선 사항

### M5 — UI 개선 (Charmbracelet 생태계)

- **파일 분리**: `internal/app/app.go` (~1700줄)를 `styles.go`, `views.go`, `commands.go`, `filter.go`로 분리
- **bubbles 컴포넌트**: `bubbles/textinput` (필터 입력), `bubbles/spinner` (로딩), `bubbles/table` (컨텍스트 선택기) 추가
- **스타일 강화**: 테두리가 있는 목록 뷰, 전체 너비 상태 바, 일관된 레이블 정렬, 스타일 적용된 도움말 바
- 의존성: `github.com/charmbracelet/bubbles`

### M6 — 긴 목록 검색/필터

- **퍼지 매칭**: `strings.Contains`를 `sahilm/fuzzy`로 교체하여 점수 기반 퍼지 검색 구현
- **매칭 하이라이트**: 매칭된 문자에 굵은체 + 주황색 스타일 적용
- **전체 필터 지원**: 모든 목록 뷰에 "/" 필터 추가 (현재 VPC 목록, 서브넷 목록에 미지원)
- **통합 아키텍처**: `Filterable` 인터페이스 + 제네릭 `applyFuzzyFilter[T]()` 로 화면별 중복 제거
- 의존성: `github.com/sahilm/fuzzy`

자세한 마일스톤 및 구현 순서는 `PLAN.md` 참조.

## 새 기능 추가 체크리스트

1. `internal/domain/model.go` → `AwsService`, `FeatureKind` 문자열 상수 추가
Expand Down
5 changes: 3 additions & 2 deletions .kiro/steering/project-overview-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ UNIC is a Go-based TUI (Terminal User Interface) tool for browsing and managing
## Tech Stack

- Language: Go (1.22+)
- TUI Framework: Bubbletea + Lipgloss + Bubbles
- TUI Framework: Bubbletea + Lipgloss + Bubbles (planned: bubbles/textinput, bubbles/spinner, bubbles/table)
- Search: sahilm/fuzzy (planned — M6 fuzzy search/filter)
- CLI Parser: Cobra
- AWS SDK: aws-sdk-go-v2 (ec2, ssm, sts)
- AWS SDK: aws-sdk-go-v2 (ec2, rds, ssm, sts, sso, ssooidc)
- Config: gopkg.in/yaml.v3 (YAML-based)
- Concurrency: goroutines + errgroup
- Error Handling: fmt.Errorf wrapping / standard errors package
Expand Down
5 changes: 3 additions & 2 deletions .kiro/steering/project-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ UNIC은 Go 기반 TUI(Terminal User Interface) 도구로, AWS 리소스를 탐
## 기술 스택

- 언어: Go (1.22+)
- TUI 프레임워크: Bubbletea + Lipgloss + Bubbles
- TUI 프레임워크: Bubbletea + Lipgloss + Bubbles (계획: bubbles/textinput, bubbles/spinner, bubbles/table)
- 검색: sahilm/fuzzy (계획 — M6 퍼지 검색/필터)
- CLI 파서: Cobra
- AWS SDK: aws-sdk-go-v2 (ec2, ssm, sts)
- AWS SDK: aws-sdk-go-v2 (ec2, rds, ssm, sts, sso, ssooidc)
- 설정 파일: gopkg.in/yaml.v3 (YAML 기반)
- 동시성: goroutines + errgroup
- 에러 처리: fmt.Errorf 래핑 / 표준 errors 패키지
Expand Down
74 changes: 71 additions & 3 deletions PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ unic/

**M4.1 — UX**
- Keyboard shortcut help screen (`?` key)
- Fuzzy search/filter on all list views
- Loading spinners for async operations
- Color theme (respect terminal colors via Lipgloss)
- ~~Fuzzy search/filter on all list views~~ → moved to M6
- ~~Loading spinners for async operations~~ → moved to M5.3

**M4.2 — Error Handling & Logging**
- Structured error messages with actionable hints
Expand All @@ -176,6 +176,66 @@ unic/

---

### M5 — UI Beautification (Charmbracelet Ecosystem)

Prerequisite: `go get github.com/charmbracelet/bubbles`

**M5.1 — File Extraction (no behavior change)**
- Split `internal/app/app.go` (~1700 lines) into focused files:
- `styles.go` — all lipgloss style vars + new styles
- `views.go` — all `view*()` methods + `renderStatusBar()`
- `commands.go` — all `tea.Cmd` functions (`load*`, `execute*`, `poll*`, etc.)
- `filter.go` — filter logic (`applyFilter`, `applyRDSFilter`, `applyIPFilter`)
- `app.go` retains: Model struct, `New()`, `Init()`, `Update()`, and all `update*()` methods

**M5.2 — bubbles/textinput for Filter**
- Replace manual character-by-character filter input with a single shared `textinput.Model`
- On "/" key → `filterTI.Focus()`, on esc/enter → `filterTI.Blur()`
- Check `filterTI.Focused()` instead of `filterActive` booleans
- Remove: `filterInput`, `filterActive`, `rdsFilter`, `rdsFilterActive`, `ipFilter`, `ipFilterActive`

**M5.3 — bubbles/spinner for Loading**
- Replace static `"Loading..."` with animated spinner (`spinner.MiniDot`)
- Start spinner tick on entering `screenLoading`, ignore ticks elsewhere

**M5.4 — bubbles/table for Context Picker**
- Convert manual column-aligned context picker to `bubbles/table`
- Columns: Name, Region, Auth, Current (*)
- Keep "a" key shortcut for adding contexts

**M5.5 — Enhanced Lipgloss Styles**
- Status bar: full-width via `lipgloss.Width(m.width)`, left/right split with `JoinHorizontal`
- List views: wrap content in `lipgloss.RoundedBorder()` box
- Detail views: consistent label alignment with `lipgloss.NewStyle().Width(14)`
- Help bar: consistent `helpStyle` across all screens

---

### M6 — Search/Filter for Long Lists

Prerequisite: `go get github.com/sahilm/fuzzy`

**M6.1 — Fuzzy Matching**
- Replace `strings.Contains` filter logic with `sahilm/fuzzy` scored fuzzy matching
- Match against `DisplayTitle()` for both filtering and highlighting
- Sort results by score descending

**M6.2 — Match Highlighting**
- Highlight matched characters with bold + orange (color 214) style
- Use match indices from fuzzy library to render per-character styling

**M6.3 — Filter on All List Views**
- Add "/" filter to VPC list and subnet list (currently missing)
- All filterable items already implement `FilterText()` and `DisplayTitle()`

**M6.4 — Unified Filter Architecture**
- Define `Filterable` interface: `FilterText() string`, `DisplayTitle() string`
- Implement generic `applyFuzzyFilter[T Filterable](items []T, query string) []filterMatch[T]`
- Store `matchIndices [][]int` parallel to filtered slices for highlighting
- Eliminate per-screen filter state duplication

---

## Implementation Order

```
Expand All @@ -184,12 +244,20 @@ M1.1 → M1.2 → M2.1 → M2.2 → M2.3 → M2.4
M3.1 ~ M3.8 (independent, any order)
M4.1 → M4.2 → M4.3
M5.1 → M5.2 ~ M5.5
M6.1 ~ M6.4
```

- M1 is complete; M2 is partially complete (SSO, credential, assume role done; Okta deferred)
Note: M5.2 (textinput) provides the foundation for M6 (enhanced search) — they converge naturally.

- M1 is complete; M2 is deferred (relying on AWS SDK default credential chain)
- M2.1 (Context-based auth with SSO, credential, assume-role) is complete
- M3 services are independent of each other, build in any order
- M3.1 (VPC), M3.2 (RDS), and M3.4 (SSM Sessions) are complete
- M4.3 (Distribution) is partially done (GoReleaser + GitHub Actions)
- M5 and M6 can begin independently of remaining M3/M4 work

---

Expand Down
Loading