Skip to main content

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 pairsgl dev, gl codegen
  • Commands within a group are verbs or action wordsgl dev start, gl infra up
  • Flags use --kebab-case for long form and single-letter -x for short form
  • Positional arguments are used sparingly — only when the argument is unambiguous (e.g., gl test content)

Command Group Taxonomy

GroupPurposeCommands
gl devDevelopment workflows — start/stop services and appsstart, stop, restart, logs, status
gl infraInfrastructure — Docker Compose data storesup, down, reset, logs, status
gl testRun tests across all stacksrun, watch, coverage
gl lintLint code across all stacksrun, fix
gl formatCode formattingrun, check
gl codegenCode generation (errors, types, OpenAPI)errors, types, openapi
gl dbDatabase operationsmigrate, seed, reset, status
gl downloadCorpus downloading (wraps gospelib-download)run, list-drivers, list-schemas, list-catalog, interactive
gl ingestIngest pipeline operations (wraps gospelib-ingest)run, status, validate
gl healthService and infrastructure health checks(runs dashboard directly)
gl setupEnvironment setup(runs setup directly)
gl configConfiguration managementshow, set, path
gl doctorDiagnose 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
zsh Alias Conflict

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.

Dashboard Preview
╭─────────────────────────────────────────────────╮
│ 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