@vpxa/aikit 0.1.157 → 0.1.159

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.
@@ -1,4 +1,4 @@
1
- import{createRequire as e}from"node:module";import{dirname as t,extname as n,join as r}from"node:path";import{CHUNK_SIZES as i,createLogger as a}from"../../core/dist/index.js";import{copyFileSync as o,existsSync as s,mkdirSync as c,readFileSync as l,readdirSync as u,realpathSync as d,renameSync as ee}from"node:fs";import{homedir as f}from"node:os";import{fileURLToPath as p}from"node:url";function m(){return{mode:`unknown`,reason:``,pathsChecked:[],os:process.platform,arch:process.arch,nodeVersion:process.version,webTreeSitterImportable:!1,healAttempted:!1,healSuccess:!1,healError:null,initError:null,wasmDir:null,grammarCount:0}}let h=m();const g={get(){return{...h,pathsChecked:h.pathsChecked.map(e=>({...e}))}},update(e){Object.assign(h,e)},reset(){h=m()}},te=[`CI`,`GITHUB_ACTIONS`,`JENKINS_URL`,`GITLAB_CI`,`TF_BUILD`];function _(){return te.some(e=>!!process.env[e])}function v(){if(_())return g.update({healAttempted:!1,healSuccess:!1,healError:null,reason:`CI environment detected - skipping auto-heal`}),null;g.update({healAttempted:!0,healSuccess:!1,healError:null,reason:`Attempting to heal WASM cache from node_modules`});let n=r(f(),`.aikit`,`cache`,`wasm`);try{let i=e(import.meta.url),a;try{a=t(i.resolve(`web-tree-sitter/package.json`)),g.update({webTreeSitterImportable:!0})}catch{return g.update({webTreeSitterImportable:!1,healSuccess:!1,healError:`web-tree-sitter not found in node_modules`,reason:`Cannot heal WASM cache without web-tree-sitter runtime`}),null}let l;try{l=t(i.resolve(`tree-sitter-wasms/package.json`))}catch{return g.update({healSuccess:!1,healError:`tree-sitter-wasms not found in node_modules (devDependency only)`,reason:`Cannot heal WASM cache without tree-sitter-wasms package`}),null}c(n,{recursive:!0});function d(e,t){let n=`${t}.tmp-${process.pid}`;o(e,n),ee(n,t)}let f=r(a,`tree-sitter.wasm`);s(f)&&d(f,r(n,`tree-sitter.wasm`));let p=r(l,`out`),m=0;if(s(p)){let e=u(p).filter(e=>e.endsWith(`.wasm`));m=e.length;for(let t of e)d(r(p,t),r(n,t))}return s(r(n,`tree-sitter.wasm`))?(g.update({healSuccess:!0,healError:null,wasmDir:n,grammarCount:m,reason:`Healed WASM cache from node_modules`}),n):(g.update({healSuccess:!1,healError:`tree-sitter.wasm not found after copy`,reason:`WASM cache heal completed without parser runtime`}),null)}catch(e){return g.update({healSuccess:!1,healError:String(e),reason:`WASM cache heal failed`}),null}}const ne=t(p(import.meta.url));function y(e){try{return d(e)}catch{return e}}const b={".ts":`tree-sitter-typescript.wasm`,".tsx":`tree-sitter-typescript.wasm`,".mts":`tree-sitter-typescript.wasm`,".cts":`tree-sitter-typescript.wasm`,".js":`tree-sitter-javascript.wasm`,".jsx":`tree-sitter-javascript.wasm`,".mjs":`tree-sitter-javascript.wasm`,".cjs":`tree-sitter-javascript.wasm`,".py":`tree-sitter-python.wasm`,".go":`tree-sitter-go.wasm`,".rs":`tree-sitter-rust.wasm`,".java":`tree-sitter-java.wasm`,".kt":`tree-sitter-kotlin.wasm`,".kts":`tree-sitter-kotlin.wasm`,".scala":`tree-sitter-scala.wasm`,".sc":`tree-sitter-scala.wasm`,".c":`tree-sitter-c.wasm`,".h":`tree-sitter-c.wasm`,".cpp":`tree-sitter-cpp.wasm`,".cc":`tree-sitter-cpp.wasm`,".cxx":`tree-sitter-cpp.wasm`,".hpp":`tree-sitter-cpp.wasm`,".hxx":`tree-sitter-cpp.wasm`,".cs":`tree-sitter-c_sharp.wasm`,".swift":`tree-sitter-swift.wasm`,".rb":`tree-sitter-ruby.wasm`,".php":`tree-sitter-php.wasm`},x=new Set(Object.keys(b));let S;function C(e){return[...new Set(Object.values(b))].filter(t=>s(r(e,t))).length}function w(){let e=y(ne),t=[r(f(),`.aikit`,`cache`,`wasm`),r(e,`..`,`..`,`wasm`),r(e,`..`,`wasm`),r(process.cwd(),`node_modules`,`@aikit`,`chunker`,`wasm`)],n=[];for(let e of t){let t=y(e),i=s(r(t,`tree-sitter.wasm`));if(n.push({path:t,exists:i}),i)return g.update({mode:`wasm`,reason:`Resolved WASM directory`,pathsChecked:n,wasmDir:t,grammarCount:C(t),initError:null}),t}return g.update({mode:`unknown`,reason:`No WASM directory containing tree-sitter.wasm was found`,pathsChecked:n,wasmDir:null,grammarCount:0}),null}function T(){return S===void 0&&(S=w()),S}function E(e){S=e===null?null:y(e),g.update({mode:S?`wasm`:`unknown`,reason:S?`WASM directory overridden at runtime`:`WASM directory override cleared`,wasmDir:S,grammarCount:S?C(S):0})}function D(e){let t=b[e];if(!t)return null;let n=T();if(!n)return null;let i=r(n,t);return s(i)?i:null}function O(){let e=T();if(!e)return null;let t=r(e,`tree-sitter.wasm`);return s(t)?t:null}const k=a(`wasm-runtime`);async function A(){let e=await import(`web-tree-sitter`),t=typeof e.default?.init==`function`?e.default:e.Parser;if(!t||typeof t.init!=`function`)throw Error(`Unsupported web-tree-sitter export shape: ${Object.keys(e).join(`, `)}`);return t}var j=class e{static instance=null;parser=null;languages=new Map;loadedGrammars=new Map;recoveryAttempts=0;static MAX_RECOVERIES=3;static MAX_PARSE_SIZE=1e6;static async initialize(){if(e.instance)return e.instance;let t=new e;return await t.init()?(e.instance=t,t):null}static get(){return e.instance}static async ensure(){let t=e.get();if(t)return t;let n=await e.initialize();if(!n)throw Error(`Failed to initialize WASM tree-sitter runtime`);return n}static dispose(){e.instance&&=(e.instance.parser?.delete(),e.instance.parser=null,e.instance.languages.clear(),e.instance.loadedGrammars.clear(),null)}async init(){try{let e;try{e=await A(),g.update({webTreeSitterImportable:!0})}catch(e){return g.update({webTreeSitterImportable:!1,mode:`regex`,reason:`web-tree-sitter import failed: ${String(e)}`,initError:String(e)}),k.warn(`web-tree-sitter module not importable`,{error:String(e)}),!1}let t=O();if(!t){k.info(`Parser WASM not found, attempting auto-heal...`);let e=v();e&&(E(e),t=O(),k.info(`Auto-heal succeeded`,{dir:e}))}if(!t)return g.update({mode:`regex`,reason:`Parser WASM file not found after heal attempt`}),k.warn(`Parser WASM file not found (auto-heal failed or skipped)`),!1;let n=t;return await e.init({locateFile:()=>n}),this.parser=new e,g.update({mode:`wasm`,reason:`WASM parser initialized successfully`,initError:null}),k.info(`WASM tree-sitter parser initialized`),!0}catch(e){return g.update({mode:`regex`,reason:`WASM initialization failed: ${String(e)}`,initError:String(e)}),k.warn(`Failed to initialize WASM tree-sitter`,{error:String(e)}),!1}}async loadLanguage(e){let t=this.languages.get(e);if(t)return t;let n=D(e);if(!n)return null;let r=this.loadedGrammars.get(n);if(r)return this.languages.set(e,r),r;try{let t=await(await A()).Language.load(n);return this.loadedGrammars.set(n,t),this.languages.set(e,t),k.info(`Loaded grammar`,{ext:e}),t}catch(t){return k.warn(`Failed to load grammar`,{ext:e,error:String(t)}),null}}async parse(t,n){if(!this.parser)return null;if(t.length>e.MAX_PARSE_SIZE)return k.warn(`File too large for WASM parser, skipping`,{ext:n,size:t.length}),null;let r=await this.loadLanguage(n);if(!r)return null;try{return this.parser.setLanguage(r),this.parser.parse(t)}catch(r){if(k.warn(`WASM parser crashed, attempting recovery...`,{ext:n,error:String(r)}),this.recoveryAttempts>=e.MAX_RECOVERIES)return k.error(`WASM parser recovery limit reached, falling back to null`,{attempts:this.recoveryAttempts}),null;if(!await this.recoverParser(n))return k.error(`WASM parser recovery failed, falling back to null`),null;try{return this.parser?.parse(t)??null}catch(e){return k.error(`WASM parser crashed again after recovery, falling back to null`,{error:String(e)}),null}}}async recoverParser(e){this.recoveryAttempts++;try{this.parser?.delete(),this.parser=null,this.languages.clear(),this.loadedGrammars.clear();let t=await A(),n=O();if(!n)return k.error(`Cannot recover: parser WASM file not found`),!1;let r=n;await t.init({locateFile:()=>r}),this.parser=new t;let i=await this.loadLanguage(e);return i?(this.parser.setLanguage(i),k.info(`WASM parser recovered successfully`,{attempt:this.recoveryAttempts}),!0):(k.error(`Cannot recover: failed to reload language`,{ext:e}),!1)}catch(e){return k.error(`WASM parser recovery threw`,{error:String(e)}),!1}}hasLanguage(e){return x.has(e)}isLanguageLoaded(e){return this.languages.has(e)}getParser(){return this.parser}getLanguage(e){return this.languages.get(e)??null}};async function M(){return await j.initialize()!==null}const re=a(`call-graph`),ie=new Set([`function_declaration`,`method_definition`,`arrow_function`,`function_definition`,`function_declaration`,`method_declaration`,`function_item`,`method_declaration`,`constructor_declaration`]),ae=new Set([`call_expression`,`new_expression`,`call`]);function oe(e,t){let r=n(t).toLowerCase(),i=j.get();if(i?.isLanguageLoaded(r)){let n=i.getParser(),a=i.getLanguage(r);if(n&&a){n.setLanguage(a);let r;try{r=n.parse(e)}catch(e){return re.warn(`WASM parser.parse() crashed in call-graph extraction`,{file:t,error:String(e)}),null}if(r){let e=[];return N(r.rootNode,t,`<module>`,e),e}}}return null}function N(e,t,n,r){if(!e)return;let i=n;if(ie.has(e.type)&&(i=se(e)??n),ae.has(e.type)){let n=ce(e);n&&r.push({callerFile:t,callerName:i,calleeName:n,line:(e.startPosition?.row??0)+1})}for(let n=0;n<(e.childCount??0);n++){let a=e.child(n);a&&N(a,t,i,r)}}function se(e){for(let t=0;t<(e.childCount??0);t++){let n=e.child(t);if(n&&(n.type===`identifier`||n.type===`property_identifier`||n.type===`name`))return n.text??null}return null}function ce(e){let t=e.childForFieldName?.(`function`)??e.child(0);return t?t.type===`identifier`||t.type===`name`?t.text??null:t.type===`member_expression`||t.type===`attribute`?(t.childForFieldName?.(`property`)??t.childForFieldName?.(`attribute`))?.text??null:e.type===`new_expression`?e.child(1)?.text??null:null:null}var P=class{maxChunkSize;constructor(e){this.maxChunkSize=e?.maxChunkSize??i.code.max}chunk(e,t){let n=this.findDeclarationBoundaries(e);if(n.length===0)return this.fallbackChunk(e,t);let r=[];for(let i=0;i<n.length;i++){let a=n[i].offset,o=i+1<n.length?n[i+1].offset:e.length,s=e.slice(a,o).trim();if(s=`// File: ${t.sourcePath}\n`+s,s.length>this.maxChunkSize){let n=this.splitByLines(s,this.maxChunkSize),i=this.getLineNumber(e,a);for(let e of n){let n=e.split(`
1
+ import{createRequire as e}from"node:module";import{dirname as t,extname as n,join as r}from"node:path";import{CHUNK_SIZES as i,createLogger as a}from"../../core/dist/index.js";import{copyFileSync as o,existsSync as s,mkdirSync as c,readFileSync as l,readdirSync as u,realpathSync as d,renameSync as ee}from"node:fs";import{homedir as f}from"node:os";import{fileURLToPath as p}from"node:url";function m(){return{mode:`unknown`,reason:``,pathsChecked:[],os:process.platform,arch:process.arch,nodeVersion:process.version,webTreeSitterImportable:!1,healAttempted:!1,healSuccess:!1,healError:null,initError:null,wasmDir:null,grammarCount:0}}let h=m();const g={get(){return{...h,pathsChecked:h.pathsChecked.map(e=>({...e}))}},update(e){Object.assign(h,e)},reset(){h=m()}},te=[`CI`,`GITHUB_ACTIONS`,`JENKINS_URL`,`GITLAB_CI`,`TF_BUILD`];function _(){return te.some(e=>!!process.env[e])}function v(){if(_())return g.update({healAttempted:!1,healSuccess:!1,healError:null,reason:`CI environment detected - skipping auto-heal`}),null;g.update({healAttempted:!0,healSuccess:!1,healError:null,reason:`Attempting to heal WASM cache from node_modules`});let n=r(f(),`.aikit`,`cache`,`wasm`);try{let i=e(import.meta.url),a;try{a=t(i.resolve(`web-tree-sitter/package.json`)),g.update({webTreeSitterImportable:!0})}catch{return g.update({webTreeSitterImportable:!1,healSuccess:!1,healError:`web-tree-sitter not found in node_modules`,reason:`Cannot heal WASM cache without web-tree-sitter runtime`}),null}let l;try{l=t(i.resolve(`tree-sitter-wasms/package.json`))}catch{return g.update({healSuccess:!1,healError:`tree-sitter-wasms not found in node_modules (devDependency only)`,reason:`Cannot heal WASM cache without tree-sitter-wasms package`}),null}c(n,{recursive:!0});function d(e,t){let n=`${t}.tmp-${process.pid}`;o(e,n),ee(n,t)}let f=r(a,`tree-sitter.wasm`);s(f)&&d(f,r(n,`tree-sitter.wasm`));let p=r(l,`out`),m=0;if(s(p)){let e=u(p).filter(e=>e.endsWith(`.wasm`));m=e.length;for(let t of e)d(r(p,t),r(n,t))}return s(r(n,`tree-sitter.wasm`))?(g.update({healSuccess:!0,healError:null,wasmDir:n,grammarCount:m,reason:`Healed WASM cache from node_modules`}),n):(g.update({healSuccess:!1,healError:`tree-sitter.wasm not found after copy`,reason:`WASM cache heal completed without parser runtime`}),null)}catch(e){return g.update({healSuccess:!1,healError:String(e),reason:`WASM cache heal failed`}),null}}const ne=t(p(import.meta.url));function y(e){try{return d(e)}catch{return e}}const b={".ts":`tree-sitter-typescript.wasm`,".tsx":`tree-sitter-typescript.wasm`,".mts":`tree-sitter-typescript.wasm`,".cts":`tree-sitter-typescript.wasm`,".js":`tree-sitter-javascript.wasm`,".jsx":`tree-sitter-javascript.wasm`,".mjs":`tree-sitter-javascript.wasm`,".cjs":`tree-sitter-javascript.wasm`,".py":`tree-sitter-python.wasm`,".go":`tree-sitter-go.wasm`,".rs":`tree-sitter-rust.wasm`,".java":`tree-sitter-java.wasm`,".kt":`tree-sitter-kotlin.wasm`,".kts":`tree-sitter-kotlin.wasm`,".scala":`tree-sitter-scala.wasm`,".sc":`tree-sitter-scala.wasm`,".c":`tree-sitter-c.wasm`,".h":`tree-sitter-c.wasm`,".cpp":`tree-sitter-cpp.wasm`,".cc":`tree-sitter-cpp.wasm`,".cxx":`tree-sitter-cpp.wasm`,".hpp":`tree-sitter-cpp.wasm`,".hxx":`tree-sitter-cpp.wasm`,".cs":`tree-sitter-c_sharp.wasm`,".swift":`tree-sitter-swift.wasm`,".rb":`tree-sitter-ruby.wasm`,".php":`tree-sitter-php.wasm`},x=new Set(Object.keys(b));let S;function C(e){return[...new Set(Object.values(b))].filter(t=>s(r(e,t))).length}function w(){let e=y(ne),t=[r(f(),`.aikit`,`cache`,`wasm`),r(e,`..`,`..`,`wasm`),r(e,`..`,`wasm`),r(process.cwd(),`node_modules`,`@aikit`,`chunker`,`wasm`)],n=[];for(let e of t){let t=y(e),i=s(r(t,`tree-sitter.wasm`));if(n.push({path:t,exists:i}),i)return g.update({mode:`wasm`,reason:`Resolved WASM directory`,pathsChecked:n,wasmDir:t,grammarCount:C(t),initError:null}),t}return g.update({mode:`unknown`,reason:`No WASM directory containing tree-sitter.wasm was found`,pathsChecked:n,wasmDir:null,grammarCount:0}),null}function T(){return S===void 0&&(S=w()),S}function E(e){S=e===null?null:y(e),g.update({mode:S?`wasm`:`unknown`,reason:S?`WASM directory overridden at runtime`:`WASM directory override cleared`,wasmDir:S,grammarCount:S?C(S):0})}function D(e){let t=b[e];if(!t)return null;let n=T();if(!n)return null;let i=r(n,t);return s(i)?i:null}function O(){let e=T();if(!e)return null;let t=r(e,`tree-sitter.wasm`);return s(t)?t:null}const k=a(`wasm-runtime`);async function A(){let e=await import(`web-tree-sitter`),t=typeof e.default?.init==`function`?e.default:e.Parser;if(!t||typeof t.init!=`function`)throw Error(`Unsupported web-tree-sitter export shape: ${Object.keys(e).join(`, `)}`);return t}var j=class e{static instance=null;parser=null;languages=new Map;loadedGrammars=new Map;recoveryAttempts=0;static MAX_RECOVERIES=3;static MAX_PARSE_SIZE=1e6;static async initialize(){if(e.instance)return e.instance;let t=new e;return await t.init()?(e.instance=t,t):null}static get(){return e.instance}static async ensure(){let t=e.get();if(t)return t;let n=await e.initialize();if(!n)throw Error(`Failed to initialize WASM tree-sitter runtime`);return n}static dispose(){e.instance&&=(e.instance.parser?.delete(),e.instance.parser=null,e.instance.languages.clear(),e.instance.loadedGrammars.clear(),null)}async init(){try{let e;try{e=await A(),g.update({webTreeSitterImportable:!0})}catch(e){return g.update({webTreeSitterImportable:!1,mode:`regex`,reason:`web-tree-sitter import failed: ${String(e)}`,initError:String(e)}),k.warn(`web-tree-sitter module not importable`,{error:String(e)}),!1}let t=O();if(!t){k.info(`Parser WASM not found, attempting auto-heal...`);let e=v();e&&(E(e),t=O(),k.info(`Auto-heal succeeded`,{dir:e}))}if(!t)return g.update({mode:`regex`,reason:`Parser WASM file not found after heal attempt`}),k.warn(`Parser WASM file not found (auto-heal failed or skipped)`),!1;let n=t;return await e.init({locateFile:()=>n}),this.parser=new e,g.update({mode:`wasm`,reason:`WASM parser initialized successfully`,initError:null}),k.info(`WASM tree-sitter parser initialized`),!0}catch(e){return g.update({mode:`regex`,reason:`WASM initialization failed: ${String(e)}`,initError:String(e)}),k.warn(`Failed to initialize WASM tree-sitter`,{error:String(e)}),!1}}async loadLanguage(e){let t=this.languages.get(e);if(t)return t;let n=D(e);if(!n)return null;let r=this.loadedGrammars.get(n);if(r)return this.languages.set(e,r),r;try{let t=await(await A()).Language.load(n);return this.loadedGrammars.set(n,t),this.languages.set(e,t),k.debug(`Loaded grammar`,{ext:e}),t}catch(t){return k.warn(`Failed to load grammar`,{ext:e,error:String(t)}),null}}async parse(t,n){if(!this.parser)return null;if(t.length>e.MAX_PARSE_SIZE)return k.warn(`File too large for WASM parser, skipping`,{ext:n,size:t.length}),null;let r=await this.loadLanguage(n);if(!r)return null;try{return this.parser.setLanguage(r),this.parser.parse(t)}catch(r){if(k.warn(`WASM parser crashed, attempting recovery...`,{ext:n,error:String(r)}),this.recoveryAttempts>=e.MAX_RECOVERIES)return k.error(`WASM parser recovery limit reached, falling back to null`,{attempts:this.recoveryAttempts}),null;if(!await this.recoverParser(n))return k.error(`WASM parser recovery failed, falling back to null`),null;try{return this.parser?.parse(t)??null}catch(e){return k.error(`WASM parser crashed again after recovery, falling back to null`,{error:String(e)}),null}}}async recoverParser(e){this.recoveryAttempts++;try{this.parser?.delete(),this.parser=null,this.languages.clear(),this.loadedGrammars.clear();let t=await A(),n=O();if(!n)return k.error(`Cannot recover: parser WASM file not found`),!1;let r=n;await t.init({locateFile:()=>r}),this.parser=new t;let i=await this.loadLanguage(e);return i?(this.parser.setLanguage(i),k.info(`WASM parser recovered successfully`,{attempt:this.recoveryAttempts}),!0):(k.error(`Cannot recover: failed to reload language`,{ext:e}),!1)}catch(e){return k.error(`WASM parser recovery threw`,{error:String(e)}),!1}}hasLanguage(e){return x.has(e)}isLanguageLoaded(e){return this.languages.has(e)}getParser(){return this.parser}getLanguage(e){return this.languages.get(e)??null}};async function M(){return await j.initialize()!==null}const re=a(`call-graph`),ie=new Set([`function_declaration`,`method_definition`,`arrow_function`,`function_definition`,`function_declaration`,`method_declaration`,`function_item`,`method_declaration`,`constructor_declaration`]),ae=new Set([`call_expression`,`new_expression`,`call`]);function oe(e,t){let r=n(t).toLowerCase(),i=j.get();if(i?.isLanguageLoaded(r)){let n=i.getParser(),a=i.getLanguage(r);if(n&&a){n.setLanguage(a);let r;try{r=n.parse(e)}catch(e){return re.warn(`WASM parser.parse() crashed in call-graph extraction`,{file:t,error:String(e)}),null}if(r){let e=[];return N(r.rootNode,t,`<module>`,e),e}}}return null}function N(e,t,n,r){if(!e)return;let i=n;if(ie.has(e.type)&&(i=se(e)??n),ae.has(e.type)){let n=ce(e);n&&r.push({callerFile:t,callerName:i,calleeName:n,line:(e.startPosition?.row??0)+1})}for(let n=0;n<(e.childCount??0);n++){let a=e.child(n);a&&N(a,t,i,r)}}function se(e){for(let t=0;t<(e.childCount??0);t++){let n=e.child(t);if(n&&(n.type===`identifier`||n.type===`property_identifier`||n.type===`name`))return n.text??null}return null}function ce(e){let t=e.childForFieldName?.(`function`)??e.child(0);return t?t.type===`identifier`||t.type===`name`?t.text??null:t.type===`member_expression`||t.type===`attribute`?(t.childForFieldName?.(`property`)??t.childForFieldName?.(`attribute`))?.text??null:e.type===`new_expression`?e.child(1)?.text??null:null:null}var P=class{maxChunkSize;constructor(e){this.maxChunkSize=e?.maxChunkSize??i.code.max}chunk(e,t){let n=this.findDeclarationBoundaries(e);if(n.length===0)return this.fallbackChunk(e,t);let r=[];for(let i=0;i<n.length;i++){let a=n[i].offset,o=i+1<n.length?n[i+1].offset:e.length,s=e.slice(a,o).trim();if(s=`// File: ${t.sourcePath}\n`+s,s.length>this.maxChunkSize){let n=this.splitByLines(s,this.maxChunkSize),i=this.getLineNumber(e,a);for(let e of n){let n=e.split(`
2
2
  `).length;r.push({text:e,sourcePath:t.sourcePath,contentType:t.contentType,chunkIndex:r.length,totalChunks:0,startLine:i,endLine:i+n-1}),i+=n}}else{let n=this.getLineNumber(e,a);r.push({text:s,sourcePath:t.sourcePath,contentType:t.contentType,chunkIndex:r.length,totalChunks:0,startLine:n,endLine:n+s.split(`
3
3
  `).length-1})}}if(n[0].offset>0){let i=e.slice(0,n[0].offset).trim();i.length>0&&r.unshift({text:`// File: ${t.sourcePath}\n${i}`,sourcePath:t.sourcePath,contentType:t.contentType,chunkIndex:0,totalChunks:0,startLine:1,endLine:this.getLineNumber(e,n[0].offset)-1})}return r.map((e,t)=>({...e,chunkIndex:t,totalChunks:r.length}))}findDeclarationBoundaries(e){let t=/^(?:export\s+)?(?:default\s+)?(?:async\s+)?(?:function|class|interface|type|const|enum|abstract\s+class)\s+(\w+)/gm,n=[],r;for(;(r=t.exec(e))!==null;){let t=e.lastIndexOf(`
4
4
  `,r.index-1)+1,i=t,a=e.slice(0,t).split(`
@@ -1,4 +1,4 @@
1
- import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-DwQDdiCJ.js";import{a as o,i as s,n as c,o as l,r as u,s as d,t as f}from"./templates-VOIHbNnT.js";import{copyFileSync as p,existsSync as m,mkdirSync as h,readFileSync as g,readdirSync as _,rmSync as ee,unlinkSync as v,writeFileSync as te}from"node:fs";import{basename as y,dirname as b,join as x,posix as S,relative as C,resolve as w,win32 as T}from"node:path";import{fileURLToPath as E}from"node:url";import{addToWorkset as ne,audit as D,check as O,checkpointLatest as re,checkpointList as ie,checkpointLoad as ae,checkpointSave as oe,codemod as se,compact as ce,dataTransform as le,delegate as ue,delegateListModels as de,deleteWorkset as fe,diffParse as pe,evaluate as me,fileSummary as he,find as ge,findDeadSymbols as _e,findExamples as ve,getWorkset as ye,gitContext as be,graphQuery as xe,guide as Se,health as Ce,laneCreate as we,laneDiff as Te,laneDiscard as Ee,laneList as De,laneMerge as Oe,laneStatus as ke,listWorksets as Ae,parseOutput as je,processList as Me,processLogs as Ne,processStart as Pe,processStatus as Fe,processStop as Ie,queueClear as Le,queueCreate as Re,queueDelete as ze,queueDone as Be,queueFail as Ve,queueGet as He,queueList as Ue,queueNext as We,queuePush as Ge,removeFromWorkset as Ke,rename as qe,replayClear as Je,replayList as Ye,replayTrim as Xe,saveWorkset as Ze,scopeMap as Qe,stashClear as $e,stashDelete as et,stashGet as tt,stashList as nt,stashSet as rt,symbol as it,testRun as at,trace as ot,watchList as st,watchStart as ct,watchStop as lt}from"../../tools/dist/index.js";import{mkdir as ut,readFile as k,rename as dt,unlink as ft,writeFile as pt}from"node:fs/promises";import{randomUUID as mt}from"node:crypto";import{homedir as A}from"node:os";import{execFileSync as ht,fork as gt}from"node:child_process";import{AIKIT_PATHS as j,EMBEDDING_DEFAULTS as _t,getGlobalDataDir as vt,getPartitionDir as yt,isUserInstalled as bt,registerWorkspace as xt,saveRegistry as St}from"../../core/dist/index.js";import{initializeWasm as Ct}from"../../chunker/dist/index.js";import{OnnxEmbedder as wt}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Tt}from"../../indexer/dist/index.js";import{SqliteGraphStore as Et,createSqliteAdapter as Dt,createStore as Ot}from"../../store/dist/index.js";const kt=[{name:`analyze`,description:`Run analyzer output for a path`,usage:`aikit analyze <type> <path>`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``;(!t||!n)&&(console.error(`Usage: aikit analyze <type> <path>`),console.error(`Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`),process.exit(1));let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:l}=await import(`../../analyzers/dist/index.js`),u=w(n),d;switch(t){case`structure`:d=await new c().analyze(u,{format:`markdown`});break;case`deps`:case`dependencies`:d=await new i().analyze(u,{format:`markdown`});break;case`symbols`:d=await new l().analyze(u,{format:`markdown`});break;case`patterns`:d=await new s().analyze(u,{format:`markdown`});break;case`entry-points`:d=await new o().analyze(u,{format:`markdown`});break;case`blast-radius`:d=await new r().analyze(process.cwd(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:console.error(`Unknown analyze type: ${t}`),console.error(`Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`),process.exit(1)}console.log(d.output)}},{name:`onboard`,description:`Run all analyses for first-time codebase onboarding`,usage:`aikit onboard <path> [--generate] [--out-dir <dir>]`,run:async e=>{let{onboard:t}=await import(`../../tools/dist/index.js`),n=``,r=`memory`,i;for(let t=0;t<e.length;t++){let a=e[t].trim();a===`--generate`?r=`generate`:a===`--out-dir`&&t+1<e.length?i=e[++t].trim():a.startsWith(`--`)||(n=a)}n||=process.cwd();let a=w(n);console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
1
+ import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-DwQDdiCJ.js";import{a as o,i as s,n as c,o as l,r as u,s as d,t as f}from"./templates-D-eA4QVK.js";import{copyFileSync as p,existsSync as m,mkdirSync as h,readFileSync as g,readdirSync as _,rmSync as ee,unlinkSync as v,writeFileSync as te}from"node:fs";import{basename as y,dirname as b,join as x,posix as S,relative as C,resolve as w,win32 as T}from"node:path";import{fileURLToPath as E}from"node:url";import{addToWorkset as ne,audit as D,check as O,checkpointLatest as re,checkpointList as ie,checkpointLoad as ae,checkpointSave as oe,codemod as se,compact as ce,dataTransform as le,delegate as ue,delegateListModels as de,deleteWorkset as fe,diffParse as pe,evaluate as me,fileSummary as he,find as ge,findDeadSymbols as _e,findExamples as ve,getWorkset as ye,gitContext as be,graphQuery as xe,guide as Se,health as Ce,laneCreate as we,laneDiff as Te,laneDiscard as Ee,laneList as De,laneMerge as Oe,laneStatus as ke,listWorksets as Ae,parseOutput as je,processList as Me,processLogs as Ne,processStart as Pe,processStatus as Fe,processStop as Ie,queueClear as Le,queueCreate as Re,queueDelete as ze,queueDone as Be,queueFail as Ve,queueGet as He,queueList as Ue,queueNext as We,queuePush as Ge,removeFromWorkset as Ke,rename as qe,replayClear as Je,replayList as Ye,replayTrim as Xe,saveWorkset as Ze,scopeMap as Qe,stashClear as $e,stashDelete as et,stashGet as tt,stashList as nt,stashSet as rt,symbol as it,testRun as at,trace as ot,watchList as st,watchStart as ct,watchStop as lt}from"../../tools/dist/index.js";import{mkdir as ut,readFile as k,rename as dt,unlink as ft,writeFile as pt}from"node:fs/promises";import{randomUUID as mt}from"node:crypto";import{homedir as A}from"node:os";import{execFileSync as ht,fork as gt}from"node:child_process";import{AIKIT_PATHS as j,EMBEDDING_DEFAULTS as _t,getGlobalDataDir as vt,getPartitionDir as yt,isUserInstalled as bt,registerWorkspace as xt,saveRegistry as St}from"../../core/dist/index.js";import{initializeWasm as Ct}from"../../chunker/dist/index.js";import{OnnxEmbedder as wt}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Tt}from"../../indexer/dist/index.js";import{SqliteGraphStore as Et,createSqliteAdapter as Dt,createStore as Ot}from"../../store/dist/index.js";const kt=[{name:`analyze`,description:`Run analyzer output for a path`,usage:`aikit analyze <type> <path>`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``;(!t||!n)&&(console.error(`Usage: aikit analyze <type> <path>`),console.error(`Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`),process.exit(1));let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:l}=await import(`../../analyzers/dist/index.js`),u=w(n),d;switch(t){case`structure`:d=await new c().analyze(u,{format:`markdown`});break;case`deps`:case`dependencies`:d=await new i().analyze(u,{format:`markdown`});break;case`symbols`:d=await new l().analyze(u,{format:`markdown`});break;case`patterns`:d=await new s().analyze(u,{format:`markdown`});break;case`entry-points`:d=await new o().analyze(u,{format:`markdown`});break;case`blast-radius`:d=await new r().analyze(process.cwd(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:console.error(`Unknown analyze type: ${t}`),console.error(`Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`),process.exit(1)}console.log(d.output)}},{name:`onboard`,description:`Run all analyses for first-time codebase onboarding`,usage:`aikit onboard <path> [--generate] [--out-dir <dir>]`,run:async e=>{let{onboard:t}=await import(`../../tools/dist/index.js`),n=``,r=`memory`,i;for(let t=0;t<e.length;t++){let a=e[t].trim();a===`--generate`?r=`generate`:a===`--out-dir`&&t+1<e.length?i=e[++t].trim():a.startsWith(`--`)||(n=a)}n||=process.cwd();let a=w(n);console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
2
2
  `);let o=await t({path:a,mode:r,outDir:i});for(let e of o.steps){let t=e.status===`success`?`✓`:`✗`,n=e.status===`success`?`${e.durationMs}ms, ${e.output.length} chars`:e.error;console.log(` ${t} ${e.name} — ${n}`)}console.log(`\nTotal: ${o.totalDurationMs}ms`),o.outDir&&console.log(`Output written to: ${o.outDir}`)}}];function M(e,t,n){let r=e.indexOf(t);if(r===-1||r+1>=e.length)return n;let i=Number.parseInt(e.splice(r,2)[1],10);return Number.isNaN(i)?n:i}function N(e,t,n){let r=e.indexOf(t);return r===-1||r+1>=e.length?n:e.splice(r,2)[1]}function P(e,t){let n=e.indexOf(t);return n===-1?!1:(e.splice(n,1),!0)}async function F(){if(process.stdin.isTTY)return``;let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf-8`)}function I(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function At(e){return e.map(e=>{let t=e.heading?` ${e.heading}`:``;return`${e.start}-${e.end}${t}`}).join(`, `)}function jt(e){switch(e.tool){case`tsc`:case`biome`:console.log(`${e.tool} errors: ${e.errors.length}`);for(let t of e.errors){let e=[t.line,t.column].filter(e=>e!==void 0).join(`:`),n=e?`${t.file}:${e}`:t.file,r=t.code?` ${t.code}`:``;console.log(`- ${n} [${t.severity}${r}] ${t.message}`)}return;case`vitest`:console.log(`Vitest summary`),console.log(` Passed: ${e.summary.passed}`),console.log(` Failed: ${e.summary.failed}`),console.log(` Skipped: ${e.summary.skipped}`),e.summary.duration!==void 0&&console.log(` Duration: ${e.summary.duration}ms`);for(let t of e.summary.tests)t.status===`fail`&&(console.log(`- ${t.name}${t.file?` (${t.file})`:``}`),t.error&&console.log(` ${t.error}`));return;case`git-status`:console.log(`Branch: ${e.status.branch??`unknown`}`),console.log(`Staged: ${e.status.staged.length}`);for(let t of e.status.staged)console.log(` ${t.status} ${t.file}`);console.log(`Unstaged: ${e.status.unstaged.length}`);for(let t of e.status.unstaged)console.log(` ${t.status} ${t.file}`);console.log(`Untracked: ${e.status.untracked.length}`);for(let t of e.status.untracked)console.log(` ?? ${t}`);return}}function Mt(e){console.log(`Overall: ${e.passed?`passed`:`failed`}`),Nt(`tsc`,e.tsc.passed,e.tsc.errors),Nt(`biome`,e.biome.passed,e.biome.errors)}function Nt(e,t,n){console.log(`${e}: ${t?`passed`:`${n.length} issue(s)`}`);for(let e of n){let t=[e.line,e.column].filter(e=>e!==void 0).join(`:`),n=t?`${e.file}:${t}`:e.file,r=e.code?` ${e.code}`:``;console.log(` - ${n} [${e.severity}${r}] ${e.message}`)}}function Pt(e){console.log(`Vitest: ${e.passed?`passed`:`failed`}`),console.log(` Duration: ${e.durationMs}ms`),console.log(` Passed: ${e.summary.passed}`),console.log(` Failed: ${e.summary.failed}`),console.log(` Skipped: ${e.summary.skipped}`),e.summary.suites!==void 0&&console.log(` Suites: ${e.summary.suites}`);let t=e.summary.tests.filter(e=>e.status===`fail`);if(t.length!==0){console.log(`Failed tests:`);for(let e of t)console.log(` - ${e.name}${e.file?` (${e.file})`:``}`),e.error&&console.log(` ${e.error}`)}}function Ft(e){console.log(`Branch: ${e.branch}`),console.log(`Staged: ${e.status.staged.length}`);for(let t of e.status.staged)console.log(` - ${t}`);console.log(`Modified: ${e.status.modified.length}`);for(let t of e.status.modified)console.log(` - ${t}`);console.log(`Untracked: ${e.status.untracked.length}`);for(let t of e.status.untracked)console.log(` - ${t}`);if(console.log(``),console.log(`Recent commits:`),e.recentCommits.length===0)console.log(` none`);else for(let t of e.recentCommits)console.log(` - ${t.hash} ${t.message}`),console.log(` ${t.author} @ ${t.date}`);e.diff&&(console.log(``),console.log(`Diff stat:`),console.log(e.diff))}function It(e){if(e.length===0){console.log(`No diff files found.`);return}for(let t of e){let e=t.oldPath?` (from ${t.oldPath})`:``;console.log(`${t.path}${e}`),console.log(` Status: ${t.status}`),console.log(` Changes: +${t.additions} -${t.deletions}`),console.log(` Hunks: ${t.hunks.length}`);for(let e of t.hunks){let t=e.header?` ${e.header}`:``;console.log(` @@ -${e.oldStart},${e.oldLines} +${e.newStart},${e.newLines} @@${t}`)}}}function Lt(e){if(console.log(`Start: ${e.start}`),console.log(`Direction: ${e.direction}`),console.log(`Depth reached: ${e.depth}`),console.log(`Nodes: ${e.nodes.length}`),e.nodes.length===0){console.log(`No trace nodes found.`);return}for(let t of e.nodes)console.log(` - [${t.relationship}] ${t.path}:${t.line} ${t.symbol}`)}function Rt(e){if(console.log(`Query: ${e.query}`),console.log(`Examples: ${e.examples.length} shown (${e.totalFound} total)`),e.examples.length===0){console.log(`No matching examples found.`);return}for(let t of e.examples){console.log(``),console.log(`${t.path}:${t.startLine}-${t.endLine}`),console.log(` Context: ${t.context}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}%`);for(let e of t.content.split(`
3
3
  `))console.log(` ${e}`)}}function L(e){console.log(e.id),console.log(` Command: ${e.command}${e.args.length>0?` ${e.args.join(` `)}`:``}`),console.log(` PID: ${e.pid??`unknown`}`),console.log(` Status: ${e.status}`),console.log(` Started: ${e.startedAt}`),e.exitCode!==void 0&&console.log(` Exit code: ${e.exitCode}`),console.log(` Logs: ${e.logs.length}`)}function zt(e){if(console.log(`Exports scanned: ${e.totalExports}`),console.log(`Dead in source: ${e.totalDeadSource} (actionable)`),console.log(`Dead in docs: ${e.totalDeadDocs} (informational)`),e.totalDeadSource===0&&e.totalDeadDocs===0){console.log(`No dead symbols found.`);return}if(e.deadInSource.length>0){console.log(`
4
4
  Dead in source (actionable):`);for(let t of e.deadInSource)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}if(e.deadInDocs.length>0){console.log(`
@@ -17,7 +17,7 @@ Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],In=[{name:`pro
17
17
  Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`),process.exit(1));let{graphStore:n}=await X(),r=N(e,`--type`,``),i=N(e,`--name`,``),a=N(e,`--node-id`,``),o=N(e,`--edge-type`,``),s=N(e,`--direction`,`both`),c=M(e,`--depth`,2),l=M(e,`--limit`,50),u=N(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];d||(console.error(`Unknown graph action: ${t}`),console.error(`Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`),process.exit(1));let f=await xe(n,{action:d,nodeType:r||void 0,namePattern:i||void 0,sourcePath:u||void 0,nodeId:a||void 0,edgeType:o||void 0,direction:s,maxDepth:c,limit:l});if(console.log(f.summary),f.nodes&&f.nodes.length>0){console.log(`
18
18
  Nodes:`);for(let e of f.nodes){let t=Object.keys(e.properties).length>0?` ${JSON.stringify(e.properties)}`:``;console.log(` ${e.name} (${e.type}, id: ${e.id})${t}`)}}if(f.edges&&f.edges.length>0){console.log(`
19
19
  Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],Jn=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=N(e,`--category`,``).trim(),n=I(N(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await F(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await X(),s=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${s.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=N(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await X(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await X(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=N(e,`--category`,``).trim()||void 0,n=N(e,`--tag`,``).trim()||void 0,{curated:r}=await X(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=N(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await F();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await X(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=M(e,`--max-chars`,3e3),n=N(e,`--path`,``).trim()||void 0,r=N(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await F();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await X(),s=await ce(o,{text:a,path:n,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}],Yn=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=M(e,`--limit`,5),n=N(e,`--mode`,`hybrid`),r=M(e,`--graph-hops`,0),i=e.join(` `).trim();i||(console.error(`Usage: aikit search <query>`),process.exit(1));let{embedder:a,store:o,graphStore:s}=await X(),c=await a.embedQuery(i),l;if(n===`keyword`)l=await o.ftsSearch(i,{limit:t});else if(n===`semantic`)l=await o.search(c,{limit:t});else{let[e,n]=await Promise.all([o.search(c,{limit:t*2}),o.ftsSearch(i,{limit:t*2}).catch(()=>[])]);l=Wt(e,n).slice(0,t)}if(l.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of l){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${l.length} result(s) found.`),r>0&&l.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(s,l.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:r,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${r} hop${r>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=M(e,`--limit`,10),n=N(e,`--glob`,``).trim()||void 0,r=N(e,`--pattern`,``).trim()||void 0,i=e.join(` `).trim()||void 0;!i&&!n&&!r&&(console.error(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`),process.exit(1));let{embedder:a,store:o}=await X(),s=await ge(a,o,{query:i,glob:n,pattern:r,limit:t});if(s.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${s.strategies.join(`, `)}`),console.log(`Results: ${s.results.length} shown (${s.totalFound} total)`);for(let e of s.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=M(e,`--max-files`,15),n=e.join(` `).trim();n||(console.error(`Usage: aikit scope-map <task> [--max-files N]`),process.exit(1));let{embedder:r,store:i}=await X(),a=await Qe(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${At(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=M(e,`--limit`,20),n=e.join(` `).trim();n||(console.error(`Usage: aikit symbol <name> [--limit N]`),process.exit(1));let{embedder:r,store:i}=await X();Vt(await it(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=N(e,`--direction`,`both`).trim()||`both`,n=M(e,`--max-depth`,3),r=e.join(` `).trim();(!r||![`forward`,`backward`,`both`].includes(t))&&(console.error(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`),process.exit(1));let{embedder:i,store:a}=await X();Lt(await ot(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=M(e,`--limit`,5),n=N(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();r||(console.error(`Usage: aikit examples <query> [--limit N] [--content-type type]`),process.exit(1));let{embedder:i,store:a}=await X();Rt(await ve(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=M(e,`--limit`,100),{embedder:n,store:r}=await X();zt(await _e(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();t||(console.error(`Usage: aikit lookup <id>`),process.exit(1));let{store:n}=await X(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}],Z=b(E(import.meta.url));function Q(e){let t=e;for(let e=0;e<10;e++){try{let e=x(t,`package.json`);if(m(e)&&JSON.parse(g(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=b(t);if(e===t)break;t=e}return w(e,`..`,`..`,`..`)}const Xn=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async()=>{let{isUserInstalled:e,getGlobalDataDir:t,computePartitionKey:n,listWorkspaces:r}=await import(`../../core/dist/index.js`),{existsSync:i}=await import(`node:fs`),a=process.cwd(),o=e(),s=i(w(a,`.vscode`,`mcp.json`)),c,l;if(o&&s)c=`workspace (overrides user-level for this workspace)`,l=w(a,`.aikit-data`);else if(o){let e=n(a);c=i(w(a,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,l=w(t(),e)}else c=`workspace`,l=w(a,`.aikit-data`);if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${c}`),console.log(` Data: ${l}`),o&&!s){let e=r();console.log(` Registry: ${e.length} workspace(s) enrolled`)}try{let{store:e}=await X(),t=await e.getStats(),n=await e.listSourcePaths();console.log(` Records: ${t.totalRecords}`),console.log(` Files: ${t.totalFiles}`),console.log(` Indexed: ${t.lastIndexedAt??`Never`}`),console.log(` Backend: ${t.storeBackend}`),console.log(` Model: ${t.embeddingModel}`),console.log(``),console.log(`Content Types:`);for(let[e,n]of Object.entries(t.contentTypeBreakdown))console.log(` ${e}: ${n}`);if(n.length>0){console.log(``),console.log(`Files (${n.length} total):`);for(let e of n.slice(0,20))console.log(` ${e}`);n.length>20&&console.log(` ... and ${n.length-20} more`)}}catch{console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.")}o&&!s&&!i(w(a,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await X();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
20
- `)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server (stdio or HTTP)`,usage:`aikit serve [--transport stdio|http] [--port N]`,run:async e=>{let t=w(Q(Z),`packages`,`server`,`dist`,`index.js`),n=N(e,`--transport`,`stdio`),r=N(e,`--port`,`3210`);try{await Pn({silent:!0})}catch{}let i=gt(t,[],{stdio:n===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,AIKIT_TRANSPORT:n,AIKIT_PORT:r}});n===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n&&(console.error(`Cannot use --user and --workspace together.`),process.exit(1)),i){let{guideProject:e}=await import(`./init-O57V8aOH.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-O57V8aOH.js`);await e({force:a})}else if(t)await G({force:a});else if(n){let{initProject:e}=await import(`./init-O57V8aOH.js`);await e({force:a})}else await G({force:a})}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=N(e,`--cwd`,``).trim()||void 0,n=N(e,`--files`,``),r=N(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await O({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});Mt(s),s.passed||(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=Ce(e.shift());console.log(`Project Health: ${t.path}`),console.log(`─`.repeat(50));for(let e of t.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${t.score}% — ${t.summary}`)}},{name:`audit`,description:`Run a unified project audit (structure, deps, patterns, health, dead symbols, check)`,usage:`aikit audit [path] [--checks structure,dependencies,patterns,health,dead_symbols,check,entry_points] [--detail efficient|normal|full]`,run:async e=>{let{store:t,embedder:n}=await X(),r=N(e,`--detail`,`efficient`)||`efficient`,i=N(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await D(t,n,{path:e.shift()||`.`,checks:a,detail:r});if(o.ok){if(console.log(o.summary),o.next&&o.next.length>0){console.log(`
21
- Suggested next steps:`);for(let e of o.next)console.log(` → ${e.tool}: ${e.reason}`)}}else console.error(o.error?.message??`Audit failed`),process.exitCode=1}},{name:`guide`,description:`Tool discovery — recommend AI Kit tools for a given goal`,usage:`aikit guide <goal> [--max N]`,run:async e=>{let t=e.indexOf(`--max`),n=5;t!==-1&&t+1<e.length&&(n=Number.parseInt(e.splice(t,2)[1],10)||5);let r=e.join(` `).trim();r||(console.error(`Usage: aikit guide <goal> [--max N]`),console.error(`Example: aikit guide "audit this project"`),process.exit(1));let i=Se(r,n);console.log(`Workflow: ${i.workflow}`),console.log(` ${i.description}\n`),console.log(`Recommended tools:`);for(let e of i.tools){let t=e.suggestedArgs?` ${JSON.stringify(e.suggestedArgs)}`:``;console.log(` ${e.order}. ${e.tool} — ${e.reason}${t}`)}i.alternativeWorkflows.length>0&&console.log(`\nAlternatives: ${i.alternativeWorkflows.join(`, `)}`)}},{name:`replay`,description:`Show recent tool invocation audit trail`,usage:`aikit replay [--last N] [--tool <name>] [--source mcp|cli]`,run:async e=>{let t=Ye({last:Number.parseInt(e[e.indexOf(`--last`)+1],10)||20,tool:e.includes(`--tool`)?e[e.indexOf(`--tool`)+1]:void 0,source:e.includes(`--source`)?e[e.indexOf(`--source`)+1]:void 0});if(t.length===0){console.log(`No replay entries. Activity is logged when tools are invoked.`);return}console.log(`Replay Log (${t.length} entries)\n`);for(let e of t){let t=e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts,n=e.status===`ok`?`✓`:`✗`;console.log(`${t} ${n} ${e.tool} (${e.durationMs}ms) [${e.source}]`),console.log(` in: ${e.input}`),console.log(` out: ${e.output}`)}Xe().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Je(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=w(Q(Z),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),l=`http://localhost:${r}/_dashboard/`,u=`http://localhost:${r}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(d||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Dashboard: ${l}`),console.log(`Press Ctrl+C to stop.`),!i){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let f=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,f),process.on(`SIGTERM`,f),await new Promise(e=>{c.on(`exit`,()=>e())})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=w(Q(Z),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),l=`http://localhost:${r}/settings/`,u=`http://localhost:${r}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(d||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Settings: ${l}`),console.log(`Press Ctrl+C to stop.`),!i){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let f=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,f),process.on(`SIGTERM`,f),await new Promise(e=>{c.on(`exit`,()=>e())})}}];function Zn(e){let t=e;for(let e=0;e<10;e++){try{let e=x(t,`package.json`);if(m(e)&&JSON.parse(g(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=b(t);if(e===t)break;t=e}return w(e,`..`,`..`,`..`)}const Qn=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{await G({force:!0});let e=process.cwd(),t=m(w(e,`.github`,`.aikit-scaffold.json`)),n=m(w(e,`.github`,`agents`)),r=m(w(e,`.github`,`prompts`)),i=m(w(e,`.claude`,`commands`));if(t||n||r||i){let{initScaffoldOnly:e}=await import(`./init-O57V8aOH.js`);await e({force:!0})}if(m(w(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-DwQDdiCJ.js`).then(e=>e.a),n=Zn(b(E(import.meta.url))),r=JSON.parse(g(w(n,`package.json`),`utf-8`)).version;await t(e,n,[...l],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-DwQDdiCJ.js`).then(e=>e.a);await i(e,n,[...u],r,!0)}let{homedir:a}=await import(`node:os`),{rmSync:o}=await import(`node:fs`),s=x(a(),`.aikit`,`cache`,`wasm`);if(m(s))try{o(s,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,s)}}}],$n=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=I(N(e,`--files`,``)),r=N(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=Ze(i,n,{description:r});console.log(`Saved workset: ${e.name}`),R(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=ye(i);if(!e){console.log(`No workset found: ${i}`);return}R(e);return}case`list`:{let e=Ae();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)R(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=fe(i);console.log(e?`Deleted workset: ${i}`:`No workset found: ${i}`);return}case`add`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset add <name> --files f1,f2`),process.exit(1));let e=ne(i,n);console.log(`Updated workset: ${e.name}`),R(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Ke(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),R(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();switch(t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1)),t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),r=t.trim()?``:await F(),i=rt(n,Ht(t||r));console.log(`Stored stash entry: ${i.key}`),console.log(` Type: ${i.type}`),console.log(` Stored: ${i.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=tt(n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=nt();if(e.length===0){console.log(`No stash entries saved.`);return}console.log(`Stash entries (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.key} (${t.type})`),console.log(` Stored: ${t.storedAt}`);return}case`delete`:{n||(console.error(`Usage: aikit stash delete <key>`),process.exit(1));let e=et(n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=$e();console.log(`Cleared ${e} stash entr${e===1?`y`:`ies`}.`);return}default:console.error(`Unknown stash action: ${t}`),console.error(`Actions: set, get, list, delete, clear`),process.exit(1)}}},{name:`lane`,description:`Manage verified lanes — isolated file copies for parallel exploration`,usage:`aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`,run:async e=>{let t=e.shift();if((!t||![`create`,`list`,`status`,`diff`,`merge`,`discard`].includes(t))&&(console.error(`Usage: aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`),process.exit(1)),t===`list`){let e=De();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=N(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=we(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=ke(n);console.log(`Lane: ${e.name}`),console.log(`Modified: ${e.modified} | Added: ${e.added} | Deleted: ${e.deleted}`);for(let t of e.entries)console.log(` ${t.status.padEnd(10)} ${t.file}`);break}case`diff`:{let e=Te(n);console.log(`Lane: ${e.name} — ${e.modified} modified, ${e.added} added, ${e.deleted} deleted`);for(let t of e.entries)t.diff&&(console.log(`\n--- ${t.file} (${t.status})`),console.log(t.diff));break}case`merge`:{let e=Oe(n);console.log(`Merged ${e.filesMerged} files from lane "${e.name}".`);for(let t of e.files)console.log(` ${t}`);break}case`discard`:{let e=Ee(n);console.log(e?`Lane "${n}" discarded.`:`Lane "${n}" not found.`);break}}}},{name:`queue`,description:`Manage task queues for sequential agent operations`,usage:`aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`,run:async e=>{let t=e.shift();if((!t||![`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`].includes(t))&&(console.error(`Usage: aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`),process.exit(1)),t===`list`){let e=Ue();if(e.length===0){console.log(`No queues.`);return}for(let t of e)console.log(`${t.name} pending:${t.pending} done:${t.done} failed:${t.failed} total:${t.total}`);return}let n=e.shift();switch(n||(console.error(`Queue name is required for "${t}".`),process.exit(1)),t){case`create`:{let e=Re(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Ge(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=We(n);console.log(e?`Next: ${e.title} (${e.id})`:`No pending items in queue "${n}".`);break}case`done`:{let t=e.shift();t||(console.error(`Usage: aikit queue done <name> <id>`),process.exit(1));let r=Be(n,t);console.log(`Marked "${r.item.title}" as done.`);break}case`fail`:{let t=e.shift(),r=e.join(` `)||`Unknown error`;t||(console.error(`Usage: aikit queue fail <name> <id> [error message]`),process.exit(1));let i=Ve(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=He(n);if(!e){console.log(`Queue "${n}" not found.`);return}console.log(`Queue: ${e.name} (${e.items.length} items)`);for(let t of e.items){let e=t.error?` — ${t.error}`:``;console.log(` ${t.status.padEnd(12)} ${t.id} ${t.title}${e}`)}break}case`clear`:{let e=Le(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=ze(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],$=[...Yn,...Jn,...kt,...qn,...Xn,...Ln,...Gt,...$n,...In,...Qn,...Gn,...Fn];$.push({name:`help`,description:`Show available commands`,run:async()=>{tr()}});async function er(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){tr();return}if(n===`--version`||n===`-v`){let e=w(b(E(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(g(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=$.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=$.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),tr(),process.exit(1));try{await r.run(t)}finally{let e=Kn();e&&await e.store.close()}}function tr(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
20
+ `)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server (stdio or HTTP)`,usage:`aikit serve [--transport stdio|http] [--port N]`,run:async e=>{let t=w(Q(Z),`packages`,`server`,`dist`,`index.js`),n=N(e,`--transport`,`stdio`),r=N(e,`--port`,`3210`);try{await Pn({silent:!0})}catch{}let i=gt(t,[],{stdio:n===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,AIKIT_TRANSPORT:n,AIKIT_PORT:r}});n===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n&&(console.error(`Cannot use --user and --workspace together.`),process.exit(1)),i){let{guideProject:e}=await import(`./init-BWhqiOl_.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-BWhqiOl_.js`);await e({force:a})}else if(t)await G({force:a});else if(n){let{initProject:e}=await import(`./init-BWhqiOl_.js`);await e({force:a})}else await G({force:a})}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=N(e,`--cwd`,``).trim()||void 0,n=N(e,`--files`,``),r=N(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await O({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});Mt(s),s.passed||(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=Ce(e.shift());console.log(`Project Health: ${t.path}`),console.log(`─`.repeat(50));for(let e of t.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${t.score}% — ${t.summary}`)}},{name:`audit`,description:`Run a unified project audit (structure, deps, patterns, health, dead symbols, check)`,usage:`aikit audit [path] [--checks structure,dependencies,patterns,health,dead_symbols,check,entry_points] [--detail efficient|normal|full]`,run:async e=>{let{store:t,embedder:n}=await X(),r=N(e,`--detail`,`efficient`)||`efficient`,i=N(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await D(t,n,{path:e.shift()||`.`,checks:a,detail:r});if(o.ok){if(console.log(o.summary),o.next&&o.next.length>0){console.log(`
21
+ Suggested next steps:`);for(let e of o.next)console.log(` → ${e.tool}: ${e.reason}`)}}else console.error(o.error?.message??`Audit failed`),process.exitCode=1}},{name:`guide`,description:`Tool discovery — recommend AI Kit tools for a given goal`,usage:`aikit guide <goal> [--max N]`,run:async e=>{let t=e.indexOf(`--max`),n=5;t!==-1&&t+1<e.length&&(n=Number.parseInt(e.splice(t,2)[1],10)||5);let r=e.join(` `).trim();r||(console.error(`Usage: aikit guide <goal> [--max N]`),console.error(`Example: aikit guide "audit this project"`),process.exit(1));let i=Se(r,n);console.log(`Workflow: ${i.workflow}`),console.log(` ${i.description}\n`),console.log(`Recommended tools:`);for(let e of i.tools){let t=e.suggestedArgs?` ${JSON.stringify(e.suggestedArgs)}`:``;console.log(` ${e.order}. ${e.tool} — ${e.reason}${t}`)}i.alternativeWorkflows.length>0&&console.log(`\nAlternatives: ${i.alternativeWorkflows.join(`, `)}`)}},{name:`replay`,description:`Show recent tool invocation audit trail`,usage:`aikit replay [--last N] [--tool <name>] [--source mcp|cli]`,run:async e=>{let t=Ye({last:Number.parseInt(e[e.indexOf(`--last`)+1],10)||20,tool:e.includes(`--tool`)?e[e.indexOf(`--tool`)+1]:void 0,source:e.includes(`--source`)?e[e.indexOf(`--source`)+1]:void 0});if(t.length===0){console.log(`No replay entries. Activity is logged when tools are invoked.`);return}console.log(`Replay Log (${t.length} entries)\n`);for(let e of t){let t=e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts,n=e.status===`ok`?`✓`:`✗`;console.log(`${t} ${n} ${e.tool} (${e.durationMs}ms) [${e.source}]`),console.log(` in: ${e.input}`),console.log(` out: ${e.output}`)}Xe().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Je(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=w(Q(Z),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),l=`http://localhost:${r}/_dashboard/`,u=`http://localhost:${r}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(d||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Dashboard: ${l}`),console.log(`Press Ctrl+C to stop.`),!i){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let f=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,f),process.on(`SIGTERM`,f),await new Promise(e=>{c.on(`exit`,()=>e())})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=w(Q(Z),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),l=`http://localhost:${r}/settings/`,u=`http://localhost:${r}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(d||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Settings: ${l}`),console.log(`Press Ctrl+C to stop.`),!i){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let f=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,f),process.on(`SIGTERM`,f),await new Promise(e=>{c.on(`exit`,()=>e())})}}];function Zn(e){let t=e;for(let e=0;e<10;e++){try{let e=x(t,`package.json`);if(m(e)&&JSON.parse(g(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=b(t);if(e===t)break;t=e}return w(e,`..`,`..`,`..`)}const Qn=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{await G({force:!0});let e=process.cwd(),t=m(w(e,`.github`,`.aikit-scaffold.json`)),n=m(w(e,`.github`,`agents`)),r=m(w(e,`.github`,`prompts`)),i=m(w(e,`.claude`,`commands`));if(t||n||r||i){let{initScaffoldOnly:e}=await import(`./init-BWhqiOl_.js`);await e({force:!0})}if(m(w(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-DwQDdiCJ.js`).then(e=>e.a),n=Zn(b(E(import.meta.url))),r=JSON.parse(g(w(n,`package.json`),`utf-8`)).version;await t(e,n,[...l],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-DwQDdiCJ.js`).then(e=>e.a);await i(e,n,[...u],r,!0)}let{homedir:a}=await import(`node:os`),{rmSync:o}=await import(`node:fs`),s=x(a(),`.aikit`,`cache`,`wasm`);if(m(s))try{o(s,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,s)}}}],$n=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=I(N(e,`--files`,``)),r=N(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=Ze(i,n,{description:r});console.log(`Saved workset: ${e.name}`),R(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=ye(i);if(!e){console.log(`No workset found: ${i}`);return}R(e);return}case`list`:{let e=Ae();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)R(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=fe(i);console.log(e?`Deleted workset: ${i}`:`No workset found: ${i}`);return}case`add`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset add <name> --files f1,f2`),process.exit(1));let e=ne(i,n);console.log(`Updated workset: ${e.name}`),R(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Ke(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),R(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();switch(t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1)),t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),r=t.trim()?``:await F(),i=rt(n,Ht(t||r));console.log(`Stored stash entry: ${i.key}`),console.log(` Type: ${i.type}`),console.log(` Stored: ${i.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=tt(n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=nt();if(e.length===0){console.log(`No stash entries saved.`);return}console.log(`Stash entries (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.key} (${t.type})`),console.log(` Stored: ${t.storedAt}`);return}case`delete`:{n||(console.error(`Usage: aikit stash delete <key>`),process.exit(1));let e=et(n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=$e();console.log(`Cleared ${e} stash entr${e===1?`y`:`ies`}.`);return}default:console.error(`Unknown stash action: ${t}`),console.error(`Actions: set, get, list, delete, clear`),process.exit(1)}}},{name:`lane`,description:`Manage verified lanes — isolated file copies for parallel exploration`,usage:`aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`,run:async e=>{let t=e.shift();if((!t||![`create`,`list`,`status`,`diff`,`merge`,`discard`].includes(t))&&(console.error(`Usage: aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`),process.exit(1)),t===`list`){let e=De();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=N(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=we(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=ke(n);console.log(`Lane: ${e.name}`),console.log(`Modified: ${e.modified} | Added: ${e.added} | Deleted: ${e.deleted}`);for(let t of e.entries)console.log(` ${t.status.padEnd(10)} ${t.file}`);break}case`diff`:{let e=Te(n);console.log(`Lane: ${e.name} — ${e.modified} modified, ${e.added} added, ${e.deleted} deleted`);for(let t of e.entries)t.diff&&(console.log(`\n--- ${t.file} (${t.status})`),console.log(t.diff));break}case`merge`:{let e=Oe(n);console.log(`Merged ${e.filesMerged} files from lane "${e.name}".`);for(let t of e.files)console.log(` ${t}`);break}case`discard`:{let e=Ee(n);console.log(e?`Lane "${n}" discarded.`:`Lane "${n}" not found.`);break}}}},{name:`queue`,description:`Manage task queues for sequential agent operations`,usage:`aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`,run:async e=>{let t=e.shift();if((!t||![`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`].includes(t))&&(console.error(`Usage: aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`),process.exit(1)),t===`list`){let e=Ue();if(e.length===0){console.log(`No queues.`);return}for(let t of e)console.log(`${t.name} pending:${t.pending} done:${t.done} failed:${t.failed} total:${t.total}`);return}let n=e.shift();switch(n||(console.error(`Queue name is required for "${t}".`),process.exit(1)),t){case`create`:{let e=Re(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Ge(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=We(n);console.log(e?`Next: ${e.title} (${e.id})`:`No pending items in queue "${n}".`);break}case`done`:{let t=e.shift();t||(console.error(`Usage: aikit queue done <name> <id>`),process.exit(1));let r=Be(n,t);console.log(`Marked "${r.item.title}" as done.`);break}case`fail`:{let t=e.shift(),r=e.join(` `)||`Unknown error`;t||(console.error(`Usage: aikit queue fail <name> <id> [error message]`),process.exit(1));let i=Ve(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=He(n);if(!e){console.log(`Queue "${n}" not found.`);return}console.log(`Queue: ${e.name} (${e.items.length} items)`);for(let t of e.items){let e=t.error?` — ${t.error}`:``;console.log(` ${t.status.padEnd(12)} ${t.id} ${t.title}${e}`)}break}case`clear`:{let e=Le(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=ze(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],$=[...Yn,...Jn,...kt,...qn,...Xn,...Ln,...Gt,...$n,...In,...Qn,...Gn,...Fn];$.push({name:`help`,description:`Show available commands`,run:async()=>{tr()}});async function er(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){tr();return}if(n===`--version`||n===`-v`){let e=w(b(E(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(g(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=$.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=$.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),tr(),process.exit(1));try{await r.run(t)}finally{let e=Kn();e&&await e.store.close()}}function tr(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
22
22
  `),console.log(`Usage: aikit <command> [options]
23
23
  `),console.log(`Commands:`);let e=Math.max(...$.map(e=>e.name.length));for(let t of $)console.log(` ${t.name.padEnd(e+2)}${t.description}`);console.log(``),console.log(`Options:`),console.log(` --help, -h Show this help`),console.log(` --version, -v Show version`)}export{er as run};
@@ -1,4 +1,4 @@
1
- import{c as e,l as t,n,o as r,r as i,t as a}from"./scaffold-DwQDdiCJ.js";import{a as o,i as s,n as c,o as l,r as u,t as d}from"./templates-VOIHbNnT.js";import{appendFileSync as f,existsSync as p,mkdirSync as m,readFileSync as h,unlinkSync as g,writeFileSync as _}from"node:fs";import{basename as v,dirname as y,join as b,resolve as x}from"node:path";import{fileURLToPath as S}from"node:url";import{AIKIT_PATHS as C,EMBEDDING_DEFAULTS as w,isUserInstalled as T}from"../../core/dist/index.js";function E(e){return p(x(e,`.cursor`))?`cursor`:p(x(e,`.claude`))?`claude-code`:p(x(e,`.windsurf`))?`windsurf`:p(x(e,`.zed`))?`zed`:p(x(e,`.idea`))?`intellij`:`copilot`}function D(e){let t=[];return p(x(e,`.cursor`))&&t.push(`cursor`),(p(x(e,`.claude`))||p(x(e,`CLAUDE.md`)))&&t.push(`claude-code`),p(x(e,`.windsurf`))&&t.push(`windsurf`),p(x(e,`.zed`))&&t.push(`zed`),p(x(e,`.idea`))&&t.push(`intellij`),p(x(e,`.gemini`))&&t.push(`gemini-cli`),(p(x(e,`.codex`))||p(x(e,`codex.md`)))&&t.push(`codex-cli`),t.push(`copilot`),[...new Set(t)]}function O(e){return{servers:{[e]:{...s}}}}function k(e){let{type:t,...n}=s;return{mcpServers:{[e]:n}}}function A(e){let{type:t,...n}=s;return{context_servers:{[e]:{...n}}}}const j={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.vscode`),r=x(n,`mcp.json`);p(r)||(m(n,{recursive:!0}),_(r,`${JSON.stringify(O(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json`))},writeInstructions(e,t){let n=x(e,`.github`),r=x(n,`copilot-instructions.md`);m(n,{recursive:!0}),_(r,c(v(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,t){_(x(e,`AGENTS.md`),d(v(e),t),`utf-8`),console.log(` Updated AGENTS.md`)}},M={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.mcp.json`);p(n)||(_(n,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,t){let n=x(e,`CLAUDE.md`),r=v(e);_(n,`${c(r,t)}\n---\n\n${d(r,t)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},N={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.cursor`),r=x(n,`mcp.json`);p(r)||(m(n,{recursive:!0}),_(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .cursor/mcp.json`))},writeInstructions(e,t){let n=x(e,`.cursor`,`rules`),r=x(n,`aikit.mdc`);m(n,{recursive:!0});let i=v(e);_(r,`${c(i,t)}\n---\n\n${d(i,t)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let a=x(n,`kb.mdc`);p(a)&&a!==r&&(g(a),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},P={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.vscode`),r=x(n,`mcp.json`);p(r)||(m(n,{recursive:!0}),_(r,`${JSON.stringify(O(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,t){let n=x(e,`.windsurfrules`),r=v(e);_(n,`${c(r,t)}\n---\n\n${d(r,t)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}},F={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.zed`),r=x(n,`settings.json`);if(m(n,{recursive:!0}),!p(r))_(r,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .zed/settings.json`);else{let e;try{e=JSON.parse(h(r,`utf-8`))}catch{console.warn(` ⚠ .zed/settings.json contains invalid JSON — skipping MCP config merge`);return}e.context_servers?.[t]||(e.context_servers={...e.context_servers,...A(t).context_servers},_(r,`${JSON.stringify(e,null,2)}\n`,`utf-8`),console.log(` Updated .zed/settings.json with context_servers`))}},writeInstructions(e,t){let n=x(e,`.rules`),r=v(e);_(n,`${c(r,t)}\n---\n\n${d(r,t)}`,`utf-8`),console.log(` Updated .rules`)},writeAgentsMd(e,t){}},I={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`mcp.json`);p(n)||(_(n,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created mcp.json`))},writeInstructions(e,t){let n=x(e,`.aiassistant`,`rules`),r=x(n,`aikit.md`);m(n,{recursive:!0});let i=v(e);_(r,`${c(i,t)}\n---\n\n${d(i,t)}`,`utf-8`),console.log(` Updated .aiassistant/rules/aikit.md`)},writeAgentsMd(e,t){}};function L(e){switch(e){case`copilot`:return j;case`claude-code`:return M;case`cursor`:return N;case`windsurf`:return P;case`zed`:return F;case`intellij`:return I;case`gemini-cli`:case`codex-cli`:return j}}const R={serverName:o,sources:[{path:`.`,excludePatterns:[`**/node_modules/**`,`**/dist/**`,`**/build/**`,`**/.git/**`,`**/${C.data}/**`,`**/coverage/**`,`**/*.min.js`,`**/package-lock.json`,`**/pnpm-lock.yaml`]}],indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:w.model,dimensions:w.dimensions},store:{backend:`sqlite-vec`,path:C.data},curated:{path:C.aiCurated}};function z(e,t){let n=x(e,`aikit.config.json`);return p(n)&&!t?(console.log(`aikit.config.json already exists. Use --force to overwrite.`),!1):(_(n,`${JSON.stringify(R,null,2)}\n`,`utf-8`),console.log(` Created aikit.config.json`),!0)}function B(e){let t=x(e,`.gitignore`),n=[{dir:`${C.data}/`,label:`AI Kit vector store`},{dir:`${C.state}/`,label:`AI Kit session state`},{dir:`${C.restorePoints}/`,label:`Restore points (codemod/rename undo snapshots)`},{dir:`${C.brainstorm}/`,label:`Brainstorming sessions`},{dir:`${C.handoffs}/`,label:`Handoff documents`}];if(p(t)){let e=h(t,`utf-8`),r=n.filter(t=>!e.includes(t.dir));r.length>0&&(f(t,`\n${r.map(e=>`# ${e.label}\n${e.dir}`).join(`
1
+ import{c as e,l as t,n,o as r,r as i,t as a}from"./scaffold-DwQDdiCJ.js";import{a as o,i as s,n as c,o as l,r as u,t as d}from"./templates-D-eA4QVK.js";import{appendFileSync as f,existsSync as p,mkdirSync as m,readFileSync as h,unlinkSync as g,writeFileSync as _}from"node:fs";import{basename as v,dirname as y,join as b,resolve as x}from"node:path";import{fileURLToPath as S}from"node:url";import{AIKIT_PATHS as C,EMBEDDING_DEFAULTS as w,isUserInstalled as T}from"../../core/dist/index.js";function E(e){return p(x(e,`.cursor`))?`cursor`:p(x(e,`.claude`))?`claude-code`:p(x(e,`.windsurf`))?`windsurf`:p(x(e,`.zed`))?`zed`:p(x(e,`.idea`))?`intellij`:`copilot`}function D(e){let t=[];return p(x(e,`.cursor`))&&t.push(`cursor`),(p(x(e,`.claude`))||p(x(e,`CLAUDE.md`)))&&t.push(`claude-code`),p(x(e,`.windsurf`))&&t.push(`windsurf`),p(x(e,`.zed`))&&t.push(`zed`),p(x(e,`.idea`))&&t.push(`intellij`),p(x(e,`.gemini`))&&t.push(`gemini-cli`),(p(x(e,`.codex`))||p(x(e,`codex.md`)))&&t.push(`codex-cli`),t.push(`copilot`),[...new Set(t)]}function O(e){return{servers:{[e]:{...s}}}}function k(e){let{type:t,...n}=s;return{mcpServers:{[e]:n}}}function A(e){let{type:t,...n}=s;return{context_servers:{[e]:{...n}}}}const j={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.vscode`),r=x(n,`mcp.json`);p(r)||(m(n,{recursive:!0}),_(r,`${JSON.stringify(O(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json`))},writeInstructions(e,t){let n=x(e,`.github`),r=x(n,`copilot-instructions.md`);m(n,{recursive:!0}),_(r,c(v(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,t){_(x(e,`AGENTS.md`),d(v(e),t),`utf-8`),console.log(` Updated AGENTS.md`)}},M={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.mcp.json`);p(n)||(_(n,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,t){let n=x(e,`CLAUDE.md`),r=v(e);_(n,`${c(r,t)}\n---\n\n${d(r,t)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},N={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.cursor`),r=x(n,`mcp.json`);p(r)||(m(n,{recursive:!0}),_(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .cursor/mcp.json`))},writeInstructions(e,t){let n=x(e,`.cursor`,`rules`),r=x(n,`aikit.mdc`);m(n,{recursive:!0});let i=v(e);_(r,`${c(i,t)}\n---\n\n${d(i,t)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let a=x(n,`kb.mdc`);p(a)&&a!==r&&(g(a),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},P={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.vscode`),r=x(n,`mcp.json`);p(r)||(m(n,{recursive:!0}),_(r,`${JSON.stringify(O(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,t){let n=x(e,`.windsurfrules`),r=v(e);_(n,`${c(r,t)}\n---\n\n${d(r,t)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}},F={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`.zed`),r=x(n,`settings.json`);if(m(n,{recursive:!0}),!p(r))_(r,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .zed/settings.json`);else{let e;try{e=JSON.parse(h(r,`utf-8`))}catch{console.warn(` ⚠ .zed/settings.json contains invalid JSON — skipping MCP config merge`);return}e.context_servers?.[t]||(e.context_servers={...e.context_servers,...A(t).context_servers},_(r,`${JSON.stringify(e,null,2)}\n`,`utf-8`),console.log(` Updated .zed/settings.json with context_servers`))}},writeInstructions(e,t){let n=x(e,`.rules`),r=v(e);_(n,`${c(r,t)}\n---\n\n${d(r,t)}`,`utf-8`),console.log(` Updated .rules`)},writeAgentsMd(e,t){}},I={scaffoldDir:`general`,writeMcpConfig(e,t){let n=x(e,`mcp.json`);p(n)||(_(n,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created mcp.json`))},writeInstructions(e,t){let n=x(e,`.aiassistant`,`rules`),r=x(n,`aikit.md`);m(n,{recursive:!0});let i=v(e);_(r,`${c(i,t)}\n---\n\n${d(i,t)}`,`utf-8`),console.log(` Updated .aiassistant/rules/aikit.md`)},writeAgentsMd(e,t){}};function L(e){switch(e){case`copilot`:return j;case`claude-code`:return M;case`cursor`:return N;case`windsurf`:return P;case`zed`:return F;case`intellij`:return I;case`gemini-cli`:case`codex-cli`:return j}}const R={serverName:o,sources:[{path:`.`,excludePatterns:[`**/node_modules/**`,`**/dist/**`,`**/build/**`,`**/.git/**`,`**/${C.data}/**`,`**/coverage/**`,`**/*.min.js`,`**/package-lock.json`,`**/pnpm-lock.yaml`]}],indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:w.model,dimensions:w.dimensions},store:{backend:`sqlite-vec`,path:C.data},curated:{path:C.aiCurated}};function z(e,t){let n=x(e,`aikit.config.json`);return p(n)&&!t?(console.log(`aikit.config.json already exists. Use --force to overwrite.`),!1):(_(n,`${JSON.stringify(R,null,2)}\n`,`utf-8`),console.log(` Created aikit.config.json`),!0)}function B(e){let t=x(e,`.gitignore`),n=[{dir:`${C.data}/`,label:`AI Kit vector store`},{dir:`${C.state}/`,label:`AI Kit session state`},{dir:`${C.restorePoints}/`,label:`Restore points (codemod/rename undo snapshots)`},{dir:`${C.brainstorm}/`,label:`Brainstorming sessions`},{dir:`${C.handoffs}/`,label:`Handoff documents`}];if(p(t)){let e=h(t,`utf-8`),r=n.filter(t=>!e.includes(t.dir));r.length>0&&(f(t,`\n${r.map(e=>`# ${e.label}\n${e.dir}`).join(`
2
2
  `)}\n`,`utf-8`),console.log(` Added ${r.map(e=>e.dir).join(`, `)} to .gitignore`))}else _(t,`${n.map(e=>`# ${e.label}\n${e.dir}`).join(`
3
3
  `)}\n`,`utf-8`),console.log(` Created .gitignore with AI Kit entries`)}function V(){return R.serverName}const H=[`decisions`,`patterns`,`conventions`,`troubleshooting`];function U(e){let t=x(e,`.ai`,`curated`);p(t)||(m(t,{recursive:!0}),console.log(` Created .ai/curated/`));for(let e of H){let n=x(t,e);p(n)||m(n,{recursive:!0})}console.log(` Created .ai/curated/{${H.join(`,`)}}/`)}function W(e){switch(e){case`zed`:return`zed`;case`intellij`:return`intellij`;case`claude-code`:return`claude-code`;case`gemini-cli`:return`gemini`;case`codex-cli`:return`codex`;default:return`copilot`}}function G(e){let t=e;for(let e=0;e<10;e++){try{let e=b(t,`package.json`);if(p(e)&&JSON.parse(h(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=y(t);if(e===t)break;t=e}return x(e,`..`,`..`,`..`)}async function K(n){let i=process.cwd();if(!z(i,n.force))return;B(i);let a=V(),o=L(E(i));o.writeMcpConfig(i,a),o.writeInstructions(i,a),o.writeAgentsMd(i,a);let s=G(y(S(import.meta.url))),c=JSON.parse(h(x(s,`package.json`),`utf-8`)).version;await t(i,s,[...l],c,n.force),await r(i,s,[...u],c,n.force);let d=D(i),f=new Set;for(let t of d){let r=W(t);f.has(r)||(f.add(r),await e(i,s,r,c,n.force))}U(i),console.log(`
4
4
  AI Kit initialized! Next steps:`),console.log(` aikit reindex Index your codebase`),console.log(` aikit search Search indexed content`),console.log(` aikit serve Start MCP server for IDE integration`),T()&&console.log(`
@@ -1,4 +1,4 @@
1
- import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,join as r,resolve as i}from"node:path";import{fileURLToPath as a}from"node:url";const o=[`const{execSync:x}=require('child_process')`,`const{readdirSync:r,renameSync:m}=require('fs')`,`const{join:j}=require('path')`,`const c=j(process.env.LOCALAPPDATA||process.env.HOME||'','npm-cache')`,`const s={stdio:'inherit'}`,`try{x('npx --prefer-online -y @vpxa/aikit serve',s)}catch{try{x('npx -y @vpxa/aikit serve',s)}catch{try{r(c).filter(d=>d.startsWith('_npx')).forEach(d=>m(j(c,d),j(c,d+'_'+Date.now())))}catch{};x('npx -y @vpxa/aikit serve',s)}}`].join(`;`),s=`aikit`,c={type:`stdio`,command:`node`,args:[`-e`,o]},l=[`aikit`,`brainstorming`,`multi-agents-development`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`,`present`,`frontend-design`,`react`,`typescript`,`docs`,`repo-access`],u=[`aikit-basic`,`aikit-advanced`,`_epilogue`],d={"chat.agentFilesLocations":{"~/.claude/agents":!1},"chat.useClaudeMdFile":!1,"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0,"workbench.browser.enableChatTools":!0,"chat.mcp.apps.enabled":!0,"chat.instructionsFilesLocations":{"~/.copilot/instructions":!0,".github/instructions":!0,".claude/rules":!1,"~/.claude/rules":!1}},f=/{\s*name:\s*'((?:\\.|[^'])*)',\s*rationale:\s*'((?:\\.|[^'])*)',\s*bitterLessonSafe:\s*(?:true|false),\s*}/g;let p=null;function m(a){let o=a;for(let i=0;i<10;i++){try{let n=r(o,`package.json`);if(e(n)&&JSON.parse(t(n,`utf8`)).name===`@vpxa/aikit`)return o}catch{}let i=n(o);if(i===o)break;o=i}return i(a,`..`,`..`,`..`,`..`)}function h(e){return e.replace(/\\'/g,`'`).replace(/\\n/g,`
1
+ import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,join as r,resolve as i}from"node:path";import{fileURLToPath as a}from"node:url";const o=[`const{execSync:x}=require('child_process')`,`const{readdirSync:r,renameSync:m}=require('fs')`,`const{join:j}=require('path')`,`const c=j(process.env.LOCALAPPDATA||process.env.HOME||'','npm-cache')`,`const s={stdio:'inherit'}`,`try{x('npx -y @vpxa/aikit serve',s)}catch{try{r(c).filter(d=>d.startsWith('_npx')).forEach(d=>m(j(c,d),j(c,d+'_'+Date.now())))}catch{};try{x('npm cache verify',{stdio:'ignore',timeout:30000})}catch{};x('npx -y @vpxa/aikit serve',s)}`].join(`;`),s=`aikit`,c={type:`stdio`,command:`node`,args:[`-e`,o]},l=[`aikit`,`brainstorming`,`multi-agents-development`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`,`present`,`frontend-design`,`react`,`typescript`,`docs`,`repo-access`],u=[`aikit-basic`,`aikit-advanced`,`_epilogue`],d={"chat.agentFilesLocations":{"~/.claude/agents":!1},"chat.useClaudeMdFile":!1,"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0,"workbench.browser.enableChatTools":!0,"chat.mcp.apps.enabled":!0,"chat.instructionsFilesLocations":{"~/.copilot/instructions":!0,".github/instructions":!0,".claude/rules":!1,"~/.claude/rules":!1}},f=/{\s*name:\s*'((?:\\.|[^'])*)',\s*rationale:\s*'((?:\\.|[^'])*)',\s*bitterLessonSafe:\s*(?:true|false),\s*}/g;let p=null;function m(a){let o=a;for(let i=0;i<10;i++){try{let n=r(o,`package.json`);if(e(n)&&JSON.parse(t(n,`utf8`)).name===`@vpxa/aikit`)return o}catch{}let i=n(o);if(i===o)break;o=i}return i(a,`..`,`..`,`..`,`..`)}function h(e){return e.replace(/\\'/g,`'`).replace(/\\n/g,`
2
2
  `).replace(/\\r/g,`\r`).replace(/\\t/g,` `).replace(/\\\\/g,`\\`)}function g(){if(p)return p;let e=i(m(n(a(import.meta.url))),`scaffold`,`definitions`,`exclusions.mjs`),r=t(e,`utf8`),o=Array.from(r.matchAll(f),([,e,t])=>({name:h(e),rationale:h(t)}));if(o.length===0)throw Error(`Failed to parse permanent exclusions from ${e}`);return p=o,o}function _(e){return e.replace(/\|/g,`\\|`).replace(/\r?\n+/g,` `).trim()}function v(){return`## Permanent Exclusions
3
3
 
4
4
  These capabilities are intentionally NOT provided by aikit. Each decision follows the Bitter Lesson: leverage computation and configurable tools over hand-crafted features.
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{rm as e}from"node:fs/promises";import{homedir as t}from"node:os";import{join as n}from"node:path";import{EMBEDDING_DEFAULTS as r}from"../../core/dist/index.js";let i=null;async function a(){return i||(i=await import(`@huggingface/transformers`),i.env.cacheDir=n(t(),`.cache`,`huggingface`,`transformers-js`)),i}var o=class{pipe=null;shutdownPromise=null;dimensions;modelId;nativeDim;queryPrefix;threadConfig;constructor(e){if(this.modelId=e?.model??r.model,this.nativeDim=e?.nativeDim??1024,this.dimensions=e?.dimensions??r.dimensions,this.dimensions>this.nativeDim)throw Error(`Configured dimensions (${this.dimensions}) exceeds model native output (${this.nativeDim}). Matryoshka truncation cannot upscale — dimensions must be <= nativeDim.`);this.queryPrefix=e?.queryPrefix??this.detectQueryPrefix(this.modelId),this.threadConfig={interOp:e?.interOpNumThreads??1,intraOp:e?.intraOpNumThreads??4}}getPipelineOptions(e){let t=e.backends.onnx;t.wasm||={};let n=t.wasm;return n.numThreads=this.threadConfig.intraOp,{dtype:`q8`,session_options:{interOpNumThreads:this.threadConfig.interOp,intraOpNumThreads:this.threadConfig.intraOp}}}computeNorm(e){let t=0;for(let n=0;n<e.length;n++)t+=e[n]*e[n];return Math.sqrt(t)}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim){let t=this.computeNorm(e);if(!Number.isFinite(t))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(t===0)throw Error(`Embedding produced zero-norm vector from ONNX output`);return e}let t=e.subarray(0,this.dimensions),n=this.computeNorm(t);if(!Number.isFinite(n))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(n===0)throw Error(`Embedding produced zero-norm vector after truncation — input may be degenerate`);let r=new Float32Array(this.dimensions);for(let e=0;e<this.dimensions;e++)r[e]=t[e]/n;return r}detectQueryPrefix(e){let t=e.toLowerCase();return t.includes(`bge`)||t.includes(`mxbai-embed`)?`Represent this sentence for searching relevant passages: `:t.includes(`/e5-`)||t.includes(`multilingual-e5`)?`query: `:``}async initialize(){if(this.pipe)return;this.shutdownPromise=null;let{pipeline:r,env:i}=await a();try{this.pipe=await r(`feature-extraction`,this.modelId,this.getPipelineOptions(i))}catch(a){let o=a.message?.toLowerCase()??``;if(this.isCorruptionError(o)){let a=n(i.cacheDir??n(t(),`.cache`,`huggingface`,`transformers-js`),this.modelId);console.error(`[aikit:auto-heal] Detected corrupted model cache for "${this.modelId}". Clearing cache at ${a} and retrying download...`);try{await e(a,{recursive:!0,force:!0})}catch{}try{this.pipe=await r(`feature-extraction`,this.modelId,this.getPipelineOptions(i)),console.error(`[aikit:auto-heal] Model "${this.modelId}" re-downloaded successfully.`);return}catch(e){throw Error(`Failed to initialize embedding model "${this.modelId}" after auto-heal: ${e.message}`)}}throw Error(`Failed to initialize embedding model "${this.modelId}": ${a.message}`)}}isCorruptionError(e){return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`checksum`,`corrupt`,`could not load`,`onnx`,`malformed`].some(t=>e.includes(t))}async shutdown(){return this.shutdownPromise||=this._doShutdown(),this.shutdownPromise}async _doShutdown(){let e=this.pipe;if(e)try{let t=e;typeof t.dispose==`function`?await t.dispose():typeof t.model?.dispose==`function`&&await t.model.dispose()}catch{}finally{this.pipe=null}}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t?.data)throw Error(`Embedding pipeline returned no output`);try{let e=new Float32Array(t.data);return this.truncateAndRenorm(e)}finally{t.dispose?.()}}async embedQuery(e){return this.embed(this.queryPrefix+e)}async embedBatch(e,t=64){if(e.length===0)return[];this.pipe||await this.initialize();let n=[];for(let r=0;r<e.length;r+=t){let i=e.slice(r,r+t),a=await this.pipe?.(i,{pooling:`mean`,normalize:!0});if(!a?.data)throw Error(`Embedding pipeline returned no output`);try{if(i.length===1){let e=new Float32Array(a.data);n.push(this.truncateAndRenorm(e))}else for(let e=0;e<i.length;e++){let t=e*this.nativeDim,r=a.data.slice(t,t+this.nativeDim);n.push(this.truncateAndRenorm(new Float32Array(r)))}}finally{a.dispose?.()}}return n}};let s=null,c=null,l=!1;const u=Number(process.env.AIKIT_EMBED_IDLE_MS),d=Number.isFinite(u)&&u>=0?u:6e4,f=Number(process.env.AIKIT_EMBED_MAX_RSS_MB),p=Number.isFinite(f)&&f>0?f:1536;function m(){let e=process.memoryUsage;return(typeof e.rss==`function`?e.rss():e().rss)/(1024*1024)>p}function h(e){process.send?.(e)}function g(){c&&=(clearTimeout(c),null)}async function _(){if(!s)return;let e=s;s=null,await e.shutdown?.()}async function v(e,t){l&&process.exit(e),l=!0,g(),t?.notifyIdle&&h({type:`idle-exit`});try{await _()}finally{process.exit(e)}}function y(){g(),d!==0&&(c=setTimeout(()=>{v(0,{notifyIdle:!0})},d))}function b(e){return Array.from(e)}function x(e){return e instanceof Error?e.message:String(e)}function S(){if(!s)throw Error(`Embedder not initialized`);return s}async function C(e,t){h({type:`error`,id:e,message:x(t)})}async function w(e){g();try{switch(e.type){case`init`:await _(),s=new o(e.config),await s.initialize(),h({type:`ready`,dimensions:s.dimensions,modelId:s.modelId});break;case`embed`:{let t=await S().embed(e.text);h({type:`result`,id:e.id,data:b(t)});break}case`embedBatch`:{let t=await S().embedBatch(e.texts,e.batchSize);h({type:`batchResult`,id:e.id,data:t.map(e=>b(e))});break}case`embedQuery`:{let t=await S().embedQuery(e.text);h({type:`result`,id:e.id,data:b(t)});break}case`shutdown`:await v(0);return}}catch(t){if(await C(e.type===`shutdown`?`shutdown`:e.type===`init`?`init`:e.id,t),e.type===`init`){await v(1);return}}if(m()){await v(0,{notifyIdle:!0});return}y()}async function T(e,t){await C(e,t),await v(1)}process.on(`message`,e=>{w(e)}),process.on(`SIGTERM`,()=>{v(0)}),process.on(`uncaughtException`,e=>{T(`fatal`,e)}),process.on(`unhandledRejection`,e=>{T(`fatal`,e)});export{};
2
+ import{rm as e}from"node:fs/promises";import{homedir as t}from"node:os";import{join as n}from"node:path";import{EMBEDDING_DEFAULTS as r}from"../../core/dist/index.js";let i=null;async function a(){if(!i){try{i=await import(`@huggingface/transformers`)}catch(e){if(e instanceof Error&&e.message.includes(`Cannot find module`)){let{createRequire:e}=await import(`node:module`);i=e(import.meta.url)(`@huggingface/transformers`)}else throw e}i.env.cacheDir=n(t(),`.cache`,`huggingface`,`transformers-js`)}return i}var o=class{pipe=null;shutdownPromise=null;dimensions;modelId;nativeDim;queryPrefix;threadConfig;constructor(e){if(this.modelId=e?.model??r.model,this.nativeDim=e?.nativeDim??1024,this.dimensions=e?.dimensions??r.dimensions,this.dimensions>this.nativeDim)throw Error(`Configured dimensions (${this.dimensions}) exceeds model native output (${this.nativeDim}). Matryoshka truncation cannot upscale — dimensions must be <= nativeDim.`);this.queryPrefix=e?.queryPrefix??this.detectQueryPrefix(this.modelId),this.threadConfig={interOp:e?.interOpNumThreads??1,intraOp:e?.intraOpNumThreads??4}}getPipelineOptions(e){let t=e.backends.onnx;t.wasm||={};let n=t.wasm;return n.numThreads=this.threadConfig.intraOp,{dtype:`q8`,session_options:{interOpNumThreads:this.threadConfig.interOp,intraOpNumThreads:this.threadConfig.intraOp}}}computeNorm(e){let t=0;for(let n=0;n<e.length;n++)t+=e[n]*e[n];return Math.sqrt(t)}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim){let t=this.computeNorm(e);if(!Number.isFinite(t))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(t===0)throw Error(`Embedding produced zero-norm vector from ONNX output`);return e}let t=e.subarray(0,this.dimensions),n=this.computeNorm(t);if(!Number.isFinite(n))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(n===0)throw Error(`Embedding produced zero-norm vector after truncation — input may be degenerate`);let r=new Float32Array(this.dimensions);for(let e=0;e<this.dimensions;e++)r[e]=t[e]/n;return r}detectQueryPrefix(e){let t=e.toLowerCase();return t.includes(`bge`)||t.includes(`mxbai-embed`)?`Represent this sentence for searching relevant passages: `:t.includes(`/e5-`)||t.includes(`multilingual-e5`)?`query: `:``}async initialize(){if(this.pipe)return;this.shutdownPromise=null;let{pipeline:r,env:i}=await a();try{this.pipe=await r(`feature-extraction`,this.modelId,this.getPipelineOptions(i))}catch(a){let o=a.message?.toLowerCase()??``;if(this.isCorruptionError(o)){let a=n(i.cacheDir??n(t(),`.cache`,`huggingface`,`transformers-js`),this.modelId);console.error(`[aikit:auto-heal] Detected corrupted model cache for "${this.modelId}". Clearing cache at ${a} and retrying download...`);try{await e(a,{recursive:!0,force:!0})}catch{}try{this.pipe=await r(`feature-extraction`,this.modelId,this.getPipelineOptions(i)),console.error(`[aikit:auto-heal] Model "${this.modelId}" re-downloaded successfully.`);return}catch(e){throw Error(`Failed to initialize embedding model "${this.modelId}" after auto-heal: ${e.message}`)}}throw Error(`Failed to initialize embedding model "${this.modelId}": ${a.message}`)}}isCorruptionError(e){return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`checksum`,`corrupt`,`could not load`,`onnx`,`malformed`].some(t=>e.includes(t))}async shutdown(){return this.shutdownPromise||=this._doShutdown(),this.shutdownPromise}async _doShutdown(){let e=this.pipe;if(e)try{let t=e;typeof t.dispose==`function`?await t.dispose():typeof t.model?.dispose==`function`&&await t.model.dispose()}catch{}finally{this.pipe=null}}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t?.data)throw Error(`Embedding pipeline returned no output`);try{let e=new Float32Array(t.data);return this.truncateAndRenorm(e)}finally{t.dispose?.()}}async embedQuery(e){return this.embed(this.queryPrefix+e)}async embedBatch(e,t=64){if(e.length===0)return[];this.pipe||await this.initialize();let n=[];for(let r=0;r<e.length;r+=t){let i=e.slice(r,r+t),a=await this.pipe?.(i,{pooling:`mean`,normalize:!0});if(!a?.data)throw Error(`Embedding pipeline returned no output`);try{if(i.length===1){let e=new Float32Array(a.data);n.push(this.truncateAndRenorm(e))}else for(let e=0;e<i.length;e++){let t=e*this.nativeDim,r=a.data.slice(t,t+this.nativeDim);n.push(this.truncateAndRenorm(new Float32Array(r)))}}finally{a.dispose?.()}}return n}};let s=null,c=null,l=!1;const u=Number(process.env.AIKIT_EMBED_IDLE_MS),d=Number.isFinite(u)&&u>=0?u:6e4,f=Number(process.env.AIKIT_EMBED_MAX_RSS_MB),p=Number.isFinite(f)&&f>0?f:1536;function m(){let e=process.memoryUsage;return(typeof e.rss==`function`?e.rss():e().rss)/(1024*1024)>p}function h(e){process.send?.(e)}function g(){c&&=(clearTimeout(c),null)}async function _(){if(!s)return;let e=s;s=null,await e.shutdown?.()}async function v(e,t){l&&process.exit(e),l=!0,g(),t?.notifyIdle&&h({type:`idle-exit`});try{await _()}finally{process.exit(e)}}function y(){g(),d!==0&&(c=setTimeout(()=>{v(0,{notifyIdle:!0})},d))}function b(e){return Array.from(e)}function x(e){return e instanceof Error?e.message:String(e)}function S(){if(!s)throw Error(`Embedder not initialized`);return s}async function C(e,t){h({type:`error`,id:e,message:x(t)})}async function w(e){g();try{switch(e.type){case`init`:await _(),s=new o(e.config),await s.initialize(),h({type:`ready`,dimensions:s.dimensions,modelId:s.modelId});break;case`embed`:{let t=await S().embed(e.text);h({type:`result`,id:e.id,data:b(t)});break}case`embedBatch`:{let t=await S().embedBatch(e.texts,e.batchSize);h({type:`batchResult`,id:e.id,data:t.map(e=>b(e))});break}case`embedQuery`:{let t=await S().embedQuery(e.text);h({type:`result`,id:e.id,data:b(t)});break}case`shutdown`:await v(0);return}}catch(t){if(await C(e.type===`shutdown`?`shutdown`:e.type===`init`?`init`:e.id,t),e.type===`init`){await v(1);return}}if(m()){await v(0,{notifyIdle:!0});return}y()}async function T(e,t){await C(e,t),await v(1)}process.on(`message`,e=>{w(e)}),process.on(`SIGTERM`,()=>{v(0)}),process.on(`uncaughtException`,e=>{T(`fatal`,e)}),process.on(`unhandledRejection`,e=>{T(`fatal`,e)});export{};
@@ -1 +1 @@
1
- import{fork as e}from"node:child_process";import{randomUUID as t}from"node:crypto";import{existsSync as n}from"node:fs";import{dirname as r,join as i}from"node:path";import{fileURLToPath as a}from"node:url";import{EMBEDDING_DEFAULTS as o}from"../../core/dist/index.js";import{rm as s}from"node:fs/promises";import{homedir as c}from"node:os";var l=class{options;logger;maxRetries;retryBaseDelayMs;workerAvailable=!0;workerPath=i(r(a(import.meta.url)),`embedder-worker.js`);pendingRequests=new Map;childState=new WeakMap;child=null;readyChild=null;pendingInit=null;pendingShutdown=null;initializePromise=null;shutdownPromise=null;currentDimensions;currentModelId;constructor(e={}){this.options=e,this.logger=e.logger,this.maxRetries=Math.max(0,e.maxRetries??3),this.retryBaseDelayMs=Math.max(0,e.retryBaseDelayMs??500),this.currentDimensions=e.dimensions??o.dimensions,this.currentModelId=e.model??o.model}get dimensions(){return this.currentDimensions}get modelId(){return this.currentModelId}async initialize(){if(!(this.readyChild&&this.child===this.readyChild)&&this.workerAvailable){if(!n(this.workerPath)){this.workerAvailable=!1,console.warn(`[aikit] Embedder worker not found at ${this.workerPath}. Embedding disabled - search will use keyword matching only. This usually means the npx cache is corrupted; restart to fix.`);return}if(this.initializePromise)return this.initializePromise;if(this.shutdownPromise){try{await this.shutdownPromise}catch{}if(this.readyChild&&this.child===this.readyChild)return}return this.initializePromise=this.startWorker().finally(()=>{this.initializePromise=null}),this.initializePromise}}async embed(e){if(!this.workerAvailable||(await this.initialize(),!this.workerAvailable))throw Error(`Embedding worker is not available — embeddings cannot be computed. Check server logs for initialization errors.`);return this.sendVectorRequestWithRetry({type:`embed`,text:e})}async embedQuery(e){if(!this.workerAvailable||(await this.initialize(),!this.workerAvailable))throw Error(`Embedding worker is not available — embeddings cannot be computed. Check server logs for initialization errors.`);return this.sendVectorRequestWithRetry({type:`embedQuery`,text:e})}async embedBatch(e,t){if(e.length===0)return[];if(!this.workerAvailable||(await this.initialize(),!this.workerAvailable))throw Error(`Embedding worker is not available — embeddings cannot be computed. Check server logs for initialization errors.`);return this.withWorkerExitRetry(`embedBatch`,()=>this.sendBatchRequest(e,t))}async sendBatchRequest(e,n){await this.initialize();let r=this.requireReadyChild(),i=t(),a=new Promise((e,t)=>{this.pendingRequests.set(i,{child:r,resolve:t=>e(t),reject:t})});try{r.send({type:`embedBatch`,id:i,texts:e,batchSize:n})}catch(e){throw this.pendingRequests.delete(i),this.toError(e,`Failed to send embedBatch request to worker`)}return a}async shutdown(){if(this.shutdownPromise)return this.shutdownPromise;let e=this.child;if(!e)return;let t=this.requireChildState(e);t.shutdownRequested=!0,this.readyChild===e&&(this.readyChild=null),this.shutdownPromise=new Promise((t,n)=>{this.pendingShutdown={child:e,resolve:t,reject:n}}).finally(()=>{this.shutdownPromise=null});try{e.send({type:`shutdown`})}catch(t){let n=this.toError(t,`Failed to send shutdown request to worker`);throw this.clearChildReference(e),this.rejectPendingForChild(e,n),this.rejectLifecycleIfOwned(`shutdown`,e,n),n}return this.shutdownPromise}async startWorker(){this.child&&this.readyChild!==this.child&&(this.child=null);let e=this.spawnChild();this.child=e,this.readyChild=null;let t=new Promise((t,n)=>{this.pendingInit={child:e,resolve:t,reject:n}});try{e.send({type:`init`,config:this.buildInitConfig()})}catch(t){let n=this.toError(t,`Failed to send init request to worker`);throw this.pendingInit=null,this.clearChildReference(e),n}return t}spawnChild(){let t=e(this.workerPath,[],{env:this.buildChildEnv()});return this.childState.set(t,{idleExitNotified:!1,shutdownRequested:!1,terminated:!1}),t.on(`message`,e=>{this.handleChildMessage(t,e)}),t.once(`error`,e=>{this.handleChildFailure(t,this.toError(e,`Embedder worker failed`))}),t.once(`exit`,(e,n)=>{this.handleChildExit(t,e,n)}),t}handleChildMessage(e,t){switch(t.type){case`ready`:{this.currentDimensions=t.dimensions,this.currentModelId=t.modelId,this.child===e&&(this.readyChild=e);let n=this.pendingInit;n?.child===e&&(this.pendingInit=null,n.resolve());return}case`result`:{let n=this.pendingRequests.get(t.id);if(!n||n.child!==e)return;this.pendingRequests.delete(t.id),n.resolve(new Float32Array(t.data));return}case`batchResult`:{let n=this.pendingRequests.get(t.id);if(!n||n.child!==e)return;if(this.pendingRequests.delete(t.id),!t.data||!Array.isArray(t.data)||t.data.length===0)n.reject(Error(`Worker returned empty or invalid batch result`));else{let e=t.data.map(e=>new Float32Array(e)),r=e.findIndex(e=>e.length===0);r>=0?n.reject(Error(`Worker returned zero-length vector at index ${r}`)):n.resolve(e)}return}case`error`:{let n=Error(t.message);if(t.id===`init`){this.clearChildReference(e),this.rejectLifecycleIfOwned(`init`,e,n);return}if(t.id===`shutdown`){this.rejectLifecycleIfOwned(`shutdown`,e,n);return}let r=this.pendingRequests.get(t.id);if(!r||r.child!==e)return;this.pendingRequests.delete(t.id),r.reject(n);return}case`idle-exit`:{let t=this.requireChildState(e);t.idleExitNotified=!0,this.clearChildReference(e);return}}}handleChildExit(e,t,n){let r=this.requireChildState(e);if(r.terminated)return;r.terminated=!0,this.clearChildReference(e);let i=r.shutdownRequested||r.idleExitNotified,a=Error(i?`Embedder worker exited before completing request`:`Embedder worker exited unexpectedly (code ${t??`null`}${n?`, signal ${n}`:``})`);this.rejectLifecycleIfOwned(`init`,e,a),i?this.resolveLifecycleIfOwned(`shutdown`,e):this.rejectLifecycleIfOwned(`shutdown`,e,a),this.rejectPendingForChild(e,a)}handleChildFailure(e,t){let n=this.requireChildState(e);n.terminated||(n.terminated=!0,this.clearChildReference(e),this.rejectLifecycleIfOwned(`init`,e,t),this.rejectLifecycleIfOwned(`shutdown`,e,t),this.rejectPendingForChild(e,t))}async sendVectorRequestWithRetry(e){return this.withWorkerExitRetry(e.type,()=>this.sendVectorRequest(e))}async sendVectorRequest(e){await this.initialize();let n=this.requireReadyChild(),r=t(),i=new Promise((e,t)=>{this.pendingRequests.set(r,{child:n,resolve:t=>e(t),reject:t})});try{n.send({...e,id:r})}catch(t){throw this.pendingRequests.delete(r),this.toError(t,`Failed to send ${e.type} request to worker`)}return i}async withWorkerExitRetry(e,t){let n=null;for(let r=0;r<=this.maxRetries;r++)try{return await t()}catch(t){let i=this.toError(t,`Failed to process ${e} request`);if(!this.isWorkerExitError(i))throw i;if(n??=i,r===this.maxRetries)throw n;let a=r+1,o=this.retryBaseDelayMs*2**r;this.logger?.warn?.(`Embedder retry ${a}/${this.maxRetries} after ${o}ms`,{requestType:e,delayMs:o,error:i.message}),this.child=null,this.readyChild=null,await this.wait(o)}throw n??Error(`Failed to process ${e} request`)}isWorkerExitError(e){return/embedder worker exited/i.test(e.message)}wait(e){return new Promise(t=>{setTimeout(t,e)})}requireReadyChild(){if(!this.child||this.readyChild!==this.child)throw Error(`Embedder worker is not initialized`);return this.child}buildInitConfig(){return{model:this.options.model,dimensions:this.options.dimensions,nativeDim:this.options.nativeDim,queryPrefix:this.options.queryPrefix,interOpNumThreads:this.options.interOpNumThreads,intraOpNumThreads:this.options.intraOpNumThreads}}buildChildEnv(){return this.options.idleTimeoutMs===void 0?process.env:{...process.env,AIKIT_EMBED_IDLE_MS:String(this.options.idleTimeoutMs)}}requireChildState(e){let t=this.childState.get(e);if(!t)throw Error(`Embedder worker state not found`);return t}clearChildReference(e){this.child===e&&(this.child=null),this.readyChild===e&&(this.readyChild=null)}rejectPendingForChild(e,t){for(let[n,r]of this.pendingRequests)r.child===e&&(this.pendingRequests.delete(n),r.reject(t))}resolveLifecycleIfOwned(e,t){let n=this.pendingShutdown;!n||n.child!==t||(this.pendingShutdown=null,n.resolve())}rejectLifecycleIfOwned(e,t,n){let r=e===`init`?this.pendingInit:this.pendingShutdown;!r||r.child!==t||(e===`init`?this.pendingInit=null:this.pendingShutdown=null,r.reject(n))}toError(e,t){return e instanceof Error?e:Error(`${t}: ${String(e)}`)}};let u=null;async function d(){return u||(u=await import(`@huggingface/transformers`),u.env.cacheDir=i(c(),`.cache`,`huggingface`,`transformers-js`)),u}var f=class{pipe=null;shutdownPromise=null;dimensions;modelId;nativeDim;queryPrefix;threadConfig;constructor(e){if(this.modelId=e?.model??o.model,this.nativeDim=e?.nativeDim??1024,this.dimensions=e?.dimensions??o.dimensions,this.dimensions>this.nativeDim)throw Error(`Configured dimensions (${this.dimensions}) exceeds model native output (${this.nativeDim}). Matryoshka truncation cannot upscale — dimensions must be <= nativeDim.`);this.queryPrefix=e?.queryPrefix??this.detectQueryPrefix(this.modelId),this.threadConfig={interOp:e?.interOpNumThreads??1,intraOp:e?.intraOpNumThreads??4}}getPipelineOptions(e){let t=e.backends.onnx;t.wasm||={};let n=t.wasm;return n.numThreads=this.threadConfig.intraOp,{dtype:`q8`,session_options:{interOpNumThreads:this.threadConfig.interOp,intraOpNumThreads:this.threadConfig.intraOp}}}computeNorm(e){let t=0;for(let n=0;n<e.length;n++)t+=e[n]*e[n];return Math.sqrt(t)}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim){let t=this.computeNorm(e);if(!Number.isFinite(t))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(t===0)throw Error(`Embedding produced zero-norm vector from ONNX output`);return e}let t=e.subarray(0,this.dimensions),n=this.computeNorm(t);if(!Number.isFinite(n))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(n===0)throw Error(`Embedding produced zero-norm vector after truncation — input may be degenerate`);let r=new Float32Array(this.dimensions);for(let e=0;e<this.dimensions;e++)r[e]=t[e]/n;return r}detectQueryPrefix(e){let t=e.toLowerCase();return t.includes(`bge`)||t.includes(`mxbai-embed`)?`Represent this sentence for searching relevant passages: `:t.includes(`/e5-`)||t.includes(`multilingual-e5`)?`query: `:``}async initialize(){if(this.pipe)return;this.shutdownPromise=null;let{pipeline:e,env:t}=await d();try{this.pipe=await e(`feature-extraction`,this.modelId,this.getPipelineOptions(t))}catch(n){let r=n.message?.toLowerCase()??``;if(this.isCorruptionError(r)){let n=i(t.cacheDir??i(c(),`.cache`,`huggingface`,`transformers-js`),this.modelId);console.error(`[aikit:auto-heal] Detected corrupted model cache for "${this.modelId}". Clearing cache at ${n} and retrying download...`);try{await s(n,{recursive:!0,force:!0})}catch{}try{this.pipe=await e(`feature-extraction`,this.modelId,this.getPipelineOptions(t)),console.error(`[aikit:auto-heal] Model "${this.modelId}" re-downloaded successfully.`);return}catch(e){throw Error(`Failed to initialize embedding model "${this.modelId}" after auto-heal: ${e.message}`)}}throw Error(`Failed to initialize embedding model "${this.modelId}": ${n.message}`)}}isCorruptionError(e){return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`checksum`,`corrupt`,`could not load`,`onnx`,`malformed`].some(t=>e.includes(t))}async shutdown(){return this.shutdownPromise||=this._doShutdown(),this.shutdownPromise}async _doShutdown(){let e=this.pipe;if(e)try{let t=e;typeof t.dispose==`function`?await t.dispose():typeof t.model?.dispose==`function`&&await t.model.dispose()}catch{}finally{this.pipe=null}}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t?.data)throw Error(`Embedding pipeline returned no output`);try{let e=new Float32Array(t.data);return this.truncateAndRenorm(e)}finally{t.dispose?.()}}async embedQuery(e){return this.embed(this.queryPrefix+e)}async embedBatch(e,t=64){if(e.length===0)return[];this.pipe||await this.initialize();let n=[];for(let r=0;r<e.length;r+=t){let i=e.slice(r,r+t),a=await this.pipe?.(i,{pooling:`mean`,normalize:!0});if(!a?.data)throw Error(`Embedding pipeline returned no output`);try{if(i.length===1){let e=new Float32Array(a.data);n.push(this.truncateAndRenorm(e))}else for(let e=0;e<i.length;e++){let t=e*this.nativeDim,r=a.data.slice(t,t+this.nativeDim);n.push(this.truncateAndRenorm(new Float32Array(r)))}}finally{a.dispose?.()}}return n}};export{l as EmbedderProxy,f as OnnxEmbedder};
1
+ import{fork as e}from"node:child_process";import{randomUUID as t}from"node:crypto";import{existsSync as n}from"node:fs";import{dirname as r,join as i}from"node:path";import{fileURLToPath as a}from"node:url";import{EMBEDDING_DEFAULTS as o}from"../../core/dist/index.js";import{rm as s}from"node:fs/promises";import{homedir as c}from"node:os";var l=class{options;logger;maxRetries;retryBaseDelayMs;workerAvailable=!0;workerPath=i(r(a(import.meta.url)),`embedder-worker.js`);pendingRequests=new Map;childState=new WeakMap;child=null;readyChild=null;pendingInit=null;pendingShutdown=null;initializePromise=null;shutdownPromise=null;currentDimensions;currentModelId;constructor(e={}){this.options=e,this.logger=e.logger,this.maxRetries=Math.max(0,e.maxRetries??3),this.retryBaseDelayMs=Math.max(0,e.retryBaseDelayMs??500),this.currentDimensions=e.dimensions??o.dimensions,this.currentModelId=e.model??o.model}get dimensions(){return this.currentDimensions}get modelId(){return this.currentModelId}async initialize(){if(!(this.readyChild&&this.child===this.readyChild)&&this.workerAvailable){if(!n(this.workerPath)){this.workerAvailable=!1,console.warn(`[aikit] Embedder worker not found at ${this.workerPath}. Embedding disabled - search will use keyword matching only. This usually means the npx cache is corrupted; restart to fix.`);return}if(this.initializePromise)return this.initializePromise;if(this.shutdownPromise){try{await this.shutdownPromise}catch{}if(this.readyChild&&this.child===this.readyChild)return}return this.initializePromise=this.startWorker().finally(()=>{this.initializePromise=null}),this.initializePromise}}async embed(e){if(!this.workerAvailable||(await this.initialize(),!this.workerAvailable))throw Error(`Embedding worker is not available — embeddings cannot be computed. Check server logs for initialization errors.`);return this.sendVectorRequestWithRetry({type:`embed`,text:e})}async embedQuery(e){if(!this.workerAvailable||(await this.initialize(),!this.workerAvailable))throw Error(`Embedding worker is not available — embeddings cannot be computed. Check server logs for initialization errors.`);return this.sendVectorRequestWithRetry({type:`embedQuery`,text:e})}async embedBatch(e,t){if(e.length===0)return[];if(!this.workerAvailable||(await this.initialize(),!this.workerAvailable))throw Error(`Embedding worker is not available — embeddings cannot be computed. Check server logs for initialization errors.`);return this.withWorkerExitRetry(`embedBatch`,()=>this.sendBatchRequest(e,t))}async sendBatchRequest(e,n){await this.initialize();let r=this.requireReadyChild(),i=t(),a=new Promise((e,t)=>{this.pendingRequests.set(i,{child:r,resolve:t=>e(t),reject:t})});try{r.send({type:`embedBatch`,id:i,texts:e,batchSize:n})}catch(e){throw this.pendingRequests.delete(i),this.toError(e,`Failed to send embedBatch request to worker`)}return a}async shutdown(){if(this.shutdownPromise)return this.shutdownPromise;let e=this.child;if(!e)return;let t=this.requireChildState(e);t.shutdownRequested=!0,this.readyChild===e&&(this.readyChild=null),this.shutdownPromise=new Promise((t,n)=>{this.pendingShutdown={child:e,resolve:t,reject:n}}).finally(()=>{this.shutdownPromise=null});try{e.send({type:`shutdown`})}catch(t){let n=this.toError(t,`Failed to send shutdown request to worker`);throw this.clearChildReference(e),this.rejectPendingForChild(e,n),this.rejectLifecycleIfOwned(`shutdown`,e,n),n}return this.shutdownPromise}async startWorker(){this.child&&this.readyChild!==this.child&&(this.child=null);let e=this.spawnChild();this.child=e,this.readyChild=null;let t=new Promise((t,n)=>{this.pendingInit={child:e,resolve:t,reject:n}});try{e.send({type:`init`,config:this.buildInitConfig()})}catch(t){let n=this.toError(t,`Failed to send init request to worker`);throw this.pendingInit=null,this.clearChildReference(e),n}return t}spawnChild(){let t=e(this.workerPath,[],{env:this.buildChildEnv()});return this.childState.set(t,{idleExitNotified:!1,shutdownRequested:!1,terminated:!1}),t.on(`message`,e=>{this.handleChildMessage(t,e)}),t.once(`error`,e=>{this.handleChildFailure(t,this.toError(e,`Embedder worker failed`))}),t.once(`exit`,(e,n)=>{this.handleChildExit(t,e,n)}),t}handleChildMessage(e,t){switch(t.type){case`ready`:{this.currentDimensions=t.dimensions,this.currentModelId=t.modelId,this.child===e&&(this.readyChild=e);let n=this.pendingInit;n?.child===e&&(this.pendingInit=null,n.resolve());return}case`result`:{let n=this.pendingRequests.get(t.id);if(!n||n.child!==e)return;this.pendingRequests.delete(t.id),n.resolve(new Float32Array(t.data));return}case`batchResult`:{let n=this.pendingRequests.get(t.id);if(!n||n.child!==e)return;if(this.pendingRequests.delete(t.id),!t.data||!Array.isArray(t.data)||t.data.length===0)n.reject(Error(`Worker returned empty or invalid batch result`));else{let e=t.data.map(e=>new Float32Array(e)),r=e.findIndex(e=>e.length===0);r>=0?n.reject(Error(`Worker returned zero-length vector at index ${r}`)):n.resolve(e)}return}case`error`:{let n=Error(t.message);if(t.id===`init`){this.clearChildReference(e),this.rejectLifecycleIfOwned(`init`,e,n);return}if(t.id===`shutdown`){this.rejectLifecycleIfOwned(`shutdown`,e,n);return}let r=this.pendingRequests.get(t.id);if(!r||r.child!==e)return;this.pendingRequests.delete(t.id),r.reject(n);return}case`idle-exit`:{let t=this.requireChildState(e);t.idleExitNotified=!0,this.clearChildReference(e);return}}}handleChildExit(e,t,n){let r=this.requireChildState(e);if(r.terminated)return;r.terminated=!0,this.clearChildReference(e);let i=r.shutdownRequested||r.idleExitNotified,a=Error(i?`Embedder worker exited before completing request`:`Embedder worker exited unexpectedly (code ${t??`null`}${n?`, signal ${n}`:``})`);this.rejectLifecycleIfOwned(`init`,e,a),i?this.resolveLifecycleIfOwned(`shutdown`,e):this.rejectLifecycleIfOwned(`shutdown`,e,a),this.rejectPendingForChild(e,a)}handleChildFailure(e,t){let n=this.requireChildState(e);n.terminated||(n.terminated=!0,this.clearChildReference(e),this.rejectLifecycleIfOwned(`init`,e,t),this.rejectLifecycleIfOwned(`shutdown`,e,t),this.rejectPendingForChild(e,t))}async sendVectorRequestWithRetry(e){return this.withWorkerExitRetry(e.type,()=>this.sendVectorRequest(e))}async sendVectorRequest(e){await this.initialize();let n=this.requireReadyChild(),r=t(),i=new Promise((e,t)=>{this.pendingRequests.set(r,{child:n,resolve:t=>e(t),reject:t})});try{n.send({...e,id:r})}catch(t){throw this.pendingRequests.delete(r),this.toError(t,`Failed to send ${e.type} request to worker`)}return i}async withWorkerExitRetry(e,t){let n=null;for(let r=0;r<=this.maxRetries;r++)try{return await t()}catch(t){let i=this.toError(t,`Failed to process ${e} request`);if(!this.isWorkerExitError(i))throw i;if(n??=i,r===this.maxRetries)throw n;let a=r+1,o=this.retryBaseDelayMs*2**r;this.logger?.warn?.(`Embedder retry ${a}/${this.maxRetries} after ${o}ms`,{requestType:e,delayMs:o,error:i.message}),this.child=null,this.readyChild=null,await this.wait(o)}throw n??Error(`Failed to process ${e} request`)}isWorkerExitError(e){return/embedder worker exited/i.test(e.message)}wait(e){return new Promise(t=>{setTimeout(t,e)})}requireReadyChild(){if(!this.child||this.readyChild!==this.child)throw Error(`Embedder worker is not initialized`);return this.child}buildInitConfig(){return{model:this.options.model,dimensions:this.options.dimensions,nativeDim:this.options.nativeDim,queryPrefix:this.options.queryPrefix,interOpNumThreads:this.options.interOpNumThreads,intraOpNumThreads:this.options.intraOpNumThreads}}buildChildEnv(){return this.options.idleTimeoutMs===void 0?process.env:{...process.env,AIKIT_EMBED_IDLE_MS:String(this.options.idleTimeoutMs)}}requireChildState(e){let t=this.childState.get(e);if(!t)throw Error(`Embedder worker state not found`);return t}clearChildReference(e){this.child===e&&(this.child=null),this.readyChild===e&&(this.readyChild=null)}rejectPendingForChild(e,t){for(let[n,r]of this.pendingRequests)r.child===e&&(this.pendingRequests.delete(n),r.reject(t))}resolveLifecycleIfOwned(e,t){let n=this.pendingShutdown;!n||n.child!==t||(this.pendingShutdown=null,n.resolve())}rejectLifecycleIfOwned(e,t,n){let r=e===`init`?this.pendingInit:this.pendingShutdown;!r||r.child!==t||(e===`init`?this.pendingInit=null:this.pendingShutdown=null,r.reject(n))}toError(e,t){return e instanceof Error?e:Error(`${t}: ${String(e)}`)}};let u=null;async function d(){if(!u){try{u=await import(`@huggingface/transformers`)}catch(e){if(e instanceof Error&&e.message.includes(`Cannot find module`)){let{createRequire:e}=await import(`node:module`);u=e(import.meta.url)(`@huggingface/transformers`)}else throw e}u.env.cacheDir=i(c(),`.cache`,`huggingface`,`transformers-js`)}return u}var f=class{pipe=null;shutdownPromise=null;dimensions;modelId;nativeDim;queryPrefix;threadConfig;constructor(e){if(this.modelId=e?.model??o.model,this.nativeDim=e?.nativeDim??1024,this.dimensions=e?.dimensions??o.dimensions,this.dimensions>this.nativeDim)throw Error(`Configured dimensions (${this.dimensions}) exceeds model native output (${this.nativeDim}). Matryoshka truncation cannot upscale — dimensions must be <= nativeDim.`);this.queryPrefix=e?.queryPrefix??this.detectQueryPrefix(this.modelId),this.threadConfig={interOp:e?.interOpNumThreads??1,intraOp:e?.intraOpNumThreads??4}}getPipelineOptions(e){let t=e.backends.onnx;t.wasm||={};let n=t.wasm;return n.numThreads=this.threadConfig.intraOp,{dtype:`q8`,session_options:{interOpNumThreads:this.threadConfig.interOp,intraOpNumThreads:this.threadConfig.intraOp}}}computeNorm(e){let t=0;for(let n=0;n<e.length;n++)t+=e[n]*e[n];return Math.sqrt(t)}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim){let t=this.computeNorm(e);if(!Number.isFinite(t))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(t===0)throw Error(`Embedding produced zero-norm vector from ONNX output`);return e}let t=e.subarray(0,this.dimensions),n=this.computeNorm(t);if(!Number.isFinite(n))throw Error(`Embedding produced non-finite norm — output contained NaN or Infinity`);if(n===0)throw Error(`Embedding produced zero-norm vector after truncation — input may be degenerate`);let r=new Float32Array(this.dimensions);for(let e=0;e<this.dimensions;e++)r[e]=t[e]/n;return r}detectQueryPrefix(e){let t=e.toLowerCase();return t.includes(`bge`)||t.includes(`mxbai-embed`)?`Represent this sentence for searching relevant passages: `:t.includes(`/e5-`)||t.includes(`multilingual-e5`)?`query: `:``}async initialize(){if(this.pipe)return;this.shutdownPromise=null;let{pipeline:e,env:t}=await d();try{this.pipe=await e(`feature-extraction`,this.modelId,this.getPipelineOptions(t))}catch(n){let r=n.message?.toLowerCase()??``;if(this.isCorruptionError(r)){let n=i(t.cacheDir??i(c(),`.cache`,`huggingface`,`transformers-js`),this.modelId);console.error(`[aikit:auto-heal] Detected corrupted model cache for "${this.modelId}". Clearing cache at ${n} and retrying download...`);try{await s(n,{recursive:!0,force:!0})}catch{}try{this.pipe=await e(`feature-extraction`,this.modelId,this.getPipelineOptions(t)),console.error(`[aikit:auto-heal] Model "${this.modelId}" re-downloaded successfully.`);return}catch(e){throw Error(`Failed to initialize embedding model "${this.modelId}" after auto-heal: ${e.message}`)}}throw Error(`Failed to initialize embedding model "${this.modelId}": ${n.message}`)}}isCorruptionError(e){return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`checksum`,`corrupt`,`could not load`,`onnx`,`malformed`].some(t=>e.includes(t))}async shutdown(){return this.shutdownPromise||=this._doShutdown(),this.shutdownPromise}async _doShutdown(){let e=this.pipe;if(e)try{let t=e;typeof t.dispose==`function`?await t.dispose():typeof t.model?.dispose==`function`&&await t.model.dispose()}catch{}finally{this.pipe=null}}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t?.data)throw Error(`Embedding pipeline returned no output`);try{let e=new Float32Array(t.data);return this.truncateAndRenorm(e)}finally{t.dispose?.()}}async embedQuery(e){return this.embed(this.queryPrefix+e)}async embedBatch(e,t=64){if(e.length===0)return[];this.pipe||await this.initialize();let n=[];for(let r=0;r<e.length;r+=t){let i=e.slice(r,r+t),a=await this.pipe?.(i,{pooling:`mean`,normalize:!0});if(!a?.data)throw Error(`Embedding pipeline returned no output`);try{if(i.length===1){let e=new Float32Array(a.data);n.push(this.truncateAndRenorm(e))}else for(let e=0;e<i.length;e++){let t=e*this.nativeDim,r=a.data.slice(t,t+this.nativeDim);n.push(this.truncateAndRenorm(new Float32Array(r)))}}finally{a.dispose?.()}}return n}};export{l as EmbedderProxy,f as OnnxEmbedder};
@@ -1 +1 @@
1
- import{createHash as e}from"node:crypto";import{existsSync as t,readFileSync as n,realpathSync as r,statSync as i,writeFileSync as a}from"node:fs";import{lstat as o,readFile as s,readdir as c,stat as l}from"node:fs/promises";import{dirname as u,extname as d,join as f,relative as p,resolve as m}from"node:path";import{AIKIT_PATHS as h,FILE_LIMITS as g,createLogger as _,detectContentType as v,serializeError as y}from"../../core/dist/index.js";import{minimatch as b}from"minimatch";import{availableParallelism as x,loadavg as S}from"node:os";import{createChunkerSync as C}from"../../chunker/dist/index.js";function w(t){return e(`sha256`).update(t).digest(`hex`).slice(0,16)}function T(t,n){let r=`${t}:${n}`;return e(`sha256`).update(r).digest(`hex`).slice(0,16)}const E=_(`indexer`);var D=class e{static BINARY_EXTENSIONS=new Set(`.node,.so,.dylib,.dll,.wasm,.bin,.exe,.png,.jpg,.jpeg,.gif,.bmp,.ico,.webp,.svg,.mp3,.mp4,.wav,.avi,.mov,.flac,.zip,.gz,.tar,.bz2,.7z,.rar,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.ttf,.otf,.woff,.woff2,.eot,.pyc,.class,.o,.obj,.a,.lib`.split(`,`));async crawl(e){let t=[],n=new Set;return await this.walkDir(e.rootDir,e.rootDir,e.excludePatterns,t,n),t}async walkDir(t,n,i,a,u){let m;try{m=await c(t,{withFileTypes:!0})}catch(e){let n=e.code;(n===`EACCES`||n===`EPERM`)&&E.warn(`Permission denied, skipping directory`,{dir:t});return}for(let c of m){let m=f(t,c.name),_=p(n,m).replace(/\\/g,`/`);if(!this.isExcluded(_,i)){if(c.isDirectory()){if(c.name.startsWith(`.`)&&!(c.name===h.ai.slice(1)&&_.startsWith(h.ai)))continue;try{if((await o(m)).isSymbolicLink())continue}catch{continue}let e;try{e=r(m)}catch{continue}if(u.has(e))continue;u.add(e),await this.walkDir(m,n,i,a,u)}else if(c.isFile()){let t=d(c.name).toLowerCase();if(e.BINARY_EXTENSIONS.has(t))continue;try{if((await l(m)).size>g.maxFileSizeBytes)continue;let e=await s(m,`utf-8`);if(e.includes(`\0`))continue;a.push({relativePath:_,absolutePath:m,content:e,extension:t})}catch{}}}}}isExcluded(e,t){return t.some(t=>b(e,t,{dot:!0}))}};const O=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`]),k=[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!0},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:`class`,exported:!0},{pattern:/^export\s+interface\s+(\w+)/gm,kind:`interface`,exported:!0},{pattern:/^export\s+type\s+(\w+)/gm,kind:`type`,exported:!0},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:`const`,exported:!0},{pattern:/^export\s+enum\s+(\w+)/gm,kind:`enum`,exported:!0},{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!1},{pattern:/^class\s+(\w+)/gm,kind:`class`,exported:!1},{pattern:/^interface\s+(\w+)/gm,kind:`interface`,exported:!1},{pattern:/^type\s+(\w+)/gm,kind:`type`,exported:!1},{pattern:/^enum\s+(\w+)/gm,kind:`enum`,exported:!1}],A=[/import\s+(?:(?:type\s+)?(?:(?:\{[^}]*\}|[\w*]+)\s+from\s+)?)['"]([^'"]+)['"]/g,/import\(\s*['"]([^'"]+)['"]\s*\)/g,/require\(\s*['"]([^'"]+)['"]\s*\)/g];function j(t,n,r){return e(`sha256`).update(`${t}:${n}:${r}`).digest(`hex`).slice(0,16)}function M(t,n,r){return e(`sha256`).update(`${t}-${r}-${n}`).digest(`hex`).slice(0,16)}function N(e,t){return f(u(t),e).replace(/\\/g,`/`).replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function P(e){return e.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function F(e,t,n){let r=d(t).toLowerCase();if(!O.has(r))return{nodes:[],edges:[]};let i=[],a=[],o=new Date().toISOString(),s=new Set,c=P(t),l=j(`module`,c,c);i.push({id:l,type:`module`,name:t,properties:{ext:r},sourcePath:t,createdAt:o});for(let{pattern:n,kind:r,exported:c}of k){let u=new RegExp(n.source,n.flags),d;for(;(d=u.exec(e))!==null;){let e=d[1],n=`${r}:${e}`;if(s.has(n))continue;s.add(n);let u=j(r,e,t);i.push({id:u,type:r,name:e,properties:{exported:c},sourcePath:t,createdAt:o}),a.push({id:M(l,u,`defines`),fromId:l,toId:u,type:`defines`,weight:c?1:.5})}}let u=n?.workspacePackages,f=new Set;for(let n of A){let r=new RegExp(n.source,n.flags),i;for(;(i=r.exec(e))!==null;){let e=i[1];if(f.has(e))continue;let n;if(e.startsWith(`.`))n=N(e,t);else if(u){let t=e.startsWith(`@`)?e.split(`/`).slice(0,2).join(`/`):e.split(`/`)[0],r=u.get(t);if(!r)continue;n=r}else continue;f.add(e);let r=P(n),o=j(`module`,r,r);a.push({id:M(l,o,`imports`),fromId:l,toId:o,type:`imports`,properties:{source:e}})}}return{nodes:i,edges:a}}const I=_(`hash-cache`);var L=class{cache;filePath;dirty=!1;constructor(e){this.filePath=m(e,`file-hashes.json`),this.cache=new Map}load(){if(t(this.filePath))try{let e=n(this.filePath,`utf-8`),t=JSON.parse(e);this.cache=new Map(Object.entries(t)),I.info(`Hash cache loaded`,{entries:this.cache.size})}catch(e){I.warn(`Hash cache load failed, starting fresh`,{err:e}),this.cache=new Map}}get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t),this.dirty=!0}delete(e){this.cache.delete(e)&&(this.dirty=!0)}flush(){if(this.dirty)try{let e={};for(let[t,n]of this.cache)e[t]=n;a(this.filePath,JSON.stringify(e),`utf-8`),this.dirty=!1}catch(e){I.warn(`Hash cache flush failed`,{err:e})}}clear(){this.cache.clear(),this.dirty=!0,this.flush()}get size(){return this.cache.size}};const R=_(`indexer`),z=()=>new Promise(e=>setImmediate(e));async function B(e,t,n,r){let i=0;async function a(){for(;i<e.length;){let n=i++;try{await t(e[n])}catch(t){r?.(e[n],t)}n%10==0&&await z()}}await Promise.all(Array.from({length:Math.min(n,e.length)},()=>a()))}function V(e){let t=x(),n=S()[0]/t;return n>1.5?2:n>1?Math.max(2,Math.floor(e/2)):e}const H=Math.max(2,Math.min(4,Math.floor(x()*.5)));var U=class{embedder;store;crawler;indexing=!1;graphStore;hashCache;get isIndexing(){return this.indexing}constructor(e,t){this.embedder=e,this.store=t,this.crawler=new D}normalizeChunkText(e){return e.replace(/^\/\/ File: [^\n]*\n?/,``).toLowerCase().replace(/\s+/g,` `).trim()}setGraphStore(e){this.graphStore=e}setHashCache(e){this.hashCache=e}async index(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndex(e,t,{})}finally{this.indexing=!1}}async getChangedFiles(e){let t=e.indexing.concurrency??H,n=await this.crawlSources(e),{filesToProcess:r}=await this.planIndexWork(n,t,{});return r.map(e=>e.relativePath)}async indexFiles(e,t,n){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndexFiles(e,t,n)}finally{this.indexing=!1}}async doIndex(e,t,n={}){let r=Date.now(),i=e.indexing.concurrency??H;t?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let a=await this.crawlSources(e),{filesToProcess:o,filesSkipped:s,pathsToRemove:c}=await this.planIndexWork(a,i,{skipHashCheck:n.skipHashCheck}),{filesProcessed:l,chunksCreated:u,chunksDeduped:d}=await this.processFiles(a,o,i,t,{graphCleared:n.graphCleared}),f=await this.cleanupRemovedFiles(c,i,o.length,l,u,t);return this.hashCache?.flush(),t?.({phase:`done`,filesTotal:o.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:s,chunksCreated:u,chunksDeduped:d,filesRemoved:f,durationMs:Date.now()-r}}async doIndexFiles(e,t,n){let r=Date.now(),i=e.indexing.concurrency??H,a=new Set(t);if(a.size===0)return{filesProcessed:0,filesSkipped:0,chunksCreated:0,chunksDeduped:0,filesRemoved:0,durationMs:Date.now()-r};n?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let o=await this.crawlSources(e),{filesToProcess:s,filesSkipped:c}=await this.planIndexWork(o,i,{requestedPaths:a}),{filesProcessed:l,chunksCreated:u,chunksDeduped:d}=await this.processFiles(o,s,i,n,{});return this.hashCache?.flush(),n?.({phase:`done`,filesTotal:s.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:c,chunksCreated:u,chunksDeduped:d,filesRemoved:0,durationMs:Date.now()-r}}async crawlSources(e){return(await Promise.all(e.sources.map(e=>this.crawler.crawl({rootDir:e.path,excludePatterns:e.excludePatterns})))).flat()}async planIndexWork(e,t,n){let r=n.requestedPaths,i;if(r){let t=e=>e.replace(/\\/g,`/`).toLowerCase(),n=new Set([...r].map(t));i=e.filter(e=>n.has(t(e.relativePath))||n.has(t(e.absolutePath)))}else i=e;if(n.skipHashCheck)return{filesToProcess:i,filesSkipped:0,pathsToRemove:[]};let a=r?[]:await this.getPathsToRemove(e),o=0,s=[];return await B(i,async e=>{let t=w(e.content);if(this.hashCache){if(this.hashCache.get(e.relativePath)===t){o++;return}}else{let n=await this.store.getBySourcePath(e.relativePath);if(n.length>0&&n[0].fileHash===t){o++;return}}s.push(e)},V(t),(e,t)=>R.error(`Hash check failed`,{sourcePath:e.relativePath,...y(t)})),{filesToProcess:s,filesSkipped:o,pathsToRemove:a}}async getPathsToRemove(e){let t=await this.store.listSourcePaths(),n=new Set(e.map(e=>e.relativePath));return t.filter(e=>!n.has(e)&&!e.startsWith(`${h.aiCurated}/`))}async buildWorkspacePackageMap(e){let t=new Map;for(let n of e)if(n.relativePath.endsWith(`package.json`))try{let e=JSON.parse(n.content);if(typeof e.name!=`string`||e.name.length===0)continue;let r=n.relativePath===`package.json`?``:n.relativePath.replace(/\/package\.json$/,``),i=``;if(typeof e.exports==`string`)i=e.exports;else if(e.exports&&typeof e.exports==`object`){let t=e.exports,n=t[`.`]??t;if(typeof n==`string`)i=n;else if(n&&typeof n==`object`){let e=n,t=e.import??e.module??e.default??e.require;typeof t==`string`&&(i=t)}}!i&&typeof e.module==`string`&&(i=e.module),!i&&typeof e.main==`string`&&(i=e.main);let a=i.replace(/^\.\//,``).replace(/^dist\//,`src/`).replace(/\.(ts|js|mjs|cjs|tsx|jsx)$/,``),o=a?r?`${r}/${a}`:a:r?`${r}/src/index`:`src/index`;t.set(e.name,o)}catch{}return t}async processFiles(t,n,r,i,a={}){let o=0,s=0,c=0,l=n.length,u=this.graphStore?await this.buildWorkspacePackageMap(t):void 0,d=new Map,f=[],p=[],m=0,h=[],g=[],_=new Map,b=0,x=async()=>{if(h.length===0)return;let e=h,t=g,n=_;h=[],g=[],_=new Map,b=0;try{await this.store.upsert(e,t);for(let[e,t]of n)this.hashCache?.set(e,t)}catch(r){h.push(...e),g.push(...t);for(let[e,t]of n)_.set(e,t);throw r}},S=async()=>{if(this.graphStore){try{f.length>0&&await this.graphStore.upsertNodes(f),p.length>0&&await this.graphStore.upsertEdges(p)}catch(e){R.warn(`Graph batch flush failed`,y(e))}f=[],p=[],m=0}};return await B(n,async t=>{i?.({phase:`chunking`,filesTotal:l,filesProcessed:o,chunksTotal:s,chunksProcessed:s,currentFile:t.relativePath});let n=v(t.relativePath),r=C(t.extension).chunk(t.content,{sourcePath:t.relativePath,contentType:n});if(r.length===0)return;let E=w(t.content),D=new Date().toISOString(),O=(e,n,r)=>({id:T(t.relativePath,n),content:e.text,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:E,contentHash:r,indexedAt:D,origin:`indexed`,tags:[],version:1}),k=[],A=[];for(let t=0;t<r.length;t++){let n=r[t],i=e(`sha256`).update(this.normalizeChunkText(n.text)).digest(`hex`),a=O(n,t,i),o=d.get(i);if(o&&this.store.upsertWithoutVector){A.push({record:a,sourceRecordId:o}),c++;continue}d.set(i,a.id),k.push({chunk:n,record:a})}i?.({phase:`embedding`,filesTotal:l,filesProcessed:o,chunksTotal:s+r.length,chunksProcessed:s,currentFile:t.relativePath});let j=k.length>0?await this.embedder.embedBatch(k.map(({chunk:e})=>e.text)):[],M=k.map(({record:e})=>e);if(i?.({phase:`storing`,filesTotal:l,filesProcessed:o,chunksTotal:s+r.length,chunksProcessed:s,currentFile:t.relativePath}),M.length>0&&(h.push(...M),g.push(...j),_.set(t.relativePath,E),b++,b>=20&&await x()),A.length>0&&h.length>0&&await x(),this.store.upsertWithoutVector)for(let{record:e,sourceRecordId:t}of A)await this.store.upsertWithoutVector(e,t);if(M.length===0&&A.length>0&&this.hashCache?.set(t.relativePath,E),this.graphStore)try{a.graphCleared||await this.graphStore.deleteBySourcePath(t.relativePath);let e=F(t.content,t.relativePath,{workspacePackages:u});e.nodes.length>0&&f.push(...e.nodes),e.edges.length>0&&p.push(...e.edges),m++,m>=50&&await S()}catch(e){R.warn(`Graph extraction failed`,{sourcePath:t.relativePath,...y(e)})}o++,s+=r.length},V(r),(e,t)=>R.error(`Processing failed`,{sourcePath:e.relativePath,...y(t)})),await x(),await S(),{filesProcessed:o,chunksCreated:s,chunksDeduped:c}}async cleanupRemovedFiles(e,t,n,r,i,a){if(e.length===0)return 0;let o=0;return a?.({phase:`cleanup`,filesTotal:n,filesProcessed:r,chunksTotal:i,chunksProcessed:i}),await B(e,async e=>{await this.store.deleteBySourcePath(e),this.hashCache?.delete(e),this.graphStore&&await this.graphStore.deleteBySourcePath(e).catch(t=>R.warn(`Graph cleanup failed`,{sourcePath:e,...y(t)})),o++},V(t),(e,t)=>R.error(`Cleanup failed`,{sourcePath:e,...y(t)})),o}async reindexAll(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{if(await this.store.dropTable(),this.graphStore)try{let e=await this.graphStore.getStats();e.nodeCount>0&&(await this.graphStore.clear(),R.info(`Graph store cleared`,{nodeCount:e.nodeCount,edgeCount:e.edgeCount}))}catch(e){R.warn(`Graph store clear failed`,y(e))}return await this.doReindex(e,t)}catch(e){throw this.indexing=!1,e}}async doReindex(e,t){try{return await this.doIndex(e,t,{skipHashCheck:!0,graphCleared:!0})}finally{this.indexing=!1}}async getStats(){return this.store.getStats()}};const W=_(`smart-index`),G=1.5;var K=class{indexer;config;store;trickleTimer=null;stopped=!1;trickleIntervalMs;batchSize;priorityQueue=[];changedFiles=[];lastRefreshTime=0;refreshing=!1;constructor(e,t,n){this.indexer=e,this.config=t,this.store=n,this.trickleIntervalMs=t.indexing.trickleIntervalMs??this.readPositiveIntEnv(`AIKIT_SMART_TRICKLE_MS`,3e4),this.batchSize=t.indexing.trickleBatchSize??this.readPositiveIntEnv(`AIKIT_SMART_BATCH_SIZE`,1)}start(){this.trickleTimer&&=(clearTimeout(this.trickleTimer),null),this.stopped=!1,W.info(`Smart index scheduler started (trickle mode)`,{intervalMs:this.trickleIntervalMs,batchSize:this.batchSize}),this.scheduleTick()}stop(){this.stopped=!0,this.trickleTimer&&=(clearTimeout(this.trickleTimer),null)}prioritize(...e){let t=[...new Set(e.filter(Boolean))].filter(e=>{try{return!i(e).isDirectory()}catch{return W.debug(`Skipping non-existent path`,{path:e}),!1}});for(let e of t){let t=this.priorityQueue.indexOf(e);t>=0&&this.priorityQueue.splice(t,1)}for(let e of t.reverse())this.priorityQueue.unshift(e);this.priorityQueue.length>500&&(this.priorityQueue.length=500),t.length>0&&W.info(`Files prioritized for trickle indexing`,{added:t.length,queued:this.priorityQueue.length})}getState(){return{mode:`smart`,queueSize:this.priorityQueue.length,changedFilesSize:this.changedFiles.length,intervalMs:this.trickleIntervalMs,batchSize:this.batchSize,running:this.trickleTimer!==null}}readPositiveIntEnv(e,t){let n=Number(process.env[e]);return Number.isFinite(n)&&n>0?n:t}scheduleTick(){this.trickleTimer=setTimeout(()=>void this.tick(),this.trickleIntervalMs),this.trickleTimer.unref&&this.trickleTimer.unref()}async tick(){if(!this.stopped)try{if(this.indexer.isIndexing){W.info(`Skipping trickle tick — indexing already in progress`);return}let e=this.getCpuCount(),t=S()[0];if(e>0&&t/e>G){W.info(`Skipping trickle tick — system load too high`,{load:t.toFixed(2),cpuCount:e,threshold:G});return}let n=await this.pickFiles();if(n.length===0){await this.maybeRefreshChangedFiles();return}W.info(`Trickle indexing tick started`,{count:n.length,files:n});let r=await this.indexer.indexFiles(this.config,n);if(this.store)try{await this.store.createFtsIndex()}catch(e){W.warn(`FTS index rebuild failed after trickle tick`,{error:String(e)})}this.changedFiles=this.changedFiles.filter(e=>!n.includes(e)),W.info(`Trickle indexing tick complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated})}catch(e){let t=String(e);if(t.includes(`not initialized`)||t.includes(`has been closed`)){W.warn(`Store closed — stopping smart index scheduler`,{error:t}),this.stop();return}W.error(`Trickle indexing tick failed`,{error:t})}finally{this.stopped||this.scheduleTick()}}getCpuCount(){try{return typeof x==`function`?x():4}catch{return 4}}async pickFiles(){let e=[];for(;e.length<this.batchSize&&this.priorityQueue.length>0;){let t=this.priorityQueue.shift();t&&!e.includes(t)&&e.push(t)}if(e.length<this.batchSize)for(await this.maybeRefreshChangedFiles();e.length<this.batchSize&&this.changedFiles.length>0;){let t=this.changedFiles.shift();t&&!e.includes(t)&&e.push(t)}return e}async maybeRefreshChangedFiles(){let e=Date.now();if(!(this.refreshing||this.changedFiles.length>0&&e-this.lastRefreshTime<6e5)){this.refreshing=!0;try{this.changedFiles=await this.indexer.getChangedFiles(this.config),this.lastRefreshTime=e,this.changedFiles.length>0&&W.info(`Refreshed changed files for trickle indexing`,{count:this.changedFiles.length})}catch(e){let t=String(e);if(t.includes(`not initialized`)||t.includes(`has been closed`)){W.warn(`Store closed — stopping smart index scheduler`,{error:t}),this.stop();return}W.error(`Failed to refresh changed files for trickle indexing`,{error:t})}finally{this.refreshing=!1}}}};export{L as FileHashCache,D as FilesystemCrawler,U as IncrementalIndexer,K as SmartIndexScheduler,F as extractGraph,T as generateRecordId,w as hashContent};
1
+ import{createHash as e}from"node:crypto";import{existsSync as t,readFileSync as n,realpathSync as r,statSync as i,writeFileSync as a}from"node:fs";import{lstat as o,readFile as s,readdir as c,stat as l}from"node:fs/promises";import{dirname as u,extname as d,join as f,relative as p,resolve as m}from"node:path";import{AIKIT_PATHS as h,FILE_LIMITS as g,createLogger as _,detectContentType as v,serializeError as y}from"../../core/dist/index.js";import{minimatch as b}from"minimatch";import{availableParallelism as x,loadavg as S}from"node:os";import{createChunkerSync as C}from"../../chunker/dist/index.js";function w(t){return e(`sha256`).update(t).digest(`hex`).slice(0,16)}function T(t,n){let r=`${t}:${n}`;return e(`sha256`).update(r).digest(`hex`).slice(0,16)}const E=_(`indexer`);var D=class e{static BINARY_EXTENSIONS=new Set(`.node,.so,.dylib,.dll,.wasm,.bin,.exe,.png,.jpg,.jpeg,.gif,.bmp,.ico,.webp,.svg,.mp3,.mp4,.wav,.avi,.mov,.flac,.zip,.gz,.tar,.bz2,.7z,.rar,.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.ttf,.otf,.woff,.woff2,.eot,.pyc,.class,.o,.obj,.a,.lib`.split(`,`));async crawl(e){let t=[],n=new Set;return await this.walkDir(e.rootDir,e.rootDir,e.excludePatterns,t,n),t}async walkDir(t,n,i,a,u){let m;try{m=await c(t,{withFileTypes:!0})}catch(e){let n=e.code;(n===`EACCES`||n===`EPERM`)&&E.warn(`Permission denied, skipping directory`,{dir:t});return}for(let c of m){let m=f(t,c.name),_=p(n,m).replace(/\\/g,`/`);if(!this.isExcluded(_,i)){if(c.isDirectory()){if(c.name.startsWith(`.`)&&!(c.name===h.ai.slice(1)&&_.startsWith(h.ai)))continue;try{if((await o(m)).isSymbolicLink())continue}catch{continue}let e;try{e=r(m)}catch{continue}if(u.has(e))continue;u.add(e),await this.walkDir(m,n,i,a,u)}else if(c.isFile()){let t=d(c.name).toLowerCase();if(e.BINARY_EXTENSIONS.has(t))continue;try{if((await l(m)).size>g.maxFileSizeBytes)continue;let e=await s(m,`utf-8`);if(e.includes(`\0`))continue;a.push({relativePath:_,absolutePath:m,content:e,extension:t})}catch{}}}}}isExcluded(e,t){return t.some(t=>b(e,t,{dot:!0}))}};const O=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`]),k=[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!0},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:`class`,exported:!0},{pattern:/^export\s+interface\s+(\w+)/gm,kind:`interface`,exported:!0},{pattern:/^export\s+type\s+(\w+)/gm,kind:`type`,exported:!0},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:`const`,exported:!0},{pattern:/^export\s+enum\s+(\w+)/gm,kind:`enum`,exported:!0},{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!1},{pattern:/^class\s+(\w+)/gm,kind:`class`,exported:!1},{pattern:/^interface\s+(\w+)/gm,kind:`interface`,exported:!1},{pattern:/^type\s+(\w+)/gm,kind:`type`,exported:!1},{pattern:/^enum\s+(\w+)/gm,kind:`enum`,exported:!1}],A=[/import\s+(?:(?:type\s+)?(?:(?:\{[^}]*\}|[\w*]+)\s+from\s+)?)['"]([^'"]+)['"]/g,/import\(\s*['"]([^'"]+)['"]\s*\)/g,/require\(\s*['"]([^'"]+)['"]\s*\)/g];function j(t,n,r){return e(`sha256`).update(`${t}:${n}:${r}`).digest(`hex`).slice(0,16)}function M(t,n,r){return e(`sha256`).update(`${t}-${r}-${n}`).digest(`hex`).slice(0,16)}function N(e,t){return f(u(t),e).replace(/\\/g,`/`).replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function P(e){return e.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function F(e,t,n){let r=d(t).toLowerCase();if(!O.has(r))return{nodes:[],edges:[]};let i=[],a=[],o=new Date().toISOString(),s=new Set,c=P(t),l=j(`module`,c,c);i.push({id:l,type:`module`,name:t,properties:{ext:r},sourcePath:t,createdAt:o});for(let{pattern:n,kind:r,exported:c}of k){let u=new RegExp(n.source,n.flags),d;for(;(d=u.exec(e))!==null;){let e=d[1],n=`${r}:${e}`;if(s.has(n))continue;s.add(n);let u=j(r,e,t);i.push({id:u,type:r,name:e,properties:{exported:c},sourcePath:t,createdAt:o}),a.push({id:M(l,u,`defines`),fromId:l,toId:u,type:`defines`,weight:c?1:.5})}}let u=n?.workspacePackages,f=new Set;for(let n of A){let r=new RegExp(n.source,n.flags),i;for(;(i=r.exec(e))!==null;){let e=i[1];if(f.has(e))continue;let n;if(e.startsWith(`.`))n=N(e,t);else if(u){let t=e.startsWith(`@`)?e.split(`/`).slice(0,2).join(`/`):e.split(`/`)[0],r=u.get(t);if(!r)continue;n=r}else continue;f.add(e);let r=P(n),o=j(`module`,r,r);a.push({id:M(l,o,`imports`),fromId:l,toId:o,type:`imports`,properties:{source:e}})}}return{nodes:i,edges:a}}const I=_(`hash-cache`);var L=class{cache;filePath;dirty=!1;constructor(e){this.filePath=m(e,`file-hashes.json`),this.cache=new Map}load(){if(t(this.filePath))try{let e=n(this.filePath,`utf-8`),t=JSON.parse(e);this.cache=new Map(Object.entries(t)),I.info(`Hash cache loaded`,{entries:this.cache.size})}catch(e){I.warn(`Hash cache load failed, starting fresh`,{err:e}),this.cache=new Map}}get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t),this.dirty=!0}delete(e){this.cache.delete(e)&&(this.dirty=!0)}flush(){if(this.dirty)try{let e={};for(let[t,n]of this.cache)e[t]=n;a(this.filePath,JSON.stringify(e),`utf-8`),this.dirty=!1}catch(e){I.warn(`Hash cache flush failed`,{err:e})}}clear(){this.cache.clear(),this.dirty=!0,this.flush()}get size(){return this.cache.size}};const R=_(`indexer`),z=()=>new Promise(e=>setImmediate(e));async function B(e,t,n,r){let i=0;async function a(){for(;i<e.length;){let n=i++;try{await t(e[n])}catch(t){r?.(e[n],t)}n%10==0&&await z()}}await Promise.all(Array.from({length:Math.min(n,e.length)},()=>a()))}function V(e){let t=x(),n=S()[0]/t;return n>1.5?2:n>1?Math.max(2,Math.floor(e/2)):e}const H=Math.max(2,Math.min(4,Math.floor(x()*.5)));var U=class{embedder;store;crawler;indexing=!1;graphStore;hashCache;get isIndexing(){return this.indexing}constructor(e,t){this.embedder=e,this.store=t,this.crawler=new D}normalizeChunkText(e){return e.replace(/^\/\/ File: [^\n]*\n?/,``).toLowerCase().replace(/\s+/g,` `).trim()}setGraphStore(e){this.graphStore=e}setHashCache(e){this.hashCache=e}async index(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndex(e,t,{})}finally{this.indexing=!1}}async getChangedFiles(e){let t=e.indexing.concurrency??H,n=await this.crawlSources(e),{filesToProcess:r}=await this.planIndexWork(n,t,{});return r.map(e=>e.relativePath)}async indexFiles(e,t,n){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndexFiles(e,t,n)}finally{this.indexing=!1}}async doIndex(e,t,n={}){let r=Date.now(),i=e.indexing.concurrency??H;t?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let a=await this.crawlSources(e),{filesToProcess:o,filesSkipped:s,pathsToRemove:c}=await this.planIndexWork(a,i,{skipHashCheck:n.skipHashCheck}),{filesProcessed:l,chunksCreated:u,chunksDeduped:d}=await this.processFiles(a,o,i,t,{graphCleared:n.graphCleared}),f=await this.cleanupRemovedFiles(c,i,o.length,l,u,t);return this.hashCache?.flush(),t?.({phase:`done`,filesTotal:o.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:s,chunksCreated:u,chunksDeduped:d,filesRemoved:f,durationMs:Date.now()-r}}async doIndexFiles(e,t,n){let r=Date.now(),i=e.indexing.concurrency??H,a=new Set(t);if(a.size===0)return{filesProcessed:0,filesSkipped:0,chunksCreated:0,chunksDeduped:0,filesRemoved:0,durationMs:Date.now()-r};n?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let o=await this.crawlSources(e),{filesToProcess:s,filesSkipped:c}=await this.planIndexWork(o,i,{requestedPaths:a}),{filesProcessed:l,chunksCreated:u,chunksDeduped:d}=await this.processFiles(o,s,i,n,{});return this.hashCache?.flush(),n?.({phase:`done`,filesTotal:s.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:c,chunksCreated:u,chunksDeduped:d,filesRemoved:0,durationMs:Date.now()-r}}async crawlSources(e){return(await Promise.all(e.sources.map(e=>this.crawler.crawl({rootDir:e.path,excludePatterns:e.excludePatterns})))).flat()}async planIndexWork(e,t,n){let r=n.requestedPaths,i;if(r){let t=e=>e.replace(/\\/g,`/`).toLowerCase(),n=new Set([...r].map(t));i=e.filter(e=>n.has(t(e.relativePath))||n.has(t(e.absolutePath)))}else i=e;if(n.skipHashCheck)return{filesToProcess:i,filesSkipped:0,pathsToRemove:[]};let a=r?[]:await this.getPathsToRemove(e),o=0,s=[];return await B(i,async e=>{let t=w(e.content);if(this.hashCache){if(this.hashCache.get(e.relativePath)===t){o++;return}}else{let n=await this.store.getBySourcePath(e.relativePath);if(n.length>0&&n[0].fileHash===t){o++;return}}s.push(e)},V(t),(e,t)=>R.error(`Hash check failed`,{sourcePath:e.relativePath,...y(t)})),{filesToProcess:s,filesSkipped:o,pathsToRemove:a}}async getPathsToRemove(e){let t=await this.store.listSourcePaths(),n=new Set(e.map(e=>e.relativePath));return t.filter(e=>!n.has(e)&&!e.startsWith(`${h.aiCurated}/`))}async buildWorkspacePackageMap(e){let t=new Map;for(let n of e)if(n.relativePath.endsWith(`package.json`))try{let e=JSON.parse(n.content);if(typeof e.name!=`string`||e.name.length===0)continue;let r=n.relativePath===`package.json`?``:n.relativePath.replace(/\/package\.json$/,``),i=``;if(typeof e.exports==`string`)i=e.exports;else if(e.exports&&typeof e.exports==`object`){let t=e.exports,n=t[`.`]??t;if(typeof n==`string`)i=n;else if(n&&typeof n==`object`){let e=n,t=e.import??e.module??e.default??e.require;typeof t==`string`&&(i=t)}}!i&&typeof e.module==`string`&&(i=e.module),!i&&typeof e.main==`string`&&(i=e.main);let a=i.replace(/^\.\//,``).replace(/^dist\//,`src/`).replace(/\.(ts|js|mjs|cjs|tsx|jsx)$/,``),o=a?r?`${r}/${a}`:a:r?`${r}/src/index`:`src/index`;t.set(e.name,o)}catch{}return t}async processFiles(t,n,r,i,a={}){let o=0,s=0,c=0,l=n.length,u=this.graphStore?await this.buildWorkspacePackageMap(t):void 0,d=new Map,f=[],p=[],m=0,h=[],g=[],_=new Map,b=0,x=async()=>{if(h.length===0)return;let e=h,t=g,n=_;h=[],g=[],_=new Map,b=0;try{await this.store.upsert(e,t);for(let[e,t]of n)this.hashCache?.set(e,t)}catch(r){h.push(...e),g.push(...t);for(let[e,t]of n)_.set(e,t);throw r}},S=async()=>{if(this.graphStore){try{f.length>0&&await this.graphStore.upsertNodes(f),p.length>0&&await this.graphStore.upsertEdges(p)}catch(e){R.warn(`Graph batch flush failed`,y(e))}f=[],p=[],m=0}};return await B(n,async t=>{i?.({phase:`chunking`,filesTotal:l,filesProcessed:o,chunksTotal:s,chunksProcessed:s,currentFile:t.relativePath});let n=v(t.relativePath),r=C(t.extension).chunk(t.content,{sourcePath:t.relativePath,contentType:n});if(r.length===0)return;let E=w(t.content),D=new Date().toISOString(),O=(e,n,r)=>({id:T(t.relativePath,n),content:e.text,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:E,contentHash:r,indexedAt:D,origin:`indexed`,tags:[],version:1}),k=[],A=[];for(let t=0;t<r.length;t++){let n=r[t],i=e(`sha256`).update(this.normalizeChunkText(n.text)).digest(`hex`),a=O(n,t,i),o=d.get(i);if(o&&this.store.upsertWithoutVector){A.push({record:a,sourceRecordId:o}),c++;continue}d.set(i,a.id),k.push({chunk:n,record:a})}i?.({phase:`embedding`,filesTotal:l,filesProcessed:o,chunksTotal:s+r.length,chunksProcessed:s,currentFile:t.relativePath});let j=k.length>0?await this.embedder.embedBatch(k.map(({chunk:e})=>e.text)):[],M=k.map(({record:e})=>e);if(i?.({phase:`storing`,filesTotal:l,filesProcessed:o,chunksTotal:s+r.length,chunksProcessed:s,currentFile:t.relativePath}),M.length>0&&(h.push(...M),g.push(...j),_.set(t.relativePath,E),b++,b>=20&&await x()),A.length>0&&h.length>0&&await x(),this.store.upsertWithoutVector)for(let{record:e,sourceRecordId:t}of A)await this.store.upsertWithoutVector(e,t);if(M.length===0&&A.length>0&&this.hashCache?.set(t.relativePath,E),this.graphStore)try{a.graphCleared||await this.graphStore.deleteBySourcePath(t.relativePath);let e=F(t.content,t.relativePath,{workspacePackages:u});e.nodes.length>0&&f.push(...e.nodes),e.edges.length>0&&p.push(...e.edges),m++,m>=50&&await S()}catch(e){R.warn(`Graph extraction failed`,{sourcePath:t.relativePath,...y(e)})}o++,s+=r.length},V(r),(e,t)=>R.error(`Processing failed`,{sourcePath:e.relativePath,...y(t)})),await x(),await S(),{filesProcessed:o,chunksCreated:s,chunksDeduped:c}}async cleanupRemovedFiles(e,t,n,r,i,a){if(e.length===0)return 0;let o=0;return a?.({phase:`cleanup`,filesTotal:n,filesProcessed:r,chunksTotal:i,chunksProcessed:i}),await B(e,async e=>{await this.store.deleteBySourcePath(e),this.hashCache?.delete(e),this.graphStore&&await this.graphStore.deleteBySourcePath(e).catch(t=>R.warn(`Graph cleanup failed`,{sourcePath:e,...y(t)})),o++},V(t),(e,t)=>R.error(`Cleanup failed`,{sourcePath:e,...y(t)})),o}async reindexAll(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{if(await this.store.dropTable(),this.graphStore)try{let e=await this.graphStore.getStats();e.nodeCount>0&&(await this.graphStore.clear(),R.info(`Graph store cleared`,{nodeCount:e.nodeCount,edgeCount:e.edgeCount}))}catch(e){R.warn(`Graph store clear failed`,y(e))}return await this.doReindex(e,t)}catch(e){throw this.indexing=!1,e}}async doReindex(e,t){try{return await this.doIndex(e,t,{skipHashCheck:!0,graphCleared:!0})}finally{this.indexing=!1}}async getStats(){return this.store.getStats()}};const W=_(`smart-index`),G=1.5;var K=class{indexer;config;store;trickleTimer=null;stopped=!1;trickleIntervalMs;batchSize;priorityQueue=[];changedFiles=[];lastRefreshTime=0;refreshing=!1;constructor(e,t,n){this.indexer=e,this.config=t,this.store=n,this.trickleIntervalMs=t.indexing.trickleIntervalMs??this.readPositiveIntEnv(`AIKIT_SMART_TRICKLE_MS`,3e4),this.batchSize=t.indexing.trickleBatchSize??this.readPositiveIntEnv(`AIKIT_SMART_BATCH_SIZE`,1)}start(){this.trickleTimer&&=(clearTimeout(this.trickleTimer),null),this.stopped=!1,W.info(`Smart index scheduler started (trickle mode)`,{intervalMs:this.trickleIntervalMs,batchSize:this.batchSize}),this.scheduleTick()}stop(){this.stopped=!0,this.trickleTimer&&=(clearTimeout(this.trickleTimer),null)}prioritize(...e){let t=[...new Set(e.filter(Boolean))].filter(e=>{try{return!i(e).isDirectory()}catch{return W.debug(`Skipping non-existent path`,{path:e}),!1}});for(let e of t){let t=this.priorityQueue.indexOf(e);t>=0&&this.priorityQueue.splice(t,1)}for(let e of t.reverse())this.priorityQueue.unshift(e);this.priorityQueue.length>500&&(this.priorityQueue.length=500),t.length>0&&W.debug(`Files prioritized for trickle indexing`,{added:t.length,queued:this.priorityQueue.length})}getState(){return{mode:`smart`,queueSize:this.priorityQueue.length,changedFilesSize:this.changedFiles.length,intervalMs:this.trickleIntervalMs,batchSize:this.batchSize,running:this.trickleTimer!==null}}readPositiveIntEnv(e,t){let n=Number(process.env[e]);return Number.isFinite(n)&&n>0?n:t}scheduleTick(){this.trickleTimer=setTimeout(()=>void this.tick(),this.trickleIntervalMs),this.trickleTimer.unref&&this.trickleTimer.unref()}async tick(){if(!this.stopped)try{if(this.indexer.isIndexing){W.info(`Skipping trickle tick — indexing already in progress`);return}let e=this.getCpuCount(),t=S()[0];if(e>0&&t/e>G){W.info(`Skipping trickle tick — system load too high`,{load:t.toFixed(2),cpuCount:e,threshold:G});return}let n=await this.pickFiles();if(n.length===0){await this.maybeRefreshChangedFiles();return}W.debug(`Trickle indexing tick started`,{count:n.length,files:n});let r=await this.indexer.indexFiles(this.config,n);if(this.store)try{await this.store.createFtsIndex()}catch(e){W.warn(`FTS index rebuild failed after trickle tick`,{error:String(e)})}this.changedFiles=this.changedFiles.filter(e=>!n.includes(e)),W.debug(`Trickle indexing tick complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated})}catch(e){let t=String(e);if(t.includes(`not initialized`)||t.includes(`has been closed`)){W.warn(`Store closed — stopping smart index scheduler`,{error:t}),this.stop();return}W.error(`Trickle indexing tick failed`,{error:t})}finally{this.stopped||this.scheduleTick()}}getCpuCount(){try{return typeof x==`function`?x():4}catch{return 4}}async pickFiles(){let e=[];for(;e.length<this.batchSize&&this.priorityQueue.length>0;){let t=this.priorityQueue.shift();t&&!e.includes(t)&&e.push(t)}if(e.length<this.batchSize)for(await this.maybeRefreshChangedFiles();e.length<this.batchSize&&this.changedFiles.length>0;){let t=this.changedFiles.shift();t&&!e.includes(t)&&e.push(t)}return e}async maybeRefreshChangedFiles(){let e=Date.now();if(!(this.refreshing||this.changedFiles.length>0&&e-this.lastRefreshTime<6e5)){this.refreshing=!0;try{this.changedFiles=await this.indexer.getChangedFiles(this.config),this.lastRefreshTime=e,this.changedFiles.length>0&&W.debug(`Refreshed changed files for trickle indexing`,{count:this.changedFiles.length})}catch(e){let t=String(e);if(t.includes(`not initialized`)||t.includes(`has been closed`)){W.warn(`Store closed — stopping smart index scheduler`,{error:t}),this.stop();return}W.error(`Failed to refresh changed files for trickle indexing`,{error:t})}finally{this.refreshing=!1}}}};export{L as FileHashCache,D as FilesystemCrawler,U as IncrementalIndexer,K as SmartIndexScheduler,F as extractGraph,T as generateRecordId,w as hashContent};