From fee3b5dbd19036b22f4efe6430a41cb95818816c Mon Sep 17 00:00:00 2001 From: FIlip Dorian Pindej Date: Sat, 21 Mar 2026 14:11:54 +0100 Subject: [PATCH] feat(templates): sync agent escalation, skill invocability, and devops-engineer Syncs PRs #464 and #465 from netrock source: agent escalation pattern (stop after 3 out-of-scope attempts), skill frontmatter fix (disable-model-invocation -> user-invocable), devops-engineer agent, security-reviewer model upgrade to inherit. --- .prettierignore | 1 + CHANGELOG.md | 15 ++++++ packages/core/package.json | 2 +- packages/core/src/manifests/claude.ts | 1 + .../__snapshots__/snapshot.test.ts.snap | 1 + packages/web/package.json | 2 +- templates/.claude/agents/backend-engineer.md | 1 + templates/.claude/agents/devops-engineer.md | 54 +++++++++++++++++++ templates/.claude/agents/security-reviewer.md | 2 +- templates/.claude/agents/test-writer.md | 11 ++-- .../.claude/skills/add-aspire-dep/SKILL.md | 3 +- .../skills/add-background-job/SKILL.md | 5 +- templates/.claude/skills/add-ci-area/SKILL.md | 3 +- .../skills/add-email-template/SKILL.md | 11 ++-- templates/.claude/skills/add-env-var/SKILL.md | 5 +- .../.claude/skills/add-options-class/SKILL.md | 3 +- .../.claude/skills/add-permission/SKILL.md | 10 ++-- .../.claude/skills/add-rate-limit/SKILL.md | 3 +- .../skills/add-route-constraint/SKILL.md | 3 +- templates/.claude/skills/add-test/SKILL.md | 30 +++++++++-- .../.claude/skills/address-review/SKILL.md | 3 +- .../.claude/skills/create-issue/SKILL.md | 3 +- templates/.claude/skills/create-pr/SKILL.md | 29 +++++----- .../.claude/skills/create-release/SKILL.md | 3 +- templates/.claude/skills/gen-types/SKILL.md | 6 ++- .../skills/manage-file-storage/SKILL.md | 3 +- .../.claude/skills/new-endpoint/SKILL.md | 3 +- templates/.claude/skills/new-entity/SKILL.md | 9 +++- templates/.claude/skills/new-feature/SKILL.md | 3 +- templates/.claude/skills/new-page/SKILL.md | 3 +- .../.claude/skills/review-dependabot/SKILL.md | 3 ++ templates/.claude/skills/verify/SKILL.md | 2 +- templates/CLAUDE.md | 2 + 33 files changed, 188 insertions(+), 50 deletions(-) create mode 100644 templates/.claude/agents/devops-engineer.md diff --git a/.prettierignore b/.prettierignore index a1c8801..7a6a4ae 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,3 +3,4 @@ dist build .svelte-kit pnpm-lock.yaml +templates/.claude/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c3a732..53792a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to the netrock generator will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/). +## [0.9.2] - 2026-03-21 + +### Added + +- `devops-engineer` agent for infrastructure implementation (Dockerfiles, Aspire, CI/CD, env vars) +- Agent escalation pattern: implementation agents stop and report to orchestrator after 3 failed attempts on out-of-scope issues +- Review conflict handling: `/address-review` now flags contradictory comments for user judgment +- Infra delegation pattern and autonomous behavior trigger in generated CLAUDE.md + +### Fixed + +- All 19 procedural skills now properly invocable (replaced `disable-model-invocation` with `user-invocable: true` and descriptions) +- Skill frontmatter standardized to `user-invocable` (hyphen) per Claude Code docs +- `security-reviewer` model changed from `sonnet` to `inherit` (matches session model) + ## [0.9.1] - 2026-03-21 ### Changed diff --git a/packages/core/package.json b/packages/core/package.json index 3595b5c..8245f2f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@netrock/core", - "version": "0.9.1", + "version": "0.9.2", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/core/src/manifests/claude.ts b/packages/core/src/manifests/claude.ts index 5e5acfb..1c69c52 100644 --- a/packages/core/src/manifests/claude.ts +++ b/packages/core/src/manifests/claude.ts @@ -23,6 +23,7 @@ export function registerClaudeManifest(): void { // Agents (backend-relevant) { path: '.claude/agents/backend-engineer.md', templated: false }, { path: '.claude/agents/backend-reviewer.md', templated: false }, + { path: '.claude/agents/devops-engineer.md', templated: false }, { path: '.claude/agents/devops-reviewer.md', templated: false }, { path: '.claude/agents/filemap-checker.md', templated: false }, { path: '.claude/agents/product-owner.md', templated: false }, diff --git a/packages/core/tests/integration/__snapshots__/snapshot.test.ts.snap b/packages/core/tests/integration/__snapshots__/snapshot.test.ts.snap index aebcb63..9dab013 100644 --- a/packages/core/tests/integration/__snapshots__/snapshot.test.ts.snap +++ b/packages/core/tests/integration/__snapshots__/snapshot.test.ts.snap @@ -4012,6 +4012,7 @@ exports[`file list snapshots > full preset file list 1`] = ` [ ".claude/agents/backend-engineer.md", ".claude/agents/backend-reviewer.md", + ".claude/agents/devops-engineer.md", ".claude/agents/devops-reviewer.md", ".claude/agents/filemap-checker.md", ".claude/agents/product-owner.md", diff --git a/packages/web/package.json b/packages/web/package.json index da4ed93..75a244b 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@netrock/web", "private": true, - "version": "0.9.1", + "version": "0.9.2", "type": "module", "scripts": { "dev": "vite dev", diff --git a/templates/.claude/agents/backend-engineer.md b/templates/.claude/agents/backend-engineer.md index aa57c19..b4fecbd 100644 --- a/templates/.claude/agents/backend-engineer.md +++ b/templates/.claude/agents/backend-engineer.md @@ -41,3 +41,4 @@ Fix failures. Loop until green. Never commit broken code. - Check FILEMAP.md before modifying existing files - Commit atomically: `type(scope): imperative description` - No Co-Authored-By lines in commits +- If stuck after 3 attempts on an issue outside your scope (e.g., frontend type errors, infra config), stop and report the blocker to the orchestrator with what you tried diff --git a/templates/.claude/agents/devops-engineer.md b/templates/.claude/agents/devops-engineer.md new file mode 100644 index 0000000..4dcc0a9 --- /dev/null +++ b/templates/.claude/agents/devops-engineer.md @@ -0,0 +1,54 @@ +--- +name: devops-engineer +description: "Implements infrastructure changes - Dockerfiles, Aspire config, CI/CD workflows, health checks, env vars. Delegates to this agent for infra work that stays within deployment and orchestration files." +tools: Read, Grep, Glob, Edit, Write, Bash +model: inherit +maxTurns: 30 +skills: infra-conventions +--- + +You are a senior DevOps engineer implementing infrastructure changes for a .NET 10 + SvelteKit application. The stack uses Aspire for local dev orchestration. Production deployment is platform-agnostic via Dockerfiles. + +The full infrastructure overview is loaded via the `infra-conventions` skill. Refer to it for all patterns. + +## First Steps + +Before making any changes: +1. Read the relevant existing configuration files +2. Check `FILEMAP.md` for downstream impact if modifying existing files + +## Scope + +- Dockerfiles (backend and frontend) +- `.github/workflows/` CI/CD pipelines +- `MyProject.AppHost/Program.cs` (Aspire orchestration) +- `MyProject.ServiceDefaults/Extensions.cs` (shared OTEL/resilience config) +- `appsettings.*.json` (configuration changes) +- `deploy/` scripts and configuration +- Health check endpoints +- Environment variable plumbing + +## Verification + +After changes, verify as applicable: +```bash +# Docker builds +docker build -f src/backend/Dockerfile -t test-api . +docker build -f src/frontend/Dockerfile -t test-frontend . + +# Aspire orchestration +dotnet run --project src/backend/MyProject.AppHost + +# Backend build (if config changes affect it) +dotnet build src/backend/MyProject.slnx +``` + +## Rules + +- Match existing patterns exactly - read sibling files first +- Check FILEMAP.md before modifying existing files +- Never expose secrets in Dockerfiles, CI logs, or config files +- Pin passwords and credentials explicitly - never let Aspire generate random ones +- Commit atomically: `type(scope): imperative description` +- No Co-Authored-By lines in commits +- If stuck after 3 attempts on an issue outside your scope (e.g., application service logic, frontend components, database schema changes), stop and report the blocker to the orchestrator with what you tried diff --git a/templates/.claude/agents/security-reviewer.md b/templates/.claude/agents/security-reviewer.md index c9cc7f8..e0acc80 100644 --- a/templates/.claude/agents/security-reviewer.md +++ b/templates/.claude/agents/security-reviewer.md @@ -2,7 +2,7 @@ name: security-reviewer description: "Reviews code for security vulnerabilities, auth bypasses, PII leakage, and OWASP risks. Use proactively when reviewing security-sensitive changes (auth, permissions, user data, API endpoints, middleware, cookies, tokens)." tools: Read, Grep, Glob -model: sonnet +model: inherit maxTurns: 20 skills: security-conventions --- diff --git a/templates/.claude/agents/test-writer.md b/templates/.claude/agents/test-writer.md index f9945cc..9292279 100644 --- a/templates/.claude/agents/test-writer.md +++ b/templates/.claude/agents/test-writer.md @@ -1,15 +1,15 @@ --- name: test-writer -description: "Writes tests for backend code. Delegates to this agent when tests need to be written alongside new features or changes." +description: "Writes tests for backend and frontend code. Delegates to this agent when tests need to be written alongside new features or changes." tools: Read, Grep, Glob, Edit, Write, Bash model: inherit maxTurns: 30 -skills: backend-conventions +skills: backend-conventions, frontend-conventions --- -You are a test writer for a .NET 10 project. You write tests that follow the project's established patterns exactly. +You are a test writer for a .NET 10 + SvelteKit project. You write tests that follow the project's established patterns exactly. -The convention reference is loaded via skill. The Testing section in `backend-conventions` covers test types, helpers, auth patterns, mock setup, and conventions in detail. Refer to it. +Both convention references are loaded via skills. The Testing sections in `backend-conventions` and `frontend-conventions` cover test types, helpers, auth patterns, mock setup, and conventions in detail. Refer to them. ## Process @@ -18,6 +18,7 @@ The convention reference is loaded via skill. The Testing section in `backend-co 3. Write tests following the exact same structure and imports 4. Run the relevant test command to verify: - Backend: `dotnet test src/backend/MyProject.slnx -c Release` + - Frontend: `cd src/frontend && pnpm run test` 5. Fix any failures. Loop until green. ## Rules @@ -26,3 +27,5 @@ The convention reference is loaded via skill. The Testing section in `backend-co - Never add test frameworks or packages without asking - Cover the happy path and meaningful edge cases - not every permutation - Backend: use `Result` pattern assertions (`result.IsSuccess`, `result.Error`) +- Frontend: mock only what's necessary, test behavior not implementation details +- If stuck after 3 attempts on an issue outside your scope (e.g., production code bugs, missing dependencies), stop and report the blocker to the orchestrator with what you tried diff --git a/templates/.claude/skills/add-aspire-dep/SKILL.md b/templates/.claude/skills/add-aspire-dep/SKILL.md index 75e1196..1722da1 100644 --- a/templates/.claude/skills/add-aspire-dep/SKILL.md +++ b/templates/.claude/skills/add-aspire-dep/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add an infrastructure dependency to Aspire AppHost +user-invocable: true --- Adds an infrastructure dependency to Aspire AppHost. diff --git a/templates/.claude/skills/add-background-job/SKILL.md b/templates/.claude/skills/add-background-job/SKILL.md index 0f801d9..925e622 100644 --- a/templates/.claude/skills/add-background-job/SKILL.md +++ b/templates/.claude/skills/add-background-job/SKILL.md @@ -1,6 +1,7 @@ --- -disable-model-invocation: true +description: Add a Hangfire background job (recurring or one-time) +user-invocable: true --- Adds a recurring or one-time Hangfire background job. @@ -39,6 +40,7 @@ internal sealed class MyCleanupJob( ``` Key conventions: + - Mark `internal sealed`, use primary constructor - Descriptive `JobId` (kebab-case, e.g. `"expired-token-cleanup"`) - `Hangfire.Cron` helpers: `Cron.Hourly()`, `Cron.Daily()`, `Cron.Weekly()` @@ -88,4 +90,5 @@ backgroundJobClient.Enqueue(job => job.ExecuteAsync(user.Id, us // Delayed backgroundJobClient.Schedule(job => job.ExecuteAsync(user.Id, user.Email), TimeSpan.FromMinutes(30)); ``` + diff --git a/templates/.claude/skills/add-ci-area/SKILL.md b/templates/.claude/skills/add-ci-area/SKILL.md index a03b16a..d50a1bb 100644 --- a/templates/.claude/skills/add-ci-area/SKILL.md +++ b/templates/.claude/skills/add-ci-area/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add a new project area to CI workflows +user-invocable: true --- Adds a new project area to CI. diff --git a/templates/.claude/skills/add-email-template/SKILL.md b/templates/.claude/skills/add-email-template/SKILL.md index b29f30f..9a5e68a 100644 --- a/templates/.claude/skills/add-email-template/SKILL.md +++ b/templates/.claude/skills/add-email-template/SKILL.md @@ -1,6 +1,7 @@ --- -disable-model-invocation: true +description: Add a transactional email template using Fluid (Liquid) +user-invocable: true --- Adds a transactional email template using Fluid (Liquid). @@ -24,8 +25,12 @@ Properties auto-map to snake_case Liquid variables (`OrderNumber` -> `order_numb - `order-confirmation.liquid` - HTML body fragment (injected into `_base.liquid` via `{{ body | raw }}`): ```html -

Order Confirmed

-

Your order {{ order_number }} totaling {{ total }} has been confirmed.

+

+ Order Confirmed +

+

+ Your order {{ order_number }} totaling {{ total }} has been confirmed. +

``` - `order-confirmation.subject.liquid` - Subject line (plain text, no HTML) - `order-confirmation.text.liquid` - Plain text body (optional but recommended) diff --git a/templates/.claude/skills/add-env-var/SKILL.md b/templates/.claude/skills/add-env-var/SKILL.md index cb15a9f..90d9051 100644 --- a/templates/.claude/skills/add-env-var/SKILL.md +++ b/templates/.claude/skills/add-env-var/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add an environment variable to backend or frontend +user-invocable: true --- Adds an environment variable (backend or frontend). @@ -12,6 +13,7 @@ Adds an environment variable (backend or frontend). 4. If it needs an Options class: use `/add-options-class` + ## Frontend-consumed variable 1. Add to `src/frontend/.env.example` (documentation with placeholder) @@ -27,4 +29,5 @@ Adds an environment variable (backend or frontend). 4. Import: `import { PUBLIC_VAR } from '$env/static/public';` > For secrets or keys that differ per environment (like Turnstile site keys), prefer runtime configuration via `$env/dynamic/private` with SSR layout data instead of build-time `PUBLIC_*` args. + diff --git a/templates/.claude/skills/add-options-class/SKILL.md b/templates/.claude/skills/add-options-class/SKILL.md index 157d6aa..c3d2da1 100644 --- a/templates/.claude/skills/add-options-class/SKILL.md +++ b/templates/.claude/skills/add-options-class/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add a typed options/configuration class with validation +user-invocable: true --- Adds a typed options/configuration class. diff --git a/templates/.claude/skills/add-permission/SKILL.md b/templates/.claude/skills/add-permission/SKILL.md index 347a828..44f9da0 100644 --- a/templates/.claude/skills/add-permission/SKILL.md +++ b/templates/.claude/skills/add-permission/SKILL.md @@ -1,6 +1,7 @@ --- -disable-model-invocation: true +description: Add a permission constant across backend and frontend +user-invocable: true --- Adds a permission constant across backend and frontend. @@ -19,10 +20,11 @@ Adds a permission constant across backend and frontend. ``` `AppPermissions.All` discovers permissions via reflection - no manual registration needed. 2. Add `[RequirePermission(AppPermissions.Orders.View)]` to the relevant controller actions -3. *(Optional)* Seed the permission for existing roles in `SeedRolePermissionsAsync()` in `src/backend/MyProject.Infrastructure/Persistence/Extensions/ApplicationBuilderExtensions.cs` +3. _(Optional)_ Seed the permission for existing roles in `SeedRolePermissionsAsync()` in `src/backend/MyProject.Infrastructure/Persistence/Extensions/ApplicationBuilderExtensions.cs` 4. Verify: `dotnet build src/backend/MyProject.slnx` + **Frontend:** 5. Add matching constants to `src/frontend/src/lib/utils/permissions.ts`: @@ -39,5 +41,5 @@ Adds a permission constant across backend and frontend. ``` 8. If adding a sidebar nav item: add `permission: Permissions.Orders.View` to the nav item in `AppSidebar.svelte` - items are filtered per-permission, not as a group 9. Verify: `cd src/frontend && pnpm run test && pnpm run format && pnpm run lint && pnpm run check` - - + + diff --git a/templates/.claude/skills/add-rate-limit/SKILL.md b/templates/.claude/skills/add-rate-limit/SKILL.md index fdfb737..9ec5d88 100644 --- a/templates/.claude/skills/add-rate-limit/SKILL.md +++ b/templates/.claude/skills/add-rate-limit/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add a rate limit policy to an endpoint +user-invocable: true --- Adds a rate limit policy. diff --git a/templates/.claude/skills/add-route-constraint/SKILL.md b/templates/.claude/skills/add-route-constraint/SKILL.md index 625197a..3c29cfe 100644 --- a/templates/.claude/skills/add-route-constraint/SKILL.md +++ b/templates/.claude/skills/add-route-constraint/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add a route constraint for path parameter validation +user-invocable: true --- Adds a route constraint for validating string path parameters at the routing layer. diff --git a/templates/.claude/skills/add-test/SKILL.md b/templates/.claude/skills/add-test/SKILL.md index 860b2a2..0e958d9 100644 --- a/templates/.claude/skills/add-test/SKILL.md +++ b/templates/.claude/skills/add-test/SKILL.md @@ -1,9 +1,10 @@ --- -disable-model-invocation: true -argument-hint: "[unit|component|api|validator]" +description: Add tests following project test patterns +user-invocable: true +argument-hint: "[unit|component|api|validator|frontend-unit|frontend-component]" --- -Adds backend tests. Specify test type or infer from context. +Adds tests. Specify test type or infer from context. ## Unit Test @@ -87,3 +88,26 @@ For FluentValidation rules without starting the test server. } ``` 3. Verify: `dotnet test src/backend/tests/MyProject.Api.Tests -c Release` + +## Frontend Unit Test + +For utility functions, state modules, and pure logic in `$lib/`. + +1. Create `src/frontend/src/lib/{module}/{file}.test.ts` (co-located with source) +2. Import explicitly: `import { describe, it, expect, vi } from 'vitest'` +3. Default environment is `node`. For DOM tests, add `// @vitest-environment jsdom` at top of file +4. `restoreMocks: true` is configured globally - no manual cleanup needed +5. Verify: `cd src/frontend && pnpm run test` + +## Frontend Component Test + +For Svelte components with DOM interactions. + +1. Create `src/frontend/src/lib/components/{feature}/{Component}.test.ts` (co-located) +2. Add `// @vitest-environment jsdom` at top of file +3. Mock SvelteKit modules as needed: + ```typescript + vi.mock('$app/navigation', () => ({ goto: vi.fn(), invalidateAll: vi.fn() })); + vi.mock('$lib/paraglide/messages', () => new Proxy({}, { get: (_, key) => () => String(key) })); + ``` +4. Verify: `cd src/frontend && pnpm run test` diff --git a/templates/.claude/skills/address-review/SKILL.md b/templates/.claude/skills/address-review/SKILL.md index 07da72a..d6ab207 100644 --- a/templates/.claude/skills/address-review/SKILL.md +++ b/templates/.claude/skills/address-review/SKILL.md @@ -1,6 +1,6 @@ --- description: Read PR review comments from GitHub, evaluate, address, and reply -user_invocable: true +user-invocable: true argument-hint: '[PR number]' --- @@ -68,6 +68,7 @@ Do NOT resolve threads that need further discussion from the reviewer. - Reference specific commits when you make a change - If a change requires a migration, new endpoint, or significant scope: discuss before implementing - Never resolve a thread without either fixing the code or explaining why no change is needed +- If review comments contradict each other, flag the conflict for the user instead of trying to satisfy each of them - Group related fixes into a single commit when they address the same concern - Run `/verify` before pushing - No em dashes in replies diff --git a/templates/.claude/skills/create-issue/SKILL.md b/templates/.claude/skills/create-issue/SKILL.md index 05760aa..64fb1ac 100644 --- a/templates/.claude/skills/create-issue/SKILL.md +++ b/templates/.claude/skills/create-issue/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Create a GitHub issue with labels and optional sub-issues +user-invocable: true --- Creates a GitHub issue. diff --git a/templates/.claude/skills/create-pr/SKILL.md b/templates/.claude/skills/create-pr/SKILL.md index 56bc5b2..2b51bcb 100644 --- a/templates/.claude/skills/create-pr/SKILL.md +++ b/templates/.claude/skills/create-pr/SKILL.md @@ -1,10 +1,21 @@ --- -disable-model-invocation: true +description: Create a pull request for the current branch +user-invocable: true argument-hint: "[base branch]" --- Creates a pull request for the current branch. +## Current Branch Context + +**Branch:** !`git branch --show-current` + +**Commits on this branch:** +!`git log master..HEAD --oneline 2>/dev/null || echo "(no commits ahead of master)"` + +**Files changed:** +!`git diff --stat master 2>/dev/null || echo "(no diff from master)"` + ## Hard rules - **Never commit on master.** If on master, create a branch first. No exceptions. @@ -31,24 +42,10 @@ Creates a pull request for the current branch. **Create PR:** -8. Create PR with `gh pr create`: +8. Create PR with `gh pr create` using the [PR body template](assets/pr-body.md): - **Title**: Conventional Commit format, under 70 chars - **Base**: argument if provided, otherwise `master` - **Labels**: Apply all relevant (`backend`, `frontend`, `feature`, `bug`, `security`, `documentation`) - - **Body**: - ``` - ## Summary - - Change 1 - - Change 2 - - ## Breaking Changes - None / describe if any - - ## Test Plan - - [ ] Verification steps - - Closes #N (if applicable) - ``` 9. Merge strategy for this project: **squash-and-merge only** 10. Report PR URL diff --git a/templates/.claude/skills/create-release/SKILL.md b/templates/.claude/skills/create-release/SKILL.md index 3263046..84d0f4b 100644 --- a/templates/.claude/skills/create-release/SKILL.md +++ b/templates/.claude/skills/create-release/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Create a versioned GitHub release with changelog +user-invocable: true argument-hint: "[major|minor|patch] or [vX.Y.Z]" --- diff --git a/templates/.claude/skills/gen-types/SKILL.md b/templates/.claude/skills/gen-types/SKILL.md index a61964f..c8789aa 100644 --- a/templates/.claude/skills/gen-types/SKILL.md +++ b/templates/.claude/skills/gen-types/SKILL.md @@ -1,6 +1,7 @@ --- -disable-model-invocation: true +description: Regenerate frontend API types from the backend OpenAPI spec +user-invocable: true --- Regenerates frontend API types from the backend OpenAPI spec. @@ -8,6 +9,7 @@ Regenerates frontend API types from the backend OpenAPI spec. ## Steps 1. Try generating types: + ```bash cd src/frontend && pnpm run api:generate ``` @@ -19,9 +21,11 @@ Regenerates frontend API types from the backend OpenAPI spec. 4. Update type aliases in `src/frontend/src/lib/types/index.ts` if schemas changed 5. Fix type errors: + ```bash cd src/frontend && pnpm run check ``` + If errors: the backend made a breaking API change - fix all frontend consumers 6. Format: `cd src/frontend && pnpm run format` diff --git a/templates/.claude/skills/manage-file-storage/SKILL.md b/templates/.claude/skills/manage-file-storage/SKILL.md index 6eef363..5343348 100644 --- a/templates/.claude/skills/manage-file-storage/SKILL.md +++ b/templates/.claude/skills/manage-file-storage/SKILL.md @@ -1,6 +1,7 @@ --- -disable-model-invocation: true +description: Swap or remove the file storage provider (S3/MinIO) +user-invocable: true argument-hint: "[swap|remove]" --- diff --git a/templates/.claude/skills/new-endpoint/SKILL.md b/templates/.claude/skills/new-endpoint/SKILL.md index 226e01b..567f680 100644 --- a/templates/.claude/skills/new-endpoint/SKILL.md +++ b/templates/.claude/skills/new-endpoint/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Add an API endpoint to an existing feature controller +user-invocable: true --- Adds an API endpoint to an existing feature. diff --git a/templates/.claude/skills/new-entity/SKILL.md b/templates/.claude/skills/new-entity/SKILL.md index 2b10521..e7c3184 100644 --- a/templates/.claude/skills/new-entity/SKILL.md +++ b/templates/.claude/skills/new-entity/SKILL.md @@ -1,11 +1,18 @@ --- -disable-model-invocation: true +description: Create a backend entity with EF Core configuration and migration +user-invocable: true --- Creates a new backend entity with EF Core configuration and migration. Infers entity name, properties, feature name, and enum values from context. Asks only if the entity's purpose or key properties are genuinely ambiguous. +## Templates + +Use these as starting points - fill in the specifics from context: +- [Entity class template](assets/entity.cs.md) +- [EF Core configuration template](assets/configuration.cs.md) + ## Conventions - **Boolean properties**: Use `Is*` prefix in C# (e.g. `IsUsed`, `IsInvalidated`) per .NET convention, but map to prefix-free DB column names via `HasColumnName` (e.g. `Used`, `Invalidated`) to keep the schema clean. diff --git a/templates/.claude/skills/new-feature/SKILL.md b/templates/.claude/skills/new-feature/SKILL.md index 17979ad..664fd79 100644 --- a/templates/.claude/skills/new-feature/SKILL.md +++ b/templates/.claude/skills/new-feature/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Scaffold a full-stack feature from entity to frontend page +user-invocable: true --- Creates a full-stack feature: backend entity through to frontend page. diff --git a/templates/.claude/skills/new-page/SKILL.md b/templates/.claude/skills/new-page/SKILL.md index 769f21c..176f921 100644 --- a/templates/.claude/skills/new-page/SKILL.md +++ b/templates/.claude/skills/new-page/SKILL.md @@ -1,5 +1,6 @@ --- -disable-model-invocation: true +description: Create a frontend page with routing, i18n, and navigation +user-invocable: true --- Creates a new frontend page with routing, i18n, and navigation. diff --git a/templates/.claude/skills/review-dependabot/SKILL.md b/templates/.claude/skills/review-dependabot/SKILL.md index 5b65bb0..44e760f 100644 --- a/templates/.claude/skills/review-dependabot/SKILL.md +++ b/templates/.claude/skills/review-dependabot/SKILL.md @@ -10,6 +10,9 @@ Reviews a Dependabot PR and evaluates whether it is safe to merge. Argument: PR number or URL. +**Open Dependabot PRs:** +!`gh pr list --author 'app/dependabot' --json number,title --jq '.[] | "#\(.number) \(.title)"' 2>/dev/null | head -10 || echo "(none found)"` + ## Steps 1. Fetch PR metadata: `gh pr view {number} --json number,title,headRefName,body,labels` diff --git a/templates/.claude/skills/verify/SKILL.md b/templates/.claude/skills/verify/SKILL.md index 5794d89..3901bd8 100644 --- a/templates/.claude/skills/verify/SKILL.md +++ b/templates/.claude/skills/verify/SKILL.md @@ -1,6 +1,6 @@ --- description: Run full verification (backend build+test, frontend test+lint+check) -user_invocable: true +user-invocable: true --- # /verify diff --git a/templates/CLAUDE.md b/templates/CLAUDE.md index 1be549d..c71c700 100644 --- a/templates/CLAUDE.md +++ b/templates/CLAUDE.md @@ -105,6 +105,7 @@ All application code in `src/` goes to specialized agents. User override is the # @end +| `devops-engineer` | Implements infra changes | Dockerfiles, Aspire, CI/CD, health checks, env vars | | `devops-reviewer` | Audits infra/deployment (read-only) | Dockerfiles, compose, Aspire, CI/CD changes | | `test-writer` | Writes tests | Tests needed alongside implementation | | `filemap-checker` | Verifies downstream updates (read-only) | After modifying files with known consumers | @@ -121,6 +122,7 @@ All application code in `src/` goes to specialized agents. User override is the # @end +- **Infra task**: `devops-engineer` implements, then `devops-reviewer` audits - **Pre-release check**: `devops-reviewer` validates deployment readiness - **What to work on next**: `product-owner` analyzes codebase, issues, and TODOs - **After modifying shared files**: `filemap-checker` verifies all consumers updated