@cachly-dev/mcp-server 0.10.227 → 0.10.228
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/src/ambient-hooks.js +1 -1
- package/dist/src/doctor.js +2 -2
- package/glama.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{existsSync as H,readFileSync as R}from"node:fs";import{readFile as j,writeFile as T,chmod as L,mkdir as x}from"node:fs/promises";import{dirname as G,resolve as l}from"node:path";import{fileURLToPath as rt}from"node:url";import{CURSOR_FLAG as nt}from"./cursor-hook.js";import{COPILOT_FLAG as st,COPILOT_HOOK_EVENTS as it}from"./copilot-hook.js";import{CODEX_FLAG as ct,CODEX_HOOK_EVENTS as at}from"./codex-hook.js";import{GEMINI_FLAG as ut,GEMINI_HOOK_EVENTS as mt}from"./gemini-hook.js";import{istCachlyEintrag as M}from"./hook-zugang.js";const v="v5",qt="ambient-recall",S="cachly-ambient-einblendung.mjs";function U(t){return t.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function C(t,o){return["#!/usr/bin/env node",`// cachly Ambient Recall \u2014 ${t} ${v}`,"// Pushes relevant memory into context automatically. Cross-platform Node hook","// (no shell script \u2014 runs identically on Windows/macOS/Linux). Never blocks","// the agent: every failure path exits 0 with no output (graceful degrade).",`// Runs the hook bundle next to this file (${S}) in this process.`,`process.env.CACHLY_BRAIN_INSTANCE_ID = '${U(o.instanceId)}';`,`process.env.CACHLY_HOOK_EVENT = '${U(t)}';`,`process.argv.splice(2, process.argv.length, '${U(t)}');`,"try {",` await import('./${S}');`,"} catch {"," process.exit(0);","}"].join(`
|
|
2
2
|
`)}function K(){const t=G(rt(import.meta.url));for(const o of[l(t,"..",$,S),l(t,"..","..",$,S)])if(H(o))return o;return null}function pt(t){return C("SessionStart",t)}function lt(t){return C("UserPromptSubmit",t)}function St(t){return C("PreToolUse",t)}function ft(t){return C("Stop",t)}const ht={SessionStart:30,UserPromptSubmit:10,PreToolUse:10,Stop:60},dt="Edit|Write|MultiEdit|NotebookEdit";function J(t,o){const e=(r,i,m)=>({...m?{matcher:m}:{},hooks:[{type:"command",command:`node "${i}"${o?` ${o(r)}`:""}`,timeout:ht[r]}]}),s={SessionStart:[e("SessionStart",t.sessionStart)],UserPromptSubmit:[e("UserPromptSubmit",t.userPromptSubmit)]};return t.preToolUse&&(s.PreToolUse=[e("PreToolUse",t.preToolUse,dt)]),t.stop&&(s.Stop=[e("Stop",t.stop)]),s}const B=".claude/hooks",bt=".claude/settings.json",F={SessionStart:"cachly-ambient-session-start.mjs",UserPromptSubmit:"cachly-ambient-prompt-submit.mjs",PreToolUse:"cachly-ambient-pre-tool.mjs",Stop:"cachly-ambient-stop.mjs"},gt=".claude/hooks/cachly-ambient-";function kt(t,o){const e=t.hooks??[];return e.length>0&&e.every(s=>{const r=s.command??"";return r.replace(/\\/g,"/").includes(gt)||o.has(r)||[...o].some(i=>r.includes(`"${i}"`))})}function Ot(t,o){const e={...t,hooks:{...t.hooks??{}}},s=e.hooks,r=J(o),i=new Set([o.sessionStart,o.userPromptSubmit,o.preToolUse,o.stop].filter(c=>!!c));for(const[c,n]of Object.entries(r)){const u=(Array.isArray(s[c])?s[c]:[]).filter(f=>!kt(f,i));s[c]=[...u,...n]}const m=JSON.stringify(e)!==JSON.stringify(t);return{settings:e,changed:m}}async function to(t,o,e,s={}){const r=l(t,B),i={instanceId:o,apiKey:e},m=["SessionStart","UserPromptSubmit","PreToolUse","Stop"],c={SessionStart:pt(i),UserPromptSubmit:lt(i),PreToolUse:St(i),Stop:ft(i)},n=a=>l(r,F[a]),u=K();if(!u)throw new Error(`cachly hook bundle ${S} missing from the package`);const f=R(u,"utf-8"),d=l(r,S),O=async a=>{try{return await j(a,"utf-8")}catch{return""}},E=l(t,bt),_=H(E);let b={};if(_){const a=await O(E);try{const g=a.charCodeAt(0)===65279?a.slice(1):a,P=g.trim()?JSON.parse(g):{};if(!w(P))throw new k("is not a JSON object");if(P.hooks!==void 0&&!w(P.hooks))throw new k('has a "hooks" field that is not an object');b=P}catch(g){const P=g instanceof k?g.message:/^\s*\/\/|\/\*/m.test(a)?"has comments, and cachly only rewrites plain JSON":"is not valid JSON";return{sessionStartPath:n("SessionStart"),promptSubmitPath:n("UserPromptSubmit"),preToolUsePath:n("PreToolUse"),stopPath:n("Stop"),bundlePath:d,scripts:"unchanged",settings:"skipped",grund:P}}}let p=!1,h=await O(d)===f;for(const a of m){const g=await O(n(a));g&&(p=!0),g!==c[a]+`
|
|
3
3
|
`&&(h=!1)}const D=h?"unchanged":p?"upgraded":"written";if(D!=="unchanged"){await x(r,{recursive:!0}),await T(d,f,"utf-8");for(const a of m)await T(n(a),c[a]+`
|
|
4
|
-
`,"utf-8"),await L(n(a),493).catch(()=>{})}const I=a=>s.portable
|
|
4
|
+
`,"utf-8"),await L(n(a),493).catch(()=>{})}const I=a=>s.portable!==!1?`\${CLAUDE_PROJECT_DIR}/${B}/${F[a]}`:n(a),{settings:ot,changed:et}=Ot(b,{sessionStart:I("SessionStart"),userPromptSubmit:I("UserPromptSubmit"),preToolUse:I("PreToolUse"),stop:I("Stop")});let y;return _?et?y="merged":y="unchanged":y="written",y!=="unchanged"&&(await x(l(t,".claude"),{recursive:!0}),await T(E,JSON.stringify(ot,null,2)+`
|
|
5
5
|
`,"utf-8")),{sessionStartPath:n("SessionStart"),promptSubmitPath:n("UserPromptSubmit"),preToolUsePath:n("PreToolUse"),stopPath:n("Stop"),bundlePath:d,scripts:D,settings:y}}const V=".cursor/hooks",Pt=".cursor/hooks.json",X="cachly-ambient-cursor.mjs",Tt={sessionStart:30,beforeSubmitPrompt:10,postToolUse:5};function N(t,o,e,s){return["#!/usr/bin/env node",`// cachly Ambient Recall \u2014 ${t} ${v}`,`// Einblendung fuer ${t}: ${e.join(", ")}.`,"// Blockiert nie: jeder Fehler endet mit Exit 0. Ruft das Buendel daneben",`// (${S}) in diesem Prozess.`,`process.env.CACHLY_BRAIN_INSTANCE_ID = '${U(s.instanceId)}';`,`process.argv.push('${o}');`,"try {",` await import('./${S}');`,"} catch {"," process.exit(0);","}"].join(`
|
|
6
6
|
`)}function _t(t){return N("Cursor",nt,["sessionStart","beforeSubmitPrompt","postToolUse"],t)}function yt(){const t=o=>[{command:`node ${V}/${X} ${o}`,timeout:Tt[o]}];return{sessionStart:t("sessionStart"),beforeSubmitPrompt:t("beforeSubmitPrompt"),postToolUse:t("postToolUse")}}function Et(t){return z(t,yt())}function z(t,o){const e={...t.hooks??{}};for(const[r,i]of Object.entries(o)){W(e[r],r);const m=(e[r]??[]).filter(c=>!M(c));e[r]=[...m,...i]}const s={...t,version:typeof t.version=="number"?t.version:1,hooks:e};return{datei:s,changed:JSON.stringify(s)!==JSON.stringify(t)}}function Y(t,o){const e={...t.hooks??{}};for(const[r,i]of Object.entries(o)){W(e[r],r);const m=(e[r]??[]).flatMap(c=>{const n=c?.hooks;if(!Array.isArray(n))return[c];const u=n.filter(f=>!M(f));return u.length===n.length?[c]:u.length?[{...c,hooks:u}]:[]});e[r]=[...m,...i]}const s={...t,hooks:e};return{datei:s,changed:JSON.stringify(s)!==JSON.stringify(t)}}async function A(t){const o=l(t.projectDir,t.hookDir),e=K();if(!e)throw new Error(`cachly hook bundle ${S} missing from the package`);const s=R(e,"utf-8"),r=l(o,S),i=l(o,t.skriptName),m=t.skript+`
|
|
7
7
|
`,c=async p=>{try{return await j(p,"utf-8")}catch{return""}},n=l(t.projectDir,t.configDatei),u=H(n)?await c(n):"",f=!u.trim();let d;try{const p=u.charCodeAt(0)===65279?u.slice(1):u,h=f?{}:JSON.parse(p);if(!w(h))throw new k("is not a JSON object");if(h.hooks!==void 0&&!w(h.hooks))throw new k('has a "hooks" field that is not an object');d=t.merge(h,i)}catch(p){const h=p instanceof k?p.message:/^\s*\/\/|\/\*/m.test(u)?"has comments, and cachly only rewrites plain JSON":"is not valid JSON";return{scriptPath:i,bundlePath:r,hooksPath:n,scripts:"unchanged",hooks:"skipped",grund:h}}await x(o,{recursive:!0});const O=await c(i),_=O===m&&await c(r)===s?"unchanged":O?"upgraded":"written";_!=="unchanged"&&(await T(r,s,"utf-8"),await T(i,m,"utf-8"),await L(i,493).catch(()=>{}));let b;if(f?b="written":d.changed?b="merged":b="unchanged",b!=="unchanged"){const p=/^([ \t]+)"/m.exec(u)?.[1]??2;await x(G(n),{recursive:!0}),await T(n,JSON.stringify(d.datei,null,p)+`
|
package/dist/src/doctor.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{existsSync as a,readFileSync as u}from"node:fs";import{resolve as d}from"node:path";import{AMBIENT_HOOK_VERSION as h}from"./ambient-hooks.js";import{netBalance as y}from"./ambient-recall.js";import{cachlyUrl as b}from"./cachly-url.js";const g=18;function N(e=process.version){const t=Number(e.replace(/^v/,"").split(".")[0]);return Number.isFinite(t)&&t>=g?{name:"Node.js",status:"ok",detail:`${e}`}:{name:"Node.js",status:"fail",detail:`${e} \u2014 too old`,hint:`cachly needs Node ${g}+ (built-in fetch). Install a current LTS from nodejs.org.`}}function R(e){if(!e)return{name:"Credential",status:"fail",detail:"CACHLY_JWT is not set",hint:"Run `npx @cachly-dev/mcp-server@latest autopilot` (browser sign-in) or export CACHLY_JWT=<cky_\u2026>."};const t=e.startsWith("cky_"),n=e.split(".").length===3;return!t&&!n?{name:"Credential",status:"warn",detail:"CACHLY_JWT is set but looks neither like a cky_\u2026 key nor a JWT",hint:"Re-copy the key from the dashboard (API Keys) \u2014 it may be truncated."}:{name:"Credential",status:"ok",detail:t?"API key (cky_\u2026)":"JWT"}}async function P(e,t=fetch){try{const n=await t(`${e}/health`,{signal:AbortSignal.timeout(5e3)});return n.ok?{name:"API",status:"ok",detail:`${e} reachable`}:{name:"API",status:"fail",detail:`${e}/health returned HTTP ${n.status}`,hint:`The API answered but is unhealthy \u2014 check ${b("/status","doctor")} or your CACHLY_API_URL.`}}catch{return{name:"API",status:"fail",detail:`${e} not reachable`,hint:"Check your network/proxy. Self-hosted: is CACHLY_API_URL correct and the API running?"}}}async function j(e,t,n=fetch){if(!t)return{name:"Auth",status:"fail",detail:"skipped \u2014 no credential",hint:"Fix the Credential check first."};try{const o=await n(`${e}/api/v1/instances`,{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(5e3)});return o.ok?{name:"Auth",status:"ok",detail:"credential accepted"}:o.status===401||o.status===403?{name:"Auth",status:"fail",detail:`API rejected the credential (HTTP ${o.status})`,hint:"The key is expired or revoked. Create a new one in the dashboard, or re-run autopilot."}:{name:"Auth",status:"warn",detail:`unexpected HTTP ${o.status} from /api/v1/instances`}}catch{return{name:"Auth",status:"warn",detail:"could not verify (network error)"}}}async function S(e,t,n,o=fetch){if(!t||!n)return{name:"Vektoren",status:"warn",detail:"skipped \u2014 no credential or instance"};try{const s=await o(`${e}/api/v1/instances/${n}/vector-coverage`,{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(12e3)});if(!s.ok)return{name:"Vektoren",status:"warn",detail:`coverage not measured (HTTP ${s.status})`};const r=await s.json();return r.status==="leer"?{name:"Vektoren",status:"ok",detail:"no lessons yet"}:r.status==="nicht-gemessen"?{name:"Vektoren",status:"warn",detail:"instance not running \u2014 not measured"}:r.status==="aus"?{name:"Vektoren",status:"fail",detail:`semantic search is OFF: ${r.lessons} lessons, 0 vectors`,hint:"Embeddings never ran for this instance. Check the embed provider; recall runs word-only until fixed."}:r.status==="luecke"?{name:"Vektoren",status:"warn",detail:`${r.vectors}/${r.lessons} lessons have vectors (${r.percent.toFixed(0)}%)`,hint:"Some lessons are invisible to semantic search. Large writes under the rate limit can skip embedding."}:{name:"Vektoren",status:"ok",detail:`${r.vectors}/${r.lessons} vectors (${r.percent.toFixed(0)}%)`}}catch{return{name:"Vektoren",status:"warn",detail:"could not verify (network error)"}}}function L(e){return e?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)?{name:"Instance",status:"ok",detail:e.slice(0,8)+"\u2026"}:{name:"Instance",status:"warn",detail:`"${e.slice(0,24)}" does not look like an instance UUID`,hint:"Copy the instance ID from the dashboard (Instances \u2192 your brain)."}:{name:"Instance",status:"warn",detail:"no CACHLY_BRAIN_INSTANCE_ID set and no default instance resolved",hint:"Run `npx @cachly-dev/mcp-server@latest init` in your project, or export CACHLY_BRAIN_INSTANCE_ID."}}const v=[{editor:"cursor",konfig:".cursor/hooks.json",buendel:".cursor/hooks/cachly-ambient-einblendung.mjs"},{editor:"copilot",konfig:".github/hooks/cachly-ambient.json",buendel:".github/hooks/cachly-ambient-einblendung.mjs"},{editor:"codex",konfig:".codex/hooks.json",buendel:".codex/hooks/cachly-ambient-einblendung.mjs"},{editor:"gemini",konfig:".gemini/settings.json",buendel:".gemini/hooks/cachly-ambient-einblendung.mjs"}];function O(e){const t={settingsExists:!1,wiredEvents:[],scriptFiles:[],editorHooks:[]};for(const n of v)try{const o=d(e,n.konfig);a(o)&&u(o,"utf-8").includes("cachly-ambient")&&a(d(e,n.buendel))&&t.editorHooks.push(n.editor)}catch{}try{const n=d(e,".claude/settings.json");if(t.settingsExists=a(n),t.settingsExists){const o=JSON.parse(u(n,"utf-8"));for(const[s,r]of Object.entries(o.hooks??{})){const m=i=>(i??"").replace(/\\/g,"/");if((r??[]).some(i=>(i.hooks??[]).some(c=>m(c.command).includes(".claude/hooks/cachly-ambient-")))){t.wiredEvents.push(s);for(const i of r??[])for(const c of i.hooks??[]){const f=m(c.command).match(/["']?([^"']*\.claude\/hooks\/cachly-ambient-[^"']+)["']?/);if(!f)continue;const l=f[1].replace(
|
|
2
|
-
`)}function
|
|
1
|
+
import{existsSync as a,readFileSync as u}from"node:fs";import{resolve as d}from"node:path";import{AMBIENT_HOOK_VERSION as h}from"./ambient-hooks.js";import{netBalance as y}from"./ambient-recall.js";import{cachlyUrl as b}from"./cachly-url.js";const g=18;function N(e=process.version){const t=Number(e.replace(/^v/,"").split(".")[0]);return Number.isFinite(t)&&t>=g?{name:"Node.js",status:"ok",detail:`${e}`}:{name:"Node.js",status:"fail",detail:`${e} \u2014 too old`,hint:`cachly needs Node ${g}+ (built-in fetch). Install a current LTS from nodejs.org.`}}function R(e){if(!e)return{name:"Credential",status:"fail",detail:"CACHLY_JWT is not set",hint:"Run `npx @cachly-dev/mcp-server@latest autopilot` (browser sign-in) or export CACHLY_JWT=<cky_\u2026>."};const t=e.startsWith("cky_"),n=e.split(".").length===3;return!t&&!n?{name:"Credential",status:"warn",detail:"CACHLY_JWT is set but looks neither like a cky_\u2026 key nor a JWT",hint:"Re-copy the key from the dashboard (API Keys) \u2014 it may be truncated."}:{name:"Credential",status:"ok",detail:t?"API key (cky_\u2026)":"JWT"}}async function P(e,t=fetch){try{const n=await t(`${e}/health`,{signal:AbortSignal.timeout(5e3)});return n.ok?{name:"API",status:"ok",detail:`${e} reachable`}:{name:"API",status:"fail",detail:`${e}/health returned HTTP ${n.status}`,hint:`The API answered but is unhealthy \u2014 check ${b("/status","doctor")} or your CACHLY_API_URL.`}}catch{return{name:"API",status:"fail",detail:`${e} not reachable`,hint:"Check your network/proxy. Self-hosted: is CACHLY_API_URL correct and the API running?"}}}async function j(e,t,n=fetch){if(!t)return{name:"Auth",status:"fail",detail:"skipped \u2014 no credential",hint:"Fix the Credential check first."};try{const o=await n(`${e}/api/v1/instances`,{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(5e3)});return o.ok?{name:"Auth",status:"ok",detail:"credential accepted"}:o.status===401||o.status===403?{name:"Auth",status:"fail",detail:`API rejected the credential (HTTP ${o.status})`,hint:"The key is expired or revoked. Create a new one in the dashboard, or re-run autopilot."}:{name:"Auth",status:"warn",detail:`unexpected HTTP ${o.status} from /api/v1/instances`}}catch{return{name:"Auth",status:"warn",detail:"could not verify (network error)"}}}async function S(e,t,n,o=fetch){if(!t||!n)return{name:"Vektoren",status:"warn",detail:"skipped \u2014 no credential or instance"};try{const s=await o(`${e}/api/v1/instances/${n}/vector-coverage`,{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(12e3)});if(!s.ok)return{name:"Vektoren",status:"warn",detail:`coverage not measured (HTTP ${s.status})`};const r=await s.json();return r.status==="leer"?{name:"Vektoren",status:"ok",detail:"no lessons yet"}:r.status==="nicht-gemessen"?{name:"Vektoren",status:"warn",detail:"instance not running \u2014 not measured"}:r.status==="aus"?{name:"Vektoren",status:"fail",detail:`semantic search is OFF: ${r.lessons} lessons, 0 vectors`,hint:"Embeddings never ran for this instance. Check the embed provider; recall runs word-only until fixed."}:r.status==="luecke"?{name:"Vektoren",status:"warn",detail:`${r.vectors}/${r.lessons} lessons have vectors (${r.percent.toFixed(0)}%)`,hint:"Some lessons are invisible to semantic search. Large writes under the rate limit can skip embedding."}:{name:"Vektoren",status:"ok",detail:`${r.vectors}/${r.lessons} vectors (${r.percent.toFixed(0)}%)`}}catch{return{name:"Vektoren",status:"warn",detail:"could not verify (network error)"}}}function L(e){return e?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)?{name:"Instance",status:"ok",detail:e.slice(0,8)+"\u2026"}:{name:"Instance",status:"warn",detail:`"${e.slice(0,24)}" does not look like an instance UUID`,hint:"Copy the instance ID from the dashboard (Instances \u2192 your brain)."}:{name:"Instance",status:"warn",detail:"no CACHLY_BRAIN_INSTANCE_ID set and no default instance resolved",hint:"Run `npx @cachly-dev/mcp-server@latest init` in your project, or export CACHLY_BRAIN_INSTANCE_ID."}}const v=[{editor:"cursor",konfig:".cursor/hooks.json",buendel:".cursor/hooks/cachly-ambient-einblendung.mjs"},{editor:"copilot",konfig:".github/hooks/cachly-ambient.json",buendel:".github/hooks/cachly-ambient-einblendung.mjs"},{editor:"codex",konfig:".codex/hooks.json",buendel:".codex/hooks/cachly-ambient-einblendung.mjs"},{editor:"gemini",konfig:".gemini/settings.json",buendel:".gemini/hooks/cachly-ambient-einblendung.mjs"}];function O(e){const t={settingsExists:!1,wiredEvents:[],scriptFiles:[],editorHooks:[]};for(const n of v)try{const o=d(e,n.konfig);a(o)&&u(o,"utf-8").includes("cachly-ambient")&&a(d(e,n.buendel))&&t.editorHooks.push(n.editor)}catch{}try{const n=d(e,".claude/settings.json");if(t.settingsExists=a(n),t.settingsExists){const o=JSON.parse(u(n,"utf-8"));for(const[s,r]of Object.entries(o.hooks??{})){const m=i=>(i??"").replace(/\\/g,"/");if((r??[]).some(i=>(i.hooks??[]).some(c=>m(c.command).includes(".claude/hooks/cachly-ambient-")))){t.wiredEvents.push(s);for(const i of r??[])for(const c of i.hooks??[]){const f=m(c.command).match(/["']?([^"']*\.claude\/hooks\/cachly-ambient-[^"']+)["']?/);if(!f)continue;const l=f[1].replace(/\$\{CLAUDE_PROJECT_DIR\}|\$CLAUDE_PROJECT_DIR/,e),k=a(l);let p="unknown";if(k)try{p=u(l,"utf-8").includes(h)?"current":"stale"}catch{}t.scriptFiles.push({path:l,exists:k,version:p})}}}}}catch{}return t}const $=["SessionStart","UserPromptSubmit","PreToolUse","Stop"];function F(e){if(!e.settingsExists||e.wiredEvents.length===0){const s=e.editorHooks??[];return s.length>0?{name:"Hooks",status:"ok",detail:`Ambient Recall hooks wired for ${s.join(", ")}`}:{name:"Hooks",status:"warn",detail:"Ambient Recall hooks are not installed in this project",hint:"Run `npx @cachly-dev/mcp-server@latest init` here (add `--editor cursor|copilot|codex|gemini` if you do not use Claude Code) \u2014 memory then injects itself (no hooks = pull-only)."}}const t=$.filter(s=>!e.wiredEvents.includes(s)),n=e.scriptFiles.filter(s=>!s.exists),o=e.scriptFiles.filter(s=>s.exists&&s.version==="stale");return n.length>0?{name:"Hooks",status:"fail",detail:`settings.json wires hooks whose script files are missing (${n.length})`,hint:"Re-run `npx @cachly-dev/mcp-server@latest init` to rewrite the scripts."}:o.length>0?{name:"Hooks",status:"warn",detail:`installed hooks are an older version (current: ${h}); v1/v2 shell hooks never ran on native Windows`,hint:"Re-run `npx @cachly-dev/mcp-server@latest init` to upgrade in place."}:t.length>0?{name:"Hooks",status:"warn",detail:`partial install \u2014 missing events: ${t.join(", ")}`,hint:"Re-run `npx @cachly-dev/mcp-server@latest init` to add the missing hooks."}:{name:"Hooks",status:"ok",detail:`all 4 events wired, scripts ${h}`}}function V(e,t){const n=y(e);return e.length===0?{name:"Ledger",status:"ok",detail:`empty (${t}) \u2014 fills up once ambient hooks inject`}:{name:"Ledger",status:"ok",detail:`${e.length} entries, net ${n.net>=0?"+":""}${n.net} tokens`}}const A={ok:"\u2705",warn:"\u26A0\uFE0F ",fail:"\u274C"};function J(e){const t=["","\u{1FA7A} cachly doctor",""];for(const s of e)t.push(` ${A[s.status]} ${s.name.padEnd(11)} ${s.detail}`),s.hint&&s.status!=="ok"&&t.push(` \u21B3 ${s.hint}`);const n=e.filter(s=>s.status==="fail").length,o=e.filter(s=>s.status==="warn").length;return t.push(""),t.push(n>0?` ${n} problem${n>1?"s":""} to fix${o?`, ${o} warning${o>1?"s":""}`:""}.`:o>0?` No blockers \u2014 ${o} warning${o>1?"s":""}.`:" Everything looks healthy. Your brain is wired."),t.push(""),t.join(`
|
|
2
|
+
`)}function D(e){return e.some(t=>t.status==="fail")?1:0}export{P as checkApiReachable,j as checkAuthAccepted,R as checkCredential,F as checkHooks,L as checkInstance,V as checkLedger,N as checkNodeVersion,S as checkVectorCoverage,D as doctorExitCode,O as inspectAmbientHooks,J as renderDoctorReport};
|
package/glama.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cachly-dev/mcp-server",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.228",
|
|
4
4
|
"mcpName": "io.github.cachly-dev/mcp-server",
|
|
5
5
|
"description": "Solve it once. From then on, your AI knows. Experience for coding agents, EU-hosted: an MCP server for Claude Code, Cursor, Copilot & Windsurf. Learns from every bug fix, commit and CI run.",
|
|
6
6
|
"type": "module",
|
package/server.json
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
"url": "https://github.com/cachly-dev/cachly-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.10.
|
|
9
|
+
"version": "0.10.228",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"name": "@cachly-dev/mcp-server",
|
|
14
14
|
"identifier": "@cachly-dev/mcp-server",
|
|
15
|
-
"version": "0.10.
|
|
15
|
+
"version": "0.10.228",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
}
|