Skip to content

Commit 0e070ac

Browse files
arimxyerclaude
andcommitted
Remove direct golang.org/x/term usage, update CLAUDE.md
Tidy go.mod (x/term kept as indirect dep of bubbletea). Update CLAUDE.md to reflect multi-file Charm architecture. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4298ff5 commit 0e070ac

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

CLAUDE.md

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,42 @@ Releases are handled by GoReleaser via GitHub Actions on version tags (`v*`). Th
1414

1515
## Architecture
1616

17-
This is a single-file Go CLI (`main.go`, no external dependencies) that fetches changelogs for AI coding assistants from the GitHub Releases API.
17+
Go CLI split across multiple files, using the Charm ecosystem (lipgloss, bubbletea, glamour) for terminal UI. Fetches changelogs for AI coding assistants from the GitHub Releases API.
1818

19-
### Core Data Model
19+
### File Structure
2020

21-
- **`Source`** — defines a tracked tool (display name, GitHub owner/repo, binary names for local detection, version args). All sources are registered in the `sources` map.
22-
- **`ChangelogEntry`** — a parsed release with version, date, sectioned changes, and ungrouped changes.
23-
- **`Section`** — a named group of changes within a release (parsed from markdown headers in release bodies).
21+
| File | Purpose |
22+
|------|---------|
23+
| `main.go` | Entry point, arg parsing, `printUsage()` |
24+
| `sources.go` | `Source` type, `sources` map, config (load/save/XDG), `enabledSources()` |
25+
| `fetch.go` | `ChangelogEntry`/`Section` types, `fetchGitHubReleases()`, `parseReleaseBody()` |
26+
| `output.go` | Output formatters: `outputJSON()`, `outputMarkdown()`, `outputPlainText()`, `outputRendered()` (glamour) |
27+
| `status.go` | `runStatusCommand()` — lipgloss table with concurrent fetch + install detection |
28+
| `latest.go` | `runLatestCommand()` — concurrent fetch, 24h filter |
29+
| `config.go` | `runConfigCommand()` — bubbletea interactive source picker |
30+
| `helpers.go` | `formatRelativeTime()`, `calculateAvgReleaseFreq()`, `openBrowser()`, `truncateString()` |
2431

25-
### Key Functions
32+
### Charm Libraries
2633

27-
- **`fetchGitHubReleases(owner, repo)`** — single GitHub API integration point; all sources use this.
28-
- **`parseReleaseBody(body)`** — converts markdown release notes into structured `Section`/changes. Skips "What's Changed" headers and `@`-prefixed lines (contributor mentions).
29-
- **`Source.DetectInstalled(ctx)`** — checks if a tool is locally installed via `exec.LookPath` + version command with 3s timeout.
34+
- **Lipgloss** (`lipgloss/table`) — styled status table in `status.go`
35+
- **Glamour** — markdown rendering for changelogs in `output.go` (`outputRendered`). Auto-detects TTY; falls back to plain text when piped.
36+
- **Bubbletea** — interactive config picker in `config.go` (Model/Update/View pattern)
37+
38+
### Key Data Flow
39+
40+
- All sources use `fetchGitHubReleases(owner, repo)` → GitHub Releases API
41+
- `ChangelogEntry.RawBody` stores the raw markdown for glamour rendering (excluded from JSON via `json:"-"`)
42+
- `parseReleaseBody()` creates structured `Sections`/`Changes` for JSON output
43+
- User config at `~/.config/aic/config.json` (XDG-aware) stores disabled sources
3044

3145
### Commands
3246

33-
The CLI uses manual arg parsing (no framework). Three command paths:
47+
Manual arg parsing (no framework). Four command paths:
3448
1. **`aic <source> [flags]`** — fetch changelog for a specific source
35-
2. **`aic latest`** — all releases from last 24h across all sources (concurrent fetching)
36-
3. **`aic status`** — table view with versions, recency, installed status, release frequency (concurrent fetching + detection)
49+
2. **`aic latest`** — all releases from last 24h across enabled sources (concurrent)
50+
3. **`aic status`** — table view with versions, recency, installed status, release frequency
51+
4. **`aic config`** — interactive picker to enable/disable sources
3752

3853
### Adding a New Source
3954

40-
Add an entry to the `sources` map in `main.go`. All sources use the same `fetchGitHubReleases` path, so only the GitHub owner/repo and binary detection info are needed. Update `printUsage()` to include the new source.
55+
Add an entry to the `sources` map in `sources.go`. All sources use `fetchGitHubReleases`, so only GitHub owner/repo and binary detection info are needed. Update `printUsage()` in `main.go` and the README table.

go.mod

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ module github.com/arimxyer/aic
22

33
go 1.25.5
44

5+
require (
6+
github.com/charmbracelet/bubbletea v1.3.10
7+
github.com/charmbracelet/glamour v0.10.0
8+
github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834
9+
)
10+
511
require (
612
github.com/alecthomas/chroma/v2 v2.14.0 // indirect
713
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
814
github.com/aymerick/douceur v0.2.0 // indirect
9-
github.com/charmbracelet/bubbletea v1.3.10 // indirect
1015
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
11-
github.com/charmbracelet/glamour v0.10.0 // indirect
12-
github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect
1316
github.com/charmbracelet/x/ansi v0.10.1 // indirect
1417
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
1518
github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect

go.sum

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
2+
github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
13
github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
24
github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I=
5+
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
6+
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
37
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
48
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
9+
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
10+
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
511
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
612
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
713
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
@@ -12,12 +18,12 @@ github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V
1218
github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk=
1319
github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE=
1420
github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA=
15-
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
16-
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
1721
github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
1822
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
1923
github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k=
2024
github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
25+
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
26+
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
2127
github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI=
2228
github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU=
2329
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
@@ -28,6 +34,8 @@ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6
2834
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
2935
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
3036
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
37+
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
38+
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
3139
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
3240
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
3341
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -58,6 +66,8 @@ github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
5866
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
5967
github.com/yuin/goldmark-emoji v1.0.5 h1:EMVWyCGPlXJfUXBXpuMu+ii3TIaxbVBnEX9uaDC4cIk=
6068
github.com/yuin/goldmark-emoji v1.0.5/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
69+
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
70+
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
6171
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
6272
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
6373
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

0 commit comments

Comments
 (0)