From aa5b194089864c1571cb03c6a12ca1425a476dc3 Mon Sep 17 00:00:00 2001 From: sriramveeraghanta Date: Fri, 17 Jul 2026 21:16:59 +0530 Subject: [PATCH] chore: add Claude Code project skills MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add five repo-scoped Claude Code skills under .claude/skills/ that encode this repo's conventions so agents follow them consistently: - branch-name — /- branches - create-pull-request — PR title with Plane work item prefix + full body - release-notes — release-PR notes for makeplane/propel (semver → main) - react-doctor — React lint/a11y/bundle/architecture triage (/doctor) - feature-docs-layout — where feature/design/plan docs live under docs/ Also gitignore local-only Claude Code artifacts (settings.local.json, scheduled_tasks.lock) so only the shared skills are tracked. --- .claude/skills/branch-name/SKILL.md | 67 ++++++++ .claude/skills/create-pull-request/SKILL.md | 65 ++++++++ .claude/skills/feature-docs-layout/SKILL.md | 58 +++++++ .claude/skills/react-doctor/SKILL.md | 50 ++++++ .claude/skills/release-notes/SKILL.md | 160 ++++++++++++++++++++ .gitignore | 4 +- 6 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 .claude/skills/branch-name/SKILL.md create mode 100644 .claude/skills/create-pull-request/SKILL.md create mode 100644 .claude/skills/feature-docs-layout/SKILL.md create mode 100644 .claude/skills/react-doctor/SKILL.md create mode 100644 .claude/skills/release-notes/SKILL.md diff --git a/.claude/skills/branch-name/SKILL.md b/.claude/skills/branch-name/SKILL.md new file mode 100644 index 00000000..a6fc6e55 --- /dev/null +++ b/.claude/skills/branch-name/SKILL.md @@ -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 `/-` 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 `/-`, where the work item ID can be cleanly extracted later (e.g., by the create-pr skill). + +## Format + +``` +/- +``` + +- 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 /- +``` + +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) diff --git a/.claude/skills/create-pull-request/SKILL.md b/.claude/skills/create-pull-request/SKILL.md new file mode 100644 index 00000000..d9f217ef --- /dev/null +++ b/.claude/skills/create-pull-request/SKILL.md @@ -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 `main` unless the user specifies otherwise. + +2. **Gather context** (in parallel): + - `git status -s` — check for uncommitted changes + - `git diff ...HEAD --stat` — files changed + - `git log ...HEAD --oneline` — all commits on the branch + - `git diff ...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] : ` (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: `` + - **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` diff --git a/.claude/skills/feature-docs-layout/SKILL.md b/.claude/skills/feature-docs-layout/SKILL.md new file mode 100644 index 00000000..da7ef095 --- /dev/null +++ b/.claude/skills/feature-docs-layout/SKILL.md @@ -0,0 +1,58 @@ +--- +name: feature-docs-layout +description: Use when saving or creating any design, spec, brainstorming, or implementation-plan markdown doc in this repo — including docs produced by the superpowers brainstorming/writing-plans skills, or any time you are about to choose a path under docs/ (especially docs/superpowers/) or decide where feature documentation lives. +user_invocable: true +--- + +# Feature Docs Layout + +## Overview + +Every planning, design, and implementation document for a feature is the **system of record** for how that feature was built. Keep them together in ONE per-feature directory: + +``` +docs//.md +``` + +**Never** write to `docs/superpowers/` and **never** date-prefix filenames. + +## The Rule + +- `` — kebab-case, descriptive, stable (e.g. `bulk-work-item-archive`). No dates, no `superpowers`. +- All docs for one feature live in the same folder, side by side. + +## Quick Reference + +| Doc | Path | +| ------------------------------------------ | ------------------------------------------- | +| Design / spec (from brainstorming) | `docs//design.md` | +| Implementation plan (from writing-plans) | `docs//plan.md` | +| Anything else (research, decisions, notes) | `docs//.md` | + +## Picking the slug + +1. If `docs//` already exists for this feature, **reuse it** — add your doc there, don't make a new folder. +2. Otherwise derive a kebab-case slug from the feature name; match the branch slug if one exists (see `branch-name`). + +## Overriding superpowers (important) + +The superpowers `brainstorming` and `writing-plans` skills default to `docs/superpowers/specs/YYYY-MM-DD--design.md` and `docs/superpowers/plans/YYYY-MM-DD-.md`. **Both skills explicitly state that user preferences for the doc location override this default. This skill is that preference.** So when following them: + +- design / spec → `docs//design.md` +- plan → `docs//plan.md` + +Do not create `docs/superpowers/`. If you find docs already there, move them into `docs//` (precedent: PR #7684). + +## Common Mistakes + +| Mistake | Fix | +| ---------------------------------------------------------- | ------------------------- | +| `docs/superpowers/specs/2026-06-12-foo-design.md` | `docs/foo/design.md` | +| `docs/superpowers/plans/2026-06-12-foo.md` | `docs/foo/plan.md` | +| `docs/2026-06-12-foo-design.md` (date prefix at top level) | `docs/foo/design.md` | +| Design and plan in different top-level folders | Both under `docs/foo/` | +| New folder when `docs/foo/` already exists | Reuse the existing folder | + +## Examples (existing in this repo) + +`docs/permissions/`, `docs/data-layer/`, `docs/work-item-types/`, `docs/pi-prediction-entity-abstraction/design.md`, `docs/rich-text-external-endpoints/plan.md`. diff --git a/.claude/skills/react-doctor/SKILL.md b/.claude/skills/react-doctor/SKILL.md new file mode 100644 index 00000000..3afcd67a --- /dev/null +++ b/.claude/skills/react-doctor/SKILL.md @@ -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//.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 `, 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 | diff --git a/.claude/skills/release-notes/SKILL.md b/.claude/skills/release-notes/SKILL.md new file mode 100644 index 00000000..69901186 --- /dev/null +++ b/.claude/skills/release-notes/SKILL.md @@ -0,0 +1,160 @@ +--- +name: release-notes +description: "Generate release notes for a `makeplane/propel` release PR (semver, e.g. `release: vX.Y.Z`) that targets `main`. Reads PR commits, filters out noise, categorizes by conventional-commit type, optionally enriches via Plane MCP, and writes the result as the PR description." +user_invocable: true +--- + +# Release Notes Generator + +Generate structured release notes from a `makeplane/propel` release PR by parsing its commit list, then update the PR description. + +## Versioning + +propel follows **semver** — the release version is `vX.Y.Z` (major.minor.patch). Versions are managed by [Changesets](https://github.com/changesets/changesets), so the release PR is usually the automated **"Version Packages"** PR that bumps `@makeplane/propel` and targets `main`. + +- Read the target version from the PR title (`release: vX.Y.Z`), the Changesets "Version Packages" body, or the bumped `package.json`. +- Release PRs always target **`main`**. Never target a `preview`/`master` branch. +- Never invent a version — always take it from the PR/changeset. + +## When to Use + +- User links/mentions a propel release PR (e.g. `release: v1.2.0`, or the Changesets "Version Packages" PR) and asks for release notes +- User asks to "create release notes" / "update PR description" for a release PR targeting `main` + +## Steps + +### 1. Fetch commits + +```bash +gh pr view --json title,body,baseRefName,headRefName,commits \ + --jq '.commits[] | .messageHeadline + "\n---BODY---\n" + .messageBody + "\n===END==="' +``` + +For a quick scan first: + +```bash +gh pr view --json commits \ + --jq '.commits[] | {oid: .oid[0:10], message: .messageHeadline}' +``` + +### 2. Filter out noise + +**Always exclude** these commits — mechanical, not user-facing: + +| Pattern | Reason | +| -------------------------------------------- | ------------------------- | +| `fix: merge conflicts` | Merge artifact | +| `Merge branch '...' of github.com:...` | Merge artifact | +| `Revert "..."` (when immediately re-applied) | Internal churn | +| `chore: version packages` / Changesets bumps | Release bookkeeping | + +### 3. Parse work item IDs + +Most meaningful commits begin with a Plane work item identifier in brackets: + +- `[WEB-XXXX]` — web/frontend product items +- `[MOBILE-XXXX]`, `[API-XXXX]`, etc. + +Always preserve these IDs in the release notes — they let readers click through to the source ticket. + +### 4. (Optional) Enrich via Plane MCP + +For larger features where the commit headline is terse, fetch the work item: + +``` +mcp__plane__retrieve_work_item_by_identifier(project_identifier="WEB", issue_identifier=6874) +``` + +Use the returned `name` and `description_stripped` to flesh out the bullet. Skip this for routine fixes — commit body is usually enough. Don't enrich every item (slow + work item descriptions are often empty). + +### 5. Categorize by conventional-commit type + +Three prefixes are **hard mappings** — no interpretation needed: + +| Commit prefix | Section | +| -------------------------------------- | --------------------- | +| `fix:`, `fix(scope):` | 🐛 Bug Fixes — always | +| `refactor:`, `chore:`, `chore(scope):` | 🔧 Chores — always | +| `chore(deps):`, dependabot bumps | 🔧 Chores — always | + +`feat:` is the only prefix that requires judgment. Read the commit title and ask: **is this a true new capability, or an improvement to something that already exists?** + +| The commit title reads like… | Section | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| New screen, flow, or capability that did not exist before ("add X", "introduce Y", "implement Z", "support A") | ✨ New Features | +| Improvement to an existing feature, UI tweak, performance gain, behavioural change, sort order, default value ("improve X", "update Y", "optimise B", "enhanced A") | 🔧 Enhancements | + +Commits with no conventional prefix: omit unless they carry a work item ID, in which case apply the same `feat:` judgment above. + +### 6. Format + +Use the semver version taken from the PR (see **Versioning** above): + +```markdown +# Release vX.Y.Z + +## ✨ New Features + +- - [TICKET-ID] Human-readable description of the new capability + Optional 1–2 sentence elaboration drawn from the commit body. + +🔧 Enhancements + +- - [TICKET-ID] Human-readable description of what improved + +🐛 Bug Fixes + +- - [TICKET-ID] Human-readable description of what was broken and is now fixed + +🔧 Chores + +- - [TICKET-ID] Human-readable description of the internal change +``` + +Rules: + +- Section header is emoji + space + label — no `#`, no `##`, no bold +- Blank line between the section header and the first bullet, and between sections +- Each bullet starts with `* [TICKET-ID]` — include the work item ID in brackets when the commit has one; rewrite the commit subject into a clear, user-facing sentence (never copy a cryptic commit message verbatim) +- Add a sub-line elaboration (indented 2 spaces) only when the commit body has substance worth surfacing: acceptance criteria, scope notes, or gotchas like "behind feature flag", "requires migration" +- No bold (`**`), no italics, no PR numbers `(#NNNN)` appended to bullets +- Drop empty sections entirely + +### 7. Update the PR description + +```bash +gh pr edit --body "$(cat <<'EOF' + +EOF +)" +``` + +Always use a HEREDOC with single-quoted `'EOF'` so backticks/dollars in the notes are preserved. + +## Quick Reference: end-to-end + +```bash +PR=42 +gh pr view $PR --json commits --jq '.commits[] | .messageHeadline + "\n---\n" + .messageBody + "\n==="' > /tmp/commits.txt +# read /tmp/commits.txt, filter, categorize, draft notes +gh pr edit $PR --body "$(cat <<'EOF' +... release notes ... +EOF +)" +``` + +## Common Mistakes + +- **Including `fix: merge conflicts`** — merge artifact, no functional content +- **Including the Changesets `version packages` bump** — release bookkeeping, not a user-visible change +- **Dropping the work item ID** — readers rely on `[WEB-XXXX]` to navigate to the ticket +- **Over-enriching with MCP lookups** — work item descriptions are often empty; commit body is usually richer +- **Using `--body` without HEREDOC** — backticks/dollar signs get shell-interpreted and corrupt the notes +- **Editing the title** — release PR titles are version markers; only edit the body +- **Inventing or reformatting the version** — propel is semver (`vX.Y.Z`); take the exact version from the PR/changeset + +## Release conventions + +- Release PRs always target **`main`** +- PR title format: `release: vX.Y.Z` — semver (major.minor.patch), managed by Changesets +- Commits coming from feature branches usually carry a work item ID (e.g. `[WEB-XXXX]`); commits without one are usually infra/chores diff --git a/.gitignore b/.gitignore index d5f41daa..3365c6d2 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,10 @@ dist-ssr *.sln *.sw? -# AI agent worktrees +# Claude Code — local settings & session artifacts (committed skills live in .claude/skills/) .claude/worktrees/ +.claude/settings.local.json +.claude/scheduled_tasks.lock # Storybook build output storybook-static