@patricksardinha/agentkit-cli 0.5.2 → 0.6.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/README.md +77 -31
- package/dist/cli.cjs +33 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +33 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
- package/src/generators/playbookGenerator.ts +34 -1
- package/tests/generators/playbookGenerator.test.ts +24 -0
package/README.md
CHANGED
|
@@ -29,20 +29,16 @@ This is a deliberate choice. AgentKit is a **structural tool** — it generates
|
|
|
29
29
|
- **You** — you optionally write a `PROJECT_BLUEPRINT.md` describing what you want to build
|
|
30
30
|
- **Claude Code** — it either reads your blueprint or asks you questions, decomposes the project into specialized agents, then executes them in sequence
|
|
31
31
|
|
|
32
|
-
This separation means AgentKit works with any LLM and never becomes outdated
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- **
|
|
36
|
-
provider (Anthropic, OpenAI, etc.)
|
|
37
|
-
- **Local models via Ollama** are free to run, but require a machine with
|
|
38
|
-
sufficient RAM and ideally a dedicated GPU — a standard laptop may
|
|
39
|
-
struggle with larger models
|
|
32
|
+
This separation means AgentKit works with any LLM and never becomes outdated as AI models improve. The tool itself costs nothing to run — but be aware:
|
|
33
|
+
|
|
34
|
+
- **Claude Code or any hosted LLM** requires a paid subscription to the provider (Anthropic, OpenAI, etc.)
|
|
35
|
+
- **Local models via Ollama** are free to run, but require a machine with sufficient RAM and ideally a dedicated GPU — a standard laptop may struggle with larger models
|
|
40
36
|
- **AgentKit itself** has no cost, no API key, and no usage limits
|
|
41
37
|
|
|
42
38
|
```
|
|
43
39
|
You (optionally write a blueprint)
|
|
44
40
|
↓
|
|
45
|
-
AgentKit CLI (generates the structure)
|
|
41
|
+
AgentKit CLI (detects stack or asks you, generates the structure)
|
|
46
42
|
↓
|
|
47
43
|
Claude Code (discovers or reads blueprint → decomposes → executes)
|
|
48
44
|
↓
|
|
@@ -161,7 +157,7 @@ Once you validate the decomposition, Claude Code executes each agent autonomousl
|
|
|
161
157
|
```
|
|
162
158
|
Agent 1 → Infra & Tauri Setup
|
|
163
159
|
reads : CLAUDE.md + agents/agent-1-infra/skills.md
|
|
164
|
-
runs : npm run
|
|
160
|
+
runs : npm run build
|
|
165
161
|
✅ passes → moves to Agent 2
|
|
166
162
|
❌ fails → analyzes error, fixes, retries (max 3 times)
|
|
167
163
|
→ after 3 failures: asks for human intervention
|
|
@@ -187,6 +183,69 @@ Read PLAYBOOK.md and execute the procedure.
|
|
|
187
183
|
|
|
188
184
|
---
|
|
189
185
|
|
|
186
|
+
## Stack Detection
|
|
187
|
+
|
|
188
|
+
AgentKit automatically reads your project directory to detect the stack.
|
|
189
|
+
If it can identify your framework, it generates a `CLAUDE.md` immediately.
|
|
190
|
+
If not, it asks you interactively.
|
|
191
|
+
|
|
192
|
+
### Automatic detection
|
|
193
|
+
|
|
194
|
+
AgentKit reads `package.json`, `Cargo.toml`, `requirements.txt`, and your
|
|
195
|
+
directory structure to identify the stack without any input from you.
|
|
196
|
+
|
|
197
|
+
| Stack | Detected by |
|
|
198
|
+
|---|---|
|
|
199
|
+
| **React + Vite** | `react` in `package.json` dependencies |
|
|
200
|
+
| **Next.js** | `next` in `package.json` dependencies |
|
|
201
|
+
| **Tauri v2** | `src-tauri/` directory present |
|
|
202
|
+
| **FastAPI** | `fastapi` in `requirements.txt` |
|
|
203
|
+
| **Express** | `express` in `package.json` dependencies |
|
|
204
|
+
| **Node.js** | `package.json` exists (generic fallback) |
|
|
205
|
+
|
|
206
|
+
### Interactive selection (when stack is not detected)
|
|
207
|
+
|
|
208
|
+
If the project directory is empty or the stack cannot be identified automatically
|
|
209
|
+
(new project, unusual structure), AgentKit asks you to pick from the supported list:
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
⚠ Stack not detected automatically.
|
|
213
|
+
? Stack not detected automatically. Please select your stack:
|
|
214
|
+
❯ React + Vite
|
|
215
|
+
Next.js
|
|
216
|
+
Tauri v2 (React + Rust)
|
|
217
|
+
FastAPI (Python)
|
|
218
|
+
Express (Node.js)
|
|
219
|
+
Node.js (generic)
|
|
220
|
+
None of the above — generate a generic CLAUDE.md to fill manually
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
This covers the most common case: **starting a brand new project** from an
|
|
224
|
+
empty folder. You pick your stack, AgentKit generates a fully enriched `CLAUDE.md`
|
|
225
|
+
with the right commands, conventions, and structure — as if it had detected the
|
|
226
|
+
stack automatically.
|
|
227
|
+
|
|
228
|
+
### "None of the above"
|
|
229
|
+
|
|
230
|
+
If your stack isn't in the list, AgentKit generates a generic `CLAUDE.md` with
|
|
231
|
+
a clear warning at the top:
|
|
232
|
+
|
|
233
|
+
```markdown
|
|
234
|
+
## ⚠️ Stack not configured
|
|
235
|
+
AgentKit could not detect your stack and no stack was selected.
|
|
236
|
+
Before running Claude Code, fill in: Stack, Commands, Structure.
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
You fill in the missing sections, then give Claude Code the usual instruction.
|
|
240
|
+
|
|
241
|
+
### Adding a new stack
|
|
242
|
+
|
|
243
|
+
The supported stack list grows with each release. If your stack isn't supported
|
|
244
|
+
yet, see the **Contributing** section — adding a new template takes less than
|
|
245
|
+
30 minutes.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
190
249
|
## The Generated Files
|
|
191
250
|
|
|
192
251
|
```
|
|
@@ -255,26 +314,16 @@ Phase 0 only ever runs once — during the initial `agentkit init`. Iterations g
|
|
|
255
314
|
|
|
256
315
|
---
|
|
257
316
|
|
|
258
|
-
## Supported Stacks
|
|
259
|
-
|
|
260
|
-
| Stack | Detected by | Template enrichment |
|
|
261
|
-
|---|---|---|
|
|
262
|
-
| **React** | `react` in `package.json` | TypeScript/JS, Vite, testing |
|
|
263
|
-
| **Next.js** | `next` in `package.json` | App Router, Tailwind, Prisma |
|
|
264
|
-
| **Tauri** | `src-tauri/` directory | Rust/JS boundary, IPC, plugins |
|
|
265
|
-
| **FastAPI** | `fastapi` in `requirements.txt` | Python, Pydantic, async |
|
|
266
|
-
| **Express** | `express` in `package.json` | REST, middleware, auth |
|
|
267
|
-
| **Node.js** | `package.json` (generic) | Scripts, modules, CI/CD |
|
|
268
|
-
| **Unknown** | fallback | Generic editable workflow |
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
317
|
## Design Philosophy
|
|
273
318
|
|
|
274
319
|
### No AI in the tool — by design
|
|
275
320
|
|
|
276
321
|
Integrating an LLM into AgentKit would mean choosing a provider, managing API keys, adding costs, and coupling the tool to a specific model that will become outdated. Instead, AgentKit is purely structural — it generates files that any LLM can read and act on. The intelligence lives in Claude Code (or whatever tool you use), not in AgentKit.
|
|
277
322
|
|
|
323
|
+
### Stack detection first, interactive fallback
|
|
324
|
+
|
|
325
|
+
AgentKit tries to detect your stack automatically. If it can't — because the project is empty or uses an uncommon structure — it asks you interactively rather than generating something useless. The goal is always a `CLAUDE.md` that Claude Code can actually use, not a generic placeholder that needs manual editing.
|
|
326
|
+
|
|
278
327
|
### Phase 0 always runs — with or without blueprint
|
|
279
328
|
|
|
280
329
|
The key insight: most developers don't know how to optimally decompose a project into agents. AgentKit solves this by always delegating decomposition to Claude Code. With a blueprint, Claude Code reads the file. Without one, it asks you three questions. Either way, you never have to think about agents yourself — that's Claude Code's job.
|
|
@@ -301,7 +350,7 @@ Every agent ends with a runnable check — not a goal, a gate. The PLAYBOOK enfo
|
|
|
301
350
|
|
|
302
351
|
This CLI was built using the exact workflow it generates.
|
|
303
352
|
|
|
304
|
-
### A
|
|
353
|
+
### A note on honesty
|
|
305
354
|
|
|
306
355
|
The `CLAUDE.md`, `AGENT_WORKFLOW.md`, and `PLAYBOOK.md` files at the root of
|
|
307
356
|
this repo are **illustrative** — they were written after the fact to show what
|
|
@@ -365,10 +414,6 @@ Step 3 — "Read PLAYBOOK.md and execute the procedure."
|
|
|
365
414
|
🎉 Workflow complete
|
|
366
415
|
```
|
|
367
416
|
|
|
368
|
-
The `CLAUDE.md`, `AGENT_WORKFLOW.md`, and `PLAYBOOK.md` in this repo show
|
|
369
|
-
exactly what each file looks like after AgentKit generates it and Claude Code
|
|
370
|
-
fills it in. Use them as a reference when writing your own `PROJECT_BLUEPRINT.md`.
|
|
371
|
-
|
|
372
417
|
---
|
|
373
418
|
|
|
374
419
|
## Project Structure
|
|
@@ -425,8 +470,9 @@ To add a new stack template:
|
|
|
425
470
|
|
|
426
471
|
1. Create `src/templates/your-stack.ts` — export `claudeMd(stack)` and `workflow(stack)`
|
|
427
472
|
2. Add detection in `src/detectors/stackDetector.ts`
|
|
428
|
-
3.
|
|
429
|
-
4.
|
|
473
|
+
3. Add the stack to the interactive selection list in `src/commands/init.ts`
|
|
474
|
+
4. Register in `src/generators/claudeMdGenerator.ts` and `workflowGenerator.ts`
|
|
475
|
+
5. Add fixtures in `tests/detectors/` and tests in `tests/generators/`
|
|
430
476
|
|
|
431
477
|
---
|
|
432
478
|
|
package/dist/cli.cjs
CHANGED
|
@@ -685,6 +685,38 @@ Wait for confirmation before moving to Phase 1.
|
|
|
685
685
|
|
|
686
686
|
---
|
|
687
687
|
|
|
688
|
+
`;
|
|
689
|
+
const betweenPhase = `## Between Phase 0 and Phase 1 \u2014 Skills Enrichment
|
|
690
|
+
|
|
691
|
+
Once the decomposition is validated, before writing any code:
|
|
692
|
+
|
|
693
|
+
1. Create all agent folders and empty skills files:
|
|
694
|
+
For each agent in your decomposition, create:
|
|
695
|
+
- agents/agent-{N}-{slug}/skills.md (empty for now)
|
|
696
|
+
|
|
697
|
+
2. Announce to the user:
|
|
698
|
+
"Agent folders created under agents/.
|
|
699
|
+
|
|
700
|
+
You can now enrich any skills.md with additional context
|
|
701
|
+
before I start executing:
|
|
702
|
+
- API documentation
|
|
703
|
+
- Database schemas
|
|
704
|
+
- Algorithm references
|
|
705
|
+
- Business conventions
|
|
706
|
+
- Any project-specific knowledge
|
|
707
|
+
|
|
708
|
+
Add .md files directly in the relevant agent folder \u2014
|
|
709
|
+
I will read everything in agents/agent-{N}-{slug}/ before
|
|
710
|
+
starting that agent.
|
|
711
|
+
|
|
712
|
+
Type 'proceed' (or any message) when you're ready
|
|
713
|
+
and I'll start Phase 1."
|
|
714
|
+
|
|
715
|
+
3. Wait for the user's message before starting Phase 1.
|
|
716
|
+
Do not start Agent 1 until the user explicitly responds.
|
|
717
|
+
|
|
718
|
+
---
|
|
719
|
+
|
|
688
720
|
`;
|
|
689
721
|
return `# PLAYBOOK.md \u2014 ${projectName}
|
|
690
722
|
|
|
@@ -715,7 +747,7 @@ After each agent:
|
|
|
715
747
|
|
|
716
748
|
---
|
|
717
749
|
|
|
718
|
-
${phase0}## Phase 1 \u2014 Execution
|
|
750
|
+
${phase0}${betweenPhase}## Phase 1 \u2014 Execution
|
|
719
751
|
|
|
720
752
|
${agentBlocks}
|
|
721
753
|
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/detectors/stackDetector.ts","../src/detectors/gitDetector.ts","../src/templates/react.ts","../src/templates/nextjs.ts","../src/templates/tauri.ts","../src/templates/fastapi.ts","../src/templates/express.ts","../src/templates/node.ts","../src/templates/unknown.ts","../src/generators/claudeMdGenerator.ts","../src/generators/workflowGenerator.ts","../src/generators/playbookGenerator.ts","../src/generators/skillsGenerator.ts","../src/utils/agentParser.ts","../src/utils/logger.ts","../src/commands/add.ts","../src/commands/status.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander'\nimport { registerInit } from './commands/init.js'\nimport { registerAdd } from './commands/add.js'\nimport { registerStatus } from './commands/status.js'\n\nconst program = new Command()\n\nprogram\n .name('agentkit')\n .description('Scaffolder des workflows multi-agents Claude Code')\n .version('0.1.0')\n\nregisterInit(program)\nregisterAdd(program)\nregisterStatus(program)\n\nprogram.parse()\n","import type { Command } from 'commander'\nimport { writeFile, readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport inquirer from 'inquirer'\nimport ora from 'ora'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { generateClaudeMd } from '../generators/claudeMdGenerator.js'\nimport { generateWorkflow } from '../generators/workflowGenerator.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport { extractAgentsFromWorkflow } from '../utils/agentParser.js'\nimport { logger } from '../utils/logger.js'\nimport type { StackInfo } from '../detectors/stackDetector.js'\nimport { basename } from 'node:path'\n\nconst FRAMEWORK_LABELS: Record<StackInfo['framework'], string> = {\n react: 'React',\n nextjs: 'Next.js',\n tauri: 'Tauri',\n fastapi: 'FastAPI (Python)',\n express: 'Express',\n node: 'Node.js',\n unknown: 'Unknown (generic)',\n}\n\nconst STACK_CHOICES = [\n { name: 'React + Vite', value: 'react' },\n { name: 'Next.js', value: 'nextjs' },\n { name: 'Tauri v2 (React + Rust)', value: 'tauri' },\n { name: 'FastAPI (Python)', value: 'fastapi' },\n { name: 'Express (Node.js)', value: 'express' },\n { name: 'Node.js (generic)', value: 'node' },\n { name: 'None of the above — generate a generic CLAUDE.md to fill manually', value: 'none' },\n]\n\nexport async function resolveStack(\n detected: StackInfo,\n): Promise<{ stack: StackInfo; stackNotConfigured: boolean }> {\n if (detected.framework !== 'unknown') {\n return { stack: detected, stackNotConfigured: false }\n }\n\n logger.warn('Stack not detected automatically.')\n const { selectedFramework } = await inquirer.prompt<{ selectedFramework: string }>([\n {\n type: 'list',\n name: 'selectedFramework',\n message: 'Stack not detected automatically. Please select your stack:',\n choices: STACK_CHOICES as unknown as string[],\n },\n ])\n\n if (selectedFramework === 'none') {\n return { stack: detected, stackNotConfigured: true }\n }\n\n const framework = selectedFramework as StackInfo['framework']\n const hasTypeScript = ['react', 'nextjs', 'tauri'].includes(framework)\n const language: StackInfo['language'] = framework === 'fastapi' ? 'python' : hasTypeScript ? 'typescript' : 'javascript'\n return {\n stack: { ...detected, framework, language, hasTypeScript },\n stackNotConfigured: false,\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path)\n return true\n } catch {\n return false\n }\n}\n\nexport function registerInit(program: Command): void {\n program\n .command('init')\n .description('Génère CLAUDE.md et AGENT_WORKFLOW.md dans le dossier courant')\n .option('-f, --force', 'Écrase les fichiers existants sans confirmation')\n .option('--blueprint <path>', 'Fichier blueprint .md à utiliser pour personnaliser les fichiers générés')\n .action(async (options: { force?: boolean; blueprint?: string }) => {\n const cwd = process.cwd()\n\n const spinner = ora('Détection de la stack…').start()\n const [stack, isGit] = await Promise.all([detectStack(cwd), isGitRepo(cwd)])\n spinner.stop()\n\n if (!isGit) {\n logger.warn('Ce dossier n\\'est pas un repo git — lancez git init si nécessaire')\n }\n\n const { stack: resolvedStack, stackNotConfigured } = await resolveStack(stack)\n\n const label = FRAMEWORK_LABELS[resolvedStack.framework]\n logger.info(`Stack : ${label} (${resolvedStack.language})`)\n\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message: `Générer les fichiers pour ${label} ?`,\n default: true,\n },\n ])\n\n if (!confirmed) {\n logger.warn('Annulé.')\n return\n }\n\n const claudeMdPath = join(cwd, 'CLAUDE.md')\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n const playbookPath = join(cwd, 'PLAYBOOK.md')\n\n // Resolve project name from package.json or directory name\n let projectName = basename(cwd)\n try {\n const pkg = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf-8')) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* fallback to dirname */ }\n\n if (!options.force) {\n const existing: string[] = []\n if (await fileExists(claudeMdPath)) existing.push('CLAUDE.md')\n if (await fileExists(workflowPath)) existing.push('AGENT_WORKFLOW.md')\n if (await fileExists(playbookPath)) existing.push('PLAYBOOK.md')\n\n if (existing.length > 0) {\n const { overwrite } = await inquirer.prompt<{ overwrite: boolean }>([\n {\n type: 'confirm',\n name: 'overwrite',\n message: `${existing.join(' et ')} existe déjà. Écraser ?`,\n default: false,\n },\n ])\n if (!overwrite) {\n logger.warn('Annulé.')\n return\n }\n }\n }\n\n // Load blueprint if provided\n let blueprintContent: string | undefined\n if (options.blueprint) {\n try {\n blueprintContent = await readFile(options.blueprint, 'utf-8')\n } catch {\n logger.error(`Blueprint introuvable : ${options.blueprint}`)\n process.exit(1)\n }\n }\n\n const genSpinner = ora('Génération des fichiers…').start()\n const claudeMdContent = generateClaudeMd(resolvedStack, blueprintContent, stackNotConfigured)\n const workflowContent = generateWorkflow(resolvedStack, blueprintContent, projectName)\n const agents = extractAgentsFromWorkflow(workflowContent)\n const playbookContent = generatePlaybook({ agents, projectName, hasBlueprint: !!blueprintContent })\n await writeFile(claudeMdPath, claudeMdContent, 'utf-8')\n await writeFile(workflowPath, workflowContent, 'utf-8')\n await writeFile(playbookPath, playbookContent, 'utf-8')\n await generateSkills(agents, cwd)\n genSpinner.succeed('Fichiers générés')\n\n logger.success('CLAUDE.md → créé')\n logger.success('AGENT_WORKFLOW.md → créé')\n logger.success('PLAYBOOK.md → créé')\n logger.success(`agents/ → ${agents.length} dossier(s) créé(s)`)\n })\n}\n","import { readFile, access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface StackInfo {\n framework: 'react' | 'nextjs' | 'tauri' | 'fastapi' | 'express' | 'node' | 'unknown'\n language: 'typescript' | 'javascript' | 'python' | 'unknown'\n hasTypeScript: boolean\n extras: string[]\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch {\n return false\n }\n}\n\nasync function readJson(p: string): Promise<Record<string, unknown> | null> {\n try {\n const raw = await readFile(p, 'utf-8')\n return JSON.parse(raw) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\nasync function readText(p: string): Promise<string | null> {\n try {\n return await readFile(p, 'utf-8')\n } catch {\n return null\n }\n}\n\nexport async function detectStack(projectPath: string): Promise<StackInfo> {\n const info: StackInfo = {\n framework: 'unknown',\n language: 'unknown',\n hasTypeScript: false,\n extras: [],\n }\n\n const packageJson = await readJson(join(projectPath, 'package.json'))\n const requirementsTxt = await readText(join(projectPath, 'requirements.txt'))\n const hasTauriDir = await pathExists(join(projectPath, 'src-tauri'))\n const hasTsConfig = await pathExists(join(projectPath, 'tsconfig.json'))\n\n if (packageJson !== null) {\n const deps = (packageJson.dependencies as Record<string, string>) ?? {}\n const devDeps = (packageJson.devDependencies as Record<string, string>) ?? {}\n const allDeps = { ...deps, ...devDeps }\n\n info.hasTypeScript = 'typescript' in allDeps || hasTsConfig\n info.language = info.hasTypeScript ? 'typescript' : 'javascript'\n\n // Order matters: most specific first\n if ('next' in allDeps) {\n info.framework = 'nextjs'\n } else if (hasTauriDir || '@tauri-apps/api' in allDeps || '@tauri-apps/cli' in allDeps) {\n info.framework = 'tauri'\n } else if ('react' in allDeps) {\n info.framework = 'react'\n } else if ('express' in allDeps) {\n info.framework = 'express'\n } else {\n info.framework = 'node'\n }\n\n if ('vitest' in allDeps || 'jest' in allDeps) info.extras.push('testing')\n if ('prisma' in allDeps || '@prisma/client' in allDeps) info.extras.push('prisma')\n if ('tailwindcss' in allDeps) info.extras.push('tailwind')\n }\n\n if (requirementsTxt !== null && info.framework === 'unknown') {\n info.language = 'python'\n if (/\\bfastapi\\b/i.test(requirementsTxt)) {\n info.framework = 'fastapi'\n }\n }\n\n if (hasTauriDir && info.framework === 'unknown') {\n info.framework = 'tauri'\n }\n\n return info\n}\n","import { access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport async function isGitRepo(projectPath: string): Promise<boolean> {\n try {\n await access(join(projectPath, '.git'))\n return true\n } catch {\n return false\n }\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const testLine = stack.extras.includes('testing') ? '- `npm test` — run tests\\n' : ''\n return `# CLAUDE.md — React Project\n\n## Stack\n- Framework : React (${lang})\n- Language : ${lang}\n- Build : Vite\n\n## Commands\n- \\`npm run dev\\` — development server\n- \\`npm run build\\` — production build\n${testLine}\n## Structure\nsrc/\n components/ ← UI components (PascalCase)\n hooks/ ← custom hooks (prefix: use*)\n pages/ ← page-level components\n utils/ ← shared helpers\n\n## Conventions\n1. Components in PascalCase\n2. Hooks prefixed with \\`use\\`\n3. Props interfaces named \\`*Props\\`\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — React Project\n\n## Stack détectée\nFramework: React | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Components\nPérimètre : composants UI réutilisables\nProduit : src/components/\nCritère : composants documentés et testés\n\n### Agent 2 · State & Hooks\nPérimètre : state management, hooks personnalisés\nProduit : src/hooks/\nCritère : hooks testés unitairement\n\n### Agent 3 · Pages & Routing\nPérimètre : assemblage des pages, react-router\nProduit : src/pages/\nCritère : navigation fonctionnelle\n\n### Agent 4 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const hasTailwind = stack.extras.includes('tailwind')\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Next.js Project\n\n## Stack\n- Framework : Next.js (TypeScript)\n- Rendering : App Router (RSC + Client Components)\n- Styling : ${hasTailwind ? 'Tailwind CSS' : 'CSS Modules'}\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (http://localhost:3000)\n- \\`npm run build\\` — production build\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n app/ ← App Router pages and layouts\n components/ ← shared UI components\n lib/ ← server utilities, db clients\n utils/ ← shared helpers\n\n## Conventions\n1. Server Components by default, \\`'use client'\\` only when needed\n2. API routes in \\`src/app/api/\\`\n3. Environment variables via \\`src/env.ts\\` (validated)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const hasPrisma = stack.extras.includes('prisma')\n return `# Agent Workflow — Next.js Project\n\n## Stack détectée\nFramework: Next.js | Language: TypeScript\n\n## Agents\n\n### Agent 1 · Data Layer\nPérimètre : schéma${hasPrisma ? ' Prisma' : ''}, types, server actions\nProduit : src/lib/, ${hasPrisma ? 'prisma/schema.prisma' : 'src/types/'}\nCritère : types compilent, migrations propres\n\n### Agent 2 · UI Components\nPérimètre : composants réutilisables (Server + Client)\nProduit : src/components/\nCritère : composants rendus sans erreur\n\n### Agent 3 · Pages & Layout\nPérimètre : App Router, layouts, pages\nProduit : src/app/\nCritère : navigation fonctionnelle, build passe\n\n### Agent 4 · API & Tests\nPérimètre : API routes, tests e2e/unitaires\nProduit : src/app/api/, tests/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Tauri Project\n\n## Stack\n- Framework : Tauri (Rust + ${lang} frontend)\n- Language : Rust (backend) + ${lang} (frontend)\n- Build : Cargo + Vite\n\n## Commands\n- \\`npm run tauri:dev\\` — development (hot reload)\n- \\`npm run tauri:build\\` — production bundle\n- \\`npm run dev\\` — frontend only\n- \\`npx tsc --noEmit\\` — type check\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/ ← frontend (${lang})\n components/\n utils/\nsrc-tauri/ ← Rust backend\n src/\n main.rs ← Tauri entry point\n commands.rs ← Tauri commands (IPC)\n tauri.conf.json\n\n## Conventions\n1. IPC commands defined in \\`src-tauri/src/commands.rs\\`\n2. Frontend invokes via \\`@tauri-apps/api/tauri\\`\n3. No direct filesystem access from frontend\n4. All console output goes through a centralized logger\n5. Always use \\`isTauri()\\` before any Tauri plugin call\n6. All Tauri plugin imports must be dynamic (never top-level)\n7. Every Tauri plugin call must have a browser fallback\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Tauri Project\n\n## Stack détectée\nFramework: Tauri | Language: Rust + ${lang}\n\n## Agents\n\n### Agent 1 · Rust Commands\nPérimètre : commandes Tauri (IPC), permissions\nProduit : src-tauri/src/commands.rs, tauri.conf.json\nCritère : \\`cargo build\\` passe\n\n### Agent 2 · Frontend UI\nPérimètre : interface ${lang}, intégration IPC\nProduit : src/components/, src/utils/\nCritère : appels IPC fonctionnels\n\n### Agent 3 · Build & Packaging\nPérimètre : configuration build, icônes, installeurs\nProduit : src-tauri/tauri.conf.json, icons/\nCritère : \\`npm run tauri build\\` produit un bundle\n\n### Agent 4 · Tests\nPérimètre : tests Rust + tests frontend\nProduit : src-tauri/tests/, tests/\nCritère : \\`cargo test\\` + \\`npm test\\` passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md — FastAPI Project\n\n## Stack\n- Framework : FastAPI (Python)\n- Language : Python 3.11+\n- Server : Uvicorn\n- Validation: Pydantic v2\n\n## Commands\n- \\`uvicorn main:app --reload\\` — development server (http://localhost:8000)\n- \\`pytest\\` — run tests\n- \\`pip install -r requirements.txt\\` — install dependencies\n\n## Structure\napp/\n main.py ← FastAPI app entry point\n routers/ ← API route groups\n models/ ← Pydantic models\n services/ ← business logic\n dependencies/ ← FastAPI dependencies (DI)\ntests/ ← pytest tests\n\n## Conventions\n1. Routers grouped by domain in \\`app/routers/\\`\n2. Pydantic models for all request/response bodies\n3. Business logic in \\`app/services/\\`, not in routes\n4. Async endpoints by default (\\`async def\\`)\n5. Environment variables via \\`python-dotenv\\` + \\`pydantic-settings\\`\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow — FastAPI Project\n\n## Stack détectée\nFramework: FastAPI | Language: Python\n\n## Agents\n\n### Agent 1 · Models & Schemas\nPérimètre : modèles Pydantic, schémas DB (SQLAlchemy/SQLModel)\nProduit : app/models/\nCritère : modèles validés, migrations propres\n\n### Agent 2 · Services\nPérimètre : logique métier, accès base de données\nProduit : app/services/\nCritère : services testés unitairement (pytest)\n\n### Agent 3 · Routers & API\nPérimètre : routes FastAPI, dépendances, auth\nProduit : app/routers/, app/dependencies/\nCritère : endpoints documentés (OpenAPI), tests d'intégration\n\n### Agent 4 · Tests & CI\nPérimètre : couverture pytest, configuration CI\nProduit : tests/, .github/workflows/\nCritère : \\`pytest\\` passe à 100%\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Express Project\n\n## Stack\n- Framework : Express (${lang})\n- Language : ${lang}\n- Runtime : Node.js 20+\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (nodemon)\n- \\`npm run build\\` — compile TypeScript\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n routes/ ← Express routers (one per domain)\n controllers/ ← request handlers\n services/ ← business logic\n middleware/ ← Express middleware\n utils/ ← shared helpers\n\n## Conventions\n1. Routes grouped by domain in \\`src/routes/\\`\n2. Business logic in \\`src/services/\\`, not in controllers\n3. Middleware for cross-cutting concerns (auth, validation)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Express Project\n\n## Stack détectée\nFramework: Express | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Data & Models\nPérimètre : modèles de données, accès DB\nProduit : src/models/, src/services/db.ts\nCritère : connexion DB fonctionnelle\n\n### Agent 2 · Services\nPérimètre : logique métier\nProduit : src/services/\nCritère : services testés unitairement\n\n### Agent 3 · Routes & Controllers\nPérimètre : routes Express, validation, auth\nProduit : src/routes/, src/controllers/, src/middleware/\nCritère : endpoints répondent correctement\n\n### Agent 4 · Tests & CI\nPérimètre : tests d'intégration, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Node.js Project\n\n## Stack\n- Runtime : Node.js 20+\n- Language : ${lang}\n\n## Commands\n- \\`npm run dev\\` — development (with watch)\n- \\`npm run build\\` — compile${stack.hasTypeScript ? ' TypeScript' : ''}\n- \\`npm start\\` — run production build\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n index.ts ← entry point\n lib/ ← core library code\n utils/ ← shared helpers\n\n## Conventions\n1. Modules follow single-responsibility principle\n2. Async/await over callbacks\n3. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Node.js Project\n\n## Stack détectée\nRuntime: Node.js | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Core Library\nPérimètre : logique principale\nProduit : src/lib/\nCritère : module fonctionne et testé\n\n### Agent 2 · CLI / API\nPérimètre : interface utilisateur (CLI ou API)\nProduit : src/index.ts, src/cli.ts\nCritère : commandes fonctionnelles\n\n### Agent 3 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md\n\n## Stack\nStack non détectée automatiquement — à remplir manuellement.\n\n## Commands\n- À définir selon le projet\n\n## Structure\nsrc/ ← code source\ntests/ ← tests\n\n## Conventions\n1. Tout output console passe par un logger centralisé\n2. À compléter selon les conventions du projet\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow\n\n## Stack détectée\nStack inconnue — workflow générique.\n\n## Agents\n\n### Agent 1 · Setup\nPérimètre : configuration initiale du projet\nProduit : structure de base\nCritère : projet compilable\n\n### Agent 2 · Core\nPérimètre : logique principale\nProduit : src/\nCritère : fonctionnalités principales opérationnelles\n\n### Agent 3 · Tests\nPérimètre : couverture de tests\nProduit : tests/\nCritère : tests passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nconst STACK_NOT_CONFIGURED_WARNING = `\n## ⚠️ Stack not configured\nAgentKit could not detect your stack and no stack was selected.\nBefore running Claude Code, fill in the following sections:\n- Stack (framework, runtime, DB, tools)\n- Commands (dev, build, test)\n- Structure (folder layout)\n\nOnce filled, give Claude Code this instruction:\n\"Read PLAYBOOK.md and execute the procedure.\"\n`\n\nexport function generateClaudeMd(stack: StackInfo, blueprintContent?: string, stackNotConfigured?: boolean): string {\n let base: string\n switch (stack.framework) {\n case 'react': base = react.claudeMd(stack); break\n case 'nextjs': base = nextjs.claudeMd(stack); break\n case 'tauri': base = tauri.claudeMd(stack); break\n case 'fastapi': base = fastapi.claudeMd(stack); break\n case 'express': base = express.claudeMd(stack); break\n case 'node': base = node.claudeMd(stack); break\n default: base = unknown.claudeMd(stack)\n }\n\n if (stackNotConfigured) {\n const firstNewline = base.indexOf('\\n')\n base = base.slice(0, firstNewline + 1) + STACK_NOT_CONFIGURED_WARNING + base.slice(firstNewline + 1)\n }\n\n if (!blueprintContent) return base\n\n const blueprintNote = '\\n> A PROJECT_BLUEPRINT.md is present — Claude Code will read it during Phase 0.\\n'\n\n const conventionsIdx = base.indexOf('\\n## Conventions')\n if (conventionsIdx !== -1) {\n return base.slice(0, conventionsIdx) + blueprintNote + base.slice(conventionsIdx)\n }\n return base + blueprintNote\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nexport function generateWorkflow(stack: StackInfo, blueprintContent?: string, projectName?: string): string {\n if (blueprintContent) return blueprintPlaceholder(projectName ?? stack.framework)\n\n switch (stack.framework) {\n case 'react': return react.workflow(stack)\n case 'nextjs': return nextjs.workflow(stack)\n case 'tauri': return tauri.workflow(stack)\n case 'fastapi': return fastapi.workflow(stack)\n case 'express': return express.workflow(stack)\n case 'node': return node.workflow(stack)\n default: return unknown.workflow(stack)\n }\n}\n\nfunction blueprintPlaceholder(projectName: string): string {\n return `# AGENT_WORKFLOW.md — ${projectName}\n\n> This file will be filled in by Claude Code during Phase 0.\n> Claude Code will read PROJECT_BLUEPRINT.md, propose a decomposition,\n> and replace this content after human validation.\n\n---\n\n*Waiting for Phase 0 decomposition...*\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport interface PlaybookInput {\n agents: Agent[]\n projectName: string\n hasBlueprint: boolean\n}\n\nexport function generatePlaybook({ agents, projectName, hasBlueprint }: PlaybookInput): string {\n const agentBlocks = agents.map((a) => agentBlock(a)).join('\\n---\\n\\n')\n\n const phase0 = hasBlueprint\n ? `## Phase 0 — Agent Decomposition (run this first)\n\n> A \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Claude Code reads it and decomposes the project into specialized agents\n> before writing a single line of code.\n\n**Read these files in order:**\n1. \\`CLAUDE.md\\`\n2. \\`PROJECT_BLUEPRINT.md\\`\n\n**Then decompose the project into agents** following these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n : `## Phase 0 — Project Discovery (run this first)\n\n> No \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Before writing any code, Claude Code asks the user what they want to build,\n> then decomposes the project into agents — exactly as if a blueprint had been provided.\n\n**Ask the user these questions and wait for their answers:**\n\n1. What is this project? (one sentence describing the goal)\n2. What are the main features you want to build? (list them)\n3. Are there any tech constraints or architecture preferences?\n (e.g. offline-only, specific DB, no auth, specific framework)\n\n**Once you have the answers, decompose the project into agents**\nfollowing these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n\n return `# PLAYBOOK.md — ${projectName}\n\n> **One instruction to give Claude Code:**\n> \"Read PLAYBOOK.md and execute the procedure.\"\n>\n> Claude Code handles the rest autonomously — project discovery or blueprint reading,\n> agent decomposition, execution, success validation, retries, and human escalation.\n> No API key required. No additional cost beyond your LLM subscription.\n\n---\n\n## Global Execution Rules\n\nBefore each agent:\n1. Read \\`CLAUDE.md\\`\n2. Read \\`agents/agent-{N}-{slug}/skills.md\\` (current agent's file)\n3. Read the agent's section in \\`AGENT_WORKFLOW.md\\`\n\nAfter each agent:\n- Run the success criterion command\n- ✅ Passes → announce \"✅ Agent N complete\" and move to the next\n- ❌ Fails → analyze the root cause, fix, rerun (max 3 attempts)\n- After 3 consecutive failures → stop and ask for human validation\n\n**Never move to the next agent without a passing success criterion.**\n**Stay strictly within your current agent's defined scope.**\n\n---\n\n${phase0}## Phase 1 — Execution\n\n${agentBlocks}\n\n---\n\n## Future Iterations\n\nWhen a new agent is added via \\`agentkit add --feature <description>\\`:\n1. A new agent block is appended to \\`AGENT_WORKFLOW.md\\`\n2. The folder \\`agents/agent-{N}-{slug}/\\` is created with \\`skills.md\\`\n3. This \\`PLAYBOOK.md\\` is regenerated to include the new agent\n4. Execution resumes at the new agent only — completed agents are not rerun\n\nWhen you receive the instruction to continue after an iteration:\n> \"Read PLAYBOOK.md and execute only the agents that haven't been completed yet.\"\n\n---\n\n## Human Validation Required\n\nStop and wait for confirmation in these situations:\n- **3 consecutive failures** on the same success criterion\n- **Missing external dependency**: API key, env variable, unavailable service\n- **Conflict** between the detected stack and the user's stated constraints\n- **Destructive operation**: overwriting files not listed in deliverables\n- **End of Phase 0**: agent decomposition must be validated before execution\n`\n}\n\nfunction agentBlock(agent: Agent): string {\n const skillsPath = `agents/agent-${agent.number}-${agent.slug}/skills.md`\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (see skills.md for details)'\n\n return `### Agent ${agent.number} · ${agent.name}\n\n**Scope**: ${agent.scope}\n\n**Skills**: \\`${skillsPath}\\`\n\n**Deliverables**:\n${outputLines}\n\n**Success criterion**:\n\\`\\`\\`bash\n${agent.criterion || 'npm run build && npm test'}\n\\`\\`\\`\n\n**On failure**:\n1. Read the full error output\n2. Fix the root cause — not the symptoms\n3. Rerun the success criterion (max 3 attempts)\n4. After 3 failures → ask for human validation\n`\n}","import { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { Agent } from '../types/agent.js'\n\nexport async function generateSkills(agents: Agent[], outputDir: string): Promise<void> {\n for (const agent of agents) {\n const agentDir = join(outputDir, 'agents', `agent-${agent.number}-${agent.slug}`)\n await mkdir(agentDir, { recursive: true })\n await writeFile(join(agentDir, 'skills.md'), skillsMd(agent), 'utf-8')\n await writeFile(join(agentDir, 'context.md'), contextMd(agent), 'utf-8')\n }\n}\n\nfunction skillsMd(agent: Agent): string {\n return `# Skills — ${agent.fullName}\n\n> Ce fichier est lu par l'agent avant de commencer.\n\n## Contexte technique\n\n<!-- À remplir : bibliothèques, versions, décisions d'architecture spécifiques à cet agent -->\n\n## Documentation de référence\n\n<!-- À remplir : liens vers docs, exemples, ADRs pertinents -->\n\n## Conventions spécifiques\n\n<!-- À remplir : règles propres à cet agent (naming, patterns, structure de fichiers) -->\n`\n}\n\nfunction contextMd(agent: Agent): string {\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (voir AGENT_WORKFLOW.md)'\n\n return `# Context — ${agent.fullName}\n\n> Ce fichier fournit le contexte additionnel à l'agent avant exécution.\n> À compléter avant de lancer cet agent.\n\n## Périmètre\n\n${agent.scope}\n\n## Fichiers produits attendus\n\n${outputLines}\n\n## Critère de succès\n\n\\`${agent.criterion || 'npm run build && npm test'}\\`\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport function toSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[·•&]/g, ' ')\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nfunction getFieldValue(lines: string[], pattern: RegExp): string {\n for (const line of lines) {\n const m = line.match(pattern)\n if (m) return (m[1] ?? '').trim()\n }\n return ''\n}\n\nexport function extractAgentsFromWorkflow(content: string): Agent[] {\n const agents: Agent[] = []\n\n // Split into blocks starting with \"### Agent N\"\n const blocks = content\n .split(/(?=^### Agent \\d)/m)\n .filter((b) => /^### Agent \\d/.test(b.trimStart()))\n\n for (const block of blocks) {\n const lines = block.split('\\n')\n\n const headerMatch = lines[0].match(/^### Agent (\\d+)\\s*[·•]\\s*(.+)$/)\n if (!headerMatch) continue\n\n const number = parseInt(headerMatch[1], 10)\n const name = headerMatch[2].trim()\n const fullName = `Agent ${number} · ${name}`\n const slug = toSlug(name)\n\n const scope = getFieldValue(lines, /Périmètre\\s*:\\s*(.+)/)\n const criterion = getFieldValue(lines, /Critère[s]?\\s*:\\s*(.+)/)\n\n // Outputs: may be inline or multi-line (indented \"- item\")\n const outputs: string[] = []\n const produitIdx = lines.findIndex((l) => /Produit\\s*:/.test(l))\n if (produitIdx !== -1) {\n const inlineVal = (lines[produitIdx].match(/Produit\\s*:\\s*(.+)/)?.[1] ?? '').trim()\n if (inlineVal) {\n outputs.push(inlineVal)\n } else {\n for (let i = produitIdx + 1; i < lines.length; i++) {\n const line = lines[i]\n if (/^\\s+[-]/.test(line)) {\n outputs.push(line.trim().replace(/^-\\s*/, ''))\n } else if (line.trim() !== '' && !/^\\s/.test(line)) {\n break\n }\n }\n }\n }\n\n agents.push({ number, name, fullName, slug, scope, outputs, criterion })\n }\n\n return agents\n}\n","import chalk from 'chalk'\n\nexport const logger = {\n info: (message: string): void => {\n process.stdout.write(chalk.blue('ℹ') + ' ' + message + '\\n')\n },\n success: (message: string): void => {\n process.stdout.write(chalk.green('✔') + ' ' + message + '\\n')\n },\n warn: (message: string): void => {\n process.stdout.write(chalk.yellow('⚠') + ' ' + message + '\\n')\n },\n error: (message: string): void => {\n process.stderr.write(chalk.red('✖') + ' ' + message + '\\n')\n },\n}\n","import type { Command } from 'commander'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport { join, basename } from 'node:path'\nimport inquirer from 'inquirer'\nimport { logger } from '../utils/logger.js'\nimport { extractAgentsFromWorkflow, toSlug } from '../utils/agentParser.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport type { Agent } from '../types/agent.js'\n\nfunction featureToAgentName(description: string): string {\n const clean = description\n .replace(/^(add|implement|create|build|integrate|setup|configure|refactor|improve)\\s+/i, '')\n .trim()\n return clean.replace(/\\b\\w/g, (c) => c.toUpperCase())\n}\n\nexport interface AddFeatureResult {\n agent: Agent\n agentDirPath: string\n}\n\nexport async function addFeatureToProject(\n description: string,\n projectDir: string,\n): Promise<AddFeatureResult> {\n const workflowPath = join(projectDir, 'AGENT_WORKFLOW.md')\n const playbookPath = join(projectDir, 'PLAYBOOK.md')\n\n let workflowContent = ''\n try {\n workflowContent = await readFile(workflowPath, 'utf-8')\n } catch {\n throw new Error(`AGENT_WORKFLOW.md not found in ${projectDir} — run agentkit init first`)\n }\n\n const existingAgents = extractAgentsFromWorkflow(workflowContent)\n const nextNumber = existingAgents.length + 1\n const name = featureToAgentName(description)\n const slug = toSlug(name)\n const fullName = `Agent ${nextNumber} · ${name}`\n\n const newAgent: Agent = {\n number: nextNumber,\n name,\n fullName,\n slug,\n scope: description,\n outputs: [`agents/agent-${nextNumber}-${slug}/`],\n criterion: 'npm run build && npm test',\n }\n\n const agentBlock = `\n### ${fullName}\nPérimètre : ${description}\nProduit :\n - agents/agent-${nextNumber}-${slug}/\nCritère : npm run build && npm test\n`\n\n await writeFile(workflowPath, workflowContent + agentBlock, 'utf-8')\n await generateSkills([newAgent], projectDir)\n\n let projectName = basename(projectDir)\n try {\n const pkg = JSON.parse(\n await readFile(join(projectDir, 'package.json'), 'utf-8'),\n ) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* use dirname fallback */ }\n\n const allAgents = [...existingAgents, newAgent]\n\n // When adding a feature iteration, hasBlueprint is false —\n // Phase 0 decomposition only runs during the initial init with --blueprint.\n const playbookContent = generatePlaybook({\n agents: allAgents,\n projectName,\n hasBlueprint: false,\n })\n await writeFile(playbookPath, playbookContent, 'utf-8')\n\n return {\n agent: newAgent,\n agentDirPath: join(projectDir, 'agents', `agent-${nextNumber}-${slug}`),\n }\n}\n\nexport function registerAdd(program: Command): void {\n const addCmd = program\n .command('add')\n .description('Add resources to the agentkit project')\n .option('--feature <description>', 'Add an agent from a feature description and regenerate PLAYBOOK.md')\n .action(async (options: { feature?: string }) => {\n if (options.feature) {\n try {\n const result = await addFeatureToProject(options.feature, process.cwd())\n logger.success(`Agent added : ${result.agent.fullName}`)\n logger.success(`Folder created : agents/agent-${result.agent.number}-${result.agent.slug}/`)\n logger.success('PLAYBOOK.md : regenerated')\n } catch (err) {\n logger.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n } else {\n addCmd.help()\n }\n })\n\n addCmd\n .command('agent')\n .description('Add a new agent to AGENT_WORKFLOW.md (interactive)')\n .action(async () => {\n const cwd = process.cwd()\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n\n let existing = ''\n try {\n existing = await readFile(workflowPath, 'utf-8')\n } catch {\n logger.error('AGENT_WORKFLOW.md not found — run agentkit init first')\n process.exit(1)\n }\n\n const agentCount = (existing.match(/^### Agent \\d+/gm) ?? []).length\n const nextNumber = agentCount + 1\n\n const answers = await inquirer.prompt<{\n name: string\n scope: string\n outputs: string\n criterion: string\n }>([\n {\n type: 'input',\n name: 'name',\n message: `Agent name (e.g. \"Agent ${nextNumber} · Feature X\"):`,\n default: `Agent ${nextNumber}`,\n },\n {\n type: 'input',\n name: 'scope',\n message: 'Scope (one sentence):',\n },\n {\n type: 'input',\n name: 'outputs',\n message: 'Deliverables (comma-separated):',\n },\n {\n type: 'input',\n name: 'criterion',\n message: 'Success criterion:',\n },\n ])\n\n const outputLines = answers.outputs\n .split(',')\n .map((o: string) => ` - ${o.trim()}`)\n .join('\\n')\n\n const agentSection = `\n### ${answers.name}\nPérimètre : ${answers.scope}\nProduit :\n${outputLines}\nCritère : ${answers.criterion}\n`\n\n await writeFile(workflowPath, existing + agentSection, 'utf-8')\n logger.success(`Agent \"${answers.name}\" added to AGENT_WORKFLOW.md`)\n })\n}","import type { Command } from 'commander'\nimport { readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport chalk from 'chalk'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { logger } from '../utils/logger.js'\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Affiche l\\'état du workflow agentkit dans le dossier courant')\n .action(async () => {\n const cwd = process.cwd()\n\n const [stack, isGit, claudeMd, workflow] = await Promise.all([\n detectStack(cwd),\n isGitRepo(cwd),\n readFile(join(cwd, 'CLAUDE.md'), 'utf-8').catch(() => null),\n readFile(join(cwd, 'AGENT_WORKFLOW.md'), 'utf-8').catch(() => null),\n ])\n\n process.stdout.write('\\n' + chalk.bold('AgentKit Status') + '\\n')\n process.stdout.write('─'.repeat(40) + '\\n')\n\n process.stdout.write(\n chalk.bold('Git repo : ') +\n (isGit ? chalk.green('✔ oui') : chalk.red('✖ non')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('Stack : ') + chalk.cyan(stack.framework) + ' (' + stack.language + ')\\n',\n )\n\n process.stdout.write(\n chalk.bold('CLAUDE.md : ') +\n (claudeMd !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('AGENT_WORKFLOW.md : ') +\n (workflow !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n if (workflow !== null) {\n const agentMatches = workflow.match(/^### Agent \\d+/gm) ?? []\n process.stdout.write(\n chalk.bold('Agents définis : ') + chalk.cyan(String(agentMatches.length)) + '\\n',\n )\n }\n\n process.stdout.write('─'.repeat(40) + '\\n\\n')\n })\n}\n"],"mappings":"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","names":["import_promises","import_node_path","import_promises","import_node_path","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","import_promises","import_node_path","chalk","import_node_path","inquirer","program","ora","import_promises","import_node_path","import_inquirer","agentBlock","program","inquirer","import_promises","import_node_path","import_chalk","program","claudeMd","workflow","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/detectors/stackDetector.ts","../src/detectors/gitDetector.ts","../src/templates/react.ts","../src/templates/nextjs.ts","../src/templates/tauri.ts","../src/templates/fastapi.ts","../src/templates/express.ts","../src/templates/node.ts","../src/templates/unknown.ts","../src/generators/claudeMdGenerator.ts","../src/generators/workflowGenerator.ts","../src/generators/playbookGenerator.ts","../src/generators/skillsGenerator.ts","../src/utils/agentParser.ts","../src/utils/logger.ts","../src/commands/add.ts","../src/commands/status.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander'\nimport { registerInit } from './commands/init.js'\nimport { registerAdd } from './commands/add.js'\nimport { registerStatus } from './commands/status.js'\n\nconst program = new Command()\n\nprogram\n .name('agentkit')\n .description('Scaffolder des workflows multi-agents Claude Code')\n .version('0.1.0')\n\nregisterInit(program)\nregisterAdd(program)\nregisterStatus(program)\n\nprogram.parse()\n","import type { Command } from 'commander'\nimport { writeFile, readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport inquirer from 'inquirer'\nimport ora from 'ora'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { generateClaudeMd } from '../generators/claudeMdGenerator.js'\nimport { generateWorkflow } from '../generators/workflowGenerator.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport { extractAgentsFromWorkflow } from '../utils/agentParser.js'\nimport { logger } from '../utils/logger.js'\nimport type { StackInfo } from '../detectors/stackDetector.js'\nimport { basename } from 'node:path'\n\nconst FRAMEWORK_LABELS: Record<StackInfo['framework'], string> = {\n react: 'React',\n nextjs: 'Next.js',\n tauri: 'Tauri',\n fastapi: 'FastAPI (Python)',\n express: 'Express',\n node: 'Node.js',\n unknown: 'Unknown (generic)',\n}\n\nconst STACK_CHOICES = [\n { name: 'React + Vite', value: 'react' },\n { name: 'Next.js', value: 'nextjs' },\n { name: 'Tauri v2 (React + Rust)', value: 'tauri' },\n { name: 'FastAPI (Python)', value: 'fastapi' },\n { name: 'Express (Node.js)', value: 'express' },\n { name: 'Node.js (generic)', value: 'node' },\n { name: 'None of the above — generate a generic CLAUDE.md to fill manually', value: 'none' },\n]\n\nexport async function resolveStack(\n detected: StackInfo,\n): Promise<{ stack: StackInfo; stackNotConfigured: boolean }> {\n if (detected.framework !== 'unknown') {\n return { stack: detected, stackNotConfigured: false }\n }\n\n logger.warn('Stack not detected automatically.')\n const { selectedFramework } = await inquirer.prompt<{ selectedFramework: string }>([\n {\n type: 'list',\n name: 'selectedFramework',\n message: 'Stack not detected automatically. Please select your stack:',\n choices: STACK_CHOICES as unknown as string[],\n },\n ])\n\n if (selectedFramework === 'none') {\n return { stack: detected, stackNotConfigured: true }\n }\n\n const framework = selectedFramework as StackInfo['framework']\n const hasTypeScript = ['react', 'nextjs', 'tauri'].includes(framework)\n const language: StackInfo['language'] = framework === 'fastapi' ? 'python' : hasTypeScript ? 'typescript' : 'javascript'\n return {\n stack: { ...detected, framework, language, hasTypeScript },\n stackNotConfigured: false,\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path)\n return true\n } catch {\n return false\n }\n}\n\nexport function registerInit(program: Command): void {\n program\n .command('init')\n .description('Génère CLAUDE.md et AGENT_WORKFLOW.md dans le dossier courant')\n .option('-f, --force', 'Écrase les fichiers existants sans confirmation')\n .option('--blueprint <path>', 'Fichier blueprint .md à utiliser pour personnaliser les fichiers générés')\n .action(async (options: { force?: boolean; blueprint?: string }) => {\n const cwd = process.cwd()\n\n const spinner = ora('Détection de la stack…').start()\n const [stack, isGit] = await Promise.all([detectStack(cwd), isGitRepo(cwd)])\n spinner.stop()\n\n if (!isGit) {\n logger.warn('Ce dossier n\\'est pas un repo git — lancez git init si nécessaire')\n }\n\n const { stack: resolvedStack, stackNotConfigured } = await resolveStack(stack)\n\n const label = FRAMEWORK_LABELS[resolvedStack.framework]\n logger.info(`Stack : ${label} (${resolvedStack.language})`)\n\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message: `Générer les fichiers pour ${label} ?`,\n default: true,\n },\n ])\n\n if (!confirmed) {\n logger.warn('Annulé.')\n return\n }\n\n const claudeMdPath = join(cwd, 'CLAUDE.md')\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n const playbookPath = join(cwd, 'PLAYBOOK.md')\n\n // Resolve project name from package.json or directory name\n let projectName = basename(cwd)\n try {\n const pkg = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf-8')) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* fallback to dirname */ }\n\n if (!options.force) {\n const existing: string[] = []\n if (await fileExists(claudeMdPath)) existing.push('CLAUDE.md')\n if (await fileExists(workflowPath)) existing.push('AGENT_WORKFLOW.md')\n if (await fileExists(playbookPath)) existing.push('PLAYBOOK.md')\n\n if (existing.length > 0) {\n const { overwrite } = await inquirer.prompt<{ overwrite: boolean }>([\n {\n type: 'confirm',\n name: 'overwrite',\n message: `${existing.join(' et ')} existe déjà. Écraser ?`,\n default: false,\n },\n ])\n if (!overwrite) {\n logger.warn('Annulé.')\n return\n }\n }\n }\n\n // Load blueprint if provided\n let blueprintContent: string | undefined\n if (options.blueprint) {\n try {\n blueprintContent = await readFile(options.blueprint, 'utf-8')\n } catch {\n logger.error(`Blueprint introuvable : ${options.blueprint}`)\n process.exit(1)\n }\n }\n\n const genSpinner = ora('Génération des fichiers…').start()\n const claudeMdContent = generateClaudeMd(resolvedStack, blueprintContent, stackNotConfigured)\n const workflowContent = generateWorkflow(resolvedStack, blueprintContent, projectName)\n const agents = extractAgentsFromWorkflow(workflowContent)\n const playbookContent = generatePlaybook({ agents, projectName, hasBlueprint: !!blueprintContent })\n await writeFile(claudeMdPath, claudeMdContent, 'utf-8')\n await writeFile(workflowPath, workflowContent, 'utf-8')\n await writeFile(playbookPath, playbookContent, 'utf-8')\n await generateSkills(agents, cwd)\n genSpinner.succeed('Fichiers générés')\n\n logger.success('CLAUDE.md → créé')\n logger.success('AGENT_WORKFLOW.md → créé')\n logger.success('PLAYBOOK.md → créé')\n logger.success(`agents/ → ${agents.length} dossier(s) créé(s)`)\n })\n}\n","import { readFile, access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface StackInfo {\n framework: 'react' | 'nextjs' | 'tauri' | 'fastapi' | 'express' | 'node' | 'unknown'\n language: 'typescript' | 'javascript' | 'python' | 'unknown'\n hasTypeScript: boolean\n extras: string[]\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch {\n return false\n }\n}\n\nasync function readJson(p: string): Promise<Record<string, unknown> | null> {\n try {\n const raw = await readFile(p, 'utf-8')\n return JSON.parse(raw) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\nasync function readText(p: string): Promise<string | null> {\n try {\n return await readFile(p, 'utf-8')\n } catch {\n return null\n }\n}\n\nexport async function detectStack(projectPath: string): Promise<StackInfo> {\n const info: StackInfo = {\n framework: 'unknown',\n language: 'unknown',\n hasTypeScript: false,\n extras: [],\n }\n\n const packageJson = await readJson(join(projectPath, 'package.json'))\n const requirementsTxt = await readText(join(projectPath, 'requirements.txt'))\n const hasTauriDir = await pathExists(join(projectPath, 'src-tauri'))\n const hasTsConfig = await pathExists(join(projectPath, 'tsconfig.json'))\n\n if (packageJson !== null) {\n const deps = (packageJson.dependencies as Record<string, string>) ?? {}\n const devDeps = (packageJson.devDependencies as Record<string, string>) ?? {}\n const allDeps = { ...deps, ...devDeps }\n\n info.hasTypeScript = 'typescript' in allDeps || hasTsConfig\n info.language = info.hasTypeScript ? 'typescript' : 'javascript'\n\n // Order matters: most specific first\n if ('next' in allDeps) {\n info.framework = 'nextjs'\n } else if (hasTauriDir || '@tauri-apps/api' in allDeps || '@tauri-apps/cli' in allDeps) {\n info.framework = 'tauri'\n } else if ('react' in allDeps) {\n info.framework = 'react'\n } else if ('express' in allDeps) {\n info.framework = 'express'\n } else {\n info.framework = 'node'\n }\n\n if ('vitest' in allDeps || 'jest' in allDeps) info.extras.push('testing')\n if ('prisma' in allDeps || '@prisma/client' in allDeps) info.extras.push('prisma')\n if ('tailwindcss' in allDeps) info.extras.push('tailwind')\n }\n\n if (requirementsTxt !== null && info.framework === 'unknown') {\n info.language = 'python'\n if (/\\bfastapi\\b/i.test(requirementsTxt)) {\n info.framework = 'fastapi'\n }\n }\n\n if (hasTauriDir && info.framework === 'unknown') {\n info.framework = 'tauri'\n }\n\n return info\n}\n","import { access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport async function isGitRepo(projectPath: string): Promise<boolean> {\n try {\n await access(join(projectPath, '.git'))\n return true\n } catch {\n return false\n }\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const testLine = stack.extras.includes('testing') ? '- `npm test` — run tests\\n' : ''\n return `# CLAUDE.md — React Project\n\n## Stack\n- Framework : React (${lang})\n- Language : ${lang}\n- Build : Vite\n\n## Commands\n- \\`npm run dev\\` — development server\n- \\`npm run build\\` — production build\n${testLine}\n## Structure\nsrc/\n components/ ← UI components (PascalCase)\n hooks/ ← custom hooks (prefix: use*)\n pages/ ← page-level components\n utils/ ← shared helpers\n\n## Conventions\n1. Components in PascalCase\n2. Hooks prefixed with \\`use\\`\n3. Props interfaces named \\`*Props\\`\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — React Project\n\n## Stack détectée\nFramework: React | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Components\nPérimètre : composants UI réutilisables\nProduit : src/components/\nCritère : composants documentés et testés\n\n### Agent 2 · State & Hooks\nPérimètre : state management, hooks personnalisés\nProduit : src/hooks/\nCritère : hooks testés unitairement\n\n### Agent 3 · Pages & Routing\nPérimètre : assemblage des pages, react-router\nProduit : src/pages/\nCritère : navigation fonctionnelle\n\n### Agent 4 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const hasTailwind = stack.extras.includes('tailwind')\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Next.js Project\n\n## Stack\n- Framework : Next.js (TypeScript)\n- Rendering : App Router (RSC + Client Components)\n- Styling : ${hasTailwind ? 'Tailwind CSS' : 'CSS Modules'}\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (http://localhost:3000)\n- \\`npm run build\\` — production build\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n app/ ← App Router pages and layouts\n components/ ← shared UI components\n lib/ ← server utilities, db clients\n utils/ ← shared helpers\n\n## Conventions\n1. Server Components by default, \\`'use client'\\` only when needed\n2. API routes in \\`src/app/api/\\`\n3. Environment variables via \\`src/env.ts\\` (validated)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const hasPrisma = stack.extras.includes('prisma')\n return `# Agent Workflow — Next.js Project\n\n## Stack détectée\nFramework: Next.js | Language: TypeScript\n\n## Agents\n\n### Agent 1 · Data Layer\nPérimètre : schéma${hasPrisma ? ' Prisma' : ''}, types, server actions\nProduit : src/lib/, ${hasPrisma ? 'prisma/schema.prisma' : 'src/types/'}\nCritère : types compilent, migrations propres\n\n### Agent 2 · UI Components\nPérimètre : composants réutilisables (Server + Client)\nProduit : src/components/\nCritère : composants rendus sans erreur\n\n### Agent 3 · Pages & Layout\nPérimètre : App Router, layouts, pages\nProduit : src/app/\nCritère : navigation fonctionnelle, build passe\n\n### Agent 4 · API & Tests\nPérimètre : API routes, tests e2e/unitaires\nProduit : src/app/api/, tests/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Tauri Project\n\n## Stack\n- Framework : Tauri (Rust + ${lang} frontend)\n- Language : Rust (backend) + ${lang} (frontend)\n- Build : Cargo + Vite\n\n## Commands\n- \\`npm run tauri:dev\\` — development (hot reload)\n- \\`npm run tauri:build\\` — production bundle\n- \\`npm run dev\\` — frontend only\n- \\`npx tsc --noEmit\\` — type check\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/ ← frontend (${lang})\n components/\n utils/\nsrc-tauri/ ← Rust backend\n src/\n main.rs ← Tauri entry point\n commands.rs ← Tauri commands (IPC)\n tauri.conf.json\n\n## Conventions\n1. IPC commands defined in \\`src-tauri/src/commands.rs\\`\n2. Frontend invokes via \\`@tauri-apps/api/tauri\\`\n3. No direct filesystem access from frontend\n4. All console output goes through a centralized logger\n5. Always use \\`isTauri()\\` before any Tauri plugin call\n6. All Tauri plugin imports must be dynamic (never top-level)\n7. Every Tauri plugin call must have a browser fallback\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Tauri Project\n\n## Stack détectée\nFramework: Tauri | Language: Rust + ${lang}\n\n## Agents\n\n### Agent 1 · Rust Commands\nPérimètre : commandes Tauri (IPC), permissions\nProduit : src-tauri/src/commands.rs, tauri.conf.json\nCritère : \\`cargo build\\` passe\n\n### Agent 2 · Frontend UI\nPérimètre : interface ${lang}, intégration IPC\nProduit : src/components/, src/utils/\nCritère : appels IPC fonctionnels\n\n### Agent 3 · Build & Packaging\nPérimètre : configuration build, icônes, installeurs\nProduit : src-tauri/tauri.conf.json, icons/\nCritère : \\`npm run tauri build\\` produit un bundle\n\n### Agent 4 · Tests\nPérimètre : tests Rust + tests frontend\nProduit : src-tauri/tests/, tests/\nCritère : \\`cargo test\\` + \\`npm test\\` passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md — FastAPI Project\n\n## Stack\n- Framework : FastAPI (Python)\n- Language : Python 3.11+\n- Server : Uvicorn\n- Validation: Pydantic v2\n\n## Commands\n- \\`uvicorn main:app --reload\\` — development server (http://localhost:8000)\n- \\`pytest\\` — run tests\n- \\`pip install -r requirements.txt\\` — install dependencies\n\n## Structure\napp/\n main.py ← FastAPI app entry point\n routers/ ← API route groups\n models/ ← Pydantic models\n services/ ← business logic\n dependencies/ ← FastAPI dependencies (DI)\ntests/ ← pytest tests\n\n## Conventions\n1. Routers grouped by domain in \\`app/routers/\\`\n2. Pydantic models for all request/response bodies\n3. Business logic in \\`app/services/\\`, not in routes\n4. Async endpoints by default (\\`async def\\`)\n5. Environment variables via \\`python-dotenv\\` + \\`pydantic-settings\\`\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow — FastAPI Project\n\n## Stack détectée\nFramework: FastAPI | Language: Python\n\n## Agents\n\n### Agent 1 · Models & Schemas\nPérimètre : modèles Pydantic, schémas DB (SQLAlchemy/SQLModel)\nProduit : app/models/\nCritère : modèles validés, migrations propres\n\n### Agent 2 · Services\nPérimètre : logique métier, accès base de données\nProduit : app/services/\nCritère : services testés unitairement (pytest)\n\n### Agent 3 · Routers & API\nPérimètre : routes FastAPI, dépendances, auth\nProduit : app/routers/, app/dependencies/\nCritère : endpoints documentés (OpenAPI), tests d'intégration\n\n### Agent 4 · Tests & CI\nPérimètre : couverture pytest, configuration CI\nProduit : tests/, .github/workflows/\nCritère : \\`pytest\\` passe à 100%\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Express Project\n\n## Stack\n- Framework : Express (${lang})\n- Language : ${lang}\n- Runtime : Node.js 20+\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (nodemon)\n- \\`npm run build\\` — compile TypeScript\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n routes/ ← Express routers (one per domain)\n controllers/ ← request handlers\n services/ ← business logic\n middleware/ ← Express middleware\n utils/ ← shared helpers\n\n## Conventions\n1. Routes grouped by domain in \\`src/routes/\\`\n2. Business logic in \\`src/services/\\`, not in controllers\n3. Middleware for cross-cutting concerns (auth, validation)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Express Project\n\n## Stack détectée\nFramework: Express | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Data & Models\nPérimètre : modèles de données, accès DB\nProduit : src/models/, src/services/db.ts\nCritère : connexion DB fonctionnelle\n\n### Agent 2 · Services\nPérimètre : logique métier\nProduit : src/services/\nCritère : services testés unitairement\n\n### Agent 3 · Routes & Controllers\nPérimètre : routes Express, validation, auth\nProduit : src/routes/, src/controllers/, src/middleware/\nCritère : endpoints répondent correctement\n\n### Agent 4 · Tests & CI\nPérimètre : tests d'intégration, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Node.js Project\n\n## Stack\n- Runtime : Node.js 20+\n- Language : ${lang}\n\n## Commands\n- \\`npm run dev\\` — development (with watch)\n- \\`npm run build\\` — compile${stack.hasTypeScript ? ' TypeScript' : ''}\n- \\`npm start\\` — run production build\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n index.ts ← entry point\n lib/ ← core library code\n utils/ ← shared helpers\n\n## Conventions\n1. Modules follow single-responsibility principle\n2. Async/await over callbacks\n3. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Node.js Project\n\n## Stack détectée\nRuntime: Node.js | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Core Library\nPérimètre : logique principale\nProduit : src/lib/\nCritère : module fonctionne et testé\n\n### Agent 2 · CLI / API\nPérimètre : interface utilisateur (CLI ou API)\nProduit : src/index.ts, src/cli.ts\nCritère : commandes fonctionnelles\n\n### Agent 3 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md\n\n## Stack\nStack non détectée automatiquement — à remplir manuellement.\n\n## Commands\n- À définir selon le projet\n\n## Structure\nsrc/ ← code source\ntests/ ← tests\n\n## Conventions\n1. Tout output console passe par un logger centralisé\n2. À compléter selon les conventions du projet\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow\n\n## Stack détectée\nStack inconnue — workflow générique.\n\n## Agents\n\n### Agent 1 · Setup\nPérimètre : configuration initiale du projet\nProduit : structure de base\nCritère : projet compilable\n\n### Agent 2 · Core\nPérimètre : logique principale\nProduit : src/\nCritère : fonctionnalités principales opérationnelles\n\n### Agent 3 · Tests\nPérimètre : couverture de tests\nProduit : tests/\nCritère : tests passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nconst STACK_NOT_CONFIGURED_WARNING = `\n## ⚠️ Stack not configured\nAgentKit could not detect your stack and no stack was selected.\nBefore running Claude Code, fill in the following sections:\n- Stack (framework, runtime, DB, tools)\n- Commands (dev, build, test)\n- Structure (folder layout)\n\nOnce filled, give Claude Code this instruction:\n\"Read PLAYBOOK.md and execute the procedure.\"\n`\n\nexport function generateClaudeMd(stack: StackInfo, blueprintContent?: string, stackNotConfigured?: boolean): string {\n let base: string\n switch (stack.framework) {\n case 'react': base = react.claudeMd(stack); break\n case 'nextjs': base = nextjs.claudeMd(stack); break\n case 'tauri': base = tauri.claudeMd(stack); break\n case 'fastapi': base = fastapi.claudeMd(stack); break\n case 'express': base = express.claudeMd(stack); break\n case 'node': base = node.claudeMd(stack); break\n default: base = unknown.claudeMd(stack)\n }\n\n if (stackNotConfigured) {\n const firstNewline = base.indexOf('\\n')\n base = base.slice(0, firstNewline + 1) + STACK_NOT_CONFIGURED_WARNING + base.slice(firstNewline + 1)\n }\n\n if (!blueprintContent) return base\n\n const blueprintNote = '\\n> A PROJECT_BLUEPRINT.md is present — Claude Code will read it during Phase 0.\\n'\n\n const conventionsIdx = base.indexOf('\\n## Conventions')\n if (conventionsIdx !== -1) {\n return base.slice(0, conventionsIdx) + blueprintNote + base.slice(conventionsIdx)\n }\n return base + blueprintNote\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nexport function generateWorkflow(stack: StackInfo, blueprintContent?: string, projectName?: string): string {\n if (blueprintContent) return blueprintPlaceholder(projectName ?? stack.framework)\n\n switch (stack.framework) {\n case 'react': return react.workflow(stack)\n case 'nextjs': return nextjs.workflow(stack)\n case 'tauri': return tauri.workflow(stack)\n case 'fastapi': return fastapi.workflow(stack)\n case 'express': return express.workflow(stack)\n case 'node': return node.workflow(stack)\n default: return unknown.workflow(stack)\n }\n}\n\nfunction blueprintPlaceholder(projectName: string): string {\n return `# AGENT_WORKFLOW.md — ${projectName}\n\n> This file will be filled in by Claude Code during Phase 0.\n> Claude Code will read PROJECT_BLUEPRINT.md, propose a decomposition,\n> and replace this content after human validation.\n\n---\n\n*Waiting for Phase 0 decomposition...*\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport interface PlaybookInput {\n agents: Agent[]\n projectName: string\n hasBlueprint: boolean\n}\n\nexport function generatePlaybook({ agents, projectName, hasBlueprint }: PlaybookInput): string {\n const agentBlocks = agents.map((a) => agentBlock(a)).join('\\n---\\n\\n')\n\n const phase0 = hasBlueprint\n ? `## Phase 0 — Agent Decomposition (run this first)\n\n> A \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Claude Code reads it and decomposes the project into specialized agents\n> before writing a single line of code.\n\n**Read these files in order:**\n1. \\`CLAUDE.md\\`\n2. \\`PROJECT_BLUEPRINT.md\\`\n\n**Then decompose the project into agents** following these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n : `## Phase 0 — Project Discovery (run this first)\n\n> No \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Before writing any code, Claude Code asks the user what they want to build,\n> then decomposes the project into agents — exactly as if a blueprint had been provided.\n\n**Ask the user these questions and wait for their answers:**\n\n1. What is this project? (one sentence describing the goal)\n2. What are the main features you want to build? (list them)\n3. Are there any tech constraints or architecture preferences?\n (e.g. offline-only, specific DB, no auth, specific framework)\n\n**Once you have the answers, decompose the project into agents**\nfollowing these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n\n const betweenPhase = `## Between Phase 0 and Phase 1 — Skills Enrichment\n\nOnce the decomposition is validated, before writing any code:\n\n1. Create all agent folders and empty skills files:\n For each agent in your decomposition, create:\n - agents/agent-{N}-{slug}/skills.md (empty for now)\n\n2. Announce to the user:\n \"Agent folders created under agents/.\n\n You can now enrich any skills.md with additional context\n before I start executing:\n - API documentation\n - Database schemas\n - Algorithm references\n - Business conventions\n - Any project-specific knowledge\n\n Add .md files directly in the relevant agent folder —\n I will read everything in agents/agent-{N}-{slug}/ before\n starting that agent.\n\n Type 'proceed' (or any message) when you're ready\n and I'll start Phase 1.\"\n\n3. Wait for the user's message before starting Phase 1.\n Do not start Agent 1 until the user explicitly responds.\n\n---\n\n`\n\n return `# PLAYBOOK.md — ${projectName}\n\n> **One instruction to give Claude Code:**\n> \"Read PLAYBOOK.md and execute the procedure.\"\n>\n> Claude Code handles the rest autonomously — project discovery or blueprint reading,\n> agent decomposition, execution, success validation, retries, and human escalation.\n> No API key required. No additional cost beyond your LLM subscription.\n\n---\n\n## Global Execution Rules\n\nBefore each agent:\n1. Read \\`CLAUDE.md\\`\n2. Read \\`agents/agent-{N}-{slug}/skills.md\\` (current agent's file)\n3. Read the agent's section in \\`AGENT_WORKFLOW.md\\`\n\nAfter each agent:\n- Run the success criterion command\n- ✅ Passes → announce \"✅ Agent N complete\" and move to the next\n- ❌ Fails → analyze the root cause, fix, rerun (max 3 attempts)\n- After 3 consecutive failures → stop and ask for human validation\n\n**Never move to the next agent without a passing success criterion.**\n**Stay strictly within your current agent's defined scope.**\n\n---\n\n${phase0}${betweenPhase}## Phase 1 — Execution\n\n${agentBlocks}\n\n---\n\n## Future Iterations\n\nWhen a new agent is added via \\`agentkit add --feature <description>\\`:\n1. A new agent block is appended to \\`AGENT_WORKFLOW.md\\`\n2. The folder \\`agents/agent-{N}-{slug}/\\` is created with \\`skills.md\\`\n3. This \\`PLAYBOOK.md\\` is regenerated to include the new agent\n4. Execution resumes at the new agent only — completed agents are not rerun\n\nWhen you receive the instruction to continue after an iteration:\n> \"Read PLAYBOOK.md and execute only the agents that haven't been completed yet.\"\n\n---\n\n## Human Validation Required\n\nStop and wait for confirmation in these situations:\n- **3 consecutive failures** on the same success criterion\n- **Missing external dependency**: API key, env variable, unavailable service\n- **Conflict** between the detected stack and the user's stated constraints\n- **Destructive operation**: overwriting files not listed in deliverables\n- **End of Phase 0**: agent decomposition must be validated before execution\n`\n}\n\nfunction agentBlock(agent: Agent): string {\n const skillsPath = `agents/agent-${agent.number}-${agent.slug}/skills.md`\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (see skills.md for details)'\n\n return `### Agent ${agent.number} · ${agent.name}\n\n**Scope**: ${agent.scope}\n\n**Skills**: \\`${skillsPath}\\`\n\n**Deliverables**:\n${outputLines}\n\n**Success criterion**:\n\\`\\`\\`bash\n${agent.criterion || 'npm run build && npm test'}\n\\`\\`\\`\n\n**On failure**:\n1. Read the full error output\n2. Fix the root cause — not the symptoms\n3. Rerun the success criterion (max 3 attempts)\n4. After 3 failures → ask for human validation\n`\n}","import { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { Agent } from '../types/agent.js'\n\nexport async function generateSkills(agents: Agent[], outputDir: string): Promise<void> {\n for (const agent of agents) {\n const agentDir = join(outputDir, 'agents', `agent-${agent.number}-${agent.slug}`)\n await mkdir(agentDir, { recursive: true })\n await writeFile(join(agentDir, 'skills.md'), skillsMd(agent), 'utf-8')\n await writeFile(join(agentDir, 'context.md'), contextMd(agent), 'utf-8')\n }\n}\n\nfunction skillsMd(agent: Agent): string {\n return `# Skills — ${agent.fullName}\n\n> Ce fichier est lu par l'agent avant de commencer.\n\n## Contexte technique\n\n<!-- À remplir : bibliothèques, versions, décisions d'architecture spécifiques à cet agent -->\n\n## Documentation de référence\n\n<!-- À remplir : liens vers docs, exemples, ADRs pertinents -->\n\n## Conventions spécifiques\n\n<!-- À remplir : règles propres à cet agent (naming, patterns, structure de fichiers) -->\n`\n}\n\nfunction contextMd(agent: Agent): string {\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (voir AGENT_WORKFLOW.md)'\n\n return `# Context — ${agent.fullName}\n\n> Ce fichier fournit le contexte additionnel à l'agent avant exécution.\n> À compléter avant de lancer cet agent.\n\n## Périmètre\n\n${agent.scope}\n\n## Fichiers produits attendus\n\n${outputLines}\n\n## Critère de succès\n\n\\`${agent.criterion || 'npm run build && npm test'}\\`\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport function toSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[·•&]/g, ' ')\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nfunction getFieldValue(lines: string[], pattern: RegExp): string {\n for (const line of lines) {\n const m = line.match(pattern)\n if (m) return (m[1] ?? '').trim()\n }\n return ''\n}\n\nexport function extractAgentsFromWorkflow(content: string): Agent[] {\n const agents: Agent[] = []\n\n // Split into blocks starting with \"### Agent N\"\n const blocks = content\n .split(/(?=^### Agent \\d)/m)\n .filter((b) => /^### Agent \\d/.test(b.trimStart()))\n\n for (const block of blocks) {\n const lines = block.split('\\n')\n\n const headerMatch = lines[0].match(/^### Agent (\\d+)\\s*[·•]\\s*(.+)$/)\n if (!headerMatch) continue\n\n const number = parseInt(headerMatch[1], 10)\n const name = headerMatch[2].trim()\n const fullName = `Agent ${number} · ${name}`\n const slug = toSlug(name)\n\n const scope = getFieldValue(lines, /Périmètre\\s*:\\s*(.+)/)\n const criterion = getFieldValue(lines, /Critère[s]?\\s*:\\s*(.+)/)\n\n // Outputs: may be inline or multi-line (indented \"- item\")\n const outputs: string[] = []\n const produitIdx = lines.findIndex((l) => /Produit\\s*:/.test(l))\n if (produitIdx !== -1) {\n const inlineVal = (lines[produitIdx].match(/Produit\\s*:\\s*(.+)/)?.[1] ?? '').trim()\n if (inlineVal) {\n outputs.push(inlineVal)\n } else {\n for (let i = produitIdx + 1; i < lines.length; i++) {\n const line = lines[i]\n if (/^\\s+[-]/.test(line)) {\n outputs.push(line.trim().replace(/^-\\s*/, ''))\n } else if (line.trim() !== '' && !/^\\s/.test(line)) {\n break\n }\n }\n }\n }\n\n agents.push({ number, name, fullName, slug, scope, outputs, criterion })\n }\n\n return agents\n}\n","import chalk from 'chalk'\n\nexport const logger = {\n info: (message: string): void => {\n process.stdout.write(chalk.blue('ℹ') + ' ' + message + '\\n')\n },\n success: (message: string): void => {\n process.stdout.write(chalk.green('✔') + ' ' + message + '\\n')\n },\n warn: (message: string): void => {\n process.stdout.write(chalk.yellow('⚠') + ' ' + message + '\\n')\n },\n error: (message: string): void => {\n process.stderr.write(chalk.red('✖') + ' ' + message + '\\n')\n },\n}\n","import type { Command } from 'commander'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport { join, basename } from 'node:path'\nimport inquirer from 'inquirer'\nimport { logger } from '../utils/logger.js'\nimport { extractAgentsFromWorkflow, toSlug } from '../utils/agentParser.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport type { Agent } from '../types/agent.js'\n\nfunction featureToAgentName(description: string): string {\n const clean = description\n .replace(/^(add|implement|create|build|integrate|setup|configure|refactor|improve)\\s+/i, '')\n .trim()\n return clean.replace(/\\b\\w/g, (c) => c.toUpperCase())\n}\n\nexport interface AddFeatureResult {\n agent: Agent\n agentDirPath: string\n}\n\nexport async function addFeatureToProject(\n description: string,\n projectDir: string,\n): Promise<AddFeatureResult> {\n const workflowPath = join(projectDir, 'AGENT_WORKFLOW.md')\n const playbookPath = join(projectDir, 'PLAYBOOK.md')\n\n let workflowContent = ''\n try {\n workflowContent = await readFile(workflowPath, 'utf-8')\n } catch {\n throw new Error(`AGENT_WORKFLOW.md not found in ${projectDir} — run agentkit init first`)\n }\n\n const existingAgents = extractAgentsFromWorkflow(workflowContent)\n const nextNumber = existingAgents.length + 1\n const name = featureToAgentName(description)\n const slug = toSlug(name)\n const fullName = `Agent ${nextNumber} · ${name}`\n\n const newAgent: Agent = {\n number: nextNumber,\n name,\n fullName,\n slug,\n scope: description,\n outputs: [`agents/agent-${nextNumber}-${slug}/`],\n criterion: 'npm run build && npm test',\n }\n\n const agentBlock = `\n### ${fullName}\nPérimètre : ${description}\nProduit :\n - agents/agent-${nextNumber}-${slug}/\nCritère : npm run build && npm test\n`\n\n await writeFile(workflowPath, workflowContent + agentBlock, 'utf-8')\n await generateSkills([newAgent], projectDir)\n\n let projectName = basename(projectDir)\n try {\n const pkg = JSON.parse(\n await readFile(join(projectDir, 'package.json'), 'utf-8'),\n ) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* use dirname fallback */ }\n\n const allAgents = [...existingAgents, newAgent]\n\n // When adding a feature iteration, hasBlueprint is false —\n // Phase 0 decomposition only runs during the initial init with --blueprint.\n const playbookContent = generatePlaybook({\n agents: allAgents,\n projectName,\n hasBlueprint: false,\n })\n await writeFile(playbookPath, playbookContent, 'utf-8')\n\n return {\n agent: newAgent,\n agentDirPath: join(projectDir, 'agents', `agent-${nextNumber}-${slug}`),\n }\n}\n\nexport function registerAdd(program: Command): void {\n const addCmd = program\n .command('add')\n .description('Add resources to the agentkit project')\n .option('--feature <description>', 'Add an agent from a feature description and regenerate PLAYBOOK.md')\n .action(async (options: { feature?: string }) => {\n if (options.feature) {\n try {\n const result = await addFeatureToProject(options.feature, process.cwd())\n logger.success(`Agent added : ${result.agent.fullName}`)\n logger.success(`Folder created : agents/agent-${result.agent.number}-${result.agent.slug}/`)\n logger.success('PLAYBOOK.md : regenerated')\n } catch (err) {\n logger.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n } else {\n addCmd.help()\n }\n })\n\n addCmd\n .command('agent')\n .description('Add a new agent to AGENT_WORKFLOW.md (interactive)')\n .action(async () => {\n const cwd = process.cwd()\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n\n let existing = ''\n try {\n existing = await readFile(workflowPath, 'utf-8')\n } catch {\n logger.error('AGENT_WORKFLOW.md not found — run agentkit init first')\n process.exit(1)\n }\n\n const agentCount = (existing.match(/^### Agent \\d+/gm) ?? []).length\n const nextNumber = agentCount + 1\n\n const answers = await inquirer.prompt<{\n name: string\n scope: string\n outputs: string\n criterion: string\n }>([\n {\n type: 'input',\n name: 'name',\n message: `Agent name (e.g. \"Agent ${nextNumber} · Feature X\"):`,\n default: `Agent ${nextNumber}`,\n },\n {\n type: 'input',\n name: 'scope',\n message: 'Scope (one sentence):',\n },\n {\n type: 'input',\n name: 'outputs',\n message: 'Deliverables (comma-separated):',\n },\n {\n type: 'input',\n name: 'criterion',\n message: 'Success criterion:',\n },\n ])\n\n const outputLines = answers.outputs\n .split(',')\n .map((o: string) => ` - ${o.trim()}`)\n .join('\\n')\n\n const agentSection = `\n### ${answers.name}\nPérimètre : ${answers.scope}\nProduit :\n${outputLines}\nCritère : ${answers.criterion}\n`\n\n await writeFile(workflowPath, existing + agentSection, 'utf-8')\n logger.success(`Agent \"${answers.name}\" added to AGENT_WORKFLOW.md`)\n })\n}","import type { Command } from 'commander'\nimport { readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport chalk from 'chalk'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { logger } from '../utils/logger.js'\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Affiche l\\'état du workflow agentkit dans le dossier courant')\n .action(async () => {\n const cwd = process.cwd()\n\n const [stack, isGit, claudeMd, workflow] = await Promise.all([\n detectStack(cwd),\n isGitRepo(cwd),\n readFile(join(cwd, 'CLAUDE.md'), 'utf-8').catch(() => null),\n readFile(join(cwd, 'AGENT_WORKFLOW.md'), 'utf-8').catch(() => null),\n ])\n\n process.stdout.write('\\n' + chalk.bold('AgentKit Status') + '\\n')\n process.stdout.write('─'.repeat(40) + '\\n')\n\n process.stdout.write(\n chalk.bold('Git repo : ') +\n (isGit ? chalk.green('✔ oui') : chalk.red('✖ non')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('Stack : ') + chalk.cyan(stack.framework) + ' (' + stack.language + ')\\n',\n )\n\n process.stdout.write(\n chalk.bold('CLAUDE.md : ') +\n (claudeMd !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('AGENT_WORKFLOW.md : ') +\n (workflow !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n if (workflow !== null) {\n const agentMatches = workflow.match(/^### Agent \\d+/gm) ?? []\n process.stdout.write(\n chalk.bold('Agents définis : ') + chalk.cyan(String(agentMatches.length)) + '\\n',\n )\n }\n\n process.stdout.write('─'.repeat(40) + '\\n\\n')\n })\n}\n"],"mappings":"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","names":["import_promises","import_node_path","import_promises","import_node_path","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","import_promises","import_node_path","chalk","import_node_path","inquirer","program","ora","import_promises","import_node_path","import_inquirer","agentBlock","program","inquirer","import_promises","import_node_path","import_chalk","program","claudeMd","workflow","chalk"]}
|
package/dist/cli.js
CHANGED
|
@@ -662,6 +662,38 @@ Wait for confirmation before moving to Phase 1.
|
|
|
662
662
|
|
|
663
663
|
---
|
|
664
664
|
|
|
665
|
+
`;
|
|
666
|
+
const betweenPhase = `## Between Phase 0 and Phase 1 \u2014 Skills Enrichment
|
|
667
|
+
|
|
668
|
+
Once the decomposition is validated, before writing any code:
|
|
669
|
+
|
|
670
|
+
1. Create all agent folders and empty skills files:
|
|
671
|
+
For each agent in your decomposition, create:
|
|
672
|
+
- agents/agent-{N}-{slug}/skills.md (empty for now)
|
|
673
|
+
|
|
674
|
+
2. Announce to the user:
|
|
675
|
+
"Agent folders created under agents/.
|
|
676
|
+
|
|
677
|
+
You can now enrich any skills.md with additional context
|
|
678
|
+
before I start executing:
|
|
679
|
+
- API documentation
|
|
680
|
+
- Database schemas
|
|
681
|
+
- Algorithm references
|
|
682
|
+
- Business conventions
|
|
683
|
+
- Any project-specific knowledge
|
|
684
|
+
|
|
685
|
+
Add .md files directly in the relevant agent folder \u2014
|
|
686
|
+
I will read everything in agents/agent-{N}-{slug}/ before
|
|
687
|
+
starting that agent.
|
|
688
|
+
|
|
689
|
+
Type 'proceed' (or any message) when you're ready
|
|
690
|
+
and I'll start Phase 1."
|
|
691
|
+
|
|
692
|
+
3. Wait for the user's message before starting Phase 1.
|
|
693
|
+
Do not start Agent 1 until the user explicitly responds.
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
665
697
|
`;
|
|
666
698
|
return `# PLAYBOOK.md \u2014 ${projectName}
|
|
667
699
|
|
|
@@ -692,7 +724,7 @@ After each agent:
|
|
|
692
724
|
|
|
693
725
|
---
|
|
694
726
|
|
|
695
|
-
${phase0}## Phase 1 \u2014 Execution
|
|
727
|
+
${phase0}${betweenPhase}## Phase 1 \u2014 Execution
|
|
696
728
|
|
|
697
729
|
${agentBlocks}
|
|
698
730
|
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/detectors/stackDetector.ts","../src/detectors/gitDetector.ts","../src/templates/react.ts","../src/templates/nextjs.ts","../src/templates/tauri.ts","../src/templates/fastapi.ts","../src/templates/express.ts","../src/templates/node.ts","../src/templates/unknown.ts","../src/generators/claudeMdGenerator.ts","../src/generators/workflowGenerator.ts","../src/generators/playbookGenerator.ts","../src/generators/skillsGenerator.ts","../src/utils/agentParser.ts","../src/utils/logger.ts","../src/commands/add.ts","../src/commands/status.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander'\nimport { registerInit } from './commands/init.js'\nimport { registerAdd } from './commands/add.js'\nimport { registerStatus } from './commands/status.js'\n\nconst program = new Command()\n\nprogram\n .name('agentkit')\n .description('Scaffolder des workflows multi-agents Claude Code')\n .version('0.1.0')\n\nregisterInit(program)\nregisterAdd(program)\nregisterStatus(program)\n\nprogram.parse()\n","import type { Command } from 'commander'\nimport { writeFile, readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport inquirer from 'inquirer'\nimport ora from 'ora'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { generateClaudeMd } from '../generators/claudeMdGenerator.js'\nimport { generateWorkflow } from '../generators/workflowGenerator.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport { extractAgentsFromWorkflow } from '../utils/agentParser.js'\nimport { logger } from '../utils/logger.js'\nimport type { StackInfo } from '../detectors/stackDetector.js'\nimport { basename } from 'node:path'\n\nconst FRAMEWORK_LABELS: Record<StackInfo['framework'], string> = {\n react: 'React',\n nextjs: 'Next.js',\n tauri: 'Tauri',\n fastapi: 'FastAPI (Python)',\n express: 'Express',\n node: 'Node.js',\n unknown: 'Unknown (generic)',\n}\n\nconst STACK_CHOICES = [\n { name: 'React + Vite', value: 'react' },\n { name: 'Next.js', value: 'nextjs' },\n { name: 'Tauri v2 (React + Rust)', value: 'tauri' },\n { name: 'FastAPI (Python)', value: 'fastapi' },\n { name: 'Express (Node.js)', value: 'express' },\n { name: 'Node.js (generic)', value: 'node' },\n { name: 'None of the above — generate a generic CLAUDE.md to fill manually', value: 'none' },\n]\n\nexport async function resolveStack(\n detected: StackInfo,\n): Promise<{ stack: StackInfo; stackNotConfigured: boolean }> {\n if (detected.framework !== 'unknown') {\n return { stack: detected, stackNotConfigured: false }\n }\n\n logger.warn('Stack not detected automatically.')\n const { selectedFramework } = await inquirer.prompt<{ selectedFramework: string }>([\n {\n type: 'list',\n name: 'selectedFramework',\n message: 'Stack not detected automatically. Please select your stack:',\n choices: STACK_CHOICES as unknown as string[],\n },\n ])\n\n if (selectedFramework === 'none') {\n return { stack: detected, stackNotConfigured: true }\n }\n\n const framework = selectedFramework as StackInfo['framework']\n const hasTypeScript = ['react', 'nextjs', 'tauri'].includes(framework)\n const language: StackInfo['language'] = framework === 'fastapi' ? 'python' : hasTypeScript ? 'typescript' : 'javascript'\n return {\n stack: { ...detected, framework, language, hasTypeScript },\n stackNotConfigured: false,\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path)\n return true\n } catch {\n return false\n }\n}\n\nexport function registerInit(program: Command): void {\n program\n .command('init')\n .description('Génère CLAUDE.md et AGENT_WORKFLOW.md dans le dossier courant')\n .option('-f, --force', 'Écrase les fichiers existants sans confirmation')\n .option('--blueprint <path>', 'Fichier blueprint .md à utiliser pour personnaliser les fichiers générés')\n .action(async (options: { force?: boolean; blueprint?: string }) => {\n const cwd = process.cwd()\n\n const spinner = ora('Détection de la stack…').start()\n const [stack, isGit] = await Promise.all([detectStack(cwd), isGitRepo(cwd)])\n spinner.stop()\n\n if (!isGit) {\n logger.warn('Ce dossier n\\'est pas un repo git — lancez git init si nécessaire')\n }\n\n const { stack: resolvedStack, stackNotConfigured } = await resolveStack(stack)\n\n const label = FRAMEWORK_LABELS[resolvedStack.framework]\n logger.info(`Stack : ${label} (${resolvedStack.language})`)\n\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message: `Générer les fichiers pour ${label} ?`,\n default: true,\n },\n ])\n\n if (!confirmed) {\n logger.warn('Annulé.')\n return\n }\n\n const claudeMdPath = join(cwd, 'CLAUDE.md')\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n const playbookPath = join(cwd, 'PLAYBOOK.md')\n\n // Resolve project name from package.json or directory name\n let projectName = basename(cwd)\n try {\n const pkg = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf-8')) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* fallback to dirname */ }\n\n if (!options.force) {\n const existing: string[] = []\n if (await fileExists(claudeMdPath)) existing.push('CLAUDE.md')\n if (await fileExists(workflowPath)) existing.push('AGENT_WORKFLOW.md')\n if (await fileExists(playbookPath)) existing.push('PLAYBOOK.md')\n\n if (existing.length > 0) {\n const { overwrite } = await inquirer.prompt<{ overwrite: boolean }>([\n {\n type: 'confirm',\n name: 'overwrite',\n message: `${existing.join(' et ')} existe déjà. Écraser ?`,\n default: false,\n },\n ])\n if (!overwrite) {\n logger.warn('Annulé.')\n return\n }\n }\n }\n\n // Load blueprint if provided\n let blueprintContent: string | undefined\n if (options.blueprint) {\n try {\n blueprintContent = await readFile(options.blueprint, 'utf-8')\n } catch {\n logger.error(`Blueprint introuvable : ${options.blueprint}`)\n process.exit(1)\n }\n }\n\n const genSpinner = ora('Génération des fichiers…').start()\n const claudeMdContent = generateClaudeMd(resolvedStack, blueprintContent, stackNotConfigured)\n const workflowContent = generateWorkflow(resolvedStack, blueprintContent, projectName)\n const agents = extractAgentsFromWorkflow(workflowContent)\n const playbookContent = generatePlaybook({ agents, projectName, hasBlueprint: !!blueprintContent })\n await writeFile(claudeMdPath, claudeMdContent, 'utf-8')\n await writeFile(workflowPath, workflowContent, 'utf-8')\n await writeFile(playbookPath, playbookContent, 'utf-8')\n await generateSkills(agents, cwd)\n genSpinner.succeed('Fichiers générés')\n\n logger.success('CLAUDE.md → créé')\n logger.success('AGENT_WORKFLOW.md → créé')\n logger.success('PLAYBOOK.md → créé')\n logger.success(`agents/ → ${agents.length} dossier(s) créé(s)`)\n })\n}\n","import { readFile, access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface StackInfo {\n framework: 'react' | 'nextjs' | 'tauri' | 'fastapi' | 'express' | 'node' | 'unknown'\n language: 'typescript' | 'javascript' | 'python' | 'unknown'\n hasTypeScript: boolean\n extras: string[]\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch {\n return false\n }\n}\n\nasync function readJson(p: string): Promise<Record<string, unknown> | null> {\n try {\n const raw = await readFile(p, 'utf-8')\n return JSON.parse(raw) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\nasync function readText(p: string): Promise<string | null> {\n try {\n return await readFile(p, 'utf-8')\n } catch {\n return null\n }\n}\n\nexport async function detectStack(projectPath: string): Promise<StackInfo> {\n const info: StackInfo = {\n framework: 'unknown',\n language: 'unknown',\n hasTypeScript: false,\n extras: [],\n }\n\n const packageJson = await readJson(join(projectPath, 'package.json'))\n const requirementsTxt = await readText(join(projectPath, 'requirements.txt'))\n const hasTauriDir = await pathExists(join(projectPath, 'src-tauri'))\n const hasTsConfig = await pathExists(join(projectPath, 'tsconfig.json'))\n\n if (packageJson !== null) {\n const deps = (packageJson.dependencies as Record<string, string>) ?? {}\n const devDeps = (packageJson.devDependencies as Record<string, string>) ?? {}\n const allDeps = { ...deps, ...devDeps }\n\n info.hasTypeScript = 'typescript' in allDeps || hasTsConfig\n info.language = info.hasTypeScript ? 'typescript' : 'javascript'\n\n // Order matters: most specific first\n if ('next' in allDeps) {\n info.framework = 'nextjs'\n } else if (hasTauriDir || '@tauri-apps/api' in allDeps || '@tauri-apps/cli' in allDeps) {\n info.framework = 'tauri'\n } else if ('react' in allDeps) {\n info.framework = 'react'\n } else if ('express' in allDeps) {\n info.framework = 'express'\n } else {\n info.framework = 'node'\n }\n\n if ('vitest' in allDeps || 'jest' in allDeps) info.extras.push('testing')\n if ('prisma' in allDeps || '@prisma/client' in allDeps) info.extras.push('prisma')\n if ('tailwindcss' in allDeps) info.extras.push('tailwind')\n }\n\n if (requirementsTxt !== null && info.framework === 'unknown') {\n info.language = 'python'\n if (/\\bfastapi\\b/i.test(requirementsTxt)) {\n info.framework = 'fastapi'\n }\n }\n\n if (hasTauriDir && info.framework === 'unknown') {\n info.framework = 'tauri'\n }\n\n return info\n}\n","import { access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport async function isGitRepo(projectPath: string): Promise<boolean> {\n try {\n await access(join(projectPath, '.git'))\n return true\n } catch {\n return false\n }\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const testLine = stack.extras.includes('testing') ? '- `npm test` — run tests\\n' : ''\n return `# CLAUDE.md — React Project\n\n## Stack\n- Framework : React (${lang})\n- Language : ${lang}\n- Build : Vite\n\n## Commands\n- \\`npm run dev\\` — development server\n- \\`npm run build\\` — production build\n${testLine}\n## Structure\nsrc/\n components/ ← UI components (PascalCase)\n hooks/ ← custom hooks (prefix: use*)\n pages/ ← page-level components\n utils/ ← shared helpers\n\n## Conventions\n1. Components in PascalCase\n2. Hooks prefixed with \\`use\\`\n3. Props interfaces named \\`*Props\\`\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — React Project\n\n## Stack détectée\nFramework: React | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Components\nPérimètre : composants UI réutilisables\nProduit : src/components/\nCritère : composants documentés et testés\n\n### Agent 2 · State & Hooks\nPérimètre : state management, hooks personnalisés\nProduit : src/hooks/\nCritère : hooks testés unitairement\n\n### Agent 3 · Pages & Routing\nPérimètre : assemblage des pages, react-router\nProduit : src/pages/\nCritère : navigation fonctionnelle\n\n### Agent 4 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const hasTailwind = stack.extras.includes('tailwind')\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Next.js Project\n\n## Stack\n- Framework : Next.js (TypeScript)\n- Rendering : App Router (RSC + Client Components)\n- Styling : ${hasTailwind ? 'Tailwind CSS' : 'CSS Modules'}\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (http://localhost:3000)\n- \\`npm run build\\` — production build\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n app/ ← App Router pages and layouts\n components/ ← shared UI components\n lib/ ← server utilities, db clients\n utils/ ← shared helpers\n\n## Conventions\n1. Server Components by default, \\`'use client'\\` only when needed\n2. API routes in \\`src/app/api/\\`\n3. Environment variables via \\`src/env.ts\\` (validated)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const hasPrisma = stack.extras.includes('prisma')\n return `# Agent Workflow — Next.js Project\n\n## Stack détectée\nFramework: Next.js | Language: TypeScript\n\n## Agents\n\n### Agent 1 · Data Layer\nPérimètre : schéma${hasPrisma ? ' Prisma' : ''}, types, server actions\nProduit : src/lib/, ${hasPrisma ? 'prisma/schema.prisma' : 'src/types/'}\nCritère : types compilent, migrations propres\n\n### Agent 2 · UI Components\nPérimètre : composants réutilisables (Server + Client)\nProduit : src/components/\nCritère : composants rendus sans erreur\n\n### Agent 3 · Pages & Layout\nPérimètre : App Router, layouts, pages\nProduit : src/app/\nCritère : navigation fonctionnelle, build passe\n\n### Agent 4 · API & Tests\nPérimètre : API routes, tests e2e/unitaires\nProduit : src/app/api/, tests/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Tauri Project\n\n## Stack\n- Framework : Tauri (Rust + ${lang} frontend)\n- Language : Rust (backend) + ${lang} (frontend)\n- Build : Cargo + Vite\n\n## Commands\n- \\`npm run tauri:dev\\` — development (hot reload)\n- \\`npm run tauri:build\\` — production bundle\n- \\`npm run dev\\` — frontend only\n- \\`npx tsc --noEmit\\` — type check\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/ ← frontend (${lang})\n components/\n utils/\nsrc-tauri/ ← Rust backend\n src/\n main.rs ← Tauri entry point\n commands.rs ← Tauri commands (IPC)\n tauri.conf.json\n\n## Conventions\n1. IPC commands defined in \\`src-tauri/src/commands.rs\\`\n2. Frontend invokes via \\`@tauri-apps/api/tauri\\`\n3. No direct filesystem access from frontend\n4. All console output goes through a centralized logger\n5. Always use \\`isTauri()\\` before any Tauri plugin call\n6. All Tauri plugin imports must be dynamic (never top-level)\n7. Every Tauri plugin call must have a browser fallback\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Tauri Project\n\n## Stack détectée\nFramework: Tauri | Language: Rust + ${lang}\n\n## Agents\n\n### Agent 1 · Rust Commands\nPérimètre : commandes Tauri (IPC), permissions\nProduit : src-tauri/src/commands.rs, tauri.conf.json\nCritère : \\`cargo build\\` passe\n\n### Agent 2 · Frontend UI\nPérimètre : interface ${lang}, intégration IPC\nProduit : src/components/, src/utils/\nCritère : appels IPC fonctionnels\n\n### Agent 3 · Build & Packaging\nPérimètre : configuration build, icônes, installeurs\nProduit : src-tauri/tauri.conf.json, icons/\nCritère : \\`npm run tauri build\\` produit un bundle\n\n### Agent 4 · Tests\nPérimètre : tests Rust + tests frontend\nProduit : src-tauri/tests/, tests/\nCritère : \\`cargo test\\` + \\`npm test\\` passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md — FastAPI Project\n\n## Stack\n- Framework : FastAPI (Python)\n- Language : Python 3.11+\n- Server : Uvicorn\n- Validation: Pydantic v2\n\n## Commands\n- \\`uvicorn main:app --reload\\` — development server (http://localhost:8000)\n- \\`pytest\\` — run tests\n- \\`pip install -r requirements.txt\\` — install dependencies\n\n## Structure\napp/\n main.py ← FastAPI app entry point\n routers/ ← API route groups\n models/ ← Pydantic models\n services/ ← business logic\n dependencies/ ← FastAPI dependencies (DI)\ntests/ ← pytest tests\n\n## Conventions\n1. Routers grouped by domain in \\`app/routers/\\`\n2. Pydantic models for all request/response bodies\n3. Business logic in \\`app/services/\\`, not in routes\n4. Async endpoints by default (\\`async def\\`)\n5. Environment variables via \\`python-dotenv\\` + \\`pydantic-settings\\`\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow — FastAPI Project\n\n## Stack détectée\nFramework: FastAPI | Language: Python\n\n## Agents\n\n### Agent 1 · Models & Schemas\nPérimètre : modèles Pydantic, schémas DB (SQLAlchemy/SQLModel)\nProduit : app/models/\nCritère : modèles validés, migrations propres\n\n### Agent 2 · Services\nPérimètre : logique métier, accès base de données\nProduit : app/services/\nCritère : services testés unitairement (pytest)\n\n### Agent 3 · Routers & API\nPérimètre : routes FastAPI, dépendances, auth\nProduit : app/routers/, app/dependencies/\nCritère : endpoints documentés (OpenAPI), tests d'intégration\n\n### Agent 4 · Tests & CI\nPérimètre : couverture pytest, configuration CI\nProduit : tests/, .github/workflows/\nCritère : \\`pytest\\` passe à 100%\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Express Project\n\n## Stack\n- Framework : Express (${lang})\n- Language : ${lang}\n- Runtime : Node.js 20+\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (nodemon)\n- \\`npm run build\\` — compile TypeScript\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n routes/ ← Express routers (one per domain)\n controllers/ ← request handlers\n services/ ← business logic\n middleware/ ← Express middleware\n utils/ ← shared helpers\n\n## Conventions\n1. Routes grouped by domain in \\`src/routes/\\`\n2. Business logic in \\`src/services/\\`, not in controllers\n3. Middleware for cross-cutting concerns (auth, validation)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Express Project\n\n## Stack détectée\nFramework: Express | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Data & Models\nPérimètre : modèles de données, accès DB\nProduit : src/models/, src/services/db.ts\nCritère : connexion DB fonctionnelle\n\n### Agent 2 · Services\nPérimètre : logique métier\nProduit : src/services/\nCritère : services testés unitairement\n\n### Agent 3 · Routes & Controllers\nPérimètre : routes Express, validation, auth\nProduit : src/routes/, src/controllers/, src/middleware/\nCritère : endpoints répondent correctement\n\n### Agent 4 · Tests & CI\nPérimètre : tests d'intégration, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Node.js Project\n\n## Stack\n- Runtime : Node.js 20+\n- Language : ${lang}\n\n## Commands\n- \\`npm run dev\\` — development (with watch)\n- \\`npm run build\\` — compile${stack.hasTypeScript ? ' TypeScript' : ''}\n- \\`npm start\\` — run production build\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n index.ts ← entry point\n lib/ ← core library code\n utils/ ← shared helpers\n\n## Conventions\n1. Modules follow single-responsibility principle\n2. Async/await over callbacks\n3. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Node.js Project\n\n## Stack détectée\nRuntime: Node.js | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Core Library\nPérimètre : logique principale\nProduit : src/lib/\nCritère : module fonctionne et testé\n\n### Agent 2 · CLI / API\nPérimètre : interface utilisateur (CLI ou API)\nProduit : src/index.ts, src/cli.ts\nCritère : commandes fonctionnelles\n\n### Agent 3 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md\n\n## Stack\nStack non détectée automatiquement — à remplir manuellement.\n\n## Commands\n- À définir selon le projet\n\n## Structure\nsrc/ ← code source\ntests/ ← tests\n\n## Conventions\n1. Tout output console passe par un logger centralisé\n2. À compléter selon les conventions du projet\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow\n\n## Stack détectée\nStack inconnue — workflow générique.\n\n## Agents\n\n### Agent 1 · Setup\nPérimètre : configuration initiale du projet\nProduit : structure de base\nCritère : projet compilable\n\n### Agent 2 · Core\nPérimètre : logique principale\nProduit : src/\nCritère : fonctionnalités principales opérationnelles\n\n### Agent 3 · Tests\nPérimètre : couverture de tests\nProduit : tests/\nCritère : tests passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nconst STACK_NOT_CONFIGURED_WARNING = `\n## ⚠️ Stack not configured\nAgentKit could not detect your stack and no stack was selected.\nBefore running Claude Code, fill in the following sections:\n- Stack (framework, runtime, DB, tools)\n- Commands (dev, build, test)\n- Structure (folder layout)\n\nOnce filled, give Claude Code this instruction:\n\"Read PLAYBOOK.md and execute the procedure.\"\n`\n\nexport function generateClaudeMd(stack: StackInfo, blueprintContent?: string, stackNotConfigured?: boolean): string {\n let base: string\n switch (stack.framework) {\n case 'react': base = react.claudeMd(stack); break\n case 'nextjs': base = nextjs.claudeMd(stack); break\n case 'tauri': base = tauri.claudeMd(stack); break\n case 'fastapi': base = fastapi.claudeMd(stack); break\n case 'express': base = express.claudeMd(stack); break\n case 'node': base = node.claudeMd(stack); break\n default: base = unknown.claudeMd(stack)\n }\n\n if (stackNotConfigured) {\n const firstNewline = base.indexOf('\\n')\n base = base.slice(0, firstNewline + 1) + STACK_NOT_CONFIGURED_WARNING + base.slice(firstNewline + 1)\n }\n\n if (!blueprintContent) return base\n\n const blueprintNote = '\\n> A PROJECT_BLUEPRINT.md is present — Claude Code will read it during Phase 0.\\n'\n\n const conventionsIdx = base.indexOf('\\n## Conventions')\n if (conventionsIdx !== -1) {\n return base.slice(0, conventionsIdx) + blueprintNote + base.slice(conventionsIdx)\n }\n return base + blueprintNote\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nexport function generateWorkflow(stack: StackInfo, blueprintContent?: string, projectName?: string): string {\n if (blueprintContent) return blueprintPlaceholder(projectName ?? stack.framework)\n\n switch (stack.framework) {\n case 'react': return react.workflow(stack)\n case 'nextjs': return nextjs.workflow(stack)\n case 'tauri': return tauri.workflow(stack)\n case 'fastapi': return fastapi.workflow(stack)\n case 'express': return express.workflow(stack)\n case 'node': return node.workflow(stack)\n default: return unknown.workflow(stack)\n }\n}\n\nfunction blueprintPlaceholder(projectName: string): string {\n return `# AGENT_WORKFLOW.md — ${projectName}\n\n> This file will be filled in by Claude Code during Phase 0.\n> Claude Code will read PROJECT_BLUEPRINT.md, propose a decomposition,\n> and replace this content after human validation.\n\n---\n\n*Waiting for Phase 0 decomposition...*\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport interface PlaybookInput {\n agents: Agent[]\n projectName: string\n hasBlueprint: boolean\n}\n\nexport function generatePlaybook({ agents, projectName, hasBlueprint }: PlaybookInput): string {\n const agentBlocks = agents.map((a) => agentBlock(a)).join('\\n---\\n\\n')\n\n const phase0 = hasBlueprint\n ? `## Phase 0 — Agent Decomposition (run this first)\n\n> A \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Claude Code reads it and decomposes the project into specialized agents\n> before writing a single line of code.\n\n**Read these files in order:**\n1. \\`CLAUDE.md\\`\n2. \\`PROJECT_BLUEPRINT.md\\`\n\n**Then decompose the project into agents** following these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n : `## Phase 0 — Project Discovery (run this first)\n\n> No \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Before writing any code, Claude Code asks the user what they want to build,\n> then decomposes the project into agents — exactly as if a blueprint had been provided.\n\n**Ask the user these questions and wait for their answers:**\n\n1. What is this project? (one sentence describing the goal)\n2. What are the main features you want to build? (list them)\n3. Are there any tech constraints or architecture preferences?\n (e.g. offline-only, specific DB, no auth, specific framework)\n\n**Once you have the answers, decompose the project into agents**\nfollowing these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n\n return `# PLAYBOOK.md — ${projectName}\n\n> **One instruction to give Claude Code:**\n> \"Read PLAYBOOK.md and execute the procedure.\"\n>\n> Claude Code handles the rest autonomously — project discovery or blueprint reading,\n> agent decomposition, execution, success validation, retries, and human escalation.\n> No API key required. No additional cost beyond your LLM subscription.\n\n---\n\n## Global Execution Rules\n\nBefore each agent:\n1. Read \\`CLAUDE.md\\`\n2. Read \\`agents/agent-{N}-{slug}/skills.md\\` (current agent's file)\n3. Read the agent's section in \\`AGENT_WORKFLOW.md\\`\n\nAfter each agent:\n- Run the success criterion command\n- ✅ Passes → announce \"✅ Agent N complete\" and move to the next\n- ❌ Fails → analyze the root cause, fix, rerun (max 3 attempts)\n- After 3 consecutive failures → stop and ask for human validation\n\n**Never move to the next agent without a passing success criterion.**\n**Stay strictly within your current agent's defined scope.**\n\n---\n\n${phase0}## Phase 1 — Execution\n\n${agentBlocks}\n\n---\n\n## Future Iterations\n\nWhen a new agent is added via \\`agentkit add --feature <description>\\`:\n1. A new agent block is appended to \\`AGENT_WORKFLOW.md\\`\n2. The folder \\`agents/agent-{N}-{slug}/\\` is created with \\`skills.md\\`\n3. This \\`PLAYBOOK.md\\` is regenerated to include the new agent\n4. Execution resumes at the new agent only — completed agents are not rerun\n\nWhen you receive the instruction to continue after an iteration:\n> \"Read PLAYBOOK.md and execute only the agents that haven't been completed yet.\"\n\n---\n\n## Human Validation Required\n\nStop and wait for confirmation in these situations:\n- **3 consecutive failures** on the same success criterion\n- **Missing external dependency**: API key, env variable, unavailable service\n- **Conflict** between the detected stack and the user's stated constraints\n- **Destructive operation**: overwriting files not listed in deliverables\n- **End of Phase 0**: agent decomposition must be validated before execution\n`\n}\n\nfunction agentBlock(agent: Agent): string {\n const skillsPath = `agents/agent-${agent.number}-${agent.slug}/skills.md`\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (see skills.md for details)'\n\n return `### Agent ${agent.number} · ${agent.name}\n\n**Scope**: ${agent.scope}\n\n**Skills**: \\`${skillsPath}\\`\n\n**Deliverables**:\n${outputLines}\n\n**Success criterion**:\n\\`\\`\\`bash\n${agent.criterion || 'npm run build && npm test'}\n\\`\\`\\`\n\n**On failure**:\n1. Read the full error output\n2. Fix the root cause — not the symptoms\n3. Rerun the success criterion (max 3 attempts)\n4. After 3 failures → ask for human validation\n`\n}","import { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { Agent } from '../types/agent.js'\n\nexport async function generateSkills(agents: Agent[], outputDir: string): Promise<void> {\n for (const agent of agents) {\n const agentDir = join(outputDir, 'agents', `agent-${agent.number}-${agent.slug}`)\n await mkdir(agentDir, { recursive: true })\n await writeFile(join(agentDir, 'skills.md'), skillsMd(agent), 'utf-8')\n await writeFile(join(agentDir, 'context.md'), contextMd(agent), 'utf-8')\n }\n}\n\nfunction skillsMd(agent: Agent): string {\n return `# Skills — ${agent.fullName}\n\n> Ce fichier est lu par l'agent avant de commencer.\n\n## Contexte technique\n\n<!-- À remplir : bibliothèques, versions, décisions d'architecture spécifiques à cet agent -->\n\n## Documentation de référence\n\n<!-- À remplir : liens vers docs, exemples, ADRs pertinents -->\n\n## Conventions spécifiques\n\n<!-- À remplir : règles propres à cet agent (naming, patterns, structure de fichiers) -->\n`\n}\n\nfunction contextMd(agent: Agent): string {\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (voir AGENT_WORKFLOW.md)'\n\n return `# Context — ${agent.fullName}\n\n> Ce fichier fournit le contexte additionnel à l'agent avant exécution.\n> À compléter avant de lancer cet agent.\n\n## Périmètre\n\n${agent.scope}\n\n## Fichiers produits attendus\n\n${outputLines}\n\n## Critère de succès\n\n\\`${agent.criterion || 'npm run build && npm test'}\\`\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport function toSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[·•&]/g, ' ')\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nfunction getFieldValue(lines: string[], pattern: RegExp): string {\n for (const line of lines) {\n const m = line.match(pattern)\n if (m) return (m[1] ?? '').trim()\n }\n return ''\n}\n\nexport function extractAgentsFromWorkflow(content: string): Agent[] {\n const agents: Agent[] = []\n\n // Split into blocks starting with \"### Agent N\"\n const blocks = content\n .split(/(?=^### Agent \\d)/m)\n .filter((b) => /^### Agent \\d/.test(b.trimStart()))\n\n for (const block of blocks) {\n const lines = block.split('\\n')\n\n const headerMatch = lines[0].match(/^### Agent (\\d+)\\s*[·•]\\s*(.+)$/)\n if (!headerMatch) continue\n\n const number = parseInt(headerMatch[1], 10)\n const name = headerMatch[2].trim()\n const fullName = `Agent ${number} · ${name}`\n const slug = toSlug(name)\n\n const scope = getFieldValue(lines, /Périmètre\\s*:\\s*(.+)/)\n const criterion = getFieldValue(lines, /Critère[s]?\\s*:\\s*(.+)/)\n\n // Outputs: may be inline or multi-line (indented \"- item\")\n const outputs: string[] = []\n const produitIdx = lines.findIndex((l) => /Produit\\s*:/.test(l))\n if (produitIdx !== -1) {\n const inlineVal = (lines[produitIdx].match(/Produit\\s*:\\s*(.+)/)?.[1] ?? '').trim()\n if (inlineVal) {\n outputs.push(inlineVal)\n } else {\n for (let i = produitIdx + 1; i < lines.length; i++) {\n const line = lines[i]\n if (/^\\s+[-]/.test(line)) {\n outputs.push(line.trim().replace(/^-\\s*/, ''))\n } else if (line.trim() !== '' && !/^\\s/.test(line)) {\n break\n }\n }\n }\n }\n\n agents.push({ number, name, fullName, slug, scope, outputs, criterion })\n }\n\n return agents\n}\n","import chalk from 'chalk'\n\nexport const logger = {\n info: (message: string): void => {\n process.stdout.write(chalk.blue('ℹ') + ' ' + message + '\\n')\n },\n success: (message: string): void => {\n process.stdout.write(chalk.green('✔') + ' ' + message + '\\n')\n },\n warn: (message: string): void => {\n process.stdout.write(chalk.yellow('⚠') + ' ' + message + '\\n')\n },\n error: (message: string): void => {\n process.stderr.write(chalk.red('✖') + ' ' + message + '\\n')\n },\n}\n","import type { Command } from 'commander'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport { join, basename } from 'node:path'\nimport inquirer from 'inquirer'\nimport { logger } from '../utils/logger.js'\nimport { extractAgentsFromWorkflow, toSlug } from '../utils/agentParser.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport type { Agent } from '../types/agent.js'\n\nfunction featureToAgentName(description: string): string {\n const clean = description\n .replace(/^(add|implement|create|build|integrate|setup|configure|refactor|improve)\\s+/i, '')\n .trim()\n return clean.replace(/\\b\\w/g, (c) => c.toUpperCase())\n}\n\nexport interface AddFeatureResult {\n agent: Agent\n agentDirPath: string\n}\n\nexport async function addFeatureToProject(\n description: string,\n projectDir: string,\n): Promise<AddFeatureResult> {\n const workflowPath = join(projectDir, 'AGENT_WORKFLOW.md')\n const playbookPath = join(projectDir, 'PLAYBOOK.md')\n\n let workflowContent = ''\n try {\n workflowContent = await readFile(workflowPath, 'utf-8')\n } catch {\n throw new Error(`AGENT_WORKFLOW.md not found in ${projectDir} — run agentkit init first`)\n }\n\n const existingAgents = extractAgentsFromWorkflow(workflowContent)\n const nextNumber = existingAgents.length + 1\n const name = featureToAgentName(description)\n const slug = toSlug(name)\n const fullName = `Agent ${nextNumber} · ${name}`\n\n const newAgent: Agent = {\n number: nextNumber,\n name,\n fullName,\n slug,\n scope: description,\n outputs: [`agents/agent-${nextNumber}-${slug}/`],\n criterion: 'npm run build && npm test',\n }\n\n const agentBlock = `\n### ${fullName}\nPérimètre : ${description}\nProduit :\n - agents/agent-${nextNumber}-${slug}/\nCritère : npm run build && npm test\n`\n\n await writeFile(workflowPath, workflowContent + agentBlock, 'utf-8')\n await generateSkills([newAgent], projectDir)\n\n let projectName = basename(projectDir)\n try {\n const pkg = JSON.parse(\n await readFile(join(projectDir, 'package.json'), 'utf-8'),\n ) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* use dirname fallback */ }\n\n const allAgents = [...existingAgents, newAgent]\n\n // When adding a feature iteration, hasBlueprint is false —\n // Phase 0 decomposition only runs during the initial init with --blueprint.\n const playbookContent = generatePlaybook({\n agents: allAgents,\n projectName,\n hasBlueprint: false,\n })\n await writeFile(playbookPath, playbookContent, 'utf-8')\n\n return {\n agent: newAgent,\n agentDirPath: join(projectDir, 'agents', `agent-${nextNumber}-${slug}`),\n }\n}\n\nexport function registerAdd(program: Command): void {\n const addCmd = program\n .command('add')\n .description('Add resources to the agentkit project')\n .option('--feature <description>', 'Add an agent from a feature description and regenerate PLAYBOOK.md')\n .action(async (options: { feature?: string }) => {\n if (options.feature) {\n try {\n const result = await addFeatureToProject(options.feature, process.cwd())\n logger.success(`Agent added : ${result.agent.fullName}`)\n logger.success(`Folder created : agents/agent-${result.agent.number}-${result.agent.slug}/`)\n logger.success('PLAYBOOK.md : regenerated')\n } catch (err) {\n logger.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n } else {\n addCmd.help()\n }\n })\n\n addCmd\n .command('agent')\n .description('Add a new agent to AGENT_WORKFLOW.md (interactive)')\n .action(async () => {\n const cwd = process.cwd()\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n\n let existing = ''\n try {\n existing = await readFile(workflowPath, 'utf-8')\n } catch {\n logger.error('AGENT_WORKFLOW.md not found — run agentkit init first')\n process.exit(1)\n }\n\n const agentCount = (existing.match(/^### Agent \\d+/gm) ?? []).length\n const nextNumber = agentCount + 1\n\n const answers = await inquirer.prompt<{\n name: string\n scope: string\n outputs: string\n criterion: string\n }>([\n {\n type: 'input',\n name: 'name',\n message: `Agent name (e.g. \"Agent ${nextNumber} · Feature X\"):`,\n default: `Agent ${nextNumber}`,\n },\n {\n type: 'input',\n name: 'scope',\n message: 'Scope (one sentence):',\n },\n {\n type: 'input',\n name: 'outputs',\n message: 'Deliverables (comma-separated):',\n },\n {\n type: 'input',\n name: 'criterion',\n message: 'Success criterion:',\n },\n ])\n\n const outputLines = answers.outputs\n .split(',')\n .map((o: string) => ` - ${o.trim()}`)\n .join('\\n')\n\n const agentSection = `\n### ${answers.name}\nPérimètre : ${answers.scope}\nProduit :\n${outputLines}\nCritère : ${answers.criterion}\n`\n\n await writeFile(workflowPath, existing + agentSection, 'utf-8')\n logger.success(`Agent \"${answers.name}\" added to AGENT_WORKFLOW.md`)\n })\n}","import type { Command } from 'commander'\nimport { readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport chalk from 'chalk'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { logger } from '../utils/logger.js'\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Affiche l\\'état du workflow agentkit dans le dossier courant')\n .action(async () => {\n const cwd = process.cwd()\n\n const [stack, isGit, claudeMd, workflow] = await Promise.all([\n detectStack(cwd),\n isGitRepo(cwd),\n readFile(join(cwd, 'CLAUDE.md'), 'utf-8').catch(() => null),\n readFile(join(cwd, 'AGENT_WORKFLOW.md'), 'utf-8').catch(() => null),\n ])\n\n process.stdout.write('\\n' + chalk.bold('AgentKit Status') + '\\n')\n process.stdout.write('─'.repeat(40) + '\\n')\n\n process.stdout.write(\n chalk.bold('Git repo : ') +\n (isGit ? chalk.green('✔ oui') : chalk.red('✖ non')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('Stack : ') + chalk.cyan(stack.framework) + ' (' + stack.language + ')\\n',\n )\n\n process.stdout.write(\n chalk.bold('CLAUDE.md : ') +\n (claudeMd !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('AGENT_WORKFLOW.md : ') +\n (workflow !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n if (workflow !== null) {\n const agentMatches = workflow.match(/^### Agent \\d+/gm) ?? []\n process.stdout.write(\n chalk.bold('Agents définis : ') + chalk.cyan(String(agentMatches.length)) + '\\n',\n )\n }\n\n process.stdout.write('─'.repeat(40) + '\\n\\n')\n })\n}\n"],"mappings":"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","names":["writeFile","readFile","join","access","join","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","join","readFile","program","join","writeFile","readFile","writeFile","join","basename","inquirer","join","readFile","agentBlock","writeFile","basename","program","inquirer","readFile","join","chalk","program","claudeMd","workflow","readFile","join","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/detectors/stackDetector.ts","../src/detectors/gitDetector.ts","../src/templates/react.ts","../src/templates/nextjs.ts","../src/templates/tauri.ts","../src/templates/fastapi.ts","../src/templates/express.ts","../src/templates/node.ts","../src/templates/unknown.ts","../src/generators/claudeMdGenerator.ts","../src/generators/workflowGenerator.ts","../src/generators/playbookGenerator.ts","../src/generators/skillsGenerator.ts","../src/utils/agentParser.ts","../src/utils/logger.ts","../src/commands/add.ts","../src/commands/status.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander'\nimport { registerInit } from './commands/init.js'\nimport { registerAdd } from './commands/add.js'\nimport { registerStatus } from './commands/status.js'\n\nconst program = new Command()\n\nprogram\n .name('agentkit')\n .description('Scaffolder des workflows multi-agents Claude Code')\n .version('0.1.0')\n\nregisterInit(program)\nregisterAdd(program)\nregisterStatus(program)\n\nprogram.parse()\n","import type { Command } from 'commander'\nimport { writeFile, readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport inquirer from 'inquirer'\nimport ora from 'ora'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { generateClaudeMd } from '../generators/claudeMdGenerator.js'\nimport { generateWorkflow } from '../generators/workflowGenerator.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport { extractAgentsFromWorkflow } from '../utils/agentParser.js'\nimport { logger } from '../utils/logger.js'\nimport type { StackInfo } from '../detectors/stackDetector.js'\nimport { basename } from 'node:path'\n\nconst FRAMEWORK_LABELS: Record<StackInfo['framework'], string> = {\n react: 'React',\n nextjs: 'Next.js',\n tauri: 'Tauri',\n fastapi: 'FastAPI (Python)',\n express: 'Express',\n node: 'Node.js',\n unknown: 'Unknown (generic)',\n}\n\nconst STACK_CHOICES = [\n { name: 'React + Vite', value: 'react' },\n { name: 'Next.js', value: 'nextjs' },\n { name: 'Tauri v2 (React + Rust)', value: 'tauri' },\n { name: 'FastAPI (Python)', value: 'fastapi' },\n { name: 'Express (Node.js)', value: 'express' },\n { name: 'Node.js (generic)', value: 'node' },\n { name: 'None of the above — generate a generic CLAUDE.md to fill manually', value: 'none' },\n]\n\nexport async function resolveStack(\n detected: StackInfo,\n): Promise<{ stack: StackInfo; stackNotConfigured: boolean }> {\n if (detected.framework !== 'unknown') {\n return { stack: detected, stackNotConfigured: false }\n }\n\n logger.warn('Stack not detected automatically.')\n const { selectedFramework } = await inquirer.prompt<{ selectedFramework: string }>([\n {\n type: 'list',\n name: 'selectedFramework',\n message: 'Stack not detected automatically. Please select your stack:',\n choices: STACK_CHOICES as unknown as string[],\n },\n ])\n\n if (selectedFramework === 'none') {\n return { stack: detected, stackNotConfigured: true }\n }\n\n const framework = selectedFramework as StackInfo['framework']\n const hasTypeScript = ['react', 'nextjs', 'tauri'].includes(framework)\n const language: StackInfo['language'] = framework === 'fastapi' ? 'python' : hasTypeScript ? 'typescript' : 'javascript'\n return {\n stack: { ...detected, framework, language, hasTypeScript },\n stackNotConfigured: false,\n }\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await readFile(path)\n return true\n } catch {\n return false\n }\n}\n\nexport function registerInit(program: Command): void {\n program\n .command('init')\n .description('Génère CLAUDE.md et AGENT_WORKFLOW.md dans le dossier courant')\n .option('-f, --force', 'Écrase les fichiers existants sans confirmation')\n .option('--blueprint <path>', 'Fichier blueprint .md à utiliser pour personnaliser les fichiers générés')\n .action(async (options: { force?: boolean; blueprint?: string }) => {\n const cwd = process.cwd()\n\n const spinner = ora('Détection de la stack…').start()\n const [stack, isGit] = await Promise.all([detectStack(cwd), isGitRepo(cwd)])\n spinner.stop()\n\n if (!isGit) {\n logger.warn('Ce dossier n\\'est pas un repo git — lancez git init si nécessaire')\n }\n\n const { stack: resolvedStack, stackNotConfigured } = await resolveStack(stack)\n\n const label = FRAMEWORK_LABELS[resolvedStack.framework]\n logger.info(`Stack : ${label} (${resolvedStack.language})`)\n\n const { confirmed } = await inquirer.prompt<{ confirmed: boolean }>([\n {\n type: 'confirm',\n name: 'confirmed',\n message: `Générer les fichiers pour ${label} ?`,\n default: true,\n },\n ])\n\n if (!confirmed) {\n logger.warn('Annulé.')\n return\n }\n\n const claudeMdPath = join(cwd, 'CLAUDE.md')\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n const playbookPath = join(cwd, 'PLAYBOOK.md')\n\n // Resolve project name from package.json or directory name\n let projectName = basename(cwd)\n try {\n const pkg = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf-8')) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* fallback to dirname */ }\n\n if (!options.force) {\n const existing: string[] = []\n if (await fileExists(claudeMdPath)) existing.push('CLAUDE.md')\n if (await fileExists(workflowPath)) existing.push('AGENT_WORKFLOW.md')\n if (await fileExists(playbookPath)) existing.push('PLAYBOOK.md')\n\n if (existing.length > 0) {\n const { overwrite } = await inquirer.prompt<{ overwrite: boolean }>([\n {\n type: 'confirm',\n name: 'overwrite',\n message: `${existing.join(' et ')} existe déjà. Écraser ?`,\n default: false,\n },\n ])\n if (!overwrite) {\n logger.warn('Annulé.')\n return\n }\n }\n }\n\n // Load blueprint if provided\n let blueprintContent: string | undefined\n if (options.blueprint) {\n try {\n blueprintContent = await readFile(options.blueprint, 'utf-8')\n } catch {\n logger.error(`Blueprint introuvable : ${options.blueprint}`)\n process.exit(1)\n }\n }\n\n const genSpinner = ora('Génération des fichiers…').start()\n const claudeMdContent = generateClaudeMd(resolvedStack, blueprintContent, stackNotConfigured)\n const workflowContent = generateWorkflow(resolvedStack, blueprintContent, projectName)\n const agents = extractAgentsFromWorkflow(workflowContent)\n const playbookContent = generatePlaybook({ agents, projectName, hasBlueprint: !!blueprintContent })\n await writeFile(claudeMdPath, claudeMdContent, 'utf-8')\n await writeFile(workflowPath, workflowContent, 'utf-8')\n await writeFile(playbookPath, playbookContent, 'utf-8')\n await generateSkills(agents, cwd)\n genSpinner.succeed('Fichiers générés')\n\n logger.success('CLAUDE.md → créé')\n logger.success('AGENT_WORKFLOW.md → créé')\n logger.success('PLAYBOOK.md → créé')\n logger.success(`agents/ → ${agents.length} dossier(s) créé(s)`)\n })\n}\n","import { readFile, access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport interface StackInfo {\n framework: 'react' | 'nextjs' | 'tauri' | 'fastapi' | 'express' | 'node' | 'unknown'\n language: 'typescript' | 'javascript' | 'python' | 'unknown'\n hasTypeScript: boolean\n extras: string[]\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p)\n return true\n } catch {\n return false\n }\n}\n\nasync function readJson(p: string): Promise<Record<string, unknown> | null> {\n try {\n const raw = await readFile(p, 'utf-8')\n return JSON.parse(raw) as Record<string, unknown>\n } catch {\n return null\n }\n}\n\nasync function readText(p: string): Promise<string | null> {\n try {\n return await readFile(p, 'utf-8')\n } catch {\n return null\n }\n}\n\nexport async function detectStack(projectPath: string): Promise<StackInfo> {\n const info: StackInfo = {\n framework: 'unknown',\n language: 'unknown',\n hasTypeScript: false,\n extras: [],\n }\n\n const packageJson = await readJson(join(projectPath, 'package.json'))\n const requirementsTxt = await readText(join(projectPath, 'requirements.txt'))\n const hasTauriDir = await pathExists(join(projectPath, 'src-tauri'))\n const hasTsConfig = await pathExists(join(projectPath, 'tsconfig.json'))\n\n if (packageJson !== null) {\n const deps = (packageJson.dependencies as Record<string, string>) ?? {}\n const devDeps = (packageJson.devDependencies as Record<string, string>) ?? {}\n const allDeps = { ...deps, ...devDeps }\n\n info.hasTypeScript = 'typescript' in allDeps || hasTsConfig\n info.language = info.hasTypeScript ? 'typescript' : 'javascript'\n\n // Order matters: most specific first\n if ('next' in allDeps) {\n info.framework = 'nextjs'\n } else if (hasTauriDir || '@tauri-apps/api' in allDeps || '@tauri-apps/cli' in allDeps) {\n info.framework = 'tauri'\n } else if ('react' in allDeps) {\n info.framework = 'react'\n } else if ('express' in allDeps) {\n info.framework = 'express'\n } else {\n info.framework = 'node'\n }\n\n if ('vitest' in allDeps || 'jest' in allDeps) info.extras.push('testing')\n if ('prisma' in allDeps || '@prisma/client' in allDeps) info.extras.push('prisma')\n if ('tailwindcss' in allDeps) info.extras.push('tailwind')\n }\n\n if (requirementsTxt !== null && info.framework === 'unknown') {\n info.language = 'python'\n if (/\\bfastapi\\b/i.test(requirementsTxt)) {\n info.framework = 'fastapi'\n }\n }\n\n if (hasTauriDir && info.framework === 'unknown') {\n info.framework = 'tauri'\n }\n\n return info\n}\n","import { access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nexport async function isGitRepo(projectPath: string): Promise<boolean> {\n try {\n await access(join(projectPath, '.git'))\n return true\n } catch {\n return false\n }\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const testLine = stack.extras.includes('testing') ? '- `npm test` — run tests\\n' : ''\n return `# CLAUDE.md — React Project\n\n## Stack\n- Framework : React (${lang})\n- Language : ${lang}\n- Build : Vite\n\n## Commands\n- \\`npm run dev\\` — development server\n- \\`npm run build\\` — production build\n${testLine}\n## Structure\nsrc/\n components/ ← UI components (PascalCase)\n hooks/ ← custom hooks (prefix: use*)\n pages/ ← page-level components\n utils/ ← shared helpers\n\n## Conventions\n1. Components in PascalCase\n2. Hooks prefixed with \\`use\\`\n3. Props interfaces named \\`*Props\\`\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — React Project\n\n## Stack détectée\nFramework: React | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Components\nPérimètre : composants UI réutilisables\nProduit : src/components/\nCritère : composants documentés et testés\n\n### Agent 2 · State & Hooks\nPérimètre : state management, hooks personnalisés\nProduit : src/hooks/\nCritère : hooks testés unitairement\n\n### Agent 3 · Pages & Routing\nPérimètre : assemblage des pages, react-router\nProduit : src/pages/\nCritère : navigation fonctionnelle\n\n### Agent 4 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const hasTailwind = stack.extras.includes('tailwind')\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Next.js Project\n\n## Stack\n- Framework : Next.js (TypeScript)\n- Rendering : App Router (RSC + Client Components)\n- Styling : ${hasTailwind ? 'Tailwind CSS' : 'CSS Modules'}\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (http://localhost:3000)\n- \\`npm run build\\` — production build\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n app/ ← App Router pages and layouts\n components/ ← shared UI components\n lib/ ← server utilities, db clients\n utils/ ← shared helpers\n\n## Conventions\n1. Server Components by default, \\`'use client'\\` only when needed\n2. API routes in \\`src/app/api/\\`\n3. Environment variables via \\`src/env.ts\\` (validated)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const hasPrisma = stack.extras.includes('prisma')\n return `# Agent Workflow — Next.js Project\n\n## Stack détectée\nFramework: Next.js | Language: TypeScript\n\n## Agents\n\n### Agent 1 · Data Layer\nPérimètre : schéma${hasPrisma ? ' Prisma' : ''}, types, server actions\nProduit : src/lib/, ${hasPrisma ? 'prisma/schema.prisma' : 'src/types/'}\nCritère : types compilent, migrations propres\n\n### Agent 2 · UI Components\nPérimètre : composants réutilisables (Server + Client)\nProduit : src/components/\nCritère : composants rendus sans erreur\n\n### Agent 3 · Pages & Layout\nPérimètre : App Router, layouts, pages\nProduit : src/app/\nCritère : navigation fonctionnelle, build passe\n\n### Agent 4 · API & Tests\nPérimètre : API routes, tests e2e/unitaires\nProduit : src/app/api/, tests/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Tauri Project\n\n## Stack\n- Framework : Tauri (Rust + ${lang} frontend)\n- Language : Rust (backend) + ${lang} (frontend)\n- Build : Cargo + Vite\n\n## Commands\n- \\`npm run tauri:dev\\` — development (hot reload)\n- \\`npm run tauri:build\\` — production bundle\n- \\`npm run dev\\` — frontend only\n- \\`npx tsc --noEmit\\` — type check\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/ ← frontend (${lang})\n components/\n utils/\nsrc-tauri/ ← Rust backend\n src/\n main.rs ← Tauri entry point\n commands.rs ← Tauri commands (IPC)\n tauri.conf.json\n\n## Conventions\n1. IPC commands defined in \\`src-tauri/src/commands.rs\\`\n2. Frontend invokes via \\`@tauri-apps/api/tauri\\`\n3. No direct filesystem access from frontend\n4. All console output goes through a centralized logger\n5. Always use \\`isTauri()\\` before any Tauri plugin call\n6. All Tauri plugin imports must be dynamic (never top-level)\n7. Every Tauri plugin call must have a browser fallback\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Tauri Project\n\n## Stack détectée\nFramework: Tauri | Language: Rust + ${lang}\n\n## Agents\n\n### Agent 1 · Rust Commands\nPérimètre : commandes Tauri (IPC), permissions\nProduit : src-tauri/src/commands.rs, tauri.conf.json\nCritère : \\`cargo build\\` passe\n\n### Agent 2 · Frontend UI\nPérimètre : interface ${lang}, intégration IPC\nProduit : src/components/, src/utils/\nCritère : appels IPC fonctionnels\n\n### Agent 3 · Build & Packaging\nPérimètre : configuration build, icônes, installeurs\nProduit : src-tauri/tauri.conf.json, icons/\nCritère : \\`npm run tauri build\\` produit un bundle\n\n### Agent 4 · Tests\nPérimètre : tests Rust + tests frontend\nProduit : src-tauri/tests/, tests/\nCritère : \\`cargo test\\` + \\`npm test\\` passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md — FastAPI Project\n\n## Stack\n- Framework : FastAPI (Python)\n- Language : Python 3.11+\n- Server : Uvicorn\n- Validation: Pydantic v2\n\n## Commands\n- \\`uvicorn main:app --reload\\` — development server (http://localhost:8000)\n- \\`pytest\\` — run tests\n- \\`pip install -r requirements.txt\\` — install dependencies\n\n## Structure\napp/\n main.py ← FastAPI app entry point\n routers/ ← API route groups\n models/ ← Pydantic models\n services/ ← business logic\n dependencies/ ← FastAPI dependencies (DI)\ntests/ ← pytest tests\n\n## Conventions\n1. Routers grouped by domain in \\`app/routers/\\`\n2. Pydantic models for all request/response bodies\n3. Business logic in \\`app/services/\\`, not in routes\n4. Async endpoints by default (\\`async def\\`)\n5. Environment variables via \\`python-dotenv\\` + \\`pydantic-settings\\`\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow — FastAPI Project\n\n## Stack détectée\nFramework: FastAPI | Language: Python\n\n## Agents\n\n### Agent 1 · Models & Schemas\nPérimètre : modèles Pydantic, schémas DB (SQLAlchemy/SQLModel)\nProduit : app/models/\nCritère : modèles validés, migrations propres\n\n### Agent 2 · Services\nPérimètre : logique métier, accès base de données\nProduit : app/services/\nCritère : services testés unitairement (pytest)\n\n### Agent 3 · Routers & API\nPérimètre : routes FastAPI, dépendances, auth\nProduit : app/routers/, app/dependencies/\nCritère : endpoints documentés (OpenAPI), tests d'intégration\n\n### Agent 4 · Tests & CI\nPérimètre : couverture pytest, configuration CI\nProduit : tests/, .github/workflows/\nCritère : \\`pytest\\` passe à 100%\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n const hasPrisma = stack.extras.includes('prisma')\n return `# CLAUDE.md — Express Project\n\n## Stack\n- Framework : Express (${lang})\n- Language : ${lang}\n- Runtime : Node.js 20+\n${hasPrisma ? '- Database : Prisma ORM\\n' : ''}\n## Commands\n- \\`npm run dev\\` — development server (nodemon)\n- \\`npm run build\\` — compile TypeScript\n- \\`npm start\\` — production server\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n routes/ ← Express routers (one per domain)\n controllers/ ← request handlers\n services/ ← business logic\n middleware/ ← Express middleware\n utils/ ← shared helpers\n\n## Conventions\n1. Routes grouped by domain in \\`src/routes/\\`\n2. Business logic in \\`src/services/\\`, not in controllers\n3. Middleware for cross-cutting concerns (auth, validation)\n4. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Express Project\n\n## Stack détectée\nFramework: Express | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Data & Models\nPérimètre : modèles de données, accès DB\nProduit : src/models/, src/services/db.ts\nCritère : connexion DB fonctionnelle\n\n### Agent 2 · Services\nPérimètre : logique métier\nProduit : src/services/\nCritère : services testés unitairement\n\n### Agent 3 · Routes & Controllers\nPérimètre : routes Express, validation, auth\nProduit : src/routes/, src/controllers/, src/middleware/\nCritère : endpoints répondent correctement\n\n### Agent 4 · Tests & CI\nPérimètre : tests d'intégration, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# CLAUDE.md — Node.js Project\n\n## Stack\n- Runtime : Node.js 20+\n- Language : ${lang}\n\n## Commands\n- \\`npm run dev\\` — development (with watch)\n- \\`npm run build\\` — compile${stack.hasTypeScript ? ' TypeScript' : ''}\n- \\`npm start\\` — run production build\n- \\`npm test\\` — run tests\n\n## Structure\nsrc/\n index.ts ← entry point\n lib/ ← core library code\n utils/ ← shared helpers\n\n## Conventions\n1. Modules follow single-responsibility principle\n2. Async/await over callbacks\n3. Tout output console passe par un logger centralisé\n`\n}\n\nexport function workflow(stack: StackInfo): string {\n const lang = stack.hasTypeScript ? 'TypeScript' : 'JavaScript'\n return `# Agent Workflow — Node.js Project\n\n## Stack détectée\nRuntime: Node.js | Language: ${lang}\n\n## Agents\n\n### Agent 1 · Core Library\nPérimètre : logique principale\nProduit : src/lib/\nCritère : module fonctionne et testé\n\n### Agent 2 · CLI / API\nPérimètre : interface utilisateur (CLI ou API)\nProduit : src/index.ts, src/cli.ts\nCritère : commandes fonctionnelles\n\n### Agent 3 · Tests & CI\nPérimètre : couverture de tests, configuration CI\nProduit : tests/, .github/workflows/\nCritère : npm test passe\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\n\nexport function claudeMd(_stack: StackInfo): string {\n return `# CLAUDE.md\n\n## Stack\nStack non détectée automatiquement — à remplir manuellement.\n\n## Commands\n- À définir selon le projet\n\n## Structure\nsrc/ ← code source\ntests/ ← tests\n\n## Conventions\n1. Tout output console passe par un logger centralisé\n2. À compléter selon les conventions du projet\n`\n}\n\nexport function workflow(_stack: StackInfo): string {\n return `# Agent Workflow\n\n## Stack détectée\nStack inconnue — workflow générique.\n\n## Agents\n\n### Agent 1 · Setup\nPérimètre : configuration initiale du projet\nProduit : structure de base\nCritère : projet compilable\n\n### Agent 2 · Core\nPérimètre : logique principale\nProduit : src/\nCritère : fonctionnalités principales opérationnelles\n\n### Agent 3 · Tests\nPérimètre : couverture de tests\nProduit : tests/\nCritère : tests passent\n`\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nconst STACK_NOT_CONFIGURED_WARNING = `\n## ⚠️ Stack not configured\nAgentKit could not detect your stack and no stack was selected.\nBefore running Claude Code, fill in the following sections:\n- Stack (framework, runtime, DB, tools)\n- Commands (dev, build, test)\n- Structure (folder layout)\n\nOnce filled, give Claude Code this instruction:\n\"Read PLAYBOOK.md and execute the procedure.\"\n`\n\nexport function generateClaudeMd(stack: StackInfo, blueprintContent?: string, stackNotConfigured?: boolean): string {\n let base: string\n switch (stack.framework) {\n case 'react': base = react.claudeMd(stack); break\n case 'nextjs': base = nextjs.claudeMd(stack); break\n case 'tauri': base = tauri.claudeMd(stack); break\n case 'fastapi': base = fastapi.claudeMd(stack); break\n case 'express': base = express.claudeMd(stack); break\n case 'node': base = node.claudeMd(stack); break\n default: base = unknown.claudeMd(stack)\n }\n\n if (stackNotConfigured) {\n const firstNewline = base.indexOf('\\n')\n base = base.slice(0, firstNewline + 1) + STACK_NOT_CONFIGURED_WARNING + base.slice(firstNewline + 1)\n }\n\n if (!blueprintContent) return base\n\n const blueprintNote = '\\n> A PROJECT_BLUEPRINT.md is present — Claude Code will read it during Phase 0.\\n'\n\n const conventionsIdx = base.indexOf('\\n## Conventions')\n if (conventionsIdx !== -1) {\n return base.slice(0, conventionsIdx) + blueprintNote + base.slice(conventionsIdx)\n }\n return base + blueprintNote\n}\n","import type { StackInfo } from '../detectors/stackDetector.js'\nimport * as react from '../templates/react.js'\nimport * as nextjs from '../templates/nextjs.js'\nimport * as tauri from '../templates/tauri.js'\nimport * as fastapi from '../templates/fastapi.js'\nimport * as express from '../templates/express.js'\nimport * as node from '../templates/node.js'\nimport * as unknown from '../templates/unknown.js'\n\nexport function generateWorkflow(stack: StackInfo, blueprintContent?: string, projectName?: string): string {\n if (blueprintContent) return blueprintPlaceholder(projectName ?? stack.framework)\n\n switch (stack.framework) {\n case 'react': return react.workflow(stack)\n case 'nextjs': return nextjs.workflow(stack)\n case 'tauri': return tauri.workflow(stack)\n case 'fastapi': return fastapi.workflow(stack)\n case 'express': return express.workflow(stack)\n case 'node': return node.workflow(stack)\n default: return unknown.workflow(stack)\n }\n}\n\nfunction blueprintPlaceholder(projectName: string): string {\n return `# AGENT_WORKFLOW.md — ${projectName}\n\n> This file will be filled in by Claude Code during Phase 0.\n> Claude Code will read PROJECT_BLUEPRINT.md, propose a decomposition,\n> and replace this content after human validation.\n\n---\n\n*Waiting for Phase 0 decomposition...*\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport interface PlaybookInput {\n agents: Agent[]\n projectName: string\n hasBlueprint: boolean\n}\n\nexport function generatePlaybook({ agents, projectName, hasBlueprint }: PlaybookInput): string {\n const agentBlocks = agents.map((a) => agentBlock(a)).join('\\n---\\n\\n')\n\n const phase0 = hasBlueprint\n ? `## Phase 0 — Agent Decomposition (run this first)\n\n> A \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Claude Code reads it and decomposes the project into specialized agents\n> before writing a single line of code.\n\n**Read these files in order:**\n1. \\`CLAUDE.md\\`\n2. \\`PROJECT_BLUEPRINT.md\\`\n\n**Then decompose the project into agents** following these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n : `## Phase 0 — Project Discovery (run this first)\n\n> No \\`PROJECT_BLUEPRINT.md\\` was provided.\n> Before writing any code, Claude Code asks the user what they want to build,\n> then decomposes the project into agents — exactly as if a blueprint had been provided.\n\n**Ask the user these questions and wait for their answers:**\n\n1. What is this project? (one sentence describing the goal)\n2. What are the main features you want to build? (list them)\n3. Are there any tech constraints or architecture preferences?\n (e.g. offline-only, specific DB, no auth, specific framework)\n\n**Once you have the answers, decompose the project into agents**\nfollowing these rules:\n\n- One agent = one coherent technical layer (never mix two layers)\n- Each agent must have a runnable success criterion (\\`npm test\\`, \\`cargo build\\`…)\n- Agents must be ordered by dependency (no feature without infra first)\n- Maximum 6 agents — if you have more, group related ones\n- Always respect this order:\n 1. Infra & Configuration\n 2. Data layer (DB schema, models, services)\n 3. External integrations (auth, APIs, local services like Ollama)\n 4. UI & pages\n 5. Advanced features (RAG, export, realtime…)\n 6. Build & release (CI/CD, packaging, installers)\n\n**Write the result directly into \\`AGENT_WORKFLOW.md\\`** — replace its current\ncontent with your decomposition.\n\n**Then ask for human validation:**\n> \"I have decomposed the project into N agents: [list them].\n> Should I proceed with execution?\"\n\nWait for confirmation before moving to Phase 1.\n\n---\n\n`\n\n const betweenPhase = `## Between Phase 0 and Phase 1 — Skills Enrichment\n\nOnce the decomposition is validated, before writing any code:\n\n1. Create all agent folders and empty skills files:\n For each agent in your decomposition, create:\n - agents/agent-{N}-{slug}/skills.md (empty for now)\n\n2. Announce to the user:\n \"Agent folders created under agents/.\n\n You can now enrich any skills.md with additional context\n before I start executing:\n - API documentation\n - Database schemas\n - Algorithm references\n - Business conventions\n - Any project-specific knowledge\n\n Add .md files directly in the relevant agent folder —\n I will read everything in agents/agent-{N}-{slug}/ before\n starting that agent.\n\n Type 'proceed' (or any message) when you're ready\n and I'll start Phase 1.\"\n\n3. Wait for the user's message before starting Phase 1.\n Do not start Agent 1 until the user explicitly responds.\n\n---\n\n`\n\n return `# PLAYBOOK.md — ${projectName}\n\n> **One instruction to give Claude Code:**\n> \"Read PLAYBOOK.md and execute the procedure.\"\n>\n> Claude Code handles the rest autonomously — project discovery or blueprint reading,\n> agent decomposition, execution, success validation, retries, and human escalation.\n> No API key required. No additional cost beyond your LLM subscription.\n\n---\n\n## Global Execution Rules\n\nBefore each agent:\n1. Read \\`CLAUDE.md\\`\n2. Read \\`agents/agent-{N}-{slug}/skills.md\\` (current agent's file)\n3. Read the agent's section in \\`AGENT_WORKFLOW.md\\`\n\nAfter each agent:\n- Run the success criterion command\n- ✅ Passes → announce \"✅ Agent N complete\" and move to the next\n- ❌ Fails → analyze the root cause, fix, rerun (max 3 attempts)\n- After 3 consecutive failures → stop and ask for human validation\n\n**Never move to the next agent without a passing success criterion.**\n**Stay strictly within your current agent's defined scope.**\n\n---\n\n${phase0}${betweenPhase}## Phase 1 — Execution\n\n${agentBlocks}\n\n---\n\n## Future Iterations\n\nWhen a new agent is added via \\`agentkit add --feature <description>\\`:\n1. A new agent block is appended to \\`AGENT_WORKFLOW.md\\`\n2. The folder \\`agents/agent-{N}-{slug}/\\` is created with \\`skills.md\\`\n3. This \\`PLAYBOOK.md\\` is regenerated to include the new agent\n4. Execution resumes at the new agent only — completed agents are not rerun\n\nWhen you receive the instruction to continue after an iteration:\n> \"Read PLAYBOOK.md and execute only the agents that haven't been completed yet.\"\n\n---\n\n## Human Validation Required\n\nStop and wait for confirmation in these situations:\n- **3 consecutive failures** on the same success criterion\n- **Missing external dependency**: API key, env variable, unavailable service\n- **Conflict** between the detected stack and the user's stated constraints\n- **Destructive operation**: overwriting files not listed in deliverables\n- **End of Phase 0**: agent decomposition must be validated before execution\n`\n}\n\nfunction agentBlock(agent: Agent): string {\n const skillsPath = `agents/agent-${agent.number}-${agent.slug}/skills.md`\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (see skills.md for details)'\n\n return `### Agent ${agent.number} · ${agent.name}\n\n**Scope**: ${agent.scope}\n\n**Skills**: \\`${skillsPath}\\`\n\n**Deliverables**:\n${outputLines}\n\n**Success criterion**:\n\\`\\`\\`bash\n${agent.criterion || 'npm run build && npm test'}\n\\`\\`\\`\n\n**On failure**:\n1. Read the full error output\n2. Fix the root cause — not the symptoms\n3. Rerun the success criterion (max 3 attempts)\n4. After 3 failures → ask for human validation\n`\n}","import { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { Agent } from '../types/agent.js'\n\nexport async function generateSkills(agents: Agent[], outputDir: string): Promise<void> {\n for (const agent of agents) {\n const agentDir = join(outputDir, 'agents', `agent-${agent.number}-${agent.slug}`)\n await mkdir(agentDir, { recursive: true })\n await writeFile(join(agentDir, 'skills.md'), skillsMd(agent), 'utf-8')\n await writeFile(join(agentDir, 'context.md'), contextMd(agent), 'utf-8')\n }\n}\n\nfunction skillsMd(agent: Agent): string {\n return `# Skills — ${agent.fullName}\n\n> Ce fichier est lu par l'agent avant de commencer.\n\n## Contexte technique\n\n<!-- À remplir : bibliothèques, versions, décisions d'architecture spécifiques à cet agent -->\n\n## Documentation de référence\n\n<!-- À remplir : liens vers docs, exemples, ADRs pertinents -->\n\n## Conventions spécifiques\n\n<!-- À remplir : règles propres à cet agent (naming, patterns, structure de fichiers) -->\n`\n}\n\nfunction contextMd(agent: Agent): string {\n const outputLines =\n agent.outputs.length > 0\n ? agent.outputs.map((o) => `- ${o}`).join('\\n')\n : '- (voir AGENT_WORKFLOW.md)'\n\n return `# Context — ${agent.fullName}\n\n> Ce fichier fournit le contexte additionnel à l'agent avant exécution.\n> À compléter avant de lancer cet agent.\n\n## Périmètre\n\n${agent.scope}\n\n## Fichiers produits attendus\n\n${outputLines}\n\n## Critère de succès\n\n\\`${agent.criterion || 'npm run build && npm test'}\\`\n`\n}\n","import type { Agent } from '../types/agent.js'\n\nexport function toSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[·•&]/g, ' ')\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nfunction getFieldValue(lines: string[], pattern: RegExp): string {\n for (const line of lines) {\n const m = line.match(pattern)\n if (m) return (m[1] ?? '').trim()\n }\n return ''\n}\n\nexport function extractAgentsFromWorkflow(content: string): Agent[] {\n const agents: Agent[] = []\n\n // Split into blocks starting with \"### Agent N\"\n const blocks = content\n .split(/(?=^### Agent \\d)/m)\n .filter((b) => /^### Agent \\d/.test(b.trimStart()))\n\n for (const block of blocks) {\n const lines = block.split('\\n')\n\n const headerMatch = lines[0].match(/^### Agent (\\d+)\\s*[·•]\\s*(.+)$/)\n if (!headerMatch) continue\n\n const number = parseInt(headerMatch[1], 10)\n const name = headerMatch[2].trim()\n const fullName = `Agent ${number} · ${name}`\n const slug = toSlug(name)\n\n const scope = getFieldValue(lines, /Périmètre\\s*:\\s*(.+)/)\n const criterion = getFieldValue(lines, /Critère[s]?\\s*:\\s*(.+)/)\n\n // Outputs: may be inline or multi-line (indented \"- item\")\n const outputs: string[] = []\n const produitIdx = lines.findIndex((l) => /Produit\\s*:/.test(l))\n if (produitIdx !== -1) {\n const inlineVal = (lines[produitIdx].match(/Produit\\s*:\\s*(.+)/)?.[1] ?? '').trim()\n if (inlineVal) {\n outputs.push(inlineVal)\n } else {\n for (let i = produitIdx + 1; i < lines.length; i++) {\n const line = lines[i]\n if (/^\\s+[-]/.test(line)) {\n outputs.push(line.trim().replace(/^-\\s*/, ''))\n } else if (line.trim() !== '' && !/^\\s/.test(line)) {\n break\n }\n }\n }\n }\n\n agents.push({ number, name, fullName, slug, scope, outputs, criterion })\n }\n\n return agents\n}\n","import chalk from 'chalk'\n\nexport const logger = {\n info: (message: string): void => {\n process.stdout.write(chalk.blue('ℹ') + ' ' + message + '\\n')\n },\n success: (message: string): void => {\n process.stdout.write(chalk.green('✔') + ' ' + message + '\\n')\n },\n warn: (message: string): void => {\n process.stdout.write(chalk.yellow('⚠') + ' ' + message + '\\n')\n },\n error: (message: string): void => {\n process.stderr.write(chalk.red('✖') + ' ' + message + '\\n')\n },\n}\n","import type { Command } from 'commander'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport { join, basename } from 'node:path'\nimport inquirer from 'inquirer'\nimport { logger } from '../utils/logger.js'\nimport { extractAgentsFromWorkflow, toSlug } from '../utils/agentParser.js'\nimport { generatePlaybook } from '../generators/playbookGenerator.js'\nimport { generateSkills } from '../generators/skillsGenerator.js'\nimport type { Agent } from '../types/agent.js'\n\nfunction featureToAgentName(description: string): string {\n const clean = description\n .replace(/^(add|implement|create|build|integrate|setup|configure|refactor|improve)\\s+/i, '')\n .trim()\n return clean.replace(/\\b\\w/g, (c) => c.toUpperCase())\n}\n\nexport interface AddFeatureResult {\n agent: Agent\n agentDirPath: string\n}\n\nexport async function addFeatureToProject(\n description: string,\n projectDir: string,\n): Promise<AddFeatureResult> {\n const workflowPath = join(projectDir, 'AGENT_WORKFLOW.md')\n const playbookPath = join(projectDir, 'PLAYBOOK.md')\n\n let workflowContent = ''\n try {\n workflowContent = await readFile(workflowPath, 'utf-8')\n } catch {\n throw new Error(`AGENT_WORKFLOW.md not found in ${projectDir} — run agentkit init first`)\n }\n\n const existingAgents = extractAgentsFromWorkflow(workflowContent)\n const nextNumber = existingAgents.length + 1\n const name = featureToAgentName(description)\n const slug = toSlug(name)\n const fullName = `Agent ${nextNumber} · ${name}`\n\n const newAgent: Agent = {\n number: nextNumber,\n name,\n fullName,\n slug,\n scope: description,\n outputs: [`agents/agent-${nextNumber}-${slug}/`],\n criterion: 'npm run build && npm test',\n }\n\n const agentBlock = `\n### ${fullName}\nPérimètre : ${description}\nProduit :\n - agents/agent-${nextNumber}-${slug}/\nCritère : npm run build && npm test\n`\n\n await writeFile(workflowPath, workflowContent + agentBlock, 'utf-8')\n await generateSkills([newAgent], projectDir)\n\n let projectName = basename(projectDir)\n try {\n const pkg = JSON.parse(\n await readFile(join(projectDir, 'package.json'), 'utf-8'),\n ) as { name?: string }\n if (pkg.name) projectName = pkg.name\n } catch { /* use dirname fallback */ }\n\n const allAgents = [...existingAgents, newAgent]\n\n // When adding a feature iteration, hasBlueprint is false —\n // Phase 0 decomposition only runs during the initial init with --blueprint.\n const playbookContent = generatePlaybook({\n agents: allAgents,\n projectName,\n hasBlueprint: false,\n })\n await writeFile(playbookPath, playbookContent, 'utf-8')\n\n return {\n agent: newAgent,\n agentDirPath: join(projectDir, 'agents', `agent-${nextNumber}-${slug}`),\n }\n}\n\nexport function registerAdd(program: Command): void {\n const addCmd = program\n .command('add')\n .description('Add resources to the agentkit project')\n .option('--feature <description>', 'Add an agent from a feature description and regenerate PLAYBOOK.md')\n .action(async (options: { feature?: string }) => {\n if (options.feature) {\n try {\n const result = await addFeatureToProject(options.feature, process.cwd())\n logger.success(`Agent added : ${result.agent.fullName}`)\n logger.success(`Folder created : agents/agent-${result.agent.number}-${result.agent.slug}/`)\n logger.success('PLAYBOOK.md : regenerated')\n } catch (err) {\n logger.error(err instanceof Error ? err.message : String(err))\n process.exit(1)\n }\n } else {\n addCmd.help()\n }\n })\n\n addCmd\n .command('agent')\n .description('Add a new agent to AGENT_WORKFLOW.md (interactive)')\n .action(async () => {\n const cwd = process.cwd()\n const workflowPath = join(cwd, 'AGENT_WORKFLOW.md')\n\n let existing = ''\n try {\n existing = await readFile(workflowPath, 'utf-8')\n } catch {\n logger.error('AGENT_WORKFLOW.md not found — run agentkit init first')\n process.exit(1)\n }\n\n const agentCount = (existing.match(/^### Agent \\d+/gm) ?? []).length\n const nextNumber = agentCount + 1\n\n const answers = await inquirer.prompt<{\n name: string\n scope: string\n outputs: string\n criterion: string\n }>([\n {\n type: 'input',\n name: 'name',\n message: `Agent name (e.g. \"Agent ${nextNumber} · Feature X\"):`,\n default: `Agent ${nextNumber}`,\n },\n {\n type: 'input',\n name: 'scope',\n message: 'Scope (one sentence):',\n },\n {\n type: 'input',\n name: 'outputs',\n message: 'Deliverables (comma-separated):',\n },\n {\n type: 'input',\n name: 'criterion',\n message: 'Success criterion:',\n },\n ])\n\n const outputLines = answers.outputs\n .split(',')\n .map((o: string) => ` - ${o.trim()}`)\n .join('\\n')\n\n const agentSection = `\n### ${answers.name}\nPérimètre : ${answers.scope}\nProduit :\n${outputLines}\nCritère : ${answers.criterion}\n`\n\n await writeFile(workflowPath, existing + agentSection, 'utf-8')\n logger.success(`Agent \"${answers.name}\" added to AGENT_WORKFLOW.md`)\n })\n}","import type { Command } from 'commander'\nimport { readFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport chalk from 'chalk'\nimport { detectStack } from '../detectors/stackDetector.js'\nimport { isGitRepo } from '../detectors/gitDetector.js'\nimport { logger } from '../utils/logger.js'\n\nexport function registerStatus(program: Command): void {\n program\n .command('status')\n .description('Affiche l\\'état du workflow agentkit dans le dossier courant')\n .action(async () => {\n const cwd = process.cwd()\n\n const [stack, isGit, claudeMd, workflow] = await Promise.all([\n detectStack(cwd),\n isGitRepo(cwd),\n readFile(join(cwd, 'CLAUDE.md'), 'utf-8').catch(() => null),\n readFile(join(cwd, 'AGENT_WORKFLOW.md'), 'utf-8').catch(() => null),\n ])\n\n process.stdout.write('\\n' + chalk.bold('AgentKit Status') + '\\n')\n process.stdout.write('─'.repeat(40) + '\\n')\n\n process.stdout.write(\n chalk.bold('Git repo : ') +\n (isGit ? chalk.green('✔ oui') : chalk.red('✖ non')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('Stack : ') + chalk.cyan(stack.framework) + ' (' + stack.language + ')\\n',\n )\n\n process.stdout.write(\n chalk.bold('CLAUDE.md : ') +\n (claudeMd !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n process.stdout.write(\n chalk.bold('AGENT_WORKFLOW.md : ') +\n (workflow !== null ? chalk.green('✔ présent') : chalk.yellow('✖ absent — lancez agentkit init')) +\n '\\n',\n )\n\n if (workflow !== null) {\n const agentMatches = workflow.match(/^### Agent \\d+/gm) ?? []\n process.stdout.write(\n chalk.bold('Agents définis : ') + chalk.cyan(String(agentMatches.length)) + '\\n',\n )\n }\n\n process.stdout.write('─'.repeat(40) + '\\n\\n')\n })\n}\n"],"mappings":"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","names":["writeFile","readFile","join","access","join","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","claudeMd","workflow","join","readFile","program","join","writeFile","readFile","writeFile","join","basename","inquirer","join","readFile","agentBlock","writeFile","basename","program","inquirer","readFile","join","chalk","program","claudeMd","workflow","readFile","join","chalk"]}
|
package/package.json
CHANGED
|
@@ -85,6 +85,39 @@ Wait for confirmation before moving to Phase 1.
|
|
|
85
85
|
|
|
86
86
|
---
|
|
87
87
|
|
|
88
|
+
`
|
|
89
|
+
|
|
90
|
+
const betweenPhase = `## Between Phase 0 and Phase 1 — Skills Enrichment
|
|
91
|
+
|
|
92
|
+
Once the decomposition is validated, before writing any code:
|
|
93
|
+
|
|
94
|
+
1. Create all agent folders and empty skills files:
|
|
95
|
+
For each agent in your decomposition, create:
|
|
96
|
+
- agents/agent-{N}-{slug}/skills.md (empty for now)
|
|
97
|
+
|
|
98
|
+
2. Announce to the user:
|
|
99
|
+
"Agent folders created under agents/.
|
|
100
|
+
|
|
101
|
+
You can now enrich any skills.md with additional context
|
|
102
|
+
before I start executing:
|
|
103
|
+
- API documentation
|
|
104
|
+
- Database schemas
|
|
105
|
+
- Algorithm references
|
|
106
|
+
- Business conventions
|
|
107
|
+
- Any project-specific knowledge
|
|
108
|
+
|
|
109
|
+
Add .md files directly in the relevant agent folder —
|
|
110
|
+
I will read everything in agents/agent-{N}-{slug}/ before
|
|
111
|
+
starting that agent.
|
|
112
|
+
|
|
113
|
+
Type 'proceed' (or any message) when you're ready
|
|
114
|
+
and I'll start Phase 1."
|
|
115
|
+
|
|
116
|
+
3. Wait for the user's message before starting Phase 1.
|
|
117
|
+
Do not start Agent 1 until the user explicitly responds.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
88
121
|
`
|
|
89
122
|
|
|
90
123
|
return `# PLAYBOOK.md — ${projectName}
|
|
@@ -116,7 +149,7 @@ After each agent:
|
|
|
116
149
|
|
|
117
150
|
---
|
|
118
151
|
|
|
119
|
-
${phase0}## Phase 1 — Execution
|
|
152
|
+
${phase0}${betweenPhase}## Phase 1 — Execution
|
|
120
153
|
|
|
121
154
|
${agentBlocks}
|
|
122
155
|
|
|
@@ -106,6 +106,30 @@ describe('generatePlaybook (common)', () => {
|
|
|
106
106
|
expect(typeof result).toBe('string')
|
|
107
107
|
expect(result).toContain('empty-project')
|
|
108
108
|
})
|
|
109
|
+
|
|
110
|
+
it(`[${label}] contains the Between Phase 0 and Phase 1 block`, () => {
|
|
111
|
+
const result = generatePlaybook({ agents: sampleAgents, projectName: 'my-app', hasBlueprint })
|
|
112
|
+
expect(result).toContain('Between Phase 0 and Phase 1')
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it(`[${label}] Between block contains "proceed"`, () => {
|
|
116
|
+
const result = generatePlaybook({ agents: sampleAgents, projectName: 'my-app', hasBlueprint })
|
|
117
|
+
expect(result).toContain('proceed')
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it(`[${label}] Between block contains "agents/"`, () => {
|
|
121
|
+
const result = generatePlaybook({ agents: sampleAgents, projectName: 'my-app', hasBlueprint })
|
|
122
|
+
expect(result).toContain('agents/')
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it(`[${label}] Between Phase block appears after Phase 0 and before Phase 1`, () => {
|
|
126
|
+
const result = generatePlaybook({ agents: sampleAgents, projectName: 'my-app', hasBlueprint })
|
|
127
|
+
const phase0Idx = result.indexOf('Phase 0')
|
|
128
|
+
const betweenIdx = result.indexOf('Between Phase 0 and Phase 1')
|
|
129
|
+
const phase1Idx = result.indexOf('Phase 1 — Execution')
|
|
130
|
+
expect(phase0Idx).toBeLessThan(betweenIdx)
|
|
131
|
+
expect(betweenIdx).toBeLessThan(phase1Idx)
|
|
132
|
+
})
|
|
109
133
|
}
|
|
110
134
|
})
|
|
111
135
|
|