@seeed-studio/solution-cli 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +157 -104
  2. package/bin/cli.js +410 -58
  3. package/bin/runner.js +1 -1
  4. package/catalog/client-config.json +2 -2
  5. package/catalog/knowledge-core.json +58452 -488
  6. package/docs/cli-guide.md +173 -200
  7. package/lib/agent.js +74 -15
  8. package/lib/catalog-dto.js +14 -1
  9. package/lib/detector.js +3 -3
  10. package/lib/doctor.js +19 -1
  11. package/lib/downloader.js +24 -0
  12. package/lib/gotchas.js +126 -0
  13. package/lib/installer.js +113 -19
  14. package/lib/integration.js +265 -0
  15. package/lib/knowledge.js +838 -100
  16. package/lib/ledger.js +1 -1
  17. package/package.json +3 -6
  18. package/skills/{sensecraft → solution-cli}/SKILL.md +125 -30
  19. package/skills/{sensecraft → solution-cli}/references/consult-and-select.md +61 -13
  20. package/skills/solution-cli/references/deploy.md +112 -0
  21. package/skills/solution-cli/references/device-management.md +298 -0
  22. package/skills/{sensecraft → solution-cli}/references/diagnose.md +15 -0
  23. package/skills/solution-cli/references/edge-gotchas.md +205 -0
  24. package/skills/solution-cli/references/generic-rk3588.md +106 -0
  25. package/skills/{sensecraft → solution-cli}/references/hardware-bom.md +9 -3
  26. package/skills/solution-cli/references/sales-feasibility.md +65 -0
  27. package/skills/{sensecraft → solution-cli}/references/secondary-development.md +10 -7
  28. package/skills/sensecraft/references/deploy.md +0 -300
  29. package/skills/sensecraft/references/device-management.md +0 -126
  30. /package/skills/{sensecraft → solution-cli}/references/app-only.md +0 -0
  31. /package/skills/{sensecraft → solution-cli}/references/error-catalog.md +0 -0
  32. /package/skills/{sensecraft → solution-cli}/references/offline.md +0 -0
  33. /package/skills/{sensecraft → solution-cli}/references/verify.md +0 -0
package/docs/cli-guide.md CHANGED
@@ -1,9 +1,7 @@
1
- # SenseCraft Solution CLI 使用与集成全景指南
2
- *(SenseCraft Solution CLI & AI Agent Skill Guide)*
1
+ # Solution CLI 使用与集成指南
2
+ *(Solution CLI & AI Agent Skill Guide)*
3
3
 
4
- > **定位**:本文档专门面向**方案架构师、现场应用工程师 (FAE)、嵌入式开发者以及 AI Agent (Claude Code / Codex / Antigravity / Work Buddy)**,系统性说明 `@seeed-studio/solution-cli` 的独特应用场景、安装流程、各功能指令的具体使用方式以及核心产出物。
5
-
6
- ---
4
+ 本文档面向方案架构师、现场工程师、开发者和 AI Agent。安装一次 `solution-cli` Skill 后,用户可以用自然语言完成方案咨询、硬件选型、部署前检查、本地/远程方案部署和部署后诊断。
7
5
 
8
6
  ## 目录
9
7
 
@@ -11,267 +9,242 @@
11
9
  2. [安装与 Agent 技能挂载](#2-安装与-agent-技能挂载)
12
10
  3. [核心功能、使用方法与具体产出](#3-核心功能使用方法与具体产出)
13
11
  - [场景一:方案探索与工况诊断 (Hub Search)](#场景一方案探索与工况诊断-hub-search)
14
- - [场景二:硬件产品规格与配件防呆评估 (Product & BOM)](#场景二硬件产品规格与配件防呆评估-product--bom)
15
- - [场景三:设备状态感知与参数热修改 (Device Management)](#场景三设备状态感知与参数热修改-device-management)
16
- - [场景四:自研模型替换与本地二次开发 (Secondary Dev)](#场景四自研模型替换与本地二次开发-secondary-dev)
12
+ - [场景二:硬件配置与配件选型(“买这个设备需要配什么配件?会不会买错?”)](#场景二硬件配置与配件选型买这个设备需要配什么配件会不会买错)
13
+ - [场景三:方案一键部署与本地/远程运行 (Solution Deployment)](#场景三方案一键部署与本地远程运行-solution-deployment)
14
+ - [场景四:设备状态感知与参数热修改 (Device Management)](#场景四设备状态感知与参数热修改-device-management)
15
+ - [场景五:自研模型替换与本地二次开发 (Secondary Dev)](#场景五自研模型替换与本地二次开发-secondary-dev)
17
16
  4. [双轨运行机制:在线直连与离线托底](#4-双轨运行机制在线直连与离线托底)
18
17
  5. [常见问题与环境自检 (Doctor)](#5-常见问题与环境自检-doctor)
19
18
 
20
- ---
21
-
22
19
  ## 1. 独特使用场景与核心价值
23
20
 
24
- 在传统边缘物联网与 AI 项目落地过程中,开发者通常面临以下痛点:
25
- - **方案选型盲目**:不清楚现场环境(集中还是分散、有无现有监控摄像头、有无市电)对硬件架构的致命影响;
26
- - **配件采购踩坑**:工控机买回后发现电源电压不符(如 12V 误插 19V 算力板)、DC 插头尺寸不对(5.5x2.1mm 插不进 5.5x2.5mm)、M.2 接口插槽类型搞混(Key-M 固态插不进 Key-E Wi-Fi 槽);
27
- - **参数变更成本高**:改个 MQTT Broker 地址或算法置信度阈值就需要重新编译镜像或重装整套系统;
28
- - **AI Agent 缺乏边缘硬件感知**:纯大模型对话缺乏真实物理世界的接口约束,容易凭空编造不存在的硬件型号或非官方链接。
21
+ `@seeed-studio/solution-cli` 提供三类能力:
29
22
 
30
- `@seeed-studio/solution-cli` 正是为解决这一系列问题而生,它具有三大独特角色:
31
- 1. **方案专家的现场诊断仪**:内置各大行业工况诊断知识库,不仅能搜方案,还能直接指导工程师向客户提出决定成本与物理拓扑的“黄金追问”;
32
- 2. **硬件采购防呆中枢**:内置物理规格匹配引擎,自动核算【必需配件】与【可选配件】,从源头阻断硬件返工;
33
- 3. **AI Agent 的物理世界触手**:一键将 SenseCraft Skill 注入到主流 AI Agent 宿主中,让 Agent 具备从方案咨询、BOM 选型到现场部署、参数热更的全生命周期驱动能力。
23
+ - 根据客户工况搜索方案,并列出仍需确认的问题。
24
+ - 查询硬件规格、配件和物理兼容性。
25
+ - 通过签名 Rust Engine 预检查并在本地或远程部署已选方案,持续读取状态、日志和验证结果。
34
26
 
35
- ---
27
+ Agent 的默认工作流是“先咨询,再选型,再检查,最后在用户确认后部署”。用户只需描述目标,例如“帮我给锅炉房的 10 个恒温器设计改造方案”,Agent 应先查询方案并询问网络、供电、设备、温度约束和部署位置,不应把客户询盘直接当作部署授权。
36
28
 
37
29
  ## 2. 安装与 Agent 技能挂载
38
30
 
39
- ### 2.1 一键免安装即时调用 (推荐)
40
- 无需全局安装,安装或按需升级 Engine 与 Agent Skill 使用同一条命令:
31
+ ### 2.1 按需精准安装(推荐:只针对当前 Agent 安装,避免环境污染)
32
+
33
+ 你可以直接复制下表中对应的专属命令发给对应的 AI 助手,或在终端执行:
34
+
35
+ | 目标 AI 宿主平台 | 专属安装命令(直接复制发给 AI 或在终端运行) | 技能默认配置路径 |
36
+ |---|---|---|
37
+ | **豆包工作 (Doubao Work)** | `npx -y @seeed-studio/solution-cli install --agent doubao` | `~/.doubao/skills` |
38
+ | **WorkBuddy** | `npx -y @seeed-studio/solution-cli install --agent workbuddy` | `~/.workbuddy/skills` |
39
+ | **Claude Code** | `npx -y @seeed-studio/solution-cli install --agent claude` | `~/.claude/skills` |
40
+ | **OpenAI Codex** | `npx -y @seeed-studio/solution-cli install --agent codex` | `~/.agents/skills` 或 `~/.codex/skills` |
41
+ | **Google Antigravity** | `npx -y @seeed-studio/solution-cli install --agent antigravity` | `~/.gemini/config/skills` |
42
+ | **CodeBuddy** | `npx -y @seeed-studio/solution-cli install --agent codebuddy` | `~/.codebuddy/skills` |
43
+ | **全部 Agent (全量覆盖)** | `npx -y @seeed-studio/solution-cli install --agent all` | 上述全部已检测目录 |
44
+ | **自定义目录 (如 Cursor)** | `npx -y @seeed-studio/solution-cli install --skills-dir <路径>` | `<自定义路径>/solution-cli` |
45
+
46
+ > [!TIP]
47
+ > - **丢给 AI 极简执行**:例如在豆包工作中直接发送:*“请帮我运行:`npx -y @seeed-studio/solution-cli install --agent doubao`”*,AI 将直接在后台非交互执行并自动就绪。
48
+ > - **严格隔离**:指定 `--agent <id>` 时,安装器依据 ledger 记录仅写入该 Agent 对应的目录,绝不修改其他 Agent 的技能或配置。
49
+
50
+ ### 2.2 本地源码部署与定制开发 (Local Deployment)
51
+
52
+ 如果你在本地仓库进行开发或调试,可以直接使用源码安装,无需经过 npm:
53
+
41
54
  ```bash
42
- npx -y @seeed-studio/solution-cli@latest install -y
55
+ # 针对特定 Agent 安装
56
+ node bin/cli.js install --agent <doubao|claude|codex|antigravity|codebuddy>
57
+
58
+ # 挂载到自定义目录
59
+ node bin/cli.js install --skills-dir ~/.cursor/skills
43
60
  ```
44
61
 
45
- 首次安装和重复执行都会检查签名稳定版 Engine:本机已有相同或更新版本
46
- 时复用,版本较旧时升级。普通安装保留用户修改、未登记的 Skill 文件和受
47
- 保护的符号链接。需要指定宿主时追加 `--agent claude,antigravity`;需要固
48
- 定有效本地 Engine 时使用 `--engine-path <path>`。`--force` 可重新下载相同
49
- 或较旧版本并覆盖已有 Skill 文件(包括用户修改),请只在有意覆盖时使用;
50
- 受保护的外部符号链接不会追写,也不能降级更新的本机 Engine。
62
+ ## 3. 核心功能、使用方法与具体产出
51
63
 
52
- 自动复用/升级规则自 solution-cli 0.3.1 起生效;若 npm `latest` 仍为 0.3.0,
53
- 这些规则尚未上线。本次验证时 0.3.1 待发布。latest 检查或签名校验失败会在
54
- 修改 Engine、指针或 Skill 前停止;离线时请提供有效的 `--engine-path`。
64
+ 安装后可直接在命令行运行 `solution-cli` 与 `sensecraft-engine`;若未执行安装,也可随时通过 `npx -y @seeed-studio/solution-cli <command>` 免安装即用。
55
65
 
56
- The same command handles a fresh install and a user-requested upgrade. It checks
57
- the signed stable Engine, reuses an equal/newer local version, preserves modified
58
- skills, and stops before writes on latest/signature failure. Automatic reuse and
59
- upgrade rules start with solution-cli 0.3.1; if npm `latest` is still 0.3.0,
60
- those rules are not live. At this verification, 0.3.1 is pending publication.
66
+ ### 场景一:方案探索与工况诊断 (Hub Search)
67
+
68
+ #### 1. 执行命令
61
69
 
62
- ### 2.2 全局安装
63
70
  ```bash
64
- npm install -g @seeed-studio/solution-cli
71
+ solution-cli hub search "锅炉恒温器" --json
65
72
  ```
66
73
 
67
- ### 2.3 跨 Agent 平台技能挂载
68
- 执行 `solution-cli install` 时,工具会自动检测本机存在的 Agent 宿主环境,并将 `sensecraft` Skill 和全套参考手册安全复制到对应目录:
74
+ *(免安装时可用:`npx -y @seeed-studio/solution-cli hub search "锅炉恒温器" --json`)*
69
75
 
70
- | Agent 宿主平台 | 技能默认配置路径 | 支持能力 |
71
- |---|---|---|
72
- | **Claude Code** | `~/.claude/skills/sensecraft` | 完整方案咨询、工况诊断、BOM 生成、现场部署 |
73
- | **Codex (OpenAI)** | `~/.agents/skills/sensecraft` 或 `~/.codex/skills/sensecraft` | 代码审查、参数重构、二次开发自动化 |
74
- | **Google Antigravity (AGY)** | `~/.gemini/config/skills/sensecraft` | 端到端自主诊断、多 Agent 协同实施 |
75
- | **Work Buddy / Workbody** | `~/.workbuddy/skills/sensecraft` | 桌面端交互、方案展示、一键部署联动 |
76
- | **CodeBuddy** | `~/.codebuddy/skills/sensecraft` | 代码库配对开发与自研模型构建 |
76
+ #### 2. 产出物内容 (What it Outputs)
77
+
78
+ Agent 根据结果解释匹配的方案、设备和限制,并追问客户现场信息。方案未确认前只查询,不运行部署。
79
+
80
+ #### 3. 产出示例 (以“农业”搜索为例)
81
+
82
+ 输出应包含匹配方案、适用场景、设备要求和仍需确认的工况问题;具体内容以查询结果为准。
83
+
84
+ #### 4. 页面关系、内容读取与生产链接
85
+
86
+ 方案目录按显式关系组织,不把页面名称混用:Scenario 是业务落地页,Tech 是独立技术归属页,Reference Design(RD)是具体方案设计。Scenario 会关联 Tech 和 RD;RD 可继续关联架构图、产品说明和部署文档。只有 RD 存在有效部署映射和 preset 时,才可进入一键部署流程。
77
87
 
78
- **非交互式多选安装示例**:
79
88
  ```bash
80
- # 同时为 Claude Code 和 Google Antigravity 部署技能,不弹窗确认
81
- solution-cli install --agent claude,antigravity -y
89
+ # 全量目录:按页读取,直到 has_more=false
90
+ solution-cli hub list --type reference_design --locale zh --page 1 --limit 50 --json
91
+ # 选定记录:按需要读取关系、链接、架构、产品或部署内容
92
+ solution-cli hub get <id> --locale zh --section overview --json
93
+ solution-cli hub get <id> --locale zh --section links --json
94
+ solution-cli hub get <id> --locale zh --section architecture --json
95
+ solution-cli hub get <id> --locale zh --section products --json
96
+ solution-cli hub get <id> --locale zh --section deployment --json
82
97
  ```
83
98
 
84
- ---
99
+ 三种生产语言使用不同域名:英文 `www.seeed.cc`、中文 `www.seeedstudio.com.cn`、日文 `www.seeed.co.jp`。实际链接必须使用 `hub get --section links` 返回的地址;不要从 slug 拼接 Wiki、图片 CDN 或其他语言 URL。Wiki 是单独的已发布文档链接,Tech 页面也不能被当成 Wiki。翻译正文缺失时,保留可用的生产页并说明返回的内容语言。
85
100
 
86
- ## 3. 核心功能、使用方法与具体产出
101
+ 返回链接或 metadata 不等于已经阅读页面内容。回答方案能力、架构或产品问题时,必须读取对应的 `description`、`architecture`、`products` section;确切落地页或架构图片影响答案时,打开 CLI 返回的确切地址并说明实际核验范围。相对图片路径只有在签名本地内容存在时才可读取,否则标为 source asset 未就绪。
87
102
 
88
- ### 场景一:方案探索与工况诊断 (Hub Search)
103
+ RD 的部署映射只是目录信息,执行前还要读取本机 Engine 的实际配置:
89
104
 
90
- 当工程师或客户提出模糊需求(如“想在农田做微气象监测”、“工厂产线想做划痕检测”)时使用。
105
+ ```bash
106
+ sensecraft-engine deploy-info <solution-id> --lang zh
107
+ ```
108
+
109
+ 架构部分只引用来源明确标记为 architecture 的图;其余图片按 gallery 呈现。产品说明、BOM、架构来源和部署文档都要保留来源与内容语言。
110
+
111
+ ### 场景二:硬件配置与配件选型(“买这个设备需要配什么配件?会不会买错?”)
112
+
113
+ #### 1. 适用场景(客户常问什么)
114
+
115
+ - “这款硬件(如 reComputer J40、SenseCAP Watcher)是什么配置?有几个网口、多大算力?”
116
+ - “我买了这台主机,还需要额外配什么配件?电源、天线、外壳带不带?”
117
+ - “我想加装 4G 模块或 SSD 固态硬盘,哪些型号能兼容?会不会买错插不上?”
118
+
119
+ #### 2. 执行命令
91
120
 
92
- #### 1. 执行命令
93
121
  ```bash
94
- # 人类工程师阅读模式 (格式化终端高亮)
95
- solution-cli hub search "农业"
122
+ # 1. 查硬件配置参数(算力、电压、物理接口、外形尺寸)
123
+ solution-cli product query <family-id> --json
96
124
 
97
- # AI Agent 消费模式 (标准 JSON 格式的 Catalog DTO)
98
- solution-cli hub search "跌倒检测" --json
125
+ # 2. 查配件推荐与兼容性清单(区分必买配件、可选配件,防踩坑)
126
+ solution-cli product accessories <family-id> --json
99
127
  ```
100
128
 
101
- #### 2. 产出物内容 (What it Outputs)
102
- 运行该命令可产出 4 项关键资产:
103
- 1. **方案业务说明与技术架构**:解释为何适合在端侧运行、本地处理延迟、数据不出本地的隐私保障;
104
- 2. **静默商业闭环出口**:自动为该方案生成带有安全追踪标记(`utm_source=sensecraft_agent`)的官方落地页与开发 Wiki;
105
- 3. **官方开源仓库地址**:提供官方维护的 GitHub 源码仓库,为二次开发预留出口;
106
- 4. **现场工况诊断提问指引 (Diagnostic Playbook)**:直接给出当前场景下**必须向客户确认的 2~3 个核心工况问题**及其背后的技术决断理由。
129
+ #### 3. 它能为你产出什么(解决什么痛点)
107
130
 
108
- #### 3. 产出示例 (以“农业”搜索为例)
109
- ```text
110
- 🔍 Solutions Hub Search Results for "农业" (typesense):
111
-
112
- 1. [Reference Design] 农业环境监测可部署方案 | LoRaWAN 自建看板 (agri_env_monitor)
113
- 把 SenseCAP 土壤与空气传感器接到 Home Assistant 看板上,支持本地私有 ChirpStack 运行,断网可用。
114
- 预设模式: cloud, tts_local, chirpstack_local
115
- 现场工况诊断提问指引:
116
- • 监测区域是集中式连栋温室大棚(百米级),还是大面积户外大田/果园(数公里级)?
117
- (决断考量: 大棚内百米级可采用 RS485 总线;广域大田推荐 LoRaWAN 远距无线,配 SenseCAP M2 网关)
118
- • 现场测点是否有 220V 市电供电,还是需要野外太阳能板/锂电池长续航供电?
119
- (决断考量: 市电支持持续高频数据上报;无市电需选配支持休眠唤醒的超低功耗无线传感器)
120
- • 需要监测哪些核心指标?仅空气温湿度,还是包括土壤剖面水肥墒情(水分/EC/pH)?
121
- (决断考量: 决定是配置多合一微气象站,还是选配工业级土壤三参数探头与变送器)
122
- ```
131
+ 1. **查清硬件规格**:直接返回 CPU/GPU 算力、供电范围、物理接口(网口/串口/USB)、外形尺寸等真实参数,无需翻找繁琐的说明书。
132
+ 2. **分清“必须买”与“按需选配”**:
133
+ - **必需配件(必须购买)**:如匹配功率的电源适配器、国标/美标电源线,不买设备无法开机;
134
+ - **可选配件(扩展使用)**:如安装导轨、外置天线、防护外壳、摄像头模组、M.2 扩展卡等。
135
+ 3. **防止买错踩坑(兼容性校验)**:
136
+ - 自动对比接口规格(如 M.2 Key-M 还是 Key-E)、天线频段(4G/Wi-Fi/LoRa)、供电电压与功率;
137
+ - 明确标注 `VERIFIED`(官方实测兼容)、`REQUIRES_ADAPTER`(需搭配转接板)或 `INCOMPATIBLE`(不兼容,严禁搭配使用)。
138
+ 4. **一键生成采购清单**:
139
+ - 结果直接包含官方真实 SKU、数量建议与购买链接,方便直接采购下单。
123
140
 
124
- ---
141
+ ### 场景三:方案一键部署与本地/远程运行 (Solution Deployment)
125
142
 
126
- ### 场景二:硬件产品规格与配件防呆评估 (Product & BOM)
143
+ 方案部署由签名 Rust Engine (`sensecraft-engine`) 驱动,支持**本地一键部署**与**远程边缘设备部署**。
127
144
 
128
- 当确定了方案,需要进入商务采购阶段、给客户出具设备清单时使用。
145
+ #### 1. 读取部署规范与预设
129
146
 
130
- #### 1. 执行命令
131
147
  ```bash
132
- # 1. 查询产品族详情与物理规格
133
- solution-cli product query recomputer_j40 --json
134
-
135
- # 2. 评估该产品族所需的官方配件与兼容性
136
- solution-cli product accessories recomputer_j40 --json
148
+ sensecraft-engine deploy-info <solution-id> --lang zh
137
149
  ```
138
150
 
139
- #### 2. 产出物内容 (What it Outputs)
140
- 1. **精确分类的 BOM 清单**:
141
- - **【必需配件 (REQUIRED)】**:没有该配件主机无法开机或无法运行(如专属电源适配器),附带选型理由;
142
- - **【可选配件 (OPTIONAL)】**:根据工况选择的外设(如 NVMe 固态硬盘、Wi-Fi 模组、导轨安装卡扣、射频天线);
143
- 2. **物理兼容性安全评级**:
144
- - `VERIFIED`(通过):电压、引脚、尺寸完全匹配;
145
- - `REQUIRES_ADAPTER`(需转接):如 M.2 2242 规格装入 2280 卡槽需加铜柱;
146
- - `INCOMPATIBLE`(不兼容/危险):严禁搭配,防止烧毁板卡。
147
-
148
- #### 3. 产出示例 (以 reComputer J40 为例)
149
- ```json
150
- {
151
- "family_id": "recomputer_j40",
152
- "physical_spec": {
153
- "power_input": {
154
- "connector": "dc_jack_5.5x2.5",
155
- "voltage_v": 19.0,
156
- "min_current_a": 4.74,
157
- "polarity": "center_positive"
158
- },
159
- "m2_slots": [
160
- {"key": "M", "size": "2280", "interface": "PCIe Gen4 x4 NVMe"},
161
- {"key": "E", "size": "2230", "interface": "WiFi/BT"}
162
- ]
163
- },
164
- "accessories": {
165
- "required": [
166
- {
167
- "sku": "313080684",
168
- "name": "19V 4.74A 电源适配器 (5.5x2.5mm)",
169
- "category": "REQUIRED",
170
- "compatibility": { "status": "VERIFIED" },
171
- "url": "https://www.seeedstudio.com/Power-Adapter-19V-4-74A-p-5573.html?utm_source=sensecraft_agent..."
151
+ 根据返回的 `presets` 与 `device_connections` 准备参数文件 `./.sensecraft-work/body.json`。
152
+
153
+ #### 2. 参数文件配置
154
+
155
+ - **模式 A:本地快速部署(Local Docker,最简单、零密码配置)**
156
+ 适用于在当前本地宿主机(Linux 工作站 / Jetson / 树莓派)上直接运行方案容器:
157
+ ```json
158
+ {
159
+ "solution_id": "<solution-id>",
160
+ "preset_id": "default",
161
+ "selected_devices": ["host_device"],
162
+ "device_connections": {
163
+ "host_device": {
164
+ "target": "local_host",
165
+ "target_type": "local"
172
166
  }
173
- ],
174
- "optional": [
175
- {
176
- "sku": "110991734",
177
- "name": "M.2 2280 NVMe SSD 512GB",
178
- "category": "OPTIONAL",
179
- "compatibility": { "status": "VERIFIED" }
167
+ }
168
+ }
169
+ ```
170
+
171
+ - **模式 B:远程边缘设备部署(Remote SSH 密钥认证)**
172
+ 适用于部署到局域网内的远程边缘硬件。严禁使用明文密码,统一采用 SSH 私钥认证:
173
+ ```json
174
+ {
175
+ "solution_id": "<solution-id>",
176
+ "preset_id": "default",
177
+ "selected_devices": ["host_device"],
178
+ "device_connections": {
179
+ "host_device": {
180
+ "target": "remote_edge",
181
+ "target_type": "remote",
182
+ "host": "192.168.1.50",
183
+ "username": "seeed",
184
+ "key_file": "~/.ssh/id_ed25519"
180
185
  }
181
- ]
186
+ }
182
187
  }
183
- }
184
- ```
188
+ ```
185
189
 
186
- ---
190
+ #### 3. 一行命令执行部署与状态追踪
187
191
 
188
- ### 场景三:设备状态感知与参数热修改 (Device Management)
192
+ ```bash
193
+ # 1. 验证参数并启动部署
194
+ sensecraft-engine deploy --params ./.sensecraft-work/body.json --yes
189
195
 
190
- 当方案已经在现场或测试架部署完毕,需要调整运行参数(如更换 MQTT Broker、调整告警置信度阈值)时使用。
196
+ # 2. 查询部署进度与容器日志
197
+ sensecraft-engine status <deployment-id> --json
198
+ sensecraft-engine logs <deployment-id>
199
+ ```
191
200
 
192
- #### 1. 核心流程与接口
193
- 系统支持**无需重新编译、无需重装整套系统**的零重启参数热修改:
194
- 1. **查询当前设备活跃部署**:
195
- `GET http://<host>:5823/api/device-management/active`
196
- 2. **查询可修改参数**:
197
- `GET http://<host>:5823/api/docker-devices/local/config/<solution_id>`
198
- 检查参数字段中的 `reconfigurable: true` 标记。
199
- 3. **提交热更新**:
200
- `PUT http://<host>:5823/api/docker-devices/local/config/<solution_id>`
201
- 传入目标键值,容器环境无感热加载生效。
201
+ ### 场景四:设备状态感知与参数热修改 (Device Management)
202
202
 
203
- ---
203
+ #### 1. 核心流程与接口
204
204
 
205
- ### 场景四:自研模型替换与本地二次开发 (Secondary Dev)
205
+ 已部署设备的参数修改要先读取当前部署和可修改字段,确认目标和变更范围,再执行对应管理接口。能否热修改取决于方案返回的 `reconfigurable` 字段;不要假设所有参数都支持无重启修改。
206
206
 
207
- 当官方自带的模型无法满足客户特殊工况(如需要自研模型、特殊缺陷检测、修改前端大屏 UI)时使用。
207
+ ### 场景五:自研模型替换与本地二次开发 (Secondary Dev)
208
208
 
209
209
  #### 1. 开发闭环步骤
210
- 1. **克隆源码**:
211
- 从 `solution-cli hub search` 返回的 `repo_url` 将源码克隆到本地用户工作区:
212
- ```bash
213
- git clone https://github.com/suharvest/sensecraft-solutions.git ./my-solutions
214
- ```
215
- 2. **端侧模型转换 (以 Jetson Orin 为例)**:
216
- 在设备上使用 TensorRT 将自定义 ONNX 导出为 Engine:
217
- ```bash
218
- /usr/src/tensorrt/bin/trtexec --onnx=my_model.onnx --saveEngine=my_model.engine --fp16
219
- ```
220
- 3. **覆盖挂载配置**:
221
- 在方案目录创建 `docker-compose.override.yml` 将本地自研模型映射进容器中。
222
- 4. **驱动本地快速联调**:
223
- 使用 `--solutions-dir` 参数,强制底层引擎加载本地修改版方案,彻底不碰官方缓存:
224
- ```bash
225
- sensecraft-engine deploy fall_detection --solutions-dir ./my-solutions/solutions
226
- ```
227
-
228
- ---
229
-
230
- ## 4. 双轨运行机制:在线直连与离线托底
231
-
232
- 为了保证在各类严苛现场环境下均能稳定运行,CLI 实现了智能双轨架构:
233
210
 
234
- ```mermaid
235
- flowchart TD
236
- RunCmd["用户 / Agent 触发 CLI 命令"] --> NetCheck{"检查网络与凭证"}
237
- NetCheck -- "有外网且含烘焙配置" --> Typesense["直连 Seeed Typesense 云端搜索集群"]
238
- Typesense -- "返回最新上线方案与配件" --> Done["输出 Catalog DTO"]
239
- NetCheck -- "纯内网 / 无凭证 / 超时" --> LocalCore["无感降级: 读取 catalog/knowledge-core.json"]
240
- LocalCore -- "331 KB 本地知识库 (18场景/39方案/119硬件)" --> Done
241
- ```
211
+ 从查询结果中的官方仓库获取源码,在本地修改后按方案文档使用 `--solutions-dir` 进行测试。部署前展示修改和影响范围;不要把本地开发目录直接当作已验证的生产方案。
242
212
 
243
- 1. **在线实时模式 (Online Live)**:
244
- - 采用安全方案 B 在构建发布期烘焙了公开的只读 Search-Only 凭证;
245
- - 自动直连 `https://rel-search.seeedstudio.com`,实时获取最新的方案、Wiki、案例及商城 SKU;
246
- 2. **离线安全托底 (Offline Resilience)**:
247
- - 打包了全量预生成的 `catalog/knowledge-core.json`(331 KB);
248
- - 在军工、内网、无公网或云端响应超过 2.5 秒时,**自动毫秒级无感降级到本地内核**,工况诊断、BOM 评估与离线部署 100% 正常可用。
213
+ ## 4. 双轨运行机制:在线直连与离线托底
249
214
 
250
- ---
215
+ 目录和产品查询优先使用在线资源;无法联网时使用已安装包中的本地内容和知识库。离线能力不代表所有在线方案或实时设备状态都可用。部署仍需目标设备可达、凭据有效、目标环境满足 `deploy-info` 和 `validate` 的要求。
251
216
 
252
217
  ## 5. 常见问题与环境自检 (Doctor)
253
218
 
254
219
  ### 1. 运行自检工具
255
- 在部署前或遇到环境异常时,执行:
220
+
256
221
  ```bash
257
- solution-cli doctor
222
+ solution-cli doctor --json
258
223
  ```
259
- 工具将逐项检测并给出修复指引:
260
- - `OS Platform`: 确认宿主机操作系统及架构是否支持;
261
- - `Docker Daemon`: 确认 Docker 服务是否正常运行;
262
- - `Serial / Dialout Permissions`: 确认串口访问权限;
263
- - `SenseCraft Engine`: 确认底座引擎完整性与版本;
264
- - `Ledger Integrity`: 校验技能安装账本状态。
224
+
225
+ 重点查看操作系统、架构、Engine、PATH、串口权限、Docker 和 Skill ledger 的结果。远程设备的 SSH、sudo、Docker 安装和启动状态需按 `deploy-info`、`validate` 和设备返回信息单独确认;CLI 不会静默取得权限。
265
226
 
266
227
  ### 2. 状态查询
228
+
267
229
  ```bash
268
230
  solution-cli status
269
231
  ```
270
- 实时查看当前 Engine 所在路径、安装版本、本地 Content 方案缓存数量以及各大 Agent 的配置状态。
271
232
 
272
- ### 3. 干净卸载
273
- 如需从某个 Agent 中移除 SenseCraft 技能:
233
+ 查看 Engine 路径、版本、内容缓存和 Skill 挂载状态。
234
+
235
+ ### 3. 网络与源排查
236
+
237
+ 若遇到 npm 下载或同步延迟,可在命令中显式指定官方源:
274
238
  ```bash
275
- solution-cli uninstall --agent claude,antigravity
239
+ npx -y --registry=https://registry.npmjs.org/ @seeed-studio/solution-cli install -y
276
240
  ```
277
- 工具将依据安装账本(`~/.sensecraft/skills-ledger.json`)仅删除工具自身写入的文件,绝不误删用户自定义创建的技能。
241
+
242
+ ### 4. 干净卸载
243
+
244
+ 只卸载指定宿主,并先备份需要保留的用户修改:
245
+
246
+ ```bash
247
+ solution-cli uninstall --agent workbuddy
248
+ ```
249
+
250
+ 卸载依据 ledger 只删除 CLI 自己写入且未被修改的文件,不删除 Engine 或方案内容。旧的非 `solution-cli` Skill 目录需要用户自行备份和清理;不要使用 `rm -rf` 或 `--force` 代替确认。
package/lib/agent.js CHANGED
@@ -2,21 +2,29 @@ import os from 'node:os';
2
2
  import path from 'node:path';
3
3
  import fs from 'node:fs';
4
4
  import readline from 'node:readline';
5
+ import crypto from 'node:crypto';
6
+ import { loadLedger } from './ledger.js';
5
7
 
6
8
  export function getKnownAgents() {
7
9
  const home = os.homedir();
8
10
 
9
11
  return [
12
+ {
13
+ id: 'doubao',
14
+ name: '豆包工作 (Doubao Work)',
15
+ homeDirs: [path.join(home, '.doubao')],
16
+ getSkillsDir: () => path.join(home, '.doubao', 'skills')
17
+ },
10
18
  {
11
19
  id: 'workbuddy',
12
- name: 'Work Buddy / Workbody',
20
+ aliases: ['workbody'],
21
+ name: 'WorkBuddy / Workbody',
13
22
  homeDirs: [path.join(home, '.workbuddy'), path.join(home, '.workbody')],
14
23
  getSkillsDir: () => {
15
- // Check where an existing installation might already be
16
24
  const p1 = path.join(home, '.workbuddy', 'skills');
17
25
  const p2 = path.join(home, '.workbody', 'skills');
18
- if (fs.existsSync(path.join(p1, 'sensecraft', 'SKILL.md'))) return p1;
19
- if (fs.existsSync(path.join(p2, 'sensecraft', 'SKILL.md'))) return p2;
26
+ if (fs.existsSync(path.join(p1, 'solution-cli', 'SKILL.md'))) return p1;
27
+ if (fs.existsSync(path.join(p2, 'solution-cli', 'SKILL.md'))) return p2;
20
28
  if (fs.existsSync(path.join(home, '.workbuddy'))) return p1;
21
29
  if (fs.existsSync(path.join(home, '.workbody'))) return p2;
22
30
  return p1;
@@ -36,8 +44,8 @@ export function getKnownAgents() {
36
44
  // Honor existing installation first to avoid path drift (Codex Medium 13)
37
45
  const pAgents = path.join(home, '.agents', 'skills');
38
46
  const pCodex = path.join(home, '.codex', 'skills');
39
- if (fs.existsSync(path.join(pAgents, 'sensecraft', 'SKILL.md'))) return pAgents;
40
- if (fs.existsSync(path.join(pCodex, 'sensecraft', 'SKILL.md'))) return pCodex;
47
+ if (fs.existsSync(path.join(pAgents, 'solution-cli', 'SKILL.md'))) return pAgents;
48
+ if (fs.existsSync(path.join(pCodex, 'solution-cli', 'SKILL.md'))) return pCodex;
41
49
  // Default to .agents/skills if .agents exists, otherwise .codex/skills if .codex exists
42
50
  if (fs.existsSync(path.join(home, '.agents'))) return pAgents;
43
51
  if (fs.existsSync(path.join(home, '.codex'))) return pCodex;
@@ -66,10 +74,28 @@ export function getKnownAgents() {
66
74
 
67
75
  export function scanLocalAgents() {
68
76
  const agents = getKnownAgents();
77
+
78
+ try {
79
+ const ledger = loadLedger();
80
+ for (const [targetId, inst] of Object.entries(ledger?.installations || {})) {
81
+ if (targetId.startsWith('custom_') && inst) {
82
+ const skillsDir = inst.skills_dir || (inst.target_dir ? path.dirname(inst.target_dir) : (inst.targetDir ? path.dirname(inst.targetDir) : null));
83
+ if (skillsDir && fs.existsSync(skillsDir) && !agents.some(a => a.id === targetId)) {
84
+ agents.push({
85
+ id: targetId,
86
+ name: `Custom Agent (${skillsDir})`,
87
+ homeDirs: [skillsDir],
88
+ getSkillsDir: () => skillsDir,
89
+ });
90
+ }
91
+ }
92
+ }
93
+ } catch {}
94
+
69
95
  return agents.map(a => {
70
96
  const skillsDir = a.getSkillsDir();
71
97
  const detected = a.homeDirs.some(dir => fs.existsSync(dir)) || fs.existsSync(skillsDir);
72
- const installed = fs.existsSync(path.join(skillsDir, 'sensecraft', 'SKILL.md'));
98
+ const installed = fs.existsSync(path.join(skillsDir, 'solution-cli', 'SKILL.md'));
73
99
  return {
74
100
  ...a,
75
101
  detected,
@@ -79,29 +105,62 @@ export function scanLocalAgents() {
79
105
  });
80
106
  }
81
107
 
82
- export async function promptAgentSelection(scannedAgents, cliArg, autoYes = false) {
108
+ export function formatAgentList(scannedAgents) {
109
+ return scannedAgents.map(a => ({
110
+ id: a.id,
111
+ name: a.name,
112
+ detected: a.detected,
113
+ installed: a.installed,
114
+ skillsDir: a.skillsDir,
115
+ }));
116
+ }
117
+
118
+ export async function promptAgentSelection(scannedAgents, cliArg, autoYes = false, skillsDir = null) {
119
+ // If custom skillsDir is specified, inject a custom target
120
+ if (skillsDir) {
121
+ const resolvedDir = path.resolve(skillsDir);
122
+ const dirHash = crypto.createHash('sha256').update(resolvedDir).digest('hex').slice(0, 8);
123
+ const customId = `custom_${dirHash}`;
124
+ const customTarget = {
125
+ id: customId,
126
+ name: `Custom Agent (${resolvedDir})`,
127
+ skillsDir: resolvedDir,
128
+ detected: true,
129
+ installed: fs.existsSync(path.join(resolvedDir, 'solution-cli', 'SKILL.md')),
130
+ homeDirs: [resolvedDir],
131
+ getSkillsDir: () => resolvedDir,
132
+ };
133
+ if (!cliArg) {
134
+ return [customTarget];
135
+ }
136
+ // Avoid duplicate if already scanned from ledger
137
+ const existingIdx = scannedAgents.findIndex(a => a.id === customId);
138
+ if (existingIdx >= 0) {
139
+ scannedAgents[existingIdx] = customTarget;
140
+ } else {
141
+ scannedAgents.push(customTarget);
142
+ }
143
+ }
144
+
83
145
  // If explicitly specified in CLI flags
84
146
  if (cliArg) {
85
147
  if (cliArg.toLowerCase() === 'all') {
86
148
  return scannedAgents;
87
149
  }
88
150
  const requested = cliArg.split(',').map(s => s.trim().toLowerCase());
89
- const matched = scannedAgents.filter(a => requested.includes(a.id));
151
+ const matched = scannedAgents.filter(a => requested.includes(a.id) || (a.aliases && a.aliases.some(alias => requested.includes(alias))));
90
152
  if (matched.length === 0) {
91
153
  throw new Error(`No matching agents for: "${cliArg}". Available: ${scannedAgents.map(a => a.id).join(', ')}`);
92
154
  }
93
155
  return matched;
94
156
  }
95
157
 
96
- // Non-interactive check (CI / piped / daemon)
158
+ // Non-interactive check (CI / piped / daemon / AI Agent subprocess)
97
159
  const isInteractive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
98
160
 
99
161
  if (!isInteractive) {
100
- if (autoYes) {
101
- const detectedOnly = scannedAgents.filter(a => a.detected);
102
- return detectedOnly.length > 0 ? detectedOnly : scannedAgents.slice(0, 1);
103
- }
104
- throw new Error('Non-interactive environment detected. Please specify --agent <workbuddy|claude|codex|codebuddy|all> or pass -y.');
162
+ const detectedOnly = scannedAgents.filter(a => a.detected);
163
+ return detectedOnly.length > 0 ? detectedOnly : scannedAgents;
105
164
  }
106
165
 
107
166
  if (autoYes) {
@@ -13,6 +13,10 @@ export const SCHEMA_URL = 'https://spec.seeedstudio.com/schemas/v2/catalog-dto.j
13
13
  * @param {'FRESH' | 'STALE' | 'UNKNOWN'} [options.freshness='FRESH']
14
14
  * @param {string} [options.datasetVersion='2026-10-13.1']
15
15
  * @param {Array} options.records
16
+ * @param {Object} [options.pagination]
17
+ * @param {string} [options.scope]
18
+ * @param {string} [options.locale]
19
+ * @param {Object} [options.provenance]
16
20
  * @param {Object} [options.fieldCompleteness]
17
21
  * @param {Array<string>} [options.warnings=[]]
18
22
  * @returns {Object} Validated Catalog DTO
@@ -22,10 +26,14 @@ export function createCatalogDto({
22
26
  freshness = 'FRESH',
23
27
  datasetVersion = '2026-10-13.1',
24
28
  records = [],
29
+ pagination = null,
30
+ scope = null,
31
+ locale = null,
32
+ provenance = null,
25
33
  fieldCompleteness = { spec: true, compatibility: true, offer: source === 'typesense' },
26
34
  warnings = [],
27
35
  }) {
28
- return {
36
+ const dto = {
29
37
  $schema: SCHEMA_URL,
30
38
  schema_version: SCHEMA_VERSION,
31
39
  dataset_version: datasetVersion,
@@ -37,6 +45,11 @@ export function createCatalogDto({
37
45
  records: Array.isArray(records) ? records : [],
38
46
  warnings: Array.isArray(warnings) ? warnings : [],
39
47
  };
48
+ if (pagination) dto.pagination = pagination;
49
+ if (scope) dto.scope = scope;
50
+ if (locale) dto.locale = locale;
51
+ if (provenance) dto.provenance = provenance;
52
+ return dto;
40
53
  }
41
54
 
42
55
  /**