@wundr.io/cli 1.0.12 → 1.0.14
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/dist/ai/ai-service.d.ts +152 -0
- package/dist/ai/ai-service.d.ts.map +1 -0
- package/dist/ai/ai-service.js +430 -0
- package/dist/ai/ai-service.js.map +1 -0
- package/dist/ai/claude-client.d.ts +130 -0
- package/dist/ai/claude-client.d.ts.map +1 -0
- package/dist/ai/claude-client.js +340 -0
- package/dist/ai/claude-client.js.map +1 -0
- package/dist/ai/conversation-manager.d.ts +164 -0
- package/dist/ai/conversation-manager.d.ts.map +1 -0
- package/dist/ai/conversation-manager.js +614 -0
- package/dist/ai/conversation-manager.js.map +1 -0
- package/dist/ai/index.d.ts +5 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/cli.d.ts +36 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +192 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/ai.d.ts +89 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +954 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/alignment.d.ts +78 -0
- package/dist/commands/alignment.d.ts.map +1 -0
- package/dist/commands/alignment.js +817 -0
- package/dist/commands/alignment.js.map +1 -0
- package/dist/commands/analyze-optimized.d.ts +14 -0
- package/dist/commands/analyze-optimized.d.ts.map +1 -0
- package/dist/commands/analyze-optimized.js +609 -0
- package/dist/commands/analyze-optimized.js.map +1 -0
- package/dist/commands/analyze.d.ts +65 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +435 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/batch.d.ts +93 -0
- package/dist/commands/batch.d.ts.map +1 -0
- package/dist/commands/batch.js +854 -0
- package/dist/commands/batch.js.map +1 -0
- package/dist/commands/chat.d.ts +72 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +678 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/claude-init.d.ts +28 -0
- package/dist/commands/claude-init.d.ts.map +1 -0
- package/dist/commands/claude-init.js +591 -0
- package/dist/commands/claude-init.js.map +1 -0
- package/dist/commands/claude-setup.d.ts +119 -0
- package/dist/commands/claude-setup.d.ts.map +1 -0
- package/dist/commands/claude-setup.js +1079 -0
- package/dist/commands/claude-setup.js.map +1 -0
- package/dist/commands/computer-setup.d.ts +8 -0
- package/dist/commands/computer-setup.d.ts.map +1 -0
- package/dist/commands/computer-setup.js +877 -0
- package/dist/commands/computer-setup.js.map +1 -0
- package/dist/commands/create-command.d.ts +7 -0
- package/dist/commands/create-command.d.ts.map +1 -0
- package/dist/commands/create-command.js +158 -0
- package/dist/commands/create-command.js.map +1 -0
- package/dist/commands/create.d.ts +74 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +556 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dashboard.d.ts +91 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +538 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/govern.d.ts +70 -0
- package/dist/commands/govern.d.ts.map +1 -0
- package/dist/commands/govern.js +481 -0
- package/dist/commands/govern.js.map +1 -0
- package/dist/commands/governance.d.ts +17 -0
- package/dist/commands/governance.d.ts.map +1 -0
- package/dist/commands/governance.js +703 -0
- package/dist/commands/governance.js.map +1 -0
- package/dist/commands/guardian.d.ts +20 -0
- package/dist/commands/guardian.d.ts.map +1 -0
- package/dist/commands/guardian.js +597 -0
- package/dist/commands/guardian.js.map +1 -0
- package/dist/commands/init.d.ts +59 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +650 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/orchestrator.d.ts +7 -0
- package/dist/commands/orchestrator.d.ts.map +1 -0
- package/dist/commands/orchestrator.js +578 -0
- package/dist/commands/orchestrator.js.map +1 -0
- package/dist/commands/performance-optimizer.d.ts +30 -0
- package/dist/commands/performance-optimizer.d.ts.map +1 -0
- package/dist/commands/performance-optimizer.js +650 -0
- package/dist/commands/performance-optimizer.js.map +1 -0
- package/dist/commands/plugins.d.ts +87 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +685 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/rag.d.ts +7 -0
- package/dist/commands/rag.d.ts.map +1 -0
- package/dist/commands/rag.js +751 -0
- package/dist/commands/rag.js.map +1 -0
- package/dist/commands/session.d.ts +41 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +441 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +24 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +172 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/test-init.d.ts +9 -0
- package/dist/commands/test-init.d.ts.map +1 -0
- package/dist/commands/test-init.js +222 -0
- package/dist/commands/test-init.js.map +1 -0
- package/dist/commands/test.d.ts +25 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +217 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/watch.d.ts +76 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +613 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/worktree.d.ts +63 -0
- package/dist/commands/worktree.d.ts.map +1 -0
- package/dist/commands/worktree.js +774 -0
- package/dist/commands/worktree.js.map +1 -0
- package/dist/context/context-manager.d.ts +155 -0
- package/dist/context/context-manager.d.ts.map +1 -0
- package/dist/context/context-manager.js +383 -0
- package/dist/context/context-manager.js.map +1 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +6 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/session-manager.d.ts +207 -0
- package/dist/context/session-manager.d.ts.map +1 -0
- package/dist/context/session-manager.js +686 -0
- package/dist/context/session-manager.js.map +1 -0
- package/dist/framework/command-interface.d.ts +349 -0
- package/dist/framework/command-interface.d.ts.map +1 -0
- package/dist/framework/command-interface.js +101 -0
- package/dist/framework/command-interface.js.map +1 -0
- package/dist/framework/command-registry.d.ts +173 -0
- package/dist/framework/command-registry.d.ts.map +1 -0
- package/dist/framework/command-registry.js +734 -0
- package/dist/framework/command-registry.js.map +1 -0
- package/dist/framework/completion-exporter.d.ts +79 -0
- package/dist/framework/completion-exporter.d.ts.map +1 -0
- package/dist/framework/completion-exporter.js +259 -0
- package/dist/framework/completion-exporter.js.map +1 -0
- package/dist/framework/debug-logger.d.ts +163 -0
- package/dist/framework/debug-logger.d.ts.map +1 -0
- package/dist/framework/debug-logger.js +373 -0
- package/dist/framework/debug-logger.js.map +1 -0
- package/dist/framework/error-handler.d.ts +196 -0
- package/dist/framework/error-handler.d.ts.map +1 -0
- package/dist/framework/error-handler.js +613 -0
- package/dist/framework/error-handler.js.map +1 -0
- package/dist/framework/help-generator.d.ts +78 -0
- package/dist/framework/help-generator.d.ts.map +1 -0
- package/dist/framework/help-generator.js +414 -0
- package/dist/framework/help-generator.js.map +1 -0
- package/dist/framework/index.d.ts +62 -0
- package/dist/framework/index.d.ts.map +1 -0
- package/dist/framework/index.js +95 -0
- package/dist/framework/index.js.map +1 -0
- package/dist/framework/interactive-repl.d.ts +138 -0
- package/dist/framework/interactive-repl.d.ts.map +1 -0
- package/dist/framework/interactive-repl.js +567 -0
- package/dist/framework/interactive-repl.js.map +1 -0
- package/dist/framework/output-formatter.d.ts +274 -0
- package/dist/framework/output-formatter.d.ts.map +1 -0
- package/dist/framework/output-formatter.js +545 -0
- package/dist/framework/output-formatter.js.map +1 -0
- package/dist/framework/progress-manager.d.ts +192 -0
- package/dist/framework/progress-manager.d.ts.map +1 -0
- package/dist/framework/progress-manager.js +408 -0
- package/dist/framework/progress-manager.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive/interactive-mode.d.ts +76 -0
- package/dist/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/interactive/interactive-mode.js +732 -0
- package/dist/interactive/interactive-mode.js.map +1 -0
- package/dist/nlp/command-mapper.d.ts +174 -0
- package/dist/nlp/command-mapper.d.ts.map +1 -0
- package/dist/nlp/command-mapper.js +624 -0
- package/dist/nlp/command-mapper.js.map +1 -0
- package/dist/nlp/command-parser.d.ts +106 -0
- package/dist/nlp/command-parser.d.ts.map +1 -0
- package/dist/nlp/command-parser.js +417 -0
- package/dist/nlp/command-parser.js.map +1 -0
- package/dist/nlp/index.d.ts +5 -0
- package/dist/nlp/index.d.ts.map +1 -0
- package/dist/nlp/index.js +8 -0
- package/dist/nlp/index.js.map +1 -0
- package/dist/nlp/intent-classifier.d.ts +59 -0
- package/dist/nlp/intent-classifier.d.ts.map +1 -0
- package/dist/nlp/intent-classifier.js +384 -0
- package/dist/nlp/intent-classifier.js.map +1 -0
- package/dist/nlp/intent-parser.d.ts +152 -0
- package/dist/nlp/intent-parser.d.ts.map +1 -0
- package/dist/nlp/intent-parser.js +746 -0
- package/dist/nlp/intent-parser.js.map +1 -0
- package/dist/plugins/plugin-manager.d.ts +121 -0
- package/dist/plugins/plugin-manager.d.ts.map +1 -0
- package/dist/plugins/plugin-manager.js +606 -0
- package/dist/plugins/plugin-manager.js.map +1 -0
- package/dist/types/index.d.ts +224 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/backup-rollback-manager.d.ts +72 -0
- package/dist/utils/backup-rollback-manager.d.ts.map +1 -0
- package/dist/utils/backup-rollback-manager.js +288 -0
- package/dist/utils/backup-rollback-manager.js.map +1 -0
- package/dist/utils/claude-config-installer.d.ts +98 -0
- package/dist/utils/claude-config-installer.d.ts.map +1 -0
- package/dist/utils/claude-config-installer.js +678 -0
- package/dist/utils/claude-config-installer.js.map +1 -0
- package/dist/utils/config-manager.d.ts +73 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +339 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/error-handler.d.ts +46 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +169 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +105 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1,751 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RAG (Retrieval-Augmented Generation) CLI Commands
|
|
4
|
+
* Manages RAG stores for AI-powered code understanding and retrieval
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createRAGCommand = createRAGCommand;
|
|
8
|
+
const tslib_1 = require("tslib");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const fs = tslib_1.__importStar(require("fs/promises"));
|
|
11
|
+
const os = tslib_1.__importStar(require("os"));
|
|
12
|
+
const path = tslib_1.__importStar(require("path"));
|
|
13
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
14
|
+
const commander_1 = require("commander");
|
|
15
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
16
|
+
const ora_1 = tslib_1.__importDefault(require("ora"));
|
|
17
|
+
// Constants
|
|
18
|
+
const RAG_BASE_DIR = path.join(os.homedir(), '.wundr', 'rag-stores');
|
|
19
|
+
const RAG_GLOBAL_DIR = path.join(RAG_BASE_DIR, 'global');
|
|
20
|
+
const RAG_PROJECT_DIR = path.join(RAG_BASE_DIR, 'project-specific');
|
|
21
|
+
const CONFIG_FILE = path.join(RAG_BASE_DIR, 'config.json');
|
|
22
|
+
// Utility functions
|
|
23
|
+
function getTimestamp() {
|
|
24
|
+
return new Date().toISOString();
|
|
25
|
+
}
|
|
26
|
+
function formatBytes(bytes) {
|
|
27
|
+
if (bytes === 0) {
|
|
28
|
+
return '0 Bytes';
|
|
29
|
+
}
|
|
30
|
+
const k = 1024;
|
|
31
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
32
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
33
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
34
|
+
}
|
|
35
|
+
function getDirSize(dirPath) {
|
|
36
|
+
if (!(0, fs_1.existsSync)(dirPath)) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
let totalSize = 0;
|
|
40
|
+
try {
|
|
41
|
+
const files = (0, fs_1.readdirSync)(dirPath);
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
const filePath = path.join(dirPath, file);
|
|
44
|
+
const stat = (0, fs_1.statSync)(filePath);
|
|
45
|
+
if (stat.isDirectory()) {
|
|
46
|
+
totalSize += getDirSize(filePath);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
totalSize += stat.size;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Ignore permission errors
|
|
55
|
+
}
|
|
56
|
+
return totalSize;
|
|
57
|
+
}
|
|
58
|
+
async function loadConfig() {
|
|
59
|
+
try {
|
|
60
|
+
const configContent = await fs.readFile(CONFIG_FILE, 'utf-8');
|
|
61
|
+
return JSON.parse(configContent);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return getDefaultConfig();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function getDefaultConfig() {
|
|
68
|
+
return {
|
|
69
|
+
version: '1.0.0',
|
|
70
|
+
stores: {
|
|
71
|
+
global: {
|
|
72
|
+
path: RAG_GLOBAL_DIR,
|
|
73
|
+
description: 'Global RAG store for shared knowledge',
|
|
74
|
+
autoSync: true,
|
|
75
|
+
pruneDeleted: true,
|
|
76
|
+
},
|
|
77
|
+
'project-specific': {
|
|
78
|
+
path: RAG_PROJECT_DIR,
|
|
79
|
+
description: 'Project-specific RAG stores',
|
|
80
|
+
autoSync: false,
|
|
81
|
+
pruneDeleted: false,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
embeddings: {
|
|
85
|
+
model: 'text-embedding-004',
|
|
86
|
+
dimensions: 768,
|
|
87
|
+
batchSize: 100,
|
|
88
|
+
},
|
|
89
|
+
indexing: {
|
|
90
|
+
chunkSize: 1000,
|
|
91
|
+
chunkOverlap: 200,
|
|
92
|
+
maxTokens: 8192,
|
|
93
|
+
},
|
|
94
|
+
retrieval: {
|
|
95
|
+
topK: 5,
|
|
96
|
+
minScore: 0.7,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async function saveConfig(config) {
|
|
101
|
+
await fs.mkdir(path.dirname(CONFIG_FILE), { recursive: true });
|
|
102
|
+
await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
103
|
+
}
|
|
104
|
+
async function getAllStores() {
|
|
105
|
+
const stores = [];
|
|
106
|
+
if ((0, fs_1.existsSync)(RAG_GLOBAL_DIR)) {
|
|
107
|
+
stores.push(RAG_GLOBAL_DIR);
|
|
108
|
+
}
|
|
109
|
+
if ((0, fs_1.existsSync)(RAG_PROJECT_DIR)) {
|
|
110
|
+
try {
|
|
111
|
+
const projectStores = (0, fs_1.readdirSync)(RAG_PROJECT_DIR);
|
|
112
|
+
for (const store of projectStores) {
|
|
113
|
+
const storePath = path.join(RAG_PROJECT_DIR, store);
|
|
114
|
+
if ((0, fs_1.statSync)(storePath).isDirectory()) {
|
|
115
|
+
stores.push(storePath);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Ignore permission errors
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return stores;
|
|
124
|
+
}
|
|
125
|
+
async function getStoreMetadata(storePath) {
|
|
126
|
+
const name = path.basename(storePath);
|
|
127
|
+
const embeddingsDir = path.join(storePath, 'embeddings');
|
|
128
|
+
const syncMetadataPath = path.join(storePath, 'metadata', 'sync.json');
|
|
129
|
+
const pruneMetadataPath = path.join(storePath, 'metadata', 'prune.json');
|
|
130
|
+
const indexMetadataPath = path.join(storePath, 'metadata', 'index.json');
|
|
131
|
+
let embeddingCount = 0;
|
|
132
|
+
if ((0, fs_1.existsSync)(embeddingsDir)) {
|
|
133
|
+
try {
|
|
134
|
+
const files = (0, fs_1.readdirSync)(embeddingsDir).filter(f => f.endsWith('.json'));
|
|
135
|
+
embeddingCount = files.length;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Ignore permission errors
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
let lastSync = null;
|
|
142
|
+
let sourceDir;
|
|
143
|
+
let status = 'unknown';
|
|
144
|
+
if ((0, fs_1.existsSync)(syncMetadataPath)) {
|
|
145
|
+
try {
|
|
146
|
+
const syncData = JSON.parse(await fs.readFile(syncMetadataPath, 'utf-8'));
|
|
147
|
+
lastSync = syncData.lastSync || null;
|
|
148
|
+
sourceDir = syncData.sourceDir;
|
|
149
|
+
status = syncData.status === 'synced' ? 'ready' : syncData.status;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// Ignore parse errors
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let lastPrune = null;
|
|
156
|
+
if ((0, fs_1.existsSync)(pruneMetadataPath)) {
|
|
157
|
+
try {
|
|
158
|
+
const pruneData = JSON.parse(await fs.readFile(pruneMetadataPath, 'utf-8'));
|
|
159
|
+
lastPrune = pruneData.lastPrune || null;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Ignore parse errors
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
let lastIndex = null;
|
|
166
|
+
if ((0, fs_1.existsSync)(indexMetadataPath)) {
|
|
167
|
+
try {
|
|
168
|
+
const indexData = JSON.parse(await fs.readFile(indexMetadataPath, 'utf-8'));
|
|
169
|
+
lastIndex = indexData.lastIndex || null;
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Ignore parse errors
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
name,
|
|
177
|
+
path: storePath,
|
|
178
|
+
embeddingCount,
|
|
179
|
+
lastSync,
|
|
180
|
+
lastPrune,
|
|
181
|
+
lastIndex,
|
|
182
|
+
status,
|
|
183
|
+
sourceDir,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// Create RAG command
|
|
187
|
+
function createRAGCommand() {
|
|
188
|
+
const command = new commander_1.Command('rag')
|
|
189
|
+
.description('Manage RAG (Retrieval-Augmented Generation) stores for AI-powered code understanding')
|
|
190
|
+
.addHelpText('after', chalk_1.default.gray(`
|
|
191
|
+
Examples:
|
|
192
|
+
${chalk_1.default.green('wundr rag status')} Show RAG store status
|
|
193
|
+
${chalk_1.default.green('wundr rag sync')} Sync all RAG stores
|
|
194
|
+
${chalk_1.default.green('wundr rag prune')} Remove deleted files from stores
|
|
195
|
+
${chalk_1.default.green('wundr rag reindex')} Re-index stores
|
|
196
|
+
${chalk_1.default.green('wundr rag create myproject')} Create a new project-specific store
|
|
197
|
+
${chalk_1.default.green('wundr rag setup')} Run initial RAG infrastructure setup
|
|
198
|
+
`));
|
|
199
|
+
// Status command (default)
|
|
200
|
+
command
|
|
201
|
+
.command('status', { isDefault: true })
|
|
202
|
+
.description('Show RAG store status and statistics')
|
|
203
|
+
.option('--json', 'Output as JSON')
|
|
204
|
+
.action(async (options) => {
|
|
205
|
+
await showStatus(options);
|
|
206
|
+
});
|
|
207
|
+
// Sync command
|
|
208
|
+
command
|
|
209
|
+
.command('sync')
|
|
210
|
+
.description('Sync all RAG stores with their source directories')
|
|
211
|
+
.option('--store <name>', 'Only sync specific store')
|
|
212
|
+
.option('--dry-run', 'Show what would be synced without making changes')
|
|
213
|
+
.action(async (options) => {
|
|
214
|
+
await syncStores(options);
|
|
215
|
+
});
|
|
216
|
+
// Prune command
|
|
217
|
+
command
|
|
218
|
+
.command('prune')
|
|
219
|
+
.description('Remove deleted files from RAG stores')
|
|
220
|
+
.option('--store <name>', 'Only prune specific store')
|
|
221
|
+
.option('--dry-run', 'Show what would be pruned without making changes')
|
|
222
|
+
.action(async (options) => {
|
|
223
|
+
await pruneStores(options);
|
|
224
|
+
});
|
|
225
|
+
// Reindex command
|
|
226
|
+
command
|
|
227
|
+
.command('reindex')
|
|
228
|
+
.description('Re-index RAG stores with updated configurations')
|
|
229
|
+
.option('--store <name>', 'Only reindex specific store')
|
|
230
|
+
.option('--force', 'Force complete reindex')
|
|
231
|
+
.action(async (options) => {
|
|
232
|
+
await reindexStores(options);
|
|
233
|
+
});
|
|
234
|
+
// Create command
|
|
235
|
+
command
|
|
236
|
+
.command('create')
|
|
237
|
+
.description('Create a new RAG store')
|
|
238
|
+
.argument('<name>', 'Store name')
|
|
239
|
+
.option('-s, --source <path>', 'Source directory to index')
|
|
240
|
+
.option('-g, --global', 'Create as global store')
|
|
241
|
+
.action(async (name, options) => {
|
|
242
|
+
await createStore(name, options);
|
|
243
|
+
});
|
|
244
|
+
// Setup command
|
|
245
|
+
command
|
|
246
|
+
.command('setup')
|
|
247
|
+
.description('Run initial RAG infrastructure setup')
|
|
248
|
+
.option('--skip-api-key', 'Skip GEMINI_API_KEY configuration')
|
|
249
|
+
.action(async (options) => {
|
|
250
|
+
await runSetup(options);
|
|
251
|
+
});
|
|
252
|
+
// Config command
|
|
253
|
+
command
|
|
254
|
+
.command('config')
|
|
255
|
+
.description('View or modify RAG configuration')
|
|
256
|
+
.option('--get <key>', 'Get configuration value')
|
|
257
|
+
.option('--set <key=value>', 'Set configuration value')
|
|
258
|
+
.option('--reset', 'Reset to default configuration')
|
|
259
|
+
.action(async (options) => {
|
|
260
|
+
await manageConfig(options);
|
|
261
|
+
});
|
|
262
|
+
// Delete command
|
|
263
|
+
command
|
|
264
|
+
.command('delete')
|
|
265
|
+
.description('Delete a RAG store')
|
|
266
|
+
.argument('<name>', 'Store name')
|
|
267
|
+
.option('--force', 'Skip confirmation')
|
|
268
|
+
.action(async (name, options) => {
|
|
269
|
+
await deleteStore(name, options);
|
|
270
|
+
});
|
|
271
|
+
return command;
|
|
272
|
+
}
|
|
273
|
+
// Command implementations
|
|
274
|
+
async function showStatus(options) {
|
|
275
|
+
const spinner = (0, ora_1.default)('Loading RAG store status...').start();
|
|
276
|
+
try {
|
|
277
|
+
const stores = await getAllStores();
|
|
278
|
+
const storeMetadata = [];
|
|
279
|
+
let totalEmbeddings = 0;
|
|
280
|
+
for (const store of stores) {
|
|
281
|
+
const metadata = await getStoreMetadata(store);
|
|
282
|
+
storeMetadata.push(metadata);
|
|
283
|
+
totalEmbeddings += metadata.embeddingCount;
|
|
284
|
+
}
|
|
285
|
+
const totalSize = getDirSize(RAG_BASE_DIR);
|
|
286
|
+
spinner.stop();
|
|
287
|
+
if (options.json) {
|
|
288
|
+
console.log(JSON.stringify({
|
|
289
|
+
timestamp: getTimestamp(),
|
|
290
|
+
stores: storeMetadata,
|
|
291
|
+
totalEmbeddings,
|
|
292
|
+
totalDiskUsage: formatBytes(totalSize),
|
|
293
|
+
configPath: CONFIG_FILE,
|
|
294
|
+
}, null, 2));
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
console.log(chalk_1.default.cyan('\nRAG Store Status Report'));
|
|
298
|
+
console.log(chalk_1.default.gray('='.repeat(70)));
|
|
299
|
+
console.log(chalk_1.default.white('Config:'), chalk_1.default.gray(CONFIG_FILE));
|
|
300
|
+
console.log(chalk_1.default.white('Total Embeddings:'), chalk_1.default.green(totalEmbeddings));
|
|
301
|
+
console.log(chalk_1.default.white('Disk Usage:'), chalk_1.default.green(formatBytes(totalSize)));
|
|
302
|
+
console.log(chalk_1.default.gray('-'.repeat(70)));
|
|
303
|
+
if (storeMetadata.length === 0) {
|
|
304
|
+
console.log(chalk_1.default.yellow('\nNo RAG stores found. Run "wundr rag setup" to get started.\n'));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
console.log(chalk_1.default.cyan(padRight('Store', 25) +
|
|
308
|
+
padRight('Embeddings', 12) +
|
|
309
|
+
padRight('Last Sync', 18) +
|
|
310
|
+
padRight('Status', 15)));
|
|
311
|
+
console.log(chalk_1.default.gray('-'.repeat(70)));
|
|
312
|
+
for (const store of storeMetadata) {
|
|
313
|
+
const lastSync = store.lastSync
|
|
314
|
+
? new Date(store.lastSync).toLocaleDateString()
|
|
315
|
+
: 'Never';
|
|
316
|
+
let statusColor = chalk_1.default.yellow;
|
|
317
|
+
if (store.status === 'ready') {
|
|
318
|
+
statusColor = chalk_1.default.green;
|
|
319
|
+
}
|
|
320
|
+
if (store.status === 'error') {
|
|
321
|
+
statusColor = chalk_1.default.red;
|
|
322
|
+
}
|
|
323
|
+
console.log(padRight(store.name, 25) +
|
|
324
|
+
padRight(String(store.embeddingCount), 12) +
|
|
325
|
+
padRight(lastSync, 18) +
|
|
326
|
+
statusColor(padRight(store.status, 15)));
|
|
327
|
+
}
|
|
328
|
+
console.log(chalk_1.default.gray('-'.repeat(70)));
|
|
329
|
+
console.log('');
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
spinner.fail('Failed to load RAG status');
|
|
333
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function syncStores(options) {
|
|
337
|
+
const spinner = (0, ora_1.default)('Syncing RAG stores...').start();
|
|
338
|
+
try {
|
|
339
|
+
const stores = await getAllStores();
|
|
340
|
+
let synced = 0;
|
|
341
|
+
let skipped = 0;
|
|
342
|
+
spinner.stop();
|
|
343
|
+
console.log(chalk_1.default.cyan('\nSyncing RAG Stores\n'));
|
|
344
|
+
for (const storePath of stores) {
|
|
345
|
+
const storeName = path.basename(storePath);
|
|
346
|
+
if (options.store && storeName !== options.store) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const sourceMetadataPath = path.join(storePath, 'metadata', 'source.json');
|
|
350
|
+
if (!(0, fs_1.existsSync)(sourceMetadataPath)) {
|
|
351
|
+
console.log(chalk_1.default.yellow(` [SKIP] ${storeName}: No source metadata`));
|
|
352
|
+
skipped++;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
try {
|
|
356
|
+
const sourceMetadata = JSON.parse(await fs.readFile(sourceMetadataPath, 'utf-8'));
|
|
357
|
+
const sourceDir = sourceMetadata.sourceDir;
|
|
358
|
+
if (!sourceDir || !(0, fs_1.existsSync)(sourceDir)) {
|
|
359
|
+
console.log(chalk_1.default.yellow(` [SKIP] ${storeName}: Source directory not found`));
|
|
360
|
+
skipped++;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
// Count files
|
|
364
|
+
let fileCount = 0;
|
|
365
|
+
const countFiles = (dir) => {
|
|
366
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const entries = (0, fs_1.readdirSync)(dir);
|
|
371
|
+
for (const entry of entries) {
|
|
372
|
+
const fullPath = path.join(dir, entry);
|
|
373
|
+
const stat = (0, fs_1.statSync)(fullPath);
|
|
374
|
+
if (stat.isDirectory() &&
|
|
375
|
+
!entry.startsWith('.') &&
|
|
376
|
+
entry !== 'node_modules') {
|
|
377
|
+
countFiles(fullPath);
|
|
378
|
+
}
|
|
379
|
+
else if (stat.isFile() &&
|
|
380
|
+
/\.(ts|js|tsx|jsx|md|json)$/.test(entry)) {
|
|
381
|
+
fileCount++;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
// Ignore permission errors
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
countFiles(sourceDir);
|
|
390
|
+
if (options.dryRun) {
|
|
391
|
+
console.log(chalk_1.default.blue(` [DRY-RUN] ${storeName}: Would sync ${fileCount} files`));
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
// Update sync metadata
|
|
395
|
+
const syncMetadata = {
|
|
396
|
+
lastSync: getTimestamp(),
|
|
397
|
+
filesCount: fileCount,
|
|
398
|
+
sourceDir,
|
|
399
|
+
status: 'synced',
|
|
400
|
+
};
|
|
401
|
+
await fs.mkdir(path.join(storePath, 'metadata'), { recursive: true });
|
|
402
|
+
await fs.writeFile(path.join(storePath, 'metadata', 'sync.json'), JSON.stringify(syncMetadata, null, 2));
|
|
403
|
+
console.log(chalk_1.default.green(` [OK] ${storeName}: Synced ${fileCount} files`));
|
|
404
|
+
}
|
|
405
|
+
synced++;
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
console.log(chalk_1.default.red(` [ERROR] ${storeName}: ${error instanceof Error ? error.message : String(error)}`));
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
console.log(chalk_1.default.gray('\n' + '-'.repeat(50)));
|
|
412
|
+
console.log(chalk_1.default.green(`Sync complete: ${synced} synced, ${skipped} skipped\n`));
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
spinner.fail('Failed to sync stores');
|
|
416
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
async function pruneStores(options) {
|
|
420
|
+
const spinner = (0, ora_1.default)('Pruning RAG stores...').start();
|
|
421
|
+
try {
|
|
422
|
+
const stores = await getAllStores();
|
|
423
|
+
let totalPruned = 0;
|
|
424
|
+
spinner.stop();
|
|
425
|
+
console.log(chalk_1.default.cyan('\nPruning RAG Stores\n'));
|
|
426
|
+
for (const storePath of stores) {
|
|
427
|
+
const storeName = path.basename(storePath);
|
|
428
|
+
if (options.store && storeName !== options.store) {
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
const embeddingsDir = path.join(storePath, 'embeddings');
|
|
432
|
+
let pruned = 0;
|
|
433
|
+
if ((0, fs_1.existsSync)(embeddingsDir)) {
|
|
434
|
+
try {
|
|
435
|
+
const embeddingFiles = (0, fs_1.readdirSync)(embeddingsDir).filter(f => f.endsWith('.json'));
|
|
436
|
+
for (const file of embeddingFiles) {
|
|
437
|
+
const embeddingPath = path.join(embeddingsDir, file);
|
|
438
|
+
try {
|
|
439
|
+
const embeddingData = JSON.parse(await fs.readFile(embeddingPath, 'utf-8'));
|
|
440
|
+
const originalPath = embeddingData.originalPath;
|
|
441
|
+
if (originalPath && !(0, fs_1.existsSync)(originalPath)) {
|
|
442
|
+
if (options.dryRun) {
|
|
443
|
+
console.log(chalk_1.default.blue(` [DRY-RUN] Would remove: ${file}`));
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
await fs.unlink(embeddingPath);
|
|
447
|
+
}
|
|
448
|
+
pruned++;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
// Skip files that can't be parsed
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
catch {
|
|
457
|
+
// Ignore permission errors
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (!options.dryRun && pruned > 0) {
|
|
461
|
+
// Update prune metadata
|
|
462
|
+
const pruneMetadata = {
|
|
463
|
+
lastPrune: getTimestamp(),
|
|
464
|
+
prunedCount: pruned,
|
|
465
|
+
status: 'completed',
|
|
466
|
+
};
|
|
467
|
+
await fs.mkdir(path.join(storePath, 'metadata'), { recursive: true });
|
|
468
|
+
await fs.writeFile(path.join(storePath, 'metadata', 'prune.json'), JSON.stringify(pruneMetadata, null, 2));
|
|
469
|
+
}
|
|
470
|
+
console.log(chalk_1.default.green(` [OK] ${storeName}: Pruned ${pruned} entries`));
|
|
471
|
+
totalPruned += pruned;
|
|
472
|
+
}
|
|
473
|
+
console.log(chalk_1.default.gray('\n' + '-'.repeat(50)));
|
|
474
|
+
console.log(chalk_1.default.green(`Prune complete: ${totalPruned} entries removed\n`));
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
spinner.fail('Failed to prune stores');
|
|
478
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
async function reindexStores(options) {
|
|
482
|
+
const spinner = (0, ora_1.default)('Re-indexing RAG stores...').start();
|
|
483
|
+
try {
|
|
484
|
+
const stores = await getAllStores();
|
|
485
|
+
spinner.stop();
|
|
486
|
+
console.log(chalk_1.default.cyan('\nRe-indexing RAG Stores\n'));
|
|
487
|
+
for (const storePath of stores) {
|
|
488
|
+
const storeName = path.basename(storePath);
|
|
489
|
+
if (options.store && storeName !== options.store) {
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
const embeddingsDir = path.join(storePath, 'embeddings');
|
|
493
|
+
const indexesDir = path.join(storePath, 'indexes');
|
|
494
|
+
await fs.mkdir(indexesDir, { recursive: true });
|
|
495
|
+
let embeddingCount = 0;
|
|
496
|
+
if ((0, fs_1.existsSync)(embeddingsDir)) {
|
|
497
|
+
try {
|
|
498
|
+
const files = (0, fs_1.readdirSync)(embeddingsDir).filter(f => f.endsWith('.json'));
|
|
499
|
+
embeddingCount = files.length;
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
// Ignore permission errors
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
// Generate index file
|
|
506
|
+
const indexFile = path.join(indexesDir, 'main.json');
|
|
507
|
+
const indexData = {
|
|
508
|
+
version: '1.0.0',
|
|
509
|
+
created: getTimestamp(),
|
|
510
|
+
updated: getTimestamp(),
|
|
511
|
+
embeddingCount,
|
|
512
|
+
indexType: 'flat',
|
|
513
|
+
status: 'ready',
|
|
514
|
+
};
|
|
515
|
+
await fs.writeFile(indexFile, JSON.stringify(indexData, null, 2));
|
|
516
|
+
// Update index metadata
|
|
517
|
+
const indexMetadata = {
|
|
518
|
+
lastIndex: getTimestamp(),
|
|
519
|
+
totalEmbeddings: embeddingCount,
|
|
520
|
+
indexFile,
|
|
521
|
+
status: 'indexed',
|
|
522
|
+
};
|
|
523
|
+
await fs.mkdir(path.join(storePath, 'metadata'), { recursive: true });
|
|
524
|
+
await fs.writeFile(path.join(storePath, 'metadata', 'index.json'), JSON.stringify(indexMetadata, null, 2));
|
|
525
|
+
console.log(chalk_1.default.green(` [OK] ${storeName}: Indexed ${embeddingCount} entries`));
|
|
526
|
+
}
|
|
527
|
+
console.log(chalk_1.default.gray('\n' + '-'.repeat(50)));
|
|
528
|
+
console.log(chalk_1.default.green('Re-index complete\n'));
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
spinner.fail('Failed to reindex stores');
|
|
532
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function createStore(name, options) {
|
|
536
|
+
const spinner = (0, ora_1.default)(`Creating RAG store: ${name}...`).start();
|
|
537
|
+
try {
|
|
538
|
+
const baseDir = options.global
|
|
539
|
+
? RAG_GLOBAL_DIR
|
|
540
|
+
: path.join(RAG_PROJECT_DIR, name);
|
|
541
|
+
if ((0, fs_1.existsSync)(baseDir)) {
|
|
542
|
+
spinner.fail(`Store already exists: ${name}`);
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
// Get source directory
|
|
546
|
+
let sourceDir = options.source;
|
|
547
|
+
if (!sourceDir) {
|
|
548
|
+
spinner.stop();
|
|
549
|
+
const answers = await inquirer_1.default.prompt([
|
|
550
|
+
{
|
|
551
|
+
type: 'input',
|
|
552
|
+
name: 'sourceDir',
|
|
553
|
+
message: 'Enter source directory to index:',
|
|
554
|
+
default: process.cwd(),
|
|
555
|
+
validate: (input) => {
|
|
556
|
+
if (!(0, fs_1.existsSync)(input)) {
|
|
557
|
+
return 'Directory does not exist';
|
|
558
|
+
}
|
|
559
|
+
return true;
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
]);
|
|
563
|
+
sourceDir = answers.sourceDir;
|
|
564
|
+
spinner.start();
|
|
565
|
+
}
|
|
566
|
+
// Create store directories
|
|
567
|
+
await fs.mkdir(path.join(baseDir, 'embeddings'), { recursive: true });
|
|
568
|
+
await fs.mkdir(path.join(baseDir, 'indexes'), { recursive: true });
|
|
569
|
+
await fs.mkdir(path.join(baseDir, 'metadata'), { recursive: true });
|
|
570
|
+
await fs.mkdir(path.join(baseDir, 'cache'), { recursive: true });
|
|
571
|
+
// Create source metadata
|
|
572
|
+
const sourceMetadata = {
|
|
573
|
+
sourceDir,
|
|
574
|
+
created: getTimestamp(),
|
|
575
|
+
name,
|
|
576
|
+
type: options.global ? 'global' : 'project-specific',
|
|
577
|
+
};
|
|
578
|
+
await fs.writeFile(path.join(baseDir, 'metadata', 'source.json'), JSON.stringify(sourceMetadata, null, 2));
|
|
579
|
+
spinner.succeed(`RAG store created: ${name}`);
|
|
580
|
+
console.log(chalk_1.default.gray(` Location: ${baseDir}`));
|
|
581
|
+
console.log(chalk_1.default.gray(` Source: ${sourceDir}`));
|
|
582
|
+
console.log(chalk_1.default.green('\nRun "wundr rag sync" to sync the store.\n'));
|
|
583
|
+
}
|
|
584
|
+
catch (error) {
|
|
585
|
+
spinner.fail('Failed to create store');
|
|
586
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
async function runSetup(options) {
|
|
590
|
+
console.log(chalk_1.default.cyan('\nRAG Infrastructure Setup\n'));
|
|
591
|
+
console.log(chalk_1.default.gray('This will set up the RAG infrastructure for Wundr.\n'));
|
|
592
|
+
const spinner = (0, ora_1.default)('Checking prerequisites...').start();
|
|
593
|
+
try {
|
|
594
|
+
// Check Node.js version
|
|
595
|
+
const versionPart = process.version.slice(1).split('.')[0] ?? '0';
|
|
596
|
+
const nodeVersion = parseInt(versionPart, 10);
|
|
597
|
+
if (nodeVersion < 18) {
|
|
598
|
+
spinner.fail(`Node.js 18+ required. Current version: ${process.version}`);
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
spinner.succeed('Node.js version OK');
|
|
602
|
+
// Install @google/genai
|
|
603
|
+
spinner.start('Checking @google/genai package...');
|
|
604
|
+
try {
|
|
605
|
+
require.resolve('@google/genai');
|
|
606
|
+
spinner.succeed('@google/genai is available');
|
|
607
|
+
}
|
|
608
|
+
catch {
|
|
609
|
+
spinner.text = 'Installing @google/genai...';
|
|
610
|
+
const { execSync } = await Promise.resolve().then(() => tslib_1.__importStar(require('child_process')));
|
|
611
|
+
execSync('npm install -g @google/genai', { stdio: 'pipe' });
|
|
612
|
+
spinner.succeed('@google/genai installed');
|
|
613
|
+
}
|
|
614
|
+
// Configure API key
|
|
615
|
+
if (!options.skipApiKey) {
|
|
616
|
+
spinner.stop();
|
|
617
|
+
console.log(chalk_1.default.yellow('\nGEMINI_API_KEY Configuration'));
|
|
618
|
+
console.log(chalk_1.default.gray('Get your API key from: https://makersuite.google.com/app/apikey\n'));
|
|
619
|
+
if (process.env.GEMINI_API_KEY) {
|
|
620
|
+
console.log(chalk_1.default.green('GEMINI_API_KEY is already set in environment.\n'));
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
console.log(chalk_1.default.yellow('GEMINI_API_KEY is not set.'));
|
|
624
|
+
console.log(chalk_1.default.gray('Add the following to your shell profile:'));
|
|
625
|
+
console.log(chalk_1.default.white(' export GEMINI_API_KEY="your-api-key-here"\n'));
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// Create directory structure
|
|
629
|
+
spinner.start('Creating RAG store directories...');
|
|
630
|
+
await fs.mkdir(RAG_GLOBAL_DIR, { recursive: true });
|
|
631
|
+
await fs.mkdir(path.join(RAG_GLOBAL_DIR, 'embeddings'), {
|
|
632
|
+
recursive: true,
|
|
633
|
+
});
|
|
634
|
+
await fs.mkdir(path.join(RAG_GLOBAL_DIR, 'indexes'), { recursive: true });
|
|
635
|
+
await fs.mkdir(path.join(RAG_GLOBAL_DIR, 'metadata'), { recursive: true });
|
|
636
|
+
await fs.mkdir(path.join(RAG_GLOBAL_DIR, 'cache'), { recursive: true });
|
|
637
|
+
await fs.mkdir(RAG_PROJECT_DIR, { recursive: true });
|
|
638
|
+
spinner.succeed('RAG store directories created');
|
|
639
|
+
// Create config file
|
|
640
|
+
spinner.start('Creating configuration file...');
|
|
641
|
+
if (!(0, fs_1.existsSync)(CONFIG_FILE)) {
|
|
642
|
+
const config = getDefaultConfig();
|
|
643
|
+
await saveConfig(config);
|
|
644
|
+
spinner.succeed('Configuration file created');
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
spinner.succeed('Configuration file already exists');
|
|
648
|
+
}
|
|
649
|
+
console.log(chalk_1.default.green('\nRAG infrastructure setup complete!\n'));
|
|
650
|
+
console.log(chalk_1.default.gray('Next steps:'));
|
|
651
|
+
console.log(chalk_1.default.white(' 1. Set GEMINI_API_KEY if not already set'));
|
|
652
|
+
console.log(chalk_1.default.white(' 2. Run "wundr rag create <name>" to create a store'));
|
|
653
|
+
console.log(chalk_1.default.white(' 3. Run "wundr rag sync" to sync your stores'));
|
|
654
|
+
console.log(chalk_1.default.white(' 4. Run "wundr rag status" to check status\n'));
|
|
655
|
+
}
|
|
656
|
+
catch (error) {
|
|
657
|
+
spinner.fail('Setup failed');
|
|
658
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
async function manageConfig(options) {
|
|
662
|
+
try {
|
|
663
|
+
if (options.reset) {
|
|
664
|
+
const config = getDefaultConfig();
|
|
665
|
+
await saveConfig(config);
|
|
666
|
+
console.log(chalk_1.default.green('Configuration reset to defaults.'));
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
const config = await loadConfig();
|
|
670
|
+
if (options.get) {
|
|
671
|
+
const keys = options.get.split('.');
|
|
672
|
+
let value = config;
|
|
673
|
+
for (const key of keys) {
|
|
674
|
+
value = value[key];
|
|
675
|
+
}
|
|
676
|
+
console.log(JSON.stringify(value, null, 2));
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
if (options.set) {
|
|
680
|
+
const [keyPath, ...valueParts] = options.set.split('=');
|
|
681
|
+
const value = valueParts.join('=');
|
|
682
|
+
if (!keyPath) {
|
|
683
|
+
console.error(chalk_1.default.red('Invalid key path'));
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
const keys = keyPath.split('.');
|
|
687
|
+
let obj = config;
|
|
688
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
689
|
+
const key = keys[i];
|
|
690
|
+
if (key) {
|
|
691
|
+
obj = obj[key];
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
const lastKey = keys[keys.length - 1];
|
|
695
|
+
if (!lastKey) {
|
|
696
|
+
console.error(chalk_1.default.red('Invalid key path'));
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
// Parse value
|
|
700
|
+
try {
|
|
701
|
+
obj[lastKey] = JSON.parse(value);
|
|
702
|
+
}
|
|
703
|
+
catch {
|
|
704
|
+
obj[lastKey] = value;
|
|
705
|
+
}
|
|
706
|
+
await saveConfig(config);
|
|
707
|
+
console.log(chalk_1.default.green(`Set ${keyPath} = ${value}`));
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
// Show current config
|
|
711
|
+
console.log(chalk_1.default.cyan('\nRAG Configuration\n'));
|
|
712
|
+
console.log(JSON.stringify(config, null, 2));
|
|
713
|
+
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
async function deleteStore(name, options) {
|
|
719
|
+
const storePath = name === 'global' ? RAG_GLOBAL_DIR : path.join(RAG_PROJECT_DIR, name);
|
|
720
|
+
if (!(0, fs_1.existsSync)(storePath)) {
|
|
721
|
+
console.log(chalk_1.default.red(`Store not found: ${name}`));
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
if (!options.force) {
|
|
725
|
+
const answers = await inquirer_1.default.prompt([
|
|
726
|
+
{
|
|
727
|
+
type: 'confirm',
|
|
728
|
+
name: 'confirm',
|
|
729
|
+
message: `Are you sure you want to delete store "${name}"?`,
|
|
730
|
+
default: false,
|
|
731
|
+
},
|
|
732
|
+
]);
|
|
733
|
+
if (!answers.confirm) {
|
|
734
|
+
console.log(chalk_1.default.yellow('Cancelled.'));
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const spinner = (0, ora_1.default)(`Deleting store: ${name}...`).start();
|
|
739
|
+
try {
|
|
740
|
+
await fs.rm(storePath, { recursive: true, force: true });
|
|
741
|
+
spinner.succeed(`Store deleted: ${name}`);
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
spinner.fail('Failed to delete store');
|
|
745
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function padRight(str, length) {
|
|
749
|
+
return str.length >= length ? str : str + ' '.repeat(length - str.length);
|
|
750
|
+
}
|
|
751
|
+
//# sourceMappingURL=rag.js.map
|