@reepoe/plugin 1.3.0 → 1.3.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/bin/clear-cache.js +98 -0
- package/bin/start.js +1 -1
- package/package.json +3 -3
- package/lib/activation-client.js +0 -326
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ReePoe Clear Cache - Reset learned patterns
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const readline = require('readline');
|
|
9
|
+
|
|
10
|
+
async function clearCache() {
|
|
11
|
+
const projectRoot = process.cwd();
|
|
12
|
+
const storePath = path.join(projectRoot, 'data', 'mini_rag_store.json');
|
|
13
|
+
const logPath = path.join(projectRoot, 'logs', 'mini_rag.log');
|
|
14
|
+
|
|
15
|
+
console.log('\n╔═══════════════════════════════════════════════════════════╗');
|
|
16
|
+
console.log('║ ReePoe Cache Clearing ║');
|
|
17
|
+
console.log('╚═══════════════════════════════════════════════════════════╝\n');
|
|
18
|
+
|
|
19
|
+
// Check if files exist
|
|
20
|
+
const storeExists = fs.existsSync(storePath);
|
|
21
|
+
const logExists = fs.existsSync(logPath);
|
|
22
|
+
|
|
23
|
+
if (!storeExists && !logExists) {
|
|
24
|
+
console.log('✅ No cache files found - nothing to clear\n');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log('📋 Files to clear:');
|
|
29
|
+
if (storeExists) {
|
|
30
|
+
try {
|
|
31
|
+
const stats = fs.statSync(storePath);
|
|
32
|
+
const storeContent = fs.readFileSync(storePath, 'utf8');
|
|
33
|
+
const patternCount = storeContent ? Object.keys(JSON.parse(storeContent)).length : 0;
|
|
34
|
+
console.log(` • ${storePath} (${patternCount} patterns, ${(stats.size / 1024).toFixed(1)} KB)`);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.log(` • ${storePath} (error reading file)`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (logExists) {
|
|
40
|
+
try {
|
|
41
|
+
const stats = fs.statSync(logPath);
|
|
42
|
+
console.log(` • ${logPath} (${(stats.size / 1024).toFixed(1)} KB)`);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.log(` • ${logPath} (error reading file)`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
console.log('');
|
|
48
|
+
|
|
49
|
+
// Confirm
|
|
50
|
+
const rl = readline.createInterface({
|
|
51
|
+
input: process.stdin,
|
|
52
|
+
output: process.stdout
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const answer = await new Promise((resolve) => {
|
|
56
|
+
rl.question('⚠️ This will delete all learned patterns. Continue? (yes/no): ', (ans) => {
|
|
57
|
+
rl.close();
|
|
58
|
+
resolve(ans.trim().toLowerCase());
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (answer !== 'yes' && answer !== 'y') {
|
|
63
|
+
console.log('\n❌ Cancelled - cache not cleared\n');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Clear files
|
|
68
|
+
try {
|
|
69
|
+
if (storeExists) {
|
|
70
|
+
// Ensure directory exists
|
|
71
|
+
const storeDir = path.dirname(storePath);
|
|
72
|
+
if (!fs.existsSync(storeDir)) {
|
|
73
|
+
fs.mkdirSync(storeDir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
fs.writeFileSync(storePath, '{}', 'utf8');
|
|
76
|
+
console.log(`✅ Cleared: ${storePath}`);
|
|
77
|
+
}
|
|
78
|
+
if (logExists) {
|
|
79
|
+
// Ensure directory exists
|
|
80
|
+
const logDir = path.dirname(logPath);
|
|
81
|
+
if (!fs.existsSync(logDir)) {
|
|
82
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
fs.writeFileSync(logPath, '', 'utf8');
|
|
85
|
+
console.log(`✅ Cleared: ${logPath}`);
|
|
86
|
+
}
|
|
87
|
+
console.log('\n✅ Cache cleared successfully!\n');
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error(`\n❌ Error clearing cache: ${error.message}\n`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
clearCache().catch(error => {
|
|
95
|
+
console.error(`❌ Error: ${error.message}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
});
|
|
98
|
+
|
package/bin/start.js
CHANGED
|
@@ -302,7 +302,7 @@ async function setupProjectIfNeeded(port) {
|
|
|
302
302
|
api: { port, host: '127.0.0.1' },
|
|
303
303
|
mini_rag: {
|
|
304
304
|
enabled: true,
|
|
305
|
-
confidence_threshold: 0.
|
|
305
|
+
confidence_threshold: 0.85,
|
|
306
306
|
cta_whitelist: ['run_tests', 'open_file', 'search_symbols', 'get_repo_stats']
|
|
307
307
|
},
|
|
308
308
|
scanner: { language: projectInfo.language, auto_scan: true }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reepoe/plugin",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "ReePoe AI Code Manager - Install in any codebase for instant AI agent integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"reepoe-status": "./bin/status.js",
|
|
28
28
|
"reepoe-metrics": "./bin/metrics.js",
|
|
29
29
|
"reepoe-admin": "./bin/admin.js",
|
|
30
|
-
"reepoe-extend-request": "./bin/extend-request.js"
|
|
30
|
+
"reepoe-extend-request": "./bin/extend-request.js",
|
|
31
|
+
"reepoe-clear-cache": "./bin/clear-cache.js"
|
|
31
32
|
},
|
|
32
33
|
"scripts": {
|
|
33
34
|
"postinstall": "node scripts/setup.js"
|
|
@@ -51,7 +52,6 @@
|
|
|
51
52
|
},
|
|
52
53
|
"files": [
|
|
53
54
|
"bin",
|
|
54
|
-
"lib",
|
|
55
55
|
"scripts",
|
|
56
56
|
"binaries",
|
|
57
57
|
"README.md"
|
package/lib/activation-client.js
DELETED
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Activation API Client (Phase 3B)
|
|
4
|
-
* Handles communication with ReePoe activation API
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const axios = require('axios');
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const os = require('os');
|
|
11
|
-
|
|
12
|
-
const API_BASE_URL = process.env.REEPOE_API_URL || 'https://reepoe-api.onrender.com';
|
|
13
|
-
|
|
14
|
-
class ActivationClient {
|
|
15
|
-
constructor() {
|
|
16
|
-
this.apiUrl = API_BASE_URL;
|
|
17
|
-
this.activationFile = path.join(os.homedir(), '.reepoe', 'activation.json');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Check if user is activated
|
|
22
|
-
*/
|
|
23
|
-
async checkActivation(email, version) {
|
|
24
|
-
try {
|
|
25
|
-
const response = await axios.post(`${this.apiUrl}/api/activate/check`, {
|
|
26
|
-
email,
|
|
27
|
-
version
|
|
28
|
-
});
|
|
29
|
-
return response.data;
|
|
30
|
-
} catch (error) {
|
|
31
|
-
if (error.response) {
|
|
32
|
-
return error.response.data;
|
|
33
|
-
}
|
|
34
|
-
throw new Error(`Activation check failed: ${error.message}`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Redeem activation code
|
|
40
|
-
*/
|
|
41
|
-
async redeemCode(email, code, version) {
|
|
42
|
-
try {
|
|
43
|
-
const machineId = this.getMachineId();
|
|
44
|
-
|
|
45
|
-
const response = await axios.post(`${this.apiUrl}/api/activate/redeem`, {
|
|
46
|
-
email,
|
|
47
|
-
code,
|
|
48
|
-
version,
|
|
49
|
-
machine_id: machineId
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
if (response.data.success) {
|
|
53
|
-
// Save activation locally
|
|
54
|
-
this.saveActivation(response.data);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return response.data;
|
|
58
|
-
} catch (error) {
|
|
59
|
-
if (error.response) {
|
|
60
|
-
return error.response.data;
|
|
61
|
-
}
|
|
62
|
-
throw new Error(`Code redemption failed: ${error.message}`);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Join waitlist
|
|
68
|
-
*/
|
|
69
|
-
async joinWaitlist(email) {
|
|
70
|
-
try {
|
|
71
|
-
const response = await axios.post(`${this.apiUrl}/api/waitlist/join`, {
|
|
72
|
-
email
|
|
73
|
-
});
|
|
74
|
-
return response.data;
|
|
75
|
-
} catch (error) {
|
|
76
|
-
if (error.response) {
|
|
77
|
-
return error.response.data;
|
|
78
|
-
}
|
|
79
|
-
throw new Error(`Waitlist join failed: ${error.message}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Get user metrics
|
|
85
|
-
*/
|
|
86
|
-
async getUserMetrics(email) {
|
|
87
|
-
try {
|
|
88
|
-
const response = await axios.get(`${this.apiUrl}/api/metrics/user/${email}`);
|
|
89
|
-
return response.data;
|
|
90
|
-
} catch (error) {
|
|
91
|
-
if (error.response) {
|
|
92
|
-
return error.response.data;
|
|
93
|
-
}
|
|
94
|
-
throw new Error(`Failed to get metrics: ${error.message}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Request extension
|
|
100
|
-
*/
|
|
101
|
-
async requestExtension(email, reason) {
|
|
102
|
-
try {
|
|
103
|
-
const response = await axios.post(`${this.apiUrl}/api/users/extend-request`, {
|
|
104
|
-
email,
|
|
105
|
-
reason
|
|
106
|
-
});
|
|
107
|
-
return response.data;
|
|
108
|
-
} catch (error) {
|
|
109
|
-
if (error.response) {
|
|
110
|
-
return error.response.data;
|
|
111
|
-
}
|
|
112
|
-
throw new Error(`Extension request failed: ${error.message}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Admin: Login
|
|
118
|
-
*/
|
|
119
|
-
async adminLogin(email, adminCode) {
|
|
120
|
-
try {
|
|
121
|
-
const response = await axios.post(`${this.apiUrl}/api/admin/auth`, {
|
|
122
|
-
email,
|
|
123
|
-
admin_code: adminCode
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
if (response.data.success) {
|
|
127
|
-
// Save admin token
|
|
128
|
-
this.saveAdminToken(response.data.admin_token);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return response.data;
|
|
132
|
-
} catch (error) {
|
|
133
|
-
if (error.response) {
|
|
134
|
-
return error.response.data;
|
|
135
|
-
}
|
|
136
|
-
throw new Error(`Admin login failed: ${error.message}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Admin: List users
|
|
142
|
-
*/
|
|
143
|
-
async adminListUsers(status = null, limit = 50) {
|
|
144
|
-
try {
|
|
145
|
-
const token = this.loadAdminToken();
|
|
146
|
-
if (!token) {
|
|
147
|
-
throw new Error('Admin token not found. Run: reepoe admin login');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
let url = `${this.apiUrl}/api/admin/users?limit=${limit}`;
|
|
151
|
-
if (status) {
|
|
152
|
-
url += `&status=${status}`;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const response = await axios.get(url, {
|
|
156
|
-
headers: { 'Authorization': `Bearer ${token}` }
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return response.data;
|
|
160
|
-
} catch (error) {
|
|
161
|
-
if (error.response) {
|
|
162
|
-
return error.response.data;
|
|
163
|
-
}
|
|
164
|
-
throw new Error(`Failed to list users: ${error.message}`);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Admin: Generate codes
|
|
170
|
-
*/
|
|
171
|
-
async adminGenerateCodes(count, codeType = 'ALPHA', adminEmail, notes) {
|
|
172
|
-
try {
|
|
173
|
-
const token = this.loadAdminToken();
|
|
174
|
-
if (!token) {
|
|
175
|
-
throw new Error('Admin token not found. Run: reepoe admin login');
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const response = await axios.post(`${this.apiUrl}/api/admin/codes/generate`, {
|
|
179
|
-
count,
|
|
180
|
-
code_type: codeType,
|
|
181
|
-
admin_email: adminEmail,
|
|
182
|
-
notes
|
|
183
|
-
}, {
|
|
184
|
-
headers: { 'Authorization': `Bearer ${token}` }
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
return response.data;
|
|
188
|
-
} catch (error) {
|
|
189
|
-
if (error.response) {
|
|
190
|
-
return error.response.data;
|
|
191
|
-
}
|
|
192
|
-
throw new Error(`Failed to generate codes: ${error.message}`);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Admin: Extend user
|
|
198
|
-
*/
|
|
199
|
-
async adminExtendUser(email, days, adminEmail) {
|
|
200
|
-
try {
|
|
201
|
-
const token = this.loadAdminToken();
|
|
202
|
-
if (!token) {
|
|
203
|
-
throw new Error('Admin token not found. Run: reepoe admin login');
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
const response = await axios.post(`${this.apiUrl}/api/admin/users/extend`, {
|
|
207
|
-
email,
|
|
208
|
-
days,
|
|
209
|
-
admin_email: adminEmail
|
|
210
|
-
}, {
|
|
211
|
-
headers: { 'Authorization': `Bearer ${token}` }
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
return response.data;
|
|
215
|
-
} catch (error) {
|
|
216
|
-
if (error.response) {
|
|
217
|
-
return error.response.data;
|
|
218
|
-
}
|
|
219
|
-
throw new Error(`Failed to extend user: ${error.message}`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// ========== Local Storage ==========
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Save activation data locally
|
|
227
|
-
*/
|
|
228
|
-
saveActivation(activationData) {
|
|
229
|
-
const configDir = path.join(os.homedir(), '.reepoe');
|
|
230
|
-
if (!fs.existsSync(configDir)) {
|
|
231
|
-
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Detect cloud environment
|
|
235
|
-
const isCloud = !!(
|
|
236
|
-
process.env.REPL_ID ||
|
|
237
|
-
process.env.CODESPACE_NAME ||
|
|
238
|
-
process.env.GITPOD_WORKSPACE_ID
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
const data = {
|
|
242
|
-
email: activationData.user?.email || activationData.email,
|
|
243
|
-
token: activationData.token,
|
|
244
|
-
activated_at: activationData.user?.activated_at || new Date().toISOString(),
|
|
245
|
-
expires_at: activationData.user?.expires_at,
|
|
246
|
-
status: activationData.user?.status || 'active',
|
|
247
|
-
api_base: isCloud ? 'https://reepoe-api.onrender.com' : 'http://localhost:8000'
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
fs.writeFileSync(this.activationFile, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Load activation data
|
|
255
|
-
*/
|
|
256
|
-
loadActivation() {
|
|
257
|
-
if (!fs.existsSync(this.activationFile)) {
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
try {
|
|
262
|
-
const data = JSON.parse(fs.readFileSync(this.activationFile, 'utf8'));
|
|
263
|
-
return data;
|
|
264
|
-
} catch (error) {
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Save admin token
|
|
271
|
-
*/
|
|
272
|
-
saveAdminToken(token) {
|
|
273
|
-
const configDir = path.join(os.homedir(), '.reepoe');
|
|
274
|
-
const adminFile = path.join(configDir, 'admin_session.json');
|
|
275
|
-
|
|
276
|
-
if (!fs.existsSync(configDir)) {
|
|
277
|
-
fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const data = {
|
|
281
|
-
token,
|
|
282
|
-
created_at: new Date().toISOString(),
|
|
283
|
-
expires_at: new Date(Date.now() + 3600000).toISOString() // 1 hour
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
fs.writeFileSync(adminFile, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Load admin token
|
|
291
|
-
*/
|
|
292
|
-
loadAdminToken() {
|
|
293
|
-
const adminFile = path.join(os.homedir(), '.reepoe', 'admin_session.json');
|
|
294
|
-
|
|
295
|
-
if (!fs.existsSync(adminFile)) {
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
const data = JSON.parse(fs.readFileSync(adminFile, 'utf8'));
|
|
301
|
-
|
|
302
|
-
// Check if expired
|
|
303
|
-
const expiresAt = new Date(data.expires_at);
|
|
304
|
-
if (new Date() > expiresAt) {
|
|
305
|
-
fs.unlinkSync(adminFile); // Delete expired token
|
|
306
|
-
return null;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
return data.token;
|
|
310
|
-
} catch (error) {
|
|
311
|
-
return null;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Get machine ID (for device tracking)
|
|
317
|
-
*/
|
|
318
|
-
getMachineId() {
|
|
319
|
-
const crypto = require('crypto');
|
|
320
|
-
const machineInfo = `${os.hostname()}-${os.platform()}-${os.arch()}`;
|
|
321
|
-
return crypto.createHash('sha256').update(machineInfo).digest('hex').substring(0, 16);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
module.exports = ActivationClient;
|
|
326
|
-
|