Automated AGENTS.md Merge with AI CLI Detection
Status: ✅ Complete · Priority: High · Created: 2025-11-27 · Tags: init, dx, ai-agents, onboarding, automation
Project: lean-spec
Team: Core Development
Overview
Problem
Current lean-spec init workflow with existing AGENTS.md files is too manual:
-
Manual Merge Execution: User must manually invoke AI tool with the merge prompt:
copilot -p "follow .lean-spec/MERGE-AGENTS-PROMPT.md to edit AGENTS.md" --allow-all-tools -
No AI CLI Auto-Detection: We already detect AI tools in spec 126, but don't leverage this to automatically execute the merge
-
Extra Step After Init: User sees instructions but has to manually copy/paste or run a separate command
Current Flow (Pain Points)
lean-spec init
↓
Found existing AGENTS.md
↓
Choose: "AI-Assisted Merge (recommended)"
↓
✓ Created AI consolidation prompt
→ .lean-spec/MERGE-AGENTS-PROMPT.md
↓
📝 Next steps:
1. Open .lean-spec/MERGE-AGENTS-PROMPT.md ← Manual
2. Send it to your AI coding assistant ← Manual
3. Let AI create the consolidated AGENTS.md ← Manual
4. Review and commit the result ← Manual
Proposed Flow
lean-spec init
↓
Found existing AGENTS.md
↓
Choose: "AI-Assisted Merge (recommended)"
↓
🔍 Detected: copilot CLI installed
↓
? Auto-merge with copilot? (Y/n)
↓ [Yes]
Running: copilot -p "..." --allow-all-tools
↓
✓ AGENTS.md merged successfully!
Review changes: git diff AGENTS.md
Goal
Make AGENTS.md merging a single-step operation by:
- Auto-detecting installed AI CLI tools (reusing spec 126 detection)
- Offering to automatically execute the merge using detected tool
- Falling back to manual instructions only when no CLI is available
Design
AI CLI Tool Registry
Extend AI_TOOL_CONFIGS with CLI execution capabilities:
interface AIToolConfig {
// ... existing fields from spec 126
cli?: {
command: string; // Primary CLI command
promptFlag: string; // Flag for inline prompts (e.g., '-p')
allowToolsFlag?: string; // Flag to enable tool use (e.g., '--allow-all-tools')
filePromptFlag?: string; // Flag for file-based prompts (e.g., '-f')
};
}
Supported AI CLIs
| Tool | CLI Command | Prompt Flag | Tools Flag | Status |
|---|---|---|---|---|
| GitHub Copilot | copilot | -p | --allow-all-tools | ✅ Verified |
| Claude Code | claude | --prompt | --allow-all-tools | ⚠️ Verify syntax |
| Gemini CLI | gemini | TBD | TBD | ⚠️ Need to verify |
| Aider | aider | --message | N/A | ⚠️ Different model |
| Codex CLI | codex | TBD | TBD | ⚠️ Need to verify |
Execution Strategy
interface MergeExecution {
tool: AIToolKey;
command: string; // Full command to execute
prompt: string; // The merge prompt content
workingDir: string; // Project directory
}
async function executeMergeWithAI(
cwd: string,
promptPath: string,
tool: AIToolKey
): Promise<{ success: boolean; output?: string; error?: string }>;
User Flow Options
Option A: Direct Execution (Recommended)
- Detect CLI → Ask to auto-execute → Run merge → Show result
Option B: Command Suggestion
- Detect CLI → Show ready-to-run command → User copies/executes
Option C: Hybrid
- Detect CLI → Show command → Ask "Run now? (Y/n)"
Decision: Use Option C (Hybrid) - Shows command for transparency, asks permission before executing
Security Considerations
- Explicit Consent: Always ask before executing AI commands
- Show Command: Display exact command before running
- Tool Flags: Use appropriate safety flags per tool
- Working Directory: Execute in project root only
- Output Capture: Show AI output for user review
Error Handling
type MergeResult =
| { status: 'success'; message: string }
| { status: 'declined'; message: string } // User said no
| { status: 'no-cli'; message: string } // No CLI detected
| { status: 'error'; error: string } // Execution failed
| { status: 'timeout'; message: string }; // AI took too long
Updated Init Flow
async function handleExistingFiles(
action: 'merge-ai' | 'merge-append' | 'overwrite' | 'skip',
existingFiles: string[],
templateDir: string,
cwd: string,
variables: Record<string, string>,
options?: { autoMerge?: boolean; skipPrompts?: boolean }
): Promise<void> {
if (action === 'merge-ai' && file === 'AGENTS.md') {
// 1. Create consolidation prompt (existing behavior)
await createMergePrompt(existing, template, promptPath);
// 2. NEW: Detect AI CLI and offer auto-merge
const detectedTools = await detectInstalledAITools();
const cliCapableTools = detectedTools.filter(t =>
t.detected && AI_TOOL_CONFIGS[t.tool].cli
);
if (cliCapableTools.length > 0) {
const tool = cliCapableTools[0]; // Use first detected tool
const config = AI_TOOL_CONFIGS[tool.tool];
const command = buildMergeCommand(config.cli!, promptPath);
console.log(chalk.cyan(`\n🔍 Detected: ${config.description}`));
console.log(chalk.gray(` Command: ${command}`));
if (!options?.skipPrompts) {
const autoMerge = await confirm({
message: 'Run merge automatically?',
default: true,
});
if (autoMerge) {
const result = await executeMergeWithAI(cwd, promptPath, tool.tool);
if (result.success) {
console.log(chalk.green('✓ AGENTS.md merged successfully!'));
console.log(chalk.gray(' Review: git diff AGENTS.md'));
return;
} else {
console.log(chalk.yellow(`⚠ Auto-merge failed: ${result.error}`));
console.log(chalk.gray(' Falling back to manual merge...'));
}
}
}
}
// 3. Fallback: Show manual instructions (existing behavior)
showManualMergeInstructions(promptPath);
}
}
Plan
-
Phase 1: CLI Configuration
- Extend
AIToolConfiginterface withcliproperty - Add CLI configs for copilot, claude, gemini, aider
- Test CLI detection for each tool
- Extend
-
Phase 2: Merge Execution
- Implement
buildMergeCommand()function - Implement
executeMergeWithAI()with spawn/exec - Add timeout handling (60s default)
- Capture and display AI output
- Implement
-
Phase 3: Integration
- Update
handleExistingFiles()with auto-merge flow - Add user confirmation prompt
- Handle
-yflag behavior (auto-execute if CLI detected) - Update error handling and fallbacks
- Update
-
Phase 4: Testing & Polish
- Test with copilot CLI
- Test with claude CLI
- Test fallback when no CLI available
- Test
-yflag behavior - Update documentation
Test
Automated Tests:
-
buildMergeCommand()generates correct command for each tool - Detection reuses spec 126 logic correctly
- Timeout handling works (mock slow execution)
- Error handling covers all failure modes
Manual Tests:
-
Fresh project with existing AGENTS.md + copilot installed
mkdir test-project && cd test-project echo "# My Project\n\nExisting instructions..." > AGENTS.md lean-spec init # Expected: Detects copilot, asks to auto-merge, executes successfully -
No CLI detected
# In environment without AI CLIs lean-spec init # Expected: Falls back to manual instructions (current behavior) -
Auto-merge declined
lean-spec init # Choose AI-Assisted Merge # Say "No" to auto-merge # Expected: Shows manual instructions -
With -y flag
lean-spec init -y # Expected: Auto-merges without asking if CLI detected
Notes
CLI Syntax Research Needed
Before implementation, verify exact CLI syntax for each tool:
| Tool | Verified | Notes |
|---|---|---|
copilot | ✅ | copilot -p "prompt" --allow-all-tools |
claude | ❓ | Need to verify prompt flag syntax |
gemini | ❓ | Need to verify CLI exists and syntax |
aider | ❓ | Different interaction model (chat-based) |
Alternative: Command-to-Clipboard
If execution feels too invasive, alternative:
🔍 Detected: copilot CLI
Command copied to clipboard:
copilot -p "follow .lean-spec/MERGE-AGENTS-PROMPT.md..." --allow-all-tools
Paste in terminal to merge automatically.
Future Enhancements
- Multi-tool selection: If multiple CLIs detected, let user choose
- Dry-run mode: Show what merge would produce without applying
- Interactive merge: Stream AI output in real-time
- Merge preview: Show diff before applying changes
- Retry with different tool: If first tool fails, offer alternatives