查看 Markdown

插件快速上手

插件是安装到某个 Paseo daemon 中的 TypeScript 项目。它可以添加界面和侧边栏项、工作区面板、文件面板、Command Center 项、斜杠命令、Composer 标签、时间线条目、主题、附件来源和 daemon 端 RPC。它还可以把编程 Agent 接入为 Provider。客户端贡献会在连接到该 daemon 的每个 Paseo 客户端上运行,包括移动端。

浏览已发布的插件,然后在你的 daemon 上安装一个:

paseo plugin add owner/slug

或者把 owner/slug 粘贴到 设置 → 插件 → 插件来源,然后选择 安装插件。Paseo 会安装注册表中经过审查的制品。想直接从 Git 仓库安装时,请使用 git:owner/repository 或完整的 Git URL。

本指南会搭建一个插件、运行它,并为它添加一个工作区面板。

创建插件

使用 daemon 所在机器上的绝对路径:

paseo plugin init /absolute/path/to/workspace-plugin
cd /absolute/path/to/workspace-plugin
npm install

init 会写入一个严格模式的 TypeScript 项目,但不会运行包管理器。npm install 只添加用于类型检查和测试的开发依赖;插件 SDK、React、React Native、TanStack Query 和 Zod 由 Paseo 在运行时提供。

生成的脚手架就是一个可用的插件:一个从侧边栏打开的界面,其中有一个按钮,通过 RPC 向 daemon 请求一句问候。

workspace-plugin/
  paseo-plugin.json      # plugin ID and supported Paseo versions
  index.client.tsx       # runs in the Paseo app
  index.server.ts        # runs in a daemon subprocess
  client/greeting.tsx    # the screen component
  client/web.ts          # the only file allowed to touch browser APIs
  server/greeting.ts     # the RPC handler
  shared/greeting.ts     # the RPC contract, imported by both
  package.json
  tsconfig.json

每个入口默认导出一个函数,该函数注册贡献并返回一个清理函数。index.client.tsx 注册界面以及打开它的侧边栏项:

import type { PluginClientContext, PluginSidebarItemProps } from "@getpaseo/plugin/client";
import { SidebarRow } from "@getpaseo/plugin/client/ui";
import { GreetingScreen } from "./client/greeting";

function GreetingItem({ currentScreen, openScreen }: PluginSidebarItemProps) {
  return (
    <SidebarRow
      icon="MessageCircle"
      active={currentScreen?.screenId === "greeting"}
      onPress={() => openScreen({ screenId: "greeting" })}
    />
  );
}

export default function contribute(client: PluginClientContext) {
  client.addScreen({ id: "greeting", title: "Greeting", Component: GreetingScreen });
  client.addSidebarHeaderItem({ id: "greeting", title: "Greeting", Component: GreetingItem });
  return () => {};
}

index.server.ts 为 shared/greeting.ts 中的契约注册处理函数:

import type { PluginServerContext } from "@getpaseo/plugin/server";
import { createGreeting } from "./server/greeting";
import { greetingRpc } from "./shared/greeting";

export default function contribute(server: PluginServerContext) {
  server.handle(greetingRpc, createGreeting);
  return () => {};
}

目录就是边界。client/ 下的代码只编译进应用的包,server/ 下的代码只编译进 daemon 的包,shared/ 则编译进两者。跨越这条边界导入、在根目录添加代码文件,或在客户端代码中导入 node: 模块,都会导致编译错误。没有 daemon 端工作的插件可以省略 index.server.ts;没有 UI 的插件可以省略 index.client.tsx。

客户端代码既在浏览器中运行,也在手机上运行。项目在不包含 DOM 库的情况下进行类型检查,因此在 client/web.ts 之外使用 document 和 window 都会报错;client/web.ts 演示了如何用 Platform.OS 把浏览器 API 隔离开,并提供原生端的后备实现。编写 UI 之前,请先阅读跨平台规则。

安装并试用

插件是受信任的、没有沙盒的代码:服务端代码和准备命令以 daemon 用户在 daemon 所在机器上的权限运行,客户端代码在 Paseo 应用内部运行。安装插件意味着你信任该代码库、它的依赖以及它将来的更新。

在你要安装到的 daemon 上,打开 设置 → 插件 下的 启用插件。它是该 daemon 上所有插件的全局开关,也对应 daemon 的 config.json 中根级的 pluginsEnabled 字段;编辑该文件后,用 paseo reload --json 应用更改。自动化工具必须先读取当前值,并在获得你的明确许可后才能打开它。

然后进行类型检查并安装:

npm run typecheck
paseo plugin install /absolute/path/to/workspace-plugin
paseo plugin ls

或者从应用中安装该目录:

  1. 在目标主机上打开 设置 → 插件。
  2. 把 /absolute/path/to/workspace-plugin 粘贴到 插件来源。
  3. 选择 安装插件。应用会使用 paseo-plugin.json 中的插件 ID。

来源字段也接受 Git 仓库、npm 包和插件子目录。可接受的语法和解析规则见插件来源。如果表单要求你更新主机,请先更新该主机再安装;已有的管理操作仍然可用。

每个已安装插件的行都会显示它的状态和描述。用它的开关启用或停用它,打开它的三点菜单可以进行设置、查看日志、重新加载和移除。

paseo plugin ls 应该把该插件报告为 running。打开 Paseo,在侧边栏中选择 Greeting,然后按 Create greeting。消息会通过 RPC 从 daemon 子进程返回。

如果侧边栏项没有出现,请检查 启用插件 是否已打开、插件是否为 running,以及客户端正在查看的是否就是你安装到的主机。paseo plugin logs workspace-plugin 会显示 daemon 端的输出,包括加载错误。

添加工作区面板

工作区面板会作为标签页,与 Agent、终端和文件并排打开。创建 client/overview.tsx:

import { type PluginWorkspacePanelProps, useWorkspace } from "@getpaseo/plugin/client";
import { useMemo } from "react";
import { Text, View } from "react-native";

export function WorkspaceOverview({ theme, layout, workspaceId }: PluginWorkspacePanelProps) {
  const workspace = useWorkspace(workspaceId, ({ name, directory }) => ({
    name,
    directory,
  }));
  const styles = useMemo(
    () => ({
      screen: {
        flex: 1,
        padding: layout.compact ? 16 : 24,
        gap: layout.compact ? 8 : 12,
        backgroundColor: theme.colors.surface0,
      },
      title: { color: theme.colors.foreground, fontSize: layout.compact ? 20 : 24 },
      label: { color: theme.colors.foregroundMuted },
      detail: { color: theme.colors.foreground },
    }),
    [theme, layout.compact],
  );

  return (
    <View style={styles.screen}>
      <Text style={styles.title}>{workspace?.name}</Text>
      <Text style={styles.label}>Directory</Text>
      <Text style={styles.detail}>{workspace?.directory}</Text>
    </View>
  );
}

useWorkspace 从应用的缓存状态中读取面板要渲染的字段,不需要 RPC,并且在无关字段变化时不会重新渲染。每个 Text 都从 theme.colors 获取颜色,layout.compact 决定间距,因此面板在每个 Paseo 主题和手机上都能正常显示。令牌列表见主题与布局。

在 index.client.tsx 中加入以下内容,注册该面板以及一个打开它的 Command Center 项:

import { WorkspaceOverview } from "./client/overview";

// Inside contribute(client), after the existing registrations:
client.addWorkspacePanel({
  id: "overview",
  title: "Workspace overview",
  icon: "PanelsTopLeft",
  context: "workspace",
  locations: ["workspace", "explorer"],
  Component: WorkspaceOverview,
});
client.addCommandCenterItem({
  id: "open-overview",
  title: "Open workspace overview",
  icon: "PanelsTopLeft",
  context: "workspace",
  onSelect({ openPanel }) {
    openPanel("overview");
  },
});

icon 可以是 Lucide 图标名称、内联 SVG 或组件。参见图标。

编辑并重新加载

只有在重新加载插件后,源码改动才会生效:

npm run typecheck
paseo plugin reload workspace-plugin

重新加载会停止旧的插件、运行它的清理函数、编译当前源码,然后重新启动它。重新加载失败后插件会保持失败状态,并在 paseo plugin ls 中报告错误;修复源码后再次重新加载即可。

打开一个工作区,在 macOS 上按 ⌘K,在 Windows 和 Linux 上按 Ctrl+K,然后选择 Open workspace overview。面板会作为工作区标签页打开。

安装已发布的插件

在 daemon 主机上用 npm 安装一个受信任的 npm 插件:

paseo plugin install npm:@acme/paseo-review@1.2.0

或者把同样的标识符粘贴到 设置 → 插件 → 插件来源,然后选择 安装插件。安装后的行使用 manifest 中的 ID,并提供与目录插件相同的启用开关以及 Logs、Reload 和 Remove 操作。获取插件时需要 npm;之后的加载和重新加载都使用已安装的文件。

标识符语法见插件来源。要分享你自己的插件,请按照发布插件操作。

发布在 Git 仓库中的插件通过显式的 Git 简写或 URL 安装:

paseo plugin add git:owner/repository
paseo plugin add https://gitlab.com/group/repository.git
paseo plugin add git:owner/monorepo:plugins/workspace
paseo plugin add git:owner/repository --ref main

当插件位于仓库根目录之下时,追加 :relative/path。--ref 只在首次安装时选择 Git 内容;省略时安装默认的 HEAD。确切的语法见来源参考。

paseo plugin ls
paseo plugin update workspace-plugin
paseo plugin update --all

ls 报告来源标识和当前已安装的版本,不会联系远程。update 会展示一个拟更新的 npm 或 Git 版本,并请求你批准。npm 提供更新的 latest 发布版本;Git 提供当前默认的 HEAD,与首次安装时的选择器无关。使用 --check 只预览,使用 --yes 则无需提示直接批准。显式目标和批量更新见 CLI 参考。

读取后端日志

daemon 端的处理函数和清理函数可以使用普通的 Node 日志:

console.log("Refreshing issues");
console.error("Issue refresh failed", error);

在 设置 → 插件 下打开插件的三点菜单并选择 Logs,即可读取最近的输出;也可以使用 CLI:

paseo plugin logs workspace-plugin
paseo plugin logs workspace-plugin --json

日志尾部包含 [paseo] 的加载、就绪、停止中和已停止条目,以及编译和加载失败信息,并且在重新加载和崩溃后依然保留。客户端的输出留在应用中。保留策略以及哪些内容不应记录,见调试后端输出。

下一步

  • 发布插件:通过 npm、私有注册表或 Git 分享。
  • 构建 Provider 插件:直接或通过 ACP 接入 Agent,渲染由 Provider 拥有的时间线条目,测试并发布它。
  • 插件参考:每种贡献类型及其字段、运行时模块、宿主环境和 CLI。
  • 把插件迁移到运行时入口:逐步迁移基于单一 index.ts 入口编写的插件。
  • TypeScript SDK:在客户端和服务端代码中以 paseo 提供的工作区、Agent、Provider 和配置 API。

赞助商