| name | author-solution |
| description | 从原始资料创作一个符合 spec 的一键部署 IoT 方案。基于 Wiki/文档/Git 仓库复现方案,提炼最简路径,输出符合公开契约(spec/CONTRACT.md)的 solution.yaml / guide.md / description.md,并用离线工具 solutionctl 校验。适用于:从资料创建新方案、提炼最简部署路径、校验方案合规性。 |
| argument-hint | <资料来源URL或路径> [solution_id] |
| allowed-tools | Read, Write, Edit, Glob, Grep, Bash, WebFetch, WebSearch |
Author Solution Skill
从原始资料(Wiki / 文档 / Git 仓库)创作一个符合 SenseCraft 方案契约的一键部署方案。
调用方式
/author-solution https://wiki.seeedstudio.com/xxx smart_factory
/author-solution ./raw_materials/ my_solution
/author-solution https://github.com/xxx/xxx # 自动生成 solution_id
$ARGUMENTS 包含:资料来源(URL 或本地路径)+ 可选的 solution_id。如果用户指定了某个 preset,只复现该 preset。
所有 device YAML 字段、guide.md Step/Target 语法、docker_deploy 派生规则等机器可读契约以 spec/CONTRACT.md 为唯一权威来源(配套 spec/*.json schema)。本 skill 只讲创作流程;遇到字段细节一律查 CONTRACT。
核心理念
- 目标用户:解决方案商(无开发能力)
- 最小工作单元:preset(而非整个 solution)
- 最简路径:去掉所有非必要步骤,让用户用最少操作完成部署
- 预配置优先:能提前配好的全部预配好,用户只需做「连接」和「点击」
- 部署 + 验证完整闭环:部署完不算完,要让用户立刻看到效果
每个 preset 必须至少有一个 verify 步骤(让用户立刻看到结果)。solutionctl validate 强制检查 verify step 存在。solution 类用 type=web_dashboard;technical 类用交互式 verify(image_predict / text_chat / voice_chat / http_debug 等)。可用的 verify/step 类型见 spec/CONTRACT.md「Deployer capabilities」表。
- 极少数纯硬件/纯云方案没有本地 dashboard 可指 → 在该 preset 上标
verify_exempt: true 豁免(CI 会接受)。
选择 verify 验证方式 + 能力不够怎么拓展
(a) 怎么选 —— 看部署出来的东西是什么,对号入座:
| verify 类型 | 当部署的是… |
|---|
web_dashboard | 一个网页 UI / 看板(Grafana、Web 应用)—— 本质是「打开这个 URL」 |
image_predict | 视觉模型 —— 传一张图、看预测结果 |
text_chat | LLM / 聊天 —— 输入 prompt、看回复 |
image_text_chat | 视觉语言模型(VLM)—— 图 + 文字 prompt |
image_text_to_image | 文生图 / 图生图 —— 输入提示词(或图),看生成的图 |
voice_chat | 语音助手 —— 说话、听 ASR/TTS |
video_stream | RTSP / MJPEG / HLS 视频输出 —— 直接在 app 的预览窗口看画面 |
robot_inspect | 机器人 / 机械臂 —— 实时观测面板,轮询机器人主容器的 /observation 端点显示关节/传感器状态 |
http_debug | 其他任意 HTTP 接口 —— 发请求看响应的通用调试器(通用兜底) |
任意步加 verify=true | 把一个非标准步骤(如手动 demo)标成 verify 步 |
这张是常用速查;权威完整清单(含每个类型的配置字段)以 spec/CONTRACT.md「Deployer capabilities」表为准。
(b) 没有合适类型怎么拓展(按优先级,前 3 条都不改引擎就能做):
- 先用通用兜底:服务暴露 HTTP API 但不是 chat/vision → 用
http_debug(任意请求/响应);只是要打开个页面 → web_dashboard(任意 URL)。这俩能覆盖绝大多数「没有专门类型」的情况。
- 如果结果本身是 RTSP / MJPEG / HLS 视频流,优先用
video_stream,不要写成“打开 ffplay/VLC 手动验证”。能在 app 里看到的结果就应在 app 里预览。
- 如果一个视频方案同时暴露“最新结果 API”(例如二维码识别文本、检测 JSON),不要为了 curl 再单独加一个
http_debug 验证步骤;优先用 video_stream 的 overlay,在预览窗口里直接叠加结果。原理是:video.*_url_template 提供视频流,data.http_url_template 轮询最新 JSON(app 通过 /api/commands/http-proxy 代理,避免浏览器 CORS),overlay.script_file 是前端 canvas renderer,签名为 (ctx, data, canvas, img),每次数据更新时把二维码文本、检测框或状态卡画到视频上。MQTT 输出则用 mqtt.* 触发同一个 renderer。只有当 API 返回本身是用户要看的主要结果、且没有可视化预览时,才用 http_debug。
- 自定义校验 / 健康检查:在 device YAML 的
actions.before / actions.after 写 run: 脚本(设备上跑任意 shell,可 sudo: true)—— 做部署前预检、部署后健康检查。参考 solutions/gpt_oss_20b/devices/jetson_deploy.yaml 的 "Validate Jetson runtime"。这是不改引擎就能拓展的主力。 字段名(actions / before / after / run / sudo)以 spec/device.schema.json 为准。
- 标记任意步:
{#id type=... verify=true} 把任意步骤当成 verify 步。
- 以上都不满足(需要一个全新的交互式 verify 类型 / 新 UI 控件):这是引擎(闭源)侧能力,本仓库加不了 —— 要么用插件原型化(见
docs/plugin-development.md),要么提一个能力需求 issue说明你要的交互形态。
关于插件(原型化自定义 verify 类型):完整开发指南见 docs/plugin-development.md。App 的插件机制(spec/plugin.schema.json 的 contributes.deployers[])现在可以给方案步骤注册新 type=。用法约定:
- 命名空间:插件类型写成
<plugin-id>/<type>(如 type=myplugin/robot_arm),一眼看出来源、不和内置/其他插件撞名。
- 声明依赖(最小 lockfile):在
solution.yaml 顶层加 requires_plugins:,列出 - {id: <plugin-id>, version: <ver>},把这个方案依赖的插件钉死。
- verify 步要标
verify=true:validate 离线、不知道插件类型的 category,所以插件做的 verify 步必须显式标 {#id type=<plugin-id>/<type> verify=true} 才算「该 preset 的 verify 步」。
- validate 对插件类型只 WARN 不 ERROR:用了命名空间插件类型的方案能离线自检通过(给 WARNING 提示其来源 + 是否漏了 requires_plugins);但非命名空间的真未知类型(没有
/)仍然 ERROR——那是拼写错误,不是插件。
- 插件类型方案不进公开 catalog:直到该类型被「收编」成官方内置类型之前,带插件类型的方案只在装了对应插件的本地/私有环境可部署,不收进公开仓库。
校验现在查得更全:solutionctl validate --check-urls 会查 schema、引用文件存在、i18n 完整、重复 id、device-ref、死链(404/410)、compose/flow 可解析、EN/ZH 结构一致。本地提交前自己跑一遍即可和 CI 一致。
说明:--check-urls 把 401/403/408/429 当「资源在、只是挡爬虫/限流」放过(如 files.seeedstudio.com 套了 Cloudflare,对脚本返回 403 但浏览器/App 正常显示)——这些图片可放心用,只有 404/410 这种真死链才报错。
诚实标注验证等级(可选但推荐):在 preset 上加 verified: 列表对用户透明——
deploy-smoke:声明它能在 CI 里起得来。前提:该 preset 有一个 type: docker_deploy 的 device YAML 在 docker: 块里标了 ci_smoke: true(仅限轻量 x86 栈;GPU/Jetson/烧固件的别标,CI 起不来)。validate 会强制这个一致性,标了 deploy-smoke 却没 ci_smoke gate 会报错。
注意:ci_smoke 是校验器直接从 raw YAML 读取的键,不在 Pydantic DockerConfig schema 里——照写就行,别因为 schema 里没有它就以为是多余字段而删掉。
hardware:你(或维护者)在真设备上跑过。
- 结果对不对(模型准不准等)永远不自动验证,靠人。
整体流程
资料 → 阅读分析 → 手动部署(第一轮)→ 整理配置文件 → 校验(solutionctl)→ 输出文档
↑ |
└─────── 修复配置文件 ←──────────────┘
第一轮手动部署是为了理解方案、发现问题、积累经验。
之后用生成的配置文件走 solutionctl validate,验证配置文件符合契约。
Phase 1: 资料收集与分析
Step 1:读取/抓取原始资料
- URL → WebFetch
- 本地路径 → 读取所有相关文件
- Git 仓库 → clone 并分析 README、docs、docker-compose 等
Step 2:提取关键信息,生成结构化摘要
## 方案概述
- 名称 / 解决什么问题 / 核心硬件(产品族 + 能力要求)/ 核心软件
## 部署步骤(原始)
1. ...
## 简化方案
- 合并/删除的步骤 / 预配置的内容 / 暴露的配置项
## 方案类型判定(solution / technical)
核心硬件必须先对照离线产品族快照(强制):
jq --arg q 'J40' '
($q | ascii_downcase) as $needle
| .families | to_entries[]
| select(
([.key, .value.title.en // "", .value.title["zh-hans"] // ""]
| join(" ") | ascii_downcase | contains($needle))
)
| {family_id: .key, title: .value.title}
' spec/product-family-manifest.json
jq --arg id 'recomputer_j40' \
'.families[$id] | {title, axes}' spec/product-family-manifest.json
- 找到产品族:记录其
family_id,后续直接用作 device_catalog key、
device_ref 和 default;需要 16 GB、特定模组等能力时,记录 manifest
中的 axis/value,后续写入 purchase.require。
- 禁止按页面产品名自造 key,也禁止记录或写入具体 SKU、具体产品名、
产品图或购买链接。运行时 App 会从 Typesense
purchase_profile 获取这些数据。
- 只有快照确实找不到该硬件时,才能使用
generic_ / external_ 前缀,并在
结构化摘要中说明为什么没有可用的 purchase_profile family。
- 完整规则和更多查询示例见
docs/product-family-contract.md。
方案类型判定(必须做)
- 完整方案 (solution):打通多个技术模块形成业务闭环,有用户能直接使用的看板/管理界面(Grafana / Frigate / Node-RED Dashboard 等)
- 技术演示 (technical):单一 AI 能力或数据处理管道,主要价值在于输出数据/接口供其他系统集成
| 特征 | → solution | → technical |
|---|
| 有面向用户的看板/仪表盘 | ✓ | |
| 端到端业务闭环 | ✓ | |
| 主要是单一 AI 能力 / 数据管道 | | ✓ |
| 主要价值在输出数据/接口 | | ✓ |
| 组合了多个独立功能模块 | ✓ | |
注意:有 Frigate 看板、Grafana 仪表盘的就是完整方案,不要因为「用了 AI 检测」就标 technical。
类型差异要点:
- technical 需声明输出接口(每个 interface 至少有 port/endpoint/topic/path/url 之一)
- 无论哪种类型,需要外部输入(摄像头/传感器)就声明输入要求
- 字段名以
spec/solution.schema.json 为准
technical 文案边界(必须执行):
- 技术演示不是 API 文档。介绍页首屏先讲「这个能力能接到什么系统、补上什么能力」,再讲端口/协议。
- 正文必须把接口翻译成人能理解的产物,例如「本地听写服务」「可播放音频流」「识别结果 JSON」,不要只写 ASR/TTS/RTSP/RKNN。
- curl/代码示例不要放在介绍页前半段;放到 guide.md 的部署完成、接口详情或验证步骤里。
- 如果前端已经根据输出接口自动展示接口卡片,description 里不要重复堆完整 API 表,只保留通俗解释或简化表。
Step 3:向用户确认简化方案 + 修改边界:
- 默认只改部署产物(docker-compose.yml、flow.json、device YAML),不改应用源码
- 用户可能允许改 docker-compose 中的环境变量、端口映射等
Phase 2: 手动部署(第一轮)
亲手走通全流程,理解每一步实际发生了什么。
Step 4:准备目标设备的连接信息(IP / SSH 用户名密码 / 串口等)。
Step 5:逐步执行简化后的部署,直接在目标设备上操作:
ssh user@device "cd /opt/myapp && docker compose up -d"
esptool.py --chip esp32s3 write_flash 0x10000 firmware.bin
scp package.deb recamera@192.168.42.1:/tmp/ && ssh recamera@192.168.42.1 "opkg install /tmp/package.deb"
每一步记录:实际执行的命令和输出、遇到的问题、用户需要填的值(→ user_inputs)、可合并/自动化的步骤(→ actions)。
Step 6:验证最终结果,Web 界面截图录屏留证。
Step 7:记录部署笔记,作为下一步生成配置文件的输入。
Phase 2.5: HuggingFace 资源下载规范
需要从 HuggingFace 拉模型/权重时,不要在镜像里装 huggingface_hub(库 + 依赖体积大,会让镜像膨胀几百 MB)。改用宿主机 curl 下载,模型 bind-mount 进容器:
- 下载脚本里不要硬编码
huggingface.co,用环境变量 HF_ENDPOINT / HF_ENDPOINT_HOST 控制 endpoint,受限网络下可切换镜像
- 验收:下载脚本的 curl/wget 命令里不出现硬编码
huggingface.co(注释里写没关系)
Phase 3: 整理配置文件
Step 8:生成 solution 目录结构(扁平结构,不要用 intro/、deploy/sections/ 等老结构)
solutions/<solution_id>/
├── solution.yaml
├── description.md / description_zh.md
├── guide.md / guide_zh.md
├── gallery/
├── devices/ # 设备配置 YAML
└── assets/ # 部署产物(compose、flow.json 等)
Step 9:编写设备配置 YAML
device YAML 的字段、各部署类型(docker_local / docker_remote / esp32_usb / recamera_cpp / ...)的必填字段,全部以 spec/CONTRACT.md 的「Device schema fields」和「Deployer capabilities」表为准(schema 文件:spec/device.schema.json)。关键映射:
| 手动部署中做了什么 | 配置文件中怎么写 |
|---|
docker compose up(本地) | type: docker_local,docker.compose_file |
| SSH 到远程跑 docker | type: docker_remote,docker_remote.compose_file |
| 同一方案既支持本地又支持远程 | guide.md 里写 type=docker_deploy(见 Step 10),由引擎派生 local/remote 两个视图 |
esptool.py write_flash | type: esp32_usb,firmware.flash_config |
opkg install xxx.deb | type: recamera_cpp,binary |
| 手动跑的 shell 命令 | actions.before / actions.after |
| 用户需要填的值 | user_inputs 列表 |
reCamera C++ 应用必须优先做 deb 包:如果原项目产物是 C/C++ 可执行文件,不要在 solution 里用 files: 复制裸二进制,也不要用 actions.after 做 chmod + nohup。正确做法是使用 skills/prepare-deb-package 打包成 .deb,在 device YAML 中写 binary.deb_package.path/name/includes_init_script/checksum,并提供 /etc/init.d/S92<service> 管理启动、停止和卸载。这样切换应用、重复部署、卸载还原才可控。只有一次性诊断脚本或非长期运行文件才考虑 files:。
docker_deploy 派生规则(一个 device YAML 写成 type: docker_deploy,引擎在加载时拆成 docker_local + docker_remote 两个视图)的完整规则见 spec/CONTRACT.md「docker_deploy view 派生规则」。要点:remote_path 必填且无 solution_id 兜底;remote_overrides.actions 是整体替换不是合并。
Step 10:编写 guide.md
每个 ## Step 对应一个部署动作。Step / Target / Mode 的完整语法、{#id ...} 属性块解析规则见 spec/CONTRACT.md「guide.md Step/Target 语法」和「guide.md heading keywords」。标准格式:
## Step 1: Deploy Services {#backend type=docker_deploy required=true config=devices/docker.yaml}
One-line description.
### Target {#local type=local config=devices/docker.yaml default=true}
### Target {#rk3576 type=remote device_name="RK3576" config=devices/docker_remote.yaml}
### Troubleshooting
| Issue | Solution |
|-------|----------|
| Docker not found | Install Docker Desktop |
Step 摘要不要太长:
## Step ... 后、首个 ### 子标题前的正文会显示在折叠步骤卡片上。这里只写 1 句“用户现在做什么 / 看到什么算成功”,不要塞 URL、参数解释、排障判据、命令或长背景。详细检查项放到 ### What to check / ### 检查内容,排障放到 ### Troubleshooting / ### 故障排查。目标长度:中文不超过 60 字,英文不超过 120 个字符。
Target 命名规范:
Target 标题不写名字 — 写成 ### Target {#id ...},冒号和名字都省略。前端会根据 type= + device_name= 自动从 i18n 决定显示名:
| markdown | 用户看到(中文) | 用户看到(英文) |
|---|
type=local | 在这台电脑上部署 | Deploy on This Machine |
type=remote(无 device_name) | 部署到另一台设备 | Deploy to Another Device |
type=remote device_name="Jetson" | 部署到 Jetson | Deploy to Jetson |
禁止写"本地/远程/Local/Remote" 等方向词作为 Target 名。
device_name= 只写芯片/产品名,不带括号备注 — ❌ "RK3576 (reComputer / ROCK 5T)" → ✓ "RK3576"。
Target ID 命名:
type 是部署类型识别依据(local / remote),不是 ID
- 本地部署 ID 可叫
local 或加前缀(backend_local)
- 远程部署 ID 用具体设备/服务名(如
rk3576),不要笼统叫 remote
多语言 guide 语法与可见文案(必须检查):
结构关键字既是语法也是可见标题,必须匹配文件语言:guide.md 用
## Preset: / ## Step N: / ### Target / ### Troubleshooting;
guide_zh.md 用 ## 套餐: / ## 步骤 N: / ### 部署目标 /
### 故障排查。不要写半翻译形式,例如 ### 目标 {...}(解析不了)
或在中文文件里保留 ### Troubleshooting、| Symptom | Cause / fix |。
中文文件的正文、表头、故障现象、按钮说明必须中文优先。允许保留的英文只限:
产品/品牌名、命令、环境变量、文件路径、URL、API 名、模型名,以及设备实际播报
或用户必须说出的英文短句。即使保留英文短句,也要先给中文解释,例如
播报物体太大、夹不住(英文提示类似 "too big for me to grip")。
交付前至少运行一次:
rg -n "Troubleshooting|Symptom|Cause / fix|Issue \\| Solution|What you'll get|Requirements|Prerequisites|Wiring|Deployment Complete" solutions/<id>/*_zh.md
uv run --package sensecraft-solutionctl solutionctl deploy-info <id> --lang zh
第一条只应命中允许保留的英文命令/产品名;第二条要人眼检查中文部署页没有英文模板表头、没有原始 {#...} 标记泄漏。
多个 docker_deploy 步部署到同一台机器 —— 用 target_inherit_from=<upstream_step_id> 让下游步自动跟随上游的 local/remote 选择。只继承 method(local/remote),不绑死 target id。同一 preset 内才能继承;引用的 step 必须在自己之前、且自己有 targets。
verify 步要复用上游 deploy 的 host —— 在 verify 步的 device YAML 里写 inherit_host_from: <step_id> 显式声明(inherit_host_from 是 device schema 顶层字段,见 CONTRACT)。
<step_id> 是上游那个 deploy ## Step 的 id(guide.md 里 {#...} 的值),不是 device id、也不是 target id。 端点模板用 {{deploy.host}},引擎会替换成被继承步骤实际选定的 host。多 deploy 步的方案必须显式写,自动 fallback("最近的 deploy 步")会选错。
最小 web_dashboard verify device YAML:
version: "1.0"
id: dashboard
name: Open Dashboard
type: web_dashboard
inherit_host_from: web
web_dashboard:
url: "http://{{deploy.host}}:8080"
title: My Dashboard
description: 页面能加载出数据即代表部署成功。
### Wiring 段严格限定为接线说明,不要塞 Docker 安装、API key 获取等非接线内容。
guide.md 里 H2 只能是 ## Preset: 或 ## Step N:(必带 {#id}) —— 其他任何顶层 ## ...(如 ## Quick Verification / ## API Reference / ## Next Steps)都是孤儿 H2,校验会拦。
- 部署完成后的总结/验证/链接 → 写成
### Deployment Complete,放在该 preset 最后一个 step 的所有 ### Target 之前。
- 附录小节(验证、API 表、下一步等)→ 写成
#### XXX(H4),嵌在 ### Deployment Complete 下面。
- 前置条件 / 系统要求 / 介绍性文字 → 放进
description.md,guide.md 只讲怎么部署。
## Step 3: Open Dashboard {#dashboard type=web_dashboard ...}
### Deployment Complete
Your service is now running.
#### Quick Verification
1. Open http://...
#### Next Steps
- [Documentation](https://...)
### Target {#local type=local ...}
Step 11:编写 solution.yaml + description
字段以 spec/solution.schema.json 和 spec/CONTRACT.md「Solution schema fields」为准。关键点:
- 方案类型(solution / technical)必须明确
- technical 类需声明输出接口(含路由标识 port/endpoint/topic/path/url)
- 需要外部输入的方案声明输入要求
device_ref 必须能在 intro.device_catalog 中找到
- 产品硬件必须先检索
spec/product-family-manifest.json:选中的 family_id
直接作为 device_catalog key、device_ref 和 device group 的 default,
不再建立第二层映射
- 能力要求只用 manifest 中声明的 axis/value 写到
purchase.require;禁止写
具体 SKU,也禁止在产品族 entry 重复具体产品名、图片和购买 URL
- 只有 manifest 中确实没有对应产品族,才使用
generic_ / external_ key,
并在交付说明中写明原因;禁止凭产品名自造 key
- 设备/封面图片用稳定可达的源:方案自带本地图(
gallery/cover.png,相对路径)或公共 CDN(files.seeedstudio.com、media-cdn.seeedstudio.com、sensecraft-statics.seeed.cc 都行)。--check-urls 只把 404/410 当死链;files.seeedstudio.com 的 Cloudflare 403 会被放过,可放心用。
最小可复制的 solution.yaml 骨架(solution 类型)
下面是一个经 solutionctl validate 通过的最小骨架(一个 docker_deploy 部署步 + 一个 web_dashboard verify 步)。复制后改 id/name/镜像即可。完整字段含义查 spec/CONTRACT.md。
version: "1.0"
id: hello_dashboard
name: Hello Dashboard
name_i18n:
zh: 你好看板
intro:
summary: A minimal one-click web dashboard you can deploy and open.
summary_i18n:
zh: 一个可一键部署并打开的最小 Web 看板。
description_file: description.md
description_file_i18n:
zh: description_zh.md
cover_image: gallery/cover.png
category: sensing
solution_type: solution
tags: [demo, dashboard]
device_catalog:
generic_edge_server:
name: Edge Server
name_i18n:
zh: 边缘服务器
image: gallery/cover.png
description: Runs the dashboard container
description_i18n:
zh: 运行看板容器
presets:
- id: default
name: Default
name_i18n:
zh: 默认
description: Deploy the dashboard on a server.
description_i18n:
zh: 在服务器上部署看板。
verified:
- deploy-smoke
device_groups:
- id: host
name: Server
name_i18n:
zh: 服务器
type: single
required: true
options:
- device_ref: generic_edge_server
default: generic_edge_server
stats:
difficulty: beginner
estimated_time: 5min
deployment:
guide_file: guide.md
guide_file_i18n:
zh: guide_zh.md
selection_mode: sequential
配套的最小 devices/web.yaml(docker_deploy + ci_smoke):
version: "1.0"
id: web
name: Deploy Dashboard
type: docker_deploy
docker:
ci_smoke: true
compose_file: ../assets/docker/docker-compose.yml
docker_remote:
compose_file: ../assets/docker/docker-compose.yml
remote_path: /opt/hello_dashboard
user_inputs:
- id: host
name: Server IP
type: text
default: "127.0.0.1"
required: true
web_dashboard verify device YAML 见上方 Step 10 的 F4 范例;guide.md 见 Step 10 的 Step/Target 格式。
description.md 遵循 skills/solution-copywriting 规范。
Phase 4: 校验
Step 12:用离线工具 solutionctl 校验方案符合公开契约。
在本仓库内(推荐,自动使用 workspace 里的 spec/ 和解析器):
uv run --package sensecraft-solutionctl solutionctl validate solutions/<solution_id> --spec-dir spec
uv run python scripts/ci/validate_product_families.py
校验工具从本仓库内运行(clone-first,不依赖 PyPI 发布)。如果要在仓库外的位置校验某个 solution,指向本仓库的 spec/ 即可:
uv run --package sensecraft-solutionctl solutionctl validate <solution_path> --spec-dir <repo>/spec
solutionctl validate 完全离线(零引擎依赖),检查:
- solution.yaml / device YAML 是否符合
spec/*.json schema;
- guide.md / guide_zh.md Step/Target 语法与
type= 是否为合法 deployer 类型(来自 spec/capabilities.json);
- 每个 preset 至少 1 个 verify step(
web_dashboard / image_predict / text_chat / voice_chat / http_debug 等,或 verify=true 标记的步骤);
- 孤儿 H2:每个
## 必须是 ## Preset: / ## 套餐: 或 ## Step N: / ## 步骤 N:,其它顶层 H2 报错;
- target 命名:
### Target 名不得是方向词(Local / Remote / 本地 / 远程 / 本机 / 远端);
- 中英文结构一致:guide.md 与 guide_zh.md 的 preset / step / target ID 必须一一对应。
validate_product_families.py 同样完全离线,使用
spec/product-family-manifest.json 检查产品族 key、device_ref / default、
purchase.require 以及是否误写具体 SKU/产品名/图片/购买链接。
必须全绿才算合格。
失败 → 修复循环(修改 device YAML / compose / flow.json / guide.md,不改应用源码),重跑直到通过。
Phase 5: 输出文档与素材
Step 13:截图和封面图
- 优先复用 Wiki 原图
- 有 dashboard 的方案,用 dashboard 实拍截图当 cover,1280x720,必须有真实数据
- 录屏作为 Demo
Step 14:确保 description / guide 文件完整。所有文件存在、步骤定义齐全。
Phase 6: 文案优化
Step 15:用 skills/solution-copywriting 做全维度检查(介绍页按类型选模板、technical 首屏可读性、部署页 Troubleshooting/Wiring 子节、中英文 ID 一致、术语通俗化)。审核改动(P0 必须修,P1 应该修,P2 视情况)。
Phase 7: 交付前自检
Step 16:跑校验 —— 失败必须修复后再交付。
uv run --package sensecraft-solutionctl solutionctl validate solutions/<solution_id> --spec-dir spec
uv run python scripts/ci/validate_product_families.py
人眼自检清单(工具查不到的):
输出清单
相关 skill / 契约
| 资源 | 内容 |
|---|
spec/CONTRACT.md | 机器可读契约:device/solution schema 字段、guide.md Step/Target 语法、docker_deploy 派生规则、heading 关键字 |
spec/*.json | solution / device / capabilities / plugin schema |
spec/product-family-manifest.json | 产品族 family id、标题、能力轴与离线 SKU 属性快照 |
docs/product-family-contract.md | 产品族选型、purchase.require 与快照刷新流程 |
skills/solution-copywriting | 文案优化规范(介绍页四段式、术语通俗化、质量检查) |
skills/prepare-docker-images | 准备 Docker 镜像与 compose 文件 |
skills/prepare-recamera-nodered | 准备 reCamera Node-RED flow |
skills/prepare-esp32-firmware | 准备 ESP32 固件 |
skills/prepare-himax-firmware | 准备 Himax WE2 固件与 AI 模型 |
skills/prepare-deb-package | 准备 reCamera C++ deb 包 |
skills/integrate-jetson-solution | 从结构化输入生成 Jetson docker_remote 方案 |