diff --git a/AGENTS.md b/AGENTS.md index d5fc0b15..0e4e3bbb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -409,7 +409,7 @@ The compiler transforms the input into valid Azure DevOps pipeline YAML based on - **Standalone**: Uses `templates/base.yml` - **1ES**: Uses `templates/1es-base.yml` -Explicit markings are embedded in these templates that the compiler is allowed to replace e.g. `{{ agency_params }}` denotes parameters which are passed to the agency command line tool. The compiler should not replace sections denoted by `${{ some content }}`. What follows is a mapping of markings to responsibilities (primarily for the standalone template). +Explicit markings are embedded in these templates that the compiler is allowed to replace e.g. `{{ copilot_params }}` denotes parameters which are passed to the copilot command line tool. The compiler should not replace sections denoted by `${{ some content }}`. What follows is a mapping of markings to responsibilities (primarily for the standalone template). ## {{ repositories }} For each additional repository specified in the front matter append: @@ -478,19 +478,16 @@ This distinction allows resources (like templates) to be available as pipeline r Should be replaced with the human-readable name from the front matter (e.g., "Daily Code Review"). This is used for display purposes like stage names. -## {{ agency_params }} +## {{ copilot_params }} -Additional params provided to agency CLI. The compiler generates: +Additional params provided to copilot CLI. The compiler generates: - `--model ` - AI model from `engine` front matter field (default: claude-opus-4.5) -- `--max-turns ` - Maximum agentic turns from `engine.max-turns` (omitted when not set) -- `--max-timeout ` - Workflow timeout in minutes from `engine.timeout-minutes` (omitted when not set) - `--disable-builtin-mcps` - Disables all built-in MCPs initially - `--no-ask-user` - Prevents interactive prompts - `--allow-tool ` - Explicitly allows specific tools (github, safeoutputs, write, shell commands like cat, date, echo, grep, head, ls, pwd, sort, tail, uniq, wc, yq) -- `--disable-mcp-server ` - Disables specific MCPs (all built-in MCPs are disabled by default and must be explicitly enabled via mcp-servers config) -- `--mcp ` - Enables MCPs specified in front matter +- `--disable-mcp-server ` - Disables specific Copilot CLI MCPs -Only built-in MCPs are passed via params. Custom MCPs (with command field) are handled separately. +All MCPs (both built-in and custom) are handled via the MCP firewall config, not via `--mcp` flags. ## {{ pool }} @@ -559,7 +556,7 @@ Should be replaced with the appropriate working directory based on the effective - `root`: `$(Build.SourcesDirectory)` - the checkout root directory - `repo`: `$(Build.SourcesDirectory)/$(Build.Repository.Name)` - the repository's subfolder -This is used for the `workingDirectory` property of the agency copilot task. +This is used for the `workingDirectory` property of the copilot task. ## {{ source_path }} @@ -733,16 +730,16 @@ Should be replaced with the agent context root for 1ES Agency jobs. This determi ## {{ mcp_configuration }} -Should be replaced with the MCP server configuration for 1ES templates. For each enabled built-in MCP, generates service connection references: +Should be replaced with the MCP server configuration for 1ES templates. For each `mcp-servers:` entry without a `command:` field, generates a service connection reference using the entry name: ```yaml -ado: - serviceConnection: mcp-ado-service-connection -kusto: - serviceConnection: mcp-kusto-service-connection +my-mcp: + serviceConnection: mcp-my-mcp-service-connection +other-mcp: + serviceConnection: mcp-other-mcp-service-connection ``` -Custom MCP servers (with `command:` field) are not supported in 1ES target. Only built-in MCPs with corresponding service connections are supported. +Custom MCP servers (with `command:` field) are not supported in 1ES target. Only entries without a `command:` (which have a corresponding service connection) are supported. ## {{ global_options }} @@ -1126,30 +1123,7 @@ cargo add ## MCP Configuration -The `mcp-servers:` field provides a unified way to configure both built-in and custom MCP (Model Context Protocol) servers. The compiler distinguishes between them by checking for the `command:` field—if present, it's a custom server; otherwise, it's a built-in. - -### Built-in MCP Servers - -Enable built-in servers with `true` or configure them with options: - -```yaml -mcp-servers: - ado: true # enabled with all default functions - ado-ext: true # Extended ADO functionality - asa: true # Azure Stream Analytics MCP - bluebird: true # Bluebird MCP - calculator: true # Calculator MCP - es-chat: true - icm: # enabled with restricted functions - allowed: - - create_incident - - get_incident - kusto: - allowed: - - query - msft-learn: true - stack: true # Stack MCP -``` +The `mcp-servers:` field configures custom MCP (Model Context Protocol) servers that the agent can use. Each entry must include a `command:` field specifying the executable to spawn. ### Custom MCP Servers @@ -1167,28 +1141,16 @@ mcp-servers: ### Configuration Properties -**For built-in MCPs:** -- `true` - Enable with all default functions -- `allowed:` - Array of function names to restrict available tools -- `service-connection:` - (1ES target only) Override the service connection name used for this MCP. If not specified, defaults to `mcp--service-connection` (e.g., `mcp-ado-service-connection` for the `ado` MCP) - -**For custom MCPs (requires `command:`):** - `command:` - The executable to run (e.g., `"node"`, `"python"`, `"dotnet"`) - `args:` - Array of command-line arguments passed to the command - `allowed:` - Array of function names agents are permitted to call (required for security) - `env:` - Optional environment variables for the MCP server process +- `service-connection:` - (1ES target only) Override the service connection name used for this MCP. If not specified, defaults to `mcp--service-connection` -### Example: Mixed Configuration +### Example: Multiple Custom MCP Servers ```yaml mcp-servers: - # Built-in servers - ado: true - ado-ext: true - es-chat: true - icm: - allowed: [create_incident, get_incident] - # Custom Python MCP server data-processor: command: "python" @@ -1214,7 +1176,6 @@ mcp-servers: 2. **Command Validation**: The compiler validates that commands are from a trusted set 3. **Argument Sanitization**: Arguments are validated to prevent injection attacks 4. **Environment Isolation**: MCP servers run in the same isolated sandbox as the pipeline -5. **Built-in Trust**: Built-in MCPs are pre-vetted; custom MCPs require explicit `allowed:` list ## Network Isolation (AWF) @@ -1330,17 +1291,13 @@ When agents are configured with multiple MCPs (e.g., `ado`, `kusto`, `icm`), the ``` ┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐ -│ │ │ │ │ ado MCP │ -│ Agent │────▶│ MCP Firewall │────▶│ (agency mcp ado)│ -│ (Agency) │ │ │ └─────────────────┘ +│ │ │ │ │ custom MCP │ +│ Agent │────▶│ MCP Firewall │────▶│ (node server.js)│ +│ (Copilot) │ │ │ └─────────────────┘ │ │ │ - Policy check │ ┌─────────────────┐ -└─────────────┘ │ - Tool routing │────▶│ icm MCP │ - │ - Audit logging │ │ (agency mcp icm)│ +└─────────────┘ │ - Tool routing │────▶│ custom MCP │ + │ - Audit logging │ │ (python -m ...) │ └──────────────────┘ └─────────────────┘ - ┌─────────────────┐ - ────▶│ custom MCP │ - │ (node server.js)│ - └─────────────────┘ ``` ### Configuration File Format @@ -1350,23 +1307,11 @@ The firewall reads a JSON configuration file at runtime: ```json { "upstreams": { - "ado": { - "command": "agency", - "args": ["mcp", "ado"], - "env": {}, - "allowed": ["*"] - }, - "icm": { - "command": "agency", - "args": ["mcp", "icm"], - "env": {}, - "allowed": ["create_incident", "get_incident"] - }, - "kusto": { - "command": "agency", - "args": ["mcp", "kusto"], - "env": {}, - "allowed": ["query"] + "data-processor": { + "command": "python", + "args": ["-m", "my_mcp_server"], + "env": { "DATA_DIR": "/data" }, + "allowed": ["process_data", "query_database"] }, "custom-tool": { "command": "node", @@ -1405,9 +1350,8 @@ The `allowed` field supports several patterns: All tools exposed by the firewall are namespaced with their upstream name: -- `ado:create-work-item` - from the `ado` upstream -- `icm:create_incident` - from the `icm` upstream -- `kusto:query` - from the `kusto` upstream +- `data-processor:process_data` - from the `data-processor` upstream +- `custom-tool:get_status` - from the `custom-tool` upstream This prevents tool name collisions and makes it clear which upstream handles each call. @@ -1423,8 +1367,8 @@ ado-aw mcp-firewall --config /path/to/config.json The firewall is automatically configured in generated pipelines: 1. **Config Generation**: The compiler generates `mcp-firewall-config.json` from the agent's `mcp-servers:` front matter -2. **MCP Registration**: The firewall is registered in the agency MCP config as `mcp-firewall` -3. **Runtime Launch**: When agency starts, it launches the firewall which spawns upstream MCPs +2. **MCP Registration**: The firewall is registered in the copilot MCP config as `mcp-firewall` +3. **Runtime Launch**: When copilot starts, it launches the firewall which spawns upstream MCPs The firewall config is written to `$(Agent.TempDirectory)/staging/mcp-firewall-config.json` in its own pipeline step, making it easy to inspect and debug. @@ -1433,9 +1377,9 @@ The firewall config is written to `$(Agent.TempDirectory)/staging/mcp-firewall-c All tool call attempts are logged to the centralized log file at `$HOME/.ado-aw/logs/YYYY-MM-DD.log`: ``` -[2026-01-29T10:15:32Z] [INFO] [firewall] ALLOWED icm:create_incident (args: {"title": "...", "severity": 3}) -[2026-01-29T10:15:45Z] [INFO] [firewall] BLOCKED icm:delete_incident (not in allowlist) -[2026-01-29T10:16:01Z] [INFO] [firewall] ALLOWED kusto:query (args: {"cluster": "...", "query": "..."}) +[2026-01-29T10:15:32Z] [INFO] [firewall] ALLOWED custom-tool:process_data (args: {"input": "..."}) +[2026-01-29T10:15:45Z] [INFO] [firewall] BLOCKED custom-tool:delete_all (not in allowlist) +[2026-01-29T10:16:01Z] [INFO] [firewall] ALLOWED data-processor:query_database (args: {"query": "..."}) ``` This provides a complete audit trail of agent actions for security review. diff --git a/src/compile/common.rs b/src/compile/common.rs index 51432e7c..891f48de 100644 --- a/src/compile/common.rs +++ b/src/compile/common.rs @@ -2,11 +2,11 @@ use anyhow::{Context, Result}; -use super::types::{FrontMatter, McpConfig, Repository, TriggerConfig}; +use super::types::{FrontMatter, Repository, TriggerConfig}; use crate::fuzzy_schedule; use crate::mcp_metadata::McpMetadataFile; -/// Check if an MCP name is a built-in (launched via agency mcp) +/// Check if an MCP name is a built-in (known to the Copilot CLI via mcp-metadata.json) pub fn is_builtin_mcp(name: &str) -> bool { let metadata = McpMetadataFile::bundled(); metadata.get(name).map(|m| m.builtin).unwrap_or(false) @@ -337,7 +337,7 @@ pub fn generate_copilot_params(front_matter: &FrontMatter) -> String { for tool in allowed_tools { if tool.contains('(') || tool.contains(')') || tool.contains(' ') { - // Use double quotes - the agency_params are embedded inside a single-quoted + // Use double quotes - the copilot_params are embedded inside a single-quoted // bash string in the AWF command, so single quotes would break quoting. params.push(format!("--allow-tool \"{}\"", tool)); } else { @@ -349,22 +349,6 @@ pub fn generate_copilot_params(front_matter: &FrontMatter) -> String { params.push(format!("--disable-mcp-server {}", mcp)); } - for (name, config) in &front_matter.mcp_servers { - let is_custom = matches!(config, McpConfig::WithOptions(opts) if opts.command.is_some()); - if is_custom { - continue; - } - - let is_enabled = match config { - McpConfig::Enabled(enabled) => *enabled, - McpConfig::WithOptions(_) => true, - }; - - if is_enabled { - params.push(format!("--mcp {}", name)); - } - } - params.join(" ") } @@ -612,11 +596,7 @@ fn normalize_relative_path(path: &std::path::Path) -> Option { /// traversal reaches the filesystem root without finding one. fn find_git_root(path: &std::path::Path) -> Option { // Start from the file's parent directory (or the path itself if it is a dir). - let start: &std::path::Path = if path.is_dir() { - path - } else { - path.parent()? - }; + let start: &std::path::Path = if path.is_dir() { path } else { path.parent()? }; let mut current = start.to_path_buf(); loop { @@ -893,7 +873,7 @@ mod tests { } #[test] - fn test_copilot_params_custom_mcp_not_added_with_mcp_flag() { + fn test_copilot_params_custom_mcp_no_mcp_flag() { let mut fm = minimal_front_matter(); fm.mcp_servers.insert( "my-tool".to_string(), @@ -903,17 +883,17 @@ mod tests { }), ); let params = generate_copilot_params(&fm); - // Custom MCPs (with command) should NOT appear as --mcp flags assert!(!params.contains("--mcp my-tool")); } #[test] - fn test_copilot_params_builtin_mcp_added_with_mcp_flag() { + fn test_copilot_params_builtin_mcp_no_mcp_flag() { let mut fm = minimal_front_matter(); fm.mcp_servers .insert("ado".to_string(), McpConfig::Enabled(true)); let params = generate_copilot_params(&fm); - assert!(params.contains("--mcp ado")); + // Copilot CLI has no built-in MCPs — all MCPs are handled via the MCP firewall + assert!(!params.contains("--mcp ado")); } #[test] diff --git a/src/compile/onees.rs b/src/compile/onees.rs index 93de9d5a..e557112d 100644 --- a/src/compile/onees.rs +++ b/src/compile/onees.rs @@ -58,7 +58,7 @@ impl Compiler for OneESCompiler { let repositories = generate_repositories(&front_matter.repositories); let checkout_steps = generate_checkout_steps(&front_matter.checkout); let checkout_self = generate_checkout_self(); - let agency_params = generate_copilot_params(front_matter); + let copilot_params = generate_copilot_params(front_matter); let effective_workspace = compute_effective_workspace( &front_matter.workspace, @@ -169,7 +169,7 @@ displayName: "Finalize""#, ("{{ pipeline_path }}", &pipeline_path), ("{{ working_directory }}", &working_directory), ("{{ workspace }}", &working_directory), - ("{{ agency_params }}", &agency_params), + ("{{ copilot_params }}", &copilot_params), ("{{ acquire_ado_token }}", &acquire_read_token), ("{{ copilot_ado_env }}", &copilot_ado_env), ("{{ acquire_write_token }}", &acquire_write_token), diff --git a/src/compile/standalone.rs b/src/compile/standalone.rs index 2fde3739..174d634c 100644 --- a/src/compile/standalone.rs +++ b/src/compile/standalone.rs @@ -59,7 +59,7 @@ impl Compiler for StandaloneCompiler { let repositories = generate_repositories(&front_matter.repositories); let checkout_steps = generate_checkout_steps(&front_matter.checkout); let checkout_self = generate_checkout_self(); - let agency_params = generate_copilot_params(front_matter); + let copilot_params = generate_copilot_params(front_matter); let agent_name = sanitize_filename(&front_matter.name); // Compute effective workspace @@ -163,7 +163,7 @@ impl Compiler for StandaloneCompiler { ("{{ agent }}", &agent_name), ("{{ agent_name }}", &front_matter.name), ("{{ agent_description }}", &front_matter.description), - ("{{ agency_params }}", &agency_params), + ("{{ copilot_params }}", &copilot_params), ("{{ source_path }}", &source_path), ("{{ pipeline_path }}", &pipeline_path), ("{{ working_directory }}", &working_directory), @@ -387,41 +387,16 @@ pub fn generate_firewall_config(front_matter: &FrontMatter) -> FirewallConfig { }, spawn_timeout_secs: 30, } - } else if common::is_builtin_mcp(name) { - // Built-in MCP with options - let mut args = vec!["mcp".to_string(), name.clone()]; - args.extend(opts.args.clone()); - - UpstreamConfig { - command: "agency".to_string(), - args, - env: opts.env.clone(), - allowed: if opts.allowed.is_empty() { - vec!["*".to_string()] - } else { - opts.allowed.clone() - }, - spawn_timeout_secs: 30, - } } else { log::warn!( - "MCP '{}' has no command and is not a built-in - skipping", + "MCP '{}' has no command - skipping", name ); continue; } - } else if common::is_builtin_mcp(name) { - // Built-in MCP with simple enablement - UpstreamConfig { - command: "agency".to_string(), - args: vec!["mcp".to_string(), name.clone()], - env: HashMap::new(), - allowed: vec!["*".to_string()], - spawn_timeout_secs: 30, - } } else { log::warn!( - "MCP '{}' is not a built-in and has no command - skipping", + "MCP '{}' has no command - skipping", name ); continue; @@ -500,38 +475,6 @@ mod tests { fm } - #[test] - fn test_generate_firewall_config_builtin_simple_enabled() { - let mut fm = minimal_front_matter(); - fm.mcp_servers - .insert("ado".to_string(), McpConfig::Enabled(true)); - let config = generate_firewall_config(&fm); - let upstream = config.upstreams.get("ado").unwrap(); - assert_eq!(upstream.command, "agency"); - assert_eq!(upstream.args, vec!["mcp", "ado"]); - assert_eq!(upstream.allowed, vec!["*"]); - } - - #[test] - fn test_generate_firewall_config_builtin_with_allowed_list() { - let mut fm = minimal_front_matter(); - fm.mcp_servers.insert( - "icm".to_string(), - McpConfig::WithOptions(McpOptions { - allowed: vec!["create_incident".to_string(), "get_incident".to_string()], - ..Default::default() - }), - ); - let config = generate_firewall_config(&fm); - let upstream = config.upstreams.get("icm").unwrap(); - assert_eq!(upstream.command, "agency"); - assert_eq!(upstream.args, vec!["mcp", "icm"]); - assert_eq!( - upstream.allowed, - vec!["create_incident".to_string(), "get_incident".to_string()] - ); - } - #[test] fn test_generate_firewall_config_custom_mcp() { let mut fm = minimal_front_matter(); @@ -569,7 +512,7 @@ mod tests { #[test] fn test_generate_firewall_config_unknown_non_builtin_skipped() { - // An MCP that is neither built-in nor has a command should be skipped + // An MCP with no command should be skipped let mut fm = minimal_front_matter(); fm.mcp_servers .insert("phantom".to_string(), McpConfig::Enabled(true)); @@ -577,6 +520,16 @@ mod tests { assert!(!config.upstreams.contains_key("phantom")); } + #[test] + fn test_generate_firewall_config_builtin_without_command_skipped() { + // A built-in MCP enabled without a custom command should be skipped + let mut fm = minimal_front_matter(); + fm.mcp_servers + .insert("ado".to_string(), McpConfig::Enabled(true)); + let config = generate_firewall_config(&fm); + assert!(!config.upstreams.contains_key("ado")); + } + #[test] fn test_generate_firewall_config_disabled_mcp_skipped() { let mut fm = minimal_front_matter(); diff --git a/src/mcp_metadata.rs b/src/mcp_metadata.rs index f917c8d6..1ce12a1e 100644 --- a/src/mcp_metadata.rs +++ b/src/mcp_metadata.rs @@ -1,4 +1,4 @@ -//! MCP Metadata - Bundled tool definitions for agency MCPs +//! MCP Metadata - Bundled tool definitions for copilot MCPs //! //! This module provides access to pre-discovered MCP tool metadata that is //! embedded at compile time. The metadata is refreshed by running: @@ -11,7 +11,7 @@ //! ./refresh-mcp-metadata.sh //! ``` //! -//! The scripts query each built-in agency MCP and save the tool definitions +//! The scripts query each built-in copilot MCP and save the tool definitions //! to `mcp-metadata.json`, which is then embedded into the binary. use serde::{Deserialize, Serialize}; @@ -38,7 +38,7 @@ pub struct ToolMetadata { pub struct McpMetadata { /// Server name/identifier pub name: String, - /// Whether this is a built-in agency MCP + /// Whether this is a built-in copilot MCP #[serde(default)] pub builtin: bool, /// Available tools diff --git a/templates/1es-base.yml b/templates/1es-base.yml index 024ff0cc..beaf756d 100644 --- a/templates/1es-base.yml +++ b/templates/1es-base.yml @@ -128,9 +128,9 @@ extends: postAgentSteps: {{ finalize_steps }} globalOptions: '--log-dir $(Agency_LogPath) {{ global_options }}' - commandOptions: '{{ agency_params }}' + commandOptions: '{{ copilot_params }}' logLevel: '{{ log_level }}' - logPath: '$(Build.StagingDirectory)/agency-logs' + logPath: '$(Build.StagingDirectory)/copilot-logs' createArtifact: true mcpConfiguration: {{ mcp_configuration }} @@ -230,7 +230,7 @@ extends: THREAT_OUTPUT_FILE="$(Agent.TempDirectory)/threat-analysis-output.txt" # Use $(cat file) like gh-aw does - the command is executed directly, not via a variable - copilot --prompt "$(cat $(Agent.TempDirectory)/threat-analysis-prompt.md)" {{ agency_params }} > "$THREAT_OUTPUT_FILE" 2>&1 + copilot --prompt "$(cat $(Agent.TempDirectory)/threat-analysis-prompt.md)" {{ copilot_params }} > "$THREAT_OUTPUT_FILE" 2>&1 AGENT_EXIT_CODE=$? echo "=== Threat Analysis Output (sanitized) ===" diff --git a/templates/base.yml b/templates/base.yml index 5d39b135..efa4b7e6 100644 --- a/templates/base.yml +++ b/templates/base.yml @@ -223,7 +223,7 @@ jobs: --container-workdir "{{ working_directory }}" \ --log-level info \ --proxy-logs-dir "$(Agent.TempDirectory)/staging/logs/firewall" \ - -- '/tmp/awf-tools/copilot --prompt "$(cat /tmp/awf-tools/agent-prompt.md)" --additional-mcp-config @/tmp/awf-tools/mcp-config.json {{ agency_params }}' \ + -- '/tmp/awf-tools/copilot --prompt "$(cat /tmp/awf-tools/agent-prompt.md)" --additional-mcp-config @/tmp/awf-tools/mcp-config.json {{ copilot_params }}' \ > "$AGENT_OUTPUT_FILE" 2>&1 \ && AGENT_EXIT_CODE=0 || AGENT_EXIT_CODE=$? @@ -263,9 +263,6 @@ jobs: if [ -d ~/.copilot/logs ]; then cp -r ~/.copilot/logs/* "$(Agent.TempDirectory)/staging/logs/" 2>/dev/null || true fi - if [ -d ~/.agency/logs ]; then - cp -r ~/.agency/logs/* "$(Agent.TempDirectory)/staging/logs/" 2>/dev/null || true - fi if [ -d ~/.ado-aw/logs ]; then cp -r ~/.ado-aw/logs/* "$(Agent.TempDirectory)/staging/logs/" 2>/dev/null || true fi @@ -395,7 +392,7 @@ jobs: --container-workdir "{{ working_directory }}" \ --log-level info \ --proxy-logs-dir "$(Agent.TempDirectory)/threat-analysis-logs/firewall" \ - -- '/tmp/awf-tools/copilot --prompt "$(cat /tmp/awf-tools/threat-analysis-prompt.md)" {{ agency_params }}' \ + -- '/tmp/awf-tools/copilot --prompt "$(cat /tmp/awf-tools/threat-analysis-prompt.md)" {{ copilot_params }}' \ > "$THREAT_OUTPUT_FILE" 2>&1 AGENT_EXIT_CODE=$? @@ -480,10 +477,6 @@ jobs: mkdir -p "$(Agent.TempDirectory)/analyzed_outputs/logs/copilot" cp -r ~/.copilot/logs/* "$(Agent.TempDirectory)/analyzed_outputs/logs/copilot/" 2>/dev/null || true fi - if [ -d ~/.agency/logs ]; then - mkdir -p "$(Agent.TempDirectory)/analyzed_outputs/logs/agency" - cp -r ~/.agency/logs/* "$(Agent.TempDirectory)/analyzed_outputs/logs/agency/" 2>/dev/null || true - fi if [ -d ~/.ado-aw/logs ]; then mkdir -p "$(Agent.TempDirectory)/analyzed_outputs/logs/ado-aw" cp -r ~/.ado-aw/logs/* "$(Agent.TempDirectory)/analyzed_outputs/logs/ado-aw/" 2>/dev/null || true @@ -555,10 +548,6 @@ jobs: mkdir -p "$(Agent.TempDirectory)/staging/logs/copilot" cp -r ~/.copilot/logs/* "$(Agent.TempDirectory)/staging/logs/copilot/" 2>/dev/null || true fi - if [ -d ~/.agency/logs ]; then - mkdir -p "$(Agent.TempDirectory)/staging/logs/agency" - cp -r ~/.agency/logs/* "$(Agent.TempDirectory)/staging/logs/agency/" 2>/dev/null || true - fi if [ -d ~/.ado-aw/logs ]; then mkdir -p "$(Agent.TempDirectory)/staging/logs/ado-aw" cp -r ~/.ado-aw/logs/* "$(Agent.TempDirectory)/staging/logs/ado-aw/" 2>/dev/null || true diff --git a/tests/EXAMPLES.md b/tests/EXAMPLES.md index dfa694b0..8fb0e037 100644 --- a/tests/EXAMPLES.md +++ b/tests/EXAMPLES.md @@ -78,10 +78,12 @@ fn test_with_hashmap() { mcps.insert("ado".to_string(), McpConfig::Enabled(true)); mcps.insert("es-chat".to_string(), McpConfig::Enabled(true)); - let result = generate_agency_params(&mcps); + let result = generate_copilot_params(&mcps); assert!(result.contains("--prompt")); - assert!(result.contains("--mcp ado") || result.contains("--mcp es-chat")); + // MCPs are handled via the MCP firewall, not --mcp flags + assert!(!result.contains("--mcp ado")); + assert!(!result.contains("--mcp es-chat")); } ``` @@ -101,7 +103,7 @@ fn test_with_options() { }), ); - let result = generate_agency_params(&mcps); + let result = generate_copilot_params(&mcps); assert!(!result.contains("--mcp custom-tool")); } diff --git a/tests/QUICKREF.md b/tests/QUICKREF.md index 5b9a0231..186f3b0b 100644 --- a/tests/QUICKREF.md +++ b/tests/QUICKREF.md @@ -49,7 +49,7 @@ ado-aw/ ✅ Schedule generation (hourly/daily) ✅ Repository configuration ✅ Checkout steps -✅ Agency parameters +✅ Copilot parameters ✅ Markdown parsing ✅ Error handling ✅ Edge cases diff --git a/tests/README.md b/tests/README.md index 4b5e3bf0..ac53fc6b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -68,8 +68,8 @@ Tests checkout step generation for: - Empty repository list - Multiple repositories -### `test_generate_agency_params_*` (3 tests) -Tests agency parameter generation for: +### `test_generate_copilot_params_*` (3 tests) +Tests copilot parameter generation for: - Built-in MCPs (enabled) - Built-in MCPs (disabled) - Custom MCPs (should be skipped) @@ -101,7 +101,7 @@ Verifies that the base template contains all required markers: - `{{ checkout_repositories }}` - `{{ agent }}` - `{{ agent_name }}` -- `{{ agency_params }}` +- `{{ copilot_params }}` ### `test_example_file_structure` Validates the example file (`examples/sample-agent.md`) to ensure: @@ -126,7 +126,7 @@ The current test suite provides coverage for: - ✅ Schedule generation - ✅ Repository configuration generation - ✅ Checkout step generation -- ✅ Agency parameter generation +- ✅ Copilot parameter generation - ✅ Markdown parsing - ✅ Template structure validation - ✅ Example file validation diff --git a/tests/SUMMARY.md b/tests/SUMMARY.md index bf14ee3c..13e775b2 100644 --- a/tests/SUMMARY.md +++ b/tests/SUMMARY.md @@ -27,10 +27,10 @@ Added 18 comprehensive unit tests in the `tests` module at the end of `main.rs`: - `test_generate_checkout_steps_empty` - Tests empty checkout list - `test_generate_checkout_steps_multiple` - Tests multiple checkout steps -#### Agency Parameters (3 tests) -- `test_generate_agency_params_builtin_enabled` - Tests enabled built-in MCPs -- `test_generate_agency_params_builtin_disabled` - Tests disabled MCPs -- `test_generate_agency_params_custom_mcp_skipped` - Verifies custom MCPs are skipped +#### Copilot Parameters (3 tests) +- `test_copilot_params_custom_mcp_no_mcp_flag` - Verifies custom MCPs don't generate --mcp flags +- `test_copilot_params_builtin_mcp_no_mcp_flag` - Verifies built-in MCPs don't generate --mcp flags (all MCPs handled via firewall) +- `test_generate_copilot_params_custom_mcp_skipped` - Verifies custom MCPs are skipped #### Markdown Parsing (4 tests) - `test_parse_markdown_valid` - Tests valid markdown with front matter @@ -78,7 +78,7 @@ The test suite provides comprehensive coverage for: - Schedule generation (hourly/daily, deterministic) - Repository configuration generation - Checkout step generation -- Agency parameter generation +- Copilot parameter generation ✅ **Error Handling** - Missing front matter diff --git a/tests/VERIFICATION.md b/tests/VERIFICATION.md index 56e73a02..6b8473bd 100644 --- a/tests/VERIFICATION.md +++ b/tests/VERIFICATION.md @@ -136,7 +136,7 @@ fn test_compile_pipeline_basic() { - `test_generate_schedule_*` - verifies schedule generation - `test_generate_repositories_*` - verifies repository YAML generation - `test_generate_checkout_steps_*` - verifies checkout step generation - - `test_generate_agency_params_*` - verifies parameter generation + - `test_generate_copilot_params_*` - verifies parameter generation - `test_parse_markdown_*` - verifies markdown parsing including error cases - Template and structure validation tests diff --git a/tests/compiler_tests.rs b/tests/compiler_tests.rs index d6eadb79..8908288d 100644 --- a/tests/compiler_tests.rs +++ b/tests/compiler_tests.rs @@ -104,8 +104,8 @@ fn test_compiled_yaml_structure() { "Template should contain agent_name marker" ); assert!( - template_content.contains("{{ agency_params }}"), - "Template should contain agency_params marker" + template_content.contains("{{ copilot_params }}"), + "Template should contain copilot_params marker" ); assert!( template_content.contains("{{ compiler_version }}"),