@dev-kosaly/kagents 0.1.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/LICENSE +34 -0
- package/README.md +35 -0
- package/agents/architect.md +166 -0
- package/agents/database_expert.md +167 -0
- package/bin/kagents.js +348 -0
- package/checklists/catalyst-change.md +10 -0
- package/checklists/review.md +26 -0
- package/commands/arch-audit.md +10 -0
- package/commands/arch-design.md +10 -0
- package/commands/arch-feature.md +10 -0
- package/commands/base-audit.md +10 -0
- package/commands/base-design.md +10 -0
- package/commands/base-evolve.md +10 -0
- package/governance/actions.yaml +36 -0
- package/package.json +34 -0
- package/skills/README.md +31 -0
- package/skills/architecture-impact/SKILL.md +68 -0
- package/skills/audit-repository/SKILL.md +53 -0
- package/skills/catalyst-export/SKILL.md +63 -0
- package/skills/db-analysis/SKILL.md +52 -0
- package/skills/db-docs/SKILL.md +177 -0
- package/skills/feature-analysis/SKILL.md +52 -0
- package/skills/schema-exploration/SKILL.md +60 -0
- package/skills/write-change-brief/SKILL.md +63 -0
- package/templates/adr/template.md +17 -0
- package/templates/change-brief/template.md +22 -0
- package/workflows/README.md +10 -0
- package/workflows/bug-local.md +9 -0
- package/workflows/existing-project.md +11 -0
- package/workflows/impact-levels.yaml +47 -0
- package/workflows/new-feature.md +13 -0
- package/workflows/new-project.md +11 -0
package/bin/kagents.js
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
// KAgents : installe le kit d'agents IA dans le projet courant.
|
|
4
|
+
// Sans dépendance. Voir `kagents --help`.
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const PKG_ROOT = path.resolve(__dirname, '..');
|
|
10
|
+
const PKG = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8'));
|
|
11
|
+
const KIT_DIRS = ['agents', 'skills', 'commands', 'templates', 'checklists', 'workflows', 'governance'];
|
|
12
|
+
const SKIP = new Set(['README.md', '.gitkeep']);
|
|
13
|
+
const BLOCK_RE = /<!-- kagents:start -->[\s\S]*?<!-- kagents:end -->/;
|
|
14
|
+
|
|
15
|
+
// Adaptateurs : un outil = une liste [dossier du kit, destination, type].
|
|
16
|
+
// type : files (fichiers), dirs (dossiers), agents (fichiers .md avec `name:`).
|
|
17
|
+
const ADAPTERS = {
|
|
18
|
+
agents: [['skills', '.agents/skills', 'dirs']],
|
|
19
|
+
claude: [
|
|
20
|
+
['commands', '.claude/commands', 'files'],
|
|
21
|
+
['skills', '.claude/skills', 'dirs'],
|
|
22
|
+
['agents', '.claude/agents', 'agents'],
|
|
23
|
+
],
|
|
24
|
+
cursor: [
|
|
25
|
+
['commands', '.cursor/commands', 'files'],
|
|
26
|
+
['skills', '.cursor/skills', 'dirs'],
|
|
27
|
+
['agents', '.cursor/agents', 'agents'],
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const HELP = `kagents ${PKG.version}
|
|
32
|
+
|
|
33
|
+
Usage : kagents [install] [--tools claude,cursor,agents|auto] [--copy]
|
|
34
|
+
kagents uninstall
|
|
35
|
+
kagents --help | --version
|
|
36
|
+
|
|
37
|
+
À lancer depuis la racine du projet.
|
|
38
|
+
--tools outils à brancher (défaut : auto = agents + claude/cursor s'ils sont détectés)
|
|
39
|
+
--copy copies au lieu de liens symboliques (aussi la variable KAGENTS_MODE=copy)
|
|
40
|
+
uninstall retire ce que KAgents a installé (docs/ est conservé)
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
const log = (m) => console.log(`kagents: ${m}`);
|
|
44
|
+
const warn = (m) => console.warn(`kagents: ATTENTION ${m}`);
|
|
45
|
+
const die = (m) => {
|
|
46
|
+
console.error(`kagents: ${m}`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// --- Arguments ----------------------------------------------------------------
|
|
51
|
+
function parseArgs(argv) {
|
|
52
|
+
const o = { cmd: 'install', tools: 'auto', copy: process.env.KAGENTS_MODE === 'copy' };
|
|
53
|
+
for (let i = 0; i < argv.length; i++) {
|
|
54
|
+
const a = argv[i];
|
|
55
|
+
if (a === '-h' || a === '--help') o.cmd = 'help';
|
|
56
|
+
else if (a === '-v' || a === '--version') o.cmd = 'version';
|
|
57
|
+
else if (a === '--copy') o.copy = true;
|
|
58
|
+
else if (a === '--tools') o.tools = argv[++i] || die('--tools attend une valeur');
|
|
59
|
+
else if (a.startsWith('--tools=')) o.tools = a.slice(8);
|
|
60
|
+
else if (a === 'install' || a === 'uninstall') o.cmd = a;
|
|
61
|
+
else if (/^[a-z,]+$/.test(a)) o.tools = a; // compat : kagents claude,cursor
|
|
62
|
+
else die(`argument inconnu : ${a}\n${HELP}`);
|
|
63
|
+
}
|
|
64
|
+
return o;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// --- Utilitaires --------------------------------------------------------------
|
|
68
|
+
// Frontmatter YAML d'une ligne par clé : { name, docs, description, ... }
|
|
69
|
+
function frontmatter(file) {
|
|
70
|
+
const lines = fs.readFileSync(file, 'utf8').split(/\r?\n/);
|
|
71
|
+
const fm = {};
|
|
72
|
+
if (lines[0] !== '---') return fm;
|
|
73
|
+
for (let i = 1; i < lines.length && lines[i] !== '---'; i++) {
|
|
74
|
+
const m = lines[i].match(/^([A-Za-z_-]+):[ \t]*(.*)$/);
|
|
75
|
+
if (m) fm[m[1]] = m[2];
|
|
76
|
+
}
|
|
77
|
+
return fm;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const exists = (p) => {
|
|
81
|
+
try {
|
|
82
|
+
fs.lstatSync(p);
|
|
83
|
+
return true;
|
|
84
|
+
} catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const listDir = (d) => (fs.existsSync(d) ? fs.readdirSync(d).sort() : []);
|
|
89
|
+
const listFiles = (dir) =>
|
|
90
|
+
listDir(dir).flatMap((n) => {
|
|
91
|
+
const p = path.join(dir, n);
|
|
92
|
+
if (SKIP.has(n)) return [];
|
|
93
|
+
return fs.statSync(p).isDirectory() ? listFiles(p) : [p];
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// --- Installateur -------------------------------------------------------------
|
|
97
|
+
class Installer {
|
|
98
|
+
constructor(target, copy) {
|
|
99
|
+
this.target = target;
|
|
100
|
+
this.copy = copy;
|
|
101
|
+
this.kagents = path.join(target, '.kagents');
|
|
102
|
+
this.manifest = path.join(this.kagents, '.installed');
|
|
103
|
+
this.entries = [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
rel(p) {
|
|
107
|
+
return path.relative(this.target, p).split(path.sep).join('/');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Place src en dest : lien relatif (repli en copie), sans jamais écraser.
|
|
111
|
+
place(src, dest) {
|
|
112
|
+
if (!fs.existsSync(src)) return;
|
|
113
|
+
if (exists(dest)) {
|
|
114
|
+
warn(`${this.rel(dest)} existe déjà et n'est pas géré par KAgents : conservé`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
118
|
+
let linked = false;
|
|
119
|
+
if (!this.copy) {
|
|
120
|
+
try {
|
|
121
|
+
const type = fs.statSync(src).isDirectory() ? 'dir' : 'file';
|
|
122
|
+
fs.symlinkSync(path.relative(path.dirname(dest), src), dest, type);
|
|
123
|
+
linked = true;
|
|
124
|
+
} catch {
|
|
125
|
+
/* pas de droits de lien (Windows) : copie */
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (!linked) fs.cpSync(src, dest, { recursive: true });
|
|
129
|
+
this.entries.push(this.rel(dest));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
cleanup() {
|
|
133
|
+
if (!fs.existsSync(this.manifest)) return [];
|
|
134
|
+
const removed = [];
|
|
135
|
+
for (const line of fs.readFileSync(this.manifest, 'utf8').split('\n')) {
|
|
136
|
+
const p = line.trim();
|
|
137
|
+
if (!p || path.isAbsolute(p) || p.split('/').includes('..')) continue;
|
|
138
|
+
const full = path.join(this.target, p);
|
|
139
|
+
if (exists(full)) fs.rmSync(full, { recursive: true, force: true });
|
|
140
|
+
removed.push(full);
|
|
141
|
+
}
|
|
142
|
+
fs.writeFileSync(this.manifest, '');
|
|
143
|
+
return removed;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
copyKit() {
|
|
147
|
+
for (const dir of KIT_DIRS) {
|
|
148
|
+
for (const f of listFiles(path.join(PKG_ROOT, dir))) {
|
|
149
|
+
const dest = path.join(this.kagents, path.relative(PKG_ROOT, f));
|
|
150
|
+
if (exists(dest)) {
|
|
151
|
+
warn(`${this.rel(dest)} existe déjà et n'est pas géré par KAgents : conservé`);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
155
|
+
fs.copyFileSync(f, dest);
|
|
156
|
+
this.entries.push(this.rel(dest));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const v = path.join(this.kagents, 'VERSION');
|
|
160
|
+
fs.writeFileSync(v, PKG.version + '\n');
|
|
161
|
+
this.entries.push(this.rel(v));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
createDocs() {
|
|
165
|
+
fs.mkdirSync(path.join(this.kagents, 'docs', 'knowledge'), { recursive: true });
|
|
166
|
+
for (const f of listDir(path.join(this.kagents, 'agents'))) {
|
|
167
|
+
if (!f.endsWith('.md')) continue;
|
|
168
|
+
const docs = frontmatter(path.join(this.kagents, 'agents', f)).docs;
|
|
169
|
+
if (docs) fs.mkdirSync(path.join(this.kagents, 'docs', docs), { recursive: true });
|
|
170
|
+
}
|
|
171
|
+
const ctx = path.join(this.kagents, 'docs', 'knowledge', 'context.md');
|
|
172
|
+
if (!fs.existsSync(ctx)) {
|
|
173
|
+
fs.writeFileSync(
|
|
174
|
+
ctx,
|
|
175
|
+
`# Contexte projet
|
|
176
|
+
|
|
177
|
+
Document partagé, écrit par l'utilisateur. Les agents le lisent, ne l'écrivent pas.
|
|
178
|
+
|
|
179
|
+
## Intention
|
|
180
|
+
|
|
181
|
+
- Ce que le système doit faire, pour qui :
|
|
182
|
+
|
|
183
|
+
## Stack
|
|
184
|
+
|
|
185
|
+
-
|
|
186
|
+
|
|
187
|
+
## Contraintes
|
|
188
|
+
|
|
189
|
+
-
|
|
190
|
+
|
|
191
|
+
## Références
|
|
192
|
+
|
|
193
|
+
-
|
|
194
|
+
`,
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
renderBlock() {
|
|
200
|
+
const agentsDir = path.join(this.kagents, 'agents');
|
|
201
|
+
const cmdDir = path.join(this.kagents, 'commands');
|
|
202
|
+
const agentRows = [];
|
|
203
|
+
const names = {};
|
|
204
|
+
for (const f of listDir(agentsDir).filter((n) => n.endsWith('.md'))) {
|
|
205
|
+
const fm = frontmatter(path.join(agentsDir, f));
|
|
206
|
+
const stem = f.replace(/\.md$/, '');
|
|
207
|
+
names[stem] = fm.name || stem;
|
|
208
|
+
const desc = (fm.description || '').split('. ')[0] || '—';
|
|
209
|
+
agentRows.push(`| ${names[stem]} | \`.kagents/agents/${f}\` | ${desc} |`);
|
|
210
|
+
}
|
|
211
|
+
const routeRows = [];
|
|
212
|
+
for (const f of listDir(cmdDir).filter((n) => n.endsWith('.md'))) {
|
|
213
|
+
const fm = frontmatter(path.join(cmdDir, f));
|
|
214
|
+
const agent = names[fm.agent] || fm.agent || '—';
|
|
215
|
+
routeRows.push(
|
|
216
|
+
`| ${fm.triggers || fm.description || '—'} | \`/${f.replace(/\.md$/, '')}\` | ${agent} | ${fm.mode || '—'} |`,
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
return [
|
|
220
|
+
'<!-- kagents:start -->',
|
|
221
|
+
'## KAgents',
|
|
222
|
+
'',
|
|
223
|
+
`Kit d'agents IA installé dans \`.kagents/\` (v${PKG.version}). Ce bloc est régénéré par \`kagents\` : ne pas l'éditer.`,
|
|
224
|
+
'',
|
|
225
|
+
"**Utilisation** : lance une commande (ex. `/base-audit`). Sans commandes dans ton outil, lis le fichier indiqué dans `.kagents/commands/` et applique-le. Contexte partagé : `.kagents/docs/knowledge/context.md`. Chaque agent n'écrit que dans son espace `.kagents/docs/<agent>-docs/`.",
|
|
226
|
+
'',
|
|
227
|
+
'### Agents',
|
|
228
|
+
'',
|
|
229
|
+
'| Agent | Fichier | Rôle |',
|
|
230
|
+
'|---|---|---|',
|
|
231
|
+
...agentRows,
|
|
232
|
+
'',
|
|
233
|
+
'### Routage',
|
|
234
|
+
'',
|
|
235
|
+
'| Demande | Commande | Agent | Mode |',
|
|
236
|
+
'|---|---|---|---|',
|
|
237
|
+
...routeRows,
|
|
238
|
+
'<!-- kagents:end -->',
|
|
239
|
+
].join('\n');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
writeAgentsMd() {
|
|
243
|
+
const file = path.join(this.target, 'AGENTS.md');
|
|
244
|
+
const block = this.renderBlock();
|
|
245
|
+
let out;
|
|
246
|
+
if (fs.existsSync(file)) {
|
|
247
|
+
const cur = fs.readFileSync(file, 'utf8');
|
|
248
|
+
out = BLOCK_RE.test(cur) ? cur.replace(BLOCK_RE, () => block) : cur.replace(/\n*$/, '\n\n') + block + '\n';
|
|
249
|
+
} else {
|
|
250
|
+
out = block + '\n';
|
|
251
|
+
}
|
|
252
|
+
fs.writeFileSync(file, out);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
resolveTools(tools) {
|
|
256
|
+
if (tools !== 'auto') return tools.split(',').filter(Boolean);
|
|
257
|
+
const t = ['agents'];
|
|
258
|
+
const has = (p) => fs.existsSync(path.join(this.target, p));
|
|
259
|
+
if (has('.claude') || has('CLAUDE.md')) t.push('claude');
|
|
260
|
+
if (has('.cursor')) t.push('cursor');
|
|
261
|
+
return t;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
runAdapters(tools) {
|
|
265
|
+
for (const tool of this.resolveTools(tools)) {
|
|
266
|
+
if (!ADAPTERS[tool]) {
|
|
267
|
+
warn(`outil inconnu : ${tool} (disponibles : ${Object.keys(ADAPTERS).join(', ')})`);
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
for (const [from, to, kind] of ADAPTERS[tool]) {
|
|
271
|
+
const srcDir = path.join(this.kagents, from);
|
|
272
|
+
for (const name of listDir(srcDir)) {
|
|
273
|
+
const src = path.join(srcDir, name);
|
|
274
|
+
if (SKIP.has(name)) continue;
|
|
275
|
+
const isDir = fs.statSync(src).isDirectory();
|
|
276
|
+
if (kind === 'dirs' && !isDir) continue;
|
|
277
|
+
if (kind !== 'dirs' && isDir) continue;
|
|
278
|
+
if (kind === 'agents') {
|
|
279
|
+
if (!name.endsWith('.md')) continue;
|
|
280
|
+
if (!frontmatter(src).name) {
|
|
281
|
+
warn(`agent ${name} sans frontmatter 'name:' : non exposé à l'outil`);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
this.place(src, path.join(this.target, to, name));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
log(`${tool} : branché`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
saveManifest() {
|
|
293
|
+
fs.mkdirSync(this.kagents, { recursive: true });
|
|
294
|
+
fs.writeFileSync(this.manifest, this.entries.join('\n') + '\n');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Supprime les dossiers vides laissés par la désinstallation (jamais .claude/.cursor eux-mêmes).
|
|
298
|
+
prune(removed) {
|
|
299
|
+
const keep = new Set([this.target, path.join(this.target, '.claude'), path.join(this.target, '.cursor')]);
|
|
300
|
+
for (const p of removed) {
|
|
301
|
+
for (let d = path.dirname(p); d.startsWith(this.target) && !keep.has(d); d = path.dirname(d)) {
|
|
302
|
+
if (!fs.existsSync(d) || fs.readdirSync(d).length) break;
|
|
303
|
+
fs.rmdirSync(d);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
install(tools) {
|
|
309
|
+
fs.mkdirSync(this.kagents, { recursive: true });
|
|
310
|
+
this.cleanup();
|
|
311
|
+
this.copyKit();
|
|
312
|
+
this.createDocs();
|
|
313
|
+
this.writeAgentsMd();
|
|
314
|
+
this.runAdapters(tools);
|
|
315
|
+
this.saveManifest();
|
|
316
|
+
log(`installé dans ${this.kagents} (${this.copy ? 'copies' : 'liens'})`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
uninstall() {
|
|
320
|
+
const removed = this.cleanup();
|
|
321
|
+
const file = path.join(this.target, 'AGENTS.md');
|
|
322
|
+
if (fs.existsSync(file)) {
|
|
323
|
+
const cur = fs.readFileSync(file, 'utf8');
|
|
324
|
+
if (BLOCK_RE.test(cur)) {
|
|
325
|
+
const out = cur.replace(BLOCK_RE, '').replace(/\n{3,}/g, '\n\n').replace(/\s+$/, '');
|
|
326
|
+
if (out) fs.writeFileSync(file, out + '\n');
|
|
327
|
+
else fs.rmSync(file);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
fs.rmSync(this.manifest, { force: true });
|
|
331
|
+
this.prune(removed);
|
|
332
|
+
log('désinstallé (.kagents/docs/ conservé : ce sont vos livrables)');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// --- Main ---------------------------------------------------------------------
|
|
337
|
+
function main() {
|
|
338
|
+
const o = parseArgs(process.argv.slice(2));
|
|
339
|
+
if (o.cmd === 'help') return console.log(HELP);
|
|
340
|
+
if (o.cmd === 'version') return console.log(PKG.version);
|
|
341
|
+
const target = process.cwd();
|
|
342
|
+
if (path.resolve(target) === PKG_ROOT) die("à lancer depuis la racine d'un projet, pas depuis le kit.");
|
|
343
|
+
const inst = new Installer(target, o.copy);
|
|
344
|
+
if (o.cmd === 'uninstall') inst.uninstall();
|
|
345
|
+
else inst.install(o.tools);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
main();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Checklist — Changement Catalyst
|
|
2
|
+
|
|
3
|
+
- [ ] Data Store / ZCQL : requetes necessaires et bornees
|
|
4
|
+
- [ ] Functions : decoupage et frequence d'appel raisonnables
|
|
5
|
+
- [ ] Cache : usage justifie, invalidation claire
|
|
6
|
+
- [ ] APIs : pas de transferts inutiles
|
|
7
|
+
- [ ] Evenements / polling : pas de boucle active inutile
|
|
8
|
+
- [ ] Auth : flux conforme au standard projet
|
|
9
|
+
|
|
10
|
+
Reference future : `standards/catalyst/`
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Checklist — Revue
|
|
2
|
+
|
|
3
|
+
## General
|
|
4
|
+
|
|
5
|
+
- [ ] Coherent avec `STATE.md` et ADR
|
|
6
|
+
- [ ] Change Brief respecte si L2+
|
|
7
|
+
- [ ] Tests adequats
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
- [ ] Pas de decision archi non documentee
|
|
12
|
+
|
|
13
|
+
## Donnees
|
|
14
|
+
|
|
15
|
+
- [ ] Source de verite unique ou exception documentee
|
|
16
|
+
- [ ] Migrations reversibles ou plan de rollback
|
|
17
|
+
|
|
18
|
+
## Securite
|
|
19
|
+
|
|
20
|
+
- [ ] Pas de secret en clair
|
|
21
|
+
- [ ] Permissions justifiees
|
|
22
|
+
|
|
23
|
+
## Performance et cout
|
|
24
|
+
|
|
25
|
+
- [ ] Pas de N+1 / requetes repetees evidentes
|
|
26
|
+
- [ ] Catalyst : voir `catalyst-change.md` si applicable
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Architect — état des lieux d'un projet existant
|
|
3
|
+
agent: architect
|
|
4
|
+
mode: B (Projet existant)
|
|
5
|
+
triggers: analyse mon projet existant, cartographie le repo, onboarding
|
|
6
|
+
---
|
|
7
|
+
Lis `.kagents/agents/architect.md` et applique-le en **situation B. Projet existant**.
|
|
8
|
+
Charge ensuite uniquement les skills que cette situation indique, depuis `.kagents/skills/`.
|
|
9
|
+
|
|
10
|
+
Demande de l'utilisateur : $ARGUMENTS
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Architect — cadrage d'un nouveau projet
|
|
3
|
+
agent: architect
|
|
4
|
+
mode: A (Nouveau projet)
|
|
5
|
+
triggers: cadre mon nouveau projet, architecture d'un nouveau projet
|
|
6
|
+
---
|
|
7
|
+
Lis `.kagents/agents/architect.md` et applique-le en **situation A. Nouveau projet**.
|
|
8
|
+
Charge ensuite uniquement les skills que cette situation indique, depuis `.kagents/skills/`.
|
|
9
|
+
|
|
10
|
+
Demande de l'utilisateur : $ARGUMENTS
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Architect — analyse d'une fonctionnalité ou modification
|
|
3
|
+
agent: architect
|
|
4
|
+
mode: C (Feature / modification)
|
|
5
|
+
triggers: analyse cette fonctionnalité, impact d'un changement, cadre ce ticket
|
|
6
|
+
---
|
|
7
|
+
Lis `.kagents/agents/architect.md` et applique-le en **situation C. Feature / modification**.
|
|
8
|
+
Charge ensuite uniquement les skills que cette situation indique, depuis `.kagents/skills/`.
|
|
9
|
+
|
|
10
|
+
Demande de l'utilisateur : $ARGUMENTS
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Base — audit de la base de données
|
|
3
|
+
agent: database_expert
|
|
4
|
+
mode: B (Audit)
|
|
5
|
+
triggers: audite ma base, analyse ma base de données, vérifie mon schéma
|
|
6
|
+
---
|
|
7
|
+
Lis `.kagents/agents/database_expert.md` et applique-le en **mode B (Audit)**.
|
|
8
|
+
Charge ensuite uniquement les skills que ce mode indique, depuis `.kagents/skills/`.
|
|
9
|
+
|
|
10
|
+
Demande de l'utilisateur : $ARGUMENTS
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Base — conception du modèle de données
|
|
3
|
+
agent: database_expert
|
|
4
|
+
mode: A (Conception)
|
|
5
|
+
triggers: conçois ma base, modèle de données d'un nouveau projet
|
|
6
|
+
---
|
|
7
|
+
Lis `.kagents/agents/database_expert.md` et applique-le en **mode A (Conception)**.
|
|
8
|
+
Charge ensuite uniquement les skills que ce mode indique, depuis `.kagents/skills/`.
|
|
9
|
+
|
|
10
|
+
Demande de l'utilisateur : $ARGUMENTS
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Base — analyse d'impact d'une fonctionnalité sur la base
|
|
3
|
+
agent: database_expert
|
|
4
|
+
mode: C (Évolution)
|
|
5
|
+
triggers: impact d'une fonctionnalité sur la base, je dois ajouter/modifier une table
|
|
6
|
+
---
|
|
7
|
+
Lis `.kagents/agents/database_expert.md` et applique-le en **mode C (Évolution)**.
|
|
8
|
+
Charge ensuite uniquement les skills que ce mode indique, depuis `.kagents/skills/`.
|
|
9
|
+
|
|
10
|
+
Demande de l'utilisateur : $ARGUMENTS
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Matrice de gouvernance — Engineering Harness
|
|
2
|
+
# Niveaux : automatic | propose | human_required | forbidden
|
|
3
|
+
|
|
4
|
+
categories:
|
|
5
|
+
automatic:
|
|
6
|
+
description: L'agent peut executer sans validation prealable.
|
|
7
|
+
examples:
|
|
8
|
+
- Lire le code et la documentation du repo
|
|
9
|
+
- Executer les scripts de validation du harness (scripts/)
|
|
10
|
+
- Corriger typos dans docs/harness sans changement de gouvernance
|
|
11
|
+
- Ajouter ou ajuster rules/skills/workflows dans ce repo apres validation humaine du PR
|
|
12
|
+
|
|
13
|
+
propose:
|
|
14
|
+
description: L'agent prepare le changement ; merge ou application apres revue humaine.
|
|
15
|
+
examples:
|
|
16
|
+
- Nouvelle rule ou skill
|
|
17
|
+
- Modification de standards/
|
|
18
|
+
- Refactoring structurel du harness
|
|
19
|
+
- Change Brief ou ADR draft (dans le repo projet)
|
|
20
|
+
|
|
21
|
+
human_required:
|
|
22
|
+
description: Validation humaine explicite avant execution ou deploiement.
|
|
23
|
+
examples:
|
|
24
|
+
- Decision d'architecture (ADR acceptee)
|
|
25
|
+
- Schema BDD significatif ou migration destructive
|
|
26
|
+
- Permissions, securite, donnees sensibles
|
|
27
|
+
- Production, suppression de donnees
|
|
28
|
+
- Release semver du harness (tag VERSION)
|
|
29
|
+
|
|
30
|
+
forbidden:
|
|
31
|
+
description: Interdit pour tout agent en conditions normales.
|
|
32
|
+
examples:
|
|
33
|
+
- Acces direct a la production ou secrets live
|
|
34
|
+
- push --force sur main
|
|
35
|
+
- Contourner hooks ou CI
|
|
36
|
+
- Centraliser STATE/schema d'un projet client dans ce repo
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dev-kosaly/kagents",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Kit d'agents IA d'ingénierie installable dans un projet (Claude Code, Cursor, AGENTS.md)",
|
|
5
|
+
"bin": {
|
|
6
|
+
"kagents": "bin/kagents.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin",
|
|
10
|
+
"agents",
|
|
11
|
+
"skills",
|
|
12
|
+
"commands",
|
|
13
|
+
"templates",
|
|
14
|
+
"checklists",
|
|
15
|
+
"workflows",
|
|
16
|
+
"governance"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"keywords": ["ai", "agents", "claude-code", "cursor", "agents-md", "database"],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+ssh://git@github.com/ScaleTaBoite/kosaly-dev-ai-agents.git"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"test": "node scripts/smoke-test.js",
|
|
31
|
+
"prepublishOnly": "npm test"
|
|
32
|
+
},
|
|
33
|
+
"license": "SEE LICENSE IN LICENSE"
|
|
34
|
+
}
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Skills
|
|
2
|
+
|
|
3
|
+
Une procedure = un dossier avec `SKILL.md` (frontmatter `name`, `description`).
|
|
4
|
+
|
|
5
|
+
## Architect / Spec (implementees)
|
|
6
|
+
|
|
7
|
+
| Skill | Role |
|
|
8
|
+
|-------|------|
|
|
9
|
+
| `feature-analysis/` | Demande feature ou modification fonctionnelle |
|
|
10
|
+
| `audit-repository/` | Cartographie projet existant |
|
|
11
|
+
| `architecture-impact/` | Impacts et niveau L0–L3 |
|
|
12
|
+
| `write-change-brief/` | Change Brief dans le repo projet |
|
|
13
|
+
|
|
14
|
+
Role canonique : `agents/architect.md`.
|
|
15
|
+
|
|
16
|
+
## Base / base de donnees (implementees)
|
|
17
|
+
|
|
18
|
+
| Skill | Role |
|
|
19
|
+
|-------|------|
|
|
20
|
+
| `schema-exploration/` | Explorer le repo et reconstruire le modele |
|
|
21
|
+
| `catalyst-export/` | Exploiter l'export JSON Catalyst |
|
|
22
|
+
| `db-analysis/` | Grille d'analyse et severites |
|
|
23
|
+
| `db-docs/` | Modeles des fichiers de `base-docs/db/` |
|
|
24
|
+
|
|
25
|
+
Agent : `agents/database_expert.md`.
|
|
26
|
+
|
|
27
|
+
## A venir (hors perimetre actuel)
|
|
28
|
+
|
|
29
|
+
- `write-adr/`
|
|
30
|
+
- `catalyst-impact/` (analyse detaillee)
|
|
31
|
+
- `init-project-artifacts/`
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture-impact
|
|
3
|
+
description: >-
|
|
4
|
+
Evalue impacts multi-axes (metier, archi, BDD, backend, frontend, securite,
|
|
5
|
+
perf, cout) et determine le niveau L0-L3 avec justification. A utiliser apres
|
|
6
|
+
feature-analysis ou audit-repository.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Architecture impact
|
|
10
|
+
|
|
11
|
+
## Quand utiliser
|
|
12
|
+
|
|
13
|
+
- Apres comprehension initiale de la demande (`feature-analysis` ou `audit-repository`).
|
|
14
|
+
- Des qu'un doute existe sur L1 vs L2 vs L3.
|
|
15
|
+
- Avant `write-change-brief` pour L2+.
|
|
16
|
+
|
|
17
|
+
Reference canonique des niveaux : `workflows/impact-levels.yaml`.
|
|
18
|
+
|
|
19
|
+
## Prerequis
|
|
20
|
+
|
|
21
|
+
- Goal et perimetre connus (meme partiellement).
|
|
22
|
+
- Findings existant disponibles ou N/A (nouveau projet greenfield).
|
|
23
|
+
|
|
24
|
+
## Fichiers a lire
|
|
25
|
+
|
|
26
|
+
- `workflows/impact-levels.yaml`
|
|
27
|
+
- Projet : `schema.yaml`, ADR liees, `STATE.md` (zones protegees)
|
|
28
|
+
- `checklists/catalyst-change.md` si stack Catalyst probable
|
|
29
|
+
- `standards/README.md` — ouvrir un standard domaine **seulement** si l'impact de ce domaine est non trivial
|
|
30
|
+
|
|
31
|
+
## Etapes
|
|
32
|
+
|
|
33
|
+
1. Remplir **Impact** (une ligne ou courte liste par axe ; « None » si vraiment aucun) :
|
|
34
|
+
|
|
35
|
+
| Axe | Contenu attendu |
|
|
36
|
+
|-----|-----------------|
|
|
37
|
+
| Business | regles, acteurs, changement comportement |
|
|
38
|
+
| Architecture | modules, boundaries, nouveaux composants |
|
|
39
|
+
| Database | voir formulations types dans `agents/architect.md` ; pas de DDL |
|
|
40
|
+
| Backend | API, jobs, integrations |
|
|
41
|
+
| Frontend | ecrans, etat, UX |
|
|
42
|
+
| Security | auth, permissions, donnees sensibles, nouvelles API |
|
|
43
|
+
| Performance | volume, latence, requetes repetees |
|
|
44
|
+
| Cost | Catalyst / infra ; signalement analyse detaillee si besoin |
|
|
45
|
+
|
|
46
|
+
2. **Choisir L0–L3** et remplir **Why** en 1–3 phrases.
|
|
47
|
+
|
|
48
|
+
Guide rapide :
|
|
49
|
+
|
|
50
|
+
- **L0** : local, pas API/BDD/archi/permissions.
|
|
51
|
+
- **L1** : feature localisee, contrat stable.
|
|
52
|
+
- **L2** : BDD, API, multi-modules ou multi-couches.
|
|
53
|
+
- **L3** : archi structurante, migration sensible, permissions majeures, securite critique, changement metier majeur.
|
|
54
|
+
|
|
55
|
+
3. **Proposal** : option retenue (simple par defaut) + alternatives ecartees en une phrase si utile.
|
|
56
|
+
4. **Decisions** : separer Accepted / To validate / Existing preserved.
|
|
57
|
+
5. **Risks / Exceptions** : regression, duplication data, hypothese non validee.
|
|
58
|
+
6. **Acceptance Criteria** : testables, orientes metier/tech sans implementation detaillee.
|
|
59
|
+
|
|
60
|
+
## Resultat attendu
|
|
61
|
+
|
|
62
|
+
- Sections Impact, Impact Level, Proposal, Decisions, Acceptance Criteria, Risks de l'**Architect Analysis** completees.
|
|
63
|
+
- Indication explicite : Database Architect requis (oui/non), ADR requise (oui/non), validation humaine (selon L2/L3).
|
|
64
|
+
|
|
65
|
+
## Proportionnalite
|
|
66
|
+
|
|
67
|
+
- L0/L1 : Impact peut etre bref ; pas de Change Brief obligatoire sauf equipe l'exige.
|
|
68
|
+
- L2/L3 : Impact complet ; Change Brief + validation selon `impact-levels.yaml`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: audit-repository
|
|
3
|
+
description: >-
|
|
4
|
+
Cartographie un projet existant ou un codebase avant changement (situation B,
|
|
5
|
+
ou A avec code deja present). Stack, modules, flux, ADR, zones protegees.
|
|
6
|
+
Sortie synthese pour Architect Analysis ou onboarding.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Audit repository
|
|
10
|
+
|
|
11
|
+
## Quand utiliser
|
|
12
|
+
|
|
13
|
+
- **Projet existant** : onboarding, audit initial, avant grosse feature (situation **B**).
|
|
14
|
+
- **Nouveau projet** avec code deja present (legacy, template, fork) — situation **A** partielle.
|
|
15
|
+
- Avant `feature-analysis` si l'agent ne connait pas la structure du repo.
|
|
16
|
+
|
|
17
|
+
Ne pas remplacer une exploration exhaustive : produire une **synthese actionnable** pour l'Architect.
|
|
18
|
+
|
|
19
|
+
## Prerequis
|
|
20
|
+
|
|
21
|
+
- Racine du repo projet identifiee.
|
|
22
|
+
- Lire d'abord les artefacts projet avant le code.
|
|
23
|
+
|
|
24
|
+
## Fichiers a lire (ordre)
|
|
25
|
+
|
|
26
|
+
1. `AGENTS.md`, `STATE.md`, `project.yaml`
|
|
27
|
+
2. `business-rules.md`, `glossary.md`, `schema.yaml`, `debt.yaml` (si present)
|
|
28
|
+
3. ADR dans le repo (souvent `docs/adr/` ou racine — chercher `ADR` par nom, limiter aux 5–10 plus recents ou pertinents)
|
|
29
|
+
4. Manifestes stack : `package.json`, `composer.json`, `catalyst.json`, README projet, configs deploy — **ceux presents uniquement**
|
|
30
|
+
5. Code : arborescence de premier niveau + dossiers mentionnes dans STATE/debt ; approfondir seulement les zones liees a la demande courante
|
|
31
|
+
|
|
32
|
+
Harness : `workflows/existing-project.md` pour alignement processus.
|
|
33
|
+
|
|
34
|
+
## Etapes
|
|
35
|
+
|
|
36
|
+
1. **Stack** : langages, frameworks, hebergement (dont Catalyst si indices).
|
|
37
|
+
2. **Architecture actuelle** : decoupage modules / couches en 5–15 lignes max.
|
|
38
|
+
3. **Flux principaux** touches ou a risque (si demande connue) ; sinon flux generiques entree/sortie.
|
|
39
|
+
4. **Decisions** : ADR acceptees resumees ; contradictions possibles avec la demande.
|
|
40
|
+
5. **Zones protegees** : depuis `STATE.md` ou deduction explicite *hypothesis*.
|
|
41
|
+
6. **Fichiers / composants cles** : liste courte avec role (pas dump de tree).
|
|
42
|
+
7. **Dette** : pointer `debt.yaml` ou observations majeures si visibles sans lire tout le code.
|
|
43
|
+
8. Integrer les findings dans **Architect Analysis** → sections Context, Found, Artifacts.
|
|
44
|
+
|
|
45
|
+
## Resultat attendu
|
|
46
|
+
|
|
47
|
+
- Section **Found** et **Artifacts** de l'Architect Analysis remplies.
|
|
48
|
+
- **Next Step** : feature-analysis, architecture-impact, ou write-change-brief selon la demande suivante.
|
|
49
|
+
|
|
50
|
+
## Limites
|
|
51
|
+
|
|
52
|
+
- Pas de refactoring propose dans l'audit.
|
|
53
|
+
- Pas de revue securite complete (signaler surfaces evidentes seulement).
|