xibecode 0.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.
- package/README.md +434 -0
- package/dist/commands/chat.d.ts +8 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +259 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config.d.ts +10 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +196 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/run.d.ts +11 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +143 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/core/agent.d.ts +49 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +392 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/context.d.ts +82 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +273 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/editor.d.ts +68 -0
- package/dist/core/editor.d.ts.map +1 -0
- package/dist/core/editor.js +271 -0
- package/dist/core/editor.js.map +1 -0
- package/dist/core/tools.d.ts +34 -0
- package/dist/core/tools.d.ts.map +1 -0
- package/dist/core/tools.js +675 -0
- package/dist/core/tools.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/enhanced-tui.d.ts +51 -0
- package/dist/ui/enhanced-tui.d.ts.map +1 -0
- package/dist/ui/enhanced-tui.js +438 -0
- package/dist/ui/enhanced-tui.js.map +1 -0
- package/dist/utils/config.d.ts +76 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +144 -0
- package/dist/utils/config.js.map +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
# XibeCode - AI Coding Assistant
|
|
2
|
+
|
|
3
|
+
> **Production-ready autonomous coding agent powered by Claude AI**
|
|
4
|
+
|
|
5
|
+
XibeCode is a professional CLI tool that brings autonomous AI coding capabilities to your terminal. Like Claude Code, but open-source, customizable, and with advanced context management.
|
|
6
|
+
|
|
7
|
+
## ๐ฏ Key Features
|
|
8
|
+
|
|
9
|
+
### Core Capabilities
|
|
10
|
+
- โ
**Autonomous Agent Loop** - AI iteratively works on tasks until completion
|
|
11
|
+
- โ
**Smart Context Management** - Automatically loads related files (imports, tests, configs)
|
|
12
|
+
- โ
**Advanced File Editing** - Search/replace, line-range edits, automatic backups
|
|
13
|
+
- โ
**Cross-Platform** - Works on Windows, macOS, and Linux
|
|
14
|
+
- โ
**Beautiful TUI** - Real-time progress, colored output, clear visualization
|
|
15
|
+
- โ
**Loop Detection** - Prevents infinite loops and runaway executions
|
|
16
|
+
- โ
**Multiple Edit Methods** - Smart edit, line-range edit, insert, revert
|
|
17
|
+
|
|
18
|
+
### File Operations
|
|
19
|
+
- ๐ Read files (whole or partial for large files)
|
|
20
|
+
- ๐ Write files (create or overwrite)
|
|
21
|
+
- โ๏ธ Edit files (search/replace with automatic backups)
|
|
22
|
+
- โ๏ธ Edit specific line ranges
|
|
23
|
+
- โฉ๏ธ Revert to previous versions
|
|
24
|
+
- ๐ Search files with glob patterns
|
|
25
|
+
- ๐ List directories
|
|
26
|
+
- ๐ง Get intelligent context (related files)
|
|
27
|
+
|
|
28
|
+
### Command Execution
|
|
29
|
+
- โก Run shell commands
|
|
30
|
+
- ๐ง Cross-platform command support
|
|
31
|
+
- ๐ Capture stdout/stderr
|
|
32
|
+
- โ
Exit code handling
|
|
33
|
+
|
|
34
|
+
## ๐ฆ Installation
|
|
35
|
+
|
|
36
|
+
### From npm (Recommended)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g xibecode
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### From Source
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/yourusername/xibecode
|
|
46
|
+
cd xibecode
|
|
47
|
+
npm install
|
|
48
|
+
npm run build
|
|
49
|
+
npm link
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## ๐ Quick Start
|
|
53
|
+
|
|
54
|
+
### 1. Set up API Key
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Interactive setup
|
|
58
|
+
xibecode config
|
|
59
|
+
|
|
60
|
+
# Or set directly
|
|
61
|
+
xibecode config --set-key YOUR_ANTHROPIC_API_KEY
|
|
62
|
+
|
|
63
|
+
# Or use environment variable
|
|
64
|
+
export ANTHROPIC_API_KEY=your_key_here
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 2. Run Your First Task
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
xibecode run "Create a Python script that prints hello world"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. Try Interactive Chat
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
xibecode chat
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## ๐ก Usage
|
|
80
|
+
|
|
81
|
+
### Run Command (Autonomous Mode)
|
|
82
|
+
|
|
83
|
+
The main command for autonomous coding tasks:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
xibecode run [prompt] [options]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Options:**
|
|
90
|
+
- `-f, --file <path>` - Read prompt from a file
|
|
91
|
+
- `-m, --model <model>` - AI model to use (default: claude-sonnet-4-5-20250929)
|
|
92
|
+
- `-b, --base-url <url>` - Custom API base URL
|
|
93
|
+
- `-k, --api-key <key>` - API key (overrides config)
|
|
94
|
+
- `-d, --max-iterations <number>` - Maximum iterations (default: 50)
|
|
95
|
+
- `-v, --verbose` - Show detailed logs
|
|
96
|
+
|
|
97
|
+
**Examples:**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Simple task
|
|
101
|
+
xibecode run "Create a REST API with Express"
|
|
102
|
+
|
|
103
|
+
# From file
|
|
104
|
+
xibecode run --file task.txt
|
|
105
|
+
|
|
106
|
+
# With verbose logging
|
|
107
|
+
xibecode run "Fix the bug in app.js" --verbose
|
|
108
|
+
|
|
109
|
+
# Using specific model
|
|
110
|
+
xibecode run "Optimize this code" --model claude-opus-4-5-20251101
|
|
111
|
+
|
|
112
|
+
# Custom API endpoint
|
|
113
|
+
xibecode run "task" --base-url https://custom-api.com
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Chat Command (Interactive Mode)
|
|
117
|
+
|
|
118
|
+
For quick questions and iterative development:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
xibecode chat [options]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Options:**
|
|
125
|
+
- `-m, --model <model>` - AI model to use
|
|
126
|
+
- `-b, --base-url <url>` - Custom API base URL
|
|
127
|
+
- `-k, --api-key <key>` - API key
|
|
128
|
+
|
|
129
|
+
**Commands in chat:**
|
|
130
|
+
- `tools on/off` - Toggle tool execution
|
|
131
|
+
- `clear` - Clear screen
|
|
132
|
+
- `exit` or `quit` - Exit chat
|
|
133
|
+
|
|
134
|
+
**Example:**
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
$ xibecode chat
|
|
138
|
+
|
|
139
|
+
You: How do I implement JWT authentication?
|
|
140
|
+
Assistant: [explains JWT auth]
|
|
141
|
+
|
|
142
|
+
You: Write the code for it
|
|
143
|
+
Assistant: [writes code using tools]
|
|
144
|
+
|
|
145
|
+
You: Add it to my Express app
|
|
146
|
+
Assistant: [modifies app.js]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Config Command
|
|
150
|
+
|
|
151
|
+
Manage your configuration:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Interactive setup
|
|
155
|
+
xibecode config
|
|
156
|
+
|
|
157
|
+
# Quick operations
|
|
158
|
+
xibecode config --set-key YOUR_KEY
|
|
159
|
+
xibecode config --set-url https://custom-api.com
|
|
160
|
+
xibecode config --set-model claude-opus-4-5-20251101
|
|
161
|
+
xibecode config --show
|
|
162
|
+
xibecode config --reset
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## ๐จ What Makes XibeCode Different
|
|
166
|
+
|
|
167
|
+
### 1. **Smart Context Management**
|
|
168
|
+
|
|
169
|
+
XibeCode automatically understands your project:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
xibecode run "Add error handling to userController.js"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The AI will:
|
|
176
|
+
- Read `userController.js`
|
|
177
|
+
- Find and read imported files
|
|
178
|
+
- Check for related test files
|
|
179
|
+
- Look at config files (package.json, tsconfig.json)
|
|
180
|
+
- Make informed edits with full context
|
|
181
|
+
|
|
182
|
+
### 2. **Advanced File Editing**
|
|
183
|
+
|
|
184
|
+
Three ways to edit files:
|
|
185
|
+
|
|
186
|
+
#### Search/Replace (Most Reliable)
|
|
187
|
+
```javascript
|
|
188
|
+
{
|
|
189
|
+
tool: "edit_file",
|
|
190
|
+
path: "app.js",
|
|
191
|
+
search: "const port = 3000;",
|
|
192
|
+
replace: "const port = process.env.PORT || 3000;"
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Line Range (For Large Files)
|
|
197
|
+
```javascript
|
|
198
|
+
{
|
|
199
|
+
tool: "edit_lines",
|
|
200
|
+
path: "app.js",
|
|
201
|
+
start_line: 10,
|
|
202
|
+
end_line: 15,
|
|
203
|
+
new_content: "// Updated code here"
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Insert (Add New Code)
|
|
208
|
+
```javascript
|
|
209
|
+
{
|
|
210
|
+
tool: "insert_at_line",
|
|
211
|
+
path: "app.js",
|
|
212
|
+
line: 5,
|
|
213
|
+
content: "const express = require('express');"
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 3. **Automatic Backups & Revert**
|
|
218
|
+
|
|
219
|
+
Every edit creates a backup. Made a mistake?
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
xibecode run "Revert app.js to previous version"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 4. **Cross-Platform**
|
|
226
|
+
|
|
227
|
+
Works identically on:
|
|
228
|
+
- โ
Windows (PowerShell)
|
|
229
|
+
- โ
macOS (bash/zsh)
|
|
230
|
+
- โ
Linux (bash)
|
|
231
|
+
|
|
232
|
+
The AI automatically uses the right commands for your OS.
|
|
233
|
+
|
|
234
|
+
### 5. **Beautiful Real-Time UI**
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
238
|
+
โ XibeCode AI Agent โ
|
|
239
|
+
โ Autonomous Coding Assistant v1.0.0 โ
|
|
240
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
241
|
+
|
|
242
|
+
๐ Task:
|
|
243
|
+
Create a REST API with Express
|
|
244
|
+
|
|
245
|
+
โ๏ธ Configuration:
|
|
246
|
+
Model: claude-sonnet-4-5-20250929
|
|
247
|
+
Max Iterations: 50
|
|
248
|
+
|
|
249
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
250
|
+
|
|
251
|
+
Iteration 1/50 (2%) - 0.5s
|
|
252
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
253
|
+
|
|
254
|
+
๐ read_file
|
|
255
|
+
โ package.json
|
|
256
|
+
โ Success
|
|
257
|
+
โ 25 lines
|
|
258
|
+
|
|
259
|
+
๐ write_file
|
|
260
|
+
โ src/server.js
|
|
261
|
+
โ Success
|
|
262
|
+
โ File created (45 lines)
|
|
263
|
+
|
|
264
|
+
๐ฌ Assistant:
|
|
265
|
+
I've created an Express server with the following endpoints...
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## ๐ ๏ธ Advanced Features
|
|
269
|
+
|
|
270
|
+
### Custom API Endpoints
|
|
271
|
+
|
|
272
|
+
Use with Azure, AWS Bedrock, or custom Claude deployments:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Via config
|
|
276
|
+
xibecode config --set-url https://your-custom-endpoint.com
|
|
277
|
+
|
|
278
|
+
# Via command
|
|
279
|
+
xibecode run "task" --base-url https://your-custom-endpoint.com
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Working with Large Files
|
|
283
|
+
|
|
284
|
+
For files >1000 lines, read in chunks:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
xibecode run "Fix the bug around line 500 in large-file.js"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The AI will:
|
|
291
|
+
1. Read lines 450-550 (context around the area)
|
|
292
|
+
2. Make targeted edit using line numbers
|
|
293
|
+
3. Verify the change
|
|
294
|
+
|
|
295
|
+
### Project Context Understanding
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
xibecode run "Understand this project structure and suggest improvements"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The AI will use `get_context` to:
|
|
302
|
+
- Map import relationships
|
|
303
|
+
- Find test files
|
|
304
|
+
- Read configs
|
|
305
|
+
- Build a mental model
|
|
306
|
+
|
|
307
|
+
### Error Recovery
|
|
308
|
+
|
|
309
|
+
If something fails, the AI will:
|
|
310
|
+
1. Read the error message
|
|
311
|
+
2. Analyze what went wrong
|
|
312
|
+
3. Try a different approach
|
|
313
|
+
4. Can revert changes if needed
|
|
314
|
+
|
|
315
|
+
## ๐ Usage Examples
|
|
316
|
+
|
|
317
|
+
### Build a Feature
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
xibecode run "Add user authentication to the Express API:
|
|
321
|
+
- POST /auth/register
|
|
322
|
+
- POST /auth/login
|
|
323
|
+
- JWT token generation
|
|
324
|
+
- Middleware to protect routes
|
|
325
|
+
- Hash passwords with bcrypt"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Fix a Bug
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
xibecode run "The tests in test/user.test.js are failing.
|
|
332
|
+
Debug and fix the issues." --verbose
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Refactor Code
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
xibecode run "Refactor src/ to use TypeScript:
|
|
339
|
+
- Convert all .js files to .ts
|
|
340
|
+
- Add type annotations
|
|
341
|
+
- Create types.ts for shared types
|
|
342
|
+
- Update tsconfig.json"
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Generate Tests
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
xibecode run "Write comprehensive tests for userController.js:
|
|
349
|
+
- Test all endpoints
|
|
350
|
+
- Test error cases
|
|
351
|
+
- Use Jest
|
|
352
|
+
- Achieve >80% coverage"
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## โ๏ธ Configuration
|
|
356
|
+
|
|
357
|
+
XibeCode stores config in `~/.xibecode/`
|
|
358
|
+
|
|
359
|
+
### Available Settings
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
{
|
|
363
|
+
"apiKey": "sk-ant-...", // Your Anthropic API key
|
|
364
|
+
"baseUrl": "https://...", // Custom API endpoint (optional)
|
|
365
|
+
"model": "claude-sonnet-4-5-...", // Default model
|
|
366
|
+
"maxIterations": 50, // Default max iterations
|
|
367
|
+
"defaultVerbose": false // Default verbose mode
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Environment Variables
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
ANTHROPIC_API_KEY=your_key # API key
|
|
375
|
+
ANTHROPIC_BASE_URL=https://... # Custom endpoint
|
|
376
|
+
XIBECODE_MODEL=claude-opus-4-... # Default model
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Config priority: CLI flags > Environment > Config file
|
|
380
|
+
|
|
381
|
+
## ๐ Safety Features
|
|
382
|
+
|
|
383
|
+
- **Loop Detection** - Stops if AI repeats the same action 3+ times
|
|
384
|
+
- **Max Iterations** - Hard limit on iterations (default: 50)
|
|
385
|
+
- **Automatic Backups** - Every edit is backed up
|
|
386
|
+
- **Revert Capability** - Can undo changes
|
|
387
|
+
- **Error Recovery** - Handles failures gracefully
|
|
388
|
+
- **Read-Before-Edit** - AI reads files before modifying
|
|
389
|
+
|
|
390
|
+
## ๐ Performance
|
|
391
|
+
|
|
392
|
+
- **Startup**: <1 second
|
|
393
|
+
- **First response**: 2-5 seconds (API latency)
|
|
394
|
+
- **Tool execution**: Instant to seconds
|
|
395
|
+
- **Memory**: ~50MB typical
|
|
396
|
+
- **Context window**: 100k tokens (smart management)
|
|
397
|
+
|
|
398
|
+
## ๐ Comparison
|
|
399
|
+
|
|
400
|
+
| Feature | XibeCode | Claude Code | Aider |
|
|
401
|
+
|---------|----------|-------------|-------|
|
|
402
|
+
| Open Source | โ
| โ | โ
|
|
|
403
|
+
| Custom API URL | โ
| โ | โ
|
|
|
404
|
+
| Smart Context | โ
| โ
| โ ๏ธ |
|
|
405
|
+
| File Editing | โ
Advanced | โ
| โ
|
|
|
406
|
+
| Cross-Platform | โ
| โ
| โ
|
|
|
407
|
+
| Loop Detection | โ
| โ
| โ |
|
|
408
|
+
| Auto Backups | โ
| โ ๏ธ | โ |
|
|
409
|
+
| Beautiful TUI | โ
| โ
| โ ๏ธ |
|
|
410
|
+
| Price | Free (your API) | $20/mo | Free |
|
|
411
|
+
|
|
412
|
+
## ๐ค Contributing
|
|
413
|
+
|
|
414
|
+
Contributions welcome! Please see CONTRIBUTING.md
|
|
415
|
+
|
|
416
|
+
## ๐ License
|
|
417
|
+
|
|
418
|
+
MIT
|
|
419
|
+
|
|
420
|
+
## ๐ Credits
|
|
421
|
+
|
|
422
|
+
Built with:
|
|
423
|
+
- [@anthropic-ai/sdk](https://www.npmjs.com/package/@anthropic-ai/sdk)
|
|
424
|
+
- [Commander.js](https://github.com/tj/commander.js/)
|
|
425
|
+
- [Inquirer.js](https://github.com/SBoudrias/Inquirer.js/)
|
|
426
|
+
- [Chalk](https://github.com/chalk/chalk)
|
|
427
|
+
- [fast-glob](https://github.com/mrmlnc/fast-glob)
|
|
428
|
+
|
|
429
|
+
Inspired by [Claude Code](https://www.anthropic.com/news/claude-code) and [Aider](https://github.com/paul-gauthier/aider)
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
**Made with โค๏ธ for developers who love AI-assisted coding**
|
|
434
|
+
# XibeCode
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AASA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,iBAgSrD"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import { EnhancedAgent } from '../core/agent.js';
|
|
3
|
+
import { CodingToolExecutor } from '../core/tools.js';
|
|
4
|
+
import { EnhancedUI } from '../ui/enhanced-tui.js';
|
|
5
|
+
import { ConfigManager } from '../utils/config.js';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import * as fs from 'fs/promises';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
export async function chatCommand(options) {
|
|
10
|
+
const ui = new EnhancedUI(false);
|
|
11
|
+
const config = new ConfigManager();
|
|
12
|
+
ui.clear();
|
|
13
|
+
ui.header('1.0.0');
|
|
14
|
+
// Get API key
|
|
15
|
+
const apiKey = options.apiKey || config.getApiKey();
|
|
16
|
+
if (!apiKey) {
|
|
17
|
+
ui.error('No API key found!');
|
|
18
|
+
console.log(chalk.white(' Set your API key:\n'));
|
|
19
|
+
console.log(chalk.cyan(' xibecode config --set-key YOUR_KEY\n'));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const model = options.model || config.getModel();
|
|
23
|
+
const baseUrl = options.baseUrl || config.getBaseUrl();
|
|
24
|
+
// Geminiโstyle intro screen
|
|
25
|
+
ui.chatBanner(process.cwd(), model, baseUrl);
|
|
26
|
+
let enableTools = true;
|
|
27
|
+
const toolExecutor = new CodingToolExecutor(process.cwd());
|
|
28
|
+
// โโ Create ONE agent for the entire chat session โโ
|
|
29
|
+
// This keeps conversation history (messages) across all turns,
|
|
30
|
+
// so the AI remembers everything you talked about.
|
|
31
|
+
const agent = new EnhancedAgent({
|
|
32
|
+
apiKey,
|
|
33
|
+
baseUrl,
|
|
34
|
+
model,
|
|
35
|
+
maxIterations: 150,
|
|
36
|
+
verbose: false,
|
|
37
|
+
});
|
|
38
|
+
let hasResponse = false;
|
|
39
|
+
// Set up event handlers ONCE (agent is reused across turns)
|
|
40
|
+
agent.on('event', (event) => {
|
|
41
|
+
switch (event.type) {
|
|
42
|
+
case 'thinking':
|
|
43
|
+
if (!hasResponse) {
|
|
44
|
+
ui.thinking(event.data.message || 'Analyzing your request...');
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
// โโ Streaming โโ
|
|
48
|
+
case 'stream_start':
|
|
49
|
+
ui.startAssistantResponse();
|
|
50
|
+
hasResponse = true;
|
|
51
|
+
break;
|
|
52
|
+
case 'stream_text':
|
|
53
|
+
ui.streamText(event.data.text);
|
|
54
|
+
break;
|
|
55
|
+
case 'stream_end':
|
|
56
|
+
ui.endAssistantResponse();
|
|
57
|
+
break;
|
|
58
|
+
// โโ Non-streaming fallback โโ
|
|
59
|
+
case 'response':
|
|
60
|
+
if (!hasResponse) {
|
|
61
|
+
ui.response(event.data.text);
|
|
62
|
+
hasResponse = true;
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
// โโ Tools โโ
|
|
66
|
+
case 'tool_call':
|
|
67
|
+
if (enableTools) {
|
|
68
|
+
ui.toolCall(event.data.name, event.data.input);
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
case 'tool_result':
|
|
72
|
+
if (enableTools) {
|
|
73
|
+
ui.toolResult(event.data.name, event.data.result, event.data.success);
|
|
74
|
+
const r = event.data.result;
|
|
75
|
+
if (r?.success && event.data.name === 'write_file') {
|
|
76
|
+
ui.fileChanged('created', r.path, r.lines ? `${r.lines} lines` : undefined);
|
|
77
|
+
}
|
|
78
|
+
else if (r?.success && event.data.name === 'edit_file') {
|
|
79
|
+
ui.fileChanged('modified', r.path || '', r.linesChanged ? `${r.linesChanged} lines` : undefined);
|
|
80
|
+
}
|
|
81
|
+
else if (r?.success && event.data.name === 'edit_lines') {
|
|
82
|
+
ui.fileChanged('modified', r.path || '', r.linesChanged ? `${r.linesChanged} lines` : undefined);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
// โโ Iteration โโ
|
|
87
|
+
case 'iteration':
|
|
88
|
+
if (!hasResponse && event.data?.current) {
|
|
89
|
+
ui.updateThinking(`Thinking... step ${event.data.current}`);
|
|
90
|
+
}
|
|
91
|
+
hasResponse = false;
|
|
92
|
+
break;
|
|
93
|
+
// โโ Errors / Warnings โโ
|
|
94
|
+
case 'error':
|
|
95
|
+
ui.error(event.data.message || event.data.error);
|
|
96
|
+
break;
|
|
97
|
+
case 'warning':
|
|
98
|
+
ui.warning(event.data.message);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
async function showPathSuggestions(raw) {
|
|
103
|
+
const input = raw.trim().slice(1).trim(); // drop leading '@'
|
|
104
|
+
const target = input ? path.resolve(process.cwd(), input) : process.cwd();
|
|
105
|
+
try {
|
|
106
|
+
const stats = await fs.stat(target);
|
|
107
|
+
const dir = stats.isDirectory() ? target : path.dirname(target);
|
|
108
|
+
const base = stats.isDirectory() ? '' : path.basename(target);
|
|
109
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
110
|
+
const filtered = base
|
|
111
|
+
? entries.filter(e => e.name.toLowerCase().startsWith(base.toLowerCase()))
|
|
112
|
+
: entries;
|
|
113
|
+
if (!filtered.length) {
|
|
114
|
+
ui.info(`No matches under ${dir}`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
console.log('');
|
|
118
|
+
console.log(' ' + chalk.bold('Files & folders:'));
|
|
119
|
+
for (const entry of filtered.slice(0, 50)) {
|
|
120
|
+
const isDir = entry.isDirectory();
|
|
121
|
+
const name = entry.name + (isDir ? '/' : '');
|
|
122
|
+
const rel = path.relative(process.cwd(), path.join(dir, entry.name)) || '.';
|
|
123
|
+
console.log(' ' +
|
|
124
|
+
(isDir ? chalk.hex('#40C4FF')('๐') : chalk.hex('#CE93D8')('๐')) +
|
|
125
|
+
' ' +
|
|
126
|
+
chalk.white(name) +
|
|
127
|
+
chalk.hex('#6B6B7B')(` ยท ${rel}`));
|
|
128
|
+
}
|
|
129
|
+
if (filtered.length > 50) {
|
|
130
|
+
console.log(' ' + chalk.hex('#6B6B7B')(`โฆ and ${filtered.length - 50} more`));
|
|
131
|
+
}
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
ui.error('Failed to list files for @ path', error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function showSlashHelp() {
|
|
139
|
+
console.log('');
|
|
140
|
+
console.log(chalk.bold(' XibeCode chat commands'));
|
|
141
|
+
console.log(' ' + chalk.hex('#6B6B7B')('โโโโโโโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
142
|
+
console.log(' ' + chalk.hex('#00D4FF')('/help') + chalk.hex('#6B6B7B')(' show this help, not an AI reply'));
|
|
143
|
+
console.log(' ' + chalk.hex('#00D4FF')('@path') + chalk.hex('#6B6B7B')(' list files/folders under path (or cwd if just "@")'));
|
|
144
|
+
console.log(' ' + chalk.hex('#00D4FF')('clear') + chalk.hex('#6B6B7B')(' clear screen and redraw header'));
|
|
145
|
+
console.log(' ' + chalk.hex('#00D4FF')('tools on') + chalk.hex('#6B6B7B')(' enable editor & filesystem tools'));
|
|
146
|
+
console.log(' ' + chalk.hex('#00D4FF')('tools off') + chalk.hex('#6B6B7B')(' disable tools (chat only)'));
|
|
147
|
+
console.log(' ' + chalk.hex('#00D4FF')('exit / quit') + chalk.hex('#6B6B7B')(' end the chat session'));
|
|
148
|
+
console.log('');
|
|
149
|
+
}
|
|
150
|
+
// โโ Chat loop โโ
|
|
151
|
+
while (true) {
|
|
152
|
+
let { message } = await inquirer.prompt([
|
|
153
|
+
{
|
|
154
|
+
type: 'input',
|
|
155
|
+
name: 'message',
|
|
156
|
+
message: chalk.hex('#00E676').bold('โฏ You '),
|
|
157
|
+
prefix: '',
|
|
158
|
+
},
|
|
159
|
+
]);
|
|
160
|
+
// Special interactive flow when user types just "@"
|
|
161
|
+
if (message.trim() === '@') {
|
|
162
|
+
try {
|
|
163
|
+
const dir = process.cwd();
|
|
164
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
165
|
+
if (!entries.length) {
|
|
166
|
+
ui.info('No files or folders in current directory');
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const choices = entries.slice(0, 100).map(entry => {
|
|
170
|
+
const isDir = entry.isDirectory();
|
|
171
|
+
const label = (isDir ? '๐ ' : '๐ ') +
|
|
172
|
+
entry.name +
|
|
173
|
+
(isDir ? '/' : '');
|
|
174
|
+
return {
|
|
175
|
+
name: label,
|
|
176
|
+
value: entry.name + (isDir ? '/' : ''),
|
|
177
|
+
};
|
|
178
|
+
});
|
|
179
|
+
const { picked } = await inquirer.prompt([
|
|
180
|
+
{
|
|
181
|
+
type: 'list',
|
|
182
|
+
name: 'picked',
|
|
183
|
+
message: 'Select file or folder',
|
|
184
|
+
choices,
|
|
185
|
+
},
|
|
186
|
+
]);
|
|
187
|
+
const followUp = await inquirer.prompt([
|
|
188
|
+
{
|
|
189
|
+
type: 'input',
|
|
190
|
+
name: 'message',
|
|
191
|
+
message: chalk.hex('#00E676').bold('โฏ You '),
|
|
192
|
+
prefix: '',
|
|
193
|
+
default: '@' + picked,
|
|
194
|
+
},
|
|
195
|
+
]);
|
|
196
|
+
message = followUp.message;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
ui.error('Failed to list files for selection', error);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (!message.trim())
|
|
204
|
+
continue;
|
|
205
|
+
const trimmed = message.trim();
|
|
206
|
+
const lowerMessage = trimmed.toLowerCase();
|
|
207
|
+
if (lowerMessage === '/help') {
|
|
208
|
+
showSlashHelp();
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (trimmed.startsWith('@')) {
|
|
212
|
+
await showPathSuggestions(trimmed);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (lowerMessage === 'exit' || lowerMessage === 'quit') {
|
|
216
|
+
const stats = agent.getStats();
|
|
217
|
+
console.log('');
|
|
218
|
+
if (stats.toolCalls > 0 || stats.iterations > 0) {
|
|
219
|
+
console.log(chalk.hex('#6B6B7B')(` session: ${stats.iterations} turns ยท ${stats.toolCalls} tool calls ยท ${stats.filesChanged} files changed`));
|
|
220
|
+
console.log('');
|
|
221
|
+
}
|
|
222
|
+
console.log(chalk.hex('#3A3A4A')(' โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ'));
|
|
223
|
+
console.log(chalk.hex('#3A3A4A')(' โ') + chalk.hex('#00D4FF')(' ๐ See you next time! ') + chalk.hex('#3A3A4A')('โ'));
|
|
224
|
+
console.log(chalk.hex('#3A3A4A')(' โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ'));
|
|
225
|
+
console.log('');
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
if (lowerMessage === 'clear') {
|
|
229
|
+
ui.clear();
|
|
230
|
+
ui.header('1.0.0');
|
|
231
|
+
ui.chatBanner(process.cwd(), model, baseUrl);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (lowerMessage === 'tools on') {
|
|
235
|
+
enableTools = true;
|
|
236
|
+
ui.success('Tools enabled');
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (lowerMessage === 'tools off') {
|
|
240
|
+
enableTools = false;
|
|
241
|
+
ui.success('Tools disabled');
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
// Reset per-message display flag
|
|
245
|
+
hasResponse = false;
|
|
246
|
+
try {
|
|
247
|
+
const tools = enableTools ? toolExecutor.getTools() : [];
|
|
248
|
+
// agent.run() resets its iteration/tool counters but KEEPS
|
|
249
|
+
// the conversation history (this.messages), so the AI has
|
|
250
|
+
// full context of everything discussed in this session.
|
|
251
|
+
await agent.run(message, tools, toolExecutor);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
ui.error('Failed to process message', error);
|
|
255
|
+
}
|
|
256
|
+
console.log('');
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=chat.js.map
|