Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions .claude/skills/open-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
name: open-pr
description: Open a pull request following Aspid.FastTools project conventions — title format, PULL_REQUEST_TEMPLATE body, label policy, commit-message rules, and scope hygiene. Use this skill whenever the user asks to open / create / draft a PR, when running `@claude` triggers a PR-creation flow, or before invoking `gh pr create` directly.
user-invocable: true
---

Use this skill any time a pull request is being opened in the Aspid.FastTools repository — manual, scripted, or via `@claude` automation.

## Title

- Short imperative sentence describing the change. Aim for under 70 characters.
- No auto-generated branch-name strings. `Claude/add onenable idregistry i bk jl` is **not** acceptable; rewrite it.
- Examples that pass: `Mark IdRegistry cache dirty on OnEnable`, `Fix this.Marker() generator for explicit interfaces, generics and field naming`, `Document PR conventions in CLAUDE.md`.

## Body

Fill out `.github/PULL_REQUEST_TEMPLATE.md` — three sections, all of which may be omitted only when truly empty.

### `## Summary`

- 1–3 bullets covering what changed and why.
- Code snippets are welcome here when they make the change concrete (e.g. the new method body, a small before/after).
- Do not paste a wall of release-notes prose; if the change really is that big, see the *Release-notes mega-PRs* carve-out below.

### `## Notes for review`

- Optional. Use it for trade-offs, risks, things you specifically want eyes on.
- Also use it to flag unrelated noise in the diff (e.g. `.github/` files that already landed on `main` showing up because the branch sits ahead of `Develop`) so reviewers know it is a no-op on merge.
- If there is nothing to say, delete the section — do not leave a placeholder.

### `## Linked issues`

- `Closes #N` for issues this PR fully resolves (auto-closes them on merge).
- `Refs #N` for related issues that the PR does not close.
- Delete the section when nothing applies.

## Labels

Pick from the existing label set; do **not** invent new labels in PRs. The label catalogue is fixed and visible via `gh label list --repo VPDPersonal/Aspid.FastTools`.

| Group | Rule |
|---|---|
| `type: *` | Exactly **one**: `feature`, `fix`, `refactor`, `documentation`, `test`, `chore`, `ci`, `style`, `performance`. |
| `area: *` | One or more for every part of the codebase the PR actually touches: `runtime`, `editor`, `generator`, `samples`. |
| `status: *` | `needs-review` once the PR is ready, `work-in-progress` while still drafting. |
| Special | `breaking-change`, `dependencies`, `needs-changelog` only when literally true. |

## Commit messages

- Short imperative sentences: `Add X`, `Fix Y`, `Mark Z`. Match the headline style already in `git log`.
- **Never** append `Co-Authored-By: Claude …` or any other Claude/Anthropic attribution trailer. Commits are authored as the human user only. This overrides default templates from any skill (e.g. `commit-commands:commit`, `commit-commands:commit-push-pr`).

## Scope

- One logical change per PR.
- If the diff drags in unrelated noise from a base-branch merge, do **not** delete it — just call it out under *Notes for review*.
- Templates (`bug_report.yml`, `feature_request.yml`, `config.yml`, `PULL_REQUEST_TEMPLATE.md`) and CI workflows (`.github/workflows/*.yml`) live on `main`; targeting them at `Develop` directly is wrong unless the change is meant to ride a release merge.

## Release-notes mega-PRs (carve-out)

`Develop` → `main` release cuts (e.g. #8) are **exempt** from the three-section template. Use feature-scoped `###` subsections instead — one per major area (e.g. `### Source generators`, `### ID System`, `### UIToolkit`, `### Layout & rename`, `### Docs & tooling`). Mirror the structure of the most recent release PR.

## Recipe

When invoked, walk through this checklist before reporting "PR opened":

1. **Branch** — confirm the head branch is named per existing patterns (`Feature/<name>`, `chore/<name>`, `claude/<auto>`). If the auto-name is ugly (e.g. `claude/add-onenable-idregistry-IBkJl`), live with it but compensate with a clean PR title.
2. **Diff** — run `git diff <base>...HEAD --stat` and skim what's actually changing. Identify the *one* logical change vs. accidental noise.
3. **Title** — draft per the rules above.
4. **Body** — fill the three template sections. Use `gh pr create --body "$(cat <<'EOF' ... EOF)"` with a HEREDOC; never inline backticks through zsh, they get eaten as command substitution and silently drop content (this happened on issue-comment 4415890039 — see the `gh api -X PATCH` recovery).
5. **Labels** — apply via `--add-label "type: X,area: Y,…"` either at create time or right after.
6. **Closes / Refs** — if any issues are involved, write them in *Linked issues*. Verify with `gh issue list --state open` what is actually linkable.
7. **Verify** — `gh pr view <N> --json title,labels,body` to confirm everything took.

## Common failure modes to avoid

- Empty body. Fix immediately if you see `body=""` on a PR you opened.
- Auto-generated title from branch name (`Claude/add-…`).
- Two `type: *` labels at once (pick one).
- Pasting unredacted Claude-attribution trailers in commit messages.
- Backtick-inside-`gh-pr-comment` shell injection (always heredoc).
12 changes: 11 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,19 @@ All palette variables in `Aspid-FastTools-Default-Dark.uss` already follow this
### Local Claude Code automation

- **PostToolUse hook** (`.claude/hooks/rebuild-generators-on-change.sh`): on every `Edit`/`Write` to `*.cs` under `Aspid.FastTools.Generators/Aspid.FastTools.Generators/`, runs `dotnet build -c Release` for the generator project (which redeploys the DLL into the Unity package). Unity-side edits, tests, and the Sample project are explicitly skipped — keep that scope when changing the hook.
- **Project skills** (`.claude/skills/`): `build-generator` (manual generator build + DLL deploy), `sync-readmes` (verify README EN/RU + root/Documentation copies against the codebase).
- **Project skills** (`.claude/skills/`): `build-generator` (manual generator build + DLL deploy), `sync-readmes` (verify README EN/RU + root/Documentation copies against the codebase), `open-pr` (project conventions for opening pull requests — see *Pull request conventions* below).
- **Project subagents** (`.claude/agents/`): `code-reviewer` (Unity/Editor boundary + generator + package convention review), `uss-bem-checker` (validates USS class names + `--aspid-*` variables against the BEM/positional grammars above).

### Submodule

`Aspid.Internal.Unity` is a git submodule providing internal Unity helpers. It is referenced but not part of the main package distribution.

## Pull request conventions

When opening a PR — manually or via `@claude` — invoke the `open-pr` skill (`.claude/skills/open-pr/SKILL.md`) for the full procedure. Quick reference:

- **Title** — short imperative sentence under 70 characters; no auto-generated branch-name strings.
- **Body** — fill out `.github/PULL_REQUEST_TEMPLATE.md` (Summary / Notes for review / Linked issues). Mega-PRs like the `Develop` → `main` release cut are exempt and use feature-scoped `###` subsections instead.
- **Labels** — exactly one `type: *`, plus matching `area: *` labels.
- **Commit messages** — short imperative sentences, **no** `Co-Authored-By: Claude …` trailer.
- **Scope** — one logical change per PR; flag any unrelated noise in *Notes for review*.
Loading