You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Select supported agent clients and configuration scope - #20932
Users should choose their agents, not skill folders. agent init, new, and init now share client selection and project/global scope.
Use stable CLI IDs copilot, claude, and opencode, with localized GitHub Copilot, Claude Code, and OpenCode labels.
Prompt agents → assets → scope. Preselect detected agents; use Copilot only when none are detected.
Write only to selected clients and scope, deduplicating shared destinations. Selecting no agents/assets performs no agent writes. MCP remains a standalone opt-in.
Keep scanners read-only, client metadata focused on destinations, and configuration writes in shared helpers.
This PR provides the foundation for aspire-skills plugin support by letting users choose their agent clients and installation scope rather than filesystem locations. Clients can share skill directories while requiring different native plugin registration, so client selection determines which installation behavior is needed, while detection supplies sensible defaults. This keeps the user-facing flow stable as native plugin support is added, while preserving copied-skill installation in this intermediate layer.
This layer retains copied skills and the existing bundle. Native plugins #20946 and bundle retirement #20947 remain separate follow-ups.
aspire agent init --agents claude --scope project --skills aspire --mcp=false
Retain main's dead Playwright scanner cleanup and resolve the overlapping Copilot detection test using editor evidence without a fabricated CLI probe.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c0f73663-c37c-4c5a-b83d-89f0b8d13c5f
Replaces skill-folder selection with supported agent-client and project/user scope selection while retaining existing skill acquisition and MCP behavior.
Changes:
Adds Copilot, Claude, and OpenCode client selection and scoped destinations.
Use --agents and project/global scope, default to detected and universal-skill clients, and leave agent-specific legacy skill directories untouched.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c0f73663-c37c-4c5a-b83d-89f0b8d13c5f
Selection, defaults, MCP consent, opt-outs, and installation scope
NewCommand.cs, InitCommand.cs, and McpInitCommand.cs
Chained setup and legacy delegation
McpConfigFileHelper.cs and OpenCode\OpenCodePaths.cs
JSON/JSONC precedence, pin preservation, validation, and owning-file migration
Hook configurator and Playwright installer
Selected-client/scope routing while preserving existing policies
CLI resources, unit tests/snapshots, E2E consumers, and installation documentation
Help, summaries, consumers, and regression coverage
The complete changed-path inventory is retained in pr-metadata.json.
Change Categories
CLI changes
Test changes
Hosting integration changes
Dashboard implementation changes
Template implementation changes
Client/component library changes
VS Code extension changes
CI infrastructure changes
Test Scenarios Executed
Scenario 1: Source build and existing focused regressions
Objective: Verify the changed CLI compiles and preserves existing agent, new/init, interaction, installer, and hook behavior.
Coverage Type: Build/unit regression
Status: ✅ Passed — 955 existing regressions.
Steps:
Built Aspire.Cli.Tests and its CLI dependencies with the temporary matrix import.
Ran the focused test classes through the system ARM64 .NET host.
Excluded Windows-incompatible Bash tests, quarantined tests, and outerloop tests.
Evidence:source-build.log, source-tests.log, and run-source-matrix.ps1.
Observations: The build completed with zero warnings/errors. The combined source run included these 955 regressions and the 831 matrix cases below: 1,786 passed, zero failed, zero skipped, in 2m 24s 589ms. Filter-excluded tests are outside that total.
Evidence:matrix-results.csv, matrix-summary.json, and matrix-receipts\N0001.json through N0765.json.
Observations: Explicit supported clients worked without detection. Omitted selection used detected clients or the Copilot fallback. Selected clients and scope determined destinations; shared locations were coalesced, and opposite-scope/unselected-exclusive files were preserved.
Expected Unhappy-Path Outcome:none and no-assets selections leave agent configuration unchanged. Across both source matrices, 149 rows verified no agent writes.
Global shared skills were tested with a fake home. External acquisition used controlled existing test services; the 144 recorded Playwright generation calls were fake dependency calls, not real npm installations.
Exercised every nonempty client subset with skills-only, MCP-only, both assets, and neither asset, using both scopes where applicable.
Cleared all clients and verified subsequent prompts were skipped.
Accepted default choices for all eight detection profiles and checked the resulting destinations.
Evidence:matrix-results.csv, matrix-receipts\I001.json through I066.json, and source-tests.log.
Observations: Assertions verified offered choices, preselection, prompt sequence, defaults, and resulting files. These are 66 controller-fixture cases, not 66 real-terminal sessions. No tracked test/project files were changed.
Expected Unhappy-Path Outcome: Clearing clients skips later asset/scope prompts; clearing all assets skips scope and agent writes.
Scenario 4: Exact-head native CLI configuration and preservation
Objective: Verify installed PR behavior in fresh projects, including scope routing, OpenCode precedence, pins, invalid configuration, and command consumers.
Status: ✅ Passed — 37/37 scenarios in the final fresh-project rerun.
Steps:
Installed and version-verified the Windows ARM64 dogfood artifact.
Created fresh projects using the downloaded PR hive.
Executed the scenario groups below and checked exits, inventories, preservation, and idempotence.
Scenario group
Cases
Result
Help and standalone MCP boundary
1
Agent options exposed; new/init do not expose MCP opt-in; hidden legacy help intentionally empty
none overrides enabled assets/Global scope
1
No agent writes
Every nonempty Project client subset
7
Correct copied-skill/MCP destinations, shared roots, and idempotence
Omitted scope/skill/MCP defaults
1
Project, bundled defaults, no MCP
Every nonempty Global MCP client subset
7
Correct supported override paths
Claude private Global skills and MCP
1
Skills and MCP written under the private override
OpenCode dual JSON/JSONC configurations
12
Pins, inherited deprecated commands, invalid containers, and precedence preserved in both scopes
Explicit OpenCode file authority
1
Adjacent sibling does not override explicit-file behavior
No assets with legacy configuration
1
No migration or writes
Invalid selections/options
1
Multiple invalid inputs fail without agent files
Legacy MCP delegation
2
Default/custom configuration behavior preserved
new chaining
1
Copied skills configured without MCP
init chaining
1
Copied skills configured while existing MCP is preserved
Evidence:native-final-results.json, native-final-scenarios.log, per-command logs, and native-final-inventory-*.json.
Observations: Inherited OpenCode pins were preserved. Effective deprecated commands were repaired in their owning JSON document rather than shadowed in JSONC. Explicit-file overrides remained authoritative.
Expected Unhappy-Path Outcome: Invalid inputs/configuration return nonzero exits and diagnostics without overwriting rejected files. Invalid inherited OpenCode containers leave both documents unchanged.
Native Global MCP used supported overrides. Native Global copied skills used Claude's private override; universal Global .agents\skills coverage remained in fake-home source fixtures.
Created fresh projects and launched the CLI in an owned terminal panel.
Exercised the decisions below with actual terminal input.
Checked exits, resulting files, preserved settings, and skipped prompts.
Case
Observed result
Clear all clients
Clearing preselected Copilot skipped remaining prompts and produced no agent files
Accept bundled defaults
Seven default skills at each unique Project root; CLI-only tools unchecked; MCP No and Project scope defaults
MCP Yes with Project
Claude skills and shared Project MCP written; Global override did not redirect Project writes
Select Global from scope menu
Down selected Global; installation used only the private Claude override and preserved the model/custom hook
Clear all assets
--skills none plus default MCP No skipped scope and agent writes
Evidence:interactive-results.json, interactive-transcript.txt, interactive-screen-excerpts.txt, interactive-file-inventory.json, and interactive-configuration-documents.json.
Observations: These five executions are additional to the 66 controller cases. The MCP-Yes run accepted Project; a fresh fixture independently verified Global using Down and Enter.
Expected Unhappy-Path Outcome: Clearing clients/assets succeeds without agent files or inappropriate later prompts.
Scenario 6: E2E consumer compilation
Objective: Verify the changed CLI E2E consumers still compile.
Coverage Type: Build validation
Status: ✅ Passed — build only; Docker execution not performed.
Created a fresh empty C# AppHost from the downloaded PR hive.
Started it using an explicit AppHost path and --isolated.
Ran describe, loaded the dashboard, and captured screenshot/accessibility evidence.
Closed only the owned browser tab, stopped the exact AppHost, and parsed the post-stop registry.
Evidence:smoke-start.log, smoke-describe.log, smoke-stop.log, smoke-stop-receipt.json, dashboard.png, and dashboard-snapshot.yml.
Observations:describe returned {"resources":[]}. The dashboard displayed zero resources, as expected for an empty AppHost. The post-stop isolated registry contained zero entries. The stopped dashboard's login token was redacted from retained evidence.
Expected Boundary Outcome: An empty AppHost renders an empty resource list rather than an error.
✅ PR VERIFIED for the tested Windows ARM64 scenarios at the exact commit above.
No product defect was found in the final runs, and no production changes were needed. Initial harness compilation/temp-directory issues and four incorrect native-harness expectations were corrected in the external harness; all affected native cases were rerun in fresh projects.
Recommendations and Coverage Limits
Linux/macOS, Windows-incompatible Bash_* tests, quarantined tests, outerloop tests, and Docker E2E execution remain unvalidated by this run. E2E compilation does not replace Docker execution.
The 831-row matrix is exhaustive for its declared axes, not every filesystem failure, client version, supplemental boundary variation, or command-consumer cross-product. Source acquisition is controlled through existing fakes. Native plugin-layer behavior and a formal security review are outside this result.
PR Comment Status
Posted at the user's request. No PR title/body changes were made.
Cleanup / Inspection Status
Completed. The owned AppHost stopped, browser tab closed, and terminal exited. Temporary installations/projects and uniquely owned build outputs were removed. Evidence and exact validation commands remain in the saved report under pr20932-client-scenarios\execution.
The worktree was clean at final verification. No commit, push, branch/base/stack change, or parent/native-layer edit was performed.
Use JSONC parsing for commented or trailing-comma MCP configs
src/Aspire.Cli/Agents/AgentClient.cs:40
The new MCP write path reads .vscode/mcp.json with Copilot's default strict JSON options before checking whether a repair is needed. VS Code allows comments and trailing commas in this file, so valid editor configuration makes agent init --agents copilot --scope project --skills none --mcp report malformed JSON and exit unsuccessfully, even without a deprecated entry. Use ConfigurationHelper.ParseOptions for these reads and add a regression covering a commented configuration and a trailing comma.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Users should choose their agents, not skill folders.
agent init,new, andinitnow share client selection and project/global scope.copilot,claude, andopencode, with localized GitHub Copilot, Claude Code, and OpenCode labels.This PR provides the foundation for
aspire-skillsplugin support by letting users choose their agent clients and installation scope rather than filesystem locations. Clients can share skill directories while requiring different native plugin registration, so client selection determines which installation behavior is needed, while detection supplies sensible defaults. This keeps the user-facing flow stable as native plugin support is added, while preserving copied-skill installation in this intermediate layer.This layer retains copied skills and the existing bundle. Native plugins #20946 and bundle retirement #20947 remain separate follow-ups.
Related to #20247