跳转到内容

排障速查

按你看到的症状查。每条给最可能原因 → 验证方法 → 修法。

插件根本没出现(图标/菜单/类型都没有)

Section titled “插件根本没出现(图标/菜单/类型都没有)”
  1. manifest 不合法(最常见)。宿主对坏 manifest 的策略是跳过并打日志,不报错弹窗:
    Terminal window
    # 打包应用日志在 ~/.XH-Editor/logs/;源码 dev 直接看终端输出
    tail -F ~/.XH-Editor/logs/*.log | grep -i "skip.*plugin.json"
    校验规则:id/name/version 必填;runtime 只认 node/static;node 必须有 entry;static 必须有 ui;capabilities 必须是数组。JSON 语法错误(尾逗号!)同样中招。
  2. 目录位置不对——插件目录(含 plugin.json 的那层)要直接位于 ~/xinghan/plugins/ 下,别多套一层。
  3. 同 id 被抢——源码根优先于安装目录,同 id”先见者胜”。日志里会有一行”重复…跳过”。
  4. 改完 manifest 没重启/reload —— manifest 只在加载时读。
  1. entry 路径错:entry 相对插件根,检查文件真实存在(ui/index.html vs ui/dist/index.html 是高频笔误);
  2. 构建产物用了绝对路径资源:iframe 服务在 /plugins/<id>/ui/ 下,vite 构建记得 base: './'(相对引用),否则 JS/CSS 404;
  3. 页面自己抛错了 —— 开发者工具 Console 选中你的 iframe 上下文看报错;
  4. devUiUrl 指着一个没起的 dev server —— 反代 502。删掉该字段或把 vite 起起来。

context 一直不到(getContext() 全 null)

Section titled “context 一直不到(getContext() 全 null)”
  1. 忘了 installContextBridge() —— 必须在监听之前装(幂等,入口顶部调一次);
  2. 只在启动时读了一次 —— context 是 iframe load 后宿主 rAF 异步推送的,首次读很可能是空。正确姿势:onContextChange(init) + 立即调一次 init(),在 init 里判字段就绪(参照 json-field 的 waitForContext 封装);
  3. 后台窗口打开的页面 rAF 可能延迟 —— 同样由 ②的写法覆盖。
  • 访问卫星项目 403 → 需要 satellite:<kind> 声明(如 Agent 会话库要 satellite:agent)—— 这是当前唯一按 manifest 声明强制拦截的面;
  • 表视图里写数据被拒 → tableViews 声明里没开对应 writes 档,或写的不是本视图挂载的表(宿主锁表,传别的 tableNodeId 一律拒);
  • skill 工具里写数据 → v1 跨进程工具只放行 readonly,这是能力层强制,改声明也没用。
  • 值形状错:单选写了选项文字而不是选项 id;日期写了 ISO 串而不是毫秒时间戳。先 getFields 看目标字段 type 与 properties;
  • 超尺寸护栏:单值默认 256KB 上限(cell/表视图写入)。大内容走资产库存引用;
  • 自动化节点返回值超 256KB → 用 ctx.uploadResultAsset 传引用。
  1. 插件视图打开了但没收到消息 —— 检查 message 监听的 msg.type === 'command' 与 commandId 拼写是否和 manifest 的 id 一致;
  2. 声明的 points 和实际右键的位置不匹配(table.rows ≠ table.cells);
  3. modal 形态:context 走上下文桥(getContext() 里有 modalId 与选区),不是 command 消息 —— 两种打开方式的接收通道不同。
  • 颜色不变:忘装 installThemeBridge(),或 CSS 写死了 hex;
  • 首帧闪白/闪黑:语义变量没给 fallback(var(--background, #fff));
  • 语言不对:用了 navigator.language(那是操作系统语言)—— 改读 getContext().locale,并在 onContextChange 里响应切换。
  • 面板里没有你的节点:manifest 校验失败(回到第一节查日志),或 configSchema 里 dependsOn 指向了不存在的字段 key;
  • 执行分类为 plugin_error:execute 抛错了,错误文案在跑历史里 —— 写人话,用户和你都靠它排障;
  • dryRun 没进来:没声明 execution.supportsDryRun(缺省宿主直接跳过你)。
  • curl http://127.0.0.1:<port>/_internal/reload?id=<你的id>(POST)看对账结果里你的插件在 added/reloaded 还是没出现;
  • node 插件加 /healthz 端点自检进程活没活;
  • 对照完整示例做二分:把示例原样放进去能跑,说明环境没问题,问题在你的插件里。