Skip to content

feat(agency): centralize Claude Code plugin and self-contained marketplace#1102

Open
Copilot wants to merge 7 commits into
mainfrom
copilot/extend-init-command-agency-plugin
Open

feat(agency): centralize Claude Code plugin and self-contained marketplace#1102
Copilot wants to merge 7 commits into
mainfrom
copilot/extend-init-command-agency-plugin

Conversation

Copilot AI commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What & why

ado-aw init --agency previously emitted a duplicated, hard-to-test plugin
template tree (src/data/agency-plugin/) into .github/ado-aw, and the result
was not detectable by the Agency marketplace. This PR centralizes the plugin as
a checked-in single source of truth, makes the repo itself an installable
marketplace, implements the full Agency plugin spec, and aligns terminology on
the canonical brand Azure DevOps Agentic Workflows.

Key changes

  • Canonical plugin at agency/plugins/ado-aw/ (single source of truth):
    .claude-plugin/plugin.json, .mcp.json (wires the read-only
    ado-aw mcp-author server), agency.json (governance + external source
    pointer, org-only identity, no PII), README.md, an agents/ado-aw.md
    dispatcher, six skills/*/SKILL.md playbooks (create/update/debug-workflow,
    compile-and-validate, manage-lifecycle, audit-build), and
    scripts/doctor.{sh,ps1} prerequisite checks.
  • Self-contained marketplace: repo-root catalogs
    .claude-plugin/marketplace.json (Claude) and .github/plugin/marketplace.json
    (Copilot) list the plugin via source: "./agency/plugins/ado-aw", so
    /plugin marketplace add <repo> detects it.
  • Hybrid --agency: init now embeds the canonical files via include_str!
    and writes them verbatim (plugin under agency/plugins/ado-aw/ + root
    catalogs); the duplicate src/data/agency-plugin/ tree is removed.
  • Lock-step versioning via release-please extra-files: plugin manifest,
    both root catalogs (metadata + plugin entry), and the pinned prompt URLs in the
    agent + create/update/debug skills bump on every release.
  • Terminology: standardized on "Azure DevOps Agentic Workflows" (the authored
    spec is an agentic workflow; pipeline = the compiled ADO execution
    artifact) across init-generated output, root catalogs, README, AGENTS.md, and
    user-facing CLI help.

Tests

  • New parity test asserts init --agency output matches the canonical source
    byte-for-byte; root-catalog existence + source assertions; updated agent-title
    assertions.
  • cargo build, full cargo test (2063 lib + integration, 0 failed),
    cargo clippy --all-targets --all-features, and shellcheck doctor.sh all green.

Follow-up (separate)

To list in the shared Agency marketplace, add a one-line extPluginSources entry
to agency-microsoft/playground's marketplace-config.json:
"https://github.com/githubnext/ado-aw.git": ["agency/plugins/ado-aw"].

@jamesadevine jamesadevine changed the title Extending init command for agency plugin generation feat(agency): centralize Claude Code plugin and self-contained marketplace Jun 22, 2026
@jamesadevine jamesadevine force-pushed the copilot/extend-init-command-agency-plugin branch from bb5fc49 to d63fe2e Compare June 22, 2026 13:27
@jamesadevine jamesadevine marked this pull request as ready for review June 22, 2026 14:32
@jamesadevine

Copy link
Copy Markdown
Collaborator

/rust-review

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Rust PR Reviewer completed successfully!

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Rust PR Review

Summary: Looks good overall — clean architecture and solid error handling. One concrete bug in the CLI help text.

Findings

🐛 Bugs / Logic Issues

  • src/main.rs:293–294 — The --agency flag help text says the plugin is written to .github/ado-aw, but AGENCY_PLUGIN_DIR is "agency/plugins/ado-aw". This is stale copy from the prior implementation (the PR description itself notes it previously wrote to .github/ado-aw). Users reading ado-aw init --help will look in the wrong place.

    // Current (wrong path in help):
    /// `.github/ado-aw` (additive to the standard agent file).
    
    // Should be:
    /// `agency/plugins/ado-aw` (additive to the standard agent file).
    

⚠️ Suggestions

  • tests/init_tests.rstest_init_agency_matches_canonical_source — The parity test only covers 9 of the 13 embedded files; update-workflow/SKILL.md, debug-workflow/SKILL.md, manage-lifecycle/SKILL.md, and audit-build/SKILL.md are not byte-for-byte verified. Since the files are include_str!-embedded (so drift between embed and canonical is compile-time impossible), the test's real value is confirming the write loop is complete. Extending it to check all 13 entries would make that guarantee explicit.

✅ What Looks Good

  • Error handling is excellent — every tokio::fs::create_dir_all and tokio::fs::write call is wrapped with .with_context(|| ...), giving actionable error messages.
  • include_str! embedding eliminates a whole class of runtime sync bugs — the embedded bytes and the canonical source are literally the same object at compile time.
  • All rel_path values are compile-time constants with no .. components, so there is no path traversal risk in write_agency_plugin.
  • doctor.sh uses set -euo pipefail and distinguishes advisory warnings from hard failures with correct exit codes.
  • Additive design (standard agent file always written; plugin emitted only with --agency) is clean and the negative test test_init_without_agency_skips_plugin guards this contract well.
  • release-please-config.json extra-files correctly targets only the 4 files that actually carry version-pinned URLs (the <!-- x-release-please-version --> comment pattern); the three skills without version pins are correctly omitted.

Generated by Rust PR Reviewer for issue #1102 · 269.6 AIC · ⌖ 12.6 AIC · ⊞ 35.4K ·
Comment /rust-review to run again

jamesadevine added a commit that referenced this pull request Jun 22, 2026
Address Rust PR Reviewer feedback on #1102:
- `--agency` help text said `.github/ado-aw` (stale); the scaffold writes to
  `agency/plugins/ado-aw` plus repo-root marketplace catalogs.
- Extend test_init_agency_matches_canonical_source to verify all 13 embedded
  plugin files byte-for-byte (was 9), covering the previously-unchecked
  update/debug/manage-lifecycle/audit-build skills.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI and others added 6 commits June 23, 2026 09:57
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
…place

Promote the embedded `--agency` templates into a live, checked-in plugin at
`agency/plugins/ado-aw/` as the single source of truth, and implement the full
Agency marketplace spec: plugin.json, .mcp.json wiring the read-only
`ado-aw mcp-author` server, agency.json governance (external `source` pointer,
org-only identity, no PII), README, an agents/ado-aw.md dispatcher, six
skills/*/SKILL.md playbooks, and scripts/doctor.{sh,ps1} prerequisite checks.

Make the repository itself an installable marketplace: add repo-root catalogs
`.claude-plugin/marketplace.json` (Claude) and `.github/plugin/marketplace.json`
(Copilot) that list the plugin via `source: "./agency/plugins/ado-aw"`, so
`/plugin marketplace add <repo>` detects it. `ado-aw init --agency` scaffolds the
plugin under `agency/plugins/ado-aw/` plus those root catalogs.

Align terminology on the canonical brand "Azure DevOps Agentic Workflows": the
authored markdown spec is an "agentic workflow"; "pipeline" is reserved for the
compiled ADO execution artifact. Swept the init-generated output, root catalogs,
README, AGENTS.md title/prose, and user-facing CLI help strings.

Versions stay lock-step with the compiler via release-please `extra-files`: the
plugin manifest, both root catalogs (metadata + plugin entry), and the pinned
prompt URLs in the agent + create/update/debug skills bump on each release.
`init` embeds the canonical files via include_str! and writes them verbatim; the
duplicate src/data/agency-plugin tree is removed. Parity tests assert the
scaffold matches the canonical source byte-for-byte. .gitattributes forces LF
under agency/plugins/** and the root catalogs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address Rust PR Reviewer feedback on #1102:
- `--agency` help text said `.github/ado-aw` (stale); the scaffold writes to
  `agency/plugins/ado-aw` plus repo-root marketplace catalogs.
- Extend test_init_agency_matches_canonical_source to verify all 13 embedded
  plugin files byte-for-byte (was 9), covering the previously-unchecked
  update/debug/manage-lifecycle/audit-build skills.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add docs/agency-plugin.md (canonical layout, skills, mcp-author wiring,
self-contained root marketplace catalogs, init --agency scaffolding,
release-please version-locking, shared-marketplace listing) and index it
from AGENTS.md, matching the repo's one-page-per-concept docs convention.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 0.37.0->0.38.0 release landed on main while this PR was open, bumping
Cargo.toml but not the not-yet-merged plugin files. Resync the literal
versions (plugin.json, both root catalogs, and the pinned prompt URLs in the
agent + create/update/debug skills) so the plugin matches the compiler.
release-please extra-files keeps them in lock-step on future releases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jamesadevine jamesadevine force-pushed the copilot/extend-init-command-agency-plugin branch from 1e0fcf3 to d4b2219 Compare June 23, 2026 09:11
@jamesadevine

Copy link
Copy Markdown
Collaborator

/rust-review

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Rust PR Reviewer completed successfully!

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Rust PR Review

Summary: Looks good overall — clean design, solid tests — but there's one user-visible bug to fix before merging.


Findings

🐛 Bugs / Logic Issues

  • doctor.sh written without execute permission (src/init.rs:171–173, agency/plugins/ado-aw/scripts/doctor.sh): tokio::fs::write does not set any file mode — it inherits umask. The file is also stored in git as 100644 (verified with git ls-files --format='%(objectmode)'). The plugin README documents ./scripts/doctor.sh as the invocation, but that will produce Permission denied on macOS/Linux since the scaffolded file is not executable. Either:

    1. Change the git mode to 100755 (git update-index --chmod=+x) and add a std::os::unix::fs::PermissionsExt call after the write for the two script files, or
    2. Update the README to bash ./scripts/doctor.sh (simpler and cross-platform consistent with PowerShell).
  • Truncated doc comment (tests/init_tests.rs:279): The first line of the test_init_force_flag_is_advertised_in_help doc comment was accidentally deleted. Line 279 currently reads /// actual purpose: bypassing the GitHub-remote guard... (mid-sentence). The deleted line was /// Test that \--force` is advertised in `init --help` and describes its`. Tests pass, but the comment is misleading.

⚠️ Suggestions

  • dest.parent() == None silent skip (src/init.rs:166, 178): if let Some(parent) = dest.parent() { create_dir_all } silently skips directory creation when parent() is None. With the hardcoded constant paths this is harmless in practice, but a bail! or unconditional create_dir_all(plugin_root) before the loop would make failures explicit rather than cascading to a cryptic write error.

  • .github/agents/ado-aw.agent.md not in release-please extra-files: The in-repo agent file has v0.37.0 hardcoded in prompt URLs, but isn't tracked for version bumps in release-please-config.json. The compiled template (src/data/init-agent.md) handles substitution correctly, but this checked-in file will silently drift on every release. Pre-existing, but the PR is already touching release-please-config.json — good opportunity to add it.

✅ What Looks Good

  • Using include_str! for all embedded files is the right call — mismatches are compile-time errors, not runtime surprises.
  • The parity test (test_init_agency_matches_canonical_source) is excellent: it directly asserts byte-for-byte identity between the embedded files and the canonical source, making template drift impossible to miss.
  • Error handling is consistent throughout — all tokio::fs calls use .with_context() with actionable messages.
  • The --agency flag as additive (standard agent file always written) is the correct design; the clap derive wiring in main.rs is clean.
  • The release-please extra-files wiring for lock-step versioning of the plugin manifest and marketplace catalogs is well-structured.

Generated by Rust PR Reviewer for issue #1102 · 472.8 AIC · ⌖ 12.6 AIC · ⊞ 33.8K ·
Comment /rust-review to run again

Round 2 review (run 28016634353) on #1102:

- doctor.sh not executable: scaffolded copies (tokio::fs::write) and the
  checked-in file (git 100644) were non-exec, so `./scripts/doctor.sh` would
  fail with Permission denied. Mark the canonical file 100755 and document the
  cross-platform-safe `bash ./scripts/doctor.sh` invocation in the plugin
  README + dispatcher agent.
- tests/init_tests.rs: restore the truncated first line of the
  test_init_force_flag_is_advertised_in_help doc comment.
- src/init.rs: replace the silent `if let Some(parent)` skip with an explicit
  parent-directory resolution + error, so a missing parent fails loudly.
- release-please: track the checked-in .github/agents/ado-aw.agent.md for
  version bumps (add x-release-please-version markers to src/data/init-agent.md
  prompt URLs + list it in extra-files) so it no longer drifts on each release.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jamesadevine

Copy link
Copy Markdown
Collaborator

/rust-review

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Rust PR Reviewer completed successfully!

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Rust PR Review

Summary: Mostly looks good — one real bug, one minor suggestion.

Findings

🐛 Bugs / Logic Issues

  • src/init.rs:171–175doctor.sh written non-executable

    tokio::fs::write creates files with mode 0644 (subject to umask); no set_permissions call follows. The canonical doctor.sh in the repo is -rwxr-xr-x, but the scaffolded copy won't be. Users who try ./doctor.sh will get Permission denied. sh doctor.sh still works, but it's a UX surprise and breaks the "just run the doctor" flow.

    The project already has the pattern in src/compile/common.rs:81:

    std::fs::set_permissions(tmp.path(), std::fs::Permissions::from_mode(mode))

    A minimal fix after the tokio::fs::write for doctor.sh:

    #[cfg(unix)]
    if rel_path.ends_with(".sh") {
        use std::os::unix::fs::PermissionsExt;
        tokio::fs::set_permissions(&dest, std::fs::Permissions::from_mode(0o755))
            .await
            .with_context(|| format!("Failed to set executable bit: {}", dest.display()))?;
    }

    The tests assert existence but not permissions, so add a #[cfg(unix)] assertion to test_init_agency_generates_plugin to guard this going forward.

⚠️ Suggestions

  • release-please-config.json — plain-string extra-files for agent/skill .md files

    The four plain-string entries (agency/plugins/ado-aw/agents/ado-aw.md, three skills) trigger release-please's regex-replace mode. This only works because those files contain the bare version string tagged with <!-- x-release-please-version -->. If someone adds a version reference to compile-and-validate/SKILL.md, manage-lifecycle/SKILL.md, or audit-build/SKILL.md without adding them here, the bump will silently be missed. A comment in the JSON (or a README note) calling out which skill files are intentionally omitted would save future confusion.

✅ What Looks Good

  • Error handling: every fallible call has a .with_context()-decorated ?. No stray unwrap() in production paths.
  • test_init_agency_matches_canonical_source: the byte-for-byte parity test is excellent — it closes the drift loop between embedded files and the checked-in source of truth.
  • No path traversal surface: all rel_path values are compile-time &str constants — no user input flows into path joins, so no traversal risk.
  • Release-please extra-files JSON paths: correctly targets the version fields in plugin.json and both marketplace catalogs with explicit JSONPath entries.

Generated by Rust PR Reviewer for issue #1102 · 289.9 AIC · ⌖ 12.3 AIC · ⊞ 33.8K ·
Comment /rust-review to run again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants