Part of the ado-aw documentation.
When extending the compiler:
- New CLI commands: Add variants to the
Commandsenum inmain.rs - New compile targets: Implement the
Compilertrait in a new file undersrc/compile/ - New front matter fields: Add fields to
FrontMatterinsrc/compile/types.rs - New template markers: Handle replacements in the target-specific compiler (e.g.,
standalone.rsoronees.rs) - New safe-output tools: Add to
src/safeoutputs/— implementToolResult,Executor, register inmod.rs,mcp.rs,execute.rs - New first-class tools: Create
src/tools/<name>/withmod.rsandextension.rs(CompilerExtension impl). Addexecute.rsif the tool has Stage 3 runtime logic. ExtendToolsConfigintypes.rs, add collection incollect_extensions() - New runtimes: Create
src/runtimes/<name>/withmod.rs(config types) andextension.rs(CompilerExtension impl). ExtendRuntimesConfigintypes.rs, add collection incollect_extensions() - Validation: Add compile-time validation for safe outputs and permissions
The codebase follows a colocation principle for tools and runtimes:
- Tools (
tools:front matter) live insrc/tools/<name>/— one directory per tool, containing both compile-time (extension.rs) and runtime (execute.rs) code. This means you can look at a single directory to understand everything a tool does. - Runtimes (
runtimes:front matter) live insrc/runtimes/<name>/— one directory per runtime, with config types inmod.rsand theCompilerExtensionimpl inextension.rs. - Infrastructure extensions (GitHub MCP, SafeOutputs MCP) that are always-on and not user-configured stay in
src/compile/extensions/. These are internal plumbing, not user-facing tools. - Safe outputs (
safe-outputs:front matter) stay insrc/safeoutputs/— they follow a different lifecycle (Stage 1 NDJSON → Stage 3 execution) and are notCompilerExtensionimplementations.
The src/compile/extensions/mod.rs file owns the CompilerExtension trait, the Extension enum, and collect_extensions(). It re-exports tool/runtime extension types from their colocated homes so the rest of the compiler can import them from a single path.
Runtimes and first-party tools declare their compilation requirements via the CompilerExtension trait (src/compile/extensions/mod.rs). Instead of scattering special-case if blocks across the compiler, each runtime/tool implements this trait and the compiler collects requirements generically:
pub trait CompilerExtension: Send {
fn name(&self) -> &str; // Display name
fn required_hosts(&self) -> Vec<String>; // AWF network allowlist
fn required_bash_commands(&self) -> Vec<String>; // Agent bash allow-list
fn prompt_supplement(&self) -> Option<String>; // Agent prompt markdown
fn prepare_steps(&self) -> Vec<String>; // Pipeline steps (install, etc.)
fn mcpg_servers(&self, ctx) -> Result<Vec<(String, McpgServerConfig)>>; // MCPG entries
fn required_awf_mounts(&self) -> Vec<AwfMount>; // AWF Docker volume mounts
fn validate(&self, ctx) -> Result<Vec<String>>; // Compile-time warnings
}To add a new runtime or tool: (1) create a directory under src/tools/ or src/runtimes/, (2) implement CompilerExtension in extension.rs, (3) add a variant to the Extension enum and a collection check in collect_extensions() in src/compile/extensions/mod.rs.