@itz4blitz/agentful 0.2.0 → 0.3.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/.claude/agents/orchestrator.md +121 -610
- package/.claude/commands/agentful-generate.md +206 -0
- package/.claude/product/README.md +32 -0
- package/.claude/skills/conversation/SKILL.md +152 -975
- package/bin/cli.js +108 -655
- package/bin/hooks/health-check.sh +16 -16
- package/lib/index.js +6 -36
- package/lib/init.js +162 -0
- package/package.json +8 -3
- package/version.json +1 -1
- package/.claude/commands/agentful-agents.md +0 -668
- package/.claude/commands/agentful-skills.md +0 -635
- package/.claude/product/CHANGES.md +0 -276
- package/lib/agent-generator.js +0 -685
- package/lib/domain-detector.js +0 -468
- package/lib/domain-structure-generator.js +0 -770
- package/lib/project-analyzer.js +0 -701
- package/lib/tech-stack-detector.js +0 -1091
- package/lib/template-engine.js +0 -153
package/bin/cli.js
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* agentful CLI
|
|
5
|
-
*
|
|
4
|
+
* agentful CLI - Thin wrapper for template initialization and status
|
|
5
|
+
*
|
|
6
|
+
* Smart analysis and generation happens in Claude Code using:
|
|
7
|
+
* - /agentful-agents command
|
|
8
|
+
* - /agentful-skills command
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
11
|
import fs from 'fs';
|
|
9
12
|
import path from 'path';
|
|
10
13
|
import { fileURLToPath } from 'url';
|
|
11
|
-
import {
|
|
12
|
-
import AgentGenerator from '../lib/agent-generator.js';
|
|
13
|
-
import DomainStructureGenerator from '../lib/domain-structure-generator.js';
|
|
14
|
+
import { initProject, isInitialized } from '../lib/init.js';
|
|
14
15
|
|
|
15
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
17
|
const __dirname = path.dirname(__filename);
|
|
17
18
|
|
|
18
19
|
// Read version from centralized config
|
|
19
20
|
const VERSION = JSON.parse(fs.readFileSync(path.join(__dirname, '../version.json'), 'utf-8')).version;
|
|
20
|
-
const AGENTFUL_DIR = path.resolve(__dirname, '..');
|
|
21
|
-
const TEMPLATE_DIR = path.join(AGENTFUL_DIR, 'template');
|
|
22
21
|
|
|
23
22
|
// ANSI colors
|
|
24
23
|
const colors = {
|
|
@@ -56,28 +55,20 @@ function showHelp() {
|
|
|
56
55
|
console.log(` ${colors.bright}agentful${colors.reset} ${colors.green}<command>${colors.reset}`);
|
|
57
56
|
console.log('');
|
|
58
57
|
console.log('COMMANDS:');
|
|
59
|
-
console.log(` ${colors.green}init${colors.reset} Initialize agentful
|
|
60
|
-
console.log(` ${colors.green}
|
|
61
|
-
console.log(` ${colors.green}
|
|
62
|
-
console.log(` ${colors.green}init --deep${colors.reset} Run deep analysis (slower, more thorough)`);
|
|
63
|
-
console.log(` ${colors.green}init --generate-agents${colors.reset} Auto-generate agents`);
|
|
64
|
-
console.log(` ${colors.green}init --generate-domains${colors.reset} Auto-generate domain structure`);
|
|
65
|
-
console.log(` ${colors.green}generate${colors.reset} Generate specialized agents from tech stack`);
|
|
66
|
-
console.log(` ${colors.green}status${colors.reset} Show current development progress`);
|
|
67
|
-
console.log(` ${colors.green}--help${colors.reset} Show this help message`);
|
|
58
|
+
console.log(` ${colors.green}init${colors.reset} Initialize agentful (copy templates)`);
|
|
59
|
+
console.log(` ${colors.green}status${colors.reset} Show agentful status and generated files`);
|
|
60
|
+
console.log(` ${colors.green}help${colors.reset} Show this help message`);
|
|
68
61
|
console.log(` ${colors.green}--version${colors.reset} Show version`);
|
|
69
62
|
console.log('');
|
|
70
63
|
console.log('AFTER INIT:');
|
|
71
|
-
console.log(` 1. ${colors.bright}
|
|
72
|
-
console.log(`
|
|
73
|
-
console.log(` ${colors.cyan}• Large/complex projects:${colors.reset} Creates .claude/product/ with domains`);
|
|
74
|
-
console.log(` ${colors.dim}(Detection based on: # of domains, frameworks, monorepo status)${colors.reset}`);
|
|
75
|
-
console.log(` 2. ${colors.bright}Edit your product specification${colors.reset}`);
|
|
76
|
-
console.log(` 3. Run ${colors.bright}claude${colors.reset} to start Claude Code`);
|
|
77
|
-
console.log(` 4. Type ${colors.bright}/agentful${colors.reset} for natural conversation or ${colors.bright}/agentful-start${colors.reset} for structured development`);
|
|
64
|
+
console.log(` 1. ${colors.bright}Run claude${colors.reset} to start Claude Code`);
|
|
65
|
+
console.log(` 2. ${colors.bright}Type /agentful-generate${colors.reset} to analyze codebase & generate agents`);
|
|
78
66
|
console.log('');
|
|
79
|
-
console.log('
|
|
80
|
-
console.log(` ${colors.cyan}/
|
|
67
|
+
console.log('CLAUDE CODE COMMANDS:');
|
|
68
|
+
console.log(` ${colors.cyan}/agentful-generate${colors.reset} - Analyze codebase, generate agents & skills`);
|
|
69
|
+
console.log(` ${colors.cyan}/agentful-start${colors.reset} - Begin structured development workflow`);
|
|
70
|
+
console.log(` ${colors.cyan}/agentful-status${colors.reset} - Show progress and completion`);
|
|
71
|
+
console.log(` ${colors.cyan}/agentful${colors.reset} - Natural conversation about your product`);
|
|
81
72
|
console.log('');
|
|
82
73
|
}
|
|
83
74
|
|
|
@@ -85,22 +76,6 @@ function showVersion() {
|
|
|
85
76
|
console.log(`agentful v${VERSION}`);
|
|
86
77
|
}
|
|
87
78
|
|
|
88
|
-
function copyDir(src, dest) {
|
|
89
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
90
|
-
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
91
|
-
|
|
92
|
-
for (const entry of entries) {
|
|
93
|
-
const srcPath = path.join(src, entry.name);
|
|
94
|
-
const destPath = path.join(dest, entry.name);
|
|
95
|
-
|
|
96
|
-
if (entry.isDirectory()) {
|
|
97
|
-
copyDir(srcPath, destPath);
|
|
98
|
-
} else {
|
|
99
|
-
fs.copyFileSync(srcPath, destPath);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
79
|
function checkGitignore() {
|
|
105
80
|
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
106
81
|
let content = '';
|
|
@@ -117,26 +92,15 @@ function checkGitignore() {
|
|
|
117
92
|
}
|
|
118
93
|
}
|
|
119
94
|
|
|
120
|
-
async function
|
|
95
|
+
async function init() {
|
|
121
96
|
showBanner();
|
|
122
97
|
|
|
123
98
|
const targetDir = process.cwd();
|
|
124
99
|
const claudeDir = path.join(targetDir, '.claude');
|
|
125
|
-
const agentfulDir = path.join(targetDir, '.agentful');
|
|
126
|
-
|
|
127
|
-
// Parse options
|
|
128
|
-
const bare = options.bare || false;
|
|
129
|
-
const smart = options.smart !== false; // Default: true
|
|
130
|
-
const deep = options.deep || false;
|
|
131
|
-
const autoGenerateAgents = options.generateAgents || false;
|
|
132
|
-
const autoGenerateDomains = options.generateDomains || false;
|
|
133
|
-
|
|
134
|
-
// Initialize analysis variable (will be populated later)
|
|
135
|
-
let analysis = null;
|
|
136
100
|
|
|
137
101
|
// Check if already initialized
|
|
138
|
-
if (
|
|
139
|
-
log(colors.yellow, '
|
|
102
|
+
if (await isInitialized(targetDir)) {
|
|
103
|
+
log(colors.yellow, 'agentful is already initialized in this directory!');
|
|
140
104
|
const readline = await import('readline');
|
|
141
105
|
const rl = readline.createInterface({
|
|
142
106
|
input: process.stdin,
|
|
@@ -153,630 +117,129 @@ async function initagentful(options = {}) {
|
|
|
153
117
|
process.exit(0);
|
|
154
118
|
}
|
|
155
119
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// Create .claude/ directory structure
|
|
161
|
-
log(colors.dim, 'Creating .claude/ directory structure...');
|
|
162
|
-
|
|
163
|
-
const sourceClaudeDir = path.join(AGENTFUL_DIR, '.claude');
|
|
164
|
-
copyDir(sourceClaudeDir, claudeDir);
|
|
165
|
-
|
|
166
|
-
// Create .agentful/ directory
|
|
167
|
-
if (!fs.existsSync(agentfulDir)) {
|
|
168
|
-
fs.mkdirSync(agentfulDir, { recursive: true });
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Initialize state files
|
|
172
|
-
log(colors.dim, 'Initializing state files...');
|
|
173
|
-
|
|
174
|
-
const now = new Date().toISOString();
|
|
175
|
-
|
|
176
|
-
fs.writeFileSync(
|
|
177
|
-
path.join(agentfulDir, 'state.json'),
|
|
178
|
-
JSON.stringify(
|
|
179
|
-
{
|
|
180
|
-
version: '0.1.1',
|
|
181
|
-
current_task: null,
|
|
182
|
-
current_phase: 'idle',
|
|
183
|
-
iterations: 0,
|
|
184
|
-
last_updated: now,
|
|
185
|
-
blocked_on: []
|
|
186
|
-
},
|
|
187
|
-
null,
|
|
188
|
-
2
|
|
189
|
-
)
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
fs.writeFileSync(
|
|
193
|
-
path.join(agentfulDir, 'decisions.json'),
|
|
194
|
-
JSON.stringify({ pending: [], resolved: [] }, null, 2)
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
fs.writeFileSync(
|
|
198
|
-
path.join(agentfulDir, 'completion.json'),
|
|
199
|
-
JSON.stringify(
|
|
200
|
-
{
|
|
201
|
-
features: {},
|
|
202
|
-
gates: {
|
|
203
|
-
tests_passing: false,
|
|
204
|
-
no_type_errors: false,
|
|
205
|
-
no_dead_code: false,
|
|
206
|
-
coverage_80: false,
|
|
207
|
-
security_clean: false
|
|
208
|
-
},
|
|
209
|
-
overall: 0,
|
|
210
|
-
last_updated: now
|
|
211
|
-
},
|
|
212
|
-
null,
|
|
213
|
-
2
|
|
214
|
-
)
|
|
215
|
-
);
|
|
216
|
-
|
|
217
|
-
fs.writeFileSync(
|
|
218
|
-
path.join(agentfulDir, 'architecture.json'),
|
|
219
|
-
JSON.stringify(
|
|
220
|
-
{
|
|
221
|
-
detected_stack: {},
|
|
222
|
-
generated_agents: [],
|
|
223
|
-
decisions: [],
|
|
224
|
-
timestamp: now
|
|
225
|
-
},
|
|
226
|
-
null,
|
|
227
|
-
2
|
|
228
|
-
)
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
// Copy templates if not bare mode
|
|
232
|
-
if (!bare) {
|
|
233
|
-
log(colors.dim, 'Creating template files...');
|
|
234
|
-
|
|
235
|
-
const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
|
|
236
|
-
const productMdPath = path.join(targetDir, 'PRODUCT.md');
|
|
237
|
-
const claudeProductDir = path.join(targetDir, '.claude/product');
|
|
238
|
-
|
|
239
|
-
if (!fs.existsSync(claudeMdPath)) {
|
|
240
|
-
fs.copyFileSync(
|
|
241
|
-
path.join(TEMPLATE_DIR, 'CLAUDE.md'),
|
|
242
|
-
claudeMdPath
|
|
243
|
-
);
|
|
244
|
-
log(colors.green, ' ✓ Created CLAUDE.md');
|
|
245
|
-
} else {
|
|
246
|
-
log(colors.dim, ' ⊙ CLAUDE.md already exists, skipping');
|
|
120
|
+
// Remove existing files
|
|
121
|
+
log(colors.dim, 'Removing existing agentful files...');
|
|
122
|
+
if (fs.existsSync(claudeDir)) {
|
|
123
|
+
fs.rmSync(claudeDir, { recursive: true, force: true });
|
|
247
124
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
analysis.domains.length >= 3 || // Multiple detected domains
|
|
252
|
-
(analysis.frameworks && analysis.frameworks.length >= 2) || // Multiple frameworks
|
|
253
|
-
(analysis.packageManager === 'workspace' || analysis.packageManager === 'monorepo') // Monorepo
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
// Create appropriate product structure
|
|
257
|
-
const productExists = fs.existsSync(productMdPath) || fs.existsSync(claudeProductDir);
|
|
258
|
-
|
|
259
|
-
if (!productExists) {
|
|
260
|
-
if (shouldUseHierarchical) {
|
|
261
|
-
// Create hierarchical .claude/product/ structure
|
|
262
|
-
log(colors.dim, ' 📁 Using hierarchical product structure (detected complex project)');
|
|
263
|
-
fs.mkdirSync(claudeProductDir, { recursive: true });
|
|
264
|
-
fs.mkdirSync(path.join(claudeProductDir, 'domains'), { recursive: true });
|
|
265
|
-
|
|
266
|
-
// Create main index.md
|
|
267
|
-
const indexContent = `# Product Specification
|
|
268
|
-
|
|
269
|
-
## Overview
|
|
270
|
-
[Describe your product here]
|
|
271
|
-
|
|
272
|
-
## Tech Stack
|
|
273
|
-
${analysis && analysis.language ? `- Language: ${analysis.language}` : ''}
|
|
274
|
-
${analysis && analysis.frameworks && analysis.frameworks.length > 0 ? `- Frameworks: ${analysis.frameworks.join(', ')}` : ''}
|
|
275
|
-
${analysis && analysis.packageManager && analysis.packageManager !== 'unknown' ? `- Package Manager: ${analysis.packageManager}` : ''}
|
|
276
|
-
|
|
277
|
-
## Domains
|
|
278
|
-
${analysis && analysis.domains.length > 0 ? analysis.domains.map((d, i) => `${i + 1}. [${d}] - Define details in \`domains/${d.toLowerCase().replace(/\s+/g, '-')}/index.md\``).join('\n') : '- [Domain 1] - Define in domains/domain-name/index.md\n- [Domain 2] - Define in domains/domain-name/index.md'}
|
|
279
|
-
|
|
280
|
-
## Priority Legend
|
|
281
|
-
- **CRITICAL**: Must have for launch
|
|
282
|
-
- **HIGH**: Important for MVP
|
|
283
|
-
- **MEDIUM**: Nice to have
|
|
284
|
-
- **LOW**: Future consideration
|
|
285
|
-
`;
|
|
286
|
-
|
|
287
|
-
fs.writeFileSync(path.join(claudeProductDir, 'index.md'), indexContent);
|
|
288
|
-
|
|
289
|
-
// Create domain directories with index files for detected domains
|
|
290
|
-
if (analysis && analysis.domains.length > 0) {
|
|
291
|
-
analysis.domains.slice(0, 8).forEach(domain => {
|
|
292
|
-
const domainDir = path.join(claudeProductDir, 'domains', domain.toLowerCase().replace(/\s+/g, '-'));
|
|
293
|
-
fs.mkdirSync(domainDir, { recursive: true });
|
|
294
|
-
|
|
295
|
-
const domainIndexContent = `# ${domain} Domain
|
|
296
|
-
|
|
297
|
-
## Overview
|
|
298
|
-
[Describe the ${domain} domain's purpose and scope]
|
|
299
|
-
|
|
300
|
-
## Features
|
|
301
|
-
1. [Feature 1] (CRITICAL)
|
|
302
|
-
- [Acceptance criteria]
|
|
303
|
-
- [Dependencies]
|
|
304
|
-
|
|
305
|
-
2. [Feature 2] (HIGH)
|
|
306
|
-
- [Acceptance criteria]
|
|
307
|
-
|
|
308
|
-
## Technical Notes
|
|
309
|
-
- [Any technical considerations specific to this domain]
|
|
310
|
-
`;
|
|
311
|
-
fs.writeFileSync(path.join(domainDir, 'index.md'), domainIndexContent);
|
|
312
|
-
});
|
|
313
|
-
} else {
|
|
314
|
-
// Create example domain structure
|
|
315
|
-
const exampleDomainDir = path.join(claudeProductDir, 'domains', 'example-domain');
|
|
316
|
-
fs.mkdirSync(exampleDomainDir, { recursive: true });
|
|
317
|
-
fs.writeFileSync(
|
|
318
|
-
path.join(exampleDomainDir, 'index.md'),
|
|
319
|
-
'# Example Domain\n\n## Overview\n[Describe this domain]\n\n## Features\n1. Example Feature (HIGH)\n'
|
|
320
|
-
);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
log(colors.green, ' ✓ Created .claude/product/ with domain structure');
|
|
324
|
-
log(colors.dim, ` → Organized by ${analysis.domains.length > 0 ? analysis.domains.length : 'example'} domain(s)`);
|
|
325
|
-
} else {
|
|
326
|
-
// Create flat PRODUCT.md structure
|
|
327
|
-
log(colors.dim, ' 📄 Using flat product structure (simple project)');
|
|
328
|
-
fs.copyFileSync(
|
|
329
|
-
path.join(TEMPLATE_DIR, 'PRODUCT.md'),
|
|
330
|
-
productMdPath
|
|
331
|
-
);
|
|
332
|
-
log(colors.green, ' ✓ Created PRODUCT.md');
|
|
333
|
-
}
|
|
334
|
-
} else {
|
|
335
|
-
log(colors.dim, ' ⊙ Product spec already exists, skipping');
|
|
125
|
+
const agentfulDir = path.join(targetDir, '.agentful');
|
|
126
|
+
if (fs.existsSync(agentfulDir)) {
|
|
127
|
+
fs.rmSync(agentfulDir, { recursive: true, force: true });
|
|
336
128
|
}
|
|
337
129
|
}
|
|
338
130
|
|
|
339
|
-
//
|
|
340
|
-
|
|
131
|
+
// Initialize using lib/init.js
|
|
132
|
+
log(colors.dim, 'Copying templates...');
|
|
133
|
+
try {
|
|
134
|
+
const result = await initProject(targetDir, { includeProduct: true });
|
|
341
135
|
|
|
342
|
-
// Perform essential project detection (unless explicitly disabled)
|
|
343
|
-
if (smart) {
|
|
344
|
-
console.log('');
|
|
345
|
-
log(colors.bright, '🔍 Detecting project essentials...');
|
|
346
136
|
console.log('');
|
|
347
|
-
|
|
348
|
-
try {
|
|
349
|
-
analysis = await analyzeProject(targetDir);
|
|
350
|
-
await exportToArchitectureJson(targetDir, analysis);
|
|
351
|
-
|
|
352
|
-
// Show only essential info
|
|
353
|
-
if (analysis.language && analysis.language !== 'unknown') {
|
|
354
|
-
log(colors.cyan, ` Language: ${analysis.language}`);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
if (analysis.frameworks.length > 0) {
|
|
358
|
-
log(colors.cyan, ` Framework: ${analysis.frameworks[0]}`);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (analysis.packageManager && analysis.packageManager !== 'unknown') {
|
|
362
|
-
log(colors.cyan, ` Package Mgr: ${analysis.packageManager}`);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
console.log('');
|
|
366
|
-
log(colors.dim, ` ✓ Detection complete`);
|
|
367
|
-
|
|
368
|
-
// Show critical warnings only
|
|
369
|
-
if (analysis.warnings && analysis.warnings.length > 0) {
|
|
370
|
-
const criticalWarnings = analysis.warnings.filter(w =>
|
|
371
|
-
w.includes('empty') || w.includes('not detect')
|
|
372
|
-
);
|
|
373
|
-
if (criticalWarnings.length > 0) {
|
|
374
|
-
console.log('');
|
|
375
|
-
log(colors.yellow, '⚠️ Warnings:');
|
|
376
|
-
criticalWarnings.forEach(warning => {
|
|
377
|
-
log(colors.dim, ` • ${warning}`);
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
} catch (error) {
|
|
383
|
-
log(colors.dim, ' ⊙ Detection skipped (project may be empty)');
|
|
384
|
-
analysis = null;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Interactive prompts for generation (if not auto-generated)
|
|
389
|
-
if (analysis && analysis.domains.length > 0 && !autoGenerateDomains && !autoGenerateAgents) {
|
|
137
|
+
log(colors.green, 'Initialized agentful successfully!');
|
|
390
138
|
console.log('');
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
output: process.stdout
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
// Ask about domain structure
|
|
398
|
-
const generateStructure = await new Promise(resolve => {
|
|
399
|
-
rl.question(`✨ Generate domain structure and specialized agents? [Y/n] `, answer => {
|
|
400
|
-
resolve(answer.toLowerCase() !== 'n');
|
|
401
|
-
});
|
|
139
|
+
log(colors.dim, 'Created files:');
|
|
140
|
+
result.files.forEach(file => {
|
|
141
|
+
log(colors.green, ` ${file}`);
|
|
402
142
|
});
|
|
403
|
-
|
|
404
|
-
rl.close();
|
|
405
|
-
|
|
406
|
-
if (generateStructure) {
|
|
407
|
-
await generateAgentsAndDomains(targetDir, analysis);
|
|
408
|
-
}
|
|
409
|
-
} else if (autoGenerateDomains || autoGenerateAgents) {
|
|
410
143
|
console.log('');
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
domains: autoGenerateDomains
|
|
415
|
-
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
log(colors.red, `Failed to initialize: ${error.message}`);
|
|
146
|
+
process.exit(1);
|
|
416
147
|
}
|
|
417
148
|
|
|
418
|
-
//
|
|
149
|
+
// Update .gitignore
|
|
150
|
+
checkGitignore();
|
|
151
|
+
|
|
152
|
+
// Show next steps
|
|
419
153
|
console.log('');
|
|
420
|
-
log(colors.
|
|
154
|
+
log(colors.bright, 'Next Steps:');
|
|
421
155
|
console.log('');
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const productMdPath = path.join(targetDir, 'PRODUCT.md');
|
|
425
|
-
const claudeProductDir = path.join(targetDir, '.claude/product');
|
|
426
|
-
const usingHierarchical = fs.existsSync(claudeProductDir);
|
|
427
|
-
const usingFlat = fs.existsSync(productMdPath);
|
|
428
|
-
|
|
429
|
-
log(colors.bright, 'Next steps:');
|
|
156
|
+
log(colors.cyan, ' 1. Run: claude');
|
|
157
|
+
log(colors.cyan, ' 2. Type: /agentful-generate');
|
|
430
158
|
console.log('');
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
console.log(` ${colors.dim}→ Organized by domains (best for larger projects)${colors.reset}`);
|
|
436
|
-
if (analysis && analysis.domains.length > 0) {
|
|
437
|
-
console.log(` ${colors.dim}→ Detected ${analysis.domains.length} domain(s) with pre-configured directories${colors.reset}`);
|
|
438
|
-
}
|
|
439
|
-
} else if (usingFlat) {
|
|
440
|
-
console.log(` ${colors.green}✓ Created PRODUCT.md${colors.reset} (flat structure)`);
|
|
441
|
-
console.log(` ${colors.dim}→ Simple, single-file format (best for small projects)${colors.reset}`);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
console.log(` 2. ${colors.cyan}Run: claude${colors.reset}`);
|
|
445
|
-
console.log(` 3. ${colors.cyan}Type: /agentful${colors.reset} (natural) or ${colors.cyan}/agentful-start${colors.reset} (structured)`);
|
|
159
|
+
log(colors.dim, 'This will analyze your codebase and generate:');
|
|
160
|
+
log(colors.dim, ' - Specialized agents for your tech stack');
|
|
161
|
+
log(colors.dim, ' - Domain-specific agents (auth, billing, etc.)');
|
|
162
|
+
log(colors.dim, ' - Skills for frameworks you use');
|
|
446
163
|
console.log('');
|
|
447
|
-
|
|
448
|
-
if (usingHierarchical) {
|
|
449
|
-
log(colors.dim, '💡 Hierarchical structure benefits:');
|
|
450
|
-
log(colors.dim, ' • Organized by domain (e.g., Auth, Users, Billing)');
|
|
451
|
-
log(colors.dim, ' • Easier to manage large feature sets');
|
|
452
|
-
log(colors.dim, ' • Teams can work on different domains in parallel');
|
|
453
|
-
console.log('');
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
log(colors.dim, 'For extended development sessions with fewer interruptions:');
|
|
457
|
-
log(colors.cyan, ` /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"`);
|
|
164
|
+
log(colors.dim, 'Optional: Edit CLAUDE.md and PRODUCT.md first to customize.');
|
|
458
165
|
console.log('');
|
|
459
166
|
}
|
|
460
167
|
|
|
461
|
-
/**
|
|
462
|
-
* Generate agents and domain structure
|
|
463
|
-
*/
|
|
464
|
-
async function generateAgentsAndDomains(projectPath, analysis, options = {}) {
|
|
465
|
-
const { agents = true, domains = true } = options;
|
|
466
|
-
|
|
467
|
-
try {
|
|
468
|
-
// Generate domain structure
|
|
469
|
-
if (domains) {
|
|
470
|
-
log(colors.dim, '📁 Creating domain structure...');
|
|
471
|
-
const domainGenerator = new DomainStructureGenerator(projectPath, analysis);
|
|
472
|
-
const domainResult = await domainGenerator.generateDomainStructure();
|
|
473
|
-
log(colors.green, ` ✓ Generated ${domainResult.domains} domains with ${domainResult.features} features`);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Generate specialized agents
|
|
477
|
-
if (agents) {
|
|
478
|
-
log(colors.dim, '🤖 Generating specialized agents...');
|
|
479
|
-
const agentGenerator = new AgentGenerator(projectPath, analysis);
|
|
480
|
-
const agentResult = await agentGenerator.generateAgents();
|
|
481
|
-
|
|
482
|
-
const totalAgents = agentResult.core.length + agentResult.domains.length + agentResult.tech.length;
|
|
483
|
-
log(colors.green, ` ✓ Generated ${totalAgents} agents:`);
|
|
484
|
-
log(colors.dim, ` - ${agentResult.core.length} core agents`);
|
|
485
|
-
if (agentResult.domains.length > 0) {
|
|
486
|
-
log(colors.dim, ` - ${agentResult.domains.length} domain agents`);
|
|
487
|
-
}
|
|
488
|
-
if (agentResult.tech.length > 0) {
|
|
489
|
-
log(colors.dim, ` - ${agentResult.tech.length} tech-specific agents`);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
console.log('');
|
|
494
|
-
log(colors.green, '✨ Generation complete!');
|
|
495
|
-
log(colors.dim, ' Your agents are now contextually aware of your codebase.');
|
|
496
|
-
} catch (error) {
|
|
497
|
-
log(colors.red, `❌ Generation failed: ${error.message}`);
|
|
498
|
-
log(colors.dim, ' You can continue without it, or run: agentful generate');
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
168
|
function showStatus() {
|
|
503
|
-
const
|
|
169
|
+
const targetDir = process.cwd();
|
|
170
|
+
const agentfulDir = path.join(targetDir, '.agentful');
|
|
504
171
|
|
|
505
172
|
if (!fs.existsSync(agentfulDir)) {
|
|
506
|
-
log(colors.red, '
|
|
173
|
+
log(colors.red, 'agentful not initialized in this directory!');
|
|
507
174
|
log(colors.dim, 'Run: npx @itz4blitz/agentful init');
|
|
508
175
|
process.exit(1);
|
|
509
176
|
}
|
|
510
177
|
|
|
511
|
-
const statePath = path.join(agentfulDir, 'state.json');
|
|
512
|
-
const completionPath = path.join(agentfulDir, 'completion.json');
|
|
513
|
-
const decisionsPath = path.join(agentfulDir, 'decisions.json');
|
|
514
|
-
|
|
515
|
-
if (!fs.existsSync(statePath)) {
|
|
516
|
-
log(colors.red, '❌ State file missing!');
|
|
517
|
-
process.exit(1);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
const state = JSON.parse(fs.readFileSync(statePath, 'utf-8'));
|
|
521
|
-
const completion = fs.existsSync(completionPath)
|
|
522
|
-
? JSON.parse(fs.readFileSync(completionPath, 'utf-8'))
|
|
523
|
-
: null;
|
|
524
|
-
const decisions = fs.existsSync(decisionsPath)
|
|
525
|
-
? JSON.parse(fs.readFileSync(decisionsPath, 'utf-8'))
|
|
526
|
-
: null;
|
|
527
|
-
|
|
528
178
|
showBanner();
|
|
529
|
-
|
|
530
|
-
log(colors.bright, 'Current Status:');
|
|
531
|
-
console.log('');
|
|
532
|
-
|
|
533
|
-
// Show current work
|
|
534
|
-
if (state.current_task) {
|
|
535
|
-
log(colors.blue, `🔧 Working on: ${colors.reset}${state.current_task}`);
|
|
536
|
-
log(colors.dim, ` Phase: ${state.current_phase}`);
|
|
537
|
-
log(colors.dim, ` Iterations: ${state.iterations}`);
|
|
538
|
-
} else {
|
|
539
|
-
log(colors.dim, '💤 Idle - no active task');
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
console.log('');
|
|
543
|
-
|
|
544
|
-
// Show completion if available
|
|
545
|
-
if (completion) {
|
|
546
|
-
const percentage = completion.overall || 0;
|
|
547
|
-
const filled = Math.round(percentage / 5);
|
|
548
|
-
const bar = '█'.repeat(filled) + '░'.repeat(20 - filled);
|
|
549
|
-
|
|
550
|
-
log(colors.bright, 'Progress:');
|
|
551
|
-
log(colors.cyan, ` ${bar} ${percentage}%`);
|
|
552
|
-
console.log('');
|
|
553
|
-
|
|
554
|
-
// Show quality gates
|
|
555
|
-
if (completion.gates) {
|
|
556
|
-
log(colors.bright, 'Quality Gates:');
|
|
557
|
-
Object.entries(completion.gates).forEach(([gate, passed]) => {
|
|
558
|
-
const icon = passed ? '✅' : '❌';
|
|
559
|
-
const label = gate.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
560
|
-
log(passed ? colors.green : colors.red, ` ${icon} ${label}`);
|
|
561
|
-
});
|
|
562
|
-
console.log('');
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// Show pending decisions
|
|
566
|
-
if (decisions && decisions.pending && decisions.pending.length > 0) {
|
|
567
|
-
log(colors.yellow, `⚠️ ${decisions.pending.length} pending decisions:`);
|
|
568
|
-
decisions.pending.forEach((d, i) => {
|
|
569
|
-
log(colors.dim, ` ${i + 1}. ${d.question}`);
|
|
570
|
-
});
|
|
571
|
-
console.log('');
|
|
572
|
-
log(colors.cyan, ` Run: /agentful-decide`);
|
|
573
|
-
console.log('');
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
// Show next action
|
|
578
|
-
log(colors.bright, 'Next Actions:');
|
|
579
|
-
log(colors.cyan, ' • /agentful-start - Continue development');
|
|
580
|
-
log(colors.cyan, ' • /agentful-decide - Answer pending decisions');
|
|
581
|
-
log(colors.cyan, ' • /agentful-validate- Run quality checks');
|
|
179
|
+
log(colors.bright, 'Agentful Status:');
|
|
582
180
|
console.log('');
|
|
583
|
-
}
|
|
584
181
|
|
|
585
|
-
|
|
586
|
-
const
|
|
587
|
-
const detected = {
|
|
588
|
-
language: null,
|
|
589
|
-
framework: null,
|
|
590
|
-
dependencies: [],
|
|
591
|
-
devDependencies: []
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
// Check for package.json (Node.js/JavaScript/TypeScript)
|
|
595
|
-
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
596
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
182
|
+
// Helper to read JSON safely
|
|
183
|
+
const readJSON = (filepath) => {
|
|
597
184
|
try {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
detected.language = pkg.type === 'module' ? 'TypeScript/ESM' : 'JavaScript/TypeScript';
|
|
602
|
-
|
|
603
|
-
// Detect framework
|
|
604
|
-
if (detected.dependencies.includes('next')) {
|
|
605
|
-
detected.framework = 'Next.js';
|
|
606
|
-
} else if (detected.dependencies.includes('react')) {
|
|
607
|
-
detected.framework = 'React';
|
|
608
|
-
} else if (detected.dependencies.includes('vue')) {
|
|
609
|
-
detected.framework = 'Vue';
|
|
610
|
-
} else if (detected.dependencies.includes('express')) {
|
|
611
|
-
detected.framework = 'Express';
|
|
612
|
-
} else if (detected.dependencies.includes('nestjs')) {
|
|
613
|
-
detected.framework = 'NestJS';
|
|
614
|
-
}
|
|
615
|
-
} catch (err) {
|
|
616
|
-
log(colors.yellow, '⚠️ Could not parse package.json');
|
|
185
|
+
return fs.existsSync(filepath) ? JSON.parse(fs.readFileSync(filepath, 'utf-8')) : null;
|
|
186
|
+
} catch {
|
|
187
|
+
return null;
|
|
617
188
|
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
// Check for requirements.txt or pyproject.toml (Python)
|
|
621
|
-
const requirementsPath = path.join(targetDir, 'requirements.txt');
|
|
622
|
-
const pyprojectPath = path.join(targetDir, 'pyproject.toml');
|
|
623
|
-
if (fs.existsSync(requirementsPath) || fs.existsSync(pyprojectPath)) {
|
|
624
|
-
detected.language = 'Python';
|
|
625
|
-
const requirements = fs.existsSync(requirementsPath)
|
|
626
|
-
? fs.readFileSync(requirementsPath, 'utf-8')
|
|
627
|
-
: '';
|
|
628
|
-
if (requirements.includes('django')) detected.framework = 'Django';
|
|
629
|
-
else if (requirements.includes('flask')) detected.framework = 'Flask';
|
|
630
|
-
else if (requirements.includes('fastapi')) detected.framework = 'FastAPI';
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// Check for go.mod (Go)
|
|
634
|
-
if (fs.existsSync(path.join(targetDir, 'go.mod'))) {
|
|
635
|
-
detected.language = 'Go';
|
|
636
|
-
detected.framework = 'Standard Library';
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Check for Cargo.toml (Rust)
|
|
640
|
-
if (fs.existsSync(path.join(targetDir, 'Cargo.toml'))) {
|
|
641
|
-
detected.language = 'Rust';
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// Check for .csproj or .fsproj (C#/.NET)
|
|
645
|
-
const csprojFiles = fs.readdirSync(targetDir).filter(f => f.endsWith('.csproj'));
|
|
646
|
-
if (csprojFiles.length > 0) {
|
|
647
|
-
detected.language = 'C#';
|
|
648
|
-
detected.framework = 'ASP.NET';
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// Check for pom.xml (Java)
|
|
652
|
-
if (fs.existsSync(path.join(targetDir, 'pom.xml'))) {
|
|
653
|
-
detected.language = 'Java';
|
|
654
|
-
detected.framework = 'Maven';
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
return detected;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
function generateAgentPrompt(stack) {
|
|
661
|
-
let prompt = `# Tech Stack Analysis\n\n`;
|
|
662
|
-
prompt += `**Language**: ${stack.language || 'Unknown'}\n`;
|
|
663
|
-
prompt += `**Framework**: ${stack.framework || 'None'}\n\n`;
|
|
189
|
+
};
|
|
664
190
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
191
|
+
// Read state files
|
|
192
|
+
const state = readJSON(path.join(agentfulDir, 'state.json'));
|
|
193
|
+
const completion = readJSON(path.join(agentfulDir, 'completion.json'));
|
|
194
|
+
const decisions = readJSON(path.join(agentfulDir, 'decisions.json'));
|
|
195
|
+
|
|
196
|
+
// Display state
|
|
197
|
+
if (state) {
|
|
198
|
+
log(colors.green, 'State:');
|
|
199
|
+
log(colors.dim, ` Initialized: ${state.initialized || 'N/A'}`);
|
|
200
|
+
const agentCount = state.agents?.length || 0;
|
|
201
|
+
const skillCount = state.skills?.length || 0;
|
|
202
|
+
log(colors.dim, ` Agents: ${agentCount} ${agentCount === 0 ? '(run /agentful-agents)' : ''}`);
|
|
203
|
+
log(colors.dim, ` Skills: ${skillCount} ${skillCount === 0 ? '(run /agentful-skills)' : ''}`);
|
|
204
|
+
console.log('');
|
|
671
205
|
}
|
|
672
206
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
prompt += `- Generated agent list\n`;
|
|
682
|
-
prompt += `- Key conventions\n\n`;
|
|
683
|
-
prompt += `Then create project-specific agent files in \`.claude/agents/\` \n`;
|
|
684
|
-
prompt += `using the naming convention: \`[tech]-specialist.md\`\n\n`;
|
|
685
|
-
|
|
686
|
-
prompt += `## Example Agent Template\n\n`;
|
|
687
|
-
prompt += `\`\`\`markdown\n`;
|
|
688
|
-
prompt += `# [Tech] Specialist Agent\n\n`;
|
|
689
|
-
prompt += `---\n`;
|
|
690
|
-
prompt += `name: [tech]-specialist\n`;
|
|
691
|
-
prompt += `description: Expert in [Tech] development patterns\n`;
|
|
692
|
-
prompt += `model: sonnet\n\n`;
|
|
693
|
-
prompt += `## Context\n\n`;
|
|
694
|
-
prompt += `[Analyze actual code samples and list real patterns]\n\n`;
|
|
695
|
-
prompt += `## Conventions\n\n`;
|
|
696
|
-
prompt += `1. [Pattern from actual code]\n`;
|
|
697
|
-
prompt += `2. [Pattern from actual code]\n`;
|
|
698
|
-
prompt += `3. [Pattern from actual code]\n\n`;
|
|
699
|
-
prompt += `## Examples from Codebase\n\n`;
|
|
700
|
-
prompt += `\`\`\`[language]\n`;
|
|
701
|
-
prompt += `[Real example from sampled files]\n`;
|
|
702
|
-
prompt += `\`\`\`\n`;
|
|
703
|
-
prompt += `\`\`\`\n\n`;
|
|
704
|
-
|
|
705
|
-
prompt += `---\n\n`;
|
|
706
|
-
prompt += `**IMPORTANT**: \n`;
|
|
707
|
-
prompt += `- Sample REAL files, don't make up patterns\n`;
|
|
708
|
-
prompt += `- Include ACTUAL code examples from this project\n`;
|
|
709
|
-
prompt += `- Respect existing conventions, don't introduce new ones\n`;
|
|
710
|
-
prompt += `- Generate agents ONLY for technologies actually in use\n`;
|
|
711
|
-
|
|
712
|
-
return prompt;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
async function generateAgents() {
|
|
716
|
-
showBanner();
|
|
717
|
-
|
|
718
|
-
const agentfulDir = path.join(process.cwd(), '.agentful');
|
|
719
|
-
|
|
720
|
-
// Check if agentful is initialized
|
|
721
|
-
if (!fs.existsSync(agentfulDir)) {
|
|
722
|
-
log(colors.red, '❌ agentful not initialized in this directory!');
|
|
723
|
-
log(colors.dim, 'Run: npx @itz4blitz/agentful init');
|
|
724
|
-
process.exit(1);
|
|
207
|
+
// Display completion
|
|
208
|
+
if (completion) {
|
|
209
|
+
const agentComp = Object.keys(completion.agents || {}).length;
|
|
210
|
+
const skillComp = Object.keys(completion.skills || {}).length;
|
|
211
|
+
if (agentComp > 0 || skillComp > 0) {
|
|
212
|
+
log(colors.green, `Completions: ${agentComp} agents, ${skillComp} skills`);
|
|
213
|
+
console.log('');
|
|
214
|
+
}
|
|
725
215
|
}
|
|
726
216
|
|
|
727
|
-
//
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if (!stack.language) {
|
|
732
|
-
log(colors.yellow, '⚠️ Could not detect language/framework');
|
|
733
|
-
log(colors.dim, 'Supported: Node.js, Python, Go, Rust, C#, Java');
|
|
734
|
-
console.log('');
|
|
735
|
-
log(colors.cyan, 'Manually trigger architect analysis by running:');
|
|
736
|
-
log(colors.cyan, ' claude');
|
|
737
|
-
log(colors.cyan, ' Then invoke the architect agent');
|
|
217
|
+
// Display decisions
|
|
218
|
+
if (decisions?.decisions?.length > 0) {
|
|
219
|
+
log(colors.yellow, `Decisions: ${decisions.decisions.length} pending`);
|
|
738
220
|
console.log('');
|
|
739
|
-
return;
|
|
740
221
|
}
|
|
741
222
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
architecture.detected_stack = stack;
|
|
755
|
-
architecture.timestamp = new Date().toISOString();
|
|
756
|
-
|
|
757
|
-
fs.writeFileSync(archPath, JSON.stringify(architecture, null, 2));
|
|
758
|
-
|
|
759
|
-
console.log('');
|
|
760
|
-
log(colors.bright, 'Tech Stack Analysis Complete!');
|
|
761
|
-
console.log('');
|
|
762
|
-
|
|
763
|
-
log(colors.bright, 'Detected Stack:');
|
|
764
|
-
if (stack.language) log(colors.cyan, ` Language: ${stack.language}`);
|
|
765
|
-
if (stack.framework) log(colors.cyan, ` Framework: ${stack.framework}`);
|
|
766
|
-
if (stack.dependencies.length > 0) {
|
|
767
|
-
log(colors.cyan, ` Dependencies: ${stack.dependencies.length} packages`);
|
|
223
|
+
// Check generated files
|
|
224
|
+
const claudeDir = path.join(targetDir, '.claude');
|
|
225
|
+
const agentFiles = fs.existsSync(path.join(claudeDir, 'agents'))
|
|
226
|
+
? fs.readdirSync(path.join(claudeDir, 'agents')).filter(f => f.endsWith('.md'))
|
|
227
|
+
: [];
|
|
228
|
+
const skillFiles = fs.existsSync(path.join(claudeDir, 'skills'))
|
|
229
|
+
? fs.readdirSync(path.join(claudeDir, 'skills')).filter(f => f.endsWith('.md'))
|
|
230
|
+
: [];
|
|
231
|
+
|
|
232
|
+
if (agentFiles.length > 0) {
|
|
233
|
+
log(colors.green, `Generated: ${agentFiles.length} agent(s), ${skillFiles.length} skill(s)`);
|
|
234
|
+
console.log('');
|
|
768
235
|
}
|
|
769
|
-
console.log('');
|
|
770
|
-
|
|
771
|
-
log(colors.bright, 'Next Steps:');
|
|
772
|
-
console.log('');
|
|
773
|
-
log(colors.cyan, ' 1. Review .agentful/architecture.json');
|
|
774
|
-
log(colors.cyan, ' 2. Run: claude');
|
|
775
|
-
log(colors.cyan, ' 3. Type: /agentful-start');
|
|
776
|
-
log(colors.cyan, ' (Architect agent will generate specialized agents automatically)');
|
|
777
|
-
console.log('');
|
|
778
236
|
|
|
779
|
-
|
|
237
|
+
// Next actions
|
|
238
|
+
log(colors.bright, 'Claude Code Commands:');
|
|
239
|
+
log(colors.cyan, ' /agentful-agents - Generate agents');
|
|
240
|
+
log(colors.cyan, ' /agentful-skills - Generate skills');
|
|
241
|
+
log(colors.cyan, ' /agentful-start - Start workflow');
|
|
242
|
+
log(colors.cyan, ' /agentful - Product chat');
|
|
780
243
|
console.log('');
|
|
781
244
|
}
|
|
782
245
|
|
|
@@ -787,42 +250,32 @@ async function main() {
|
|
|
787
250
|
|
|
788
251
|
switch (command) {
|
|
789
252
|
case 'init':
|
|
790
|
-
|
|
791
|
-
const initOptions = {
|
|
792
|
-
bare: args.includes('--bare'),
|
|
793
|
-
smart: !args.includes('--no-smart'),
|
|
794
|
-
deep: args.includes('--deep'),
|
|
795
|
-
generateAgents: args.includes('--generate-agents'),
|
|
796
|
-
generateDomains: args.includes('--generate-domains')
|
|
797
|
-
};
|
|
798
|
-
await initagentful(initOptions);
|
|
253
|
+
await init();
|
|
799
254
|
break;
|
|
800
255
|
|
|
801
256
|
case 'status':
|
|
802
257
|
showStatus();
|
|
803
258
|
break;
|
|
804
259
|
|
|
805
|
-
case '
|
|
806
|
-
await generateAgents();
|
|
807
|
-
break;
|
|
808
|
-
|
|
260
|
+
case 'help':
|
|
809
261
|
case '--help':
|
|
810
262
|
case '-h':
|
|
811
|
-
case 'help':
|
|
812
263
|
showHelp();
|
|
813
264
|
break;
|
|
814
265
|
|
|
266
|
+
case 'version':
|
|
815
267
|
case '--version':
|
|
816
268
|
case '-v':
|
|
817
269
|
showVersion();
|
|
818
270
|
break;
|
|
819
271
|
|
|
820
272
|
default:
|
|
821
|
-
if (!command
|
|
273
|
+
if (!command) {
|
|
822
274
|
showHelp();
|
|
823
275
|
} else {
|
|
824
276
|
log(colors.red, `Unknown command: ${command}`);
|
|
825
|
-
log(
|
|
277
|
+
console.log('');
|
|
278
|
+
log(colors.dim, 'Run: agentful help');
|
|
826
279
|
process.exit(1);
|
|
827
280
|
}
|
|
828
281
|
}
|