@elysiumoss/grepo
v0.5.0
Published
AI-powered GitHub repository management CLI — generate READMEs, topics, descriptions, and more using Gemini
Maintainers
Readme
grepo
Overview
grepo automates the heavy lifting of repository maintenance.
By integrating with LLM providers like Google Gemini, it intelligently analyzes your codebase to generate professional READMEs, suggest relevant repository topics, craft repository descriptions, summarize technologies, and recommend improvements.
High-Level Flow
flowchart LR
User(["👤 User"]) -->|grepo readme owner/repo| CLI["🛠️ grepo CLI"]
CLI --> Config["⚙️ Config Builder<br/>env + .grepo + flags"]
Config --> Ingest["📦 GitIngest<br/>tree + content"]
Ingest --> LLM["🤖 Gemini LLM"]
LLM --> Validator["🧪 Mermaid Validator"]
Validator --> Output{"Output target?"}
Output -->|--push / --apply| GitHub["🐙 GitHub API"]
Output -->|local| File["📄 README.md / stdout"]
GitHub -.->|writes| Repo[("Repository")]Architecture
grepo is built on top of the Effect ecosystem, providing typed errors, composable services, and structured concurrency.
The CLI is decomposed into commands, services, and utilities.
Module Layout
graph TB
subgraph Entry["Entry Point"]
cli["cli.ts<br/>argv router"]
end
subgraph Commands["Commands (src/commands)"]
readme["readme.ts"]
topics["topics.ts"]
describe["describe.ts"]
analyze["analyze.ts<br/>summary/tech/improve"]
end
subgraph Services["Services (src/services.ts)"]
gemini["Gemini Service"]
github["GitHub Service"]
gitingest["GitIngest fetcher"]
end
subgraph Utils["Utilities (src/utils)"]
args["args.ts<br/>parser"]
validation["validation.ts<br/>URL/key checks"]
configFile["config-file.ts<br/>~/.grepo"]
prompts["prompts/readme.ts"]
mermaid["mermaid.ts<br/>diagram fixer"]
logger["logger.ts"]
end
cli --> args
cli --> configFile
cli --> Commands
Commands --> Services
Commands --> validation
readme --> prompts
readme --> mermaid
Services --> loggerLayered Architecture
flowchart TB
subgraph Presentation["Presentation Layer"]
argv["argv parsing"]
usage["usage / help text"]
loggerOut["structured logger"]
end
subgraph Application["Application Layer (Commands)"]
runReadme["readme.run"]
runTopics["topics.run"]
runDescribe["describe.run"]
runAnalyze["analyze.run"]
end
subgraph Domain["Domain Layer (Services)"]
Gemini["Gemini (Effect Tag)"]
GitHub["GitHub (Effect Tag)"]
fetchRepo["fetchRepo"]
end
subgraph Infra["Infrastructure"]
GeminiClient["@google/genai"]
GitHubClient["fetch + REST v3"]
GitIngestAPI["gitingest.com"]
end
Presentation --> Application
Application --> Domain
Domain --> InfraCommand Pipeline
Every command follows the same shape: parse → fetch context → prompt → act.
The readme command adds analysis, generation, and mermaid validation phases.
Generic Command Flow
flowchart TD
Start(["grepo <cmd> <url>"]) --> ParseArgs["Parse argv<br/>(args.ts)"]
ParseArgs --> LoadEnv["Load .env / ~/.grepo"]
LoadEnv --> HasKey{"GEMINI_API_KEY<br/>present?"}
HasKey -->|no| Prompt["Interactive setup<br/>(promptConfigSetup)"]
HasKey -->|yes| Build["buildConfig()"]
Prompt --> Build
Build --> Validate{"Valid URL +<br/>key + token?"}
Validate -->|no| Fail(["❌ ValidationError"])
Validate -->|yes| Branch["Detect default branch"]
Branch --> Layers["Compose Effect layers<br/>(GeminiLive, GitHubLive)"]
Layers --> Dispatch["Dispatch by command"]
Dispatch --> Run["run(config)"]
Run --> Done(["✅ Result / push"])readme — Three-Phase Generation
flowchart LR
A["Repo URL"] --> B["GitIngest fetch"]
B --> C["extractExistingReadme"]
C --> D["Phase 1<br/>Analysis prompt"]
D --> E["parseAnalysis"]
E --> F["Phase 2<br/>Generation prompt"]
F --> G["Raw markdown"]
G --> H["Phase 3<br/>validateAndFixMermaid"]
H --> I{"Push?"}
I -->|yes| J["github.pushFile"]
I -->|no| K["writeFile(README.md)"]topics — Suggest & Apply
flowchart LR
A["Repo URL"] --> B["GitIngest fetch"]
B --> C["Topics prompt"]
C --> D["Gemini → JSON array"]
D --> E["validate topics"]
E --> F{"--apply?"}
F -->|yes + --merge| G["getTopics ∪ new"]
F -->|yes| H["setTopics(new)"]
F -->|no / --dry-run| I["Print only"]
G --> H
H --> J(["✅ Topics updated"])describe — Description + Homepage Detection
flowchart LR
A["Repo URL"] --> B["GitIngest fetch"]
B --> C["Describe prompt<br/>(detect homepage<br/>from package.json,<br/>CNAME, badges...)"]
C --> D["Gemini → {description, homepage}"]
D --> E{"--apply?"}
E -->|yes| F["github.updateRepo"]
E -->|no| G["Print only"]
F --> H(["✅ About section updated"])Service Topology
Services are exposed as Effect Context Tags so commands can declare dependencies in their type signature without coupling to concrete clients.
classDiagram
class GeminiServiceApi {
+generateContent(prompt) Effect~string, GeminiError~
}
class GitHubServiceApi {
+getDefaultBranch(owner, repo)
+getTopics(owner, repo)
+setTopics(owner, repo, topics)
+pushFile(owner, repo, path, content, msg, branch)
+updateRepo(owner, repo, data)
}
class GitIngest {
+fetchRepo(url, token) Effect~RepoData, GitIngestError~
}
class GeminiClient {
-apiKey
+generateContent(prompt)
}
class GitHubClient {
-token
+getDefaultBranch()
+pushFile()
+setTopics()
+updateRepo()
}
GeminiServiceApi <|.. GeminiClient : provides
GitHubServiceApi <|.. GitHubClient : provides
GeminiServiceApi --> GeminiError : may fail with
GitHubServiceApi --> GitHubError : may fail with
GitIngest --> GitIngestError : may fail withSequence: Generating a README
sequenceDiagram
autonumber
actor U as User
participant C as grepo CLI
participant Cfg as Config
participant GI as GitIngest
participant G as Gemini
participant M as Mermaid Validator
participant GH as GitHub API
participant FS as Local FS
U->>C: grepo readme https://github.com/o/r --push
C->>Cfg: loadEnv + buildConfig
Cfg-->>C: GrepoConfig
C->>GH: getDefaultBranch(o, r)
GH-->>C: "main"
C->>GI: fetchRepositoryContent(url)
GI-->>C: { tree, content }
C->>G: analysisPrompt(tree, content)
G-->>C: structured analysis
C->>G: generationPrompt(analysis)
G-->>C: raw README markdown
C->>M: validateAndFixMermaid(raw)
alt Diagram has syntax errors
M->>G: re-prompt with error
G-->>M: corrected diagram
end
M-->>C: validated README
C->>FS: writeFile("README.md")
C->>GH: pushFile(o, r, "README.md", branch)
GH-->>U: ✅ commitConfiguration Resolution
grepo resolves credentials in a layered, override-friendly order:
flowchart TD
Start(["Need GEMINI_API_KEY"]) --> Env{"process.env<br/>GEMINI_API_KEY?"}
Env -->|yes| Use(["✅ use it"])
Env -->|no| Google{"GOOGLE_API_KEY?"}
Google -->|yes| Use
Google -->|no| File{"~/.grepo/config<br/>geminiApiKey?"}
File -->|yes| Use
File -->|no| Prompt["Interactive setup<br/>(promptConfigSetup)"]
Prompt --> Save["Save 0600 file<br/>writeConfigFile"]
Save --> UseError Model
Errors are tagged data classes from errors.ts.
Each command declares its possible failures in the type so Effect.catchTags can route them to user-friendly messages.
stateDiagram-v2
[*] --> Running
Running --> GeminiError: LLM call failed
Running --> GitHubError: API call failed
Running --> GitIngestError: ingest failed
Running --> ValidationError: bad URL / key
Running --> Success: ✅ exit 0
GeminiError --> ExitNonZero: log + exit 1
GitHubError --> ExitNonZero
GitIngestError --> ExitNonZero
ValidationError --> ExitNonZero
ExitNonZero --> [*]
Success --> [*]Installation
Ensure you have Bun (or Node ≥ 20.19) installed, then install grepo globally:
bun add -g @elysiumoss/grepo
# or
npm install -g @elysiumoss/grepoUsage
Generate a new README.md for a repository:
grepo readme https://github.com/owner/repo --format md --pushAutomatically update repository topics based on code analysis:
grepo topics https://github.com/owner/repo --apply --mergeGenerate a description and detect the homepage:
grepo describe https://github.com/owner/repo --applyCLI Reference
| Command | Description |
| :--------- | :--------------------------------------------------------- |
| readme | Generate and optionally push a README documentation file |
| topics | Analyze code and suggest/apply repository topics |
| describe | Generate a repository description and detect homepage URLs |
| summary | Provide a comprehensive summary of the repository |
| tech | List technologies, frameworks, and tools used |
| improve | Suggest 5 specific, actionable improvements |
Options
| Flag | Applies to | Description |
| :-------------------- | :---------------------- | :--------------------------------------------------------- |
| --format md\|mdx | readme | Output format (default: md) |
| --style … | readme | minimal, standard, or comprehensive (default: standard) |
| --output <file> | readme | Output file path |
| --push | readme | Commit the generated file directly to GitHub |
| --apply | topics, describe | Apply changes to the GitHub API |
| --merge | topics | Merge with existing topics instead of replacing |
| --dry-run | all mutating commands | Preview changes without writing or pushing |
| --branch <name> | readme | Target branch (default: auto-detect from repo) |
| --tone <voice> | readme | casual, professional, minimal, or technical |
Configuration
grepo requires authentication for repository access and AI analysis.
Configure these via environment variables, a .env file, or ~/.grepo/config.json:
| Key | Required for |
| :---------------------------------- | :--------------------------------- |
| GEMINI_API_KEY / GOOGLE_API_KEY | All commands (LLM analysis) |
| GH_TOKEN / GITHUB_TOKEN | --push, --apply, --merge |
Example .env file:
GEMINI_API_KEY=AIzaSy...
GH_TOKEN=ghp_...If no key is present, grepo will run an interactive setup on first use and persist your choices to ~/.grepo/config.json with 0600 permissions.
Development
git clone https://github.com/ElysiumOSS/grepo
cd grepo
bun install
bun run build # tsdown build
bun run test # vitest
bun run lint # biome checkTesting Topology
graph LR
Vitest["vitest"] --> Unit["Unit tests<br/>*.test.ts"]
Unit --> ConfigT["config.test.ts"]
Unit --> CommandT["commands/*.test.ts"]
Unit --> UtilT["utils/*.test.ts"]
Unit --> MermaidT["mermaid.test.ts"]
Vitest --> Coverage["@vitest/coverage-v8<br/>≥ 80% target"]See .github/CONTRIBUTING.md and .github/DEVELOPMENT.md for detailed guidelines.
License
This project is licensed under the MIT License.
