diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 4f8d4ba2a..ef99958b1 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,7 +9,8 @@ { "name": "microsoft-finops-toolkit", "version": "15.0.0", - "source": "./plugins/microsoft-finops-toolkit", + "source": "./src/templates/agent-plugin", + "strict": true, "description": "Microsoft FinOps toolkit plugin for AI-powered cloud financial management.", "category": "finops", "homepage": "https://aka.ms/finops/toolkit" diff --git a/src/powershell/Tests/Unit/AgentPlugins.Tests.ps1 b/src/powershell/Tests/Unit/AgentPlugins.Tests.ps1 index ccb2a66d4..c702de2b2 100644 --- a/src/powershell/Tests/Unit/AgentPlugins.Tests.ps1 +++ b/src/powershell/Tests/Unit/AgentPlugins.Tests.ps1 @@ -34,7 +34,7 @@ Describe 'Agent plugin manifest' { $root.agents | Should -Be './agents/' $root.mcpServers | Should -Be '.mcp.json' $claude.agents | Should -BeNullOrEmpty - $claude.mcpServers | Should -BeNullOrEmpty + $claude.mcpServers | Should -Be './.mcp.json' $claude.outputStyles | Should -Be './output-styles/' } @@ -48,11 +48,21 @@ Describe 'Agent plugin manifest' { $claude = Get-Content (Join-Path $script:Plugin '.claude-plugin/plugin.json') -Raw | ConvertFrom-Json $root.mcpServers | Should -Be '.mcp.json' - $claude.mcpServers | Should -BeNullOrEmpty - $claude.agents | Should -BeNullOrEmpty + $claude.mcpServers | Should -Be './.mcp.json' Join-Path $script:Plugin '.mcp.json' | Should -Exist } + It 'Declares resolvable paths for every Claude component' { + $claude = Get-Content (Join-Path $script:Plugin '.claude-plugin/plugin.json') -Raw | ConvertFrom-Json + $paths = @($claude.commands) + @($claude.skills) + @($claude.mcpServers) + @($claude.outputStyles) + + $paths.Count | Should -BeGreaterOrEqual 4 + $paths | ForEach-Object { + $_ | Should -Not -BeNullOrEmpty + Join-Path $script:Plugin $_ | Should -Exist + } + } + It 'Uses unpinned Azure MCP latest package in .mcp.json' { $mcp = Get-Content (Join-Path $script:Plugin '.mcp.json') -Raw | ConvertFrom-Json $args = $mcp.mcpServers.'azure-mcp-server'.args @@ -64,13 +74,17 @@ Describe 'Agent plugin manifest' { } Describe 'Agent plugin components' { - It 'Ships agent definitions as NAME.agent.md files' { - $agents = Get-ChildItem (Join-Path $script:Plugin 'agents') -Filter '*.agent.md' - $agents.Count | Should -BeGreaterThan 0 + It 'Ships agent definitions as Claude-compatible NAME.md files' { + $agents = Get-ChildItem (Join-Path $script:Plugin 'agents') -Filter '*.md' + + $agents.Count | Should -Be 5 + $agents.Name | ForEach-Object { + $_ | Should -Not -Match '\.agent\.md$' + } } It 'Gives every agent a name and description in front matter' { - Get-ChildItem (Join-Path $script:Plugin 'agents') -Filter '*.agent.md' | ForEach-Object { + Get-ChildItem (Join-Path $script:Plugin 'agents') -Filter '*.md' | ForEach-Object { $content = Get-Content $_.FullName -Raw $content | Should -Match '(?ms)^---\s.*^name:\s*\S.*^description:\s*\S.*^---' } @@ -167,7 +181,7 @@ Describe 'Plugin discovery and marketplaces' { It 'Uses repository-root-relative marketplace sources' { $marketplaces = @{ '.github/plugin/marketplace.json' = './plugins/microsoft-finops-toolkit' - '.claude-plugin/marketplace.json' = './plugins/microsoft-finops-toolkit' + '.claude-plugin/marketplace.json' = './src/templates/agent-plugin' } foreach ($marketplace in $marketplaces.Keys) @@ -177,4 +191,11 @@ Describe 'Plugin discovery and marketplaces' { $entry.source | Should -Be $marketplaces[$marketplace] } } + + It 'Enables strict mode explicitly for the Claude plugin' { + $json = Get-Content (Join-Path $script:RepoRoot '.claude-plugin/marketplace.json') -Raw | ConvertFrom-Json + $entry = $json.plugins | Where-Object { $_.name -eq 'microsoft-finops-toolkit' } + + $entry.strict | Should -BeTrue + } } \ No newline at end of file diff --git a/src/templates/agent-plugin/.claude-plugin/plugin.json b/src/templates/agent-plugin/.claude-plugin/plugin.json index 109c206d7..21d3b74b8 100644 --- a/src/templates/agent-plugin/.claude-plugin/plugin.json +++ b/src/templates/agent-plugin/.claude-plugin/plugin.json @@ -14,5 +14,6 @@ "skills": [ "./skills/" ], + "mcpServers": "./.mcp.json", "outputStyles": "./output-styles/" } diff --git a/src/templates/agent-plugin/agents/azure-capacity-manager.agent.md b/src/templates/agent-plugin/agents/azure-capacity-manager.md similarity index 100% rename from src/templates/agent-plugin/agents/azure-capacity-manager.agent.md rename to src/templates/agent-plugin/agents/azure-capacity-manager.md diff --git a/src/templates/agent-plugin/agents/chief-financial-officer.agent.md b/src/templates/agent-plugin/agents/chief-financial-officer.md similarity index 100% rename from src/templates/agent-plugin/agents/chief-financial-officer.agent.md rename to src/templates/agent-plugin/agents/chief-financial-officer.md diff --git a/src/templates/agent-plugin/agents/finops-practitioner.agent.md b/src/templates/agent-plugin/agents/finops-practitioner.md similarity index 100% rename from src/templates/agent-plugin/agents/finops-practitioner.agent.md rename to src/templates/agent-plugin/agents/finops-practitioner.md diff --git a/src/templates/agent-plugin/agents/ftk-database-query.agent.md b/src/templates/agent-plugin/agents/ftk-database-query.md similarity index 100% rename from src/templates/agent-plugin/agents/ftk-database-query.agent.md rename to src/templates/agent-plugin/agents/ftk-database-query.md diff --git a/src/templates/agent-plugin/agents/ftk-hubs-agent.agent.md b/src/templates/agent-plugin/agents/ftk-hubs-agent.md similarity index 100% rename from src/templates/agent-plugin/agents/ftk-hubs-agent.agent.md rename to src/templates/agent-plugin/agents/ftk-hubs-agent.md