Building from source
The application lives in app/. Runtime is Bun. The TUI is OpenTUI.
export PATH="$HOME/.bun/bin:$PATH"
cd app
bun install
bun run src/bin.ts --help
bun test
bun run check:coverage
bun run typecheck
bun run typecheck:web
bun run check:architecture
bun run check:dead
bun run check:dupFrom the repository root (after bun install in app/):
bun run app/src/bin.ts
cd app && bun link # optional: `devctl` on PATHLayout
| Path | Role |
|---|---|
app/src/bin.ts | Entry |
app/src/bootstrap/ | Composition roots (daemon + client) |
app/src/application/client-runtime.ts | Injected CLI/TUI operations and controller contract |
app/src/presentation/cli/ | Commander CLI |
app/src/presentation/tui/ | OpenTUI screens and overlays |
app/src/presentation/tui/hooks/ | Client queries, command execution, and TUI state |
app/src/presentation/tui/helpers/ | Screen-specific formatting, navigation, logs, and plan helpers |
app/src/presentation/mcp/ | Streamable HTTP MCP server |
app/src/presentation/web/ | Loopback telemetry web UI (SPA is authored in app/web/ and embedded here) |
app/src/domain/ | Service, identity, config, log, session, and preference types and policies |
app/src/adapters/config/ | Discover, decode, merge, validate |
app/src/adapters/process/ | Host process runtime |
app/src/adapters/google/ | Google / IAP / tokens |
app/src/adapters/daemon/supervisor.ts | Daemon host (socket, recovery, watch, listeners) |
app/src/adapters/rpc/controller.ts | Local supervisor or socket / named-pipe client |
app/tui.json | Starter TUI preferences |
Layer rules: architecture.md. Check with bun run check:architecture. Coverage: bun run check:coverage (aggregate funcs/lines; OpenTUI screens and hooks are ignored). Unused files and dependencies: bun run check:dead (Knip). Copy-paste clones: bun run check:dup (jscpd).
There is no separate Go tree.
TUI preferences
Configuration is tui.json or tui.jsonc: theme, keybinds, leader_timeout, font_size, mouse, scroll_speed, log_timestamps, log_metadata, mcp_enabled, mcp_port, mcp_disabled_tools.
mcp_disabled_tools is a deny-list of MCP tool names (empty means every tool is available). See MCP.
Search order:
Settings writes go to ~/.devctl/tui.json unless the env override is set (then changes apply for this session only).
keybinds merge with the built-in defaults, so you only override what you change. Defaults use cmd on macOS and ctrl on Linux/Windows (command+c / ctrl+c in the TUI).
{
"theme": "devctl",
"leader_timeout": 2000,
"keybinds": {
"leader": "ctrl+x",
"command_list": "ctrl+p"
},
"mouse": true,
"mcp_enabled": false,
"mcp_disabled_tools": []
}Tests
cd app && bun testIntegration tests that need Google stay skipped unless credentials are present.