A CLI and TUI tool to manage your GitHub stars with AI — sync, analyze, categorize, search, and generate awesome lists.
starman syncs your GitHub stars, analyzes them with AI, generates awesome lists, and backs up your data — all from the CLI or TUI.
- TUI — Terminal user interface with Stars, Categories, Trending, and Stats views. Search overlay, command mode (
:), sidebar preview, configurable keybindings, dark/light themes. - Sync — Concurrent paginated pull of GitHub starred repos into local SQLite (preserves AI analysis on re-sync). Supports
--watchmode for periodic auto-sync. - Analyze — Batch AI analysis (OpenAI-compatible): summaries, tags, categories with bidirectional keyword matching, plus embedding vector generation for semantic search and
search_textfor full-text index. - Search — Three-tier hybrid search (vector semantic matching > AI query understanding + text retrieval > basic text search), structured filtering (
--lang/--category/--platform/--tag),--sortoptions, and--jsonoutput. - Generate — Markdown Awesome List in 3 modes: by language, by AI category, or flat (auto-push to GitHub repo).
- Category Management — List, add, edit, delete custom categories. Built-in categories with keyword matching for AI auto-classification.
- Star/Unstar — Star management with local DB sync.
- Backup — Push
starman.dbas a SQLite binary file to any GitHub repository via Git Data API. - Config — Interactive config with env var resolution for secrets.
- Stats — View distribution of synced repos by language, category, or tag.
- Info — Inspect repo details including AI summary, README with multi-language variant support.
- Trending — Browse GitHub trending repositories (RSS or search API) with interactive starring.
- Tag & Categorize — Batch manage custom tags and categories on local repos, with category locking.
- Completion — Shell auto-completion for bash, zsh, fish, and PowerShell.
brew install morehao/tap/starmancurl -fsSL https://raw.githubusercontent.com/morehao/starman/main/scripts/install.sh | shDownload the .deb file from GitHub Releases:
dpkg -i starman_*.debDownload the .rpm file from GitHub Releases:
rpm -i starman_*.rpmscoop bucket add morehao https://github.com/morehao/scoop-bucket
scoop install starmango install github.com/morehao/starman/cmd/starman@latestgit clone https://github.com/morehao/starman.git
cd starman
go build -o starman ./cmd/starmanNo CGO required — uses modernc.org/sqlite (pure Go SQLite driver) for cross-platform compilation.
starman config initInteractive prompt will ask for GitHub username, token, and AI settings. Config is saved to ~/.starman/config.yaml.
You can also set sensitive fields via environment variables instead of the config file:
| Environment variable | Purpose |
|---|---|
STARMAN_GITHUB_TOKEN |
GitHub token (falls back to GITHUB_TOKEN) |
STARMAN_AI_API_KEY |
AI API key |
STARMAN_EMBEDDING_API_KEY |
Embedding API key (for vector search) |
starman syncPulls all your starred repos from GitHub into the local SQLite database at ~/.starman/starman.db.
starman analyzeAnalyzes up to 20 unanalyzed repos by default: fetches README, calls AI for summary/tags/platforms/search_text, resolves a category via keyword matching, and generates embedding vectors for semantic search. Results are cached in the DB — re-running only processes new repos. Use --all to analyze all unanalyzed repos, or --force to re-analyze existing ones. After analysis, the FTS5 index is automatically rebuilt for search.
# By programming language
starman generate -s language > README.md
# By AI category (shows AI summaries and tags)
starman generate -s category > README.md
# Flat list
starman generate -s flat > README.md
# Auto-push to a GitHub repo
starman generate -s language --repo awesome-stars# Basic semantic search
starman search "terminal tools"
# Filter by language and sort by stars
starman search "framework" --lang Go --sort stars --limit 10
# Filter by platform and tag
starman search "database" --platform cli --tag go
# JSON output
starman search "machine learning" --jsonThree-tier hybrid search: attempts vector semantic matching first (requires embedding config), degrades to AI query understanding + full-text retrieval, then falls back to basic text search. Matches against full_name, description, AI summary, search_text, tags, and topics with weighted scoring.
starmanRunning starman without subcommands launches the terminal user interface with Stars, Categories, Trending, and Stats views. Use Tab to switch views, : for commands, / for search.
# Browse weekly trending repos
starman trending
# Daily trending, filtered by language
starman trending --since daily --lang Rust
# Interactively star repos from trending
starman trending --starRunning starman without any subcommands starts the terminal user interface built with Bubble Tea.
| View | Description |
|---|---|
| Stars | Browse, filter, and manage your starred repos. Sections: All / Language / Category / Tag. m for Actions menu (sync, analyze, star/unstar, edit category/tags, open in browser) |
| Categories | Manage custom category definitions — list, add, edit, delete categories with keywords and sort order. m for Actions menu |
| Trending | Browse GitHub trending repositories. Sections: Daily / Weekly / Monthly. m for Actions menu (star, refresh, sync) |
| Stats | Full-screen distribution charts by language, category, or tag. h/l to switch dimensions |
| Key | Action |
|---|---|
Tab / Shift+Tab |
Switch view |
j/k |
Move up/down |
g/G |
First/last item |
]/[ |
Next/previous section tab |
h/l |
Switch stats dimension |
m |
Actions menu |
p |
Toggle sidebar |
/ |
Search overlay |
: |
Command mode |
r |
Refresh |
q |
Quit |
Press : to enter command mode — runs any starman subcommand directly via headless cobra command tree (e.g. :sync --full, :analyze --all, :search "term" --lang Go). The output is shown in a viewport overlay.
Available on every command:
| Flag | Type | Default | Description |
|---|---|---|---|
--config |
string | ~/.starman/config.yaml |
Config file path |
--token |
string | "" |
GitHub token (overrides config/env) |
--verbose |
bool | false |
Verbose output |
--version |
bool | false |
Print version |
Sync starred repos from GitHub to local SQLite.
starman sync [--full] [--watch] [--interval 30m] [--touch]| Flag | Type | Default | Description |
|---|---|---|---|
--full |
bool | false |
Full sync: remove repos that are no longer starred on GitHub |
--watch |
bool | false |
Watch mode: periodic auto-sync |
--interval |
duration | 30m |
Watch mode sync interval (minimum 5m) |
--touch |
bool | false |
Lightweight sync: only update repo timestamps (exclusive with --full/--watch) |
AI analysis results and custom fields are preserved across syncs.
Batch AI analysis: README → summary/tags/platform/search_text → category → embedding → FTS5 rebuild.
starman analyze [--all] [--repo <name> ...] [--force] [--limit N]| Flag | Type | Default | Description |
|---|---|---|---|
--all |
bool | false |
Analyze all unanalyzed repos |
--repo |
stringSlice | [] |
Specific repo full names to analyze (repeatable) |
--force |
bool | false |
Force re-analyze even if already analyzed |
--limit |
int | 20 |
Max repos to analyze (0 = no limit) |
Failure isolation: single repo failure doesn't stop the batch. Failed repos are marked analysis_failed for retry.
Three-tier hybrid search with structured filtering.
starman search <query> [--json] [--limit N] [--lang L] [--category C] [--platform P]
[--tag T] [--min-stars N] [--max-stars N] [--sort score|stars|name]| Flag | Type | Default | Description |
|---|---|---|---|
--json |
bool | false |
JSON output |
--limit |
int | 0 |
Limit results (0 = no limit) |
--lang |
string | "" |
Filter by language |
--category |
string | "" |
Filter by category |
--platform |
string | "" |
Filter by platform: web / desktop / mobile / cli / library / service |
--tag |
stringSlice | [] |
Filter by tag (OR logic, repeatable) |
--min-stars |
int | 0 |
Minimum star count |
--max-stars |
int | 0 |
Maximum star count (0 = no limit) |
--analyzed |
bool | false |
Only show analyzed repos |
--no-analyzed |
bool | false |
Only show unanalyzed repos |
--analysis-failed |
bool | false |
Only show analysis-failed repos |
--no-vector |
bool | false |
Disable vector search, text search only |
--sort |
string | score |
Sort by: score / stars / name |
Search tiers: vector semantic matching (sqlite-vec) → AI query understanding + FTS5 full-text retrieval → basic text search. Transparent degradation when vector config is absent.
Generate an Awesome List Markdown file from the local database.
starman generate [output] [-s language|category|flat] [-o file] [--repo <name>] [-m msg] [-T template]| Flag | Type | Default | Description |
|---|---|---|---|
-s, --sort |
string | from config | Sort mode: language / category / flat |
-o, --output |
string | "" |
Output file path (default: stdout) |
--repo |
string | "" |
Push to a GitHub repo's README (e.g. awesome-stars) |
-m, --message |
string | "update stars" |
Commit message for --repo |
-T, --template |
string | "" |
Custom template file path |
Templates:
language— Group by programming language (embedded:by_language.tmpl)category— Group by AI category with summaries and tags (by_category.tmpl)flat— Flat list (flat.tmpl)
Configuration management with interactive init and masked display.
starman config init # Interactive config creation
starman config show # Display current config (secrets masked)config init walks through GitHub username/token, AI BaseURL/API Key/Model, and writes ~/.starman/config.yaml.
config show prints full config with token/key showing only first and last 2 characters.
Star a repository on GitHub and sync to local DB.
starman star <owner/repo>Unstar a repository on GitHub and mark locally as unstarred (StarredAt="").
starman unstar <owner/repo>Backup starman.db as a SQLite binary file to a GitHub repository via Git Data API.
starman backup --repo <name> [-m "message"]| Flag | Type | Default | Description |
|---|---|---|---|
--repo |
string | "" |
GitHub repo to push backup to (e.g. awesome-stars) |
-m, --message |
string | "backup starman data" |
Commit message |
Backup pushes starman.db to starman-backup/starman.db in the target repository using GitHub's Git Data API (blobs, trees, commits, refs).
Show distribution statistics of synced repositories.
starman stats [--by language|category|tag] [--top N] [--json]| Flag | Type | Default | Description |
|---|---|---|---|
--by |
string | language |
Dimension: language / category / tag |
--top |
int | 10 |
Show top N items (0 = all) |
--json |
bool | false |
JSON output |
Display detailed repository information.
starman info <owner/repo> [--readme] [--readme-variant <file>]| Flag | Type | Default | Description |
|---|---|---|---|
--readme |
bool | false |
Fetch and display README |
--readme-variant |
string | "" |
Specific README variant (e.g. README_zh.md) |
Shows: URL, language, stars/forks, topics, starred-at time, AI summary/tags/category, custom fields, lock status.
Manage custom tags on repositories.
# Single repo: + to add, - to remove
starman tag <owner/repo> +awesome,-old
# Batch: add tags to all Go repos
starman tag --lang Go --add awesome,cli
# Batch: remove tags filtered by category
starman tag --cat-filter "开发工具" --remove deprecated| Flag | Type | Default | Description |
|---|---|---|---|
--lang |
string | "" |
Batch: filter by language |
--cat-filter |
string | "" |
Batch: filter by existing category |
--add |
string | "" |
Batch: comma-separated tags to add |
--remove |
string | "" |
Batch: comma-separated tags to remove |
Tags are stored in custom_tags and never overwritten by AI analysis.
Manage custom category on repositories with lock support.
# Single repo: set category with lock
starman categorize <owner/repo> "AI 机器学习" --lock
# Batch: set category for all Python repos
starman categorize --lang Python "数据分析"
# Batch: recategorize from one category to another
starman categorize --cat-filter "web-app" "其他"| Flag | Type | Default | Description |
|---|---|---|---|
--lang |
string | "" |
Batch: filter by language |
--cat-filter |
string | "" |
Batch: filter by existing category |
--lock |
bool | false |
Lock category (prevent AI overwrite) |
--unlock |
bool | false |
Unlock category |
Manage custom category definitions.
starman category list # List all categories
starman category add <id> [--name "Display Name"] # Add a custom category
[--keywords "kw1,kw2"] [--sort-order N] [--is-hidden]
starman category edit <id> [--name "New Name"] # Edit a category
[--keywords "kw1,kw2"] [--sort-order N] [--is-hidden]
starman category delete <id> [--force] # Delete a custom category| Flag | Type | Default | Description |
|---|---|---|---|
--name |
string | "" |
Display name (defaults to id for add) |
--keywords |
string | "" |
Comma-separated keywords for auto-classification |
--sort-order |
int | 0 |
Sort order (0 appends to end for add) |
--is-hidden |
bool | false |
Hide from AI analysis |
--force |
bool | false |
Skip delete confirmation |
Built-in categories cannot be deleted. Custom categories can be added, edited, and deleted.
Browse GitHub trending repositories.
starman trending [--since daily|weekly|monthly] [--lang L] [--top N] [--source rss|search] [--star]| Flag | Type | Default | Description |
|---|---|---|---|
--since |
string | weekly |
Time range: daily / weekly / monthly |
--lang |
string | "" |
Filter by language |
--top |
int | 20 |
Show top N repos |
--source |
string | rss |
Data source: rss / search |
--star |
bool | false |
Interactive star selection |
Default source is RSS (GitHubTrendingRSS); --source search uses GitHub Search API fallback.
Generate shell auto-completion script.
starman completion bash # Bash completion
starman completion zsh # Zsh completion
starman completion fish # Fish completion
starman completion powershell # PowerShell completionUsage: source <(starman completion zsh) (or the appropriate shell).
Config file: ~/.starman/config.yaml (created by starman config init).
github:
token: "" # or use STARMAN_GITHUB_TOKEN / GITHUB_TOKEN
username: ""
ai:
base_url: "https://api.openai.com/v1"
api_key: "" # or use STARMAN_AI_API_KEY
model: "gpt-4o-mini"
concurrency: 3
custom_prompt: ""
embedding:
base_url: "https://api.openai.com/v1"
api_key: "" # or use STARMAN_EMBEDDING_API_KEY
model: "text-embedding-3-small"
generate:
sort: "language" # language | category | flat
tui:
default_view: stars # stars | categories | trending | stats
confirm_quit: false
theme: dark # dark | light
preview:
open: true
position: right # right | bottom
width: 0.42
height: 0.4
keybindings:
universal:
quit: q
refresh: r
search: /
command: ":"
toggle_sidebar: p
help: "?"
stars:
sync: s
analyze: a
toggle_star: x
edit_category: c
edit_tag: tPriority: CLI flag > environment variable > config file > default value.
starman config show prints the current configuration with sensitive fields masked.
starman works with any OpenAI-compatible API endpoint (/v1/chat/completions). Compatible providers include:
- OpenAI
- DeepSeek
- Moonshot (MiMo)
- OpenRouter
- Local models via Ollama / vLLM / LM Studio
Set ai.base_url and ai.model to match your provider. The ai.concurrency setting controls batch analysis parallelism.
Embedding also works with any OpenAI-compatible embedding API endpoint (/v1/embeddings). Configure the embedding section to enable vector semantic search; when unconfigured, search gracefully degrades to text retrieval.
- TUI with headless command execution — The TUI reuses the cobra command tree via
cmdrunner, so every CLI subcommand is automatically available in command mode (:) without additional implementation. See ADR-001. - Incremental sync preserves analysis — Re-syncing from GitHub never overwrites AI summaries, tags, categories, or custom fields you've set.
- Category locking — Lock a repo's category with
category_lockedto prevent AI from overwriting your manual assignment. - Three-tier hybrid search — Search first attempts vector semantic matching (sqlite-vec), degrades to AI query understanding + full-text retrieval, then falls back to basic text search. Transparent degradation when vector config is absent — zero-cost operation. The
ai_search_textfield generated by LLM during analysis enriches the search index for better recall. - Analyze failure isolation — If AI analysis fails for one repo, the batch continues. Failed repos are marked with
analysis_failedfor retry. - Generate reads from local DB —
generatenever calls the GitHub API for data; it reads from SQLite. Runsyncfirst, thenanalyzefor AI categories. - Stats are free —
stats,info, andsearch(without AI) only read from the local SQLite database. No API calls, no token needed. - Trending dual source —
trendingdefaults to RSS via GitHubTrendingRSS.--source searchfalls back to the official GitHub Search API. - Backup via Git Data API —
backuppushes the rawstarman.dbfile to any GitHub repository using blob/tree/commit/ref operations — no WebDAV needed.
| Component | Library |
|---|---|
| CLI framework | cobra + pflag |
| TUI framework | bubbletea v2 + lipgloss v2 + bubbles v2 |
| Markdown rendering | glamour |
| GitHub API | go-github v71 + httpcache |
| Concurrency | conc |
| SQLite | modernc.org/sqlite + modernc.org/sqlite/vec (pure Go, no CGO) |
| Config | yaml.v3 |
| AI | OpenAI-compatible HTTP API (no SDK) |
# Build (optimized, stripped)
make build
# Install
make install
# Test
make test
# Lint
make lint
# Build and run
make run
# Clean
make cleanOr use Go directly:
# Build
CGO_ENABLED=0 go build -ldflags="-s -w" -trimpath -o starman ./cmd/starman/
# Test
go test ./...
# Vet
go vet ./...cmd/starman/main.go # Entry point
docs/
adr-001-headless-cli-command-execution.md # Architecture Decision Record
screenshots/ # TUI screenshots
internal/
cli/ # Cobra command definitions
config/ # YAML config loading + env var resolution
store/ # SQLite data layer (Store interface)
github/ # GitHub API client (go-github wrapper)
ai/ # OpenAI-compatible client + analysis/categorization/search
discovery/ # Trending repos (RSS + search API fallback)
generate/ # Markdown template rendering
backup/ # Git Data API backup (SQLite binary push)
tui/ # Bubble Tea terminal UI
cmdrunner/ # Headless cobra command execution
components/ # Reusable UI components (15 packages)
constants/ # Icon constants
keys/ # Keybinding registry
theme/ # Dark/light theme tokens
context/ # Shared TUI context
common/ # Shared styles
version/ # Version info (ldflags injection)
internal/generate/templates/ # Embedded Markdown templates
Package dependencies flow in one direction: cli/tui → business packages → store. The github package converts go-github types to local store types internally, so no third-party types leak across boundaries.
