@dev-kosaly/kagents 0.1.0 → 0.2.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.
Files changed (44) hide show
  1. package/README.md +99 -20
  2. package/agents/architect.md +84 -116
  3. package/bin/kagents.js +178 -15
  4. package/bin/postinstall.js +26 -0
  5. package/commands/architect-audit.md +17 -0
  6. package/commands/architect-compare.md +13 -0
  7. package/commands/architect-decision.md +20 -0
  8. package/commands/architect-design.md +18 -0
  9. package/commands/architect-impact.md +16 -0
  10. package/commands/architect-spec.md +18 -0
  11. package/commands/architect-status.md +26 -0
  12. package/commands/architect.md +20 -0
  13. package/docs/architect-commands.md +52 -0
  14. package/package.json +5 -2
  15. package/rules/domains/architect-chat.md +61 -0
  16. package/rules/domains/architect-invariants.md +22 -0
  17. package/skills/README.md +17 -20
  18. package/skills/architect-audit/SKILL.md +31 -0
  19. package/skills/architect-decision/SKILL.md +40 -0
  20. package/skills/architect-discovery/SKILL.md +43 -0
  21. package/skills/architect-impact/SKILL.md +32 -0
  22. package/skills/architect-index/SKILL.md +31 -0
  23. package/skills/architect-status/SKILL.md +41 -0
  24. package/skills/architect-write-output/SKILL.md +49 -0
  25. package/templates/architect-decision/template.md +47 -0
  26. package/templates/architect-design/template.md +31 -0
  27. package/templates/architect-index/INDEX.template.md +47 -0
  28. package/templates/architect-output/template.md +95 -0
  29. package/templates/architect-spec/template.md +39 -0
  30. package/workflows/architect-architecture.md +19 -0
  31. package/workflows/architect-audit-run.md +14 -0
  32. package/workflows/architect-decision.md +20 -0
  33. package/workflows/architect-design.md +15 -0
  34. package/workflows/architect-impact-levels.yaml +28 -0
  35. package/workflows/architect-impact.md +20 -0
  36. package/workflows/architect-spec.md +19 -0
  37. package/workflows/architect-status.md +21 -0
  38. package/commands/arch-audit.md +0 -10
  39. package/commands/arch-design.md +0 -10
  40. package/commands/arch-feature.md +0 -10
  41. package/skills/architecture-impact/SKILL.md +0 -68
  42. package/skills/audit-repository/SKILL.md +0 -53
  43. package/skills/feature-analysis/SKILL.md +0 -52
  44. package/skills/write-change-brief/SKILL.md +0 -63
package/bin/kagents.js CHANGED
@@ -5,39 +5,49 @@
5
5
 
6
6
  const fs = require('fs');
7
7
  const path = require('path');
8
+ const readline = require('readline');
9
+ const tty = require('tty');
8
10
 
9
11
  const PKG_ROOT = path.resolve(__dirname, '..');
10
12
  const PKG = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8'));
11
- const KIT_DIRS = ['agents', 'skills', 'commands', 'templates', 'checklists', 'workflows', 'governance'];
13
+ const KIT_DIRS = ['agents', 'skills', 'commands', 'rules', 'templates', 'checklists', 'workflows', 'governance', 'docs'];
12
14
  const SKIP = new Set(['README.md', '.gitkeep']);
13
15
  const BLOCK_RE = /<!-- kagents:start -->[\s\S]*?<!-- kagents:end -->/;
16
+ const GITIGNORE_RE = /# kagents:start\n[\s\S]*?# kagents:end\n?/;
17
+ // On ignore le kit (régénérable) mais pas docs/ : livrables et contexte sont à versionner.
14
18
 
15
19
  // Adaptateurs : un outil = une liste [dossier du kit, destination, type].
16
20
  // type : files (fichiers), dirs (dossiers), agents (fichiers .md avec `name:`).
21
+ // Les skills ne sont volontairement PAS liées dans .claude/ ni .cursor/ : ces outils les listeraient
22
+ // comme commandes `/`. Les agents et commandes les chargent par chemin depuis .kagents/skills/.
17
23
  const ADAPTERS = {
18
24
  agents: [['skills', '.agents/skills', 'dirs']],
19
25
  claude: [
20
26
  ['commands', '.claude/commands', 'files'],
21
- ['skills', '.claude/skills', 'dirs'],
22
27
  ['agents', '.claude/agents', 'agents'],
23
28
  ],
24
29
  cursor: [
25
30
  ['commands', '.cursor/commands', 'files'],
26
- ['skills', '.cursor/skills', 'dirs'],
27
31
  ['agents', '.cursor/agents', 'agents'],
32
+ ['rules/global', '.cursor/rules', 'files'],
33
+ ['rules/domains', '.cursor/rules', 'files'],
28
34
  ],
29
35
  };
30
36
 
31
37
  const HELP = `kagents ${PKG.version}
32
38
 
33
- Usage : kagents [install] [--tools claude,cursor,agents|auto] [--copy]
39
+ Usage : kagents [install] [--tools claude,cursor,agents|auto|none] [--yes] [--copy]
40
+ kagents --configure (rechoisir les outils)
34
41
  kagents uninstall
35
42
  kagents --help | --version
36
43
 
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é)
44
+ À lancer depuis la racine du projet. Dans un terminal, une liste permet de choisir
45
+ les outils à brancher ; le choix est mémorisé dans .kagents/config.json.
46
+ --tools outils à brancher, sans question
47
+ --yes, -y ne pose pas de question (détection automatique)
48
+ --configure pose à nouveau la question
49
+ --copy copies au lieu de liens symboliques (aussi KAGENTS_MODE=copy)
50
+ uninstall retire ce que KAgents a installé (docs/ est conservé)
41
51
  `;
42
52
 
43
53
  const log = (m) => console.log(`kagents: ${m}`);
@@ -49,12 +59,14 @@ const die = (m) => {
49
59
 
50
60
  // --- Arguments ----------------------------------------------------------------
51
61
  function parseArgs(argv) {
52
- const o = { cmd: 'install', tools: 'auto', copy: process.env.KAGENTS_MODE === 'copy' };
62
+ const o = { cmd: 'install', tools: null, yes: false, configure: false, copy: process.env.KAGENTS_MODE === 'copy' };
53
63
  for (let i = 0; i < argv.length; i++) {
54
64
  const a = argv[i];
55
65
  if (a === '-h' || a === '--help') o.cmd = 'help';
56
66
  else if (a === '-v' || a === '--version') o.cmd = 'version';
57
67
  else if (a === '--copy') o.copy = true;
68
+ else if (a === '-y' || a === '--yes') o.yes = true;
69
+ else if (a === '--configure') o.configure = true;
58
70
  else if (a === '--tools') o.tools = argv[++i] || die('--tools attend une valeur');
59
71
  else if (a.startsWith('--tools=')) o.tools = a.slice(8);
60
72
  else if (a === 'install' || a === 'uninstall') o.cmd = a;
@@ -100,6 +112,7 @@ class Installer {
100
112
  this.copy = copy;
101
113
  this.kagents = path.join(target, '.kagents');
102
114
  this.manifest = path.join(this.kagents, '.installed');
115
+ this.config = path.join(this.kagents, 'config.json');
103
116
  this.entries = [];
104
117
  }
105
118
 
@@ -168,6 +181,7 @@ class Installer {
168
181
  const docs = frontmatter(path.join(this.kagents, 'agents', f)).docs;
169
182
  if (docs) fs.mkdirSync(path.join(this.kagents, 'docs', docs), { recursive: true });
170
183
  }
184
+ this.createArchitectDocs();
171
185
  const ctx = path.join(this.kagents, 'docs', 'knowledge', 'context.md');
172
186
  if (!fs.existsSync(ctx)) {
173
187
  fs.writeFileSync(
@@ -196,6 +210,17 @@ Document partagé, écrit par l'utilisateur. Les agents le lisent, ne l'écriven
196
210
  }
197
211
  }
198
212
 
213
+ // Espace de l'Architect : livrables, décisions, propositions et INDEX.md (créé une fois, jamais écrasé).
214
+ createArchitectDocs() {
215
+ const root = path.join(this.kagents, 'docs', 'architect-docs');
216
+ if (!fs.existsSync(root)) return;
217
+ for (const d of ['architecture', 'impacts', 'features', 'specs', 'designs', 'audits'].map((n) => `outputs/${n}`).concat(['decisions', 'proposals']))
218
+ fs.mkdirSync(path.join(root, d), { recursive: true });
219
+ const index = path.join(root, 'INDEX.md');
220
+ const tpl = path.join(this.kagents, 'templates', 'architect-index', 'INDEX.template.md');
221
+ if (!fs.existsSync(index) && fs.existsSync(tpl)) fs.copyFileSync(tpl, index);
222
+ }
223
+
199
224
  renderBlock() {
200
225
  const agentsDir = path.join(this.kagents, 'agents');
201
226
  const cmdDir = path.join(this.kagents, 'commands');
@@ -252,15 +277,49 @@ Document partagé, écrit par l'utilisateur. Les agents le lisent, ne l'écriven
252
277
  fs.writeFileSync(file, out);
253
278
  }
254
279
 
255
- resolveTools(tools) {
256
- if (tools !== 'auto') return tools.split(',').filter(Boolean);
257
- const t = ['agents'];
280
+ // Bloc .gitignore : le kit et les liens que l'on a posés, jamais docs/ (sauf les fichiers du kit qui s'y trouvent).
281
+ gitignoreBlock() {
282
+ const extra = this.entries.filter((e) => !e.startsWith('.kagents/') || e.startsWith('.kagents/docs/')).sort();
283
+ return ['# kagents:start', '.kagents/*', '!.kagents/docs/', ...extra, '# kagents:end'].join('\n') + '\n';
284
+ }
285
+
286
+ writeGitignore() {
287
+ const file = path.join(this.target, '.gitignore');
288
+ if (!fs.existsSync(file) && !fs.existsSync(path.join(this.target, '.git'))) return;
289
+ const cur = fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : '';
290
+ const block = this.gitignoreBlock();
291
+ const out = GITIGNORE_RE.test(cur)
292
+ ? cur.replace(GITIGNORE_RE, () => block)
293
+ : (cur && !cur.endsWith('\n') ? cur + '\n' : cur) + (cur ? '\n' : '') + block;
294
+ fs.writeFileSync(file, out);
295
+ }
296
+
297
+ detectTools() {
258
298
  const has = (p) => fs.existsSync(path.join(this.target, p));
299
+ const t = [];
259
300
  if (has('.claude') || has('CLAUDE.md')) t.push('claude');
260
301
  if (has('.cursor')) t.push('cursor');
261
302
  return t;
262
303
  }
263
304
 
305
+ resolveTools(tools) {
306
+ return tools === 'auto' ? ['agents', ...this.detectTools()] : tools;
307
+ }
308
+
309
+ loadConfig() {
310
+ try {
311
+ const c = JSON.parse(fs.readFileSync(this.config, 'utf8'));
312
+ return Array.isArray(c.tools) ? c.tools : null;
313
+ } catch {
314
+ return null;
315
+ }
316
+ }
317
+
318
+ saveConfig(tools) {
319
+ fs.mkdirSync(this.kagents, { recursive: true });
320
+ fs.writeFileSync(this.config, JSON.stringify({ tools }, null, 2) + '\n');
321
+ }
322
+
264
323
  runAdapters(tools) {
265
324
  for (const tool of this.resolveTools(tools)) {
266
325
  if (!ADAPTERS[tool]) {
@@ -312,6 +371,7 @@ Document partagé, écrit par l'utilisateur. Les agents le lisent, ne l'écriven
312
371
  this.createDocs();
313
372
  this.writeAgentsMd();
314
373
  this.runAdapters(tools);
374
+ this.writeGitignore();
315
375
  this.saveManifest();
316
376
  log(`installé dans ${this.kagents} (${this.copy ? 'copies' : 'liens'})`);
317
377
  }
@@ -327,22 +387,125 @@ Document partagé, écrit par l'utilisateur. Les agents le lisent, ne l'écriven
327
387
  else fs.rmSync(file);
328
388
  }
329
389
  }
390
+ const gi = path.join(this.target, '.gitignore');
391
+ if (fs.existsSync(gi) && GITIGNORE_RE.test(fs.readFileSync(gi, 'utf8'))) {
392
+ const out = fs.readFileSync(gi, 'utf8').replace(GITIGNORE_RE, '').replace(/\n{3,}/g, '\n\n').replace(/\s+$/, '');
393
+ if (out) fs.writeFileSync(gi, out + '\n');
394
+ else fs.rmSync(gi);
395
+ }
330
396
  fs.rmSync(this.manifest, { force: true });
397
+ fs.rmSync(this.config, { force: true });
331
398
  this.prune(removed);
332
399
  log('désinstallé (.kagents/docs/ conservé : ce sont vos livrables)');
333
400
  }
334
401
  }
335
402
 
403
+ // --- Question interactive -----------------------------------------------------
404
+ // Terminal utilisable : le nôtre, ou /dev/tty quand on est lancé par un postinstall (stdin/stdout détournés).
405
+ function openTTY() {
406
+ if (process.stdin.isTTY && process.stdout.isTTY) return { input: process.stdin, output: process.stdout, close() {} };
407
+ if (process.env.KAGENTS_FROM_POSTINSTALL && process.platform !== 'win32') {
408
+ try {
409
+ const rfd = fs.openSync('/dev/tty', 'r');
410
+ const wfd = fs.openSync('/dev/tty', 'w');
411
+ const input = new tty.ReadStream(rfd);
412
+ const output = new tty.WriteStream(wfd);
413
+ return { input, output, close: () => { input.destroy(); output.destroy(); } };
414
+ } catch {
415
+ return null;
416
+ }
417
+ }
418
+ return null;
419
+ }
420
+
421
+ // Liste à cocher : ↑↓ déplacer, espace cocher, a tout, entrée valider. Renvoie les ids cochés.
422
+ function multiselect(io, message, items) {
423
+ return new Promise((resolve) => {
424
+ const { input, output } = io;
425
+ const state = items.map((i) => ({ ...i }));
426
+ let cur = 0;
427
+ let drawn = false;
428
+ const draw = () => {
429
+ if (drawn) output.write(`\x1b[${state.length + 1}A`);
430
+ drawn = true;
431
+ output.write(`\x1b[2K\x1b[1m?\x1b[0m ${message}\n`);
432
+ state.forEach((it, i) => {
433
+ const box = it.checked ? '\x1b[32m◉\x1b[0m' : '◯';
434
+ output.write(`\x1b[2K ${i === cur ? '\x1b[36m❯\x1b[0m' : ' '} ${box} ${it.label}\n`);
435
+ });
436
+ };
437
+ const finish = () => {
438
+ input.removeListener('keypress', onKey);
439
+ input.setRawMode(false);
440
+ input.pause();
441
+ output.write('\x1b[?25h');
442
+ io.close();
443
+ resolve(state.filter((i) => i.checked).map((i) => i.id));
444
+ };
445
+ const onKey = (str, key = {}) => {
446
+ if (key.ctrl && key.name === 'c') {
447
+ output.write('\x1b[?25h\n');
448
+ process.exit(130);
449
+ }
450
+ if (key.name === 'up') cur = (cur + state.length - 1) % state.length;
451
+ else if (key.name === 'down') cur = (cur + 1) % state.length;
452
+ else if (key.name === 'space') state[cur].checked = !state[cur].checked;
453
+ else if (key.name === 'a') {
454
+ const all = state.every((i) => i.checked);
455
+ state.forEach((i) => (i.checked = !all));
456
+ } else if (key.name === 'return') {
457
+ draw();
458
+ return finish();
459
+ }
460
+ draw();
461
+ };
462
+ readline.emitKeypressEvents(input);
463
+ input.setRawMode(true);
464
+ input.resume();
465
+ output.write('\x1b[?25l');
466
+ input.on('keypress', onKey);
467
+ draw();
468
+ });
469
+ }
470
+
471
+ async function chooseTools(inst, o) {
472
+ if (o.tools) {
473
+ const t = o.tools === 'auto' ? 'auto' : o.tools === 'none' ? [] : o.tools.split(',').filter(Boolean);
474
+ if (t !== 'auto') inst.chosen = t;
475
+ return t;
476
+ }
477
+ if (!o.configure) {
478
+ const saved = inst.loadConfig();
479
+ if (saved) return saved;
480
+ }
481
+ if (!o.yes && !process.env.KAGENTS_NO_PROMPT && !process.env.CI) {
482
+ const io = openTTY();
483
+ if (io) {
484
+ const detected = inst.detectTools();
485
+ const picked = await multiselect(io, 'Pour quels outils installer KAgents ? (↑↓ espace a entrée)', [
486
+ { id: 'claude', label: 'Claude Code (.claude/commands, .claude/agents)', checked: detected.includes('claude') },
487
+ { id: 'cursor', label: 'Cursor (.cursor/commands, .cursor/agents, .cursor/rules)', checked: detected.includes('cursor') },
488
+ { id: 'agents', label: 'Codex et autres outils AGENTS.md (.agents/skills)', checked: true },
489
+ ]);
490
+ inst.chosen = picked;
491
+ return picked;
492
+ }
493
+ }
494
+ return 'auto';
495
+ }
496
+
336
497
  // --- Main ---------------------------------------------------------------------
337
- function main() {
498
+ async function main() {
338
499
  const o = parseArgs(process.argv.slice(2));
339
500
  if (o.cmd === 'help') return console.log(HELP);
340
501
  if (o.cmd === 'version') return console.log(PKG.version);
341
502
  const target = process.cwd();
342
503
  if (path.resolve(target) === PKG_ROOT) die("à lancer depuis la racine d'un projet, pas depuis le kit.");
343
504
  const inst = new Installer(target, o.copy);
344
- if (o.cmd === 'uninstall') inst.uninstall();
345
- else inst.install(o.tools);
505
+ if (o.cmd === 'uninstall') return inst.uninstall();
506
+ const tools = await chooseTools(inst, o);
507
+ inst.install(tools);
508
+ if (inst.chosen) inst.saveConfig(inst.chosen);
346
509
  }
347
510
 
348
511
  main();
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Lancé par npm/pnpm après `add @dev-kosaly/kagents` : installe le kit dans le projet.
4
+ // Ne doit jamais faire échouer l'installation des dépendances.
5
+ const path = require('path');
6
+ const { spawnSync } = require('child_process');
7
+
8
+ const pkgRoot = path.resolve(__dirname, '..');
9
+ const project = process.env.INIT_CWD;
10
+
11
+ const skip = (why) => {
12
+ if (why) console.log(`kagents: installation automatique ignorée (${why}). Lancez : npx kagents`);
13
+ process.exit(0);
14
+ };
15
+
16
+ if (process.env.KAGENTS_SKIP_POSTINSTALL) skip();
17
+ if (!project) skip();
18
+ if (process.env.npm_config_global === 'true') skip('installation globale');
19
+ if (!pkgRoot.split(path.sep).includes('node_modules')) skip(); // développement du kit lui-même
20
+ if (path.resolve(project) === pkgRoot) skip();
21
+
22
+ try {
23
+ spawnSync(process.execPath, [path.join(__dirname, 'kagents.js')], { cwd: project, stdio: 'inherit', env: { ...process.env, KAGENTS_FROM_POSTINSTALL: '1' } });
24
+ } catch {
25
+ /* jamais bloquant */
26
+ }
@@ -0,0 +1,17 @@
1
+ ---
2
+ description: Architect — auditer l'architecture existante
3
+ agent: architect
4
+ mode: Audit
5
+ triggers: audite l'architecture existante
6
+ ---
7
+ Lis le role Architect.
8
+
9
+ Commande : **`kagents architect:audit [scope]`**.
10
+
11
+ Identifier incoherences, derives, ecarts doc/code **uniquement si observes**. Ne pas modifier le code.
12
+
13
+ Skills internes : `architect-audit`, `architect-write-output`, `architect-index`.
14
+
15
+ Workflow : `workflows/architect-audit-run.md`.
16
+
17
+ Scope optionnel : $ARGUMENTS
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: Architect — comparer des options (extension future)
3
+ agent: architect
4
+ mode: Comparaison (non implémenté)
5
+ triggers: compare ces options d'architecture
6
+ ---
7
+ **Extension preparee — non implementee.**
8
+
9
+ Commande prevue : `kagents architect:compare "<question>"`.
10
+
11
+ Voir `docs/architect-commands.md`. Ne pas simuler un workflow complet tant qu'il n'est pas defini.
12
+
13
+ Question : $ARGUMENTS
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Architect — enregistrer une decision humaine explicitement fournie
3
+ agent: architect
4
+ mode: Décision humaine
5
+ triggers: enregistre cette décision d'architecture
6
+ ---
7
+ Lis `agents/architect.md`.
8
+
9
+ Commande : **`kagents architect:decision "<decision>"`**.
10
+
11
+ Le argument utilisateur **est** la decision a enregistrer (confirmation humaine implicite via la commande). Ce n'est pas une question a resoudre.
12
+
13
+ Skill : `architect-decision`.
14
+ Workflow : `workflows/architect-decision.md`.
15
+ Template : `templates/architect-decision/template.md`.
16
+ Cible : `.kagents/docs/architect-docs/decisions/DEC-XXX-<slug>.md`
17
+
18
+ Statut par defaut : **VALIDEE**. Ne jamais promouvoir une PROPOSITION agent sans cette commande.
19
+
20
+ Decision a enregistrer : $ARGUMENTS
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Architect — concevoir une architecture cible (proposition)
3
+ agent: architect
4
+ mode: Architecture cible
5
+ triggers: conçois l'architecture cible, propose une architecture
6
+ ---
7
+ Lis le role Architect.
8
+
9
+ Commande : **`kagents architect:design "<objectif>"`**.
10
+
11
+ Distinction : `kagents architect` = observe ; `kagents architect:design` = **cible proposee** (PROPOSITION, pas decision).
12
+
13
+ Skills internes : `architect-discovery` (existant), `architect-write-output`, `architect-index`.
14
+
15
+ Workflow : `workflows/architect-design.md`.
16
+ Template : `templates/architect-design/template.md`.
17
+
18
+ Objectif : $ARGUMENTS
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Architect — impact d'une evolution sur l'architecture existante
3
+ agent: architect
4
+ mode: Impact
5
+ triggers: avant de coder, impact d'une évolution, ajouter une fonctionnalité
6
+ ---
7
+ Lis le role Architect (chemins ci-dessus).
8
+
9
+ Commande officielle : **`kagents architect:impact "<demande>"`**.
10
+
11
+ Skills internes : `architect-audit` (si besoin), `architect-impact`, `architect-write-output`, `architect-index`.
12
+
13
+ Workflow : `workflows/architect-impact.md`.
14
+ Niveaux : `workflows/architect-impact-levels.yaml`.
15
+
16
+ Demande : $ARGUMENTS
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Architect — formaliser une fonctionnalite en specification
3
+ agent: architect
4
+ mode: Spécification
5
+ triggers: spécifie cette fonctionnalité, rédige la spec
6
+ ---
7
+ Lis le role Architect.
8
+
9
+ Commande : **`kagents architect:spec "<fonctionnalite>"`**.
10
+
11
+ Distinction : section **Impact** (ce que ca touche) vs **Spec** (comportement attendu). Ne pas inventer de regles metier.
12
+
13
+ Skills internes : `architect-audit` (si besoin), `architect-impact` (partie impact uniquement), `architect-write-output`, `architect-index`.
14
+
15
+ Workflow : `workflows/architect-spec.md`.
16
+ Template : `templates/architect-spec/template.md`.
17
+
18
+ Fonctionnalite : $ARGUMENTS
@@ -0,0 +1,26 @@
1
+ ---
2
+ description: Architect — etat documentaire et architectural connu (read-only)
3
+ agent: architect
4
+ mode: État (lecture seule)
5
+ triggers: où en est-on, état des décisions et propositions
6
+ ---
7
+ Lis `agents/architect.md` (ou `.kagents/docs/architect-docs/architect.md`).
8
+
9
+ Commande : **`kagents architect:status`**.
10
+
11
+ Skill interne : `architect-status`.
12
+ Workflow : `workflows/architect-status.md`.
13
+
14
+ **Read-only** : pas de nouveau livrable obligatoire ; pas d'audit repo complet.
15
+
16
+ Sortie chat type :
17
+
18
+ # Architect — Etat du projet
19
+
20
+ **Etat architectural :** ...
21
+ **Derniere activite :** ...
22
+ **Travaux ouverts / Decisions en attente / Blocages** (si presents)
23
+
24
+ Sections adaptatives : Travaux en cours (tableau), Decisions, Handoffs, Points d'attention, Derniers livrables, Prochaine etape.
25
+
26
+ Argument optionnel (filtre domaine) : $ARGUMENTS
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Architect — vue de l'architecture observee du projet
3
+ agent: architect
4
+ mode: Architecture observée
5
+ triggers: explique l'architecture, comment le projet est construit
6
+ ---
7
+ Lis le role Architect :
8
+ - projet client : `.kagents/docs/architect-docs/architect.md`
9
+ - harness : `agents/architect.md`
10
+
11
+ Commande officielle : **`kagents architect`** (ne pas utiliser `kagents architecture`).
12
+
13
+ Applique la vue **architecture actuelle observee** — pas une analyse de feature.
14
+
15
+ Skills internes : `architect-discovery`, `architect-write-output`, `architect-index`.
16
+
17
+ Workflow : `workflows/architect-architecture.md`.
18
+ Contrat : `docs/architect-commands.md`.
19
+
20
+ Demande ou focus : $ARGUMENTS
@@ -0,0 +1,52 @@
1
+ # Contrat des commandes — Architect (public)
2
+
3
+ Racine officielle : **`kagents architect`** (pas `kagents architecture`).
4
+
5
+ Les skills `architect-*` sont **internes** ; l'utilisateur invoque une **commande**, pas une skill.
6
+
7
+ ## Priorite 1 — disponibles
8
+
9
+ | Commande | Role | Workflow | Skills internes | Livrable |
10
+ |----------|------|----------|-----------------|----------|
11
+ | `kagents architect` | Architecture **observee** (existant) | `workflows/architect-architecture.md` | discovery, write-output, index | `outputs/architecture/` |
12
+ | `kagents architect:impact "<demande>"` | Impact d'une evolution | `workflows/architect-impact.md` | audit?, impact, write-output, index | `outputs/features/` ou `outputs/impacts/` |
13
+ | `kagents architect:spec "<fonctionnalite>"` | Spec exploitable (comportement attendu) | `workflows/architect-spec.md` | audit?, impact (partie impact), write-output, index | `outputs/specs/` |
14
+ | `kagents architect:design "<objectif>"` | Architecture **cible** proposee | `workflows/architect-design.md` | discovery, write-output, index | `outputs/designs/` |
15
+ | `kagents architect:audit [scope]` | Audit architecture existante | `workflows/architect-audit-run.md` | audit, write-output, index | `outputs/audits/` |
16
+ | `kagents architect:status` | Etat documentaire (read-only) | `workflows/architect-status.md` | architect-status | chat |
17
+ | `kagents architect:decision "<texte>"` | Decision **humaine** enregistree | `workflows/architect-decision.md` | architect-decision | `decisions/DEC-XXX-*.md` |
18
+
19
+ Fichiers entree harness : `commands/architect*.md`.
20
+
21
+ ## Distinctions
22
+
23
+ - **Impact** : ce que le changement **touche** (MVC, risques, L0–L3).
24
+ - **Spec** : ce que la fonctionnalite doit **faire** (comportement, cas, criteres) + reference impact si pertinent.
25
+ - **architect** (sans suffixe) : etat **reel** observe.
26
+ - **architect:design** : etat **cible** PROPOSITION (jamais decision automatique).
27
+ - **architect:status** : synthese **read-only** (INDEX, decisions, proposals, travaux ouverts) — pas d’audit repo complet.
28
+ - **architect:decision** : enregistre une decision **explicitement fournie ou confirmee par l’humain** ; statut typique **VALIDEE** ; registre `decisions/DEC-XXX-*.md` + ligne dans INDEX. Une proposition dans `proposals/` ou un livrable n’est **pas** promue en decision sans cette commande.
29
+
30
+ Statuts decision : PROPOSEE, A VALIDER, VALIDEE, REJETEE, REMPLACEE (remplacement sans suppression du fichier historique).
31
+
32
+ ## Priorite 2 — extension
33
+
34
+ | Commande | Statut |
35
+ |----------|--------|
36
+ | `kagents architect:compare "<question>"` | Prepare — workflow a creer |
37
+
38
+ Fichier : `commands/architect-compare.md`.
39
+
40
+ ## Mode naturel
41
+
42
+ Formulations sans commande → resolver vers la commande la plus proche (souvent `architect:impact` ou `architect`).
43
+
44
+ ## Database Architect (Base)
45
+
46
+ **Hors scope.** Commandes inchangees : `commands/base-audit.md`, `base-design.md`, `base-evolve.md`.
47
+
48
+ ## Chaine d'execution
49
+
50
+ ```text
51
+ Commande → agents/architect.md → rules/architect-* → workflow → skills → template → livrable → INDEX → chat
52
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev-kosaly/kagents",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Kit d'agents IA d'ingénierie installable dans un projet (Claude Code, Cursor, AGENTS.md)",
5
5
  "bin": {
6
6
  "kagents": "bin/kagents.js"
@@ -10,10 +10,12 @@
10
10
  "agents",
11
11
  "skills",
12
12
  "commands",
13
+ "rules",
13
14
  "templates",
14
15
  "checklists",
15
16
  "workflows",
16
- "governance"
17
+ "governance",
18
+ "docs"
17
19
  ],
18
20
  "engines": {
19
21
  "node": ">=18"
@@ -27,6 +29,7 @@
27
29
  "access": "public"
28
30
  },
29
31
  "scripts": {
32
+ "postinstall": "node bin/postinstall.js",
30
33
  "test": "node scripts/smoke-test.js",
31
34
  "prepublishOnly": "npm test"
32
35
  },
@@ -0,0 +1,61 @@
1
+ # Contrat de sortie chat — Architect
2
+
3
+ Reference adaptative — omettre les sections sans contenu utile.
4
+
5
+ Priorite : **Clarte > Pertinence > Structure > Concision > Esthetique**.
6
+
7
+ ```markdown
8
+ # Architect — [titre]
9
+
10
+ **Mode :** Architecture | Impact
11
+ **Niveau :** L0 | L1 | L2 | L3
12
+ **Statut :** ETABLI | A VALIDER | BLOQUANT (selon le cas)
13
+
14
+ ## Synthese
15
+
16
+ Quelques paragraphes : conclusion immediate, ce qui a ete analyse, proposition retenue.
17
+
18
+ ## Constats principaux
19
+
20
+ Tableau ou liste (elements importants seulement).
21
+
22
+ ## Impact architectural
23
+
24
+ Tableau MVC si mode Impact (ou « Pas d'impact identifie » par couche).
25
+
26
+ | Couche | Impact | Element cle |
27
+ |--------|--------|-------------|
28
+ | Modele | | |
29
+ | Controleur | | |
30
+ | Vue | | |
31
+
32
+ ## Architecture concernee
33
+
34
+ Diagramme Mermaid ou schema **uniquement** si cela clarifie flux ou composants.
35
+
36
+ ## Points a decider
37
+
38
+ Decisions humaines importantes (pas les propositions de l'agent presentees comme decidees).
39
+
40
+ ## Incertitudes / points bloquants
41
+
42
+ Ce qui influence la suite (max 5 questions bloquantes).
43
+
44
+ ## Handoff
45
+
46
+ ### Base (Database Expert)
47
+ Si BDD / donnees concernees : ce que Base doit analyser dans `base-docs/`.
48
+
49
+ ### Suite du travail
50
+ Validation humaine, Base, puis implementation (Developer hors scope de ce role).
51
+
52
+ ## Prochaine etape
53
+
54
+ Action concrete.
55
+
56
+ ## Livrable
57
+
58
+ Chemin exact : `.kagents/docs/architect-docs/outputs/...`
59
+ ```
60
+
61
+ Le chat **n'est pas** une copie du fichier persistant. Ne pas lister tous les fichiers du repo.
@@ -0,0 +1,22 @@
1
+ # Invariants — Architect / Spec
2
+
3
+ ## Non-negociable
4
+
5
+ - Ne pas modifier le code applicatif, migrations, modeles, ni `base-docs/`.
6
+ - Ne pas ecrire SQL ni imposer un schema BDD.
7
+ - Ne pas modifier les commandes, agents ou skills Base.
8
+ - Ne pas lire ni recopier secrets (`.env`, credentials, tokens).
9
+ - Ne pas ecraser un livrable dans `architect-docs/outputs/` sans suffixe version explicite.
10
+ - Ne pas transformer PROPOSITION / DEDUIT en ETABLI sans source.
11
+
12
+ ## Qualification
13
+
14
+ Chaque affirmation importante porte un statut : ETABLI, DEDUIT, PROPOSITION, A VALIDER, INCONNU, BLOQUANT.
15
+
16
+ ## Repository vs documentation
17
+
18
+ Le code prevaut en cas de divergence avec une doc obsolete ; signaler l'ecart, ne pas trancher silencieusement.
19
+
20
+ ## knowledge/context.md
21
+
22
+ Lecture autorisee. Ecriture automatique interdite sauf instruction explicite utilisateur ou politique projet documentee.