toddpan/dsh-feyagate ↗★ 0

@dsh-external/dsh-feyagate-gateway

FeyaGate 网关 × DSH —— 在 DSH 里托管本机 miloco-mcp-server,并提供服务/授权/账号的可视化设置界面 适合需要一键部署、管理本地MCP服务并接入其工具链的开发者。

Package
@dsh-external/dsh-feyagate-gateway
Compatibility
Unverified
Cordis peer range
>=4.0.0-rc <5
Version
0.3.2
License
MIT
Last updated
Sep 27, 2026

Install

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:toddpan/dsh-feyagate

dsh-feyagate-gateway

这个文件解决什么问题:让三类读者各自在 3 分钟内找到自己要看的东西 —— 想装的人拿到最短安装路径,想贡献的人拿到开发环境与目录职责,关心合规的人拿到"仓库里到底有什么、没有什么"。

License: MIT npm 包名 @dsh-external/dsh-feyagate-gateway · 版本 0.3.1

0.3.1 变更:重新生成 manifest/server-manifest.json。上游 miloco-mcp-server v1.2.20 的 mac-arm64 产物 已于 2026-09-25 重新打包并覆盖发布(旧包缺 4 个依赖库导致启动即 dyld: Library not loaded,且 MQTT 未编入 导致华为设备能登录却无法控制)。清单里的 sha256 必须跟着更新,否则安装会以校验不通过结束 —— 请先升级插件到 0.3.1 再安装/升级后台服务。


一句话

FeyaGate(飞阳网关)的 DSH 插件:在 DSH 里托管本机的后台服务 miloco-mcp-server(自动下载 → 校验 → 安装 → 守护 → 升级 → 失败回滚),把它的 76 个 MCP 工具(数量出自 FeyaGate_MCP_API.md §4)接进 DSH,并在设置面板里提供「服务 / 账号 / 授权」三个管理界面。

插件本体开源(MIT);真正的智能家居逻辑在闭源二进制里,二进制不进这个仓库、不随 npm 包分发,运行时从权利人自己的渠道下载并按清单校验(见 NOTICE)。

用词约定(全文一致):平台账号相关一律说「登录」,只有许可证才说「授权」;本机这个进程一律叫「后台服务」,不叫「网关」;「飞阳网关」是产品名与设置入口名。


架构一眼看完

┌─────────────────────────────── DSH 宿主进程 ────────────────────────────────┐
│                                                                            │
│  ┌────────────────────────┐        ┌─────────────────────────────────────┐ │
│  │ 浏览器半侧 lib/client.js│  同源  │ Host 半侧(插件本体,进程内运行)    │ │
│  │ 设置 › 飞阳网关         │ ◄────► │ /dsh-feyagate/* 管理 API            │ │
│  │ [服务][账号][授权]      │  HTTP  │ 安装·校验·守护·升级·生成 config.yaml │ │
│  └────────────────────────┘        └──────┬──────────────────┬───────────┘ │
│                                           │ ① spawn / 健康轮询 │ ② 常驻    │
│  ┌───────────────────────────────┐        │    /health         │          │
│  │ @deepseek-ai/dsh-mcp-client   │  HTTP  │                    ▼          │
│  │ serverName: feyagate          │ ─────► │        ┌────────────────────┐ │
│  │ 工具名 mcp__feyagate__*       │        │        │ MCP 门面 :38081    │ │
│  └───────────────────────────────┘        │        │ 秒答 initialize    │ │
│         ▲ 模型在对话里调用                 │        │ 就绪后代理工具调用 │ │
│         │                                  │        └─────────┬──────────┘ │
└─────────┼──────────────────────────────────┼──────────────────┼────────────┘
          │                                  ▼                  │ ③ 代理
          │                   ┌──────────────────────────────┐  │
          │                   │ 后台服务 miloco-mcp-server   │◄─┘
          │                   │ 127.0.0.1:38080(可漂移)    │
          │                   │ POST /mcp/http · GET /health │
          │                   │ 落盘 ~/.dsh/dsh-feyagate/    │
          │                   └───────────┬──────────────────┘
          │                               │ HTTPS / P2P / MQTT
          │                               ▼
          │        小米云 · 涂鸦云 · 美的云 · 易微联 · 华为云 · Home Assistant
          │                               ▲
          │                               │ 局域网
          └─────────────── 米家摄像头 · 小爱音箱 · 小智终端

三条要点:

  1. 桥连的是插件自己的常驻门面,不是子进程。门面端口写进 state.json,由 cordis.patch.yml 里的 !!js 表达式在 boot 时读取;子进程没装也能秒回 initialize(只返回空工具表),因此"先启动 DSH 再装服务"不会烧掉 MCP 桥的重连预算,升级窗口对模型也是零感知。tools/list_changed 的送达是最终一致的:桥的 SSE 流建立时若子进程已健康,门面立即补发一次;通知发出时若暂无客户端流,则标记 pending 并有界重发(5s/次、上限 12 次)——两种时序下桥都不需要重启 DSH 即可拿到工具列表。
  2. 子进程真实端口是运行期细节。默认 38080,被占用时在 20 个端口范围内漂移;期望端口进 state.json 的 server.port,实际生效的端口在启动这一轮写进生成的 config.yaml,不写进任何静态配置。
  3. 安装根目录本身是不可移动的。config.yaml 就放在根目录,子进程把设备身份与许可证锚定在 config.yaml 所在目录 —— 根目录一换就等于换了一份身份(见下方「数据在哪里」与 ADR-0002)。

安装与最短路径

1. 装插件

dsh plugin --profile 
 add @dsh-external/dsh-feyagate-gateway

是你要装进去的 profile 名(例如 web)。这条命令把参数原样转发给 pnpm,并在 package.json 里看到 dsh.bundle.patch 后把本插件的 bundle 追加进 dsh.profile.bundles —— 不需要手改 profile 文件。装完重启(或让 HMR 重合成配置层)后,设置面板左侧会多出一行「飞阳网关」。

2. 装后台服务(唯一必须做的一件事)

打开 设置 › 飞阳网关 › 服务 › 概览,点 安装后台服务。安装向导会依次做五件事,每一步都有真实进度:

① 下载  ████████░░░░  56%  17.1 MB / 30.4 MB · 1.8 MB/s
② 校验  sha256 与同版本 .sha256 比对        ← 不通过就删除文件并中止
③ 解压  释放到 versions//
④ 写入  可执行权限(macOS 还会去 quarantine + ad-hoc 重签)
⑤ 启动  切 current 指针 → 拉起进程 → 轮询 /health

MVP 不会在你点之前偷偷下载任何东西。没装就是没装,界面只会给你一个按钮。

3. 确认工具接上了

安装完成后,在对话里问一句「列出我的智能家居设备」。模型应该能调用到形如 mcp__feyagate__* 的工具(例如 mcp__feyagate__device_list)。

公开工具名由 MCP 桥做函数名规范化(原始名里有 /,如 device/list),以运行时 tools/list 的结果为准;本仓库文档里写的名字是形状示意。

4. 登录平台账号

在设置界面里点着登录:设置 › 插件 › 飞阳网关 › 平台登录,米家 / 涂鸦 / 美的 / 易微联 / 华为五张卡片各自一个流程(涂鸦直接显示可扫的二维码,米家是「拿授权地址 → 粘回回调地址」两步)。哪张卡片能用由后台服务自己报的能力决定:本机 v1.2.19 没有华为工具,华为卡片就明确写「本构建不支持」而不是给一个必然失败的按钮;后台服务升到 v1.2.20 后这张卡片自己出现,插件不用跟着升级。

凭据(账号、密码、验证码)只在本机回环内交给后台服务进程:插件不落盘、不写日志、不回显,写操作全部校验 Origin,密码输入框提交后即清空。详见 ADR-0009。

对话里也能走(工具清单见 FeyaGate_MCP_API.md)——两者调的是同一批工具:小米走浏览器 OAuth、涂鸦走二维码、美的/易微联走账号密码、华为走两步验证码。

涂鸦(唯一一条完全在聊天里走完的授权链) —— 你只需要做两件事:

  1. 先在涂鸦 App 里查一次自己的用户代码:我的 → 设置 → 账号与安全 → 用户代码,把它发给模型(形如 AY1790336520…)。
  2. 模型回复里会出现一张二维码图片(不是 token 文本)。用涂鸦 App 右上角「+ / 扫一扫」扫它,再在 App 里点「确认登录」。

之后不用你再说话:插件在服务端替模型轮询(单次最多等 35 秒),扫到即返回,模型会告诉你已登录,并可以接着 device_list 看设备。

为什么必须由插件出图:上游 auth/tuya_qr 只回一个 token(tuyaSmart--qrLogin/?token=…)——那是给摄像头扫的载荷,聊天里没有可扫的东西,用户会被卡在「请扫描下方二维码」却没有二维码。插件把 token 渲染成 PNG(/dsh-feyagate/auth/tuya/qr.png?token=…)并写进工具结果与工具描述,见 docs/verify-tuya-auth-flow.md。

图片没显示时(客户端不渲染图片):工具结果里同时给了 qr_text_url(方块字符版二维码,任何客户端都能显示);也可以直接把该地址粘进浏览器。

最短路径到"控制一盏灯":装插件 → 装后台服务 → 对话里让模型登录米家 → 让模型 device/list 找到灯 → 开灯。


功能清单

MVP(0.1.x 目标)

能力说明
后台服务托管按 manifest/server-manifest.json 解析平台资产 → 多源降级下载 → 先校验后解压 → 落到 versions// → 切 current 指针
进程守护spawn / PID 文件 / 孤儿与多实例清理 / /health 轮询(40 × 500ms)/ 崩溃退避重启(1s→30s)/ 熔断(60 秒内 5 次崩溃停止自动重启)
端口管理默认 38080,占用时在 20 个端口内漂移;期望端口留在 state.json 的 server.port,本次实际端口记进 server.effectivePort 并写进生成的 config.yaml
config.yaml 生成插件是唯一写者,字段归属见 ADR-0003;子进程会回写的字段读回合并,不覆盖
MCP 接入官方 @deepseek-ai/dsh-mcp-client 桥指向插件常驻门面(127.0.0.1:38081),工具以 mcp__feyagate__* 出现;tools/list_changed 最终送达(流建立补发 + pending 有界重发),装服务/改端口后桥无需重启 DSH
76 个 MCP 工具(数量出自 FeyaGate_MCP_API.md §4 的自述)设备/摄像头/场景/定时/触发规则/记忆/技能/小智/授权查询,全部经门面代理到子进程
设置界面 · 服务概览 / 安装与重装 / 升级与版本 / 端口与网络 / 日志与诊断 / 危险区
设置界面 · 授权许可证与试用期:版本、状态、到期、宽限、授权码写入、设备 ID、各平台试用剩余
设置界面 · 账号总览只读:平台清单、登录状态、设备数、试用剩余(清单以服务端下发为准,本地不写死)
设置界面 · 平台登录五个平台的图形化登录/退出:米家两步 OAuth(自动从回调地址里抠 code)、涂鸦二维码(服务端完成最长 35 秒的扫码等待)、美的/易微联账号口令、华为两步验证码(按 retry_without_code 分流,不白费一个验证码);能力协商驱动,缺哪个平台就说清缺什么;授权过期时给出"去授权标签"而不是"密码错了"
升级与回滚检查更新 → 升级到 versions// → 健康确认失败自动回滚 lastKnownGood;断电安全靠 pending 标记
随插件分发的 Skill 文档skills/feyagate-gateway/SKILL.md,教模型怎么正确调用这 76 个工具
插件自身升级只做"检测到新版本 + 提示 + 给可复制的升级命令"(见下)

二期(明确不是"已支持")

  • 常驻门面的工具集热更新(子进程就绪后发 notifications/tools/list_changed)之外的多端点管理:局域网 ESP32 网关、远端 miloco,条目分「本机托管」与「远端只连」。
  • Home Assistant(上游 miloco-mcp-server 与桌面端都没有 HA provider,只有 ESP32 固件有;要做只能直连 ESP32 的 /api/v1/platform/ha/* 或 HA 自己的 WebSocket)。
  • 设备页与摄像头页(连接 / 断开 / 抓拍 / 采集参数)、智能页(小智 AI / Vision AI / 触发规则 / 记忆 / 技能)。
  • 插件内一键升级(spawn dsh plugin update + 宿主重启)。
  • 诊断包导出、镜像源配置界面。

明确不做

  • 不做自研 DRM:许可证事实源在子进程,插件只呈现与转发。
  • 不读写已有的 ~/.feyagate 安装(只做只读探测,用于提示"检测到既有安装",见 ADR-0002)。
  • 不在运行期动态增减工具集(会打断 KV cache 前缀;平台开关要求重连)。
  • 不下载、不镜像、不分发小米专有库 libmiot_camera_lite。

设置界面

界面注册在唯一一个 settings.section(id feyagate,label「飞阳网关」,order 30)下;插件级参数挂在 settings.plugin.item,可复用 DSH 通用的「已覆盖 / 恢复默认 / 未保存 / 保存失败」表单语义。参数表(src/settings.ts 的 PluginSettings):

参数默认说明
serverPort38080子进程的期望端口
facadePort38081门面端口(改它需要重启 DSH)
bindAddress127.0.0.1可选 0.0.0.0(开局域网,必须看警告)
cloudServercn小米云区域
autoStarttrueDSH 启动时自动拉起子进程
mirrorBasenull自建镜像前缀(降级链的第三环)
localArchivenull本地安装包路径(降级链的最后一环)
allowUnverifiedfalse允许安装"完全没有校验值"的资产(界面里是显式确认)

安装根目录不在参数里:它固定是 ~/.dsh/dsh-feyagate(或 $DSH_HOME/dsh-feyagate)。这不是漏了,是因为换目录等于换设备身份。

地图不是按钮:DSH 的 settings.section 只拿到 close(),拿不到跨页跳转能力,所以界面里的跨页指引一律写成可复制的文字路径(设置 › 插件 › 插件配置 › 飞阳网关)。

TabMVP 做到哪解决什么问题
服务概览 / 安装与重装 / 升级与版本 / 端口与网络 / 日志与诊断 / 危险区「后台服务在不在、什么版本、坏在哪、怎么修」
账号总览只读总览(平台清单 + 登录状态 + 设备数 + 试用剩余)「一屏看清哪个平台是红的」
平台登录五个平台的登录/退出(能力协商驱动,缺什么说什么)「直接在界面里把账号登进去」,不必先学会跟模型描述工具调用
设备❌ 二期「设备都被看见了吗、摄像头能看吗」
智能❌ 二期小智 AI / Vision AI / 触发规则 / 记忆 / 技能
授权许可证与试用期(授权码写入、各平台状态、设备 ID)「免费能用什么、授权解锁什么、还剩几天」

每个 tab 顶部有一条常驻服务状态条(10 秒轮询、页面不可见时暂停),把运维面的结论带到每一页:

● 运行中 · v1.2.20 · 端口 38080 · 3/7 平台已登录 · 试用剩 12 天   [检查更新]
○ 未安装 · 尚未下载后台服务                                       [安装]
▲ 降级运行 · 华为设备控制不可用(命令通道未建立)                  查看原因

截图占位(docs/images/ 目录本仓库暂不创建,避免提交二进制;下面按顺序补图):

界面设计规格(逐屏字段、状态词表、错误文案三层结构、可用性走查、验收清单)在 UX 设计文档;本文只描述已确认的 MVP 范围,两者不一致处见下方「已知不一致」。


为什么需要 manifest/server-manifest.json

因为上游资产命名逐版本漂移,运行时拼文件名必然失败。这不是假设,是同一仓库同一年的实测事实:

版本平台真实资产名备注
v1.2.20mac-arm64miloco-mcp-server-mac-arm64-v1.2.20.zip「规范」形态
v1.2.20mac-x64miloco-mcp-server-mac-x64-v1.2.20.tar.gz完全没有 zip
v1.2.20win-x64——这个版本没有任何 Windows 资产,所以 Windows 默认目标停在 1.2.19
v1.2.19win-x64miloco-mcp-server-1.2.19-windows-x64.zip版本号在前、写 windows 而不是 win
v1.2.19win-x64miloco-mcp-server.exe还有一个裸可执行文件,没有压缩包
v1.2.17linux-arm64miloco-mcp-server-linux-arm64-v1.2.17.tar.gzlinux-arm64 的最新版本停在 1.2.17

所以本仓库自带一份权威清单:逐平台记录真实文件名、体积、URL 与 sha256(没有 .sha256 sidecar 的资产记 null)。清单同时承载:

  • pluginCompat.minSupportedServer / maxTestedServer:低于下限拒绝运行,高于上限提示"未测试"。
  • channel.stable:逐平台的默认目标版本(Windows 与 linux-arm64 因此不会去追一个根本不存在的版本)。
  • fotaType:FOTA 兜底源里各平台对应的 type id(mac-arm64 与 linux-arm64 没有 FOTA 条目,实测)。

维护者更新清单:

node scripts/gen-manifest.mjs                     # 抓取全部 release,重算 sha256
node scripts/gen-manifest.mjs --tag v1.2.20       # 只更新一个 tag
node scripts/gen-manifest.mjs --compute-missing   # 对没有 sidecar 的资产下载一次并本地算 sha256
                                                  # (默认只补每个平台的默认目标)

--compute-missing 的意义:sha256: null 的资产必须先由用户显式确认才能安装。它对"默认目标"把这条路走通,更早的钉版本仍然留在不可校验状态,因此不在 happy path 上。

package.json 里另有 npm run check:manifest(→ scripts/verify-manifest.mjs)用于校验清单自洽(资产 URL 与文件名一致、channel 指向存在的资产、pluginCompat 区间合法),适合接进 CI。


运维手册

数据在哪里

安装根目录默认 ~/.dsh/dsh-feyagate($DSH_HOME 存在时是 $DSH_HOME/dsh-feyagate):

~/.dsh/dsh-feyagate/
├── state.json                 插件唯一的可变账本:current / lastKnownGood / pending / 端口 / facade 端口 / 设置
├── config.yaml                ★ 生成物(插件是唯一写者),子进程按 `--config` 读它
├── data/                      ★ 子进程数据:token、license.json、device_id.txt、memory、skills、快照
├── logs/server.log            子进程 stdout/stderr + 插件日志,单行截断 4000 字符
├── versions//        每个版本一个不可变目录(下载→校验→解压的落点)
├── cache/                     下载的压缩包与解压暂存
└── current                    指针文件(不是软链接,为了 Windows),内容是一行版本号

config.yaml 为什么在根目录而不是 config/ 子目录里:这不是风格选择。子进程把所有相对路径按 config.yaml 所在目录展开(src/config.cpp 的 resolve_path 作用于 license_file、每个 *_token_file、memory.data_dir、skill.*_dir),并且 src/main.cpp 用它推导自己的数据目录(device_id.txt、token_usage.json)。所以"config.yaml 旁边那个目录"就是数据根。放进 config/ 会让 data/ 悄悄变成 config/data/,还会挪走 license.json —— 那正是设备 ID 与授权绑定的地方,用户升级一次插件就会被云端当成新设备、重新领一份免费试用。这就是 src/paths.ts 把文件放在根目录的原因。

唯一不可移动的东西就是安装根目录。移动或重建它 = 换一份 device_id = 授权与免费试用重新绑定。因此插件从不"迁移"这个目录,只往里写。备份时请整目录一起备。

改端口

  • HTTP 端口(子进程):设置 › 飞阳网关 › 服务 › 端口与网络 → 保存 → 会提示"端口改动需要重启后台服务才会生效",并自动重启。默认 38080,被占用时自动漂移并在界面上显示真实端口。
  • 门面端口:默认 38081,写进 state.json。改动它需要重启 DSH,因为 MCP 桥的 URL 来自 boot 时求值的 cordis.patch.yml。
  • 绑定地址:默认只绑 loopback。要开局域网必须显式开启,界面会同时给出"本地接口不校验身份"的警告。

日志

  • 界面:服务 › 日志与诊断,可切级别(对应子进程的 LOGV/LOGD/LOGI/LOGW/LOGE)、按行数与关键字过滤、复制全部。
  • 文件:~/.dsh/dsh-feyagate/logs/server.log(同一份环形缓冲区同时喂界面与文件,所以界面里能看到"崩溃行 + 守护进程的反应"的因果顺序)。

回滚

三种情形:

  1. 升级后没通过健康检查 → 自动回滚到 lastKnownGood,界面留一条常驻橙条,提供「重试升级 / 查看失败日志 / 保留旧版本并忽略此版本」。
  2. 升级中途断电/崩溃 → state.json 里的 pending 在下次启动仍未确认,自动回滚。这就是 versions/ 不可变 + current 指针 + pending 三件套存在的理由。
  3. 手动回滚 → 服务 › 升级与版本 › 版本历史,点「回滚到此版本」(本机已有该版本目录时才可用;没有则需要重新下载)。

卸载

先停服务(服务 › 危险区 › 停止服务),再删目录:

# 1) 停服务(界面:设置 › 飞阳网关 › 服务 › 危险区 › 停止服务)
# 2) 删后台服务与数据(不可恢复:平台凭据、设备、记忆、技能、快照、日志)
rm -rf ~/.dsh/dsh-feyagate

# 3) 卸载插件本体
dsh plugin --profile 
 remove @dsh-external/dsh-feyagate-gateway

只想留数据、只删二进制?删 ~/.dsh/dsh-feyagate/versions 与 current 即可(界面上的「卸载服务」做的就是这件事,凭据与配置保留)。

清理时不要动根目录以外的东西:不要删 config.yaml 与 data/(那是设备身份与授权),也不要动 ~/.dsh/profiles/ /(那是 DSH 自己的)。只想留数据、只删二进制?删 ~/.dsh/dsh-feyagate/versions 与 current 即可(界面上的「卸载服务」做的就是这件事,凭据与配置保留)。


故障排查

症状可能原因处理
启动时提示 feyagate-gateway … did not activate / failed to import装的是源码目录或 git 依赖,而 lib/ 是构建产物、不在仓库里;宿主 import 不到入口在该包目录跑 npm install && npm run build(prepare 脚本会在 npm install 时自动构建;dsh plugin add 用 link: 语义、不会触发它)。npm 安装的正式包自带 lib/,不受影响
工具列表里没有 mcp__feyagate__*① 插件没装进当前 profile;② MCP 桥行没生效;③ 桥连不上门面(门面端口被改但没有重启 DSH);④ 后台服务尚未装/尚未健康(门面如实回空表);⑤ 上游工具清单不合规:零参数工具的 inputSchema 是 {}(缺 type:"object"),严格客户端会整份拒收 tools/list ⇒ 一个工具都注册不上(服务却显示"已连接")① `dsh plugin --profile
why @dsh-external/dsh-feyagate-gateway;② 检查 profile 的 bundle 列表里有没有本插件;③ 设置 › 飞阳网关 › 服务 看状态条,重启 DSH 让 patch 重新求值;④ 装/启动后台服务后**无需重启 DSH**:服务健康后门面自动(必要时补发)tools/list_changed,桥随即 re-sync 出工具;⑤ **已修**:门面转发 tools/list时会把不合规的inputSchema补齐成{type:"object", properties:{}}(见 [docs/verify-mcp-inputschema-fix.md](https://github.com/toddpan/dsh-feyagate/blob/0f83b21707e0dfc78e39369fb313788ec06965c3/docs/verify-mcp-inputschema-fix.md)),升级插件后重启 DSH 即可。判断方法:插件的 logs里会有一行已修正 N 个工具的 inputSchema`
工具列表里有工具但调用失败后台服务没起 / 正在升级 / 门面还没代理到子进程看状态条:未安装 → 点安装;异常 → 看日志;升级中 → 等 10–20 秒
服务起不来:端口被占用HTTP 端口被别的进程占了(常见:另一份 miloco / 既有 ~/.feyagate 安装)界面报 FG-PORT-001 并给出占用 PID;点「换一个端口」(插件会在 20 个端口内漂移)或结束占用进程
服务起不来:macOS 未签名被拦Gatekeeper 拦下未公证的第三方二进制界面报 FG-PERM-001,给两条路:系统设置 › 隐私与安全性 ›「仍要打开」,或复制 xattr -dr com.apple.quarantine /versions//miloco-mcp-server。受 MDM 管理的机器绕不过去
服务起不来:依赖缺失上游产物漏带运行库。已实测:mac-arm64 v1.2.20 的二进制声明依赖 lib/libyaml-cpp.0.9.dylib、libavcodec.62.dylib、libavutil.60.dylib、libswscale.9.dylib,而归档里只有 libmiot_camera_lite.dylib —— dyld 立即中止,进程活不过 20 毫秒插件报 FG-PKG-004「安装包缺少运行库」,并在同一条错误里附上子进程自己打印的 dyld 原文(折叠在「技术细节」)。这是上游发布包的问题,换一个版本或等上游修;Linux 侧是否有同类缺失尚未实测,按日志里的 error while loading shared libraries 判断。华为控制另需 libmosquitto,缺失时是降级不是故障(brew install mosquitto 后重启服务)
服务起不来:健康检查超时20 秒内 /health 无 2xx(端口冲突 / 被安全策略拦 / 依赖缺失三类之一)报 FG-BOOT-001,界面给「查看日志 / 换端口重试 / 重新安装」三个出口;不要只看转圈,日志末行一定有原因。子进程若在就绪前就退出,插件立刻失败并把它最后 12 行输出一起报出来,不会再让你等满 20 秒;启动期退出也不会进入崩溃重启循环