agdi 2.5.1 → 2.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 +184 -23
- package/dist/chunk-NVMD3WL3.js +349 -0
- package/dist/index.js +244 -7
- package/dist/rag-6HO4ZLBN.js +16 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
[](https://nodejs.org/)
|
|
20
20
|
[](https://www.typescriptlang.org/)
|
|
21
21
|
|
|
22
|
-
**Build full-stack apps from natural language •
|
|
22
|
+
**Build full-stack apps from natural language • Multi-Agent AI • Codebase RAG • Enterprise Security**
|
|
23
23
|
|
|
24
24
|
[Website](https://agdi-dev.vercel.app) · [npm](https://www.npmjs.com/package/agdi) · [GitHub](https://github.com/anassagd432/Agdi-dev)
|
|
25
25
|
|
|
@@ -27,6 +27,71 @@
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
+
## 🚀 What's New in v2.6
|
|
31
|
+
|
|
32
|
+
<table>
|
|
33
|
+
<tr>
|
|
34
|
+
<td width="50%">
|
|
35
|
+
|
|
36
|
+
### 🤖 Multi-Agent System
|
|
37
|
+
Planner → Coder → Reviewer pipeline. Your code is reviewed by AI before delivery.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
→ /agent
|
|
41
|
+
🤖 Multi-agent mode: ON
|
|
42
|
+
Planner → Coder → Reviewer pipeline enabled
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</td>
|
|
46
|
+
<td width="50%">
|
|
47
|
+
|
|
48
|
+
### 🔍 Codebase RAG
|
|
49
|
+
Index and search your entire project semantically. The AI understands your code.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
→ /index
|
|
53
|
+
✓ Indexed 47 files, 312 chunks
|
|
54
|
+
|
|
55
|
+
→ /search authentication
|
|
56
|
+
🔍 src/auth/login.ts:15 (0.87)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
</td>
|
|
60
|
+
</tr>
|
|
61
|
+
<tr>
|
|
62
|
+
<td width="50%">
|
|
63
|
+
|
|
64
|
+
### 🔧 MCP Tool Integration
|
|
65
|
+
Model Context Protocol for standardized AI tool calls.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
→ /tools
|
|
69
|
+
🔧 Available Tools
|
|
70
|
+
read_file [filesystem]
|
|
71
|
+
list_dir [filesystem]
|
|
72
|
+
search_code [code]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
</td>
|
|
76
|
+
<td width="50%">
|
|
77
|
+
|
|
78
|
+
### 🧠 Persistent Memory
|
|
79
|
+
AI remembers your preferences and project context across sessions.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
→ /memory
|
|
83
|
+
🧠 Memory Stats
|
|
84
|
+
Total entries: 12
|
|
85
|
+
Projects: 3
|
|
86
|
+
Preferences: 5
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
</td>
|
|
90
|
+
</tr>
|
|
91
|
+
</table>
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
30
95
|
## ⚡ Quick Start
|
|
31
96
|
|
|
32
97
|
```bash
|
|
@@ -50,13 +115,25 @@ $ agdi
|
|
|
50
115
|
|
|
51
116
|
Model: gemini-2.5-flash
|
|
52
117
|
Workspace: ~/projects/my-app
|
|
53
|
-
Commands: /status, /diff, /commit, /build, /
|
|
118
|
+
Commands: /status, /diff, /commit, /build, /index, /search, /agent, /help, /exit
|
|
54
119
|
|
|
55
120
|
──────────────────────────────────────────────────
|
|
56
121
|
|
|
122
|
+
→ /agent
|
|
123
|
+
🤖 Multi-agent mode: ON
|
|
124
|
+
|
|
57
125
|
→ create a todo app with dark mode and local storage
|
|
58
126
|
|
|
59
|
-
|
|
127
|
+
📋 Phase 1: Planning...
|
|
128
|
+
✓ Plan created
|
|
129
|
+
|
|
130
|
+
💻 Phase 2: Coding...
|
|
131
|
+
✓ Code generated
|
|
132
|
+
|
|
133
|
+
🔍 Phase 3: Review (iteration 1)...
|
|
134
|
+
✓ Code approved!
|
|
135
|
+
|
|
136
|
+
✅ Multi-Agent Pipeline Complete
|
|
60
137
|
|
|
61
138
|
📋 Action Plan - todo-app
|
|
62
139
|
─────────────────────────
|
|
@@ -80,7 +157,8 @@ Generating action plan...
|
|
|
80
157
|
### 🤖 AI-Powered Development
|
|
81
158
|
- **Natural language to code** — Describe what you want, get production-ready apps
|
|
82
159
|
- **Conversation memory** — AI remembers context across messages
|
|
83
|
-
- **Multi-
|
|
160
|
+
- **Multi-agent mode** — Planner, Coder, Reviewer pipeline
|
|
161
|
+
- **Codebase RAG** — AI understands your entire project
|
|
84
162
|
|
|
85
163
|
</td>
|
|
86
164
|
<td width="50%">
|
|
@@ -107,9 +185,10 @@ Generating action plan...
|
|
|
107
185
|
### 🌐 Multi-Provider AI
|
|
108
186
|
- **Gemini** — Free tier, fast responses
|
|
109
187
|
- **OpenRouter** — 400+ models, one API
|
|
110
|
-
- **OpenAI** — GPT-4o,
|
|
111
|
-
- **Anthropic** — Claude
|
|
188
|
+
- **OpenAI** — GPT-4o, o3 reasoning
|
|
189
|
+
- **Anthropic** — Claude 4.5 Sonnet
|
|
112
190
|
- **DeepSeek** — R1, V3 models
|
|
191
|
+
- **Puter** — 100% free, no key needed
|
|
113
192
|
|
|
114
193
|
</td>
|
|
115
194
|
</tr>
|
|
@@ -131,6 +210,11 @@ Inside the session:
|
|
|
131
210
|
|---------|-------------|
|
|
132
211
|
| `/build <prompt>` | Generate & execute an app from description |
|
|
133
212
|
| `/edit <file>` | AI-powered surgical file editing |
|
|
213
|
+
| `/index` | 🆕 Index current project for RAG search |
|
|
214
|
+
| `/search <query>` | 🆕 Semantic code search |
|
|
215
|
+
| `/tools` | 🆕 List available MCP tools |
|
|
216
|
+
| `/agent` | 🆕 Toggle multi-agent mode |
|
|
217
|
+
| `/memory` | 🆕 View persistent memory stats |
|
|
134
218
|
| `/status` | AI analysis of git status |
|
|
135
219
|
| `/diff` | AI explanation of current changes |
|
|
136
220
|
| `/commit` | Auto-generate & run git commit |
|
|
@@ -153,6 +237,70 @@ agdi run [dir] # Run a generated project
|
|
|
153
237
|
|
|
154
238
|
---
|
|
155
239
|
|
|
240
|
+
## 🤖 Multi-Agent Architecture (v2.6)
|
|
241
|
+
|
|
242
|
+
Enable with `/agent` for higher quality code:
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
┌──────────────────────────────────────────────────────────┐
|
|
246
|
+
│ User Request │
|
|
247
|
+
└─────────────────────────┬────────────────────────────────┘
|
|
248
|
+
▼
|
|
249
|
+
┌──────────────────────────────────────────────────────────┐
|
|
250
|
+
│ 📋 PLANNER AGENT │
|
|
251
|
+
│ Analyzes request, creates step-by-step implementation │
|
|
252
|
+
│ plan, identifies files to create/modify │
|
|
253
|
+
└─────────────────────────┬────────────────────────────────┘
|
|
254
|
+
▼
|
|
255
|
+
┌──────────────────────────────────────────────────────────┐
|
|
256
|
+
│ 💻 CODER AGENT │
|
|
257
|
+
│ Writes production-ready TypeScript/React code │
|
|
258
|
+
│ following the plan │
|
|
259
|
+
└─────────────────────────┬────────────────────────────────┘
|
|
260
|
+
▼
|
|
261
|
+
┌──────────────────────────────────────────────────────────┐
|
|
262
|
+
│ 🔍 REVIEWER AGENT │
|
|
263
|
+
│ Reviews for: │
|
|
264
|
+
│ • Correctness • Security • Performance • Completeness │
|
|
265
|
+
│ │
|
|
266
|
+
│ → APPROVED: Code delivered to user │
|
|
267
|
+
│ → NEEDS_CHANGES: Sent back to CODER (max 3 loops) │
|
|
268
|
+
└─────────────────────────┬────────────────────────────────┘
|
|
269
|
+
▼
|
|
270
|
+
┌──────────────────────────────────────────────────────────┐
|
|
271
|
+
│ ✅ High-Quality, Reviewed Code │
|
|
272
|
+
└──────────────────────────────────────────────────────────┘
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## 🔍 Codebase RAG (v2.6)
|
|
278
|
+
|
|
279
|
+
Index your project so AI can understand all your code:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Index your project (creates searchable chunks)
|
|
283
|
+
→ /index
|
|
284
|
+
✓ Indexed 47 files, 312 chunks
|
|
285
|
+
|
|
286
|
+
# Semantic search
|
|
287
|
+
→ /search user authentication
|
|
288
|
+
🔍 Search Results
|
|
289
|
+
src/auth/login.ts:15 (0.87)
|
|
290
|
+
export async function authenticateUser...
|
|
291
|
+
src/middleware/auth.ts:1 (0.65)
|
|
292
|
+
import { verifyToken } from...
|
|
293
|
+
src/hooks/useAuth.ts:5 (0.52)
|
|
294
|
+
const AuthContext = createContext...
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
**How it works:**
|
|
298
|
+
1. **Indexer** walks your project, chunks code by functions/classes
|
|
299
|
+
2. **Retriever** uses TF-IDF semantic search (no external vector DB)
|
|
300
|
+
3. **Context** is automatically injected into AI prompts
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
156
304
|
## 🛡️ Security Architecture
|
|
157
305
|
|
|
158
306
|
Agdi includes **zero-trust security** designed for safe AI-assisted development:
|
|
@@ -195,7 +343,7 @@ Real-time scanning detects:
|
|
|
195
343
|
- **22+ secret patterns** — AWS, GitHub, OpenAI, Anthropic, Stripe, etc.
|
|
196
344
|
- **Shell injection** — Dangerous command patterns
|
|
197
345
|
- **Prompt injection** — LLM manipulation attempts
|
|
198
|
-
- **
|
|
346
|
+
- **Network exfiltration** — Suspicious external requests
|
|
199
347
|
|
|
200
348
|
### 📊 Audit Logging
|
|
201
349
|
|
|
@@ -220,7 +368,6 @@ All decisions logged to `~/.agdi/audit.jsonl`:
|
|
|
220
368
|
| Kimi K2 | `moonshotai/kimi-k2:free` | General purpose |
|
|
221
369
|
| Gemma 3N E2B | `google/gemma-3n-e2b-it:free` | Lightweight |
|
|
222
370
|
| LFM Thinking | `liquid/lfm-2.5-1.2b-thinking:free` | Agentic tasks |
|
|
223
|
-
| Devstral ⚠️ | `mistralai/devstral-2512:free` | Ends Jan 27 |
|
|
224
371
|
|
|
225
372
|
### Image Generation
|
|
226
373
|
|
|
@@ -243,9 +390,9 @@ All decisions logged to `~/.agdi/audit.jsonl`:
|
|
|
243
390
|
<td>
|
|
244
391
|
|
|
245
392
|
**OpenRouter** 🌐
|
|
246
|
-
- Claude
|
|
247
|
-
- GPT-
|
|
248
|
-
- Llama
|
|
393
|
+
- Claude 4.5 Sonnet
|
|
394
|
+
- GPT-5 / GPT-4o
|
|
395
|
+
- Llama 4 Maverick
|
|
249
396
|
- DeepSeek R1
|
|
250
397
|
- 400+ more
|
|
251
398
|
|
|
@@ -253,10 +400,10 @@ All decisions logged to `~/.agdi/audit.jsonl`:
|
|
|
253
400
|
<td>
|
|
254
401
|
|
|
255
402
|
**OpenAI** 🧠
|
|
403
|
+
- GPT-5
|
|
256
404
|
- GPT-4o
|
|
257
|
-
-
|
|
405
|
+
- o3
|
|
258
406
|
- o1
|
|
259
|
-
- o1-mini
|
|
260
407
|
|
|
261
408
|
</td>
|
|
262
409
|
</tr>
|
|
@@ -264,15 +411,15 @@ All decisions logged to `~/.agdi/audit.jsonl`:
|
|
|
264
411
|
<td>
|
|
265
412
|
|
|
266
413
|
**Anthropic** 💜
|
|
414
|
+
- Claude 4.5 Sonnet
|
|
415
|
+
- Claude 4.5 Opus
|
|
267
416
|
- Claude 3.5 Sonnet
|
|
268
|
-
- Claude 3.5 Haiku
|
|
269
|
-
- Claude 3 Opus
|
|
270
417
|
|
|
271
418
|
</td>
|
|
272
419
|
<td>
|
|
273
420
|
|
|
274
421
|
**DeepSeek** 🌊
|
|
275
|
-
- DeepSeek V3
|
|
422
|
+
- DeepSeek V3.2
|
|
276
423
|
- DeepSeek R1 (Reasoning)
|
|
277
424
|
|
|
278
425
|
</td>
|
|
@@ -300,6 +447,9 @@ Config stored in `~/.agdi/`:
|
|
|
300
447
|
├── config.json # API keys & settings
|
|
301
448
|
├── rules.json # Permission rules
|
|
302
449
|
├── trusted-workspaces.json # Trusted directories
|
|
450
|
+
├── memory/ # 🆕 Persistent memory
|
|
451
|
+
│ └── store.json
|
|
452
|
+
├── indexes/ # 🆕 RAG indexes
|
|
303
453
|
└── audit.jsonl # Audit log
|
|
304
454
|
```
|
|
305
455
|
|
|
@@ -325,10 +475,14 @@ agdi auth --status
|
|
|
325
475
|
<p>TypeScript Errors</p>
|
|
326
476
|
</td>
|
|
327
477
|
<td align="center">
|
|
328
|
-
<h3>
|
|
478
|
+
<h3>60</h3>
|
|
329
479
|
<p>Tests Passing</p>
|
|
330
480
|
</td>
|
|
331
481
|
<td align="center">
|
|
482
|
+
<h3>148 KB</h3>
|
|
483
|
+
<p>Build Size</p>
|
|
484
|
+
</td>
|
|
485
|
+
<td align="center">
|
|
332
486
|
<h3>22+</h3>
|
|
333
487
|
<p>Security Patterns</p>
|
|
334
488
|
</td>
|
|
@@ -344,14 +498,20 @@ agdi auth --status
|
|
|
344
498
|
## 🚀 Examples
|
|
345
499
|
|
|
346
500
|
```bash
|
|
347
|
-
# Create a full-stack app
|
|
348
|
-
agdi
|
|
501
|
+
# Create a full-stack app (multi-agent recommended)
|
|
502
|
+
agdi
|
|
503
|
+
→ /agent
|
|
504
|
+
→ Create a blog with authentication and markdown support
|
|
349
505
|
|
|
350
|
-
#
|
|
351
|
-
agdi
|
|
506
|
+
# Semantic search your codebase
|
|
507
|
+
agdi
|
|
508
|
+
→ /index
|
|
509
|
+
→ /search payment processing
|
|
352
510
|
|
|
353
|
-
#
|
|
354
|
-
agdi
|
|
511
|
+
# AI-powered file editing
|
|
512
|
+
agdi
|
|
513
|
+
→ /edit src/components/Header.tsx
|
|
514
|
+
"Add a dark mode toggle button"
|
|
355
515
|
|
|
356
516
|
# Interactive development
|
|
357
517
|
agdi
|
|
@@ -371,6 +531,7 @@ agdi
|
|
|
371
531
|
- **Styling**: Chalk, Ora
|
|
372
532
|
- **Build**: tsup
|
|
373
533
|
- **Testing**: Vitest
|
|
534
|
+
- **AI**: Multi-agent, RAG, Token Optimization
|
|
374
535
|
|
|
375
536
|
---
|
|
376
537
|
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/core/rag/indexer.ts
|
|
9
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync, statSync, mkdirSync } from "fs";
|
|
10
|
+
import { join, extname, relative } from "path";
|
|
11
|
+
import { homedir } from "os";
|
|
12
|
+
import { createHash } from "crypto";
|
|
13
|
+
var INDEX_DIR = join(homedir(), ".agdi", "indexes");
|
|
14
|
+
var CHUNK_SIZE = 50;
|
|
15
|
+
var OVERLAP = 10;
|
|
16
|
+
var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
17
|
+
".ts",
|
|
18
|
+
".tsx",
|
|
19
|
+
".js",
|
|
20
|
+
".jsx",
|
|
21
|
+
".mjs",
|
|
22
|
+
".cjs",
|
|
23
|
+
".py",
|
|
24
|
+
".rb",
|
|
25
|
+
".go",
|
|
26
|
+
".rs",
|
|
27
|
+
".java",
|
|
28
|
+
".kt",
|
|
29
|
+
".c",
|
|
30
|
+
".cpp",
|
|
31
|
+
".h",
|
|
32
|
+
".hpp",
|
|
33
|
+
".cs",
|
|
34
|
+
".json",
|
|
35
|
+
".yaml",
|
|
36
|
+
".yml",
|
|
37
|
+
".toml",
|
|
38
|
+
".md",
|
|
39
|
+
".txt",
|
|
40
|
+
".css",
|
|
41
|
+
".scss",
|
|
42
|
+
".html"
|
|
43
|
+
]);
|
|
44
|
+
var IGNORE_DIRS = /* @__PURE__ */ new Set([
|
|
45
|
+
"node_modules",
|
|
46
|
+
".git",
|
|
47
|
+
"dist",
|
|
48
|
+
"build",
|
|
49
|
+
".next",
|
|
50
|
+
"__pycache__",
|
|
51
|
+
".venv",
|
|
52
|
+
"venv",
|
|
53
|
+
"target",
|
|
54
|
+
".idea",
|
|
55
|
+
".vscode",
|
|
56
|
+
"coverage",
|
|
57
|
+
".nyc_output"
|
|
58
|
+
]);
|
|
59
|
+
var IGNORE_FILES = /* @__PURE__ */ new Set([
|
|
60
|
+
"package-lock.json",
|
|
61
|
+
"yarn.lock",
|
|
62
|
+
"pnpm-lock.yaml",
|
|
63
|
+
".DS_Store",
|
|
64
|
+
"Thumbs.db"
|
|
65
|
+
]);
|
|
66
|
+
function getLanguage(ext) {
|
|
67
|
+
const langMap = {
|
|
68
|
+
".ts": "typescript",
|
|
69
|
+
".tsx": "typescript",
|
|
70
|
+
".js": "javascript",
|
|
71
|
+
".jsx": "javascript",
|
|
72
|
+
".mjs": "javascript",
|
|
73
|
+
".py": "python",
|
|
74
|
+
".rb": "ruby",
|
|
75
|
+
".go": "go",
|
|
76
|
+
".rs": "rust",
|
|
77
|
+
".java": "java",
|
|
78
|
+
".kt": "kotlin",
|
|
79
|
+
".c": "c",
|
|
80
|
+
".cpp": "cpp",
|
|
81
|
+
".cs": "csharp",
|
|
82
|
+
".json": "json",
|
|
83
|
+
".yaml": "yaml",
|
|
84
|
+
".yml": "yaml",
|
|
85
|
+
".md": "markdown",
|
|
86
|
+
".css": "css",
|
|
87
|
+
".html": "html"
|
|
88
|
+
};
|
|
89
|
+
return langMap[ext] || "text";
|
|
90
|
+
}
|
|
91
|
+
function generateId(filePath, startLine) {
|
|
92
|
+
const hash = createHash("md5").update(`${filePath}:${startLine}`).digest("hex").slice(0, 8);
|
|
93
|
+
return `chunk_${hash}`;
|
|
94
|
+
}
|
|
95
|
+
function hashContent(content) {
|
|
96
|
+
return createHash("md5").update(content).digest("hex").slice(0, 12);
|
|
97
|
+
}
|
|
98
|
+
function detectChunkType(content, language) {
|
|
99
|
+
const firstLine = content.split("\n")[0].trim();
|
|
100
|
+
if (language === "typescript" || language === "javascript") {
|
|
101
|
+
if (/^(export\s+)?(async\s+)?function\s/.test(firstLine)) return "function";
|
|
102
|
+
if (/^(export\s+)?(abstract\s+)?class\s/.test(firstLine)) return "class";
|
|
103
|
+
if (/^(import|from)\s/.test(firstLine)) return "import";
|
|
104
|
+
if (/^export\s/.test(firstLine)) return "export";
|
|
105
|
+
}
|
|
106
|
+
if (language === "python") {
|
|
107
|
+
if (/^(async\s+)?def\s/.test(firstLine)) return "function";
|
|
108
|
+
if (/^class\s/.test(firstLine)) return "class";
|
|
109
|
+
if (/^(from|import)\s/.test(firstLine)) return "import";
|
|
110
|
+
}
|
|
111
|
+
if (/^(\/\/|\/\*|#|""")/.test(firstLine)) return "comment";
|
|
112
|
+
return "other";
|
|
113
|
+
}
|
|
114
|
+
function* walkDirectory(dir, basePath) {
|
|
115
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
116
|
+
for (const entry of entries) {
|
|
117
|
+
const fullPath = join(dir, entry.name);
|
|
118
|
+
if (entry.isDirectory()) {
|
|
119
|
+
if (!IGNORE_DIRS.has(entry.name)) {
|
|
120
|
+
yield* walkDirectory(fullPath, basePath);
|
|
121
|
+
}
|
|
122
|
+
} else if (entry.isFile()) {
|
|
123
|
+
if (!IGNORE_FILES.has(entry.name)) {
|
|
124
|
+
const ext = extname(entry.name).toLowerCase();
|
|
125
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
126
|
+
yield fullPath;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function chunkFile(filePath, basePath) {
|
|
133
|
+
const content = readFileSync(filePath, "utf-8");
|
|
134
|
+
const lines = content.split("\n");
|
|
135
|
+
const ext = extname(filePath).toLowerCase();
|
|
136
|
+
const language = getLanguage(ext);
|
|
137
|
+
const relativePath = relative(basePath, filePath);
|
|
138
|
+
const chunks = [];
|
|
139
|
+
for (let i = 0; i < lines.length; i += CHUNK_SIZE - OVERLAP) {
|
|
140
|
+
const chunkLines = lines.slice(i, i + CHUNK_SIZE);
|
|
141
|
+
const chunkContent = chunkLines.join("\n");
|
|
142
|
+
if (chunkContent.trim().length === 0) continue;
|
|
143
|
+
chunks.push({
|
|
144
|
+
id: generateId(filePath, i),
|
|
145
|
+
filePath,
|
|
146
|
+
relativePath,
|
|
147
|
+
content: chunkContent,
|
|
148
|
+
startLine: i + 1,
|
|
149
|
+
endLine: Math.min(i + CHUNK_SIZE, lines.length),
|
|
150
|
+
type: detectChunkType(chunkContent, language),
|
|
151
|
+
language,
|
|
152
|
+
hash: hashContent(chunkContent)
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return chunks;
|
|
156
|
+
}
|
|
157
|
+
function indexProject(projectPath) {
|
|
158
|
+
const startTime = Date.now();
|
|
159
|
+
const allChunks = [];
|
|
160
|
+
let fileCount = 0;
|
|
161
|
+
for (const filePath of walkDirectory(projectPath, projectPath)) {
|
|
162
|
+
try {
|
|
163
|
+
const stat = statSync(filePath);
|
|
164
|
+
if (stat.size > 1024 * 1024) continue;
|
|
165
|
+
const chunks = chunkFile(filePath, projectPath);
|
|
166
|
+
allChunks.push(...chunks);
|
|
167
|
+
fileCount++;
|
|
168
|
+
} catch {
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const index = {
|
|
172
|
+
version: 1,
|
|
173
|
+
projectPath,
|
|
174
|
+
indexedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
175
|
+
fileCount,
|
|
176
|
+
chunkCount: allChunks.length,
|
|
177
|
+
chunks: allChunks
|
|
178
|
+
};
|
|
179
|
+
saveIndex(projectPath, index);
|
|
180
|
+
console.log(`Indexed ${fileCount} files, ${allChunks.length} chunks in ${Date.now() - startTime}ms`);
|
|
181
|
+
return index;
|
|
182
|
+
}
|
|
183
|
+
function getIndexPath(projectPath) {
|
|
184
|
+
const hash = createHash("md5").update(projectPath).digest("hex").slice(0, 12);
|
|
185
|
+
return join(INDEX_DIR, `${hash}.json`);
|
|
186
|
+
}
|
|
187
|
+
function saveIndex(projectPath, index) {
|
|
188
|
+
if (!existsSync(INDEX_DIR)) {
|
|
189
|
+
mkdirSync(INDEX_DIR, { recursive: true });
|
|
190
|
+
}
|
|
191
|
+
writeFileSync(getIndexPath(projectPath), JSON.stringify(index));
|
|
192
|
+
}
|
|
193
|
+
function loadIndex(projectPath) {
|
|
194
|
+
const indexPath = getIndexPath(projectPath);
|
|
195
|
+
if (!existsSync(indexPath)) return null;
|
|
196
|
+
try {
|
|
197
|
+
const data = readFileSync(indexPath, "utf-8");
|
|
198
|
+
return JSON.parse(data);
|
|
199
|
+
} catch {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function isIndexStale(index) {
|
|
204
|
+
const indexedAt = new Date(index.indexedAt).getTime();
|
|
205
|
+
const hourAgo = Date.now() - 60 * 60 * 1e3;
|
|
206
|
+
return indexedAt < hourAgo;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/core/rag/retriever.ts
|
|
210
|
+
function tokenize(text) {
|
|
211
|
+
return text.toLowerCase().replace(/[^a-z0-9_]/g, " ").split(/\s+/).filter((t) => t.length > 2);
|
|
212
|
+
}
|
|
213
|
+
function calculateTF(tokens) {
|
|
214
|
+
const tf = /* @__PURE__ */ new Map();
|
|
215
|
+
for (const token of tokens) {
|
|
216
|
+
tf.set(token, (tf.get(token) || 0) + 1);
|
|
217
|
+
}
|
|
218
|
+
const max = Math.max(...tf.values());
|
|
219
|
+
for (const [token, count] of tf) {
|
|
220
|
+
tf.set(token, count / max);
|
|
221
|
+
}
|
|
222
|
+
return tf;
|
|
223
|
+
}
|
|
224
|
+
function scoreChunk(chunk, queryTokens, queryTF) {
|
|
225
|
+
const chunkTokens = tokenize(chunk.content);
|
|
226
|
+
const chunkTF = calculateTF(chunkTokens);
|
|
227
|
+
let score = 0;
|
|
228
|
+
const matchedTokens = /* @__PURE__ */ new Set();
|
|
229
|
+
for (const queryToken of queryTokens) {
|
|
230
|
+
if (chunkTF.has(queryToken)) {
|
|
231
|
+
score += chunkTF.get(queryToken) * (queryTF.get(queryToken) || 1);
|
|
232
|
+
matchedTokens.add(queryToken);
|
|
233
|
+
}
|
|
234
|
+
for (const chunkToken of chunkTokens) {
|
|
235
|
+
if (chunkToken.startsWith(queryToken) || queryToken.startsWith(chunkToken)) {
|
|
236
|
+
if (!matchedTokens.has(queryToken)) {
|
|
237
|
+
score += 0.5 * (queryTF.get(queryToken) || 1);
|
|
238
|
+
matchedTokens.add(queryToken);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const pathTokens = tokenize(chunk.relativePath);
|
|
244
|
+
for (const queryToken of queryTokens) {
|
|
245
|
+
if (pathTokens.includes(queryToken)) {
|
|
246
|
+
score += 0.5;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (chunk.type === "function" || chunk.type === "class") {
|
|
250
|
+
score *= 1.2;
|
|
251
|
+
}
|
|
252
|
+
score = score / Math.sqrt(queryTokens.length);
|
|
253
|
+
return score;
|
|
254
|
+
}
|
|
255
|
+
function extractHighlights(chunk, queryTokens) {
|
|
256
|
+
const lines = chunk.content.split("\n");
|
|
257
|
+
const highlights = [];
|
|
258
|
+
for (const line of lines) {
|
|
259
|
+
const lineLower = line.toLowerCase();
|
|
260
|
+
for (const token of queryTokens) {
|
|
261
|
+
if (lineLower.includes(token)) {
|
|
262
|
+
const trimmed = line.trim();
|
|
263
|
+
if (trimmed.length > 0 && !highlights.includes(trimmed)) {
|
|
264
|
+
highlights.push(trimmed.slice(0, 100));
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (highlights.length >= 3) break;
|
|
270
|
+
}
|
|
271
|
+
return highlights;
|
|
272
|
+
}
|
|
273
|
+
function searchCodebase(projectPath, query, options = {}) {
|
|
274
|
+
const limit = options.limit ?? 10;
|
|
275
|
+
const minScore = options.minScore ?? 0.1;
|
|
276
|
+
const index = loadIndex(projectPath);
|
|
277
|
+
if (!index) {
|
|
278
|
+
console.warn("No index found. Run /index first.");
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
const queryTokens = tokenize(query);
|
|
282
|
+
if (queryTokens.length === 0) {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
const queryTF = calculateTF(queryTokens);
|
|
286
|
+
const results = [];
|
|
287
|
+
for (const chunk of index.chunks) {
|
|
288
|
+
if (options.fileTypes && !options.fileTypes.includes(chunk.language)) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (options.chunkTypes && !options.chunkTypes.includes(chunk.type)) {
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const score = scoreChunk(chunk, queryTokens, queryTF);
|
|
295
|
+
if (score >= minScore) {
|
|
296
|
+
results.push({
|
|
297
|
+
chunk,
|
|
298
|
+
score,
|
|
299
|
+
highlights: extractHighlights(chunk, queryTokens)
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
results.sort((a, b) => b.score - a.score);
|
|
304
|
+
return results.slice(0, limit);
|
|
305
|
+
}
|
|
306
|
+
function getRelevantContext(projectPath, prompt, maxChunks = 5) {
|
|
307
|
+
const results = searchCodebase(projectPath, prompt, { limit: maxChunks });
|
|
308
|
+
if (results.length === 0) {
|
|
309
|
+
return "";
|
|
310
|
+
}
|
|
311
|
+
const parts = ["[Relevant Code Context]"];
|
|
312
|
+
for (const result of results) {
|
|
313
|
+
parts.push(`
|
|
314
|
+
// ${result.chunk.relativePath}:${result.chunk.startLine}-${result.chunk.endLine}`);
|
|
315
|
+
parts.push("```" + result.chunk.language);
|
|
316
|
+
parts.push(result.chunk.content.slice(0, 500));
|
|
317
|
+
if (result.chunk.content.length > 500) {
|
|
318
|
+
parts.push("// ... (truncated)");
|
|
319
|
+
}
|
|
320
|
+
parts.push("```");
|
|
321
|
+
}
|
|
322
|
+
parts.push("[/Relevant Code Context]\n");
|
|
323
|
+
return parts.join("\n");
|
|
324
|
+
}
|
|
325
|
+
function findFiles(projectPath, pattern) {
|
|
326
|
+
const index = loadIndex(projectPath);
|
|
327
|
+
if (!index) return [];
|
|
328
|
+
const patternLower = pattern.toLowerCase();
|
|
329
|
+
const seen = /* @__PURE__ */ new Set();
|
|
330
|
+
const results = [];
|
|
331
|
+
for (const chunk of index.chunks) {
|
|
332
|
+
if (seen.has(chunk.filePath)) continue;
|
|
333
|
+
if (chunk.relativePath.toLowerCase().includes(patternLower)) {
|
|
334
|
+
seen.add(chunk.filePath);
|
|
335
|
+
results.push(chunk);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return results;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export {
|
|
342
|
+
__require,
|
|
343
|
+
indexProject,
|
|
344
|
+
loadIndex,
|
|
345
|
+
isIndexStale,
|
|
346
|
+
searchCodebase,
|
|
347
|
+
getRelevantContext,
|
|
348
|
+
findFiles
|
|
349
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
});
|
|
2
|
+
import {
|
|
3
|
+
__require,
|
|
4
|
+
indexProject,
|
|
5
|
+
searchCodebase
|
|
6
|
+
} from "./chunk-NVMD3WL3.js";
|
|
8
7
|
|
|
9
8
|
// src/index.ts
|
|
10
9
|
import { Command } from "commander";
|
|
@@ -3915,7 +3914,174 @@ Generate the unified diff to make this change.`;
|
|
|
3915
3914
|
}
|
|
3916
3915
|
}
|
|
3917
3916
|
|
|
3917
|
+
// src/core/mcp/tools.ts
|
|
3918
|
+
var tools = /* @__PURE__ */ new Map();
|
|
3919
|
+
function registerTool(tool) {
|
|
3920
|
+
tools.set(tool.name, tool);
|
|
3921
|
+
}
|
|
3922
|
+
function listTools() {
|
|
3923
|
+
return Array.from(tools.values());
|
|
3924
|
+
}
|
|
3925
|
+
registerTool({
|
|
3926
|
+
name: "read_file",
|
|
3927
|
+
description: "Read the contents of a file",
|
|
3928
|
+
category: "filesystem",
|
|
3929
|
+
parameters: [
|
|
3930
|
+
{ name: "path", type: "string", description: "File path to read", required: true }
|
|
3931
|
+
],
|
|
3932
|
+
execute: async (params) => {
|
|
3933
|
+
const { readFileSync: readFileSync8 } = await import("fs");
|
|
3934
|
+
const { resolve: resolve5 } = await import("path");
|
|
3935
|
+
try {
|
|
3936
|
+
const filePath = resolve5(process.cwd(), params.path);
|
|
3937
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
3938
|
+
return {
|
|
3939
|
+
success: true,
|
|
3940
|
+
data: content,
|
|
3941
|
+
display: `Read ${content.split("\n").length} lines from ${params.path}`
|
|
3942
|
+
};
|
|
3943
|
+
} catch (error) {
|
|
3944
|
+
return {
|
|
3945
|
+
success: false,
|
|
3946
|
+
error: `Failed to read file: ${error}`
|
|
3947
|
+
};
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
});
|
|
3951
|
+
registerTool({
|
|
3952
|
+
name: "list_dir",
|
|
3953
|
+
description: "List files in a directory",
|
|
3954
|
+
category: "filesystem",
|
|
3955
|
+
parameters: [
|
|
3956
|
+
{ name: "path", type: "string", description: "Directory path", required: false, default: "." }
|
|
3957
|
+
],
|
|
3958
|
+
execute: async (params) => {
|
|
3959
|
+
const { readdirSync: readdirSync2, statSync: statSync2 } = await import("fs");
|
|
3960
|
+
const { resolve: resolve5, join: join8 } = await import("path");
|
|
3961
|
+
try {
|
|
3962
|
+
const dirPath = resolve5(process.cwd(), params.path || ".");
|
|
3963
|
+
const entries = readdirSync2(dirPath);
|
|
3964
|
+
const files = [];
|
|
3965
|
+
const dirs = [];
|
|
3966
|
+
for (const entry of entries) {
|
|
3967
|
+
try {
|
|
3968
|
+
const stat = statSync2(join8(dirPath, entry));
|
|
3969
|
+
if (stat.isDirectory()) {
|
|
3970
|
+
dirs.push(entry + "/");
|
|
3971
|
+
} else {
|
|
3972
|
+
files.push(entry);
|
|
3973
|
+
}
|
|
3974
|
+
} catch {
|
|
3975
|
+
files.push(entry);
|
|
3976
|
+
}
|
|
3977
|
+
}
|
|
3978
|
+
return {
|
|
3979
|
+
success: true,
|
|
3980
|
+
data: { dirs, files },
|
|
3981
|
+
display: `${dirs.length} directories, ${files.length} files`
|
|
3982
|
+
};
|
|
3983
|
+
} catch (error) {
|
|
3984
|
+
return {
|
|
3985
|
+
success: false,
|
|
3986
|
+
error: `Failed to list directory: ${error}`
|
|
3987
|
+
};
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
});
|
|
3991
|
+
registerTool({
|
|
3992
|
+
name: "search_code",
|
|
3993
|
+
description: "Search for code in the current project",
|
|
3994
|
+
category: "code",
|
|
3995
|
+
parameters: [
|
|
3996
|
+
{ name: "query", type: "string", description: "Search query", required: true },
|
|
3997
|
+
{ name: "limit", type: "number", description: "Max results", required: false, default: 5 }
|
|
3998
|
+
],
|
|
3999
|
+
execute: async (params) => {
|
|
4000
|
+
const { searchCodebase: searchCodebase2 } = await import("./rag-6HO4ZLBN.js");
|
|
4001
|
+
const results = searchCodebase2(
|
|
4002
|
+
process.cwd(),
|
|
4003
|
+
params.query,
|
|
4004
|
+
{ limit: params.limit || 5 }
|
|
4005
|
+
);
|
|
4006
|
+
if (results.length === 0) {
|
|
4007
|
+
return {
|
|
4008
|
+
success: true,
|
|
4009
|
+
data: [],
|
|
4010
|
+
display: "No results found"
|
|
4011
|
+
};
|
|
4012
|
+
}
|
|
4013
|
+
const display = results.map(
|
|
4014
|
+
(r) => `${r.chunk.relativePath}:${r.chunk.startLine} (score: ${r.score.toFixed(2)})`
|
|
4015
|
+
).join("\n");
|
|
4016
|
+
return {
|
|
4017
|
+
success: true,
|
|
4018
|
+
data: results.map((r) => ({
|
|
4019
|
+
file: r.chunk.relativePath,
|
|
4020
|
+
line: r.chunk.startLine,
|
|
4021
|
+
content: r.chunk.content.slice(0, 200)
|
|
4022
|
+
})),
|
|
4023
|
+
display
|
|
4024
|
+
};
|
|
4025
|
+
}
|
|
4026
|
+
});
|
|
4027
|
+
registerTool({
|
|
4028
|
+
name: "run_command",
|
|
4029
|
+
description: "Run a shell command (requires user approval)",
|
|
4030
|
+
category: "system",
|
|
4031
|
+
parameters: [
|
|
4032
|
+
{ name: "command", type: "string", description: "Command to run", required: true }
|
|
4033
|
+
],
|
|
4034
|
+
execute: async (params) => {
|
|
4035
|
+
return {
|
|
4036
|
+
success: false,
|
|
4037
|
+
error: "Shell commands require explicit user approval. Use /build or /exec instead."
|
|
4038
|
+
};
|
|
4039
|
+
}
|
|
4040
|
+
});
|
|
4041
|
+
|
|
4042
|
+
// src/core/memory-store.ts
|
|
4043
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
4044
|
+
import { join as join7 } from "path";
|
|
4045
|
+
import { homedir as homedir6 } from "os";
|
|
4046
|
+
var MEMORY_DIR = join7(homedir6(), ".agdi", "memory");
|
|
4047
|
+
var MEMORY_FILE = join7(MEMORY_DIR, "store.json");
|
|
4048
|
+
function ensureMemoryDir() {
|
|
4049
|
+
if (!existsSync10(MEMORY_DIR)) {
|
|
4050
|
+
mkdirSync5(MEMORY_DIR, { recursive: true });
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
function loadMemoryStore() {
|
|
4054
|
+
ensureMemoryDir();
|
|
4055
|
+
if (existsSync10(MEMORY_FILE)) {
|
|
4056
|
+
try {
|
|
4057
|
+
const data = readFileSync7(MEMORY_FILE, "utf-8");
|
|
4058
|
+
return JSON.parse(data);
|
|
4059
|
+
} catch {
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
return {
|
|
4063
|
+
version: 1,
|
|
4064
|
+
entries: [],
|
|
4065
|
+
userPreferences: {},
|
|
4066
|
+
projectContexts: {}
|
|
4067
|
+
};
|
|
4068
|
+
}
|
|
4069
|
+
function getMemoryStats() {
|
|
4070
|
+
const store = loadMemoryStore();
|
|
4071
|
+
const byType = {};
|
|
4072
|
+
for (const entry of store.entries) {
|
|
4073
|
+
byType[entry.type] = (byType[entry.type] || 0) + 1;
|
|
4074
|
+
}
|
|
4075
|
+
return {
|
|
4076
|
+
totalEntries: store.entries.length,
|
|
4077
|
+
byType,
|
|
4078
|
+
projectCount: Object.keys(store.projectContexts).length,
|
|
4079
|
+
preferenceCount: Object.keys(store.userPreferences).length
|
|
4080
|
+
};
|
|
4081
|
+
}
|
|
4082
|
+
|
|
3918
4083
|
// src/commands/agdi-dev.ts
|
|
4084
|
+
var multiAgentMode = false;
|
|
3919
4085
|
var BASE_CHAT_PROMPT = `You are Agdi dev, an elite AI coding assistant. You help developers write code, debug issues, and build applications.
|
|
3920
4086
|
|
|
3921
4087
|
## Your Capabilities
|
|
@@ -4091,6 +4257,69 @@ async function startCodingMode() {
|
|
|
4091
4257
|
}
|
|
4092
4258
|
continue;
|
|
4093
4259
|
}
|
|
4260
|
+
if (trimmed === "/index") {
|
|
4261
|
+
const spinner2 = ora4("Indexing project...").start();
|
|
4262
|
+
try {
|
|
4263
|
+
const index = indexProject(process.cwd());
|
|
4264
|
+
spinner2.succeed(`Indexed ${index.fileCount} files, ${index.chunkCount} chunks`);
|
|
4265
|
+
} catch (error) {
|
|
4266
|
+
spinner2.fail("Indexing failed: " + (error instanceof Error ? error.message : String(error)));
|
|
4267
|
+
}
|
|
4268
|
+
continue;
|
|
4269
|
+
}
|
|
4270
|
+
if (trimmed.startsWith("/search ")) {
|
|
4271
|
+
const query = userInput.slice(8).trim();
|
|
4272
|
+
if (!query) {
|
|
4273
|
+
console.log(chalk12.yellow("\nUsage: /search <query>\n"));
|
|
4274
|
+
continue;
|
|
4275
|
+
}
|
|
4276
|
+
const results = searchCodebase(process.cwd(), query, { limit: 8 });
|
|
4277
|
+
if (results.length === 0) {
|
|
4278
|
+
console.log(chalk12.gray("\nNo results found. Try /index first.\n"));
|
|
4279
|
+
} else {
|
|
4280
|
+
console.log(chalk12.cyan.bold("\n\u{1F50D} Search Results\n"));
|
|
4281
|
+
for (const r of results) {
|
|
4282
|
+
console.log(chalk12.green(` ${r.chunk.relativePath}:${r.chunk.startLine}`) + chalk12.gray(` (${r.score.toFixed(2)})`));
|
|
4283
|
+
if (r.highlights.length > 0) {
|
|
4284
|
+
console.log(chalk12.gray(` ${r.highlights[0].slice(0, 60)}...`));
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
console.log("");
|
|
4288
|
+
}
|
|
4289
|
+
continue;
|
|
4290
|
+
}
|
|
4291
|
+
if (trimmed === "/tools") {
|
|
4292
|
+
const tools2 = listTools();
|
|
4293
|
+
console.log(chalk12.cyan.bold("\n\u{1F527} Available Tools\n"));
|
|
4294
|
+
for (const tool of tools2) {
|
|
4295
|
+
console.log(chalk12.green(` ${tool.name}`) + chalk12.gray(` [${tool.category}]`));
|
|
4296
|
+
console.log(chalk12.gray(` ${tool.description}`));
|
|
4297
|
+
}
|
|
4298
|
+
console.log("");
|
|
4299
|
+
continue;
|
|
4300
|
+
}
|
|
4301
|
+
if (trimmed === "/agent") {
|
|
4302
|
+
multiAgentMode = !multiAgentMode;
|
|
4303
|
+
console.log(chalk12.cyan(`
|
|
4304
|
+
\u{1F916} Multi-agent mode: ${multiAgentMode ? chalk12.green("ON") : chalk12.gray("OFF")}
|
|
4305
|
+
`));
|
|
4306
|
+
if (multiAgentMode) {
|
|
4307
|
+
console.log(chalk12.gray(" Planner \u2192 Coder \u2192 Reviewer pipeline enabled\n"));
|
|
4308
|
+
}
|
|
4309
|
+
continue;
|
|
4310
|
+
}
|
|
4311
|
+
if (trimmed === "/memory") {
|
|
4312
|
+
const stats = getMemoryStats();
|
|
4313
|
+
console.log(chalk12.cyan.bold("\n\u{1F9E0} Memory Stats\n"));
|
|
4314
|
+
console.log(chalk12.gray(` Total entries: ${stats.totalEntries}`));
|
|
4315
|
+
console.log(chalk12.gray(` Projects: ${stats.projectCount}`));
|
|
4316
|
+
console.log(chalk12.gray(` Preferences: ${stats.preferenceCount}`));
|
|
4317
|
+
for (const [type, count] of Object.entries(stats.byType)) {
|
|
4318
|
+
console.log(chalk12.gray(` ${type}: ${count}`));
|
|
4319
|
+
}
|
|
4320
|
+
console.log("");
|
|
4321
|
+
continue;
|
|
4322
|
+
}
|
|
4094
4323
|
if (trimmed.startsWith("/build ") || trimmed.startsWith("build ")) {
|
|
4095
4324
|
const prompt = userInput.replace(/^\/?build\s+/i, "").trim();
|
|
4096
4325
|
if (prompt) {
|
|
@@ -4302,6 +4531,15 @@ function showHelp() {
|
|
|
4302
4531
|
console.log(chalk12.gray(" /build ") + "Generate and execute an application");
|
|
4303
4532
|
console.log(chalk12.gray(" /edit ") + "AI-powered surgical file editing");
|
|
4304
4533
|
console.log("");
|
|
4534
|
+
console.log(chalk12.cyan(" RAG Commands:"));
|
|
4535
|
+
console.log(chalk12.gray(" /index ") + "Index current project for search");
|
|
4536
|
+
console.log(chalk12.gray(" /search ") + "Semantic code search");
|
|
4537
|
+
console.log("");
|
|
4538
|
+
console.log(chalk12.cyan(" Advanced:"));
|
|
4539
|
+
console.log(chalk12.gray(" /tools ") + "List available MCP tools");
|
|
4540
|
+
console.log(chalk12.gray(" /agent ") + "Toggle multi-agent mode");
|
|
4541
|
+
console.log(chalk12.gray(" /memory ") + "Show memory stats");
|
|
4542
|
+
console.log("");
|
|
4305
4543
|
console.log(chalk12.cyan(" Conversation:"));
|
|
4306
4544
|
console.log(chalk12.gray(" /clear ") + "Clear conversation history");
|
|
4307
4545
|
console.log(chalk12.gray(" /history ") + "Show recent conversation");
|
|
@@ -4312,7 +4550,6 @@ function showHelp() {
|
|
|
4312
4550
|
console.log(chalk12.gray(" /help ") + "Show this help");
|
|
4313
4551
|
console.log(chalk12.gray(" /exit ") + "Exit Agdi");
|
|
4314
4552
|
console.log(chalk12.gray("\n Or just type your coding question!\n"));
|
|
4315
|
-
console.log(chalk12.gray('Tip: "Create a todo app" will generate & write files.\n'));
|
|
4316
4553
|
}
|
|
4317
4554
|
function handleError(error) {
|
|
4318
4555
|
const msg = error instanceof Error ? error.message : String(error);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findFiles,
|
|
3
|
+
getRelevantContext,
|
|
4
|
+
indexProject,
|
|
5
|
+
isIndexStale,
|
|
6
|
+
loadIndex,
|
|
7
|
+
searchCodebase
|
|
8
|
+
} from "./chunk-NVMD3WL3.js";
|
|
9
|
+
export {
|
|
10
|
+
findFiles,
|
|
11
|
+
getRelevantContext,
|
|
12
|
+
indexProject,
|
|
13
|
+
isIndexStale,
|
|
14
|
+
loadIndex,
|
|
15
|
+
searchCodebase
|
|
16
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agdi",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "AI-powered app generator - build full-stack apps from natural language in your terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -62,4 +62,4 @@
|
|
|
62
62
|
"jszip": "^3.10.0",
|
|
63
63
|
"ora": "^8.0.0"
|
|
64
64
|
}
|
|
65
|
-
}
|
|
65
|
+
}
|