@cachly-dev/mcp-server 0.10.184 → 0.10.186
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 +6 -6
- package/dist/src/autor.js +1 -1
- package/dist/src/brain-watch-hook.js +7 -7
- package/dist/src/browser-adresse.js +1 -0
- package/dist/src/cls-hook.js +6 -6
- package/dist/src/embeddings.js +2 -2
- package/dist/src/git-ohne-shell.js +1 -0
- package/dist/src/handlers/brain.js +60 -60
- package/dist/src/handlers/cache.js +28 -32
- package/dist/src/handlers/fedbrain.js +38 -38
- package/dist/src/index.js +129 -129
- package/glama.json +1 -1
- package/hooks/cachly-ambient-einblendung.mjs +11 -11
- package/package.json +4 -3
- package/server.json +3 -3
|
@@ -1,59 +1,55 @@
|
|
|
1
|
-
import{randomUUID as
|
|
1
|
+
import{randomUUID as P}from"node:crypto";import{McpError as V,ErrorCode as Y}from"@modelcontextprotocol/sdk/types.js";import{readdir as W,stat as z,readFile as G}from"node:fs/promises";import{join as Q,relative as Z,extname as ee}from"node:path";import{computeEmbedding as R,hasEmbedProvider as U,embedProviderHint as J}from"../embeddings.js";import{einbettTakt as te}from"../einbett-takt.js";import{detectNamespace as K}from"../namespace.js";import{simpleHash as se}from"../confidence.js";import{scanKeys as ae}from"../utils.js";import{cachlyUrl as X}from"../cachly-url.js";const _e=new Set(["cache_get","cache_set","cache_delete","cache_exists","cache_ttl","cache_keys","cache_stats","semantic_search","detect_namespace","cache_warmup","index_project","cache_mset","cache_mget","cache_lock_acquire","cache_lock_release","cache_stream_set","cache_stream_get","cache_org_stats","set_cost_per_call"]);async function $e(F,u,f,E){switch(F){case"cache_get":{const{instance_id:n,key:e,org_id:a}=u,t=await f(n);let s=await t.get(e),i="direct";if(s===null&&a){const r=`org:${a}:sem:${e}`;s=await t.get(r),s!==null&&(i=`org:${a}:sem`)}if(s===null)return`Key \`${e}\` \u2192 **not found** (null)`;let c=s;try{c=JSON.stringify(JSON.parse(s),null,2)}catch{}const o=i!=="direct"?` _(from shared org namespace \`${i}\`)_`:"";return`Key \`${e}\`:${o}
|
|
2
2
|
\`\`\`
|
|
3
3
|
${c}
|
|
4
|
-
\`\`\``}case"cache_set":{const{instance_id:n,key:e,value:a,ttl:t,org_id:s}=
|
|
4
|
+
\`\`\``}case"cache_set":{const{instance_id:n,key:e,value:a,ttl:t,org_id:s}=u,i=await f(n);return t&&t>0?(await i.set(e,a,"EX",t),s&&await i.set(`org:${s}:sem:${e}`,a,"EX",t),`\u2705 Set \`${e}\` (TTL: ${t}s)${s?` + shared to \`org:${s}:sem\``:""}`):(await i.set(e,a),s&&await i.set(`org:${s}:sem:${e}`,a),`\u2705 Set \`${e}\` (no expiry)${s?` + shared to \`org:${s}:sem\``:""}`)}case"cache_delete":{const{instance_id:n,keys:e}=u;return`\u2705 Deleted **${await(await f(n)).del(...e)}** of ${e.length} key(s): ${e.map(s=>`\`${s}\``).join(", ")}`}case"cache_exists":{const{instance_id:n,keys:e}=u;return`**${await(await f(n)).exists(...e)}** of ${e.length} key(s) exist in cache.`}case"cache_ttl":{const{instance_id:n,key:e}=u,t=await(await f(n)).ttl(e);if(t===-2)return`Key \`${e}\` \u2192 **does not exist**`;if(t===-1)return`Key \`${e}\` \u2192 **no expiry** (persists forever)`;const s=Math.floor(t/60),i=t%60;return`Key \`${e}\` \u2192 TTL: **${t}s** (${s}m ${i}s remaining)`}case"cache_keys":{const{instance_id:n,pattern:e="*",count:a=50}=u,t=Math.min(a,500),s=await f(n),i=[],c=s.scanStream({match:e,count:100});await new Promise((r,_)=>{c.on("data",d=>{i.push(...d),i.length>=t&&(c.destroy(),r())}),c.on("end",r),c.on("error",_)});const o=i.slice(0,t);return o.length===0?`No keys found matching pattern \`${e}\`.`:[`Found **${o.length}** key(s) matching \`${e}\`:`,...o.map(r=>` \u2022 \`${r}\``),o.length===t?`
|
|
5
5
|
_(showing first ${t} \u2014 narrow pattern to see more)_`:""].filter(Boolean).join(`
|
|
6
|
-
`)}case"cache_stats":{const{instance_id:n}=
|
|
7
|
-
]+)`))?.[1]?.trim()??"n/a",c=i(a,"used_memory_human"),o=i(a,"used_memory_peak_human"),r=i(t,"keyspace_hits"),
|
|
8
|
-
`).filter(w=>w.startsWith("db")).map(w=>` ${w.trim()}`),p=[`\u{1F4CA} **Cache Stats for instance \`${n}\`:**`,"",` \u{1F4BE} Memory used: ${c} (peak: ${o})`,` \u26A1 Ops/sec: ${d}`,` \u{1F3AF} Hit rate: ${x}% (${r} hits / ${
|
|
6
|
+
`)}case"cache_stats":{const{instance_id:n}=u,e=await f(n),[a,t,s]=await Promise.all([e.info("memory"),e.info("stats"),e.info("keyspace")]),i=(w,L)=>w.match(new RegExp(`${L}:([^\r
|
|
7
|
+
]+)`))?.[1]?.trim()??"n/a",c=i(a,"used_memory_human"),o=i(a,"used_memory_peak_human"),r=i(t,"keyspace_hits"),_=i(t,"keyspace_misses"),d=i(t,"instantaneous_ops_per_sec"),h=(await e.info("clients")).match(/connected_clients:(\d+)/)?.[1]??"n/a",y=parseInt(r)||0,g=parseInt(_)||0,T=y+g,x=T>0?(y/T*100).toFixed(1):"n/a",v=s.split(`
|
|
8
|
+
`).filter(w=>w.startsWith("db")).map(w=>` ${w.trim()}`),p=[`\u{1F4CA} **Cache Stats for instance \`${n}\`:**`,"",` \u{1F4BE} Memory used: ${c} (peak: ${o})`,` \u26A1 Ops/sec: ${d}`,` \u{1F3AF} Hit rate: ${x}% (${r} hits / ${_} misses)`,` \u{1F517} Clients: ${h}`,"",v.length>0?` \u{1F5C2}\uFE0F Keyspace:
|
|
9
9
|
${v.join(`
|
|
10
|
-
`)}`:" \u{1F5C2}\uFE0F Keyspace: (empty)"];try{const w=await
|
|
11
|
-
`)}case"semantic_search":{const{instance_id:n,query:e,threshold:a=.82,namespace:t="cachly:sem",top_k:s=5,use_hybrid:i=!1,auto_namespace:c=!1}=
|
|
10
|
+
`)}`:" \u{1F5C2}\uFE0F Keyspace: (empty)"];try{const w=await E(`/api/v1/instances/${n}`);if(w.vector_token){const L=process.env.CACHLY_VECTOR_URL??"https://api.cachly.dev",C=await fetch(`${L}/v1/sem/${w.vector_token}/stats`,{signal:AbortSignal.timeout(5e3)});if(C.ok){const m=await C.json(),b=(l,$=2)=>l!==void 0?l.toLocaleString("en-US",{minimumFractionDigits:$,maximumFractionDigits:$}):"n/a",O=l=>l!==void 0?l.toLocaleString("en-US"):"n/a",k=m.total_hits??0,S=m.total_entries??0;if(k===0&&S===0){const l=$=>($*50*.25*.002*30).toFixed(2);p.push("","\u{1F4B0} **Tokenmaxxing ROI \u2014 Projection:**"," \u{1F4ED} No cache hits yet \u2014 you're just getting started.",""," \u{1F4CA} Typical savings for your team size:",` 5 devs \xD7 50 LLM calls/day \xD7 25% hit-rate \u2192 ~$${l(5)}/month`,` 10 devs \xD7 50 LLM calls/day \xD7 25% hit-rate \u2192 ~$${l(10)}/month`,` 20 devs \xD7 50 LLM calls/day \xD7 25% hit-rate \u2192 ~$${l(20)}/month`," (Assumes avg $0.002/call saved per cache hit)",""," \u{1F680} Next: route LLM calls through cachly to start accumulating hits.",` Docs: ${X("/docs/semantic","cache-stats")}`)}else{const l=m.savings?.week_over_week_pct,$=l!==void 0?` ${l>=0?"\u{1F4C8}":"\u{1F4C9}"} 7d trend: ${l>=0?"+":""}${l.toFixed(1)}% vs prev week`:"";p.push("","\u{1F4B0} **Tokenmaxxing ROI:**",` \u{1F4E6} Semantic entries: ${O(m.total_entries)}`,` \u{1F3AF} Total cache hits: ${O(m.total_hits)}`,` \u23F1\uFE0F Hits last 24h: ${O(m.savings?.hits_last_24h)}`,` \u{1F4C5} Hits last 7d: ${O(m.savings?.hits_last_7d)}`,...$?[$]:[],` \u{1F4B5} Total saved: $${b(m.savings?.estimated_total_saved_usd)}`,` \u{1F4C8} Projected/month: $${b(m.savings?.estimated_monthly_saved_usd)}`,` \u{1F4CA} Avg per hit: $${b(m.savings?.avg_cost_per_call_usd,4)}`)}m.top_hits&&m.top_hits.length>0&&(p.push("","\u{1F51D} Top cached prompts:"),m.top_hits.slice(0,3).forEach(($,j)=>{const N=$.prompt.length>50?`${$.prompt.slice(0,50)}\u2026`:$.prompt;p.push(` ${j+1}. "${N}" (hit ${$.hit_count}\xD7)`)}))}}}catch{}return p.join(`
|
|
11
|
+
`)}case"semantic_search":{const{instance_id:n,query:e,threshold:a=.82,namespace:t="cachly:sem",top_k:s=5,use_hybrid:i=!1,auto_namespace:c=!1}=u,o=c?K(e):t;if(!U())return`\u274C semantic_search requires an embedding provider.
|
|
12
12
|
|
|
13
|
-
Current: ${
|
|
13
|
+
Current: ${J()}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
COHERE_API_KEY (provider: cohere)
|
|
19
|
-
GEMINI_API_KEY (provider: gemini)
|
|
20
|
-
OLLAMA_BASE_URL (provider: ollama \u2013 local, no key needed)
|
|
21
|
-
Also set: CACHLY_EMBED_PROVIDER=<provider>`;const r=await b(`/api/v1/instances/${n}`);if(!r.vector_token)return`\u274C Semantic search is only available on Speed and Business tiers.
|
|
15
|
+
Easiest: sign in (CACHLY_JWT). Embeddings then run on the cachly servers in the EU, no extra key.
|
|
16
|
+
Or set OLLAMA_BASE_URL to use a local model (no key needed).
|
|
17
|
+
Your own key with a third-party provider works only if you name the provider yourself: CACHLY_EMBED_PROVIDER=<openai|gemini|mistral|cohere> plus its API key. The text is then sent to that provider.`;const r=await E(`/api/v1/instances/${n}`);if(!r.vector_token)return`\u274C Semantic search is only available on Speed and Business tiers.
|
|
22
18
|
|
|
23
19
|
Your instance "${r.name}" is on the **${r.tier.toUpperCase()}** tier.
|
|
24
|
-
Upgrade at ${
|
|
20
|
+
Upgrade at ${X(`/instances/${n}`,"upgrade")}`;const _=await R(e),d=process.env.CACHLY_VECTOR_URL??`https://api.cachly.dev/v1/sem/${r.vector_token}`,h={embedding:_,namespace:o,threshold:a,top_k:s};i&&(h.hybrid=!0,h.prompt=e);const y=await fetch(`${d}/search`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h),signal:AbortSignal.timeout(8e3)});if(!y.ok)throw new V(Y.InternalError,`Vector search failed: ${y.statusText}`);const g=await y.json();if(!g.length||g.length===1&&!g[0].found)return`\u{1F50D} No semantically similar entries found for:
|
|
25
21
|
_"${e}"_
|
|
26
22
|
|
|
27
23
|
Try lowering the threshold (current: ${a}) or using different keywords.`;const T=await f(n),x=[`\u{1F50D} **Semantic search results** for: _"${e}"_`,` Threshold: ${a} \xB7 Namespace: \`${o}\``,""];for(const v of g){if(!v.found||!v.id)continue;const p=await T.get(`${o}:val:${v.id}`);x.push(`**Match** (similarity: ${((v.similarity??0)*100).toFixed(1)}%)`,` Prompt: _"${v.prompt??"(unknown)"}"_`,p?` Value: \`${p.slice(0,200)}${p.length>200?"\u2026":""}\``:" Value: _(evicted from cache)_","")}return x.join(`
|
|
28
|
-
`)}case"detect_namespace":{const{prompt:n}=
|
|
29
|
-
`)}case"cache_warmup":{const{instance_id:n,entries:e,namespace:a="cachly:sem",ttl:t,auto_namespace:s=!1}=
|
|
24
|
+
`)}case"detect_namespace":{const{prompt:n}=u,e=K(n),a=e.split(":").pop(),t={code:"\u{1F4BB} Code \u2014 contains programming constructs or syntax",translation:"\u{1F310} Translation \u2014 asks to translate between languages",summary:"\u{1F4DD} Summary \u2014 requests a summary or key points (TL;DR)",qa:"\u2753 Q&A \u2014 a direct question or query",creative:"\u{1F3A8} Creative \u2014 general, creative, or conversational prompt"};return[`**Detected namespace:** \`${e}\``,`**Type:** ${t[a]??a}`,"",`_Prompt: "${n.slice(0,120)}${n.length>120?"\u2026":""}"_`,"","\u{1F4A1} Use this namespace in `semantic_search` or `cache_warmup` for better hit rates."," Set `auto_namespace: true` to apply this detection automatically."].join(`
|
|
25
|
+
`)}case"cache_warmup":{const{instance_id:n,entries:e,namespace:a="cachly:sem",ttl:t,auto_namespace:s=!1}=u;if(!U())return`\u274C cache_warmup requires an embedding provider.
|
|
30
26
|
|
|
31
|
-
Current: ${
|
|
27
|
+
Current: ${J()}
|
|
32
28
|
|
|
33
29
|
Supported: openai (default) \xB7 mistral \xB7 cohere \xB7 ollama (local) \xB7 gemini
|
|
34
|
-
Set CACHLY_EMBED_PROVIDER and the matching API key env var.`;const i=await
|
|
35
|
-
`)}case"index_project":{const{instance_id:n,dir:e,extensions:a,max_files:t=100,ttl:s=86400,summary_chars:i=1200,namespace:c="cachly:sem:code",hintergrund:o=!1}=
|
|
36
|
-
Extensions checked: ${[...r].join(", ")}`;const h=await
|
|
37
|
-
${
|
|
38
|
-
${
|
|
39
|
-
`)}case"cache_mset":{const{instance_id:n,items:e}=
|
|
30
|
+
Set CACHLY_EMBED_PROVIDER and the matching API key env var.`;const i=await E(`/api/v1/instances/${n}`),c=process.env.CACHLY_VECTOR_URL??(i.vector_token?`https://api.cachly.dev/v1/sem/${i.vector_token}`:null),o=await f(n);let r=0,_=0;const d=[];for(const h of e){const y=h.namespace??(s?K(h.prompt):a),g=await R(h.prompt);let T=!1;if(c){const p=await fetch(`${c}/search`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({embedding:g,namespace:y,threshold:.98}),signal:AbortSignal.timeout(8e3)}).catch(()=>null);p?.ok&&(T=(await p.json())[0]?.found??!1)}if(T){_++,d.push(` \u23ED\uFE0F _"${h.prompt.slice(0,60)}${h.prompt.length>60?"\u2026":""}"_ \u2192 already cached`);continue}const x=P(),v=`${y}:val:${x}`;if(t&&t>0?await o.set(v,h.value,"EX",t):await o.set(v,h.value),c){const p={id:x,prompt:h.prompt,namespace:y,embedding:g};t&&t>0&&(p.expires_at=new Date(Date.now()+t*1e3).toISOString()),await fetch(`${c}/entries`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p),signal:AbortSignal.timeout(8e3)}).catch(()=>{})}else{const p=`${y}:emb:${x}`,w=JSON.stringify({embedding:g,prompt:h.prompt});t&&t>0?await o.set(p,w,"EX",t):await o.set(p,w)}r++,d.push(` \u2705 _"${h.prompt.slice(0,60)}${h.prompt.length>60?"\u2026":""}"_ \u2192 \`${y}\``)}return["\u{1F525} **Cache Warmup Complete**","",` \u2705 Warmed: **${r}** new entries`,` \u23ED\uFE0F Skipped: **${_}** (already cached at \u2265 0.98 similarity)`,` \u{1F4E6} Total: ${e.length}`,s?" \u{1F3F7}\uFE0F Namespacing: auto-detected per prompt":` \u{1F3F7}\uFE0F Namespace: \`${a}\``,c?" \u{1F50D} Mode: pgvector HNSW (Speed/Business tier)":" \u{1F50D} Mode: Valkey SCAN (upgrade to Speed tier for scalable search)","",...d].join(`
|
|
31
|
+
`)}case"index_project":{const{instance_id:n,dir:e,extensions:a,max_files:t=100,ttl:s=86400,summary_chars:i=1200,namespace:c="cachly:sem:code",hintergrund:o=!1}=u,r=new Set((a??["ts","js","tsx","jsx","go","py","java","rs","md","kt","swift"]).map(k=>k.startsWith(".")?k:`.${k}`)),_=[];async function d(k){if(_.length>=t)return;const S=await W(k,{withFileTypes:!0}).catch(()=>null);if(S)for(const l of S){if(_.length>=t)break;const $=Q(k,l.name);if(l.isDirectory()){if([".git","node_modules","dist","build",".next","__pycache__","vendor"].includes(l.name))continue;await d($)}else l.isFile()&&r.has(ee(l.name).toLowerCase())&&_.push($)}}if(await d(e),_.length===0)return`\u274C No matching files found in \`${e}\`.
|
|
32
|
+
Extensions checked: ${[...r].join(", ")}`;const h=await E(`/api/v1/instances/${n}`),y=process.env.CACHLY_VECTOR_URL??(h.vector_token?`https://api.cachly.dev/v1/sem/${h.vector_token}`:null),g=y&&U();let T=0,x=0,v=0,p=0,w=0;const L=[],C=new Date(Date.now()+s*1e3).toISOString(),m=await f(n),b=te({hintergrund:o});for(const k of _){const S=Z(e,k);let l,$;try{const A=await z(k);if(A.size>2e5){x++;continue}$=A.size,l=await G(k,"utf-8")}catch{v++;continue}const j=`cachly:idx:hash:${S}`,N=`${$}:${l.length}:${se(l)}`;if(await m.get(j)===N){const A=`cachly:idx:${S}`;s>0&&await m.expire(A,s),s>0&&await m.expire(j,s),w++;continue}const H=l.slice(0,i).replace(/\s+/g," ").trim(),M=`cachly:idx:${S}`,I=`File: ${S}
|
|
33
|
+
${H}`;if(s>0?await m.set(M,I,"EX",s):await m.set(M,I),s>0?await m.set(j,N,"EX",s):await m.set(j,N),T++,L.push(` \u2705 ${S}`),g&&b.darf())try{const A=`File: ${S}
|
|
34
|
+
${H}`;await b.warte();const B=await R(A).catch(q=>{throw b.fehler(q),q}),D=P();await fetch(`${y}/entries`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:D,prompt:A,namespace:c,embedding:B,expires_at:C}),signal:AbortSignal.timeout(8e3)}),await m.set(`${c}:val:${D}`,S,"EX",s),p++}catch{}}return[`\u{1F4C2} **index_project Complete** \u2014 ${g?"\u{1F50D} Keyword + \u{1F3AF} Semantic":"\u{1F50D} Keyword only (no embedding provider)"}`,"",` \u{1F4C1} Dir: ${e}`,` \u2705 Indexed: **${T}** files (new/changed)`,` \u267B\uFE0F Unchanged: ${w} files (hash match \u2014 skipped)`,...g?[` \u{1F3AF} Semantic: **${p}** files (vector-searchable)`]:[],` \u23ED\uFE0F Skipped: ${x} (too large or filtered)`,` \u274C Errors: ${v}`,` \u23F1\uFE0F TTL: ${s}s (${Math.round(s/3600)}h)`,"","\u{1F4A1} **Next steps:**",' 1. Use `smart_recall("how does auth work")` to find relevant files.'," 2. Re-run index_project after major refactors.",...g?[]:[" 3. Sign in (CACHLY_JWT) or set OLLAMA_BASE_URL to also enable semantic search."],"",...L.length<=20?L:[...L.slice(0,20),` \u2026 and ${L.length-20} more`]].join(`
|
|
35
|
+
`)}case"cache_mset":{const{instance_id:n,items:e}=u;if(!Array.isArray(e)||e.length===0)return"\u26A0\uFE0F No items provided.";const t=(await f(n)).pipeline();for(const s of e){const i=typeof s.value=="string"?s.value:JSON.stringify(s.value);s.ttl&&s.ttl>0?t.set(s.key,i,"EX",s.ttl):t.set(s.key,i)}return await t.exec(),`\u2705 **cache_mset** \u2013 ${e.length} key(s) written in one pipeline round-trip.
|
|
40
36
|
`+e.map(s=>` \u2022 \`${s.key}\`${s.ttl?` (TTL ${s.ttl}s)`:""}`).join(`
|
|
41
|
-
`)}case"cache_mget":{const{instance_id:n,keys:e}=
|
|
37
|
+
`)}case"cache_mget":{const{instance_id:n,keys:e}=u;if(!Array.isArray(e)||e.length===0)return"\u26A0\uFE0F No keys provided.";const t=await(await f(n)).mget(...e),s=e.map((i,c)=>{const o=t[c];return o===null?` \u2022 \`${i}\`: _null (miss)_`:` \u2022 \`${i}\`: ${o}`});return`\u2705 **cache_mget** \u2013 ${e.length} key(s) fetched in one round-trip.
|
|
42
38
|
`+s.join(`
|
|
43
|
-
`)}case"cache_lock_acquire":{const{instance_id:n,key:e,ttl_ms:a=5e3,retries:t=3,retry_delay_ms:s=50}=
|
|
39
|
+
`)}case"cache_lock_acquire":{const{instance_id:n,key:e,ttl_ms:a=5e3,retries:t=3,retry_delay_ms:s=50}=u,i=await f(n),c=`cachly:lock:${e}`,o=P();for(let r=0;r<=t;r++){if(await i.set(c,o,"PX",a,"NX")==="OK")return`\u{1F512} **cache_lock_acquire** \u2013 Lock acquired!
|
|
44
40
|
|
|
45
41
|
Key: \`${e}\`
|
|
46
42
|
Token: \`${o}\`
|
|
47
43
|
TTL: ${a} ms
|
|
48
44
|
|
|
49
|
-
\u{1F4A1} Use **cache_lock_release** with this token to release early.`;r<t&&await new Promise(d=>setTimeout(d,s))}return`\u274C **cache_lock_acquire** \u2013 Could not acquire lock for \`${e}\` after ${t+1} attempts.`}case"cache_lock_release":{const{instance_id:n,key:e,token:a}=
|
|
45
|
+
\u{1F4A1} Use **cache_lock_release** with this token to release early.`;r<t&&await new Promise(d=>setTimeout(d,s))}return`\u274C **cache_lock_acquire** \u2013 Could not acquire lock for \`${e}\` after ${t+1} attempts.`}case"cache_lock_release":{const{instance_id:n,key:e,token:a}=u;return await(await f(n)).eval('if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end',1,`cachly:lock:${e}`,a)===1?`\u{1F513} **cache_lock_release** \u2013 Lock \`${e}\` released.`:`\u26A0\uFE0F **cache_lock_release** \u2013 Lock \`${e}\` expired or token mismatch.`}case"cache_stream_set":{const{instance_id:n,key:e,chunks:a,ttl:t}=u;if(!Array.isArray(a)||a.length===0)return"\u26A0\uFE0F No chunks provided.";const s=await f(n),i=`cachly:stream:${e}`;await s.del(i);const c=s.pipeline();for(const o of a)c.rpush(i,o);return t&&t>0&&c.expire(i,t),await c.exec(),`\u2705 **cache_stream_set** \u2013 ${a.length} chunk(s) stored.
|
|
50
46
|
Key: \`${e}\`
|
|
51
47
|
${t?` TTL: ${t}s
|
|
52
|
-
`:""} Total size: ${a.reduce((o,r)=>o+r.length,0)} chars`}case"cache_stream_get":{const{instance_id:n,key:e}=
|
|
48
|
+
`:""} Total size: ${a.reduce((o,r)=>o+r.length,0)} chars`}case"cache_stream_get":{const{instance_id:n,key:e}=u,a=await f(n),t=`cachly:stream:${e}`,s=await a.llen(t);if(s===0)return`\u26A0\uFE0F **cache_stream_get** \u2013 Cache miss for key \`${e}\`.`;const c=(await a.lrange(t,0,-1)).join(""),o=c.slice(0,500);return`\u2705 **cache_stream_get** \u2013 ${s} chunk(s) retrieved for \`${e}\`.
|
|
53
49
|
|
|
54
50
|
**Preview** (first 500 chars):
|
|
55
51
|
\`\`\`
|
|
56
52
|
${o}${o.length<c.length?"\u2026":""}
|
|
57
|
-
\`\`\``}case"cache_org_stats":{const{instance_id:n,org_id:e}=
|
|
58
|
-
`)}case"set_cost_per_call":{const{instance_id:n,cost_per_call_usd:e}=
|
|
59
|
-
`)}default:return null}}export{
|
|
53
|
+
\`\`\``}case"cache_org_stats":{const{instance_id:n,org_id:e}=u,a=await f(n),t=`org:${e}:sem`,i=(await ae(a,`${t}:*`,{max:1e4,timeoutMs:5e3})).length,c=[`\u{1F3E2} Org Cache Stats for org \`${e}\`:`,` \u{1F4E6} Shared entries: ${i}`,` \u{1F511} Namespace: ${t}`," \u{1F465} Benefit: All instances sharing this org_id serve from the same cache","",`\u{1F4A1} To enable sharing: set org_id="${e}" in cache_set calls`];try{const o=await E(`/api/v1/orgs/${e}/savings`),r=d=>`$${(d??0).toFixed(2)}`;c.push("","\u{1F4B0} Org-wide Tokenmaxxing ROI:",` \u{1F5A5}\uFE0F Instances: ${o.instance_count}`,` \u{1F3AF} Total cache hits: ${o.total_hits.toLocaleString("en-US")}`,` \u23F1\uFE0F Hits last 24h: ${o.hits_last_24h.toLocaleString("en-US")}`,` \u{1F4B5} Total saved: ${r(o.estimated_total_saved_usd)}`,` \u{1F4C8} Projected/month: ${r(o.estimated_monthly_saved_usd)}`);const _=[...o.per_instance??[]].sort((d,h)=>h.estimated_total_saved_usd-d.estimated_total_saved_usd).slice(0,5);if(_.length>0){c.push(""," Top instances by savings:");for(const d of _)c.push(` \u2022 ${d.name||d.instance_id}: ${r(d.estimated_total_saved_usd)} (${d.total_hits.toLocaleString("en-US")} hits)`)}}catch{}return c.join(`
|
|
54
|
+
`)}case"set_cost_per_call":{const{instance_id:n,cost_per_call_usd:e}=u;if(!e||e<=0||e>100)throw new V(Y.InvalidParams,"cost_per_call_usd must be a positive number \u2264 100");await E(`/api/v1/instances/${n}/cost-per-call`,{method:"PUT",body:JSON.stringify({cost_per_call_usd:e})});const a={"0.02":"claude-opus-4.8","0.015":"gpt-5.5","0.009":"claude-sonnet-4.6","0.002":"gpt-5.5-mini","0.001":"claude-haiku-4.5"},t=a[e.toString()]?` (${a[e.toString()]})`:"";return[`\u2705 **Cost per call updated** \u2014 $${e.toFixed(4)}${t}`,"",`ROI savings in \`cache_stats\` will now use $${e.toFixed(4)} per avoided LLM call.`,"Run `cache_stats` to see your updated savings estimate."].join(`
|
|
55
|
+
`)}default:return null}}export{_e as CACHE_TOOL_NAMES,$e as handleCacheTool};
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import{createHmac as
|
|
2
|
-
`);const
|
|
3
|
-
`);const
|
|
4
|
-
`)}case"cls_ingest":{const{instance_id:
|
|
5
|
-
`)}if(
|
|
6
|
-
`)}if(
|
|
7
|
-
`)}return`\u274C Unknown CLS source: "${
|
|
8
|
-
`];if(t.includes("git")){const
|
|
9
|
-
`)}case"fedbrain_contribute":{const{instance_id:
|
|
10
|
-
`)}case"fedbrain_search":{const{instance_id:
|
|
11
|
-
`);const
|
|
12
|
-
`];for(const
|
|
13
|
-
`)}case"fedbrain_confirm":{const{instance_id:
|
|
14
|
-
`);const e=await I(
|
|
15
|
-
`)}case"fedbrain_status":{const{instance_id:
|
|
16
|
-
`,`### \u{1F4E4} Contributed Lessons: ${
|
|
17
|
-
`)}case"brain_federate":{const{instance_id:
|
|
18
|
-
`);let
|
|
19
|
-
`)}case"crystal_view":{const{instance_id:
|
|
20
|
-
`);const e=
|
|
21
|
-
`)}case"compact_recover":{const{instance_id:
|
|
1
|
+
import{createHmac as se}from"node:crypto";import{ckgSlug as k,extractProblemConcept as oe,ckgUpsertNode as M,ckgUpdateEdge as J,ckgUpsertPersonNode as ne,ckgUpsertFileNode as ie,ckgRecordCollaboration as ae}from"../ckg.js";import{safeJsonParse as R,normalizeGitPath as re}from"../utils.js";import{buildClsPostCommitHook as ce}from"../cls-hook.js";import{alsShellWort as le,beginntMitBindestrich as ue,gitLesen as X,instanzIdFuerSkript as de,istCommitHash as fe,pruefeOrdner as he}from"../git-ohne-shell.js";import{installBrainWatchHook as me}from"../brain-watch-hook.js";import{keywordSearch as pe,wortindexEntwerten as ge}from"../search.js";import{buildFirstContactReport as Z,suggestRecallQueries as _e}from"../first-contact.js";import{classifyCommit as we,extractDomain as ye}from"../commit-art.js";import{VEKTOR_NACHTRAG as $e}from"../bedeutung.js";let be=null,ke=null,U=0;const Se=10,ee=[];function xe(){return U<Se?(U++,Promise.resolve()):new Promise(P=>ee.push(P))}function Ce(){const P=ee.shift();P?P():U--}const Je=new Set(["madc_deliberate","cls_ingest","cls_install_hooks","fedbrain_contribute","fedbrain_search","fedbrain_confirm","fedbrain_status","brain_federate","crystal_view","compact_recover","brain_from_git","brain_from_ci","brain_predict_failures","brain_contribute_signal","brain_import_meta","brain_watch"]);async function Pe(P,j,I,K){switch(P){case"madc_deliberate":{const{instance_id:w,topic:r}=j,i=await I(w),e=(await i.lrange(`cachly:lessons:${r}`,0,-1)).map(g=>{try{return JSON.parse(g)}catch{return null}}).filter(Boolean);if(e.length<2)return[`\u{1F5F3}\uFE0F **MADC: "${r}"**`,"",`Not enough history for deliberation (need \u2265 2 entries, found ${e.length}).`,"","Call `learn_from_attempts` with conflicting outcomes to trigger deliberation."].join(`
|
|
2
|
+
`);const d=[{name:"InfraAgent",domains:["infra","k8s","docker","server","wireguard","helm"]},{name:"AuthAgent",domains:["auth","jwt","keycloak","oauth","oidc","token"]},{name:"DeployAgent",domains:["deploy","ci","pipeline","rsync","release"]},{name:"DatabaseAgent",domains:["db","gorm","migration","postgres","clickhouse","redis"]},{name:"DebugAgent",domains:["debug","panic","race","nil","fix","error"]},{name:"APIAgent",domains:["api","http","grpc","rest","fiber","web"]}],c=r.split(":")[0]??"",a=d.filter(g=>g.domains.some(S=>c===S||r.includes(S))),o=a.length>0?a:d,l=new Map;for(const g of o){let S=0;for(const $ of g.domains){const C=[],N=i.scanStream({match:`cachly:ckg:node:${$}*`,count:50});await new Promise((v,T)=>{N.on("data",B=>C.push(...B)),N.on("end",v),N.on("error",T)}),S+=C.length}l.set(g.name,S)}const m=e.filter(g=>g.outcome==="success"||g.outcome==="partial"),s=e.filter(g=>g.outcome==="failure");if(s.length===0)return[`\u{1F5F3}\uFE0F **MADC: "${r}"**`,"",`No contradictions found \u2014 all ${m.length} entries have non-failure outcomes.`,"",`Use \`ckg_inspect(concept="${k(r)}")\` to explore the confidence graph.`].join(`
|
|
3
|
+
`);const n=[];for(const g of o){const S=l.get(g.name)??0;let $,C;S<2?($="abstain",C="insufficient domain coverage"):m.length>=s.length*2?($="success",C=`${m.length}/${e.length} entries confirm success`):s.length>=m.length*2?($="failure",C=`${s.length}/${e.length} entries confirm failure`):($="abstain",C=`contested (${m.length} success vs ${s.length} failure)`),n.push({agent:g.name,vote:$,coverage:S,reason:C})}const u=n.filter(g=>g.vote==="success").length,h=n.filter(g=>g.vote==="failure").length,f=n.filter(g=>g.vote==="abstain").length;let p,y;u>0&&h===0?(p="unanimous_success",y=`\u2705 **Unanimous: SUCCESS** \u2014 ${u} agent(s) confirm, ${f} abstain`):h>0&&u===0?(p="unanimous_failure",y=`\u274C **Unanimous: FAILURE** \u2014 ${h} agent(s) confirm, ${f} abstain`):(p="contested",y=`\u26A0\uFE0F **CONTESTED** \u2014 ${u} success votes, ${h} failure votes, ${f} abstain`);const _=k(`resolution:${r}`),x={id:_,domain:"resolution",type:"resolution",count:1,ts:new Date().toISOString(),resolution:p,topic:r,votes:{success:u,failure:h,abstain:f}};if(await i.set(`cachly:ckg:node:${_}`,JSON.stringify(x)),p==="contested")await J(i,k(r),"contradicts",_,!1);else{if(((p==="unanimous_success"?"failure":"success")==="failure"?s:m).length>0){const $=await i.smembers(`cachly:ckg:idx:from:${k(r)}`);for(const C of $){const N=await i.get(C);if(N)try{const v=JSON.parse(N);v.edgeType==="fixes"&&v.confidence>.15&&p==="unanimous_failure"&&(v.confidence=.1,v.last_updated=new Date().toISOString(),await i.set(C,JSON.stringify(v)))}catch{}}}await i.del(`cachly:ckg:conflict:${k(r)}`)}const L=[`\u{1F5F3}\uFE0F **MADC Deliberation: "${r}"**`,"",`\u{1F4CA} Evidence: ${m.length} success/partial vs ${s.length} failure entries (${e.length} total)`,"",`**Voting agents (${o.length}):**`,...n.map(g=>{const S=g.vote==="success"?"\u2705":g.vote==="failure"?"\u274C":"\u2B1C",$="\u2593".repeat(Math.min(g.coverage,5))+"\u2591".repeat(Math.max(0,5-g.coverage));return` ${S} **${g.agent}** [${$}] ${g.coverage} CKG edges \u2014 ${g.reason}`}),"",y,""];return p==="unanimous_success"?L.push(`\u{1F527} Failure entries superseded \u2014 store confirmed lesson: \`learn_from_attempts(topic="${r}", outcome="success", ...)\``):p==="unanimous_failure"?L.push(`\u{1F6AB} Success claims unconfirmed \u2014 re-verify: \`recall_best_solution(topic="${r}")\``):L.push(`\u26A0\uFE0F Contested \u2014 run \`causal_trace\` before acting. Explore: \`ckg_inspect(concept="${k(r)}")\``),L.push("",`\u{1F4DD} Resolution node: \`cachly:ckg:node:${_}\``),L.join(`
|
|
4
|
+
`)}case"cls_ingest":{const{instance_id:w,source:r,payload:i}=j,t=await I(w),e=new Date().toISOString(),d="cachly:cls:events";if(r==="git_commit"){const c=String(i.message??""),a=String(i.sha??""),o=Array.isArray(i.files)?i.files:[],l=/^fix/i.test(c)?"fix":/^feat/i.test(c)?"feat":/^refactor/i.test(c)?"refactor":/^test/i.test(c)?"test":"commit",m=`${l}:${k(c.slice(0,60))}`,s=k(m);await M(t,s,l,"commit");for(const h of o.slice(0,10)){const f=h.includes("auth")?"auth":h.includes("api")?"api":h.includes("infra")?"infra":h.includes("web")?"web":"code",p=k(`file:${f}`);await M(t,p,"file",f),await J(t,s,"co-occurs",p,!0)}const n={topic:m,outcome:"success",what_worked:c,what_failed:"",context:`CLS/git: sha=${a}`,severity:"minor",file_paths:o.slice(0,10),commands:a?[`git show ${a}`]:[],tags:["cls","git"],depends_on:[],recall_count:0,ts:e,verified_at:e,confidence:.6,audit_trail:[{ts:e,action:"cls_git_commit"}],version:3};return await t.rpush(`cachly:lessons:${m}`,JSON.stringify(n)),await t.get(`cachly:lesson:best:${m}`)||await t.set(`cachly:lesson:best:${m}`,JSON.stringify(n)),await t.rpush(d,JSON.stringify({source:r,payload:{message:c,sha:a},ts:e})),await t.ltrim(d,-200,-1),["\u{1F4E8} **CLS Ingested: git_commit**","",`Commit \`${a.slice(0,8)||"?"}\`: ${c.slice(0,80)}`,`Concept: \`${s}\` (${l}) \xB7 Files: ${o.length}`,"",`\u{1F578}\uFE0F CKG: \`${s}\` + ${o.length} file edges \xB7 Lesson: \`${m}\``,`\u{1F4A1} Inspect: \`ckg_inspect(concept="${l}")\``].join(`
|
|
5
|
+
`)}if(r==="ci_outcome"){const c=String(i.status??""),a=String(i.prev_status??""),o=String(i.job??"unknown"),l=String(i.context??""),m=["failure","red","error"].includes(a)&&["success","green","passed"].includes(c),s=["success","green","passed"].includes(a)&&["failure","red","error"].includes(c),n=`ci:${k(o)}`,u=k(n);if(await M(t,u,"ci","job"),m){const f=k(`problem:${k(o)}`);await M(t,f,"problem","ci-failure"),await J(t,u,"fixes",f,!0);const p={topic:n,outcome:"success",what_worked:`CI job "${o}" went ${a} \u2192 ${c}`,what_failed:`Job "${o}" was failing`,context:`CLS/ci: ${l}`,severity:"major",file_paths:[],commands:[],tags:["cls","ci"],depends_on:[],recall_count:0,ts:e,verified_at:e,confidence:.75,audit_trail:[{ts:e,action:"cls_ci_fixed"}],version:3};await t.rpush(`cachly:lessons:${n}`,JSON.stringify(p)),await t.set(`cachly:lesson:best:${n}`,JSON.stringify(p))}else if(s){const f=k(`cause:${k(o)}`);await M(t,f,"cause","ci-break"),await J(t,u,"causes",f,!1)}return await t.rpush(d,JSON.stringify({source:r,payload:{status:c,prev_status:a,job:o},ts:e})),await t.ltrim(d,-200,-1),["\u{1F4E8} **CLS Ingested: ci_outcome**","",`${m?"\u2705 Fixed":s?"\u{1F534} Broken":"\u{1F4CA} Recorded"}: \`${o}\` \u2014 ${a||"?"} \u2192 ${c}`,m?"\u{1F527} CKG `fixes` edge added (75% confidence)":s?"\u26A1 CKG `causes` edge added":"\u{1F4CA} State recorded",`\u{1F4A1} Lesson: \`${n}\` | Predict: \`brain_predict(context="${o}")\``].join(`
|
|
6
|
+
`)}if(r==="ide_diagnostic"){const c=String(i.error??""),a=String(i.fix??""),o=String(i.file??""),l=oe(c)??"unknown-error",m=`debug:${k(l)}`,s=k(m),n=k(`problem:${l}`);await M(t,s,"debug","diagnostic"),await M(t,n,"problem","compiler-error"),await J(t,s,"fixes",n,!0);const u={topic:m,outcome:"success",what_worked:a,what_failed:c,context:`CLS/ide: ${o}`,severity:"minor",file_paths:o?[o]:[],commands:[],tags:["cls","ide-diagnostic"],depends_on:[],recall_count:0,ts:e,verified_at:e,confidence:.65,audit_trail:[{ts:e,action:"cls_ide_diagnostic"}],version:3};return await t.rpush(`cachly:lessons:${m}`,JSON.stringify(u)),await t.get(`cachly:lesson:best:${m}`)||await t.set(`cachly:lesson:best:${m}`,JSON.stringify(u)),await t.rpush(d,JSON.stringify({source:r,payload:{error:c.slice(0,60),fix:a.slice(0,60),file:o},ts:e})),await t.ltrim(d,-200,-1),["\u{1F4E8} **CLS Ingested: ide_diagnostic**","",`Error: \`${c.slice(0,80)}\``,`Fix: ${a.slice(0,100)}`,o?`File: \`${o}\``:"","",`\u{1F578}\uFE0F CKG: \`${s}\` \u2192 fixes \u2192 \`${n}\` | Lesson: \`${m}\``].filter(f=>f!=="").join(`
|
|
7
|
+
`)}return`\u274C Unknown CLS source: "${r}". Valid: git_commit, ci_outcome, ide_diagnostic`}case"cls_install_hooks":{const{instance_id:w,repo_path:r=".",hooks:i=["git","ci"]}=j,t=Array.isArray(i)?i:["git","ci"],e=[`\u{1F50C} **CLS Hook Installation Guide**
|
|
8
|
+
`];if(de(w),t.includes("git")){const d=ce(w),c=le(`${r}/.git/hooks/post-commit`);e.push("### Git post-commit hook"),e.push("**Quick install (run once per repo):**"),e.push("```sh"),e.push(`touch ${c}`),e.push(`grep -q 'cachly CLS' ${c} || cat >> ${c} << 'HOOK'`),e.push(d),e.push("HOOK"),e.push(`chmod +x ${c}`),e.push("```"),e.push("After install: every `git commit` automatically updates your brain's CKG."),e.push("")}return t.includes("ci")&&(e.push("### GitHub Actions CI outcome hook"),e.push("**Add at the end of each job** (after build/test steps):"),e.push("```yaml"),e.push("- name: cachly CLS \u2014 record CI outcome"),e.push(" if: always()"),e.push(" run: |"),e.push(' node -e "'),e.push(" const r=require('https');"),e.push(` const d=JSON.stringify({instance_id:'${w}',source:'ci_outcome',payload:{`),e.push(" status:'${{ job.status }}',prev_status:'unknown',job:'${{ github.job }}',"),e.push(" context:'github-actions run ${{ github.run_number }}'}});"),e.push(" r.request({hostname:'api.cachly.dev',path:'/api/v1/cls/ingest',method:'POST',"),e.push(" headers:{'Content-Type':'application/json','Authorization':'Bearer $CACHLY_JWT',"),e.push(" 'Content-Length':d.length}},()=>{}).end(d);"),e.push(' " 2>/dev/null || true'),e.push(" env:"),e.push(" CACHLY_JWT: ${{ secrets.CACHLY_JWT }}"),e.push("```"),e.push("")),e.push('\u{1F4A1} Once installed: `brain_search(query="cls")` to verify events are arriving.'),e.push('\u{1F4CA} Monitor CKG growth: `ckg_inspect(concept="ci")` or `ckg_inspect(concept="fix")`'),e.join(`
|
|
9
|
+
`)}case"fedbrain_contribute":{const{instance_id:w,lesson_key:r,visibility:i="public"}=j,t=await I(w),e=await t.get(`cachly:lesson:best:${r}`);if(!e)return`\u274C Lesson \`${r}\` not found. Store it first with \`learn_from_attempts\`.`;const d=R(e,null);if(!d)return`\u274C Lesson \`${r}\` data is corrupted. Re-store with \`learn_from_attempts\`.`;const c=[d.topic.split(":")[0],...d.tags??[]].filter(Boolean),a=[...new Set(c)].sort().join(","),o=`${d.topic}:${d.outcome}:${d.what_worked}`,l=se("sha256",`cachly-fedbrain:${w}`).update(o).digest("hex").slice(0,16),m={cert_id:l,lesson_key:r,visibility:i,domain_fingerprint:a,contributed_at:new Date().toISOString(),confirm_count:0,trust_score:d.outcome==="success"?.85:.5};await t.set(`cachly:fedbrain:cert:${l}`,JSON.stringify(m)),await t.sadd("cachly:fedbrain:contributed",l);let s;try{await K("/api/v1/syndication/contribute",{method:"POST",body:JSON.stringify({topic:d.topic,outcome:d.outcome,what_worked:d.what_worked,what_failed:d.what_failed??"",severity:d.severity??"major",cert_id:l,domain_fingerprint:a,visibility:i})}),s="\u2705 Contributed to global commons"}catch{s="\u{1F4E6} Stored locally (commons API unavailable \u2014 will sync when online)"}return[`\u{1F310} **FedBrain Contribute: "${r}"**`,"",`\u{1F4DC} Certificate: \`${l}\``,`\u{1F3F7}\uFE0F Domain fingerprint: ${c.slice(0,6).map(n=>`\`${n}\``).join(", ")}`,`\u{1F512} Visibility: ${i}`,"",s,"","\u{1F4A1} At 10 independent confirms \u2192 \u{1F3C6} Gold Standard",`\u{1F50D} Search: \`fedbrain_search(query="${d.topic.split(":").slice(-1)[0]}")\``].join(`
|
|
10
|
+
`)}case"fedbrain_search":{const{instance_id:w,query:r,context_hints:i=[],limit:t=10}=j,e=await I(w),d=await e.smembers("cachly:fedbrain:contributed"),c=new Map;for(const n of d.slice(0,30)){const u=await e.get(`cachly:fedbrain:cert:${n}`);if(u)try{const h=JSON.parse(u);for(const f of(h.domain_fingerprint??"").split(",").filter(Boolean))c.set(f,(c.get(f)??0)+1)}catch{}}for(const n of Array.isArray(i)?i:[])c.set(n.toLowerCase(),(c.get(n.toLowerCase())??0)+2);let a=[],o=!1;try{const n=new URLSearchParams({q:r,limit:String(Math.min(t*2,50))});a=(await K(`/api/v1/syndication/search?${n}`)).results??[]}catch{o=!0;const n=[],u=e.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((h,f)=>{u.on("data",p=>n.push(...p)),u.on("end",h),u.on("error",f)});for(const h of n.slice(0,60)){const f=await e.get(h);if(f)try{const p=JSON.parse(f),y=`${p.topic} ${p.what_worked??""} ${p.what_failed??""}`.toLowerCase();r.toLowerCase().split(/\s+/).some(_=>_.length>2&&y.includes(_))&&a.push({id:h.split(":").pop()??h,topic:p.topic,category:p.topic.split(":")[0],outcome:p.outcome,what_worked:p.what_worked??"",severity:p.severity??"major",confirm_count:0,created_at:p.ts??new Date().toISOString()})}catch{}}}const l=o?" \u2014 \u26A0\uFE0F Commons unreachable, local fallback (this machine only, not confirmed by the network)":"";if(a.length===0)return[`\u{1F310} **FedBrain Search: "${r}"**${l}`,"",'No results. Contribute: `fedbrain_contribute(lesson_key="fix:...")`'].join(`
|
|
11
|
+
`);const m=a.map(n=>{const u=(n.domain_fingerprint??n.category??"").split(",").filter(Boolean),h=u.reduce((_,x)=>_+(c.get(x)??0),0),f=c.size>0?h/Math.max(1,c.size+u.length):0,p=Math.min(1,n.confirm_count/10),y=f*.4+p*.4+(n.outcome==="success"?.2:0);return{...n,weightedScore:y,isGoldStandard:!o&&n.confirm_count>=10}}).sort((n,u)=>u.weightedScore-n.weightedScore).slice(0,t),s=[`\u{1F310} **FedBrain Search: "${r}"** \u2014 ${m.length} result${m.length!==1?"s":""} (context-weighted)${l}
|
|
12
|
+
`];for(const n of m){const u=n.outcome==="success"?"\u2705":n.outcome==="failure"?"\u274C":"\u26A0\uFE0F",h=n.isGoldStandard?" \u{1F3C6} _Gold Standard_":!o&&n.confirm_count>=3?` \u2713${n.confirm_count}`:"",f=Math.round(n.weightedScore*100);s.push(`${u}${h} **\`${n.topic}\`** [ctx: ${f}%]`),n.what_worked&&s.push(` \u2705 ${n.what_worked.slice(0,150)}`),n.what_failed&&s.push(` \u274C ${n.what_failed.slice(0,80)}`),s.push(` _${n.confirm_count} confirm${n.confirm_count!==1?"s":""} | id: \`${n.id}\`_`,"")}if(c.size>0){const n=[...c.entries()].sort((u,h)=>h[1]-u[1]).slice(0,5).map(([u,h])=>`\`${u}\`(${h})`).join(", ");s.push(`\u{1F3AF} Your context: ${n}`)}return s.push('\u{1F4A1} Confirm a result: `fedbrain_confirm(id="<id>", topic="<topic>", outcome="worked")`'),s.join(`
|
|
13
|
+
`)}case"fedbrain_confirm":{const{instance_id:w,id:r,topic:i,outcome:t}=j;if(!r)return["\u274C **FedBrain Confirm** needs the lesson `id` from `fedbrain_search` results.",'Run `fedbrain_search(query="...")`, copy the id shown next to a result,','then: `fedbrain_confirm(id="<id>", topic="<topic>", outcome="worked")`.'].join(`
|
|
14
|
+
`);const e=await I(w),d=new Date().toISOString(),c=JSON.stringify({id:r,topic:i,outcome:t,ts:d});await e.rpush("cachly:fedbrain:confirmations",c),await e.ltrim("cachly:fedbrain:confirmations",-200,-1);const a=t==="worked",o=t==="partially_worked";i&&await J(e,k(i),"fixes",k(`syndicated:${i}`),a,o);let l;try{await K(`/api/v1/syndication/${encodeURIComponent(r)}/confirm`,{method:"POST"}),l="\u2705 Confirmation propagated to global commons"}catch{await e.rpush("cachly:fedbrain:pending_confirms",c),await e.ltrim("cachly:fedbrain:pending_confirms",-50,-1),l="\u{1F4E6} Queued locally (API unavailable \u2014 will propagate on next online session)"}return[`${a?"\u2705":o?"\u26A0\uFE0F":"\u274C"} **FedBrain Confirm: "${i??r}"** \u2192 ${t}`,"",l,"",i?`\u{1F578}\uFE0F CKG confidence ${a||o?"boosted":"reduced"} for \`${k(i)}\``:"\u{1F578}\uFE0F Local CKG unchanged (pass `topic` to also update your own confidence graph)","\u{1F4A1} Your confirmation helps other brains worldwide.",'\u{1F4CA} Status: `fedbrain_status(instance_id="...")`'].join(`
|
|
15
|
+
`)}case"fedbrain_status":{const{instance_id:w}=j,r=await I(w),i=await r.smembers("cachly:fedbrain:contributed"),t=await r.lrange("cachly:fedbrain:confirmations",-10,-1),e=await r.llen("cachly:fedbrain:pending_confirms"),d=t.map(o=>{try{return JSON.parse(o)}catch{return null}}).filter(Boolean),c=[];for(const o of i.slice(0,15)){const l=await r.get(`cachly:fedbrain:cert:${o}`);if(l)try{const m=JSON.parse(l);c.push({cert_id:m.cert_id,lesson_key:m.lesson_key,confirm_count:m.confirm_count??0,trust_score:m.trust_score??.5,isGold:(m.confirm_count??0)>=10})}catch{}}const a=[`\u{1F310} **FedBrain Status**
|
|
16
|
+
`,`### \u{1F4E4} Contributed Lessons: ${i.length}`];if(c.length>0)for(const o of c){const l=o.isGold?" \u{1F3C6} Gold Standard":"",m="\u2588".repeat(Math.min(10,o.confirm_count))+"\u2591".repeat(Math.max(0,10-o.confirm_count));a.push(` \`${o.lesson_key}\` [${m}] \xD7${o.confirm_count}${l}`)}else a.push(' _None yet. Contribute with `fedbrain_contribute(lesson_key="fix:...")`_');if(a.push("",`### \u{1F4E5} Recent Confirmations: ${d.length}`),d.length>0)for(const o of d.slice(-5)){const l=o.outcome==="worked"?"\u2705":o.outcome==="partially_worked"?"\u26A0\uFE0F":"\u274C";a.push(` ${l} \`${o.topic}\` \u2014 ${o.outcome} (${new Date(o.ts).toLocaleDateString("de-DE")})`)}else a.push(" _None yet. Confirm syndicated lessons with `fedbrain_confirm`_");return e>0&&a.push("",`\u26A0\uFE0F ${e} confirmation${e!==1?"s":""} pending propagation`),a.push("","---",'**Contribute:** `fedbrain_contribute(lesson_key="fix:...")`','**Search:** `fedbrain_search(query="...")`','**Confirm:** `fedbrain_confirm(id="...", topic="...", outcome="worked")`'),a.join(`
|
|
17
|
+
`)}case"brain_federate":{const{instance_id:w,source:r,domain:i,min_confidence:t=.6,dry_run:e=!1}=j;if(w===r)return"\u274C Source and destination cannot be the same brain.";const d=await I(w),c=await I(r),a=i==="*"?"cachly:ckg:node:*":`cachly:ckg:node:${i}*`,o=[],l=c.scanStream({match:a,count:100});if(await new Promise((y,_)=>{l.on("data",x=>o.push(...x)),l.on("end",y),l.on("error",_)}),o.length===0)return[`\u{1F9E0} **brain_federate: "${i}"**`,"",`No CKG nodes found in source brain for domain \`${i}\`.`,"The source brain may not have knowledge in this area yet.",`Try: \`fedbrain_search(query="${i}")\` to find global commons knowledge instead.`].join(`
|
|
18
|
+
`);let m=0,s=0,n=0,u=0;const h=[];for(const y of o){const _=await c.get(y);if(!_)continue;let x;try{x=JSON.parse(_)}catch{continue}e||await d.set(y,_),m++;const L=await c.smembers(`cachly:ckg:idx:from:${x.id}`);for(const $ of L){const C=await c.get($);if(!C)continue;let N;try{N=JSON.parse(C)}catch{continue}if(N.confidence<t){u++;continue}e||(await d.set($,C),await d.sadd(`cachly:ckg:idx:from:${N.from}`,$),await d.sadd(`cachly:ckg:idx:to:${N.to}`,$)),s++}const g=`cachly:lesson:best:${x.id}`,S=await c.get(g);if(S&&(e||await d.set(g,S),n++,h.length<8))try{const $=JSON.parse(S),C=$.outcome==="success"?"\u2705":$.outcome==="failure"?"\u274C":"\u26A0\uFE0F";h.push(` ${C} \`${$.topic}\` \u2014 ${($.what_worked??"").slice(0,80)}`)}catch{}}if(!e){const y=JSON.stringify({source:r,domain:i,transferred_at:new Date().toISOString(),nodes:m,edges:s,lessons:n});await d.rpush("cachly:fedbrain:federations",y),await d.ltrim("cachly:fedbrain:federations",-50,-1)}const p=[`\u{1F9E0} **brain_federate: "${i}"**${e?" (DRY RUN \u2014 no writes)":""}`,"",`\u{1F4E4} Source: \`${r}\``,`\u{1F4E5} Destination: \`${w}\``,`\u{1F50D} Domain filter: \`${i}\` | min_confidence: ${t}`,"","### Transfer Summary",` \u{1F578}\uFE0F CKG nodes: ${m}`,` \u{1F517} CKG edges: ${s} (${u} skipped, confidence < ${t})`,` \u{1F4DA} Lessons: ${n}`,""];return h.length>0&&(p.push("### Sample lessons transferred:",...h),n>h.length&&p.push(` _... and ${n-h.length} more_`),p.push("")),e?p.push("\u{1F4A1} Run without `dry_run: true` to apply the transfer."):(p.push(`\u2705 Transfer complete. Your brain now has the \`${i}\` knowledge from \`${r}\`.`),p.push(`\u{1F50D} Explore: \`ckg_inspect(concept="${i}")\` | \`recall_best_solution(topic="${i}:...")\``)),p.join(`
|
|
19
|
+
`)}case"crystal_view":{const{instance_id:w,show_raw:r=!1}=j,i=await I(w),t=await i.get("cachly:crystal:latest");if(!t)return["\u{1F48E} **Memory Crystal: not yet created**","","No crystal found. Create one with `memory_crystalize()` to compress your accumulated wisdom.","","\u{1F4A1} Tip: run `memory_crystalize` monthly for best results."].join(`
|
|
20
|
+
`);const e=R(t,null);if(!e)return"\u274C Memory Crystal data is corrupted. Re-create with `memory_crystalize()`.";const d=Math.floor((Date.now()-new Date(e.ts).getTime())/864e5),c=d<=7?"\u{1F7E2}":d<=30?"\u{1F7E1}":"\u{1F534}",a=[`\u{1F48E} **Memory Crystal: ${e.label}**`,"",`\u{1F4C5} Created: ${new Date(e.ts).toLocaleDateString("de-DE")} (${d}d ago ${c})`,`\u{1F4CA} Compressed from: ${e.created_from}`,`\u{1F5C2}\uFE0F Categories: ${e.categories.slice(0,10).map(l=>`\`${l}\``).join(", ")}${e.categories.length>10?` +${e.categories.length-10} more`:""}`,"",`**\u{1F511} Top patterns (${e.top_patterns.length}):**`];for(const l of e.top_patterns)a.push(` \u2022 **${l.category}** (${l.count}\xD7): ${l.insight.slice(0,110)}`);d>30&&a.push("",`\u26A0\uFE0F Crystal is ${d}d old \u2014 run \`memory_crystalize()\` to refresh it.`),r&&a.push("","```json",JSON.stringify(e,null,2),"```");const o=await i.get("cachly:crystal:team:latest").catch(()=>null);if(o){const l=R(o,null);if(l&&l.patterns?.length){const m=Math.floor((Date.now()-new Date(l.ts).getTime())/864e5);a.push("","---",`\u{1F4A0} **Team Crystal: ${l.label}** _(${m}d ago \xB7 ${l.contributors} contributors)_`,"_Fixes multiple teammates independently converged on \u2014 the team-wide layer:_");for(const s of l.patterns.slice(0,5))a.push(` \u2022 \u{1F9E9} **${s.concept}** \u2014 ${s.author_count} people (${s.authors.map(n=>`@${n}`).join(", ")}): ${s.convergent_fix.slice(0,90)}`)}}return a.push("",'\u{1F4A1} Refresh: `memory_crystalize()` \xB7 `team_crystallize()` | Recover: `compact_recover(instance_id="...")`'),a.join(`
|
|
21
|
+
`)}case"compact_recover":{const{instance_id:w,focus:r=""}=j,i=await I(w),t=[`\u{1F501} **Compact Recovery Briefing**
|
|
22
22
|
`];t.push(`> *Call this first after any context limit hit. Reconstructs where you left off.*
|
|
23
|
-
`);const e=await
|
|
24
|
-
`)}case"brain_from_git":{const
|
|
25
|
-
`)){const b=O.trim();if(b.startsWith("COMMIT|||")){
|
|
26
|
-
\u{1F9E0} brain_from_git: processing ${
|
|
27
|
-
`);for(let O=0;O<
|
|
28
|
-
`),
|
|
23
|
+
`);const e=await i.get("cachly:crystal:latest");if(e){const s=R(e,null);if(s){t.push(`### \u{1F48E} Memory Crystal: ${s.label}`),t.push(`Compressed from ${s.session_count} sessions, ${s.lesson_count} lessons.`);const n=r?s.top_patterns.filter(u=>u.category.toLowerCase().includes(r.toLowerCase())||u.insight.toLowerCase().includes(r.toLowerCase())).slice(0,4):s.top_patterns.slice(0,4);for(const u of n)t.push(` \u2022 **${u.category}**: ${u.insight.slice(0,100)}`);t.push("")}}const d=await i.get("cachly:session:last");if(d){const s=R(d,null);s&&(t.push("### \u{1F550} Last Session"),s.focus&&t.push(`Focus: _${s.focus}_`),s.summary&&t.push(`Summary: ${s.summary.slice(0,300)}`),t.push(""))}const c=await i.get("cachly:session:handoff");if(c){const s=R(c,null);if(s){if(t.push("### \u{1F4CB} Handoff (from last window)"),s.context_summary&&t.push(`Context: ${s.context_summary.slice(0,200)}`),s.remaining_tasks?.length){t.push("Remaining tasks:");for(const n of s.remaining_tasks.slice(0,5))t.push(` \u2022 ${n}`)}s.instructions&&t.push(`\u26A0\uFE0F Instructions: ${s.instructions.slice(0,200)}`),s.blocked_on&&t.push(`\u{1F6A7} Blocked on: ${s.blocked_on}`),t.push("")}}const a=await i.get("cachly:ctx:wip-registry");if(a){const s=R(a,null);s?.content&&(t.push("### \u{1F527} WIP Registry"),t.push(s.content.slice(0,400)),t.push(""))}const o=[],l=i.scanStream({match:"cachly:roadmap:*",count:100});await new Promise((s,n)=>{l.on("data",u=>o.push(...u)),l.on("end",s),l.on("error",n)});const m=[];for(const s of o.slice(0,30)){const n=await i.get(s);if(n)try{const u=JSON.parse(n);(u.status==="in_progress"||u.status==="blocked")&&m.push({title:u.title??s,status:u.status,priority:u.priority})}catch{}}if(m.length>0){t.push("### \u{1F6A7} Open Items");for(const s of m.slice(0,5))t.push(` \u2022 [${s.status}] ${s.title}`);t.push("")}if(r){const s=[],n=i.scanStream({match:"cachly:lesson:best:*",count:200});await new Promise((h,f)=>{n.on("data",p=>s.push(...p)),n.on("end",h),n.on("error",f)});const u=[];for(const h of s){const f=await i.get(h);if(f)try{const p=JSON.parse(f);p.topic.toLowerCase().includes(r.toLowerCase())&&p.what_worked&&u.push({topic:p.topic,what_worked:p.what_worked})}catch{}}if(u.length>0){t.push(`### \u{1F4A1} Relevant Lessons for "${r}"`);for(const h of u.slice(0,4))t.push(` \u2022 **${h.topic}**: ${h.what_worked.slice(0,100)}`);t.push("")}}return t.length<=3&&t.push("_No brain data found. Start accumulating knowledge with `learn_from_attempts` and `session_start`._"),t.push("---","\u{1F9E0} Brain is ready. Continue your work \u2014 full context restored."),t.join(`
|
|
24
|
+
`)}case"brain_from_git":{const w=Date.now(),{instance_id:r,repo_path:i=".",limit:t=100,branch:e="HEAD",since:d="",incremental:c=!0}=j,a=await I(r),{resolve:o}=await import("node:path"),l=o(i),m=Math.max(1,Math.floor(Math.min(Number(t)||100,500)));if(typeof e!="string"||ue(e))return'\u274C Ungueltiger `branch`: darf nicht mit "-" beginnen.';await xe();try{try{if(!he(l))throw new Error("kein Ordner");X(l,["rev-parse","--git-dir"],{stderr:"pipe"})}catch{return`\u274C Not a git repository: \`${l}\`. Pass \`repo_path\` pointing to a git checkout.`}const s=`cachly:brain_from_git:last_sha:${Buffer.from(l).toString("base64").slice(0,32)}`;let n="",u=!1;c!==!1&&!d&&(n=await a.get(s)??"",fe(n)||(n=""),u=!!n);const f=(u?`${n}..HEAD`:"")||e||"HEAD",p=["log",f,...d?[`--since=${d}`]:[],"--pretty=format:COMMIT|||%H|||%s|||%ad|||%an","--date=short","--no-merges","--name-only","-n",String(m)];let y="";try{y=X(l,p,{stderr:"pipe",timeoutMs:6e4})}catch(O){return`\u274C git log failed: ${O.message}. Check \`repo_path\` and \`branch\`.`}const _=[];let x=null;for(const O of y.split(`
|
|
25
|
+
`)){const b=O.trim();if(b.startsWith("COMMIT|||")){x&&_.push(x);const[,A,E,G,q]=b.split("|||");x={sha:(A??"").trim(),subject:(E??"").trim(),date:(G??"").trim(),author:(q??"").trim(),files:[]}}else if(b&&x){const A=re(b);A&&x.files.push(A)}}if(x&&_.push(x),_.length===0)return u?`\u2705 brain_from_git: Brain is up to date \u2014 no new commits since last run (last SHA: \`${n.slice(0,8)}\`).`:Z({repoDir:l,revRange:f,processed:0,ingested:0,skipped:0,durationMs:Date.now()-w,isIncremental:!1,instanceId:r,categories:[],suggestedQueries:[],emptyReason:`No commits found in \`${l}\` on branch \`${e}\`${d?` since ${d}`:""}.`});const L=new Date().toISOString();let g=0,S=0;const $=new Map,C=new Map,N=[];let v=null;const T=_.length,B=Math.max(1,Math.floor(T/10));let H=0;process.stderr.write(`
|
|
26
|
+
\u{1F9E0} brain_from_git: processing ${T} commits from ${l}...
|
|
27
|
+
`);for(let O=0;O<_.length;O++){const b=_[O];if(O-H>=B&&(process.stderr.write(` \u23F3 Processing ${O}/${T} commits (${g} lessons so far)...
|
|
28
|
+
`),H=O),!b.subject){S++;continue}const{category:A,outcome:E,severity:G}=we(b.subject),q=ye(b.subject),D=`${A}:${q}`;$.set(A,($.get(A)??0)+1),C.set(G,(C.get(G)??0)+1),N.push(D),(!v||A==="fix"&&!v.topic.startsWith("fix:"))&&(v={topic:D,subject:b.subject});const W=b.files.filter(F=>F.length>0).slice(0,12),V={topic:D,outcome:E,severity:G,what_worked:b.subject.slice(0,200),what_failed:"",context:`git:${b.sha.slice(0,8)} by ${b.author} on ${b.date}`,author:b.author||void 0,file_paths:W,commands:[`git show ${b.sha.slice(0,8)}`],tags:["brain_from_git",A,"git-history"],visibility:"team",depends_on:[],recall_count:0,ts:L,verified_at:L,confidence:.55,audit_trail:[{ts:L,action:"brain_from_git",sha:b.sha.slice(0,8)}],version:3};await a.get(`cachly:lesson:best:${D}`)||(await a.set(`cachly:lesson:best:${D}`,JSON.stringify(V),"EX",90*86400),await a.rpush(`cachly:lessons:${D}`,JSON.stringify(V)),await a.ltrim(`cachly:lessons:${D}`,-100,-1),await a.expire(`cachly:lessons:${D}`,90*86400),await a.sadd($e,D).catch(()=>{})),await a.rpush("cachly:lessons:brain_from_git:all",JSON.stringify({topic:D,sha:b.sha.slice(0,8),subject:b.subject.slice(0,60)})),await a.ltrim("cachly:lessons:brain_from_git:all",-500,-1),await a.expire("cachly:lessons:brain_from_git:all",90*86400);const Y=k(D);if(await M(a,Y,A,"git-derived"),b.author)try{const F=await ne(a,b.author,A);await J(a,F,"authored",Y,E==="success",E==="partial");for(const te of W.slice(0,8)){const Q=await ie(a,te);await J(a,F,"touched",Q,!0),await ae(a,Q,F)}}catch{}g++}process.stderr.write(` \u2705 brain_from_git complete: ${g}/${T} commits ingested
|
|
29
29
|
|
|
30
|
-
`)
|
|
31
|
-
`)}case"brain_predict_failures":{const{instance_id:
|
|
32
|
-
`);const
|
|
33
|
-
`];s.push(`> Pre-deploy failure analysis based on ${
|
|
34
|
-
`);for(let
|
|
35
|
-
`)}case"brain_contribute_signal":{const{instance_id:
|
|
36
|
-
`)}case"brain_import_meta":{const{instance_id:
|
|
37
|
-
`);const
|
|
38
|
-
`)}case"brain_watch":{const{instance_id:
|
|
39
|
-
`):[`\u{1F9E0} **brain_watch ${{written:"\u2705 Hook installed (new)",upgraded:"\u{1F504} Hook upgraded to latest version",appended:"\u{1F4CE} Hook appended to existing post-commit script",unchanged:"\u2713 Hook already up to date \u2014 nothing changed"}[
|
|
40
|
-
`)}default:return null}}export{
|
|
30
|
+
`),g>0&&ge(),_.length>0&&_[0]?.sha&&await a.set(s,_[0].sha,"EX",2160*3600),be={fixes:$.get("fix")??0,features:$.get("feat")??0,refactors:$.get("refactor")??0,total:g};let z=null;if(v&&g>0)try{const O=await pe(a,["cachly:lesson:best:*"],v.subject,1);if(O.length>0){const b=R(O[0].content,{});z={query:v.subject.slice(0,80),topic:b.topic??O[0].key.replace("cachly:lesson:best:",""),snippet:(b.what_worked??"").slice(0,120)||v.subject.slice(0,120)}}}catch{}return Z({repoDir:l,revRange:f,processed:_.length,ingested:g,skipped:S,durationMs:Date.now()-w,isIncremental:u,lastSha:n,instanceId:r,categories:[...$.entries()].sort((O,b)=>b[1]-O[1]),severities:[...C.entries()].sort((O,b)=>b[1]-O[1]),proof:z,suggestedQueries:_e(N,r)})}finally{Ce()}}case"brain_from_ci":{const{instance_id:w,outcomes:r}=j,i=await I(w),t=Date.now();let e=0,d=0,c=0;const a=r.length;for(const o of r){const l=String(o.status??""),m=String(o.prev_status??""),s=String(o.job??"unknown"),n=String(o.context??""),u=["failure","red","error"].includes(m)&&["success","green","passed"].includes(l),h=["success","green","passed"].includes(m)&&["failure","red","error"].includes(l),f=`ci:${k(s)}`,p=k(f);if(await M(i,p,"ci","job"),u){const _=k(`problem:${k(s)}`);await M(i,_,"problem","ci-failure"),await J(i,p,"fixes",_,!0);const x={topic:f,outcome:"success",what_worked:`CI job "${s}" went ${m} \u2192 ${l}`,what_failed:`Job "${s}" was failing`,context:`brain_from_ci: ${n}`,severity:"major",file_paths:[],commands:[],tags:["brain_from_ci","ci"],depends_on:[],recall_count:0,ts:t,verified_at:t,confidence:.65,audit_trail:[{ts:t,action:"brain_from_ci_fixed"}],version:3};await i.rpush(`cachly:lessons:${f}`,JSON.stringify(x)),await i.ltrim(`cachly:lessons:${f}`,-100,-1),await i.set(`cachly:lesson:best:${f}`,JSON.stringify(x)),e++}else if(h){const _=k(`cause:${k(s)}`);await M(i,_,"cause","ci-break"),await J(i,p,"causes",_,!1),d++}else c++;const y=`cachly:cls:${w}`;await i.rpush(y,JSON.stringify({source:"ci_outcome",payload:{status:l,prev_status:m,job:s},ts:t})),await i.ltrim(y,-200,-1)}return ke={fixes:e,breaks:d,stable:c,total:a},[`\u{1F4E5} **brain_from_ci**: Ingested ${a} outcomes \u2014 ${e} fixes learned, ${d} breaks noted, ${c} stable`,"",e>0?`\u2705 ${e} fix lesson${e!==1?"s":""} written (confidence 0.65) \u2014 CKG \`fixes\` edges added`:"",d>0?`\u{1F534} ${d} break${d!==1?"s":""} noted \u2014 CKG \`causes\` edges added`:"",c>0?`\u{1F4CA} ${c} stable outcome${c!==1?"s":""} recorded`:"","",'\u{1F4A1} Explore: `brain_search(query="ci")` | `brain_predict(context="<job-name>")`'].filter(Boolean).join(`
|
|
31
|
+
`)}case"brain_predict_failures":{const{instance_id:w,context:r,top_k:i=5,format:t="detailed"}=j,e=await I(w),d=r.toLowerCase().replace(/[^a-z0-9\s\-_:.]/g," ").split(/\s+/).filter(u=>u.length>2),c=[];for(const u of d.slice(0,8)){const h=[],f=e.scanStream({match:`cachly:ckg:node:*${u}*`,count:50});await new Promise((p,y)=>{f.on("data",_=>h.push(..._)),f.on("end",p),f.on("error",y)});for(const p of h.slice(0,5)){const y=await e.get(p);if(!y)continue;const _=R(y,null);if(!_)continue;const x=await e.smembers(`cachly:ckg:idx:from:${_.id}`);for(const L of x.slice(0,20)){const g=await e.get(L);if(!g)continue;const S=R(g,null);if(!S||S.edgeType!=="causes"&&S.edgeType!=="degrades_under")continue;const $=await e.smembers(`cachly:ckg:idx:from:${S.to}`);let C;for(const N of $.slice(0,10)){const v=await e.get(N);if(!v)continue;const T=R(v,null);if(T&&T.edgeType==="fixes"){const B=await e.get(`cachly:lesson:best:${T.from}`);if(B){C=R(B,null)?.what_worked?.slice(0,120);break}}}c.push({concept:_.id,failure:S.to.replace(/-/g," "),probability:S.confidence,fix:C,source:"ckg"})}}}const a=[],o=e.scanStream({match:"cachly:lesson:best:*",count:300});await new Promise((u,h)=>{o.on("data",f=>a.push(...f)),o.on("end",u),o.on("error",h)});for(const u of a.slice(0,100)){const h=await e.get(u);if(h)try{const f=JSON.parse(h);if(f.outcome!=="failure"&&f.outcome!=="partial"||!f.what_failed)continue;const p=`${f.topic} ${f.what_failed}`.toLowerCase(),y=d.filter(x=>p.includes(x)).length/Math.max(1,d.length);if(y<.15)continue;const _=f.severity==="critical"?.15:f.severity==="major"?.05:0;c.push({concept:f.topic,failure:f.what_failed.slice(0,80),probability:Math.min(.97,(f.confidence??.5)*y*1.5+_),fix:f.what_worked?.slice(0,120),topic:f.topic,source:"lesson"})}catch{}}if(c.length===0)return[`\u{1F52E} **Failure Prediction: "${r}"**`,"","No known failure patterns found for this context.",'\u{1F4A1} The brain learns from every `learn_from_attempts(outcome="failure")` call.',`\u{1F50D} Try: \`brain_predict(context="${r}")\` for broader predictions.`].join(`
|
|
32
|
+
`);const l=new Set,m=c.filter(u=>{const h=u.failure.slice(0,40);return l.has(h)?!1:(l.add(h),!0)}).sort((u,h)=>h.probability-u.probability).slice(0,Number(i)),s=[`\u{1F52E} **Failure Prediction for: "${r}"**
|
|
33
|
+
`];s.push(`> Pre-deploy failure analysis based on ${c.length} patterns. Ranked by probability.
|
|
34
|
+
`);for(let u=0;u<m.length;u++){const h=m[u],f=Math.round(h.probability*100),p="\u2588".repeat(Math.round(f/10))+"\u2591".repeat(10-Math.round(f/10)),y=f>=70?"\u{1F534}":f>=40?"\u{1F7E1}":"\u{1F7E2}";s.push(`${y} **${u+1}. ${h.failure}**`),s.push(` Probability: ${p} **${f}%** (${h.source==="ckg"?"CKG causal edge":"lesson history"})`),t==="detailed"&&h.fix&&s.push(` \u2705 Pre-loaded fix: _${h.fix}_`),t==="detailed"&&h.topic&&s.push(` \u{1F4DA} Lesson: \`${h.topic}\``),s.push("")}const n=m.filter(u=>u.probability>=.6);return n.length>0?s.push(`\u26A0\uFE0F **${n.length} high-risk failure${n.length>1?"s":""} detected** (\u226560% probability). Review fixes before proceeding.`):s.push("\u2705 No high-risk failures detected. Proceed with caution and monitor closely."),s.push("",'\u{1F4A1} After deploy: `learn_from_attempts(topic="deploy:...", outcome="success|failure")` to improve future predictions.'),s.join(`
|
|
35
|
+
`)}case"brain_contribute_signal":{const{instance_id:w,topic_category:r,outcome:i,confidence:t=.5}=j;if(!r?.trim())throw new Error("topic_category is required");if(!["success","failure","partial"].includes(i))throw new Error("outcome must be success, failure, or partial");const e=t>=.75?"high":t>=.5?"medium":"low";let d="\u{1F4E6} Signal stored locally (commons API unavailable)";try{await K("/api/v1/federation/signals",{method:"POST",body:JSON.stringify({topic_category:r.trim().toLowerCase(),outcome:i,confidence:t})}),d="\u2705 Signal contributed to the global commons (no raw data shared)"}catch{const c=await I(w),a=`cachly:fed:outbox:${Date.now()}`;await c.set(a,JSON.stringify({topic_category:r,outcome:i,bucket:e,ts:new Date().toISOString()}),"EX",3600*24*7).catch(()=>{})}return[`\u{1F512} **Brain Contribute Signal: \`${r}\`**`,"",`\u{1F4CA} Outcome: **${i}** \xB7 Confidence bucket: **${e}**`,"\u{1F6E1}\uFE0F Privacy: topic category only \u2014 no lesson text, no org identity","",d,"","\u{1F4A1} When \u2265 k orgs contribute the same pattern, a meta-lesson appears in `brain_import_meta`."].join(`
|
|
36
|
+
`)}case"brain_import_meta":{const{instance_id:w,category:r,limit:i=20}=j;let t=[],e=3;try{const o=new URLSearchParams;r&&o.set("category",r),o.set("limit",String(Math.min(i,200)));const l=await K(`/api/v1/federation/meta?${o.toString()}`);t=l.meta_lessons??[],e=l.k_threshold??3}catch{return"\u274C Could not reach the global commons API. Try again later."}if(t.length===0)return["\u{1F310} **Brain Import Meta-Lessons**","",`No meta-lessons available yet (k-threshold: ${e} signals required).`,"","\u{1F4A1} Contribute signals with `brain_contribute_signal` to help build the commons."].join(`
|
|
37
|
+
`);const d=await I(w);let c=0;for(const o of t){const l=`cachly:lesson:best:meta:${o.topic_category}`;await d.get(l)||(await d.set(l,JSON.stringify({topic:`meta:${o.topic_category}`,outcome:o.dominant_outcome,what_worked:o.contributor_count!=null?`Meta-pattern from ${o.contributor_count} independent orgs`:`Meta-pattern from ${o.signal_count} signals`,what_failed:"",recall_count:0,ts:o.derived_at,state:"meta",avg_confidence:o.avg_confidence,signal_count:o.signal_count,audit_trail:[{ts:new Date().toISOString(),action:"imported_meta"}]})),c++)}const a=[`\u{1F310} **Brain Import Meta-Lessons** (k \u2265 ${e})`,"","| Topic Category | Outcome | Confidence | Signals |","|---|---|---|---|"];for(const o of t.slice(0,15)){const l=(o.avg_confidence*100).toFixed(0)+"%";a.push(`| \`${o.topic_category}\` | ${o.dominant_outcome} | ${l} | ${o.signal_count} |`)}return t.length>15&&a.push(`| _\u2026${t.length-15} more_ | | | |`),a.push("",`\u2705 **${c}** new meta-lessons imported into local Brain.`),c<t.length&&a.push(`_(${t.length-c} already present \u2014 not overwritten)_`),a.join(`
|
|
38
|
+
`)}case"brain_watch":{const{instance_id:w="",project_dir:r=".",api_key:i}=j,{resolve:t}=await import("node:path"),e=t(r),{result:d,hookPath:c}=await me(e,w,i);return d==="skipped-no-git"?["\u26A0\uFE0F **brain_watch: no git repository found**","",`No \`.git\` directory in \`${e}\`.`,"Pass `project_dir` pointing to a git checkout."].join(`
|
|
39
|
+
`):[`\u{1F9E0} **brain_watch ${{written:"\u2705 Hook installed (new)",upgraded:"\u{1F504} Hook upgraded to latest version",appended:"\u{1F4CE} Hook appended to existing post-commit script",unchanged:"\u2713 Hook already up to date \u2014 nothing changed"}[d]??d}**`,"",`Hook path: \`${c}\``,`Instance: \`${w||"(none \u2014 set CACHLY_BRAIN_INSTANCE_ID or pass instance_id)"}\``,"","Every future commit will automatically teach your Brain.","No manual `brain_from_git` needed \u2014 the hook runs silently in the background.","",'\u{1F4A1} Verify: `git commit --allow-empty -m "test brain_watch"` then `smart_recall(query="test")`'].join(`
|
|
40
|
+
`)}default:return null}}export{Je as FEDBRAIN_TOOL_NAMES,ke as _lastBrainFromCiCounts,be as _lastBrainFromGitCounts,Pe as handleFedbrainTool};
|