@cachly-dev/mcp-server 0.10.225 → 0.10.226

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 CHANGED
@@ -343,7 +343,7 @@ Manual snippets are in [Manual Setup](#manual-setup).
343
343
 
344
344
  | Editor / client | Auto-setup | Config file written | Global config | Notes |
345
345
  |---|---|---|---|---|
346
- | **Claude Code** | yes | `~/.claude/mcp.json` + `.mcp.json` | yes, always | Without a key: test Brain at session start (plugin) or on the first tool call; browser sign-in only as fallback |
346
+ | **Claude Code** | yes | `.mcp.json` | with the plugin | Without a key: test Brain at session start (plugin) or on the first tool call; browser sign-in only as fallback |
347
347
  | **Cursor** | yes, detected via `.cursor/` | `.cursor/mcp.json`, hooks in `.cursor/hooks.json` | no | Project-level; restart Cursor after setup. Lessons arrive with the first tool call of a turn |
348
348
  | **Windsurf** | yes, detected via `.windsurf/` | `.windsurf/mcp.json` | no | Project-level; restart Windsurf after setup |
349
349
  | **VS Code + Copilot** | yes, detected via `.vscode/` | `.vscode/mcp.json`, hooks in `.github/hooks/cachly-ambient.json` | no | Needs the VS Code MCP support or Copilot chat. Briefing at session start, lessons before each prompt |
@@ -361,14 +361,14 @@ Manual snippets are in [Manual Setup](#manual-setup).
361
361
  |---|---|
362
362
  | `autosetup` or `autopilot` from a terminal (TTY) | OAuth device flow: one click in the browser, the API key is saved automatically |
363
363
  | `autosetup` from a VS Code task or CI (no TTY) | Detects the non-interactive run, opens the browser with a step-by-step guide, prints the `CACHLY_JWT=... autosetup` command |
364
- | First tool call without any key | Test Brain: an anonymous Brain on EU servers. The key is saved to `~/.cachly/credentials.json` and `~/.claude/mcp.json`, and the call goes through. If that fails (offline, rate limit), the inline device flow starts with a URL and a code |
364
+ | First tool call without any key | Test Brain: an anonymous Brain on EU servers. The key is saved to `~/.cachly/credentials.json`, and the call goes through. If that fails (offline, rate limit), the inline device flow starts with a URL and a code |
365
365
  | First tool call with `CACHLY_BRAIN_INSTANCE_ID` set but no key | Inline device flow. You already have a Brain, so no second account is created |
366
366
  | `CACHLY_JWT=cky_live_xxx npx ... autosetup` | Skips the sign-in step and uses the key you pass |
367
367
 
368
368
  ## Manual Setup
369
369
 
370
370
  <details>
371
- <summary><b>Claude Code</b> (<code>~/.claude/mcp.json</code> or <code>.mcp.json</code>)</summary>
371
+ <summary><b>Claude Code</b> (<code>.mcp.json</code> in the project)</summary>
372
372
 
373
373
  ```json
374
374
  {
@@ -381,6 +381,10 @@ Manual snippets are in [Manual Setup](#manual-setup).
381
381
  }
382
382
  ```
383
383
 
384
+ For all your projects at once, use the plugin above, or
385
+ `claude mcp add -s user cachly -- npx -y @cachly-dev/mcp-server@latest`
386
+ (Claude Code stores that in `~/.claude.json`).
387
+
384
388
  Without a key, the first tool call creates a test Brain on EU servers. No sign-up.
385
389
  Run `npx @cachly-dev/mcp-server@latest autopilot` to use your own account instead.
386
390
  </details>
@@ -1 +1 @@
1
- const u=new Set;function i(e){if(e instanceof Error)return(e.message||e.name||"Error").slice(0,200);if(typeof e=="string")return e.slice(0,200)||"leerer Text geworfen";if(e===void 0)return"undefined geworfen (kein Grund mitgegeben)";if(e===null)return"null geworfen (kein Grund mitgegeben)";try{const n=JSON.stringify(e);return n&&n!=="{}"?n.slice(0,200):`${typeof e} ohne Inhalt geworfen`}catch{return`${typeof e} geworfen, nicht darstellbar`}}function c(e,n){return u.has(e)?!1:(u.add(e),console.error(`[aussetzer] ${e}: ${n}`),!0)}function l(e){return u.has(e)}function f(){return[...u]}function h(){u.clear()}const g="bedeutung-ohne-vektoren",E="bedeutung-ohne-dienst",m="bedeutung-ohne-fragevektor",p="bedeutung-abbruch",x="einbettung-beim-schreiben",d="versuch-laeuft-leer",s="cachly:aussetzer:",a=720*60*60;async function z(e,n,o){const r=c(n,o);if(!e)return r;try{const t=`${s}${n}`;await e.hincrby(t,"anzahl",1),await e.hset(t,{zuletzt:new Date().toISOString(),text:o.slice(0,500)}),await e.expire(t,a)}catch(t){c(`${n}-vermerk`,`der Aussetzer liess sich nicht vermerken (${t instanceof Error?t.message:String(t)}) \u2014 er steht nur in diesem Protokoll und ist nach einem Neustart weg`)}return r}async function k(e){if(!e)return null;try{const n=await e.keys(`${s}*`),o=[];for(const r of n){const t=await e.hgetall(r);!t||!t.anzahl||o.push({grund:r.slice(s.length),anzahl:Number(t.anzahl)||0,zuletzt:t.zuletzt??"",text:t.text??""})}return o.sort((r,t)=>t.anzahl-r.anzahl||r.grund.localeCompare(t.grund)),o}catch{return null}}export{a as AUSSETZER_TTL_SEKUNDEN,s as AUSSETZER_VORSATZ,E as OHNE_DIENST,m as OHNE_FRAGEVEKTOR,x as OHNE_SCHREIBVEKTOR,g as OHNE_VEKTOREN,p as SINNPFAD_ABBRUCH,d as VERSUCH_LEER,i as fehlerText,f as gemeldeteGruende,k as leseVermerke,c as meldeEinmal,z as meldeUndVermerke,l as schonGemeldet,h as setzeAussetzerZurueck};
1
+ const s=new Set;let u=!1;function l(){u=!0}function f(e){if(e instanceof Error)return(e.message||e.name||"Error").slice(0,200);if(typeof e=="string")return e.slice(0,200)||"leerer Text geworfen";if(e===void 0)return"undefined geworfen (kein Grund mitgegeben)";if(e===null)return"null geworfen (kein Grund mitgegeben)";try{const n=JSON.stringify(e);return n&&n!=="{}"?n.slice(0,200):`${typeof e} ohne Inhalt geworfen`}catch{return`${typeof e} geworfen, nicht darstellbar`}}function c(e,n){return s.has(e)?!1:(s.add(e),u||console.error(`[aussetzer] ${e}: ${n}`),!0)}function h(e){return s.has(e)}function g(){return[...s]}function E(){s.clear(),u=!1}const m="bedeutung-ohne-vektoren",p="bedeutung-ohne-dienst",x="bedeutung-ohne-fragevektor",d="bedeutung-abbruch",z="einbettung-beim-schreiben",k="versuch-laeuft-leer",a="cachly:aussetzer:",i=720*60*60;async function y(e,n,o){const r=c(n,o);if(!e)return r;try{const t=`${a}${n}`;await e.hincrby(t,"anzahl",1),await e.hset(t,{zuletzt:new Date().toISOString(),text:o.slice(0,500)}),await e.expire(t,i)}catch(t){c(`${n}-vermerk`,`der Aussetzer liess sich nicht vermerken (${t instanceof Error?t.message:String(t)}) \u2014 er steht nur in diesem Protokoll und ist nach einem Neustart weg`)}return r}async function S(e){if(!e)return null;try{const n=await e.keys(`${a}*`),o=[];for(const r of n){const t=await e.hgetall(r);!t||!t.anzahl||o.push({grund:r.slice(a.length),anzahl:Number(t.anzahl)||0,zuletzt:t.zuletzt??"",text:t.text??""})}return o.sort((r,t)=>t.anzahl-r.anzahl||r.grund.localeCompare(t.grund)),o}catch{return null}}export{i as AUSSETZER_TTL_SEKUNDEN,a as AUSSETZER_VORSATZ,p as OHNE_DIENST,x as OHNE_FRAGEVEKTOR,z as OHNE_SCHREIBVEKTOR,m as OHNE_VEKTOREN,d as SINNPFAD_ABBRUCH,k as VERSUCH_LEER,l as aussetzerLeise,f as fehlerText,g as gemeldeteGruende,S as leseVermerke,c as meldeEinmal,y as meldeUndVermerke,h as schonGemeldet,E as setzeAussetzerZurueck};
@@ -1,13 +1,13 @@
1
- import{zeitpunkt as u}from"./zeitmessung.js";const s={apiUrl:process.env.CACHLY_API_URL??"https://api.cachly.dev",jwt:process.env.CACHLY_JWT??"",model:process.env.CACHLY_EMBED_MODEL??""};function S(n){s.jwt=n,n&&!b&&c==="none"&&(c="cachly")}const A=Number(process.env.CACHLY_EMBED_TIMEOUT_MS??8e3),p=Number(process.env.CACHLY_EMBED_TIMEOUT_MAX_MS??45e3),h=12;function f(n,r){return r==="kurz"?A:Math.min(p,A+n.length*h)}function g(){return process.env.CACHLY_JWT?"cachly":process.env.OLLAMA_BASE_URL?"ollama":"none"}const b=!!process.env.CACHLY_EMBED_PROVIDER;let c=(process.env.CACHLY_EMBED_PROVIDER??g()).toLowerCase();async function I(n,r,a){const d=f(n,r);switch(c){case"cachly":{if(!s.jwt)throw new Error(`CACHLY_JWT not set.
1
+ import{zeitpunkt as A}from"./zeitmessung.js";const i={apiUrl:process.env.CACHLY_API_URL??"https://api.cachly.dev",jwt:process.env.CACHLY_JWT??"",model:process.env.CACHLY_EMBED_MODEL??""};function R(r){i.jwt=r,r&&!I&&d==="none"&&(d="cachly")}const h=Number(process.env.CACHLY_EMBED_TIMEOUT_MS??8e3),p=Number(process.env.CACHLY_EMBED_TIMEOUT_MAX_MS??45e3),g=12;function f(r,n){return n==="kurz"?h:Math.min(p,h+r.length*g)}function b(){return process.env.CACHLY_JWT?"cachly":process.env.OLLAMA_BASE_URL?"ollama":"none"}const I=!!process.env.CACHLY_EMBED_PROVIDER;let d=(process.env.CACHLY_EMBED_PROVIDER??b()).toLowerCase();async function y(r,n,s){const c=f(r,n);switch(d){case"cachly":{if(!i.jwt)throw new Error(`CACHLY_JWT not set.
2
2
 
3
3
  The "cachly" provider uses server-side embeddings via the Cachly API.
4
4
  Set CACHLY_JWT, or use another provider via CACHLY_EMBED_PROVIDER:
5
5
  openai \u2192 OPENAI_API_KEY
6
6
  gemini \u2192 GEMINI_API_KEY
7
- ollama \u2192 OLLAMA_BASE_URL (local, no key needed)`);const e=`${s.apiUrl}/api/v1/embed`,o={text:n};(a??s.model)&&(o.model=a??s.model);const t=process.env.CACHLY_ADMIN_KEY??"",i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.jwt}`,...t?{"X-Admin-Key":t}:{}},body:JSON.stringify(o),signal:AbortSignal.timeout(d)});if(!i.ok){const _=await i.text();let l=null;const m=Number(i.headers.get("retry-after"));if(Number.isFinite(m)&&m>=0)l=m;else try{const E=JSON.parse(_);typeof E.retry_after=="number"&&E.retry_after>=0&&(l=E.retry_after)}catch{}throw Object.assign(new Error(`Cachly embed API error ${i.status}: ${_.slice(0,200)}`),{status:i.status,retryAfterSek:l})}return(await i.json()).embedding}case"mistral":{const e=process.env.MISTRAL_API_KEY;if(!e)throw new Error("MISTRAL_API_KEY not set");const o=s.model!=="text-embedding-3-small"?s.model:"mistral-embed",t=await fetch("https://api.mistral.ai/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,input:[n]}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Mistral embedding error: ${t.statusText}`);const i=await t.json();if(!i.data?.[0]?.embedding)throw new Error("Mistral returned empty embedding response");return i.data[0].embedding}case"cohere":{const e=process.env.COHERE_API_KEY;if(!e)throw new Error("COHERE_API_KEY not set");const o=s.model!=="text-embedding-3-small"?s.model:"embed-english-v3.0",t=await fetch("https://api.cohere.com/v2/embed",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,texts:[n],input_type:"search_query",embedding_types:["float"]}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Cohere embedding error: ${t.statusText}`);return(await t.json()).embeddings.float[0]}case"ollama":{const e=process.env.OLLAMA_BASE_URL??"http://localhost:11434",o=a??(s.model!=="text-embedding-3-small"?s.model:"nomic-embed-text"),t=await fetch(`${e}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:o,prompt:n}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Ollama embedding error: ${t.statusText}`);return(await t.json()).embedding}case"gemini":{const e=process.env.GEMINI_API_KEY;if(!e)throw new Error("GEMINI_API_KEY not set");const o=s.model!=="text-embedding-3-small"?s.model:"text-embedding-004",t=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${o}:embedContent?key=${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:`models/${o}`,content:{parts:[{text:n}]}}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`Gemini embedding error: ${t.statusText}`);return(await t.json()).embedding.values}case"openai":{const e=process.env.OPENAI_API_KEY;if(!e)throw new Error(`OPENAI_API_KEY not set.
7
+ ollama \u2192 OLLAMA_BASE_URL (local, no key needed)`);const e=`${i.apiUrl}/api/v1/embed`,o={text:r};(s??i.model)&&(o.model=s??i.model);const t=process.env.CACHLY_ADMIN_KEY??"",a=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${i.jwt}`,...t?{"X-Admin-Key":t}:{}},body:JSON.stringify(o),signal:AbortSignal.timeout(c)});if(!a.ok){const _=await a.text();let E=null;const m=Number(a.headers.get("retry-after"));if(Number.isFinite(m)&&m>=0)E=m;else try{const u=JSON.parse(_);typeof u.retry_after=="number"&&u.retry_after>=0&&(E=u.retry_after)}catch{}throw Object.assign(new Error(`Cachly embed API error ${a.status}: ${_.slice(0,200)}`),{status:a.status,retryAfterSek:E})}return(await a.json()).embedding}case"mistral":{const e=process.env.MISTRAL_API_KEY;if(!e)throw new Error("MISTRAL_API_KEY not set");const o=i.model!=="text-embedding-3-small"?i.model:"mistral-embed",t=await fetch("https://api.mistral.ai/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,input:[r]}),signal:AbortSignal.timeout(c)});if(!t.ok)throw new Error(`Mistral embedding error: ${t.statusText}`);const a=await t.json();if(!a.data?.[0]?.embedding)throw new Error("Mistral returned empty embedding response");return a.data[0].embedding}case"cohere":{const e=process.env.COHERE_API_KEY;if(!e)throw new Error("COHERE_API_KEY not set");const o=i.model!=="text-embedding-3-small"?i.model:"embed-english-v3.0",t=await fetch("https://api.cohere.com/v2/embed",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,texts:[r],input_type:"search_query",embedding_types:["float"]}),signal:AbortSignal.timeout(c)});if(!t.ok)throw new Error(`Cohere embedding error: ${t.statusText}`);return(await t.json()).embeddings.float[0]}case"ollama":{const e=process.env.OLLAMA_BASE_URL??"http://localhost:11434",o=s??(i.model!=="text-embedding-3-small"?i.model:"nomic-embed-text"),t=await fetch(`${e}/api/embeddings`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:o,prompt:r}),signal:AbortSignal.timeout(c)});if(!t.ok)throw new Error(`Ollama embedding error: ${t.statusText}`);return(await t.json()).embedding}case"gemini":{const e=process.env.GEMINI_API_KEY;if(!e)throw new Error("GEMINI_API_KEY not set");const o=i.model!=="text-embedding-3-small"?i.model:"text-embedding-004",t=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${o}:embedContent?key=${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:`models/${o}`,content:{parts:[{text:r}]}}),signal:AbortSignal.timeout(c)});if(!t.ok)throw new Error(`Gemini embedding error: ${t.statusText}`);return(await t.json()).embedding.values}case"openai":{const e=process.env.OPENAI_API_KEY;if(!e)throw new Error(`OPENAI_API_KEY not set.
8
8
 
9
9
  Set OPENAI_API_KEY in your .env, or switch provider:
10
10
  CACHLY_EMBED_PROVIDER=gemini (+ GEMINI_API_KEY)
11
11
  CACHLY_EMBED_PROVIDER=ollama (local, free)
12
- CACHLY_EMBED_PROVIDER=cachly (server-side, no key needed)`);const o=s.model||"text-embedding-3-small",t=await fetch("https://api.openai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,input:n}),signal:AbortSignal.timeout(d)});if(!t.ok)throw new Error(`OpenAI embedding error: ${t.statusText}`);const i=await t.json();if(!i.data?.[0]?.embedding)throw new Error("OpenAI returned empty embedding response");return i.data[0].embedding}default:throw new Error(`Unknown CACHLY_EMBED_PROVIDER="${c}".
13
- Supported: cachly (default), openai, mistral, cohere, ollama, gemini`)}}const y=3,C=4;function w(n){const r=n;if(typeof r?.status=="number")return r.status===429||r.status>=500;if(r?.name==="TimeoutError"||r?.name==="AbortError")return!1;if(/fetch failed/i.test(String(r?.message??"")))return!0;const a=r?.cause?.code??"";return["ECONNRESET","ECONNREFUSED","ETIMEDOUT","EAI_AGAIN","EPIPE","UND_ERR_SOCKET"].includes(a)}function M(n,r,a){if(r>=(a==="lang"?C:y)||!w(n))return null;const e=n?.retryAfterSek;if(typeof e=="number"&&Number.isFinite(e)&&e>=0){const o=e*1e3;return a==="kurz"?o<=2e3?o:null:Math.min(o,61e3)}return a==="lang"?Math.min(1e3*2**(r-1),8e3):250*2**(r-1)}async function L(n,r){const a=r?.geduld??"kurz";if(r?.modell&&c!=="cachly"&&c!=="ollama")throw new Error(`Anbieter "${c}" kann kein abweichendes Modell anfragen (verlangt: ${r.modell}).`);let d=0;for(;;){d++;try{u(`einbettung: Anfang (${n.length} Zeichen, Versuch ${d})`);const e=await I(n,a,r?.modell);return u("einbettung: fertig"),e}catch(e){const o=M(e,d,a);if(o===null)throw e;await new Promise(t=>setTimeout(t,o))}}}function T(){switch(c){case"cachly":return!!s.jwt;case"mistral":return!!process.env.MISTRAL_API_KEY;case"cohere":return!!process.env.COHERE_API_KEY;case"ollama":return!0;case"gemini":return!!process.env.GEMINI_API_KEY;case"openai":return!!process.env.OPENAI_API_KEY;case"none":return!1;default:return!1}}function v(){const n={cachly:"CACHLY_JWT (server-side, no extra key needed)",openai:"OPENAI_API_KEY",mistral:"MISTRAL_API_KEY",cohere:"COHERE_API_KEY",ollama:"OLLAMA_BASE_URL (optional, default: http://localhost:11434)",gemini:"GEMINI_API_KEY"};if(c==="none")return"No embedding provider configured. Sign in (CACHLY_JWT) to use the EU-hosted cachly embeddings, or set OLLAMA_BASE_URL for a local model. Brain works without embedding.";const r=n[c]??"CACHLY_JWT";return`CACHLY_EMBED_PROVIDER=${c} \u2192 requires ${r}`}export{c as EMBED_PROVIDER,L as computeEmbedding,s as embedConfig,v as embedProviderHint,T as hasEmbedProvider,w as istVoruebergehend,S as setEmbedJwt,M as wiederholungMs,f as zeitlimitMs};
12
+ CACHLY_EMBED_PROVIDER=cachly (server-side, no key needed)`);const o=i.model||"text-embedding-3-small",t=await fetch("https://api.openai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:o,input:r}),signal:AbortSignal.timeout(c)});if(!t.ok)throw new Error(`OpenAI embedding error: ${t.statusText}`);const a=await t.json();if(!a.data?.[0]?.embedding)throw new Error("OpenAI returned empty embedding response");return a.data[0].embedding}default:throw new Error(`Unknown CACHLY_EMBED_PROVIDER="${d}".
13
+ Supported: cachly (default), openai, mistral, cohere, ollama, gemini`)}}const w=3,C=4;function M(r){const n=r;if(typeof n?.status=="number")return n.status===429||n.status>=500;if(n?.name==="TimeoutError"||n?.name==="AbortError")return!1;if(/fetch failed/i.test(String(n?.message??"")))return!0;const s=n?.cause?.code??"";return["ECONNRESET","ECONNREFUSED","ETIMEDOUT","EAI_AGAIN","EPIPE","UND_ERR_SOCKET"].includes(s)}function O(r,n,s){if(n>=(s==="lang"?C:w)||!M(r))return null;const e=r?.retryAfterSek;if(typeof e=="number"&&Number.isFinite(e)&&e>=0){const o=e*1e3;return s==="kurz"?o<=2e3?o:null:Math.min(o,61e3)}return s==="lang"?Math.min(1e3*2**(n-1),8e3):250*2**(n-1)}function N(r,n){const s=`${n?.modell??""}\0${n?.geduld??"kurz"}\0${r}`,c=Date.now(),e=l.get(s);if(e&&e.bis>c)return e.vektor;const o=T(r,n);if(l.set(s,{bis:c+P,vektor:o}),l.size>v){const t=l.keys().next().value;t!==void 0&&l.delete(t)}return o.catch(()=>{l.get(s)?.vektor===o&&l.delete(s)}),o}const P=6e4,v=200,l=new Map;function Y(){l.clear()}async function T(r,n){const s=n?.geduld??"kurz";if(n?.modell&&d!=="cachly"&&d!=="ollama")throw new Error(`Anbieter "${d}" kann kein abweichendes Modell anfragen (verlangt: ${n.modell}).`);let c=0;for(;;){c++;try{A(`einbettung: Anfang (${r.length} Zeichen, Versuch ${c})`);const e=await y(r,s,n?.modell);return A("einbettung: fertig"),e}catch(e){const o=O(e,c,s);if(o===null)throw e;await new Promise(t=>setTimeout(t,o))}}}function k(){switch(d){case"cachly":return!!i.jwt;case"mistral":return!!process.env.MISTRAL_API_KEY;case"cohere":return!!process.env.COHERE_API_KEY;case"ollama":return!0;case"gemini":return!!process.env.GEMINI_API_KEY;case"openai":return!!process.env.OPENAI_API_KEY;case"none":return!1;default:return!1}}function D(){const r={cachly:"CACHLY_JWT (server-side, no extra key needed)",openai:"OPENAI_API_KEY",mistral:"MISTRAL_API_KEY",cohere:"COHERE_API_KEY",ollama:"OLLAMA_BASE_URL (optional, default: http://localhost:11434)",gemini:"GEMINI_API_KEY"};if(d==="none")return"No embedding provider configured. Sign in (CACHLY_JWT) to use the EU-hosted cachly embeddings, or set OLLAMA_BASE_URL for a local model. Brain works without embedding.";const n=r[d]??"CACHLY_JWT";return`CACHLY_EMBED_PROVIDER=${d} \u2192 requires ${n}`}export{d as EMBED_PROVIDER,N as computeEmbedding,i as embedConfig,D as embedProviderHint,k as hasEmbedProvider,M as istVoruebergehend,R as setEmbedJwt,Y as vergissEinbettungen,O as wiederholungMs,f as zeitlimitMs};
@@ -1,4 +1,4 @@
1
- function l(o){if(!o)return null;const n=o.split(`
2
- `),t=n.findIndex(r=>/first recall already works/i.test(r));if(t===-1)return null;const e=[];for(let r=t;r<n.length&&!(r>t&&n[r].trim()==="");r++)e.push(n[r]);return e.join(`
3
- `).trim()||null}function s(o,n){const t=n.trim();return["\u{1F3AF} Proof \u2014 your first recall already works.",` Top hit: **${o}** \u2014 ${t}`].join(`
4
- `)}export{l as extractFirstRecallProof,s as renderFirstRecallProof};
1
+ function l(t){if(!t)return null;const r=t.split(`
2
+ `),e=r.findIndex(n=>/first recall already works/i.test(n));if(e===-1)return null;const i=[];for(let n=e;n<r.length&&!(n>e&&r[n].trim()==="");n++)i.push(r[n]);return i.join(`
3
+ `).trim()||null}function c(t,r){const e=r.trim();return["\u{1F3AF} Proof \u2014 your first recall already works.",` Top hit: ${t} \u2014 ${e}`].join(`
4
+ `)}function s(t){if(!t)return null;const r=/\*\*💡\s+([^*]+)\*\*/.exec(t);if(!r)return null;const e=t.slice(r.index+r[0].length),i=/^>\s+(.+)$/m.exec(e);if(!i)return null;const o=r[1].trim(),n=i[1].trim();return!o||!n?null:{topic:o,what:n}}function u(t){return t.replace(/\*\*/g,"").replace(/`/g,"")}export{l as extractFirstRecallProof,s as extractTopHit,u as fuersTerminal,c as renderFirstRecallProof};
@@ -0,0 +1 @@
1
+ import{createHash as r}from"node:crypto";function a(t){return`cachly:brain_from_git:last_sha:${r("sha256").update(t).digest("hex").slice(0,32)}`}function s(t){return`cachly:brain_from_git:last_sha:${Buffer.from(t).toString("base64").slice(0,32)}`}export{s as alterStartpunktSchluessel,a as startpunktSchluessel};
@@ -6,7 +6,7 @@ No matching lessons found in brain.`);if(w)return w;const d=await M(l),u=g.toLow
6
6
  `);const t=[`\u{1F50D} **Causal Trace: "${g}"**`,""];if(f.length>0){t.push("### \u{1F578}\uFE0F CKG Graph (confidence-ranked)");for(const o of f){const a=Math.round(o.edge.confidence*100),r="\u2593".repeat(Math.round(a/10))+"\u2591".repeat(10-Math.round(a/10));t.push(` ${o.edge.from} **\u2192[${o.edge.edgeType}]\u2192** ${o.edge.to}`),t.push(` ${r} ${a}% confidence (${o.edge.successes}/${o.edge.trials} confirmed)`),o.lesson?.what_worked&&t.push(` \u2705 Fix: ${o.lesson.what_worked.slice(0,150)}`),t.push("")}}if(v.length>0){t.push(f.length>0?`### \u{1F4DA} Text Search (${v.length} related lessons)`:`Found **${v.length}** related lessons. Reconstructed causal chain:`,"");const o=v.filter(p=>p.lesson.outcome!=="success"),a=v.filter(p=>p.lesson.outcome==="success");o.length>0&&(t.push("**Root causes & failure chain:**"),o.forEach((p,n)=>{const e=p.lesson,s=_[e.severity??"minor"]??"\u{1F7E1}";t.push(`${n===0?" Root:":" \u2192 :"} ${s} \`${e.topic}\``),e.what_failed&&t.push(` \u21B3 ${e.what_failed.slice(0,120)}`)}),t.push("")),a.length>0&&(t.push("**Solutions that worked before:**"),a.forEach((p,n)=>{const e=p.lesson,s=new Date(e.ts).toLocaleDateString("de-DE");t.push(` ${n+1}. \u2705 \`${e.topic}\` \u2014 ${s} \xB7 in ${e.recall_count??0} answers`),e.what_worked&&t.push(` ${e.what_worked.slice(0,200)}`)}),t.push(""));const r=a[0]?.lesson;if(r?.what_worked){t.push("**\u26A1 Most likely fix:**"),t.push("```"),t.push(r.what_worked.slice(0,500)),t.push("```"),t.push("");const p=F(r)?P(r,"trace"):0;p>0&&d.incrbyfloat(`cachly:stats:time_saved_mins:${l}`,p).catch(()=>{})}}return t.push(`\u{1F4A1} After applying: \`learn_from_attempts(topic="fix:${u[0]??"issue"}", outcome="success", ...)\``),f.length>0&&t.push(`\u{1F578}\uFE0F Explore graph: \`ckg_inspect(concept="${u[0]??"fix"}")\``),t.join(`
7
7
  `)}case"knowledge_decay":{let f=function(t){const o=Math.round(t/10);return"\u2588".repeat(o)+"\u2591".repeat(10-o)+` ${t}%`};const{instance_id:l,min_age_days:g=0,show_top:$=20}=S,m=await M(l),w=Date.now(),d=g*864e5;let u=0;const _=[];do{const[t,o]=await m.scan(u,"MATCH","cachly:lesson:best:*","COUNT",200);u=parseInt(t),_.push(...o)}while(u!==0);const c=[];for(const t of _){const o=await m.get(t);if(o){const a=x(o,null);if(!a)continue;const r=w-new Date(a.ts).getTime();if(r<d)continue;const p=Math.floor(r/864e5),n=a.recall_count??0,e=Math.max(0,p-7),s=Math.max(5,100-e),i=Math.min(50,n*5),D=a.outcome==="failure"?-20:0,T=Math.min(100,Math.max(0,s+i+D));c.push({topic:a.topic,confidence:T,age_days:p,recalls:n,outcome:a.outcome})}}c.sort((t,o)=>t.confidence-o.confidence);const y=c.slice(0,$),k=c.length>0?Math.round(c.reduce((t,o)=>t+o.confidence,0)/c.length):0,b=c.filter(t=>t.confidence<30).length,h=c.filter(t=>t.confidence>=70).length;return[`\u{1F9EA} **Knowledge Decay Report** \u2014 ${c.length} lessons`,"",`Average confidence: **${f(k)}**`,`\u{1F534} Critical (<30%): ${b} \u{1F7E2} Healthy (\u226570%): ${h}`,"","Lowest confidence lessons (fix these first):","",...y.map((t,o)=>`${(o+1).toString().padStart(2)}. \`${t.topic}\`
8
8
  ${f(t.confidence)} \xB7 ${t.age_days}d old \xB7 ${t.recalls} recalls \xB7 ${t.outcome}`),"",c.length>$?`\u2026 and ${c.length-$} more lessons`:"","",b>0?`\u26A0\uFE0F ${b} lessons are critically stale. Validate them and re-run \`learn_from_attempts\` with updated findings.`:"\u2705 Brain confidence is healthy overall.","","\u{1F4A1} Run `memory_consolidate` to prune stale entries \xB7 `causal_trace` to find root causes."].filter(t=>t!=="").join(`
9
- `)}case"autopilot":{const{instance_id:l,editor:g="claude",project_name:$="this project",style:m="full"}=S,w=z({editor:String(g),project_name:String($)},"die Anweisungsdatei (CLAUDE.md)");if(!w.ok)return w.meldung;const d=(b,h)=>b.replace(/[\p{C}\s]+/gu," ").trim().slice(0,h),u=d(w.felder.editor,30)||"claude",_=d(w.felder.project_name,80)||"this project",c=`## Cachly AI Brain \u2014 Autopilot
9
+ `)}case"autopilot":{const{instance_id:l,editor:g="claude",project_name:$="this project",style:m="full"}=S,w=z({editor:String(g),project_name:String($)},"the instruction file (CLAUDE.md)");if(!w.ok)return w.meldung;const d=(b,h)=>b.replace(/[\p{C}\s]+/gu," ").trim().slice(0,h),u=d(w.felder.editor,30)||"claude",_=d(w.felder.project_name,80)||"this project",c=`## Cachly AI Brain \u2014 Autopilot
10
10
 
11
11
  **Instance:** \`${l}\`
12
12