Skip to content
Open
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
27 changes: 27 additions & 0 deletions .agents/skills/recettes-client/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,36 @@ toaster.addMessage({ description: 'Saved', type: 'success', closeable: true, tit
</template>
```

## Form Inputs — DsfrInput

Real `DsfrInputProps` (from `@gouvminint/vue-dsfr`, confirmed against `node_modules/@gouvminint/vue-dsfr/**/DsfrInput.types.d.ts`):

| Prop | Type | Purpose |
|------|------|---------|
| `modelValue` | `string \| number` | v-model |
| `label` | `string` | Field label |
| `labelVisible` | `boolean` | Show/hide label |
| `hint` | `string` | Help text |
| `isInvalid` | `boolean` | Error state (red border + error styling) |
| `isValid` | `boolean` | Success state |
| `isTextarea` | `boolean` | Render as `<textarea>` |
| `isWithWrapper` | `boolean` | Wrap in `.fr-input-group` |

```vue
<DsfrInput
v-model="email"
label="Email"
:is-invalid="!!errors.email"
:hint="errors.email ?? 'Format attendu : nom@domaine.fr'"
/>
```

There is **no `native-validators` prop** — validation/error state is driven by `isInvalid` + `hint`/`errorMessage`, handled in your own validation logic (e.g. VeeValidate, Zod).

## Gotchas

- **DSFR is mandatory** — Ministry of Interior projects must use VueDsfr, not a generic component library
- **Package name is `@gouvminint/vue-dsfr`, not `@gouvfr/dsfr-vue`** — and components are prefixed `Dsfr*` (`DsfrInput`, `DsfrButton`), not `Fr*`. A plan referencing `@gouvfr/dsfr-vue`/`FrInput` is hallucinated — verify against `package.json` and `node_modules/@gouvminint/vue-dsfr` before coding (see the verification checklist in `AGENTS.md`)
- **Vue component files need 2+ words** — `LoginForm.vue` not `Form.vue` (exception: `App.vue`)
- **Jest DOM with Vitest** — do NOT install Jest, Jest DOM is compatible with Vitest directly
- **Toaster timeouts must clean up** — always `clearTimeout` on remove to prevent memory leaks
Expand Down
32 changes: 32 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,38 @@ Conventional Commits format. French is acceptable.

Each subproject has its own `AGENTS.md` with project-specific config. This file takes precedence for cross-project conventions.

## Implementing a Plan

Before and while implementing a plan (migration, feature, refactor) that touches external libraries:

### 1. Verify dependencies actually exist

- [ ] Check the plan's packages match what's installed (`package.json`, lockfile) — a plan can reference a package that doesn't exist on npm or isn't the one used by the project
- [ ] Check installed versions match what the plan assumes (`pnpm list <pkg>`)
- [ ] If a package isn't installed yet, confirm it exists on npm before adding it (`npm view <pkg>`)

> Example: a plan referenced `@gouvfr/dsfr-vue` (`FrInput`, `FrButton`) — that package doesn't exist on npm. The project actually uses `@gouvminint/vue-dsfr` (`DsfrInput`, `DsfrButton`).

### 2. Read the real type definitions before coding

- [ ] Locate the `.d.ts` files for the library (`node_modules/<pkg>/**/*.d.ts`)
- [ ] Read the actual component/function signature before writing code that uses it
- [ ] Adapt the plan's code if the real API differs — don't copy-paste it as-is

> Example: a plan used `<FrInput :native-validators="{ required: { errorMessage: '...', enable: true } }" />`, but `DsfrInputProps` (`node_modules/@gouvminint/vue-dsfr/types/components/DsfrInput/DsfrInput.types.d.ts`) has `isInvalid?: boolean` and no `native-validators`. See [recettes-client] for the real DsfrInput API.

### 3. Build before committing

- [ ] Run the project build / typecheck (`pnpm build`, `vue-tsc --noEmit`, `tsc --noEmit`) at the end of each task
- [ ] Fix all type errors before committing
- [ ] Never commit a state that breaks the build, even "temporarily"

### 4. Test existing behavior before changing it

- [ ] Run the app (`pnpm dev`) and check the current behavior of the feature being modified
- [ ] Identify pre-existing bugs (e.g. a non-reactive toast, a frozen counter) — don't confuse them with regressions introduced by the plan
- [ ] Either fix pre-existing bugs as part of the task, or note them explicitly as out of scope in the plan/PR

## Gotchas

- Vue components need 2+ words (`BadgeTypeOrganisme.vue`, not `Badge.vue`)
Expand Down