Skip to content
Open
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
73 changes: 73 additions & 0 deletions .claude/commands/pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
description: Prepare a Conventional-Commit PR title, a changeset-style body, and a squash-vs-rebase recommendation for the current branch. Text only — no pushing, no gh calls.
---

# /pr — prepare a pull request

Produce the **text** for a PR on the current branch, following the project's git
workflow (see `CONTRIBUTING.md` → Git Workflow). Do **not** push, force-push, or
call `gh` / the GitHub API. Output is for the user to read, edit, and use.

## Steps

1. **Resolve branches.**
- Current branch: `git rev-parse --abbrev-ref HEAD`.
- Base branch: use `$ARGUMENTS` if given, else the repo default
(`git remote show <remote>` / the branch the PR will target, typically
`next-cleanup` or `main`).
- If the current branch is `main` or a shared `solidjs-community/*` branch,
**stop** and tell the user to move the work to a feature branch — this
workflow never commits changes there directly.

2. **Survey the change** (read-only):
- `git log --oneline --no-decorate <base>..HEAD`
- `git diff --stat <base>...HEAD`
- Read the actual diff for the non-trivial files so the summary is accurate,
not guessed. Note any breaking changes (removed/renamed exports, changed
signatures).

3. **Draft the title** — a single [Conventional Commit](https://www.conventionalcommits.org)
line: `type(scope): summary`.
- `type` ∈ `feat | fix | docs | refactor | test | perf | chore`.
- This becomes the squash commit subject on the base branch, so write it as a
changelog entry: imperative, specific, no trailing period.
- If the branch spans more than one logical change, say so and suggest
splitting into separate PRs rather than forcing an "and" title.

4. **Draft the body** — the changeset. Structure:
- **Summary** — what changed and why, in prose a reader understands without
the diff.
- **What changed** — bullets of the concrete edits (grouped by area).
- **Breaking** — only if applicable; list each break explicitly.
- **Test plan** — the checks actually run (lint/types/tests) with results, and
anything still pending. Run them if not already run; never fabricate results.

5. **Recommend a merge strategy** (per CONTRIBUTING):
- **Squash** (default) when the branch's commits are scratch/exploratory work.
- **Rebase** only when the branch's own commits are already clean and each is
a meaningful, self-contained unit worth keeping on the base branch.
- State which and one line of why.

## Style rules

- No hard-wrapping the body at a fixed column — one line per paragraph/bullet,
let it reflow (GitHub renders it).
- No `Co-Authored-By` trailer.
- Match the repo's voice: direct, concrete, no filler.

## Output format

Return exactly this, ready to copy:

```
Title:
<conventional-commit title>

Body:
<changeset body>

Merge: <squash|rebase> — <one-line reason>
```

Then stop. Do not push or open the PR unless the user explicitly asks in a
follow-up.
66 changes: 66 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,72 @@ if (context.gl.xr) {
Use full names: `raycaster`, not `rc`. When a name shadows an outer scope,
prefix with `_` to disambiguate (`_raycaster`).

## Git Workflow

The history on `main` is meant to be read by humans. We keep it that way by
letting branches be messy and merges be clean.

### Branch for every change

Never commit directly to `main` or to any shared `solidjs-community` branch.
Create a feature branch (`feat/xr-decoupling`, `fix/resize-render`) and open a
PR from it.

### Your branch is yours; shared branches are not

Commit as often as you like on your own branch — exploration, WIP, and
AI-assisted commits are all fine. Force-push your own PR branch freely to clean
it up (rebase, amend, reorder). **Never** force-push `main` or a shared branch.

The noise stays on the branch; it never has to reach `main` (see merge
strategy). So commit in whatever rhythm keeps you productive.

### One PR, one logical change

A PR should be one feature or one fix. If you're tempted to write "and" in the
title, it's probably two PRs. Smaller PRs squash into cleaner history and are
easier to review and revert.

### Merge strategy

- **Squash — the default.** Use it whenever the branch's commits are scratch
work (the AI-per-prompt case). The whole branch collapses to one commit on
`main`. The granular history isn't lost — GitHub keeps it on the PR page even
after the branch is deleted.
- **Rebase — the exception.** Use it only when the branch's *own* commits are
already clean and each is a meaningful, self-contained unit you want to keep
on `main` (e.g. a multi-phase feature split into `core →` then `consumer`
commits). This puts them on `main` linearly.
- **Never merge-commit.** Merge bubbles are the noise we're avoiding.

### The PR title and body are the changelog

Because we squash, **the PR title becomes the commit subject on `main` and the
PR description becomes the commit body.** They are the permanent, human-readable
record of the change — write them as such, not as a throwaway note.

- **Title — a [Conventional Commit](https://www.conventionalcommits.org):**
`type(scope): summary`, where `type` is one of `feat`, `fix`, `docs`,
`refactor`, `test`, `perf`, `chore`. This is what shows up in `git log main`,
so it doubles as the changeset entry.
- **Body — what changed and why.** Enough that a reader six months out
understands the change without the diff. Note breaking changes explicitly.

```
# ❌ Bad PR title (becomes a useless commit on main)
updates

# ✅ Good PR title
feat(xr): decouple the WebXR loop from core; add createXR
```

### Fixed points

We don't cut prerelease tags. Instead, every push publishes a preview package
via [pkg.pr.new](https://pkg.pr.new), each pinned to a commit SHA — so any
build you're running maps back to an exact commit. A clean, squashed `main` plus
per-commit previews give reliable points to compare against.

## Tooling

### Package Management
Expand Down
Loading
Loading