expxagents 0.29.1 → 0.29.3

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.
@@ -1,36 +1,62 @@
1
1
  import readline from 'node:readline';
2
+ import path from 'node:path';
2
3
  import dotenv from 'dotenv';
3
4
  import { AgentRunner, SessionManager, SUPPORTED_MODELS, DEFAULT_MODEL } from '@expxagents/agent';
4
- // Load .env from current working directory
5
- dotenv.config();
6
- const COLORS = {
5
+ import { getVersion } from '../utils/version.js';
6
+ const C = {
7
7
  reset: '\x1b[0m',
8
8
  dim: '\x1b[2m',
9
9
  green: '\x1b[32m',
10
10
  cyan: '\x1b[36m',
11
11
  yellow: '\x1b[33m',
12
12
  magenta: '\x1b[35m',
13
+ blue: '\x1b[34m',
14
+ white: '\x1b[37m',
13
15
  bold: '\x1b[1m',
16
+ bgCyan: '\x1b[46m',
17
+ bgBlue: '\x1b[44m',
14
18
  };
15
- function printBanner(model) {
19
+ function printBanner(model, version) {
16
20
  const modelInfo = SUPPORTED_MODELS.find(m => m.id === model);
17
21
  const label = modelInfo?.name ?? model;
18
- console.log(`\n${COLORS.bold}${COLORS.cyan}ExpxAgents CLI${COLORS.reset} ${COLORS.dim}— powered by OpenRouter${COLORS.reset}`);
19
- console.log(`${COLORS.dim}Model: ${COLORS.yellow}${label}${COLORS.reset}`);
20
- console.log(`${COLORS.dim}Working directory: ${process.cwd()}${COLORS.reset}`);
21
- console.log(`${COLORS.dim}Type ${COLORS.bold}/help${COLORS.reset}${COLORS.dim} for commands, ${COLORS.bold}/quit${COLORS.reset}${COLORS.dim} to exit${COLORS.reset}\n`);
22
+ const cwd = process.cwd();
23
+ const dir = cwd.split('/').slice(-2).join('/');
24
+ console.log('');
25
+ console.log(`${C.cyan} ╔══════════════════════════════════════════════════╗${C.reset}`);
26
+ console.log(`${C.cyan} ║${C.reset} ${C.cyan}║${C.reset}`);
27
+ console.log(`${C.cyan} ║${C.reset} ${C.bold}${C.cyan}▓▓▓ ExpxAgents CLI ▓▓▓${C.reset} ${C.cyan}║${C.reset}`);
28
+ console.log(`${C.cyan} ║${C.reset} ${C.dim}AI Coding Agent — powered by OpenRouter${C.reset} ${C.cyan}║${C.reset}`);
29
+ console.log(`${C.cyan} ║${C.reset} ${C.cyan}║${C.reset}`);
30
+ console.log(`${C.cyan} ╚══════════════════════════════════════════════════╝${C.reset}`);
31
+ console.log('');
32
+ console.log(` ${C.dim}Model${C.reset} ${C.yellow}${label}${C.reset}`);
33
+ console.log(` ${C.dim}Dir${C.reset} ${C.white}${dir}${C.reset}`);
34
+ console.log(` ${C.dim}Version${C.reset} ${C.dim}v${version}${C.reset}`);
35
+ console.log(` ${C.dim}Tools${C.reset} ${C.green}14 tools${C.reset} ${C.dim}(files, bash, web, search)${C.reset}`);
36
+ console.log('');
37
+ console.log(` ${C.dim}Tips: ${C.bold}/help${C.reset}${C.dim} commands • ${C.bold}/models${C.reset}${C.dim} list models • ${C.bold}/quit${C.reset}${C.dim} exit${C.reset}`);
38
+ console.log(` ${C.dim}──────────────────────────────────────────────────${C.reset}`);
39
+ console.log('');
22
40
  }
23
41
  function printHelp() {
24
- console.log(`
25
- ${COLORS.bold}Commands:${COLORS.reset}
26
- ${COLORS.cyan}/help${COLORS.reset} Show this help
27
- ${COLORS.cyan}/model <id>${COLORS.reset} Switch model (e.g. /model openai/gpt-4o)
28
- ${COLORS.cyan}/models${COLORS.reset} List available models
29
- ${COLORS.cyan}/clear${COLORS.reset} Clear conversation history
30
- ${COLORS.cyan}/quit${COLORS.reset} Exit
31
- `);
42
+ console.log('');
43
+ console.log(` ${C.bold}${C.cyan}Commands${C.reset}`);
44
+ console.log(` ${C.dim}──────────────────────────────────────${C.reset}`);
45
+ console.log(` ${C.cyan}/help${C.reset} Show this help`);
46
+ console.log(` ${C.cyan}/model ${C.dim}<id>${C.reset} Switch model`);
47
+ console.log(` ${C.cyan}/models${C.reset} List available models`);
48
+ console.log(` ${C.cyan}/clear${C.reset} Clear conversation`);
49
+ console.log(` ${C.cyan}/quit${C.reset} Exit`);
50
+ console.log('');
51
+ console.log(` ${C.bold}${C.cyan}Shortcuts${C.reset}`);
52
+ console.log(` ${C.dim}──────────────────────────────────────${C.reset}`);
53
+ console.log(` ${C.cyan}Ctrl+C${C.reset} Exit`);
54
+ console.log(` ${C.cyan}Ctrl+D${C.reset} Exit`);
55
+ console.log('');
32
56
  }
33
57
  export async function cliChatCommand(options) {
58
+ // Load .env from the user's current working directory (explicit path for npx compatibility)
59
+ dotenv.config({ path: path.resolve(process.cwd(), '.env') });
34
60
  const apiKey = process.env.OPENROUTER_API_KEY;
35
61
  if (!apiKey) {
36
62
  console.error('OPENROUTER_API_KEY is not set. Get one at https://openrouter.ai/keys');
@@ -54,7 +80,7 @@ export async function cliChatCommand(options) {
54
80
  const summary = typeof args === 'object' && args !== null
55
81
  ? Object.entries(args).map(([k, v]) => `${k}=${String(v).slice(0, 60)}`).join(', ')
56
82
  : String(args).slice(0, 80);
57
- process.stderr.write(`${COLORS.dim}[${tool}] ${summary}${COLORS.reset}\n`);
83
+ process.stderr.write(` ${C.dim}${C.cyan}⚡${C.reset} ${C.dim}${tool}${C.reset} ${C.dim}${summary}${C.reset}\n`);
58
84
  },
59
85
  });
60
86
  try {
@@ -68,11 +94,11 @@ export async function cliChatCommand(options) {
68
94
  return;
69
95
  }
70
96
  // Interactive REPL mode
71
- printBanner(model);
97
+ printBanner(model, getVersion());
72
98
  const rl = readline.createInterface({
73
99
  input: process.stdin,
74
100
  output: process.stdout,
75
- prompt: `${COLORS.green}>${COLORS.reset} `,
101
+ prompt: `${C.bold}${C.cyan}❯${C.reset} `,
76
102
  });
77
103
  rl.prompt();
78
104
  rl.on('line', async (line) => {
@@ -88,7 +114,7 @@ export async function cliChatCommand(options) {
88
114
  case '/quit':
89
115
  case '/exit':
90
116
  case '/q':
91
- console.log(`${COLORS.dim}Goodbye!${COLORS.reset}`);
117
+ console.log(`\n ${C.dim}Goodbye! ${C.cyan}✦${C.reset}\n`);
92
118
  process.exit(0);
93
119
  break;
94
120
  case '/help':
@@ -96,37 +122,37 @@ export async function cliChatCommand(options) {
96
122
  rl.prompt();
97
123
  return;
98
124
  case '/models':
99
- console.log(`\n${COLORS.bold}Available models:${COLORS.reset}`);
125
+ console.log(`\n${C.bold}Available models:${C.reset}`);
100
126
  for (const m of SUPPORTED_MODELS) {
101
- const active = m.id === model ? ` ${COLORS.green}(active)${COLORS.reset}` : '';
102
- console.log(` ${COLORS.cyan}${m.id}${COLORS.reset} — ${m.name} (${(m.contextWindow / 1000).toFixed(0)}K ctx)${active}`);
127
+ const active = m.id === model ? ` ${C.green}(active)${C.reset}` : '';
128
+ console.log(` ${C.cyan}${m.id}${C.reset} — ${m.name} (${(m.contextWindow / 1000).toFixed(0)}K ctx)${active}`);
103
129
  }
104
130
  console.log('');
105
131
  rl.prompt();
106
132
  return;
107
133
  case '/model':
108
134
  if (!args[0]) {
109
- console.log(`Current model: ${COLORS.yellow}${model}${COLORS.reset}`);
135
+ console.log(`Current model: ${C.yellow}${model}${C.reset}`);
110
136
  }
111
137
  else {
112
138
  model = args[0];
113
139
  const info = SUPPORTED_MODELS.find(m => m.id === model);
114
140
  if (info) {
115
- console.log(`${COLORS.green}Switched to ${info.name}${COLORS.reset}`);
141
+ console.log(`${C.green}Switched to ${info.name}${C.reset}`);
116
142
  }
117
143
  else {
118
- console.log(`${COLORS.yellow}Warning: "${model}" is not in curated list. Tool use may not work.${COLORS.reset}`);
144
+ console.log(`${C.yellow}Warning: "${model}" is not in curated list. Tool use may not work.${C.reset}`);
119
145
  }
120
146
  }
121
147
  rl.prompt();
122
148
  return;
123
149
  case '/clear':
124
150
  sessionManager.create(sessionId, process.cwd());
125
- console.log(`${COLORS.dim}Conversation cleared.${COLORS.reset}`);
151
+ console.log(`${C.dim}Conversation cleared.${C.reset}`);
126
152
  rl.prompt();
127
153
  return;
128
154
  default:
129
- console.log(`${COLORS.dim}Unknown command: ${cmd}. Type /help for commands.${COLORS.reset}`);
155
+ console.log(`${C.dim}Unknown command: ${cmd}. Type /help for commands.${C.reset}`);
130
156
  rl.prompt();
131
157
  return;
132
158
  }
@@ -145,11 +171,11 @@ export async function cliChatCommand(options) {
145
171
  const summary = typeof args === 'object' && args !== null
146
172
  ? Object.entries(args).map(([k, v]) => `${k}=${String(v).slice(0, 60)}`).join(', ')
147
173
  : String(args).slice(0, 80);
148
- process.stderr.write(`${COLORS.dim}[${tool}] ${summary}${COLORS.reset}\n`);
174
+ process.stderr.write(` ${C.dim}${C.cyan}⚡${C.reset} ${C.dim}${tool}${C.reset} ${C.dim}${summary}${C.reset}\n`);
149
175
  },
150
176
  onAskUser: async (question) => {
151
177
  return new Promise((resolve) => {
152
- rl.question(`${COLORS.magenta}Agent asks:${COLORS.reset} ${question}\n${COLORS.green}>${COLORS.reset} `, resolve);
178
+ rl.question(`\n ${C.magenta}? ${question}${C.reset}\n ${C.bold}${C.cyan}❯${C.reset} `, resolve);
153
179
  });
154
180
  },
155
181
  });
@@ -158,12 +184,12 @@ export async function cliChatCommand(options) {
158
184
  console.log('\n');
159
185
  }
160
186
  catch (err) {
161
- console.error(`\n${COLORS.yellow}Error: ${err instanceof Error ? err.message : String(err)}${COLORS.reset}\n`);
187
+ console.error(`\n${C.yellow}Error: ${err instanceof Error ? err.message : String(err)}${C.reset}\n`);
162
188
  }
163
189
  rl.prompt();
164
190
  });
165
191
  rl.on('close', () => {
166
- console.log(`\n${COLORS.dim}Goodbye!${COLORS.reset}`);
192
+ console.log(`\n${C.dim}Goodbye!${C.reset}`);
167
193
  process.exit(0);
168
194
  });
169
195
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expxagents",
3
- "version": "0.29.1",
3
+ "version": "0.29.3",
4
4
  "description": "Multi-agent orchestration platform for AI squads",
5
5
  "author": "ExpxAgents",
6
6
  "license": "MIT",