Skip to content

[SILO-1466] feat: api_v2 support via client.v2 (406 operations) - #70

Open
Prashant-Surya wants to merge 2 commits into
mainfrom
feat/silo-1466-python-sdk-v2
Open

[SILO-1466] feat: api_v2 support via client.v2 (406 operations)#70
Prashant-Surya wants to merge 2 commits into
mainfrom
feat/silo-1466-python-sdk-v2

Conversation

@Prashant-Surya

Copy link
Copy Markdown
Member

Description

Adds the complete Plane api_v2 surface to the Python SDK — 406 operations across 120 resource groups — as a single chained form rooted at the workspace, mirroring the API's own scope tree. v1 is untouched (every existing symbol resolves to the same v1 module).

ws = client.v2.workspace("acme")                     # zero-I/O locator
proj = ws.project("ENG")                             # project key or UUID
proj.work_items.create(CreateWorkItem(name="Fix login bug", state="Todo", labels=["bug"]))
proj.work_items.comments.list(work_item_id)
ws.work_items.retrieve_by_identifier("ENG-12")       # readable key, no project needed
ws.wiki.pages.create(CreatePage(name="Runbook"))     # public page -> default collection
client.v2.users.me()                                 # the six non-workspace operations
  • Kernel (plane/api/v2/_kernel/): transport with RFC 9457 problem+json errors, offset/cursor pagination with a stall guard, ?fields / ?expand / ?order_by validated per operation against the OpenAPI golden, upsert, bulk create/update/delete with per-row results, find_by_name, custom verb actions, scope-bound resources.
  • Generated constants (scripts/generate_v2_constants.py) for all 406 operations; every implemented operation is declared in exactly one resource's operations map and a two-way coverage test enforces 406/406.
  • Request models follow v1's convention: Create<Resource> / Update<Resource>; models live in plane.models.v2.
  • Method set is identical to @makeplane/plane-node-sdk (snake_case vs camelCase).
  • Version bumped to 0.3.0; README gains an "API v2" section.

Type of Change

  • Feature (non-breaking change which adds functionality)

Test Scenarios

  • Offline: pytest tests/v2 --ignore=tests/v2/integration — 421 tests against responses mocks asserting verb, exact URL, query, and body; error paths, stall guard, field/expand rejection, bulk cap, find-by-name ambiguity, two-way operation coverage.
  • Live: tests/v2/integration skips without PLANE_BASE_URL / PLANE_API_KEY / WORKSPACE_SLUG; against a plane-dev instance: 362 passed, 23 skipped (feature-mode conflicts), 0 failed — includes an end-to-end scenario (test_full_scenario.py) and the two work-item-type flows ported from plane-ee.
  • ruff clean on the v2 tree; mypy unchanged from main (56 pre-existing v1 findings, 0 in v2).
  • CI: new test.yml runs the offline suite; a secret-gated v2-golden-drift job regenerates the constants against plane-ee's golden.

Follow-ups (not in this PR)

  • The v1 tree still carries 28 pre-existing ruff findings and is not lint-gated by the new workflow.
  • Spec items raised on plane-ee in SILO-1464: page delete requires archive first (undocumented), collection delete orphans pages, pages_* operationIds sit on /collections/.

References

  • SILO-1466
  • Companion: plane-node-sdk [SILO-1463], plane-ee [SILO-1464] (the live suite depends on that permission fix for users/me, permissions/me, worklogs/summary).

🤖 Generated with Claude Code

https://claude.ai/code/session_015XXZ9CT96T1dZoiSYmtiNe

…operations

`client.v2` exposes every api_v2 operation through a single chained form rooted at
the workspace, mirroring the API's own scope tree:

    ws = client.v2.workspace("acme")          # zero-I/O locator
    proj = ws.project("ENG")                  # key or UUID
    proj.work_items.create(WorkItemWrite(name="Fix login bug", state="Todo"))
    ws.work_items.retrieve_by_identifier("ENG-12")
    ws.wiki.pages.create(PageWrite(name="Runbook"))   # public page -> default collection
    client.v2.users.me()                      # the six non-workspace operations

- Kernel: transport with RFC 9457 errors, offset/cursor envelopes with a stall
  guard, ?fields/?expand/?order_by validated per operation against the golden,
  upsert, bulk create/update/delete with per-row results, find_by_name, custom
  verb actions, scope-bound resources (`V2Resource(transport, **scope)`).
- Spec-generated constants (`scripts/generate_v2_constants.py`) for all 406
  operations; every implemented operation is declared in exactly one resource's
  `operations` map and a two-way coverage test enforces 406/406.
- Method set is identical to @makeplane/plane-node-sdk (snake_case vs camelCase).
- Offline tests under tests/v2 (responses); live tests under tests/v2/integration
  skip without PLANE_BASE_URL/PLANE_API_KEY/WORKSPACE_SLUG.
- CI: .github/workflows/test.yml runs the offline suite; a secret-gated
  `v2-golden-drift` job regenerates the constants against plane-ee's golden.
- Version 0.3.0. v1 surface untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XXZ9CT96T1dZoiSYmtiNe
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 249 files, which is 149 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: eaf2432e-af50-42db-9857-ef595a954633

📥 Commits

Reviewing files that changed from the base of the PR and between 31a4f9e and a57823e.

⛔ Files ignored due to path filters (2)
  • plane/api/v2/_generated/__init__.py is excluded by !**/_generated/**
  • plane/api/v2/_generated/constants.py is excluded by !**/_generated/**
📒 Files selected for processing (249)
  • .github/workflows/test.yml
  • CLAUDE.md
  • README.md
  • plane/__init__.py
  • plane/api/v2/__init__.py
  • plane/api/v2/_kernel/__init__.py
  • plane/api/v2/_kernel/errors.py
  • plane/api/v2/_kernel/pagination.py
  • plane/api/v2/_kernel/resource.py
  • plane/api/v2/_kernel/transport.py
  • plane/api/v2/artifacts.py
  • plane/api/v2/assets.py
  • plane/api/v2/audit_logs.py
  • plane/api/v2/automations/__init__.py
  • plane/api/v2/automations/activities.py
  • plane/api/v2/automations/edges.py
  • plane/api/v2/automations/nodes.py
  • plane/api/v2/collections/__init__.py
  • plane/api/v2/collections/members.py
  • plane/api/v2/collections/pages.py
  • plane/api/v2/customer_properties.py
  • plane/api/v2/customers/__init__.py
  • plane/api/v2/customers/customers.py
  • plane/api/v2/customers/property_values.py
  • plane/api/v2/customers/requests.py
  • plane/api/v2/customers/work_items.py
  • plane/api/v2/cycles.py
  • plane/api/v2/estimates/__init__.py
  • plane/api/v2/estimates/points.py
  • plane/api/v2/features.py
  • plane/api/v2/group_sync/__init__.py
  • plane/api/v2/group_sync/config.py
  • plane/api/v2/group_sync/project_mappings.py
  • plane/api/v2/group_sync/workspace_mappings.py
  • plane/api/v2/initiatives/__init__.py
  • plane/api/v2/initiatives/initiatives.py
  • plane/api/v2/initiatives/labels.py
  • plane/api/v2/initiatives/projects.py
  • plane/api/v2/initiatives/work_items.py
  • plane/api/v2/intakes.py
  • plane/api/v2/invitations.py
  • plane/api/v2/labels.py
  • plane/api/v2/members.py
  • plane/api/v2/milestones.py
  • plane/api/v2/modules.py
  • plane/api/v2/pages.py
  • plane/api/v2/permission_schemes.py
  • plane/api/v2/permissions.py
  • plane/api/v2/project.py
  • plane/api/v2/projects.py
  • plane/api/v2/releases/__init__.py
  • plane/api/v2/releases/changelog.py
  • plane/api/v2/releases/comments.py
  • plane/api/v2/releases/labels.py
  • plane/api/v2/releases/links.py
  • plane/api/v2/releases/tags.py
  • plane/api/v2/releases/work_items.py
  • plane/api/v2/roles.py
  • plane/api/v2/states.py
  • plane/api/v2/stickies.py
  • plane/api/v2/teamspaces.py
  • plane/api/v2/users.py
  • plane/api/v2/views/__init__.py
  • plane/api/v2/views/project.py
  • plane/api/v2/views/workspace.py
  • plane/api/v2/webhook_logs.py
  • plane/api/v2/webhooks.py
  • plane/api/v2/wiki.py
  • plane/api/v2/work_item_properties/__init__.py
  • plane/api/v2/work_item_properties/contexts.py
  • plane/api/v2/work_item_properties/options.py
  • plane/api/v2/work_item_properties/workspace_options.py
  • plane/api/v2/work_item_relation_definitions.py
  • plane/api/v2/work_item_templates/__init__.py
  • plane/api/v2/work_item_templates/project.py
  • plane/api/v2/work_item_templates/workspace.py
  • plane/api/v2/work_item_types/__init__.py
  • plane/api/v2/work_item_types/properties.py
  • plane/api/v2/work_items/__init__.py
  • plane/api/v2/work_items/activities.py
  • plane/api/v2/work_items/attachments.py
  • plane/api/v2/work_items/comments.py
  • plane/api/v2/work_items/dependencies.py
  • plane/api/v2/work_items/links.py
  • plane/api/v2/work_items/relations.py
  • plane/api/v2/work_items/worklogs.py
  • plane/api/v2/work_items/workspace.py
  • plane/api/v2/workflows/__init__.py
  • plane/api/v2/workflows/states.py
  • plane/api/v2/workflows/transitions.py
  • plane/api/v2/workflows/workflows.py
  • plane/api/v2/worklogs.py
  • plane/api/v2/workspace.py
  • plane/client/plane_client.py
  • plane/config.py
  • plane/models/v2/__init__.py
  • plane/models/v2/artifacts.py
  • plane/models/v2/assets.py
  • plane/models/v2/audit_logs.py
  • plane/models/v2/automations.py
  • plane/models/v2/collections.py
  • plane/models/v2/common.py
  • plane/models/v2/customer_properties.py
  • plane/models/v2/customers.py
  • plane/models/v2/cycle_actions.py
  • plane/models/v2/cycles.py
  • plane/models/v2/estimates.py
  • plane/models/v2/features.py
  • plane/models/v2/group_sync.py
  • plane/models/v2/initiatives.py
  • plane/models/v2/intakes.py
  • plane/models/v2/invitations.py
  • plane/models/v2/labels.py
  • plane/models/v2/members.py
  • plane/models/v2/milestone_work_items.py
  • plane/models/v2/milestones.py
  • plane/models/v2/module_work_items.py
  • plane/models/v2/modules.py
  • plane/models/v2/pages.py
  • plane/models/v2/permission_schemes.py
  • plane/models/v2/permissions.py
  • plane/models/v2/project_role_distribution.py
  • plane/models/v2/projects.py
  • plane/models/v2/releases.py
  • plane/models/v2/roles.py
  • plane/models/v2/states.py
  • plane/models/v2/stickies.py
  • plane/models/v2/teamspaces.py
  • plane/models/v2/users.py
  • plane/models/v2/views.py
  • plane/models/v2/webhook_logs.py
  • plane/models/v2/webhooks.py
  • plane/models/v2/work_item_properties.py
  • plane/models/v2/work_item_relation_definitions.py
  • plane/models/v2/work_item_templates.py
  • plane/models/v2/work_item_types.py
  • plane/models/v2/work_items.py
  • plane/models/v2/workflows.py
  • plane/models/v2/worklogs_summary.py
  • pyproject.toml
  • scripts/generate_v2_constants.py
  • tests/v2/__init__.py
  • tests/v2/conftest.py
  • tests/v2/fixtures/__init__.py
  • tests/v2/fixtures/_hidden/__init__.py
  • tests/v2/fixtures/_hidden/resource.py
  • tests/v2/fixtures/nested/__init__.py
  • tests/v2/fixtures/nested/deep/__init__.py
  • tests/v2/fixtures/nested/deep/resource.py
  • tests/v2/integration/__init__.py
  • tests/v2/integration/conftest.py
  • tests/v2/integration/helpers.py
  • tests/v2/integration/test_artifacts.py
  • tests/v2/integration/test_assets.py
  • tests/v2/integration/test_audit_logs.py
  • tests/v2/integration/test_automations.py
  • tests/v2/integration/test_bulk.py
  • tests/v2/integration/test_collections.py
  • tests/v2/integration/test_crud.py
  • tests/v2/integration/test_customer_properties.py
  • tests/v2/integration/test_customers.py
  • tests/v2/integration/test_cycle_actions.py
  • tests/v2/integration/test_errors.py
  • tests/v2/integration/test_estimates.py
  • tests/v2/integration/test_features.py
  • tests/v2/integration/test_find_one.py
  • tests/v2/integration/test_full_scenario.py
  • tests/v2/integration/test_group_sync.py
  • tests/v2/integration/test_initiatives.py
  • tests/v2/integration/test_intakes.py
  • tests/v2/integration/test_invitations.py
  • tests/v2/integration/test_members.py
  • tests/v2/integration/test_milestone_work_items.py
  • tests/v2/integration/test_module_work_items.py
  • tests/v2/integration/test_pages.py
  • tests/v2/integration/test_pagination.py
  • tests/v2/integration/test_permission_schemes.py
  • tests/v2/integration/test_permissions.py
  • tests/v2/integration/test_project_work_item_types_flow.py
  • tests/v2/integration/test_projects.py
  • tests/v2/integration/test_releases.py
  • tests/v2/integration/test_roles.py
  • tests/v2/integration/test_scope_parity.py
  • tests/v2/integration/test_stickies.py
  • tests/v2/integration/test_teamspaces.py
  • tests/v2/integration/test_upsert.py
  • tests/v2/integration/test_users.py
  • tests/v2/integration/test_views.py
  • tests/v2/integration/test_webhook_logs.py
  • tests/v2/integration/test_webhooks.py
  • tests/v2/integration/test_work_item_properties.py
  • tests/v2/integration/test_work_item_relation_definitions.py
  • tests/v2/integration/test_work_item_sub_resources.py
  • tests/v2/integration/test_work_item_templates.py
  • tests/v2/integration/test_work_item_types.py
  • tests/v2/integration/test_work_items.py
  • tests/v2/integration/test_workflows.py
  • tests/v2/integration/test_worklogs_summary.py
  • tests/v2/integration/test_workspace_work_item_types_flow.py
  • tests/v2/integration/test_workspace_work_items.py
  • tests/v2/test_artifacts_resource.py
  • tests/v2/test_assets_resource.py
  • tests/v2/test_audit_logs_resource.py
  • tests/v2/test_automations_resource.py
  • tests/v2/test_bulk.py
  • tests/v2/test_collections_resource.py
  • tests/v2/test_customer_properties_resource.py
  • tests/v2/test_customers_resource.py
  • tests/v2/test_cycles_resource.py
  • tests/v2/test_errors.py
  • tests/v2/test_estimates_resource.py
  • tests/v2/test_features_resource.py
  • tests/v2/test_find_one.py
  • tests/v2/test_generated_constants.py
  • tests/v2/test_group_sync_resource.py
  • tests/v2/test_initiatives_resource.py
  • tests/v2/test_intakes_resource.py
  • tests/v2/test_invitations_resource.py
  • tests/v2/test_labels_resource.py
  • tests/v2/test_live_smoke.py
  • tests/v2/test_locators.py
  • tests/v2/test_members_resource.py
  • tests/v2/test_milestones_resource.py
  • tests/v2/test_modules_resource.py
  • tests/v2/test_operations_coverage.py
  • tests/v2/test_pages_resource.py
  • tests/v2/test_pagination.py
  • tests/v2/test_permission_schemes_resource.py
  • tests/v2/test_permissions_resource.py
  • tests/v2/test_projects_resource.py
  • tests/v2/test_releases_resource.py
  • tests/v2/test_resource.py
  • tests/v2/test_roles_resource.py
  • tests/v2/test_states_resource.py
  • tests/v2/test_stickies_resource.py
  • tests/v2/test_teamspaces_resource.py
  • tests/v2/test_transport.py
  • tests/v2/test_users_resource.py
  • tests/v2/test_views_resource.py
  • tests/v2/test_webhook_logs_resource.py
  • tests/v2/test_webhooks_resource.py
  • tests/v2/test_work_item_properties_resource.py
  • tests/v2/test_work_item_relation_definitions_resource.py
  • tests/v2/test_work_item_templates_resource.py
  • tests/v2/test_work_item_types_resource.py
  • tests/v2/test_work_items_resource.py
  • tests/v2/test_workflows_resource.py
  • tests/v2/test_worklogs_summary_resource.py
  • tests/v2/test_workspace_work_items_resource.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@makeplane

makeplane Bot commented Aug 30, 2026

Copy link
Copy Markdown

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

…ookups (review feedback)

Review feedback on the v2 surface (runs/sdk-v2-foundation/plans/2026-09-03-team-feedback.md,
items 1, 2 and the SDK-now part of 5).

Renames (work item type properties, project + workspace scoped):
- work_item_types.properties.attach(type_id, property_ids) -> link(type_id, property_ids)
- work_item_types.properties.detach(type_id, property_id)  -> unlink(type_id, property_id)
  (operations keys stay attach/detach; unlink docstring carries the web app warning)

Removed (manage verbs) -> replaced by bridge sub-resources with add/remove:
- cycles.manage_work_items        -> cycles.work_items.add/remove
- modules.manage_work_items       -> modules.work_items.add/remove
- milestones.manage_work_items    -> milestones.work_items.add/remove
- customers.manage_work_items     -> customers.work_items.add/remove
- releases.manage_work_items      -> releases.work_items.add/remove
- releases.manage_labels          -> releases.labels.add/remove
- initiatives.manage_work_items   -> initiatives.work_items.add/remove
- initiatives.manage_projects     -> initiatives.projects.add/remove
- initiatives.manage_labels       -> initiatives.labels.add/remove
- wiki.collections.members.manage -> wiki.collections.members.add/remove
- wiki.collections.pages.manage   -> wiki.collections.pages.add/remove
  add POSTs {"add": [...]} and returns `added`; remove POSTs {"remove": [...]} and
  returns `removed`; 0 or >100 ids raise ValueError before any request. One kernel
  helper, V2Resource._bridge(key=, ids=, **path_params), plus `bridge_path` for
  catalog resources whose own path is not the bridge URL. Each golden manage
  operationId moves to its bridge class (406/406 still declared exactly once).
  *Manage* request/response models stay as files but are no longer exported from
  plane.models.v2 (CollectionMemberAdd stays public).

Added lookups (server-side via _find_one, golden filters verified):
- roles.find_by_slug(slug, *, namespace=None)
- estimates.points.find_by_key(estimate_id, key)
- work_item_properties.find_by_name(name) and workspace sibling (name = property key)
- work_item_properties.options.find_by_name(property_id, name), workspace sibling,
  and workspace work_item_properties.contexts.find_by_name(property_id, name)

Tests: offline coverage for every new/renamed method incl. the 0/101-id guard and
exact JSON body per verb; all call sites converted, integration suite still
all-skip without env. README + CLAUDE.md v2 sections updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QwQ1tqb3831E7rezg5zqs
@Prashant-Surya

Copy link
Copy Markdown
Member Author

Review feedback landed as one commit on top (a57823e), so the delta is reviewable on its own. Public method tree stays identical to the Node SDK (513 = 513 after normalisation).

Feedback What changed
attach/detachlink/unlink (work item type properties, matches the web app's "Unlink property") work_item_types.properties.link(type_id, ids) / .unlink(type_id, id) in both scopes
manage_work_itemsx.y.work_items.add / remove Every manage_* is gone. Bridges are sub-resources: proj.cycles.work_items.add(cycle_id, ids) / .remove(...), same for modules, milestones, customers, releases, initiatives (.work_items, .projects), ws.releases.labels.add(release_id, ids), ws.initiatives.labels.add(...), ws.wiki.collections.pages.add(...), .members.add(...). Each verb sends only its own key; 0 or >100 ids raise ValueError before any request; returns the ids actually changed.
Lookup by slug / name ws.roles.find_by_slug(slug, namespace=...), proj.estimates.points.find_by_key(estimate_id, key), find_by_name on work item properties (both scopes), property options and contexts. name on properties is the machine key (story-points); lookup by the UI label needs a ?display_name= filter, which is on a plane-ee branch pending spec review, and find_by_display_name will follow it.
archive_then_delete Parked. Only pages gate delete on archive, and that reads as an app defect to fix server-side rather than mirror here.
find_by_name + state group Skipped: state names are unique per project/workspace under governance.
Workspace by slug No workspace endpoint exists in v1 or v2 today; GET /api/v2/workspaces/{slug}/ (+ list) is on a plane-ee branch pending spec review, then ws.retrieve() lands here.
Batching chained calls On hold. Chaining is zero-I/O (only the leaf call hits the network); there is no multi-op batch endpoint, and the per-resource bulk_* methods are the batching primitive.

Checks on the new commit: pytest tests/v2 453 passed / 393 skipped, operations coverage 406/406, ruff clean, mypy clean on v2 files. Live suite not re-run (dev API was stopped).

@coldtea-pr-lens

coldtea-pr-lens Bot commented Sep 3, 2026

Copy link
Copy Markdown

◈ PR Lens

🟢 +13 new · 🟠 ~1 changed · 🔴 -0 removed · 3 flows · 41 files · commit a57823e


Architecture

Architecture diagram for makeplane/plane-python-sdk at a57823e

14 components touched across 5 lanes.

Open full size


Inside the changed components — 3 views

Component view — V2 Kernel, Transport & Engine

The core engine powering api_v2:⁠ V2Transport with session retry and RFC 9457 error decoding, generic V2Resource CRUD and bridge handler, pagination discrimination, and OpenAPI golden constants validation.

Architecture view of Component view — V2 Kernel, Transport & Engine in makeplane/plane-python-sdk

Component view — Zero-I/O Locators & Scoping Hierarchy

Zero-network-I/O locator chaining (client.v2.workspace(slug).project(id)) that binds path parameters in memory and exposes domain resources without making API calls.

Architecture view of Component view — Zero-I/O Locators & Scoping Hierarchy in makeplane/plane-python-sdk

Component view — V2 Domain Resources & Membership Bridges

The v2 domain resource suites for work items, planning, governance, and CRM/automations connecting to the V2Resource kernel for CRUD, bulk writes, and 100-item capped membership bridging.

Architecture view of Component view — V2 Domain Resources & Membership Bridges in makeplane/plane-python-sdk

Data flow

Data flow diagram for makeplane/plane-python-sdk at a57823e

Scoped locator query with pagination · Batch creation with partial failure tracking · Membership bridging with batch limit validation

Open full size


The other flows — 2 sequences

Batch creation with partial failure tracking

Sequence diagram of Batch creation with partial failure tracking in makeplane/plane-python-sdk

Membership bridging with batch limit validation

Sequence diagram of Membership bridging with batch limit validation in makeplane/plane-python-sdk

Drill down
SDK Client & Core — 7 components
🟡 CHANGED PlaneClient

Main SDK entry point that initializes the shared configuration, v1 resource APIs, and the new v2 namespace at client.v2.

🟢 NEW V2 Namespace

Top-level entry point for API v2, holding non-workspace resources and the zero-I/O workspace locator method.

🟢 NEW V2 Transport

Shared HTTP transport managing /api/v2 prefixing, auth headers, urllib3 retries, and RFC 9457 problem+json error decoding into PlaneAPIError.

🟢 NEW V2 Resource Kernel

Generic CRUD base class handling URL path interpolation, query param validation, bulk writes, and 100-item capped membership bridging.

🟢 NEW V2 Pagination Engine

Discriminates offset vs cursor response styles and provides stalled-loop-guarded pagination generators.

🟢 NEW V2 Generated Constants

OpenAPI golden lookup tables specifying operation IDs, allowed fields, expandable relations, order-by keys, and bulk limits.

🟢 NEW V2 Pydantic Models

Typed request, response, pagination, and bulk write result models where sparse read fields default to optional.

Workspaces & Projects — 2 components
🟢 NEW Workspace Locator

Zero-I/O locator binding a workspace slug in memory and exposing all workspace-level resources plus project locators.

🟢 NEW Project Locator

Zero-I/O locator binding workspace slug and project ID or key in memory, exposing project-level sub-resources.

Work Items & Planning — 2 components
🟢 NEW V2 Work Items API

Project and workspace work item CRUD with nested sub-resources for comments, attachments, relations, dependencies, links, activities, and worklogs.

🟢 NEW V2 Planning API

Cycles, modules, milestones, intakes, and estimates resources with membership bridges to link and unlink work items.

Workflows & Governance — 1 component
🟢 NEW V2 Governance & Workflows API

States, workflows, work item types, custom properties, relation definitions, roles, and permissions resources.

CRM, Content & Automation — 2 components
🟢 NEW Wiki Locator

Sub-locator under workspace binding pages and collections without performing network requests.

🟢 NEW V2 CRM, Content & Automations API

Wiki pages, collections, customers, releases, initiatives, webhooks, audit logs, and project/workspace automations.


View

  • Architecture lens
  • Data flow lens
  • Expand every detail
  • Show unchanged neighbours

Tip

Push a new commit and the whole comment re-renders for the new head. An older run never overwrites a newer one, so a slow render cannot put a stale diagram back.

🪧 More tips
  • Run PR Lens on your own machine: npx skills add coldteadotai/pr-lens installs the agent skill. Then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Draw a diff before it is even a pull request: npx @coldtea/pr-lens-cli analyze --base origin/main reads the diff with your own model key, and npx @coldtea/pr-lens-cli render .pr-lens/graph.json draws the same lenses on your machine.
  • The boxes under View are live. Tick Architecture lens or Data flow lens to choose which diagrams appear, or Expand every detail to open every drill-down at once. The comment redraws in place a few seconds later.
  • Show unchanged neighbours lists the components this change did not touch alongside the ones it did, so the drill-down shows what the changed code sits next to.
  • GitHub will not let you zoom an image in a comment. The link under each diagram opens it full size on a page of its own, where you can.
  • The CLI's render picks up .github/pr-lens.yml automatically and applies your corrections (renames, exclusions, lane pins) at draw time.
  • Would you rather run it from CI on a key of your own? Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and a model key in your repository secrets, say GEMINI_API_KEY. The Action asks Gemini by default, or OpenAI and any endpoint speaking /chat/completions through its provider input.
  • PR Lens is free for open source. A star on the repository is what keeps it going.
  • The diagrams follow your GitHub theme, so dark mode gets the dark render and light mode the light one, and the moving dots show this pull request's data in motion.

◈ Rendered by PR Lens · crafted with ❤️ by the Coldtea team · Come say hi on Discord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant