Skip to content

TypeScript AppHost: expose ResourceCommandService.ExecuteCommandAsync for programmatic command execution #16770

@davidfowl

Description

@davidfowl

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

C# AppHosts can compose commands by resolving ResourceCommandService from DI inside an executeCommand callback and invoking another resource's command:

var commandService = context.ServiceProvider.GetRequiredService<ResourceCommandService>();
var result = await commandService.ExecuteCommandAsync("cache", "clear-cache", context.CancellationToken);

The TypeScript AppHost SDK has no supported equivalent — the polyglot generator does not expose ResourceCommandService, so a TypeScript withCommand callback has no AppHost-side API for invoking another Aspire command.

Verified against microsoft/aspire@main (commit 7ff7e2e2d):

  • src/Aspire.Hosting/ApplicationModel/ResourceCommandService.cs — C# implementation exists, registered as a singleton on DistributedApplication.
  • git grep "ResourceCommandService" against *.ts files in the repo: zero hits anywhere (snapshots, src, samples).
  • The TypeScript codegen snapshot does not declare the type.

Describe the solution you'd like

Expose ResourceCommandService.ExecuteCommandAsync(resourceName, commandName, cancellationToken) to TypeScript AppHosts, returning Promise<ExecuteCommandResult>. The resolution path can match whatever convention is already used for other Aspire services (e.g., resolved via serviceProvider, or surfaced as a top-level helper).

const result = await getResourceCommandService(context.serviceProvider)
    .executeCommandAsync("cache", "clear-cache", context.cancellationToken);

Secondary asks (nice-to-have, not part of the headline):

  • Parity for the resourceId-based overload that accepts a specific replica's resource ID.
  • Consistent serialization of ExecuteCommandResult.data across the polyglot boundary so a downstream command can be consumed by a composing command (this may already be the case; flagging because it's the next thing a real caller will need).

Additional context

Use cases this unblocks for TypeScript AppHosts (mirrors the Programmatically execute commands docs section):

  1. A "reset-all" command that fans out and clears a cache, restarts a backend, and re-seeds a database.
  2. A composite "issue-token" + "deploy" sequence where one command consumes the structured output of another.
  3. A startup orchestration script driven from the AppHost itself.

Came up while documenting custom commands (microsoft/aspire.dev#822). The "Programmatically execute commands" section now carries a top-level note flagging the entire feature as a C#-only AppHost capability.

Metadata

Metadata

Assignees

Labels

area-polyglotIssues related to polyglot apphosts

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions