vibelearn 0.1.2 → 0.1.3
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibelearn",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Learn from every coding session — automatically extracts concepts from your Claude Code sessions, generates adaptive quiz questions across 7 formats, and tracks mastery with spaced repetition.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ahun Atajanov"
|
package/plugin/package.json
CHANGED
|
@@ -114,7 +114,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
114
114
|
${c}`}var xP=new Set([".js",".jsx",".ts",".tsx",".mjs",".cjs",".py",".pyw",".go",".rs",".rb",".java",".cs",".cpp",".c",".h",".hpp",".swift",".kt",".php",".vue",".svelte"]),kP=new Set(["node_modules",".git","dist","build",".next","__pycache__",".venv","venv","env",".env","target","vendor",".cache",".turbo","coverage",".nyc_output",".claude",".smart-file-read"]),SP=512*1024;async function*u$(t,e,r=20){if(r<=0)return;let n;try{n=await(0,zn.readdir)(t,{withFileTypes:!0})}catch{return}for(let o of n){if(o.name.startsWith(".")&&o.name!=="."||kP.has(o.name))continue;let i=(0,hi.join)(t,o.name);if(o.isDirectory())yield*u$(i,e,r-1);else if(o.isFile()){let a=o.name.slice(o.name.lastIndexOf("."));xP.has(a)&&(yield i)}}}async function wP(t){try{let e=await(0,zn.stat)(t);if(e.size>SP||e.size===0)return null;let r=await(0,zn.readFile)(t,"utf-8");return r.slice(0,1e3).includes("\0")?null:r}catch{return null}}async function l$(t,e,r={}){let n=r.maxResults||20,o=e.toLowerCase(),i=o.split(/[\s_\-./]+/).filter(h=>h.length>0),a=[];for await(let h of u$(t,t)){if(r.filePattern&&!(0,hi.relative)(t,h).toLowerCase().includes(r.filePattern.toLowerCase()))continue;let _=await wP(h);_&&a.push({absolutePath:h,relativePath:(0,hi.relative)(t,h),content:_})}let s=a$(a),c=[],u=[],l=0;for(let[h,_]of s){l+=zP(_);let E=Ns(h.toLowerCase(),i)>0,I=[],A=(j,Le)=>{for(let de of j){let Bt=0,Qe="",Wt=Ns(de.name.toLowerCase(),i);Wt>0&&(Bt+=Wt*3,Qe="name match"),de.signature.toLowerCase().includes(o)&&(Bt+=2,Qe=Qe?`${Qe} + signature`:"signature match"),de.jsdoc&&de.jsdoc.toLowerCase().includes(o)&&(Bt+=1,Qe=Qe?`${Qe} + jsdoc`:"jsdoc match"),Bt>0&&(E=!0,I.push({filePath:h,symbolName:Le?`${Le}.${de.name}`:de.name,kind:de.kind,signature:de.signature,jsdoc:de.jsdoc,lineStart:de.lineStart,lineEnd:de.lineEnd,matchReason:Qe})),de.children&&A(de.children,de.name)}};A(_.symbols),E&&(c.push(_),u.push(...I))}u.sort((h,_)=>{let b=Ns(h.symbolName.toLowerCase(),i);return Ns(_.symbolName.toLowerCase(),i)-b});let d=u.slice(0,n),p=new Set(d.map(h=>h.filePath)),f=c.filter(h=>p.has(h.filePath)).slice(0,n),g=f.reduce((h,_)=>h+_.foldedTokenEstimate,0);return{foldedFiles:f,matchingSymbols:d,totalFilesScanned:a.length,totalSymbolsFound:l,tokenEstimate:g}}function Ns(t,e){let r=0;for(let n of e)if(t===n)r+=10;else if(t.includes(n))r+=5;else{let o=0,i=0;for(let a of n){let s=t.indexOf(a,o);s!==-1&&(i++,o=s+1)}i===n.length&&(r+=1)}return r}function zP(t){let e=t.symbols.length;for(let r of t.symbols)r.children&&(e+=r.children.length);return e}function d$(t,e){let r=[];if(r.push(`\u{1F50D} Smart Search: "${e}"`),r.push(` Scanned ${t.totalFilesScanned} files, found ${t.totalSymbolsFound} symbols`),r.push(` ${t.matchingSymbols.length} matches across ${t.foldedFiles.length} files (~${t.tokenEstimate} tokens for folded view)`),r.push(""),t.matchingSymbols.length===0)return r.push(" No matching symbols found."),r.join(`
|
|
115
115
|
`);r.push("\u2500\u2500 Matching Symbols \u2500\u2500"),r.push("");for(let n of t.matchingSymbols){if(r.push(` ${n.kind} ${n.symbolName} (${n.filePath}:${n.lineStart+1})`),r.push(` ${n.signature}`),n.jsdoc){let o=n.jsdoc.split(`
|
|
116
116
|
`).find(i=>i.replace(/^[\s*/]+/,"").trim().length>0);o&&r.push(` \u{1F4AC} ${o.replace(/^[\s*/]+/,"").trim()}`)}r.push("")}r.push("\u2500\u2500 Folded File Views \u2500\u2500"),r.push("");for(let n of t.foldedFiles)r.push(wn(n)),r.push("");return r.push("\u2500\u2500 Actions \u2500\u2500"),r.push(" To see full implementation: use smart_unfold with file path and symbol name"),r.join(`
|
|
117
|
-
`)}var jf=require("node:fs/promises"),Rs=require("node:path"),IP="0.1.
|
|
117
|
+
`)}var jf=require("node:fs/promises"),Rs=require("node:path"),IP="0.1.3";console.log=(...t)=>{ve.error("CONSOLE","Intercepted console output (MCP protocol protection)",void 0,{args:t})};var p$={search:"/api/search",timeline:"/api/timeline"};async function f$(t,e){ve.debug("SYSTEM","\u2192 Worker API",void 0,{endpoint:t,params:e});try{let r=new URLSearchParams;for(let[a,s]of Object.entries(e))s!=null&&r.append(a,String(s));let n=`${t}?${r}`,o=await Os(n);if(!o.ok){let a=await o.text();throw new Error(`Worker API error (${o.status}): ${a}`)}let i=await o.json();return ve.debug("SYSTEM","\u2190 Worker API success",void 0,{endpoint:t}),i}catch(r){return ve.error("SYSTEM","\u2190 Worker API error",{endpoint:t},r),{content:[{type:"text",text:`Error calling Worker API: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async function EP(t,e){ve.debug("HTTP","Worker API request (POST)",void 0,{endpoint:t});try{let r=await Os(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok){let o=await r.text();throw new Error(`Worker API error (${r.status}): ${o}`)}let n=await r.json();return ve.debug("HTTP","Worker API success (POST)",void 0,{endpoint:t}),{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(r){return ve.error("HTTP","Worker API error (POST)",{endpoint:t},r),{content:[{type:"text",text:`Error calling Worker API: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}}async function TP(){try{return(await Os("/api/health")).ok}catch(t){return ve.debug("SYSTEM","Worker health check failed",{},t),!1}}var m$=[{name:"__IMPORTANT",description:`3-LAYER WORKFLOW (ALWAYS FOLLOW):
|
|
118
118
|
1. search(query) \u2192 Get index with IDs (~50-100 tokens/result)
|
|
119
119
|
2. timeline(anchor=ID) \u2192 Get context around interesting results
|
|
120
120
|
3. get_observations([IDs]) \u2192 Fetch full details ONLY for filtered IDs
|
|
@@ -172,7 +172,7 @@ Please see the 3.x to 4.x migration guide for details on how to update your app.
|
|
|
172
172
|
`).run().changes}clearAll(){return this.db.prepare(`
|
|
173
173
|
DELETE FROM pending_messages
|
|
174
174
|
WHERE status IN ('pending', 'processing', 'failed')
|
|
175
|
-
`).run().changes}toPendingMessage(e){return{type:e.message_type,tool_name:e.tool_name||void 0,tool_input:e.tool_input?JSON.parse(e.tool_input):void 0,tool_response:e.tool_response?JSON.parse(e.tool_response):void 0,prompt_number:e.prompt_number||void 0,cwd:e.cwd||void 0,last_assistant_message:e.last_assistant_message||void 0}}}});var G2={};vn(G2,{ModeManager:()=>xt});var Od,tg,xt,Xn=ht(()=>{"use strict";Od=require("fs"),tg=require("path");ie();qt();xt=class t{static instance=null;activeMode=null;modesDir;constructor(){let e=Tr(),r=[(0,tg.join)(e,"modes"),(0,tg.join)(e,"..","plugin","modes")],n=r.find(i=>(0,Od.existsSync)(i));this.modesDir=n||r[0]}static getInstance(){return t.instance||(t.instance=new t),t.instance}parseInheritance(e){let r=e.split("--");if(r.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(r.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:r[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,r){let n={...e};for(let i in r){let s=r[i],o=e[i];this.isPlainObject(s)&&this.isPlainObject(o)?n[i]=this.deepMerge(o,s):n[i]=s}return n}loadModeFile(e){let r=(0,tg.join)(this.modesDir,`${e}.json`);if(!(0,Od.existsSync)(r))throw new Error(`Mode file not found: ${r}`);let n=(0,Od.readFileSync)(r,"utf-8");return JSON.parse(n)}loadMode(e){let r=this.parseInheritance(e);if(!r.hasParent)try{let c=this.loadModeFile(e);return this.activeMode=c,b.debug("SYSTEM",`Loaded mode: ${c.name} (${e})`,void 0,{types:c.observation_types.map(u=>u.id),concepts:c.observation_concepts.map(u=>u.id)}),c}catch{if(b.warn("SYSTEM",`Mode file not found: ${e}, falling back to 'code'`),e==="code")throw new Error("Critical: code.json mode file missing");return this.loadMode("code")}let{parentId:n,overrideId:i}=r,s;try{s=this.loadMode(n)}catch{b.warn("SYSTEM",`Parent mode '${n}' not found for ${e}, falling back to 'code'`),s=this.loadMode("code")}let o;try{o=this.loadModeFile(i),b.debug("SYSTEM",`Loaded override file: ${i} for parent ${n}`)}catch{return b.warn("SYSTEM",`Override file '${i}' not found, using parent mode '${n}' only`),this.activeMode=s,s}if(!o)return b.warn("SYSTEM",`Invalid override file: ${i}, using parent mode '${n}' only`),this.activeMode=s,s;let a=this.deepMerge(s,o);return this.activeMode=a,b.debug("SYSTEM",`Loaded mode with inheritance: ${a.name} (${e} = ${n} + ${i})`,void 0,{parent:n,override:i,types:a.observation_types.map(c=>c.id),concepts:a.observation_concepts.map(c=>c.id)}),a}getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Call loadMode() first.");return this.activeMode}getObservationTypes(){return this.getActiveMode().observation_types}getObservationConcepts(){return this.getActiveMode().observation_concepts}getTypeIcon(e){return this.getObservationTypes().find(n=>n.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(n=>n.id===e)?.work_emoji||"\u{1F4DD}"}validateType(e){return this.getObservationTypes().some(r=>r.id===e)}getTypeLabel(e){return this.getObservationTypes().find(n=>n.id===e)?.label||e}}});function J2(t){if(!t)return[];try{let e=JSON.parse(t);return Array.isArray(e)?e:[]}catch(e){return b.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:t?.substring(0,50)},e),[]}}function Ei(t){return new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function qr(t){return new Date(t).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function jo(t){return new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function X2(t,e){return VE.default.isAbsolute(t)?VE.default.relative(e,t):t}function Ji(t,e,r){let n=J2(t);if(n.length>0)return X2(n[0],e);if(r){let i=J2(r);if(i.length>0)return X2(i[0],e)}return"General"}function xc(t){return t?Math.ceil(t.length/4):0}function Xi(t,e){let r=new Map;for(let i of t){let s=e(i),o=jo(s);r.has(o)||r.set(o,[]),r.get(o).push(i)}let n=Array.from(r.entries()).sort((i,s)=>{let o=new Date(i[0]).getTime(),a=new Date(s[0]).getTime();return o-a});return new Map(n)}var VE,Sc=ht(()=>{"use strict";VE=nt(require("path"),1);ie()});function _he(){try{let t=process.stdin;return t.isTTY?!1:(t.readable,!0)}catch{return!1}}function bhe(t){let e=t.trim();if(!e)return{success:!1};try{return{success:!0,value:JSON.parse(e)}}catch{return{success:!1}}}async function oq(){if(_he())return new Promise((t,e)=>{let r="",n=!1,i=null,s=()=>{try{process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),process.stdin.removeAllListeners("error")}catch{}},o=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),t(l))},a=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),e(l))},c=()=>{let l=bhe(r);return l.success?(o(l.value),!0):!1},u=setTimeout(()=>{n||c()||(r.trim()?a(new Error(`Incomplete JSON after ${sq}ms: ${r.slice(0,100)}...`)):o(void 0))},sq);try{process.stdin.on("data",l=>{r+=l,i&&(clearTimeout(i),i=null),!c()&&(i=setTimeout(()=>{c()},xhe))}),process.stdin.on("end",()=>{n||c()||o((r.trim(),void 0))}),process.stdin.on("error",()=>{n||o(void 0)})}catch{n=!0,clearTimeout(u),s(),t(void 0)}})}var sq,xhe,aq=ht(()=>{"use strict";sq=3e4,xhe=50});var cq,uq=ht(()=>{"use strict";cq={normalizeInput(t){let e=t??{};return{sessionId:e.session_id??e.id??e.sessionId,cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.tool_name,toolInput:e.tool_input,toolResponse:e.tool_response,transcriptPath:e.transcript_path}},formatOutput(t){let e=t??{};if(e.hookSpecificOutput){let n={hookSpecificOutput:t.hookSpecificOutput};return e.systemMessage&&(n.systemMessage=e.systemMessage),n}let r={};return e.systemMessage&&(r.systemMessage=e.systemMessage),r}}});var lq,dq=ht(()=>{"use strict";lq={normalizeInput(t){let e=t??{},r=!!e.command&&!e.tool_name;return{sessionId:e.conversation_id||e.generation_id||e.id,cwd:e.workspace_roots?.[0]??e.cwd??process.cwd(),prompt:e.prompt??e.query??e.input??e.message,toolName:r?"Bash":e.tool_name,toolInput:r?{command:e.command}:e.tool_input,toolResponse:r?{output:e.output}:e.result_json,transcriptPath:void 0,filePath:e.file_path,edits:e.edits}},formatOutput(t){return{continue:t.continue??!0}}}});var Jk,pq=ht(()=>{"use strict";Jk={normalizeInput(t){let e=t;return{sessionId:e.sessionId??e.session_id??"unknown",cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.toolName??e.tool_name,toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResponse??e.tool_response,transcriptPath:e.transcriptPath??e.transcript_path,filePath:e.filePath??e.file_path,edits:e.edits}},formatOutput(t){return t}}});function fq(t){switch(t){case"claude-code":return cq;case"cursor":return lq;case"raw":return Jk;default:return Jk}}var mq=ht(()=>{"use strict";uq();dq();pq()});var hq=ht(()=>{"use strict"});function vq(t){if(!t||t.trim()==="")return b.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:t}),"unknown-project";let e=gq.default.basename(t);if(e===""){if(process.platform==="win32"){let n=t.match(/^([A-Z]):\\/i);if(n){let s=`drive-${n[1].toUpperCase()}`;return b.info("PROJECT_NAME","Drive root detected",{cwd:t,projectName:s}),s}}return b.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:t}),"unknown-project"}return e}var gq,yq=ht(()=>{"use strict";gq=nt(require("path"),1);ie();hq()});function She(t){let e=t.startsWith("~")?(0,_q.homedir)()+t.slice(1):t;e=e.replace(/\\/g,"/");let r=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");return r=r.replace(/\*\*/g,"<<<GLOBSTAR>>>").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]").replace(/<<<GLOBSTAR>>>/g,".*"),new RegExp(`^${r}$`)}function sv(t,e){if(!e||!e.trim())return!1;let r=t.replace(/\\/g,"/"),n=e.split(",").map(i=>i.trim()).filter(Boolean);for(let i of n)try{if(She(i).test(r))return!0}catch{continue}return!1}var _q,Xk=ht(()=>{"use strict";_q=require("os")});var Yk,Qk=ht(()=>{"use strict";Jr();yq();ie();Tn();Xk();kr();qt();Yk={async execute(t){if(!await In())return{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let{sessionId:r,cwd:n,prompt:i}=t;if(!r)return b.warn("HOOK","session-init: No sessionId provided, skipping (Codex CLI or unknown platform)"),{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let s=Re.loadFromFile(Qt);if(n&&sv(n,s.VIBELEARN_EXCLUDED_PROJECTS))return b.info("HOOK","Project excluded from tracking",{cwd:n}),{continue:!0,suppressOutput:!0};let o=!i||!i.trim()?"[media prompt]":i,a=vq(n);b.debug("HOOK","session-init: Calling /api/sessions/init",{contentSessionId:r,project:a});let c=await Gt("/api/sessions/init",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contentSessionId:r,project:a,prompt:o})});if(!c.ok)return b.failure("HOOK",`Session initialization failed: ${c.status}`,{contentSessionId:r,project:a}),{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let u=await c.json(),l=u.sessionDbId,d=u.promptNumber;if(b.debug("HOOK","session-init: Received from /api/sessions/init",{sessionDbId:l,promptNumber:d,skipped:u.skipped,contextInjected:u.contextInjected}),b.debug("HOOK",`[ALIGNMENT] Hook Entry | contentSessionId=${r} | prompt#=${d} | sessionDbId=${l}`),u.skipped&&u.reason==="private")return b.info("HOOK",`INIT_COMPLETE | sessionDbId=${l} | promptNumber=${d} | skipped=true | reason=private`,{sessionId:l}),{continue:!0,suppressOutput:!0};if(u.contextInjected)return b.info("HOOK",`INIT_COMPLETE | sessionDbId=${l} | promptNumber=${d} | skipped_agent_init=true | reason=context_already_injected`,{sessionId:l}),{continue:!0,suppressOutput:!0};if(t.platform!=="cursor"&&l){let p=o.startsWith("/")?o.substring(1):o;b.debug("HOOK","session-init: Calling /sessions/{sessionDbId}/init",{sessionDbId:l,promptNumber:d});let f=await Gt(`/sessions/${l}/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userPrompt:p,promptNumber:d})});f.ok||b.failure("HOOK",`SDK agent start failed: ${f.status}`,{sessionDbId:l,promptNumber:d})}else t.platform==="cursor"&&b.debug("HOOK","session-init: Skipping SDK agent init for Cursor platform",{sessionDbId:l,promptNumber:d});return b.info("HOOK",`INIT_COMPLETE | sessionDbId=${l} | promptNumber=${d} | project=${a}`,{sessionId:l}),{continue:!0,suppressOutput:!0}}}});function Ehe(t,e,r,n,i){let s=r??{},o={contentSessionId:t,tool_name:e,cwd:i};if(e==="Write"||e==="Edit"||e==="NotebookEdit"){let a=s.file_path??s.path??"",c=s.content??s.new_string??"";return c.length>bq&&(c=c.slice(0,bq)+`
|
|
175
|
+
`).run().changes}toPendingMessage(e){return{type:e.message_type,tool_name:e.tool_name||void 0,tool_input:e.tool_input?JSON.parse(e.tool_input):void 0,tool_response:e.tool_response?JSON.parse(e.tool_response):void 0,prompt_number:e.prompt_number||void 0,cwd:e.cwd||void 0,last_assistant_message:e.last_assistant_message||void 0}}}});var G2={};vn(G2,{ModeManager:()=>xt});var Od,tg,xt,Xn=ht(()=>{"use strict";Od=require("fs"),tg=require("path");ie();qt();xt=class t{static instance=null;activeMode=null;modesDir;constructor(){let e=Tr(),r=[(0,tg.join)(e,"modes"),(0,tg.join)(e,"..","plugin","modes")],n=r.find(i=>(0,Od.existsSync)(i));this.modesDir=n||r[0]}static getInstance(){return t.instance||(t.instance=new t),t.instance}parseInheritance(e){let r=e.split("--");if(r.length===1)return{hasParent:!1,parentId:"",overrideId:""};if(r.length>2)throw new Error(`Invalid mode inheritance: ${e}. Only one level of inheritance supported (parent--override)`);return{hasParent:!0,parentId:r[0],overrideId:e}}isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}deepMerge(e,r){let n={...e};for(let i in r){let s=r[i],o=e[i];this.isPlainObject(s)&&this.isPlainObject(o)?n[i]=this.deepMerge(o,s):n[i]=s}return n}loadModeFile(e){let r=(0,tg.join)(this.modesDir,`${e}.json`);if(!(0,Od.existsSync)(r))throw new Error(`Mode file not found: ${r}`);let n=(0,Od.readFileSync)(r,"utf-8");return JSON.parse(n)}loadMode(e){let r=this.parseInheritance(e);if(!r.hasParent)try{let c=this.loadModeFile(e);return this.activeMode=c,b.debug("SYSTEM",`Loaded mode: ${c.name} (${e})`,void 0,{types:c.observation_types.map(u=>u.id),concepts:c.observation_concepts.map(u=>u.id)}),c}catch{if(b.warn("SYSTEM",`Mode file not found: ${e}, falling back to 'code'`),e==="code")throw new Error("Critical: code.json mode file missing");return this.loadMode("code")}let{parentId:n,overrideId:i}=r,s;try{s=this.loadMode(n)}catch{b.warn("SYSTEM",`Parent mode '${n}' not found for ${e}, falling back to 'code'`),s=this.loadMode("code")}let o;try{o=this.loadModeFile(i),b.debug("SYSTEM",`Loaded override file: ${i} for parent ${n}`)}catch{return b.warn("SYSTEM",`Override file '${i}' not found, using parent mode '${n}' only`),this.activeMode=s,s}if(!o)return b.warn("SYSTEM",`Invalid override file: ${i}, using parent mode '${n}' only`),this.activeMode=s,s;let a=this.deepMerge(s,o);return this.activeMode=a,b.debug("SYSTEM",`Loaded mode with inheritance: ${a.name} (${e} = ${n} + ${i})`,void 0,{parent:n,override:i,types:a.observation_types.map(c=>c.id),concepts:a.observation_concepts.map(c=>c.id)}),a}getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Call loadMode() first.");return this.activeMode}getObservationTypes(){return this.getActiveMode().observation_types}getObservationConcepts(){return this.getActiveMode().observation_concepts}getTypeIcon(e){return this.getObservationTypes().find(n=>n.id===e)?.emoji||"\u{1F4DD}"}getWorkEmoji(e){return this.getObservationTypes().find(n=>n.id===e)?.work_emoji||"\u{1F4DD}"}validateType(e){return this.getObservationTypes().some(r=>r.id===e)}getTypeLabel(e){return this.getObservationTypes().find(n=>n.id===e)?.label||e}}});function J2(t){if(!t)return[];try{let e=JSON.parse(t);return Array.isArray(e)?e:[]}catch(e){return b.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:t?.substring(0,50)},e),[]}}function Ei(t){return new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function qr(t){return new Date(t).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function jo(t){return new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function X2(t,e){return VE.default.isAbsolute(t)?VE.default.relative(e,t):t}function Ji(t,e,r){let n=J2(t);if(n.length>0)return X2(n[0],e);if(r){let i=J2(r);if(i.length>0)return X2(i[0],e)}return"General"}function xc(t){return t?Math.ceil(t.length/4):0}function Xi(t,e){let r=new Map;for(let i of t){let s=e(i),o=jo(s);r.has(o)||r.set(o,[]),r.get(o).push(i)}let n=Array.from(r.entries()).sort((i,s)=>{let o=new Date(i[0]).getTime(),a=new Date(s[0]).getTime();return o-a});return new Map(n)}var VE,Sc=ht(()=>{"use strict";VE=nt(require("path"),1);ie()});function _he(){try{let t=process.stdin;return t.isTTY?!1:(t.readable,!0)}catch{return!1}}function bhe(t){let e=t.trim();if(!e)return{success:!1};try{return{success:!0,value:JSON.parse(e)}}catch{return{success:!1}}}async function oq(){if(_he())return new Promise((t,e)=>{let r="",n=!1,i=null,s=()=>{try{process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),process.stdin.removeAllListeners("error")}catch{}},o=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),t(l))},a=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),e(l))},c=()=>{let l=bhe(r);return l.success?(o(l.value),!0):!1},u=setTimeout(()=>{n||c()||(r.trim()?a(new Error(`Incomplete JSON after ${sq}ms: ${r.slice(0,100)}...`)):o(void 0))},sq);try{process.stdin.on("data",l=>{r+=l,i&&(clearTimeout(i),i=null),!c()&&(i=setTimeout(()=>{c()},xhe))}),process.stdin.on("end",()=>{n||c()||o((r.trim(),void 0))}),process.stdin.on("error",()=>{n||o(void 0)})}catch{n=!0,clearTimeout(u),s(),t(void 0)}})}var sq,xhe,aq=ht(()=>{"use strict";sq=3e4,xhe=50});var cq,uq=ht(()=>{"use strict";cq={normalizeInput(t){let e=t??{};return{sessionId:e.session_id??e.id??e.sessionId,cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.tool_name,toolInput:e.tool_input,toolResponse:e.tool_response,transcriptPath:e.transcript_path}},formatOutput(t){let e=t??{};if(e.hookSpecificOutput){let n={hookSpecificOutput:t.hookSpecificOutput};return e.systemMessage&&(n.systemMessage=e.systemMessage),n}let r={};return e.systemMessage&&(r.systemMessage=e.systemMessage),r}}});var lq,dq=ht(()=>{"use strict";lq={normalizeInput(t){let e=t??{},r=!!e.command&&!e.tool_name;return{sessionId:e.conversation_id||e.generation_id||e.id,cwd:e.workspace_roots?.[0]??e.cwd??process.cwd(),prompt:e.prompt??e.query??e.input??e.message,toolName:r?"Bash":e.tool_name,toolInput:r?{command:e.command}:e.tool_input,toolResponse:r?{output:e.output}:e.result_json,transcriptPath:void 0,filePath:e.file_path,edits:e.edits}},formatOutput(t){return{continue:t.continue??!0}}}});var Jk,pq=ht(()=>{"use strict";Jk={normalizeInput(t){let e=t;return{sessionId:e.sessionId??e.session_id??"unknown",cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.toolName??e.tool_name,toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResponse??e.tool_response,transcriptPath:e.transcriptPath??e.transcript_path,filePath:e.filePath??e.file_path,edits:e.edits}},formatOutput(t){return t}}});function fq(t){switch(t){case"claude-code":return cq;case"cursor":return lq;case"raw":return Jk;default:return Jk}}var mq=ht(()=>{"use strict";uq();dq();pq()});var hq=ht(()=>{"use strict"});function vq(t){if(!t||t.trim()==="")return b.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:t}),"unknown-project";let e=gq.default.basename(t);if(e===""){if(process.platform==="win32"){let n=t.match(/^([A-Z]):\\/i);if(n){let s=`drive-${n[1].toUpperCase()}`;return b.info("PROJECT_NAME","Drive root detected",{cwd:t,projectName:s}),s}}return b.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:t}),"unknown-project"}return e}var gq,yq=ht(()=>{"use strict";gq=nt(require("path"),1);ie();hq()});function She(t){let e=t.startsWith("~")?(0,_q.homedir)()+t.slice(1):t;e=e.replace(/\\/g,"/");let r=e.replace(/[.+^${}()|[\]\\]/g,"\\$&");return r=r.replace(/\*\*/g,"<<<GLOBSTAR>>>").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]").replace(/<<<GLOBSTAR>>>/g,".*"),new RegExp(`^${r}$`)}function sv(t,e){if(!e||!e.trim())return!1;let r=t.replace(/\\/g,"/"),n=e.split(",").map(i=>i.trim()).filter(Boolean);for(let i of n)try{if(She(i).test(r))return!0}catch{continue}return!1}var _q,Xk=ht(()=>{"use strict";_q=require("os")});var Yk,Qk=ht(()=>{"use strict";Jr();yq();ie();Tn();Xk();kr();qt();Yk={async execute(t){if(!await In())return{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let{sessionId:r,cwd:n,prompt:i}=t;if(!r)return b.warn("HOOK","session-init: No sessionId provided, skipping (Codex CLI or unknown platform)"),{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let s=Re.loadFromFile(Qt);if(n&&sv(n,s.VIBELEARN_EXCLUDED_PROJECTS))return b.info("HOOK","Project excluded from tracking",{cwd:n}),{continue:!0,suppressOutput:!0};let o=!i||!i.trim()?"[media prompt]":i,a=vq(n);b.debug("HOOK","session-init: Calling /api/sessions/init",{contentSessionId:r,project:a});let c=await Gt("/api/sessions/init",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contentSessionId:r,project:a,prompt:o})});if(!c.ok)return b.failure("HOOK",`Session initialization failed: ${c.status}`,{contentSessionId:r,project:a}),{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let u=await c.json(),l=u.sessionDbId,d=u.promptNumber;if(b.debug("HOOK","session-init: Received from /api/sessions/init",{sessionDbId:l,promptNumber:d,skipped:u.skipped,contextInjected:u.contextInjected}),b.debug("HOOK",`[ALIGNMENT] Hook Entry | contentSessionId=${r} | prompt#=${d} | sessionDbId=${l}`),u.skipped&&u.reason==="private")return b.info("HOOK",`INIT_COMPLETE | sessionDbId=${l} | promptNumber=${d} | skipped=true | reason=private`,{sessionId:l}),{continue:!0,suppressOutput:!0};if(u.contextInjected)return b.info("HOOK",`INIT_COMPLETE | sessionDbId=${l} | promptNumber=${d} | skipped_agent_init=true | reason=context_already_injected`,{sessionId:l}),{continue:!0,suppressOutput:!0};if(t.platform!=="cursor"&&l){let p=o.startsWith("/")?o.substring(1):o;b.debug("HOOK","session-init: Calling /sessions/{sessionDbId}/init",{sessionDbId:l,promptNumber:d});let f=await Gt(`/sessions/${l}/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userPrompt:p,promptNumber:d})});f.ok||b.failure("HOOK",`SDK agent start failed: ${f.status}`,{sessionDbId:l,promptNumber:d})}else t.platform==="cursor"&&b.debug("HOOK","session-init: Skipping SDK agent init for Cursor platform",{sessionDbId:l,promptNumber:d});return b.info("HOOK",`INIT_COMPLETE | sessionDbId=${l} | promptNumber=${d} | project=${a}`,{sessionId:l}),{continue:!0,suppressOutput:!0}}}});function Ehe(t,e,r,n,i){let s=r??{},o={contentSessionId:t,tool_name:e,cwd:i,tool_input:r,tool_response:n};if(e==="Write"||e==="Edit"||e==="NotebookEdit"){let a=s.file_path??s.path??"",c=s.content??s.new_string??"";return c.length>bq&&(c=c.slice(0,bq)+`
|
|
176
176
|
// [truncated]`),{...o,tool_type:e==="Write"?"file_write":"file_edit",file_path:a,content:c}}if(e==="Read")return{...o,tool_type:"file_read",file_path:s.file_path??s.path??""};if(e==="Bash"){let a=s.command??s.cmd??"";if(whe.test(a.trim())){let l=a.trim().split(/\s+/).slice(2);return{...o,tool_type:"package_install",command:a,package_names:l}}let u=String(n??"").slice(0,2e3);return{...o,tool_type:"bash_command",command:a,output:u}}return{...o,tool_type:"other_tool"}}var bq,whe,e$,t$=ht(()=>{"use strict";Jr();ie();Tn();Xk();kr();qt();bq=10*1024,whe=/^(npm\s+install|npm\s+i|yarn\s+add|pnpm\s+add|pip\s+install|pip3\s+install|go\s+get|cargo\s+add|bundle\s+add)\s+/;e$={async execute(t){if(!await In())return{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};let{sessionId:r,cwd:n,toolName:i,toolInput:s,toolResponse:o}=t;if(!i)return{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};if(!n)throw new Error(`Missing cwd in PostToolUse hook input for session ${r}, tool ${i}`);let a=Re.loadFromFile(Qt);if(sv(n,a.VIBELEARN_EXCLUDED_PROJECTS))return b.debug("HOOK","Project excluded from tracking, skipping observation",{cwd:n,toolName:i}),{continue:!0,suppressOutput:!0};let c=Ehe(r,i,s,o,n);b.dataIn("HOOK",`PostToolUse: ${i} [${c.tool_type}]`,{});try{let u=await Gt("/api/sessions/observations",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!u.ok)return b.warn("HOOK","Observation storage failed, skipping",{status:u.status,toolName:i}),{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS};b.debug("HOOK","Observation sent successfully",{toolName:i,type:c.tool_type})}catch(u){return b.warn("HOOK","Observation fetch error, skipping",{error:u instanceof Error?u.message:String(u)}),{continue:!0,suppressOutput:!0,exitCode:ut.SUCCESS}}return{continue:!0,suppressOutput:!0}}}});function xq(t,e,r=!1){if(!t||!(0,ov.existsSync)(t))return b.warn("PARSER",`Transcript path missing or file does not exist: ${t}`),"";let n=(0,ov.readFileSync)(t,"utf-8").trim();if(!n)return b.warn("PARSER",`Transcript file exists but is empty: ${t}`),"";let i=n.split(`
|
|
177
177
|
`),s=!1;for(let o=i.length-1;o>=0;o--){let a=JSON.parse(i[o]);if(a.type===e&&(s=!0,a.message?.content)){let c="",u=a.message.content;if(typeof u=="string")c=u;else if(Array.isArray(u))c=u.filter(l=>l.type==="text").map(l=>l.text).join(`
|
|
178
178
|
`);else throw new Error(`Unknown message content format in transcript. Type: ${typeof u}`);return r&&(c=c.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g,""),c=c.replace(/\n{3,}/g,`
|
|
@@ -247,7 +247,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
247
247
|
`);if(e===-1)return null;let r=this._buffer.toString("utf8",0,e).replace(/\r$/,"");return this._buffer=this._buffer.subarray(e+1),MW(r)}clear(){this._buffer=void 0}};function MW(t){return TR.parse(JSON.parse(t))}function gC(t){return JSON.stringify(t)+`
|
|
248
248
|
`}var LW=Nl.default.platform==="win32"?["APPDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","PATH","PROCESSOR_ARCHITECTURE","SYSTEMDRIVE","SYSTEMROOT","TEMP","USERNAME","USERPROFILE","PROGRAMFILES"]:["HOME","LOGNAME","PATH","SHELL","TERM","USER"];function UW(){let t={};for(let e of LW){let r=Nl.default.env[e];r!==void 0&&(r.startsWith("()")||(t[e]=r))}return t}var Em=class{constructor(e){this._readBuffer=new wm,this._stderrStream=null,this._serverParams=e,(e.stderr==="pipe"||e.stderr==="overlapped")&&(this._stderrStream=new yC.PassThrough)}async start(){if(this._process)throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");return new Promise((e,r)=>{this._process=(0,vC.default)(this._serverParams.command,this._serverParams.args??[],{env:{...UW(),...this._serverParams.env},stdio:["pipe","pipe",this._serverParams.stderr??"inherit"],shell:!1,windowsHide:Nl.default.platform==="win32"&&qW(),cwd:this._serverParams.cwd}),this._process.on("error",n=>{r(n),this.onerror?.(n)}),this._process.on("spawn",()=>{e()}),this._process.on("close",n=>{this._process=void 0,this.onclose?.()}),this._process.stdin?.on("error",n=>{this.onerror?.(n)}),this._process.stdout?.on("data",n=>{this._readBuffer.append(n),this.processReadBuffer()}),this._process.stdout?.on("error",n=>{this.onerror?.(n)}),this._stderrStream&&this._process.stderr&&this._process.stderr.pipe(this._stderrStream)})}get stderr(){return this._stderrStream?this._stderrStream:this._process?.stderr??null}get pid(){return this._process?.pid??null}processReadBuffer(){for(;;)try{let e=this._readBuffer.readMessage();if(e===null)break;this.onmessage?.(e)}catch(e){this.onerror?.(e)}}async close(){if(this._process){let e=this._process;this._process=void 0;let r=new Promise(n=>{e.once("close",()=>{n()})});try{e.stdin?.end()}catch{}if(await Promise.race([r,new Promise(n=>setTimeout(n,2e3).unref())]),e.exitCode===null){try{e.kill("SIGTERM")}catch{}await Promise.race([r,new Promise(n=>setTimeout(n,2e3).unref())])}if(e.exitCode===null)try{e.kill("SIGKILL")}catch{}}this._readBuffer.clear()}send(e){return new Promise(r=>{if(!this._process?.stdin)throw new Error("Not connected");let n=gC(e);this._process.stdin.write(n)?r():this._process.stdin.once("drain",r)})}};function qW(){return"type"in Nl.default}Jr();Tn();kr();var Ua=require("fs"),b0=require("path"),AC=require("os");ie();var u7=(0,b0.join)((0,AC.homedir)(),".vibelearn"),_0=(0,b0.join)(u7,".env"),l7=["ANTHROPIC_API_KEY","CLAUDECODE"];function d7(t){let e={};for(let r of t.split(`
|
|
249
249
|
`)){let n=r.trim();if(!n||n.startsWith("#"))continue;let i=n.indexOf("=");if(i===-1)continue;let s=n.slice(0,i).trim(),o=n.slice(i+1).trim();(o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'"))&&(o=o.slice(1,-1)),s&&(e[s]=o)}return e}function x0(){if(!(0,Ua.existsSync)(_0))return{};try{let t=(0,Ua.readFileSync)(_0,"utf-8"),e=d7(t),r={};return e.ANTHROPIC_API_KEY&&(r.ANTHROPIC_API_KEY=e.ANTHROPIC_API_KEY),e.GEMINI_API_KEY&&(r.GEMINI_API_KEY=e.GEMINI_API_KEY),e.OPENROUTER_API_KEY&&(r.OPENROUTER_API_KEY=e.OPENROUTER_API_KEY),e.VIBELEARN_API_KEY&&(r.VIBELEARN_API_KEY=e.VIBELEARN_API_KEY),r}catch(t){return b.warn("ENV","Failed to load .env file",{path:_0},t),{}}}function jC(t=!0){let e={};for(let[r,n]of Object.entries(process.env))n!==void 0&&!l7.includes(r)&&(e[r]=n);if(e.CLAUDE_CODE_ENTRYPOINT="sdk-ts",t){let r=x0();(process.env.VIBELEARN_CLAUDE_AUTH_METHOD??"cli")==="api"&&r.ANTHROPIC_API_KEY&&(e.ANTHROPIC_API_KEY=r.ANTHROPIC_API_KEY),r.GEMINI_API_KEY&&(e.GEMINI_API_KEY=r.GEMINI_API_KEY),r.OPENROUTER_API_KEY&&(e.OPENROUTER_API_KEY=r.OPENROUTER_API_KEY),!e.ANTHROPIC_API_KEY&&process.env.CLAUDE_CODE_OAUTH_TOKEN&&(e.CLAUDE_CODE_OAUTH_TOKEN=process.env.CLAUDE_CODE_OAUTH_TOKEN)}return e}function qa(t){return x0()[t]}function p7(){return!!x0().ANTHROPIC_API_KEY}function Om(){return p7()?"API key (from ~/.vibelearn/.env)":process.env.CLAUDE_CODE_OAUTH_TOKEN?"Claude Code OAuth token (from parent process)":"Claude Code CLI (subscription billing)"}ie();var mo=require("fs"),GC=require("os"),$0=nt(require("path"),1);ie();var Bi=require("fs"),DC=require("os"),Ml=nt(require("path"),1);ie();var f7=5e3,m7=1e3,h7=Ml.default.join((0,DC.homedir)(),".vibelearn"),g7=Ml.default.join(h7,"supervisor.json");function pn(t){if(!Number.isInteger(t)||t<0||t===0)return!1;try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}var w0=class{registryPath;entries=new Map;runtimeProcesses=new Map;initialized=!1;constructor(e=g7){this.registryPath=e}initialize(){if(this.initialized)return;if(this.initialized=!0,(0,Bi.mkdirSync)(Ml.default.dirname(this.registryPath),{recursive:!0}),!(0,Bi.existsSync)(this.registryPath)){this.persist();return}try{let n=JSON.parse((0,Bi.readFileSync)(this.registryPath,"utf-8")).processes??{};for(let[i,s]of Object.entries(n))this.entries.set(i,s)}catch(r){b.warn("SYSTEM","Failed to parse supervisor registry, rebuilding",{path:this.registryPath},r),this.entries.clear()}let e=this.pruneDeadEntries();e>0&&b.info("SYSTEM","Removed dead processes from supervisor registry",{removed:e}),this.persist()}register(e,r,n){this.initialize(),this.entries.set(e,r),n&&this.runtimeProcesses.set(e,n),this.persist()}unregister(e){this.initialize(),this.entries.delete(e),this.runtimeProcesses.delete(e),this.persist()}clear(){this.entries.clear(),this.runtimeProcesses.clear(),this.persist()}getAll(){return this.initialize(),Array.from(this.entries.entries()).map(([e,r])=>({id:e,...r})).sort((e,r)=>{let n=Date.parse(e.startedAt),i=Date.parse(r.startedAt);return(Number.isNaN(n)?0:n)-(Number.isNaN(i)?0:i)})}getBySession(e){let r=String(e);return this.getAll().filter(n=>n.sessionId!==void 0&&String(n.sessionId)===r)}getRuntimeProcess(e){return this.runtimeProcesses.get(e)}getByPid(e){return this.getAll().filter(r=>r.pid===e)}pruneDeadEntries(){this.initialize();let e=0;for(let[r,n]of this.entries)pn(n.pid)||(this.entries.delete(r),this.runtimeProcesses.delete(r),e+=1);return e>0&&this.persist(),e}async reapSession(e){this.initialize();let r=this.getBySession(e);if(r.length===0)return 0;let n=typeof e=="number"?e:Number(e)||void 0;b.info("SYSTEM",`Reaping ${r.length} process(es) for session ${e}`,{sessionId:n,pids:r.map(a=>a.pid)});let i=r.filter(a=>pn(a.pid));for(let a of i)try{process.kill(a.pid,"SIGTERM")}catch(c){c.code!=="ESRCH"&&b.debug("SYSTEM",`Failed to SIGTERM session process PID ${a.pid}`,{pid:a.pid},c)}let s=Date.now()+f7;for(;Date.now()<s&&i.filter(c=>pn(c.pid)).length!==0;)await new Promise(c=>setTimeout(c,100));let o=i.filter(a=>pn(a.pid));for(let a of o){b.warn("SYSTEM",`Session process PID ${a.pid} did not exit after SIGTERM, sending SIGKILL`,{pid:a.pid,sessionId:n});try{process.kill(a.pid,"SIGKILL")}catch(c){c.code!=="ESRCH"&&b.debug("SYSTEM",`Failed to SIGKILL session process PID ${a.pid}`,{pid:a.pid},c)}}if(o.length>0){let a=Date.now()+m7;for(;Date.now()<a&&o.filter(u=>pn(u.pid)).length!==0;)await new Promise(u=>setTimeout(u,100))}for(let a of r)this.entries.delete(a.id),this.runtimeProcesses.delete(a.id);return this.persist(),b.info("SYSTEM",`Reaped ${r.length} process(es) for session ${e}`,{sessionId:n,reaped:r.length}),r.length}persist(){let e={processes:Object.fromEntries(this.entries.entries())};(0,Bi.mkdirSync)(Ml.default.dirname(this.registryPath),{recursive:!0}),(0,Bi.writeFileSync)(this.registryPath,JSON.stringify(e,null,2))}},S0=null;function Pm(){return S0||(S0=new w0),S0}var LC=require("child_process"),UC=require("fs"),qC=require("os"),E0=nt(require("path"),1),FC=require("util");ie();Tn();var v7=(0,FC.promisify)(LC.execFile),y7=E0.default.join((0,qC.homedir)(),".vibelearn"),_7=E0.default.join(y7,"worker.pid");async function ZC(t){let e=t.currentPid??process.pid,r=t.pidFilePath??_7,n=t.registry.getAll(),i=[...n].filter(o=>o.pid!==e).sort((o,a)=>Date.parse(a.startedAt)-Date.parse(o.startedAt));for(let o of i){if(!pn(o.pid)){t.registry.unregister(o.id);continue}try{await MC(o.pid,"SIGTERM")}catch(a){b.debug("SYSTEM","Failed to send SIGTERM to child process",{pid:o.pid,type:o.type},a)}}await zC(i,5e3);let s=i.filter(o=>pn(o.pid));for(let o of s)try{await MC(o.pid,"SIGKILL")}catch(a){b.debug("SYSTEM","Failed to force kill child process",{pid:o.pid,type:o.type},a)}await zC(s,1e3);for(let o of i)t.registry.unregister(o.id);for(let o of n.filter(a=>a.pid===e))t.registry.unregister(o.id);try{(0,UC.rmSync)(r,{force:!0})}catch(o){b.debug("SYSTEM","Failed to remove PID file during shutdown",{pidFilePath:r},o)}t.registry.pruneDeadEntries()}async function zC(t,e){let r=Date.now()+e;for(;Date.now()<r;){if(t.filter(i=>pn(i.pid)).length===0)return;await new Promise(i=>setTimeout(i,100))}}async function MC(t,e){if(e==="SIGTERM"){try{process.kill(t,e)}catch(r){if(r.code==="ESRCH")return;throw r}return}if(process.platform==="win32"){let r=await b7();if(r){await new Promise((i,s)=>{r(t,e,o=>{if(!o){i();return}if(o.code==="ESRCH"){i();return}s(o)})});return}let n=["/PID",String(t),"/T"];e==="SIGKILL"&&n.push("/F"),await v7("taskkill",n,{timeout:Mr.POWERSHELL_COMMAND,windowsHide:!0});return}try{process.kill(t,e)}catch(r){if(r.code==="ESRCH")return;throw r}}async function b7(){let t="tree-kill";try{let e=await import(t);return e.default??e}catch{return null}}ie();var HC=3e4,Fa=null;function x7(){let e=Pm().pruneDeadEntries();e>0&&b.info("SYSTEM",`Health check: pruned ${e} dead process(es) from registry`)}function BC(){Fa===null&&(Fa=setInterval(x7,HC),Fa.unref(),b.debug("SYSTEM","Health checker started",{intervalMs:HC}))}function VC(){Fa!==null&&(clearInterval(Fa),Fa=null,b.debug("SYSTEM","Health checker stopped"))}var S7=$0.default.join((0,GC.homedir)(),".vibelearn"),w7=$0.default.join(S7,"worker.pid"),k0=class{registry;started=!1;stopPromise=null;signalHandlersRegistered=!1;shutdownInitiated=!1;shutdownHandler=null;constructor(e){this.registry=e}async start(){if(this.started)return;if(this.registry.initialize(),T0({logAlive:!1})==="alive")throw new Error("Worker already running");this.started=!0,BC()}configureSignalHandlers(e){if(this.shutdownHandler=e,this.signalHandlersRegistered)return;this.signalHandlersRegistered=!0;let r=async n=>{if(this.shutdownInitiated){b.warn("SYSTEM",`Received ${n} but shutdown already in progress`);return}this.shutdownInitiated=!0,b.info("SYSTEM",`Received ${n}, shutting down...`);try{this.shutdownHandler?await this.shutdownHandler():await this.stop()}catch(i){b.error("SYSTEM","Error during shutdown",{},i);try{await this.stop()}catch(s){b.debug("SYSTEM","Supervisor shutdown fallback failed",{},s)}}process.exit(0)};process.on("SIGTERM",()=>{r("SIGTERM")}),process.on("SIGINT",()=>{r("SIGINT")}),process.platform!=="win32"&&(process.argv.includes("--daemon")?process.on("SIGHUP",()=>{b.debug("SYSTEM","Ignoring SIGHUP in daemon mode")}):process.on("SIGHUP",()=>{r("SIGHUP")}))}async stop(){if(this.stopPromise){await this.stopPromise;return}VC(),this.stopPromise=ZC({registry:this.registry,currentPid:process.pid}).finally(()=>{this.started=!1,this.stopPromise=null}),await this.stopPromise}assertCanSpawn(e){if(this.stopPromise!==null)throw new Error(`Supervisor is shutting down, refusing to spawn ${e}`)}registerProcess(e,r,n){this.registry.register(e,r,n)}unregisterProcess(e){this.registry.unregister(e)}getRegistry(){return this.registry}},Cm=new k0(Pm());async function WC(){await Cm.start()}async function KC(){await Cm.stop()}function Ft(){return Cm}function JC(t){Cm.configureSignalHandlers(t)}function T0(t={}){let e=t.pidFilePath??w7;if(!(0,mo.existsSync)(e))return"missing";let r=null;try{r=JSON.parse((0,mo.readFileSync)(e,"utf-8"))}catch(n){return b.warn("SYSTEM","Failed to parse worker PID file, removing it",{path:e},n),(0,mo.rmSync)(e,{force:!0}),"invalid"}return pn(r.pid)?((t.logAlive??!0)&&b.info("SYSTEM","Worker already running (PID alive)",{existingPid:r.pid,existingPort:r.port,startedAt:r.startedAt}),"alive"):(b.info("SYSTEM","Removing stale PID file (worker process is dead)",{pid:r.pid,port:r.port,startedAt:r.startedAt}),(0,mo.rmSync)(e,{force:!0}),"stale")}var I0=["CLAUDECODE_","CLAUDE_CODE_"],R0=new Set(["CLAUDECODE","CLAUDE_CODE_SESSION","CLAUDE_CODE_ENTRYPOINT","MCP_SESSION_ID"]);function ks(t=process.env){let e={};for(let[r,n]of Object.entries(t))n!==void 0&&(R0.has(r)||I0.some(i=>r.startsWith(i))||(e[r]=n));return e}var Nm=require("fs"),O0=require("path"),XC=require("os"),E7="vibelearn@anergcorp";function Am(){try{let t=process.env.CLAUDE_CONFIG_DIR||(0,O0.join)((0,XC.homedir)(),".claude"),e=(0,O0.join)(t,"settings.json");if(!(0,Nm.existsSync)(e))return!1;let r=(0,Nm.readFileSync)(e,"utf-8");return JSON.parse(r)?.enabledPlugins?.[E7]===!1}catch{return!1}}var $s=nt(require("path"),1),C0=require("os"),er=require("fs"),Vi=require("child_process"),tN=require("util");ie();Tn();var YC=(0,tN.promisify)(Vi.exec),rN=$s.default.join((0,C0.homedir)(),".vibelearn"),mi=$s.default.join(rN,"worker.pid");var QC=30;function eN(t){return t?/(^|[\\/])bun(\.exe)?$/i.test(t.trim()):!1}function k7(t,e){let r=e==="win32"?`where ${t}`:`which ${t}`;try{return(0,Vi.execSync)(r,{stdio:["ignore","pipe","ignore"],encoding:"utf-8",windowsHide:!0}).split(/\r?\n/).map(s=>s.trim()).find(s=>s.length>0)||null}catch{return null}}function $7(t={}){let e=t.platform??process.platform,r=t.execPath??process.execPath;if(e!=="win32"||eN(r))return r;let n=t.env??process.env,i=t.homeDirectory??(0,C0.homedir)(),s=t.pathExists??er.existsSync,o=t.lookupInPath??k7,a=[n.BUN,n.BUN_PATH,$s.default.join(i,".bun","bin","bun.exe"),$s.default.join(i,".bun","bin","bun"),n.USERPROFILE?$s.default.join(n.USERPROFILE,".bun","bin","bun.exe"):void 0,n.LOCALAPPDATA?$s.default.join(n.LOCALAPPDATA,"bun","bun.exe"):void 0,n.LOCALAPPDATA?$s.default.join(n.LOCALAPPDATA,"bun","bin","bun.exe"):void 0];for(let c of a){let u=c?.trim();if(u&&(eN(u)&&s(u)||u.toLowerCase()==="bun"))return u}return o("bun",e)}function nN(t){(0,er.mkdirSync)(rN,{recursive:!0}),(0,er.writeFileSync)(mi,JSON.stringify(t,null,2))}function N0(){if(!(0,er.existsSync)(mi))return null;try{return JSON.parse((0,er.readFileSync)(mi,"utf-8"))}catch(t){return b.warn("SYSTEM","Failed to parse PID file",{path:mi},t),null}}function ho(){if((0,er.existsSync)(mi))try{(0,er.unlinkSync)(mi)}catch(t){b.warn("SYSTEM","Failed to remove PID file",{path:mi},t)}}function Gi(t){return process.platform==="win32"?Math.round(t*2):t}function T7(t){if(!t||t.trim()==="")return-1;let e=t.trim(),r=0,n=e.match(/^(\d+)-(\d+):(\d+):(\d+)$/);if(n)return r=parseInt(n[1],10)*24*60+parseInt(n[2],10)*60+parseInt(n[3],10),r;let i=e.match(/^(\d+):(\d+):(\d+)$/);if(i)return r=parseInt(i[1],10)*60+parseInt(i[2],10),r;let s=e.match(/^(\d+):(\d+)$/);return s?parseInt(s[1],10):-1}var P0=["worker-service.cjs","chroma-mcp"],I7=["mcp-server.cjs"];async function iN(){let t=process.platform==="win32",e=process.pid,r=[],n=[...P0,...I7];try{if(t){let s=`powershell -NoProfile -NonInteractive -Command "Get-CimInstance Win32_Process -Filter '(${n.map(l=>`CommandLine LIKE '%${l}%'`).join(" OR ")}) AND ProcessId != ${e}' | Select-Object ProcessId, CommandLine, CreationDate | ConvertTo-Json"`,{stdout:o}=await YC(s,{timeout:Mr.POWERSHELL_COMMAND,windowsHide:!0});if(!o.trim()||o.trim()==="null"){b.debug("SYSTEM","No orphaned vibelearn processes found (Windows)");return}let a=JSON.parse(o),c=Array.isArray(a)?a:[a],u=Date.now();for(let l of c){let d=l.ProcessId;if(!Number.isInteger(d)||d<=0||d===e)continue;let p=l.CommandLine||"";if(P0.some(m=>p.includes(m)))r.push(d),b.debug("SYSTEM","Found orphaned process (aggressive)",{pid:d,commandLine:p.substring(0,80)});else{let m=l.CreationDate?.match(/\/Date\((\d+)\)\//);if(m){let g=parseInt(m[1],10),h=(u-g)/(1e3*60);h>=QC&&(r.push(d),b.debug("SYSTEM","Found orphaned process (age-gated)",{pid:d,ageMinutes:Math.round(h)}))}}}}else{let i=n.join("|"),{stdout:s}=await YC(`ps -eo pid,etime,command | grep -E "${i}" | grep -v grep || true`);if(!s.trim()){b.debug("SYSTEM","No orphaned vibelearn processes found (Unix)");return}let o=s.trim().split(`
|
|
250
|
-
`);for(let a of o){let c=a.trim().match(/^(\d+)\s+(\S+)\s+(.*)$/);if(!c)continue;let u=parseInt(c[1],10),l=c[2],d=c[3];if(!Number.isInteger(u)||u<=0||u===e)continue;if(P0.some(f=>d.includes(f)))r.push(u),b.debug("SYSTEM","Found orphaned process (aggressive)",{pid:u,command:d.substring(0,80)});else{let f=T7(l);f>=QC&&(r.push(u),b.debug("SYSTEM","Found orphaned process (age-gated)",{pid:u,ageMinutes:f,command:d.substring(0,80)}))}}}}catch(i){b.error("SYSTEM","Failed to enumerate orphaned processes during aggressive cleanup",{},i);return}if(r.length!==0){if(b.info("SYSTEM","Aggressive startup cleanup: killing orphaned processes",{platform:t?"Windows":"Unix",count:r.length,pids:r}),t){for(let i of r)if(!(!Number.isInteger(i)||i<=0))try{(0,Vi.execSync)(`taskkill /PID ${i} /T /F`,{timeout:Mr.POWERSHELL_COMMAND,stdio:"ignore",windowsHide:!0})}catch(s){b.debug("SYSTEM","Failed to kill process, may have already exited",{pid:i},s)}}else for(let i of r)try{process.kill(i,"SIGKILL")}catch(s){b.debug("SYSTEM","Process already exited",{pid:i},s)}b.info("SYSTEM","Aggressive startup cleanup complete",{count:r.length})}}function A0(t,e,r={}){let n=process.platform==="win32";Ft().assertCanSpawn("worker daemon");let i=ks({...process.env,VIBELEARN_WORKER_PORT:String(e),...r});if(n){let a=$7();if(!a){b.error("SYSTEM","Failed to locate Bun runtime for Windows worker spawn");return}let c=a.replace(/'/g,"''"),u=t.replace(/'/g,"''"),l=`Start-Process -FilePath '${c}' -ArgumentList '${u}','--daemon' -WindowStyle Hidden`;try{return(0,Vi.execSync)(`powershell -NoProfile -Command "${l}"`,{stdio:"ignore",windowsHide:!0,env:i}),0}catch(d){b.error("SYSTEM","Failed to spawn worker daemon on Windows",{runtimePath:a},d);return}}let s="/usr/bin/setsid";if((0,er.existsSync)(s)){let a=(0,Vi.spawn)(s,[process.execPath,t,"--daemon"],{detached:!0,stdio:"ignore",env:i});return a.pid===void 0?void 0:(a.unref(),a.pid)}let o=(0,Vi.spawn)(process.execPath,[t,"--daemon"],{detached:!0,stdio:"ignore",env:i});if(o.pid!==void 0)return o.unref(),o.pid}function sN(t){if(t===0)return!0;if(!Number.isInteger(t)||t<0)return!1;try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}function oN(t=15e3){try{let e=(0,er.statSync)(mi);return Date.now()-e.mtimeMs<t}catch{return!1}}function aN(){try{if(!(0,er.existsSync)(mi))return;let t=new Date;(0,er.utimesSync)(mi,t,t)}catch{}}function cN(){return T0({logAlive:!1})}var uN=nt(require("path"),1),lN=require("fs");ie();qt();async function j0(t,e,r="GET"){let n=await fetch(`http://127.0.0.1:${t}${e}`,{method:r}),i="";try{i=await n.text()}catch{}return{ok:n.ok,statusCode:n.status,body:i}}async function Ll(t){try{return(await fetch(`http://127.0.0.1:${t}/api/health`)).ok}catch{return!1}}async function dN(t,e,r,n){let i=Date.now();for(;Date.now()-i<r;){try{if((await j0(t,e)).ok)return!0}catch(s){b.debug("SYSTEM",n,{},s)}await new Promise(s=>setTimeout(s,500))}return!1}function go(t,e=3e4){return dN(t,"/api/health",e,"Service not ready yet, will retry")}function pN(t,e=3e4){return dN(t,"/api/readiness",e,"Worker not ready yet, will retry")}async function jm(t,e=1e4){let r=Date.now();for(;Date.now()-r<e;){if(!await Ll(t))return!0;await new Promise(n=>setTimeout(n,500))}return!1}async function Dm(t){try{let e=await j0(t,"/api/admin/shutdown","POST");return e.ok?!0:(b.warn("SYSTEM","Shutdown request returned error",{status:e.statusCode}),!1)}catch(e){return e instanceof Error&&e.message?.includes("ECONNREFUSED")?(b.debug("SYSTEM","Worker already stopped",{},e),!1):(b.error("SYSTEM","Shutdown request failed unexpectedly",{},e),!1)}}function R7(){try{let t=uN.default.join(Hi,"package.json");return JSON.parse((0,lN.readFileSync)(t,"utf-8")).version}catch(t){let e=t.code;if(e==="ENOENT"||e==="EBUSY")return b.debug("SYSTEM","Could not read plugin version (shutdown race)",{code:e}),"unknown";throw t}}async function O7(t){try{let e=await j0(t,"/api/version");return e.ok?JSON.parse(e.body).version:null}catch{return b.debug("SYSTEM","Could not fetch worker version",{}),null}}async function fN(t){let e=R7(),r=await O7(t);return!r||e==="unknown"?{matches:!0,pluginVersion:e,workerVersion:r}:{matches:e===r,pluginVersion:e,workerVersion:r}}ie();async function mN(t){b.info("SYSTEM","Shutdown initiated"),t.server&&(await P7(t.server),b.info("SYSTEM","HTTP server closed")),await t.sessionManager.shutdownAll(),t.mcpClient&&(await t.mcpClient.close(),b.info("SYSTEM","MCP client closed")),t.chromaMcpManager&&(b.info("SHUTDOWN","Stopping Chroma MCP connection..."),await t.chromaMcpManager.stop(),b.info("SHUTDOWN","Chroma MCP connection stopped")),t.dbManager&&await t.dbManager.close(),await KC(),b.info("SYSTEM","Worker shutdown complete")}async function P7(t){t.closeAllConnections(),process.platform==="win32"&&await new Promise(e=>setTimeout(e,500)),await new Promise((e,r)=>{t.close(n=>n?r(n):e())}),process.platform==="win32"&&(await new Promise(e=>setTimeout(e,500)),b.info("SYSTEM","Waited for Windows port cleanup"))}var E2=nt(Zh(),1),qE=nt(require("fs"),1),Ed=nt(require("path"),1);var d2=["search","context","summarize","import","export"],p2=["workflow","search_params","examples","all"];ie();var ME=nt(Zh(),1),y2=nt(v2(),1),_2=nt(require("path"),1);qt();ie();function LE(t){let e=[];e.push(ME.default.json({limit:"50mb"})),e.push((0,y2.default)({origin:(i,s)=>{!i||i.startsWith("http://localhost:")||i.startsWith("http://127.0.0.1:")?s(null,!0):s(new Error("CORS not allowed"))},methods:["GET","HEAD","POST","PUT","PATCH","DELETE"],allowedHeaders:["Content-Type","Authorization","X-Requested-With"],credentials:!1})),e.push((i,s,o)=>{let c=[".html",".js",".css",".svg",".png",".jpg",".jpeg",".webp",".woff",".woff2",".ttf",".eot"].some(m=>i.path.endsWith(m)),u=i.path==="/api/logs";if(i.path.startsWith("/health")||i.path==="/"||c||u)return o();let l=Date.now(),d=`${i.method}-${Date.now()}`,p=t(i.method,i.path,i.body);b.debug("HTTP",`\u2192 ${i.method} ${i.path}`,{requestId:d},p);let f=s.send.bind(s);s.send=function(m){let g=Date.now()-l;return b.debug("HTTP",`\u2190 ${s.statusCode} ${i.path}`,{requestId:d,duration:`${g}ms`}),f(m)},o()});let r=Tr(),n=_2.default.join(r,"plugin","ui");return e.push(ME.default.static(n)),e}function wd(t,e,r){let n=t.ip||t.connection.remoteAddress||"";if(!(n==="127.0.0.1"||n==="::1"||n==="::ffff:127.0.0.1"||n==="localhost")){b.warn("SECURITY","Admin endpoint access denied - not localhost",{endpoint:t.path,clientIp:n,method:t.method}),e.status(403).json({error:"Forbidden",message:"Admin endpoints are only accessible from localhost"});return}r()}function UE(t,e,r){if(!r||Object.keys(r).length===0||e.includes("/init"))return"";if(e.includes("/observations")){let n=r.tool_name||"?",i=r.tool_input;return`tool=${b.formatTool(n,i)}`}return e.includes("/summarize")?"requesting summary":""}ie();var gc=class extends Error{constructor(r,n=500,i,s){super(r);this.statusCode=n;this.code=i;this.details=s;this.name="AppError"}};function b2(t,e,r,n){let i={error:t,message:e};return r&&(i.code=r),n&&(i.details=n),i}var x2=(t,e,r,n)=>{let i=t instanceof gc?t.statusCode:500;b.error("HTTP",`Error handling ${e.method} ${e.path}`,{statusCode:i,error:t.message,code:t instanceof gc?t.code:void 0},t);let s=b2(t.name||"Error",t.message,t instanceof gc?t.code:void 0,t instanceof gc?t.details:void 0);r.status(i).json(s)};function S2(t,e){e.status(404).json(b2("NotFound",`Cannot ${t.method} ${t.path}`))}var w2="0.1.2",Hh=class{app;server=null;options;startTime=Date.now();constructor(e){this.options=e,this.app=(0,E2.default)(),this.setupMiddleware(),this.setupCoreRoutes()}getHttpServer(){return this.server}async listen(e,r){return new Promise((n,i)=>{this.server=this.app.listen(e,r,()=>{b.info("SYSTEM","HTTP server started",{host:r,port:e,pid:process.pid}),n()}),this.server.on("error",i)})}async close(){this.server&&(this.server.closeAllConnections(),process.platform==="win32"&&await new Promise(e=>setTimeout(e,500)),await new Promise((e,r)=>{this.server.close(n=>n?r(n):e())}),process.platform==="win32"&&await new Promise(e=>setTimeout(e,500)),this.server=null,b.info("SYSTEM","HTTP server closed"))}registerRoutes(e){e.setupRoutes(this.app)}finalizeRoutes(){this.app.use(S2),this.app.use(x2)}setupMiddleware(){LE(UE).forEach(r=>this.app.use(r))}setupCoreRoutes(){this.app.get("/api/health",(e,r)=>{r.status(200).json({status:"ok",version:w2,workerPath:this.options.workerPath,uptime:Date.now()-this.startTime,managed:process.env.VIBELEARN_MANAGED==="true",hasIpc:typeof process.send=="function",platform:process.platform,pid:process.pid,initialized:this.options.getInitializationComplete(),mcpReady:this.options.getMcpReady(),ai:this.options.getAiStatus()})}),this.app.get("/api/readiness",(e,r)=>{this.options.getInitializationComplete()?r.status(200).json({status:"ready",mcpReady:this.options.getMcpReady()}):r.status(503).json({status:"initializing",message:"Worker is still initializing, please retry"})}),this.app.get("/api/version",(e,r)=>{r.status(200).json({version:w2})}),this.app.get("/api/instructions",async(e,r)=>{let n=e.query.topic||"all",i=e.query.operation;if(n&&!p2.includes(n))return r.status(400).json({error:"Invalid topic"});try{let s;if(i){if(!d2.includes(i))return r.status(400).json({error:"Invalid operation"});let o=Ed.default.resolve(__dirname,"../skills/mem-search/operations"),a=Ed.default.resolve(o,`${i}.md`);if(!a.startsWith(o+Ed.default.sep))return r.status(400).json({error:"Invalid request"});s=await qE.promises.readFile(a,"utf-8")}else{let o=Ed.default.join(__dirname,"../skills/mem-search/SKILL.md"),a=await qE.promises.readFile(o,"utf-8");s=this.extractInstructionSection(a,n)}r.json({content:[{type:"text",text:s}]})}catch{r.status(404).json({error:"Instruction not found"})}}),this.app.post("/api/admin/restart",wd,async(e,r)=>{r.json({status:"restarting"}),process.platform==="win32"&&process.env.VIBELEARN_MANAGED==="true"&&process.send?(b.info("SYSTEM","Sending restart request to wrapper"),process.send({type:"restart"})):setTimeout(async()=>{try{await this.options.onRestart()}finally{process.exit(0)}},100)}),this.app.post("/api/admin/shutdown",wd,async(e,r)=>{r.json({status:"shutting_down"}),process.platform==="win32"&&process.env.VIBELEARN_MANAGED==="true"&&process.send?(b.info("SYSTEM","Sending shutdown request to wrapper"),process.send({type:"shutdown"})):setTimeout(async()=>{try{await this.options.onShutdown()}finally{process.exit(0)}},100)}),this.app.get("/api/admin/doctor",wd,(e,r)=>{let o=Ft().getRegistry().getAll().map(m=>({id:m.id,pid:m.pid,type:m.type,status:pn(m.pid)?"alive":"dead",startedAt:m.startedAt})),a=o.filter(m=>m.status==="dead").map(m=>m.pid),c=!Object.keys(process.env).some(m=>R0.has(m)||I0.some(g=>m.startsWith(g))),u=Date.now()-this.startTime,l=Math.floor(u/1e3),d=Math.floor(l/3600),p=Math.floor(l%3600/60),f=d>0?`${d}h ${p}m`:`${p}m`;r.json({supervisor:{running:!0,pid:process.pid,uptime:f},processes:o,health:{deadProcessPids:a,envClean:c}})})}extractInstructionSection(e,r){let n={workflow:this.extractBetween(e,"## The Workflow","## Search Parameters"),search_params:this.extractBetween(e,"## Search Parameters","## Examples"),examples:this.extractBetween(e,"## Examples","## Why This Workflow"),all:e};return n[r]||n.all}extractBetween(e,r,n){let i=e.indexOf(r),s=e.indexOf(n);return i===-1?e:s===-1?e.substring(i):e.substring(i,s).trim()}};var mt=nt(require("path"),1),$d=require("os"),Bt=require("fs"),T2=require("child_process"),I2=require("util");ie();Jr();qt();var Nn=require("fs"),kd=require("path");ie();function k2(t){try{return(0,Nn.existsSync)(t)?JSON.parse((0,Nn.readFileSync)(t,"utf-8")):{}}catch(e){return b.error("CONFIG","Failed to read Cursor registry, using empty registry",{file:t,error:e instanceof Error?e.message:String(e)}),{}}}function $2(t,e){let r=(0,kd.join)(t,"..");(0,Nn.mkdirSync)(r,{recursive:!0}),(0,Nn.writeFileSync)(t,JSON.stringify(e,null,2))}function FE(t,e){let r=(0,kd.join)(t,".cursor","rules"),n=(0,kd.join)(r,"vibelearn-context.mdc"),i=`${n}.tmp`;(0,Nn.mkdirSync)(r,{recursive:!0});let s=`---
|
|
250
|
+
`);for(let a of o){let c=a.trim().match(/^(\d+)\s+(\S+)\s+(.*)$/);if(!c)continue;let u=parseInt(c[1],10),l=c[2],d=c[3];if(!Number.isInteger(u)||u<=0||u===e)continue;if(P0.some(f=>d.includes(f)))r.push(u),b.debug("SYSTEM","Found orphaned process (aggressive)",{pid:u,command:d.substring(0,80)});else{let f=T7(l);f>=QC&&(r.push(u),b.debug("SYSTEM","Found orphaned process (age-gated)",{pid:u,ageMinutes:f,command:d.substring(0,80)}))}}}}catch(i){b.error("SYSTEM","Failed to enumerate orphaned processes during aggressive cleanup",{},i);return}if(r.length!==0){if(b.info("SYSTEM","Aggressive startup cleanup: killing orphaned processes",{platform:t?"Windows":"Unix",count:r.length,pids:r}),t){for(let i of r)if(!(!Number.isInteger(i)||i<=0))try{(0,Vi.execSync)(`taskkill /PID ${i} /T /F`,{timeout:Mr.POWERSHELL_COMMAND,stdio:"ignore",windowsHide:!0})}catch(s){b.debug("SYSTEM","Failed to kill process, may have already exited",{pid:i},s)}}else for(let i of r)try{process.kill(i,"SIGKILL")}catch(s){b.debug("SYSTEM","Process already exited",{pid:i},s)}b.info("SYSTEM","Aggressive startup cleanup complete",{count:r.length})}}function A0(t,e,r={}){let n=process.platform==="win32";Ft().assertCanSpawn("worker daemon");let i=ks({...process.env,VIBELEARN_WORKER_PORT:String(e),...r});if(n){let a=$7();if(!a){b.error("SYSTEM","Failed to locate Bun runtime for Windows worker spawn");return}let c=a.replace(/'/g,"''"),u=t.replace(/'/g,"''"),l=`Start-Process -FilePath '${c}' -ArgumentList '${u}','--daemon' -WindowStyle Hidden`;try{return(0,Vi.execSync)(`powershell -NoProfile -Command "${l}"`,{stdio:"ignore",windowsHide:!0,env:i}),0}catch(d){b.error("SYSTEM","Failed to spawn worker daemon on Windows",{runtimePath:a},d);return}}let s="/usr/bin/setsid";if((0,er.existsSync)(s)){let a=(0,Vi.spawn)(s,[process.execPath,t,"--daemon"],{detached:!0,stdio:"ignore",env:i});return a.pid===void 0?void 0:(a.unref(),a.pid)}let o=(0,Vi.spawn)(process.execPath,[t,"--daemon"],{detached:!0,stdio:"ignore",env:i});if(o.pid!==void 0)return o.unref(),o.pid}function sN(t){if(t===0)return!0;if(!Number.isInteger(t)||t<0)return!1;try{return process.kill(t,0),!0}catch(e){return e.code==="EPERM"}}function oN(t=15e3){try{let e=(0,er.statSync)(mi);return Date.now()-e.mtimeMs<t}catch{return!1}}function aN(){try{if(!(0,er.existsSync)(mi))return;let t=new Date;(0,er.utimesSync)(mi,t,t)}catch{}}function cN(){return T0({logAlive:!1})}var uN=nt(require("path"),1),lN=require("fs");ie();qt();async function j0(t,e,r="GET"){let n=await fetch(`http://127.0.0.1:${t}${e}`,{method:r}),i="";try{i=await n.text()}catch{}return{ok:n.ok,statusCode:n.status,body:i}}async function Ll(t){try{return(await fetch(`http://127.0.0.1:${t}/api/health`)).ok}catch{return!1}}async function dN(t,e,r,n){let i=Date.now();for(;Date.now()-i<r;){try{if((await j0(t,e)).ok)return!0}catch(s){b.debug("SYSTEM",n,{},s)}await new Promise(s=>setTimeout(s,500))}return!1}function go(t,e=3e4){return dN(t,"/api/health",e,"Service not ready yet, will retry")}function pN(t,e=3e4){return dN(t,"/api/readiness",e,"Worker not ready yet, will retry")}async function jm(t,e=1e4){let r=Date.now();for(;Date.now()-r<e;){if(!await Ll(t))return!0;await new Promise(n=>setTimeout(n,500))}return!1}async function Dm(t){try{let e=await j0(t,"/api/admin/shutdown","POST");return e.ok?!0:(b.warn("SYSTEM","Shutdown request returned error",{status:e.statusCode}),!1)}catch(e){return e instanceof Error&&e.message?.includes("ECONNREFUSED")?(b.debug("SYSTEM","Worker already stopped",{},e),!1):(b.error("SYSTEM","Shutdown request failed unexpectedly",{},e),!1)}}function R7(){try{let t=uN.default.join(Hi,"package.json");return JSON.parse((0,lN.readFileSync)(t,"utf-8")).version}catch(t){let e=t.code;if(e==="ENOENT"||e==="EBUSY")return b.debug("SYSTEM","Could not read plugin version (shutdown race)",{code:e}),"unknown";throw t}}async function O7(t){try{let e=await j0(t,"/api/version");return e.ok?JSON.parse(e.body).version:null}catch{return b.debug("SYSTEM","Could not fetch worker version",{}),null}}async function fN(t){let e=R7(),r=await O7(t);return!r||e==="unknown"?{matches:!0,pluginVersion:e,workerVersion:r}:{matches:e===r,pluginVersion:e,workerVersion:r}}ie();async function mN(t){b.info("SYSTEM","Shutdown initiated"),t.server&&(await P7(t.server),b.info("SYSTEM","HTTP server closed")),await t.sessionManager.shutdownAll(),t.mcpClient&&(await t.mcpClient.close(),b.info("SYSTEM","MCP client closed")),t.chromaMcpManager&&(b.info("SHUTDOWN","Stopping Chroma MCP connection..."),await t.chromaMcpManager.stop(),b.info("SHUTDOWN","Chroma MCP connection stopped")),t.dbManager&&await t.dbManager.close(),await KC(),b.info("SYSTEM","Worker shutdown complete")}async function P7(t){t.closeAllConnections(),process.platform==="win32"&&await new Promise(e=>setTimeout(e,500)),await new Promise((e,r)=>{t.close(n=>n?r(n):e())}),process.platform==="win32"&&(await new Promise(e=>setTimeout(e,500)),b.info("SYSTEM","Waited for Windows port cleanup"))}var E2=nt(Zh(),1),qE=nt(require("fs"),1),Ed=nt(require("path"),1);var d2=["search","context","summarize","import","export"],p2=["workflow","search_params","examples","all"];ie();var ME=nt(Zh(),1),y2=nt(v2(),1),_2=nt(require("path"),1);qt();ie();function LE(t){let e=[];e.push(ME.default.json({limit:"50mb"})),e.push((0,y2.default)({origin:(i,s)=>{!i||i.startsWith("http://localhost:")||i.startsWith("http://127.0.0.1:")?s(null,!0):s(new Error("CORS not allowed"))},methods:["GET","HEAD","POST","PUT","PATCH","DELETE"],allowedHeaders:["Content-Type","Authorization","X-Requested-With"],credentials:!1})),e.push((i,s,o)=>{let c=[".html",".js",".css",".svg",".png",".jpg",".jpeg",".webp",".woff",".woff2",".ttf",".eot"].some(m=>i.path.endsWith(m)),u=i.path==="/api/logs";if(i.path.startsWith("/health")||i.path==="/"||c||u)return o();let l=Date.now(),d=`${i.method}-${Date.now()}`,p=t(i.method,i.path,i.body);b.debug("HTTP",`\u2192 ${i.method} ${i.path}`,{requestId:d},p);let f=s.send.bind(s);s.send=function(m){let g=Date.now()-l;return b.debug("HTTP",`\u2190 ${s.statusCode} ${i.path}`,{requestId:d,duration:`${g}ms`}),f(m)},o()});let r=Tr(),n=_2.default.join(r,"plugin","ui");return e.push(ME.default.static(n)),e}function wd(t,e,r){let n=t.ip||t.connection.remoteAddress||"";if(!(n==="127.0.0.1"||n==="::1"||n==="::ffff:127.0.0.1"||n==="localhost")){b.warn("SECURITY","Admin endpoint access denied - not localhost",{endpoint:t.path,clientIp:n,method:t.method}),e.status(403).json({error:"Forbidden",message:"Admin endpoints are only accessible from localhost"});return}r()}function UE(t,e,r){if(!r||Object.keys(r).length===0||e.includes("/init"))return"";if(e.includes("/observations")){let n=r.tool_name||"?",i=r.tool_input;return`tool=${b.formatTool(n,i)}`}return e.includes("/summarize")?"requesting summary":""}ie();var gc=class extends Error{constructor(r,n=500,i,s){super(r);this.statusCode=n;this.code=i;this.details=s;this.name="AppError"}};function b2(t,e,r,n){let i={error:t,message:e};return r&&(i.code=r),n&&(i.details=n),i}var x2=(t,e,r,n)=>{let i=t instanceof gc?t.statusCode:500;b.error("HTTP",`Error handling ${e.method} ${e.path}`,{statusCode:i,error:t.message,code:t instanceof gc?t.code:void 0},t);let s=b2(t.name||"Error",t.message,t instanceof gc?t.code:void 0,t instanceof gc?t.details:void 0);r.status(i).json(s)};function S2(t,e){e.status(404).json(b2("NotFound",`Cannot ${t.method} ${t.path}`))}var w2="0.1.3",Hh=class{app;server=null;options;startTime=Date.now();constructor(e){this.options=e,this.app=(0,E2.default)(),this.setupMiddleware(),this.setupCoreRoutes()}getHttpServer(){return this.server}async listen(e,r){return new Promise((n,i)=>{this.server=this.app.listen(e,r,()=>{b.info("SYSTEM","HTTP server started",{host:r,port:e,pid:process.pid}),n()}),this.server.on("error",i)})}async close(){this.server&&(this.server.closeAllConnections(),process.platform==="win32"&&await new Promise(e=>setTimeout(e,500)),await new Promise((e,r)=>{this.server.close(n=>n?r(n):e())}),process.platform==="win32"&&await new Promise(e=>setTimeout(e,500)),this.server=null,b.info("SYSTEM","HTTP server closed"))}registerRoutes(e){e.setupRoutes(this.app)}finalizeRoutes(){this.app.use(S2),this.app.use(x2)}setupMiddleware(){LE(UE).forEach(r=>this.app.use(r))}setupCoreRoutes(){this.app.get("/api/health",(e,r)=>{r.status(200).json({status:"ok",version:w2,workerPath:this.options.workerPath,uptime:Date.now()-this.startTime,managed:process.env.VIBELEARN_MANAGED==="true",hasIpc:typeof process.send=="function",platform:process.platform,pid:process.pid,initialized:this.options.getInitializationComplete(),mcpReady:this.options.getMcpReady(),ai:this.options.getAiStatus()})}),this.app.get("/api/readiness",(e,r)=>{this.options.getInitializationComplete()?r.status(200).json({status:"ready",mcpReady:this.options.getMcpReady()}):r.status(503).json({status:"initializing",message:"Worker is still initializing, please retry"})}),this.app.get("/api/version",(e,r)=>{r.status(200).json({version:w2})}),this.app.get("/api/instructions",async(e,r)=>{let n=e.query.topic||"all",i=e.query.operation;if(n&&!p2.includes(n))return r.status(400).json({error:"Invalid topic"});try{let s;if(i){if(!d2.includes(i))return r.status(400).json({error:"Invalid operation"});let o=Ed.default.resolve(__dirname,"../skills/mem-search/operations"),a=Ed.default.resolve(o,`${i}.md`);if(!a.startsWith(o+Ed.default.sep))return r.status(400).json({error:"Invalid request"});s=await qE.promises.readFile(a,"utf-8")}else{let o=Ed.default.join(__dirname,"../skills/mem-search/SKILL.md"),a=await qE.promises.readFile(o,"utf-8");s=this.extractInstructionSection(a,n)}r.json({content:[{type:"text",text:s}]})}catch{r.status(404).json({error:"Instruction not found"})}}),this.app.post("/api/admin/restart",wd,async(e,r)=>{r.json({status:"restarting"}),process.platform==="win32"&&process.env.VIBELEARN_MANAGED==="true"&&process.send?(b.info("SYSTEM","Sending restart request to wrapper"),process.send({type:"restart"})):setTimeout(async()=>{try{await this.options.onRestart()}finally{process.exit(0)}},100)}),this.app.post("/api/admin/shutdown",wd,async(e,r)=>{r.json({status:"shutting_down"}),process.platform==="win32"&&process.env.VIBELEARN_MANAGED==="true"&&process.send?(b.info("SYSTEM","Sending shutdown request to wrapper"),process.send({type:"shutdown"})):setTimeout(async()=>{try{await this.options.onShutdown()}finally{process.exit(0)}},100)}),this.app.get("/api/admin/doctor",wd,(e,r)=>{let o=Ft().getRegistry().getAll().map(m=>({id:m.id,pid:m.pid,type:m.type,status:pn(m.pid)?"alive":"dead",startedAt:m.startedAt})),a=o.filter(m=>m.status==="dead").map(m=>m.pid),c=!Object.keys(process.env).some(m=>R0.has(m)||I0.some(g=>m.startsWith(g))),u=Date.now()-this.startTime,l=Math.floor(u/1e3),d=Math.floor(l/3600),p=Math.floor(l%3600/60),f=d>0?`${d}h ${p}m`:`${p}m`;r.json({supervisor:{running:!0,pid:process.pid,uptime:f},processes:o,health:{deadProcessPids:a,envClean:c}})})}extractInstructionSection(e,r){let n={workflow:this.extractBetween(e,"## The Workflow","## Search Parameters"),search_params:this.extractBetween(e,"## Search Parameters","## Examples"),examples:this.extractBetween(e,"## Examples","## Why This Workflow"),all:e};return n[r]||n.all}extractBetween(e,r,n){let i=e.indexOf(r),s=e.indexOf(n);return i===-1?e:s===-1?e.substring(i):e.substring(i,s).trim()}};var mt=nt(require("path"),1),$d=require("os"),Bt=require("fs"),T2=require("child_process"),I2=require("util");ie();Jr();qt();var Nn=require("fs"),kd=require("path");ie();function k2(t){try{return(0,Nn.existsSync)(t)?JSON.parse((0,Nn.readFileSync)(t,"utf-8")):{}}catch(e){return b.error("CONFIG","Failed to read Cursor registry, using empty registry",{file:t,error:e instanceof Error?e.message:String(e)}),{}}}function $2(t,e){let r=(0,kd.join)(t,"..");(0,Nn.mkdirSync)(r,{recursive:!0}),(0,Nn.writeFileSync)(t,JSON.stringify(e,null,2))}function FE(t,e){let r=(0,kd.join)(t,".cursor","rules"),n=(0,kd.join)(r,"vibelearn-context.mdc"),i=`${n}.tmp`;(0,Nn.mkdirSync)(r,{recursive:!0});let s=`---
|
|
251
251
|
alwaysApply: true
|
|
252
252
|
description: "VibeLearn context from past sessions (auto-updated)"
|
|
253
253
|
---
|
|
@@ -1592,7 +1592,7 @@ Respond ONLY with this XML (no other text):
|
|
|
1592
1592
|
FROM vl_concepts
|
|
1593
1593
|
WHERE session_id = ?
|
|
1594
1594
|
ORDER BY confidence DESC
|
|
1595
|
-
`).all(i);n.json({summary:o,concepts:a})}};var Khe={},qhe=120*1e3;function m$(){return f$.default.join(Re.get("VIBELEARN_DATA_DIR"),".worker-start-attempted")}function Fhe(){if(process.platform!=="win32")return!1;let t=m$();if(!(0,os.existsSync)(t))return!1;try{let e=(0,os.statSync)(t).mtimeMs;return Date.now()-e<qhe}catch{return!1}}function Zhe(){if(process.platform==="win32")try{(0,os.writeFileSync)(m$(),"","utf-8")}catch{}}function Hhe(){if(process.platform==="win32")try{let t=m$();(0,os.existsSync)(t)&&(0,os.unlinkSync)(t)}catch{}}var Bhe="0.1.2";function Aq(t,e){return{continue:!0,suppressOutput:!0,status:t,...e&&{message:e}}}var av=class{server;startTime=Date.now();mcpClient;mcpReady=!1;initializationCompleteFlag=!1;isShuttingDown=!1;dbManager;sessionManager;sseBroadcaster;sdkAgent;geminiAgent;openRouterAgent;paginationHelper;settingsManager;sessionEventBroadcaster;searchRoutes=null;initializationComplete;resolveInitialization;stopOrphanReaper=null;staleSessionReaperInterval=null;lastAiInteraction=null;constructor(){this.initializationComplete=new Promise(e=>{this.resolveInitialization=e}),this.dbManager=new Kh,this.sessionManager=new Qh(this.dbManager),this.sseBroadcaster=new eg,this.sdkAgent=new Pg(this.dbManager,this.sessionManager),this.geminiAgent=new Cg(this.dbManager,this.sessionManager),this.openRouterAgent=new jg(this.dbManager,this.sessionManager),this.paginationHelper=new Dg(this.dbManager),this.settingsManager=new zg(this.dbManager),this.sessionEventBroadcaster=new qg(this.sseBroadcaster,this),this.sessionManager.setOnSessionDeleted(()=>{this.broadcastProcessingStatus()}),this.mcpClient=new xm({name:"worker-search-proxy",version:Bhe},{capabilities:{}}),this.server=new Hh({getInitializationComplete:()=>this.initializationCompleteFlag,getMcpReady:()=>this.mcpReady,onShutdown:()=>this.shutdown(),onRestart:()=>this.shutdown(),workerPath:__filename,getAiStatus:()=>{let e="claude";return Gc()&&Zo()?e="openrouter":Vc()&&Fo()&&(e="gemini"),{provider:e,authMethod:Om(),lastInteraction:this.lastAiInteraction?{timestamp:this.lastAiInteraction.timestamp,success:this.lastAiInteraction.success,...this.lastAiInteraction.error&&{error:this.lastAiInteraction.error}}:null}}}),this.registerRoutes(),this.registerSignalHandlers()}registerSignalHandlers(){JC(async()=>{this.isShuttingDown=!0,await this.shutdown()})}registerRoutes(){this.server.app.get("/api/context/inject",async(e,r,n)=>{if(!this.initializationCompleteFlag||!this.searchRoutes){b.warn("SYSTEM","Context requested before initialization complete, returning empty"),r.status(200).json({content:[{type:"text",text:""}]});return}n()}),this.server.app.use("/api",async(e,r,n)=>{if(this.initializationCompleteFlag){n();return}let i=3e4,s=new Promise((o,a)=>setTimeout(()=>a(new Error("Database initialization timeout")),i));try{await Promise.race([this.initializationComplete,s]),n()}catch(o){b.error("HTTP",`Request to ${e.method} ${e.path} rejected \u2014 DB not initialized`,{},o),r.status(503).json({error:"Service initializing",message:"Database is still initializing, please retry"})}}),this.server.registerRoutes(new Zg(this.sseBroadcaster,this.dbManager,this.sessionManager)),this.server.registerRoutes(new Vg(this.sessionManager,this.dbManager,this.sdkAgent,this.geminiAgent,this.openRouterAgent,this.sessionEventBroadcaster,this)),this.server.registerRoutes(new Gg(this.paginationHelper,this.dbManager,this.sessionManager,this.sseBroadcaster,this,this.startTime)),this.server.registerRoutes(new Xg(this.settingsManager)),this.server.registerRoutes(new Qg),this.server.registerRoutes(new ev(this.dbManager,"vibelearn")),this.server.registerRoutes(new iv(this.dbManager))}async start(){let e=dn(),r=y0();await WC(),await this.server.listen(e,r),nN({pid:process.pid,port:e,startedAt:new Date().toISOString()}),Ft().registerProcess("worker",{pid:process.pid,type:"worker",startedAt:new Date().toISOString()}),b.info("SYSTEM","Worker started",{host:r,port:e,pid:process.pid}),this.initializeBackground().catch(n=>{b.error("SYSTEM","Background initialization failed",{},n)})}async initializeBackground(){try{await iN();let{ModeManager:e}=await Promise.resolve().then(()=>(Xn(),G2)),{SettingsDefaultsManager:r}=await Promise.resolve().then(()=>(kr(),wC)),{USER_SETTINGS_PATH:n}=await Promise.resolve().then(()=>(qt(),PC)),i=r.loadFromFile(n),s="code";e.getInstance().loadMode(s),b.info("SYSTEM",`Mode loaded: ${s}`),await this.dbManager.initialize();let{PendingMessageStore:o}=await Promise.resolve().then(()=>(js(),Ao)),c=new o(this.dbManager.getSessionStore().db,3).resetStaleProcessingMessages(0);c>0&&b.info("SYSTEM",`Reset ${c} stale processing messages to pending`);let u=new Lg,l=new Ug,d=new Mg(this.dbManager.getSessionSearch(),this.dbManager.getSessionStore(),this.dbManager.getChromaSync(),u,l);this.searchRoutes=new Wg(d),this.server.registerRoutes(this.searchRoutes),b.info("WORKER","SearchManager initialized and search routes registered"),this.initializationCompleteFlag=!0,this.resolveInitialization(),b.info("SYSTEM","Core initialization complete (DB + search ready)");let p=f$.default.join(__dirname,"mcp-server.cjs");Ft().assertCanSpawn("mcp server");let f=new Em({command:"node",args:[p],env:ks(process.env)}),m=3e5,g=this.mcpClient.connect(f),h,v=new Promise((y,x)=>{h=setTimeout(()=>x(new Error("MCP connection timeout after 5 minutes")),m)});try{await Promise.race([g,v])}catch(y){clearTimeout(h),b.warn("WORKER","MCP server connection failed, cleaning up subprocess",{error:y instanceof Error?y.message:String(y)});try{await f.close()}catch{}throw y}clearTimeout(h);let _=f._process;_?.pid&&(Ft().registerProcess("mcp-server",{pid:_.pid,type:"mcp",startedAt:new Date().toISOString()},_),_.once("exit",()=>{Ft().unregisterProcess("mcp-server")})),this.mcpReady=!0,b.success("WORKER","MCP server connected"),this.stopOrphanReaper=B2(()=>{let y=new Set;for(let[x]of this.sessionManager.sessions)y.add(x);return y}),b.info("SYSTEM","Started orphan reaper (runs every 30 seconds)"),this.staleSessionReaperInterval=setInterval(async()=>{try{let y=await this.sessionManager.reapStaleSessions();y>0&&b.info("SYSTEM",`Reaped ${y} stale sessions`)}catch(y){b.error("SYSTEM","Stale session reaper error",{error:y instanceof Error?y.message:String(y)})}},120*1e3),this.processPendingQueues(50).then(y=>{y.sessionsStarted>0&&b.info("SYSTEM",`Auto-recovered ${y.sessionsStarted} sessions with pending work`,{totalPending:y.totalPendingSessions,started:y.sessionsStarted,sessionIds:y.startedSessionIds})}).catch(y=>{b.error("SYSTEM","Auto-recovery of pending queues failed",{},y)})}catch(e){throw b.error("SYSTEM","Background initialization failed",{},e),e}}getActiveAgent(){return Gc()&&Zo()?this.openRouterAgent:Vc()&&Fo()?this.geminiAgent:this.sdkAgent}startSessionProcessor(e,r){if(!e)return;let n=e.sessionDbId,i=this.getActiveAgent(),s=i.constructor.name;e.abortController.signal.aborted&&(b.debug("SYSTEM","Replacing aborted AbortController before starting generator",{sessionId:e.sessionDbId}),e.abortController=new AbortController);let o=!1,a=!1;b.info("SYSTEM",`Starting generator (${r}) using ${s}`,{sessionId:n}),e.lastGeneratorActivity=Date.now(),e.generatorPromise=i.startSession(e,this).catch(async c=>{let u=c?.message||"";if(["Claude executable not found","CLAUDE_CODE_PATH","ENOENT","spawn","Invalid API key","FOREIGN KEY constraint failed"].some(d=>u.includes(d))){o=!0,this.lastAiInteraction={timestamp:Date.now(),success:!1,provider:s,error:u},b.error("SDK","Unrecoverable generator error - will NOT restart",{sessionId:e.sessionDbId,project:e.project,errorMessage:u});return}if(this.isSessionTerminatedError(c))return b.warn("SDK","SDK resume failed, falling back to standalone processing",{sessionId:e.sessionDbId,project:e.project,reason:c instanceof Error?c.message:String(c)}),this.runFallbackForTerminatedSession(e,c);throw(u.includes("aborted by user")||u.includes("No conversation found"))&&e.memorySessionId&&(b.warn("SDK","Detected stale resume failure, clearing memorySessionId for fresh start",{sessionId:e.sessionDbId,memorySessionId:e.memorySessionId,errorMessage:u}),this.dbManager.getSessionStore().updateMemorySessionId(e.sessionDbId,null),e.memorySessionId=null,e.forceInit=!0),b.error("SDK","Session generator failed",{sessionId:e.sessionDbId,project:e.project,provider:s},c),a=!0,this.lastAiInteraction={timestamp:Date.now(),success:!1,provider:s,error:u},c}).finally(async()=>{let c=Ds(e.sessionDbId);if(c&&c.process.exitCode===null&&await zs(c,5e3),e.generatorPromise=null,!a&&!o&&(this.lastAiInteraction={timestamp:Date.now(),success:!0,provider:s}),o){b.warn("SYSTEM","Skipping restart due to unrecoverable error",{sessionId:e.sessionDbId}),this.broadcastProcessingStatus();return}let{PendingMessageStore:u}=(js(),Xc(Ao)),l=new u(this.dbManager.getSessionStore().db,3);if(e.idleTimedOut){b.info("SYSTEM","Generator exited due to idle timeout, not restarting",{sessionId:e.sessionDbId}),e.idleTimedOut=!1,this.broadcastProcessingStatus();return}let d=l.getPendingCount(e.sessionDbId),p=3;if(d>0){if(e.consecutiveRestarts=(e.consecutiveRestarts||0)+1,e.consecutiveRestarts>p){b.error("SYSTEM","Exceeded max pending-work restarts, stopping to prevent infinite loop",{sessionId:e.sessionDbId,pendingCount:d,consecutiveRestarts:e.consecutiveRestarts}),e.consecutiveRestarts=0,this.broadcastProcessingStatus();return}b.info("SYSTEM","Pending work remains after generator exit, restarting with fresh AbortController",{sessionId:e.sessionDbId,pendingCount:d,attempt:e.consecutiveRestarts}),e.abortController=new AbortController,this.startSessionProcessor(e,"pending-work-restart")}else e.consecutiveRestarts=0;this.broadcastProcessingStatus()})}isSessionTerminatedError(e){let n=(e instanceof Error?e.message:String(e)).toLowerCase();return n.includes("process aborted by user")||n.includes("processtransport")||n.includes("not ready for writing")||n.includes("session generator failed")||n.includes("claude code process")}async runFallbackForTerminatedSession(e,r){if(!e)return;let n=e.sessionDbId;if(!e.memorySessionId){let o=`fallback-${n}-${Date.now()}`;e.memorySessionId=o,this.dbManager.getSessionStore().updateMemorySessionId(n,o)}if(Fo())try{await this.geminiAgent.startSession(e,this);return}catch(o){b.warn("SDK","Fallback Gemini failed, trying OpenRouter",{sessionId:n,error:o instanceof Error?o.message:String(o)})}if(Zo())try{await this.openRouterAgent.startSession(e,this);return}catch(o){b.warn("SDK","Fallback OpenRouter failed",{sessionId:n,error:o instanceof Error?o.message:String(o)})}let s=this.sessionManager.getPendingMessageStore().markAllSessionMessagesAbandoned(n);s>0&&b.warn("SDK","No fallback available; marked pending messages abandoned",{sessionId:n,abandoned:s}),this.sessionManager.removeSessionImmediate(n),this.sessionEventBroadcaster.broadcastSessionCompleted(n)}async processPendingQueues(e=10){let{PendingMessageStore:r}=await Promise.resolve().then(()=>(js(),Ao)),n=new r(this.dbManager.getSessionStore().db,3),i=this.dbManager.getSessionStore(),s=360*60*1e3,o=Date.now()-s;try{let u=i.db.prepare(`
|
|
1595
|
+
`).all(i);n.json({summary:o,concepts:a})}};var Khe={},qhe=120*1e3;function m$(){return f$.default.join(Re.get("VIBELEARN_DATA_DIR"),".worker-start-attempted")}function Fhe(){if(process.platform!=="win32")return!1;let t=m$();if(!(0,os.existsSync)(t))return!1;try{let e=(0,os.statSync)(t).mtimeMs;return Date.now()-e<qhe}catch{return!1}}function Zhe(){if(process.platform==="win32")try{(0,os.writeFileSync)(m$(),"","utf-8")}catch{}}function Hhe(){if(process.platform==="win32")try{let t=m$();(0,os.existsSync)(t)&&(0,os.unlinkSync)(t)}catch{}}var Bhe="0.1.3";function Aq(t,e){return{continue:!0,suppressOutput:!0,status:t,...e&&{message:e}}}var av=class{server;startTime=Date.now();mcpClient;mcpReady=!1;initializationCompleteFlag=!1;isShuttingDown=!1;dbManager;sessionManager;sseBroadcaster;sdkAgent;geminiAgent;openRouterAgent;paginationHelper;settingsManager;sessionEventBroadcaster;searchRoutes=null;initializationComplete;resolveInitialization;stopOrphanReaper=null;staleSessionReaperInterval=null;lastAiInteraction=null;constructor(){this.initializationComplete=new Promise(e=>{this.resolveInitialization=e}),this.dbManager=new Kh,this.sessionManager=new Qh(this.dbManager),this.sseBroadcaster=new eg,this.sdkAgent=new Pg(this.dbManager,this.sessionManager),this.geminiAgent=new Cg(this.dbManager,this.sessionManager),this.openRouterAgent=new jg(this.dbManager,this.sessionManager),this.paginationHelper=new Dg(this.dbManager),this.settingsManager=new zg(this.dbManager),this.sessionEventBroadcaster=new qg(this.sseBroadcaster,this),this.sessionManager.setOnSessionDeleted(()=>{this.broadcastProcessingStatus()}),this.mcpClient=new xm({name:"worker-search-proxy",version:Bhe},{capabilities:{}}),this.server=new Hh({getInitializationComplete:()=>this.initializationCompleteFlag,getMcpReady:()=>this.mcpReady,onShutdown:()=>this.shutdown(),onRestart:()=>this.shutdown(),workerPath:__filename,getAiStatus:()=>{let e="claude";return Gc()&&Zo()?e="openrouter":Vc()&&Fo()&&(e="gemini"),{provider:e,authMethod:Om(),lastInteraction:this.lastAiInteraction?{timestamp:this.lastAiInteraction.timestamp,success:this.lastAiInteraction.success,...this.lastAiInteraction.error&&{error:this.lastAiInteraction.error}}:null}}}),this.registerRoutes(),this.registerSignalHandlers()}registerSignalHandlers(){JC(async()=>{this.isShuttingDown=!0,await this.shutdown()})}registerRoutes(){this.server.app.get("/api/context/inject",async(e,r,n)=>{if(!this.initializationCompleteFlag||!this.searchRoutes){b.warn("SYSTEM","Context requested before initialization complete, returning empty"),r.status(200).json({content:[{type:"text",text:""}]});return}n()}),this.server.app.use("/api",async(e,r,n)=>{if(this.initializationCompleteFlag){n();return}let i=3e4,s=new Promise((o,a)=>setTimeout(()=>a(new Error("Database initialization timeout")),i));try{await Promise.race([this.initializationComplete,s]),n()}catch(o){b.error("HTTP",`Request to ${e.method} ${e.path} rejected \u2014 DB not initialized`,{},o),r.status(503).json({error:"Service initializing",message:"Database is still initializing, please retry"})}}),this.server.registerRoutes(new Zg(this.sseBroadcaster,this.dbManager,this.sessionManager)),this.server.registerRoutes(new Vg(this.sessionManager,this.dbManager,this.sdkAgent,this.geminiAgent,this.openRouterAgent,this.sessionEventBroadcaster,this)),this.server.registerRoutes(new Gg(this.paginationHelper,this.dbManager,this.sessionManager,this.sseBroadcaster,this,this.startTime)),this.server.registerRoutes(new Xg(this.settingsManager)),this.server.registerRoutes(new Qg),this.server.registerRoutes(new ev(this.dbManager,"vibelearn")),this.server.registerRoutes(new iv(this.dbManager))}async start(){let e=dn(),r=y0();await WC(),await this.server.listen(e,r),nN({pid:process.pid,port:e,startedAt:new Date().toISOString()}),Ft().registerProcess("worker",{pid:process.pid,type:"worker",startedAt:new Date().toISOString()}),b.info("SYSTEM","Worker started",{host:r,port:e,pid:process.pid}),this.initializeBackground().catch(n=>{b.error("SYSTEM","Background initialization failed",{},n)})}async initializeBackground(){try{await iN();let{ModeManager:e}=await Promise.resolve().then(()=>(Xn(),G2)),{SettingsDefaultsManager:r}=await Promise.resolve().then(()=>(kr(),wC)),{USER_SETTINGS_PATH:n}=await Promise.resolve().then(()=>(qt(),PC)),i=r.loadFromFile(n),s="code";e.getInstance().loadMode(s),b.info("SYSTEM",`Mode loaded: ${s}`),await this.dbManager.initialize();let{PendingMessageStore:o}=await Promise.resolve().then(()=>(js(),Ao)),c=new o(this.dbManager.getSessionStore().db,3).resetStaleProcessingMessages(0);c>0&&b.info("SYSTEM",`Reset ${c} stale processing messages to pending`);let u=new Lg,l=new Ug,d=new Mg(this.dbManager.getSessionSearch(),this.dbManager.getSessionStore(),this.dbManager.getChromaSync(),u,l);this.searchRoutes=new Wg(d),this.server.registerRoutes(this.searchRoutes),b.info("WORKER","SearchManager initialized and search routes registered"),this.initializationCompleteFlag=!0,this.resolveInitialization(),b.info("SYSTEM","Core initialization complete (DB + search ready)");let p=f$.default.join(__dirname,"mcp-server.cjs");Ft().assertCanSpawn("mcp server");let f=new Em({command:"node",args:[p],env:ks(process.env)}),m=3e5,g=this.mcpClient.connect(f),h,v=new Promise((y,x)=>{h=setTimeout(()=>x(new Error("MCP connection timeout after 5 minutes")),m)});try{await Promise.race([g,v])}catch(y){clearTimeout(h),b.warn("WORKER","MCP server connection failed, cleaning up subprocess",{error:y instanceof Error?y.message:String(y)});try{await f.close()}catch{}throw y}clearTimeout(h);let _=f._process;_?.pid&&(Ft().registerProcess("mcp-server",{pid:_.pid,type:"mcp",startedAt:new Date().toISOString()},_),_.once("exit",()=>{Ft().unregisterProcess("mcp-server")})),this.mcpReady=!0,b.success("WORKER","MCP server connected"),this.stopOrphanReaper=B2(()=>{let y=new Set;for(let[x]of this.sessionManager.sessions)y.add(x);return y}),b.info("SYSTEM","Started orphan reaper (runs every 30 seconds)"),this.staleSessionReaperInterval=setInterval(async()=>{try{let y=await this.sessionManager.reapStaleSessions();y>0&&b.info("SYSTEM",`Reaped ${y} stale sessions`)}catch(y){b.error("SYSTEM","Stale session reaper error",{error:y instanceof Error?y.message:String(y)})}},120*1e3),this.processPendingQueues(50).then(y=>{y.sessionsStarted>0&&b.info("SYSTEM",`Auto-recovered ${y.sessionsStarted} sessions with pending work`,{totalPending:y.totalPendingSessions,started:y.sessionsStarted,sessionIds:y.startedSessionIds})}).catch(y=>{b.error("SYSTEM","Auto-recovery of pending queues failed",{},y)})}catch(e){throw b.error("SYSTEM","Background initialization failed",{},e),e}}getActiveAgent(){return Gc()&&Zo()?this.openRouterAgent:Vc()&&Fo()?this.geminiAgent:this.sdkAgent}startSessionProcessor(e,r){if(!e)return;let n=e.sessionDbId,i=this.getActiveAgent(),s=i.constructor.name;e.abortController.signal.aborted&&(b.debug("SYSTEM","Replacing aborted AbortController before starting generator",{sessionId:e.sessionDbId}),e.abortController=new AbortController);let o=!1,a=!1;b.info("SYSTEM",`Starting generator (${r}) using ${s}`,{sessionId:n}),e.lastGeneratorActivity=Date.now(),e.generatorPromise=i.startSession(e,this).catch(async c=>{let u=c?.message||"";if(["Claude executable not found","CLAUDE_CODE_PATH","ENOENT","spawn","Invalid API key","FOREIGN KEY constraint failed"].some(d=>u.includes(d))){o=!0,this.lastAiInteraction={timestamp:Date.now(),success:!1,provider:s,error:u},b.error("SDK","Unrecoverable generator error - will NOT restart",{sessionId:e.sessionDbId,project:e.project,errorMessage:u});return}if(this.isSessionTerminatedError(c))return b.warn("SDK","SDK resume failed, falling back to standalone processing",{sessionId:e.sessionDbId,project:e.project,reason:c instanceof Error?c.message:String(c)}),this.runFallbackForTerminatedSession(e,c);throw(u.includes("aborted by user")||u.includes("No conversation found"))&&e.memorySessionId&&(b.warn("SDK","Detected stale resume failure, clearing memorySessionId for fresh start",{sessionId:e.sessionDbId,memorySessionId:e.memorySessionId,errorMessage:u}),this.dbManager.getSessionStore().updateMemorySessionId(e.sessionDbId,null),e.memorySessionId=null,e.forceInit=!0),b.error("SDK","Session generator failed",{sessionId:e.sessionDbId,project:e.project,provider:s},c),a=!0,this.lastAiInteraction={timestamp:Date.now(),success:!1,provider:s,error:u},c}).finally(async()=>{let c=Ds(e.sessionDbId);if(c&&c.process.exitCode===null&&await zs(c,5e3),e.generatorPromise=null,!a&&!o&&(this.lastAiInteraction={timestamp:Date.now(),success:!0,provider:s}),o){b.warn("SYSTEM","Skipping restart due to unrecoverable error",{sessionId:e.sessionDbId}),this.broadcastProcessingStatus();return}let{PendingMessageStore:u}=(js(),Xc(Ao)),l=new u(this.dbManager.getSessionStore().db,3);if(e.idleTimedOut){b.info("SYSTEM","Generator exited due to idle timeout, not restarting",{sessionId:e.sessionDbId}),e.idleTimedOut=!1,this.broadcastProcessingStatus();return}let d=l.getPendingCount(e.sessionDbId),p=3;if(d>0){if(e.consecutiveRestarts=(e.consecutiveRestarts||0)+1,e.consecutiveRestarts>p){b.error("SYSTEM","Exceeded max pending-work restarts, stopping to prevent infinite loop",{sessionId:e.sessionDbId,pendingCount:d,consecutiveRestarts:e.consecutiveRestarts}),e.consecutiveRestarts=0,this.broadcastProcessingStatus();return}b.info("SYSTEM","Pending work remains after generator exit, restarting with fresh AbortController",{sessionId:e.sessionDbId,pendingCount:d,attempt:e.consecutiveRestarts}),e.abortController=new AbortController,this.startSessionProcessor(e,"pending-work-restart")}else e.consecutiveRestarts=0;this.broadcastProcessingStatus()})}isSessionTerminatedError(e){let n=(e instanceof Error?e.message:String(e)).toLowerCase();return n.includes("process aborted by user")||n.includes("processtransport")||n.includes("not ready for writing")||n.includes("session generator failed")||n.includes("claude code process")}async runFallbackForTerminatedSession(e,r){if(!e)return;let n=e.sessionDbId;if(!e.memorySessionId){let o=`fallback-${n}-${Date.now()}`;e.memorySessionId=o,this.dbManager.getSessionStore().updateMemorySessionId(n,o)}if(Fo())try{await this.geminiAgent.startSession(e,this);return}catch(o){b.warn("SDK","Fallback Gemini failed, trying OpenRouter",{sessionId:n,error:o instanceof Error?o.message:String(o)})}if(Zo())try{await this.openRouterAgent.startSession(e,this);return}catch(o){b.warn("SDK","Fallback OpenRouter failed",{sessionId:n,error:o instanceof Error?o.message:String(o)})}let s=this.sessionManager.getPendingMessageStore().markAllSessionMessagesAbandoned(n);s>0&&b.warn("SDK","No fallback available; marked pending messages abandoned",{sessionId:n,abandoned:s}),this.sessionManager.removeSessionImmediate(n),this.sessionEventBroadcaster.broadcastSessionCompleted(n)}async processPendingQueues(e=10){let{PendingMessageStore:r}=await Promise.resolve().then(()=>(js(),Ao)),n=new r(this.dbManager.getSessionStore().db,3),i=this.dbManager.getSessionStore(),s=360*60*1e3,o=Date.now()-s;try{let u=i.db.prepare(`
|
|
1596
1596
|
SELECT id FROM sdk_sessions
|
|
1597
1597
|
WHERE status = 'active' AND started_at_epoch < ?
|
|
1598
1598
|
`).all(o);if(u.length>0){let l=u.map(f=>f.id),d=l.map(()=>"?").join(",");i.db.prepare(`
|