Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
6023e8c
[WEB-6784] feat scrollbar in shortcuts modal (#8872)
b-saikrishnakanth Apr 9, 2026
e6b9d4c
[WEB-6785] fix: update border for project timezone (#8870)
b-saikrishnakanth Apr 9, 2026
c21d2c6
chore: remove Intercom integration and chat support components (#8875)
sriramveeraghanta Apr 9, 2026
39325d2
chore: update dependencies (Django, cryptography, axios, lodash) (#8880)
sriramveeraghanta Apr 9, 2026
db3c8f2
[WEB-6840] feat: skip role & use-case steps for self-hosted instances…
anmolsinghbhatia Apr 13, 2026
bbf14fb
chore(deps): bump pytest (#8891)
dependabot[bot] Apr 14, 2026
13db2f8
enhance sub-issue query performance with optimized annotations and su…
PhuongPN6689 Apr 14, 2026
ac11c3e
fix: enforce workspace membership on V2 asset endpoints (#8885)
sriramveeraghanta Apr 20, 2026
a8a16c8
fix: replace IS_SELF_MANAGED with WEBHOOK_ALLOWED_IPS allowlist (#8884)
sriramveeraghanta Apr 20, 2026
45b4fc8
[SILO-1158] chore: add context for project in relations API (#8860)
Saurabhkmr98 Apr 20, 2026
aea66f5
fix: sanitize filenames in upload paths to prevent path traversal (#8…
sriramveeraghanta Apr 20, 2026
da41f14
chore(ci): suppress CodeQL file coverage deprecation warning (#8916)
sriramveeraghanta Apr 20, 2026
62b2d1b
chore: update CODEOWNERS for apps and deployments (#8919)
sriramveeraghanta Apr 20, 2026
f1d567a
chore: add Claude Code skills for PR descriptions and release notes (…
sriramveeraghanta Apr 20, 2026
c62930e
chore: bump up the package version
sriramveeraghanta Apr 20, 2026
03a2be8
chore(deps): bump lxml (#8925)
dependabot[bot] Apr 22, 2026
32fb88a
chore(deps): bump axios, uuid and add security overrides (#8930)
sriramveeraghanta Apr 25, 2026
a40e064
chore(deps): bump postcss (#8931)
dependabot[bot] Apr 27, 2026
db1c5b9
fix: filter out soft-deleted states from API endpoints (#8840)
KanteshMurade Apr 28, 2026
a62fe8a
chore(deps): remove unused pnpm overrides (#8973)
sriramveeraghanta Apr 29, 2026
9491bdb
fix(api): scope cross-workspace resource lookups to prevent IDOR (#9008)
sriramveeraghanta May 4, 2026
ff21e53
fix(nginx): correct real_ip_header typo X-Forward-For → X-Forwarded-F…
MinitJain May 5, 2026
4c1bdd1
fix(api): use requester's workspace role for project member role upda…
sriramveeraghanta May 5, 2026
4225bc5
[GIT-175] fix: completed_at updation logic for work items (#9044)
sangeethailango May 12, 2026
761c999
fix: add WEBHOOK_ALLOWED_HOSTS allowlist for internal webhook targets…
sriramveeraghanta May 14, 2026
1dabc63
fix: pnpm path for Docker builds (#9079)
sriramveeraghanta May 14, 2026
7fd8e33
Merge branch 'canary' of github.com:makeplane/plane into preview
sriramveeraghanta May 14, 2026
65d6a94
refactor(i18n): migrate packages/i18n from MobX to react-i18next (#8898)
sriramveeraghanta May 14, 2026
50a7b47
fix(api): pass project_lead_id (not User instance) when creating Proj…
jamartineztelecoengineer84-dotcom May 14, 2026
208f359
[WEB-7181] fix: empty comment quick-actions menu in work item activit…
b-saikrishnakanth May 19, 2026
4ca6d6c
[WEB-7182] fix: remove profile preferences activity (#9025)
b-saikrishnakanth May 19, 2026
039d582
fix(aio): use JSON array double quotes in VOLUME instruction (#9099)
astarte75 May 21, 2026
fd613dc
fix(web): add requestIdleCallback fallback for Safari/iOS (#9094)
bubacho May 24, 2026
41b03bb
Merge commit from fork
sriramveeraghanta May 25, 2026
e71a8f5
[GIT-174]chore: set completed_at as read only field for work item (#9…
sangeethailango May 25, 2026
9f77ea5
fix: Add docker pytest runner and fix bugs the suite surfaced (#9138)
sriramveeraghanta May 25, 2026
13a3ea2
fix: security vulnerabilities for plane docker images (#9140)
pratapalakshmi May 26, 2026
310d2ed
chore: restructure .claude/skills into per-skill directories (#9146)
sriramveeraghanta May 26, 2026
edf2475
refactor: logging with retention + API token hardening (#9148)
sriramveeraghanta May 27, 2026
0acb32e
chore: bump turbo to 2.9.14, migrate pnpm config to workspace yaml (#…
sriramveeraghanta May 27, 2026
095b1aa
[WEB-7447] feat: migrate CE telemetry from OTLP traces to OTLP metric…
mguptahub May 28, 2026
f14451a
fix(web): add Safari fallback for requestIdleCallback (#9137)
KanteshMurade May 28, 2026
248f5d6
refactor(api): source API_KEY_RATE_LIMIT from settings, drop service …
sriramveeraghanta May 28, 2026
04622ce
fix: harden webhook/link/OAuth-avatar SSRF (advisory clusters A/B/C/E…
sriramveeraghanta May 30, 2026
3f57fef
chore: move all dependencies into pnpm catalog (#9153)
sriramveeraghanta May 31, 2026
011328c
[GIT-213] fix: return HTTP response from dispatch() exception handler…
sriramveeraghanta Jun 1, 2026
bd0d164
fix(GIT-235): add styles to onboarding tour close button for contrast…
Rahulcheryala Jun 1, 2026
e388cb9
fix: declare @tailwindcss/postcss in admin/space/web for Docker build…
sriramveeraghanta Jun 1, 2026
7ec8d49
fix: bump npm deps to resolve Dependabot advisories (#9191)
sriramveeraghanta Jun 1, 2026
b1c78fe
fix(api): rate-limit magic-code verify, bound per-token attempts (GHS…
sriramveeraghanta Jun 1, 2026
4280c4d
fix: handle error message for special characters in Identifier of Pro…
durgeshhhhhhh Jun 3, 2026
b6e47cc
fix: dropdown shadow on the work item more options (#9154)
karthiksuki Jun 3, 2026
9a30a07
fix(api): enforce workspace membership on GenericAssetEndpoint (#9212)
sriramveeraghanta Jun 4, 2026
0bbfe95
fix: bump react-router and vitest to resolve Dependabot advisories (#…
sriramveeraghanta Jun 4, 2026
a153531
chore: integrate react-doctor scanning (#9223)
sriramveeraghanta Jun 8, 2026
373f149
[GIT-238] refactor: migrate types from apps/web to @plane/types (#9203)
Rahulcheryala Jun 9, 2026
2f7941a
fix(api): sanitize XLSX export cells to prevent formula injection (#9…
sriramveeraghanta Jun 10, 2026
fd16d03
fix(api): reject API key auth for deactivated user accounts (#9225)
sriramveeraghanta Jun 10, 2026
498f857
fix: resolve esbuild advisory and bump turbo to 2.9.18 (#9236)
sriramveeraghanta Jun 15, 2026
f2feca6
feat(api): add workspace_slug to webhook delivery payload (#9232)
ch4og Jun 15, 2026
7db4d8e
chore(deps): bump pyjwt (#9241)
dependabot[bot] Jun 16, 2026
2541a8c
chore(deps): bump cryptography (#9243)
dependabot[bot] Jun 16, 2026
53a323d
chore(deps): bump the npm_and_yarn group across 1 directory with 3 up…
dependabot[bot] Jun 16, 2026
ad73ca3
[WEB-7730] fix(security): scope cascade deletes to workspace in BulkD…
mguptahub Jun 20, 2026
0f1f4d5
fix: Require at least one alphanumeric char in workspace name (#9263)
okxint Jun 20, 2026
81d9873
[WEB-7727] fix(security): scope issue ID validation to workspace/proj…
mguptahub Jun 20, 2026
ad32dc7
chore(deps): upgrade Storybook to v10 and fix security advisories (#9…
sriramveeraghanta Jun 20, 2026
7b0704d
fix(api): require at least one alphanumeric char in workspace name (#…
sriramveeraghanta Jun 20, 2026
64da8dc
fix: Use APP_DOMAIN env var for bot user email (#9262)
okxint Jun 20, 2026
4a0746b
fix: scope workspace user preference filter to current user (#9279)
sriramveeraghanta Jun 20, 2026
6220ba9
[WEB-7854] fix: prevent workspace invite token disclosure and invite …
mguptahub Jun 23, 2026
0d58adb
[WEB-7774] fix(security): sanitize comment_html and intake descriptio…
mguptahub Jun 23, 2026
971c2aa
[WEB-7769] fix(security): scope EstimatePoint create/destroy to works…
mguptahub Jun 23, 2026
1acc69e
[WEB-7805] fix: remove hardcoded SECRET_KEY from community deployment…
mguptahub Jun 23, 2026
cc3eb97
[WEB-7813] fix: prevent ORM order_by injection in issue and other end…
mguptahub Jun 23, 2026
6c9dbb5
[WEB-7787] fix(security): block deactivated user login and fix Worksp…
mguptahub Jun 23, 2026
1e8f363
[WEB-7787] fix(auth): restore activation flow and narrow deactivation…
mguptahub Jun 24, 2026
90ae845
[GIT-239 | GIT-240] refactor: hooks and constants consolidation to co…
Rahulcheryala Jun 26, 2026
4577dc3
[WEB-7776] fix(security): scope FileAsset queries to prevent cross-pr…
mguptahub Jun 30, 2026
28ae25b
[WEB-7847] fix: enforce workspace membership on entity-search endpoin…
mguptahub Jun 30, 2026
24fad36
[WEB-7945] fix(security): prevent shell injection in feature-deployme…
mguptahub Jul 1, 2026
4b52dce
[WEB-7855] fix(security): prevent project invite email disclosure via…
mguptahub Jul 1, 2026
5829f0f
[WEB-7892] fix(security): scope attachment PATCH/DELETE/GET by issue_…
mguptahub Jul 1, 2026
7fbf14a
[WEB-7894] fix: eliminate TOCTOU race in InstanceAdminSignUp (GHSA-p5…
mguptahub Jul 1, 2026
d5dda5d
fix: Issues created or updated via REST API send no notifications or …
wildsurfer Jul 7, 2026
4fc79a2
fix(security): block bot user logins (#9368)
sriramveeraghanta Jul 7, 2026
b91b61c
[WEB-7778] fix(security): reject unverified OAuth provider emails to …
mguptahub Jul 9, 2026
14a4c22
[WEB-7877] fix(security): enforce token + auth validation on project …
mguptahub Jul 9, 2026
73e3608
[WEB-7888] fix(security): normalize href before protocol check in Cus…
mguptahub Jul 9, 2026
e1ef420
[WEB-7895] fix: scope UserProjectInvitationsViewset to workspace-vali…
mguptahub Jul 9, 2026
6395e1d
[WEB-8017] fix(security): sanitize order_by on external REST API list…
mguptahub Jul 9, 2026
2e007e1
[WEB-8019] fix(security): scope CycleIssue reassignment lookup to wor…
mguptahub Jul 9, 2026
dc9d80b
[WEB-8060] fix(security): enforce authz on is_active member (de)activ…
mguptahub Jul 9, 2026
18ea715
fix(user): clone user data before updates to prevent mutations (#9285)
codingwolf-at Jul 13, 2026
9dff20e
[WEB-7887] fix(security): prevent stored XSS via SVG attachment serve…
mguptahub Jul 13, 2026
d3d3de4
[WEB-8012] fix: prevent ORM group_by/sub_group_by injection in issue …
mguptahub Jul 13, 2026
e63f0c3
[WEB-8066] fix: scope workspace asset get/patch/delete to project mem…
mguptahub Jul 14, 2026
bed58d9
chore: clean up React Doctor warnings in admin app (#9418)
sriramveeraghanta Jul 14, 2026
8ef78bf
[GIT-248 | GIT-254] refactor: store and components consolidation to c…
codingwolf-at Jul 16, 2026
b3591b9
[WEB-8068] fix: scope workspace cycles/modules listing to project mem…
mguptahub Jul 16, 2026
5842ca8
[WEB-8075] fix: scope ProjectMemberPermission SAFE_METHODS to project…
mguptahub Jul 16, 2026
cfe951c
[WEB-8095] fix: scope page-version reads to the URL project (GHSA-g49…
mguptahub Jul 16, 2026
af1be50
[WEB-8074] fix: scope IssueListEndpoint to guest created_by (#9374)
mguptahub Jul 16, 2026
7cef741
feat(api): add lite list endpoints for projects, members, cycles, and…
akhil-vamshi-konam Jul 17, 2026
a8e53b6
chore(deps): resolve open Dependabot security alerts (#9456)
sriramveeraghanta Jul 21, 2026
8222982
Merge remote-tracking branch 'origin/preview' into chore/upgrade-prev…
Jul 22, 2026
ebd88f8
fix(merge): restore move-page feature dropped in preview merge, drop …
Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
67 changes: 67 additions & 0 deletions .claude/skills/branch-name/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: branch-name
description: Use when starting a new branch or renaming an existing one — produces a branch name in the format `<type>/<work-item-id>-<short-description>` that's compatible with the create-pr skill's work item ID extraction.
user_invocable: true
---

# Branch Naming

Create branch names that follow the convention `<type>/<work-item-id>-<short-description>`, where the work item ID can be cleanly extracted later (e.g., by the create-pr skill).

## Format

```
<type>/<work-item-id>-<short-description>
```

- All lowercase, hyphen-separated
- Work item ID stays in its original form but lowercased (e.g., `SILO-1146` → `silo-1146`)
- Short description is 2–5 words in kebab-case, focused on the _what_, not the _how_

## Workflow

1. **Determine the type** based on the work being done:
- `feat` — new functionality
- `fix` — bug fix
- `chore` — tooling, deps, config, non-user-facing housekeeping
- `refactor` — restructuring without behavior change
- `docs` — documentation only
- `perf` — performance improvement

2. **Determine the work item ID**:
- If the user gives one, use it
- If they reference a Plane work item (e.g., a URL or title), extract the ID
- If none exists, ask the user — don't invent one

3. **Write the short description**:
- 2–5 words in kebab-case
- Describe the outcome, not the implementation (`add-app-tile-visibility`, not `update-tile-component`)
- Skip filler words (`the`, `a`, `for`)

4. **Assemble and create the branch**:

```
git checkout -b <type>/<work-item-id-lowercased>-<short-description>
```

5. **Return the branch name** to the user.

## Examples

```
fix/silo-1146-relative-config-urls
feat/web-1234-app-tile-visibility
chore/web-2201-bump-eslint
refactor/silo-980-extract-auth-middleware
docs/web-1500-pr-template-update
perf/silo-1310-cache-workspace-lookup
```

## Common Mistakes

- Putting the work item ID at the end instead of after the type (breaks extraction)
- Using underscores or camelCase instead of hyphens
- Uppercasing the work item ID inside the branch name (it should be lowercase here, uppercased only when used as the PR title prefix)
- Writing a long, narrative description — keep it scannable
- Omitting the work item ID when one exists in Plane
- Using a type that won't match the eventual PR type (pick the type you'd use in the PR title)
65 changes: 65 additions & 0 deletions .claude/skills/create-pull-request/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: create-pull-request
description: Use when creating a pull request for the current branch — gathers branch context, generates a PR description following the repo's pull_request_template.md, and creates the PR with a Plane work item ID prefix in the title.
user_invocable: true
---

# Create PR

Create a pull request using the repo's PR template, a Plane work item ID as the title prefix, and a fully filled-out description based on the actual diff.

## Workflow

1. **Determine the base branch**: Default to `preview` unless the user specifies otherwise.

2. **Gather context** (in parallel):
- `git status -s` — check for uncommitted changes
- `git diff <base>...HEAD --stat` — files changed
- `git log <base>...HEAD --oneline` — all commits on the branch
- `git diff <base>...HEAD --no-color` — full diff for understanding changes (if very large, focus on the most important files first)
- `git rev-parse --abbrev-ref --symbolic-full-name @{u}` — check if branch tracks a remote
- Read `.github/pull_request_template.md` from the repo root

3. **Determine work item ID**:
- Extract from branch name if it contains an identifier (e.g., `chore/silo-1146-foo``SILO-1146`, `feat/web-1234-x``WEB-1234`)
- If not found in branch name, ask the user

4. **Draft the PR** using the template from step 2:

**Title**: `[WORK-ITEM-ID] <type>: <concise summary>` (under 70 chars)
- Type reflects the change: `fix`, `feat`, `chore`, `refactor`, `docs`, `perf`, etc.

**Body**: Fill in every section from the PR template based on the actual diff:
- **Description** — Clear, concise summary of what the PR does and why. Focus on the "what" and "why", not line-by-line changes. Mention important implementation decisions.
- **Type of Change** — Check the appropriate box(es): Bug fix, Feature, Improvement, Code refactoring, Performance improvements, Documentation update.
- **Screenshots and Media** — Leave a placeholder: `<!-- Add screenshots here -->`
- **Test Scenarios** — Suggest concrete scenarios grounded in the actual changes (e.g., "Navigate to project settings and verify the new toggle works"), not generic ones.
- **References** — Include the work item ID, any linked issues the user mentions, and any Sentry issue links/IDs (e.g., `SENTRY-ABC123` or Sentry URLs) referenced earlier in the conversation.

Append a Claude Code session line at the bottom of the body.

5. **Push and create** (in parallel where possible):
- Push branch with `-u` if no upstream is set
- Create PR via `gh pr create` using a HEREDOC for the body

6. **Return the PR URL** to the user.

## Example Title

```
[SILO-1146] fix: allow relative URLs for configuration_url and improve app tile visibility
```

## Guidelines

- Keep the description concise but informative
- Use bullet points when listing multiple changes
- Focus on user-facing impact, not implementation details
- Don't fabricate test scenarios that aren't relevant to the actual changes

## Common Mistakes

- Summarizing only the latest commit instead of all commits on the branch
- Forgetting to check for an upstream before pushing
- Using a work item ID format that doesn't match the branch convention
- Wrapping the PR body in a code fence when passing it to `gh pr create`
50 changes: 50 additions & 0 deletions .claude/skills/react-doctor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: react-doctor
description: Use when finishing a feature, fixing a bug, before committing React code, or when the user types `/doctor`, asks to scan, triage, or clean up React diagnostics. Covers lint, accessibility, bundle size, architecture. Includes a regression check and a full local-triage workflow that fetches the canonical playbook.
version: "1.1.0"
---

# React Doctor

Scans React codebases for security, performance, correctness, and architecture issues. Outputs a 0–100 health score.

## After making React code changes:

Run `npx react-doctor@latest --verbose --diff` and check the score did not regress.

If the score dropped, fix the regressions before committing.

## For general cleanup or code improvement:

Run `npx react-doctor@latest --verbose` (without `--diff`) to scan the full codebase. Fix issues by severity — errors first, then warnings.

## /doctor — full local triage workflow

When the user types `/doctor`, says "run react doctor", or asks for a full triage / cleanup pass (not just a regression check), fetch the canonical local-triage playbook and follow every step in it:

```bash
curl --fail --silent --show-error \
--header 'Cache-Control: no-cache' \
https://www.react.doctor/prompts/react-doctor-agent.md
```

The playbook is the single source of truth — a scan → filter → triage → fix → validate loop that edits the working tree directly (never commits, never opens PRs). Updating the prompt at its source updates every agent on its next fetch — no skill reinstall needed.

Pair it with the matching per-rule prompts at `https://www.react.doctor/prompts/rules/<plugin>/<rule>.md` (fetched on demand inside the playbook) so each fix uses the canonical, reviewer-tested recipe.

## Configuring or explaining rules

When the user wants to understand a rule, disagrees with one, or wants to disable / tune which rules run (not fix code), use the `doctor-explain` skill (alias `/doctor-config`). Start with `npx react-doctor@latest rules explain <rule>`, then apply the narrowest control via `npx react-doctor@latest rules disable|set|category|ignore-tag …`, which edits your `doctor.config.*` (or `package.json#reactDoctor`).

## Command

```bash
npx react-doctor@latest --verbose --diff
```

| Flag | Purpose |
| ----------- | --------------------------------------------- |
| `.` | Scan current directory |
| `--verbose` | Show affected files and line numbers per rule |
| `--diff` | Only scan changed files vs base branch |
| `--score` | Output only the numeric score |
200 changes: 200 additions & 0 deletions .claude/skills/release-notes/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
name: release-notes
description: "Generate release notes for a Plane release PR in either `makeplane/plane-cloud` (date-based versioning, e.g. `release: vYY.MM.DD-N`) or `makeplane/plane-ee` (semver, e.g. `release: vX.Y.Z`). Reads PR commits, filters out noise, categorizes by conventional-commit type, optionally enriches via Plane MCP, and writes the result as the PR description in the GitHub Releases format."
user_invocable: true
---

# Release Notes Generator

Generate structured release notes from a Plane release PR by parsing its commit list, then update the PR description. Output matches the format used on `github.com/makeplane/plane/releases` (e.g. [v1.2.0](https://github.com/makeplane/plane/releases/tag/v1.2.0)). Works for both `makeplane/plane-cloud` and `makeplane/plane-ee`.

## Repo-specific versioning

Plane uses **different version schemes** across its two release repos. Detect which repo the PR belongs to and use the matching scheme when communicating about the release — the version itself does **not** appear in the release notes body (GitHub's release tag carries it).

| Repo | Version scheme | Example PR title | Source branch | Target branch |
| ----------------------- | -------------- | ---------------------- | ------------- | -------------------- |
| `makeplane/plane-cloud` | Date-based | `release: v26.04.13-1` | `uat` | `master` |
| `makeplane/plane-ee` | Semver | `release: v1.12.0` | `uat` | `master` / `preview` |

- **plane-cloud** ships daily — version is `vYY.MM.DD-N` where `N` is the counter for that date's release.
- **plane-ee** ships on a versioned cadence — version is `vX.Y.Z` (major.minor.patch) following semver.
- Detect the repo with `gh pr view <PR_NUM> --json headRepository,baseRepository` or from the URL the user shared.

## When to Use

- User links/mentions a Plane release PR (e.g. `release: v26.04.13-1` for cloud or `release: v1.12.0` for EE) and asks for release notes
- User asks to "create release notes" / "update PR description" for a PR in `makeplane/plane-cloud` or `makeplane/plane-ee`
- The branch is named `uat` or `release/x.y.z` and the base is `master` or `preview`

## Steps

### 1. Fetch commits

```bash
gh pr view <PR_NUM> --json title,body,baseRefName,headRefName,commits \
--jq '.commits[] | .messageHeadline + "\n---BODY---\n" + .messageBody + "\n===END==="'
```

For a quick scan first:

```bash
gh pr view <PR_NUM> --json commits \
--jq '.commits[] | {oid: .oid[0:10], message: .messageHeadline}'
```

### 2. Filter out noise

**Always exclude** these commits — mechanical, not user-facing:

| Pattern | Reason |
| -------------------------------------------- | ------------------------------------- |
| `Sync: Enterprise Changes #NNNN` | Cross-repo sync, no functional change |
| `fix: merge conflicts` | Merge artifact |
| `Merge branch '...' of github.com:...` | Merge artifact |
| `Revert "..."` (when immediately re-applied) | Internal churn |

### 3. Identify work item IDs (for research only)

Most meaningful commits begin with a Plane work item identifier in brackets:

- `[WEB-XXXX]` — web/frontend product items
- `[SILO-XXXX]` — Silo (integrations: Slack, GitHub, GitLab, Jira/Linear)
- `[MOBILE-XXXX]`, `[API-XXXX]`, etc.

**Do not include these IDs in the release notes.** The GitHub Releases format is end-user-facing — IDs are only useful as a lookup key for fetching context in step 4.

### 4. (Optional) Enrich via Plane MCP

For larger features where the commit headline is terse, fetch the work item to write a richer paragraph:

```
mcp__plane__retrieve_work_item_by_identifier(project_identifier="WEB", issue_identifier=6874)
```

Use the returned `name` and `description_stripped` to flesh out the prose. Skip for routine fixes — commit body is usually enough. Don't enrich every item (slow + descriptions are often empty).

### 5. Categorize commits

Map each surviving commit into one of four sections:

| Commit signal | Section |
| --------------------------------------------------------------------------------------------------------------------- | --------------- |
| `feat:` that introduces a brand-new screen, flow, or capability | ✨ Features |
| `feat:` that improves an existing feature, plus most `refactor:` and behavioural `chore:` items that are user-visible | ⬆️ Enhancements |
| `fix:`, `fix(scope):` | 🐞 Bug fixes |
| CVE upgrades, dependency bumps that close a vulnerability, security hardening | 🛡️ Security |

**Drop entirely** (do not surface to users): pure infra `chore:`, dependabot bumps with no CVE, internal refactors with no behavioural impact, test-only changes, doc-only changes.

### 6. Format

Output follows the GitHub Releases convention — `###` for section headers, with two spaces between the emoji and the label for ✨ / ⬆️ / 🐞 (matches `v1.2.0`).

```markdown
### ✨ Features

#### **Short Feature Name in Title Case**

A 1–3 sentence paragraph describing what the user gets, why it matters, and any notable behaviour. Write in product-marketing voice, not commit-message voice.

- Optional nested bullets for sub-capabilities or callouts
- Keep them user-facing — what the user can now do

#### **Second Major Feature**

Another descriptive paragraph. Each major feature gets its own `####` subsection.

### ⬆️ Enhancements

- One-line description of an improvement to an existing capability
- Another improvement, written as a clean sentence (no commit prefix, no ticket ID)

### 🐞 Bug fixes

- Plain-English description of what was broken and is now fixed
- Another bug fix

### 🛡️ Security

- Upgraded <component> to <version> to mitigate [CVE-XXXX-NNNNN](https://link-to-advisory). Brief impact note.
- Other security-relevant change
```

Rules:

- Section headers use `###` (three hashes), then emoji + **two spaces** + label — exactly as in the published v1.2.0 release. Exception: 🛡️ Security uses a single space (matches v1.2.0).
- Features use `####` (four hashes) and the feature name is **bolded** inside the heading: `#### **Feature Name**`.
- Each feature gets a real paragraph, not a bullet — written for end users, not engineers.
- Enhancements, Bug fixes, and Security are simple bullets. No nested asterisks, no ticket IDs, no PR numbers.
- **Do not include work item IDs (`[WEB-XXXX]`) or PR numbers (`(#NNNN)`)** in any section — this format is user-facing.
- **Do not add a `# Release vX.Y.Z` heading.** The GitHub release tag carries the version; the body starts directly with the first `### ✨ Features` section.
- **Do not insert images.** The user adds screenshots manually after the notes are drafted. Leave space for them only if the user asks.
- Drop empty sections entirely.
- Blank line between section header and first bullet/feature, and between sections.

### 7. Update the PR description

```bash
gh pr edit <PR_NUM> --body "$(cat <<'EOF'
<release notes markdown>
EOF
)"
```

Always use a HEREDOC with single-quoted `'EOF'` so backticks/dollars in the notes are preserved.

## Quick Reference: end-to-end

```bash
PR=2498
gh pr view $PR --json commits --jq '.commits[] | .messageHeadline + "\n---\n" + .messageBody + "\n==="' > /tmp/commits.txt
# read /tmp/commits.txt, filter, categorize into the four sections, draft notes
gh pr edit $PR --body "$(cat <<'EOF'
### ✨ Features

#### **...**

...

### ⬆️ Enhancements

- ...

### 🐞 Bug fixes

- ...

### 🛡️ Security

- ...
EOF
)"
```

## Reference example

The canonical target format is [v1.2.0](https://github.com/makeplane/plane/releases/tag/v1.2.0) on `makeplane/plane`. When in doubt about heading levels, spacing, bolding, or paragraph voice, match that page exactly (minus images).

## Common Mistakes

- **Including work item IDs in bullets** — the GitHub Releases format is user-facing; `[WEB-XXXX]` belongs in internal research, not the output.
- **Adding a `# Release vX.Y.Z` heading** — GitHub's release tag is the version. The body starts with `### ✨ Features`.
- **Copy-pasting commit subjects verbatim** — rewrite into product-marketing English. "fix: peek overview reload on parent add" → "Fixed peek overview reloading on adding a parent".
- **Bulleting features instead of writing paragraphs** — major features get `#### **Name**` plus a real paragraph; only enhancements/bugs/security use bullets.
- **Including `Sync: Enterprise Changes` commits** — these are sync PRs, never user-visible.
- **Including `fix: merge conflicts`** — merge artifact, no functional content.
- **Inserting images** — leave images for the user; they add screenshots manually.
- **Using `--body` without HEREDOC** — backticks/dollar signs get shell-interpreted and corrupt the notes.
- **Editing the PR title** — release PR titles are version markers; only edit the body.
- **Adding a Chores section** — the GitHub Releases format has no Chores section; user-invisible chores are dropped entirely.

## Plane-Specific Conventions

- Release PRs go from `uat` → `master` (or `preview`).
- PR title format:
- `plane-cloud`: `release: vYY.MM.DD-N` where N is the daily release counter for that date.
- `plane-ee`: `release: vX.Y.Z` semver (major.minor.patch).
- Commits coming from feature branches always carry a work item ID; commits without one are usually infra/chores and almost always dropped from notes.
- `Sync: Enterprise Changes #NNNN` are automated cross-repo syncs and are _always_ skipped.
- CVE-related upgrades (NextJS, React, Django, nginx, etc.) belong under 🛡️ Security with a link to the advisory and a one-line impact note.
Loading
Loading