starman
English | 简体中文
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, tracks releases, and backs up your data — all from the CLI or TUI.
Features
- TUI — Terminal user interface with Stars, Categories, Trending, Releases, 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
--watch mode 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_text for 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), --sort options, and --json output.
- 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.
- Release Tracking — Subscribe to repos and pull new releases with incremental watermark.
- Star/Unstar — Star management with local DB sync.
- Backup — Push
starman.db as 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.
Installation
macOS / Linux (Homebrew)
brew install morehao/tap/starman
Linux (Shell)
curl -fsSL https://raw.githubusercontent.com/morehao/starman/main/scripts/install.sh | sh
Linux (.deb)
Download the .deb file from GitHub Releases:
dpkg -i starman_*.deb
Linux (.rpm)
Download the .rpm file from GitHub Releases:
rpm -i starman_*.rpm
Windows (Scoop)
scoop bucket add morehao https://github.com/morehao/scoop-bucket
scoop install starman
From source
go install github.com/morehao/starman/cmd/starman@latest
Build from repository
git clone https://github.com/morehao/starman.git
cd starman
go build -o starman ./cmd/starman
No CGO required — uses modernc.org/sqlite (pure Go SQLite driver) for cross-platform compilation.
Quick Start
1. Create config
starman config init
Interactive 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) |
2. Sync starred repos
starman sync
Pulls all your starred repos from GitHub into the local SQLite database at ~/.starman/starman.db.
3. Analyze with AI
starman analyze
Analyzes 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.
4. Generate awesome list
# 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
5. Search
# 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" --json
Three-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.
6. Launch TUI
starman
Running starman without subcommands launches the terminal user interface with Stars, Categories, Trending, Releases, and Stats views. Use Tab to switch views, : for commands, / for search.
7. Discover trending repos
# Browse weekly trending repos
starman trending
# Daily trending, filtered by language
starman trending --since daily --lang Rust
# Interactively star repos from trending
starman trending --star
TUI
Running starman without any subcommands starts the terminal user interface built with Bubble Tea.

Views
| 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) |
| Releases |
Track new releases from subscribed repos with read/unread filtering. m for Actions menu (mark read, show all/unread, refresh, sync, open in browser) |
| Stats |
Full-screen distribution charts by language, category, or tag. h/l to switch dimensions |
Key Bindings
| 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 |
Command Mode
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.
Command Reference
Global Flags
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 |
starman sync
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.
starman analyze
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.
starman search <query>
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.
starman generate [output]
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)
starman config
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.
starman release
Track repository releases with incremental watermark.
starman release list [--all] # List unread (or all) releases
starman release pull # Pull new releases for subscribed repos
starman release subscribe <owner/repo> # Subscribe + pull initial releases
starman release unsubscribe <owner/repo> # Unsubscribe
| Flag |
Type |
Default |
Description |
--all |
bool |
false |
list subcommand: show all releases including read |
starman star <owner/repo>
Star a repository on GitHub and sync to local DB.
starman star <owner/repo>
starman unstar <owner/repo>
Unstar a repository on GitHub and mark locally as unstarred (StarredAt="").
starman unstar <owner/repo>
starman backup
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).
starman stats
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 |
starman info <owner/repo>
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.
starman tag [owner/repo] [tagExpr]
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.
starman categorize [owner/repo] <category>
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 |
starman 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.
starman trending
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.
starman completion <shell>
Generate shell auto-completion script.
starman completion bash # Bash completion
starman completion zsh # Zsh completion
starman completion fish # Fish completion
starman completion powershell # PowerShell completion
Usage: source <(starman completion zsh) (or the appropriate shell).
Configuration
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 | releases | 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: t
Priority: CLI flag > environment variable > config file > default value.
starman config show prints the current configuration with sensitive fields masked.
AI Configuration
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.
Key Design
- 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_locked to 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_text field 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_failed for retry.
- Release watermark — Subscribed repos track the latest fetched release timestamp, so
release pull only retrieves new releases.
- Generate reads from local DB —
generate never calls the GitHub API for data; it reads from SQLite. Run sync first, then analyze for AI categories.
- Stats are free —
stats, info, and search (without AI) only read from the local SQLite database. No API calls, no token needed.
- Trending dual source —
trending defaults to RSS via GitHubTrendingRSS. --source search falls back to the official GitHub Search API.
- Backup via Git Data API —
backup pushes the raw starman.db file to any GitHub repository using blob/tree/commit/ref operations — no WebDAV needed.
Tech Stack
Development
# Build (optimized, stripped)
make build
# Install
make install
# Test
make test
# Lint
make lint
# Build and run
make run
# Clean
make clean
Or use Go directly:
# Build
CGO_ENABLED=0 go build -ldflags="-s -w" -trimpath -o starman ./cmd/starman/
# Test
go test ./...
# Vet
go vet ./...
Project Structure
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
release/ # Release tracker with watermark
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.
License
MIT License