@anmol-srv/sigil 0.10.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.
Files changed (49) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +417 -0
  3. package/dist/cli.js +1019 -0
  4. package/dist/hooks/post-tool-use.js +70 -0
  5. package/dist/hooks/session-end.js +222 -0
  6. package/dist/hooks/stop.js +259 -0
  7. package/dist/hooks/user-prompt-submit.js +279 -0
  8. package/dist/server.js +573 -0
  9. package/integrations/hermes/README.md +41 -0
  10. package/integrations/hermes/plugin/README.md +72 -0
  11. package/integrations/hermes/plugin/__init__.py +353 -0
  12. package/integrations/hermes/plugin/plugin.yaml +10 -0
  13. package/knexfile.js +15 -0
  14. package/package.json +100 -0
  15. package/prompts/audm-decision.md +31 -0
  16. package/prompts/chunk-context.md +23 -0
  17. package/prompts/default-extraction.md +35 -0
  18. package/prompts/entity-extraction.md +37 -0
  19. package/prompts/input-classifier.md +23 -0
  20. package/prompts/query-router.md +18 -0
  21. package/src/db/migrations/20260310120000_create-cortex-document-table.cjs +21 -0
  22. package/src/db/migrations/20260310120001_create-cortex-chunk-table.cjs +37 -0
  23. package/src/db/migrations/20260310120002_create-cortex-fact-table.cjs +37 -0
  24. package/src/db/migrations/20260310120003_create-cortex-entity-table.cjs +26 -0
  25. package/src/db/migrations/20260310120004_create-cortex-relation-table.cjs +27 -0
  26. package/src/db/migrations/20260310120005_create-cortex-history-table.cjs +16 -0
  27. package/src/db/migrations/20260311120000_add-entity-namespace-and-relation-indexes.cjs +32 -0
  28. package/src/db/migrations/20260312120000_add-fact-entity-linking.cjs +22 -0
  29. package/src/db/migrations/20260313093130_create-api-key-table.cjs +15 -0
  30. package/src/db/migrations/20260313120000_add-entity-dedup-support.cjs +13 -0
  31. package/src/db/migrations/20260313150000_create-connector-tables.cjs +46 -0
  32. package/src/db/migrations/20260318120000_add-contextual-chunk-prefix.cjs +11 -0
  33. package/src/db/migrations/20260318120001_add-fact-temporal-validity.cjs +15 -0
  34. package/src/db/migrations/20260318120002_add-fact-importance.cjs +11 -0
  35. package/src/db/migrations/20260318120003_add-fact-access-tracking.cjs +13 -0
  36. package/src/db/migrations/20260405120000_add-unique-constraints.cjs +58 -0
  37. package/src/db/migrations/20260405140000_create-llm-log-table.cjs +21 -0
  38. package/src/db/migrations/20260424120000_split-fact-lifecycle.cjs +86 -0
  39. package/src/db/migrations/20260424120002_create-embedding-cache.cjs +26 -0
  40. package/src/db/migrations/20260429120000_halfvec-index-compression.cjs +34 -0
  41. package/src/db/migrations/20260429120100_create-hebbian-edge-table.cjs +37 -0
  42. package/src/db/migrations/20260429120200_upgrade-embedding-dim-1024.cjs +68 -0
  43. package/src/db/migrations/20260504120000_scope-document-source-path-uniqueness.cjs +45 -0
  44. package/src/db/migrations/20260508001733_add-entity-aliases.cjs +42 -0
  45. package/src/db/migrations/20260512120000_create-entity-hebbian-edge.cjs +42 -0
  46. package/src/db/migrations/20260512120000_create-pod-tables.cjs +71 -0
  47. package/src/db/migrations/20260512120100_create-pod-membership.cjs +50 -0
  48. package/src/db/migrations/20260512120200_add-document-source-metadata.cjs +32 -0
  49. package/src/db/migrations/20260514023428_rewrite-session-pods-and-add-fact-attribution-columns.cjs +86 -0
@@ -0,0 +1,279 @@
1
+ #!/usr/bin/env node
2
+ var sr=Object.defineProperty;var f=(e,t)=>()=>(e&&(t=e(e=0)),t);var I=(e,t)=>{for(var n in t)sr(e,n,{get:t[n],enumerable:!0})};import{fileURLToPath as mr}from"node:url";import{dirname as et,join as O}from"node:path";import{existsSync as tt}from"node:fs";import{homedir as fr}from"node:os";function hr(){let e=et(mr(import.meta.url));for(let t=0;t<10;t++){if(tt(O(e,"package.json"))&&tt(O(e,"prompts")))return e;let n=et(e);if(n===e)break;e=n}return process.cwd()}var nt,Z,qi,rt,C,Q,zi,Xi,Er,ot,_r,it,Zi,Qi,at,ea,ta,P=f(()=>{nt=hr(),Z=O(nt,"prompts"),qi=O(nt,"src","db","migrations"),rt=fr(),C=O(rt,".sigil"),Q=O(C,".env"),zi=O(C,"db"),Xi=O(C,"CLAUDE.md"),Er=O(C,"schemas"),ot=O(C,".hook-errors.log"),_r=O(C,".last-clean-doctor"),it=O(C,".active-session.json"),Zi=O(C,".stop-cursor.json"),Qi=O(C,".hook-dedup.json"),at=O(rt,".claude"),ea=O(at,"settings.json"),ta=O(at,"CLAUDE.md")});var ct={};I(ct,{default:()=>c});var T,st,yr,c,g=f(()=>{T=(e,t)=>process.env[e]??t,st=T("SIGIL_DB_TYPE","postgres");if(st!=="postgres")throw new Error(`SIGIL_DB_TYPE=${st} is no longer supported. Sigil 0.10.0+ is Postgres-only.
3
+ PGlite was deprecated; existing PGlite data at ~/.sigil/db is preserved but unreachable from this version.
4
+ Set SIGIL_DB_TYPE=postgres in ~/.sigil/.env and configure SIGIL_DB_HOST / PORT / NAME / USER / PASSWORD.
5
+ Run \`sigil init\` for an interactive setup.`);yr={db:{type:"postgres",host:T("SIGIL_DB_HOST","localhost"),port:Number(T("SIGIL_DB_PORT",5432)),database:T("SIGIL_DB_NAME","sigil"),user:T("SIGIL_DB_USER","sigil_app"),password:T("SIGIL_DB_PASSWORD","")},embedding:{provider:process.env.EMBEDDING_PROVIDER||"",model:process.env.EMBEDDING_MODEL||"nomic-embed-text",dimensions:Number(process.env.EMBEDDING_DIMENSIONS)||768,ollamaHost:process.env.OLLAMA_HOST||"http://localhost:11434",openaiApiKey:process.env.OPENAI_API_KEY||"",voyageApiKey:process.env.VOYAGE_API_KEY||"",openrouterApiKey:process.env.OPENROUTER_API_KEY||"",openrouterBaseUrl:process.env.EMBEDDING_OPENROUTER_BASE_URL||process.env.LLM_OPENROUTER_BASE_URL||"",openrouterReferer:process.env.EMBEDDING_OPENROUTER_REFERER||process.env.LLM_OPENROUTER_REFERER||"https://github.com/Anmol-Srv/sigil",openrouterTitle:process.env.EMBEDDING_OPENROUTER_TITLE||process.env.LLM_OPENROUTER_TITLE||"Sigil"},llm:{provider:process.env.LLM_PROVIDER||"",openaiApiKey:process.env.OPENAI_API_KEY||"",openaiModel:process.env.LLM_OPENAI_MODEL||"gpt-4o-mini",ollamaHost:process.env.LLM_OLLAMA_HOST||process.env.OLLAMA_HOST||"http://localhost:11434",ollamaModel:process.env.LLM_OLLAMA_MODEL||"qwen2.5:7b",cliModel:process.env.LLM_CLI_MODEL||"haiku",apiKey:process.env.ANTHROPIC_API_KEY||"",openrouterApiKey:process.env.OPENROUTER_API_KEY||"",openrouterModel:process.env.LLM_OPENROUTER_MODEL||"google/gemini-flash-latest",openrouterBaseUrl:process.env.LLM_OPENROUTER_BASE_URL||"",openrouterReferer:process.env.LLM_OPENROUTER_REFERER||"https://github.com/Anmol-Srv/sigil",openrouterTitle:process.env.LLM_OPENROUTER_TITLE||"Sigil",extractionModel:process.env.LLM_EXTRACTION_MODEL||"",decisionModel:process.env.LLM_DECISION_MODEL||"",entityModel:process.env.LLM_ENTITY_MODEL||"",maxRetries:Number(process.env.LLM_MAX_RETRIES)||3,cliTimeout:Number(process.env.LLM_CLI_TIMEOUT)||12e4},output:{storage:process.env.OUTPUT_STORAGE||"local",dir:process.env.OUTPUT_DIR||"./output",s3:{endpoint:process.env.S3_ENDPOINT||"",bucket:process.env.S3_BUCKET||"",region:process.env.S3_REGION||"us-east-1",accessKey:process.env.S3_ACCESS_KEY||"",secretKey:process.env.S3_SECRET_KEY||"",publicUrl:process.env.S3_PUBLIC_URL||""}},server:{port:Number(process.env.PORT)||4e3,host:process.env.HOST||"0.0.0.0",logLevel:process.env.LOG_LEVEL||"info"},defaults:{namespace:process.env.DEFAULT_NAMESPACE||"default"},memory:{skipThreshold:Number(process.env.MEMORY_SKIP_THRESHOLD)||.88,ambiguousThreshold:Number(process.env.MEMORY_AMBIGUOUS_THRESHOLD)||.78,minFactSimilarity:Number(process.env.MEMORY_MIN_FACT_SIMILARITY)||.45},search:{synthesize:T("SIGIL_SYNTHESIZE","true")!=="false",synthesizeModel:T("SIGIL_SYNTH_MODEL","")},ingest:{eagerExtract:T("SIGIL_EAGER_EXTRACT","true")!=="false"},hebbian:{entity:{enabled:T("SIGIL_HEBBIAN_ENTITY_ENABLED",null,"true")!=="false",eta:Number(T("SIGIL_HEBBIAN_ENTITY_ETA",null,1)),cap:Number(T("SIGIL_HEBBIAN_ENTITY_CAP",null,50)),halfLifeDays:Number(T("SIGIL_HEBBIAN_ENTITY_HALF_LIFE_DAYS",null,30)),minEffective:Number(T("SIGIL_HEBBIAN_ENTITY_MIN_EFFECTIVE",null,.5)),rrfWeight:Number(T("SIGIL_HEBBIAN_ENTITY_RRF_WEIGHT",null,.3)),maxWriteEntities:Number(T("SIGIL_HEBBIAN_ENTITY_MAX_WRITE",null,12)),expandPerSeed:Number(T("SIGIL_HEBBIAN_ENTITY_EXPAND_PER_SEED",null,3))}}},c=yr});var W={};I(W,{default:()=>p});import gr from"knex";function Sr(e){return Array.isArray(e)?e.map(we):e&&typeof e=="object"?we(e):e}function Ar(e,t){return t(br(e))}function we(e){if(!e||typeof e!="object"||e instanceof Date)return e;if(Array.isArray(e))return e.map(we);let t={};for(let[n,r]of Object.entries(e))t[n.replace(/_([a-z])/g,(o,i)=>i.toUpperCase())]=r;return t}function br(e){return e.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}var wr,p,A=f(()=>{g();wr=gr({client:"pg",connection:{host:c.db.host,port:c.db.port,database:c.db.database,user:c.db.user,password:c.db.password},pool:{min:2,max:10},postProcessResponse:Sr,wrapIdentifier:Ar});p=wr});var mt={};I(mt,{validateConfig:()=>pt,validateConfigDeep:()=>Ir});function pt(){let e=[];return Or(e),Tr(e),Nr(e),e}async function Ir(){let e=pt();if(c.db.type==="postgres"&&!e.some(t=>t.code.startsWith("DB_")))try{await(await Promise.resolve().then(()=>(A(),W))).default.raw("SELECT 1")}catch(t){e.push({level:"fail",code:"DB_UNREACHABLE",message:`Postgres at ${c.db.host}:${c.db.port}/${c.db.database} unreachable: ${t.message.split(`
6
+ `)[0]}`,fix:"Start Postgres (e.g. `docker start sigil-pg` or your equivalent) and verify SIGIL_DB_HOST/PORT/NAME/USER/PASSWORD in ~/.sigil/.env"})}return e}function Or(e){let{provider:t,model:n}=c.embedding;if(t&&n){let r=Object.keys(lt).find(o=>lt[o].some(i=>i.test(n)));r&&r!==t&&e.push({level:"fail",code:"EMBEDDING_PROVIDER_MODEL_MISMATCH",message:`EMBEDDING_PROVIDER=${t} but EMBEDDING_MODEL=${n} is a ${r} model.`,fix:Rr(t,n,r)})}if(t&&dt[t]){let r=dt[t];c.embedding[r]||e.push({level:"fail",code:"EMBEDDING_PROVIDER_MISSING_KEY",message:`EMBEDDING_PROVIDER=${t} but no ${ee(r)} found.`,fix:`Set ${ee(r)} in ~/.sigil/.env, or run 'sigil init' to reconfigure.`})}}function Tr(e){let{provider:t}=c.llm;if(t&&ut[t]){let n=ut[t];c.llm[n]||e.push({level:"fail",code:"LLM_PROVIDER_MISSING_KEY",message:`LLM_PROVIDER=${t} but no ${ee(n)} found.`,fix:`Set ${ee(n)} in ~/.sigil/.env, or run 'sigil init' to reconfigure.`})}t==="openrouter"&&c.llm.openrouterModel&&(c.llm.openrouterModel.includes("/")||e.push({level:"warn",code:"OPENROUTER_MODEL_FORMAT",message:`LLM_OPENROUTER_MODEL=${c.llm.openrouterModel} doesn't look like vendor/model format.`,fix:'Use format like "anthropic/claude-haiku-4-5" or "google/gemini-2.5-flash".'}))}function Nr(e){c.db.type==="postgres"&&(!c.db.host||!c.db.database||!c.db.user)&&e.push({level:"fail",code:"DB_CONFIG_INCOMPLETE",message:"SIGIL_DB_TYPE=postgres but host/database/user missing.",fix:"Set SIGIL_DB_HOST, SIGIL_DB_NAME, SIGIL_DB_USER, SIGIL_DB_PASSWORD in ~/.sigil/.env. Run `sigil init` for an interactive setup."})}function ee(e){return{openaiApiKey:"OPENAI_API_KEY",apiKey:"ANTHROPIC_API_KEY",openrouterApiKey:"OPENROUTER_API_KEY",voyageApiKey:"VOYAGE_API_KEY"}[e]||e}function Rr(e,t,n){let r={voyage:"voyage-3.5, voyage-3-large, voyage-code-3.5",openai:"text-embedding-3-large, text-embedding-3-small",ollama:"nomic-embed-text, mxbai-embed-large"}[e]||"(see provider docs)";return`Either set EMBEDDING_PROVIDER=${n} (matches your current model), or change EMBEDDING_MODEL to one of: ${r}`}var lt,ut,dt,ft=f(()=>{g();lt={voyage:[/^voyage-/],openai:[/^text-embedding-/],ollama:[/^nomic-embed/,/^mxbai-embed/,/^all-minilm/,/^bge-/,/^snowflake-/,/^granite-embedding/]},ut={openai:"openaiApiKey",anthropic:"apiKey",openrouter:"openrouterApiKey"},dt={openai:"openaiApiKey",voyage:"voyageApiKey",openrouter:"openrouterApiKey"}});function Ae(e,t){let n={};for(let r of e)n[r[t]]=r;return n}function te(e,t){if(t<1)return[];let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}var ne=f(()=>{});var gt={};I(gt,{chat:()=>Mr,meta:()=>xr,setup:()=>kr});async function Mr(e,{model:t,jsonMode:n=!1}={}){let r=t||c.llm.openaiModel,o=[{role:"user",content:e}];n&&!e.toLowerCase().includes("json")&&o.unshift({role:"system",content:"Respond with valid JSON."});let i={model:r,messages:o};n&&(i.response_format={type:"json_object"});let s=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c.llm.openaiApiKey}`},body:JSON.stringify(i)});if(!s.ok){let h=await s.text();throw new Error(`OpenAI error ${s.status}: ${h}`)}let a=await s.json(),l=a.choices[0].message.content.trim(),u=a.usage||{};return{text:l,inputTokens:u.prompt_tokens||0,outputTokens:u.completion_tokens||0,model:r}}async function kr({existing:e,clack:t}){let n=e.OPENAI_API_KEY||"",r=await t.text({message:"OpenAI API key (paste, then Enter)",placeholder:n?"(keep existing \u2014 press Enter)":"sk-proj-...",validate:o=>{if(!o&&!n)return"API key is required";if(o&&!o.startsWith("sk-"))return'OpenAI keys start with "sk-" \u2014 check paste'}});return t.isCancel(r)?null:{env:{OPENAI_API_KEY:r||n}}}var xr,wt=f(()=>{g();xr={id:"openai",label:"OpenAI",hint:"gpt-4o-mini"}});function v(e){return Math.ceil((e||"").length/4)}function be(e,t,n){let r=Fr[e];return r?(t*r.input+n*r.output)/1e6:0}function K({provider:e,model:t,caller:n,input:r,response:o,inputTokens:i,outputTokens:s,cost:a,durationMs:l,status:u,error:h}){p("llm_log").insert({provider:e,model:t,caller:n,input:r?.slice(0,1e4),response:o?.slice(0,1e4),inputTokens:i,outputTokens:s,cost:a,durationMs:l,status:u,error:h?.slice(0,2e3)}).catch(E=>console.error("[llm-log] Write failed:",E.message))}async function Ie(e,t=3){for(let n=1;n<=t;n++)try{return await e()}catch(r){if(n===t)throw r;let o=Math.min(1e3*2**(n-1),1e4);await new Promise(i=>setTimeout(i,o))}}var Fr,j=f(()=>{A();Fr={"gpt-4o-mini":{input:.15,output:.6},"gpt-4o":{input:2.5,output:10},"gpt-4.1-nano":{input:.1,output:.4},"gpt-4.1-mini":{input:.4,output:1.6},"claude-haiku-4-5-20251001":{input:.8,output:4},"claude-sonnet-4-6":{input:3,output:15},"claude-opus-4-6":{input:15,output:75}}});var St={};I(St,{chat:()=>Hr,meta:()=>$r,setup:()=>Ur});async function Br(){if(!Oe){let{default:e}=await import("@anthropic-ai/sdk");Oe=new e({apiKey:c.llm.apiKey})}return Oe}async function Hr(e,{model:t,jsonMode:n=!1}={}){let r=t||"claude-haiku-4-5-20251001",o=await Br(),i=[{role:"user",content:e}],s=n?"Respond with valid JSON only. No explanation or wrapping.":void 0,a=await o.messages.create({model:r,max_tokens:4096,messages:i,...s&&{system:s}});return{text:a.content[0].text.trim(),inputTokens:a.usage?.input_tokens||v(e),outputTokens:a.usage?.output_tokens||v(a.content[0].text),model:r}}async function Ur({existing:e,clack:t}){let n=e.ANTHROPIC_API_KEY||"",r=await t.text({message:"Anthropic API key (paste, then Enter)",placeholder:n?"(keep existing \u2014 press Enter)":"sk-ant-...",validate:o=>{if(!o&&!n)return"API key is required";if(o&&!o.startsWith("sk-ant-"))return'Anthropic keys start with "sk-ant-" \u2014 check paste'}});return t.isCancel(r)?null:{env:{ANTHROPIC_API_KEY:r||n}}}var Oe,$r,At=f(()=>{g();j();Oe=null;$r={id:"anthropic",label:"Anthropic",hint:"Claude Haiku \u2014 requires API key"}});var It={};I(It,{chat:()=>Yr,meta:()=>Wr,setup:()=>Kr});async function Yr(e,{model:t,jsonMode:n=!1}={}){let r=t||c.llm.openrouterModel;if(!c.llm.openrouterApiKey)throw new Error("OPENROUTER_API_KEY is not set");if(!r)throw new Error("No OpenRouter model resolved. Set LLM_OPENROUTER_MODEL or pass `model`.");let o=[{role:"user",content:e}];n&&!e.toLowerCase().includes("json")&&o.unshift({role:"system",content:"Respond with valid JSON."});let i={model:r,messages:o};n&&(i.response_format={type:"json_object"});let s=(c.llm.openrouterBaseUrl||Gr).replace(/\/+$/,""),a={"Content-Type":"application/json",Authorization:`Bearer ${c.llm.openrouterApiKey}`};c.llm.openrouterReferer&&(a["HTTP-Referer"]=c.llm.openrouterReferer),c.llm.openrouterTitle&&(a["X-Title"]=c.llm.openrouterTitle);let l=await fetch(`${s}/chat/completions`,{method:"POST",headers:a,body:JSON.stringify(i)});if(!l.ok){let d=await l.text();throw new Error(`OpenRouter error ${l.status}: ${d}`)}let u=await l.json(),E=(u.choices?.[0]?.message?.content||"").trim(),m=u.usage||{};return{text:E,inputTokens:m.prompt_tokens||0,outputTokens:m.completion_tokens||0,model:u.model||r}}async function Kr({existing:e,clack:t}){let n={},r=e.OPENROUTER_API_KEY||"",o=await t.text({message:"OpenRouter API key (paste, then Enter)",placeholder:r?"(keep existing \u2014 press Enter)":"sk-or-v1-...",validate:l=>{if(!l&&!r)return"API key is required";if(l&&!l.startsWith("sk-or-"))return'OpenRouter keys start with "sk-or-" \u2014 check paste'}});if(t.isCancel(o))return null;n.OPENROUTER_API_KEY=o||r;let i=e.LLM_OPENROUTER_MODEL||"",s=await t.text({message:"OpenRouter model (vendor/model)",placeholder:i||bt,validate:l=>{if(l&&!l.includes("/"))return'OpenRouter models are "vendor/model" \u2014 e.g. google/gemini-flash-latest'}});if(t.isCancel(s))return null;n.LLM_OPENROUTER_MODEL=s||i||bt;let a=await t.select({message:"Configure per-task model overrides? (advanced \u2014 better quality / cost)",options:[{value:"no",label:"No, use one model everywhere",hint:"simpler \u2014 debug one model"},{value:"yes",label:"Yes, configure smart split",hint:"~5\xD7 cheaper extraction + better AUDM/synthesis"}],initialValue:"no"});if(t.isCancel(a))return null;if(a==="yes"){let l=await t.text({message:"Extraction model (high-volume; cheap matters)",placeholder:e.LLM_EXTRACTION_MODEL||x.extraction});if(t.isCancel(l))return null;n.LLM_EXTRACTION_MODEL=l||e.LLM_EXTRACTION_MODEL||x.extraction;let u=await t.text({message:"Decision model (AUDM; smart matters)",placeholder:e.LLM_DECISION_MODEL||x.decision});if(t.isCancel(u))return null;n.LLM_DECISION_MODEL=u||e.LLM_DECISION_MODEL||x.decision;let h=await t.text({message:"Synthesis model (read-time answer composition)",placeholder:e.SIGIL_SYNTH_MODEL||x.synthesis});if(t.isCancel(h))return null;n.SIGIL_SYNTH_MODEL=h||e.SIGIL_SYNTH_MODEL||x.synthesis}return t.note(`OpenRouter can drive both LLM calls and embeddings.
7
+ You will pick an embedding provider in the next step \u2014 "openrouter" is an option,
8
+ or you can use a direct provider (Ollama / OpenAI / Voyage) for embeddings.`,"OpenRouter scope"),{env:n}}var Gr,Wr,bt,x,Ot=f(()=>{g();Gr="https://openrouter.ai/api/v1";Wr={id:"openrouter",label:"OpenRouter",hint:"one key, many models (Anthropic / OpenAI / Meta / ...)"},bt="google/gemini-flash-latest",x={extraction:"openrouter:qwen/qwen3.5-flash",decision:"openrouter:anthropic/claude-sonnet-latest",synthesis:"openrouter:anthropic/claude-sonnet-latest"}});var Tt={};I(Tt,{chat:()=>zr,meta:()=>Xr,setup:()=>Zr});import{spawn as jr}from"node:child_process";function qr(e,t){let n=c.llm.cliTimeout||12e4;return new Promise((r,o)=>{let i=jr("claude",e,{stdio:["pipe","pipe","pipe"]}),s=setTimeout(()=>{i.kill("SIGTERM"),o(new Error(`claude CLI timed out after ${n}ms`))},n),a="",l="";i.stdout.on("data",u=>{a+=u}),i.stderr.on("data",u=>{l+=u}),i.on("error",u=>{clearTimeout(s),o(new Error(`Failed to spawn claude CLI: ${u.message}`))}),i.on("close",u=>{clearTimeout(s),r({stdout:a,stderr:l,code:u})}),i.stdin.write(t),i.stdin.end()})}async function zr(e,{model:t,jsonMode:n=!1}={}){let r=t||c.llm.cliModel||"haiku",o=Vr[r]||r,i=["-p","--model",o,"--output-format","json"];n&&i.push("--json-schema",Jr);let{stdout:s,stderr:a,code:l}=await qr(i,e);if(l!==0)throw new Error(`claude CLI exited ${l}: ${(a||s).slice(0,500)}`);let u;try{u=JSON.parse(s)}catch{return{text:s.trim(),inputTokens:v(e),outputTokens:v(s),model:o}}if(u.is_error)throw new Error(`claude CLI error: ${u.result||"unknown error"}`);let h=n&&u.structured_output?JSON.stringify(u.structured_output):(u.result||"").trim(),E=u.usage||{};return{text:h,inputTokens:E.input_tokens||v(e),outputTokens:E.output_tokens||v(h),model:o,cost:u.total_cost_usd||0}}async function Zr(){return{env:{}}}var Vr,Jr,Xr,Nt=f(()=>{g();j();Vr={"claude-haiku-4-5-20251001":"haiku","claude-sonnet-4-6":"sonnet","claude-opus-4-6":"opus"},Jr=JSON.stringify({type:"object",additionalProperties:!0});Xr={id:"claude-cli",label:"Claude Code",hint:"uses your existing subscription \u2014 no extra API key"}});var Rt={};I(Rt,{chat:()=>Qr,meta:()=>eo,setup:()=>to});async function Qr(e,{model:t,jsonMode:n=!1}={}){let r=t||c.llm.ollamaModel,o=`${c.llm.ollamaHost}/api/chat`,i={model:r,messages:[{role:"user",content:e}],stream:!1};n&&(i.format="json");let s=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!s.ok){let l=await s.text();throw new Error(`Ollama error ${s.status}: ${l}`)}let a=await s.json();return{text:a.message.content.trim(),inputTokens:a.prompt_eval_count||v(e),outputTokens:a.eval_count||v(a.message.content),model:r}}async function to({existing:e,clack:t}){let n=e.OLLAMA_HOST||"http://localhost:11434",r=await t.text({message:"Ollama host",placeholder:n,initialValue:n,validate:o=>{if(o&&!/^https?:\/\//.test(o))return"Must start with http:// or https://"}});return t.isCancel(r)?null:{env:{OLLAMA_HOST:r||n}}}var eo,Dt=f(()=>{g();j();eo={id:"ollama",label:"Ollama",hint:"local models \u2014 no API cost"}});var vt={};I(vt,{embedBatch:()=>ro});async function ro(e,{model:t,ollamaHost:n}){let r=te(e,no),o=[];for(let i of r){let s=await fetch(`${n}/api/embed`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:t,input:i})});if(!s.ok)throw new Error(`Ollama embed failed: ${s.status} ${await s.text()}`);let a=await s.json();o.push(...a.embeddings)}return o}var no,Ct=f(()=>{ne();no=50});var Lt={};I(Lt,{embedBatch:()=>oo});async function oo(e,{model:t,openaiApiKey:n,dimensions:r}={}){let o={model:t,input:e};r&&/^text-embedding-3/.test(t)&&(o.dimensions=r);let i=await fetch("https://api.openai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify(o)});if(!i.ok)throw new Error(`OpenAI embed failed: ${i.status} ${await i.text()}`);return(await i.json()).data.map(a=>a.embedding)}var Pt=f(()=>{});var Mt={};I(Mt,{embedBatch:()=>ao});async function ao(e,{model:t,voyageApiKey:n,inputType:r="document",dimensions:o}={}){if(!n)throw new Error("VOYAGE_API_KEY is not set. Get one at dashboard.voyageai.com.");let i=te(e,io),s=[];for(let a of i){let l={input:a,model:t||"voyage-3-large",input_type:r==="query"?"query":"document"};o&&(l.output_dimension=o);let u=await fetch("https://api.voyageai.com/v1/embeddings",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify(l)});if(!u.ok){let m=await u.text();throw new Error(`Voyage embed failed: ${u.status} ${m}`)}let E=[...(await u.json()).data].sort((m,d)=>m.index-d.index);s.push(...E.map(m=>m.embedding))}return s}var io,xt=f(()=>{ne();io=50});var kt={};I(kt,{embedBatch:()=>co});async function co(e,{model:t,openrouterApiKey:n,openrouterBaseUrl:r,openrouterReferer:o,openrouterTitle:i,dimensions:s}={}){if(!n)throw new Error("OPENROUTER_API_KEY is not set");if(!t)throw new Error('No OpenRouter embedding model resolved. Set EMBEDDING_MODEL (e.g. "openai/text-embedding-3-large").');let a={model:t,input:e};s&&/(^|\/)text-embedding-3/.test(t)&&(a.dimensions=s);let l=(r||so).replace(/\/+$/,""),u={"Content-Type":"application/json",Authorization:`Bearer ${n}`};o&&(u["HTTP-Referer"]=o),i&&(u["X-Title"]=i);let h=await fetch(`${l}/embeddings`,{method:"POST",headers:u,body:JSON.stringify(a)});if(!h.ok)throw new Error(`OpenRouter embed failed: ${h.status} ${await h.text()}`);return[...(await h.json()).data].sort((d,_)=>d.index-_.index).map(d=>d.embedding)}var so,Ft=f(()=>{so="https://openrouter.ai/api/v1"});import{spawn as lo}from"node:child_process";async function De(e){if(!Te[e]){let t=Re[e];if(!t)throw new Error(`Unknown LLM provider: "${e}". Available: ${Object.keys(Re).join(", ")}`);let n=await t();Te[e]=n.chat}return Te[e]}async function Ht(e){if(!Ne[e]){let t=Bt[e];if(!t)throw new Error(`Unknown embedding provider: "${e}". Available: ${Object.keys(Bt).join(", ")}`);let n=await t();Ne[e]=n.embedBatch}return Ne[e]}function $t(e,t){if(!e)return{provider:t,model:null};let n=e.indexOf(":");return n>0&&Re[e.slice(0,n)]?{provider:e.slice(0,n),model:e.slice(n+1)}:{provider:t,model:e}}async function Ut(){let e=c.llm.ollamaHost||c.embedding.ollamaHost||"http://localhost:11434";try{return(await fetch(`${e}/api/tags`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}function uo(){return new Promise(e=>{let t=lo("claude",["--version"],{stdio:"pipe"});t.on("error",()=>e(!1)),t.on("close",n=>e(n===0)),setTimeout(()=>{t.kill(),e(!1)},3e3)})}async function Gt(){if(N)return N;if(c.llm.provider)return N=c.llm.provider,N;if(c.llm.openrouterApiKey)return N="openrouter",N;if(c.llm.apiKey)return N="anthropic",N;if(c.llm.openaiApiKey)return N="openai",N;if(await Ut())return N="ollama",N;if(await uo())return N="claude-cli",N;throw new Error(`No LLM provider available. Either:
9
+ - Set LLM_PROVIDER (openai, anthropic, openrouter, ollama, claude-cli)
10
+ - Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or OPENROUTER_API_KEY
11
+ - Start Ollama locally
12
+ - Install the Claude CLI (claude)`)}async function Yt(){if(R)return R;if(c.embedding.provider)return R=c.embedding.provider,R;if(c.embedding.voyageApiKey)return R="voyage",R;if(await Ut())return R="ollama",R;if(c.embedding.openaiApiKey)return R="openai",R;if(c.embedding.openrouterApiKey)return R="openrouter",R;throw new Error(`No embedding provider available. Either:
13
+ - Set EMBEDDING_PROVIDER (voyage, ollama, openai, openrouter)
14
+ - Set VOYAGE_API_KEY (recommended \u2014 best quality)
15
+ - Start Ollama locally
16
+ - Set OPENAI_API_KEY
17
+ - Set OPENROUTER_API_KEY (and EMBEDDING_MODEL like "openai/text-embedding-3-large")`)}var Re,Bt,Te,Ne,N,R,ve=f(()=>{g();Re={openai:()=>Promise.resolve().then(()=>(wt(),gt)),anthropic:()=>Promise.resolve().then(()=>(At(),St)),openrouter:()=>Promise.resolve().then(()=>(Ot(),It)),"claude-cli":()=>Promise.resolve().then(()=>(Nt(),Tt)),ollama:()=>Promise.resolve().then(()=>(Dt(),Rt))},Bt={ollama:()=>Promise.resolve().then(()=>(Ct(),vt)),openai:()=>Promise.resolve().then(()=>(Pt(),Lt)),voyage:()=>Promise.resolve().then(()=>(xt(),Mt)),openrouter:()=>Promise.resolve().then(()=>(Ft(),kt))},Te={},Ne={};N=null,R=null});function L(e){return e?`[${e.join(",")}]`:null}function Wt(){let e=Number(c.embedding.dimensions)||768;if(!Number.isInteger(e)||e<=0)throw new Error(`Invalid EMBEDDING_DIMENSIONS: ${c.embedding.dimensions}`);return e}function k(e="embedding"){return`(${e}::halfvec(${Wt()}))`}function F(){return`?::halfvec(${Wt()})`}var B=f(()=>{g()});import{createHash as po}from"node:crypto";function fo(e,t,n,r="document"){let o=po("sha256");return o.update(e),o.update("\0"),o.update(t),o.update("\0"),o.update(r),o.update("\0"),o.update(n),o.digest("hex")}async function ho(e){if(!e.length)return new Map;let t=await p("embedding_cache").whereIn("key",e).select("key","embedding");return new Map(t.map(n=>[n.key,Eo(n.embedding)]))}function Eo(e){return Array.isArray(e)||typeof e!="string"?e:(e.startsWith("[")?e.slice(1,-1):e).split(",").map(Number)}async function _o(e){e.length&&await p("embedding_cache").whereIn("key",e).update({hits:p.raw("hits + 1"),lastUsedAt:p.fn.now()})}async function yo(e,t,n){if(e.length){for(let{key:r,embedding:o}of e)await p.raw(`
18
+ INSERT INTO embedding_cache (key, provider, model, embedding, hits, created_at, last_used_at)
19
+ VALUES (?, ?, ?, ?, 0, NOW(), NOW())
20
+ ON CONFLICT (key) DO UPDATE
21
+ SET last_used_at = NOW(),
22
+ hits = embedding_cache.hits + 1
23
+ `,[r,t,n,L(o)]);await wo()}}async function wo(){let e=Date.now();if(e-jt<go)return;jt=e;let[{count:t}]=await p("embedding_cache").count("key as count"),n=Number(t);if(n<=Kt)return;let r=Math.min(n-Kt,mo);await p.raw(`
24
+ DELETE FROM embedding_cache WHERE key IN (
25
+ SELECT key FROM embedding_cache ORDER BY last_used_at ASC LIMIT ?
26
+ )
27
+ `,[r])}async function Vt(e,t,n,r,o,i={}){if(!e.length)return[];let s=i.inputType||o?.inputType||"document",a=e.map(d=>fo(t,n,d,s)),l=await ho(a),u=[],h=[],E=new Array(e.length);for(let d=0;d<e.length;d++){let _=l.get(a[d]);_?E[d]=_:(u.push(e[d]),h.push(d))}if(u.length){let d=await r(u,o),_=[];for(let y=0;y<u.length;y++){let w=h[y];E[w]=d[y],_.push({key:a[w],embedding:d[y]})}yo(_,t,n).catch(y=>{process.stderr.write(`[embedding-cache] store failed: ${y.message}
28
+ `)})}let m=a.filter(d=>l.has(d));return m.length&&_o(m).catch(()=>{}),E}var Kt,mo,jt,go,Jt=f(()=>{B();A();Kt=1e4,mo=500;jt=0,go=6e4});async function Ce(e,t={}){let[n]=await re([e],t);return n}async function re(e,{inputType:t="document"}={}){if(!e.length)return[];let n=await Yt(),r=await Ht(n),o=c.embedding.model,i={...c.embedding,inputType:t};return Vt(e,n,o,r,i,{inputType:t})}var Wa,Le=f(()=>{g();ve();Jt();({dimensions:Wa}=c.embedding)});var qt,zt=f(()=>{qt="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"});import{webcrypto as Xt}from"node:crypto";function Ao(e){!M||M.length<e?(M=Buffer.allocUnsafe(e*So),Xt.getRandomValues(M),H=0):H+e>M.length&&(Xt.getRandomValues(M),H=0),H+=e}function Zt(e=21){Ao(e|=0);let t="";for(let n=H-e;n<H;n++)t+=qt[M[n]&63];return t}var So,M,H,Qt=f(()=>{zt();So=128});async function en(e,t){let n=t||c.defaults.namespace,r=e.toLowerCase();return p("entity").where({namespace:n}).whereNull("mergedWith").where(function(){this.whereRaw("LOWER(name) = ?",[r]).orWhereRaw("aliases @> ARRAY[?]::text[]",[r])}).first()||null}async function tn(e,{entityType:t,namespace:n,limit:r=10}={}){let o=p("entity").whereRaw("LOWER(name) LIKE ?",[`%${e.toLowerCase()}%`]).whereNull("mergedWith").orderBy("mentionCount","desc").limit(r);return t&&o.where({entityType:t}),n&&o.where({namespace:n}),o}var nn=f(()=>{A();B();g()});async function oe({podType:e,externalId:t,name:n,namespace:r,attrs:o={},entityId:i=null,connectionId:s=null,startedAt:a=null}){if(!t)throw new Error("upsertPod requires externalId; use insertPod for custom pods");let l=`pod-${Zt(16)}`,u=r||c.defaults.namespace,{rows:[h]}=await p.raw(`
29
+ INSERT INTO pod (uid, pod_type, name, namespace, attrs, entity_id, connection_id, external_id, started_at, created_at, updated_at)
30
+ VALUES (?, ?, ?, ?, ?::jsonb, ?, ?, ?, ?, NOW(), NOW())
31
+ ON CONFLICT (pod_type, external_id, namespace) WHERE external_id IS NOT NULL DO UPDATE SET
32
+ attrs = pod.attrs || EXCLUDED.attrs,
33
+ updated_at = NOW()
34
+ RETURNING *, (xmax = 0) AS "isNew"
35
+ `,[l,e,n,u,JSON.stringify(o),i,s,t,a]);return{pod:h,isNew:h.isNew}}async function Pe(e){return p("pod").where({uid:e}).first()||null}async function rn({podType:e,externalId:t,namespace:n}){return p("pod").where({podType:e,externalId:t,namespace:n||c.defaults.namespace}).first()||null}async function Me(e,t){await p.raw("UPDATE pod SET attrs = attrs || ?::jsonb, updated_at = NOW() WHERE id = ?",[JSON.stringify(t),e])}async function on(e,t=new Date){await p("pod").where({id:e}).update({endedAt:t,updatedAt:p.fn.now()})}async function V(e,{docs:t=0,facts:n=0}){!t&&!n||await p.raw(`UPDATE pod
36
+ SET member_doc_count = member_doc_count + ?,
37
+ member_fact_count = member_fact_count + ?,
38
+ updated_at = NOW()
39
+ WHERE id = ?`,[t,n,e])}var ie=f(()=>{Qt();A();g()});var se={};I(se,{attach:()=>ae,attachDocument:()=>bo,attachEntity:()=>Io,attachFact:()=>sn,detach:()=>Oo,factIdsInPod:()=>Ro,listMembers:()=>To,listPodsForMember:()=>No});async function ae(e,t,n,r="primary"){let{rowCount:o}=await p.raw(`INSERT INTO pod_membership (pod_id, member_type, member_id, role)
40
+ VALUES (?, ?, ?, ?)
41
+ ON CONFLICT (pod_id, member_type, member_id) DO NOTHING`,[e,t,n,r]);return o>0&&(t==="fact"?await V(e,{facts:1}):t==="document"&&await V(e,{docs:1})),{attached:o>0}}async function Oo(e,t,n){let r=await p("pod_membership").where({podId:e,memberType:t,memberId:n}).del();return r>0&&(t==="fact"?await V(e,{facts:-1}):t==="document"&&await V(e,{docs:-1})),{detached:r>0}}async function To(e,{memberType:t,limit:n=20}={}){if(!t)throw new Error("listMembers requires a memberType filter");return p(`${t} as t`).join("pod_membership as pm",function(){this.on("pm.member_id","=","t.id").andOnVal("pm.member_type","=",t)}).where("pm.pod_id",e).orderBy("pm.createdAt","desc").limit(n).select("t.*","pm.role as podRole","pm.createdAt as attachedAt")}async function No(e,t){return p("pod as p").join("pod_membership as pm","pm.pod_id","p.id").where("pm.memberType",e).where("pm.memberId",t).select("p.*","pm.role as podRole")}async function Ro(e){return await p("pod_membership").where({podId:e,memberType:"fact"}).pluck("memberId")}var sn,bo,Io,xe=f(()=>{A();ie();sn=(e,t,n)=>ae(e,"fact",t,n),bo=(e,t,n)=>ae(e,"document",t,n),Io=(e,t,n)=>ae(e,"entity",t,n)});async function cn(e,{limit:t=50}={}){return p("fact").join("fact_entity","fact.id","fact_entity.fact_id").where("fact_entity.entity_id",e).where("fact.status","active").select("fact.*","fact_entity.mention_count as entityMentionCount").orderBy("fact_entity.mention_count","desc").limit(t)}async function J(e){if(!e.length)return new Map;let t=await p("fact_entity").whereIn("factId",e).select("factId","entityId"),n=new Map;for(let r of t)n.has(r.factId)||n.set(r.factId,[]),n.get(r.factId).push(r.entityId);return n}var ce=f(()=>{A();xe()});async function ln(e){let t=await Gt();return $t(e,t)}async function ke(e,{model:t,caller:n}={}){let{provider:r,model:o}=await ln(t),i=await De(r),s=Date.now();try{let a=await Ie(()=>i(e,{model:o,jsonMode:!1}),c.llm.maxRetries),l=a.cost||be(a.model,a.inputTokens,a.outputTokens);return K({provider:r,model:a.model,caller:n,input:e,response:a.text,inputTokens:a.inputTokens,outputTokens:a.outputTokens,cost:l,durationMs:Date.now()-s,status:"success"}),a.text}catch(a){throw K({provider:r,model:o,caller:n,input:e,response:null,inputTokens:0,outputTokens:0,cost:0,durationMs:Date.now()-s,status:"error",error:a.message}),a}}async function le(e,{model:t,caller:n}={}){let{provider:r,model:o}=await ln(t),i=await De(r),s=Date.now();try{let a=await Ie(()=>i(e,{model:o,jsonMode:!0}),c.llm.maxRetries),l=a.cost||be(a.model,a.inputTokens,a.outputTokens);return K({provider:r,model:a.model,caller:n,input:e,response:a.text,inputTokens:a.inputTokens,outputTokens:a.outputTokens,cost:l,durationMs:Date.now()-s,status:"success"}),Do(a.text)}catch(a){throw K({provider:r,model:o,caller:n,input:e,response:null,inputTokens:0,outputTokens:0,cost:0,durationMs:Date.now()-s,status:"error",error:a.message}),a}}function Do(e){try{return JSON.parse(e.trim())}catch{}let t=e.match(/```(?:json)?\s*([\s\S]*?)```/);if(t)try{return JSON.parse(t[1].trim())}catch{}let n=e.match(/[\[{][\s\S]*[\]}]/);if(n)try{return JSON.parse(n[0])}catch{}return null}var q=f(()=>{g();ve();j()});import vo from"node:path";async function un(e){e.length&&await p.raw(`UPDATE fact_lifecycle
42
+ SET access_count = access_count + 1,
43
+ last_accessed_at = NOW(),
44
+ stage = CASE WHEN stage = 'stable' THEN 'editing' ELSE stage END,
45
+ stage_entered_at = CASE WHEN stage = 'stable' THEN NOW() ELSE stage_entered_at END
46
+ WHERE fact_id = ANY(?)`,[e])}var ys,gs,ws,dn=f(()=>{A();Le();q();B();g();P();ys=vo.join(Z,"audm-decision.md"),gs=c.memory.skipThreshold,ws=c.memory.ambiguousThreshold});async function pn(e){if(!e||e.length<2)return;let t=[...new Set(e.filter(i=>Number.isInteger(i)))].sort((i,s)=>i-s);if(t.length<2)return;let n=[];for(let i=0;i<t.length;i++)for(let s=i+1;s<t.length;s++)n.push([t[i],t[s]]);let r=n.map(()=>"(?, ?, 1, NOW(), NOW())").join(", "),o=n.flat();await p.raw(`
47
+ INSERT INTO hebbian_edge (fact_a_id, fact_b_id, strength, first_seen_at, last_seen_at)
48
+ VALUES ${r}
49
+ ON CONFLICT (fact_a_id, fact_b_id)
50
+ DO UPDATE SET
51
+ strength = hebbian_edge.strength + 1,
52
+ last_seen_at = NOW()
53
+ `,o)}var mn=f(()=>{A()});var fn={};I(fn,{consolidateEntityCoRetrievalEdges:()=>Po,getCoRetrievedEntities:()=>Lo,getEdgeStrengthsForRanking:()=>Be,getEntityHebbianStats:()=>Mo,strengthenEntityEdges:()=>Fe});function ue(e){return Co/Math.max(e,1)}async function Fe(e,t={}){if(!c.hebbian.entity.enabled||!e||e.length<2)return;let n=t.eta??c.hebbian.entity.eta,r=t.cap??c.hebbian.entity.cap,o=[...new Set(e.filter(l=>Number.isInteger(l)))].sort((l,u)=>l-u);if(o.length<2)return;let i=[];for(let l=0;l<o.length;l++)for(let u=l+1;u<o.length;u++)i.push([o[l],o[u]]);let s=i.map(()=>"(?, ?, ?, NOW(), NOW())").join(", "),a=i.flatMap(([l,u])=>[l,u,n]);await p.raw(`
54
+ INSERT INTO entity_hebbian_edge (entity_a_id, entity_b_id, strength, first_seen_at, last_seen_at)
55
+ VALUES ${s}
56
+ ON CONFLICT (entity_a_id, entity_b_id)
57
+ DO UPDATE SET
58
+ strength = LEAST(entity_hebbian_edge.strength + ?, ?),
59
+ last_seen_at = NOW()
60
+ `,[...a,n,r])}async function Lo(e,t={}){if(!c.hebbian.entity.enabled)return[];let n=t.limit??10,r=t.minEffectiveStrength??c.hebbian.entity.minEffective,o=ue(t.halfLifeDays??c.hebbian.entity.halfLifeDays),{rows:i}=await p.raw(`
61
+ SELECT
62
+ CASE WHEN entity_a_id = ? THEN entity_b_id ELSE entity_a_id END AS "partnerId",
63
+ (strength * EXP(-1.0 * ?::float8 * EXTRACT(EPOCH FROM (NOW() - last_seen_at)) / 86400.0))::float8 AS "effectiveStrength",
64
+ strength::float8 AS "rawStrength",
65
+ last_seen_at AS "lastSeenAt"
66
+ FROM entity_hebbian_edge
67
+ WHERE entity_a_id = ? OR entity_b_id = ?
68
+ ORDER BY "effectiveStrength" DESC
69
+ LIMIT ?
70
+ `,[e,o,e,e,n*3]);return i.filter(s=>s.effectiveStrength>=r).slice(0,n)}async function Be(e,t,n={}){if(!c.hebbian.entity.enabled)return new Map;if(!e.length||!t.length)return new Map;let r=ue(n.halfLifeDays??c.hebbian.entity.halfLifeDays),o=[...new Set(e)],i=[...new Set(t)].filter(l=>!o.includes(l));if(!i.length)return new Map;let{rows:s}=await p.raw(`
71
+ SELECT
72
+ CASE
73
+ WHEN entity_a_id = ANY(?::bigint[]) THEN entity_b_id
74
+ ELSE entity_a_id
75
+ END AS "candidateId",
76
+ SUM(strength * EXP(-1.0 * ?::float8 * EXTRACT(EPOCH FROM (NOW() - last_seen_at)) / 86400.0))::float8 AS "summedStrength"
77
+ FROM entity_hebbian_edge
78
+ WHERE
79
+ (entity_a_id = ANY(?::bigint[]) AND entity_b_id = ANY(?::bigint[]))
80
+ OR
81
+ (entity_b_id = ANY(?::bigint[]) AND entity_a_id = ANY(?::bigint[]))
82
+ GROUP BY "candidateId"
83
+ `,[o,r,o,i,o,i]),a=new Map;for(let l of s)a.set(Number(l.candidateId),l.summedStrength);return a}async function Po({floor:e=.5,decayDays:t=90}={}){let n=ue(c.hebbian.entity.halfLifeDays),{rows:r}=await p.raw(`
84
+ DELETE FROM entity_hebbian_edge
85
+ WHERE (strength * EXP(-1.0 * ?::float8 * EXTRACT(EPOCH FROM (NOW() - last_seen_at)) / 86400.0)) <= ?
86
+ AND last_seen_at < NOW() - (INTERVAL '1 day' * ?)
87
+ RETURNING entity_a_id
88
+ `,[n,e,t]);return r.length}async function Mo({topN:e=5}={}){let t=ue(c.hebbian.entity.halfLifeDays),n=await p.raw(`
89
+ SELECT
90
+ COUNT(*)::int AS "edgeCount",
91
+ COALESCE(AVG(strength)::float8, 0) AS "avgStrength",
92
+ COALESCE(MAX(strength)::float8, 0) AS "maxStrength"
93
+ FROM entity_hebbian_edge
94
+ `),r=await p.raw(`
95
+ SELECT
96
+ ea.name AS "aName",
97
+ eb.name AS "bName",
98
+ strength::float8 AS "strength",
99
+ (strength * EXP(-1.0 * ?::float8 * EXTRACT(EPOCH FROM (NOW() - last_seen_at)) / 86400.0))::float8 AS "decayed"
100
+ FROM entity_hebbian_edge
101
+ JOIN entity ea ON ea.id = entity_a_id
102
+ JOIN entity eb ON eb.id = entity_b_id
103
+ ORDER BY "decayed" DESC
104
+ LIMIT ?
105
+ `,[t,e]);return{edgeCount:n.rows[0]?.edgeCount??0,avgStrength:n.rows[0]?.avgStrength??0,maxStrength:n.rows[0]?.maxStrength??0,topPairs:r.rows??[]}}var Co,He=f(()=>{A();g();Co=Math.log(2)});async function hn(e,{direction:t="both",relationType:n,limit:r=50}={}){let o=a=>{let l=a==="outgoing"?"source_id":"target_id",u=a==="outgoing"?"target_id":"source_id";return p.raw(`
106
+ SELECT r.id AS "relationId", r.relation_type AS "relationType",
107
+ r.mention_count AS "mentionCount", r.valid_at AS "validAt",
108
+ e.id AS "entityId", e.uid, e.name, e.entity_type AS "entityType",
109
+ e.description, '${a}' AS direction
110
+ FROM relation r
111
+ JOIN entity e ON e.id = r.${u}
112
+ WHERE r.${l} = ?
113
+ AND r.invalid_at IS NULL
114
+ AND e.merged_with IS NULL
115
+ ${n?"AND r.relation_type = ?":""}
116
+ ORDER BY r.mention_count DESC
117
+ LIMIT ?
118
+ `,n?[e,n,r]:[e,r])};if(t==="outgoing"){let{rows:a}=await o("outgoing");return a}if(t==="incoming"){let{rows:a}=await o("incoming");return a}let[i,s]=await Promise.all([o("outgoing"),o("incoming")]);return[...i.rows,...s.rows]}var En=f(()=>{A()});function de({minConfidence:e="medium",pointInTime:t,categories:n}){let r=xo[e]??1,o=[r],i="",s="";return t&&(i="AND valid_from <= ? AND (valid_until IS NULL OR valid_until > ?)",o.push(t,t)),n?.length&&(s="AND category = ANY(?)",o.push(n)),{minRank:r,temporalClause:i,categoryClause:s,filterParams:o}}var xo,z,pe=f(()=>{xo={low:0,medium:1,high:2},z=`CASE confidence
119
+ WHEN 'high' THEN 2
120
+ WHEN 'medium' THEN 1
121
+ ELSE 0
122
+ END`});async function _n(e,{namespaces:t,limit:n=20}){let r=L(e),o=`${k("embedding")} <=> ${F()}`,{rows:i}=await p.raw(`
123
+ SELECT id, document_id AS "documentId", chunk_index AS "chunkIndex",
124
+ content, section_heading AS "sectionHeading", namespace,
125
+ 1 - (${o}) as similarity
126
+ FROM chunk
127
+ WHERE namespace = ANY(?)
128
+ AND embedding IS NOT NULL
129
+ ORDER BY ${o}
130
+ LIMIT ?
131
+ `,[r,t,r,n]);return i}var yn=f(()=>{A();B();g();pe()});async function gn(e,{namespaces:t,limit:n=20}){let{rows:r}=await p.raw(`
132
+ SELECT id, document_id AS "documentId", chunk_index AS "chunkIndex",
133
+ content, section_heading AS "sectionHeading", namespace,
134
+ ts_rank(search_vector, plainto_tsquery('english', ?)) as rank
135
+ FROM chunk
136
+ WHERE namespace = ANY(?)
137
+ AND search_vector @@ plainto_tsquery('english', ?)
138
+ ORDER BY rank DESC
139
+ LIMIT ?
140
+ `,[e,t,e,n]);return r}var wn=f(()=>{A();pe()});async function An(e,t,{namespaces:n,limit:r=5,minConfidence:o="medium",pointInTime:i,categories:s,podIds:a=null}){let l=L(t),u=`${k("embedding")} <=> ${F()}`,{temporalClause:h,categoryClause:E,filterParams:m}=de({minConfidence:o,pointInTime:i,categories:s}),d=r*$o,_=Array.isArray(a)&&a.length>0,y=_?`AND id = ANY(
141
+ SELECT member_id FROM pod_membership
142
+ WHERE member_type = 'fact' AND pod_id = ANY(?::int[])
143
+ )`:"",w=_?[a]:[],[D,...b]=m,Ee=[l,l,n,D,...b,...w,l,d],_e=[e,e,n,D,e,...b,...w,d],S=[d,d,r],ye=`
144
+ WITH semantic AS (
145
+ SELECT id,
146
+ uid,
147
+ content, category, confidence, importance, namespace, status,
148
+ source_document_ids AS "sourceDocumentIds",
149
+ source_section AS "sourceSection",
150
+ created_at,
151
+ 1 - (${u}) AS similarity,
152
+ ROW_NUMBER() OVER (ORDER BY ${u}) AS rank_ix
153
+ FROM fact
154
+ WHERE namespace = ANY(?)
155
+ AND status = 'active'
156
+ AND embedding IS NOT NULL
157
+ AND ${z} >= ?
158
+ ${h}
159
+ ${E}
160
+ ${y}
161
+ ORDER BY ${u}
162
+ LIMIT ?
163
+ ),
164
+ keyword AS (
165
+ SELECT id,
166
+ uid,
167
+ content, category, confidence, importance, namespace, status,
168
+ source_document_ids AS "sourceDocumentIds",
169
+ source_section AS "sourceSection",
170
+ created_at,
171
+ ts_rank_cd(search_vector, plainto_tsquery('english', ?)) AS keyword_rank,
172
+ ROW_NUMBER() OVER (ORDER BY ts_rank_cd(search_vector, plainto_tsquery('english', ?)) DESC) AS rank_ix
173
+ FROM fact
174
+ WHERE namespace = ANY(?)
175
+ AND status = 'active'
176
+ AND ${z} >= ?
177
+ AND search_vector @@ plainto_tsquery('english', ?)
178
+ ${h}
179
+ ${E}
180
+ ${y}
181
+ ORDER BY keyword_rank DESC
182
+ LIMIT ?
183
+ ),
184
+ fused AS (
185
+ SELECT COALESCE(s.id, k.id) AS id,
186
+ COALESCE(s.uid, k.uid) AS uid,
187
+ COALESCE(s.content, k.content) AS content,
188
+ COALESCE(s.category, k.category) AS category,
189
+ COALESCE(s.confidence, k.confidence) AS confidence,
190
+ COALESCE(s.importance, k.importance) AS importance,
191
+ COALESCE(s.namespace, k.namespace) AS namespace,
192
+ COALESCE(s.status, k.status) AS status,
193
+ COALESCE(s."sourceDocumentIds", k."sourceDocumentIds") AS "sourceDocumentIds",
194
+ COALESCE(s."sourceSection", k."sourceSection") AS "sourceSection",
195
+ COALESCE(s.created_at, k.created_at) AS created_at,
196
+ COALESCE(s.similarity, 0) AS similarity,
197
+ (
198
+ ${Bo} * (1.0 / (${Sn} + COALESCE(s.rank_ix, ?)))
199
+ + ${Ho} * (1.0 / (${Sn} + COALESCE(k.rank_ix, ?)))
200
+ ) AS rrf_raw
201
+ FROM semantic s
202
+ FULL OUTER JOIN keyword k ON s.id = k.id
203
+ ),
204
+ ranked AS (
205
+ SELECT f.*,
206
+ COALESCE(fl.access_count, 0) AS access_count,
207
+ fl.last_accessed_at,
208
+ -- ACT-R activation: ln(n+1) - 0.5*ln(t_days), softplus to keep >= 0.
209
+ -- t_days floor of 0.01 prevents log(0). Recently-accessed facts win ties.
210
+ ln(1.0 + exp(
211
+ ln(COALESCE(fl.access_count, 0) + 1.0)
212
+ - 0.5 * ln(
213
+ GREATEST(
214
+ EXTRACT(epoch FROM (now() - COALESCE(fl.last_accessed_at, f.created_at))) / 86400.0,
215
+ 0.01
216
+ )
217
+ )
218
+ )) AS activation,
219
+ CASE f.importance WHEN 'vital' THEN ${Uo} ELSE 1.0 END AS importance_mult,
220
+ CASE f.confidence
221
+ WHEN 'high' THEN ${Go}
222
+ WHEN 'medium' THEN ${Yo}
223
+ WHEN 'low' THEN ${Wo}
224
+ ELSE 1.0
225
+ END AS confidence_mult
226
+ FROM fused f
227
+ LEFT JOIN fact_lifecycle fl ON fl.fact_id = f.id
228
+ )
229
+ SELECT id, uid, content, category, confidence, importance, namespace, status,
230
+ "sourceDocumentIds", "sourceSection", similarity,
231
+ rrf_raw,
232
+ access_count,
233
+ last_accessed_at AS "lastAccessedAt",
234
+ activation,
235
+ (rrf_raw * activation * importance_mult * confidence_mult) AS final_score
236
+ FROM ranked
237
+ ORDER BY final_score DESC,
238
+ CASE WHEN importance = 'vital' THEN 0 ELSE 1 END
239
+ LIMIT ?
240
+ `,ir=[...Ee,..._e,...S],{rows:X}=await p.raw(ye,ir);if(!X.length)return[];let ar=X[0].final_score||X[0].rrf_raw||1;return X.map(ge=>({...ge,rrfScore:Math.round(Number(ge.final_score||ge.rrf_raw)/Number(ar)*100)/100}))}var Sn,Bo,Ho,$o,Uo,Go,Yo,Wo,bn=f(()=>{A();B();g();pe();Sn=20,Bo=1,Ho=.7,$o=3,Uo=1.5,Go=1,Yo=.85,Wo=.7});async function In(e){let t=e.map(o=>o.id),n=await J(t),r=new Set;for(let o of n.values())for(let i of o)r.add(i);return r.size?p("entity").whereIn("id",[...r]).whereNull("mergedWith").select("id","uid","name","entityType","description"):[]}async function On(e,{limit:t=10}={}){if(!e.length)return[];let n=await p("relation").where(function(){this.whereIn("sourceId",e).orWhereIn("targetId",e)}).whereNull("invalidAt").select("*").limit(t*3),r=new Set(e),o=new Set,i=new Map;for(let E of n){let m=r.has(E.sourceId)?E.targetId:E.sourceId;o.add(m),i.has(m)||i.set(m,E)}if(!o.size)return[];let s=await p("entity").whereIn("id",[...o]).whereNull("mergedWith").select("id","name"),a=new Map(s.map(E=>[E.id,E.name])),l=await p("fact").join("fact_entity","fact.id","fact_entity.factId").whereIn("fact_entity.entityId",[...o]).where("fact.status","active").select("fact.*","fact_entity.entityId").orderBy("fact_entity.mentionCount","desc").limit(t*3),u=new Set,h=[];for(let E of l){if(u.has(E.id))continue;u.add(E.id);let m=i.get(E.entityId),d=a.get(E.entityId)||"unknown",_=m?.relationType||"related";if(h.push({...E,relationPath:`${d} (${_})`,graphDistance:1}),h.length>=t)break}return h}function Tn(e,t,n,r){let o=new Set(n),i=e.map(a=>({...a,resultType:"direct"})),s=t.filter(a=>!e.some(l=>l.id===a.id)).map(a=>({...a,rrfScore:(a.rrfScore||.1)*.5,resultType:"related"}));return[...i,...s].slice(0,r)}var Nn=f(()=>{A();ce()});var $,$e=f(()=>{$=class{#e=new Map;#t;#n;constructor({maxSize:t=100,ttlMs:n=300*1e3}={}){this.#t=t,this.#n=n}get(t){let n=this.#e.get(t);if(n){if(Date.now()-n.timestamp>this.#n){this.#e.delete(t);return}return n.value}}set(t,n){if(this.#e.size>=this.#t){let r=this.#e.keys().next().value;this.#e.delete(r)}this.#e.set(t,{value:n,timestamp:Date.now()})}}});async function Dn(e){let t=Rn.get(e);if(t)return t;let n=`You are a search query expander for a personal knowledge base.
241
+
242
+ Given the user's query, generate 3-5 alternative search queries that would help find ALL relevant information \u2014 including facts that don't literally match the query but are semantically related.
243
+
244
+ Think about:
245
+ - Synonyms and rephrased versions
246
+ - Inverse/negative framings (if someone asks "what should I use", also search for "what to avoid")
247
+ - Related concepts that would inform the answer
248
+ - Specific terms someone might have used when storing this knowledge
249
+
250
+ User query: "${e}"
251
+
252
+ Respond with ONLY a JSON array of strings. Do not include the original query.`;try{let r=await le(n,{model:c.llm.extractionModel,caller:"query-expander"});if(!Array.isArray(r))return[e];let o=r.filter(s=>typeof s=="string"&&s.trim()).slice(0,Ko),i=o.length?[e,...o]:[e];return Rn.set(e,i),i}catch(r){return console.error("[query-expander] Failed:",r.message),[e]}}var Ko,Rn,vn=f(()=>{q();$e();g();Ko=5,Rn=new $({maxSize:100,ttlMs:300*1e3})});import{readFile as jo}from"node:fs/promises";import{join as Vo}from"node:path";async function Pn(e){let t=e.trim().toLowerCase(),n=Ue.get(t);if(n)return n;let o=`${await jo(Jo,"utf8")}
253
+
254
+ ---
255
+
256
+ Query: ${e}
257
+
258
+ ---
259
+
260
+ Respond with ONLY a JSON object: { "intent": "preference|factual|entity_lookup|exploratory|temporal", "categories": [...], "entities": [...], "expand": bool, "pointInTime": null or "YYYY-MM-DD", "reasoning": "..." }`;try{let i=await le(o,{model:c.llm.extractionModel,caller:"query-router"});if(!i||!qo.includes(i.intent)){let l=Cn("factual",{});return Ue.set(t,l),l}let s=Ln[i.intent],a={intent:i.intent,categories:Array.isArray(i.categories)&&i.categories.length?i.categories:s.categories,entities:Array.isArray(i.entities)?i.entities:[],expand:typeof i.expand=="boolean"?i.expand:s.expand,useGraph:s.useGraph,limit:s.limit,pointInTime:i.pointInTime||null,reasoning:i.reasoning||""};return Ue.set(t,a),a}catch(i){return console.error("[query-router] Failed:",i.message),Cn("factual",{reasoning:`Fallback \u2014 ${i.message}`})}}function Cn(e,t={}){let n=Ln[e];return{intent:e,categories:n.categories,entities:[],expand:n.expand,useGraph:n.useGraph,limit:n.limit,pointInTime:null,reasoning:"",...t}}var Jo,Ue,qo,Ln,Mn=f(()=>{q();$e();g();P();Jo=Vo(Z,"query-router.md"),Ue=new $({maxSize:200,ttlMs:600*1e3}),qo=["preference","factual","entity_lookup","exploratory","temporal"],Ln={preference:{categories:["preference","opinion","personal"],expand:!1,useGraph:!1,limit:null},factual:{categories:[],expand:!1,useGraph:!1,limit:null},entity_lookup:{categories:[],expand:!1,useGraph:!0,limit:null},exploratory:{categories:[],expand:!0,useGraph:!0,limit:15},temporal:{categories:[],expand:!1,useGraph:!1,limit:null}}});function kn(e){for(let t of zo)if(!e[t])throw new Error(`Pod kind missing required field: ${t}`);if(e.visibility&&!Xo.has(e.visibility))throw new Error(`Pod kind ${e.name}: invalid visibility ${e.visibility}`);if(e.activeMode&&!Zo.has(e.activeMode))throw new Error(`Pod kind ${e.name}: invalid activeMode ${e.activeMode}`);if(e.writePolicy&&!Qo.has(e.writePolicy))throw new Error(`Pod kind ${e.name}: invalid writePolicy ${e.writePolicy}`);xn.set(e.name,ei(e))}function ei(e){return{visibility:"private",activeMode:"multi-active",hotContextBudget:0,retrievalWeights:{recency:1,relevance:1},importanceDefault:2,ttlDays:null,writePolicy:"origin-only",lifecycle:{},...e}}async function Fn(e={}){let t=[];for(let n of xn.values())if(typeof n.resolveActiveScope=="function")try{let r=await n.resolveActiveScope(e);Array.isArray(r)&&r.length>0&&t.push({kind:n,scope:r})}catch{}return t}var zo,Xo,Zo,Qo,xn,Ge=f(()=>{P();zo=["name"],Xo=new Set(["private","shared","public"]),Zo=new Set(["singleton-live","multi-active","rolling-window","always"]),Qo=new Set(["origin-only","shared-allowlist","open"]),xn=new Map});var We={};I(We,{CURSOR_PATH:()=>U,endActiveSession:()=>ui,ensureActiveSession:()=>si,getActiveCursor:()=>li,getActiveSessionPodUid:()=>Ye});import{writeFile as ti,readFile as ni,unlink as ri}from"node:fs/promises";import{existsSync as oi,mkdirSync as ii}from"node:fs";import{dirname as Bn}from"node:path";async function me(){try{let e=await ni(U,"utf8");return JSON.parse(e)}catch{return null}}async function Hn(e){oi(Bn(U))||ii(Bn(U),{recursive:!0}),await ti(U,JSON.stringify(e,null,2),"utf8")}async function si({sessionId:e,transcriptPath:t=null,cwd:n=null,model:r=null,namespace:o=null}){if(!e)throw new Error("ensureActiveSession requires sessionId from hook stdin");let i=o||c.defaults.namespace,s=await me();if(s&&s.session_id===e&&s.namespace===i){let u=await Pe(s.pod_uid);if(u)return await Me(u.id,{turn_count:(di(u.attrs)||0)+1}),await ci(s),u}let a=new Date,{pod:l}=await oe({podType:$n,externalId:e,name:Gn({sessionId:e,startedAt:a}),namespace:i,attrs:Un({sessionId:e,transcriptPath:t,cwd:n,turnCount:1,model:r}),startedAt:a});return await Hn({session_id:e,pod_uid:l.uid,namespace:i,started_at:l.startedAt??a.toISOString(),last_seen_at:new Date().toISOString()}),l}async function ci(e){await Hn({...e,last_seen_at:new Date().toISOString()})}async function Ye({allowStale:e=!1}={}){let t=await me();return!t||!t.pod_uid||!e&&t.started_at&&Date.now()-new Date(t.started_at).getTime()>ai?null:t.pod_uid}async function li(){return me()}async function ui({conclusion:e=null,summary:t=null}={}){let n=await me();if(!n)return null;let r=await Pe(n.pod_uid);if(r){if(e||t){let o={};e&&(o.conclusion=e),t&&(o.summary=t),await Me(r.id,o)}await on(r.id)}try{await ri(U)}catch{}return r}function di(e){if(!e)return 0;if(typeof e=="object")return e.turn_count??0;try{return JSON.parse(e).turn_count??0}catch{return 0}}var U,ai,fe=f(()=>{ie();Ke();g();P();U=it,ai=360*60*1e3});function Un({sessionId:e,transcriptPath:t=null,cwd:n=null,turnCount:r=0,model:o=null,conclusion:i=null,summary:s=null}){return{session_id:e,transcript_path:t,cwd:n,turn_count:r,model:o,conclusion:i,summary:s}}function Gn({sessionId:e,startedAt:t=new Date}={}){let r=(t instanceof Date?t:new Date(t)).toISOString().replace("T"," ").slice(0,16),o=e?e.slice(0,8):"unknown";return`claude-session ${r} (${o})`}var $n,Yn,Ke=f(()=>{fe();$n="claude_session",Yn={name:"claude_session",description:"Claude Code session",identityField:"session_id",attrsSchema:{session_id:"string",transcript_path:"string",cwd:"string",turn_count:"number",model:"string",conclusion:"string",summary:"string"},visibility:"private",activeMode:"singleton-live",hotContextBudget:6,retrievalWeights:{recency:1,relevance:.7},importanceDefault:2,ttlDays:90,schemaDocPath:"kinds/claude_session.schema.md",writePolicy:"origin-only",resolveActiveScope:async()=>{try{let e=await Ye();return e?[e]:[]}catch{return[]}}}});var mi,Wn,Kn=f(()=>{A();g();mi=1440*60*1e3,Wn={name:"person",description:"A person you have a working relationship with",identityField:"primary_handle",attrsSchema:{platforms:"object",role:"string",relationship:"string",notes:"string"},visibility:"private",activeMode:"rolling-window",hotContextBudget:4,retrievalWeights:{recency:1,relevance:.8},importanceDefault:3,ttlDays:null,schemaDocPath:"kinds/person.schema.md",writePolicy:"origin-only",resolveActiveScope:async(e={})=>{let t=e.namespace||c.defaults.namespace;try{let n=new Date(Date.now()-mi);return(await p("pod as p").join("pod_membership as pm","pm.pod_id","p.id").join("fact_lifecycle as fl","fl.fact_id","pm.member_id").where("pm.memberType","fact").where("p.podType","person").where("p.namespace",t).where("p.status","active").where("fl.lastAccessedAt",">=",n).distinct("p.uid")).map(o=>o.uid)}catch{return[]}}}});var Vn={};I(Vn,{POD_TYPE:()=>Ve,deriveProjectRoot:()=>qe,ensureProjectPod:()=>hi,formatForDisplay:()=>_i,membership:()=>se,projectKind:()=>Je});import{execFileSync as fi}from"node:child_process";import{basename as jn}from"node:path";async function hi({cwd:e,namespace:t=null}){if(!e)return null;let n=qe(e),r=t||c.defaults.namespace,i=(n!==e?!1:je(e)===e)?n:je(e),{pod:s}=await oe({podType:Ve,externalId:n,name:jn(n)||n,namespace:r,attrs:{root_path:n,git_root:i||null,display_name:jn(n)||n,discovered_at:new Date().toISOString()},startedAt:new Date});return s}function qe(e){return je(e)||e}function je(e){try{return fi("git",["rev-parse","--show-toplevel"],{cwd:e,encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim()||null}catch{return null}}async function Ei(){try{let{getActiveCursor:e}=await Promise.resolve().then(()=>(fe(),We));return(await e())?.cwd||null}catch{return null}}function _i(e){let t=yi(e.attrs);return{uid:e.uid,name:e.name,rootPath:t.root_path,gitRoot:t.git_root,displayName:t.display_name,discoveredAt:t.discovered_at,memberFactCount:e.memberFactCount,memberDocCount:e.memberDocCount}}function yi(e){if(!e)return{};if(typeof e=="object")return e;try{return JSON.parse(e)}catch{return{}}}var Ve,Je,ze=f(()=>{ie();xe();g();Ve="project",Je={name:"project",description:"Code project rooted at a git repo or directory",identityField:"root_path",attrsSchema:{root_path:"string",git_root:"string",display_name:"string",discovered_at:"string"},visibility:"shared",activeMode:"multi-active",hotContextBudget:4,retrievalWeights:{recency:.6,relevance:1},importanceDefault:3,ttlDays:null,schemaDocPath:"kinds/project.schema.md",writePolicy:"origin-only",resolveActiveScope:async(e={})=>{let t=e.cwd||await Ei();if(!t)return[];try{let n=e.namespace||c.defaults.namespace,r=qe(t),o=await rn({podType:Ve,externalId:r,namespace:n});return o?[o.uid]:[]}catch{return[]}}}});async function wi(e){if(e.project)return e.project;if(!e.cwd)try{let{getActiveCursor:t}=await Promise.resolve().then(()=>(fe(),We)),n=await t();e={...e,cwd:n?.cwd}}catch{return null}if(!e.cwd)return null;try{let{deriveProjectRoot:t}=await Promise.resolve().then(()=>(ze(),Vn)),n=t(e.cwd);return n?n.split("/").pop():null}catch{return null}}function Si(e){if(!e)return{};if(typeof e=="object")return e;try{return JSON.parse(e)}catch{return{}}}var gi,Jn,qn=f(()=>{A();g();gi="playbook",Jn={name:"playbook",description:"A reusable workflow or debug recipe (procedural memory)",identityField:"slug",attrsSchema:{slug:"string",project:"string",description:"string",tags:"array"},visibility:"shared",activeMode:"always",hotContextBudget:3,retrievalWeights:{recency:.3,relevance:1},importanceDefault:3,ttlDays:null,schemaDocPath:"kinds/playbook.schema.md",writePolicy:"origin-only",resolveActiveScope:async(e={})=>{let t=e.namespace||c.defaults.namespace,n=await wi(e);try{let o=await p("pod").where({podType:gi,namespace:t,status:"active"}).select("uid","attrs");return n?o.filter(s=>{let a=Si(s.attrs);return!a.project||a.project===n}).map(s=>s.uid):o.map(s=>s.uid)}catch{return[]}}}});var Ai,zn,Xn=f(()=>{A();g();Ai=["__virtual:vital__"],zn={name:"vital",description:"Facts marked importance=5 (vital), surfaced globally",identityField:null,attrsSchema:{},visibility:"public",activeMode:"always",hotContextBudget:6,retrievalWeights:{recency:.5,relevance:1},importanceDefault:5,ttlDays:null,schemaDocPath:"kinds/vital.schema.md",writePolicy:"open",resolveActiveScope:async()=>Ai,fetchFacts:async(e={},{slots:t=8,namespace:n}={})=>{let r=n||e.namespace||c.defaults.namespace;return p("fact as f").leftJoin("fact_lifecycle as fl","fl.fact_id","f.id").where({"f.status":"active","f.namespace":r}).where(o=>{o.where("f.importance","vital").orWhere("f.importance_score",5)}).orderByRaw("COALESCE(fl.access_count, 0) DESC, f.created_at DESC").limit(t).pluck("f.content")}}});function Ii(){if(!Zn){for(let e of bi)kn(e);Zn=!0}}var bi,Zn,Qn=f(()=>{Ge();Ke();Kn();ze();qn();Xn();bi=[Yn,Je,Wn,Jn,zn],Zn=!1;Ii()});var rr={};I(rr,{isSearchableQuery:()=>er,search:()=>Ri});async function Ri(e,{namespaces:t,limit:n=5,minConfidence:r="medium",useGraph:o=!1,includeChunks:i=!1,pointInTime:s,expand:a=!1,route:l=!0,categories:u,synthesize:h=c.search.synthesize,podScope:E=null,ctx:m={}}={}){if(!er(e))return Di();h&&(i=!0);let d=null;l&&(d=await Pn(e),o=o||d.useGraph,a=a||d.expand,n=d.limit||n,s=s||d.pointInTime,u=u||(d.categories.length?d.categories:void 0));let _=await Pi(e,t),y=await Li(E,{...m,namespace:t?.[0]}),w;_?w=await Mi(_,e,{namespaces:t,limit:n,minConfidence:r,includeChunks:i,pointInTime:s,categories:u,podIds:y}):w=await Fi(e,{namespaces:t,limit:n,minConfidence:r,useGraph:o,includeChunks:i,pointInTime:s,expand:a,categories:u,podIds:y});let D=w.facts.map(b=>b.id).filter(Boolean);if(un(D).catch(b=>console.error("[access-tracking]",b.message)),pn(D.slice(0,8)).catch(b=>console.error("[hebbian]",b.message)),c.hebbian.entity.enabled&&D.length>=2&&Ci(D).catch(b=>console.error("[hebbian-entity]",b.message)),h)try{w.synthesized=await vi(e,w)}catch(b){console.error("[synthesizer] failed:",b.message),w.synthesized=null}return w}function er(e){let t=String(e||"").trim();return t?!/^[*%_?\s]+$/.test(t):!1}function Di(){return{facts:[],chunks:[],matchedEntity:null,relatedEntities:[]}}async function vi(e,{facts:t,chunks:n}){let r=[];if(t.slice(0,10).forEach((s,a)=>{r.push(`[F${a+1}] (${s.category}) ${s.content}`)}),n.length&&n.slice(0,15).forEach((s,a)=>{let l=(s.content||"").replace(/\s+/g," ").trim();l&&r.push(`[C${a+1}] ${l.slice(0,2e3)}`)}),!r.length)return"No retrieved evidence \u2014 nothing to synthesize.";let o=`You are answering a question from a personal-memory system.
261
+ Each retrieved item is labeled [F#] (a stored fact) or [C#] (a raw conversation chunk
262
+ that may include user/assistant turns and dates).
263
+
264
+ Question: ${e}
265
+
266
+ Retrieved memory items:
267
+ ${r.join(`
268
+ `)}
269
+
270
+ Instructions:
271
+ - Read the chunks carefully \u2014 the answer is often a specific phrase or date inside one of them, not always pre-summarized as a fact.
272
+ - Reason step-by-step internally for temporal questions ("first", "before", "after", "how many days") \u2014 compare the dates explicitly.
273
+ - Cite items in square brackets where they directly support the answer, e.g. [C2].
274
+ - Only respond "Not in retrieved memory." if you genuinely cannot find the information after carefully reading every chunk. Prefer a careful answer with citation over refusal.
275
+ - Plain text only, no headers. Direct answer first, then a short justification if needed. 1-4 sentences total.`,i=c.search.synthesizeModel||c.llm.extractionModel||void 0;return ke(o,{model:i,caller:"synthesizer"})}async function Ci(e){let t=await J(e.slice(0,8)),n=[];for(let o of t.values())for(let i of o)n.push(i);let r=[...new Set(n)].slice(0,c.hebbian.entity.maxWriteEntities);await Fe(r)}async function Li(e,t={}){if(e==null||e==="global")return null;if(e==="auto"){let r=(await Fn(t)).flatMap(i=>i.scope).filter(i=>typeof i=="string"&&!i.startsWith("__virtual:"));return r.length===0?[]:(await p("pod").whereIn("uid",r).select("id")).map(i=>i.id)}if(Array.isArray(e)){if(e.length===0)return[];if(e.every(o=>typeof o=="number"))return e;let n=e.filter(o=>typeof o=="string");return n.length===0?[]:(await p("pod").where(function(){this.whereIn("uid",n).orWhereIn("name",n)}).select("id")).map(o=>o.id)}return null}async function Pi(e,t){if(e.length<2||e.length>Ni)return null;let n=t[0]||c.defaults.namespace,r=await en(e,n);return r||(await tn(e,{namespace:n,limit:1}))[0]||null}async function Mi(e,t,{namespaces:n,limit:r,minConfidence:o,includeChunks:i,pointInTime:s,categories:a,podIds:l}){let u=xi(t,e),h=await re(u,{inputType:"query"}),[E,m,...d]=await Promise.all([cn(e.id,{limit:r}),hn(e.id,{limit:15}),...u.map((S,ye)=>nr(S,{queryEmbedding:h[ye],namespaces:n,limit:r,minConfidence:o,includeChunks:i,pointInTime:s,categories:a,podIds:l}))]),_=E.map(S=>({...S,source:"entity"})),y=he(d.map(S=>S.facts),r*2),w=new Set(_.map(S=>S.id)),D=y.filter(S=>!w.has(S.id)).map(S=>({...S,source:"search"})),b=[..._,...D].slice(0,r);if(c.hebbian.entity.enabled&&b.length>=2)try{b=await tr(b,{seedEntityIds:[e.id]})}catch(S){console.error("[hebbian-entity-boost]",S.message)}let Ee=i?he(d.map(S=>S.chunks||[]),r):[],_e=m.map(S=>({id:S.entityId,name:S.name,type:S.entityType,relation:S.relationType,direction:S.direction,mentions:S.mentionCount}));return{facts:b,chunks:Ee,matchedEntity:{id:e.id,name:e.name,type:e.entityType,mentions:e.mentionCount,description:e.description||null,aliases:e.aliases||[]},relatedEntities:_e}}function xi(e,t){let n=[e],r=(t.aliases||[]).filter(s=>typeof s=="string"&&s.trim());if(!r.length)return n;let o=(t.name||"").trim(),i=new Set([e.toLowerCase()]);for(let s of r){let a=e;if(o){let l=new RegExp(`\\b${ki(o)}\\b`,"gi");if(l.test(a))a=a.replace(l,s);else{i.has(s.toLowerCase())||(n.push(s),i.add(s.toLowerCase()));continue}}i.has(a.toLowerCase())||(n.push(a),i.add(a.toLowerCase()))}return n}function ki(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function Fi(e,{namespaces:t,limit:n,minConfidence:r,useGraph:o,includeChunks:i,pointInTime:s,expand:a=!1,categories:l,podIds:u}){let h=a?await Dn(e):[e],E=await re(h,{inputType:"query"}),m=await Promise.all(h.map((y,w)=>nr(y,{queryEmbedding:E[w],namespaces:t,limit:n,minConfidence:r,includeChunks:i,pointInTime:s,categories:l,podIds:u}))),d=he(m.map(y=>y.facts),n);if(d=d.map(y=>({...y,source:"search"})),c.hebbian.entity.enabled&&d.length>=2)try{d=await tr(d)}catch(y){console.error("[hebbian-entity-boost]",y.message)}if(o&&d.length)try{let y=await In(d.slice(0,5));if(y.length){let w=await Bi(y.map(b=>b.id)),D=await On(w,{limit:5});d=Tn(d,D,w,n)}}catch(y){console.error("[graph-enhancement] Failed:",y.message)}let _=i?he(m.map(y=>y.chunks),n):[];return{facts:d,chunks:_,matchedEntity:null,relatedEntities:[]}}async function tr(e,t={}){let n=e.map(m=>m.id).filter(Boolean);if(n.length<2)return e;let r=await J(n);if(!r.size)return e;let o,i;if(t.seedEntityIds?.length)o=t.seedEntityIds,i=e;else{let m=t.seedFactCount??3,d=[];for(let _ of e.slice(0,m)){let y=r.get(_.id)||[];for(let w of y)d.push(w)}o=d,i=e.slice(m)}if(!o.length)return e;let s=new Set;for(let m of i){let d=r.get(m.id)||[];for(let _ of d)s.add(_)}if(!s.size)return e;let a=await Be([...new Set(o)],[...s]);if(!a.size)return e;let l=new Map,u=0;for(let m of e){let d=r.get(m.id)||[],_=0;for(let y of d){let w=a.get(y)||0;w>_&&(_=w)}l.set(m.id,_),_>u&&(u=_)}if(u===0)return e;let h=c.hebbian.entity.rrfWeight;return e.map(m=>{let d=(l.get(m.id)||0)/u,_=(m.rrfScore||0)+h*d;return{...m,rrfScore:Math.round(_*100)/100,coRetrievalBoost:Math.round(d*100)/100}}).sort((m,d)=>(d.rrfScore||0)-(m.rrfScore||0))}async function Bi(e){let t=c.hebbian.entity.expandPerSeed;if(!t||!e.length)return e;let{getCoRetrievedEntities:n}=await Promise.resolve().then(()=>(He(),fn)),r=await Promise.all(e.map(i=>n(i,{limit:t}).catch(()=>[]))),o=new Set(e);for(let i of r)for(let s of i)o.add(Number(s.partnerId));return[...o]}function he(e,t){let n={},r={};for(let s of e)for(let[a,l]of s.entries())r[l.id]=l,n[l.id]=(n[l.id]||0)+1/(Xe+a+1);let o=Object.entries(n).sort(([,s],[,a])=>a-s),i=o.length?o[0][1]:1;return o.slice(0,t).map(([s,a])=>({...r[s],rrfScore:Math.round(a/i*100)/100}))}async function nr(e,{queryEmbedding:t,namespaces:n,limit:r,minConfidence:o,includeChunks:i=!1,pointInTime:s,categories:a,podIds:l}){let u=t||await Ce(e,{inputType:"query"}),h=An(e,u,{namespaces:n,limit:r,minConfidence:o,pointInTime:s,categories:a,podIds:l}),E=i?[_n(u,{namespaces:n,limit:r}),gn(e,{namespaces:n,limit:r})]:[],[m,...d]=await Promise.all([h,...E]),_=i&&d.length===2?Hi(d[0],d[1],r):[];return{facts:m,chunks:_}}function Hi(e,t,n){let r={},o={...Ae(e,"id"),...Ae(t,"id")};e.forEach((a,l)=>{r[a.id]=(r[a.id]||0)+Oi/(Xe+l+1)}),t.forEach((a,l)=>{r[a.id]=(r[a.id]||0)+Ti/(Xe+l+1)});let i=Object.entries(r).sort(([a,l],[u,h])=>{if(l!==h)return h-l;let E=o[a]?.importance==="vital"?1:0;return(o[u]?.importance==="vital"?1:0)-E}),s=i.length?i[0][1]:1;return i.slice(0,n).map(([a,l])=>({...o[a],rrfScore:Math.round(l/s*100)/100}))}var Xe,Oi,Ti,Ni,or=f(()=>{ne();Le();g();nn();ce();dn();mn();He();En();ce();yn();wn();bn();Nn();vn();Mn();q();Qn();Ge();A();Xe=20,Oi=1,Ti=.7,Ni=60});var Y="***MASKED***",cr=[/\b(sk-(?:proj-|ant-)?[A-Za-z0-9_\-]{20,})\b/g,/\b(ghp_[A-Za-z0-9]{36,})\b/g,/\b(github_pat_[A-Za-z0-9_]{20,})\b/g,/\b(gho_[A-Za-z0-9]{36,})\b/g,/\b(glpat-[A-Za-z0-9_\-]{20,})\b/g,/\b(xox[baprs]-[A-Za-z0-9\-]{10,})\b/g,/\b(whsec_[A-Za-z0-9]{20,})\b/g,/\b(rk_(?:live|test)_[A-Za-z0-9]{20,})\b/g,/\b(AKIA[A-Z0-9]{16})\b/g,/\b(ASIA[A-Z0-9]{16})\b/g,/\b(eyJ[A-Za-z0-9_\-]{20,}\.[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,})\b/g,/\b([A-Za-z0-9]{24}\.[A-Za-z0-9_\-]{6}\.[A-Za-z0-9_\-]{27})\b/g,/\b(\d{8,12}:[A-Za-z0-9_\-]{35})\b/g],lr=new RegExp(`\\b(api[_-]?key|api[_-]?secret|secret[_-]?key|secret|token|password|passwd|pwd|auth[_-]?token|access[_-]?token|refresh[_-]?token|bearer|private[_-]?key|client[_-]?secret)\\s*[=:]\\s*["']?([^\\s"']{8,})["']?`,"gi"),ur=/(\w+:\/\/)([^:/\s]+):([^@\s]{3,})@/g,dr=["DATABASE_URL","REDIS_URL","MONGODB_URI","MONGO_URI","POSTGRES_URL","DSN","CONNECTION_STRING","ENCRYPTION_KEY","JWT_SECRET","SIGIL_ENCRYPTION_KEY","SESSION_SECRET","WEBHOOK_SECRET"],pr=new RegExp(`\\b(${dr.join("|")})\\s*[=:]\\s*["']?([^\\s"']+)["']?`,"gi");function Qe(e){if(!e||typeof e!="string")return e;let t=e;for(let n of cr)t=t.replace(n,Y);return t=t.replace(lr,(n,r)=>`${r}=${Y}`),t=t.replace(ur,(n,r)=>`${r}${Y}:${Y}@`),t=t.replace(pr,(n,r)=>`${r}=${Y}`),t}P();import{appendFile as Dr,readFile as sa,writeFile as ca,unlink as la}from"node:fs/promises";import{createHash as vr}from"node:crypto";var Cr=ot;async function Se(e,t,n=null){try{let r={ts:new Date().toISOString(),hook:e,error:t?.message||String(t),input_hash:n?Lr(n):null};await Dr(Cr,JSON.stringify(r)+`
276
+ `,"utf8")}catch{}}async function ht(e,t=null){try{let{validateConfig:n}=await Promise.resolve().then(()=>(ft(),mt)),r=n().filter(o=>o.level==="fail");if(r.length===0)return!1;for(let o of r){let i=new Error(`${o.code}: ${o.message} \u2014 fix: ${o.fix}`);await Se(e,i,t)}return!0}catch{return!1}}function Lr(e){try{let t=typeof e=="string"?e:JSON.stringify(e);return vr("sha256").update(t).digest("hex").slice(0,12)}catch{return null}}P();import{resolve as Pr}from"node:path";import{existsSync as Et}from"node:fs";import{config as _t}from"dotenv";function yt(){let e=Pr(process.cwd(),".env");Et(e)&&_t({path:e,quiet:!0}),Et(Q)&&Q!==e&&_t({path:Q,quiet:!0})}yt();var $i=8,Ze=20,Ui=4800;async function Gi(){let e=[];for await(let o of process.stdin)e.push(o);let t=Buffer.concat(e).toString("utf8").trim();if(!t)return G();let n=JSON.parse(t),r=n.prompt||"";if(r.length<$i||await ht("user-prompt-submit",t))return G();try{let{search:o}=await Promise.resolve().then(()=>(or(),rr)),i=(await Promise.resolve().then(()=>(g(),ct))).default,s;try{s=await o(r,{namespaces:[i.defaults.namespace],limit:Ze,useGraph:!1,route:!0,expand:!0,synthesize:!1,podScope:"auto",ctx:{cwd:n.cwd||null,sessionId:n.session_id||null}})}catch(m){process.stderr.write(`[sigil:user-prompt-submit] pod-scoped search failed, retrying global: ${m.message}
277
+ `),s=await o(r,{namespaces:[i.defaults.namespace],limit:Ze,useGraph:!1,route:!0,expand:!0,synthesize:!1,podScope:"global"})}let a=s?.facts||[];if(a.length===0)try{a=(await o(r,{namespaces:[i.defaults.namespace],limit:Ze,useGraph:!1,route:!0,expand:!0,synthesize:!1,podScope:"global"}))?.facts||[]}catch{}if(!a.length)return await(await Promise.resolve().then(()=>(A(),W))).default.destroy(),G();let l=[],u=0;for(let m of a){let d=(m.content||"").length+4;if(l.length>0&&u+d>Ui)break;l.push(m),u+=d}let h=Qe([`Sigil memory (${l.length} relevant facts):`,...l.map(m=>`- ${m.content}`)].join(`
278
+ `));return await(await Promise.resolve().then(()=>(A(),W))).default.destroy(),G(h)}catch(o){process.stderr.write(`[sigil:user-prompt-submit] ${o.message}
279
+ `),await Se("user-prompt-submit",o,t);try{await(await Promise.resolve().then(()=>(A(),W))).default.destroy()}catch{}return G()}}function G(e){let t={hookSpecificOutput:{hookEventName:"UserPromptSubmit",...e&&{additionalContext:e}}};process.stdout.write(JSON.stringify(t))}Gi();