@cachly-dev/mcp-server 0.10.222 → 0.10.224
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 +8 -2
- package/dist/src/abstention.js +2 -2
- package/dist/src/autor.js +1 -1
- package/dist/src/doppel-kandidat.js +1 -1
- package/dist/src/entscheidung-ableiten.js +1 -1
- package/dist/src/ersetzung-vorschlag.js +1 -1
- package/dist/src/handlers/brain.js +64 -65
- package/dist/src/index.js +42 -42
- package/dist/src/leeres-brain.js +5 -5
- package/dist/src/rangfolge.js +1 -1
- package/dist/src/search.js +1 -1
- package/dist/src/sitzungs-kosten.js +1 -1
- package/dist/src/startwissen.js +19 -19
- package/dist/src/upgrade-nudge.js +1 -1
- package/dist/src/vorspann.js +1 -1
- package/glama.json +1 -1
- package/hooks/cachly-ambient-einblendung.mjs +17 -17
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/src/startwissen.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import{execFile as
|
|
2
|
-
`)}let
|
|
3
|
-
`),t.startvorrat&&
|
|
4
|
-
`),{art:"ausgeschlossen",ordner:s,grund:
|
|
5
|
-
`),{art:"hat-lektionen"};if(await
|
|
6
|
-
`);const
|
|
7
|
-
`),{art:"fehler",grund:g}}const a=[];for(const h of await m(
|
|
8
|
-
`),a.length>0&&(
|
|
9
|
-
`),{art:"fehler",grund:s}}}function
|
|
10
|
-
`)}async function
|
|
11
|
-
`),{art:"hat-lektionen"};if(await s.set(d,JSON.stringify({stand:"startvorrat",seit:new Date().toISOString(),ordner:e}),"NX")!=="OK")return{art:"schon-erledigt"};
|
|
12
|
-
`);try{await
|
|
13
|
-
`),{art:"fehler",grund:a}}const
|
|
14
|
-
`),
|
|
15
|
-
`),a.length>0&&(
|
|
16
|
-
`),await
|
|
17
|
-
`);break}}return
|
|
18
|
-
`),
|
|
19
|
-
`),
|
|
1
|
+
import{execFile as I}from"node:child_process";import{homedir as D}from"node:os";import{basename as M,isAbsolute as X,relative as K,resolve as w}from"node:path";import{safeJsonParse as S,scanKeys as m}from"./utils.js";import{STARTER_CORPUS_SIZE as L}from"./starter-corpus.js";import{NAME_VEKTOR_PRAEFIX as B,VEKTOR_NACHTRAG as E,VEKTOR_PRAEFIX as A,ZWEIT_VEKTOR_PRAEFIX as R,packe as b,textFuerNamensVektor as F,textFuerVektor as T}from"./bedeutung.js";const d="cachly:startwissen:git",$=30,N=1500,J=1e3,W=3,_=90*86400,j=L;function G(t=process.env){return!/^(0|false|off|no|nein)$/i.test((t.CACHLY_STARTVORRAT??"").trim())}const v=t=>new Promise(e=>setTimeout(e,t));function ct(t){for(const n of t.wurzeln??[])if(n.uri.startsWith("file:"))try{return t.dateiPfad(n.uri)}catch{}const e=t.env??{};for(const n of["CLAUDE_PROJECT_DIR","CACHLY_WORKSPACE"]){const r=(e[n]??"").trim();if(r&&!r.includes("${"))return r}return t.cwd}function H(t,e){const n=K(e,t);return n===""||!n.startsWith("..")&&!X(n)}function U(t,e){return process.platform==="win32"?t.toLowerCase()===e.toLowerCase():t===e}function z(t,e=process.env){const n=w(t),r=(e.CLAUDE_PLUGIN_ROOT??"").trim();if(r&&!r.includes("${")&&H(n,w(r)))return"plugin-ordner";if(n.split(/[\\/]+/).some(i=>i==="node_modules"||i==="_npx"))return"paketordner";const s=e.HOME||e.USERPROFILE||D();return s&&U(n,w(s))?"heimordner":""}function O(t){return new Promise(e=>{try{I("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,windowsHide:!0},(n,r)=>{const s=String(r??"").trim();e(n||!s?"":w(s))})}catch{e("")}})}const V=5;function Z(t,e=V){return new Promise(n=>{try{I("git",["log",`-n${e}`,"--format=%s"],{cwd:t,timeout:3e3,windowsHide:!0},(r,s)=>{if(r)return n([]);n(String(s??"").split(/\r?\n/).map(i=>i.trim()).filter(Boolean).map(i=>i.length>90?`${i.slice(0,89)}\u2026`:i))})}catch{n([])}})}async function lt(t,e=process.env,n=O,r=Z){try{const s=await n(w(await t()));return!s||z(s,e)?[]:await r(s)}catch{return[]}}function C(t,e){return["","","---",`\u2139\uFE0F **cachly:** this new Brain just learned ${t} lesson${t===1?"":"s"} from the git history of \`${M(e)}\` (last ${$} commits at most). \`smart_recall\` finds them now. Tell the user once.`].join(`
|
|
2
|
+
`)}let p="";function ht(){const t=p;return p="",t}async function Y(t){const e=t.protokoll??(r=>{process.stderr.write(r)}),n=t.env??process.env;try{if(t.vomHook)return await q(t,t.vomHook,e);const r=w(await t.projektOrdner()),s=await(t.gitWurzel??O)(r);if(!s)return e(`cachly: ${r} is not a git repository \u2014 the new Brain starts without git history.
|
|
3
|
+
`),t.startvorrat&&G(n)?await Q(t,r,e):{art:"kein-repo",ordner:r};const i=z(s,n);if(i)return e(`cachly: ${s} is not a user project (${i}) \u2014 no import from git history.
|
|
4
|
+
`),{art:"ausgeschlossen",ordner:s,grund:i};const o=await t.verbindung(t.instanzId);if((await m(o,"cachly:lesson:best:*",{max:1})).length>0)return e(`cachly: this Brain already has lessons \u2014 no import from git history.
|
|
5
|
+
`),{art:"hat-lektionen"};if(await o.set(d,JSON.stringify({stand:"laeuft",seit:new Date().toISOString(),ordner:s}),"NX")!=="OK")return{art:"schon-erledigt"};e(`cachly: new Brain \u2014 learning from the last ${$} commits of ${s} in the background.
|
|
6
|
+
`);const c=Date.now();try{await t.ausGit({instance_id:t.instanzId,repo_path:s,limit:$})}catch(h){const g=h instanceof Error?h.message:String(h);return await o.set(d,JSON.stringify({stand:"abgebrochen",am:new Date().toISOString(),grund:g.slice(0,200)})).catch(()=>{}),e(`cachly: import from git history failed: ${g}
|
|
7
|
+
`),{art:"fehler",grund:g}}const a=[];for(const h of await m(o,"cachly:lesson:best:*",{max:1e3})){const g=S(await o.get(h),{});(Array.isArray(g.tags)?g.tags:[]).includes("brain_from_git")&&a.push({topic:h.slice(19),lektion:g})}await o.set(d,JSON.stringify({stand:"fertig",am:new Date().toISOString(),ordner:s,lektionen:a.length})).catch(()=>{});const l=((Date.now()-c)/1e3).toFixed(1);e(`cachly: learned ${a.length} lessons from git history in ${l} s.
|
|
8
|
+
`),a.length>0&&(p=C(a.length,s));try{t.melde?.(a.length)}catch{}const u=await k(o,a,t,e);return{art:"fertig",ordner:s,lektionen:a.length,vektoren:u}}catch(r){const s=r instanceof Error?r.message:String(r);return e(`cachly: import from git history stopped: ${s}
|
|
9
|
+
`),{art:"fehler",grund:s}}}function P(t){return["","","---",`\u2139\uFE0F **cachly:** the project folder is not a git repository, so this new Brain loaded ${t} starter lesson${t===1?"":"s"} (common engineering fixes, tagged \`source: "starter"\`; they never override own lessons). \`smart_recall\` finds them now. Tell the user once.`].join(`
|
|
10
|
+
`)}async function Q(t,e,n){const r=t.startvorrat;if(!r)return{art:"kein-repo",ordner:e};const s=await t.verbindung(t.instanzId);if((await m(s,"cachly:lesson:best:*",{max:1})).length>0)return n(`cachly: this Brain already has lessons \u2014 no starter lessons.
|
|
11
|
+
`),{art:"hat-lektionen"};if(await s.set(d,JSON.stringify({stand:"startvorrat",seit:new Date().toISOString(),ordner:e}),"NX")!=="OK")return{art:"schon-erledigt"};n(`cachly: new Brain without git history \u2014 loading ${j} starter lessons in the background.
|
|
12
|
+
`);try{await r({instance_id:t.instanzId})}catch(c){const a=c instanceof Error?c.message:String(c);return await s.set(d,JSON.stringify({stand:"abgebrochen",am:new Date().toISOString(),grund:a.slice(0,200)})).catch(()=>{}),n(`cachly: loading starter lessons failed: ${a}
|
|
13
|
+
`),{art:"fehler",grund:a}}const o=[];for(const c of await m(s,"cachly:lesson:best:*",{max:1e3})){const a=S(await s.get(c),{});a.source==="starter"&&o.push({topic:c.slice(19),lektion:a})}await s.set(d,JSON.stringify({stand:"fertig",am:new Date().toISOString(),ordner:e,startvorrat:o.length})).catch(()=>{}),n(`cachly: loaded ${o.length} starter lessons.
|
|
14
|
+
`),o.length>0&&(p=P(o.length));try{t.meldeStartvorrat?.(o.length)}catch{}const f=await k(s,o,t,n);return{art:"startvorrat",ordner:e,lektionen:o.length,vektoren:f}}async function q(t,e,n){const r=w(await t.projektOrdner()),s=e.art==="git",i=s&&await(t.gitWurzel??O)(r)||r,o=await t.verbindung(t.instanzId),f=new Date().toISOString();if(await o.set(d,JSON.stringify(s?{stand:"fertig",am:f,ordner:i,lektionen:e.lektionen,quelle:"hook"}:{stand:"fertig",am:f,ordner:r,startvorrat:e.lektionen,quelle:"hook"}),"NX")!=="OK")return{art:"schon-erledigt"};const a=[];for(const u of await m(o,"cachly:lesson:best:*",{max:1e3})){const h=S(await o.get(u),{});(s?Array.isArray(h.tags)&&h.tags.includes("brain_from_git"):h.source==="starter")&&a.push({topic:u.slice(19),lektion:h})}if(s){n(`cachly: the session hook learned ${a.length} lessons from the git history of ${i}.
|
|
15
|
+
`),a.length>0&&(p=C(a.length,i));try{t.melde?.(a.length)}catch{}}else{n(`cachly: the session hook loaded ${a.length} starter lessons.
|
|
16
|
+
`),await o.set(`cachly:stats:born_at:${t.instanzId}`,f,"EX",365*86400,"NX").catch(()=>{}),await o.set(`cachly:brain:starter_seeded:${t.instanzId}`,f,"EX",365*86400).catch(()=>{}),a.length>0&&(p=P(a.length));try{t.meldeStartvorrat?.(a.length)}catch{}}const l=await k(o,a,t,n,{nurFehlende:!0});return s?{art:"fertig",ordner:i,lektionen:a.length,vektoren:l}:{art:"startvorrat",ordner:r,lektionen:a.length,vektoren:l}}async function k(t,e,n,r,{nurFehlende:s=!1}={}){const i=n.einbetten;if(!i||e.length===0||!(n.hatEinbettung??(()=>!0))())return 0;for(const{topic:l}of e)await t.sadd(E,l).catch(()=>{});const o=n.schlafen??v,f=n.pauseMs??N;let c=0,a=0;for(const{topic:l,lektion:u}of e)try{if(await o(f),s&&await t.exists(`${A}${l}`)){await t.srem(E,l),c++,a=0;continue}const h=await i(T({...u,topic:l}));h?.length&&(await t.set(`${A}${l}`,b(h),"EX",_),await t.srem(E,l),c++),await o(f);const g=await i(F(l));g?.length&&await t.set(`${B}${l}`,b(g),"EX",_),a=0}catch{if(a++,a>=W){r(`cachly: embedding service unavailable \u2014 ${e.length-c} lessons wait in the backlog; smart_recall fills them in later.
|
|
17
|
+
`);break}}return r(`cachly: search vectors for git lessons: ${c}/${e.length}.
|
|
18
|
+
`),c>0&&await tt(t,e,n,r,s),c}async function tt(t,e,n,r,s=!1){const i=n.einbettenZweit;if(!i)return 0;const o=n.schlafen??v,f=n.pauseMs??N;let c=0;for(const{topic:a,lektion:l}of e)try{if(s&&await t.exists(`${R}${a}`)){c++;continue}await o(f);const u=await i(T({...l,topic:a}));u?.length&&(await t.set(`${R}${a}`,b(u),"EX",_),c++)}catch{break}return r(`cachly: second-model vectors for git lessons: ${c}/${e.length}.
|
|
19
|
+
`),c}const y=new Map,x=new Map;function ft(t){return x.get(t)}function gt(t){const e=y.get(t.instanzId);if(e)return e;const n=(async()=>(await(t.schlafen??v)(t.anlaufMs??J),Y(t)))().catch(r=>({art:"fehler",grund:r instanceof Error?r.message:String(r)})).then(r=>(x.set(t.instanzId,r.art),r));return y.set(t.instanzId,n),n}function ut(t){return y.has(t)}async function dt(t,e){return await t.set(d,JSON.stringify({stand:e,seit:new Date().toISOString()}),"NX")==="OK"}function wt(){y.clear(),x.clear(),p=""}export{J as ANLAUF_MS,N as EINBETT_PAUSE_MS,V as ERSTE_ANTWORT_COMMITS,j as STARTVORRAT_LEKTIONEN,$ as STARTWISSEN_COMMITS,d as STARTWISSEN_MARKE,wt as _startwissenZuruecksetzen,z as ausschlussGrund,dt as beanspruchStartwissen,O as echteGitWurzel,ht as holeStartwissenHinweis,Y as lerneAusGitGeschichte,Z as letzteCommitBetreffe,lt as projektCommits,gt as starteStartwissen,G as startvorratErlaubt,P as startvorratSatz,ft as startwissenAusgang,ut as startwissenGestartet,C as startwissenSatz,ct as waehleProjektOrdner};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function u({used:e,limit:n}){if(!Number.isFinite(n)||n<=0||!Number.isFinite(e)||e/n<.8)return null;const r=Math.max(0,n-e);return`\u{1F4C8} ${r} ${r===1?"recall":"recalls"} left this month on the free plan \u2014 see cachly.dev/pricing to keep going.`}export{u as upgradeNudge};
|
package/dist/src/vorspann.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const f=100,i=[{name:"IP-Adresse",re:/\b\d{1,3}(?:\.\d{1,3}){3}\b/},{name:"Port",re:/:\d{2,5}\b/},{name:"Zahl",re:/\b\d+(?:[.,]\d+)?\s*(?:%|s|ms|m|h|d|MB|GB|TB|KB|k|x|×|EUR|€|\$)?\b/},{name:"Pfad",re:/(?:^|\s)(?:\/[\w.-]+){2,}|[A-Za-z]:\\[\w\\.-]+/},{name:"Befehl oder Datei",re:/`[^`]+`|\b[\w-]+\.(?:ts|tsx|go|js|mjs|py|sh|yml|yaml|json|sql|env)\b/},{name:"Schluessel",re:/\b[A-Z][A-Z0-9]*(?:_[A-Z0-9]+){2,}\b|\b[A-Z][A-Z0-9_]{3,}\s*=/},{name:"Version",re:/\bv?\d+\.\d+(?:\.\d+)?\b/}];function o(t){if(t.length<=100)return!1;const e=t.slice(0,100);return!/[.;!?](?:\s|$)/.test(e)}function c(t){let e=-1;for(const r of i){const n=r.re.exec(t);if(!n)continue;const s=n.index;(e===-1||s<e)&&(e=s)}return e}function h(t){const e=typeof t=="string"?t:"",r=e.slice(0,100),n=i.filter(a=>a.re.test(r)).map(a=>a.name),s=c(e);return{vorspann:r,traegtTatsache:n.length>0,gefunden:n,tatsacheStehtSpaeter:n.length===0&&s>=100,ersteTatsacheBei:s,abgeschnitten:o(e)}}function u(t){const e=h(t);return e.vorspann.trim()?e.traegtTatsache&&e.abgeschnitten?`\u{1F4CF} **The opening stops mid-sentence** \u2014 the number is up front, its meaning is not. The next session's briefing cuts off at 100 characters and then shows a number without meaning. One complete sentence within the first 100 characters is enough: not "13 of them green because", but "13 checks were green without testing anything."`:e.traegtTatsache?null:e.tatsacheStehtSpaeter?`\u{1F4CF} **The decisive fact starts at character ${e.ersteTatsacheBei}** \u2014 the next session's briefing ends at 100. Put the number, address or command at the start of \`what_worked\`; the background belongs at the end or in \`context\`.`:"\u{1F4CF} **No number, address or command in the first 100 characters** \u2014 that is all the next session sees in its briefing. If this lesson carries a hard fact, move it to the front.":null}export{f as VORSPANN_ZEICHEN,h as pruefeVorspann,u as vorspannHinweis};
|