feat(plugins): add FinOps Toolkit agent plugins#2167
Conversation
There was a problem hiding this comment.
Pull request overview
Adds FinOps Toolkit “agent plugin” assets (Copilot CLI + Claude), expands shared FinOps/Cost Management agent skills, and wires plugin/marketplace version updates into the repo versioning script.
Changes:
- Introduces a new Copilot CLI plugin template (commands, agents, skills, marketplace metadata).
- Updates Claude plugin agents/output-style and extends the shared skill/query catalog guidance.
- Extends
Update-Version.ps1to update Copilot plugin and marketplace manifests.
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| src/templates/copilot-plugin/README.md | New Copilot CLI plugin README covering install and included assets. |
| src/templates/copilot-plugin/plugin.json | New Copilot CLI plugin manifest (commands/agents/skills + MCP server). |
| src/templates/copilot-plugin/commands/ftk/ytd-report.md | New Copilot command prompt for fiscal YTD reporting. |
| src/templates/copilot-plugin/commands/ftk/mom-report.md | New Copilot command prompt for month-over-month reporting. |
| src/templates/copilot-plugin/commands/ftk/hubs-healthCheck.md | New Copilot command prompt for hub version + freshness checks. |
| src/templates/copilot-plugin/commands/ftk/hubs-connect.md | New Copilot command prompt for hub discovery/connection + env persistence. |
| src/templates/copilot-plugin/commands/ftk/cost-optimization.md | New Copilot command prompt for Advisor/orphaned/rightsizing optimization report. |
| src/templates/copilot-plugin/agents/ftk-hubs-agent.agent.md | New Copilot agent definition for hub deployment/ops. |
| src/templates/copilot-plugin/agents/ftk-database-query.agent.md | New Copilot agent definition for FinOps hubs KQL evidence ownership. |
| src/templates/copilot-plugin/agents/finops-practitioner.agent.md | New Copilot agent definition for practitioner orchestration role. |
| src/templates/copilot-plugin/agents/chief-financial-officer.agent.md | New Copilot agent definition for CFO framing role. |
| src/templates/copilot-plugin/.build.config | Build packaging config for the Copilot plugin template. |
| src/templates/claude-plugin/README.md | Updates Claude plugin README to reflect new agent topology and catalog notes. |
| src/templates/claude-plugin/output-styles/ftk-output-style.md | Extends output style guidance (capacity mapping, data sufficiency language, terminology). |
| src/templates/claude-plugin/agents/ftk-database-query.md | Updates Claude agent guidance (Kusto boundary/ownership, query strategy). |
| src/templates/claude-plugin/agents/finops-practitioner.md | Updates orchestration model and FinOps capability wording. |
| src/templates/claude-plugin/agents/chief-financial-officer.md | Updates CFO agent boundaries and collaboration expectations. |
| src/templates/claude-plugin/agents/azure-capacity-manager.md | Adds new Claude subagent for Azure capacity evidence. |
| src/templates/claude-plugin/.claude-plugin/plugin.json | Updates Claude plugin manifest (agents list + version). |
| src/templates/agent-skills/finops-toolkit/SKILL.md | Expands query catalog list and updates guidance wording/links. |
| src/templates/agent-skills/finops-toolkit/references/top-cost-drivers.md | Adjusts recommended workflow to prefer aggregate queries before row-level bases. |
| src/templates/agent-skills/finops-toolkit/references/finops-hubs.md | Updates catalog guidance and reference links (FinOps Foundation). |
| src/templates/agent-skills/finops-toolkit/references/custom-dimension-analysis.md | Updates workflow guidance to prefer scenario-specific catalog queries first. |
| src/templates/agent-skills/finops-toolkit/references/cost-comparison.md | Updates comparison workflow guidance to prefer aggregate queries first. |
| src/templates/agent-skills/finops-toolkit/README.md | Updates catalog count and query descriptions. |
| src/templates/agent-skills/azure-cost-management/references/azure-vm-rightsizing.md | Updates FinOps Framework capability link (usage optimization). |
| src/templates/agent-skills/azure-cost-management/references/azure-savings-plans.md | Updates FinOps Framework capability link (rate optimization). |
| src/templates/agent-skills/azure-cost-management/references/azure-retail-prices.md | Updates FinOps Framework capability link (rate optimization). |
| src/templates/agent-skills/azure-cost-management/references/azure-orphaned-resources.md | Updates FinOps Framework capability link (usage optimization). |
| src/templates/agent-skills/azure-cost-management/references/azure-commitment-discount-decision.md | Updates FinOps Framework capability link (rate optimization). |
| src/scripts/Update-Version.ps1 | Updates prerelease label behavior and expands version propagation to Copilot + marketplace. |
| .github/plugin/marketplace.json | Adds Copilot CLI marketplace manifest for plugin distribution. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RolandKrummenacher
left a comment
There was a problem hiding this comment.
Review summary
The new Copilot CLI plugin, the azure-capacity-manager agent, and the evidence-delegation restructuring of the personas are solid, well-written work. The Update-Version.ps1 label/bump refactor also fixes a real prerelease bug (see inline note). Two issues should block merge as a standalone PR, plus a couple of consistency fixes — details inline.
Blockers
- Plugin/marketplace versions are pinned to
13.0.0while the repo is at15.0.0-dev.0;claude-plugin/plugin.jsonis actually downgraded from15.0.0→13.0.0. - The skill docs are bumped from 17 → 37 queries and link ~20
.kqlfiles (ai-*,anomaly-*,commitment-utilization-score, etc.) that do not exist anywhere on the branch — only the original 17 catalog files are present.
Consistency
3. Three different query counts across docs: Claude docs say 37, the new Copilot README says 21, actual = 17.
4. Update-Version.ps1 updates plugins[].version in marketplace.json but never the top-level metadata.version, so it will stay pinned at 13.0.0 across future releases.
If the 20 new query files land in a sibling split PR, the doc/count bumps should travel with them; otherwise the files belong here.
RolandKrummenacher
left a comment
There was a problem hiding this comment.
Follow-up: the /ftk-ytd-report command hardcodes a July–June fiscal year ("Our fiscal year ends on June 30th."). That's Microsoft's internal FY, not the customer's. Most orgs running this plugin are on a calendar fiscal year (Jan–Dec) or some other fiscal-year-end month, so for them the command computes the wrong year-to-date window and forecasts to the wrong date.
This PR introduces it in the new copilot-plugin/commands/ftk/ytd-report.md; the same text also already exists in claude-plugin/commands/ftk/ytd-report.md and is surfaced in both README command tables ("forecast through end of fiscal year (June 30)"). Worth making the fiscal-year-end configurable — e.g. read it from .ftk/environments.local.md, prompt for it, or default to the calendar year — rather than baking in June 30. Since the Claude copy has the same issue, consider fixing both so the plugins stay in sync.
RolandKrummenacher
left a comment
There was a problem hiding this comment.
One more class of hardcoding worth a careful look — a likely real-data leak. Most of the other hardcoded values I checked are fine (illustrative ago(30d) windows, eastus example regions, list-price estimates, 00000000-… placeholder GUIDs in the READMEs, currency-formatting guidance). The exception is the example table in copilot-plugin/agents/ftk-database-query.agent.md, which uses real-looking identifiers instead of placeholders — see inline. Minor: hubs-healthCheck.md enumerates public and China clouds but not Azure US Government — worth confirming that's intentional.
RolandKrummenacher
left a comment
There was a problem hiding this comment.
The autonomous report commands (/ftk-mom-report, /ftk-ytd-report) depend on an ftk/knowledge/ knowledge base as a read input, but nothing in the plugin creates or populates it — see inline. ftk/notes/, ftk/planning/, and ftk/results/ are fine (runtime output dirs the agent creates on the fly); ftk/knowledge/ is the one that's expected to pre-exist. Same issue is present in the claude-plugin copies of both commands.
RolandKrummenacher
left a comment
There was a problem hiding this comment.
Final directory-related finding: how the plugins' skill folders are wired makes it likely they fail to load for many consumers. Details inline on the skill symlink. (The separate ftk/knowledge/ scaffolding gap is already in another thread.)
RolandKrummenacher
left a comment
There was a problem hiding this comment.
Design inconsistency in how shared content is delivered, and it has already caused a shipping bug. Skills are shared by reference (symlinks into agent-skills/), but agents and commands are duplicated by value into each plugin — so skills can't drift, but agents/commands silently can, and have. Details inline.
…t agent Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…etry - Default portal/CLI to Low (read-only) access; keep autonomous reporting so the 19 scheduled report tasks run unattended on a least-privilege identity. Stop defaulting subscription-wide Reader. (Roland H1) - Verify the downloaded recipe package: require an expected SHA-256 (fail-closed) and an https host allowlist before Expand-Archive. (Roland H2) - Remove dead bin/telemetry.sh, its hardcoded App Insights key, and the no-op --no-telemetry / SRE_AGENT_NO_TELEMETRY opt-out. (Roland M4) - Parameterize deployer principalType so CI/CD OIDC service-principal deploys assign RBAC correctly. (Roland #2167-adjacent CI finding) Compiled azuredeploy.json + recipe zip are regenerated in a later build pass (two deferred tests remain red until then). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dge paths Update query catalog docs to the 17 shipped KQL files, mark fiscal year as a customizable example, repoint ftk/knowledge references to bundled skill assets, soften runaway language, and reconcile marketplace version to 15.0.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
RolandKrummenacher
left a comment
There was a problem hiding this comment.
Approving — all review findings are resolved at the tip:
- ✅ Leaked identifiers scrubbed from the working tree (
msbwftktreyhub+ tenant/subscription GUIDs replaced with placeholders) - ✅ Versions restored to
15.0.0(claude plugin.json + both marketplace.json fields) - ✅ Missing
azure-capacity-managerCopilot agent added - ✅ Catalog count corrected to 17 (matches actual)
- ✅ Fiscal-year assumption made explicit (July–June is an example only)
- ✅
ftk/knowledge/no longer referenced as an unscaffolded input
One non-blocking follow-up: the original identifiers still exist in git history (commit 173aedc2) since the scrub was a commit-on-top, not a history rewrite. Recommend scrubbing history (or confirming those resources are dead/rotated) as separate housekeeping — approving on the understanding that these are non-secret resource identifiers. Thanks for the quick turnaround!
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…gins # Conflicts: # docs-mslearn/toolkit/changelog.md
- Replace claude-plugin/copilot-plugin with src/templates/agent-plugin - Remove deprecated azure-cost-management skill and drop /ftk/cost-optimization - Keep finops-toolkit-only command set (hubs-connect, hubs-healthCheck, mom-report, ytd-report) - Fix marketplace/discovery pointers and schemas - Update build + parity tests for consolidated layout Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Validation and execution proof update for this PR:
Spec validation RTMs completed against all required references:
Verdict: PASS for all three (with git-based install/distribution model). Execution proof:
Symlink correctness:
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Why
The FinOps Toolkit needed one plugin implementation that stays consistent across Claude Code, GitHub Copilot CLI, Visual Studio Code agent plugins, and the Azure SRE Agent packaging model. The previous split between
claude-pluginandcopilot-plugincreated drift risk and duplicated maintenance.This PR consolidates to a single source (
src/templates/agent-plugin) and removes deprecated surface area so we can ship one canonical FinOps plugin definition.What changed
Consolidated plugin template
src/templates/claude-pluginandsrc/templates/copilot-pluginwithsrc/templates/agent-plugin.plugin.jsonfor Copilot CLI and kept.claude-plugin/plugin.jsonfor Claude.src/templates/agent-plugin:.plugin.github/plugin/marketplace.json.claude-plugin/marketplace.jsonSkill and command surface cleanup
azure-cost-managementskill from the plugin payload.finops-toolkitskill./ftk/cost-optimizationfrom the command set./ftk/hubs-connect/ftk/hubs-healthCheck/ftk/mom-report/ftk/ytd-reportmom-reportandytd-reportinstructions to remove references to the removed skill.Build and validation wiring
Build-AgentPlugin.ps1for the consolidated layout.src/queries->skills/finops-toolkit/references/queriesdocs-mslearn->skills/finops-toolkit/references/docs-mslearnAgentPlugins.Tests.ps1to validate the single consolidated plugin shape.Validation
Spec conformance RTMs
Validated against:
Result: the FinOps Toolkit plugin artifact and primary marketplace entry pass the validated scope for all four specs with the current structure (git-based install path). Note: the secondary
microsoft-learnmarketplace entry uses an external URL source, which is supported by Claude and VS Code marketplace guidance but is outside the repo-relative plugin source shape documented by the Copilot marketplace page.Execution proof
Build-Toolkit.ps1 agent-pluginsucceeds.finops-toolkitskillInvoke-Pester ./src/powershell/Tests/Unit/AgentPlugins.Tests.ps1passes (16/16).