mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 11:42:52 +00:00
docs(plugins): explain saved configuration and launch-only MCP servers
This commit is contained in:
+5
-1
@@ -430,7 +430,11 @@ The [public reference](../public-docs/plugins/reference.md#icons) owns the autho
|
||||
|
||||
Server entries register lifecycle observers with `server.on()` and request transforms with
|
||||
`server.before()`. The [public reference](../public-docs/plugins/reference.md#lifecycle-hooks)
|
||||
owns callback shapes, ordering, and failure behavior. `plugin-examples/lifecycle-logger` registers all
|
||||
owns callback shapes, ordering, and failure behavior. `agent.create` edits the agent's saved
|
||||
configuration; `agent.session_open` contributes launch-only `env`, `tools`, and `mcpServers`,
|
||||
re-derived on each open and following the plugin's lifecycle. See
|
||||
[Inject MCP servers](../public-docs/plugins/reference.md#inject-mcp-servers) for choosing the hook.
|
||||
`plugin-examples/lifecycle-logger` registers all
|
||||
eleven hooks; `plugin-examples/lifecycle-actions` demonstrates common automation callbacks.
|
||||
Session-open hooks also [attach tools to individual agents](../public-docs/plugins/reference.md#attach-tools-to-agents),
|
||||
as shown in `plugin-examples/agent-tools`. The agent manager stamps their metadata per session;
|
||||
|
||||
@@ -8,11 +8,11 @@ import type { AgentSessionConfig } from "../agent/agent-sdk-types.js";
|
||||
import { createTestAgentClient } from "../test-utils/fake-agent-client.js";
|
||||
import { createTestPaseoDaemon } from "../test-utils/paseo-daemon.js";
|
||||
|
||||
test("the configuration example adds MCP servers and overrides Codex options while preserving other configuration", async () => {
|
||||
test("the configuration example saves Codex options and injects launch-only MCP servers while preserving other configuration", async () => {
|
||||
const directory = await mkdtemp(path.join(tmpdir(), "paseo-config-example-"));
|
||||
const launches: AgentSessionConfig[] = [];
|
||||
const daemon = await createTestPaseoDaemon({
|
||||
daemonVersion: "0.8.0",
|
||||
daemonVersion: "0.13.2",
|
||||
agentClients: {
|
||||
codex: createTestAgentClient("codex", {
|
||||
supportsMcpServers: true,
|
||||
@@ -23,7 +23,10 @@ test("the configuration example adds MCP servers and overrides Codex options whi
|
||||
},
|
||||
mcpEnabled: false,
|
||||
});
|
||||
const client = new DaemonClient({ url: `ws://127.0.0.1:${daemon.port}/ws`, appVersion: "0.8.0" });
|
||||
const client = new DaemonClient({
|
||||
url: `ws://127.0.0.1:${daemon.port}/ws`,
|
||||
appVersion: "0.13.2",
|
||||
});
|
||||
try {
|
||||
await client.connect();
|
||||
await client.fetchAgents({ subscribe: {} });
|
||||
@@ -53,9 +56,11 @@ test("the configuration example adds MCP servers and overrides Codex options whi
|
||||
},
|
||||
mcpServers: {
|
||||
existing: { type: "http", url: "https://existing.example.com/mcp" },
|
||||
company: { type: "http", url: "https://tools.example.com/mcp" },
|
||||
},
|
||||
});
|
||||
expect(daemon.daemon.agentManager.getAgent(agent.id)!.config.mcpServers).toEqual({
|
||||
existing: { type: "http", url: "https://existing.example.com/mcp" },
|
||||
});
|
||||
expect(launches[0].mcpServers).toEqual({
|
||||
existing: { type: "http", url: "https://existing.example.com/mcp" },
|
||||
company: { type: "http", url: "https://tools.example.com/mcp" },
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
# Agent configuration
|
||||
|
||||
Changes new Codex agents through `server.before("agent.create", ...)`:
|
||||
Sets saved Codex options through `server.before("agent.create", ...)`:
|
||||
|
||||
- Sets `config.providerOptions.sandbox_mode` to `workspace-write`.
|
||||
- Sets `config.providerOptions.approval_policy` to `on-request`.
|
||||
- Adds the `company` server to `config.mcpServers`.
|
||||
- Preserves other configuration, provider options, MCP servers, and environment overrides.
|
||||
- Preserves other configuration and provider options.
|
||||
|
||||
Adds the `company` MCP server to Codex launches through
|
||||
`server.before("agent.session_open", ...)`. The server is never saved in the agent's configuration;
|
||||
existing saved MCP servers are preserved. Existing agents receive the server through the
|
||||
[session reopen behavior](../../public-docs/plugins/reference.md#attach-tools-to-agents).
|
||||
|
||||
Replace `https://tools.example.com/mcp` in `index.server.ts` with your MCP server URL before using
|
||||
this example. The URL is a placeholder. The `company` entry replaces an existing server with that name.
|
||||
this example. A `company` name collision with a saved server or another
|
||||
plugin fails the session open and names both sources.
|
||||
|
||||
Install on a daemon with plugins enabled:
|
||||
|
||||
@@ -16,11 +21,13 @@ Install on a daemon with plugins enabled:
|
||||
paseo plugin install /absolute/path/to/plugin-examples/agent-configuration
|
||||
```
|
||||
|
||||
The callback receives the request after earlier plugins have transformed it. The nested spreads
|
||||
preserve their settings; the explicit values replace only the named fields. Paseo validates and saves
|
||||
the resulting configuration before starting the agent. Existing agents are unchanged.
|
||||
Each session-open callback receives only this plugin's MCP servers. The nested spreads preserve
|
||||
entries added by this plugin's earlier callbacks. The create callback receives configuration after
|
||||
earlier plugins have transformed it; its explicit Codex options replace the named fields in the
|
||||
saved configuration of new agents and remain after this plugin is disabled.
|
||||
|
||||
See the [lifecycle reference](../../public-docs/plugins/reference.md#lifecycle-hooks) for ordering
|
||||
and callback shapes. [Lifecycle actions](../lifecycle-actions) demonstrates provider switching and
|
||||
environment injection. Its provider-switch callback clears provider options when changing Codex to
|
||||
Claude, so use these examples separately when trying the Codex-specific settings.
|
||||
See [Inject MCP servers](../../public-docs/plugins/reference.md#inject-mcp-servers) for choosing
|
||||
between saved configuration and plugin-owned servers. [Lifecycle actions](../lifecycle-actions)
|
||||
demonstrates provider switching and environment injection. Its provider-switch callback clears
|
||||
provider options when changing Codex to Claude, so use these examples separately when trying the
|
||||
Codex-specific settings.
|
||||
|
||||
@@ -15,12 +15,22 @@ export default function contribute(server: PluginServerContext) {
|
||||
sandbox_mode: "workspace-write",
|
||||
approval_policy: "on-request",
|
||||
},
|
||||
mcpServers: {
|
||||
...request.config.mcpServers,
|
||||
company: {
|
||||
type: "http",
|
||||
url: "https://tools.example.com/mcp",
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.provider !== "codex") {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
...request,
|
||||
mcpServers: {
|
||||
...request.mcpServers,
|
||||
company: {
|
||||
type: "http",
|
||||
url: "https://tools.example.com/mcp",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "agent-configuration",
|
||||
"requirements": {
|
||||
"paseo": ">=0.8.0"
|
||||
"paseo": ">=0.13.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,9 +653,14 @@ export default function contribute(server: PluginServerContext) {
|
||||
|
||||
Hooks run on the daemon while the plugin is enabled, even with no app connected.
|
||||
|
||||
### Change configuration and inject an MCP server
|
||||
`agent.create` edits the agent's saved configuration. Changes to `config` are persisted and remain
|
||||
after the plugin is disabled or removed. `agent.session_open` contributes launch-only `env`, `tools`,
|
||||
and `mcpServers`, re-derived on every create, resume, refresh, and import, following the plugin's
|
||||
lifecycle without being saved in the agent record.
|
||||
|
||||
Add this callback inside `contribute(server)`. Replace the placeholder URL with your MCP endpoint.
|
||||
### Change saved configuration
|
||||
|
||||
Add this callback inside `contribute(server)` to set the saved options for new Codex agents:
|
||||
|
||||
```ts
|
||||
server.before("agent.create", ({ request }) => {
|
||||
@@ -672,27 +677,50 @@ server.before("agent.create", ({ request }) => {
|
||||
sandbox_mode: "workspace-write",
|
||||
approval_policy: "on-request",
|
||||
},
|
||||
mcpServers: {
|
||||
...request.config.mcpServers,
|
||||
company: {
|
||||
type: "http",
|
||||
url: "https://tools.example.com/mcp",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
| Input | Result |
|
||||
| ------------------------------------------- | ----------------------------- |
|
||||
| `providerOptions.sandbox_mode: "read-only"` | `"workspace-write"` |
|
||||
| `providerOptions.web_search: "disabled"` | Preserved by the spread |
|
||||
| Existing `mcpServers.search` | Preserved by the spread |
|
||||
| Existing `mcpServers.company` | Replaced with the entry above |
|
||||
| Input | Result |
|
||||
| ------------------------------------------- | ----------------------- |
|
||||
| `providerOptions.sandbox_mode: "read-only"` | `"workspace-write"` |
|
||||
| `providerOptions.web_search: "disabled"` | Preserved by the spread |
|
||||
|
||||
The selected provider validates `providerOptions` and must support the configured MCP servers.
|
||||
Explicit Codex sandbox and approval options override its mode presets.
|
||||
The selected provider validates `providerOptions`. Explicit Codex sandbox and approval options
|
||||
override its mode presets.
|
||||
|
||||
### Inject MCP servers
|
||||
|
||||
Use `agent.create.config.mcpServers` when the server should become part of the agent's saved
|
||||
configuration. For a plugin-owned server, add this callback inside `contribute(server)`, replacing
|
||||
the placeholder URL with your MCP endpoint:
|
||||
|
||||
```ts
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.provider !== "codex") return;
|
||||
|
||||
return {
|
||||
...request,
|
||||
mcpServers: {
|
||||
...request.mcpServers,
|
||||
company: { type: "http", url: "https://tools.example.com/mcp" },
|
||||
},
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
`request.mcpServers` uses the same server configurations as `AgentSessionConfig.mcpServers`.
|
||||
The map starts empty for each plugin and accumulates across that plugin's own callbacks. It never
|
||||
contains the agent's saved servers or another plugin's servers. Replace the map to add, replace,
|
||||
or remove this plugin's entries; returning `undefined` preserves it. Paseo merges the plugins'
|
||||
final maps in plugin-ID order.
|
||||
|
||||
A name colliding with a saved server, Paseo's internal `paseo` server, or another plugin's server
|
||||
fails the session open and names the server and both sources. A provider without MCP support fails
|
||||
with `does not support MCP servers`, naming the plugin. Opens with `purpose: "history"` ignore
|
||||
these servers. Install, disable, and reload changes reach existing agents through the
|
||||
[session reopen behavior](#attach-tools-to-agents).
|
||||
|
||||
### Inject environment variables on every session opening
|
||||
|
||||
@@ -708,8 +736,8 @@ server.before("agent.session_open", ({ request }) => {
|
||||
});
|
||||
```
|
||||
|
||||
This runs on create, resume, refresh, and import. To inject only on creation, set `env` in an
|
||||
`agent.create` callback instead.
|
||||
Session-open overrides are re-derived on every open. `agent.create.env` applies only to the
|
||||
initial launch and is not saved in the agent's configuration.
|
||||
|
||||
### Attach tools to agents
|
||||
|
||||
@@ -992,11 +1020,11 @@ type PluginTurnOutcome =
|
||||
|
||||
### Before hooks
|
||||
|
||||
| Name | Request fields | Editable |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
||||
| `agent.create` | `config`, optional `env` | Public agent config except `cwd`; `env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`, read-only `title` and `labels`, `reason`, `purpose`, `env`, `tools` | `env` and `tools` |
|
||||
| `workspace.create` | `source`, optional `title`, `firstAgentContext` | Entire explicit creation request |
|
||||
| Name | Request fields | Editable |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
|
||||
| `agent.create` | `config`, optional `env` | Public agent config except `cwd`; `env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`, read-only `title` and `labels`, `reason`, `purpose`, `env`, `tools`, `mcpServers` | Launch-only `env`, `tools`, `mcpServers` |
|
||||
| `workspace.create` | `source`, optional `title`, `firstAgentContext` | Entire explicit creation request |
|
||||
|
||||
**`agent.create.config`** uses `AgentSessionConfig`:
|
||||
|
||||
@@ -1020,6 +1048,7 @@ type PluginTurnOutcome =
|
||||
"title": "Workspace notes",
|
||||
"labels": { "notes/enabled": "true" },
|
||||
"tools": [],
|
||||
"mcpServers": {},
|
||||
"reason": "resume",
|
||||
"purpose": "interactive",
|
||||
"env": { "COMPANY_ENV": "development" }
|
||||
@@ -1032,6 +1061,7 @@ type PluginTurnOutcome =
|
||||
| `title` | Read-only string or `null`; creation title on create, stored title on resume. |
|
||||
| `labels` | Read-only string map; creation labels on create, stored labels on resume. |
|
||||
| `tools` | Editable `AgentToolDefinition[]`, local to this plugin. See [Attach tools to agents](#attach-tools-to-agents). |
|
||||
| `mcpServers` | Editable launch-only server map, local to this plugin. See [Inject MCP servers](#inject-mcp-servers). |
|
||||
| `reason` | `create`, `resume`, `refresh`, `import` |
|
||||
| `purpose` | `interactive`, `history` |
|
||||
| `env` | Launch override map; excludes the daemon's inherited environment. Replace the map to add, replace, or remove overrides. |
|
||||
@@ -1043,7 +1073,7 @@ Creation request
|
||||
→ agent.create hooks (plugin-ID order; registration order within each plugin)
|
||||
→ resolve defaults and validate provider configuration
|
||||
→ derive launch configuration with Paseo runtime tools and daemon prompt
|
||||
→ agent.session_open hooks (same ordering; env and plugin-local tools)
|
||||
→ agent.session_open hooks (same ordering; env and plugin-local tools and MCP servers)
|
||||
→ set PASEO_AGENT_ID and PASEO_AGENT_CWD
|
||||
→ open provider session and save agent configuration
|
||||
```
|
||||
@@ -1055,8 +1085,9 @@ Creation request
|
||||
| `undefined` | Unchanged request |
|
||||
| Throws or returns invalid data | Operation fails; later callbacks do not run |
|
||||
|
||||
No automatic deep merge. Later callbacks can overwrite earlier values. Agent configuration is
|
||||
saved; environment overrides are not persisted with it.
|
||||
There is no automatic deep merge. `env` accumulates across plugins; `tools` and `mcpServers`
|
||||
accumulate only across callbacks within the same plugin. Returning a replacement map or array
|
||||
replaces that scope's prior value.
|
||||
|
||||
### Context and cleanup
|
||||
|
||||
|
||||
@@ -529,9 +529,12 @@ export default function contribute(server: PluginServerContext) {
|
||||
|
||||
只要插件处于启用状态,钩子就会在 daemon 上运行,即使没有应用连接。
|
||||
|
||||
### 修改配置并注入 MCP 服务器 {#change-configuration-and-inject-an-mcp-server}
|
||||
`agent.create` 修改 Agent 的已保存配置。对 `config` 的修改会被持久化,在插件停用或移除后仍然保留。
|
||||
`agent.session_open` 提供仅用于启动的 `env`、`tools` 和 `mcpServers`;每次创建、恢复、刷新和导入时都会重新计算,随插件的生命周期变化,不会写入 Agent 记录。
|
||||
|
||||
在 `contribute(server)` 中添加这个回调。把占位 URL 替换为你的 MCP 端点。
|
||||
### 修改已保存的配置 {#change-saved-configuration}
|
||||
|
||||
在 `contribute(server)` 中添加这个回调,为新的 Codex Agent 设置已保存的选项:
|
||||
|
||||
```ts
|
||||
server.before("agent.create", ({ request }) => {
|
||||
@@ -548,13 +551,6 @@ server.before("agent.create", ({ request }) => {
|
||||
sandbox_mode: "workspace-write",
|
||||
approval_policy: "on-request",
|
||||
},
|
||||
mcpServers: {
|
||||
...request.config.mcpServers,
|
||||
company: {
|
||||
type: "http",
|
||||
url: "https://tools.example.com/mcp",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -564,10 +560,37 @@ server.before("agent.create", ({ request }) => {
|
||||
| ------------------------------------------- | ------------------- |
|
||||
| `providerOptions.sandbox_mode: "read-only"` | `"workspace-write"` |
|
||||
| `providerOptions.web_search: "disabled"` | 由展开运算保留 |
|
||||
| 已有的 `mcpServers.search` | 由展开运算保留 |
|
||||
| 已有的 `mcpServers.company` | 被替换为上面的条目 |
|
||||
|
||||
所选的 Provider 会校验 `providerOptions`,并且必须支持配置的 MCP 服务器。显式的 Codex 沙盒和批准选项会覆盖它的模式预设。
|
||||
所选的 Provider 会校验 `providerOptions`。显式的 Codex 沙盒和批准选项会覆盖它的模式预设。
|
||||
|
||||
### 注入 MCP 服务器 {#inject-mcp-servers}
|
||||
|
||||
需要将服务器保存为 Agent 配置的一部分时,使用 `agent.create.config.mcpServers`。
|
||||
插件拥有的服务器使用下面的回调,在 `contribute(server)` 中添加,并把占位 URL 替换为你的 MCP 端点:
|
||||
|
||||
```ts
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.provider !== "codex") return;
|
||||
|
||||
return {
|
||||
...request,
|
||||
mcpServers: {
|
||||
...request.mcpServers,
|
||||
company: { type: "http", url: "https://tools.example.com/mcp" },
|
||||
},
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
`request.mcpServers` 使用与 `AgentSessionConfig.mcpServers` 相同的服务器配置。
|
||||
每个插件的映射从空开始,只在该插件自己的回调之间累积,不包含 Agent 已保存的服务器或其他插件的服务器。
|
||||
替换映射即可添加、替换或移除本插件的条目;返回 `undefined` 会保持不变。
|
||||
Paseo 按插件 ID 顺序合并各插件的最终映射。
|
||||
|
||||
名称与已保存的服务器、Paseo 内部的 `paseo` 服务器或其他插件的服务器冲突时,会话打开失败,错误会指出服务器名称及双方来源。
|
||||
不支持 MCP 的 Provider 会报 `does not support MCP servers` 错误,并指出插件名称。
|
||||
`purpose: "history"` 的会话打开会忽略这些服务器。安装、停用和重新加载插件后,现有 Agent
|
||||
通过[会话重新打开行为](#attach-tools-to-agents)获取变化。
|
||||
|
||||
### 在每次打开会话时注入环境变量 {#inject-environment-variables-on-every-session-opening}
|
||||
|
||||
@@ -583,7 +606,7 @@ server.before("agent.session_open", ({ request }) => {
|
||||
});
|
||||
```
|
||||
|
||||
它会在创建、恢复、刷新和导入时运行。如果只想在创建时注入,请改为在 `agent.create` 回调中设置 `env`。
|
||||
会话打开时的环境变量覆盖项会在每次打开时重新计算。`agent.create.env` 只作用于首次启动,不会写入 Agent 的已保存配置。
|
||||
|
||||
### 为 Agent 附加工具 {#attach-tools-to-agents}
|
||||
|
||||
@@ -852,11 +875,11 @@ type PluginTurnOutcome =
|
||||
|
||||
### before 钩子 {#before-hooks}
|
||||
|
||||
| 名称 | 请求字段 | 可编辑 |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------------- |
|
||||
| `agent.create` | `config`,可选的 `env` | 除 `cwd` 外的公开 Agent 配置;`env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`,只读的 `title` 和 `labels`,`reason`, `purpose`, `env`, `tools` | `env` 和 `tools` |
|
||||
| `workspace.create` | `source`,可选的 `title`,`firstAgentContext` | 整个显式创建请求 |
|
||||
| 名称 | 请求字段 | 可编辑 |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| `agent.create` | `config`,可选的 `env` | 除 `cwd` 外的公开 Agent 配置;`env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`,只读的 `title` 和 `labels`,`reason`, `purpose`, `env`, `tools`, `mcpServers` | 仅用于启动的 `env`、`tools`、`mcpServers` |
|
||||
| `workspace.create` | `source`,可选的 `title`,`firstAgentContext` | 整个显式创建请求 |
|
||||
|
||||
**`agent.create.config`** 使用 `AgentSessionConfig`:
|
||||
|
||||
@@ -880,6 +903,7 @@ type PluginTurnOutcome =
|
||||
"title": "Workspace notes",
|
||||
"labels": { "notes/enabled": "true" },
|
||||
"tools": [],
|
||||
"mcpServers": {},
|
||||
"reason": "resume",
|
||||
"purpose": "interactive",
|
||||
"env": { "COMPANY_ENV": "development" }
|
||||
@@ -892,6 +916,7 @@ type PluginTurnOutcome =
|
||||
| `title` | 只读字符串或 `null`;创建时使用创建请求的标题,恢复时使用已保存的标题。 |
|
||||
| `labels` | 只读的字符串映射;创建时使用创建请求的标签,恢复时使用已保存的标签。 |
|
||||
| `tools` | 可编辑的 `AgentToolDefinition[]`,仅包含此插件的工具。参阅[为 Agent 附加工具](#attach-tools-to-agents)。 |
|
||||
| `mcpServers` | 可编辑的服务器映射,仅用于启动且仅包含本插件的条目。参阅[注入 MCP 服务器](#inject-mcp-servers)。 |
|
||||
| `reason` | `create`、`resume`、`refresh`、`import` |
|
||||
| `purpose` | `interactive`、`history` |
|
||||
| `env` | 启动覆盖映射;不包括 daemon 继承的环境变量。替换整个映射即可添加、替换或移除覆盖项。 |
|
||||
@@ -903,7 +928,7 @@ Creation request
|
||||
→ agent.create hooks (plugin-ID order; registration order within each plugin)
|
||||
→ resolve defaults and validate provider configuration
|
||||
→ derive launch configuration with Paseo runtime tools and daemon prompt
|
||||
→ agent.session_open hooks (same ordering; env and plugin-local tools)
|
||||
→ agent.session_open hooks (same ordering; env and plugin-local tools and MCP servers)
|
||||
→ set PASEO_AGENT_ID and PASEO_AGENT_CWD
|
||||
→ open provider session and save agent configuration
|
||||
```
|
||||
@@ -915,7 +940,8 @@ Creation request
|
||||
| `undefined` | 未改变的请求 |
|
||||
| 抛出错误或返回无效数据 | 操作失败;后面的回调不会运行 |
|
||||
|
||||
没有自动的深度合并。后面的回调可以覆盖前面的值。Agent 配置会被保存;环境变量覆盖项不会随之持久化。
|
||||
没有自动的深度合并。`env` 在插件之间累积;`tools` 和 `mcpServers` 只在同一插件的回调之间累积。
|
||||
返回替换的映射或数组会替换该范围内之前的值。
|
||||
|
||||
### context 与清理 {#context-and-cleanup}
|
||||
|
||||
@@ -1187,7 +1213,7 @@ export function IssueActions({ theme }: PluginSurfaceProps) {
|
||||
```tsx
|
||||
import { Markdown } from "@getpaseo/plugin/client/ui";
|
||||
|
||||
<Markdown>{"## 审查\n\n检查**通过**。"}</Markdown>;
|
||||
<Markdown>{"## Review\n\nThe checks **passed**."}</Markdown>;
|
||||
```
|
||||
|
||||
`children` 是唯一的属性,必须为字符串。更新它会立即渲染新内容;空字符串不渲染任何内容。
|
||||
|
||||
@@ -27,28 +27,29 @@ public docs; this skill indexes the references and examples.
|
||||
|
||||
Pick the contribution that matches the request. Each row names the registration, when it fits, and where the full contract lives. Most plugins combine several: a slash command that calls an RPC, which appends a timeline row, which a renderer draws.
|
||||
|
||||
| Contribution | Registration | Use it when | Reference |
|
||||
| ------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| Screen and sidebar item | `addScreen` + `addSidebarHeaderItem`/`addSidebarFooterItem` | A full screen of plugin UI, or sidebar header or footer rows that open a screen or popover | reference.md → Screens and sidebar items |
|
||||
| Workspace panel | `addWorkspacePanel` | UI that lives as a tab beside agents, terminals, files, and diffs; `locations: ["explorer"]` for the Explorer | reference.md → Workspace panels |
|
||||
| File panel | `addFilePanel` | View or edit a matching file inside the file tab through its file handle | reference.md → File panels; `plugin-examples/pdf-panel`, `plugin-examples/markdown-panel` |
|
||||
| Command Center item | `addCommandCenterItem` | A global, workspace, or agent action reachable from ⌘K | reference.md → Command Center items |
|
||||
| Client slash command | `addSlashCommand` | A `/command args` in the composer that runs plugin code instead of prompting the agent | reference.md → Slash commands |
|
||||
| Composer pill | `addComposerPill` | A per-agent button in the composer track bar next to Tasks and Subagents | reference.md → Composer pills |
|
||||
| Timeline transformer | `addTimelineTransformer` + `addTimelineRenderer` | Replace, explode, or hide a built-in timeline item, including while it streams | reference.md → Timeline items; `plugin-examples/timeline-items`, `plugin-examples/inline-thinking` |
|
||||
| Timeline row | `paseo.agents.ref(id).timeline.append(...)` | Push a plugin-owned row into an agent timeline from a server handler and update it later | reference.md → Append a timeline row from the daemon |
|
||||
| Attachment source | `client.addAttachmentSource` + `server.handle` | Let the user attach a searchable external resource, such as an issue, to a prompt | reference.md → Add a composer attachment source; `plugin-examples/linear` |
|
||||
| Theme | `addTheme` | A light or dark palette under Settings → Appearance | reference.md → Contribute a theme; `plugin-examples/catppuccin` |
|
||||
| Plugin RPC | `defineRpc` + `server.handle` + `useRpc` | Daemon-side work that is not a normal Paseo operation: vendor APIs, credentials, local files | reference.md → Add plugin-specific backend behavior |
|
||||
| Lifecycle events | `server.on` | Observe agent/workspace lifecycle, inspect ended turns, and answer permission requests | [Lifecycle hooks](https://paseo.sh/docs/plugins/reference.md#lifecycle-hooks) |
|
||||
| Creation and launch hooks | `server.before` | Change agent config, provider options, MCP servers, environment, or workspace isolation before the operation | [Before hooks](https://paseo.sh/docs/plugins/reference.md#before-hooks) |
|
||||
| Paseo SDK | `usePaseo()` / handler `{ paseo }` | Normal Paseo operations: workspaces, agents, providers, config | reference.md → Use the Paseo SDK |
|
||||
| Contribution | Registration | Use it when | Reference |
|
||||
| ------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| Screen and sidebar item | `addScreen` + `addSidebarHeaderItem`/`addSidebarFooterItem` | A full screen of plugin UI, or sidebar header or footer rows that open a screen or popover | reference.md → Screens and sidebar items |
|
||||
| Workspace panel | `addWorkspacePanel` | UI that lives as a tab beside agents, terminals, files, and diffs; `locations: ["explorer"]` for the Explorer | reference.md → Workspace panels |
|
||||
| File panel | `addFilePanel` | View or edit a matching file inside the file tab through its file handle | reference.md → File panels; `plugin-examples/pdf-panel`, `plugin-examples/markdown-panel` |
|
||||
| Command Center item | `addCommandCenterItem` | A global, workspace, or agent action reachable from ⌘K | reference.md → Command Center items |
|
||||
| Client slash command | `addSlashCommand` | A `/command args` in the composer that runs plugin code instead of prompting the agent | reference.md → Slash commands |
|
||||
| Composer pill | `addComposerPill` | A per-agent button in the composer track bar next to Tasks and Subagents | reference.md → Composer pills |
|
||||
| Timeline transformer | `addTimelineTransformer` + `addTimelineRenderer` | Replace, explode, or hide a built-in timeline item, including while it streams | reference.md → Timeline items; `plugin-examples/timeline-items`, `plugin-examples/inline-thinking` |
|
||||
| Timeline row | `paseo.agents.ref(id).timeline.append(...)` | Push a plugin-owned row into an agent timeline from a server handler and update it later | reference.md → Append a timeline row from the daemon |
|
||||
| Attachment source | `client.addAttachmentSource` + `server.handle` | Let the user attach a searchable external resource, such as an issue, to a prompt | reference.md → Add a composer attachment source; `plugin-examples/linear` |
|
||||
| Theme | `addTheme` | A light or dark palette under Settings → Appearance | reference.md → Contribute a theme; `plugin-examples/catppuccin` |
|
||||
| Plugin RPC | `defineRpc` + `server.handle` + `useRpc` | Daemon-side work that is not a normal Paseo operation: vendor APIs, credentials, local files | reference.md → Add plugin-specific backend behavior |
|
||||
| Lifecycle events | `server.on` | Observe agent/workspace lifecycle, inspect ended turns, and answer permission requests | [Lifecycle hooks](https://paseo.sh/docs/plugins/reference.md#lifecycle-hooks) |
|
||||
| Creation and launch hooks | `server.before` | `agent.create` edits saved config; `agent.session_open` contributes launch-only `env`, `tools`, `mcpServers` on every open; `workspace.create` chooses isolation | [Before hooks](https://paseo.sh/docs/plugins/reference.md#before-hooks) |
|
||||
| Paseo SDK | `usePaseo()` / handler `{ paseo }` | Normal Paseo operations: workspaces, agents, providers, config | reference.md → Use the Paseo SDK |
|
||||
|
||||
| Lifecycle task | Example |
|
||||
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| Log all eleven hooks | [lifecycle-logger](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-logger) |
|
||||
| Follow-ups, permissions, environment, provider switching, worktrees | [lifecycle-actions](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-actions) |
|
||||
| Inject MCP servers and change Codex sandbox/approval options | [agent-configuration](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-configuration) |
|
||||
| Lifecycle task | Example |
|
||||
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| Log all eleven hooks | [lifecycle-logger](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-logger) |
|
||||
| Follow-ups, permissions, environment, provider switching, worktrees | [lifecycle-actions](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-actions) |
|
||||
| Inject launch-only MCP servers and save Codex sandbox/approval options | [agent-configuration](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-configuration) |
|
||||
| Attach a tool to selected agents | [agent-tools](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-tools) |
|
||||
|
||||
## Create the project
|
||||
|
||||
@@ -377,6 +378,35 @@ Inputs and outputs are validated on both sides. Backend handlers receive the sam
|
||||
|
||||
Use TanStack Query for async request state, caching, and mutations.
|
||||
|
||||
### Contribute tools and MCP servers at session open
|
||||
|
||||
Use `before("agent.session_open")` for per-agent tools and plugin-owned MCP servers. Add this
|
||||
callback inside `contribute(server)`:
|
||||
|
||||
```ts
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.provider !== "codex") return;
|
||||
return {
|
||||
...request,
|
||||
mcpServers: {
|
||||
...request.mcpServers,
|
||||
company: { type: "http", url: "https://tools.example.com/mcp" },
|
||||
},
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
`tools` and `mcpServers` start empty for each plugin and accumulate across its own callbacks.
|
||||
They are launch-only. Use `agent.create` to edit configuration that should be saved with the agent.
|
||||
See [Attach tools to agents](https://paseo.sh/docs/plugins/reference.md#attach-tools-to-agents)
|
||||
for `defineAgentTool` and targeting, and
|
||||
[Inject MCP servers](https://paseo.sh/docs/plugins/reference.md#inject-mcp-servers) for server configuration and collisions.
|
||||
|
||||
Starting, stopping, or reloading a plugin with a session-open hook marks open agent sessions stale.
|
||||
Each reopens before its next idle prompt without interrupting a running turn.
|
||||
`await paseo.agents.ref(id).reload()` applies changes immediately and interrupts a running turn;
|
||||
`refresh()` only reads the current snapshot.
|
||||
|
||||
### Debug daemon-side behavior
|
||||
|
||||
Backend contributions can use normal Node logging. `console.log()` writes to the plugin's stdout;
|
||||
|
||||
Reference in New Issue
Block a user