create-gef 1.2.0 → 1.3.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.
package/.cursorrules CHANGED
@@ -182,6 +182,9 @@ Ces limites sont non-négociables. L'IA ne peut JAMAIS générer du code qui les
182
182
  - Commit dédié : `docs(adr): création ADR-XXX — [titre] (#ticket)`
183
183
  - ⚠️ Ne PAS consigner les ADR dans le RESEARCH_LOG (réservé aux bugs).
184
184
 
185
+ ### Fin d'une tâche (Avant de conclure)
186
+ - [ ] **Vérification Documentaire** : As-tu mis à jour le `README.md`, le `CHANGELOG.md` ou la doc Diátaxis si tes changements impactent l'architecture, l'installation ou les fonctionnalités globales ? **Tu dois toujours faire cette vérification proactivement, sans que l'utilisateur te le demande.**
187
+
185
188
  ---
186
189
 
187
190
  *Ce fichier est la loi fondamentale du GEF. Il garantit un niveau d'ingénierie DORA "Elite" sur tous les projets.*
package/.windsurfrules CHANGED
@@ -182,6 +182,9 @@ Ces limites sont non-négociables. L'IA ne peut JAMAIS générer du code qui les
182
182
  - Commit dédié : `docs(adr): création ADR-XXX — [titre] (#ticket)`
183
183
  - ⚠️ Ne PAS consigner les ADR dans le RESEARCH_LOG (réservé aux bugs).
184
184
 
185
+ ### Fin d'une tâche (Avant de conclure)
186
+ - [ ] **Vérification Documentaire** : As-tu mis à jour le `README.md`, le `CHANGELOG.md` ou la doc Diátaxis si tes changements impactent l'architecture, l'installation ou les fonctionnalités globales ? **Tu dois toujours faire cette vérification proactivement, sans que l'utilisateur te le demande.**
187
+
185
188
  ---
186
189
 
187
190
  *Ce fichier est la loi fondamentale du GEF. Il garantit un niveau d'ingénierie DORA "Elite" sur tous les projets.*
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.0](https://github.com/Gnzikoune/GEF/compare/v1.2.0...v1.3.0) (2026-07-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * **generator:** automatisation des verrous mecaniques ([#10](https://github.com/Gnzikoune/GEF/issues/10)) ([1b92577](https://github.com/Gnzikoune/GEF/commit/1b9257770bb33ddf653ecbcb09cb4e5c50ff4826))
9
+ * **generator:** verrous physiques anti-contournement (Linter, PR, CI) ([fede0ce](https://github.com/Gnzikoune/GEF/commit/fede0ce4a9dfa9e4fd5de6f84108fe4aee24ea48))
10
+
3
11
  ## [1.2.0](https://github.com/Gnzikoune/GEF/compare/v1.1.1...v1.2.0) (2026-07-21)
4
12
 
5
13
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Un framework d'ingénierie logicielle qui transforme des règles de travail en outils automatisés. Il garantit traçabilité, sécurité et qualité sur chaque projet, dès le premier commit.
4
4
  >
5
- > **🛡️ Standards de l'Industrie Enforcés :** GitHub Flow (PRs obligatoires), OWASP Security Limits (Rate Limiting, JWT Exp), et Clean Code Metrics adaptatifs (Startup / Standard / Mission Critical).
5
+ > **🛡️ Standards de l'Industrie Enforcés :** GitHub Flow (PRs obligatoires), OWASP Security Limits (Rate Limiting, JWT Exp), Clean Code Metrics adaptatifs (Startup / Standard / Mission Critical), et **Garantie Anti-Contournement IA** (Crash Clause, `.cursorrules` complets, CI d'intention).
6
6
 
7
7
  ---
8
8
 
@@ -16,7 +16,8 @@
16
16
  6. [Le Pipeline CI/CD (Brique C)](#6-le-pipeline-cicd-brique-c)
17
17
  7. [Les Prompts IA (Brique D)](#7-les-prompts-ia-brique-d)
18
18
  8. [Le Tech Lead Virtuel (Brique E)](#8-le-tech-lead-virtuel-brique-e)
19
- 9. [La Source de Vérité](#9-la-source-de-vérité)
19
+ 9. [La Garantie Anti-Contournement IA (Brique F)](#9-la-garantie-anti-contournement-ia-brique-f)
20
+ 10. [La Source de Vérité](#10-la-source-de-vérité)
20
21
 
21
22
  ---
22
23
 
@@ -39,6 +40,8 @@ GEF/
39
40
  ├── PROJECT_CONFIG.template.md ← Template de configuration projet
40
41
  ├── README.md ← Ce fichier
41
42
  ├── package.json ← Package NPM (rend le GEF exécutable via npx)
43
+ ├── .cursorrules ← Brique F : Toutes les règles GEF pour les IDEs IA (Cursor, Windsurf)
44
+ ├── .windsurfrules ← Brique F : Alias .cursorrules pour Windsurf
42
45
 
43
46
  ├── generator/ ← Brique A : CLI de génération de projet
44
47
  │ ├── index.js ← Point d'entrée (routage des commandes : help, version, update, interactif)
@@ -52,16 +55,18 @@ GEF/
52
55
  │ │ ├── scaffold-linter.js ← Génération des configs Biome, ESLint, Ruff
53
56
  │ │ ├── scaffold-docker.js ← Dockerfile, docker-compose, init.sql
54
57
  │ │ ├── scaffold-ci.js ← Workflows GitHub Actions (CI/CD, release-please)
58
+ │ │ ├── scaffold-ai-rules.js ← Brique F : Copie .cursorrules dans chaque projet généré
55
59
  │ │ └── update.js ← Mise à jour d'un projet existant
56
60
  │ └── templates/
57
61
  │ └── adr-template.md ← Template d'ADR prêt à l'emploi
58
62
 
59
- ├── hooks/ ← Hooks Git (installés dans le dépôt GEF lui-même)
63
+ ├── hooks/ ← Brique B : Hooks Git (installés dans le dépôt GEF lui-même)
60
64
  │ ├── commit-msg ← Conventional Commits + référence Kanban obligatoire (#XYZ)
61
- │ └── pre-commit ← Détection secrets, lint
65
+ │ └── pre-commit ← Détection secrets, lint, blocage commit sur main/master
62
66
 
63
- ├── ci-templates/ ← Brique C : Template de base CI/CD
64
- └── main.yml ← (le générateur produit un CI adapté à la stack)
67
+ ├── ci-templates/ ← Brique C : Templates de base CI/CD
68
+ ├── main.yml ← (le générateur produit un CI adapté à la stack)
69
+ │ └── pr-intention-check.yml ← Brique F : Bloque les PRs sans intention métier déclarée
65
70
 
66
71
  ├── .github/workflows/
67
72
  │ └── release-please.yml ← Automatisation des releases du GEF lui-même
@@ -224,7 +229,7 @@ Installés automatiquement par le générateur dans `.git/hooks/` de chaque proj
224
229
  | Hook | Règle appliquée |
225
230
  |---|---|
226
231
  | **`commit-msg`** | Bloque tout commit dont le message ne respecte pas le format `Conventional Commits + référence Kanban`. Format : `feat: description (#42)`. |
227
- | **`pre-commit`** | Détecte les secrets en clair (clés API, tokens). Vérifie le formatage (linter). Analyse la taille des fichiers selon la sévérité choisie. Bloquant. |
232
+ | **`pre-commit`** | Détecte les secrets en clair (clés API, tokens). Vérifie le formatage (linter). Analyse la taille des fichiers selon la sévérité choisie. **Bloque tout commit direct sur `main` ou `master`.** |
228
233
  | **`pre-push`** | **Dynamique** : Bloque tout push direct sur `main` si le projet est en GitHub Flow. Exécute les tests locaux si en Trunk-Based Development. |
229
234
 
230
235
  Ces hooks sont générés à la volée par le générateur en fonction des choix de l'équipe, et installablés dans `.git/hooks/` du projet.
@@ -283,7 +288,27 @@ Avant d'écrire le code applicatif, l'IA rédige le test E2E (Playwright) qui d
283
288
 
284
289
  ---
285
290
 
286
- ## 9. La Source de Vérité
291
+ ## 9. La Garantie Anti-Contournement IA (Brique F)
292
+
293
+ Le GEF va au-delà des règles textuelles. Il **impose mécaniquement** aux IA les bonnes pratiques dès l'ouverture du projet, sans que l'utilisateur ait à les répéter.
294
+
295
+ ### Comment ça fonctionne
296
+
297
+ | Mécanisme | Fichier | Effet |
298
+ |---|---|---|
299
+ | **Règles natives IDE** | `.cursorrules` / `.windsurfrules` | Toute IA (Cursor, Windsurf, Copilot) lit ces fichiers au démarrage et connaît instantanément les §0 à §10 du Playbook (Clean Code, Architecture, Sécurité OWASP, Git Flow, Tests, Workflows). |
300
+ | **Crash Clause** | `prompts/system_prompt.md` | L'IA est instruite de s'arrêter immédiatement et de signaler tout obstacle, au lieu de l'improvisation silencieuse. |
301
+ | **Checklist Pull Request** | `.github/PULL_REQUEST_TEMPLATE.md` | L'IA (et l'humain) doit physiquement cocher les validations (Tests, Docs, ADR) avant qu'une PR puisse être mergée. |
302
+ | **Blocage Linter (Hard Limits)** | `biome.json` / `.eslintrc.json` / `ruff.toml` | Le linter est configuré avec les limites (ex: 15 lignes max, 2 paramètres) et plantera si l'IA tente de bypasser le framework. |
303
+ | **Blocage local** | `hooks/pre-commit` | Un commit direct sur `main` est physiquement impossible, tout comme un commit qui ne passe pas le Linter. |
304
+ | **Validation CI (Intention & Tests)** | `ci-templates/pr-intention-check.yml` & `main.yml` | La CI rejette les PRs sans intention métier, et bloque si la couverture de tests < 80%. |
305
+ | **Propagation** | `generator/features/scaffold-ai-rules.js` | Chaque projet généré hérite automatiquement du `.cursorrules` complet (source unique de vérité). |
306
+
307
+ > La puissance réside ici : l'utilisateur n'a jamais à expliquer les règles à l'IA. Elles sont déjà là.
308
+
309
+ ---
310
+
311
+ ## 10. La Source de Vérité
287
312
 
288
313
  Toutes les règles appliquées par ce framework sont définies dans un seul document :
289
314
 
@@ -129,6 +129,8 @@ function buildTestBlock(isNode, isPython, database) {
129
129
  if (isNode) {
130
130
  return ` - name: Tests (avec couverture)
131
131
  run: npm test -- --coverage --if-present${dbEnv}
132
+ # Note: Configurez Jest ou Vitest dans votre projet pour échouer si la couverture < 80%
133
+ # Ex Jest: "coverageThreshold": { "global": { "lines": 80 } }
132
134
 
133
135
  - name: Upload Coverage
134
136
  uses: codecov/codecov-action@v4
@@ -139,7 +141,7 @@ function buildTestBlock(isNode, isPython, database) {
139
141
  return ` - name: Tests (pytest + coverage)
140
142
  run: |
141
143
  pip install pytest pytest-cov
142
- pytest tests/ -v --cov=src --cov-report=xml${dbEnv}
144
+ pytest tests/ -v --cov=src --cov-report=xml --cov-fail-under=80${dbEnv}
143
145
 
144
146
  - name: Upload Coverage
145
147
  uses: codecov/codecov-action@v4
@@ -90,6 +90,20 @@ function createAdrTemplate(gefDir) {
90
90
  if (fs.existsSync(templateSrc)) fs.copyFileSync(templateSrc, dest);
91
91
  }
92
92
 
93
+ function createPRTemplate(gefDir) {
94
+ const templateSrc = path.join(gefDir, 'generator', 'templates', 'PULL_REQUEST_TEMPLATE.md');
95
+ fs.mkdirSync('.github', { recursive: true });
96
+ const dest = '.github/PULL_REQUEST_TEMPLATE.md';
97
+ if (fs.existsSync(templateSrc)) fs.copyFileSync(templateSrc, dest);
98
+ }
99
+
100
+ function copyAdditionalWorkflows(gefDir) {
101
+ const src = path.join(gefDir, 'ci-templates', 'pr-intention-check.yml');
102
+ const destDir = '.github/workflows';
103
+ fs.mkdirSync(destDir, { recursive: true });
104
+ if (fs.existsSync(src)) fs.copyFileSync(src, path.join(destDir, 'pr-intention-check.yml'));
105
+ }
106
+
93
107
  function createResearchLog(language) {
94
108
  const isEn = language === 'English';
95
109
  const dest = 'docs/research/RESEARCH_LOG.md';
@@ -148,6 +162,8 @@ export function scaffoldGef(answers, gefDir) {
148
162
  createDirectories(answers.includeCI);
149
163
  copyAndTemplateGefAssets(gefDir, answers.strictness, answers.language);
150
164
  createAdrTemplate(gefDir);
165
+ createPRTemplate(gefDir);
166
+ if (answers.includeCI) copyAdditionalWorkflows(gefDir);
151
167
  createResearchLog(answers.language);
152
168
  createProjectConfig(answers, gefDir);
153
169
  createReadme(answers);
@@ -5,16 +5,30 @@ import fs from 'fs';
5
5
  import { execSync } from 'child_process';
6
6
  import chalk from 'chalk';
7
7
 
8
+ /**
9
+ * Détermine les limites métriques selon le niveau de sévérité.
10
+ */
11
+ function getLimits(strictness) {
12
+ if (strictness.includes('Startup')) return { maxLines: 50, maxParams: 4, maxComplexity: 15 };
13
+ if (strictness.includes('Mission Critical')) return { maxLines: 15, maxParams: 2, maxComplexity: 5 };
14
+ return { maxLines: 30, maxParams: 3, maxComplexity: 10 }; // Standard
15
+ }
16
+
8
17
  /**
9
18
  * Configure ESLint et Prettier.
10
19
  */
11
- function configureEslint(stack) {
12
- console.log(chalk.yellow('🧹 Configuration de ESLint + Prettier...'));
20
+ function configureEslint(stack, strictness) {
21
+ console.log(chalk.yellow('🧹 Configuration de ESLint + Prettier avec Hard Limits...'));
22
+ const limits = getLimits(strictness);
13
23
  const eslintConfig = {
14
24
  env: { browser: true, es2021: true, node: true },
15
25
  extends: ['eslint:recommended', 'prettier'],
16
26
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
17
- rules: {},
27
+ rules: {
28
+ 'max-lines-per-function': ['error', limits.maxLines],
29
+ 'max-params': ['error', limits.maxParams],
30
+ 'complexity': ['error', limits.maxComplexity]
31
+ },
18
32
  };
19
33
  fs.writeFileSync('.eslintrc.json', JSON.stringify(eslintConfig, null, 2));
20
34
  fs.writeFileSync('.prettierrc', '{\n "semi": true,\n "singleQuote": true,\n "printWidth": 100\n}\n');
@@ -31,8 +45,9 @@ function configureEslint(stack) {
31
45
  /**
32
46
  * Configure Biome.
33
47
  */
34
- function configureBiome() {
35
- console.log(chalk.yellow('⚡ Configuration de Biome...'));
48
+ function configureBiome(strictness) {
49
+ console.log(chalk.yellow('⚡ Configuration de Biome avec Hard Limits...'));
50
+ const limits = getLimits(strictness);
36
51
  const biomeConfig = {
37
52
  $schema: "https://biomejs.dev/schemas/1.8.3/schema.json",
38
53
  formatter: {
@@ -44,7 +59,15 @@ function configureBiome() {
44
59
  },
45
60
  linter: {
46
61
  enabled: true,
47
- rules: { recommended: true }
62
+ rules: {
63
+ recommended: true,
64
+ complexity: {
65
+ noExcessiveCognitiveComplexity: {
66
+ level: "error",
67
+ options: { maxAllowedComplexity: limits.maxComplexity }
68
+ }
69
+ }
70
+ }
48
71
  }
49
72
  };
50
73
  fs.writeFileSync('biome.json', JSON.stringify(biomeConfig, null, 2));
@@ -61,12 +84,16 @@ function configureBiome() {
61
84
  /**
62
85
  * Configure Ruff pour Python.
63
86
  */
64
- function configureRuff() {
65
- console.log(chalk.yellow('🐍 Configuration de Ruff...'));
87
+ function configureRuff(strictness) {
88
+ console.log(chalk.yellow('🐍 Configuration de Ruff avec Hard Limits...'));
89
+ const limits = getLimits(strictness);
66
90
  const ruffToml = `[lint]
67
- select = ["E", "F", "I"]
91
+ select = ["E", "F", "I", "C90"]
68
92
  ignore = []
69
93
 
94
+ [lint.mccabe]
95
+ max-complexity = ${limits.maxComplexity}
96
+
70
97
  [format]
71
98
  quote-style = "double"
72
99
  indent-style = "space"
@@ -77,13 +104,13 @@ indent-style = "space"
77
104
  /**
78
105
  * Orchestre la génération de la configuration du linter.
79
106
  */
80
- export function scaffoldLinter(linterChoice, stack) {
107
+ export function scaffoldLinter(linterChoice, stack, strictness) {
81
108
  if (linterChoice === 'Aucun' || !linterChoice) return;
82
109
 
83
110
  try {
84
- if (linterChoice.includes('ESLint')) configureEslint(stack);
85
- else if (linterChoice.includes('Biome')) configureBiome();
86
- else if (linterChoice.includes('Ruff')) configureRuff();
111
+ if (linterChoice.includes('ESLint')) configureEslint(stack, strictness);
112
+ else if (linterChoice.includes('Biome')) configureBiome(strictness);
113
+ else if (linterChoice.includes('Ruff')) configureRuff(strictness);
87
114
  console.log(chalk.green('✅ Linter configuré.'));
88
115
  } catch (err) {
89
116
  console.log(chalk.red('Erreur lors de la configuration du linter.'));
@@ -44,7 +44,7 @@ async function run() {
44
44
  process.chdir(projectPath);
45
45
 
46
46
  scaffoldStack(answers, projectPath);
47
- scaffoldLinter(answers.linter, answers.stack);
47
+ scaffoldLinter(answers.linter, answers.stack, answers.strictness);
48
48
  scaffoldGef(answers, GEF_DIR);
49
49
  scaffoldAiRules(GEF_DIR, projectPath);
50
50
  if (answers.includeDocker) scaffoldDocker(answers.stack, answers.database, answers.projectName);
@@ -0,0 +1,14 @@
1
+ ## Intention
2
+ *Décrivez ici le "Pourquoi" de cette Pull Request. Quel problème résout-elle ou quelle valeur métier apporte-t-elle ?*
3
+
4
+ ## Changements
5
+ *Liste des fichiers majeurs ou composants modifiés.*
6
+
7
+ ## Checklist Qualité GEF (Obligatoire)
8
+ Avant de fusionner, vous DEVEZ valider ces éléments :
9
+
10
+ - [ ] J'ai vérifié que le code respecte les Hard Limits du niveau de sévérité du projet.
11
+ - [ ] J'ai écrit ou mis à jour le test unitaire / E2E associé (la CI bloquera si coverage < 80%).
12
+ - [ ] J'ai créé un rapport ADR dans `docs/explanation/adr/` s'il y a un ajout de dépendance majeure ou une nouvelle architecture.
13
+ - [ ] J'ai mis à jour le README.md / CHANGELOG.md si nécessaire.
14
+ - [ ] La pipeline CI/CD de validation est verte.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-gef",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Générateur interactif de projets respectant le framework GEF",
5
5
  "type": "module",
6
6
  "bin": {