@vpxa/aikit 0.1.114 → 0.1.116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.114",
3
+ "version": "0.1.116",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -3,7 +3,7 @@ import{i as e,t}from"./constants-Nz_Z7XS-.js";import{copyFileSync as n,existsSyn
3
3
  `))console.log(` ${e}`)}}function B(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 ut(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(`
5
5
  Dead in docs (informational):`);for(let t of e.deadInDocs)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}}function dt(e){console.log(e.path),console.log(` Language: ${e.language}`),console.log(` Lines: ${e.lines}`),console.log(` Estimated tokens: ~${e.estimatedTokens}`),console.log(``),U(`Imports`,e.imports),U(`Exports`,e.exports),U(`Functions`,e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}`)),U(`Classes`,e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}`)),U(`Interfaces`,e.interfaces.map(e=>`${e.name} @ line ${e.line}`)),U(`Types`,e.types.map(e=>`${e.name} @ line ${e.line}`))}function ft(e){if(console.log(`Symbol: ${e.name}`),e.definedIn?console.log(`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`):console.log(`Defined in: not found`),console.log(``),console.log(`Imported by:`),e.importedBy.length===0)console.log(` none`);else for(let t of e.importedBy)console.log(` - ${t.path}:${t.line} ${t.importStatement}`);if(console.log(``),console.log(`Referenced in:`),e.referencedIn.length===0)console.log(` none`);else for(let t of e.referencedIn)console.log(` - ${t.path}:${t.line} ${t.context}`)}function V(e){console.log(e.name),console.log(` Files: ${e.files.length}`),console.log(` Updated: ${e.updated}`),e.description&&console.log(` Description: ${e.description}`);for(let t of e.files)console.log(` - ${t}`)}function H(e){if(console.log(e.id),console.log(` Label: ${e.label}`),console.log(` Created: ${e.createdAt}`),e.notes&&console.log(` Notes: ${e.notes}`),e.files?.length){console.log(` Files: ${e.files.length}`);for(let t of e.files)console.log(` - ${t}`)}console.log(` Data:`);for(let t of JSON.stringify(e.data,null,2).split(`
6
- `))console.log(` ${t}`)}function U(e,t){if(console.log(`${e}:`),t.length===0){console.log(` none`),console.log(``);return}for(let e of t)console.log(` - ${e}`);console.log(``)}function pt(e){let t=e.trim();if(!t)return``;try{return JSON.parse(t)}catch{return e}}function mt(e){let t=e.trim();if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Checkpoint data must be a JSON object.`);return n}function ht(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score)}const gt=[{name:`parse-output`,description:`Parse build or tool output from stdin`,usage:`aikit parse-output [--tool tsc|vitest|biome|git-status]`,run:async e=>{let t=F(e,`--tool`,``).trim()||void 0,n=await L();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),rt(g(n,t))}},{name:`git`,description:`Show git branch, status, recent commits, and optional diff stats`,usage:`aikit git [--cwd path] [--commit-count N] [--diff]`,run:async e=>{ot(await he({cwd:F(e,`--cwd`,``).trim()||void 0,commitCount:P(e,`--commit-count`,5),includeDiff:I(e,`--diff`)}))}},{name:`diff`,description:`Parse unified diff text from stdin into structured file changes`,usage:`git diff | aikit diff`,run:async()=>{let e=await L();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),st(ce({diff:e}))}},{name:`summarize`,description:`Show a structural summary of a file`,usage:`aikit summarize <path>`,run:async e=>{let t=e.shift()?.trim();t||(console.error(`Usage: aikit summarize <path>`),process.exit(1)),dt(await ue({path:l(t)}))}},{name:`checkpoint`,description:`Save and restore lightweight session checkpoints`,usage:`aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`,run:async e=>{let t=e.shift()?.trim();switch(t||(console.error(`Usage: aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`),process.exit(1)),t){case`save`:{let t=e.shift()?.trim(),n=F(e,`--data`,``),r=F(e,`--notes`,``).trim()||void 0,i=n.trim()?``:await L();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),H(te(t,mt(n||i),{notes:r}));return}case`load`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint load <id>`),process.exit(1));let n=ee(t);if(!n){console.log(`No checkpoint found: ${t}`);return}H(n);return}case`list`:{let e=h();if(e.length===0){console.log(`No checkpoints saved.`);return}console.log(`Checkpoints (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.id}`),console.log(` Label: ${t.label}`),console.log(` Created: ${t.createdAt}`);return}case`latest`:{let e=m();if(!e){console.log(`No checkpoints saved.`);return}H(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],_t=[{name:`proc`,description:`Manage in-memory child processes`,usage:`aikit proc <start|stop|status|list|logs> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim(),n=e.shift()?.trim();(!t||!n)&&(console.error(`Usage: aikit proc start <id> <command> [args...]`),process.exit(1)),B(y(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=x(t);if(!n){console.log(`No managed process found: ${t}`);return}B(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=b(t);if(!n){console.log(`No managed process found: ${t}`);return}B(n);return}case`list`:{let e=_();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)B(t),console.log(``);return}case`logs`:{let t=P(e,`--tail`,50),n=e.shift()?.trim();n||(console.error(`Usage: aikit proc logs <id> [--tail N]`),process.exit(1));let r=v(n,t);if(r.length===0){console.log(`No logs found for process: ${n}`);return}for(let e of r)console.log(e);return}default:console.error(`Unknown proc action: ${t}`),console.error(`Actions: start, stop, status, list, logs`),process.exit(1)}}},{name:`watch`,description:`Manage in-memory filesystem watchers`,usage:`aikit watch <start|stop|list> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch start <path>`),process.exit(1));let n=We({path:l(t)});console.log(`Started watcher: ${n.id}`),console.log(` Path: ${n.path}`),console.log(` Status: ${n.status}`);return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch stop <id>`),process.exit(1));let n=Ge(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=Ue();if(e.length===0){console.log(`No active watchers.`);return}for(let t of e)console.log(`${t.id}`),console.log(` Path: ${t.path}`),console.log(` Status: ${t.status}`),console.log(` Events: ${t.eventCount}`);return}default:console.error(`Unknown watch action: ${t}`),console.error(`Actions: start, stop, list`),process.exit(1)}}},{name:`delegate`,description:`Delegate a task to a local Ollama model`,usage:`aikit delegate [--model name] [--system prompt] [--temp 0.3] <prompt | --stdin>`,run:async e=>{if((e[0]===`models`?e.shift():void 0)===`models`){try{let e=await oe();if(e.length===0){console.log(`No Ollama models available. Pull one with: ollama pull gemma4:e2b`);return}for(let t of e)console.log(t)}catch{console.error(`Ollama is not running. Start it with: ollama serve`),process.exit(1)}return}let t=F(e,`--model`,``),n=F(e,`--system`,``),r=P(e,`--temp`,.3),i=F(e,`--context`,``),a=e.join(` `);a||=await L(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await k(l(i),`utf-8`));let s=await ae({prompt:a,model:t||void 0,system:n||void 0,context:o,temperature:r});s.error&&(console.error(`Error: ${s.error}`),process.exit(1)),console.log(s.response),console.error(`\n(${s.model}, ${s.durationMs}ms, ${s.tokenCount??`?`} tokens)`)}}],vt=[{name:`eval`,description:`Evaluate JavaScript or TypeScript in a constrained VM sandbox`,usage:`aikit eval [code] [--lang js|ts] [--timeout ms]`,run:async e=>{let t=F(e,`--lang`,`js`),n=P(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await L(),a=r||i;a.trim()||(console.error(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`),process.exit(1));let o=le({code:a,lang:t===`ts`?`ts`:`js`,timeout:n});if(!o.success){console.error(`Eval failed in ${o.durationMs}ms: ${o.error}`),process.exitCode=1;return}console.log(`Eval succeeded in ${o.durationMs}ms`),console.log(`─`.repeat(60)),console.log(o.output)}},{name:`test`,description:`Run Vitest for all tests or a specific subset`,usage:`aikit test [files...] [--grep pattern] [--cwd path] [--timeout ms]`,run:async e=>{let t=F(e,`--grep`,``).trim()||void 0,n=F(e,`--cwd`,``).trim()||void 0,r=P(e,`--timeout`,6e4),i=e.filter(Boolean),a=await Ve({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});at(a),a.passed||(process.exitCode=1)}},{name:`rename`,description:`Rename a symbol across files using whole-word regex matching`,usage:`aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``,r=e.shift()?.trim()??``;(!t||!n||!r)&&(console.error(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`),process.exit(1));let i=R(F(e,`--extensions`,``)),a=R(F(e,`--exclude`,``)),o=await ke({oldName:t,newName:n,rootPath:l(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:I(e,`--dry-run`)});console.log(JSON.stringify(o,null,2))}},{name:`codemod`,description:`Apply regex-based codemod rules from a JSON file across a path`,usage:`aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=F(e,`--rules`,``).trim();(!t||!n)&&(console.error(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`),process.exit(1));let r=await k(l(n),`utf-8`),i;try{i=JSON.parse(r)}catch{throw Error(`Failed to parse rules file as JSON: ${n}`)}if(!Array.isArray(i))throw Error(`Codemod rules file must contain a JSON array.`);let a=R(F(e,`--extensions`,``)),o=R(F(e,`--exclude`,``)),s=await ne({rootPath:l(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:I(e,`--dry-run`)});console.log(JSON.stringify(s,null,2))}},{name:`transform`,description:`Apply jq-like transforms to JSON from stdin`,usage:`cat data.json | aikit transform <expression>`,run:async e=>{let t=e.join(` `).trim(),n=await L();(!t||!n.trim())&&(console.error(`Usage: cat data.json | aikit transform <expression>`),process.exit(1));let r=ie({input:n,expression:t});console.log(r.outputString)}}];function W(){let e=process.env.AIKIT_CONFIG_PATH??(r(l(process.cwd(),`aikit.config.json`))?l(process.cwd(),`aikit.config.json`):null);if(!e)return yt();let t=a(e,`utf-8`),n;try{n=JSON.parse(t)}catch{console.error(`Failed to parse ${e} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let i=s(e);return n.sources=n.sources.map(e=>({...e,path:l(i,e.path)})),n.store.path=l(i,n.store.path),n.curated=n.curated??{path:`curated`},n.curated.path=l(i,n.curated.path),G(n,i),n}function yt(){let e=process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`aikit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:j.model,dimensions:j.dimensions},store:{backend:`sqlite-vec`,path:l(e,A.data)},curated:{path:l(e,A.aiCurated)},stateDir:l(e,A.state)};return G(t,e),t}function G(e,t){if(!qe())return;let n=Je(t);e.store.path=l(M(n.partition)),e.stateDir=l(M(n.partition),`state`),e.curated||={path:l(t,A.aiCurated)}}async function bt(){let e=W(),t=new Xe({model:e.embedding.model,dimensions:e.embedding.dimensions});await t.initialize();let n=null;if(e.store.backend===`sqlite-vec`){let t=l(e.store.path,`aikit.db`),i=s(t);if(!r(i)){let{mkdirSync:e}=await import(`node:fs`);e(i,{recursive:!0})}n=await Qe(t)}let i=await $e({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await i.initialize();let a=new Ze(t,i),{CuratedKnowledgeManager:o}=await import(`../../server/dist/index.js`),c=new o(e.curated.path,i,t),u;try{let t=n?new N({adapter:n}):new N({path:e.store.path});await t.initialize(),u=t,a.setGraphStore(u)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),u={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNeighbors:async()=>({nodes:[],edges:[]}),traverse:async()=>({nodes:[],edges:[]}),findNodes:async()=>[],findEdges:async()=>[],deleteNode:async()=>{},deleteBySourcePath:async()=>0,clear:async()=>{},getStats:async()=>({nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}),validate:async()=>({valid:!0,orphanNodes:[],danglingEdges:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}}),setNodeCommunity:async()=>{},detectCommunities:async()=>({}),traceProcess:async()=>({id:``,entryNodeId:``,label:``,properties:{},steps:[]}),getProcesses:async()=>[],deleteProcess:async()=>{},depthGroupedTraversal:async()=>({}),getCohesionScore:async()=>0,getSymbol360:async()=>({node:{id:``,type:``,name:``,properties:{}},incoming:[],outgoing:[],community:null,processes:[]}),close:async()=>{}}}return await Ye().catch(()=>{}),{config:e,embedder:t,store:i,graphStore:u,indexer:a,curated:c,sqliteAdapter:n}}async function xt(){let e=await import(`../../flows/dist/index.js`),{FlowLoader:t,FlowRegistryManager:n,FlowStateMachine:r,GitInstaller:a}=e,o=typeof e.getBuiltinFlows==`function`?e.getBuiltinFlows:void 0,s=W(),l=c(s.stateDir??c(s.sources[0].path,`.aikit-state`),`flows`,`installed`),u=c(Ke(),`flows`);i(u,{recursive:!0});let d=c(u,`registry.json`),f=s.sources[0].path,p=c(f,`.flows`);return{loader:new t,registry:new n(d),stateMachine:new r(p,{before:[],after:[{id:`_docs-sync`,description:`Synchronize project documentation — update docs/ folder based on changes made during the flow.`,position:`after`,skills:[`docs`]}]}),git:new a(l),getBuiltinFlows:o,cwd:f}}const K=[e=>c(`skills`,e,`SKILL.md`),e=>c(`skills`,e,`README.md`),e=>c(e,`SKILL.md`),e=>c(e,`README.md`)];function St(e,t){for(let a of t.steps){let t=c(e,a.instruction);if(r(t))continue;let o=!1;for(let l of K){let u=c(e,l(a.id));if(r(u)){let e=s(t);r(e)||i(e,{recursive:!0}),n(u,t),o=!0;break}}o||console.warn(`Warning: instruction file for step "${a.id}" not found.\n Expected: ${a.instruction}\n Searched: ${K.map(e=>e(a.id)).join(`, `)}`)}}const Ct=[{name:`flow`,description:`Manage pluggable development flows`,usage:`flow <add|remove|list|info|use|update|status|start|reset> [args]`,run:async e=>{let t=e[0];if(!t){console.log(`Usage: aikit flow <add|remove|list|info|use|update|status|start|reset|runs>`),console.log(``),console.log(`Commands:`),console.log(` add <source> Install a flow from git URL or local path`),console.log(` remove <name> Remove an installed flow`),console.log(` list List all installed flows`),console.log(` info <name> Show details of a flow`),console.log(` use <name> Set active flow (start it)`),console.log(` update <name> Update a flow from its source`),console.log(` status Show current flow execution status`),console.log(` start [name] Start a flow (or resume)`),console.log(` reset Reset the active flow`),console.log(` runs List all flow runs`);return}let n=await xt();switch(t){case`add`:{let t=e[1];if(!t){console.error(`Usage: aikit flow add <source>`),console.error(` source: git URL (https://...) or local path`);return}let i=t.startsWith(`http`)||t.startsWith(`git@`)||t.endsWith(`.git`),a=l(t),s=r(a);if(!i&&!s){console.error(`Source not found: ${t}`),console.error(`Provide a git URL or existing local path.`);return}let c,u;if(i){console.log(`Cloning ${t}...`);let e=n.git.clone(t);if(!e.success||!e.data){console.error(e.error??`Failed to clone flow`);return}c=e.data,u=`git`}else{let r=e[2]||o(a);console.log(`Copying local flow from ${t}...`);let i=n.git.copyLocal(a,r);if(!i.success||!i.data){console.error(i.error??`Failed to copy local flow`);return}c=i.data,u=`local`}let d=await n.loader.load(c);if(!d.success||!d.data){console.error(d.error??`Failed to load flow`),n.git.remove(c);return}let{manifest:f,format:p}=d.data;if(St(c,f),f.install.length>0){console.log(`Installing ${f.install.length} dependencies...`);let e=n.git.runInstallDeps(f.install);if(!e.success){console.error(`Dependency install failed: ${e.error}`),n.git.remove(c);return}}let m=new Date().toISOString(),h=n.registry.register({name:f.name,version:f.version,source:t,sourceType:u,installPath:c,format:p,registeredAt:m,updatedAt:m,manifest:f});if(!h.success){console.error(h.error??`Failed to register flow`),n.git.remove(c);return}console.log(`✓ Flow "${f.name}" v${f.version} installed (${p} format)`),console.log(` Steps: ${f.steps.map(e=>e.id).join(` → `)}`);break}case`remove`:{let t=e[1];if(!t){console.error(`Usage: aikit flow remove <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}let i=n.git.remove(r.installPath);if(!i.success){console.error(i.error??`Failed to remove flow files`);return}let a=n.registry.unregister(t);if(!a.success){console.error(a.error??`Failed to unregister flow`);return}console.log(`✓ Flow "${t}" removed`);break}case`list`:{let e=n.registry.list();if(e.length===0){console.log("No flows installed. Use `aikit flow add <source>` to install one.");return}console.log(`Installed Flows:`),console.log(`─`.repeat(60));for(let t of e){let e=t.manifest.steps.map(e=>e.id).join(` → `);console.log(` ${t.name} v${t.version} (${t.sourceType}, ${t.format})`),console.log(` Steps: ${e}`)}let t=n.stateMachine.getStatus();t.success&&t.data&&(console.log(``),console.log(`Active: ${t.data.flow} (${t.data.status}, step: ${t.data.currentStep??`done`})`));break}case`info`:{let t=e[1];if(!t){console.error(`Usage: aikit flow info <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}console.log(`Flow: ${r.name}`),console.log(`Version: ${r.version}`),console.log(`Source: ${r.source} (${r.sourceType})`),console.log(`Format: ${r.format}`),console.log(`Path: ${r.installPath}`),console.log(`Registered: ${r.registeredAt}`),console.log(`Updated: ${r.updatedAt}`),console.log(``),console.log(`Steps:`);for(let e of r.manifest.steps){let t=e.requires.length?` (requires: ${e.requires.join(`, `)})`:``;console.log(` ${e.id}: ${e.name}${t}`),console.log(` Skill: ${e.skill}`),console.log(` Produces: ${e.produces.join(`, `)}`)}if(r.manifest.install.length>0){console.log(``),console.log(`Dependencies:`);for(let e of r.manifest.install)console.log(` ${e}`)}break}case`use`:case`start`:{let r=e[1],i=r?n.registry.get(r):null;if(t===`use`&&!r){console.error(`Usage: aikit flow use <name>`);return}if(t===`start`&&!r){let e=n.stateMachine.getStatus();if(e.success&&e.data&&e.data.status===`active`){console.log(`Resuming flow: ${e.data.flow}`),console.log(`Current step: ${e.data.currentStep}`),console.log(`Completed: ${e.data.completedSteps.join(`, `)||`none`}`);return}console.error("No active flow. Use `aikit flow start <name>` to begin one.");return}if(!i){console.error(`Flow "${r}" not found. Use \`aikit flow list\` to see installed flows.`);return}let a=e[2],o=n.stateMachine.start(i.name,i.manifest,a);if(!o.success||!o.data){console.error(o.error??`Failed to start flow`);return}let s=o.data;console.log(`✓ Flow "${i.name}" started`),console.log(` Topic: ${s.topic}`),console.log(` Run directory: ${s.runDir}`),console.log(` Current step: ${s.currentStep}`),console.log(` Steps: ${i.manifest.steps.map(e=>e.id).join(` → `)}`);break}case`update`:{let t=e[1];if(!t){console.error(`Usage: aikit flow update <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}if(r.sourceType!==`git`){console.error(`Flow "${t}" is ${r.sourceType}, not updatable via git`);return}console.log(`Updating ${t}...`);let i=n.git.update(r.installPath);if(!i.success){console.error(i.error??`Failed to update flow`);return}let a=await n.loader.load(r.installPath);if(a.success&&a.data){let e=new Date().toISOString(),t=n.registry.register({...r,version:a.data.manifest.version,format:a.data.format,manifest:a.data.manifest,updatedAt:e});if(!t.success){console.error(t.error??`Failed to refresh flow registry entry`);return}}console.log(`✓ Flow "${t}" updated`);break}case`status`:{let e=n.stateMachine.getStatus();if(!e.success||!e.data){console.log(`No active flow.`);return}let t=e.data;if(console.log(`Flow: ${t.flow}`),console.log(`Topic: ${t.topic}`),console.log(`Slug: ${t.slug}`),console.log(`Run Dir: ${t.runDir}`),console.log(`Status: ${t.status}`),console.log(`Current Step: ${t.currentStep??`(completed)`}`),console.log(`Completed: ${t.completedSteps.join(`, `)||`none`}`),t.skippedSteps.length>0&&console.log(`Skipped: ${t.skippedSteps.join(`, `)}`),console.log(`Started: ${t.startedAt}`),console.log(`Updated: ${t.updatedAt}`),Object.keys(t.artifacts).length>0){console.log(`Artifacts:`);for(let[e,n]of Object.entries(t.artifacts))console.log(` ${e}: ${n}`)}break}case`reset`:{let e=n.stateMachine.reset();if(!e.success){console.error(e.error??`Failed to reset flow state`);return}console.log(`✓ Flow abandoned`);break}case`runs`:{let t=e[1],r=e[2],i=n.stateMachine.listRuns({flow:t,status:r});if(i.length===0){console.log(`No flow runs found.`);return}console.log(`Flow Runs:`),console.log(`─`.repeat(80));for(let e of i){let t=e.currentStep?` → ${e.currentStep}`:``;console.log(` ${e.id} [${e.status}] ${e.flow}${t}`),console.log(` Topic: ${e.topic}`),console.log(` Started: ${e.startedAt} | Updated: ${e.updatedAt}`)}break}default:console.error(`Unknown flow command: ${t}`),console.log("Use `aikit flow` for help.")}}}];let q=null;async function J(){return q||=await bt(),q}function wt(){return q}const Tt=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
6
+ `))console.log(` ${t}`)}function U(e,t){if(console.log(`${e}:`),t.length===0){console.log(` none`),console.log(``);return}for(let e of t)console.log(` - ${e}`);console.log(``)}function pt(e){let t=e.trim();if(!t)return``;try{return JSON.parse(t)}catch{return e}}function mt(e){let t=e.trim();if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Checkpoint data must be a JSON object.`);return n}function ht(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score)}const gt=[{name:`parse-output`,description:`Parse build or tool output from stdin`,usage:`aikit parse-output [--tool tsc|vitest|biome|git-status]`,run:async e=>{let t=F(e,`--tool`,``).trim()||void 0,n=await L();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),rt(g(n,t))}},{name:`git`,description:`Show git branch, status, recent commits, and optional diff stats`,usage:`aikit git [--cwd path] [--commit-count N] [--diff]`,run:async e=>{ot(await he({cwd:F(e,`--cwd`,``).trim()||void 0,commitCount:P(e,`--commit-count`,5),includeDiff:I(e,`--diff`)}))}},{name:`diff`,description:`Parse unified diff text from stdin into structured file changes`,usage:`git diff | aikit diff`,run:async()=>{let e=await L();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),st(ce({diff:e}))}},{name:`summarize`,description:`Show a structural summary of a file`,usage:`aikit summarize <path>`,run:async e=>{let t=e.shift()?.trim();t||(console.error(`Usage: aikit summarize <path>`),process.exit(1)),dt(await ue({path:l(t)}))}},{name:`checkpoint`,description:`Save and restore lightweight session checkpoints`,usage:`aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`,run:async e=>{let t=e.shift()?.trim();switch(t||(console.error(`Usage: aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`),process.exit(1)),t){case`save`:{let t=e.shift()?.trim(),n=F(e,`--data`,``),r=F(e,`--notes`,``).trim()||void 0,i=n.trim()?``:await L();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),H(te(t,mt(n||i),{notes:r}));return}case`load`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint load <id>`),process.exit(1));let n=ee(t);if(!n){console.log(`No checkpoint found: ${t}`);return}H(n);return}case`list`:{let e=h();if(e.length===0){console.log(`No checkpoints saved.`);return}console.log(`Checkpoints (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.id}`),console.log(` Label: ${t.label}`),console.log(` Created: ${t.createdAt}`);return}case`latest`:{let e=m();if(!e){console.log(`No checkpoints saved.`);return}H(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],_t=[{name:`proc`,description:`Manage in-memory child processes`,usage:`aikit proc <start|stop|status|list|logs> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim(),n=e.shift()?.trim();(!t||!n)&&(console.error(`Usage: aikit proc start <id> <command> [args...]`),process.exit(1)),B(y(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=x(t);if(!n){console.log(`No managed process found: ${t}`);return}B(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=b(t);if(!n){console.log(`No managed process found: ${t}`);return}B(n);return}case`list`:{let e=_();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)B(t),console.log(``);return}case`logs`:{let t=P(e,`--tail`,50),n=e.shift()?.trim();n||(console.error(`Usage: aikit proc logs <id> [--tail N]`),process.exit(1));let r=v(n,t);if(r.length===0){console.log(`No logs found for process: ${n}`);return}for(let e of r)console.log(e);return}default:console.error(`Unknown proc action: ${t}`),console.error(`Actions: start, stop, status, list, logs`),process.exit(1)}}},{name:`watch`,description:`Manage in-memory filesystem watchers`,usage:`aikit watch <start|stop|list> ...`,run:async e=>{let t=e.shift()?.trim()??``;switch(t){case`start`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch start <path>`),process.exit(1));let n=We({path:l(t)});console.log(`Started watcher: ${n.id}`),console.log(` Path: ${n.path}`),console.log(` Status: ${n.status}`);return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit watch stop <id>`),process.exit(1));let n=Ge(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=Ue();if(e.length===0){console.log(`No active watchers.`);return}for(let t of e)console.log(`${t.id}`),console.log(` Path: ${t.path}`),console.log(` Status: ${t.status}`),console.log(` Events: ${t.eventCount}`);return}default:console.error(`Unknown watch action: ${t}`),console.error(`Actions: start, stop, list`),process.exit(1)}}},{name:`delegate`,description:`Delegate a task to a local Ollama model`,usage:`aikit delegate [--model name] [--system prompt] [--temp 0.3] <prompt | --stdin>`,run:async e=>{if((e[0]===`models`?e.shift():void 0)===`models`){try{let e=await oe();if(e.length===0){console.log(`No Ollama models available. Pull one with: ollama pull gemma4:e2b`);return}for(let t of e)console.log(t)}catch{console.error(`Ollama is not running. Start it with: ollama serve`),process.exit(1)}return}let t=F(e,`--model`,``),n=F(e,`--system`,``),r=P(e,`--temp`,.3),i=F(e,`--context`,``),a=e.join(` `);a||=await L(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await k(l(i),`utf-8`));let s=await ae({prompt:a,model:t||void 0,system:n||void 0,context:o,temperature:r});s.error&&(console.error(`Error: ${s.error}`),process.exit(1)),console.log(s.response),console.error(`\n(${s.model}, ${s.durationMs}ms, ${s.tokenCount??`?`} tokens)`)}}],vt=[{name:`eval`,description:`Evaluate JavaScript or TypeScript in a constrained VM sandbox`,usage:`aikit eval [code] [--lang js|ts] [--timeout ms]`,run:async e=>{let t=F(e,`--lang`,`js`),n=P(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await L(),a=r||i;a.trim()||(console.error(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`),process.exit(1));let o=le({code:a,lang:t===`ts`?`ts`:`js`,timeout:n});if(!o.success){console.error(`Eval failed in ${o.durationMs}ms: ${o.error}`),process.exitCode=1;return}console.log(`Eval succeeded in ${o.durationMs}ms`),console.log(`─`.repeat(60)),console.log(o.output)}},{name:`test`,description:`Run Vitest for all tests or a specific subset`,usage:`aikit test [files...] [--grep pattern] [--cwd path] [--timeout ms]`,run:async e=>{let t=F(e,`--grep`,``).trim()||void 0,n=F(e,`--cwd`,``).trim()||void 0,r=P(e,`--timeout`,6e4),i=e.filter(Boolean),a=await Ve({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});at(a),a.passed||(process.exitCode=1)}},{name:`rename`,description:`Rename a symbol across files using whole-word regex matching`,usage:`aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``,r=e.shift()?.trim()??``;(!t||!n||!r)&&(console.error(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`),process.exit(1));let i=R(F(e,`--extensions`,``)),a=R(F(e,`--exclude`,``)),o=await ke({oldName:t,newName:n,rootPath:l(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:I(e,`--dry-run`)});console.log(JSON.stringify(o,null,2))}},{name:`codemod`,description:`Apply regex-based codemod rules from a JSON file across a path`,usage:`aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`,run:async e=>{let t=e.shift()?.trim()??``,n=F(e,`--rules`,``).trim();(!t||!n)&&(console.error(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`),process.exit(1));let r=await k(l(n),`utf-8`),i;try{i=JSON.parse(r)}catch{throw Error(`Failed to parse rules file as JSON: ${n}`)}if(!Array.isArray(i))throw Error(`Codemod rules file must contain a JSON array.`);let a=R(F(e,`--extensions`,``)),o=R(F(e,`--exclude`,``)),s=await ne({rootPath:l(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:I(e,`--dry-run`)});console.log(JSON.stringify(s,null,2))}},{name:`transform`,description:`Apply jq-like transforms to JSON from stdin`,usage:`cat data.json | aikit transform <expression>`,run:async e=>{let t=e.join(` `).trim(),n=await L();(!t||!n.trim())&&(console.error(`Usage: cat data.json | aikit transform <expression>`),process.exit(1));let r=ie({input:n,expression:t});console.log(r.outputString)}}];function W(){let e=process.env.AIKIT_CONFIG_PATH??(r(l(process.cwd(),`aikit.config.json`))?l(process.cwd(),`aikit.config.json`):null);if(!e)return yt();let t=a(e,`utf-8`),n;try{n=JSON.parse(t)}catch{console.error(`Failed to parse ${e} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let i=s(e);return n.sources=n.sources.map(e=>({...e,path:l(i,e.path)})),n.store.path=l(i,n.store.path),n.curated=n.curated??{path:`curated`},n.curated.path=l(i,n.curated.path),G(n,i),n}function yt(){let e=process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`aikit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:j.model,dimensions:j.dimensions},store:{backend:`sqlite-vec`,path:l(e,A.data)},curated:{path:l(e,A.aiCurated)},stateDir:l(e,A.state)};return G(t,e),t}function G(e,t){if(!qe())return;let n=Je(t);e.store.path=l(M(n.partition)),e.stateDir=l(M(n.partition),`state`),e.curated||={path:l(t,A.aiCurated)}}async function bt(){let e=W(),t=new Xe({model:e.embedding.model,dimensions:e.embedding.dimensions,interOpNumThreads:e.embedding.interOpNumThreads,intraOpNumThreads:e.embedding.intraOpNumThreads});await t.initialize();let n=null;if(e.store.backend===`sqlite-vec`){let t=l(e.store.path,`aikit.db`),i=s(t);if(!r(i)){let{mkdirSync:e}=await import(`node:fs`);e(i,{recursive:!0})}n=await Qe(t)}let i=await $e({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await i.initialize();let a=new Ze(t,i),{CuratedKnowledgeManager:o}=await import(`../../server/dist/index.js`),c=new o(e.curated.path,i,t),u;try{let t=n?new N({adapter:n}):new N({path:e.store.path});await t.initialize(),u=t,a.setGraphStore(u)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),u={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNeighbors:async()=>({nodes:[],edges:[]}),traverse:async()=>({nodes:[],edges:[]}),findNodes:async()=>[],findEdges:async()=>[],deleteNode:async()=>{},deleteBySourcePath:async()=>0,clear:async()=>{},getStats:async()=>({nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}),validate:async()=>({valid:!0,orphanNodes:[],danglingEdges:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}}),setNodeCommunity:async()=>{},detectCommunities:async()=>({}),traceProcess:async()=>({id:``,entryNodeId:``,label:``,properties:{},steps:[]}),getProcesses:async()=>[],deleteProcess:async()=>{},depthGroupedTraversal:async()=>({}),getCohesionScore:async()=>0,getSymbol360:async()=>({node:{id:``,type:``,name:``,properties:{}},incoming:[],outgoing:[],community:null,processes:[]}),close:async()=>{}}}return await Ye().catch(()=>{}),{config:e,embedder:t,store:i,graphStore:u,indexer:a,curated:c,sqliteAdapter:n}}async function xt(){let e=await import(`../../flows/dist/index.js`),{FlowLoader:t,FlowRegistryManager:n,FlowStateMachine:r,GitInstaller:a}=e,o=typeof e.getBuiltinFlows==`function`?e.getBuiltinFlows:void 0,s=W(),l=c(s.stateDir??c(s.sources[0].path,`.aikit-state`),`flows`,`installed`),u=c(Ke(),`flows`);i(u,{recursive:!0});let d=c(u,`registry.json`),f=s.sources[0].path,p=c(f,`.flows`);return{loader:new t,registry:new n(d),stateMachine:new r(p,{before:[],after:[{id:`_docs-sync`,description:`Synchronize project documentation — update docs/ folder based on changes made during the flow.`,position:`after`,skills:[`docs`]}]}),git:new a(l),getBuiltinFlows:o,cwd:f}}const K=[e=>c(`skills`,e,`SKILL.md`),e=>c(`skills`,e,`README.md`),e=>c(e,`SKILL.md`),e=>c(e,`README.md`)];function St(e,t){for(let a of t.steps){let t=c(e,a.instruction);if(r(t))continue;let o=!1;for(let l of K){let u=c(e,l(a.id));if(r(u)){let e=s(t);r(e)||i(e,{recursive:!0}),n(u,t),o=!0;break}}o||console.warn(`Warning: instruction file for step "${a.id}" not found.\n Expected: ${a.instruction}\n Searched: ${K.map(e=>e(a.id)).join(`, `)}`)}}const Ct=[{name:`flow`,description:`Manage pluggable development flows`,usage:`flow <add|remove|list|info|use|update|status|start|reset> [args]`,run:async e=>{let t=e[0];if(!t){console.log(`Usage: aikit flow <add|remove|list|info|use|update|status|start|reset|runs>`),console.log(``),console.log(`Commands:`),console.log(` add <source> Install a flow from git URL or local path`),console.log(` remove <name> Remove an installed flow`),console.log(` list List all installed flows`),console.log(` info <name> Show details of a flow`),console.log(` use <name> Set active flow (start it)`),console.log(` update <name> Update a flow from its source`),console.log(` status Show current flow execution status`),console.log(` start [name] Start a flow (or resume)`),console.log(` reset Reset the active flow`),console.log(` runs List all flow runs`);return}let n=await xt();switch(t){case`add`:{let t=e[1];if(!t){console.error(`Usage: aikit flow add <source>`),console.error(` source: git URL (https://...) or local path`);return}let i=t.startsWith(`http`)||t.startsWith(`git@`)||t.endsWith(`.git`),a=l(t),s=r(a);if(!i&&!s){console.error(`Source not found: ${t}`),console.error(`Provide a git URL or existing local path.`);return}let c,u;if(i){console.log(`Cloning ${t}...`);let e=n.git.clone(t);if(!e.success||!e.data){console.error(e.error??`Failed to clone flow`);return}c=e.data,u=`git`}else{let r=e[2]||o(a);console.log(`Copying local flow from ${t}...`);let i=n.git.copyLocal(a,r);if(!i.success||!i.data){console.error(i.error??`Failed to copy local flow`);return}c=i.data,u=`local`}let d=await n.loader.load(c);if(!d.success||!d.data){console.error(d.error??`Failed to load flow`),n.git.remove(c);return}let{manifest:f,format:p}=d.data;if(St(c,f),f.install.length>0){console.log(`Installing ${f.install.length} dependencies...`);let e=n.git.runInstallDeps(f.install);if(!e.success){console.error(`Dependency install failed: ${e.error}`),n.git.remove(c);return}}let m=new Date().toISOString(),h=n.registry.register({name:f.name,version:f.version,source:t,sourceType:u,installPath:c,format:p,registeredAt:m,updatedAt:m,manifest:f});if(!h.success){console.error(h.error??`Failed to register flow`),n.git.remove(c);return}console.log(`✓ Flow "${f.name}" v${f.version} installed (${p} format)`),console.log(` Steps: ${f.steps.map(e=>e.id).join(` → `)}`);break}case`remove`:{let t=e[1];if(!t){console.error(`Usage: aikit flow remove <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}let i=n.git.remove(r.installPath);if(!i.success){console.error(i.error??`Failed to remove flow files`);return}let a=n.registry.unregister(t);if(!a.success){console.error(a.error??`Failed to unregister flow`);return}console.log(`✓ Flow "${t}" removed`);break}case`list`:{let e=n.registry.list();if(e.length===0){console.log("No flows installed. Use `aikit flow add <source>` to install one.");return}console.log(`Installed Flows:`),console.log(`─`.repeat(60));for(let t of e){let e=t.manifest.steps.map(e=>e.id).join(` → `);console.log(` ${t.name} v${t.version} (${t.sourceType}, ${t.format})`),console.log(` Steps: ${e}`)}let t=n.stateMachine.getStatus();t.success&&t.data&&(console.log(``),console.log(`Active: ${t.data.flow} (${t.data.status}, step: ${t.data.currentStep??`done`})`));break}case`info`:{let t=e[1];if(!t){console.error(`Usage: aikit flow info <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}console.log(`Flow: ${r.name}`),console.log(`Version: ${r.version}`),console.log(`Source: ${r.source} (${r.sourceType})`),console.log(`Format: ${r.format}`),console.log(`Path: ${r.installPath}`),console.log(`Registered: ${r.registeredAt}`),console.log(`Updated: ${r.updatedAt}`),console.log(``),console.log(`Steps:`);for(let e of r.manifest.steps){let t=e.requires.length?` (requires: ${e.requires.join(`, `)})`:``;console.log(` ${e.id}: ${e.name}${t}`),console.log(` Skill: ${e.skill}`),console.log(` Produces: ${e.produces.join(`, `)}`)}if(r.manifest.install.length>0){console.log(``),console.log(`Dependencies:`);for(let e of r.manifest.install)console.log(` ${e}`)}break}case`use`:case`start`:{let r=e[1],i=r?n.registry.get(r):null;if(t===`use`&&!r){console.error(`Usage: aikit flow use <name>`);return}if(t===`start`&&!r){let e=n.stateMachine.getStatus();if(e.success&&e.data&&e.data.status===`active`){console.log(`Resuming flow: ${e.data.flow}`),console.log(`Current step: ${e.data.currentStep}`),console.log(`Completed: ${e.data.completedSteps.join(`, `)||`none`}`);return}console.error("No active flow. Use `aikit flow start <name>` to begin one.");return}if(!i){console.error(`Flow "${r}" not found. Use \`aikit flow list\` to see installed flows.`);return}let a=e[2],o=n.stateMachine.start(i.name,i.manifest,a);if(!o.success||!o.data){console.error(o.error??`Failed to start flow`);return}let s=o.data;console.log(`✓ Flow "${i.name}" started`),console.log(` Topic: ${s.topic}`),console.log(` Run directory: ${s.runDir}`),console.log(` Current step: ${s.currentStep}`),console.log(` Steps: ${i.manifest.steps.map(e=>e.id).join(` → `)}`);break}case`update`:{let t=e[1];if(!t){console.error(`Usage: aikit flow update <name>`);return}let r=n.registry.get(t);if(!r){console.error(`Flow "${t}" not found`);return}if(r.sourceType!==`git`){console.error(`Flow "${t}" is ${r.sourceType}, not updatable via git`);return}console.log(`Updating ${t}...`);let i=n.git.update(r.installPath);if(!i.success){console.error(i.error??`Failed to update flow`);return}let a=await n.loader.load(r.installPath);if(a.success&&a.data){let e=new Date().toISOString(),t=n.registry.register({...r,version:a.data.manifest.version,format:a.data.format,manifest:a.data.manifest,updatedAt:e});if(!t.success){console.error(t.error??`Failed to refresh flow registry entry`);return}}console.log(`✓ Flow "${t}" updated`);break}case`status`:{let e=n.stateMachine.getStatus();if(!e.success||!e.data){console.log(`No active flow.`);return}let t=e.data;if(console.log(`Flow: ${t.flow}`),console.log(`Topic: ${t.topic}`),console.log(`Slug: ${t.slug}`),console.log(`Run Dir: ${t.runDir}`),console.log(`Status: ${t.status}`),console.log(`Current Step: ${t.currentStep??`(completed)`}`),console.log(`Completed: ${t.completedSteps.join(`, `)||`none`}`),t.skippedSteps.length>0&&console.log(`Skipped: ${t.skippedSteps.join(`, `)}`),console.log(`Started: ${t.startedAt}`),console.log(`Updated: ${t.updatedAt}`),Object.keys(t.artifacts).length>0){console.log(`Artifacts:`);for(let[e,n]of Object.entries(t.artifacts))console.log(` ${e}: ${n}`)}break}case`reset`:{let e=n.stateMachine.reset();if(!e.success){console.error(e.error??`Failed to reset flow state`);return}console.log(`✓ Flow abandoned`);break}case`runs`:{let t=e[1],r=e[2],i=n.stateMachine.listRuns({flow:t,status:r});if(i.length===0){console.log(`No flow runs found.`);return}console.log(`Flow Runs:`),console.log(`─`.repeat(80));for(let e of i){let t=e.currentStep?` → ${e.currentStep}`:``;console.log(` ${e.id} [${e.status}] ${e.flow}${t}`),console.log(` Topic: ${e.topic}`),console.log(` Started: ${e.startedAt} | Updated: ${e.updatedAt}`)}break}default:console.error(`Unknown flow command: ${t}`),console.log("Use `aikit flow` for help.")}}}];let q=null;async function J(){return q||=await bt(),q}function wt(){return q}const Tt=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
7
7
  Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear
8
8
  Options: --type, --name, --node-id, --edge-type, --direction, --depth, --limit, --source-path`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit graph <action>
9
9
  Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`),process.exit(1));let{graphStore:n}=await J(),r=F(e,`--type`,``),i=F(e,`--name`,``),a=F(e,`--node-id`,``),o=F(e,`--edge-type`,``),s=F(e,`--direction`,`both`),c=P(e,`--depth`,2),l=P(e,`--limit`,50),u=F(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 ge(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(`
@@ -198,7 +198,11 @@ interface AikitConfig {
198
198
  };
199
199
  embedding: {
200
200
  model: string;
201
- dimensions: number;
201
+ dimensions: number; /** Default 1. */
202
+ interOpNumThreads?: number; /** Default 4. */
203
+ intraOpNumThreads?: number; /** Default true. */
204
+ childProcess?: boolean; /** Default 60000. */
205
+ idleTimeoutMs?: number;
202
206
  };
203
207
  store: {
204
208
  backend: string;
@@ -0,0 +1,2 @@
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";import{env as i,pipeline as a}from"@huggingface/transformers";i.cacheDir=n(t(),`.cache`,`huggingface`,`transformers-js`);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(){let e=i.backends.onnx;e.wasm||={};let t=e.wasm;return t.numThreads=this.threadConfig.intraOp,{dtype:`q8`,session_options:{interOpNumThreads:this.threadConfig.interOp,intraOpNumThreads:this.threadConfig.intraOp}}}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim)return e;let t=e.subarray(0,this.dimensions),n=0;for(let e=0;e<t.length;e++)n+=t[e]*t[e];if(n=Math.sqrt(n),n===0)return new Float32Array(this.dimensions);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){this.shutdownPromise=null;try{this.pipe=await a(`feature-extraction`,this.modelId,this.getPipelineOptions())}catch(r){let o=r.message?.toLowerCase()??``;if(this.isCorruptionError(o)){let r=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 ${r} and retrying download...`);try{await e(r,{recursive:!0,force:!0})}catch{}try{this.pipe=await a(`feature-extraction`,this.modelId,this.getPipelineOptions()),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}": ${r.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)throw Error(`Embedding pipeline returned no output`);let n=new Float32Array(t.data);return this.truncateAndRenorm(n)}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)throw Error(`Embedding pipeline returned no output`);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)))}}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;function f(e){process.send?.(e)}function p(){c&&=(clearTimeout(c),null)}async function m(){if(!s)return;let e=s;s=null,await e.shutdown?.()}async function h(e,t){l&&process.exit(e),l=!0,p(),t?.notifyIdle&&f({type:`idle-exit`});try{await m()}finally{process.exit(e)}}function g(){p(),d!==0&&(c=setTimeout(()=>{h(0,{notifyIdle:!0})},d))}function _(e){return Array.from(e)}function v(e){return e instanceof Error?e.message:String(e)}function y(){if(!s)throw Error(`Embedder not initialized`);return s}async function b(e,t){f({type:`error`,id:e,message:v(t)})}async function x(e){p();try{switch(e.type){case`init`:await m(),s=new o(e.config),await s.initialize(),f({type:`ready`,dimensions:s.dimensions,modelId:s.modelId});break;case`embed`:{let t=await y().embed(e.text);f({type:`result`,id:e.id,data:_(t)});break}case`embedBatch`:{let t=await y().embedBatch(e.texts,e.batchSize);f({type:`batchResult`,id:e.id,data:t.map(e=>_(e))});break}case`embedQuery`:{let t=await y().embedQuery(e.text);f({type:`result`,id:e.id,data:_(t)});break}case`shutdown`:await h(0);return}}catch(t){await b(e.type===`shutdown`?`shutdown`:e.type===`init`?`init`:e.id,t),e.type===`init`&&await h(1)}g()}async function S(e,t){await b(e,t),await h(1)}process.on(`message`,e=>{x(e)}),process.on(`SIGTERM`,()=>{h(0)}),process.on(`uncaughtException`,e=>{S(`fatal`,e)}),process.on(`unhandledRejection`,e=>{S(`fatal`,e)});export{};
@@ -23,19 +23,72 @@ interface IEmbedder {
23
23
  shutdown?(): Promise<void>;
24
24
  }
25
25
  //#endregion
26
+ //#region packages/embeddings/src/embedder-proxy.d.ts
27
+ interface EmbedderProxyOptions {
28
+ model?: string;
29
+ dimensions?: number;
30
+ nativeDim?: number;
31
+ queryPrefix?: string;
32
+ interOpNumThreads?: number;
33
+ intraOpNumThreads?: number;
34
+ idleTimeoutMs?: number;
35
+ }
36
+ declare class EmbedderProxy implements IEmbedder {
37
+ private readonly options;
38
+ private readonly workerPath;
39
+ private readonly pendingRequests;
40
+ private readonly childState;
41
+ private child;
42
+ private readyChild;
43
+ private pendingInit;
44
+ private pendingShutdown;
45
+ private initializePromise;
46
+ private shutdownPromise;
47
+ private currentDimensions;
48
+ private currentModelId;
49
+ constructor(options?: EmbedderProxyOptions);
50
+ get dimensions(): number;
51
+ get modelId(): string;
52
+ initialize(): Promise<void>;
53
+ embed(text: string): Promise<Float32Array>;
54
+ embedQuery(text: string): Promise<Float32Array>;
55
+ embedBatch(texts: string[], batchSize?: number): Promise<Float32Array[]>;
56
+ shutdown(): Promise<void>;
57
+ private startWorker;
58
+ private spawnChild;
59
+ private handleChildMessage;
60
+ private handleChildExit;
61
+ private handleChildFailure;
62
+ private sendVectorRequest;
63
+ private requireReadyChild;
64
+ private buildInitConfig;
65
+ private buildChildEnv;
66
+ private requireChildState;
67
+ private clearChildReference;
68
+ private rejectPendingForChild;
69
+ private resolveLifecycleIfOwned;
70
+ private rejectLifecycleIfOwned;
71
+ private toError;
72
+ }
73
+ //#endregion
26
74
  //#region packages/embeddings/src/onnx-embedder.d.ts
27
75
  declare class OnnxEmbedder implements IEmbedder {
28
76
  private pipe;
77
+ private shutdownPromise;
29
78
  readonly dimensions: number;
30
79
  readonly modelId: string;
31
80
  private readonly nativeDim;
32
81
  private readonly queryPrefix;
82
+ private readonly threadConfig;
33
83
  constructor(options?: {
34
84
  model?: string;
35
85
  dimensions?: number;
36
86
  nativeDim?: number;
37
87
  queryPrefix?: string;
88
+ interOpNumThreads?: number;
89
+ intraOpNumThreads?: number;
38
90
  });
91
+ private getPipelineOptions;
39
92
  /**
40
93
  * Matryoshka truncation: slice to targetDim and re-normalize.
41
94
  * Only applied when targetDim < nativeDim.
@@ -46,9 +99,10 @@ declare class OnnxEmbedder implements IEmbedder {
46
99
  initialize(): Promise<void>;
47
100
  private isCorruptionError;
48
101
  shutdown(): Promise<void>;
102
+ private _doShutdown;
49
103
  embed(text: string): Promise<Float32Array>;
50
104
  embedQuery(query: string): Promise<Float32Array>;
51
105
  embedBatch(texts: string[], batchSize?: number): Promise<Float32Array[]>;
52
106
  }
53
107
  //#endregion
54
- export { type IEmbedder, OnnxEmbedder };
108
+ export { EmbedderProxy, type EmbedderProxyOptions, type IEmbedder, OnnxEmbedder };
@@ -1 +1 @@
1
- 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";import{env as i,pipeline as a}from"@huggingface/transformers";i.cacheDir=n(t(),`.cache`,`huggingface`,`transformers-js`);var o=class{pipe=null;dimensions;modelId;nativeDim;queryPrefix;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)}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim)return e;let t=e.subarray(0,this.dimensions),n=0;for(let e=0;e<t.length;e++)n+=t[e]*t[e];if(n=Math.sqrt(n),n===0)return new Float32Array(this.dimensions);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)try{this.pipe=await a(`feature-extraction`,this.modelId,{dtype:`q8`})}catch(r){let o=r.message?.toLowerCase()??``;if(this.isCorruptionError(o)){let r=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 ${r} and retrying download...`);try{await e(r,{recursive:!0,force:!0})}catch{}try{this.pipe=await a(`feature-extraction`,this.modelId,{dtype:`q8`}),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}": ${r.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(){this.pipe=null}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t)throw Error(`Embedding pipeline returned no output`);let n=new Float32Array(t.data);return this.truncateAndRenorm(n)}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)throw Error(`Embedding pipeline returned no output`);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)))}}return n}};export{o as OnnxEmbedder};
1
+ import{fork as e}from"node:child_process";import{randomUUID as t}from"node:crypto";import{dirname as n,join as r}from"node:path";import{fileURLToPath as i}from"node:url";import{EMBEDDING_DEFAULTS as a}from"../../core/dist/index.js";import{rm as o}from"node:fs/promises";import{homedir as s}from"node:os";import{env as c,pipeline as l}from"@huggingface/transformers";var u=class{options;workerPath=r(n(i(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.currentDimensions=e.dimensions??a.dimensions,this.currentModelId=e.model??a.model}get dimensions(){return this.currentDimensions}get modelId(){return this.currentModelId}async initialize(){if(!(this.readyChild&&this.child===this.readyChild)){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){return this.sendVectorRequest({type:`embed`,text:e})}async embedQuery(e){return this.sendVectorRequest({type:`embedQuery`,text:e})}async embedBatch(e,n){if(e.length===0)return[];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;this.pendingRequests.delete(t.id),n.resolve(t.data.map(e=>new Float32Array(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 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}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)}`)}};c.cacheDir=r(s(),`.cache`,`huggingface`,`transformers-js`);var d=class{pipe=null;shutdownPromise=null;dimensions;modelId;nativeDim;queryPrefix;threadConfig;constructor(e){if(this.modelId=e?.model??a.model,this.nativeDim=e?.nativeDim??1024,this.dimensions=e?.dimensions??a.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(){let e=c.backends.onnx;e.wasm||={};let t=e.wasm;return t.numThreads=this.threadConfig.intraOp,{dtype:`q8`,session_options:{interOpNumThreads:this.threadConfig.interOp,intraOpNumThreads:this.threadConfig.intraOp}}}truncateAndRenorm(e){if(this.dimensions>=this.nativeDim)return e;let t=e.subarray(0,this.dimensions),n=0;for(let e=0;e<t.length;e++)n+=t[e]*t[e];if(n=Math.sqrt(n),n===0)return new Float32Array(this.dimensions);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){this.shutdownPromise=null;try{this.pipe=await l(`feature-extraction`,this.modelId,this.getPipelineOptions())}catch(e){let t=e.message?.toLowerCase()??``;if(this.isCorruptionError(t)){let e=r(c.cacheDir??r(s(),`.cache`,`huggingface`,`transformers-js`),this.modelId);console.error(`[aikit:auto-heal] Detected corrupted model cache for "${this.modelId}". Clearing cache at ${e} and retrying download...`);try{await o(e,{recursive:!0,force:!0})}catch{}try{this.pipe=await l(`feature-extraction`,this.modelId,this.getPipelineOptions()),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}": ${e.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)throw Error(`Embedding pipeline returned no output`);let n=new Float32Array(t.data);return this.truncateAndRenorm(n)}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)throw Error(`Embedding pipeline returned no output`);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)))}}return n}};export{u as EmbedderProxy,d as OnnxEmbedder};
@@ -0,0 +1 @@
1
+ import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{AIKIT_PATHS as a,EMBEDDING_DEFAULTS as o,createLogger as s,getPartitionDir as c,isUserInstalled as l,registerWorkspace as u,serializeError as d}from"../../core/dist/index.js";const f=n(i(import.meta.url)),p=s(`server`),m=[`auto`,`manual`,`smart`],h={model:o.model,dimensions:o.dimensions,childProcess:!0,idleTimeoutMs:6e4};function g(e){return typeof e==`string`&&m.includes(e)}function _(e,t,n){let i=r(e),a=r(t);if(!i.startsWith(a))throw Error(`Config ${n} path escapes workspace root: ${e} is not under ${t}`);return i}function v(e){let t=process.env.AIKIT_INDEX_MODE;if(g(t))return t;if(e.indexMode)return e.indexMode;let n=process.env.AIKIT_AUTO_INDEX;return n===void 0?e.autoIndex===void 0?`smart`:e.autoIndex?`auto`:`manual`:n===`true`?`auto`:`manual`}function y(){let i=process.env.AIKIT_CONFIG_PATH??(e(r(process.cwd(),`aikit.config.json`))?r(process.cwd(),`aikit.config.json`):r(f,`..`,`..`,`..`,`aikit.config.json`));try{if(!e(i))return p.info(`No config file found, using defaults`,{configPath:i}),b();let o=t(i,`utf-8`),s=JSON.parse(o);if(s.embedding={...h,...s.embedding},!s.sources||!Array.isArray(s.sources)||s.sources.length===0)throw Error(`Config must have at least one source`);if(!s.store?.path)throw Error(`Config must specify store.path`);if(s.autoIndex!==void 0&&typeof s.autoIndex!=`boolean`)throw Error(`Config autoIndex must be a boolean`);if(s.indexMode!==void 0&&!g(s.indexMode))throw Error(`Config indexMode must be one of: ${m.join(`, `)}`);let c=n(i);return s.sources=s.sources.map(e=>({...e,path:_(r(c,e.path),c,`source`)})),s.store.path=_(r(c,s.store.path),c,`store`),s.curated=s.curated??{path:a.aiCurated},s.curated.path=_(r(c,s.curated.path),c,`curated`),x(s,c),s.indexMode=v(s),s}catch(e){return p.error(`Failed to load config`,{configPath:i,...d(e)}),p.warn(`Falling back to default configuration`,{configPath:i}),b()}}function b(){let e=process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`aikit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{...h},store:{backend:`sqlite-vec`,path:r(e,a.data)},curated:{path:r(e,a.aiCurated)},onboardDir:r(e,a.aiContext),stateDir:r(e,a.state)};return x(t,e),t.indexMode=v(t),t}function x(e,t){if(!l())return;let n=t,i=u(n);e.store.path=r(c(i.partition)),e.onboardDir=r(c(i.partition),`onboard`),e.stateDir=r(c(i.partition),`state`),e.curated||={path:r(n,a.aiCurated)}}function S(t,n){if(!e(n))throw Error(`Workspace root does not exist: ${n}`);p.info(`Reconfiguring for workspace root`,{workspaceRoot:n});try{process.chdir(n),p.info(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){p.warn(`Failed to chdir to workspace root`,{workspaceRoot:n,...d(e)})}t.sources=[{path:n,excludePatterns:t.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],t.store.path=r(n,a.data),t.curated={path:r(n,a.aiCurated)},t.onboardDir=r(n,a.aiContext),t.stateDir=r(n,a.state),x(t,n)}export{y as loadConfig,S as reconfigureForWorkspace,v as resolveIndexMode};
@@ -1 +1 @@
1
- import{t as e}from"./curated-manager-CXSPygmJ.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-BL-I_FFY.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-OaSHcA6x.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-qD-mw6RP.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(s.aikit.indexer,l,s.aikit.store),n=s.aikit.store;g=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),s.setSmartScheduler(t),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-BL-I_FFY.js`),import(`./server-qD-mw6RP.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(()=>{d.info(`Auto-shutdown: no activity for 30 minutes — exiting`),process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`smart`?h.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};
1
+ import{t as e}from"./curated-manager-CXSPygmJ.js";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i,pathToFileURL as a}from"node:url";import{parseArgs as o}from"node:util";import{createLogger as s,serializeError as c}from"../../core/dist/index.js";const l=n(i(import.meta.url)),u=(()=>{try{let e=r(l,`..`,`..`,`..`,`package.json`);return JSON.parse(t(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}})(),d=s(`server`);function f(){return process.env.AIKIT_TRANSPORT?process.env.AIKIT_TRANSPORT:process.stdin.isTTY?`http`:`stdio`}const{values:p}=(()=>{let e=process.argv[1];if(!e)return!1;try{return import.meta.url===a(e).href}catch{return!1}})()?o({allowPositionals:!0,options:{transport:{type:`string`,default:f()},port:{type:`string`,default:process.env.AIKIT_PORT??`3210`}}}):{values:{transport:f(),port:process.env.AIKIT_PORT??`3210`}};async function m(){if(process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,c(e))}),d.info(`Starting MCP AI Kit server`,{version:u}),p.transport===`http`){let[{default:e},{loadConfig:t,resolveIndexMode:n},{registerDashboardRoutes:r,resolveDashboardDir:i},{registerSettingsRoutes:a,resolveSettingsDir:o},{createSettingsRouter:s}]=await Promise.all([import(`express`),import(`./config-D4z6-EcI.js`),import(`./dashboard-static-BfIe0Si1.js`),import(`./settings-static-BosGZSPf.js`),import(`./routes-OaSHcA6x.js`)]),l=t();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path});let u=e();u.use(e.json());let f=Number(p.port);u.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.AIKIT_CORS_ORIGIN??`http://localhost:${f}`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),r(u,i(),d);let m=new Date().toISOString();u.use(`/settings/api`,s({log:d,mcpInfo:()=>({transport:`http`,port:f,pid:process.pid,startedAt:m})})),a(u,o(),d),u.get(`/health`,(e,t)=>{t.json({status:`ok`})});let h=!1,g=null,_=null,v=null,y=Promise.resolve();u.post(`/mcp`,async(e,t)=>{if(!h||!_||!v){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let n=y,r;y=new Promise(e=>{r=e}),await n;try{let n=new v({sessionIdGenerator:void 0});await _.connect(n),await n.handleRequest(e,t,e.body),n.close()}catch(e){if(d.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{r()}}),u.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),u.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let b=u.listen(f,`127.0.0.1`,()=>{d.info(`MCP server listening`,{url:`http://127.0.0.1:${f}/mcp`,port:f}),setTimeout(async()=>{try{let[{createLazyServer:e,ALL_TOOL_NAMES:t},{StreamableHTTPServerTransport:r},{checkForUpdates:i,autoUpgradeScaffold:a}]=await Promise.all([import(`./server-Cbe4LQqt.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./version-check-Bj07vc5x.js`)]);i(),a();let o=n(l),s=e(l,o);_=s.server,v=r,h=!0,d.info(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:t.length,resourceCount:2}),s.startInit(),o===`auto`?s.ready.then(async()=>{try{let e=l.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e}),await s.runInitialIndex(),d.info(`Initial index complete`)}catch(e){d.error(`Initial index failed; will retry on aikit_reindex`,c(e))}}).catch(e=>d.error(`AI Kit init or indexing failed`,c(e))):o===`smart`?s.ready.then(async()=>{try{if(!s.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(s.aikit.indexer,l,s.aikit.store),n=s.aikit.store;g=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),s.setSmartScheduler(t),d.info(`Smart index scheduler started (HTTP mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit initialization failed`,c(e))):(s.ready.catch(e=>d.error(`AI Kit initialization failed`,c(e))),d.info(`Initial full indexing skipped in HTTP mode`,{indexMode:o}))}catch(e){d.error(`Failed to load server modules`,c(e))}},100)}),x=async e=>{d.info(`Shutdown signal received`,{signal:e}),g?.stop(),b.close(),_&&await _.close(),process.exit(0)};process.on(`SIGINT`,()=>x(`SIGINT`)),process.on(`SIGTERM`,()=>x(`SIGTERM`))}else{let[{loadConfig:e,reconfigureForWorkspace:t,resolveIndexMode:n},{createLazyServer:r},{checkForUpdates:a,autoUpgradeScaffold:o},{RootsListChangedNotificationSchema:s}]=await Promise.all([import(`./config-D4z6-EcI.js`),import(`./server-Cbe4LQqt.js`),import(`./version-check-Bj07vc5x.js`),import(`@modelcontextprotocol/sdk/types.js`)]),l=e();d.info(`Config loaded`,{sourceCount:l.sources.length,storePath:l.store.path}),a(),o();let u=n(l),f=r(l,u),{server:p,startInit:m,ready:h,runInitialIndex:g}=f,{StdioServerTransport:_}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),v=new _;await p.connect(v),d.info(`MCP server started`,{transport:`stdio`});let y=e=>{if(e.length===0)return!1;let n=e[0].uri,r=n.startsWith(`file://`)?i(n):n;return d.info(`MCP roots resolved`,{rootUri:n,rootPath:r,rootCount:e.length}),t(l,r),l.allRoots=e.map(e=>{let t=e.uri;return t.startsWith(`file://`)?i(t):t}),!0},b=!1;try{b=y((await p.server.listRoots()).roots),b||d.info(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...c(e)}),b=!0}b||=await new Promise(e=>{let t=setTimeout(()=>{d.warn(`Timed out waiting for MCP roots/list_changed; using cwd fallback`,{cwd:process.cwd()}),e(!1)},5e3);p.server.setNotificationHandler(s,async()=>{clearTimeout(t);try{e(y((await p.server.listRoots()).roots))}catch(t){d.warn(`roots/list retry failed after notification`,c(t)),e(!1)}})}),m();let x=null,S=()=>{x&&clearTimeout(x),x=setTimeout(()=>{d.info(`Auto-shutdown: no activity for 30 minutes — exiting`),process.exit(0)},18e5),x.unref&&x.unref()};S(),process.stdin.on(`data`,()=>S()),h.catch(e=>{d.error(`Initialization failed — server will continue with limited tools`,c(e))}),u===`auto`?g().catch(e=>d.error(`Initial index failed`,c(e))):u===`smart`?h.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,l,f.aikit.store),n=f.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),d.info(`Smart index scheduler started (stdio mode)`)}catch(e){d.error(`Failed to start smart index scheduler`,c(e))}}).catch(e=>d.error(`AI Kit init failed for smart scheduler`,c(e))):d.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:u})}}m().catch(e=>{d.error(`Fatal error`,c(e)),process.exit(1)});export{e as CuratedKnowledgeManager};