@cachly-dev/mcp-server 0.10.190 → 0.10.192

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
@@ -24,8 +24,9 @@ problem returns. Your Brain (the store of your lessons) lives on EU servers.
24
24
  /plugin install cachly-brain@cachly
25
25
  ```
26
26
 
27
- There is no JSON to write, no path to set and no key to copy. On the first tool call
28
- without a key, cachly creates a test Brain on EU servers. The test Brain has 14 days of
27
+ There is no JSON to write, no path to set and no key to copy. Without a key, cachly creates
28
+ a test Brain on EU servers when the session starts (the plugin hook does it; the first tool
29
+ call does it if the hook did not). The test Brain has 14 days of
29
30
  the Dev tier. After that it runs on the free tier with the same key.
30
31
 
31
32
  Check it with `claude mcp list`. You should see `plugin:cachly-brain:cachly … ✔ Connected`.
@@ -310,7 +311,7 @@ Manual snippets are in [Manual Setup](#manual-setup).
310
311
 
311
312
  | Editor / client | Auto-setup | Config file written | Global config | Notes |
312
313
  |---|---|---|---|---|
313
- | **Claude Code** | yes | `~/.claude/mcp.json` + `.mcp.json` | yes, always | Without a key: test Brain on the first tool call; browser sign-in only as fallback |
314
+ | **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 |
314
315
  | **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 |
315
316
  | **Windsurf** | yes, detected via `.windsurf/` | `.windsurf/mcp.json` | no | Project-level; restart Windsurf after setup |
316
317
  | **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 |
@@ -444,6 +445,9 @@ The free tier needs no credit card.
444
445
  | `CACHLY_PROFILE` | unset | `lean` lists 8 tools plus `cachly_tool`, `recall` lists the 3 read-only tools |
445
446
  | `CACHLY_UPDATE_CHECK` | on | Set to `false` to stop the version check. npm is asked at most once a day, with a 2-second limit |
446
447
  | `CACHLY_NO_TELEMETRY` | unset | Set to `1` to disable usage pings. They include your API token and up to 80 characters of `smart_recall` queries |
448
+ | `CACHLY_LERNEN` | on | Learning from use in the prompt hook. For 5 % of prompts the matching lessons are computed but not shown (control group), up to 10 % try a stricter or shorter setting. At the end of each turn the hook reports which setting ran and whether the agent named a shown lesson; topics are sent hashed, prompts never. Set to `0` (or `CACHLY_NO_TELEMETRY=1`) to turn it off |
449
+ | `CACHLY_KONTROLLE_ANTEIL` | `5%` | Share of prompts in the control group. `0` turns the control group off, at most `50%` |
450
+ | `CACHLY_ERKUNDUNG` | `10%` | Share of prompts that may try another setting. `0` keeps the leading setting, at most `10%` |
447
451
 
448
452
  ## Ecosystem and docs
449
453
 
@@ -1,2 +1,2 @@
1
- import{promptEinblendung as c,holeBestand as u,sitzungsKontext as l,hookAusgabe as i,estimateTokens as a}from"./einblendung.js";function f(e){const t=(e??"").trim();if(!t)return null;try{const n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}const m=new Set(["Edit","Write","MultiEdit","NotebookEdit"]);function p(e){const t=e.hook_event_name??"UserPromptSubmit";if(t==="SessionStart"||t==="Stop")return null;if(t==="PreToolUse"){if(e.tool_name&&!m.has(e.tool_name))return null;const r=e.tool_input?.file_path;if(typeof r!="string"||!r.trim())return null;const o=r.trim().replace(/\\/g,"/"),s=(e.cwd??"").replace(/\\/g,"/").replace(/\/+$/,"");return s&&o.toLowerCase().startsWith(s.toLowerCase()+"/")?o.slice(s.length+1):o}return(e.prompt??"").trim()||null}const g=/\b(fixed|resolved|behoben|gefixt|root cause|the bug was|der fehler (lag|war)|ursache (war|gefunden)|now passes|tests? (are|is|sind) (green|grün)|deployed successfully)\b/i;function b(e){const t=(e.last_assistant_message??"").trim();return t.length<80||!g.test(t)?null:{action:(t.split(`
2
- `).find(r=>r.trim().length>0)?.trim()??t).slice(0,200),outcome:"success",details:t.slice(0,500),severity:"minor"}}function d(e){const t=e.action.toLowerCase().replace(/[^a-z0-9:\-_\s]/g,"").trim().split(/\s+/).slice(0,4).join("-");return{topic:t?t.includes(":")?t:`auto:${t}`:"auto:stop",outcome:e.outcome,what_worked:e.action,context:e.details,severity:e.severity,source:"ambient-stop",tags:["auto-learned"]}}const x=i,h=5e3;async function k(e,t){try{const n=f(e);if(!n)return"";const r=n.hook_event_name??"UserPromptSubmit";if(!t.cfg.jwt||!t.cfg.instanceId)return"";let o="";if(r==="SessionStart"){const{lessons:s}=await u(t.cfg,{force:!0,fetchFn:t.fetchFn});o=l(s)}else{const s=p(n);if(s===null)return"";o=(await c(s,t.cfg,{nebenlauf:t.nebenlauf,abrufMs:h,leser:r!=="PreToolUse",session:n.session_id??null,protokoll:t.protokoll,fetchFn:t.fetchFn})).kontext}if(!o)return"";try{t.onInject?.(a(o),r)}catch{}return i(r,o)}catch{return""}}export{h as PROMPT_ABRUF_MS,x as buildHookOutput,f as parseHookPayload,p as recallQueryFor,k as runEinblendung,d as stopLernanfrage,b as stopObservation};
1
+ import{promptEinblendung as c,holeBestand as u,sitzungsKontext as l,hookAusgabe as i,estimateTokens as a}from"./einblendung.js";function f(e){const t=(e??"").trim();if(!t)return null;try{const n=JSON.parse(t);return n&&typeof n=="object"?n:null}catch{return null}}const m=new Set(["Edit","Write","MultiEdit","NotebookEdit"]);function p(e){const t=e.hook_event_name??"UserPromptSubmit";if(t==="SessionStart"||t==="Stop")return null;if(t==="PreToolUse"){if(e.tool_name&&!m.has(e.tool_name))return null;const r=e.tool_input?.file_path;if(typeof r!="string"||!r.trim())return null;const o=r.trim().replace(/\\/g,"/"),s=(e.cwd??"").replace(/\\/g,"/").replace(/\/+$/,"");return s&&o.toLowerCase().startsWith(s.toLowerCase()+"/")?o.slice(s.length+1):o}return(e.prompt??"").trim()||null}const g=/\b(fixed|resolved|behoben|gefixt|root cause|the bug was|der fehler (lag|war)|ursache (war|gefunden)|now passes|tests? (are|is|sind) (green|grün)|deployed successfully)\b/i;function w(e){const t=(e.last_assistant_message??"").trim();return t.length<80||!g.test(t)?null:{action:(t.split(`
2
+ `).find(r=>r.trim().length>0)?.trim()??t).slice(0,200),outcome:"success",details:t.slice(0,500),severity:"minor"}}function b(e){const t=e.action.toLowerCase().replace(/[^a-z0-9:\-_\s]/g,"").trim().split(/\s+/).slice(0,4).join("-");return{topic:t?t.includes(":")?t:`auto:${t}`:"auto:stop",outcome:e.outcome,what_worked:e.action,context:e.details,severity:e.severity,source:"ambient-stop",tags:["auto-learned"]}}const x=i,h=5e3;async function k(e,t){try{const n=f(e);if(!n)return"";const r=n.hook_event_name??"UserPromptSubmit";if(!t.cfg.jwt||!t.cfg.instanceId)return"";let o="";if(r==="SessionStart"){const{lessons:s}=await u(t.cfg,{force:!0,fetchFn:t.fetchFn});o=l(s)}else{const s=p(n);if(s===null)return"";o=(await c(s,t.cfg,{nebenlauf:t.nebenlauf,abrufMs:h,leser:r!=="PreToolUse",session:n.session_id??null,protokoll:t.protokoll,ereignis:r,editor:t.editor,fetchFn:t.fetchFn})).kontext}if(!o)return"";try{t.onInject?.(a(o),r)}catch{}return i(r,o)}catch{return""}}export{h as PROMPT_ABRUF_MS,x as buildHookOutput,f as parseHookPayload,p as recallQueryFor,k as runEinblendung,b as stopLernanfrage,w as stopObservation};
@@ -1,2 +1,4 @@
1
- import{readFileSync as P}from"node:fs";import{parseHookPayload as g,runEinblendung as U,stopLernanfrage as k,stopObservation as y}from"./ambient-cli.js";import{stopAntwort as O}from"./schreibbeleg.js";import{holeBestand as I}from"./einblendung.js";import{appendLedgerEntry as T,reportLedgerEntry as E}from"./ambient-ledger.js";import{copilotHatHook as F,cursorHatHook as C,findeInstanz as S,findeSchluessel as _,hookUmfeld as h,projektHatHook as v}from"./hook-zugang.js";import{CURSOR_FLAG as l,cursorEreignis as w,cursorHookAntwort as R,cursorLeer as j,istCursorNutzlast as x}from"./cursor-hook.js";import{COPILOT_FLAG as b,copilotEreignis as N,copilotHookAntwort as G,istFremdeLaufzeit as z}from"./copilot-hook.js";import{CODEX_FLAG as B,codexHookAntwort as D}from"./codex-hook.js";import{GEMINI_FLAG as A,geminiEreignis as Y,geminiHookAntwort as K}from"./gemini-hook.js";const M="https://api.cachly.dev",$="ambient-auffrischen",H=new Set(["SessionStart","UserPromptSubmit","PreToolUse","Stop"]);async function J(t,e){if(!t.args.includes(l)&&(w(e,t.args)!=="sessionStart"||C(t.umfeld)))return"";const o=t.args.filter(n=>n==="--plugin");return R({payload:e,args:t.args,claudeLauf:(n,u)=>p({...t,raw:n,args:[u,...o]}),ablageOrdner:t.cursorAblage})}function V(t,e){const r=(o,n)=>p({...t,raw:o,args:[n]});return t.args.includes(b)?G({payload:e,args:t.args,claudeLauf:r,ablageOrdner:t.copilotAblage}):t.args.includes(B)?D({payload:e,args:t.args,claudeLauf:r}):t.args.includes(A)?K({payload:e,args:t.args,claudeLauf:r}):null}async function p(t){try{const e=g(t.raw);if(t.args.includes(l)||x(e))return await J(t,e);const r=V(t,e);if(r)return await r;const o=e?.hook_event_name??t.args.find(i=>H.has(i))??t.umfeld.env.CACHLY_HOOK_EVENT??"";if(z(e)&&(o!=="SessionStart"&&o!=="UserPromptSubmit"||F(t.umfeld))||t.args.includes("--plugin")&&o&&v(o,t.umfeld))return"";if(o==="Stop"&&e?.transcript_path)try{const i=P(e.transcript_path,"utf-8").split(`
2
- `),f=O(i,e.stop_hook_active===!0);if(f)return f}catch{}const n=_(t.umfeld),u=S(t.umfeld);if(!n||!u)return"";const c={apiUrl:t.apiUrl,jwt:n,instanceId:u};if(o==="Stop"){const i=e?y(e):null;return i&&await(t.fetchFn??fetch)(`${c.apiUrl}/api/v1/instances/${c.instanceId}/learn`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c.jwt}`},body:JSON.stringify(k(i)),signal:AbortSignal.timeout(8e3)}).catch(()=>{}),""}let a;const s=await(t.einblenden??U)(t.raw,{cfg:c,nebenlauf:t.selbst?[t.selbst,$]:void 0,fetchFn:t.fetchFn,onInject:(i,f)=>{const m={ts:new Date().toISOString(),event:f,injected:i,prevented:0};T(m),a=E(c,m,t.fetchFn)}});return a&&await Promise.race([a,new Promise(i=>setTimeout(i,500))]),s}catch{return""}}async function X(){if(process.stdin.isTTY)return"";const t=[];for await(const e of process.stdin)t.push(e);return Buffer.concat(t).toString("utf-8")}function L(){return process.env.CACHLY_API_URL||M}const d={SessionStart:25e3,UserPromptSubmit:8e3,PreToolUse:8e3,Stop:5e4,sessionStart:25e3,beforeSubmitPrompt:8e3,postToolUse:3e3,userPromptSubmitted:8e3,PostToolUse:3e3,BeforeAgent:8e3};function q(t,e){return t.includes(l)?j(w(e,t)):t.includes(b)?N(e,t)?"{}":"":t.includes(A)&&Y(e,t)?"{}":""}async function ct(t,e){try{const r=await X(),o=g(r),n=o?.hook_event_name??t.find(s=>H.has(s)||Object.hasOwn(d,s))??"",u=Number(process.env.CACHLY_HOOK_FRIST_MS)||d[n]||d.UserPromptSubmit,c=q(t,o),a=await Promise.race([p({args:t,raw:r,umfeld:h(),apiUrl:L(),selbst:e}),new Promise(s=>setTimeout(()=>s(c),u))]);a&&await new Promise(s=>process.stdout.write(a,()=>s()))}catch{}process.exit(0)}async function ut(){try{const t=h(),e=_(t),r=S(t);e&&r&&await I({apiUrl:L(),jwt:e,instanceId:r},{force:!0})}catch{}process.exit(0)}export{$ as AUFFRISCHEN,d as HOOK_FRIST_MS,M as STANDARD_API_URL,ut as auffrischenHauptlauf,p as hookAntwort,ct as hookHauptlauf};
1
+ import{readFileSync as F}from"node:fs";import{parseHookPayload as k,runEinblendung as T,stopLernanfrage as v,stopObservation as C}from"./ambient-cli.js";import{stopAntwort as x}from"./schreibbeleg.js";import{holeBestand as K,hookAusgabe as z}from"./einblendung.js";import{belohnungMelden as N}from"./lernen.js";import{appendLedgerEntry as j,reportLedgerEntry as R}from"./ambient-ledger.js";import{copilotHatHook as M,cursorHatHook as G,findeInstanz as A,findeSchluessel as H,hookUmfeld as b,pluginVersion as B,projektHatHook as Y}from"./hook-zugang.js";import{ABKUEHLUNG_HOOK_MS as $,schreibeAuftrag as D,sichereKonto as J,startwissenEingeschaltet as V}from"./konto-anlegen.js";import{istInstanzKennung as Q,sofortTestHinweis as X}from"./zugang.js";import{CURSOR_FLAG as p,cursorEreignis as O,cursorHookAntwort as q,cursorLeer as W,istCursorNutzlast as y}from"./cursor-hook.js";import{COPILOT_FLAG as g,copilotEreignis as Z,copilotHookAntwort as tt,istFremdeLaufzeit as I}from"./copilot-hook.js";import{CODEX_FLAG as U,codexHookAntwort as et}from"./codex-hook.js";import{GEMINI_FLAG as h,geminiEreignis as nt,geminiHookAntwort as rt}from"./gemini-hook.js";const ot="https://api.cachly.dev",L=5e3,it="ambient-auffrischen",P=new Set(["SessionStart","UserPromptSubmit","PreToolUse","Stop"]);async function st(t,e){if(!t.args.includes(p)&&(O(e,t.args)!=="sessionStart"||G(t.umfeld)))return"";const i=t.args.filter(r=>r==="--plugin");return q({payload:e,args:t.args,claudeLauf:(r,u)=>S({...t,raw:r,args:[u,...i]}),ablageOrdner:t.cursorAblage})}function ct(t,e){const n=(i,r)=>S({...t,raw:i,args:[r]});return t.args.includes(g)?tt({payload:e,args:t.args,claudeLauf:n,ablageOrdner:t.copilotAblage}):t.args.includes(U)?et({payload:e,args:t.args,claudeLauf:n}):t.args.includes(h)?rt({payload:e,args:t.args,claudeLauf:n}):null}function ut(t,e){return t.includes(p)||y(e)?"cursor":t.includes(g)?"copilot":t.includes(U)?"codex":t.includes(h)?"gemini":I(e)?"vscode":"claude"}async function at(t){const e=await J({apiUrl:t.apiUrl,version:B(t.umfeld),home:t.umfeld.heim,env:{...t.umfeld.env,CACHLY_QUELLE:"claude-code-plugin"},fristMs:L,anfrageMs:L,abkuehlungMs:$,holen:t.fetchFn});return e.art==="vorhanden"?{apiKey:e.apiKey,instanzId:e.instanzId,hinweis:""}:e.art!=="angelegt"?null:(V(t.umfeld.env)&&D({instanzId:e.test.instanzId,projekt:t.umfeld.projekt},{home:t.umfeld.heim}),{apiKey:e.test.apiKey,instanzId:e.test.instanzId,hinweis:X(e.test)})}function ft(t,e){const n=e.replace(/^\s+/,"");if(!t)return z("SessionStart",n);try{const i=JSON.parse(t),r=i.hookSpecificOutput?.additionalContext;return!i.hookSpecificOutput||typeof r!="string"?t:(i.hookSpecificOutput.additionalContext=`${n}
2
+
3
+ ${r}`,JSON.stringify(i))}catch{return t}}async function S(t){try{const e=k(t.raw),n={...t,editor:t.editor??ut(t.args,e)};if(n.args.includes(p)||y(e))return await st(n,e);const i=ct(n,e);if(i)return await i;const r=e?.hook_event_name??n.args.find(o=>P.has(o))??n.umfeld.env.CACHLY_HOOK_EVENT??"";if(I(e)&&(r!=="SessionStart"&&r!=="UserPromptSubmit"||M(n.umfeld))||n.args.includes("--plugin")&&r&&Y(r,n.umfeld))return"";let u=null;if(r==="Stop"&&e?.transcript_path)try{u=F(e.transcript_path,"utf-8").split(`
4
+ `);const o=x(u,e.stop_hook_active===!0);if(o)return o}catch{}let a=H(n.umfeld),c=A(n.umfeld),s="";if(!a&&r==="SessionStart"&&n.args.includes("--plugin")&&!Q(c)){const o=await at(n);o&&(a=o.apiKey,c=o.instanzId??c,s=o.hinweis)}if(!a||!c)return"";const f={apiUrl:n.apiUrl,jwt:a,instanceId:c};if(r==="Stop"){const o=e?C(e):null,m=o?(n.fetchFn??fetch)(`${f.apiUrl}/api/v1/instances/${f.instanceId}/learn`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.jwt}`},body:JSON.stringify(v(o)),signal:AbortSignal.timeout(8e3)}).catch(()=>{}):void 0,l=N(f,e?.session_id??null,u,{fetchFn:n.fetchFn});return await Promise.all([m,l]),""}let d;const w=await(n.einblenden??T)(n.raw,{cfg:f,nebenlauf:n.selbst?[n.selbst,it]:void 0,editor:n.editor,fetchFn:n.fetchFn,onInject:(o,m)=>{const l={ts:new Date().toISOString(),event:m,injected:o,prevented:0};j(l),d=R(f,l,n.fetchFn)}});return d&&await Promise.race([d,new Promise(o=>setTimeout(o,500))]),s?ft(w,s):w}catch{return""}}async function lt(){if(process.stdin.isTTY)return"";const t=[];for await(const e of process.stdin)t.push(e);return Buffer.concat(t).toString("utf-8")}function E(){return process.env.CACHLY_API_URL||ot}const _={SessionStart:25e3,UserPromptSubmit:8e3,PreToolUse:8e3,Stop:5e4,sessionStart:25e3,beforeSubmitPrompt:8e3,postToolUse:3e3,userPromptSubmitted:8e3,PostToolUse:3e3,BeforeAgent:8e3};function pt(t,e){return t.includes(p)?W(O(e,t)):t.includes(g)?Z(e,t)?"{}":"":t.includes(h)&&nt(e,t)?"{}":""}async function It(t,e){try{const n=await lt(),i=k(n),r=i?.hook_event_name??t.find(s=>P.has(s)||Object.hasOwn(_,s))??"",u=Number(process.env.CACHLY_HOOK_FRIST_MS)||_[r]||_.UserPromptSubmit,a=pt(t,i),c=await Promise.race([S({args:t,raw:n,umfeld:b(),apiUrl:E(),selbst:e}),new Promise(s=>setTimeout(()=>s(a),u))]);c&&await new Promise(s=>process.stdout.write(c,()=>s()))}catch{}process.exit(0)}async function Ut(){try{const t=b(),e=H(t),n=A(t);e&&n&&await K({apiUrl:E(),jwt:e,instanceId:n},{force:!0,lernen:!0})}catch{}process.exit(0)}export{it as AUFFRISCHEN,_ as HOOK_FRIST_MS,L as KONTO_FRIST_MS,ot as STANDARD_API_URL,Ut as auffrischenHauptlauf,ut as editorVon,S as hookAntwort,It as hookHauptlauf};
@@ -1,8 +1,8 @@
1
- import{readFileSync as I,existsSync as v,writeFileSync as b,mkdirSync as D,statSync as Y,appendFileSync as J}from"node:fs";import{dirname as k,join as h}from"node:path";import{tmpdir as m}from"node:os";import{createHash as q}from"node:crypto";import{spawn as Z}from"node:child_process";import{Einblendbestand as x,torWoerter as L}from"./einblendung-kern.js";import{rahmeEin as N}from"./einblendung-rahmen.js";import{istMarkiert as z}from"./verdacht-marke.js";import{leserText as F}from"./seltenheitsbestand.js";import{mischeMitLeser as C}from"./leser.js";import{LeserSicherung as G,dateiSpeicher as K,frageLeser as W}from"./leser-sicherung.js";import{LESER_TIEFE_EINBLENDUNG as V,LESER_ZEITLIMIT_MS as X}from"./rangfolge-stellschrauben.js";import{stufeEinblendungNachVersion as Q}from"./gueltigkeit-version.js";export*from"./einblendung-kern.js";const ee=600*1e3,T=8e3,te=60*1e3,j=120,$=V,ne=1500,R=X,re=h(m(),"cachly-ambient-netlog.jsonl");function xe(e=process.cwd()){const t={apiUrl:process.env.CACHLY_API_URL||"https://api.cachly.dev",jwt:process.env.CACHLY_JWT||"",instanceId:process.env.CACHLY_BRAIN_INSTANCE_ID||""};if(t.jwt&&t.instanceId)return t;let n=e;for(let o=0;o<8;o++){const s=h(n,".mcp.json");if(v(s))try{const i=JSON.parse(I(s,"utf8"))?.mcpServers?.cachly?.env??{};if(t.apiUrl=t.apiUrl||i.CACHLY_API_URL||"https://api.cachly.dev",t.jwt=t.jwt||i.CACHLY_JWT||"",t.instanceId=t.instanceId||i.CACHLY_BRAIN_INSTANCE_ID||"",t.jwt&&t.instanceId)return t}catch{}const r=k(n);if(r===n)break;n=r}return t}function S(e){return q("sha1").update(e).digest("hex").slice(0,12)}function se(e){return h(m(),`cachly-ambient-bestand-${S(e)}.json`)}function oe(e){return h(m(),`cachly-leser-sicherung-${S(e)}.json`)}function ie(e){return h(m(),`cachly-ambient-auffrischen-${S(e)}.lock`)}async function M(e,{fetchFn:t=fetch,zeitlimitMs:n=T}={}){try{const o=await t(`${e.apiUrl}/api/v1/instances/${e.instanceId}/export`,{headers:{Authorization:`Bearer ${e.jwt}`},signal:AbortSignal.timeout(n)});if(!o.ok)return null;const s=await o.json();return Array.isArray(s?.lessons)?s.lessons.map(r=>typeof r=="string"?ae(r):r).filter(r=>!!r&&typeof r=="object"):null}catch{return null}}function ae(e){try{return JSON.parse(e)}catch{return null}}function H(e,t){try{D(k(e),{recursive:!0}),b(e,JSON.stringify({at:Date.now(),lessons:t}),{mode:384})}catch{}}function O(e){try{const t=JSON.parse(I(e,"utf8"));if(Array.isArray(t?.lessons))return{at:Number(t.at)||0,lessons:t.lessons}}catch{}return null}function ce(e,t){const n=ie(e.instanceId);try{if(v(n)&&Date.now()-Y(n).mtimeMs<te)return;b(n,String(Date.now()),{mode:384})}catch{return}try{Z(process.execPath,t,{detached:!0,stdio:"ignore",env:{...process.env,CACHLY_API_URL:e.apiUrl,CACHLY_JWT:e.jwt,CACHLY_BRAIN_INSTANCE_ID:e.instanceId}}).unref()}catch{}}async function le(e,{force:t=!1,nebenlauf:n,abrufMs:o=T,fetchFn:s}={}){if(!e.jwt||!e.instanceId)return{lessons:[],quelle:"nicht-eingerichtet"};const r=se(e.instanceId);if(t){const c=await M(e,{fetchFn:s,zeitlimitMs:o});if(c)return H(r,c),{lessons:c,quelle:"server"};const l=O(r);return l?{lessons:l.lessons,quelle:"platte-alt"}:{lessons:[],quelle:"server-nicht-erreichbar"}}const i=O(r);if(i){const c=Date.now()-i.at<ee;return!c&&n&&ce(e,n),{lessons:i.lessons,quelle:c?"platte":"platte-alt"}}const u=await M(e,{fetchFn:s,zeitlimitMs:o});return u?(H(r,u),{lessons:u,quelle:"server"}):{lessons:[],quelle:"server-nicht-erreichbar"}}function g(e){return Math.ceil(String(e).length/4)}function E(e){const t=e.severity?`[${e.severity}] `:"",n=String(e.what_worked??"").replace(/\s+/g," ").trim(),o=n.length>j?`${n.slice(0,j)}\u2026`:n,s=typeof e.versionshinweis=="string"?` [${e.versionshinweis}]`:"";return`- ${t}${e.topic}${s}: ${o}`}const d={lessons:[],tokens:0,topScore:0,belege:0};function U(e,t,n){const o=[];let s=0;e=Q(e);for(const{lektion:r}of e.slice(0,t)){const i=g(E(r));if(s+i>n)break;o.push(r),s+=i}return{lessons:o,tokens:s,topScore:Math.round(e[0].punkte*100)/100,belege:e[0].belege}}function Le(e,t,{minBelege:n=2,topK:o=3,tokenBudget:s=600}={}){if(!Array.isArray(t)||t.length===0)return{...d};if(L(e).length===0)return{...d};const r=new x(t).sortiere(e).filter(i=>i.belege>=n);return r.length===0?{...d}:U(r,o,s)}function ue(e){return F(e,ne)}async function B(e,t,n,{zeitlimitMs:o=R,fetchFn:s}={}){if(!e?.jwt||!e?.instanceId||n.length===0)return{art:"ohne"};if(["0","off","aus","false"].includes(String(process.env.CACHLY_LESER||"").toLowerCase()))return{art:"ohne"};const r=new G(K(oe(e.instanceId)));return W({url:`${e.apiUrl}/api/v1/rerank`,jwt:e.jwt,frage:t,texte:n,instanceId:e.instanceId,zeitlimitMs:o,fetchFn:s},r)}async function Ne(e,t,n,o={}){const s=await B(e,t,n,o);return s.art==="punkte"?{scores:s.scores,provider:s.provider,ms:s.ms}:null}async function pe(e,t,n,{minBelege:o=2,topK:s=3,tokenBudget:r=600,tiefe:i=$,zeitlimitMs:u=R,fetchFn:c}={}){const l={...d,leser:"aus",leserMs:0};if(!Array.isArray(t)||t.length===0||L(e).length===0)return l;let a=new x(t).sortiere(e).filter(p=>p.belege>=o);if(a.length===0)return l;let y="aus",w=0;if(a.length>1&&i>0){const p=a.slice(0,i),P=a.slice(i),f=await B(n,e,p.map(A=>ue(A.lektion)),{zeitlimitMs:u,fetchFn:c});f.art==="punkte"?(a=[...C(p.map(_=>_.punkte),f.scores,1).map(_=>p[_]),...P],y=f.provider,w=f.ms):f.art==="uebersprungen"&&(y="uebersprungen")}return{...U(a,s,r),leser:y,leserMs:w}}function fe(e){if(!e.lessons.length)return"";const t=e.lessons.map(E).join(`
1
+ import{readFileSync as T,existsSync as C,writeFileSync as R,mkdirSync as Y,statSync as Z,appendFileSync as G}from"node:fs";import{dirname as j,join as _}from"node:path";import{tmpdir as S}from"node:os";import{createHash as F}from"node:crypto";import{spawn as W}from"node:child_process";import{Einblendbestand as $,torWoerter as B}from"./einblendung-kern.js";import{rahmeEin as U}from"./einblendung-rahmen.js";import{istMarkiert as V}from"./verdacht-marke.js";import{leserText as X}from"./seltenheitsbestand.js";import{mischeMitLeser as z}from"./leser.js";import{LeserSicherung as Q,dateiSpeicher as ee,frageLeser as te}from"./leser-sicherung.js";import{LESER_TIEFE_EINBLENDUNG as ne,LESER_ZEITLIMIT_MS as re}from"./rangfolge-stellschrauben.js";import{stufeEinblendungNachVersion as se}from"./gueltigkeit-version.js";import{ARME as H,BASIS_MIN_BELEGE as oe,MERKMAL_KANDIDATEN as ie,OHNE_LERNEN as le,entscheide as ae,leseArmZaehlung as ce,lernEinstellungen as ue,lernenAuffrischen as pe,merkeEntscheidung as fe,neuerSatz as he,sitzungsKennung as me,zugKennung as de}from"./lernen.js";export*from"./einblendung-kern.js";import{belohnungMelden as it,lernenAuffrischen as lt,lernEinstellungen as at,ARME as ct}from"./lernen.js";const ge=600*1e3,Ee=300*1e3,_e=10*1e3,Se=2e3,Ae=50,ke=60*1e3;function Ie(e,t){return t<Ee?{ttlMs:_e,sofort:!0}:e<Ae?{ttlMs:ke,sofort:!1}:{ttlMs:ge,sofort:!1}}const O=8e3,Ne=60*1e3,P=120,D=ne,ye=1500,I=re,be=_(S(),"cachly-ambient-netlog.jsonl");function We(e=process.cwd()){const t={apiUrl:process.env.CACHLY_API_URL||"https://api.cachly.dev",jwt:process.env.CACHLY_JWT||"",instanceId:process.env.CACHLY_BRAIN_INSTANCE_ID||""};if(t.jwt&&t.instanceId)return t;let n=e;for(let s=0;s<8;s++){const o=_(n,".mcp.json");if(C(o))try{const i=JSON.parse(T(o,"utf8"))?.mcpServers?.cachly?.env??{};if(t.apiUrl=t.apiUrl||i.CACHLY_API_URL||"https://api.cachly.dev",t.jwt=t.jwt||i.CACHLY_JWT||"",t.instanceId=t.instanceId||i.CACHLY_BRAIN_INSTANCE_ID||"",t.jwt&&t.instanceId)return t}catch{}const r=j(n);if(r===n)break;n=r}return t}function N(e){return F("sha1").update(e).digest("hex").slice(0,12)}function we(e){return _(S(),`cachly-ambient-bestand-${N(e)}.json`)}function Me(e){return _(S(),`cachly-leser-sicherung-${N(e)}.json`)}function Le(e){return _(S(),`cachly-ambient-auffrischen-${N(e)}.lock`)}async function y(e,{fetchFn:t=fetch,zeitlimitMs:n=O}={}){try{const s=await t(`${e.apiUrl}/api/v1/instances/${e.instanceId}/export`,{headers:{Authorization:`Bearer ${e.jwt}`},signal:AbortSignal.timeout(n)});if(!s.ok)return null;const o=await s.json();return Array.isArray(o?.lessons)?o.lessons.map(r=>typeof r=="string"?ve(r):r).filter(r=>!!r&&typeof r=="object"):null}catch{return null}}function ve(e){try{return JSON.parse(e)}catch{return null}}function b(e,t){try{const n=Date.now(),s=w(e)?.seit??n;Y(j(e),{recursive:!0}),R(e,JSON.stringify({at:n,seit:s,lessons:t}),{mode:384})}catch{}}function w(e){try{const t=JSON.parse(T(e,"utf8"));if(Array.isArray(t?.lessons)){const n=Number(t.at)||0;return{at:n,seit:Number(t.seit)||n,lessons:t.lessons}}}catch{}return null}function xe(e,t){const n=Le(e.instanceId);try{if(C(n)&&Date.now()-Z(n).mtimeMs<Ne)return;R(n,String(Date.now()),{mode:384})}catch{return}try{W(process.execPath,t,{detached:!0,stdio:"ignore",env:{...process.env,CACHLY_API_URL:e.apiUrl,CACHLY_JWT:e.jwt,CACHLY_BRAIN_INSTANCE_ID:e.instanceId}}).unref()}catch{}}async function Te(e,{force:t=!1,nebenlauf:n,abrufMs:s=O,lernen:o=!1,fetchFn:r}={}){if(!e.jwt||!e.instanceId)return{lessons:[],quelle:"nicht-eingerichtet"};const i=we(e.instanceId);if(t){const[a]=await Promise.all([y(e,{fetchFn:r,zeitlimitMs:s}),o?pe(e,{fetchFn:r}):void 0]);if(a)return b(i,a),{lessons:a,quelle:"server"};const f=w(i);return f?{lessons:f.lessons,quelle:"platte-alt"}:{lessons:[],quelle:"server-nicht-erreichbar"}}const l=w(i);if(l){const a=Date.now(),f=Ie(l.lessons.length,a-l.seit);if(a-l.at<f.ttlMs)return{lessons:l.lessons,quelle:"platte"};if(f.sofort){const m=await y(e,{fetchFn:r,zeitlimitMs:Math.min(s,Se)});return m?(b(i,m),{lessons:m,quelle:"server"}):{lessons:l.lessons,quelle:"platte-alt"}}return n&&xe(e,n),{lessons:l.lessons,quelle:"platte-alt"}}const u=await y(e,{fetchFn:r,zeitlimitMs:s});return u?(b(i,u),{lessons:u,quelle:"server"}):{lessons:[],quelle:"server-nicht-erreichbar"}}function M(e){return Math.ceil(String(e).length/4)}function L(e){const t=e.severity?`[${e.severity}] `:"",n=String(e.what_worked??"").replace(/\s+/g," ").trim(),s=n.length>P?`${n.slice(0,P)}\u2026`:n,o=typeof e.versionshinweis=="string"?` [${e.versionshinweis}]`:"";return`- ${t}${e.topic}${o}: ${s}`}const A={lessons:[],tokens:0,topScore:0,belege:0};function v(e,t,n){if(e.length===0)return{...A};const s=[];let o=0;e=se(e);for(const{lektion:r}of e.slice(0,t)){const i=M(L(r));if(o+i>n)break;s.push(r),o+=i}return{lessons:s,tokens:o,topScore:Math.round(e[0].punkte*100)/100,belege:e[0].belege}}function Ve(e,t,{minBelege:n=2,topK:s=3,tokenBudget:o=600}={}){if(!Array.isArray(t)||t.length===0)return{...A};if(B(e).length===0)return{...A};const r=new $(t).sortiere(e).filter(i=>i.belege>=n);return r.length===0?{...A}:v(r,s,o)}function Ce(e){return X(e,ye)}async function J(e,t,n,{zeitlimitMs:s=I,fetchFn:o}={}){if(!e?.jwt||!e?.instanceId||n.length===0)return{art:"ohne"};if(["0","off","aus","false"].includes(String(process.env.CACHLY_LESER||"").toLowerCase()))return{art:"ohne"};const r=new Q(ee(Me(e.instanceId)));return te({url:`${e.apiUrl}/api/v1/rerank`,jwt:e.jwt,frage:t,texte:n,instanceId:e.instanceId,zeitlimitMs:s,fetchFn:o},r)}async function Xe(e,t,n,s={}){const o=await J(e,t,n,s);return o.art==="punkte"?{scores:o.scores,provider:o.provider,ms:o.ms}:null}async function K(e,t,n,{minBelege:s,tiefe:o,zeitlimitMs:r,fetchFn:i}){const l={sortiert:[],leser:"aus",leserMs:0};if(!Array.isArray(t)||t.length===0||B(e).length===0)return l;let u=new $(t).sortiere(e).filter(h=>h.belege>=s);if(u.length===0)return l;let a="aus",f=0;if(u.length>1&&o>0){const h=u.slice(0,o),m=u.slice(o),d=await J(n,e,h.map(E=>Ce(E.lektion)),{zeitlimitMs:r,fetchFn:i});d.art==="punkte"?(u=[...z(h.map(p=>p.punkte),d.scores,1).map(p=>({...h[p],leser:d.scores[p]})),...m],a=d.provider,f=d.ms):d.art==="uebersprungen"&&(a="uebersprungen")}return{sortiert:u,leser:a,leserMs:f}}async function Qe(e,t,n,{minBelege:s=2,topK:o=3,tokenBudget:r=600,tiefe:i=D,zeitlimitMs:l=I,fetchFn:u}={}){const a=await K(e,t,n,{minBelege:s,tiefe:i,zeitlimitMs:l,fetchFn:u});return{...v(a.sortiert,o,r),leser:a.leser,leserMs:a.leserMs}}function Re(e){if(!e.lessons.length)return"";const t=e.lessons.map(L).join(`
2
2
  `);return`\u{1F9E0} Cachly Brain \u2014 relevant lessons for this task (auto-recall, ${e.lessons.length}):
3
- ${N(t)}
4
- (ambient-recall \xB7 ~${e.tokens} tokens \xB7 match score ${e.topScore})`}const he=5;function Ce(e){const t=e.filter(r=>!z(r));if(!t.length)return"";const n=t.filter(r=>{const i=String(r.topic??"");return!(/^auto:/.test(i)||/^[a-z]+:?$/.test(i))}),s=[...n.length?n:t].sort((r,i)=>(Number(i.recall_count)||0)-(Number(r.recall_count)||0)).slice(0,he).map(E).join(`
3
+ ${U(t)}
4
+ (ambient-recall \xB7 ~${e.tokens} tokens \xB7 match score ${e.topScore})`}const je=5;function et(e){const t=e.filter(r=>!V(r));if(!t.length)return"";const n=t.filter(r=>{const i=String(r.topic??"");return!(/^auto:/.test(i)||/^[a-z]+:?$/.test(i))}),o=[...n.length?n:t].sort((r,i)=>(Number(i.recall_count)||0)-(Number(r.recall_count)||0)).slice(0,je).map(L).join(`
5
5
  `);return`\u{1F9E0} Cachly Brain \u2014 ambient recall active (${t.length} lessons). Top by proven reuse:
6
- ${N(s)}
7
- (Relevant lessons for each task are auto-injected per prompt. ~${g(s)} tokens.)`}function Te(e,t){return t?JSON.stringify({hookSpecificOutput:{hookEventName:e,additionalContext:t}}):""}async function je(e,t,{nebenlauf:n,abrufMs:o,leser:s=!0,session:r=null,protokoll:i=!0,fetchFn:u}={}){const{lessons:c,quelle:l}=await le(t,{nebenlauf:n,abrufMs:o,fetchFn:u}),a=await pe(e,c,t,{tiefe:s?$:0,fetchFn:u});if(i)try{J(re,JSON.stringify({at:Date.now(),session:r,prompt_tokens:g(e),injected_tokens:a.tokens,matches:a.lessons.length,top_score:a.topScore,belege:a.belege,leser:a.leser,leser_ms:a.leserMs,quelle:l,bestand:c.length})+`
8
- `)}catch{}return{kontext:fe(a),auswahl:a,quelle:l,bestand:c.length}}export{T as ABRUF_TIMEOUT_MS,j as ANZEIGE_ZEICHEN,ee as BESTAND_TTL_MS,R as LESER_HOOK_ZEITLIMIT_MS,ne as LESER_MAX_ZEICHEN,$ as LESER_TIEFE,re as NETZ_PROTOKOLL,he as SITZUNG_TOP_N,se as bestandPfad,g as estimateTokens,le as holeBestand,Te as hookAusgabe,B as leserAnfrageApi,Ne as leserPunkteApi,ue as leserText,C as mischeMitLeser,je as promptEinblendung,fe as promptKontext,E as renderLesson,xe as resolveConfig,Le as selectRelevant,pe as selectRelevantMitLeser,oe as sicherungsPfad,Ce as sitzungsKontext,ce as starteNebenlauf};
6
+ ${U(o)}
7
+ (Relevant lessons for each task are auto-injected per prompt. ~${M(o)} tokens.)`}function tt(e,t){return t?JSON.stringify({hookSpecificOutput:{hookEventName:e,additionalContext:t}}):""}function $e(e,t){return e.map((n,s)=>({x:n,rang:s,gezeigt:t.includes(n.lektion)})).filter(({rang:n,gezeigt:s})=>n<ie||s).map(({x:n,rang:s,gezeigt:o})=>({thema:String(n.lektion.topic??""),rang:s,punkte:Math.round(n.punkte*1e3)/1e3,belege:n.belege,leser:typeof n.leser=="number"&&Number.isFinite(n.leser)?Math.round(n.leser*1e3)/1e3:null,gezeigt:o}))}async function nt(e,t,{nebenlauf:n,abrufMs:s,leser:o=!0,session:r=null,protokoll:i=!0,ereignis:l="UserPromptSubmit",editor:u="",lernen:a=!0,fetchFn:f}={}){const{lessons:h,quelle:m}=await Te(t,{nebenlauf:n,abrufMs:s,fetchFn:f}),d=ue(),E=a&&d.aktiv&&l==="UserPromptSubmit"&&!!t.instanceId,p=E?ae({instanceId:t.instanceId,sitzung:r,prompt:e,zaehlung:ce(t.instanceId),einstellungen:d}):le,x=H[p.arm]??H[0],g=await K(e,h,t,{minBelege:oe,tiefe:o?D:0,zeitlimitMs:I,fetchFn:f}),c={...v(g.sortiert.filter(q=>q.belege>=x.minBelege),x.topK,600),leser:g.leser,leserMs:g.leserMs},k=p.kontrolle?"":Re(c);if(E&&g.sortiert.length>0&&fe(t.instanceId,r,he({sitzung:me(r),zug:de(e),ereignis:l,editor:u,arm:p.arm,kontrolle:p.kontrolle,erkundet:p.erkundet,ausgewaehlt:c.lessons.length,kandidatenZahl:g.sortiert.length,belege:c.belege,topScore:c.topScore,leser:c.leser,leserMs:c.leserMs,quelle:m,bestand:h.length,kandidaten:$e(g.sortiert,c.lessons)})),i)try{G(be,JSON.stringify({at:Date.now(),session:r,prompt_tokens:M(e),injected_tokens:k?c.tokens:0,matches:k?c.lessons.length:0,arm:p.arm,kontrolle:p.kontrolle,ausgewaehlt:c.lessons.length,top_score:c.topScore,belege:c.belege,leser:c.leser,leser_ms:c.leserMs,quelle:m,bestand:h.length})+`
8
+ `)}catch{}return{kontext:k,auswahl:c,quelle:m,bestand:h.length,entscheidung:p}}export{O as ABRUF_TIMEOUT_MS,P as ANZEIGE_ZEICHEN,ct as ARME,_e as BESTAND_TTL_JUNG_MS,ke as BESTAND_TTL_KLEIN_MS,ge as BESTAND_TTL_MS,Se as JUNG_ABRUF_MS,Ee as JUNG_FENSTER_MS,Ae as KLEIN_LEKTIONEN,I as LESER_HOOK_ZEITLIMIT_MS,ye as LESER_MAX_ZEICHEN,D as LESER_TIEFE,be as NETZ_PROTOKOLL,je as SITZUNG_TOP_N,it as belohnungMelden,Ie as bestandFrist,we as bestandPfad,M as estimateTokens,Te as holeBestand,tt as hookAusgabe,at as lernEinstellungen,lt as lernenAuffrischen,J as leserAnfrageApi,Xe as leserPunkteApi,Ce as leserText,z as mischeMitLeser,nt as promptEinblendung,Re as promptKontext,L as renderLesson,We as resolveConfig,Ve as selectRelevant,Qe as selectRelevantMitLeser,Me as sicherungsPfad,et as sitzungsKontext,xe as starteNebenlauf};
@@ -1 +1 @@
1
- import{readdirSync as u,readFileSync as f}from"node:fs";import{homedir as l}from"node:os";import{join as n}from"node:path";import{readInstanceId as j,resolveApiKey as k}from"./credentials.js";import{echterWert as d}from"./zugang.js";function E(o=process.env){return{env:o,heim:o.HOME||o.USERPROFILE||l(),projekt:o.CLAUDE_PROJECT_DIR||process.cwd()}}function i(o){try{return JSON.parse(f(o,"utf8"))}catch{return null}}function a(o){return[n(o.heim,".claude","mcp.json"),n(o.projekt,".mcp.json"),n(o.heim,".cursor","mcp.json"),n(o.heim,".codeium","windsurf","mcp_config.json")].map(e=>{const r=i(e)?.mcpServers?.cachly?.env;return r&&typeof r=="object"?r:{}})}function h(...o){for(const e of o){const r=d(e);if(r)return r}return""}function H(o){return h(o.env.CLAUDE_PLUGIN_OPTION_API_KEY,k({env:o.env,home:o.heim,cwd:o.projekt}),...a(o).map(e=>e.CACHLY_JWT))}function N(o){return h(o.env.CLAUDE_PLUGIN_OPTION_INSTANCE_ID,o.env.CACHLY_BRAIN_INSTANCE_ID,j({home:o.heim}),...a(o).map(e=>e.CACHLY_BRAIN_INSTANCE_ID))}const m="cachly-ambient-";function S(o){return[n(o.projekt,".cursor","hooks.json"),n(o.heim,".cursor","hooks.json")].some(e=>{const r=i(e)?.hooks;return!!r&&typeof r=="object"&&Object.values(r).some(t=>Array.isArray(t)&&t.some(s=>String(s?.command??"").includes(m)))})}function A(o){const e=o;return[e?.command,e?.bash,e?.powershell].some(r=>String(r??"").includes(m))}function g(o){const e=o.env.COPILOT_HOME?n(o.env.COPILOT_HOME,"hooks"):n(o.heim,".copilot","hooks");return[n(o.projekt,".github","hooks"),e].some(r=>{let t;try{t=u(r).filter(s=>s.endsWith(".json"))}catch{return!1}return t.some(s=>{const c=i(n(r,s))?.hooks;return!!c&&typeof c=="object"&&Object.values(c).some(p=>Array.isArray(p)&&p.some(A))})})}function v(o,e){return[n(e.projekt,".claude","settings.json"),n(e.projekt,".claude","settings.local.json"),n(e.heim,".claude","settings.json")].some(r=>{const t=i(r)?.hooks?.[o];return Array.isArray(t)&&t.some(s=>Array.isArray(s?.hooks)&&s.hooks.some(c=>String(c?.command??"").includes(m)))})}export{m as PROJEKT_HOOK_MARKE,g as copilotHatHook,S as cursorHatHook,N as findeInstanz,H as findeSchluessel,E as hookUmfeld,A as istCachlyEintrag,v as projektHatHook};
1
+ import{readdirSync as f,readFileSync as l}from"node:fs";import{homedir as k}from"node:os";import{join as n}from"node:path";import{readInstanceId as d,resolveApiKey as j}from"./credentials.js";import{echterWert as a}from"./zugang.js";function E(o=process.env){return{env:o,heim:o.HOME||o.USERPROFILE||k(),projekt:o.CLAUDE_PROJECT_DIR||process.cwd()}}function i(o){try{return JSON.parse(l(o,"utf8"))}catch{return null}}function u(o){return[n(o.heim,".claude","mcp.json"),n(o.projekt,".mcp.json"),n(o.heim,".cursor","mcp.json"),n(o.heim,".codeium","windsurf","mcp_config.json")].map(e=>{const r=i(e)?.mcpServers?.cachly?.env;return r&&typeof r=="object"?r:{}})}function h(...o){for(const e of o){const r=a(e);if(r)return r}return""}function g(o){return h(o.env.CLAUDE_PLUGIN_OPTION_API_KEY,j({env:o.env,home:o.heim,cwd:o.projekt}),...u(o).map(e=>e.CACHLY_JWT))}function v(o){return h(o.env.CLAUDE_PLUGIN_OPTION_INSTANCE_ID,o.env.CACHLY_BRAIN_INSTANCE_ID,d({home:o.heim}),...u(o).map(e=>e.CACHLY_BRAIN_INSTANCE_ID))}function N(o){const e=a(o.env.CLAUDE_PLUGIN_ROOT);if(!e)return"unbekannt";const r=i(n(e,".claude-plugin","plugin.json"))?.version;return typeof r=="string"&&/^\d[0-9A-Za-z.+-]{0,30}$/.test(r)?r:"unbekannt"}const m="cachly-ambient-";function H(o){return[n(o.projekt,".cursor","hooks.json"),n(o.heim,".cursor","hooks.json")].some(e=>{const r=i(e)?.hooks;return!!r&&typeof r=="object"&&Object.values(r).some(t=>Array.isArray(t)&&t.some(s=>String(s?.command??"").includes(m)))})}function A(o){const e=o;return[e?.command,e?.bash,e?.powershell].some(r=>String(r??"").includes(m))}function L(o){const e=o.env.COPILOT_HOME?n(o.env.COPILOT_HOME,"hooks"):n(o.heim,".copilot","hooks");return[n(o.projekt,".github","hooks"),e].some(r=>{let t;try{t=f(r).filter(s=>s.endsWith(".json"))}catch{return!1}return t.some(s=>{const c=i(n(r,s))?.hooks;return!!c&&typeof c=="object"&&Object.values(c).some(p=>Array.isArray(p)&&p.some(A))})})}function S(o,e){return[n(e.projekt,".claude","settings.json"),n(e.projekt,".claude","settings.local.json"),n(e.heim,".claude","settings.json")].some(r=>{const t=i(r)?.hooks?.[o];return Array.isArray(t)&&t.some(s=>Array.isArray(s?.hooks)&&s.hooks.some(c=>String(c?.command??"").includes(m)))})}export{m as PROJEKT_HOOK_MARKE,L as copilotHatHook,H as cursorHatHook,v as findeInstanz,g as findeSchluessel,E as hookUmfeld,A as istCachlyEintrag,N as pluginVersion,S as projektHatHook};