Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
38 changes: 26 additions & 12 deletions .agents/skills/doc-writer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ import InstallPackage from "@components/InstallPackage.astro";
import InstallDotNetPackage from "@components/InstallDotNetPackage.astro";
import AsciinemaPlayer from "@components/AsciinemaPlayer.astro";
import Badge from "@astrojs/starlight/components/Badge.astro";
import Image from "astro:assets";
import { Image } from "astro:assets";
```

### Component Usage
Expand Down Expand Up @@ -452,9 +452,10 @@ Aspire supports both **C# AppHosts** (`AppHost.cs`) and **TypeScript AppHosts**
### 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.
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.
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.
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

Expand Down Expand Up @@ -538,6 +539,8 @@ If a hosting integration does not yet have TypeScript AppHost support, show only

Do **not** wrap a single language in a single-language `<Tabs>` component — that creates a misleading UI suggesting another option exists.

Use this exception at the operation level, not as a shortcut for the whole page. If some APIs are exported to TypeScript and others are not, provide synchronized C# and TypeScript tabs for every supported operation and place the limitation beside only the unsupported operation.

## Integration Documentation

### File Location
Expand Down Expand Up @@ -569,7 +572,7 @@ description: Learn how to use the [Technology] integration with Aspire.

import { Aside, Tabs, TabItem } from "@astrojs/starlight/components";
import InstallPackage from "@components/InstallPackage.astro";
import Image from "astro:assets";
import { Image } from "astro:assets";

import techIcon from "@assets/icons/technology.svg";

Expand All @@ -578,6 +581,7 @@ import techIcon from "@assets/icons/technology.svg";
alt="Technology logo"
width={100}
height={100}
fit="contain"
style="float: left; margin-right: 1rem;"
data-zoom-off
/>
Expand Down Expand Up @@ -768,11 +772,14 @@ For collapsed sections with children:

### Update Integration Links

After adding integration documentation, run the update-integrations prompt to ensure the integration is indexed:
After adding or moving integration documentation:

```
.github/prompts/update-integrations.prompt.md
```
1. Run `pnpm --dir ./src/frontend update:integrations` when the package catalog
needs to be refreshed from NuGet.
2. Reconcile the exact package IDs and canonical documentation URLs in
`src/frontend/src/data/integration-docs.json`.
3. Run `pnpm --dir ./src/frontend test:unit:structured-data` to verify that the
mappings are unique and resolve to real pages.

## Writing Style Guidelines

Expand Down Expand Up @@ -822,14 +829,15 @@ Place icons in `src/frontend/src/assets/icons/`
### Icon Usage

```mdx
import Image from "astro:assets";
import { Image } from "astro:assets";
import techIcon from "@assets/icons/technology.svg";

<Image
src={techIcon}
alt="Technology logo"
width={100}
height={100}
fit="contain"
style="float: left; margin-right: 1rem;"
data-zoom-off
/>
Expand All @@ -841,14 +849,19 @@ For light/dark theme variants:
import ThemeImage from "@components/ThemeImage.astro";

<ThemeImage
lightSrc={techIconLight}
darkSrc={techIconDark}
light={techIconLight}
dark={techIconDark}
alt="Technology logo"
width={100}
height={100}
/>
```

When an integration logo sets both `width` and `height`, use `fit="contain"` so
Astro preserves the complete source artwork instead of cropping it to the
requested aspect ratio. `ThemeImage` applies contained fitting automatically.
Use `ThemeImage` whenever separate light and dark logo assets exist.

### Terminal Recordings (Asciinema)

For details on terminal recordings, including how to create and embed them, see the [terminal-recordings skill reference](./references/terminal-recordings.md).
Expand All @@ -863,6 +876,7 @@ Before submitting documentation:
4. **Review formatting**: Verify components render correctly
5. **Run relevant tests**: Do not consider documentation or component work done until the affected tests pass
6. **Check navigation**: Confirm sidebar entries are correct
7. **Check integration logos**: At desktop and mobile widths, verify the full logo is visible, uncropped, and legible in both light and dark themes

### Documentation Validation Strategy

Expand Down
12 changes: 9 additions & 3 deletions .agents/skills/update-integrations/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ If the Aspire release branch is not publicly reachable yet, set one of the overr
Fetch the latest package data from the configured package feeds:

```bash
cd src/frontend && node scripts/update-integrations.js
pnpm --dir ./src/frontend update:integrations
```

This writes updated package metadata to `src/frontend/src/data/aspire-integrations.json`. The script queries the NuGet v3 API for packages matching `owner:aspire`, `Aspire.Hosting.`, and `CommunityToolkit.Aspire`, then filters out deprecated, unlisted, and excluded packages.
Expand Down Expand Up @@ -118,7 +118,7 @@ The documentation site organizes integrations into these categories:

1. Match against existing similar package mappings in `integration-docs.json`
2. Infer from the package name and technology category
3. **Verify the page exists** — use Playwright MCP tools or check the file system under `src/frontend/src/content/docs/` to confirm the target page is real
3. **Verify the page exists** — check the file system under `src/frontend/src/content/docs/`, then use Playwright CLI to confirm the route renders
4. If no valid documentation page can be found, flag the package for manual review

### 5. Generate API reference data
Expand Down Expand Up @@ -223,14 +223,20 @@ Do not assume a page exists without verification.

Write the updated `integration-docs.json` maintaining consistent formatting (2-space indentation, trailing newline). The API reference JSON files in `src/frontend/src/data/pkgs/` are written directly by the generation script and require no additional save step.

Run the structured-data tests after changing the catalog or documentation map:

```bash
pnpm --dir ./src/frontend test:unit:structured-data
```

## Entry format

Each entry in `integration-docs.json` follows this structure:

```json
{
"match": "Aspire.Hosting.Redis",
"href": "/integrations/caching/redis/"
"href": "/integrations/caching/redis/redis-get-started/"
}
```

Expand Down
65 changes: 37 additions & 28 deletions .github/agents/community-toolkit-integration-doc-writer.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,32 @@ Documentation should match the style and format of existing documentation in the
- Should no integration be provided, do not continue, instead request the user to provide one.
- The Community Toolkit is found at https://github.com/CommunityToolkit/Aspire
- README files for integrations are in the `src` folder of the Community Toolkit repo, under the relevant integration subfolder (using the name of the integration, such as `CommunityToolkit.Aspire.Hosting.Ollama`, `CommunityToolkit.Aspire.Hosting.Rust`, `CommunityToolkit.Aspire.SurrealDB`, etc.).
- The README file of the integration should be used as the primary source of information for generating the documentation.
- Use the integration README as the starting point. Treat the extension methods,
resource types, settings classes, generated `api/*.cs` export artifact, and
tests as the authoritative sources for API and connection behavior.

## Creating a plan

1. Review the README file of the provided Community Toolkit integration.
1. Review the README and authoritative source files for the provided Community Toolkit integration.
2. Identify the correct subfolder in the `src/frontend/src/content/docs/integrations` folder based on the integration's category.
3. Review existing integration documentation from this repo such as:
- `src/frontend/src/content/docs/integrations/ai/ollama.mdx`
- `src/frontend/src/content/docs/integrations/databases/kurrentdb.mdx`
- `src/frontend/src/content/docs/integrations/frameworks/python.mdx`
- `src/frontend/src/content/docs/integrations/ai/ollama/ollama-get-started.mdx`
- `src/frontend/src/content/docs/integrations/ai/ollama/ollama-host.mdx`
- `src/frontend/src/content/docs/integrations/ai/ollama/ollama-connect.mdx`
- `src/frontend/src/content/docs/integrations/frameworks/rust.mdx`
4. Create a plan for generating the documentation that includes:
- The target subfolder for the documentation.
- The filename for the documentation file (should be the name of the integration in lowercase, with spaces replaced by hyphens, and a `.mdx` extension).
- The page shape:
- `get-started`, `host`, and `connect` for integrations with a meaningful consuming-app connection flow.
- `get-started` and `host` for host-only frameworks and tools.
- A focused single page for add-on extensions that decorate an official Aspire resource.
- The filenames and routes for every page in the selected shape.
- A breakdown of sections to include in the documentation, based on the README content and existing documentation style.
5. Implement the plan by creating the necessary directories and files, and writing the documentation content in Astro format.

## Update the sidebar navigation

After creating the documentation file, update `src/frontend/config/sidebar/sidebar.topics.ts` to add the new integration to the appropriate category section:
After creating the documentation, update `src/frontend/config/sidebar/integrations.topics.ts` to add the integration to the appropriate category section:

1. Locate the relevant integration category section in the sidebar (e.g., "Frameworks & runtimes", "Data & databases", "Caching & state", etc.)
2. Add a new entry to the `items` array for that category:
Expand All @@ -81,11 +87,9 @@ Example entry:

After completing all documentation writing and sidebar updates:

1. Execute the "Update Integration Documentation Links" prompt located at `.github/prompts/update-integrations.prompt.md`
2. This prompt will:
- Synchronize package names from the NuGet catalog with their corresponding documentation URLs
- Update `src/frontend/src/data/integration-docs.json` with mappings for the newly created documentation
- Ensure the new integration is discoverable through the integration gallery and search
1. Run `pnpm --dir ./src/frontend update:integrations` if the NuGet package catalog needs to be refreshed.
2. Reconcile each exact package ID with its canonical page in `src/frontend/src/data/integration-docs.json`.
3. Run `pnpm --dir ./src/frontend test:unit:structured-data`.

This step ensures that the documentation you've created is properly indexed and linked in the Aspire documentation site.

Expand All @@ -94,7 +98,7 @@ This step ensures that the documentation you've created is properly indexed and
### Frontmatter

- **Title**: Should be concise and include "integration" (e.g., "Python integration", "Ollama integration")
- **Description**: A brief summary of what the integration does and its purpose. Required for all docs except framework integrations.
- **Description**: A brief summary of what the integration does and its purpose. Required for every English documentation page.
- For hosting integrations: Describe what the integration orchestrates/configures
- For client integrations: Describe what the client connects to and its purpose
- For combined integrations: Describe both aspects
Expand All @@ -119,26 +123,23 @@ This step ensures that the documentation you've created is properly indexed and

### Structure and sections

#### For hosting-only integrations (e.g., Rust, Python):
#### For host-only integrations:

1. **Introduction paragraph**: Brief description of what the integration is and what it enables
2. **Prerequisites** (if any): Use an `Aside` with type="note" for requirements like installed tools
3. **Hosting integration section**:
- Package installation with `InstallPackage`
- "Add [Technology] resource" subsection with basic example
- Configuration subsections (endpoints, arguments, volumes, bind mounts, etc.)
- Working directory explanation if relevant
4. **See also section**: Links to official docs, Community Toolkit repo, and related Aspire resources
1. Create a **get-started page** with the introduction, benefits, architecture, prerequisites, a short AppHost setup flow, and related links.
2. Create a **host page** with package installation, the basic resource example, configuration options, health behavior, and the complete exported AppHost API surface.
3. Do not create an empty or "not applicable" connect page.

#### For hosting + client integrations (e.g., Ollama, KurrentDB):
#### For connection-capable integrations:

1. **Introduction paragraph**: Brief description with link to the technology's website
2. **Hosting integration section**:
1. Create a **get-started page** with the introduction, benefits, architecture, and links to the host and connect flows.
2. Create a **host page** with:
- Package installation with `InstallPackage`
- "Add [Technology] resource" subsection
- Configuration subsections (volumes, bind mounts, parameters, etc.)
- "Hosting integration health checks" subsection (if applicable)
3. **Client integration section**:
- A connection-property summary that links to the connect page
3. Create a **connect page** with:
- The exact connection string and connection properties exposed by the resource
- Package installation with `InstallDotNetPackage`
- "Add [Technology] client" subsection
- "Add keyed [Technology] client" subsection (if supported)
Expand All @@ -149,12 +150,20 @@ This step ensures that the documentation you've created is properly indexed and
- Inline delegates
- "Client integration health checks" subsection (if applicable)
- "Observability and telemetry" subsection (if applicable) with logging and tracing details
4. **See also section**
- C#, TypeScript, Python, and Go examples when stable clients exist
4. Add a **See also** section to each page where it helps navigation.

#### For add-on extensions:

Keep a focused single page adjacent to the official integration it extends.
Document the official base resource, package installation, the added
`With...` APIs, C# and TypeScript examples when exported, and any tool-specific
prerequisites. Do not present the add-on as a standalone service.

### Code blocks

- Use proper syntax highlighting: `csharp`, `json`, `sql`, etc.
- Include descriptive titles: `title="C# — AppHost.cs"`, `title="JSON — appsettings.json"`
- Include descriptive titles: `title="AppHost.cs"`, `title="apphost.mts"`, `title="appsettings.json"`
- For C# code in AppHost, always end with `// After adding all resources, run the app...` comment
- Show complete, runnable examples
- Use proper formatting and indentation
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/components/ThemeImage.astro
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const {
const imageWidth = width ?? dark.width;
const imageHeight = height ?? dark.height;
const imageClass = [classOverride, 'theme-image'].filter(Boolean).join(' ');
const imageOptions = { width: imageWidth, height: imageHeight };
const imageOptions = { width: imageWidth, height: imageHeight, fit: 'contain' as const };
const optimizedLight = await getImage({ src: light, ...imageOptions });
const optimizedDark = await getImage({ src: dark, ...imageOptions });
const themedImageProps = {
Expand All @@ -41,6 +41,7 @@ const themedImageProps = {
'data-dark-srcset': optimizedDark.srcSet.attribute,
width: imageWidth,
height: imageHeight,
fit: 'contain' as const,
decoding: 'async' as const,
loading: 'lazy' as const,
};
Expand Down
Loading
Loading