@claude-flow/codex 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +301 -0
  2. package/dist/cli.d.ts +9 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +649 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/generators/agents-md.d.ts +12 -0
  7. package/dist/generators/agents-md.d.ts.map +1 -0
  8. package/dist/generators/agents-md.js +641 -0
  9. package/dist/generators/agents-md.js.map +1 -0
  10. package/dist/generators/config-toml.d.ts +74 -0
  11. package/dist/generators/config-toml.d.ts.map +1 -0
  12. package/dist/generators/config-toml.js +910 -0
  13. package/dist/generators/config-toml.js.map +1 -0
  14. package/dist/generators/index.d.ts +9 -0
  15. package/dist/generators/index.d.ts.map +1 -0
  16. package/dist/generators/index.js +9 -0
  17. package/dist/generators/index.js.map +1 -0
  18. package/dist/generators/skill-md.d.ts +20 -0
  19. package/dist/generators/skill-md.d.ts.map +1 -0
  20. package/dist/generators/skill-md.js +946 -0
  21. package/dist/generators/skill-md.js.map +1 -0
  22. package/dist/index.d.ts +45 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +46 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/initializer.d.ts +87 -0
  27. package/dist/initializer.d.ts.map +1 -0
  28. package/dist/initializer.js +666 -0
  29. package/dist/initializer.js.map +1 -0
  30. package/dist/migrations/index.d.ts +114 -0
  31. package/dist/migrations/index.d.ts.map +1 -0
  32. package/dist/migrations/index.js +856 -0
  33. package/dist/migrations/index.js.map +1 -0
  34. package/dist/templates/index.d.ts +92 -0
  35. package/dist/templates/index.d.ts.map +1 -0
  36. package/dist/templates/index.js +284 -0
  37. package/dist/templates/index.js.map +1 -0
  38. package/dist/types.d.ts +218 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +8 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/validators/index.d.ts +42 -0
  43. package/dist/validators/index.d.ts.map +1 -0
  44. package/dist/validators/index.js +929 -0
  45. package/dist/validators/index.js.map +1 -0
  46. package/package.json +88 -0
package/dist/cli.js ADDED
@@ -0,0 +1,649 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @claude-flow/codex - CLI
4
+ *
5
+ * Command-line interface for Codex integration
6
+ * Part of the coflow rebranding initiative
7
+ */
8
+ import { Command } from 'commander';
9
+ import chalk from 'chalk';
10
+ import { CodexInitializer } from './initializer.js';
11
+ import { validateAgentsMd, validateSkillMd, validateConfigToml } from './validators/index.js';
12
+ import { migrateFromClaudeCode, analyzeClaudeMd, generateMigrationReport } from './migrations/index.js';
13
+ import { listTemplates, BUILT_IN_SKILLS } from './templates/index.js';
14
+ import { generateSkillMd } from './generators/skill-md.js';
15
+ import { VERSION, PACKAGE_INFO } from './index.js';
16
+ import fs from 'fs-extra';
17
+ import path from 'path';
18
+ const program = new Command();
19
+ // Custom error handler for better output
20
+ function handleError(error, message) {
21
+ const errorMessage = error instanceof Error ? error.message : String(error);
22
+ console.error(chalk.red.bold('\nError:'), chalk.red(message ?? errorMessage));
23
+ if (error instanceof Error && error.stack && process.env.DEBUG) {
24
+ console.error(chalk.gray('\nStack trace:'));
25
+ console.error(chalk.gray(error.stack));
26
+ }
27
+ process.exit(1);
28
+ }
29
+ // Validate project path exists and is accessible
30
+ async function validatePath(projectPath) {
31
+ const resolvedPath = path.resolve(projectPath);
32
+ try {
33
+ const stats = await fs.stat(resolvedPath);
34
+ if (!stats.isDirectory()) {
35
+ throw new Error(`Path is not a directory: ${resolvedPath}`);
36
+ }
37
+ return resolvedPath;
38
+ }
39
+ catch (error) {
40
+ if (error.code === 'ENOENT') {
41
+ // Directory doesn't exist, try to create it
42
+ console.log(chalk.yellow(`Creating directory: ${resolvedPath}`));
43
+ await fs.ensureDir(resolvedPath);
44
+ return resolvedPath;
45
+ }
46
+ throw error;
47
+ }
48
+ }
49
+ // Validate skill name format
50
+ function validateSkillName(name) {
51
+ const validPattern = /^[a-z][a-z0-9-]*$/;
52
+ return validPattern.test(name);
53
+ }
54
+ // Print banner
55
+ function printBanner() {
56
+ console.log(chalk.cyan.bold('\n Claude Flow Codex'));
57
+ console.log(chalk.gray(' OpenAI Codex integration for Claude Flow'));
58
+ console.log(chalk.gray(' ----------------------------------------\n'));
59
+ }
60
+ program
61
+ .name('claude-flow-codex')
62
+ .description('OpenAI Codex integration for Claude Flow - Part of the coflow ecosystem')
63
+ .version(VERSION, '-v, --version', 'Display version number')
64
+ .option('--debug', 'Enable debug mode', false)
65
+ .hook('preAction', (thisCommand) => {
66
+ if (thisCommand.opts().debug) {
67
+ process.env.DEBUG = 'true';
68
+ }
69
+ });
70
+ // Init command
71
+ program
72
+ .command('init')
73
+ .description('Initialize a new Codex project with AGENTS.md and skills')
74
+ .option('-t, --template <template>', 'Template to use (minimal, default, full, enterprise)', 'default')
75
+ .option('-s, --skills <skills>', 'Comma-separated list of skills to include')
76
+ .option('-f, --force', 'Overwrite existing files', false)
77
+ .option('--dual', 'Generate both Codex and Claude Code configurations', false)
78
+ .option('-p, --path <path>', 'Project path', process.cwd())
79
+ .option('-q, --quiet', 'Suppress verbose output', false)
80
+ .action(async (options) => {
81
+ try {
82
+ if (!options.quiet) {
83
+ printBanner();
84
+ }
85
+ // Validate template
86
+ const validTemplates = ['minimal', 'default', 'full', 'enterprise'];
87
+ if (!validTemplates.includes(options.template)) {
88
+ console.error(chalk.red(`Invalid template: ${options.template}`));
89
+ console.log(chalk.gray(`Valid templates: ${validTemplates.join(', ')}`));
90
+ process.exit(1);
91
+ }
92
+ const projectPath = await validatePath(options.path);
93
+ console.log(chalk.blue('Initializing Codex project...'));
94
+ console.log(chalk.gray(` Path: ${projectPath}`));
95
+ console.log(chalk.gray(` Template: ${options.template}`));
96
+ if (options.skills) {
97
+ console.log(chalk.gray(` Skills: ${options.skills}`));
98
+ }
99
+ if (options.force) {
100
+ console.log(chalk.yellow(' Force: enabled (will overwrite existing files)'));
101
+ }
102
+ if (options.dual) {
103
+ console.log(chalk.gray(' Mode: dual (Codex + Claude Code)'));
104
+ }
105
+ const initializer = new CodexInitializer();
106
+ const skills = options.skills?.split(',').map((s) => s.trim()).filter(Boolean);
107
+ // Validate skill names if provided
108
+ if (skills) {
109
+ for (const skill of skills) {
110
+ if (!validateSkillName(skill)) {
111
+ console.error(chalk.red(`Invalid skill name: ${skill}`));
112
+ console.log(chalk.gray('Skill names must be kebab-case (lowercase letters, numbers, hyphens)'));
113
+ process.exit(1);
114
+ }
115
+ }
116
+ }
117
+ const result = await initializer.initialize({
118
+ projectPath,
119
+ template: options.template,
120
+ skills,
121
+ force: options.force,
122
+ dual: options.dual,
123
+ });
124
+ if (result.success) {
125
+ console.log(chalk.green.bold('\n Project initialized successfully!'));
126
+ if (result.filesCreated.length > 0) {
127
+ console.log(chalk.white('\n Files created:'));
128
+ for (const file of result.filesCreated) {
129
+ console.log(chalk.gray(` ${chalk.green('+')} ${file}`));
130
+ }
131
+ }
132
+ if (result.skillsGenerated.length > 0) {
133
+ console.log(chalk.white('\n Skills generated:'));
134
+ for (const skill of result.skillsGenerated) {
135
+ console.log(chalk.gray(` ${chalk.cyan('$')}${skill}`));
136
+ }
137
+ }
138
+ if (result.warnings && result.warnings.length > 0) {
139
+ console.log(chalk.yellow('\n Warnings:'));
140
+ for (const warning of result.warnings) {
141
+ console.log(chalk.yellow(` ! ${warning}`));
142
+ }
143
+ }
144
+ console.log(chalk.blue.bold('\n Next steps:'));
145
+ console.log(chalk.gray(' 1. Review AGENTS.md and customize for your project'));
146
+ console.log(chalk.gray(' 2. Review .agents/config.toml settings'));
147
+ console.log(chalk.gray(' 3. Start using skills with $skill-name syntax'));
148
+ console.log();
149
+ }
150
+ else {
151
+ console.log(chalk.red.bold('\n Initialization failed'));
152
+ if (result.errors) {
153
+ for (const error of result.errors) {
154
+ console.log(chalk.red(` - ${error}`));
155
+ }
156
+ }
157
+ process.exit(1);
158
+ }
159
+ }
160
+ catch (error) {
161
+ handleError(error, 'Failed to initialize project');
162
+ }
163
+ });
164
+ // Generate skill command
165
+ program
166
+ .command('generate-skill')
167
+ .alias('gs')
168
+ .description('Generate a new SKILL.md file')
169
+ .requiredOption('-n, --name <name>', 'Skill name (kebab-case)')
170
+ .option('-d, --description <description>', 'Skill description')
171
+ .option('-t, --triggers <triggers>', 'Comma-separated trigger conditions')
172
+ .option('-s, --skip <skip>', 'Comma-separated skip conditions')
173
+ .option('-p, --path <path>', 'Output path', process.cwd())
174
+ .option('--dry-run', 'Show what would be generated without writing', false)
175
+ .action(async (options) => {
176
+ try {
177
+ printBanner();
178
+ // Validate skill name
179
+ if (!validateSkillName(options.name)) {
180
+ console.error(chalk.red(`Invalid skill name: ${options.name}`));
181
+ console.log(chalk.gray('Skill names must be kebab-case (lowercase letters, numbers, hyphens)'));
182
+ console.log(chalk.gray('Examples: my-skill, code-analyzer, data-processor'));
183
+ process.exit(1);
184
+ }
185
+ const projectPath = await validatePath(options.path);
186
+ console.log(chalk.blue(`Generating skill: ${chalk.white(options.name)}`));
187
+ const triggers = options.triggers?.split(',').map((s) => s.trim()).filter(Boolean);
188
+ const skipWhen = options.skip?.split(',').map((s) => s.trim()).filter(Boolean);
189
+ const skillMd = await generateSkillMd({
190
+ name: options.name,
191
+ description: options.description ?? `Custom skill: ${options.name}`,
192
+ triggers: triggers ?? ['Define when to trigger this skill'],
193
+ skipWhen: skipWhen ?? ['Define when to skip this skill'],
194
+ });
195
+ if (options.dryRun) {
196
+ console.log(chalk.yellow('\nDry run - would generate:'));
197
+ console.log(chalk.gray('---'));
198
+ console.log(skillMd);
199
+ console.log(chalk.gray('---'));
200
+ return;
201
+ }
202
+ const skillDir = path.join(projectPath, '.agents', 'skills', options.name);
203
+ await fs.ensureDir(skillDir);
204
+ const skillPath = path.join(skillDir, 'SKILL.md');
205
+ // Check if skill already exists
206
+ if (await fs.pathExists(skillPath)) {
207
+ console.log(chalk.yellow(`Skill already exists: ${skillPath}`));
208
+ console.log(chalk.gray('Use --force to overwrite (not yet implemented)'));
209
+ process.exit(1);
210
+ }
211
+ await fs.writeFile(skillPath, skillMd);
212
+ console.log(chalk.green.bold(`\n Skill created successfully!`));
213
+ console.log(chalk.gray(` Path: ${skillPath}`));
214
+ console.log(chalk.gray(` Use: ${chalk.cyan('$' + options.name)}`));
215
+ console.log();
216
+ }
217
+ catch (error) {
218
+ handleError(error, 'Failed to generate skill');
219
+ }
220
+ });
221
+ // Validate command
222
+ program
223
+ .command('validate')
224
+ .alias('check')
225
+ .description('Validate AGENTS.md, SKILL.md, or config.toml files')
226
+ .option('-f, --file <file>', 'File to validate')
227
+ .option('-p, --path <path>', 'Project path to validate all files', process.cwd())
228
+ .option('--fix', 'Attempt to fix issues (not yet implemented)', false)
229
+ .option('--strict', 'Treat warnings as errors', false)
230
+ .action(async (options) => {
231
+ try {
232
+ printBanner();
233
+ const projectPath = path.resolve(options.path);
234
+ const filesToValidate = [];
235
+ if (options.file) {
236
+ // Validate specific file
237
+ const filePath = path.resolve(options.file);
238
+ if (!await fs.pathExists(filePath)) {
239
+ console.error(chalk.red(`File not found: ${filePath}`));
240
+ process.exit(1);
241
+ }
242
+ const fileName = path.basename(filePath).toLowerCase();
243
+ if (fileName === 'agents.md') {
244
+ filesToValidate.push({ path: filePath, type: 'agents' });
245
+ }
246
+ else if (fileName === 'skill.md') {
247
+ filesToValidate.push({ path: filePath, type: 'skill' });
248
+ }
249
+ else if (fileName === 'config.toml') {
250
+ filesToValidate.push({ path: filePath, type: 'config' });
251
+ }
252
+ else {
253
+ console.error(chalk.red(`Unknown file type: ${fileName}`));
254
+ console.log(chalk.gray('Supported files: AGENTS.md, SKILL.md, config.toml'));
255
+ process.exit(1);
256
+ }
257
+ }
258
+ else {
259
+ // Validate all files in project
260
+ console.log(chalk.blue(`Scanning project: ${projectPath}`));
261
+ const agentsMd = path.join(projectPath, 'AGENTS.md');
262
+ const configToml = path.join(projectPath, '.agents', 'config.toml');
263
+ if (await fs.pathExists(agentsMd)) {
264
+ filesToValidate.push({ path: agentsMd, type: 'agents' });
265
+ }
266
+ if (await fs.pathExists(configToml)) {
267
+ filesToValidate.push({ path: configToml, type: 'config' });
268
+ }
269
+ // Find skill files
270
+ const skillsDir = path.join(projectPath, '.agents', 'skills');
271
+ if (await fs.pathExists(skillsDir)) {
272
+ try {
273
+ const skills = await fs.readdir(skillsDir);
274
+ for (const skill of skills) {
275
+ const skillPath = path.join(skillsDir, skill);
276
+ const skillStats = await fs.stat(skillPath);
277
+ if (skillStats.isDirectory()) {
278
+ const skillMd = path.join(skillPath, 'SKILL.md');
279
+ if (await fs.pathExists(skillMd)) {
280
+ filesToValidate.push({ path: skillMd, type: 'skill' });
281
+ }
282
+ }
283
+ }
284
+ }
285
+ catch {
286
+ // Ignore errors reading skills directory
287
+ }
288
+ }
289
+ }
290
+ if (filesToValidate.length === 0) {
291
+ console.log(chalk.yellow('No files found to validate'));
292
+ console.log(chalk.gray('Run `claude-flow-codex init` to create a project'));
293
+ return;
294
+ }
295
+ console.log(chalk.blue(`\nValidating ${filesToValidate.length} file(s)...\n`));
296
+ let hasErrors = false;
297
+ let hasWarnings = false;
298
+ let totalErrors = 0;
299
+ let totalWarnings = 0;
300
+ for (const file of filesToValidate) {
301
+ let content;
302
+ try {
303
+ content = await fs.readFile(file.path, 'utf-8');
304
+ }
305
+ catch (error) {
306
+ console.log(chalk.red(` ! Cannot read: ${file.path}`));
307
+ hasErrors = true;
308
+ continue;
309
+ }
310
+ let result;
311
+ switch (file.type) {
312
+ case 'agents':
313
+ result = await validateAgentsMd(content);
314
+ break;
315
+ case 'skill':
316
+ result = await validateSkillMd(content);
317
+ break;
318
+ case 'config':
319
+ result = await validateConfigToml(content);
320
+ break;
321
+ }
322
+ const relativePath = path.relative(projectPath, file.path);
323
+ if (result.valid && result.warnings.length === 0) {
324
+ console.log(chalk.green(` ${chalk.green.bold('PASS')} ${relativePath}`));
325
+ }
326
+ else if (result.valid) {
327
+ console.log(chalk.yellow(` ${chalk.yellow.bold('WARN')} ${relativePath}`));
328
+ hasWarnings = true;
329
+ }
330
+ else {
331
+ console.log(chalk.red(` ${chalk.red.bold('FAIL')} ${relativePath}`));
332
+ hasErrors = true;
333
+ }
334
+ for (const error of result.errors) {
335
+ totalErrors++;
336
+ const lineInfo = error.line ? chalk.gray(` (line ${error.line})`) : '';
337
+ console.log(chalk.red(` ${chalk.red('x')} ${error.message}${lineInfo}`));
338
+ }
339
+ for (const warning of result.warnings) {
340
+ totalWarnings++;
341
+ console.log(chalk.yellow(` ${chalk.yellow('!')} ${warning.message}`));
342
+ if (warning.suggestion) {
343
+ console.log(chalk.gray(` ${warning.suggestion}`));
344
+ }
345
+ }
346
+ }
347
+ // Summary
348
+ console.log();
349
+ if (hasErrors) {
350
+ console.log(chalk.red.bold(` ${totalErrors} error(s), ${totalWarnings} warning(s)`));
351
+ process.exit(1);
352
+ }
353
+ else if (hasWarnings && options.strict) {
354
+ console.log(chalk.yellow.bold(` ${totalWarnings} warning(s) (strict mode)`));
355
+ process.exit(1);
356
+ }
357
+ else if (hasWarnings) {
358
+ console.log(chalk.yellow(` All files valid with ${totalWarnings} warning(s)`));
359
+ }
360
+ else {
361
+ console.log(chalk.green.bold(' All files valid!'));
362
+ }
363
+ }
364
+ catch (error) {
365
+ handleError(error, 'Validation failed');
366
+ }
367
+ });
368
+ // Migrate command
369
+ program
370
+ .command('migrate')
371
+ .description('Migrate from Claude Code (CLAUDE.md) to Codex (AGENTS.md)')
372
+ .option('-f, --from <file>', 'Source CLAUDE.md file', 'CLAUDE.md')
373
+ .option('-o, --output <path>', 'Output directory', process.cwd())
374
+ .option('--analyze-only', 'Only analyze, do not generate files', false)
375
+ .option('--generate-skills', 'Generate skill files from detected patterns', true)
376
+ .option('--preserve-comments', 'Preserve comments from original file', true)
377
+ .action(async (options) => {
378
+ try {
379
+ printBanner();
380
+ const sourcePath = path.resolve(options.from);
381
+ if (!await fs.pathExists(sourcePath)) {
382
+ console.error(chalk.red(`Source file not found: ${sourcePath}`));
383
+ console.log(chalk.gray('\nLooking for CLAUDE.md in the current directory.'));
384
+ console.log(chalk.gray('Use --from <path> to specify a different source file.'));
385
+ process.exit(1);
386
+ }
387
+ let content;
388
+ try {
389
+ content = await fs.readFile(sourcePath, 'utf-8');
390
+ }
391
+ catch (error) {
392
+ handleError(error, `Cannot read source file: ${sourcePath}`);
393
+ }
394
+ if (options.analyzeOnly) {
395
+ console.log(chalk.blue('Analyzing CLAUDE.md...'));
396
+ console.log(chalk.gray(`Source: ${sourcePath}\n`));
397
+ const analysis = await analyzeClaudeMd(content);
398
+ console.log(chalk.white.bold('Sections found:'));
399
+ if (analysis.sections.length > 0) {
400
+ for (const section of analysis.sections) {
401
+ console.log(chalk.gray(` - ${section}`));
402
+ }
403
+ }
404
+ else {
405
+ console.log(chalk.gray(' (none)'));
406
+ }
407
+ console.log(chalk.white.bold('\nSkills detected:'));
408
+ if (analysis.skills.length > 0) {
409
+ for (const skill of analysis.skills) {
410
+ console.log(chalk.gray(` - /${skill} ${chalk.cyan('->')} $${skill}`));
411
+ }
412
+ }
413
+ else {
414
+ console.log(chalk.gray(' (none)'));
415
+ }
416
+ console.log(chalk.white.bold('\nHooks used:'));
417
+ if (analysis.hooks.length > 0) {
418
+ for (const hook of analysis.hooks) {
419
+ console.log(chalk.gray(` - ${hook}`));
420
+ }
421
+ }
422
+ else {
423
+ console.log(chalk.gray(' (none)'));
424
+ }
425
+ console.log(chalk.white.bold('\nCustom instructions:'));
426
+ if (analysis.customInstructions.length > 0) {
427
+ for (const instruction of analysis.customInstructions.slice(0, 5)) {
428
+ console.log(chalk.gray(` - ${instruction.substring(0, 60)}...`));
429
+ }
430
+ if (analysis.customInstructions.length > 5) {
431
+ console.log(chalk.gray(` ... and ${analysis.customInstructions.length - 5} more`));
432
+ }
433
+ }
434
+ else {
435
+ console.log(chalk.gray(' (none)'));
436
+ }
437
+ if (analysis.warnings.length > 0) {
438
+ console.log(chalk.yellow.bold('\nMigration warnings:'));
439
+ for (const warning of analysis.warnings) {
440
+ console.log(chalk.yellow(` ! ${warning}`));
441
+ }
442
+ }
443
+ console.log();
444
+ }
445
+ else {
446
+ console.log(chalk.blue('Migrating to Codex...'));
447
+ console.log(chalk.gray(`Source: ${sourcePath}`));
448
+ console.log(chalk.gray(`Output: ${path.resolve(options.output)}\n`));
449
+ const result = await migrateFromClaudeCode({
450
+ sourcePath,
451
+ targetPath: options.output,
452
+ generateSkills: options.generateSkills,
453
+ preserveComments: options.preserveComments,
454
+ });
455
+ const report = generateMigrationReport(result);
456
+ console.log(report);
457
+ if (result.success) {
458
+ console.log(chalk.green.bold('\n Migration completed successfully!'));
459
+ console.log(chalk.gray('\n Next steps:'));
460
+ console.log(chalk.gray(' 1. Review the generated AGENTS.md'));
461
+ console.log(chalk.gray(' 2. Check skill invocation syntax (/ -> $)'));
462
+ console.log(chalk.gray(' 3. Run `claude-flow-codex validate` to verify'));
463
+ console.log();
464
+ }
465
+ else {
466
+ console.log(chalk.red.bold('\n Migration failed'));
467
+ process.exit(1);
468
+ }
469
+ }
470
+ }
471
+ catch (error) {
472
+ handleError(error, 'Migration failed');
473
+ }
474
+ });
475
+ // Templates command
476
+ program
477
+ .command('templates')
478
+ .alias('list-templates')
479
+ .description('List available templates')
480
+ .option('--json', 'Output as JSON', false)
481
+ .action((options) => {
482
+ try {
483
+ const templates = listTemplates();
484
+ if (options.json) {
485
+ console.log(JSON.stringify(templates, null, 2));
486
+ return;
487
+ }
488
+ printBanner();
489
+ console.log(chalk.white.bold('Available templates:\n'));
490
+ for (const template of templates) {
491
+ console.log(chalk.cyan.bold(` ${template.name}`));
492
+ console.log(chalk.gray(` ${template.description}`));
493
+ console.log(chalk.gray(` Skills: ${template.skillCount} included`));
494
+ console.log();
495
+ }
496
+ console.log(chalk.gray('Use: claude-flow-codex init --template <name>'));
497
+ console.log();
498
+ }
499
+ catch (error) {
500
+ handleError(error, 'Failed to list templates');
501
+ }
502
+ });
503
+ // Skills command
504
+ program
505
+ .command('skills')
506
+ .alias('list-skills')
507
+ .description('List available built-in skills')
508
+ .option('--json', 'Output as JSON', false)
509
+ .action((options) => {
510
+ try {
511
+ if (options.json) {
512
+ console.log(JSON.stringify(BUILT_IN_SKILLS, null, 2));
513
+ return;
514
+ }
515
+ printBanner();
516
+ console.log(chalk.white.bold('Built-in skills:\n'));
517
+ for (const [name, info] of Object.entries(BUILT_IN_SKILLS)) {
518
+ console.log(chalk.cyan(` $${name}`));
519
+ console.log(chalk.gray(` ${info.description}`));
520
+ console.log(chalk.gray(` Category: ${info.category}`));
521
+ console.log();
522
+ }
523
+ console.log(chalk.gray('Use: claude-flow-codex generate-skill -n <name> to create a custom skill'));
524
+ console.log();
525
+ }
526
+ catch (error) {
527
+ handleError(error, 'Failed to list skills');
528
+ }
529
+ });
530
+ // Info command
531
+ program
532
+ .command('info')
533
+ .description('Show package information')
534
+ .option('--json', 'Output as JSON', false)
535
+ .action((options) => {
536
+ try {
537
+ if (options.json) {
538
+ console.log(JSON.stringify(PACKAGE_INFO, null, 2));
539
+ return;
540
+ }
541
+ console.log(chalk.cyan.bold('\n @claude-flow/codex'));
542
+ console.log(chalk.gray(' ' + '='.repeat(40)));
543
+ console.log(chalk.white(` Version: ${PACKAGE_INFO.version}`));
544
+ console.log(chalk.white(` Description: ${PACKAGE_INFO.description}`));
545
+ console.log(chalk.white(` Future: ${PACKAGE_INFO.futureUmbrella} (umbrella package)`));
546
+ console.log(chalk.white(` Repository: ${PACKAGE_INFO.repository}`));
547
+ console.log(chalk.gray(' ' + '='.repeat(40)));
548
+ console.log(chalk.gray('\n Part of the coflow rebranding initiative'));
549
+ console.log();
550
+ }
551
+ catch (error) {
552
+ handleError(error, 'Failed to show info');
553
+ }
554
+ });
555
+ // Doctor command - check system health
556
+ program
557
+ .command('doctor')
558
+ .description('Check system health and dependencies')
559
+ .action(async () => {
560
+ try {
561
+ printBanner();
562
+ console.log(chalk.blue('Running health checks...\n'));
563
+ const checks = [];
564
+ // Check Node.js version
565
+ const nodeVersion = process.version;
566
+ const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0] ?? '0', 10);
567
+ if (nodeMajor >= 18) {
568
+ checks.push({ name: 'Node.js', status: 'pass', message: `${nodeVersion} (>= 18 required)` });
569
+ }
570
+ else {
571
+ checks.push({ name: 'Node.js', status: 'fail', message: `${nodeVersion} (>= 18 required)` });
572
+ }
573
+ // Check for AGENTS.md in current directory
574
+ const agentsMdExists = await fs.pathExists(path.join(process.cwd(), 'AGENTS.md'));
575
+ if (agentsMdExists) {
576
+ checks.push({ name: 'AGENTS.md', status: 'pass', message: 'Found in current directory' });
577
+ }
578
+ else {
579
+ checks.push({ name: 'AGENTS.md', status: 'warn', message: 'Not found - run init to create' });
580
+ }
581
+ // Check for .agents directory
582
+ const agentsDir = await fs.pathExists(path.join(process.cwd(), '.agents'));
583
+ if (agentsDir) {
584
+ checks.push({ name: '.agents/', status: 'pass', message: 'Directory exists' });
585
+ }
586
+ else {
587
+ checks.push({ name: '.agents/', status: 'warn', message: 'Not found - run init to create' });
588
+ }
589
+ // Check for config.toml
590
+ const configExists = await fs.pathExists(path.join(process.cwd(), '.agents', 'config.toml'));
591
+ if (configExists) {
592
+ checks.push({ name: 'config.toml', status: 'pass', message: 'Found in .agents/' });
593
+ }
594
+ else {
595
+ checks.push({ name: 'config.toml', status: 'warn', message: 'Not found' });
596
+ }
597
+ // Check for git
598
+ try {
599
+ const gitExists = await fs.pathExists(path.join(process.cwd(), '.git'));
600
+ if (gitExists) {
601
+ checks.push({ name: 'Git', status: 'pass', message: 'Repository detected' });
602
+ }
603
+ else {
604
+ checks.push({ name: 'Git', status: 'warn', message: 'Not a git repository' });
605
+ }
606
+ }
607
+ catch {
608
+ checks.push({ name: 'Git', status: 'warn', message: 'Cannot check' });
609
+ }
610
+ // Print results
611
+ let hasFailures = false;
612
+ for (const check of checks) {
613
+ const icon = check.status === 'pass' ? chalk.green('PASS')
614
+ : check.status === 'warn' ? chalk.yellow('WARN')
615
+ : chalk.red('FAIL');
616
+ console.log(` ${icon} ${chalk.white(check.name)}`);
617
+ console.log(chalk.gray(` ${check.message}`));
618
+ if (check.status === 'fail') {
619
+ hasFailures = true;
620
+ }
621
+ }
622
+ console.log();
623
+ if (hasFailures) {
624
+ console.log(chalk.red.bold(' Some checks failed'));
625
+ process.exit(1);
626
+ }
627
+ else {
628
+ console.log(chalk.green.bold(' All checks passed!'));
629
+ }
630
+ console.log();
631
+ }
632
+ catch (error) {
633
+ handleError(error, 'Health check failed');
634
+ }
635
+ });
636
+ // Error handling for unknown commands
637
+ program.on('command:*', () => {
638
+ console.error(chalk.red(`Invalid command: ${program.args.join(' ')}`));
639
+ console.log(chalk.gray(`Run ${chalk.white('claude-flow-codex --help')} for available commands.`));
640
+ process.exit(1);
641
+ });
642
+ // Parse and run
643
+ program.parse();
644
+ // If no command provided, show help
645
+ if (!process.argv.slice(2).length) {
646
+ printBanner();
647
+ program.outputHelp();
648
+ }
649
+ //# sourceMappingURL=cli.js.map