@defai.digital/ax-cli 3.15.26 → 4.0.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 (99) hide show
  1. package/README.md +67 -21
  2. package/config-defaults/prompts.yaml +5 -0
  3. package/dist/agent/execution/tool-executor.js +47 -1
  4. package/dist/agent/execution/tool-executor.js.map +1 -1
  5. package/dist/agent/llm-agent.js +4 -4
  6. package/dist/agent/llm-agent.js.map +1 -1
  7. package/dist/agent/parallel-tools.js +1 -0
  8. package/dist/agent/parallel-tools.js.map +1 -1
  9. package/dist/commands/cache.js +37 -34
  10. package/dist/commands/cache.js.map +1 -1
  11. package/dist/commands/doctor.js +111 -65
  12. package/dist/commands/doctor.js.map +1 -1
  13. package/dist/commands/init/wizard.js +10 -12
  14. package/dist/commands/init/wizard.js.map +1 -1
  15. package/dist/commands/init.d.ts +3 -3
  16. package/dist/commands/init.js +173 -25
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/mcp.js +106 -55
  19. package/dist/commands/mcp.js.map +1 -1
  20. package/dist/commands/setup.d.ts +0 -1
  21. package/dist/commands/setup.js +33 -194
  22. package/dist/commands/setup.js.map +1 -1
  23. package/dist/commands/usage.js +45 -51
  24. package/dist/commands/usage.js.map +1 -1
  25. package/dist/index.js +3 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/llm/tools.d.ts +2 -9
  28. package/dist/llm/tools.js +8 -579
  29. package/dist/llm/tools.js.map +1 -1
  30. package/dist/mcp/content-length-transport.d.ts +18 -0
  31. package/dist/mcp/content-length-transport.js +121 -3
  32. package/dist/mcp/content-length-transport.js.map +1 -1
  33. package/dist/mcp/error-remediation.js +54 -17
  34. package/dist/mcp/error-remediation.js.map +1 -1
  35. package/dist/planner/types.d.ts +4 -4
  36. package/dist/tools/ax-agent.d.ts +32 -0
  37. package/dist/tools/ax-agent.js +105 -0
  38. package/dist/tools/ax-agent.js.map +1 -1
  39. package/dist/tools/definitions/ask-user.d.ts +8 -0
  40. package/dist/tools/definitions/ask-user.js +168 -0
  41. package/dist/tools/definitions/ask-user.js.map +1 -0
  42. package/dist/tools/definitions/ax-agent.d.ts +8 -0
  43. package/dist/tools/definitions/ax-agent.js +276 -0
  44. package/dist/tools/definitions/ax-agent.js.map +1 -0
  45. package/dist/tools/definitions/bash-output.d.ts +7 -0
  46. package/dist/tools/definitions/bash-output.js +78 -0
  47. package/dist/tools/definitions/bash-output.js.map +1 -0
  48. package/dist/tools/definitions/bash.d.ts +8 -0
  49. package/dist/tools/definitions/bash.js +152 -0
  50. package/dist/tools/definitions/bash.js.map +1 -0
  51. package/dist/tools/definitions/create-file.d.ts +7 -0
  52. package/dist/tools/definitions/create-file.js +129 -0
  53. package/dist/tools/definitions/create-file.js.map +1 -0
  54. package/dist/tools/definitions/design.d.ts +12 -0
  55. package/dist/tools/definitions/design.js +368 -0
  56. package/dist/tools/definitions/design.js.map +1 -0
  57. package/dist/tools/definitions/index.d.ts +49 -0
  58. package/dist/tools/definitions/index.js +87 -0
  59. package/dist/tools/definitions/index.js.map +1 -0
  60. package/dist/tools/definitions/multi-edit.d.ts +7 -0
  61. package/dist/tools/definitions/multi-edit.js +123 -0
  62. package/dist/tools/definitions/multi-edit.js.map +1 -0
  63. package/dist/tools/definitions/search.d.ts +7 -0
  64. package/dist/tools/definitions/search.js +159 -0
  65. package/dist/tools/definitions/search.js.map +1 -0
  66. package/dist/tools/definitions/str-replace-editor.d.ts +7 -0
  67. package/dist/tools/definitions/str-replace-editor.js +145 -0
  68. package/dist/tools/definitions/str-replace-editor.js.map +1 -0
  69. package/dist/tools/definitions/todo.d.ts +8 -0
  70. package/dist/tools/definitions/todo.js +261 -0
  71. package/dist/tools/definitions/todo.js.map +1 -0
  72. package/dist/tools/definitions/view-file.d.ts +7 -0
  73. package/dist/tools/definitions/view-file.js +111 -0
  74. package/dist/tools/definitions/view-file.js.map +1 -0
  75. package/dist/tools/format-generators.d.ts +62 -0
  76. package/dist/tools/format-generators.js +291 -0
  77. package/dist/tools/format-generators.js.map +1 -0
  78. package/dist/tools/index.d.ts +3 -0
  79. package/dist/tools/index.js +5 -0
  80. package/dist/tools/index.js.map +1 -1
  81. package/dist/tools/types.d.ts +175 -0
  82. package/dist/tools/types.js +11 -0
  83. package/dist/tools/types.js.map +1 -0
  84. package/dist/ui/utils/image-handler.js +3 -0
  85. package/dist/ui/utils/image-handler.js.map +1 -1
  86. package/dist/utils/enhanced-error-messages.js +43 -23
  87. package/dist/utils/enhanced-error-messages.js.map +1 -1
  88. package/dist/utils/init-validator.d.ts +4 -0
  89. package/dist/utils/init-validator.js +17 -13
  90. package/dist/utils/init-validator.js.map +1 -1
  91. package/dist/utils/llm-optimized-instruction-generator.js +97 -136
  92. package/dist/utils/llm-optimized-instruction-generator.js.map +1 -1
  93. package/dist/utils/project-analyzer.d.ts +6 -0
  94. package/dist/utils/project-analyzer.js +92 -189
  95. package/dist/utils/project-analyzer.js.map +1 -1
  96. package/dist/utils/template-manager.d.ts +8 -0
  97. package/dist/utils/template-manager.js +54 -110
  98. package/dist/utils/template-manager.js.map +1 -1
  99. package/package.json +1 -1
@@ -1,14 +1,23 @@
1
1
  /**
2
- * Init command - DEPRECATED: Use 'ax-cli setup' instead
2
+ * Init command for project setup and analysis
3
3
  *
4
- * This command is kept for backwards compatibility and redirects to setup.
5
- * The project initialization functionality has been integrated into the setup command.
4
+ * This command initializes project-level configuration (.ax-cli/CUSTOM.md).
5
+ * For API configuration, use 'ax-cli setup'.
6
6
  */
7
7
  import { Command } from 'commander';
8
+ import { existsSync, mkdirSync, writeFileSync, renameSync, unlinkSync } from 'fs';
9
+ import { join, resolve } from 'path';
10
+ import * as prompts from '@clack/prompts';
8
11
  import chalk from 'chalk';
12
+ import { ProjectAnalyzer } from '../utils/project-analyzer.js';
13
+ import { LLMOptimizedInstructionGenerator } from '../utils/llm-optimized-instruction-generator.js';
14
+ import { InitValidator } from '../utils/init-validator.js';
15
+ import { InitWizard } from './init/wizard.js';
16
+ import { extractErrorMessage } from '../utils/error-handler.js';
17
+ import { CONFIG_DIR_NAME, FILE_NAMES } from '../constants.js';
9
18
  export function createInitCommand() {
10
19
  const initCommand = new Command('init')
11
- .description('Initialize project (deprecated: use "ax-cli setup" instead)')
20
+ .description('Initialize AX CLI for your project with intelligent analysis')
12
21
  .option('-f, --force', 'Force regeneration even if files exist', false)
13
22
  .option('-v, --verbose', 'Verbose output showing analysis details', false)
14
23
  .option('-d, --directory <dir>', 'Project directory to analyze')
@@ -19,28 +28,167 @@ export function createInitCommand() {
19
28
  .option('--dry-run', 'Show what would be done without making changes', false)
20
29
  .option('--validate', 'Run validation checks only', false)
21
30
  .action(async (options) => {
22
- // Show deprecation notice
23
- console.log(chalk.yellow('\nāš ļø Deprecation Notice:'));
24
- console.log(chalk.yellow(' "ax-cli init" has been merged into "ax-cli setup"'));
25
- console.log(chalk.yellow(' Please use "ax-cli setup" for full configuration.\n'));
26
- // Build equivalent setup command
27
- const args = ['setup'];
28
- if (options.force)
29
- args.push('--force');
30
- if (options.verbose)
31
- args.push('--verbose');
32
- if (options.directory)
33
- args.push('-d', options.directory);
34
- // Note: Some init-specific options (template, preview, dry-run, validate)
35
- // are not directly supported in setup. Show guidance.
36
- if (options.template || options.preview || options.dryRun || options.validate) {
37
- console.log(chalk.dim('Note: Some options (--template, --preview, --dry-run, --validate)'));
38
- console.log(chalk.dim('are not available in the new setup command.\n'));
31
+ try {
32
+ prompts.intro(chalk.cyan('AX CLI Project Initialization'));
33
+ const projectRoot = options.directory ? resolve(options.directory) : process.cwd();
34
+ if (options.verbose) {
35
+ prompts.log.info(`Working directory: ${projectRoot}`);
36
+ }
37
+ // Check if in a git repo or has package.json (reasonable project indicator)
38
+ const hasGit = existsSync(join(projectRoot, '.git'));
39
+ const hasPackageJson = existsSync(join(projectRoot, 'package.json'));
40
+ const isProject = hasGit || hasPackageJson;
41
+ if (!isProject && !options.validate) {
42
+ prompts.log.warn('No project detected in current directory (no .git or package.json)');
43
+ prompts.log.info('Run from a project directory to initialize it.');
44
+ prompts.outro(chalk.yellow('Initialization skipped'));
45
+ return;
46
+ }
47
+ // Run validation (single instance, reused for --validate flag or normal flow)
48
+ const validator = new InitValidator(projectRoot);
49
+ const validationResult = validator.validate();
50
+ if (options.validate) {
51
+ console.log('\n' + InitValidator.formatValidationResult(validationResult));
52
+ process.exit(validationResult.valid ? 0 : 1);
53
+ }
54
+ if (!validationResult.valid) {
55
+ prompts.log.error('Project validation failed:');
56
+ console.log(InitValidator.formatValidationResult(validationResult));
57
+ process.exit(1);
58
+ }
59
+ if (options.verbose && (validationResult.warnings.length > 0 || validationResult.suggestions.length > 0)) {
60
+ console.log(InitValidator.formatValidationResult(validationResult));
61
+ }
62
+ // Check if already initialized
63
+ const axCliDir = join(projectRoot, CONFIG_DIR_NAME);
64
+ const customMdPath = join(axCliDir, FILE_NAMES.CUSTOM_MD);
65
+ const indexPath = join(axCliDir, FILE_NAMES.INDEX_JSON);
66
+ if (!options.force && existsSync(customMdPath)) {
67
+ prompts.log.success('Project already initialized!');
68
+ prompts.log.info(`Custom instructions: ${customMdPath}`);
69
+ prompts.log.info(`Project index: ${indexPath}`);
70
+ prompts.log.info('Use --force to regenerate');
71
+ prompts.outro(chalk.green('Already configured'));
72
+ return;
73
+ }
74
+ // Run interactive wizard for template selection (unless --yes or --no-interaction)
75
+ let selectedTemplate = undefined;
76
+ if (!options.noInteraction && !options.yes) {
77
+ const wizard = new InitWizard({
78
+ nonInteractive: options.noInteraction,
79
+ yes: options.yes,
80
+ template: options.template,
81
+ });
82
+ const wizardResult = await wizard.run();
83
+ selectedTemplate = wizardResult.selectedTemplate;
84
+ }
85
+ // Create config directory
86
+ if (!existsSync(axCliDir)) {
87
+ mkdirSync(axCliDir, { recursive: true });
88
+ if (options.verbose) {
89
+ prompts.log.info(`Created ${CONFIG_DIR_NAME} directory`);
90
+ }
91
+ }
92
+ // Analyze project
93
+ const spinner = prompts.spinner();
94
+ spinner.start('Analyzing project...');
95
+ const analyzer = new ProjectAnalyzer(projectRoot);
96
+ const result = await analyzer.analyze();
97
+ if (!result.success || !result.projectInfo) {
98
+ spinner.stop('Analysis failed');
99
+ prompts.log.error(`Project analysis failed: ${result.error || 'Unknown error'}`);
100
+ process.exit(1);
101
+ }
102
+ const projectInfo = result.projectInfo;
103
+ spinner.stop('Analysis complete');
104
+ // Display analysis results
105
+ if (options.verbose) {
106
+ prompts.log.info(`Project: ${projectInfo.name} (${projectInfo.projectType})`);
107
+ prompts.log.info(`Language: ${projectInfo.primaryLanguage}`);
108
+ if (projectInfo.techStack.length > 0) {
109
+ prompts.log.info(`Stack: ${projectInfo.techStack.join(', ')}`);
110
+ }
111
+ }
112
+ // Generate content (either from template or project analysis)
113
+ let instructions;
114
+ let index;
115
+ if (selectedTemplate) {
116
+ instructions = selectedTemplate.instructions;
117
+ const indexData = {
118
+ projectName: selectedTemplate.name,
119
+ version: selectedTemplate.version,
120
+ projectType: selectedTemplate.projectType,
121
+ ...selectedTemplate.metadata,
122
+ templateId: selectedTemplate.id,
123
+ templateAppliedAt: new Date().toISOString(),
124
+ };
125
+ index = JSON.stringify(indexData, null, 2);
126
+ }
127
+ else {
128
+ // Generate LLM-optimized instructions
129
+ const generator = new LLMOptimizedInstructionGenerator({
130
+ compressionLevel: 'moderate',
131
+ hierarchyEnabled: true,
132
+ criticalRulesCount: 5,
133
+ includeDODONT: true,
134
+ includeTroubleshooting: true,
135
+ });
136
+ instructions = generator.generateInstructions(projectInfo);
137
+ index = generator.generateIndex(projectInfo);
138
+ }
139
+ // Preview or dry-run mode
140
+ if (options.dryRun) {
141
+ prompts.log.info('Dry-run mode - no changes made');
142
+ prompts.log.info(`Would create: ${customMdPath}`);
143
+ prompts.log.info(`Would create: ${indexPath}`);
144
+ prompts.outro(chalk.green('Dry-run complete'));
145
+ return;
146
+ }
147
+ // Write files using atomic operations
148
+ const tmpCustomPath = `${customMdPath}.tmp`;
149
+ const tmpIndexPath = `${indexPath}.tmp`;
150
+ try {
151
+ writeFileSync(tmpCustomPath, instructions, 'utf-8');
152
+ writeFileSync(tmpIndexPath, index, 'utf-8');
153
+ // Atomic rename
154
+ renameSync(tmpCustomPath, customMdPath);
155
+ renameSync(tmpIndexPath, indexPath);
156
+ prompts.log.success(`Generated custom instructions: ${customMdPath}`);
157
+ prompts.log.success(`Generated project index: ${indexPath}`);
158
+ }
159
+ catch (writeError) {
160
+ // Cleanup temp files on error
161
+ try {
162
+ if (existsSync(tmpCustomPath))
163
+ unlinkSync(tmpCustomPath);
164
+ if (existsSync(tmpIndexPath))
165
+ unlinkSync(tmpIndexPath);
166
+ }
167
+ catch {
168
+ // Ignore cleanup errors
169
+ }
170
+ throw writeError;
171
+ }
172
+ // Show completion summary
173
+ await prompts.note(`Project: ${projectInfo.name} (${projectInfo.projectType})\n` +
174
+ `Language: ${projectInfo.primaryLanguage}\n` +
175
+ (projectInfo.techStack.length > 0 ? `Stack: ${projectInfo.techStack.join(', ')}\n` : '') +
176
+ `\nFiles created:\n` +
177
+ ` ${customMdPath}\n` +
178
+ ` ${indexPath}`, 'Project Summary');
179
+ await prompts.note('1. Review .ax-cli/CUSTOM.md and customize if needed\n' +
180
+ '2. Start chatting: ax-cli\n' +
181
+ '3. Use --force to regenerate after project changes', 'Next Steps');
182
+ prompts.outro(chalk.green('Project initialized successfully!'));
183
+ }
184
+ catch (error) {
185
+ prompts.log.error(`Error during initialization: ${extractErrorMessage(error)}`);
186
+ if (options.verbose && error instanceof Error && error.stack) {
187
+ console.error('\nStack trace:');
188
+ console.error(error.stack);
189
+ }
190
+ process.exit(1);
39
191
  }
40
- console.log(chalk.cyan('Equivalent command:'));
41
- console.log(chalk.cyan(` ax-cli ${args.join(' ')}\n`));
42
- // Instead of running, just inform the user
43
- console.log('Run the setup command to configure your project.\n');
44
192
  });
45
193
  return initCommand;
46
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,iBAAiB;IAC/B,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SACpC,WAAW,CAAC,6DAA6D,CAAC;SAC1E,MAAM,CAAC,aAAa,EAAE,wCAAwC,EAAE,KAAK,CAAC;SACtE,MAAM,CAAC,eAAe,EAAE,yCAAyC,EAAE,KAAK,CAAC;SACzE,MAAM,CAAC,uBAAuB,EAAE,8BAA8B,CAAC;SAC/D,MAAM,CAAC,WAAW,EAAE,2CAA2C,EAAE,KAAK,CAAC;SACvE,MAAM,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,KAAK,CAAC;SAChE,MAAM,CAAC,8BAA8B,EAAE,yBAAyB,CAAC;SACjE,MAAM,CAAC,WAAW,EAAE,iCAAiC,EAAE,KAAK,CAAC;SAC7D,MAAM,CAAC,WAAW,EAAE,gDAAgD,EAAE,KAAK,CAAC;SAC5E,MAAM,CAAC,YAAY,EAAE,4BAA4B,EAAE,KAAK,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,OAUd,EAAE,EAAE;QACH,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sDAAsD,CAAC,CAAC,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wDAAwD,CAAC,CAAC,CAAC;QAEpF,iCAAiC;QACjC,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,OAAO,CAAC,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,OAAO,CAAC,OAAO;YAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,IAAI,OAAO,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAE1D,0EAA0E;QAC1E,sDAAsD;QACtD,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC,CAAC;YAC5F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC,CAAC;QAC1E,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAExD,2CAA2C;QAC3C,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEL,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { getTemplateNames, getTemplatesByCategory } from '../mcp/templates.js';
4
4
  import { getMCPManager } from '../llm/tools.js';
5
5
  import { MCPServerIdSchema } from '@ax-cli/schemas';
6
6
  import chalk from 'chalk';
7
+ import * as prompts from '@clack/prompts';
7
8
  import { ConsoleMessenger } from '../utils/console-messenger.js';
8
9
  import { extractErrorMessage } from '../utils/error-handler.js';
9
10
  import { validateServerConfig, formatValidationResult } from '../mcp/validation.js';
@@ -35,6 +36,18 @@ export function createMCPCommand() {
35
36
  .option('-e, --env [env...]', 'Environment variables (key=value format)', [])
36
37
  .action(async (name, options) => {
37
38
  try {
39
+ // BUG FIX: Parse command-line --env options first to supplement process.env
40
+ // This handles the case where environment variables were set in a way
41
+ // that the current process doesn't see (e.g., exported in a subshell)
42
+ const cliEnvVars = {};
43
+ for (const envVar of options.env || []) {
44
+ const eqIndex = envVar.indexOf('=');
45
+ if (eqIndex > 0) {
46
+ const key = envVar.slice(0, eqIndex);
47
+ const value = envVar.slice(eqIndex + 1);
48
+ cliEnvVars[key] = value;
49
+ }
50
+ }
38
51
  // Check if using template
39
52
  if (options.template) {
40
53
  const template = getTemplate(name);
@@ -54,27 +67,49 @@ export function createMCPCommand() {
54
67
  console.log(chalk.gray(template.description));
55
68
  console.log();
56
69
  // Check required environment variables
70
+ // BUG FIX: Check both process.env AND command-line --env options
57
71
  const envVars = {};
58
- let missingEnvVars = false;
72
+ const missingEnvVarsList = [];
59
73
  for (const envVar of template.requiredEnv) {
60
- const value = process.env[envVar.name];
74
+ // Priority: CLI --env flag > process.env
75
+ const value = cliEnvVars[envVar.name] || process.env[envVar.name];
61
76
  if (!value) {
62
- console.log(chalk.yellow(`āš ļø Missing environment variable: ${chalk.bold(envVar.name)}`));
63
- console.log(chalk.gray(` ${envVar.description}`));
64
- if (envVar.url) {
65
- console.log(chalk.gray(` More info: ${envVar.url}`));
66
- }
67
- console.log();
68
- missingEnvVars = true;
77
+ missingEnvVarsList.push(envVar);
69
78
  }
70
79
  else {
71
80
  envVars[envVar.name] = value;
72
81
  }
73
82
  }
74
- if (missingEnvVars) {
75
- console.log(chalk.red('āŒ Setup cannot continue without required environment variables.'));
76
- console.log();
77
- console.log(chalk.blue('Setup instructions:'));
83
+ if (missingEnvVarsList.length > 0) {
84
+ console.log(chalk.yellow('āš ļø Missing required environment variables:\n'));
85
+ for (const envVar of missingEnvVarsList) {
86
+ console.log(chalk.yellow(` • ${chalk.bold(envVar.name)}`));
87
+ console.log(chalk.gray(` ${envVar.description}`));
88
+ if (envVar.url) {
89
+ console.log(chalk.gray(` Documentation: ${envVar.url}`));
90
+ }
91
+ console.log();
92
+ }
93
+ console.log(chalk.red('āŒ Setup cannot continue without required environment variables.\n'));
94
+ // BUG FIX: Provide multiple options for setting environment variables
95
+ console.log(chalk.blue('Options to provide the missing variables:\n'));
96
+ // Option 1: Pass directly via --env flag
97
+ const envFlags = missingEnvVarsList.map(e => `--env ${e.name}=YOUR_VALUE`).join(' ');
98
+ console.log(chalk.white(' Option 1: Pass directly with --env flag (recommended):'));
99
+ console.log(chalk.cyan(` ax-cli mcp add ${name} --template ${envFlags}\n`));
100
+ // Option 2: Export in current shell
101
+ console.log(chalk.white(' Option 2: Export in current shell:'));
102
+ for (const envVar of missingEnvVarsList) {
103
+ console.log(chalk.cyan(` export ${envVar.name}="your_value"`));
104
+ }
105
+ console.log(chalk.cyan(` ax-cli mcp add ${name} --template\n`));
106
+ // Option 3: Add to shell profile
107
+ console.log(chalk.white(' Option 3: Add to shell profile (~/.bashrc or ~/.zshrc):'));
108
+ for (const envVar of missingEnvVarsList) {
109
+ console.log(chalk.cyan(` export ${envVar.name}="your_value"`));
110
+ }
111
+ console.log(chalk.gray(' Then restart your terminal or run: source ~/.zshrc\n'));
112
+ console.log(chalk.blue('Full setup instructions:'));
78
113
  console.log(template.setupInstructions);
79
114
  process.exit(1);
80
115
  }
@@ -554,50 +589,59 @@ export function createMCPCommand() {
554
589
  const { MCPHealthMonitor } = await import('../mcp/health.js');
555
590
  const manager = getMCPManager();
556
591
  const healthMonitor = new MCPHealthMonitor(manager);
592
+ // JSON mode - plain output
593
+ if (options.json) {
594
+ const health = serverName
595
+ ? filterValidHealth([await healthMonitor.getServerStatus(serverName)])
596
+ : await healthMonitor.getHealthReport();
597
+ console.log(JSON.stringify(health, null, 2));
598
+ return;
599
+ }
557
600
  if (options.watch) {
558
601
  // Continuous monitoring mode
559
- console.log(chalk.blue.bold('\nšŸ“Š MCP Server Health Monitoring\n'));
560
- console.log(chalk.gray('Press Ctrl+C to stop\n'));
602
+ prompts.intro(chalk.cyan('MCP Server Health Monitoring'));
603
+ prompts.log.info('Press Ctrl+C to stop');
561
604
  // Start monitoring (uses configured health check interval)
562
605
  healthMonitor.start(MCP_CONFIG.HEALTH_CHECK_INTERVAL);
563
606
  // Display initial report
564
607
  const displayHealth = async () => {
565
608
  console.clear();
566
- console.log(chalk.blue.bold('šŸ“Š MCP Server Health Report\n'));
567
- console.log(chalk.gray(`Last updated: ${new Date().toLocaleTimeString()}\n`));
609
+ prompts.intro(chalk.cyan('MCP Server Health Report'));
610
+ prompts.log.message(`Last updated: ${new Date().toLocaleTimeString()}`);
568
611
  const health = serverName
569
612
  ? filterValidHealth([await healthMonitor.getServerStatus(serverName)])
570
613
  : await healthMonitor.getHealthReport();
571
614
  if (health.length === 0) {
572
- console.log(chalk.yellow('No servers connected'));
615
+ prompts.log.warn('No servers connected');
573
616
  return;
574
617
  }
575
618
  for (const server of health) {
576
619
  const statusIcon = server.connected ? 'āœ“' : 'āœ—';
577
- const statusColor = server.connected ? chalk.green : chalk.red;
578
620
  const statusText = server.connected ? 'Connected' : 'Disconnected';
579
- console.log(statusColor(`${statusIcon} ${chalk.bold(server.serverName)} (${statusText})`));
580
- console.log(chalk.gray(` Transport: MCP`));
621
+ // Build server info
622
+ const serverInfo = [];
623
+ serverInfo.push(`Transport: MCP`);
581
624
  if (server.uptime) {
582
- console.log(chalk.gray(` Uptime: ${MCPHealthMonitor.formatUptime(server.uptime)}`));
625
+ serverInfo.push(`Uptime: ${MCPHealthMonitor.formatUptime(server.uptime)}`);
583
626
  }
584
- console.log(chalk.gray(` Tools: ${server.toolCount} available`));
627
+ serverInfo.push(`Tools: ${server.toolCount} available`);
585
628
  if (server.avgLatency) {
586
- console.log(chalk.gray(` Latency: avg ${MCPHealthMonitor.formatLatency(server.avgLatency)}, p95 ${MCPHealthMonitor.formatLatency(server.p95Latency || 0)}`));
629
+ serverInfo.push(`Latency: avg ${MCPHealthMonitor.formatLatency(server.avgLatency)}, p95 ${MCPHealthMonitor.formatLatency(server.p95Latency || 0)}`);
587
630
  }
588
631
  const successRateColor = server.successRate >= 95 ? chalk.green :
589
632
  server.successRate >= 80 ? chalk.yellow : chalk.red;
590
- console.log(chalk.gray(` Success Rate: ${successRateColor(`${server.successRate.toFixed(1)}%`)} (${server.successCount}/${server.successCount + server.failureCount} calls)`));
633
+ serverInfo.push(`Success Rate: ${successRateColor(`${server.successRate.toFixed(1)}%`)} (${server.successCount}/${server.successCount + server.failureCount} calls)`);
591
634
  if (server.lastError) {
592
- console.log(chalk.red(` Last Error: ${server.lastError}`));
635
+ serverInfo.push(chalk.red(`Last Error: ${server.lastError}`));
593
636
  if (server.lastErrorAt) {
594
637
  const timeSinceError = Date.now() - server.lastErrorAt;
595
- console.log(chalk.gray(` ${MCPHealthMonitor.formatUptime(timeSinceError)} ago`));
638
+ serverInfo.push(` ${MCPHealthMonitor.formatUptime(timeSinceError)} ago`);
596
639
  }
597
640
  }
598
- console.log();
641
+ const titleColor = server.connected ? chalk.green : chalk.red;
642
+ prompts.note(serverInfo.join('\n'), titleColor(`${statusIcon} ${server.serverName} (${statusText})`));
599
643
  }
600
- console.log(chalk.gray('Next update in 60 seconds...'));
644
+ prompts.log.message(chalk.dim('Next update in 60 seconds...'));
601
645
  };
602
646
  // Display immediately
603
647
  await displayHealth();
@@ -607,67 +651,74 @@ export function createMCPCommand() {
607
651
  process.once('SIGINT', () => {
608
652
  clearInterval(watchInterval);
609
653
  healthMonitor.stop();
610
- console.log(chalk.yellow('\n\nšŸ‘‹ Stopped health monitoring\n'));
654
+ prompts.outro(chalk.yellow('Stopped health monitoring'));
611
655
  process.exit(0);
612
656
  });
613
657
  }
614
658
  else {
615
- // One-time health check
659
+ // One-time health check with @clack/prompts
660
+ prompts.intro(chalk.cyan('MCP Server Health'));
661
+ const spinner = prompts.spinner();
662
+ spinner.start('Checking server health...');
616
663
  const health = serverName
617
664
  ? filterValidHealth([await healthMonitor.getServerStatus(serverName)])
618
665
  : await healthMonitor.getHealthReport();
619
- if (options.json) {
620
- console.log(JSON.stringify(health, null, 2));
621
- return;
622
- }
666
+ spinner.stop('Health check complete');
623
667
  if (health.length === 0) {
624
668
  if (serverName) {
625
- console.log(chalk.yellow(`\nāš ļø Server "${serverName}" not found\n`));
669
+ prompts.log.warn(`Server "${serverName}" not found`);
626
670
  }
627
671
  else {
628
- console.log(chalk.yellow('\nāš ļø No MCP servers connected\n'));
629
- console.log(chalk.blue('To add a server:'));
630
- console.log(chalk.cyan(' ax-cli mcp add figma --template'));
631
- console.log();
672
+ prompts.log.warn('No MCP servers connected');
673
+ prompts.log.info('To add a server: ax-cli mcp add figma --template');
632
674
  }
675
+ prompts.outro('');
633
676
  return;
634
677
  }
635
- console.log(chalk.blue.bold('\nšŸ“Š MCP Server Health Report\n'));
678
+ // Display each server's health
636
679
  for (const server of health) {
637
680
  const statusIcon = server.connected ? 'āœ“' : 'āœ—';
638
- const statusColor = server.connected ? chalk.green : chalk.red;
639
681
  const statusText = server.connected ? 'Connected' : 'Disconnected';
640
- console.log(statusColor(`${statusIcon} ${chalk.bold(server.serverName)} (${statusText})`));
641
- console.log(chalk.gray(` Transport: MCP`));
682
+ // Build server info
683
+ const serverInfo = [];
684
+ serverInfo.push(`Transport: MCP`);
642
685
  if (server.uptime) {
643
- console.log(chalk.gray(` Uptime: ${MCPHealthMonitor.formatUptime(server.uptime)}`));
686
+ serverInfo.push(`Uptime: ${MCPHealthMonitor.formatUptime(server.uptime)}`);
644
687
  }
645
- console.log(chalk.gray(` Tools: ${server.toolCount} available`));
688
+ serverInfo.push(`Tools: ${server.toolCount} available`);
646
689
  if (server.avgLatency) {
647
- console.log(chalk.gray(` Latency: avg ${MCPHealthMonitor.formatLatency(server.avgLatency)}, p95 ${MCPHealthMonitor.formatLatency(server.p95Latency || 0)}`));
690
+ serverInfo.push(`Latency: avg ${MCPHealthMonitor.formatLatency(server.avgLatency)}, p95 ${MCPHealthMonitor.formatLatency(server.p95Latency || 0)}`);
648
691
  }
649
692
  const successRateColor = server.successRate >= 95 ? chalk.green :
650
693
  server.successRate >= 80 ? chalk.yellow : chalk.red;
651
- console.log(chalk.gray(` Success Rate: ${successRateColor(`${server.successRate.toFixed(1)}%`)} (${server.successCount}/${server.successCount + server.failureCount} calls)`));
694
+ serverInfo.push(`Success Rate: ${successRateColor(`${server.successRate.toFixed(1)}%`)} (${server.successCount}/${server.successCount + server.failureCount} calls)`);
652
695
  if (server.lastError) {
653
- console.log(chalk.red(` Last Error: ${server.lastError}`));
696
+ serverInfo.push(chalk.red(`Last Error: ${server.lastError}`));
654
697
  if (server.lastErrorAt) {
655
698
  const timeSinceError = Date.now() - server.lastErrorAt;
656
- console.log(chalk.gray(` ${MCPHealthMonitor.formatUptime(timeSinceError)} ago`));
699
+ serverInfo.push(` ${MCPHealthMonitor.formatUptime(timeSinceError)} ago`);
657
700
  }
658
701
  }
659
702
  if (server.lastSuccess) {
660
703
  const timeSinceSuccess = Date.now() - server.lastSuccess;
661
- console.log(chalk.gray(` Last Successful Call: ${MCPHealthMonitor.formatUptime(timeSinceSuccess)} ago`));
704
+ serverInfo.push(`Last Successful Call: ${MCPHealthMonitor.formatUptime(timeSinceSuccess)} ago`);
662
705
  }
663
- console.log();
706
+ const titleColor = server.connected ? chalk.green : chalk.red;
707
+ prompts.note(serverInfo.join('\n'), titleColor(`${statusIcon} ${server.serverName} (${statusText})`));
708
+ }
709
+ // Summary
710
+ const connectedCount = health.filter(s => s.connected).length;
711
+ const totalCount = health.length;
712
+ if (connectedCount === totalCount) {
713
+ prompts.outro(chalk.green(`All ${totalCount} server(s) healthy. Use --watch to monitor.`));
714
+ }
715
+ else {
716
+ prompts.outro(chalk.yellow(`${connectedCount}/${totalCount} server(s) connected. Use --watch to monitor.`));
664
717
  }
665
- console.log(chalk.gray('šŸ’” Tip: Use --watch to continuously monitor server health'));
666
- console.log();
667
718
  }
668
719
  }
669
720
  catch (error) {
670
- console.error(chalk.red(`\nāŒ Error: ${extractErrorMessage(error)}\n`));
721
+ prompts.log.error(`Error: ${extractErrorMessage(error)}`);
671
722
  process.exit(1);
672
723
  }
673
724
  });