@cachly-dev/mcp-server 0.10.187 → 0.10.190

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.
@@ -1,19 +1,19 @@
1
- import{safeJsonParse as j}from"../utils.js";import{STARTER_CORPUS as k,STARTER_CORPUS_SIZE as x}from"../starter-corpus.js";import{cachlyUrl as T}from"../cachly-url.js";import{VEKTOR_NACHTRAG as R}from"../bedeutung.js";const q=new Set(["brain_share","brain_import","brain_share_list","brain_unshare","brain_discover","brain_seed_starter"]);async function I(v,w){const y=[],$=v.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((s,h)=>{$.on("data",e=>y.push(...e)),$.on("end",s),$.on("error",h)});const o=[];for(const s of y.slice(0,500)){const h=await v.get(s);if(!h)continue;const e=j(h,null);!e||!e.topic||w&&w.length>0&&!w.some(a=>e.topic.includes(a))||o.push({topic:e.topic,outcome:e.outcome,...e.what_worked?{what_worked:e.what_worked}:{},...e.what_failed?{what_failed:e.what_failed}:{},...e.ctx?{ctx:e.ctx}:{},...e.tags?.length?{tags:e.tags}:{},...e.author?{author:e.author}:{},...e.service?{service:e.service}:{},confidence:e.confidence??1,ts:e.ts})}return o}async function J(v,w,y,$){switch(v){case"brain_share":{const{instance_id:o,title:s="My Brain Snapshot",description:h="",topic_filter:e,visibility:t="unlisted",max_lessons:a=100,dry_run:r=!1}=w;if(!o)return"\u26A0\uFE0F `brain_share` requires `instance_id`.";const l=await y(o),c=Array.isArray(e)&&e.length>0?e:void 0,i=(await I(l,c)).slice(0,a);if(i.length===0)return["\u{1F4E4} **brain_share** \u2014 nothing to share yet","",`No lessons found in Brain \`${o}\`${c?` matching topics: ${c.join(", ")}`:""}.`,"",'Store lessons first with `learn_from_attempts(topic="...", what_worked="...")`.'].join(`
2
- `);if(r){const u=i.slice(0,5).map(p=>` ${p.outcome==="success"?"\u2705":p.outcome==="failure"?"\u274C":"\u26A0\uFE0F"} \`${p.topic}\` \u2014 ${(p.what_worked??p.what_failed??"").slice(0,80)}`);return[`\u{1F4E4} **brain_share (DRY RUN)** \u2014 would share ${i.length} lesson${i.length!==1?"s":""}`,"",`**Title:** ${s}`,`**Visibility:** ${t}`,c?`**Topic filter:** ${c.join(", ")}`:"","","**Sample lessons (first 5):**",...u,i.length>5?` _...and ${i.length-5} more_`:"","","_Remove `dry_run=true` to create the public share._"].filter(p=>p!=="").join(`
3
- `)}let n=null,d=null;try{n=(await $("/api/v1/brains/share",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:s,description:h,visibility:t,lessons:i})})).share_id??null,n&&(d=T(`/brain/share/${n}`,"brain-share"))}catch(u){const p=u.message??"";if(p.includes("404")||p.includes("not found")||p.includes("ECONNREFUSED")){const m=JSON.stringify({title:s,description:h,visibility:t,lessons:i,exported_at:new Date().toISOString()},null,2);return[`\u{1F4E4} **brain_share** \u2014 exported ${i.length} lesson${i.length!==1?"s":""}`,"","\u26A0\uFE0F The public share API is not yet available. Here is your portable snapshot:","","```json",m.slice(0,3e3)+(m.length>3e3?`
4
- ... (truncated)`:""),"```","","_To import this on another Brain, use `brain_import` with the JSON payload._"].join(`
5
- `)}return`\u274C brain_share failed: ${u.message}`}const b=i.slice(0,5).map(u=>` ${u.outcome==="success"?"\u2705":u.outcome==="failure"?"\u274C":"\u26A0\uFE0F"} \`${u.topic}\``);try{const u=JSON.stringify({share_id:n,title:s,visibility:t,lesson_count:i.length,created_at:new Date().toISOString()});await l.rpush("cachly:brain:shares",u),await l.ltrim("cachly:brain:shares",-20,-1)}catch{}return[`\u{1F4E4} **brain_share** \u2014 ${i.length} lesson${i.length!==1?"s":""} shared`,"",`**Share ID:** \`${n}\``,`**URL:** ${d}`,`**Title:** ${s}`,`**Visible:** ${t}`,"","**Sample lessons:**",...b,i.length>5?` _...and ${i.length-5} more_`:"","","**Anyone can import this Brain with:**",`\`brain_import(instance_id="<their-id>", share_id="${n}")\``,"","_To list all your shares, run `brain_share_list`._"].filter(u=>u!=="").join(`
6
- `)}case"brain_import":{const{instance_id:o,share_id:s,topic_prefix:h="",min_confidence:e=0,dry_run:t=!1,overwrite:a=!1}=w;if(!o)return"\u26A0\uFE0F `brain_import` requires `instance_id`.";if(!s)return"\u26A0\uFE0F `brain_import` requires `share_id`. Get one from `brain_share`.";const r=s.replace(/^.*\/brain\/share\//,"").trim();let l;try{l=await $(`/api/v1/brains/share/${r}`)}catch(f){const g=f.message??"";return g.includes("404")||g.includes("not found")?["\u274C **brain_import** \u2014 share not found","",`Share ID \`${r}\` does not exist or has been removed.`,"","Ask the Brain owner to re-run `brain_share` and share the new ID with you."].join(`
7
- `):`\u274C brain_import failed: ${f.message}`}const c=l.lessons??[];if(c.length===0)return`\u26A0\uFE0F Share \`${r}\` exists but contains no lessons.`;const _=await y(o);let i=0,n=0,d=0;const b=[];for(const f of c){if((f.confidence??1)<e){n++;continue}const g=h?`${h}:${f.topic}`:f.topic,N=`cachly:lesson:best:${g}`;if(!a&&await _.get(N)){d++;continue}const O=JSON.stringify({...f,topic:g,imported_from:r,imported_at:new Date().toISOString()});if(!t){await _.set(N,O);const S=`cachly:lessons:${g}`;await _.rpush(S,O),await _.ltrim(S,-100,-1),await _.expire(S,90*86400)}if(i++,b.length<6){const S=f.outcome==="success"?"\u2705":f.outcome==="failure"?"\u274C":"\u26A0\uFE0F";b.push(` ${S} \`${g}\` \u2014 ${(f.what_worked??f.what_failed??"").slice(0,80)}`)}}if(!t&&i>0)try{const f=JSON.stringify({share_id:r,title:l.title,imported:i,skipped:n,conflicts:d,topic_prefix:h,imported_at:new Date().toISOString()});await _.rpush("cachly:brain:imports",f),await _.ltrim("cachly:brain:imports",-20,-1)}catch{}const u=t?" (DRY RUN \u2014 no writes)":"",p=l.title??r,m=[`\u{1F4E5} **brain_import${u}** \u2014 from "${p}"`,"",`**Share ID:** \`${r}\``,`**Lessons imported:** ${i}`,...n>0?[`**Skipped (low confidence):** ${n}`]:[],...d>0?[`**Skipped (already exist):** ${d} _(pass \`overwrite=true\` to replace)_`]:[],""];return b.length>0&&(m.push("**Sample lessons imported:**",...b),i>6&&m.push(` _...and ${i-6} more_`)),i>0&&!t?m.push("",'\u2705 Brain updated \u2014 use `smart_recall(query="...")` to query the new knowledge.'):t?m.push("","_Remove `dry_run=true` to actually import these lessons._"):i===0&&d>0&&m.push("","\u2139\uFE0F All lessons already exist in your Brain. Pass `overwrite=true` to update them."),m.join(`
8
- `)}case"brain_share_list":{const{instance_id:o}=w;if(!o)return"\u26A0\uFE0F `brain_share_list` requires `instance_id`.";const s=await y(o);let h=[];try{h=(await s.lrange("cachly:brain:shares",0,-1)).map(c=>{try{return JSON.parse(c)}catch{return null}}).filter(Boolean)}catch{}let e=[];try{e=(await $("/api/v1/brains/share")).shares??[]}catch{}const t=e.length>0?e:h;if(t.length===0)return["\u{1F4E4} **brain_share_list** \u2014 no shares yet","","You haven't shared any Brain snapshots from this instance.","",`Create one with: \`brain_share(instance_id="${o}", title="My Patterns")\``].join(`
9
- `);const a=[`\u{1F4E4} **Your Brain Shares** (${t.length})`,"","| # | Title | Lessons | Visibility | Created |","|---|-------|---------|------------|---------|"];for(const[l,c]of t.entries()){const _=new Date(c.created_at),i=isNaN(_.getTime())?c.created_at:_.toISOString().slice(0,10),n=c.visibility==="public"?"\u{1F310} public":"\u{1F517} unlisted";a.push(`| ${l+1} | ${c.title??"\u2014"} | ${c.lesson_count??"?"} | ${n} | ${i} |`)}const r=t[t.length-1];return a.push("",`**Import command:** \`brain_import(instance_id="<their-id>", share_id="${r?.share_id??"..."}")\``,`**Revoke:** \`brain_unshare(instance_id="${o}", share_id="<id>")\``),a.join(`
10
- `)}case"brain_unshare":{const{instance_id:o,share_id:s}=w;if(!o)return"\u26A0\uFE0F `brain_unshare` requires `instance_id`.";if(!s)return"\u26A0\uFE0F `brain_unshare` requires `share_id`.";try{await $(`/api/v1/brains/share/${s}`,{method:"DELETE"})}catch(e){const t=e.message??"";if(t.includes("404")||t.includes("not found"))return`\u274C Share \`${s}\` not found \u2014 it may have already been removed.`;if(t.includes("ECONNREFUSED")||t.includes("fetch failed")){const a=await y(o);try{const l=(await a.lrange("cachly:brain:shares",0,-1)).filter(c=>{try{return JSON.parse(c).share_id!==s}catch{return!0}});await a.del("cachly:brain:shares");for(const c of l)await a.rpush("cachly:brain:shares",c)}catch{}return["\u26A0\uFE0F **brain_unshare** \u2014 removed from local log","",`API unreachable \u2014 removed \`${s}\` from your local share registry.`,"The public link may still be accessible until the API confirms deletion."].join(`
11
- `)}return`\u274C brain_unshare failed: ${t}`}const h=await y(o);try{const t=(await h.lrange("cachly:brain:shares",0,-1)).filter(a=>{try{return JSON.parse(a).share_id!==s}catch{return!0}});await h.del("cachly:brain:shares");for(const a of t)await h.rpush("cachly:brain:shares",a)}catch{}return["\u{1F5D1}\uFE0F **brain_unshare** \u2014 share revoked","",`Share \`${s}\` has been deleted. The public link is no longer accessible.`,"","_Anyone who already imported this Brain keeps their local copy._"].join(`
12
- `)}case"brain_discover":{const{query:o="",topic:s="",limit:h=10}=w;let e=[];try{const a=new URLSearchParams;o&&a.set("q",o),s&&a.set("topic",s),a.set("limit",String(h)),e=await $(`/api/v1/brains/discover?${a.toString()}`)}catch(a){const r=a.message??"";return r.includes("404")||r.includes("ECONNREFUSED")||r.includes("fetch failed")?["\u{1F50D} **brain_discover** \u2014 marketplace not yet live","","The public Brain marketplace is coming soon.","","**In the meantime:**",' \u2022 Share your Brain: `brain_share(instance_id="...", visibility="public")`',' \u2022 Import by ID: `brain_import(instance_id="...", share_id="<id>")`',` \u2022 Community index: ${T("/brains","brain-discover")}`].join(`
13
- `):`\u274C brain_discover failed: ${r}`}if(e.length===0)return[`\u{1F50D} **brain_discover** \u2014 no public Brains found ${o?`matching "${o}"`:s?`in topic "${s}"`:""}`.trim(),"",'Be the first! `brain_share(instance_id="...", visibility="public")`'].join(`
14
- `);const t=[`\u{1F50D} **brain_discover**${o?` \u2014 "${o}"`:""}${s?` \xB7 topic: ${s}`:""} (${e.length} result${e.length!==1?"s":""})`,""];for(const[a,r]of e.entries()){const l=new Date(r.created_at),c=isNaN(l.getTime())?"":` \xB7 ${l.toISOString().slice(0,10)}`,_=r.imports!=null?` \xB7 ${r.imports} imports`:"",i=r.topics?.length?` \xB7 topics: ${r.topics.slice(0,4).join(", ")}`:"",n=r.author?` by **${r.author}**`:"";t.push(`**${a+1}. ${r.title}**${n}`,` \u{1F4DA} ${r.lesson_count} lessons${i}${_}${c}`,r.description?` _${r.description.slice(0,120)}_`:"",` \`brain_import(instance_id="...", share_id="${r.share_id}")\``,"")}return t.push(`_Browse more at ${T("/brains","brain-discover")}_`),t.filter(a=>a!==" ").join(`
15
- `)}case"brain_seed_starter":{const{instance_id:o,topic_filter:s,dry_run:h=!1,force:e=!1}=w;if(!o)return"\u26A0\uFE0F `brain_seed_starter` requires `instance_id`.";const t=await y(o),a=await t.get(`cachly:brain:starter_seeded:${o}`);if(a&&!e&&!h)return["\u{1F331} **brain_seed_starter** \u2014 already seeded","",`This Brain was seeded with the starter corpus on ${a}.`,"","Pass `force=true` to re-seed (existing starter lessons will be refreshed)."].join(`
16
- `);const r=Array.isArray(s)&&s.length>0?s:void 0,l=r?k.filter(n=>r.some(d=>n.topic.includes(d)||n.tags.some(b=>b.includes(d)))):k;if(l.length===0)return["\u{1F331} **brain_seed_starter** \u2014 no matching starter lessons","",`No starter lessons match filter: ${r?.join(", ")}.`,`Available topics: ${k.map(n=>`\`${n.topic}\``).join(", ")}`].join(`
17
- `);if(h){const n=l.slice(0,8).map(d=>` \u2705 \`${d.topic}\` \u2014 ${d.what_worked.slice(0,70)}\u2026`);return[`\u{1F331} **brain_seed_starter (DRY RUN)** \u2014 would seed ${l.length} lesson${l.length!==1?"s":""}`,"",...n,l.length>8?` _...and ${l.length-8} more_`:"","","_Remove `dry_run=true` to seed these into the Brain._"].filter(d=>d!=="").join(`
18
- `)}const c=new Date().toISOString();let _=0,i=0;for(const n of l){const d=`cachly:lesson:best:${n.topic}`;if(!e){const p=await t.get(d);if(p){const m=j(p,null);if(m&&m.source!=="starter"){i++;continue}}}const b=JSON.stringify({topic:n.topic,outcome:n.outcome,what_worked:n.what_worked,what_failed:n.what_failed,ctx:n.ctx,tags:n.tags,confidence:n.confidence,recall_count:0,source:"starter",ts:c,verified_at:c,version:3});await t.set(d,b),await t.sadd(R,n.topic).catch(()=>{});const u=`cachly:lessons:${n.topic}`;await t.rpush(u,b),await t.ltrim(u,-100,-1),await t.expire(u,90*86400),_++}return await t.set(`cachly:stats:born_at:${o}`,c,"EX",365*86400,"NX").catch(()=>{}),await t.set(`cachly:brain:starter_seeded:${o}`,c,"EX",365*86400),["\u{1F331} **brain_seed_starter** \u2014 Brain seeded","",`**${_}** universal engineering lesson${_!==1?"s":""} added${i>0?` (${i} skipped \u2014 your own lessons take priority)`:""}.`,"","Your Brain now answers common questions out of the box:",' \u2022 `smart_recall(query="docker build slow")`',' \u2022 `smart_recall(query="pod OOMKilled")`',' \u2022 `smart_recall(query="jwt token rejected")`',"",'_Starter lessons are tagged `source: "starter"` and never override your own._',"_They're replaced as you learn project-specific lessons on the same topics._"].join(`
19
- `)}default:return null}}export{q as SHARE_TOOL_NAMES,x as STARTER_CORPUS_SIZE,J as handleShareTool};
1
+ import{safeJsonParse as E}from"../utils.js";import{STARTER_CORPUS as x,STARTER_CORPUS_SIZE as q}from"../starter-corpus.js";import{cachlyUrl as B}from"../cachly-url.js";import{VEKTOR_NACHTRAG as P}from"../bedeutung.js";import{schwaerze as z}from"../geheimnis-filter.js";import{fuerEigenenSpeicher as I,fuerWeitergabe as D,hinweise as J,istMarkiert as L,markiert as U,weitergabeHinweis as C,zaehlHinweise as H}from"../schreibtor.js";const W=new Set(["brain_share","brain_import","brain_share_list","brain_unshare","brain_discover","brain_seed_starter"]);async function K(O,g){const y=[],$=O.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((a,u)=>{$.on("data",e=>y.push(...e)),$.on("end",a),$.on("error",u)});const n=[];for(const a of y.slice(0,500)){const u=await O.get(a);if(!u)continue;const e=E(u,null);!e||!e.topic||g&&g.length>0&&!g.some(i=>e.topic.includes(i))||n.push({topic:e.topic,outcome:e.outcome,...e.what_worked?{what_worked:e.what_worked}:{},...e.what_failed?{what_failed:e.what_failed}:{},...e.ctx?{ctx:e.ctx}:{},...e.tags?.length?{tags:e.tags}:{},...e.author?{author:e.author}:{},...e.service?{service:e.service}:{},confidence:e.confidence??1,ts:e.ts})}return n}async function Q(O,g,y,$){switch(O){case"brain_share":{const{instance_id:n,title:a="My Brain Snapshot",description:u="",topic_filter:e,visibility:t="unlisted",max_lessons:i=100,dry_run:r=!1}=g;if(!n)return"\u26A0\uFE0F `brain_share` requires `instance_id`.";const c=D({title:a,description:u},"die Share");if(!c.ok)return c.meldung;const l=[...c.geschwaerzt],_=c.felder.title,f=c.felder.description,s=await y(n),p=Array.isArray(e)&&e.length>0?e:void 0,w=await K(s,p),m=[],S=[];for(const o of w){if(S.length>=i)break;const d=z(o.topic).text;if(L(o)){m.push(`${d} (beim Speichern markiert)`);continue}const b=D(o,"die Share");if(!b.ok){m.push(`${d} (${b.verdacht.join("; ")})`);continue}l.push(...b.geschwaerzt),S.push(b.felder)}const h=S,T=[C(l),m.length?`\u26D4 Tuersteher: ${m.length} Lektion(en) NICHT in die Share aufgenommen (Anweisung oder gefaehrlicher Befehl erkannt): ${m.slice(0,10).join(", ")}${m.length>10?", \u2026":""}. Pruefen und einzeln neu speichern; die Lektionen im Brain bleiben unveraendert.`:""].filter(Boolean);if(h.length===0)return["\u{1F4E4} **brain_share** \u2014 nothing to share yet","",`No lessons found in Brain \`${n}\`${p?` matching topics: ${p.join(", ")}`:""}${m.length?" that can be shared":""}.`,"",'Store lessons first with `learn_from_attempts(topic="...", what_worked="...")`.',...T].join(`
2
+ `);if(r){const o=h.slice(0,5).map(d=>` ${d.outcome==="success"?"\u2705":d.outcome==="failure"?"\u274C":"\u26A0\uFE0F"} \`${d.topic}\` \u2014 ${(d.what_worked??d.what_failed??"").slice(0,80)}`);return[`\u{1F4E4} **brain_share (DRY RUN)** \u2014 would share ${h.length} lesson${h.length!==1?"s":""}`,"",`**Title:** ${_}`,`**Visibility:** ${t}`,p?`**Topic filter:** ${p.join(", ")}`:"","","**Sample lessons (first 5):**",...o,h.length>5?` _...and ${h.length-5} more_`:"","",...T,"_Remove `dry_run=true` to create the public share._"].filter(d=>d!=="").join(`
3
+ `)}let j=null,v=null;try{j=(await $("/api/v1/brains/share",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({title:_,description:f,visibility:t,lessons:h})})).share_id??null,j&&(v=B(`/brain/share/${j}`,"brain-share"))}catch(o){const d=o.message??"";if(d.includes("404")||d.includes("not found")||d.includes("ECONNREFUSED")){const b=JSON.stringify({title:_,description:f,visibility:t,lessons:h,exported_at:new Date().toISOString()},null,2);return[`\u{1F4E4} **brain_share** \u2014 exported ${h.length} lesson${h.length!==1?"s":""}`,"","\u26A0\uFE0F The public share API is not yet available. Here is your portable snapshot:","","```json",b.slice(0,3e3)+(b.length>3e3?`
4
+ ... (truncated)`:""),"```","","_To import this on another Brain, use `brain_import` with the JSON payload._",...T].join(`
5
+ `)}return`\u274C brain_share failed: ${o.message}`}const k=h.slice(0,5).map(o=>` ${o.outcome==="success"?"\u2705":o.outcome==="failure"?"\u274C":"\u26A0\uFE0F"} \`${o.topic}\``);try{const o=JSON.stringify({share_id:j,title:_,visibility:t,lesson_count:h.length,created_at:new Date().toISOString()});await s.rpush("cachly:brain:shares",o),await s.ltrim("cachly:brain:shares",-20,-1)}catch{}return[`\u{1F4E4} **brain_share** \u2014 ${h.length} lesson${h.length!==1?"s":""} shared`,"",`**Share ID:** \`${j}\``,`**URL:** ${v}`,`**Title:** ${_}`,`**Visible:** ${t}`,"","**Sample lessons:**",...k,h.length>5?` _...and ${h.length-5} more_`:"","","**Anyone can import this Brain with:**",`\`brain_import(instance_id="<their-id>", share_id="${j}")\``,"","_To list all your shares, run `brain_share_list`._",...T.length?["",...T]:[]].filter(o=>o!=="").join(`
6
+ `)}case"brain_import":{const{instance_id:n,share_id:a,topic_prefix:u="",min_confidence:e=0,dry_run:t=!1,overwrite:i=!1}=g;if(!n)return"\u26A0\uFE0F `brain_import` requires `instance_id`.";if(!a)return"\u26A0\uFE0F `brain_import` requires `share_id`. Get one from `brain_share`.";const r=a.replace(/^.*\/brain\/share\//,"").trim();let c;try{c=await $(`/api/v1/brains/share/${r}`)}catch(k){const o=k.message??"";return o.includes("404")||o.includes("not found")?["\u274C **brain_import** \u2014 share not found","",`Share ID \`${r}\` does not exist or has been removed.`,"","Ask the Brain owner to re-run `brain_share` and share the new ID with you."].join(`
7
+ `):`\u274C brain_import failed: ${k.message}`}const l=c.lessons??[];if(l.length===0)return`\u26A0\uFE0F Share \`${r}\` exists but contains no lessons.`;const _=await y(n);let f=0,s=0,p=0;const w=[];let m=0,S=0;const h=I({title:c.title??""}),T=h.felder.title||r;for(const k of l){if((k.confidence??1)<e){s++;continue}const o=I(k);o.geschwaerzt.length&&m++,o.verdacht.length&&S++;const d=o.verdacht.length?{...o.felder,tags:U(o.felder.tags,o.verdacht)}:o.felder,b=u?`${u}:${d.topic}`:d.topic,R=`cachly:lesson:best:${b}`;if(!i&&await _.get(R)){p++;continue}const A=JSON.stringify({...d,topic:b,imported_from:r,imported_at:new Date().toISOString()});if(!t){await _.set(R,A);const N=`cachly:lessons:${b}`;await _.rpush(N,A),await _.ltrim(N,-100,-1),await _.expire(N,90*86400)}if(f++,w.length<6){const N=d.outcome==="success"?"\u2705":d.outcome==="failure"?"\u274C":"\u26A0\uFE0F";w.push(` ${N} \`${b}\` \u2014 ${(d.what_worked??d.what_failed??"").slice(0,80)}`)}}if(!t&&f>0)try{const k=JSON.stringify({share_id:r,title:h.felder.title||void 0,...h.verdacht.length?{verdacht:h.verdacht}:{},imported:f,skipped:s,conflicts:p,topic_prefix:u,imported_at:new Date().toISOString()});await _.rpush("cachly:brain:imports",k),await _.ltrim("cachly:brain:imports",-20,-1)}catch{}const v=[`\u{1F4E5} **brain_import${t?" (DRY RUN \u2014 no writes)":""}** \u2014 from "${T}"`,"",`**Share ID:** \`${r}\``,`**Lessons imported:** ${f}`,...s>0?[`**Skipped (low confidence):** ${s}`]:[],...p>0?[`**Skipped (already exist):** ${p} _(pass \`overwrite=true\` to replace)_`]:[],...H(m,S,`${l.length} Eintraegen`),...J(h,"notiz"),""];return w.length>0&&(v.push("**Sample lessons imported:**",...w),f>6&&v.push(` _...and ${f-6} more_`)),f>0&&!t?v.push("",'\u2705 Brain updated \u2014 use `smart_recall(query="...")` to query the new knowledge.'):t?v.push("","_Remove `dry_run=true` to actually import these lessons._"):f===0&&p>0&&v.push("","\u2139\uFE0F All lessons already exist in your Brain. Pass `overwrite=true` to update them."),v.join(`
8
+ `)}case"brain_share_list":{const{instance_id:n}=g;if(!n)return"\u26A0\uFE0F `brain_share_list` requires `instance_id`.";const a=await y(n);let u=[];try{u=(await a.lrange("cachly:brain:shares",0,-1)).map(l=>{try{return JSON.parse(l)}catch{return null}}).filter(Boolean)}catch{}let e=[];try{e=(await $("/api/v1/brains/share")).shares??[]}catch{}const t=e.length>0?e:u;if(t.length===0)return["\u{1F4E4} **brain_share_list** \u2014 no shares yet","","You haven't shared any Brain snapshots from this instance.","",`Create one with: \`brain_share(instance_id="${n}", title="My Patterns")\``].join(`
9
+ `);const i=[`\u{1F4E4} **Your Brain Shares** (${t.length})`,"","| # | Title | Lessons | Visibility | Created |","|---|-------|---------|------------|---------|"];for(const[c,l]of t.entries()){const _=new Date(l.created_at),f=isNaN(_.getTime())?l.created_at:_.toISOString().slice(0,10),s=l.visibility==="public"?"\u{1F310} public":"\u{1F517} unlisted";i.push(`| ${c+1} | ${l.title??"\u2014"} | ${l.lesson_count??"?"} | ${s} | ${f} |`)}const r=t[t.length-1];return i.push("",`**Import command:** \`brain_import(instance_id="<their-id>", share_id="${r?.share_id??"..."}")\``,`**Revoke:** \`brain_unshare(instance_id="${n}", share_id="<id>")\``),i.join(`
10
+ `)}case"brain_unshare":{const{instance_id:n,share_id:a}=g;if(!n)return"\u26A0\uFE0F `brain_unshare` requires `instance_id`.";if(!a)return"\u26A0\uFE0F `brain_unshare` requires `share_id`.";try{await $(`/api/v1/brains/share/${a}`,{method:"DELETE"})}catch(e){const t=e.message??"";if(t.includes("404")||t.includes("not found"))return`\u274C Share \`${a}\` not found \u2014 it may have already been removed.`;if(t.includes("ECONNREFUSED")||t.includes("fetch failed")){const i=await y(n);try{const c=(await i.lrange("cachly:brain:shares",0,-1)).filter(l=>{try{return JSON.parse(l).share_id!==a}catch{return!0}});await i.del("cachly:brain:shares");for(const l of c)await i.rpush("cachly:brain:shares",l)}catch{}return["\u26A0\uFE0F **brain_unshare** \u2014 removed from local log","",`API unreachable \u2014 removed \`${a}\` from your local share registry.`,"The public link may still be accessible until the API confirms deletion."].join(`
11
+ `)}return`\u274C brain_unshare failed: ${t}`}const u=await y(n);try{const t=(await u.lrange("cachly:brain:shares",0,-1)).filter(i=>{try{return JSON.parse(i).share_id!==a}catch{return!0}});await u.del("cachly:brain:shares");for(const i of t)await u.rpush("cachly:brain:shares",i)}catch{}return["\u{1F5D1}\uFE0F **brain_unshare** \u2014 share revoked","",`Share \`${a}\` has been deleted. The public link is no longer accessible.`,"","_Anyone who already imported this Brain keeps their local copy._"].join(`
12
+ `)}case"brain_discover":{const{query:n="",topic:a="",limit:u=10}=g;let e=[];try{const i=new URLSearchParams;n&&i.set("q",n),a&&i.set("topic",a),i.set("limit",String(u)),e=await $(`/api/v1/brains/discover?${i.toString()}`)}catch(i){const r=i.message??"";return r.includes("404")||r.includes("ECONNREFUSED")||r.includes("fetch failed")?["\u{1F50D} **brain_discover** \u2014 marketplace not yet live","","The public Brain marketplace is coming soon.","","**In the meantime:**",' \u2022 Share your Brain: `brain_share(instance_id="...", visibility="public")`',' \u2022 Import by ID: `brain_import(instance_id="...", share_id="<id>")`',` \u2022 Community index: ${B("/brains","brain-discover")}`].join(`
13
+ `):`\u274C brain_discover failed: ${r}`}if(e.length===0)return[`\u{1F50D} **brain_discover** \u2014 no public Brains found ${n?`matching "${n}"`:a?`in topic "${a}"`:""}`.trim(),"",'Be the first! `brain_share(instance_id="...", visibility="public")`'].join(`
14
+ `);const t=[`\u{1F50D} **brain_discover**${n?` \u2014 "${n}"`:""}${a?` \xB7 topic: ${a}`:""} (${e.length} result${e.length!==1?"s":""})`,""];for(const[i,r]of e.entries()){const c=new Date(r.created_at),l=isNaN(c.getTime())?"":` \xB7 ${c.toISOString().slice(0,10)}`,_=r.imports!=null?` \xB7 ${r.imports} imports`:"",f=r.topics?.length?` \xB7 topics: ${r.topics.slice(0,4).join(", ")}`:"",s=r.author?` by **${r.author}**`:"";t.push(`**${i+1}. ${r.title}**${s}`,` \u{1F4DA} ${r.lesson_count} lessons${f}${_}${l}`,r.description?` _${r.description.slice(0,120)}_`:"",` \`brain_import(instance_id="...", share_id="${r.share_id}")\``,"")}return t.push(`_Browse more at ${B("/brains","brain-discover")}_`),t.filter(i=>i!==" ").join(`
15
+ `)}case"brain_seed_starter":{const{instance_id:n,topic_filter:a,dry_run:u=!1,force:e=!1}=g;if(!n)return"\u26A0\uFE0F `brain_seed_starter` requires `instance_id`.";const t=await y(n),i=await t.get(`cachly:brain:starter_seeded:${n}`);if(i&&!e&&!u)return["\u{1F331} **brain_seed_starter** \u2014 already seeded","",`This Brain was seeded with the starter corpus on ${i}.`,"","Pass `force=true` to re-seed (existing starter lessons will be refreshed)."].join(`
16
+ `);const r=Array.isArray(a)&&a.length>0?a:void 0,c=r?x.filter(s=>r.some(p=>s.topic.includes(p)||s.tags.some(w=>w.includes(p)))):x;if(c.length===0)return["\u{1F331} **brain_seed_starter** \u2014 no matching starter lessons","",`No starter lessons match filter: ${r?.join(", ")}.`,`Available topics: ${x.map(s=>`\`${s.topic}\``).join(", ")}`].join(`
17
+ `);if(u){const s=c.slice(0,8).map(p=>` \u2705 \`${p.topic}\` \u2014 ${p.what_worked.slice(0,70)}\u2026`);return[`\u{1F331} **brain_seed_starter (DRY RUN)** \u2014 would seed ${c.length} lesson${c.length!==1?"s":""}`,"",...s,c.length>8?` _...and ${c.length-8} more_`:"","","_Remove `dry_run=true` to seed these into the Brain._"].filter(p=>p!=="").join(`
18
+ `)}const l=new Date().toISOString();let _=0,f=0;for(const s of c){const p=`cachly:lesson:best:${s.topic}`;if(!e){const S=await t.get(p);if(S){const h=E(S,null);if(h&&h.source!=="starter"){f++;continue}}}const w=JSON.stringify({topic:s.topic,outcome:s.outcome,what_worked:s.what_worked,what_failed:s.what_failed,ctx:s.ctx,tags:s.tags,confidence:s.confidence,recall_count:0,source:"starter",ts:l,verified_at:l,version:3});await t.set(p,w),await t.sadd(P,s.topic).catch(()=>{});const m=`cachly:lessons:${s.topic}`;await t.rpush(m,w),await t.ltrim(m,-100,-1),await t.expire(m,90*86400),_++}return await t.set(`cachly:stats:born_at:${n}`,l,"EX",365*86400,"NX").catch(()=>{}),await t.set(`cachly:brain:starter_seeded:${n}`,l,"EX",365*86400),["\u{1F331} **brain_seed_starter** \u2014 Brain seeded","",`**${_}** universal engineering lesson${_!==1?"s":""} added${f>0?` (${f} skipped \u2014 your own lessons take priority)`:""}.`,"","Your Brain now answers common questions out of the box:",' \u2022 `smart_recall(query="docker build slow")`',' \u2022 `smart_recall(query="pod OOMKilled")`',' \u2022 `smart_recall(query="jwt token rejected")`',"",'_Starter lessons are tagged `source: "starter"` and never override your own._',"_They're replaced as you learn project-specific lessons on the same topics._"].join(`
19
+ `)}default:return null}}export{W as SHARE_TOOL_NAMES,q as STARTER_CORPUS_SIZE,Q as handleShareTool};
@@ -1,42 +1,42 @@
1
- import{McpError as C,ErrorCode as j}from"@modelcontextprotocol/sdk/types.js";import{calculateConfidence as I}from"../confidence.js";import{ckgSlug as M}from"../ckg.js";import{keywordSearch as N}from"../search.js";import{safeJsonParse as v}from"../utils.js";import{sofortAntwortNeuesBrain as B}from"../leeres-brain.js";async function O(T,y,k,b,a){const t=(await a(`/api/v1/instances/${T}`).catch(()=>null))?.org_id;if(!t)return null;let i=null;try{i=await a(`/api/v1/orgs/${t}/brain/predict`,{method:"POST",body:JSON.stringify({context:y,top_k:k})})}catch{return null}return!i||!i.warnings||i.warnings.length===0?null:await L(y,i,b,a)}async function R(T,y,k){const b=y.warnings[0]?.problem||T;if(!b)return[];try{const a=await k(`/api/v1/syndication/search?q=${encodeURIComponent(b)}&limit=3`),o=new Set(y.warnings.map(t=>t.problem));return(a.results??[]).filter(t=>!!t.topic&&!!t.what_worked&&!o.has(t.topic)).slice(0,3).map(t=>({topic:t.topic,what_worked:t.what_worked.slice(0,160)}))}catch{return[]}}async function L(T,y,k,b){const a=[`\u{1F52E} **Org Brain Predict: "${T}"**`,""];for(const o of y.warnings){const t=Math.max(0,o.team_span-1),i=o.recurrence.reduce((p,s)=>p+(s.count??0),0),c=o.severity==="critical"?"\u{1F534}":o.severity==="major"?"\u{1F7E0}":"\u{1F7E1}";o.team_span>=2?a.push(`\u26A0\uFE0F **CROSS-TEAM RISK** \u2014 this pattern failed ${i}\xD7 across ${t} other team${t===1?"":"s"}:`):a.push(`\u26A0\uFE0F **RISK** \u2014 this pattern failed ${i}\xD7 before:`),a.push(` ${c} problem: \`${o.problem}\``);for(const p of o.recurrence.slice(0,6)){const s=p.last_seen?` (last: ${p.last_seen.slice(0,10)})`:"";a.push(` \u2022 ${p.team} \xD7${p.count}${s}`)}const d=o.fixes[0];if(d){const p=Math.round((d.confidence??0)*100),s=d.source_team?` (${d.source_team})`:"";a.push(` \u2705 Proven fix \u2014 ${p}% confidence, confirmed ${d.confirm_count}\xD7${s}:`),a.push(` ${d.summary}`)}a.push("")}if(k==="org+commons"){const o=await R(T,y,b);if(o.length>0){a.push("\u{1F310} **From the public Knowledge Commons** (cross-org, lower-signal):");for(const t of o)a.push(` \u2022 \`${t.topic}\` \u2014 ${t.what_worked}`);a.push("")}}return a.push('\u{1F4A1} Heeded the warning? `learn_from_attempts(..., tags=["prevented-by-org-graph"])` \u2192 counts as a prevented cross-team mistake.'),a.join(`
2
- `)}const U=new Set(["syndicate","syndicate_search","syndicate_stats","syndicate_trending","brain_search","ckg_inspect","brain_predict","brain_plan","brain_marketplace","brain_install","brain_conflicts","brain_resolve_conflict","brain_confirm_ci","brain_briefing"]);async function J(T,y,k,b){switch(T){case"syndicate":{const{topic:a,outcome:o="success",what_worked:t,what_failed:i="",severity:c="minor",tags:d=[],scope:p="public"}=y;if(!a||!t)throw new C(j.InvalidParams,"topic and what_worked are required");const n=await b("/api/v1/syndication/contribute",{method:"POST",body:JSON.stringify({topic:a,outcome:o,what_worked:t,what_failed:i,severity:c,tags:d,scope:p})}),h=p==="org"?"\u{1F3E2} org-private":"\u{1F310} global commons",f=n.deduped?`
3
- > \u267B\uFE0F Duplicate detected \u2014 trust score incremented for the existing lesson.`:"";return[`${p==="org"?"\u{1F3E2}":"\u{1F310}"} **Lesson syndicated to the ${p==="org"?"org Knowledge Commons":"global Knowledge Commons"}**${f}`,"",`**ID:** \`${n.id}\``,`**Topic:** \`${n.topic}\` \xB7 **Outcome:** ${n.outcome} \xB7 **Scope:** ${h}`,"",p==="org"?'This lesson is visible only within your organisation. Use `syndicate_search(scope="org")` to find it.':"Your lesson is now searchable by every AI brain in the network.","When another instance confirms it works, its trust score rises \u2014 and so does your contributor reputation.","",`**Tip:** Use \`syndicate_search(q="${a}")\` to see all community lessons on this topic.`].join(`
4
- `)}case"syndicate_search":{const{q:a="",limit:o=20,category:t="",scope:i=""}=y,c=new URLSearchParams;a&&c.set("q",a),t&&c.set("category",t),i&&c.set("scope",i),c.set("limit",String(Math.min(Math.max(1,o),50)));const d=await b(`/api/v1/syndication/search?${c}`);if(!d.results||d.results.length===0)return a?`No lessons found for "${a}" in the global Knowledge Commons yet.
1
+ import{McpError as I,ErrorCode as P}from"@modelcontextprotocol/sdk/types.js";import{calculateConfidence as M}from"../confidence.js";import{ckgSlug as B}from"../ckg.js";import{keywordSearch as O}from"../search.js";import{safeJsonParse as S}from"../utils.js";import{sofortAntwortNeuesBrain as K}from"../leeres-brain.js";import{fuerEigenenSpeicher as R,fuerWeitergabe as L,markiert as D,weitergabeHinweis as E,zaehlHinweise as A}from"../schreibtor.js";async function q(T,y,k,$,a){const e=(await a(`/api/v1/instances/${T}`).catch(()=>null))?.org_id;if(!e)return null;let r=null;try{r=await a(`/api/v1/orgs/${e}/brain/predict`,{method:"POST",body:JSON.stringify({context:y,top_k:k})})}catch{return null}return!r||!r.warnings||r.warnings.length===0?null:await z(y,r,$,a)}async function W(T,y,k){const $=y.warnings[0]?.problem||T;if(!$)return[];try{const a=await k(`/api/v1/syndication/search?q=${encodeURIComponent($)}&limit=3`),o=new Set(y.warnings.map(e=>e.problem));return(a.results??[]).filter(e=>!!e.topic&&!!e.what_worked&&!o.has(e.topic)).slice(0,3).map(e=>({topic:e.topic,what_worked:e.what_worked.slice(0,160)}))}catch{return[]}}async function z(T,y,k,$){const a=[`\u{1F52E} **Org Brain Predict: "${T}"**`,""];for(const o of y.warnings){const e=Math.max(0,o.team_span-1),r=o.recurrence.reduce((p,t)=>p+(t.count??0),0),c=o.severity==="critical"?"\u{1F534}":o.severity==="major"?"\u{1F7E0}":"\u{1F7E1}";o.team_span>=2?a.push(`\u26A0\uFE0F **CROSS-TEAM RISK** \u2014 this pattern failed ${r}\xD7 across ${e} other team${e===1?"":"s"}:`):a.push(`\u26A0\uFE0F **RISK** \u2014 this pattern failed ${r}\xD7 before:`),a.push(` ${c} problem: \`${o.problem}\``);for(const p of o.recurrence.slice(0,6)){const t=p.last_seen?` (last: ${p.last_seen.slice(0,10)})`:"";a.push(` \u2022 ${p.team} \xD7${p.count}${t}`)}const d=o.fixes[0];if(d){const p=Math.round((d.confidence??0)*100),t=d.source_team?` (${d.source_team})`:"";a.push(` \u2705 Proven fix \u2014 ${p}% confidence, confirmed ${d.confirm_count}\xD7${t}:`),a.push(` ${d.summary}`)}a.push("")}if(k==="org+commons"){const o=await W(T,y,$);if(o.length>0){a.push("\u{1F310} **From the public Knowledge Commons** (cross-org, lower-signal):");for(const e of o)a.push(` \u2022 \`${e.topic}\` \u2014 ${e.what_worked}`);a.push("")}}return a.push('\u{1F4A1} Heeded the warning? `learn_from_attempts(..., tags=["prevented-by-org-graph"])` \u2192 counts as a prevented cross-team mistake.'),a.join(`
2
+ `)}const V=new Set(["syndicate","syndicate_search","syndicate_stats","syndicate_trending","brain_search","ckg_inspect","brain_predict","brain_plan","brain_marketplace","brain_install","brain_conflicts","brain_resolve_conflict","brain_confirm_ci","brain_briefing"]);async function Q(T,y,k,$){switch(T){case"syndicate":{const{topic:a,outcome:o="success",what_worked:e,what_failed:r="",severity:c="minor",tags:d=[],scope:p="public"}=y;if(!a||!e)throw new I(P.InvalidParams,"topic and what_worked are required");const t=L({topic:a,what_worked:e,what_failed:r,tags:d},p==="org"?"die Org":"die Commons");if(!t.ok)return t.meldung;const s={...t.felder,outcome:o,severity:c,scope:p},f=await $("/api/v1/syndication/contribute",{method:"POST",body:JSON.stringify(s)}),h=p==="org"?"\u{1F3E2} org-private":"\u{1F310} global commons",u=f.deduped?`
3
+ > \u267B\uFE0F Duplicate detected \u2014 trust score incremented for the existing lesson.`:"";return[`${p==="org"?"\u{1F3E2}":"\u{1F310}"} **Lesson syndicated to the ${p==="org"?"org Knowledge Commons":"global Knowledge Commons"}**${u}`,"",`**ID:** \`${f.id}\``,`**Topic:** \`${f.topic}\` \xB7 **Outcome:** ${f.outcome} \xB7 **Scope:** ${h}`,"",p==="org"?'This lesson is visible only within your organisation. Use `syndicate_search(scope="org")` to find it.':"Your lesson is now searchable by every AI brain in the network.","When another instance confirms it works, its trust score rises \u2014 and so does your contributor reputation.","",`**Tip:** Use \`syndicate_search(q="${t.felder.topic}")\` to see all community lessons on this topic.`,...t.geschwaerzt.length?["",E(t.geschwaerzt)]:[]].join(`
4
+ `)}case"syndicate_search":{const{q:a="",limit:o=20,category:e="",scope:r=""}=y,c=new URLSearchParams;a&&c.set("q",a),e&&c.set("category",e),r&&c.set("scope",r),c.set("limit",String(Math.min(Math.max(1,o),50)));const d=await $(`/api/v1/syndication/search?${c}`);if(!d.results||d.results.length===0)return a?`No lessons found for "${a}" in the global Knowledge Commons yet.
5
5
 
6
- Be the first to contribute: \`syndicate(topic="...", what_worked="...")\``:'The global Knowledge Commons is empty. Be the first contributor:\n`syndicate(topic="deploy:api", what_worked="...")`';const p=u=>u==="success"?"\u2705":u==="failure"?"\u274C":"\u26A0\uFE0F",s=u=>u==="critical"?"\u{1F534}":u==="major"?"\u{1F7E1}":"\u{1F7E2}",n=u=>{const l=Math.min(10,Math.round(u/5));return"\u2588".repeat(l)+"\u2591".repeat(10-l)+` \xD7${u}`},h=[a,t].filter(Boolean).join(" \xB7 "),f=[`## \u{1F310} Global Knowledge Commons${h?` \u2014 ${h}`:" \u2014 Recent"}`,`*${d.count} lesson${d.count===1?"":"s"} found*`,""];for(const u of d.results)f.push(`### ${p(u.outcome)} \`${u.topic}\` ${s(u.severity)}`,`**Trust:** ${n(u.confirm_count)}`,u.what_worked?`**What worked:** ${u.what_worked}`:"",u.what_failed?`**What failed:** ${u.what_failed}`:"",`*Contributed ${new Date(u.created_at).toLocaleDateString("de-DE")} \xB7 ID: \`${u.id}\`*`,"");return f.push("---",`**Confirm** (this helped you): \`syndicate(topic="${d.results[0]?.topic??"..."}", what_worked="...")\` \u2192 auto-deduped, trust +1`,'**Contribute your own:** `syndicate(topic="fix:...", what_worked="...")`','**Filter by category:** `syndicate_search(category="fix")`'),f.filter(u=>u!=="").join(`
7
- `)}case"syndicate_stats":{const a=await b("/api/v1/syndication/stats"),o=i=>{const c=Math.min(10,Math.round(i/5));return"\u2588".repeat(c)+"\u2591".repeat(10-c)+` \xD7${i}`},t=["## \u{1F310} Global Knowledge Commons \u2014 Stats","","| Metric | Value |","|---|---|",`| Total lessons | **${a.total_lessons.toLocaleString()}** |`,`| Total confirms | **${a.total_confirms.toLocaleString()}** |`,`| Added last 7 days | **${a.added_last_7_days}** |`,"","### Top Categories"];for(const i of a.top_categories??[])t.push(`- \`${i.category}\` \u2014 ${i.count} lesson${i.count===1?"":"s"}`);t.push("","### Most Trusted Lessons");for(const i of a.most_trusted??[])t.push(`**\`${i.topic}\`** ${o(i.confirm_count)}`,`> ${i.what_worked.slice(0,120)}${i.what_worked.length>120?"\u2026":""}`,"");if(t.push("---",'**Contribute:** `syndicate(topic="...", what_worked="...")` | **Search:** `syndicate_search(q="your problem")`'),a.top_contributors?.length){t.push("","### \u{1F3C5} Top Contributors (anonymous)");for(const i of a.top_contributors)t.push(`- Trust **${i.trust_score}** \xB7 ${i.lessons_count} lesson${i.lessons_count===1?"":"s"} \xB7 ${i.confirms_received} confirms received`)}return t.join(`
8
- `)}case"syndicate_trending":{const{limit:a=10}=y,o=new URLSearchParams({limit:String(Math.min(Math.max(1,a),50))}),t=await b(`/api/v1/syndication/trending?${o}`);if(!t.results||t.results.length===0)return["## \u{1F4C8} Trending in the Knowledge Commons","","No trending lessons yet (need at least 2 confirms in the last 7 days).","",'Contribute and confirm lessons to see them trend: `syndicate(topic="...", what_worked="...")`'].join(`
9
- `);const i=n=>n==="success"?"\u2705":n==="failure"?"\u274C":"\u26A0\uFE0F",c=n=>n==="critical"?"\u{1F534}":n==="major"?"\u{1F7E1}":"\u{1F7E2}",d=n=>{const h=Math.min(10,Math.round(n/5));return"\u2588".repeat(h)+"\u2591".repeat(10-h)+` \xD7${n}`},p=n=>{const h=Math.min(10,Math.round(n*2));return"\u25B2".repeat(h)+"\u25B3".repeat(10-h)+` ${n.toFixed(2)}/day`},s=["## \u{1F4C8} Trending in the Knowledge Commons","*Lessons with the fastest confirmation velocity in the last 7 days*",""];for(const n of t.results)s.push(`### ${i(n.outcome)} \`${n.topic}\` ${c(n.severity)}`,`**Trend:** ${p(n.trend_score)} | **Trust:** ${d(n.confirm_count)}`,n.what_worked?`**What worked:** ${n.what_worked.slice(0,200)}${n.what_worked.length>200?"\u2026":""}`:"",`*ID: \`${n.id}\` \xB7 ${new Date(n.created_at).toLocaleDateString("de-DE")}*`,"");return s.push("---",`**Confirm** (if this helped you): \`syndicate(topic="${t.results[0]?.topic??"..."}", what_worked="...")\` \u2192 auto-deduped, trust +1`,'**All trending:** `syndicate_trending(limit=50)` | **Search:** `syndicate_search(q="...")`'),s.filter(n=>n!=="").join(`
10
- `)}case"brain_search":{const{instance_id:a,query:o,limit:t=15}=y,i=await B(a,b,`\u{1F50E} **Brain Search: "${o}"**
6
+ Be the first to contribute: \`syndicate(topic="...", what_worked="...")\``:'The global Knowledge Commons is empty. Be the first contributor:\n`syndicate(topic="deploy:api", what_worked="...")`';const p=u=>u==="success"?"\u2705":u==="failure"?"\u274C":"\u26A0\uFE0F",t=u=>u==="critical"?"\u{1F534}":u==="major"?"\u{1F7E1}":"\u{1F7E2}",s=u=>{const l=Math.min(10,Math.round(u/5));return"\u2588".repeat(l)+"\u2591".repeat(10-l)+` \xD7${u}`},f=[a,e].filter(Boolean).join(" \xB7 "),h=[`## \u{1F310} Global Knowledge Commons${f?` \u2014 ${f}`:" \u2014 Recent"}`,`*${d.count} lesson${d.count===1?"":"s"} found*`,""];for(const u of d.results)h.push(`### ${p(u.outcome)} \`${u.topic}\` ${t(u.severity)}`,`**Trust:** ${s(u.confirm_count)}`,u.what_worked?`**What worked:** ${u.what_worked}`:"",u.what_failed?`**What failed:** ${u.what_failed}`:"",`*Contributed ${new Date(u.created_at).toLocaleDateString("de-DE")} \xB7 ID: \`${u.id}\`*`,"");return h.push("---",`**Confirm** (this helped you): \`syndicate(topic="${d.results[0]?.topic??"..."}", what_worked="...")\` \u2192 auto-deduped, trust +1`,'**Contribute your own:** `syndicate(topic="fix:...", what_worked="...")`','**Filter by category:** `syndicate_search(category="fix")`'),h.filter(u=>u!=="").join(`
7
+ `)}case"syndicate_stats":{const a=await $("/api/v1/syndication/stats"),o=r=>{const c=Math.min(10,Math.round(r/5));return"\u2588".repeat(c)+"\u2591".repeat(10-c)+` \xD7${r}`},e=["## \u{1F310} Global Knowledge Commons \u2014 Stats","","| Metric | Value |","|---|---|",`| Total lessons | **${a.total_lessons.toLocaleString()}** |`,`| Total confirms | **${a.total_confirms.toLocaleString()}** |`,`| Added last 7 days | **${a.added_last_7_days}** |`,"","### Top Categories"];for(const r of a.top_categories??[])e.push(`- \`${r.category}\` \u2014 ${r.count} lesson${r.count===1?"":"s"}`);e.push("","### Most Trusted Lessons");for(const r of a.most_trusted??[])e.push(`**\`${r.topic}\`** ${o(r.confirm_count)}`,`> ${r.what_worked.slice(0,120)}${r.what_worked.length>120?"\u2026":""}`,"");if(e.push("---",'**Contribute:** `syndicate(topic="...", what_worked="...")` | **Search:** `syndicate_search(q="your problem")`'),a.top_contributors?.length){e.push("","### \u{1F3C5} Top Contributors (anonymous)");for(const r of a.top_contributors)e.push(`- Trust **${r.trust_score}** \xB7 ${r.lessons_count} lesson${r.lessons_count===1?"":"s"} \xB7 ${r.confirms_received} confirms received`)}return e.join(`
8
+ `)}case"syndicate_trending":{const{limit:a=10}=y,o=new URLSearchParams({limit:String(Math.min(Math.max(1,a),50))}),e=await $(`/api/v1/syndication/trending?${o}`);if(!e.results||e.results.length===0)return["## \u{1F4C8} Trending in the Knowledge Commons","","No trending lessons yet (need at least 2 confirms in the last 7 days).","",'Contribute and confirm lessons to see them trend: `syndicate(topic="...", what_worked="...")`'].join(`
9
+ `);const r=s=>s==="success"?"\u2705":s==="failure"?"\u274C":"\u26A0\uFE0F",c=s=>s==="critical"?"\u{1F534}":s==="major"?"\u{1F7E1}":"\u{1F7E2}",d=s=>{const f=Math.min(10,Math.round(s/5));return"\u2588".repeat(f)+"\u2591".repeat(10-f)+` \xD7${s}`},p=s=>{const f=Math.min(10,Math.round(s*2));return"\u25B2".repeat(f)+"\u25B3".repeat(10-f)+` ${s.toFixed(2)}/day`},t=["## \u{1F4C8} Trending in the Knowledge Commons","*Lessons with the fastest confirmation velocity in the last 7 days*",""];for(const s of e.results)t.push(`### ${r(s.outcome)} \`${s.topic}\` ${c(s.severity)}`,`**Trend:** ${p(s.trend_score)} | **Trust:** ${d(s.confirm_count)}`,s.what_worked?`**What worked:** ${s.what_worked.slice(0,200)}${s.what_worked.length>200?"\u2026":""}`:"",`*ID: \`${s.id}\` \xB7 ${new Date(s.created_at).toLocaleDateString("de-DE")}*`,"");return t.push("---",`**Confirm** (if this helped you): \`syndicate(topic="${e.results[0]?.topic??"..."}", what_worked="...")\` \u2192 auto-deduped, trust +1`,'**All trending:** `syndicate_trending(limit=50)` | **Search:** `syndicate_search(q="...")`'),t.filter(s=>s!=="").join(`
10
+ `)}case"brain_search":{const{instance_id:a,query:o,limit:e=15}=y,r=await K(a,$,`\u{1F50E} **Brain Search: "${o}"**
11
11
 
12
- No results found across all brain data.`);if(i)return i;const c=await k(a),d=await N(c,["cachly:lesson:best:*","cachly:ctx:*","cachly:idx:*","cachly:session:last","cachly:session:handoff","cachly:roadmap:*","cachly:ckg:node:*"],o,t);if(d.length===0)return[`\u{1F50E} **Brain Search: "${o}"**`,"","No results found across all brain data.","","\u{1F4A1} Try `smart_recall` or check `list_remembered`."].join(`
12
+ No results found across all brain data.`);if(r)return r;const c=await k(a),d=await O(c,["cachly:lesson:best:*","cachly:ctx:*","cachly:idx:*","cachly:session:last","cachly:session:handoff","cachly:roadmap:*","cachly:ckg:node:*"],o,e);if(d.length===0)return[`\u{1F50E} **Brain Search: "${o}"**`,"","No results found across all brain data.","","\u{1F4A1} Try `smart_recall` or check `list_remembered`."].join(`
13
13
  `);const p=[`\u{1F50E} **Brain Search: "${o}"** \u2014 ${d.length} result${d.length!==1?"s":""} across all brain data
14
- `];for(const s of d.slice(0,t)){const n=s.key.startsWith("cachly:lesson:")?"\u{1F4A1} lesson":s.key.startsWith("cachly:ctx:")?"\u{1F4DD} context":s.key.startsWith("cachly:idx:")?"\u{1F4C2} index":s.key.startsWith("cachly:session:")?"\u{1F550} session":s.key.startsWith("cachly:roadmap:")?"\u{1F5FA}\uFE0F roadmap":s.key.startsWith("cachly:ckg:node:")?"\u{1F578}\uFE0F ckg-node":"\u{1F5C4}\uFE0F data",h=s.content.slice(0,280).replace(/\n/g," ");p.push(`**${n}** \`${s.key.split(":").slice(2).join(":")}\` _(BM25: ${s.score.toFixed(2)})_`),p.push(`> ${h}${s.content.length>280?"\u2026":""}
14
+ `];for(const t of d.slice(0,e)){const s=t.key.startsWith("cachly:lesson:")?"\u{1F4A1} lesson":t.key.startsWith("cachly:ctx:")?"\u{1F4DD} context":t.key.startsWith("cachly:idx:")?"\u{1F4C2} index":t.key.startsWith("cachly:session:")?"\u{1F550} session":t.key.startsWith("cachly:roadmap:")?"\u{1F5FA}\uFE0F roadmap":t.key.startsWith("cachly:ckg:node:")?"\u{1F578}\uFE0F ckg-node":"\u{1F5C4}\uFE0F data",f=t.content.slice(0,280).replace(/\n/g," ");p.push(`**${s}** \`${t.key.split(":").slice(2).join(":")}\` _(BM25: ${t.score.toFixed(2)})_`),p.push(`> ${f}${t.content.length>280?"\u2026":""}
15
15
  `)}return p.join(`
16
- `)}case"ckg_inspect":{const{instance_id:a,concept:o,max_hops:t=2}=y,i=await k(a),c=M(o),d=new Set,p=[],s=[{id:c,hop:0}];for(;s.length>0;){const{id:e,hop:r}=s.shift();if(d.has(e)||r>t)continue;d.add(e);const g=await i.smembers(`cachly:ckg:idx:from:${e}`),w=await i.smembers(`cachly:ckg:idx:to:${e}`);for(const m of[...g,...w].slice(0,50)){const _=await i.get(m);if(!_)continue;const $=v(_,null);$&&(p.push($),r<t&&(d.has($.from)||s.push({id:$.from,hop:r+1}),d.has($.to)||s.push({id:$.to,hop:r+1})))}}if(p.length===0){const e=[],r=i.scanStream({match:`cachly:ckg:node:*${c}*`,count:100});if(await new Promise((w,m)=>{r.on("data",_=>e.push(..._)),r.on("end",w),r.on("error",m)}),e.length===0)return[`\u{1F578}\uFE0F **CKG Inspect: "${o}"**`,"","No CKG nodes found. The graph builds automatically as you call `learn_from_attempts`.","","\u{1F4A1} Once you have lessons stored, CKG edges will appear here."].join(`
17
- `);const g=e.slice(0,10).map(w=>` \u2022 \`${w.replace("cachly:ckg:node:","")}\``).join(`
18
- `);return[`\u{1F578}\uFE0F **CKG Inspect: "${o}"**`,"",`No edges found for \`${c}\`, but found similar nodes:`,g,"",'Try: `ckg_inspect(concept="<exact-node-id>")`'].join(`
19
- `)}const n=new Set,h=p.filter(e=>{const r=`${e.from}:${e.edgeType}:${e.to}`;return n.has(r)?!1:(n.add(r),!0)}).sort((e,r)=>r.confidence-e.confidence),f={fixes:"\u{1F527}",requires:"\u{1F517}","co-occurs":"\u{1F504}",causes:"\u26A1",contradicts:"\u26A0\uFE0F",degrades_under:"\u{1F4C9}"},u=[`\u{1F578}\uFE0F **CKG Inspect: "${o}"** (${h.length} edge${h.length!==1?"s":""}, ${d.size} node${d.size!==1?"s":""} traversed)
20
- `],l=new Map;for(const e of h)l.has(e.edgeType)||l.set(e.edgeType,[]),l.get(e.edgeType).push(e);for(const[e,r]of l){const g=f[e]??"\u2192";u.push(`**${g} ${e}** (${r.length})`);for(const w of r.slice(0,8)){const m=Math.round(w.confidence*100),_="\u2593".repeat(Math.round(m/10))+"\u2591".repeat(10-Math.round(m/10));u.push(` \`${w.from}\` \u2192 \`${w.to}\` ${_} ${m}% (${w.successes.toFixed(1)}/${w.trials} trials)`)}u.push("")}return u.push(`\u{1F4A1} Expand: \`ckg_inspect(concept="${o}", max_hops=3)\` | Predict: \`brain_predict(context="${o}")\``),u.join(`
21
- `)}case"brain_predict":{const{instance_id:a,context:o,top_k:t=5,scope:i="instance"}=y;if(i==="org"||i==="org+commons"){const l=await O(a,o,t,i,b);if(l!==null)return l}const c=await B(a,b,`\u{1F52E} **Brain Predict: "${o}"**
16
+ `)}case"ckg_inspect":{const{instance_id:a,concept:o,max_hops:e=2}=y,r=await k(a),c=B(o),d=new Set,p=[],t=[{id:c,hop:0}];for(;t.length>0;){const{id:n,hop:i}=t.shift();if(d.has(n)||i>e)continue;d.add(n);const w=await r.smembers(`cachly:ckg:idx:from:${n}`),g=await r.smembers(`cachly:ckg:idx:to:${n}`);for(const m of[...w,...g].slice(0,50)){const _=await r.get(m);if(!_)continue;const b=S(_,null);b&&(p.push(b),i<e&&(d.has(b.from)||t.push({id:b.from,hop:i+1}),d.has(b.to)||t.push({id:b.to,hop:i+1})))}}if(p.length===0){const n=[],i=r.scanStream({match:`cachly:ckg:node:*${c}*`,count:100});if(await new Promise((g,m)=>{i.on("data",_=>n.push(..._)),i.on("end",g),i.on("error",m)}),n.length===0)return[`\u{1F578}\uFE0F **CKG Inspect: "${o}"**`,"","No CKG nodes found. The graph builds automatically as you call `learn_from_attempts`.","","\u{1F4A1} Once you have lessons stored, CKG edges will appear here."].join(`
17
+ `);const w=n.slice(0,10).map(g=>` \u2022 \`${g.replace("cachly:ckg:node:","")}\``).join(`
18
+ `);return[`\u{1F578}\uFE0F **CKG Inspect: "${o}"**`,"",`No edges found for \`${c}\`, but found similar nodes:`,w,"",'Try: `ckg_inspect(concept="<exact-node-id>")`'].join(`
19
+ `)}const s=new Set,f=p.filter(n=>{const i=`${n.from}:${n.edgeType}:${n.to}`;return s.has(i)?!1:(s.add(i),!0)}).sort((n,i)=>i.confidence-n.confidence),h={fixes:"\u{1F527}",requires:"\u{1F517}","co-occurs":"\u{1F504}",causes:"\u26A1",contradicts:"\u26A0\uFE0F",degrades_under:"\u{1F4C9}"},u=[`\u{1F578}\uFE0F **CKG Inspect: "${o}"** (${f.length} edge${f.length!==1?"s":""}, ${d.size} node${d.size!==1?"s":""} traversed)
20
+ `],l=new Map;for(const n of f)l.has(n.edgeType)||l.set(n.edgeType,[]),l.get(n.edgeType).push(n);for(const[n,i]of l){const w=h[n]??"\u2192";u.push(`**${w} ${n}** (${i.length})`);for(const g of i.slice(0,8)){const m=Math.round(g.confidence*100),_="\u2593".repeat(Math.round(m/10))+"\u2591".repeat(10-Math.round(m/10));u.push(` \`${g.from}\` \u2192 \`${g.to}\` ${_} ${m}% (${g.successes.toFixed(1)}/${g.trials} trials)`)}u.push("")}return u.push(`\u{1F4A1} Expand: \`ckg_inspect(concept="${o}", max_hops=3)\` | Predict: \`brain_predict(context="${o}")\``),u.join(`
21
+ `)}case"brain_predict":{const{instance_id:a,context:o,top_k:e=5,scope:r="instance"}=y;if(r==="org"||r==="org+commons"){const l=await q(a,o,e,r,$);if(l!==null)return l}const c=await K(a,$,`\u{1F52E} **Brain Predict: "${o}"**
22
22
 
23
- No predictions yet \u2014 the brain hasn't seen this domain.`);if(c)return c;const d=await k(a),p=o.toLowerCase().replace(/[^a-z0-9\s\-_:]/g," ").split(/\s+/).filter(l=>l.length>2),s=[];for(const l of p.slice(0,6)){const e=[],r=d.scanStream({match:`cachly:ckg:node:*${l}*`,count:50});await new Promise((g,w)=>{r.on("data",m=>e.push(...m)),r.on("end",g),r.on("error",w)});for(const g of e.slice(0,5)){const w=await d.get(g);if(!w)continue;const m=v(w,null);if(!m)continue;const _=await d.smembers(`cachly:ckg:idx:from:${m.id}`);for(const $ of _.slice(0,20)){const S=await d.get($);if(!S)continue;const x=v(S,null);if(!x||x.edgeType!=="fixes"&&x.edgeType!=="co-occurs"&&x.edgeType!=="causes")continue;const P=await d.get(`cachly:lesson:best:${x.from}`),K=P?v(P,null)??void 0:void 0;s.push({concept:m.id,edgeType:x.edgeType,target:x.to,confidence:x.confidence,lesson:K})}}}const n=[],h=[],f=d.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((l,e)=>{f.on("data",r=>h.push(...r)),f.on("end",l),f.on("error",e)});for(const l of h){const e=await d.get(l);if(e){const r=v(e,null);if(!r)continue;const g=[r.topic,r.what_failed??"",r.what_worked??""].join(" ").toLowerCase();if(p.reduce((m,_)=>m+(g.includes(_)?1:0),0)>=1&&r.outcome!=="failure"){const m=I(r);n.push({...r,confidence:m})}}}if(n.sort((l,e)=>e.confidence-l.confidence),s.length===0&&n.length===0)return[`\u{1F52E} **Brain Predict: "${o}"**`,"","No predictions yet \u2014 the brain hasn't seen this domain.","","\u{1F4A1} As you solve problems in this area and call `learn_from_attempts`, the CKG builds up and predictions become available."].join(`
23
+ No predictions yet \u2014 the brain hasn't seen this domain.`);if(c)return c;const d=await k(a),p=o.toLowerCase().replace(/[^a-z0-9\s\-_:]/g," ").split(/\s+/).filter(l=>l.length>2),t=[];for(const l of p.slice(0,6)){const n=[],i=d.scanStream({match:`cachly:ckg:node:*${l}*`,count:50});await new Promise((w,g)=>{i.on("data",m=>n.push(...m)),i.on("end",w),i.on("error",g)});for(const w of n.slice(0,5)){const g=await d.get(w);if(!g)continue;const m=S(g,null);if(!m)continue;const _=await d.smembers(`cachly:ckg:idx:from:${m.id}`);for(const b of _.slice(0,20)){const x=await d.get(b);if(!x)continue;const v=S(x,null);if(!v||v.edgeType!=="fixes"&&v.edgeType!=="co-occurs"&&v.edgeType!=="causes")continue;const j=await d.get(`cachly:lesson:best:${v.from}`),C=j?S(j,null)??void 0:void 0;t.push({concept:m.id,edgeType:v.edgeType,target:v.to,confidence:v.confidence,lesson:C})}}}const s=[],f=[],h=d.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((l,n)=>{h.on("data",i=>f.push(...i)),h.on("end",l),h.on("error",n)});for(const l of f){const n=await d.get(l);if(n){const i=S(n,null);if(!i)continue;const w=[i.topic,i.what_failed??"",i.what_worked??""].join(" ").toLowerCase();if(p.reduce((m,_)=>m+(w.includes(_)?1:0),0)>=1&&i.outcome!=="failure"){const m=M(i);s.push({...i,confidence:m})}}}if(s.sort((l,n)=>n.confidence-l.confidence),t.length===0&&s.length===0)return[`\u{1F52E} **Brain Predict: "${o}"**`,"","No predictions yet \u2014 the brain hasn't seen this domain.","","\u{1F4A1} As you solve problems in this area and call `learn_from_attempts`, the CKG builds up and predictions become available."].join(`
24
24
  `);const u=[`\u{1F52E} **Brain Predict: "${o}"**
25
- `];if(s.length>0){const l=new Set,e=s.filter(r=>{const g=`${r.concept}:${r.edgeType}:${r.target}`;return l.has(g)?!1:(l.add(g),!0)}).sort((r,g)=>g.confidence-r.confidence).slice(0,t);u.push(`### \u{1F578}\uFE0F CKG Predictions (based on ${e.length} known edges)`);for(const r of e){const g=Math.round(r.confidence*100),w=r.edgeType==="fixes"?"\u{1F527}":r.edgeType==="co-occurs"?"\u{1F504}":"\u26A1";u.push(`${w} **${g}%** \`${r.concept}\` _${r.edgeType}_ \`${r.target}\``),r.lesson?.what_worked&&u.push(` \u2705 ${r.lesson.what_worked.slice(0,120)}`)}u.push("")}if(n.length>0){u.push(`### \u{1F4DA} Relevant Lessons (${Math.min(n.length,t)} pre-loaded)`);for(const l of n.slice(0,t)){const e=Math.round(l.confidence*100);u.push(` \u2705 **${e}%** \`${l.topic}\` \u2014 ${(l.what_worked??"").slice(0,120)}`)}u.push("")}return u.push('\u{1F4A1} Outcome confirmed? `learn_from_attempts(topic="fix:...", outcome="success", ...)` \u2192 improves future predictions'),u.join(`
26
- `)}case"brain_plan":{const{instance_id:a,task:o,top_k:t=5}=y;if(!o||!o.trim())throw new C(j.InvalidParams,"task is required");const i=await k(a),c=o.toLowerCase().replace(/[^a-z0-9\s\-_:]/g," ").split(/\s+/).filter(l=>l.length>2),d=[],p=i.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((l,e)=>{p.on("data",r=>d.push(...r)),p.on("end",l),p.on("error",e)});const s=[];for(const l of d){const e=await i.get(l);if(!e)continue;const r=v(e,null);if(!r)continue;const g=[r.topic,r.what_worked??"",r.what_failed??""].join(" ").toLowerCase(),w=c.reduce((m,_)=>m+(g.includes(_)?1:0),0);w>=1&&s.push({l:r,score:w,confidence:I(r)})}if(s.length===0)return[`\u{1F5FA}\uFE0F **Brain Plan: "${o}"**`,"","No grounded plan yet \u2014 the brain hasn't seen this area.","","\u{1F4A1} As you work here and call `learn_from_attempts`, brain_plan will assemble"," an ordered, proven plan from your own history. For now, proceed carefully"," and capture what works."].join(`
27
- `);s.sort((l,e)=>e.score-l.score||e.confidence-l.confidence);const n=s.filter(l=>l.l.outcome==="failure"||(l.l.what_failed??"").trim().length>0),h=s.filter(l=>l.l.outcome==="success"||l.l.outcome==="partial"),f=[`\u{1F5FA}\uFE0F **Brain Plan: "${o}"**`,"",`_Grounded in ${s.length} relevant lesson${s.length!==1?"s":""} from your own Brain._`,""];if(n.length>0){f.push("### \u26A0\uFE0F Likely failure modes (avoid these)");const l={critical:0,major:1,minor:2};n.slice().sort((e,r)=>(l[e.l.severity??"minor"]??1)-(l[r.l.severity??"minor"]??1)||r.confidence-e.confidence).slice(0,t).forEach(({l:e,confidence:r})=>{const g=e.severity==="critical"?"\u{1F534}":e.severity==="major"?"\u{1F7E1}":"\u{1F7E2}",w=(e.what_failed??e.what_worked??"").slice(0,120);f.push(`${g} **${Math.round(r*100)}%** \`${e.topic}\`${w?` \u2014 ${w}`:""}`)}),f.push("")}if(h.length>0){const l=h.slice(0,t),e=new Map(l.map(m=>[m.l.topic,m])),r=[],g=new Set,w=(m,_)=>{if(!(g.has(m.l.topic)||_>10)){for(const $ of m.l.depends_on??[]){const S=e.get($);S&&!g.has($)&&w(S,_+1)}g.has(m.l.topic)||(g.add(m.l.topic),r.push(m))}};for(const m of l)w(m,0);f.push("### \u{1F527} Recommended steps (proven fixes, in order)"),r.forEach(({l:m,confidence:_},$)=>{f.push(`${$+1}. **${Math.round(_*100)}%** \`${m.topic}\` \u2014 ${(m.what_worked??"").slice(0,140)}`);const S=(m.commands??[]).slice(0,2);S.length>0&&f.push(` \`\`\`
28
- ${S.join(`
25
+ `];if(t.length>0){const l=new Set,n=t.filter(i=>{const w=`${i.concept}:${i.edgeType}:${i.target}`;return l.has(w)?!1:(l.add(w),!0)}).sort((i,w)=>w.confidence-i.confidence).slice(0,e);u.push(`### \u{1F578}\uFE0F CKG Predictions (based on ${n.length} known edges)`);for(const i of n){const w=Math.round(i.confidence*100),g=i.edgeType==="fixes"?"\u{1F527}":i.edgeType==="co-occurs"?"\u{1F504}":"\u26A1";u.push(`${g} **${w}%** \`${i.concept}\` _${i.edgeType}_ \`${i.target}\``),i.lesson?.what_worked&&u.push(` \u2705 ${i.lesson.what_worked.slice(0,120)}`)}u.push("")}if(s.length>0){u.push(`### \u{1F4DA} Relevant Lessons (${Math.min(s.length,e)} pre-loaded)`);for(const l of s.slice(0,e)){const n=Math.round(l.confidence*100);u.push(` \u2705 **${n}%** \`${l.topic}\` \u2014 ${(l.what_worked??"").slice(0,120)}`)}u.push("")}return u.push('\u{1F4A1} Outcome confirmed? `learn_from_attempts(topic="fix:...", outcome="success", ...)` \u2192 improves future predictions'),u.join(`
26
+ `)}case"brain_plan":{const{instance_id:a,task:o,top_k:e=5}=y;if(!o||!o.trim())throw new I(P.InvalidParams,"task is required");const r=await k(a),c=o.toLowerCase().replace(/[^a-z0-9\s\-_:]/g," ").split(/\s+/).filter(l=>l.length>2),d=[],p=r.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((l,n)=>{p.on("data",i=>d.push(...i)),p.on("end",l),p.on("error",n)});const t=[];for(const l of d){const n=await r.get(l);if(!n)continue;const i=S(n,null);if(!i)continue;const w=[i.topic,i.what_worked??"",i.what_failed??""].join(" ").toLowerCase(),g=c.reduce((m,_)=>m+(w.includes(_)?1:0),0);g>=1&&t.push({l:i,score:g,confidence:M(i)})}if(t.length===0)return[`\u{1F5FA}\uFE0F **Brain Plan: "${o}"**`,"","No grounded plan yet \u2014 the brain hasn't seen this area.","","\u{1F4A1} As you work here and call `learn_from_attempts`, brain_plan will assemble"," an ordered, proven plan from your own history. For now, proceed carefully"," and capture what works."].join(`
27
+ `);t.sort((l,n)=>n.score-l.score||n.confidence-l.confidence);const s=t.filter(l=>l.l.outcome==="failure"||(l.l.what_failed??"").trim().length>0),f=t.filter(l=>l.l.outcome==="success"||l.l.outcome==="partial"),h=[`\u{1F5FA}\uFE0F **Brain Plan: "${o}"**`,"",`_Grounded in ${t.length} relevant lesson${t.length!==1?"s":""} from your own Brain._`,""];if(s.length>0){h.push("### \u26A0\uFE0F Likely failure modes (avoid these)");const l={critical:0,major:1,minor:2};s.slice().sort((n,i)=>(l[n.l.severity??"minor"]??1)-(l[i.l.severity??"minor"]??1)||i.confidence-n.confidence).slice(0,e).forEach(({l:n,confidence:i})=>{const w=n.severity==="critical"?"\u{1F534}":n.severity==="major"?"\u{1F7E1}":"\u{1F7E2}",g=(n.what_failed??n.what_worked??"").slice(0,120);h.push(`${w} **${Math.round(i*100)}%** \`${n.topic}\`${g?` \u2014 ${g}`:""}`)}),h.push("")}if(f.length>0){const l=f.slice(0,e),n=new Map(l.map(m=>[m.l.topic,m])),i=[],w=new Set,g=(m,_)=>{if(!(w.has(m.l.topic)||_>10)){for(const b of m.l.depends_on??[]){const x=n.get(b);x&&!w.has(b)&&g(x,_+1)}w.has(m.l.topic)||(w.add(m.l.topic),i.push(m))}};for(const m of l)g(m,0);h.push("### \u{1F527} Recommended steps (proven fixes, in order)"),i.forEach(({l:m,confidence:_},b)=>{h.push(`${b+1}. **${Math.round(_*100)}%** \`${m.topic}\` \u2014 ${(m.what_worked??"").slice(0,140)}`);const x=(m.commands??[]).slice(0,2);x.length>0&&h.push(` \`\`\`
28
+ ${x.join(`
29
29
  `)}
30
- \`\`\``),(m.depends_on??[]).length>0&&f.push(` \u21B3 depends on: ${(m.depends_on??[]).map(x=>`\`${x}\``).join(", ")}`)}),f.push("")}const u=s.filter(l=>(l.l.file_paths??[]).length>0||(l.l.commands??[]).length>0).slice(0,4);if(u.length>0){f.push("### \u2705 Pre-flight checklist");const l=[...new Set(u.flatMap(e=>e.l.file_paths??[]))].slice(0,6);l.length>0&&f.push(` \u2022 Review files that were involved before: ${l.map(e=>`\`${e}\``).join(", ")}`),f.push(" \u2022 Confirm the top failure mode above can't recur in your change"),f.push(" \u2022 Have a rollback ready for any `critical`/`major` step"),f.push("")}return f.push('\u{1F4A1} After you ship: `learn_from_attempts(topic="...", outcome="success", ...)` \u2192 the next plan gets sharper.'),f.join(`
31
- `)}case"brain_marketplace":{const{min_confirms:a=1}=y,o=new URLSearchParams;a&&a>1&&o.set("min_confirms",String(a));const t=await b(`/api/v1/syndication/brains${o.toString()?`?${o}`:""}`);if(!t.brains||t.brains.length===0)return["## \u{1F9E0} Domain Brain Marketplace","","No domain brains are available yet \u2014 the marketplace fills as the community","contributes verified lessons. Be an early contributor:",'`syndicate(topic="k8s:oom-kill", what_worked="raise memory limit + add probe")`'].join(`
32
- `);const i=["## \u{1F9E0} Domain Brain Marketplace",`*${t.count} installable brain${t.count===1?"":"s"} \xB7 curated from the global Knowledge Commons*`,""];for(const c of t.brains){const d=c.curated?"\u2B50 curated":"community";i.push(`### ${c.icon} ${c.name} \`${c.slug}\``,`${c.description}`,`**${c.lesson_count}** lesson${c.lesson_count===1?"":"s"} \xB7 \u{1F91D} ${c.total_confirms} community confirm${c.total_confirms===1?"":"s"} \xB7 ${d}`,`Install: \`brain_install(slug="${c.slug}")\``,"")}return i.push("---","_Installed brains merge into your local Brain and surface in `smart_recall` \u2014 they never override your own lessons._"),i.join(`
33
- `)}case"brain_install":{const{instance_id:a,slug:o,min_confirms:t=1,limit:i=200,dry_run:c=!1}=y,d=typeof o=="string"?o.trim():"";if(!d)throw new C(j.InvalidParams,"slug is required \u2014 run brain_marketplace() to see available domain brains");const p=new URLSearchParams;t&&t>1&&p.set("min_confirms",String(t)),i&&i!==200&&p.set("limit",String(Math.min(Math.max(1,i),500)));const s=await b(`/api/v1/syndication/brains/${encodeURIComponent(d)}${p.toString()?`?${p}`:""}`);if(!s.lessons||s.lessons.length===0)return`No installable lessons found for domain brain \`${d}\`. Run \`brain_marketplace()\` to see what's available.`;if(c)return[`## \u{1F4E6} ${s.name} (DRY RUN)`,`Would install **${s.lessons.length}** lesson${s.lessons.length===1?"":"s"} into your Brain.`,"",...s.lessons.slice(0,15).map(e=>` \u2022 \`${e.topic}\` \xB7 \u{1F91D} ${e.confirm_count}`),s.lessons.length>15?` \u2026and ${s.lessons.length-15} more`:"","",`Run without \`dry_run\` to install: \`brain_install(slug="${d}")\``].filter(Boolean).join(`
34
- `);const n=await k(a),h=`marketplace:${d}`,f=new Date().toISOString();let u=0,l=0;for(const e of s.lessons){if(!e.topic||!e.what_worked){l++;continue}const r=`cachly:lesson:best:${e.topic}`,g=await n.get(r);if(g){const $=v(g,null);if($&&$.source!==h){l++;continue}}const w=(()=>{const $=v(e.tags,[]);return Array.isArray($)?$.filter(S=>typeof S=="string"):[]})(),m=JSON.stringify({topic:e.topic,outcome:e.outcome||"success",what_worked:e.what_worked,what_failed:e.what_failed||"",severity:e.severity||"minor",tags:w,visibility:"team",confidence:I({ts:f,verified_at:f,recall_count:e.confirm_count}),recall_count:0,source:h,ts:f,verified_at:f,version:3});await n.set(r,m);const _=`cachly:lessons:${e.topic}`;await n.rpush(_,m),await n.ltrim(_,-100,-1),await n.expire(_,90*86400),u++}return await n.set(`cachly:stats:born_at:${a}`,f,"EX",365*86400,"NX").catch(()=>{}),[`## \u{1F4E6} Installed: ${s.name}`,"",`**${u}** lesson${u===1?"":"s"} merged into your Brain${l>0?` \xB7 ${l} skipped (your own lessons take priority)`:""}.`,"","They're live in `smart_recall` now \u2014 try a query in this domain:",` \u2022 \`smart_recall(query="${s.lessons[0]?.topic.split(":").pop()??"your problem"}")\``,"",`_Installed lessons are tagged \`source: "${h}"\` and never override your own. Re-run anytime to pull updates._`].join(`
35
- `)}case"brain_conflicts":{const{instance_id:a}=y,o=await k(a),t=[],i=o.scanStream({match:"cachly:ckg:conflict:*",count:100});await new Promise((h,f)=>{i.on("data",u=>t.push(...u)),i.on("end",h),i.on("error",f)});const c=[];if(t.length>0){const h=await o.mget(...t);for(const f of h){const u=v(f??null,null);u&&!u.resolved&&c.push(u)}}const d=[],p=o.scanStream({match:"cachly:agents:active:*",count:100});await new Promise((h,f)=>{p.on("data",u=>d.push(...u)),p.on("end",h),p.on("error",f)});const s=[];if(d.length>0){const h=await o.mget(...d);for(const f of h){const u=v(f??null,null);u&&s.push(u)}}const n=["## \u2694\uFE0F Brain Conflicts & Live Agents",""];if(n.push(`**\u{1F916} Active agents (last 1h):** ${s.length}`),s.length>0)for(const h of s.sort((f,u)=>u.ts.localeCompare(f.ts)).slice(0,10)){const f=Math.round((Date.now()-new Date(h.ts).getTime())/6e4);n.push(` - **${h.author}** \u2014 last: \`${h.last_topic??"?"}\` (${h.last_outcome??"?"}, ${f}m ago)`)}if(n.push(""),c.length===0)return n.push("**\u2705 No unresolved belief conflicts.** The Brain is in consensus."),n.join(`
36
- `);n.push(`**\u26A0\uFE0F Unresolved belief conflicts:** ${c.length}`),n.push(""),n.push("| Topic | Confirmed fix | Contradicted by | Detected |"),n.push("|---|---|---|---|");for(const h of c.sort((f,u)=>u.detected_at.localeCompare(f.detected_at)).slice(0,20)){const f=Math.round((Date.now()-new Date(h.detected_at).getTime())/36e5);n.push(`| \`${h.topic}\` | ${(h.fix_confidence*100).toFixed(0)}% (n=${h.fix_trials}) | ${h.reported_by??"unknown"} | ${f}h ago |`)}return n.push(""),n.push(`_Arbitrate with \`brain_resolve_conflict(instance_id="${a}", topic="<topic>", winner="success"|"failure")\`._`),n.join(`
37
- `)}case"brain_resolve_conflict":{const{instance_id:a,topic:o,winner:t,resolved_by:i="human"}=y;if(!o||!o.trim())throw new C(j.InvalidParams,"topic is required");if(t!=="success"&&t!=="failure")throw new C(j.InvalidParams,'winner must be "success" or "failure"');const c=await k(a),d=M(o),p=`cachly:ckg:conflict:${d}`,s=await c.get(p);if(!s)return`\u{1F4ED} No active conflict found for \`${o}\`. Run \`brain_conflicts(instance_id="${a}")\` to list open conflicts.`;let n=0;if(t==="failure"){const e=await c.smembers(`cachly:ckg:idx:from:${d}`);for(const r of e){const g=await c.get(r);if(!g)continue;const w=v(g,null);!w||w.edgeType!=="fixes"||(w.confidence=.1,await c.set(r,JSON.stringify(w)),n++)}}let h=!1;const f=`cachly:lesson:best:${o}`,u=await c.get(f);if(u){const e=v(u,null);e&&e.outcome===t?e.state==="provisional"&&(e.state="active",e.verified_at=new Date().toISOString(),await c.set(f,JSON.stringify(e))):e&&e.outcome&&e.outcome!==t&&(e.state="archived",e.audit_trail=[...Array.isArray(e.audit_trail)?e.audit_trail:[],{ts:new Date().toISOString(),action:"conflict_loser_archived",resolved_by:i}],await c.set(f,JSON.stringify(e)),h=!0)}const l=v(s,null)??{};return l.resolved=!0,l.winner=t,l.resolved_by=i,l.resolved_at=new Date().toISOString(),await c.set(p,JSON.stringify(l),"EX",3600*24*30),[`## \u2705 Conflict resolved \u2014 \`${o}\``,"",`**Winner:** ${t==="success"?"\u2705 success (fix is valid)":"\u274C failure (fix retired)"}`,`**Resolved by:** ${i}`,"",`- CKG \`fixes\` edges decayed: **${n}**`,`- Losing lesson archived: **${h?"yes":"no"}**`,"",t==="failure"?"_The contradicted fix is retired. smart_recall will stop surfacing it; future attempts start fresh._":"_The fix is reaffirmed. The contradicting failure no longer blocks recall._"].join(`
38
- `)}case"brain_confirm_ci":{const{instance_id:a,job_status:o,topics:t,scan_topics:i=[],source:c="manual"}=y;if(!o||!["success","failure","cancelled"].includes(o))throw new Error("job_status must be success, failure, or cancelled");if(!t?.length)throw new Error("topics is required");if(o==="cancelled")return"\u23ED\uFE0F CI was cancelled \u2014 no confidence changes applied.";let d;try{d=await b(`/api/v1/instances/${a}/ci-outcome`,{method:"POST",body:JSON.stringify({job_status:o,topics:t,scan_topics:i,source:c})})}catch{return"\u26A0\uFE0F Could not reach Brain API \u2014 CI outcome not recorded. Will retry on next call."}if(d.updated===0)return[`\u{1F916} **brain_confirm_ci** \u2014 CI ${o}`,"","No confidence changes (no matching predictions for these topics).",`Topics checked: ${t.slice(0,5).map(s=>`\`${s}\``).join(", ")}${t.length>5?` +${t.length-5} more`:""}`].join(`
39
- `);const p=[`\u{1F916} **brain_confirm_ci** \u2014 CI ${o==="success"?"\u2705":"\u274C"} \xB7 ${d.updated} lesson${d.updated!==1?"s":""} updated`,"","| Topic | Old | New | \u0394 | Reason |","|---|---|---|---|---|"];for(const s of d.confidence_deltas){const n=s.delta>0?"+":"",h=s.reason==="confirmed_failure"?"\u{1F534}":"\u{1F7E1}";p.push(`| \`${s.topic}\` | ${(s.old*100).toFixed(0)}% | ${(s.new*100).toFixed(0)}% | ${n}${(s.delta*100).toFixed(0)}% | ${h} ${s.reason} |`)}return p.push("","_Brain self-calibrated from real CI signal. No manual `learn_from_attempts` needed._"),p.join(`
40
- `)}case"brain_briefing":{const{instance_id:a,event_type:o,context:t,threshold:i}=y;if(!["file_open","pr_open","deploy","manual"].includes(o))throw new Error("event_type must be file_open, pr_open, deploy, or manual");if(!t?.trim())throw new Error("context is required");let c;try{c=await b(`/api/v1/instances/${a}/briefing`,{method:"POST",body:JSON.stringify({event_type:o,context:t,...i!==void 0?{threshold:i}:{}})})}catch{return"\u26A0\uFE0F Could not reach Brain API \u2014 no proactive briefing available right now."}const d=o==="file_open"?"\u{1F4C2}":o==="pr_open"?"\u{1F500}":o==="deploy"?"\u{1F680}":"\u{1F50D}";if(c.warnings.length===0)return[`${d} **brain_briefing** \u2014 ${o} \xB7 \u2705 no known risk patterns matched`,"",`Checked against ${c.matched_lessons} related lesson${c.matched_lessons!==1?"s":""}. You're clear to proceed.`].join(`
41
- `);const p=c.risk_level==="high"?"\u{1F534}":c.risk_level==="medium"?"\u{1F7E1}":"\u{1F7E2}",s=[`${d} **brain_briefing** \u2014 ${o} \xB7 ${p} risk: ${c.risk_level.toUpperCase()}`,"",`The Brain proactively found ${c.warnings.length} known pattern${c.warnings.length!==1?"s":""} that may apply here:`,"","| Topic | Confidence | Severity | What to watch | Known fix |","|---|---|---|---|---|"];for(const n of c.warnings){const h=n.fix?n.fix.length>80?n.fix.slice(0,80)+"\u2026":n.fix:"\u2014";s.push(`| \`${n.topic}\` | ${(n.confidence*100).toFixed(0)}% | ${n.severity} | ${n.message} | ${h} |`)}return s.push("","_Surfaced proactively \u2014 no `smart_recall` needed. Address the highest-confidence items first._"),s.join(`
42
- `)}default:return null}}export{U as SYNDICATE_TOOL_NAMES,J as handleSyndicateTool};
30
+ \`\`\``),(m.depends_on??[]).length>0&&h.push(` \u21B3 depends on: ${(m.depends_on??[]).map(v=>`\`${v}\``).join(", ")}`)}),h.push("")}const u=t.filter(l=>(l.l.file_paths??[]).length>0||(l.l.commands??[]).length>0).slice(0,4);if(u.length>0){h.push("### \u2705 Pre-flight checklist");const l=[...new Set(u.flatMap(n=>n.l.file_paths??[]))].slice(0,6);l.length>0&&h.push(` \u2022 Review files that were involved before: ${l.map(n=>`\`${n}\``).join(", ")}`),h.push(" \u2022 Confirm the top failure mode above can't recur in your change"),h.push(" \u2022 Have a rollback ready for any `critical`/`major` step"),h.push("")}return h.push('\u{1F4A1} After you ship: `learn_from_attempts(topic="...", outcome="success", ...)` \u2192 the next plan gets sharper.'),h.join(`
31
+ `)}case"brain_marketplace":{const{min_confirms:a=1}=y,o=new URLSearchParams;a&&a>1&&o.set("min_confirms",String(a));const e=await $(`/api/v1/syndication/brains${o.toString()?`?${o}`:""}`);if(!e.brains||e.brains.length===0)return["## \u{1F9E0} Domain Brain Marketplace","","No domain brains are available yet \u2014 the marketplace fills as the community","contributes verified lessons. Be an early contributor:",'`syndicate(topic="k8s:oom-kill", what_worked="raise memory limit + add probe")`'].join(`
32
+ `);const r=["## \u{1F9E0} Domain Brain Marketplace",`*${e.count} installable brain${e.count===1?"":"s"} \xB7 curated from the global Knowledge Commons*`,""];for(const c of e.brains){const d=c.curated?"\u2B50 curated":"community";r.push(`### ${c.icon} ${c.name} \`${c.slug}\``,`${c.description}`,`**${c.lesson_count}** lesson${c.lesson_count===1?"":"s"} \xB7 \u{1F91D} ${c.total_confirms} community confirm${c.total_confirms===1?"":"s"} \xB7 ${d}`,`Install: \`brain_install(slug="${c.slug}")\``,"")}return r.push("---","_Installed brains merge into your local Brain and surface in `smart_recall` \u2014 they never override your own lessons._"),r.join(`
33
+ `)}case"brain_install":{const{instance_id:a,slug:o,min_confirms:e=1,limit:r=200,dry_run:c=!1}=y,d=typeof o=="string"?o.trim():"";if(!d)throw new I(P.InvalidParams,"slug is required \u2014 run brain_marketplace() to see available domain brains");const p=new URLSearchParams;e&&e>1&&p.set("min_confirms",String(e)),r&&r!==200&&p.set("limit",String(Math.min(Math.max(1,r),500)));const t=await $(`/api/v1/syndication/brains/${encodeURIComponent(d)}${p.toString()?`?${p}`:""}`);if(!t.lessons||t.lessons.length===0)return`No installable lessons found for domain brain \`${d}\`. Run \`brain_marketplace()\` to see what's available.`;if(c)return[`## \u{1F4E6} ${t.name} (DRY RUN)`,`Would install **${t.lessons.length}** lesson${t.lessons.length===1?"":"s"} into your Brain.`,"",...t.lessons.slice(0,15).map(w=>` \u2022 \`${w.topic}\` \xB7 \u{1F91D} ${w.confirm_count}`),t.lessons.length>15?` \u2026and ${t.lessons.length-15} more`:"","",`Run without \`dry_run\` to install: \`brain_install(slug="${d}")\``].filter(Boolean).join(`
34
+ `);const s=await k(a),f=`marketplace:${d}`,h=new Date().toISOString();let u=0,l=0,n=0,i=0;for(const w of t.lessons){if(!w.topic||!w.what_worked){l++;continue}const g=(()=>{const C=S(w.tags,[]);return Array.isArray(C)?C.filter(N=>typeof N=="string"):[]})(),m=R({topic:w.topic,what_worked:w.what_worked,what_failed:w.what_failed??"",tags:g});m.geschwaerzt.length&&n++,m.verdacht.length&&i++;const _={...w,...m.felder},b=`cachly:lesson:best:${_.topic}`,x=await s.get(b);if(x){const C=S(x,null);if(C&&C.source!==f){l++;continue}}const v=JSON.stringify({topic:_.topic,outcome:_.outcome||"success",what_worked:_.what_worked,what_failed:_.what_failed||"",severity:_.severity||"minor",tags:D(m.felder.tags,m.verdacht),visibility:"team",confidence:M({ts:h,verified_at:h,recall_count:_.confirm_count}),recall_count:0,source:f,ts:h,verified_at:h,version:3});await s.set(b,v);const j=`cachly:lessons:${_.topic}`;await s.rpush(j,v),await s.ltrim(j,-100,-1),await s.expire(j,90*86400),u++}return await s.set(`cachly:stats:born_at:${a}`,h,"EX",365*86400,"NX").catch(()=>{}),[`## \u{1F4E6} Installed: ${t.name}`,"",`**${u}** lesson${u===1?"":"s"} merged into your Brain${l>0?` \xB7 ${l} skipped (your own lessons take priority)`:""}.`,"","They're live in `smart_recall` now \u2014 try a query in this domain:",` \u2022 \`smart_recall(query="${t.lessons[0]?.topic.split(":").pop()??"your problem"}")\``,"",`_Installed lessons are tagged \`source: "${f}"\` and never override your own. Re-run anytime to pull updates._`,...n+i>0?["",...A(n,i,`${t.lessons.length} Lektionen`)]:[]].join(`
35
+ `)}case"brain_conflicts":{const{instance_id:a}=y,o=await k(a),e=[],r=o.scanStream({match:"cachly:ckg:conflict:*",count:100});await new Promise((f,h)=>{r.on("data",u=>e.push(...u)),r.on("end",f),r.on("error",h)});const c=[];if(e.length>0){const f=await o.mget(...e);for(const h of f){const u=S(h??null,null);u&&!u.resolved&&c.push(u)}}const d=[],p=o.scanStream({match:"cachly:agents:active:*",count:100});await new Promise((f,h)=>{p.on("data",u=>d.push(...u)),p.on("end",f),p.on("error",h)});const t=[];if(d.length>0){const f=await o.mget(...d);for(const h of f){const u=S(h??null,null);u&&t.push(u)}}const s=["## \u2694\uFE0F Brain Conflicts & Live Agents",""];if(s.push(`**\u{1F916} Active agents (last 1h):** ${t.length}`),t.length>0)for(const f of t.sort((h,u)=>u.ts.localeCompare(h.ts)).slice(0,10)){const h=Math.round((Date.now()-new Date(f.ts).getTime())/6e4);s.push(` - **${f.author}** \u2014 last: \`${f.last_topic??"?"}\` (${f.last_outcome??"?"}, ${h}m ago)`)}if(s.push(""),c.length===0)return s.push("**\u2705 No unresolved belief conflicts.** The Brain is in consensus."),s.join(`
36
+ `);s.push(`**\u26A0\uFE0F Unresolved belief conflicts:** ${c.length}`),s.push(""),s.push("| Topic | Confirmed fix | Contradicted by | Detected |"),s.push("|---|---|---|---|");for(const f of c.sort((h,u)=>u.detected_at.localeCompare(h.detected_at)).slice(0,20)){const h=Math.round((Date.now()-new Date(f.detected_at).getTime())/36e5);s.push(`| \`${f.topic}\` | ${(f.fix_confidence*100).toFixed(0)}% (n=${f.fix_trials}) | ${f.reported_by??"unknown"} | ${h}h ago |`)}return s.push(""),s.push(`_Arbitrate with \`brain_resolve_conflict(instance_id="${a}", topic="<topic>", winner="success"|"failure")\`._`),s.join(`
37
+ `)}case"brain_resolve_conflict":{const{instance_id:a,topic:o,winner:e,resolved_by:r="human"}=y;if(!o||!o.trim())throw new I(P.InvalidParams,"topic is required");if(e!=="success"&&e!=="failure")throw new I(P.InvalidParams,'winner must be "success" or "failure"');const c=await k(a),d=B(o),p=`cachly:ckg:conflict:${d}`,t=await c.get(p);if(!t)return`\u{1F4ED} No active conflict found for \`${o}\`. Run \`brain_conflicts(instance_id="${a}")\` to list open conflicts.`;let s=0;if(e==="failure"){const n=await c.smembers(`cachly:ckg:idx:from:${d}`);for(const i of n){const w=await c.get(i);if(!w)continue;const g=S(w,null);!g||g.edgeType!=="fixes"||(g.confidence=.1,await c.set(i,JSON.stringify(g)),s++)}}let f=!1;const h=`cachly:lesson:best:${o}`,u=await c.get(h);if(u){const n=S(u,null);n&&n.outcome===e?n.state==="provisional"&&(n.state="active",n.verified_at=new Date().toISOString(),await c.set(h,JSON.stringify(n))):n&&n.outcome&&n.outcome!==e&&(n.state="archived",n.audit_trail=[...Array.isArray(n.audit_trail)?n.audit_trail:[],{ts:new Date().toISOString(),action:"conflict_loser_archived",resolved_by:r}],await c.set(h,JSON.stringify(n)),f=!0)}const l=S(t,null)??{};return l.resolved=!0,l.winner=e,l.resolved_by=r,l.resolved_at=new Date().toISOString(),await c.set(p,JSON.stringify(l),"EX",3600*24*30),[`## \u2705 Conflict resolved \u2014 \`${o}\``,"",`**Winner:** ${e==="success"?"\u2705 success (fix is valid)":"\u274C failure (fix retired)"}`,`**Resolved by:** ${r}`,"",`- CKG \`fixes\` edges decayed: **${s}**`,`- Losing lesson archived: **${f?"yes":"no"}**`,"",e==="failure"?"_The contradicted fix is retired. smart_recall will stop surfacing it; future attempts start fresh._":"_The fix is reaffirmed. The contradicting failure no longer blocks recall._"].join(`
38
+ `)}case"brain_confirm_ci":{const{instance_id:a,job_status:o,topics:e,scan_topics:r=[],source:c="manual"}=y;if(!o||!["success","failure","cancelled"].includes(o))throw new Error("job_status must be success, failure, or cancelled");if(!e?.length)throw new Error("topics is required");if(o==="cancelled")return"\u23ED\uFE0F CI was cancelled \u2014 no confidence changes applied.";let d;try{d=await $(`/api/v1/instances/${a}/ci-outcome`,{method:"POST",body:JSON.stringify({job_status:o,topics:e,scan_topics:r,source:c})})}catch{return"\u26A0\uFE0F Could not reach Brain API \u2014 CI outcome not recorded. Will retry on next call."}if(d.updated===0)return[`\u{1F916} **brain_confirm_ci** \u2014 CI ${o}`,"","No confidence changes (no matching predictions for these topics).",`Topics checked: ${e.slice(0,5).map(t=>`\`${t}\``).join(", ")}${e.length>5?` +${e.length-5} more`:""}`].join(`
39
+ `);const p=[`\u{1F916} **brain_confirm_ci** \u2014 CI ${o==="success"?"\u2705":"\u274C"} \xB7 ${d.updated} lesson${d.updated!==1?"s":""} updated`,"","| Topic | Old | New | \u0394 | Reason |","|---|---|---|---|---|"];for(const t of d.confidence_deltas){const s=t.delta>0?"+":"",f=t.reason==="confirmed_failure"?"\u{1F534}":"\u{1F7E1}";p.push(`| \`${t.topic}\` | ${(t.old*100).toFixed(0)}% | ${(t.new*100).toFixed(0)}% | ${s}${(t.delta*100).toFixed(0)}% | ${f} ${t.reason} |`)}return p.push("","_Brain self-calibrated from real CI signal. No manual `learn_from_attempts` needed._"),p.join(`
40
+ `)}case"brain_briefing":{const{instance_id:a,event_type:o,context:e,threshold:r}=y;if(!["file_open","pr_open","deploy","manual"].includes(o))throw new Error("event_type must be file_open, pr_open, deploy, or manual");if(!e?.trim())throw new Error("context is required");let c;try{c=await $(`/api/v1/instances/${a}/briefing`,{method:"POST",body:JSON.stringify({event_type:o,context:e,...r!==void 0?{threshold:r}:{}})})}catch{return"\u26A0\uFE0F Could not reach Brain API \u2014 no proactive briefing available right now."}const d=o==="file_open"?"\u{1F4C2}":o==="pr_open"?"\u{1F500}":o==="deploy"?"\u{1F680}":"\u{1F50D}";if(c.warnings.length===0)return[`${d} **brain_briefing** \u2014 ${o} \xB7 \u2705 no known risk patterns matched`,"",`Checked against ${c.matched_lessons} related lesson${c.matched_lessons!==1?"s":""}. You're clear to proceed.`].join(`
41
+ `);const p=c.risk_level==="high"?"\u{1F534}":c.risk_level==="medium"?"\u{1F7E1}":"\u{1F7E2}",t=[`${d} **brain_briefing** \u2014 ${o} \xB7 ${p} risk: ${c.risk_level.toUpperCase()}`,"",`The Brain proactively found ${c.warnings.length} known pattern${c.warnings.length!==1?"s":""} that may apply here:`,"","| Topic | Confidence | Severity | What to watch | Known fix |","|---|---|---|---|---|"];for(const s of c.warnings){const f=s.fix?s.fix.length>80?s.fix.slice(0,80)+"\u2026":s.fix:"\u2014";t.push(`| \`${s.topic}\` | ${(s.confidence*100).toFixed(0)}% | ${s.severity} | ${s.message} | ${f} |`)}return t.push("","_Surfaced proactively \u2014 no `smart_recall` needed. Address the highest-confidence items first._"),t.join(`
42
+ `)}default:return null}}export{V as SYNDICATE_TOOL_NAMES,Q as handleSyndicateTool};