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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ htmlcov/
*.egg-info/
dist/
build/

# AI tools
.claude
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Claude instructions

@ai-resources/CLAUDE.md

1 change: 1 addition & 0 deletions ai-resources/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.claude/
3 changes: 3 additions & 0 deletions ai-resources/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Codex instructions

@CLAUDE.md
11 changes: 11 additions & 0 deletions ai-resources/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Claude instructions

## All rules

@rules/all.md

## All skills

@skills/fix-vulns/SKILL.md
@skills/link-skills/SKILL.md
@skills/md2pdf/SKILL.md
68 changes: 68 additions & 0 deletions ai-resources/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# ai-resources

A centralised collection of AI coding resources (rules and skills), shareable across multiple repos via `git subtree`.

**Rules** live in [`rules`](./rules/) as focused markdown files.

**Skills** live in [`skills`](./skills/).

> **Other AI tools** (Cursor, Copilot, Windsurf, etc.) use different mechanisms to load rules. Refer to their documentation for how to reference external markdown files.

## Using these resources in your repo

### Add this repo as a subtree

Run this once in your target repo, from the repo root:

```sh
git checkout -b chore/add-ai-resources
git subtree add --prefix ai-resources https://github.com/mcalthrop/ai-resources main --squash
```

`git subtree add` creates a commit automatically, so create a branch first to keep the change reviewable via a PR.

### Import all rules and skills

To import all rules and skills, add a single line to your `CLAUDE.md` or `AGENTS.md`:

```md
@ai-resources/CLAUDE.md
```

### Set up skills as slash commands

Skills become available as slash commands (e.g. `/md2pdf`) once they are symlinked into the consuming repo's `.claude/skills/` directory.

If your `CLAUDE.md` imports `@ai-resources/CLAUDE.md`, Claude already knows how to set up the symlinks. Just tell it:

> link skills

Claude will create the symlinks automatically via the bundled `link-skills` skill.

### Import specific rules

To import only the rules you need, import them to your `CLAUDE.md` or `AGENTS.md`:

```md
@ai-resources/rules/general.md
@ai-resources/rules/pull-requests.md
@ai-resources/rules/conventional-commits.md
@ai-resources/rules/conventional-branch-names.md
```

The tool reads the instructions file automatically, so the imported rules are always active.

### Update the resources

When the resources in this repo change, your repo won't automatically see them.

So to pick them up, create a branch and pull in the latest changes:

```sh
git checkout -b chore/update-ai-resources
git subtree pull --prefix ai-resources https://github.com/mcalthrop/ai-resources main --squash
```

Like `git subtree add`, this creates a commit automatically.

If you are importing individual files, check whether any rules were added, removed, or renamed and update your instructions file accordingly.
8 changes: 8 additions & 0 deletions ai-resources/rules/all.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# All Rules

@general.md
@zsh-node-commands.md
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zsh-node-commands.md is referenced here, but there is no such file under ai-resources/rules/ (the only matching rule file is zsh-bash-commands.md). As written, importing @rules/all.md (and therefore @ai-resources/CLAUDE.md) will fail; update the reference or rename the rule file so the include resolves.

Suggested change
@zsh-node-commands.md
@zsh-bash-commands.md

Copilot uses AI. Check for mistakes.
@code-organisation.md
@pull-requests.md
@conventional-commits.md
@conventional-branch-names.md
4 changes: 4 additions & 0 deletions ai-resources/rules/code-organisation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Code Organisation

- Each function should live in its own file.
- Test files live adjacent to the source file they test, mirroring the name (e.g. `fetchRecipes.ts` → `fetchRecipes.test.ts`).
45 changes: 45 additions & 0 deletions ai-resources/rules/conventional-branch-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Conventional Branch Names

Always name branches following the [Conventional Branch specification](https://conventional-branch.github.io/).

## Format

```txt
<type>/<short-description>
```

Use the same types as Conventional Commits. The short description should be lowercase, hyphen-separated, and concise.

## Types

| Type | Use when |
| ------ | ---------- |
| `feat` | Implementing a new feature |
| `fix` | Fixing a bug |
| `docs` | Documentation-only changes |
| `style` | Formatting or style changes |
| `refactor` | Code restructuring without behaviour change |
| `test` | Adding or updating tests |
| `chore` | Build, dependency, or tooling updates |
| `ci` | CI/CD pipeline changes |
| `perf` | Performance improvements |
| `revert` | Reverting a previous change |

## Rules

- Use only lowercase letters, numbers, and hyphens.
- Keep the description short — ideally 2–5 words.
- Do not include ticket/issue numbers in the branch name unless the project convention requires it.
- Never use `main` or `master` as a base name.

## Examples

```txt
feat/user-authentication
fix/null-pointer-on-login
docs/update-api-reference
chore/upgrade-dependencies
refactor/extract-payment-service
test/add-checkout-unit-tests
ci/add-deploy-workflow
```
50 changes: 50 additions & 0 deletions ai-resources/rules/conventional-commits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Conventional Commits

Always write commit messages following the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/).

## Format

```txt
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```

## Types

| Type | Use when |
| ------ | ---------- |
| `feat` | A new feature |
| `fix` | A bug fix |
| `docs` | Documentation changes only |
| `style` | Formatting, missing semicolons, etc. — no logic change |
| `refactor` | Code change that neither fixes a bug nor adds a feature |
| `test` | Adding or correcting tests |
| `chore` | Build process, dependency, or tooling changes |
| `ci` | CI/CD configuration changes |
| `perf` | Performance improvements |
| `revert` | Reverts a previous commit |

## Rules

- The description must be lowercase and not end with a period.
- Use the imperative mood in the description (e.g. "add feature" not "added feature").
- Keep the description under 72 characters.
- Add a scope in parentheses after the type when it helps clarify the area of change, e.g. `feat(auth): add OAuth2 support`.
- Mark breaking changes with `!` after the type/scope, e.g. `feat!: remove deprecated endpoint`, and include a `BREAKING CHANGE:` footer.

## Examples

```txt
feat(auth): add OAuth2 login support
fix: prevent crash when config file is missing
docs: update installation instructions
chore(deps): upgrade vitest to v2
refactor(api): extract response normalisation to helper
test(checkout): add edge case for empty cart
feat!: remove legacy REST endpoint

BREAKING CHANGE: the /v1/users endpoint has been removed; use /v2/users instead
```
7 changes: 7 additions & 0 deletions ai-resources/rules/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# General Rules

- Do what has been asked; nothing more, nothing less.
- NEVER create files unless they're absolutely necessary for achieving your goal.
- ALWAYS prefer editing an existing file to creating a new one.
- NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested.
- ALWAYS use British English.
36 changes: 36 additions & 0 deletions ai-resources/rules/pull-requests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Pull Requests

## Creating a PR

- ALWAYS create pull requests in draft mode using the `--draft` flag with `gh pr create`.
- ALWAYS show a link to the created pull request.

## After a PR is Merged

Run the following steps after a pull request has been merged:

1. Fetch and prune remote-tracking branches:

```sh
git fetch --all --prune --prune-tags
```

2. Switch to the main branch:

```sh
git checkout main
```

3. Delete the local branch for the merged PR:

```sh
git branch -D <branch-name>
```

4. Pull the latest changes from main:

```sh
git pull origin main
```

5. Install packages using the appropriate package manager for the repo (e.g. `pnpm install`, `npm install`, `yarn install`, `pip install -r requirements.txt`).
12 changes: 12 additions & 0 deletions ai-resources/rules/zsh-bash-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Running Commands with the `bash` shell

When running commands in the `bash` shell:

```sh
zsh -i -c "..."
```
Comment on lines +1 to +7
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rule says it is about running commands with the bash shell, but the recommended invocation is zsh -i -c "..." and the rationale references .zshrc. Please clarify whether this rule is about the Claude bash tool (which may execute via zsh for nvm) or about zsh itself, and update the heading/wording accordingly to avoid confusion.

Copilot uses AI. Check for mistakes.

Reasons:

- `-i`: Forces shell to be interactive. Ensures that the `.zshrc` file is loaded.
- `-c`: Takes the first argument as a command to execute.
54 changes: 54 additions & 0 deletions ai-resources/skills/fix-vulns/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: fix-vulns
description: Check for vulnerabilities with pnpm audit and raise a PR to fix them. Use when the user asks to "fix vulnerabilities", "fix vulns", "audit dependencies", or "fix security issues".
disable-model-invocation: true
allowed-tools: Bash, Read, Edit
---

# fix-vulns

Check for `pnpm` dependency vulnerabilities and raise a PR that addresses all of them.

## Instructions

1. Run the audit:

```bash
zsh -i -c "pnpm audit"
```

2. If no vulnerabilities are found, report that and stop.

3. If vulnerabilities are found, fetch the latest `main` and create a branch:

```bash
git fetch origin main
git checkout -b fix/security-vulnerabilities origin/main
```

4. Attempt to fix all vulnerabilities automatically:

```bash
zsh -i -c "pnpm audit --fix"
```

5. If any vulnerabilities remain after `--fix`, resolve them by manually updating the affected packages to the minimum safe version identified in the audit output:

```bash
zsh -i -c "pnpm update <package-name>"
```

6. Re-run the audit to confirm all vulnerabilities are resolved:

```bash
zsh -i -c "pnpm audit"
```

7. Commit the changes:

```bash
git add pnpm-lock.yaml package.json
git commit -m "fix(deps): resolve pnpm audit vulnerabilities"
```

8. Push the branch and raise a draft PR. The PR body must list every vulnerability that was fixed, including package name, severity, and the resolution applied.
26 changes: 26 additions & 0 deletions ai-resources/skills/link-skills/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: link-skills
description: Link all skills from the ai-resources git subtree into .claude/skills/. Use when the user asks to "link skills", "set up skills from ai-resources", or "link to all skills in the ai-resources subtree".
disable-model-invocation: true
allowed-tools: Bash
---

# link-skills

Create symlinks in `.claude/skills/` for every skill in the `ai-resources` subtree, making them available as slash commands.

## Instructions

1. Confirm that an `ai-resources/skills/` directory exists in the current working directory. If not, abort and tell the user to add the `ai-resources` subtree first.
2. Create `.claude/skills/` in the current working directory if it does not already exist.
3. For each subdirectory in `ai-resources/skills/`, create a relative symlink:

```bash
for skill_dir in ai-resources/skills/*/; do
skill_name=$(basename "$skill_dir")
mkdir -p .claude/skills
ln -sfn "../../ai-resources/skills/$skill_name" ".claude/skills/$skill_name"
done
```

4. Report which symlinks were created.
38 changes: 38 additions & 0 deletions ai-resources/skills/md2pdf/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: md2pdf
description: Convert a Markdown file to PDF. Use when the user asks to convert a .md file to PDF, generate a PDF from Markdown, or run md-to-pdf.
argument-hint: <input.md>
disable-model-invocation: true
allowed-tools: Bash
---

# md2pdf

Convert a Markdown file to PDF using `npx md-to-pdf` with the config bundled in this skill directory.

## Instructions

The user invoked this with: $ARGUMENTS

1. Resolve the input file path from `$ARGUMENTS`. If a relative path is given, resolve it relative to the current working directory.
2. Ensure Chrome is available for Puppeteer:

```bash
zsh -i -c "npx puppeteer browsers install chrome"
```

3. Determine the absolute path to this skill's directory (where this SKILL.md lives) — it contains `md-to-pdf.config.js`.
4. Run the conversion:

```bash
zsh -i -c "npx md-to-pdf --config-file '<skill-dir>/md-to-pdf.config.js' <input-file>"
```

5. Report the path of the generated PDF (same directory as the input file, with a `.pdf` extension).

## Notes

- The config adds a footer with a left-aligned `Generated: <timestamp>`, a centre-aligned filename, and a right-aligned `Page X of Y`.
- Bottom margin is increased to prevent the footer overlapping content.
- On Mac Silicon with an x64 Node install, a "Degraded performance warning" about Rosetta may appear — this is harmless.
- The `zsh -i -c "..."` wrapper ensures the correct Node version from `.nvmrc` is active.
Loading
Loading