Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 59 additions & 59 deletions .agents/skills/doc-writer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,17 +290,17 @@ When a page shows the **On this page** table of contents (the default behavior u

If your opening section is truly introductory, keep it as body copy without an `Overview` heading. If that section has a more specific purpose, use a descriptive heading such as `Key concepts`, `Prerequisites`, or another topic-specific label.

For Aspire AppHost code examples, use synced `Tabs` / `TabItem` blocks with `syncKey='aspire-lang'` at each code snippet. Do **not** add a page-level `PivotSelector` just to switch AppHost code samples between C# and TypeScript. Readers should be able to switch the language at the specific snippet they are reading.
For Aspire AppHost code examples, use synced `Tabs` / `TabItem` blocks with `syncKey='aspire-lang'` at each code snippet. List TypeScript first so `apphost.mts` is the default experience for readers without a saved preference. Do **not** add a page-level `PivotSelector` just to switch AppHost code samples between TypeScript and C#. Readers should be able to switch the language at the specific snippet they are reading.

```mdx
<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>
C# example content here.
</TabItem>

<TabItem id='typescript' label='TypeScript'>
TypeScript example content here.
</TabItem>

<TabItem id='csharp' label='C#'>
C# example content here.
</TabItem>
</Tabs>
```

Expand Down Expand Up @@ -445,40 +445,26 @@ For client/library packages:
<InstallDotNetPackage package="Aspire.StackExchange.Redis" />
```

## AppHost Language Parity (C# and TypeScript)
## AppHost Language Parity (TypeScript and C#)

Aspire supports both **C# AppHosts** (`AppHost.cs`) and **TypeScript AppHosts** (`apphost.mts`). Documentation must treat both languages as first-class citizens. **Always show both C# and TypeScript code samples for AppHost code unless the feature is genuinely language-specific or TypeScript support does not exist yet.** Never write AppHost or hosting-integration documentation with a C#-only bias.
Aspire supports both **TypeScript AppHosts** (`apphost.mts`) and **C# AppHosts** (`AppHost.cs`). Documentation must treat both languages as first-class citizens. **Always show both TypeScript and C# code samples for AppHost code unless the feature is genuinely language-specific or TypeScript support does not exist yet.** Never write AppHost or hosting-integration documentation with a C#-only bias.

### Core Principles

1. **Always show both languages**: Every AppHost-focused example, walkthrough, and AppHost code sample must include both C# and TypeScript variants unless the feature is genuinely language-specific.
1. **Always show both languages**: Every AppHost-focused example, walkthrough, and AppHost code sample must include both TypeScript and C# variants unless the feature is genuinely language-specific.
2. **Show implementations, not availability notes**: When a TypeScript AppHost API exists, demonstrate it in a complete TypeScript tab beside the C# example. A note or callout that only names the available TypeScript methods does not satisfy language parity.
3. **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()`".
4. **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. **Default to TypeScript**: Put the TypeScript tab first so `apphost.mts` is on the left and selected for readers without a saved preference. Keep C# as an equal peer and preserve the reader's explicit language selection.
5. **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.

### AppHost tabs pattern for AppHost content

Use synced `Tabs` for AppHost-specific content that changes between C# and TypeScript. Each AppHost code snippet should provide its own language tabs and use `syncKey='aspire-lang'` so the user's language choice stays synchronized across snippets on the page.
Use synced `Tabs` for AppHost-specific content that changes between TypeScript and C#. Each AppHost code snippet should provide its own language tabs, list TypeScript first, and use `syncKey='aspire-lang'` so the user's language choice stays synchronized across snippets on the page.

````mdx
import { Tabs, TabItem } from "@astrojs/starlight/components";

<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

builder.AddProject<Projects.Api>("api")
.WithReference(cache);

builder.Build().Run();
```

</TabItem>
<TabItem id='typescript' label='TypeScript'>

```typescript title="apphost.mts"
Expand All @@ -494,6 +480,20 @@ await api.withReference(cache);
await builder.build().run();
```

</TabItem>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache");

builder.AddProject<Projects.Api>("api")
.WithReference(cache);

builder.Build().Run();
```

</TabItem>
</Tabs>
````
Expand All @@ -506,15 +506,15 @@ If a section heading should appear in the **On this page** table of contents, ke

### Conventions

| Aspect | C# | TypeScript |
| ---------------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| File title | `title="AppHost.cs"` | `title="apphost.mts"` |
| Tab wrapper | Shared `<Tabs syncKey='aspire-lang'>` container | Shared `<Tabs syncKey='aspire-lang'>` container |
| Tab item | `<TabItem id='csharp' label='C#'>` | `<TabItem id='typescript' label='TypeScript'>` |
| Builder creation | `DistributedApplication.CreateBuilder(args)` | `import { createBuilder } from './.aspire/modules/aspire.mjs';` then newline for space followed by `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()` |
| Aspect | TypeScript | C# |
| ---------------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| File title | `title="apphost.mts"` | `title="AppHost.cs"` |
| Tab wrapper | Shared `<Tabs syncKey='aspire-lang'>` container | Shared `<Tabs syncKey='aspire-lang'>` container |
| Tab item | `<TabItem id='typescript' label='TypeScript'>` | `<TabItem id='csharp' label='C#'>` |
| Builder creation | `import { createBuilder } from './.aspire/modules/aspire.mjs';` then newline for space followed by `await createBuilder();` | `DistributedApplication.CreateBuilder(args)` |
| Method casing | camelCase (`addRedis`) | PascalCase (`AddRedis`) |
| Async pattern | `await` each builder call | Synchronous fluent calls |
| Build & run | `await builder.build().run()` | `builder.Build().Run()` |

### Prose Guidelines

Expand Down Expand Up @@ -595,18 +595,6 @@ Brief description of the technology and what the integration enables.
### Add [Technology] resource

<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var tech = builder.AddTechnology("tech");

// After adding all resources, run the app...
builder.Build().Run();
```

</TabItem>
<TabItem id='typescript' label='TypeScript'>

```typescript title="apphost.mts"
Expand All @@ -619,6 +607,18 @@ const tech = await builder.addTechnology("tech");
await builder.build().run();
```

</TabItem>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var tech = builder.AddTechnology("tech");

// After adding all resources, run the app...
builder.Build().Run();
```

</TabItem>
</Tabs>

Expand All @@ -644,20 +644,6 @@ Include both hosting and client sections:
### Add [Technology] resource

<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var tech = builder.AddTechnology("tech");

builder.AddProject<Projects.Api>("api")
.WithReference(tech);

builder.Build().Run();
```

</TabItem>
<TabItem id='typescript' label='TypeScript'>

```typescript title="apphost.mts"
Expand All @@ -673,6 +659,20 @@ await api.withReference(tech);
await builder.build().run();
```

</TabItem>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);

var tech = builder.AddTechnology("tech");

builder.AddProject<Projects.Api>("api")
.WithReference(tech);

builder.Build().Run();
```

</TabItem>
</Tabs>

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/whatsnew/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ infer from context — e.g. a fresh release with no page → `draft`).
| What | Path |
|------|------|
| What's-new pages | `src/frontend/src/content/docs/whats-new/aspire-N-N.mdx` (JA under `.../ja/whats-new/`) |
| Version constants | `src/frontend/config/aspire-versions.mjs` (`currentAspireMajorMinorVersion`, `currentAspireVersion`) |
| Version constants | `src/frontend/config/aspire-versions.mjs` (`currentAspireMajorMinorVersion`, `currentAspireVersion`, `currentAspirePreviewVersion`) |
| Sidebar | `src/frontend/config/sidebar/docs.topics.ts` (What's-new `items`) |
| Announcement banner | `banner:` frontmatter on `src/frontend/src/content/docs/index.mdx`, `src/frontend/src/content/docs/docs.mdx`, `src/frontend/src/content/docs/community/index.mdx`, and each `src/frontend/src/content/docs/{locale}/index.mdx` (+ `.../ja/docs.mdx`); rendered by `src/frontend/src/components/starlight/Banner.astro` |
| Assets | `src/frontend/src/assets/whats-new/aspire-<version>/` |
Expand Down
7 changes: 5 additions & 2 deletions .agents/skills/whatsnew/references/01-draft-scaffold.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ duplicating.
dedicated **"New integrations"** and **"Default container image updates"** sections.
If the file already exists, reconcile structure without clobbering existing content.
3. **Version constants.** Update `src/frontend/config/aspire-versions.mjs`:
`currentAspireMajorMinorVersion = 'N.N'` and `currentAspireVersion = 'N.N.0'` (only
when N.N is the new current release). This drives the `%ASPIRE_VERSION%` remark
`currentAspireMajorMinorVersion = 'N.N'`, `currentAspireVersion` to the latest
stable `N.N.PATCH`, and `currentAspirePreviewVersion` to the matching full
`N.N.PATCH-preview.*` package version. Set both package versions to the initial
release patch when N.N becomes current, then keep them aligned with the site
AppHost during servicing updates. These drive the Aspire version remark
placeholders site-wide.
4. **Site-wide announcement banner.** The banner is **per-page frontmatter**, not a
global config. Update the `banner.content` string **and its link** to point at
Expand Down
4 changes: 2 additions & 2 deletions .agents/skills/whatsnew/references/02-research.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ This is the phase that turns the skeleton into a real, reviewable page.
the section (next step).
7. **Author the draft.** Populate the scaffolded MDX from the dossier: write the lede,
the "This release introduces" bullets (1:1 with the `##` sections, same order), and
each section body with impact-first prose, `LearnMore` deep-links, and C#/TypeScript
`<Tabs syncKey='aspire-lang'>` where a feature spans AppHost languages. Credit each
each section body with impact-first prose, `LearnMore` deep-links, and TypeScript/C#
`<Tabs syncKey='aspire-lang'>` with TypeScript first where a feature spans AppHost languages. Credit each
merged community PR by `@handle`. **Only include sections that apply** — delete any
standard section with no content. In particular, when the release has **no breaking
changes**, remove the "⚠️ Breaking changes" section *and* the breaking-changes
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/whatsnew/references/03-critique.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ actionable, severity-ranked findings report. **Makes no edits** — {polish} act
- `<Aside>` used **judiciously** (not eye-burning). Breaking-changes caution present
**only** when the release has breaking changes — when it has none, both the caution
*and* the "⚠️ Breaking changes" section are omitted (no empty section left behind).
- C#/TypeScript **tab parity** (`syncKey='aspire-lang'`) wherever a feature spans AppHost languages.
- TypeScript/C# **tab parity** (`syncKey='aspire-lang'`, TypeScript first) wherever a feature spans AppHost languages.
- `publishDate` frontmatter set (the `Released MMMM D, YYYY` badge + GitHub release-notes link auto-render; no hand-placed header).

**Content standards (mandated)**
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/whatsnew/references/05-polish.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ lands *after* the `{validate}` gate and must not ship unchecked.
- Tighten to **KISS**; smooth flow and voice per the `doc-writer` skill; dedupe.
- Confirm the "This release introduces" bullets map **1:1** to sections (same order).
- Right-size `<Aside>` usage (judicious — don't burn the reader's eyes).
- C#/TypeScript **tab parity** (`syncKey='aspire-lang'`) complete and correct.
- TypeScript/C# **tab parity** (`syncKey='aspire-lang'`, TypeScript first) complete and correct.
- Reconcile **"✨ New integrations"**, **"📦 Integration updates"**, and **"🐳 Default
container image updates"** against the freshly regenerated data (below).
- Finalize **contributor thanks** (`@handle` + one-line note per merged community PR).
Expand Down
3 changes: 2 additions & 1 deletion .agents/skills/whatsnew/references/whats-new-template.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# them at build once this is the current release — see config/aspire-versions.mjs):
# %ASPIRE_VERSION_MAJOR_MINOR% → currentAspireMajorMinorVersion
# %ASPIRE_VERSION% → currentAspireVersion
# %ASPIRE_VERSION_PREVIEW% → currentAspirePreviewVersion
#
# Delete this comment block when scaffolding. Keep it STRUCTURE ONLY: headings +
# placeholders, no researched prose. Content lands in {research}/{polish}.
Expand Down Expand Up @@ -105,7 +106,7 @@ The easiest way to upgrade to Aspire {{VERSION_MAJOR_MINOR}} is using the [`aspi
sections. Order sections by customer impact / DX. Add feature-specific
sections (e.g. "🌐 TypeScript AppHost", "🧱 Go and Bun") near the top when
they are the headline. Remove any standard section that doesn't apply.
Use <Tabs syncKey='aspire-lang'> for C#/TypeScript parity, `LearnMore` to
Use <Tabs syncKey='aspire-lang'> with TypeScript first for TypeScript/C# parity, `LearnMore` to
deep-link, and <Aside> sparingly for genuinely important call-outs.
───────────────────────────────────────────────────────────────────────── */}

Expand Down
3 changes: 2 additions & 1 deletion .agents/skills/whatsnew/references/writing-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ These are the specific quality gates critique/validate enforce:
Go) rather than defining any of them in opposition to another.
- **Second person, active voice, imperative mood.** Concise, professional-approachable.
- **Dates spelled out:** "August 18, 2025" — never "8/18/25".
- **C#/TypeScript parity:** when a feature spans AppHost languages, show both with
- **TypeScript/C# parity:** when a feature spans AppHost languages, show both with
`<Tabs syncKey='aspire-lang'>` / `<TabItem>` so the tab choice syncs page-wide.
Put TypeScript first so `apphost.mts` is the default for readers without a saved preference.
- **Version tokens:** in prose for the *current* release you may use the build-time
placeholders `%ASPIRE_VERSION%` / `%ASPIRE_VERSION_MAJOR_MINOR%` (replaced by the
remark plugin). The article slug, sidebar, and header use the literal version.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ This step ensures that the documentation you've created is properly indexed and

- Import `Badge` from '@astrojs/starlight/components' and add `<Badge text="⭐ Community Toolkit" variant="tip" size="large" />` at the top
- Import and use the `Aside` component for notes, tips, cautions, and warnings
- Import and use synced `Tabs` and `TabItem` from `@astrojs/starlight/components` for AppHost examples when both C# and TypeScript AppHost APIs are available. Use `syncKey='aspire-lang'` and tab IDs `csharp` and `typescript`.
- Import and use synced `Tabs` and `TabItem` from `@astrojs/starlight/components` for AppHost examples when both TypeScript and C# AppHost APIs are available. Put the `typescript` tab first, followed by `csharp`, and use `syncKey='aspire-lang'`.
- Import and use `InstallPackage` for hosting packages
- Import and use `InstallDotNetPackage` for client packages
- Import `Image` from 'astro:assets' for icons
Expand Down Expand Up @@ -171,7 +171,7 @@ prerequisites. Do not present the add-on as a standalone service.
### AppHost language parity

- Follow the `doc-writer` skill's AppHost language parity guidance for all AppHost and hosting-integration examples.
- Always show both C# AppHost (`AppHost.cs`) and TypeScript AppHost (`apphost.mts`) variants inside synced `Tabs` (with `syncKey='aspire-lang'`) unless the feature is genuinely language-specific or TypeScript AppHost support does not exist yet.
- Always show both TypeScript AppHost (`apphost.mts`) and C# AppHost (`AppHost.cs`) variants inside synced `Tabs` (with `syncKey='aspire-lang'`) unless the feature is genuinely language-specific or TypeScript AppHost support does not exist yet. Put TypeScript first so it is the default.
- Before writing a TypeScript AppHost example, verify the API exists in the TypeScript AppHost SDK. Do not invent TypeScript samples.
- If TypeScript AppHost support is not available, show only the C# example without language tabs and add a note that TypeScript AppHost support for the integration is not yet available.
- Use language-neutral prose around AppHost examples, such as "Add a resource to your AppHost" instead of C#-specific method instructions.
Expand Down
Loading
Loading