firmwareloop 0.1.1__tar.gz → 0.1.3__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 (35) hide show
  1. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/PKG-INFO +3 -3
  2. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/README.md +2 -2
  3. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/firmwareloop.egg-info/PKG-INFO +3 -3
  4. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/pyproject.toml +1 -1
  5. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/__init__.py +1 -1
  6. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/fw_mcp_server.py +114 -8
  7. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/logic_decode.ps1 +1 -0
  8. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/ndtdbg_bridge.ps1 +6 -4
  9. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/setup-agent-mcp.ps1 +2 -2
  10. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/LICENSE +0 -0
  11. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/firmwareloop.egg-info/SOURCES.txt +0 -0
  12. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/firmwareloop.egg-info/dependency_links.txt +0 -0
  13. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/firmwareloop.egg-info/entry_points.txt +0 -0
  14. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/firmwareloop.egg-info/requires.txt +0 -0
  15. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/firmwareloop.egg-info/top_level.txt +0 -0
  16. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/setup.cfg +0 -0
  17. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/acceptance-scenario.ps1 +0 -0
  18. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/build.ps1 +0 -0
  19. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/can.ps1 +0 -0
  20. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/check-qoder-mcp.ps1 +0 -0
  21. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/common/build-backends.psm1 +0 -0
  22. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/common/fw.psm1 +0 -0
  23. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/common/uart_probe.py +0 -0
  24. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/doctor.ps1 +0 -0
  25. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/flash.ps1 +0 -0
  26. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/instrument_cli.py +0 -0
  27. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/lib/__init__.py +0 -0
  28. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/lib/instruments.py +0 -0
  29. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/lib/ndtdbg.py +0 -0
  30. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/logic_capture.ps1 +0 -0
  31. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/ndtdbg_cli.py +0 -0
  32. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/reset.ps1 +0 -0
  33. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/sigrok_csv_to_fwloop.py +0 -0
  34. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/test-backends.ps1 +0 -0
  35. {firmwareloop-0.1.1 → firmwareloop-0.1.3}/tools/test.ps1 +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firmwareloop
3
- Version: 0.1.1
3
+ Version: 0.1.3
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
@@ -338,7 +338,7 @@ claude mcp remove --scope user agentic-hil
338
338
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
339
339
  ├── demo-make/ 示例固件(Make;构建测试载体)
340
340
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
341
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.1.1)
341
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.1.3)
342
342
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
343
343
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
344
344
  ├── CLAUDE.md Claude Code CLI 指南
@@ -348,7 +348,7 @@ claude mcp remove --scope user agentic-hil
348
348
 
349
349
  ---
350
350
 
351
- ## 能力验证状态(v0.1.1)
351
+ ## 能力验证状态(v0.1.3)
352
352
 
353
353
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
354
354
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -310,7 +310,7 @@ claude mcp remove --scope user agentic-hil
310
310
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
311
311
  ├── demo-make/ 示例固件(Make;构建测试载体)
312
312
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
313
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.1.1)
313
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.1.3)
314
314
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
315
315
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
316
316
  ├── CLAUDE.md Claude Code CLI 指南
@@ -320,7 +320,7 @@ claude mcp remove --scope user agentic-hil
320
320
 
321
321
  ---
322
322
 
323
- ## 能力验证状态(v0.1.1)
323
+ ## 能力验证状态(v0.1.3)
324
324
 
325
325
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
326
326
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firmwareloop
3
- Version: 0.1.1
3
+ Version: 0.1.3
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
@@ -338,7 +338,7 @@ claude mcp remove --scope user agentic-hil
338
338
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
339
339
  ├── demo-make/ 示例固件(Make;构建测试载体)
340
340
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
341
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.1.1)
341
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.1.3)
342
342
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
343
343
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
344
344
  ├── CLAUDE.md Claude Code CLI 指南
@@ -348,7 +348,7 @@ claude mcp remove --scope user agentic-hil
348
348
 
349
349
  ---
350
350
 
351
- ## 能力验证状态(v0.1.1)
351
+ ## 能力验证状态(v0.1.3)
352
352
 
353
353
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
354
354
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "firmwareloop"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  description = "AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -2,4 +2,4 @@
2
2
  FirmwareLoop - AI Agent Firmware Development and Lab Automation Platform.
3
3
  """
4
4
 
5
- __version__ = "0.1.1"
5
+ __version__ = "0.1.3"
@@ -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.1.1).
3
+ fw_mcp_server.py - FirmwareLoop High-Level Workflow & Device MCP Server (v0.1.3).
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, Cursor) via the Model Context
@@ -18,6 +18,7 @@ Tools provided:
18
18
  - fw_ndtdbg_measure: NdtBox pressure-sensor data stream polling over IIC (ndtdbg_cli.py)
19
19
  - fw_ndtdbg_read_reg: NdtBox IIC register read (ndtdbg_cli.py)
20
20
  - fw_ndtdbg_write_reg: NdtBox IIC register write, double-gated (ndtdbg_cli.py)
21
+ - fw_ndtdbg_capture_seq: NdtBox register sequence + concurrent I2C capture for waveform evidence (ndtdbg_cli.py)
21
22
  - fw_logic_capture: Logic analyzer protocol capture (logic_capture.ps1)
22
23
  - fw_logic_decode: Logic analyzer protocol decoding & assertion (logic_decode.ps1)
23
24
  - fw_get_evidence: Read structured audit run evidence (artifacts/runs/)
@@ -305,6 +306,71 @@ def handle_fw_ndtdbg_write_reg(args: Dict[str, Any]) -> Dict[str, Any]:
305
306
  return res
306
307
 
307
308
 
309
+ def handle_fw_ndtdbg_capture_seq(args: Dict[str, Any]) -> Dict[str, Any]:
310
+ """单次调用内并发: 逻辑分析仪抓取与 NdtBox 寄存器序列同时进行。
311
+
312
+ MCP 工具调用不可并行, 串行调用无法让抓取窗口覆盖物理事务; 此工具在
313
+ handler 内以线程并发二者, 返回 capture 路径供 fw_logic_decode 消费。
314
+ """
315
+ import threading
316
+
317
+ cli_script = os.path.join(REPO_ROOT, "tools", "ndtdbg_cli.py")
318
+ cap_script = os.path.join(REPO_ROOT, "tools", "logic_capture.ps1")
319
+ duration_ms = int(args.get("duration_ms", 8000))
320
+ writes = args.get("writes", [{"reg": "0xBE", "data": "01"}, {"reg": "0x01", "data": "BE 42"}])
321
+ poll_reg = args.get("poll_reg", "0x01")
322
+ poll_attempts = int(args.get("poll_attempts", 5))
323
+ readback_reg = args.get("readback_reg", "0xBE")
324
+
325
+ cap_out: Dict[str, Any] = {}
326
+
327
+ def do_capture() -> None:
328
+ cap_cmd = [PWSH_EXE, "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass",
329
+ "-File", cap_script, "-Protocol", "i2c", "-Backend", "sigrok",
330
+ "-DurationSec", str(duration_ms / 1000.0), "-Json"]
331
+ cap_out.update(run_process(cap_cmd, timeout=duration_ms / 1000.0 + 120))
332
+
333
+ th = threading.Thread(target=do_capture)
334
+ th.start()
335
+
336
+ seq: Dict[str, Any] = {"writes": []}
337
+ try:
338
+ for w in writes:
339
+ write_cmd = [PYTHON_EXE, cli_script, "write-reg", "--addr", str(w.get("reg")),
340
+ "--data", str(w.get("data")), "--confirm"]
341
+ _ndtdbg_reg_args(args, write_cmd)
342
+ res = run_process(write_cmd, timeout=60)
343
+ seq["writes"].append({"reg": w.get("reg"), "data": w.get("data"),
344
+ "ok": bool(res.get("success")), "result": res if not res.get("success") else res.get("data")})
345
+ if poll_reg:
346
+ for attempt in range(poll_attempts + 1):
347
+ read_cmd = [PYTHON_EXE, cli_script, "read-reg", "--addr", str(poll_reg), "--len", "2"]
348
+ _ndtdbg_reg_args(args, read_cmd)
349
+ res = run_process(read_cmd, timeout=60)
350
+ val = (res.get("data") or {}).get("data", {}).get("hex", "")
351
+ seq["poll"] = {"reg": poll_reg, "attempts": attempt + 1, "hex": val,
352
+ "cleared": val == "00 00"}
353
+ if val == "00 00" or attempt >= poll_attempts:
354
+ break
355
+ import time
356
+ time.sleep(0.1)
357
+ if readback_reg:
358
+ read_cmd = [PYTHON_EXE, cli_script, "read-reg", "--addr", str(readback_reg), "--len", "1"]
359
+ _ndtdbg_reg_args(args, read_cmd)
360
+ res = run_process(read_cmd, timeout=60)
361
+ seq["readback"] = {"reg": readback_reg,
362
+ "hex": (res.get("data") or {}).get("data", {}).get("hex", "")}
363
+ finally:
364
+ th.join(timeout=duration_ms / 1000.0 + 180)
365
+
366
+ cap = cap_out.get("data") or cap_out
367
+ capture_path = None
368
+ if cap and isinstance(cap, dict):
369
+ capture_path = cap.get("capture")
370
+ return {"ok": bool(capture_path), "action": "capture-seq",
371
+ "sequence": seq, "capture": cap, "capture_path": capture_path}
372
+
373
+
308
374
  def handle_fw_logic_capture(args: Dict[str, Any]) -> Dict[str, Any]:
309
375
  script = os.path.join(REPO_ROOT, "tools", "logic_capture.ps1")
310
376
  cmd = [PWSH_EXE, "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, "-Json"]
@@ -1199,6 +1265,37 @@ TOOLS_REGISTRY = {
1199
1265
  },
1200
1266
  "handler": handle_fw_ndtdbg_write_reg,
1201
1267
  },
1268
+ "fw_ndtdbg_capture_seq": {
1269
+ "description": "One-call protocol evidence: concurrently runs a NdtBox register write sequence (default 0xBE=01, 0x01=BE 42, poll 0x01, readback 0xBE) and a 3s Saleae/sigrok I2C capture, returning the capture path for fw_logic_decode.",
1270
+ "inputSchema": {
1271
+ "type": "object",
1272
+ "properties": {
1273
+ "duration_ms": {
1274
+ "type": "integer",
1275
+ "description": "Logic capture duration in milliseconds",
1276
+ "default": 3000,
1277
+ },
1278
+ "writes": {
1279
+ "type": "array",
1280
+ "items": {
1281
+ "type": "object",
1282
+ "properties": {
1283
+ "reg": {"type": "string"},
1284
+ "data": {"type": "string"},
1285
+ },
1286
+ },
1287
+ "description": "Register write sequence (default 0xBE=01, 0x01=BE 42)",
1288
+ },
1289
+ "poll_reg": {"type": "string", "description": "Poll register until 00 00 (default 0x01)"},
1290
+ "poll_attempts": {"type": "integer", "description": "Max poll attempts", "default": 5},
1291
+ "readback_reg": {"type": "string", "description": "Read-back verification register (default 0xBE)"},
1292
+ "dll_dir": {"type": "string", "description": "NdtDebugTool lib directory; default from lab.yaml"},
1293
+ "slave_addr": {"type": "string", "description": "IIC slave address (e.g. 0xA0)"},
1294
+ },
1295
+ "additionalProperties": False,
1296
+ },
1297
+ "handler": handle_fw_ndtdbg_capture_seq,
1298
+ },
1202
1299
  "fw_logic_capture": {
1203
1300
  "description": "Capture digital protocol waveforms (I2C, SPI, UART) via Saleae / sigrok or deterministic simulator.",
1204
1301
  "inputSchema": {
@@ -1336,7 +1433,7 @@ def process_request(req: Dict[str, Any]) -> Optional[Dict[str, Any]]:
1336
1433
  },
1337
1434
  "serverInfo": {
1338
1435
  "name": "firmwareloop",
1339
- "version": "0.1.1"
1436
+ "version": "0.1.3"
1340
1437
  }
1341
1438
  }
1342
1439
  }
@@ -1428,7 +1525,7 @@ def process_request(req: Dict[str, Any]) -> Optional[Dict[str, Any]]:
1428
1525
  def handle_cli_update() -> int:
1429
1526
  """Handle `firmwareloop update` command."""
1430
1527
  print("============================================================")
1431
- print(" FirmwareLoop Auto-Updater (v0.1.1)")
1528
+ print(" FirmwareLoop Auto-Updater (v0.1.3)")
1432
1529
  print("============================================================")
1433
1530
 
1434
1531
  is_git_repo = os.path.exists(os.path.join(REPO_ROOT, ".git"))
@@ -1526,7 +1623,16 @@ def upsert_qoder_mcp_json(mcp_path: str, servers: Optional[Dict[str, Any]] = Non
1526
1623
  mcp_servers = data.get("mcpServers")
1527
1624
  if not isinstance(mcp_servers, dict):
1528
1625
  mcp_servers = {}
1529
- mcp_servers.update(payload)
1626
+ # Merge per-entry (not whole-key replace): keep existing per-server extras
1627
+ # like "env" (e.g. FW_LAB_CONFIG) that this payload does not define.
1628
+ for name, entry in payload.items():
1629
+ old = mcp_servers.get(name)
1630
+ if isinstance(old, dict) and isinstance(entry, dict):
1631
+ merged = dict(old)
1632
+ merged.update(entry)
1633
+ mcp_servers[name] = merged
1634
+ else:
1635
+ mcp_servers[name] = entry
1530
1636
  data["mcpServers"] = mcp_servers
1531
1637
  parent = os.path.dirname(mcp_path)
1532
1638
  if parent:
@@ -1571,7 +1677,7 @@ def configure_qoder_user_mcp(user_home: str) -> List[Dict[str, Any]]:
1571
1677
  def handle_cli_setup() -> int:
1572
1678
  """Handle `firmwareloop setup` command: simultaneously configure Antigravity CLI, Claude Code CLI, and Qoder IDE."""
1573
1679
  print("============================================================")
1574
- print(" FirmwareLoop Multi-Agent Global Setup Helper (v0.1.1)")
1680
+ print(" FirmwareLoop Multi-Agent Global Setup Helper (v0.1.3)")
1575
1681
  print("============================================================")
1576
1682
  print("")
1577
1683
 
@@ -1676,7 +1782,7 @@ def handle_cli_setup() -> int:
1676
1782
  def handle_cli_init() -> int:
1677
1783
  """Handle `firmwareloop init` command."""
1678
1784
  print("============================================================")
1679
- print(" FirmwareLoop Multi-Agent Project Initializer (v0.1.1)")
1785
+ print(" FirmwareLoop Multi-Agent Project Initializer (v0.1.3)")
1680
1786
  print("============================================================")
1681
1787
  cwd = os.getcwd()
1682
1788
  print(f"[*] Initializing multi-agent guidelines & bench config in:\n {cwd}\n")
@@ -1697,7 +1803,7 @@ def handle_cli_init() -> int:
1697
1803
 
1698
1804
 
1699
1805
  def print_cli_help() -> None:
1700
- print("""FirmwareLoop (fwloop) — AI Agent Firmware Engineering & Lab Automation Platform (v0.1.1)
1806
+ print("""FirmwareLoop (fwloop) — AI Agent Firmware Engineering & Lab Automation Platform (v0.1.3)
1701
1807
 
1702
1808
  Usage:
1703
1809
  fwloop [command] (or: firmwareloop [command])
@@ -1728,7 +1834,7 @@ def main() -> None:
1728
1834
  elif cmd in ["setup", "register"]:
1729
1835
  sys.exit(handle_cli_setup())
1730
1836
  elif cmd in ["version", "-v", "--version"]:
1731
- print("FirmwareLoop v0.1.1")
1837
+ print("FirmwareLoop v0.1.3")
1732
1838
  sys.exit(0)
1733
1839
  elif cmd in ["help", "-h", "--help"]:
1734
1840
  print_cli_help()
@@ -22,6 +22,7 @@ param(
22
22
  [string]$CaptureFile, # direct path to the raw CSV
23
23
  [ValidateSet('spi', 'uart', 'i2c')]
24
24
  [string]$Protocol, # override protocol (else read from metadata)
25
+ [int]$FrequencyHz = 0, # clock frequency hint (Hz); reserved for future decode validation
25
26
  [string]$Expect, # expected decoded value (hex string or text)
26
27
  [ValidateSet('hex', 'text')]
27
28
  [string]$ExpectKind = 'hex',
@@ -68,7 +68,7 @@ function Parse-Hex([string]$s) {
68
68
  try { $bytes[[int]($i / 2)] = [Convert]::ToByte($clean.Substring($i, 2), 16) }
69
69
  catch { Fail "CONFIG_ERROR" "Data 含非法十六进制字符" $clean.Substring($i, 2) }
70
70
  }
71
- return $bytes
71
+ return ,$bytes # PS 函数返回会展开单元素数组, 一元数组符保护类型
72
72
  }
73
73
 
74
74
  function Open-Device([int]$iIndex) {
@@ -103,10 +103,12 @@ function Read-Reg([uint32]$h, [int]$addr, [int]$reg, [int]$len) {
103
103
  return $rb
104
104
  }
105
105
 
106
- function Write-Reg([uint32]$h, [int]$addr, [int]$reg, [byte[]]$data) {
107
- $wb = New-Object byte[] (2 + $data.Length)
106
+ function Write-Reg([uint32]$h, [int]$addr, [int]$reg, $data) {
107
+ # 无类型约束 + 函数内强转: 兼容标量/单元素数组/byte[] 各种传参形态 (PS5.1 会展开单元素数组)
108
+ $bytes = [byte[]]@($data)
109
+ $wb = New-Object byte[] (2 + $bytes.Length)
108
110
  for ($i = 0; $i -lt $wb.Length; $i++) {
109
- if ($i -eq 0) { $wb[0] = $addr } elseif ($i -eq 1) { $wb[1] = $reg } else { $wb[$i] = $data[$i - 2] }
111
+ if ($i -eq 0) { $wb[0] = $addr } elseif ($i -eq 1) { $wb[1] = $reg } else { $wb[$i] = $bytes[$i - 2] }
110
112
  }
111
113
  if (-not (Invoke-WriteRead $h $wb (New-Object byte[] 0))) { Fail "TARGET_MISMATCH" ("IIC 写无应答 addr=0x{0:X2} reg=0x{1:X2}" -f $addr, $reg) ("{0:X2}/{1:X2}" -f $addr, $reg) }
112
114
  }
@@ -1,6 +1,6 @@
1
1
  <#
2
2
  .SYNOPSIS
3
- Dual-Tier MCP setup and registration helper (v0.1.1).
3
+ Dual-Tier MCP setup and registration helper (v0.1.3).
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.1.1)" -ForegroundColor Green
245
+ Write-Host " FirmwareLoop Dual-Tier MCP & Agent Setup Helper (v0.1.3)" -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