$env:DOTBOT_HOME and are resolved at runtime by a layered content resolver - no framework code is copied into your project by default. Running dotbot init creates only the project’s .bot/workspace/ tree (tracked in git) and a .bot/.gitignore.
Three core systems
MCP server
A pure PowerShell stdio MCP server implementing protocol version 2024-11-05. Tools are auto-discovered fromsrc/mcp/tools/{tool-name}/ subdirectories, and no registration is needed. The server exposes 31 tools across task management, session management, plans, decisions, steering, workflow control, and dev lifecycle. Because tools are file-based, you can add custom tools by dropping a metadata.json and script.ps1 into a new subfolder.
Web UI
A pure PowerShell HTTP server with a vanilla JS frontend. Seven tabs: Overview, Product, Roadmap, Processes, Decisions, Workflow, Settings. The default port is 8686; the server auto-selects the next available port if 8686 is busy. Launch the UI withdotbot go from your project root.
Runtime
Manages AI CLI invocations as tracked processes. The runtime handles git worktree isolation and coordinates two-phase execution (analysis then execution) for each task. AI provider invocations are normalised through a pluggable adapter layer in Dotbot.Harness, which ships adapters for Claude Code, Codex, Antigravity, Copilot, and OpenCode. An HTTP control plane (Dotbot.Runtime) exposes workflow run state over a local endpoint consumed by the dashboard, CLI commands, and the MCP server..bot/ directory layout
dotbot init creates two items: a workspace/ tree tracked in git, and a .gitignore that excludes machine-local state.
.bot/ under specific conditions.
Content resolution
Framework content (agents, skills, prompts, workflows, stacks, MCP tools, hooks) lives in the dotbot install directory at$env:DOTBOT_HOME. The layered content resolver checks .bot/content/<type>/<name>/ first; if no project-level override exists, it falls back to $env:DOTBOT_HOME/content/<type>/<name>/. Your project only needs to include the files it wants to customise.
Stacks follow the same pattern. A stack like dotnet-blazor declares extends: dotnet in its manifest; the resolver applies settings in dependency order and deep-merges them: framework defaults, then workflow settings, then stack settings. Settings declared closer to the project always win.
Runtime modules
The runtime is implemented as 19 PowerShell modules undersrc/runtime/Modules/ in the dotbot install directory.
HTTP runtime
Dotbot.Runtime runs as an in-process HTTP server whendotbot go or dotbot serve starts. It publishes its address to .bot/.control/runtime.json so the UI server, MCP server, and CLI commands like dotbot runtime-status can discover it without hard-coded ports.
- HttpServer - listener loop, request routing, and token authentication.
- ControlPlaneClient - outbound registration with an optional mothership dashboard in fleet mode.
- EndpointDiscovery - resolves the runtime URL from environment variables, settings, or the connection file.
- Lifecycle - start, stale-PID detection, and graceful shutdown.
Runtime state: .bot/.control/ vs .bot/workspace/
dotbot separates ephemeral machine-local state from durable version-controlled state into two distinct directories.
.bot/.control/ - gitignored, machine-local
This directory is always gitignored. It contains:
Do not commit anything from
.bot/.control/.
.bot/workspace/ - version-controlled
This directory is committed to git. Every team member sees the same task queue, session history, product documents, and plans through standard git history.
Committing
workspace/ to git means every task, question, answer, decision, and code change is auditable by your entire team through standard git tooling.
Git worktree isolation
Eachprompt and prompt_template task runs in its own git branch (task/{short-id}-{slug}) and a separate worktree directory (../worktrees/{repo}/task-{short-id}-{slug}/). On completion, the task branch is squash-merged back to the main branch and the worktree is cleaned up. This approach keeps the main working tree clean during concurrent execution and makes per-task rollback trivial.
script, mcp, and task_gen tasks skip worktree isolation and run directly in the project root. This is safe because those task types do not invoke the AI and make deterministic, auditable changes that do not require branch isolation.