Skip to content

Internals — contributor guide ​

This directory is the source map for people who change devctl itself. It is not the product manual. Users of the CLI, TUI, MCP, or YAML config should start at docs/README.md.

The user wiki and MCP search_docs / get_doc tools only index the top-level pages under docs/. These internals pages live next to that documentation so they stay in the repo and on the VitePress site, without mixing into the operator wiki.

docs/architecture.md is the short layer map CI enforces. This guide is the file-by-file map of the running TypeScript tree.

This file is the docs-site index (/internals/). GitHub’s folder view uses README.md — keep the two in sync if you edit the hub.

What this guide is ​

A file-by-file orientation of the repository: how two processes talk, which layer owns which decision, how a keystroke or devctl start becomes a spawned process, and how to add a feature without violating hexagonal rules.

It does not re-teach YAML for services, IAP audiences, or TUI keybinds. Those remain in the user pages. When an internals page needs product context, it links out.

Start with the system map for the client/daemon boundary, service lifecycle, and identity and observability flows. Then use the reading order below to explore each subsystem.

Read in this order ​

New contributors should follow this path once. After that, jump by subsystem.

StepPageWhy
1How to read the codeMental model, first files to open, how to chase a behavior
2Repository mapEvery top-level directory and what it is not
3Process modelClient vs supervisor, lock, socket, attach vs spawn
4LayersImport rules, composition roots, what CI actually checks
5Bootstrapbin.ts → createClient / createDaemon
6RPCLine-delimited JSON, methods, auth token, events
7DomainTypes and policies with no I/O
8ApplicationCommands, orchestrator, health monitor
9PortsEvery replaceable boundary
10AdaptersDaemon, config, process, Google, proxy, storage
11PresentationCLI, TUI, MCP, loopback web UI
12Config pipelineDiscover → decode → merge → validate → snapshot
13RuntimeStart/stop waves, processes, containers, reload
14Identity and proxyTokens, impersonation, IAP, HTTP recipes
15Logs, telemetry, LLMRing buffer, worker, OTLP, LiteLLM
16Events and errorsBus facts vs command calls; exit codes
17Testing and CIbun test, architecture, coverage, hygiene
18PackagingCompiled binary, npm launcher, Homebrew, docs site
19Adding a featureChecklists for RPC, CLI, TUI, MCP, config fields

Hard rules that show up everywhere ​

  1. Nothing in the application hard-codes a service name, port, or service account. Those come from .devctl/ after load.
  2. Presentation never starts or kills processes. CLI, TUI, MCP, and the web UI call application commands or the Controller. ProcessRuntime lives in adapters.
  3. Commands are calls. Events are facts that already happened. Do not drive start/stop through Bus.
  4. Google Cloud is an adapter. Local-only configs must run with no ADC.
  5. One composition root per process: bootstrap/client.ts and bootstrap/daemon.ts. No DI container.

Day-to-day commands: CONTRIBUTING.md. Layer checker: architecture.md.

Released under the MIT License. Use at your own risk.