Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6d38875
Le projet dit avec quel pnpm il s'installe
Shaenn Aug 21, 2026
f8a2dc1
L'override de vite dit à quelle condition il disparaît
Shaenn Aug 21, 2026
674cc3c
La CI ne redemande plus la version qu'elle a déjà
Shaenn Aug 21, 2026
15a57c6
Le socle exigé dit la version que le projet épingle
Shaenn Aug 21, 2026
407923f
La politique d'installation dit ce qu'elle refuse
Shaenn Aug 21, 2026
1a79dd7
@quasar/extras passe en 2.0.4
Shaenn Aug 21, 2026
5a08795
dompurify passe en 3.4.14
Shaenn Aug 21, 2026
3222d25
fastify passe en 5.12.1
Shaenn Aug 21, 2026
7d62f7c
mermaid passe en 11.17.0
Shaenn Aug 21, 2026
640ca06
@quasar/app-vite passe en 3.7.0
Shaenn Aug 21, 2026
06a4c79
concurrently passe en 10.0.5
Shaenn Aug 21, 2026
ac5aca7
vitest passe en 4.1.11
Shaenn Aug 21, 2026
1c9f9f6
vue-tsc passe en 3.3.10
Shaenn Aug 22, 2026
8b30f42
quasar passe en 2.25.1, et le pack de langue redit à quoi il sert
Shaenn Aug 22, 2026
5effa70
quasar passe en 2.26.0
Shaenn Aug 25, 2026
f8d514e
vue-i18n passe en 11.4.9
Shaenn Aug 25, 2026
49867b3
@quasar/app-vite passe en 3.8.0
Shaenn Aug 25, 2026
c2945b0
eslint passe en 10.9.0
Shaenn Aug 25, 2026
f707179
vue-tsc passe en 3.3.11
Shaenn Aug 25, 2026
e445255
Le socle de qualité arrive avec ses greffons
Shaenn Aug 25, 2026
e6db5d5
Le socle de qualité s'installe, et le dépôt cesse d'être vert à tort
Shaenn Aug 25, 2026
4cd4fca
Le dépôt passe à la mise en forme du parc
Shaenn Aug 25, 2026
b940be3
Les fonctions nommées se déclarent avec function
Shaenn Aug 25, 2026
fbabd80
Les cinq comparaisons lâches disent ce qu'elles comparent
Shaenn Aug 25, 2026
1339443
Les assertions des tests ne dépendent plus d'un si
Shaenn Aug 25, 2026
13471d2
Les verbes du manifeste sont ceux du parc
Shaenn Aug 25, 2026
f5a1b67
Les imports sont rangés, et leurs commentaires avec eux
Shaenn Aug 25, 2026
25c71fe
Chaque toThrow dit quelle erreur il attend
Shaenn Aug 25, 2026
5cdecaf
Les quatre exceptions restantes disent pourquoi elles en sont
Shaenn Aug 25, 2026
1c6cf33
La documentation dit ce que les commandes font maintenant
Shaenn Aug 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 7 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
root = true

[*]
charset = utf-8
indent_size = 2
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
6 changes: 2 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

## Vérifié

- [ ] `pnpm lint`
- [ ] `pnpm typecheck`
- [ ] `pnpm test`
- [ ] `pnpm build` — le seul à typer `src/`
- [ ] `pnpm verifie` — lint, typage et tests
- [ ] `pnpm build` — Quasar sait produire le bundle
- [ ] Essayé dans l'application, pas seulement en test

## À savoir
Expand Down
23 changes: 11 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
# système de fichiers, les noms courts 8.3, l'énumération des processus. Les faire tourner
# ailleurs vérifierait autre chose que ce qui est livré.
#
# `build` en plus de `typecheck` : `pnpm typecheck` ne couvre que `server/` et `test/`. Le
# front n'est typé que par `vue-tsc`, que seul le build déclenche. Sans cette étape, une
# rupture de types dans `src/` passerait la CI.
# `build` en plus de `typecheck` : depuis la mise au socle, `pnpm typecheck` ouvre la marche
# par `vue-tsc` et couvre donc le front, ce qu'il ne faisait pas — le build ne rattrape plus
# une rupture de types. Il reste parce qu'il vérifie autre chose : que Quasar sait produire
# le bundle, résoudre les alias et les imports dynamiques du manuel.

name: CI

Expand All @@ -27,16 +28,14 @@ jobs:
steps:
- uses: actions/checkout@v7

# 11 et non 10 : les gardes de `pnpm-workspace.yaml` sont des fonctions de
# pnpm 11. Sous la 10, `pnpm install` ne vérifie pas le lockfile contre
# elles — la quarantaine ne protégeait donc que la machine qui résout, et
# un lockfile fabriqué ailleurs avec une dérogation locale passait la CI
# sans un mot. C'est aussi la version qui écrit le lockfile en local :
# laisser la CI le relire avec une majeure de retard est une panne qui
# attend son heure.
# Pas de version ici : `packageManager` dans `package.json` la porte
# désormais, et l'action refuse de démarrer si les deux se contredisent.
# Ce qui se joue sur ce numéro : les gardes de `pnpm-workspace.yaml` sont
# des fonctions de pnpm 11. Sous la 10, `pnpm install` ne vérifie pas le
# lockfile contre elles — la quarantaine ne protégeait donc que la machine
# qui résout, et un lockfile fabriqué ailleurs avec une dérogation locale
# passait la CI sans un mot.
- uses: pnpm/action-setup@v6
with:
version: 11

- uses: actions/setup-node@v7
with:
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
# Même version que `ci.yml`, et pour la même raison : voir le commentaire
# qui s'y trouve.
# Même version que `ci.yml`, et par le même chemin : `packageManager` dans
# `package.json`. Voir le commentaire qui s'y trouve.
- uses: pnpm/action-setup@v6
with:
version: 11
- uses: actions/setup-node@v7
with:
node-version: 24.19.0
Expand Down
17 changes: 17 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Regénéré par pnpm à chaque `pnpm add` : le formater le remet en écart au
# geste suivant, pour un fichier que personne ne lit à la main.
pnpm-lock.yaml

# Ce que le dépôt ne versionne pas. `prettier .` ne lit pas le .gitignore : sans
# ces lignes, il reformaterait la sortie de build, la copie du manuel recopiée
# dans le site vitrine et le harnais Playwright.
dist/
.quasar/
harness/
site/guide/
site/en/guide/
site/.vitepress/cache/
site/.vitepress/dist/
llm règles/
idea/
.local/
6 changes: 5 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"singleQuote": true,
"printWidth": 100
"endOfLine": "auto",
"printWidth": 150,
"vueIndentScriptAndStyle": true,
"trailingComma": "all"
}
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,33 @@ par cas.
Une version se pose quand il y a quelque chose à annoncer, pas à chaque fusion. Une journée
entière de montées de dépendances n'en produit aucune.

## [1.3.1] — 2026-08-25

Une version d'entretien : rien de visible à l'écran, tout sous le capot. Elle réunit deux
chantiers — ce qu'il faut pour installer AURA sans surprise, et l'adoption du socle de
qualité commun aux dépôts du parc.

### Ce qui change pour vous

- **L'installation dit ce qu'elle exige.** Le gestionnaire de paquets est épinglé dans le
manifeste, le socle exigé nomme la version que le projet fige, et la politique
d'installation dit ce qu'elle refuse plutôt que de le laisser découvrir à l'échec.
- **Les dépendances sont à jour.** Quasar, Vite, Fastify, Vitest, ESLint, vue-i18n, mermaid,
dompurify et le reste. Aucune ne change ce que vous voyez.

### Sous le capot

- **Le typecheck ne laisse plus rien dehors.** `pnpm typecheck` ne regardait que le BFF et
les tests : une rupture de types dans un composant du front passait pour vérifiée. Il
ouvre maintenant la marche par `vue-tsc`.
- **Un seul geste avant de pousser.** `pnpm verifie` enchaîne le lint, le typage et les
tests. `pnpm lint` relit les 384 fichiers du dépôt au lieu de quatre dossiers.
- **La mise en forme est vérifiée, pas seulement disponible.** Prettier est lancé comme une
règle ESLint, aux réglages du parc. Le dépôt est reformaté en entier.
- **Des règles de style que le dépôt ne portait pas.** `eqeqeq`, `curly`, `func-style`,
`no-console`, `ban-ts-comment`, plus les règles Vue et Vitest du parc. Le lint ne relève
plus rien : zéro erreur, zéro avertissement.

## [1.3.0] — 2026-08-20

Une version d'une seule capacité, et elle est grande : la **Passerelle**, qui relie une
Expand Down Expand Up @@ -173,6 +200,7 @@ collées, reprise d'une session existante.
externe, aucun secret dans le navigateur. Voir [SECURITY.md](SECURITY.md).
- Windows, exclusivement — la seule plateforme sur laquelle l'application a tourné.

[1.3.1]: https://github.com/Shaenn/aura/releases/tag/v1.3.1
[1.3.0]: https://github.com/Shaenn/aura/releases/tag/v1.3.0
[1.2.0]: https://github.com/Shaenn/aura/releases/tag/v1.2.0
[1.1.0]: https://github.com/Shaenn/aura/releases/tag/v1.1.0
Expand Down
21 changes: 15 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,23 @@ un téléphone, ce qui supposerait de l'adapter à cet écran.
```bash
pnpm dev:all # front :9100 + BFF :8800 (proxy /api → :8800)
pnpm test # vitest, environnement node, test/**/*.test.ts
pnpm typecheck # tsc sur server/ et test/ — ne couvre PAS src/
pnpm lint
pnpm format
pnpm typecheck # vue-tsc sur src/, puis tsc sur server/ et test/
pnpm lint # eslint . — 384 fichiers, mise en forme comprise
pnpm lint:fix
pnpm format # prettier . --write puis pnpm lint:fix
pnpm format:check
pnpm verifie # lint + typecheck + test : le geste avant de pousser
```

`src/` est typé par `vue-tsc` via `vite-plugin-checker`, donc uniquement pendant
`pnpm dev` ou `pnpm build`. Une modification du front qui casse les types ne sera **pas**
vue par `pnpm typecheck`.
`pnpm typecheck` couvre tout ce que le dépôt contient : le front par `vue-tsc`, le BFF et
les tests par `tsc`. `vite-plugin-checker` continue de typer `src/` pendant `pnpm dev`,
mais il ne rattrape plus rien que la ligne de commande ne verrait pas.

Prettier est lancé **comme une règle ESLint** (`eslint-plugin-prettier/recommended`) : la
mise en forme se relève par `pnpm lint` et se corrige par le même `--fix`. Une seule
réserve : le correcteur de `local/import-order` remplace le bloc des imports par les seuls
imports triés, et efface ce qui vit entre eux — un `export … from`, un commentaire de
groupe. Ordonner les imports à la main plutôt que de laisser `pnpm format` s'en charger.

`server/` et `test/` ont leur propre `tsconfig.json` (Node, pas de `lib: dom`) ; la racine
les exclut. `exactOptionalPropertyTypes` est actif côté `src/`, inactif côté `server/`.
Expand Down
11 changes: 6 additions & 5 deletions CONTRIBUTING.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,15 @@ rather than copying their markup/CSS.
## Quality

```bash
pnpm lint # ESLint
pnpm format # Prettier
pnpm typecheck # tsc over server/ and test/
pnpm verifie # lint + typecheck + test — run this before pushing
pnpm lint # ESLint, formatting included
pnpm format # Prettier, then ESLint --fix
pnpm typecheck # vue-tsc over src/, then tsc over server/ and test/
pnpm test # vitest
```

`src/` is **not** covered by `pnpm typecheck`: the front is typed by `vue-tsc` through
`vite-plugin-checker`, therefore during `pnpm dev` or `pnpm build`.
`pnpm typecheck` covers the front, the BFF and the tests. Prettier runs as an ESLint rule:
formatting is reported by `pnpm lint` and fixed by the same `--fix`.

`server/` and `test/` have their own `tsconfig.json` (Node, `lib: esnext` without DOM, `.ts`
extensions allowed on import); the root tsconfig excludes them. `exactOptionalPropertyTypes` is on
Expand Down
11 changes: 6 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,15 @@ plutôt que de recopier leur markup/CSS.
## Qualité

```bash
pnpm lint # ESLint
pnpm format # Prettier
pnpm typecheck # tsc sur server/ et test/
pnpm verifie # lint + typecheck + test — le geste avant de pousser
pnpm lint # ESLint, mise en forme comprise
pnpm format # Prettier puis ESLint --fix
pnpm typecheck # vue-tsc sur src/, puis tsc sur server/ et test/
pnpm test # vitest
```

`src/` n'est **pas** couvert par `pnpm typecheck` : le front est typé par `vue-tsc` via
`vite-plugin-checker`, donc pendant `pnpm dev` ou `pnpm build`.
`pnpm typecheck` couvre le front, le BFF et les tests. Prettier est lancé comme une règle
ESLint : la mise en forme se relève par `pnpm lint` et se corrige par le même `--fix`.

`server/` et `test/` ont leur propre `tsconfig.json` (Node, `lib: esnext` sans DOM, extensions `.ts`
autorisées à l'import) ; le tsconfig racine les exclut. `exactOptionalPropertyTypes` est actif côté
Expand Down
2 changes: 1 addition & 1 deletion INSTALL.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ system.
## Requirements

- **Node.js 24** installed on the machine.
- **pnpm** ≥ 10 (`npm i -g pnpm`).
- **pnpm** ≥ 11 (`npm i -g pnpm`).
- **Claude Code** installed and run at least once, with an existing **`~/.claude`** folder
(on Windows: `C:\Users\<you>\.claude`). That folder is what AURA reads and changes.

Expand Down
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ supposent ce système.
## Pré-requis

- **Node.js 24** installé sur le poste.
- **pnpm** ≥ 10 (`npm i -g pnpm`).
- **pnpm** ≥ 11 (`npm i -g pnpm`).
- **Claude Code** installé et lancé au moins une fois, avec un dossier **`~/.claude`** existant
(sous Windows : `C:\Users\<vous>\.claude`). C'est ce dossier qu'AURA lit et modifie.

Expand Down
8 changes: 5 additions & 3 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ report a flaw.

- **Node.js 24** — a single major version: the one the application is developed, tested and
shipped on, and the one CI runs. Node 24 is under long-term support.
- **pnpm** ≥ 10 — `npm i -g pnpm`.
- **pnpm** ≥ 11 — `npm i -g pnpm`. The exact version is pinned by `packageManager` in
`package.json`: the guards in `pnpm-workspace.yaml` are pnpm 11 features, and an earlier
major would ignore them silently.
- **Claude Code** installed and run at least once, so an existing `~/.claude` folder.
On Windows: `C:\Users\<you>\.claude`.

Expand Down Expand Up @@ -478,8 +480,8 @@ accessibility and the write contract, and they are documented. Issues and PRs ar
either language.

```bash
pnpm lint
pnpm typecheck # server/ and test/
pnpm verifie # lint + typecheck + test
pnpm typecheck # src/, server/ and test/
pnpm test # vitest
```

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,9 @@ comment signaler une faille.

- **Node.js 24** — une seule version majeure, celle sur laquelle l'application est développée,
testée et livrée. C'est aussi celle que la CI fait tourner. Node 24 est en support long terme.
- **pnpm** ≥ 10 — `npm i -g pnpm`.
- **pnpm** ≥ 11 — `npm i -g pnpm`. La version exacte est épinglée par `packageManager` dans
`package.json` : les gardes de `pnpm-workspace.yaml` sont des fonctions de pnpm 11, et une
majeure antérieure les ignorerait en silence.
- **Claude Code** installé et lancé au moins une fois, donc un dossier `~/.claude` existant —
`C:\Users\<vous>\.claude`.

Expand Down Expand Up @@ -525,8 +527,8 @@ Les issues et les pull requests sont bienvenues. Avant d'ouvrir une PR, lisez
design, l'accessibilité et le contrat d'écriture, et elles sont documentées.

```bash
pnpm lint
pnpm typecheck # server/ et test/
pnpm verifie # lint + typecheck + test
pnpm typecheck # src/, server/ et test/
pnpm test # vitest
```

Expand Down
113 changes: 113 additions & 0 deletions eslint-rules/import-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { builtinModules } from 'node:module'

const builtins = new Set(builtinModules.flatMap((m) => [m, `node:${m}`]))

/**
* @typedef {'builtin' | 'external' | 'parent' | 'sibling' | 'index'} ImportGroup
*/

/** @type {ImportGroup[]} */
const GROUP_ORDER = ['builtin', 'external', 'parent', 'sibling', 'index']

/**
* @param {string} source
* @returns {ImportGroup}
*/
function getGroup(source) {
if (builtins.has(source)) {
return 'builtin'
}
if (source === '.' || source === './' || source === './index') {
return 'index'
}
if (source.startsWith('./')) {
return 'sibling'
}
if (source.startsWith('../')) {
return 'parent'
}
return 'external'
}

/**
* @param {string} source
* @returns {number}
*/
function groupRank(source) {
return GROUP_ORDER.indexOf(getGroup(source))
}

/**
* @param {import('estree').ImportDeclaration} a
* @param {import('estree').ImportDeclaration} b
* @returns {number}
*/
function compareImports(a, b) {
const srcA = /** @type {string} */ (a.source.value)
const srcB = /** @type {string} */ (b.source.value)
const rankDiff = groupRank(srcA) - groupRank(srcB)
if (rankDiff !== 0) {
return rankDiff
}
return srcA.localeCompare(srcB)
}

/** @type {import('eslint').Rule.RuleModule} */
const rule = {
meta: {
type: 'suggestion',
docs: {
description: 'Enforce import ordering by group (builtin, external, parent, sibling, index) then alphabetically within each group',
},
fixable: 'code',
schema: [],
messages: {
outOfOrder: "'{{ current }}' ({{ currentGroup }}) should come before '{{ previous }}' ({{ previousGroup }}).",
},
},

create(context) {
return {
Program(node) {
/** @type {import('estree').ImportDeclaration[]} */
const imports = node.body.filter((/** @type {import('estree').Statement} */ s) => s.type === 'ImportDeclaration')

if (imports.length < 2) {
return
}

for (let i = 1; i < imports.length; i++) {
if (compareImports(imports[i - 1], imports[i]) > 0) {
const prev = /** @type {string} */ (imports[i - 1].source.value)
const curr = /** @type {string} */ (imports[i].source.value)

context.report({
node: imports[i],
messageId: 'outOfOrder',
data: {
current: curr,
currentGroup: getGroup(curr),
previous: prev,
previousGroup: getGroup(prev),
},
fix(fixer) {
const sourceCode = context.sourceCode
const sorted = [...imports].sort(compareImports)

/** @type {[number, number]} */
const originalRange = [imports[0].range[0], imports[imports.length - 1].range[1]]

const sortedText = sorted.map((imp) => sourceCode.getText(imp)).join('\n')

return fixer.replaceTextRange(originalRange, sortedText)
},
})
break
}
}
},
}
},
}

export default rule
Loading