CLI Overview
GospeLib ships a single gl command that acts as the unified entry point for all developer workflows — starting services, running tests, downloading corpus data, managing infrastructure, and more. Two developers working on the same subcommand independently should produce nearly identical user experiences because every CLI tool in the repo follows this shared specification.
The design optimizes for three audiences:
- User friendliness — intuitive subcommands, beautiful output, sensible defaults
- Machine friendliness — structured JSON output, composable flags, deterministic exit codes
- Developer friendliness — modular code, canonical library stack, easy extensibility
Architecture
gl is a Python Click application packaged at tools/cli/ and installed as the gl entry point. It acts as the top-level command group, dispatching to subcommand groups. Each group may be implemented in Python (preferred), Go, or Bash (constrained), but is always invocable through gl.
┌──────────────────────────────────────────────────────────────────┐
│ gl (Click group) │
│ │
│ gl dev gl infra gl test gl lint gl codegen gl db │
│ gl download gl ingest gl health gl setup gl format │
│ gl config gl doctor │
│ │
│ Dispatches to: │
│ • Python Click subcommands (same process) │
│ • Thin wrappers around existing pnpm/nx/docker/uv commands │
│ • Existing Python CLI entry points (gospelib-download, etc.) │
└──────────────────────────────────────────────────────────────────┘
Each group is a click.Group registered on the root group via cli.add_command(). Groups that wrap existing tools (e.g., gl download wrapping gospelib-download) delegate to the existing entry point rather than duplicating logic.
Command Structure
gl <group> <command> [args...] [flags...]
Naming rules:
- Groups are nouns or verb-noun pairs —
gl dev,gl codegen - Commands within a group are verbs or action words —
gl dev start,gl infra up - Flags use
--kebab-casefor long form and single-letter-xfor short form - Positional arguments are used sparingly — only when the argument is unambiguous (e.g.,
gl test content)
Command Group Taxonomy
| Group | Purpose | Commands |
|---|---|---|
gl dev | Development workflows — start/stop services and apps | start, stop, restart, logs, status |
gl infra | Infrastructure — Docker Compose data stores | up, down, reset, logs, status |
gl test | Run tests across all stacks | run, watch, coverage |
gl lint | Lint code across all stacks | run, fix |
gl format | Code formatting | run, check |
gl codegen | Code generation (errors, types, OpenAPI) | errors, types, openapi |
gl db | Database operations | migrate, seed, reset, status |
gl download | Corpus downloading (wraps gospelib-download) | run, list-drivers, list-schemas, list-catalog, interactive |
gl ingest | Ingest pipeline operations (wraps gospelib-ingest) | run, status, validate |
gl health | Service and infrastructure health checks | (runs dashboard directly) |
gl setup | Environment setup | (runs setup directly) |
gl config | Configuration management | show, set, path |
gl doctor | Diagnose common environment problems | (runs diagnostics directly) |
Installation
The gl command is available on PATH inside the devcontainer automatically — no manual setup required.
Package location: tools/cli/
pyproject.toml entry point:
[project.scripts]
gl = "gospelib_cli.main:cli"
The devcontainer post-create.sh script handles installation:
# Install gl CLI
echo "==> Installing gl CLI..."
cd tools/cli && uv sync && cd ../..
echo 'export PATH="/workspaces/main/tools/cli/.venv/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/workspaces/main/tools/cli/.venv/bin:$PATH"' >> ~/.bashrc
# Override zsh git plugin's gl alias
echo 'unalias gl 2>/dev/null; true' >> ~/.zshrc
After container creation, verify:
which gl # Should resolve to the installed entry point
gl --version # Should print the current version
The Oh My Zsh git plugin defines alias gl='git pull'. The devcontainer setup overrides this automatically, but if gl invokes git pull instead of the CLI, run:
unalias gl
Or restart your shell. The post-create.sh script appends unalias gl 2>/dev/null; true to ~/.zshrc after the Oh My Zsh source line.
Root Command Behavior
Running gl with no arguments displays a status dashboard showing the installed version, all command groups, current infrastructure status, and a usage hint.
╭─────────────────────────────────────────────────╮
│ GospeLib CLI v0.1.0 │
╰─────────────────────────────────────────────────╯
dev Development workflows (start, stop, logs)
infra Infrastructure management (up, down, reset)
test Run tests (JS, Python, Go)
lint Lint code across stacks
format Format code (Prettier, Ruff)
codegen Generate code (errors, types, openapi)
db Database operations (migrate, seed, reset)
download Download corpus data from external sources
ingest Run the data ingest pipeline
health Check service and infrastructure health
setup Run first-time environment setup
config View and manage configuration
doctor Diagnose environment problems
Run gl <group> --help for details on any group.
What's Next
- Visual Design Language — colors, typography, progress indicators, and output styling
- Help & Commands — help system design and command design patterns
- Output & Logging — output formats, filtering, and verbosity levels
- Configuration — configuration hierarchy and error handling
- Code Organization — package layout, library standards, and testing
- Migration Plan — migrating existing scripts to the
glCLI