@pugi/plugin-plane
v0.1.0-alpha.2
Published
Pugi Plane plugin - per-tenant Plane.so workspace provisioning, task and doc mirroring, and 60-issue-per-module cap enforcement.
Downloads
306
Maintainers
Readme
@pugi/plugin-plane
Per-tenant Plane.so integration for Pugi. Provisions a dedicated Plane workspace + project per customer, mirrors the local TaskList and Markdown docs into Plane, and enforces the 60-issue-per-module React error-boundary cap.
Part of the Pugi 1.0 soft fork sprint (see ADR-0081 and ADR-0073).
Install
pnpm add @pugi/plugin-planeUsage
// pugi.config.ts
export default {
plugin: [
[
'@pugi/plugin-plane',
{
planeBase: 'https://plane.pugi.io/api/v1',
// apiToken read from env PUGI_PLANE_TOKEN or OS keychain when omitted.
tenantId: 'acme-corp',
// workspaceSlug + projectId are provisioned on first `pugi.plane.init`
// and persisted between sessions.
maxIssuesPerModule: 60,
enableBidirectionalSync: false,
},
],
],
};Tools
| Tool | Purpose |
|---|---|
| pugi.plane.init | Idempotent workspace + project + labels + states provisioning. |
| pugi.plane.mirror | Push local .pugi/tasks.jsonl and configured doc paths to Plane. |
| pugi.plane.sync | Bi-directional reconcile (disabled by default - requires webhook receiver). |
| pugi.plane.status | Workspace + project + connection health + per-module issue counts. |
Hooks
tool.execute.after:
- When a
bashtool runsgh pr createsuccessfully, parses the PR URL from stdout, looks up the matching Plane issue by ID parsed from the command (or stdout), and posts a comment linking the PR. - When a
pugi.runtool finishes, walks the.pugi/runs/<runId>/tree and uploads each file as an attachment on the Plane issue withexternal_id = run:<runId>. Files larger thanattachmentMaxBytes(default 10 MiB) are skipped with a warning.
The original Day-21 spec asked for a
command.execute.beforehook ongh pr create. That hook fires before the command runs, so the PR URL is not available yet. We usetool.execute.afterinstead.
Tier matrix
| Feature | Min tier |
|---|---|
| plane.init | Founder ($20) |
| plane.mirror.issues | Founder ($20) |
| plane.mirror.pages | Builder ($99) |
| plane.sync | Team ($199) |
| plane.workspace.per-customer | Team ($199) |
Free tier blocks the plugin entirely; the local TaskList remains
available. Tier is resolved via Anvil /v1/me with a 1-hour disk cache.
Module cap rationale
Plane's React UI crashes the error boundary when a module exposes more
than 60 issues (engine-VM observation, 2026-05-30). The mirror flow
caps at 60 client-side and opens ${baseName}-2, ${baseName}-3, ...
sibling modules. This trades navigation depth for crash safety.
Token storage
Bearer tokens are never persisted plaintext:
- In-process options.apiToken (highest precedence).
PUGI_PLANE_TOKENenv.- OS keychain (macOS
security, Linuxsecret-tool). ~/.pugi/plane-token.enc(AES-256-GCM, HKDF key from hostname + UID + tenant).
Renaming the host machine invalidates the encrypted-file fallback and forces re-auth - intentional safe-degrade.
Constraints
- Per ADR-0081, this package MUST NOT import other
@pugi/plugin-*packages. The tier-gate and Plane REST client are vendored locally. - No runtime dependencies beyond
@pugi-ai/pluginandzod(peer). - Mock fetch in tests - the suite never reaches a live Plane server.
License
MIT. See LICENSE.
