---
title: 插件参考
description: 本地插件文件、客户端和服务端运行时、平台限制、贡献、RPC、生命周期、宿主环境和 CLI 命令。
nav: 参考
---
# 插件参考 {#plugin-reference}
从[插件快速上手](/docs/plugins)开始创建你的第一个插件。
要迁移已有的插件?请按照独立的[运行时入口迁移指南](/docs/plugins/migration)操作。
本地插件是安装到某个 Paseo daemon 中的目录来源。插件可以贡献:
- 为 Paseo 客户端添加 React Native 界面,以及侧边栏顶部和底部项;
- 作为工作区标签页打开的工作区面板和 Agent 面板;
- 用于查看或编辑匹配文件的[文件面板](#file-panels);
- Command Center 中的全局、工作区和 Agent 操作;
- 消息 Composer 中的斜杠命令;
- 经过转换的、以及由 daemon 推送的 Agent 时间线行;
- **设置 → 外观** 中的浅色和深色主题;
- 在 daemon 旁运行、经过 schema 校验的 RPC 处理函数;
- 通过 TypeScript SDK 执行的普通 Paseo 操作;
- 消息 Composer 中可搜索的外部资源。
插件代码是受信任的,没有沙盒。客户端界面在 Paseo 应用中运行。后端贡献在一个子进程中运行,可以访问 daemon 所在的机器,包括它的文件、进程、凭据和网络。
## 已连接的主机 {#connected-hosts}
客户端界面中的 `usePaseo().hosts` 与服务端处理函数或生命周期钩子中的 `context.paseo.hosts`
使用相同的 [SDK 主机 API](/sdk/reference#clienthosts)。它们描述所选 daemon 保存的连接。
现有的 `useHosts()` 和 `getPaseoClient(serverId)` 仍描述应用已知的主机。
```ts
const remote = await context.paseo.hosts.client("srv_build_box");
try {
return await remote.workspaces.list();
} finally {
await remote.dispose();
}
```
返回的 API 拥有自己的观察。销毁插件 API 时也会释放由它派生的作用域。
远程调用应留在拥有它的处理函数或生命周期作用域内。调用 B 不会把 B 的插件生命周期钩子转发到 A。
通过路由插件创建的注册项保留其来源身份,其中包含经过认证的链路和发起调用的插件。
## 项目文件 {#project-files}
`paseo plugin init /absolute/path/to/my-plugin` 会创建:
```text
my-plugin/
paseo-plugin.json
index.client.tsx
index.server.ts
client/greeting.tsx
server/greeting.ts
shared/greeting.ts
package.json
tsconfig.json
```
必需的根 manifest 是 `paseo-plugin.json`:
```json
{
"id": "my-plugin",
"description": "Reviews changes before merge",
"requirements": { "paseo": ">=0.8.0" }
}
```
| 字段 | 是否必填 | 行为 |
| -------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `id` | 是 | 默认的安装 ID。 |
| `name` | 否 | 注册表和网站使用的非空显示名称;与安装 ID 无关。 |
| `icon` | 否 | 插件包内 PNG 文件的相对路径。 |
| `media` | 否 | 包内图片或视频路径的数组,或 HTTPS URL。空数组是有效的。 |
| `description` | 否 | 在 **设置 → 插件** 中显示在插件 ID 下方的非空摘要。 |
| `translations` | 否 | 其他语言的展示文本,由注册表读取,Paseo 会忽略它。见[其他语言](/docs/plugins/publishing#other-languages)。 |
| `requirements` | 否 | 支持的 Paseo 版本,见下文。 |
| `build` | 否 | 准备命令,见 CLI 参考。 |
路径相对于 `paseo-plugin.json`,使用正斜杠,并且不能包含 `..` 片段。即使 `media` 在运行时 manifest 中是可选的,可视化插件的注册表展示页仍然需要一张界面图片。接受的格式和展示页要求见[图标和截图](/docs/plugins/publishing#icons-and-screenshots)。Paseo 会校验这些引用,但不会打开本地资源或获取 URL。
未知的顶层字段会被忽略。已知字段仍然会被校验,`requirements` 中的未知键会被拒绝,以免拼写错误的约束悄悄跳过兼容性检查。使用 `name`、`icon` 或 `media` 的 manifest 需要 Paseo 0.11.0 或更高版本;较旧的 daemon 会在安装时拒绝这些字段。
### 版本要求 {#requirements}
`requirements` 是一个可选对象。它目前支持的键 `paseo` 接受一个 npm semver 范围。省略 `requirements.paseo` 表示 `<0.8.0`:即该插件早于第一个破坏性的插件版本。Paseo 0.8 及更高版本会拒绝它,并附上[迁移指南](migration)的链接。空字符串、无效的范围以及未知的 manifest 要求键都会被拒绝。
| 范围 | 兼容的版本 |
| ---------------- | ---------------------------------------------------- |
| `>=0.8.0` | 0.8.0 及之后的版本,包括预发布版本和将来的破坏性版本 |
| `^0.8.0` | 0.8.x 版本,包括预发布版本 |
| `>=0.8.3 <0.9.0` | 0.8.3 到最后一个 0.8 补丁版本,包括预发布版本 |
预发布的 Paseo 版本也满足其稳定核心版本(`major.minor.patch`)所满足的范围,因此 `0.8.0-beta.1` 满足 `>=0.8.0`,但不满足 `<0.8.0`。
`>=0.12.0-beta.4` 这样的预发布最低版本也会通过稳定核心 `0.12.0` 接受 `0.12.0-beta.3`。若要排除同一核心的较早构建,请使用不同的稳定核心版本。
`paseo plugin init` 会写入 `>=` 加当前 CLI 版本,并为类型检查固定匹配的 SDK。采用更新的 API 时,请提高最低版本。当某个之后的版本不兼容时,请添加上限;只有下限并不能保证免受将来破坏性变更的影响。
daemon 会在安装、运行准备命令或加载插件之前检查自己的版本,并在启动、启用和重新加载时再次检查。被拒绝的更新会保留已安装的修订。每个已连接的应用在执行客户端代码之前会检查自己的版本,并在 **设置 → 插件** 中显示不兼容。兼容的 daemon 并不能让较旧的应用变得兼容。没有客户端入口的插件不要求已连接的应用匹配。
例如:`Plugin "review" requires Paseo >=0.8.0. Your daemon is 0.7.2.` 请使用兼容的插件修订,或更新提示中的运行时。0.8 之前的版本不理解这个 manifest 字段,也无法显示这条新的诊断信息。
### 运行时入口 {#runtime-entries}
| 入口 | 运行时 | 接收 | 何时需要 |
| ------------------ | ---------------------- | --------------------- | ------------------------------------------------ |
| `index.client.tsx` | Paseo 应用,每个客户端 | `PluginClientContext` | 插件有任何 UI、回调、主题或附件来源时 |
| `index.server.ts` | daemon 子进程 | `PluginServerContext` | 插件贡献处理函数、钩子、设置持久化或 Provider 时 |
至少需要一个入口;两者都接受 `.ts` 或 `.tsx`。仍然只有旧 `index.ts` 的目录会加载失败,并指向[迁移指南](/docs/plugins/migration)。
插件、界面、侧边栏项、工作区面板、Command Center 项、附件来源和斜杠命令的 ID 以小写字母开头,只包含小写字母、数字或连字符。
生成的 `package.json` 把 `@getpaseo/plugin` 和其他宿主模块安装为开发依赖,用于本地类型检查和测试。它们的运行时实例由 Paseo 提供。使用者在添加插件时不会安装它们。
其他每个模块都位于以下三个目录之一。在其中嵌套没有问题;位于插件根目录的模块会导致编译错误。
| 目录 | 编译进 | 用于 |
| --------- | -------------- | --------------------------------------------------- |
| `client/` | 仅应用的包 | React、React Native、hook、样式、界面、面板和回调。 |
| `server/` | 仅 daemon 的包 | Node API、本地资源、凭据和 RPC 处理函数。 |
| `shared/` | 两者 | Zod RPC 契约以及两个运行时都会导入的普通值。 |
## 运行时翻译 {#runtime-translations}
**尚未发布的 API。** 发布插件前,请将 `requirements.paseo` 设置为首次包含这些 API 的版本。[翻译示例](https://github.com/getpaseo/paseo/tree/main/plugin-examples/translations) 暂用 `>=0.12.1`,实际引入版本尚未确定。
将 JSON 资源随客户端代码一起打包。必须提供英语(`en`);其他语言使用规范语言标签,例如 `zh-CN`。资源由嵌套对象和字符串叶节点组成。其他语言可省略键,缺失时回退到英语。定义翻译时会拒绝未知键、无效资源、非规范语言标签,以及与英语不一致的插值占位符。
```ts
// client/messages.ts
import { defineTranslations } from "@getpaseo/plugin/client";
import en from "./locales/en.json";
import zhCN from "./locales/zh-CN.json";
export const messages = defineTranslations({ resources: { en, "zh-CN": zhCN } });
```
在插件的 `tsconfig.json` 中启用 `resolveJsonModule`。Paseo 在本地打包这些导入,不通过网络加载。资源对示例:
`client/locales/en.json`:
```json
{
"title": "Workspace notes",
"add": "Add note",
"notes_one": "{{count}} note",
"notes_other": "{{count}} notes"
}
```
`client/locales/zh-CN.json`:
```json
{
"title": "工作区笔记",
"add": "添加笔记",
"notes_other": "{{count}} 条笔记"
}
```
在 React UI 中使用插件的 hook:
```tsx
import { useTranslation } from "@getpaseo/plugin/client";
import { Text } from "react-native";
import { messages } from "./messages";
function NoteCount({ count }: { count: number }) {
const { t, locale } = useTranslation(messages);
return {t("notes", { count })};
}
```
对于由宿主持续渲染的标签,使用 `messages.message(key, options?)`:
```tsx
client.addScreen({
id: "notes",
title: messages.message("title"),
Component: Notes,
});
```
`PluginText` 为 `string | PluginMessage`。消息引用支持界面标题(包括标题函数)、设置与侧边栏标题、工作区与文件面板标题、Command Center 标题、斜杠命令描述与参数提示、按钮标题与标签、嵌套菜单标题、附件来源标题/选择器标题/搜索占位文本,以及主题名称。现有的字符串仍然有效。保持 ID、斜杠命令名称、图标、URL 和命令搜索关键词不变。
描述符类型保留现有的字符串默认值。为翻译描述符显式标注类型时,传入文本类型参数,例如 `PluginScreenContribution`。内联注册会自动推导类型。
回调中的临时文本使用 `client.i18n.t(messages, "add")`,它读取调用时的应用语言。`client.i18n.locale` 和 hook 的 `locale` 返回解析后的应用语言,即使某条消息回退到英语。不要将 `t` 的返回值用作持续注册的标签。
键由英语资源推导。`notes` 等复数基础键要求数字类型的 `count`;i18next 根据语言选择 `_zero`、`_one`、`_two`、`_few`、`_many` 或 `_other` 形式。命名插值使用 `{{name}}`,调用时传入 `{ name: value }`。TypeScript 将导入 JSON 的字符串值拓宽为 `string`,因此 JSON 插值名称在运行时检查;内联字面量资源还能推导必需的插值名称。`{{amount, number}}` 等 i18next 格式化语法使用解析后语言的 `Intl` 格式化器。
显式选择的应用语言优先于设备语言;“跟随系统”使用应用支持的语言解析规则。连接到同一 daemon 的不同应用各自保留语言设置。切换语言会更新已挂载的 UI 和宿主标签,不重新加载插件、不重置组件状态,也不替换 RPC/查询缓存。网页和原生的模态框与弹出层均收到相同的安装上下文。
RPC 返回与语言无关的结构化数据,在客户端翻译呈现内容。保持用户草稿、agent 输出、原始 daemon 错误、日志与终端文本不变。manifest 列表翻译和 `OVERVIEW..md` 是独立的发布元数据,参见[你的列表页面](publishing#your-listing-page)。
## 运行时模块 {#runtime-modules}
Paseo 从对应的入口构建每个包。把 `client/` 导入 daemon 的包、把 `server/` 导入应用的包,或在应用的包中任何位置导入 Node 模块,都会导致编译错误。服务端导入 React、React Native 或客户端 SDK 入口也会失败。共享代码只能导入共享代码:不能导入 Node、React、特定运行时的 SDK 入口或特定运行时的类型。
SDK 根入口(`@getpaseo/plugin`)只包含共享数据、schema 和与运行时无关的辅助函数。从 `/client` 导入客户端 context 和 hook,从 `/server` 导入服务端 context 和生命周期契约,从 `/client/ui` 导入 UI。这些规则同样适用于类型导入和传递依赖。`/client/host` 是应用宿主的私有模块;插件不能导入它。
### 客户端运行时 {#client-runtime}
Paseo 为客户端代码提供以下模块:
| 模块 | 用于 |
| ---------------------------- | -------------------------------------------------------------------------------------------- |
| `@getpaseo/plugin` | 共享数据、`defineRpc`、`defineSettings`、`defineAttachmentSource`、`RpcInput` 和 `RpcOutput` |
| `@getpaseo/plugin/client/ui` | Paseo UI 组件和 UI hook |
| `@getpaseo/plugin/client` | 客户端贡献 context、`usePaseo`、`useRpc`、`useSettings` 和数据 hook |
| `@tanstack/react-query` | 请求状态和缓存 |
| `react` | 组件和 hook |
| `react/jsx-runtime` | 编译后的 JSX |
| `react-native` | 跨平台 UI |
| `zod` | 共享 schema |
宿主拥有与之配套的 React 和渲染器版本。SDK 的 React peer 范围允许补丁版本差异,以便工具链和 Node 使用者使用;它不会改变应用固定的 React 版本,也不保证与其他宿主的渲染器兼容。
这些确切的模块标识符使用宿主的运行时实例。请求其他宿主模块的客户端包会以 `Module "" is not available in plugin client code` 失败。
不要导入 `lucide-react-native`、`react-native-svg` 或 DOM 库。把贡献的 `icon` 字段设为一个 [Lucide 图标名称](https://lucide.dev/icons/)、内联 SVG 或组件;Paseo 会校验图标并渲染它。参见[图标](#icons)。
### 跨平台规则 {#cross-platform-rules}
客户端代码通过 React Native Web 在 iOS、Android 和浏览器中运行。在浏览器中正常、在手机上崩溃的组件是最常见的插件 bug。规则如下:
| 应该 | 不应该 |
| ------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| 使用 `react-native` 中的 `View`、`Text`、`Pressable`、`ScrollView`、`TextInput` | 使用 ``、`
`、`