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
36 changes: 36 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,52 @@ Follow the [Stimulus Handbook](https://stimulus.hotwired.dev/handbook/introducti
- Follow the red-green-refactor cycle: failing test, minimal fix, then refactor
- Be careful with system/JS tests — avoid patterns that lead to flakiness

## Session recap

When the user says **"recap"**, **"ai recap"**, or runs **`ai/recap`**, review the full conversation and report two parts:

1. **Recap** — what was accomplished this session.
2. **Unresolved** — dropped threads, unanswered questions, unfinished tasks, and unresolved disagreements (from either side).

This is an agent task — NOT the `/audit` skill (design/accessibility review, only on an explicit `/audit`) and NOT `ai/security` (the security scan). The `ai/recap` script only emits the trigger word; the agent does the work per this section.

**Format the Unresolved part as a bulleted list with a count header.**

If nothing is unresolved:
```
- Nothing unresolved
- All tasks completed, questions answered, and threads closed
```

If there are unresolved items:
```
- 3 unresolved items below
- 1. Item title
- Description of what's unresolved
- 2. Item title
- Description of what's unresolved
- 3. Item title
- Description of what's unresolved
```

### After submitting a PR

After creating or submitting a pull request, automatically perform the session recap (Recap + Unresolved) using the format above.

## Quick Commands

See `ai/` directory for executable scripts:

| Command | What it does |
|---|---|
| `ai/recap` | Session recap: accomplishments + unresolved items (see above) |
| `ai/test [args]` | Run RSpec |
| `ai/lint` | Rubocop on all files |
| `ai/lint --fix` | Auto-fix lint issues |
| `ai/server` | Start dev services (web + vite) |
| `ai/console` | Rails console |
| `ai/routes -g pattern` | Search Rails routes |
| `ai/db-migrate` | Run database migrations |
| `ai/security` | Security scan: Brakeman + bundler-audit (mirrors CI) |

> **"ai <name>" means the `ai/` script of that name** (e.g. "ai test" → `ai/test`, "ai security" → `ai/security`) — shell scripts in `ai/`, not slash-command skills. If a referenced `ai/<name>` script doesn't exist, ask what's intended rather than substituting a similarly named skill. (`ai/recap` is special — it triggers the agent **Session recap** behavior above, not a real script's output; never confuse it with the `/audit` design skill or the `ai/security` scan.)
36 changes: 36 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,52 @@ Standard mise activation (`eval "$(mise activate <shell>)"` in your shell rc, pe
- Follow the red-green-refactor cycle: failing test, minimal fix, then refactor
- Be careful with system/JS tests — avoid patterns that lead to flakiness

## Session recap

When the user says **"recap"**, **"ai recap"**, or runs **`ai/recap`**, review the full conversation and report two parts:

1. **Recap** — what was accomplished this session.
2. **Unresolved** — dropped threads, unanswered questions, unfinished tasks, and unresolved disagreements (from either side).

This is an agent task — NOT the `/audit` skill (design/accessibility review, only on an explicit `/audit`) and NOT `ai/security` (the security scan). The `ai/recap` script only emits the trigger word; the agent does the work per this section.

**Format the Unresolved part as a bulleted list with a count header.**

If nothing is unresolved:
```
- Nothing unresolved
- All tasks completed, questions answered, and threads closed
```

If there are unresolved items:
```
- 3 unresolved items below
- 1. Item title
- Description of what's unresolved
- 2. Item title
- Description of what's unresolved
- 3. Item title
- Description of what's unresolved
```

### After submitting a PR

After creating or submitting a pull request, automatically perform the session recap (Recap + Unresolved) using the format above.

## Quick Commands

See `ai/` directory for executable scripts:

| Command | What it does |
|---|---|
| `ai/recap` | Session recap: accomplishments + unresolved items (see above) |
| `ai/test [args]` | Run RSpec |
| `ai/lint` | Rubocop on all files |
| `ai/lint --fix` | Auto-fix lint issues |
| `ai/server` | Start dev services (web + vite) |
| `ai/console` | Rails console |
| `ai/routes -g pattern` | Search Rails routes |
| `ai/db-migrate` | Run database migrations |
| `ai/security` | Security scan: Brakeman + bundler-audit (mirrors CI) |

> **"ai <name>" means the `ai/` script of that name** (e.g. "ai test" → `ai/test`, "ai security" → `ai/security`) — shell scripts in `ai/`, not slash-command skills. If a referenced `ai/<name>` script doesn't exist, ask what's intended rather than substituting a similarly named skill. (`ai/recap` is special — it triggers the agent **Session recap** behavior above, not a real script's output; never confuse it with the `/audit` design skill or the `ai/security` scan.)
7 changes: 7 additions & 0 deletions ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ Quick-reference scripts for common development tasks. Designed for AI agents and

| Command | What it does |
|---|---|
| `ai/recap` | Session recap: accomplishments + unresolved items (agent behavior; see below) |
| `ai/test [args]` | Run RSpec tests (`ai/test spec/models/user_spec.rb:42`) |
| `ai/lint` | Rubocop on all files |
| `ai/lint --fix` | Auto-fix lint issues |
| `ai/server` | Start all dev services (web + vite) |
| `ai/console` | Rails console |
| `ai/routes -g pattern` | Search Rails routes |
| `ai/db-migrate` | Run database migrations |
| `ai/security` | Security scan: Brakeman + bundler-audit (mirrors CI) |

All scripts pass through extra arguments, so `ai/test --fail-fast` works as expected.

Only the commands listed above exist. "ai <name>" refers to one of these `ai/` scripts — not a slash-command skill. Two phrases are special:

- **"ai security"** runs `ai/security` (the security scan above).
- **"ai recap"** (or `ai/recap`, which just prints the trigger word) tells the agent to review the conversation and report two parts: **Recap** (what was accomplished) and **Unresolved** (dropped threads, unanswered questions, unfinished tasks, and disagreements from either side). The agent performs it directly per `CLAUDE.md`. It is never the `/audit` design/accessibility skill.
7 changes: 7 additions & 0 deletions ai/recap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Session recap: triggers the AI to review the conversation and report
# (1) what was accomplished and (2) unresolved items — dropped threads,
# unanswered questions, unfinished tasks, and disagreements from either side.
# This script just prints the trigger word; the agent does the work per CLAUDE.md.
# Not the /audit design skill, and not ai/security (the security scan).
echo "recap"
17 changes: 17 additions & 0 deletions ai/security
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Security scan: Brakeman (Rails static analysis) + bundler-audit (gem CVEs).
# Mirrors the CI security scan. Unrelated to the /audit design/accessibility skill.
# Runs both tools even if the first reports issues, and exits non-zero if either fails.
set -uo pipefail
source "$(dirname "$0")/.ruby-env"

status=0

echo "→ Brakeman — Rails security static analysis"
bin/brakeman --no-pager || status=1

echo
echo "→ bundler-audit — known CVEs in gems"
bin/bundler-audit || status=1

exit $status
Comment on lines +5 to +17