firmwareloop 0.9.0__tar.gz → 0.11.1__tar.gz

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 (45) hide show
  1. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/PKG-INFO +62 -8
  2. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/README.md +59 -7
  3. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/firmwareloop.egg-info/PKG-INFO +62 -8
  4. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/firmwareloop.egg-info/SOURCES.txt +7 -1
  5. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/firmwareloop.egg-info/requires.txt +3 -0
  6. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/pyproject.toml +12 -1
  7. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/__init__.py +1 -1
  8. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/build.ps1 +3 -2
  9. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/can.ps1 +7 -4
  10. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/check-qoder-mcp.ps1 +3 -2
  11. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/common/fw.psm1 +114 -0
  12. firmwareloop-0.11.1/tools/doctor.ps1 +668 -0
  13. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/flash.ps1 +3 -2
  14. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/fw_mcp_server.py +369 -39
  15. firmwareloop-0.11.1/tools/lib/doctor_summary.py +190 -0
  16. firmwareloop-0.11.1/tools/lib/session_run.py +279 -0
  17. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/logic_capture.ps1 +64 -10
  18. firmwareloop-0.11.1/tools/logic_capture_summary.py +204 -0
  19. firmwareloop-0.11.1/tools/logic_decode.ps1 +503 -0
  20. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/reset.ps1 +3 -2
  21. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/setup-agent-mcp.ps1 +2 -2
  22. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/sigrok_csv_to_fwloop.py +9 -4
  23. firmwareloop-0.11.1/tools/templates/lab.example.yaml +195 -0
  24. firmwareloop-0.11.1/tools/templates/skill-firmwareloop.md +37 -0
  25. firmwareloop-0.11.1/tools/templates/skill-fwloop-adapter.md +190 -0
  26. firmwareloop-0.9.0/tools/doctor.ps1 +0 -274
  27. firmwareloop-0.9.0/tools/logic_decode.ps1 +0 -308
  28. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/LICENSE +0 -0
  29. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/firmwareloop.egg-info/dependency_links.txt +0 -0
  30. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/firmwareloop.egg-info/entry_points.txt +0 -0
  31. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/firmwareloop.egg-info/top_level.txt +0 -0
  32. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/setup.cfg +0 -0
  33. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/acceptance-scenario.ps1 +0 -0
  34. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/common/build-backends.psm1 +0 -0
  35. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/common/uart_probe.py +0 -0
  36. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/instrument_cli.py +0 -0
  37. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/lib/__init__.py +0 -0
  38. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/lib/instruments.py +0 -0
  39. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/lib/ndtdbg.py +0 -0
  40. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/lib/serial_assistant.py +0 -0
  41. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/ndtdbg_bridge.ps1 +0 -0
  42. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/ndtdbg_cli.py +0 -0
  43. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/serial_cli.py +0 -0
  44. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/test-backends.ps1 +0 -0
  45. {firmwareloop-0.9.0 → firmwareloop-0.11.1}/tools/test.ps1 +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firmwareloop
3
- Version: 0.9.0
3
+ Version: 0.11.1
4
4
  Summary: AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)
5
5
  Author-email: WeilinZhang <19523330249@163.com>
6
6
  License: MIT
@@ -24,6 +24,8 @@ Requires-Dist: pytest>=8.0.0
24
24
  Requires-Dist: pyocd>=0.36.0
25
25
  Requires-Dist: pyyaml>=6.0
26
26
  Requires-Dist: agentic-hil>=0.14.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest-xdist>=3.6.0; extra == "dev"
27
29
  Dynamic: license-file
28
30
 
29
31
  # FirmwareLoop (`fwloop`)
@@ -107,10 +109,32 @@ FirmwareLoop 为 AI Agent 暴露了开箱即用的 MCP 工具,涵盖 5 大核
107
109
 
108
110
  ## NDT 公司同事快捷通道(一键离线部署)
109
111
 
110
- 拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线、无需手工配置。
112
+ 拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线。
111
113
  完整指南与常见错误速查见随包分发的 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)。
112
114
 
113
- **装完即可用**:重启 AI Agent 后直接对话操作 NdtBox(状态检查 / 数据采集 / 抓波形 / 固件烧录),无需其它命令。
115
+ **安装器自动完成**:uv + 离线 wheel 安装 fwloop、`fwloop setup`(注册 Agent + 生成全局配置)、写入 NdtDebugTool 路径、
116
+ Saleae Logic16 固件落位(`%LOCALAPPDATA%\sigrok-firmware`)、sigrok-cli 安装。
117
+
118
+ **安装器不装驱动 —— 这一步只在需要时由人工完成(两类,互不相关)**
119
+
120
+ | 需要什么 | 什么时候才需要 | 怎么做 |
121
+ |---|---|---|
122
+ | **NdtBox 驱动(CH341PAR)** | 这台电脑**从没连过 NdtBox** 才需要(上位机报 Device Not Found / 设备管理器带 ⚠️)。平时能用 NdtDebugTool 就说明已装好 | 运行包内 `assets\NDTBoxDriver\CH341PAR.EXE`(串口场景另装 `CH341SER.EXE`) |
123
+ | **逻辑分析仪驱动(Zadig → `libusb-win32`)** | 只做寄存器读写**不需要**;要用**抓波形 / 波形证据**(`fw_logic_capture`、`fw_ndtdbg_capture_seq`)时才需要 | 按 `Fwloop_setup_pack\README.md` 第 2 步:Zadig → 选中 Logic S/16 → 驱动选 `libusb-win32` → 拔插一次。**装好了怎么确认**见下方说明(一句话:让 Agent 抓一次波形,能抓到就算装好了) |
124
+
125
+ > **怎么确认逻辑分析仪驱动装好了(第 1 条对人足够)**
126
+ >
127
+ > 1. **让 Agent 抓一次波形**,例如对它说"用 fwloop 抓一次 I2C 波形并解码"——**能抓到波形,就说明驱动装好了**;
128
+ > 2. 想亲自核对:设备管理器 → 那台 Saleae → 右键属性 → 驱动程序 → 服务显示 `libusb-win32`;
129
+ > 3. 抓不到时的现象:报 `Failed to open device.` 或 `... EP1 command ... LIBUSB_ERROR_IO` ⇒ 驱动没绑对,回第 1 步重做(换 USB 口后也要重做);
130
+ > 4. Agent 自查用的技术判据:`fwloop doctor` 的仪器深检项 `checks.instruments` —— `status=ok`,且 `libusb_bound` 中该仪器的 `service` 为 `libusb0`/`libusbK`。
131
+ >
132
+ > **为什么"能扫到"不等于"能用"**:驱动绑定不对时 `sigrok-cli --scan` 依然列得出设备,但采集初始化会失败在
133
+ > `Failed to receive reply to EP1 command 0x7d: LIBUSB_ERROR_IO`。原理与三个高频坑(换 USB 口后需重绑、
134
+ > 拔插后需重试一次、阈值要匹配被测电平)详见下文 **《前置条件:仪器接入(Windows)》**。
135
+
136
+ **装完后**:重启 AI Agent,先让它跑一次环境检查(`fw_doctor`,它会用人话汇报每台仪器/串口能不能用、缺什么怎么补),再操作 NdtBox
137
+ (状态检查 / 数据采集 / 固件烧录 / 抓波形——抓波形前按上表确认逻辑分析仪驱动已就绪)。
114
138
  若还要在某个单片机工程里做编译 / 烧录 / HIL 测试,进入该工程根目录执行一次 `fwloop init`(每个新工程一次)。
115
139
 
116
140
  ---
@@ -130,6 +154,36 @@ uv tool install agentic-hil
130
154
 
131
155
  ---
132
156
 
157
+ ### 前置条件:仪器接入(Windows)
158
+
159
+ 框架通过 libusb / VCP 类后端访问 USB 逻辑分析仪、USB 转 IIC/UART 桥等仪器。
160
+ **首次在这台电脑使用某台仪器、或换过 USB 端口之后**,请先确认驱动绑定——这是"仪器打不开"最常见的原因:
161
+
162
+ | 仪器类别 | 需要什么 | 自查方法 | 装错/没装时的症状 |
163
+ |---|---|---|---|
164
+ | USB 逻辑分析仪(sigrok/Saleae 类,含 FX2/EZ-USB 固件上传型) | 绑定到 libusb 类驱动(`libusb-win32`,或 `WinUSB`) | 最直接:让它抓一次波形,能抓到就行;手工核对:设备管理器 → 设备 → 属性 → 驱动程序/服务(应显示 `libusb-win32` / `libusb0` / `libusbK` / `WinUSB`);也可让 Agent 读 `fwloop doctor` 的仪器深检项 | 采集报 `Failed to open device.`;初始化阶段报 `... EP1 command ... LIBUSB_ERROR_IO` |
165
+ | USB 转 IIC/UART 桥(CH340/CH341、CP210x、FTDI…) | 厂商 VCP 驱动 | 出现 COM 口,`fwloop doctor` 的 `com_ports` 能列出 | 端口不存在 / 打开报占用 |
166
+ | 蓝牙或 ELTIMA 等虚拟串口 | 不作为被测口 | `fwloop doctor` 会把虚拟口单独列出来(不与真实口混在一起) | 能打开但永远无数据 |
167
+
168
+ **用 Zadig 给逻辑分析仪绑定驱动(人工一次,需管理员)**
169
+
170
+ 1. 关闭一切可能占用该设备的软件(厂商上位机、PulseView、Saleae Logic 2 等)——**独占是前提**。
171
+ 2. 管理员运行 Zadig(sigrok 安装目录自带 `zadig.exe`;也可用官方包)→ `Options → List All Devices`。
172
+ 3. 选中**当前在线**的那台设备(按 VID/PID 核对;忽略"幽灵"残留节点),目标驱动选 `WinUSB` → `Replace Driver`。
173
+ 4. **拔插一次**设备,再让 Agent 重试。
174
+ 5. 若仍打不开、或初始化阶段报 EP1/命令无应答:对该设备改绑 `libusb-win32` 再试(两者互为 A/B 对照)。
175
+
176
+ **三个会反复踩的坑**
177
+
178
+ - 驱动绑定**跟随 USB 端口实例**:换一个 USB 口 = 新的设备实例,Windows 可能重新绑回默认驱动 → 需对该实例重做一次 Zadig。
179
+ - 拔插会**重置设备状态**:刚初始化的设备拔插后要重新初始化;首次打开报"等待设备重启 / 初始化失败"时,等 3–5 秒重试一次通常即可。
180
+ - **阈值/量程必须覆盖被测电平**:采集前确认被测逻辑电平落在仪器档位内(例:1.8 V 逻辑需选覆盖 1.4–3.6 V 的档位,而不是 0.7–1.4 V;示波器注意探针 1x/10x 衰减比)。
181
+
182
+ > 驱动安装需要管理员权限与设备选择,误绑会影响其它软件,因此框架**不自动安装驱动**,只做「检测 → 指引 → 复验」:
183
+ > `fwloop doctor` 会报告每台仪器当前的就绪状态**和下一步该怎么修**(Agent 读的也是同一份内容)。公司交付包覆盖的环境由安装器代做(见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md))。
184
+
185
+ ---
186
+
133
187
  ### 可选:接入 NdtBox 调试盒(公司内部 USB→IIC 调试工具)
134
188
 
135
189
  如需用 Agent 直接操作 NdtBox(固件寄存器读写 / 数据采集 / 逻辑分析仪协议验证),安装后执行一次:
@@ -154,7 +208,7 @@ fwloop ndtdebugtool "C:/Users/weilin.zhang/Desktop/zwl/NdtDebugTool-v1.0.19"
154
208
  **前置要求:**
155
209
 
156
210
  - **CH341 驱动**:首次在这台电脑使用 NdtBox 时,运行交付包内 `assets\NDTBoxDriver\CH341PAR.EXE`(USB 转 IIC);COM 串口场景另装 `CH341SER.EXE`
157
- - **Saleae 波形证据**(可选):Saleae Logic16 固件(落位 `%LOCALAPPDATA%\sigrok-firmware`)+ sigrok-cli,并用 Zadig 配置 `libusb-win32` 驱动——交付包一键安装器会自动完成,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
211
+ - **Saleae 波形证据**(可选):Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware` + sigrok-cli;**驱动绑定(Zadig)见上文《前置条件:仪器接入(Windows)》**——交付包一键安装器会自动完成这两步,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
158
212
  - **USB 独占**:测试时退出 NdtDebugTool 上位机 STDataCollection.exe(同时打开会互踢)
159
213
 
160
214
  ---
@@ -231,7 +285,7 @@ fwloop init
231
285
  |---|---|---|---|
232
286
  | **`fwloop setup`** | **系统全局级** | 给各大 Agent(Antigravity / Claude Code / Qoder / Qoder CN / CodeBuddy)配置全局 MCP 与同步技能包 | **全电脑只需跑 1 次** |
233
287
  | **`fwloop init`** | **工程项目级** | 在当前单片机代码目录下生成 `AGENTS.md`、`GEMINI.md`、`CLAUDE.md` 与台架配置 | **每个新单片机项目跑 1 次** |
234
- | **`fwloop doctor`** | **环境诊断** | 检查编译器(Keil/GCC)、Python 环境、串口与探针连接健康度 | 随时排查环境时使用 |
288
+ | **`fwloop doctor`** | **环境诊断** | 一屏人话摘要:核心工具链是否正常、仪器能不能用(逻辑分析仪/串口/探针…)、缺什么怎么补。加 `--json` 看原始数据 | 随时排查环境时使用 |
235
289
  | **`fwloop update`** | **自动更新** | 一键自动拉取最新代码并热重载依赖 | 升级工具版本时使用 |
236
290
 
237
291
  ---
@@ -307,7 +361,7 @@ fwloop update
307
361
 
308
362
  3. 环境健康体检与依赖诊断:
309
363
  ```bash
310
- fwloop doctor
364
+ fwloop doctor # 人话摘要; 需要原始数据时另加 --json
311
365
  ```
312
366
 
313
367
  4. 查看或生成各大 Agent MCP 注册指令:
@@ -385,7 +439,7 @@ claude mcp remove --scope user agentic-hil
385
439
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
386
440
  ├── demo-make/ 示例固件(Make;构建测试载体)
387
441
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
388
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.9.0)
442
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.1)
389
443
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
390
444
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
391
445
  ├── CLAUDE.md Claude Code CLI 指南
@@ -395,7 +449,7 @@ claude mcp remove --scope user agentic-hil
395
449
 
396
450
  ---
397
451
 
398
- ## 能力验证状态(v0.9.0)
452
+ ## 能力验证状态(v0.11.1)
399
453
 
400
454
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
401
455
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -79,10 +79,32 @@ FirmwareLoop 为 AI Agent 暴露了开箱即用的 MCP 工具,涵盖 5 大核
79
79
 
80
80
  ## NDT 公司同事快捷通道(一键离线部署)
81
81
 
82
- 拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线、无需手工配置。
82
+ 拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线。
83
83
  完整指南与常见错误速查见随包分发的 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)。
84
84
 
85
- **装完即可用**:重启 AI Agent 后直接对话操作 NdtBox(状态检查 / 数据采集 / 抓波形 / 固件烧录),无需其它命令。
85
+ **安装器自动完成**:uv + 离线 wheel 安装 fwloop、`fwloop setup`(注册 Agent + 生成全局配置)、写入 NdtDebugTool 路径、
86
+ Saleae Logic16 固件落位(`%LOCALAPPDATA%\sigrok-firmware`)、sigrok-cli 安装。
87
+
88
+ **安装器不装驱动 —— 这一步只在需要时由人工完成(两类,互不相关)**
89
+
90
+ | 需要什么 | 什么时候才需要 | 怎么做 |
91
+ |---|---|---|
92
+ | **NdtBox 驱动(CH341PAR)** | 这台电脑**从没连过 NdtBox** 才需要(上位机报 Device Not Found / 设备管理器带 ⚠️)。平时能用 NdtDebugTool 就说明已装好 | 运行包内 `assets\NDTBoxDriver\CH341PAR.EXE`(串口场景另装 `CH341SER.EXE`) |
93
+ | **逻辑分析仪驱动(Zadig → `libusb-win32`)** | 只做寄存器读写**不需要**;要用**抓波形 / 波形证据**(`fw_logic_capture`、`fw_ndtdbg_capture_seq`)时才需要 | 按 `Fwloop_setup_pack\README.md` 第 2 步:Zadig → 选中 Logic S/16 → 驱动选 `libusb-win32` → 拔插一次。**装好了怎么确认**见下方说明(一句话:让 Agent 抓一次波形,能抓到就算装好了) |
94
+
95
+ > **怎么确认逻辑分析仪驱动装好了(第 1 条对人足够)**
96
+ >
97
+ > 1. **让 Agent 抓一次波形**,例如对它说"用 fwloop 抓一次 I2C 波形并解码"——**能抓到波形,就说明驱动装好了**;
98
+ > 2. 想亲自核对:设备管理器 → 那台 Saleae → 右键属性 → 驱动程序 → 服务显示 `libusb-win32`;
99
+ > 3. 抓不到时的现象:报 `Failed to open device.` 或 `... EP1 command ... LIBUSB_ERROR_IO` ⇒ 驱动没绑对,回第 1 步重做(换 USB 口后也要重做);
100
+ > 4. Agent 自查用的技术判据:`fwloop doctor` 的仪器深检项 `checks.instruments` —— `status=ok`,且 `libusb_bound` 中该仪器的 `service` 为 `libusb0`/`libusbK`。
101
+ >
102
+ > **为什么"能扫到"不等于"能用"**:驱动绑定不对时 `sigrok-cli --scan` 依然列得出设备,但采集初始化会失败在
103
+ > `Failed to receive reply to EP1 command 0x7d: LIBUSB_ERROR_IO`。原理与三个高频坑(换 USB 口后需重绑、
104
+ > 拔插后需重试一次、阈值要匹配被测电平)详见下文 **《前置条件:仪器接入(Windows)》**。
105
+
106
+ **装完后**:重启 AI Agent,先让它跑一次环境检查(`fw_doctor`,它会用人话汇报每台仪器/串口能不能用、缺什么怎么补),再操作 NdtBox
107
+ (状态检查 / 数据采集 / 固件烧录 / 抓波形——抓波形前按上表确认逻辑分析仪驱动已就绪)。
86
108
  若还要在某个单片机工程里做编译 / 烧录 / HIL 测试,进入该工程根目录执行一次 `fwloop init`(每个新工程一次)。
87
109
 
88
110
  ---
@@ -102,6 +124,36 @@ uv tool install agentic-hil
102
124
 
103
125
  ---
104
126
 
127
+ ### 前置条件:仪器接入(Windows)
128
+
129
+ 框架通过 libusb / VCP 类后端访问 USB 逻辑分析仪、USB 转 IIC/UART 桥等仪器。
130
+ **首次在这台电脑使用某台仪器、或换过 USB 端口之后**,请先确认驱动绑定——这是"仪器打不开"最常见的原因:
131
+
132
+ | 仪器类别 | 需要什么 | 自查方法 | 装错/没装时的症状 |
133
+ |---|---|---|---|
134
+ | USB 逻辑分析仪(sigrok/Saleae 类,含 FX2/EZ-USB 固件上传型) | 绑定到 libusb 类驱动(`libusb-win32`,或 `WinUSB`) | 最直接:让它抓一次波形,能抓到就行;手工核对:设备管理器 → 设备 → 属性 → 驱动程序/服务(应显示 `libusb-win32` / `libusb0` / `libusbK` / `WinUSB`);也可让 Agent 读 `fwloop doctor` 的仪器深检项 | 采集报 `Failed to open device.`;初始化阶段报 `... EP1 command ... LIBUSB_ERROR_IO` |
135
+ | USB 转 IIC/UART 桥(CH340/CH341、CP210x、FTDI…) | 厂商 VCP 驱动 | 出现 COM 口,`fwloop doctor` 的 `com_ports` 能列出 | 端口不存在 / 打开报占用 |
136
+ | 蓝牙或 ELTIMA 等虚拟串口 | 不作为被测口 | `fwloop doctor` 会把虚拟口单独列出来(不与真实口混在一起) | 能打开但永远无数据 |
137
+
138
+ **用 Zadig 给逻辑分析仪绑定驱动(人工一次,需管理员)**
139
+
140
+ 1. 关闭一切可能占用该设备的软件(厂商上位机、PulseView、Saleae Logic 2 等)——**独占是前提**。
141
+ 2. 管理员运行 Zadig(sigrok 安装目录自带 `zadig.exe`;也可用官方包)→ `Options → List All Devices`。
142
+ 3. 选中**当前在线**的那台设备(按 VID/PID 核对;忽略"幽灵"残留节点),目标驱动选 `WinUSB` → `Replace Driver`。
143
+ 4. **拔插一次**设备,再让 Agent 重试。
144
+ 5. 若仍打不开、或初始化阶段报 EP1/命令无应答:对该设备改绑 `libusb-win32` 再试(两者互为 A/B 对照)。
145
+
146
+ **三个会反复踩的坑**
147
+
148
+ - 驱动绑定**跟随 USB 端口实例**:换一个 USB 口 = 新的设备实例,Windows 可能重新绑回默认驱动 → 需对该实例重做一次 Zadig。
149
+ - 拔插会**重置设备状态**:刚初始化的设备拔插后要重新初始化;首次打开报"等待设备重启 / 初始化失败"时,等 3–5 秒重试一次通常即可。
150
+ - **阈值/量程必须覆盖被测电平**:采集前确认被测逻辑电平落在仪器档位内(例:1.8 V 逻辑需选覆盖 1.4–3.6 V 的档位,而不是 0.7–1.4 V;示波器注意探针 1x/10x 衰减比)。
151
+
152
+ > 驱动安装需要管理员权限与设备选择,误绑会影响其它软件,因此框架**不自动安装驱动**,只做「检测 → 指引 → 复验」:
153
+ > `fwloop doctor` 会报告每台仪器当前的就绪状态**和下一步该怎么修**(Agent 读的也是同一份内容)。公司交付包覆盖的环境由安装器代做(见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md))。
154
+
155
+ ---
156
+
105
157
  ### 可选:接入 NdtBox 调试盒(公司内部 USB→IIC 调试工具)
106
158
 
107
159
  如需用 Agent 直接操作 NdtBox(固件寄存器读写 / 数据采集 / 逻辑分析仪协议验证),安装后执行一次:
@@ -126,7 +178,7 @@ fwloop ndtdebugtool "C:/Users/weilin.zhang/Desktop/zwl/NdtDebugTool-v1.0.19"
126
178
  **前置要求:**
127
179
 
128
180
  - **CH341 驱动**:首次在这台电脑使用 NdtBox 时,运行交付包内 `assets\NDTBoxDriver\CH341PAR.EXE`(USB 转 IIC);COM 串口场景另装 `CH341SER.EXE`
129
- - **Saleae 波形证据**(可选):Saleae Logic16 固件(落位 `%LOCALAPPDATA%\sigrok-firmware`)+ sigrok-cli,并用 Zadig 配置 `libusb-win32` 驱动——交付包一键安装器会自动完成,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
181
+ - **Saleae 波形证据**(可选):Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware` + sigrok-cli;**驱动绑定(Zadig)见上文《前置条件:仪器接入(Windows)》**——交付包一键安装器会自动完成这两步,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
130
182
  - **USB 独占**:测试时退出 NdtDebugTool 上位机 STDataCollection.exe(同时打开会互踢)
131
183
 
132
184
  ---
@@ -203,7 +255,7 @@ fwloop init
203
255
  |---|---|---|---|
204
256
  | **`fwloop setup`** | **系统全局级** | 给各大 Agent(Antigravity / Claude Code / Qoder / Qoder CN / CodeBuddy)配置全局 MCP 与同步技能包 | **全电脑只需跑 1 次** |
205
257
  | **`fwloop init`** | **工程项目级** | 在当前单片机代码目录下生成 `AGENTS.md`、`GEMINI.md`、`CLAUDE.md` 与台架配置 | **每个新单片机项目跑 1 次** |
206
- | **`fwloop doctor`** | **环境诊断** | 检查编译器(Keil/GCC)、Python 环境、串口与探针连接健康度 | 随时排查环境时使用 |
258
+ | **`fwloop doctor`** | **环境诊断** | 一屏人话摘要:核心工具链是否正常、仪器能不能用(逻辑分析仪/串口/探针…)、缺什么怎么补。加 `--json` 看原始数据 | 随时排查环境时使用 |
207
259
  | **`fwloop update`** | **自动更新** | 一键自动拉取最新代码并热重载依赖 | 升级工具版本时使用 |
208
260
 
209
261
  ---
@@ -279,7 +331,7 @@ fwloop update
279
331
 
280
332
  3. 环境健康体检与依赖诊断:
281
333
  ```bash
282
- fwloop doctor
334
+ fwloop doctor # 人话摘要; 需要原始数据时另加 --json
283
335
  ```
284
336
 
285
337
  4. 查看或生成各大 Agent MCP 注册指令:
@@ -357,7 +409,7 @@ claude mcp remove --scope user agentic-hil
357
409
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
358
410
  ├── demo-make/ 示例固件(Make;构建测试载体)
359
411
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
360
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.9.0)
412
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.1)
361
413
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
362
414
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
363
415
  ├── CLAUDE.md Claude Code CLI 指南
@@ -367,7 +419,7 @@ claude mcp remove --scope user agentic-hil
367
419
 
368
420
  ---
369
421
 
370
- ## 能力验证状态(v0.9.0)
422
+ ## 能力验证状态(v0.11.1)
371
423
 
372
424
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
373
425
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firmwareloop
3
- Version: 0.9.0
3
+ Version: 0.11.1
4
4
  Summary: AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)
5
5
  Author-email: WeilinZhang <19523330249@163.com>
6
6
  License: MIT
@@ -24,6 +24,8 @@ Requires-Dist: pytest>=8.0.0
24
24
  Requires-Dist: pyocd>=0.36.0
25
25
  Requires-Dist: pyyaml>=6.0
26
26
  Requires-Dist: agentic-hil>=0.14.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest-xdist>=3.6.0; extra == "dev"
27
29
  Dynamic: license-file
28
30
 
29
31
  # FirmwareLoop (`fwloop`)
@@ -107,10 +109,32 @@ FirmwareLoop 为 AI Agent 暴露了开箱即用的 MCP 工具,涵盖 5 大核
107
109
 
108
110
  ## NDT 公司同事快捷通道(一键离线部署)
109
111
 
110
- 拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线、无需手工配置。
112
+ 拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线。
111
113
  完整指南与常见错误速查见随包分发的 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)。
112
114
 
113
- **装完即可用**:重启 AI Agent 后直接对话操作 NdtBox(状态检查 / 数据采集 / 抓波形 / 固件烧录),无需其它命令。
115
+ **安装器自动完成**:uv + 离线 wheel 安装 fwloop、`fwloop setup`(注册 Agent + 生成全局配置)、写入 NdtDebugTool 路径、
116
+ Saleae Logic16 固件落位(`%LOCALAPPDATA%\sigrok-firmware`)、sigrok-cli 安装。
117
+
118
+ **安装器不装驱动 —— 这一步只在需要时由人工完成(两类,互不相关)**
119
+
120
+ | 需要什么 | 什么时候才需要 | 怎么做 |
121
+ |---|---|---|
122
+ | **NdtBox 驱动(CH341PAR)** | 这台电脑**从没连过 NdtBox** 才需要(上位机报 Device Not Found / 设备管理器带 ⚠️)。平时能用 NdtDebugTool 就说明已装好 | 运行包内 `assets\NDTBoxDriver\CH341PAR.EXE`(串口场景另装 `CH341SER.EXE`) |
123
+ | **逻辑分析仪驱动(Zadig → `libusb-win32`)** | 只做寄存器读写**不需要**;要用**抓波形 / 波形证据**(`fw_logic_capture`、`fw_ndtdbg_capture_seq`)时才需要 | 按 `Fwloop_setup_pack\README.md` 第 2 步:Zadig → 选中 Logic S/16 → 驱动选 `libusb-win32` → 拔插一次。**装好了怎么确认**见下方说明(一句话:让 Agent 抓一次波形,能抓到就算装好了) |
124
+
125
+ > **怎么确认逻辑分析仪驱动装好了(第 1 条对人足够)**
126
+ >
127
+ > 1. **让 Agent 抓一次波形**,例如对它说"用 fwloop 抓一次 I2C 波形并解码"——**能抓到波形,就说明驱动装好了**;
128
+ > 2. 想亲自核对:设备管理器 → 那台 Saleae → 右键属性 → 驱动程序 → 服务显示 `libusb-win32`;
129
+ > 3. 抓不到时的现象:报 `Failed to open device.` 或 `... EP1 command ... LIBUSB_ERROR_IO` ⇒ 驱动没绑对,回第 1 步重做(换 USB 口后也要重做);
130
+ > 4. Agent 自查用的技术判据:`fwloop doctor` 的仪器深检项 `checks.instruments` —— `status=ok`,且 `libusb_bound` 中该仪器的 `service` 为 `libusb0`/`libusbK`。
131
+ >
132
+ > **为什么"能扫到"不等于"能用"**:驱动绑定不对时 `sigrok-cli --scan` 依然列得出设备,但采集初始化会失败在
133
+ > `Failed to receive reply to EP1 command 0x7d: LIBUSB_ERROR_IO`。原理与三个高频坑(换 USB 口后需重绑、
134
+ > 拔插后需重试一次、阈值要匹配被测电平)详见下文 **《前置条件:仪器接入(Windows)》**。
135
+
136
+ **装完后**:重启 AI Agent,先让它跑一次环境检查(`fw_doctor`,它会用人话汇报每台仪器/串口能不能用、缺什么怎么补),再操作 NdtBox
137
+ (状态检查 / 数据采集 / 固件烧录 / 抓波形——抓波形前按上表确认逻辑分析仪驱动已就绪)。
114
138
  若还要在某个单片机工程里做编译 / 烧录 / HIL 测试,进入该工程根目录执行一次 `fwloop init`(每个新工程一次)。
115
139
 
116
140
  ---
@@ -130,6 +154,36 @@ uv tool install agentic-hil
130
154
 
131
155
  ---
132
156
 
157
+ ### 前置条件:仪器接入(Windows)
158
+
159
+ 框架通过 libusb / VCP 类后端访问 USB 逻辑分析仪、USB 转 IIC/UART 桥等仪器。
160
+ **首次在这台电脑使用某台仪器、或换过 USB 端口之后**,请先确认驱动绑定——这是"仪器打不开"最常见的原因:
161
+
162
+ | 仪器类别 | 需要什么 | 自查方法 | 装错/没装时的症状 |
163
+ |---|---|---|---|
164
+ | USB 逻辑分析仪(sigrok/Saleae 类,含 FX2/EZ-USB 固件上传型) | 绑定到 libusb 类驱动(`libusb-win32`,或 `WinUSB`) | 最直接:让它抓一次波形,能抓到就行;手工核对:设备管理器 → 设备 → 属性 → 驱动程序/服务(应显示 `libusb-win32` / `libusb0` / `libusbK` / `WinUSB`);也可让 Agent 读 `fwloop doctor` 的仪器深检项 | 采集报 `Failed to open device.`;初始化阶段报 `... EP1 command ... LIBUSB_ERROR_IO` |
165
+ | USB 转 IIC/UART 桥(CH340/CH341、CP210x、FTDI…) | 厂商 VCP 驱动 | 出现 COM 口,`fwloop doctor` 的 `com_ports` 能列出 | 端口不存在 / 打开报占用 |
166
+ | 蓝牙或 ELTIMA 等虚拟串口 | 不作为被测口 | `fwloop doctor` 会把虚拟口单独列出来(不与真实口混在一起) | 能打开但永远无数据 |
167
+
168
+ **用 Zadig 给逻辑分析仪绑定驱动(人工一次,需管理员)**
169
+
170
+ 1. 关闭一切可能占用该设备的软件(厂商上位机、PulseView、Saleae Logic 2 等)——**独占是前提**。
171
+ 2. 管理员运行 Zadig(sigrok 安装目录自带 `zadig.exe`;也可用官方包)→ `Options → List All Devices`。
172
+ 3. 选中**当前在线**的那台设备(按 VID/PID 核对;忽略"幽灵"残留节点),目标驱动选 `WinUSB` → `Replace Driver`。
173
+ 4. **拔插一次**设备,再让 Agent 重试。
174
+ 5. 若仍打不开、或初始化阶段报 EP1/命令无应答:对该设备改绑 `libusb-win32` 再试(两者互为 A/B 对照)。
175
+
176
+ **三个会反复踩的坑**
177
+
178
+ - 驱动绑定**跟随 USB 端口实例**:换一个 USB 口 = 新的设备实例,Windows 可能重新绑回默认驱动 → 需对该实例重做一次 Zadig。
179
+ - 拔插会**重置设备状态**:刚初始化的设备拔插后要重新初始化;首次打开报"等待设备重启 / 初始化失败"时,等 3–5 秒重试一次通常即可。
180
+ - **阈值/量程必须覆盖被测电平**:采集前确认被测逻辑电平落在仪器档位内(例:1.8 V 逻辑需选覆盖 1.4–3.6 V 的档位,而不是 0.7–1.4 V;示波器注意探针 1x/10x 衰减比)。
181
+
182
+ > 驱动安装需要管理员权限与设备选择,误绑会影响其它软件,因此框架**不自动安装驱动**,只做「检测 → 指引 → 复验」:
183
+ > `fwloop doctor` 会报告每台仪器当前的就绪状态**和下一步该怎么修**(Agent 读的也是同一份内容)。公司交付包覆盖的环境由安装器代做(见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md))。
184
+
185
+ ---
186
+
133
187
  ### 可选:接入 NdtBox 调试盒(公司内部 USB→IIC 调试工具)
134
188
 
135
189
  如需用 Agent 直接操作 NdtBox(固件寄存器读写 / 数据采集 / 逻辑分析仪协议验证),安装后执行一次:
@@ -154,7 +208,7 @@ fwloop ndtdebugtool "C:/Users/weilin.zhang/Desktop/zwl/NdtDebugTool-v1.0.19"
154
208
  **前置要求:**
155
209
 
156
210
  - **CH341 驱动**:首次在这台电脑使用 NdtBox 时,运行交付包内 `assets\NDTBoxDriver\CH341PAR.EXE`(USB 转 IIC);COM 串口场景另装 `CH341SER.EXE`
157
- - **Saleae 波形证据**(可选):Saleae Logic16 固件(落位 `%LOCALAPPDATA%\sigrok-firmware`)+ sigrok-cli,并用 Zadig 配置 `libusb-win32` 驱动——交付包一键安装器会自动完成,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
211
+ - **Saleae 波形证据**(可选):Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware` + sigrok-cli;**驱动绑定(Zadig)见上文《前置条件:仪器接入(Windows)》**——交付包一键安装器会自动完成这两步,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
158
212
  - **USB 独占**:测试时退出 NdtDebugTool 上位机 STDataCollection.exe(同时打开会互踢)
159
213
 
160
214
  ---
@@ -231,7 +285,7 @@ fwloop init
231
285
  |---|---|---|---|
232
286
  | **`fwloop setup`** | **系统全局级** | 给各大 Agent(Antigravity / Claude Code / Qoder / Qoder CN / CodeBuddy)配置全局 MCP 与同步技能包 | **全电脑只需跑 1 次** |
233
287
  | **`fwloop init`** | **工程项目级** | 在当前单片机代码目录下生成 `AGENTS.md`、`GEMINI.md`、`CLAUDE.md` 与台架配置 | **每个新单片机项目跑 1 次** |
234
- | **`fwloop doctor`** | **环境诊断** | 检查编译器(Keil/GCC)、Python 环境、串口与探针连接健康度 | 随时排查环境时使用 |
288
+ | **`fwloop doctor`** | **环境诊断** | 一屏人话摘要:核心工具链是否正常、仪器能不能用(逻辑分析仪/串口/探针…)、缺什么怎么补。加 `--json` 看原始数据 | 随时排查环境时使用 |
235
289
  | **`fwloop update`** | **自动更新** | 一键自动拉取最新代码并热重载依赖 | 升级工具版本时使用 |
236
290
 
237
291
  ---
@@ -307,7 +361,7 @@ fwloop update
307
361
 
308
362
  3. 环境健康体检与依赖诊断:
309
363
  ```bash
310
- fwloop doctor
364
+ fwloop doctor # 人话摘要; 需要原始数据时另加 --json
311
365
  ```
312
366
 
313
367
  4. 查看或生成各大 Agent MCP 注册指令:
@@ -385,7 +439,7 @@ claude mcp remove --scope user agentic-hil
385
439
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
386
440
  ├── demo-make/ 示例固件(Make;构建测试载体)
387
441
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
388
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.9.0)
442
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.1)
389
443
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
390
444
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
391
445
  ├── CLAUDE.md Claude Code CLI 指南
@@ -395,7 +449,7 @@ claude mcp remove --scope user agentic-hil
395
449
 
396
450
  ---
397
451
 
398
- ## 能力验证状态(v0.9.0)
452
+ ## 能力验证状态(v0.11.1)
399
453
 
400
454
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
401
455
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -17,6 +17,7 @@ tools/flash.ps1
17
17
  tools/fw_mcp_server.py
18
18
  tools/instrument_cli.py
19
19
  tools/logic_capture.ps1
20
+ tools/logic_capture_summary.py
20
21
  tools/logic_decode.ps1
21
22
  tools/ndtdbg_bridge.ps1
22
23
  tools/ndtdbg_cli.py
@@ -30,6 +31,11 @@ tools/common/build-backends.psm1
30
31
  tools/common/fw.psm1
31
32
  tools/common/uart_probe.py
32
33
  tools/lib/__init__.py
34
+ tools/lib/doctor_summary.py
33
35
  tools/lib/instruments.py
34
36
  tools/lib/ndtdbg.py
35
- tools/lib/serial_assistant.py
37
+ tools/lib/serial_assistant.py
38
+ tools/lib/session_run.py
39
+ tools/templates/lab.example.yaml
40
+ tools/templates/skill-firmwareloop.md
41
+ tools/templates/skill-fwloop-adapter.md
@@ -5,3 +5,6 @@ pytest>=8.0.0
5
5
  pyocd>=0.36.0
6
6
  pyyaml>=6.0
7
7
  agentic-hil>=0.14.0
8
+
9
+ [dev]
10
+ pytest-xdist>=3.6.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "firmwareloop"
7
- version = "0.9.0"
7
+ version = "0.11.1"
8
8
  description = "AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -42,9 +42,20 @@ fwloop = "tools.fw_mcp_server:main"
42
42
  fw-mcp = "tools.fw_mcp_server:main"
43
43
  fw = "tools.fw_mcp_server:main"
44
44
 
45
+ # 开发/验收工具链 (不随 wheel 分发给使用者): 并行跑单测用
46
+ # uv pip install -e ".[dev]"
47
+ # python -m pytest tests/unit -n auto --dist=loadfile
48
+ [project.optional-dependencies]
49
+ dev = [
50
+ "pytest-xdist>=3.6.0",
51
+ ]
52
+
45
53
  [tool.setuptools.packages.find]
46
54
  where = ["."]
47
55
  include = ["tools*"]
48
56
 
49
57
  [tool.setuptools.package-data]
50
58
  "*" = ["*.ps1", "*.psm1", "*.yaml", "*.md", "*.json"]
59
+ # 随包分发的模板/资源 (v0.9.1): tools/templates/ 下的 lab.yaml 模板与 skill 副本。
60
+ # 仓库根的 lab/ 与 skills/ 不在 wheel 内, 安装态必须靠这些副本 (防漂移测试锁定一致)。
61
+ "tools" = ["templates/*.yaml", "templates/*.md"]
@@ -2,4 +2,4 @@
2
2
  FirmwareLoop - AI Agent Firmware Development and Lab Automation Platform.
3
3
  """
4
4
 
5
- __version__ = "0.9.0"
5
+ __version__ = "0.11.1"
@@ -49,8 +49,9 @@ $repoRoot = Get-FwRepoRoot
49
49
  $sw = [System.Diagnostics.Stopwatch]::StartNew()
50
50
 
51
51
  function Exit-WithError {
52
- param([string]$Class, [string]$Message, [string]$Detail)
53
- $body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail
52
+ # v0.11.0: -Remedy 透传到 New-FwError (未给则按 error_class 取默认建议)
53
+ param([string]$Class, [string]$Message, [string]$Detail, [string]$Remedy)
54
+ $body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail -Remedy $Remedy
54
55
  if ($Json) { Write-FwJson $body -Compact } else { Write-FwJson $body; Write-Error "$Class : $Message" -ErrorAction Continue }
55
56
  exit 2
56
57
  }
@@ -39,22 +39,25 @@ $repoRoot = Get-FwRepoRoot
39
39
  $stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
40
40
 
41
41
  function Exit-WithError {
42
- param([string]$Class, [string]$Message, [string]$Detail)
43
- $body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail
42
+ # v0.11.0: -Remedy 透传到 New-FwError (未给则按 error_class 取默认建议)
43
+ param([string]$Class, [string]$Message, [string]$Detail, [string]$Remedy)
44
+ $body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail -Remedy $Remedy
44
45
  if ($Json) { Write-FwJson $body -Compact } else { Write-FwJson $body; Write-Error "$Class : $Message" -ErrorAction Continue }
45
46
  exit 2
46
47
  }
47
48
 
48
49
  # CAN TX default requires explicit authorization (Spec §12: 人工授权)
49
50
  if ($Command -eq 'send' -and -not $Authorized) {
50
- Exit-WithError -Class 'PERMISSION_DENIED' -Message 'CAN TX requires explicit human authorization; pass -Authorized after approval (Spec §12/§24).'
51
+ Exit-WithError -Class 'PERMISSION_DENIED' -Message 'CAN TX requires explicit human authorization; pass -Authorized after approval (Spec §12/§24).' `
52
+ -Remedy 'CAN TX 属需授权操作: 取得人工批准后加 -Authorized 重跑; 只读场景用 read/session-start'
51
53
  }
52
54
 
53
55
  $cmd = Get-Command agentic-hil -ErrorAction SilentlyContinue
54
56
  $tool = if ($cmd) { $cmd.Source } else { $null }
55
57
 
56
58
  if ($Backend -eq 'agentic-hil' -and -not $tool) {
57
- Exit-WithError -Class 'PROBE_NOT_FOUND' -Message "'agentic-hil' is not installed; CAN is not available until Agentic HIL is installed (Spec §32)." -Detail 'Install Agentic HIL, then verify its CAN schema with: agentic-hil --help'
59
+ Exit-WithError -Class 'PROBE_NOT_FOUND' -Message "'agentic-hil' is not installed; CAN is not available until Agentic HIL is installed (Spec §32)." -Detail 'Install Agentic HIL, then verify its CAN schema with: agentic-hil --help' `
60
+ -Remedy 'uv tool install agentic-hil (或 uv pip install agentic-hil), 然后 fwloop setup 注册 MCP; 复核: fwloop doctor 的 agentic_hil 项'
58
61
  }
59
62
 
60
63
  # Resolve lab config for adapter/channel/bitrate defaults (never hardcoded)
@@ -26,8 +26,9 @@ Import-Module (Join-Path $PSScriptRoot 'common\fw.psm1') -Force
26
26
  $repoRoot = Get-FwRepoRoot
27
27
 
28
28
  function Exit-WithError {
29
- param([string]$Class, [string]$Message, [string]$Detail)
30
- $body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail
29
+ # v0.11.0: -Remedy 透传到 New-FwError (未给则按 error_class 取默认建议)
30
+ param([string]$Class, [string]$Message, [string]$Detail, [string]$Remedy)
31
+ $body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail -Remedy $Remedy
31
32
  if ($Json) { Write-FwJson $body -Compact } else { Write-FwJson $body; Write-Error "$Class : $Message" -ErrorAction Continue }
32
33
  exit 2
33
34
  }