diff --git a/src/frontend/src/content/docs/app-host/executable-resources.mdx b/src/frontend/src/content/docs/app-host/executable-resources.mdx
index 596d6163d..d02b1ead8 100644
--- a/src/frontend/src/content/docs/app-host/executable-resources.mdx
+++ b/src/frontend/src/content/docs/app-host/executable-resources.mdx
@@ -276,7 +276,7 @@ const app = await builder.addExecutable("api", "uvicorn", ".", ["main:app", "--r
### `withEnvironment` API unification in Aspire 13.3
-Aspire 13.3 unified polyglot AppHost environment assignment behind a single `withEnvironment(name, value)` pattern. The public TypeScript API accepts plain strings, reference expressions, endpoint references, parameter resources, supported resources that expose connection strings, expression values, and awaitable forms of supported values.
+Aspire 13.3 unified non-C# AppHost environment assignment behind a single `withEnvironment(name, value)` pattern. The public TypeScript API accepts plain strings, reference expressions, endpoint references, parameter resources, supported resources that expose connection strings, expression values, and awaitable forms of supported values.
When upgrading to Aspire 13.3, replace every earlier per-kind environment helper call with `withEnvironment(name, value)`. The 13.3 TypeScript SDK doesn't generate compatibility aliases for those helpers.
diff --git a/src/frontend/src/content/docs/app-host/with-terminal.mdx b/src/frontend/src/content/docs/app-host/with-terminal.mdx
index 42b2860b7..205a88e9d 100644
--- a/src/frontend/src/content/docs/app-host/with-terminal.mdx
+++ b/src/frontend/src/content/docs/app-host/with-terminal.mdx
@@ -74,16 +74,9 @@ The terminal session is described by a set of options with sensible defaults:
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Columns` | `120` | The initial number of columns for the terminal grid. |
| `Rows` | `30` | The initial number of rows for the terminal grid. |
+| `Shell` | `null` | The shell to launch for the session. When `null`, the default is used: for containers this is typically `/bin/sh`; for executables the process itself is the terminal program. |
| `ShowTerminalHost` | `false` | Whether the hidden per-replica terminal host resources appear in the dashboard and CLI resource lists. Set to `true` to diagnose terminal-host startup or connectivity issues. |
-
-
-
-
@@ -118,7 +111,7 @@ await builder.build().run();
```
diff --git a/src/frontend/src/content/docs/extensibility/multi-language-integration-authoring.mdx b/src/frontend/src/content/docs/extensibility/multi-language-integration-authoring.mdx
index 8d5b8cdda..d31d56ab8 100644
--- a/src/frontend/src/content/docs/extensibility/multi-language-integration-authoring.mdx
+++ b/src/frontend/src/content/docs/extensibility/multi-language-integration-authoring.mdx
@@ -119,7 +119,7 @@ XML doc comments are the primary source for generated SDK API documentation. The
Use `ats-*` override tags when the standard C# XML documentation doesn't translate well to generated SDK docs — for example, when a `` references C#-specific types or language constructs that have no direct equivalent in TypeScript. The supported overrides are:
-- `` — overrides `` in polyglot docs
+- `` — overrides `` in [polyglot](/get-started/glossary/#polyglot) docs
- `` — overrides `` for a specific parameter
- `` — overrides ``
- `` — overrides ``
diff --git a/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx b/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx
index 8886bbfc8..b19173d68 100644
--- a/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx
+++ b/src/frontend/src/content/docs/get-started/add-aspire-existing-app.mdx
@@ -96,7 +96,7 @@ The AppHost is the orchestration layer. Your choice here changes how you express
Aspire offers two C# AppHost styles:
-**File-based AppHost** — a single `apphost.cs` file that uses `#:sdk` and `#:package` directives. No `.csproj`, no solution integration required. Best for polyglot repos or quick setups.
+**File-based AppHost** — a single `apphost.cs` file that uses `#:sdk` and `#:package` directives. No `.csproj`, no solution integration required. Best for repos with [polyglot](/get-started/glossary/#polyglot) code or quick setups.
**Project-based AppHost** — a traditional `AppHost.csproj` that lives inside a `.sln` alongside your other C# projects. Uses `ProjectReference` items and the generated `Projects` namespace for strongly-typed `AddProject()` calls. Best when your repo is already a .NET solution and you want IDE-integrated orchestration.
diff --git a/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx b/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx
index 4c2fd2d72..22dfe92c4 100644
--- a/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx
+++ b/src/frontend/src/content/docs/get-started/aspire-vscode-extension.mdx
@@ -14,7 +14,7 @@ import debugSessions from '@assets/get-started/code-extension-debug.png';
import debugSessionsLight from '@assets/get-started/code-extension-debug-light.png';
import { Kbd } from 'starlight-kbd/components';
-The official Aspire extension for [Visual Studio Code](https://code.visualstudio.com/) turns VS Code into a first-class environment for building, debugging, and shipping polyglot Aspire apps.
+The official Aspire extension for [Visual Studio Code](https://code.visualstudio.com/) turns VS Code into a first-class environment for building, debugging, and shipping [polyglot](/get-started/glossary/#polyglot) Aspire apps.
Press to build your AppHost, start your resources, and debug supported resource types — C#, TypeScript, Python, browser apps, and Azure Functions — alongside the Aspire dashboard.
:::note[Prerequisites]
diff --git a/src/frontend/src/content/docs/get-started/faq.mdx b/src/frontend/src/content/docs/get-started/faq.mdx
index ecb50e2fa..7b72b775c 100644
--- a/src/frontend/src/content/docs/get-started/faq.mdx
+++ b/src/frontend/src/content/docs/get-started/faq.mdx
@@ -10,7 +10,7 @@ This page answers common questions about what Aspire is, how it fits into your w
Aspire is an agent-ready, code-first tool to compose, debug, and deploy any distributed app. It makes it easier to build, run, debug, and deploy services across any language, stack, or cloud. It's free and open source at [github.com/microsoft/aspire](https://github.com/microsoft/aspire).
-Its central idea is the **AppHost**: the place where you declare your services, resources, dependencies, endpoints, parameters, and relationships in code instead of scattering that information across many config files. AppHosts can be written in **C# or TypeScript**, which makes Aspire a strong fit for polyglot teams.
+Its central idea is the **AppHost**: the place where you declare your services, resources, dependencies, endpoints, parameters, and relationships in code instead of scattering that information across many config files. AppHosts can be written in **C# or TypeScript**, which makes Aspire a strong fit for teams that use [polyglot](/get-started/glossary/#polyglot) code.
Learn more: [Build your first Aspire app](/get-started/first-app/)
diff --git a/src/frontend/src/content/docs/get-started/glossary.mdx b/src/frontend/src/content/docs/get-started/glossary.mdx
index 332b575ec..d649a9d8b 100644
--- a/src/frontend/src/content/docs/get-started/glossary.mdx
+++ b/src/frontend/src/content/docs/get-started/glossary.mdx
@@ -4,6 +4,8 @@ description: Key terms and concepts used throughout Aspire documentation — App
---
import { Aside } from '@astrojs/starlight/components';
+import PivotSelector from '@components/PivotSelector.astro';
+import Pivot from '@components/Pivot.astro';
This glossary defines the key terms and concepts you'll encounter when working with Aspire. Bookmark this page as a quick reference.
@@ -13,16 +15,27 @@ These are the foundational concepts you need to understand when working with Asp
### AppHost
-The **AppHost** is the orchestration project where you define your entire application's architecture in C# code. It's a special Aspire project that:
+The **AppHost** is the orchestration project where you define your entire application's architecture. It's a special Aspire project that:
-- Declares what services, databases, and containers make up your application
-- Defines how resources depend on each other
-- Configures how resources communicate
-- Orchestrates startup order during local development
-- Generates deployment artifacts for production
+- Declares what services, databases, and containers make up your application.
+- Defines how resources depend on each other.
+- Configures how resources communicate.
+- Orchestrates startup order during local development.
+- Generates deployment artifacts for production.
Think of it as the "control tower" for your distributed application.
+
+
+
```csharp title="AppHost.cs"
// This IS the AppHost - Program.cs in your AppHost project
var builder = DistributedApplication.CreateBuilder(args);
@@ -33,6 +46,21 @@ var api = builder.AddProject("api")
builder.Build().Run();
```
+
+
+```typescript title="apphost.mts"
+import { createBuilder } from './.aspire/modules/aspire.mjs';
+
+// This IS the AppHost in a TypeScript project
+const builder = await createBuilder();
+
+const db = await builder.addPostgres("db");
+await builder.addProject("api", "../Api/Api.csproj")
+ .withReference(db);
+
+await builder.build().run();
+```
+
### Resource
@@ -72,6 +100,10 @@ Aspire helps you orchestrate all these pieces together.
When you add `builder.AddServiceDefaults()` to a project, you get production-ready observability and resilience out of the box.
+### Polyglot
+
+In this repository, **polyglot** means relating to code and applications written in multiple languages, including TypeScript, C#, Python, Go, Java, and Rust. Aspire supports polyglot code in AppHosts, generated SDKs, others projects, and related tooling.
+
---
## APIs and patterns
@@ -86,11 +118,20 @@ These are the key APIs and patterns you'll use when building Aspire applications
2. Sets up service discovery so your code can find the other resource
3. Creates a dependency relationship for startup ordering
+
```csharp title="AppHost.cs"
var db = builder.AddPostgres("db");
var api = builder.AddProject("api")
.WithReference(db); // API now has DATABASE connection info injected
```
+
+
+```typescript title="apphost.mts"
+const db = await builder.addPostgres("db");
+await builder.addProject("api", "../Api/Api.csproj")
+ .withReference(db); // API now has DATABASE connection info injected
+```
+
The API project will receive environment variables like:
- `ConnectionStrings__db` - The database connection string
@@ -98,38 +139,66 @@ The API project will receive environment variables like:
### WaitFor
-`WaitFor()` tells Aspire to delay starting a resource until its dependency is ready:
+`WaitFor()`/`waitFor()` tells Aspire to delay starting a resource until its dependency is ready:
+
```csharp title="AppHost.cs"
var db = builder.AddPostgres("db");
var api = builder.AddProject("api")
.WithReference(db)
.WaitFor(db); // Don't start API until database is healthy
```
+
+
+```typescript title="apphost.mts"
+const db = await builder.addPostgres("db");
+await builder.addProject("api", "../Api/Api.csproj")
+ .withReference(db)
+ .waitFor(db); // Don't start API until database is healthy
+```
+
### WaitForCompletion
`WaitForCompletion()` waits for a resource to finish and exit (not just start). Useful for setup scripts:
+
```csharp title="AppHost.cs"
var migrate = builder.AddProject("migrate");
var api = builder.AddProject("api")
.WaitForCompletion(migrate); // Wait for migrations to complete
```
+
+
+```typescript title="apphost.mts"
+const migrate = await builder.addProject("migrate", "../DbMigration/DbMigration.csproj");
+await builder.addProject("api", "../Api/Api.csproj")
+ .waitForCompletion(migrate); // Wait for migrations to complete
+```
+
### WaitForStart
`WaitForStart()` waits only for a resource to reach the running state, without waiting for health checks to pass:
+
```csharp title="AppHost.cs"
var db = builder.AddPostgres("db");
var api = builder.AddProject("api")
.WaitForStart(db); // Start as soon as db is running, don't wait for healthy
```
+
+
+```typescript title="apphost.mts"
+const db = await builder.addPostgres("db");
+await builder.addProject("api", "../Api/Api.csproj")
+ .waitForStart(db); // Start as soon as db is running, don't wait for healthy
+```
+
The preceding code:
diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-log-analytics.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-log-analytics.mdx
index 40d437b04..95da2c645 100644
--- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-log-analytics.mdx
+++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-log-analytics.mdx
@@ -232,7 +232,7 @@ var appInsights = builder.AddAzureApplicationInsights("app-insights", logAnalyti
TypeScript AppHosts can use curated provisioning helper APIs when an
integration exposes them. This example directly customizes Azure.Provisioning
objects through `ConfigureInfrastructure`, which is currently C#-only unless
- the integration wraps the scenario in a polyglot-friendly helper.
+ the integration wraps the scenario in a [polyglot](/get-started/glossary/#polyglot)-friendly helper.
The preceding code:
diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-postgresql/azure-postgresql-host.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-postgresql/azure-postgresql-host.mdx
index b17ad7c81..e891bea61 100644
--- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-postgresql/azure-postgresql-host.mdx
+++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-postgresql/azure-postgresql-host.mdx
@@ -483,7 +483,7 @@ builder.Build().Run();
TypeScript AppHosts can use curated provisioning helper APIs when an
integration exposes them. This example directly customizes Azure.Provisioning
objects through `ConfigureInfrastructure`, which is currently C#-only unless
- the integration wraps the scenario in a polyglot-friendly helper.
+ the integration wraps the scenario in a [polyglot](/get-started/glossary/#polyglot)-friendly helper.
The preceding code:
diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-sql-database/azure-sql-database-host.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-sql-database/azure-sql-database-host.mdx
index e36f2d7f0..c6ee296cd 100644
--- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-sql-database/azure-sql-database-host.mdx
+++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-sql-database/azure-sql-database-host.mdx
@@ -340,7 +340,7 @@ builder.Build().Run();
TypeScript AppHosts can use curated provisioning helper APIs when an
integration exposes them. This example directly customizes Azure.Provisioning
objects through `ConfigureInfrastructure`, which is currently C#-only unless
- the integration wraps the scenario in a polyglot-friendly helper.
+ the integration wraps the scenario in a [polyglot](/get-started/glossary/#polyglot)-friendly helper.
The preceding code:
diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-virtual-network.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-virtual-network.mdx
index cdc14d34d..b9379cde4 100644
--- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-virtual-network.mdx
+++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-virtual-network.mdx
@@ -446,7 +446,7 @@ storage.ConfigureInfrastructure(infra =>
TypeScript AppHosts can use curated provisioning helper APIs when an
integration exposes them. This example directly customizes Azure.Provisioning
objects through `ConfigureInfrastructure`, which is currently C#-only unless
- the integration wraps the scenario in a polyglot-friendly helper.
+ the integration wraps the scenario in a [polyglot](/get-started/glossary/#polyglot)-friendly helper.
#### Service-specific requirements
diff --git a/src/frontend/src/content/docs/integrations/databases/ravendb/ravendb-host.mdx b/src/frontend/src/content/docs/integrations/databases/ravendb/ravendb-host.mdx
index ce246363d..3fffd12de 100644
--- a/src/frontend/src/content/docs/integrations/databases/ravendb/ravendb-host.mdx
+++ b/src/frontend/src/content/docs/integrations/databases/ravendb/ravendb-host.mdx
@@ -353,7 +353,7 @@ builder.Build().Run();
## Connection properties
diff --git a/src/frontend/src/content/docs/integrations/databases/surrealdb/surrealdb-host.mdx b/src/frontend/src/content/docs/integrations/databases/surrealdb/surrealdb-host.mdx
index 83c43a98b..5811d0e58 100644
--- a/src/frontend/src/content/docs/integrations/databases/surrealdb/surrealdb-host.mdx
+++ b/src/frontend/src/content/docs/integrations/databases/surrealdb/surrealdb-host.mdx
@@ -323,7 +323,7 @@ await builder.build().run();
-The `WithLogLevel` method enables verbose logging in the SurrealDB container, which is useful during development and debugging. The polyglot TypeScript AppHost accepts the log level as a string (for example, `"Trace"`, `"Debug"`, `"Information"`, `"Warning"`, `"Error"`, `"Critical"`, or `"None"`).
+The `WithLogLevel` method enables verbose logging in the SurrealDB container, which is useful during development and debugging. The non-C# TypeScript AppHost accepts the log level as a string (for example, `"Trace"`, `"Debug"`, `"Information"`, `"Warning"`, `"Error"`, `"Critical"`, or `"None"`).
## Health checks
diff --git a/src/frontend/src/content/docs/integrations/devtools/dev-tunnels.mdx b/src/frontend/src/content/docs/integrations/devtools/dev-tunnels.mdx
index 28ab0d978..64e2804f5 100644
--- a/src/frontend/src/content/docs/integrations/devtools/dev-tunnels.mdx
+++ b/src/frontend/src/content/docs/integrations/devtools/dev-tunnels.mdx
@@ -244,7 +244,7 @@ The `DevTunnelOptions` class provides several configuration options:
| `Region` | The `DevTunnelRegion` to create the tunnel in; automatic when unset |
diff --git a/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-connect.mdx b/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-connect.mdx
index bbb448aef..05529a58f 100644
--- a/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-connect.mdx
+++ b/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-connect.mdx
@@ -239,7 +239,7 @@ For more information, see the [OpenFeature JavaScript SDK](https://openfeature.d
## Use OFREP provider
-As an alternative to the native provider, you can connect to flagd using the [OFREP (OpenFeature Remote Evaluation Protocol)](https://openfeature.dev/specification/appendix-c/). OFREP is a standardized HTTP/REST-based protocol for remote feature flag evaluation, making it language-agnostic and well-suited for polyglot environments.
+As an alternative to the native provider, you can connect to flagd using the [OFREP (OpenFeature Remote Evaluation Protocol)](https://openfeature.dev/specification/appendix-c/). OFREP is a standardized HTTP/REST-based protocol for remote feature flag evaluation, making it language-agnostic and well-suited for [polyglot](/get-started/glossary/#polyglot) environments.
### Install the OFREP provider
diff --git a/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-get-started.mdx b/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-get-started.mdx
index 12ffe55c0..d609c70a7 100644
--- a/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-get-started.mdx
+++ b/src/frontend/src/content/docs/integrations/devtools/flagd/flagd-get-started.mdx
@@ -89,7 +89,7 @@ Getting there is a two-step process: model the flagd resource in your AppHost, t
diff --git a/src/frontend/src/content/docs/integrations/frameworks/go/go-host.mdx b/src/frontend/src/content/docs/integrations/frameworks/go/go-host.mdx
index 2c5ffc326..fc548c912 100644
--- a/src/frontend/src/content/docs/integrations/frameworks/go/go-host.mdx
+++ b/src/frontend/src/content/docs/integrations/frameworks/go/go-host.mdx
@@ -511,7 +511,7 @@ await builder.build().run();
## Experimental Go AppHost templates
-The `Aspire.Hosting.Go` integration can be used from C# and TypeScript AppHosts. Aspire also includes experimental Go AppHost and Go starter template support in the Aspire CLI. The Go AppHost templates use experimental Go AppHost APIs instead of the `Aspire.Hosting.Go` package. To enable Go AppHost language support for CLI templates, enable the Go polyglot feature flag:
+The `Aspire.Hosting.Go` integration can be used from C# and TypeScript AppHosts. Aspire also includes experimental Go AppHost and Go starter template support in the Aspire CLI. The Go AppHost templates use experimental Go AppHost APIs instead of the `Aspire.Hosting.Go` package. To enable Go AppHost language support for CLI templates, enable the Go [polyglot](/get-started/glossary/#polyglot) feature flag:
```bash title="Aspire CLI"
aspire config set features:experimentalPolyglot:go true --global
diff --git a/src/frontend/src/content/docs/ja/extensibility/multi-language-integration-authoring.mdx b/src/frontend/src/content/docs/ja/extensibility/multi-language-integration-authoring.mdx
index ad493fe90..8f18f1780 100644
--- a/src/frontend/src/content/docs/ja/extensibility/multi-language-integration-authoring.mdx
+++ b/src/frontend/src/content/docs/ja/extensibility/multi-language-integration-authoring.mdx
@@ -223,6 +223,8 @@ TypeScript 側で値を一度読み取る async 操作として扱いたい場
2. TypeScript 呼び出し元に必要なプロパティだけを個別の `[AspireExport]` 属性で注釈します。
3. 可変状態(環境変数、コマンド ライン引数、URL リスト)には、生のコレクションではなく小さな *editor* クラスを公開します。
+このドキュメントで使う [polyglot](/get-started/glossary/#polyglot) は、TypeScript、C#、Python、Go、Java、Rust など、複数の言語で書かれたコードやアプリケーションを指します。
+
### editor クラスを定義する
editor は可変コレクションをラップし、生のコレクションを TypeScript に渡す代わりに、通常は `add`、`set`、`remove` などの特定操作を公開します:
diff --git a/src/frontend/src/content/docs/reference/cli/commands/aspire-start.mdx b/src/frontend/src/content/docs/reference/cli/commands/aspire-start.mdx
index 1693f1127..c61625f03 100644
--- a/src/frontend/src/content/docs/reference/cli/commands/aspire-start.mdx
+++ b/src/frontend/src/content/docs/reference/cli/commands/aspire-start.mdx
@@ -27,7 +27,7 @@ You can output detached startup details as a table or JSON, and you can pass add
### Startup readiness and failure diagnostics
-`aspire start` waits for the AppHost to report that it has reached a stable running state before detaching. This means that early startup failures — such as TypeScript syntax errors in a polyglot AppHost or C# compile errors in a .NET AppHost — are surfaced in the parent terminal instead of being silently lost in the background.
+`aspire start` waits for the AppHost to report that it has reached a stable running state before detaching. This means that early startup failures — such as TypeScript syntax errors in a non-C# AppHost or C# compile errors in a .NET AppHost — are surfaced in the parent terminal instead of being silently lost in the background.
When the AppHost fails to start, `aspire start` displays a curated excerpt of the startup output that filters out noise such as package install logs and highlights the relevant error messages:
diff --git a/src/frontend/src/content/docs/reference/cli/configuration.mdx b/src/frontend/src/content/docs/reference/cli/configuration.mdx
index 9dbc489cc..b6f9e6856 100644
--- a/src/frontend/src/content/docs/reference/cli/configuration.mdx
+++ b/src/frontend/src/content/docs/reference/cli/configuration.mdx
@@ -163,9 +163,9 @@ CLI supports.
aspire config set features. true --global
```
- For example, consider the following that enables global support for Go:
+ For example, consider the following that enables global support for Go:
- ```bash title="Enable global polyglot Go support"
+ ```bash title="Enable global Go support"
aspire config set features:experimentalPolyglot:go true
```
diff --git a/src/frontend/src/content/docs/reference/cli/includes/config-settings-table.md b/src/frontend/src/content/docs/reference/cli/includes/config-settings-table.md
index 4b34b069a..a194839c6 100644
--- a/src/frontend/src/content/docs/reference/cli/includes/config-settings-table.md
+++ b/src/frontend/src/content/docs/reference/cli/includes/config-settings-table.md
@@ -6,12 +6,13 @@ title: Config Settings Table
| ----------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `appHost.path` | `appHost.path` | Project-scoped path to the default AppHost entry point. This setting must be configured in the local `aspire.config.json` file. |
| `channel` | `channel` | Default Aspire channel used by channel-aware commands such as `aspire new`, `aspire init`, and `aspire update`. |
+| `features.aspireSkillsRemoteFetchEnabled` | `features.aspireSkillsRemoteFetchEnabled` | Enable or disable preview remote fetching of Aspire skills bundles from GitHub. |
| `features.defaultWatchEnabled` | `features.defaultWatchEnabled` | Enable or disable watch mode by default when running Aspire applications for automatic restarts on file changes. |
-| `features.experimentalPolyglot:go` | `features.experimentalPolyglot:go` | Enable or disable experimental Go language support for polyglot Aspire applications. |
-| `features.experimentalPolyglot:java` | `features.experimentalPolyglot:java` | Enable or disable experimental Java language support for polyglot Aspire applications. |
-| `features.experimentalPolyglot:python` | `features.experimentalPolyglot:python` | Enable or disable experimental Python language support for polyglot Aspire applications. |
-| `features.experimentalPolyglot:rust` | `features.experimentalPolyglot:rust` | Enable or disable experimental Rust language support for polyglot Aspire applications. |
-| `features.polyglotIntegrationFilterEnabled` | `features.polyglotIntegrationFilterEnabled` | Enable or disable filtering `aspire add`, `aspire integration list`, and `aspire integration search` results to only integrations compatible with a non-C# (polyglot) AppHost. Disabled by default because remote NuGet feeds don't reliably answer the `tags:polyglot` query used to build the compatibility allow-list. |
+| `features.experimentalPolyglot:go` | `features.experimentalPolyglot:go` | Enable or disable experimental Go language support for non-C# Aspire applications. |
+| `features.experimentalPolyglot:java` | `features.experimentalPolyglot:java` | Enable or disable experimental Java language support for non-C# Aspire applications. |
+| `features.experimentalPolyglot:python` | `features.experimentalPolyglot:python` | Enable or disable experimental Python language support for non-C# Aspire applications. |
+| `features.experimentalPolyglot:rust` | `features.experimentalPolyglot:rust` | Enable or disable experimental Rust language support for non-C# Aspire applications. |
+| `features.polyglotIntegrationFilterEnabled` | `features.polyglotIntegrationFilterEnabled` | Enable or disable filtering `aspire add`, `aspire integration list`, and `aspire integration search` results to only integrations compatible with a non-C# AppHost. Disabled by default because remote NuGet feeds don't reliably answer the `tags:polyglot` query used to build the compatibility allow-list. |
| `features.showAllTemplates` | `features.showAllTemplates` | Show all available templates, including experimental ones, in `aspire new` and `aspire init`. |
| `features.showDeprecatedPackages` | `features.showDeprecatedPackages` | Show or hide deprecated packages in `aspire add` search results. |
| `features.updateNotificationsEnabled` | `features.updateNotificationsEnabled` | Enable or disable Aspire CLI update notifications. |
diff --git a/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx b/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
index a7bd94ae6..4fe5cf8f4 100644
--- a/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
+++ b/src/frontend/src/content/docs/whats-new/aspire-13-3.mdx
@@ -695,7 +695,7 @@ Aspire 13.3 closes most of the remaining functional gap between C# AppHosts and
### Unified `withEnvironment` API
-Aspire 13.3 introduces a unified `withEnvironment(name, value)` API for polyglot AppHosts (TypeScript, Java, Python, Go, Rust). The public TypeScript API accepts plain strings, reference expressions, endpoint references, parameter resources, supported resources that expose connection strings, expression values, and awaitable forms of supported values:
+Aspire 13.3 introduces a unified `withEnvironment(name, value)` API for non-C# AppHosts (TypeScript, Java, Python, Go, Rust). Previously, environment variable injection required separate methods for each value kind (`withEnvironmentEndpoint`, `withEnvironmentParameter`, `withEnvironmentConnectionString`, and so on). Now, a single call handles all value types:
```typescript title="apphost.mts"
const primaryEndpoint = await cache.primaryEndpoint();
diff --git a/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx b/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx
index 359e4ea97..360c7324d 100644
--- a/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx
+++ b/src/frontend/src/content/docs/whats-new/aspire-13-4.mdx
@@ -138,12 +138,12 @@ Aspire 13.4 validates TypeScript AppHosts before startup, so type-checking and c
Docs now include TypeScript examples alongside C# where the API is available, and the release adds TypeScript samples you can start from.
-The [Aspire Type System (ATS)](/extensibility/multi-language-integration-authoring/) APIs that power polyglot AppHost authoring are now generally available, so projects can remove `ASPIREATS001` suppressions. The generated TypeScript SDK also adds C# XML-doc JSDoc, fluent async method chaining, `ExternalServiceResource` support in `withEnvironment`, and fixes for generated names and exports.
+The [Aspire Type System (ATS)](/extensibility/multi-language-integration-authoring/) APIs that power non-C# AppHost authoring are now generally available, so projects can remove `ASPIREATS001` suppressions. The generated TypeScript SDK also adds C# XML-doc JSDoc, fluent async method chaining, `ExternalServiceResource` support in `withEnvironment`, and fixes for generated names and exports.
Existing TypeScript AppHosts scaffolded by earlier CLI versions continue to work on 13.4 without changes. If your project uses `apphost.ts` and `./.modules/aspire.js`, see [Legacy `apphost.ts` projects (pre-13.4)](#legacy-apphostts-projects-pre-134) for compatibility details and an opt-in migration to the new `apphost.mts` layout.
- For preview polyglot AppHosts behind feature flags, see [`aspire config set`](/reference/cli/commands/aspire-config-set/).
+ For preview non-C# AppHosts behind feature flags, see [`aspire config set`](/reference/cli/commands/aspire-config-set/).
For setup details, see [TypeScript AppHosts](/app-host/typescript-apphost/).
To explore working examples, browse the [Aspire samples](/reference/samples/).
@@ -770,7 +770,7 @@ After migrating, `aspire run` behaves exactly the same as before — the CLI now
-Aspire 13.4 includes several breaking changes. Most are small renames or configuration moves, but a few affect deployment and the polyglot AppHost SDK layout. Review the subsections that apply to your app before upgrading.
+Aspire 13.4 includes several breaking changes. Most are small renames or configuration moves, but a few affect deployment and the non-C# AppHost SDK layout. Review the subsections that apply to your app before upgrading.
#### `aspire exec` command removed
@@ -780,7 +780,7 @@ Remove scripts or workflows that call `aspire exec`. For resource-specific actio
#### Generated TypeScript modules consolidated under `.aspire/modules/`
-Generated polyglot SDK modules now live under a single `.aspire/modules/` directory instead of being split across `.modules/` and `.aspire/`. Generated language references — TypeScript imports, Go replace directives, Python editable paths, Java source lists, and Rust module paths — are updated automatically to point at the new location.
+Generated non-C# SDK modules now live under a single `.aspire/modules/` directory instead of being split across `.modules/` and `.aspire/`. Generated language references — TypeScript imports, Go replace directives, Python editable paths, Java source lists, and Rust module paths — are updated automatically to point at the new location.
Re-run `aspire run` (or your code-generation step) to regenerate references, and update any custom tooling or `.gitignore` entries that referenced the old `.modules/` path.
@@ -874,7 +874,7 @@ For full guidance and the container path mapping, see [PostgreSQL 18 data direct
1. **Update the CLI** — run `aspire update --self`. This step is **required** for TypeScript AppHosts; running `aspire update` against a 13.3.x TypeScript project before updating the CLI fails with `No code generator found for language: TypeScript` and leaves the project in a partially-upgraded, unrunnable state (see [microsoft/aspire#17077](https://github.com/microsoft/aspire/issues/17077)).
-2. **Update your projects** — run `aspire update` from the root of your repository. For polyglot AppHosts, this regenerates SDK modules under `.aspire/modules/`.
+2. **Update your projects** — run `aspire update` from the root of your repository. For non-C# AppHosts, this regenerates SDK modules under `.aspire/modules/`.
3. **Run `aspire doctor`** to check your environment setup and spot conflicting CLI installs.
4. **Audit scripts and CI** for removed/changed commands — `aspire exec` and non-interactive `aspire update` calls.
5. **Update Kubernetes deployment code** — move Helm chart properties into `WithHelm(...)`, rename `ingress.WithRoute(...)` to `ingress.WithPath(...)`, and mark routed endpoints external with `WithExternalHttpEndpoints()`.
diff --git a/src/frontend/src/content/docs/whats-new/aspire-13-5.mdx b/src/frontend/src/content/docs/whats-new/aspire-13-5.mdx
index d75185c7e..a7fcfb85f 100644
--- a/src/frontend/src/content/docs/whats-new/aspire-13-5.mdx
+++ b/src/frontend/src/content/docs/whats-new/aspire-13-5.mdx
@@ -1,6 +1,6 @@
---
title: "What's new in Aspire 13.5"
-description: "Explore Aspire 13.5, a developer-experience release: interactive terminal sessions, the Interaction Service across C# and TypeScript AppHosts with file uploads and progress dialogs, user-defined resource command arguments, generally available TypeScript AppHosts with health checks and container files, HTTPS certificates for projects, Kubernetes and AKS persistent volumes, a refreshed dashboard, and a rebranded VS Code extension."
+description: "Explore Aspire 13.5: Interactive terminal sessions, polyglot IInteractionService, TypeScript AppHost stability, terminal commands with user inputs, custom health checks, distributed tracing improvements, and dashboard enhancements."
sidebar:
label: Aspire 13.5
order: 0
@@ -12,33 +12,40 @@ tableOfContents:
import {
Steps,
Aside,
+ FileTree,
Icon,
Tabs,
TabItem,
} from '@astrojs/starlight/components';
import LearnMore from '@components/LearnMore.astro';
import OsAwareTabs from '@components/OsAwareTabs.astro';
-import { Image } from 'astro:assets';
-import dashboardResources from '@assets/dashboard/explore/projects.png';
-import dashboardStructuredLogsFiltered from '@assets/dashboard/explore/structured-logs-filtered.png';
-import dashboardTracesFiltering from '@assets/dashboard/explore/traces-filtering.png';
-
-Aspire 13.5 is here, and it's a **developer-experience** release through and through — sharper tooling, **closer C# and TypeScript parity**, and a batch of runtime-stability fixes. The headline is a richer, more interactive AppHost: resources can host **interactive terminal sessions** with `WithTerminal()`, the **Interaction Service** now works across both **C#** and **TypeScript** AppHosts — with **file uploads** and **progress dialogs** — and resource commands can **prompt for user-defined arguments** before they run. **TypeScript AppHosts are now generally available**, gaining **custom health checks** and **container file copying** to close the gap with C#. Projects can request **HTTPS developer certificates**, and deployment picks up **persistent volumes for Kubernetes and AKS**. The dashboard gets an officially branded visual refresh and sharper telemetry filtering, and the Visual Studio Code extension is rebranded to **Aspire** with dashboard, debugging, and discovery improvements.
+Aspire 13.5 is here with focus on **developer experience**, **[polyglot](/get-started/glossary/#polyglot) feature parity**, and **runtime stability**. This release brings **interactive terminal sessions** via `WithTerminal()`, **IInteractionService available across all polyglot AppHosts** (TypeScript, Python, Go, Java, and Rust), **user-defined arguments in resource commands** for interactive workflows, **TypeScript AppHost startup optimizations** and **stability fixes**, **custom health checks for TypeScript AppHosts**, **container file copying** in polyglot AppHosts, **promoted IInteractionService to stable**, a major **Foundry integration update** to use the CLI-based lifecycle, **distributed trace improvements** including timestamp filtering, **dashboard telemetry enhancements**, new **VS Code extension commands** including opening the Dashboard in a side panel, **Bun debugging support**, **resource command visibility** in the extension tree, **Aspire CLI available via npm**, and many more improvements and bug fixes across AppHost, CLI, Dashboard, and Extensions.
We'd love to hear what you think. Drop by [ Discord](https://aka.ms/aspire-discord) to chat with the team and the community, or file feedback and issues on [ GitHub](https://github.com/microsoft/aspire/issues).
This release introduces:
-- **Interactive terminal sessions** with the experimental `WithTerminal()` API, so you can attach to REPLs, shells, and other terminal programs running as Aspire resources from the dashboard — with an opt-in `aspire terminal` CLI command.
-- **The Interaction Service across C# and TypeScript AppHosts** — prompts, message boxes, notifications, and dynamic inputs, now with **file uploads** and **progress dialogs**. The core `PromptInput`/`PromptInputs` surface is stable and no longer requires suppressing `ASPIREINTERACTION001`.
-- **User-defined resource command arguments**, so the dashboard can prompt for input before invoking a command — the CLI exposes them as `--` options — with full C# and TypeScript parity.
-- **HTTPS certificates for project resources** through a new experimental configuration API.
-- **Generally available TypeScript AppHosts**, adding **custom health checks** and **container file copying** at parity with C#, plus faster startup and a batch of reliability fixes.
-- **The Aspire CLI on npm and Nix**, with the CLI bundle enabled by default in new C# projects — acquired on the fly via `dnx`.
-- **A refreshed, officially branded dashboard** with timestamp filtering, numeric operators, and console-log text search.
-- **A rebranded Visual Studio Code extension** with a dashboard side panel, Bun and MAUI debugging, and resource commands in the tree view.
-- **Cross-scope Azure resource references** with the `AsExisting*` family, and **persistent volumes for Kubernetes and AKS**.
+- **Interactive terminal sessions** with `WithTerminal()` on AppHost resources enable live REPL and shell interaction through the Dashboard and CLI.
+- **Polyglot IInteractionService parity** brings prompts, message boxes, notifications, and dynamic inputs to TypeScript, Python, Go, Java, and Rust AppHosts alongside C#.
+- **User-defined resource command arguments** let Dashboard and CLI prompt for input before invoking commands like custom deploy or setup workflows.
+- **TypeScript AppHost stability improvements** fix deadlocks, optimize startup by racing connection attempts against process exit, and validate compilation before execution.
+- **Custom health checks in TypeScript AppHosts** enable resource-specific health monitoring in polyglot environments.
+- **Container file copying in TypeScript AppHosts** brings parity with C# for copying host files into containers with ownership and permission controls.
+- **IInteractionService promoted to stable** removes the ASPIREINTERACTION001 diagnostic requirement from production code.
+- **CLI available via npm** (@microsoft/aspire-cli) provides an alternative installation path alongside the default distribution.
+- **Embedded Aspire skills bundle fallback** ensures the CLI can bootstrap even when GitHub release asset acquisition is unavailable.
+- **Faster TypeScript AppHost startup** skips fixed delays and races the connection retry loop, reducing time-to-ready.
+- **Friendly error messages for health check failures** replace raw exception stacks with actionable diagnostics in the Dashboard.
+- **Distributed trace timestamp filtering** enables precise telemetry searches by date and time.
+- **VS Code Dashboard in side panel** lets you monitor your app without leaving VS Code.
+- **Bun debugging support** in VS Code extension via WebKit Inspector Protocol.
+- **Resource commands in VS Code tree view** display all available actions (Start, Stop, custom commands) under each resource.
+- **Improved parameter display** in VS Code shows secret masks, missing value warnings, and consistent formatting across panels.
+- **VS Code extension renamed to "Aspire"** and rebranded for clarity on the Marketplace.
+- **AppHost discovery efficiency** in VS Code respects exclusion settings and debounces file changes to reduce background scanning.
+- **Foundry Local integration CLI update** now uses the foundry CLI for lifecycle management, requiring foundry 1.1.0+.
+- **Proxyless endpoint port allocation** assigns dynamic public host ports before resources are created, so endpoint property references resolve consistently.
- …and much more.
## 🆙 Upgrade to Aspire 13.5
@@ -46,10 +53,6 @@ This release introduces:
-
-
-Or install the CLI from scratch. The Aspire CLI ships through the package managers you already use — added in the 13.4 timeframe and now the recommended way to get it — so pick whichever fits your environment:
-
-
-
-
-```bash title="Install with Homebrew"
-brew install --cask microsoft/aspire/aspire
-```
-
-
-
-
-```bash title="Install with npm"
-npm install -g @microsoft/aspire-cli
-```
-
-
-
-
-```bash title="Install with the .NET CLI"
-dotnet tool install -g Aspire.Cli
-```
-
-
-
-
-```powershell title="Install with WinGet"
-winget install Microsoft.Aspire
-```
-
-
-
-
-```bash title="Install with mise"
-mise use -g aspire
-```
-
-
-
-
-```bash title="Install with Nix"
-nix profile add github:microsoft/aspire#aspire-cli
-```
-
-
-
-
-Prefer the one-line install script? It still works everywhere:
+Or install the CLI from scratch:
@@ -143,884 +99,115 @@ Prefer the one-line install script? It still works everywhere:
- For every installation method, see [Install the CLI](/get-started/install-cli/).
-
-
-
-
-## 🧩 App model and AppHost
-
-The AppHost is where 13.5 invests most heavily. These additions make local development more interactive and bring the C# and TypeScript app models closer to parity — from terminal sessions and richer user interactions to modeling more kinds of resources.
-
-### 🖥️ Interactive terminal sessions with WithTerminal()
-
-AppHost authors can now call `WithTerminal()` on a resource to enable an interactive terminal session. The dashboard can attach to and detach from the session at will, so you can drive REPLs, shells, and other terminal programs that run as Aspire resources — right from the dashboard's terminal view. Terminal dimensions are configurable through `TerminalOptions`, which exposes `Columns` (default `120`), `Rows` (default `30`), and `ShowTerminalHost`.
-
-
-
-
-
-
-```csharp title="AppHost.cs"
-#pragma warning disable ASPIRETERMINAL001
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddContainer("db", "postgres")
- .WithTerminal(options =>
- {
- options.Columns = 200;
- options.Rows = 50;
- });
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-// Polyglot AppHosts expose a parameterless withTerminal(). Terminal dimensions
-// (TerminalOptions.Columns/Rows) can only be configured from C#.
-await builder.addContainer('db', 'postgres').withTerminal();
-
-await builder.build().run();
-```
-
-
-
-
-
- For details, see [Interactive terminal sessions with WithTerminal()](/app-host/with-terminal/).
-
-
-### 💬 Interaction Service for C# and TypeScript AppHosts
-
-The Interaction Service and all of its related types — prompts, message boxes, notifications, and dynamic inputs — now work the same way from **C#** and **TypeScript** AppHosts, so the examples below come in both languages. The core prompt and input APIs (`PromptInputAsync`, `PromptInputsAsync`, and the supporting `InteractionInput`, `InputType`, and `InteractionInputCollection` types) are now **stable**, so you no longer have to suppress `ASPIREINTERACTION001` to use them from production code.
-
-The example below adds a resource command that prompts the user to choose a region, then acts on the selection.
-
-
-
-
-```csharp title="AppHost.cs"
-using Aspire.Hosting.ApplicationModel;
-using Microsoft.Extensions.DependencyInjection;
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-var api = builder.AddContainer("api", "nginx");
-
-api.WithCommand("configure-region", "Configure region", async ctx =>
-{
- var interaction = ctx.Services.GetRequiredService();
-
- // Commands invoked from the CLI run with NonInteractive = true, where
- // PromptInputsAsync throws. Only prompt when a UI is attached.
- if (!interaction.IsAvailable)
- {
- return CommandResults.Success();
- }
-
- var result = await interaction.PromptInputsAsync(
- title: "Configure region",
- message: "Choose the region to deploy to.",
- inputs:
- [
- new InteractionInput
- {
- Name = "region",
- Label = "Region",
- InputType = InputType.Choice,
- Options =
- [
- new("us", "United States"),
- new("eu", "Europe"),
- ]
- }
- ],
- cancellationToken: ctx.CancellationToken);
-
- if (result.Canceled)
- {
- return CommandResults.Canceled();
- }
-
- var region = result.Data["region"].Value;
- return CommandResults.Success();
-});
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-import type { InteractionChoiceOption } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-const api = await builder.addContainer('api', 'nginx');
-
-await api.withCommand('configure-region', 'Configure region', async (ctx) => {
- const interaction = await ctx.services().getInteractionService();
-
- if (!(await interaction.isAvailable())) {
- return { success: true, message: 'No interactive dashboard.' };
- }
-
- const regionInput = await interaction.createChoiceInput('region', {
- choices: [
- { value: 'us', label: 'United States' },
- { value: 'eu', label: 'Europe' },
- ] as InteractionChoiceOption[],
- });
-
- const result = await interaction.promptInputs(
- 'Configure region',
- 'Choose the region to deploy to.',
- [regionInput],
- { primaryButtonText: 'Apply' }
- );
-
- if (await result.canceled()) {
- return { success: false, message: 'Canceled.' };
- }
-
- const region = await result.inputs().value('region');
- return { success: true, message: `region=${region ?? ''}` };
-});
-
-await builder.build().run();
-```
-
-
-
-
-
- For the full API surface and TypeScript examples, see [Interaction service](/extensibility/interaction-service/).
-
-
-### 📤 File uploads and progress dialogs
-
-The Interaction Service can now ask users to **upload a file**. Add an `InteractionInput` with `InputType.File`, and the dashboard renders a file picker constrained by an optional `FileFilter` and `MaxFileSize`. After submission, C# AppHosts read the uploaded content through `InteractionFile` (via `ReadAllBytesAsync()` or `OpenRead()`), while TypeScript AppHosts receive the upload as an on-disk path (`file.filePath`) to read with Node's `fs` APIs. The file-upload input is **stable**. Long-running commands can also show a **progress dialog** with `PromptProgressAsync`.
-
-
-
-
-
-
-```csharp title="AppHost.cs"
-#pragma warning disable ASPIREINTERACTION001
-
-using Aspire.Hosting.ApplicationModel;
-using Microsoft.Extensions.DependencyInjection;
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-var importer = builder.AddContainer("importer", "nginx");
-
-importer.WithCommand("import-data", "Import data", async ctx =>
-{
- var interaction = ctx.Services.GetRequiredService();
-
- // Commands invoked from the CLI run with NonInteractive = true, where
- // PromptInputsAsync throws. Only prompt when a UI is attached.
- if (!interaction.IsAvailable)
- {
- return CommandResults.Success();
- }
-
- var result = await interaction.PromptInputsAsync(
- title: "Import data",
- message: "Select a JSON file to import.",
- inputs:
- [
- new InteractionInput
- {
- Name = "dataFile",
- Label = "Data file",
- InputType = InputType.File,
- FileFilter = ".json",
- MaxFileSize = 10 * 1024 * 1024, // 10 MB
- Required = true
- }
- ],
- cancellationToken: ctx.CancellationToken);
-
- if (result.Canceled)
- {
- return CommandResults.Canceled();
- }
-
- var file = result.Data["dataFile"].Files?[0];
- if (file is null)
- {
- return CommandResults.Failure("No file was uploaded.");
- }
-
- var bytes = await file.ReadAllBytesAsync(ctx.CancellationToken);
-
- // Progress dialog is experimental (ASPIREINTERACTION001). Run the work in
- // ProgressInteractionOptions.Work so the dialog closes when the work
- // completes; without a Work callback it stays open until the token cancels.
- await interaction.PromptProgressAsync(
- message: $"Processing {bytes.Length} bytes",
- title: "Importing...",
- options: new ProgressInteractionOptions
- {
- Work = async progress =>
- {
- // Long-running processing runs here while the dialog is shown.
- await Task.Delay(TimeSpan.FromSeconds(2), progress.CancellationToken);
- }
- },
- cancellationToken: ctx.CancellationToken);
-
- return CommandResults.Success();
-});
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-import { statSync } from 'node:fs';
-
-const builder = await createBuilder();
-
-const importer = await builder.addContainer('importer', 'nginx');
-
-await importer.withCommand('import-data', 'Import data', async (ctx) => {
- const interaction = await ctx.services().getInteractionService();
-
- // Commands invoked from the CLI run without an attached UI, where prompting
- // throws. Only prompt when the interaction service is available.
- if (!(await interaction.isAvailable())) {
- return { success: true, message: 'No interactive dashboard.' };
- }
-
- const fileInput = await interaction.createFileInput('dataFile', {
- label: 'Data file',
- fileFilter: '.json',
- maxFileSize: 10 * 1024 * 1024, // 10 MB
- required: true,
- });
-
- const result = await interaction.promptInput(
- 'Import data',
- 'Select a JSON file to import.',
- fileInput,
- { primaryButtonText: 'Import' });
-
- if (result.canceled) {
- return { success: false, message: 'Canceled.' };
- }
-
- // Uploaded files are written to disk; read them through their filePath.
- const file = result.input?.files?.[0];
- if (!file?.filePath) {
- return { success: false, message: 'No file was uploaded.' };
- }
-
- const bytes = statSync(file.filePath).size;
-
- // The work callback runs while the progress dialog is shown; the dialog
- // closes when the callback completes.
- await interaction.promptProgress(`Processing ${bytes} bytes`, {
- title: 'Importing...',
- options: {
- work: async () => {
- await new Promise((resolve) => setTimeout(resolve, 2000));
- },
- },
- });
-
- return { success: true, message: 'Imported.' };
-});
-
-await builder.build().run();
-```
-
-
-
-
-
- For inputs, validation, and result handling, see [Interaction service](/extensibility/interaction-service/).
-
-
-### ⚙️ Resource commands with user-defined arguments
-
-Resource commands can now declare **named arguments**. In the dashboard, users are prompted for these arguments before the command runs; from the CLI, each argument is surfaced as a `--` option, and the command errors when a required option is missing. Populate `CommandOptions.Arguments` with `InteractionInput` descriptors, and read the collected values from `ExecuteCommandContext.Arguments` inside the command callback. TypeScript AppHosts get full parity through Aspire Type System (ATS) exports. This mechanism is stable and works for interactive workflows such as custom deployment or setup procedures.
-
-
-
-
-```csharp title="AppHost.cs"
-using Aspire.Hosting.ApplicationModel;
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddContainer("api", "nginx")
- .WithCommand(
- name: "echo",
- displayName: "Echo",
- executeCommand: ctx =>
- {
- var message = ctx.Arguments["message"].Value;
- // Use the collected argument...
- return Task.FromResult(CommandResults.Success());
- },
- commandOptions: new CommandOptions
- {
- Description = "Echo a message.",
- Arguments =
- [
- new InteractionInput
- {
- Name = "message",
- Label = "Message",
- InputType = InputType.Text,
- Required = true
- }
- ]
- });
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder, InputType } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-await builder.addContainer('api', 'nginx').withCommand('echo', 'Echo', async (ctx) => {
- const args = await ctx.arguments();
- const message = await args.value('message');
- // Use the collected argument...
- return { success: true, message: `message=${message ?? ''}` };
-}, {
- commandOptions: {
- arguments: [
- { name: 'message', inputType: InputType.Text, required: true },
- ],
- },
-});
-
-await builder.build().run();
-```
-
-
-
-
-
- For the full command API, see [Custom resource commands](/fundamentals/custom-resource-commands/).
-
-
-### 🔐 HTTPS certificates for project resources
-
-Project and executable resources can now be configured with HTTPS certificates directly from the AppHost. Use `WithHttpsDeveloperCertificate()` to inject the local ASP.NET Core developer certificate, `WithHttpsCertificate(certificate, password)` to supply an explicit `X509Certificate2`, or `WithHttpsCertificateConfiguration(...)` for full control. `WithoutHttpsCertificate()` opts a resource out.
-
-
-
-
-
-
-```csharp title="AppHost.cs"
-#pragma warning disable ASPIRECERTIFICATES001
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddProject("api")
- .WithHttpsDeveloperCertificate();
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-await builder.addProject('api', './src/Api').withHttpsDeveloperCertificate();
-
-await builder.build().run();
-```
-
-
-
-
-
- For certificate options and deployment considerations, see [Certificate configuration](/app-host/certificate-configuration/).
-
-
-### ☁️ Reference existing Azure resources across scopes
-
-Aspire 13.5 makes it easier to point at Azure resources that live **outside** your app's own resource group, subscription, or tenant. The `AsExistingInResourceGroup(name, resourceGroup, subscription)`, `AsExistingInSubscription(name, subscription)`, and `AsExistingInTenant(name)` methods — along with their `RunAsExisting*` and `PublishAsExisting*` variants — attach an existing-resource annotation so provisioning references the resource in the scope you specify. Each accepts either literal strings or `ParameterResource` values, so scope details can come from parameters and secrets.
-
-
-
-
-```csharp title="AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
-
-var name = builder.AddParameter("sb-name");
-var resourceGroup = builder.AddParameter("sb-rg");
-var subscription = builder.AddParameter("sb-sub");
-
-builder.AddAzureServiceBus("sb")
- .AsExistingInResourceGroup(name, resourceGroup, subscription);
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-const name = await builder.addParameter('sb-name');
-const resourceGroup = await builder.addParameter('sb-rg');
-const subscription = await builder.addParameter('sb-sub');
-
-await builder.addAzureServiceBus('sb')
- .asExistingInResourceGroup(name, resourceGroup, subscription);
-
-await builder.build().run();
-```
-
-
-
-
-
- For run- versus publish-mode behavior, see [Use existing Azure resources](/integrations/cloud/azure/customize-resources/).
-
-
-### 🐞 Model .NET projects by path with AddDotnetProject
-
-Aspire 13.5 adds the experimental `AddDotnetProject(name, path)` API in the new `Aspire.Hosting.Dotnet` package. It models a .NET project **by its path** — as a `DotnetProjectResource` — which is useful when you can't (or don't want to) add a compile-time `ProjectReference` from the AppHost, for example when the project lives outside your solution or you're assembling a mixed-language app. The resource participates in orchestration like any other project, and the [Aspire Visual Studio Code extension](/get-started/aspire-vscode-extension/) can attach a debugger to it through the new `SupportsDebuggingAnnotation`.
-
-
-
-
-
-
-```csharp title="AppHost.cs"
-#pragma warning disable ASPIREDOTNETPROJECT001
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddDotnetProject("inventory", @"../InventoryService/InventoryService.csproj");
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-await builder.addDotnetProject('inventory', '../InventoryService/InventoryService.csproj');
-
-await builder.build().run();
-```
-
-
-
-
-Because a `DotnetProjectResource` is orchestration-only, `aspire publish` and `aspire deploy` fail with an actionable error rather than emitting a manifest with machine-local paths. When you need to publish a path-based project, reach for `AddCSharpApp(...)`/`addCSharpApp(...)` or configure container publishing with `PublishAsDockerFile(...)`.
-
-Go resources get a debugging boost too: the Delve server accepts a single client by default and can opt into **multi-client** mode via `WithDelveServer(o => o.AcceptMultiClient = true)`, and typed options for common Delve server flags (including `--continue`) are configured through `DelveServerOptions` in C# AppHosts.
-
-
- For modeling .NET projects, see [Set up .NET / C# apps in the AppHost](/integrations/frameworks/dotnet/dotnet-host/); for Go, see [Go hosting integration](/integrations/frameworks/go/go-host/).
+ For more details on installing the Aspire CLI, see [Install the CLI](/get-started/install-cli/).
-## 🟦 TypeScript AppHost improvements
+## 🖥️ Interactive terminal sessions with WithTerminal()
-TypeScript (and polyglot) AppHost support is now **generally available** in 13.5 — the `ASPIREATS001` experimental diagnostic is gone, so you no longer suppress anything to author an AppHost in TypeScript. With GA in place, this release closes several remaining gaps with C#.
-
-### 💚 Custom health checks
-
-TypeScript AppHosts can now register custom health check callbacks with `builder.addHealthCheck(name, check)` and attach them (or the built-in checks) to a resource with `resource.withHealthCheck(key)`. The callback returns a `HealthCheckResult` with a `status`, optional `description`, and optional `data`. Project resources also gain `withEndpointsInEnvironment(endpointNames)` to control which endpoints are injected into environment variables. This brings TypeScript to parity with C#, where custom checks are registered through `AddHealthChecks().AddCheck(...)` and attached with the same `WithHealthCheck(key)` method.
-
-```typescript title="apphost.mts"
-import { createBuilder, HealthStatus } from './.aspire/modules/aspire.mjs';
-import type { HealthCheckResult } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-const myCheck = async (): Promise => ({
- status: HealthStatus.Healthy,
- description: 'All systems nominal',
- data: { version: '1.0' },
-});
-await builder.addHealthCheck('my_check', myCheck);
-
-await builder.addRedis('cache').withHealthCheck('my_check');
-
-await builder.build().run();
-```
+AppHost authors can now call `WithTerminal()` on a resource to enable interactive terminal sessions. The Dashboard and CLI can attach to and detach from the session at will, enabling live use of REPLs, shells, and other terminal programs running as Aspire resources. This is particularly powerful for resource orchestration workflows where you need to interact with services in real-time.
- For the TypeScript AppHost model, see [TypeScript AppHost](/app-host/typescript-apphost/), and for health checks in general, see [Health checks](/fundamentals/health-checks/).
+ For details, see [WithTerminal() interactive terminal sessions](/app-host/with-terminal/).
-### 🐳 Container file copying
-
-TypeScript AppHosts can now copy host files into container resources, reaching parity with C#. Use `withContainerFiles(destinationPath, sourcePath, options)` to copy a directory, or `withContainerFilesCallback(destinationPath, callback, options)` to generate files dynamically at build time. Ownership and permissions are controlled through `ContainerFilesOptions` (`defaultOwner`, `defaultGroup`, `umask`). C# exposes the same capability through the `WithContainerFiles(...)` overloads, which accept either a source directory or a build-time callback.
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
+## 🌐 IInteractionService available across polyglot AppHosts
-const builder = await createBuilder();
-
-await builder.addContainer('myapp', 'nginx')
- .withContainerFiles('/usr/share/nginx/html', './wwwroot', {
- defaultOwner: 101, // nginx user UID
- defaultGroup: 101,
- umask: 0o022,
- })
- .withContainerFilesCallback('/etc/nginx/conf.d', async (ctx) => {
- const conf = await ctx.createFile('default.conf', {
- contents: 'server { listen 80; }',
- mode: 0o644,
- });
- return [conf];
- });
-
-await builder.build().run();
-```
+IInteractionService and all related interaction types (prompts, message boxes, notifications, dynamic inputs) are now available in **non-C# AppHosts** written in TypeScript, Python, Go, Java, and Rust—providing feature parity with C# AppHosts. This enables rich user interaction patterns across all supported languages.
- For the full callback surface, see [Container files](/app-host/container-files/).
+ For TypeScript examples, see [IInteractionService](/extensibility/interaction-service/).
-### ⚡ Faster startup and reliability fixes
-
-TypeScript AppHost startup no longer waits a fixed delay before the CLI attempts to connect; the CLI now races the RPC connection retry loop against process exit, reducing the time from `aspire run` to an active AppHost. This release also fixes several reliability issues:
+## 🆙 IInteractionService promoted to stable
-- A deadlock where async callbacks stored in `IOptions.Configure` were invoked during `BeforeStartEvent`.
-- A startup reliability issue with `WithBrowserLogs()` where tracked browser sessions could fail even when the browser eventually became responsive; the CDP startup timeout has been increased.
-- Failures when proxyless container endpoint references were accessed before the container was created.
-- `aspire run` failing for polyglot AppHosts that use `*.dev.localhost` resource service URLs.
+The `IInteractionService` API is no longer marked experimental. The `ASPIREINTERACTION001` diagnostic has been removed, so you can use interaction features without compiler suppressions in production code.
-## 🖥️ Aspire CLI
+## ⚙️ Resource commands with user-defined arguments
-The CLI is central to the Aspire developer experience, and 13.5 makes it easier to install, keep current, and reason about how it runs.
+HTTP resource commands now support named arguments, allowing the Dashboard and CLI to prompt for user input before invoking them. TypeScript AppHosts achieve full parity through Aspire Type System (ATS) exports. This enables interactive workflows such as custom deployment or setup procedures.
-### 📦 Install via npm and Nix
+## 💚 Custom health checks for TypeScript AppHosts
-The Aspire CLI is now available as an npm package (`@microsoft/aspire-cli`), and on Nix via the flake (`nix profile add github:microsoft/aspire#aspire-cli`). The update command and update notifier detect npm-installed versions and print the matching npm command instead of overwriting the managed binary. When the CLI can't fetch the Aspire skills bundle from GitHub release assets, it falls back to an embedded bundle and shows a non-fatal warning instead of failing the command.
+TypeScript AppHosts can now register custom health check callbacks using `builder.addHealthCheck()` and attach them to resources. Project resources also gain `withEndpointsInEnvironment()` to control which endpoints are injected into environment variables.
-
- For every installation method, see [Install the CLI](/get-started/install-cli/).
-
+## 🐳 TypeScript AppHosts support container file copying
-### 🎯 CLI bundle by default
+TypeScript AppHosts can now export `withContainerFiles` to copy host files into container resources, with full support for owner, group, and umask options—achieving parity with C# AppHosts.
-
+## ⚡ Faster TypeScript AppHost startup
-The *CLI bundle* is a copy of the Aspire CLI that an AppHost can resolve for itself, so `dotnet run` and `aspire run` behave identically and everyone on the team — and CI — uses a consistent CLI version without a separate global install. In 13.5, new C# AppHosts created from the templates opt in automatically by setting `AspireUseCliBundle=true`, so the bundle is resolved out of the box.
+TypeScript AppHost startup no longer waits a fixed delay before the CLI attempts to connect. The CLI now races the RPC connection retry loop against process exit, reducing the time from `aspire run` to an active AppHost.
-Here's what that means in practice:
+## 🔧 TypeScript AppHost fixes
-- **Nothing manual for new projects.** When the bundle is enabled and the CLI is 13.5.0 or later, `dotnet run` acquires the bundle on the fly through `dnx` and delegates to `aspire run`. It's a change in behavior from earlier releases, but not one you have to configure.
-- **Existing projects are unaffected** unless they opt in. The SDK-level default remains opt-in (`false`); set `AspireUseCliBundle=true` in your AppHost to adopt it, or pin the CLI through a local tool manifest for reproducible `dnx` invocation.
-- **The state is always explicit.** Diagnostics tell you exactly what's happening rather than failing silently: `ASPIRE009` (error) when the bundle can't be resolved, `ASPIRE010` (warning) when a project opts out, and `ASPIRE011` when `dnx` isn't available. You can force the DNX invocation path with `AspireCliInvocationMode=Dnx`.
+- Fixed a deadlock in TypeScript AppHosts where async callbacks stored in `IOptions.Configure` were invoked during `BeforeStartEvent`.
+- Fixed a startup reliability issue with `WithBrowserLogs()` where tracked browser sessions could fail even when the browser eventually became responsive. The CDP startup command timeout has been increased.
+- Fixed failures when proxyless container endpoint references were accessed before container creation.
+- Fixed `aspire run` failing for polyglot AppHosts using `*.dev.localhost` resource service URLs.
-### 🛠️ Command improvements
-
-- **`aspire stop --force`** performs a normal stop and then cleans up the AppHost's persistent resources, permanently deleting their data without an additional confirmation prompt.
-- **`aspire update --migrate`** migrates legacy TypeScript AppHost entry points (`apphost.ts` → `apphost.mts`).
-- **`aspire doctor`** reports operating-system details (including Linux distro info from `/etc/os-release`), detects Visual Studio Code, and adds DCP health checks. JSON output includes a structured `operating-system` check for tooling.
-- **`aspire docs search`** returns more relevant results.
-- Stale AppHost backchannel sockets are pruned automatically so they no longer block commands like `aspire add`, and Ctrl+C/SIGTERM handling is more responsive during startup.
-
-
- See the reference for [`aspire stop`](/reference/cli/commands/aspire-stop/), [`aspire update`](/reference/cli/commands/aspire-update/), and [`aspire doctor`](/reference/cli/commands/aspire-doctor/).
-
+## 📦 Aspire CLI available via npm
-## 📊 Dashboard
+The Aspire CLI is now available as an npm package (`@microsoft/aspire-cli`), providing an alternative installation method alongside the standard distribution. The update command and update notifier now detect and handle npm-installed versions.
-The dashboard is often the first thing you see when you run an Aspire app, and 13.5 gives it a substantial refresh — official branding, sharper telemetry filtering, and a built-in terminal view.
+## 💬 CLI improvements and diagnostics
-### 🎨 Refreshed, officially branded UI
+- **OS information in `aspire doctor`**: The `aspire doctor` command now reports operating system details in its Environment section. Human-readable output shows the OS type and version; on Linux it includes distro details from `/etc/os-release`. JSON output adds a structured `operating-system` check with `osType`, `displayName`, `version`, and `description` metadata fields for tooling.
+- **Embedded Aspire skills bundle fallback**: When GitHub release asset acquisition is unavailable, the CLI uses the embedded bundle and shows a non-fatal warning instead of failing the entire command.
+- **Faster stale backchannel socket cleanup**: Stale AppHost backchannel socket files no longer block CLI commands like `aspire add`. The CLI automatically prunes orphaned sockets before probing.
+- **Better TypeScript AppHost error messages**: When AppHost code generation fails due to version mismatches, the CLI provides enriched diagnostic output to help identify the cause.
+- **Improved aspire agent init output**: The command now collects updated skill/location pairs and prints one compact summary instead of repeating success for every skill.
+- **Improved aspire ls discovery**: Fixed multiple bugs in the settings discovery pipeline including settings.json compatibility and aspire.config.json handling.
+- **TypeScript AppHosts honor --no-build**: TypeScript AppHosts now correctly skip the TypeScript compilation check when the --no-build flag is passed.
+- **CLI shutdown responsiveness**: Multiple improvements to Ctrl+C/SIGTERM handling, including faster signal responsiveness during AppHost startup.
-The dashboard adopts official Aspire branding and a refreshed visual design built on a new design-token system, with accessibility improvements across the UI.
+## 📊 Dashboard and telemetry improvements
-
+- **Timestamp filter for telemetry**: Filter logs and traces by timestamp using a dedicated search qualifier in the Dashboard filter dialog.
+- **Numeric equality operators**: The telemetry filter dialog now includes `==` and `!=` operators for exact numeric value matching.
+- **Rich text visualizer improvements**: The TextVisualizerDialog now disables markdown formatting for JSON and XML content.
+- **Dashboard startup log formatting**: Improved output with indented URLs, separated container access warnings, and restored legacy login URL for `dotnet watch` integration.
+- **Friendly health check error messages**: Health check failures now display concise, actionable messages instead of raw exception stacks.
+- **Fixed telemetry streaming with resource filters**: Streams now wait for resources to appear before returning empty results.
+- **Fixed duplicate replica display names**: Dashboard now uses the last 8 characters of the service.instance.id GUID to prevent collisions.
-### 🔎 Sharper telemetry filtering
-
-- **Timestamp filter for telemetry** — filter logs and traces by timestamp using a dedicated search qualifier in the filter dialog.
-- **Numeric equality operators** — the telemetry filter dialog adds `==` and `!=` for exact numeric matching.
-- **Console logs text filter** — filter console-log output by text.
-- **Reconnect modal** — a clearer modal appears when the dashboard loses its connection to the AppHost.
-
-
-
-
-
-### 🖥️ Terminal view
-
-Running resources configured with `WithTerminal()` open in a terminal view in the dashboard by default, so you can interact with the live session immediately. Resources that are waiting, starting, exited, or failed fall back to the console-logs view until they reach the running state.
-
-
-
-Additional dashboard fixes include friendlier health-check error messages (in place of raw exception stacks), deduplicated replica display names, and correct telemetry streaming when resource filters are applied.
-
-## 🧩 Visual Studio Code extension
-
-The Aspire extension for Visual Studio Code is rebranded to **Aspire** (with an updated icon and display name) and gains a batch of new capabilities:
-
-- **Open the dashboard in a side panel** instead of an external browser.
-- **Bun debugging** (via the WebKit Inspector Protocol) and **MAUI debugging** support.
-- **Resource commands in the tree view** — Start, Stop, and custom commands appear as child items under each resource.
-- **Discovered AppHosts** — idle AppHosts found in the workspace appear in the Aspire pane with context-menu actions, and `launchUrl` from `launchSettings.json` is honored.
-- **Improved parameter display** — consistent secret masking, missing-value warnings, and truncation across panels.
-- **More efficient discovery** — respects workspace exclusion settings and debounces file changes, and terminal commands now use structured shell arguments to prevent command injection.
-- **A richer extension API surface** for integration with the C# Dev Kit.
-
-
-
-
- For setup and usage, see [Aspire Visual Studio Code extension](/get-started/aspire-vscode-extension/).
-
+## 🧩 VS Code extension enhancements
-## 🚀 Deployment and integrations
+- **Open Aspire Dashboard in side panel**: A new command lets you open the Dashboard in a side-by-side panel instead of an external browser.
+- **Bun debugging support**: VS Code extension now supports debugging Bun applications via the WebKit Inspector Protocol.
+- **Resource commands in tree view**: Resource commands (Start, Stop, custom commands) are displayed as child items under each resource.
+- **VS Code extension telemetry**: The extension now collects activation, debug session, and dashboard interaction signals for product improvement.
+- **Support launchUrl in launchSettings.json**: The extension respects the `launchUrl` property as the serverReadyAction URI format.
+- **Show discovered AppHosts in Aspire pane**: Idle AppHosts discovered via `aspire ls` now display in the VS Code Aspire pane with context menu actions.
+- **Security hardening**: Terminal commands now use structured shell arguments to prevent command injection via malicious paths or resource names.
+- **Parameter display improvements**: Consistent display across panels with secret masks, missing value warnings, and 80-character truncation for non-secrets.
+- **VS Code extension branding**: Rebranded to "Aspire" with an updated icon and display name.
+- **AppHost discovery efficiency**: Respects workspace exclusion settings, debounces file changes, and avoids overlapping discovery runs.
-Getting from local development to a deployed environment keeps getting smoother. This release adds first-class Kubernetes and AKS storage, more predictable Azure Container Apps naming and networking, and a batch of new and updated hosting integrations.
+## 🔌 Integration improvements
-### 📦 Persistent volumes for Kubernetes and AKS
-
-You can now model Kubernetes `PersistentVolumeClaim`s as first-class resources. Call `AddPersistentVolume(name)` on a Kubernetes environment, configure it with `WithStorageClass`, `WithCapacity`, and `WithAccessMode`, and bind it to a workload with `WithPersistentVolume(...)`. Any workload bound to a persistent volume is rendered as a `StatefulSet` rather than a `Deployment`. The same `AddPersistentVolume` API is available on the AKS environment via `Aspire.Hosting.Azure.Kubernetes`.
-
-
-
-
-
-
-```csharp title="AppHost.cs"
-#pragma warning disable ASPIRECOMPUTE002
-
-using Aspire.Hosting.Kubernetes;
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-var k8s = builder.AddKubernetesEnvironment("k8s");
-
-var data = k8s.AddPersistentVolume("data")
- .WithStorageClass("managed-csi")
- .WithCapacity("20Gi")
- .WithAccessMode(PersistentVolumeAccessMode.ReadWriteOnce);
-
-builder.AddContainer("postgres", "postgres:16")
- .WithVolume("data", "/var/lib/postgresql/data")
- .WithPersistentVolume(data);
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder, PersistentVolumeAccessMode } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-const k8s = await builder.addKubernetesEnvironment('k8s');
-
-const data = await k8s.addPersistentVolume('data')
- .withStorageClass('managed-csi')
- .withCapacity('20Gi')
- .withAccessMode(PersistentVolumeAccessMode.ReadWriteOnce);
-
-// The polyglot withVolume() reorders parameters to (target, name?), so the
-// mount path comes first. withKubernetesPersistentVolume() then binds by name.
-await builder.addContainer('postgres', 'postgres:16')
- .withVolume('/var/lib/postgresql/data', 'data')
- .withKubernetesPersistentVolume(data);
-
-await builder.build().run();
-```
-
-
-
-
-
- For details, see [Persistent volumes](/deployment/kubernetes/persistent-volumes/) and [Deploy to AKS](/deployment/kubernetes/aks/).
-
-
-### 🏷️ Unique resource naming for Azure Container Apps
-
-Azure Container Apps environments can opt into deterministic, collision-resistant resource names with `WithUniqueResourceNaming()`, which is useful when you deploy more than one environment into the same resource group. Names incorporate a `uniqueString(resourceGroup().id)` suffix while preserving each environment's digits, so `cae1` and `cae2` stay distinct.
-
-
-
-
-
-
-```csharp title="AppHost.cs"
-#pragma warning disable ASPIREACANAMING002
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddAzureContainerAppEnvironment("acaenv")
- .WithUniqueResourceNaming();
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-await builder.addAzureContainerAppEnvironment('acaenv')
- .withUniqueResourceNaming();
-
-await builder.build().run();
-```
-
-
-
-
-
- For more configuration options, see [Configure Azure Container Apps environments](/integrations/cloud/azure/configure-container-apps/).
-
-
-### 🔗 Virtual network integration for Azure environments
-
-Azure Container Apps and Azure App Service environments can now be placed into a delegated subnet. Declare a subnet with `WithServiceDelegation(serviceName)`, then attach it to an environment with `WithDelegatedSubnet(subnet)`. The virtual-network builder APIs live in `Aspire.Hosting.Azure.Network` and emit the [`ASPIREAZURE003`](/diagnostics/aspireazure003/) experimental diagnostic.
-
-
- For App Service hosting, see [Azure App Service hosting integration](/integrations/cloud/azure/azure-app-service/azure-app-service-host/).
-
-
-### ✨ New and updated integrations
-
-The integrations ecosystem keeps growing. Aspire 13.5 opens a preview path to a new deployment platform, sharpens the AI hosting story, and folds in a batch of community-driven improvements. Here are the highlights:
-
-- **Radius (preview).** The new `Aspire.Hosting.Radius` integration adds `AddRadiusEnvironment(name)` (with `WithNamespace(...)`) so you can publish your app to a [Radius](https://radapp.io/) environment. Publish-time infrastructure configuration (`ConfigureRadiusInfrastructure`) and project container-image overrides are gated behind experimental diagnostics.
-- **Foundry Local.** `AddFoundry(name).RunAsFoundryLocal()` now drives the installed **foundry CLI** for lifecycle management, and resources can be exposed as hosted agents with `AsHostedAgent(...)`, where `HostedAgentProtocol` is `Responses` or `Invocations`.
-- **Redis modules.** `AddRedis(...).WithModule(path)` loads a Redis module into the container, with `RedisModules` constants (`Json`, `Search`, `BloomFilter`, `TimeSeries`) pointing at the modules shipped in Redis 8+ images — see the sample below.
-- **.NET projects by path.** The new `Aspire.Hosting.Dotnet` package provides the experimental `AddDotnetProject` API for modeling .NET projects by path, covered earlier in this release.
-- **Dev tunnels regions.** `DevTunnelOptions.Region` (a `DevTunnelRegion?` enum) lets you pin the region a tunnel is created in.
-- **Blazor gateway on Docker Compose.** Blazor gateway resources now support Docker Compose publishing.
-
-
-
-
-```csharp title="AppHost.cs"
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddRedis("cache")
- .WithModule(RedisModules.Json)
- .WithModule(RedisModules.Search);
-
-builder.Build().Run();
-```
-
-
-
-
-```typescript title="apphost.mts"
-import { createBuilder, RedisModules } from './.aspire/modules/aspire.mjs';
-
-const builder = await createBuilder();
-
-await builder.addRedis('cache')
- .withModule(RedisModules.Json)
- .withModule(RedisModules.Search);
-
-await builder.build().run();
-```
-
-
-
-
-
- For Redis hosting, see [Redis hosting integration](/integrations/caching/redis/redis-host/); for tunnels, see [Dev tunnels](/integrations/devtools/dev-tunnels/); for Foundry, see [Azure AI Foundry](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/).
-
-
-## 🧰 Templates
-
-New project templates target **.NET 11 preview** in addition to the current LTS, and C# AppHost templates set `AspireUseCliBundle=true` by default so freshly scaffolded projects resolve the CLI bundle out of the box.
+- **Foundry Local CLI update**: The Foundry Local integration now uses the installed foundry CLI for lifecycle management instead of internal SDK APIs, requiring foundry CLI 1.1.0+.
+- **DevTunnel region configuration**: Added a `Region` property to `DevTunnelOptions` for specifying the tunnel creation region.
+- **Blazor gateway Docker Compose support**: Added Docker Compose publish support for Blazor gateway resources.
+- **Redis TLS deadlock fix**: Fixed a deadlock during Redis container startup when TLS was enabled with persistent lifetime.
## Breaking changes
The following breaking changes are included in Aspire 13.5:
-1. **`ServiceProvider` renamed to `Services`.** The `ServiceProvider` property on hosting context types is now `Services`. Update your code to use the new property name.
-
-2. **`PublishAsConnectionString` marked obsolete.** Switch to `AddConnectionString` in publish-mode app model code.
-
-3. **`aspire ps --resources` and `--include-hidden` removed.** `aspire ps` now focuses on AppHost-level summaries; use `aspire describe` for detailed resource data. (`--include-hidden` remains on the `aspire resource` subcommand.)
-
-4. **GitHub Models integration deprecated.** GitHub Models is no longer available to new customers, so `Aspire.Hosting.GitHub.Models` is deprecated. Its public APIs are marked `[Obsolete]` and the package no longer appears in `aspire add` output; it will be removed in a future release. Migrate to the [Azure AI Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/).
-
-5. **Proxyless endpoint port allocation timing changed.** Proxyless endpoints without an explicit public `port` now receive one during service preparation, before workload resources are created. The default allocation range is `10000-32767` and can be overridden with `ASPIRE_PROXYLESS_ENDPOINT_PORT_RANGE=start-end`.
-
-6. **Go polyglot: a single optional `options` DTO is now passed directly.** When an exported API has exactly one optional `options` DTO parameter, the Go code generator now passes the DTO type directly instead of wrapping it in a generated method-options struct. Go AppHosts that used the wrapper form must update their call sites after regenerating the SDK.
-
-7. **`TerminalOptions.Shell` removed; `Columns`/`Rows` validated.** `TerminalOptions` no longer has a `Shell` property, and `Columns`/`Rows` now throw `ArgumentOutOfRangeException` when set to zero or a negative value. The internal terminal implementation types are gated behind the `ASPIRETERMINAL001` experimental diagnostic.
+1. **ServiceProvider renamed to Services**: The `ServiceProvider` property on context types is now obsolete and replaced with `Services`. The old property still works but generates a compiler warning. Update your code to use the new property name.
-8. **`DevTunnelRegion` enum values normalized.** Region enum names were normalized — for example, `UKSouth` (not `UkSouth`) and `SoutheastAsia` (not `SouthEastAsia`). Update any code that referenced the old spellings.
+2. **PublishAsConnectionString marked obsolete**: The `PublishAsConnectionString` extension methods are now obsolete. Callers should switch to `AddConnectionString` in publish-mode app model code.
-9. **Dashboard AI Assistant removed.** The AI Assistant chat UI has been removed from the dashboard.
+3. **aspire ps --resources flag removed**: The `--resources` and `--include-hidden` flags have been removed from `aspire ps`, which now focuses on AppHost-level summaries. Use `aspire describe` for detailed resource data.
-10. **VS Code dashboard auto-launch removed.** The extension no longer opens the dashboard automatically; opt in with the `dashboardBrowser` setting or `launch.json` value.
+4. **GitHub Models integration deprecated**: The GitHub Models service is no longer available to new customers, so the `Aspire.Hosting.GitHub.Models` integration is sunset as of Aspire 13.5. All public APIs are marked `[Obsolete]`, and the package no longer appears in `aspire add` output. One final obsolete release will ship on NuGet, and the package will be removed entirely in a future version. Migrate to the [Azure AI Foundry integration](/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-get-started/) instead. See [microsoft/aspire#18402](https://github.com/microsoft/aspire/issues/18402) for details.
-11. **Orleans provider annotation is internal.** `OrleansProviderTypeAnnotation` and `ProviderConfiguration` are now internal.
+5. **Proxyless endpoint port allocation timing changed**: Proxyless endpoints without an explicit public `port` now receive one during service preparation, before workload resources are created. Executable proxyless endpoints that previously failed without a public port, and container proxyless endpoints that expected the public port to be assigned later during container startup, should expect Aspire to assign the port earlier. The default allocation range is `10000-32767` and can be overridden with `ASPIRE_PROXYLESS_ENDPOINT_PORT_RANGE=start-end`. Persistent resources reuse allocated ports from user secrets when available.
-12. **`DotnetProjectResource` moved to `Aspire.Hosting.Dotnet` and made experimental.** It now lives in the `Aspire.Hosting.Dotnet` namespace and emits the `ASPIREDOTNETPROJECT001` diagnostic.
+6. **Go polyglot SDK: single optional `options` DTO is now passed directly**: When a C# exported API has exactly one optional parameter that is a DTO named `options` (with no coexisting cancellation token or callback), the Go polyglot code generator now passes the DTO type directly as a variadic parameter instead of wrapping it in a generated method-options struct. Go AppHosts that used the wrapper-struct form must update their call sites after regenerating the SDK.
## Known issues
diff --git a/src/frontend/src/data/pkgs/Aspire.Hosting.13.4.6.json b/src/frontend/src/data/pkgs/Aspire.Hosting.13.4.6.json
index 3dc625770..5c2a47152 100644
--- a/src/frontend/src/data/pkgs/Aspire.Hosting.13.4.6.json
+++ b/src/frontend/src/data/pkgs/Aspire.Hosting.13.4.6.json
@@ -34107,7 +34107,7 @@
"children": [
{
"kind": "text",
- "text": "This C# overload is not exported to polyglot AppHosts. Use the language-specific static process command API instead."
+ "text": "This C# overload is not exported to non-C# AppHosts. Use the language-specific static process command API instead."
}
]
}
@@ -34236,7 +34236,7 @@
{
"name": "Aspire.Hosting.AspireExportIgnoreAttribute",
"arguments": {
- "Reason": "Process command factories are C# callbacks and cannot be represented in polyglot AppHosts."
+ "Reason": "Process command factories are C# callbacks and cannot be represented in non-C# AppHosts."
}
}
],
@@ -34335,7 +34335,7 @@
"children": [
{
"kind": "text",
- "text": "This C# callback overload is not available in polyglot AppHosts."
+ "text": "This C# callback overload is not available in non-C# AppHosts."
}
]
}
@@ -34457,7 +34457,7 @@
{
"name": "Aspire.Hosting.AspireExportIgnoreAttribute",
"arguments": {
- "Reason": "Process command factories are C# callbacks and cannot be represented in polyglot AppHosts."
+ "Reason": "Process command factories are C# callbacks and cannot be represented in non-C# AppHosts."
}
}
],
@@ -34556,7 +34556,7 @@
"children": [
{
"kind": "text",
- "text": "This C# callback overload is not available in polyglot AppHosts."
+ "text": "This C# callback overload is not available in non-C# AppHosts."
}
]
}
diff --git a/src/frontend/src/data/pkgs/Aspire.Hosting.Kubernetes.13.4.6-preview.1.26319.6.json b/src/frontend/src/data/pkgs/Aspire.Hosting.Kubernetes.13.4.6-preview.1.26319.6.json
index 26a5b84bc..70b486f49 100644
--- a/src/frontend/src/data/pkgs/Aspire.Hosting.Kubernetes.13.4.6-preview.1.26319.6.json
+++ b/src/frontend/src/data/pkgs/Aspire.Hosting.Kubernetes.13.4.6-preview.1.26319.6.json
@@ -8360,7 +8360,7 @@
{
"name": "Aspire.Hosting.AspireExportIgnoreAttribute",
"arguments": {
- "Reason": "Kubernetes manifest resource types are C#-only customization objects and are not part of the polyglot SDK surface."
+ "Reason": "Kubernetes manifest resource types are C#-only customization objects and are not part of the non-C# SDK surface."
}
}
],
diff --git a/src/frontend/src/data/pkgs/Aspire.Hosting.Yarp.13.4.6.json b/src/frontend/src/data/pkgs/Aspire.Hosting.Yarp.13.4.6.json
index 383715dc7..01effa73d 100644
--- a/src/frontend/src/data/pkgs/Aspire.Hosting.Yarp.13.4.6.json
+++ b/src/frontend/src/data/pkgs/Aspire.Hosting.Yarp.13.4.6.json
@@ -1205,7 +1205,7 @@
{
"name": "Aspire.Hosting.AspireExportIgnoreAttribute",
"arguments": {
- "Reason": "A single internal export with an optional sourcePath parameter provides the polyglot API without changing the public C# overloads."
+ "Reason": "A single internal export with an optional sourcePath parameter provides the non-C# API without changing the public C# overloads."
}
}
],
@@ -1265,7 +1265,7 @@
{
"name": "Aspire.Hosting.AspireExportIgnoreAttribute",
"arguments": {
- "Reason": "A single internal export with an optional sourcePath parameter provides the polyglot API without changing the public C# overloads."
+ "Reason": "A single internal export with an optional sourcePath parameter provides the non-C# API without changing the public C# overloads."
}
}
],