From da5dd4b33b2a9045f40b7464f0b054fc45f2eab3 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 25 Mar 2026 17:55:17 -0700 Subject: [PATCH 1/4] Add TypeScript AppHost parity guidance to doc-writer skill - Add 'AppHost Language Parity' section with core principles for treating C# and TypeScript as equal first-class citizens - Document the standard tab pattern (syncKey=apphost-lang) with conventions table for method casing, async patterns, file titles - Provide prose guidelines to avoid C#-biased language - Add guidance for when TypeScript is not yet supported - Update hosting-only and hosting+client integration templates to include both C# and TypeScript code examples - Update code block examples to show both languages Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/skills/doc-writer/SKILL.md | 157 ++++++++++++++++++++++++++++- 1 file changed, 153 insertions(+), 4 deletions(-) diff --git a/.github/skills/doc-writer/SKILL.md b/.github/skills/doc-writer/SKILL.md index f7751181b..989ebe8f9 100644 --- a/.github/skills/doc-writer/SKILL.md +++ b/.github/skills/doc-writer/SKILL.md @@ -258,7 +258,7 @@ For more information, see [aspire config command reference](/reference/cli/comma Always include a descriptive title: ```mdx -```csharp title="C# — AppHost.cs" +```csharp title="AppHost.cs" var builder = DistributedApplication.CreateBuilder(args); var api = builder.AddProject("api"); @@ -268,6 +268,18 @@ builder.Build().Run(); ``` ``` +```mdx +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const api = await builder.addProject("api", "../Api/Api.csproj"); + +await builder.build().run(); +``` +``` + For JSON configuration: ```mdx @@ -294,6 +306,93 @@ For client/library packages: ``` +## AppHost Language Parity (C# and TypeScript) + +Aspire supports both **C# AppHosts** (`AppHost.cs`) and **TypeScript AppHosts** (`apphost.ts`). Documentation must treat both languages as first-class citizens. Never write AppHost or hosting-integration documentation with a C#-only bias. + +### Core Principles + +1. **Always show both languages**: Every AppHost code example must include both C# and TypeScript variants unless the feature is genuinely language-specific. +2. **Use neutral framing**: Write prose that applies to both languages. Say "In your AppHost" not "In your C# project". Say "Add a Redis resource" not "Call `builder.AddRedis()`". +3. **Neither language is the default**: Don't present C# first as the "real" example and TypeScript as an afterthought. Both tabs are equal peers. +4. **Verify TypeScript APIs exist**: Before writing a TypeScript example, confirm the API exists in the TypeScript AppHost SDK. Do not invent TypeScript samples — if you are unsure whether an API is available, flag it for review. + +### Tab Pattern for AppHost Code + +Use `` so the reader's language choice persists across the page and across pages: + +```mdx +import { Tabs, TabItem } from '@astrojs/starlight/components'; + + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var cache = builder.AddRedis("cache"); + +builder.AddProject("api") + .WithReference(cache); + +builder.Build().Run(); +``` + + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const cache = await builder.addRedis("cache"); + +await builder.addProject("api", "../Api/Api.csproj") + .withReference(cache); + +await builder.build().run(); +``` + + + +``` + +### Conventions + +| Aspect | C# | TypeScript | +|---|---|---| +| File title | `title="AppHost.cs"` | `title="apphost.ts"` | +| Tab label | `C#` | `TypeScript` | +| Sync key | `apphost-lang` | `apphost-lang` | +| Builder creation | `DistributedApplication.CreateBuilder(args)` | `await createBuilder()` | +| Method casing | PascalCase (`AddRedis`) | camelCase (`addRedis`) | +| Async pattern | Synchronous fluent calls | `await` each builder call | +| Build & run | `builder.Build().Run()` | `await builder.build().run()` | + +### Prose Guidelines + +When writing narrative text around AppHost examples: + +- ✅ "Add a Redis resource to your AppHost" +- ✅ "The following example shows how to configure a PostgreSQL resource" +- ❌ "Call `builder.AddRedis()` in your _Program.cs_" (C#-specific) +- ❌ "Add the following C# code to your AppHost" (when both languages should be shown) + +When a concept differs between languages (e.g., configuration files, async patterns), explain both within the tabs or in language-neutral prose above the tabs. + +### When TypeScript Is Not Yet Supported + +If a hosting integration does not yet have TypeScript AppHost support, show only the C# example **without tabs** and add a note: + +```mdx + +``` + +Do **not** wrap a single language in a `` component — that creates a misleading UI suggesting another option exists. + ## Integration Documentation ### File Location @@ -323,7 +422,7 @@ title: [Technology] integration description: Learn how to use the [Technology] integration with Aspire. --- -import { Aside } from '@astrojs/starlight/components'; +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; import InstallPackage from '@components/InstallPackage.astro'; import Image from 'astro:assets'; @@ -339,7 +438,10 @@ Brief description of the technology and what the integration enables. ### Add [Technology] resource -```csharp title="C# — AppHost.cs" + + + +```csharp title="AppHost.cs" var builder = DistributedApplication.CreateBuilder(args); var tech = builder.AddTechnology("tech"); @@ -348,6 +450,22 @@ var tech = builder.AddTechnology("tech"); builder.Build().Run(); ``` + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const tech = await builder.addTechnology("tech"); + +await builder.build().run(); +``` + + + + ### Configuration options Describe available configuration methods and options. @@ -369,7 +487,38 @@ Include both hosting and client sections: ### Add [Technology] resource -[Hosting examples...] + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var tech = builder.AddTechnology("tech"); + +builder.AddProject("api") + .WithReference(tech); + +builder.Build().Run(); +``` + + + + +```typescript title="apphost.ts" +import { createBuilder } from './.modules/aspire.js'; + +const builder = await createBuilder(); + +const tech = await builder.addTechnology("tech"); + +await builder.addProject("api", "../Api/Api.csproj") + .withReference(tech); + +await builder.build().run(); +``` + + + ### Hosting integration health checks From 5576f18d9df73ad797229cfb4be56c9bf4962e83 Mon Sep 17 00:00:00 2001 From: David Fowler Date: Wed, 25 Mar 2026 22:59:39 -0700 Subject: [PATCH 2/4] Fix TypeScript async chaining in AppHost examples Separate await calls for addProject and withReference to match the documented 'await each builder call' convention. Previously the samples chained .withReference() on an unawaited promise. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/skills/doc-writer/SKILL.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/skills/doc-writer/SKILL.md b/.github/skills/doc-writer/SKILL.md index 989ebe8f9..fe0295ee3 100644 --- a/.github/skills/doc-writer/SKILL.md +++ b/.github/skills/doc-writer/SKILL.md @@ -348,8 +348,8 @@ const builder = await createBuilder(); const cache = await builder.addRedis("cache"); -await builder.addProject("api", "../Api/Api.csproj") - .withReference(cache); +const api = await builder.addProject("api", "../Api/Api.csproj"); +await api.withReference(cache); await builder.build().run(); ``` @@ -511,8 +511,8 @@ const builder = await createBuilder(); const tech = await builder.addTechnology("tech"); -await builder.addProject("api", "../Api/Api.csproj") - .withReference(tech); +const api = await builder.addProject("api", "../Api/Api.csproj"); +await api.withReference(tech); await builder.build().run(); ``` From 8a2da8154d99ba365e1aefbf39a91ff934fb572e Mon Sep 17 00:00:00 2001 From: David Pine Date: Thu, 26 Mar 2026 15:26:52 -0500 Subject: [PATCH 3/4] Fix markdown formatting in SKILL.md --- .github/skills/doc-writer/SKILL.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/skills/doc-writer/SKILL.md b/.github/skills/doc-writer/SKILL.md index fe0295ee3..11a8b23e7 100644 --- a/.github/skills/doc-writer/SKILL.md +++ b/.github/skills/doc-writer/SKILL.md @@ -239,7 +239,7 @@ For more information, see [Service Defaults](/fundamentals/service-defaults/). The component renders an open-book icon alongside the provided content. Place it after a section or code example to point readers to deeper documentation. It works well inside `