@patricksardinha/agentkit-cli 0.2.0 → 0.4.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.
@@ -0,0 +1,43 @@
1
+ # Skills — Agent 3 · Generators & Templates
2
+
3
+ > This file is read by Agent 3 before starting its work.
4
+
5
+ ## Template function signature
6
+
7
+ Every template file must export exactly these two functions:
8
+
9
+ ```typescript
10
+ export function claudeMd(stack: StackInfo): string
11
+ export function workflow(stack: StackInfo): string
12
+ ```
13
+
14
+ The `workflow()` function returns a markdown string. The workflowGenerator
15
+ is responsible for parsing that string into an `Agent[]` array.
16
+
17
+ ## Agent type
18
+
19
+ ```typescript
20
+ export interface Agent {
21
+ number: number // 1, 2, 3…
22
+ slug: string // 'infra', 'auth', 'features'…
23
+ name: string // 'Infra & Setup', 'Auth & Supabase'…
24
+ scope: string // one-line description
25
+ outputs: string[]
26
+ criterion: string // the runnable bash command
27
+ }
28
+ ```
29
+
30
+ ## Blueprint parsing
31
+
32
+ When `blueprintContent` is provided, parse `## Feature` sections
33
+ using simple line splitting — no external markdown parser needed.
34
+ Extract bullet points under each `##` heading and use them to name
35
+ and scope the generated agents.
36
+
37
+ ## playbookGenerator rules
38
+
39
+ The PLAYBOOK.md must always start with the one-instruction block:
40
+ > "Read PLAYBOOK.md and execute the procedure."
41
+
42
+ The retry limit is always 3. The escalation section is always present.
43
+ Do not make these values configurable — consistency is the point.
@@ -0,0 +1,37 @@
1
+ # Skills — Agent 4 · Commands CLI
2
+
3
+ > This file is read by Agent 4 before starting its work.
4
+
5
+ ## Commander.js setup
6
+
7
+ The CLI binary is `agentkit`. The three subcommands are:
8
+ - `init [options]` with `--blueprint <path>`
9
+ - `add [options]` with `--feature <description>`
10
+ - `status`
11
+
12
+ ## init command behavior
13
+
14
+ 1. Run gitDetector — warn but don't block if not a git repo
15
+ 2. Run stackDetector on process.cwd()
16
+ 3. If --blueprint provided: read file, warn if path doesn't exist
17
+ 4. Call claudeMdGenerator(stack, blueprintContent?)
18
+ 5. Call workflowGenerator(stack, blueprintContent?) → { markdown, agents }
19
+ 6. Call playbookGenerator(agents, projectName)
20
+ 7. Call skillsGenerator(agents)
21
+ 8. Write all files — never overwrite existing files without --force flag
22
+
23
+ ## add command behavior
24
+
25
+ 1. Check AGENT_WORKFLOW.md exists — error if not (run init first)
26
+ 2. Parse existing agents to find the last number
27
+ 3. Generate new agent block from --feature description
28
+ 4. Append to AGENT_WORKFLOW.md
29
+ 5. Create agents/agent-{N+1}-{slug}/skills.md
30
+ 6. Regenerate PLAYBOOK.md entirely (not append — full regeneration)
31
+
32
+ ## Output rules
33
+
34
+ - Use logger.ts for all output — never console.log directly
35
+ - Use ora spinner during file generation
36
+ - Use chalk.green for success, chalk.yellow for warnings, chalk.red for errors
37
+ - Always print a summary of generated files at the end of init
package/dist/cli.cjs CHANGED
@@ -114,25 +114,6 @@ async function isGitRepo(projectPath) {
114
114
  }
115
115
  }
116
116
 
117
- // src/utils/blueprintParser.ts
118
- function parseBlueprint(content) {
119
- const features = [];
120
- const sectionRegex = /^## (.+)$/gm;
121
- const sections = [];
122
- let m;
123
- while ((m = sectionRegex.exec(content)) !== null) {
124
- sections.push({ name: m[1].trim(), start: m.index });
125
- }
126
- for (let i = 0; i < sections.length; i++) {
127
- const section = sections[i];
128
- const end = i + 1 < sections.length ? sections[i + 1].start : content.length;
129
- const body = content.slice(section.start, end);
130
- const items = [...body.matchAll(/^[-*]\s+(.+)$/gm)].map((r) => r[1].trim());
131
- features.push({ name: section.name, items });
132
- }
133
- return features;
134
- }
135
-
136
117
  // src/templates/react.ts
137
118
  function claudeMd(stack) {
138
119
  const lang = stack.hasTypeScript ? "TypeScript" : "JavaScript";
@@ -567,73 +548,17 @@ function generateClaudeMd(stack, blueprintContent) {
567
548
  base = claudeMd7(stack);
568
549
  }
569
550
  if (!blueprintContent) return base;
570
- const features = parseBlueprint(blueprintContent);
571
- if (features.length === 0) return base;
572
- const featureLines = features.map((f, i) => {
573
- const sub = f.items.length > 0 ? "\n" + f.items.map((it) => ` - ${it}`).join("\n") : "";
574
- return `${i + 1}. **${f.name}**${sub}`;
575
- }).join("\n");
576
- const featureSection = `
577
- ## Features (Blueprint)
578
-
579
- ${featureLines}
580
- `;
551
+ const blueprintNote = "\n> A PROJECT_BLUEPRINT.md is present \u2014 Claude Code will read it during Phase 0.\n";
581
552
  const conventionsIdx = base.indexOf("\n## Conventions");
582
553
  if (conventionsIdx !== -1) {
583
- return base.slice(0, conventionsIdx) + featureSection + base.slice(conventionsIdx);
584
- }
585
- return base + featureSection;
586
- }
587
-
588
- // src/utils/agentParser.ts
589
- function toSlug(name) {
590
- return name.toLowerCase().replace(/[·•&]/g, " ").replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
591
- }
592
- function getFieldValue(lines, pattern) {
593
- for (const line of lines) {
594
- const m = line.match(pattern);
595
- if (m) return (m[1] ?? "").trim();
596
- }
597
- return "";
598
- }
599
- function extractAgentsFromWorkflow(content) {
600
- const agents = [];
601
- const blocks = content.split(/(?=^### Agent \d)/m).filter((b) => /^### Agent \d/.test(b.trimStart()));
602
- for (const block of blocks) {
603
- const lines = block.split("\n");
604
- const headerMatch = lines[0].match(/^### Agent (\d+)\s*[·•]\s*(.+)$/);
605
- if (!headerMatch) continue;
606
- const number = parseInt(headerMatch[1], 10);
607
- const name = headerMatch[2].trim();
608
- const fullName = `Agent ${number} \xB7 ${name}`;
609
- const slug = toSlug(name);
610
- const scope = getFieldValue(lines, /Périmètre\s*:\s*(.+)/);
611
- const criterion = getFieldValue(lines, /Critère[s]?\s*:\s*(.+)/);
612
- const outputs = [];
613
- const produitIdx = lines.findIndex((l) => /Produit\s*:/.test(l));
614
- if (produitIdx !== -1) {
615
- const inlineVal = (lines[produitIdx].match(/Produit\s*:\s*(.+)/)?.[1] ?? "").trim();
616
- if (inlineVal) {
617
- outputs.push(inlineVal);
618
- } else {
619
- for (let i = produitIdx + 1; i < lines.length; i++) {
620
- const line = lines[i];
621
- if (/^\s+[-]/.test(line)) {
622
- outputs.push(line.trim().replace(/^-\s*/, ""));
623
- } else if (line.trim() !== "" && !/^\s/.test(line)) {
624
- break;
625
- }
626
- }
627
- }
628
- }
629
- agents.push({ number, name, fullName, slug, scope, outputs, criterion });
554
+ return base.slice(0, conventionsIdx) + blueprintNote + base.slice(conventionsIdx);
630
555
  }
631
- return agents;
556
+ return base + blueprintNote;
632
557
  }
633
558
 
634
559
  // src/generators/workflowGenerator.ts
635
- function generateWorkflow(stack, blueprintContent) {
636
- if (blueprintContent) return blueprintWorkflow(stack, blueprintContent);
560
+ function generateWorkflow(stack, blueprintContent, projectName) {
561
+ if (blueprintContent) return blueprintPlaceholder(projectName ?? stack.framework);
637
562
  switch (stack.framework) {
638
563
  case "react":
639
564
  return workflow(stack);
@@ -651,100 +576,177 @@ function generateWorkflow(stack, blueprintContent) {
651
576
  return workflow7(stack);
652
577
  }
653
578
  }
654
- function blueprintWorkflow(stack, blueprintContent) {
655
- const features = parseBlueprint(blueprintContent);
656
- const agentBlocks = features.map((feature, i) => {
657
- const n = i + 1;
658
- const slug = toSlug(feature.name);
659
- const outputLines = feature.items.length > 0 ? feature.items.map((item) => ` - ${item}`).join("\n") : ` - src/${slug}/`;
660
- return `### Agent ${n} \xB7 ${feature.name}
661
- P\xE9rim\xE8tre : Impl\xE9menter la fonctionnalit\xE9 ${feature.name.toLowerCase()}
662
- Produit :
663
- ${outputLines}
664
- Crit\xE8re : npm test (tests ${feature.name.toLowerCase()} passent)`;
665
- });
666
- const ciN = features.length + 1;
667
- agentBlocks.push(
668
- `### Agent ${ciN} \xB7 Tests & CI
669
- P\xE9rim\xE8tre : Couverture de tests compl\xE8te et configuration du pipeline CI
670
- Produit :
671
- - tests/
672
- - .github/workflows/
673
- Crit\xE8re : npm test passe, pipeline CI vert`
674
- );
675
- return `# Agent Workflow \u2014 ${stack.framework} (Blueprint)
579
+ function blueprintPlaceholder(projectName) {
580
+ return `# AGENT_WORKFLOW.md \u2014 ${projectName}
676
581
 
677
- ## Stack d\xE9tect\xE9e
678
- Framework: ${stack.framework} | Language: ${stack.language}
582
+ > This file will be filled in by Claude Code during Phase 0.
583
+ > Claude Code will read PROJECT_BLUEPRINT.md, propose a decomposition,
584
+ > and replace this content after human validation.
679
585
 
680
- ## Agents
586
+ ---
681
587
 
682
- ${agentBlocks.join("\n\n")}
588
+ *Waiting for Phase 0 decomposition...*
683
589
  `;
684
590
  }
685
591
 
686
592
  // src/generators/playbookGenerator.ts
687
- function generatePlaybook({ agents, projectName }) {
593
+ function generatePlaybook({ agents, projectName, hasBlueprint }) {
688
594
  const agentBlocks = agents.map((a) => agentBlock(a)).join("\n---\n\n");
595
+ const phase0 = hasBlueprint ? `## Phase 0 \u2014 Agent Decomposition (run this first)
596
+
597
+ > A \`PROJECT_BLUEPRINT.md\` was provided.
598
+ > Claude Code reads it and decomposes the project into specialized agents
599
+ > before writing a single line of code.
600
+
601
+ **Read these files in order:**
602
+ 1. \`CLAUDE.md\`
603
+ 2. \`PROJECT_BLUEPRINT.md\`
604
+
605
+ **Then decompose the project into agents** following these rules:
606
+
607
+ - One agent = one coherent technical layer (never mix two layers)
608
+ - Each agent must have a runnable success criterion (\`npm test\`, \`cargo build\`\u2026)
609
+ - Agents must be ordered by dependency (no feature without infra first)
610
+ - Maximum 6 agents \u2014 if you have more, group related ones
611
+ - Always respect this order:
612
+ 1. Infra & Configuration
613
+ 2. Data layer (DB schema, models, services)
614
+ 3. External integrations (auth, APIs, local services like Ollama)
615
+ 4. UI & pages
616
+ 5. Advanced features (RAG, export, realtime\u2026)
617
+ 6. Build & release (CI/CD, packaging, installers)
618
+
619
+ **Write the result directly into \`AGENT_WORKFLOW.md\`** \u2014 replace its current
620
+ content with your decomposition.
621
+
622
+ **Then ask for human validation:**
623
+ > "I have decomposed the project into N agents: [list them].
624
+ > Should I proceed with execution?"
625
+
626
+ Wait for confirmation before moving to Phase 1.
627
+
628
+ ---
629
+
630
+ ` : `## Phase 0 \u2014 Project Discovery (run this first)
631
+
632
+ > No \`PROJECT_BLUEPRINT.md\` was provided.
633
+ > Before writing any code, Claude Code asks the user what they want to build,
634
+ > then decomposes the project into agents \u2014 exactly as if a blueprint had been provided.
635
+
636
+ **Ask the user these questions and wait for their answers:**
637
+
638
+ 1. What is this project? (one sentence describing the goal)
639
+ 2. What are the main features you want to build? (list them)
640
+ 3. Are there any tech constraints or architecture preferences?
641
+ (e.g. offline-only, specific DB, no auth, specific framework)
642
+
643
+ **Once you have the answers, decompose the project into agents**
644
+ following these rules:
645
+
646
+ - One agent = one coherent technical layer (never mix two layers)
647
+ - Each agent must have a runnable success criterion (\`npm test\`, \`cargo build\`\u2026)
648
+ - Agents must be ordered by dependency (no feature without infra first)
649
+ - Maximum 6 agents \u2014 if you have more, group related ones
650
+ - Always respect this order:
651
+ 1. Infra & Configuration
652
+ 2. Data layer (DB schema, models, services)
653
+ 3. External integrations (auth, APIs, local services like Ollama)
654
+ 4. UI & pages
655
+ 5. Advanced features (RAG, export, realtime\u2026)
656
+ 6. Build & release (CI/CD, packaging, installers)
657
+
658
+ **Write the result directly into \`AGENT_WORKFLOW.md\`** \u2014 replace its current
659
+ content with your decomposition.
660
+
661
+ **Then ask for human validation:**
662
+ > "I have decomposed the project into N agents: [list them].
663
+ > Should I proceed with execution?"
664
+
665
+ Wait for confirmation before moving to Phase 1.
666
+
667
+ ---
668
+
669
+ `;
689
670
  return `# PLAYBOOK.md \u2014 ${projectName}
690
671
 
691
- > Donne cette instruction \xE0 Claude Code : 'Lis PLAYBOOK.md et ex\xE9cute la proc\xE9dure.'
672
+ > **One instruction to give Claude Code:**
673
+ > "Read PLAYBOOK.md and execute the procedure."
674
+ >
675
+ > Claude Code handles the rest autonomously \u2014 project discovery or blueprint reading,
676
+ > agent decomposition, execution, success validation, retries, and human escalation.
677
+ > No API key required. No additional cost beyond your LLM subscription.
692
678
 
693
- ## R\xE8gles d'ex\xE9cution globales
679
+ ---
694
680
 
695
- Avant chaque agent :
696
- 1. Lire \`CLAUDE.md\`
697
- 2. Lire \`agents/agent-{N}-{slug}/skills.md\` (le fichier de l'agent courant)
681
+ ## Global Execution Rules
698
682
 
699
- Apr\xE8s chaque agent :
700
- - Ex\xE9cuter le crit\xE8re de succ\xE8s
701
- - Si succ\xE8s \u2192 annoncer "\u2705 Agent N termin\xE9" et passer au suivant
702
- - Si \xE9chec \u2192 analyser la cause racine, corriger, r\xE9ex\xE9cuter (max 3 tentatives)
703
- - Apr\xE8s 3 \xE9checs cons\xE9cutifs \u2192 pause et demander validation humaine
704
- - **Ne jamais passer \xE0 l'agent suivant sans crit\xE8re valid\xE9**
683
+ Before each agent:
684
+ 1. Read \`CLAUDE.md\`
685
+ 2. Read \`agents/agent-{N}-{slug}/skills.md\` (current agent's file)
686
+ 3. Read the agent's section in \`AGENT_WORKFLOW.md\`
705
687
 
706
- ## Agents
688
+ After each agent:
689
+ - Run the success criterion command
690
+ - \u2705 Passes \u2192 announce "\u2705 Agent N complete" and move to the next
691
+ - \u274C Fails \u2192 analyze the root cause, fix, rerun (max 3 attempts)
692
+ - After 3 consecutive failures \u2192 stop and ask for human validation
693
+
694
+ **Never move to the next agent without a passing success criterion.**
695
+ **Stay strictly within your current agent's defined scope.**
696
+
697
+ ---
698
+
699
+ ${phase0}## Phase 1 \u2014 Execution
707
700
 
708
701
  ${agentBlocks}
709
702
 
710
- ## It\xE9rations futures
703
+ ---
704
+
705
+ ## Future Iterations
706
+
707
+ When a new agent is added via \`agentkit add --feature <description>\`:
708
+ 1. A new agent block is appended to \`AGENT_WORKFLOW.md\`
709
+ 2. The folder \`agents/agent-{N}-{slug}/\` is created with \`skills.md\`
710
+ 3. This \`PLAYBOOK.md\` is regenerated to include the new agent
711
+ 4. Execution resumes at the new agent only \u2014 completed agents are not rerun
711
712
 
712
- Lorsqu'un nouvel agent est ajout\xE9 via \`agentkit add --feature <description>\` :
713
- 1. Un nouveau bloc agent est ajout\xE9 \xE0 la fin de \`AGENT_WORKFLOW.md\`
714
- 2. Le dossier \`agents/agent-{N}-{slug}/\` est cr\xE9\xE9 avec \`skills.md\` et \`context.md\`
715
- 3. Ce \`PLAYBOOK.md\` est r\xE9g\xE9n\xE9r\xE9 automatiquement pour inclure le nouvel agent
716
- 4. L'ex\xE9cution reprend \xE0 ce nouvel agent uniquement \u2014 les agents pr\xE9c\xE9dents ne sont pas r\xE9ex\xE9cut\xE9s
713
+ When you receive the instruction to continue after an iteration:
714
+ > "Read PLAYBOOK.md and execute only the agents that haven't been completed yet."
717
715
 
718
- ## Validation humaine requise
716
+ ---
719
717
 
720
- Les cas suivants n\xE9cessitent une pause et une confirmation humaine avant de continuer :
721
- - **3 \xE9checs cons\xE9cutifs** sur le crit\xE8re de succ\xE8s d'un agent
722
- - **D\xE9pendance externe manquante** : cl\xE9 API, variable d'environnement non d\xE9finie, service tiers inaccessible
723
- - **Conflit** entre le blueprint fourni (\`--blueprint\`) et la stack d\xE9tect\xE9e automatiquement
718
+ ## Human Validation Required
719
+
720
+ Stop and wait for confirmation in these situations:
721
+ - **3 consecutive failures** on the same success criterion
722
+ - **Missing external dependency**: API key, env variable, unavailable service
723
+ - **Conflict** between the detected stack and the user's stated constraints
724
+ - **Destructive operation**: overwriting files not listed in deliverables
725
+ - **End of Phase 0**: agent decomposition must be validated before execution
724
726
  `;
725
727
  }
726
728
  function agentBlock(agent) {
727
729
  const skillsPath = `agents/agent-${agent.number}-${agent.slug}/skills.md`;
728
- const outputLines = agent.outputs.length > 0 ? agent.outputs.map((o) => `- ${o}`).join("\n") : "- (voir skills.md pour le d\xE9tail)";
729
- return `### ${agent.fullName}
730
+ const outputLines = agent.outputs.length > 0 ? agent.outputs.map((o) => `- ${o}`).join("\n") : "- (see skills.md for details)";
731
+ return `### Agent ${agent.number} \xB7 ${agent.name}
730
732
 
731
- **P\xE9rim\xE8tre** : ${agent.scope}
733
+ **Scope**: ${agent.scope}
732
734
 
733
- **Skills** : \`${skillsPath}\`
735
+ **Skills**: \`${skillsPath}\`
734
736
 
735
- **Fichiers produits** :
737
+ **Deliverables**:
736
738
  ${outputLines}
737
739
 
738
- **Crit\xE8re de succ\xE8s** :
740
+ **Success criterion**:
739
741
  \`\`\`bash
740
742
  ${agent.criterion || "npm run build && npm test"}
741
743
  \`\`\`
742
744
 
743
- **En cas d'\xE9chec** :
744
- 1. Analyser le message d'erreur complet
745
- 2. Corriger la cause racine (pas les sympt\xF4mes)
746
- 3. R\xE9ex\xE9cuter le crit\xE8re (max 3 tentatives)
747
- 4. Apr\xE8s 3 \xE9checs \u2192 demander validation humaine
745
+ **On failure**:
746
+ 1. Read the full error output
747
+ 2. Fix the root cause \u2014 not the symptoms
748
+ 3. Rerun the success criterion (max 3 attempts)
749
+ 4. After 3 failures \u2192 ask for human validation
748
750
  `;
749
751
  }
750
752
 
@@ -798,6 +800,52 @@ ${outputLines}
798
800
  `;
799
801
  }
800
802
 
803
+ // src/utils/agentParser.ts
804
+ function toSlug(name) {
805
+ return name.toLowerCase().replace(/[·•&]/g, " ").replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
806
+ }
807
+ function getFieldValue(lines, pattern) {
808
+ for (const line of lines) {
809
+ const m = line.match(pattern);
810
+ if (m) return (m[1] ?? "").trim();
811
+ }
812
+ return "";
813
+ }
814
+ function extractAgentsFromWorkflow(content) {
815
+ const agents = [];
816
+ const blocks = content.split(/(?=^### Agent \d)/m).filter((b) => /^### Agent \d/.test(b.trimStart()));
817
+ for (const block of blocks) {
818
+ const lines = block.split("\n");
819
+ const headerMatch = lines[0].match(/^### Agent (\d+)\s*[·•]\s*(.+)$/);
820
+ if (!headerMatch) continue;
821
+ const number = parseInt(headerMatch[1], 10);
822
+ const name = headerMatch[2].trim();
823
+ const fullName = `Agent ${number} \xB7 ${name}`;
824
+ const slug = toSlug(name);
825
+ const scope = getFieldValue(lines, /Périmètre\s*:\s*(.+)/);
826
+ const criterion = getFieldValue(lines, /Critère[s]?\s*:\s*(.+)/);
827
+ const outputs = [];
828
+ const produitIdx = lines.findIndex((l) => /Produit\s*:/.test(l));
829
+ if (produitIdx !== -1) {
830
+ const inlineVal = (lines[produitIdx].match(/Produit\s*:\s*(.+)/)?.[1] ?? "").trim();
831
+ if (inlineVal) {
832
+ outputs.push(inlineVal);
833
+ } else {
834
+ for (let i = produitIdx + 1; i < lines.length; i++) {
835
+ const line = lines[i];
836
+ if (/^\s+[-]/.test(line)) {
837
+ outputs.push(line.trim().replace(/^-\s*/, ""));
838
+ } else if (line.trim() !== "" && !/^\s/.test(line)) {
839
+ break;
840
+ }
841
+ }
842
+ }
843
+ }
844
+ agents.push({ number, name, fullName, slug, scope, outputs, criterion });
845
+ }
846
+ return agents;
847
+ }
848
+
801
849
  // src/utils/logger.ts
802
850
  var import_chalk = __toESM(require("chalk"), 1);
803
851
  var logger = {
@@ -897,9 +945,9 @@ function registerInit(program2) {
897
945
  }
898
946
  const genSpinner = (0, import_ora.default)("G\xE9n\xE9ration des fichiers\u2026").start();
899
947
  const claudeMdContent = generateClaudeMd(stack, blueprintContent);
900
- const workflowContent = generateWorkflow(stack, blueprintContent);
948
+ const workflowContent = generateWorkflow(stack, blueprintContent, projectName);
901
949
  const agents = extractAgentsFromWorkflow(workflowContent);
902
- const playbookContent = generatePlaybook({ agents, projectName });
950
+ const playbookContent = generatePlaybook({ agents, projectName, hasBlueprint: !!blueprintContent });
903
951
  await (0, import_promises4.writeFile)(claudeMdPath, claudeMdContent, "utf-8");
904
952
  await (0, import_promises4.writeFile)(workflowPath, workflowContent, "utf-8");
905
953
  await (0, import_promises4.writeFile)(playbookPath, playbookContent, "utf-8");
@@ -927,7 +975,7 @@ async function addFeatureToProject(description, projectDir) {
927
975
  try {
928
976
  workflowContent = await (0, import_promises5.readFile)(workflowPath, "utf-8");
929
977
  } catch {
930
- throw new Error(`AGENT_WORKFLOW.md introuvable dans ${projectDir} \u2014 lancez agentkit init`);
978
+ throw new Error(`AGENT_WORKFLOW.md not found in ${projectDir} \u2014 run agentkit init first`);
931
979
  }
932
980
  const existingAgents = extractAgentsFromWorkflow(workflowContent);
933
981
  const nextNumber = existingAgents.length + 1;
@@ -961,7 +1009,11 @@ Crit\xE8re : npm run build && npm test
961
1009
  } catch {
962
1010
  }
963
1011
  const allAgents = [...existingAgents, newAgent];
964
- const playbookContent = generatePlaybook({ agents: allAgents, projectName });
1012
+ const playbookContent = generatePlaybook({
1013
+ agents: allAgents,
1014
+ projectName,
1015
+ hasBlueprint: false
1016
+ });
965
1017
  await (0, import_promises5.writeFile)(playbookPath, playbookContent, "utf-8");
966
1018
  return {
967
1019
  agent: newAgent,
@@ -969,13 +1021,13 @@ Crit\xE8re : npm run build && npm test
969
1021
  };
970
1022
  }
971
1023
  function registerAdd(program2) {
972
- const addCmd = program2.command("add").description("Ajoute des ressources au projet agentkit").option("--feature <description>", "Ajoute un agent depuis une description de feature et r\xE9g\xE9n\xE8re PLAYBOOK.md").action(async (options) => {
1024
+ const addCmd = program2.command("add").description("Add resources to the agentkit project").option("--feature <description>", "Add an agent from a feature description and regenerate PLAYBOOK.md").action(async (options) => {
973
1025
  if (options.feature) {
974
1026
  try {
975
1027
  const result = await addFeatureToProject(options.feature, process.cwd());
976
- logger.success(`Agent ajout\xE9 : ${result.agent.fullName}`);
977
- logger.success(`Dossier cr\xE9\xE9 : agents/agent-${result.agent.number}-${result.agent.slug}/`);
978
- logger.success("PLAYBOOK.md : r\xE9g\xE9n\xE9r\xE9");
1028
+ logger.success(`Agent added : ${result.agent.fullName}`);
1029
+ logger.success(`Folder created : agents/agent-${result.agent.number}-${result.agent.slug}/`);
1030
+ logger.success("PLAYBOOK.md : regenerated");
979
1031
  } catch (err) {
980
1032
  logger.error(err instanceof Error ? err.message : String(err));
981
1033
  process.exit(1);
@@ -984,14 +1036,14 @@ function registerAdd(program2) {
984
1036
  addCmd.help();
985
1037
  }
986
1038
  });
987
- addCmd.command("agent").description("Ajoute un nouvel agent dans AGENT_WORKFLOW.md (interactif)").action(async () => {
1039
+ addCmd.command("agent").description("Add a new agent to AGENT_WORKFLOW.md (interactive)").action(async () => {
988
1040
  const cwd = process.cwd();
989
1041
  const workflowPath = (0, import_node_path6.join)(cwd, "AGENT_WORKFLOW.md");
990
1042
  let existing = "";
991
1043
  try {
992
1044
  existing = await (0, import_promises5.readFile)(workflowPath, "utf-8");
993
1045
  } catch {
994
- logger.error("AGENT_WORKFLOW.md introuvable \u2014 lancez d'abord : agentkit init");
1046
+ logger.error("AGENT_WORKFLOW.md not found \u2014 run agentkit init first");
995
1047
  process.exit(1);
996
1048
  }
997
1049
  const agentCount = (existing.match(/^### Agent \d+/gm) ?? []).length;
@@ -1000,23 +1052,23 @@ function registerAdd(program2) {
1000
1052
  {
1001
1053
  type: "input",
1002
1054
  name: "name",
1003
- message: `Nom de l'agent (ex: "Agent ${nextNumber} \xB7 Feature X") :`,
1055
+ message: `Agent name (e.g. "Agent ${nextNumber} \xB7 Feature X"):`,
1004
1056
  default: `Agent ${nextNumber}`
1005
1057
  },
1006
1058
  {
1007
1059
  type: "input",
1008
1060
  name: "scope",
1009
- message: "P\xE9rim\xE8tre (une phrase) :"
1061
+ message: "Scope (one sentence):"
1010
1062
  },
1011
1063
  {
1012
1064
  type: "input",
1013
1065
  name: "outputs",
1014
- message: "Fichiers produits (s\xE9par\xE9s par des virgules) :"
1066
+ message: "Deliverables (comma-separated):"
1015
1067
  },
1016
1068
  {
1017
1069
  type: "input",
1018
1070
  name: "criterion",
1019
- message: "Crit\xE8re de succ\xE8s :"
1071
+ message: "Success criterion:"
1020
1072
  }
1021
1073
  ]);
1022
1074
  const outputLines = answers.outputs.split(",").map((o) => ` - ${o.trim()}`).join("\n");
@@ -1028,7 +1080,7 @@ ${outputLines}
1028
1080
  Crit\xE8re : ${answers.criterion}
1029
1081
  `;
1030
1082
  await (0, import_promises5.writeFile)(workflowPath, existing + agentSection, "utf-8");
1031
- logger.success(`Agent "${answers.name}" ajout\xE9 dans AGENT_WORKFLOW.md`);
1083
+ logger.success(`Agent "${answers.name}" added to AGENT_WORKFLOW.md`);
1032
1084
  });
1033
1085
  }
1034
1086