不要一次学完 Manifest 的全部字段。按你现在要交付的东西选档,跑通后再升档。官方案例也按同一阶梯:CURL 停在「最小可用 + 可选一张卡」;红火台走到「业务会话 + 查询 Tool + Surface + Skill + MCP」。
三档对照
| 档位 | 你要交付 | 工程里有什么 | 不必有什么 | 对照案例 |
|---|---|---|---|---|
| 0 · 最小页 | 可安装完整页,能调 wf |
manifest + 页面 + 真权限 |
tools、skills、UI Module | Hello 级;CURL 的主体 |
| 1 · 会说话 | Agent / MCP 能查或打开你的能力 | 档 0 + contributes.tools(+ 可选 Skill) |
自定义会话卡/磁贴 | 红火台的 query/launch 层 |
| 2 · 嵌进宿主 | 会话卡、home/Spotlight 磁贴 | 档 1 + React UI Module + card/widget 注册 | — | 红火台 Surface;CURL 的请求摘要卡 |
脚手架:vanilla / react-ts / vue-ts → 档 0;需要卡/磁贴再选 react-ui-ts(高信任提示)。
档 0 · 最小可运行
目标: 拖进客户端能打开,能发一次 wf.request 或写本地存储。
npm create @workfly/app my-app -- --template react-ts
cd my-app && npm install
npm run dev # 浏览器内循环
npm run build # 出 .wfapp.zip,拖进「小程序」面板验证
Manifest 只要: 身份、manifest: 2、ui.standalone(sandbox + full + routing)、launchers、真实用到的 permissions。
硬约束:
- 联网用
wf.request,声明net.fetch - 需要登录时
wf.login()换你自己的业务会话,不摸宿主 Token - 路由表先写后用;单页也要显式
routing
验收: 安装后冷启动、刷新、权限拒绝提示符合预期。
→ 细节:开发指南 · 快速开始
档 1 · 贡献 AI 可调能力
目标: 用户对主助手说「查我的订单」时,能走你的只读 query,或打开你的页面入口——而不是只能「请用户自己点开应用」。
推荐在工程根增加(不要预建空目录):
capabilities/tools/<name>.json
capabilities/skills/<id>/SKILL.md
与内联 contributes.tools 等价,由 @workfly/miniapp-kit 在 build 时合并:
query:固定 HTTPS、readOnly: true、字段白名单;可用workfly.sessionKey/workfly.expose。launch:打开已声明 path;可配workfly.resultCard(内部 Agent 不自动导航)。
Skill 的 id/name/description 只写在 frontmatter。
验收:
- 内部会话:query 返回可读文本 + 可选卡;launch 出卡不自动跳转
- 外部 MCP(若 expose):只拿到字段受限 JSON,没有卡
- 未登录/会话缺失:Tool 报错,不改业务数据
→ 拆解:红火台案例 · 会话与 Surface
档 2 · 宿主 Surface
目标: 余额/订单等摘要直接出现在会话或 home 磁贴,点击再进完整页。
增加:
ui.modules(workfly-react@1、Shadow CSS)surfaces/cards.json与surfaces/widgets.json(mode: "react"+ module + component;也可内联 contributes)- Tool 的
resultCard.kind指向已注册 kind - 可选
suggestions(最多 4 条;查询用send,有副作用用fill)
验收: 安装出现高信任确认;卡宽高与主题 token 正常;磁贴随拖拽跨度改布局;来源行可点回应用。
未审核第三方可长期停在档 1。→ CURL 的卡片边界 · 理念 · 完整页 vs Surface
旁路 · IM 入口 + 宿主 AI(会话总结类)
目标: 在群聊/单聊工具栏挂一个图标,打开后读取当前会话历史,用你的提示词调 WorkFly AI 流式输出(例如「总结精彩」「提取待办」)。这是 档 0 完整页 + 贡献点 + 宿主只读/补全 API,不必上 React UI Module。
工程要点:
surfaces/im-entries.json(或contributes.imEntries):placement(如composer.toolbar.end)、icon/label/tooltip、launch.path,建议presentation: "popover"。- 权限:
im.chatContext(历史/上下文)、ai.complete(纯补全,无工具)。 - 打开后读
wf.getLaunchOptionsSync().query(chatId等)→wf.im.getHistory→ 本地筛选 →wf.ai.complete({ system, prompt, onChunk })。
验收:
- 安装后进会话,工具栏出现图标;点开浮层能读到与当前会话一致的 chatId
- 首次弹权限询问;拒绝后调用失败且可在设置里重开
- 流式输出可见;换会话再开入口,上下文不串
明确不做: 裸 ACP/本机 CLI、代发 IM、扫其它会话、把主 Agent 全工具面交给第三方包。
→ 签名:WF API · wf.im · wf.ai · 开发指南 IM 入口与宿主 AI
推荐学习顺序
- 用档 0 做一个只读列表页(或先装官方 CURL 包感受安装体验)
- 读 CURL 案例:最小权限、内容带入、
wf.request - 加一个只读 query Tool(档 1),用客户端 Agent 或 MCP 试调
- 读 红火台案例:登录、路由、白名单、Skill
- 需要「挂在聊天工具栏 + 总结会话」时做上方 IM + 宿主 AI 旁路
- 确有嵌入需求再上档 2
升档时不要做的事
- 为「以后可能用」提前申请 restricted 权限或 UI Module
- 在 query 里伪装写操作
- 把完整后台页面塞进会话卡
- 只出卡不给 Agent
summary/ 结构化投影 - 用 dev 预览代替安装包验收 Vault 与真实权限
- 向第三方小程序开放裸 ACP 或任意 chatId 扫库