chore: sync website translation parent

This commit is contained in:
Mohamed Boudra
2026-10-20 08:49:08 +02:00
358 changed files with 16024 additions and 7804 deletions
+2 -1
View File
@@ -222,7 +222,8 @@ client.addCommandCenterItem({
});
```
`icon` is a [Lucide](https://lucide.dev/icons/) icon name.
`icon` is a [Lucide](https://lucide.dev/icons/) icon name, inline SVG, or a component. See
[Icons](/docs/plugins/reference#icons).
## Edit and reload
+1 -1
View File
@@ -180,7 +180,7 @@ client.addCommandCenterItem({
});
```
`icon` 是一个 [Lucide](https://lucide.dev/icons/) 图标名称。
`icon` 可以是 [Lucide](https://lucide.dev/icons/) 图标名称、内联 SVG 或组件。参见[图标](/docs/plugins/reference#icons)。
## 编辑并重新加载 {#edit-and-reload}
+15 -8
View File
@@ -51,8 +51,8 @@ Also supply a one-sentence description: use `package.json`'s `description` for n
### Other languages
The website shows listings in English and Simplified Chinese. English is required; translations are
optional. Add translated listing text to `paseo-plugin.json`, keyed by language tag:
Listings show in English and Simplified Chinese. English is required and translations are optional.
Add a translated `name` and `description` to `paseo-plugin.json`, keyed by language tag:
```json
{
@@ -65,13 +65,20 @@ optional. Add translated listing text to `paseo-plugin.json`, keyed by language
}
```
Each field is optional. A missing translated `name` or `description` shows the English one.
Each field is optional, and a missing one shows the English text. The registry checks
`translations` when it publishes the plugin: keys are canonical language tags other than `en`, and
each value sets only `name` or `description`, as non-empty strings. Paseo itself does not read
`translations`, so a mistake there fails publication, not installation.
To translate the overview, put a whole copy beside `OVERVIEW.md` named for the language, such as
`OVERVIEW.zh-CN.md`, and include it in the published package. The scaffold's `files` list already
includes `OVERVIEW.*.md`. Readers in that language see the translated overview; without one, they
see the English overview with a notice. Keep the translation in step with `OVERVIEW.md`; the overview rules
above apply to it too.
To translate the overview, publish a complete copy named for the language next to `OVERVIEW.md`,
such as `OVERVIEW.zh-CN.md`. The scaffold's `files` list already includes `OVERVIEW.*.md`. The
registry reads `OVERVIEW.<tag>.md` as a translation when the tag is a canonical language tag with a
two- or three-letter language code, other than `en`. It ignores other names, such as
`OVERVIEW.backup.md` or `OVERVIEW.zh-cn.md`. A three-letter name such as `OVERVIEW.old.md` counts as
a language, so do not use one for a non-translation. Readers in that language see the
translation; others see the English overview with a notice. The overview rules above apply to
translations, so update them when `OVERVIEW.md` changes. Reviewers can add or correct translations
in the registry.
## Icons and screenshots
+3 -3
View File
@@ -35,7 +35,7 @@ nav: 发布
### 其他语言 {#other-languages}
网站以英文和简体中文显示展示页。英文是必需的;翻译是可选的。在 `paseo-plugin.json` 中添加翻译后的展示文本,以语言标签为键:
展示页以英文和简体中文显示。英文是必需的,翻译是可选的。在 `paseo-plugin.json` 中添加翻译后的 `name` 和 `description`,以语言标签为键:
```json
{
@@ -48,9 +48,9 @@ nav: 发布
}
```
每个字段都是可选的。缺少翻译后的 `name` 或 `description` 时,会显示英文的值。
每个字段都是可选的,缺少的字段会显示英文。注册表在发布插件时检查 `translations`:键必须是除 `en` 之外的标准语言标签,每个值只能设置 `name` 或 `description`,且必须是非空字符串。Paseo 本身不读取 `translations`,因此这里的错误会导致发布失败,而不会影响安装。
要翻译概览,请在 `OVERVIEW.md` 旁边放一份以语言命名的完整副本,例如 `OVERVIEW.zh-CN.md`,并把它包含在发布的包中。脚手架的 `files` 列表已经包含 `OVERVIEW.*.md`。使用该语言的读者会看到翻译后的概览;没有翻译时,他们会看到英文概览和一条提示。请让翻译与 `OVERVIEW.md` 保持同步;上面的概览规则同样适用于它。
要翻译概览,请在 `OVERVIEW.md` 旁边发布一份以语言命名的完整副本,例如 `OVERVIEW.zh-CN.md`。脚手架的 `files` 列表已经包含 `OVERVIEW.*.md`。当标签是语言代码为两个或三个字母、且不是 `en` 的标准语言标签时,注册表会把 `OVERVIEW.<标签>.md` 当作翻译,并忽略 `OVERVIEW.backup.md`、`OVERVIEW.zh-cn.md` 这类其他名称。`OVERVIEW.old.md` 这样的三字母名称会被当作一种语言,因此不要用它命名非翻译文件。使用该语言的读者会看到翻译;其他读者会看到英文概览和一条提示。上面的概览规则同样适用于翻译,因此 `OVERVIEW.md` 变更时请同步更新翻译。审查者可以在注册表中补充或修正翻译。
## 图标和截图 {#icons-and-screenshots}
+106 -44
View File
@@ -52,16 +52,16 @@ The required root manifest is `paseo-plugin.json`:
}
```
| Field | Required | Behavior |
| -------------- | -------- | ----------------------------------------------------------------------------------------- |
| `id` | Yes | Default installation ID. |
| `name` | No | Non-empty display name for the registry and website; independent of the installation ID. |
| `icon` | No | Relative path to a PNG inside the plugin package. |
| `media` | No | Array of image or video paths inside the package, or HTTPS URLs. An empty array is valid. |
| `description` | No | Non-empty summary shown below the plugin ID in **Settings → Plugins**. |
| `translations` | No | Listing `name` and `description` in other languages, keyed by language tag. |
| `requirements` | No | Supported Paseo versions, described below. |
| `build` | No | Preparation commands, described in the CLI reference. |
| Field | Required | Behavior |
| -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | Yes | Default installation ID. |
| `name` | No | Non-empty display name for the registry and website; independent of the installation ID. |
| `icon` | No | Relative path to a PNG inside the plugin package. |
| `media` | No | Array of image or video paths inside the package, or HTTPS URLs. An empty array is valid. |
| `description` | No | Non-empty summary shown below the plugin ID in **Settings → Plugins**. |
| `translations` | No | Listing text in other languages, read by the registry and ignored by Paseo. See [other languages](/docs/plugins/publishing#other-languages). |
| `requirements` | No | Supported Paseo versions, described below. |
| `build` | No | Preparation commands, described in the CLI reference. |
Paths are relative to `paseo-plugin.json`, use forward slashes, and cannot contain `..`
segments. Registry listings for visual plugins require an interface image even though `media` is
@@ -74,10 +74,6 @@ Unknown top-level fields are ignored. Known fields still validate, and unknown k
Manifests using `name`, `icon`, or `media` require Paseo 0.11.0 or later; older daemons reject
these fields during installation.
`translations` keys are canonical language tags other than `en`, such as `zh-CN`. Each value may
set `name`, `description`, or both, as non-empty strings; other keys are rejected. See
[other languages](/docs/plugins/publishing#other-languages) for how listings use them.
### Requirements
`requirements` is an optional object. Its currently supported key, `paseo`, accepts an npm semver
@@ -242,7 +238,7 @@ guarantee compatibility with another host's renderer.
These exact module specifiers use the host's runtime instances. A client bundle that requests another host module fails with `Module "<name>" is not available in plugin client code`.
Do not import `lucide-react-native`, `react-native-svg`, or DOM libraries. Set contribution `icon` fields to a [Lucide icon name](https://lucide.dev/icons/); Paseo validates the name and renders the icon.
Do not import `lucide-react-native`, `react-native-svg`, or DOM libraries. Set contribution `icon` fields to a [Lucide icon name](https://lucide.dev/icons/), inline SVG, or a component; Paseo validates the icon and renders it. See [Icons](#icons).
### Cross-platform rules
@@ -418,11 +414,9 @@ Use `runAcpProvider()` from `@getpaseo/plugin/server/acp` to adapt a command-bac
hooks only for a vendor's discovery, configuration, notification, or tool-call differences.
`ProviderRegistration.icon` is a file path relative to the plugin directory, such as `icon.svg`.
It must resolve inside that directory to a regular SVG file no larger than 64 KiB. The SVG must be
self-contained: scripts, styles, `foreignObject`, event-handler attributes, JavaScript URLs, and
external `href` or `xlink:href` references are rejected. Fragment references such as `#mark` are
allowed. Paseo reads and sanitizes the file when the plugin starts; the string is never an inline
SVG or URL.
It must resolve inside that directory to a regular file that follows the
[SVG icon rules](#svg-rules). Paseo reads and validates the file when the plugin starts; the string
is never inline SVG or a URL.
### Usage sources
@@ -596,7 +590,7 @@ bypasses that cache. Entries carry `id`, `account.label`, and `fetchedAt`. Faile
on `server_info.features.usageSources`. The older `provider.usage.list` RPC maps the same reports
for 0.10 clients and renders problems into its `error` string.
The source icon follows the provider SVG restrictions above.
The source icon is a file path with the same rules as a provider icon.
## Entry point and cleanup
@@ -1048,10 +1042,10 @@ closes the popover.
Render the item with the sidebar kit from `@getpaseo/plugin/client/ui`:
| Component | Props and behavior |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SidebarRow` | Required `onPress`; optional `icon` (Lucide name or `{ size, color }` component), `label`, `active`, `trailing`, `id`. A full-width row. `trailing` renders beside the row's pressable, so a button in it presses on its own; a press elsewhere in it presses the row. `id` tells rows of one item apart in test IDs. |
| `SidebarSeparator` | No props. The sidebar's separator line, between groups of rows. |
| Component | Props and behavior |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SidebarRow` | Required `onPress`; optional `icon` (any [icon](#icons) form), `label`, `active`, `trailing`, `id`. A full-width row. `trailing` renders beside the row's pressable, so a button in it presses on its own; a press elsewhere in it presses the row. `id` tells rows of one item apart in test IDs. |
| `SidebarSeparator` | No props. The sidebar's separator line, between groups of rows. |
A popover anchors to the row that was pressed, whether the press landed on the row or on its
`trailing` content, so a per-row "More" button opens its popover next to its own row.
@@ -1326,14 +1320,82 @@ Showing another toast replaces the currently visible toast. An empty message is
### Icons
`Icon` renders a [Lucide icon](https://lucide.dev/icons/) from Paseo's installed icon set. Plugin bundles do not import
`lucide-react-native` or `react-native-svg`.
Every contribution `icon` field takes one of three forms, typed `PluginIcon` in
`@getpaseo/plugin/client`:
| Prop | Type | Required | Behavior |
| ------- | -------- | -------- | ----------------------------------------------- |
| `name` | `string` | Yes | Lucide icon name. Unknown names render nothing. |
| `size` | `number` | No | Icon width and height. |
| `color` | `string` | No | Icon color. Use a plugin theme token. |
| Form | Example | Use it for |
| ----------- | --------------------------- | --------------------------------------------------- |
| Lucide name | `icon: "Scan"` | Any [Lucide icon](https://lucide.dev/icons/). |
| Inline SVG | `icon: { svg: reviewIcon }` | A brand mark or an icon Lucide does not have. |
| Component | `icon: ReviewBadge` | An icon that changes with state, such as a counter. |
Attachment sources take a Lucide name or inline SVG (`PluginSerializableIcon`), because each
attached item stores its source's icon.
Paseo validates the icon when the contribution registers. An unknown Lucide name or an SVG that
breaks a rule fails the plugin with the reason:
```text
Workspace panel review has an invalid icon: script elements are not allowed
```
Paseo draws inline SVG at the surface's icon size and passes the surface's icon color as
`currentColor`. Paint with `currentColor` to follow the theme; fixed fills keep their colors.
A component receives `PluginIconProps`, `{ size, color }`, and renders within that size. Header
buttons and composer pills pass [`PluginButtonIconProps`](#custom-icons-and-popover-content).
#### SVG rules
Inline SVG, provider icons, and usage-source icons follow the same rules:
- One `<svg>` document, no larger than 64 KiB.
- No `<script>`, `<style>`, or `<foreignObject>` elements.
- No event-handler attributes such as `onclick`, and no `javascript:` URLs.
- `href` and `xlink:href` point only at fragments in the same document, such as `#mark`.
#### Ship SVG markup
Keep the markup in a client module:
```ts
// client/icons.ts
export const reviewIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 4h16v16H4z" />
</svg>`;
```
Or put an `.svg` file in `client/` and import it. The plugin compiler bundles the file's markup as a
string. Declare the module once so TypeScript accepts the import:
```ts
// client/svg.d.ts
declare module "*.svg" {
const markup: string;
export default markup;
}
```
```ts
// index.client.tsx
import reviewIcon from "./client/review.svg";
client.addWorkspacePanel({ id: "review", title: "Review", icon: { svg: reviewIcon } /* … */ });
```
#### Render an icon
`Icon` from `@getpaseo/plugin/client/react-native` draws an icon in your own UI. Plugin bundles do
not import `lucide-react-native` or `react-native-svg`.
| Prop | Type | Required | Behavior |
| ------- | ------------ | ---------------- | ------------------------------------------------------------ |
| `name` | `string` | `name` or `icon` | Lucide icon name. |
| `icon` | `PluginIcon` | `name` or `icon` | Any icon form above. |
| `size` | `number` | No | Icon width and height. Defaults to 24. |
| `color` | `string` | No | Icon color and SVG `currentColor`. Use a plugin theme token. |
An unknown name or an SVG that breaks a rule renders nothing.
## Timeline items
@@ -1520,7 +1582,7 @@ Themes need a host that supports them. A client released before `addTheme` canno
Register a component with `client.addSettingsScreen({ id, title, icon, Component })` in
`index.client.tsx`. It appears under **Settings → Plugins → your plugin** on that host.
`id` is unique within the installation; `icon` is a Lucide name. Registration returns an
`id` is unique within the installation; `icon` is any [icon](#icons) form. Registration returns an
idempotent remover, and plugin teardown removes remaining screens.
Call `client.openSettings(id)` or a Command Center callback's `openSettings(id)` to open one
@@ -1717,7 +1779,7 @@ export default function contribute(client: PluginClientContext) {
| ----------- | -------- | ------------------------------------------------------------- |
| `id` | Yes | Plugin-local panel ID. |
| `title` | Yes | Workspace-tab title. |
| `icon` | Yes | Lucide icon name. |
| `icon` | Yes | Lucide name, `{ svg }`, or component. See [Icons](#icons). |
| `context` | Yes | `workspace` or `agent`. |
| `locations` | No | `workspace` and/or `explorer`. Defaults to `workspace`. |
| `Component` | Yes | React Native component matching the selected context's props. |
@@ -1801,14 +1863,14 @@ client.addCommandCenterItem({
`addCommandCenterItem` fields:
| Field | Required | Meaning |
| ---------- | -------- | ---------------------------------------------- |
| `id` | Yes | Plugin-local item ID. |
| `title` | Yes | Search result title. |
| `icon` | Yes | Lucide icon name. |
| `keywords` | No | Additional Command Center search terms. |
| `context` | Yes | `global`, `workspace`, or `agent`. |
| `onSelect` | Yes | Client-side callback for the matching context. |
| Field | Required | Meaning |
| ---------- | -------- | ---------------------------------------------------------- |
| `id` | Yes | Plugin-local item ID. |
| `title` | Yes | Search result title. |
| `icon` | Yes | Lucide name, `{ svg }`, or component. See [Icons](#icons). |
| `keywords` | No | Additional Command Center search terms. |
| `context` | Yes | `global`, `workspace`, or `agent`. |
| `onSelect` | Yes | Client-side callback for the matching context. |
Global items appear on the installation's selected host. Workspace items appear only when that host has an active cached workspace. Agent items appear only when the focused workspace tab is an agent or an agent-context plugin panel whose cached record belongs to that workspace. Missing context removes the item rather than calling the plugin to discover it.
@@ -1934,7 +1996,7 @@ These contracts are exported from `@getpaseo/plugin/client`.
| Field | Required | Meaning |
| ---------- | -------- | ----------------------------------------------------------------------- |
| `title` | Yes | Non-empty accessible label, tooltip, and sheet title. |
| `icon` | Yes | Lucide name or `ComponentType<PluginButtonIconProps>`. |
| `icon` | Yes | Lucide name, `{ svg }`, or `ComponentType<PluginButtonIconProps>`. |
| `label` | No | Non-empty display text. Omit to use the placement's default. |
| `visible` | No | Defaults to `true`. False removes the trigger and its layout space. |
| `disabled` | No | Defaults to `false`. Keeps the button visible and prevents interaction. |
@@ -2342,7 +2404,7 @@ export default function contribute(server: PluginServerContext) {
}
```
Paseo owns the composer menu, search picker, selected pill, draft state, and submission. The `text` value is the complete snapshot sent to the agent.
Paseo owns the composer menu, search picker, selected pill, draft state, and submission. The `text` value is the complete snapshot sent to the agent. `icon` is a Lucide name or `{ svg }`; see [Icons](#icons).
## Hosts and lifecycle
+111 -51
View File
@@ -50,23 +50,21 @@ my-plugin/
}
```
| 字段 | 是否必填 | 行为 |
| -------------- | -------- | -------------------------------------------------------- |
| `id` | 是 | 默认的安装 ID。 |
| `name` | 否 | 注册表和网站使用的非空显示名称;与安装 ID 无关。 |
| `icon` | 否 | 插件包内 PNG 文件的相对路径。 |
| `media` | 否 | 包内图片或视频路径的数组,或 HTTPS URL。空数组是有效的。 |
| `description` | 否 | 在 **设置 → 插件** 中显示在插件 ID 下方的非空摘要。 |
| `translations` | 否 | 其他语言的展示 `name` 和 `description`,以语言标签为键。 |
| `requirements` | 否 | 支持的 Paseo 版本,见下文。 |
| `build` | 否 | 准备命令,见 CLI 参考。 |
| 字段 | 是否必填 | 行为 |
| -------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `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 会在安装时拒绝这些字段。
`translations` 的键是除 `en` 之外的标准语言标签,例如 `zh-CN`。每个值可以设置 `name`、`description` 或两者,必须是非空字符串;其他键会被拒绝。展示页如何使用它们,见[其他语言](/docs/plugins/publishing#other-languages)。
### 版本要求 {#requirements}
`requirements` 是一个可选对象。它目前支持的键 `paseo` 接受一个 npm semver 范围。省略 `requirements.paseo` 表示 `<0.8.0`:即该插件早于第一个破坏性的插件版本。Paseo 0.8 及更高版本会拒绝它,并附上[迁移指南](migration)的链接。空字符串、无效的范围以及未知的 manifest 要求键都会被拒绝。
@@ -207,7 +205,7 @@ Paseo 为客户端代码提供以下模块:
这些确切的模块标识符使用宿主的运行时实例。请求其他宿主模块的客户端包会以 `Module "<name>" is not available in plugin client code` 失败。
不要导入 `lucide-react-native`、`react-native-svg` 或 DOM 库。把贡献的 `icon` 字段设为一个 [Lucide 图标名称](https://lucide.dev/icons/);Paseo 会校验名称并渲染图标。
不要导入 `lucide-react-native`、`react-native-svg` 或 DOM 库。把贡献的 `icon` 字段设为一个 [Lucide 图标名称](https://lucide.dev/icons/)、内联 SVG 或组件;Paseo 会校验图标并渲染它。参见[图标](#icons)。
### 跨平台规则 {#cross-platform-rules}
@@ -348,7 +346,7 @@ Paseo 刷新 Agent 的方式是关闭它当前的 Provider 会话,再用当前
使用 `@getpaseo/plugin/server/acp` 中的 `runAcpProvider()` 适配一个基于命令的 ACP。只针对厂商在发现、配置、通知或工具调用方面的差异添加转换器钩子。
`ProviderRegistration.icon` 是相对于插件目录的文件路径,例如 `icon.svg`。它必须解析到该目录内一个不超过 64 KiB 的普通 SVG 文件。SVG 必须是自包含的:脚本、样式、`foreignObject`、事件处理属性、JavaScript URL 以及外部的 `href` 或 `xlink:href` 引用都会被拒绝。允许 `#mark` 这样的片段引用。Paseo 在插件启动时读取并清理该文件;这个字符串从不是内联 SVG 或 URL。
`ProviderRegistration.icon` 是相对于插件目录的文件路径,例如 `icon.svg`。它必须解析到该目录内一个遵循 [SVG 图标规则](#svg-rules)的普通文件。Paseo 在插件启动时读取并校验该文件;这个字符串从不是内联 SVG 或 URL。
### 用量来源 {#usage-sources}
@@ -471,7 +469,7 @@ export default function contribute(server: PluginServerContext) {
不带 ID 调用 `usage.list_reports` 时会发现账号。带 ID 调用时,它会刷新已知的账号,而不重新发现身份。如果某个存储切换了账号,现有卡片会显示新登录的配额,直到下一次发现。报告会缓存五分钟;`forceRefresh` 会绕过缓存。条目携带 `id`、`account.label` 和 `fetchedAt`。失败的账号还会携带可选的 `loginErrors` 条目,其中包含 `harness` 和每个登录失败的 `report`。客户端通过 `server_info.features.usageSources` 判断是否启用此功能。较旧的 `provider.usage.list` RPC 会为 0.10 客户端映射同样的报告,并把问题渲染到它的 `error` 字符串中。
来源图标遵循上文的 Provider SVG 限制。
来源图标是一个文件路径,规则与 Provider 图标相同。
## 入口与清理 {#entry-point-and-cleanup}
@@ -894,10 +892,10 @@ export default function contribute(client: PluginClientContext) {
用 `@getpaseo/plugin/client/ui` 中的侧边栏组件渲染该项:
| 组件 | 属性与行为 |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SidebarRow` | 必填 `onPress`;可选 `icon`(Lucide 名称或接收 `{ size, color }` 的组件)、`label`、`active`、`trailing`、`id`。占满整行宽度。`trailing` 渲染在行的可按区域旁边,因此其中的按钮可以单独按下;按下其中其他位置则相当于按下该行。`id` 用于在测试 ID 中区分同一项的多行。 |
| `SidebarSeparator` | 没有属性。侧边栏的分隔线,放在各组行之间。 |
| 组件 | 属性与行为 |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `SidebarRow` | 必填 `onPress`;可选 `icon`(任意一种[图标](#icons)形式)、`label`、`active`、`trailing`、`id`。占满整行宽度。`trailing` 渲染在行的可按区域旁边,因此其中的按钮可以单独按下;按下其中其他位置则相当于按下该行。`id` 用于在测试 ID 中区分同一项的多行。 |
| `SidebarSeparator` | 没有属性。侧边栏的分隔线,放在各组行之间。 |
弹出框锚定在被按下的那一行,无论按下的是行本身还是它的 `trailing` 内容,因此每行的“More”按钮会在它自己的行旁边打开弹出框。
@@ -1141,13 +1139,75 @@ async function copyResult() {
### 图标 {#icons}
`Icon` 从 Paseo 已安装的图标集中渲染一个 [Lucide 图标](https://lucide.dev/icons/)。插件包不导入 `lucide-react-native` 或 `react-native-svg`。
每个贡献的 `icon` 字段都接受以下三种形式之一,类型为 `@getpaseo/plugin/client` 中的 `PluginIcon`:
| 属性 | 类型 | 是否必填 | 行为 |
| ------- | -------- | -------- | --------------------------------------------- |
| `name` | `string` | 是 | Lucide 图标名称。未知的名称不会渲染任何内容。 |
| `size` | `number` | 否 | 图标的宽度和高度。 |
| `color` | `string` | 否 | 图标颜色。请使用插件主题令牌。 |
| 形式 | 示例 | 适用场景 |
| ----------- | --------------------------- | ----------------------------------------------- |
| Lucide 名称 | `icon: "Scan"` | 任意 [Lucide 图标](https://lucide.dev/icons/)。 |
| 内联 SVG | `icon: { svg: reviewIcon }` | 品牌标志,或 Lucide 中没有的图标。 |
| 组件 | `icon: ReviewBadge` | 随状态变化的图标,例如计数器。 |
附件来源接受 Lucide 名称或内联 SVG(`PluginSerializableIcon`),因为每个附加的条目都会保存其来源的图标。
Paseo 在贡献注册时校验图标。未知的 Lucide 名称或违反规则的 SVG 会导致插件加载失败,并给出原因:
```text
Workspace panel review has an invalid icon: script elements are not allowed
```
Paseo 按界面的图标尺寸绘制内联 SVG,并把界面的图标颜色作为 `currentColor` 传入。用 `currentColor` 绘制即可跟随主题;固定的填充色会保持原样。
组件会收到 `PluginIconProps`,即 `{ size, color }`,并在该尺寸内渲染。头部按钮和 Composer 胶囊传入的是 [`PluginButtonIconProps`](#custom-icons-and-popover-content)。
#### SVG 规则 {#svg-rules}
内联 SVG、Provider 图标和用量来源图标遵循相同的规则:
- 只有一个 `<svg>` 文档,大小不超过 64 KiB。
- 不含 `<script>`、`<style>` 或 `<foreignObject>` 元素。
- 不含 `onclick` 这类事件处理属性,也不含 `javascript:` URL。
- `href` 和 `xlink:href` 只能指向同一文档中的片段,例如 `#mark`。
#### 提供 SVG 标记 {#ship-svg-markup}
把标记放在一个客户端模块中:
```ts
// client/icons.ts
export const reviewIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 4h16v16H4z" />
</svg>`;
```
或者把一个 `.svg` 文件放进 `client/` 并导入它。插件编译器会把文件的标记打包为字符串。声明一次该模块,让 TypeScript 接受这个导入:
```ts
// client/svg.d.ts
declare module "*.svg" {
const markup: string;
export default markup;
}
```
```ts
// index.client.tsx
import reviewIcon from "./client/review.svg";
client.addWorkspacePanel({ id: "review", title: "Review", icon: { svg: reviewIcon } /* … */ });
```
#### 渲染图标 {#render-an-icon}
`@getpaseo/plugin/client/react-native` 中的 `Icon` 用于在你自己的 UI 中绘制图标。插件包不导入 `lucide-react-native` 或 `react-native-svg`。
| 属性 | 类型 | 是否必填 | 行为 |
| ------- | ------------ | ----------------------- | ---------------------------------------------------------- |
| `name` | `string` | `name` 或 `icon` 二选一 | Lucide 图标名称。 |
| `icon` | `PluginIcon` | `name` 或 `icon` 二选一 | 上文任意一种图标形式。 |
| `size` | `number` | 否 | 图标的宽度和高度。默认为 24。 |
| `color` | `string` | 否 | 图标颜色,也是 SVG 的 `currentColor`。请使用插件主题令牌。 |
未知的名称或违反规则的 SVG 不会渲染任何内容。
## 时间线条目 {#timeline-items}
@@ -1299,7 +1359,7 @@ export default function contribute(client: PluginClientContext) {
## 设置界面 {#settings-screens}
在 `index.client.tsx` 中用 `client.addSettingsScreen({ id, title, icon, Component })` 注册一个组件。它会出现在该主机的 **设置 → 插件 → 你的插件** 下。`id` 在同一次安装中唯一;`icon` 是一个 Lucide 名称。注册返回一个幂等的移除函数,插件销毁时会移除剩余的界面。
在 `index.client.tsx` 中用 `client.addSettingsScreen({ id, title, icon, Component })` 注册一个组件。它会出现在该主机的 **设置 → 插件 → 你的插件** 下。`id` 在同一次安装中唯一;`icon` 可以是任意一种[图标](#icons)形式。注册返回一个幂等的移除函数,插件销毁时会移除剩余的界面。
调用 `client.openSettings(id)` 或 Command Center 回调中的 `openSettings(id)` 可以打开你自己的某个界面。即使多台主机安装了同一个插件,每次安装也有各自的值和路由。
@@ -1476,14 +1536,14 @@ export default function contribute(client: PluginClientContext) {
`addWorkspacePanel` 的字段:
| 字段 | 是否必填 | 含义 |
| ----------- | -------- | -------------------------------------------------- |
| `id` | 是 | 插件内部的面板 ID。 |
| `title` | 是 | 工作区标签页的标题。 |
| `icon` | 是 | Lucide 图标名称。 |
| `context` | 是 | `workspace` 或 `agent`。 |
| `locations` | 否 | `workspace` 和/或 `explorer`。默认为 `workspace`。 |
| `Component` | 是 | 与所选上下文的属性相匹配的 React Native 组件。 |
| 字段 | 是否必填 | 含义 |
| ----------- | -------- | --------------------------------------------------- |
| `id` | 是 | 插件内部的面板 ID。 |
| `title` | 是 | 工作区标签页的标题。 |
| `icon` | 是 | Lucide 名称、`{ svg }` 或组件。参见[图标](#icons)。 |
| `context` | 是 | `workspace` 或 `agent`。 |
| `locations` | 否 | `workspace` 和/或 `explorer`。默认为 `workspace`。 |
| `Component` | 是 | 与所选上下文的属性相匹配的 React Native 组件。 |
工作区面板接收 `PluginWorkspacePanelProps`:`context: "workspace"`、`theme`、`host`、`layout` 和 `workspaceId`。Agent 面板接收 `PluginAgentPanelProps`:`context: "agent"`、相同的通用字段和 `workspaceId`,外加 `agentId`。
@@ -1564,14 +1624,14 @@ client.addCommandCenterItem({
`addCommandCenterItem` 的字段:
| 字段 | 是否必填 | 含义 |
| ---------- | -------- | ---------------------------------- |
| `id` | 是 | 插件内部的条目 ID。 |
| `title` | 是 | 搜索结果的标题。 |
| `icon` | 是 | Lucide 图标名称。 |
| `keywords` | 否 | 额外的 Command Center 搜索词。 |
| `context` | 是 | `global`、`workspace` 或 `agent`。 |
| `onSelect` | 是 | 对应上下文的客户端回调。 |
| 字段 | 是否必填 | 含义 |
| ---------- | -------- | --------------------------------------------------- |
| `id` | 是 | 插件内部的条目 ID。 |
| `title` | 是 | 搜索结果的标题。 |
| `icon` | 是 | Lucide 名称、`{ svg }` 或组件。参见[图标](#icons)。 |
| `keywords` | 否 | 额外的 Command Center 搜索词。 |
| `context` | 是 | `global`、`workspace` 或 `agent`。 |
| `onSelect` | 是 | 对应上下文的客户端回调。 |
全局条目出现在该安装所选择的主机上。只有当该主机有一个处于活动状态的缓存工作区时,工作区条目才会出现。只有当获得焦点的工作区标签页是一个 Agent,或者是一个缓存记录属于该工作区的 Agent 上下文插件面板时,Agent 条目才会出现。缺少上下文时条目会被移除,而不是调用插件去获取上下文。
@@ -1690,14 +1750,14 @@ const pill = client.addComposerPill({
这些契约从 `@getpaseo/plugin/client` 导出。
| 字段 | 是否必填 | 含义 |
| ---------- | -------- | -------------------------------------------------------- |
| `title` | 是 | 非空的无障碍标签、提示文字和底部面板标题。 |
| `icon` | 是 | Lucide 名称或 `ComponentType<PluginButtonIconProps>`。 |
| `label` | 否 | 非空的显示文字。省略时使用该位置的默认值。 |
| `visible` | 否 | 默认为 `true`。为 false 时移除触发器及其占用的布局空间。 |
| `disabled` | 否 | 默认为 `false`。按钮保持可见,但无法交互。 |
| `behavior` | 是 | 下面三种形式之一。 |
| 字段 | 是否必填 | 含义 |
| ---------- | -------- | ------------------------------------------------------------------ |
| `title` | 是 | 非空的无障碍标签、提示文字和底部面板标题。 |
| `icon` | 是 | Lucide 名称、`{ svg }` 或 `ComponentType<PluginButtonIconProps>`。 |
| `label` | 否 | 非空的显示文字。省略时使用该位置的默认值。 |
| `visible` | 否 | 默认为 `true`。为 false 时移除触发器及其占用的布局空间。 |
| `disabled` | 否 | 默认为 `false`。按钮保持可见,但无法交互。 |
| `behavior` | 是 | 下面三种形式之一。 |
```tsx
type PluginButtonBehavior =
@@ -2086,7 +2146,7 @@ export default function contribute(server: PluginServerContext) {
}
```
Composer 菜单、搜索选择器、选中后的胶囊、草稿状态和提交都由 Paseo 负责。`text` 的值就是发送给 Agent 的完整快照。
Composer 菜单、搜索选择器、选中后的胶囊、草稿状态和提交都由 Paseo 负责。`text` 的值就是发送给 Agent 的完整快照。`icon` 是 Lucide 名称或 `{ svg }`;参见[图标](#icons)。
## 主机与生命周期 {#hosts-and-lifecycle}