@cachly-dev/mcp-server 0.10.74 → 0.10.76
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 +34 -0
- package/dist/src/handlers/brain.js +15 -1
- package/dist/src/handlers/brain.js.map +1 -1
- package/dist/src/index.js +29 -4
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/src/index.js
CHANGED
|
@@ -63,7 +63,7 @@ import { Redis } from 'ioredis';
|
|
|
63
63
|
const API_URL = process.env.CACHLY_API_URL ?? 'https://api.cachly.dev';
|
|
64
64
|
let JWT = process.env.CACHLY_JWT ?? '';
|
|
65
65
|
const _EMBED_MODEL = process.env.CACHLY_EMBED_MODEL ?? '';
|
|
66
|
-
const CURRENT_VERSION = '0.10.
|
|
66
|
+
const CURRENT_VERSION = '0.10.76';
|
|
67
67
|
// Max time to wait for a freshly-provisioned instance to become "running" before
|
|
68
68
|
// giving up. Free-tier provisioning in high-latency regions can take 45–90s, so the
|
|
69
69
|
// old hard-coded 25s caused spurious "instance_not_reachable" on first run.
|
|
@@ -2294,9 +2294,17 @@ if (process.argv[2] === 'setup') {
|
|
|
2294
2294
|
const { existsSync } = await import('node:fs');
|
|
2295
2295
|
const { resolve, dirname } = await import('node:path');
|
|
2296
2296
|
const { createInterface } = await import('node:readline');
|
|
2297
|
+
const setupStartMs = Date.now();
|
|
2297
2298
|
sendFunnelEvent('setup_started');
|
|
2298
|
-
// --yes / -y → non-interactive mode (skips all prompts, picks defaults)
|
|
2299
|
-
|
|
2299
|
+
// --yes / -y → non-interactive mode (skips all prompts, picks defaults).
|
|
2300
|
+
// Also auto-detect a non-interactive stdin (VSCode tasks, CI, piped input):
|
|
2301
|
+
// a readline question against a non-TTY stdin never resolves and hangs the
|
|
2302
|
+
// wizard forever. Treat that exactly like --yes so we never block.
|
|
2303
|
+
const stdinIsInteractive = process.stdin.isTTY === true;
|
|
2304
|
+
const nonInteractive = process.argv.includes('--yes') || process.argv.includes('-y') || !stdinIsInteractive;
|
|
2305
|
+
if (!stdinIsInteractive && !process.argv.includes('--yes') && !process.argv.includes('-y')) {
|
|
2306
|
+
console.log('ℹ️ Non-interactive terminal detected — running in automatic mode (no prompts).\n');
|
|
2307
|
+
}
|
|
2300
2308
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2301
2309
|
const ask = (q, defaultVal = '') => {
|
|
2302
2310
|
if (nonInteractive) {
|
|
@@ -2443,6 +2451,17 @@ if (process.argv[2] === 'setup') {
|
|
|
2443
2451
|
execSync(`${openCmd} "${signupUrl}"`, { stdio: 'ignore' });
|
|
2444
2452
|
}
|
|
2445
2453
|
catch { /* can't open browser — instructions shown above */ }
|
|
2454
|
+
// In a non-interactive terminal (VSCode task, CI) we cannot read a pasted
|
|
2455
|
+
// key — exit with clear, actionable instructions instead of hanging.
|
|
2456
|
+
if (nonInteractive) {
|
|
2457
|
+
sendFunnelEvent('device_flow_failed', { reason: 'non_interactive_no_key' });
|
|
2458
|
+
console.error('\n ⚠️ This terminal is non-interactive, so the key cannot be pasted here.');
|
|
2459
|
+
console.error(' Get your key at the URL above, then set it and re-run setup:\n');
|
|
2460
|
+
console.error(' \x1b[1mCACHLY_JWT=cky_live_xxx npx @cachly-dev/mcp-server@latest setup\x1b[0m\n');
|
|
2461
|
+
console.error(' Or add it to your editor\'s MCP config under env.CACHLY_JWT.\n');
|
|
2462
|
+
rl.close();
|
|
2463
|
+
process.exit(1);
|
|
2464
|
+
}
|
|
2446
2465
|
token = await ask(' Paste API key (cky_live_...): ');
|
|
2447
2466
|
if (!token) {
|
|
2448
2467
|
console.error('\nAPI key is required. Aborting.\n');
|
|
@@ -2825,7 +2844,13 @@ if (process.argv[2] === 'setup') {
|
|
|
2825
2844
|
catch { /* non-critical */ }
|
|
2826
2845
|
// Setup reached the end successfully — close the funnel.
|
|
2827
2846
|
JWT = token;
|
|
2828
|
-
|
|
2847
|
+
const setupElapsedS = Math.round((Date.now() - setupStartMs) / 1000);
|
|
2848
|
+
sendFunnelEvent('setup_completed', { instance_id: instance.id, elapsed_s: setupElapsedS });
|
|
2849
|
+
console.log('\n╔══════════════════════════════════════════════════════╗');
|
|
2850
|
+
console.log('║ 🚀 Brain is ready. ║');
|
|
2851
|
+
console.log(`║ ⏱️ Setup completed in ${String(setupElapsedS + 's').padEnd(5)} — restart your editor ║`);
|
|
2852
|
+
console.log('║ and your AI arrives pre-briefed every session. ║');
|
|
2853
|
+
console.log('╚══════════════════════════════════════════════════════╝\n');
|
|
2829
2854
|
rl.close();
|
|
2830
2855
|
// Give the fire-and-forget telemetry a moment to flush before exit.
|
|
2831
2856
|
await new Promise(r => setTimeout(r, 300));
|