@cachly-dev/mcp-server 0.10.174 → 0.10.175

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
@@ -467,7 +467,7 @@ following. Manual snippets are in the **Manual Setup** section below.
467
467
 
468
468
  | Editor / Client | Auto-setup | Config file written | Global config | Notes |
469
469
  |---|---|---|---|---|
470
- | **Claude Code** | ✅ | `~/.claude/mcp.json` + `.mcp.json` | ✅ global always | Runtime device-flow sign-in on first tool call |
470
+ | **Claude Code** | ✅ | `~/.claude/mcp.json` + `.mcp.json` | ✅ global always | No key: test Brain on first tool call; browser sign-in only as fallback |
471
471
  | **Cursor** | ✅ detected via `.cursor/` | `.cursor/mcp.json` | — | Project-level; restart Cursor after setup |
472
472
  | **Windsurf** | ✅ detected via `.windsurf/` | `.windsurf/mcp.json` | — | Project-level; restart Windsurf after setup |
473
473
  | **VS Code + Copilot** | ✅ detected via `.vscode/` | `.vscode/mcp.json` | — | Requires VS Code MCP extension or Copilot chat |
@@ -483,7 +483,8 @@ following. Manual snippets are in the **Manual Setup** section below.
483
483
  |---|---|
484
484
  | `autosetup` from a real terminal (TTY) | OAuth device-flow → browser click → API key saved automatically |
485
485
  | `autosetup` from VSCode task / CI (non-TTY) | Auto-detects non-interactive, opens browser with step-by-step guide, prints `CACHLY_JWT=... autosetup` instruction |
486
- | First tool call from Claude Code (no JWT yet) | Inline device-flow: MCP returns URL + code, browser opens automatically, next call proceeds |
486
+ | First tool call without any key | Instant trial: an anonymous test Brain on EU servers, key saved to `~/.cachly/credentials.json` and `~/.claude/mcp.json`, the call proceeds. If that fails (offline, rate limit): inline device-flow with URL + code |
487
+ | First tool call with `CACHLY_BRAIN_INSTANCE_ID` set but no key | Inline device-flow (you already have a Brain — no second account is created) |
487
488
  | `CACHLY_JWT=cky_live_xxx npx ... autosetup` | Skips auth step entirely, uses provided key |
488
489
 
489
490
  > **Tip — fastest per-project setup from inside Claude Code:**
@@ -509,7 +510,8 @@ following. Manual snippets are in the **Manual Setup** section below.
509
510
  }
510
511
  }
511
512
  ```
512
- On the first tool call your AI will prompt you to sign in — takes 10 seconds.
513
+ Without a key, the first tool call creates a test Brain on EU servers — no sign-up.
514
+ Run `npx @cachly-dev/mcp-server@latest autopilot` to use your own account instead.
513
515
  </details>
514
516
 
515
517
  <details>
@@ -1,2 +1,2 @@
1
- import{promptEinblendung as l,holeBestand as u,sitzungsKontext as c,hookAusgabe as i,estimateTokens as f}from"./einblendung.js";function a(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"}}const S=i,h=5e3;async function k(e,t){try{const n=a(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=c(s)}else{const s=p(n);if(s===null)return"";o=(await l(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?.(f(o),r)}catch{}return i(r,o)}catch{return""}}export{h as PROMPT_ABRUF_MS,S as buildHookOutput,a as parseHookPayload,p as recallQueryFor,k as runEinblendung,w 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 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};
@@ -0,0 +1 @@
1
+ import{fileURLToPath as o}from"node:url";import{AUFFRISCHEN as r,auffrischenHauptlauf as t,hookHauptlauf as i}from"./ambient-hook.js";const a=process.argv.slice(2);a[0]===r?await t():await i(a,o(import.meta.url));
@@ -0,0 +1,2 @@
1
+ import{readFileSync as w}from"node:fs";import{parseHookPayload as f,runEinblendung as y,stopLernanfrage as b,stopObservation as g}from"./ambient-cli.js";import{stopAntwort as U}from"./schreibbeleg.js";import{holeBestand as P}from"./einblendung.js";import{appendLedgerEntry as I,reportLedgerEntry as A}from"./ambient-ledger.js";import{findeInstanz as u,findeSchluessel as l,hookUmfeld as d,projektHatHook as H}from"./hook-zugang.js";const T="https://api.cachly.dev",v="ambient-auffrischen",m=new Set(["SessionStart","UserPromptSubmit","PreToolUse","Stop"]);async function k(t){try{const e=f(t.raw),n=e?.hook_event_name??t.args.find(o=>m.has(o))??t.umfeld.env.CACHLY_HOOK_EVENT??"";if(t.args.includes("--plugin")&&n&&H(n,t.umfeld))return"";if(n==="Stop"&&e?.transcript_path)try{const o=w(e.transcript_path,"utf-8").split(`
2
+ `),a=U(o,e.stop_hook_active===!0);if(a)return a}catch{}const i=l(t.umfeld),c=u(t.umfeld);if(!i||!c)return"";const s={apiUrl:t.apiUrl,jwt:i,instanceId:c};if(n==="Stop"){const o=e?g(e):null;return o&&await(t.fetchFn??fetch)(`${s.apiUrl}/api/v1/instances/${s.instanceId}/learn`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s.jwt}`},body:JSON.stringify(b(o)),signal:AbortSignal.timeout(8e3)}).catch(()=>{}),""}let r;const _=await(t.einblenden??y)(t.raw,{cfg:s,nebenlauf:t.selbst?[t.selbst,v]:void 0,fetchFn:t.fetchFn,onInject:(o,a)=>{const p={ts:new Date().toISOString(),event:a,injected:o,prevented:0};I(p),r=A(s,p,t.fetchFn)}});return r&&await Promise.race([r,new Promise(o=>setTimeout(o,500))]),_}catch{return""}}async function O(){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 h(){return process.env.CACHLY_API_URL||T}const S={SessionStart:25e3,UserPromptSubmit:8e3,PreToolUse:8e3,Stop:5e4};async function R(t,e){try{const n=await O(),i=f(n)?.hook_event_name??t.find(r=>m.has(r))??"",c=Number(process.env.CACHLY_HOOK_FRIST_MS)||S[i]||S.UserPromptSubmit,s=await Promise.race([k({args:t,raw:n,umfeld:d(),apiUrl:h(),selbst:e}),new Promise(r=>setTimeout(()=>r(""),c))]);s&&await new Promise(r=>process.stdout.write(s,()=>r()))}catch{}process.exit(0)}async function N(){try{const t=d(),e=l(t),n=u(t);e&&n&&await P({apiUrl:h(),jwt:e,instanceId:n},{force:!0})}catch{}process.exit(0)}export{v as AUFFRISCHEN,S as HOOK_FRIST_MS,T as STANDARD_API_URL,N as auffrischenHauptlauf,k as hookAntwort,R as hookHauptlauf};
@@ -1,5 +1,6 @@
1
- import{existsSync as v}from"node:fs";import{readFile as E,writeFile as y,chmod as N,mkdir as A}from"node:fs/promises";import{resolve as S}from"node:path";const O="v4",H="ambient-recall",w=`npx @cachly-dev/mcp-server@latest ${H}`;function P(t){return t.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function d(t,o){const e=o.cliCommand??w;return["#!/usr/bin/env node",`// cachly Ambient Recall \u2014 ${t} ${O}`,"// Pushes relevant memory into context automatically. Cross-platform Node hook","// (no shell script \u2014 runs identically on Windows/macOS/Linux). Never blocks","// the agent: every failure path exits 0 with no output (graceful degrade).","import { spawn } from 'node:child_process';",`process.env.CACHLY_BRAIN_INSTANCE_ID = '${P(o.instanceId)}';`,"if (!process.env.CACHLY_JWT && process.env.CACHLY_API_KEY) process.env.CACHLY_JWT = process.env.CACHLY_API_KEY;",`process.env.CACHLY_HOOK_EVENT = '${P(t)}';`,"try {",` const child = spawn('${P(e)}', { shell: true, stdio: ['inherit', 'inherit', 'ignore'] });`," child.on('error', () => process.exit(0));"," child.on('close', () => process.exit(0));","} catch {"," process.exit(0);","}"].join(`
2
- `)}function L(t){return d("SessionStart",t)}function R(t){return d("UserPromptSubmit",t)}function $(t){return d("PreToolUse",t)}function M(t){return d("Stop",t)}const Y={SessionStart:30,UserPromptSubmit:10,PreToolUse:10,Stop:60},F="Edit|Write|MultiEdit|NotebookEdit";function J(t){const o=(c,n,r)=>({...r?{matcher:r}:{},hooks:[{type:"command",command:`node "${n}"`,timeout:Y[c]}]}),e={SessionStart:[o("SessionStart",t.sessionStart)],UserPromptSubmit:[o("UserPromptSubmit",t.userPromptSubmit)]};return t.preToolUse&&(e.PreToolUse=[o("PreToolUse",t.preToolUse,F)]),t.stop&&(e.Stop=[o("Stop",t.stop)]),e}const C=".claude/hooks",j=".claude/settings.json",k={SessionStart:"cachly-ambient-session-start.mjs",UserPromptSubmit:"cachly-ambient-prompt-submit.mjs",PreToolUse:"cachly-ambient-pre-tool.mjs",Stop:"cachly-ambient-stop.mjs"},K=".claude/hooks/cachly-ambient-";function B(t,o){const e=t.hooks??[];return e.length>0&&e.every(c=>{const n=c.command??"";return n.includes(K)||o.has(n)||[...o].some(r=>n.includes(`"${r}"`))})}function D(t,o){const e={...t,hooks:{...t.hooks??{}}},c=e.hooks,n=J(o),r=new Set([o.sessionStart,o.userPromptSubmit,o.preToolUse,o.stop].filter(a=>!!a));for(const[a,i]of Object.entries(n)){const f=(Array.isArray(c[a])?c[a]:[]).filter(m=>!B(m,r));c[a]=[...f,...i]}const l=JSON.stringify(e)!==JSON.stringify(t);return{settings:e,changed:l}}async function q(t,o,e,c={}){const n=S(t,C);await A(n,{recursive:!0});const r={instanceId:o,apiKey:e},l=["SessionStart","UserPromptSubmit","PreToolUse","Stop"],a={SessionStart:L(r),UserPromptSubmit:R(r),PreToolUse:$(r),Stop:M(r)},i=s=>S(n,k[s]),f=async s=>{try{return await E(s,"utf-8")}catch{return""}};let m=!1,g=!0;for(const s of l){const _=await f(i(s));_&&(m=!0),_!==a[s]+`
3
- `&&(g=!1)}const T=g?"unchanged":m?"upgraded":"written";if(T!=="unchanged")for(const s of l)await y(i(s),a[s]+`
4
- `,"utf-8"),await N(i(s),493).catch(()=>{});const h=S(t,j),U=v(h);let b={};if(U)try{b=JSON.parse(await E(h,"utf-8"))}catch{b={}}const p=s=>c.portable?`$CLAUDE_PROJECT_DIR/${C}/${k[s]}`:i(s),{settings:x,changed:I}=D(b,{sessionStart:p("SessionStart"),userPromptSubmit:p("UserPromptSubmit"),preToolUse:p("PreToolUse"),stop:p("Stop")});let u;return U?I?u="merged":u="unchanged":u="written",u!=="unchanged"&&(await A(S(t,".claude"),{recursive:!0}),await y(h,JSON.stringify(x,null,2)+`
5
- `,"utf-8")),{sessionStartPath:i("SessionStart"),promptSubmitPath:i("UserPromptSubmit"),preToolUsePath:i("PreToolUse"),stopPath:i("Stop"),scripts:T,settings:u}}export{H as AMBIENT_CLI_SUBCOMMAND,O as AMBIENT_HOOK_VERSION,F as PRE_TOOL_USE_MATCHER,J as buildAmbientSettingsHooks,$ as buildPreToolUseHook,L as buildSessionStartHook,M as buildStopHook,R as buildUserPromptSubmitHook,q as installAmbientHooks,D as mergeAmbientSettings};
1
+ import{existsSync as I,readFileSync as L}from"node:fs";import{readFile as A,writeFile as U,chmod as M,mkdir as w}from"node:fs/promises";import{dirname as j,resolve as l}from"node:path";import{fileURLToPath as B}from"node:url";const D="v5",st="ambient-recall",m="cachly-ambient-einblendung.mjs";function T(t){return t.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}function b(t,o){return["#!/usr/bin/env node",`// cachly Ambient Recall \u2014 ${t} ${D}`,"// Pushes relevant memory into context automatically. Cross-platform Node hook","// (no shell script \u2014 runs identically on Windows/macOS/Linux). Never blocks","// the agent: every failure path exits 0 with no output (graceful degrade).",`// Runs the hook bundle next to this file (${m}) in this process.`,`process.env.CACHLY_BRAIN_INSTANCE_ID = '${T(o.instanceId)}';`,`process.env.CACHLY_HOOK_EVENT = '${T(t)}';`,`process.argv.splice(2, process.argv.length, '${T(t)}');`,"try {",` await import('./${m}');`,"} catch {"," process.exit(0);","}"].join(`
2
+ `)}function J(){const t=j(B(import.meta.url));for(const o of[l(t,"..",E,m),l(t,"..","..",E,m)])if(I(o))return o;return null}function K(t){return b("SessionStart",t)}function F(t){return b("UserPromptSubmit",t)}function G(t){return b("PreToolUse",t)}function V(t){return b("Stop",t)}const W={SessionStart:30,UserPromptSubmit:10,PreToolUse:10,Stop:60},Y="Edit|Write|MultiEdit|NotebookEdit";function $(t,o){const e=(n,i,u)=>({...u?{matcher:u}:{},hooks:[{type:"command",command:`node "${i}"${o?` ${o(n)}`:""}`,timeout:W[n]}]}),r={SessionStart:[e("SessionStart",t.sessionStart)],UserPromptSubmit:[e("UserPromptSubmit",t.userPromptSubmit)]};return t.preToolUse&&(r.PreToolUse=[e("PreToolUse",t.preToolUse,Y)]),t.stop&&(r.Stop=[e("Stop",t.stop)]),r}const H=".claude/hooks",Q=".claude/settings.json",R={SessionStart:"cachly-ambient-session-start.mjs",UserPromptSubmit:"cachly-ambient-prompt-submit.mjs",PreToolUse:"cachly-ambient-pre-tool.mjs",Stop:"cachly-ambient-stop.mjs"},q=".claude/hooks/cachly-ambient-";function z(t,o){const e=t.hooks??[];return e.length>0&&e.every(r=>{const n=r.command??"";return n.includes(q)||o.has(n)||[...o].some(i=>n.includes(`"${i}"`))})}function X(t,o){const e={...t,hooks:{...t.hooks??{}}},r=e.hooks,n=$(o),i=new Set([o.sessionStart,o.userPromptSubmit,o.preToolUse,o.stop].filter(a=>!!a));for(const[a,c]of Object.entries(n)){const p=(Array.isArray(r[a])?r[a]:[]).filter(f=>!z(f,i));r[a]=[...p,...c]}const u=JSON.stringify(e)!==JSON.stringify(t);return{settings:e,changed:u}}async function nt(t,o,e,r={}){const n=l(t,H);await w(n,{recursive:!0});const i={instanceId:o,apiKey:e},u=["SessionStart","UserPromptSubmit","PreToolUse","Stop"],a={SessionStart:K(i),UserPromptSubmit:F(i),PreToolUse:G(i),Stop:V(i)},c=s=>l(n,R[s]),p=J();if(!p)throw new Error(`cachly hook bundle ${m} missing from the package`);const f=L(p,"utf-8"),h=l(n,m),k=async s=>{try{return await A(s,"utf-8")}catch{return""}};let y=!1,O=await k(h)===f;for(const s of u){const x=await k(c(s));x&&(y=!0),x!==a[s]+`
3
+ `&&(O=!1)}const _=O?"unchanged":y?"upgraded":"written";if(_!=="unchanged"){await U(h,f,"utf-8");for(const s of u)await U(c(s),a[s]+`
4
+ `,"utf-8"),await M(c(s),493).catch(()=>{})}const P=l(t,Q),N=I(P);let g={};if(N)try{g=JSON.parse(await A(P,"utf-8"))}catch{g={}}const d=s=>r.portable?`$CLAUDE_PROJECT_DIR/${H}/${R[s]}`:c(s),{settings:C,changed:v}=X(g,{sessionStart:d("SessionStart"),userPromptSubmit:d("UserPromptSubmit"),preToolUse:d("PreToolUse"),stop:d("Stop")});let S;return N?v?S="merged":S="unchanged":S="written",S!=="unchanged"&&(await w(l(t,".claude"),{recursive:!0}),await U(P,JSON.stringify(C,null,2)+`
5
+ `,"utf-8")),{sessionStartPath:c("SessionStart"),promptSubmitPath:c("UserPromptSubmit"),preToolUsePath:c("PreToolUse"),stopPath:c("Stop"),bundlePath:h,scripts:_,settings:S}}const rt=["SessionStart","UserPromptSubmit","Stop"],E="hooks";function it(){const t=`\${CLAUDE_PLUGIN_ROOT}/${E}/${m}`,o=$({sessionStart:t,userPromptSubmit:t,stop:t},e=>`${e} --plugin`);return JSON.stringify({hooks:o},null,2)+`
6
+ `}export{st as AMBIENT_CLI_SUBCOMMAND,D as AMBIENT_HOOK_VERSION,m as HOOK_BUENDEL,E as PLUGIN_HOOK_DIR,rt as PLUGIN_HOOK_EVENTS,Y as PRE_TOOL_USE_MATCHER,$ as buildAmbientSettingsHooks,it as buildPluginHooksJson,G as buildPreToolUseHook,K as buildSessionStartHook,V as buildStopHook,F as buildUserPromptSubmitHook,J as hookBuendelQuelle,nt as installAmbientHooks,X as mergeAmbientSettings};
@@ -1,6 +1,6 @@
1
- import{appendFile as u,readFile as s,rename as f,writeFile as p}from"node:fs/promises";import{mkdir as d}from"node:fs/promises";import{homedir as m}from"node:os";import{dirname as l,resolve as y}from"node:path";function a(){return y(m(),".cachly","ambient-ledger.jsonl")}function v(t){return JSON.stringify({ts:t.ts,event:t.event,injected:Math.max(0,Math.round(t.injected)),prevented:Math.max(0,Math.round(t.prevented)),...t.note?{note:t.note.slice(0,200)}:{}})}function g(t){const n=[];for(const i of t.split(`
2
- `)){const o=i.trim();if(o)try{const e=JSON.parse(o);if(typeof e!="object"||e===null)continue;const r=Number(e.injected),c=Number(e.prevented);if(!Number.isFinite(r)||!Number.isFinite(c))continue;n.push({ts:typeof e.ts=="string"?e.ts:"",event:typeof e.event=="string"?e.event:"unknown",injected:Math.max(0,r),prevented:Math.max(0,c),...typeof e.note=="string"?{note:e.note}:{}})}catch{}}return n}const h=256*1024,x=400;async function b(t,n=a()){try{await d(l(n),{recursive:!0}),await u(n,v(t)+`
3
- `,"utf-8");const i=await s(n,"utf-8");if(Buffer.byteLength(i,"utf-8")>h){const e=i.split(`
4
- `).filter(Boolean).slice(-x).join(`
1
+ import{appendFile as u,readFile as a,rename as d,writeFile as p}from"node:fs/promises";import{mkdir as f}from"node:fs/promises";import{homedir as m}from"node:os";import{dirname as l,resolve as y}from"node:path";function c(){return y(m(),".cachly","ambient-ledger.jsonl")}function v(e){return JSON.stringify({ts:e.ts,event:e.event,injected:Math.max(0,Math.round(e.injected)),prevented:Math.max(0,Math.round(e.prevented)),...e.note?{note:e.note.slice(0,200)}:{}})}function h(e){const n=[];for(const r of e.split(`
2
+ `)){const o=r.trim();if(o)try{const t=JSON.parse(o);if(typeof t!="object"||t===null)continue;const i=Number(t.injected),s=Number(t.prevented);if(!Number.isFinite(i)||!Number.isFinite(s))continue;n.push({ts:typeof t.ts=="string"?t.ts:"",event:typeof t.event=="string"?t.event:"unknown",injected:Math.max(0,i),prevented:Math.max(0,s),...typeof t.note=="string"?{note:t.note}:{}})}catch{}}return n}const E=256*1024,j=400;async function L(e,n=c()){try{await f(l(n),{recursive:!0}),await u(n,v(e)+`
3
+ `,"utf-8");const r=await a(n,"utf-8");if(Buffer.byteLength(r,"utf-8")>E){const t=r.split(`
4
+ `).filter(Boolean).slice(-j).join(`
5
5
  `)+`
6
- `,r=n+".tmp";await p(r,e,"utf-8"),await f(r,n)}}catch{}}async function L(t=a()){try{return g(await s(t,"utf-8"))}catch{return[]}}export{b as appendLedgerEntry,a as defaultLedgerPath,g as parseLedger,L as readLedger,v as serializeEntry};
6
+ `,i=n+".tmp";await p(i,t,"utf-8"),await d(i,n)}}catch{}}async function N(e=c()){try{return h(await a(e,"utf-8"))}catch{return[]}}function M(e,n,r=fetch){return!e.instanceId||!e.jwt||process.env.CACHLY_NO_TELEMETRY==="1"?Promise.resolve():r(`${e.apiUrl}/api/v1/instances/${e.instanceId}/ambient-events`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e.jwt}`},body:JSON.stringify({events:[n]}),signal:AbortSignal.timeout(3e3)}).then(()=>{},()=>{})}export{L as appendLedgerEntry,c as defaultLedgerPath,h as parseLedger,N as readLedger,M as reportLedgerEntry,v as serializeEntry};
@@ -0,0 +1 @@
1
+ function l(o){return[...o].sort((e,r)=>r-e)}function i(o,e){const r=o.filter(t=>e.has(t.key)).sort((t,c)=>(e.get(t.key)??0)-(e.get(c.key)??0)),s=o.filter(t=>!e.has(t.key)).sort((t,c)=>c.hybridScore-t.hybridScore),u=[];let n=0,h=0;for(;n<r.length||h<s.length;)h<s.length&&(n>=r.length||s[h].hybridScore>r[n].hybridScore)?u.push(s[h++]):u.push(r[n++]);return u}export{i as ordneNachHausordnung,l as rangWerte};
@@ -0,0 +1 @@
1
+ function o(t){const e=t.toLowerCase();return/\b(fix|fixed|fixes|bug|hotfix|patch|revert|resolve|closes? #\d+)\b/.test(e)?{category:"fix",outcome:"success",severity:/\b(critical|crash|security|auth|data loss|outage|prod|production)\b/.test(e)?"critical":/\b(major|breaking|regression|hotfix)\b/.test(e)?"major":"minor"}:/\b(feat|feature|add|added|implement|new|introduce)\b/.test(e)?{category:"feat",outcome:"success",severity:"minor"}:/\b(refactor|clean|cleanup|improve|simplify|extract|rename)\b/.test(e)?{category:"refactor",outcome:"success",severity:"minor"}:/\b(perf|optimize|speed|cache|latency|memory|performance)\b/.test(e)?{category:"perf",outcome:"success",severity:"major"}:/\b(security|cve|auth|csrf|xss|sql|injection|sanitize|escape|encrypt)\b/.test(e)?{category:"security",outcome:"success",severity:"critical"}:/\b(deploy|ci|cd|build|docker|k8s|helm|infra|devops)\b/.test(e)?{category:"deploy",outcome:"success",severity:"major"}:/\b(test|spec|coverage|assert|mock|unit|integration)\b/.test(e)?{category:"test",outcome:"success",severity:"minor"}:{category:"chore",outcome:"success",severity:"minor"}}function c(t){return o(t).category}function i(t){return t.toLowerCase().replace(/[^a-z0-9\s\-_]/g," ").split(/\s+/).filter(s=>s.length>3&&!["that","this","with","from","when","into","also","some","were"].includes(s)).slice(0,3).join("-")||"general"}function n(t){return`${c(t)}:${i(t)}`}function a(t){const e=new Set;for(const r of t)r&&e.add(n(r));return e.size}function u(t){return/^\s*["']?revert\b/i.test(t)}export{o as classifyCommit,c as commitArt,i as extractDomain,u as istRueckbau,n as lektionsThema,a as zaehleLektionen};
@@ -1 +1 @@
1
- import{existsSync as o,mkdirSync as d,writeFileSync as p,renameSync as a,chmodSync as f,readFileSync as i}from"node:fs";import{resolve as s,dirname as y}from"node:path";function m(){return process.env.HOME??process.env.USERPROFILE??process.env.APPDATA??""}function h(e){return/^\$\{[^}]*\}$/.test(e.trim())}function r(e){if(!(typeof e!="string"||e.length===0))return h(e)?void 0:e}function u(e={}){const n=e.home??m();return s(n,".cachly","credentials.json")}function C(e,n={}){try{const t=u(n);d(y(t),{recursive:!0});const c=`${t}.${process.pid}-${Date.now()}.tmp`;p(c,JSON.stringify({apiKey:e},null,2),"utf8");try{f(c,384)}catch{}a(c,t)}catch{}}function l(e){try{const n=u(e);if(!o(n))return;const t=JSON.parse(i(n,"utf8"));return r(t.apiKey)}catch{return}}function S(e){try{const n=s(e.cwd??process.cwd(),".mcp.json");if(!o(n))return;const t=JSON.parse(i(n,"utf8"));return r(t.mcpServers?.cachly?.env?.CACHLY_JWT)}catch{return}}function P(e={}){const n=e.env??process.env;return r(n.CACHLY_JWT)??r(n.CACHLY_API_KEY)??l(e)??S(e)}export{u as credentialsPath,h as istPlatzhalter,P as resolveApiKey,C as saveApiKey};
1
+ import{existsSync as o,mkdirSync as f,writeFileSync as p,renameSync as l,chmodSync as y,readFileSync as s}from"node:fs";import{resolve as a,dirname as m}from"node:path";function h(){return process.env.HOME??process.env.USERPROFILE??process.env.APPDATA??""}function S(e){return/^\$\{[^}]*\}$/.test(e.trim())}function r(e){if(!(typeof e!="string"||e.length===0))return S(e)?void 0:e}function u(e={}){const n=e.home??h();return a(n,".cachly","credentials.json")}function I(e,n={}){const t=i(n),c=t?.apiKey===e?r(t.instanceId):void 0;d({apiKey:e,...c?{instanceId:c}:{}},n)}function x(e,n){const t=i(n);!r(e)||!t?.apiKey||t.apiKey!==n.apiKey||t.instanceId!==e&&d({...t,instanceId:e},n)}function P(e={}){return r(i(e)?.instanceId)}function i(e){try{const n=u(e);if(!o(n))return null;const t=JSON.parse(s(n,"utf8"));return t&&typeof t=="object"?t:null}catch{return null}}function d(e,n){try{const t=u(n);f(m(t),{recursive:!0});const c=`${t}.${process.pid}-${Date.now()}.tmp`;p(c,JSON.stringify(e,null,2),"utf8");try{y(c,384)}catch{}l(c,t)}catch{}}function v(e){return r(i(e)?.apiKey)}function C(e){try{const n=a(e.cwd??process.cwd(),".mcp.json");if(!o(n))return;const t=JSON.parse(s(n,"utf8"));return r(t.mcpServers?.cachly?.env?.CACHLY_JWT)}catch{return}}function H(e={}){const n=e.env??process.env;return r(n.CACHLY_JWT)??r(n.CACHLY_API_KEY)??v(e)??C(e)}export{u as credentialsPath,S as istPlatzhalter,P as readInstanceId,H as resolveApiKey,I as saveApiKey,x as saveInstanceId};