JasperFx.Aspire — JasperFx CLI verbs as Aspire dashboard commands (A1)#402
Merged
Conversation
…ands (A1)
New JasperFx.Aspire hosting package. One line of AppHost code adds clickable
custom commands to a resource tile in the .NET Aspire dashboard for a JasperFx
app's CLI verbs (check-env, describe, codegen, resources, projections):
builder.AddProject<Projects.Api>("api").WithJasperFxCommands();
Because Marten, Wolverine, and Polecat all build on the same JasperFx command
infrastructure, this lights up for the whole Critter Stack with no per-product code.
Implementation (Phase 1 — curated catalog, zero runtime coupling to the target):
- WithJasperFxCommands / WithJasperFxCommand extensions + JasperFxCommandOptions /
JasperFxCommandRegistration. Read-only verbs (check-env, describe, codegen preview)
are added by default; mutating verbs (codegen write, resources, projections) require
IncludeMutatingCommands and each get a confirmation prompt.
- JasperFxVerbCatalog: static metadata (verb, mutating?, icon, display text, default
confirmation) for the standard verbs; unknown verbs are treated as mutating.
- JasperFxCommandExecutor: the dashboard callback runs in the AppHost, so it spawns a
short-lived child of the same app — `dotnet run --project <csproj> --no-build -- <verb>` —
with the resource's *resolved* environment evaluated from its EnvironmentCallbackAnnotations
(connection strings, etc.) layered on the inherited AppHost env. Child stdout/stderr stream
into the resource's dashboard logs via ResourceLoggerService; exit code maps to the toast.
Targets net10.0 against Aspire.Hosting 13.3.1 (Aspire 13 is net10-first; uses the 9.2+
CommandOptions WithCommand overload). 16 unit tests cover the catalog selection/templating
and the executor's ProcessStartInfo construction + exit-code mapping. A standalone sample
under src/AspireSample (Postgres + a check-env that needs the injected connection string) is
kept out of jasperfx.sln for manual dashboard click-through. Wired into the NugetPack target.
Deferred (Phase 2, follow-up): a machine-readable `describe --json` so the catalog can be
discovered dynamically from the target instead of curated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced May 31, 2026
Closed
Closed
New /cli/aspire page documenting WithJasperFxCommands — the curated read-only verbs, mutating opt-in + confirmation, single-command registration, the spawn-child-with-resolved-environment mechanic (with a mermaid sequence diagram), safety, and requirements. Added under the Command Line sidebar section. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced May 31, 2026
jeremydmiller
added a commit
to JasperFx/marten
that referenced
this pull request
Jun 1, 2026
…mp JasperFx.* 2.2.1 → 2.4.0 (#4593) The new JasperFx.Aspire package (JasperFx/jasperfx#402) surfaces a JasperFx app's CLI verbs as clickable custom commands on each resource tile in the .NET Aspire dashboard. Marten apps inherit this for free because they build on the JasperFx command layer. New page: docs/configuration/aspire-commands.md - Quick-start: WithJasperFxCommands() one-liner on the Marten service resource in the Aspire AppHost project. - Highlights the four verbs that matter most for Marten: check-env, describe, resources, projections. - Confirmation behavior for mutating verbs + per-verb customization (DisplayName, ConfirmationMessage, IconName, IsHighlighted, IsEnabled). - WithJasperFxCommand single-verb registration with fixed-args (the "rebuild MyProjection only" recipe). - Constraint notes: AppHost-layer only, child-process verb spawn picks up Aspire-injected env, requires ApplyJasperFxExtensions + RunJasperFxCommandsAsync wiring in the service's Program.cs. Wired into the sidebar under "Command Line Tooling" in docs/.vitepress/config.mts; reciprocal cross-link added at the top of docs/configuration/cli.md so anyone landing on the CLI page sees the Aspire entry-point too. Dependency bump: JasperFx, JasperFx.Events, JasperFx.SourceGenerator, JasperFx.Events.SourceGenerator 2.2.1 → 2.4.0 in Directory.Packages.props to pull in the package referenced by the new docs. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Implements A1 from the design doc (
.claude/docs/jasperfx-aspire-command-integration-design.md): a newJasperFx.Aspirehosting package that surfaces a JasperFx app's command-line verbs as clickable custom commands on the resource tile in the .NET Aspire dashboard.Because Marten, Wolverine, and Polecat all build on the same JasperFx command infrastructure, this lights up for the entire Critter Stack with no per-product code.
What's here (Phase 1)
WithJasperFxCommands/WithJasperFxCommandextensions +JasperFxCommandOptions/JasperFxCommandRegistration. Read-only verbs (check-env,describe,codegenpreview) are added by default; mutating verbs (codegen write,resources,projections) requireIncludeMutatingCommandsand each get a confirmation prompt.JasperFxVerbCatalog— curated static metadata for the standard verbs (zero runtime coupling to the target). Unknown/product-specific verbs are accepted and treated as mutating (safe-by-default).JasperFxCommandExecutor— the dashboard callback runs in the AppHost, so it spawns a short-lived child of the same app (dotnet run --project <csproj> --no-build -- <verb>) with the resource's resolved environment (evaluated from itsEnvironmentCallbackAnnotations — connection strings etc.) layered on the inherited AppHost env. Child stdout/stderr stream into the resource's dashboard logs viaResourceLoggerService; the exit code maps to the success/failure toast.Aspire version
Targets net10.0 against Aspire.Hosting 13.3.1 (Aspire 13 is net10-first), using the 9.2+
CommandOptionsWithCommandoverload. The design doc said "pin to 9.x" — that predates Aspire's move to 13.x calendar versioning; 13.x is the current stable and the API is the sameCommandOptionsshape.De-risking spike (design step 0)
The riskiest mechanic — resolving a resource's Aspire-managed environment inside the command callback — is validated at the API level: the whole surface (
WithCommand/CommandOptions,EnvironmentCallbackContextevaluation,IValueProvider.GetValueAsync,ResourceLoggerService,KnownResourceStates) compiles against real Aspire 13.3.1, and the standalone sample (src/AspireSample) integrates it into a real AppHost.Verification
dotnet build jasperfx.sln -c Releaseclean.ProcessStartInfoconstruction + exit-code mapping).dotnet run --project src/AspireSample/AspireSample.AppHost, click Check environment on theapitile) — the end-to-end env-resolution proof can't be automated headlessly. Steps insrc/AspireSample/README.md.The sample is intentionally out of
jasperfx.slnso core CI isn't burdened with the Aspire AppHost SDK + Postgres hosting restore.Deferred to follow-ups
describe --jsonin JasperFx core so the catalog is discovered dynamically from the target (incl. product-specific/custom verbs) instead of curated.🤖 Generated with Claude Code