firmwareloop 0.11.1__tar.gz → 0.11.2__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.
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/PKG-INFO +14 -4
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/README.md +13 -3
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/firmwareloop.egg-info/PKG-INFO +14 -4
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/firmwareloop.egg-info/SOURCES.txt +1 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/pyproject.toml +1 -1
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/__init__.py +1 -1
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/can.ps1 +2 -2
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/flash.ps1 +1 -1
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/fw_mcp_server.py +80 -30
- firmwareloop-0.11.2/tools/installer/README.md +44 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/lib/serial_assistant.py +11 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/logic_capture.ps1 +7 -7
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/logic_decode.ps1 +5 -2
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/setup-agent-mcp.ps1 +2 -2
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/LICENSE +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/firmwareloop.egg-info/dependency_links.txt +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/firmwareloop.egg-info/entry_points.txt +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/firmwareloop.egg-info/requires.txt +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/firmwareloop.egg-info/top_level.txt +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/setup.cfg +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/acceptance-scenario.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/build.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/check-qoder-mcp.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/common/build-backends.psm1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/common/fw.psm1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/common/uart_probe.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/doctor.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/instrument_cli.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/lib/__init__.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/lib/doctor_summary.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/lib/instruments.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/lib/ndtdbg.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/lib/session_run.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/logic_capture_summary.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/ndtdbg_bridge.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/ndtdbg_cli.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/reset.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/serial_cli.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/sigrok_csv_to_fwloop.py +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/templates/lab.example.yaml +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/templates/skill-firmwareloop.md +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/templates/skill-fwloop-adapter.md +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/test-backends.ps1 +0 -0
- {firmwareloop-0.11.1 → firmwareloop-0.11.2}/tools/test.ps1 +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: firmwareloop
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.2
|
|
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
|
|
@@ -234,7 +234,17 @@ fwloop setup
|
|
|
234
234
|
| DeepSeek Harness (DSH) | `~/.dsh/profiles/<已派生 profile>/cordis.patch.yml` |
|
|
235
235
|
| ZCode IDE | `~/.zcode/cli/config.json` |
|
|
236
236
|
|
|
237
|
-
2. **同步技能包**(`firmwareloop`、`fwloop-adapter
|
|
237
|
+
2. **同步技能包**(`firmwareloop`、`fwloop-adapter`)到各 Agent 的全局 Skill 目录(探测式:Agent 主目录存在才写入,`skills/` 子目录自动创建):
|
|
238
|
+
|
|
239
|
+
| Agent | Skill 写入位置 |
|
|
240
|
+
|---|---|
|
|
241
|
+
| Google Antigravity / Gemini CLI | `~/.gemini/antigravity-cli/skills/` |
|
|
242
|
+
| Claude Code CLI | `~/.claude/skills/` |
|
|
243
|
+
| Qoder / Qoder CN | `~/.qoder/skills/`、`~/.qoder-cn/skills/` |
|
|
244
|
+
| CodeBuddy IDE | `~/.codebuddy/skills/` |
|
|
245
|
+
| DeepSeek Harness (DSH) | `~/.dsh/skills/` |
|
|
246
|
+
| ZCode IDE | `~/.zcode/skills/` |
|
|
247
|
+
| 通用(跨 Agent 工具链) | `~/.agents/skills/`(特殊:无"未安装"概念,机器上不存在时直接创建) |
|
|
238
248
|
3. **生成机器级全局配置** `%APPDATA%\FirmwareLoop\lab.yaml`(NdtBox 配置模板,已存在则不覆盖)。
|
|
239
249
|
|
|
240
250
|
> 手动注册(可选):Claude Code 也可逐条注册,效果相同:
|
|
@@ -439,7 +449,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
439
449
|
├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
|
|
440
450
|
├── demo-make/ 示例固件(Make;构建测试载体)
|
|
441
451
|
├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
|
|
442
|
-
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.
|
|
452
|
+
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.2)
|
|
443
453
|
├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
|
|
444
454
|
├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
|
|
445
455
|
├── CLAUDE.md Claude Code CLI 指南
|
|
@@ -449,7 +459,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
449
459
|
|
|
450
460
|
---
|
|
451
461
|
|
|
452
|
-
## 能力验证状态(v0.11.
|
|
462
|
+
## 能力验证状态(v0.11.2)
|
|
453
463
|
|
|
454
464
|
> 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
|
|
455
465
|
> `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
|
|
@@ -204,7 +204,17 @@ fwloop setup
|
|
|
204
204
|
| DeepSeek Harness (DSH) | `~/.dsh/profiles/<已派生 profile>/cordis.patch.yml` |
|
|
205
205
|
| ZCode IDE | `~/.zcode/cli/config.json` |
|
|
206
206
|
|
|
207
|
-
2. **同步技能包**(`firmwareloop`、`fwloop-adapter
|
|
207
|
+
2. **同步技能包**(`firmwareloop`、`fwloop-adapter`)到各 Agent 的全局 Skill 目录(探测式:Agent 主目录存在才写入,`skills/` 子目录自动创建):
|
|
208
|
+
|
|
209
|
+
| Agent | Skill 写入位置 |
|
|
210
|
+
|---|---|
|
|
211
|
+
| Google Antigravity / Gemini CLI | `~/.gemini/antigravity-cli/skills/` |
|
|
212
|
+
| Claude Code CLI | `~/.claude/skills/` |
|
|
213
|
+
| Qoder / Qoder CN | `~/.qoder/skills/`、`~/.qoder-cn/skills/` |
|
|
214
|
+
| CodeBuddy IDE | `~/.codebuddy/skills/` |
|
|
215
|
+
| DeepSeek Harness (DSH) | `~/.dsh/skills/` |
|
|
216
|
+
| ZCode IDE | `~/.zcode/skills/` |
|
|
217
|
+
| 通用(跨 Agent 工具链) | `~/.agents/skills/`(特殊:无"未安装"概念,机器上不存在时直接创建) |
|
|
208
218
|
3. **生成机器级全局配置** `%APPDATA%\FirmwareLoop\lab.yaml`(NdtBox 配置模板,已存在则不覆盖)。
|
|
209
219
|
|
|
210
220
|
> 手动注册(可选):Claude Code 也可逐条注册,效果相同:
|
|
@@ -409,7 +419,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
409
419
|
├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
|
|
410
420
|
├── demo-make/ 示例固件(Make;构建测试载体)
|
|
411
421
|
├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
|
|
412
|
-
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.
|
|
422
|
+
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.2)
|
|
413
423
|
├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
|
|
414
424
|
├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
|
|
415
425
|
├── CLAUDE.md Claude Code CLI 指南
|
|
@@ -419,7 +429,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
419
429
|
|
|
420
430
|
---
|
|
421
431
|
|
|
422
|
-
## 能力验证状态(v0.11.
|
|
432
|
+
## 能力验证状态(v0.11.2)
|
|
423
433
|
|
|
424
434
|
> 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
|
|
425
435
|
> `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: firmwareloop
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.2
|
|
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
|
|
@@ -234,7 +234,17 @@ fwloop setup
|
|
|
234
234
|
| DeepSeek Harness (DSH) | `~/.dsh/profiles/<已派生 profile>/cordis.patch.yml` |
|
|
235
235
|
| ZCode IDE | `~/.zcode/cli/config.json` |
|
|
236
236
|
|
|
237
|
-
2. **同步技能包**(`firmwareloop`、`fwloop-adapter
|
|
237
|
+
2. **同步技能包**(`firmwareloop`、`fwloop-adapter`)到各 Agent 的全局 Skill 目录(探测式:Agent 主目录存在才写入,`skills/` 子目录自动创建):
|
|
238
|
+
|
|
239
|
+
| Agent | Skill 写入位置 |
|
|
240
|
+
|---|---|
|
|
241
|
+
| Google Antigravity / Gemini CLI | `~/.gemini/antigravity-cli/skills/` |
|
|
242
|
+
| Claude Code CLI | `~/.claude/skills/` |
|
|
243
|
+
| Qoder / Qoder CN | `~/.qoder/skills/`、`~/.qoder-cn/skills/` |
|
|
244
|
+
| CodeBuddy IDE | `~/.codebuddy/skills/` |
|
|
245
|
+
| DeepSeek Harness (DSH) | `~/.dsh/skills/` |
|
|
246
|
+
| ZCode IDE | `~/.zcode/skills/` |
|
|
247
|
+
| 通用(跨 Agent 工具链) | `~/.agents/skills/`(特殊:无"未安装"概念,机器上不存在时直接创建) |
|
|
238
248
|
3. **生成机器级全局配置** `%APPDATA%\FirmwareLoop\lab.yaml`(NdtBox 配置模板,已存在则不覆盖)。
|
|
239
249
|
|
|
240
250
|
> 手动注册(可选):Claude Code 也可逐条注册,效果相同:
|
|
@@ -439,7 +449,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
439
449
|
├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
|
|
440
450
|
├── demo-make/ 示例固件(Make;构建测试载体)
|
|
441
451
|
├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
|
|
442
|
-
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.
|
|
452
|
+
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.2)
|
|
443
453
|
├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
|
|
444
454
|
├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
|
|
445
455
|
├── CLAUDE.md Claude Code CLI 指南
|
|
@@ -449,7 +459,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
449
459
|
|
|
450
460
|
---
|
|
451
461
|
|
|
452
|
-
## 能力验证状态(v0.11.
|
|
462
|
+
## 能力验证状态(v0.11.2)
|
|
453
463
|
|
|
454
464
|
> 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
|
|
455
465
|
> `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
|
|
@@ -61,8 +61,8 @@ if ($Backend -eq 'agentic-hil' -and -not $tool) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
# Resolve lab config for adapter/channel/bitrate defaults (never hardcoded)
|
|
64
|
-
$labCfg = Join-Path $repoRoot 'lab
|
|
65
|
-
if (-not (Test-Path -LiteralPath $labCfg)) { $labCfg = Join-Path $repoRoot 'lab
|
|
64
|
+
$labCfg = Join-Path (Join-Path $repoRoot 'lab') 'lab.yaml'
|
|
65
|
+
if (-not (Test-Path -LiteralPath $labCfg)) { $labCfg = Join-Path (Join-Path $repoRoot 'lab') 'lab.example.yaml' }
|
|
66
66
|
$canCfg = @{}
|
|
67
67
|
if (Test-Path -LiteralPath $labCfg) {
|
|
68
68
|
try {
|
|
@@ -87,7 +87,7 @@ switch ($Backend) {
|
|
|
87
87
|
Exit-WithError -Class 'TOOLCHAIN_NOT_FOUND' -Message 'pyocd 未找到。请在 Python 环境中安装 pyocd (`uv pip install pyocd`)。' -Detail 'pyOCD 用于通过 ST-LINK / CMSIS-DAP 烧录 STM32 芯片。'
|
|
88
88
|
}
|
|
89
89
|
$targetChip = 'stm32f103rc'
|
|
90
|
-
$labYaml = Join-Path $repoRoot 'lab
|
|
90
|
+
$labYaml = Join-Path (Join-Path $repoRoot 'lab') 'lab.yaml'
|
|
91
91
|
if (Test-Path -LiteralPath $labYaml) {
|
|
92
92
|
$labContent = Get-Content -LiteralPath $labYaml -Raw
|
|
93
93
|
if ($labContent -match 'target_chip:\s*["'']?([^"''\r\n]+)') {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
fw_mcp_server.py - FirmwareLoop High-Level Workflow & Device MCP Server (v0.11.
|
|
3
|
+
fw_mcp_server.py - FirmwareLoop High-Level Workflow & Device MCP Server (v0.11.2).
|
|
4
4
|
|
|
5
5
|
Exposes high-level firmware engineering and hardware management tools to AI Coding
|
|
6
6
|
Agents (Antigravity CLI, Claude Code CLI, Qoder IDE, CodeBuddy IDE, DeepSeek Harness,
|
|
@@ -2610,7 +2610,7 @@ def process_request(req: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
|
2610
2610
|
},
|
|
2611
2611
|
"serverInfo": {
|
|
2612
2612
|
"name": "firmwareloop",
|
|
2613
|
-
"version": "0.11.
|
|
2613
|
+
"version": "0.11.2"
|
|
2614
2614
|
}
|
|
2615
2615
|
}
|
|
2616
2616
|
}
|
|
@@ -2745,7 +2745,7 @@ def _settle_stashed_entrypoints(stashed) -> None:
|
|
|
2745
2745
|
def handle_cli_update() -> int:
|
|
2746
2746
|
"""Handle `firmwareloop update` command."""
|
|
2747
2747
|
print("============================================================")
|
|
2748
|
-
print(" FirmwareLoop Auto-Updater (v0.11.
|
|
2748
|
+
print(" FirmwareLoop Auto-Updater (v0.11.2)")
|
|
2749
2749
|
print("============================================================")
|
|
2750
2750
|
|
|
2751
2751
|
is_git_repo = os.path.exists(os.path.join(REPO_ROOT, ".git"))
|
|
@@ -3224,6 +3224,67 @@ def configure_codebuddy_user_mcp(user_home: str) -> Dict[str, Any]:
|
|
|
3224
3224
|
return {"ok": False, "path": mcp_file, "reason": str(exc)}
|
|
3225
3225
|
|
|
3226
3226
|
|
|
3227
|
+
# setup [7] Skill 同步目标: 与 MCP 注册列表对齐 (MCP 支持哪个 Agent, Skill 就配哪个),
|
|
3228
|
+
# 另含 .agents 跨 Agent 通用约定。顺序对齐 setup 的 MCP 段编号。
|
|
3229
|
+
# 形状均为 <agent主目录>/<skills相对路径>/<skill>/<name>/SKILL.md; 探测判据 = agent
|
|
3230
|
+
# 主目录存在 (与各 MCP 段的 not_installed 语义一致; skills/ 子目录不存在时自动创建)。
|
|
3231
|
+
# 例外: .agents 是跨 Agent 通用约定, 无"未安装"概念 -> install_dir=None 免探测,
|
|
3232
|
+
# 机器上不存在时直接创建 ~/.agents 写入。
|
|
3233
|
+
SKILL_SYNC_TARGETS = [
|
|
3234
|
+
# (显示名, agent 主目录[安装探测判据; None=通用免探测], 全局 skills 目录相对 user_home)
|
|
3235
|
+
("Antigravity", ".gemini", os.path.join(".gemini", "antigravity-cli", "skills")),
|
|
3236
|
+
("Claude Code", ".claude", os.path.join(".claude", "skills")),
|
|
3237
|
+
("Qoder", ".qoder", os.path.join(".qoder", "skills")),
|
|
3238
|
+
("Qoder CN", ".qoder-cn", os.path.join(".qoder-cn", "skills")),
|
|
3239
|
+
("CodeBuddy", ".codebuddy", os.path.join(".codebuddy", "skills")),
|
|
3240
|
+
("DSH", ".dsh", os.path.join(".dsh", "skills")),
|
|
3241
|
+
("ZCode", ".zcode", os.path.join(".zcode", "skills")),
|
|
3242
|
+
(".agents (cross-agent)", None, os.path.join(".agents", "skills")),
|
|
3243
|
+
]
|
|
3244
|
+
|
|
3245
|
+
GLOBAL_SKILL_NAMES = ("firmwareloop", "fwloop-adapter")
|
|
3246
|
+
|
|
3247
|
+
|
|
3248
|
+
def sync_global_skills(user_home: str) -> List[Dict[str, Any]]:
|
|
3249
|
+
"""把 GLOBAL_SKILL_NAMES 中的 skill 同步到各 Agent 全局 skills 目录 (表驱动)。
|
|
3250
|
+
|
|
3251
|
+
- 目标来自 SKILL_SYNC_TARGETS (与 setup 的 MCP 注册面对齐);
|
|
3252
|
+
- 探测语义与 MCP 段一致: agent 主目录不存在 -> not_installed 跳过, 不创建;
|
|
3253
|
+
install_dir=None 的通用目标 (.agents) 免探测, 不存在时直接创建;
|
|
3254
|
+
- 已存在的 SKILL.md 无条件覆盖 (与既有 Antigravity/Claude 行为一致, 顺带
|
|
3255
|
+
消除 skills-marketplace/手工安装造成的版本漂移);
|
|
3256
|
+
- 源解析走 _skill_template_path(): 仓库 skills/ 优先, 安装态回退包内 templates。
|
|
3257
|
+
返回 per-agent 结果: {"agent", "ok", "path", "synced"/"reason"/"warnings"}。
|
|
3258
|
+
"""
|
|
3259
|
+
results: List[Dict[str, Any]] = []
|
|
3260
|
+
for label, install_dir, skills_rel in SKILL_SYNC_TARGETS:
|
|
3261
|
+
skills_dir = os.path.join(user_home, skills_rel)
|
|
3262
|
+
if install_dir is not None and not os.path.isdir(os.path.join(user_home, install_dir)):
|
|
3263
|
+
results.append({"agent": label, "ok": False, "path": skills_dir,
|
|
3264
|
+
"reason": "not_installed"})
|
|
3265
|
+
continue
|
|
3266
|
+
synced: List[str] = []
|
|
3267
|
+
warnings: List[str] = []
|
|
3268
|
+
for sk in GLOBAL_SKILL_NAMES:
|
|
3269
|
+
sk_src = _skill_template_path(sk)
|
|
3270
|
+
if not sk_src:
|
|
3271
|
+
warnings.append(f"{sk}: 源缺失 (仓库 skills/ 与包内 templates/ 均未找到)")
|
|
3272
|
+
continue
|
|
3273
|
+
try:
|
|
3274
|
+
target = os.path.join(skills_dir, sk)
|
|
3275
|
+
os.makedirs(target, exist_ok=True)
|
|
3276
|
+
shutil.copyfile(sk_src, os.path.join(target, "SKILL.md"))
|
|
3277
|
+
synced.append(sk)
|
|
3278
|
+
except OSError as exc:
|
|
3279
|
+
warnings.append(f"{sk}: {exc}")
|
|
3280
|
+
entry: Dict[str, Any] = {"agent": label, "ok": bool(synced),
|
|
3281
|
+
"path": skills_dir, "synced": synced}
|
|
3282
|
+
if warnings:
|
|
3283
|
+
entry["warnings"] = warnings
|
|
3284
|
+
results.append(entry)
|
|
3285
|
+
return results
|
|
3286
|
+
|
|
3287
|
+
|
|
3227
3288
|
DSH_MCP_CLIENT_PLUGIN = "@deepseek-ai/dsh-mcp-client"
|
|
3228
3289
|
|
|
3229
3290
|
# DSH (DeepSeek Harness) profile patch entries. Tools surface as
|
|
@@ -3498,7 +3559,7 @@ def set_ndtdbg_dlldir(dll_path: str) -> str:
|
|
|
3498
3559
|
def handle_cli_setup() -> int:
|
|
3499
3560
|
"""Handle `firmwareloop setup` command: simultaneously configure Antigravity CLI, Claude Code CLI, Qoder IDE, CodeBuddy IDE, DeepSeek Harness (DSH), and ZCode IDE."""
|
|
3500
3561
|
print("============================================================")
|
|
3501
|
-
print(" FirmwareLoop Multi-Agent Global Setup Helper (v0.11.
|
|
3562
|
+
print(" FirmwareLoop Multi-Agent Global Setup Helper (v0.11.2)")
|
|
3502
3563
|
print("============================================================")
|
|
3503
3564
|
print("")
|
|
3504
3565
|
|
|
@@ -3612,30 +3673,19 @@ def handle_cli_setup() -> int:
|
|
|
3612
3673
|
else:
|
|
3613
3674
|
print(f" - User MCP: [Warning] Could not write {zc_result['path']}: {zc_result.get('reason')}")
|
|
3614
3675
|
|
|
3615
|
-
# 7. Global Skills Sync
|
|
3616
|
-
#
|
|
3617
|
-
#
|
|
3676
|
+
# 7. Global Skills Sync — 目标表驱动 (SKILL_SYNC_TARGETS), 与 MCP 注册面全量对齐
|
|
3677
|
+
# (外加 .agents 跨 Agent 通用约定); 探测式 (agent 主目录存在才写, not_installed
|
|
3678
|
+
# 跳过)。源解析 (v0.9.2): 仓库 skills/<name>/SKILL.md 优先, 安装态回退包内
|
|
3679
|
+
# tools/templates/skill-<name>.md (skills/ 不随 wheel 分发)。
|
|
3618
3680
|
print(f"\n[7] Global Skills:")
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
try:
|
|
3628
|
-
ag_target = os.path.join(ag_skills_dir, sk)
|
|
3629
|
-
os.makedirs(ag_target, exist_ok=True)
|
|
3630
|
-
shutil.copyfile(sk_src, os.path.join(ag_target, "SKILL.md"))
|
|
3631
|
-
|
|
3632
|
-
cl_target = os.path.join(claude_skills_dir, sk)
|
|
3633
|
-
os.makedirs(cl_target, exist_ok=True)
|
|
3634
|
-
shutil.copyfile(sk_src, os.path.join(cl_target, "SKILL.md"))
|
|
3635
|
-
skills_synced += 1
|
|
3636
|
-
except Exception as exc: # noqa: BLE001
|
|
3637
|
-
print(f" - {sk}: [Warning] {exc}")
|
|
3638
|
-
print(f" - Synchronized: [OK] {skills_synced} skills (firmwareloop, fwloop-adapter) to Antigravity & Claude Code")
|
|
3681
|
+
for item in sync_global_skills(user_home):
|
|
3682
|
+
if item["ok"]:
|
|
3683
|
+
print(f" - {item['agent']}: [OK] {', '.join(item['synced'])} -> {item['path']}")
|
|
3684
|
+
elif item.get("reason") == "not_installed":
|
|
3685
|
+
print(f" - {item['agent']}: agent 主目录不存在, 跳过 (not_installed)")
|
|
3686
|
+
else:
|
|
3687
|
+
for warn in item.get("warnings") or [item.get("reason") or "unknown"]:
|
|
3688
|
+
print(f" - {item['agent']}: [Warning] {warn}")
|
|
3639
3689
|
|
|
3640
3690
|
# 8. Machine-level global lab.yaml (ndtdbg config for the globally installed tool)
|
|
3641
3691
|
global_cfg = ensure_global_lab_yaml()
|
|
@@ -3654,7 +3704,7 @@ def handle_cli_setup() -> int:
|
|
|
3654
3704
|
def handle_cli_init(chip: Optional[str] = None, upgrade: bool = False) -> int:
|
|
3655
3705
|
"""Handle `firmwareloop init [target_chip]` command."""
|
|
3656
3706
|
print("============================================================")
|
|
3657
|
-
print(" FirmwareLoop Multi-Agent Project Initializer (v0.11.
|
|
3707
|
+
print(" FirmwareLoop Multi-Agent Project Initializer (v0.11.2)")
|
|
3658
3708
|
print("============================================================")
|
|
3659
3709
|
cwd = os.getcwd()
|
|
3660
3710
|
print(f"[*] Initializing multi-agent guidelines & bench config in:\n {cwd}\n")
|
|
@@ -3687,7 +3737,7 @@ def handle_cli_init(chip: Optional[str] = None, upgrade: bool = False) -> int:
|
|
|
3687
3737
|
|
|
3688
3738
|
|
|
3689
3739
|
def print_cli_help() -> None:
|
|
3690
|
-
print("""FirmwareLoop (fwloop) — AI Agent Firmware Engineering & Lab Automation Platform (v0.11.
|
|
3740
|
+
print("""FirmwareLoop (fwloop) — AI Agent Firmware Engineering & Lab Automation Platform (v0.11.2)
|
|
3691
3741
|
|
|
3692
3742
|
Usage:
|
|
3693
3743
|
fwloop [command] (or: firmwareloop [command])
|
|
@@ -3737,7 +3787,7 @@ def main() -> None:
|
|
|
3737
3787
|
elif cmd in ["describe", "contract", "tools"]:
|
|
3738
3788
|
sys.exit(handle_cli_describe(args[1] if len(args) > 1 else None))
|
|
3739
3789
|
elif cmd in ["version", "-v", "--version"]:
|
|
3740
|
-
print("FirmwareLoop v0.11.
|
|
3790
|
+
print("FirmwareLoop v0.11.2")
|
|
3741
3791
|
sys.exit(0)
|
|
3742
3792
|
elif cmd in ["help", "-h", "--help"]:
|
|
3743
3793
|
print_cli_help()
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# 离线交付包安装器(NSIS 源码)
|
|
2
|
+
|
|
3
|
+
这份目录收纳 `Fwloop_setup_pack` 一键安装器的 **NSIS 源码**(此前只存在于构建机的临时目录,
|
|
4
|
+
丢失后无法重编 —— 2026-09-14 收纳入库)。
|
|
5
|
+
|
|
6
|
+
| 文件 | 产物 | 用途 |
|
|
7
|
+
| :--- | :--- | :--- |
|
|
8
|
+
| `deploy_setup.nsi` | `Fwloop_setup_pack\fwloop-deploy-setup.exe` | 一键部署:fwloop 离线安装 + Agent 注册 + NdtBox 配置 + Saleae 固件 + sigrok-cli |
|
|
9
|
+
| `install_firmware.nsi` | `Fwloop_setup_pack\assets\saleae-logic16-firmware-setup.exe` | Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware`(支持 `/S`) |
|
|
10
|
+
|
|
11
|
+
## 什么时候需要重编译
|
|
12
|
+
|
|
13
|
+
**只需要同步 firmwareloop 版本时 —— 不需要**。安装器**不内嵌** wheels/python:它在目标机上从
|
|
14
|
+
`$EXEDIR\assets\wheels` 离线安装(`uv tool install --find-links "$EXEDIR\assets\wheels" --offline ...`)。
|
|
15
|
+
同步固件包版本的步骤:
|
|
16
|
+
|
|
17
|
+
1. `uv build` 生成新 wheel;
|
|
18
|
+
2. 用新 wheel 替换 `Fwloop_setup_pack\assets\wheels\firmwareloop-<旧>.whl`(依赖 wheel 不变则不动);
|
|
19
|
+
3. 更新 `Fwloop_setup_pack\README.md` 里的版本引用;
|
|
20
|
+
4. 离线冒烟:`uv pip install --offline --find-links Fwloop_setup_pack\assets\wheels "firmwareloop==<新版本>"`
|
|
21
|
+
(装进临时 venv,验证 `fwloop --version`)。
|
|
22
|
+
|
|
23
|
+
**改了安装器逻辑 / 升级内嵌 uv.exe 时 —— 需要**(见下)。
|
|
24
|
+
|
|
25
|
+
## 如何编译
|
|
26
|
+
|
|
27
|
+
1. 工具链:NSIS 3.08(https://nsis.sourceforge.io/download/ ,本机历史构建放在 `.tmp\nsis-build\nsis-3.08\`,
|
|
28
|
+
该目录易失,丢了重新下载解压即可)。
|
|
29
|
+
2. 在**含 nsis-3.08 的目录**下执行(nsi 里的 `OutFile` 与资源相对路径按当时布局写死):
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
cd <含 nsis-3.08 的目录> # 例: .tmp\nsis-build
|
|
33
|
+
.\nsis-3.08\makensis.exe deploy_setup.nsi
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. `deploy_setup.nsi` 的 `OutFile` 是**绝对路径**(指向 `Fwloop_setup_pack\fwloop-deploy-setup.exe`),
|
|
37
|
+
换机器/换布局时先改这一行;资源引用形如 `..\..\Fwloop_setup_pack\assets\uv\uv.exe`(内嵌的只有 uv.exe)。
|
|
38
|
+
|
|
39
|
+
## 交付包同步清单(每次发版)
|
|
40
|
+
|
|
41
|
+
1. `uv build` + 替换 `assets\wheels\firmwareloop-*.whl`;
|
|
42
|
+
2. 更新 `Fwloop_setup_pack\README.md` 的版本引用(`版本要求` / `wheels` 描述 / `fwloop version` 注释);
|
|
43
|
+
3. 离线冒烟(上面的第 4 步);
|
|
44
|
+
4. **不必**重编译 `fwloop-deploy-setup.exe`(除非改了安装器逻辑)。
|
|
@@ -1123,6 +1123,17 @@ def pid_alive(pid: int | None) -> bool:
|
|
|
1123
1123
|
out = subprocess.run(["tasklist", "/FI", f"PID eq {int(pid)}", "/NH"],
|
|
1124
1124
|
capture_output=True, text=True, timeout=10)
|
|
1125
1125
|
return str(int(pid)) in (out.stdout or "")
|
|
1126
|
+
# POSIX: 已退出但未被父进程收割的僵尸进程, os.kill(pid, 0) 依然报存活
|
|
1127
|
+
# -> wait_pid_exit 永远超时 (CI Linux 实测)。/proc 可读时以进程状态为准。
|
|
1128
|
+
stat_path = f"/proc/{int(pid)}/stat"
|
|
1129
|
+
if os.path.exists(stat_path):
|
|
1130
|
+
try:
|
|
1131
|
+
with open(stat_path, encoding="utf-8") as fh:
|
|
1132
|
+
state = fh.read().rsplit(")", 1)[-1].strip()[:1]
|
|
1133
|
+
if state:
|
|
1134
|
+
return state != "Z"
|
|
1135
|
+
except OSError:
|
|
1136
|
+
pass # /proc 读失败 (非 Linux) -> 回退 os.kill 探测
|
|
1126
1137
|
os.kill(int(pid), 0)
|
|
1127
1138
|
return True
|
|
1128
1139
|
except Exception: # noqa: BLE001
|
|
@@ -67,11 +67,11 @@ if ($Backend -eq 'sigrok') {
|
|
|
67
67
|
# ---- output layout ------------------------------------------------------------
|
|
68
68
|
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
|
|
69
69
|
$runId = Get-FwRunId
|
|
70
|
-
if (-not $OutDir) { $OutDir = Join-Path $repoRoot
|
|
70
|
+
if (-not $OutDir) { $OutDir = Join-Path (Join-Path (Join-Path $repoRoot 'artifacts') 'captures') $runId }
|
|
71
71
|
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null
|
|
72
72
|
|
|
73
73
|
# decoder config snapshot (read from lab/protocol-decode.yaml if present)
|
|
74
|
-
$decodeCfg = Join-Path $repoRoot 'lab
|
|
74
|
+
$decodeCfg = Join-Path (Join-Path $repoRoot 'lab') 'protocol-decode.yaml'
|
|
75
75
|
$configOut = Join-Path $OutDir 'decoder-config.yaml'
|
|
76
76
|
if (Test-Path -LiteralPath $decodeCfg) {
|
|
77
77
|
Copy-Item -LiteralPath $decodeCfg -Destination $configOut -Force
|
|
@@ -265,8 +265,8 @@ else {
|
|
|
265
265
|
if ($deriveRes.exit_code -ne 0 -or -not (Test-Path -LiteralPath $rawSigrok)) {
|
|
266
266
|
Exit-WithError -Class 'LOGIC_CAPTURE_ERROR' -Message 'sigrok-cli CSV export from capture.sr failed.' -Detail ($deriveRes.stdout + $deriveRes.stderr)
|
|
267
267
|
}
|
|
268
|
-
$convScript = Join-Path $repoRoot 'tools
|
|
269
|
-
$py = Resolve-FwPython
|
|
268
|
+
$convScript = Join-Path (Join-Path $repoRoot 'tools') 'sigrok_csv_to_fwloop.py'
|
|
269
|
+
$py = Resolve-FwPython -RepoRoot $repoRoot
|
|
270
270
|
$convRes = Invoke-FwProcess -FilePath $py -Arguments @($convScript, $rawSigrok, $rawFile, $SampleRateHz) `
|
|
271
271
|
-WorkingDirectory $repoRoot -TimeoutMs 120000
|
|
272
272
|
if ($convRes.exit_code -ne 0 -or -not (Test-Path -LiteralPath $rawFile)) {
|
|
@@ -281,12 +281,12 @@ else {
|
|
|
281
281
|
# ---- 摘要: 实际时长/截断 + 每通道活动 + 接线判定 (v0.9.2) ------------------------
|
|
282
282
|
$summary = $null
|
|
283
283
|
$summaryPath = Join-Path $OutDir 'capture-summary.json'
|
|
284
|
-
$sumScript = Join-Path $repoRoot 'tools
|
|
285
|
-
$sumPy = Resolve-FwPython
|
|
284
|
+
$sumScript = Join-Path (Join-Path $repoRoot 'tools') 'logic_capture_summary.py'
|
|
285
|
+
$sumPy = Resolve-FwPython -RepoRoot $repoRoot
|
|
286
286
|
if ((Test-Path -LiteralPath $sumScript) -and $sumPy) {
|
|
287
287
|
$sumArgs = @($sumScript, $rawFile, '--protocol', $Protocol, '--out', $summaryPath)
|
|
288
288
|
if ($Backend -eq 'sigrok') { $sumArgs += @('--requested-s', "$DurationSec") }
|
|
289
|
-
$cfgPath = Join-Path $repoRoot 'lab
|
|
289
|
+
$cfgPath = Join-Path (Join-Path $repoRoot 'lab') 'protocol-decode.yaml'
|
|
290
290
|
if (Test-Path -LiteralPath $cfgPath) { $sumArgs += @('--config', $cfgPath) }
|
|
291
291
|
$sumRes = Invoke-FwProcess -FilePath $sumPy -Arguments $sumArgs -WorkingDirectory $repoRoot -TimeoutMs 60000
|
|
292
292
|
if ($sumRes.exit_code -eq 0) {
|
|
@@ -96,7 +96,9 @@ if (-not (Test-Path -LiteralPath $rawFile)) {
|
|
|
96
96
|
|
|
97
97
|
# ---- protocol/config resolution ------------------------------------------------
|
|
98
98
|
$cfg = @{}
|
|
99
|
-
|
|
99
|
+
# 跨平台注意: 子路径分段 Join-Path (字面量 'lab\protocol-decode.yaml' 在 Linux pwsh
|
|
100
|
+
# 会变成文件名含反斜杠的单段路径, Test-Path 恒 False -> 通道映射静默回落 builtin-default)
|
|
101
|
+
$cfgPath = Join-Path (Join-Path $repoRoot 'lab') 'protocol-decode.yaml'
|
|
100
102
|
# YAML is not natively parseable in PowerShell; the venv python + PyYAML does it.
|
|
101
103
|
if ($meta -and $meta.protocol) { $reqProtocol = [string]$meta.protocol } else { $reqProtocol = $null }
|
|
102
104
|
if ($Protocol) { $reqProtocol = $Protocol }
|
|
@@ -110,7 +112,8 @@ $signalMap = [ordered]@{}
|
|
|
110
112
|
$channelMapSource = 'builtin-default'
|
|
111
113
|
$cfgBaud = 0
|
|
112
114
|
if (Test-Path -LiteralPath $cfgPath) {
|
|
113
|
-
|
|
115
|
+
# -RepoRoot 必传: 裸调用只找 PATH python, CI 上是没装 pyyaml 的系统解释器 -> 解析失败
|
|
116
|
+
$pyCfg = Resolve-FwPython -RepoRoot $repoRoot
|
|
114
117
|
if ($pyCfg) {
|
|
115
118
|
$pyScript = "import json,sys;sys.stdout.reconfigure(encoding='utf-8',errors='replace');" +
|
|
116
119
|
"import yaml;d=(yaml.safe_load(open(sys.argv[1],encoding='utf-8')) or {});" +
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<#
|
|
2
2
|
.SYNOPSIS
|
|
3
|
-
Dual-Tier MCP setup and registration helper (v0.11.
|
|
3
|
+
Dual-Tier MCP setup and registration helper (v0.11.2).
|
|
4
4
|
Inspects installed AI coding agents (Qoder, Claude Code, Antigravity, Cursor)
|
|
5
5
|
and configures global MCP / skills or prints exact registration commands.
|
|
6
6
|
|
|
@@ -242,7 +242,7 @@ if ($Json) {
|
|
|
242
242
|
Write-FwJson ([pscustomobject]$report)
|
|
243
243
|
} else {
|
|
244
244
|
Write-Host "============================================================" -ForegroundColor Cyan
|
|
245
|
-
Write-Host " FirmwareLoop Dual-Tier MCP & Agent Setup Helper (v0.11.
|
|
245
|
+
Write-Host " FirmwareLoop Dual-Tier MCP & Agent Setup Helper (v0.11.2)" -ForegroundColor Green
|
|
246
246
|
Write-Host "============================================================" -ForegroundColor Cyan
|
|
247
247
|
Write-Host ""
|
|
248
248
|
Write-Host "[1] Google Antigravity / Gemini CLI:" -ForegroundColor Yellow
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|