create-go-plate 0.0.0-stage → 0.1.1
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/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/README.md +345 -2
- package/bin/create.mjs +198 -0
- package/modules/ai/docs/AI.md +20 -0
- package/modules/ai/evals/README.md +10 -0
- package/modules/ci-github/.github/dependabot.yml +8 -0
- package/modules/ci-github/.github/workflows/ci.yml +38 -0
- package/modules/claude/.claude/hooks/format.mjs +37 -0
- package/modules/claude/.claude/hooks/lib.mjs +32 -0
- package/modules/claude/.claude/hooks/protect-files.mjs +69 -0
- package/modules/claude/.claude/hooks/session-start.mjs +50 -0
- package/modules/claude/.claude/settings.json +61 -0
- package/modules/claude/.mcp.json +12 -0
- package/modules/claude/CLAUDE.md +13 -0
- package/package.json +40 -4
- package/template/.claude/agents/reviewer.md +25 -0
- package/template/.claude/agents/test-writer.md +19 -0
- package/template/.claude/skills/audit-securite/SKILL.md +23 -0
- package/template/.claude/skills/cadrage/SKILL.md +81 -0
- package/template/.claude/skills/fin-de-session/SKILL.md +28 -0
- package/template/.claude/skills/spec/SKILL.md +36 -0
- package/template/.claude/skills/stress-test/SKILL.md +25 -0
- package/template/.editorconfig +18 -0
- package/template/.env.example +7 -0
- package/template/AGENTS.md +98 -0
- package/template/README.md +62 -0
- package/template/TASKS.md +16 -0
- package/template/docs/ARCHITECTURE.md +38 -0
- package/template/docs/DESIGN.md +37 -0
- package/template/docs/PRD.md +38 -0
- package/template/docs/RULES.md +31 -0
- package/template/docs/SECURITY.md +43 -0
- package/template/docs/SESSION-LOG.md +15 -0
- package/template/docs/TESTING.md +34 -0
- package/template/docs/decisions/0000-template.md +16 -0
- package/template/docs/decisions/README.md +8 -0
- package/template/docs/specs/README.md +12 -0
- package/template/docs/specs/_template/plan.md +27 -0
- package/template/docs/specs/_template/spec.md +23 -0
- package/template/docs/specs/_template/tasks.md +8 -0
- package/template/gitignore +30 -0
- package/template/src/README.md +9 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// PostToolUse : formate automatiquement chaque fichier modifié par l'agent.
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { projectDir, readStdinJson, relativeToProject } from "./lib.mjs";
|
|
6
|
+
|
|
7
|
+
// À RENSEIGNER pendant /cadrage, une fois la stack choisie. Le chemin du fichier est ajouté à la fin.
|
|
8
|
+
// Exemples :
|
|
9
|
+
// "npx prettier --write --ignore-unknown" (JS/TS, CSS, Markdown…)
|
|
10
|
+
// "npx @biomejs/biome format --write" (JS/TS)
|
|
11
|
+
// "ruff format" (Python)
|
|
12
|
+
// "gofmt -w" (Go)
|
|
13
|
+
// Laisser vide désactive le formatage.
|
|
14
|
+
const FORMAT_COMMAND = "";
|
|
15
|
+
|
|
16
|
+
if (!FORMAT_COMMAND) process.exit(0);
|
|
17
|
+
|
|
18
|
+
const input = readStdinJson();
|
|
19
|
+
const filePath = input.tool_input?.file_path;
|
|
20
|
+
if (!filePath) process.exit(0);
|
|
21
|
+
|
|
22
|
+
const absolute = path.resolve(projectDir, filePath);
|
|
23
|
+
const rel = relativeToProject(absolute);
|
|
24
|
+
// Uniquement les fichiers du projet, hors dépendances.
|
|
25
|
+
if (rel.startsWith("..") || /(^|\/)node_modules\//.test(rel) || !existsSync(absolute)) process.exit(0);
|
|
26
|
+
|
|
27
|
+
const result = spawnSync(`${FORMAT_COMMAND} ${JSON.stringify(absolute)}`, {
|
|
28
|
+
cwd: projectDir,
|
|
29
|
+
shell: true,
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (result.status !== 0) {
|
|
34
|
+
// Code 1 = erreur non bloquante : affichée à l'utilisateur, l'agent continue.
|
|
35
|
+
process.stderr.write(`Formatage échoué pour ${rel} :\n${result.stderr || result.stdout || ""}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Utilitaires partagés par les hooks. Aucune dépendance : seulement Node.
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
export const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
6
|
+
|
|
7
|
+
export function readStdinJson() {
|
|
8
|
+
try {
|
|
9
|
+
const raw = readFileSync(0, "utf8");
|
|
10
|
+
return raw.trim() ? JSON.parse(raw) : {};
|
|
11
|
+
} catch {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function readProjectFile(relativePath) {
|
|
17
|
+
try {
|
|
18
|
+
return readFileSync(path.join(projectDir, relativePath), "utf8");
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function stripHtmlComments(text) {
|
|
25
|
+
return text.replace(/<!--[\s\S]*?-->/g, "");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Chemin relatif au projet, avec des "/" quel que soit l'OS.
|
|
29
|
+
export function relativeToProject(filePath) {
|
|
30
|
+
const absolute = path.resolve(projectDir, filePath);
|
|
31
|
+
return path.relative(projectDir, absolute).split(path.sep).join("/");
|
|
32
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// PreToolUse : bloque l'accès aux fichiers sensibles et les commandes git destructrices.
|
|
2
|
+
// Sortie code 2 = action refusée ; le message sur stderr est renvoyé à l'agent.
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { readStdinJson, relativeToProject } from "./lib.mjs";
|
|
5
|
+
|
|
6
|
+
// Fichiers dont le contenu ne doit jamais être lu ni modifié par l'agent.
|
|
7
|
+
const SECRET_FILE = /(^|\/)\.env(\.(?!example$)[^/]+)?$|\.(pem|key|p12|pfx)$/i;
|
|
8
|
+
// Fichiers que l'agent peut lire mais ne doit modifier qu'avec les outils dédiés.
|
|
9
|
+
const GENERATED_FILE =
|
|
10
|
+
/(^|\/)(package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|poetry\.lock|uv\.lock|Cargo\.lock)$/;
|
|
11
|
+
const GIT_DIR = /(^|\/)\.git\//;
|
|
12
|
+
|
|
13
|
+
// Commandes shell qui mentionnent un fichier .env réel (pas .env.example).
|
|
14
|
+
const BASH_SECRET = /(^|[\s'"=<>|;&(/])\.env(\.(?!example\b)[\w.-]+)?(?![\w.-])/;
|
|
15
|
+
const BASH_FORCE_PUSH = /\bgit\s+push\b[^;&|]*\s(--force(?!-with-lease)|-f)(\s|$)/;
|
|
16
|
+
const BASH_RESET_HARD = /\bgit\s+reset\b[^;&|]*\s--hard\b/;
|
|
17
|
+
|
|
18
|
+
function deny(message) {
|
|
19
|
+
process.stderr.write(`${message}\n`);
|
|
20
|
+
process.exit(2);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const input = readStdinJson();
|
|
24
|
+
const tool = input.tool_name;
|
|
25
|
+
const toolInput = input.tool_input || {};
|
|
26
|
+
|
|
27
|
+
if (tool === "Bash") {
|
|
28
|
+
const command = String(toolInput.command || "");
|
|
29
|
+
if (BASH_SECRET.test(command)) {
|
|
30
|
+
deny(
|
|
31
|
+
"Bloqué par .claude/hooks/protect-files.mjs : la commande touche un fichier .env réel. " +
|
|
32
|
+
"Les secrets ne sont pas accessibles à l'agent ; demande à l'utilisateur de faire cette action lui-même " +
|
|
33
|
+
"(ou utilise .env.example pour documenter une variable)."
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (BASH_FORCE_PUSH.test(command) || BASH_RESET_HARD.test(command)) {
|
|
37
|
+
deny(
|
|
38
|
+
"Bloqué par .claude/hooks/protect-files.mjs : commande git destructrice (push --force / reset --hard). " +
|
|
39
|
+
"Voir docs/RULES.md. Si c'est vraiment nécessaire, l'utilisateur doit la lancer lui-même."
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const filePath = toolInput.file_path || toolInput.notebook_path;
|
|
46
|
+
if (!filePath) process.exit(0);
|
|
47
|
+
|
|
48
|
+
const rel = relativeToProject(filePath);
|
|
49
|
+
const name = path.posix.basename(rel);
|
|
50
|
+
|
|
51
|
+
if (SECRET_FILE.test(rel)) {
|
|
52
|
+
deny(
|
|
53
|
+
`Bloqué par .claude/hooks/protect-files.mjs : ${name} peut contenir des secrets. ` +
|
|
54
|
+
"Documente les variables dans .env.example et demande à l'utilisateur de remplir le vrai fichier."
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (tool !== "Read" && GIT_DIR.test(`${rel}/`)) {
|
|
59
|
+
deny("Bloqué par .claude/hooks/protect-files.mjs : ne modifie pas le dossier .git directement, utilise les commandes git.");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (tool !== "Read" && GENERATED_FILE.test(rel)) {
|
|
63
|
+
deny(
|
|
64
|
+
`Bloqué par .claude/hooks/protect-files.mjs : ${name} est généré. ` +
|
|
65
|
+
"Modifie-le via le gestionnaire de paquets (install / add / remove), pas à la main."
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
process.exit(0);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// SessionStart : redonne à l'agent le contexte de reprise (statut du cadrage, tâches en cours,
|
|
2
|
+
// dernière entrée du journal). Ce qui est écrit sur stdout est ajouté au contexte de la session.
|
|
3
|
+
import { readProjectFile, stripHtmlComments } from "./lib.mjs";
|
|
4
|
+
|
|
5
|
+
const MAX_CHARS = 3000;
|
|
6
|
+
|
|
7
|
+
function section(markdown, title) {
|
|
8
|
+
const lines = stripHtmlComments(markdown).split("\n");
|
|
9
|
+
const start = lines.findIndex((l) => l.trim().toLowerCase() === `## ${title}`.toLowerCase());
|
|
10
|
+
if (start === -1) return "";
|
|
11
|
+
const end = lines.findIndex((l, i) => i > start && /^##\s/.test(l));
|
|
12
|
+
return lines
|
|
13
|
+
.slice(start + 1, end === -1 ? undefined : end)
|
|
14
|
+
.join("\n")
|
|
15
|
+
.trim();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function lastLogEntry(markdown) {
|
|
19
|
+
const text = stripHtmlComments(markdown);
|
|
20
|
+
const match = text.match(/^###\s[\s\S]*?(?=^###\s|(?![\s\S]))/m);
|
|
21
|
+
return match ? match[0].trim() : "";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const out = [];
|
|
25
|
+
|
|
26
|
+
const agents = readProjectFile("AGENTS.md");
|
|
27
|
+
if (agents) {
|
|
28
|
+
const status = section(agents, "Statut du cadrage").split("\n")[0].replace(/\*/g, "").trim();
|
|
29
|
+
if (status) out.push(`Statut du cadrage : ${status}`);
|
|
30
|
+
if (/NON FAIT/.test(status)) {
|
|
31
|
+
out.push("Le cadrage n'est pas fait : avant de coder une fonctionnalité, propose /cadrage.");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const tasks = readProjectFile("TASKS.md");
|
|
36
|
+
if (tasks) {
|
|
37
|
+
const current = section(tasks, "En cours");
|
|
38
|
+
out.push(`Tâches en cours (TASKS.md) :\n${current || "(aucune)"}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const log = readProjectFile("docs/SESSION-LOG.md");
|
|
42
|
+
if (log) {
|
|
43
|
+
const entry = lastLogEntry(log);
|
|
44
|
+
if (entry) out.push(`Dernière session (docs/SESSION-LOG.md) :\n${entry}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (out.length) {
|
|
48
|
+
const text = `Contexte de reprise du projet\n\n${out.join("\n\n")}`;
|
|
49
|
+
process.stdout.write(text.length > MAX_CHARS ? `${text.slice(0, MAX_CHARS)}\n…(tronqué)` : text);
|
|
50
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
+
"permissions": {
|
|
4
|
+
"deny": [
|
|
5
|
+
"Read(./.env)",
|
|
6
|
+
"Read(./.env.local)",
|
|
7
|
+
"Read(./.env.*.local)",
|
|
8
|
+
"Read(./.env.production)",
|
|
9
|
+
"Edit(./.env)",
|
|
10
|
+
"Edit(./.env.local)",
|
|
11
|
+
"Edit(./.env.*.local)",
|
|
12
|
+
"Edit(./.env.production)",
|
|
13
|
+
"Bash(git push --force *)",
|
|
14
|
+
"Bash(git push -f *)",
|
|
15
|
+
"Bash(git reset --hard *)"
|
|
16
|
+
],
|
|
17
|
+
"ask": [
|
|
18
|
+
"Bash(git push *)",
|
|
19
|
+
"Bash(rm -rf *)",
|
|
20
|
+
"Bash(git clean *)",
|
|
21
|
+
"Bash(npm publish *)"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"hooks": {
|
|
25
|
+
"SessionStart": [
|
|
26
|
+
{
|
|
27
|
+
"hooks": [
|
|
28
|
+
{
|
|
29
|
+
"type": "command",
|
|
30
|
+
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/session-start.mjs\"",
|
|
31
|
+
"timeout": 10
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"PreToolUse": [
|
|
37
|
+
{
|
|
38
|
+
"matcher": "Read|Edit|Write|MultiEdit|NotebookEdit|Bash",
|
|
39
|
+
"hooks": [
|
|
40
|
+
{
|
|
41
|
+
"type": "command",
|
|
42
|
+
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/protect-files.mjs\"",
|
|
43
|
+
"timeout": 10
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"PostToolUse": [
|
|
49
|
+
{
|
|
50
|
+
"matcher": "Edit|Write|MultiEdit",
|
|
51
|
+
"hooks": [
|
|
52
|
+
{
|
|
53
|
+
"type": "command",
|
|
54
|
+
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/format.mjs\"",
|
|
55
|
+
"timeout": 60
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@AGENTS.md
|
|
2
|
+
|
|
3
|
+
<!--
|
|
4
|
+
Les instructions du projet vivent dans AGENTS.md (lu par tous les agents).
|
|
5
|
+
N'ajoute ici que ce qui est spécifique à Claude Code.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
## Spécifique à Claude Code
|
|
9
|
+
|
|
10
|
+
- Pour une tâche complexe, utilise le mode plan avant d'éditer.
|
|
11
|
+
- Délègue la relecture au sous-agent `reviewer` avant de déclarer une fonctionnalité terminée.
|
|
12
|
+
- Les hooks de `.claude/settings.json` bloquent l'écriture des fichiers sensibles et formatent
|
|
13
|
+
le code après chaque modification : ne cherche pas à les contourner.
|
package/package.json
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-go-plate",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Cadrage prêt à l'emploi pour développer une application avec un agent de code (Claude Code, Codex, Cursor…) : PRD, architecture, specs, ADR, skills, hooks, CI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-go-plate": "bin/create.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"template",
|
|
12
|
+
"modules",
|
|
13
|
+
"CHANGELOG.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "node --test",
|
|
17
|
+
"prepublishOnly": "npm test"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20.16"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"create",
|
|
24
|
+
"template",
|
|
25
|
+
"scaffold",
|
|
26
|
+
"vibecoding",
|
|
27
|
+
"ai-agent",
|
|
28
|
+
"claude-code",
|
|
29
|
+
"agents-md",
|
|
30
|
+
"spec-driven-development"
|
|
31
|
+
],
|
|
32
|
+
"author": "Jeanpierregaba",
|
|
33
|
+
"homepage": "https://github.com/Jeanpierregaba/create-go-plate#readme",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/Jeanpierregaba/create-go-plate.git"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/Jeanpierregaba/create-go-plate/issues"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT"
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: Relecteur de code critique et indépendant. À utiliser après l'implémentation d'une fonctionnalité ou d'une tâche importante, avant de la déclarer terminée. Ne modifie pas le code.
|
|
4
|
+
tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Tu es un développeur senior qui relit le travail d'un collègue. Tu n'écris pas de code : tu
|
|
8
|
+
signales les problèmes, preuves à l'appui.
|
|
9
|
+
|
|
10
|
+
Avant de commencer, lis `AGENTS.md`, `docs/RULES.md` et, si elle existe, la spec de la
|
|
11
|
+
fonctionnalité dans `docs/specs/`. Regarde les changements avec `git diff` (et `git diff --staged`).
|
|
12
|
+
|
|
13
|
+
Vérifie, par ordre de priorité :
|
|
14
|
+
1. **Exactitude** : le code fait-il ce que demande la spec ? Les critères d'acceptation sont-ils
|
|
15
|
+
tous couverts ? Bugs, cas limites et cas d'erreur non gérés.
|
|
16
|
+
2. **Sécurité** : contrôle d'accès côté serveur, validation des entrées, secrets, données exposées
|
|
17
|
+
(voir `docs/SECURITY.md`).
|
|
18
|
+
3. **Respect des règles** : `docs/RULES.md`, règles d'architecture d'`AGENTS.md`, ADR.
|
|
19
|
+
4. **Tests** : les tests vérifient-ils vraiment le comportement (et pas seulement qu'aucune erreur
|
|
20
|
+
n'est levée) ? Lance-les.
|
|
21
|
+
5. **Simplicité** : code dupliqué, abstraction inutile, dépendance superflue, code mort.
|
|
22
|
+
|
|
23
|
+
Rends une liste de constats classés (bloquant / à corriger / suggestion), chacun avec le fichier,
|
|
24
|
+
la ligne, le problème concret et la correction proposée. Si tout est bon, dis-le clairement.
|
|
25
|
+
N'invente pas de problème pour avoir quelque chose à dire.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-writer
|
|
3
|
+
description: Écrit des tests à partir d'une spec ou d'un comportement attendu, notamment AVANT l'implémentation pour les parties critiques (TDD). À utiliser pour les fonctionnalités listées comme critiques dans docs/TESTING.md, ou pour combler un manque de tests.
|
|
4
|
+
tools: Read, Grep, Glob, Bash, Write, Edit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Tu écris des tests, pas le code de production.
|
|
8
|
+
|
|
9
|
+
1. Lis `docs/TESTING.md` (outils et conventions), `AGENTS.md` (commandes) et la spec concernée
|
|
10
|
+
dans `docs/specs/`.
|
|
11
|
+
2. Pour chaque critère d'acceptation, écris au moins un test, plus les cas limites et d'erreur
|
|
12
|
+
listés dans la spec.
|
|
13
|
+
3. Les tests vérifient le comportement observable (entrées → sorties, effets), pas les détails
|
|
14
|
+
d'implémentation. Un test = un comportement, avec un nom qui le décrit en clair.
|
|
15
|
+
4. Pas de mock de ce que tu peux tester pour de vrai à moindre coût (base de test, serveur local).
|
|
16
|
+
5. Lance les tests :
|
|
17
|
+
- en mode TDD (code pas encore écrit), ils doivent **échouer pour la bonne raison** ;
|
|
18
|
+
- sinon, ils doivent passer. S'ils révèlent un bug, signale-le sans corriger le code de production.
|
|
19
|
+
6. Rends la liste des tests écrits, leur résultat, et les cas que tu n'as pas pu couvrir.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit-securite
|
|
3
|
+
description: Audit de sécurité de l'application à partir de docs/SECURITY.md - vérifie le code réel, pas seulement la doc. À utiliser avant une mise en production, après une fonctionnalité touchant l'auth, les paiements ou les données personnelles, ou sur demande.
|
|
4
|
+
argument-hint: "[périmètre, optionnel : dossier, fonctionnalité ou 'tout']"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Audit de sécurité
|
|
8
|
+
|
|
9
|
+
Périmètre : $ARGUMENTS (par défaut : tout le projet).
|
|
10
|
+
|
|
11
|
+
1. Lis `docs/SECURITY.md`, `docs/RULES.md` et la partie auth / données de `docs/ARCHITECTURE.md`.
|
|
12
|
+
2. Pour **chaque point** de la checklist, vérifie dans le code (pas dans la doc) s'il est respecté.
|
|
13
|
+
Cite le fichier et la ligne comme preuve. Statut : OK / À corriger / Non applicable / Non vérifiable.
|
|
14
|
+
3. Cherche en plus :
|
|
15
|
+
- secrets en dur (clés, tokens, mots de passe, URL avec identifiants), y compris dans l'historique git
|
|
16
|
+
- variables d'environnement secrètes exposées au client
|
|
17
|
+
- routes / actions serveur sans contrôle d'accès, ou qui ne vérifient pas la propriété de la ressource
|
|
18
|
+
- entrées non validées, SQL concaténé, HTML non échappé
|
|
19
|
+
- dépendances vulnérables (lance l'outil d'audit de la stack)
|
|
20
|
+
- si l'app utilise un LLM : contenu externe injecté dans les prompts sans séparation, outils trop permissifs
|
|
21
|
+
4. Rends un rapport classé par gravité (critique / haute / moyenne / basse), avec pour chaque
|
|
22
|
+
problème : où, risque concret, correction proposée.
|
|
23
|
+
5. Ne corrige qu'après validation. Mets à jour les cases de `docs/SECURITY.md` en fonction du résultat.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cadrage
|
|
3
|
+
description: Cadrage complet d'un nouveau projet avant tout développement. Interroge l'utilisateur et remplit PRD, architecture, design, règles, sécurité, tests, backlog et outillage. À utiliser au démarrage d'un projet, ou quand AGENTS.md indique "Statut du cadrage : NON FAIT" et que l'utilisateur veut commencer à coder.
|
|
4
|
+
argument-hint: "[étape à reprendre, optionnel]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Cadrage du projet
|
|
8
|
+
|
|
9
|
+
Tu mènes un entretien de cadrage puis tu remplis les fichiers du projet. L'utilisateur n'est pas
|
|
10
|
+
forcément développeur : explique tes propositions simplement et justifie chaque choix technique.
|
|
11
|
+
|
|
12
|
+
## Règles de l'entretien
|
|
13
|
+
|
|
14
|
+
- Pose **au plus 4 questions à la fois**, regroupées par thème. Propose des réponses par défaut
|
|
15
|
+
raisonnables pour que l'utilisateur puisse simplement valider.
|
|
16
|
+
- Après chaque étape : écris le fichier, montre un résumé en 3-5 lignes, demande validation avant
|
|
17
|
+
de passer à la suivante.
|
|
18
|
+
- Remplace les commentaires `<!-- ... -->` d'instruction par le vrai contenu. Garde la structure
|
|
19
|
+
des titres. Si une section ne s'applique pas, écris « Sans objet — <raison> ».
|
|
20
|
+
- **Reprise** : commence par regarder quels fichiers sont déjà remplis et reprends à la première
|
|
21
|
+
étape non terminée (ou à celle indiquée en argument : $ARGUMENTS). Annonce où tu reprends.
|
|
22
|
+
- Ne code aucune fonctionnalité pendant le cadrage.
|
|
23
|
+
|
|
24
|
+
## Étapes
|
|
25
|
+
|
|
26
|
+
### 1. Produit → `docs/PRD.md`
|
|
27
|
+
Problème, utilisateurs, parcours principaux, fonctionnalités du MVP (une ligne testable chacune),
|
|
28
|
+
hors scope, vocabulaire du domaine, critères de succès, contraintes (budget, délai, RGPD, appareils).
|
|
29
|
+
Pousse l'utilisateur à **réduire** le MVP : ce qui n'est pas indispensable va dans « Hors scope ».
|
|
30
|
+
|
|
31
|
+
### 2. Architecture → `docs/ARCHITECTURE.md` + ADR
|
|
32
|
+
- Propose une stack adaptée au PRD et au niveau de l'utilisateur, avec 1 alternative et les compromis.
|
|
33
|
+
Privilégie des technologies répandues et bien documentées (l'agent les maîtrise mieux).
|
|
34
|
+
- **Vérifie les versions actuelles** et les commandes d'installation dans la doc officielle
|
|
35
|
+
(MCP Context7 ou recherche web) : ne te fie pas à ta mémoire.
|
|
36
|
+
- Une fois validée : remplis ARCHITECTURE.md et crée `docs/decisions/0001-choix-de-la-stack.md`
|
|
37
|
+
à partir de `docs/decisions/0000-template.md`. Un ADR par autre décision structurante
|
|
38
|
+
(base de données, auth, hébergement…).
|
|
39
|
+
|
|
40
|
+
### 3. Design → `docs/DESIGN.md`
|
|
41
|
+
Intention, design system, écrans principaux, accessibilité, responsive, ton.
|
|
42
|
+
Si le projet n'a pas d'interface : supprime DESIGN.md et sa ligne dans AGENTS.md.
|
|
43
|
+
|
|
44
|
+
### 4. Stress-test
|
|
45
|
+
Applique la skill `stress-test` sur PRD + ARCHITECTURE + DESIGN. Intègre les corrections validées
|
|
46
|
+
et résume les risques restants dans « Points d'attention » d'ARCHITECTURE.md.
|
|
47
|
+
|
|
48
|
+
### 5. Instructions de l'agent → `AGENTS.md`
|
|
49
|
+
Remplis : le projet en une phrase, stack, structure du dépôt, commandes, règles d'architecture non
|
|
50
|
+
négociables (avec liens ADR), conventions de code. Reste concis : ce fichier est lu à chaque session.
|
|
51
|
+
|
|
52
|
+
### 6. Garde-fous → `docs/RULES.md`, `docs/SECURITY.md`, `docs/TESTING.md`
|
|
53
|
+
- RULES : ajoute les interdits spécifiques au projet.
|
|
54
|
+
- SECURITY : adapte la checklist à la stack (ex : RLS si Supabase), supprime l'inapplicable en
|
|
55
|
+
justifiant.
|
|
56
|
+
- TESTING : outils de test, fonctionnalités critiques en TDD, ce que la CI vérifie.
|
|
57
|
+
|
|
58
|
+
### 7. Backlog → `TASKS.md`
|
|
59
|
+
Une ligne par fonctionnalité du MVP, ordonnées par dépendance puis valeur. La première doit
|
|
60
|
+
être petite et livrable rapidement (souvent : squelette déployable + auth).
|
|
61
|
+
|
|
62
|
+
### 8. Outillage
|
|
63
|
+
- `.claude/hooks/format.mjs` (s'il existe) : renseigne `FORMAT_COMMAND` avec le formateur de la stack.
|
|
64
|
+
- `.github/workflows/ci.yml` (s'il existe) : remplace l'étape d'avertissement par les vraies étapes
|
|
65
|
+
install / lint / typecheck / test / build, avec les versions vérifiées.
|
|
66
|
+
- `.env.example` : les variables nécessaires, sans valeur, commentées.
|
|
67
|
+
- `.mcp.json` : propose les serveurs MCP utiles à cette stack (base de données, hébergeur…).
|
|
68
|
+
N'ajoute que des serveurs officiels ou largement reconnus, et explique à quoi chacun sert.
|
|
69
|
+
- `README.md` : section « Démarrer ».
|
|
70
|
+
|
|
71
|
+
### 9. Squelette → `src/` (ou l'emplacement prévu par la stack)
|
|
72
|
+
Initialise le projet avec l'outil officiel de la stack, crée la structure de dossiers décrite
|
|
73
|
+
dans ARCHITECTURE.md avec des fichiers quasi vides. Vérifie que lint, typecheck, tests et build
|
|
74
|
+
passent sur ce squelette vide. Supprime `src/README.md` s'il n'est plus utile.
|
|
75
|
+
|
|
76
|
+
## Fin du cadrage
|
|
77
|
+
|
|
78
|
+
1. Dans AGENTS.md, remplace « **NON FAIT** » par « **FAIT (AAAA-MM-JJ)** ».
|
|
79
|
+
2. Ajoute une entrée dans `docs/SESSION-LOG.md`.
|
|
80
|
+
3. Propose un commit : `chore: cadrage initial du projet`.
|
|
81
|
+
4. Indique la prochaine étape : `/spec` sur la première fonctionnalité de TASKS.md.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fin-de-session
|
|
3
|
+
description: Clôture une session de travail - met à jour TASKS.md, les tasks.md des specs en cours et ajoute une entrée en haut de docs/SESSION-LOG.md. À utiliser quand l'utilisateur dit qu'il s'arrête, ou en fin de journée.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fin de session
|
|
7
|
+
|
|
8
|
+
1. **Faire le point** : liste ce qui a été fait pendant la session (conversation + `git log` /
|
|
9
|
+
`git status` depuis le début de la session) et ce qui n'est pas commité.
|
|
10
|
+
2. **`TASKS.md`** : déplace ce qui est terminé, mets à jour « En cours », ajoute les nouvelles
|
|
11
|
+
tâches découvertes.
|
|
12
|
+
3. **Specs en cours** : coche les tâches faites dans `docs/specs/*/tasks.md`.
|
|
13
|
+
4. **Décisions** : si une décision technique a été prise sans ADR, crée-le dans `docs/decisions/`.
|
|
14
|
+
5. **`docs/SESSION-LOG.md`** : ajoute en HAUT (sous le commentaire) une entrée au format :
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
### AAAA-MM-JJ — titre court
|
|
18
|
+
- Fait :
|
|
19
|
+
- Pièges rencontrés :
|
|
20
|
+
- Décisions : (liens vers les ADR)
|
|
21
|
+
- Prochaine étape :
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
« Prochaine étape » doit être assez précise pour qu'une nouvelle session démarre sans question.
|
|
25
|
+
6. **Commit** : s'il reste des changements, propose un message de commit (ne committe qu'avec
|
|
26
|
+
l'accord de l'utilisateur).
|
|
27
|
+
7. Si une règle ou convention a été découverte pendant la session, propose de l'ajouter à
|
|
28
|
+
`AGENTS.md` ou `docs/RULES.md`.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec
|
|
3
|
+
description: Démarre une nouvelle fonctionnalité en spec-driven development - crée docs/specs/NNN-nom/ avec spec, plan technique et liste de tâches, à valider avant tout code. À utiliser dès que l'utilisateur veut ajouter une fonctionnalité non triviale.
|
|
4
|
+
argument-hint: "<description de la fonctionnalité>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Nouvelle fonctionnalité : $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Ne code rien tant que les trois étapes ci-dessous ne sont pas validées par l'utilisateur.
|
|
10
|
+
|
|
11
|
+
## 0. Préparer
|
|
12
|
+
- Numéro : le plus grand `NNN` existant dans `docs/specs/` + 1 (commence à `001`).
|
|
13
|
+
- Copie `docs/specs/_template/` vers `docs/specs/NNN-nom-court/` (nom en kebab-case).
|
|
14
|
+
- Relis `docs/PRD.md`, `AGENTS.md` et les ADR concernés pour rester cohérent.
|
|
15
|
+
|
|
16
|
+
## 1. Spec → `spec.md` (le QUOI)
|
|
17
|
+
Remplis le fichier. Pose les questions nécessaires (4 max à la fois) pour lever les ambiguïtés.
|
|
18
|
+
Les critères d'acceptation doivent être vérifiables par un test. Fais valider.
|
|
19
|
+
|
|
20
|
+
## 2. Plan → `plan.md` (le COMMENT)
|
|
21
|
+
Fichiers touchés, modèle de données, API, composants, dépendances éventuelles (vérifiées : elles
|
|
22
|
+
existent, sont maintenues, doc à jour). Si une décision est structurante, crée un ADR.
|
|
23
|
+
Pour une fonctionnalité risquée, applique la skill `stress-test` sur la spec et le plan.
|
|
24
|
+
Fais valider.
|
|
25
|
+
|
|
26
|
+
## 3. Tâches → `tasks.md`
|
|
27
|
+
Découpe en tâches de quelques dizaines de minutes, chacune testable et committable seule, dans
|
|
28
|
+
l'ordre d'exécution. Pour les parties critiques (voir `docs/TESTING.md`), la tâche « écrire le
|
|
29
|
+
test » précède la tâche d'implémentation.
|
|
30
|
+
|
|
31
|
+
## 4. Lancer
|
|
32
|
+
- Ajoute la fonctionnalité dans « En cours » de `TASKS.md` avec un lien vers la spec.
|
|
33
|
+
- Implémente tâche par tâche : après chacune, lance lint / typecheck / tests, coche la tâche,
|
|
34
|
+
propose un commit.
|
|
35
|
+
- À la fin : vérifie chaque critère d'acceptation, fais relire par le sous-agent `reviewer`,
|
|
36
|
+
puis déplace la ligne dans « Terminé ».
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stress-test
|
|
3
|
+
description: Relecture critique des documents de cadrage ou d'une spec pour trouver ce qui va casser, les cas limites oubliés et le sur-engineering. À utiliser après avoir rédigé PRD/ARCHITECTURE, ou sur une spec avant de l'implémenter.
|
|
4
|
+
argument-hint: "[fichier(s) à challenger, par défaut PRD + ARCHITECTURE + DESIGN]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Stress-test
|
|
8
|
+
|
|
9
|
+
Cible : $ARGUMENTS (par défaut `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/DESIGN.md`).
|
|
10
|
+
|
|
11
|
+
Lis la cible en entier, puis réponds en jouant l'avocat du diable — un développeur senior qui doit
|
|
12
|
+
maintenir ce projet pendant 2 ans. Classe chaque point par gravité (bloquant / important / mineur).
|
|
13
|
+
|
|
14
|
+
1. **Ce qui va casser** : points de défaillance, dépendances fragiles, limites de services tiers
|
|
15
|
+
(quotas, coûts, verrouillage), montée en charge.
|
|
16
|
+
2. **Cas limites oubliés** : données vides, doublons, accès concurrents, utilisateur supprimé,
|
|
17
|
+
paiement échoué, fuseau horaire, hors ligne, gros volumes, caractères spéciaux.
|
|
18
|
+
3. **Sécurité** : passe en revue `docs/SECURITY.md` au regard de cette architecture.
|
|
19
|
+
4. **Sur-engineering** : ce qui est trop complexe pour un MVP et peut être simplifié ou reporté.
|
|
20
|
+
5. **Contradictions** entre les documents (PRD ↔ architecture ↔ design).
|
|
21
|
+
6. **Questions ouvertes** que l'utilisateur doit trancher.
|
|
22
|
+
|
|
23
|
+
Ensuite, propose les modifications concrètes à apporter aux fichiers. **N'applique qu'après
|
|
24
|
+
validation**, puis résume les risques acceptés dans « Points d'attention » d'ARCHITECTURE.md
|
|
25
|
+
(ou dans la spec si la cible est une spec).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
insert_final_newline = true
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
indent_style = space
|
|
9
|
+
indent_size = 2
|
|
10
|
+
|
|
11
|
+
[*.md]
|
|
12
|
+
trim_trailing_whitespace = false
|
|
13
|
+
|
|
14
|
+
[*.py]
|
|
15
|
+
indent_size = 4
|
|
16
|
+
|
|
17
|
+
[Makefile]
|
|
18
|
+
indent_style = tab
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Variables d'environnement attendues par le projet.
|
|
2
|
+
# Copier vers .env et compléter avec les vraies valeurs. Ne jamais committer .env.
|
|
3
|
+
# Chaque variable ajoutée au code doit apparaître ici, sans valeur, avec un commentaire.
|
|
4
|
+
# Rappel : les variables préfixées NEXT_PUBLIC_, VITE_, EXPO_PUBLIC_… sont visibles dans le navigateur.
|
|
5
|
+
|
|
6
|
+
# Exemple :
|
|
7
|
+
# DATABASE_URL= # chaîne de connexion à la base (local)
|