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
95 changes: 95 additions & 0 deletions .claude/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
name: commit
description: Stage relevant files and create a well-formed git commit. Use this when the user asks to commit changes, save work, or create a commit.
---

# Commit Skill

Read [`.claude/skills/writing-style.md`](../writing-style.md) before writing the commit message.

Creates a clean, well-formed commit following this project's conventions.

## Steps

### 1. Check for project hooks

If the repo has a hook runner, ensure it is installed before committing. Common patterns:

```bash
# Husky.Net (dotnet)
if [ -f .husky/task-runner.json ] && [ ! -f .husky/_/husky.sh ]; then
dotnet tool restore && dotnet husky install
fi

# Husky (Node)
# hooks install automatically via npm ci / npm install

# lefthook
if [ -f lefthook.yml ] || [ -f .lefthook.yml ]; then
lefthook install
fi
```

Do not use `--no-verify`.

### 2. Understand what changed

```bash
git status
git diff
git diff --staged
git log --oneline -5
```

### 3. Stage files

Stage specific files by name — never `git add -A` or `git add .` blindly. Exclude:
- `.env` files or anything with secrets/credentials
- Large binaries not already tracked
- Unrelated changes to the task at hand

### 4. Write the commit message

- **First line**: Imperative mood, ≤72 chars, no trailing period. Front-load the outcome — a reader scanning `git log` sees this line only.
- **Body** (optional): One short paragraph explaining *why*, not what. Skip if the title is self-explanatory. Follow the sentence mechanics in `writing-style.md`.
- **Trailer**: Add a `Co-Authored-By:` line that identifies the model that helped write this commit. Use whatever attribution feels accurate — the model name you know yourself to be running as, or simply `Claude` if you are uncertain. The address is always `noreply@anthropic.com`. The point is honest attribution, not a precise version string.

Always pass the message via HEREDOC to avoid shell escaping issues:

```bash
git commit -m "$(cat <<'EOF'
Title here

Optional body explaining why.

Co-Authored-By: Claude <noreply@anthropic.com>
EOF
)"
```

### 5. Handle hook failures

If a git hook fails:
1. Read the error output carefully
2. Fix the underlying issue (formatting, linting, type errors — whatever the hook checks)
3. Re-stage the affected files
4. Create a **new commit** — never `git commit --amend` for a failed commit, and never use `--no-verify`

### 6. Verify success

```bash
git status
```

Confirm a clean working tree.

### 7. Refresh the PR description if one exists

```bash
gh pr view --json number,url,isDraft,baseRefName --jq '{number,url,isDraft,baseRefName}' 2>/dev/null
```

- **No PR** → done. Say nothing.
- **PR exists** → compare the current body against the current diff versus the PR's base branch. A PR description always describes the current diff against the base branch. It is never a log of the commits on the branch and never records the direction the work took. If any section (`## What`, `## Verify`, or the lead paragraph) no longer describes that diff, the description is stale.
- **Stale description** → read and follow [pr](../pr/SKILL.md)'s update path (step 7). Do not hand-edit the body inline from the commit skill. State plainly what was refreshed.
- **Still accurate** → state that the description is still accurate. No edit needed.
118 changes: 118 additions & 0 deletions .claude/skills/issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
name: issue
description: File a well-formed bug report or feature request. Use when the user asks to open an issue, report a bug, or request a feature.
---

# Issue Skill

Read [`.claude/skills/writing-style.md`](../writing-style.md) before writing anything.

Files a GitHub issue that matches the repo's templates, applies correct labels, and checks for duplicates first.

## Steps

### 1. Check for duplicates

Search for near-duplicates before opening anything. Link any you find in the issue body rather than filing a second. Use the full URL form for all links — see `## Linking to issues and pull requests` in [`writing-style.md`](../writing-style.md).

```bash
gh issue list --search "<key terms>" --limit 10
```

### 2. Determine the issue type

- **Bug** — something that used to work stopped, or produces wrong output. Use `bug-report` structure.
- **Feature / enhancement** — something that does not exist yet, or needs to be better. Use `enhancement` structure.

### 3. Write the title

- ≤70 characters, no trailing period
- States the observable problem or the wanted capability — not the internal cause or the implementation

### 4. Write the body

**Bug report:**

```
<One sentence: what went wrong and, briefly, under what condition. Be specific.>

### What happened

<What you saw. Include the command you ran, the input, and the exact output or
error. Commands and error messages go in fenced blocks.>

### How to reproduce

<Minimal steps. A command and the file it ran against is enough if that covers it.
Skip this section if the "What happened" section already makes it reproducible.>

### Version or commit

<Output of the tool's `--version` flag, or the commit SHA if building from source.
This is the single most useful piece of triage data.>
```

**Feature request:**

```
<One sentence: the outcome you want, not the implementation.>

### What is getting in your way

<The concrete limitation. What are you trying to do, and what stops you?
One to three sentences.>

### What would you like instead

<Your proposed change or outcome. If you have a specific implementation in mind,
describe it — but a clear outcome is enough.>

### Anything else

<Examples from other tools, links, screenshots, or context that did not fit above.
Skip this section if there is nothing to add.>
```

Formatting rules:
- Same plain-language rules as PR bodies — active voice, short sentences, no mechanical noun clusters.
- Commands and error messages in fenced blocks.
- Backticks on all identifiers: flags, config keys, file paths, method names.
- Skip any section that has nothing to say — a blank section adds noise, not structure.

### 5. Choose labels

Apply the labels this repo defines. Common defaults:

1. **Type** (required): `bug` or `enhancement`
2. **Area** (one, if the repo defines area labels): pick the label that matches the affected subsystem
3. **`needs triage`** (if the repo uses it)

Do not invent new labels. Check `.github/` or the repo's CONTRIBUTING guide for the label set.

### 6. Create the issue

One call — title, labels, and body together:

```bash
gh issue create \
--title "<title>" \
--label "bug,needs triage" \
--body "$(cat <<'EOF'
<lead sentence>

### What happened

...

### Version or commit

...
EOF
)"
```

Replace `bug` with `enhancement` for feature requests. Omit area or triage labels if the repo does not use them.

### 7. Return the issue URL

Always print the URL so the user can open it directly.
160 changes: 160 additions & 0 deletions .claude/skills/pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
name: pr
description: Create a GitHub pull request with a focused why/what body. Use when the user asks to open a PR, create a pull request, or ship a branch.
---

# PR Skill

Read [`.claude/skills/writing-style.md`](../writing-style.md) before writing anything.

Creates a GitHub PR body that a newcomer can orient from in under a minute: front-loaded outcome, grounded Why, behaviour-led What, verifiable by the reviewer.

## Steps

### 1. Understand the branch

```bash
git status
git log main..HEAD --oneline
git diff main...HEAD --stat
```

### 2. Commit uncommitted work if needed

If the working tree has changes that belong in this PR, read and follow [commit](../commit/SKILL.md) first. Do not commit inline. Do not skip hooks.

### 3. Push (if needed)

```bash
git push -u origin HEAD
```

### 4. Write the PR title

- ≤70 characters, imperative mood, no trailing period
- States what changed at a human level — not a file list, not a symbol name
- No `[bug]` / `[feature]` / `[chore]` prefixes — the label carries the type

### 5. Write the PR body

Required structure:

```
<One or two sentences, no heading. What this changes and the effect.
A newcomer reads only this and knows whether the PR concerns them.>

**Prompt summary:** <One paragraph, two to three sentences. What the author was asked
to do in their own framing — the goal behind the branch, not the diff. Present tense,
active voice. This is the ask; ## Why is the problem in the code. They are not
interchangeable and neither restates the other. Omit only when the branch has no
originating ask.>

## Why
<Two to four sentences. The concrete failure or gap. Active voice, present tense
for current behaviour. Do not open with the history of a prior PR.>

## What

#### <Conceptual label — not a filename>
<Prose paragraph. Group by what changed conceptually, not by which files moved.
Lead with behaviour. Name a symbol only when the reviewer needs it to find the code.
Two to four sentences. Three to five sections total.>

## Verify
<How a reviewer confirms this locally. Use real commands they would run.
If there is no clear local verification step, omit this section entirely.
Do not list CI checks or scripts an agent would run to prove their own work —
those are not reviewer steps.>
```

Conditional add-ons — each is one or two sentences with a bold lead-in, no heading:

- **Breaking** — what a consumer must change and when it bites them.
- **Out of scope** — a gap this PR deliberately leaves, so a reviewer does not raise it as a finding.
- **Risk** — shared or production state this touches. Required when the change reaches infrastructure, credentials, or shared data stores.
- **Stack** — position and links when this is one of several stacked PRs: `3 of 5, on top of [#42](https://github.com/org/repo/pull/42)`. A bare `Stack: 3/5` with no links is not enough.

**Do not** include bullet lists of changed files. Do not summarize what the diff already states plainly.

### 6. Apply labels

Apply the labels this repo uses. Common defaults:

| Label | Use when |
|---|---|
| `bug` | A defect in existing behaviour is fixed |
| `enhancement` or `feature` | A capability is added or improved |
| `chore` | Cleanup, refactor, internal restructure — no user-visible change |
| `documentation` | Docs-only change |
| `dependencies` | Dependency version bumps |

Check `.github/workflows/` or the repo's CONTRIBUTING guide for any enforced label policy before creating the PR.

### 7. Check whether a PR already exists

```bash
gh pr view --json number,url,baseRefName --jq '{number,url,baseRefName}' 2>/dev/null
```

**If a PR exists — update it.**

Rebuild the body from the cumulative diff against the PR's own base branch (not a hardcoded `main`):

```bash
git diff origin/<baseRefName>...HEAD --stat
git diff origin/<baseRefName>...HEAD
```

Write the description of **the current diff against the base** — never a log of the commits on the branch and never an "update" or "addendum" appended to the old body. Any section of the old body that no longer matches the diff is wrong, not history. Replace it.

- Preserve the original `**Prompt summary:**` verbatim unless the ask itself changed; extend it rather than replace it when scope was added.
- Reassess the label — added commits can shift a `chore` to a `bug`.
- Apply in one call:

```bash
gh pr edit --title "<title>" --body "$(cat <<'EOF'
<new body>
EOF
)"
```

Add or remove the label only if it changed:

```bash
gh pr edit --add-label "<new-label>" --remove-label "<old-label>"
```

**If no PR exists — create it.** Proceed to step 8.

### 8. Create the PR

One call — title, label, and body together. No follow-up `gh pr edit`:

```bash
gh pr create --title "<title>" --label "<label>" --body "$(cat <<'EOF'
<lead sentence(s)>

**Prompt summary:** ...

## Why

...

## What

#### ...

...

## Verify

```bash
<command>
```
EOF
)"
```

### 9. Return the PR URL

Always print the URL so the user can open it directly.
Loading
Loading