@vpxa/aikit 0.1.356 → 0.1.357

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.356",
3
+ "version": "0.1.357",
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",
@@ -122,7 +122,7 @@
122
122
  },
123
123
  "scripts": {
124
124
  "postinstall": "node ./bin/postinstall-managed-launcher.mjs",
125
- "build": "node scripts/build.mjs",
125
+ "build": "node scripts/build.mjs && node packages/claude-desktop/scripts/build-mcpb.mjs",
126
126
  "typecheck": "tsc -b tsconfig.build.json --emitDeclarationOnly",
127
127
  "clean": "turbo run clean && rimraf --glob node_modules \"packages/*/node_modules\"",
128
128
  "lint": "biome check .",
@@ -141,6 +141,7 @@
141
141
  "release": "node scripts/release.mjs",
142
142
  "release:dry": "node scripts/release.mjs --dry-run",
143
143
  "nodeprune": "pnpm -s dlx npkill -D -y && pnpm store prune && pnpm clean",
144
+ "build:mcpb": "node packages/claude-desktop/scripts/build-mcpb.mjs",
144
145
  "test:watch": "vitest",
145
146
  "validate": "pnpm build && pnpm test && pnpm lint:fix && pnpm typecheck"
146
147
  }
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env node
2
+ // GENERATED — pipe relay for AI Kit MCP server.
3
+ //
4
+ // Resolves the managed install path (~/.aikit/current-version.json)
5
+ // and spawns the server with stdio pipes for GUI-host compatibility.
6
+ //
7
+ import { spawn } from 'node:child_process';
8
+ import { existsSync, readFileSync } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { delimiter, join } from 'node:path';
11
+
12
+ const VERSION_FILE = join(homedir(), '.aikit', 'current-version.json');
13
+
14
+ function getServerPath() {
15
+ if (!existsSync(VERSION_FILE)) return null;
16
+ try {
17
+ const { version } = JSON.parse(readFileSync(VERSION_FILE, 'utf-8'));
18
+ const p = join(homedir(), '.aikit', 'versions', 'v' + version, 'packages', 'server', 'dist', 'bin.js');
19
+ return existsSync(p) ? p : null;
20
+ } catch { return null; }
21
+ }
22
+
23
+ function findNodeOnPath() {
24
+ const names = process.platform === 'win32' ? ['node.exe', 'node'] : ['node'];
25
+ for (const dir of (process.env.PATH || '').split(delimiter)) {
26
+ if (!dir) continue;
27
+ for (const name of names) {
28
+ const candidate = join(dir, name);
29
+ if (existsSync(candidate)) return candidate;
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+
35
+ function getNodePath() {
36
+ const candidates = [
37
+ process.env.AIKIT_NODE_PATH,
38
+ findNodeOnPath(),
39
+ process.platform === 'win32' ? 'C:\\nvm4w\\nodejs\\node.exe' : null,
40
+ process.platform === 'win32' ? 'C:\\Program Files\\nodejs\\node.exe' : null,
41
+ process.platform === 'win32' ? join(process.env.LOCALAPPDATA || '', 'Programs', 'nodejs', 'node.exe') : null,
42
+ process.execPath,
43
+ ];
44
+ for (const candidate of candidates) {
45
+ if (candidate && existsSync(candidate)) return candidate;
46
+ }
47
+ return process.execPath;
48
+ }
49
+
50
+ const serverPath = getServerPath();
51
+ if (!serverPath) {
52
+ process.stderr.write('AI Kit not found. Install: npx @vpxa/aikit install\n');
53
+ process.exit(1);
54
+ }
55
+ const nodePath = getNodePath();
56
+
57
+ // Spawn with pipe mode for GUI host compatibility
58
+ const child = spawn(nodePath, [serverPath, 'serve'], {
59
+ stdio: ['pipe', 'pipe', 'pipe'],
60
+ env: process.env,
61
+ });
62
+
63
+ // Relay stdin/stderr between host and server
64
+ process.stdin.on('data', (chunk) => {
65
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) child.stdin.write(chunk);
66
+ });
67
+ process.stdin.on('end', () => {
68
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) child.stdin.end();
69
+ });
70
+ child.stderr.pipe(process.stderr);
71
+ child.stdin.on('error', (err) => {
72
+ if (err?.code !== 'EPIPE' && err?.code !== 'ERR_STREAM_WRITE_AFTER_END') {
73
+ process.stderr.write('aikit stdin: ' + err.message + '\n');
74
+ }
75
+ });
76
+
77
+ let childStdoutBuffer = '';
78
+ function sendToChild(message) {
79
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) {
80
+ child.stdin.write(JSON.stringify(message) + '\n');
81
+ }
82
+ }
83
+
84
+ // Claude Desktop can close .mcpb transports if the server asks roots/list
85
+ // before initialize completes. Answer that bootstrap request inside the
86
+ // relay and let AI Kit use its existing configured-root/cwd fallback.
87
+ child.stdout.setEncoding('utf8');
88
+ child.stdout.on('data', (chunk) => {
89
+ childStdoutBuffer += chunk;
90
+ for (;;) {
91
+ const newline = childStdoutBuffer.indexOf('\n');
92
+ if (newline < 0) break;
93
+ const line = childStdoutBuffer.slice(0, newline);
94
+ childStdoutBuffer = childStdoutBuffer.slice(newline + 1);
95
+ const trimmed = line.trim();
96
+ if (!trimmed) { process.stdout.write(line + '\n'); continue; }
97
+ try {
98
+ const message = JSON.parse(trimmed);
99
+ if (message?.method === 'roots/list' && message.id !== undefined) {
100
+ sendToChild({ jsonrpc: '2.0', id: message.id, result: { roots: [] } });
101
+ continue;
102
+ }
103
+ } catch {}
104
+ process.stdout.write(line + '\n');
105
+ }
106
+ });
107
+ child.stdout.on('end', () => {
108
+ if (childStdoutBuffer) process.stdout.write(childStdoutBuffer);
109
+ });
110
+
111
+ child.once('error', (err) => {
112
+ process.stderr.write('aikit: ' + err.message + '\n');
113
+ process.exit(1);
114
+ });
115
+ child.once('exit', (code, signal) => {
116
+ process.exit(signal === 'SIGINT' ? 130 : signal === 'SIGTERM' ? 143 : code ?? 1);
117
+ });
118
+ for (const sig of ['SIGINT', 'SIGTERM']) {
119
+ process.once(sig, () => { if (!child.killed) child.kill(sig); });
120
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@vpxa/aikit-claude-desktop",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "description": "AI Kit MCP Bundle for Claude Desktop — one-click .mcpb install",
7
+ "scripts": {
8
+ "build:mcpb": "node scripts/build-mcpb.mjs",
9
+ "clean": "rimraf dist *.mcpb"
10
+ }
11
+ }
@@ -1,7 +1,7 @@
1
- import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-BNPHP-QC.js";import{A as o,B as s,C as c,D as l,E as u,F as d,I as f,L as p,M as ee,N as te,O as ne,P as re,R as ie,S as ae,T as oe,_ as se,a as ce,b as le,c as m,d as h,f as ue,g as de,h as g,i as fe,j as pe,k as me,l as he,m as _,n as ge,o as _e,p as v,s as y,t as ve,u as b,v as ye,w as be,x as xe,y as Se,z as x}from"./templates-zHGu9MXa.js";import{copyFileSync as Ce,existsSync as S,mkdirSync as C,readFileSync as w,readdirSync as T,renameSync as we,rmSync as E,statSync as Te,unlinkSync as Ee,writeFileSync as D}from"node:fs";import{basename as De,dirname as O,join as k,posix as A,relative as Oe,resolve as j,win32 as M}from"node:path";import{fileURLToPath as ke}from"node:url";import{arch as Ae,homedir as N,platform as je}from"node:os";import{AIKIT_PATHS as P,AIKIT_RUNTIME_PATHS as Me,EMBEDDING_DEFAULTS as Ne,INSTALL_ARGS as Pe,cleanupOldVersions as Fe,createLogger as F,getGlobalDataDir as Ie,getPartitionDir as Le,isUserInstalled as Re,migrateLegacyWorkspaceLayout as ze,registerWorkspace as Be,safeCwd as I,safeCwdOrHome as Ve,saveRegistry as He}from"../../core/dist/index.js";import{initializeWasm as Ue}from"../../chunker/dist/index.js";import{OnnxEmbedder as We}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Ge}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ke,createSqliteAdapter as qe,createStore as Je}from"../../store/dist/index.js";import{mkdir as Ye,readFile as Xe,rename as Ze,rm as Qe,unlink as $e,writeFile as L}from"node:fs/promises";import{addToWorkset as et,audit as tt,check as nt,checkpointLatest as rt,checkpointList as it,checkpointLoad as at,checkpointSave as ot,codemod as st,compact as ct,dataTransform as lt,delegate as ut,delegateListModels as dt,deleteWorkset as ft,diffParse as pt,evaluate as mt,fileSummary as ht,find as gt,findDeadSymbols as _t,findExamples as vt,getWorkset as yt,gitContext as bt,graphQuery as xt,guide as St,health as Ct,laneCreate as wt,laneDiff as Tt,laneDiscard as Et,laneList as Dt,laneMerge as Ot,laneStatus as kt,listWorksets as At,parseOutput as jt,processList as Mt,processLogs as Nt,processStart as Pt,processStatus as Ft,processStop as It,queueClear as Lt,queueCreate as Rt,queueDelete as zt,queueDone as Bt,queueFail as Vt,queueGet as Ht,queueList as Ut,queueNext as Wt,queuePush as Gt,removeFromWorkset as Kt,rename as qt,replayClear as Jt,replayList as Yt,replayTrim as Xt,saveWorkset as Zt,scopeMap as Qt,stashClear as $t,stashDelete as en,stashGet as tn,stashList as nn,stashSet as rn,symbol as an,testRun as on,trace as sn,watchList as cn,watchStart as ln,watchStop as un}from"../../tools/dist/index.js";import{execFileSync as dn,execSync as R,fork as fn,spawn as pn}from"node:child_process";import{extractSvg as mn,renderToResult as hn,sanitizeTitle as gn}from"../../server/dist/index.js";import{randomUUID as _n}from"node:crypto";import{parse as vn,stringify as yn}from"yaml";function bn(){let e=I(),t=process.env.AIKIT_CONFIG_PATH??(e&&S(j(e,`aikit.config.json`))?j(e,`aikit.config.json`):null),n=t?O(t):e??N();if(ze(n),!t)return xn();let r=w(t,`utf-8`),i;try{i=JSON.parse(r)}catch{console.error(`Failed to parse ${t} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let a=n;return i.sources=i.sources.map(e=>({...e,path:j(a,e.path)})),i.store.path=j(a,i.store.path),i.curated=i.curated??{path:P.aiCurated},i.curated.path=j(a,i.curated.path),i.onboardDir||=P.aiContext,i.onboardDir=j(a,i.onboardDir),i.stateDir||=P.state,i.stateDir=j(a,i.stateDir),Sn(i,a),i}function xn(){let e=process.env.AIKIT_WORKSPACE_ROOT??I()??N();ze(e);let t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`aikit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:Ne.model,dimensions:Ne.dimensions},store:{backend:`sqlite-vec`,path:j(e,P.data)},curated:{path:j(e,P.aiCurated)},onboardDir:j(e,P.aiContext),stateDir:j(e,P.state)};return Sn(t,e),t}function Sn(e,t){if(!Re())return;let n=Be(t);e.store.path=j(Le(n.partition),Me.data),e.stateDir=j(Le(n.partition),Me.state),e.onboardDir=j(Le(n.partition),Me.onboard),e.curated={path:j(Le(n.partition),Me.curated)}}async function Cn(){let e=bn(),t=new We({model:e.embedding.model,dimensions:e.embedding.dimensions,interOpNumThreads:e.embedding.interOpNumThreads,intraOpNumThreads:e.embedding.intraOpNumThreads});await t.initialize();let n=null;if(e.store.backend===`sqlite-vec`){let t=j(e.store.path,`aikit.db`),r=O(t);if(!S(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await qe(t)}let r=await Je({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new Ge(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new Ke({adapter:n}):new Ke({path:e.store.path});await t.initialize(),s=t,i.setGraphStore(s)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),s={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNodes:async()=>[],getNeighbors:async()=>({nodes:[],edges:[]}),traverse:async()=>({nodes:[],edges:[]}),findNodes:async()=>[],findEdges:async()=>[],deleteNode:async()=>{},deleteBySourcePath:async()=>0,clear:async()=>{},getStats:async()=>({nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}),validate:async()=>({valid:!0,orphanNodes:[],danglingEdges:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}}),setNodeCommunity:async()=>{},detectCommunities:async()=>({}),traceProcess:async()=>({id:``,entryNodeId:``,label:``,properties:{},steps:[]}),getProcesses:async()=>[],deleteProcess:async()=>{},depthGroupedTraversal:async()=>({}),getCohesionScore:async()=>0,getSymbol360:async()=>({node:{id:``,type:``,name:``,properties:{}},incoming:[],outgoing:[],community:null,processes:[]}),close:async()=>{}}}return await Ue().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const wn=[{name:`analyze`,description:`Run analyzer output for a path`,usage:`aikit analyze <type> <path>`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``;if(!t||!n)throw new h(`Usage: aikit analyze <type> <path>
1
+ import{d as e,f as t,i as n,p as r,s as i,u as a}from"./scaffold-BNPHP-QC.js";import{A as o,B as s,C as c,D as l,E as u,F as d,I as f,L as p,M as ee,N as te,O as ne,P as re,R as ie,S as ae,T as oe,_ as se,a as ce,b as le,c as m,d as h,f as ue,g as de,h as g,i as fe,j as pe,k as me,l as he,m as _,n as ge,o as _e,p as v,s as y,t as ve,u as b,v as ye,w as be,x as xe,y as Se,z as x}from"./templates-Bu7dZtk_.js";import{copyFileSync as Ce,existsSync as S,mkdirSync as C,readFileSync as w,readdirSync as T,renameSync as we,rmSync as E,statSync as Te,unlinkSync as Ee,writeFileSync as D}from"node:fs";import{basename as De,dirname as O,join as k,posix as A,relative as Oe,resolve as j,win32 as M}from"node:path";import{fileURLToPath as ke}from"node:url";import{arch as Ae,homedir as N,platform as je}from"node:os";import{AIKIT_PATHS as P,AIKIT_RUNTIME_PATHS as Me,EMBEDDING_DEFAULTS as Ne,INSTALL_ARGS as Pe,cleanupOldVersions as Fe,createLogger as F,getGlobalDataDir as Ie,getPartitionDir as Le,isUserInstalled as Re,migrateLegacyWorkspaceLayout as ze,registerWorkspace as Be,safeCwd as I,safeCwdOrHome as Ve,saveRegistry as He}from"../../core/dist/index.js";import{initializeWasm as Ue}from"../../chunker/dist/index.js";import{OnnxEmbedder as We}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Ge}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ke,createSqliteAdapter as qe,createStore as Je}from"../../store/dist/index.js";import{mkdir as Ye,readFile as Xe,rename as Ze,rm as Qe,unlink as $e,writeFile as L}from"node:fs/promises";import{addToWorkset as et,audit as tt,check as nt,checkpointLatest as rt,checkpointList as it,checkpointLoad as at,checkpointSave as ot,codemod as st,compact as ct,dataTransform as lt,delegate as ut,delegateListModels as dt,deleteWorkset as ft,diffParse as pt,evaluate as mt,fileSummary as ht,find as gt,findDeadSymbols as _t,findExamples as vt,getWorkset as yt,gitContext as bt,graphQuery as xt,guide as St,health as Ct,laneCreate as wt,laneDiff as Tt,laneDiscard as Et,laneList as Dt,laneMerge as Ot,laneStatus as kt,listWorksets as At,parseOutput as jt,processList as Mt,processLogs as Nt,processStart as Pt,processStatus as Ft,processStop as It,queueClear as Lt,queueCreate as Rt,queueDelete as zt,queueDone as Bt,queueFail as Vt,queueGet as Ht,queueList as Ut,queueNext as Wt,queuePush as Gt,removeFromWorkset as Kt,rename as qt,replayClear as Jt,replayList as Yt,replayTrim as Xt,saveWorkset as Zt,scopeMap as Qt,stashClear as $t,stashDelete as en,stashGet as tn,stashList as nn,stashSet as rn,symbol as an,testRun as on,trace as sn,watchList as cn,watchStart as ln,watchStop as un}from"../../tools/dist/index.js";import{execFileSync as dn,execSync as R,fork as fn,spawn as pn}from"node:child_process";import{extractSvg as mn,renderToResult as hn,sanitizeTitle as gn}from"../../server/dist/index.js";import{randomUUID as _n}from"node:crypto";import{parse as vn,stringify as yn}from"yaml";function bn(){let e=I(),t=process.env.AIKIT_CONFIG_PATH??(e&&S(j(e,`aikit.config.json`))?j(e,`aikit.config.json`):null),n=t?O(t):e??N();if(ze(n),!t)return xn();let r=w(t,`utf-8`),i;try{i=JSON.parse(r)}catch{console.error(`Failed to parse ${t} as JSON. Ensure the file contains valid JSON.`),process.exit(1)}let a=n;return i.sources=i.sources.map(e=>({...e,path:j(a,e.path)})),i.store.path=j(a,i.store.path),i.curated=i.curated??{path:P.aiCurated},i.curated.path=j(a,i.curated.path),i.onboardDir||=P.aiContext,i.onboardDir=j(a,i.onboardDir),i.stateDir||=P.state,i.stateDir=j(a,i.stateDir),Sn(i,a),i}function xn(){let e=process.env.AIKIT_WORKSPACE_ROOT??I()??N();ze(e);let t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`aikit`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:Ne.model,dimensions:Ne.dimensions},store:{backend:`sqlite-vec`,path:j(e,P.data)},curated:{path:j(e,P.aiCurated)},onboardDir:j(e,P.aiContext),stateDir:j(e,P.state)};return Sn(t,e),t}function Sn(e,t){if(!Re())return;let n=Be(t);e.store.path=j(Le(n.partition),Me.data),e.stateDir=j(Le(n.partition),Me.state),e.onboardDir=j(Le(n.partition),Me.onboard),e.curated={path:j(Le(n.partition),Me.curated)}}async function Cn(){let e=bn(),t=new We({model:e.embedding.model,dimensions:e.embedding.dimensions,interOpNumThreads:e.embedding.interOpNumThreads,intraOpNumThreads:e.embedding.intraOpNumThreads});await t.initialize();let n=null;if(e.store.backend===`sqlite-vec`){let t=j(e.store.path,`aikit.db`),r=O(t);if(!S(r)){let{mkdirSync:e}=await import(`node:fs`);e(r,{recursive:!0})}n=await qe(t)}let r=await Je({backend:e.store.backend,path:e.store.path,embeddingDim:e.embedding.dimensions,adapter:n??void 0});await r.initialize();let i=new Ge(t,r),{CuratedKnowledgeManager:a}=await import(`../../server/dist/index.js`),o=new a(e.curated.path,r,t),s;try{let t=n?new Ke({adapter:n}):new Ke({path:e.store.path});await t.initialize(),s=t,i.setGraphStore(s)}catch(e){console.error(`[aikit] Graph store init failed (non-fatal): ${e.message}`),s={initialize:async()=>{},upsertNode:async()=>{},upsertEdge:async()=>{},upsertNodes:async()=>{},upsertEdges:async()=>{},getNode:async()=>null,getNodes:async()=>[],getNeighbors:async()=>({nodes:[],edges:[]}),traverse:async()=>({nodes:[],edges:[]}),findNodes:async()=>[],findEdges:async()=>[],deleteNode:async()=>{},deleteBySourcePath:async()=>0,clear:async()=>{},getStats:async()=>({nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}),validate:async()=>({valid:!0,orphanNodes:[],danglingEdges:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}}),setNodeCommunity:async()=>{},detectCommunities:async()=>({}),traceProcess:async()=>({id:``,entryNodeId:``,label:``,properties:{},steps:[]}),getProcesses:async()=>[],deleteProcess:async()=>{},depthGroupedTraversal:async()=>({}),getCohesionScore:async()=>0,getSymbol360:async()=>({node:{id:``,type:``,name:``,properties:{}},incoming:[],outgoing:[],community:null,processes:[]}),close:async()=>{}}}return await Ue().catch(()=>{}),{config:e,embedder:t,store:r,graphStore:s,indexer:i,curated:o,sqliteAdapter:n}}const wn=[{name:`analyze`,description:`Run analyzer output for a path`,usage:`aikit analyze <type> <path>`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``;if(!t||!n)throw new h(`Usage: aikit analyze <type> <path>
2
2
  Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`);let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:l}=await import(`../../analyzers/dist/index.js`),u=j(n),d;switch(t){case`structure`:d=await new c().analyze(u,{format:`markdown`});break;case`deps`:case`dependencies`:d=await new i().analyze(u,{format:`markdown`});break;case`symbols`:d=await new l().analyze(u,{format:`markdown`});break;case`patterns`:d=await new s().analyze(u,{format:`markdown`});break;case`entry-points`:d=await new o().analyze(u,{format:`markdown`});break;case`blast-radius`:d=await new r().analyze(I()??N(),{files:[n],format:`markdown`});break;case`diagram`:d=await new a().analyze(u,{diagramType:`architecture`});break;default:throw new h(`Unknown analyze type: ${t}\nTypes: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`)}console.log(d.output)}},{name:`onboard`,description:`Run all analyses for first-time codebase onboarding`,usage:`aikit onboard <path> [--generate] [--out-dir <dir>]`,run:async e=>{let{onboard:t}=await import(`../../tools/dist/index.js`),n=``,r=`memory`,i;for(let t=0;t<e.length;t++){let a=e[t].trim();a===`--generate`?r=`generate`:a===`--out-dir`&&t+1<e.length?i=e[++t].trim():a.startsWith(`--`)||(n=a)}n||=I()??N();let a=j(n),o=bn();console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
3
3
  `);let s=await t({path:a,mode:r,outDir:i??o.onboardDir});for(let e of s.steps){let t=e.status===`success`?`✓`:`✗`,n=e.status===`success`?`${e.durationMs}ms, ${e.output.length} chars`:e.error;console.log(` ${t} ${e.name} — ${n}`)}console.log(`\nTotal: ${s.totalDurationMs}ms`),s.outDir&&console.log(`Output written to: ${s.outDir}`)}}],Tn=[{name:`parse-output`,description:`Parse build or tool output from stdin`,usage:`aikit parse-output [--tool tsc|vitest|biome|git-status]`,run:async e=>{let t=g(e,`--tool`,``).trim()||void 0,n=await f();n.trim()||(console.error(`Usage: aikit parse-output [--tool tsc|vitest|biome|git-status]`),process.exit(1)),pe(jt(n,t))}},{name:`git`,description:`Show git branch, status, recent commits, and optional diff stats`,usage:`aikit git [--cwd path] [--commit-count N] [--diff]`,run:async e=>{ne(await bt({cwd:g(e,`--cwd`,``).trim()||void 0,commitCount:_(e,`--commit-count`,5),includeDiff:v(e,`--diff`)}))}},{name:`diff`,description:`Parse unified diff text from stdin into structured file changes`,usage:`git diff | aikit diff`,run:async()=>{let e=await f();e.trim()||(console.error(`Usage: git diff | aikit diff`),process.exit(1)),oe(pt({diff:e}))}},{name:`summarize`,description:`Show a structural summary of a file`,usage:`aikit summarize <path>`,run:async e=>{let t=e.shift()?.trim();t||(console.error(`Usage: aikit summarize <path>`),process.exit(1)),l(await ht({path:j(t)}))}},{name:`checkpoint`,description:`Save and restore lightweight session checkpoints`,usage:`aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`,run:async e=>{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint <save|load|list|latest> [label-or-id] [--data json] [--notes text]`),process.exit(1));let n=await ue();switch(t){case`save`:{let t=e.shift()?.trim(),r=g(e,`--data`,``),i=g(e,`--notes`,``).trim()||void 0,a=r.trim()?``:await f();t||(console.error(`Usage: aikit checkpoint save <label> [--data json] [--notes text]`),process.exit(1)),c(ot(n,t,xe(r||a),{notes:i}));return}case`load`:{let t=e.shift()?.trim();t||(console.error(`Usage: aikit checkpoint load <id>`),process.exit(1));let r=at(n,t);if(!r){console.log(`No checkpoint found: ${t}`);return}c(r);return}case`list`:{let e=it(n);if(e.length===0){console.log(`No checkpoints saved.`);return}console.log(`Checkpoints (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.id}`),console.log(` Label: ${t.label}`),console.log(` Created: ${t.createdAt}`);return}case`latest`:{let e=rt(n);if(!e){console.log(`No checkpoints saved.`);return}c(e);return}default:console.error(`Unknown checkpoint action: ${t}`),console.error(`Actions: save, load, list, latest`),process.exit(1)}}}],En=k(N(),`.aikit`),z=k(En,`daemon.json`),Dn=3210,B=F(`cli:daemon`);function On(){if(!S(z))return null;try{return JSON.parse(w(z,`utf-8`))}catch{return null}}function kn(e){S(En)||C(En,{recursive:!0});let t=`${z}.tmp`;D(t,JSON.stringify(e,null,2)),we(t,z)}function V(){S(z)&&E(z)}async function H(e){try{return process.kill(e,0),!0}catch{return!1}}async function An(e){try{return(await fetch(`http://127.0.0.1:${e}/health`,{signal:AbortSignal.timeout(2e3)})).ok}catch{return!1}}async function jn(e,t){let n=Date.now();for(B.debug(`Polling health endpoint on port ${e}...`);Date.now()-n<t;){if(await An(e))return B.debug(`Daemon health check passed`),!0;await new Promise(e=>setTimeout(e,200))}return!1}async function Mn(){let e=On();if(!e)return B.info(`Daemon is not running`),null;if(!await H(e.pid))return V(),B.debug(`Daemon was not running (stale state cleaned up)`),{pid:e.pid,wasRunning:!1};B.debug(`Sending SIGTERM to daemon...`);try{process.kill(e.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(e.pid)&&(B.debug(`Sending SIGKILL to daemon...`),process.kill(e.pid,`SIGKILL`))}catch{}return V(),{pid:e.pid,wasRunning:!0}}async function Nn(e){let t=p();B.debug(`Spawning daemon process...`);let n=pn(process.execPath,[t,`--transport`,`http`,`--port`,String(e)],{stdio:`ignore`,detached:!0,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(e)}});n.unref(),await jn(e,3e4)||(B.error(`Daemon failed to start within 30 seconds`),n.kill(`SIGTERM`),process.exit(1));let r=ye();if(n.pid===void 0)throw Error(`Daemon child process has no PID`);return kn({port:e,pid:n.pid,version:r,startedAt:new Date().toISOString()}),{pid:n.pid,port:e}}const Pn=[{name:`daemon`,description:`Run AI Kit as a background HTTP daemon — survives IDE restarts, shares across windows (start|stop|status|restart)`,usage:`aikit daemon <start|stop|status|restart> [--port <port>]`,run:async e=>{let t=e[0];if(!t){console.error(`Usage: aikit daemon <start|stop|status|restart>`),console.error(``),console.error(`Commands:`),console.error(` start Start the AI Kit daemon`),console.error(` stop Stop the AI Kit daemon`),console.error(` status Show daemon status`),console.error(` restart Restart the AI Kit daemon`);return}switch(t){case`start`:{let t=On();if(t){if(await H(t.pid)&&await An(t.port)){B.info(`Daemon already running (PID ${t.pid}, port ${t.port})`);return}B.debug(`Cleaning up stale daemon state...`),V()}let n=e.indexOf(`--port`),r=await Nn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):Dn);B.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}case`stop`:{let e=await Mn();e?.wasRunning&&B.info(`Daemon stopped (PID ${e.pid})`);return}case`status`:{let e=On();if(!e){console.log(`Daemon: stopped`);return}if(!(await H(e.pid)&&await An(e.port))){V(),console.log(`Daemon: stopped (stale state cleaned up)`);return}console.log(`Daemon: running`),console.log(` PID: ${e.pid}`),console.log(` Port: ${e.port}`),console.log(` Version: ${e.version}`),console.log(` Started: ${e.startedAt}`);return}case`restart`:{let t=On();if(t){if(await H(t.pid)){B.debug(`Sending SIGTERM to daemon...`);try{process.kill(t.pid,`SIGTERM`),await new Promise(e=>setTimeout(e,2e3)),await H(t.pid)&&(B.debug(`Sending SIGKILL to daemon...`),process.kill(t.pid,`SIGKILL`))}catch{}}V(),B.info(`Daemon stopped (PID ${t.pid})`)}else B.info(`Daemon is not running`);let n=e.indexOf(`--port`),r=await Nn(n!==-1&&e[n+1]?Number.parseInt(e[n+1],10):Dn);B.info(`Daemon started (PID ${r.pid}, port ${r.port})`);return}default:console.error(`Unknown daemon command: ${t}`),console.error("Use `aikit daemon` for help.")}}}],Fn=[{name:`diagram`,description:`Render a diagram from structured JSON input. Reads stdin, produces HTML + markdown + SVG.`,usage:`aikit diagram [--type <type>] [--output <dir>] [--title <title>] [--subtitle <subtitle>] [--palette warm|technical] [--format all|html|md|svg] < input.json`,run:async e=>{let t=U(e,`--type`),n=U(e,`--output`),r=U(e,`--title`),i=U(e,`--subtitle`),a=U(e,`--format`)??`all`,o=U(e,`--palette`),s=``,c=process.stdin;c.setEncoding(`utf-8`);for await(let e of c)s+=e;s.trim()||(console.error(`No input provided. Pipe diagram JSON to stdin.`),console.error(`Usage: aikit diagram [--type <type>] [--output <dir>] < input.json`),process.exit(1));let l;try{l=JSON.parse(s)}catch(e){console.error(`Invalid JSON: ${e.message}`),process.exit(1)}let u=l.meta??{};t&&l.diagram_type!==t&&(console.error(`Error: --type "${t}" does not match input diagram_type "${l.diagram_type}". Remove --type or use the correct type. Mutating the discriminator produces invalid output.`),process.exit(1)),o&&(o!==`warm`&&o!==`technical`&&(console.error(`Invalid palette "${o}". Expected "warm" or "technical".`),process.exit(1)),u.palette&&u.palette!==o&&console.warn(`Warning: --palette "${o}" overrides input meta.palette "${String(u.palette)}"`),l.meta={...u,palette:o});try{let e=hn(l,{title:r||void 0,subtitle:i||void 0,dualOutput:!0});if(n){let t=j(n);await Ye(t,{recursive:!0});let i=gn(r||l.meta?.title||`diagram`);if(a===`all`||a===`html`){let n=k(t,`${i}.html`);await L(n,e.html,`utf-8`),console.log(`Written: ${n}`)}if((a===`all`||a===`md`)&&e.markdown){let n=k(t,`${i}.md`);await L(n,e.markdown,`utf-8`),console.log(`Written: ${n}`)}if(a===`all`||a===`svg`){let n=mn(e.html);if(n){let e=k(t,`${i}.svg`);await L(e,n,`utf-8`),console.log(`Written: ${e}`)}}}else process.stdout.write(e.html)}catch(e){console.error(`Rendering failed: ${e.message}`),process.exit(1)}}}];function U(e,t){let n=e.indexOf(t);if(n>=0&&n+1<e.length)return e[n+1]}function In(e){let t=``,n=0,r=e.length;for(;n<r;)if(e[n]===`"`){for(t+=`"`,n++;n<r&&e[n]!==`"`;)e[n]===`\\`&&(t+=e[n++]),n<r&&(t+=e[n++]);n<r&&(t+=e[n++])}else if(e[n]===`/`&&n+1<r&&e[n+1]===`/`)for(n+=2;n<r&&e[n]!==`
4
- `;)n++;else if(e[n]===`/`&&n+1<r&&e[n+1]===`*`){for(n+=2;n+1<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2}else t+=e[n++];return t.replace(/,(\s*[}\]])/g,`$1`)}var W=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!S(t))return{};let n=await Xe(t,`utf-8`);try{return JSON.parse(In(n))}catch{throw Error(`Invalid JSON in ${t}. Please fix or remove the file before retrying.`)}}async writeConfig(e,t){let n=this.getConfigPath(t),r=O(n),i=k(r,`.aikit-tmp-${_n()}.json`);await Ye(r,{recursive:!0});try{await L(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await Ze(i,n)}catch(e){try{await $e(i)}catch{}throw e}}async registerMcp(e,t,n){let r=await this.readConfig(n);r[this.configKey]||(r[this.configKey]={}),r[this.configKey][e]=t,await this.writeConfig(r,n)}async unregisterMcp(e,t){let n=await this.readConfig(t);n[this.configKey]&&(delete n[this.configKey][e],await this.writeConfig(n,t))}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}},Ln=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.claude`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.claude`,`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:e.resolve(t,`hooks`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?M:A}},Rn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},G=class extends W{family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;hasInstructions=!1;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getConfigDir();if(process.platform===`darwin`){let t=this.getMacAppPath();return S(e)||t!==null&&S(t)}return S(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),hooks:e.resolve(t,`hooks`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=N();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?M:A}},zn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(j(N(),`.copilot`)):!1}getConfigPath(){return j(N(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return j(N(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=j(N(),`.copilot`);return{agents:j(e,`agents`),skills:j(e,`skills`),prompts:null,flows:j(e,`flows`),hooks:j(e,`hooks`),commands:null,instructions:j(N(),`.github`,`copilot-instructions.md`),manifest:j(e,`.aikit-scaffold.json`)}}},Bn=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Vn=class extends G{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Hn=class e extends W{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;if(S(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!S(t))return!1;try{return T(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return j(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ye(r,{recursive:!0});let i=t.args??[],a=i.indexOf(`-e`),o;if(a!==-1&&a+1<i.length){let t=i[a+1],n=j(r,`${e}-launcher.js`);await L(n,t,`utf-8`),o=[...i.slice(0,a),n,...i.slice(a+2)]}else o=[...i];let s={type:`stdio`,...t,args:o};await super.registerMcp(e,s,n)}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return t}getCopilotConfigDir(){let e=N();return process.platform===`win32`?j(process.env.LOCALAPPDATA??j(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`github-copilot`,`intellij`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=N();return process.platform===`win32`?j(process.env.APPDATA??j(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`JetBrains`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`JetBrains`)}},Un=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Wn=class extends G{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Gn=class extends G{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Kn=class extends G{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},qn=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Jn=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},Yn=class extends W{id=`hermes`;name=`Hermes Agent`;family=`hermes`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp_servers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule();return S(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!S(e))return{};let t=w(e,`utf-8`);try{return vn(t)??{}}catch{throw Error(`Invalid YAML in ${e}. Please fix or remove the file before retrying.`)}}async writeConfig(e){let t=this.getConfigPath(),n=this.getPathModule().dirname(t),r={};if(S(t))try{r=vn(w(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ye(n,{recursive:!0}),D(t,yn(r,{lineWidth:120}),`utf-8`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={command:t.command,args:t.args??[],enabled:!0},await this.writeConfig(n)}getScaffoldRoot(){return this.getHermesDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getHermesDir();return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}buildInstructionContent(e,t){return`# AI Kit — Hermes Agent Instructions
4
+ `;)n++;else if(e[n]===`/`&&n+1<r&&e[n+1]===`*`){for(n+=2;n+1<r&&!(e[n]===`*`&&e[n+1]===`/`);)n++;n+=2}else t+=e[n++];return t.replace(/,(\s*[}\]])/g,`$1`)}var W=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!S(t))return{};let n=await Xe(t,`utf-8`);try{return JSON.parse(In(n))}catch{throw Error(`Invalid JSON in ${t}. Please fix or remove the file before retrying.`)}}async writeConfig(e,t){let n=this.getConfigPath(t),r=O(n),i=k(r,`.aikit-tmp-${_n()}.json`);await Ye(r,{recursive:!0});try{await L(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await Ze(i,n)}catch(e){try{await $e(i)}catch{}throw e}}async registerMcp(e,t,n){let r=await this.readConfig(n);r[this.configKey]||(r[this.configKey]={}),r[this.configKey][e]=t,await this.writeConfig(r,n)}async unregisterMcp(e,t){let n=await this.readConfig(t);n[this.configKey]&&(delete n[this.configKey][e],await this.writeConfig(n,t))}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}},Ln=class extends W{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule().resolve(N());return S(this.getPathModule().resolve(e,`.claude.json`))||S(this.getPathModule().resolve(e,`.claude`))}getConfigPath(){return this.getPathModule().resolve(N(),`.claude.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:e.resolve(t,`hooks`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?M:A}},Rn=class extends W{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},G=class extends W{family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;hasInstructions=!1;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getConfigDir();if(process.platform===`darwin`){let t=this.getMacAppPath();return S(e)||t!==null&&S(t)}return S(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),hooks:e.resolve(t,`hooks`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=N();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?M:A}},zn=class extends W{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(j(N(),`.copilot`)):!1}getConfigPath(){return j(N(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return j(N(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=j(N(),`.copilot`);return{agents:j(e,`agents`),skills:j(e,`skills`),prompts:null,flows:j(e,`flows`),hooks:j(e,`hooks`),commands:null,instructions:j(N(),`.github`,`copilot-instructions.md`),manifest:j(e,`.aikit-scaffold.json`)}}},Bn=class extends G{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Vn=class extends G{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.mdc`)}},Hn=class e extends W{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;if(S(this.getCopilotConfigDir()))return!0;let t=this.getJetBrainsBaseDir();if(!S(t))return!1;try{return T(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(){return j(this.getCopilotConfigDir(),`mcp.json`)}async registerMcp(e,t,n){let r=this.getCopilotConfigDir();await Ye(r,{recursive:!0});let i=t.args??[],a=i.indexOf(`-e`),o;if(a!==-1&&a+1<i.length){let t=i[a+1],n=j(r,`${e}-launcher.js`);await L(n,t,`utf-8`),o=[...i.slice(0,a),n,...i.slice(a+2)]}else o=[...i];let s={type:`stdio`,...t,args:o};await super.registerMcp(e,s,n)}getScaffoldRoot(e){return null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null,hooks:null}}buildInstructionContent(e,t){return t}getCopilotConfigDir(){let e=N();return process.platform===`win32`?j(process.env.LOCALAPPDATA??j(e,`AppData`,`Local`),`github-copilot`,`intellij`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`github-copilot`,`intellij`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`github-copilot`,`intellij`)}getJetBrainsBaseDir(){let e=N();return process.platform===`win32`?j(process.env.APPDATA??j(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?j(e,`Library`,`Application Support`,`JetBrains`):j(process.env.XDG_CONFIG_HOME??j(e,`.config`),`JetBrains`)}},Un=class extends G{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Wn=class extends G{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Gn=class extends G{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},Kn=class extends G{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(N(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},qn=class extends G{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(N(),this.scaffoldBase,`rules`,`aikit.md`)}},Jn=class extends W{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?S(this.getPathModule().resolve(N(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(N(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(N(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(N(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}getPathModule(){return process.platform===`win32`?M:A}},Yn=class extends W{id=`hermes`;name=`Hermes Agent`;family=`hermes`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcp_servers`;async detect(){if(!this.isPlatformSupported())return!1;let e=this.getPathModule();return S(this.getHermesDir(e))}getConfigPath(){return this.getPathModule().resolve(this.getHermesDir(),`config.yaml`)}async readConfig(){let e=this.getConfigPath();if(!S(e))return{};let t=w(e,`utf-8`);try{return vn(t)??{}}catch{throw Error(`Invalid YAML in ${e}. Please fix or remove the file before retrying.`)}}async writeConfig(e){let t=this.getConfigPath(),n=this.getPathModule().dirname(t),r={};if(S(t))try{r=vn(w(t,`utf-8`))}catch{}e[this.configKey]&&(r[this.configKey]=e[this.configKey]),await Ye(n,{recursive:!0}),D(t,yn(r,{lineWidth:120}),`utf-8`)}async registerMcp(e,t){let n=await this.readConfig();n[this.configKey]||(n[this.configKey]={});let r=n[this.configKey];r[e]={command:t.command,args:t.args??[],enabled:!0},await this.writeConfig(n)}getScaffoldRoot(){return this.getHermesDir()}getScaffoldPaths(){let e=this.getPathModule(),t=this.getHermesDir();return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`),hooks:null}}buildInstructionContent(e,t){return`# AI Kit — Hermes Agent Instructions
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.
@@ -48,12 +48,12 @@ Issues found:`);for(let e of n.issues)console.log(` - ${e}`)}}}],Xr=[{name:`pro
48
48
  Options: --type, --name, --node-id, --edge-type, --direction, --depth, --limit, --source-path`,run:async e=>{let t=e.shift()?.trim()??``;if(!t)throw new h(`Usage: aikit graph <action>
49
49
  Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let{graphStore:n}=await Z(),r=g(e,`--type`,``),i=g(e,`--name`,``),a=g(e,`--node-id`,``),o=g(e,`--edge-type`,``),s=g(e,`--direction`,`both`),c=_(e,`--depth`,2),l=_(e,`--limit`,50),u=g(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];if(!d)throw new h(`Unknown graph action: ${t}\nActions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`);let f=await xt(n,{action:d,nodeType:r||void 0,namePattern:i||void 0,sourcePath:u||void 0,nodeId:a||void 0,edgeType:o||void 0,direction:s,maxDepth:c,limit:l});if(console.log(f.summary),f.nodes&&f.nodes.length>0){console.log(`
50
50
  Nodes:`);for(let e of f.nodes){let t=Object.keys(e.properties).length>0?` ${JSON.stringify(e.properties)}`:``;console.log(` ${e.name} (${e.type}, id: ${e.id})${t}`)}}if(f.edges&&f.edges.length>0){console.log(`
51
- Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],di=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=g(e,`--category`,``).trim(),n=x(g(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await f(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Z(),s=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${s.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=g(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await Z(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=g(e,`--category`,``).trim()||void 0,n=g(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=g(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await f();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Z(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=_(e,`--max-chars`,3e3),n=g(e,`--path`,``).trim()||void 0,r=g(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await f();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Z(),s=n?await ct(o,{path:n,query:i,maxChars:t,segmentation:r}):await ct(o,{text:a??``,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}];function fi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function pi(){let e=await $n({scope:`user`});if(e.length===0)return 0;let t=br(),n=0;for(let r of e)try{let e=(await r.readConfig())[r.configKey]?.[m];if(!e||!fi(e))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(m,t),n++}catch{}return n}const mi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await pi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=F(`cli:rollback`),hi=k(N(),`.aikit`,`versions`),gi=k(N(),`.aikit`,`current-version.json`),_i=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(hi,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(hi,`current-version.json.tmp`);await L(i,JSON.stringify({version:t},null,2),`utf-8`),await Ze(i,gi),Q.debug(`Switched to v${t}`)}}],vi=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=Se(e),n=_(e,`--limit`,5),r=g(e,`--mode`,`hybrid`),i=_(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new h(`Usage: aikit search <query>`);let{embedder:o,store:s,graphStore:c}=await Z(),l=await o.embedQuery(a),u;if(r===`keyword`)u=await s.ftsSearch(a,{limit:n});else if(r===`semantic`)u=await s.search(l,{limit:n});else{let[e,t]=await Promise.all([s.search(l,{limit:n*2}),s.ftsSearch(a,{limit:n*2}).catch(()=>[])]);u=ie(e,t).slice(0,n)}if(t){me({query:a,results:u,graphHops:i});return}if(u.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of u){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${u.length} result(s) found.`),i>0&&u.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(c,u.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=Se(e),n=_(e,`--limit`,10),r=g(e,`--glob`,``).trim()||void 0,i=g(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new h(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:o,store:s}=await Z(),c=await gt(o,s,{query:a,glob:r,pattern:i,limit:n});if(t){me(c);return}if(c.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${c.strategies.join(`, `)}`),console.log(`Results: ${c.results.length} shown (${c.totalFound} total)`);for(let e of c.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=_(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new h(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await Qt(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${de(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=_(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new h(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();ee(await an(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=g(e,`--direction`,`both`).trim()||`both`,n=_(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new h(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();re(await sn(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=_(e,`--limit`,5),n=g(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new h(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();u(await vt(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=_(e,`--limit`,100),{embedder:n,store:r}=await Z();be(await _t(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();if(!t)throw new h(`Usage: aikit lookup <id>`);let{store:n}=await Z(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}];async function yi(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),c=p(),l=a(process.execPath,[c,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),u=`http://localhost:${t}${r}`,d=`http://localhost:${t}/health`,f=!1;for(let e=0;e<30;e+=1){try{if((await fetch(d)).ok){f=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!f)throw l.kill(),new h(`Server failed to start within 30 seconds.`);let ee=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${ee}: ${u}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,u],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[u],{stdio:`ignore`,detached:!0}).unref()}let te=()=>{l.kill(),process.exit(0)};process.on(`SIGINT`,te),process.on(`SIGTERM`,te),await new Promise(e=>{l.on(`exit`,()=>e())})}const bi=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=Se(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:o}=await import(`../../core/dist/index.js`),{existsSync:s}=await import(`node:fs`),c=Ve(),l=a(),u=s(j(c,`.vscode`,`mcp.json`)),d={mode:void 0,dataPath:void 0};if(l&&u)d.mode=`workspace (overrides user-level for this workspace)`,d.dataPath=j(c,n.data);else if(l){let e=r(c);d.mode=s(j(c,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,d.dataPath=i(e)}else d.mode=`workspace`,d.dataPath=j(c,n.data);l&&!u&&(d.workspaces=o().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();d.records=t.totalRecords,d.files=t.totalFiles,d.lastIndexed=t.lastIndexedAt??null,d.backend=t.storeBackend,d.model=t.embeddingModel,d.contentTypeBreakdown=t.contentTypeBreakdown,d.sourcePaths=n.slice(0,20),d.sourcePathTotal=n.length}catch{d.indexAvailable=!1}if(t){me(d);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${d.mode}`),console.log(` Data: ${d.dataPath}`),l&&!u){let e=o();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(d.records!==void 0){console.log(` Records: ${d.records}`),console.log(` Files: ${d.files}`),console.log(` Indexed: ${d.lastIndexed??`Never`}`),console.log(` Backend: ${d.backend}`),console.log(` Model: ${d.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(d.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=d.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${d.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);d.sourcePathTotal>20&&console.log(` ... and ${d.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");l&&!u&&!s(j(c,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Z();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
52
- `)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=g(e,`--transport`,`stdio`),n=g(e,`--port`,`3210`),r=v(e,`--daemon`);try{await Jr({silent:!0})}catch{}if(t===`stdio`&&r){let{runProxy:e}=await import(`../../server/dist/proxy.js`);try{let t=`http://127.0.0.1:${n}/health`;if((await fetch(t,{signal:AbortSignal.timeout(2e3)})).ok){await e({port:Number(n),autoStart:!1});return}}catch{}await e({port:Number(n),autoStart:!0});return}let i=fn(p(),[],{cwd:N(),stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:t,AIKIT_PORT:n}});t===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n)throw new h(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-DbMdFkrH.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-DbMdFkrH.js`);await e({force:a})}else if(t)await Dr({force:a});else if(n){let{initProject:e}=await import(`./init-DbMdFkrH.js`);await e({force:a})}else await Dr({force:a})}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=g(e,`--cwd`,``).trim()||void 0,n=g(e,`--files`,``),r=g(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await nt({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});ae(s),s.passed||(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=Se(e),n=Ct(e.shift());if(t){me(n);return}console.log(`Project Health: ${n.path}`),console.log(`─`.repeat(50));for(let e of n.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${n.score}% — ${n.summary}`)}},{name:`prune`,description:`Clean up orphaned storage, legacy data, and stale partitions`,usage:`aikit prune [--dry-run] [--max-age-days=90] [--force]`,run:async e=>{let{prune:t,formatBytes:n,markPruneRun:r}=await import(`../../tools/dist/index.js`),i=e.includes(`--dry-run`),a=e.includes(`--force`),o=e.find(e=>e.startsWith(`--max-age-days=`)),s=o?Number.parseInt(o.split(`=`)[1]??``,10):90;if(!i&&!a){console.log(`⚠️ This will permanently delete data. Use --dry-run to preview, or --force to execute.`);return}console.log(i?`🔍 Dry run — no files will be deleted
51
+ Edges:`);for(let e of f.edges){let t=e.weight===1?``:` (weight: ${e.weight})`;console.log(` ${e.fromId} --[${e.type}]--> ${e.toId}${t}`)}}f.stats&&(console.log(`\nNode types: ${JSON.stringify(f.stats.nodeTypes)}`),console.log(`Edge types: ${JSON.stringify(f.stats.edgeTypes)}`)),f.deleted!==void 0&&console.log(`Deleted: ${f.deleted}`)}}],di=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=g(e,`--category`,``).trim(),n=x(g(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await f(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Z(),s=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${s.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=g(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Z(),i=await r.forget(n,t);console.log(`Removed curated entry: ${i.path}`)}},{name:`read`,description:`Read a curated entry`,usage:`aikit read <path>`,run:async e=>{let t=e.shift()?.trim()??``;t||(console.error(`Usage: aikit read <path>`),process.exit(1));let{curated:n}=await Z(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=g(e,`--category`,``).trim()||void 0,n=g(e,`--tag`,``).trim()||void 0,{curated:r}=await Z(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=g(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await f();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Z(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=_(e,`--max-chars`,3e3),n=g(e,`--path`,``).trim()||void 0,r=g(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await f();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Z(),s=n?await ct(o,{path:n,query:i,maxChars:t,segmentation:r}):await ct(o,{text:a??``,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}];function fi(e){if(!e)return!1;let t=/[/\\]versions[/\\]v\d+\.\d+\.\d+[/\\]/;return e.command&&t.test(e.command)?!0:e.args?e.args.some(e=>t.test(e)):!1}async function pi(){let e=await $n({scope:`user`});if(e.length===0)return 0;let t=br(),n=0;for(let r of e)try{let e=(await r.readConfig())[r.configKey]?.[m];if(!e||!fi(e))continue;C(O(r.getConfigPath()),{recursive:!0}),await r.registerMcp(m,t),n++}catch{}return n}const mi=[{name:`migrate-launcher`,description:`Migrate version-pinned MCP configs to version-neutral launcher (narrow, no side effects)`,usage:`aikit migrate-launcher`,run:async()=>{let e=await pi();if(e===0){console.log(`No version-pinned configs found.`);return}console.log(`Migrated ${e} IDE config(s) to version-neutral launcher.`),console.log(`Restart your IDE for changes to take effect.`)}}],Q=F(`cli:rollback`),hi=k(N(),`.aikit`,`versions`),gi=k(N(),`.aikit`,`current-version.json`),_i=[{name:`rollback`,description:`Rollback to a previous AI Kit version (see "aikit versions" for available)`,usage:`aikit rollback <version>`,run:async e=>{let t=e[0];t||(console.error(`Usage: aikit rollback <version>`),console.error(`Example: aikit rollback 0.1.280`),process.exit(1)),Q.debug(`Validating version directory for v${t}...`);let n=k(hi,`v${t}`);S(n)||(Q.warn(`Version v${t} not found`),process.exit(1)),Q.debug(`Validating version dir...`);let r=k(n,`package.json`);S(r)||(Q.error(`Version v${t} is missing package.json`),process.exit(1));try{JSON.parse(w(r,`utf-8`)).version||(Q.error(`Version v${t} has invalid package.json (missing version field)`),process.exit(1))}catch{Q.error(`Version v${t} has invalid package.json`),process.exit(1)}let i=k(hi,`current-version.json.tmp`);await L(i,JSON.stringify({version:t},null,2),`utf-8`),await Ze(i,gi),Q.debug(`Switched to v${t}`)}}],vi=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=Se(e),n=_(e,`--limit`,5),r=g(e,`--mode`,`hybrid`),i=_(e,`--graph-hops`,0),a=e.join(` `).trim();if(!a)throw new h(`Usage: aikit search <query>`);let{embedder:o,store:s,graphStore:c}=await Z(),l=await o.embedQuery(a),u;if(r===`keyword`)u=await s.ftsSearch(a,{limit:n});else if(r===`semantic`)u=await s.search(l,{limit:n});else{let[e,t]=await Promise.all([s.search(l,{limit:n*2}),s.ftsSearch(a,{limit:n*2}).catch(()=>[])]);u=ie(e,t).slice(0,n)}if(t){me({query:a,results:u,graphHops:i});return}if(u.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of u){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${u.length} result(s) found.`),i>0&&u.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(c,u.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:i,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${i} hop${i>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=Se(e),n=_(e,`--limit`,10),r=g(e,`--glob`,``).trim()||void 0,i=g(e,`--pattern`,``).trim()||void 0,a=e.join(` `).trim()||void 0;if(!a&&!r&&!i)throw new h(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`);let{embedder:o,store:s}=await Z(),c=await gt(o,s,{query:a,glob:r,pattern:i,limit:n});if(t){me(c);return}if(c.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${c.strategies.join(`, `)}`),console.log(`Results: ${c.results.length} shown (${c.totalFound} total)`);for(let e of c.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=_(e,`--max-files`,15),n=e.join(` `).trim();if(!n)throw new h(`Usage: aikit scope-map <task> [--max-files N]`);let{embedder:r,store:i}=await Z(),a=await Qt(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${de(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=_(e,`--limit`,20),n=e.join(` `).trim();if(!n)throw new h(`Usage: aikit symbol <name> [--limit N]`);let{embedder:r,store:i}=await Z();ee(await an(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=g(e,`--direction`,`both`).trim()||`both`,n=_(e,`--max-depth`,3),r=e.join(` `).trim();if(!r||![`forward`,`backward`,`both`].includes(t))throw new h(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`);let{embedder:i,store:a}=await Z();re(await sn(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=_(e,`--limit`,5),n=g(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();if(!r)throw new h(`Usage: aikit examples <query> [--limit N] [--content-type type]`);let{embedder:i,store:a}=await Z();u(await vt(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=_(e,`--limit`,100),{embedder:n,store:r}=await Z();be(await _t(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();if(!t)throw new h(`Usage: aikit lookup <id>`);let{store:n}=await Z(),r=await n.getById(t);if(r){console.log(r.id),console.log(`─`.repeat(60)),console.log(`Path: ${r.sourcePath}`),console.log(`Chunk: ${r.chunkIndex+1}/${r.totalChunks}`),console.log(`Lines: ${r.startLine}-${r.endLine}`),console.log(`Type: ${r.contentType} | Origin: ${r.origin}`),r.tags.length>0&&console.log(`Tags: ${r.tags.join(`, `)}`),console.log(``),console.log(r.content);return}let i=await n.getBySourcePath(t);if(i.length===0){console.log(`No indexed content found for: ${t}`);return}i.sort((e,t)=>e.chunkIndex-t.chunkIndex),console.log(t),console.log(`─`.repeat(60)),console.log(`Chunks: ${i.length} | Type: ${i[0].contentType}`);for(let e of i){let t=e.startLine?` (lines ${e.startLine}-${e.endLine})`:``;console.log(`\nChunk ${e.chunkIndex+1}/${e.totalChunks}${t}`),console.log(e.content)}}}];async function yi(e){let{port:t,noOpen:n,urlPath:r,commandName:i}=e;console.log(`Starting AI Kit server on port ${t}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),c=p(),l=a(process.execPath,[c,`--transport`,`http`,`--port`,String(t)],{cwd:N(),stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(t)}}),u=`http://localhost:${t}${r}`,d=`http://localhost:${t}/health`,f=!1;for(let e=0;e<30;e+=1){try{if((await fetch(d)).ok){f=!0;break}}catch{}await new Promise(e=>setTimeout(e,1e3))}if(!f)throw l.kill(),new h(`Server failed to start within 30 seconds.`);let ee=i.charAt(0).toUpperCase()+i.slice(1);if(console.log(`AI Kit ${ee}: ${u}`),console.log(`Press Ctrl+C to stop.`),!n){let e=o();e===`win32`?a(`cmd`,[`/c`,`start`,``,u],{stdio:`ignore`,detached:!0}).unref():a(e===`darwin`?`open`:`xdg-open`,[u],{stdio:`ignore`,detached:!0}).unref()}let te=()=>{l.kill(),process.exit(0)};process.on(`SIGINT`,te),process.on(`SIGTERM`,te),await new Promise(e=>{l.on(`exit`,()=>e())})}const bi=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async e=>{let t=Se(e),{AIKIT_PATHS:n,computePartitionKey:r,getPartitionDir:i,isUserInstalled:a,listWorkspaces:o}=await import(`../../core/dist/index.js`),{existsSync:s}=await import(`node:fs`),c=Ve(),l=a(),u=s(j(c,`.vscode`,`mcp.json`)),d={mode:void 0,dataPath:void 0};if(l&&u)d.mode=`workspace (overrides user-level for this workspace)`,d.dataPath=j(c,n.data);else if(l){let e=r(c);d.mode=s(j(c,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,d.dataPath=i(e)}else d.mode=`workspace`,d.dataPath=j(c,n.data);l&&!u&&(d.workspaces=o().length);try{let{store:e}=await Z(),t=await e.getStats(),n=await e.listSourcePaths();d.records=t.totalRecords,d.files=t.totalFiles,d.lastIndexed=t.lastIndexedAt??null,d.backend=t.storeBackend,d.model=t.embeddingModel,d.contentTypeBreakdown=t.contentTypeBreakdown,d.sourcePaths=n.slice(0,20),d.sourcePathTotal=n.length}catch{d.indexAvailable=!1}if(t){me(d);return}if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${d.mode}`),console.log(` Data: ${d.dataPath}`),l&&!u){let e=o();console.log(` Registry: ${e.length} workspace(s) enrolled`)}if(d.records!==void 0){console.log(` Records: ${d.records}`),console.log(` Files: ${d.files}`),console.log(` Indexed: ${d.lastIndexed??`Never`}`),console.log(` Backend: ${d.backend}`),console.log(` Model: ${d.model}`),console.log(``),console.log(`Content Types:`);for(let[e,t]of Object.entries(d.contentTypeBreakdown))console.log(` ${e}: ${t}`);let e=d.sourcePaths;if(e.length>0){console.log(``),console.log(`Files (${d.sourcePathTotal} total):`);for(let t of e.slice(0,20))console.log(` ${t}`);d.sourcePathTotal>20&&console.log(` ... and ${d.sourcePathTotal-20} more`)}}else console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.");l&&!u&&!s(j(c,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx -y @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Z();console.log(`Indexing sources...`);let o=e=>{e.phase===`chunking`&&e.currentFile&&process.stdout.write(`\r [${e.filesProcessed+1}/${e.filesTotal}] ${e.currentFile}`),e.phase===`done`&&process.stdout.write(`
52
+ `)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server. Default: direct stdio (one server per workspace). Use --daemon to share a single HTTP daemon across multiple clients.`,usage:`aikit serve [--transport stdio|http] [--port N] [--daemon]`,run:async e=>{let t=g(e,`--transport`,`stdio`),n=g(e,`--port`,`3210`),r=v(e,`--daemon`);try{await Jr({silent:!0})}catch{}if(t===`stdio`&&r){let{runProxy:e}=await import(`../../server/dist/proxy.js`);try{let t=`http://127.0.0.1:${n}/health`;if((await fetch(t,{signal:AbortSignal.timeout(2e3)})).ok){await e({port:Number(n),autoStart:!1});return}}catch{}await e({port:Number(n),autoStart:!0});return}let i=fn(p(),[],{cwd:N(),stdio:t===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,NODE_OPTIONS:s(process.env.NODE_OPTIONS),AIKIT_TRANSPORT:t,AIKIT_PORT:n}});t===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n)throw new h(`Cannot use --user and --workspace together.`);if(i){let{guideProject:e}=await import(`./init-CWLiK7bC.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-CWLiK7bC.js`);await e({force:a})}else if(t)await Dr({force:a});else if(n){let{initProject:e}=await import(`./init-CWLiK7bC.js`);await e({force:a})}else await Dr({force:a})}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=g(e,`--cwd`,``).trim()||void 0,n=g(e,`--files`,``),r=g(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await nt({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});ae(s),s.passed||(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=Se(e),n=Ct(e.shift());if(t){me(n);return}console.log(`Project Health: ${n.path}`),console.log(`─`.repeat(50));for(let e of n.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${n.score}% — ${n.summary}`)}},{name:`prune`,description:`Clean up orphaned storage, legacy data, and stale partitions`,usage:`aikit prune [--dry-run] [--max-age-days=90] [--force]`,run:async e=>{let{prune:t,formatBytes:n,markPruneRun:r}=await import(`../../tools/dist/index.js`),i=e.includes(`--dry-run`),a=e.includes(`--force`),o=e.find(e=>e.startsWith(`--max-age-days=`)),s=o?Number.parseInt(o.split(`=`)[1]??``,10):90;if(!i&&!a){console.log(`⚠️ This will permanently delete data. Use --dry-run to preview, or --force to execute.`);return}console.log(i?`🔍 Dry run — no files will be deleted
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
55
  ✅ Cleanup complete.`))}},{name:`audit`,description:`Run a unified project audit (structure, deps, patterns, health, dead symbols, check)`,usage:`aikit audit [path] [--checks structure,dependencies,patterns,health,dead_symbols,check,entry_points] [--detail efficient|normal|full]`,run:async e=>{let{store:t,embedder:n}=await Z(),r=g(e,`--detail`,`efficient`)||`efficient`,i=g(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await tt(t,n,{path:e.shift()||`.`,checks:a,detail:r});if(o.ok){if(console.log(o.summary),o.next&&o.next.length>0){console.log(`
56
56
  Suggested next steps:`);for(let e of o.next)console.log(` → ${e.tool}: ${e.reason}`)}}else console.error(o.error?.message??`Audit failed`),process.exitCode=1}},{name:`guide`,description:`Tool discovery — recommend AI Kit tools for a given goal`,usage:`aikit guide <goal> [--max N]`,run:async e=>{let t=e.indexOf(`--max`),n=5;t!==-1&&t+1<e.length&&(n=Number.parseInt(e.splice(t,2)[1],10)||5);let r=e.join(` `).trim();if(!r)throw new h(`Usage: aikit guide <goal> [--max N]
57
- Example: aikit guide "audit this project"`);let i=St(r,n);console.log(`Workflow: ${i.workflow}`),console.log(` ${i.description}\n`),console.log(`Recommended tools:`);for(let e of i.tools){let t=e.suggestedArgs?` ${JSON.stringify(e.suggestedArgs)}`:``;console.log(` ${e.order}. ${e.tool} — ${e.reason}${t}`)}i.alternativeWorkflows.length>0&&console.log(`\nAlternatives: ${i.alternativeWorkflows.join(`, `)}`)}},{name:`replay`,description:`Show recent tool invocation audit trail`,usage:`aikit replay [--last N] [--tool <name>] [--source mcp|cli]`,run:async e=>{let t=Yt({last:Number.parseInt(e[e.indexOf(`--last`)+1],10)||20,tool:e.includes(`--tool`)?e[e.indexOf(`--tool`)+1]:void 0,source:e.includes(`--source`)?e[e.indexOf(`--source`)+1]:void 0});if(t.length===0){console.log(`No replay entries. Activity is logged when tools are invoked.`);return}console.log(`Replay Log (${t.length} entries)\n`);for(let e of t){let t=e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts,n=e.status===`ok`?`✓`:`✗`;console.log(`${t} ${n} ${e.tool} (${e.durationMs}ms) [${e.source}]`),console.log(` in: ${e.input}`),console.log(` out: ${e.output}`)}Xt().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Jt(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await yi({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/_dashboard/`,commandName:`dashboard`})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await yi({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=F(`cli:update`),xi=k(N(),`.aikit`),Si=k(xi,`versions`),Ci=k(xi,`current-version.json`);function wi(){if(!S(Ci))return null;try{let e=w(Ci,`utf-8`);return JSON.parse(e)}catch{return null}}function Ti(e){S(xi)||C(xi,{recursive:!0});let t=`${Ci}.tmp`;D(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),we(t,Ci)}function Ei(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=n[e]??0,i=r[e]??0;if(t>i)return!0;if(t<i)return!1}return!1}async function Di(){let e=await fetch(`https://registry.npmjs.org/@vpxa%2faikit/latest`);if(!e.ok)throw Error(`npm registry responded ${e.status}: ${e.statusText}`);let t=await e.json(),n=Array.isArray(t)?t[0]:t;return n.version??n[`dist-tags`]?.latest??`0.0.0`}const Oi=[{name:`version-update`,description:`Update AI Kit to the latest version from npm (auto-detects and installs newer release)`,usage:`aikit version-update`,run:async()=>{let e=wi();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Di()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Ei(t,e.version)){$.info(`Already latest version.`);return}$.debug(`Updating to ${t}...`);try{let e=`https://registry.npmjs.org/@vpxa/aikit/-/aikit-${t}.tgz`,n=await fetch(e);if(!n.ok)throw Error(`Download failed: ${n.status} ${n.statusText}`);let r=Buffer.from(await n.arrayBuffer()),i=k(Si,`v${t}-staging`);S(i)&&E(i,{recursive:!0,force:!0}),C(i,{recursive:!0});try{let e=k(i,`aikit-${t}.tgz`);D(e,r),$.debug(`Extracting...`),R(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=k(i,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),R(`npm ${Pe.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=k(n,`packages`,`server`,`dist`,`bin.js`);if(!S(a))throw Error(`Server entry not found at ${a}`);let o=k(Si,`v${t}`);S(Si)||C(Si,{recursive:!0}),S(o)&&($.debug(`Removing previous installation at ${o}...`),E(o,{recursive:!0,force:!0})),we(n,o),Ti(t),$.info(`Updated to ${t}`)}finally{S(i)&&E(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],ki=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{await Dr({force:!0});let e=I();if(e){if(S(j(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-DbMdFkrH.js`);await e({force:!0})}if(S(j(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=se(),r=ye();await t(e,n,[...he],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[..._e],r,!0)}}let{rmSync:t}=await import(`node:fs`),n=k(N(),`.aikit`,`cache`,`wasm`);if(S(n))try{t(n,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,n)}}}],Ai=F(`cli:versions`),ji=k(N(),`.aikit`,`versions`),Mi=k(N(),`.aikit`,`current-version.json`);function Ni(){try{return S(Mi)?JSON.parse(w(Mi,`utf-8`)).version??null:null}catch{return null}}const Pi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!S(ji)){Ai.warn(`No versions installed.`);return}let e=Ni(),t=T(ji,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=Te(k(ji,e.name));return{name:e.name,ver:e.name.slice(1),mtime:t.mtime}}).sort((e,t)=>t.mtime.getTime()-e.mtime.getTime());if(t.length===0){Ai.warn(`No versions installed.`);return}for(let n of t){let t=n.ver===e,r=n.mtime.toISOString().split(`T`)[0],i=t?`(current)`:`(older)`,a=t?` ←`:``;console.log(`${n.name} - ${r} ${i}${a}`)}}}],Fi=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=x(g(e,`--files`,``)),r=g(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=Zt(i,n,{description:r});console.log(`Saved workset: ${e.name}`),d(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=yt(i);if(!e){console.log(`No workset found: ${i}`);return}d(e);return}case`list`:{let e=At();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)d(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=ft(i);console.log(e?`Deleted workset: ${i}`:`No workset found: ${i}`);return}case`add`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset add <name> --files f1,f2`),process.exit(1));let e=et(i,n);console.log(`Updated workset: ${e.name}`),d(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Kt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),d(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1));let r=await ue();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await f(),a=rn(r,n,le(t||i));console.log(`Stored stash entry: ${a.key}`),console.log(` Type: ${a.type}`),console.log(` Stored: ${a.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=tn(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=nn(r);if(e.length===0){console.log(`No stash entries saved.`);return}console.log(`Stash entries (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.key} (${t.type})`),console.log(` Stored: ${t.storedAt}`);return}case`delete`:{n||(console.error(`Usage: aikit stash delete <key>`),process.exit(1));let e=en(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=$t(r);console.log(`Cleared ${e} stash entr${e===1?`y`:`ies`}.`);return}default:console.error(`Unknown stash action: ${t}`),console.error(`Actions: set, get, list, delete, clear`),process.exit(1)}}},{name:`lane`,description:`Manage verified lanes — isolated file copies for parallel exploration`,usage:`aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`,run:async e=>{let t=e.shift();if((!t||![`create`,`list`,`status`,`diff`,`merge`,`discard`].includes(t))&&(console.error(`Usage: aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`),process.exit(1)),t===`list`){let e=Dt();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=g(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=wt(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=kt(n);console.log(`Lane: ${e.name}`),console.log(`Modified: ${e.modified} | Added: ${e.added} | Deleted: ${e.deleted}`);for(let t of e.entries)console.log(` ${t.status.padEnd(10)} ${t.file}`);break}case`diff`:{let e=Tt(n);console.log(`Lane: ${e.name} — ${e.modified} modified, ${e.added} added, ${e.deleted} deleted`);for(let t of e.entries)t.diff&&(console.log(`\n--- ${t.file} (${t.status})`),console.log(t.diff));break}case`merge`:{let e=Ot(n);console.log(`Merged ${e.filesMerged} files from lane "${e.name}".`);for(let t of e.files)console.log(` ${t}`);break}case`discard`:{let e=Et(n);console.log(e?`Lane "${n}" discarded.`:`Lane "${n}" not found.`);break}}}},{name:`queue`,description:`Manage task queues for sequential agent operations`,usage:`aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`,run:async e=>{let t=e.shift();if((!t||![`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`].includes(t))&&(console.error(`Usage: aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`),process.exit(1)),t===`list`){let e=Ut();if(e.length===0){console.log(`No queues.`);return}for(let t of e)console.log(`${t.name} pending:${t.pending} done:${t.done} failed:${t.failed} total:${t.total}`);return}let n=e.shift();switch(n||(console.error(`Queue name is required for "${t}".`),process.exit(1)),t){case`create`:{let e=Rt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Gt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Wt(n);console.log(e?`Next: ${e.title} (${e.id})`:`No pending items in queue "${n}".`);break}case`done`:{let t=e.shift();t||(console.error(`Usage: aikit queue done <name> <id>`),process.exit(1));let r=Bt(n,t);console.log(`Marked "${r.item.title}" as done.`);break}case`fail`:{let t=e.shift(),r=e.join(` `)||`Unknown error`;t||(console.error(`Usage: aikit queue fail <name> <id> [error message]`),process.exit(1));let i=Vt(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Ht(n);if(!e){console.log(`Queue "${n}" not found.`);return}console.log(`Queue: ${e.name} (${e.items.length} items)`);for(let t of e.items){let e=t.error?` — ${t.error}`:``;console.log(` ${t.status.padEnd(12)} ${t.id} ${t.title}${e}`)}break}case`clear`:{let e=Lt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=zt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Ii=[...vi,...di,...wn,...ui,...yr,...bi,...Zr,...Fn,...Tn,...Pn,...Fi,...Xr,...Oi,...ki,...ti,...Yr,...mi,...Pi,..._i,...si];Ii.push({name:`help`,description:`Show available commands`,run:async()=>{Ri()}});async function Li(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Ri();return}if(n===`--version`||n===`-v`){let e=j(O(ke(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(w(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Ii.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Ii.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Ri(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof h&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=li();e&&await e.store.close()}}function Ri(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
57
+ Example: aikit guide "audit this project"`);let i=St(r,n);console.log(`Workflow: ${i.workflow}`),console.log(` ${i.description}\n`),console.log(`Recommended tools:`);for(let e of i.tools){let t=e.suggestedArgs?` ${JSON.stringify(e.suggestedArgs)}`:``;console.log(` ${e.order}. ${e.tool} — ${e.reason}${t}`)}i.alternativeWorkflows.length>0&&console.log(`\nAlternatives: ${i.alternativeWorkflows.join(`, `)}`)}},{name:`replay`,description:`Show recent tool invocation audit trail`,usage:`aikit replay [--last N] [--tool <name>] [--source mcp|cli]`,run:async e=>{let t=Yt({last:Number.parseInt(e[e.indexOf(`--last`)+1],10)||20,tool:e.includes(`--tool`)?e[e.indexOf(`--tool`)+1]:void 0,source:e.includes(`--source`)?e[e.indexOf(`--source`)+1]:void 0});if(t.length===0){console.log(`No replay entries. Activity is logged when tools are invoked.`);return}console.log(`Replay Log (${t.length} entries)\n`);for(let e of t){let t=e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts,n=e.status===`ok`?`✓`:`✗`;console.log(`${t} ${n} ${e.tool} (${e.durationMs}ms) [${e.source}]`),console.log(` in: ${e.input}`),console.log(` out: ${e.output}`)}Xt().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{Jt(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await yi({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/_dashboard/`,commandName:`dashboard`})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210;await yi({port:Number.isFinite(n)?n:3210,noOpen:e.includes(`--no-open`),urlPath:`/settings/`,commandName:`settings`})}}],$=F(`cli:update`),xi=k(N(),`.aikit`),Si=k(xi,`versions`),Ci=k(xi,`current-version.json`);function wi(){if(!S(Ci))return null;try{let e=w(Ci,`utf-8`);return JSON.parse(e)}catch{return null}}function Ti(e){S(xi)||C(xi,{recursive:!0});let t=`${Ci}.tmp`;D(t,`${JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)}\n`),we(t,Ci)}function Ei(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=n[e]??0,i=r[e]??0;if(t>i)return!0;if(t<i)return!1}return!1}async function Di(){let e=await fetch(`https://registry.npmjs.org/@vpxa%2faikit/latest`);if(!e.ok)throw Error(`npm registry responded ${e.status}: ${e.statusText}`);let t=await e.json(),n=Array.isArray(t)?t[0]:t;return n.version??n[`dist-tags`]?.latest??`0.0.0`}const Oi=[{name:`version-update`,description:`Update AI Kit to the latest version from npm (auto-detects and installs newer release)`,usage:`aikit version-update`,run:async()=>{let e=wi();if(!e){$.debug("No installed version found. Run `aikit install` first.");return}$.debug(`Current version: ${e.version}`);let t;try{t=await Di()}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Failed to check for updates: ${t}`);return}if($.debug(`Latest version: ${t}`),!Ei(t,e.version)){$.info(`Already latest version.`);return}$.debug(`Updating to ${t}...`);try{let e=`https://registry.npmjs.org/@vpxa/aikit/-/aikit-${t}.tgz`,n=await fetch(e);if(!n.ok)throw Error(`Download failed: ${n.status} ${n.statusText}`);let r=Buffer.from(await n.arrayBuffer()),i=k(Si,`v${t}-staging`);S(i)&&E(i,{recursive:!0,force:!0}),C(i,{recursive:!0});try{let e=k(i,`aikit-${t}.tgz`);D(e,r),$.debug(`Extracting...`),R(`tar -xzf "${e}"`,{cwd:i,stdio:`pipe`,timeout:6e4});let n=k(i,`package`);if(!S(n))throw Error(`Expected "package/" directory not found after extraction`);$.debug(`Installing production dependencies...`),R(`npm ${Pe.join(` `)}`,{cwd:n,stdio:`pipe`,timeout:3e5});let a=k(n,`packages`,`server`,`dist`,`bin.js`);if(!S(a))throw Error(`Server entry not found at ${a}`);let o=k(Si,`v${t}`);S(Si)||C(Si,{recursive:!0}),S(o)&&($.debug(`Removing previous installation at ${o}...`),E(o,{recursive:!0,force:!0})),we(n,o),Ti(t),$.info(`Updated to ${t}`)}finally{S(i)&&E(i,{recursive:!0,force:!0})}}catch(e){let t=e instanceof Error?e.message:String(e);$.error(`Update failed: ${t}`)}}}],ki=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{await Dr({force:!0});let e=I();if(e){if(S(j(e,`.github`,`.aikit-scaffold.json`))){let{initScaffoldOnly:e}=await import(`./init-CWLiK7bC.js`);await e({force:!0})}if(S(j(e,`.github`,`skills`))){let{smartCopySkills:t}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a),n=se(),r=ye();await t(e,n,[...he],r,!0);let{smartCopyFlows:i}=await import(`./scaffold-BNPHP-QC.js`).then(e=>e.a);await i(e,n,[..._e],r,!0)}}let{rmSync:t}=await import(`node:fs`),n=k(N(),`.aikit`,`cache`,`wasm`);if(S(n))try{t(n,{recursive:!0,force:!0}),console.log(`✓ WASM cache cleared (will re-resolve on next start)`)}catch{console.warn(`⚠ Could not clear WASM cache at`,n)}}}],Ai=F(`cli:versions`),ji=k(N(),`.aikit`,`versions`),Mi=k(N(),`.aikit`,`current-version.json`);function Ni(){try{return S(Mi)?JSON.parse(w(Mi,`utf-8`)).version??null:null}catch{return null}}const Pi=[{name:`versions`,description:`List installed AI Kit versions (shows current, date, and available rollbacks)`,usage:`aikit versions`,run:async()=>{if(!S(ji)){Ai.warn(`No versions installed.`);return}let e=Ni(),t=T(ji,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>{let t=Te(k(ji,e.name));return{name:e.name,ver:e.name.slice(1),mtime:t.mtime}}).sort((e,t)=>t.mtime.getTime()-e.mtime.getTime());if(t.length===0){Ai.warn(`No versions installed.`);return}for(let n of t){let t=n.ver===e,r=n.mtime.toISOString().split(`T`)[0],i=t?`(current)`:`(older)`,a=t?` ←`:``;console.log(`${n.name} - ${r} ${i}${a}`)}}}],Fi=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=x(g(e,`--files`,``)),r=g(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=Zt(i,n,{description:r});console.log(`Saved workset: ${e.name}`),d(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=yt(i);if(!e){console.log(`No workset found: ${i}`);return}d(e);return}case`list`:{let e=At();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)d(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=ft(i);console.log(e?`Deleted workset: ${i}`:`No workset found: ${i}`);return}case`add`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset add <name> --files f1,f2`),process.exit(1));let e=et(i,n);console.log(`Updated workset: ${e.name}`),d(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=Kt(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),d(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1));let r=await ue();switch(t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),i=t.trim()?``:await f(),a=rn(r,n,le(t||i));console.log(`Stored stash entry: ${a.key}`),console.log(` Type: ${a.type}`),console.log(` Stored: ${a.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=tn(r,n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=nn(r);if(e.length===0){console.log(`No stash entries saved.`);return}console.log(`Stash entries (${e.length})`),console.log(`─`.repeat(60));for(let t of e)console.log(`${t.key} (${t.type})`),console.log(` Stored: ${t.storedAt}`);return}case`delete`:{n||(console.error(`Usage: aikit stash delete <key>`),process.exit(1));let e=en(r,n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=$t(r);console.log(`Cleared ${e} stash entr${e===1?`y`:`ies`}.`);return}default:console.error(`Unknown stash action: ${t}`),console.error(`Actions: set, get, list, delete, clear`),process.exit(1)}}},{name:`lane`,description:`Manage verified lanes — isolated file copies for parallel exploration`,usage:`aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`,run:async e=>{let t=e.shift();if((!t||![`create`,`list`,`status`,`diff`,`merge`,`discard`].includes(t))&&(console.error(`Usage: aikit lane <create|list|status|diff|merge|discard> [name] [--files f1,f2]`),process.exit(1)),t===`list`){let e=Dt();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=g(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=wt(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=kt(n);console.log(`Lane: ${e.name}`),console.log(`Modified: ${e.modified} | Added: ${e.added} | Deleted: ${e.deleted}`);for(let t of e.entries)console.log(` ${t.status.padEnd(10)} ${t.file}`);break}case`diff`:{let e=Tt(n);console.log(`Lane: ${e.name} — ${e.modified} modified, ${e.added} added, ${e.deleted} deleted`);for(let t of e.entries)t.diff&&(console.log(`\n--- ${t.file} (${t.status})`),console.log(t.diff));break}case`merge`:{let e=Ot(n);console.log(`Merged ${e.filesMerged} files from lane "${e.name}".`);for(let t of e.files)console.log(` ${t}`);break}case`discard`:{let e=Et(n);console.log(e?`Lane "${n}" discarded.`:`Lane "${n}" not found.`);break}}}},{name:`queue`,description:`Manage task queues for sequential agent operations`,usage:`aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`,run:async e=>{let t=e.shift();if((!t||![`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`].includes(t))&&(console.error(`Usage: aikit queue <create|push|next|done|fail|get|list|clear|delete> [name] [args]`),process.exit(1)),t===`list`){let e=Ut();if(e.length===0){console.log(`No queues.`);return}for(let t of e)console.log(`${t.name} pending:${t.pending} done:${t.done} failed:${t.failed} total:${t.total}`);return}let n=e.shift();switch(n||(console.error(`Queue name is required for "${t}".`),process.exit(1)),t){case`create`:{let e=Rt(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Gt(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=Wt(n);console.log(e?`Next: ${e.title} (${e.id})`:`No pending items in queue "${n}".`);break}case`done`:{let t=e.shift();t||(console.error(`Usage: aikit queue done <name> <id>`),process.exit(1));let r=Bt(n,t);console.log(`Marked "${r.item.title}" as done.`);break}case`fail`:{let t=e.shift(),r=e.join(` `)||`Unknown error`;t||(console.error(`Usage: aikit queue fail <name> <id> [error message]`),process.exit(1));let i=Vt(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=Ht(n);if(!e){console.log(`Queue "${n}" not found.`);return}console.log(`Queue: ${e.name} (${e.items.length} items)`);for(let t of e.items){let e=t.error?` — ${t.error}`:``;console.log(` ${t.status.padEnd(12)} ${t.id} ${t.title}${e}`)}break}case`clear`:{let e=Lt(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=zt(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Ii=[...vi,...di,...wn,...ui,...yr,...bi,...Zr,...Fn,...Tn,...Pn,...Fi,...Xr,...Oi,...ki,...ti,...Yr,...mi,...Pi,..._i,...si];Ii.push({name:`help`,description:`Show available commands`,run:async()=>{Ri()}});async function Li(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){Ri();return}if(n===`--version`||n===`-v`){let e=j(O(ke(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(w(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Ii.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Ii.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),Ri(),process.exit(1));try{await r.run(t)}catch(e){throw e instanceof h&&(console.error(e.message),process.exit(e.exitCode)),e}finally{let e=li();e&&await e.store.close()}}function Ri(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
58
58
  `),console.log(`Usage: aikit <command> [options]
59
59
  `),console.log(`Commands:`);let e=Math.max(...Ii.map(e=>e.name.length));for(let t of Ii)console.log(` ${t.name.padEnd(e+2)}${t.description}`);console.log(``),console.log(`Options:`),console.log(` --help, -h Show this help`),console.log(` --version, -v Show version`)}export{Li as run};
@@ -1,4 +1,4 @@
1
- import{c as e,l as t,n,o as r,r as i,t as a}from"./scaffold-BNPHP-QC.js";import{_ as o,c as s,l as c,n as l,o as u,r as d,s as f,t as p}from"./templates-zHGu9MXa.js";import{appendFileSync as m,existsSync as h,mkdirSync as g,readFileSync as _,unlinkSync as v,writeFileSync as y}from"node:fs";import{basename as b,dirname as x,resolve as S}from"node:path";import{homedir as C}from"node:os";import{AIKIT_PATHS as w,EMBEDDING_DEFAULTS as T,isUserInstalled as E}from"../../core/dist/index.js";function D(e){return h(S(e,`.cursor`))?`cursor`:h(S(e,`.claude`))?`claude-code`:h(S(e,`.windsurf`))?`windsurf`:h(S(e,`.zed`))?`zed`:h(S(e,`.idea`))?`intellij`:h(S(e,`.opencode`))?`opencode`:h(S(e,`AGENTS.md`))?`hermes`:`copilot`}function O(e){let t=[];return h(S(e,`.cursor`))&&t.push(`cursor`),(h(S(e,`.claude`))||h(S(e,`CLAUDE.md`)))&&t.push(`claude-code`),h(S(e,`.windsurf`))&&t.push(`windsurf`),h(S(e,`.zed`))&&t.push(`zed`),h(S(e,`.idea`))&&t.push(`intellij`),h(S(e,`.gemini`))&&t.push(`gemini-cli`),(h(S(e,`.codex`))||h(S(e,`codex.md`)))&&t.push(`codex-cli`),(h(S(e,`.opencode`))||h(S(e,`OPENCODE.md`)))&&t.push(`opencode`),t.push(`copilot`),t.push(`hermes`),[...new Set(t)]}function k(e){return{servers:{[e]:{...f}}}}function A(e){let{type:t,...n}=f;return{mcpServers:{[e]:n}}}function j(e){let{type:t,...n}=f;return{context_servers:{[e]:{...n}}}}function M(e){let{type:t,...n}=f;return{mcp:{[e]:{type:`local`,command:[n.command,...n.args]}}}}const N={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json`))},writeInstructions(e,t){let n=S(e,`.github`),r=S(n,`copilot-instructions.md`);g(n,{recursive:!0}),y(r,l(b(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,t){y(S(e,`AGENTS.md`),p(b(e),t),`utf-8`),console.log(` Updated AGENTS.md`)}},P=`Orchestrator`;function F(e){let{command:t,args:n}=f;return{[e]:{command:t,args:[...n],type:`stdio`,env:{}}}}function I(e,t){let n=t??S(C(),`.claude`),r=S(n,`settings.json`),i=S(n,`..`,`.claude.json`),a=F(e),o;if(!h(i))o={};else try{o=JSON.parse(_(i,`utf-8`))}catch{console.warn(` ⚠ ${i} invalid JSON — overwriting`),o={}}g(x(i),{recursive:!0}),o.mcpServers={...o.mcpServers||{},...a},y(i,`${JSON.stringify(o,null,2)}\n`,`utf-8`),console.log(` Updated ${i} — ${e} MCP server`);let s;if(!h(r))g(n,{recursive:!0}),s={agent:P};else{try{s=JSON.parse(_(r,`utf-8`))}catch{console.warn(` ⚠ ${r} invalid JSON — overwriting`),s={}}delete s.mcpServers}s.agent=P;let c=S(n,`hooks`,`scripts`).replace(/\\/g,`/`);try{let e=d(`claude`,c);e.hooks&&Object.keys(e.hooks).length>0&&(s.hooks=e.hooks)}catch{console.warn(` ⚠ Failed to generate hooks block`)}y(r,`${JSON.stringify(s,null,2)}\n`,`utf-8`),console.log(` Updated ${r} — default agent + hooks`)}const L={scaffoldDir:`general`,writeMcpConfig(e,t){I(t);let n=S(e,`.mcp.json`);h(n)||(y(n,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,t){let n=S(e,`CLAUDE.md`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},R={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.cursor`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .cursor/mcp.json`))},writeInstructions(e,t){let n=S(e,`.cursor`,`rules`),r=S(n,`aikit.mdc`);g(n,{recursive:!0});let i=b(e);y(r,`${l(i,t)}\n---\n\n${p(i,t)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let a=S(n,`kb.mdc`);h(a)&&a!==r&&(v(a),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},z={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,t){let n=S(e,`.windsurfrules`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}},B={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.zed`),r=S(n,`settings.json`);if(g(n,{recursive:!0}),!h(r))y(r,`${JSON.stringify(j(t),null,2)}\n`,`utf-8`),console.log(` Created .zed/settings.json`);else{let e;try{e=JSON.parse(_(r,`utf-8`))}catch{console.warn(` ⚠ .zed/settings.json contains invalid JSON — skipping MCP config merge`);return}e.context_servers?.[t]||(e.context_servers={...e.context_servers,...j(t).context_servers},y(r,`${JSON.stringify(e,null,2)}\n`,`utf-8`),console.log(` Updated .zed/settings.json with context_servers`))}},writeInstructions(e,t){let n=S(e,`.rules`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated .rules`)},writeAgentsMd(e,t){}},V={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`mcp.json`);h(n)||(y(n,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created mcp.json`))},writeInstructions(e,t){let n=S(e,`.aiassistant`,`rules`),r=S(n,`aikit.md`);g(n,{recursive:!0});let i=b(e);y(r,`${l(i,t)}\n---\n\n${p(i,t)}`,`utf-8`),console.log(` Updated .aiassistant/rules/aikit.md`)},writeAgentsMd(e,t){}},H={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.opencode`),r=S(n,`opencode.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(M(t),null,2)}\n`,`utf-8`),console.log(` Created .opencode/opencode.json`))},writeInstructions(e,t){let n=S(e,`OPENCODE.md`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated OPENCODE.md`)},writeAgentsMd(e,t){}},U={scaffoldDir:`general`,writeMcpConfig(e,t){},writeInstructions(e,t){let n=S(e,`AGENTS.md`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated AGENTS.md (Hermes)`)},writeAgentsMd(e,t){}};function W(e){switch(e){case`copilot`:return N;case`claude-code`:return L;case`cursor`:return R;case`windsurf`:return z;case`zed`:return B;case`intellij`:return V;case`opencode`:return H;case`hermes`:return U;case`gemini-cli`:case`codex-cli`:return N}}const G={serverName:s,sources:[{path:`.`,excludePatterns:[`**/node_modules/**`,`**/dist/**`,`**/build/**`,`**/.git/**`,`**/${w.data}/**`,`**/coverage/**`,`**/*.min.js`,`**/package-lock.json`,`**/pnpm-lock.yaml`]}],indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:T.model,dimensions:T.dimensions},store:{backend:`sqlite-vec`,path:w.data},curated:{path:w.aiCurated}};function K(e,t){let n=S(e,`aikit.config.json`);return h(n)&&!t?(console.log(`aikit.config.json already exists. Use --force to overwrite.`),!1):(y(n,`${JSON.stringify(G,null,2)}\n`,`utf-8`),console.log(` Created aikit.config.json`),!0)}function q(e){let t=S(e,`.gitignore`),n=[{dir:`.flows/`,label:`AI Kit flow runs`}];if(h(t)){let e=_(t,`utf-8`),r=n.filter(t=>!e.includes(t.dir));r.length>0&&(m(t,`\n${r.map(e=>`# ${e.label}\n${e.dir}`).join(`
1
+ import{c as e,l as t,n,o as r,r as i,t as a}from"./scaffold-BNPHP-QC.js";import{_ as o,c as s,l as c,n as l,o as u,r as d,s as f,t as p}from"./templates-Bu7dZtk_.js";import{appendFileSync as m,existsSync as h,mkdirSync as g,readFileSync as _,unlinkSync as v,writeFileSync as y}from"node:fs";import{basename as b,dirname as x,resolve as S}from"node:path";import{homedir as C}from"node:os";import{AIKIT_PATHS as w,EMBEDDING_DEFAULTS as T,isUserInstalled as E}from"../../core/dist/index.js";function D(e){return h(S(e,`.cursor`))?`cursor`:h(S(e,`.claude`))?`claude-code`:h(S(e,`.windsurf`))?`windsurf`:h(S(e,`.zed`))?`zed`:h(S(e,`.idea`))?`intellij`:h(S(e,`.opencode`))?`opencode`:h(S(e,`AGENTS.md`))?`hermes`:`copilot`}function O(e){let t=[];return h(S(e,`.cursor`))&&t.push(`cursor`),(h(S(e,`.claude`))||h(S(e,`CLAUDE.md`)))&&t.push(`claude-code`),h(S(e,`.windsurf`))&&t.push(`windsurf`),h(S(e,`.zed`))&&t.push(`zed`),h(S(e,`.idea`))&&t.push(`intellij`),h(S(e,`.gemini`))&&t.push(`gemini-cli`),(h(S(e,`.codex`))||h(S(e,`codex.md`)))&&t.push(`codex-cli`),(h(S(e,`.opencode`))||h(S(e,`OPENCODE.md`)))&&t.push(`opencode`),t.push(`copilot`),t.push(`hermes`),[...new Set(t)]}function k(e){return{servers:{[e]:{...f}}}}function A(e){let{type:t,...n}=f;return{mcpServers:{[e]:n}}}function j(e){let{type:t,...n}=f;return{context_servers:{[e]:{...n}}}}function M(e){let{type:t,...n}=f;return{mcp:{[e]:{type:`local`,command:[n.command,...n.args]}}}}const N={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json`))},writeInstructions(e,t){let n=S(e,`.github`),r=S(n,`copilot-instructions.md`);g(n,{recursive:!0}),y(r,l(b(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,t){y(S(e,`AGENTS.md`),p(b(e),t),`utf-8`),console.log(` Updated AGENTS.md`)}},P=`Orchestrator`;function F(e){let{command:t,args:n}=f;return{[e]:{command:t,args:[...n],type:`stdio`,env:{}}}}function I(e,t){let n=t??S(C(),`.claude`),r=S(n,`settings.json`),i=S(n,`..`,`.claude.json`),a=F(e),o;if(!h(i))o={};else try{o=JSON.parse(_(i,`utf-8`))}catch{console.warn(` ⚠ ${i} invalid JSON — overwriting`),o={}}g(x(i),{recursive:!0}),o.mcpServers={...o.mcpServers||{},...a},y(i,`${JSON.stringify(o,null,2)}\n`,`utf-8`),console.log(` Updated ${i} — ${e} MCP server`);let s;if(!h(r))g(n,{recursive:!0}),s={agent:P};else{try{s=JSON.parse(_(r,`utf-8`))}catch{console.warn(` ⚠ ${r} invalid JSON — overwriting`),s={}}delete s.mcpServers}s.agent=P;let c=S(n,`hooks`,`scripts`).replace(/\\/g,`/`);try{let e=d(`claude`,c);e.hooks&&Object.keys(e.hooks).length>0&&(s.hooks=e.hooks)}catch{console.warn(` ⚠ Failed to generate hooks block`)}y(r,`${JSON.stringify(s,null,2)}\n`,`utf-8`),console.log(` Updated ${r} — default agent + hooks`)}const L={scaffoldDir:`general`,writeMcpConfig(e,t){I(t);let n=S(e,`.mcp.json`);h(n)||(y(n,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,t){let n=S(e,`CLAUDE.md`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},R={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.cursor`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created .cursor/mcp.json`))},writeInstructions(e,t){let n=S(e,`.cursor`,`rules`),r=S(n,`aikit.mdc`);g(n,{recursive:!0});let i=b(e);y(r,`${l(i,t)}\n---\n\n${p(i,t)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let a=S(n,`kb.mdc`);h(a)&&a!==r&&(v(a),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},z={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(k(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,t){let n=S(e,`.windsurfrules`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}},B={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.zed`),r=S(n,`settings.json`);if(g(n,{recursive:!0}),!h(r))y(r,`${JSON.stringify(j(t),null,2)}\n`,`utf-8`),console.log(` Created .zed/settings.json`);else{let e;try{e=JSON.parse(_(r,`utf-8`))}catch{console.warn(` ⚠ .zed/settings.json contains invalid JSON — skipping MCP config merge`);return}e.context_servers?.[t]||(e.context_servers={...e.context_servers,...j(t).context_servers},y(r,`${JSON.stringify(e,null,2)}\n`,`utf-8`),console.log(` Updated .zed/settings.json with context_servers`))}},writeInstructions(e,t){let n=S(e,`.rules`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated .rules`)},writeAgentsMd(e,t){}},V={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`mcp.json`);h(n)||(y(n,`${JSON.stringify(A(t),null,2)}\n`,`utf-8`),console.log(` Created mcp.json`))},writeInstructions(e,t){let n=S(e,`.aiassistant`,`rules`),r=S(n,`aikit.md`);g(n,{recursive:!0});let i=b(e);y(r,`${l(i,t)}\n---\n\n${p(i,t)}`,`utf-8`),console.log(` Updated .aiassistant/rules/aikit.md`)},writeAgentsMd(e,t){}},H={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.opencode`),r=S(n,`opencode.json`);h(r)||(g(n,{recursive:!0}),y(r,`${JSON.stringify(M(t),null,2)}\n`,`utf-8`),console.log(` Created .opencode/opencode.json`))},writeInstructions(e,t){let n=S(e,`OPENCODE.md`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated OPENCODE.md`)},writeAgentsMd(e,t){}},U={scaffoldDir:`general`,writeMcpConfig(e,t){},writeInstructions(e,t){let n=S(e,`AGENTS.md`),r=b(e);y(n,`${l(r,t)}\n---\n\n${p(r,t)}`,`utf-8`),console.log(` Updated AGENTS.md (Hermes)`)},writeAgentsMd(e,t){}};function W(e){switch(e){case`copilot`:return N;case`claude-code`:return L;case`cursor`:return R;case`windsurf`:return z;case`zed`:return B;case`intellij`:return V;case`opencode`:return H;case`hermes`:return U;case`gemini-cli`:case`codex-cli`:return N}}const G={serverName:s,sources:[{path:`.`,excludePatterns:[`**/node_modules/**`,`**/dist/**`,`**/build/**`,`**/.git/**`,`**/${w.data}/**`,`**/coverage/**`,`**/*.min.js`,`**/package-lock.json`,`**/pnpm-lock.yaml`]}],indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:T.model,dimensions:T.dimensions},store:{backend:`sqlite-vec`,path:w.data},curated:{path:w.aiCurated}};function K(e,t){let n=S(e,`aikit.config.json`);return h(n)&&!t?(console.log(`aikit.config.json already exists. Use --force to overwrite.`),!1):(y(n,`${JSON.stringify(G,null,2)}\n`,`utf-8`),console.log(` Created aikit.config.json`),!0)}function q(e){let t=S(e,`.gitignore`),n=[{dir:`.flows/`,label:`AI Kit flow runs`}];if(h(t)){let e=_(t,`utf-8`),r=n.filter(t=>!e.includes(t.dir));r.length>0&&(m(t,`\n${r.map(e=>`# ${e.label}\n${e.dir}`).join(`
2
2
  `)}\n`,`utf-8`),console.log(` Added ${r.map(e=>e.dir).join(`, `)} to .gitignore`))}else y(t,`${n.map(e=>`# ${e.label}\n${e.dir}`).join(`
3
3
  `)}\n`,`utf-8`),console.log(` Created .gitignore with AI Kit entries`)}function J(){return G.serverName}const Y=[`decisions`,`patterns`,`conventions`,`troubleshooting`];function X(e){let t=S(e,`.ai`,`curated`);h(t)||(g(t,{recursive:!0}),console.log(` Created .ai/curated/`));for(let e of Y){let n=S(t,e);h(n)||g(n,{recursive:!0})}console.log(` Created .ai/curated/{${Y.join(`,`)}}/`)}function Z(e){switch(e){case`zed`:return`zed`;case`intellij`:return`intellij`;case`claude-code`:return`claude-code`;case`gemini-cli`:return`gemini`;case`codex-cli`:return`codex`;case`opencode`:return`opencode`;case`hermes`:return`hermes`;default:return`copilot`}}async function Q(n){let i=process.cwd();if(S(i)===S(C())){console.log(` Skipping workspace init: cannot scaffold the home directory.`),console.log(" Use `aikit init` (without --workspace) for user-level setup.");return}if(!K(i,n.force))return;q(i);let a=J(),s=W(D(i));s.writeMcpConfig(i,a),s.writeInstructions(i,a),s.writeAgentsMd(i,a);let l=o(),d=JSON.parse(_(S(l,`package.json`),`utf-8`)).version;await t(i,l,[...c],d,n.force),await r(i,l,[...u],d,n.force);let f=O(i),p=new Set;for(let t of f){let r=Z(t);p.has(r)||(p.add(r),await e(i,l,r,d,n.force))}X(i),console.log(`
4
4
  AI Kit initialized! Next steps:`),console.log(` aikit reindex Index your codebase`),console.log(` aikit search Search indexed content`),console.log(` aikit serve Start MCP server for IDE integration`),E()&&console.log(`
@@ -2,7 +2,7 @@ import{createRequire as e}from"node:module";import{readFileSync as t}from"node:f
2
2
  `))console.log(` ${e}`)}}function S(e){console.log(e.id),console.log(` Command: ${e.command}${e.args.length>0?` ${e.args.join(` `)}`:``}`),console.log(` PID: ${e.pid??`unknown`}`),console.log(` Status: ${e.status}`),console.log(` Started: ${e.startedAt}`),e.exitCode!==void 0&&console.log(` Exit code: ${e.exitCode}`),console.log(` Logs: ${e.logs.length}`)}function C(e){if(console.log(`Exports scanned: ${e.totalExports}`),console.log(`Dead in source: ${e.totalDeadSource} (actionable)`),console.log(`Dead in docs: ${e.totalDeadDocs} (informational)`),e.totalDeadSource===0&&e.totalDeadDocs===0){console.log(`No dead symbols found.`);return}if(e.deadInSource.length>0){console.log(`
3
3
  Dead in source (actionable):`);for(let t of e.deadInSource)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}if(e.deadInDocs.length>0){console.log(`
4
4
  Dead in docs (informational):`);for(let t of e.deadInDocs)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}}function w(e){console.log(e.path),console.log(` Language: ${e.language}`),console.log(` Lines: ${e.lines}`),console.log(` Estimated tokens: ~${e.estimatedTokens}`),console.log(``),O(`Imports`,e.imports),O(`Exports`,e.exports),O(`Functions`,e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}`)),O(`Classes`,e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}`)),O(`Interfaces`,e.interfaces.map(e=>`${e.name} @ line ${e.line}`)),O(`Types`,e.types.map(e=>`${e.name} @ line ${e.line}`))}function T(e){if(console.log(`Symbol: ${e.name}`),e.definedIn?console.log(`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`):console.log(`Defined in: not found`),console.log(``),console.log(`Imported by:`),e.importedBy.length===0)console.log(` none`);else for(let t of e.importedBy)console.log(` - ${t.path}:${t.line} ${t.importStatement}`);if(console.log(``),console.log(`Referenced in:`),e.referencedIn.length===0)console.log(` none`);else for(let t of e.referencedIn)console.log(` - ${t.path}:${t.line} ${t.context}`)}function E(e){console.log(e.name),console.log(` Files: ${e.files.length}`),console.log(` Updated: ${e.updated}`),e.description&&console.log(` Description: ${e.description}`);for(let t of e.files)console.log(` - ${t}`)}function D(e){let t=Array.isArray(e.data.files)?e.data.files.filter(e=>typeof e==`string`):[];if(console.log(e.id),console.log(` Label: ${e.label}`),console.log(` Created: ${e.createdAt}`),e.notes&&console.log(` Notes: ${e.notes}`),t.length>0){console.log(` Files: ${t.length}`);for(let e of t)console.log(` - ${e}`)}console.log(` Data:`);for(let t of JSON.stringify(e.data,null,2).split(`
5
- `))console.log(` ${t}`)}function O(e,t){if(console.log(`${e}:`),t.length===0){console.log(` none`),console.log(``);return}for(let e of t)console.log(` - ${e}`);console.log(``)}function k(e){let t=e.trim();if(!t)return``;try{return JSON.parse(t)}catch{return e}}function A(e){let t=e.trim();if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Checkpoint data must be a JSON object.`);return n}function j(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score)}const M=[`const{spawn:s}=require('child_process')`,`const{existsSync:e,readFileSync:r}=require('fs')`,`const{join:j}=require('path')`,`const{homedir:h}=require('os')`,`const n=process.env.NODE_OPTIONS||'';if(!n.includes('ExperimentalWarning'))process.env.NODE_OPTIONS=n?(n+' --disable-warning=ExperimentalWarning'):'--disable-warning=ExperimentalWarning'`,`const l=(c,a,o={})=>{const p=s(c,a,{stdio:'inherit',env:process.env,...o});p.once('error',q=>{try{process.stderr.write('aikit: failed to start MCP server - '+q.message)}catch{}process.exit(1)});p.once('exit',(q,g)=>process.exit(g==='SIGINT'?130:g==='SIGTERM'?143:(q??1)));for(const g of ['SIGINT','SIGTERM'])process.once(g,()=>{if(!p.killed)p.kill(g)})}`,`const f=j(h(),'.aikit','current-version.json');if(e(f)){try{const{version:g}=JSON.parse(r(f,'utf-8'));const p=j(h(),'.aikit','versions','v'+g,'packages','server','dist','bin.js');if(!e(p))throw Error('Local install not found at '+p);l(process.execPath,[p,'serve'])}catch(c){try{process.stderr.write('aikit: local install failed - '+c.message+'. Run: aikit install')}catch{}process.exit(1)}}else{const c=process.platform==='win32'?'npx.cmd':'npx';l(c,['-y','@vpxa/aikit@latest','serve'],process.platform==='win32'?{shell:true}:{})}`].join(`;`),N=`aikit`,P={type:`stdio`,command:`node`,args:[`-e`,M]},F=[`aikit`,`brainstorming`,`multi-agents-development`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`,`present`,`frontend-design`,`react`,`typescript`,`docs`,`repo-access`],I=[`aikit-basic`,`aikit-advanced`,`_epilogue`],L={"chat.agentFilesLocations":{"~/.claude/agents":!1},"chat.useClaudeMdFile":!1,"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0,"workbench.browser.enableChatTools":!0,"chat.mcp.apps.enabled":!0,"chat.instructionsFilesLocations":{"~/.copilot/instructions":!0,".github/instructions":!0,".claude/rules":!1,"~/.claude/rules":!1}},R=[`copilot`,`claude`,`copilotCli`,`hermes`],z={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`}},B={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`]}},V={"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`}},de={PreCompact:3e3,PostToolUse:3e3},H={copilot:`hooks.json`,copilotCli:`hooks.json`,hermes:`hooks.json`},U=R;function W(e){if(!U.includes(e))throw Error(`Unknown platform: "${e}". Supported: ${U.join(`, `)}. Add it to SUPPORTED_PLATFORMS in exec-hooks.mjs first, then add entries to HOOK_EVENTS and HOOK_TOOL_MATCHERS. Add FILE_NAMES in generateHooks if file-producing.`);for(let[t,n]of Object.entries(z))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(B))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.`)}function fe(e,t){return(e.matcher||[]).flatMap(e=>{let n=B[e];if(!n)throw Error(`Unknown hook matcher: ${e}`);return n[t]||[]})}function G(e,t,n,r){let i=`${n}/${e.script}`;return fe(e,r),r===`copilot`?{event:t,steps:[{type:`command`,command:`node`,args:[i],timeout:de[e.event]||5e3}]}:r===`claude`?{type:`command`,command:`node ${i}`}:{command:`node`,args:[i]}}function pe(e,t){W(e);let n={};for(let r of Object.values(V)){let i=z[r.event]?.[e];if(!i){console.warn(`[aikit] Unsupported hook event ${r.event} for ${e} — skipping`);continue}n[i]||=[],n[i].push(G(r,i,t,e))}return{hooks:n}}function me(e,t){if(W(e),e===`copilot`){let n=Object.values(V).flatMap(n=>{let r=z[n.event]?.[e];return r?G(n,r,t,e):(console.warn(`[aikit] Unsupported hook event ${n.event} for ${e} — skipping`),[])});return[{path:H[e],content:JSON.stringify({hooks:n},null,2)}]}if(e===`claude`)return[];if(!(e in H))throw Error(`Platform "${e}" is missing from FILE_NAMES. Add "${e}: '<filename>'" to FILE_NAMES in adapters/hooks.mjs.`);let n={};for(let r of Object.values(V)){let i=z[r.event]?.[e];if(!i){console.warn(`[aikit] Unsupported hook event ${r.event} for ${e} — skipping`);continue}n[i]||=[],n[i].push(G(r,i,t,e))}return[{path:H[e],content:JSON.stringify({hooks:n},null,2)}]}function he(){return[`_runtime.mjs`,...Object.values(V).map(e=>e.script)]}const ge=[{id:`no-grep-search`,toolName:`grep_search`,description:`grep_search / semantic_search → use search`,alternative:`search({ query })`,reason:`Hybrid search across all indexed + curated content — richer results than grep`,severity:`error`,action:`redirect`},{id:`no-semantic-search`,toolName:`semantic_search`,description:`semantic_search → use search`,alternative:`search({ query })`,reason:`Hybrid search across all indexed + curated content — vector + FTS fusion`,severity:`error`,action:`redirect`},{id:`no-grep-symbol`,toolName:`grep_search`,description:`grep_search for a symbol → use symbol`,alternative:`symbol({ name })`,reason:`Definition + references with scope and call context`,severity:`error`,action:`redirect`,heuristic:`grep_search for a specific symbol name`},{id:`no-read-file-understanding`,toolName:`read_file`,description:`read_file to understand a file → use file_summary`,alternative:`file_summary({ path })`,reason:`Structure, exports, imports — 10x fewer tokens than raw file reads`,severity:`error`,action:`warn`,heuristic:`read_file with range > 50 lines and no subsequent edit`},{id:`no-read-file-find-code`,toolName:`read_file`,description:`read_file to find specific code → use compact`,alternative:`compact({ path, query })`,reason:`Fresh compression: compact({ path, query }); query is required unless ref is supplied`,severity:`error`,action:`warn`,heuristic:`read_file to locate specific code without editing`},{id:`no-read-file-multiple`,toolName:`read_file`,description:`Multiple read_file calls → use digest`,alternative:`digest({ sources, query: "<task description>" })`,reason:`Compresses multiple files into token-budgeted summary`,severity:`error`,action:`warn`,heuristic:`consecutive read_file calls on different files without edits`},{id:`no-read-file-large`,toolName:`read_file`,description:`read_file (>50 lines to understand) → use file_summary → compact → digest`,alternative:`file_summary → compact → digest`,reason:`Use compressed context, not raw reads — 10x fewer tokens`,severity:`warning`,action:`warn`,heuristic:`read_file with endLine - startLine > 50 and no subsequent edit on same file`},{id:`no-ctxc-misuse`,toolName:`compact`,description:`Cached ctxc ref to refocus prior output → use compact with ref`,alternative:`compact({ ref }) or compact({ ref, query? })`,reason:`ctxc_... values are reversible refs, not ids or file paths. Prefer enrich: true on follow-up retrieval`,severity:`error`,action:`warn`,heuristic:`using ctxc_ value as a file path instead of as a ref`},{id:`no-terminal-test`,toolName:`run_in_terminal`,description:`run_in_terminal for tests → use test_run`,alternative:`test_run({})`,reason:`Run tests with structured output — no shell needed`,severity:`error`,action:`redirect`,commandPatterns:[`vitest`,`jest`,`mocha`,`pnpm test`,`npm test`]},{id:`no-terminal-typecheck`,toolName:`run_in_terminal`,description:`run_in_terminal for tsc/lint → use check`,alternative:`check({})`,reason:`Typecheck + lint combined, summary output — no shell needed`,severity:`error`,action:`redirect`,commandPatterns:[`\\btsc\\b`,`pnpm check`,`pnpm typecheck`,`pnpm lint`,`biome`]},{id:`no-terminal-grep`,toolName:`run_in_terminal`,description:`run_in_terminal for find/grep → use find or search`,alternative:`find({ pattern }) or search({ query })`,reason:`No shell needed, richer results with AI Kit search`,severity:`error`,action:`redirect`,commandPatterns:[`\\bgrep\\b`,`\\bfind\\b`,`\\brg\\b`,`Select-String`]},{id:`no-terminal-code-edits`,toolName:`run_in_terminal`,description:`run_in_terminal for code edits → use replace_string_in_file`,alternative:`replace_string_in_file`,reason:`Avoid shell-edit loops; use native edit tool instead`,severity:`error`,action:`redirect`,commandPatterns:[`sed`,`awk`,`Set-Content`,`Out-File`,`>>`,`\\| tee`]},{id:`no-edit-without-reading`,toolName:`replace_string_in_file`,description:`Editing without reading → use file_summary then targeted read_file`,alternative:`file_summary({ path }) → read_file({ path, offset, limit })`,reason:`Safer edits: understand structure before modifying`,severity:`error`,action:`warn`,heuristic:`replace_string_in_file on a file not previously read`},{id:`no-get-changed-files`,toolName:`get_changed_files`,description:`get_changed_files → use run_in_terminal with git diff`,alternative:"run_in_terminal with `git diff <specific-file>`",reason:`Diff only target file instead of all uncommitted diffs (100K+ tokens)`,severity:`error`,action:`redirect`},{id:`no-fetch-webpage`,toolName:`fetch_webpage`,description:`fetch_webpage → use web_fetch`,alternative:`web_fetch({ url })`,reason:`Readability extract + token budget — richer output than raw fetch`,severity:`error`,action:`redirect`},{id:`no-subagent-present`,toolName:`present`,description:`present (from subagent) → return structured text`,alternative:`Return findings as structured text`,reason:`Subagent present calls are invisible to the user (only Orchestrator should present)`,severity:`error`,action:`warn`,heuristic:`present called in subagent context`},{id:`no-apply-patch`,toolName:`apply_patch`,description:`apply_patch → use native edit tool`,alternative:`edit file tool`,reason:`AI Kit does not manage apply_patch; use the host environment edit tool`,severity:`warning`,action:`warn`},{id:`no-memory-native`,toolName:`memory`,description:`memory tool → use knowledge tool`,alternative:`knowledge (remember / search / list)`,reason:`AI Kit knowledge tool provides persistent cross-session memory with categories and tags`,severity:`warning`,action:`warn`}];function _e(e){let t=e.toolName;if(e.commandPatterns&&e.commandPatterns.length>0){let n=e.description.match(/^(.*?)\s*→/);n&&(t=n[1].trim())}else if(e.heuristic){let n=e.description.match(/^(.*?)\s*→/);n&&(t=n[1].trim())}return{id:e.id,forbidden:t,alternative:e.alternative,severity:e.severity,reason:e.reason,matchPattern:e.commandPatterns?null:e.toolName,commandPatterns:e.commandPatterns??null,heuristic:e.heuristic??null}}const ve=ge.map(_e);function ye(){return[`| NEVER use this | USE THIS AI Kit TOOL INSTEAD | Why |`,`|---|---|---|`,...ve.filter(e=>e.severity===`error`).map(e=>`| \`${e.forbidden}\` | \`${e.alternative}\` | ${e.reason} |`)].join(`
5
+ `))console.log(` ${t}`)}function O(e,t){if(console.log(`${e}:`),t.length===0){console.log(` none`),console.log(``);return}for(let e of t)console.log(` - ${e}`);console.log(``)}function k(e){let t=e.trim();if(!t)return``;try{return JSON.parse(t)}catch{return e}}function A(e){let t=e.trim();if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Checkpoint data must be a JSON object.`);return n}function j(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score)}const M=[`const{spawn:s}=require('child_process')`,`const{existsSync:e,readFileSync:r}=require('fs')`,`const{join:j}=require('path')`,`const{homedir:h}=require('os')`,`const n=process.env.NODE_OPTIONS||'';if(!n.includes('ExperimentalWarning'))process.env.NODE_OPTIONS=n?(n+' --disable-warning=ExperimentalWarning'):'--disable-warning=ExperimentalWarning'`,`const l=(c,a,o={})=>{const p=s(c,a,{stdio:'inherit',env:process.env,...o});p.once('error',q=>{try{process.stderr.write('aikit: failed to start MCP server - '+q.message)}catch{}process.exit(1)});p.once('exit',(q,g)=>process.exit(g==='SIGINT'?130:g==='SIGTERM'?143:(q??1)));for(const g of ['SIGINT','SIGTERM'])process.once(g,()=>{if(!p.killed)p.kill(g)})}`,`const f=j(h(),'.aikit','current-version.json');if(e(f)){try{const{version:g}=JSON.parse(r(f,'utf-8'));const p=j(h(),'.aikit','versions','v'+g,'packages','server','dist','bin.js');if(!e(p))throw Error('Local install not found at '+p);l(process.execPath,[p,'serve'])}catch(c){try{process.stderr.write('aikit: local install failed - '+c.message+'. Run: aikit install')}catch{}process.exit(1)}}else{const c=process.platform==='win32'?'npx.cmd':'npx';l(c,['-y','@vpxa/aikit@latest','serve'],process.platform==='win32'?{shell:true}:{})}`].join(`;`),N=`aikit`,P={type:`stdio`,command:`node`,args:[`-e`,M]},F=[`aikit`,`brainstorming`,`multi-agents-development`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`,`present`,`frontend-design`,`react`,`typescript`,`docs`,`repo-access`],I=[`aikit-basic`,`aikit-advanced`,`_epilogue`],L={"chat.agentFilesLocations":{"~/.claude/agents":!1},"chat.useClaudeMdFile":!1,"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0,"workbench.browser.enableChatTools":!0,"chat.mcp.apps.enabled":!0,"chat.instructionsFilesLocations":{"~/.copilot/instructions":!0,".github/instructions":!0,".claude/rules":!1,"~/.claude/rules":!1}},R=[`copilot`,`claude`,`copilotCli`,`hermes`],z={SessionStart:{copilot:`SessionStart`,claude:`SessionStart`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolUse`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolUse`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`SubagentStart`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreCompact`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`Stop`,copilotCli:`stop`,hermes:`Stop`}},B={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`]}},V={"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`}},de={PreCompact:3e3,PostToolUse:3e3},H={copilot:`hooks.json`,copilotCli:`hooks.json`,hermes:`hooks.json`},U=R;function W(e){if(!U.includes(e))throw Error(`Unknown platform: "${e}". Supported: ${U.join(`, `)}. Add it to SUPPORTED_PLATFORMS in exec-hooks.mjs first, then add entries to HOOK_EVENTS and HOOK_TOOL_MATCHERS. Add FILE_NAMES in generateHooks if file-producing.`);for(let[t,n]of Object.entries(z))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(B))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.`)}function fe(e,t){return(e.matcher||[]).flatMap(e=>{let n=B[e];if(!n)throw Error(`Unknown hook matcher: ${e}`);return n[t]||[]})}function G(e,t,n,r){let i=`${n}/${e.script}`;return fe(e,r),r===`copilot`?{event:t,steps:[{type:`command`,command:`node`,args:[i],timeout:de[e.event]||5e3}]}:r===`claude`?{type:`command`,command:`node ${i}`}:{command:`node`,args:[i]}}function pe(e,t){W(e);let n={};for(let r of Object.values(V)){let i=z[r.event]?.[e];if(!i){console.warn(`[aikit] Unsupported hook event ${r.event} for ${e} — skipping`);continue}n[i]||=[],n[i].push(G(r,i,t,e))}return{hooks:n}}function me(e,t){if(W(e),e===`copilot`){let n=Object.values(V).flatMap(n=>{let r=z[n.event]?.[e];return r?G(n,r,t,e):(console.warn(`[aikit] Unsupported hook event ${n.event} for ${e} — skipping`),[])});return[{path:H[e],content:JSON.stringify({hooks:n},null,2)}]}if(e===`claude`)return[];if(!(e in H))throw Error(`Platform "${e}" is missing from FILE_NAMES. Add "${e}: '<filename>'" to FILE_NAMES in adapters/hooks.mjs.`);let n={};for(let r of Object.values(V)){let i=z[r.event]?.[e];if(!i){console.warn(`[aikit] Unsupported hook event ${r.event} for ${e} — skipping`);continue}n[i]||=[],n[i].push(G(r,i,t,e))}return[{path:H[e],content:JSON.stringify({hooks:n},null,2)}]}function he(){return[`_runtime.mjs`,...Object.values(V).map(e=>e.script)]}const ge=[{id:`no-grep-search`,toolName:`grep_search`,description:`grep_search / semantic_search → use search`,alternative:`search({ query })`,reason:`Hybrid search across all indexed + curated content — richer results than grep`,severity:`error`,action:`redirect`},{id:`no-semantic-search`,toolName:`semantic_search`,description:`semantic_search → use search`,alternative:`search({ query })`,reason:`Hybrid search across all indexed + curated content — vector + FTS fusion`,severity:`error`,action:`redirect`},{id:`no-grep-symbol`,toolName:`grep_search`,description:`grep_search for a symbol → use symbol`,alternative:`symbol({ name })`,reason:`Definition + references with scope and call context`,severity:`error`,action:`redirect`,heuristic:`grep_search for a specific symbol name`},{id:`no-read-file-understanding`,toolName:`read_file`,description:`read_file to understand a file → use file_summary`,alternative:`file_summary({ path })`,reason:`Structure, exports, imports — 10x fewer tokens than raw file reads`,severity:`error`,action:`warn`,heuristic:`read_file with range > 50 lines and no subsequent edit`},{id:`no-read-file-find-code`,toolName:`read_file`,description:`read_file to find specific code → use compact`,alternative:`compact({ path, query })`,reason:`Fresh compression: compact({ path, query }); query is required unless ref is supplied`,severity:`error`,action:`warn`,heuristic:`read_file to locate specific code without editing`},{id:`no-read-file-multiple`,toolName:`read_file`,description:`Multiple read_file calls → use digest`,alternative:`digest({ sources, query: "<task description>" })`,reason:`Compresses multiple files into token-budgeted summary`,severity:`error`,action:`warn`,heuristic:`consecutive read_file calls on different files without edits`},{id:`no-read-file-large`,toolName:`read_file`,description:`read_file (>50 lines to understand) → use file_summary → compact → digest`,alternative:`file_summary → compact → digest`,reason:`Use compressed context, not raw reads — 10x fewer tokens`,severity:`warning`,action:`warn`,heuristic:`read_file with endLine - startLine > 50 and no subsequent edit on same file`},{id:`no-ctxc-misuse`,toolName:`compact`,description:`Cached ctxc ref to refocus prior output → use compact with ref`,alternative:`compact({ ref }) or compact({ ref, query? })`,reason:`ctxc_... values are reversible refs, not ids or file paths. Prefer enrich: true on follow-up retrieval`,severity:`error`,action:`warn`,heuristic:`using ctxc_ value as a file path instead of as a ref`},{id:`no-terminal-test`,toolName:`run_in_terminal`,description:`run_in_terminal for tests → use test_run`,alternative:`test_run({})`,reason:`Run tests with structured output — no shell needed`,severity:`error`,action:`redirect`,commandPatterns:[`vitest`,`jest`,`mocha`,`pnpm test`,`npm test`]},{id:`no-terminal-typecheck`,toolName:`run_in_terminal`,description:`run_in_terminal for tsc/lint → use check`,alternative:`check({})`,reason:`Typecheck + lint combined, summary output — no shell needed`,severity:`error`,action:`redirect`,commandPatterns:[`\\btsc\\b`,`pnpm check`,`pnpm typecheck`,`pnpm lint`,`biome`]},{id:`no-terminal-grep`,toolName:`run_in_terminal`,description:`run_in_terminal for find/grep → use find or search`,alternative:`find({ pattern }) or search({ query })`,reason:`No shell needed, richer results with AI Kit search`,severity:`error`,action:`redirect`,commandPatterns:[`\\bgrep\\b`,`\\bfind\\b`,`\\brg\\b`,`Select-String`]},{id:`no-terminal-code-edits`,toolName:`run_in_terminal`,description:`run_in_terminal for code edits → use replace_string_in_file`,alternative:`replace_string_in_file`,reason:`Avoid shell-edit loops; use native edit tool instead`,severity:`error`,action:`redirect`,commandPatterns:[`sed`,`awk`,`Set-Content`,`Out-File`,`>>`,`\\| tee`]},{id:`no-edit-without-reading`,toolName:`replace_string_in_file`,description:`Editing without reading → use file_summary then targeted read_file`,alternative:`file_summary({ path }) → read_file({ path, offset, limit })`,reason:`Safer edits: understand structure before modifying`,severity:`error`,action:`warn`,heuristic:`replace_string_in_file on a file not previously read`},{id:`no-get-changed-files`,toolName:`get_changed_files`,description:`get_changed_files → use run_in_terminal with git diff`,alternative:"run_in_terminal with `git diff <specific-file>`",reason:`Diff only target file instead of all uncommitted diffs (100K+ tokens)`,severity:`error`,action:`redirect`},{id:`no-fetch-webpage`,toolName:`fetch_webpage`,description:`fetch_webpage → use web_fetch`,alternative:`web_fetch({ url })`,reason:`Readability extract + token budget — richer output than raw fetch`,severity:`error`,action:`redirect`},{id:`no-subagent-present`,toolName:`present`,description:`present (from subagent) → return structured text`,alternative:`Return findings as structured text`,reason:`Subagent present calls are invisible to the user (only Orchestrator should present)`,severity:`error`,action:`warn`,heuristic:`present called in subagent context`},{id:`no-apply-patch`,toolName:`apply_patch`,description:`apply_patch → use native edit tool`,alternative:`edit file tool`,reason:`AI Kit does not manage apply_patch; use the host environment edit tool`,severity:`warning`,action:`warn`},{id:`no-memory-native`,toolName:`memory`,description:`memory tool → use knowledge tool`,alternative:`knowledge (remember / search / list)`,reason:`AI Kit knowledge tool provides persistent cross-session memory with categories and tags`,severity:`warning`,action:`warn`}];function _e(e){let t=e.toolName;if(e.commandPatterns&&e.commandPatterns.length>0){let n=e.description.match(/^(.*?)\s*→/);n&&(t=n[1].trim())}else if(e.heuristic){let n=e.description.match(/^(.*?)\s*→/);n&&(t=n[1].trim())}return{id:e.id,forbidden:t,alternative:e.alternative,severity:e.severity,reason:e.reason,matchPattern:e.commandPatterns?null:e.toolName,commandPatterns:e.commandPatterns??null,heuristic:e.heuristic??null}}const ve=ge.map(_e);function ye(){return[`| NEVER use this | USE THIS AI Kit TOOL INSTEAD | Why |`,`|---|---|---|`,...ve.filter(e=>e.severity===`error`).map(e=>`| \`${e.forbidden}\` | \`${e.alternative}\` | ${e.reason} |`)].join(`
6
6
  `)}function K(e){return`
7
7
  ## Flow Context Bootstrap
8
8
 
@@ -105,7 +105,7 @@ No cross-package dependencies detected.`;let s=new Set;for(let e of o.keys()){le
105
105
  ---
106
106
 
107
107
  `)}const tu={ja:{"API Surface":`API サーフェス`,"Type Inventory":`型インベントリ`,"No symbol data available.":`シンボルデータが利用できません。`,"No exported symbols found.":`エクスポートされたシンボルが見つかりませんでした。`,"No exported types/interfaces found.":`エクスポートされた型・インターフェースが見つかりませんでした。`,Contents:`目次`,"Codebase Knowledge":`コードベースナレッジ`},zh:{"API Surface":`API 接口`,"Type Inventory":`类型清单`,"No symbol data available.":`没有可用的符号数据。`,"No exported symbols found.":`未找到导出的符号。`,"No exported types/interfaces found.":`未找到导出的类型/接口。`,Contents:`目录`,"Codebase Knowledge":`代码库知识`},ko:{"API Surface":`API 표면`,"Type Inventory":`타입 인벤토리`,"No symbol data available.":`심볼 데이터를 사용할 수 없습니다.`,"No exported symbols found.":`내보낸 심볼을 찾을 수 없습니다.`,"No exported types/interfaces found.":`내보낸 타입/인터페이스를 찾을 수 없습니다.`,Contents:`목차`,"Codebase Knowledge":`코드베이스 지식`},ru:{"API Surface":`Поверхность API`,"Type Inventory":`Инвентарь типов`,"No symbol data available.":`Нет данных о символах.`,"No exported symbols found.":`Экспортированные символы не найдены.`,"No exported types/interfaces found.":`Экспортированные типы/интерфейсы не найдены.`,Contents:`Содержание`,"Codebase Knowledge":`База знаний кода`}};function J(e,t){if(!t||t===`en`)return e;let n=tu[t];return n?n[e]??e:e}const nu=Se(`tools:onboard:update`);function ru(e){return we(xe(e))}async function iu(e){let t=_(e,`knowledge-graph.json`);if(!F(t))return null;try{let e=await s(t,`utf-8`);return JSON.parse(e)}catch{return null}}async function au(e,t){let n=_(e,`knowledge-graph.json`),r=_(e,`.tmp-graph-${Date.now()}-${Pe(4).toString(`hex`)}.json`);await f(r,JSON.stringify(t,null,2),`utf-8`),await l(r,n)}function ou(e,t){let n=new Map;for(let t of e)n.set(t.id,t);for(let e of t)n.set(e.id,e);return[...n.values()]}function su(e,t,n){let r=e=>`${String(e.source)}|${String(e.target)}|${String(e.relation)}`,i=new Set,a=[];for(let t of e){let e=String(t.source),o=String(t.target);if(n?.has(e)||n?.has(o))continue;let s=r(t);i.has(s)||(i.add(s),a.push(t))}for(let e of t){let t=r(e);i.has(t)||(i.add(t),a.push(e))}return a}function cu(e){let t={},n={},r={};for(let i of e){let e=String(i.type||`unknown`);t[e]=(t[e]||0)+1;let a=String(i.layer||`unknown`);n[a]=(n[a]||0)+1;let o=String(i.domain||`unknown`);r[o]=(r[o]||0)+1}return{byType:t,byLayer:n,byDomain:r}}async function lu(e,t,n,r){let i=Date.now(),{scanCodebase:a}=await Promise.resolve().then(()=>Ou),{buildImportMap:o}=await import(`./import-resolver-nPrVzU5s.js`).then(e=>e.i),c=await a(e),l=new uo(_(ru(e),`cache`)),u=[],d=[],f=new Set;for(let e of r.nodes)String(e.type)===`file`&&f.add(String(e.id));let p=0,m=0,h=c.files.filter(e=>e.category===`source`||e.category===`config`);for(let e of h)try{let t=await s(e.path,`utf-8`),n=U(`sha256`).update(t).digest(`hex`),r=Ds(e.path);if(await l.get(e.path,n)){p++,f.delete(r);continue}m++,u.push({id:r,label:e.path.split(`/`).pop()||e.path,type:`file`,filePath:e.path,confidence:`extracted`,evidence:`Incremental update: ${e.path}`}),await l.set(e.path,n,{path:e.path,size:e.size,category:e.category},e.size,0),f.delete(r)}catch(t){nu.warn(`Failed to process file during incremental update`,{file:e.path,err:t})}if(m>0){let t=await o(e,h),n={next:r.edges.length+1};for(let[e,r]of Object.entries(t)){let t=Ds(e);for(let e of r)if(e.resolvedPath){let r=Ds(e.resolvedPath);d.push({id:As(n.next++),source:t,target:r,relation:`imports`,confidence:`extracted`})}}}let g=ou(r.nodes,u),v=su(r.edges,d,f),y=g.filter(e=>{if(String(e.type)===`file`)return!f.has(String(e.id));if(e.filePath){let t=Ds(String(e.filePath));return!f.has(t)}return!0}),b=new Map;for(let e of v){let t=String(e.source),n=String(e.target);b.set(t,(b.get(t)||0)+1),b.set(n,(b.get(n)||0)+1)}let x=[...b.entries()].sort((e,t)=>t[1]-e[1]).slice(0,10).map(([e,t])=>({id:e,label:y.find(t=>t.id===e)?.label||e,edgeCount:t})),S={extracted:0,inferred:0,ambiguous:0};for(let e of v){let t=String(e.confidence);t===`extracted`?S.extracted++:t===`inferred`?S.inferred++:t===`ambiguous`&&S.ambiguous++}let C=cu(y),w={schema_version:`1.0`,project:{name:n,root:e,files:y.filter(e=>String(e.type)===`file`).length},nodes:y,edges:v,summary:{total_nodes:y.length,total_edges:v.length,god_nodes:x,confidence_distribution:S,clusters:C},metadata:{analyzed_at:new Date().toISOString(),duration_ms:Date.now()-i,version:`1.0`}};return await au(t,w),{unchangedCount:p,changedCount:m,deletedCount:f.size,mergedNodes:y.length,mergedEdges:v.length,graph:w}}const uu={structure:`Project Structure`,dependencies:`Dependencies`,"entry-points":`Entry Points`,symbols:`Symbols`,patterns:`Patterns`,diagram:`C4 Container Diagram`,"code-map":`Code Map (Module Graph)`,"config-values":`Configuration Values`,"synthesis-guide":`Synthesis Guide`};function du(e,t,n,r){let i=[`Analysis baselines for **${n}** have been generated.`];t===`generate`?i.push("Individual results are in the sibling `.md` and `.json` files in this directory.",``):i.push(`Results are stored in the AI Kit vector store.`,``);let a=r.get(`symbols`),o=r.get(`dependencies`),s=r.get(`patterns`),c=r.get(`entry-points`),l=a?.totalCount??0,u=a?.exportedCount??0,d=o?.totalImports??0,f=c?.total??0,p=(s?.patterns??[]).map(e=>e.pattern),m=p.some(e=>e.startsWith(`Spring`)),h=p.includes(`AWS CDK`)||p.includes(`CDK IaC`),g=p.includes(`Maven`),_=p.includes(`Serverless`)||f>3,v=o?.external?Object.keys(o.external):[],y=v.some(e=>[`express`,`fastify`,`next`,`react`,`vitest`,`jest`].includes(e))||d>0,b=v.some(e=>[`turbo`,`lerna`,`nx`].includes(e))||p.includes(`Monorepo`);if(i.push(`### Project Profile`,``),i.push(`- **${l} symbols** (${u} exported), **${d} imports**, **${f} entry ${f===1?`point`:`points`}**`),p.length>0&&i.push(`- **Detected**: ${p.slice(0,8).join(`, `)}`),i.push(``),l===0&&d===0&&f===0)return i.push(`> **Note:** This project appears to be empty or contains no analyzable source code.`,`> Run onboard again after adding source files.`),i.join(`
108
- `);let x=e.filter(e=>e.status===`success`),S=e.filter(e=>e.status===`failed`);i.push(`### Completed Analyses`,``);for(let e of x){let n=uu[e.name]??e.name,r=e.output.length>1e3?`${Math.round(e.output.length/1024)}KB`:`${e.output.length}B`;t===`generate`?i.push(`- ✓ [${n}](./${e.name}.md) (${r})`):i.push(`- ✓ ${n} (${r})`)}if(S.length>0){i.push(``,`### Failed Analyses`,``);for(let e of S)i.push(`- ✗ ${e.name}: ${e.error}`)}i.push(``,`### Recommended Reading Order`,``,"1. **Start with** `synthesis-guide.md` (this file) → `entry-points.md` → `patterns.md`","2. **Module graph** via `code-map.md` — cross-package call edges with function names","3. **Architecture** via `diagram.md` (C4 Container) → `dependencies.md`","4. **Browse structure** via `structure.md` for file layout","5. **API surface** via `symbols.md` — file paths + exported symbols (capped at 80KB)","6. **Reference**: `config-values.md` (config reference)",``,`> **Size guidance:** Total output is ~`);let C=x.reduce((e,t)=>e+t.output.length,0)/1024;return i[i.length-1]+=`${Math.round(C)}KB. Focus on code-map.md + entry-points.md + diagram.md (~${Math.round((x.find(e=>e.name===`code-map`)?.output.length??0)/1024+(x.find(e=>e.name===`entry-points`)?.output.length??0)/1024+(x.find(e=>e.name===`diagram`)?.output.length??0)/1024)}KB) for maximum signal-to-token ratio.`,i.push(``,`### Synthesize Knowledge`,``,'Produce the following `aikit_knowledge` entries with `action: "remember"`:',``),i.push("1. **Architecture Summary** (category: `architecture`)"),b?(i.push(` - Package boundaries, dependency graph between packages`),i.push(` - Shared vs service-specific code`)):_?(i.push(` - Lambda functions, triggers, event flow`),i.push(` - Infrastructure patterns (queues, tables, APIs)`)):m?(i.push(` - Controller → Service → Repository layers`),i.push(` - Spring configuration and profiles`)):(i.push(` - Layer structure, dependency flow`),i.push(` - Key design decisions`)),i.push(``),i.push("2. **Domain Model** (category: `architecture`)"),i.push(` - Key entities/types and their relationships`),i.push(` - Data flow from entry points through processing`),i.push(``),i.push("3. **Conventions** (category: `conventions`)"),i.push(` - Naming patterns, file organization, testing approach`),h&&i.push(` - CDK construct patterns and stack organization`),y&&i.push(` - Build tooling, package manager, module system`),g&&i.push(` - Maven module structure, dependency management`),i.push(``,`### Using AI Kit Tools`,``,`This project has an AI Kit MCP server with tools for search, analysis, memory, and more.`,"`aikit init` has already created `.github/copilot-instructions.md` and `AGENTS.md` with the complete tool reference.","If not, run `npx @vpxa/aikit init` to generate them.",``,`**Workflow pattern — use on every task:**`,``,"```",`aikit_search({ query: "your task keywords" }) # Recall prior decisions`,`aikit_scope_map({ task: "what you are doing" }) # Get a reading plan`,`# ... do the work ...`,`aikit_check({}) # Typecheck + lint`,`aikit_test_run({}) # Run tests`,`aikit_knowledge({ action: "remember", title: "What I learned", category: "decisions" }) # Persist`,"```"),i.join(`
108
+ `);let x=e.filter(e=>e.status===`success`),S=e.filter(e=>e.status===`failed`);i.push(`### Completed Analyses`,``);for(let e of x){let n=uu[e.name]??e.name,r=e.output.length>1e3?`${Math.round(e.output.length/1024)}KB`:`${e.output.length}B`;t===`generate`?i.push(`- ✓ [${n}](./${e.name}.md) (${r})`):i.push(`- ✓ ${n} (${r})`)}if(S.length>0){i.push(``,`### Failed Analyses`,``);for(let e of S)i.push(`- ✗ ${e.name}: ${e.error}`)}i.push(``,`### Recommended Reading Order`,``,"1. **Start with** `synthesis-guide.md` (this file) → `entry-points.md` → `patterns.md`","2. **Module graph** via `code-map.md` — cross-package call edges with function names","3. **Architecture** via `diagram.md` (C4 Container) → `dependencies.md`","4. **Browse structure** via `structure.md` for file layout","5. **API surface** via `symbols.md` — file paths + exported symbols (capped at 80KB)","6. **Reference**: `config-values.md` (config reference)",``,`> **Size guidance:** Total output is ~`);let C=x.reduce((e,t)=>e+t.output.length,0)/1024;return i[i.length-1]+=`${Math.round(C)}KB. Focus on code-map.md + entry-points.md + diagram.md (~${Math.round((x.find(e=>e.name===`code-map`)?.output.length??0)/1024+(x.find(e=>e.name===`entry-points`)?.output.length??0)/1024+(x.find(e=>e.name===`diagram`)?.output.length??0)/1024)}KB) for maximum signal-to-token ratio.`,i.push(``,`### Synthesize Knowledge`,``,'Produce the following `aikit_knowledge` entries with `action: "remember"`:',``),i.push("1. **Architecture Summary** (category: `architecture`)"),b?(i.push(` - Package boundaries, dependency graph between packages`),i.push(` - Shared vs service-specific code`)):_?(i.push(` - Lambda functions, triggers, event flow`),i.push(` - Infrastructure patterns (queues, tables, APIs)`)):m?(i.push(` - Controller → Service → Repository layers`),i.push(` - Spring configuration and profiles`)):(i.push(` - Layer structure, dependency flow`),i.push(` - Key design decisions`)),i.push(``),i.push("2. **Domain Model** (category: `architecture`)"),i.push(` - Key entities/types and their relationships`),i.push(` - Data flow from entry points through processing`),i.push(``),i.push("3. **Conventions** (category: `conventions`)"),i.push(` - Naming patterns, file organization, testing approach`),h&&i.push(` - CDK construct patterns and stack organization`),y&&i.push(` - Build tooling, package manager, module system`),g&&i.push(` - Maven module structure, dependency management`),i.push(``,`### Using AI Kit Tools`,``,`This project has an AI Kit MCP server with tools for search, analysis, memory, and more.`,"`aikit init` has already created `.github/copilot-instructions.md` and `AGENTS.md` with the complete tool reference.","If not, run `npx -y @vpxa/aikit init` to generate them.",``,`**Workflow pattern — use on every task:**`,``,"```",`aikit_search({ query: "your task keywords" }) # Recall prior decisions`,`aikit_scope_map({ task: "what you are doing" }) # Get a reading plan`,`# ... do the work ...`,`aikit_check({}) # Typecheck + lint`,`aikit_test_run({}) # Run tests`,`aikit_knowledge({ action: "remember", title: "What I learned", category: "decisions" }) # Persist`,"```"),i.join(`
109
109
  `)}function fu(e,t,n){let r=e.get(`dependencies`),i=e.get(`symbols`),a=e.get(`entry-points`),o=[`## Code Map: ${t}\n`];if(!r&&!i)return o.push(`No dependency or symbol data available.`),o.join(`
110
110
  `);let s=r?.reverseGraph??{},c=i?.symbols??[],l=a?.entryPoints??[],u=new Map;for(let e of c){if(!e.exported)continue;let t=e.filePath.replace(/\\/g,`/`);if(Zl(t))continue;let n=u.get(t);n?n.push({name:e.name,kind:e.kind}):u.set(t,[{name:e.name,kind:e.kind}])}let d=new Map;for(let[e,t]of Object.entries(s)){let n=$l(e.replace(/\\/g,`/`),u),r=t.map(e=>e.replace(/\\/g,`/`)).filter(e=>!Zl(e));if(r.length===0)continue;let i=d.get(n);if(i)for(let e of r)i.add(e);else d.set(n,new Set(r))}let f=new Map;for(let e of l)f.set(e.filePath.replace(/\\/g,`/`),{name:e.name,trigger:e.trigger});let p=new Map,m=new Map;if(n)for(let[e,t]of n){if(Zl(e))continue;let n=Ql(e);for(let[r,i]of t){if(Zl(r)||n===Ql(r))continue;let t=p.get(e);t||(t=new Map,p.set(e,t)),t.set(r,i);let a=m.get(r),o={file:e,symbols:i};a?a.push(o):m.set(r,[o])}}let h=new Set;for(let e of f.keys())h.add(e);for(let e of p.keys())h.add(e);for(let e of m.keys())h.add(e);if(!n)for(let e of u.keys()){let t=d.get(e);t&&t.size>=3&&h.add(e)}let g=new Map;for(let e of h){let t=Ql(e),n=g.get(t);n?n.push(e):g.set(t,[e])}let _=[...g.entries()].sort((e,t)=>e[0].localeCompare(t[0])),v=n?`AST call graph`:`import analysis`,y=n?`, ${p.size} cross-package callers`:``;o.push(`**${h.size} key modules** (${v}${y})\n`),o.push(`**Legend:** ⚡ Entry point | 📤 Exports | → Calls (outgoing) | ← Called by (incoming) | ➡ Used by (import)
111
111
  `);for(let[e,t]of _){t.sort(),o.push(`### ${e}/\n`);for(let r of t){let t=u.get(r),i=f.get(r),a=p.get(r),s=m.get(r),c=d.get(r),l=r.startsWith(`${e}/`)?r.slice(e.length+1):r;if(o.push(`**${l}**`),i&&o.push(` ⚡ Entry: \`${i.name}\`${i.trigger?` (${i.trigger})`:``}`),t&&t.length>0){let e=t.slice(0,8).map(e=>`${e.name}`).join(`, `),n=t.length>8?` (+${t.length-8})`:``;o.push(` 📤 ${e}${n}`)}if(a&&a.size>0){let t=[...a.entries()].sort((e,t)=>t[1].length-e[1].length);for(let[n,r]of t.slice(0,4)){let t=n.startsWith(`${e}/`)?n.slice(e.length+1):n;o.push(` → ${t}: ${r.slice(0,5).join(`, `)}${r.length>5?`…`:``}`)}t.length>4&&o.push(` → +${t.length-4} more targets`)}if(s&&s.length>0){for(let t of s.slice(0,4)){let n=t.file.startsWith(`${e}/`)?t.file.slice(e.length+1):t.file;o.push(` ← ${n}: ${t.symbols.slice(0,4).join(`, `)}${t.symbols.length>4?`…`:``}`)}s.length>4&&o.push(` ← +${s.length-4} more callers`)}else if(!n&&c&&c.size>0){let e=[...c].filter(e=>!Zl(e));e.length<=3?o.push(` ➡ Used by: ${e.join(`, `)}`):o.push(` ➡ Used by: ${e.slice(0,3).join(`, `)} (+${e.length-3} more)`)}o.push(``)}}return o.join(`
@@ -4,5 +4,5 @@ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from
4
4
  `)}function M(){return[`# aikit — Claude Code Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Full sub-agent instructions live in `.claude/agents/`.","Slash commands live in `.claude/commands/`.","MCP server config lives in `.mcp.json` (project) and `~/.claude.json` (user-global — written by `claude mcp add --scope user`).","Default agent set to `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator, no `/agent` command needed.",``,"Start with `AGENTS.md`, then open the specific sub-agent file you want to use.",``,c,``,s,``].join(`
5
5
  `)}function N(e,t,n,r,i){let a=T(t.toolRole),o=O(t),s=v(t.skills),c=e===`Orchestrator`?[b,x]:[S],l=[n,...o,t.bodyAddendum,s,...c].filter(Boolean).join(`
6
6
 
7
- `).trim(),u=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${y(t.description)}.`,d=i?.[e],f=[`---`,`name: ${C(e)}`,`description: ${w(t.description)}`,...d?[`model: ${w(d)}`]:[],`allowedTools:`,...a.map(e=>` - ${e}`),`---`,``,`# ${e} - ${t.title||e}`,``,u];return l&&f.push(``,l),f.push(``),f.join(`
7
+ `).trim(),u=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${y(t.description)}.`,d=i?.[e],f=a.length>0?`tools: [${a.join(`, `)}]`:null,p=t.skills?.length>0?`skills: [${t.skills.map(([e])=>e).join(`, `)}]`:null,m=[`---`,`name: ${C(e)}`,`description: ${w(t.description)}`,...d?[`model: ${w(d)}`]:[],...f?[f]:[],`mcpServers:`,` - aikit`,...p?[p]:[],`---`,``,`# ${e} - ${t.title||e}`,``,u];return l&&m.push(``,l),m.push(``),m.join(`
8
8
  `)}function P(){let t=[],n=a(`claude-code`),s=p(e,n),c=m(e);t.push({path:`.mcp.json`,content:`${_({serverName:i,mcpEntry:r,configKey:`mcpServers`})}\n`}),t.push({path:`CLAUDE.md`,content:M()}),t.push({path:`AGENTS.md`,content:j(s)});for(let[e,n]of Object.entries(o))t.push({path:`.claude/commands/aikit-${e}.md`,content:E(e,n)});for(let[r,i]of Object.entries(e)){let e=D(r,c);if(i.variants){for(let[a,o]of Object.entries(i.variants)){let c=`${r}-${a}`;t.push({path:`.claude/agents/${c}.md`,content:N(c,{...i,description:o.description||i.description,identity:o.identity,bodyAddendum:o.bodyAddendum},e,s,n)})}continue}t.push({path:`.claude/agents/${r}.md`,content:N(r,i,e,s,n)})}return t}export{b as CLAUDE_FLOWS_SECTION,x as CLAUDE_ORCHESTRATOR_FLOW_ROUTING_SECTION,P as generateClaudeCode};
@@ -1 +1 @@
1
- const e=[`copilot`,`claude`,`copilotCli`,`hermes`],t={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`}},n={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`]}},r={"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`}};function i(r){let i=[{name:`HOOK_EVENTS`,entries:Object.values(t)},{name:`HOOK_TOOL_MATCHERS`,entries:Object.values(n)}];for(let t of e){for(let e of i)for(let n of e.entries)if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e.name} (entry has keys: ${Object.keys(n).join(`, `)}). Add a "${t}" key to all entries in ${e.name} in exec-hooks.mjs.`);if(r){for(let[e,n]of Object.entries(r))if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e} (has keys: ${Object.keys(n).join(`, `)}). Add "${t}: '...'" to ${e}.`)}}}export{r as EXEC_HOOKS,t as HOOK_EVENTS,n as HOOK_TOOL_MATCHERS,e as SUPPORTED_PLATFORMS,i as validateAllPlatformRegistries};
1
+ const e=[`copilot`,`claude`,`copilotCli`,`hermes`],t={SessionStart:{copilot:`SessionStart`,claude:`SessionStart`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolUse`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolUse`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`SubagentStart`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreCompact`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`Stop`,copilotCli:`stop`,hermes:`Stop`}},n={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`]}},r={"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`}};function i(r){let i=[{name:`HOOK_EVENTS`,entries:Object.values(t)},{name:`HOOK_TOOL_MATCHERS`,entries:Object.values(n)}];for(let t of e){for(let e of i)for(let n of e.entries)if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e.name} (entry has keys: ${Object.keys(n).join(`, `)}). Add a "${t}" key to all entries in ${e.name} in exec-hooks.mjs.`);if(r){for(let[e,n]of Object.entries(r))if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e} (has keys: ${Object.keys(n).join(`, `)}). Add "${t}: '...'" to ${e}.`)}}}export{r as EXEC_HOOKS,t as HOOK_EVENTS,n as HOOK_TOOL_MATCHERS,e as SUPPORTED_PLATFORMS,i as validateAllPlatformRegistries};
@@ -2,7 +2,10 @@ import { defineConfig } from 'vitest/config';
2
2
 
3
3
  export default defineConfig({
4
4
  test: {
5
- include: ['scaffold/__tests__/prompts-quality.test.mjs'],
5
+ include: [
6
+ 'scaffold/__tests__/prompts-quality.test.mjs',
7
+ 'scaffold/__tests__/cli-adapters.test.mjs',
8
+ ],
6
9
  exclude: ['**/node_modules/**'],
7
10
  },
8
11
  });