Skip to content

Commit a2bd920

Browse files
authored
feat(init): scaffold dispatcher skill alongside the agent (#1499)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9d964cf9-4314-42e5-9e31-1793722e6a42
1 parent b7201b9 commit a2bd920

8 files changed

Lines changed: 313 additions & 3 deletions

File tree

.github/skills/ado-aw/SKILL.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
name: ado-aw
3+
description: Azure DevOps Agentic Workflows (ado-aw) - Create, update, and debug AI-powered Azure DevOps agentic workflows
4+
---
5+
6+
# Azure DevOps Agentic Workflows Skill
7+
8+
This skill helps you create and manage Azure DevOps agentic workflows using **ado-aw**.
9+
10+
ado-aw compiles human-friendly markdown files with YAML front matter into secure, multi-stage Azure DevOps pipelines that run AI agents in network-isolated sandboxes.
11+
12+
## Setup
13+
14+
Before creating or compiling workflows, ensure the ado-aw compiler is available. Use the first-time installer for your platform:
15+
16+
```bash
17+
# Linux
18+
curl -fsSL https://github.com/githubnext/ado-aw/releases/latest/download/install-linux.sh | sh
19+
20+
# macOS (Apple Silicon)
21+
curl -fsSL https://github.com/githubnext/ado-aw/releases/latest/download/install-macos.sh | sh
22+
23+
# Windows (PowerShell)
24+
$script = Join-Path $env:TEMP "install-ado-aw.ps1"
25+
Invoke-WebRequest "https://github.com/githubnext/ado-aw/releases/latest/download/install-windows.ps1" -UseBasicParsing -OutFile $script
26+
Get-FileHash $script -Algorithm SHA256
27+
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
28+
& $script
29+
```
30+
31+
These scripts validate release checksums, install `ado-aw`, and update PATH when needed.
32+
If Windows reports a `UseShellExecute` environment-variable error, run these commands from your current PowerShell session instead of wrapping them in `powershell -Command`.
33+
34+
Verify: `ado-aw --version`
35+
36+
## What This Skill Does
37+
38+
This is a **dispatcher skill** that routes your request to the appropriate specialized prompt:
39+
40+
- **Creating new agentic workflows** → Routes to the create prompt
41+
- **Updating existing workflows** → Routes to the update prompt
42+
- **Debugging failing workflows** → Routes to the debug prompt
43+
44+
## Available Prompts
45+
46+
### Create New Agentic Workflow
47+
**Load when**: User wants to create a new agentic workflow from scratch
48+
49+
**Prompt file**: https://raw.githubusercontent.com/githubnext/ado-aw/v0.44.0/prompts/create-ado-agentic-workflow.md <!-- x-release-please-version -->
50+
51+
**Use cases**:
52+
- "Create an agentic workflow that reviews PRs weekly"
53+
- "I need a workflow that triages work items daily"
54+
- "Design a scheduled dependency updater"
55+
56+
### Update Existing Workflow
57+
**Load when**: User wants to modify an existing agent workflow file
58+
59+
**Prompt file**: https://raw.githubusercontent.com/githubnext/ado-aw/v0.44.0/prompts/update-ado-agentic-workflow.md <!-- x-release-please-version -->
60+
61+
**Use cases**:
62+
- "Add the Azure DevOps MCP to my workflow"
63+
- "Change the schedule from daily to weekly"
64+
- "Add work item creation as a safe output"
65+
66+
### Debug Failing Workflow
67+
**Load when**: User needs to troubleshoot a failing agentic workflow
68+
69+
**Prompt file**: https://raw.githubusercontent.com/githubnext/ado-aw/v0.44.0/prompts/debug-ado-agentic-workflow.md <!-- x-release-please-version -->
70+
71+
**Use cases**:
72+
- "Why is my agentic workflow failing?"
73+
- "The agent can't reach the MCP server"
74+
- "Safe outputs aren't being processed"
75+
76+
## Instructions
77+
78+
When a user interacts with you:
79+
80+
1. **Identify the task type** from the user's request
81+
2. **Load the appropriate prompt** from the URLs listed above
82+
3. **Follow the loaded prompt's instructions** exactly
83+
4. **If uncertain**, ask clarifying questions to determine the right prompt
84+
85+
## Quick Reference
86+
87+
```bash
88+
# Compile an agent file to pipeline YAML
89+
ado-aw compile <agent-file.md>
90+
91+
# Recompile all detected pipelines
92+
ado-aw compile
93+
94+
# Verify pipeline matches source
95+
ado-aw check <pipeline.lock.yml>
96+
```
97+
98+
## Key Features
99+
100+
- **Natural language workflows**: Write in markdown with YAML frontmatter
101+
- **3-stage security**: Agent → Threat Analysis → Safe Output Execution
102+
- **Network isolation**: AWF (Agentic Workflow Firewall) with domain whitelisting
103+
- **MCP Gateway**: Tool routing for Azure DevOps, custom MCPs
104+
- **Safe outputs**: Controlled write operations (PRs, work items, wiki pages)
105+
- **Agent memory**: Persistent storage across pipeline runs
106+
107+
## Important Notes
108+
109+
- Agent files must be compiled with `ado-aw compile` after YAML frontmatter changes
110+
- Markdown body (agent instructions) changes do NOT require recompilation
111+
- The agent never has direct write access — all mutations go through safe outputs
112+
- Full reference: https://raw.githubusercontent.com/githubnext/ado-aw/v0.44.0/AGENTS.md <!-- x-release-please-version -->

.github/workflows/doc-freshness-check.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ Extract the actual CLI commands from `src/main.rs` (the clap `Commands` enum) an
134134
verify `docs/cli.md` documents every subcommand with correct arguments, flags,
135135
and default values.
136136

137+
Also verify the documented `init` scaffold output matches `src/init.rs`. `init`
138+
writes **both** a dispatcher agent (`.github/agents/ado-aw.agent.md`, from
139+
`src/data/init-agent.md`) **and** a dispatcher skill
140+
(`.github/skills/ado-aw/SKILL.md`, from `src/data/init-skill.md`), plus the
141+
`--agency` plugin tree. If a scaffold file, template, or path changes, ensure
142+
the `init` bullet in `docs/cli.md` and the `src/data/` + `init.rs` entries in
143+
the `AGENTS.md` architecture tree list every emitted file.
144+
137145
### 4. Front matter fields (`docs/front-matter.md` and the pages it links)
138146

139147
Compare the `FrontMatter` struct in `src/compile/types.rs` against the documented

AGENTS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ fail-closed and only pauses when the agent actually proposed a reviewed output.
117117
│ │ ├── lower.rs # IR → serde_yaml::Value lowering
118118
│ │ ├── emit.rs # Thin `lower() + serde_yaml::to_string()` wrapper
119119
│ │ └── summary.rs # Public, serializable PipelineSummary / GraphSummary for agent-facing tooling (see docs/ir.md Public JSON summary)
120-
│ ├── init.rs # Repository initialization for AI-first authoring (incl. `--agency` plugin scaffold, embeds agency/plugins/ado-aw/ via include_str!)
120+
│ ├── init.rs # Repository initialization for AI-first authoring: scaffolds a dispatcher agent (.github/agents/ado-aw.agent.md) AND skill (.github/skills/ado-aw/SKILL.md); `--agency` plugin scaffold embeds agency/plugins/ado-aw/ via include_str!
121121
│ ├── execute.rs # Stage 3 safe output execution
122122
│ ├── fuzzy_schedule.rs # Fuzzy schedule parsing
123123
│ ├── logging.rs # File-based logging infrastructure
@@ -219,7 +219,8 @@ fail-closed and only pauses when the agent actually proposed a reviewed output.
219219
│ │ └── extension.rs # CompilerExtension impl
220220
│ ├── data/
221221
│ │ ├── ecosystem_domains.json # Network allowlists per ecosystem
222-
│ │ ├── init-agent.md # Dispatcher agent template for `init` command
222+
│ │ ├── init-agent.md # Dispatcher agent template for `init` command (→ .github/agents/ado-aw.agent.md)
223+
│ │ ├── init-skill.md # Dispatcher skill template for `init` command (→ .github/skills/ado-aw/SKILL.md)
223224
│ │ └── threat-analysis.md # Threat detection analysis prompt template
224225
│ └── tools/ # First-class tool implementations (one dir per tool)
225226
│ ├── mod.rs

docs/cli.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Global flags (apply to all subcommands): `--verbose, -v` (enable info-level logg
1111
- `--force` - Bypass the GitHub-remote guard (use when running inside a GitHub-hosted repository like `githubnext/ado-aw` itself)
1212
- `--agency` - **Additive.** Also generate an Agency / [Claude Code plugin](https://code.claude.com/docs/en/plugins-reference) and the marketplace catalogs that make the repo directly installable (in addition to the standard Copilot agent file). Writes the plugin under `agency/plugins/ado-aw` (mirroring how it is checked in to ado-aw itself) plus **repo-root** marketplace catalogs `.claude-plugin/marketplace.json` (Claude) and `.github/plugin/marketplace.json` (Copilot) that list the plugin via `source: "./agency/plugins/ado-aw"`. After scaffolding, register with `/plugin marketplace add <repo>` then `/plugin install ado-aw@ado-aw`. The plugin tree is a verbatim copy of the canonical in-repo plugin at [`agency/plugins/ado-aw/`](../agency/plugins/ado-aw): `.claude-plugin/plugin.json`, `.mcp.json` (wires the read-only `ado-aw mcp-author` server), `agency.json` (marketplace governance + external `source` pointer), `README.md`, an `agents/ado-aw.md` dispatcher subagent, six `skills/<name>/SKILL.md` playbooks (`create-workflow`, `update-workflow`, `debug-workflow`, `compile-and-validate`, `manage-lifecycle`, `audit-build`), and `scripts/doctor.{sh,ps1}` prerequisite checks. The canonical plugin + catalogs are version-locked to the compiler (release-please bumps the plugin/catalog versions + pinned prompt URLs in lock-step).
1313
- Creates `.github/agents/ado-aw.agent.md` — a Copilot dispatcher agent that routes to specialized prompts for creating, updating, and debugging agentic pipelines
14+
- Additively creates `.github/skills/ado-aw/SKILL.md` — the same dispatcher in Copilot **skill** (`SKILL.md`) format, so surfaces that consume skills get the router too (mirrors how gh-aw's `init` emits both an agent and a skill). Both files are version-pinned and kept in sync with their templates (`src/data/init-agent.md`, `src/data/init-skill.md`).
1415
- The agent auto-downloads the ado-aw compiler and handles the full lifecycle (create → compile → check)
1516
- `compile [<path>]` - Compile a markdown file to Azure DevOps pipeline YAML. If no path is given, auto-discovers and recompiles all detected agentic pipelines in the current directory.
1617
- `--output, -o <path>` - Optional output path for the generated YAML (only valid when a path is provided). If the path is an existing directory, the compiled YAML is written inside that directory using the default filename derived from the markdown source (e.g. `foo.md``<dir>/foo.lock.yml`).

release-please-config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"agency/plugins/ado-aw/skills/create-workflow/SKILL.md",
3636
"agency/plugins/ado-aw/skills/update-workflow/SKILL.md",
3737
"agency/plugins/ado-aw/skills/debug-workflow/SKILL.md",
38-
".github/agents/ado-aw.agent.md"
38+
".github/agents/ado-aw.agent.md",
39+
".github/skills/ado-aw/SKILL.md"
3940
]
4041
}
4142
}

src/data/init-skill.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
---
2+
name: ado-aw
3+
description: Azure DevOps Agentic Workflows (ado-aw) - Create, update, and debug AI-powered Azure DevOps agentic workflows
4+
---
5+
6+
# Azure DevOps Agentic Workflows Skill
7+
8+
This skill helps you create and manage Azure DevOps agentic workflows using **ado-aw**.
9+
10+
ado-aw compiles human-friendly markdown files with YAML front matter into secure, multi-stage Azure DevOps pipelines that run AI agents in network-isolated sandboxes.
11+
12+
## Setup
13+
14+
Before creating or compiling workflows, ensure the ado-aw compiler is available. Use the first-time installer for your platform:
15+
16+
```bash
17+
# Linux
18+
curl -fsSL https://github.com/githubnext/ado-aw/releases/latest/download/install-linux.sh | sh
19+
20+
# macOS (Apple Silicon)
21+
curl -fsSL https://github.com/githubnext/ado-aw/releases/latest/download/install-macos.sh | sh
22+
23+
# Windows (PowerShell)
24+
$script = Join-Path $env:TEMP "install-ado-aw.ps1"
25+
Invoke-WebRequest "https://github.com/githubnext/ado-aw/releases/latest/download/install-windows.ps1" -UseBasicParsing -OutFile $script
26+
Get-FileHash $script -Algorithm SHA256
27+
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
28+
& $script
29+
```
30+
31+
These scripts validate release checksums, install `ado-aw`, and update PATH when needed.
32+
If Windows reports a `UseShellExecute` environment-variable error, run these commands from your current PowerShell session instead of wrapping them in `powershell -Command`.
33+
34+
Verify: `ado-aw --version`
35+
36+
## What This Skill Does
37+
38+
This is a **dispatcher skill** that routes your request to the appropriate specialized prompt:
39+
40+
- **Creating new agentic workflows** → Routes to the create prompt
41+
- **Updating existing workflows** → Routes to the update prompt
42+
- **Debugging failing workflows** → Routes to the debug prompt
43+
44+
## Available Prompts
45+
46+
### Create New Agentic Workflow
47+
**Load when**: User wants to create a new agentic workflow from scratch
48+
49+
**Prompt file**: https://raw.githubusercontent.com/githubnext/ado-aw/v{{ compiler_version }}/prompts/create-ado-agentic-workflow.md <!-- x-release-please-version -->
50+
51+
**Use cases**:
52+
- "Create an agentic workflow that reviews PRs weekly"
53+
- "I need a workflow that triages work items daily"
54+
- "Design a scheduled dependency updater"
55+
56+
### Update Existing Workflow
57+
**Load when**: User wants to modify an existing agent workflow file
58+
59+
**Prompt file**: https://raw.githubusercontent.com/githubnext/ado-aw/v{{ compiler_version }}/prompts/update-ado-agentic-workflow.md <!-- x-release-please-version -->
60+
61+
**Use cases**:
62+
- "Add the Azure DevOps MCP to my workflow"
63+
- "Change the schedule from daily to weekly"
64+
- "Add work item creation as a safe output"
65+
66+
### Debug Failing Workflow
67+
**Load when**: User needs to troubleshoot a failing agentic workflow
68+
69+
**Prompt file**: https://raw.githubusercontent.com/githubnext/ado-aw/v{{ compiler_version }}/prompts/debug-ado-agentic-workflow.md <!-- x-release-please-version -->
70+
71+
**Use cases**:
72+
- "Why is my agentic workflow failing?"
73+
- "The agent can't reach the MCP server"
74+
- "Safe outputs aren't being processed"
75+
76+
## Instructions
77+
78+
When a user interacts with you:
79+
80+
1. **Identify the task type** from the user's request
81+
2. **Load the appropriate prompt** from the URLs listed above
82+
3. **Follow the loaded prompt's instructions** exactly
83+
4. **If uncertain**, ask clarifying questions to determine the right prompt
84+
85+
## Quick Reference
86+
87+
```bash
88+
# Compile an agent file to pipeline YAML
89+
ado-aw compile <agent-file.md>
90+
91+
# Recompile all detected pipelines
92+
ado-aw compile
93+
94+
# Verify pipeline matches source
95+
ado-aw check <pipeline.lock.yml>
96+
```
97+
98+
## Key Features
99+
100+
- **Natural language workflows**: Write in markdown with YAML frontmatter
101+
- **3-stage security**: Agent → Threat Analysis → Safe Output Execution
102+
- **Network isolation**: AWF (Agentic Workflow Firewall) with domain whitelisting
103+
- **MCP Gateway**: Tool routing for Azure DevOps, custom MCPs
104+
- **Safe outputs**: Controlled write operations (PRs, work items, wiki pages)
105+
- **Agent memory**: Persistent storage across pipeline runs
106+
107+
## Important Notes
108+
109+
- Agent files must be compiled with `ado-aw compile` after YAML frontmatter changes
110+
- Markdown body (agent instructions) changes do NOT require recompilation
111+
- The agent never has direct write access — all mutations go through safe outputs
112+
- Full reference: https://raw.githubusercontent.com/githubnext/ado-aw/v{{ compiler_version }}/AGENTS.md <!-- x-release-please-version -->

src/init.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ const AGENT_TEMPLATE: &str = include_str!("data/init-agent.md");
77
const AGENT_DIR: &str = ".github/agents";
88
const AGENT_FILENAME: &str = "ado-aw.agent.md";
99

10+
// The dispatcher skill template is embedded from src/data/init-skill.md. It
11+
// mirrors the agent (same routing/prompt content) in Copilot skill (SKILL.md)
12+
// format, matching how gh-aw's `init` emits both an agent and a skill.
13+
const SKILL_TEMPLATE: &str = include_str!("data/init-skill.md");
14+
15+
const SKILL_DIR: &str = ".github/skills/ado-aw";
16+
const SKILL_FILENAME: &str = "SKILL.md";
17+
1018
/// Root directory (relative to the target repo) for the generated Agency /
1119
/// Claude Code plugin. Mirrors the canonical in-repo layout (`agency/plugins/
1220
/// ado-aw/`) so a scaffolded consumer repo matches how the plugin is checked in
@@ -124,6 +132,24 @@ pub async fn run(path: Option<&std::path::Path>, agency: bool) -> Result<()> {
124132
// Print success message
125133
println!("✓ Created {}", agent_path.display());
126134

135+
// Additively scaffold the dispatcher skill (SKILL.md format). This mirrors
136+
// gh-aw's `init`, which emits both a dispatcher agent and a dispatcher
137+
// skill so Copilot surfaces that consume skills also get the router.
138+
let skill_dir = base.join(SKILL_DIR);
139+
let skill_path = skill_dir.join(SKILL_FILENAME);
140+
141+
tokio::fs::create_dir_all(&skill_dir)
142+
.await
143+
.with_context(|| format!("Failed to create directory: {}", skill_dir.display()))?;
144+
145+
let skill_content = SKILL_TEMPLATE.replace("{{ compiler_version }}", version);
146+
147+
tokio::fs::write(&skill_path, skill_content)
148+
.await
149+
.with_context(|| format!("Failed to write skill file: {}", skill_path.display()))?;
150+
151+
println!("✓ Created {}", skill_path.display());
152+
127153
// `--agency` is additive: keep the standard agent file above and also emit
128154
// the Agency / Claude Code plugin.
129155
if agency {

tests/init_tests.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ fn test_init_creates_agent_file() {
3434
!content.contains("{{ compiler_version }}"),
3535
"Version placeholder should be replaced with actual version"
3636
);
37+
38+
// `init` additively scaffolds the dispatcher skill (SKILL.md format),
39+
// mirroring gh-aw which emits both an agent and a skill.
40+
let skill_path = temp_dir.path().join(".github/skills/ado-aw/SKILL.md");
41+
assert!(skill_path.exists(), "Skill file should be created");
42+
43+
let skill_content =
44+
fs::read_to_string(&skill_path).expect("Should be able to read skill file");
45+
assert!(
46+
skill_content.contains("Azure DevOps Agentic Workflows Skill"),
47+
"Skill file should contain the expected title"
48+
);
49+
assert!(
50+
skill_content.starts_with("---\nname: ado-aw\n")
51+
|| skill_content.starts_with("---\r\nname: ado-aw\r\n"),
52+
"Skill file should carry the `name: ado-aw` front matter"
53+
);
54+
assert!(
55+
!skill_content.contains("{{ compiler_version }}"),
56+
"Version placeholder should be replaced in the skill file"
57+
);
3758
}
3859

3960
/// Test that `init` always overwrites an existing agent file (no --force needed)
@@ -414,6 +435,34 @@ fn test_committed_agent_file_matches_template_output() {
414435
);
415436
}
416437

438+
/// Guard that the committed `.github/skills/ado-aw/SKILL.md` stays in sync with
439+
/// its template `src/data/init-skill.md`: running `init` must reproduce the
440+
/// committed file byte-for-byte. As with the agent file, the committed copy (not
441+
/// the placeholder-bearing template) is what release-please version-bumps.
442+
#[test]
443+
fn test_committed_skill_file_matches_template_output() {
444+
let repo_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
445+
let committed = fs::read_to_string(repo_root.join(".github/skills/ado-aw/SKILL.md"))
446+
.expect("committed skill file should be readable");
447+
448+
let temp_dir = tempfile::tempdir().expect("Failed to create temp directory");
449+
let output = ado_aw_bin()
450+
.args(["init", "--path", temp_dir.path().to_str().unwrap()])
451+
.output()
452+
.expect("Failed to run ado-aw init");
453+
assert!(output.status.success(), "init should succeed");
454+
455+
let generated = fs::read_to_string(temp_dir.path().join(".github/skills/ado-aw/SKILL.md"))
456+
.expect("generated skill file should be readable");
457+
458+
assert_eq!(
459+
generated.replace("\r\n", "\n"),
460+
committed.replace("\r\n", "\n"),
461+
"committed .github/skills/ado-aw/SKILL.md is stale — regenerate it with \
462+
`ado-aw init --force` after editing src/data/init-skill.md"
463+
);
464+
}
465+
417466
/// `init --agency` must NOT clobber a consumer's pre-existing, differing root
418467
/// marketplace catalog. It should leave the existing file untouched and still
419468
/// scaffold the plugin tree.

0 commit comments

Comments
 (0)