@cachly-dev/mcp-server 0.10.224 → 0.10.225
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 +4 -3
- package/dist/src/handlers/advanced.js +1 -1
- package/dist/src/handlers/brain.js +56 -56
- package/dist/src/handlers/team.js +1 -1
- package/dist/src/projektdateien.js +10 -4
- package/dist/src/uninstall.js +4 -4
- package/dist/src/wirkungsspur.js +1 -1
- package/glama.json +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -67,7 +67,8 @@ npx @cachly-dev/mcp-server@latest autopilot
|
|
|
67
67
|
`autopilot` finds the editors you use and writes the MCP config for each. It also writes
|
|
68
68
|
the rule file each editor reads in every chat (`CLAUDE.md`, `AGENTS.md`,
|
|
69
69
|
`.cursor/rules/cachly.mdc`, `.github/copilot-instructions.md`, `.windsurfrules`,
|
|
70
|
-
`.clinerules`
|
|
70
|
+
`.clinerules`; `GEMINI.md`, `.junie/guidelines.md` and `.continue/rules/cachly.md` where
|
|
71
|
+
you use Gemini CLI, Junie or Continue), which tells your AI to check its memory before a task. It adds a git
|
|
71
72
|
hook that learns from your commits and fills your Brain from your git history. You sign
|
|
72
73
|
in once in the browser (a device code, no password, no credit card), so the Brain
|
|
73
74
|
belongs to your own account from the start. Restart your editor afterwards.
|
|
@@ -75,8 +76,8 @@ belongs to your own account from the start. Restart your editor afterwards.
|
|
|
75
76
|
You can also add the server by hand (see [Manual Setup](#manual-setup)). Without a key,
|
|
76
77
|
the first tool call creates the same test Brain as in Claude Code. Without a rule file,
|
|
77
78
|
Claude Code still starts each task with `smart_recall`, because the server's instructions
|
|
78
|
-
ask for it.
|
|
79
|
-
there, the rule file from `autopilot` is what makes your AI use its memory.
|
|
79
|
+
ask for it. Gemini CLI also passes them on. Some editors do not (Cline, Continue and Zed,
|
|
80
|
+
for example); there, the rule file from `autopilot` is what makes your AI use its memory.
|
|
80
81
|
|
|
81
82
|
> **Already inside Claude, Cursor or Copilot?** Paste this to your AI:
|
|
82
83
|
> ```
|
|
@@ -3,7 +3,7 @@ import{ckgSlug as j}from"../ckg.js";import{safeJsonParse as x,darfHeraus as N}fr
|
|
|
3
3
|
`)}case"causal_trace":{const{instance_id:l,problem:g,max_depth:$=5,tags:m=[]}=S,w=await W(l,L,`\u{1F50D} **Causal Trace: "${g}"**
|
|
4
4
|
|
|
5
5
|
No matching lessons found in brain.`);if(w)return w;const d=await M(l),u=g.toLowerCase().replace(/[^a-z0-9\s\-_:]/g," ").split(/\s+/).filter(o=>o.length>2),_={critical:"\u{1F534}",major:"\u{1F7E0}",minor:"\u{1F7E1}"},c=[];try{for(const o of u.slice(0,4)){const a=await d.smembers(`cachly:ckg:idx:from:${j(o)}`),r=await d.smembers(`cachly:ckg:idx:to:${j(o)}`),p=[],n=d.scanStream({match:`cachly:ckg:node:*${o}*`,count:50});await new Promise((e,s)=>{n.on("data",i=>p.push(...i)),n.on("end",e),n.on("error",s)});for(const e of p.slice(0,10)){const s=await d.get(e);if(!s)continue;const i=x(s,null);if(!i)continue;const D=await d.smembers(`cachly:ckg:idx:from:${i.id}`);for(const T of D.slice(0,20)){const R=await d.get(T);if(!R)continue;const C=x(R,null);if(!C||C.edgeType!=="fixes"&&C.edgeType!=="requires")continue;const I=await d.get(`cachly:lesson:best:${C.from.replace(/-/g,":").replace(/^fix:/,"fix:")}`),E=I?x(I,null)??void 0:void 0;c.push({conceptId:i.id,edge:C,lesson:E&&B(E)?E:void 0})}}for(const e of[...a,...r].slice(0,20)){const s=await d.get(e);if(!s)continue;const i=x(s,null);if(!i)continue;const D=await d.get(`cachly:lesson:best:${i.from}`),T=D?x(D,null)??void 0:void 0;c.push({conceptId:i.from,edge:i,lesson:T&&B(T)?T:void 0})}}}catch{}const y=new Set,f=c.filter(o=>{const a=`${o.edge.from}:${o.edge.edgeType}:${o.edge.to}`;return y.has(a)?!1:(y.add(a),!0)}).sort((o,a)=>a.edge.confidence-o.edge.confidence).slice(0,$);let k=0;const b=[];do{const[o,a]=await d.scan(k,"MATCH","cachly:lesson:best:*","COUNT",200);k=parseInt(o),b.push(...a)}while(k!==0);const h=[];for(const o of b){const a=await d.get(o);if(a){const r=x(a,null);if(!r||!B(r)||m.length>0&&!(r.tags??[]).some(e=>m.includes(e)))continue;const p=[r.topic,r.what_failed??"",r.what_worked??"",r.context??""].join(" ").toLowerCase(),n=u.reduce((e,s)=>e+(p.includes(s)?1:0),0);n>0&&h.push({score:n,lesson:r,key:o})}}h.sort((o,a)=>a.score-o.score);const v=h.slice(0,$);if(v.length===0&&f.length===0)return[`\u{1F50D} **Causal Trace: "${g}"**`,"","No matching lessons found in brain.","","\u{1F4A1} After you solve this, call:","```","learn_from_attempts(",` instance_id = "${l}",`,` topic = "fix:${u[0]??"issue"}",`,' outcome = "success",',' what_worked = "...",',` what_failed = "${g}",`,")","```"].join(`
|
|
6
|
-
`);const t=[`\u{1F50D} **Causal Trace: "${g}"**`,""];if(f.length>0){t.push("### \u{1F578}\uFE0F CKG Graph (confidence-ranked)");for(const o of f){const a=Math.round(o.edge.confidence*100),r="\u2593".repeat(Math.round(a/10))+"\u2591".repeat(10-Math.round(a/10));t.push(` ${o.edge.from} **\u2192[${o.edge.edgeType}]\u2192** ${o.edge.to}`),t.push(` ${r} ${a}% confidence (${o.edge.successes}/${o.edge.trials} confirmed)`),o.lesson?.what_worked&&t.push(` \u2705 Fix: ${o.lesson.what_worked.slice(0,150)}`),t.push("")}}if(v.length>0){t.push(f.length>0?`### \u{1F4DA} Text Search (${v.length} related lessons)`:`Found **${v.length}** related lessons. Reconstructed causal chain:`,"");const o=v.filter(p=>p.lesson.outcome!=="success"),a=v.filter(p=>p.lesson.outcome==="success");o.length>0&&(t.push("**Root causes & failure chain:**"),o.forEach((p,n)=>{const e=p.lesson,s=_[e.severity??"minor"]??"\u{1F7E1}";t.push(`${n===0?" Root:":" \u2192 :"} ${s} \`${e.topic}\``),e.what_failed&&t.push(` \u21B3 ${e.what_failed.slice(0,120)}`)}),t.push("")),a.length>0&&(t.push("**Solutions that worked before:**"),a.forEach((p,n)=>{const e=p.lesson,s=new Date(e.ts).toLocaleDateString("de-DE");t.push(` ${n+1}. \u2705 \`${e.topic}\` \u2014 ${s} \xB7
|
|
6
|
+
`);const t=[`\u{1F50D} **Causal Trace: "${g}"**`,""];if(f.length>0){t.push("### \u{1F578}\uFE0F CKG Graph (confidence-ranked)");for(const o of f){const a=Math.round(o.edge.confidence*100),r="\u2593".repeat(Math.round(a/10))+"\u2591".repeat(10-Math.round(a/10));t.push(` ${o.edge.from} **\u2192[${o.edge.edgeType}]\u2192** ${o.edge.to}`),t.push(` ${r} ${a}% confidence (${o.edge.successes}/${o.edge.trials} confirmed)`),o.lesson?.what_worked&&t.push(` \u2705 Fix: ${o.lesson.what_worked.slice(0,150)}`),t.push("")}}if(v.length>0){t.push(f.length>0?`### \u{1F4DA} Text Search (${v.length} related lessons)`:`Found **${v.length}** related lessons. Reconstructed causal chain:`,"");const o=v.filter(p=>p.lesson.outcome!=="success"),a=v.filter(p=>p.lesson.outcome==="success");o.length>0&&(t.push("**Root causes & failure chain:**"),o.forEach((p,n)=>{const e=p.lesson,s=_[e.severity??"minor"]??"\u{1F7E1}";t.push(`${n===0?" Root:":" \u2192 :"} ${s} \`${e.topic}\``),e.what_failed&&t.push(` \u21B3 ${e.what_failed.slice(0,120)}`)}),t.push("")),a.length>0&&(t.push("**Solutions that worked before:**"),a.forEach((p,n)=>{const e=p.lesson,s=new Date(e.ts).toLocaleDateString("de-DE");t.push(` ${n+1}. \u2705 \`${e.topic}\` \u2014 ${s} \xB7 in ${e.recall_count??0} answers`),e.what_worked&&t.push(` ${e.what_worked.slice(0,200)}`)}),t.push(""));const r=a[0]?.lesson;if(r?.what_worked){t.push("**\u26A1 Most likely fix:**"),t.push("```"),t.push(r.what_worked.slice(0,500)),t.push("```"),t.push("");const p=F(r)?P(r,"trace"):0;p>0&&d.incrbyfloat(`cachly:stats:time_saved_mins:${l}`,p).catch(()=>{})}}return t.push(`\u{1F4A1} After applying: \`learn_from_attempts(topic="fix:${u[0]??"issue"}", outcome="success", ...)\``),f.length>0&&t.push(`\u{1F578}\uFE0F Explore graph: \`ckg_inspect(concept="${u[0]??"fix"}")\``),t.join(`
|
|
7
7
|
`)}case"knowledge_decay":{let f=function(t){const o=Math.round(t/10);return"\u2588".repeat(o)+"\u2591".repeat(10-o)+` ${t}%`};const{instance_id:l,min_age_days:g=0,show_top:$=20}=S,m=await M(l),w=Date.now(),d=g*864e5;let u=0;const _=[];do{const[t,o]=await m.scan(u,"MATCH","cachly:lesson:best:*","COUNT",200);u=parseInt(t),_.push(...o)}while(u!==0);const c=[];for(const t of _){const o=await m.get(t);if(o){const a=x(o,null);if(!a)continue;const r=w-new Date(a.ts).getTime();if(r<d)continue;const p=Math.floor(r/864e5),n=a.recall_count??0,e=Math.max(0,p-7),s=Math.max(5,100-e),i=Math.min(50,n*5),D=a.outcome==="failure"?-20:0,T=Math.min(100,Math.max(0,s+i+D));c.push({topic:a.topic,confidence:T,age_days:p,recalls:n,outcome:a.outcome})}}c.sort((t,o)=>t.confidence-o.confidence);const y=c.slice(0,$),k=c.length>0?Math.round(c.reduce((t,o)=>t+o.confidence,0)/c.length):0,b=c.filter(t=>t.confidence<30).length,h=c.filter(t=>t.confidence>=70).length;return[`\u{1F9EA} **Knowledge Decay Report** \u2014 ${c.length} lessons`,"",`Average confidence: **${f(k)}**`,`\u{1F534} Critical (<30%): ${b} \u{1F7E2} Healthy (\u226570%): ${h}`,"","Lowest confidence lessons (fix these first):","",...y.map((t,o)=>`${(o+1).toString().padStart(2)}. \`${t.topic}\`
|
|
8
8
|
${f(t.confidence)} \xB7 ${t.age_days}d old \xB7 ${t.recalls} recalls \xB7 ${t.outcome}`),"",c.length>$?`\u2026 and ${c.length-$} more lessons`:"","",b>0?`\u26A0\uFE0F ${b} lessons are critically stale. Validate them and re-run \`learn_from_attempts\` with updated findings.`:"\u2705 Brain confidence is healthy overall.","","\u{1F4A1} Run `memory_consolidate` to prune stale entries \xB7 `causal_trace` to find root causes."].filter(t=>t!=="").join(`
|
|
9
9
|
`)}case"autopilot":{const{instance_id:l,editor:g="claude",project_name:$="this project",style:m="full"}=S,w=z({editor:String(g),project_name:String($)},"die Anweisungsdatei (CLAUDE.md)");if(!w.ok)return w.meldung;const d=(b,h)=>b.replace(/[\p{C}\s]+/gu," ").trim().slice(0,h),u=d(w.felder.editor,30)||"claude",_=d(w.felder.project_name,80)||"this project",c=`## Cachly AI Brain \u2014 Autopilot
|