@gencode/agents 0.13.0 → 0.15.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @gencode/agents
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5af5e22: Add an opt-out switch for LLM session title generation. New sessions now generate a conversational title via the flash model by default (unchanged), but you can skip that LLM call for runs that don't need it — for example batch/one-shot jobs, embedded API usage, or CI.
8
+
9
+ - CLI: pass `--disable-title` on `aimax run` or `aimax resume`. It overrides the new env var `AIMAX_DISABLE_TITLE=true`.
10
+ - Programmatic: set `titleGeneration: { enabled: false }` on `AgentRunParams`.
11
+
12
+ When the switch is off, the session still gets a title — it falls back to a truncated version of the first user message, so the session list is never blank. No token cost and no network call happen. The switch controls only title generation; topic segmentation is unaffected. Start-up logs now show the resolved state as `titleGen: enabled|disabled`.
13
+
14
+ ### Patch Changes
15
+
16
+ - cbd1dba: AIMax now treats `LLMRequestError` model failures as retryable transient LLM failures even when the upstream gateway also reports non-retryable-looking metadata such as `BadRequestError` or HTTP 400. Runs still avoid replaying an attempt after assistant text or tool results have already been produced, and the agent log now records why a retry was skipped with fields such as `reason`, `retryableError`, `attemptRecordCount`, `recordsWithToolResults`, and `recordsWithAssistantText`.
17
+ - cbd1dba: AIMax now retries LLM turns when the streaming connection is torn down mid-response by the network or upstream, instead of failing the whole run on the first attempt.
18
+
19
+ Previously, if the HTTP socket was closed while the model was still streaming (for example an upstream gateway or load balancer dropping the connection, surfacing in logs as `streamErrorType="TypeError"`, `streamErrorMessage="terminated"`, `streamErrorCauseCode="UND_ERR_SOCKET"`, or Node errno codes such as `ECONNRESET`/`EPIPE`/`ETIMEDOUT`), the error reached the turn-retry loop without any retryable metadata, so it was treated as a final failure and the run stopped at `attempt=1` even though `maxAttempts` was higher.
20
+
21
+ Such transport-level failures are now recognized as transient and replayed within the existing turn-retry budget (default 3 attempts, exponential backoff). No configuration is required — the new behavior is on by default. User-initiated aborts and genuine non-retryable provider errors (e.g. HTTP 4xx with a real status code) are still not retried, and an attempt is still never replayed once assistant text or tool results have been produced.
22
+
23
+ ## 0.14.0
24
+
25
+ ### Minor Changes
26
+
27
+ - 5773651: Add the `aimax-server` one-shot prestart entry for container deployments. It starts a local HTTP server, warms system-level AIMax runtime state before the user request arrives, accepts one `/run` request with the same run options used by `aimax run`, delegates execution through the CLI path, and exits after the agent loop finishes. The normal `aimax run` command remains available as the cold-path fallback.
28
+
3
29
  ## 0.13.0
4
30
 
5
31
  ### Minor Changes
@@ -1,2 +1,2 @@
1
- import { C as AgentsConfig, S as AgentModelConfig, _ as saveAgentsConfig, a as listAgents, b as AgentBinding, c as normalizeAgentId, d as resolveAgentDir, f as resolveAgentIdByBinding, g as resolveModelString, h as resolveModelFallbacks, i as getAgentConfig, l as removeAgent, m as resolveDefaultAgentId, n as addBinding, o as listBindings, p as resolveAgentsConfigPath, r as aimaxDir, s as loadAgentsConfig, t as addAgent, u as removeBindings, v as updateAgent, x as AgentConfig, y as updateAgentIdentity } from "../index-DGdf27gv.js";
1
+ import { C as AgentsConfig, S as AgentModelConfig, _ as saveAgentsConfig, a as listAgents, b as AgentBinding, c as normalizeAgentId, d as resolveAgentDir, f as resolveAgentIdByBinding, g as resolveModelString, h as resolveModelFallbacks, i as getAgentConfig, l as removeAgent, m as resolveDefaultAgentId, n as addBinding, o as listBindings, p as resolveAgentsConfigPath, r as aimaxDir, s as loadAgentsConfig, t as addAgent, u as removeBindings, v as updateAgent, x as AgentConfig, y as updateAgentIdentity } from "../index-BNCxlrCH.js";
2
2
  export { AgentBinding, AgentConfig, AgentModelConfig, AgentsConfig, addAgent, addBinding, aimaxDir, getAgentConfig, listAgents, listBindings, loadAgentsConfig, normalizeAgentId, removeAgent, removeBindings, resolveAgentDir, resolveAgentIdByBinding, resolveAgentsConfigPath, resolveDefaultAgentId, resolveModelFallbacks, resolveModelString, saveAgentsConfig, updateAgent, updateAgentIdentity };
@@ -1 +1 @@
1
- import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as _,y as v}from"../config-DYv0xUdi.js";export{h as addAgent,u as addBinding,p as aimaxDir,s as getAgentConfig,t as listAgents,d as listBindings,m as loadAgentsConfig,n as normalizeAgentId,c as removeAgent,g as removeBindings,r as resolveAgentDir,i as resolveAgentIdByBinding,f as resolveAgentsConfigPath,l as resolveDefaultAgentId,o as resolveModelFallbacks,a as resolveModelString,e as saveAgentsConfig,_ as updateAgent,v as updateAgentIdentity};
1
+ import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,t as h,u as g,v as _,y as v}from"../config-DDlWxQf7.js";export{h as addAgent,u as addBinding,p as aimaxDir,s as getAgentConfig,t as listAgents,d as listBindings,m as loadAgentsConfig,n as normalizeAgentId,c as removeAgent,g as removeBindings,r as resolveAgentDir,i as resolveAgentIdByBinding,f as resolveAgentsConfigPath,l as resolveDefaultAgentId,o as resolveModelFallbacks,a as resolveModelString,e as saveAgentsConfig,_ as updateAgent,v as updateAgentIdentity};
@@ -1,6 +1,6 @@
1
- import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{A as t,C as n,L as r}from"./session-DIkujhuw.js";import{createRequire as i}from"node:module";import a from"node:fs/promises";import o,{basename as s}from"node:path";import c from"node:crypto";import l from"node:fs";function u(e){return!!(e&&typeof e==`object`&&`code`in e&&e.code===`ENOENT`)}async function d(e){let t;try{t=await a.lstat(e)}catch(e){if(u(e))return{missing:!0};throw e}if(t.isSymbolicLink()||!t.isFile())throw Error(`path required`);return{missing:!1,stat:t}}function f(e){try{l.mkdirSync(e,{recursive:!0})}catch{}return e}function p(e){return e.trim().replace(/^[./]+/,``).replace(/\\/g,`/`)}function m(e){let t=p(e);return t?t===`MEMORY.md`||t===`memory.md`?!0:t.startsWith(`memory/`):!1}async function h(e,t){let n=await a.readdir(e,{withFileTypes:!0});for(let r of n){let n=o.join(e,r.name);if(!r.isSymbolicLink()){if(r.isDirectory()){await h(n,t);continue}r.isFile()&&r.name.endsWith(`.md`)&&t.push(n)}}}async function g(e){let t=[],n=o.join(e,`MEMORY.md`),r=o.join(e,`memory.md`),i=o.join(e,`memory`),s=async e=>{try{let n=await a.lstat(e);if(n.isSymbolicLink()||!n.isFile()||!e.endsWith(`.md`))return;t.push(e)}catch{}};await s(n),await s(r);try{let e=await a.lstat(i);!e.isSymbolicLink()&&e.isDirectory()&&await h(i,t)}catch{}if(t.length<=1)return t;let c=new Set,l=[];for(let e of t){let t=e;try{t=await a.realpath(e)}catch{}c.has(t)||(c.add(t),l.push(e))}return l}function _(e){return c.createHash(`sha256`).update(e).digest(`hex`)}async function ee(e,t){let n;try{n=await a.stat(e)}catch(e){if(u(e))return null;throw e}let r;try{r=await a.readFile(e,`utf-8`)}catch(e){if(u(e))return null;throw e}let i=_(r);return{path:o.relative(t,e).replace(/\\/g,`/`),absPath:e,mtimeMs:n.mtimeMs,size:n.size,hash:i}}function te(e,t){let n=e.split(`
1
+ import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{A as t,C as n,L as r}from"./session-CvZsdTZJ.js";import{o as i,r as a}from"./provider-registry-DPbmbWqS.js";import{createRequire as o}from"node:module";import s from"node:fs/promises";import c,{basename as l}from"node:path";import u from"node:crypto";import d from"node:fs";function f(e){return!!(e&&typeof e==`object`&&`code`in e&&e.code===`ENOENT`)}async function p(e){let t;try{t=await s.lstat(e)}catch(e){if(f(e))return{missing:!0};throw e}if(t.isSymbolicLink()||!t.isFile())throw Error(`path required`);return{missing:!1,stat:t}}function m(e){try{d.mkdirSync(e,{recursive:!0})}catch{}return e}function ee(e){return e.trim().replace(/^[./]+/,``).replace(/\\/g,`/`)}function h(e){let t=ee(e);return t?t===`MEMORY.md`||t===`memory.md`?!0:t.startsWith(`memory/`):!1}async function g(e,t){let n=await s.readdir(e,{withFileTypes:!0});for(let r of n){let n=c.join(e,r.name);if(!r.isSymbolicLink()){if(r.isDirectory()){await g(n,t);continue}r.isFile()&&r.name.endsWith(`.md`)&&t.push(n)}}}async function _(e){let t=[],n=c.join(e,`MEMORY.md`),r=c.join(e,`memory.md`),i=c.join(e,`memory`),a=async e=>{try{let n=await s.lstat(e);if(n.isSymbolicLink()||!n.isFile()||!e.endsWith(`.md`))return;t.push(e)}catch{}};await a(n),await a(r);try{let e=await s.lstat(i);!e.isSymbolicLink()&&e.isDirectory()&&await g(i,t)}catch{}if(t.length<=1)return t;let o=new Set,l=[];for(let e of t){let t=e;try{t=await s.realpath(e)}catch{}o.has(t)||(o.add(t),l.push(e))}return l}function v(e){return u.createHash(`sha256`).update(e).digest(`hex`)}async function te(e,t){let n;try{n=await s.stat(e)}catch(e){if(f(e))return null;throw e}let r;try{r=await s.readFile(e,`utf-8`)}catch(e){if(f(e))return null;throw e}let i=v(r);return{path:c.relative(t,e).replace(/\\/g,`/`),absPath:e,mtimeMs:n.mtimeMs,size:n.size,hash:i}}function ne(e,t){let n=e.split(`
2
2
  `);if(n.length===0)return[];let r=Math.max(32,t.tokens*4),i=Math.max(0,t.overlap*4),a=[],o=[],s=0,c=()=>{if(o.length===0)return;let e=o[0],t=o[o.length-1];if(!e||!t)return;let n=o.map(e=>e.line).join(`
3
- `),r=e.lineNo,i=t.lineNo;a.push({startLine:r,endLine:i,text:n,hash:_(n)})},l=()=>{if(i<=0||o.length===0){o=[],s=0;return}let e=0,t=[];for(let n=o.length-1;n>=0;--n){let r=o[n];if(r&&(e+=r.line.length+1,t.unshift(r),e>=i))break}o=t,s=t.reduce((e,t)=>e+t.line.length+1,0)};for(let e=0;e<n.length;e+=1){let t=n[e]??``,i=e+1,a=[];if(t.length===0)a.push(``);else for(let e=0;e<t.length;e+=r)a.push(t.slice(e,e+r));for(let e of a){let t=e.length+1;s+t>r&&o.length>0&&(c(),l()),o.push({line:e,lineNo:i}),s+=t}}return c(),a}function ne(e,t){if(!(!t||t.length===0))for(let n of e)n.startLine=t[n.startLine-1]??n.startLine,n.endLine=t[n.endLine-1]??n.endLine}function v(e){try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function re(e,t){if(e.length===0||t.length===0)return 0;let n=Math.min(e.length,t.length),r=0,i=0,a=0;for(let o=0;o<n;o+=1){let n=e[o]??0,s=t[o]??0;r+=n*s,i+=n*n,a+=s*s}return i===0||a===0?0:r/(Math.sqrt(i)*Math.sqrt(a))}async function y(e){try{let t=await import(`sqlite-vec`),n=(e.extensionPath?.trim()?e.extensionPath.trim():void 0)??t.getLoadablePath();return n?e.db.loadExtension(n):t.load(e.db),{ok:!0,extensionPath:n}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}const b=i(import.meta.url);function ie(){return globalThis.Bun!==void 0}function ae(){try{return b(`node:sqlite`)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`SQLite support is unavailable in this Node runtime (missing node:sqlite). ${t}`,{cause:e})}}var oe=class{constructor(e){this.stmt=e}all(...e){return this.stmt.all(...e)}get(...e){return this.stmt.get(...e)}run(...e){this.stmt.run(...e)}},se=class{db;constructor(e,t){let n=b(`bun:sqlite`);this.db=new(n.Database??n.default?.Database)(e)}exec(e){this.db.run(e)}prepare(e){return new oe(this.db.prepare(e))}loadExtension(e){this.db.loadExtension(e)}close(){this.db.close()}},ce=class{stmt;constructor(e){this.stmt=e}all(...e){return this.stmt.all(...e)}get(...e){return this.stmt.get(...e)}run(...e){this.stmt.run(...e)}},le=class{db;constructor(e,t){let{DatabaseSync:n}=ae();this.db=new n(e,{allowExtension:t?.allowExtension})}exec(e){this.db.exec(e)}prepare(e){return new ce(this.db.prepare(e))}loadExtension(e){this.db.loadExtension(e)}close(){this.db.close()}};function x(e,t){return ie()?new se(e,t):new le(e,t)}function ue(e){return(e.toLowerCase().match(/[\p{L}\p{N}_]+/gu)??[]).filter(Boolean)}function de(e){return c.createHash(`sha256`).update(e).digest().readUInt32BE(0)}function S(e,t=384){let n=Array(t).fill(0),r=ue(e);if(r.length===0)return n;for(let e of r){let r=de(e)%t;n[r]+=1}let i=Math.sqrt(n.reduce((e,t)=>e+t*t,0));if(i>0)for(let e=0;e<n.length;e+=1)n[e]=n[e]/i;return n}function C(e){let t=e?.model?.trim()||`mock-embedding-v1`,n=e?.dimensions??384;return{id:`external-mock`,model:t,embedQuery:async e=>S(e,n),embedBatch:async e=>e.map(e=>S(e,n))}}const w=new class{providers=new Map;byPluginId=new Map;register(e){this.providers.set(e.id,e),e.pluginId&&this.byPluginId.set(e.pluginId,e.id)}getById(e){return this.providers.get(e)}getByPluginId(e){let t=this.byPluginId.get(e);return t?this.providers.get(t):void 0}clear(){this.providers.clear(),this.byPluginId.clear()}};function fe(e){let t=e.id?.trim()||e.pluginId;return w.register({id:t,pluginId:e.pluginId,create:e.create,config:e.config,rootDir:e.rootDir,source:e.source}),t}function T(e){let t=e.providerId?.trim(),n=e.pluginId?.trim(),r=(t?w.getById(t):void 0)??(n?w.getByPluginId(n):void 0);return r?{provider:r.create({dataDir:e.dataDir,memoryDir:e.memoryDir,pluginId:r.pluginId,config:r.config,rootDir:r.rootDir,source:r.source}),registration:r}:null}function pe(){w.clear()}const E={enabled:!1,lambda:.7};function D(e){let t=e.toLowerCase().match(/[a-z0-9_]+/g)??[];return new Set(t)}function me(e,t){if(e.size===0&&t.size===0)return 1;if(e.size===0||t.size===0)return 0;let n=0,r=e.size<=t.size?e:t,i=e.size<=t.size?t:e;for(let e of r)i.has(e)&&n++;let a=e.size+t.size-n;return a===0?0:n/a}function he(e,t,n){if(t.length===0)return 0;let r=0,i=n.get(e.id)??D(e.content);for(let e of t){let t=me(i,n.get(e.id)??D(e.content));t>r&&(r=t)}return r}function ge(e,t,n){return n*e-(1-n)*t}function _e(e,t={}){let{enabled:n=E.enabled,lambda:r=E.lambda}=t;if(!n||e.length<=1)return[...e];let i=Math.max(0,Math.min(1,r));if(i===1)return e.slice().sort((e,t)=>t.score-e.score);let a=new Map;for(let t of e)a.set(t.id,D(t.content));let o=Math.max(...e.map(e=>e.score)),s=Math.min(...e.map(e=>e.score)),c=o-s,l=e=>c===0?1:(e-s)/c,u=[],d=new Set(e);for(;d.size>0;){let e=null,t=-1/0;for(let n of d){let r=ge(l(n.score),he(n,u,a),i);(r>t||r===t&&n.score>(e?.score??-1/0))&&(t=r,e=n)}if(e)u.push(e),d.delete(e);else break}return u}function ve(e,t={}){if(e.length===0)return e;let n=new Map;return _e(e.map((e,t)=>{let r=`${e.path}:${e.startLine}:${t}`;return n.set(r,e),{id:r,score:e.score,content:e.snippet}}),t).map(e=>n.get(e.id))}const O={enabled:!1,halfLifeDays:30},k=/(?:^|\/)(?:memory)\/(\d{4})-(\d{2})-(\d{2})\.md$/;function ye(e){return!Number.isFinite(e)||e<=0?0:Math.LN2/e}function be(e){let t=ye(e.halfLifeDays),n=Math.max(0,e.ageInDays);return t<=0||!Number.isFinite(n)?1:Math.exp(-t*n)}function xe(e){return e.score*be(e)}function Se(e){let t=e.replaceAll(`\\`,`/`).replace(/^\.\//,``),n=k.exec(t);if(!n)return null;let r=Number(n[1]),i=Number(n[2]),a=Number(n[3]);if(!Number.isInteger(r)||!Number.isInteger(i)||!Number.isInteger(a))return null;let o=Date.UTC(r,i-1,a),s=new Date(o);return s.getUTCFullYear()!==r||s.getUTCMonth()!==i-1||s.getUTCDate()!==a?null:s}function Ce(e){let t=e.replaceAll(`\\`,`/`).replace(/^\.\//,``);return t===`MEMORY.md`||t===`memory.md`?!0:t.startsWith(`memory/`)?!k.test(t):!1}async function we(e){let t=Se(e.filePath);if(t)return t;if(e.source===`memory`&&Ce(e.filePath)||!e.memoryRoot)return null;let n=o.isAbsolute(e.filePath)?e.filePath:o.resolve(e.memoryRoot,e.filePath);try{let e=await a.stat(n);return Number.isFinite(e.mtimeMs)?new Date(e.mtimeMs):null}catch{return null}}function Te(e,t){return Math.max(0,t-e.getTime())/864e5}async function Ee(e){let t={...O,...e.temporalDecay};if(!t.enabled)return[...e.results];let n=e.nowMs??Date.now(),r=new Map;return Promise.all(e.results.map(async i=>{let a=`${i.source}:${i.path}`,o=r.get(a);o||(o=we({filePath:i.path,source:i.source,memoryRoot:e.memoryRoot}),r.set(a,o));let s=await o;if(!s)return i;let c=xe({score:i.score,ageInDays:Te(s,n),halfLifeDays:t.halfLifeDays});return{...i,score:c}}))}function De(e){let t=e.match(/[\p{L}\p{N}_]+/gu)?.map(e=>e.trim()).filter(Boolean)??[];return t.length===0?null:t.map(e=>`"${e.replaceAll(`"`,``)}"`).join(` AND `)}function Oe(e){return 1/(1+(Number.isFinite(e)?Math.max(0,e):999))}async function ke(e){let t=new Map;for(let n of e.vector)t.set(n.id,{id:n.id,path:n.path,startLine:n.startLine,endLine:n.endLine,source:n.source,snippet:n.snippet,vectorScore:n.vectorScore,textScore:0});for(let n of e.keyword){let e=t.get(n.id);e?(e.textScore=n.textScore,n.snippet&&n.snippet.length>0&&(e.snippet=n.snippet)):t.set(n.id,{id:n.id,path:n.path,startLine:n.startLine,endLine:n.endLine,source:n.source,snippet:n.snippet,vectorScore:0,textScore:n.textScore})}let n=(await Ee({results:Array.from(t.values()).map(t=>{let n=e.vectorWeight*t.vectorScore+e.textWeight*t.textScore;return{path:t.path,startLine:t.startLine,endLine:t.endLine,score:n,snippet:t.snippet,source:t.source}}),temporalDecay:{...O,...e.temporalDecay},memoryRoot:e.memoryRoot,nowMs:e.nowMs})).slice().sort((e,t)=>t.score-e.score),r={...E,...e.mmr};return r.enabled?ve(n,r):n}function Ae(e){e.db.exec(`
3
+ `),r=e.lineNo,i=t.lineNo;a.push({startLine:r,endLine:i,text:n,hash:v(n)})},l=()=>{if(i<=0||o.length===0){o=[],s=0;return}let e=0,t=[];for(let n=o.length-1;n>=0;--n){let r=o[n];if(r&&(e+=r.line.length+1,t.unshift(r),e>=i))break}o=t,s=t.reduce((e,t)=>e+t.line.length+1,0)};for(let e=0;e<n.length;e+=1){let t=n[e]??``,i=e+1,a=[];if(t.length===0)a.push(``);else for(let e=0;e<t.length;e+=r)a.push(t.slice(e,e+r));for(let e of a){let t=e.length+1;s+t>r&&o.length>0&&(c(),l()),o.push({line:e,lineNo:i}),s+=t}}return c(),a}function re(e,t){if(!(!t||t.length===0))for(let n of e)n.startLine=t[n.startLine-1]??n.startLine,n.endLine=t[n.endLine-1]??n.endLine}function y(e){try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function ie(e,t){if(e.length===0||t.length===0)return 0;let n=Math.min(e.length,t.length),r=0,i=0,a=0;for(let o=0;o<n;o+=1){let n=e[o]??0,s=t[o]??0;r+=n*s,i+=n*n,a+=s*s}return i===0||a===0?0:r/(Math.sqrt(i)*Math.sqrt(a))}async function b(e){try{let t=await import(`sqlite-vec`),n=(e.extensionPath?.trim()?e.extensionPath.trim():void 0)??t.getLoadablePath();return n?e.db.loadExtension(n):t.load(e.db),{ok:!0,extensionPath:n}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}const x=o(import.meta.url);function ae(){return globalThis.Bun!==void 0}function oe(){try{return x(`node:sqlite`)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`SQLite support is unavailable in this Node runtime (missing node:sqlite). ${t}`,{cause:e})}}var se=class{constructor(e){this.stmt=e}all(...e){return this.stmt.all(...e)}get(...e){return this.stmt.get(...e)}run(...e){this.stmt.run(...e)}},ce=class{db;constructor(e,t){let n=x(`bun:sqlite`);this.db=new(n.Database??n.default?.Database)(e)}exec(e){this.db.run(e)}prepare(e){return new se(this.db.prepare(e))}loadExtension(e){this.db.loadExtension(e)}close(){this.db.close()}},le=class{stmt;constructor(e){this.stmt=e}all(...e){return this.stmt.all(...e)}get(...e){return this.stmt.get(...e)}run(...e){this.stmt.run(...e)}},ue=class{db;constructor(e,t){let{DatabaseSync:n}=oe();this.db=new n(e,{allowExtension:t?.allowExtension})}exec(e){this.db.exec(e)}prepare(e){return new le(this.db.prepare(e))}loadExtension(e){this.db.loadExtension(e)}close(){this.db.close()}};function S(e,t){return ae()?new ce(e,t):new ue(e,t)}function de(e){return(e.toLowerCase().match(/[\p{L}\p{N}_]+/gu)??[]).filter(Boolean)}function fe(e){return u.createHash(`sha256`).update(e).digest().readUInt32BE(0)}function C(e,t=384){let n=Array(t).fill(0),r=de(e);if(r.length===0)return n;for(let e of r){let r=fe(e)%t;n[r]+=1}let i=Math.sqrt(n.reduce((e,t)=>e+t*t,0));if(i>0)for(let e=0;e<n.length;e+=1)n[e]=n[e]/i;return n}function w(e){let t=e?.model?.trim()||`mock-embedding-v1`,n=e?.dimensions??384;return{id:`external-mock`,model:t,embedQuery:async e=>C(e,n),embedBatch:async e=>e.map(e=>C(e,n))}}const T={enabled:!1,lambda:.7};function E(e){let t=e.toLowerCase().match(/[a-z0-9_]+/g)??[];return new Set(t)}function pe(e,t){if(e.size===0&&t.size===0)return 1;if(e.size===0||t.size===0)return 0;let n=0,r=e.size<=t.size?e:t,i=e.size<=t.size?t:e;for(let e of r)i.has(e)&&n++;let a=e.size+t.size-n;return a===0?0:n/a}function me(e,t,n){if(t.length===0)return 0;let r=0,i=n.get(e.id)??E(e.content);for(let e of t){let t=pe(i,n.get(e.id)??E(e.content));t>r&&(r=t)}return r}function he(e,t,n){return n*e-(1-n)*t}function ge(e,t={}){let{enabled:n=T.enabled,lambda:r=T.lambda}=t;if(!n||e.length<=1)return[...e];let i=Math.max(0,Math.min(1,r));if(i===1)return e.slice().sort((e,t)=>t.score-e.score);let a=new Map;for(let t of e)a.set(t.id,E(t.content));let o=Math.max(...e.map(e=>e.score)),s=Math.min(...e.map(e=>e.score)),c=o-s,l=e=>c===0?1:(e-s)/c,u=[],d=new Set(e);for(;d.size>0;){let e=null,t=-1/0;for(let n of d){let r=he(l(n.score),me(n,u,a),i);(r>t||r===t&&n.score>(e?.score??-1/0))&&(t=r,e=n)}if(e)u.push(e),d.delete(e);else break}return u}function _e(e,t={}){if(e.length===0)return e;let n=new Map;return ge(e.map((e,t)=>{let r=`${e.path}:${e.startLine}:${t}`;return n.set(r,e),{id:r,score:e.score,content:e.snippet}}),t).map(e=>n.get(e.id))}const D={enabled:!1,halfLifeDays:30},O=/(?:^|\/)(?:memory)\/(\d{4})-(\d{2})-(\d{2})\.md$/;function ve(e){return!Number.isFinite(e)||e<=0?0:Math.LN2/e}function ye(e){let t=ve(e.halfLifeDays),n=Math.max(0,e.ageInDays);return t<=0||!Number.isFinite(n)?1:Math.exp(-t*n)}function be(e){return e.score*ye(e)}function xe(e){let t=e.replaceAll(`\\`,`/`).replace(/^\.\//,``),n=O.exec(t);if(!n)return null;let r=Number(n[1]),i=Number(n[2]),a=Number(n[3]);if(!Number.isInteger(r)||!Number.isInteger(i)||!Number.isInteger(a))return null;let o=Date.UTC(r,i-1,a),s=new Date(o);return s.getUTCFullYear()!==r||s.getUTCMonth()!==i-1||s.getUTCDate()!==a?null:s}function Se(e){let t=e.replaceAll(`\\`,`/`).replace(/^\.\//,``);return t===`MEMORY.md`||t===`memory.md`?!0:t.startsWith(`memory/`)?!O.test(t):!1}async function Ce(e){let t=xe(e.filePath);if(t)return t;if(e.source===`memory`&&Se(e.filePath)||!e.memoryRoot)return null;let n=c.isAbsolute(e.filePath)?e.filePath:c.resolve(e.memoryRoot,e.filePath);try{let e=await s.stat(n);return Number.isFinite(e.mtimeMs)?new Date(e.mtimeMs):null}catch{return null}}function k(e,t){return Math.max(0,t-e.getTime())/864e5}async function A(e){let t={...D,...e.temporalDecay};if(!t.enabled)return[...e.results];let n=e.nowMs??Date.now(),r=new Map;return Promise.all(e.results.map(async i=>{let a=`${i.source}:${i.path}`,o=r.get(a);o||(o=Ce({filePath:i.path,source:i.source,memoryRoot:e.memoryRoot}),r.set(a,o));let s=await o;if(!s)return i;let c=be({score:i.score,ageInDays:k(s,n),halfLifeDays:t.halfLifeDays});return{...i,score:c}}))}function we(e){let t=e.match(/[\p{L}\p{N}_]+/gu)?.map(e=>e.trim()).filter(Boolean)??[];return t.length===0?null:t.map(e=>`"${e.replaceAll(`"`,``)}"`).join(` AND `)}function Te(e){return 1/(1+(Number.isFinite(e)?Math.max(0,e):999))}async function Ee(e){let t=new Map;for(let n of e.vector)t.set(n.id,{id:n.id,path:n.path,startLine:n.startLine,endLine:n.endLine,source:n.source,snippet:n.snippet,vectorScore:n.vectorScore,textScore:0});for(let n of e.keyword){let e=t.get(n.id);e?(e.textScore=n.textScore,n.snippet&&n.snippet.length>0&&(e.snippet=n.snippet)):t.set(n.id,{id:n.id,path:n.path,startLine:n.startLine,endLine:n.endLine,source:n.source,snippet:n.snippet,vectorScore:0,textScore:n.textScore})}let n=(await A({results:Array.from(t.values()).map(t=>{let n=e.vectorWeight*t.vectorScore+e.textWeight*t.textScore;return{path:t.path,startLine:t.startLine,endLine:t.endLine,score:n,snippet:t.snippet,source:t.source}}),temporalDecay:{...D,...e.temporalDecay},memoryRoot:e.memoryRoot,nowMs:e.nowMs})).slice().sort((e,t)=>t.score-e.score),r={...T,...e.mmr};return r.enabled?_e(n,r):n}function De(e){e.db.exec(`
4
4
  CREATE TABLE IF NOT EXISTS meta (
5
5
  key TEXT PRIMARY KEY,
6
6
  value TEXT NOT NULL
@@ -37,35 +37,35 @@ import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{A as t,C as n,L as r}f
37
37
  updated_at INTEGER NOT NULL,
38
38
  PRIMARY KEY (provider, model, provider_key, hash)
39
39
  );
40
- `),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_embedding_cache_updated_at ON ${e.embeddingCacheTable}(updated_at);`);let t=!1,n;if(e.ftsEnabled)try{e.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${e.ftsTable} USING fts5(\n text,\n id UNINDEXED,\n path UNINDEXED,\n source UNINDEXED,\n model UNINDEXED,\n start_line UNINDEXED,\n end_line UNINDEXED\n);`),t=!0}catch(e){let r=e instanceof Error?e.message:String(e);t=!1,n=r}return A(e.db,`files`,`source`,`TEXT NOT NULL DEFAULT 'memory'`),A(e.db,`chunks`,`source`,`TEXT NOT NULL DEFAULT 'memory'`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path);`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_source ON chunks(source);`),{ftsAvailable:t,...n?{ftsError:n}:{}}}function A(e,t,n,r){e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)||e.exec(`ALTER TABLE ${t} ADD COLUMN ${n} ${r}`)}function j(e,t){return e.length<=t?e:e.slice(0,t)}const je=e=>Buffer.from(new Float32Array(e).buffer);async function Me(e){return e.queryVec.length===0||e.limit<=0?[]:await e.ensureVectorReady(e.queryVec.length)?e.db.prepare(`SELECT c.id, c.path, c.start_line, c.end_line, c.text,
40
+ `),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_embedding_cache_updated_at ON ${e.embeddingCacheTable}(updated_at);`);let t=!1,n;if(e.ftsEnabled)try{e.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${e.ftsTable} USING fts5(\n text,\n id UNINDEXED,\n path UNINDEXED,\n source UNINDEXED,\n model UNINDEXED,\n start_line UNINDEXED,\n end_line UNINDEXED\n);`),t=!0}catch(e){let r=e instanceof Error?e.message:String(e);t=!1,n=r}return j(e.db,`files`,`source`,`TEXT NOT NULL DEFAULT 'memory'`),j(e.db,`chunks`,`source`,`TEXT NOT NULL DEFAULT 'memory'`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_path ON chunks(path);`),e.db.exec(`CREATE INDEX IF NOT EXISTS idx_chunks_source ON chunks(source);`),{ftsAvailable:t,...n?{ftsError:n}:{}}}function j(e,t,n,r){e.prepare(`PRAGMA table_info(${t})`).all().some(e=>e.name===n)||e.exec(`ALTER TABLE ${t} ADD COLUMN ${n} ${r}`)}function M(e,t){return e.length<=t?e:e.slice(0,t)}const Oe=e=>Buffer.from(new Float32Array(e).buffer);async function ke(e){return e.queryVec.length===0||e.limit<=0?[]:await e.ensureVectorReady(e.queryVec.length)?e.db.prepare(`SELECT c.id, c.path, c.start_line, c.end_line, c.text,
41
41
  c.source,
42
42
  vec_distance_cosine(v.embedding, ?) AS dist
43
- FROM ${e.vectorTable} v\n JOIN chunks c ON c.id = v.id\n WHERE c.model = ?${e.sourceFilterVec.sql}\n ORDER BY dist ASC\n LIMIT ?`).all(je(e.queryVec),e.providerModel,...e.sourceFilterVec.params,e.limit).map(t=>({id:t.id,path:t.path,startLine:t.start_line,endLine:t.end_line,score:1-t.dist,snippet:j(t.text,e.snippetMaxChars),source:t.source})):Ne({db:e.db,providerModel:e.providerModel,sourceFilter:e.sourceFilterChunks}).map(t=>({chunk:t,score:re(e.queryVec,t.embedding)})).filter(e=>Number.isFinite(e.score)).slice().sort((e,t)=>t.score-e.score).slice(0,e.limit).map(t=>({id:t.chunk.id,path:t.chunk.path,startLine:t.chunk.startLine,endLine:t.chunk.endLine,score:t.score,snippet:j(t.chunk.text,e.snippetMaxChars),source:t.chunk.source}))}function Ne(e){return e.db.prepare(`SELECT id, path, start_line, end_line, text, embedding, source
43
+ FROM ${e.vectorTable} v\n JOIN chunks c ON c.id = v.id\n WHERE c.model = ?${e.sourceFilterVec.sql}\n ORDER BY dist ASC\n LIMIT ?`).all(Oe(e.queryVec),e.providerModel,...e.sourceFilterVec.params,e.limit).map(t=>({id:t.id,path:t.path,startLine:t.start_line,endLine:t.end_line,score:1-t.dist,snippet:M(t.text,e.snippetMaxChars),source:t.source})):Ae({db:e.db,providerModel:e.providerModel,sourceFilter:e.sourceFilterChunks}).map(t=>({chunk:t,score:ie(e.queryVec,t.embedding)})).filter(e=>Number.isFinite(e.score)).slice().sort((e,t)=>t.score-e.score).slice(0,e.limit).map(t=>({id:t.chunk.id,path:t.chunk.path,startLine:t.chunk.startLine,endLine:t.chunk.endLine,score:t.score,snippet:M(t.chunk.text,e.snippetMaxChars),source:t.chunk.source}))}function Ae(e){return e.db.prepare(`SELECT id, path, start_line, end_line, text, embedding, source
44
44
  FROM chunks
45
- WHERE model = ?${e.sourceFilter.sql}`).all(e.providerModel,...e.sourceFilter.params).map(e=>({id:e.id,path:e.path,startLine:e.start_line,endLine:e.end_line,text:e.text,embedding:v(e.embedding),source:e.source}))}async function Pe(e){if(e.limit<=0)return[];let t=e.buildFtsQuery(e.query);if(!t)return[];let n=e.providerModel?` AND model = ?`:``,r=e.providerModel?[e.providerModel]:[];return e.db.prepare(`SELECT id, path, source, start_line, end_line, text,\n bm25(${e.ftsTable}) AS rank\n FROM ${e.ftsTable}\n WHERE ${e.ftsTable} MATCH ?${n}${e.sourceFilter.sql}\n ORDER BY rank ASC\n LIMIT ?`).all(t,...r,...e.sourceFilter.params,e.limit).map(t=>{let n=e.bm25RankToScore(t.rank);return{id:t.id,path:t.path,startLine:t.start_line,endLine:t.end_line,score:n,textScore:n,snippet:j(t.text,e.snippetMaxChars),source:t.source}})}const M={chunkTokens:400,chunkOverlap:80,maxResults:6,minScore:.2,fallback:{enabled:!0},embedding:{},experimental:{sessionMemory:!1},sources:[`memory`],store:{sessionStoreName:void 0,vector:{enabled:!0}},hybrid:{enabled:!0,vectorWeight:.7,textWeight:.3,candidateMultiplier:4,mmr:{enabled:!1,lambda:.7},temporalDecay:{enabled:!1,halfLifeDays:30}},cache:{enabled:!0,maxEntries:5e4},sync:{onSessionStart:!0,onSearch:!0,watch:!0,watchDebounceMs:1500,sessions:{deltaBytes:1e5,deltaMessages:50}},citations:`auto`};function Fe(e,n,r){let i=t(e,{storeName:r});return o.relative(i,n).replace(/\\/g,`/`)}async function Ie(e,n){let r=t(e,{storeName:n});try{let e=await a.readdir(r,{withFileTypes:!0}),t=[];for(let n of e){if(!n.isDirectory())continue;let e=o.join(r,n.name,`transcript.jsonl`);try{(await a.stat(e)).isFile()&&t.push(e)}catch{}}return t}catch(e){if(u(e))return[];throw e}}function Le(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>typeof e==`string`?e:e&&typeof e==`object`&&`text`in e?String(e.text??``):``).filter(Boolean).join(` `):e?String(e):``}async function Re(e,t,i){let s;try{s=await a.stat(t)}catch(e){if(u(e))return null;throw e}let c;try{let e=await r(t);if(e===null)return null;c=e}catch(e){if(u(e))return null;throw e}let l=[],d=[],f=c.split(`
46
- `);for(let e=0;e<f.length;e+=1){let t=f[e]?.trim();if(t)try{let n=JSON.parse(t),r=n.role??`unknown`,i=Le(n.content);if(!i)continue;let a=i.split(`
47
- `);for(let t of a)l.push(`[${r}] ${t}`),d.push(e+1)}catch{}}let p=l.join(`
48
- `),m=_(p);return{path:o.join(n(i),Fe(e,t,i)).replace(/\\/g,`/`),absPath:t,mtimeMs:s.mtimeMs,size:s.size,hash:m,content:p,lineMap:d}}const N=`chunks_vec`,P=`chunks_fts`,F=`embedding_cache`,I=`memory_index_meta_v1`,L=3e4;function ze(e,t,n){let r=t.split(`
49
- `);for(let t of r){let n=t.match(/^##\s+(.+)$/);if(n?.[1])return`${e}#${n[1].trim()}`}return`${e}#L${n}`}const R=new Map,Be=[`database disk image is malformed`,`database disk image malformed`,`file is not a database`,`database disk image is corrupt`,`sqlite_corrupt`];function z(e){let t=`${typeof e==`object`&&e&&`code`in e?String(e.code??``).toLowerCase():``} ${e instanceof Error?e.message:String(e)}`.toLowerCase();return Be.some(e=>t.includes(e))}function Ve(e){let t=`${e}.corrupt-${new Date().toISOString().replace(/[:.]/g,`-`)}`,n=!1;for(let r of[``,`-wal`,`-shm`]){let i=`${e}${r}`,a=`${t}${r}`;try{if(!l.existsSync(i))continue;l.renameSync(i,a),n=!0}catch{try{l.rmSync(i,{force:!0}),n=!0}catch{}}}return n?t:null}function He(e,t){let r=n(t.store.sessionStoreName),i=[...t.sources].sort().join(`,`),a=t.experimental.sessionMemory?`sessions-on`:`sessions-off`,o=t.store.vector.enabled?`vector-on`:`vector-off`;return[e,`store=${r}`,`sources=${i}`,a,o].join(`::`)}function B(e,t){let n={...e,...t,hybrid:{...e.hybrid,...t?.hybrid??{}},cache:{...e.cache,...t?.cache??{}},sync:{...e.sync,...t?.sync??{}},experimental:{...e.experimental,...t?.experimental??{}},sources:t?.sources??e.sources,embedding:{...e.embedding,...t?.embedding??{}},store:{...e.store,...t?.store??{},vector:{...e.store.vector,...t?.store?.vector??{}}}};return n.experimental.sessionMemory&&!n.sources.includes(`sessions`)&&(n.sources=[...n.sources,`sessions`]),n}var V=class e{dataDir;memoryRoot;storePath;config;sessionStoreName;provider;providerKey;embeddingProviderId;db;dirty=!0;ftsAvailable=!1;ftsError;vector={enabled:!0,available:null,extensionPath:void 0,loadError:void 0,dims:void 0};vectorReady=null;watchers=[];watchTimer=null;sessionWatchTimer=null;sessionsDirty=!1;sessionsDirtyFiles=new Set;sessionPendingFiles=new Set;searchFallbackOnly=!1;lastRebuildSummary;sessionDeltas=new Map;static get(t,n){let r=o.join(t,`.aimax`),i=B(M,n),a=He(r,i),s=R.get(a);if(s)return n&&s.applyConfig(n),s;let c=new e(t,r,i);return R.set(a,c),c}static disposeForDataDir(e){let t=o.join(e,`.aimax`),n=0;for(let[e,r]of R.entries())e.startsWith(`${t}::`)&&(r.dispose(),R.delete(e),n+=1);return n}static disposeAll(){let e=0;for(let[t,n]of R.entries())n.dispose(),R.delete(t),e+=1;return e}constructor(e,t,r){this.dataDir=e,this.memoryRoot=t,this.storePath=o.join(t,`.index.sqlite`),this.config=B(M,r),this.sessionStoreName=n(this.config.store.sessionStoreName),this.provider=C(),this.providerKey=this.computeProviderKey(),this.applyEmbeddingProvider(),this.vector.enabled=this.config.store.vector.enabled,this.vector.extensionPath=this.config.store.vector.extensionPath,this.db=this.openRecoveredDatabase(),this.ensureWatcher(),this.ensureSessionListener(),this.dirty=!0}applyConfig(e){this.config=B(this.config,e),this.sessionStoreName=n(this.config.store.sessionStoreName),this.applyEmbeddingProvider(),this.vector.enabled=this.config.store.vector.enabled,this.vector.extensionPath=this.config.store.vector.extensionPath,this.ensureWatcher(),this.ensureSessionListener()}warmSession(){this.config.sync.onSessionStart&&this.sync({reason:`session-start`}).catch(()=>{})}noteSessionUpdate(e){this.scheduleSessionDirty(e)}dispose(){this.watchTimer&&=(clearTimeout(this.watchTimer),null),this.sessionWatchTimer&&=(clearTimeout(this.sessionWatchTimer),null);for(let e of this.watchers.splice(0))try{e.close()}catch{}this.sessionPendingFiles.clear(),this.sessionsDirtyFiles.clear(),this.sessionDeltas.clear();try{this.db.close()}catch{}}status(){let e=this.buildSourceFilter(),t=this.db.prepare(`SELECT COUNT(*) as c FROM files WHERE 1=1${e.sql}`).get(...e.params),n=this.db.prepare(`SELECT COUNT(*) as c FROM chunks WHERE 1=1${e.sql}`).get(...e.params),r=(()=>{let t=Array.from(this.config.sources);if(t.length===0)return[];let n=new Map;for(let e of t)n.set(e,{files:0,chunks:0});let r=this.db.prepare(`SELECT source, COUNT(*) as c FROM files WHERE 1=1${e.sql} GROUP BY source`).all(...e.params);for(let e of r){let t=n.get(e.source)??{files:0,chunks:0};t.files=e.c??0,n.set(e.source,t)}let i=this.db.prepare(`SELECT source, COUNT(*) as c FROM chunks WHERE 1=1${e.sql} GROUP BY source`).all(...e.params);for(let e of i){let t=n.get(e.source)??{files:0,chunks:0};t.chunks=e.c??0,n.set(e.source,t)}return t.map(e=>Object.assign({source:e},n.get(e)))})(),i=this.provider?`hybrid`:`fts-only`,a=this.config.cache.enabled?this.db.prepare(`SELECT COUNT(*) as c FROM ${F}`).get()?.c??0:void 0;return{backend:`builtin`,files:t?.c??0,chunks:n?.c??0,dirty:this.dirty||this.sessionsDirty,workspaceDir:this.memoryRoot,dbPath:this.storePath,provider:this.provider.id,model:this.provider.model,sources:Array.from(this.config.sources),sourceCounts:r,cache:this.config.cache.enabled?{enabled:!0,entries:a,maxEntries:this.config.cache.maxEntries}:{enabled:!1,maxEntries:this.config.cache.maxEntries},fts:{enabled:this.config.hybrid.enabled,available:this.ftsAvailable,error:this.ftsError,rows:this.getFtsRowCount()},vector:{enabled:this.vector.enabled,available:this.vector.available??void 0,extensionPath:this.vector.extensionPath,loadError:this.vector.loadError,dims:this.vector.dims},custom:{searchMode:i,fallbackActive:this.searchFallbackOnly,lastRebuildSummary:this.lastRebuildSummary}}}async probeEmbeddingAvailability(){try{return await this.provider.embedBatch([`ping`]),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async probeVectorAvailability(){return this.vector.enabled?await this.ensureVectorReady():!1}async search(e){let t=e.trim();if(!t)return[];if(this.readMeta()?this.config.sync.onSearch&&(this.dirty||this.sessionsDirty)&&this.sync({reason:`search`}).catch(()=>{this.searchFallbackOnly=!0}):await this.sync({reason:`boot`}).catch(()=>{this.searchFallbackOnly=!0}),this.searchFallbackOnly)return this.decorateCitations(await this.fileScanSearch(t));let n=this.config.hybrid,r=Math.min(200,Math.max(1,Math.floor(this.config.maxResults*n.candidateMultiplier))),i=n.enabled&&this.ftsAvailable?await this.searchKeyword(t,r).catch(()=>[]):[],a=await this.provider.embedQuery(t).catch(()=>[]),o=a.some(e=>e!==0)?await this.searchVector(a,r).catch(()=>[]):[],s=[];if(!n.enabled||!this.ftsAvailable)s=o.filter(e=>e.score>=this.config.minScore).slice(0,this.config.maxResults);else{let e=await ke({vector:o.map(e=>({id:`${e.path}:${e.startLine}:${e.endLine}:${e.source}`,path:e.path,startLine:e.startLine,endLine:e.endLine,source:e.source,snippet:e.snippet,vectorScore:e.score})),keyword:i.map(e=>({id:`${e.path}:${e.startLine}:${e.endLine}:${e.source}`,path:e.path,startLine:e.startLine,endLine:e.endLine,source:e.source,snippet:e.snippet,textScore:e.textScore})),vectorWeight:n.vectorWeight,textWeight:n.textWeight,mmr:n.mmr,temporalDecay:n.temporalDecay,memoryRoot:this.memoryRoot}),t=e.filter(e=>e.score>=this.config.minScore);if(t.length>0||i.length===0)s=t.slice(0,this.config.maxResults);else{let t=Math.min(this.config.minScore,n.textWeight);s=e.filter(e=>e.score>=t).slice(0,this.config.maxResults)}}return s.length>0?this.decorateCitations(this.decorateEntryIds(s)):this.config.fallback.enabled?(this.searchFallbackOnly=!0,this.decorateCitations(this.decorateEntryIds(await this.fileScanSearch(t)))):[]}async readFile(e){let{absPath:t,relPath:n}=this.resolveMemoryFilePath(e.relPath);if((await d(t)).missing)return{text:``,path:n};let r;try{r=await a.readFile(t,`utf-8`)}catch(e){if(u(e))return{text:``,path:n};throw e}if(!e.from&&!e.lines)return{text:r,path:n};let i=r.split(`
50
- `),o=Math.max(1,e.from??1),s=Math.max(1,e.lines??i.length);return{text:i.slice(o-1,o-1+s).join(`
51
- `),path:n}}async replaceFile(e){let{absPath:t}=this.resolveMemoryFilePath(e.relPath);await a.mkdir(o.dirname(t),{recursive:!0}),await a.writeFile(t,e.content,`utf-8`),this.dirty=!0,await this.syncAndPostCheck(`replace`)}async deleteFile(e){let{absPath:t}=this.resolveMemoryFilePath(e);try{await a.unlink(t)}catch(e){if(u(e))return;throw e}this.dirty=!0,await this.syncAndPostCheck(`delete`)}async appendToMemory(e){let t=this.memoryRoot;await a.mkdir(t,{recursive:!0});let n=o.join(t,`MEMORY.md`),r=e.endsWith(`
52
- `)?e:`${e}\n`;await a.appendFile(n,r,`utf-8`),this.dirty=!0,await this.syncAndPostCheck(`append`)}openDatabase(){return f(o.dirname(this.storePath)),x(this.storePath,{allowExtension:this.vector.enabled})}openRecoveredDatabase(){let e=null;try{return e=this.openDatabase(),this.db=e,this.ensureSchema(),e}catch(t){try{e?.close()}catch{}if(!z(t))throw t;Ve(this.storePath),e=this.openDatabase(),this.db=e,this.ftsAvailable=!1,this.ftsError=void 0,this.vector.available=null,this.vector.dims=void 0;try{this.ensureSchema()}catch(t){try{e.close()}catch{}throw t}return this.searchFallbackOnly=!0,e}}ensureSchema(){let e=Ae({db:this.db,embeddingCacheTable:F,ftsTable:P,ftsEnabled:this.config.hybrid.enabled});this.ftsAvailable=e.ftsAvailable,e.ftsError&&(this.ftsError=e.ftsError)}async ensureVectorReady(e){if(!this.vector.enabled)return!1;this.vectorReady||=this.withTimeout(this.loadVectorExtension(),L,`sqlite-vec load timed out after ${Math.round(L/1e3)}s`);let t=!1;try{t=await this.vectorReady||!1}catch(e){let t=e instanceof Error?e.message:String(e);return this.vector.available=!1,this.vector.loadError=t,this.vectorReady=null,!1}return t&&typeof e==`number`&&e>0&&this.ensureVectorTable(e),t}async loadVectorExtension(){if(this.vector.available!==null)return this.vector.available;if(!this.vector.enabled)return this.vector.available=!1,!1;try{let e=this.vector.extensionPath?.trim()?this.vector.extensionPath.trim():void 0,t=await y({db:this.db,extensionPath:e});if(!t.ok)throw Error(t.error??`unknown sqlite-vec load error`);return this.vector.extensionPath=t.extensionPath,this.vector.available=!0,!0}catch(e){let t=e instanceof Error?e.message:String(e);return this.vector.available=!1,this.vector.loadError=t,!1}}ensureVectorTable(e){this.vector.dims!==e&&(this.vector.dims&&this.vector.dims!==e&&this.dropVectorTable(),this.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${N} USING vec0(\n id TEXT PRIMARY KEY,\n embedding FLOAT[${e}]\n)`),this.vector.dims=e)}dropVectorTable(){try{this.db.exec(`DROP TABLE IF EXISTS ${N}`)}catch{}}async withTimeout(e,t,n){if(!Number.isFinite(t)||t<=0)return await e;let r=null,i=new Promise((e,i)=>{r=setTimeout(()=>i(Error(n)),t)});try{return await Promise.race([e,i])}finally{r&&clearTimeout(r)}}ensureWatcher(){if(!this.config.sync.watch||this.watchers.length>0)return;let e=[o.join(this.memoryRoot,`MEMORY.md`),o.join(this.memoryRoot,`memory.md`),o.join(this.memoryRoot,`memory`)],t=()=>{this.dirty=!0,this.scheduleWatchSync()};for(let n of e)try{let e=l.watch(n,{recursive:!1},t);e.on(`error`,()=>{try{e.close()}catch{}}),this.watchers.push(e)}catch{}}scheduleWatchSync(){this.config.sync.watch&&(this.watchTimer&&clearTimeout(this.watchTimer),this.watchTimer=setTimeout(()=>{this.watchTimer=null,this.sync({reason:`watch`}).catch(()=>{})},this.config.sync.watchDebounceMs))}ensureSessionListener(){if(!this.config.experimental.sessionMemory)return;let e=t(this.dataDir,{storeName:this.sessionStoreName});try{let t=l.watch(e,{recursive:!0},(t,n)=>{if(!n||!n.endsWith(`transcript.jsonl`))return;let r=o.join(e,n);this.scheduleSessionDirty(r)});this.watchers.push(t)}catch{}}scheduleSessionDirty(e){this.config.experimental.sessionMemory&&(this.sessionPendingFiles.add(e),!this.sessionWatchTimer&&(this.sessionWatchTimer=setTimeout(()=>{this.sessionWatchTimer=null,this.processSessionDeltaBatch().catch(()=>{})},5e3)))}async processSessionDeltaBatch(){if(this.sessionPendingFiles.size===0)return;let e=Array.from(this.sessionPendingFiles);this.sessionPendingFiles.clear();let t=!1;for(let n of e){let e=await this.updateSessionDelta(n);if(!e)continue;let r=e.deltaBytes,i=e.deltaMessages,a=r<=0?e.pendingBytes>0:e.pendingBytes>=r,o=i<=0?e.pendingMessages>0:e.pendingMessages>=i;!a&&!o||(this.sessionsDirtyFiles.add(n),this.sessionsDirty=!0,e.pendingBytes=r>0?Math.max(0,e.pendingBytes-r):0,e.pendingMessages=i>0?Math.max(0,e.pendingMessages-i):0,t=!0)}t&&this.sync({reason:`session-delta`}).catch(()=>{})}async updateSessionDelta(e){let t=this.config.sync.sessions;if(!t)return null;let n;try{n=await a.stat(e)}catch{return null}let r=n.size,i=this.sessionDeltas.get(e);i||(i={lastSize:0,pendingBytes:0,pendingMessages:0},this.sessionDeltas.set(e,i));let o=Math.max(0,r-i.lastSize);return o===0&&r===i.lastSize?{deltaBytes:t.deltaBytes,deltaMessages:t.deltaMessages,pendingBytes:i.pendingBytes,pendingMessages:i.pendingMessages}:(r<i.lastSize?(i.lastSize=r,i.pendingBytes+=r,t.deltaMessages>0&&(t.deltaBytes<=0||i.pendingBytes<t.deltaBytes)&&(i.pendingMessages+=await this.countNewlines(e,0,r))):(i.pendingBytes+=o,t.deltaMessages>0&&(t.deltaBytes<=0||i.pendingBytes<t.deltaBytes)&&(i.pendingMessages+=await this.countNewlines(e,i.lastSize,r)),i.lastSize=r),this.sessionDeltas.set(e,i),{deltaBytes:t.deltaBytes,deltaMessages:t.deltaMessages,pendingBytes:i.pendingBytes,pendingMessages:i.pendingMessages})}async countNewlines(e,t,n){if(n<=t)return 0;let r;try{r=await a.open(e,`r`)}catch{return 0}try{let e=t,i=0,a=Buffer.alloc(64*1024);for(;e<n;){let t=Math.min(a.length,n-e),{bytesRead:o}=await r.read(a,0,t,e);if(o<=0)break;for(let e=0;e<o;e+=1)a[e]===10&&(i+=1);e+=o}return i}finally{await r.close()}}computeProviderKey(){return _(JSON.stringify({provider:this.provider.id,model:this.provider.model}))}resolveMemoryFilePath(e){let t=e.trim();if(!t)throw Error(`path required`);let n=o.isAbsolute(t)?o.resolve(t):o.resolve(this.memoryRoot,t),r=o.relative(this.memoryRoot,n).replace(/\\/g,`/`);if(!(r.length>0&&!r.startsWith(`..`)&&!o.isAbsolute(r)&&m(r))||!n.endsWith(`.md`))throw Error(`path required`);return{absPath:n,relPath:r}}applyEmbeddingProvider(){let e=this.config.embedding?.providerId?.trim();if(e){let t=T({providerId:e,dataDir:this.dataDir,memoryDir:this.memoryRoot});if(!t)throw Error(`Embedding provider not found: ${e}`);this.provider=t.provider,this.embeddingProviderId=e,this.providerKey=this.computeProviderKey(),this.dirty=!0;return}this.embeddingProviderId&&(this.provider=C(),this.embeddingProviderId=void 0,this.providerKey=this.computeProviderKey(),this.dirty=!0)}readMeta(){let e=this.db.prepare(`SELECT value FROM meta WHERE key = ?`).get(I);if(!e?.value)return null;try{return JSON.parse(e.value)}catch{return null}}writeMeta(e){let t=JSON.stringify(e);this.db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(I,t)}loadEmbeddingCache(e){if(!this.config.cache.enabled||e.length===0)return new Map;let t=Array.from(new Set(e.filter(Boolean)));if(t.length===0)return new Map;let n=new Map,r=[this.provider.id,this.provider.model,this.providerKey];for(let e=0;e<t.length;e+=400){let i=t.slice(e,e+400),a=i.map(()=>`?`).join(`, `),o=this.db.prepare(`SELECT hash, embedding FROM ${F}\n WHERE provider = ? AND model = ? AND provider_key = ? AND hash IN (${a})`).all(...r,...i);for(let e of o)n.set(e.hash,v(e.embedding))}return n}upsertEmbeddingCache(e){if(!this.config.cache.enabled||e.length===0)return;let t=Date.now(),n=this.db.prepare(`INSERT INTO ${F} (provider, model, provider_key, hash, embedding, dims, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(provider, model, provider_key, hash) DO UPDATE SET\n embedding=excluded.embedding,\n dims=excluded.dims,\n updated_at=excluded.updated_at`);for(let r of e){let e=r.embedding??[];n.run(this.provider.id,this.provider.model,this.providerKey,r.hash,JSON.stringify(e),e.length,t)}}async embedChunks(e){if(e.length===0)return[];let t=this.loadEmbeddingCache(e.map(e=>e.hash)),n=Array.from({length:e.length},()=>[]),r=[];for(let i=0;i<e.length;i+=1){let a=e[i],o=a?.hash?t.get(a.hash):void 0;o&&o.length>0?n[i]=o:a&&r.push({index:i,chunk:a})}if(r.length===0)return n;let i=await this.provider.embedBatch(r.map(e=>e.chunk.text)),a=[];for(let e=0;e<r.length;e+=1){let t=r[e],o=i[e]??[];n[t.index]=o,a.push({hash:t.chunk.hash,embedding:o})}return this.upsertEmbeddingCache(a),n}async indexFile(e,t){let n=te(t.content??await a.readFile(e.absPath,`utf-8`),{tokens:this.config.chunkTokens,overlap:this.config.chunkOverlap}).filter(e=>e.text.trim().length>0);t.source===`sessions`&&ne(n,t.lineMap);let r=await this.embedChunks(n),i=r.find(e=>e.length>0),o=i?await this.ensureVectorReady(i.length):!1,s=Date.now();if(o)try{this.db.prepare(`DELETE FROM ${N} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,t.source)}catch{}if(this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${P} WHERE path = ? AND source = ? AND model = ?`).run(e.path,t.source,this.provider.model)}catch{}this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,t.source);for(let i=0;i<n.length;i+=1){let a=n[i],c=r[i]??[],l=_(`${t.source}:${e.path}:${a.startLine}:${a.endLine}:${a.hash}:${this.provider.model}`);if(this.db.prepare(`INSERT INTO chunks (id, path, source, start_line, end_line, hash, model, text, embedding, updated_at)
45
+ WHERE model = ?${e.sourceFilter.sql}`).all(e.providerModel,...e.sourceFilter.params).map(e=>({id:e.id,path:e.path,startLine:e.start_line,endLine:e.end_line,text:e.text,embedding:y(e.embedding),source:e.source}))}async function je(e){if(e.limit<=0)return[];let t=e.buildFtsQuery(e.query);if(!t)return[];let n=e.providerModel?` AND model = ?`:``,r=e.providerModel?[e.providerModel]:[];return e.db.prepare(`SELECT id, path, source, start_line, end_line, text,\n bm25(${e.ftsTable}) AS rank\n FROM ${e.ftsTable}\n WHERE ${e.ftsTable} MATCH ?${n}${e.sourceFilter.sql}\n ORDER BY rank ASC\n LIMIT ?`).all(t,...r,...e.sourceFilter.params,e.limit).map(t=>{let n=e.bm25RankToScore(t.rank);return{id:t.id,path:t.path,startLine:t.start_line,endLine:t.end_line,score:n,textScore:n,snippet:M(t.text,e.snippetMaxChars),source:t.source}})}const N={chunkTokens:400,chunkOverlap:80,maxResults:6,minScore:.2,fallback:{enabled:!0},embedding:{},experimental:{sessionMemory:!1},sources:[`memory`],store:{sessionStoreName:void 0,vector:{enabled:!0}},hybrid:{enabled:!0,vectorWeight:.7,textWeight:.3,candidateMultiplier:4,mmr:{enabled:!1,lambda:.7},temporalDecay:{enabled:!1,halfLifeDays:30}},cache:{enabled:!0,maxEntries:5e4},sync:{onSessionStart:!0,onSearch:!0,watch:!0,watchDebounceMs:1500,sessions:{deltaBytes:1e5,deltaMessages:50}},citations:`auto`};function P(e,n,r){let i=t(e,{storeName:r});return c.relative(i,n).replace(/\\/g,`/`)}async function Me(e,n){let r=t(e,{storeName:n});try{let e=await s.readdir(r,{withFileTypes:!0}),t=[];for(let n of e){if(!n.isDirectory())continue;let e=c.join(r,n.name,`transcript.jsonl`);try{(await s.stat(e)).isFile()&&t.push(e)}catch{}}return t}catch(e){if(f(e))return[];throw e}}function Ne(e){return typeof e==`string`?e:Array.isArray(e)?e.map(e=>typeof e==`string`?e:e&&typeof e==`object`&&`text`in e?String(e.text??``):``).filter(Boolean).join(` `):e?String(e):``}async function Pe(e,t,i){let a;try{a=await s.stat(t)}catch(e){if(f(e))return null;throw e}let o;try{let e=await r(t);if(e===null)return null;o=e}catch(e){if(f(e))return null;throw e}let l=[],u=[],d=o.split(`
46
+ `);for(let e=0;e<d.length;e+=1){let t=d[e]?.trim();if(t)try{let n=JSON.parse(t),r=n.role??`unknown`,i=Ne(n.content);if(!i)continue;let a=i.split(`
47
+ `);for(let t of a)l.push(`[${r}] ${t}`),u.push(e+1)}catch{}}let p=l.join(`
48
+ `),m=v(p);return{path:c.join(n(i),P(e,t,i)).replace(/\\/g,`/`),absPath:t,mtimeMs:a.mtimeMs,size:a.size,hash:m,content:p,lineMap:u}}const F=`chunks_vec`,I=`chunks_fts`,L=`embedding_cache`,R=`memory_index_meta_v1`,z=3e4;function Fe(e,t,n){let r=t.split(`
49
+ `);for(let t of r){let n=t.match(/^##\s+(.+)$/);if(n?.[1])return`${e}#${n[1].trim()}`}return`${e}#L${n}`}const B=new Map,Ie=[`database disk image is malformed`,`database disk image malformed`,`file is not a database`,`database disk image is corrupt`,`sqlite_corrupt`];function V(e){let t=`${typeof e==`object`&&e&&`code`in e?String(e.code??``).toLowerCase():``} ${e instanceof Error?e.message:String(e)}`.toLowerCase();return Ie.some(e=>t.includes(e))}function Le(e){let t=`${e}.corrupt-${new Date().toISOString().replace(/[:.]/g,`-`)}`,n=!1;for(let r of[``,`-wal`,`-shm`]){let i=`${e}${r}`,a=`${t}${r}`;try{if(!d.existsSync(i))continue;d.renameSync(i,a),n=!0}catch{try{d.rmSync(i,{force:!0}),n=!0}catch{}}}return n?t:null}function Re(e,t){let r=n(t.store.sessionStoreName),i=[...t.sources].sort().join(`,`),a=t.experimental.sessionMemory?`sessions-on`:`sessions-off`,o=t.store.vector.enabled?`vector-on`:`vector-off`;return[e,`store=${r}`,`sources=${i}`,a,o].join(`::`)}function H(e,t){let n={...e,...t,hybrid:{...e.hybrid,...t?.hybrid??{}},cache:{...e.cache,...t?.cache??{}},sync:{...e.sync,...t?.sync??{}},experimental:{...e.experimental,...t?.experimental??{}},sources:t?.sources??e.sources,embedding:{...e.embedding,...t?.embedding??{}},store:{...e.store,...t?.store??{},vector:{...e.store.vector,...t?.store?.vector??{}}}};return n.experimental.sessionMemory&&!n.sources.includes(`sessions`)&&(n.sources=[...n.sources,`sessions`]),n}var U=class e{dataDir;memoryRoot;storePath;config;sessionStoreName;provider;providerKey;embeddingProviderId;db;dirty=!0;ftsAvailable=!1;ftsError;vector={enabled:!0,available:null,extensionPath:void 0,loadError:void 0,dims:void 0};vectorReady=null;watchers=[];watchTimer=null;sessionWatchTimer=null;sessionsDirty=!1;sessionsDirtyFiles=new Set;sessionPendingFiles=new Set;searchFallbackOnly=!1;lastRebuildSummary;sessionDeltas=new Map;static get(t,n){let r=c.join(t,`.aimax`),i=H(N,n),a=Re(r,i),o=B.get(a);if(o)return n&&o.applyConfig(n),o;let s=new e(t,r,i);return B.set(a,s),s}static disposeForDataDir(e){let t=c.join(e,`.aimax`),n=0;for(let[e,r]of B.entries())e.startsWith(`${t}::`)&&(r.dispose(),B.delete(e),n+=1);return n}static disposeAll(){let e=0;for(let[t,n]of B.entries())n.dispose(),B.delete(t),e+=1;return e}constructor(e,t,r){this.dataDir=e,this.memoryRoot=t,this.storePath=c.join(t,`.index.sqlite`),this.config=H(N,r),this.sessionStoreName=n(this.config.store.sessionStoreName),this.provider=w(),this.providerKey=this.computeProviderKey(),this.applyEmbeddingProvider(),this.vector.enabled=this.config.store.vector.enabled,this.vector.extensionPath=this.config.store.vector.extensionPath,this.db=this.openRecoveredDatabase(),this.ensureWatcher(),this.ensureSessionListener(),this.dirty=!0}applyConfig(e){this.config=H(this.config,e),this.sessionStoreName=n(this.config.store.sessionStoreName),this.applyEmbeddingProvider(),this.vector.enabled=this.config.store.vector.enabled,this.vector.extensionPath=this.config.store.vector.extensionPath,this.ensureWatcher(),this.ensureSessionListener()}warmSession(){this.config.sync.onSessionStart&&this.sync({reason:`session-start`}).catch(()=>{})}noteSessionUpdate(e){this.scheduleSessionDirty(e)}dispose(){this.watchTimer&&=(clearTimeout(this.watchTimer),null),this.sessionWatchTimer&&=(clearTimeout(this.sessionWatchTimer),null);for(let e of this.watchers.splice(0))try{e.close()}catch{}this.sessionPendingFiles.clear(),this.sessionsDirtyFiles.clear(),this.sessionDeltas.clear();try{this.db.close()}catch{}}status(){let e=this.buildSourceFilter(),t=this.db.prepare(`SELECT COUNT(*) as c FROM files WHERE 1=1${e.sql}`).get(...e.params),n=this.db.prepare(`SELECT COUNT(*) as c FROM chunks WHERE 1=1${e.sql}`).get(...e.params),r=(()=>{let t=Array.from(this.config.sources);if(t.length===0)return[];let n=new Map;for(let e of t)n.set(e,{files:0,chunks:0});let r=this.db.prepare(`SELECT source, COUNT(*) as c FROM files WHERE 1=1${e.sql} GROUP BY source`).all(...e.params);for(let e of r){let t=n.get(e.source)??{files:0,chunks:0};t.files=e.c??0,n.set(e.source,t)}let i=this.db.prepare(`SELECT source, COUNT(*) as c FROM chunks WHERE 1=1${e.sql} GROUP BY source`).all(...e.params);for(let e of i){let t=n.get(e.source)??{files:0,chunks:0};t.chunks=e.c??0,n.set(e.source,t)}return t.map(e=>Object.assign({source:e},n.get(e)))})(),i=this.provider?`hybrid`:`fts-only`,a=this.config.cache.enabled?this.db.prepare(`SELECT COUNT(*) as c FROM ${L}`).get()?.c??0:void 0;return{backend:`builtin`,files:t?.c??0,chunks:n?.c??0,dirty:this.dirty||this.sessionsDirty,workspaceDir:this.memoryRoot,dbPath:this.storePath,provider:this.provider.id,model:this.provider.model,sources:Array.from(this.config.sources),sourceCounts:r,cache:this.config.cache.enabled?{enabled:!0,entries:a,maxEntries:this.config.cache.maxEntries}:{enabled:!1,maxEntries:this.config.cache.maxEntries},fts:{enabled:this.config.hybrid.enabled,available:this.ftsAvailable,error:this.ftsError,rows:this.getFtsRowCount()},vector:{enabled:this.vector.enabled,available:this.vector.available??void 0,extensionPath:this.vector.extensionPath,loadError:this.vector.loadError,dims:this.vector.dims},custom:{searchMode:i,fallbackActive:this.searchFallbackOnly,lastRebuildSummary:this.lastRebuildSummary}}}async probeEmbeddingAvailability(){try{return await this.provider.embedBatch([`ping`]),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async probeVectorAvailability(){return this.vector.enabled?await this.ensureVectorReady():!1}async search(e){let t=e.trim();if(!t)return[];if(this.readMeta()?this.config.sync.onSearch&&(this.dirty||this.sessionsDirty)&&this.sync({reason:`search`}).catch(()=>{this.searchFallbackOnly=!0}):await this.sync({reason:`boot`}).catch(()=>{this.searchFallbackOnly=!0}),this.searchFallbackOnly)return this.decorateCitations(await this.fileScanSearch(t));let n=this.config.hybrid,r=Math.min(200,Math.max(1,Math.floor(this.config.maxResults*n.candidateMultiplier))),i=n.enabled&&this.ftsAvailable?await this.searchKeyword(t,r).catch(()=>[]):[],a=await this.provider.embedQuery(t).catch(()=>[]),o=a.some(e=>e!==0)?await this.searchVector(a,r).catch(()=>[]):[],s=[];if(!n.enabled||!this.ftsAvailable)s=o.filter(e=>e.score>=this.config.minScore).slice(0,this.config.maxResults);else{let e=await Ee({vector:o.map(e=>({id:`${e.path}:${e.startLine}:${e.endLine}:${e.source}`,path:e.path,startLine:e.startLine,endLine:e.endLine,source:e.source,snippet:e.snippet,vectorScore:e.score})),keyword:i.map(e=>({id:`${e.path}:${e.startLine}:${e.endLine}:${e.source}`,path:e.path,startLine:e.startLine,endLine:e.endLine,source:e.source,snippet:e.snippet,textScore:e.textScore})),vectorWeight:n.vectorWeight,textWeight:n.textWeight,mmr:n.mmr,temporalDecay:n.temporalDecay,memoryRoot:this.memoryRoot}),t=e.filter(e=>e.score>=this.config.minScore);if(t.length>0||i.length===0)s=t.slice(0,this.config.maxResults);else{let t=Math.min(this.config.minScore,n.textWeight);s=e.filter(e=>e.score>=t).slice(0,this.config.maxResults)}}return s.length>0?this.decorateCitations(this.decorateEntryIds(s)):this.config.fallback.enabled?(this.searchFallbackOnly=!0,this.decorateCitations(this.decorateEntryIds(await this.fileScanSearch(t)))):[]}async readFile(e){let{absPath:t,relPath:n}=this.resolveMemoryFilePath(e.relPath);if((await p(t)).missing)return{text:``,path:n};let r;try{r=await s.readFile(t,`utf-8`)}catch(e){if(f(e))return{text:``,path:n};throw e}if(!e.from&&!e.lines)return{text:r,path:n};let i=r.split(`
50
+ `),a=Math.max(1,e.from??1),o=Math.max(1,e.lines??i.length);return{text:i.slice(a-1,a-1+o).join(`
51
+ `),path:n}}async replaceFile(e){let{absPath:t}=this.resolveMemoryFilePath(e.relPath);await s.mkdir(c.dirname(t),{recursive:!0}),await s.writeFile(t,e.content,`utf-8`),this.dirty=!0,await this.syncAndPostCheck(`replace`)}async deleteFile(e){let{absPath:t}=this.resolveMemoryFilePath(e);try{await s.unlink(t)}catch(e){if(f(e))return;throw e}this.dirty=!0,await this.syncAndPostCheck(`delete`)}async appendToMemory(e){let t=this.memoryRoot;await s.mkdir(t,{recursive:!0});let n=c.join(t,`MEMORY.md`),r=e.endsWith(`
52
+ `)?e:`${e}\n`;await s.appendFile(n,r,`utf-8`),this.dirty=!0,await this.syncAndPostCheck(`append`)}openDatabase(){return m(c.dirname(this.storePath)),S(this.storePath,{allowExtension:this.vector.enabled})}openRecoveredDatabase(){let e=null;try{return e=this.openDatabase(),this.db=e,this.ensureSchema(),e}catch(t){try{e?.close()}catch{}if(!V(t))throw t;Le(this.storePath),e=this.openDatabase(),this.db=e,this.ftsAvailable=!1,this.ftsError=void 0,this.vector.available=null,this.vector.dims=void 0;try{this.ensureSchema()}catch(t){try{e.close()}catch{}throw t}return this.searchFallbackOnly=!0,e}}ensureSchema(){let e=De({db:this.db,embeddingCacheTable:L,ftsTable:I,ftsEnabled:this.config.hybrid.enabled});this.ftsAvailable=e.ftsAvailable,e.ftsError&&(this.ftsError=e.ftsError)}async ensureVectorReady(e){if(!this.vector.enabled)return!1;this.vectorReady||=this.withTimeout(this.loadVectorExtension(),z,`sqlite-vec load timed out after ${Math.round(z/1e3)}s`);let t=!1;try{t=await this.vectorReady||!1}catch(e){let t=e instanceof Error?e.message:String(e);return this.vector.available=!1,this.vector.loadError=t,this.vectorReady=null,!1}return t&&typeof e==`number`&&e>0&&this.ensureVectorTable(e),t}async loadVectorExtension(){if(this.vector.available!==null)return this.vector.available;if(!this.vector.enabled)return this.vector.available=!1,!1;try{let e=this.vector.extensionPath?.trim()?this.vector.extensionPath.trim():void 0,t=await b({db:this.db,extensionPath:e});if(!t.ok)throw Error(t.error??`unknown sqlite-vec load error`);return this.vector.extensionPath=t.extensionPath,this.vector.available=!0,!0}catch(e){let t=e instanceof Error?e.message:String(e);return this.vector.available=!1,this.vector.loadError=t,!1}}ensureVectorTable(e){this.vector.dims!==e&&(this.vector.dims&&this.vector.dims!==e&&this.dropVectorTable(),this.db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS ${F} USING vec0(\n id TEXT PRIMARY KEY,\n embedding FLOAT[${e}]\n)`),this.vector.dims=e)}dropVectorTable(){try{this.db.exec(`DROP TABLE IF EXISTS ${F}`)}catch{}}async withTimeout(e,t,n){if(!Number.isFinite(t)||t<=0)return await e;let r=null,i=new Promise((e,i)=>{r=setTimeout(()=>i(Error(n)),t)});try{return await Promise.race([e,i])}finally{r&&clearTimeout(r)}}ensureWatcher(){if(!this.config.sync.watch||this.watchers.length>0)return;let e=[c.join(this.memoryRoot,`MEMORY.md`),c.join(this.memoryRoot,`memory.md`),c.join(this.memoryRoot,`memory`)],t=()=>{this.dirty=!0,this.scheduleWatchSync()};for(let n of e)try{let e=d.watch(n,{recursive:!1},t);e.on(`error`,()=>{try{e.close()}catch{}}),this.watchers.push(e)}catch{}}scheduleWatchSync(){this.config.sync.watch&&(this.watchTimer&&clearTimeout(this.watchTimer),this.watchTimer=setTimeout(()=>{this.watchTimer=null,this.sync({reason:`watch`}).catch(()=>{})},this.config.sync.watchDebounceMs))}ensureSessionListener(){if(!this.config.experimental.sessionMemory)return;let e=t(this.dataDir,{storeName:this.sessionStoreName});try{let t=d.watch(e,{recursive:!0},(t,n)=>{if(!n||!n.endsWith(`transcript.jsonl`))return;let r=c.join(e,n);this.scheduleSessionDirty(r)});this.watchers.push(t)}catch{}}scheduleSessionDirty(e){this.config.experimental.sessionMemory&&(this.sessionPendingFiles.add(e),!this.sessionWatchTimer&&(this.sessionWatchTimer=setTimeout(()=>{this.sessionWatchTimer=null,this.processSessionDeltaBatch().catch(()=>{})},5e3)))}async processSessionDeltaBatch(){if(this.sessionPendingFiles.size===0)return;let e=Array.from(this.sessionPendingFiles);this.sessionPendingFiles.clear();let t=!1;for(let n of e){let e=await this.updateSessionDelta(n);if(!e)continue;let r=e.deltaBytes,i=e.deltaMessages,a=r<=0?e.pendingBytes>0:e.pendingBytes>=r,o=i<=0?e.pendingMessages>0:e.pendingMessages>=i;!a&&!o||(this.sessionsDirtyFiles.add(n),this.sessionsDirty=!0,e.pendingBytes=r>0?Math.max(0,e.pendingBytes-r):0,e.pendingMessages=i>0?Math.max(0,e.pendingMessages-i):0,t=!0)}t&&this.sync({reason:`session-delta`}).catch(()=>{})}async updateSessionDelta(e){let t=this.config.sync.sessions;if(!t)return null;let n;try{n=await s.stat(e)}catch{return null}let r=n.size,i=this.sessionDeltas.get(e);i||(i={lastSize:0,pendingBytes:0,pendingMessages:0},this.sessionDeltas.set(e,i));let a=Math.max(0,r-i.lastSize);return a===0&&r===i.lastSize?{deltaBytes:t.deltaBytes,deltaMessages:t.deltaMessages,pendingBytes:i.pendingBytes,pendingMessages:i.pendingMessages}:(r<i.lastSize?(i.lastSize=r,i.pendingBytes+=r,t.deltaMessages>0&&(t.deltaBytes<=0||i.pendingBytes<t.deltaBytes)&&(i.pendingMessages+=await this.countNewlines(e,0,r))):(i.pendingBytes+=a,t.deltaMessages>0&&(t.deltaBytes<=0||i.pendingBytes<t.deltaBytes)&&(i.pendingMessages+=await this.countNewlines(e,i.lastSize,r)),i.lastSize=r),this.sessionDeltas.set(e,i),{deltaBytes:t.deltaBytes,deltaMessages:t.deltaMessages,pendingBytes:i.pendingBytes,pendingMessages:i.pendingMessages})}async countNewlines(e,t,n){if(n<=t)return 0;let r;try{r=await s.open(e,`r`)}catch{return 0}try{let e=t,i=0,a=Buffer.alloc(64*1024);for(;e<n;){let t=Math.min(a.length,n-e),{bytesRead:o}=await r.read(a,0,t,e);if(o<=0)break;for(let e=0;e<o;e+=1)a[e]===10&&(i+=1);e+=o}return i}finally{await r.close()}}computeProviderKey(){return v(JSON.stringify({provider:this.provider.id,model:this.provider.model}))}resolveMemoryFilePath(e){let t=e.trim();if(!t)throw Error(`path required`);let n=c.isAbsolute(t)?c.resolve(t):c.resolve(this.memoryRoot,t),r=c.relative(this.memoryRoot,n).replace(/\\/g,`/`);if(!(r.length>0&&!r.startsWith(`..`)&&!c.isAbsolute(r)&&h(r))||!n.endsWith(`.md`))throw Error(`path required`);return{absPath:n,relPath:r}}applyEmbeddingProvider(){let e=this.config.embedding?.providerId?.trim();if(e){let t=i({providerId:e,dataDir:this.dataDir,memoryDir:this.memoryRoot});if(!t)throw Error(`Embedding provider not found: ${e}`);this.provider=t.provider,this.embeddingProviderId=e,this.providerKey=this.computeProviderKey(),this.dirty=!0;return}this.embeddingProviderId&&(this.provider=w(),this.embeddingProviderId=void 0,this.providerKey=this.computeProviderKey(),this.dirty=!0)}readMeta(){let e=this.db.prepare(`SELECT value FROM meta WHERE key = ?`).get(R);if(!e?.value)return null;try{return JSON.parse(e.value)}catch{return null}}writeMeta(e){let t=JSON.stringify(e);this.db.prepare(`INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(R,t)}loadEmbeddingCache(e){if(!this.config.cache.enabled||e.length===0)return new Map;let t=Array.from(new Set(e.filter(Boolean)));if(t.length===0)return new Map;let n=new Map,r=[this.provider.id,this.provider.model,this.providerKey];for(let e=0;e<t.length;e+=400){let i=t.slice(e,e+400),a=i.map(()=>`?`).join(`, `),o=this.db.prepare(`SELECT hash, embedding FROM ${L}\n WHERE provider = ? AND model = ? AND provider_key = ? AND hash IN (${a})`).all(...r,...i);for(let e of o)n.set(e.hash,y(e.embedding))}return n}upsertEmbeddingCache(e){if(!this.config.cache.enabled||e.length===0)return;let t=Date.now(),n=this.db.prepare(`INSERT INTO ${L} (provider, model, provider_key, hash, embedding, dims, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(provider, model, provider_key, hash) DO UPDATE SET\n embedding=excluded.embedding,\n dims=excluded.dims,\n updated_at=excluded.updated_at`);for(let r of e){let e=r.embedding??[];n.run(this.provider.id,this.provider.model,this.providerKey,r.hash,JSON.stringify(e),e.length,t)}}async embedChunks(e){if(e.length===0)return[];let t=this.loadEmbeddingCache(e.map(e=>e.hash)),n=Array.from({length:e.length},()=>[]),r=[];for(let i=0;i<e.length;i+=1){let a=e[i],o=a?.hash?t.get(a.hash):void 0;o&&o.length>0?n[i]=o:a&&r.push({index:i,chunk:a})}if(r.length===0)return n;let i=await this.provider.embedBatch(r.map(e=>e.chunk.text)),a=[];for(let e=0;e<r.length;e+=1){let t=r[e],o=i[e]??[];n[t.index]=o,a.push({hash:t.chunk.hash,embedding:o})}return this.upsertEmbeddingCache(a),n}async indexFile(e,t){let n=ne(t.content??await s.readFile(e.absPath,`utf-8`),{tokens:this.config.chunkTokens,overlap:this.config.chunkOverlap}).filter(e=>e.text.trim().length>0);t.source===`sessions`&&re(n,t.lineMap);let r=await this.embedChunks(n),i=r.find(e=>e.length>0),a=i?await this.ensureVectorReady(i.length):!1,o=Date.now();if(a)try{this.db.prepare(`DELETE FROM ${F} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,t.source)}catch{}if(this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${I} WHERE path = ? AND source = ? AND model = ?`).run(e.path,t.source,this.provider.model)}catch{}this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,t.source);for(let i=0;i<n.length;i+=1){let s=n[i],c=r[i]??[],l=v(`${t.source}:${e.path}:${s.startLine}:${s.endLine}:${s.hash}:${this.provider.model}`);if(this.db.prepare(`INSERT INTO chunks (id, path, source, start_line, end_line, hash, model, text, embedding, updated_at)
53
53
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
54
54
  ON CONFLICT(id) DO UPDATE SET
55
55
  hash=excluded.hash,
56
56
  model=excluded.model,
57
57
  text=excluded.text,
58
58
  embedding=excluded.embedding,
59
- updated_at=excluded.updated_at`).run(l,e.path,t.source,a.startLine,a.endLine,a.hash,this.provider.model,a.text,JSON.stringify(c),s),o&&c.length>0){try{this.db.prepare(`DELETE FROM ${N} WHERE id = ?`).run(l)}catch{}this.db.prepare(`INSERT INTO ${N} (id, embedding) VALUES (?, ?)`).run(l,Buffer.from(new Float32Array(c).buffer))}this.ftsAvailable&&this.db.prepare(`INSERT INTO ${P} (text, id, path, source, model, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`).run(a.text,l,e.path,t.source,this.provider.model,a.startLine,a.endLine)}this.db.prepare(`INSERT INTO files (path, source, hash, mtime, size) VALUES (?, ?, ?, ?, ?)
59
+ updated_at=excluded.updated_at`).run(l,e.path,t.source,s.startLine,s.endLine,s.hash,this.provider.model,s.text,JSON.stringify(c),o),a&&c.length>0){try{this.db.prepare(`DELETE FROM ${F} WHERE id = ?`).run(l)}catch{}this.db.prepare(`INSERT INTO ${F} (id, embedding) VALUES (?, ?)`).run(l,Buffer.from(new Float32Array(c).buffer))}this.ftsAvailable&&this.db.prepare(`INSERT INTO ${I} (text, id, path, source, model, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?, ?)`).run(s.text,l,e.path,t.source,this.provider.model,s.startLine,s.endLine)}this.db.prepare(`INSERT INTO files (path, source, hash, mtime, size) VALUES (?, ?, ?, ?, ?)
60
60
  ON CONFLICT(path) DO UPDATE SET
61
61
  source=excluded.source,
62
62
  hash=excluded.hash,
63
63
  mtime=excluded.mtime,
64
- size=excluded.size`).run(e.path,t.source,e.hash,e.mtimeMs,e.size)}buildSourceFilter(){let e=this.config.sources;return e.length?{sql:` AND source IN (${e.map(()=>`?`).join(`, `)})`,params:e}:{sql:``,params:[]}}async searchVector(e,t){return await Me({db:this.db,vectorTable:N,providerModel:this.provider.model,queryVec:e,limit:t,snippetMaxChars:700,ensureVectorReady:async e=>await this.ensureVectorReady(e),sourceFilterVec:this.buildSourceFilter(),sourceFilterChunks:this.buildSourceFilter()})}async searchKeyword(e,t){return this.ftsAvailable?await Pe({db:this.db,ftsTable:P,providerModel:this.provider.model,query:e,limit:t,snippetMaxChars:700,sourceFilter:this.buildSourceFilter(),buildFtsQuery:e=>De(e),bm25RankToScore:Oe}):[]}resetIndex(){if(this.db.exec(`DELETE FROM files`),this.db.exec(`DELETE FROM chunks`),this.ftsAvailable)try{this.db.exec(`DELETE FROM ${P}`)}catch{}this.dropVectorTable(),this.vector.dims=void 0,this.sessionsDirtyFiles.clear()}async syncAndPostCheck(e){try{await this.sync({reason:`mutation-postcheck`})}catch{this.searchFallbackOnly=!0;return}this.searchFallbackOnly=!this.indexHasSearchableData()}indexHasSearchableData(){try{if((this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get()?.c??0)>0)return!0}catch{}try{if(l.readdirSync(this.memoryRoot).filter(e=>e.endsWith(`.md`)).length>0)return!1;let e=o.join(this.memoryRoot,`memory`);return l.existsSync(e)?l.readdirSync(e).filter(e=>e.endsWith(`.md`)).length===0:!0}catch{return!1}}async fileScanSearch(e){let t=e.trim().toLowerCase();if(!t)return[];let n=await g(this.memoryRoot),r=[];for(let e of n){let n=``;try{n=await a.readFile(e,`utf-8`)}catch{continue}let i=o.relative(this.memoryRoot,e).replace(/\\/g,`/`);i.startsWith(`memory/`);let c=n.split(`
65
- `);for(let n=0;n<c.length;n+=1){let a=c[n]??``,o=a.toLowerCase();if(!o.includes(t))continue;let l=o===t?1:Math.max(.2,t.length/Math.max(a.length,t.length));r.push({path:i||s(e),startLine:n+1,endLine:n+1,score:Number(l.toFixed(4)),snippet:a.slice(0,700),source:`memory`})}}return r.sort((e,t)=>t.score-e.score||e.path.localeCompare(t.path)||e.startLine-t.startLine),r.slice(0,this.config.maxResults)}getFtsRowCount(){if(this.ftsAvailable)try{return this.db.prepare(`SELECT COUNT(*) as c FROM ${P}`).get()?.c??0}catch{return}}buildRebuildSummary(e){let t=this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get();return{reason:e.reason,memoryFilesIndexed:e.memoryFilesIndexed,sessionFilesIndexed:e.sessionFilesIndexed,staleMemoryFilesRemoved:e.staleMemoryFilesRemoved,staleSessionFilesRemoved:e.staleSessionFilesRemoved,chunks:t?.c??0,ftsRows:this.getFtsRowCount(),fallbackActive:this.searchFallbackOnly,needsFullReindex:e.needsFullReindex}}async rebuild(e=`manual-rebuild`){return this.resetIndex(),this.dirty=!0,this.sessionsDirty=!0,await this.sync({reason:e,forceFullReindex:!0}),this.lastRebuildSummary??this.buildRebuildSummary({reason:e,memoryFilesIndexed:0,sessionFilesIndexed:0,staleMemoryFilesRemoved:0,staleSessionFilesRemoved:0,needsFullReindex:!0})}async sync(e){let t=this.readMeta(),n=e?.forceFullReindex||!t||t.model!==this.provider.model||t.provider!==this.provider.id||t.providerKey!==this.providerKey||t.chunkTokens!==this.config.chunkTokens||t.chunkOverlap!==this.config.chunkOverlap||this.vector.available&&!t?.vectorDims;n&&this.resetIndex();let r=await g(this.memoryRoot),i=(await Promise.all(r.map(async e=>ee(e,this.memoryRoot)))).filter(e=>e!==null),a=new Set(i.map(e=>e.path)),o=0,s=i.map(e=>async()=>{let t=this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(e.path,`memory`);!n&&t?.hash===e.hash||(await this.indexFile(e,{source:`memory`}),o+=1)});for(let e of s)await e();let c=0,l=this.db.prepare(`SELECT path FROM files WHERE source = ?`).all(`memory`);for(let e of l)if(!a.has(e.path)){this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(e.path,`memory`),c+=1;try{this.db.prepare(`DELETE FROM ${N} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,`memory`)}catch{}if(this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,`memory`),this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${P} WHERE path = ? AND source = ? AND model = ?`).run(e.path,`memory`,this.provider.model)}catch{}}let u={indexed:0,staleRemoved:0};this.config.experimental.sessionMemory&&(n||this.sessionsDirty)&&(u=await this.syncSessionFiles(n)),this.writeMeta({model:this.provider.model,provider:this.provider.id,providerKey:this.providerKey,chunkTokens:this.config.chunkTokens,chunkOverlap:this.config.chunkOverlap,...this.vector.available&&this.vector.dims?{vectorDims:this.vector.dims}:{}}),this.dirty=!1,this.searchFallbackOnly=!this.indexHasSearchableData(),this.lastRebuildSummary=this.buildRebuildSummary({reason:e?.reason??`sync`,memoryFilesIndexed:o,sessionFilesIndexed:u.indexed,staleMemoryFilesRemoved:c,staleSessionFilesRemoved:u.staleRemoved,needsFullReindex:!!n})}async syncSessionFiles(e){let t=await Ie(this.dataDir,this.sessionStoreName),n=(await Promise.all(t.map(async e=>Re(this.dataDir,e,this.sessionStoreName)))).filter(e=>e!==null),r=new Set(n.map(e=>e.path)),i=e||this.sessionsDirtyFiles.size===0,a=0;for(let t of n){if(!i&&!this.sessionsDirtyFiles.has(t.absPath))continue;let n=this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(t.path,`sessions`);if(!e&&n?.hash===t.hash){this.resetSessionDelta(t.absPath,t.size);continue}await this.indexFile(t,{source:`sessions`,content:t.content,lineMap:t.lineMap}),a+=1,this.resetSessionDelta(t.absPath,t.size)}let o=0,s=this.db.prepare(`SELECT path FROM files WHERE source = ?`).all(`sessions`);for(let e of s)if(!r.has(e.path)){this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(e.path,`sessions`),o+=1;try{this.db.prepare(`DELETE FROM ${N} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,`sessions`)}catch{}if(this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,`sessions`),this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${P} WHERE path = ? AND source = ? AND model = ?`).run(e.path,`sessions`,this.provider.model)}catch{}}return this.sessionsDirty=!1,this.sessionsDirtyFiles.clear(),{indexed:a,staleRemoved:o}}resetSessionDelta(e,t){let n=this.sessionDeltas.get(e);n&&(n.lastSize=t,n.pendingBytes=0,n.pendingMessages=0)}decorateCitations(e){return this.config.citations===`off`?e:e.map(e=>{let t=`Source: ${e.path}#L${e.startLine}-L${e.endLine}`;return this.config.citations===`on`?{...e,citation:t,snippet:`${e.snippet}\n\n${t}`}:{...e,citation:t}})}decorateEntryIds(e){return e.map(e=>{if(e.id)return e;let t=ze(e.path,e.snippet,e.startLine);return{...e,id:t}})}};function H(e){return e instanceof Error?e.message:String(e)}function U(e){return z(e)}function W(e,t){let n=t.trim();if(!n)throw Error(`path required`);let r=o.isAbsolute(n)?o.resolve(n):o.resolve(e,n),i=o.relative(e,r).replace(/\\/g,`/`);if(!(i.length>0&&!i.startsWith(`..`)&&!o.isAbsolute(i))||!m(i)||!r.endsWith(`.md`))throw Error(`path required`);return{absPath:r,relPath:i}}async function G(e,t){let n=t.trim().toLowerCase();if(!n)return[];let r=await g(e),i=[];for(let t of r){let r;try{r=await a.readFile(t,`utf-8`)}catch{continue}let s=o.relative(e,t).replace(/\\/g,`/`)||o.basename(t),c=r.split(`
66
- `);for(let e=0;e<c.length;e+=1){let t=c[e]??``,r=t.toLowerCase();if(!r.includes(n))continue;let a=r===n?1:Math.max(.2,n.length/Math.max(t.length,n.length));i.push({id:`${s}#L${e+1}`,path:s,startLine:e+1,endLine:e+1,score:Number(a.toFixed(4)),snippet:t.slice(0,700),source:`memory`})}}return i.sort((e,t)=>t.score-e.score||e.path.localeCompare(t.path)||e.startLine-t.startLine),i.slice(0,20)}function K(e,t){let n=e.memoryDir;return{id:`builtin-memory`,name:`Builtin Memory Provider`,status:()=>({backend:`builtin`,provider:`builtin-memory`,workspaceDir:n,dbPath:o.join(n,`.index.sqlite`),dirty:!0,files:void 0,chunks:void 0,fts:{enabled:!1,available:!1,error:t},vector:{enabled:!1,available:!1,loadError:t},custom:{searchMode:`file-scan`,fallbackActive:!0,fallbackReason:t}}),search:async e=>G(n,e),getLines:async(e,t,r)=>{let{absPath:i,relPath:o}=W(n,e),s;try{s=await a.readFile(i,`utf-8`)}catch{return[]}let c=s.split(`
67
- `),l=Math.max(1,t),u=Math.max(1,r-l+1);return c.slice(l-1,l-1+u)},listFiles:async()=>g(n),append:async e=>{await a.mkdir(n,{recursive:!0});let t=e.endsWith(`
68
- `)?e:`${e}\n`;await a.appendFile(o.join(n,`MEMORY.md`),t,`utf-8`)},updateFile:async(e,t)=>{let{absPath:r}=W(n,e);await a.mkdir(o.dirname(r),{recursive:!0}),await a.writeFile(r,t,`utf-8`)},deleteFile:async e=>{let{absPath:t}=W(n,e);await a.unlink(t).catch(e=>{if(e.code!==`ENOENT`)throw e})},sync:async()=>{},noteSessionUpdate:()=>{}}}function q(e,t){let n=e.memoryDir,r=t?.includeSessions?{experimental:{sessionMemory:!0},sources:[`memory`,`sessions`],store:{sessionStoreName:e.sessionStoreName,vector:{enabled:!0}}}:e.sessionStoreName?{store:{sessionStoreName:e.sessionStoreName,vector:{enabled:!0}}}:void 0,i;try{i=V.get(e.dataDir,r)}catch(t){if(U(t))return K(e,H(t));throw t}let a=async(e,t)=>{try{return await e()}catch(e){if(!U(e))throw e;return await t()}};return{id:`builtin-memory`,name:`Builtin Memory Provider`,status:()=>{try{return i.status()}catch(t){if(U(t))return K(e,H(t)).status();throw t}},search:async(e,t)=>a(()=>i.search(e),()=>G(n,e)),getLines:async(t,n,r)=>await a(async()=>{let e=Math.max(1,r-n+1),a=await i.readFile({relPath:t,from:n,lines:e});return a.text?a.text.split(`
69
- `):[]},()=>K(e).getLines(t,n,r)),listFiles:async()=>g(n),append:async t=>a(()=>i.appendToMemory(t),()=>K(e).append(t)),updateFile:async(t,n)=>{await a(()=>i.replaceFile({relPath:t,content:n}),()=>K(e).updateFile(t,n))},deleteFile:async t=>{await a(()=>i.deleteFile(t),()=>K(e).deleteFile(t))},sync:async e=>{await a(async()=>{if(e===`cli-rebuild`){await i.rebuild(e);return}await i.sync({reason:e??`provider-sync`})},async()=>{})},noteSessionUpdate:e=>{let t=o.isAbsolute(e)?e:o.resolve(e);i.noteSessionUpdate(t)}}}function J(){let e=new Date;return{date:e.toISOString().slice(0,10),time:`${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}`}}function Ue(e,t){let{date:n}=J();return e===`session`&&t?`session-${t}.md`:`${n}.md`}async function We(e,t,n,r){let{time:i}=J(),s=Ue(n,r),c=o.join(e,`memory`,s);await a.mkdir(o.dirname(c),{recursive:!0}),await a.appendFile(c,`- [${i}] ${t.trim()}\n`,`utf-8`)}function Ge(e){return e.replace(/\s*\[[^\]]+\]\s*$/,``).trim()}function Y(e){let t=new Map,n=``;for(let r of e.split(`
70
- `)){let e=r.match(/^## (.+)/);if(e){n=e[1].trim(),t.has(n)||t.set(n,{entries:[],sectionTags:[]});continue}let i=t.get(n);if(!i)continue;let a=r.match(/<!--\s*created:\s*(\d{4}-\d{2}-\d{2})\s*-->/);if(a){i.created=a[1];continue}let o=r.match(/<!--\s*tags:\s*([^>]*?)-->/);if(o){i.sectionTags=o[1].split(`,`).map(e=>e.trim()).filter(Boolean);continue}let s=r.match(/^[-*] (.+)/);if(n){let e=Ge(s?s[1]??``:r);e&&i.entries.push({content:e})}}return t}function Ke(e){let t=[];e.size>0&&t.push(`# Memory`,``);for(let[n,r]of e){t.push(`## ${n}`),r.created&&t.push(`<!-- created: ${r.created} -->`),r.sectionTags.length>0&&t.push(`<!-- tags: ${r.sectionTags.join(`, `)} -->`);let e=new Set;for(let n of r.entries){let r=n.content.trim();!r||e.has(r)||(e.add(r),t.push(`- ${r}`))}t.push(``)}return t.join(`
71
- `)}function qe(e,t){let n=Y(t);if(n.size===0)return null;let r=Y(e);for(let[e,t]of n)r.set(e,t);return Ke(r)}const X=new class{providers=new Map;byPluginId=new Map;register(e){this.providers.set(e.id,e),e.pluginId&&this.byPluginId.set(e.pluginId,e.id)}getById(e){return this.providers.get(e)}getByPluginId(e){let t=this.byPluginId.get(e);return t?this.providers.get(t):void 0}clear(){this.providers.clear(),this.byPluginId.clear()}};function Je(e){let t=e.id?.trim()||e.pluginId;return X.register({id:t,pluginId:e.pluginId,create:e.create,config:e.config,rootDir:e.rootDir,source:e.source}),t}function Z(e){let t=e.providerId?.trim(),n=e.pluginId?.trim(),r=(t?X.getById(t):void 0)??(n?X.getByPluginId(n):void 0);if(!r)return null;let i={dataDir:e.dataDir,memoryDir:e.memoryDir,sessionId:e.sessionId,sessionStoreName:e.sessionStoreName,pluginId:r.pluginId,config:r.config,rootDir:r.rootDir,source:r.source};return{provider:r.create(i),registration:r}}function Ye(){X.clear()}var Xe=e({createDefaultMemoryProvider:()=>Q,resolveMemoryProviderOrDefault:()=>$});function Q(e,t){let n=q(e,t),r=async()=>{try{return await a.readFile(o.join(e.memoryDir,`MEMORY.md`),`utf-8`)}catch(e){if(e.code===`ENOENT`)return``;throw e}};return{...n,appendRecent:async(t,n)=>{await We(e.memoryDir,t,n,e.sessionId)},updateFile:async(e,t)=>{if(e!==`MEMORY.md`){await n.updateFile(e,t);return}let i=await r(),a=/^#\s+Memory\s*$/m.test(t)?qe(i,t):null;await n.updateFile(e,a??t)}}}function $(e){let t=Z({providerId:e.providerId,pluginId:e.pluginId,dataDir:e.dataDir,memoryDir:e.memoryDir,sessionId:e.sessionId,sessionStoreName:e.sessionStoreName});if(t)return{provider:t.provider,registration:t.registration,providerId:t.registration.id,pluginId:t.registration.pluginId,providerSource:`plugin`,fallbackToBuiltin:!1};let n=Q({dataDir:e.dataDir,memoryDir:e.memoryDir,sessionId:e.sessionId,sessionStoreName:e.sessionStoreName},{includeSessions:e.includeSessions});return{provider:n,providerId:n.id,providerSource:`builtin`,fallbackToBuiltin:!0}}export{Ye as a,V as c,pe as d,T as f,g,_ as h,Je as i,z as l,y as m,Xe as n,Z as o,x as p,$ as r,q as s,Q as t,fe as u};
64
+ size=excluded.size`).run(e.path,t.source,e.hash,e.mtimeMs,e.size)}buildSourceFilter(){let e=this.config.sources;return e.length?{sql:` AND source IN (${e.map(()=>`?`).join(`, `)})`,params:e}:{sql:``,params:[]}}async searchVector(e,t){return await ke({db:this.db,vectorTable:F,providerModel:this.provider.model,queryVec:e,limit:t,snippetMaxChars:700,ensureVectorReady:async e=>await this.ensureVectorReady(e),sourceFilterVec:this.buildSourceFilter(),sourceFilterChunks:this.buildSourceFilter()})}async searchKeyword(e,t){return this.ftsAvailable?await je({db:this.db,ftsTable:I,providerModel:this.provider.model,query:e,limit:t,snippetMaxChars:700,sourceFilter:this.buildSourceFilter(),buildFtsQuery:e=>we(e),bm25RankToScore:Te}):[]}resetIndex(){if(this.db.exec(`DELETE FROM files`),this.db.exec(`DELETE FROM chunks`),this.ftsAvailable)try{this.db.exec(`DELETE FROM ${I}`)}catch{}this.dropVectorTable(),this.vector.dims=void 0,this.sessionsDirtyFiles.clear()}async syncAndPostCheck(e){try{await this.sync({reason:`mutation-postcheck`})}catch{this.searchFallbackOnly=!0;return}this.searchFallbackOnly=!this.indexHasSearchableData()}indexHasSearchableData(){try{if((this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get()?.c??0)>0)return!0}catch{}try{if(d.readdirSync(this.memoryRoot).filter(e=>e.endsWith(`.md`)).length>0)return!1;let e=c.join(this.memoryRoot,`memory`);return d.existsSync(e)?d.readdirSync(e).filter(e=>e.endsWith(`.md`)).length===0:!0}catch{return!1}}async fileScanSearch(e){let t=e.trim().toLowerCase();if(!t)return[];let n=await _(this.memoryRoot),r=[];for(let e of n){let n=``;try{n=await s.readFile(e,`utf-8`)}catch{continue}let i=c.relative(this.memoryRoot,e).replace(/\\/g,`/`);i.startsWith(`memory/`);let a=n.split(`
65
+ `);for(let n=0;n<a.length;n+=1){let o=a[n]??``,s=o.toLowerCase();if(!s.includes(t))continue;let c=s===t?1:Math.max(.2,t.length/Math.max(o.length,t.length));r.push({path:i||l(e),startLine:n+1,endLine:n+1,score:Number(c.toFixed(4)),snippet:o.slice(0,700),source:`memory`})}}return r.sort((e,t)=>t.score-e.score||e.path.localeCompare(t.path)||e.startLine-t.startLine),r.slice(0,this.config.maxResults)}getFtsRowCount(){if(this.ftsAvailable)try{return this.db.prepare(`SELECT COUNT(*) as c FROM ${I}`).get()?.c??0}catch{return}}buildRebuildSummary(e){let t=this.db.prepare(`SELECT COUNT(*) as c FROM chunks`).get();return{reason:e.reason,memoryFilesIndexed:e.memoryFilesIndexed,sessionFilesIndexed:e.sessionFilesIndexed,staleMemoryFilesRemoved:e.staleMemoryFilesRemoved,staleSessionFilesRemoved:e.staleSessionFilesRemoved,chunks:t?.c??0,ftsRows:this.getFtsRowCount(),fallbackActive:this.searchFallbackOnly,needsFullReindex:e.needsFullReindex}}async rebuild(e=`manual-rebuild`){return this.resetIndex(),this.dirty=!0,this.sessionsDirty=!0,await this.sync({reason:e,forceFullReindex:!0}),this.lastRebuildSummary??this.buildRebuildSummary({reason:e,memoryFilesIndexed:0,sessionFilesIndexed:0,staleMemoryFilesRemoved:0,staleSessionFilesRemoved:0,needsFullReindex:!0})}async sync(e){let t=this.readMeta(),n=e?.forceFullReindex||!t||t.model!==this.provider.model||t.provider!==this.provider.id||t.providerKey!==this.providerKey||t.chunkTokens!==this.config.chunkTokens||t.chunkOverlap!==this.config.chunkOverlap||this.vector.available&&!t?.vectorDims;n&&this.resetIndex();let r=await _(this.memoryRoot),i=(await Promise.all(r.map(async e=>te(e,this.memoryRoot)))).filter(e=>e!==null),a=new Set(i.map(e=>e.path)),o=0,s=i.map(e=>async()=>{let t=this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(e.path,`memory`);!n&&t?.hash===e.hash||(await this.indexFile(e,{source:`memory`}),o+=1)});for(let e of s)await e();let c=0,l=this.db.prepare(`SELECT path FROM files WHERE source = ?`).all(`memory`);for(let e of l)if(!a.has(e.path)){this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(e.path,`memory`),c+=1;try{this.db.prepare(`DELETE FROM ${F} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,`memory`)}catch{}if(this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,`memory`),this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${I} WHERE path = ? AND source = ? AND model = ?`).run(e.path,`memory`,this.provider.model)}catch{}}let u={indexed:0,staleRemoved:0};this.config.experimental.sessionMemory&&(n||this.sessionsDirty)&&(u=await this.syncSessionFiles(n)),this.writeMeta({model:this.provider.model,provider:this.provider.id,providerKey:this.providerKey,chunkTokens:this.config.chunkTokens,chunkOverlap:this.config.chunkOverlap,...this.vector.available&&this.vector.dims?{vectorDims:this.vector.dims}:{}}),this.dirty=!1,this.searchFallbackOnly=!this.indexHasSearchableData(),this.lastRebuildSummary=this.buildRebuildSummary({reason:e?.reason??`sync`,memoryFilesIndexed:o,sessionFilesIndexed:u.indexed,staleMemoryFilesRemoved:c,staleSessionFilesRemoved:u.staleRemoved,needsFullReindex:!!n})}async syncSessionFiles(e){let t=await Me(this.dataDir,this.sessionStoreName),n=(await Promise.all(t.map(async e=>Pe(this.dataDir,e,this.sessionStoreName)))).filter(e=>e!==null),r=new Set(n.map(e=>e.path)),i=e||this.sessionsDirtyFiles.size===0,a=0;for(let t of n){if(!i&&!this.sessionsDirtyFiles.has(t.absPath))continue;let n=this.db.prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`).get(t.path,`sessions`);if(!e&&n?.hash===t.hash){this.resetSessionDelta(t.absPath,t.size);continue}await this.indexFile(t,{source:`sessions`,content:t.content,lineMap:t.lineMap}),a+=1,this.resetSessionDelta(t.absPath,t.size)}let o=0,s=this.db.prepare(`SELECT path FROM files WHERE source = ?`).all(`sessions`);for(let e of s)if(!r.has(e.path)){this.db.prepare(`DELETE FROM files WHERE path = ? AND source = ?`).run(e.path,`sessions`),o+=1;try{this.db.prepare(`DELETE FROM ${F} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`).run(e.path,`sessions`)}catch{}if(this.db.prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`).run(e.path,`sessions`),this.ftsAvailable)try{this.db.prepare(`DELETE FROM ${I} WHERE path = ? AND source = ? AND model = ?`).run(e.path,`sessions`,this.provider.model)}catch{}}return this.sessionsDirty=!1,this.sessionsDirtyFiles.clear(),{indexed:a,staleRemoved:o}}resetSessionDelta(e,t){let n=this.sessionDeltas.get(e);n&&(n.lastSize=t,n.pendingBytes=0,n.pendingMessages=0)}decorateCitations(e){return this.config.citations===`off`?e:e.map(e=>{let t=`Source: ${e.path}#L${e.startLine}-L${e.endLine}`;return this.config.citations===`on`?{...e,citation:t,snippet:`${e.snippet}\n\n${t}`}:{...e,citation:t}})}decorateEntryIds(e){return e.map(e=>{if(e.id)return e;let t=Fe(e.path,e.snippet,e.startLine);return{...e,id:t}})}};function W(e){return e instanceof Error?e.message:String(e)}function G(e){return V(e)}function K(e,t){let n=t.trim();if(!n)throw Error(`path required`);let r=c.isAbsolute(n)?c.resolve(n):c.resolve(e,n),i=c.relative(e,r).replace(/\\/g,`/`);if(!(i.length>0&&!i.startsWith(`..`)&&!c.isAbsolute(i))||!h(i)||!r.endsWith(`.md`))throw Error(`path required`);return{absPath:r,relPath:i}}async function q(e,t){let n=t.trim().toLowerCase();if(!n)return[];let r=await _(e),i=[];for(let t of r){let r;try{r=await s.readFile(t,`utf-8`)}catch{continue}let a=c.relative(e,t).replace(/\\/g,`/`)||c.basename(t),o=r.split(`
66
+ `);for(let e=0;e<o.length;e+=1){let t=o[e]??``,r=t.toLowerCase();if(!r.includes(n))continue;let s=r===n?1:Math.max(.2,n.length/Math.max(t.length,n.length));i.push({id:`${a}#L${e+1}`,path:a,startLine:e+1,endLine:e+1,score:Number(s.toFixed(4)),snippet:t.slice(0,700),source:`memory`})}}return i.sort((e,t)=>t.score-e.score||e.path.localeCompare(t.path)||e.startLine-t.startLine),i.slice(0,20)}function J(e,t){let n=e.memoryDir;return{id:`builtin-memory`,name:`Builtin Memory Provider`,status:()=>({backend:`builtin`,provider:`builtin-memory`,workspaceDir:n,dbPath:c.join(n,`.index.sqlite`),dirty:!0,files:void 0,chunks:void 0,fts:{enabled:!1,available:!1,error:t},vector:{enabled:!1,available:!1,loadError:t},custom:{searchMode:`file-scan`,fallbackActive:!0,fallbackReason:t}}),search:async e=>q(n,e),getLines:async(e,t,r)=>{let{absPath:i,relPath:a}=K(n,e),o;try{o=await s.readFile(i,`utf-8`)}catch{return[]}let c=o.split(`
67
+ `),l=Math.max(1,t),u=Math.max(1,r-l+1);return c.slice(l-1,l-1+u)},listFiles:async()=>_(n),append:async e=>{await s.mkdir(n,{recursive:!0});let t=e.endsWith(`
68
+ `)?e:`${e}\n`;await s.appendFile(c.join(n,`MEMORY.md`),t,`utf-8`)},updateFile:async(e,t)=>{let{absPath:r}=K(n,e);await s.mkdir(c.dirname(r),{recursive:!0}),await s.writeFile(r,t,`utf-8`)},deleteFile:async e=>{let{absPath:t}=K(n,e);await s.unlink(t).catch(e=>{if(e.code!==`ENOENT`)throw e})},sync:async()=>{},noteSessionUpdate:()=>{}}}function Y(e,t){let n=e.memoryDir,r=t?.includeSessions?{experimental:{sessionMemory:!0},sources:[`memory`,`sessions`],store:{sessionStoreName:e.sessionStoreName,vector:{enabled:!0}}}:e.sessionStoreName?{store:{sessionStoreName:e.sessionStoreName,vector:{enabled:!0}}}:void 0,i;try{i=U.get(e.dataDir,r)}catch(t){if(G(t))return J(e,W(t));throw t}let a=async(e,t)=>{try{return await e()}catch(e){if(!G(e))throw e;return await t()}};return{id:`builtin-memory`,name:`Builtin Memory Provider`,status:()=>{try{return i.status()}catch(t){if(G(t))return J(e,W(t)).status();throw t}},search:async(e,t)=>a(()=>i.search(e),()=>q(n,e)),getLines:async(t,n,r)=>await a(async()=>{let e=Math.max(1,r-n+1),a=await i.readFile({relPath:t,from:n,lines:e});return a.text?a.text.split(`
69
+ `):[]},()=>J(e).getLines(t,n,r)),listFiles:async()=>_(n),append:async t=>a(()=>i.appendToMemory(t),()=>J(e).append(t)),updateFile:async(t,n)=>{await a(()=>i.replaceFile({relPath:t,content:n}),()=>J(e).updateFile(t,n))},deleteFile:async t=>{await a(()=>i.deleteFile(t),()=>J(e).deleteFile(t))},sync:async e=>{await a(async()=>{if(e===`cli-rebuild`){await i.rebuild(e);return}await i.sync({reason:e??`provider-sync`})},async()=>{})},noteSessionUpdate:e=>{let t=c.isAbsolute(e)?e:c.resolve(e);i.noteSessionUpdate(t)}}}function X(){let e=new Date;return{date:e.toISOString().slice(0,10),time:`${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}`}}function ze(e,t){let{date:n}=X();return e===`session`&&t?`session-${t}.md`:`${n}.md`}async function Be(e,t,n,r){let{time:i}=X(),a=ze(n,r),o=c.join(e,`memory`,a);await s.mkdir(c.dirname(o),{recursive:!0}),await s.appendFile(o,`- [${i}] ${t.trim()}\n`,`utf-8`)}function Ve(e){return e.replace(/\s*\[[^\]]+\]\s*$/,``).trim()}function Z(e){let t=new Map,n=``;for(let r of e.split(`
70
+ `)){let e=r.match(/^## (.+)/);if(e){n=e[1].trim(),t.has(n)||t.set(n,{entries:[],sectionTags:[]});continue}let i=t.get(n);if(!i)continue;let a=r.match(/<!--\s*created:\s*(\d{4}-\d{2}-\d{2})\s*-->/);if(a){i.created=a[1];continue}let o=r.match(/<!--\s*tags:\s*([^>]*?)-->/);if(o){i.sectionTags=o[1].split(`,`).map(e=>e.trim()).filter(Boolean);continue}let s=r.match(/^[-*] (.+)/);if(n){let e=Ve(s?s[1]??``:r);e&&i.entries.push({content:e})}}return t}function He(e){let t=[];e.size>0&&t.push(`# Memory`,``);for(let[n,r]of e){t.push(`## ${n}`),r.created&&t.push(`<!-- created: ${r.created} -->`),r.sectionTags.length>0&&t.push(`<!-- tags: ${r.sectionTags.join(`, `)} -->`);let e=new Set;for(let n of r.entries){let r=n.content.trim();!r||e.has(r)||(e.add(r),t.push(`- ${r}`))}t.push(``)}return t.join(`
71
+ `)}function Ue(e,t){let n=Z(t);if(n.size===0)return null;let r=Z(e);for(let[e,t]of n)r.set(e,t);return He(r)}var We=e({createDefaultMemoryProvider:()=>Q,resolveMemoryProviderOrDefault:()=>$});function Q(e,t){let n=Y(e,t),r=async()=>{try{return await s.readFile(c.join(e.memoryDir,`MEMORY.md`),`utf-8`)}catch(e){if(e.code===`ENOENT`)return``;throw e}};return{...n,appendRecent:async(t,n)=>{await Be(e.memoryDir,t,n,e.sessionId)},updateFile:async(e,t)=>{if(e!==`MEMORY.md`){await n.updateFile(e,t);return}let i=await r(),a=/^#\s+Memory\s*$/m.test(t)?Ue(i,t):null;await n.updateFile(e,a??t)}}}function $(e){let t=a({providerId:e.providerId,pluginId:e.pluginId,dataDir:e.dataDir,memoryDir:e.memoryDir,sessionId:e.sessionId,sessionStoreName:e.sessionStoreName});if(t)return{provider:t.provider,registration:t.registration,providerId:t.registration.id,pluginId:t.registration.pluginId,providerSource:`plugin`,fallbackToBuiltin:!1};let n=Q({dataDir:e.dataDir,memoryDir:e.memoryDir,sessionId:e.sessionId,sessionStoreName:e.sessionStoreName},{includeSessions:e.includeSessions});return{provider:n,providerId:n.id,providerSource:`builtin`,fallbackToBuiltin:!0}}export{U as a,b as c,Y as i,v as l,We as n,V as o,$ as r,S as s,Q as t,_ as u};
@@ -1 +1 @@
1
- import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{E as t}from"./session-DIkujhuw.js";import n from"node:fs/promises";import r from"node:path";var i=e({appendGoalEvent:()=>o,goalEventsPath:()=>a});function a(e,n,i){return r.join(t(e,n,i),`goal`,`events.jsonl`)}async function o(e,t,i,o){let s={...i,sessionId:t,timestamp:new Date().toISOString()},c=a(e,t,o);await n.mkdir(r.dirname(c),{recursive:!0}),await n.appendFile(c,`${JSON.stringify(s)}\n`,`utf-8`)}export{a as n,i as r,o as t};
1
+ import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{E as t}from"./session-CvZsdTZJ.js";import n from"node:fs/promises";import r from"node:path";var i=e({appendGoalEvent:()=>o,goalEventsPath:()=>a});function a(e,n,i){return r.join(t(e,n,i),`goal`,`events.jsonl`)}async function o(e,t,i,o){let s={...i,sessionId:t,timestamp:new Date().toISOString()},c=a(e,t,o);await n.mkdir(r.dirname(c),{recursive:!0}),await n.appendFile(c,`${JSON.stringify(s)}\n`,`utf-8`)}export{a as n,i as r,o as t};
@@ -1 +1 @@
1
- import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{E as t,P as n}from"./session-DIkujhuw.js";import{t as r}from"./goal-events-vnNkQVzi.js";import{MAX_GOAL_OBJECTIVE_CHARS as i}from"@gencode/shared";import a from"node:fs/promises";import o from"node:path";import{randomUUID as s}from"node:crypto";var c=e({GOAL_OBJECTIVE_REF:()=>u,GoalObjectiveResolutionError:()=>l,deleteGoal:()=>v,goalDir:()=>d,goalObjectiveMdPath:()=>p,goalPath:()=>f,mirrorGoalStatusToSession:()=>y,readGoal:()=>m,resolveGoalObjective:()=>h,updateGoal:()=>_,writeGoal:()=>g}),l=class extends Error{constructor(e,t){super(e,t),this.name=`GoalObjectiveResolutionError`}};const u=`goal/objective.md`;function d(e,n,r){return o.join(t(e,n,r),`goal`)}function f(e,t,n){return o.join(d(e,t,n),`goal.json`)}function p(e,t,n){return o.join(d(e,t,n),`objective.md`)}async function m(e,t,n){let r=f(e,t,n);try{let e=await a.readFile(r,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async function h(e,n,r,i){if(r.objectiveRef){let s=o.join(t(e,n,i),r.objectiveRef);try{return await a.readFile(s,`utf-8`)}catch(e){throw new l(`Goal objective reference "${r.objectiveRef}" could not be read for session "${n}"`,{cause:e})}}return r.objective}async function g(e,t,n,o){let c=await m(e,t,o),l=n.objective.trim(),g=new Date().toISOString(),_={...n,objective:l,goalId:n.goalId??s(),createdAt:n.createdAt??g,updatedAt:n.updatedAt??g};c&&((await h(e,t,c,o)).trim()===l?c.pendingObjectiveUpdatedNotice&&(_.pendingObjectiveUpdatedNotice=!0):_.pendingObjectiveUpdatedNotice=!0);let v=d(e,t,o);await a.mkdir(v,{recursive:!0});let b;if(_.objective.length>i)b=_.objective,_.objective=_.objective.slice(0,200)+`...`,_.objectiveRef=u;else{delete _.objectiveRef;try{await a.unlink(p(e,t,o))}catch(e){if(e.code!==`ENOENT`)throw e}}if(b!==void 0){let n=p(e,t,o),r=n+`.tmp`;await a.writeFile(r,b,`utf-8`),await a.rename(r,n)}let x=f(e,t,o),S=x+`.tmp`;return await a.writeFile(S,JSON.stringify(_,null,2),`utf-8`),await a.rename(S,x),await y(e,t,_.status,o),await r(e,t,{goalId:_.goalId,action:c?`replaced`:`created`,status:_.status,source:o?.eventSource??`store`,detail:c?{previousGoalId:c.goalId}:void 0},o),_}async function _(e,t,n,i){let o=await m(e,t,i);if(!o)return null;if(`objective`in n||`objectiveRef`in n||`goalId`in n||`createdAt`in n)throw Error(`updateGoal only supports status, tokenBudget, tokensUsed, and timeUsedSeconds; use writeGoal() to change the objective`);let s={...o,...n,updatedAt:new Date().toISOString()},c=f(e,t,i),l=c+`.tmp`;await a.writeFile(l,JSON.stringify(s,null,2),`utf-8`),await a.rename(l,c),n.status!==void 0&&await y(e,t,s.status,i);let u=n.status===`paused`?`paused`:n.status===`active`&&o.status!==`active`?`resumed`:n.status===`budget_limited`?`budget_limited`:n.status===`complete`?`completed`:`updated`;return await r(e,t,{goalId:s.goalId,action:u,status:s.status,source:i?.eventSource??`store`,detail:{fields:Object.keys(n)}},i),s}async function v(e,t,n){let i=await m(e,t,n);return i?(await r(e,t,{goalId:i.goalId,action:`deleted`,status:null,source:n?.eventSource??`store`},n),await a.rm(d(e,t,n),{recursive:!0,force:!0}),await y(e,t,null,n),!0):!1}async function y(e,t,r,i){await n(e,t,{goalStatus:r},i)}export{c as a,h as c,f as i,_ as l,d as n,y as o,p as r,m as s,v as t,g as u};
1
+ import{t as e}from"./rolldown-runtime-CNxR59P3.js";import{E as t,P as n}from"./session-CvZsdTZJ.js";import{t as r}from"./goal-events-BtFriEK5.js";import{MAX_GOAL_OBJECTIVE_CHARS as i}from"@gencode/shared";import a from"node:fs/promises";import o from"node:path";import{randomUUID as s}from"node:crypto";var c=e({GOAL_OBJECTIVE_REF:()=>u,GoalObjectiveResolutionError:()=>l,deleteGoal:()=>v,goalDir:()=>d,goalObjectiveMdPath:()=>p,goalPath:()=>f,mirrorGoalStatusToSession:()=>y,readGoal:()=>m,resolveGoalObjective:()=>h,updateGoal:()=>_,writeGoal:()=>g}),l=class extends Error{constructor(e,t){super(e,t),this.name=`GoalObjectiveResolutionError`}};const u=`goal/objective.md`;function d(e,n,r){return o.join(t(e,n,r),`goal`)}function f(e,t,n){return o.join(d(e,t,n),`goal.json`)}function p(e,t,n){return o.join(d(e,t,n),`objective.md`)}async function m(e,t,n){let r=f(e,t,n);try{let e=await a.readFile(r,`utf-8`);return JSON.parse(e)}catch(e){if(e.code===`ENOENT`)return null;throw e}}async function h(e,n,r,i){if(r.objectiveRef){let s=o.join(t(e,n,i),r.objectiveRef);try{return await a.readFile(s,`utf-8`)}catch(e){throw new l(`Goal objective reference "${r.objectiveRef}" could not be read for session "${n}"`,{cause:e})}}return r.objective}async function g(e,t,n,o){let c=await m(e,t,o),l=n.objective.trim(),g=new Date().toISOString(),_={...n,objective:l,goalId:n.goalId??s(),createdAt:n.createdAt??g,updatedAt:n.updatedAt??g};c&&((await h(e,t,c,o)).trim()===l?c.pendingObjectiveUpdatedNotice&&(_.pendingObjectiveUpdatedNotice=!0):_.pendingObjectiveUpdatedNotice=!0);let v=d(e,t,o);await a.mkdir(v,{recursive:!0});let b;if(_.objective.length>i)b=_.objective,_.objective=_.objective.slice(0,200)+`...`,_.objectiveRef=u;else{delete _.objectiveRef;try{await a.unlink(p(e,t,o))}catch(e){if(e.code!==`ENOENT`)throw e}}if(b!==void 0){let n=p(e,t,o),r=n+`.tmp`;await a.writeFile(r,b,`utf-8`),await a.rename(r,n)}let x=f(e,t,o),S=x+`.tmp`;return await a.writeFile(S,JSON.stringify(_,null,2),`utf-8`),await a.rename(S,x),await y(e,t,_.status,o),await r(e,t,{goalId:_.goalId,action:c?`replaced`:`created`,status:_.status,source:o?.eventSource??`store`,detail:c?{previousGoalId:c.goalId}:void 0},o),_}async function _(e,t,n,i){let o=await m(e,t,i);if(!o)return null;if(`objective`in n||`objectiveRef`in n||`goalId`in n||`createdAt`in n)throw Error(`updateGoal only supports status, tokenBudget, tokensUsed, and timeUsedSeconds; use writeGoal() to change the objective`);let s={...o,...n,updatedAt:new Date().toISOString()},c=f(e,t,i),l=c+`.tmp`;await a.writeFile(l,JSON.stringify(s,null,2),`utf-8`),await a.rename(l,c),n.status!==void 0&&await y(e,t,s.status,i);let u=n.status===`paused`?`paused`:n.status===`active`&&o.status!==`active`?`resumed`:n.status===`budget_limited`?`budget_limited`:n.status===`complete`?`completed`:`updated`;return await r(e,t,{goalId:s.goalId,action:u,status:s.status,source:i?.eventSource??`store`,detail:{fields:Object.keys(n)}},i),s}async function v(e,t,n){let i=await m(e,t,n);return i?(await r(e,t,{goalId:i.goalId,action:`deleted`,status:null,source:n?.eventSource??`store`},n),await a.rm(d(e,t,n),{recursive:!0,force:!0}),await y(e,t,null,n),!0):!1}async function y(e,t,r,i){await n(e,t,{goalStatus:r},i)}export{c as a,h as c,f as i,_ as l,d as n,y as o,p as r,m as s,v as t,g as u};
@@ -1,3 +1,3 @@
1
- import e from"node:fs/promises";import t from"node:path";import n from"node:crypto";import{spawn as r}from"node:child_process";import{createJiti as i}from"jiti";function a(e,t){return{id:`pi:${e}`,name:e,version:`0.0.0-${n.createHash(`sha256`).update(t).digest(`hex`).slice(0,8)}`,description:`Pi extension ${e}`,configSchema:{}}}function o(e){return(e.split(/[/\\]/).pop()??`extension`).replace(/\.(ts|js|mts|cts)$/i,``)}const s=[`.js`,`.ts`,`.mjs`,`.mts`,`.cjs`,`.cts`],c=[`index.js`,`index.mjs`,`index.cjs`,`index.ts`,`index.mts`,`index.cts`];let l,u=null;async function d(e){return u||(u=await m(e),console.log(`[PiExtensionLoader] Pre-loaded ${u.length} extension(s)`),u)}async function f(e){return u||(!e||e.length===0?[]:(console.log(`[PiExtensionLoader] No pre-loaded cache, loading now (cold start)`),await m(e)))}function p(){return l||=i(import.meta.url,{interopDefault:!0,requireCache:!0}),l}async function m(e){let t=new Set;for(let n of e)await h(n,t);let n=p(),r=[];for(let e of[...t].sort()){let t;try{t=n(e)}catch(t){console.warn(`[PiExtensionLoader] Failed to load extension from ${e}:`,t);continue}let i=typeof t==`function`?t:t&&typeof t==`object`&&`default`in t?t.default:void 0;if(typeof i!=`function`){console.warn(`[PiExtensionLoader] Skipping ${e}: no default function export`);continue}r.push({factory:i,sourcePath:e,name:o(e)})}return r}async function h(n,r){let i;try{i=await e.readdir(n,{withFileTypes:!0})}catch{return}for(let e of c)if(i.find(t=>t.isFile()&&String(t.name)===e)){r.add(t.join(n,e));return}for(let e of i){let i=t.join(n,String(e.name));if(e.isDirectory()){await h(i,r);continue}if(!e.isFile())continue;let a=String(e.name);s.some(e=>a.endsWith(e))&&r.add(i)}}var g=class{filePath;constructor(e){this.filePath=t.join(e,`pi-extension-entries.jsonl`)}async appendEntry(t,n){let r={type:t,data:n,timestamp:Date.now()};await e.appendFile(this.filePath,`${JSON.stringify(r)}\n`,`utf-8`)}async readEntries(){try{return(await e.readFile(this.filePath,`utf-8`)).trim().split(`
2
- `).filter(Boolean).map(e=>JSON.parse(e))}catch{return[]}}};function _(e){return{name:e.name,label:e.name,description:e.description??e.name,parameters:y(e.parameters),async execute(t,n,r,i){let a=await e.execute(t,n??{},r,i);return{content:a.content,details:a.details??{},isError:a.isError??!1}}}}function v(e){return y(e)}function y(e){if(!e||typeof e!=`object`)return{type:`object`,properties:{}};let t=e;return t.type===`object`||t.properties||typeof t.$schema==`string`||t.$id?t:{type:`object`,properties:t}}const b={tool_call:`before_tool_call`,tool_result:`tool_result`,turn_start:`turn_start`,turn_end:`turn_end`,agent_start:`agent_start`,before_agent_start:`before_agent_start`,agent_end:`agent_end`,session_start:`session_start`,session_shutdown:`session_end`,session_end:`session_end`,input:`input`,resources_discover:`resources_discover`,context:`context`,before_provider_request:`before_provider_request`,session_before_compact:`before_compaction`,session_compact:`after_compaction`,session_before_switch:`session_before_switch`,session_before_fork:`session_before_fork`};var x=class{commands=new Map;flags=new Map;activeTools=null;constructor(e){this.extensions=e}async activate(e){for(let t of this.extensions){let n=a(t.name,t.sourcePath).id,r=this.createExtensionAPI(n,e,t.sourcePath);try{await t.factory(r)}catch(e){console.warn(`[PiExtensionHost] Failed to activate extension "${t.name}":`,e)}}}getRegisteredCommands(){return this.commands}resolveCommand(e){return this.commands.get(e.replace(/^\//,``).toLowerCase())}getRegisteredFlags(){return this.flags}createExtensionAPI(e,t,n){let i=t.sessionDir??t.hookContext.session?.getSessionDir(),a=i?new g(i):void 0,o={notify:(n,r=`info`)=>{t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:r,scope:`plugin`,phase:`pi_extension_notify`,message:n,details:{pluginId:e}}).catch(()=>void 0)},confirm:async n=>t.dialogBridge?.confirm?t.dialogBridge.confirm(n,e):(t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`warn`,scope:`plugin`,phase:`pi_extension_confirm`,message:`Confirm: ${n}`,details:{pluginId:e}}).catch(()=>void 0),!1),select:async(n,r)=>{if(t.dialogBridge?.select)return t.dialogBridge.select(n,r,e);t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`warn`,scope:`plugin`,phase:`pi_extension_select`,message:`Select (${n}): [${r.join(`, `)}]`,details:{pluginId:e}}).catch(()=>void 0)},setStatus:(n,r)=>{t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`info`,scope:`plugin`,phase:`pi_extension_status`,message:r??n,details:{pluginId:e,statusId:n}}).catch(()=>void 0)},theme:{fg:(e,t)=>t}},s=t.hookContext.workspaceDir,c=t.hookContext.session,l=c?{getEntries:()=>c.getEntries(),getBranch:async()=>c.getBranch?c.getBranch():c.getEntries(),getLeafId:async()=>{if(c.getLeafId)return c.getLeafId();let e=await c.getEntries();return e[e.length-1]?.id??null},getSessionFile:()=>{if(c.getSessionFile)return c.getSessionFile()}}:void 0,u={sessionId:t.sessionId,workspaceDir:s,cwd:s,signal:t.hookContext.signal,hasUI:t.dialogBridge!=null,ui:t.uiBridge??o,appendEntry:a?async(e,t)=>{await a.appendEntry(e,t)}:void 0,sessionManager:l,isIdle:()=>t.runtimeBridge?.isIdle()??!0,compact:e=>{t.runtimeBridge&&t.runtimeBridge.requestCompact(e)},hasPendingMessages:()=>t.runtimeBridge?.hasPendingMessages()??!1};return{on:(r,i)=>{let a=b[r];if(!a){console.warn(`[PiExtensionHost] Extension "${e}" registered unsupported event "${r}". No native hook mapping available.`);return}t.hookRegistry.register({pluginId:e,hookName:a,source:e,handler:((t,a)=>S(r,i,t,u,a,e,n))})},registerTool:n=>{t.toolRegistry.register(e,_(n))},getAllTools:()=>t.toolRegistry.list().map(e=>{let t=e.tool;return{name:t.name??e.names[0]??``,description:t.description??``,parameters:v(t.parameters)}}),setActiveTools:n=>{this.activeTools=new Set(n),t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`info`,scope:`plugin`,phase:`pi_extension_set_active_tools`,message:`Set active tools: ${n.join(`, `)}`,details:{pluginId:e,toolNames:n}}).catch(()=>void 0)},getActiveTools:()=>this.activeTools?Array.from(this.activeTools):[],registerCommand:(...e)=>{let t=String(e[0]??``).replace(/^\//,``).toLowerCase(),n=e[1],r,i;if(typeof n==`function`)r=n,i=typeof e[2]==`string`?e[2]:void 0;else if(n&&typeof n==`object`&&`handler`in n){let e=n;r=e.handler,i=e.description}!t||typeof r!=`function`||this.commands.set(t,{handler:r,description:i})},registerFlag:(t,n)=>{this.flags.set(`${e}:${String(t)}`,n)},getFlag:n=>{let r=`${e}:${n}`;if(this.flags.has(r))return this.flags.get(r);let i=t.piExtensionConfigs?.get(e)?.[n];if(i!==void 0)return i},getCommands:()=>Array.from(this.commands.entries()).map(([t,n])=>({name:t,description:n.description??``,source:`extension`,sourceInfo:{path:e,source:e,scope:`project`,origin:`top-level`,baseDir:void 0}})),exec:(e,t,n)=>new Promise(i=>{let a=r(e,t,{cwd:n?.cwd??s??process.cwd(),shell:!1,stdio:[`ignore`,`pipe`,`pipe`]}),o=``,c=``,l=!1,u=!1,d,f=()=>{l||(l=!0,a.kill(`SIGTERM`),setTimeout(()=>{a.killed||a.kill(`SIGKILL`)},5e3))},p=(e,t)=>{let n=65536-(o.length+c.length);if(n<=0){u||(u=!0,f());return}let r=t.length>n?t.slice(0,n):t;e===`stdout`?o+=r:c+=r,t.length>n&&!u&&(u=!0,f())},m=e=>{if(d&&clearTimeout(d),n?.signal)try{n.signal.removeEventListener(`abort`,f)}catch{}i(e)};n?.signal&&(n.signal.aborted?f():n.signal.addEventListener(`abort`,f,{once:!0})),n?.timeout&&n.timeout>0&&(d=setTimeout(()=>f(),n.timeout)),a.stdout?.on(`data`,e=>{p(`stdout`,e.toString())}),a.stderr?.on(`data`,e=>{p(`stderr`,e.toString())}),a.on(`close`,e=>{m({stdout:o,stderr:c,code:u?1:e??0,killed:u||l})}),a.on(`error`,e=>{m({stdout:o,stderr:e.message,code:1,killed:!0})})}),sendUserMessage:(e,n)=>{let r=typeof e==`string`?e:Array.isArray(e)?e.map(e=>e.text??``).join(`
3
- `):String(e);t.runtimeBridge?t.runtimeBridge.sendUserMessage(r,n):console.warn(`[PiExtensionHost] sendUserMessage called but no runtimeBridge available`)},appendEntry:u.appendEntry}}};function S(e,t,n,r,i,a,o){return C(e,t,n,r,i,o).catch(t=>{console.warn(`[PiExtensionHost] Extension "${a}" handler for "${e}" threw:`,t)})}async function C(e,t,n,r,i,a){let o=n;if(e===`tool_call`){let e=await t({toolCallId:o.toolCallId,toolName:o.toolName,input:o.params??o.input},r);return e?{block:e.block,blockReason:e.reason,params:e.input}:void 0}if(e===`tool_result`){let e=await t({type:`tool_result`,toolCallId:o.toolCallId,toolName:o.toolName,input:o.input,content:o.content,details:o.details,isError:o.isError},r);return e?{content:e.content,details:e.details,isError:e.isError}:void 0}if(e===`before_agent_start`){let e=await t({prompt:o.prompt,systemPrompt:o.systemPrompt,systemPromptOptions:o.systemPromptOptions??{}},r);return e?{systemPrompt:e.systemPrompt,prependContext:e.prependContext,message:e.message??e.messages?.[0]}:void 0}if(e===`input`){let e=await t({text:o.prompt??o.raw},r);return e?e.action===`continue`?{action:`continue`}:e.action===`handled`||e.handled&&e.action===void 0?e.action?{action:`handled`,handled:!0}:{handled:!0}:e.action===`transform`?{action:`transform`,prompt:e.text}:{prompt:e.text,handled:e.handled}:void 0}if(e===`session_before_compact`){let e=await t({messageCount:o.messageCount,compactingCount:o.compactingCount},r);return e?{skipPersist:e.skipPersist??e.skip,injectRecall:e.injectRecall??e.recall}:void 0}if(e===`session_compact`){await t({messageCount:o.messageCount,compactedCount:o.compactedCount},r);return}if(e===`context`){let e=await t({messages:o.messages},r);return e?{messages:e.messages}:void 0}if(e===`before_provider_request`){let e=await t({model:o.model,messages:o.messages,tools:o.tools},r);return e?{messages:e.messages,tools:e.tools,abort:e.abort}:void 0}if(e===`resources_discover`){let e=await t({extensionDir:a},r);return e?{skillPaths:e.skillPaths}:void 0}if(e===`session_start`||e===`session_shutdown`||e===`session_end`){await t({...o,reason:o.reason??(e===`session_start`?`startup`:`normal`)},r);return}if(e===`session_before_switch`){let e=await t({reason:o.reason,targetSessionFile:o.targetSessionFile},r);return e?{cancel:e.cancel}:void 0}if(e===`session_before_fork`){let e=await t({entryId:o.entryId,position:o.position??`before`},r);return e?{cancel:e.cancel}:void 0}return t(n,r)}export{d as a,f as i,g as n,m as r,x as t};
1
+ import{i as e}from"./loader-CkdBGDtW.js";import t from"node:fs/promises";import n from"node:path";import{spawn as r}from"node:child_process";var i=class{filePath;constructor(e){this.filePath=n.join(e,`pi-extension-entries.jsonl`)}async appendEntry(e,n){let r={type:e,data:n,timestamp:Date.now()};await t.appendFile(this.filePath,`${JSON.stringify(r)}\n`,`utf-8`)}async readEntries(){try{return(await t.readFile(this.filePath,`utf-8`)).trim().split(`
2
+ `).filter(Boolean).map(e=>JSON.parse(e))}catch{return[]}}};function a(e){return{name:e.name,label:e.name,description:e.description??e.name,parameters:s(e.parameters),async execute(t,n,r,i){let a=await e.execute(t,n??{},r,i);return{content:a.content,details:a.details??{},isError:a.isError??!1}}}}function o(e){return s(e)}function s(e){if(!e||typeof e!=`object`)return{type:`object`,properties:{}};let t=e;return t.type===`object`||t.properties||typeof t.$schema==`string`||t.$id?t:{type:`object`,properties:t}}const c={tool_call:`before_tool_call`,tool_result:`tool_result`,turn_start:`turn_start`,turn_end:`turn_end`,agent_start:`agent_start`,before_agent_start:`before_agent_start`,agent_end:`agent_end`,session_start:`session_start`,session_shutdown:`session_end`,session_end:`session_end`,input:`input`,resources_discover:`resources_discover`,context:`context`,before_provider_request:`before_provider_request`,session_before_compact:`before_compaction`,session_compact:`after_compaction`,session_before_switch:`session_before_switch`,session_before_fork:`session_before_fork`};var l=class{commands=new Map;flags=new Map;activeTools=null;constructor(e){this.extensions=e}async activate(t){for(let n of this.extensions){let r=e(n.name,n.sourcePath).id,i=this.createExtensionAPI(r,t,n.sourcePath);try{await n.factory(i)}catch(e){console.warn(`[PiExtensionHost] Failed to activate extension "${n.name}":`,e)}}}getRegisteredCommands(){return this.commands}resolveCommand(e){return this.commands.get(e.replace(/^\//,``).toLowerCase())}getRegisteredFlags(){return this.flags}createExtensionAPI(e,t,n){let s=t.sessionDir??t.hookContext.session?.getSessionDir(),l=s?new i(s):void 0,d={notify:(n,r=`info`)=>{t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:r,scope:`plugin`,phase:`pi_extension_notify`,message:n,details:{pluginId:e}}).catch(()=>void 0)},confirm:async n=>t.dialogBridge?.confirm?t.dialogBridge.confirm(n,e):(t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`warn`,scope:`plugin`,phase:`pi_extension_confirm`,message:`Confirm: ${n}`,details:{pluginId:e}}).catch(()=>void 0),!1),select:async(n,r)=>{if(t.dialogBridge?.select)return t.dialogBridge.select(n,r,e);t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`warn`,scope:`plugin`,phase:`pi_extension_select`,message:`Select (${n}): [${r.join(`, `)}]`,details:{pluginId:e}}).catch(()=>void 0)},setStatus:(n,r)=>{t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`info`,scope:`plugin`,phase:`pi_extension_status`,message:r??n,details:{pluginId:e,statusId:n}}).catch(()=>void 0)},theme:{fg:(e,t)=>t}},f=t.hookContext.workspaceDir,p=t.hookContext.session,m=p?{getEntries:()=>p.getEntries(),getBranch:async()=>p.getBranch?p.getBranch():p.getEntries(),getLeafId:async()=>{if(p.getLeafId)return p.getLeafId();let e=await p.getEntries();return e[e.length-1]?.id??null},getSessionFile:()=>{if(p.getSessionFile)return p.getSessionFile()}}:void 0,h={sessionId:t.sessionId,workspaceDir:f,cwd:f,signal:t.hookContext.signal,hasUI:t.dialogBridge!=null,ui:t.uiBridge??d,appendEntry:l?async(e,t)=>{await l.appendEntry(e,t)}:void 0,sessionManager:m,isIdle:()=>t.runtimeBridge?.isIdle()??!0,compact:e=>{t.runtimeBridge&&t.runtimeBridge.requestCompact(e)},hasPendingMessages:()=>t.runtimeBridge?.hasPendingMessages()??!1};return{on:(r,i)=>{let a=c[r];if(!a){console.warn(`[PiExtensionHost] Extension "${e}" registered unsupported event "${r}". No native hook mapping available.`);return}t.hookRegistry.register({pluginId:e,hookName:a,source:e,handler:((t,a)=>u(r,i,t,h,a,e,n))})},registerTool:n=>{t.toolRegistry.register(e,a(n))},getAllTools:()=>t.toolRegistry.list().map(e=>{let t=e.tool;return{name:t.name??e.names[0]??``,description:t.description??``,parameters:o(t.parameters)}}),setActiveTools:n=>{this.activeTools=new Set(n),t.eventDispatcher.dispatchDiagnostic(t.sessionId,{level:`info`,scope:`plugin`,phase:`pi_extension_set_active_tools`,message:`Set active tools: ${n.join(`, `)}`,details:{pluginId:e,toolNames:n}}).catch(()=>void 0)},getActiveTools:()=>this.activeTools?Array.from(this.activeTools):[],registerCommand:(...e)=>{let t=String(e[0]??``).replace(/^\//,``).toLowerCase(),n=e[1],r,i;if(typeof n==`function`)r=n,i=typeof e[2]==`string`?e[2]:void 0;else if(n&&typeof n==`object`&&`handler`in n){let e=n;r=e.handler,i=e.description}!t||typeof r!=`function`||this.commands.set(t,{handler:r,description:i})},registerFlag:(t,n)=>{this.flags.set(`${e}:${String(t)}`,n)},getFlag:n=>{let r=`${e}:${n}`;if(this.flags.has(r))return this.flags.get(r);let i=t.piExtensionConfigs?.get(e)?.[n];if(i!==void 0)return i},getCommands:()=>Array.from(this.commands.entries()).map(([t,n])=>({name:t,description:n.description??``,source:`extension`,sourceInfo:{path:e,source:e,scope:`project`,origin:`top-level`,baseDir:void 0}})),exec:(e,t,n)=>new Promise(i=>{let a=r(e,t,{cwd:n?.cwd??f??process.cwd(),shell:!1,stdio:[`ignore`,`pipe`,`pipe`]}),o=``,s=``,c=!1,l=!1,u,d=()=>{c||(c=!0,a.kill(`SIGTERM`),setTimeout(()=>{a.killed||a.kill(`SIGKILL`)},5e3))},p=(e,t)=>{let n=65536-(o.length+s.length);if(n<=0){l||(l=!0,d());return}let r=t.length>n?t.slice(0,n):t;e===`stdout`?o+=r:s+=r,t.length>n&&!l&&(l=!0,d())},m=e=>{if(u&&clearTimeout(u),n?.signal)try{n.signal.removeEventListener(`abort`,d)}catch{}i(e)};n?.signal&&(n.signal.aborted?d():n.signal.addEventListener(`abort`,d,{once:!0})),n?.timeout&&n.timeout>0&&(u=setTimeout(()=>d(),n.timeout)),a.stdout?.on(`data`,e=>{p(`stdout`,e.toString())}),a.stderr?.on(`data`,e=>{p(`stderr`,e.toString())}),a.on(`close`,e=>{m({stdout:o,stderr:s,code:l?1:e??0,killed:l||c})}),a.on(`error`,e=>{m({stdout:o,stderr:e.message,code:1,killed:!0})})}),sendUserMessage:(e,n)=>{let r=typeof e==`string`?e:Array.isArray(e)?e.map(e=>e.text??``).join(`
3
+ `):String(e);t.runtimeBridge?t.runtimeBridge.sendUserMessage(r,n):console.warn(`[PiExtensionHost] sendUserMessage called but no runtimeBridge available`)},appendEntry:h.appendEntry}}};function u(e,t,n,r,i,a,o){return d(e,t,n,r,i,o).catch(t=>{console.warn(`[PiExtensionHost] Extension "${a}" handler for "${e}" threw:`,t)})}async function d(e,t,n,r,i,a){let o=n;if(e===`tool_call`){let e=await t({toolCallId:o.toolCallId,toolName:o.toolName,input:o.params??o.input},r);return e?{block:e.block,blockReason:e.reason,params:e.input}:void 0}if(e===`tool_result`){let e=await t({type:`tool_result`,toolCallId:o.toolCallId,toolName:o.toolName,input:o.input,content:o.content,details:o.details,isError:o.isError},r);return e?{content:e.content,details:e.details,isError:e.isError}:void 0}if(e===`before_agent_start`){let e=await t({prompt:o.prompt,systemPrompt:o.systemPrompt,systemPromptOptions:o.systemPromptOptions??{}},r);return e?{systemPrompt:e.systemPrompt,prependContext:e.prependContext,message:e.message??e.messages?.[0]}:void 0}if(e===`input`){let e=await t({text:o.prompt??o.raw},r);return e?e.action===`continue`?{action:`continue`}:e.action===`handled`||e.handled&&e.action===void 0?e.action?{action:`handled`,handled:!0}:{handled:!0}:e.action===`transform`?{action:`transform`,prompt:e.text}:{prompt:e.text,handled:e.handled}:void 0}if(e===`session_before_compact`){let e=await t({messageCount:o.messageCount,compactingCount:o.compactingCount},r);return e?{skipPersist:e.skipPersist??e.skip,injectRecall:e.injectRecall??e.recall}:void 0}if(e===`session_compact`){await t({messageCount:o.messageCount,compactedCount:o.compactedCount},r);return}if(e===`context`){let e=await t({messages:o.messages},r);return e?{messages:e.messages}:void 0}if(e===`before_provider_request`){let e=await t({model:o.model,messages:o.messages,tools:o.tools},r);return e?{messages:e.messages,tools:e.tools,abort:e.abort}:void 0}if(e===`resources_discover`){let e=await t({extensionDir:a},r);return e?{skillPaths:e.skillPaths}:void 0}if(e===`session_start`||e===`session_shutdown`||e===`session_end`){await t({...o,reason:o.reason??(e===`session_start`?`startup`:`normal`)},r);return}if(e===`session_before_switch`){let e=await t({reason:o.reason,targetSessionFile:o.targetSessionFile},r);return e?{cancel:e.cancel}:void 0}if(e===`session_before_fork`){let e=await t({entryId:o.entryId,position:o.position??`before`},r);return e?{cancel:e.cancel}:void 0}return t(n,r)}export{i as n,l as t};