#53

feat(plane): read Plane work item relations with issue-graph plane

Openamitav13wants to merge intofrom

Problem

issue-graph reads GitHub and Linear, but teams that track work in Plane can't map blockers, epics, and linked PRs before they start work.

Changes

  • issue-graph plane <PROJ-123|url|uuid> reads a work item neighborhood, and --project UUID|IDENTIFIER captures a whole project. Both use the existing work graph, Markdown and JSON output, dashboard, --cluster/--clusters, and --github.
  • Relations come from Plane's v1 relations endpoint, because the blocking and ordering types are only available there. blocking/blocked_by, start_before/start_after, and finish_before/finish_after each become one directed edge, with the same evidence ID from either side. duplicate and relates_to are undirected, and unknown types keep their native name.
  • The reader pages the workspace work item list (v2, 100 per page) before crawling. That list gives each item's project, parent, and state, so children, parents, and items in other projects resolve without extra requests, and each crawled item costs two requests (relations and links). Plane's v2 list ignores id and id__in filters, so items can't be fetched in batches by ID. When the workspace is larger than --max-pages, the reader falls back to per-item lookups and records that in the report's index coverage.
  • Plane Cloud allows 60 requests per minute per key. The REST reader keeps a client-side budget of 50 per minute (PLANE_REQUESTS_PER_MINUTE), honors Retry-After on 429, and prints one note when it starts pacing.
  • Auth is PLANE_API_KEY sent in the X-API-Key header. Self-hosted Plane works through PLANE_API_URL and PLANE_WEB_URL, which must use https except on localhost. Only GET requests are sent.
  • Plane's cancelled state group is stored as canceled, so the dashboard's existing state colors apply.
  • resolveGithubAttachments now accepts any report with the fields it reads (GithubResolvableReport), so Plane reports can use it. Linear behavior is unchanged.
  • New export issue-graph/transport/plane. Docs page /docs/plane, plus README, bundled skill, schema, and an Unreleased changelog section above the release markers.

Not included: browser login (Plane OAuth needs a registered app), Plane's v2-only implements relations, and text mentions.

Visual proof

Fixture output:

$ issue-graph plane ENG-12 --depth 0
# Plane graph · fixture / Engine

Coverage: complete within requested scope · 1 nodes · depth 0

## ENG-12 · Mount the engine behind the staff check

Status: In Progress

https://app.plane.so/fixture/browse/ENG-12/

- ← parent: ENG-10
- ← blocks: ENG-11
- → blocks: ENG-13
- → finishes before: ENG-13
- Link: feat: mount the engine · https://github.com/acme/app/pull/412

Live test against a private Plane Cloud workspace of 170 work items:

  • One neighborhood at depth 1 read 8 items in 5.5 s.

  • A project capture of 80 of 155 items took 193 s at the default budget, with no failed or partial reads. It found 168 blocks, 57 parent, and 3 relates_to edges, plus 19 links. The open count (98) matched Plane's own filtered total.

  • Help, README, docs, and the bundled skill agree

  • Generated content was refreshed from its source

  • Packaging changes were checked against the installed archive (pnpm test:package)

  • A release PR changes the package.json version and the matching CHANGELOG.md notes (not a release PR)

Checks: pnpm lint, pnpm typecheck, pnpm test (956 passed, 58 new), pnpm build, pnpm check:docs, pnpm test:package.

🤖 Generated with Claude Code

Activity

10
vercel[bot]4d ago

@amitav13 is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot]reviewed4d ago
amitav13reviewed4d ago
amitav13reviewed4d ago
vercel[bot]reviewed4d ago
amitav13reviewed4d ago