@vpxa/aikit 0.1.344 → 0.1.345

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 (47) hide show
  1. package/package.json +1 -1
  2. package/packages/cli/dist/index.js +19 -19
  3. package/packages/cli/dist/{init-DgYgDXBw.js → init-XINdWZ5p.js} +1 -1
  4. package/packages/cli/dist/{templates-DEHhml1n.js → templates-Cjsh5cLs.js} +48 -16
  5. package/packages/core/dist/index.d.ts +269 -2
  6. package/packages/core/dist/index.js +1 -1
  7. package/packages/flows/dist/index.d.ts +141 -4
  8. package/packages/flows/dist/index.js +6 -6
  9. package/packages/server/dist/bin.js +1 -1
  10. package/packages/server/dist/config-BsS-77rp.js +2 -0
  11. package/packages/server/dist/config-Ds28Hvip.js +1 -0
  12. package/packages/server/dist/index.js +1 -1
  13. package/packages/server/dist/prelude-DYBTvrwz.js +2 -0
  14. package/packages/server/dist/prelude-V2gaMyeg.js +1 -0
  15. package/packages/server/dist/promotion-DRnRfteq.js +3 -0
  16. package/packages/server/dist/promotion-DzVLWVtx.js +2 -0
  17. package/packages/server/dist/sampling-0YAQqixD.js +1 -0
  18. package/packages/server/dist/sampling-BQmYJ4pz.js +2 -0
  19. package/packages/server/dist/{server-qVK37TfU.js → server--QWu4dF1.js} +171 -169
  20. package/packages/server/dist/{server-2ntNwLtr.js → server-Cv8aM3Xx.js} +170 -170
  21. package/packages/server/dist/{server-http-BwaQWT2R.js → server-http-BF6fnIQ0.js} +1 -1
  22. package/packages/server/dist/{server-http-BXF275jD.js → server-http-DoIPqaqk.js} +1 -1
  23. package/packages/server/dist/{server-stdio-DVjY0Ebj.js → server-stdio-CFH9BET5.js} +1 -1
  24. package/packages/server/dist/{server-stdio-By2Kx_7Y.js → server-stdio-CXF39-d2.js} +1 -1
  25. package/packages/server/dist/{startup-maintenance-L9NUOBVy.js → startup-maintenance-CBJWiJ7p.js} +1 -1
  26. package/packages/server/dist/{startup-maintenance-DYmXBVTV.js → startup-maintenance-DX1yTfBa.js} +1 -1
  27. package/packages/server/dist/version-check-BjFqR01r.js +1 -0
  28. package/packages/server/dist/version-check-_2wmedTl.js +2 -0
  29. package/packages/tools/dist/index.d.ts +140 -1
  30. package/packages/tools/dist/index.js +87 -82
  31. package/scaffold/dist/adapters/_shared.mjs +9 -9
  32. package/scaffold/dist/definitions/agents.mjs +2 -2
  33. package/scaffold/dist/definitions/bodies.mjs +22 -13
  34. package/scaffold/dist/definitions/flows.mjs +28 -12
  35. package/scaffold/dist/definitions/protocols.mjs +38 -8
  36. package/scaffold/dist/definitions/skills/aikit.mjs +80 -17
  37. package/scaffold/dist/definitions/skills/docs.mjs +9 -0
  38. package/scaffold/dist/definitions/skills/lesson-learned.mjs +9 -0
  39. package/scaffold/dist/definitions/skills/multi-agents-development.mjs +10 -5
  40. package/packages/server/dist/config-B-wvmMyo.js +0 -1
  41. package/packages/server/dist/config-Bx85fwRX.js +0 -2
  42. package/packages/server/dist/prelude-DOxnDMN4.js +0 -2
  43. package/packages/server/dist/prelude-Dzih_AGV.js +0 -1
  44. package/packages/server/dist/promotion-RbjKfC88.js +0 -3
  45. package/packages/server/dist/promotion-l1L8Vf7U.js +0 -2
  46. package/packages/server/dist/version-check-2-tfmCnt.js +0 -2
  47. package/packages/server/dist/version-check-BKtLrLhw.js +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.344",
3
+ "version": "0.1.345",
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,C as s,D as c,E as l,F as u,I as d,L as f,M as p,N as m,O as ee,P as te,S as ne,T as re,_ as ie,a as h,b as ae,c as g,d as _,f as v,g as oe,h as y,i as b,j as se,k as x,l as ce,m as S,n as le,o as ue,p as C,r as de,s as fe,t as pe,u as me,v as he,w as ge,x as _e,y as ve}from"./templates-DEHhml1n.js";import{copyFileSync as ye,existsSync as w,mkdirSync as T,readFileSync as E,readdirSync as D,renameSync as be,rmSync as O,statSync as xe,unlinkSync as Se,writeFileSync as k}from"node:fs";import{basename as Ce,dirname as A,join as j,posix as M,relative as we,resolve as N,win32 as P}from"node:path";import{fileURLToPath as Te}from"node:url";import{initializeWasm as Ee}from"../../chunker/dist/index.js";import{AIKIT_PATHS as F,AIKIT_RUNTIME_PATHS as De,EMBEDDING_DEFAULTS as Oe,INSTALL_ARGS as ke,createLogger as I,getGlobalDataDir as Ae,getPartitionDir as je,isUserInstalled as Me,migrateLegacyWorkspaceLayout as Ne,registerWorkspace as Pe,saveRegistry as Fe}from"../../core/dist/index.js";import{OnnxEmbedder as Ie}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Le}from"../../indexer/dist/index.js";import{SqliteGraphStore as Re,createSqliteAdapter as ze,createStore as Be}from"../../store/dist/index.js";import{mkdir as Ve,readFile as He,rename as Ue,rm as We,unlink as Ge,writeFile as L}from"node:fs/promises";import{addToWorkset as Ke,audit as qe,check as Je,checkpointLatest as Ye,checkpointList as Xe,checkpointLoad as Ze,checkpointSave as Qe,codemod as $e,compact as et,dataTransform as tt,delegate as nt,delegateListModels as rt,deleteWorkset as it,diffParse as at,evaluate as ot,fileSummary as st,find as ct,findDeadSymbols as lt,findExamples as ut,getWorkset as dt,gitContext as ft,graphQuery as pt,guide as mt,health as ht,laneCreate as gt,laneDiff as _t,laneDiscard as vt,laneList as yt,laneMerge as bt,laneStatus as xt,listWorksets as St,parseOutput as Ct,processList as wt,processLogs as Tt,processStart as Et,processStatus as Dt,processStop as Ot,queueClear as kt,queueCreate as At,queueDelete as jt,queueDone as Mt,queueFail as Nt,queueGet as Pt,queueList as Ft,queueNext as It,queuePush as Lt,removeFromWorkset as Rt,rename as zt,replayClear as Bt,replayList as Vt,replayTrim as Ht,saveWorkset as Ut,scopeMap as Wt,stashClear as Gt,stashDelete as Kt,stashGet as qt,stashList as Jt,stashSet as Yt,symbol as Xt,testRun as Zt,trace as Qt,watchList as $t,watchStart as en,watchStop as tn}from"../../tools/dist/index.js";import{execFileSync as nn,execSync as R,fork as rn,spawn as an}from"node:child_process";import{arch as on,homedir as z,platform as sn}from"node:os";import{extractSvg as cn,renderToResult as ln,sanitizeTitle as un}from"../../server/dist/index.js";import{randomUUID as dn}from"node:crypto";import{parse as fn,stringify as pn}from"yaml";function mn(){let e=process.env.AIKIT_CONFIG_PATH??(w(N(process.cwd(),`aikit.config.json`))?N(process.cwd(),`aikit.config.json`):null),t=e?A(e):process.cwd();if(Ne(t),!e)return hn();let n=E(e,`utf-8`),r;try{r=JSON.parse(n)}catch{console.error(`Failed to parse ${e} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let i=t;return r.sources=r.sources.map(e=>({...e,path:N(i,e.path)})),r.store.path=N(i,r.store.path),r.curated=r.curated??{path:F.aiCurated},r.curated.path=N(i,r.curated.path),r.onboardDir||=F.aiContext,r.onboardDir=N(i,r.onboardDir),r.stateDir||=F.state,r.stateDir=N(i,r.stateDir),gn(r,i),r}function hn(){let e=process.env.AIKIT_WORKSPACE_ROOT??process.cwd();Ne(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:Oe.model,dimensions:Oe.dimensions},store:{backend:`sqlite-vec`,path:N(e,F.data)},curated:{path:N(e,F.aiCurated)},onboardDir:N(e,F.aiContext),stateDir:N(e,F.state)};return gn(t,e),t}function gn(e,t){if(!Me())return;let n=Pe(t);e.store.path=N(je(n.partition),De.data),e.stateDir=N(je(n.partition),De.state),e.onboardDir=N(je(n.partition),De.onboard),e.curated={path:N(je(n.partition),De.curated)}}async function _n(){let e=mn(),t=new Ie({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=N(e.store.path,`aikit.db`),r=A(t);if(!w(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await ze(t)}let r=await Be({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new Le(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new Re({adapter:n}):new Re({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,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 Ee().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const vn=[{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 g(`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=N(n),d;switch(t){case`structure`:d=await new c().analyze(u,{format:`markdown`});break;case`deps`:case`dependencies`:d=await new i().analyze(u,{format:`markdown`});break;case`symbols`:d=await new l().analyze(u,{format:`markdown`});break;case`patterns`:d=await new s().analyze(u,{format:`markdown`});break;case`entry-points`:d=await new o().analyze(u,{format:`markdown`});break;case`blast-radius`:d=await new r().analyze(process.cwd(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:throw new g(`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||=process.cwd();let a=N(n),o=mn();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}`)}}],yn=[{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=v(e,`--tool`,``).trim()||void 0,n=await m();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),ee(Ct(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 ft({cwd:v(e,`--cwd`,``).trim()||void 0,commitCount:_(e,`--commit-count`,5),includeDiff:me(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 m();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),ne(at({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)),ge(await st({path:N(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 ce();switch(t){case`save`:{let t=e.shift()?.trim(),r=v(e,`--data`,``),i=v(e,`--notes`,``).trim()||void 0,a=r.trim()?``:await m();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),ae(Qe(n,t,he(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=Ze(n,t);if(!r){console.log(`No checkpoint found: ${t}`);return}ae(r);return}case`list`:{let e=Xe(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=Ye(n);if(!e){console.log(`No checkpoints saved.`);return}ae(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],bn=j(z(),`.aikit`),B=j(bn,`daemon.json`),xn=3210,V=I(`cli:daemon`);function Sn(){if(!w(B))return null;try{return JSON.parse(E(B,`utf-8`))}catch{return null}}function Cn(e){w(bn)||T(bn,{recursive:!0});let t=`${B}.tmp`;k(t,JSON.stringify(e,null,2)),be(t,B)}function wn(){w(B)&&O(B)}async function H(e){try{return process.kill(e,0),!0}catch{return!1}}async function Tn(e){try{return(await fetch(`http://127.0.0.1:${e}/health`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}async function En(e,t){let n=Date.now();for(V.debug(`Polling health endpoint on port ${e}...`);Date.now()-n<t;){if(await Tn(e))return V.debug(`Daemon health check passed`),!0;await new Promise(e=>setTimeout(e,200))}return!1}async function Dn(){let e=Sn();if(!e)return V.info(`Daemon is not running`),null;if(!await H(e.pid))return wn(),V.debug(`Daemon was not running (stale state cleaned up)`),{pid:e.pid,wasRunning:!1};V.debug(`Sending SIGTERM to daemon...`);try{process.kill(e.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(e.pid)&&(V.debug(`Sending SIGKILL to daemon...`),process.kill(e.pid,`SIGKILL`))}catch{}return wn(),{pid:e.pid,wasRunning:!0}}async function On(e){let t=te();V.debug(`Spawning daemon process...`);let n=an(process.execPath,[t,`--transport`,`http`,`--port`,String(e)],{stdio:`ignore`,detached:!0,env:{...process.env,NODE_OPTIONS:f(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)}});n.unref(),await En(e,3e4)||(V.error(`Daemon failed to start within 30 seconds`),n.kill(`SIGTERM`),process.exit(1));let r=y();if(n.pid===void 0)throw Error(`Daemon child process has no PID`);return Cn({port:e,pid:n.pid,version:r,startedAt:new Date().toISOString()}),{pid:n.pid,port:e}}const kn=[{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=Sn();if(t){if(await H(t.pid)&&await Tn(t.port)){V.info(`Daemon already running (PID ${t.pid}, port ${t.port})`);return}V.debug(`Cleaning up stale daemon state...`),wn()}let n=e.indexOf(`--port`),r=await On(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):xn);V.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}case`stop`:{let e=await Dn();e?.wasRunning&&V.info(`Daemon stopped (PID ${e.pid})`);return}case`status`:{let e=Sn();if(!e){console.log(`Daemon: stopped`);return}if(!(await H(e.pid)&&await Tn(e.port))){wn(),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=Sn();if(t){if(await H(t.pid)){V.debug(`Sending SIGTERM to daemon...`);try{process.kill(t.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(t.pid)&&(V.debug(`Sending SIGKILL to daemon...`),process.kill(t.pid,`SIGKILL`))}catch{}}wn(),V.info(`Daemon stopped (PID ${t.pid})`)}else V.info(`Daemon is not running`);let n=e.indexOf(`--port`),r=await On(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):xn);V.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}default:console.error(`Unknown daemon command: ${t}`),console.error("Use `aikit daemon` for help.")}}}],An=[{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=ln(l,{title:r||void 0,subtitle:i||void 0,dualOutput:!0});if(n){let t=N(n);await Ve(t,{recursive:!0});let i=un(r||l.meta?.title||`diagram`);if(a===`all`||a===`html`){let n=j(t,`${i}.html`);await L(n,e.html,`utf-8`),console.log(`Written: ${n}`)}if((a===`all`||a===`md`)&&e.markdown){let n=j(t,`${i}.md`);await L(n,e.markdown,`utf-8`),console.log(`Written: ${n}`)}if(a===`all`||a===`svg`){let n=cn(e.html);if(n){let e=j(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 jn(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(!w(t))return{};let n=await He(t,`utf-8`);try{return JSON.parse(jn(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=A(n),i=j(r,`.aikit-tmp-${dn()}.json`);await Ve(r,{recursive:!0});try{await L(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await Ue(i,n)}catch(e){try{await Ge(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}`}},Mn=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(this.getPathModule().resolve(z(),`.claude`)):!1}getConfigPath(){return this.getPathModule().resolve(z(),`.claude`,`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),`.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:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?P:M}},Nn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(this.getPathModule().resolve(z(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(z(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),`.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`?P:M}},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 w(e)||t!==null&&w(t)}return w(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),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=z();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`?P:M}},Pn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(N(z(),`.copilot`)):!1}getConfigPath(){return N(z(),`.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 N(z(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=N(z(),`.copilot`);return{agents:N(e,`agents`),skills:N(e,`skills`),prompts:null,flows:N(e,`flows`),hooks:N(e,`hooks`),commands:null,instructions:N(z(),`.github`,`copilot-instructions.md`),manifest:N(e,`.aikit-scaffold.json`)}}},Fn=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(z(),this.scaffoldBase,`rules`,`aikit.mdc`)}},In=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(z(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Ln=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(w(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!w(t))return!1;try{return D(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return N(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ve(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=N(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=z();return process.platform===`win32`?N(process.env.LOCALAPPDATA??N(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?N(e,`Library`,`Application Support`,`github-copilot`,`intellij`):N(process.env.XDG_CONFIG_HOME??N(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=z();return process.platform===`win32`?N(process.env.APPDATA??N(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?N(e,`Library`,`Application Support`,`JetBrains`):N(process.env.XDG_CONFIG_HOME??N(e,`.config`),`JetBrains`)}},Rn=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(z(),this.scaffoldBase,`rules`,`aikit.md`)}},zn=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(z(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Bn=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(z(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Vn=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(z(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Hn=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(z(),this.scaffoldBase,`rules`,`aikit.md`)}},Un=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(this.getPathModule().resolve(z(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(z(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),`.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`?P:M}},Wn=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 w(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!w(e))return{};let t=E(e,`utf-8`);try{return fn(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(w(t))try{r=fn(E(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ve(n,{recursive:!0}),k(t,pn(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,C as s,D as c,E as l,F as u,I as d,L as f,M as p,N as m,O as ee,P as te,S as ne,T as re,_ as ie,a as h,b as g,c as _,d as v,f as y,g as ae,h as oe,i as b,j as se,k as x,l as ce,m as S,n as le,o as ue,p as de,r as fe,s as pe,t as me,u as C,v as he,w as ge,x as _e,y as ve}from"./templates-Cjsh5cLs.js";import{copyFileSync as ye,existsSync as w,mkdirSync as T,readFileSync as E,readdirSync as D,renameSync as be,rmSync as O,statSync as xe,unlinkSync as Se,writeFileSync as k}from"node:fs";import{basename as Ce,dirname as A,join as j,posix as M,relative as we,resolve as N,win32 as P}from"node:path";import{fileURLToPath as Te}from"node:url";import{initializeWasm as Ee}from"../../chunker/dist/index.js";import{AIKIT_PATHS as F,AIKIT_RUNTIME_PATHS as De,EMBEDDING_DEFAULTS as Oe,INSTALL_ARGS as ke,cleanupOldVersions as Ae,createLogger as I,getGlobalDataDir as je,getPartitionDir as Me,isUserInstalled as Ne,migrateLegacyWorkspaceLayout as Pe,registerWorkspace as Fe,saveRegistry as Ie}from"../../core/dist/index.js";import{OnnxEmbedder as Le}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Re}from"../../indexer/dist/index.js";import{SqliteGraphStore as ze,createSqliteAdapter as Be,createStore as Ve}from"../../store/dist/index.js";import{mkdir as He,readFile as Ue,rename as We,rm as Ge,unlink as Ke,writeFile as L}from"node:fs/promises";import{addToWorkset as qe,audit as Je,check as Ye,checkpointLatest as Xe,checkpointList as Ze,checkpointLoad as Qe,checkpointSave as $e,codemod as et,compact as tt,dataTransform as nt,delegate as rt,delegateListModels as it,deleteWorkset as at,diffParse as ot,evaluate as st,fileSummary as ct,find as lt,findDeadSymbols as ut,findExamples as dt,getWorkset as ft,gitContext as pt,graphQuery as mt,guide as ht,health as gt,laneCreate as _t,laneDiff as vt,laneDiscard as yt,laneList as bt,laneMerge as xt,laneStatus as St,listWorksets as Ct,parseOutput as wt,processList as Tt,processLogs as Et,processStart as Dt,processStatus as Ot,processStop as kt,queueClear as At,queueCreate as jt,queueDelete as Mt,queueDone as Nt,queueFail as Pt,queueGet as Ft,queueList as It,queueNext as Lt,queuePush as Rt,removeFromWorkset as zt,rename as Bt,replayClear as Vt,replayList as Ht,replayTrim as Ut,saveWorkset as Wt,scopeMap as Gt,stashClear as Kt,stashDelete as qt,stashGet as Jt,stashList as Yt,stashSet as Xt,symbol as Zt,testRun as Qt,trace as $t,watchList as en,watchStart as tn,watchStop as nn}from"../../tools/dist/index.js";import{execFileSync as rn,execSync as R,fork as an,spawn as on}from"node:child_process";import{arch as sn,homedir as z,platform as cn}from"node:os";import{extractSvg as ln,renderToResult as un,sanitizeTitle as dn}from"../../server/dist/index.js";import{randomUUID as fn}from"node:crypto";import{parse as pn,stringify as mn}from"yaml";function hn(){let e=process.env.AIKIT_CONFIG_PATH??(w(N(process.cwd(),`aikit.config.json`))?N(process.cwd(),`aikit.config.json`):null),t=e?A(e):process.cwd();if(Pe(t),!e)return gn();let n=E(e,`utf-8`),r;try{r=JSON.parse(n)}catch{console.error(`Failed to parse ${e} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let i=t;return r.sources=r.sources.map(e=>({...e,path:N(i,e.path)})),r.store.path=N(i,r.store.path),r.curated=r.curated??{path:F.aiCurated},r.curated.path=N(i,r.curated.path),r.onboardDir||=F.aiContext,r.onboardDir=N(i,r.onboardDir),r.stateDir||=F.state,r.stateDir=N(i,r.stateDir),_n(r,i),r}function gn(){let e=process.env.AIKIT_WORKSPACE_ROOT??process.cwd();Pe(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:Oe.model,dimensions:Oe.dimensions},store:{backend:`sqlite-vec`,path:N(e,F.data)},curated:{path:N(e,F.aiCurated)},onboardDir:N(e,F.aiContext),stateDir:N(e,F.state)};return _n(t,e),t}function _n(e,t){if(!Ne())return;let n=Fe(t);e.store.path=N(Me(n.partition),De.data),e.stateDir=N(Me(n.partition),De.state),e.onboardDir=N(Me(n.partition),De.onboard),e.curated={path:N(Me(n.partition),De.curated)}}async function vn(){let e=hn(),t=new Le({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=N(e.store.path,`aikit.db`),r=A(t);if(!w(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await Be(t)}let r=await Ve({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new Re(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new ze({adapter:n}):new ze({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,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 Ee().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const yn=[{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 _(`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=N(n),d;switch(t){case`structure`:d=await new c().analyze(u,{format:`markdown`});break;case`deps`:case`dependencies`:d=await new i().analyze(u,{format:`markdown`});break;case`symbols`:d=await new l().analyze(u,{format:`markdown`});break;case`patterns`:d=await new s().analyze(u,{format:`markdown`});break;case`entry-points`:d=await new o().analyze(u,{format:`markdown`});break;case`blast-radius`:d=await new r().analyze(process.cwd(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:throw new _(`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||=process.cwd();let a=N(n),o=hn();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}`)}}],bn=[{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=y(e,`--tool`,``).trim()||void 0,n=await m();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),ee(wt(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 pt({cwd:y(e,`--cwd`,``).trim()||void 0,commitCount:v(e,`--commit-count`,5),includeDiff:C(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 m();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),ne(ot({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)),ge(await ct({path:N(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 ce();switch(t){case`save`:{let t=e.shift()?.trim(),r=y(e,`--data`,``),i=y(e,`--notes`,``).trim()||void 0,a=r.trim()?``:await m();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),g($e(n,t,he(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=Qe(n,t);if(!r){console.log(`No checkpoint found: ${t}`);return}g(r);return}case`list`:{let e=Ze(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=Xe(n);if(!e){console.log(`No checkpoints saved.`);return}g(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],xn=j(z(),`.aikit`),B=j(xn,`daemon.json`),Sn=3210,V=I(`cli:daemon`);function Cn(){if(!w(B))return null;try{return JSON.parse(E(B,`utf-8`))}catch{return null}}function wn(e){w(xn)||T(xn,{recursive:!0});let t=`${B}.tmp`;k(t,JSON.stringify(e,null,2)),be(t,B)}function Tn(){w(B)&&O(B)}async function H(e){try{return process.kill(e,0),!0}catch{return!1}}async function En(e){try{return(await fetch(`http://127.0.0.1:${e}/health`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}async function Dn(e,t){let n=Date.now();for(V.debug(`Polling health endpoint on port ${e}...`);Date.now()-n<t;){if(await En(e))return V.debug(`Daemon health check passed`),!0;await new Promise(e=>setTimeout(e,200))}return!1}async function On(){let e=Cn();if(!e)return V.info(`Daemon is not running`),null;if(!await H(e.pid))return Tn(),V.debug(`Daemon was not running (stale state cleaned up)`),{pid:e.pid,wasRunning:!1};V.debug(`Sending SIGTERM to daemon...`);try{process.kill(e.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(e.pid)&&(V.debug(`Sending SIGKILL to daemon...`),process.kill(e.pid,`SIGKILL`))}catch{}return Tn(),{pid:e.pid,wasRunning:!0}}async function kn(e){let t=te();V.debug(`Spawning daemon process...`);let n=on(process.execPath,[t,`--transport`,`http`,`--port`,String(e)],{stdio:`ignore`,detached:!0,env:{...process.env,NODE_OPTIONS:f(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)}});n.unref(),await Dn(e,3e4)||(V.error(`Daemon failed to start within 30 seconds`),n.kill(`SIGTERM`),process.exit(1));let r=oe();if(n.pid===void 0)throw Error(`Daemon child process has no PID`);return wn({port:e,pid:n.pid,version:r,startedAt:new Date().toISOString()}),{pid:n.pid,port:e}}const An=[{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=Cn();if(t){if(await H(t.pid)&&await En(t.port)){V.info(`Daemon already running (PID ${t.pid}, port ${t.port})`);return}V.debug(`Cleaning up stale daemon state...`),Tn()}let n=e.indexOf(`--port`),r=await kn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):Sn);V.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}case`stop`:{let e=await On();e?.wasRunning&&V.info(`Daemon stopped (PID ${e.pid})`);return}case`status`:{let e=Cn();if(!e){console.log(`Daemon: stopped`);return}if(!(await H(e.pid)&&await En(e.port))){Tn(),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=Cn();if(t){if(await H(t.pid)){V.debug(`Sending SIGTERM to daemon...`);try{process.kill(t.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(t.pid)&&(V.debug(`Sending SIGKILL to daemon...`),process.kill(t.pid,`SIGKILL`))}catch{}}Tn(),V.info(`Daemon stopped (PID ${t.pid})`)}else V.info(`Daemon is not running`);let n=e.indexOf(`--port`),r=await kn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):Sn);V.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}default:console.error(`Unknown daemon command: ${t}`),console.error("Use `aikit daemon` for help.")}}}],jn=[{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=un(l,{title:r||void 0,subtitle:i||void 0,dualOutput:!0});if(n){let t=N(n);await He(t,{recursive:!0});let i=dn(r||l.meta?.title||`diagram`);if(a===`all`||a===`html`){let n=j(t,`${i}.html`);await L(n,e.html,`utf-8`),console.log(`Written: ${n}`)}if((a===`all`||a===`md`)&&e.markdown){let n=j(t,`${i}.md`);await L(n,e.markdown,`utf-8`),console.log(`Written: ${n}`)}if(a===`all`||a===`svg`){let n=ln(e.html);if(n){let e=j(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 Mn(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(!w(t))return{};let n=await Ue(t,`utf-8`);try{return JSON.parse(Mn(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=A(n),i=j(r,`.aikit-tmp-${fn()}.json`);await He(r,{recursive:!0});try{await L(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await We(i,n)}catch(e){try{await Ke(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}`}},Nn=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(this.getPathModule().resolve(z(),`.claude`)):!1}getConfigPath(){return this.getPathModule().resolve(z(),`.claude`,`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),`.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:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?P:M}},Pn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(this.getPathModule().resolve(z(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(z(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),`.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`?P:M}},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 w(e)||t!==null&&w(t)}return w(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),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=z();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`?P:M}},Fn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(N(z(),`.copilot`)):!1}getConfigPath(){return N(z(),`.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 N(z(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=N(z(),`.copilot`);return{agents:N(e,`agents`),skills:N(e,`skills`),prompts:null,flows:N(e,`flows`),hooks:N(e,`hooks`),commands:null,instructions:N(z(),`.github`,`copilot-instructions.md`),manifest:N(e,`.aikit-scaffold.json`)}}},In=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(z(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Ln=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(z(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Rn=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(w(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!w(t))return!1;try{return D(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return N(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await He(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=N(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=z();return process.platform===`win32`?N(process.env.LOCALAPPDATA??N(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?N(e,`Library`,`Application Support`,`github-copilot`,`intellij`):N(process.env.XDG_CONFIG_HOME??N(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=z();return process.platform===`win32`?N(process.env.APPDATA??N(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?N(e,`Library`,`Application Support`,`JetBrains`):N(process.env.XDG_CONFIG_HOME??N(e,`.config`),`JetBrains`)}},zn=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(z(),this.scaffoldBase,`rules`,`aikit.md`)}},Bn=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(z(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Vn=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(z(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Hn=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(z(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Un=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(z(),this.scaffoldBase,`rules`,`aikit.md`)}},Wn=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?w(this.getPathModule().resolve(z(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(z(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(z(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(z(),`.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`?P:M}},Gn=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 w(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!w(e))return{};let t=E(e,`utf-8`);try{return pn(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(w(t))try{r=pn(E(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await He(n,{recursive:!0}),k(t,mn(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_compact\`, \`mcp_aikit_digest\`, and \`mcp_aikit_stratum_card\` 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(z(),`AppData`,`Local`);return t.resolve(e,`hermes`)}return t.resolve(z(),`.hermes`)}getPathModule(){return process.platform===`win32`?P:M}},Gn=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=z();return[e.resolve(t,`.config`,`opencode`),e.resolve(t,`.opencode`)].some(e=>w(e))}getConfigPath(){return this.getPathModule().resolve(z(),`.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(z(),`.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`?P:M}},Kn=class extends W{id=`zed`;name=`Zed`;family=`zed`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`context_servers`;async detect(){return this.isPlatformSupported()?w(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||z(),`Zed`):e.resolve(z(),`.config`,`zed`)}getPathModule(){return process.platform===`win32`?P:M}};const qn=[new zn,new Bn,new Vn,new Fn,new In,new Hn,new Rn,new Pn,new Ln,new Mn,new Un,new Nn,new Kn,new Gn,new Wn];async function Jn(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 Yn=[`copilot`,`claude`,`copilotCli`,`hermes`],Xn={SessionStart:{copilot:`SessionStart`,claude:`PreToolCall`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolCall`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolCall`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`PreToolCall`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreToolCall`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`PostToolCall`,copilotCli:`stop`,hermes:`Stop`}},Zn={fileRead:{copilot:[`read_file`,`readFile`],claude:[`Read`],copilotCli:[`read_file`],hermes:[`read_file`]},fileWrite:{copilot:[`editFiles`,`replace_string_in_file`,`create_file`],claude:[`Write`,`Edit`],copilotCli:[`editFiles`,`replace_string_in_file`],hermes:[`write_file`,`patch`]},fileSearch:{copilot:[`grep_search`,`semantic_search`,`find`],claude:[`Bash`],copilotCli:[`grep_search`],hermes:[`search_files`]}},Qn={"privacy-guard":{id:`privacy-guard`,event:`PreToolUse`,tier:`safety`,description:`Blocks reads of secret-bearing env files, key material, SSH paths, and credential artifacts.`,script:`privacy-guard.mjs`,matcher:[`fileRead`],scope:`user`,patterns:[`.env`,`*.pem`,`*.key`,`id_rsa*`,`.ssh/*`,`*credentials*`,`*.secret`]},"scout-guard":{id:`scout-guard`,event:`PreToolUse`,tier:`safety`,description:`Blocks reads and searches inside generated, dependency, and git object directories.`,script:`scout-guard.mjs`,matcher:[`fileRead`,`fileSearch`],scope:`user`,patterns:[`node_modules/`,`dist/`,`.git/objects/`,`vendor/`,`build/`]},"subagent-context":{id:`subagent-context`,event:`SubagentStart`,tier:`efficiency`,description:`Injects compact project context into each subagent spawn to reduce repeated discovery.`,script:`subagent-context.mjs`,scope:`user`},"pre-compact-save":{id:`pre-compact-save`,event:`PreCompact`,tier:`efficiency`,description:`Persists critical state before context compaction truncates recent session history.`,script:`pre-compact-save.mjs`,scope:`user`},"post-edit-check":{id:`post-edit-check`,event:`PostToolUse`,tier:`nudge`,description:`After repeated file edits, injects a validation reminder so checks are not skipped.`,script:`post-edit-check.mjs`,matcher:[`fileWrite`],scope:`user`},"session-init":{id:`session-init`,event:`SessionStart`,tier:`nudge`,description:`Detects project stack and injects workspace metadata and environment context at startup.`,script:`session-init.mjs`,scope:`user`},"session-observer":{id:`session-observer`,event:`PostToolUse`,tier:`efficiency`,description:`Captures tool usage patterns for autonomous lesson extraction. Writes to session buffer.`,script:`session-observer.mjs`,scope:`user`},"session-learn":{id:`session-learn`,event:`Stop`,tier:`efficiency`,description:`Nudges final pattern analysis on buffered observations at session end.`,script:`session-learn.mjs`,scope:`user`}},$n={PreCompact:3e3,PostToolUse:3e3},er={copilot:`hooks.json`,claude:`hooks-settings.json`,copilotCli:`hooks.json`,hermes:`hooks.json`},tr=Yn;function nr(e){if(!tr.includes(e))throw Error(`Unknown platform: "${e}". Supported: ${tr.join(`, `)}. Add it to SUPPORTED_PLATFORMS in exec-hooks.mjs first, then add entries to HOOK_EVENTS, HOOK_TOOL_MATCHERS, and FILE_NAMES.`);for(let[t,n]of Object.entries(Xn))if(!(e in n))throw Error(`Platform "${e}" is missing from HOOK_EVENTS.${t}. Add a "${e}" key to HOOK_EVENTS.${t} in exec-hooks.mjs.`);for(let[t,n]of Object.entries(Zn))if(!(e in n))throw Error(`Platform "${e}" is missing from HOOK_TOOL_MATCHERS.${t}. Add a "${e}" key to HOOK_TOOL_MATCHERS.${t} in exec-hooks.mjs.`);if(!(e in er))throw Error(`Platform "${e}" is missing from FILE_NAMES. Add "${e}: '<filename>'" to FILE_NAMES in adapters/hooks.mjs.`)}function rr(e,t){return(e.matcher||[]).flatMap(e=>{let n=Zn[e];if(!n)throw Error(`Unknown hook matcher: ${e}`);return n[t]||[]})}function ir(e,t,n,r){let i=`${n}/${e.script}`;return rr(e,r),r===`copilot`?{event:t,steps:[{type:`command`,command:`node`,args:[i],timeout:$n[e.event]||5e3}]}:r===`claude`?{type:`command`,command:`node ${i}`}:{command:`node`,args:[i]}}function ar(e,t){if(nr(e),e===`copilot`){let n=Object.values(Qn).flatMap(n=>{let r=Xn[n.event]?.[e];return r?ir(n,r,t,e):(console.warn(`[aikit] Unsupported hook event ${n.event} for ${e} — skipping`),[])});return[{path:er[e],content:JSON.stringify({hooks:n},null,2)}]}let n={};for(let r of Object.values(Qn)){let i=Xn[r.event]?.[e];if(!i){console.warn(`[aikit] Unsupported hook event ${r.event} for ${e} — skipping`);continue}n[i]||=[],n[i].push(ir(r,i,t,e))}return[{path:er[e],content:JSON.stringify({hooks:n},null,2)}]}function or(){return[`_runtime.mjs`,...Object.values(Qn).map(e=>e.script)]}const K=I(`cli:install`),sr=/^\d+\.\d+\.\d+(-[\w.+]+)?(\+[\w.]+)?$/,q=j(z(),`.aikit`),J=j(q,`versions`),cr=j(q,`current-version.json`),lr=`@vpxa/aikit`,ur=`Usage:
17
+ 4. **Use context compression** — \`mcp_aikit_compact\`, \`mcp_aikit_digest\`, and \`mcp_aikit_stratum_card\` 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(z(),`AppData`,`Local`);return t.resolve(e,`hermes`)}return t.resolve(z(),`.hermes`)}getPathModule(){return process.platform===`win32`?P:M}},Kn=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=z();return[e.resolve(t,`.config`,`opencode`),e.resolve(t,`.opencode`)].some(e=>w(e))}getConfigPath(){return this.getPathModule().resolve(z(),`.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(z(),`.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`?P:M}},qn=class extends W{id=`zed`;name=`Zed`;family=`zed`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`context_servers`;async detect(){return this.isPlatformSupported()?w(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||z(),`Zed`):e.resolve(z(),`.config`,`zed`)}getPathModule(){return process.platform===`win32`?P:M}};const Jn=[new Bn,new Vn,new Hn,new In,new Ln,new Un,new zn,new Fn,new Rn,new Nn,new Wn,new Pn,new qn,new Kn,new Gn];async function Yn(e){let t=e?.scope?Jn.filter(t=>t.scope===e.scope):Jn;return(await Promise.allSettled(t.map(async e=>await e.detect()?e:null))).flatMap(e=>e.status!==`fulfilled`||e.value===null?[]:[e.value])}const Xn=[`copilot`,`claude`,`copilotCli`,`hermes`],Zn={SessionStart:{copilot:`SessionStart`,claude:`PreToolCall`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolCall`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolCall`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`PreToolCall`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreToolCall`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`PostToolCall`,copilotCli:`stop`,hermes:`Stop`}},Qn={fileRead:{copilot:[`read_file`,`readFile`],claude:[`Read`],copilotCli:[`read_file`],hermes:[`read_file`]},fileWrite:{copilot:[`editFiles`,`replace_string_in_file`,`create_file`],claude:[`Write`,`Edit`],copilotCli:[`editFiles`,`replace_string_in_file`],hermes:[`write_file`,`patch`]},fileSearch:{copilot:[`grep_search`,`semantic_search`,`find`],claude:[`Bash`],copilotCli:[`grep_search`],hermes:[`search_files`]}},$n={"privacy-guard":{id:`privacy-guard`,event:`PreToolUse`,tier:`safety`,description:`Blocks reads of secret-bearing env files, key material, SSH paths, and credential artifacts.`,script:`privacy-guard.mjs`,matcher:[`fileRead`],scope:`user`,patterns:[`.env`,`*.pem`,`*.key`,`id_rsa*`,`.ssh/*`,`*credentials*`,`*.secret`]},"scout-guard":{id:`scout-guard`,event:`PreToolUse`,tier:`safety`,description:`Blocks reads and searches inside generated, dependency, and git object directories.`,script:`scout-guard.mjs`,matcher:[`fileRead`,`fileSearch`],scope:`user`,patterns:[`node_modules/`,`dist/`,`.git/objects/`,`vendor/`,`build/`]},"subagent-context":{id:`subagent-context`,event:`SubagentStart`,tier:`efficiency`,description:`Injects compact project context into each subagent spawn to reduce repeated discovery.`,script:`subagent-context.mjs`,scope:`user`},"pre-compact-save":{id:`pre-compact-save`,event:`PreCompact`,tier:`efficiency`,description:`Persists critical state before context compaction truncates recent session history.`,script:`pre-compact-save.mjs`,scope:`user`},"post-edit-check":{id:`post-edit-check`,event:`PostToolUse`,tier:`nudge`,description:`After repeated file edits, injects a validation reminder so checks are not skipped.`,script:`post-edit-check.mjs`,matcher:[`fileWrite`],scope:`user`},"session-init":{id:`session-init`,event:`SessionStart`,tier:`nudge`,description:`Detects project stack and injects workspace metadata and environment context at startup.`,script:`session-init.mjs`,scope:`user`},"session-observer":{id:`session-observer`,event:`PostToolUse`,tier:`efficiency`,description:`Captures tool usage patterns for autonomous lesson extraction. Writes to session buffer.`,script:`session-observer.mjs`,scope:`user`},"session-learn":{id:`session-learn`,event:`Stop`,tier:`efficiency`,description:`Nudges final pattern analysis on buffered observations at session end.`,script:`session-learn.mjs`,scope:`user`}},er={PreCompact:3e3,PostToolUse:3e3},tr={copilot:`hooks.json`,claude:`hooks-settings.json`,copilotCli:`hooks.json`,hermes:`hooks.json`},nr=Xn;function rr(e){if(!nr.includes(e))throw Error(`Unknown platform: "${e}". Supported: ${nr.join(`, `)}. Add it to SUPPORTED_PLATFORMS in exec-hooks.mjs first, then add entries to HOOK_EVENTS, HOOK_TOOL_MATCHERS, and FILE_NAMES.`);for(let[t,n]of Object.entries(Zn))if(!(e in n))throw Error(`Platform "${e}" is missing from HOOK_EVENTS.${t}. Add a "${e}" key to HOOK_EVENTS.${t} in exec-hooks.mjs.`);for(let[t,n]of Object.entries(Qn))if(!(e in n))throw Error(`Platform "${e}" is missing from HOOK_TOOL_MATCHERS.${t}. Add a "${e}" key to HOOK_TOOL_MATCHERS.${t} in exec-hooks.mjs.`);if(!(e in tr))throw Error(`Platform "${e}" is missing from FILE_NAMES. Add "${e}: '<filename>'" to FILE_NAMES in adapters/hooks.mjs.`)}function ir(e,t){return(e.matcher||[]).flatMap(e=>{let n=Qn[e];if(!n)throw Error(`Unknown hook matcher: ${e}`);return n[t]||[]})}function ar(e,t,n,r){let i=`${n}/${e.script}`;return ir(e,r),r===`copilot`?{event:t,steps:[{type:`command`,command:`node`,args:[i],timeout:er[e.event]||5e3}]}:r===`claude`?{type:`command`,command:`node ${i}`}:{command:`node`,args:[i]}}function or(e,t){if(rr(e),e===`copilot`){let n=Object.values($n).flatMap(n=>{let r=Zn[n.event]?.[e];return r?ar(n,r,t,e):(console.warn(`[aikit] Unsupported hook event ${n.event} for ${e} — skipping`),[])});return[{path:tr[e],content:JSON.stringify({hooks:n},null,2)}]}let n={};for(let r of Object.values($n)){let i=Zn[r.event]?.[e];if(!i){console.warn(`[aikit] Unsupported hook event ${r.event} for ${e} — skipping`);continue}n[i]||=[],n[i].push(ar(r,i,t,e))}return[{path:tr[e],content:JSON.stringify({hooks:n},null,2)}]}function sr(){return[`_runtime.mjs`,...Object.values($n).map(e=>e.script)]}const K=I(`cli:install`),cr=/^\d+\.\d+\.\d+(-[\w.+]+)?(\+[\w.]+)?$/,q=j(z(),`.aikit`),J=j(q,`versions`),lr=j(q,`current-version.json`),ur=`@vpxa/aikit`,dr=`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 dr(e){if(!sr.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}async function fr(){let e=await fetch(`https://registry.npmjs.org/${lr}/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 pr(e){let t=j(e,`packages`,`server`,`dist`,`bin.js`);if(!w(t))throw Error(`Server entry point not found at ${t}. The installation may be incomplete or corrupted.`);let n=j(e,`node_modules`);if(!w(n))throw Error(`node_modules not found at ${n}. Production dependencies may not have been installed.`)}function mr(e){let t=j(e,`package.json`),n=JSON.parse(E(t,`utf-8`));if(!n.version)throw Error(`No "version" field in ${t}`);return n.version}function hr(e){w(q)||T(q,{recursive:!0});let t=j(q,`current-version.json.tmp`);k(t,`${JSON.stringify({version:e},null,2)}\n`),be(t,cr)}function gr(e){let t=D(e).filter(e=>e.endsWith(`.tgz`));return t.length>0?t[0]:null}function _r(e,t){K.debug(`Extracting...`),R(`tar -xzf "${t}"`,{cwd:e,stdio:`pipe`,timeout:6e4});let n=j(e,`package`);if(!w(n))throw Error(`Expected "package/" directory not found after extraction`);return K.debug(`Installing production dependencies...`),R(`npm ${ke.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5}),n}function vr(e,t){let n=j(J,`v${t}`);w(J)||T(J,{recursive:!0}),w(n)&&(K.debug(`Removing previous installation...`,{target:n}),O(n,{recursive:!0})),be(e,n),hr(t),K.debug(`Installation complete`,{package:`${lr}@${t}`,target:n})}function yr(){let e={win32:`win32`,darwin:`darwin`,linux:`linux`},t={x64:`x64`,arm64:`arm64`},n=e[sn()],r=t[on()];return!n||!r?(K.warn(`Unknown platform, falling back to npm pack`,{platform:sn(),arch:on()}),``):`${n}-${r}`}function br(e){let t=yr();if(!t)return null;let n=`aikit-v${e}-${t}.tar.gz`,r=j(j(q,`cache`,`tarballs`),n);return w(r)?r:null}function xr(e,t){let n=j(J,`v${t}-staging`);w(n)&&O(n,{recursive:!0}),T(n,{recursive:!0});try{K.debug(`Extracting prebuilt tarball...`),R(`tar -xzf "${e}"`,{cwd:n,stdio:`pipe`,timeout:6e4});let r=j(n,`aikit-v${t}-${yr()}`);if(!w(r)){let e=j(n,`package`);if(w(e)){K.debug(`Validating installation...`),pr(e),vr(e,t);return}throw Error(`Expected directory not found after extracting prebuilt tarball`)}K.debug(`Validating installation...`),pr(r),vr(r,t)}finally{w(n)&&O(n,{recursive:!0})}}function Sr(e){dr(e);let t=br(e);if(t){K.debug(`Found prebuilt tarball`,{path:t}),xr(t,e);return}let n=j(J,`v${e}-staging`);w(n)&&O(n,{recursive:!0}),T(n,{recursive:!0});try{K.debug(`Downloading...`,{package:`${lr}@${e}`}),R(`npm pack ${lr}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:n,stdio:`pipe`,timeout:12e4});let t=gr(n);if(!t)throw Error(`No .tgz file found after npm pack`);let r=_r(n,t);K.debug(`Validating installation...`),pr(r),vr(r,e)}finally{w(n)&&O(n,{recursive:!0})}}function Cr(e){dr(e);let t=j(J,`v${e}`);try{pr(t),hr(e)}catch{Sr(e)}}function wr(e){if(!w(e))throw Error(`Tarball not found: ${e}`);let t=j(J,`_offline-detect-${Date.now()}`);T(t,{recursive:!0});let n;try{R(`tar -xzf "${e}"`,{cwd:t,stdio:`pipe`,timeout:6e4}),n=mr(j(t,`package`))}finally{w(t)&&O(t,{recursive:!0})}K.debug(`Installing from local tarball...`,{package:`${lr}@${n}`});let r=j(J,`v${n}-staging`);w(r)&&O(r,{recursive:!0}),T(r,{recursive:!0});try{ye(e,j(r,`offline-${n}.tgz`));let t=_r(r,`offline-${n}.tgz`);return K.debug(`Validating installation...`),pr(t),vr(t,n),n}finally{w(r)&&O(r,{recursive:!0})}}async function Tr(e){try{let t=j(J,`v${e}`,`packages`,`server`,`dist`,`bin.js`);if(!w(t)){K.warn(`Server entry not found — skipping MCP registration`,{serverPath:t});return}let n={command:b.command,args:b.args?[...b.args]:void 0,type:b.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=nn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&w(e)&&(n.command=e)}catch{}}let r=await Jn({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(h,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 Er=[{name:`install`,description:`Install AI Kit to ~/.aikit/versions/ (one-time setup for fast local startup)`,usage:ur,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(ur);return}if(i){let t=e[n+1];await Tr(wr(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 fr(),K.debug(`Latest version detected`,{version:a})),Sr(a),await Tr(a),K.debug(`Install complete — restart your IDE to use the new version`)}}];function Dr(){let e=Or();if(e)return e;let t={command:b.command,args:b.args?[...b.args]:void 0,type:b.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(t.env={PATH:e});try{let e=nn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&w(e)&&(t.command=e)}catch{}}return t}function Or(){let e=j(z(),`.aikit`,`current-version.json`);if(!w(e))return null;try{let t=JSON.parse(E(e,`utf-8`));if(typeof t.version!=`string`||t.version.length===0||!w(j(j(z(),`.aikit`,`versions`,`v${t.version}`),`packages`,`server`,`dist`,`bin.js`)))return null;let n={command:b.command,args:b.args?[...b.args]:void 0,type:b.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=nn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&w(e)&&(n.command=e)}catch{}}return n}catch{return null}}const kr=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function Ar(e,t,n){let r=N(z(),`.copilot`,`instructions`,`copilot-instructions.md`);!w(r)||n.has(r)||(T(A(r),{recursive:!0}),k(r,`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`,`utf-8`),n.add(r))}function jr(e,t=!1){if(!kr.has(e.name))return;let n=N(A(e.getConfigPath()),`settings.json`),r={};if(w(n))try{let e=E(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(fe))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&&(k(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.name}: updated settings.json`))}async function Mr(r,o,s,c,l=!1){let u=new Map,d=new Set,f=le(`aikit`,s),p=pe(`aikit`,s);for(let e of o)e.getScaffoldRoot()!==null&&u.set(e.id,e);if(Ar(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 m=await n(r,`copilot`),ee=await n(r,`opencode`),te=await n(r,`hermes-agent`),ne=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)}}}return t},re=ne(m),ie=ne(ee),h=ne(te),ae=await n(r,`skills`),g=new Set;for(let e of ae){let t=e.path.indexOf(`/`);t!==-1&&g.add(e.path.substring(0,t))}let _=await n(r,`flows`),v=new Set;for(let e of _){let t=e.path.indexOf(`/`);t!==-1&&v.add(e.path.substring(0,t))}let oe=await n(r,`claude-code`),y=N(r,`scaffold`,`general`,`hooks`,`scripts`),b=w(y)?y:N(import.meta.dirname,`../../../../../scaffold/general/hooks/scripts`),se=or(),x=new Set,ce=new Set,S=new Set,ue=(n,r,o,s)=>{let u=s.get(o);if(!n||!r||!u||u.length===0)return;let d=`${o}:${r}:${n}`;if(x.has(d))return;x.add(d);let f=e(r)??a(c);f.version=c,i(u,n,f,o,l),t(r,f),S.add(A(r))},C=(n,r,o,s)=>{if(!n||!r||s.length===0)return;let u=`${o}:${r}:${n}`;if(x.has(u))return;if(x.add(u),o===`flows`&&!ce.has(n)){for(let e of v){let t=N(n,e,`skills`);w(t)&&(O(t,{recursive:!0,force:!0}),console.log(` ${A(r)}: migrated ${e} flow to steps/ layout`))}ce.add(n)}let d=e(r)??a(c);d.version=c,i(s,n,d,o,l),t(r,d),S.add(A(r))},de=(e,t,n)=>{!e||!t||C(e,t,`hooks`,[...ar(n,N(e,`scripts`).replace(/\\/g,`/`)),...se.map(e=>({path:`scripts/${e}`,content:E(N(b,e),`utf-8`)}))])};for(let e of u.values()){let t=e.getScaffoldPaths(),n=e.family===`opencode`?ie:e.family===`hermes`?h:re;ue(t.agents,t.manifest,`agents`,n),ue(t.prompts,t.manifest,`prompts`,n),C(t.skills,t.manifest,`skills`,ae),C(t.flows,t.manifest,`flows`,_),C(t.commands,t.manifest,`commands`,oe),de(t.hooks,t.manifest,e.family===`claude`?`claude`:`copilot`)}for(let e of S)console.log(` ${e}: scaffold updated (${g.size} skills)`);for(let e of u.values()){let t=e.getScaffoldPaths().instructions;!t||d.has(t)||(T(A(t),{recursive:!0}),k(t,e.buildInstructionContent(f,p),`utf-8`),d.add(t))}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}function Nr(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e)if(kr.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(N(r,`kb.instructions.md`)),t.push(N(r,`aikit.instructions.md`))}else n.name===`Cursor`||n.name===`Cursor Nightly`?t.push(N(e,`rules`,`kb.mdc`)):n.name===`Windsurf`&&t.push(N(e,`rules`,`kb.md`))}for(let e of t)w(e)&&(Se(e),console.log(` Removed legacy file: ${e}`))}async function Pr(e){let t=h,n=S(),r=JSON.parse(E(N(n,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${r}...\n`);let i=Ae();T(i,{recursive:!0}),console.log(` Global data store: ${i}`),console.log(` Managed runtime: v${r}`),Cr(r),Fe({version:1,workspaces:{}}),console.log(` Created registry.json`);let a=await Jn({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=Or();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)jr(t,e.force)}console.log(`
41
- Installing scaffold files:`),await Mr(n,a,t,r,e.force),Nr(a),console.log(`
39
+ --help, -h Show this help`;function fr(e){if(!cr.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}async function pr(){let e=await fetch(`https://registry.npmjs.org/${ur}/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 mr(e){let t=j(e,`packages`,`server`,`dist`,`bin.js`);if(!w(t))throw Error(`Server entry point not found at ${t}. The installation may be incomplete or corrupted.`);let n=j(e,`node_modules`);if(!w(n))throw Error(`node_modules not found at ${n}. Production dependencies may not have been installed.`)}function hr(e){let t=j(e,`package.json`),n=JSON.parse(E(t,`utf-8`));if(!n.version)throw Error(`No "version" field in ${t}`);return n.version}function gr(e){w(q)||T(q,{recursive:!0});let t=j(q,`current-version.json.tmp`);k(t,`${JSON.stringify({version:e},null,2)}\n`),be(t,lr)}function _r(e){let t=D(e).filter(e=>e.endsWith(`.tgz`));return t.length>0?t[0]:null}function vr(e,t){K.debug(`Extracting...`),R(`tar -xzf "${t}"`,{cwd:e,stdio:`pipe`,timeout:6e4});let n=j(e,`package`);if(!w(n))throw Error(`Expected "package/" directory not found after extraction`);return K.debug(`Installing production dependencies...`),R(`npm ${ke.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5}),n}function yr(e,t){let n=j(J,`v${t}`);w(J)||T(J,{recursive:!0}),w(n)&&(K.debug(`Removing previous installation...`,{target:n}),O(n,{recursive:!0})),be(e,n),gr(t),Ae(J,t),K.debug(`Installation complete`,{package:`${ur}@${t}`,target:n})}function br(){let e={win32:`win32`,darwin:`darwin`,linux:`linux`},t={x64:`x64`,arm64:`arm64`},n=e[cn()],r=t[sn()];return!n||!r?(K.warn(`Unknown platform, falling back to npm pack`,{platform:cn(),arch:sn()}),``):`${n}-${r}`}function xr(e){let t=br();if(!t)return null;let n=`aikit-v${e}-${t}.tar.gz`,r=j(j(q,`cache`,`tarballs`),n);return w(r)?r:null}function Sr(e,t){let n=j(J,`v${t}-staging`);w(n)&&O(n,{recursive:!0}),T(n,{recursive:!0});try{K.debug(`Extracting prebuilt tarball...`),R(`tar -xzf "${e}"`,{cwd:n,stdio:`pipe`,timeout:6e4});let r=j(n,`aikit-v${t}-${br()}`);if(!w(r)){let e=j(n,`package`);if(w(e)){K.debug(`Validating installation...`),mr(e),yr(e,t);return}throw Error(`Expected directory not found after extracting prebuilt tarball`)}K.debug(`Validating installation...`),mr(r),yr(r,t)}finally{w(n)&&O(n,{recursive:!0})}}function Cr(e){fr(e);let t=xr(e);if(t){K.debug(`Found prebuilt tarball`,{path:t}),Sr(t,e);return}let n=j(J,`v${e}-staging`);w(n)&&O(n,{recursive:!0}),T(n,{recursive:!0});try{K.debug(`Downloading...`,{package:`${ur}@${e}`}),R(`npm pack ${ur}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:n,stdio:`pipe`,timeout:12e4});let t=_r(n);if(!t)throw Error(`No .tgz file found after npm pack`);let r=vr(n,t);K.debug(`Validating installation...`),mr(r),yr(r,e)}finally{w(n)&&O(n,{recursive:!0})}}function wr(e){fr(e);let t=j(J,`v${e}`);try{mr(t),gr(e)}catch{Cr(e)}}function Tr(e){if(!w(e))throw Error(`Tarball not found: ${e}`);let t=j(J,`_offline-detect-${Date.now()}`);T(t,{recursive:!0});let n;try{R(`tar -xzf "${e}"`,{cwd:t,stdio:`pipe`,timeout:6e4}),n=hr(j(t,`package`))}finally{w(t)&&O(t,{recursive:!0})}K.debug(`Installing from local tarball...`,{package:`${ur}@${n}`});let r=j(J,`v${n}-staging`);w(r)&&O(r,{recursive:!0}),T(r,{recursive:!0});try{ye(e,j(r,`offline-${n}.tgz`));let t=vr(r,`offline-${n}.tgz`);return K.debug(`Validating installation...`),mr(t),yr(t,n),n}finally{w(r)&&O(r,{recursive:!0})}}async function Er(e){try{let t=j(J,`v${e}`,`packages`,`server`,`dist`,`bin.js`);if(!w(t)){K.warn(`Server entry not found — skipping MCP registration`,{serverPath:t});return}let n={command:b.command,args:b.args?[...b.args]:void 0,type:b.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=rn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&w(e)&&(n.command=e)}catch{}}let r=await Yn({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(h,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 Dr=[{name:`install`,description:`Install AI Kit to ~/.aikit/versions/ (one-time setup for fast local startup)`,usage:dr,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(dr);return}if(i){let t=e[n+1];await Er(Tr(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 pr(),K.debug(`Latest version detected`,{version:a})),Cr(a),await Er(a),K.debug(`Install complete — restart your IDE to use the new version`)}}];function Or(){let e=kr();if(e)return e;let t={command:b.command,args:b.args?[...b.args]:void 0,type:b.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(t.env={PATH:e});try{let e=rn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&w(e)&&(t.command=e)}catch{}}return t}function kr(){let e=j(z(),`.aikit`,`current-version.json`);if(!w(e))return null;try{let t=JSON.parse(E(e,`utf-8`));if(typeof t.version!=`string`||t.version.length===0||!w(j(j(z(),`.aikit`,`versions`,`v${t.version}`),`packages`,`server`,`dist`,`bin.js`)))return null;let n={command:b.command,args:b.args?[...b.args]:void 0,type:b.type};if(process.platform!==`win32`){let e=process.env.PATH;e&&(n.env={PATH:e});try{let e=rn(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();e&&w(e)&&(n.command=e)}catch{}}return n}catch{return null}}const Ar=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function jr(e,t,n){let r=N(z(),`.copilot`,`instructions`,`copilot-instructions.md`);!w(r)||n.has(r)||(T(A(r),{recursive:!0}),k(r,`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`,`utf-8`),n.add(r))}function Mr(e,t=!1){if(!Ar.has(e.name))return;let n=N(A(e.getConfigPath()),`settings.json`),r={};if(w(n))try{let e=E(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(pe))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&&(k(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.name}: updated settings.json`))}async function Nr(r,o,s,c,l=!1){let u=new Map,d=new Set,f=le(`aikit`,s),p=me(`aikit`,s);for(let e of o)e.getScaffoldRoot()!==null&&u.set(e.id,e);if(jr(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 m=await n(r,`copilot`),ee=await n(r,`opencode`),te=await n(r,`hermes-agent`),ne=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)}}}return t},re=ne(m),ie=ne(ee),h=ne(te),g=await n(r,`skills`),_=new Set;for(let e of g){let t=e.path.indexOf(`/`);t!==-1&&_.add(e.path.substring(0,t))}let v=await n(r,`flows`),y=new Set;for(let e of v){let t=e.path.indexOf(`/`);t!==-1&&y.add(e.path.substring(0,t))}let ae=await n(r,`claude-code`),oe=N(r,`scaffold`,`general`,`hooks`,`scripts`),b=w(oe)?oe:N(import.meta.dirname,`../../../../../scaffold/general/hooks/scripts`),se=sr(),x=new Set,ce=new Set,S=new Set,ue=(n,r,o,s)=>{let u=s.get(o);if(!n||!r||!u||u.length===0)return;let d=`${o}:${r}:${n}`;if(x.has(d))return;x.add(d);let f=e(r)??a(c);f.version=c,i(u,n,f,o,l),t(r,f),S.add(A(r))},de=(n,r,o,s)=>{if(!n||!r||s.length===0)return;let u=`${o}:${r}:${n}`;if(x.has(u))return;if(x.add(u),o===`flows`&&!ce.has(n)){for(let e of y){let t=N(n,e,`skills`);w(t)&&(O(t,{recursive:!0,force:!0}),console.log(` ${A(r)}: migrated ${e} flow to steps/ layout`))}ce.add(n)}let d=e(r)??a(c);d.version=c,i(s,n,d,o,l),t(r,d),S.add(A(r))},fe=(e,t,n)=>{!e||!t||de(e,t,`hooks`,[...or(n,N(e,`scripts`).replace(/\\/g,`/`)),...se.map(e=>({path:`scripts/${e}`,content:E(N(b,e),`utf-8`)}))])};for(let e of u.values()){let t=e.getScaffoldPaths(),n=e.family===`opencode`?ie:e.family===`hermes`?h:re;ue(t.agents,t.manifest,`agents`,n),ue(t.prompts,t.manifest,`prompts`,n),de(t.skills,t.manifest,`skills`,g),de(t.flows,t.manifest,`flows`,v),de(t.commands,t.manifest,`commands`,ae),fe(t.hooks,t.manifest,e.family===`claude`?`claude`:`copilot`)}for(let e of S)console.log(` ${e}: scaffold updated (${_.size} skills)`);for(let e of u.values()){let t=e.getScaffoldPaths().instructions;!t||d.has(t)||(T(A(t),{recursive:!0}),k(t,e.buildInstructionContent(f,p),`utf-8`),d.add(t))}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}function Pr(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e)if(Ar.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(N(r,`kb.instructions.md`)),t.push(N(r,`aikit.instructions.md`))}else n.name===`Cursor`||n.name===`Cursor Nightly`?t.push(N(e,`rules`,`kb.mdc`)):n.name===`Windsurf`&&t.push(N(e,`rules`,`kb.md`))}for(let e of t)w(e)&&(Se(e),console.log(` Removed legacy file: ${e}`))}async function Fr(e){let t=h,n=S(),r=JSON.parse(E(N(n,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${r}...\n`);let i=je();T(i,{recursive:!0}),console.log(` Global data store: ${i}`),console.log(` Managed runtime: v${r}`),wr(r),Ie({version:1,workspaces:{}}),console.log(` Created registry.json`);let a=await Yn({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=kr();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)Mr(t,e.force)}console.log(`
41
+ Installing scaffold files:`),await Nr(n,a,t,r,e.force),Pr(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 Fr=[{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`}],Ir=[`.copilot/skills`,`.agents/skills`],Lr=/^(?:mcp_)?aikit_[a-z0-9_]+$/;function Rr(e,t){return(we(e,t)||t).split(`\\`).join(`/`)}function zr(e){let t=new Set;for(let n of Fr){let r=j(e,n.directory);if(w(r))try{for(let e of D(r,{withFileTypes:!0})){if(n.suffix===`/SKILL.md`){if(e.isDirectory()){let n=j(r,e.name,`SKILL.md`);w(n)&&t.add(n)}continue}e.isFile()&&e.name.endsWith(n.suffix)&&t.add(j(r,e.name))}}catch{}}return[...t].sort()}function Br(e){let t=new Set;for(let n of Ir){let r=j(e,n);if(w(r))try{for(let e of D(r,{withFileTypes:!0}))e.isDirectory()&&t.add(e.name.toLowerCase())}catch{}}return t}function Vr(e){if(!e.startsWith(`---`))return null;let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return t?t[1]:null}function Hr(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=Ur(i);e&&r.push(e),i=``;continue}i+=e}let o=Ur(i);return o&&r.push(o),r}function Ur(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function Wr(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 Gr(e){if(!e.startsWith(`---`))return;let t=Vr(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 Wr(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=Wr(a);if(o)return o}}function Kr(e,t){try{let n=E(t,`utf8`),i=Gr(n);return{filePath:t,displayPath:Rr(e,t),content:n,parsed:i?null:r(n),yamlError:i}}catch{return null}}function qr(e){return zr(e).map(t=>Kr(e,t)).filter(e=>e!==null)}function Jr(e){if(!e.parsed)return[];let t=e.parsed.fields.applyTo;return t?Hr(t):[]}function Yr(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 Xr(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 Zr={name:`yaml-parse`,run:e=>{try{return qr(e).filter(e=>e.yamlError).map(e=>({severity:`error`,file:e.displayPath,message:`invalid YAML frontmatter: ${e.yamlError}`,code:`yaml-parse-error`}))}catch{return[]}}},Qr={name:`skill-refs`,run:e=>{try{let t=Br(e);if(t.size===0)return[];let n=[];for(let r of qr(e))if(r.filePath.endsWith(`.agent.md`))for(let e of Xr(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[]}}},$r={name:`tool-names`,run:e=>{try{let t=[];for(let n of qr(e))if(n.parsed)for(let e of n.parsed.tools.map(Ur))e&&!Lr.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[]}}},ei={name:`glob-patterns`,run:e=>{try{let t=[];for(let n of qr(e))if(n.parsed)for(let e of Jr(n)){let r=Yr(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 ti(e){let t=e.reset??!1,n=e.silent??!1,r=[],i=0,a=0,o=await Jn({scope:`user`}),s=Dr(),c=S(),l=y(),u=e=>{r.push(e),a+=1,n||console.log(`- ${e}`)};for(let e of o){let n=e.getConfigPath();if(i+=1,!w(n)){T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Fixed: ${e.name} — MCP config was missing, recreated`);continue}try{if(!(await e.readConfig())[e.configKey]?.aikit){T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Fixed: ${e.name} — MCP entry was missing, added`);continue}t&&(T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Reset: ${e.name} — MCP config restored to factory defaults`))}catch{ye(n,`${n}.bak`),T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Fixed: ${e.name} — MCP config was corrupt, backed up and recreated`)}}await Y(async()=>{for(let e of o)jr(e,t)}),await Y(()=>Mr(c,o,h,l??`0.0.0`,t));let d=[Zr,Qr,$r,ei];for(let e of d)try{let t=e.run(process.cwd());for(let e of t)(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 ni=[{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 Ir=[{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`}],Lr=[`.copilot/skills`,`.agents/skills`],Rr=/^(?:mcp_)?aikit_[a-z0-9_]+$/;function zr(e,t){return(we(e,t)||t).split(`\\`).join(`/`)}function Br(e){let t=new Set;for(let n of Ir){let r=j(e,n.directory);if(w(r))try{for(let e of D(r,{withFileTypes:!0})){if(n.suffix===`/SKILL.md`){if(e.isDirectory()){let n=j(r,e.name,`SKILL.md`);w(n)&&t.add(n)}continue}e.isFile()&&e.name.endsWith(n.suffix)&&t.add(j(r,e.name))}}catch{}}return[...t].sort()}function Vr(e){let t=new Set;for(let n of Lr){let r=j(e,n);if(w(r))try{for(let e of D(r,{withFileTypes:!0}))e.isDirectory()&&t.add(e.name.toLowerCase())}catch{}}return t}function Hr(e){if(!e.startsWith(`---`))return null;let t=e.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);return t?t[1]:null}function Ur(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=Wr(i);e&&r.push(e),i=``;continue}i+=e}let o=Wr(i);return o&&r.push(o),r}function Wr(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1).trim():t}function Gr(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 Kr(e){if(!e.startsWith(`---`))return;let t=Hr(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 Gr(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=Gr(a);if(o)return o}}function qr(e,t){try{let n=E(t,`utf8`),i=Kr(n);return{filePath:t,displayPath:zr(e,t),content:n,parsed:i?null:r(n),yamlError:i}}catch{return null}}function Jr(e){return Br(e).map(t=>qr(e,t)).filter(e=>e!==null)}function Yr(e){if(!e.parsed)return[];let t=e.parsed.fields.applyTo;return t?Ur(t):[]}function Xr(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 Zr(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 Jr(e).filter(e=>e.yamlError).map(e=>({severity:`error`,file:e.displayPath,message:`invalid YAML frontmatter: ${e.yamlError}`,code:`yaml-parse-error`}))}catch{return[]}}},$r={name:`skill-refs`,run:e=>{try{let t=Vr(e);if(t.size===0)return[];let n=[];for(let r of Jr(e))if(r.filePath.endsWith(`.agent.md`))for(let e of Zr(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[]}}},ei={name:`tool-names`,run:e=>{try{let t=[];for(let n of Jr(e))if(n.parsed)for(let e of n.parsed.tools.map(Wr))e&&!Rr.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[]}}},ti={name:`glob-patterns`,run:e=>{try{let t=[];for(let n of Jr(e))if(n.parsed)for(let e of Yr(n)){let r=Xr(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 ni(e){let t=e.reset??!1,n=e.silent??!1,r=[],i=0,a=0,o=await Yn({scope:`user`}),s=Or(),c=S(),l=oe(),u=e=>{r.push(e),a+=1,n||console.log(`- ${e}`)};for(let e of o){let n=e.getConfigPath();if(i+=1,!w(n)){T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Fixed: ${e.name} — MCP config was missing, recreated`);continue}try{if(!(await e.readConfig())[e.configKey]?.aikit){T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Fixed: ${e.name} — MCP entry was missing, added`);continue}t&&(T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Reset: ${e.name} — MCP config restored to factory defaults`))}catch{ye(n,`${n}.bak`),T(A(n),{recursive:!0}),await Y(()=>e.registerMcp(h,s)),u(`Fixed: ${e.name} — MCP config was corrupt, backed up and recreated`)}}await Y(async()=>{for(let e of o)Mr(e,t)}),await Y(()=>Nr(c,o,h,l??`0.0.0`,t));let d=[Qr,$r,ei,ti];for(let e of d)try{let t=e.run(process.cwd());for(let e of t)(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 ri=[{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 ti({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}`)}}}],ri=[{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)),c(Et(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=Ot(t);if(!n){console.log(`No managed process found: ${t}`);return}c(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=Dt(t);if(!n){console.log(`No managed process found: ${t}`);return}c(n);return}case`list`:{let e=wt();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)c(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=Tt(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=en({path:N(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=tn(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=$t();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 rt();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=v(e,`--model`,``),n=v(e,`--system`,``),r=_(e,`--temp`,.3),i=v(e,`--context`,``),a=e.join(` `);a||=await m(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await He(N(i),`utf-8`));let s=await nt({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)`)}}],ii=[{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=v(e,`--lang`,`js`),n=_(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await m(),a=r||i;if(!a.trim())throw new g(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`);let o=await ot({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=!me(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=v(e,`--grep`,``).trim()||void 0,n=v(e,`--cwd`,``).trim()||void 0,r=_(e,`--timeout`,6e4),i=e.filter(Boolean),a=await Zt({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});o(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 g(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let i=d(v(e,`--extensions`,``)),a=d(v(e,`--exclude`,``)),o=await zt({oldName:t,newName:n,rootPath:N(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:me(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=v(e,`--rules`,``).trim();if(!t||!n)throw new g(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let r=await He(N(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=d(v(e,`--extensions`,``)),o=d(v(e,`--exclude`,``)),s=await $e({rootPath:N(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:me(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 m();if(!t||!n.trim())throw new g(`Usage: cat data.json | aikit transform <expression>`);let r=tt({input:n,expression:t});console.log(r.outputString)}}];async function ai(){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=mn(),s=o.stateDir;if(!s)throw Error(`stateDir not configured`);let c=j(s,`flows`,`installed`),l=j(Ae(),`flows`);T(l,{recursive:!0});let u=j(l,`registry.json`),d=o.sources[0].path,f=j(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 oi=[e=>j(`skills`,e,`SKILL.md`),e=>j(`skills`,e,`README.md`),e=>j(e,`SKILL.md`),e=>j(e,`README.md`)];function si(e,t){for(let n of t.steps){let t=j(e,n.instruction);if(w(t))continue;let r=!1;for(let i of oi){let a=j(e,i(n.id));if(w(a)){let e=A(t);w(e)||T(e,{recursive:!0}),ye(a,t),r=!0;break}}r||console.warn(`Warning: instruction file for step "${n.id}" not found.\n Expected: ${n.instruction}\n Searched: ${oi.map(e=>e(n.id)).join(`, `)}`)}}const ci=[{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 ai();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=N(t),a=w(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]||Ce(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(si(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=I(`cli:gc`),li=j(z(),`.aikit`,`versions`),ui=j(z(),`.aikit`,`current-version.json`);function di(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 fi(e,t){return e.major===t.major?e.minor===t.minor?t.patch-e.patch:t.minor-e.minor:t.major-e.major}function pi(){try{return w(ui)?JSON.parse(E(ui,`utf-8`)).version??null:null}catch{return null}}const mi=[{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(!w(li)){X.info(`No version directories found.`);return}let t=_(e,`--keep`,2),n=pi(),r=D(li,{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 We(j(li,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:di(e.name)})).filter(e=>e.semver!==null).sort((e,t)=>fi(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 We(j(li,e.name),{recursive:!0,force:!0}),X.debug(`Removed ${e.name}`);X.info(`Removed ${s.length} versions`)}}];let hi=null;async function Z(){return hi||=await _n(),hi}function gi(){return hi}const _i=[{name:`graph`,description:`Query the knowledge graph`,usage:`aikit graph <action> [options]
45
+ `);let n=await ni({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}`)}}}],ii=[{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)),c(Dt(t,n,e));return}case`stop`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc stop <id>`),process.exit(1));let n=kt(t);if(!n){console.log(`No managed process found: ${t}`);return}c(n);return}case`status`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit proc status <id>`),process.exit(1));let n=Ot(t);if(!n){console.log(`No managed process found: ${t}`);return}c(n);return}case`list`:{let e=Tt();if(e.length===0){console.log(`No managed processes.`);return}for(let t of e)c(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=Et(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=tn({path:N(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=nn(t);console.log(n?`Stopped watcher: ${t}`:`Watcher not found: ${t}`);return}case`list`:{let e=en();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 it();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=y(e,`--model`,``),n=y(e,`--system`,``),r=v(e,`--temp`,.3),i=y(e,`--context`,``),a=e.join(` `);a||=await m(),a||(console.error(`Usage: aikit delegate [--model name] <prompt>`),process.exit(1));let o;i&&(o=await Ue(N(i),`utf-8`));let s=await rt({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)`)}}],ai=[{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=y(e,`--lang`,`js`),n=v(e,`--timeout`,5e3),r=e.join(` `),i=r.trim()?``:await m(),a=r||i;if(!a.trim())throw new _(`Usage: aikit eval [code] [--lang js|ts] [--timeout ms]`);let o=await st({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=!C(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=y(e,`--grep`,``).trim()||void 0,n=y(e,`--cwd`,``).trim()||void 0,r=v(e,`--timeout`,6e4),i=e.filter(Boolean),a=await Qt({files:i.length>0?i:void 0,grep:t,cwd:n,timeout:r});o(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 _(`Usage: aikit rename <old> <new> <path> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let i=d(y(e,`--extensions`,``)),a=d(y(e,`--exclude`,``)),o=await Bt({oldName:t,newName:n,rootPath:N(r),extensions:i.length>0?i:void 0,exclude:a.length>0?a:void 0,dryRun:C(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=y(e,`--rules`,``).trim();if(!t||!n)throw new _(`Usage: aikit codemod <path> --rules <file.json> [--dry-run] [--extensions .ts,.tsx] [--exclude dist/**]`);let r=await Ue(N(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=d(y(e,`--extensions`,``)),o=d(y(e,`--exclude`,``)),s=await et({rootPath:N(t),rules:i,extensions:a.length>0?a:void 0,exclude:o.length>0?o:void 0,dryRun:C(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 m();if(!t||!n.trim())throw new _(`Usage: cat data.json | aikit transform <expression>`);let r=nt({input:n,expression:t});console.log(r.outputString)}}];async function oi(){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=hn(),s=o.stateDir;if(!s)throw Error(`stateDir not configured`);let c=j(s,`flows`,`installed`),l=j(je(),`flows`);T(l,{recursive:!0});let u=j(l,`registry.json`),d=o.sources[0].path,f=j(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 si=[e=>j(`skills`,e,`SKILL.md`),e=>j(`skills`,e,`README.md`),e=>j(e,`SKILL.md`),e=>j(e,`README.md`)];function ci(e,t){for(let n of t.steps){let t=j(e,n.instruction);if(w(t))continue;let r=!1;for(let i of si){let a=j(e,i(n.id));if(w(a)){let e=A(t);w(e)||T(e,{recursive:!0}),ye(a,t),r=!0;break}}r||console.warn(`Warning: instruction file for step "${n.id}" not found.\n Expected: ${n.instruction}\n Searched: ${si.map(e=>e(n.id)).join(`, `)}`)}}const li=[{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 oi();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=N(t),a=w(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]||Ce(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(ci(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=I(`cli:gc`),ui=j(z(),`.aikit`,`versions`),di=j(z(),`.aikit`,`current-version.json`);function fi(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 pi(e,t){return e.major===t.major?e.minor===t.minor?t.patch-e.patch:t.minor-e.minor:t.major-e.major}function mi(){try{return w(di)?JSON.parse(E(di,`utf-8`)).version??null:null}catch{return null}}const hi=[{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(!w(ui)){X.info(`No version directories found.`);return}let t=v(e,`--keep`,2),n=mi(),r=D(ui,{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 Ge(j(ui,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:fi(e.name)})).filter(e=>e.semver!==null).sort((e,t)=>pi(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 Ge(j(ui,e.name),{recursive:!0,force:!0}),X.debug(`Removed ${e.name}`);X.info(`Removed ${s.length} versions`)}}];let gi=null;async function Z(){return gi||=await vn(),gi}function _i(){return gi}const vi=[{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 g(`Usage: aikit graph <action>
49
- Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await Z(),r=v(e,`--type`,``),i=v(e,`--name`,``),a=v(e,`--node-id`,``),o=v(e,`--edge-type`,``),s=v(e,`--direction`,`both`),c=_(e,`--depth`,2),l=_(e,`--limit`,50),u=v(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 g(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await pt(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 _(`Usage: aikit graph <action>
49
+ Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await Z(),r=y(e,`--type`,``),i=y(e,`--name`,``),a=y(e,`--node-id`,``),o=y(e,`--edge-type`,``),s=y(e,`--direction`,`both`),c=v(e,`--depth`,2),l=v(e,`--limit`,50),u=y(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 _(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await mt(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}`)}}],vi=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=v(e,`--category`,``).trim(),n=d(v(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await m(),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=v(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=v(e,`--category`,``).trim()||void 0,n=v(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=v(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await m();(!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=v(e,`--path`,``).trim()||void 0,r=v(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await m();(!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 et(o,{path:n,query:i,maxChars:t,segmentation:r}):await et(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 yi(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 bi(){let e=await Jn({scope:`user`});if(e.length===0)return 0;let t=Dr(),n=0;for(let r of e)try{let e=(await r.readConfig())[r.configKey]?.[h];if(!e||!yi(e))continue;T(A(r.getConfigPath()),{recursive:!0}),await r.registerMcp(h,t),n++}catch{}return n}const xi=[{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 bi();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=I(`cli:rollback`),Si=j(z(),`.aikit`,`versions`),Ci=j(z(),`.aikit`,`current-version.json`),wi=[{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=j(Si,`v${t}`);w(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=j(n,`package.json`);w(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(E(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=j(Si,`current-version.json.tmp`);await L(i,JSON.stringify({version:t},null,2),`utf-8`),await Ue(i,Ci),Q.debug(`Switched to v${t}`)}}],Ti=[{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=oe(e),n=_(e,`--limit`,5),r=v(e,`--mode`,`hybrid`),i=_(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new g(`Usage: aikit search <query>`);let{embedder:o,store:s,graphStore:c}=await Z(),d=await o.embedQuery(a),f;if(r===`keyword`)f=await s.ftsSearch(a,{limit:n});else if(r===`semantic`)f=await s.search(d,{limit:n});else{let[e,t]=await Promise.all([s.search(d,{limit:n*2}),s.ftsSearch(a,{limit:n*2}).catch(()=>[])]);f=u(e,t).slice(0,n)}if(t){l({query:a,results:f,graphHops:i});return}if(f.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of f){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(`${f.length} result(s) found.`),i>0&&f.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(c,f.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=oe(e),n=_(e,`--limit`,10),r=v(e,`--glob`,``).trim()||void 0,i=v(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new g(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:o,store:s}=await Z(),c=await ct(o,s,{query:a,glob:r,pattern:i,limit:n});if(t){l(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 g(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await Wt(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: ${C(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 g(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();x(await Xt(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=v(e,`--direction`,`both`).trim()||`both`,n=_(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new g(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();se(await Qt(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=v(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new g(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();s(await ut(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();_e(await lt(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 g(`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 Ei(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`),s=te(),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(t)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:f(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),l=`http://localhost:${t}${r}`,u=`http://localhost:${t}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!d)throw c.kill(),new g(`Server failed to start within 30 seconds.`);let p=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${p}: ${l}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let m=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,m),process.on(`SIGTERM`,m),await new Promise(e=>{c.on(`exit`,()=>e())})}const Di=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=oe(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=process.cwd(),u=a(),d=s(N(c,`.vscode`,`mcp.json`)),f={mode:void 0,dataPath:void 0};if(u&&d)f.mode=`workspace (overrides user-level for this workspace)`,f.dataPath=N(c,n.data);else if(u){let e=r(c);f.mode=s(N(c,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,f.dataPath=i(e)}else f.mode=`workspace`,f.dataPath=N(c,n.data);u&&!d&&(f.workspaces=o().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();f.records=t.totalRecords,f.files=t.totalFiles,f.lastIndexed=t.lastIndexedAt??null,f.backend=t.storeBackend,f.model=t.embeddingModel,f.contentTypeBreakdown=t.contentTypeBreakdown,f.sourcePaths=n.slice(0,20),f.sourcePathTotal=n.length}catch{f.indexAvailable=!1}if(t){l(f);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${f.mode}`),console.log(` Data: ${f.dataPath}`),u&&!d){let e=o();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(f.records!==void 0){console.log(` Records: ${f.records}`),console.log(` Files: ${f.files}`),console.log(` Indexed: ${f.lastIndexed??`Never`}`),console.log(` Backend: ${f.backend}`),console.log(` Model: ${f.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(f.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=f.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${f.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);f.sourcePathTotal>20&&console.log(` ... and ${f.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");u&&!d&&!s(N(c,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await 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=v(e,`--transport`,`stdio`),n=v(e,`--port`,`3210`),r=me(e,`--daemon`);try{await ti({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=rn(te(),[],{stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:f(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 g(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-DgYgDXBw.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-DgYgDXBw.js`);await e({force:a})}else if(t)await Pr({force:a});else if(n){let{initProject:e}=await import(`./init-DgYgDXBw.js`);await e({force:a})}else await Pr({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=v(e,`--cwd`,``).trim()||void 0,n=v(e,`--files`,``),r=v(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 Je({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});ve(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=oe(e),n=ht(e.shift());if(t){l(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}`)}}],yi=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=y(e,`--category`,``).trim(),n=d(y(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await m(),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=y(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=y(e,`--category`,``).trim()||void 0,n=y(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=y(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await m();(!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=v(e,`--max-chars`,3e3),n=y(e,`--path`,``).trim()||void 0,r=y(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await m();(!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 tt(o,{path:n,query:i,maxChars:t,segmentation:r}):await tt(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 bi(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 xi(){let e=await Yn({scope:`user`});if(e.length===0)return 0;let t=Or(),n=0;for(let r of e)try{let e=(await r.readConfig())[r.configKey]?.[h];if(!e||!bi(e))continue;T(A(r.getConfigPath()),{recursive:!0}),await r.registerMcp(h,t),n++}catch{}return n}const Si=[{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 xi();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=I(`cli:rollback`),Ci=j(z(),`.aikit`,`versions`),wi=j(z(),`.aikit`,`current-version.json`),Ti=[{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=j(Ci,`v${t}`);w(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=j(n,`package.json`);w(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(E(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=j(Ci,`current-version.json.tmp`);await L(i,JSON.stringify({version:t},null,2),`utf-8`),await We(i,wi),Q.debug(`Switched to v${t}`)}}],Ei=[{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=ae(e),n=v(e,`--limit`,5),r=y(e,`--mode`,`hybrid`),i=v(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new _(`Usage: aikit search <query>`);let{embedder:o,store:s,graphStore:c}=await Z(),d=await o.embedQuery(a),f;if(r===`keyword`)f=await s.ftsSearch(a,{limit:n});else if(r===`semantic`)f=await s.search(d,{limit:n});else{let[e,t]=await Promise.all([s.search(d,{limit:n*2}),s.ftsSearch(a,{limit:n*2}).catch(()=>[])]);f=u(e,t).slice(0,n)}if(t){l({query:a,results:f,graphHops:i});return}if(f.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of f){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(`${f.length} result(s) found.`),i>0&&f.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(c,f.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=ae(e),n=v(e,`--limit`,10),r=y(e,`--glob`,``).trim()||void 0,i=y(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new _(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:o,store:s}=await Z(),c=await lt(o,s,{query:a,glob:r,pattern:i,limit:n});if(t){l(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 _(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await Gt(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=v(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new _(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();x(await Zt(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=y(e,`--direction`,`both`).trim()||`both`,n=v(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new _(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();se(await $t(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=y(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new _(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();s(await dt(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 Z();_e(await ut(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 _(`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 Di(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`),s=te(),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(t)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:f(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),l=`http://localhost:${t}${r}`,u=`http://localhost:${t}/health`,d=!1;for(let e=0;e<30;e+=1){try{if((await fetch(u)).ok){d=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!d)throw c.kill(),new _(`Server failed to start within 30 seconds.`);let p=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${p}: ${l}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,l],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[l],{stdio:`ignore`,detached:!0}).unref()}let m=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,m),process.on(`SIGTERM`,m),await new Promise(e=>{c.on(`exit`,()=>e())})}const Oi=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=ae(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=process.cwd(),u=a(),d=s(N(c,`.vscode`,`mcp.json`)),f={mode:void 0,dataPath:void 0};if(u&&d)f.mode=`workspace (overrides user-level for this workspace)`,f.dataPath=N(c,n.data);else if(u){let e=r(c);f.mode=s(N(c,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,f.dataPath=i(e)}else f.mode=`workspace`,f.dataPath=N(c,n.data);u&&!d&&(f.workspaces=o().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();f.records=t.totalRecords,f.files=t.totalFiles,f.lastIndexed=t.lastIndexedAt??null,f.backend=t.storeBackend,f.model=t.embeddingModel,f.contentTypeBreakdown=t.contentTypeBreakdown,f.sourcePaths=n.slice(0,20),f.sourcePathTotal=n.length}catch{f.indexAvailable=!1}if(t){l(f);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${f.mode}`),console.log(` Data: ${f.dataPath}`),u&&!d){let e=o();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(f.records!==void 0){console.log(` Records: ${f.records}`),console.log(` Files: ${f.files}`),console.log(` Indexed: ${f.lastIndexed??`Never`}`),console.log(` Backend: ${f.backend}`),console.log(` Model: ${f.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(f.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=f.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${f.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);f.sourcePathTotal>20&&console.log(` ... and ${f.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");u&&!d&&!s(N(c,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await 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=y(e,`--transport`,`stdio`),n=y(e,`--port`,`3210`),r=C(e,`--daemon`);try{await ni({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=an(te(),[],{stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:f(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 _(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-XINdWZ5p.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-XINdWZ5p.js`);await e({force:a})}else if(t)await Fr({force:a});else if(n){let{initProject:e}=await import(`./init-XINdWZ5p.js`);await e({force:a})}else await Fr({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=y(e,`--cwd`,``).trim()||void 0,n=y(e,`--files`,``),r=y(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 Ye({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});ve(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=ae(e),n=gt(e.shift());if(t){l(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=v(e,`--detail`,`efficient`)||`efficient`,i=v(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await qe(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 g(`Usage: aikit guide <goal> [--max N]
57
- Example: aikit guide "audit this project"`);let i=mt(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=Vt({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}`)}Ht().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Bt(),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 Ei({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 Ei({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=I(`cli:update`),Oi=j(z(),`.aikit`),ki=j(Oi,`versions`),Ai=j(Oi,`current-version.json`);function ji(){if(!w(Ai))return null;try{let e=E(Ai,`utf-8`);return JSON.parse(e)}catch{return null}}function Mi(e){w(Oi)||T(Oi,{recursive:!0});let t=`${Ai}.tmp`;k(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),be(t,Ai)}function Ni(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 Pi(){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 Fi=[{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=ji();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Pi()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Ni(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=j(ki,`v${t}-staging`);w(i)&&O(i,{recursive:!0,force:!0}),T(i,{recursive:!0});try{let e=j(i,`aikit-${t}.tgz`);k(e,r),$.debug(`Extracting...`),R(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=j(i,`package`);if(!w(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),R(`npm ${ke.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=j(n,`packages`,`server`,`dist`,`bin.js`);if(!w(a))throw Error(`Server entry not found at ${a}`);let o=j(ki,`v${t}`);w(ki)||T(ki,{recursive:!0}),w(o)&&($.debug(`Removing previous installation at ${o}...`),O(o,{recursive:!0,force:!0})),be(n,o),Mi(t),$.info(`Updated to ${t}`)}finally{w(i)&&O(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],Ii=[{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 Pr({force:!0});let e=process.cwd();if(w(N(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-DgYgDXBw.js`);await e({force:!0})}if(w(N(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=S(),r=y();await t(e,n,[...ue],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[...de],r,!0)}let{homedir:t}=await import(`node:os`),{rmSync:n}=await import(`node:fs`),r=j(t(),`.aikit`,`cache`,`wasm`);if(w(r))try{n(r,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,r)}}}],Li=I(`cli:versions`),Ri=j(z(),`.aikit`,`versions`),zi=j(z(),`.aikit`,`current-version.json`);function Bi(){try{return w(zi)?JSON.parse(E(zi,`utf-8`)).version??null:null}catch{return null}}const Vi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!w(Ri)){Li.warn(`No versions installed.`);return}let e=Bi(),t=D(Ri,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=xe(j(Ri,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){Li.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}`)}}}],Hi=[{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=d(v(e,`--files`,``)),r=v(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=Ut(i,n,{description:r});console.log(`Saved workset: ${e.name}`),p(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=dt(i);if(!e){console.log(`No workset found: ${i}`);return}p(e);return}case`list`:{let e=St();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)p(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=it(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=Ke(i,n);console.log(`Updated workset: ${e.name}`),p(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Rt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),p(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 ce();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await m(),a=Yt(r,n,ie(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=qt(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=Jt(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=Kt(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=Gt(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=yt();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=v(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=gt(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=xt(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=_t(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=bt(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=vt(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=Ft();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=At(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Lt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=It(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=Mt(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=Nt(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Pt(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=kt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=jt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Ui=[...Ti,...vi,...vn,..._i,...Er,...Di,...ii,...An,...yn,...kn,...Hi,...ri,...Fi,...Ii,...ci,...ni,...xi,...Vi,...wi,...mi];Ui.push({name:`help`,description:`Show available commands`,run:async()=>{Gi()}});async function Wi(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Gi();return}if(n===`--version`||n===`-v`){let e=N(A(Te(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(E(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Ui.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Ui.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Gi(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof g&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=gi();e&&await e.store.close()}}function Gi(){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 Z(),r=y(e,`--detail`,`efficient`)||`efficient`,i=y(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await Je(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 _(`Usage: aikit guide <goal> [--max N]
57
+ Example: aikit guide "audit this project"`);let i=ht(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=Ht({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}`)}Ut().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Vt(),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 Di({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 Di({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=I(`cli:update`),ki=j(z(),`.aikit`),Ai=j(ki,`versions`),ji=j(ki,`current-version.json`);function Mi(){if(!w(ji))return null;try{let e=E(ji,`utf-8`);return JSON.parse(e)}catch{return null}}function Ni(e){w(ki)||T(ki,{recursive:!0});let t=`${ji}.tmp`;k(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),be(t,ji)}function Pi(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 Fi(){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 Ii=[{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=Mi();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Fi()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Pi(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=j(Ai,`v${t}-staging`);w(i)&&O(i,{recursive:!0,force:!0}),T(i,{recursive:!0});try{let e=j(i,`aikit-${t}.tgz`);k(e,r),$.debug(`Extracting...`),R(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=j(i,`package`);if(!w(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),R(`npm ${ke.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=j(n,`packages`,`server`,`dist`,`bin.js`);if(!w(a))throw Error(`Server entry not found at ${a}`);let o=j(Ai,`v${t}`);w(Ai)||T(Ai,{recursive:!0}),w(o)&&($.debug(`Removing previous installation at ${o}...`),O(o,{recursive:!0,force:!0})),be(n,o),Ni(t),$.info(`Updated to ${t}`)}finally{w(i)&&O(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],Li=[{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 Fr({force:!0});let e=process.cwd();if(w(N(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-XINdWZ5p.js`);await e({force:!0})}if(w(N(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=S(),r=oe();await t(e,n,[...ue],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[...fe],r,!0)}let{homedir:t}=await import(`node:os`),{rmSync:n}=await import(`node:fs`),r=j(t(),`.aikit`,`cache`,`wasm`);if(w(r))try{n(r,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,r)}}}],Ri=I(`cli:versions`),zi=j(z(),`.aikit`,`versions`),Bi=j(z(),`.aikit`,`current-version.json`);function Vi(){try{return w(Bi)?JSON.parse(E(Bi,`utf-8`)).version??null:null}catch{return null}}const Hi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!w(zi)){Ri.warn(`No versions installed.`);return}let e=Vi(),t=D(zi,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=xe(j(zi,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){Ri.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}`)}}}],Ui=[{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=d(y(e,`--files`,``)),r=y(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=Wt(i,n,{description:r});console.log(`Saved workset: ${e.name}`),p(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=ft(i);if(!e){console.log(`No workset found: ${i}`);return}p(e);return}case`list`:{let e=Ct();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)p(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=at(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=qe(i,n);console.log(`Updated workset: ${e.name}`),p(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=zt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),p(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 ce();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await m(),a=Xt(r,n,ie(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=Jt(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=Yt(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=qt(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=Kt(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=bt();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=y(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=_t(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=St(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=vt(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=xt(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=yt(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=It();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=jt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Rt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Lt(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=Nt(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=Pt(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Ft(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=At(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=Mt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Wi=[...Ei,...yi,...yn,...vi,...Dr,...Oi,...ai,...jn,...bn,...An,...Ui,...ii,...Ii,...Li,...li,...ri,...Si,...Hi,...Ti,...hi];Wi.push({name:`help`,description:`Show available commands`,run:async()=>{Ki()}});async function Gi(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Ki();return}if(n===`--version`||n===`-v`){let e=N(A(Te(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(E(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Wi.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Wi.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Ki(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof _&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=_i();e&&await e.store.close()}}function Ki(){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(...Ui.map(e=>e.name.length));for(let t of Ui)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{Wi as run};
59
+ `),console.log(`Commands:`);let e=Math.max(...Wi.map(e=>e.name.length));for(let t of Wi)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{Gi as run};