devgrep
Install

Architecture

devgrep is a local-first CLI built around four small layers — indexers, storage, search, and commands/TUI.

┌─────────────────────────────────────────────────────────────┐
│                     Cobra CLI (cmd/)                        │
│   search · index · stats · sources · doctor · version       │
└───────────────────────────┬─────────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        ▼                   ▼                   ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│   Indexers    │   │ Search Engine │   │  Bubble Tea   │
│ shell-history │   │ fuzzy + rank  │   │     TUI       │
│ logs · notes  │   │ typo fallback │   │  (internal/  │
│ (Indexer IF)  │   │               │   │     tui)      │
└───────┬───────┘   └───────┬───────┘   └───────────────┘
        │                   │
        └─────────┬─────────┘
                  ▼
        ┌─────────────────────┐
        │   SQLite (WAL)      │
        │ ~/.local/share/     │
        │   devgrep/devgrep.db│
        │ documents · states  │
        │ watched_paths · …   │
        └─────────────────────┘
                  ▲
                  │ fsnotify (watch mode)
        ┌─────────┴─────────┐
        │  Local files only   │
        │ history · logs · md │
        └─────────────────────┘

Command layer

cmd/ defines the Cobra tree: search, index, stats, sources, doctor, version. The root command applies direct-search fallback — if the first non-flag argument is not a known subcommand, args are rewritten to search.

Package layout mirrors responsibilities:

  • internal/history — bash and zsh history parsing
  • internal/logs — log indexing and tail mode
  • internal/indexer — pluggable Indexer interface and markdown indexer
  • internal/storage — SQLite migrations and prepared statements
  • internal/search — fuzzy search and plain formatting
  • internal/ranking — scoring model
  • internal/tui — Bubble Tea interface
  • internal/doctor — health checks

Indexers

Phase 1 sources are shell history, .log files, and markdown notes. Each source implements the Indexer interface so future sources (Docker logs, Git history, CI logs) can be added without changing command code.

File discovery uses centralized ignore logic in internal/utils, shared by normal indexing, dry-run, and watch re-indexing. The policy skips configured directories, huge files, media, binaries, and archives before parsers run.

SQLite storage

Default path: ~/.local/share/devgrep/devgrep.db

WAL mode, busy timeout, prepared statements, and source state for incremental indexing.

Tables

  • documents — indexed commands, log lines, notes
  • source_states — file offsets and modification metadata
  • search_stats — local query frequency
  • index_runs — indexing performance history
  • schema_migrations — applied schema versions
  • watched_paths — directories restored by watch mode

The sources command reads document metadata and groups locations without duplicating paths.

Ranking

Ranking blends configurable weights:

yaml
ranking:
  fuzzy: 0.38
  recency: 0.26
  frequency: 0.10
  exact: 0.16
  command_length: 0.02
  directory_relevance: 0.08

Fuzzy match quality drives primary scoring; typo-tolerant fallback ranking handles near matches. Recency and usage frequency come from document metadata and search_stats.

Watch mode

Explicit index paths are persisted in watched_paths. Foreground watch uses fsnotify with 500ms debounced re-indexing, reuses the same indexers, and deletes documents when files are removed.

Shell history files are always added to the watcher set alongside configured directories.

Parser system

Each indexer owns parsing logic:

  • History indexers read bash/zsh formats with deduplication
  • Log indexer detects severity levels and respects max file size
  • Note indexer walks markdown files under configured paths

Normalized documents share a common schema in storage regardless of source type.

Privacy

No telemetry, background network calls, accounts, or cloud API. All indexing and search operate on local files only. See the FAQ for database size and offline behavior.