@vpxa/aikit 0.1.357 → 0.1.359

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/dist/index.js +19 -19
  3. package/packages/cli/dist/init-Cvys5TD4.js +7 -0
  4. package/packages/cli/dist/{templates-Bu7dZtk_.js → templates-d2UQHjpi.js} +13 -12
  5. package/packages/server/dist/bin.js +1 -1
  6. package/packages/server/dist/index.js +1 -1
  7. package/packages/server/dist/prelude-CfXBHLpw.js +1 -0
  8. package/packages/server/dist/prelude-D33q42vQ.js +2 -0
  9. package/packages/server/dist/sampling-Cs9MoNYX.js +2 -0
  10. package/packages/server/dist/sampling-DFogBKrL.js +1 -0
  11. package/packages/server/dist/{server-D5eu57oU.js → server-BZVPmRGV.js} +160 -160
  12. package/packages/server/dist/{server-D7gZ4K_H.js → server-CICqmfQ_.js} +160 -160
  13. package/packages/server/dist/{server-http-AarbD3gm.js → server-http-CPU9_eVT.js} +1 -1
  14. package/packages/server/dist/{server-http-wnYmWFkC.js → server-http-D3DK1H19.js} +1 -1
  15. package/packages/server/dist/{server-stdio-BWoMqXU8.js → server-stdio-BRKxFWyO.js} +1 -1
  16. package/packages/server/dist/{server-stdio-CBGO6XiO.js → server-stdio-l8I0RW4l.js} +1 -1
  17. package/scaffold/dist/adapters/hooks.mjs +1 -1
  18. package/scaffold/dist/definitions/exec-hooks.mjs +1 -1
  19. package/scaffold/dist/definitions/protocols.mjs +7 -6
  20. package/scaffold/dist/definitions/skills/aikit.mjs +4 -4
  21. package/scaffold/general/hooks/scripts/_runtime.mjs +87 -15
  22. package/scaffold/general/hooks/scripts/freshness-signal.mjs +196 -0
  23. package/scaffold/general/hooks/scripts/privacy-guard.mjs +19 -6
  24. package/scaffold/general/hooks/scripts/scope-guard.mjs +160 -0
  25. package/scaffold/general/hooks/scripts/scout-guard.mjs +18 -14
  26. package/packages/cli/dist/init-CWLiK7bC.js +0 -7
  27. package/packages/server/dist/prelude-DetbWo8R.js +0 -1
  28. package/packages/server/dist/prelude-hfAEi93R.js +0 -2
  29. package/packages/server/dist/sampling-CWjnUevo.js +0 -2
  30. package/packages/server/dist/sampling-CnE3owSt.js +0 -1
  31. package/scaffold/general/hooks/scripts/post-edit-check.mjs +0 -36
  32. package/scaffold/general/hooks/scripts/pre-compact-save.mjs +0 -13
  33. package/scaffold/general/hooks/scripts/session-init.mjs +0 -85
  34. package/scaffold/general/hooks/scripts/session-learn.mjs +0 -53
  35. package/scaffold/general/hooks/scripts/session-observer.mjs +0 -77
  36. package/scaffold/general/hooks/scripts/subagent-context.mjs +0 -59
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.357",
3
+ "version": "0.1.359",
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",
@@ -1,7 +1,7 @@
1
- import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-BNPHP-QC.js";import{A as o,B as s,C as c,D as l,E as u,F as d,I as f,L as p,M as ee,N as te,O as ne,P as re,R as ie,S as ae,T as oe,_ as se,a as ce,b as le,c as m,d as h,f as ue,g as de,h as g,i as fe,j as pe,k as me,l as he,m as _,n as ge,o as _e,p as v,s as y,t as ve,u as b,v as ye,w as be,x as xe,y as Se,z as x}from"./templates-Bu7dZtk_.js";import{copyFileSync as Ce,existsSync as S,mkdirSync as C,readFileSync as w,readdirSync as T,renameSync as we,rmSync as E,statSync as Te,unlinkSync as Ee,writeFileSync as D}from"node:fs";import{basename as De,dirname as O,join as k,posix as A,relative as Oe,resolve as j,win32 as M}from"node:path";import{fileURLToPath as ke}from"node:url";import{arch as Ae,homedir as N,platform as je}from"node:os";import{AIKIT_PATHS as P,AIKIT_RUNTIME_PATHS as Me,EMBEDDING_DEFAULTS as Ne,INSTALL_ARGS as Pe,cleanupOldVersions as Fe,createLogger as F,getGlobalDataDir as Ie,getPartitionDir as Le,isUserInstalled as Re,migrateLegacyWorkspaceLayout as ze,registerWorkspace as Be,safeCwd as I,safeCwdOrHome as Ve,saveRegistry as He}from"../../core/dist/index.js";import{initializeWasm as Ue}from"../../chunker/dist/index.js";import{OnnxEmbedder as We}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Ge}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ke,createSqliteAdapter as qe,createStore as Je}from"../../store/dist/index.js";import{mkdir as Ye,readFile as Xe,rename as Ze,rm as Qe,unlink as $e,writeFile as L}from"node:fs/promises";import{addToWorkset as et,audit as tt,check as nt,checkpointLatest as rt,checkpointList as it,checkpointLoad as at,checkpointSave as ot,codemod as st,compact as ct,dataTransform as lt,delegate as ut,delegateListModels as dt,deleteWorkset as ft,diffParse as pt,evaluate as mt,fileSummary as ht,find as gt,findDeadSymbols as _t,findExamples as vt,getWorkset as yt,gitContext as bt,graphQuery as xt,guide as St,health as Ct,laneCreate as wt,laneDiff as Tt,laneDiscard as Et,laneList as Dt,laneMerge as Ot,laneStatus as kt,listWorksets as At,parseOutput as jt,processList as Mt,processLogs as Nt,processStart as Pt,processStatus as Ft,processStop as It,queueClear as Lt,queueCreate as Rt,queueDelete as zt,queueDone as Bt,queueFail as Vt,queueGet as Ht,queueList as Ut,queueNext as Wt,queuePush as Gt,removeFromWorkset as Kt,rename as qt,replayClear as Jt,replayList as Yt,replayTrim as Xt,saveWorkset as Zt,scopeMap as Qt,stashClear as $t,stashDelete as en,stashGet as tn,stashList as nn,stashSet as rn,symbol as an,testRun as on,trace as sn,watchList as cn,watchStart as ln,watchStop as un}from"../../tools/dist/index.js";import{execFileSync as dn,execSync as R,fork as fn,spawn as pn}from"node:child_process";import{extractSvg as mn,renderToResult as hn,sanitizeTitle as gn}from"../../server/dist/index.js";import{randomUUID as _n}from"node:crypto";import{parse as vn,stringify as yn}from"yaml";function bn(){let e=I(),t=process.env.AIKIT_CONFIG_PATH??(e&&S(j(e,`aikit.config.json`))?j(e,`aikit.config.json`):null),n=t?O(t):e??N();if(ze(n),!t)return xn();let r=w(t,`utf-8`),i;try{i=JSON.parse(r)}catch{console.error(`Failed to parse ${t} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let a=n;return i.sources=i.sources.map(e=>({...e,path:j(a,e.path)})),i.store.path=j(a,i.store.path),i.curated=i.curated??{path:P.aiCurated},i.curated.path=j(a,i.curated.path),i.onboardDir||=P.aiContext,i.onboardDir=j(a,i.onboardDir),i.stateDir||=P.state,i.stateDir=j(a,i.stateDir),Sn(i,a),i}function xn(){let e=process.env.AIKIT_WORKSPACE_ROOT??I()??N();ze(e);let 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:Ne.model,dimensions:Ne.dimensions},store:{backend:`sqlite-vec`,path:j(e,P.data)},curated:{path:j(e,P.aiCurated)},onboardDir:j(e,P.aiContext),stateDir:j(e,P.state)};return Sn(t,e),t}function Sn(e,t){if(!Re())return;let n=Be(t);e.store.path=j(Le(n.partition),Me.data),e.stateDir=j(Le(n.partition),Me.state),e.onboardDir=j(Le(n.partition),Me.onboard),e.curated={path:j(Le(n.partition),Me.curated)}}async function Cn(){let e=bn(),t=new We({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=j(e.store.path,`aikit.db`),r=O(t);if(!S(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await qe(t)}let r=await Je({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new Ge(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new Ke({adapter:n}):new Ke({path:e.store.path});await t.initialize(),s=t,i.setGraphStore(s)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),s={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNodes:async()=>[],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 Ue().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const wn=[{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()??``;if(!t||!n)throw new h(`Usage: aikit analyze <type> <path>
2
- Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`);let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:l}=await import(`../../analyzers/dist/index.js`),u=j(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(I()??N(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:throw new h(`Unknown analyze type: ${t}\nTypes: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`)}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||=I()??N();let a=j(n),o=bn();console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
3
- `);let s=await t({path:a,mode:r,outDir:i??o.onboardDir});for(let e of s.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: ${s.totalDurationMs}ms`),s.outDir&&console.log(`Output written to: ${s.outDir}`)}}],Tn=[{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=g(e,`--tool`,``).trim()||void 0,n=await f();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),pe(jt(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=>{ne(await bt({cwd:g(e,`--cwd`,``).trim()||void 0,commitCount:_(e,`--commit-count`,5),includeDiff:v(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 f();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),oe(pt({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)),l(await ht({path:j(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();t||(console.error(`Usage: aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`),process.exit(1));let n=await ue();switch(t){case`save`:{let t=e.shift()?.trim(),r=g(e,`--data`,``),i=g(e,`--notes`,``).trim()||void 0,a=r.trim()?``:await f();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),c(ot(n,t,xe(r||a),{notes:i}));return}case`load`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint load <id>`),process.exit(1));let r=at(n,t);if(!r){console.log(`No checkpoint found: ${t}`);return}c(r);return}case`list`:{let e=it(n);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=rt(n);if(!e){console.log(`No checkpoints saved.`);return}c(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],En=k(N(),`.aikit`),z=k(En,`daemon.json`),Dn=3210,B=F(`cli:daemon`);function On(){if(!S(z))return null;try{return JSON.parse(w(z,`utf-8`))}catch{return null}}function kn(e){S(En)||C(En,{recursive:!0});let t=`${z}.tmp`;D(t,JSON.stringify(e,null,2)),we(t,z)}function V(){S(z)&&E(z)}async function H(e){try{return process.kill(e,0),!0}catch{return!1}}async function An(e){try{return(await fetch(`http://127.0.0.1:${e}/health`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}async function jn(e,t){let n=Date.now();for(B.debug(`Polling health endpoint on port ${e}...`);Date.now()-n<t;){if(await An(e))return B.debug(`Daemon health check passed`),!0;await new Promise(e=>setTimeout(e,200))}return!1}async function Mn(){let e=On();if(!e)return B.info(`Daemon is not running`),null;if(!await H(e.pid))return V(),B.debug(`Daemon was not running (stale state cleaned up)`),{pid:e.pid,wasRunning:!1};B.debug(`Sending SIGTERM to daemon...`);try{process.kill(e.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(e.pid)&&(B.debug(`Sending SIGKILL to daemon...`),process.kill(e.pid,`SIGKILL`))}catch{}return V(),{pid:e.pid,wasRunning:!0}}async function Nn(e){let t=p();B.debug(`Spawning daemon process...`);let n=pn(process.execPath,[t,`--transport`,`http`,`--port`,String(e)],{stdio:`ignore`,detached:!0,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)}});n.unref(),await jn(e,3e4)||(B.error(`Daemon failed to start within 30 seconds`),n.kill(`SIGTERM`),process.exit(1));let r=ye();if(n.pid===void 0)throw Error(`Daemon child process has no PID`);return kn({port:e,pid:n.pid,version:r,startedAt:new Date().toISOString()}),{pid:n.pid,port:e}}const Pn=[{name:`daemon`,description:`Run AI Kit as a background HTTP daemon — survives IDE restarts, shares across windows (start|stop|status|restart)`,usage:`aikit daemon <start|stop|status|restart> [--port <port>]`,run:async e=>{let t=e[0];if(!t){console.error(`Usage: aikit daemon <start|stop|status|restart>`),console.error(``),console.error(`Commands:`),console.error(` start Start the AI Kit daemon`),console.error(` stop Stop the AI Kit daemon`),console.error(` status Show daemon status`),console.error(` restart Restart the AI Kit daemon`);return}switch(t){case`start`:{let t=On();if(t){if(await H(t.pid)&&await An(t.port)){B.info(`Daemon already running (PID ${t.pid}, port ${t.port})`);return}B.debug(`Cleaning up stale daemon state...`),V()}let n=e.indexOf(`--port`),r=await Nn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):Dn);B.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}case`stop`:{let e=await Mn();e?.wasRunning&&B.info(`Daemon stopped (PID ${e.pid})`);return}case`status`:{let e=On();if(!e){console.log(`Daemon: stopped`);return}if(!(await H(e.pid)&&await An(e.port))){V(),console.log(`Daemon: stopped (stale state cleaned up)`);return}console.log(`Daemon: running`),console.log(` PID: ${e.pid}`),console.log(` Port: ${e.port}`),console.log(` Version: ${e.version}`),console.log(` Started: ${e.startedAt}`);return}case`restart`:{let t=On();if(t){if(await H(t.pid)){B.debug(`Sending SIGTERM to daemon...`);try{process.kill(t.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(t.pid)&&(B.debug(`Sending SIGKILL to daemon...`),process.kill(t.pid,`SIGKILL`))}catch{}}V(),B.info(`Daemon stopped (PID ${t.pid})`)}else B.info(`Daemon is not running`);let n=e.indexOf(`--port`),r=await Nn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):Dn);B.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}default:console.error(`Unknown daemon command: ${t}`),console.error("Use `aikit daemon` for help.")}}}],Fn=[{name:`diagram`,description:`Render a diagram from structured JSON input. Reads stdin, produces HTML + markdown + SVG.`,usage:`aikit diagram [--type <type>] [--output <dir>] [--title <title>] [--subtitle <subtitle>] [--palette warm|technical] [--format all|html|md|svg] < input.json`,run:async e=>{let t=U(e,`--type`),n=U(e,`--output`),r=U(e,`--title`),i=U(e,`--subtitle`),a=U(e,`--format`)??`all`,o=U(e,`--palette`),s=``,c=process.stdin;c.setEncoding(`utf-8`);for await(let e of c)s+=e;s.trim()||(console.error(`No input provided. Pipe diagram JSON to stdin.`),console.error(`Usage: aikit diagram [--type <type>] [--output <dir>] < input.json`),process.exit(1));let l;try{l=JSON.parse(s)}catch(e){console.error(`Invalid JSON: ${e.message}`),process.exit(1)}let u=l.meta??{};t&&l.diagram_type!==t&&(console.error(`Error: --type "${t}" does not match input diagram_type "${l.diagram_type}". Remove --type or use the correct type. Mutating the discriminator produces invalid output.`),process.exit(1)),o&&(o!==`warm`&&o!==`technical`&&(console.error(`Invalid palette "${o}". Expected "warm" or "technical".`),process.exit(1)),u.palette&&u.palette!==o&&console.warn(`Warning: --palette "${o}" overrides input meta.palette "${String(u.palette)}"`),l.meta={...u,palette:o});try{let e=hn(l,{title:r||void 0,subtitle:i||void 0,dualOutput:!0});if(n){let t=j(n);await Ye(t,{recursive:!0});let i=gn(r||l.meta?.title||`diagram`);if(a===`all`||a===`html`){let n=k(t,`${i}.html`);await L(n,e.html,`utf-8`),console.log(`Written: ${n}`)}if((a===`all`||a===`md`)&&e.markdown){let n=k(t,`${i}.md`);await L(n,e.markdown,`utf-8`),console.log(`Written: ${n}`)}if(a===`all`||a===`svg`){let n=mn(e.html);if(n){let e=k(t,`${i}.svg`);await L(e,n,`utf-8`),console.log(`Written: ${e}`)}}}else process.stdout.write(e.html)}catch(e){console.error(`Rendering failed: ${e.message}`),process.exit(1)}}}];function U(e,t){let n=e.indexOf(t);if(n>=0&&n+1<e.length)return e[n+1]}function In(e){let t=``,n=0,r=e.length;for(;n<r;)if(e[n]===`"`){for(t+=`"`,n++;n<r&&e[n]!==`"`;)e[n]===`\\`&&(t+=e[n++]),n<r&&(t+=e[n++]);n<r&&(t+=e[n++])}else if(e[n]===`/`&&n+1<r&&e[n+1]===`/`)for(n+=2;n<r&&e[n]!==`
4
- `;)n++;else if(e[n]===`/`&&n+1<r&&e[n+1]===`*`){for(n+=2;n+1<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2}else t+=e[n++];return t.replace(/,(\s*[}\]])/g,`$1`)}var W=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!S(t))return{};let n=await Xe(t,`utf-8`);try{return JSON.parse(In(n))}catch{throw Error(`Invalid JSON in ${t}. Please fix or remove the file before retrying.`)}}async writeConfig(e,t){let n=this.getConfigPath(t),r=O(n),i=k(r,`.aikit-tmp-${_n()}.json`);await Ye(r,{recursive:!0});try{await L(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await Ze(i,n)}catch(e){try{await $e(i)}catch{}throw e}}async registerMcp(e,t,n){let r=await this.readConfig(n);r[this.configKey]||(r[this.configKey]={}),r[this.configKey][e]=t,await this.writeConfig(r,n)}async unregisterMcp(e,t){let n=await this.readConfig(t);n[this.configKey]&&(delete n[this.configKey][e],await this.writeConfig(n,t))}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}},Ln=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule().resolve(N());return S(this.getPathModule().resolve(e,`.claude.json`))||S(this.getPathModule().resolve(e,`.claude`))}getConfigPath(){return this.getPathModule().resolve(N(),`.claude.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:e.resolve(t,`hooks`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?M:A}},Rn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},G=class extends W{family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;hasInstructions=!1;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getConfigDir();if(process.platform===`darwin`){let t=this.getMacAppPath();return S(e)||t!==null&&S(t)}return S(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),hooks:e.resolve(t,`hooks`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=N();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?M:A}},zn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(j(N(),`.copilot`)):!1}getConfigPath(){return j(N(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return j(N(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=j(N(),`.copilot`);return{agents:j(e,`agents`),skills:j(e,`skills`),prompts:null,flows:j(e,`flows`),hooks:j(e,`hooks`),commands:null,instructions:j(N(),`.github`,`copilot-instructions.md`),manifest:j(e,`.aikit-scaffold.json`)}}},Bn=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Vn=class extends G{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Hn=class e extends W{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;if(S(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!S(t))return!1;try{return T(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return j(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ye(r,{recursive:!0});let i=t.args??[],a=i.indexOf(`-e`),o;if(a!==-1&&a+1<i.length){let t=i[a+1],n=j(r,`${e}-launcher.js`);await L(n,t,`utf-8`),o=[...i.slice(0,a),n,...i.slice(a+2)]}else o=[...i];let s={type:`stdio`,...t,args:o};await super.registerMcp(e,s,n)}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return t}getCopilotConfigDir(){let e=N();return process.platform===`win32`?j(process.env.LOCALAPPDATA??j(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`github-copilot`,`intellij`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=N();return process.platform===`win32`?j(process.env.APPDATA??j(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`JetBrains`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`JetBrains`)}},Un=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Wn=class extends G{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Gn=class extends G{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Kn=class extends G{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},qn=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Jn=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},Yn=class extends W{id=`hermes`;name=`Hermes Agent`;family=`hermes`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp_servers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule();return S(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!S(e))return{};let t=w(e,`utf-8`);try{return vn(t)??{}}catch{throw Error(`Invalid YAML in ${e}. Please fix or remove the file before retrying.`)}}async writeConfig(e){let t=this.getConfigPath(),n=this.getPathModule().dirname(t),r={};if(S(t))try{r=vn(w(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ye(n,{recursive:!0}),D(t,yn(r,{lineWidth:120}),`utf-8`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={command:t.command,args:t.args??[],enabled:!0},await this.writeConfig(n)}getScaffoldRoot(){return this.getHermesDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getHermesDir();return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}buildInstructionContent(e,t){return`# AI Kit — Hermes Agent Instructions
1
+ import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-BNPHP-QC.js";import{A as o,B as s,C as c,D as l,E as u,F as d,I as f,L as ee,M as te,N as ne,O as re,P as ie,R as ae,S as oe,T as se,_ as ce,a as p,b as le,c as ue,d as m,f as de,g as fe,h,i as g,j as pe,k as _,l as me,m as v,n as he,o as ge,p as y,r as _e,s as ve,t as ye,u as be,v as xe,w as Se,x as Ce,y as we,z as b}from"./templates-d2UQHjpi.js";import{copyFileSync as Te,existsSync as x,mkdirSync as S,readFileSync as C,readdirSync as w,renameSync as Ee,rmSync as T,statSync as De,unlinkSync as Oe,writeFileSync as E}from"node:fs";import{basename as ke,dirname as D,join as O,posix as k,relative as Ae,resolve as A,win32 as j}from"node:path";import{fileURLToPath as je}from"node:url";import{arch as Me,homedir as M,platform as Ne}from"node:os";import{AIKIT_PATHS as N,AIKIT_RUNTIME_PATHS as Pe,EMBEDDING_DEFAULTS as Fe,INSTALL_ARGS as Ie,cleanupOldVersions as Le,createLogger as P,getGlobalDataDir as Re,getPartitionDir as ze,isUserInstalled as Be,migrateLegacyWorkspaceLayout as Ve,registerWorkspace as He,safeCwd as F,safeCwdOrHome as Ue,saveRegistry as We}from"../../core/dist/index.js";import{initializeWasm as Ge}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ke}from"../../embeddings/dist/index.js";import{IncrementalIndexer as qe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Je,createSqliteAdapter as Ye,createStore as Xe}from"../../store/dist/index.js";import{mkdir as Ze,readFile as Qe,rename as $e,rm as et,unlink as tt,writeFile as I}from"node:fs/promises";import{addToWorkset as nt,audit as rt,check as it,checkpointLatest as at,checkpointList as ot,checkpointLoad as st,checkpointSave as ct,codemod as lt,compact as ut,dataTransform as dt,delegate as ft,delegateListModels as pt,deleteWorkset as mt,diffParse as ht,evaluate as gt,fileSummary as _t,find as vt,findDeadSymbols as yt,findExamples as bt,getWorkset as xt,gitContext as St,graphQuery as Ct,guide as wt,health as Tt,laneCreate as Et,laneDiff as Dt,laneDiscard as Ot,laneList as kt,laneMerge as At,laneStatus as jt,listWorksets as Mt,parseOutput as Nt,processList as Pt,processLogs as Ft,processStart as It,processStatus as Lt,processStop as Rt,queueClear as zt,queueCreate as Bt,queueDelete as Vt,queueDone as Ht,queueFail as Ut,queueGet as Wt,queueList as Gt,queueNext as Kt,queuePush as qt,removeFromWorkset as Jt,rename as Yt,replayClear as Xt,replayList as Zt,replayTrim as Qt,saveWorkset as $t,scopeMap as en,stashClear as tn,stashDelete as nn,stashGet as rn,stashList as an,stashSet as on,symbol as sn,testRun as cn,trace as ln,watchList as un,watchStart as dn,watchStop as fn}from"../../tools/dist/index.js";import{execFileSync as pn,execSync as L,fork as mn,spawn as hn}from"node:child_process";import{extractSvg as gn,renderToResult as _n,sanitizeTitle as vn}from"../../server/dist/index.js";import{randomUUID as yn}from"node:crypto";import{parse as bn,stringify as xn}from"yaml";function Sn(){let e=F(),t=process.env.AIKIT_CONFIG_PATH??(e&&x(A(e,`aikit.config.json`))?A(e,`aikit.config.json`):null),n=t?D(t):e??M();if(Ve(n),!t)return Cn();let r=C(t,`utf-8`),i;try{i=JSON.parse(r)}catch{console.error(`Failed to parse ${t} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let a=n;return i.sources=i.sources.map(e=>({...e,path:A(a,e.path)})),i.store.path=A(a,i.store.path),i.curated=i.curated??{path:N.aiCurated},i.curated.path=A(a,i.curated.path),i.onboardDir||=N.aiContext,i.onboardDir=A(a,i.onboardDir),i.stateDir||=N.state,i.stateDir=A(a,i.stateDir),wn(i,a),i}function Cn(){let e=process.env.AIKIT_WORKSPACE_ROOT??F()??M();Ve(e);let 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:Fe.model,dimensions:Fe.dimensions},store:{backend:`sqlite-vec`,path:A(e,N.data)},curated:{path:A(e,N.aiCurated)},onboardDir:A(e,N.aiContext),stateDir:A(e,N.state)};return wn(t,e),t}function wn(e,t){if(!Be())return;let n=He(t);e.store.path=A(ze(n.partition),Pe.data),e.stateDir=A(ze(n.partition),Pe.state),e.onboardDir=A(ze(n.partition),Pe.onboard),e.curated={path:A(ze(n.partition),Pe.curated)}}async function Tn(){let e=Sn(),t=new Ke({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=A(e.store.path,`aikit.db`),r=D(t);if(!x(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await Ye(t)}let r=await Xe({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new qe(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new Je({adapter:n}):new Je({path:e.store.path});await t.initialize(),s=t,i.setGraphStore(s)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),s={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNodes:async()=>[],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 Ge().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const En=[{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()??``;if(!t||!n)throw new m(`Usage: aikit analyze <type> <path>
2
+ Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`);let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:l}=await import(`../../analyzers/dist/index.js`),u=A(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(F()??M(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:throw new m(`Unknown analyze type: ${t}\nTypes: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`)}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||=F()??M();let a=A(n),o=Sn();console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
3
+ `);let s=await t({path:a,mode:r,outDir:i??o.onboardDir});for(let e of s.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: ${s.totalDurationMs}ms`),s.outDir&&console.log(`Output written to: ${s.outDir}`)}}],Dn=[{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=h(e,`--tool`,``).trim()||void 0,n=await f();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),pe(Nt(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=>{re(await St({cwd:h(e,`--cwd`,``).trim()||void 0,commitCount:v(e,`--commit-count`,5),includeDiff:y(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 f();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),se(ht({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)),l(await _t({path:A(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();t||(console.error(`Usage: aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`),process.exit(1));let n=await de();switch(t){case`save`:{let t=e.shift()?.trim(),r=h(e,`--data`,``),i=h(e,`--notes`,``).trim()||void 0,a=r.trim()?``:await f();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),c(ct(n,t,Ce(r||a),{notes:i}));return}case`load`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint load <id>`),process.exit(1));let r=st(n,t);if(!r){console.log(`No checkpoint found: ${t}`);return}c(r);return}case`list`:{let e=ot(n);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=at(n);if(!e){console.log(`No checkpoints saved.`);return}c(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],On=O(M(),`.aikit`),R=O(On,`daemon.json`),kn=3210,z=P(`cli:daemon`);function An(){if(!x(R))return null;try{return JSON.parse(C(R,`utf-8`))}catch{return null}}function jn(e){x(On)||S(On,{recursive:!0});let t=`${R}.tmp`;E(t,JSON.stringify(e,null,2)),Ee(t,R)}function B(){x(R)&&T(R)}async function V(e){try{return process.kill(e,0),!0}catch{return!1}}async function Mn(e){try{return(await fetch(`http://127.0.0.1:${e}/health`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}async function Nn(e,t){let n=Date.now();for(z.debug(`Polling health endpoint on port ${e}...`);Date.now()-n<t;){if(await Mn(e))return z.debug(`Daemon health check passed`),!0;await new Promise(e=>setTimeout(e,200))}return!1}async function Pn(){let e=An();if(!e)return z.info(`Daemon is not running`),null;if(!await V(e.pid))return B(),z.debug(`Daemon was not running (stale state cleaned up)`),{pid:e.pid,wasRunning:!1};z.debug(`Sending SIGTERM to daemon...`);try{process.kill(e.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await V(e.pid)&&(z.debug(`Sending SIGKILL to daemon...`),process.kill(e.pid,`SIGKILL`))}catch{}return B(),{pid:e.pid,wasRunning:!0}}async function Fn(e){let t=ee();z.debug(`Spawning daemon process...`);let n=hn(process.execPath,[t,`--transport`,`http`,`--port`,String(e)],{stdio:`ignore`,detached:!0,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)}});n.unref(),await Nn(e,3e4)||(z.error(`Daemon failed to start within 30 seconds`),n.kill(`SIGTERM`),process.exit(1));let r=xe();if(n.pid===void 0)throw Error(`Daemon child process has no PID`);return jn({port:e,pid:n.pid,version:r,startedAt:new Date().toISOString()}),{pid:n.pid,port:e}}const In=[{name:`daemon`,description:`Run AI Kit as a background HTTP daemon — survives IDE restarts, shares across windows (start|stop|status|restart)`,usage:`aikit daemon <start|stop|status|restart> [--port <port>]`,run:async e=>{let t=e[0];if(!t){console.error(`Usage: aikit daemon <start|stop|status|restart>`),console.error(``),console.error(`Commands:`),console.error(` start Start the AI Kit daemon`),console.error(` stop Stop the AI Kit daemon`),console.error(` status Show daemon status`),console.error(` restart Restart the AI Kit daemon`);return}switch(t){case`start`:{let t=An();if(t){if(await V(t.pid)&&await Mn(t.port)){z.info(`Daemon already running (PID ${t.pid}, port ${t.port})`);return}z.debug(`Cleaning up stale daemon state...`),B()}let n=e.indexOf(`--port`),r=await Fn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):kn);z.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}case`stop`:{let e=await Pn();e?.wasRunning&&z.info(`Daemon stopped (PID ${e.pid})`);return}case`status`:{let e=An();if(!e){console.log(`Daemon: stopped`);return}if(!(await V(e.pid)&&await Mn(e.port))){B(),console.log(`Daemon: stopped (stale state cleaned up)`);return}console.log(`Daemon: running`),console.log(` PID: ${e.pid}`),console.log(` Port: ${e.port}`),console.log(` Version: ${e.version}`),console.log(` Started: ${e.startedAt}`);return}case`restart`:{let t=An();if(t){if(await V(t.pid)){z.debug(`Sending SIGTERM to daemon...`);try{process.kill(t.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await V(t.pid)&&(z.debug(`Sending SIGKILL to daemon...`),process.kill(t.pid,`SIGKILL`))}catch{}}B(),z.info(`Daemon stopped (PID ${t.pid})`)}else z.info(`Daemon is not running`);let n=e.indexOf(`--port`),r=await Fn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):kn);z.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}default:console.error(`Unknown daemon command: ${t}`),console.error("Use `aikit daemon` for help.")}}}],Ln=[{name:`diagram`,description:`Render a diagram from structured JSON input. Reads stdin, produces HTML + markdown + SVG.`,usage:`aikit diagram [--type <type>] [--output <dir>] [--title <title>] [--subtitle <subtitle>] [--palette warm|technical] [--format all|html|md|svg] < input.json`,run:async e=>{let t=H(e,`--type`),n=H(e,`--output`),r=H(e,`--title`),i=H(e,`--subtitle`),a=H(e,`--format`)??`all`,o=H(e,`--palette`),s=``,c=process.stdin;c.setEncoding(`utf-8`);for await(let e of c)s+=e;s.trim()||(console.error(`No input provided. Pipe diagram JSON to stdin.`),console.error(`Usage: aikit diagram [--type <type>] [--output <dir>] < input.json`),process.exit(1));let l;try{l=JSON.parse(s)}catch(e){console.error(`Invalid JSON: ${e.message}`),process.exit(1)}let u=l.meta??{};t&&l.diagram_type!==t&&(console.error(`Error: --type "${t}" does not match input diagram_type "${l.diagram_type}". Remove --type or use the correct type. Mutating the discriminator produces invalid output.`),process.exit(1)),o&&(o!==`warm`&&o!==`technical`&&(console.error(`Invalid palette "${o}". Expected "warm" or "technical".`),process.exit(1)),u.palette&&u.palette!==o&&console.warn(`Warning: --palette "${o}" overrides input meta.palette "${String(u.palette)}"`),l.meta={...u,palette:o});try{let e=_n(l,{title:r||void 0,subtitle:i||void 0,dualOutput:!0});if(n){let t=A(n);await Ze(t,{recursive:!0});let i=vn(r||l.meta?.title||`diagram`);if(a===`all`||a===`html`){let n=O(t,`${i}.html`);await I(n,e.html,`utf-8`),console.log(`Written: ${n}`)}if((a===`all`||a===`md`)&&e.markdown){let n=O(t,`${i}.md`);await I(n,e.markdown,`utf-8`),console.log(`Written: ${n}`)}if(a===`all`||a===`svg`){let n=gn(e.html);if(n){let e=O(t,`${i}.svg`);await I(e,n,`utf-8`),console.log(`Written: ${e}`)}}}else process.stdout.write(e.html)}catch(e){console.error(`Rendering failed: ${e.message}`),process.exit(1)}}}];function H(e,t){let n=e.indexOf(t);if(n>=0&&n+1<e.length)return e[n+1]}function Rn(e){let t=``,n=0,r=e.length;for(;n<r;)if(e[n]===`"`){for(t+=`"`,n++;n<r&&e[n]!==`"`;)e[n]===`\\`&&(t+=e[n++]),n<r&&(t+=e[n++]);n<r&&(t+=e[n++])}else if(e[n]===`/`&&n+1<r&&e[n+1]===`/`)for(n+=2;n<r&&e[n]!==`
4
+ `;)n++;else if(e[n]===`/`&&n+1<r&&e[n+1]===`*`){for(n+=2;n+1<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2}else t+=e[n++];return t.replace(/,(\s*[}\]])/g,`$1`)}var U=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!x(t))return{};let n=await Qe(t,`utf-8`);try{return JSON.parse(Rn(n))}catch{throw Error(`Invalid JSON in ${t}. Please fix or remove the file before retrying.`)}}async writeConfig(e,t){let n=this.getConfigPath(t),r=D(n),i=O(r,`.aikit-tmp-${yn()}.json`);await Ze(r,{recursive:!0});try{await I(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await $e(i,n)}catch(e){try{await tt(i)}catch{}throw e}}async registerMcp(e,t,n){let r=await this.readConfig(n);r[this.configKey]||(r[this.configKey]={}),r[this.configKey][e]=t,await this.writeConfig(r,n)}async unregisterMcp(e,t){let n=await this.readConfig(t);n[this.configKey]&&(delete n[this.configKey][e],await this.writeConfig(n,t))}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}};const zn=`Orchestrator`;var Bn=class extends U{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule().resolve(M());return x(this.getPathModule().resolve(e,`.claude.json`))||x(this.getPathModule().resolve(e,`.claude`))}getConfigPath(){return this.getPathModule().resolve(M(),`.claude.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:e.resolve(t,`hooks`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}async registerMcp(e,t,n){await super.registerMcp(e,t,n);let r=this.getPathModule(),i=r.resolve(M(),`.claude`),a=r.resolve(i,`settings.json`),o;if(!x(a))S(i,{recursive:!0}),o={agent:zn};else try{o=JSON.parse(C(a,`utf-8`))}catch{o={}}o.agent=zn;let s=r.resolve(i,`hooks`,`scripts`).replace(/\\/g,`/`);try{let e=ue(`claude`,s);e.hooks&&Object.keys(e.hooks).length>0&&(o.hooks=e.hooks)}catch{}E(a,`${JSON.stringify(o,null,2)}\n`,`utf-8`)}getPathModule(){return process.platform===`win32`?j:k}},Vn=class extends U{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?x(this.getPathModule().resolve(M(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?j:k}},W=class extends U{family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;hasInstructions=!1;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getConfigDir();if(process.platform===`darwin`){let t=this.getMacAppPath();return x(e)||t!==null&&x(t)}return x(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),hooks:e.resolve(t,`hooks`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=M();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?j:k}},Hn=class extends U{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?x(A(M(),`.copilot`)):!1}getConfigPath(){return A(M(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return A(M(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=A(M(),`.copilot`);return{agents:A(e,`agents`),skills:A(e,`skills`),prompts:null,flows:A(e,`flows`),hooks:A(e,`hooks`),commands:null,instructions:A(M(),`.github`,`copilot-instructions.md`),manifest:A(e,`.aikit-scaffold.json`)}}},Un=class extends W{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Wn=class extends W{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Gn=class e extends U{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;if(x(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!x(t))return!1;try{return w(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return A(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ze(r,{recursive:!0});let i=t.args??[],a=i.indexOf(`-e`),o;if(a!==-1&&a+1<i.length){let t=i[a+1],n=A(r,`${e}-launcher.js`);await I(n,t,`utf-8`),o=[...i.slice(0,a),n,...i.slice(a+2)]}else o=[...i];let s={type:`stdio`,...t,args:o};await super.registerMcp(e,s,n)}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return t}getCopilotConfigDir(){let e=M();return process.platform===`win32`?A(process.env.LOCALAPPDATA??A(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?A(e,`Library`,`Application Support`,`github-copilot`,`intellij`):A(process.env.XDG_CONFIG_HOME??A(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=M();return process.platform===`win32`?A(process.env.APPDATA??A(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?A(e,`Library`,`Application Support`,`JetBrains`):A(process.env.XDG_CONFIG_HOME??A(e,`.config`),`JetBrains`)}},Kn=class extends W{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.md`)}},qn=class extends W{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Jn=class extends W{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Yn=class extends W{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Xn=class extends W{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.md`)}},Zn=class extends U{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?x(this.getPathModule().resolve(M(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?j:k}},Qn=class extends U{id=`hermes`;name=`Hermes Agent`;family=`hermes`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp_servers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule();return x(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!x(e))return{};let t=C(e,`utf-8`);try{return bn(t)??{}}catch{throw Error(`Invalid YAML in ${e}. Please fix or remove the file before retrying.`)}}async writeConfig(e){let t=this.getConfigPath(),n=this.getPathModule().dirname(t),r={};if(x(t))try{r=bn(C(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ze(n,{recursive:!0}),E(t,xn(r,{lineWidth:120}),`utf-8`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={command:t.command,args:t.args??[],enabled:!0},await this.writeConfig(n)}getScaffoldRoot(){return this.getHermesDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getHermesDir();return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}buildInstructionContent(e,t){return`# AI Kit — Hermes Agent Instructions
5
5
 
6
6
  This project has an **AI Kit** MCP server (\`aikit\`) providing 64 tools for search, code analysis,
7
7
  persistent memory, context compression, and guided development flows.
@@ -14,7 +14,7 @@ at session start and available as \`mcp_aikit_*\` prefixed tool calls.
14
14
  1. **AI Kit tools are available immediately** — they appear as \`mcp_aikit_search\`, \`mcp_aikit_file_summary\`, etc.
15
15
  2. **Prefer AI Kit tools over raw shell/file operations** — they provide structured, token-efficient results
16
16
  3. **Check for active flows** — use \`mcp_aikit_flow\` with action: 'status' to see if a guided workflow is running
17
- 4. **Use context compression** — \`mcp_aikit_file_summary\` (T1=structure, T2=structure+content), \`mcp_aikit_digest\` reduce token consumption 5-20x\n\n---\n\n${t}`}getHermesDir(e){let t=e??this.getPathModule();if(process.platform===`win32`){let e=process.env.LOCALAPPDATA??t.resolve(N(),`AppData`,`Local`);return t.resolve(e,`hermes`)}return t.resolve(N(),`.hermes`)}getPathModule(){return process.platform===`win32`?M:A}},Xn=class extends W{id=`opencode`;name=`OpenCode`;family=`opencode`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule(),t=N();return[e.resolve(t,`.config`,`opencode`),e.resolve(t,`.opencode`)].some(e=>S(e))}getConfigPath(){return this.getPathModule().resolve(N(),`.config`,`opencode`,`opencode.jsonc`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={type:`local`,command:[t.command,...t.args||[]]},await this.writeConfig(n)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.config`,`opencode`)}getScaffoldPaths(){let e=this.getPathModule(),t=this.getScaffoldRoot();return t?{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`OPENCODE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}:super.getScaffoldPaths()}getPathModule(){return process.platform===`win32`?M:A}},Zn=class extends W{id=`zed`;name=`Zed`;family=`zed`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`context_servers`;async detect(){return this.isPlatformSupported()?S(this.getConfigDir()):!1}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`settings.json`)}async registerMcp(e,t){let{type:n,...r}=t,i={...r,env:r.env??{}};await super.registerMcp(e,i)}getScaffoldRoot(){return this.getConfigDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getConfigDir();return{agents:e.resolve(t,`prompts`),skills:null,prompts:e.resolve(t,`prompts`),flows:null,commands:null,instructions:null,manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getConfigDir(){let e=this.getPathModule();return process.platform===`win32`?e.resolve(process.env.APPDATA||N(),`Zed`):e.resolve(N(),`.config`,`zed`)}getPathModule(){return process.platform===`win32`?M:A}};const Qn=[new Wn,new Gn,new Kn,new Bn,new Vn,new qn,new Un,new zn,new Hn,new Ln,new Jn,new Rn,new Zn,new Xn,new Yn];async function $n(e){let t=e?.scope?Qn.filter(t=>t.scope===e.scope):Qn;return(await Promise.allSettled(t.map(async e=>await e.detect()?e:null))).flatMap(e=>e.status!==`fulfilled`||e.value===null?[]:[e.value])}const K=F(`cli:install`),er=/^\d+\.\d+\.\d+(-[\w.+]+)?(\+[\w.]+)?$/,q=k(N(),`.aikit`),J=k(q,`versions`),tr=k(q,`current-version.json`),nr=`@vpxa/aikit`,rr=`Usage:
17
+ 4. **Use context compression** — \`mcp_aikit_file_summary\` (T1=structure, T2=structure+content), \`mcp_aikit_digest\` reduce token consumption 5-20x\n\n---\n\n${t}`}getHermesDir(e){let t=e??this.getPathModule();if(process.platform===`win32`){let e=process.env.LOCALAPPDATA??t.resolve(M(),`AppData`,`Local`);return t.resolve(e,`hermes`)}return t.resolve(M(),`.hermes`)}getPathModule(){return process.platform===`win32`?j:k}},$n=class extends U{id=`opencode`;name=`OpenCode`;family=`opencode`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule(),t=M();return[e.resolve(t,`.config`,`opencode`),e.resolve(t,`.opencode`)].some(e=>x(e))}getConfigPath(){return this.getPathModule().resolve(M(),`.config`,`opencode`,`opencode.jsonc`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={type:`local`,command:[t.command,...t.args||[]]},await this.writeConfig(n)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.config`,`opencode`)}getScaffoldPaths(){let e=this.getPathModule(),t=this.getScaffoldRoot();return t?{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`OPENCODE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}:super.getScaffoldPaths()}getPathModule(){return process.platform===`win32`?j:k}},er=class extends U{id=`zed`;name=`Zed`;family=`zed`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`context_servers`;async detect(){return this.isPlatformSupported()?x(this.getConfigDir()):!1}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`settings.json`)}async registerMcp(e,t){let{type:n,...r}=t,i={...r,env:r.env??{}};await super.registerMcp(e,i)}getScaffoldRoot(){return this.getConfigDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getConfigDir();return{agents:e.resolve(t,`prompts`),skills:null,prompts:e.resolve(t,`prompts`),flows:null,commands:null,instructions:null,manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getConfigDir(){let e=this.getPathModule();return process.platform===`win32`?e.resolve(process.env.APPDATA||M(),`Zed`):e.resolve(M(),`.config`,`zed`)}getPathModule(){return process.platform===`win32`?j:k}};const tr=[new qn,new Jn,new Yn,new Un,new Wn,new Xn,new Kn,new Hn,new Gn,new Bn,new Zn,new Vn,new er,new $n,new Qn];async function nr(e){let t=e?.scope?tr.filter(t=>t.scope===e.scope):tr;return(await Promise.allSettled(t.map(async e=>await e.detect()?e:null))).flatMap(e=>e.status!==`fulfilled`||e.value===null?[]:[e.value])}const G=P(`cli:install`),rr=/^\d+\.\d+\.\d+(-[\w.+]+)?(\+[\w.]+)?$/,K=O(M(),`.aikit`),q=O(K,`versions`),ir=O(K,`current-version.json`),ar=`@vpxa/aikit`,or=`Usage:
18
18
  aikit install
19
19
  aikit install --version <version>
20
20
  aikit install --offline <path-to-tarball>
@@ -36,24 +36,24 @@ After install, verify with:
36
36
  Options:
37
37
  --version <version> Install a specific version instead of latest
38
38
  --offline <path> Install from a local tarball (no network needed)
39
- --help, -h Show this help`;function ir(e){if(!er.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}async function ar(){let e=await fetch(`https://registry.npmjs.org/${nr}/latest`,{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw Error(`Failed to fetch latest version from npm registry (HTTP ${e.status})`);let t=await e.json();if(!t.version)throw Error(`npm registry response missing "version" field`);return t.version}function or(e){let t=k(e,`packages`,`server`,`dist`,`bin.js`);if(!S(t))throw Error(`Server entry point not found at ${t}. The installation may be incomplete or corrupted.`);let n=k(e,`node_modules`);if(!S(n))throw Error(`node_modules not found at ${n}. Production dependencies may not have been installed.`)}function sr(e){let t=k(e,`package.json`),n=JSON.parse(w(t,`utf-8`));if(!n.version)throw Error(`No "version" field in ${t}`);return n.version}function cr(e){S(q)||C(q,{recursive:!0});let t=k(q,`current-version.json.tmp`);D(t,`${JSON.stringify({version:e},null,2)}\n`),we(t,tr)}function lr(e){let t=T(e).filter(e=>e.endsWith(`.tgz`));return t.length>0?t[0]:null}function ur(e,t){K.debug(`Extracting...`),R(`tar -xzf "${t}"`,{cwd:e,stdio:`pipe`,timeout:6e4});let n=k(e,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);return K.debug(`Installing production dependencies...`),R(`npm ${Pe.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5}),n}function dr(e,t){let n=k(J,`v${t}`);S(J)||C(J,{recursive:!0}),S(n)&&(K.debug(`Removing previous installation...`,{target:n}),E(n,{recursive:!0})),we(e,n),cr(t),Fe(J,t),K.debug(`Installation complete`,{package:`${nr}@${t}`,target:n})}function fr(){let e={win32:`win32`,darwin:`darwin`,linux:`linux`},t={x64:`x64`,arm64:`arm64`},n=e[je()],r=t[Ae()];return!n||!r?(K.warn(`Unknown platform, falling back to npm pack`,{platform:je(),arch:Ae()}),``):`${n}-${r}`}function pr(e){let t=fr();if(!t)return null;let n=`aikit-v${e}-${t}.tar.gz`,r=k(k(q,`cache`,`tarballs`),n);return S(r)?r:null}function mr(e,t){let n=k(J,`v${t}-staging`);S(n)&&E(n,{recursive:!0}),C(n,{recursive:!0});try{K.debug(`Extracting prebuilt tarball...`),R(`tar -xzf "${e}"`,{cwd:n,stdio:`pipe`,timeout:6e4});let r=k(n,`aikit-v${t}-${fr()}`);if(!S(r)){let e=k(n,`package`);if(S(e)){K.debug(`Validating installation...`),or(e),dr(e,t);return}throw Error(`Expected directory not found after extracting prebuilt tarball`)}K.debug(`Validating installation...`),or(r),dr(r,t)}finally{S(n)&&E(n,{recursive:!0})}}function hr(e){ir(e);let t=pr(e);if(t){K.debug(`Found prebuilt tarball`,{path:t}),mr(t,e);return}let n=k(J,`v${e}-staging`);S(n)&&E(n,{recursive:!0}),C(n,{recursive:!0});try{K.debug(`Downloading...`,{package:`${nr}@${e}`}),R(`npm pack ${nr}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:n,stdio:`pipe`,timeout:12e4});let t=lr(n);if(!t)throw Error(`No .tgz file found after npm pack`);let r=ur(n,t);K.debug(`Validating installation...`),or(r),dr(r,e)}finally{S(n)&&E(n,{recursive:!0})}}function gr(e){ir(e);let t=k(J,`v${e}`);try{or(t),cr(e)}catch{hr(e)}}function _r(e){if(!S(e))throw Error(`Tarball not found: ${e}`);let t=k(J,`_offline-detect-${Date.now()}`);C(t,{recursive:!0});let n;try{R(`tar -xzf "${e}"`,{cwd:t,stdio:`pipe`,timeout:6e4}),n=sr(k(t,`package`))}finally{S(t)&&E(t,{recursive:!0})}K.debug(`Installing from local tarball...`,{package:`${nr}@${n}`});let r=k(J,`v${n}-staging`);S(r)&&E(r,{recursive:!0}),C(r,{recursive:!0});try{Ce(e,k(r,`offline-${n}.tgz`));let t=ur(r,`offline-${n}.tgz`);return K.debug(`Validating installation...`),or(t),dr(t,n),n}finally{S(r)&&E(r,{recursive:!0})}}async function vr(e){try{let t=k(J,`v${e}`,`packages`,`server`,`dist`,`bin.js`);if(!S(t)){K.warn(`Server entry not found — skipping MCP registration`,{serverPath:t});return}let n={command:y.command,args:y.args?[...y.args]:void 0,type:y.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=dn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(n.command=e)}catch{}}let r=await $n({scope:`user`});if(r.length===0){K.info(`No supported IDEs detected for MCP registration`);return}let i=0;for(let e of r)try{await e.registerMcp(m,n),i++}catch(t){K.warn(`Failed to register MCP for ${e.name}`,{error:t.message})}i>0&&K.info(`MCP server configured for ${i} IDE(s) — using version-neutral launcher`)}catch(e){K.warn(`MCP registration failed`,{error:e.message})}}const yr=[{name:`install`,description:`Install AI Kit to ~/.aikit/versions/ (one-time setup for fast local startup)`,usage:rr,run:async e=>{let t=e.indexOf(`--version`),n=e.indexOf(`--offline`),r=t!==-1&&t+1<e.length,i=n!==-1&&n+1<e.length;if(e.includes(`--help`)||e.includes(`-h`)){console.log(rr);return}if(i){let t=e[n+1];await vr(_r(t)),K.debug(`Install complete — restart your IDE to use the new version`);return}let a;r?a=e[t+1]:(K.debug(`Checking npm registry for latest version...`),a=await ar(),K.debug(`Latest version detected`,{version:a})),hr(a),await vr(a),K.debug(`Install complete — restart your IDE to use the new version`)}}];function br(){let e=xr();if(e)return e;let t={command:y.command,args:y.args?[...y.args]:void 0,type:y.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(t.env={PATH:e});try{let e=dn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(t.command=e)}catch{}}return t}function xr(){let e=k(N(),`.aikit`,`current-version.json`);if(!S(e))return null;try{let t=JSON.parse(w(e,`utf-8`));if(typeof t.version!=`string`||t.version.length===0||!S(k(k(N(),`.aikit`,`versions`,`v${t.version}`),`packages`,`server`,`dist`,`bin.js`)))return null;let n={command:y.command,args:y.args?[...y.args]:void 0,type:y.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=dn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&S(e)&&(n.command=e)}catch{}}return n}catch{return null}}const Sr=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function Cr(e,t,n){let r=j(N(),`.copilot`,`instructions`,`copilot-instructions.md`);!S(r)||n.has(r)||(C(O(r),{recursive:!0}),D(r,`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`,`utf-8`),n.add(r))}function wr(e,t=!1){if(!Sr.has(e.name))return;let n=j(O(e.getConfigPath()),`settings.json`),r={};if(S(n))try{let e=w(n,`utf-8`);r=JSON.parse(e)}catch{console.log(` ${e.name}: skipped settings.json (invalid JSON)`);return}let i=!1;for(let[e,n]of Object.entries(b))if(typeof n==`object`&&n){let t=typeof r[e]==`object`&&r[e]!==null?r[e]:{},a={...t,...n};JSON.stringify(a)!==JSON.stringify(t)&&(r[e]=a,i=!0)}else(t||!(e in r))&&(r[e]=n,i=!0);i&&(D(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.name}: updated settings.json`))}async function Tr(r,o,s,c,l=!1){let u=new Map,d=new Set,f=ge(`aikit`,s),p=ve(`aikit`,s);for(let e of o)e.getScaffoldRoot()!==null&&u.set(e.id,e);if(Cr(f,p,d),u.size===0){d.size>0?console.log(` Instruction files: ${[...d].join(`, `)}`):console.log(` No IDEs with global scaffold support detected.`);return}let ee=await n(r,`copilot`),te=await n(r,`opencode`),ne=await n(r,`hermes-agent`),re=await n(r,`claude-code`),ie=e=>{let t=new Map;for(let n of e){let e=n.path.indexOf(`/`);if(e===-1)continue;let r=n.path.substring(0,e);if(r===`agents`||r===`prompts`){let i=t.get(r)??[];i.push({path:n.path.substring(e+1),content:n.content}),t.set(r,i)}else if(r===`.opencode`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}else if(r===`.claude`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}}return t},ae=ie(ee),oe=ie(te),se=ie(ne),le=ie(re),m=await n(r,`skills`),h=new Set;for(let e of m){let t=e.path.indexOf(`/`);t!==-1&&h.add(e.path.substring(0,t))}let ue=await n(r,`flows`),de=new Set;for(let e of ue){let t=e.path.indexOf(`/`);t!==-1&&de.add(e.path.substring(0,t))}let g=await n(r,`claude-code`),pe=j(r,`scaffold`,`general`,`hooks`,`scripts`),me=S(pe)?pe:j(import.meta.dirname,`../../../../../scaffold/general/hooks/scripts`),he=ce(),_=new Set,_e=new Set,v=new Set,y=(n,r,o,s)=>{let u=s.get(o);if(!n||!r||!u||u.length===0)return;let d=`${o}:${r}:${n}`;if(_.has(d))return;_.add(d);let f=e(r)??a(c);f.version=c,i(u,n,f,o,l),t(r,f),v.add(O(r))},b=(n,r,o,s)=>{if(!n||!r||s.length===0)return;let u=`${o}:${r}:${n}`;if(_.has(u))return;if(_.add(u),o===`flows`&&!_e.has(n)){for(let e of de){let t=j(n,e,`skills`);S(t)&&(E(t,{recursive:!0,force:!0}),console.log(` ${O(r)}: migrated ${e} flow to steps/ layout`))}_e.add(n)}let d=e(r)??a(c);d.version=c,i(s,n,d,o,l),t(r,d),v.add(O(r))},ye=(e,t,n)=>{!e||!t||b(e,t,`hooks`,[...fe(n,j(e,`scripts`).replace(/\\/g,`/`)),...he.map(e=>({path:`scripts/${e}`,content:w(j(me,e),`utf-8`)}))])};for(let e of u.values()){let t=e.getScaffoldPaths(),n=e.family===`opencode`?oe:e.family===`hermes`?se:e.family===`claude`?le:ae;y(t.agents,t.manifest,`agents`,n),y(t.prompts,t.manifest,`prompts`,n),b(t.skills,t.manifest,`skills`,m),b(t.flows,t.manifest,`flows`,ue),b(t.commands,t.manifest,`commands`,g),ye(t.hooks,t.manifest,e.family===`claude`?`claude`:`copilot`)}for(let e of v)console.log(` ${e}: scaffold updated (${h.size} skills)`);for(let e of u.values()){let t=e.getScaffoldPaths().instructions;!t||d.has(t)||(C(O(t),{recursive:!0}),D(t,e.buildInstructionContent(f,p),`utf-8`),d.add(t))}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}function Er(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e){if(Sr.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(j(r,`kb.instructions.md`)),t.push(j(r,`aikit.instructions.md`))}else if(n.name===`Cursor`||n.name===`Cursor Nightly`)t.push(j(e,`rules`,`kb.mdc`));else if(n.name===`Windsurf`)t.push(j(e,`rules`,`kb.md`));else if(n.family===`claude`){let n=j(e,`agents`);if(S(n)){for(let e of T(n))if(e.endsWith(`.agent.md`)){let r=j(n,e);Ee(r),t.push(r)}}}}}for(let e of t)S(e)&&(Ee(e),console.log(` Removed legacy file: ${e}`))}async function Dr(e){let t=m,n=se(),r=JSON.parse(w(j(n,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${r}...\n`);let i=Ie();C(i,{recursive:!0}),console.log(` Global data store: ${i}`),console.log(` Managed runtime: v${r}`),gr(r),He({version:1,workspaces:{}}),console.log(` Created registry.json`);let a=await $n({scope:`user`});if(a.length===0)console.log(`
40
- No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${a.length} IDE(s):`);let n=xr();if(!n)throw Error(`Managed runtime v${r} was installed but its MCP server entry could not be resolved.`);for(let e of a)try{await e.registerMcp(t,n),console.log(` ${e.name}: configured ${t}`)}catch(t){console.log(` ${e.name}: failed to configure (${t.message})`)}for(let t of a)wr(t,e.force)}console.log(`
41
- Installing scaffold files:`),await Tr(n,a,t,r,e.force),Er(a),console.log(`
39
+ --help, -h Show this help`;function sr(e){if(!rr.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}async function cr(){let e=await fetch(`https://registry.npmjs.org/${ar}/latest`,{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw Error(`Failed to fetch latest version from npm registry (HTTP ${e.status})`);let t=await e.json();if(!t.version)throw Error(`npm registry response missing "version" field`);return t.version}function lr(e){let t=O(e,`packages`,`server`,`dist`,`bin.js`);if(!x(t))throw Error(`Server entry point not found at ${t}. The installation may be incomplete or corrupted.`);let n=O(e,`node_modules`);if(!x(n))throw Error(`node_modules not found at ${n}. Production dependencies may not have been installed.`)}function ur(e){let t=O(e,`package.json`),n=JSON.parse(C(t,`utf-8`));if(!n.version)throw Error(`No "version" field in ${t}`);return n.version}function dr(e){x(K)||S(K,{recursive:!0});let t=O(K,`current-version.json.tmp`);E(t,`${JSON.stringify({version:e},null,2)}\n`),Ee(t,ir)}function fr(e){let t=w(e).filter(e=>e.endsWith(`.tgz`));return t.length>0?t[0]:null}function pr(e,t){G.debug(`Extracting...`),L(`tar -xzf "${t}"`,{cwd:e,stdio:`pipe`,timeout:6e4});let n=O(e,`package`);if(!x(n))throw Error(`Expected "package/" directory not found after extraction`);return G.debug(`Installing production dependencies...`),L(`npm ${Ie.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5}),n}function mr(e,t){let n=O(q,`v${t}`);x(q)||S(q,{recursive:!0}),x(n)&&(G.debug(`Removing previous installation...`,{target:n}),T(n,{recursive:!0})),Ee(e,n),dr(t),Le(q,t),G.debug(`Installation complete`,{package:`${ar}@${t}`,target:n})}function hr(){let e={win32:`win32`,darwin:`darwin`,linux:`linux`},t={x64:`x64`,arm64:`arm64`},n=e[Ne()],r=t[Me()];return!n||!r?(G.warn(`Unknown platform, falling back to npm pack`,{platform:Ne(),arch:Me()}),``):`${n}-${r}`}function gr(e){let t=hr();if(!t)return null;let n=`aikit-v${e}-${t}.tar.gz`,r=O(O(K,`cache`,`tarballs`),n);return x(r)?r:null}function _r(e,t){let n=O(q,`v${t}-staging`);x(n)&&T(n,{recursive:!0}),S(n,{recursive:!0});try{G.debug(`Extracting prebuilt tarball...`),L(`tar -xzf "${e}"`,{cwd:n,stdio:`pipe`,timeout:6e4});let r=O(n,`aikit-v${t}-${hr()}`);if(!x(r)){let e=O(n,`package`);if(x(e)){G.debug(`Validating installation...`),lr(e),mr(e,t);return}throw Error(`Expected directory not found after extracting prebuilt tarball`)}G.debug(`Validating installation...`),lr(r),mr(r,t)}finally{x(n)&&T(n,{recursive:!0})}}function vr(e){sr(e);let t=gr(e);if(t){G.debug(`Found prebuilt tarball`,{path:t}),_r(t,e);return}let n=O(q,`v${e}-staging`);x(n)&&T(n,{recursive:!0}),S(n,{recursive:!0});try{G.debug(`Downloading...`,{package:`${ar}@${e}`}),L(`npm pack ${ar}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:n,stdio:`pipe`,timeout:12e4});let t=fr(n);if(!t)throw Error(`No .tgz file found after npm pack`);let r=pr(n,t);G.debug(`Validating installation...`),lr(r),mr(r,e)}finally{x(n)&&T(n,{recursive:!0})}}function yr(e){sr(e);let t=O(q,`v${e}`);try{lr(t),dr(e)}catch{vr(e)}}function br(e){if(!x(e))throw Error(`Tarball not found: ${e}`);let t=O(q,`_offline-detect-${Date.now()}`);S(t,{recursive:!0});let n;try{L(`tar -xzf "${e}"`,{cwd:t,stdio:`pipe`,timeout:6e4}),n=ur(O(t,`package`))}finally{x(t)&&T(t,{recursive:!0})}G.debug(`Installing from local tarball...`,{package:`${ar}@${n}`});let r=O(q,`v${n}-staging`);x(r)&&T(r,{recursive:!0}),S(r,{recursive:!0});try{Te(e,O(r,`offline-${n}.tgz`));let t=pr(r,`offline-${n}.tgz`);return G.debug(`Validating installation...`),lr(t),mr(t,n),n}finally{x(r)&&T(r,{recursive:!0})}}async function xr(e){try{let t=O(q,`v${e}`,`packages`,`server`,`dist`,`bin.js`);if(!x(t)){G.warn(`Server entry not found — skipping MCP registration`,{serverPath:t});return}let n={command:g.command,args:g.args?[...g.args]:void 0,type:g.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&x(e)&&(n.command=e)}catch{}}let r=await nr({scope:`user`});if(r.length===0){G.info(`No supported IDEs detected for MCP registration`);return}let i=0;for(let e of r)try{await e.registerMcp(p,n),i++}catch(t){G.warn(`Failed to register MCP for ${e.name}`,{error:t.message})}i>0&&G.info(`MCP server configured for ${i} IDE(s) — using version-neutral launcher`)}catch(e){G.warn(`MCP registration failed`,{error:e.message})}}const Sr=[{name:`install`,description:`Install AI Kit to ~/.aikit/versions/ (one-time setup for fast local startup)`,usage:or,run:async e=>{let t=e.indexOf(`--version`),n=e.indexOf(`--offline`),r=t!==-1&&t+1<e.length,i=n!==-1&&n+1<e.length;if(e.includes(`--help`)||e.includes(`-h`)){console.log(or);return}if(i){let t=e[n+1];await xr(br(t)),G.debug(`Install complete — restart your IDE to use the new version`);return}let a;r?a=e[t+1]:(G.debug(`Checking npm registry for latest version...`),a=await cr(),G.debug(`Latest version detected`,{version:a})),vr(a),await xr(a),G.debug(`Install complete — restart your IDE to use the new version`)}}];function Cr(){let e=wr();if(e)return e;let t={command:g.command,args:g.args?[...g.args]:void 0,type:g.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(t.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&x(e)&&(t.command=e)}catch{}}return t}function wr(){let e=O(M(),`.aikit`,`current-version.json`);if(!x(e))return null;try{let t=JSON.parse(C(e,`utf-8`));if(typeof t.version!=`string`||t.version.length===0||!x(O(O(M(),`.aikit`,`versions`,`v${t.version}`),`packages`,`server`,`dist`,`bin.js`)))return null;let n={command:g.command,args:g.args?[...g.args]:void 0,type:g.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=pn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&x(e)&&(n.command=e)}catch{}}return n}catch{return null}}const Tr=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function Er(e,t,n){let r=A(M(),`.copilot`,`instructions`,`copilot-instructions.md`);!x(r)||n.has(r)||(S(D(r),{recursive:!0}),E(r,`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`,`utf-8`),n.add(r))}function Dr(e,t=!1){if(!Tr.has(e.name))return;let n=A(D(e.getConfigPath()),`settings.json`),r={};if(x(n))try{let e=C(n,`utf-8`);r=JSON.parse(e)}catch{console.log(` ${e.name}: skipped settings.json (invalid JSON)`);return}let i=!1;for(let[e,n]of Object.entries(ve))if(typeof n==`object`&&n){let t=typeof r[e]==`object`&&r[e]!==null?r[e]:{},a={...t,...n};JSON.stringify(a)!==JSON.stringify(t)&&(r[e]=a,i=!0)}else(t||!(e in r))&&(r[e]=n,i=!0);i&&(E(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.name}: updated settings.json`))}async function Or(r,o,s,c,l=!1){let u=new Map,d=new Set,f=he(`aikit`,s),ee=ye(`aikit`,s);for(let e of o)e.getScaffoldRoot()!==null&&u.set(e.id,e);if(Er(f,ee,d),u.size===0){d.size>0?console.log(` Instruction files: ${[...d].join(`, `)}`):console.log(` No IDEs with global scaffold support detected.`);return}let te=await n(r,`copilot`),ne=await n(r,`opencode`),re=await n(r,`hermes-agent`),ie=await n(r,`claude-code`),ae=e=>{let t=new Map;for(let n of e){let e=n.path.indexOf(`/`);if(e===-1)continue;let r=n.path.substring(0,e);if(r===`agents`||r===`prompts`){let i=t.get(r)??[];i.push({path:n.path.substring(e+1),content:n.content}),t.set(r,i)}else if(r===`.opencode`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}else if(r===`.claude`){let r=n.path.indexOf(`/`,e+1);if(r!==-1&&n.path.substring(e+1,r)===`agents`){let e=t.get(`agents`)??[];e.push({path:n.path.substring(r+1),content:n.content}),t.set(`agents`,e)}}}return t},oe=ae(te),se=ae(ne),ce=ae(re),p=ae(ie),le=await n(r,`skills`),ue=new Set;for(let e of le){let t=e.path.indexOf(`/`);t!==-1&&ue.add(e.path.substring(0,t))}let m=await n(r,`flows`),de=new Set;for(let e of m){let t=e.path.indexOf(`/`);t!==-1&&de.add(e.path.substring(0,t))}let fe=await n(r,`claude-code`),h=A(r,`scaffold`,`general`,`hooks`,`scripts`),g=x(h)?h:A(import.meta.dirname,`../../../../../scaffold/general/hooks/scripts`),pe=be(),_=new Set,v=new Set,ge=new Set,y=(n,r,o,s)=>{let u=s.get(o);if(!n||!r||!u||u.length===0)return;let d=`${o}:${r}:${n}`;if(_.has(d))return;_.add(d);let f=e(r)??a(c);f.version=c,i(u,n,f,o,l),t(r,f),ge.add(D(r))},_e=(n,r,o,s)=>{if(!n||!r||s.length===0)return;let u=`${o}:${r}:${n}`;if(_.has(u))return;if(_.add(u),o===`flows`&&!v.has(n)){for(let e of de){let t=A(n,e,`skills`);x(t)&&(T(t,{recursive:!0,force:!0}),console.log(` ${D(r)}: migrated ${e} flow to steps/ layout`))}v.add(n)}let d=e(r)??a(c);d.version=c,i(s,n,d,o,l),t(r,d),ge.add(D(r))},ve=(e,t,n)=>{!e||!t||_e(e,t,`hooks`,[...me(n,A(e,`scripts`).replace(/\\/g,`/`)),...pe.map(e=>({path:`scripts/${e}`,content:C(A(g,e),`utf-8`)}))])};for(let e of u.values()){let t=e.getScaffoldPaths(),n=e.family===`opencode`?se:e.family===`hermes`?ce:e.family===`claude`?p:oe;y(t.agents,t.manifest,`agents`,n),y(t.prompts,t.manifest,`prompts`,n),_e(t.skills,t.manifest,`skills`,le),_e(t.flows,t.manifest,`flows`,m),_e(t.commands,t.manifest,`commands`,fe),ve(t.hooks,t.manifest,e.family===`claude`?`claude`:`copilot`)}for(let e of ge)console.log(` ${e}: scaffold updated (${ue.size} skills)`);for(let e of u.values()){let t=e.getScaffoldPaths().instructions;!t||d.has(t)||(S(D(t),{recursive:!0}),E(t,e.buildInstructionContent(f,ee),`utf-8`),d.add(t))}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}function kr(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e){if(Tr.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(A(r,`kb.instructions.md`)),t.push(A(r,`aikit.instructions.md`))}else if(n.name===`Cursor`||n.name===`Cursor Nightly`)t.push(A(e,`rules`,`kb.mdc`));else if(n.name===`Windsurf`)t.push(A(e,`rules`,`kb.md`));else if(n.family===`claude`){let n=A(e,`agents`);if(x(n)){for(let e of w(n))if(e.endsWith(`.agent.md`)){let r=A(n,e);Oe(r),t.push(r)}}}}}for(let e of t)x(e)&&(Oe(e),console.log(` Removed legacy file: ${e}`))}async function Ar(e){let t=p,n=ce(),r=JSON.parse(C(A(n,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${r}...\n`);let i=Re();S(i,{recursive:!0}),console.log(` Global data store: ${i}`),console.log(` Managed runtime: v${r}`),yr(r),We({version:1,workspaces:{}}),console.log(` Created registry.json`);let a=await nr({scope:`user`});if(a.length===0)console.log(`
40
+ No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${a.length} IDE(s):`);let n=wr();if(!n)throw Error(`Managed runtime v${r} was installed but its MCP server entry could not be resolved.`);for(let e of a)try{await e.registerMcp(t,n),console.log(` ${e.name}: configured ${t}`)}catch(t){console.log(` ${e.name}: failed to configure (${t.message})`)}for(let t of a)Dr(t,e.force)}console.log(`
41
+ Installing scaffold files:`),await Or(n,a,t,r,e.force),kr(a),console.log(`
42
42
  User-level AI Kit installation complete!`),console.log(`
43
- Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}const Or=[{directory:`.github/copilot/agents`,suffix:`.agent.md`},{directory:`.github/copilot/prompts`,suffix:`.prompt.md`},{directory:`.copilot/skills`,suffix:`/SKILL.md`},{directory:`.agents/skills`,suffix:`/SKILL.md`}],kr=[`.copilot/skills`,`.agents/skills`],Ar=/^(?:mcp_)?aikit_[a-z0-9_]+$/;function jr(e,t){return(Oe(e,t)||t).split(`\\`).join(`/`)}function Mr(e){let t=new Set;for(let n of Or){let r=k(e,n.directory);if(S(r))try{for(let e of T(r,{withFileTypes:!0})){if(n.suffix===`/SKILL.md`){if(e.isDirectory()){let n=k(r,e.name,`SKILL.md`);S(n)&&t.add(n)}continue}e.isFile()&&e.name.endsWith(n.suffix)&&t.add(k(r,e.name))}}catch{}}return[...t].sort()}function Nr(e){let t=new Set;for(let n of kr){let r=k(e,n);if(S(r))try{for(let e of T(r,{withFileTypes:!0}))e.isDirectory()&&t.add(e.name.toLowerCase())}catch{}}return t}function Pr(e){if(!e.startsWith(`---`))return null;let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return t?t[1]:null}function Fr(e){let t=e.trim();if(!t)return[];let n=t.startsWith(`[`)&&t.endsWith(`]`)?t.slice(1,-1):t,r=[],i=``,a=null;for(let e of n){if((e===`"`||e===`'`)&&a===null){a=e,i+=e;continue}if(e===a){a=null,i+=e;continue}if(e===`,`&&a===null){let e=Ir(i);e&&r.push(e),i=``;continue}i+=e}let o=Ir(i);return o&&r.push(o),r}function Ir(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function Lr(e){let t=e.trim();if(!t)return;if(t.startsWith(`[`)!==t.endsWith(`]`))return`inline array is missing a closing bracket`;if(!t.startsWith(`[`))return;let n=null;for(let e=1;e<t.length-1;e+=1){let r=t[e];if((r===`"`||r===`'`)&&n===null){n=r;continue}r===n&&(n=null)}if(n!==null)return`inline array has an unterminated quoted value`}function Rr(e){if(!e.startsWith(`---`))return;let t=Pr(e);if(t===null)return`frontmatter is missing a closing --- delimiter`;let n=!1;for(let e of t.split(/\r?\n/)){let t=e.trim();if(!t||t.startsWith(`#`))continue;if(n){if(/^\s{2,}[A-Za-z0-9_-]+:\s*.*$/.test(e))return Lr(e.replace(/^\s{2,}[A-Za-z0-9_-]+:\s*/,``));n=!1}let r=e.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);if(!r)return`unsupported frontmatter line: ${t}`;let[,i,a]=r;if(i===`metadata`&&a.trim()===``){n=!0;continue}let o=Lr(a);if(o)return o}}function zr(e,t){try{let n=w(t,`utf8`),i=Rr(n);return{filePath:t,displayPath:jr(e,t),content:n,parsed:i?null:r(n),yamlError:i}}catch{return null}}function Br(e){return Mr(e).map(t=>zr(e,t)).filter(e=>e!==null)}function Vr(e){if(!e.parsed)return[];let t=e.parsed.fields.applyTo;return t?Fr(t):[]}function Hr(e){let t=e.trim();if(!t)return`glob pattern is empty`;let n=[],r={"[":`]`,"{":`}`,"(":`)`},i=new Set(Object.values(r));for(let e=0;e<t.length;e+=1){let a=t[e];if(t[e-1]!==`\\`){if(a in r){n.push(r[a]);continue}if(i.has(a)&&n.pop()!==a)return`glob pattern has an unexpected '${a}'`}}if(n.length>0)return`glob pattern is missing '${n[n.length-1]}'`}function Ur(e){let t=new Set;for(let n of e.matchAll(/<skill>\s*([a-z][a-z0-9-]*)\s*<\/skill>/gi))t.add(n[1].toLowerCase());let n=e.split(/\r?\n/),r=!1;for(let e of n){if(/^#{1,6}\s+skills\b/i.test(e)){r=!0;continue}if(r&&/^#{1,6}\s+/.test(e)&&(r=!1),!r)continue;let n=e.match(/^\|\s*([a-z][a-z0-9-]*)\s*\|/i);if(n){let e=n[1].toLowerCase();e!==`skill`&&t.add(e)}for(let n of e.matchAll(/`([a-z][a-z0-9-]*)`/gi))t.add(n[1].toLowerCase())}return[...t]}const Wr={name:`yaml-parse`,run:e=>{try{return Br(e).filter(e=>e.yamlError).map(e=>({severity:`error`,file:e.displayPath,message:`invalid YAML frontmatter: ${e.yamlError}`,code:`yaml-parse-error`}))}catch{return[]}}},Gr={name:`skill-refs`,run:e=>{try{let t=Nr(e);if(t.size===0)return[];let n=[];for(let r of Br(e))if(r.filePath.endsWith(`.agent.md`))for(let e of Ur(r.content))t.has(e)||n.push({severity:`warning`,file:r.displayPath,message:`referenced skill '${e}' was not found in .copilot/skills or .agents/skills`,code:`skill-ref-missing`});return n}catch{return[]}}},Kr={name:`tool-names`,run:e=>{try{let t=[];for(let n of Br(e))if(n.parsed)for(let e of n.parsed.tools.map(Ir))e&&!Ar.test(e)&&t.push({severity:`warning`,file:n.displayPath,message:`tool '${e}' should use an aikit-prefixed name`,code:`tool-name-invalid`});return t}catch{return[]}}},qr={name:`glob-patterns`,run:e=>{try{let t=[];for(let n of Br(e))if(n.parsed)for(let e of Vr(n)){let r=Hr(e);r&&t.push({severity:`warning`,file:n.displayPath,message:`applyTo pattern '${e}' is invalid: ${r}`,code:`glob-pattern-invalid`})}return t}catch{return[]}}};async function Y(e){let t=console.log;console.log=()=>{};try{return await e()}finally{console.log=t}}async function Jr(e){let t=e.reset??!1,n=e.silent??!1,r=[],i=0,a=0,o=await $n({scope:`user`}),s=br(),c=se(),l=ye(),u=e=>{r.push(e),a+=1,n||console.log(`- ${e}`)};for(let e of o){let n=e.getConfigPath();if(i+=1,!S(n)){C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(m,s)),u(`Fixed: ${e.name} — MCP config was missing, recreated`);continue}try{if(!(await e.readConfig())[e.configKey]?.aikit){C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(m,s)),u(`Fixed: ${e.name} — MCP entry was missing, added`);continue}t&&(C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(m,s)),u(`Reset: ${e.name} — MCP config restored to factory defaults`))}catch{Ce(n,`${n}.bak`),C(O(n),{recursive:!0}),await Y(()=>e.registerMcp(m,s)),u(`Fixed: ${e.name} — MCP config was corrupt, backed up and recreated`)}}await Y(async()=>{for(let e of o)wr(e,t)}),await Y(()=>Tr(c,o,m,l??`0.0.0`,t));let d=[Wr,Gr,Kr,qr];for(let e of d)try{let t=I();if(!t)continue;let r=e.run(t);for(let e of r)(e.severity===`error`||e.severity===`warning`)&&(n||console.warn(`[doctor:${e.code}] ${e.file}: ${e.message}`))}catch{}if(n){if(r.length>0)for(let e of r)console.error(`[doctor] ${e}`)}else r.length===0&&console.log(`- No MCP config issues found.`);return{checked:i,fixed:a,issues:r}}const Yr=[{name:`doctor`,description:`Check and repair AI Kit configuration files`,usage:`aikit doctor [--reset]`,run:async e=>{let t=e.includes(`--reset`);console.log(t?`Resetting AI Kit to factory defaults...
43
+ Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}const jr=[{directory:`.github/copilot/agents`,suffix:`.agent.md`},{directory:`.github/copilot/prompts`,suffix:`.prompt.md`},{directory:`.copilot/skills`,suffix:`/SKILL.md`},{directory:`.agents/skills`,suffix:`/SKILL.md`}],Mr=[`.copilot/skills`,`.agents/skills`],Nr=/^(?:mcp_)?aikit_[a-z0-9_]+$/;function Pr(e,t){return(Ae(e,t)||t).split(`\\`).join(`/`)}function Fr(e){let t=new Set;for(let n of jr){let r=O(e,n.directory);if(x(r))try{for(let e of w(r,{withFileTypes:!0})){if(n.suffix===`/SKILL.md`){if(e.isDirectory()){let n=O(r,e.name,`SKILL.md`);x(n)&&t.add(n)}continue}e.isFile()&&e.name.endsWith(n.suffix)&&t.add(O(r,e.name))}}catch{}}return[...t].sort()}function Ir(e){let t=new Set;for(let n of Mr){let r=O(e,n);if(x(r))try{for(let e of w(r,{withFileTypes:!0}))e.isDirectory()&&t.add(e.name.toLowerCase())}catch{}}return t}function Lr(e){if(!e.startsWith(`---`))return null;let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return t?t[1]:null}function Rr(e){let t=e.trim();if(!t)return[];let n=t.startsWith(`[`)&&t.endsWith(`]`)?t.slice(1,-1):t,r=[],i=``,a=null;for(let e of n){if((e===`"`||e===`'`)&&a===null){a=e,i+=e;continue}if(e===a){a=null,i+=e;continue}if(e===`,`&&a===null){let e=zr(i);e&&r.push(e),i=``;continue}i+=e}let o=zr(i);return o&&r.push(o),r}function zr(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function Br(e){let t=e.trim();if(!t)return;if(t.startsWith(`[`)!==t.endsWith(`]`))return`inline array is missing a closing bracket`;if(!t.startsWith(`[`))return;let n=null;for(let e=1;e<t.length-1;e+=1){let r=t[e];if((r===`"`||r===`'`)&&n===null){n=r;continue}r===n&&(n=null)}if(n!==null)return`inline array has an unterminated quoted value`}function Vr(e){if(!e.startsWith(`---`))return;let t=Lr(e);if(t===null)return`frontmatter is missing a closing --- delimiter`;let n=!1;for(let e of t.split(/\r?\n/)){let t=e.trim();if(!t||t.startsWith(`#`))continue;if(n){if(/^\s{2,}[A-Za-z0-9_-]+:\s*.*$/.test(e))return Br(e.replace(/^\s{2,}[A-Za-z0-9_-]+:\s*/,``));n=!1}let r=e.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);if(!r)return`unsupported frontmatter line: ${t}`;let[,i,a]=r;if(i===`metadata`&&a.trim()===``){n=!0;continue}let o=Br(a);if(o)return o}}function Hr(e,t){try{let n=C(t,`utf8`),i=Vr(n);return{filePath:t,displayPath:Pr(e,t),content:n,parsed:i?null:r(n),yamlError:i}}catch{return null}}function Ur(e){return Fr(e).map(t=>Hr(e,t)).filter(e=>e!==null)}function Wr(e){if(!e.parsed)return[];let t=e.parsed.fields.applyTo;return t?Rr(t):[]}function Gr(e){let t=e.trim();if(!t)return`glob pattern is empty`;let n=[],r={"[":`]`,"{":`}`,"(":`)`},i=new Set(Object.values(r));for(let e=0;e<t.length;e+=1){let a=t[e];if(t[e-1]!==`\\`){if(a in r){n.push(r[a]);continue}if(i.has(a)&&n.pop()!==a)return`glob pattern has an unexpected '${a}'`}}if(n.length>0)return`glob pattern is missing '${n[n.length-1]}'`}function Kr(e){let t=new Set;for(let n of e.matchAll(/<skill>\s*([a-z][a-z0-9-]*)\s*<\/skill>/gi))t.add(n[1].toLowerCase());let n=e.split(/\r?\n/),r=!1;for(let e of n){if(/^#{1,6}\s+skills\b/i.test(e)){r=!0;continue}if(r&&/^#{1,6}\s+/.test(e)&&(r=!1),!r)continue;let n=e.match(/^\|\s*([a-z][a-z0-9-]*)\s*\|/i);if(n){let e=n[1].toLowerCase();e!==`skill`&&t.add(e)}for(let n of e.matchAll(/`([a-z][a-z0-9-]*)`/gi))t.add(n[1].toLowerCase())}return[...t]}const qr={name:`yaml-parse`,run:e=>{try{return Ur(e).filter(e=>e.yamlError).map(e=>({severity:`error`,file:e.displayPath,message:`invalid YAML frontmatter: ${e.yamlError}`,code:`yaml-parse-error`}))}catch{return[]}}},Jr={name:`skill-refs`,run:e=>{try{let t=Ir(e);if(t.size===0)return[];let n=[];for(let r of Ur(e))if(r.filePath.endsWith(`.agent.md`))for(let e of Kr(r.content))t.has(e)||n.push({severity:`warning`,file:r.displayPath,message:`referenced skill '${e}' was not found in .copilot/skills or .agents/skills`,code:`skill-ref-missing`});return n}catch{return[]}}},Yr={name:`tool-names`,run:e=>{try{let t=[];for(let n of Ur(e))if(n.parsed)for(let e of n.parsed.tools.map(zr))e&&!Nr.test(e)&&t.push({severity:`warning`,file:n.displayPath,message:`tool '${e}' should use an aikit-prefixed name`,code:`tool-name-invalid`});return t}catch{return[]}}},Xr={name:`glob-patterns`,run:e=>{try{let t=[];for(let n of Ur(e))if(n.parsed)for(let e of Wr(n)){let r=Gr(e);r&&t.push({severity:`warning`,file:n.displayPath,message:`applyTo pattern '${e}' is invalid: ${r}`,code:`glob-pattern-invalid`})}return t}catch{return[]}}};async function J(e){let t=console.log;console.log=()=>{};try{return await e()}finally{console.log=t}}async function Zr(e){let t=e.reset??!1,n=e.silent??!1,r=[],i=0,a=0,o=await nr({scope:`user`}),s=Cr(),c=ce(),l=xe(),u=e=>{r.push(e),a+=1,n||console.log(`- ${e}`)};for(let e of o){let n=e.getConfigPath();if(i+=1,!x(n)){S(D(n),{recursive:!0}),await J(()=>e.registerMcp(p,s)),u(`Fixed: ${e.name} — MCP config was missing, recreated`);continue}try{if(!(await e.readConfig())[e.configKey]?.aikit){S(D(n),{recursive:!0}),await J(()=>e.registerMcp(p,s)),u(`Fixed: ${e.name} — MCP entry was missing, added`);continue}t&&(S(D(n),{recursive:!0}),await J(()=>e.registerMcp(p,s)),u(`Reset: ${e.name} — MCP config restored to factory defaults`))}catch{Te(n,`${n}.bak`),S(D(n),{recursive:!0}),await J(()=>e.registerMcp(p,s)),u(`Fixed: ${e.name} — MCP config was corrupt, backed up and recreated`)}}await J(async()=>{for(let e of o)Dr(e,t)}),await J(()=>Or(c,o,p,l??`0.0.0`,t));let d=[qr,Jr,Yr,Xr];for(let e of d)try{let t=F();if(!t)continue;let r=e.run(t);for(let e of r)(e.severity===`error`||e.severity===`warning`)&&(n||console.warn(`[doctor:${e.code}] ${e.file}: ${e.message}`))}catch{}if(n){if(r.length>0)for(let e of r)console.error(`[doctor] ${e}`)}else r.length===0&&console.log(`- No MCP config issues found.`);return{checked:i,fixed:a,issues:r}}const Qr=[{name:`doctor`,description:`Check and repair AI Kit configuration files`,usage:`aikit doctor [--reset]`,run:async e=>{let t=e.includes(`--reset`);console.log(t?`Resetting AI Kit to factory defaults...
44
44
  `:`Running AI Kit doctor...
45
- `);let n=await Jr({reset:t,silent:!1});if(console.log(`\nDone: ${n.checked} checked, ${n.fixed} fixed.`),n.issues.length>0){console.log(`
46
- Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],Xr=[{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)),o(Pt(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=It(t);if(!n){console.log(`No managed process found: ${t}`);return}o(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=Ft(t);if(!n){console.log(`No managed process found: ${t}`);return}o(n);return}case`list`:{let e=Mt();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)o(t),console.log(``);return}case`logs`:{let t=_(e,`--tail`,50),n=e.shift()?.trim();n||(console.error(`Usage: aikit proc logs <id> [--tail N]`),process.exit(1));let r=Nt(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=ln({path:j(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=un(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=cn();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 dt();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=g(e,`--model`,``),n=g(e,`--system`,``),r=_(e,`--temp`,.3),i=g(e,`--context`,``),a=e.join(` `);a||=await f(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await Xe(j(i),`utf-8`));let s=await ut({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)`)}}],Zr=[{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=g(e,`--lang`,`js`),n=_(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await f(),a=r||i;if(!a.trim())throw new h(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`);let o=await mt({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:`proxy`,description:`Run stdio-to-HTTP proxy for IDE MCP integration`,usage:`aikit proxy [--port port] [--no-auto-start]`,run:async e=>{let t=_(e,`--port`,3210),n=!v(e,`--no-auto-start`),{runProxy:r}=await import(`../../server/dist/proxy.js`);await r({port:t,autoStart:n})}},{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=g(e,`--grep`,``).trim()||void 0,n=g(e,`--cwd`,``).trim()||void 0,r=_(e,`--timeout`,6e4),i=e.filter(Boolean),a=await on({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});te(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()??``;if(!t||!n||!r)throw new h(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let i=x(g(e,`--extensions`,``)),a=x(g(e,`--exclude`,``)),o=await qt({oldName:t,newName:n,rootPath:j(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:v(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=g(e,`--rules`,``).trim();if(!t||!n)throw new h(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let r=await Xe(j(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=x(g(e,`--extensions`,``)),o=x(g(e,`--exclude`,``)),s=await st({rootPath:j(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:v(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 f();if(!t||!n.trim())throw new h(`Usage: cat data.json | aikit transform <expression>`);let r=lt({input:n,expression:t});console.log(r.outputString)}}];async function Qr(){let e=await import(`../../flows/dist/index.js`),{FlowLoader:t,FlowRegistryManager:n,FlowStateMachine:r,GitInstaller:i}=e,a=typeof e.getBuiltinFlows==`function`?e.getBuiltinFlows:void 0,o=bn(),s=o.stateDir;if(!s)throw Error(`stateDir not configured`);let c=k(s,`flows`,`installed`),l=k(Ie(),`flows`);C(l,{recursive:!0});let u=k(l,`registry.json`),d=o.sources[0].path,f=k(d,`.flows`);return{loader:new t,registry:new n(u),stateMachine:new r(f,{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 i(c),getBuiltinFlows:a,cwd:d}}const $r=[e=>k(`skills`,e,`SKILL.md`),e=>k(`skills`,e,`README.md`),e=>k(e,`SKILL.md`),e=>k(e,`README.md`)];function ei(e,t){for(let n of t.steps){let t=k(e,n.instruction);if(S(t))continue;let r=!1;for(let i of $r){let a=k(e,i(n.id));if(S(a)){let e=O(t);S(e)||C(e,{recursive:!0}),Ce(a,t),r=!0;break}}r||console.warn(`Warning: instruction file for step "${n.id}" not found.\n Expected: ${n.instruction}\n Searched: ${$r.map(e=>e(n.id)).join(`, `)}`)}}const ti=[{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 Qr();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 r=t.startsWith(`http`)||t.startsWith(`git@`)||t.endsWith(`.git`),i=j(t),a=S(i);if(!r&&!a){console.error(`Source not found: ${t}`),console.error(`Provide a git URL or existing local path.`);return}let o,s;if(r){console.log(`Cloning ${t}...`);let e=n.git.clone(t);if(!e.success||!e.data){console.error(e.error??`Failed to clone flow`);return}o=e.data,s=`git`}else{let r=e[2]||De(i);console.log(`Copying local flow from ${t}...`);let a=n.git.copyLocal(i,r);if(!a.success||!a.data){console.error(a.error??`Failed to copy local flow`);return}o=a.data,s=`local`}let c=await n.loader.load(o);if(!c.success||!c.data){console.error(c.error??`Failed to load flow`),n.git.remove(o);return}let{manifest:l,format:u}=c.data;if(ei(o,l),l.install.length>0){console.log(`Installing ${l.install.length} dependencies...`);let e=n.git.runInstallDeps(l.install);if(!e.success){console.error(`Dependency install failed: ${e.error}`),n.git.remove(o);return}}let d=new Date().toISOString(),f=n.registry.register({name:l.name,version:l.version,source:t,sourceType:s,installPath:o,format:u,registeredAt:d,updatedAt:d,manifest:l});if(!f.success){console.error(f.error??`Failed to register flow`),n.git.remove(o);return}console.log(`✓ Flow "${l.name}" v${l.version} installed (${u} format)`),console.log(` Steps: ${l.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.")}}}],X=F(`cli:gc`),ni=k(N(),`.aikit`,`versions`),ri=k(N(),`.aikit`,`current-version.json`);function ii(e){let t=e.match(/^v(\d+)\.(\d+)\.(\d+)$/);return t?{major:Number.parseInt(t[1],10),minor:Number.parseInt(t[2],10),patch:Number.parseInt(t[3],10)}:null}function ai(e,t){return e.major===t.major?e.minor===t.minor?t.patch-e.patch:t.minor-e.minor:t.major-e.major}function oi(){try{return S(ri)?JSON.parse(w(ri,`utf-8`)).version??null:null}catch{return null}}const si=[{name:`gc`,description:`Free disk space by removing old AI Kit versions (keeps current + last N)`,usage:`aikit gc [--keep N]`,run:async e=>{if(!S(ni)){X.info(`No version directories found.`);return}let t=_(e,`--keep`,2),n=oi(),r=T(ni,{withFileTypes:!0}),i=new Set(r.filter(e=>e.isDirectory()&&(e.name.includes(`-staging`)||e.name.startsWith(`_offline-detect-`)||e.name.startsWith(`_aikit-tarball-staging-`))).map(e=>e.name));for(let e of i)await Qe(k(ni,e),{recursive:!0,force:!0}),X.debug(`Removed ${e}`);let a=r.filter(e=>e.isDirectory()&&!i.has(e.name)).map(e=>({name:e.name,semver:ii(e.name)})).filter(e=>e.semver!==null).sort((e,t)=>ai(e.semver,t.semver));if(a.length===0){X.info(`No version directories found.`);return}let o=new Set;n&&o.add(`v${n}`);for(let e of a){if(o.size>=t+ +!!n)break;o.add(e.name)}let s=a.filter(e=>!o.has(e.name));if(s.length===0){X.info(`No versions to clean`);return}for(let e of s)await Qe(k(ni,e.name),{recursive:!0,force:!0}),X.debug(`Removed ${e.name}`);X.info(`Removed ${s.length} versions`)}}];let ci=null;async function Z(){return ci||=await Cn(),ci}function li(){return ci}const ui=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
45
+ `);let n=await Zr({reset:t,silent:!1});if(console.log(`\nDone: ${n.checked} checked, ${n.fixed} fixed.`),n.issues.length>0){console.log(`
46
+ Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],$r=[{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)),o(It(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=Rt(t);if(!n){console.log(`No managed process found: ${t}`);return}o(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=Lt(t);if(!n){console.log(`No managed process found: ${t}`);return}o(n);return}case`list`:{let e=Pt();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)o(t),console.log(``);return}case`logs`:{let t=v(e,`--tail`,50),n=e.shift()?.trim();n||(console.error(`Usage: aikit proc logs <id> [--tail N]`),process.exit(1));let r=Ft(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=dn({path:A(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=fn(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=un();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 pt();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=h(e,`--model`,``),n=h(e,`--system`,``),r=v(e,`--temp`,.3),i=h(e,`--context`,``),a=e.join(` `);a||=await f(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await Qe(A(i),`utf-8`));let s=await ft({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)`)}}],ei=[{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=h(e,`--lang`,`js`),n=v(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await f(),a=r||i;if(!a.trim())throw new m(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`);let o=await gt({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:`proxy`,description:`Run stdio-to-HTTP proxy for IDE MCP integration`,usage:`aikit proxy [--port port] [--no-auto-start]`,run:async e=>{let t=v(e,`--port`,3210),n=!y(e,`--no-auto-start`),{runProxy:r}=await import(`../../server/dist/proxy.js`);await r({port:t,autoStart:n})}},{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=h(e,`--grep`,``).trim()||void 0,n=h(e,`--cwd`,``).trim()||void 0,r=v(e,`--timeout`,6e4),i=e.filter(Boolean),a=await cn({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});ne(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()??``;if(!t||!n||!r)throw new m(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let i=b(h(e,`--extensions`,``)),a=b(h(e,`--exclude`,``)),o=await Yt({oldName:t,newName:n,rootPath:A(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:y(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=h(e,`--rules`,``).trim();if(!t||!n)throw new m(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let r=await Qe(A(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=b(h(e,`--extensions`,``)),o=b(h(e,`--exclude`,``)),s=await lt({rootPath:A(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:y(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 f();if(!t||!n.trim())throw new m(`Usage: cat data.json | aikit transform <expression>`);let r=dt({input:n,expression:t});console.log(r.outputString)}}];async function ti(){let e=await import(`../../flows/dist/index.js`),{FlowLoader:t,FlowRegistryManager:n,FlowStateMachine:r,GitInstaller:i}=e,a=typeof e.getBuiltinFlows==`function`?e.getBuiltinFlows:void 0,o=Sn(),s=o.stateDir;if(!s)throw Error(`stateDir not configured`);let c=O(s,`flows`,`installed`),l=O(Re(),`flows`);S(l,{recursive:!0});let u=O(l,`registry.json`),d=o.sources[0].path,f=O(d,`.flows`);return{loader:new t,registry:new n(u),stateMachine:new r(f,{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 i(c),getBuiltinFlows:a,cwd:d}}const ni=[e=>O(`skills`,e,`SKILL.md`),e=>O(`skills`,e,`README.md`),e=>O(e,`SKILL.md`),e=>O(e,`README.md`)];function ri(e,t){for(let n of t.steps){let t=O(e,n.instruction);if(x(t))continue;let r=!1;for(let i of ni){let a=O(e,i(n.id));if(x(a)){let e=D(t);x(e)||S(e,{recursive:!0}),Te(a,t),r=!0;break}}r||console.warn(`Warning: instruction file for step "${n.id}" not found.\n Expected: ${n.instruction}\n Searched: ${ni.map(e=>e(n.id)).join(`, `)}`)}}const ii=[{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 ti();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 r=t.startsWith(`http`)||t.startsWith(`git@`)||t.endsWith(`.git`),i=A(t),a=x(i);if(!r&&!a){console.error(`Source not found: ${t}`),console.error(`Provide a git URL or existing local path.`);return}let o,s;if(r){console.log(`Cloning ${t}...`);let e=n.git.clone(t);if(!e.success||!e.data){console.error(e.error??`Failed to clone flow`);return}o=e.data,s=`git`}else{let r=e[2]||ke(i);console.log(`Copying local flow from ${t}...`);let a=n.git.copyLocal(i,r);if(!a.success||!a.data){console.error(a.error??`Failed to copy local flow`);return}o=a.data,s=`local`}let c=await n.loader.load(o);if(!c.success||!c.data){console.error(c.error??`Failed to load flow`),n.git.remove(o);return}let{manifest:l,format:u}=c.data;if(ri(o,l),l.install.length>0){console.log(`Installing ${l.install.length} dependencies...`);let e=n.git.runInstallDeps(l.install);if(!e.success){console.error(`Dependency install failed: ${e.error}`),n.git.remove(o);return}}let d=new Date().toISOString(),f=n.registry.register({name:l.name,version:l.version,source:t,sourceType:s,installPath:o,format:u,registeredAt:d,updatedAt:d,manifest:l});if(!f.success){console.error(f.error??`Failed to register flow`),n.git.remove(o);return}console.log(`✓ Flow "${l.name}" v${l.version} installed (${u} format)`),console.log(` Steps: ${l.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.")}}}],Y=P(`cli:gc`),ai=O(M(),`.aikit`,`versions`),oi=O(M(),`.aikit`,`current-version.json`);function si(e){let t=e.match(/^v(\d+)\.(\d+)\.(\d+)$/);return t?{major:Number.parseInt(t[1],10),minor:Number.parseInt(t[2],10),patch:Number.parseInt(t[3],10)}:null}function ci(e,t){return e.major===t.major?e.minor===t.minor?t.patch-e.patch:t.minor-e.minor:t.major-e.major}function li(){try{return x(oi)?JSON.parse(C(oi,`utf-8`)).version??null:null}catch{return null}}const ui=[{name:`gc`,description:`Free disk space by removing old AI Kit versions (keeps current + last N)`,usage:`aikit gc [--keep N]`,run:async e=>{if(!x(ai)){Y.info(`No version directories found.`);return}let t=v(e,`--keep`,2),n=li(),r=w(ai,{withFileTypes:!0}),i=new Set(r.filter(e=>e.isDirectory()&&(e.name.includes(`-staging`)||e.name.startsWith(`_offline-detect-`)||e.name.startsWith(`_aikit-tarball-staging-`))).map(e=>e.name));for(let e of i)await et(O(ai,e),{recursive:!0,force:!0}),Y.debug(`Removed ${e}`);let a=r.filter(e=>e.isDirectory()&&!i.has(e.name)).map(e=>({name:e.name,semver:si(e.name)})).filter(e=>e.semver!==null).sort((e,t)=>ci(e.semver,t.semver));if(a.length===0){Y.info(`No version directories found.`);return}let o=new Set;n&&o.add(`v${n}`);for(let e of a){if(o.size>=t+ +!!n)break;o.add(e.name)}let s=a.filter(e=>!o.has(e.name));if(s.length===0){Y.info(`No versions to clean`);return}for(let e of s)await et(O(ai,e.name),{recursive:!0,force:!0}),Y.debug(`Removed ${e.name}`);Y.info(`Removed ${s.length} versions`)}}];let di=null;async function X(){return di||=await Tn(),di}function fi(){return di}const pi=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
47
47
  Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear
48
- Options: --type, --name, --node-id, --edge-type, --direction, --depth, --limit, --source-path`,run:async e=>{let t=e.shift()?.trim()??``;if(!t)throw new h(`Usage: aikit graph <action>
49
- Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await Z(),r=g(e,`--type`,``),i=g(e,`--name`,``),a=g(e,`--node-id`,``),o=g(e,`--edge-type`,``),s=g(e,`--direction`,`both`),c=_(e,`--depth`,2),l=_(e,`--limit`,50),u=g(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];if(!d)throw new h(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await xt(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(`
48
+ Options: --type, --name, --node-id, --edge-type, --direction, --depth, --limit, --source-path`,run:async e=>{let t=e.shift()?.trim()??``;if(!t)throw new m(`Usage: aikit graph <action>
49
+ Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await X(),r=h(e,`--type`,``),i=h(e,`--name`,``),a=h(e,`--node-id`,``),o=h(e,`--edge-type`,``),s=h(e,`--direction`,`both`),c=v(e,`--depth`,2),l=v(e,`--limit`,50),u=h(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];if(!d)throw new m(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await Ct(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(`
50
50
  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(`
51
- 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}`)}}],di=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=g(e,`--category`,``).trim(),n=x(g(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 Z(),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=g(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),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 Z(),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=g(e,`--category`,``).trim()||void 0,n=g(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),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=g(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 Z(),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=_(e,`--max-chars`,3e3),n=g(e,`--path`,``).trim()||void 0,r=g(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 Z(),s=n?await ct(o,{path:n,query:i,maxChars:t,segmentation:r}):await ct(o,{text:a??``,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)}}];function fi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function pi(){let e=await $n({scope:`user`});if(e.length===0)return 0;let t=br(),n=0;for(let r of e)try{let e=(await r.readConfig())[r.configKey]?.[m];if(!e||!fi(e))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(m,t),n++}catch{}return n}const mi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await pi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=F(`cli:rollback`),hi=k(N(),`.aikit`,`versions`),gi=k(N(),`.aikit`,`current-version.json`),_i=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(hi,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(hi,`current-version.json.tmp`);await L(i,JSON.stringify({version:t},null,2),`utf-8`),await Ze(i,gi),Q.debug(`Switched to v${t}`)}}],vi=[{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=Se(e),n=_(e,`--limit`,5),r=g(e,`--mode`,`hybrid`),i=_(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new h(`Usage: aikit search <query>`);let{embedder:o,store:s,graphStore:c}=await Z(),l=await o.embedQuery(a),u;if(r===`keyword`)u=await s.ftsSearch(a,{limit:n});else if(r===`semantic`)u=await s.search(l,{limit:n});else{let[e,t]=await Promise.all([s.search(l,{limit:n*2}),s.ftsSearch(a,{limit:n*2}).catch(()=>[])]);u=ie(e,t).slice(0,n)}if(t){me({query:a,results:u,graphHops:i});return}if(u.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of u){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(`${u.length} result(s) found.`),i>0&&u.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(c,u.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>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=Se(e),n=_(e,`--limit`,10),r=g(e,`--glob`,``).trim()||void 0,i=g(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new h(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:o,store:s}=await Z(),c=await gt(o,s,{query:a,glob:r,pattern:i,limit:n});if(t){me(c);return}if(c.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${c.strategies.join(`, `)}`),console.log(`Results: ${c.results.length} shown (${c.totalFound} total)`);for(let e of c.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=_(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new h(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await Qt(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: ${de(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=_(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new h(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();ee(await an(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=g(e,`--direction`,`both`).trim()||`both`,n=_(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new h(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();re(await sn(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=_(e,`--limit`,5),n=g(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new h(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();u(await vt(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=_(e,`--limit`,100),{embedder:n,store:r}=await Z();be(await _t(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();if(!t)throw new h(`Usage: aikit lookup <id>`);let{store:n}=await Z(),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)}}}];async function yi(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),c=p(),l=a(process.execPath,[c,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),u=`http://localhost:${t}${r}`,d=`http://localhost:${t}/health`,f=!1;for(let e=0;e<30;e+=1){try{if((await fetch(d)).ok){f=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!f)throw l.kill(),new h(`Server failed to start within 30 seconds.`);let ee=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${ee}: ${u}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,u],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[u],{stdio:`ignore`,detached:!0}).unref()}let te=()=>{l.kill(),process.exit(0)};process.on(`SIGINT`,te),process.on(`SIGTERM`,te),await new Promise(e=>{l.on(`exit`,()=>e())})}const bi=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=Se(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:o}=await import(`../../core/dist/index.js`),{existsSync:s}=await import(`node:fs`),c=Ve(),l=a(),u=s(j(c,`.vscode`,`mcp.json`)),d={mode:void 0,dataPath:void 0};if(l&&u)d.mode=`workspace (overrides user-level for this workspace)`,d.dataPath=j(c,n.data);else if(l){let e=r(c);d.mode=s(j(c,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,d.dataPath=i(e)}else d.mode=`workspace`,d.dataPath=j(c,n.data);l&&!u&&(d.workspaces=o().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();d.records=t.totalRecords,d.files=t.totalFiles,d.lastIndexed=t.lastIndexedAt??null,d.backend=t.storeBackend,d.model=t.embeddingModel,d.contentTypeBreakdown=t.contentTypeBreakdown,d.sourcePaths=n.slice(0,20),d.sourcePathTotal=n.length}catch{d.indexAvailable=!1}if(t){me(d);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${d.mode}`),console.log(` Data: ${d.dataPath}`),l&&!u){let e=o();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(d.records!==void 0){console.log(` Records: ${d.records}`),console.log(` Files: ${d.files}`),console.log(` Indexed: ${d.lastIndexed??`Never`}`),console.log(` Backend: ${d.backend}`),console.log(` Model: ${d.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(d.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=d.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${d.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);d.sourcePathTotal>20&&console.log(` ... and ${d.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");l&&!u&&!s(j(c,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @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 Z();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(`
52
- `)},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. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=g(e,`--transport`,`stdio`),n=g(e,`--port`,`3210`),r=v(e,`--daemon`);try{await Jr({silent:!0})}catch{}if(t===`stdio`&&r){let{runProxy:e}=await import(`../../server/dist/proxy.js`);try{let t=`http://127.0.0.1:${n}/health`;if((await fetch(t,{signal:AbortSignal.timeout(2e3)})).ok){await e({port:Number(n),autoStart:!1});return}}catch{}await e({port:Number(n),autoStart:!0});return}let i=fn(p(),[],{cwd:N(),stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:t,AIKIT_PORT:n}});t===`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)throw new h(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-CWLiK7bC.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-CWLiK7bC.js`);await e({force:a})}else if(t)await Dr({force:a});else if(n){let{initProject:e}=await import(`./init-CWLiK7bC.js`);await e({force:a})}else await Dr({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=g(e,`--cwd`,``).trim()||void 0,n=g(e,`--files`,``),r=g(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 nt({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});ae(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=Se(e),n=Ct(e.shift());if(t){me(n);return}console.log(`Project Health: ${n.path}`),console.log(`─`.repeat(50));for(let e of n.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${n.score}% — ${n.summary}`)}},{name:`prune`,description:`Clean up orphaned storage, legacy data, and stale partitions`,usage:`aikit prune [--dry-run] [--max-age-days=90] [--force]`,run:async e=>{let{prune:t,formatBytes:n,markPruneRun:r}=await import(`../../tools/dist/index.js`),i=e.includes(`--dry-run`),a=e.includes(`--force`),o=e.find(e=>e.startsWith(`--max-age-days=`)),s=o?Number.parseInt(o.split(`=`)[1]??``,10):90;if(!i&&!a){console.log(`⚠️ This will permanently delete data. Use --dry-run to preview, or --force to execute.`);return}console.log(i?`🔍 Dry run — no files will be deleted
51
+ 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}`)}}],mi=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=h(e,`--category`,``).trim(),n=b(h(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=h(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=h(e,`--category`,``).trim()||void 0,n=h(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=h(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=v(e,`--max-chars`,3e3),n=h(e,`--path`,``).trim()||void 0,r=h(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=n?await ut(o,{path:n,query:i,maxChars:t,segmentation:r}):await ut(o,{text:a??``,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)}}];function hi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function gi(){let e=await nr({scope:`user`});if(e.length===0)return 0;let t=Cr(),n=0;for(let r of e)try{let e=(await r.readConfig())[r.configKey]?.[p];if(!e||!hi(e))continue;S(D(r.getConfigPath()),{recursive:!0}),await r.registerMcp(p,t),n++}catch{}return n}const _i=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await gi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Z=P(`cli:rollback`),vi=O(M(),`.aikit`,`versions`),yi=O(M(),`.aikit`,`current-version.json`),bi=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Z.debug(`Validating version directory for v${t}...`);let n=O(vi,`v${t}`);x(n)||(Z.warn(`Version v${t} not found`),process.exit(1)),Z.debug(`Validating version dir...`);let r=O(n,`package.json`);x(r)||(Z.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(C(r,`utf-8`)).version||(Z.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Z.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=O(vi,`current-version.json.tmp`);await I(i,JSON.stringify({version:t},null,2),`utf-8`),await $e(i,yi),Z.debug(`Switched to v${t}`)}}],xi=[{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=we(e),n=v(e,`--limit`,5),r=h(e,`--mode`,`hybrid`),i=v(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new m(`Usage: aikit search <query>`);let{embedder:o,store:s,graphStore:c}=await X(),l=await o.embedQuery(a),u;if(r===`keyword`)u=await s.ftsSearch(a,{limit:n});else if(r===`semantic`)u=await s.search(l,{limit:n});else{let[e,t]=await Promise.all([s.search(l,{limit:n*2}),s.ftsSearch(a,{limit:n*2}).catch(()=>[])]);u=ae(e,t).slice(0,n)}if(t){_({query:a,results:u,graphHops:i});return}if(u.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of u){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(`${u.length} result(s) found.`),i>0&&u.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(c,u.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>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=we(e),n=v(e,`--limit`,10),r=h(e,`--glob`,``).trim()||void 0,i=h(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new m(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:o,store:s}=await X(),c=await vt(o,s,{query:a,glob:r,pattern:i,limit:n});if(t){_(c);return}if(c.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${c.strategies.join(`, `)}`),console.log(`Results: ${c.results.length} shown (${c.totalFound} total)`);for(let e of c.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=v(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new m(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await X(),a=await en(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: ${fe(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=v(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new m(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await X();te(await sn(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=h(e,`--direction`,`both`).trim()||`both`,n=v(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new m(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await X();ie(await ln(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=v(e,`--limit`,5),n=h(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new m(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await X();u(await bt(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=v(e,`--limit`,100),{embedder:n,store:r}=await X();Se(await yt(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();if(!t)throw new m(`Usage: aikit lookup <id>`);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)}}}];async function Si(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),c=ee(),l=a(process.execPath,[c,`--transport`,`http`,`--port`,String(t)],{cwd:M(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),u=`http://localhost:${t}${r}`,d=`http://localhost:${t}/health`,f=!1;for(let e=0;e<30;e+=1){try{if((await fetch(d)).ok){f=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!f)throw l.kill(),new m(`Server failed to start within 30 seconds.`);let te=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${te}: ${u}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,u],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[u],{stdio:`ignore`,detached:!0}).unref()}let ne=()=>{l.kill(),process.exit(0)};process.on(`SIGINT`,ne),process.on(`SIGTERM`,ne),await new Promise(e=>{l.on(`exit`,()=>e())})}const Ci=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=we(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:o}=await import(`../../core/dist/index.js`),{existsSync:s}=await import(`node:fs`),c=Ue(),l=a(),u=s(A(c,`.vscode`,`mcp.json`)),d={mode:void 0,dataPath:void 0};if(l&&u)d.mode=`workspace (overrides user-level for this workspace)`,d.dataPath=A(c,n.data);else if(l){let e=r(c);d.mode=s(A(c,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,d.dataPath=i(e)}else d.mode=`workspace`,d.dataPath=A(c,n.data);l&&!u&&(d.workspaces=o().length);try{let{store:e}=await X(),t=await e.getStats(),n=await e.listSourcePaths();d.records=t.totalRecords,d.files=t.totalFiles,d.lastIndexed=t.lastIndexedAt??null,d.backend=t.storeBackend,d.model=t.embeddingModel,d.contentTypeBreakdown=t.contentTypeBreakdown,d.sourcePaths=n.slice(0,20),d.sourcePathTotal=n.length}catch{d.indexAvailable=!1}if(t){_(d);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${d.mode}`),console.log(` Data: ${d.dataPath}`),l&&!u){let e=o();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(d.records!==void 0){console.log(` Records: ${d.records}`),console.log(` Files: ${d.files}`),console.log(` Indexed: ${d.lastIndexed??`Never`}`),console.log(` Backend: ${d.backend}`),console.log(` Model: ${d.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(d.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=d.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${d.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);d.sourcePathTotal>20&&console.log(` ... and ${d.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");l&&!u&&!s(A(c,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @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(`
52
+ `)},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. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=h(e,`--transport`,`stdio`),n=h(e,`--port`,`3210`),r=y(e,`--daemon`);try{await Zr({silent:!0})}catch{}if(t===`stdio`&&r){let{runProxy:e}=await import(`../../server/dist/proxy.js`);try{let t=`http://127.0.0.1:${n}/health`;if((await fetch(t,{signal:AbortSignal.timeout(2e3)})).ok){await e({port:Number(n),autoStart:!1});return}}catch{}await e({port:Number(n),autoStart:!0});return}let i=mn(ee(),[],{cwd:M(),stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:t,AIKIT_PORT:n}});t===`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)throw new m(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-Cvys5TD4.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-Cvys5TD4.js`);await e({force:a})}else if(t)await Ar({force:a});else if(n){let{initProject:e}=await import(`./init-Cvys5TD4.js`);await e({force:a})}else await Ar({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=h(e,`--cwd`,``).trim()||void 0,n=h(e,`--files`,``),r=h(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 it({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});oe(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=we(e),n=Tt(e.shift());if(t){_(n);return}console.log(`Project Health: ${n.path}`),console.log(`─`.repeat(50));for(let e of n.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${n.score}% — ${n.summary}`)}},{name:`prune`,description:`Clean up orphaned storage, legacy data, and stale partitions`,usage:`aikit prune [--dry-run] [--max-age-days=90] [--force]`,run:async e=>{let{prune:t,formatBytes:n,markPruneRun:r}=await import(`../../tools/dist/index.js`),i=e.includes(`--dry-run`),a=e.includes(`--force`),o=e.find(e=>e.startsWith(`--max-age-days=`)),s=o?Number.parseInt(o.split(`=`)[1]??``,10):90;if(!i&&!a){console.log(`⚠️ This will permanently delete data. Use --dry-run to preview, or --force to execute.`);return}console.log(i?`🔍 Dry run — no files will be deleted
53
53
  `:`🧹 Pruning storage...
54
54
  `);let c=await t({dryRun:i,maxAgeDays:s});console.log(`Results:`),console.log(` Forge-ground orphans: ${c.forgeGroundOrphans.count} dirs (${n(c.forgeGroundOrphans.bytesFreed)})`),console.log(` Legacy LanceDB: ${c.legacyLance.count} dirs (${n(c.legacyLance.bytesFreed)})`),console.log(` Empty ephemeral dirs: ${c.emptyEphemeral.count} dirs`),console.log(` Stale partitions: ${c.stalePartitions.count} dirs (${n(c.stalePartitions.bytesFreed)})`),console.log(` Browser profiles: ${c.browserProfiles.count} dirs (${n(c.browserProfiles.bytesFreed)})`),console.log(`\n Total freed: ${n(c.totalBytesFreed)}`),i||(r(),console.log(`
55
- ✅ Cleanup complete.`))}},{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 Z(),r=g(e,`--detail`,`efficient`)||`efficient`,i=g(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await tt(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(`
56
- 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();if(!r)throw new h(`Usage: aikit guide <goal> [--max N]
57
- Example: aikit guide "audit this project"`);let i=St(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=Yt({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}`)}Xt().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Jt(),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;await yi({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/_dashboard/`,commandName:`dashboard`})}},{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;await yi({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=F(`cli:update`),xi=k(N(),`.aikit`),Si=k(xi,`versions`),Ci=k(xi,`current-version.json`);function wi(){if(!S(Ci))return null;try{let e=w(Ci,`utf-8`);return JSON.parse(e)}catch{return null}}function Ti(e){S(xi)||C(xi,{recursive:!0});let t=`${Ci}.tmp`;D(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),we(t,Ci)}function Ei(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=n[e]??0,i=r[e]??0;if(t>i)return!0;if(t<i)return!1}return!1}async function Di(){let e=await fetch(`https://registry.npmjs.org/@vpxa%2faikit/latest`);if(!e.ok)throw Error(`npm registry responded ${e.status}: ${e.statusText}`);let t=await e.json(),n=Array.isArray(t)?t[0]:t;return n.version??n[`dist-tags`]?.latest??`0.0.0`}const Oi=[{name:`version-update`,description:`Update AI Kit to the latest version from npm (auto-detects and installs newer release)`,usage:`aikit version-update`,run:async()=>{let e=wi();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Di()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Ei(t,e.version)){$.info(`Already latest version.`);return}$.debug(`Updating to ${t}...`);try{let e=`https://registry.npmjs.org/@vpxa/aikit/-/aikit-${t}.tgz`,n=await fetch(e);if(!n.ok)throw Error(`Download failed: ${n.status} ${n.statusText}`);let r=Buffer.from(await n.arrayBuffer()),i=k(Si,`v${t}-staging`);S(i)&&E(i,{recursive:!0,force:!0}),C(i,{recursive:!0});try{let e=k(i,`aikit-${t}.tgz`);D(e,r),$.debug(`Extracting...`),R(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=k(i,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),R(`npm ${Pe.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=k(n,`packages`,`server`,`dist`,`bin.js`);if(!S(a))throw Error(`Server entry not found at ${a}`);let o=k(Si,`v${t}`);S(Si)||C(Si,{recursive:!0}),S(o)&&($.debug(`Removing previous installation at ${o}...`),E(o,{recursive:!0,force:!0})),we(n,o),Ti(t),$.info(`Updated to ${t}`)}finally{S(i)&&E(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],ki=[{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 Dr({force:!0});let e=I();if(e){if(S(j(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-CWLiK7bC.js`);await e({force:!0})}if(S(j(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=se(),r=ye();await t(e,n,[...he],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[..._e],r,!0)}}let{rmSync:t}=await import(`node:fs`),n=k(N(),`.aikit`,`cache`,`wasm`);if(S(n))try{t(n,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,n)}}}],Ai=F(`cli:versions`),ji=k(N(),`.aikit`,`versions`),Mi=k(N(),`.aikit`,`current-version.json`);function Ni(){try{return S(Mi)?JSON.parse(w(Mi,`utf-8`)).version??null:null}catch{return null}}const Pi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!S(ji)){Ai.warn(`No versions installed.`);return}let e=Ni(),t=T(ji,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=Te(k(ji,e.name));return{name:e.name,ver:e.name.slice(1),mtime:t.mtime}}).sort((e,t)=>t.mtime.getTime()-e.mtime.getTime());if(t.length===0){Ai.warn(`No versions installed.`);return}for(let n of t){let t=n.ver===e,r=n.mtime.toISOString().split(`T`)[0],i=t?`(current)`:`(older)`,a=t?` ←`:``;console.log(`${n.name} - ${r} ${i}${a}`)}}}],Fi=[{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=x(g(e,`--files`,``)),r=g(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=Zt(i,n,{description:r});console.log(`Saved workset: ${e.name}`),d(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=yt(i);if(!e){console.log(`No workset found: ${i}`);return}d(e);return}case`list`:{let e=At();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)d(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=ft(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=et(i,n);console.log(`Updated workset: ${e.name}`),d(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Kt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),d(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();t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1));let r=await ue();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await f(),a=rn(r,n,le(t||i));console.log(`Stored stash entry: ${a.key}`),console.log(` Type: ${a.type}`),console.log(` Stored: ${a.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=tn(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=nn(r);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=en(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=$t(r);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=Dt();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=g(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=wt(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=kt(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=Tt(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=Ot(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=Et(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=Ut();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=Rt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Gt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Wt(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=Bt(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=Vt(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Ht(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=Lt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=zt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Ii=[...vi,...di,...wn,...ui,...yr,...bi,...Zr,...Fn,...Tn,...Pn,...Fi,...Xr,...Oi,...ki,...ti,...Yr,...mi,...Pi,..._i,...si];Ii.push({name:`help`,description:`Show available commands`,run:async()=>{Ri()}});async function Li(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Ri();return}if(n===`--version`||n===`-v`){let e=j(O(ke(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(w(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Ii.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Ii.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Ri(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof h&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=li();e&&await e.store.close()}}function Ri(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
55
+ ✅ Cleanup complete.`))}},{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=h(e,`--detail`,`efficient`)||`efficient`,i=h(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await rt(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(`
56
+ 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();if(!r)throw new m(`Usage: aikit guide <goal> [--max N]
57
+ Example: aikit guide "audit this project"`);let i=wt(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=Zt({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}`)}Qt().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Xt(),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;await Si({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/_dashboard/`,commandName:`dashboard`})}},{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;await Si({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],Q=P(`cli:update`),wi=O(M(),`.aikit`),Ti=O(wi,`versions`),Ei=O(wi,`current-version.json`);function Di(){if(!x(Ei))return null;try{let e=C(Ei,`utf-8`);return JSON.parse(e)}catch{return null}}function Oi(e){x(wi)||S(wi,{recursive:!0});let t=`${Ei}.tmp`;E(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),Ee(t,Ei)}function ki(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=n[e]??0,i=r[e]??0;if(t>i)return!0;if(t<i)return!1}return!1}async function Ai(){let e=await fetch(`https://registry.npmjs.org/@vpxa%2faikit/latest`);if(!e.ok)throw Error(`npm registry responded ${e.status}: ${e.statusText}`);let t=await e.json(),n=Array.isArray(t)?t[0]:t;return n.version??n[`dist-tags`]?.latest??`0.0.0`}const ji=[{name:`version-update`,description:`Update AI Kit to the latest version from npm (auto-detects and installs newer release)`,usage:`aikit version-update`,run:async()=>{let e=Di();if(!e){Q.debug("No installed version found. Run `aikit install` first.");return}Q.debug(`Current version: ${e.version}`);let t;try{t=await Ai()}catch(e){let t=e instanceof Error?e.message:String(e);Q.error(`Failed to check for updates: ${t}`);return}if(Q.debug(`Latest version: ${t}`),!ki(t,e.version)){Q.info(`Already latest version.`);return}Q.debug(`Updating to ${t}...`);try{let e=`https://registry.npmjs.org/@vpxa/aikit/-/aikit-${t}.tgz`,n=await fetch(e);if(!n.ok)throw Error(`Download failed: ${n.status} ${n.statusText}`);let r=Buffer.from(await n.arrayBuffer()),i=O(Ti,`v${t}-staging`);x(i)&&T(i,{recursive:!0,force:!0}),S(i,{recursive:!0});try{let e=O(i,`aikit-${t}.tgz`);E(e,r),Q.debug(`Extracting...`),L(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=O(i,`package`);if(!x(n))throw Error(`Expected "package/" directory not found after extraction`);Q.debug(`Installing production dependencies...`),L(`npm ${Ie.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=O(n,`packages`,`server`,`dist`,`bin.js`);if(!x(a))throw Error(`Server entry not found at ${a}`);let o=O(Ti,`v${t}`);x(Ti)||S(Ti,{recursive:!0}),x(o)&&(Q.debug(`Removing previous installation at ${o}...`),T(o,{recursive:!0,force:!0})),Ee(n,o),Oi(t),Q.info(`Updated to ${t}`)}finally{x(i)&&T(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);Q.error(`Update failed: ${t}`)}}}],Mi=[{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 Ar({force:!0});let e=F();if(e){if(x(A(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-Cvys5TD4.js`);await e({force:!0})}if(x(A(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=ce(),r=xe();await t(e,n,[...ge],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[..._e],r,!0)}}let{rmSync:t}=await import(`node:fs`),n=O(M(),`.aikit`,`cache`,`wasm`);if(x(n))try{t(n,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,n)}}}],Ni=P(`cli:versions`),Pi=O(M(),`.aikit`,`versions`),Fi=O(M(),`.aikit`,`current-version.json`);function Ii(){try{return x(Fi)?JSON.parse(C(Fi,`utf-8`)).version??null:null}catch{return null}}const Li=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!x(Pi)){Ni.warn(`No versions installed.`);return}let e=Ii(),t=w(Pi,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=De(O(Pi,e.name));return{name:e.name,ver:e.name.slice(1),mtime:t.mtime}}).sort((e,t)=>t.mtime.getTime()-e.mtime.getTime());if(t.length===0){Ni.warn(`No versions installed.`);return}for(let n of t){let t=n.ver===e,r=n.mtime.toISOString().split(`T`)[0],i=t?`(current)`:`(older)`,a=t?` ←`:``;console.log(`${n.name} - ${r} ${i}${a}`)}}}],Ri=[{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=b(h(e,`--files`,``)),r=h(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=$t(i,n,{description:r});console.log(`Saved workset: ${e.name}`),d(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=xt(i);if(!e){console.log(`No workset found: ${i}`);return}d(e);return}case`list`:{let e=Mt();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)d(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=mt(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=nt(i,n);console.log(`Updated workset: ${e.name}`),d(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Jt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),d(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();t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1));let r=await de();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await f(),a=on(r,n,le(t||i));console.log(`Stored stash entry: ${a.key}`),console.log(` Type: ${a.type}`),console.log(` Stored: ${a.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=rn(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=an(r);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=nn(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=tn(r);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=kt();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=h(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=Et(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=jt(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=Dt(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=At(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=Ot(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=Gt();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=Bt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=qt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Kt(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=Ht(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=Ut(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Wt(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=zt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=Vt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],$=[...xi,...mi,...En,...pi,...Sr,...Ci,...ei,...Ln,...Dn,...In,...Ri,...$r,...ji,...Mi,...ii,...Qr,..._i,...Li,...bi,...ui];$.push({name:`help`,description:`Show available commands`,run:async()=>{Bi()}});async function zi(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Bi();return}if(n===`--version`||n===`-v`){let e=A(D(je(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(C(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}`),Bi(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof m&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=fi();e&&await e.store.close()}}function Bi(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
58
58
  `),console.log(`Usage: aikit <command> [options]
59
- `),console.log(`Commands:`);let e=Math.max(...Ii.map(e=>e.name.length));for(let t of Ii)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{Li as run};
59
+ `),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{zi as run};
@@ -0,0 +1,7 @@
1
+ import{c as e,l as t,n,o as r,r as i,t as a}from"./scaffold-BNPHP-QC.js";import{_ as o,a as s,c,i as l,n as u,o as d,r as f,t as p}from"./templates-d2UQHjpi.js";import{appendFileSync as m,existsSync as h,mkdirSync as g,readFileSync as _,unlinkSync as v,writeFileSync as y}from"node:fs";import{basename as b,dirname as x,resolve as S}from"node:path";import{homedir as C}from"node:os";import{AIKIT_PATHS as w,EMBEDDING_DEFAULTS as T,isUserInstalled as E}from"../../core/dist/index.js";function D(e){return h(S(e,`.cursor`))?`cursor`:h(S(e,`.claude`))?`claude-code`:h(S(e,`.windsurf`))?`windsurf`:h(S(e,`.zed`))?`zed`:h(S(e,`.idea`))?`intellij`:h(S(e,`.opencode`))?`opencode`:h(S(e,`AGENTS.md`))?`hermes`:`copilot`}function O(e){let t=[];return h(S(e,`.cursor`))&&t.push(`cursor`),(h(S(e,`.claude`))||h(S(e,`CLAUDE.md`)))&&t.push(`claude-code`),h(S(e,`.windsurf`))&&t.push(`windsurf`),h(S(e,`.zed`))&&t.push(`zed`),h(S(e,`.idea`))&&t.push(`intellij`),h(S(e,`.gemini`))&&t.push(`gemini-cli`),(h(S(e,`.codex`))||h(S(e,`codex.md`)))&&t.push(`codex-cli`),(h(S(e,`.opencode`))||h(S(e,`OPENCODE.md`)))&&t.push(`opencode`),t.push(`copilot`),t.push(`hermes`),[...new Set(t)]}function k(e){return{servers:{[e]:{...l}}}}function A(e){let{type:t,...n}=l;return{mcpServers:{[e]:n}}}function j(e){let{type:t,...n}=l;return{context_servers:{[e]:{...n}}}}function M(e){let{type:t,...n}=l;return{mcp:{[e]:{type:`local`,command:[n.command,...n.args]}}}}const N={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json`))},writeInstructions(e,t){let n=S(e,`.github`),r=S(n,`copilot-instructions.md`);g(n,{recursive:!0}),y(r,u(b(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,t){y(S(e,`AGENTS.md`),p(b(e),t),`utf-8`),console.log(` Updated AGENTS.md`)}},P=`Orchestrator`;function F(e){let{command:t,args:n}=l;return{[e]:{command:t,args:[...n],type:`stdio`,env:{}}}}function I(e,t){let n=t??S(C(),`.claude`),r=S(n,`settings.json`),i=S(n,`..`,`.claude.json`),a=F(e),o;if(!h(i))o={};else try{o=JSON.parse(_(i,`utf-8`))}catch{console.warn(` ⚠ ${i} invalid JSON — overwriting`),o={}}g(x(i),{recursive:!0}),o.mcpServers={...o.mcpServers||{},...a},y(i,`${JSON.stringify(o,null,2)}\n`,`utf-8`),console.log(` Updated ${i} — ${e} MCP server`);let s;if(!h(r))g(n,{recursive:!0}),s={agent:P};else{try{s=JSON.parse(_(r,`utf-8`))}catch{console.warn(` ⚠ ${r} invalid JSON — overwriting`),s={}}delete s.mcpServers}s.agent=P;let l=S(n,`hooks`,`scripts`).replace(/\\/g,`/`);try{let e=c(`claude`,l);e.hooks&&Object.keys(e.hooks).length>0&&(s.hooks=e.hooks)}catch{console.warn(` ⚠ Failed to generate hooks block`)}y(r,`${JSON.stringify(s,null,2)}\n`,`utf-8`),console.log(` Updated ${r} — default agent + hooks`)}const L={scaffoldDir:`general`,writeMcpConfig(e,t){I(t);let n=S(e,`.mcp.json`);h(n)||(y(n,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,t){let n=S(e,`CLAUDE.md`),r=b(e);y(n,`${u(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},R={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.cursor`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .cursor/mcp.json`))},writeInstructions(e,t){let n=S(e,`.cursor`,`rules`),r=S(n,`aikit.mdc`);g(n,{recursive:!0});let i=b(e);y(r,`${u(i,t)}\n---\n\n${p(i,t)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let a=S(n,`kb.mdc`);h(a)&&a!==r&&(v(a),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},z={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,t){let n=S(e,`.windsurfrules`),r=b(e);y(n,`${u(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}},B={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.zed`),r=S(n,`settings.json`);if(g(n,{recursive:!0}),!h(r))y(r,`${JSON.stringify(j(t),null,2)}\n`,`utf-8`),console.log(` Created .zed/settings.json`);else{let e;try{e=JSON.parse(_(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,...j(t).context_servers},y(r,`${JSON.stringify(e,null,2)}\n`,`utf-8`),console.log(` Updated .zed/settings.json with context_servers`))}},writeInstructions(e,t){let n=S(e,`.rules`),r=b(e);y(n,`${u(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated .rules`)},writeAgentsMd(e,t){}},V={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`mcp.json`);h(n)||(y(n,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created mcp.json`))},writeInstructions(e,t){let n=S(e,`.aiassistant`,`rules`),r=S(n,`aikit.md`);g(n,{recursive:!0});let i=b(e);y(r,`${u(i,t)}\n---\n\n${p(i,t)}`,`utf-8`),console.log(` Updated .aiassistant/rules/aikit.md`)},writeAgentsMd(e,t){}},H={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.opencode`),r=S(n,`opencode.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(M(t),null,2)}\n`,`utf-8`),console.log(` Created .opencode/opencode.json`))},writeInstructions(e,t){let n=S(e,`OPENCODE.md`),r=b(e);y(n,`${u(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated OPENCODE.md`)},writeAgentsMd(e,t){}},U={scaffoldDir:`general`,writeMcpConfig(e,t){},writeInstructions(e,t){let n=S(e,`AGENTS.md`),r=b(e);y(n,`${u(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated AGENTS.md (Hermes)`)},writeAgentsMd(e,t){}};function W(e){switch(e){case`copilot`:return N;case`claude-code`:return L;case`cursor`:return R;case`windsurf`:return z;case`zed`:return B;case`intellij`:return V;case`opencode`:return H;case`hermes`:return U;case`gemini-cli`:case`codex-cli`:return N}}const G={serverName:s,sources:[{path:`.`,excludePatterns:[`**/node_modules/**`,`**/dist/**`,`**/build/**`,`**/.git/**`,`**/${w.data}/**`,`**/coverage/**`,`**/*.min.js`,`**/package-lock.json`,`**/pnpm-lock.yaml`]}],indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:T.model,dimensions:T.dimensions},store:{backend:`sqlite-vec`,path:w.data},curated:{path:w.aiCurated}};function K(e,t){let n=S(e,`aikit.config.json`);return h(n)&&!t?(console.log(`aikit.config.json already exists. Use --force to overwrite.`),!1):(y(n,`${JSON.stringify(G,null,2)}\n`,`utf-8`),console.log(` Created aikit.config.json`),!0)}function q(e){let t=S(e,`.gitignore`),n=[{dir:`.flows/`,label:`AI Kit flow runs`}];if(h(t)){let e=_(t,`utf-8`),r=n.filter(t=>!e.includes(t.dir));r.length>0&&(m(t,`\n${r.map(e=>`# ${e.label}\n${e.dir}`).join(`
2
+ `)}\n`,`utf-8`),console.log(` Added ${r.map(e=>e.dir).join(`, `)} to .gitignore`))}else y(t,`${n.map(e=>`# ${e.label}\n${e.dir}`).join(`
3
+ `)}\n`,`utf-8`),console.log(` Created .gitignore with AI Kit entries`)}function J(){return G.serverName}const Y=[`decisions`,`patterns`,`conventions`,`troubleshooting`];function X(e){let t=S(e,`.ai`,`curated`);h(t)||(g(t,{recursive:!0}),console.log(` Created .ai/curated/`));for(let e of Y){let n=S(t,e);h(n)||g(n,{recursive:!0})}console.log(` Created .ai/curated/{${Y.join(`,`)}}/`)}function Z(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`;case`opencode`:return`opencode`;case`hermes`:return`hermes`;default:return`copilot`}}async function Q(n){let i=process.cwd();if(S(i)===S(C())){console.log(` Skipping workspace init: cannot scaffold the home directory.`),console.log(" Use `aikit init` (without --workspace) for user-level setup.");return}if(!K(i,n.force))return;q(i);let a=J(),s=W(D(i));s.writeMcpConfig(i,a),s.writeInstructions(i,a),s.writeAgentsMd(i,a);let c=o(),l=JSON.parse(_(S(c,`package.json`),`utf-8`)).version;await t(i,c,[...d],l,n.force),await r(i,c,[...f],l,n.force);let u=O(i),p=new Set;for(let t of u){let r=Z(t);p.has(r)||(p.add(r),await e(i,c,r,l,n.force))}X(i),console.log(`
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`),E()&&console.log(`
5
+ Note: User-level AI Kit is also installed. This workspace uses its own local data store.`)}async function ee(e){E()?await $(e):await Q(e)}async function $(t){let n=process.cwd();if(S(n)===S(C())){console.log(` Skipping workspace scaffold: cannot scaffold the home directory.`);return}let i=J(),a=W(D(n));a.writeInstructions(n,i),a.writeAgentsMd(n,i);let s=o(),c=JSON.parse(_(S(s,`package.json`),`utf-8`)).version,l=O(n),u=new Set;for(let r of l){let i=Z(r);u.has(i)||(u.add(i),await e(n,s,i,c,t.force))}await r(n,s,[...f],c,t.force),X(n),q(n),console.log(`
6
+ Workspace scaffolded for user-level AI Kit! Files added:`),console.log(` Instruction files (AGENTS.md, copilot-instructions.md, etc.)`),console.log(` .ai/curated/ directories`),console.log(` .github/agents/ & .github/prompts/`),console.log(`
7
+ The user-level AI Kit server will auto-index this workspace when opened in your IDE.`)}async function te(){let e=process.cwd(),t=O(e),r=o(),s=[...await i(e,r,[...d])],c=new Set;for(let i of t){let t=Z(i);c.has(t)||(c.add(t),s.push(...await n(e,r,t)))}s.push(...await a(e,r,[...f]));let l={summary:{total:s.length,new:s.filter(e=>e.status===`new`).length,outdated:s.filter(e=>e.status===`outdated`).length,current:s.filter(e=>e.status===`current`).length},files:s};console.log(JSON.stringify(l,null,2))}export{te as guideProject,Q as initProject,$ as initScaffoldOnly,ee as initSmart};