266 lines
7.1 KiB
Markdown
266 lines
7.1 KiB
Markdown
# Tooling Mesh — Pre-commit (headers) + Snippets VS Code
|
|
|
|
Ce document fournit :
|
|
1) un **contrôle automatique** (pre-commit) qui vérifie la présence des headers de traçabilité Mesh
|
|
2) des **snippets VS Code** pour insérer rapidement les headers
|
|
|
|
Référence normative : `docs/headers-template.md`.
|
|
|
|
---
|
|
|
|
## 1) Pre-commit : vérification des headers
|
|
|
|
### 1.1 Fichiers à ajouter
|
|
|
|
#### `.pre-commit-config.yaml` (à la racine)
|
|
```yaml
|
|
repos:
|
|
- repo: local
|
|
hooks:
|
|
- id: mesh-traceability-headers
|
|
name: Mesh traceability headers check
|
|
entry: python3 scripts/check_trace_headers.py
|
|
language: system
|
|
types_or: [python, javascript, typescript, rust, yaml, toml, markdown, css, html]
|
|
pass_filenames: true
|
|
```
|
|
|
|
#### `scripts/check_trace_headers.py`
|
|
```python
|
|
#!/usr/bin/env python3
|
|
# Created by: Claude — 2025-12-29
|
|
# Purpose: Validate Mesh traceability headers in repo files
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# File extensions we validate
|
|
VALID_EXTS = {
|
|
".rs",
|
|
".py",
|
|
".ts",
|
|
".tsx",
|
|
".js",
|
|
".jsx",
|
|
".yml",
|
|
".yaml",
|
|
".toml",
|
|
".md",
|
|
".css",
|
|
".html",
|
|
".htm",
|
|
}
|
|
|
|
# For markdown we allow HTML comment headers
|
|
HEADER_PATTERNS = [
|
|
re.compile(r"^\s*//\s*Created by:\s*.+$", re.IGNORECASE),
|
|
re.compile(r"^\s*#\s*Created by:\s*.+$", re.IGNORECASE),
|
|
re.compile(r"^\s*/\*\s*$", re.IGNORECASE),
|
|
re.compile(r"^\s*<!--\s*$", re.IGNORECASE),
|
|
]
|
|
|
|
REQUIRED_FIELDS = [
|
|
re.compile(r"Created by:\s*.+", re.IGNORECASE),
|
|
re.compile(r"Date:\s*\d{4}-\d{2}-\d{2}", re.IGNORECASE),
|
|
re.compile(r"Purpose:\s*.+", re.IGNORECASE),
|
|
]
|
|
|
|
|
|
def is_text_file(path: Path) -> bool:
|
|
# basic heuristic: try decode as utf-8
|
|
try:
|
|
path.read_text(encoding="utf-8")
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def has_required_header(text: str) -> bool:
|
|
# Check within first 40 lines
|
|
head = "\n".join(text.splitlines()[:40])
|
|
if not any(p.search(head) for p in HEADER_PATTERNS):
|
|
return False
|
|
return all(p.search(head) for p in REQUIRED_FIELDS)
|
|
|
|
|
|
def main(argv: list[str]) -> int:
|
|
files = [Path(a) for a in argv[1:] if a and not a.startswith("-")]
|
|
if not files:
|
|
return 0
|
|
|
|
bad: list[str] = []
|
|
|
|
for f in files:
|
|
if not f.exists() or f.is_dir():
|
|
continue
|
|
if f.suffix.lower() not in VALID_EXTS:
|
|
continue
|
|
if not is_text_file(f):
|
|
continue
|
|
|
|
txt = f.read_text(encoding="utf-8", errors="replace")
|
|
if not has_required_header(txt):
|
|
bad.append(str(f))
|
|
|
|
if bad:
|
|
sys.stderr.write("\nMesh header check failed. Missing/invalid traceability header in:\n")
|
|
for b in bad:
|
|
sys.stderr.write(f"- {b}\n")
|
|
sys.stderr.write("\nExpected header fields near top of file: Created by, Date (YYYY-MM-DD), Purpose.\n")
|
|
sys.stderr.write("See: docs/headers-template.md\n\n")
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main(sys.argv))
|
|
```
|
|
|
|
#### `scripts/check_trace_headers.py` (permissions)
|
|
```bash
|
|
chmod +x scripts/check_trace_headers.py
|
|
```
|
|
|
|
### 1.2 Installation pre-commit
|
|
```bash
|
|
pipx install pre-commit # ou pip install pre-commit
|
|
pre-commit install
|
|
pre-commit run --all-files
|
|
```
|
|
|
|
### 1.3 Notes
|
|
- Ce hook vérifie uniquement les **headers de création** (Created by / Date / Purpose) dans les premières lignes.
|
|
- La traçabilité des **modifications ponctuelles** (fin de ligne) reste une règle humaine + revue.
|
|
- Si tu veux imposer aussi `Modified by` dans certaines conditions, on peut ajouter une règle (par ex. pour fichiers existants dans Git).
|
|
|
|
---
|
|
|
|
## 2) Snippets VS Code
|
|
|
|
### 2.1 Fichier snippets à ajouter
|
|
Créer : `.vscode/mesh.code-snippets`
|
|
|
|
```json
|
|
{
|
|
"Mesh Header — Rust": {
|
|
"prefix": "mesh-header-rs",
|
|
"body": [
|
|
"// Created by: ${1:AgentName}",
|
|
"// Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"// Purpose: ${2:Short description}",
|
|
"// Refs: ${3:optional}",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for Rust files"
|
|
},
|
|
"Mesh Header — Python": {
|
|
"prefix": "mesh-header-py",
|
|
"body": [
|
|
"# Created by: ${1:AgentName}",
|
|
"# Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"# Purpose: ${2:Short description}",
|
|
"# Refs: ${3:optional}",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for Python files"
|
|
},
|
|
"Mesh Header — TS/JS": {
|
|
"prefix": "mesh-header-ts",
|
|
"body": [
|
|
"// Created by: ${1:AgentName}",
|
|
"// Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"// Purpose: ${2:Short description}",
|
|
"// Refs: ${3:optional}",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for TypeScript/JavaScript files"
|
|
},
|
|
"Mesh Header — YAML": {
|
|
"prefix": "mesh-header-yaml",
|
|
"body": [
|
|
"# Created by: ${1:AgentName}",
|
|
"# Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"# Purpose: ${2:Short description}",
|
|
"# Refs: ${3:optional}",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for YAML files"
|
|
},
|
|
"Mesh Header — TOML": {
|
|
"prefix": "mesh-header-toml",
|
|
"body": [
|
|
"# Created by: ${1:AgentName}",
|
|
"# Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"# Purpose: ${2:Short description}",
|
|
"# Refs: ${3:optional}",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for TOML files"
|
|
},
|
|
"Mesh Header — Markdown": {
|
|
"prefix": "mesh-header-md",
|
|
"body": [
|
|
"<!--",
|
|
"Created by: ${1:AgentName}",
|
|
"Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"Purpose: ${2:Short description}",
|
|
"Refs: ${3:optional}",
|
|
"-->",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for Markdown files"
|
|
},
|
|
"Mesh Header — CSS": {
|
|
"prefix": "mesh-header-css",
|
|
"body": [
|
|
"/*",
|
|
"Created by: ${1:AgentName}",
|
|
"Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"Purpose: ${2:Short description}",
|
|
"Refs: ${3:optional}",
|
|
"*/",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for CSS files"
|
|
},
|
|
"Mesh Header — HTML": {
|
|
"prefix": "mesh-header-html",
|
|
"body": [
|
|
"<!--",
|
|
"Created by: ${1:AgentName}",
|
|
"Date: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}",
|
|
"Purpose: ${2:Short description}",
|
|
"Refs: ${3:optional}",
|
|
"-->",
|
|
""
|
|
],
|
|
"description": "Insert Mesh traceability header for HTML files"
|
|
},
|
|
"Mesh Modified Tag": {
|
|
"prefix": "mesh-mod",
|
|
"body": [
|
|
"Modified by: ${1:AgentName} — ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} — ${2:reason}"
|
|
],
|
|
"description": "Insert a Mesh modified-by tag"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2.2 Activation
|
|
Les snippets dans `.vscode/*.code-snippets` sont automatiquement pris en compte par VS Code.
|
|
|
|
Utilisation :
|
|
- taper `mesh-header-` puis sélectionner le snippet.
|
|
|
|
---
|
|
|
|
## 3) Recommandation Mesh
|
|
- Appliquer le hook pre-commit sur tous les développeurs.
|
|
- Dans Codex, fixer `AgentName` à une valeur stable (ex. `Codex`).
|
|
- Pour les sous-agents : `SubAgent:SecurityReview`, etc.
|
|
|