--- 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` | 使用 `
`、``、`