Skip to content

13.4: Load Aspire skills catalog from bundle manifest#17553

Merged
IEvangelist merged 14 commits into
mainfrom
ievangelist/dapine-skill-catalog-pr
May 29, 2026
Merged

13.4: Load Aspire skills catalog from bundle manifest#17553
IEvangelist merged 14 commits into
mainfrom
ievangelist/dapine-skill-catalog-pr

Conversation

@IEvangelist
Copy link
Copy Markdown
Member

@IEvangelist IEvangelist commented May 27, 2026

Closes #17551.

Summary

aspire agent init builds its installable skill catalog from a hardcoded SkillDefinition.All list that only knew about three bundle skills (aspire, aspireify, aspire-deployment). The published microsoft/aspire-skills bundle currently ships six skills, so aspire-init, aspire-monitoring, and aspire-orchestration were silently invisible to the CLI prompt and to --skills. Future bundle-only additions had the same problem.

This PR makes the bundle manifest the source of truth for bundled Aspire skill names, descriptions, defaults, language filters, and install exclusions, and keeps CLI-owned definitions only for skills that don't live in the bundle (playwright-cli, dotnet-inspect).

What changed

  • AspireSkillsBundle.GetSkillDefinitions() projects every skill from skill-manifest.json into installable SkillDefinition entries — bundle-derived defaults, applicable languages, and install excludes flow through automatically.
  • AgentInitCommand resolves the bundle before the skill prompt, merges the bundle-derived catalog with CLI-local static skills, and reuses the same resolved bundle for installation so we don't acquire/validate the bundle twice. CLI-local skills win on name collisions.
  • --skills help text no longer claims a stale hardcoded list and documents all/none.
  • AgentInitCommand.PromptAndChainAsync now takes an optional Func<SkillDefinition, bool> so callers express policy as data, not a hardcoded enum. The static helper ExcludeOneTimeSetupSkillsFromDefaults is backed by a single s_oneTimeSetupSkillNames set, so adding a future wiring/bootstrap-style bundle skill is a one-liner instead of an invisible behavior change. aspireify is preselected only when the workspace was just created by aspire init; aspire new already produced the skeleton, so preselecting aspireify would be redundant.
  • Skill descriptions shown in the prompt are derived from the SKILL.md front matter (single sentence after the **{TYPE} SKILL** marker), and the displayed catalog is sorted alphabetically for determinism. The leading-separator strip only runs when a **TYPE** prefix was actually trimmed, so descriptions like -Quickly do X. keep their leading character.
  • Bundle resolution failures are now silent fallbacks to the embedded snapshot rather than warnings — disconnected/airgapped users still get the full local catalog instead of seeing only playwright-cli and dotnet-inspect. The previous warning is demoted to LogDebug. When the caller passes --skills and names a non-CLI skill the bundle was expected to provide, the install failure is surfaced before the catalog-rejection error so the underlying cause isn't hidden behind a generic "value not in choices" message.
  • The MCP applicator participates in the interactive multi-select prompt for UX, but is no longer addressable via --skillsPromptForSelectionsAsync now accepts an optional bindingChoices subset, and the unified prompt restricts non-interactive validation to the actual SkillDefinition catalog. The non-interactive "value not in choices" error also strips Spectre markup so [bold]/[dim] tokens don't leak verbatim into the error output.
  • All user-facing strings are localized through the existing AgentCommandStrings .resx (with matching .xlf regen). Thrown InvalidOperationExceptions remain CultureInfo.InvariantCulture-formatted per the existing pattern in this area.
  • Validation (defense-in-depth): bundle skill names are NFC-normalized, must not be path-rooted or contain /, \, ., .., Path.GetInvalidFileNameChars(), or any char.IsControl character (covers U+0001–U+001F + C1 controls on Linux/macOS where GetInvalidFileNameChars is only { \0, / }), and Windows reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9, with or without extension) are rejected. Prompt markup is escaped; duplicate skill-name detection is case-insensitive.

Feature flag — aspireSkillsRemoteFetchEnabled (default off)

The GitHub release fetch path is now gated behind a new features:aspireSkillsRemoteFetchEnabled toggle (in KnownFeatures). 13.4 ships with this disabled, so out of the box aspire agent init only uses the cached bundle and the embedded .tgz snapshot baked into the CLI build. No network call goes out to github.com/microsoft/aspire-skills unless the user explicitly opts in.

Opt in with:

aspire config set features:aspireSkillsRemoteFetchEnabled true

When the flag is on, the resolution order stays cache → GitHub release → embedded snapshot (with sigstore provenance verification on the GitHub asset). When the flag is off, the order is cache → embedded snapshot. Cached bundles still work in both modes because the cache lookup runs before the flag check. This gives us a kill switch we can flip later (or per user) without shipping new CLI bits, and lets 13.4 ship the surface-area fix while we settle the remaining trust-and-distribution questions in the separate threat-model review.

Bundle versioning — how this works in practice

The CLI pins a single microsoft/aspire-skills version (AspireSkillsInstaller.Version = "0.0.1") and resolves bundles in order: versioned cache → GitHub release tagged with that version (if remote fetch is enabled) → embedded snapshot. Caches are version-keyed, so old versions self-evict after 7 days.

When microsoft/aspire-skills ships a new release, the existing scheduled workflow update-aspire-skills-bundle.yml (runs daily at 17:00 UTC and on-demand) handles the coordinated update via eng/scripts/update-aspire-skills-bundle.ps1:

  1. Detects the new aspire-skills release.
  2. Rewrites the Version constant, refreshes the embedded .tgz snapshot + metadata, and updates the SHA-256 in Aspire.Cli.csproj.
  3. Runs the AspireSkillsInstallerTests, AspireSkillsBundleTests, and AgentInitCommandTests against the new bundle.
  4. Opens an auto-PR ([Automated] Update Aspire skills bundle).

After that PR merges and ships in a new CLI build, users on the new CLI transparently pick up the new bundle — including any new skills the bundle adds, because the catalog is now driven by the manifest rather than a hand-maintained list. Users on older CLIs continue requesting the version they were built against.

Tests

  • AgentInitCommand_NonInteractive_AllBundleSkills_AreInstallableByName (integration): primes the bundle through IAspireSkillsInstaller, derives the skill list from bundle.GetSkillDefinitions(), and uses that same list for both --skills and the install assertions. Adding/removing a skill in the fake fixture (or the real bundle) requires no edits to the test body.
  • AgentInitCommand_NonInteractive_BundleOnlySkillsBeyondCliCatalog_AreInstallable (Hex1b end-to-end): focused regression guard for the three bundle-only names the original bug hid (aspire-init, aspire-monitoring, aspire-orchestration). Future bundle additions are intentionally out of scope so this stays a stable snapshot of the original regression.
  • InstallAsync_WhenRemoteFetchFeatureIsDisabled_SkipsGitHubAndUsesEmbedded and InstallAsync_WhenRemoteFetchFeatureIsDisabledAndCacheExists_UsesCacheWithoutNetwork: assert the new feature flag never reaches the network when off (HTTP handler throws on any call; attestation verifier asserted never called).
  • LoadAsync_ThrowsWhenSkillNameIsUnsafe (theory): parameterized rejection cases for control characters, non-NFC names, and Windows reserved device names (CON, CON.md, nul, LPT3, ...).
  • SimplifyDescription_ProducesExpectedSummary: regression cases for descriptions that start with - or : without a **TYPE** prefix — the leading separator is preserved.
  • Existing coverage: prompt catalog contents, --skills all, explicit bundle skill selection, unavailable-bundle fallback behavior, and aspire init vs aspire new default selection.

All AgentInitCommandTests (34/34), AspireSkillsBundleTests, and AspireSkillsInstallerTests pass locally; full Aspire.Cli.Tests suite green except for one unrelated, pre-existing Windows \r\n flake in ListConsoleLogsToolTests.ListConsoleLogsTool_ReturnsLogs_ForSpecificResource.

Manual verification

Installed the PR build, deleted the local skills cache, and disconnected the network — aspire new (with AI = Y) still surfaces the full catalog from the embedded snapshot. Previously the disconnected path silently dropped to just playwright-cli and dotnet-inspect.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist requested a review from mitchdenny as a code owner May 27, 2026 18:08
Copilot AI review requested due to automatic review settings May 27, 2026 18:08
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17553

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17553"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates aspire agent init to treat the Aspire skills bundle manifest (skill-manifest.json) as the source of truth for bundle-backed skills, so the interactive catalog doesn’t drift behind microsoft/aspire-skills.

Changes:

  • Load skill definitions dynamically from the resolved Aspire skills bundle manifest and reuse that resolved bundle for installation.
  • Adjust default-skill selection so standalone/aspire new no longer preselect aspireify, while aspire init still does.
  • Update tests and localized help text to reflect dynamic bundle-backed skills plus CLI-defined skills.

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Aspire.Cli.Tests/TestServices/FakePlaywrightServices.cs Extends the fake bundle manifest to include additional bundle-defined skills for test coverage.
tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs Updates assertions for new default-skill behavior and uses shared skill-name constants.
tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs Updates selection logic to find skills by name rather than static instances.
tests/Aspire.Cli.Tests/Commands/AgentInitCommandTests.cs Adds/updates tests for manifest-driven skill catalog and revised defaults.
tests/Aspire.Cli.Tests/Agents/CommonAgentApplicatorsTests.cs Updates tests to distinguish CLI-defined skills from bundle-defined skills.
tests/Aspire.Cli.Tests/Agents/AspireSkillsInstallerTests.cs Aligns installer tests with manifest-sourced bundle skill definitions.
tests/Aspire.Cli.Tests/Agents/AspireSkillsBundleTests.cs Adds coverage for enumerating manifest skills and updates existing bundle tests.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.zh-Hant.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.zh-Hans.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.tr.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ru.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.pt-BR.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.pl.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ko.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ja.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.it.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.fr.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.es.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.de.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/xlf/AgentCommandStrings.cs.xlf Updates localized --skills help text to mention dynamic bundle skills.
src/Aspire.Cli/Resources/AgentCommandStrings.resx Updates --skills option description text.
src/Aspire.Cli/Resources/AgentCommandStrings.Designer.cs Updates generated resource accessor doc comment for the changed string.
src/Aspire.Cli/Commands/InitCommand.cs Uses agent-init default mode that includes aspireify for the init flow and checks selection by name.
src/Aspire.Cli/Commands/AgentInitCommand.cs Adds manifest-sourced skill loading, default-mode handling, and bundle reuse during install.
src/Aspire.Cli/Agents/SkillDefinition.cs Removes hardcoded bundle skill entries; introduces bundle-skill factory, name checks, and name-based equality.
src/Aspire.Cli/Agents/AspireSkills/AspireSkillsBundle.cs Exposes manifest skill definitions and validates manifest skill descriptions.
Files not reviewed (1)
  • src/Aspire.Cli/Resources/AgentCommandStrings.Designer.cs: Language not supported

Comment thread src/Aspire.Cli/Commands/AgentInitCommand.cs Outdated
Comment thread src/Aspire.Cli/Commands/AgentInitCommand.cs Outdated
IEvangelist and others added 2 commits May 27, 2026 13:56
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist marked this pull request as draft May 28, 2026 12:22
IEvangelist and others added 2 commits May 28, 2026 10:55
…navailable warning

- Extract just the first sentence (after stripping the leading bold `**TYPE SKILL**` tag) for bundle skill descriptions shown in the agent init selection prompt so the list stays readable.

- Sort the merged skill catalog deterministically by name (OrdinalIgnoreCase) so prompt ordering is stable regardless of manifest order.

- When the Aspire skills bundle is unavailable (network failure, version mismatch, etc.), silently fall back to the CLI-defined skills instead of surfacing a user-visible warning. The installer already logs the underlying cause at debug, and the equivalent `LogWarning` paths on the corrupt-bundle catch blocks are demoted to `LogDebug` to match.

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

The embedded Aspire skills bundle ships inside the CLI binary as the
trusted last-resort fallback, and the on-disk cache is populated by this
installer itself. Both sources are gated by bundle version (the cache
directory is version-keyed), so the bundle manifest's supports range
should only gate fresh downloads from GitHub.

Previously, a prerelease CLI build whose version fell outside the
embedded snapshot's stamped range (e.g., a 13.5.x dogfood build paired
with a snapshot supporting '>=13.4.0 <13.5.0') would reject the embedded
bundle on every offline invocation, leaving the user with only the
CLI-defined PlaywrightCli and DotnetInspect skills.

Add a skipCompatibilityCheck parameter to AspireSkillsBundle.LoadAsync,
plumb it through CacheArchiveAsync, and apply it to the embedded install
and cache-load paths. The GitHub-download path keeps strict validation
because we don't otherwise know what we're getting.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
IEvangelist and others added 2 commits May 28, 2026 12:22
The default-skill selection in agent init was driven by a two-value enum
(AgentInitSkillDefaultMode) whose IncludeAspireify member named a specific
skill. That locks the design into a named set: every time a caller needs a
different default-selection rule, the enum has to grow another member.

Replace the enum with an optional Func<SkillDefinition, bool>? predicate
parameter on AgentInitCommand.PromptAndChainAsync. Semantics:

- null  -> trust the bundle author's SkillDefinition.IsDefault as-is
          (what 'aspire init' wants so aspireify chains into the flow)
- non-null -> caller decides which skills are pre-selected

The 'aspireify is one-time wiring' decision moves to the two call sites
that need it ('aspire new' and standalone 'aspire agent init') via an
internal AgentInitCommand.ExcludeAspireifyFromDefaults helper method.
No new enum values are needed when future contexts emerge.

Drops the dead IsDefaultSkill helper and the enum type. No user-visible
behavior change beyond what the predicate expresses.

Tests:
- Rename PromptAndChainAsync_WithIncludeAspireifyDefault_SelectsAspireify
  to PromptAndChainAsync_WithoutPredicateOverride_PreSelectsBundleDefaultsIncludingAspireify
  to match the new contract (no override = trust bundle's IsDefault).
- Add PromptAndChainAsync_WithExcludeAspireifyPredicate_DoesNotPreSelectAspireify
  to lock in the predicate-based override path.
- Add AgentInitCommand_NonInteractive_WithAllBundleSkillNames_InstallsEverySkillSurfacedByBundle
  as a regression guard: passing every bundle skill name to --skills must
  materialize all six SKILL.md files (aspire-init, aspire-monitoring,
  aspire-orchestration were invisible before this PR).
- Add AgentInitCommand_NonInteractive_WithExplicitBundleSkillName_InstallsBundleSkill
  proving bundle-only names are selectable via --skills now that the
  catalog comes from the manifest.
- Extend the Hex1b cache fixture to seed all six bundle skills and add
  AgentInitCommand_NonInteractive_WithAllSkills_InstallsEverySkillSurfacedByBundle
  as a full-stack regression guard against the original report.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adding a skill to the bundle (or to the test fixture) no longer requires
mirroring the change in test assertions:

- Integration test now derives the skill list from the bundle's manifest
  via IAspireSkillsInstaller, so --skills and the install assertions are
  data-driven against whatever the fake produces.
- Hex1b regression test now narrows to the bundle-only skill names
  (aspire-init/-monitoring/-orchestration) that the original bug hid.
  Future bundle additions don't widen this scope; the test stays a
  focused snapshot of the original regression.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist marked this pull request as ready for review May 28, 2026 17:48
… feature

13.4 ships with the GitHub bundle fetch path disabled; users get the embedded snapshot only. Setting features:aspireSkillsRemoteFetchEnabled to true re-enables the GitHub release acquisition and sigstore provenance verification path. The cache lookup and embedded fallback are unaffected, so cached bundles still load without network access.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist
Copy link
Copy Markdown
Member Author

PR #17553 Testing Report

PR Information

CLI Version Verification

  • Expected (PR head short SHA): 6beecaf7
  • Installed CLI reports: 13.5.0-pr.17553.g6beecaf7
  • Status: ✅ Verified

Changes Analyzed

The PR moves the installable skill catalog for aspire agent init away from a hardcoded SkillDefinition.All list and onto the microsoft/aspire-skills bundle manifest, adds a feature flag (features:aspireSkillsRemoteFetchEnabled, default off) gating GitHub remote fetch, and reworks the aspire new / aspire init agent-init policy so aspireify is preselected only when aspire init just produced the skeleton.

Change categories

  • CLI changes (src/Aspire.Cli/Agents/**, src/Aspire.Cli/Commands/AgentInitCommand.cs, src/Aspire.Cli/Commands/{InitCommand,NewCommand}.cs, src/Aspire.Cli/KnownFeatures.cs)
  • Resource/.xlf localization (12 languages)
  • Test-only changes (AgentInitCommandTests, AspireSkillsBundleTests, AspireSkillsInstallerTests, etc.)
  • Hosting / Dashboard / Template / Client-component / public API-file changes

Test Scenarios Executed

Scenario 1 — Help text reflects the new --skills semantics

Objective: Confirm aspire agent init --help no longer claims a stale hardcoded skill list and documents all/none.
Coverage Type: Happy path.
Status: ✅ Passed.

Verified:

  • --skills description: "Comma-separated list of skills to install. Bundle skills are loaded dynamically; CLI-provided skills include playwright-cli,dotnet-inspect. Use 'all' or 'none'"
  • No literal aspire,aspireify,aspire-deployment enumeration anywhere in help text.
  • Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\01-help-text.txt

Scenario 2 — --skills all installs the full bundle catalog

Objective: Run aspire agent init --skills all --skill-locations standard --non-interactive in an empty workspace and confirm every bundle skill is materialized.
Coverage Type: Happy path.
Status: ✅ Passed.

Steps:

  1. Created empty workspace scenario-02-skills-all.
  2. Ran the command above.

Observed installs (under .agents/skills): aspire, aspire-deployment, aspire-init, aspire-monitoring, aspire-orchestration, aspireify, playwright-cli.

Note on dotnet-inspect: Not installed. This is expected, not a regression — SkillDefinition.DotnetInspect in src/Aspire.Cli/Agents/SkillDefinition.cs is documented as "Only offered when the workspace contains a .NET AppHost," and the scenario runs against an empty workspace.

Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\02-skills-all.txt


Scenario 3 — The three previously-hidden bundle-only skills are selectable by name (regression guard)

Objective: Validate the original bug fix — aspire-init, aspire-monitoring, aspire-orchestration were silently invisible to --skills before this PR.
Coverage Type: Happy path (regression guard).
Status: ✅ Passed.

Command: aspire agent init --workspace-root <fresh> --skills aspire-init,aspire-monitoring,aspire-orchestration --skill-locations standard --non-interactive

Result: Exit 0, exactly the three requested skills installed under .agents/skills/, no others.

Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\03-bundle-only-skills.txt


Scenario 4 — Boundary: --skills none does nothing

Objective: Confirm the explicit none token short-circuits the install without errors.
Coverage Type: Boundary.
Status: ✅ Passed.

Result: Exit 0, workspace contains zero files after run (no .agents directory created).
Expected outcome: Command succeeds, nothing installed. ✅

Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\04-skills-none.txt


Scenario 5 — Unhappy path: unknown skill name is rejected

Objective: aspire agent init --skills not-a-real-skill ... should fail with a clear validation error and a non-zero exit code; nothing should be written to the workspace.
Coverage Type: Unhappy path / negative input.
Status: ✅ Passed (assertions), with ⚠️ two real findings in the rejection message itself.

Result (assertions):

  • Exit 21 ✅ (non-zero)
  • Error mentions the bad value not-a-real-skill
  • Nothing installed ✅
  • Expected unhappy-path outcome: Clear validation error + non-zero exit, no partial install. Met.

🔴 Finding 5.1 — Spectre.Console markup leaks as raw text in the validation error.
The error's "Available values" list ends with:
[bold]Install Aspire MCP server[/] [dim](configures detected agent environments)[/]
Those [bold]...[/] / [dim]...[/] tokens are Spectre.Console markup. In an interactive prompt path they would render as styled text, but the validation error formats labels as plain text and prints the markup verbatim. This is a localized-string-rendering bug visible to anyone who mistypes --skills.

🔴 Finding 5.2 — The Install Aspire MCP server MCP-applicator entry pollutes the --skills validation catalog.
In src/Aspire.Cli/Commands/AgentInitCommand.cs (around lines 226–274), the prompt builds a single skillChoices list by appending combinedMcpApplicator (an AgentEnvironmentApplicator, not a SkillDefinition) onto availableSkills and then binds that whole list to the --skills option via PromptForSelectionsAsync(..., binding: skillsBinding, ...). As a result, the MCP applicator is enumerated as a "valid value" for --skills even though it's a separate concern (and its label is the localized resource string InitCommand_ConfigureMcpServer wrapped in Spectre markup, which is what triggers Finding 5.1). The PR re-uses this existing prompt shape for the new dynamic catalog, so the bad surface area is now also more visible than before.

Suggested fix sketch (not implemented): keep the MCP applicator out of the --skills binding (e.g. give it a separate option or a separate prompt), or filter skillChoices to SkillDefinition instances before formatting the "Available values" message; either way, render labels with Markup.Escape (or supply a plain-text label callback) when they reach the non-interactive validator.

Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\05-unknown-skill.txt


Scenario 6 — aspire new with --suppress-agent-init is unaffected

Objective: Indirectly exercise the ExcludeAspireifyFromDefaults policy plumbing added to NewCommand and confirm the standard new-project flow still works end-to-end.
Coverage Type: Happy path (integration touchpoint).
Status: ✅ Passed.

Command:
aspire new aspire-empty --name PrSmoke17553 --output <fresh> --source <PR hive> --version 13.5.0-pr.17553.g6beecaf7 --language csharp --localhost-tld false --suppress-agent-init --non-interactive

Result: Project created (file-based apphost.cs + apphost.run.json + aspire.config.json), no .agents folder created.

Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\06-new-suppress-agent-init.txt


Scenario 7 — features:aspireSkillsRemoteFetchEnabled is registered and defaults to false

Objective: Verify the new feature flag is wired and 13.4/13.5 ships with it disabled, and that the bundle resolution still succeeds with the flag off (cache → embedded snapshot path).
Coverage Type: Happy path / configuration verification.
Status: ✅ Passed.

Verified:

  • aspire config list --all lists:

    aspireSkillsRemoteFetchEnabled (default: false)
    Allow the Aspire CLI to download the aspire-skills bundle from GitHub. When disabled (the 13.4 default), the CLI only uses the cached bundle and the embedded snapshot baked into the CLI; toggle on to opt in to the remote fetch path.

  • Scenarios 2 and 3 implicitly exercise the cache/embedded-snapshot path (flag is at its default false) and both succeeded, so the offline fallback works.
  • Minor: aspire config get features:aspireSkillsRemoteFetchEnabled returns not found (exit 10) when the user has not explicitly set the value. That's pre-existing behavior of config get (only user-overridden values), not a regression introduced by this PR.

Evidence: C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\07-feature-flag-list.txt, C:\Users\dapine\AppData\Local\Temp\aspire-pr-test-fc7303fd86604a3eb8869c982347866e\evidence\07-feature-flag-get.txt


Summary

Scenario Status Notes
1. Help text ✅ Passed Stale list gone; all/none documented
2. --skills all ✅ Passed 6 bundle + playwright-cli installed; dotnet-inspect correctly gated
3. Bundle-only skills regression ✅ Passed All 3 previously-hidden skills installable by name
4. --skills none ✅ Passed Clean no-op
5. Unknown skill ⚠️ Passes assertions, two new findings Spectre markup leak in error; MCP applicator pollutes --skills catalog
6. aspire new --suppress-agent-init ✅ Passed Project created, no .agents folder
7. Feature flag default off ✅ Passed Flag registered with default: false; offline path works

Overall Result

✅ PR FUNCTIONALLY VERIFIED — the primary fix (bundle-driven catalog so aspire-init, aspire-monitoring, aspire-orchestration are visible to --skills, the prompt, and aspire new) works as advertised, the new feature flag is in place and defaults to false, and the aspire new flow is unaffected.

Recommendations

  1. Address the --skills validation surface (Findings 5.1 + 5.2): exclude AgentEnvironmentApplicator items from the value set bound to --skills, and escape/strip Spectre markup before the validator prints labels. This regression is small but visible to any user who mistypes --skills, and it incidentally exposes a non-skill ("Install Aspire MCP server") as if it were a selectable skill name.
  2. Optional follow-up: consider a unit test under AgentInitCommandTests that drives aspire agent init --skills <bogus> --non-interactive and snapshots the rejection message — that would have caught both findings.

- Fix 1: SimplifyDescription only strips leading -/: when a **TYPE** prefix was actually trimmed; preserves descriptions like `-Quickly do X.` and `:memo notes`.
- Fix 2: ValidateSkillName adds explicit char.IsControl() check so U+0001..U+001F / U+0085 are rejected on Linux/macOS where Path.GetInvalidFileNameChars only returns { 0, / }.
- Fix 3: rename ExcludeAspireifyFromDefaults -> ExcludeOneTimeSetupSkillsFromDefaults backed by a single OneTimeSetupSkillNames set so future bundle bootstrap skills do not silently start auto-selecting.
- Fix 4: ResolveAvailableSkillsAsync now returns the bundle install failure message and AgentInitCommand surfaces it before MatchChoicesOrThrow when --skills names a non-CLI skill the bundle was expected to provide.
- Fix 5: ValidateSkillName also rejects empty strings, NFC-incorrect names, and Windows reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9 with or without extension) to match the PR description.
- Comment 5.1: ThrowNonInteractiveInvalidValue strips Spectre markup from each formatted choice so [[bold]]/[[dim]] tokens do not leak verbatim.
- Comment 5.2: PromptForSelectionsAsync gains an optional bindingChoices parameter; the MCP applicator (UX-only prompt item) is now excluded from --skills non-interactive validation.

Adds regression tests for the SimplifyDescription edge case and a parameterized rejection theory covering control chars, NFC, and Windows reserved names.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist IEvangelist enabled auto-merge (squash) May 28, 2026 21:07
@IEvangelist IEvangelist changed the title Load Aspire skills catalog from bundle manifest 13.4: Load Aspire skills catalog from bundle manifest May 28, 2026
@davidfowl davidfowl added this to the 13.4 milestone May 29, 2026
Adds two ConsoleInteractionService tests covering the rejection-message behaviors flagged by the PR testing report:

- OmitsItemsOutsideBindingChoices: items present in the visible multi-select prompt but excluded from bindingChoices (e.g. the MCP applicator entry) must not appear in the non-interactive Available values list.

- StripsSpectreMarkupFromChoiceLabels: [bold]/[dim] tokens from choice formatters used by the interactive prompt must be stripped before the plain-text rejection message is printed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist
Copy link
Copy Markdown
Member Author

Thanks for the thorough write-up! Good catches on findings 5.1 and 5.2, but worth flagging that both were actually addressed in commit 1d33bada9 ("Address self-review observations on bundle skill catalog"), which landed after the 6beecaf7 commit your testing run targeted. Specifically:

  • 5.1 (Spectre markup leak) — ConsoleInteractionService.ThrowNonInteractiveInvalidValue now applies .RemoveSpectreFormatting() to each formatted choice before emitting the Available values line, so [bold] / [dim] tokens no longer leak into the plain-text rejection message.
  • 5.2 (MCP applicator in --skills catalog) — PromptForSelectionsAsync gained an optional bindingChoices parameter, and AgentInitCommand now passes availableSkills.Cast<object>() for it. The MCP applicator still participates in the interactive multi-select prompt for UX but is no longer addressable from --skills and no longer appears in the non-interactive rejection list.

Took the optional follow-up too — da28e36c2 adds two ConsoleInteractionServiceTests regression tests at the layer where the bug actually lived (so any future caller of the API is protected, not just aspire agent init):

  1. PromptForSelectionsAsync_NonInteractive_CliProvidedInvalidValue_OmitsItemsOutsideBindingChoices — asserts that items present in the visible prompt but excluded from bindingChoices do not appear in the Available values output.
  2. PromptForSelectionsAsync_NonInteractive_CliProvidedInvalidValue_StripsSpectreMarkupFromChoiceLabels — asserts that [bold]Label[/] / [dim]...[/] tokens in the formatted labels are stripped before the rejection message is emitted (the underlying choice text and any plain-text suffix in parentheses survive).

If you'd like an additional aspire agent init --skills not-a-real-skill snapshot test at the command layer too, happy to add that — but the two unit tests above directly guard the contract that produced both findings.

Comment thread src/Aspire.Cli/Agents/AspireSkills/AspireSkillsBundle.cs Outdated
IEvangelist and others added 2 commits May 29, 2026 02:44
…romptAsync rename

Per davidfowl's review: we own the Aspire skills bundle and write its
contents, so the defense-in-depth ValidateSkillName check is modelling the
wrong threat. Drop the validator, its helpers, the reserved-device list,
the now-unused System.Text using, and the unit tests that exercised it.

Also rename the AgentCommandTests call site of WaitForSuccessPromptFailFastAsync
to WaitForSuccessPromptAsync to match the consolidated helper that landed
on main in #17588 (the FailFast variant was folded back into the canonical
WaitForSuccessPromptAsync).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@IEvangelist
Copy link
Copy Markdown
Member Author

/backport to release/13.4

@github-actions
Copy link
Copy Markdown
Contributor

Started backporting to release/13.4 (link to workflow run)

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

@IEvangelist backporting to release/13.4 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Load Aspire skills catalog from bundle manifest
Using index info to reconstruct a base tree...
M	src/Aspire.Cli/Commands/AgentInitCommand.cs
M	src/Aspire.Cli/Resources/AgentCommandStrings.Designer.cs
M	src/Aspire.Cli/Resources/AgentCommandStrings.resx
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.cs.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.de.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.es.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.fr.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.it.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ja.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ko.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.pl.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.pt-BR.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ru.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.tr.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.zh-Hans.xlf
M	src/Aspire.Cli/Resources/xlf/AgentCommandStrings.zh-Hant.xlf
M	tests/Aspire.Cli.Tests/Commands/AgentInitCommandTests.cs
M	tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs
Falling back to patching base and 3-way merge...
Auto-merging src/Aspire.Cli/Commands/AgentInitCommand.cs
CONFLICT (content): Merge conflict in src/Aspire.Cli/Commands/AgentInitCommand.cs
Auto-merging src/Aspire.Cli/Resources/AgentCommandStrings.Designer.cs
Auto-merging src/Aspire.Cli/Resources/AgentCommandStrings.resx
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.cs.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.de.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.es.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.fr.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.it.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ja.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ko.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.pl.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.pt-BR.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.ru.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.tr.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.zh-Hans.xlf
Auto-merging src/Aspire.Cli/Resources/xlf/AgentCommandStrings.zh-Hant.xlf
Auto-merging tests/Aspire.Cli.Tests/Commands/AgentInitCommandTests.cs
Auto-merging tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 Load Aspire skills catalog from bundle manifest
Error: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

Bundle-sourced skills (aspire, aspireify, aspire-deployment, aspire-init,
aspire-monitoring, aspire-orchestration) are now uniformly pre-selected in
the agent-init install prompt instead of respecting per-skill IsDefault
from the manifest. The CLI is the source of truth for the installable
catalog; bundle authors no longer opt in per skill via the manifest.
ExcludeOneTimeSetupSkillsFromDefaults continues to strip aspireify from
'aspire new' and standalone 'aspire agent init' flows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/Aspire.Cli/KnownFeatures.cs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/Aspire.Cli/Interaction/ConsoleInteractionService.cs
Copy link
Copy Markdown
Member

@joperezr joperezr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — really solid work. Code is well-structured, comments explain the why in all the right places, and test coverage is broad (loved the SimplifyDescription theory and the CliDefinedSkillsWinBundleNameCollisions regression). Left one tiny non-blocking nit about log level on the bad-asset path; take it or leave it.

@IEvangelist could you also port this to release/13.4? The feature flag default reads as "the 13.4 default" so it would be good to actually have it in that branch.

@IEvangelist IEvangelist merged commit 09240b5 into main May 29, 2026
920 of 927 checks passed
@IEvangelist IEvangelist deleted the ievangelist/dapine-skill-catalog-pr branch May 29, 2026 19:02
@microsoft-github-policy-service microsoft-github-policy-service Bot modified the milestones: 13.4, 13.5 May 29, 2026
@github-actions
Copy link
Copy Markdown
Contributor

CLI E2E Tests unknown — 109 passed, 0 failed, 2 unknown (commit c82e479)

View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #78566764122 Logs
AddPackageWhileAppHostRunningDetached Recording #78566764122 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #78566764979 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #78566764979 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #78566764979 Logs
AgentInitCommand_NonInteractive_BundleOnlySkillsBeyondCliCatalog_AreInstallable Recording #78566764979 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #78566765029 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #78566765029 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #78566765029 Logs
AllPublishMethodsBuildDockerImages Recording #78566764366 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #78566765412 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #78566764734 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #78566765243 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #78566765200 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #78566765200 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #78566764594 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #78566764734 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #78566764734 Logs
Banner_DisplayedOnFirstRun Recording #78566765294 Logs
Banner_DisplayedWithExplicitFlag Recording #78566765294 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #78566765294 Logs
CertificatesClean_RemovesCertificates Recording #78566764909 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #78566764909 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #78566764909 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #78566765363 Logs
CreateAndRunAspireStarterProject Recording #78566764304 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #78566764448 Logs
CreateAndRunEmptyAppHostProject Recording #78566764860 Logs
CreateAndRunJavaEmptyAppHostProject Recording #78566765151 Logs
CreateAndRunJsReactProject Recording #78566764636 Logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording #78566764304 Logs
CreateAndRunPythonReactProject Recording #78566765199 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #78566764528 Logs
CreateAndRunTypeScriptStarterProject Recording #78566764957 Logs
CreateJavaAppHostWithViteApp Recording #78566764867 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #78566764940 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #78566764940 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #78566764567 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #78566764567 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #78566764567 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #78566764567 Logs
DeployK8sBasicApiService Recording #78566765712 Logs
DeployK8sWithExternalHelmChart Recording #78566765045 Logs
DeployK8sWithGarnet Recording #78566764374 Logs
DeployK8sWithMongoDB Recording #78566764094 Logs
DeployK8sWithMySql Recording #78566766035 Logs
DeployK8sWithPostgres Recording #78566765502 Logs
DeployK8sWithRabbitMQ Recording #78566764224 Logs
DeployK8sWithRedis Recording #78566765723 Logs
DeployK8sWithSqlServer Recording #78566765351 Logs
DeployK8sWithValkey Recording #78566765421 Logs
DeployTypeScriptAppToKubernetes Recording #78566765238 Logs
DescribeCommandResolvesReplicaNames Recording #78566765425 Logs
DescribeCommandShowsRunningResources Recording #78566765425 Logs
DetachFormatJsonProducesValidJson Recording #78566764740 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #78566764740 Logs
DoPublishAndDeployListStepsWork Recording #78566765923 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #78566764338 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #78566764979 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #78566764449 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #78566764449 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #78566764449 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78566765568 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #78566764940 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #78566765363 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #78566765363 Logs
GlobalMigration_PreservesAllValueTypes Recording #78566765363 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #78566765363 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #78566765363 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #78566765568 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #78566764940 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #78566764849 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #78566765031 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #78566764366 Logs
LatestCliCanStartStableChannelAppHost Recording #78566764304 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #78566764304 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #78566764594 Logs
LogsCommandShowsResourceLogs Recording #78566764593 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #78566763891 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #78566763891 Logs
PsCommandListsRunningAppHost Recording #78566764189 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #78566764189 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #78566764617 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #78566764617 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #78566764617 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #78566764617 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #78566764752 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #78566764752 Logs
RestoreGeneratesSdkFiles Recording #78566765051 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #78566764360 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #78566764360 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #78566765176 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #78566766145 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #78566764538 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #78566764538 Logs
SecretCrudOnDotNetAppHost Recording #78566765024 Logs
SecretCrudOnTypeScriptAppHost Recording #78566765480 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #78566765338 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #78566764396 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #78566764538 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #78566764538 Logs
StopAllAppHostsFromAppHostDirectory Recording #78566765429 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #78566765347 Logs
StopNonInteractiveSingleAppHost Recording #78566765429 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #78566764220 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #78566764122 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #78566764360 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #78566764866 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #78566764866 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #78566764866 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #78566764866 Logs

📹 Recordings uploaded automatically from CI run #26651247059

aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request May 29, 2026
…ls catalog

Documents the changes from microsoft/aspire#17553:
- Skills catalog is now loaded from the bundle manifest (skill-manifest.json)
  instead of a hardcoded list, exposing previously invisible bundle-only skills
  (aspire-init, aspire-monitoring, aspire-orchestration).
- Clarifies which skills come from the bundle vs. from the CLI directly.
- Documents the aspireify pre-selection difference between aspire init and aspire new.
- Documents the aspireSkillsRemoteFetchEnabled feature flag (default off) and
  the bundle resolution order (cache → GitHub release → embedded snapshot).
- Updates --skills option description to list valid bundle and CLI skill names.
- Adds examples for installing bundle-only skills and enabling remote fetch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot
Copy link
Copy Markdown
Contributor

Pull request created: #1125

Generated by PR Documentation Check

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1125 targeting release/13.4.

Updated src/frontend/src/content/docs/reference/cli/commands/aspire-agent-init.mdx to document the bundle-manifest-driven skills catalog introduced in this PR. Changes include: new Skills catalog subsection listing the full set of bundle-provided skills (aspire, aspireify, aspire-init, aspire-monitoring, aspire-orchestration) and CLI-defined skills; new Bundle resolution and remote fetch subsection documenting the features:aspireSkillsRemoteFetchEnabled feature flag (default off) and resolution order; updated --skills option description; and two new examples for installing specific bundle skills and enabling remote fetch.

Note

This draft PR needs human review before merging.

joperezr pushed a commit that referenced this pull request May 29, 2026
Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

aspire agent init does not surface all bundled Aspire skills

4 participants