AGENTS.md · diff

git:20260125.0fa8930 to git:20260205.4c0e8af

184 added, 191 removed. Audit A to A.

# Skulto Agent Guide
> Scope: Root project (applies to all subdirectories unless overridden)
- Skulto is an offline-first tool for syncing and managing agent skills. It scrapes GitHub for AI skill files, indexes them with SQLite FTS5, provides a Bubble Tea TUI, and translates skills between 6 AI platforms.
-
## Quick Facts
- | Attribute | Value |
- |-----------|-------|
+ | Item | Value |
+ |------|-------|
| **Primary language** | Go 1.25+ |
- | **Package manager** | Go modules |
- | **Build system** | Make |
- | **Database** | SQLite with FTS5 (GORM) |
- | **TUI framework** | Bubble Tea + Lip Gloss |
- | **CI/CD** | GitHub Actions |
- | **Data location** | `~/.skulto/` (simplified from XDG) |
+ | **Package manager** | Go modules (`go mod`) |
+ | **Build tool** | Make (`make build`, `make build-mcp`) |
+ | **CLI framework** | [Cobra](https://github.com/spf13/cobra) + [Fang](https://github.com/charmbracelet/fang) |
+ | **TUI framework** | [Bubble Tea](https://github.com/charmbracelet/bubbletea) + [Lip Gloss](https://github.com/charmbracelet/lipgloss) |
+ | **MCP framework** | [mcp-go](https://github.com/mark3labs/mcp-go) |
+ | **Database** | SQLite with GORM + FTS5 for full-text search |
+ | **CI/CD** | GitHub Actions (`.github/workflows/ci.yml`) |
+ | **Analytics** | PostHog (opt-out via `SKULTO_TELEMETRY_TRACKING_ENABLED=false`) |
+ | **Primary binaries** | `skulto` (CLI/TUI), `skulto-mcp` (MCP server) |
## Repository Tour
```
skulto/
- ├── cmd/skulto/ # Main CLI entry point
- ├── internal/ # Private packages (see below)
- │ ├── cli/ # Cobra CLI commands (add, list, pull, etc.)
- │ ├── config/ # Configuration (env vars only, no config file)
- │ ├── db/ # GORM + SQLite + FTS5 database layer
- │ ├── detect/ # AI tool detection on system
- │ ├── embedding/ # Embedding provider abstraction
- │ ├── installer/ # Skill installation via symlinks
- │ ├── llm/ # LLM provider abstraction (Anthropic, OpenAI, OpenRouter)
- │ ├── log/ # Structured logging
- │ ├── migration/ # Database migrations
- │ ├── models/ # Data structures (Skill, Tag, Source, etc.)
- │ ├── scraper/ # GitHub scraping (git clone + REST API)
- │ ├── search/ # Search service + background indexer
- │ ├── security/ # Security scanner for skills
- │ ├── skillgen/ # Skill generation utilities
- │ ├── telemetry/ # PostHog analytics (opt-in)
- │ ├── testutil/ # Test utilities (SkipAITests helper)
- │ ├── tui/ # Bubble Tea TUI
- │ │ ├── components/ # Reusable UI components
- │ │ └── views/ # Screen views (home, search, detail, etc.)
- │ └── vector/ # Vector store (chromem-go)
- ├── pkg/version/ # Version info (set via ldflags)
- ├── scripts/ # Build and release scripts
- ├── docs/ # Planning documents
- │ ├── completed/ # Finished implementation plans
- │ └── in-review/ # Plans under review
- └── .github/workflows/ # CI/CD pipelines
+ ├── cmd/skulto/ # Main CLI entry point
+ ├── cmd/skulto-mcp/ # MCP server binary
+ ├── internal/
+ │ ├── cli/ # Cobra CLI commands (add, install, pull, etc.)
+ │ │ └── prompts/ # Interactive CLI prompts (platform selector)
+ │ ├── config/ # Configuration (env vars only)
+ │ ├── db/ # GORM + SQLite + FTS5 database layer
+ │ ├── detect/ # AI tool detection on system
+ │ ├── embedding/ # Embedding provider abstraction
+ │ ├── favorites/ # File-based favorites persistence
+ │ ├── installer/ # Skill installation via symlinks (33 platforms)
+ │ ├── llm/ # LLM provider abstraction
+ │ ├── log/ # Structured logging
+ │ ├── mcp/ # MCP server implementation
+ │ ├── migration/ # Database migrations
+ │ ├── models/ # Data structures (Skill, Tag, Source, etc.)
+ │ ├── scraper/ # GitHub scraping (git clone based)
+ │ ├── search/ # Search service
+ │ ├── security/ # Security scanner for skills
+ │ ├── telemetry/ # PostHog analytics (opt-out)
+ │ ├── testutil/ # Test utilities
+ │ ├── tui/ # Bubble Tea TUI
+ │ │ ├── components/ # Reusable UI components (dialogs, selectors)
+ │ │ └── views/ # Screen views (home, search, detail, etc.)
+ │ └── vector/ # Vector store
+ ├── pkg/version/ # Version info (set via ldflags)
+ ├── scripts/ # Build and release scripts
+ ├── docs/ # Documentation and plan files
+ │ └── plans/ # Implementation plans
+ ├── assets/ # Demo GIFs for README
+ └── .github/workflows/ # CI/CD pipelines
```
- ## Tooling & Setup
-
- ### Prerequisites
+ ### Key Directories
- - **Go 1.25+** (check with `go version`)
- - **Make** (for build automation)
- - **asdf** (optional, uses `.tool-versions`)
+ | Path | Owner/Purpose |
+ |------|---------------|
+ | `internal/cli/` | CLI command implementations - each file is a Cobra command |
+ | `internal/tui/views/` | TUI screens - Bubble Tea models for each view |
+ | `internal/mcp/` | MCP server - handlers expose CLI/TUI functionality to AI agents |
+ | `internal/installer/` | Cross-platform skill installation - symlink management for 33 AI tools |
+ | `internal/telemetry/` | PostHog event tracking - events defined in `events.go`, client in `client.go` |
+ | `internal/db/` | Database operations - GORM models and FTS5 search |
- ### Environment Variables
+ ## Tooling & Setup
- Configuration is done entirely via environment variables (no config file).
+ ### Requirements
- | Variable | Purpose | Required |
- |----------|---------|----------|
- | `GITHUB_TOKEN` | Higher GitHub API rate limits | Optional |
- | `OPENAI_API_KEY` | Embeddings for semantic search | Optional |
- | `ANTHROPIC_API_KEY` | LLM provider | Optional |
- | `OPENROUTER_API_KEY` | Alternative LLM provider | Optional |
- | `RUN_AI_TESTS` | Enable AI-dependent tests | Test only |
- | `SKULTO_TELEMETRY_TRACKING_ENABLED` | Set to `false` to disable telemetry (enabled by default) | Optional |
+ - Go 1.25 or higher
+ - Make
+ - (Optional) `GITHUB_TOKEN` for higher GitHub API rate limits
+ - (Optional) `OPENAI_API_KEY` for embeddings in semantic search
- ### Initial Setup
+ ### Install Dependencies
```bash
- # Install dependencies + golangci-lint
make deps
+ ```
- # Build the binary
- make build
+ This downloads Go modules and installs golangci-lint to `./bin/`.
- # Run the TUI
- ./build/skulto
- ```
+ ### Environment Variables
- ## Common Tasks
+ | Variable | Purpose |
+ |----------|---------|
+ | `GITHUB_TOKEN` | Higher GitHub API rate limits (optional) |
+ | `OPENAI_API_KEY` | Embeddings for semantic search (optional) |
+ | `SKULTO_TELEMETRY_TRACKING_ENABLED` | Set to `false` to disable telemetry |
+ | `SKULTO_POSTHOG_API_KEY` | PostHog API key (set at build time) |
- | Task | Command | Description |
- |------|---------|-------------|
- | Build | `make build` | Production build to `./build/skulto` |
- | Dev build | `make dev` | Build with race detector (requires CGO) |
- | Run | `make run` | Build and run TUI |
- | Test | `make test` | Run all tests |
- | Test + race | `make test-race` | Tests with race detector |
- | Coverage | `make test-coverage` | Generate `coverage.html` |
- | Lint | `make lint` | Run golangci-lint |
- | Format | `make format` | Run `go fmt` |
- | Clean | `make clean` | Remove build artifacts |
- | Ship | `make ship_it` | Build, lint, test, then push |
+ ### Data Directory
- ### Running Specific Tests
+ Skulto stores data in `~/.skulto/`:
- ```bash
- # Run all tests
- go test ./...
+ | Path | Purpose |
+ |------|---------|
+ | `~/.skulto/skulto.db` | SQLite database |
+ | `~/.skulto/skulto.log` | Logfile |
+ | `~/.skulto/repositories/` | Cloned git repositories |
+ | `~/.skulto/favorites.json` | Favorite skills (persists across DB resets) |
- # Run tests for a specific package
- go test ./internal/db/...
+ ## Common Tasks
- # Run AI-dependent tests (requires API keys)
- RUN_AI_TESTS=1 go test ./...
+ ### Build
- # Run with verbose output
- go test -v ./internal/config/...
+ ```bash
+ make build # Build skulto binary → ./build/skulto
+ make build-mcp # Build MCP server → ./build/skulto-mcp
+ make build-all # Build both binaries
+ make dev # Development build with race detector (requires CGO)
```
- ## CLI Subcommands
+ ### Run
- Skulto provides both an interactive TUI and CLI subcommands for scripting.
+ ```bash
+ ./build/skulto # Launch TUI
+ ./build/skulto <cmd> # Run CLI command (add, install, pull, etc.)
+ ```
- | Command | Purpose |
- |---------|---------|
- | `skulto` | Launch the interactive Bubble Tea TUI |
- | `skulto add <repo>` | Add a skill repository and sync its skills |
- | `skulto list` | List all configured source repositories with skill counts |
- | `skulto pull` | Pull/sync all skill repositories and reconcile installed skills |
- | `skulto remove [repo]` | Remove a skill repository (uninstalls skills, deletes from DB and disk) |
- | `skulto scan` | Scan skills for security threats (prompt injection, dangerous patterns) |
- | `skulto update` | Combined `pull` + `scan` with enhanced change reporting |
- | `skulto info <slug>` | Show detailed information about a specific skill |
+ ### Test
- ### Command Details
+ ```bash
+ make test # Run all tests with coverage → coverage.html
+ make test-race # Run tests with race detector
+ ```
- **`skulto add <repo>`** - Add a skill repository
- - Parses GitHub URLs: `owner/repo`, `https://github.com/owner/repo`, `git@github.com:owner/repo.git`
- - Clones repository and scans for skills
- - Flag: `--no-sync` to defer cloning
+ ### Lint & Format
- **`skulto pull`** - Sync all repositories
- - Clones/updates all registered repositories
- - Scans AI tool directories to detect installed skills
- - Reconciles database state with filesystem
+ ```bash
+ make lint # Run golangci-lint
+ make format # Format code with gofmt
+ make vet # Run go vet
+ ```
- **`skulto remove [repo]`** - Remove a repository
- - Interactive selection if no repo specified
- - Uninstalls all skills (removes symlinks)
- - Deletes skill records, source record, and git clone
- - Flag: `--force` to skip confirmation
+ ### Clean
- **`skulto scan`** - Security scanning
- - Scans for prompt injection and dangerous code patterns
- - Flags: `--all`, `--skill <id>`, `--source <owner/repo>`, `--pending`
- - Reports threat levels: CRITICAL, HIGH, MEDIUM, LOW
+ ```bash
+ make clean # Remove build artifacts and coverage files
+ ```
- **`skulto update`** - Pull + scan with reporting
- - Phase 1: Pull repositories
- - Phase 2: Security scan on new/updated skills
- - Phase 3: Summary report with change details
- - Flag: `--scan-all` to scan all skills
+ ### Ship (Push after checks)
- ## Testing & Quality Gates
+ ```bash
+ make ship_it # Build, lint, test, then push (via scripts/ship-it.sh)
+ ```
- ### Test Categories
+ ## Testing & Quality Gates
- 1. **Unit tests** - Fast, no external dependencies
- 2. **Integration tests** - May require network (git clone tests)
- 3. **AI tests** - Require API keys, gated by `RUN_AI_TESTS=1`
+ ### Running Tests
- ### AI Test Guard
+ Tests are located alongside source files in `*_test.go` files:
- Tests requiring LLM/embedding API keys use `testutil.SkipAITests(t)`:
+ ```bash
+ make test # Full test suite with coverage
+ go test ./internal/cli/... # Test specific package
+ go test -v -run TestSearch # Run specific test
+ ```
- ```go
- func TestSomethingWithAI(t *testing.T) {
- testutil.SkipAITests(t) // Skips unless RUN_AI_TESTS=1
+ ### Coverage
- apiKey := os.Getenv("OPENAI_API_KEY")
- if apiKey == "" {
- t.Skip("OPENAI_API_KEY not set")
- }
- // ...
- }
- ```
+ After running `make test`:
+ - `coverage.out` - Raw coverage data
+ - `coverage.html` - HTML report (open in browser)
- ### CI Pipeline
+ ### CI Expectations
- The CI workflow (`.github/workflows/ci.yml`) runs:
- 1. `make deps` - Install dependencies
- 2. `make lint` - Linting with golangci-lint
- 3. `make test` - All tests
- 4. Cross-platform builds (linux/darwin, amd64/arm64)
+ CI (`.github/workflows/ci.yml`) runs on every push to `main` and all PRs:
- ### Coverage Expectations
+ 1. **Lint** - `make lint` (golangci-lint)
+ 2. **Test** - `make test` with coverage
+ 3. **Build matrix** - Cross-compile for linux/darwin on amd64/arm64
- - Aim for meaningful coverage on business logic
- - Characterization tests exist for installer behavior
- - Integration tests cover scraper and search pipelines
+ All CI checks must pass before merging.
## Workflow Expectations
### Branching
- `main` is the primary branch
- - Feature branches: `feature/<name>`
- - Bug fixes: `fix/<name>`
+ - Feature branches should be prefixed with `feature/` or similar
+ - PRs require passing CI checks
### Commit Messages
Follow [Conventional Commits](https://www.conventionalcommits.org/):
```
feat(scraper): add support for new skill format
fix(tui): correct keybinding for search
docs(readme): update installation instructions
refactor(installer): extract symlink helper
test(db): add characterization tests
- chore(deps): update dependencies
+ chore(deps): update go-openai to v1.41
```
- ### Pre-Push Checklist
+ ### Code Style
- 1. `make format` - Format code
- 2. `make lint` - Pass linting
- 3. `make test` - Pass all tests
- 4. `make build` - Verify build succeeds
+ - Follow standard Go conventions
+ - Run `make format` before committing
+ - Write tests for new functionality
+ - Document exported functions
- Or use: `make ship_it` (runs build, lint, test, then pushes)
+ ## Architecture Notes
- ## Code Conventions
+ ### Three Interfaces, One Codebase
- ### Package Structure
+ Skulto exposes the same functionality through three interfaces:
- - `internal/` packages are private to the module
- - Each package has a primary file matching the package name (e.g., `db/db.go`)
- - Tests are co-located with source files (`*_test.go`)
+ 1. **CLI** (`internal/cli/`) - Cobra commands for scripting
+ 2. **TUI** (`internal/tui/`) - Bubble Tea interactive UI
+ 3. **MCP** (`internal/mcp/`) - Model Context Protocol server for AI tools
- ### Error Handling
+ All three use shared services:
+ - `internal/installer/InstallService` - Unified installation
+ - `internal/db/` - Database operations
+ - `internal/telemetry/` - Analytics tracking
- - Wrap errors with context: `fmt.Errorf("operation failed: %w", err)`
- - Return early on errors
- - Use `require.NoError(t, err)` in tests
+ ### Telemetry Consistency
- ### Configuration
+ **Important for maintainers**: The telemetry system (`internal/telemetry/`) tracks user actions across all three interfaces. When adding new user-facing features:
- - All config flows through `internal/config`
- - Configuration is read from environment variables only (no config file)
- - `Config.BaseDir` is the root for all data (`~/.skulto/`)
- - Repositories are cloned to `~/.skulto/repositories/`
- - Use `config.GetPaths(cfg)` for derived paths
+ 1. Define the event in `internal/telemetry/events.go`
+ 2. Add the tracking method to both `posthogClient` and `noopClient`
+ 3. Add the method signature to the `Client` interface in `client.go`
+ 4. Call the tracking method from CLI, TUI, AND MCP handlers
- ### Database
+ Current telemetry events are organized by surface area:
+ - **CLI events**: `EventCLICommandExecuted`, `EventRepoAdded`, etc.
+ - **TUI events**: `EventViewNavigated`, `EventSkillInstalled`, etc.
+ - **Session events**: `EventSessionSummary`, `EventAppStarted`, `EventAppExited`
- - GORM with SQLite backend
- - FTS5 for full-text search on skills
- - Models in `internal/models/`
- - Database operations in `internal/db/`
+ ### InstallService
- ## Documentation Duties
+ The `InstallService` (`internal/installer/service.go`) is the unified entry point for skill installation. It:
+ - Handles platform detection
+ - Manages symlink creation
+ - Tracks telemetry for installations
+ - Is used by CLI, TUI, and MCP
- ### When to Update README.md
+ ### Platform Registry
- - New user-facing features
- - Changed CLI commands or flags
- - Updated installation steps
- - Modified keybindings
+ Skulto supports 33 AI platforms. The platform registry is in `internal/installer/platforms.go`. Each platform defines:
+ - Detection method (command, directory)
+ - Global and project-level skill paths
+ - Display name and aliases
+ ## Documentation Duties
+
+ - Update `README.md` when features, setup steps, or CLI commands change
+ - Document new CLI commands with examples
+ - Update this `AGENTS.md` when adding new packages or significant architecture changes
+ - Plan documents go in `docs/plans/`
+
## Finish the Task Checklist
- After completing any task:
+ Before completing any task, verify:
- - [ ] Run `make format` and `make lint`
- - [ ] Run `make test` to verify no regressions
- - [ ] Update `README.md` and `AGENTS.md` if user-facing/project-changes changes were made
- - [ ] Update relevant docs if architecture changed
- - [ ] Commit with conventional commit format
+ - [ ] Code passes linter (`make lint`)
+ - [ ] Code is formatted (`make format`)
+ - [ ] All new code has tests
+ - [ ] All tests pass (`make test`)
+ - [ ] No new warnings introduced
+ - [ ] Update relevant docs (& `README.md` if significant changes)
+ - [ ] Summarize changes in conventional commit format
- ### Commit Template
+ ### Commit Summary Template
```
- <type>(<scope>): <description>
+ <type>(<scope>): <short description>
- [optional body]
+ <optional body explaining the "why">
+
+ <optional footer with breaking changes or issue refs>
```
- Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`
+ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `perf`