@seeed-studio/solution-cli 0.3.0 → 0.3.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seeed-studio/solution-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Zero-friction installer and CLI runner for SenseCraft Engine and AI Agent Skills (Work Buddy, Claude Code, Codex, CodeBuddy)",
5
5
  "type": "module",
6
6
  "main": "./lib/installer.js",
@@ -16,7 +16,7 @@ Do NOT read all reference files at once. Determine the user's workflow state and
16
16
  | **DISCOVERY / CONSULT**<br>“我想做防跌倒监控”、“有智慧农场方案吗” | `references/consult-and-select.md` | `solution-cli hub search "<keyword>" --json` | **DO NOT run deploy**; user is exploring scenarios and has not confirmed hardware. |
17
17
  | **PROCUREMENT / VERIFY_BOM**<br>“买什么硬件?”、“J4012 需要配什么配件?” | `references/hardware-bom.md` | `solution-cli product accessories <id> --json` | **DO NOT fabricate** third-party SKUs or prices. Always distinguish REQUIRED vs OPTIONAL accessories. |
18
18
  | **ONBOARDING / PRECHECK**<br>“设备到了,插上了网线/USB”、“环境自检” | `references/diagnose.md` | `solution-cli doctor` / `sensecraft-engine device scan` | Freeze hardware requirements into DeploymentLockfile before proceeding to apply. |
19
- | **DEPLOYING / APPLY**<br>“开始安装”、“部署 fall_detection” | `references/deploy.md` | `sensecraft-engine deploy --solution <id>` | **DEPLOYMENT CRITICAL SECTION**: Zero external commercial queries allowed during apply. |
19
+ | **DEPLOYING / APPLY**<br>“开始安装”、“部署 fall_detection” | `references/deploy.md` | `sensecraft-engine deploy <id>` | **DEPLOYMENT CRITICAL SECTION**: Zero external commercial queries allowed during apply. |
20
20
  | **MANAGE / RECONFIG**<br>“改一下 MQTT 地址”、“查看已安装应用”、“重启服务”、“修改配置” | `references/device-management.md` | `curl BASE/api/docker-devices/local/config/<id>` | **Check before write**: Only alter `reconfigurable: true` fields; check current value before modifying. |
21
21
  | **CUSTOMIZE / SECONDARY_DEV**<br>“我想改源码”、“换成自研模型”、“改前端看板”、“GitHub 仓库” | `references/secondary-development.md` | `git clone <repo_url>` / `sensecraft-engine --solutions-dir` | **Never edit cached content**: Clone to user workspace, pair-program, test locally with `--solutions-dir`. |
22
22
  | **TROUBLESHOOTING**<br>“部署报错”、“黑屏”、“无视频流” | `references/error-catalog.md` | `sensecraft-engine logs` / `solution-cli product verify-compatibility` | Max 3 fix-and-retry rounds. Follow local auto-patching rule. |
@@ -78,7 +78,7 @@ daemon is a host prerequisite, not evidence that a deployment has passed.
78
78
  you checked, what you changed). Transient registry or network errors follow
79
79
  the backoff rule in `references/deploy.md` §6 and do not use up a round.
80
80
  4. **Preserving official cache & Local auto-patching**: Never edit files directly under the official content cache directory (`~/.sensecraft/content/`). When fixing a solution-level bug (timeout too short, wrong port/env var, minor syntax/transfer glitch, broken health check):
81
- - In CLI / Engine mode: copy the solution from `~/.sensecraft/content/solutions/<id>` into `./.sensecraft-work/solutions/<id>`, apply the minimal fix in that copy. **Crucial engine switch step**: Because an existing engine daemon instance retains its initial solution directory in memory, you MUST stop the running instance first: `sensecraft-engine daemon stop`. Then re-run deployment with `--solutions-dir ./.sensecraft-work/solutions` so the fresh engine instance picks up the patched files. Show the user the patch diff.
81
+ - In CLI / Engine mode: copy the solution from `~/.sensecraft/content/solutions/<id>` into `./.sensecraft-work/solutions/<id>`, apply the minimal fix in that copy. Then re-run deployment with `sensecraft-engine deploy <id> --solutions-dir ./.sensecraft-work/solutions` so the engine picks up the patched files. Show the user the patch diff.
82
82
  - If running with the Desktop App: use the app's edit copy mechanism (`references/app-only.md` §4).
83
83
  5. **Reading output:** read the CLI's JSON output directly; it is small. If a
84
84
  filter is needed, use `jq` only when it is already installed. Do not start
@@ -103,7 +103,7 @@ daemon is a host prerequisite, not evidence that a deployment has passed.
103
103
  asset reuse, power/cabling, inspection speed/materials) to help the user converge
104
104
  on the optimal hardware architecture and budget.
105
105
 
106
- ## Step 0 — Install the engine and the solutions (every task)
106
+ ## Step 0 — Install the engine and the solutions (when needed)
107
107
 
108
108
  1. Check whether it is installed: `sensecraft-engine --version`. If the command
109
109
  is not found, also try `~/.sensecraft/bin/sensecraft-engine --version`
@@ -121,14 +121,28 @@ daemon is a host prerequisite, not evidence that a deployment has passed.
121
121
  command and stop; do not install packages or start another interpreter.
122
122
  `minisign` is required to verify the signed release manifest; Unix `jq` is
123
123
  required by the shell installer to read it.
124
- 3. Not installed → install it together with the solutions (ask the user first,
125
- it downloads a program):
124
+ 3. If it is not installed, install it together with the solutions (ask the user
125
+ first, it downloads a program). If the user explicitly asks to upgrade or
126
+ reinstall, use the same solution-cli command; do not reinstall on every
127
+ deployment:
126
128
 
127
129
  **Recommended (Zero-friction via solution-cli, auto-detects existing app & agents)**:
128
130
  ```bash
129
- npx @seeed-studio/solution-cli install -y
131
+ npx -y @seeed-studio/solution-cli@latest install -y
130
132
  ```
131
133
 
134
+ The command checks the signed stable Engine on fresh and repeat runs, reuses
135
+ an equal or newer local version, and upgrades an older one. It preserves
136
+ modified/unregistered skills and protected symlinks. Add `--agent ...` for an
137
+ explicit agent selection or `--engine-path <path>` for a valid custom pin.
138
+ `--force` can re-download equal/older versions and overwrite existing skill
139
+ files, including user modifications; use it only when that overwrite is
140
+ intended. Protected external symlinks are not followed, and it never
141
+ downgrades a newer discovered Engine. Automatic upgrade rules start with
142
+ solution-cli 0.3.1; if npm `latest` is still 0.3.0, those rules are not live.
143
+ At this verification, 0.3.1 is pending publication. Latest/signature failure
144
+ stops before writes; offline use requires a valid explicit local Engine path.
145
+
132
146
  **Fallback (Standalone shell script when Node.js is not present)**:
133
147
  ```bash
134
148
  curl --compressed -fsSL https://sensecraft-statics.seeed.cc/solution-app/engine/install.sh | sh -s -- --with-content
@@ -162,9 +176,8 @@ daemon is a host prerequisite, not evidence that a deployment has passed.
162
176
  list` or `deploy-info` exits with code 3 when no usable resource/solution
163
177
  directory is available and tells you to run `content pull`. If a usable
164
178
  directory exists but the requested solution ID is unknown, the query exits
165
- with code 2. After `content pull` / `update`, if an engine instance is
166
- already running it keeps the solutions it loaded at start: run
167
- `sensecraft-engine daemon stop` when no deployment is running.
179
+ with code 2. After `content pull` / `update`, newly downloaded or updated
180
+ solutions are available to subsequent deployment and query commands.
168
181
  5. Device pre-checks on this computer: `sensecraft-engine doctor --json`. Each
169
182
  check has `status` (`ok` / `warn` / `fail`) and a `fix` command. Show the
170
183
  user any `fail` and its `fix`; running a `fix` changes this computer and
@@ -22,50 +22,57 @@
22
22
  当设备已经部署运行,用户希望修改 L1 参数(如更改 MQTT 目标服务器)时:
23
23
 
24
24
  ### 步骤一:获取运行时信息与当前部署列表
25
- 读取运行环境指针(从 `~/.sensecraft/runtime.json` 获取 `base_url`,默认为 `http://127.0.0.1:3260`):
25
+ 读取运行环境指针并校验服务健康(桌面端每次启动分配随机端口并写入 `~/.sensecraft/runtime.json`;源码开发环境固定为 `http://127.0.0.1:3260`):
26
26
  ```bash
27
+ # 解析运行时 BASE_URL 并校验连通性
28
+ BASE_URL=$(jq -r '.base_url // "http://127.0.0.1:3260"' ~/.sensecraft/runtime.json 2>/dev/null || echo "http://127.0.0.1:3260")
29
+ curl -sf "$BASE_URL/api/health" > /dev/null || { echo "SenseCraft 服务未在 $BASE_URL 就绪"; exit 1; }
30
+
27
31
  # 查询当前设备上活跃运行的方案实例
28
- curl -s "http://127.0.0.1:3260/api/device-management/active"
32
+ curl -s "$BASE_URL/api/device-management/active"
29
33
  ```
30
34
  - 输出包含 `solution_id`、`device_id`、`status`(running/stopped)、`deployed_at` 及运行 URL。
31
35
 
32
36
  ### 步骤二:读取可配参数及当前值(Get Config)
33
37
  ```bash
34
38
  # 本地 Docker 部署实例
35
- curl -s "http://127.0.0.1:3260/api/docker-devices/local/config/<solution_id>"
39
+ curl -s "$BASE_URL/api/docker-devices/local/config/<solution_id>"
36
40
 
37
41
  # 远程设备实例(通过 SSH 提取运行态值)
38
- curl -s -X POST "http://127.0.0.1:3260/api/docker-devices/config/<solution_id>" \
42
+ curl -s -X POST "$BASE_URL/api/docker-devices/config/<solution_id>" \
39
43
  -H "Content-Type: application/json" \
40
44
  -d '{"connection": {"host": "<ip>", "username": "<user>", "password": "<pwd>"}}'
41
45
  ```
42
46
  - 检查返回的 `fields` 列表:
43
- - 确认用户想要修改的参数是否存在(`field.id`);
47
+ - 确认用户想要修改的参数是否存在(`field.id`,如 `mqtt_broker`、`mqtt_port`);
44
48
  - 查看当前已生效的数值(`field.current_value`);
45
49
  - 核对其校验规则(`field.validation`)。
46
50
 
47
51
  ### 步骤三:验证并提交新参数(Update Config)
52
+ > [!IMPORTANT]
53
+ > `values` 字典中的 key 必须使用步骤二返回的 `field.id`(例如 `mqtt_broker`、`mqtt_port`),严禁使用环境变量大写名(如 `MQTT_BROKER_HOST`),否则会被后端配置解析器静默忽略。
54
+
48
55
  向用户确认修改后,发起热更新请求:
49
56
  ```bash
50
- # 本地 Docker 部署实例更新
51
- curl -s -X PUT "http://127.0.0.1:3260/api/docker-devices/local/config/<solution_id>" \
57
+ # 本地 Docker 部署实例更新(使用从 GET 返回查得的 field.id)
58
+ curl -s -X PUT "$BASE_URL/api/docker-devices/local/config/<solution_id>" \
52
59
  -H "Content-Type: application/json" \
53
60
  -d '{
54
61
  "values": {
55
- "MQTT_BROKER_HOST": "192.168.1.200",
56
- "MQTT_BROKER_PORT": 1883
62
+ "mqtt_broker": "192.168.1.200",
63
+ "mqtt_port": 1883
57
64
  }
58
65
  }'
59
66
 
60
67
  # 远程设备实例更新
61
- curl -s -X PUT "http://127.0.0.1:3260/api/docker-devices/config/<solution_id>" \
68
+ curl -s -X PUT "$BASE_URL/api/docker-devices/config/<solution_id>" \
62
69
  -H "Content-Type: application/json" \
63
70
  -d '{
64
- "values": { "MQTT_BROKER_HOST": "192.168.1.200" },
71
+ "values": { "mqtt_broker": "192.168.1.200" },
65
72
  "connection": { "host": "<ip>", "username": "<user>", "password": "<pwd>" }
66
73
  }'
67
74
  ```
68
- - **后端自动执行**:模板替换 ➔ 生成新的 env ➔ `docker compose up -d` 重新创建受影响容器 ➔ 更新部署 manifest 记录。
75
+ - **后端自动执行**:根据 `field.id` 执行模板替换 ➔ 生成新的 env ➔ `docker compose up -d` 重新创建受影响容器 ➔ 更新部署 manifest 记录。
69
76
  - **无需整机重装**,数据卷与现有文件完全保留。
70
77
 
71
78
  ---
@@ -74,16 +81,41 @@ curl -s -X PUT "http://127.0.0.1:3260/api/docker-devices/config/<solution_id>" \
74
81
 
75
82
  当用户要求“重启服务”、“暂停运行”或“更新容器镜像”时:
76
83
 
84
+ ### 本地 Docker 部署实例(无凭据要求)
77
85
  ```bash
78
86
  # 执行 start / stop / restart / update
79
- curl -s -X POST "http://127.0.0.1:3260/api/device-management/<deployment_id>/action" \
87
+ curl -s -X POST "$BASE_URL/api/device-management/<deployment_id>/action" \
80
88
  -H "Content-Type: application/json" \
81
89
  -d '{
82
90
  "action": "restart",
83
91
  "device_id": "<step_id>"
84
92
  }'
85
93
  ```
94
+
95
+ ### 远程设备实例(必须显式携带 SSH 认证凭据)
96
+ 远程设备(Jetson / Raspberry Pi 等)通过 SSH 协议由底层执行容器编排动作。由于后端安全机制禁用了 SSH-agent 与自动公钥搜寻,且不持久化保存设备明文密码,因此远程操作**必须向用户获取并显式传入 `password` 或 `key_file`**:
97
+
98
+ ```bash
99
+ # 远程实例 - 密码认证
100
+ curl -s -X POST "$BASE_URL/api/device-management/<deployment_id>/action" \
101
+ -H "Content-Type: application/json" \
102
+ -d '{
103
+ "action": "restart",
104
+ "device_id": "<step_id>",
105
+ "password": "<ssh_password>"
106
+ }'
107
+
108
+ # 远程实例 - 私钥文件认证(支持 ~/.ssh/ 下的私钥路径)
109
+ curl -s -X POST "$BASE_URL/api/device-management/<deployment_id>/action" \
110
+ -H "Content-Type: application/json" \
111
+ -d '{
112
+ "action": "restart",
113
+ "device_id": "<step_id>",
114
+ "key_file": "~/.ssh/id_rsa"
115
+ }'
116
+ ```
86
117
  - `action` 支持:`start`(启动)、`stop`(停止)、`restart`(重启)、`update`(拉取最新镜像并重启)。
118
+ - **判定规则**:从步骤一 `/api/device-management/active` 的返回值中检查目标实例的 `host` 字段。若 `host` 不为 `localhost` 或 `127.0.0.1`,即属于远程设备,发起 action 请求前必须准备好认证凭据。
87
119
 
88
120
  ---
89
121
 
@@ -81,7 +81,7 @@ three classes:
81
81
  | Class | Example | What you do |
82
82
  |---|---|---|
83
83
  | **Device / environment** | port taken, disk full, Docker missing, network blocked, wrong password, serial permission | Propose the exact fix commands → user OK → run them → retry |
84
- | **Solution configuration** | timeout too short, wrong port/env in compose, health check endpoint 404, minor syntax/transfer glitch | **CLI / Engine mode (Auto-healing patch)**: Copy the solution from `~/.sensecraft/content/solutions/<id>` to `./.sensecraft-work/solutions/<id>`, apply the minimal required fix. Stop the previous engine instance (`sensecraft-engine daemon stop`) so it reloads the new solution directory, and redeploy with `--solutions-dir ./.sensecraft-work/solutions` so the user succeeds immediately! Show the user the patch diff. Desktop app running: fix it in the edit copy (`app-only.md` §4) → validate → apply → retry. |
84
+ | **Solution configuration** | timeout too short, wrong port/env in compose, health check endpoint 404, minor syntax/transfer glitch | **CLI / Engine mode (Auto-healing patch)**: Copy the solution from `~/.sensecraft/content/solutions/<id>` to `./.sensecraft-work/solutions/<id>`, apply the minimal required fix, and redeploy with `sensecraft-engine deploy <id> --solutions-dir ./.sensecraft-work/solutions` so the user succeeds immediately! Show the user the patch diff. Desktop app running: fix it in the edit copy (`app-only.md` §4) → validate → apply → retry. |
85
85
  | **Engine bug** | exit code 5, a panic in `engine.log`, a step that fails the same way on any device, behaviour contradicting the solution's own config | Stop. Prepare the issue report below |
86
86
 
87
87
  If the evidence does not fit any row, say so and show the user the first error
@@ -65,11 +65,8 @@ git clone https://github.com/Seeed-Studio/ModelAssistant.git ./my-model-assistan
65
65
  修改完成后,无需打包推送到 CDN,直接利用 `sensecraft-engine` 的 `--solutions-dir` 特性在本地无缝验证:
66
66
 
67
67
  ```bash
68
- # 1. 如果已有守护进程正在运行,先停止释放端口与旧方案缓存
69
- sensecraft-engine daemon stop
70
-
71
- # 2. 从本地自定义工程目录加载方案并执行部署测试
72
- sensecraft-engine deploy --solutions-dir ./my-solutions/solutions --solution <id>
68
+ # 从本地自定义工程目录加载方案并执行部署测试
69
+ sensecraft-engine deploy <id> --solutions-dir ./my-solutions/solutions
73
70
  ```
74
71
  - 引擎将直接读取本地工程中的 `solution.yaml`、`devices/*.yaml` 和 `docker-compose.yml`,秒级完成本地部署生效。
75
72