Paseo plugin: browse, filter, and search work items in a self-hosted Plane workspace and start work on any of them in a fresh workspace.
npmjs · Paseo 0.9+
paseo plugin add npm:@aightto/plane-to-paseo@0.1.1GitHub · Paseo 0.8 fallback
paseo plugin add g0rdonL/plane-to-paseo --ref 5ea774fed27bfbb991c1a955019e70bead49080fGit security status and fallback installation are pinned to commit 5ea774fed27b.
From the plugin's README
git clone git@github.com:g0rdonL/plane-to-paseo.git
cd plane-to-paseo
npm install # .npmrc sets legacy-peer-deps; npm 10.9 crashes without it
npm run typecheck
paseo plugin install "$PWD"
paseo plugin ls # plane-to-paseo should report "running"
Then in Plane, open Profile settings → Developer → API tokens
(https://<instance>/settings/profile/api-tokens/), create a token, and paste it in Paseo under
Settings → Plugins → Plane. Instance URL and workspace slug default to
https://plane.aight.to and aight; fill them in for any other instance.
The token is validated before it is saved, then stored daemon-side in
$PASEO_HOME/plugins/plane-to-paseo/credentials.json with mode 0600. It never reaches the app,
the settings document, or the logs. PLANE_API_KEY (plus optional PLANE_URL and
PLANE_WORKSPACE) in the daemon's environment overrides the file.
README
A Paseo plugin for a self-hosted Plane workspace. Browse, filter, and search work items across every project, change their status and assignees, and hand one to a fresh Paseo worktree with the whole ticket (description, comments, links, images) as the agent's first message.
Ported from ChrisjanWust/linear-to-paseo (MIT). The UI shell is the same; the data layer is new and targets Plane's v1 REST API.
git clone git@github.com:g0rdonL/plane-to-paseo.git
cd plane-to-paseo
npm install # .npmrc sets legacy-peer-deps; npm 10.9 crashes without it
npm run typecheck
paseo plugin install "$PWD"
paseo plugin ls # plane-to-paseo should report "running"
Then in Plane, open Profile settings → Developer → API tokens
(https://<instance>/settings/profile/api-tokens/), create a token, and paste it in Paseo under
Settings → Plugins → Plane. Instance URL and workspace slug default to
https://plane.aight.to and aight; fill them in for any other instance.
The token is validated before it is saved, then stored daemon-side in
$PASEO_HOME/plugins/plane-to-paseo/credentials.json with mode 0600. It never reaches the app,
the settings document, or the logs. PLANE_API_KEY (plus optional PLANE_URL and
PLANE_WORKSPACE) in the daemon's environment overrides the file.
The hand-off form lists the chosen provider's modes and remembers the last one per provider. With nothing remembered it uses the provider's default (Auto for Claude). Bypass-style modes are marked because the prompt is ticket text: anyone who can edit or comment on a work item is writing instructions for an agent that will run without approval prompts.
npm run typecheck
npm test # unit tests against a local HTTP fake of Plane v1
npm run check # biome lint + format
paseo plugin reload plane-to-paseo
paseo plugin logs plane-to-paseo
Live smoke test, read-only, against a real instance. Read the token from the stored credentials so it never appears on screen:
PLANE_API_KEY="$(node -e 'console.log(JSON.parse(require("fs").readFileSync(process.env.HOME+"/.paseo/plugins/plane-to-paseo/credentials.json","utf8")).token)')" \
npx vitest run live
Layout follows Paseo's runtime boundaries: client/ runs in the app (React Native primitives
only), server/ runs in the daemon subprocess (credentials and every Plane call), shared/ holds
Zod contracts and pure functions.
advanced-search is Commercial
Edition only) and its list endpoint rejects filters, so the daemon lists each project's work
items (up to 500 each) and filters locally. Results are cached for 15 seconds; projects, states,
labels, and members for 5 minutes.<image-component src="<asset id>"> becomes the instance's asset API URL in the
Markdown. At download time the daemon trades it for a short-lived presigned URL and fetches the
bytes without the API key. At most 10 images, 8 MB each, 20 seconds total, sent to the agent as
attachments.failed. Check paseo plugin ls for the error and paseo plugin logs plane-to-paseo for output. Plugin RPC names must match ^[a-z][a-z0-9._-]*$; a camelCase
name stops the whole plugin from loading.[plane-to-paseo:app] …, including the chosen model, mode, and target, and any error
with its stack.expand=parent returns {} rather than null when there is no parent. Add the case to the
fake in server/plane/service.test.ts and widen the schema in server/plane/service.ts.Cycles and modules, estimates (Plane stores point ids), creating work items, real-time updates, and more than one workspace at a time.
MIT. See LICENSE.
Scanned 12 Oct 2026, 11:28 UTC from g0rdonL/plane-to-paseo.