@next-friday/create-app 2.1.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/package.json +1 -1
  2. package/templates/base/.agents/agents.json +7 -0
  3. package/templates/base/.agents/hooks/agent-format-after-edit.sh +15 -0
  4. package/templates/base/.agents/hooks/agent-production-gate.sh +10 -0
  5. package/templates/base/.agents/hooks/agent-test-edit-gate.sh +25 -0
  6. package/templates/base/.agents/review.md +21 -0
  7. package/templates/base/.agents/rules/no-suppression.md +1 -1
  8. package/templates/base/.agents/skills/babysit-pr/SKILL.md +8 -0
  9. package/templates/base/.agents/skills/brand-policy/SKILL.md +12 -0
  10. package/templates/base/.agents/skills/compliance-policy/SKILL.md +12 -0
  11. package/templates/base/.agents/skills/security-policy/SKILL.md +12 -0
  12. package/templates/base/.agents/skills/ux-policy/SKILL.md +12 -0
  13. package/templates/base/.agents/skills/write-intent/SKILL.md +30 -0
  14. package/templates/base/.agents/skills/write-spec/SKILL.md +12 -0
  15. package/templates/base/.claude/managed-settings.example.json +26 -0
  16. package/templates/base/.claude/settings.json +31 -0
  17. package/templates/base/.claude/skills/babysit-pr/SKILL.md +8 -0
  18. package/templates/base/.claude/skills/brand-policy/SKILL.md +12 -0
  19. package/templates/base/.claude/skills/compliance-policy/SKILL.md +12 -0
  20. package/templates/base/.claude/skills/security-policy/SKILL.md +12 -0
  21. package/templates/base/.claude/skills/ux-policy/SKILL.md +12 -0
  22. package/templates/base/.claude/skills/write-intent/SKILL.md +30 -0
  23. package/templates/base/.claude/skills/write-spec/SKILL.md +12 -0
  24. package/templates/base/.cursor/BUGBOT.md +1 -0
  25. package/templates/base/.cursor/hooks.json +15 -0
  26. package/templates/base/.cursor/rules/no-suppression.mdc +1 -1
  27. package/templates/base/.cursor/skills/babysit-pr/SKILL.md +8 -0
  28. package/templates/base/.cursor/skills/brand-policy/SKILL.md +12 -0
  29. package/templates/base/.cursor/skills/compliance-policy/SKILL.md +12 -0
  30. package/templates/base/.cursor/skills/security-policy/SKILL.md +12 -0
  31. package/templates/base/.cursor/skills/ux-policy/SKILL.md +12 -0
  32. package/templates/base/.cursor/skills/write-intent/SKILL.md +30 -0
  33. package/templates/base/.cursor/skills/write-spec/SKILL.md +12 -0
  34. package/templates/base/.github/workflows/agent-evals.yml +128 -0
  35. package/templates/base/.github/workflows/claude.yml +39 -0
  36. package/templates/base/.github/zizmor.yml +1 -1
  37. package/templates/base/REVIEW.md +21 -0
  38. package/templates/base/SETUP.md +108 -0
  39. package/templates/base/bands.yaml +10 -0
  40. package/templates/base/evals/README.md +15 -0
  41. package/templates/base/evals/check.sh +17 -0
  42. package/templates/base/intent/README.md +8 -0
  43. package/templates/base/lessons/README.md +3 -0
  44. package/templates/base/scripts/sync-agent-rules.ts +111 -1
  45. package/templates/nestjs/.agents/agents/verifier.md +1 -0
  46. package/templates/nestjs/.claude/agents/verifier.md +7 -0
  47. package/templates/nestjs/.cursor/agents/verifier.md +7 -0
  48. package/templates/nestjs/.github/workflows/ci.yml +44 -0
  49. package/templates/nestjs/AGENTS.md +17 -4
  50. package/templates/nestjs/README.md +1 -16
  51. package/templates/nextjs/.agents/agents/verifier.md +1 -0
  52. package/templates/nextjs/.agents/mcp.json +8 -0
  53. package/templates/nextjs/.claude/agents/verifier.md +7 -0
  54. package/templates/nextjs/.cursor/agents/verifier.md +7 -0
  55. package/templates/nextjs/.cursor/mcp.json +8 -0
  56. package/templates/nextjs/.github/workflows/ci.yml +44 -0
  57. package/templates/nextjs/.mcp.json +8 -0
  58. package/templates/nextjs/AGENTS.md +17 -4
  59. package/templates/nextjs/README.md +1 -16
  60. package/templates/nodejs/.agents/agents/verifier.md +1 -0
  61. package/templates/nodejs/.claude/agents/verifier.md +7 -0
  62. package/templates/nodejs/.cursor/agents/verifier.md +7 -0
  63. package/templates/nodejs/.github/workflows/ci.yml +44 -0
  64. package/templates/nodejs/AGENTS.md +17 -4
  65. package/templates/nodejs/README.md +1 -16
  66. package/templates/payload/.agents/agents/verifier.md +1 -0
  67. package/templates/payload/.agents/mcp.json +8 -0
  68. package/templates/payload/.claude/agents/verifier.md +7 -0
  69. package/templates/payload/.cursor/agents/verifier.md +7 -0
  70. package/templates/payload/.cursor/mcp.json +8 -0
  71. package/templates/payload/.github/workflows/ci.yml +44 -0
  72. package/templates/payload/.mcp.json +8 -0
  73. package/templates/payload/AGENTS.md +17 -4
  74. package/templates/payload/README.md +1 -16
  75. package/templates/turborepo/.agents/agents/verifier.md +1 -0
  76. package/templates/turborepo/.agents/mcp.json +8 -0
  77. package/templates/turborepo/.claude/agents/verifier.md +7 -0
  78. package/templates/turborepo/.cursor/agents/verifier.md +7 -0
  79. package/templates/turborepo/.cursor/mcp.json +8 -0
  80. package/templates/turborepo/.github/workflows/ci.yml +44 -0
  81. package/templates/turborepo/.mcp.json +8 -0
  82. package/templates/turborepo/AGENTS.md +17 -4
  83. package/templates/turborepo/README.md +1 -16
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ tools: Bash, Read
5
+ ---
6
+
7
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ readonly: true
5
+ ---
6
+
7
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -172,6 +172,50 @@ jobs:
172
172
  environment: dev
173
173
  commit_sha: ${{ github.sha }}
174
174
 
175
+ triage:
176
+ name: Triage failed build
177
+ needs:
178
+ - checks
179
+ - image
180
+ if: failure() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
181
+ runs-on: ubuntu-latest
182
+ timeout-minutes: 15
183
+ permissions:
184
+ actions: read # Needed to read the logs of the failed jobs.
185
+ id-token: write # Needed to authenticate to Anthropic with the workflow's OIDC token.
186
+ pull-requests: write # Needed to post the summary on the pull request.
187
+ steps:
188
+ - name: Collect the build log
189
+ env:
190
+ GH_TOKEN: ${{ github.token }}
191
+ REPOSITORY: ${{ github.repository }}
192
+ RUN_ID: ${{ github.run_id }}
193
+ run: |
194
+ mkdir -p out
195
+ for job in $(gh api "repos/$REPOSITORY/actions/runs/$RUN_ID/jobs" --paginate --jq '.jobs[] | select(.conclusion == "failure") | .id'); do
196
+ gh api "repos/$REPOSITORY/actions/jobs/$job/logs" >> out/build.log
197
+ done
198
+ - name: Triage failed build
199
+ id: triage
200
+ uses: anthropics/claude-code-action@61a9c274fa7110a66dfafc1bbbced03833eb25fe # v1.0.269
201
+ with:
202
+ anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
203
+ anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
204
+ prompt: >
205
+ Read the build log at out/build.log. Identify the most
206
+ likely cause, say whether the failure looks flaky or real, and write a
207
+ three-line summary for the PR thread.
208
+ claude_args: >-
209
+ --allowedTools "Read"
210
+ --json-schema '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}'
211
+ - name: Post the summary
212
+ env:
213
+ GH_TOKEN: ${{ github.token }}
214
+ PR_NUMBER: ${{ github.event.pull_request.number }}
215
+ REPOSITORY: ${{ github.repository }}
216
+ SUMMARY: ${{ fromJSON(steps.triage.outputs.structured_output).summary }}
217
+ run: gh pr comment "$PR_NUMBER" --repo "$REPOSITORY" --body "$SUMMARY"
218
+
175
219
  ci:
176
220
  name: All Checks
177
221
  if: always()
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -14,19 +14,32 @@ Next.js App Router web app with React and Tailwind CSS, in TypeScript on pnpm an
14
14
  | Every check | `pnpm verify` |
15
15
  | Render rules after a change | `pnpm rules:sync` |
16
16
 
17
- ## How it fits together
17
+ ## Verifying your work
18
+
19
+ - Build: `pnpm build` (prints the `Route (app)` table)
20
+ - Test: `pnpm test:coverage` (all green, then the coverage summary; never skip or delete a failing test)
21
+ - Lint: `pnpm verify:static` (ESLint allows zero warnings; prints `✔ no dependency violations found`)
22
+
23
+ Run all three before reporting any task complete, and paste the output. `pnpm verify` runs all three.
24
+ If a test fails, fix the code, not the test.
25
+
26
+ ## Architecture
18
27
 
19
28
  - Routes live in `app/`. `app/health/route.ts` serves `/health`.
20
29
  - `next.config.ts` builds `output: "standalone"`, enables Cache Components, and sets the security headers. `pnpm start` copies the static assets into `.next/standalone` and serves it.
21
30
 
22
- ## Mandatory rules
31
+ ## Conventions
23
32
 
24
- 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
33
+ 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, or a skill or subagent in `.agents/skills/` or `.agents/agents/`, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
25
34
  2. **Put unit tests next to the code as `app/**/*.test.{ts,tsx}` and Playwright end-to-end tests in `test/` as `*.e2e.test.ts`.** Vitest collects only the first pattern.
26
35
  3. **Ask the user before adding component tests.** They need a DOM test environment, and Vitest runs in Node.js.
27
36
  4. **Read configuration from environment variables and fail when one is missing.** Document each variable in `.env.example`.
37
+ 5. **Start from the accepted spec, in plan mode.** Claude Code starts every session in plan mode (`.claude/settings.json`); in Cursor, switch to Plan Mode before the first edit. Give the plan the change's `intent/<change>/intent.md` and `spec.md`, and have it name the files that change, the order of the work, and the tests that prove it. Commit the approved plan as `intent/<change>/plan.md`. When implementation departs from the plan, update `plan.md` in the same commit.
38
+ 6. **Start a bug fix with a failing test.** Reproduce the bug as a test, run it, and confirm it fails for the reason you expect. Commit that test. Then create `.git/bug-fix-in-progress`, so `.agents/hooks/agent-test-edit-gate.sh` blocks test edits, and make the test pass without editing it. Delete `.git/bug-fix-in-progress` when the fix is done.
39
+
40
+ ## Things Claude gets wrong
28
41
 
29
- ## Known pitfalls
42
+ When Claude makes a mistake twice, add the correction here.
30
43
 
31
44
  - **First end-to-end run**: run `pnpm exec playwright install chromium` once. `pnpm test:e2e` starts the development server unless one is already running.
32
45
  - **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
@@ -12,22 +12,7 @@ pnpm dev
12
12
 
13
13
  ## After creating a project from this template
14
14
 
15
- 1. Install gitleaks and jq (see [CONTRIBUTING.md](CONTRIBUTING.md)). Make the first commit on `main` and push it. The Git hooks allow only this first commit and push on `main`; work on branches after that.
16
-
17
- ```sh
18
- git add --all
19
- git commit -m "chore(repo): start from template"
20
- git push --set-upstream origin main
21
- ```
22
-
23
- 2. Add your team as the owner of every file in `.github/CODEOWNERS`, and replace the owner placeholder in `.github/zizmor.yml`.
24
- 3. Replace the template's description and owner: `package.json#description`, `repository.url`, and `author`, and the `Next Friday Next.js template` text in `app/layout.tsx`, `app/page.tsx`, and their tests. Change `license` from `UNLICENSED` if the project is open source.
25
- 4. In the repository settings:
26
- - **Actions → General → Workflow permissions:** select **Read repository contents and packages permissions**. Every workflow requests the extra permissions it needs.
27
- - **Advanced Security:** enable private vulnerability reporting, Dependabot alerts, Dependabot security updates, secret scanning, and push protection. `SECURITY.md` sends reporters to private vulnerability reporting.
28
- - **Cursor Bugbot:** enable the repository at [Bugbot](https://cursor.com/automations/from-cursor/bugbot). Bugbot reviews pull requests against the rules linked from `.cursor/BUGBOT.md`.
29
- - **Rules → Rulesets:** protect `main` with squash merges only, a linear history, no force pushes or deletion, and the required checks `All Checks` and `Validate pull request title`. Rulesets in a private repository need GitHub Pro, Team, or Enterprise; on GitHub Free, make the repository public or upgrade.
30
- - Create the `needs triage` label, which the issue forms apply: `gh label create "needs triage"`.
15
+ Follow [SETUP.md](SETUP.md) in order. It sets up the repository, the reviews, and the AI-native SDLC. In step 1, also replace the `Next Friday Next.js template` text in `app/layout.tsx`, `app/page.tsx`, and their tests.
31
16
 
32
17
  ## Scripts
33
18
 
@@ -0,0 +1 @@
1
+ Start the app with `pnpm start:dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ tools: Bash, Read
5
+ ---
6
+
7
+ Start the app with `pnpm start:dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ readonly: true
5
+ ---
6
+
7
+ Start the app with `pnpm start:dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -164,6 +164,50 @@ jobs:
164
164
  environment: dev
165
165
  commit_sha: ${{ github.sha }}
166
166
 
167
+ triage:
168
+ name: Triage failed build
169
+ needs:
170
+ - checks
171
+ - image
172
+ if: failure() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
173
+ runs-on: ubuntu-latest
174
+ timeout-minutes: 15
175
+ permissions:
176
+ actions: read # Needed to read the logs of the failed jobs.
177
+ id-token: write # Needed to authenticate to Anthropic with the workflow's OIDC token.
178
+ pull-requests: write # Needed to post the summary on the pull request.
179
+ steps:
180
+ - name: Collect the build log
181
+ env:
182
+ GH_TOKEN: ${{ github.token }}
183
+ REPOSITORY: ${{ github.repository }}
184
+ RUN_ID: ${{ github.run_id }}
185
+ run: |
186
+ mkdir -p out
187
+ for job in $(gh api "repos/$REPOSITORY/actions/runs/$RUN_ID/jobs" --paginate --jq '.jobs[] | select(.conclusion == "failure") | .id'); do
188
+ gh api "repos/$REPOSITORY/actions/jobs/$job/logs" >> out/build.log
189
+ done
190
+ - name: Triage failed build
191
+ id: triage
192
+ uses: anthropics/claude-code-action@61a9c274fa7110a66dfafc1bbbced03833eb25fe # v1.0.269
193
+ with:
194
+ anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
195
+ anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
196
+ prompt: >
197
+ Read the build log at out/build.log. Identify the most
198
+ likely cause, say whether the failure looks flaky or real, and write a
199
+ three-line summary for the PR thread.
200
+ claude_args: >-
201
+ --allowedTools "Read"
202
+ --json-schema '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}'
203
+ - name: Post the summary
204
+ env:
205
+ GH_TOKEN: ${{ github.token }}
206
+ PR_NUMBER: ${{ github.event.pull_request.number }}
207
+ REPOSITORY: ${{ github.repository }}
208
+ SUMMARY: ${{ fromJSON(steps.triage.outputs.structured_output).summary }}
209
+ run: gh pr comment "$PR_NUMBER" --repo "$REPOSITORY" --body "$SUMMARY"
210
+
167
211
  ci:
168
212
  name: All Checks
169
213
  if: always()
@@ -13,18 +13,31 @@ TypeScript HTTP service on `node:http`, without a framework, on pnpm and Node.js
13
13
  | Every check | `pnpm verify` |
14
14
  | Render rules after a change | `pnpm rules:sync` |
15
15
 
16
- ## How it fits together
16
+ ## Verifying your work
17
+
18
+ - Build: `pnpm build` (prints nothing after `$ tsc -p tsconfig.build.json`)
19
+ - Test: `pnpm test:coverage` (all green, then the coverage summary; never skip or delete a failing test)
20
+ - Lint: `pnpm verify:static` (ESLint allows zero warnings; prints `✔ no dependency violations found`)
21
+
22
+ Run all three before reporting any task complete, and paste the output. `pnpm verify` runs all three.
23
+ If a test fails, fix the code, not the test.
24
+
25
+ ## Architecture
17
26
 
18
27
  - `src/main.ts` starts `createAppServer()` from `src/server.ts` on `parsePort(process.env.PORT)`, and on `SIGTERM` or `SIGINT` stops accepting connections and closes any left after 10 seconds.
19
28
  - `src/server.ts` answers `GET` and `HEAD` `/health` and returns 404 for every other request. Routes go there.
20
29
 
21
- ## Mandatory rules
30
+ ## Conventions
22
31
 
23
- 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
32
+ 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, or a skill or subagent in `.agents/skills/` or `.agents/agents/`, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
24
33
  2. **Put tests next to the code as `src/**/*.test.ts`.** Vitest collects only that pattern.
25
34
  3. **Read configuration from environment variables and fail when one is missing**, as `parsePort` does. Document each variable in `.env.example`; `pnpm start` and `pnpm start:dev` load `.env`.
35
+ 4. **Start from the accepted spec, in plan mode.** Claude Code starts every session in plan mode (`.claude/settings.json`); in Cursor, switch to Plan Mode before the first edit. Give the plan the change's `intent/<change>/intent.md` and `spec.md`, and have it name the files that change, the order of the work, and the tests that prove it. Commit the approved plan as `intent/<change>/plan.md`. When implementation departs from the plan, update `plan.md` in the same commit.
36
+ 5. **Start a bug fix with a failing test.** Reproduce the bug as a test, run it, and confirm it fails for the reason you expect. Commit that test. Then create `.git/bug-fix-in-progress`, so `.agents/hooks/agent-test-edit-gate.sh` blocks test edits, and make the test pass without editing it. Delete `.git/bug-fix-in-progress` when the fix is done.
37
+
38
+ ## Things Claude gets wrong
26
39
 
27
- ## Known pitfalls
40
+ When Claude makes a mistake twice, add the correction here.
28
41
 
29
42
  - **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
30
43
 
@@ -14,22 +14,7 @@ The server listens on the port set by `PORT` in `.env`, which the CLI created fr
14
14
 
15
15
  ## After creating a project from this template
16
16
 
17
- 1. Install gitleaks and jq (see [CONTRIBUTING.md](CONTRIBUTING.md)). Make the first commit on `main` and push it. The Git hooks allow only this first commit and push on `main`; work on branches after that.
18
-
19
- ```sh
20
- git add --all
21
- git commit -m "chore(repo): start from template"
22
- git push --set-upstream origin main
23
- ```
24
-
25
- 2. Add your team as the owner of every file in `.github/CODEOWNERS`, and replace the owner placeholder in `.github/zizmor.yml`.
26
- 3. Replace the template's description and owner: `package.json#description`, `repository.url`, and `author`. Change `license` from `UNLICENSED` if the project is open source.
27
- 4. In the repository settings:
28
- - **Actions → General → Workflow permissions:** select **Read repository contents and packages permissions**. Every workflow requests the extra permissions it needs.
29
- - **Advanced Security:** enable private vulnerability reporting, Dependabot alerts, Dependabot security updates, secret scanning, and push protection. `SECURITY.md` sends reporters to private vulnerability reporting.
30
- - **Cursor Bugbot:** enable the repository at [Bugbot](https://cursor.com/automations/from-cursor/bugbot). Bugbot reviews pull requests against the rules linked from `.cursor/BUGBOT.md`.
31
- - **Rules → Rulesets:** protect `main` with squash merges only, a linear history, no force pushes or deletion, and the required checks `All Checks` and `Validate pull request title`. Rulesets in a private repository need GitHub Pro, Team, or Enterprise; on GitHub Free, make the repository public or upgrade.
32
- - Create the `needs triage` label, which the issue forms apply: `gh label create "needs triage"`.
17
+ Follow [SETUP.md](SETUP.md) in order. It sets up the repository, the reviews, and the AI-native SDLC.
33
18
 
34
19
  ## Scripts
35
20
 
@@ -0,0 +1 @@
1
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ tools: Bash, Read
5
+ ---
6
+
7
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ readonly: true
5
+ ---
6
+
7
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -189,6 +189,50 @@ jobs:
189
189
  environment: dev
190
190
  commit_sha: ${{ github.sha }}
191
191
 
192
+ triage:
193
+ name: Triage failed build
194
+ needs:
195
+ - checks
196
+ - image
197
+ if: failure() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
198
+ runs-on: ubuntu-latest
199
+ timeout-minutes: 15
200
+ permissions:
201
+ actions: read # Needed to read the logs of the failed jobs.
202
+ id-token: write # Needed to authenticate to Anthropic with the workflow's OIDC token.
203
+ pull-requests: write # Needed to post the summary on the pull request.
204
+ steps:
205
+ - name: Collect the build log
206
+ env:
207
+ GH_TOKEN: ${{ github.token }}
208
+ REPOSITORY: ${{ github.repository }}
209
+ RUN_ID: ${{ github.run_id }}
210
+ run: |
211
+ mkdir -p out
212
+ for job in $(gh api "repos/$REPOSITORY/actions/runs/$RUN_ID/jobs" --paginate --jq '.jobs[] | select(.conclusion == "failure") | .id'); do
213
+ gh api "repos/$REPOSITORY/actions/jobs/$job/logs" >> out/build.log
214
+ done
215
+ - name: Triage failed build
216
+ id: triage
217
+ uses: anthropics/claude-code-action@61a9c274fa7110a66dfafc1bbbced03833eb25fe # v1.0.269
218
+ with:
219
+ anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
220
+ anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
221
+ prompt: >
222
+ Read the build log at out/build.log. Identify the most
223
+ likely cause, say whether the failure looks flaky or real, and write a
224
+ three-line summary for the PR thread.
225
+ claude_args: >-
226
+ --allowedTools "Read"
227
+ --json-schema '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}'
228
+ - name: Post the summary
229
+ env:
230
+ GH_TOKEN: ${{ github.token }}
231
+ PR_NUMBER: ${{ github.event.pull_request.number }}
232
+ REPOSITORY: ${{ github.repository }}
233
+ SUMMARY: ${{ fromJSON(steps.triage.outputs.structured_output).summary }}
234
+ run: gh pr comment "$PR_NUMBER" --repo "$REPOSITORY" --body "$SUMMARY"
235
+
192
236
  ci:
193
237
  name: All Checks
194
238
  if: always()
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -16,20 +16,33 @@ Payload CMS on Next.js App Router and PostgreSQL, in TypeScript on pnpm and Node
16
16
  | Every check | `pnpm verify` |
17
17
  | Render rules after a change | `pnpm rules:sync` |
18
18
 
19
- ## How it fits together
19
+ ## Verifying your work
20
+
21
+ - Build: `pnpm build` (prints the `Route (app)` table)
22
+ - Test: `pnpm test:coverage` (all green, then the coverage summary; never skip or delete a failing test)
23
+ - Lint: `pnpm verify:static` (ESLint allows zero warnings; prints `✔ no dependency violations found`)
24
+
25
+ Run all three before reporting any task complete, and paste the output. `pnpm verify` runs all three.
26
+ If a test fails, fix the code, not the test.
27
+
28
+ ## Architecture
20
29
 
21
30
  - `src/payload.config.ts` wires the collections in `src/collections/` to PostgreSQL. The site lives in `src/app/(frontend)/`, and `src/app/health/route.ts` serves `/health`.
22
31
  - In development, Payload applies collection changes to the database directly. In production, the server applies the migrations in `src/migrations/` when it starts.
23
32
 
24
- ## Mandatory rules
33
+ ## Conventions
25
34
 
26
- 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
35
+ 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, or a skill or subagent in `.agents/skills/` or `.agents/agents/`, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
27
36
  2. **Change the schema only through collections, then regenerate and commit.** Payload generates `src/app/(payload)/`, `src/payload-types.ts`, and `src/migrations/`; run `pnpm generate:types`, `pnpm generate:importmap`, and `pnpm migrate:create <name>`. Do not edit those files by hand.
28
37
  3. **Put unit tests next to the code as `src/**/*.test.{ts,tsx}` and Playwright end-to-end tests in `test/` as `*.e2e.test.ts`.** Vitest collects only the first pattern.
29
38
  4. **Ask the user before adding component tests.** They need a DOM test environment, and Vitest runs in Node.js.
30
39
  5. **Read configuration through `requireEnvironment` in `src/environment.ts`.** Document each variable in `.env.example`.
40
+ 6. **Start from the accepted spec, in plan mode.** Claude Code starts every session in plan mode (`.claude/settings.json`); in Cursor, switch to Plan Mode before the first edit. Give the plan the change's `intent/<change>/intent.md` and `spec.md`, and have it name the files that change, the order of the work, and the tests that prove it. Commit the approved plan as `intent/<change>/plan.md`. When implementation departs from the plan, update `plan.md` in the same commit.
41
+ 7. **Start a bug fix with a failing test.** Reproduce the bug as a test, run it, and confirm it fails for the reason you expect. Commit that test. Then create `.git/bug-fix-in-progress`, so `.agents/hooks/agent-test-edit-gate.sh` blocks test edits, and make the test pass without editing it. Delete `.git/bug-fix-in-progress` when the fix is done.
42
+
43
+ ## Things Claude gets wrong
31
44
 
32
- ## Known pitfalls
45
+ When Claude makes a mistake twice, add the correction here.
33
46
 
34
47
  - **Database for `pnpm dev` and end-to-end tests**: both need a PostgreSQL database in `DATABASE_URL` and `PAYLOAD_SECRET` in `.env`; the README lists every variable. Run `pnpm exec playwright install chromium` once before the first `pnpm test:e2e`.
35
48
  - **Agent shell gate**: `.agents/hooks/agent-shell-gate.sh` blocks a shell command that writes to a protected path such as `.agents`, `.cursor`, `.claude/rules`, or `.husky`. It is a convenience, not a security boundary: CI and code-owner review are the boundary.
@@ -24,22 +24,7 @@ In development, Payload applies collection changes to the database directly. In
24
24
 
25
25
  ## After creating a project from this template
26
26
 
27
- 1. Install gitleaks and jq (see [CONTRIBUTING.md](CONTRIBUTING.md)). Make the first commit on `main` and push it. The Git hooks allow only this first commit and push on `main`; work on branches after that.
28
-
29
- ```sh
30
- git add --all
31
- git commit -m "chore(repo): start from template"
32
- git push --set-upstream origin main
33
- ```
34
-
35
- 2. Add your team as the owner of every file in `.github/CODEOWNERS`, and replace the owner placeholder in `.github/zizmor.yml`.
36
- 3. Replace the template's description and owner: `package.json#description`, `repository.url`, and `author`, and the `Next Friday Payload template` text in `src/app/(frontend)/layout.tsx`, `src/app/(frontend)/page.tsx`, and their tests. Change `license` from `UNLICENSED` if the project is open source.
37
- 4. In the repository settings:
38
- - **Actions → General → Workflow permissions:** select **Read repository contents and packages permissions**. Every workflow requests the extra permissions it needs.
39
- - **Advanced Security:** enable private vulnerability reporting, Dependabot alerts, Dependabot security updates, secret scanning, and push protection. `SECURITY.md` sends reporters to private vulnerability reporting.
40
- - **Cursor Bugbot:** enable the repository at [Bugbot](https://cursor.com/automations/from-cursor/bugbot). Bugbot reviews pull requests against the rules linked from `.cursor/BUGBOT.md`.
41
- - **Rules → Rulesets:** protect `main` with squash merges only, a linear history, no force pushes or deletion, and the required checks `All Checks` and `Validate pull request title`. Rulesets in a private repository need GitHub Pro, Team, or Enterprise; on GitHub Free, make the repository public or upgrade.
42
- - Create the `needs triage` label, which the issue forms apply: `gh label create "needs triage"`.
27
+ Follow [SETUP.md](SETUP.md) in order. It sets up the repository, the reviews, and the AI-native SDLC. In step 1, also replace the `Next Friday Payload template` text in `src/app/(frontend)/layout.tsx`, `src/app/(frontend)/page.tsx`, and their tests.
43
28
 
44
29
  ## Scripts
45
30
 
@@ -0,0 +1 @@
1
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ tools: Bash, Read
5
+ ---
6
+
7
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: verifier
3
+ description: Runs the app and checks the change works before the session reports done
4
+ readonly: true
5
+ ---
6
+
7
+ Start the app with `pnpm dev`. Exercise the changed behavior and the two nearest neighboring flows. Report what you ran, what you saw, and any behavior that does not match plan.md. Do not fix anything; report only.
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -297,6 +297,50 @@ jobs:
297
297
  environment: dev
298
298
  commit_sha: ${{ github.sha }}
299
299
 
300
+ triage:
301
+ name: Triage failed build
302
+ needs:
303
+ - checks
304
+ - image
305
+ if: failure() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
306
+ runs-on: ubuntu-latest
307
+ timeout-minutes: 15
308
+ permissions:
309
+ actions: read # Needed to read the logs of the failed jobs.
310
+ id-token: write # Needed to authenticate to Anthropic with the workflow's OIDC token.
311
+ pull-requests: write # Needed to post the summary on the pull request.
312
+ steps:
313
+ - name: Collect the build log
314
+ env:
315
+ GH_TOKEN: ${{ github.token }}
316
+ REPOSITORY: ${{ github.repository }}
317
+ RUN_ID: ${{ github.run_id }}
318
+ run: |
319
+ mkdir -p out
320
+ for job in $(gh api "repos/$REPOSITORY/actions/runs/$RUN_ID/jobs" --paginate --jq '.jobs[] | select(.conclusion == "failure") | .id'); do
321
+ gh api "repos/$REPOSITORY/actions/jobs/$job/logs" >> out/build.log
322
+ done
323
+ - name: Triage failed build
324
+ id: triage
325
+ uses: anthropics/claude-code-action@61a9c274fa7110a66dfafc1bbbced03833eb25fe # v1.0.269
326
+ with:
327
+ anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
328
+ anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
329
+ prompt: >
330
+ Read the build log at out/build.log. Identify the most
331
+ likely cause, say whether the failure looks flaky or real, and write a
332
+ three-line summary for the PR thread.
333
+ claude_args: >-
334
+ --allowedTools "Read"
335
+ --json-schema '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}'
336
+ - name: Post the summary
337
+ env:
338
+ GH_TOKEN: ${{ github.token }}
339
+ PR_NUMBER: ${{ github.event.pull_request.number }}
340
+ REPOSITORY: ${{ github.repository }}
341
+ SUMMARY: ${{ fromJSON(steps.triage.outputs.structured_output).summary }}
342
+ run: gh pr comment "$PR_NUMBER" --repo "$REPOSITORY" --body "$SUMMARY"
343
+
300
344
  ci:
301
345
  name: All Checks
302
346
  if: always()
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "playwright": {
4
+ "command": "npx",
5
+ "args": ["@playwright/mcp@0.0.83"]
6
+ }
7
+ }
8
+ }
@@ -17,21 +17,34 @@ Turborepo workspace in TypeScript on pnpm and Node.js `>=24.22.1 <25`. `apps/app
17
17
  | Every check | `pnpm verify` |
18
18
  | Render rules after a change | `pnpm rules:sync` |
19
19
 
20
- ## How it fits together
20
+ ## Verifying your work
21
+
22
+ - Build: `pnpm build` (prints `Tasks: 2 successful, 2 total`)
23
+ - Test: `pnpm test:coverage` (all green, and prints `Tasks: 2 successful, 2 total`; never skip or delete a failing test)
24
+ - Lint: `pnpm verify:static` (ESLint allows zero warnings; the dependency check prints `Tasks: 2 successful, 2 total`)
25
+
26
+ Run all three before reporting any task complete, and paste the output. `pnpm verify` runs all three.
27
+ If a test fails, fix the code, not the test.
28
+
29
+ ## Architecture
21
30
 
22
31
  - Root scripts run lint, format, Knip, and the agent checks once for the workspace, and hand `build`, `test`, `typecheck`, and `depcruise` to Turborepo for each app. `TURBO_FILTER` narrows them; the default is every app.
23
32
  - The site lives in `apps/app/app/`. The backoffice site lives in `apps/backoffice/src/app/(frontend)/`, its collections in `apps/backoffice/src/collections/`, and its config in `apps/backoffice/src/payload.config.ts`. The root `generate:*` and `migrate*` scripts run in the backoffice.
24
33
  - In development, Payload applies collection changes to the database directly. In production, the backoffice applies the migrations in `apps/backoffice/src/migrations/` when it starts.
25
34
 
26
- ## Mandatory rules
35
+ ## Conventions
27
36
 
28
- 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
37
+ 1. **Follow `.agents/rules/`.** `.agents/rules.json` gives each rule's scope; Claude Code and Cursor load them. After changing either, or a skill or subagent in `.agents/skills/` or `.agents/agents/`, run `pnpm rules:sync`; `pnpm check` fails on stale copies.
29
38
  2. **Change the backoffice schema only through collections, then regenerate and commit.** Payload generates `apps/backoffice/src/app/(payload)/`, `apps/backoffice/src/payload-types.ts`, and `apps/backoffice/src/migrations/`; run `pnpm generate:types`, `pnpm generate:importmap`, and `pnpm migrate:create <name>`. Do not edit those files by hand.
30
39
  3. **Put unit tests next to the code and Playwright end-to-end tests in `apps/app/test/` and `apps/backoffice/test/` as `*.e2e.test.ts`.** Vitest collects `apps/app/app/**/*.test.{ts,tsx}` and `apps/backoffice/src/**/*.test.{ts,tsx}`.
31
40
  4. **Ask the user before adding component tests.** They need a DOM test environment, and Vitest runs in Node.js.
32
41
  5. **Read backoffice configuration through `requireEnvironment` in `apps/backoffice/src/environment.ts`.** Document each variable in `.env.example`.
42
+ 6. **Start from the accepted spec, in plan mode.** Claude Code starts every session in plan mode (`.claude/settings.json`); in Cursor, switch to Plan Mode before the first edit. Give the plan the change's `intent/<change>/intent.md` and `spec.md`, and have it name the files that change, the order of the work, and the tests that prove it. Commit the approved plan as `intent/<change>/plan.md`. When implementation departs from the plan, update `plan.md` in the same commit.
43
+ 7. **Start a bug fix with a failing test.** Reproduce the bug as a test, run it, and confirm it fails for the reason you expect. Commit that test. Then create `.git/bug-fix-in-progress`, so `.agents/hooks/agent-test-edit-gate.sh` blocks test edits, and make the test pass without editing it. Delete `.git/bug-fix-in-progress` when the fix is done.
44
+
45
+ ## Things Claude gets wrong
33
46
 
34
- ## Known pitfalls
47
+ When Claude makes a mistake twice, add the correction here.
35
48
 
36
49
  - **Next.js docs live per app**: this Next.js version differs from your training data. Read the guide in `apps/app/node_modules/next/dist/docs/` or `apps/backoffice/node_modules/next/dist/docs/` before writing Next.js code; the workspace root has no `next` package.
37
50
  - **Database for `pnpm dev` and end-to-end tests**: the backoffice needs a PostgreSQL database in `DATABASE_URL` and `PAYLOAD_SECRET` in `.env`; the README lists every variable. Run `pnpm --filter ./apps/app exec playwright install chromium` once before the first `pnpm test:e2e`.