@vpxa/aikit 0.1.97 → 0.1.99
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 +1 -1
- package/packages/cli/dist/constants-BHJ95m41.js +1 -0
- package/packages/cli/dist/index.js +3 -3
- package/packages/cli/dist/{init-DjZFwBjs.js → init-CVtbu7zj.js} +1 -1
- package/packages/cli/dist/{templates-DrkDLz-X.js → templates-DVcEiTlc.js} +27 -65
- package/packages/cli/dist/{user-CY8UN2JU.js → user-Dj8KE0_0.js} +1 -1
- package/scaffold/dist/definitions/bodies.mjs +145 -2
- package/scaffold/dist/definitions/protocols.mjs +403 -118
- package/scaffold/dist/definitions/skills.mjs +40 -0
- package/packages/cli/dist/constants-BSGpNyrr.js +0 -1
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=`aikit`,t={type:`stdio`,command:`node`,args:[`-e`,[`const{execFileSync:x}=require('child_process')`,`const{renameSync:m}=require('fs')`,`const{join:j}=require('path')`,`const d=process.platform==='win32'?j(process.env.LOCALAPPDATA||'','npm-cache','_npx'):j(require('os').homedir(),'.npm','_npx')`,`const s={stdio:'inherit',shell:true}`,`try{x('npx',['-y','@vpxa/aikit','serve'],s)}catch(e){try{m(d,d+'_'+Date.now())}catch{};x('npx',['-y','@vpxa/aikit','serve'],s)}`].join(`;`)]},n=[`aikit`,`brainstorming`,`multi-agents-development`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`,`present`,`frontend-design`,`react`,`typescript`,`docs`,`repo-access`],r=[`aikit-basic`,`aikit-advanced`,`_epilogue`],i={"chat.agentFilesLocations":{"~/.claude/agents":!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}};export{i as a,n as i,t as n,e as r,r as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e,t}from"./constants-
|
|
1
|
+
import{i as e,t}from"./constants-BHJ95m41.js";import{copyFileSync as n,existsSync as r,mkdirSync as i,readFileSync as a}from"node:fs";import{basename as o,dirname as s,join as c,resolve as l}from"node:path";import{fileURLToPath as u}from"node:url";import{addToWorkset as d,audit as f,batch as p,check as m,checkpointLatest as h,checkpointList as ee,checkpointLoad as te,checkpointSave as ne,codemod as re,compact as ie,dataTransform as ae,delegate as oe,delegateListModels as se,deleteWorkset as ce,diffParse as le,evaluate as ue,fileSummary as de,find as g,findDeadSymbols as fe,findExamples as pe,getWorkset as me,gitContext as he,graphQuery as ge,guide as _e,health as ve,laneCreate as ye,laneDiff as be,laneDiscard as xe,laneList as Se,laneMerge as Ce,laneStatus as we,listWorksets as Te,parseOutput as _,processList as v,processLogs as y,processStart as b,processStatus as x,processStop as S,queueClear as C,queueCreate as w,queueDelete as T,queueDone as E,queueFail as D,queueGet as O,queueList as Ee,queueNext as De,queuePush as Oe,removeFromWorkset as ke,rename as Ae,replayClear as je,replayList as Me,replayTrim as Ne,saveWorkset as Pe,scopeMap as Fe,stashClear as Ie,stashDelete as Le,stashGet as Re,stashList as ze,stashSet as Be,symbol as Ve,testRun as He,trace as Ue,watchList as We,watchStart as Ge,watchStop as Ke}from"../../tools/dist/index.js";import{readFile as k}from"node:fs/promises";import{AIKIT_PATHS as A,getGlobalDataDir as qe,getPartitionDir as j,isUserInstalled as Je,registerWorkspace as Ye}from"../../core/dist/index.js";import{initializeWasm as Xe}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ze}from"../../embeddings/dist/index.js";import{IncrementalIndexer as Qe}from"../../indexer/dist/index.js";import{SqliteGraphStore as $e,createStore as et}from"../../store/dist/index.js";import{fork as tt}from"node:child_process";const nt=[{name:`analyze`,description:`Run analyzer output for a path`,usage:`aikit analyze <type> <path>`,run:async e=>{let t=e.shift()?.trim()??``,n=e.shift()?.trim()??``;(!t||!n)&&(console.error(`Usage: aikit analyze <type> <path>`),console.error(`Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`),process.exit(1));let{BlastRadiusAnalyzer:r,DependencyAnalyzer:i,DiagramGenerator:a,EntryPointAnalyzer:o,PatternAnalyzer:s,StructureAnalyzer:c,SymbolAnalyzer:u}=await import(`../../analyzers/dist/index.js`),d=l(n),f;switch(t){case`structure`:f=await new c().analyze(d,{format:`markdown`});break;case`deps`:case`dependencies`:f=await new i().analyze(d,{format:`markdown`});break;case`symbols`:f=await new u().analyze(d,{format:`markdown`});break;case`patterns`:f=await new s().analyze(d,{format:`markdown`});break;case`entry-points`:f=await new o().analyze(d,{format:`markdown`});break;case`blast-radius`:f=await new r().analyze(process.cwd(),{files:[n],format:`markdown`});break;case`diagram`:f=await new a().analyze(d,{diagramType:`architecture`});break;default:console.error(`Unknown analyze type: ${t}`),console.error(`Types: structure, deps, symbols, patterns, entry-points, blast-radius, diagram`),process.exit(1)}console.log(f.output)}},{name:`onboard`,description:`Run all analyses for first-time codebase onboarding`,usage:`aikit onboard <path> [--generate] [--out-dir <dir>]`,run:async e=>{let{onboard:t}=await import(`../../tools/dist/index.js`),n=``,r=`memory`,i;for(let t=0;t<e.length;t++){let a=e[t].trim();a===`--generate`?r=`generate`:a===`--out-dir`&&t+1<e.length?i=e[++t].trim():a.startsWith(`--`)||(n=a)}n||=process.cwd();let a=l(n);console.log(`Onboarding: ${a} (mode: ${r})`),console.log(`Running analyses...
|
|
2
2
|
`);let o=await t({path:a,mode:r,outDir:i});for(let e of o.steps){let t=e.status===`success`?`✓`:`✗`,n=e.status===`success`?`${e.durationMs}ms, ${e.output.length} chars`:e.error;console.log(` ${t} ${e.name} — ${n}`)}console.log(`\nTotal: ${o.totalDurationMs}ms`),o.outDir&&console.log(`Output written to: ${o.outDir}`)}}];function M(e,t,n){let r=e.indexOf(t);if(r===-1||r+1>=e.length)return n;let i=Number.parseInt(e.splice(r,2)[1],10);return Number.isNaN(i)?n:i}function N(e,t,n){let r=e.indexOf(t);return r===-1||r+1>=e.length?n:e.splice(r,2)[1]}function P(e,t){let n=e.indexOf(t);return n===-1?!1:(e.splice(n,1),!0)}async function F(){if(process.stdin.isTTY)return``;let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf-8`)}async function rt(e){return e?k(l(e),`utf-8`):F()}function I(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function it(e){let t=JSON.parse(e);if(Array.isArray(t))return{operations:L(t)};if(t&&typeof t==`object`&&`operations`in t){let e=t;return{operations:L(e.operations),concurrency:typeof e.concurrency==`number`?e.concurrency:void 0}}throw Error(`Batch input must be an array of operations or an object with an operations array.`)}function L(e){if(!Array.isArray(e))throw Error(`Batch operations must be an array.`);return e.map((e,t)=>{if(!e||typeof e!=`object`)throw Error(`Batch operation at index ${t} must be an object.`);let n=e;if(typeof n.id!=`string`||n.id.length===0)throw Error(`Batch operation at index ${t} is missing a valid id.`);if(typeof n.type!=`string`||n.type.length===0)throw Error(`Batch operation ${n.id} is missing a valid type.`);if(!n.args||typeof n.args!=`object`||Array.isArray(n.args))throw Error(`Batch operation ${n.id} must include an args object.`);return{id:n.id,type:n.type,args:n.args}})}function at(e){return e.map(e=>{let t=e.heading?` ${e.heading}`:``;return`${e.start}-${e.end}${t}`}).join(`, `)}function ot(e){switch(e.tool){case`tsc`:case`biome`:console.log(`${e.tool} errors: ${e.errors.length}`);for(let t of e.errors){let e=[t.line,t.column].filter(e=>e!==void 0).join(`:`),n=e?`${t.file}:${e}`:t.file,r=t.code?` ${t.code}`:``;console.log(`- ${n} [${t.severity}${r}] ${t.message}`)}return;case`vitest`:console.log(`Vitest summary`),console.log(` Passed: ${e.summary.passed}`),console.log(` Failed: ${e.summary.failed}`),console.log(` Skipped: ${e.summary.skipped}`),e.summary.duration!==void 0&&console.log(` Duration: ${e.summary.duration}ms`);for(let t of e.summary.tests)t.status===`fail`&&(console.log(`- ${t.name}${t.file?` (${t.file})`:``}`),t.error&&console.log(` ${t.error}`));return;case`git-status`:console.log(`Branch: ${e.status.branch??`unknown`}`),console.log(`Staged: ${e.status.staged.length}`);for(let t of e.status.staged)console.log(` ${t.status} ${t.file}`);console.log(`Unstaged: ${e.status.unstaged.length}`);for(let t of e.status.unstaged)console.log(` ${t.status} ${t.file}`);console.log(`Untracked: ${e.status.untracked.length}`);for(let t of e.status.untracked)console.log(` ?? ${t}`);return}}function st(e){console.log(`Overall: ${e.passed?`passed`:`failed`}`),R(`tsc`,e.tsc.passed,e.tsc.errors),R(`biome`,e.biome.passed,e.biome.errors)}function R(e,t,n){console.log(`${e}: ${t?`passed`:`${n.length} issue(s)`}`);for(let e of n){let t=[e.line,e.column].filter(e=>e!==void 0).join(`:`),n=t?`${e.file}:${t}`:e.file,r=e.code?` ${e.code}`:``;console.log(` - ${n} [${e.severity}${r}] ${e.message}`)}}function ct(e){console.log(`Vitest: ${e.passed?`passed`:`failed`}`),console.log(` Duration: ${e.durationMs}ms`),console.log(` Passed: ${e.summary.passed}`),console.log(` Failed: ${e.summary.failed}`),console.log(` Skipped: ${e.summary.skipped}`),e.summary.suites!==void 0&&console.log(` Suites: ${e.summary.suites}`);let t=e.summary.tests.filter(e=>e.status===`fail`);if(t.length!==0){console.log(`Failed tests:`);for(let e of t)console.log(` - ${e.name}${e.file?` (${e.file})`:``}`),e.error&&console.log(` ${e.error}`)}}function lt(e){console.log(`Branch: ${e.branch}`),console.log(`Staged: ${e.status.staged.length}`);for(let t of e.status.staged)console.log(` - ${t}`);console.log(`Modified: ${e.status.modified.length}`);for(let t of e.status.modified)console.log(` - ${t}`);console.log(`Untracked: ${e.status.untracked.length}`);for(let t of e.status.untracked)console.log(` - ${t}`);if(console.log(``),console.log(`Recent commits:`),e.recentCommits.length===0)console.log(` none`);else for(let t of e.recentCommits)console.log(` - ${t.hash} ${t.message}`),console.log(` ${t.author} @ ${t.date}`);e.diff&&(console.log(``),console.log(`Diff stat:`),console.log(e.diff))}function ut(e){if(e.length===0){console.log(`No diff files found.`);return}for(let t of e){let e=t.oldPath?` (from ${t.oldPath})`:``;console.log(`${t.path}${e}`),console.log(` Status: ${t.status}`),console.log(` Changes: +${t.additions} -${t.deletions}`),console.log(` Hunks: ${t.hunks.length}`);for(let e of t.hunks){let t=e.header?` ${e.header}`:``;console.log(` @@ -${e.oldStart},${e.oldLines} +${e.newStart},${e.newLines} @@${t}`)}}}function dt(e){if(console.log(`Start: ${e.start}`),console.log(`Direction: ${e.direction}`),console.log(`Depth reached: ${e.depth}`),console.log(`Nodes: ${e.nodes.length}`),e.nodes.length===0){console.log(`No trace nodes found.`);return}for(let t of e.nodes)console.log(` - [${t.relationship}] ${t.path}:${t.line} ${t.symbol}`)}function ft(e){if(console.log(`Query: ${e.query}`),console.log(`Examples: ${e.examples.length} shown (${e.totalFound} total)`),e.examples.length===0){console.log(`No matching examples found.`);return}for(let t of e.examples){console.log(``),console.log(`${t.path}:${t.startLine}-${t.endLine}`),console.log(` Context: ${t.context}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}%`);for(let e of t.content.split(`
|
|
3
3
|
`))console.log(` ${e}`)}}function z(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 pt(e){if(console.log(`Exports scanned: ${e.totalExports}`),console.log(`Dead in source: ${e.totalDeadSource} (actionable)`),console.log(`Dead in docs: ${e.totalDeadDocs} (informational)`),e.totalDeadSource===0&&e.totalDeadDocs===0){console.log(`No dead symbols found.`);return}if(e.deadInSource.length>0){console.log(`
|
|
4
4
|
Dead in source (actionable):`);for(let t of e.deadInSource)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}if(e.deadInDocs.length>0){console.log(`
|
|
@@ -9,7 +9,7 @@ Dead in docs (informational):`);for(let t of e.deadInDocs)console.log(` - ${t.p
|
|
|
9
9
|
Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`),process.exit(1));let{graphStore:n}=await Y(),r=N(e,`--type`,``),i=N(e,`--name`,``),a=N(e,`--node-id`,``),o=N(e,`--edge-type`,``),s=N(e,`--direction`,`both`),c=M(e,`--depth`,2),l=M(e,`--limit`,50),u=N(e,`--source-path`,``),d={stats:`stats`,"find-nodes":`find_nodes`,"find-edges":`find_edges`,neighbors:`neighbors`,traverse:`traverse`,delete:`delete`,clear:`clear`}[t];d||(console.error(`Unknown graph action: ${t}`),console.error(`Actions: stats, find-nodes, find-edges, neighbors, traverse, delete, clear`),process.exit(1));let f=await ge(n,{action:d,nodeType:r||void 0,namePattern:i||void 0,sourcePath:u||void 0,nodeId:a||void 0,edgeType:o||void 0,direction:s,maxDepth:c,limit:l});if(console.log(f.summary),f.nodes&&f.nodes.length>0){console.log(`
|
|
10
10
|
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(`
|
|
11
11
|
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}`)}}],Ot=[{name:`remember`,description:`Store curated knowledge`,usage:`aikit remember <title> --category <cat> [--tags tag1,tag2]`,run:async e=>{let t=N(e,`--category`,``).trim(),n=I(N(e,`--tags`,``)),r=e.shift()?.trim()??``,i=await F(),a=i.trim().length>0?i:e.join(` `).trim();(!r||!t||!a.trim())&&(console.error(`Usage: aikit remember <title> --category <cat> [--tags tag1,tag2]`),process.exit(1));let{curated:o}=await Y(),s=await o.remember(r,a,t,n);console.log(`Stored curated entry`),console.log(` Path: ${s.path}`),console.log(` Category: ${t}`),n.length>0&&console.log(` Tags: ${n.join(`, `)}`)}},{name:`forget`,description:`Remove a curated entry`,usage:`aikit forget <path> --reason <reason>`,run:async e=>{let t=N(e,`--reason`,``).trim(),n=e.shift()?.trim()??``;(!n||!t)&&(console.error(`Usage: aikit forget <path> --reason <reason>`),process.exit(1));let{curated:r}=await Y(),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 Y(),r=await n.read(t);console.log(r.title),console.log(`─`.repeat(60)),console.log(`Path: ${r.path}`),console.log(`Category: ${r.category}`),console.log(`Version: ${r.version}`),console.log(`Tags: ${r.tags.length>0?r.tags.join(`, `):`None`}`),console.log(``),console.log(r.content)}},{name:`list`,description:`List curated entries`,usage:`aikit list [--category <cat>] [--tag <tag>]`,run:async e=>{let t=N(e,`--category`,``).trim()||void 0,n=N(e,`--tag`,``).trim()||void 0,{curated:r}=await Y(),i=await r.list({category:t,tag:n});if(i.length===0){console.log(`No curated entries found.`);return}console.log(`Curated entries (${i.length})`),console.log(`─`.repeat(60));for(let e of i){console.log(e.path),console.log(` ${e.title}`),console.log(` Category: ${e.category} | Version: ${e.version}`),console.log(` Tags: ${e.tags.length>0?e.tags.join(`, `):`None`}`);let t=e.contentPreview.replace(/\s+/g,` `).trim();t&&console.log(` Preview: ${t}`),console.log(``)}}},{name:`update`,description:`Update a curated entry`,usage:`aikit update <path> --reason <reason>`,run:async e=>{let t=N(e,`--reason`,``).trim(),n=e.shift()?.trim()??``,r=await F();(!n||!t||!r.trim())&&(console.error(`Usage: aikit update <path> --reason <reason>`),process.exit(1));let{curated:i}=await Y(),a=await i.update(n,r,t);console.log(`Updated curated entry`),console.log(` Path: ${a.path}`),console.log(` Version: ${a.version}`)}},{name:`compact`,description:`Compress text for context`,usage:`aikit compact <query> [--path <file>] [--max-chars N] [--segmentation paragraph|sentence|line]`,run:async e=>{let t=M(e,`--max-chars`,3e3),n=N(e,`--path`,``).trim()||void 0,r=N(e,`--segmentation`,`paragraph`),i=e.join(` `).trim(),a=n?void 0:await F();(!i||!n&&!a?.trim())&&(console.error(`Usage: aikit compact <query> --path <file> OR cat file | aikit compact <query>`),process.exit(1));let{embedder:o}=await Y(),s=await ie(o,{text:a,path:n,query:i,maxChars:t,segmentation:r});console.log(`Compressed ${s.originalChars} chars to ${s.compressedChars} chars`),console.log(`Ratio: ${(s.ratio*100).toFixed(1)}% | Segments: ${s.segmentsKept}/${s.segmentsTotal}`),console.log(``),console.log(s.text)}}],kt=[{name:`search`,description:`Search the AI Kit index`,usage:`aikit search <query> [--limit N] [--mode hybrid|semantic|keyword] [--graph-hops 0-3]`,run:async e=>{let t=M(e,`--limit`,5),n=N(e,`--mode`,`hybrid`),r=M(e,`--graph-hops`,0),i=e.join(` `).trim();i||(console.error(`Usage: aikit search <query>`),process.exit(1));let{embedder:a,store:o,graphStore:s}=await Y(),c=await a.embedQuery(i),l;if(n===`keyword`)l=await o.ftsSearch(i,{limit:t});else if(n===`semantic`)l=await o.search(c,{limit:t});else{let[e,n]=await Promise.all([o.search(c,{limit:t*2}),o.ftsSearch(i,{limit:t*2}).catch(()=>[])]);l=U(e,n).slice(0,t)}if(l.length===0){console.log(`No results found.`);return}for(let{record:e,score:t}of l){console.log(`\n${`─`.repeat(60)}`),console.log(`[${(t*100).toFixed(1)}%] ${e.sourcePath}:${e.startLine}-${e.endLine}`),console.log(` Type: ${e.contentType} | Origin: ${e.origin}`),e.tags.length>0&&console.log(` Tags: ${e.tags.join(`, `)}`),console.log(``);let n=e.content.length>500?`${e.content.slice(0,500)}...`:e.content;console.log(n)}if(console.log(`\n${`─`.repeat(60)}`),console.log(`${l.length} result(s) found.`),r>0&&l.length>0)try{let{graphAugmentSearch:e}=await import(`../../tools/dist/index.js`),t=(await e(s,l.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:r,maxPerHit:5})).filter(e=>e.graphContext.nodes.length>0);if(t.length>0){console.log(`\nGraph context (${r} hop${r>1?`s`:``}):\n`);for(let e of t){console.log(` ${e.sourcePath}:`);for(let t of e.graphContext.nodes.slice(0,5))console.log(` → ${t.name} (${t.type})`);for(let t of e.graphContext.edges.slice(0,5))console.log(` → ${t.fromId} --[${t.type}]--> ${t.toId}`)}}}catch(e){console.error(`[graph] augmentation failed: ${e.message}`)}}},{name:`find`,description:`Run federated search across indexed content and files`,usage:`aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`,run:async e=>{let t=M(e,`--limit`,10),n=N(e,`--glob`,``).trim()||void 0,r=N(e,`--pattern`,``).trim()||void 0,i=e.join(` `).trim()||void 0;!i&&!n&&!r&&(console.error(`Usage: aikit find [query] [--glob <pattern>] [--pattern <regex>] [--limit N]`),process.exit(1));let{embedder:a,store:o}=await Y(),s=await g(a,o,{query:i,glob:n,pattern:r,limit:t});if(s.results.length===0){console.log(`No matches found.`);return}console.log(`Strategies: ${s.strategies.join(`, `)}`),console.log(`Results: ${s.results.length} shown (${s.totalFound} total)`);for(let e of s.results){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;console.log(`\n[${e.source}] ${e.path}${t}`),console.log(` Score: ${(e.score*100).toFixed(1)}%`),e.preview&&console.log(` ${e.preview.replace(/\s+/g,` `).trim()}`)}}},{name:`scope-map`,description:`Generate a reading plan for a task`,usage:`aikit scope-map <task> [--max-files N]`,run:async e=>{let t=M(e,`--max-files`,15),n=e.join(` `).trim();n||(console.error(`Usage: aikit scope-map <task> [--max-files N]`),process.exit(1));let{embedder:r,store:i}=await Y(),a=await Fe(r,i,{task:n,maxFiles:t});console.log(`Task: ${a.task}`),console.log(`Files: ${a.files.length}`),console.log(`Estimated tokens: ${a.totalEstimatedTokens}`),console.log(``),console.log(`Reading order:`);for(let e of a.readingOrder)console.log(` ${e}`);for(let[e,t]of a.files.entries())console.log(`\n${e+1}. ${t.path}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}% | Tokens: ${t.estimatedTokens}`),console.log(` Why: ${t.reason}`),t.focusRanges.length>0&&console.log(` Focus: ${at(t.focusRanges)}`)}},{name:`symbol`,description:`Resolve a symbol definition, imports, and references`,usage:`aikit symbol <name> [--limit N]`,run:async e=>{let t=M(e,`--limit`,20),n=e.join(` `).trim();n||(console.error(`Usage: aikit symbol <name> [--limit N]`),process.exit(1));let{embedder:r,store:i}=await Y();ht(await Ve(r,i,{name:n,limit:t}))}},{name:`trace`,description:`Trace forward/backward flow for a symbol or file location`,usage:`aikit trace <start> [--direction forward|backward|both] [--max-depth N]`,run:async e=>{let t=N(e,`--direction`,`both`).trim()||`both`,n=M(e,`--max-depth`,3),r=e.join(` `).trim();(!r||![`forward`,`backward`,`both`].includes(t))&&(console.error(`Usage: aikit trace <start> [--direction forward|backward|both] [--max-depth N]`),process.exit(1));let{embedder:i,store:a}=await Y();dt(await Ue(i,a,{start:r,direction:t,maxDepth:n}))}},{name:`examples`,description:`Find real code examples of a symbol or pattern`,usage:`aikit examples <query> [--limit N] [--content-type type]`,run:async e=>{let t=M(e,`--limit`,5),n=N(e,`--content-type`,``).trim()||void 0,r=e.join(` `).trim();r||(console.error(`Usage: aikit examples <query> [--limit N] [--content-type type]`),process.exit(1));let{embedder:i,store:a}=await Y();ft(await pe(i,a,{query:r,limit:t,contentType:n}))}},{name:`dead-symbols`,description:`Find exported symbols that appear to be unused`,usage:`aikit dead-symbols [--limit N]`,run:async e=>{let t=M(e,`--limit`,100),{embedder:n,store:r}=await Y();pt(await fe(n,r,{limit:t}))}},{name:`lookup`,description:`Look up indexed content by record ID or source path`,usage:`aikit lookup <id>`,run:async e=>{let t=e.join(` `).trim();t||(console.error(`Usage: aikit lookup <id>`),process.exit(1));let{store:n}=await Y(),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)}}}],X=s(u(import.meta.url));function Z(e){let t=e;for(let e=0;e<10;e++){try{let e=c(t,`package.json`);if(r(e)&&JSON.parse(a(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=s(t);if(e===t)break;t=e}return l(e,`..`,`..`,`..`)}const At=[{name:`status`,description:`Show AI Kit index status and statistics`,run:async()=>{let{isUserInstalled:e,getGlobalDataDir:t,computePartitionKey:n,listWorkspaces:r}=await import(`../../core/dist/index.js`),{existsSync:i}=await import(`node:fs`),a=process.cwd(),o=e(),s=i(l(a,`.vscode`,`mcp.json`)),c,u;if(o&&s)c=`workspace (overrides user-level for this workspace)`,u=l(a,`.aikit-data`);else if(o){let e=n(a);c=i(l(a,`AGENTS.md`))?`user (workspace scaffolded)`:`user (workspace not scaffolded)`,u=l(t(),e)}else c=`workspace`,u=l(a,`.aikit-data`);if(console.log(`AI Kit Status`),console.log(`─`.repeat(40)),console.log(` Mode: ${c}`),console.log(` Data: ${u}`),o&&!s){let e=r();console.log(` Registry: ${e.length} workspace(s) enrolled`)}try{let{store:e}=await Y(),t=await e.getStats(),n=await e.listSourcePaths();console.log(` Records: ${t.totalRecords}`),console.log(` Files: ${t.totalFiles}`),console.log(` Indexed: ${t.lastIndexedAt??`Never`}`),console.log(` Backend: ${t.storeBackend}`),console.log(` Model: ${t.embeddingModel}`),console.log(``),console.log(`Content Types:`);for(let[e,n]of Object.entries(t.contentTypeBreakdown))console.log(` ${e}: ${n}`);if(n.length>0){console.log(``),console.log(`Files (${n.length} total):`);for(let e of n.slice(0,20))console.log(` ${e}`);n.length>20&&console.log(` ... and ${n.length-20} more`)}}catch{console.log(``),console.log(" Index not available — run `aikit reindex` to index this workspace.")}o&&!s&&!i(l(a,`AGENTS.md`))&&(console.log(``),console.log(" Action: Run `npx @vpxa/aikit init` to add AGENTS.md and copilot-instructions.md"))}},{name:`reindex`,description:`Re-index the AI Kit index from configured sources`,usage:`aikit reindex [--full]`,run:async e=>{let t=e.includes(`--full`),{store:n,indexer:r,curated:i,config:a}=await Y();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(`
|
|
12
|
-
`)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server (stdio or HTTP)`,usage:`aikit serve [--transport stdio|http] [--port N]`,run:async e=>{let t=l(Z(X),`packages`,`server`,`dist`,`index.js`),n=N(e,`--transport`,`stdio`),r=N(e,`--port`,`3210`),i=tt(t,[],{stdio:n===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,AIKIT_TRANSPORT:n,AIKIT_PORT:r}});n===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--
|
|
13
|
-
Suggested next steps:`);for(let e of o.next)console.log(` → ${e.tool}: ${e.reason}`)}}else console.error(o.error?.message??`Audit failed`),process.exitCode=1}},{name:`guide`,description:`Tool discovery — recommend AI Kit tools for a given goal`,usage:`aikit guide <goal> [--max N]`,run:async e=>{let t=e.indexOf(`--max`),n=5;t!==-1&&t+1<e.length&&(n=Number.parseInt(e.splice(t,2)[1],10)||5);let r=e.join(` `).trim();r||(console.error(`Usage: aikit guide <goal> [--max N]`),console.error(`Example: aikit guide "audit this project"`),process.exit(1));let i=_e(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=Me({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}`)}Ne().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{je(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=l(Z(X),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),u=`http://localhost:${r}/_dashboard/`,d=`http://localhost:${r}/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||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Dashboard: ${u}`),console.log(`Press Ctrl+C to stop.`),!i){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 p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=l(Z(X),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),u=`http://localhost:${r}/settings/`,d=`http://localhost:${r}/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||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Settings: ${u}`),console.log(`Press Ctrl+C to stop.`),!i){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 p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}}];function jt(e){let t=e;for(let e=0;e<10;e++){try{let e=c(t,`package.json`);if(r(e)&&JSON.parse(a(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=s(t);if(e===t)break;t=e}return l(e,`..`,`..`,`..`)}const Mt=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{let{initUser:n}=await import(`./user-CY8UN2JU.js`);await n({force:!0});let i=process.cwd(),o=r(l(i,`.github`,`.aikit-scaffold.json`)),c=r(l(i,`.github`,`agents`)),d=r(l(i,`.github`,`prompts`)),f=r(l(i,`.claude`,`commands`));if(o||c||d||f){let{initScaffoldOnly:e}=await import(`./init-DjZFwBjs.js`);await e({force:!0})}if(r(l(i,`.github`,`skills`))){let{smartCopySkills:n}=await import(`./scaffold-D664MT9M.js`),r=jt(s(u(import.meta.url))),o=JSON.parse(a(l(r,`package.json`),`utf-8`)).version;await n(i,r,[...e],o,!0);let{smartCopyFlows:c}=await import(`./scaffold-D664MT9M.js`);await c(i,r,[...t],o,!0)}}}],Nt=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=I(N(e,`--files`,``)),r=N(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=Pe(i,n,{description:r});console.log(`Saved workset: ${e.name}`),B(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=me(i);if(!e){console.log(`No workset found: ${i}`);return}B(e);return}case`list`:{let e=Te();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)B(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=ce(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=d(i,n);console.log(`Updated workset: ${e.name}`),B(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=ke(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),B(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();switch(t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1)),t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),r=t.trim()?``:await F(),i=Be(n,gt(t||r));console.log(`Stored stash entry: ${i.key}`),console.log(` Type: ${i.type}`),console.log(` Stored: ${i.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=Re(n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=ze();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=Le(n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=Ie();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=Se();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=N(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=ye(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=we(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=be(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=Ce(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=xe(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=Ee();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=w(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Oe(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=De(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=E(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=D(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=O(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=C(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=T(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Q=[...kt,...Ot,...nt,...Dt,...At,...xt,...yt,...Nt,...bt,...Mt,...q];Q.push({name:`help`,description:`Show available commands`,run:async()=>{$()}});async function Pt(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){$();return}if(n===`--version`||n===`-v`){let e=l(s(u(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(a(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Q.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Q.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),$(),process.exit(1));try{await r.run(t)}finally{let e=Et();e&&await e.store.close()}}function $(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
|
|
12
|
+
`)},s;t?(console.log(`Dropping existing index for full reindex...`),s=await r.reindexAll(a,o)):s=await r.index(a,o),console.log(`Done: ${s.filesProcessed} files, ${s.chunksCreated} chunks in ${(s.durationMs/1e3).toFixed(1)}s`),console.log(`Building FTS index...`),await n.createFtsIndex(),console.log(`Re-indexing curated entries...`);let c=await i.reindexAll();console.log(`Curated: ${c.indexed} entries restored`)}},{name:`serve`,description:`Start the MCP server (stdio or HTTP)`,usage:`aikit serve [--transport stdio|http] [--port N]`,run:async e=>{let t=l(Z(X),`packages`,`server`,`dist`,`index.js`),n=N(e,`--transport`,`stdio`),r=N(e,`--port`,`3210`),i=tt(t,[],{stdio:n===`stdio`?[`pipe`,`pipe`,`inherit`,`ipc`]:`inherit`,env:{...process.env,AIKIT_TRANSPORT:n,AIKIT_PORT:r}});n===`stdio`&&i.stdin&&i.stdout&&(process.stdin.pipe(i.stdin),i.stdout.pipe(process.stdout)),i.on(`exit`,e=>process.exit(e??0)),process.on(`SIGINT`,()=>i.kill(`SIGINT`)),process.on(`SIGTERM`,()=>i.kill(`SIGTERM`)),await new Promise(()=>{})}},{name:`init`,description:`Initialize AI Kit in the current directory`,usage:`aikit init [--workspace] [--smart] [--force] [--guide]`,run:async e=>{let t=e.includes(`--user`),n=e.includes(`--workspace`),r=e.includes(`--smart`),i=e.includes(`--guide`),a=e.includes(`--force`);if(t&&n&&(console.error(`Cannot use --user and --workspace together.`),process.exit(1)),i){let{guideProject:e}=await import(`./init-CVtbu7zj.js`);await e();return}if(r){let{initSmart:e}=await import(`./init-CVtbu7zj.js`);await e({force:a})}else if(t){let{initUser:e}=await import(`./user-Dj8KE0_0.js`);await e({force:a})}else if(n){let{initProject:e}=await import(`./init-CVtbu7zj.js`);await e({force:a})}else{let{initUser:e}=await import(`./user-Dj8KE0_0.js`);await e({force:a})}}},{name:`check`,description:`Run incremental typecheck and lint`,usage:`aikit check [--cwd <dir>] [--files f1,f2] [--skip-types] [--skip-lint] [--detail efficient|normal|full]`,run:async e=>{let t=N(e,`--cwd`,``).trim()||void 0,n=N(e,`--files`,``),r=N(e,`--detail`,`full`)||`full`,i=n.split(`,`).map(e=>e.trim()).filter(Boolean),a=!1;e.includes(`--skip-types`)&&(e.splice(e.indexOf(`--skip-types`),1),a=!0);let o=!1;e.includes(`--skip-lint`)&&(e.splice(e.indexOf(`--skip-lint`),1),o=!0);let s=await m({cwd:t,files:i.length>0?i:void 0,skipTypes:a,skipLint:o,detail:r});st(s),s.passed||(process.exitCode=1)}},{name:`batch`,description:`Execute built-in operations from JSON input`,usage:`aikit batch [--file path] [--concurrency N]`,run:async e=>{let t=N(e,`--file`,``).trim()||void 0,n=(()=>{let t=e.indexOf(`--concurrency`);if(t===-1||t+1>=e.length)return 0;let n=Number.parseInt(e.splice(t,2)[1],10);return Number.isNaN(n)?0:n})(),r=await rt(t);r.trim()||(console.error(`Usage: aikit batch [--file path] [--concurrency N]`),process.exit(1));let i=it(r),a=n>0?n:i.concurrency,o=i.operations.some(e=>e.type!==`check`)?await Y():null,s=await p(i.operations,async e=>vt(e,o),{concurrency:a});console.log(JSON.stringify(s,null,2)),s.some(e=>e.status===`error`)&&(process.exitCode=1)}},{name:`health`,description:`Run project health checks on the current directory`,usage:`aikit health [path]`,run:async e=>{let t=ve(e.shift());console.log(`Project Health: ${t.path}`),console.log(`─`.repeat(50));for(let e of t.checks){let t=e.status===`pass`?`+`:e.status===`warn`?`~`:`X`;console.log(` [${t}] ${e.name}: ${e.message}`)}console.log(`─`.repeat(50)),console.log(`Score: ${t.score}% — ${t.summary}`)}},{name:`audit`,description:`Run a unified project audit (structure, deps, patterns, health, dead symbols, check)`,usage:`aikit audit [path] [--checks structure,dependencies,patterns,health,dead_symbols,check,entry_points] [--detail efficient|normal|full]`,run:async e=>{let{store:t,embedder:n}=await Y(),r=N(e,`--detail`,`efficient`)||`efficient`,i=N(e,`--checks`,``),a=i?i.split(`,`).map(e=>e.trim()):void 0,o=await f(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(`
|
|
13
|
+
Suggested next steps:`);for(let e of o.next)console.log(` → ${e.tool}: ${e.reason}`)}}else console.error(o.error?.message??`Audit failed`),process.exitCode=1}},{name:`guide`,description:`Tool discovery — recommend AI Kit tools for a given goal`,usage:`aikit guide <goal> [--max N]`,run:async e=>{let t=e.indexOf(`--max`),n=5;t!==-1&&t+1<e.length&&(n=Number.parseInt(e.splice(t,2)[1],10)||5);let r=e.join(` `).trim();r||(console.error(`Usage: aikit guide <goal> [--max N]`),console.error(`Example: aikit guide "audit this project"`),process.exit(1));let i=_e(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=Me({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}`)}Ne().catch(()=>{})}},{name:`replay-clear`,description:`Clear the replay audit trail`,run:async()=>{je(),console.log(`Replay log cleared.`)}},{name:`dashboard`,description:`Launch web dashboard for knowledge graph visualization`,usage:`aikit dashboard [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=l(Z(X),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),u=`http://localhost:${r}/_dashboard/`,d=`http://localhost:${r}/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||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Dashboard: ${u}`),console.log(`Press Ctrl+C to stop.`),!i){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 p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}},{name:`settings`,description:`Launch web UI to manage AI Kit configuration and environment variables`,usage:`aikit settings [--port <port>] [--no-open]`,run:async e=>{let t=e.indexOf(`--port`),n=t!==-1&&e[t+1]?Number.parseInt(e[t+1],10):3210,r=Number.isFinite(n)?n:3210,i=e.includes(`--no-open`);console.log(`Starting AI Kit server on port ${r}...`);let{spawn:a}=await import(`node:child_process`),{platform:o}=await import(`node:os`),s=l(Z(X),`packages`,`server`,`dist`,`index.js`),c=a(process.execPath,[s,`--transport`,`http`,`--port`,String(r)],{stdio:[`ignore`,`pipe`,`pipe`],env:{...process.env,AIKIT_TRANSPORT:`http`,AIKIT_PORT:String(r)}}),u=`http://localhost:${r}/settings/`,d=`http://localhost:${r}/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||(console.error(`Server failed to start within 30 seconds.`),c.kill(),process.exit(1)),console.log(`AI Kit Settings: ${u}`),console.log(`Press Ctrl+C to stop.`),!i){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 p=()=>{c.kill(),process.exit(0)};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),await new Promise(e=>{c.on(`exit`,()=>e())})}}];function jt(e){let t=e;for(let e=0;e<10;e++){try{let e=c(t,`package.json`);if(r(e)&&JSON.parse(a(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=s(t);if(e===t)break;t=e}return l(e,`..`,`..`,`..`)}const Mt=[{name:`upgrade`,description:`Upgrade AI Kit agents, prompts, and skills to the latest version (user-level and workspace-level)`,usage:`aikit upgrade`,run:async()=>{let{initUser:n}=await import(`./user-Dj8KE0_0.js`);await n({force:!0});let i=process.cwd(),o=r(l(i,`.github`,`.aikit-scaffold.json`)),c=r(l(i,`.github`,`agents`)),d=r(l(i,`.github`,`prompts`)),f=r(l(i,`.claude`,`commands`));if(o||c||d||f){let{initScaffoldOnly:e}=await import(`./init-CVtbu7zj.js`);await e({force:!0})}if(r(l(i,`.github`,`skills`))){let{smartCopySkills:n}=await import(`./scaffold-D664MT9M.js`),r=jt(s(u(import.meta.url))),o=JSON.parse(a(l(r,`package.json`),`utf-8`)).version;await n(i,r,[...e],o,!0);let{smartCopyFlows:c}=await import(`./scaffold-D664MT9M.js`);await c(i,r,[...t],o,!0)}}}],Nt=[{name:`workset`,description:`Manage saved file sets`,usage:`aikit workset <action> [name] [--files f1,f2] [--description desc]`,run:async e=>{let t=e.shift()?.trim(),n=I(N(e,`--files`,``)),r=N(e,`--description`,``).trim()||void 0,i=e.shift()?.trim();switch(t||(console.error(`Usage: aikit workset <action> [name] [--files f1,f2] [--description desc]`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)),t){case`save`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset save <name> --files f1,f2 [--description desc]`),process.exit(1));let e=Pe(i,n,{description:r});console.log(`Saved workset: ${e.name}`),B(e);return}case`get`:{i||(console.error(`Usage: aikit workset get <name>`),process.exit(1));let e=me(i);if(!e){console.log(`No workset found: ${i}`);return}B(e);return}case`list`:{let e=Te();if(e.length===0){console.log(`No worksets saved.`);return}console.log(`Worksets (${e.length})`),console.log(`─`.repeat(60));for(let t of e)B(t),console.log(``);return}case`delete`:{i||(console.error(`Usage: aikit workset delete <name>`),process.exit(1));let e=ce(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=d(i,n);console.log(`Updated workset: ${e.name}`),B(e);return}case`remove`:{(!i||n.length===0)&&(console.error(`Usage: aikit workset remove <name> --files f1,f2`),process.exit(1));let e=ke(i,n);if(!e){console.log(`No workset found: ${i}`);return}console.log(`Updated workset: ${e.name}`),B(e);return}default:console.error(`Unknown workset action: ${t}`),console.error(`Actions: save, get, list, delete, add, remove`),process.exit(1)}}},{name:`stash`,description:`Persist and retrieve named intermediate values`,usage:`aikit stash <set|get|list|delete|clear> [key] [value]`,run:async e=>{let t=e.shift()?.trim(),n=e.shift()?.trim();switch(t||(console.error(`Usage: aikit stash <set|get|list|delete|clear> [key] [value]`),process.exit(1)),t){case`set`:{n||(console.error(`Usage: aikit stash set <key> <value>`),process.exit(1));let t=e.join(` `),r=t.trim()?``:await F(),i=Be(n,gt(t||r));console.log(`Stored stash entry: ${i.key}`),console.log(` Type: ${i.type}`),console.log(` Stored: ${i.storedAt}`);return}case`get`:{n||(console.error(`Usage: aikit stash get <key>`),process.exit(1));let e=Re(n);if(!e){console.log(`No stash entry found: ${n}`);return}console.log(JSON.stringify(e,null,2));return}case`list`:{let e=ze();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=Le(n);console.log(e?`Deleted stash entry: ${n}`:`No stash entry found: ${n}`);return}case`clear`:{let e=Ie();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=Se();if(e.length===0){console.log(`No active lanes.`);return}for(let t of e)console.log(`${t.name} (${t.sourceFiles.length} files, created ${t.createdAt})`);return}let n=e.shift();switch(n||(console.error(`Lane name is required for "${t}".`),process.exit(1)),t){case`create`:{let t=N(e,`--files`,``);t||(console.error(`Usage: aikit lane create <name> --files file1.ts,file2.ts`),process.exit(1));let r=ye(n,t.split(`,`).map(e=>e.trim()));console.log(`Lane "${r.name}" created with ${r.sourceFiles.length} files.`);break}case`status`:{let e=we(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=be(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=Ce(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=xe(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=Ee();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=w(n);console.log(`Queue "${e.name}" created.`);break}case`push`:{let t=Oe(n,e.join(` `)||`Untitled task`);console.log(`Pushed "${t.title}" (${t.id}) to queue "${n}".`);break}case`next`:{let e=De(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=E(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=D(n,t,r);console.log(`Marked "${i.title}" as failed: ${r}`);break}case`get`:{let e=O(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=C(n);console.log(`Cleared ${e} completed/failed items from queue "${n}".`);break}case`delete`:{let e=T(n);console.log(e?`Queue "${n}" deleted.`:`Queue "${n}" not found.`);break}}}}],Q=[...kt,...Ot,...nt,...Dt,...At,...xt,...yt,...Nt,...bt,...Mt,...q];Q.push({name:`help`,description:`Show available commands`,run:async()=>{$()}});async function Pt(e){let t=[...e],n=t.shift();if(!n||n===`--help`||n===`-h`){$();return}if(n===`--version`||n===`-v`){let e=l(s(u(import.meta.url)),`..`,`..`,`..`,`package.json`),t=JSON.parse(a(e,`utf-8`));console.log(t.version);return}if(n&&new Set([`--user`,`--workspace`,`--guide`,`--smart`]).has(n)){let e=Q.find(e=>e.name===`init`);if(e){await e.run([n,...t]);return}}let r=Q.find(e=>e.name===n);r||(console.error(`Unknown command: ${n}`),$(),process.exit(1));try{await r.run(t)}finally{let e=Et();e&&await e.store.close()}}function $(){console.log(`@vpxa/aikit — Local-first AI developer toolkit
|
|
14
14
|
`),console.log(`Usage: aikit <command> [options]
|
|
15
15
|
`),console.log(`Commands:`);let e=Math.max(...Q.map(e=>e.name.length));for(let t of Q)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{Pt as run};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{i as e,n as t,r as n,t as r}from"./constants-
|
|
1
|
+
import{i as e,n as t,r as n,t as r}from"./constants-BHJ95m41.js";import{n as i,t as a}from"./templates-DVcEiTlc.js";import{guideFlows as o,guideScaffold as s,guideSkills as c,smartCopyClaudeCommands as l,smartCopyFlows as u,smartCopyScaffold as d,smartCopySkills as f}from"./scaffold-D664MT9M.js";import{appendFileSync as p,existsSync as m,mkdirSync as h,readFileSync as g,unlinkSync as _,writeFileSync as v}from"node:fs";import{basename as y,dirname as b,join as x,resolve as S}from"node:path";import{fileURLToPath as C}from"node:url";import{AIKIT_PATHS as w,isUserInstalled as T}from"../../core/dist/index.js";function E(e){return m(S(e,`.cursor`))?`cursor`:m(S(e,`.claude`))?`claude-code`:m(S(e,`.windsurf`))?`windsurf`:`copilot`}function D(e){return{servers:{[e]:{...t}}}}function O(e){let{type:n,...r}=t;return{mcpServers:{[e]:r}}}const k={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);m(r)||(h(n,{recursive:!0}),v(r,`${JSON.stringify(D(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`);h(n,{recursive:!0}),v(r,i(y(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,t){v(S(e,`AGENTS.md`),a(y(e),t),`utf-8`),console.log(` Updated AGENTS.md`)}},A={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.mcp.json`);m(n)||(v(n,`${JSON.stringify(O(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,t){let n=S(e,`CLAUDE.md`),r=y(e);v(n,`${i(r,t)}\n---\n\n${a(r,t)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},j={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.cursor`),r=S(n,`mcp.json`);m(r)||(h(n,{recursive:!0}),v(r,`${JSON.stringify(O(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`);h(n,{recursive:!0});let o=y(e);v(r,`${i(o,t)}\n---\n\n${a(o,t)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let s=S(n,`kb.mdc`);m(s)&&s!==r&&(_(s),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},M={scaffoldDir:`general`,writeMcpConfig(e,t){let n=S(e,`.vscode`),r=S(n,`mcp.json`);m(r)||(h(n,{recursive:!0}),v(r,`${JSON.stringify(D(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,t){let n=S(e,`.windsurfrules`),r=y(e);v(n,`${i(r,t)}\n---\n\n${a(r,t)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}};function N(e){switch(e){case`copilot`:return k;case`claude-code`:return A;case`cursor`:return j;case`windsurf`:return M}}const P={serverName:n,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:`mixedbread-ai/mxbai-embed-large-v1`,dimensions:1024},store:{backend:`lancedb`,path:`${w.data}/lance`},curated:{path:w.aiCurated}};function F(e,t){let n=S(e,`aikit.config.json`);return m(n)&&!t?(console.log(`aikit.config.json already exists. Use --force to overwrite.`),!1):(v(n,`${JSON.stringify(P,null,2)}\n`,`utf-8`),console.log(` Created aikit.config.json`),!0)}function I(e){let t=S(e,`.gitignore`),n=[{dir:`${w.data}/`,label:`AI Kit vector store`},{dir:`${w.state}/`,label:`AI Kit session state`},{dir:`${w.restorePoints}/`,label:`Restore points (codemod/rename undo snapshots)`},{dir:`${w.brainstorm}/`,label:`Brainstorming sessions`},{dir:`${w.handoffs}/`,label:`Handoff documents`}];if(m(t)){let e=g(t,`utf-8`),r=n.filter(t=>!e.includes(t.dir));r.length>0&&(p(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 v(t,`${n.map(e=>`# ${e.label}\n${e.dir}`).join(`
|
|
3
3
|
`)}\n`,`utf-8`),console.log(` Created .gitignore with AI Kit entries`)}function L(){return P.serverName}const R=[`decisions`,`patterns`,`conventions`,`troubleshooting`];function z(e){let t=S(e,`.ai`,`curated`);m(t)||(h(t,{recursive:!0}),console.log(` Created .ai/curated/`));for(let e of R){let n=S(t,e);m(n)||h(n,{recursive:!0})}console.log(` Created .ai/curated/{${R.join(`,`)}}/`)}function B(e){let t=e;for(let e=0;e<10;e++){try{let e=x(t,`package.json`);if(m(e)&&JSON.parse(g(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=b(t);if(e===t)break;t=e}return S(e,`..`,`..`,`..`)}async function V(t){let n=process.cwd();if(!F(n,t.force))return;I(n);let i=L(),a=N(E(n));a.writeMcpConfig(n,i),a.writeInstructions(n,i),a.writeAgentsMd(n,i);let o=B(b(C(import.meta.url))),s=JSON.parse(g(S(o,`package.json`),`utf-8`)).version;await f(n,o,[...e],s,t.force),await u(n,o,[...r],s,t.force),await d(n,o,`copilot`,s,t.force),await l(n,o,s,t.force),z(n),console.log(`
|
|
4
4
|
AI Kit initialized! Next steps:`),console.log(` aikit reindex Index your codebase`),console.log(` aikit search Search indexed content`),console.log(` aikit serve Start MCP server for IDE integration`),T()&&console.log(`
|
|
@@ -43,9 +43,9 @@ Even then, use \`file_summary\` first to identify which lines to read.
|
|
|
43
43
|
|
|
44
44
|
## Core Rules
|
|
45
45
|
|
|
46
|
-
1. **
|
|
46
|
+
1. **Recall before acting** — \`search({ query })\` for past decisions/conventions about the area you're changing. If a prior decision exists, **follow it** — don't silently override. Then \`scope_map({ task })\` for a reading plan.
|
|
47
47
|
2. **Compress, don't read** — \`file_summary\` → \`compact\` → \`digest\`. NEVER raw-read a file to "understand" it.
|
|
48
|
-
3. **Remember** — \`search({ query: "SESSION CHECKPOINT", origin: "curated" })\` at session start. \`remember()\` decisions at session end.
|
|
48
|
+
3. **Remember** — \`search({ query: "SESSION CHECKPOINT", origin: "curated" })\` at session start. \`remember()\` decisions at session end. Auto-knowledge captures conventions and patterns from tool outputs automatically.
|
|
49
49
|
4. **Validate** — \`check({})\` + \`test_run({})\` before presenting changes. \`blast_radius({ changed_files })\` for impact.
|
|
50
50
|
5. **Lifecycle** — Check \`status({})\` first. If onboard not run, run \`onboard({ path: "." })\`. After implementation, \`reindex({})\` + \`produce_knowledge({})\`. At session end, \`remember()\` checkpoint.
|
|
51
51
|
|
|
@@ -67,6 +67,21 @@ When you need to explain something or ask for user input:
|
|
|
67
67
|
- Free-form text input always goes through elicitation, even when using \`present\` for the explanation
|
|
68
68
|
- Prefer the simplest method that adequately conveys the information
|
|
69
69
|
|
|
70
|
+
## Communication Style
|
|
71
|
+
|
|
72
|
+
**Terse by default.** All responses use compressed communication unless user requests otherwise.
|
|
73
|
+
|
|
74
|
+
**Default (always active):**
|
|
75
|
+
- Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course), hedging
|
|
76
|
+
- Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for")
|
|
77
|
+
- Abbreviate common terms: DB/auth/config/req/res/fn/impl/deps/env
|
|
78
|
+
- Arrows for causality (X → Y). Pattern: \`[thing] [action] [reason]. [next step].\`
|
|
79
|
+
- Code blocks, technical terms, and error messages stay exact
|
|
80
|
+
|
|
81
|
+
**Disable with:** "full", "detail", "explain" — next response uses full verbose prose, then resumes terse.
|
|
82
|
+
|
|
83
|
+
**Always verbose regardless of mode:** security warnings, irreversible action confirmations, multi-step sequences where fragments risk misread.
|
|
84
|
+
|
|
70
85
|
## Custom Agents
|
|
71
86
|
|
|
72
87
|
This project has specialized agents in \`.github/agents/\`. Use them instead of built-in modes:
|
|
@@ -87,6 +102,8 @@ Check \`.github/agents/\` for the full list of available agents.
|
|
|
87
102
|
|
|
88
103
|
AI Kit provides cross-session persistent memory. **Use it actively** — decisions, patterns, and context that survive between conversations.
|
|
89
104
|
|
|
105
|
+
Auto-knowledge also captures facts automatically from tool outputs (conventions detected, errors encountered, test results, research findings). These are searchable alongside manually stored entries.
|
|
106
|
+
|
|
90
107
|
| Action | Tool | Example |
|
|
91
108
|
|--------|------|---------|
|
|
92
109
|
| Store | \`remember\` | \`remember({ title: "Auth uses JWT RS256", content: "...", category: "decisions" })\` |
|
|
@@ -98,6 +115,14 @@ AI Kit provides cross-session persistent memory. **Use it actively** — decisio
|
|
|
98
115
|
|
|
99
116
|
**Categories:** \`conventions\`, \`decisions\`, \`patterns\`, \`context\`, \`session\`
|
|
100
117
|
|
|
118
|
+
**Task-level recall** (do BEFORE implementing any feature):
|
|
119
|
+
\`\`\`
|
|
120
|
+
search({ query: "keywords about what you're building" }) // check past decisions
|
|
121
|
+
list({ category: "decisions" }) // scan recent decisions
|
|
122
|
+
// If results exist → read and follow them
|
|
123
|
+
// If no results → proceed, then remember() your decisions
|
|
124
|
+
\`\`\`
|
|
125
|
+
|
|
101
126
|
**Session checkpoint** (do at end of every session):
|
|
102
127
|
\`\`\`
|
|
103
128
|
remember({ title: "Session checkpoint: <topic>", content: "Done: ... / Decisions: ... / Next: ... / Blockers: ...", category: "session" })
|
|
@@ -173,69 +198,6 @@ Need to understand a file?
|
|
|
173
198
|
|
|
174
199
|
---
|
|
175
200
|
|
|
176
|
-
## Guidelines
|
|
177
|
-
|
|
178
|
-
Behavioral guidelines to reduce common LLM coding mistakes. Apply when writing, reviewing, or refactoring code.
|
|
179
|
-
|
|
180
|
-
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
|
|
181
|
-
|
|
182
|
-
### 1. Think Before Coding
|
|
183
|
-
|
|
184
|
-
**Don't assume. Don't hide confusion. Surface tradeoffs.**
|
|
185
|
-
|
|
186
|
-
- State assumptions explicitly. If uncertain, ask.
|
|
187
|
-
- If multiple interpretations exist, present them — don't pick silently.
|
|
188
|
-
- If a simpler approach exists, say so. Push back when warranted.
|
|
189
|
-
- If something is unclear, stop. Name what's confusing. Ask.
|
|
190
|
-
|
|
191
|
-
### 2. Simplicity First
|
|
192
|
-
|
|
193
|
-
**Minimum code that solves the problem. Nothing speculative.**
|
|
194
|
-
|
|
195
|
-
- No features beyond what was asked.
|
|
196
|
-
- No abstractions for single-use code.
|
|
197
|
-
- No "flexibility" or "configurability" that wasn't requested.
|
|
198
|
-
- No error handling for impossible scenarios.
|
|
199
|
-
- If you write 200 lines and it could be 50, rewrite it.
|
|
200
|
-
|
|
201
|
-
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
|
|
202
|
-
|
|
203
|
-
### 3. Surgical Changes
|
|
204
|
-
|
|
205
|
-
**Touch only what you must. Clean up only your own mess.**
|
|
206
|
-
|
|
207
|
-
When editing existing code:
|
|
208
|
-
- Don't "improve" adjacent code, comments, or formatting.
|
|
209
|
-
- Don't refactor things that aren't broken.
|
|
210
|
-
- Match existing style, even if you'd do it differently.
|
|
211
|
-
- If you notice unrelated dead code, mention it — don't delete it.
|
|
212
|
-
|
|
213
|
-
When your changes create orphans:
|
|
214
|
-
- Remove imports/variables/functions that YOUR changes made unused.
|
|
215
|
-
- Don't remove pre-existing dead code unless asked.
|
|
216
|
-
|
|
217
|
-
The test: Every changed line should trace directly to the user's request.
|
|
218
|
-
|
|
219
|
-
### 4. Goal-Driven Execution
|
|
220
|
-
|
|
221
|
-
**Define success criteria. Loop until verified.**
|
|
222
|
-
|
|
223
|
-
Transform tasks into verifiable goals:
|
|
224
|
-
- "Add validation" → "Write tests for invalid inputs, then make them pass"
|
|
225
|
-
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
|
|
226
|
-
- "Refactor X" → "Ensure tests pass before and after"
|
|
227
|
-
|
|
228
|
-
For multi-step tasks, state a brief plan:
|
|
229
|
-
\`\`\`
|
|
230
|
-
1. [Step] → verify: [check]
|
|
231
|
-
2. [Step] → verify: [check]
|
|
232
|
-
3. [Step] → verify: [check]
|
|
233
|
-
\`\`\`
|
|
234
|
-
|
|
235
|
-
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
|
|
236
|
-
|
|
237
|
-
---
|
|
238
|
-
|
|
239
201
|
## Full Documentation
|
|
240
202
|
|
|
241
203
|
For complete tool documentation (82 tools), workflow chains, search strategies, session protocol, and persistent memory patterns, load the \`aikit\` skill at session start.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as e,n as t,r as n}from"./constants-BSGpNyrr.js";import{n as r,t as i}from"./templates-DrkDLz-X.js";import{loadAdapter as a,n as o,r as s,smartCopyFromMemory as c,t as l}from"./scaffold-D664MT9M.js";import{existsSync as u,mkdirSync as d,readFileSync as f,readdirSync as p,rmSync as m,unlinkSync as h,writeFileSync as g}from"node:fs";import{dirname as _,join as v,posix as y,resolve as b,win32 as x}from"node:path";import{fileURLToPath as S}from"node:url";import{mkdir as C,readFile as w,rename as T,unlink as E,writeFile as D}from"node:fs/promises";import{getGlobalDataDir as O,saveRegistry as k}from"../../core/dist/index.js";import{execFileSync as A}from"node:child_process";import{randomUUID as j}from"node:crypto";import{homedir as M}from"node:os";var N=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!u(t))return{};let n=await w(t,`utf-8`);try{return JSON.parse(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=_(n),i=v(r,`.aikit-tmp-${j()}.json`);await C(r,{recursive:!0});try{await D(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await T(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}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}},P=class extends N{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(this.getPathModule().resolve(M(),`.claude`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.claude`,`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?x:y}},F=class extends N{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(this.getPathModule().resolve(M(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getPathModule(){return process.platform===`win32`?x:y}},I=class extends N{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 u(e)||t!==null&&u(t)}return u(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=M();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?x:y}},L=class extends N{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(b(M(),`.copilot`)):!1}getConfigPath(){return b(M(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return b(M(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=b(M(),`.copilot`);return{agents:b(e,`agents`),skills:b(e,`skills`),prompts:null,flows:b(e,`flows`),commands:null,instructions:b(M(),`.github`,`copilot-instructions.md`),manifest:b(e,`.aikit-scaffold.json`)}}},R=class extends I{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.mdc`)}},z=class extends I{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.mdc`)}},B=class e extends N{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`workspace`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;let t=this.getJetBrainsBaseDir();if(!u(t))return!1;try{return p(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(e){if(!e)throw Error(`IntelliJ adapter requires projectRoot (scope: workspace)`);return b(e,`mcp.json`)}async registerMcp(e,t,n){let r={type:`stdio`,...t};await super.registerMcp(e,r,n)}getScaffoldRoot(e){return e?b(e,`.github`,`agents`):null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return e?{agents:b(e,`.github`,`agents`),skills:null,prompts:null,flows:null,commands:null,instructions:b(e,`AGENTS.md`),manifest:null}:{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null}}buildInstructionContent(e,t){return t}getJetBrainsBaseDir(){let e=M();return process.platform===`win32`?b(process.env.APPDATA??b(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?b(e,`Library`,`Application Support`,`JetBrains`):b(process.env.XDG_CONFIG_HOME??b(e,`.config`),`JetBrains`)}},V=class extends I{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.md`)}},H=class extends I{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},U=class extends I{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},W=class extends I{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},G=class extends I{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.md`)}},K=class extends N{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(this.getPathModule().resolve(M(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getPathModule(){return process.platform===`win32`?x:y}};const q=[new H,new U,new W,new R,new z,new G,new V,new L,new B,new P,new K,new F];function J(){return[...q]}async function Y(e){let t=e?.scope?q.filter(t=>t.scope===e.scope):q;return(await Promise.allSettled(t.map(async e=>await e.detect()?e:null))).flatMap(e=>e.status!==`fulfilled`||e.value===null?[]:[e.value])}function X(e){let t=e;for(let e=0;e<10;e++){try{let e=v(t,`package.json`);if(u(e)&&JSON.parse(f(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=_(t);if(e===t)break;t=e}return b(e,`..`,`..`,`..`)}function Z(){let e={command:t.command,args:t.args?[...t.args]:void 0,type:t.type};if(process.platform!==`win32`){let t=process.env.PATH;t&&(e.env={PATH:t});try{let t=A(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();t&&u(t)&&(e.command=t)}catch{}}return e}const Q=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function $(t,n=!1){if(!Q.has(t.name))return;let r=b(_(t.getConfigPath()),`settings.json`),i={};if(u(r))try{let e=f(r,`utf-8`);i=JSON.parse(e)}catch{console.log(` ${t.name}: skipped settings.json (invalid JSON)`);return}let a=!1;for(let[t,r]of Object.entries(e))if(typeof r==`object`&&r){let e=typeof i[t]==`object`&&i[t]!==null?i[t]:{},n={...e,...r};JSON.stringify(n)!==JSON.stringify(e)&&(i[t]=n,a=!0)}else (n||!(t in i))&&(i[t]=r,a=!0);a&&(g(r,`${JSON.stringify(i,null,2)}\n`,`utf-8`),console.log(` ${t.name}: updated settings.json`))}async function ee(e,t,n,f,p=!1){let h=new Map;for(let e of t)e.getScaffoldRoot()!==null&&h.set(e.id,e);if(t.some(e=>Q.has(e.name))){let e=J().find(e=>e.id===`copilot-cli`);e&&h.set(e.id,e)}if(h.size===0){console.log(` No IDEs with global scaffold support detected.`);return}let v=await a(e,`copilot`),y=new Map;for(let e of v){let t=e.path.indexOf(`/`);if(t===-1)continue;let n=e.path.substring(0,t);if(n!==`agents`&&n!==`prompts`)continue;let r=y.get(n)??[];r.push({path:e.path.substring(t+1),content:e.content}),y.set(n,r)}let x=await a(e,`skills`),S=new Set;for(let e of x){let t=e.path.indexOf(`/`);t!==-1&&S.add(e.path.substring(0,t))}let C=await a(e,`flows`),w=new Set;for(let e of C){let t=e.path.indexOf(`/`);t!==-1&&w.add(e.path.substring(0,t))}let T=await a(e,`claude-code`),E=new Set,D=new Set,O=new Set,k=(e,t,n)=>{let r=y.get(n);if(!e||!t||!r||r.length===0)return;let i=`${n}:${t}:${e}`;if(E.has(i))return;E.add(i);let a=o(t)??l(f);a.version=f,c(r,e,a,n,p),s(t,a),O.add(_(t))},A=(e,t,n,r)=>{if(!e||!t||r.length===0)return;let i=`${n}:${t}:${e}`;if(E.has(i))return;if(E.add(i),n===`flows`&&!D.has(e)){for(let n of w){let r=b(e,n,`skills`);u(r)&&(m(r,{recursive:!0,force:!0}),console.log(` ${_(t)}: migrated ${n} flow to steps/ layout`))}D.add(e)}let a=o(t)??l(f);a.version=f,c(r,e,a,n,p),s(t,a),O.add(_(t))};for(let e of h.values()){let t=e.getScaffoldPaths();k(t.agents,t.manifest,`agents`),k(t.prompts,t.manifest,`prompts`),A(t.skills,t.manifest,`skills`,x),A(t.flows,t.manifest,`flows`,C),A(t.commands,t.manifest,`commands`,T)}for(let e of O)console.log(` ${e}: scaffold updated (${S.size} skills)`);let j=new Set,M=r(`aikit`,n),N=i(`aikit`,n);for(let e of h.values()){let t=e.getScaffoldPaths().instructions;!t||j.has(t)||(d(_(t),{recursive:!0}),g(t,e.buildInstructionContent(M,N),`utf-8`),j.add(t))}j.size>0&&console.log(` Instruction files: ${[...j].join(`, `)}`)}function te(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e)if(Q.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(b(r,`kb.instructions.md`)),t.push(b(r,`aikit.instructions.md`))}else n.name===`Cursor`||n.name===`Cursor Nightly`?t.push(b(e,`rules`,`kb.mdc`)):n.name===`Windsurf`&&t.push(b(e,`rules`,`kb.md`))}for(let e of t)u(e)&&(h(e),console.log(` Removed legacy file: ${e}`))}async function ne(e){let t=n,r=X(_(S(import.meta.url))),i=JSON.parse(f(b(r,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${i}...\n`);let a=O();d(a,{recursive:!0}),console.log(` Global data store: ${a}`),k({version:1,workspaces:{}}),console.log(` Created registry.json`);let o=await Y({scope:`user`});if(o.length===0)console.log(`
|
|
1
|
+
import{a as e,n as t,r as n}from"./constants-BHJ95m41.js";import{n as r,t as i}from"./templates-DVcEiTlc.js";import{loadAdapter as a,n as o,r as s,smartCopyFromMemory as c,t as l}from"./scaffold-D664MT9M.js";import{existsSync as u,mkdirSync as d,readFileSync as f,readdirSync as p,rmSync as m,unlinkSync as h,writeFileSync as g}from"node:fs";import{dirname as _,join as v,posix as y,resolve as b,win32 as x}from"node:path";import{fileURLToPath as S}from"node:url";import{mkdir as C,readFile as w,rename as T,unlink as E,writeFile as D}from"node:fs/promises";import{getGlobalDataDir as O,saveRegistry as k}from"../../core/dist/index.js";import{execFileSync as A}from"node:child_process";import{randomUUID as j}from"node:crypto";import{homedir as M}from"node:os";var N=class{isPlatformSupported(){return this.platforms.includes(process.platform)}async readConfig(e){let t=this.getConfigPath(e);if(!u(t))return{};let n=await w(t,`utf-8`);try{return JSON.parse(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=_(n),i=v(r,`.aikit-tmp-${j()}.json`);await C(r,{recursive:!0});try{await D(i,`${JSON.stringify(e,null,2)}\n`,`utf-8`),await T(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}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}},P=class extends N{id=`claude-code`;name=`Claude Code`;family=`claude`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(this.getPathModule().resolve(M(),`.claude`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.claude`,`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.claude`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.claude`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:e.resolve(t,`commands`),instructions:e.resolve(t,`CLAUDE.md`),manifest:e.resolve(t,`.aikit-scaffold.json`)}}buildInstructionContent(e,t){return`${e}\n---\n\n${t}`}getPathModule(){return process.platform===`win32`?x:y}},F=class extends N{id=`codex-cli`;name=`Codex CLI`;family=`codex`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(this.getPathModule().resolve(M(),`.codex`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.codex`,`config.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.codex`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.codex`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getPathModule(){return process.platform===`win32`?x:y}},I=class extends N{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 u(e)||t!==null&&u(t)}return u(e)}getConfigPath(){return this.getPathModule().resolve(this.getConfigDir(),`mcp.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),this.scaffoldBase)}getInstructionsRoot(){let e=this.getInstructionFilePath();return e?this.getPathModule().dirname(e):null}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),this.scaffoldBase);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:e.resolve(this.getConfigDir(),`prompts`),flows:e.resolve(t,`flows`),commands:null,instructions:this.getInstructionFilePath(),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getConfigDir(){let e=this.getPathModule(),t=M();if(process.platform===`win32`){let n=process.env.APPDATA??e.resolve(t,`AppData`,`Roaming`);return e.resolve(n,this.configDirName,`User`)}if(process.platform===`darwin`)return e.resolve(t,`Library`,`Application Support`,this.configDirName,`User`);let n=process.env.XDG_CONFIG_HOME??e.resolve(t,`.config`);return e.resolve(n,this.configDirName,`User`)}getMacAppPath(){return null}getInstructionFilePath(){return null}getPathModule(){return process.platform===`win32`?x:y}},L=class extends N{id=`copilot-cli`;name=`Copilot CLI`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(b(M(),`.copilot`)):!1}getConfigPath(){return b(M(),`.copilot`,`mcp-config.json`)}async registerMcp(e,t,n){let r={...t,tools:[`*`]},i=await this.readConfig(n);i[this.configKey]||(i[this.configKey]={}),i[this.configKey][e]=r,await this.writeConfig(i,n)}getScaffoldRoot(){return b(M(),`.copilot`)}getInstructionsRoot(){return null}getScaffoldPaths(){let e=b(M(),`.copilot`);return{agents:b(e,`agents`),skills:b(e,`skills`),prompts:null,flows:b(e,`flows`),commands:null,instructions:b(M(),`.github`,`copilot-instructions.md`),manifest:b(e,`.aikit-scaffold.json`)}}},R=class extends I{id=`cursor`;name=`Cursor`;configKey=`mcpServers`;configDirName=`Cursor`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.mdc`)}},z=class extends I{id=`cursor-nightly`;name=`Cursor Nightly`;configKey=`mcpServers`;configDirName=`Cursor Nightly`;scaffoldBase=`.cursor`;getMacAppPath(){return`/Applications/Cursor Nightly.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.mdc`)}},B=class e extends N{id=`intellij`;name=`IntelliJ IDEA`;family=`copilot`;platforms=[`win32`,`darwin`,`linux`];scope=`workspace`;configKey=`servers`;static PRODUCTS=[`IntelliJIdea`,`IdeaIC`,`WebStorm`,`PyCharm`,`PyCharmCE`,`GoLand`,`PhpStorm`,`CLion`,`Rider`,`RubyMine`,`RustRover`,`DataGrip`];async detect(){if(!this.isPlatformSupported())return!1;let t=this.getJetBrainsBaseDir();if(!u(t))return!1;try{return p(t,{withFileTypes:!0}).some(t=>t.isDirectory()&&e.PRODUCTS.some(e=>t.name.startsWith(e)))}catch{return!1}}getConfigPath(e){if(!e)throw Error(`IntelliJ adapter requires projectRoot (scope: workspace)`);return b(e,`mcp.json`)}async registerMcp(e,t,n){let r={type:`stdio`,...t};await super.registerMcp(e,r,n)}getScaffoldRoot(e){return e?b(e,`.github`,`agents`):null}getInstructionsRoot(e){return null}getScaffoldPaths(e){return e?{agents:b(e,`.github`,`agents`),skills:null,prompts:null,flows:null,commands:null,instructions:b(e,`AGENTS.md`),manifest:null}:{agents:null,skills:null,prompts:null,flows:null,commands:null,instructions:null,manifest:null}}buildInstructionContent(e,t){return t}getJetBrainsBaseDir(){let e=M();return process.platform===`win32`?b(process.env.APPDATA??b(e,`AppData`,`Roaming`),`JetBrains`):process.platform===`darwin`?b(e,`Library`,`Application Support`,`JetBrains`):b(process.env.XDG_CONFIG_HOME??b(e,`.config`),`JetBrains`)}},V=class extends I{id=`trae`;name=`Trae`;configKey=`servers`;configDirName=`Trae`;scaffoldBase=`.trae`;getMacAppPath(){return`/Applications/Trae.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.md`)}},H=class extends I{id=`vscode`;name=`VS Code`;configKey=`servers`;configDirName=`Code`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},U=class extends I{id=`vscode-insiders`;name=`VS Code Insiders`;configKey=`servers`;configDirName=`Code - Insiders`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/Visual Studio Code - Insiders.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},W=class extends I{id=`vscodium`;name=`VSCodium`;configKey=`servers`;configDirName=`VSCodium`;scaffoldBase=`.copilot`;hasInstructions=!0;getMacAppPath(){return`/Applications/VSCodium.app`}getInstructionFilePath(){return this.hasInstructions?this.getPathModule().resolve(M(),this.scaffoldBase,`instructions`,`copilot-instructions.md`):null}buildInstructionContent(e,t){return`---\napplyTo: "**"\n---\n\n${e}\n---\n\n${t}`}},G=class extends I{id=`windsurf`;name=`Windsurf`;configKey=`servers`;configDirName=`Windsurf`;scaffoldBase=`.windsurf`;getMacAppPath(){return`/Applications/Windsurf.app`}getInstructionFilePath(){return this.getPathModule().resolve(M(),this.scaffoldBase,`rules`,`aikit.md`)}},K=class extends N{id=`gemini-cli`;name=`Gemini CLI`;family=`gemini`;platforms=[`win32`,`darwin`,`linux`];scope=`user`;configKey=`mcpServers`;async detect(){return this.isPlatformSupported()?u(this.getPathModule().resolve(M(),`.gemini`)):!1}getConfigPath(){return this.getPathModule().resolve(M(),`.gemini`,`settings.json`)}getScaffoldRoot(){return this.getPathModule().resolve(M(),`.gemini`)}getScaffoldPaths(){let e=this.getPathModule(),t=e.resolve(M(),`.gemini`);return{agents:e.resolve(t,`agents`),skills:e.resolve(t,`skills`),prompts:null,flows:e.resolve(t,`flows`),commands:null,instructions:e.resolve(t,`AGENTS.md`),manifest:e.resolve(t,`.aikit-scaffold.json`)}}getPathModule(){return process.platform===`win32`?x:y}};const q=[new H,new U,new W,new R,new z,new G,new V,new L,new B,new P,new K,new F];function J(){return[...q]}async function Y(e){let t=e?.scope?q.filter(t=>t.scope===e.scope):q;return(await Promise.allSettled(t.map(async e=>await e.detect()?e:null))).flatMap(e=>e.status!==`fulfilled`||e.value===null?[]:[e.value])}function X(e){let t=e;for(let e=0;e<10;e++){try{let e=v(t,`package.json`);if(u(e)&&JSON.parse(f(e,`utf8`)).name===`@vpxa/aikit`)return t}catch{}let e=_(t);if(e===t)break;t=e}return b(e,`..`,`..`,`..`)}function Z(){let e={command:t.command,args:t.args?[...t.args]:void 0,type:t.type};if(process.platform!==`win32`){let t=process.env.PATH;t&&(e.env={PATH:t});try{let t=A(`which`,[`node`],{encoding:`utf-8`,timeout:3e3}).trim();t&&u(t)&&(e.command=t)}catch{}}return e}const Q=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function $(t,n=!1){if(!Q.has(t.name))return;let r=b(_(t.getConfigPath()),`settings.json`),i={};if(u(r))try{let e=f(r,`utf-8`);i=JSON.parse(e)}catch{console.log(` ${t.name}: skipped settings.json (invalid JSON)`);return}let a=!1;for(let[t,r]of Object.entries(e))if(typeof r==`object`&&r){let e=typeof i[t]==`object`&&i[t]!==null?i[t]:{},n={...e,...r};JSON.stringify(n)!==JSON.stringify(e)&&(i[t]=n,a=!0)}else (n||!(t in i))&&(i[t]=r,a=!0);a&&(g(r,`${JSON.stringify(i,null,2)}\n`,`utf-8`),console.log(` ${t.name}: updated settings.json`))}async function ee(e,t,n,f,p=!1){let h=new Map;for(let e of t)e.getScaffoldRoot()!==null&&h.set(e.id,e);if(t.some(e=>Q.has(e.name))){let e=J().find(e=>e.id===`copilot-cli`);e&&h.set(e.id,e)}if(h.size===0){console.log(` No IDEs with global scaffold support detected.`);return}let v=await a(e,`copilot`),y=new Map;for(let e of v){let t=e.path.indexOf(`/`);if(t===-1)continue;let n=e.path.substring(0,t);if(n!==`agents`&&n!==`prompts`)continue;let r=y.get(n)??[];r.push({path:e.path.substring(t+1),content:e.content}),y.set(n,r)}let x=await a(e,`skills`),S=new Set;for(let e of x){let t=e.path.indexOf(`/`);t!==-1&&S.add(e.path.substring(0,t))}let C=await a(e,`flows`),w=new Set;for(let e of C){let t=e.path.indexOf(`/`);t!==-1&&w.add(e.path.substring(0,t))}let T=await a(e,`claude-code`),E=new Set,D=new Set,O=new Set,k=(e,t,n)=>{let r=y.get(n);if(!e||!t||!r||r.length===0)return;let i=`${n}:${t}:${e}`;if(E.has(i))return;E.add(i);let a=o(t)??l(f);a.version=f,c(r,e,a,n,p),s(t,a),O.add(_(t))},A=(e,t,n,r)=>{if(!e||!t||r.length===0)return;let i=`${n}:${t}:${e}`;if(E.has(i))return;if(E.add(i),n===`flows`&&!D.has(e)){for(let n of w){let r=b(e,n,`skills`);u(r)&&(m(r,{recursive:!0,force:!0}),console.log(` ${_(t)}: migrated ${n} flow to steps/ layout`))}D.add(e)}let a=o(t)??l(f);a.version=f,c(r,e,a,n,p),s(t,a),O.add(_(t))};for(let e of h.values()){let t=e.getScaffoldPaths();k(t.agents,t.manifest,`agents`),k(t.prompts,t.manifest,`prompts`),A(t.skills,t.manifest,`skills`,x),A(t.flows,t.manifest,`flows`,C),A(t.commands,t.manifest,`commands`,T)}for(let e of O)console.log(` ${e}: scaffold updated (${S.size} skills)`);let j=new Set,M=r(`aikit`,n),N=i(`aikit`,n);for(let e of h.values()){let t=e.getScaffoldPaths().instructions;!t||j.has(t)||(d(_(t),{recursive:!0}),g(t,e.buildInstructionContent(M,N),`utf-8`),j.add(t))}j.size>0&&console.log(` Instruction files: ${[...j].join(`, `)}`)}function te(e){let t=[];for(let n of e){let e=n.getScaffoldRoot();if(e)if(Q.has(n.name)){let r=n.getInstructionsRoot()??e;t.push(b(r,`kb.instructions.md`)),t.push(b(r,`aikit.instructions.md`))}else n.name===`Cursor`||n.name===`Cursor Nightly`?t.push(b(e,`rules`,`kb.mdc`)):n.name===`Windsurf`&&t.push(b(e,`rules`,`kb.md`))}for(let e of t)u(e)&&(h(e),console.log(` Removed legacy file: ${e}`))}async function ne(e){let t=n,r=X(_(S(import.meta.url))),i=JSON.parse(f(b(r,`package.json`),`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${i}...\n`);let a=O();d(a,{recursive:!0}),console.log(` Global data store: ${a}`),k({version:1,workspaces:{}}),console.log(` Created registry.json`);let o=await Y({scope:`user`});if(o.length===0)console.log(`
|
|
2
2
|
No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${o.length} IDE(s):`);let n=Z();for(let e of o)try{await e.registerMcp(t,n),console.log(` ${e.name}: configured ${t}`)}catch(t){console.log(` ${e.name}: failed to configure (${t.message})`)}for(let t of o)$(t,e.force)}console.log(`
|
|
3
3
|
Installing scaffold files:`),await ee(r,o,t,i,e.force),te(o),console.log(`
|
|
4
4
|
User-level AI Kit installation complete!`),console.log(`
|
|
@@ -11,6 +11,25 @@ const e={Orchestrator:e=>`You orchestrate the full development lifecycle: **plan
|
|
|
11
11
|
|
|
12
12
|
${e}
|
|
13
13
|
|
|
14
|
+
### Agent Dispatch Rules
|
|
15
|
+
|
|
16
|
+
**Match the task to the RIGHT specialist. Implementer is NOT the default for everything.**
|
|
17
|
+
|
|
18
|
+
| Signal in task | Dispatch to | NOT to |
|
|
19
|
+
|----------------|-------------|--------|
|
|
20
|
+
| Bug, error, stack trace, "fix ...", "doesn't work", flaky test, regression | **Debugger** | ~~Implementer~~ |
|
|
21
|
+
| "Refactor", "cleanup", "simplify", extract, rename-at-scale, reduce complexity, DRY | **Refactor** | ~~Implementer~~ |
|
|
22
|
+
| UI, component, styling, responsive, layout, animation, accessibility, CSS | **Frontend** | ~~Implementer~~ |
|
|
23
|
+
| New feature, implement, add endpoint, build, create, wire up | **Implementer** | — |
|
|
24
|
+
| Security audit, vulnerability, CVE, auth hardening, input sanitization | **Security** | ~~Implementer~~ |
|
|
25
|
+
| Docs, README, API docs, changelog, migration guide | **Documenter** | ~~Implementer~~ |
|
|
26
|
+
|
|
27
|
+
**Compound tasks** (e.g., "fix the bug then refactor the module"):
|
|
28
|
+
- Split into sequential batches: Debugger first → then Refactor
|
|
29
|
+
- NEVER send both concerns to Implementer as a single dispatch
|
|
30
|
+
|
|
31
|
+
**When uncertain:** If the task contains "fix" or "broken" or "error" → it's Debugger. If it contains "clean up" or "improve structure" → it's Refactor. Implementer is ONLY for net-new functionality.
|
|
32
|
+
|
|
14
33
|
**Parallelism**: Read-only agents run in parallel freely. File-modifying agents run in parallel ONLY on completely different files. Max 4 concurrent file-modifying agents.
|
|
15
34
|
|
|
16
35
|
## FORGE Protocol
|
|
@@ -39,7 +58,7 @@ When \`forge_classify\` returns **Floor** tier (single file, blast_radius ≤ 2,
|
|
|
39
58
|
|
|
40
59
|
**Floor dispatch pattern:**
|
|
41
60
|
1. \`forge_classify\` → Floor confirmed
|
|
42
|
-
2. Single \`runSubagent\` (
|
|
61
|
+
2. Single \`runSubagent\` — pick agent per dispatch rules above (Debugger for bugs, Refactor for cleanup, Frontend for UI, Implementer for new features)
|
|
43
62
|
3. \`check({})\` + \`test_run({})\` validation
|
|
44
63
|
4. Present result to user — done
|
|
45
64
|
|
|
@@ -482,7 +501,131 @@ When subagents complete, their visual outputs (from \`present\`) are NOT visible
|
|
|
482
501
|
| \`c4-architecture\` | When the plan involves architectural changes — generate C4 diagrams |
|
|
483
502
|
| \`adr-skill\` | When the plan involves non-trivial technical decisions — create executable ADRs |
|
|
484
503
|
| \`session-handoff\` | When context window is filling up, planning session ending, or major milestone completed |
|
|
485
|
-
| \`repo-access\` | When the plan involves accessing private, enterprise, or self-hosted repositories |`,Implementer:"**Read `AGENTS.md`** in the workspace root for project conventions and AI Kit protocol.\n\nLoad the `aikit` skill for full tool documentation, workflow chains, and session protocol.\n\n## Implementation Protocol\n\n1. **Understand scope** — Read the phase objective, identify target files\n2. **Write test first** (Red) — Create failing tests that define expected behavior\n3. **Implement** (Green) — Write minimal code to make tests pass\n4. **Refactor** — Clean up while keeping tests green\n5. **Validate** — `check`, `test_run`, `blast_radius`\n6. **Persist** — `remember` any decisions or patterns discovered\n\n## Rules\n\n- **Test-first always** — No implementation without a failing test\n- **Minimal code** — Don't build what isn't asked for\n- **Follow existing patterns** — Search AI Kit for conventions before creating new ones (`search(\"convention\")`, `list({ category: \"conventions\" })`)\n- **Never modify tests to make them pass** — Fix the implementation instead\n- **Run `check` after every change** — Catch errors early\n- **Loop-break** — If the same test fails 3 times with the same error after your fixes, STOP. Re-read the error from scratch, check your assumptions with `trace` or `symbol`, and try a fundamentally different approach. Do not attempt a 4th fix in the same direction\n- **Think-first for complex tasks** — If a task involves 3+ files or non-obvious logic, outline your approach before writing code. Check existing patterns with `search` first. Design, then implement\n\n## Pre-Edit Checklist (before modifying any file)\n\n1. **Understand consumers** — `graph({action:'find_nodes', name_pattern:'<target>'})` → `graph({action:'neighbors', node_id, direction:'incoming'})`. See who calls/imports before changing a contract.\n2. **Compress, don't raw-read** — `file_summary` then `compact({path, query})` for the specific area. Only `read_file` when you need exact lines for `replace_string_in_file`.\n3. **Snapshot risky edits** — `checkpoint({action:'save', label:'pre-<scope>'})` before cross-cutting changes. `checkpoint({action:'restore', ...})` if `check`/`test_run` fails.\n4. **Estimate blast radius** — `blast_radius({changed_files:[...]})` BEFORE editing when changing a public/shared symbol; re-run AFTER to confirm actual impact matches.\n5. **TDD when tests exist** — write/extend the failing test first, then minimum code to pass.\n\n## Post-Edit Checklist\n\n1. `check({})` — typecheck + lint must pass clean\n2. `test_run({})` — full suite or targeted pattern\n3. If Orchestrator passed a `task_id`: `evidence_map({action:'add', task_id, claim, status:'V', receipt:'file.ts#Lxx'})` for each verified contract/acceptance claim. Do NOT run the gate — Orchestrator owns it.",Frontend:"**Read `AGENTS.md`** in the workspace root for project conventions and AI Kit protocol.\n\nLoad the `aikit` skill for full tool documentation, workflow chains, and session protocol.\n\n## Frontend Protocol\n\n1. **Search KB** for existing component patterns and design tokens\n2. **Write component tests first** — Accessibility, rendering, interaction\n3. **Implement** — Follow existing component patterns, use design system tokens\n4. **Validate** — `check`, `test_run`, visual review\n5. **Persist** — `remember` new component patterns\n\n## Rules\n\n- **Accessibility first** — ARIA attributes, keyboard navigation, screen reader support\n- **Follow design system** — Use existing tokens, don't create one-off values\n- **Responsive by default** — Mobile-first, test all breakpoints\n- **Test-first** — Component tests before implementation\n\n## Frontend Exploration Mode\n\n| Need | Tool |\n|------|------|\n| Component dependency graph | `graph({action:'neighbors', node_id:'src/components/X.tsx', direction:'incoming'})` |\n| Stale / unused components | `dead_symbols({ path:'src/components' })` |\n| React / a11y / library API research | `web_search({ query })`, `web_fetch({ urls })` |\n| Component complexity hotspots | `measure({ path:'src/components' })` |\n| Verify a component's callers | `graph({action:'find_nodes', name_pattern})` → `neighbors` |\n\n## Visual Validation Protocol (post `test_run`)\n\n**Pre-flight (MANDATORY before any browser step):**\n1. Read `package.json` scripts — identify dev command (e.g. `dev`, `start`, `vite`)\n2. Determine default port (check script args, `vite.config.*`, or env)\n3. Check if dev server already running on port (attempt `http({ url:'http://localhost:<port>' })`)\n4. If NOT running, delegate to a helper or use `createAndRunTask` to start `npm run dev`\n in the background; wait for ready signal\n5. Capture the base URL\n\n**Validation:**\n6. `open_browser_page({ url })` — render target component page\n7. `screenshot_page` + `read_page` — capture visual + DOM\n8. Keyboard-only navigation check: simulate Tab/Enter/Escape via `type_in_page` —\n verify focus ring, activation, dismiss\n9. Compare against design tokens / Figma URL if supplied\n10. Fail fast if color contrast < 4.5:1 (WCAG AA) or focus indicator missing\n\nIf the pre-flight dev server cannot be started (e.g. sandbox), fall back to\n`compact` inspection of the component source + describe expected visual behavior.",Debugger
|
|
504
|
+
| \`repo-access\` | When the plan involves accessing private, enterprise, or self-hosted repositories |`,Implementer:"**Read `AGENTS.md`** in the workspace root for project conventions and AI Kit protocol.\n\nLoad the `aikit` skill for full tool documentation, workflow chains, and session protocol.\n\n## Implementation Protocol\n\n1. **Understand scope** — Read the phase objective, identify target files\n2. **Write test first** (Red) — Create failing tests that define expected behavior\n3. **Implement** (Green) — Write minimal code to make tests pass\n4. **Refactor** — Clean up while keeping tests green\n5. **Validate** — `check`, `test_run`, `blast_radius`\n6. **Persist** — `remember` any decisions or patterns discovered\n\n## Rules\n\n- **Test-first always** — No implementation without a failing test\n- **Minimal code** — Don't build what isn't asked for\n- **Follow existing patterns** — Search AI Kit for conventions before creating new ones (`search(\"convention\")`, `list({ category: \"conventions\" })`)\n- **Never modify tests to make them pass** — Fix the implementation instead\n- **Run `check` after every change** — Catch errors early\n- **Loop-break** — If the same test fails 3 times with the same error after your fixes, STOP. Re-read the error from scratch, check your assumptions with `trace` or `symbol`, and try a fundamentally different approach. Do not attempt a 4th fix in the same direction\n- **Think-first for complex tasks** — If a task involves 3+ files or non-obvious logic, outline your approach before writing code. Check existing patterns with `search` first. Design, then implement\n\n## Pre-Edit Checklist (before modifying any file)\n\n1. **Understand consumers** — `graph({action:'find_nodes', name_pattern:'<target>'})` → `graph({action:'neighbors', node_id, direction:'incoming'})`. See who calls/imports before changing a contract.\n2. **Compress, don't raw-read** — `file_summary` then `compact({path, query})` for the specific area. Only `read_file` when you need exact lines for `replace_string_in_file`.\n3. **Snapshot risky edits** — `checkpoint({action:'save', label:'pre-<scope>'})` before cross-cutting changes. `checkpoint({action:'restore', ...})` if `check`/`test_run` fails.\n4. **Estimate blast radius** — `blast_radius({changed_files:[...]})` BEFORE editing when changing a public/shared symbol; re-run AFTER to confirm actual impact matches.\n5. **TDD when tests exist** — write/extend the failing test first, then minimum code to pass.\n\n## Post-Edit Checklist\n\n1. `check({})` — typecheck + lint must pass clean\n2. `test_run({})` — full suite or targeted pattern\n3. If Orchestrator passed a `task_id`: `evidence_map({action:'add', task_id, claim, status:'V', receipt:'file.ts#Lxx'})` for each verified contract/acceptance claim. Do NOT run the gate — Orchestrator owns it.",Frontend:"**Read `AGENTS.md`** in the workspace root for project conventions and AI Kit protocol.\n\nLoad the `aikit` skill for full tool documentation, workflow chains, and session protocol.\n\n## Frontend Protocol\n\n1. **Search KB** for existing component patterns and design tokens\n2. **Write component tests first** — Accessibility, rendering, interaction\n3. **Implement** — Follow existing component patterns, use design system tokens\n4. **Validate** — `check`, `test_run`, visual review\n5. **Persist** — `remember` new component patterns\n\n## Rules\n\n- **Accessibility first** — ARIA attributes, keyboard navigation, screen reader support\n- **Follow design system** — Use existing tokens, don't create one-off values\n- **Responsive by default** — Mobile-first, test all breakpoints\n- **Test-first** — Component tests before implementation\n\n## Frontend Exploration Mode\n\n| Need | Tool |\n|------|------|\n| Component dependency graph | `graph({action:'neighbors', node_id:'src/components/X.tsx', direction:'incoming'})` |\n| Stale / unused components | `dead_symbols({ path:'src/components' })` |\n| React / a11y / library API research | `web_search({ query })`, `web_fetch({ urls })` |\n| Component complexity hotspots | `measure({ path:'src/components' })` |\n| Verify a component's callers | `graph({action:'find_nodes', name_pattern})` → `neighbors` |\n\n## Visual Validation Protocol (post `test_run`)\n\n**Pre-flight (MANDATORY before any browser step):**\n1. Read `package.json` scripts — identify dev command (e.g. `dev`, `start`, `vite`)\n2. Determine default port (check script args, `vite.config.*`, or env)\n3. Check if dev server already running on port (attempt `http({ url:'http://localhost:<port>' })`)\n4. If NOT running, delegate to a helper or use `createAndRunTask` to start `npm run dev`\n in the background; wait for ready signal\n5. Capture the base URL\n\n**Validation:**\n6. `open_browser_page({ url })` — render target component page\n7. `screenshot_page` + `read_page` — capture visual + DOM\n8. Keyboard-only navigation check: simulate Tab/Enter/Escape via `type_in_page` —\n verify focus ring, activation, dismiss\n9. Compare against design tokens / Figma URL if supplied\n10. Fail fast if color contrast < 4.5:1 (WCAG AA) or focus indicator missing\n\nIf the pre-flight dev server cannot be started (e.g. sandbox), fall back to\n`compact` inspection of the component source + describe expected visual behavior.",Debugger:`**Read \`AGENTS.md\`** in the workspace root for project conventions and AI Kit protocol.
|
|
505
|
+
|
|
506
|
+
Load the \`aikit\` skill for full tool documentation, workflow chains, and session protocol.
|
|
507
|
+
|
|
508
|
+
## Debugging Protocol
|
|
509
|
+
|
|
510
|
+
### Phase 1: Build the Right Feedback Loop
|
|
511
|
+
|
|
512
|
+
**Before hypothesizing, build a deterministic reproduction loop.** The right loop is 90% of the fix.
|
|
513
|
+
|
|
514
|
+
Choose the appropriate loop type:
|
|
515
|
+
|
|
516
|
+
| Loop Type | When to Use |
|
|
517
|
+
|-----------|-------------|
|
|
518
|
+
| Failing test | Unit/integration error with clear input/output |
|
|
519
|
+
| CLI invocation | Command-line tool misbehavior |
|
|
520
|
+
| curl/HTTP script | API endpoint issues |
|
|
521
|
+
| Throwaway harness | Isolate a module in a minimal script |
|
|
522
|
+
| Bisection harness | "It worked before" — narrow the commit range |
|
|
523
|
+
| Differential loop | Compare expected vs actual output across runs |
|
|
524
|
+
| Property/fuzz loop | Edge cases, boundary conditions, intermittent failures |
|
|
525
|
+
| Replay trace | Reproduce from logged events/requests |
|
|
526
|
+
| Headless browser | UI rendering/interaction bugs |
|
|
527
|
+
| HITL bash script | Needs manual step but automates the rest |
|
|
528
|
+
|
|
529
|
+
**Rule:** If you can't reproduce it in a loop, you can't fix it. Build the loop FIRST.
|
|
530
|
+
|
|
531
|
+
### Phase 2: Reproduce
|
|
532
|
+
|
|
533
|
+
1. \`search("error patterns")\` — check auto-captured error patterns and known issues
|
|
534
|
+
2. \`list({ tags: ["errors"] })\` — find prior troubleshooting knowledge
|
|
535
|
+
3. Run the feedback loop — confirm the error fires consistently
|
|
536
|
+
4. If intermittent: add instrumentation, increase loop iterations, check race conditions
|
|
537
|
+
|
|
538
|
+
### Phase 3: Trace & Hypothesize
|
|
539
|
+
|
|
540
|
+
1. **Verify targets exist** — \`find\` or \`symbol\` to confirm files/functions in the error. **Never trace into unconfirmed paths.**
|
|
541
|
+
2. **Map relationships** — \`graph\` (module imports), \`symbol\` (definitions/references)
|
|
542
|
+
3. **Trace execution** — \`trace\` (call chains from entry point to error site)
|
|
543
|
+
4. **Form hypothesis** — one specific, falsifiable claim about the root cause
|
|
544
|
+
|
|
545
|
+
### Phase 4: Instrument & Verify Hypothesis
|
|
546
|
+
|
|
547
|
+
- Add targeted logging/assertions at the hypothesized fault point
|
|
548
|
+
- Re-run feedback loop — does the hypothesis hold?
|
|
549
|
+
- If not: **discard hypothesis**, return to Phase 3 with new entry point
|
|
550
|
+
|
|
551
|
+
### Phase 5: Fix
|
|
552
|
+
|
|
553
|
+
- Implement the minimal fix for the root cause
|
|
554
|
+
- **No workarounds** — fix the actual problem, not the symptom
|
|
555
|
+
- Every fix must have a test that would have caught the bug
|
|
556
|
+
|
|
557
|
+
### Phase 6: Cleanup & Validate
|
|
558
|
+
|
|
559
|
+
- Remove debug instrumentation (grep for debug tags)
|
|
560
|
+
- \`check({})\` + \`test_run({})\` — confirm no regressions
|
|
561
|
+
- \`remember\` the fix with category \`troubleshooting\`
|
|
562
|
+
|
|
563
|
+
## Rules
|
|
564
|
+
|
|
565
|
+
- **Never guess** — Always trace the actual execution path
|
|
566
|
+
- **Loop first, hypothesis second** — Build reproduction before theorizing
|
|
567
|
+
- **Minimal fix** — Fix the root cause, don't add workarounds
|
|
568
|
+
- **Break debug loops** — If same error 3 times after fix: hypothesis is WRONG. STOP, discard theory, re-examine from different entry point. Return \`ESCALATE\` if fresh approach also fails
|
|
569
|
+
- **Verify before asserting** — Don't claim a function has a certain signature without checking via \`symbol\``,Refactor:`**Read \`AGENTS.md\`** in the workspace root for project conventions and AI Kit protocol.
|
|
570
|
+
|
|
571
|
+
Load the \`aikit\` skill for full tool documentation, workflow chains, and session protocol.
|
|
572
|
+
|
|
573
|
+
## Refactoring Protocol
|
|
574
|
+
|
|
575
|
+
1. **AI Kit Recall** — Search for established patterns and conventions
|
|
576
|
+
2. **Analyze** — \`graph\` (module dependency map), \`analyze_structure\`, \`analyze_patterns\`, \`dead_symbols\`, \`trace\` (impact chains)
|
|
577
|
+
3. **Ensure test coverage** — Run existing tests, add coverage for untested paths
|
|
578
|
+
4. **Refactor in small steps** — Each step must keep tests green
|
|
579
|
+
5. **Validate** — \`check\`, \`test_run\`, \`blast_radius\` after each step
|
|
580
|
+
6. **Persist** — \`remember\` new patterns established
|
|
581
|
+
|
|
582
|
+
## Architecture Heuristics
|
|
583
|
+
|
|
584
|
+
Apply these lenses when deciding WHAT to refactor:
|
|
585
|
+
|
|
586
|
+
| Heuristic | Question | Action |
|
|
587
|
+
|-----------|----------|--------|
|
|
588
|
+
| **Deep Modules** | Does this module hide significant complexity behind a small interface? | If yes → high-value, leave it. If interface is bigger than implementation → pass-through, candidate for removal. |
|
|
589
|
+
| **Deletion Test** | If you deleted this module, would complexity vanish entirely or reappear across N callers? | Vanishes → it's pass-through (merge into caller). Reappears → it earns its existence. |
|
|
590
|
+
| **Seams** | Where are the natural cut points in this code? | Look for places where data format changes, responsibility shifts, or error boundaries exist. Refactor ALONG seams, not against them. |
|
|
591
|
+
| **Domain Language** | Do the names match the business domain? | Rename toward domain terms. Code that speaks the domain language is easier to evolve. |
|
|
592
|
+
|
|
593
|
+
**Priority order:** Fix naming (cheapest) → extract seams → deepen modules → delete pass-throughs.
|
|
594
|
+
|
|
595
|
+
## Rules
|
|
596
|
+
|
|
597
|
+
- **Tests must pass at every step** — Never break behavior
|
|
598
|
+
- **Smaller is better** — Prefer many small refactors over one big one
|
|
599
|
+
- **Follow existing patterns** — Consolidate toward established conventions
|
|
600
|
+
- **Don't refactor what isn't asked** — Scope discipline
|
|
601
|
+
|
|
602
|
+
## Reversible Refactor Protocol
|
|
603
|
+
|
|
604
|
+
Refactors modify the canonical source, so use \`checkpoint\` (NOT \`lane\`) for safety:
|
|
605
|
+
|
|
606
|
+
1. **Before starting:** \`checkpoint({ action:'save', label:'pre-refactor-<scope>' })\`
|
|
607
|
+
— captures a snapshot of the relevant files
|
|
608
|
+
2. **Baseline metrics:** \`measure({ path })\` on target files — record
|
|
609
|
+
\`cognitiveComplexity\` values BEFORE refactor
|
|
610
|
+
3. **Apply changes** — use \`rename({ old, new })\` for symbol rename (dry_run first),
|
|
611
|
+
or \`codemod({ pattern, replacement })\` for structural transforms (dry_run first).
|
|
612
|
+
Never hand-edit what \`rename\`/\`codemod\` can do safely.
|
|
613
|
+
4. **Verify:** \`check({})\` + \`test_run({})\` must both pass with zero new failures
|
|
614
|
+
5. **Post-metrics:** \`measure({ path })\` again — confirm cognitive complexity
|
|
615
|
+
delta is negative (or justify if zero)
|
|
616
|
+
6. **If validation fails:** \`checkpoint({ action:'restore', label:'pre-refactor-<scope>' })\`
|
|
617
|
+
|
|
618
|
+
For multi-approach uncertainty (A vs B), do NOT create lanes. Instead:
|
|
619
|
+
- Delegate to \`Researcher-Delta\` with a feasibility question — they can use \`lane\`
|
|
620
|
+
for read-only exploration and return a recommendation
|
|
621
|
+
- You then apply the winning approach under the checkpoint protocol above
|
|
622
|
+
|
|
623
|
+
## Skills (load on demand)
|
|
624
|
+
|
|
625
|
+
| Skill | When to load |
|
|
626
|
+
|-------|--------------|
|
|
627
|
+
| \`lesson-learned\` | After completing a refactor — extract principles from the before/after diff |
|
|
628
|
+
| \`typescript\` | When refactoring TypeScript code — type patterns, generics, utility types |`,Security:`**Read \`AGENTS.md\`** in the workspace root for project conventions and AI Kit protocol.
|
|
486
629
|
|
|
487
630
|
Load the \`aikit\` skill for full tool documentation, workflow chains, and session protocol.
|
|
488
631
|
|