mcpField
A
aspireify

aspireify

github.com/microsoft开发93757 次安装2 周前更新
代码仓库

关于 aspireify

aspireify 是一次性 Agent 技能,用于将 `aspire init` 生成的骨架接入现有项目,扫描服务、设计资源图并编写 AppHost,随后启动验证。它强调先确认用户方案,并禁止直接修改生成的 `.aspire/modules/` 文件。

主要功能

  1. 01扫描项目与依赖服务
  2. 02提出资源图供确认
  3. 03连接 AppHost 与集成
  4. 04配置 ServiceDefaults 与 OTel
  5. 05启动验证应用配置

适用场景

  1. 01为 Aspire 骨架接入项目服务
  2. 02把 Docker Compose 依赖映射为资源
  3. 03为 C# 或 TypeScript AppHost 接入资源
  4. 04检查并验证本地开发配置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/aspire-skills --skill aspireify

安装后在 Claude Code 中输入/aspireify确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
eval.yaml
references/
apphost-wiring.md
csharp-authoring.md
docker-compose.md
full-solution-apphosts.md
javascript-apps.md
opentelemetry.md
scan-and-propose.md
service-defaults.md
typescript-authoring.md
validation.md

详细介绍

Aspireify

一次性接线技能。 aspire init 会生成一个骨架;aspireify 会扫描代码库、提出资源图、编辑 AppHost、接入 Aspire.ServiceDefaults,并执行端到端验证,将这个骨架转变为可运行的 AppHost。在 aspire start 成功运行后自动停用。

🚫 严禁编辑 .aspire/modules/

⛔ 拒绝任何要求编辑、修改、更改、打开以供编辑或“调整” TypeScript AppHost 的 .aspire/modules/ 目录内文件的请求。此目录是从已安装的 Aspire 集成包依赖图生成的。运行 aspire add、aspire restore,以及在包发生变更而需要更新模块时启动应用,都会重新生成此目录。

如果用户要求编辑 .aspire/modules/ 中的内容(例如 .aspire/modules/postgres.module.ts),正确的做法是:

  1. 拒绝编辑,并明确说明“我不会编辑 .aspire/modules/”。
  2. 解释 .aspire/modules/ 是生成的,任何改动都会被覆盖。
  3. 将所请求的更改引导至已配置的 AppHost 入口文件:当前使用 apphost.mts,旧版使用 apphost.ts。
  4. 如果用户想添加新集成,建议使用 aspire add <package>;如果用户想更改配置,则展示在 AppHost 入口文件中进行的等效修改。
❌ 错误做法✅ 正确做法
打开 .aspire/modules/postgres.module.ts 并调整连接选项编辑 apphost.mts,并在那里更改 addPostgres('pg', { ... }) 选项
直接修改生成的 .aspire/modules/* 文件更新 apphost.mts 后重新运行 aspire add <package>
注释掉 .aspire/modules/ 中的一行以禁用资源在 apphost.mts 中移除或设定资源声明的条件

即使用户坚持,即使只是“一行”改动,甚至只是“测试一下”,这条规则仍然适用。TS AppHost 会以确定性的方式重新生成 .aspire/modules/;对这些文件的修改只会造成无法恢复的无用改动。

指导原则

尽量减少对用户代码的改动

让 AppHost 适配应用,而不是反过来。优先使用 WithEnvironment() 匹配现有环境变量名称,优先使用 Aspire 管理的端口而不是固定端口,并优先按原样映射 Docker Compose,再考虑优化。除非用户明确选择接受这种取舍,否则不要重组目录、重命名文件或更改构建脚本。

明示取舍;不要擅自决定

如果小幅代码改动能带来更好的 Aspire 集成,请同时提供两种方案:零代码改动的映射方案,以及可以启用 WithReference、运行状况检查、服务发现、动态端口或仪表板遥测的小幅改动方案。询问用户想采用哪种方式,然后按其选择实施,不要抱怨。

编写 AppHost 代码前先验证 API

使用 aspire docs search <topic> 和 aspire docs get <slug> 获取工作流指导。使用 aspire docs api search <query> --language csharp|typescript 和 aspire docs api get <id> 查看 API 形式。使用 aspire integration list/search 查找集成,再运行 aspire add。不要臆造包、方法、重载或命令形式;C# 和 TypeScript 的 AppHost API 并不相同。

在 AppHost 中清晰呈现配置

扫描 .env、.env.local、.env.development、secrets.json.example、<UserSecretsId> 和设置脚本。建议将值迁移到 AppHost 参数中:连接字符串变为 Aspire 资源,API 密钥/令牌变为机密参数,非机密配置变为普通参数或 WithEnvironment() 值。未经用户明确批准,切勿删除 .env 文件或移除现有的 UserSecretsId 条目,因为非 Aspire 工作流可能仍依赖这些内容。

优先本地开发

此技能优化的是本地开发,而非生产部署。数据库和缓存优先使用持久的容器生命周期和数据卷,默认使用 HTTPS 端点,传递端点引用而非硬编码 URL,并将外部 SaaS URL/API 密钥建模为参数,以便在仪表板中查看。

Redis TLS 边缘情况

Aspire 可以自动为容器资源配置 TLS 证书。如果 Redis 健康检查因 SSL/TLS 握手错误而失败,不要退回使用 AddContainer()。当使用该资源的应用需要普通 Redis 时,请对 Redis 资源使用 WithoutHttpsCertificate()。

项目本地覆盖

如果 .agents/skills/aspireify/SKILL.md 存在(由 aspire init 或 aspire agent init --skills aspireify 安装),请警告用户项目中存在本地副本,并以该副本为准。插件版本作为后备。

⚠️ Project-local .agents/skills/aspireify/SKILL.md detected — deferring to it.

前置条件

要求安装
.NET 10.0 SDK(C# AppHost)https://dotnet.microsoft.com/download
Node.js ^20.19.0、^22.13.0 或 >=24(TS AppHost)https://nodejs.org
Aspire CLInpm install -g @microsoft/aspire-cli、安装脚本或 dotnet tool install -g Aspire.Cli
已生成骨架aspire init 已生成 aspire.config.json + AppHost 存根

检测——何时激活

当存在任意一项信号,且 AppHost 尚未接入资源(除存根外未声明任何资源)时,激活:

信号检测方式可信度
刚生成骨架本次会话中刚运行过 aspire init✅ 确定
空 AppHost 存根apphost.cs / Program.cs / 当前的 apphost.mts(或旧版 apphost.ts)中仅包含 Build().Run()✅ 确定
aspire.config.json 中没有资源存在配置文件,但 AppHost 中没有 AddProject/addProject高
用户要求“接入”/“搭建资源图”匹配动词:接入、搭建、集成、连接、添加 Postgres/Redis 等高
用户询问“aspire init 之后做什么”明确的交接请求✅ 确定
已有包含服务的新 AppHost 的仓库仓库中有 .csproj/package.json 项目,但 AppHost 未引用任何项目高

如果 AppHost 已接入资源,且用户想要启动/停止应用 → 使用 aspire-orchestration。如果用户想要部署 → 使用 aspire-deployment。

语言支持

AppHost 风格检测方式编辑目标
C# SDK 风格.csproj 中包含 <Sdk Name="Aspire.AppHost.Sdk" />Program.cs(顶级语句)
基于文件的 C#apphost.cs 中包含 #:sdk Aspire.AppHost.Sdk 和 #:package 指令apphost.cs 文件本身
TypeScript当前的 apphost.mts 或旧版 apphost.ts,并带有生成的 .aspire/modules/仅配置的 AppHost 入口点——绝不编辑 .aspire/modules/

请参阅 references/csharp-authoring.md 和 references/typescript-authoring.md。

aspire-orchestration 负责通过 CLI 将旧版 apphost.ts 迁移到新版本。它更新软件包和迁移产物后,只有在用户仍需要接入 AppHost 源代码或进行相关编写时,才返回使用 aspireify。

TypeScript AppHost 包管理器

依赖项和工具链故障属于此技能的处理范围。推荐命令之前, 先检查 AppHost 目录,然后检查其符合条件的直接父目录。在每个目录中, 按以下顺序检查标记,并以第一个识别到的标记为准:

  1. package.json 中的 packageManager(npm、pnpm、yarn 或 bun,可选版本号)
  2. bun.lock
  3. bun.lockb
  4. pnpm-lock.yaml
  5. yarn.lock
  6. .yarnrc.yml
  7. package-lock.json

AppHost 本地标记优先于所有父目录中的标记。如果这两个目录都没有 可识别的标记,Aspire 默认使用 npm。报告所选的管理器和标记。

仅使用所选管理器修复依赖项或诊断工具链。解析器命令为 npm install、bun install 和 yarn install;生成的 brownfield pnpm AppHost 使用 pnpm install --ignore-workspace, 其他 pnpm 依赖项安装使用 pnpm install。不支持 Yarn Classic(yarn@1... 或 v1 锁文件): 请停止操作,并要求用户升级到 Yarn 4+,或明确迁移到 npm、pnpm 或 Bun。

不要更改 packageManager,也不要仅为影响检测或切换管理器而创建、替换或重新生成 锁文件。除非用户明确选择升级或迁移,否则应保留现有文件。使用 aspire start --non-interactive 启动 AppHost,而不是使用原始包管理器启动器。完整命令矩阵和解析器详情请参阅 references/typescript-authoring.md。

工作流阶段

1. SCAN     → discover projects, services, dependencies, integration candidates
2. PROPOSE  → resource graph + integration list, confirm with user
3. EDIT     → wire AppHost, add ServiceDefaults + OTel + health checks
4. VALIDATE → aspire start --non-interactive → aspire wait <each resource>
5. DEACTIVATE → confirm clean start, hand off to aspire-orchestration

如需采用与上游完全一致的详细工作流,请在编辑前加载以下参考文档:

  • apphost-wiring.md — 完整的 AppHost 接线工作流、API 查询、端点/参数模式、验证、解决方案更新和清理。
  • docker-compose.md — docker-compose 迁移、配置文件、映像映射、端口、卷和 depends_on。
  • full-solution-apphosts.md — 大型解决方案的分类处理、混合 SDK 边界、解决方案成员资格、ServiceDefaults 放置位置和旧版主机迁移。
  • javascript-apps.md — JavaScript 资源选择、工作区/单体仓库包管理器处理、端口、脚本和 TS AppHost 包配置。
  • opentelemetry.md — 为非 .NET 服务配置可选的 Node.js、Python 和 Go OpenTelemetry。
1. 扫描

遍历仓库并建立清单:

内容方法
.NET 项目find . -name '*.csproj' -not -path '*/bin/*' -not -path '*/obj/*'
Node 服务find . -name 'package.json' -not -path '*/node_modules/*'
Python 服务find . -name 'pyproject.toml' -o -name 'requirements.txt'
compose 中的容器依赖项docker-compose.yml、compose.yaml(Postgres?Redis?Rabbit?)
连接字符串在 appsettings*.json、.env*、config/* 中 grep Postgres、Redis、Mongo、RabbitMQ、Cosmos、ServiceBus
集成包每个项目运行 dotnet list package;检查 package.json 中的 dependencies
现有端点launchSettings.json、next.config.js、vite.config.ts 中硬编码的端口

完整的启发式规则请参阅 references/scan-and-propose.md。

2. 提议

在编辑之前展示资源图。提出澄清问题:

  • “我在 docker-compose.yml 中看到了 Postgres——应该将其建模为 AddPostgres('db'),还是使用 Azure Database for PostgreSQL?”
  • “你的 React 应用硬编码了 http://localhost:5000——要替换为 Aspire 服务发现(endpoint.url)吗?”
  • “你的 API 有一个 /admin 端点——要将其从 WithReference() 中排除,以免使用方看到它吗?”
3. 编辑

应用提议的资源图。根据 AppHost 语言采用合适的编写方式。

4. 验证
aspire start --non-interactive --format Json
aspire wait <resource>          # repeat for each declared resource
aspire describe --format Json   # sanity check graph

完整的验证流程和恢复方法请参阅 references/validation.md。

5. 自动停用

在 aspire start 成功运行后,宣布:

✅ AppHost wired and validated. Handing off to aspire-orchestration for
   day-to-day start/stop/wait. Aspireify is done.

集成发现目录

将检测到的服务映射到 Aspire 集成。完整目录请参阅 references/scan-and-propose.md。

检测到的服务C#TS
compose 中的 Postgres / Npgsql 包AddPostgres("pg").AddDatabase("db")addPostgres('pg').addDatabase('db')
compose 中的 Redis / StackExchange.RedisAddRedis("cache")addRedis('cache')
RabbitMQAddRabbitMQ("mq")(v7 客户端,支持发布-订阅追踪)addRabbitMQ('mq')
MongoDBAddMongoDB("mongo")addMongoDB('mongo')
Cosmos DBAddAzureCosmosDB("cosmos")addAzureCosmosDB('cosmos')
Azure Service BusAddAzureServiceBus("sb")addAzureServiceBus('sb')
Azure Cache for Redis(Entra)AddAzureRedis("cache")(现已正式发布)addAzureRedis('cache')
Next.js 前端AddNextJsApp("web", "./web")addNextJsApp('web', '../web')
Vite SPAAddViteApp("web", "./web")addViteApp('web', '../web')
普通 Node 应用AddNodeApp("api", "server.js")addNodeApp('api', 'server.js')

当前编写规则

规则原因
在 TS 中使用统一的 withEnvironment(name, value) — 不要使用已弃用的按类型区分的帮助方法(withEnvironmentEndpoint、withEnvironmentParameter 等)一个 API 可处理所有类型的值;按类型区分的帮助方法已弃用
JS 前端优先使用 AddNextJsApp / AddViteApp,而非手动编写 Dockerfile提供一流的生命周期支持,并集成 PublishAs*
JS 发布使用 PublishAsStaticWebsite / PublishAsNodeServer / PublishAsPackageScript取代手动编写的 Dockerfile;SPA → 静态网站,SSR Node → NodeServer,package-script SSR → PackageScript
为前端资源添加 WithBrowserLogs(),以便在仪表板中查看浏览器控制台和屏幕截图Aspire.Hosting.Browsers 会在仪表板中呈现浏览器遥测数据
存在多个环境时,使用 WithComputeEnvironment(env) 将每个资源绑定到计算环境多环境部署需要显式绑定
绝不要编辑 TS AppHost 中的 .aspire/modules/该目录由生成器生成,手动修改会被覆盖。只编辑已配置的 apphost.mts(或旧版 apphost.ts)
使用 WithEndpoint("name", e => ...) 更新端点端点回调会更新现有端点,而不会因重复项而抛出异常
将管理端点标记为 ExcludeReferenceEndpoint = true防止消费者通过 WithReference() 获取管理 URL
查询不熟悉的 API:aspire docs api search <query> --language csharp|typescript不要猜测重载或构建器链
使用上下文的 .Services / await ctx.services().getInteractionService().ServiceProvider 已过时,而单独调用 ctx.services() 只会返回服务访问器
对外部连接字符串使用 AddConnectionStringPublishAsConnectionString 已过时
提示用户前检查 IInteractionService.IsAvailable通过 CLI 调用的命令可能无法交互;对于仪表板和 CLI 输入,优先使用命令参数
将 WithTerminal() 视为实验性功能抑制 ASPIRETERMINAL001;不要生成已移除的 TerminalOptions.Shell 或 TypeScript 维度选项
所有 Aspire SDK 和 Aspire.Hosting.* 包都使用同一发布系列混用不同发布系列可能导致启动失败
将 GitHub Models 集成迁移到 Azure AI FoundryAspire.Hosting.GitHub.Models 已弃用,且不会出现在集成发现中
Redis 8 模块使用 WithModule(RedisModules.*)优先使用类型化的 JSON、Search、Bloom Filter 和 TimeSeries 常量,而非原始模块路径
托管的可执行文件/容器 Agent 使用 Foundry AsHostedAgent(...)当前 Azure AI Foundry 路径取代了已弃用的 GitHub Models

C# 与 TS 快速参考

概念C#TypeScript
构建器var builder = DistributedApplication.CreateBuilder(args);const builder = await createBuilder();
添加项目builder.AddProject<Projects.Api>("api")(SDK)或 AddProject("api", "../Api/Api.csproj")await builder.addProject('api', '../Api/Api.csproj')
设置环境变量(任意值类型).WithEnvironment("KEY", value).withEnvironment('KEY', value) ← 统一 API
等待依赖项.WaitFor(db).waitFor(db)
传递连接.WithReference(db).withReference(db)
外部 HTTP.WithExternalHttpEndpoints().withExternalHttpEndpoints()
终结点表达式api.GetEndpoint("http")api.getEndpoint('http').url / .host / .port
构建并运行builder.Build().Run();await builder.build().run();

ServiceDefaults 配置

每个项目都应调用 builder.AddServiceDefaults();,以启用 OpenTelemetry、 运行状况检查和服务发现。添加对 Aspire.ServiceDefaults 项目的引用 (对于非单体仓库,使用 NuGet)。请参阅 references/service-defaults.md。

终结点和引用约定

// Public-facing API. Mark "admin" endpoint as not-for-consumers.
var api = builder.AddProject<Projects.Api>("api")
    .WithExternalHttpEndpoints()
    .WithEndpoint("admin", e => e.ExcludeReferenceEndpoint = true);

// Frontend wires the API via service discovery.
builder.AddNextJsApp("web", "./web")
    .WithReference(api)        // injects services__api__http and __https
    .WaitFor(api)
    .WithBrowserLogs();        // browser console + screenshots

验证与恢复

症状操作
aspire start 因构建错误失败修复代码,然后重新运行 aspire start
编辑时出现文件锁错误移交给 aspire-orchestration → aspire stop → 重试
aspire describe 未显示资源重新运行 aspire describe --include-hidden;aspire ps 仅适用于 AppHost 级别
TS AppHost 更改未生效确认编辑的是已配置的 apphost.mts(或旧版 apphost.ts),而不是 .aspire/modules/
aspire start 输出混有其他内容的 JSON解析前去除非 JSON 行(#15843)

完整流程见 references/validation.md。

移交规则

场景移交至
尚未创建 AppHost 框架→ aspire-init skill
日常启动/停止/等待/重启→ aspire-orchestration skill
发布、部署、销毁、流水线步骤→ aspire-deployment skill
日志、追踪、指标、仪表板、浏览器日志检查→ aspire-monitoring skill
已部署应用(Azure/AKS)诊断→ azure-diagnostics skill(azure-skills)

关键规则

  • 绝不覆盖现有文件——始终采用增补或合并的方式。
  • 修改服务代码前先征求同意,尤其是 OpenTelemetry 和 ServiceDefaults 注入。
  • 尊重现有项目结构——不要重组代码库。
  • 如果遇到困难,使用 aspire doctor 诊断环境问题。
  • 绝不要在 WithEnvironment / withEnvironment 中硬编码 URL——应传递终结点引用,例如 api.GetEndpoint("http") 或 api.getEndpoint('http'),而不是字符串字面量。
  • 绝不要使用 WithUrlForEndpoint / withUrlForEndpoint 设置 dev.localhost URL——该 API 仅用于仪表板显示标签;dev.localhost 应配置在 AppHost 启动/配置文件中。

参考资料

评论

支持 Markdown