xibecode 0.5.4 → 0.6.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/README.md +32 -9
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +133 -34
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +33 -42
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +7 -1
- package/dist/commands/run.js.map +1 -1
- package/dist/core/agent.d.ts +9 -7
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +102 -28
- package/dist/core/agent.js.map +1 -1
- package/dist/core/background-agent.d.ts +23 -0
- package/dist/core/background-agent.d.ts.map +1 -0
- package/dist/core/background-agent.js +138 -0
- package/dist/core/background-agent.js.map +1 -0
- package/dist/core/code-graph.d.ts +18 -0
- package/dist/core/code-graph.d.ts.map +1 -0
- package/dist/core/code-graph.js +105 -0
- package/dist/core/code-graph.js.map +1 -0
- package/dist/core/conflict-solver.d.ts +26 -0
- package/dist/core/conflict-solver.d.ts.map +1 -0
- package/dist/core/conflict-solver.js +108 -0
- package/dist/core/conflict-solver.js.map +1 -0
- package/dist/core/docs-scraper.d.ts +2 -1
- package/dist/core/docs-scraper.d.ts.map +1 -1
- package/dist/core/docs-scraper.js +10 -1
- package/dist/core/docs-scraper.js.map +1 -1
- package/dist/core/modes.d.ts +1 -1
- package/dist/core/modes.d.ts.map +1 -1
- package/dist/core/modes.js +105 -5
- package/dist/core/modes.js.map +1 -1
- package/dist/core/pattern-miner.d.ts +43 -0
- package/dist/core/pattern-miner.d.ts.map +1 -0
- package/dist/core/pattern-miner.js +123 -0
- package/dist/core/pattern-miner.js.map +1 -0
- package/dist/core/planMode.d.ts +2 -1
- package/dist/core/planMode.d.ts.map +1 -1
- package/dist/core/planMode.js +6 -2
- package/dist/core/planMode.js.map +1 -1
- package/dist/core/session-bridge.d.ts +5 -1
- package/dist/core/session-bridge.d.ts.map +1 -1
- package/dist/core/session-bridge.js +13 -0
- package/dist/core/session-bridge.js.map +1 -1
- package/dist/core/skills.d.ts +2 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/swarm.d.ts +19 -0
- package/dist/core/swarm.d.ts.map +1 -0
- package/dist/core/swarm.js +77 -0
- package/dist/core/swarm.js.map +1 -0
- package/dist/core/tools.d.ts +8 -0
- package/dist/core/tools.d.ts.map +1 -1
- package/dist/core/tools.js +289 -8
- package/dist/core/tools.js.map +1 -1
- package/dist/core/visual-feedback.d.ts +20 -0
- package/dist/core/visual-feedback.d.ts.map +1 -0
- package/dist/core/visual-feedback.js +117 -0
- package/dist/core/visual-feedback.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/config.d.ts +76 -5
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +99 -22
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/git.d.ts +14 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +101 -0
- package/dist/utils/git.js.map +1 -1
- package/dist/webui/server.d.ts.map +1 -1
- package/dist/webui/server.js +78 -19
- package/dist/webui/server.js.map +1 -1
- package/package.json +23 -22
- package/webui-dist/assets/index-CSla6Lzy.css +32 -0
- package/webui-dist/assets/{index-D1p8sGlX.js → index-jeWUzIG0.js} +102 -95
- package/webui-dist/assets/index-jeWUzIG0.js.map +1 -0
- package/webui-dist/assets/{xterm-Da3kUA9L.js → xterm-B4aZdZLt.js} +2 -2
- package/webui-dist/assets/{xterm-Da3kUA9L.js.map → xterm-B4aZdZLt.js.map} +1 -1
- package/webui-dist/assets/{xterm-addon-fit-BUikER34.js → xterm-addon-fit-CY2T_uda.js} +2 -2
- package/webui-dist/assets/{xterm-addon-fit-BUikER34.js.map → xterm-addon-fit-CY2T_uda.js.map} +1 -1
- package/webui-dist/assets/{xterm-addon-web-links-DUxNSHSG.js → xterm-addon-web-links-D93WX0PV.js} +2 -2
- package/webui-dist/assets/{xterm-addon-web-links-DUxNSHSG.js.map → xterm-addon-web-links-D93WX0PV.js.map} +1 -1
- package/webui-dist/index.html +2 -2
- package/webui-dist/assets/index-6lisHL5w.css +0 -32
- package/webui-dist/assets/index-D1p8sGlX.js.map +0 -1
package/README.md
CHANGED
|
@@ -10,7 +10,32 @@ AI-powered autonomous coding assistant for your terminal, browser, and desktop.
|
|
|
10
10
|
|
|
11
11
|
XibeCode is a CLI agent that can read and edit code, run commands, and iterate on tasks from your terminal using LLMs. It includes a **WebUI** for a browser-based experience, a **Desktop App** (Electron) for native IDE-like usage, **AI-powered test generation**, and **multi-model support** for both Anthropic and OpenAI models.
|
|
12
12
|
|
|
13
|
-
## What's New in v0.5.
|
|
13
|
+
## What's New in v0.5.7
|
|
14
|
+
|
|
15
|
+
### 🚀 Native Gemini Support
|
|
16
|
+
|
|
17
|
+
XibeCode now supports Google Gemini natively via their OpenAI-compatible endpoint.
|
|
18
|
+
|
|
19
|
+
- **New Models**: Gemini 3 Deep Think, Gemini 3 Flash Preview, Gemini 2.5 Pro.
|
|
20
|
+
- **Direct Integration**: Use your Google API Key without proxies.
|
|
21
|
+
|
|
22
|
+
### 🔒 Settings Security & UI
|
|
23
|
+
|
|
24
|
+
- **Eye Toggle**: Added visibility toggle for API keys in Settings.
|
|
25
|
+
- **Improved Masking**: Better feedback for existing keys.
|
|
26
|
+
- **Native Providers**: Added native Google option in the provider dropdown.
|
|
27
|
+
|
|
28
|
+
### ⚡ Comprehensive Model Update (2025-2026)
|
|
29
|
+
|
|
30
|
+
Verified support for the latest flagships from OpenAI (GPT-5.2), Anthropic (Claude 4.6), Zhipu AI (GLM-5), and more.
|
|
31
|
+
|
|
32
|
+
### ✨ Feature Improvements
|
|
33
|
+
|
|
34
|
+
- **Enhanced Custom Providers**: Explicit "API Format" selection for custom endpoints.
|
|
35
|
+
- **UI Fixes**: Improved "Apply Custom Model" button feedback and settings persistence.
|
|
36
|
+
- **Performance**: Optimized model list loading and configuration handling.
|
|
37
|
+
|
|
38
|
+
### v0.5.4
|
|
14
39
|
|
|
15
40
|
- **Context Chips** - Terminal context (full buffer or selections) is now added as "chips" to the chat instead of raw text, keeping the interface clean while giving the AI full context.
|
|
16
41
|
- **Interactive Plan Mode** - Plan mode now asks clarifying questions, searches the web, and generates detailed `implementations.md` with checkboxes. Click "Build" to auto-execute the plan.
|
|
@@ -274,16 +299,10 @@ Type `/` in the input to open the command palette:
|
|
|
274
299
|
| `/mode agent` | 🤖 | Autonomous coding (default) |
|
|
275
300
|
| `/mode plan` | 📝 | Interactive planning with web research |
|
|
276
301
|
| `/mode tester` | 🧪 | Testing and QA |
|
|
277
|
-
| `/mode debugger` | 🐛 | Bug investigation |
|
|
278
302
|
| `/mode security` | 🔒 | Security analysis |
|
|
303
|
+
| `/mode pentest` | 🔓 | Penetration testing - run app and probe for vulnerabilities |
|
|
279
304
|
| `/mode review` | 👀 | Code review |
|
|
280
305
|
| `/mode team_leader` | 👑 | Coordinate team |
|
|
281
|
-
| `/mode architect` | 🏛️ | System design |
|
|
282
|
-
| `/mode engineer` | 🛠️ | Implementation |
|
|
283
|
-
| `/mode seo` | 🌐 | SEO optimization |
|
|
284
|
-
| `/mode product` | 🔥 | Product strategy |
|
|
285
|
-
| `/mode data` | 📊 | Data analysis |
|
|
286
|
-
| `/mode researcher` | 📚 | Deep research |
|
|
287
306
|
|
|
288
307
|
### File References (`@`)
|
|
289
308
|
|
|
@@ -447,7 +466,7 @@ POST /api/tests/run # Run project tests
|
|
|
447
466
|
|
|
448
467
|
## Project Structure
|
|
449
468
|
|
|
450
|
-
```
|
|
469
|
+
```text
|
|
451
470
|
xibecode/
|
|
452
471
|
├── src/
|
|
453
472
|
│ ├── core/ # Agent, tools, context
|
|
@@ -460,6 +479,10 @@ xibecode/
|
|
|
460
479
|
└── tests/ # Test suites
|
|
461
480
|
```
|
|
462
481
|
|
|
482
|
+
## Dependency Map
|
|
483
|
+
|
|
484
|
+

|
|
485
|
+
|
|
463
486
|
## Project Docs
|
|
464
487
|
|
|
465
488
|
- `CHANGELOG.md` — release history
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAqBA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAqBA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,iBA8+CrD"}
|
package/dist/commands/chat.js
CHANGED
|
@@ -72,7 +72,7 @@ export async function chatCommand(options) {
|
|
|
72
72
|
model,
|
|
73
73
|
maxIterations: 10,
|
|
74
74
|
verbose: false,
|
|
75
|
-
},
|
|
75
|
+
}, currentProvider || 'anthropic');
|
|
76
76
|
// Gemini‑style intro screen
|
|
77
77
|
ui.chatBanner(process.cwd(), model, baseUrl);
|
|
78
78
|
let enableTools = true;
|
|
@@ -90,6 +90,8 @@ export async function chatCommand(options) {
|
|
|
90
90
|
model,
|
|
91
91
|
maxIterations: 150,
|
|
92
92
|
verbose: false,
|
|
93
|
+
provider: currentProvider,
|
|
94
|
+
customProviderFormat: config.get('customProviderFormat'),
|
|
93
95
|
}, currentProvider);
|
|
94
96
|
const allModes = getAllModes();
|
|
95
97
|
let currentMode = agent.getMode();
|
|
@@ -126,9 +128,23 @@ export async function chatCommand(options) {
|
|
|
126
128
|
// File might not exist yet
|
|
127
129
|
}
|
|
128
130
|
}
|
|
131
|
+
// Check for [[PENTEST_READY]] tag
|
|
132
|
+
if (text.includes('[[PENTEST_READY]]')) {
|
|
133
|
+
const fs = require('fs');
|
|
134
|
+
const path = require('path');
|
|
135
|
+
const reportPath = path.join(process.cwd(), 'pentest-report.md');
|
|
136
|
+
try {
|
|
137
|
+
const reportContent = fs.readFileSync(reportPath, 'utf-8');
|
|
138
|
+
SessionBridge.onPentestReady(reportContent, 'pentest-report.md');
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// File might not exist yet
|
|
142
|
+
}
|
|
143
|
+
}
|
|
129
144
|
}
|
|
130
145
|
async function handlePlannerQuestions(questions) {
|
|
131
146
|
try {
|
|
147
|
+
closeRL();
|
|
132
148
|
const inquirer = (await import('inquirer')).default;
|
|
133
149
|
const answers = {};
|
|
134
150
|
for (const q of questions) {
|
|
@@ -189,6 +205,9 @@ export async function chatCommand(options) {
|
|
|
189
205
|
catch {
|
|
190
206
|
// Inquirer not available or error
|
|
191
207
|
}
|
|
208
|
+
finally {
|
|
209
|
+
createRL();
|
|
210
|
+
}
|
|
192
211
|
}
|
|
193
212
|
function setupAgentHandlers() {
|
|
194
213
|
agent.removeAllListeners('event');
|
|
@@ -308,18 +327,87 @@ export async function chatCommand(options) {
|
|
|
308
327
|
messages: agent.getMessages(),
|
|
309
328
|
isProcessing: false,
|
|
310
329
|
});
|
|
311
|
-
|
|
312
|
-
let
|
|
313
|
-
let
|
|
330
|
+
const inputQueue = [];
|
|
331
|
+
let inputResolver = null;
|
|
332
|
+
let isAgentRunning = false;
|
|
333
|
+
let rl = null;
|
|
334
|
+
let sigintCount = 0;
|
|
335
|
+
let lastSigintTime = 0;
|
|
336
|
+
function handleSigint() {
|
|
337
|
+
const now = Date.now();
|
|
338
|
+
// debounce in case both rl and keypress emit SIGINT
|
|
339
|
+
if (now - lastSigintTime < 100)
|
|
340
|
+
return;
|
|
341
|
+
lastSigintTime = now;
|
|
342
|
+
if (sigintCount === 0) {
|
|
343
|
+
console.log('');
|
|
344
|
+
ui.warning('Press Ctrl+C again to exit.');
|
|
345
|
+
if (!isAgentRunning)
|
|
346
|
+
promptUser();
|
|
347
|
+
sigintCount++;
|
|
348
|
+
setTimeout(() => { sigintCount = 0; }, 3000);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
process.exit(0);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function promptUser() {
|
|
355
|
+
process.stdout.write(chalk.hex('#00E676').bold('❯ You ') + '');
|
|
356
|
+
}
|
|
357
|
+
function createRL() {
|
|
358
|
+
if (rl)
|
|
359
|
+
return;
|
|
360
|
+
rl = readline.createInterface({
|
|
361
|
+
input: process.stdin,
|
|
362
|
+
output: process.stdout,
|
|
363
|
+
terminal: true
|
|
364
|
+
});
|
|
365
|
+
rl.on('line', (line) => {
|
|
366
|
+
const msg = line.trim();
|
|
367
|
+
if (!msg) {
|
|
368
|
+
if (!isAgentRunning)
|
|
369
|
+
promptUser();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (isAgentRunning) {
|
|
373
|
+
agent.injectMessage(msg);
|
|
374
|
+
console.log('');
|
|
375
|
+
ui.success(`Message queued for agent's next step.`);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
const item = { message: msg, source: 'tui' };
|
|
379
|
+
if (inputResolver) {
|
|
380
|
+
inputResolver(item);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
inputQueue.push(item);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
rl.on('SIGINT', handleSigint);
|
|
388
|
+
}
|
|
389
|
+
function closeRL() {
|
|
390
|
+
if (rl) {
|
|
391
|
+
rl.close();
|
|
392
|
+
rl = null;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
314
395
|
// Listen for messages from WebUI
|
|
315
396
|
SessionBridge.on('user_message', async (content, source) => {
|
|
316
397
|
if (source === 'webui') {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
398
|
+
if (isAgentRunning) {
|
|
399
|
+
agent.injectMessage(content);
|
|
400
|
+
console.log('');
|
|
401
|
+
ui.info(`WebUI message injected into agent's thought process.`);
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
const item = { message: content, source: 'webui' };
|
|
405
|
+
if (inputResolver) {
|
|
406
|
+
inputResolver(item);
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
inputQueue.push(item);
|
|
410
|
+
}
|
|
323
411
|
}
|
|
324
412
|
}
|
|
325
413
|
});
|
|
@@ -327,33 +415,16 @@ export async function chatCommand(options) {
|
|
|
327
415
|
* Get input from either TUI or WebUI (whichever comes first)
|
|
328
416
|
*/
|
|
329
417
|
async function getInput() {
|
|
330
|
-
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
pendingWebUIMessage = null;
|
|
334
|
-
return { message: msg, source: 'webui' };
|
|
418
|
+
createRL();
|
|
419
|
+
if (inputQueue.length > 0) {
|
|
420
|
+
return inputQueue.shift();
|
|
335
421
|
}
|
|
336
422
|
return new Promise((resolve) => {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
resolve(
|
|
423
|
+
promptUser();
|
|
424
|
+
inputResolver = (input) => {
|
|
425
|
+
inputResolver = null;
|
|
426
|
+
resolve(input);
|
|
341
427
|
};
|
|
342
|
-
// Create readline interface for TUI input
|
|
343
|
-
const rl = readline.createInterface({
|
|
344
|
-
input: process.stdin,
|
|
345
|
-
output: process.stdout,
|
|
346
|
-
});
|
|
347
|
-
// Show prompt
|
|
348
|
-
process.stdout.write(chalk.hex('#00E676').bold('❯ You ') + '');
|
|
349
|
-
rl.on('line', (line) => {
|
|
350
|
-
webUIMessageResolver = null;
|
|
351
|
-
rl.close();
|
|
352
|
-
resolve({ message: line, source: 'tui' });
|
|
353
|
-
});
|
|
354
|
-
rl.on('close', () => {
|
|
355
|
-
webUIMessageResolver = null;
|
|
356
|
-
});
|
|
357
428
|
});
|
|
358
429
|
}
|
|
359
430
|
async function showPathSuggestions(raw) {
|
|
@@ -477,6 +548,7 @@ export async function chatCommand(options) {
|
|
|
477
548
|
ui.info('No saved sessions yet.');
|
|
478
549
|
return;
|
|
479
550
|
}
|
|
551
|
+
closeRL();
|
|
480
552
|
const { picked } = await inquirer.prompt([
|
|
481
553
|
{
|
|
482
554
|
type: 'list',
|
|
@@ -488,6 +560,7 @@ export async function chatCommand(options) {
|
|
|
488
560
|
})),
|
|
489
561
|
},
|
|
490
562
|
]);
|
|
563
|
+
createRL();
|
|
491
564
|
const loaded = await sessionManager.loadSession(picked);
|
|
492
565
|
if (!loaded) {
|
|
493
566
|
ui.error('Failed to load selected session');
|
|
@@ -505,6 +578,8 @@ export async function chatCommand(options) {
|
|
|
505
578
|
model,
|
|
506
579
|
maxIterations: 150,
|
|
507
580
|
verbose: false,
|
|
581
|
+
provider: currentProvider || config.get('provider'),
|
|
582
|
+
customProviderFormat: config.get('customProviderFormat'),
|
|
508
583
|
}, currentProvider || config.get('provider'));
|
|
509
584
|
setupAgentHandlers();
|
|
510
585
|
currentMode = agent.getMode();
|
|
@@ -519,6 +594,7 @@ export async function chatCommand(options) {
|
|
|
519
594
|
];
|
|
520
595
|
const customModels = (config.get('customModels') || []);
|
|
521
596
|
const unique = Array.from(new Set([current, ...fixedModels, ...customModels.map(m => m.id)]));
|
|
597
|
+
closeRL();
|
|
522
598
|
const { picked } = await inquirer.prompt([
|
|
523
599
|
{
|
|
524
600
|
type: 'list',
|
|
@@ -532,11 +608,13 @@ export async function chatCommand(options) {
|
|
|
532
608
|
}),
|
|
533
609
|
},
|
|
534
610
|
]);
|
|
611
|
+
createRL();
|
|
535
612
|
config.set('model', picked);
|
|
536
613
|
ui.success(`Model set to: ${picked}`);
|
|
537
614
|
}
|
|
538
615
|
async function handleThemesCommand() {
|
|
539
616
|
const current = ui.getThemeName();
|
|
617
|
+
closeRL();
|
|
540
618
|
const { picked } = await inquirer.prompt([
|
|
541
619
|
{
|
|
542
620
|
type: 'list',
|
|
@@ -548,6 +626,7 @@ export async function chatCommand(options) {
|
|
|
548
626
|
})),
|
|
549
627
|
},
|
|
550
628
|
]);
|
|
629
|
+
createRL();
|
|
551
630
|
ui.setTheme(picked);
|
|
552
631
|
config.set('theme', picked);
|
|
553
632
|
ui.success(`Theme set to: ${picked}`);
|
|
@@ -663,6 +742,10 @@ export async function chatCommand(options) {
|
|
|
663
742
|
process.stdin.on('keypress', (_str, key) => {
|
|
664
743
|
if (!key)
|
|
665
744
|
return;
|
|
745
|
+
if (key.ctrl && key.name === 'c') {
|
|
746
|
+
handleSigint();
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
666
749
|
if (key.name === 'tab') {
|
|
667
750
|
const idx = allModes.indexOf(currentMode);
|
|
668
751
|
const next = allModes[(idx + 1) % allModes.length];
|
|
@@ -713,6 +796,7 @@ export async function chatCommand(options) {
|
|
|
713
796
|
value: entry.name + (isDir ? '/' : ''),
|
|
714
797
|
};
|
|
715
798
|
});
|
|
799
|
+
closeRL();
|
|
716
800
|
const { picked } = await inquirer.prompt([
|
|
717
801
|
{
|
|
718
802
|
type: 'list',
|
|
@@ -730,9 +814,11 @@ export async function chatCommand(options) {
|
|
|
730
814
|
default: '@' + picked,
|
|
731
815
|
},
|
|
732
816
|
]);
|
|
817
|
+
createRL();
|
|
733
818
|
message = followUp.message;
|
|
734
819
|
}
|
|
735
820
|
catch (error) {
|
|
821
|
+
createRL();
|
|
736
822
|
ui.error('Failed to list files for selection', error);
|
|
737
823
|
continue;
|
|
738
824
|
}
|
|
@@ -804,6 +890,7 @@ export async function chatCommand(options) {
|
|
|
804
890
|
continue;
|
|
805
891
|
}
|
|
806
892
|
if (lowerMessage === '/provider') {
|
|
893
|
+
closeRL();
|
|
807
894
|
const { picked } = await inquirer.prompt([
|
|
808
895
|
{
|
|
809
896
|
type: 'list',
|
|
@@ -815,6 +902,7 @@ export async function chatCommand(options) {
|
|
|
815
902
|
],
|
|
816
903
|
},
|
|
817
904
|
]);
|
|
905
|
+
createRL();
|
|
818
906
|
currentProvider = picked;
|
|
819
907
|
config.set('provider', picked);
|
|
820
908
|
// Recreate agent with new provider but keep conversation history
|
|
@@ -1040,6 +1128,7 @@ export async function chatCommand(options) {
|
|
|
1040
1128
|
});
|
|
1041
1129
|
console.log('');
|
|
1042
1130
|
// Prompt to install
|
|
1131
|
+
closeRL();
|
|
1043
1132
|
const { installChoice } = await inquirer.prompt([
|
|
1044
1133
|
{
|
|
1045
1134
|
type: 'list',
|
|
@@ -1054,6 +1143,7 @@ export async function chatCommand(options) {
|
|
|
1054
1143
|
],
|
|
1055
1144
|
},
|
|
1056
1145
|
]);
|
|
1146
|
+
createRL();
|
|
1057
1147
|
if (installChoice === '__cancel__') {
|
|
1058
1148
|
continue;
|
|
1059
1149
|
}
|
|
@@ -1244,10 +1334,19 @@ export async function chatCommand(options) {
|
|
|
1244
1334
|
if (messageSource === 'tui') {
|
|
1245
1335
|
SessionBridge.onTUIUserMessage(message);
|
|
1246
1336
|
}
|
|
1337
|
+
isAgentRunning = true;
|
|
1247
1338
|
// agent.run() resets its iteration/tool counters but KEEPS
|
|
1248
1339
|
// the conversation history (this.messages), so the AI has
|
|
1249
1340
|
// full context of everything discussed in this session.
|
|
1250
1341
|
await agent.run(message, tools, toolExecutor);
|
|
1342
|
+
isAgentRunning = false;
|
|
1343
|
+
const unhandled = agent.getInjectedMessages();
|
|
1344
|
+
if (unhandled.length > 0) {
|
|
1345
|
+
agent.clearInjectedMessages();
|
|
1346
|
+
for (const msg of unhandled) {
|
|
1347
|
+
inputQueue.push({ message: msg, source: 'tui' });
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1251
1350
|
const stats = agent.getStats();
|
|
1252
1351
|
// Update SessionBridge with latest messages
|
|
1253
1352
|
SessionBridge.updateState({ messages: agent.getMessages() });
|