paseo-plugin
Build and manage trusted local Paseo plugins. Use when the user asks to create, edit, install, reload, enable, disable, remove, or troubleshoot a Paseo plugin; add lifecycle hooks; transform agent configuration, environment, MCP servers, or workspace creation; automate permissions or turn follow-ups
By getpaseo · 522 installs
npx skills add getpaseo/paseo --skill paseo-plugin
Source repository · Upstream listing
Paseo plugins
Build or manage the requested plugin directly. Use the current public docs to catch contract changes, but keep working from this skill if the network is unavailable.
User's request: $ARGUMENTS
Check current documentation
Fetch [https://paseo.sh/llms.txt](https://paseo.sh/llms.txt) first. Select and fetch the current plugin Markdown pages from that index before changing a plugin:
[Plugin quickstart](https://paseo.sh/docs/plugins.md) ([browser page](https://paseo.sh/docs/plugins))
[Plugin reference](https://paseo.sh/docs/plugins/v0.8/reference.md) ([browser page](https://paseo.sh/docs/plugins/v0.8/reference))
Use the deployed docs when they disagree with this skill. Do not send the user away to read them instead of completing the work.
In the Paseo repository, use public docs/plugins/v0.8/reference.md for the checkout's API, including
unreleased changes. Use docs/plugins.md for maintainer guidance. Complete contracts belong in the
public docs; this skill indexes the references and examples.
What a plugin can contribute
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
Sidebar surface addSurface + addSidebarItem A full screen of plugin UI reachable from the sidebar reference.md → Surfaces and sidebar items; plugin examples/local plugin
Workspace panel addWorkspacePanel UI that lives as a tab beside agents, terminals, files, and diffs; locations: ["explorer"] for the Explorer reference.md → Workspace panels
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 → Client 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/v0.8/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/v0.8/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)
Create the project
Use an absolute path on the daemon machine. init writes files but does not install packages.
The generated project contains:
The manifest supplies the default install ID and supported Paseo versions:
Keep requirements.paseo correct whenever creating or editing a plugin. init uses = followed
by the CLI version. Raise the minimum when adopting newer APIs; add an upper bound when a later
Paseo release is incompatible. Use npm semver ranges and explicitly include beta versions when
targeting betas. Missing requirements mean <0.8.0 ; complete the 0.8 entry migration before adding
=0.8.0 . Verify compatibility with both the daemon and the app running client contributions.
See [requirements](https://paseo.sh/docs/plugins/v0.8/reference requirements).
Each runtime has its own optional entry. A plugin must have at least one. Both entries accept
.ts or .tsx ; use .tsx when an entry imports components.
Path Runtime
index.client.tsx and client/ App
index.server.ts and server/ Daemon subprocess
shared/ Both
Do not put any other code modules in the plugin root.
A client import of server/ , a server import of client/ , and every node: import reachable from
client code is a compile error. A relative import to another code file in the plugin root is also a
compile error; move it into client/ , server/ , or shared/ . Shared modules contain Zod contracts
and plain values; they do not import Node or React Native runtime APIs.
Default export one contribution function from each entry and return cleanup:
Cleanup can be async. Use it for timers, watchers, sockets, subscriptions, and other resources
created by plugin code. Every client add method returns an idempotent remover. Paseo calls the
entry cleanup first, removes registrations that remain, rejects pending RPCs, closes the plugin
session, and stops the subprocess when the plugin stops.
Add a workspace panel
Workspace panels live beside agents, terminals, files, and diffs. Plugins run on desktop and
mobile, and Paseo has multiple themes. Every Text must take its color from theme.colors .
Use layout.compact for padding and stacking. Unstyled text is black and fails in dark themes.
Use useWorkspace(id, selector) and useAgent(id, selector) . Selectors are required
and their results use shallow equality. Never select the whole snapshot or add an RPC to discover
the active workspace or agent. Command callbacks receive the selected host's paseo , typed
rpc(contract, input) , openSurface(id) , and contextual openPanel(id) capabilities.
Add a sidebar surface
Plugin surfaces use React Native primitives and work across desktop, browser, iOS, and Android. Register the surface before its sidebar item. Color text from theme.colors and pad from layout.compact .
Icons are Lucide icon names. theme is a typed PluginTheme on every surface and panel. Primary text uses theme.colors.foreground ; labels use theme.colors.foregroundMuted ; the root view uses theme.colors.surface0 . layout.compact is true on mobile and narrow windows. Paseo owns the route, header, host picker, close action, error boundary, and per installation query client.
Before writing imports, classify each module as shared, client, or server. Follow the
[SDK import boundaries](https://paseo.sh/docs/plugins/v0.8/reference.md runtime modules), including
transitive and type dependencies. The root is shared only; hooks and client contexts belong to
@getpaseo/plugin/client , server contexts to /server , and host UI to /client/react native or /client/ui .
Install dependencies locally for typechecking; Paseo supplies host runtime modules. JSX uses the
automatic runtime. Do not import /client/host from plugin code.
Works on mobile
Before reporting a plugin done:
Use React Native primitives only: View , Text , Pressable , ScrollView , and TextInput .
Do not use HTML elements, className , CSS strings, or onClick .
Do not put "DOM" in tsconfig.json or use /// <reference lib="dom" / . Put DOM globals only in
client/web.ts , declare only what that module uses, gate every export on Platform.OS === "web" ,
and provide the native alternative or a no op.
Take colors from theme.colors .
Check the compact layout.
Run this audit on client/ :
A hit outside client/web.ts is a bug.
Choose the correct API
Use the existing Paseo SDK for normal Paseo operations. Use plugin RPC only for plugin specific backend behavior.
Call Paseo from a surface
usePaseo() borrows the selected host's current connection. Never create another client inside a surface.
The API covers workspaces, agents, providers, and daemon config. It omits connection lifecycle because Paseo owns the connection. Consult the current [SDK reference](https://paseo.sh/docs/sdk/reference.md) for method details.
Add daemon side behavior
Define one Zod contract in shared/ , register its subprocess handler in index.server.ts , and
call it from client code with useRpc() :
Inputs and outputs are validated on both sides. Backend handlers receive the same PaseoApi as { paseo } ; their IPC backed daemon session lives exactly as long as the subprocess. Backend code can use Node APIs and installed dependencies. Keep credentials, filesystem access, shell commands, and vendor API calls in the handler rather than the client surface.
Use TanStack Query for async request state, caching, and mutations.
Debug daemon side behavior
Backend contributions can use normal Node logging. console.log() writes to the plugin's stdout;
console.error() writes to stderr. Paseo captures both streams w