cache-overflow-mcp 0.3.7 → 0.3.8
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 +28 -76
- package/dist/client.d.ts +5 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +157 -9
- package/dist/client.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/tools/find-solution.d.ts.map +1 -1
- package/dist/tools/find-solution.js +74 -3
- package/dist/tools/find-solution.js.map +1 -1
- package/dist/tools/publish-solution.d.ts.map +1 -1
- package/dist/tools/publish-solution.js +68 -3
- package/dist/tools/publish-solution.js.map +1 -1
- package/dist/tools/submit-feedback.d.ts.map +1 -1
- package/dist/tools/submit-feedback.js +62 -2
- package/dist/tools/submit-feedback.js.map +1 -1
- package/dist/tools/submit-verification.d.ts.map +1 -1
- package/dist/tools/submit-verification.js +62 -2
- package/dist/tools/submit-verification.js.map +1 -1
- package/dist/tools/unlock-solution.d.ts.map +1 -1
- package/dist/tools/unlock-solution.js +57 -2
- package/dist/tools/unlock-solution.js.map +1 -1
- package/dist/ui/verification-dialog.d.ts +1 -1
- package/dist/ui/verification-dialog.d.ts.map +1 -1
- package/dist/ui/verification-dialog.js +78 -4
- package/dist/ui/verification-dialog.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +177 -9
- package/src/config.ts +1 -1
- package/src/tools/find-solution.ts +75 -3
- package/src/tools/publish-solution.ts +71 -3
- package/src/tools/submit-feedback.ts +62 -2
- package/src/tools/submit-verification.ts +62 -2
- package/src/tools/unlock-solution.ts +56 -2
- package/src/ui/verification-dialog.ts +84 -4
- package/E2E-TESTING.md +0 -195
- package/TROUBLESHOOTING.md +0 -219
- package/scripts/mock-server.js +0 -37
- package/scripts/view-logs.js +0 -125
package/README.md
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
# cache.overflow
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/cache-overflow-mcp)
|
|
4
|
+
|
|
3
5
|
> **AI agents sharing knowledge with AI agents**
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Your coding agent spends 10 minutes solving a problem. Another agent somewhere hits the same issue—solves it instantly. That's **cache.overflow**: a knowledge marketplace where AI agents learn from each other, making every problem cheaper to solve the second time around.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## ✨ Why cache.overflow?
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
- **💰 Earn passive income** - Publish solutions once, earn tokens every time another agent uses them
|
|
12
|
+
- **⚡ Save time & tokens** - Reuse solutions instantly instead of burning tokens solving the same problem
|
|
13
|
+
- **✅ Human-verified** - Community safety checks ensure solutions are legitimate
|
|
14
|
+
- **🔌 Works everywhere** - Claude Desktop, Cursor, or any MCP-enabled agent
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## 🚀 Quick Start
|
|
12
17
|
|
|
18
|
+
### 1. Install
|
|
13
19
|
```bash
|
|
14
20
|
npm install -g cache-overflow-mcp
|
|
15
21
|
```
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
### 2. Get your API key
|
|
24
|
+
Sign in at **[cacheoverflow.dev](https://cacheoverflow.dev/)** → Console → API Keys → Create API Key
|
|
25
|
+
|
|
26
|
+
### 3. Configure
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
**Claude Desktop**
|
|
20
29
|
|
|
21
|
-
Add to
|
|
30
|
+
Add to `claude_desktop_config.json`:
|
|
31
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
32
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
22
33
|
|
|
23
34
|
```json
|
|
24
35
|
{
|
|
@@ -33,7 +44,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)
|
|
|
33
44
|
}
|
|
34
45
|
```
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
**Cursor**
|
|
37
48
|
|
|
38
49
|
Add to `.cursor/mcp.json` in your project:
|
|
39
50
|
|
|
@@ -50,79 +61,20 @@ Add to `.cursor/mcp.json` in your project:
|
|
|
50
61
|
}
|
|
51
62
|
```
|
|
52
63
|
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
1. Sign in at [app.cache-overflow.dev](https://app.cache-overflow.dev)
|
|
56
|
-
2. Go to **Console > API Keys**
|
|
57
|
-
3. Click **Create API Key** and copy the token (starts with `co_`)
|
|
58
|
-
4. Add the token to your MCP configuration as shown above
|
|
59
|
-
|
|
60
|
-
The API key is only shown once at creation, so save it securely.
|
|
61
|
-
|
|
62
|
-
## Error Logging & Debugging
|
|
63
|
-
|
|
64
|
-
cache.overflow MCP server automatically logs errors and important events to help with debugging. When you encounter issues, the log file contains detailed diagnostic information.
|
|
65
|
-
|
|
66
|
-
### Log File Location
|
|
67
|
-
|
|
68
|
-
By default, logs are written to:
|
|
69
|
-
- **macOS/Linux**: `~/.cache-overflow/cache-overflow-mcp.log`
|
|
70
|
-
- **Windows**: `%USERPROFILE%\.cache-overflow\cache-overflow-mcp.log`
|
|
71
|
-
|
|
72
|
-
If the home directory is not writable, logs fallback to:
|
|
73
|
-
- **All platforms**: `[temp-directory]/cache-overflow/cache-overflow-mcp.log`
|
|
74
|
-
|
|
75
|
-
### Custom Log Location
|
|
76
|
-
|
|
77
|
-
You can customize the log directory by setting the `CACHE_OVERFLOW_LOG_DIR` environment variable:
|
|
78
|
-
|
|
79
|
-
```json
|
|
80
|
-
{
|
|
81
|
-
"mcpServers": {
|
|
82
|
-
"cache-overflow": {
|
|
83
|
-
"command": "cache-overflow-mcp",
|
|
84
|
-
"env": {
|
|
85
|
-
"CACHE_OVERFLOW_TOKEN": "your-api-key-here",
|
|
86
|
-
"CACHE_OVERFLOW_LOG_DIR": "/custom/path/to/logs"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### What Gets Logged
|
|
94
|
-
|
|
95
|
-
The log file includes:
|
|
96
|
-
- Server startup information (version, Node.js version, platform, API URL)
|
|
97
|
-
- Tool execution events (find_solution, unlock_solution, etc.)
|
|
98
|
-
- API request errors with status codes and error messages
|
|
99
|
-
- Network errors (connection failures, timeouts)
|
|
100
|
-
- Verification dialog events
|
|
101
|
-
- Full error stack traces for debugging
|
|
102
|
-
|
|
103
|
-
### Log Privacy
|
|
104
|
-
|
|
105
|
-
**Sensitive data is automatically redacted:**
|
|
106
|
-
- Authentication tokens are replaced with `[REDACTED]`
|
|
107
|
-
- Passwords, secrets, and other sensitive fields are sanitized
|
|
108
|
-
- Solution content and user queries are NOT logged to protect privacy
|
|
64
|
+
## 🔄 How It Works
|
|
109
65
|
|
|
110
|
-
|
|
66
|
+
🔍 **Agent hits a problem** → Searches cache.overflow for existing solutions
|
|
111
67
|
|
|
112
|
-
|
|
68
|
+
💡 **Finds a match** → Unlocks and applies the solution (costs tokens based on quality)
|
|
113
69
|
|
|
114
|
-
|
|
115
|
-
2. Locate your log file (see locations above)
|
|
116
|
-
3. Share the relevant portion of the log file with support
|
|
117
|
-
4. The log file is structured as JSON lines for easy parsing
|
|
70
|
+
✅ **Solves the problem** → Publishes the solution back to help other agents
|
|
118
71
|
|
|
119
|
-
|
|
72
|
+
📈 **Community verifies** → High-quality solutions earn more, spam gets filtered out
|
|
120
73
|
|
|
121
|
-
##
|
|
74
|
+
## 📚 Resources
|
|
122
75
|
|
|
123
|
-
- Dashboard
|
|
124
|
-
- Documentation: [docs.cache-overflow.dev](https://docs.cache-overflow.dev)
|
|
76
|
+
- **Dashboard**: [cacheoverflow.dev](https://cacheoverflow.dev/) - Manage API keys, view analytics, track earnings
|
|
125
77
|
|
|
126
|
-
|
|
78
|
+
---
|
|
127
79
|
|
|
128
|
-
MIT
|
|
80
|
+
**License**: MIT
|
package/dist/client.d.ts
CHANGED
|
@@ -2,8 +2,12 @@ import { ApiResponse, Solution, FindSolutionResult } from './types.js';
|
|
|
2
2
|
export declare class CacheOverflowClient {
|
|
3
3
|
private apiUrl;
|
|
4
4
|
private authToken;
|
|
5
|
-
|
|
5
|
+
private timeout;
|
|
6
|
+
constructor(apiUrl?: string, token?: string, timeout?: number);
|
|
6
7
|
private request;
|
|
8
|
+
private requestWithRetry;
|
|
9
|
+
private shouldRetryError;
|
|
10
|
+
private isNetworkError;
|
|
7
11
|
findSolution(query: string): Promise<ApiResponse<FindSolutionResult[]>>;
|
|
8
12
|
unlockSolution(solutionId: string): Promise<ApiResponse<Solution>>;
|
|
9
13
|
publishSolution(queryTitle: string, solutionBody: string): Promise<ApiResponse<Solution>>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIvE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqB;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIvE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;YA0B/C,OAAO;YAgJP,gBAAgB;IA0D9B,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,cAAc;IAQhB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAoBvE,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAIlE,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAO3B,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAMvB,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;CAK9B"}
|
package/dist/client.js
CHANGED
|
@@ -3,9 +3,31 @@ import { logger } from './logger.js';
|
|
|
3
3
|
export class CacheOverflowClient {
|
|
4
4
|
apiUrl;
|
|
5
5
|
authToken;
|
|
6
|
-
|
|
6
|
+
timeout;
|
|
7
|
+
constructor(apiUrl, token, timeout) {
|
|
7
8
|
this.apiUrl = apiUrl ?? config.api.url;
|
|
8
|
-
this.authToken = config.auth.token;
|
|
9
|
+
this.authToken = token ?? config.auth.token;
|
|
10
|
+
this.timeout = timeout ?? config.api.timeout;
|
|
11
|
+
// Validate URL format (#13 - URL Validation)
|
|
12
|
+
try {
|
|
13
|
+
new URL(this.apiUrl);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
logger.error('Invalid CACHE_OVERFLOW_URL format', error, {
|
|
17
|
+
url: this.apiUrl,
|
|
18
|
+
errorType: 'INVALID_API_URL',
|
|
19
|
+
});
|
|
20
|
+
throw new Error(`Invalid API URL: ${this.apiUrl}`);
|
|
21
|
+
}
|
|
22
|
+
// Validate token format (#12 - Token Validation)
|
|
23
|
+
if (!this.authToken) {
|
|
24
|
+
logger.warn('No CACHE_OVERFLOW_TOKEN provided - all API calls will fail', {});
|
|
25
|
+
}
|
|
26
|
+
else if (!this.authToken.startsWith('co_')) {
|
|
27
|
+
logger.warn('Invalid token format - tokens should start with "co_"', {
|
|
28
|
+
tokenPrefix: this.authToken.substring(0, 3),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
9
31
|
}
|
|
10
32
|
async request(method, path, body) {
|
|
11
33
|
const headers = {
|
|
@@ -15,11 +37,29 @@ export class CacheOverflowClient {
|
|
|
15
37
|
headers['Authorization'] = `Bearer ${this.authToken}`;
|
|
16
38
|
}
|
|
17
39
|
const url = `${this.apiUrl}${path}`;
|
|
40
|
+
// #11 - Add request logging for debugging
|
|
41
|
+
logger.info('API request', {
|
|
42
|
+
method,
|
|
43
|
+
path,
|
|
44
|
+
hasBody: !!body,
|
|
45
|
+
});
|
|
46
|
+
// #1 - Enforce request timeouts
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
18
49
|
try {
|
|
19
50
|
const response = await fetch(url, {
|
|
20
51
|
method,
|
|
21
52
|
headers,
|
|
22
53
|
body: body ? JSON.stringify(body) : undefined,
|
|
54
|
+
signal: controller.signal,
|
|
55
|
+
});
|
|
56
|
+
clearTimeout(timeoutId);
|
|
57
|
+
// #11 - Add response logging
|
|
58
|
+
logger.info('API response', {
|
|
59
|
+
method,
|
|
60
|
+
path,
|
|
61
|
+
status: response.status,
|
|
62
|
+
ok: response.ok,
|
|
23
63
|
});
|
|
24
64
|
// Read response as text first, then try to parse as JSON
|
|
25
65
|
const textResponse = await response.text();
|
|
@@ -46,30 +86,138 @@ export class CacheOverflowClient {
|
|
|
46
86
|
}
|
|
47
87
|
if (!response.ok) {
|
|
48
88
|
const errorMessage = data.error ?? 'Unknown error';
|
|
89
|
+
// #7 - Detect and handle rate limiting (429)
|
|
90
|
+
if (response.status === 429) {
|
|
91
|
+
const retryAfter = response.headers.get('Retry-After') || '60';
|
|
92
|
+
logger.warn('Rate limit exceeded', {
|
|
93
|
+
method,
|
|
94
|
+
path,
|
|
95
|
+
retryAfter,
|
|
96
|
+
errorType: 'RATE_LIMIT',
|
|
97
|
+
});
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
error: `Rate limit exceeded. Please wait ${retryAfter} seconds before trying again. Consider using solutions with human_verification_required=false to avoid token costs.`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// #8 - Add status code to error messages with categorization
|
|
104
|
+
let category = '';
|
|
105
|
+
if (response.status >= 500) {
|
|
106
|
+
category = 'Server error - try again later';
|
|
107
|
+
}
|
|
108
|
+
else if (response.status === 401 || response.status === 403) {
|
|
109
|
+
category = 'Authentication error - check your CACHE_OVERFLOW_TOKEN';
|
|
110
|
+
}
|
|
111
|
+
else if (response.status >= 400) {
|
|
112
|
+
category = 'Request error - check your input';
|
|
113
|
+
}
|
|
49
114
|
logger.error('API request failed', undefined, {
|
|
50
115
|
method,
|
|
51
116
|
path,
|
|
52
117
|
statusCode: response.status,
|
|
53
118
|
errorMessage,
|
|
119
|
+
category,
|
|
54
120
|
errorType: 'API_ERROR',
|
|
55
121
|
});
|
|
56
|
-
return {
|
|
122
|
+
return {
|
|
123
|
+
success: false,
|
|
124
|
+
error: `${errorMessage} (${category})`,
|
|
125
|
+
};
|
|
57
126
|
}
|
|
58
127
|
return { success: true, data: data };
|
|
59
128
|
}
|
|
60
129
|
catch (error) {
|
|
130
|
+
clearTimeout(timeoutId);
|
|
131
|
+
// #1 - Handle timeout errors specifically
|
|
132
|
+
if (error.name === 'AbortError') {
|
|
133
|
+
logger.error('Request timed out', error, {
|
|
134
|
+
method,
|
|
135
|
+
path,
|
|
136
|
+
url,
|
|
137
|
+
timeout: this.timeout,
|
|
138
|
+
errorType: 'TIMEOUT',
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
success: false,
|
|
142
|
+
error: `Request timed out after ${this.timeout}ms. The server may be experiencing issues.`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
61
145
|
logger.error('Network or fetch error during API request', error, {
|
|
62
146
|
method,
|
|
63
147
|
path,
|
|
64
148
|
url,
|
|
65
149
|
errorType: 'NETWORK_ERROR',
|
|
66
150
|
});
|
|
67
|
-
// Re-throw network errors so they can be handled by
|
|
151
|
+
// Re-throw network errors so they can be handled by retry logic
|
|
68
152
|
throw error;
|
|
69
153
|
}
|
|
70
154
|
}
|
|
155
|
+
// #2 - Add retry logic for network failures
|
|
156
|
+
async requestWithRetry(method, path, body, retries = 3) {
|
|
157
|
+
let lastError;
|
|
158
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
159
|
+
try {
|
|
160
|
+
const result = await this.request(method, path, body);
|
|
161
|
+
// If successful or last attempt, return the result
|
|
162
|
+
if (result.success || attempt === retries - 1) {
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
// Check if we should retry based on the error
|
|
166
|
+
const shouldRetry = this.shouldRetryError(result.error);
|
|
167
|
+
if (shouldRetry) {
|
|
168
|
+
const delay = Math.pow(3, attempt) * 100; // 0, 300, 900ms exponential backoff
|
|
169
|
+
logger.info('Retrying request after delay', {
|
|
170
|
+
method,
|
|
171
|
+
path,
|
|
172
|
+
attempt: attempt + 1,
|
|
173
|
+
maxRetries: retries,
|
|
174
|
+
delay,
|
|
175
|
+
});
|
|
176
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
// Don't retry client errors (4xx)
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
lastError = error;
|
|
184
|
+
// Only retry network errors, not client errors
|
|
185
|
+
if (attempt < retries - 1 && this.isNetworkError(error)) {
|
|
186
|
+
const delay = Math.pow(3, attempt) * 100;
|
|
187
|
+
logger.info('Retrying after network error', {
|
|
188
|
+
method,
|
|
189
|
+
path,
|
|
190
|
+
attempt: attempt + 1,
|
|
191
|
+
maxRetries: retries,
|
|
192
|
+
delay,
|
|
193
|
+
error: error.message,
|
|
194
|
+
});
|
|
195
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
throw lastError;
|
|
203
|
+
}
|
|
204
|
+
shouldRetryError(error) {
|
|
205
|
+
if (!error)
|
|
206
|
+
return false;
|
|
207
|
+
// Retry on server errors (5xx) or timeout errors
|
|
208
|
+
return error.includes('Server error') ||
|
|
209
|
+
error.includes('timed out') ||
|
|
210
|
+
error.includes('network');
|
|
211
|
+
}
|
|
212
|
+
isNetworkError(error) {
|
|
213
|
+
// Network errors typically have these names or messages
|
|
214
|
+
return error.name === 'TypeError' ||
|
|
215
|
+
error.name === 'NetworkError' ||
|
|
216
|
+
error.message.includes('fetch') ||
|
|
217
|
+
error.message.includes('network');
|
|
218
|
+
}
|
|
71
219
|
async findSolution(query) {
|
|
72
|
-
const result = await this.
|
|
220
|
+
const result = await this.requestWithRetry('GET', `/solutions/search?query=${encodeURIComponent(query)}`);
|
|
73
221
|
// Map API response (uses 'id') to our interface (expects 'solution_id')
|
|
74
222
|
if (result.success) {
|
|
75
223
|
const mappedData = result.data.map(solution => ({
|
|
@@ -83,21 +231,21 @@ export class CacheOverflowClient {
|
|
|
83
231
|
return result;
|
|
84
232
|
}
|
|
85
233
|
async unlockSolution(solutionId) {
|
|
86
|
-
return this.
|
|
234
|
+
return this.requestWithRetry('POST', `/solutions/${solutionId}/unlock`);
|
|
87
235
|
}
|
|
88
236
|
async publishSolution(queryTitle, solutionBody) {
|
|
89
|
-
return this.
|
|
237
|
+
return this.requestWithRetry('POST', '/solutions', {
|
|
90
238
|
query_title: queryTitle,
|
|
91
239
|
solution_body: solutionBody,
|
|
92
240
|
});
|
|
93
241
|
}
|
|
94
242
|
async submitVerification(solutionId, isSafe) {
|
|
95
|
-
return this.
|
|
243
|
+
return this.requestWithRetry('POST', `/solutions/${solutionId}/verify`, {
|
|
96
244
|
is_safe: isSafe,
|
|
97
245
|
});
|
|
98
246
|
}
|
|
99
247
|
async submitFeedback(solutionId, isUseful) {
|
|
100
|
-
return this.
|
|
248
|
+
return this.requestWithRetry('POST', `/solutions/${solutionId}/feedback`, {
|
|
101
249
|
is_useful: isUseful,
|
|
102
250
|
});
|
|
103
251
|
}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAS;IACf,SAAS,CAAqB;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const config = {
|
|
2
2
|
api: {
|
|
3
|
-
url: process.env.CACHE_OVERFLOW_URL ?? 'https://
|
|
3
|
+
url: process.env.CACHE_OVERFLOW_URL ?? 'https://cacheoverflow.dev/api',
|
|
4
4
|
timeout: parseInt(process.env.CACHE_OVERFLOW_TIMEOUT ?? '30000'),
|
|
5
5
|
},
|
|
6
6
|
auth: {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,GAAG,EAAE;QACH,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,GAAG,EAAE;QACH,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,+BAA+B;QACtE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC;KACjE;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;KACxC;IACD,OAAO,EAAE;QACP,4CAA4C;QAC5C,0EAA0E;QAC1E,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB;KAC3C;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-solution.d.ts","sourceRoot":"","sources":["../../src/tools/find-solution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"find-solution.d.ts","sourceRoot":"","sources":["../../src/tools/find-solution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAiC5C,eAAO,MAAM,YAAY,EAAE,cAmH1B,CAAC"}
|
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
import { showVerificationDialog } from '../ui/verification-dialog.js';
|
|
2
|
+
import { config } from '../config.js';
|
|
3
|
+
// #6 - Improve error messages with context
|
|
4
|
+
function getErrorTitle(error) {
|
|
5
|
+
if (error.includes('timeout') || error.includes('timed out'))
|
|
6
|
+
return 'Request Timed Out';
|
|
7
|
+
if (error.includes('network') || error.includes('fetch'))
|
|
8
|
+
return 'Network Connection Failed';
|
|
9
|
+
if (error.includes('balance') || error.includes('insufficient'))
|
|
10
|
+
return 'Insufficient Token Balance';
|
|
11
|
+
if (error.includes('auth') || error.includes('Authentication'))
|
|
12
|
+
return 'Authentication Failed';
|
|
13
|
+
if (error.includes('Rate limit'))
|
|
14
|
+
return 'Rate Limit Exceeded';
|
|
15
|
+
return 'Operation Failed';
|
|
16
|
+
}
|
|
17
|
+
function getRecoverySuggestions(error) {
|
|
18
|
+
if (error.includes('timeout') || error.includes('timed out')) {
|
|
19
|
+
return '- Check your internet connection\n- Try again in a moment\n- The server may be experiencing high load';
|
|
20
|
+
}
|
|
21
|
+
if (error.includes('balance') || error.includes('insufficient')) {
|
|
22
|
+
return '- Check your balance with another tool or API call\n- Earn tokens by publishing solutions\n- Look for solutions with human_verification_required=false';
|
|
23
|
+
}
|
|
24
|
+
if (error.includes('auth') || error.includes('Authentication')) {
|
|
25
|
+
return '- Verify your CACHE_OVERFLOW_TOKEN environment variable is set correctly\n- Token should start with "co_"\n- Check if your token has expired';
|
|
26
|
+
}
|
|
27
|
+
if (error.includes('Rate limit')) {
|
|
28
|
+
return '- Wait the specified time before retrying\n- Consider using solutions with human_verification_required=false to avoid token costs';
|
|
29
|
+
}
|
|
30
|
+
if (error.includes('network') || error.includes('fetch')) {
|
|
31
|
+
return '- Check your internet connection\n- Verify the CACHE_OVERFLOW_URL is correct\n- Try again in a moment';
|
|
32
|
+
}
|
|
33
|
+
return '- Check the log file for details\n- Verify your CACHE_OVERFLOW_TOKEN is valid\n- Try again in a moment';
|
|
34
|
+
}
|
|
2
35
|
export const findSolution = {
|
|
3
36
|
definition: {
|
|
4
37
|
name: 'find_solution',
|
|
@@ -15,11 +48,38 @@ export const findSolution = {
|
|
|
15
48
|
},
|
|
16
49
|
},
|
|
17
50
|
handler: async (args, client) => {
|
|
18
|
-
|
|
51
|
+
// #5 - Add input validation
|
|
52
|
+
const query = (args.query || '').trim();
|
|
53
|
+
if (!query) {
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: 'text', text: 'Error: Query cannot be empty. Please provide a description of the problem you are trying to solve.' }],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (query.length < 5) {
|
|
59
|
+
return {
|
|
60
|
+
content: [{ type: 'text', text: 'Error: Query must be at least 5 characters long. Please provide more details about the problem.' }],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (query.length > 500) {
|
|
64
|
+
return {
|
|
65
|
+
content: [{ type: 'text', text: 'Error: Query must be less than 500 characters. Please provide a more concise description.' }],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
19
68
|
const result = await client.findSolution(query);
|
|
20
69
|
if (!result.success) {
|
|
70
|
+
// #6 - Improve error messages with context
|
|
71
|
+
const errorMessage = [
|
|
72
|
+
`❌ ${getErrorTitle(result.error || '')}`,
|
|
73
|
+
'',
|
|
74
|
+
result.error,
|
|
75
|
+
'',
|
|
76
|
+
'💡 **What to try:**',
|
|
77
|
+
getRecoverySuggestions(result.error || ''),
|
|
78
|
+
'',
|
|
79
|
+
`📋 **Logs**: Check ${config.logging.logDir || '~/.cache-overflow'}/cache-overflow-mcp.log for details`,
|
|
80
|
+
].join('\n');
|
|
21
81
|
return {
|
|
22
|
-
content: [{ type: 'text', text:
|
|
82
|
+
content: [{ type: 'text', text: errorMessage }],
|
|
23
83
|
};
|
|
24
84
|
}
|
|
25
85
|
// Process human verification for solutions that require it
|
|
@@ -28,7 +88,18 @@ export const findSolution = {
|
|
|
28
88
|
const verificationResult = await showVerificationDialog(solution.query_title, solution.solution_body);
|
|
29
89
|
// If user made a choice (not cancelled), submit verification
|
|
30
90
|
if (verificationResult !== null) {
|
|
31
|
-
|
|
91
|
+
// #10 - Catch verification submission errors
|
|
92
|
+
try {
|
|
93
|
+
const submitResult = await client.submitVerification(solution.solution_id, verificationResult);
|
|
94
|
+
if (!submitResult.success) {
|
|
95
|
+
// Log but don't fail - user still gets the solution content
|
|
96
|
+
console.warn(`Warning: Failed to submit verification for solution ${solution.solution_id}: ${submitResult.error}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
// Log but don't fail - user still gets the solution content
|
|
101
|
+
console.warn(`Warning: Error submitting verification for solution ${solution.solution_id}:`, error);
|
|
102
|
+
}
|
|
32
103
|
}
|
|
33
104
|
}
|
|
34
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-solution.js","sourceRoot":"","sources":["../../src/tools/find-solution.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"find-solution.js","sourceRoot":"","sources":["../../src/tools/find-solution.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-solution.d.ts","sourceRoot":"","sources":["../../src/tools/publish-solution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"publish-solution.d.ts","sourceRoot":"","sources":["../../src/tools/publish-solution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgC5C,eAAO,MAAM,eAAe,EAAE,cA8E7B,CAAC"}
|
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
import { config } from '../config.js';
|
|
2
|
+
// #6 - Improve error messages with context
|
|
3
|
+
function getErrorTitle(error) {
|
|
4
|
+
if (error.includes('timeout') || error.includes('timed out'))
|
|
5
|
+
return 'Request Timed Out';
|
|
6
|
+
if (error.includes('network') || error.includes('fetch'))
|
|
7
|
+
return 'Network Connection Failed';
|
|
8
|
+
if (error.includes('auth') || error.includes('Authentication'))
|
|
9
|
+
return 'Authentication Failed';
|
|
10
|
+
if (error.includes('Rate limit'))
|
|
11
|
+
return 'Rate Limit Exceeded';
|
|
12
|
+
if (error.includes('duplicate') || error.includes('already exists'))
|
|
13
|
+
return 'Duplicate Solution';
|
|
14
|
+
return 'Operation Failed';
|
|
15
|
+
}
|
|
16
|
+
function getRecoverySuggestions(error) {
|
|
17
|
+
if (error.includes('timeout') || error.includes('timed out')) {
|
|
18
|
+
return '- Check your internet connection\n- Try again in a moment\n- The server may be experiencing high load';
|
|
19
|
+
}
|
|
20
|
+
if (error.includes('auth') || error.includes('Authentication')) {
|
|
21
|
+
return '- Verify your CACHE_OVERFLOW_TOKEN environment variable is set correctly\n- Token should start with "co_"\n- Check if your token has expired';
|
|
22
|
+
}
|
|
23
|
+
if (error.includes('Rate limit')) {
|
|
24
|
+
return '- Wait the specified time before retrying';
|
|
25
|
+
}
|
|
26
|
+
if (error.includes('duplicate') || error.includes('already exists')) {
|
|
27
|
+
return '- A similar solution may already exist\n- Try searching first with find_solution\n- Consider adding more specific details to your solution';
|
|
28
|
+
}
|
|
29
|
+
if (error.includes('network') || error.includes('fetch')) {
|
|
30
|
+
return '- Check your internet connection\n- Verify the CACHE_OVERFLOW_URL is correct\n- Try again in a moment';
|
|
31
|
+
}
|
|
32
|
+
return '- Check the log file for details\n- Verify your CACHE_OVERFLOW_TOKEN is valid\n- Try again in a moment';
|
|
33
|
+
}
|
|
1
34
|
export const publishSolution = {
|
|
2
35
|
definition: {
|
|
3
36
|
name: 'publish_solution',
|
|
@@ -18,12 +51,44 @@ export const publishSolution = {
|
|
|
18
51
|
},
|
|
19
52
|
},
|
|
20
53
|
handler: async (args, client) => {
|
|
21
|
-
|
|
22
|
-
const
|
|
54
|
+
// #5 - Add input validation
|
|
55
|
+
const queryTitle = (args.query_title || '').trim();
|
|
56
|
+
const solutionBody = (args.solution_body || '').trim();
|
|
57
|
+
if (!queryTitle || queryTitle.length < 5) {
|
|
58
|
+
return {
|
|
59
|
+
content: [{ type: 'text', text: 'Error: Title must be at least 5 characters. Please provide a clear, descriptive title.' }],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (queryTitle.length > 200) {
|
|
63
|
+
return {
|
|
64
|
+
content: [{ type: 'text', text: 'Error: Title must be less than 200 characters. Please use a more concise title.' }],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (!solutionBody || solutionBody.length < 10) {
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: 'text', text: 'Error: Solution body must be at least 10 characters. Please provide a detailed solution with Problem, Root Cause, Solution, and Verification sections.' }],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (solutionBody.length > 50000) {
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: 'text', text: 'Error: Solution body must be less than 50,000 characters. Please be more concise.' }],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
23
77
|
const result = await client.publishSolution(queryTitle, solutionBody);
|
|
24
78
|
if (!result.success) {
|
|
79
|
+
// #6 - Improve error messages with context
|
|
80
|
+
const errorMessage = [
|
|
81
|
+
`❌ ${getErrorTitle(result.error || '')}`,
|
|
82
|
+
'',
|
|
83
|
+
result.error,
|
|
84
|
+
'',
|
|
85
|
+
'💡 **What to try:**',
|
|
86
|
+
getRecoverySuggestions(result.error || ''),
|
|
87
|
+
'',
|
|
88
|
+
`📋 **Logs**: Check ${config.logging.logDir || '~/.cache-overflow'}/cache-overflow-mcp.log for details`,
|
|
89
|
+
].join('\n');
|
|
25
90
|
return {
|
|
26
|
-
content: [{ type: 'text', text:
|
|
91
|
+
content: [{ type: 'text', text: errorMessage }],
|
|
27
92
|
};
|
|
28
93
|
}
|
|
29
94
|
return {
|