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 areconsole/src/cli/adapters/index.tsandconsole/src/cli/handlers/index.ts.pilot/– the Python‑backed knowledge engine that stores specifications, memories, and the semantic graph (Semble/CodeGraph). Files such aspilot/hooks/_lib/util.pyandpilot/hooks/_checkers/charset.pyprovide 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 moduleinstaller/context.pyis 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
- Startup –
console/src/cli/adapters/index.tsregisters adapters for Claude (claude-code.ts) and Codex (codex.ts). The adapter returns aSessionobject consumed by the handler layer. - Command handling –
console/src/cli/handlers/index.tsdispatches CLI verbs (spec,fix,build) to concrete handlers (session‑init.ts,user‑message.ts). Each handler builds aContextviaconsole/src/services/context/ContextBuilder.ts. - Context generation –
ContextBuilderpulls 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. - Execution loop – The selected handler invokes
console/src/services/context/ObservationCompiler.ts, which streams LLM observations to theTokenCalculatorfor cost‑aware prompting. Results are fed back to the UI (console/src/components/*) and persisted byinstaller/context.py. - Persistence –
installer/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. - CI/CD – GitHub Actions run
npm ciinconsole/andpip 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.py ↔ installer/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.developmentindocs/site/; unpinned GitHub Action (anthropics/claude-code-action@v1); continue‑on‑error inrelease-dev.yml; direct push tomaininrelease.yml. - Medium – Base image not pinned in
.devcontainer/Dockerfile; checkout persists credentials indeploy-website.yml. - Low – No timeout on
claude.ymljobs.
- Resource safety –
open(...)without context manager ininstaller/ui.pyand two pilot hooks. - Resilience – Broad
except:clauses ininstaller/platform_utils.pyand 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.pyandinstaller/steps/pilot_files.py. - Clarity – Hub module
installer/context.pyis 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.