vexi-cli 0.5.1 → 0.5.2
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/README.md +8 -8
- package/dist/agent.js +44 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
**Open-source AI coding agent for your terminal.**
|
|
13
13
|
Bring your own key · Zero config · Multilingual · 100% local
|
|
14
14
|
|
|
15
|
-
[](https://www.npmjs.com/package/vexi)
|
|
15
|
+
[](https://www.npmjs.com/package/vexi-cli)
|
|
16
16
|
[](LICENSE)
|
|
17
17
|
[](package.json)
|
|
18
18
|
|
|
@@ -25,7 +25,7 @@ Bring your own key · Zero config · Multilingual · 100% local
|
|
|
25
25
|
## Install
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
npm install -g vexi
|
|
28
|
+
npm install -g vexi-cli
|
|
29
29
|
vexi
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -239,7 +239,7 @@ saving.
|
|
|
239
239
|
|
|
240
240
|
| | Vexi | OpenCode | Claude Code | Cursor |
|
|
241
241
|
| --- | --- | --- | --- | --- |
|
|
242
|
-
| Install | `npm i -g vexi` | binary/script | `npm i -g` | desktop app |
|
|
242
|
+
| Install | `npm i -g vexi-cli` | binary/script | `npm i -g` | desktop app |
|
|
243
243
|
| BYOK (any provider) | ✅ 5 providers, auto-detect | ✅ | ❌ Anthropic only | partial |
|
|
244
244
|
| Works fully offline/local | ✅ no server, no account | ✅ | ❌ account | ❌ account |
|
|
245
245
|
| Native-language code explanations | ✅ ar/es/pt/fr | ❌ | ❌ | ❌ |
|
|
@@ -292,19 +292,19 @@ To add support for a new key format, edit a single file: `src/providers/detect.t
|
|
|
292
292
|
|
|
293
293
|
## 🌍 العربية
|
|
294
294
|
|
|
295
|
-
**Vexi** — وكيل برمجة بالذكاء الاصطناعي مفتوح المصدر يعمل في الطرفية. ثبّته بأمر واحد (`npm install -g vexi`)، الصق مفتاح API الخاص بك مرة واحدة، وابدأ فورًا. لا تسجيل، لا خادم، كل شيء يعمل محليًا على جهازك. يشرح Vexi أي كود بالعربية الفصحى (`vexi explain auth.ts --ar`) في ملفات HTML تدعم الاتجاه من اليمين لليسار بشكل مثالي، ويتعلّم أسلوبك البرمجي الشخصي من جلساتك السابقة (`vexi learn`).
|
|
295
|
+
**Vexi** — وكيل برمجة بالذكاء الاصطناعي مفتوح المصدر يعمل في الطرفية. ثبّته بأمر واحد (`npm install -g vexi-cli`)، الصق مفتاح API الخاص بك مرة واحدة، وابدأ فورًا. لا تسجيل، لا خادم، كل شيء يعمل محليًا على جهازك. يشرح Vexi أي كود بالعربية الفصحى (`vexi explain auth.ts --ar`) في ملفات HTML تدعم الاتجاه من اليمين لليسار بشكل مثالي، ويتعلّم أسلوبك البرمجي الشخصي من جلساتك السابقة (`vexi learn`).
|
|
296
296
|
|
|
297
297
|
## 🌍 Español
|
|
298
298
|
|
|
299
|
-
**Vexi** es un agente de programación con IA, de código abierto, que vive en tu terminal. Instálalo con un solo comando (`npm install -g vexi`), pega tu clave API una vez y empieza al instante. Sin registro, sin servidor: todo se ejecuta localmente. Vexi detecta tu proveedor automáticamente y habla tu idioma.
|
|
299
|
+
**Vexi** es un agente de programación con IA, de código abierto, que vive en tu terminal. Instálalo con un solo comando (`npm install -g vexi-cli`), pega tu clave API una vez y empieza al instante. Sin registro, sin servidor: todo se ejecuta localmente. Vexi detecta tu proveedor automáticamente y habla tu idioma.
|
|
300
300
|
|
|
301
301
|
## 🌍 Português
|
|
302
302
|
|
|
303
|
-
**Vexi** é um agente de programação com IA, de código aberto, que vive no seu terminal. Instale com um único comando (`npm install -g vexi`), cole sua chave de API uma vez e comece imediatamente. Sem cadastro, sem servidor: tudo roda localmente. O Vexi detecta seu provedor automaticamente e fala o seu idioma.
|
|
303
|
+
**Vexi** é um agente de programação com IA, de código aberto, que vive no seu terminal. Instale com um único comando (`npm install -g vexi-cli`), cole sua chave de API uma vez e comece imediatamente. Sem cadastro, sem servidor: tudo roda localmente. O Vexi detecta seu provedor automaticamente e fala o seu idioma.
|
|
304
304
|
|
|
305
305
|
## 🌍 Français
|
|
306
306
|
|
|
307
|
-
**Vexi** est un agent de codage IA open source qui vit dans votre terminal. Installez-le en une seule commande (`npm install -g vexi`), collez votre clé API une fois et commencez immédiatement. Pas de compte, pas de serveur : tout s'exécute localement. Vexi détecte automatiquement votre fournisseur et parle votre langue.
|
|
307
|
+
**Vexi** est un agent de codage IA open source qui vit dans votre terminal. Installez-le en une seule commande (`npm install -g vexi-cli`), collez votre clé API une fois et commencez immédiatement. Pas de compte, pas de serveur : tout s'exécute localement. Vexi détecte automatiquement votre fournisseur et parle votre langue.
|
|
308
308
|
|
|
309
309
|
---
|
|
310
310
|
|
|
@@ -312,6 +312,6 @@ To add support for a new key format, edit a single file: `src/providers/detect.t
|
|
|
312
312
|
|
|
313
313
|
**MIT License** · Made with ⚡ by the Vexi community
|
|
314
314
|
|
|
315
|
-
`npm install -g vexi`
|
|
315
|
+
`npm install -g vexi-cli`
|
|
316
316
|
|
|
317
317
|
</div>
|
package/dist/agent.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { basename } from 'node:path';
|
|
18
18
|
import { platform } from 'node:os';
|
|
19
19
|
import { input, select, confirm } from '@inquirer/prompts';
|
|
20
|
+
import * as nodeRl from 'node:readline';
|
|
20
21
|
import ora from 'ora';
|
|
21
22
|
import { loadConfig, saveConfig, CONFIG_PATH } from './config.js';
|
|
22
23
|
import { createProvider, detectProvider, sanitizeKey, PROVIDER_INFO, ProviderError, } from './providers/index.js';
|
|
@@ -28,6 +29,42 @@ import { McpManager, parseToolCall } from './mcp/client.js';
|
|
|
28
29
|
import { loadMcpConfig } from './mcp/config.js';
|
|
29
30
|
import { ARABIC_RTL_NOTE, getStrings, t } from './i18n/index.js';
|
|
30
31
|
import { accent, dim, err, ok, printBanner, printStatusLine, userPrompt, vexiLabel, warn } from './ui/index.js';
|
|
32
|
+
/**
|
|
33
|
+
* Read a user message with multi-line paste support.
|
|
34
|
+
* Lines pasted together arrive within milliseconds of each other;
|
|
35
|
+
* a 30 ms debounce collects them all before resolving.
|
|
36
|
+
*/
|
|
37
|
+
function readMessage(rl, prompt) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const lines = [];
|
|
40
|
+
let settled = false;
|
|
41
|
+
let timer = null;
|
|
42
|
+
const finish = () => {
|
|
43
|
+
if (settled)
|
|
44
|
+
return;
|
|
45
|
+
settled = true;
|
|
46
|
+
rl.removeListener('line', onLine);
|
|
47
|
+
rl.removeListener('close', onClose);
|
|
48
|
+
resolve(lines.join('\n'));
|
|
49
|
+
};
|
|
50
|
+
const onLine = (line) => {
|
|
51
|
+
lines.push(line);
|
|
52
|
+
if (timer)
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
timer = setTimeout(finish, 30);
|
|
55
|
+
};
|
|
56
|
+
const onClose = () => {
|
|
57
|
+
if (!settled) {
|
|
58
|
+
settled = true;
|
|
59
|
+
rl.removeListener('line', onLine);
|
|
60
|
+
reject(Object.assign(new Error('stdin closed'), { name: 'ExitPromptError' }));
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
rl.on('line', onLine);
|
|
64
|
+
rl.once('close', onClose);
|
|
65
|
+
process.stdout.write(prompt + ' ');
|
|
66
|
+
});
|
|
67
|
+
}
|
|
31
68
|
export async function runAgent(opts) {
|
|
32
69
|
const s = getStrings(opts.lang);
|
|
33
70
|
printBanner(opts.version);
|
|
@@ -46,6 +83,10 @@ export async function runAgent(opts) {
|
|
|
46
83
|
}
|
|
47
84
|
let provider = createProvider(config.provider, config.apiKey, config.model);
|
|
48
85
|
const root = process.cwd();
|
|
86
|
+
// Create a persistent readline interface for the chat loop.
|
|
87
|
+
// Must be created AFTER all inquirer prompts (first-run setup) are done.
|
|
88
|
+
const chatRl = nodeRl.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
89
|
+
chatRl.on('SIGINT', () => process.exit(0));
|
|
49
90
|
// ── Full project understanding: scan + load memory + load skills ──────
|
|
50
91
|
const scanSpinner = ora({ text: dim(s.scanning), spinner: 'dots' }).start();
|
|
51
92
|
let project = null;
|
|
@@ -129,11 +170,12 @@ export async function runAgent(opts) {
|
|
|
129
170
|
while (true) {
|
|
130
171
|
let line;
|
|
131
172
|
try {
|
|
132
|
-
line = await
|
|
173
|
+
line = await readMessage(chatRl, userPrompt);
|
|
133
174
|
}
|
|
134
175
|
catch {
|
|
135
176
|
// Ctrl+C / closed stdin
|
|
136
177
|
console.log('\n' + ok(s.goodbye));
|
|
178
|
+
chatRl.close();
|
|
137
179
|
return;
|
|
138
180
|
}
|
|
139
181
|
const text = line.trim();
|
|
@@ -146,6 +188,7 @@ export async function runAgent(opts) {
|
|
|
146
188
|
case '/exit':
|
|
147
189
|
case '/quit':
|
|
148
190
|
console.log(ok(s.goodbye));
|
|
191
|
+
chatRl.close();
|
|
149
192
|
await mcp.close();
|
|
150
193
|
return;
|
|
151
194
|
case '/help':
|