# 发给同事 (/docs/plugins/share)

## 开发时挂到 Dex Buddy [#开发时挂到-dex-buddy]

打开已经装好的 Dex Buddy，进入插件页，点加号，选「加载本地目录」。选中的文件夹可以是插件根（里面直接有 `plugin.manifest.json`），也可以是一个父目录，里面每个子目录是一个插件。父目录只登记一次。取消选择不会改列表。

不要把源码复制进 Dex Buddy 的安装目录。改一处、另一处还是旧的。正确路径只有插件页「加载本地目录」。

日常改模型调用：按 [模型](/docs/plugins/models) 拷 `dex-buddy-sdk.js` / `dex_buddy_sdk.py`，对照 `SDK_VERSION`，本机填 `DEX_BUDDY_API_KEY`，`index.js` 里 `requireEntitlement(ctx)` 再 `bindModels(ctx)`，Python 子进程用 `childEnv`。装进 Dex Buddy 验收时走上面这条路，业务代码不用改。不要把 Key 打进 zip。

这条路径记在用户数据目录的 `unpacked-plugins.json`，重启后还在。本地实例的 id 是 `dev-` 加上该目录真实路径的哈希，不是清单 `id`。设置页、`plugin-data` 和页面调用的服务都用实例 id。清单 id 相同的已安装插件可以同时开着，保存或移除本地实例不会改到它的密钥和 `plugin-data`。

详情「…」里可以重新加载，或按发布预览（与插件中心同一套文件和依赖，仍用这份实例的设置）。重新加载会从登记的源码目录重读清单并重新挂上后端。工作区标题栏的重新加载对本地实例同样重挂后端，对已安装插件只刷新页面。移除只取消登记并删掉这个实例 id 下的宿主数据，源码还在磁盘上。

改完 `index.js`、它 require 的子文件或页面后，在插件详情或标题栏重新加载，不必退出。

## 打成 zip 给别人安装 [#打成-zip-给别人安装]

同事拖进工作台的 zip 由作者自己打。压缩包要满足其中一种：

- 解压后根上就是 `plugin.manifest.json`
- 解压后只有一层目录，这个目录里有 `plugin.manifest.json`

不要打进密钥、虚拟环境和依赖目录。包里不要出现绝对路径或 `..`。拖进工作台的 zip 和插件中心的差别见 [打包](/docs/plugins/pack) 里的「两种安装包」。安装之后不要把缓存、导出和数据库写回安装目录，见 [数据](/docs/plugins/data)。

对方打开 Dex Buddy，把 zip 拖进欢迎页，或从图标轨的拼图进入插件页，加号里选「添加压缩包」。列表会马上出现，不用重启。同一个已安装插件再次安装会覆盖。插件页加载的本地目录使用另一把实例 id，不挡住这次安装。

## 发到插件中心 [#发到插件中心]

同事不收下载地址。作者改版本、推 tag。需要 Python 或 Node 依赖时在清单里声明 `runtime`。步骤见 [发到插件中心](/docs/plugins/publish)。

## 这样会加载失败 [#这样会加载失败]

- `id` 含大写、中文、下划线，或超过 64 个字符。
- `type` 写成 `ui`，但没有 `uiEntry`。
- `main`、`uiEntry` 或 `settingsEntry` 写成绝对路径，或路径里有 `..`。
- zip 里没有 `plugin.manifest.json`，或有多份、Dex Buddy 无法确定用哪一份。
- 服务方法返回了函数、类实例，或页面调用了一个不存在的方法。
- 服务名已经被另一个非本地插件注册过。本地实例和已安装插件可以注册同一个服务名，页面只会调到自己这份。
