{"id":"plane-to-paseo","repo":"g0rdonL/plane-to-paseo","url":"https://github.com/g0rdonL/plane-to-paseo","package":"@aightto/plane-to-paseo","npm":{"package":"@aightto/plane-to-paseo","version":"0.1.1","integrity":"sha512-DR7uc6tFrr6vi06HRfW+/J2yGr24ElYCyqjJFSCF/A2eYDIrIHk0sg+r8ujspZsL8Ow+pvnP5RRTWwiWCSO+5A==","publishedAt":"2026-10-06T04:12:12.499Z","downloadsLast30Days":199},"name":"plane-to-paseo","description":"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.","categories":["productivity"],"platforms":[],"caveats":["Requires a self-hosted Plane instance (v1 API) and a personal access token","Optional write-back on hand-off changes the work item's state and assignees and posts a comment"],"images":[],"themes":[],"health":{"manifestValid":true,"hasReadme":true,"hasLicense":true,"hasTests":true,"hasTypecheckScript":true,"updatedRecently":true},"scannedAt":"2026-10-12T11:28:43.714Z","addedAt":"2026-10-12T16:25:02+05:00","npmSecurity":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-10-12T11:28:14.457Z","version":"0.1.1","integrity":"sha512-DR7uc6tFrr6vi06HRfW+/J2yGr24ElYCyqjJFSCF/A2eYDIrIHk0sg+r8ujspZsL8Ow+pvnP5RRTWwiWCSO+5A=="},"version":"0.1.1","security":{"status":"passed","blockingFindings":0,"advisoryFindings":0,"scannedAt":"2026-10-12T11:28:14.457Z","commit":"5ea774fed27bfbb991c1a955019e70bead49080f"},"license":"MIT","paseoVersionRequirement":">=0.10.3","descriptionNodes":[{"type":"text","text":"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."}],"caveatNodes":[[{"type":"text","text":"Requires a self-hosted Plane instance (v1 API) and a personal access token"}],[{"type":"text","text":"Optional write-back on hand-off changes the work item's state and assignees and posts a comment"}]],"manifest":{"id":"plane-to-paseo","requirements":{"paseo":">=0.10.3"}},"repoMeta":{"stars":0,"defaultBranch":"main","pushedAt":"2026-10-05T12:57:18Z"},"owner":{"login":"g0rdonL","avatarUrl":"https://avatars.githubusercontent.com/u/22794866?v=4"},"installNotesHtml":"<pre><code class=\"language-bash\">git clone git@github.com:g0rdonL/plane-to-paseo.git\ncd plane-to-paseo\nnpm install            # .npmrc sets legacy-peer-deps; npm 10.9 crashes without it\nnpm run typecheck\npaseo plugin install \"$PWD\"\npaseo plugin ls        # plane-to-paseo should report \"running\"\n</code></pre>\n<p>Then in Plane, open <strong>Profile settings → Developer → API tokens</strong>\n(<code>https://&#x3C;instance>/settings/profile/api-tokens/</code>), create a token, and paste it in Paseo under\n<strong>Settings → Plugins → Plane</strong>. Instance URL and workspace slug default to\n<code>https://plane.aight.to</code> and <code>aight</code>; fill them in for any other instance.</p>\n<p>The token is validated before it is saved, then stored daemon-side in\n<code>$PASEO_HOME/plugins/plane-to-paseo/credentials.json</code> with mode <code>0600</code>. It never reaches the app,\nthe settings document, or the logs. <code>PLANE_API_KEY</code> (plus optional <code>PLANE_URL</code> and\n<code>PLANE_WORKSPACE</code>) in the daemon's environment overrides the file.</p>","readmeText":"# plane-to-paseo\n\nA [Paseo](https://paseo.sh) plugin for a self-hosted [Plane](https://plane.so) workspace. Browse,\nfilter, and search work items across every project, change their status and assignees, and hand\none to a fresh Paseo worktree with the whole ticket (description, comments, links, images) as the\nagent's first message.\n\nPorted from [ChrisjanWust/linear-to-paseo](https://github.com/ChrisjanWust/linear-to-paseo) (MIT).\nThe UI shell is the same; the data layer is new and targets Plane's v1 REST API.\n\n## Features\n\n- **Browser**: work items from every active project, newest first. Filter by project, state,\n  assignee (mine / unassigned / specific people), priority, and label; filters combine with AND.\n  Local search covers identifier, title, labels, and description; a full-text fallback asks Plane.\n- **Detail**: description and comments converted from Plane's HTML to Markdown, parent, links,\n  file attachments, and inline images.\n- **Edit in place**: tap the status chip to move a work item to another state in its project; tap\n  **Edit** beside the assignees to pick from the project's members.\n- **Hand-off**: create a worktree workspace (or use an existing one), choose the model and agent\n  mode, edit the prompt, and start. Optional write-back moves the item to the project's first\n  \"started\" state, adds you as an assignee, and posts a comment linking the agent.\n- **Composer attachment**: attach a Plane work item to any message.\n\n## Requirements\n\n- Paseo daemon and app **0.10.3** or newer, with plugins enabled.\n- A Plane instance with the v1 API (tested against Plane Community Edition v1.4.2).\n- A Plane personal access token for a member of the workspace.\n\n## Install\n\n```bash\ngit clone git@github.com:g0rdonL/plane-to-paseo.git\ncd plane-to-paseo\nnpm install            # .npmrc sets legacy-peer-deps; npm 10.9 crashes without it\nnpm run typecheck\npaseo plugin install \"$PWD\"\npaseo plugin ls        # plane-to-paseo should report \"running\"\n```\n\nThen in Plane, open **Profile settings → Developer → API tokens**\n(`https://<instance>/settings/profile/api-tokens/`), create a token, and paste it in Paseo under\n**Settings → Plugins → Plane**. Instance URL and workspace slug default to\n`https://plane.aight.to` and `aight`; fill them in for any other instance.\n\nThe token is validated before it is saved, then stored daemon-side in\n`$PASEO_HOME/plugins/plane-to-paseo/credentials.json` with mode `0600`. It never reaches the app,\nthe settings document, or the logs. `PLANE_API_KEY` (plus optional `PLANE_URL` and\n`PLANE_WORKSPACE`) in the daemon's environment overrides the file.\n\n## Agent mode\n\nThe hand-off form lists the chosen provider's modes and remembers the last one per provider. With\nnothing remembered it uses the provider's default (Auto for Claude). Bypass-style modes are marked\nbecause the prompt is ticket text: anyone who can edit or comment on a work item is writing\ninstructions for an agent that will run without approval prompts.\n\n## Development\n\n```bash\nnpm run typecheck\nnpm test               # unit tests against a local HTTP fake of Plane v1\nnpm run check          # biome lint + format\npaseo plugin reload plane-to-paseo\npaseo plugin logs plane-to-paseo\n```\n\nLive smoke test, read-only, against a real instance. Read the token from the stored credentials\nso it never appears on screen:\n\n```bash\nPLANE_API_KEY=\"$(node -e 'console.log(JSON.parse(require(\"fs\").readFileSync(process.env.HOME+\"/.paseo/plugins/plane-to-paseo/credentials.json\",\"utf8\")).token)')\" \\\n  npx vitest run live\n```\n\nLayout follows Paseo's runtime boundaries: `client/` runs in the app (React Native primitives\nonly), `server/` runs in the daemon subprocess (credentials and every Plane call), `shared/` holds\nZod contracts and pure functions.\n\n## How it talks to Plane\n\n- **Fan-out listing.** Plane CE has no cross-project query (`advanced-search` is Commercial\n  Edition only) and its list endpoint rejects filters, so the daemon lists each project's work\n  items (up to 500 each) and filters locally. Results are cached for 15 seconds; projects, states,\n  labels, and members for 5 minutes.\n- **Images.** `<image-component src=\"<asset id>\">` becomes the instance's asset API URL in the\n  Markdown. At download time the daemon trades it for a short-lived presigned URL and fetches the\n  bytes without the API key. At most 10 images, 8 MB each, 20 seconds total, sent to the agent as\n  attachments.\n- **Write-back.** Never pulls an item that is already started or done back to \"started\"; adds the\n  viewer to existing assignees instead of replacing them.\n\n## Troubleshooting\n\n- **Plugin shows `failed`.** Check `paseo plugin ls` for the error and `paseo plugin logs\n  plane-to-paseo` for output. Plugin RPC names must match `^[a-z][a-z0-9._-]*$`; a camelCase\n  name stops the whole plugin from loading.\n- **A button seems to do nothing.** App-side steps of the hand-off are mirrored into the plugin\n  log as `[plane-to-paseo:app] …`, including the chosen model, mode, and target, and any error\n  with its stack.\n- **\"Plane returned a non-JSON response\".** The instance URL points at Plane's web app or a\n  proxy page rather than the API host.\n- **Detail fails schema validation.** Plane's serializers have quirks; for example\n  `expand=parent` returns `{}` rather than `null` when there is no parent. Add the case to the\n  fake in `server/plane/service.test.ts` and widen the schema in `server/plane/service.ts`.\n- **Agent started in \"Always Ask\".** Choose the mode in the hand-off form; it is remembered per\n  provider.\n\n## Not yet supported\n\nCycles and modules, estimates (Plane stores point ids), creating work items, real-time updates,\nand more than one workspace at a time.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n"}