The Problem

Engineers using Claude Code or Codex get fast code generation but lose the discipline of spec‑driven design, test‑first development, and reproducible knowledge. The result is fragmented implementations, missing tests, and drifting requirements that make production hand‑off risky.

What This Does

pilot-shell bundles five self‑contained projects that together impose a production‑grade workflow on LLM‑generated code:

  • console/ – a TypeScript web dashboard and CLI that orchestrates the LLM, runs spec creation (/spec), TDD (/fix), and continuous quality gates. Core entry points are console/src/cli/adapters/index.ts and console/src/cli/handlers/index.ts.
  • pilot/ – the Python‑backed knowledge engine that stores specifications, memories, and the semantic graph (Semble/CodeGraph). Files such as pilot/hooks/_lib/util.py and pilot/hooks/_checkers/charset.py provide the validation layer.
  • launcher/ – a thin Node wrapper that launches the dashboard in a Docker container (launcher/ contains only executable TS files).
  • installer/ – the automated installer that configures the environment, pulls secrets, and seeds the vector store. The hub module installer/context.py is imported by 21 other modules.
  • scripts/ – one‑off utilities (e.g., scripts/build-hooks.js) used by CI.

All projects share the same Docker dev container (.devcontainer/Dockerfile) and a GitHub Actions CI pipeline (.github/workflows/*). The repo is deliberately split so each component can be versioned or replaced independently.

How It Is Wired

  1. Startupconsole/src/cli/adapters/index.ts registers adapters for Claude (claude-code.ts) and Codex (codex.ts). The adapter returns a Session object consumed by the handler layer.
  2. Command handlingconsole/src/cli/handlers/index.ts dispatches CLI verbs (spec, fix, build) to concrete handlers (session‑init.ts, user‑message.ts). Each handler builds a Context via console/src/services/context/ContextBuilder.ts.
  3. Context generationContextBuilder pulls stored specs from the Python pilot (pilot/hooks/_lib/util.py) through an HTTP MCP server (console/src/servers/mcp-server.ts). The server loads the knowledge graph and returns a JSON spec.
  4. Execution loop – The selected handler invokes console/src/services/context/ObservationCompiler.ts, which streams LLM observations to the TokenCalculator for cost‑aware prompting. Results are fed back to the UI (console/src/components/*) and persisted by installer/context.py.
  5. Persistenceinstaller/context.py (the highest‑degree hub) writes spec snapshots and vector embeddings to the local SQLite store used by the pilot. Because it is imported by 21 modules, any change here has a wide blast radius.
  6. CI/CD – GitHub Actions run npm ci in console/ and pip install -r requirements.txt (implicit in the Python installer) before executing the test suites (tests/ under each project). The workflow also builds the Docker image defined in .devcontainer/Dockerfile.

The import graph shows two small cycles (installer/steps/claude_files.pyinstaller/steps/pilot_files.py) that increase maintenance friction, and a handful of deep‑nesting hotspots (e.g., installer/steps/dependencies.py).

How To Use It

# Clone the repo
git clone https://github.com/moses-y/pilot-shell
cd pilot-shell

# Build the dev container (Docker required)
docker build -f .devcontainer/Dockerfile -t pilot-shell-dev .

# Install the Node front‑end
cd console
npm ci

# Run the installer (creates .env.example, seeds vector store)
cd ../installer
python -m installer.cli install   # entry point defined in installer/cli.py

# Start the dashboard
cd ../console
npm run dev   # starts Vite dev server on http://localhost:5173

The installer expects a Claude or OpenAI token in docs/site/.env.development (currently committed – see health section). After the dev server is running, the CLI can be invoked directly, e.g.:

node console/src/cli/commands.ts spec new-feature

Real‑World Use

A team adds a new microservice: they run pilot-shell console spec new-service, write a high‑level requirement, and the system scaffolds a TDD suite, generates skeleton code, and stores the spec in the shared vector store. Subsequent developers can query the knowledge graph (pilot/ APIs) to retrieve rationale, reducing onboarding time and preventing duplicate effort.

Code Health & Issues

  • Critical – Secrets in workflow .github/workflows/claude.yml (CLAUDE_CODE_OAUTH_TOKEN).
  • High – Tracked .env.development in docs/site/; unpinned GitHub Action (anthropics/claude-code-action@v1); continue‑on‑error in release-dev.yml; direct push to main in release.yml.
  • Medium – Base image not pinned in .devcontainer/Dockerfile; checkout persists credentials in deploy-website.yml.
  • Low – No timeout on claude.yml jobs.
  • Resource safetyopen(...) without context manager in installer/ui.py and two pilot hooks.
  • Resilience – Broad except: clauses in installer/platform_utils.py and related steps.
  • Cognitive load – Deep nesting (up to 8 levels) and oversized files (installer/steps/dependencies.py ≈ 1.5 k LOC).
  • Soundness – Circular imports between installer/steps/claude_files.py and installer/steps/pilot_files.py.
  • Clarity – Hub module installer/context.py is a churn hotspot.
  • Duplication – Repeated UI snippets across 17 component files in docs/site/src/components/.

All findings stem from deterministic static analysis; no additional issues were inferred.

The Bottom Line

pilot-shell provides a concrete, spec‑driven wrapper around Claude Code/Codex that enforces TDD, persistent memory, and CI checks. The architecture is modular, but the installer and context hub are high‑impact change points, and several security‑related secrets are currently exposed. Teams ready to adopt LLM‑assisted development can benefit, provided they remediate the critical secret leaks and tighten the most tangled modules.