@ai-cortex/daemon 0.1.5 → 0.1.7
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/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ ${r.length>16e3?r.slice(0,16e3)+`
|
|
|
37
37
|
`;for(let c of a)c.write(u);for(let c of l)c.write(u)}function d(u,c){let h=u.url??"/",f=u.method??"GET",b=new URL(h,`http://${u.headers.host||"localhost"}`),y=b.pathname;if(c.setHeader("Access-Control-Allow-Origin","null"),c.setHeader("X-Content-Type-Options","nosniff"),y.startsWith("/api/")){let m=u.headers.authorization,w=m?.startsWith("Bearer ")?m.slice(7):null,k=b.searchParams.get("token");if(w!==r&&k!==r){c.writeHead(401,{"content-type":"application/json"}),c.end(JSON.stringify({error:"unauthorized",message:"Invalid or missing API token. Check ~/.cortex/api-token"}));return}}if(f==="GET"&&y==="/"){try{let m=ho(yo,"../dashboard/index.html"),w=ho(yo,"../../src/dashboard/index.html"),k=xi(m)?m:w,v=Si(k,"utf-8").replace("</head>",`<script>window.CORTEX_API_TOKEN='${r}';</script></head>`);c.writeHead(200,{"Content-Type":"text/html","Content-Security-Policy":"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; img-src 'self'","X-Frame-Options":"DENY","X-Content-Type-Options":"nosniff"}),c.end(v)}catch{c.writeHead(404,{"Content-Type":"text/plain"}),c.end("Dashboard not found")}return}if(f==="GET"&&y==="/api/status"){let m={running:!0,pid:process.pid,port:o.proxyPort,uptime:(Date.now()-i.uptimeStartMs)/1e3,brainEntries:e.getEntryCount(),requestCount:i.requestCount,version:"0.1.0"};N(c,m);return}if(f==="GET"&&y==="/api/session/current"){let m={requestCount:i.requestCount,tokensSaved:i.totalTokensSaved,injectionsCount:i.totalInjections,matchRate:i.requestCount>0?i.totalInjections/i.requestCount:0,avgLatencyMs:i.requestCount>0?Math.round(i.totalLatencyMs/i.requestCount):0};N(c,m);return}if(f==="GET"&&y==="/api/logs/stream"){bo(u,c,l);return}if(f==="GET"&&y==="/api/brain/summary"){let m=e.getAllEntries(),w={};for(let P of m){let v=P.source??"local";w[v]=(w[v]??0)+1}let k={totalEntries:m.length,bySource:w,recentMatches:[]};N(c,k);return}if(f==="GET"&&y==="/api/features"){N(c,{features:n.list()});return}let j=y.match(/^\/api\/features\/([a-zA-Z]+)\/toggle$/);if(f==="POST"&&j){let m=new Set(["pruning","injection","fingerprinting","matching","logging","dashboard","verbose","agentTracking"]),w=j[1];if(!m.has(w)){c.writeHead(400,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:`Unknown feature: ${w}`}));return}let k=w,P=1024,v=[],ne=0,oe=!1;u.on("data",I=>{if(ne+=I.length,ne>P){oe=!0,u.destroy(),c.headersSent||(c.writeHead(413,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Request body too large"})));return}v.push(I)}),u.on("end",()=>{if(oe)return;let I;if(v.length>0)try{let Q=JSON.parse(Buffer.concat(v).toString());typeof Q.enabled=="boolean"&&(I=Q.enabled)}catch{}I!==void 0?I?n.enable(k):n.disable(k):n.isEnabled(k)?n.disable(k):n.enable(k);let ke=n.isEnabled(k);Dn(o.dataDir,{action:"feature:toggle",target:k,value:ke,timestamp:new Date().toISOString(),source:"api"});let ce=n.list().find(Q=>Q.name===k);N(c,ce??{name:k,enabled:ke})});return}if(f==="GET"&&y==="/api/pipeline/live"){bo(u,c,a);return}if(f==="GET"&&y==="/api/agents"){s?N(c,{agents:s.listActive(),enabled:!0}):N(c,{agents:[],enabled:!1});return}if(f==="GET"&&y==="/api/agents/topology"){s?N(c,{...s.getTopology(),enabled:!0}):N(c,{version:2,sessions:[],unlinked:[],ambiguityLevel:"none",mainSessions:[],orphanSubagents:[],enabled:!1});return}if(f==="GET"&&y==="/api/agents/history"){s?N(c,{history:s.listHistory(),enabled:!0}):N(c,{history:[],enabled:!1});return}let B=y.match(/^\/api\/agents\/([^/]+)$/);if(f==="GET"&&B){if(!s){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent tracking is disabled"}));return}let m=s.get(B[1]);if(!m){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent not found"}));return}N(c,{agent:m.info,parentLink:m.parentLink??null});return}let S=y.match(/^\/api\/agents\/([^/]+)\/requests$/);if(f==="GET"&&S){if(!s){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent tracking is disabled"}));return}let m=s.get(S[1]);if(!m){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent not found"}));return}let w=m.requestHistory.map(P=>({requestId:P.requestId,timestamp:P.timestamp,model:P.model,messageCount:P.messagesSummary.length,tokensBefore:P.tokensBefore,tokensAfter:P.tokensAfter,operationsSummary:{pruneCount:P.operations.filter(v=>v.type==="prune").length,tokensSaved:P.tokensBefore-P.tokensAfter,injected:P.operations.some(v=>v.type==="inject"),injectedTitle:P.operations.find(v=>v.type==="inject")?.brainEntryTitle??null}})),k=o.agentTracking.maxRequestHistory;N(c,{requests:w,capped:k>0&&m.info.requestCount>k,maxRequestHistory:k});return}let E=y.match(/^\/api\/agents\/([^/]+)\/requests\/(\d+)$/);if(f==="GET"&&E){if(!s){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent tracking is disabled"}));return}let m=s.get(E[1]);if(!m){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent not found"}));return}let w=parseInt(E[2],10),k=m.requestHistory.find(P=>P.requestId===w);if(!k){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Request not found"}));return}N(c,{snapshot:k});return}let J=y.match(/^\/api\/agents\/([^/]+)\/uncap-history$/);if(f==="POST"&&J){if(!s){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent tracking is disabled"}));return}let m=s.get(J[1]);if(!m){c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Agent not found"}));return}m.uncapHistory(),N(c,{uncapped:!0});return}if(f==="GET"&&y==="/api/statusline"){let m=po(i.lastPhase,i.lastPhaseCtx),w=i.requestCount>0?Math.round(i.totalLatencyMs/i.requestCount):0;N(c,{phase:i.lastPhase,text:m,stats:{requests:i.requestCount,tokensSaved:i.totalTokensSaved,injections:i.totalInjections,avgLatencyMs:w},lastMatch:i.lastPhaseCtx.title??null,lastConfidence:i.lastConfidence??null,agentType:i.lastPhaseCtx.agentType??null,teamName:i.lastPhaseCtx.teamName??null,elements:o.statusline.elements});return}c.writeHead(404,{"Content-Type":"text/plain"}),c.end("Not Found")}return{handler:d,sseHeartbeat:g}}function N(t,e){t.writeHead(200,{"Content-Type":"application/json"}),t.end(JSON.stringify(e))}function bo(t,e,n){if(n.size>=Ti){e.writeHead(503,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"Too many SSE connections"}));return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),n.add(e),t.on("close",()=>{n.delete(e)})}var yo,Ti,xo=C(()=>{"use strict";fo();ht();yo=Ci(wi(import.meta.url));Ti=50});import*as vo from"node:http";import{randomBytes as vi}from"node:crypto";import{existsSync as Co,readFileSync as ki,writeFileSync as Ei,mkdirSync as Ai}from"node:fs";import{join as wo}from"node:path";import{homedir as To}from"node:os";function Pi(){let t=wo(To(),".cortex","api-token");if(Co(t))return ki(t,"utf-8").trim();let e=vi(32).toString("hex"),n=wo(To(),".cortex");return Co(n)||Ai(n,{recursive:!0}),Ei(t,e,{encoding:"utf-8",mode:384}),e}function ko(t,e,n,o,r,s){let i=s??Pi(),{handler:a,sseHeartbeat:l}=So(t,e,n,o,i,r),g=vo.createServer(a),d=null;function u(){return new Promise((h,f)=>{g.once("error",f),g.listen(o.dashboardPort,"127.0.0.1",()=>{g.removeListener("error",f),console.log("[cortex] API token: ~/.cortex/api-token"),d=setInterval(()=>{l()},3e4),h()})})}function c(){return new Promise((h,f)=>{d&&(clearInterval(d),d=null),g.close(b=>{b?f(b):h()})})}return{start:u,stop:c,apiToken:i}}var Eo=C(()=>{"use strict";xo()});var St,Ue,Ao=C(()=>{"use strict";St=class t{static MAX_UNCAPPED_HISTORY=100;info;fingerprint=null;tokenEstimate=0;lastMatchResults=null;armed=!1;armPayload=null;requestHistory=[];parentLink=null;historyUncapped=!1;constructor(e){this.info=e}pushSnapshot(e,n){this.requestHistory.push(e);let o=this.historyUncapped?t.MAX_UNCAPPED_HISTORY:n;o>0&&this.requestHistory.length>o&&(this.requestHistory=this.requestHistory.slice(-o))}uncapHistory(){this.historyUncapped=!0}},Ue=class{active=new Map;history=[];evictionTimer;config;emitter;constructor(e,n){this.config=e,this.emitter=n,this.evictionTimer=setInterval(()=>this.evictStale(),6e4),this.evictionTimer.unref()}getOrCreate(e,n){let o=this.active.get(e);if(o)return o.info.lastSeenAt=Date.now(),o.info.requestCount++,o;for(this.evictStale();this.active.size>=this.config.maxActive;)this.evictOldest();return o=new St(n),this.active.set(e,o),o}get(e){return this.active.get(e)}evictStale(){let e=Date.now(),n=0;for(let[o,r]of this.active){let s=this.getTtl(r.info.type);e-r.info.lastSeenAt>s&&(this.moveToHistory(o,r,"expired"),n++)}return n}listActive(){return Array.from(this.active.values()).map(e=>e.info)}listHistory(){return[...this.history]}countActiveByType(e){let n=0;for(let o of this.active.values())o.info.type===e&&n++;return n}getTopology(){let e=new Map,n=[],o=[],r=[];for(let a of this.active.values())a.info.type==="main"&&(e.set(a.info.conversationId,{agent:a.info,teams:[],subagents:[]}),o.push(a.info.conversationId));for(let a of this.active.values())if(a.info.type!=="main"){if(a.parentLink){let l=e.get(a.parentLink.parentAgentId);if(l){let g={agent:a.info,parentLink:a.parentLink};if(a.info.type==="teammate"&&a.info.teamName){let d=l.teams.find(u=>u.name===a.info.teamName);d||(d={name:a.info.teamName,members:[]},l.teams.push(d)),d.members.push(g)}else l.subagents.push(g);continue}}n.push(a.info),a.info.type==="subagent"&&r.push(a.info.conversationId)}let s=this.countActiveByType("main"),i=s<=1?"none":s===2?"low":"high";return{version:2,sessions:Array.from(e.values()),unlinked:n,ambiguityLevel:i,mainSessions:o,orphanSubagents:r}}shutdown(){clearInterval(this.evictionTimer);for(let[e,n]of this.active)this.moveToHistory(e,n,"evicted")}moveToHistory(e,n,o){let r={info:{...n.info},totalRequests:n.info.requestCount,totalTokensSaved:0,totalInjections:0,duration:n.info.lastSeenAt-n.info.firstSeenAt,completionReason:o,completedAt:Date.now()};this.history.push(r),this.history.length>this.config.maxHistory&&(this.history=this.history.slice(-this.config.maxHistory)),this.active.delete(e),this.emitter&&this.emitter.emitEvent({type:"agent:completed",requestId:0,agentId:e,agentType:n.info.type,totalRequests:n.info.requestCount,totalTokensSaved:0,totalInjections:0,duration:r.duration,completionReason:o})}evictOldest(){let e=null;for(let[n,o]of this.active)(!e||o.info.lastSeenAt<e.state.info.lastSeenAt)&&(e={id:n,state:o});e&&this.moveToHistory(e.id,e.state,"evicted")}getTtl(e){switch(e){case"subagent":return this.config.subagentTtlMs;case"main":return this.config.mainTtlMs;case"teammate":return this.config.teammateTtlMs;default:return this.config.subagentTtlMs}}}});var Ro={};le(Ro,{startCortex:()=>Mi});import{readFileSync as Po}from"node:fs";import{join as xt,dirname as Ri}from"node:path";import{fileURLToPath as $i}from"node:url";import X from"chalk";async function Mi(){let t=Ri($i(import.meta.url)),e;try{e=JSON.parse(Po(xt(t,"../../package.json"),"utf-8")).version}catch{e=JSON.parse(Po(xt(t,"../package.json"),"utf-8")).version}console.log(X.bold(`Cortex v${e} starting...`));let n=R(),o=new ae(n);(await be(n)).passed||(console.log(X.red("\nPreflight checks failed. Run `npm run setup` to fix.\n")),process.exit(1));let s=new De;o.isEnabled("verbose")&&co(s),o.isEnabled("logging")&&qn(s,n.dataDir);let i,a=[];o.isEnabled("agentTracking")&&(i=new Ue(n.agentTracking,s),a=vn(),console.log(X.dim(`[cortex] Agent tracking enabled (${a.length} team config(s) found)`)));let l=await ge.open(xt(n.dataDir,"brain.db")),g={log:()=>{}},d=new Fe(n,l,g,s,o,i);a.length>0&&d.setKnownTeams(a),console.log(X.dim("[cortex] Initializing brain and embedder...")),await d.initialize();let u=so(n,async(f,b)=>{let y=await d.processRequest(f);return{body:y.body,modified:y.modified}});await u.start();let c=null;o.isEnabled("dashboard")&&(c=ko(s,l,o,n,i),await c.start());let h=async()=>{console.log(X.dim(`
|
|
38
38
|
[cortex] Shutting down...`)),i&&i.shutdown(),c&&await c.stop(),await u.stop(),l.close(),process.exit(0)};process.on("SIGINT",h),process.on("SIGTERM",h),console.log(""),console.log(X.green.bold(` Cortex running on port ${n.proxyPort}`)),console.log(X.dim(` Set ANTHROPIC_BASE_URL=http://localhost:${n.proxyPort} to activate`)),c&&console.log(X.dim(` Management API: http://localhost:${n.dashboardPort}`)),console.log(X.dim(` Brain: ${l.getEntryCount()} entries loaded`)),console.log("")}var $o=C(()=>{"use strict";q();re();On();mt();ht();io();ao();lo();bt();Eo();Ao();ut()});import{existsSync as We,mkdirSync as Fi,readFileSync as Oi,writeFileSync as Bo}from"node:fs";import{join as Io}from"node:path";import{homedir as Li}from"node:os";function Je(){return We(He)}function ze(){if(!We(Se))return{};try{return JSON.parse(Oi(Se,"utf-8"))}catch{return{}}}function xe(t){let e=ze();for(let[n,o]of Object.entries(t))_i.has(n)||(typeof o=="object"&&o!==null&&!Array.isArray(o)&&typeof e[n]=="object"&&e[n]!==null?e[n]={...e[n],...o}:e[n]=o);We(He)||Fi(He,{recursive:!0}),Bo(Se,JSON.stringify(e,null,2)+`
|
|
39
39
|
`,"utf-8")}function No(t){if(!We(Se))return;let e=ze();delete e[t],Bo(Se,JSON.stringify(e,null,2)+`
|
|
40
|
-
`,"utf-8")}var He,Se,_i,Ke=C(()=>{"use strict";He=Io(Li(),".claude"),Se=Io(He,"settings.json");_i=new Set(["__proto__","constructor","prototype"])});var Lo={};le(Lo,{runWizard:()=>vt});import{createInterface as Di}from"node:readline";import{existsSync as Fo,mkdirSync as qi,readFileSync as Oo,writeFileSync as Ui}from"node:fs";import{join as Ce,dirname as Hi}from"node:path";import{fileURLToPath as Wi}from"node:url";import{homedir as Ji}from"node:os";import p from"chalk";import{stringify as zi}from"yaml";function Xe(t,e){return new Promise(n=>{process.stdout.write(t);let o=Di({input:process.stdin,output:process.stdout});o.once("line",r=>{o.close(),n(r.trim()||e)})})}function Tt(t,e=!0){return Xe(`${t} [${e?"Y/n":"y/N"}]: `,e?"y":"n").then(o=>o.toLowerCase()==="y")}async function vt(){console.log("");let t=Hi(Wi(import.meta.url)),e;try{e=JSON.parse(Oo(Ce(t,"../../package.json"),"utf-8")).version}catch{e=JSON.parse(Oo(Ce(t,"../package.json"),"utf-8")).version}console.log(p.cyan("\u2554\u2550\u2550 Cortex Setup Wizard \u2550\u2550\u2557")),console.log(p.cyan(`\u2551 v${e.padEnd(22)}\u2551`)),console.log(p.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\
|
|
40
|
+
`,"utf-8")}var He,Se,_i,Ke=C(()=>{"use strict";He=Io(Li(),".claude"),Se=Io(He,"settings.json");_i=new Set(["__proto__","constructor","prototype"])});var Lo={};le(Lo,{runWizard:()=>vt});import{createInterface as Di}from"node:readline";import{existsSync as Fo,mkdirSync as qi,readFileSync as Oo,writeFileSync as Ui}from"node:fs";import{join as Ce,dirname as Hi}from"node:path";import{fileURLToPath as Wi}from"node:url";import{homedir as Ji}from"node:os";import p from"chalk";import{stringify as zi}from"yaml";function Xe(t,e){return new Promise(n=>{process.stdout.write(t);let o=Di({input:process.stdin,output:process.stdout});o.once("line",r=>{o.close(),n(r.trim()||e)})})}function Tt(t,e=!0){return Xe(`${t} [${e?"Y/n":"y/N"}]: `,e?"y":"n").then(o=>o.toLowerCase()==="y")}async function vt(){console.log("");let t=Hi(Wi(import.meta.url)),e;try{e=JSON.parse(Oo(Ce(t,"../../package.json"),"utf-8")).version}catch{e=JSON.parse(Oo(Ce(t,"../package.json"),"utf-8")).version}console.log(p.cyan("\u2554\u2550\u2550 Cortex Setup Wizard \u2550\u2550\u2557")),console.log(p.cyan(`\u2551 v${e.padEnd(22)}\u2551`)),console.log(p.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),console.log(""),console.log(p.dim(" Cortex makes your AI coding agents smarter. It runs")),console.log(p.dim(" as a local proxy, automatically augmenting conversations")),console.log(p.dim(" with relevant knowledge from your brain directory.")),console.log(""),console.log(p.bold(`Step 1: Prerequisites
|
|
41
41
|
`));let n=R(),o=await be(n);for(;!o.passed;)console.log(""),console.log(p.red("Some checks failed. Please fix the issues above.")),await Tt("Fix and retry?")||(console.log("Setup aborted."),process.exit(1)),o=await be(n);console.log(""),console.log(p.bold(`Step 2: Configuration
|
|
42
42
|
`));let r=await Xe(" Proxy port [9090]: ","9090"),s=await Xe(" Target API URL [https://api.anthropic.com]: ","https://api.anthropic.com"),i=await Xe(" Brain directory [./brain/entries]: ","./brain/entries");console.log("");let a=Ce(Ji(),".cortex");Fo(a)||qi(a,{recursive:!0});let l={proxyPort:Number(r),targetBaseUrl:s,brainDir:i},g=Ce(a,"config.yaml");Ui(g,zi(l),"utf-8"),console.log(p.green(` \u2713 Config written to ${g}`)),console.log(""),console.log(p.bold(`Step 3: Model Download
|
|
43
43
|
`)),console.log(p.dim(" Downloading embedding model (~130MB, first time only)..."));let d=Date.now();if(await Ie(Ce(a,"models")),console.log(p.green(` \u2713 Model ready in ${((Date.now()-d)/1e3).toFixed(1)}s`)),console.log(""),Fo(i)){let c=dt(i);console.log(p.green(` \u2713 ${c.length} brain entries found`))}else console.log(p.yellow(" \u26A0 Brain directory does not exist yet \u2014 create it later"));console.log(""),console.log(p.bold(`Step 4: Claude Code Integration
|