@vpxa/aikit 0.1.37 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/package.json +1 -1
  2. package/packages/indexer/dist/graph-extractor.d.ts +6 -2
  3. package/packages/indexer/dist/graph-extractor.js +1 -1
  4. package/packages/indexer/dist/incremental-indexer.d.ts +1 -0
  5. package/packages/indexer/dist/incremental-indexer.js +1 -1
  6. package/packages/indexer/dist/index.d.ts +2 -2
  7. package/packages/server/dist/output-schemas.d.ts +1 -0
  8. package/packages/server/dist/output-schemas.js +1 -1
  9. package/packages/server/dist/tool-metadata.js +1 -1
  10. package/packages/server/dist/tools/context.tools.js +9 -9
  11. package/packages/server/dist/tools/infra.tools.js +1 -1
  12. package/packages/server/dist/tools/status.tool.js +3 -3
  13. package/packages/tools/dist/guide.js +1 -1
  14. package/packages/tools/dist/symbol.js +1 -1
  15. package/packages/tools/dist/trace.js +1 -1
  16. package/packages/tools/dist/web-fetch.js +1 -1
  17. package/scaffold/__tests__/copilot-inline-shared-protocols.test.mjs +39 -0
  18. package/scaffold/adapters/copilot.mjs +11 -5
  19. package/scaffold/definitions/agents.mjs +3 -2
  20. package/scaffold/definitions/bodies.mjs +6 -19
  21. package/scaffold/definitions/protocols.mjs +11 -2
  22. package/scaffold/general/agents/Architect-Reviewer-Alpha.agent.md +61 -1
  23. package/scaffold/general/agents/Architect-Reviewer-Beta.agent.md +61 -1
  24. package/scaffold/general/agents/Code-Reviewer-Alpha.agent.md +65 -1
  25. package/scaffold/general/agents/Code-Reviewer-Beta.agent.md +65 -1
  26. package/scaffold/general/agents/Debugger.agent.md +354 -3
  27. package/scaffold/general/agents/Documenter.agent.md +353 -2
  28. package/scaffold/general/agents/Explorer.agent.md +2 -1
  29. package/scaffold/general/agents/Frontend.agent.md +353 -2
  30. package/scaffold/general/agents/Implementer.agent.md +353 -2
  31. package/scaffold/general/agents/Orchestrator.agent.md +121 -2
  32. package/scaffold/general/agents/Planner.agent.md +353 -2
  33. package/scaffold/general/agents/Refactor.agent.md +354 -3
  34. package/scaffold/general/agents/Researcher-Alpha.agent.md +105 -1
  35. package/scaffold/general/agents/Researcher-Beta.agent.md +105 -1
  36. package/scaffold/general/agents/Researcher-Delta.agent.md +105 -1
  37. package/scaffold/general/agents/Researcher-Gamma.agent.md +105 -1
  38. package/scaffold/general/agents/Security.agent.md +353 -2
  39. package/scaffold/general/agents/_shared/code-agent-base.md +9 -1
  40. package/scaffold/general/agents/_shared/researcher-base.md +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -1,6 +1,10 @@
1
1
  import { GraphEdge, GraphNode } from "../../store/dist/index.js";
2
2
 
3
3
  //#region packages/indexer/src/graph-extractor.d.ts
4
+ interface ExtractGraphOptions {
5
+ /** Maps workspace package names to entry module paths without extensions. */
6
+ workspacePackages?: Map<string, string>;
7
+ }
4
8
  interface ExtractedGraph {
5
9
  nodes: GraphNode[];
6
10
  edges: GraphEdge[];
@@ -13,6 +17,6 @@ interface ExtractedGraph {
13
17
  * - "defines" edges from module → symbol
14
18
  * - "imports" edges from module → imported module
15
19
  */
16
- declare function extractGraph(content: string, sourcePath: string): ExtractedGraph;
20
+ declare function extractGraph(content: string, sourcePath: string, options?: ExtractGraphOptions): ExtractedGraph;
17
21
  //#endregion
18
- export { ExtractedGraph, extractGraph };
22
+ export { ExtractGraphOptions, ExtractedGraph, extractGraph };
@@ -1 +1 @@
1
- import{createHash as e}from"node:crypto";import{dirname as t,extname as n,join as r}from"node:path";const i=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`]),a=[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!0},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:`class`,exported:!0},{pattern:/^export\s+interface\s+(\w+)/gm,kind:`interface`,exported:!0},{pattern:/^export\s+type\s+(\w+)/gm,kind:`type`,exported:!0},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:`const`,exported:!0},{pattern:/^export\s+enum\s+(\w+)/gm,kind:`enum`,exported:!0},{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!1},{pattern:/^class\s+(\w+)/gm,kind:`class`,exported:!1},{pattern:/^interface\s+(\w+)/gm,kind:`interface`,exported:!1},{pattern:/^type\s+(\w+)/gm,kind:`type`,exported:!1},{pattern:/^enum\s+(\w+)/gm,kind:`enum`,exported:!1}],o=[/import\s+(?:(?:type\s+)?(?:(?:\{[^}]*\}|[\w*]+)\s+from\s+)?)['"]([^'"]+)['"]/g,/import\(\s*['"]([^'"]+)['"]\s*\)/g,/require\(\s*['"]([^'"]+)['"]\s*\)/g];function s(t,n,r){return e(`sha256`).update(`${t}:${n}:${r}`).digest(`hex`).slice(0,16)}function c(t,n,r){return e(`sha256`).update(`${t}-${r}-${n}`).digest(`hex`).slice(0,16)}function l(e,n){return r(t(n),e).replace(/\\/g,`/`).replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function u(e){return e.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function d(e,t){let r=n(t).toLowerCase();if(!i.has(r))return{nodes:[],edges:[]};let d=[],f=[],p=new Date().toISOString(),m=new Set,h=u(t),g=s(`module`,h,h);d.push({id:g,type:`module`,name:t,properties:{ext:r},sourcePath:t,createdAt:p});for(let{pattern:n,kind:r,exported:i}of a){let a=new RegExp(n.source,n.flags),o;for(;(o=a.exec(e))!==null;){let e=o[1],n=`${r}:${e}`;if(m.has(n))continue;m.add(n);let a=s(r,e,t);d.push({id:a,type:r,name:e,properties:{exported:i},sourcePath:t,createdAt:p}),f.push({id:c(g,a,`defines`),fromId:g,toId:a,type:`defines`,weight:i?1:.5})}}let _=new Set;for(let n of o){let r=new RegExp(n.source,n.flags),i;for(;(i=r.exec(e))!==null;){let e=i[1];if(!e.startsWith(`.`)||_.has(e))continue;_.add(e);let n=l(e,t),r=s(`module`,n,n);f.push({id:c(g,r,`imports`),fromId:g,toId:r,type:`imports`,properties:{source:e}})}}return{nodes:d,edges:f}}export{d as extractGraph};
1
+ import{createHash as e}from"node:crypto";import{dirname as t,extname as n,join as r}from"node:path";const i=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`]),a=[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!0},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:`class`,exported:!0},{pattern:/^export\s+interface\s+(\w+)/gm,kind:`interface`,exported:!0},{pattern:/^export\s+type\s+(\w+)/gm,kind:`type`,exported:!0},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:`const`,exported:!0},{pattern:/^export\s+enum\s+(\w+)/gm,kind:`enum`,exported:!0},{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:`function`,exported:!1},{pattern:/^class\s+(\w+)/gm,kind:`class`,exported:!1},{pattern:/^interface\s+(\w+)/gm,kind:`interface`,exported:!1},{pattern:/^type\s+(\w+)/gm,kind:`type`,exported:!1},{pattern:/^enum\s+(\w+)/gm,kind:`enum`,exported:!1}],o=[/import\s+(?:(?:type\s+)?(?:(?:\{[^}]*\}|[\w*]+)\s+from\s+)?)['"]([^'"]+)['"]/g,/import\(\s*['"]([^'"]+)['"]\s*\)/g,/require\(\s*['"]([^'"]+)['"]\s*\)/g];function s(t,n,r){return e(`sha256`).update(`${t}:${n}:${r}`).digest(`hex`).slice(0,16)}function c(t,n,r){return e(`sha256`).update(`${t}-${r}-${n}`).digest(`hex`).slice(0,16)}function l(e,n){return r(t(n),e).replace(/\\/g,`/`).replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function u(e){return e.replace(/\.(js|jsx|ts|tsx|mjs|cjs)$/,``)}function d(e,t,r){let d=n(t).toLowerCase();if(!i.has(d))return{nodes:[],edges:[]};let f=[],p=[],m=new Date().toISOString(),h=new Set,g=u(t),_=s(`module`,g,g);f.push({id:_,type:`module`,name:t,properties:{ext:d},sourcePath:t,createdAt:m});for(let{pattern:n,kind:r,exported:i}of a){let a=new RegExp(n.source,n.flags),o;for(;(o=a.exec(e))!==null;){let e=o[1],n=`${r}:${e}`;if(h.has(n))continue;h.add(n);let a=s(r,e,t);f.push({id:a,type:r,name:e,properties:{exported:i},sourcePath:t,createdAt:m}),p.push({id:c(_,a,`defines`),fromId:_,toId:a,type:`defines`,weight:i?1:.5})}}let v=r?.workspacePackages,y=new Set;for(let n of o){let r=new RegExp(n.source,n.flags),i;for(;(i=r.exec(e))!==null;){let e=i[1];if(y.has(e))continue;let n;if(e.startsWith(`.`))n=l(e,t);else if(v){let t=e.startsWith(`@`)?e.split(`/`).slice(0,2).join(`/`):e.split(`/`)[0],r=v.get(t);if(!r)continue;n=r}else continue;y.add(e);let r=u(n),a=s(`module`,r,r);p.push({id:c(_,a,`imports`),fromId:_,toId:a,type:`imports`,properties:{source:e}})}}return{nodes:f,edges:p}}export{d as extractGraph};
@@ -56,6 +56,7 @@ declare class IncrementalIndexer {
56
56
  private crawlSources;
57
57
  private planIndexWork;
58
58
  private getPathsToRemove;
59
+ private buildWorkspacePackageMap;
59
60
  private processFiles;
60
61
  private cleanupRemovedFiles;
61
62
  /**
@@ -1 +1 @@
1
- import{generateRecordId as e,hashContent as t}from"./file-hasher.js";import{FilesystemCrawler as n}from"./filesystem-crawler.js";import{extractGraph as r}from"./graph-extractor.js";import{AIKIT_PATHS as i,createLogger as a,detectContentType as o,serializeError as s}from"../../core/dist/index.js";import{availableParallelism as c,loadavg as l}from"node:os";import{createChunkerSync as u}from"../../chunker/dist/index.js";const d=a(`indexer`),f=()=>new Promise(e=>setImmediate(e));async function p(e,t,n,r){let i=0;async function a(){for(;i<e.length;){let n=i++;try{await t(e[n])}catch(t){r?.(e[n],t)}n%10==0&&await f()}}await Promise.all(Array.from({length:Math.min(n,e.length)},()=>a()))}function m(e){let t=c(),n=l()[0]/t;return n>1.5?2:n>1?Math.max(2,Math.floor(e/2)):e}const h=Math.max(2,Math.min(4,Math.floor(c()*.5)));var g=class{crawler;indexing=!1;graphStore;hashCache;get isIndexing(){return this.indexing}constructor(e,t){this.embedder=e,this.store=t,this.crawler=new n}setGraphStore(e){this.graphStore=e}setHashCache(e){this.hashCache=e}async index(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndex(e,t,{})}finally{this.indexing=!1}}async getChangedFiles(e){let t=e.indexing.concurrency??h,n=await this.crawlSources(e),{filesToProcess:r}=await this.planIndexWork(n,t,{});return r.map(e=>e.relativePath)}async indexFiles(e,t,n){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndexFiles(e,t,n)}finally{this.indexing=!1}}async doIndex(e,t,n={}){let r=Date.now(),i=e.indexing.concurrency??h;t?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let a=await this.crawlSources(e),{filesToProcess:o,filesSkipped:s,pathsToRemove:c}=await this.planIndexWork(a,i,{skipHashCheck:n.skipHashCheck}),{filesProcessed:l,chunksCreated:u}=await this.processFiles(o,i,t,{graphCleared:n.graphCleared}),d=await this.cleanupRemovedFiles(c,i,o.length,l,u,t);return this.hashCache?.flush(),t?.({phase:`done`,filesTotal:o.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:s,chunksCreated:u,filesRemoved:d,durationMs:Date.now()-r}}async doIndexFiles(e,t,n){let r=Date.now(),i=e.indexing.concurrency??h,a=new Set(t);if(a.size===0)return{filesProcessed:0,filesSkipped:0,chunksCreated:0,filesRemoved:0,durationMs:Date.now()-r};n?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let o=await this.crawlSources(e),{filesToProcess:s,filesSkipped:c}=await this.planIndexWork(o,i,{requestedPaths:a}),{filesProcessed:l,chunksCreated:u}=await this.processFiles(s,i,n,{});return this.hashCache?.flush(),n?.({phase:`done`,filesTotal:s.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:c,chunksCreated:u,filesRemoved:0,durationMs:Date.now()-r}}async crawlSources(e){return(await Promise.all(e.sources.map(e=>this.crawler.crawl({rootDir:e.path,excludePatterns:e.excludePatterns})))).flat()}async planIndexWork(e,n,r){let i=r.requestedPaths,a=i?e.filter(e=>i.has(e.relativePath)):e;if(r.skipHashCheck)return{filesToProcess:a,filesSkipped:0,pathsToRemove:[]};let o=i?[]:await this.getPathsToRemove(e),c=0,l=[];return await p(a,async e=>{let n=t(e.content);if(this.hashCache){if(this.hashCache.get(e.relativePath)===n){c++;return}}else{let t=await this.store.getBySourcePath(e.relativePath);if(t.length>0&&t[0].fileHash===n){c++;return}}l.push(e)},m(n),(e,t)=>d.error(`Hash check failed`,{sourcePath:e.relativePath,...s(t)})),{filesToProcess:l,filesSkipped:c,pathsToRemove:o}}async getPathsToRemove(e){let t=await this.store.listSourcePaths(),n=new Set(e.map(e=>e.relativePath));return t.filter(e=>!n.has(e)&&!e.startsWith(`${i.aiCurated}/`))}async processFiles(n,i,a,c={}){let l=0,f=0,h=n.length,g=[],_=[],v=0,y=[],b=[],x=new Map,S=0,C=async()=>{if(y.length===0)return;let e=y,t=b,n=x;y=[],b=[],x=new Map,S=0,await this.store.upsert(e,t);for(let[e,t]of n)this.hashCache?.set(e,t)},w=async()=>{if(this.graphStore){try{g.length>0&&await this.graphStore.upsertNodes(g),_.length>0&&await this.graphStore.upsertEdges(_)}catch(e){d.warn(`Graph batch flush failed`,s(e))}g=[],_=[],v=0}};return await p(n,async n=>{a?.({phase:`chunking`,filesTotal:h,filesProcessed:l,chunksTotal:f,chunksProcessed:f,currentFile:n.relativePath});let i=o(n.relativePath),p=u(n.extension).chunk(n.content,{sourcePath:n.relativePath,contentType:i});if(p.length===0)return;a?.({phase:`embedding`,filesTotal:h,filesProcessed:l,chunksTotal:f+p.length,chunksProcessed:f,currentFile:n.relativePath});let m=await this.embedder.embedBatch(p.map(e=>e.text)),T=t(n.content),E=p.map((t,r)=>({id:e(n.relativePath,r),content:t.text,sourcePath:t.sourcePath,contentType:t.contentType,headingPath:t.headingPath,chunkIndex:t.chunkIndex,totalChunks:t.totalChunks,startLine:t.startLine,endLine:t.endLine,fileHash:T,indexedAt:new Date().toISOString(),origin:`indexed`,tags:[],version:1}));if(a?.({phase:`storing`,filesTotal:h,filesProcessed:l,chunksTotal:f+p.length,chunksProcessed:f,currentFile:n.relativePath}),y.push(...E),b.push(...m),x.set(n.relativePath,T),S++,S>=20&&await C(),this.graphStore)try{c.graphCleared||await this.graphStore.deleteBySourcePath(n.relativePath);let e=r(n.content,n.relativePath);e.nodes.length>0&&g.push(...e.nodes),e.edges.length>0&&_.push(...e.edges),v++,v>=50&&await w()}catch(e){d.warn(`Graph extraction failed`,{sourcePath:n.relativePath,...s(e)})}l++,f+=p.length},m(i),(e,t)=>d.error(`Processing failed`,{sourcePath:e.relativePath,...s(t)})),await C(),await w(),{filesProcessed:l,chunksCreated:f}}async cleanupRemovedFiles(e,t,n,r,i,a){if(e.length===0)return 0;let o=0;return a?.({phase:`cleanup`,filesTotal:n,filesProcessed:r,chunksTotal:i,chunksProcessed:i}),await p(e,async e=>{await this.store.deleteBySourcePath(e),this.hashCache?.delete(e),this.graphStore&&await this.graphStore.deleteBySourcePath(e).catch(t=>d.warn(`Graph cleanup failed`,{sourcePath:e,...s(t)})),o++},m(t),(e,t)=>d.error(`Cleanup failed`,{sourcePath:e,...s(t)})),o}async reindexAll(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{if(await this.store.dropTable(),this.graphStore)try{let e=await this.graphStore.getStats();e.nodeCount>0&&(await this.graphStore.clear(),d.info(`Graph store cleared`,{nodeCount:e.nodeCount,edgeCount:e.edgeCount}))}catch(e){d.warn(`Graph store clear failed`,s(e))}return await this.doReindex(e,t)}catch(e){throw this.indexing=!1,e}}async doReindex(e,t){try{return await this.doIndex(e,t,{skipHashCheck:!0,graphCleared:!0})}finally{this.indexing=!1}}async getStats(){return this.store.getStats()}};export{g as IncrementalIndexer};
1
+ import{generateRecordId as e,hashContent as t}from"./file-hasher.js";import{FilesystemCrawler as n}from"./filesystem-crawler.js";import{extractGraph as r}from"./graph-extractor.js";import{AIKIT_PATHS as i,createLogger as a,detectContentType as o,serializeError as s}from"../../core/dist/index.js";import{availableParallelism as c,loadavg as l}from"node:os";import{createChunkerSync as u}from"../../chunker/dist/index.js";const d=a(`indexer`),f=()=>new Promise(e=>setImmediate(e));async function p(e,t,n,r){let i=0;async function a(){for(;i<e.length;){let n=i++;try{await t(e[n])}catch(t){r?.(e[n],t)}n%10==0&&await f()}}await Promise.all(Array.from({length:Math.min(n,e.length)},()=>a()))}function m(e){let t=c(),n=l()[0]/t;return n>1.5?2:n>1?Math.max(2,Math.floor(e/2)):e}const h=Math.max(2,Math.min(4,Math.floor(c()*.5)));var g=class{crawler;indexing=!1;graphStore;hashCache;get isIndexing(){return this.indexing}constructor(e,t){this.embedder=e,this.store=t,this.crawler=new n}setGraphStore(e){this.graphStore=e}setHashCache(e){this.hashCache=e}async index(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndex(e,t,{})}finally{this.indexing=!1}}async getChangedFiles(e){let t=e.indexing.concurrency??h,n=await this.crawlSources(e),{filesToProcess:r}=await this.planIndexWork(n,t,{});return r.map(e=>e.relativePath)}async indexFiles(e,t,n){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{return await this.doIndexFiles(e,t,n)}finally{this.indexing=!1}}async doIndex(e,t,n={}){let r=Date.now(),i=e.indexing.concurrency??h;t?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let a=await this.crawlSources(e),{filesToProcess:o,filesSkipped:s,pathsToRemove:c}=await this.planIndexWork(a,i,{skipHashCheck:n.skipHashCheck}),{filesProcessed:l,chunksCreated:u}=await this.processFiles(a,o,i,t,{graphCleared:n.graphCleared}),d=await this.cleanupRemovedFiles(c,i,o.length,l,u,t);return this.hashCache?.flush(),t?.({phase:`done`,filesTotal:o.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:s,chunksCreated:u,filesRemoved:d,durationMs:Date.now()-r}}async doIndexFiles(e,t,n){let r=Date.now(),i=e.indexing.concurrency??h,a=new Set(t);if(a.size===0)return{filesProcessed:0,filesSkipped:0,chunksCreated:0,filesRemoved:0,durationMs:Date.now()-r};n?.({phase:`crawling`,filesTotal:0,filesProcessed:0,chunksTotal:0,chunksProcessed:0});let o=await this.crawlSources(e),{filesToProcess:s,filesSkipped:c}=await this.planIndexWork(o,i,{requestedPaths:a}),{filesProcessed:l,chunksCreated:u}=await this.processFiles(o,s,i,n,{});return this.hashCache?.flush(),n?.({phase:`done`,filesTotal:s.length,filesProcessed:l,chunksTotal:u,chunksProcessed:u}),{filesProcessed:l,filesSkipped:c,chunksCreated:u,filesRemoved:0,durationMs:Date.now()-r}}async crawlSources(e){return(await Promise.all(e.sources.map(e=>this.crawler.crawl({rootDir:e.path,excludePatterns:e.excludePatterns})))).flat()}async planIndexWork(e,n,r){let i=r.requestedPaths,a=i?e.filter(e=>i.has(e.relativePath)):e;if(r.skipHashCheck)return{filesToProcess:a,filesSkipped:0,pathsToRemove:[]};let o=i?[]:await this.getPathsToRemove(e),c=0,l=[];return await p(a,async e=>{let n=t(e.content);if(this.hashCache){if(this.hashCache.get(e.relativePath)===n){c++;return}}else{let t=await this.store.getBySourcePath(e.relativePath);if(t.length>0&&t[0].fileHash===n){c++;return}}l.push(e)},m(n),(e,t)=>d.error(`Hash check failed`,{sourcePath:e.relativePath,...s(t)})),{filesToProcess:l,filesSkipped:c,pathsToRemove:o}}async getPathsToRemove(e){let t=await this.store.listSourcePaths(),n=new Set(e.map(e=>e.relativePath));return t.filter(e=>!n.has(e)&&!e.startsWith(`${i.aiCurated}/`))}async buildWorkspacePackageMap(e){let t=new Map;for(let n of e)if(n.relativePath.endsWith(`package.json`))try{let e=JSON.parse(n.content);if(typeof e.name!=`string`||e.name.length===0)continue;let r=n.relativePath===`package.json`?``:n.relativePath.replace(/\/package\.json$/,``),i=``;if(typeof e.exports==`string`)i=e.exports;else if(e.exports&&typeof e.exports==`object`){let t=e.exports,n=t[`.`]??t;if(typeof n==`string`)i=n;else if(n&&typeof n==`object`){let e=n,t=e.import??e.module??e.default??e.require;typeof t==`string`&&(i=t)}}!i&&typeof e.module==`string`&&(i=e.module),!i&&typeof e.main==`string`&&(i=e.main);let a=i.replace(/^\.\//,``).replace(/^dist\//,`src/`).replace(/\.(ts|js|mjs|cjs|tsx|jsx)$/,``),o=a?r?`${r}/${a}`:a:r?`${r}/src/index`:`src/index`;t.set(e.name,o)}catch{}return t}async processFiles(n,i,a,c,l={}){let f=0,h=0,g=i.length,_=this.graphStore?await this.buildWorkspacePackageMap(n):void 0,v=[],y=[],b=0,x=[],S=[],C=new Map,w=0,T=async()=>{if(x.length===0)return;let e=x,t=S,n=C;x=[],S=[],C=new Map,w=0,await this.store.upsert(e,t);for(let[e,t]of n)this.hashCache?.set(e,t)},E=async()=>{if(this.graphStore){try{v.length>0&&await this.graphStore.upsertNodes(v),y.length>0&&await this.graphStore.upsertEdges(y)}catch(e){d.warn(`Graph batch flush failed`,s(e))}v=[],y=[],b=0}};return await p(i,async n=>{c?.({phase:`chunking`,filesTotal:g,filesProcessed:f,chunksTotal:h,chunksProcessed:h,currentFile:n.relativePath});let i=o(n.relativePath),a=u(n.extension).chunk(n.content,{sourcePath:n.relativePath,contentType:i});if(a.length===0)return;c?.({phase:`embedding`,filesTotal:g,filesProcessed:f,chunksTotal:h+a.length,chunksProcessed:h,currentFile:n.relativePath});let p=await this.embedder.embedBatch(a.map(e=>e.text)),m=t(n.content),D=a.map((t,r)=>({id:e(n.relativePath,r),content:t.text,sourcePath:t.sourcePath,contentType:t.contentType,headingPath:t.headingPath,chunkIndex:t.chunkIndex,totalChunks:t.totalChunks,startLine:t.startLine,endLine:t.endLine,fileHash:m,indexedAt:new Date().toISOString(),origin:`indexed`,tags:[],version:1}));if(c?.({phase:`storing`,filesTotal:g,filesProcessed:f,chunksTotal:h+a.length,chunksProcessed:h,currentFile:n.relativePath}),x.push(...D),S.push(...p),C.set(n.relativePath,m),w++,w>=20&&await T(),this.graphStore)try{l.graphCleared||await this.graphStore.deleteBySourcePath(n.relativePath);let e=r(n.content,n.relativePath,{workspacePackages:_});e.nodes.length>0&&v.push(...e.nodes),e.edges.length>0&&y.push(...e.edges),b++,b>=50&&await E()}catch(e){d.warn(`Graph extraction failed`,{sourcePath:n.relativePath,...s(e)})}f++,h+=a.length},m(a),(e,t)=>d.error(`Processing failed`,{sourcePath:e.relativePath,...s(t)})),await T(),await E(),{filesProcessed:f,chunksCreated:h}}async cleanupRemovedFiles(e,t,n,r,i,a){if(e.length===0)return 0;let o=0;return a?.({phase:`cleanup`,filesTotal:n,filesProcessed:r,chunksTotal:i,chunksProcessed:i}),await p(e,async e=>{await this.store.deleteBySourcePath(e),this.hashCache?.delete(e),this.graphStore&&await this.graphStore.deleteBySourcePath(e).catch(t=>d.warn(`Graph cleanup failed`,{sourcePath:e,...s(t)})),o++},m(t),(e,t)=>d.error(`Cleanup failed`,{sourcePath:e,...s(t)})),o}async reindexAll(e,t){if(this.indexing)throw Error(`Indexing is already in progress`);this.indexing=!0;try{if(await this.store.dropTable(),this.graphStore)try{let e=await this.graphStore.getStats();e.nodeCount>0&&(await this.graphStore.clear(),d.info(`Graph store cleared`,{nodeCount:e.nodeCount,edgeCount:e.edgeCount}))}catch(e){d.warn(`Graph store clear failed`,s(e))}return await this.doReindex(e,t)}catch(e){throw this.indexing=!1,e}}async doReindex(e,t){try{return await this.doIndex(e,t,{skipHashCheck:!0,graphCleared:!0})}finally{this.indexing=!1}}async getStats(){return this.store.getStats()}};export{g as IncrementalIndexer};
@@ -1,7 +1,7 @@
1
1
  import { generateRecordId, hashContent } from "./file-hasher.js";
2
2
  import { CrawlOptions, CrawlResult, FilesystemCrawler } from "./filesystem-crawler.js";
3
- import { ExtractedGraph, extractGraph } from "./graph-extractor.js";
3
+ import { ExtractGraphOptions, ExtractedGraph, extractGraph } from "./graph-extractor.js";
4
4
  import { FileHashCache } from "./hash-cache.js";
5
5
  import { IncrementalIndexer, IndexProgress, IndexResult, ProgressCallback } from "./incremental-indexer.js";
6
6
  import { SmartIndexScheduler } from "./smart-index-scheduler.js";
7
- export { type CrawlOptions, type CrawlResult, type ExtractedGraph, FileHashCache, FilesystemCrawler, IncrementalIndexer, type IndexProgress, type IndexResult, type ProgressCallback, SmartIndexScheduler, extractGraph, generateRecordId, hashContent };
7
+ export { type CrawlOptions, type CrawlResult, type ExtractGraphOptions, type ExtractedGraph, FileHashCache, FilesystemCrawler, IncrementalIndexer, type IndexProgress, type IndexResult, type ProgressCallback, SmartIndexScheduler, extractGraph, generateRecordId, hashContent };
@@ -26,6 +26,7 @@ declare const StatusOutputSchema: z.ZodObject<{
26
26
  scaffoldVersion: z.ZodNullable<z.ZodString>;
27
27
  workspaceScaffoldVersion: z.ZodNullable<z.ZodString>;
28
28
  upgradeAvailable: z.ZodBoolean;
29
+ contextPressure: z.ZodNumber;
29
30
  }, z.core.$strip>;
30
31
  declare const ListOutputSchema: z.ZodObject<{
31
32
  entries: z.ZodArray<z.ZodObject<{
@@ -1 +1 @@
1
- import{z as e}from"zod";const t=e.object({totalRecords:e.number(),totalFiles:e.number(),lastIndexedAt:e.string().nullable(),onboarded:e.boolean(),onboardDir:e.string(),contentTypes:e.record(e.string(),e.number()),wasmAvailable:e.boolean(),graphStats:e.object({nodes:e.number(),edges:e.number()}).nullable(),curatedCount:e.number(),serverVersion:e.string(),scaffoldVersion:e.string().nullable(),workspaceScaffoldVersion:e.string().nullable(),upgradeAvailable:e.boolean()}),n=e.object({entries:e.array(e.object({path:e.string(),title:e.string(),category:e.string(),tags:e.array(e.string()),version:e.number(),preview:e.string()})),totalCount:e.number()}),r=e.object({ok:e.boolean(),checks:e.array(e.object({name:e.string(),ok:e.boolean(),message:e.string().optional()}))}),i=e.object({summary:e.object({totalFiles:e.number(),totalLines:e.number(),totalCodeLines:e.number(),totalFunctions:e.number(),avgComplexity:e.number(),maxComplexity:e.object({value:e.number(),file:e.string()})}),files:e.array(e.object({path:e.string(),lines:e.number(),code:e.number(),complexity:e.number(),functions:e.number()}))}),a=e.object({platform:e.string(),arch:e.string(),nodeVersion:e.string(),cwd:e.string(),cpus:e.number(),memoryFreeGb:e.number(),memoryTotalGb:e.number()}),o=e.object({iso:e.string(),unix:e.number(),timezone:e.string(),formatted:e.string()}),s=e.object({passed:e.boolean(),errorCount:e.number(),warningCount:e.number(),topErrors:e.array(e.string())}),c=e.object({passed:e.boolean(),tsc:s,biome:s}),l=e.object({name:e.string(),definedIn:e.object({path:e.string(),line:e.number(),kind:e.string(),signature:e.string().optional()}).nullable(),importedBy:e.array(e.object({path:e.string(),line:e.number(),importStatement:e.string()})),referencedIn:e.array(e.object({path:e.string(),line:e.number(),context:e.string(),scope:e.string().optional()})),graphContext:e.object({definingModule:e.string().optional(),importedByModules:e.array(e.string()),siblingSymbols:e.array(e.string())}).nullable()}),u=e.object({sourcePath:e.string(),contentType:e.string(),score:e.number(),headingPath:e.string().optional(),startLine:e.number().optional(),endLine:e.number().optional(),origin:e.string().optional(),category:e.string().optional(),tags:e.array(e.string()).optional()}),d=e.object({results:e.array(u),totalResults:e.number(),searchMode:e.string(),query:e.string()}),f=e.object({path:e.string(),line:e.number().optional(),matchType:e.string(),preview:e.string()}),p=e.object({matches:e.array(f),totalMatches:e.number(),pattern:e.string(),truncated:e.boolean()}),m=e.object({path:e.string(),relevance:e.number(),estimatedTokens:e.number(),focusLines:e.array(e.string()).optional()}),h=e.object({files:e.array(m),totalFiles:e.number(),totalEstimatedTokens:e.number(),task:e.string()}),g=e.object({path:e.string(),impact:e.string(),reason:e.string()}),_=e.object({changedFiles:e.array(e.string()),affectedFiles:e.array(g),totalAffected:e.number(),riskLevel:e.string()}),v=e.object({name:e.string(),passed:e.boolean(),message:e.string().optional(),severity:e.string().optional()}),y=e.object({passed:e.boolean(),score:e.number(),checks:e.array(v),summary:e.string()}),b=e.object({id:e.string(),name:e.string(),type:e.string(),sourcePath:e.string().optional()}),x=e.object({fromId:e.string(),toId:e.string(),type:e.string()}),S=e.object({nodes:e.array(b),edges:e.array(x),totalNodes:e.number(),totalEdges:e.number(),query:e.string()}),C=e.object({symbols:e.array(e.object({name:e.string(),path:e.string(),line:e.number().optional(),kind:e.string()})),totalDead:e.number()}),w=e.object({files:e.number(),packages:e.number(),languages:e.record(e.string(),e.number()),tree:e.string()}),T=e.object({path:e.string(),language:e.string(),lines:e.number(),imports:e.number(),exports:e.number(),functions:e.number(),classes:e.number()}),E=e.object({gitRoot:e.string(),branch:e.string(),commitCount:e.number(),hasUncommitted:e.boolean(),recentCommits:e.array(e.object({hash:e.string(),message:e.string(),author:e.string(),date:e.string()}))}),D=e.object({originalChars:e.number(),compressedChars:e.number(),ratio:e.number(),segmentsKept:e.number(),segmentsTotal:e.number()});export{w as AnalyzeStructureOutputSchema,y as AuditOutputSchema,_ as BlastRadiusOutputSchema,c as CheckOutputSchema,D as CompactOutputSchema,C as DeadSymbolsOutputSchema,a as EnvOutputSchema,T as FileSummaryOutputSchema,p as FindOutputSchema,E as GitContextOutputSchema,S as GraphOutputSchema,r as HealthOutputSchema,n as ListOutputSchema,i as MeasureOutputSchema,h as ScopeMapOutputSchema,d as SearchOutputSchema,t as StatusOutputSchema,l as SymbolOutputSchema,o as TimeOutputSchema};
1
+ import{z as e}from"zod";const t=e.object({totalRecords:e.number(),totalFiles:e.number(),lastIndexedAt:e.string().nullable(),onboarded:e.boolean(),onboardDir:e.string(),contentTypes:e.record(e.string(),e.number()),wasmAvailable:e.boolean(),graphStats:e.object({nodes:e.number(),edges:e.number()}).nullable(),curatedCount:e.number(),serverVersion:e.string(),scaffoldVersion:e.string().nullable(),workspaceScaffoldVersion:e.string().nullable(),upgradeAvailable:e.boolean(),contextPressure:e.number().min(0).max(100).describe(`0–100 score indicating knowledge base saturation`)}),n=e.object({entries:e.array(e.object({path:e.string(),title:e.string(),category:e.string(),tags:e.array(e.string()),version:e.number(),preview:e.string()})),totalCount:e.number()}),r=e.object({ok:e.boolean(),checks:e.array(e.object({name:e.string(),ok:e.boolean(),message:e.string().optional()}))}),i=e.object({summary:e.object({totalFiles:e.number(),totalLines:e.number(),totalCodeLines:e.number(),totalFunctions:e.number(),avgComplexity:e.number(),maxComplexity:e.object({value:e.number(),file:e.string()})}),files:e.array(e.object({path:e.string(),lines:e.number(),code:e.number(),complexity:e.number(),functions:e.number()}))}),a=e.object({platform:e.string(),arch:e.string(),nodeVersion:e.string(),cwd:e.string(),cpus:e.number(),memoryFreeGb:e.number(),memoryTotalGb:e.number()}),o=e.object({iso:e.string(),unix:e.number(),timezone:e.string(),formatted:e.string()}),s=e.object({passed:e.boolean(),errorCount:e.number(),warningCount:e.number(),topErrors:e.array(e.string())}),c=e.object({passed:e.boolean(),tsc:s,biome:s}),l=e.object({name:e.string(),definedIn:e.object({path:e.string(),line:e.number(),kind:e.string(),signature:e.string().optional()}).nullable(),importedBy:e.array(e.object({path:e.string(),line:e.number(),importStatement:e.string()})),referencedIn:e.array(e.object({path:e.string(),line:e.number(),context:e.string(),scope:e.string().optional()})),graphContext:e.object({definingModule:e.string().optional(),importedByModules:e.array(e.string()),siblingSymbols:e.array(e.string())}).nullable()}),u=e.object({sourcePath:e.string(),contentType:e.string(),score:e.number(),headingPath:e.string().optional(),startLine:e.number().optional(),endLine:e.number().optional(),origin:e.string().optional(),category:e.string().optional(),tags:e.array(e.string()).optional()}),d=e.object({results:e.array(u),totalResults:e.number(),searchMode:e.string(),query:e.string()}),f=e.object({path:e.string(),line:e.number().optional(),matchType:e.string(),preview:e.string()}),p=e.object({matches:e.array(f),totalMatches:e.number(),pattern:e.string(),truncated:e.boolean()}),m=e.object({path:e.string(),relevance:e.number(),estimatedTokens:e.number(),focusLines:e.array(e.string()).optional()}),h=e.object({files:e.array(m),totalFiles:e.number(),totalEstimatedTokens:e.number(),task:e.string()}),g=e.object({path:e.string(),impact:e.string(),reason:e.string()}),_=e.object({changedFiles:e.array(e.string()),affectedFiles:e.array(g),totalAffected:e.number(),riskLevel:e.string()}),v=e.object({name:e.string(),passed:e.boolean(),message:e.string().optional(),severity:e.string().optional()}),y=e.object({passed:e.boolean(),score:e.number(),checks:e.array(v),summary:e.string()}),b=e.object({id:e.string(),name:e.string(),type:e.string(),sourcePath:e.string().optional()}),x=e.object({fromId:e.string(),toId:e.string(),type:e.string()}),S=e.object({nodes:e.array(b),edges:e.array(x),totalNodes:e.number(),totalEdges:e.number(),query:e.string()}),C=e.object({symbols:e.array(e.object({name:e.string(),path:e.string(),line:e.number().optional(),kind:e.string()})),totalDead:e.number()}),w=e.object({files:e.number(),packages:e.number(),languages:e.record(e.string(),e.number()),tree:e.string()}),T=e.object({path:e.string(),language:e.string(),lines:e.number(),imports:e.number(),exports:e.number(),functions:e.number(),classes:e.number()}),E=e.object({gitRoot:e.string(),branch:e.string(),commitCount:e.number(),hasUncommitted:e.boolean(),recentCommits:e.array(e.object({hash:e.string(),message:e.string(),author:e.string(),date:e.string()}))}),D=e.object({originalChars:e.number(),compressedChars:e.number(),ratio:e.number(),segmentsKept:e.number(),segmentsTotal:e.number()});export{w as AnalyzeStructureOutputSchema,y as AuditOutputSchema,_ as BlastRadiusOutputSchema,c as CheckOutputSchema,D as CompactOutputSchema,C as DeadSymbolsOutputSchema,a as EnvOutputSchema,T as FileSummaryOutputSchema,p as FindOutputSchema,E as GitContextOutputSchema,S as GraphOutputSchema,r as HealthOutputSchema,n as ListOutputSchema,i as MeasureOutputSchema,h as ScopeMapOutputSchema,d as SearchOutputSchema,t as StatusOutputSchema,l as SymbolOutputSchema,o as TimeOutputSchema};
@@ -1 +1 @@
1
- const e={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0}},symbol:{title:`Symbol Resolver`,annotations:{readOnlyHint:!0,idempotentHint:!0}},trace:{title:`Data Flow Tracer`,annotations:{readOnlyHint:!0,idempotentHint:!0}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0}},lookup:{title:`Chunk Lookup`,annotations:{readOnlyHint:!0,idempotentHint:!0}},dead_symbols:{title:`Dead Symbol Finder`,annotations:{readOnlyHint:!0,idempotentHint:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_structure:{title:`Analyze Structure`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_dependencies:{title:`Analyze Dependencies`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_symbols:{title:`Analyze Symbols`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_patterns:{title:`Analyze Patterns`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_entry_points:{title:`Analyze Entry Points`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_diagram:{title:`Analyze Diagram`,annotations:{readOnlyHint:!0,idempotentHint:!0}},blast_radius:{title:`Blast Radius`,annotations:{readOnlyHint:!0,idempotentHint:!0}},brainstorm:{title:`Brainstorm Session`,annotations:{readOnlyHint:!0,idempotentHint:!0}},remember:{title:`Remember Knowledge`,annotations:{readOnlyHint:!1}},read:{title:`Read Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},update:{title:`Update Knowledge`,annotations:{readOnlyHint:!1}},forget:{title:`Forget Knowledge`,annotations:{readOnlyHint:!1,destructiveHint:!0}},list:{title:`List Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},compact:{title:`Semantic Compactor`,annotations:{readOnlyHint:!0,idempotentHint:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stratum_card:{title:`Stratum Card`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_classify:{title:`FORGE Classify`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0}},batch:{title:`Batch Operations`,annotations:{readOnlyHint:!0,idempotentHint:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0}},data_transform:{title:`Data Transform`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stash:{title:`Stash Values`,annotations:{readOnlyHint:!1}},checkpoint:{title:`Session Checkpoint`,annotations:{readOnlyHint:!1}},workset:{title:`Workset Manager`,annotations:{readOnlyHint:!1}},lane:{title:`Exploration Lane`,annotations:{readOnlyHint:!1}},git_context:{title:`Git Context`,annotations:{readOnlyHint:!0,idempotentHint:!0}},diff_parse:{title:`Diff Parser`,annotations:{readOnlyHint:!0,idempotentHint:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0}},watch:{title:`File Watcher`,annotations:{readOnlyHint:!1,openWorldHint:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0}},config:{title:`Configuration Manager`,annotations:{readOnlyHint:!1}},status:{title:`AI Kit Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},health:{title:`Health Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},reindex:{title:`Reindex`,annotations:{readOnlyHint:!1}},onboard:{title:`Onboard Codebase`,annotations:{readOnlyHint:!1}},graph:{title:`Knowledge Graph`,annotations:{readOnlyHint:!1}},guide:{title:`Tool Guide`,annotations:{readOnlyHint:!0,idempotentHint:!0}},replay:{title:`Replay History`,annotations:{readOnlyHint:!0,idempotentHint:!0}},changelog:{title:`Generate Changelog`,annotations:{readOnlyHint:!0,idempotentHint:!0}},regex_test:{title:`Regex Tester`,annotations:{readOnlyHint:!0,idempotentHint:!0}},encode:{title:`Encode / Decode`,annotations:{readOnlyHint:!0,idempotentHint:!0}},measure:{title:`Code Metrics`,annotations:{readOnlyHint:!0,idempotentHint:!0}},schema_validate:{title:`Schema Validator`,annotations:{readOnlyHint:!0,idempotentHint:!0}},snippet:{title:`Code Snippets`,annotations:{readOnlyHint:!1}},env:{title:`Environment Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},time:{title:`Date & Time`,annotations:{readOnlyHint:!0,idempotentHint:!0}},web_fetch:{title:`Web Fetch`,annotations:{readOnlyHint:!0,openWorldHint:!0}},web_search:{title:`Web Search`,annotations:{readOnlyHint:!0,openWorldHint:!0}},http:{title:`HTTP Request`,annotations:{readOnlyHint:!1,openWorldHint:!0}},queue:{title:`Operation Queue`,annotations:{readOnlyHint:!1}},bridge_push:{title:`Bridge Push`,annotations:{readOnlyHint:!1}},bridge_pull:{title:`Bridge Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0}},bridge_sync:{title:`Bridge Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evolution_state:{title:`Evolution State`,annotations:{readOnlyHint:!1}},policy_check:{title:`Policy Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_list:{title:`Flow List`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_info:{title:`Flow Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_start:{title:`Flow Start`,annotations:{readOnlyHint:!1}},flow_step:{title:`Flow Step`,annotations:{readOnlyHint:!1}},flow_status:{title:`Flow Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_reset:{title:`Flow Reset`,annotations:{readOnlyHint:!1}},flow_read_instruction:{title:`Flow Read Instruction`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_add:{title:`Flow Add`,annotations:{readOnlyHint:!1}},flow_remove:{title:`Flow Remove`,annotations:{readOnlyHint:!1}},flow_update:{title:`Flow Update`,annotations:{readOnlyHint:!1}}};function t(t){return e[t]??{title:t,annotations:{readOnlyHint:!1}}}export{e as TOOL_METADATA,t as getToolMeta};
1
+ const e={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0}},symbol:{title:`Symbol Resolver — Cross-Module Definitions & References`,annotations:{readOnlyHint:!0,idempotentHint:!0}},trace:{title:`Data Flow Tracer — Cross-Module Call & Import Chains`,annotations:{readOnlyHint:!0,idempotentHint:!0}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0}},lookup:{title:`Chunk Lookup`,annotations:{readOnlyHint:!0,idempotentHint:!0}},dead_symbols:{title:`Dead Symbol Finder`,annotations:{readOnlyHint:!0,idempotentHint:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_structure:{title:`Analyze Structure`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_dependencies:{title:`Analyze Dependencies`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_symbols:{title:`Analyze Symbols`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_patterns:{title:`Analyze Patterns`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_entry_points:{title:`Analyze Entry Points`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_diagram:{title:`Analyze Diagram`,annotations:{readOnlyHint:!0,idempotentHint:!0}},blast_radius:{title:`Blast Radius`,annotations:{readOnlyHint:!0,idempotentHint:!0}},brainstorm:{title:`Brainstorm Session`,annotations:{readOnlyHint:!0,idempotentHint:!0}},remember:{title:`Remember Knowledge`,annotations:{readOnlyHint:!1}},read:{title:`Read Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},update:{title:`Update Knowledge`,annotations:{readOnlyHint:!1}},forget:{title:`Forget Knowledge`,annotations:{readOnlyHint:!1,destructiveHint:!0}},list:{title:`List Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},compact:{title:`Semantic Compactor`,annotations:{readOnlyHint:!0,idempotentHint:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stratum_card:{title:`Stratum Card`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_classify:{title:`FORGE Classify`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0}},batch:{title:`Batch Operations`,annotations:{readOnlyHint:!0,idempotentHint:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0}},data_transform:{title:`Data Transform`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stash:{title:`Stash Values`,annotations:{readOnlyHint:!1}},checkpoint:{title:`Session Checkpoint`,annotations:{readOnlyHint:!1}},workset:{title:`Workset Manager`,annotations:{readOnlyHint:!1}},lane:{title:`Exploration Lane`,annotations:{readOnlyHint:!1}},git_context:{title:`Git Context`,annotations:{readOnlyHint:!0,idempotentHint:!0}},diff_parse:{title:`Diff Parser`,annotations:{readOnlyHint:!0,idempotentHint:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0}},watch:{title:`File Watcher`,annotations:{readOnlyHint:!1,openWorldHint:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0}},config:{title:`Configuration Manager`,annotations:{readOnlyHint:!1}},status:{title:`AI Kit Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},health:{title:`Health Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},reindex:{title:`Reindex`,annotations:{readOnlyHint:!1}},onboard:{title:`Onboard Codebase`,annotations:{readOnlyHint:!1}},graph:{title:`Code Knowledge Graph — Module & Symbol Relationships`,annotations:{readOnlyHint:!1}},guide:{title:`Tool Guide`,annotations:{readOnlyHint:!0,idempotentHint:!0}},replay:{title:`Replay History`,annotations:{readOnlyHint:!0,idempotentHint:!0}},changelog:{title:`Generate Changelog`,annotations:{readOnlyHint:!0,idempotentHint:!0}},regex_test:{title:`Regex Tester`,annotations:{readOnlyHint:!0,idempotentHint:!0}},encode:{title:`Encode / Decode`,annotations:{readOnlyHint:!0,idempotentHint:!0}},measure:{title:`Code Metrics`,annotations:{readOnlyHint:!0,idempotentHint:!0}},schema_validate:{title:`Schema Validator`,annotations:{readOnlyHint:!0,idempotentHint:!0}},snippet:{title:`Code Snippets`,annotations:{readOnlyHint:!1}},env:{title:`Environment Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},time:{title:`Date & Time`,annotations:{readOnlyHint:!0,idempotentHint:!0}},web_fetch:{title:`Web Fetch`,annotations:{readOnlyHint:!0,openWorldHint:!0}},web_search:{title:`Web Search`,annotations:{readOnlyHint:!0,openWorldHint:!0}},http:{title:`HTTP Request`,annotations:{readOnlyHint:!1,openWorldHint:!0}},queue:{title:`Operation Queue`,annotations:{readOnlyHint:!1}},bridge_push:{title:`Bridge Push`,annotations:{readOnlyHint:!1}},bridge_pull:{title:`Bridge Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0}},bridge_sync:{title:`Bridge Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evolution_state:{title:`Evolution State`,annotations:{readOnlyHint:!1}},policy_check:{title:`Policy Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_list:{title:`Flow List`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_info:{title:`Flow Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_start:{title:`Flow Start`,annotations:{readOnlyHint:!1}},flow_step:{title:`Flow Step`,annotations:{readOnlyHint:!1}},flow_status:{title:`Flow Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_reset:{title:`Flow Reset`,annotations:{readOnlyHint:!1}},flow_read_instruction:{title:`Flow Read Instruction`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_add:{title:`Flow Add`,annotations:{readOnlyHint:!1}},flow_remove:{title:`Flow Remove`,annotations:{readOnlyHint:!1}},flow_update:{title:`Flow Update`,annotations:{readOnlyHint:!1}}};function t(t){return e[t]??{title:t,annotations:{readOnlyHint:!1}}}export{e as TOOL_METADATA,t as getToolMeta};
@@ -1,10 +1,10 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{CompactOutputSchema as t,DeadSymbolsOutputSchema as n,FileSummaryOutputSchema as r,FindOutputSchema as i,ScopeMapOutputSchema as a,SymbolOutputSchema as o}from"../output-schemas.js";import{fanOutSearch as s,openWorkspaceStores as c,resolveWorkspaces as l}from"../cross-workspace.js";import{isAbsolute as u,resolve as d}from"node:path";import{z as f}from"zod";import{CONTENT_TYPES as p,computePartitionKey as m,createLogger as h,serializeError as g}from"../../../core/dist/index.js";import{compact as _,fileSummary as v,find as y,findDeadSymbols as b,findExamples as x,scopeMap as S,symbol as C,trace as w,truncateToTokenBudget as T}from"../../../tools/dist/index.js";const E=h(`tools:context`);function D(n,r,i,a){let o=e(`compact`);n.registerTool(`compact`,{title:o.title,description:"Compress text to relevant sections using embedding similarity (no LLM). Provide either `text` or `path` (server reads the file — saves a round-trip). Segments by paragraph/sentence/line.",outputSchema:t,inputSchema:{text:f.string().optional().describe(`The text to compress (provide this OR path, not both)`),path:f.string().optional().describe(`File path to read server-side — avoids read_file round-trip + token doubling (provide this OR text)`),query:f.string().describe(`Focus query — what are you trying to understand?`),max_chars:f.number().min(100).max(5e4).default(3e3).describe(`Target output size in characters`),segmentation:f.enum([`paragraph`,`sentence`,`line`]).default(`paragraph`).describe(`How to split the text for scoring`),token_budget:f.number().min(50).max(12500).optional().describe(`Token budget — overrides max_chars (approx 4 chars per token). Use to fit output into a specific context window.`)},annotations:o.annotations},async({text:e,path:t,query:n,max_chars:o,segmentation:s,token_budget:c})=>{try{let l=t&&!u(t)?d(a,t):t;if(!e&&!l)return{content:[{type:`text`,text:`Error: Either "text" or "path" must be provided.`}],isError:!0};let f=await _(r,{text:e,path:l,query:n,maxChars:o,tokenBudget:c,segmentation:s,cache:i});return{content:[{type:`text`,text:[`Compressed ${f.originalChars} → ${f.compressedChars} chars (${(f.ratio*100).toFixed(0)}%)`,`Kept ${f.segmentsKept}/${f.segmentsTotal} segments`,``,f.text].join(`
2
- `)}],structuredContent:{originalChars:f.originalChars,compressedChars:f.compressedChars,ratio:f.ratio,segmentsKept:f.segmentsKept,segmentsTotal:f.segmentsTotal}}}catch(e){return E.error(`Compact failed`,g(e)),{content:[{type:`text`,text:`Compact failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function O(t,n,r){let i=e(`scope_map`);t.registerTool(`scope_map`,{title:i.title,description:`Generate a task-scoped reading plan. Given a task description, identifies which files and sections are relevant, with estimated token counts and suggested reading order.`,outputSchema:a,inputSchema:{task:f.string().describe(`Description of the task to scope`),max_files:f.number().min(1).max(50).default(15).describe(`Maximum files to include`),content_type:f.enum(p).optional().describe(`Filter by content type`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`)},annotations:i.annotations},async({task:e,max_files:t,content_type:i,max_tokens:a})=>{try{let o=await S(n,r,{task:e,maxFiles:t,contentType:i}),s=[`## Scope Map: ${e}`,`Total estimated tokens: ~${o.totalEstimatedTokens}`,``,`### Files (by relevance)`,...o.files.map((e,t)=>`${t+1}. **${e.path}** (~${e.estimatedTokens} tokens, ${(e.relevance*100).toFixed(0)}% relevant)\n ${e.reason}\n Focus: ${e.focusRanges.map(e=>`L${e.start}-${e.end}`).join(`, `)}`),``,`### Suggested Reading Order`,...o.readingOrder.map((e,t)=>`${t+1}. ${e}`),``,`### Suggested Compact Calls`,`_Estimated compressed total: ~${Math.ceil(o.totalEstimatedTokens/5)} tokens_`,...o.compactCommands.map((e,t)=>`${t+1}. ${e}`)].join(`
3
- `)+"\n\n---\n_Next: Use `search` to dive into specific files, or `compact` to compress file contents for context._";return{content:[{type:`text`,text:a?T(s,a):s}],structuredContent:{files:o.files.map(e=>({path:e.path,relevance:e.relevance,estimatedTokens:e.estimatedTokens,...e.focusRanges.length>0?{focusLines:e.focusRanges.map(e=>`L${e.start}-${e.end}`)}:{}})),totalFiles:o.files.length,totalEstimatedTokens:o.totalEstimatedTokens,task:e}}}catch(e){return E.error(`Scope map failed`,g(e)),{content:[{type:`text`,text:`Scope map failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function k(t,n,r){let a=e(`find`);t.registerTool(`find`,{title:a.title,description:`Multi-strategy search combining vector, FTS, glob, and regex. Use for precise queries needing multiple strategies. mode=examples finds real usage of a symbol. For general discovery use search instead.`,outputSchema:i,inputSchema:{query:f.string().optional().describe(`Semantic/keyword search query (required for mode "examples")`),glob:f.string().optional().describe(`File glob pattern (search mode only)`),pattern:f.string().optional().describe(`Regex pattern to match in content (search mode only)`),limit:f.number().min(1).max(50).default(10).describe(`Max results`),content_type:f.enum(p).optional().describe(`Filter by content type`),mode:f.enum([`search`,`examples`]).default(`search`).describe(`Mode: "search" (default) for federated search, "examples" to find usage examples of a symbol/pattern`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),workspaces:f.array(f.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`)},annotations:a.annotations},async({query:e,glob:t,pattern:i,limit:a,content_type:o,mode:u,max_tokens:d,workspaces:f})=>{try{if(u===`examples`){if(!e)return{content:[{type:`text`,text:`Error: "query" is required for mode "examples".`}],isError:!0};let t=await x(n,r,{query:e,limit:a,contentType:o}),i=JSON.stringify(t);return{content:[{type:`text`,text:d?T(i,d):i}]}}let p=await y(n,r,{query:e,glob:t,pattern:i,limit:a,contentType:o}),h=``;if(f&&f.length>0&&e){let t=l(f,m(process.cwd()));if(t.length>0){let{stores:r,closeAll:i}=await c(t);try{let i=await s(r,await n.embedQuery(e),{limit:a,contentType:o});for(let e of i)p.results.push({path:`[${e.workspace}] ${e.record.sourcePath}`,score:e.score,source:`cross-workspace`,lineRange:e.record.startLine?{start:e.record.startLine,end:e.record.endLine}:void 0,preview:e.record.content.slice(0,200)});p.results.sort((e,t)=>t.score-e.score),p.results=p.results.slice(0,a),p.totalFound=p.results.length,h=` + ${t.length} workspace(s)`}finally{await i()}}}if(p.results.length===0)return{content:[{type:`text`,text:`No results found.${p.failedStrategies?.length?`\nStrategies attempted: ${p.strategies.join(`, `)}\nFailed: ${p.failedStrategies.map(e=>`${e.strategy} (${e.reason})`).join(`, `)}`:p.strategies.length===0?`
4
- No search strategies were activated. Provide at least one of: query, glob, or pattern.`:``}`}],structuredContent:{matches:[],totalMatches:0,pattern:e??t??i??``,truncated:!1}};let g=[`Found ${p.totalFound} results via ${p.strategies.join(` + `)}${h}`,``,...p.results.map(e=>{let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``,n=e.preview?`\n ${e.preview.slice(0,100)}...`:``;return`- [${e.source}] ${e.path}${t} (${(e.score*100).toFixed(0)}%)${n}`})];return{content:[{type:`text`,text:d?T(g.join(`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{CompactOutputSchema as t,DeadSymbolsOutputSchema as n,FileSummaryOutputSchema as r,FindOutputSchema as i,ScopeMapOutputSchema as a,SymbolOutputSchema as o}from"../output-schemas.js";import{fanOutSearch as s,openWorkspaceStores as c,resolveWorkspaces as l}from"../cross-workspace.js";import{isAbsolute as u,resolve as d}from"node:path";import{z as f}from"zod";import{stat as p}from"node:fs/promises";import{CONTENT_TYPES as m,computePartitionKey as h,createLogger as g,serializeError as _}from"../../../core/dist/index.js";import{StructureAnalyzer as v}from"../../../analyzers/dist/index.js";import{compact as y,fileSummary as b,find as x,findDeadSymbols as S,findExamples as C,scopeMap as w,symbol as T,trace as E,truncateToTokenBudget as D}from"../../../tools/dist/index.js";const O=g(`tools:context`);function k(n,r,i,a){let o=e(`compact`);n.registerTool(`compact`,{title:o.title,description:"Compress text to relevant sections using embedding similarity (no LLM). Provide either `text` or `path` (server reads the file — saves a round-trip). Segments by paragraph/sentence/line.",outputSchema:t,inputSchema:{text:f.string().optional().describe(`The text to compress (provide this OR path, not both)`),path:f.string().optional().describe(`File path to read server-side — avoids read_file round-trip + token doubling (provide this OR text)`),query:f.string().describe(`Focus query — what are you trying to understand?`),max_chars:f.number().min(100).max(5e4).default(3e3).describe(`Target output size in characters`),segmentation:f.enum([`paragraph`,`sentence`,`line`]).default(`paragraph`).describe(`How to split the text for scoring`),token_budget:f.number().min(50).max(12500).optional().describe(`Token budget — overrides max_chars (approx 4 chars per token). Use to fit output into a specific context window.`)},annotations:o.annotations},async({text:e,path:t,query:n,max_chars:o,segmentation:s,token_budget:c})=>{try{let l=t&&!u(t)?d(a,t):t;if(!e&&!l)return{content:[{type:`text`,text:`Error: Either "text" or "path" must be provided.`}],isError:!0};let f=await y(r,{text:e,path:l,query:n,maxChars:o,tokenBudget:c,segmentation:s,cache:i});return{content:[{type:`text`,text:[`Compressed ${f.originalChars} → ${f.compressedChars} chars (${(f.ratio*100).toFixed(0)}%)`,`Kept ${f.segmentsKept}/${f.segmentsTotal} segments`,``,f.text].join(`
2
+ `)}],structuredContent:{originalChars:f.originalChars,compressedChars:f.compressedChars,ratio:f.ratio,segmentsKept:f.segmentsKept,segmentsTotal:f.segmentsTotal}}}catch(e){return O.error(`Compact failed`,_(e)),{content:[{type:`text`,text:`Compact failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function A(t,n,r){let i=e(`scope_map`);t.registerTool(`scope_map`,{title:i.title,description:`Generate a task-scoped reading plan. Given a task description, identifies which files and sections are relevant, with estimated token counts and suggested reading order.`,outputSchema:a,inputSchema:{task:f.string().describe(`Description of the task to scope`),max_files:f.number().min(1).max(50).default(15).describe(`Maximum files to include`),content_type:f.enum(m).optional().describe(`Filter by content type`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`)},annotations:i.annotations},async({task:e,max_files:t,content_type:i,max_tokens:a})=>{try{let o=await w(n,r,{task:e,maxFiles:t,contentType:i}),s=[`## Scope Map: ${e}`,`Total estimated tokens: ~${o.totalEstimatedTokens}`,``,`### Files (by relevance)`,...o.files.map((e,t)=>`${t+1}. **${e.path}** (~${e.estimatedTokens} tokens, ${(e.relevance*100).toFixed(0)}% relevant)\n ${e.reason}\n Focus: ${e.focusRanges.map(e=>`L${e.start}-${e.end}`).join(`, `)}`),``,`### Suggested Reading Order`,...o.readingOrder.map((e,t)=>`${t+1}. ${e}`),``,`### Suggested Compact Calls`,`_Estimated compressed total: ~${Math.ceil(o.totalEstimatedTokens/5)} tokens_`,...o.compactCommands.map((e,t)=>`${t+1}. ${e}`)].join(`
3
+ `)+"\n\n---\n_Next: Use `search` to dive into specific files, or `compact` to compress file contents for context._";return{content:[{type:`text`,text:a?D(s,a):s}],structuredContent:{files:o.files.map(e=>({path:e.path,relevance:e.relevance,estimatedTokens:e.estimatedTokens,...e.focusRanges.length>0?{focusLines:e.focusRanges.map(e=>`L${e.start}-${e.end}`)}:{}})),totalFiles:o.files.length,totalEstimatedTokens:o.totalEstimatedTokens,task:e}}}catch(e){return O.error(`Scope map failed`,_(e)),{content:[{type:`text`,text:`Scope map failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function j(t,n,r){let a=e(`find`);t.registerTool(`find`,{title:a.title,description:`Multi-strategy search combining vector, FTS, glob, and regex. Use for precise queries needing multiple strategies. mode=examples finds real usage of a symbol. For general discovery use search instead.`,outputSchema:i,inputSchema:{query:f.string().optional().describe(`Semantic/keyword search query (required for mode "examples")`),glob:f.string().optional().describe(`File glob pattern (search mode only)`),pattern:f.string().optional().describe(`Regex pattern to match in content (search mode only)`),limit:f.number().min(1).max(50).default(10).describe(`Max results`),content_type:f.enum(m).optional().describe(`Filter by content type`),mode:f.enum([`search`,`examples`]).default(`search`).describe(`Mode: "search" (default) for federated search, "examples" to find usage examples of a symbol/pattern`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),workspaces:f.array(f.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`)},annotations:a.annotations},async({query:e,glob:t,pattern:i,limit:a,content_type:o,mode:u,max_tokens:d,workspaces:f})=>{try{if(u===`examples`){if(!e)return{content:[{type:`text`,text:`Error: "query" is required for mode "examples".`}],isError:!0};let t=await C(n,r,{query:e,limit:a,contentType:o}),i=JSON.stringify(t);return{content:[{type:`text`,text:d?D(i,d):i}]}}let p=await x(n,r,{query:e,glob:t,pattern:i,limit:a,contentType:o}),m=``;if(f&&f.length>0&&e){let t=l(f,h(process.cwd()));if(t.length>0){let{stores:r,closeAll:i}=await c(t);try{let i=await s(r,await n.embedQuery(e),{limit:a,contentType:o});for(let e of i)p.results.push({path:`[${e.workspace}] ${e.record.sourcePath}`,score:e.score,source:`cross-workspace`,lineRange:e.record.startLine?{start:e.record.startLine,end:e.record.endLine}:void 0,preview:e.record.content.slice(0,200)});p.results.sort((e,t)=>t.score-e.score),p.results=p.results.slice(0,a),p.totalFound=p.results.length,m=` + ${t.length} workspace(s)`}finally{await i()}}}if(p.results.length===0)return{content:[{type:`text`,text:`No results found.${p.failedStrategies?.length?`\nStrategies attempted: ${p.strategies.join(`, `)}\nFailed: ${p.failedStrategies.map(e=>`${e.strategy} (${e.reason})`).join(`, `)}`:p.strategies.length===0?`
4
+ No search strategies were activated. Provide at least one of: query, glob, or pattern.`:``}`}],structuredContent:{matches:[],totalMatches:0,pattern:e??t??i??``,truncated:!1}};let g=[`Found ${p.totalFound} results via ${p.strategies.join(` + `)}${m}`,``,...p.results.map(e=>{let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``,n=e.preview?`\n ${e.preview.slice(0,100)}...`:``;return`- [${e.source}] ${e.path}${t} (${(e.score*100).toFixed(0)}%)${n}`})];return{content:[{type:`text`,text:d?D(g.join(`
5
5
  `),d):g.join(`
6
- `)}],structuredContent:{matches:p.results.map(e=>({path:e.path,...e.lineRange?{line:e.lineRange.start}:{},matchType:e.source,preview:e.preview?.slice(0,200)??``})),totalMatches:p.totalFound,pattern:e??t??i??``,truncated:p.results.length<p.totalFound}}}catch(e){return E.error(`Find failed`,g(e)),{content:[{type:`text`,text:`Find failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function A(t,n,r,i){let a=e(`symbol`);t.registerTool(`symbol`,{title:a.title,description:`Find definition, imports, and references of a named symbol (function, class, type). For tracing data flow across call sites use trace instead.`,inputSchema:{name:f.string().describe(`Symbol name to look up (function, class, type, etc.)`),limit:f.number().min(1).max(50).default(20).describe(`Max results per category`),workspaces:f.array(f.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`)},outputSchema:o,annotations:a.annotations},async({name:e,limit:t,workspaces:a})=>{try{let o=await C(n,r,{name:e,limit:t,graphStore:i});if(a&&a.length>0){let r=l(a,m(process.cwd()));if(r.length>0){let{stores:i,closeAll:a}=await c(r);try{for(let[r,a]of i){let i=await C(n,a,{name:e,limit:t});i.definedIn&&!o.definedIn&&(o.definedIn={...i.definedIn,path:`[${r}] ${i.definedIn.path}`});for(let e of i.referencedIn)o.referencedIn.push({...e,path:`[${r}] ${e.path}`});if(i.importedBy){o.importedBy=o.importedBy??[];for(let e of i.importedBy)o.importedBy.push({...e,path:`[${r}] ${e.path}`})}}}finally{await a()}}}let s={name:o.name,definedIn:o.definedIn??null,importedBy:o.importedBy??[],referencedIn:o.referencedIn??[],graphContext:o.graphContext??null};return{content:[{type:`text`,text:P(o)}],structuredContent:s}}catch(e){return E.error(`Symbol lookup failed`,g(e)),{content:[{type:`text`,text:`Symbol lookup failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function j(t,n,i){let a=e(`file_summary`);t.registerTool(`file_summary`,{title:a.title,description:`Create a concise structural summary of a source file: imports, exports, functions, classes, interfaces, and types.`,outputSchema:r,inputSchema:{path:f.string().describe(`Absolute path to the file to summarize`)},annotations:a.annotations},async({path:e})=>{try{let t=u(e)?e:d(i,e),r=await v({path:t,content:(await n.get(t)).content});return{content:[{type:`text`,text:F(r)}],structuredContent:{path:r.path,language:r.language,lines:r.lines,imports:r.imports?.length??0,exports:r.exports?.length??0,functions:r.functions?.length??0,classes:r.classes?.length??0}}}catch(e){return E.error(`File summary failed`,g(e)),{content:[{type:`text`,text:`File summary failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function M(t,n,r,i){let a=e(`trace`);t.registerTool(`trace`,{title:a.title,description:`Follow data flow forward/backward across imports and call sites from a starting symbol or file:line. For finding a single symbol definition use symbol instead.`,inputSchema:{start:f.string().describe(`Starting point — symbol name or file:line reference`),direction:f.enum([`forward`,`backward`,`both`]).describe(`Which direction to trace relationships`),max_depth:f.number().min(1).max(10).default(3).optional().describe(`Maximum trace depth`)},annotations:a.annotations},async({start:e,direction:t,max_depth:a})=>{try{let o=await w(n,r,{start:e,direction:t,maxDepth:a,graphStore:i}),s=[`## Trace: ${o.start}`,`Direction: ${o.direction} | Depth: ${o.depth}`,``];if(o.graphContext&&(s.push(`### Graph Context`),o.graphContext.definingModule&&s.push(`- Module: ${o.graphContext.definingModule}`),o.graphContext.community&&s.push(`- Community: ${o.graphContext.community}`),o.graphContext.importedByModules.length>0&&s.push(`- Imported by modules: ${o.graphContext.importedByModules.join(`, `)}`),o.graphContext.siblingSymbols.length>0&&s.push(`- Sibling symbols: ${o.graphContext.siblingSymbols.join(`, `)}`),s.push(``)),o.nodes.length===0)s.push(`No connections found.`);else{let e=o.nodes.filter(e=>e.relationship===`calls`),t=o.nodes.filter(e=>e.relationship===`called-by`),n=o.nodes.filter(e=>e.relationship===`imports`),r=o.nodes.filter(e=>e.relationship===`imported-by`),i=o.nodes.filter(e=>e.relationship===`references`);if(e.length>0){s.push(`### Calls (${e.length})`);for(let t of e){let e=t.scope?` (from ${t.scope}())`:``;s.push(`- ${t.symbol}() — ${t.path}:${t.line}${e}`)}s.push(``)}if(t.length>0){s.push(`### Called by (${t.length})`);for(let e of t){let t=e.scope?` in ${e.scope}()`:``;s.push(`- ${e.symbol}()${t} — ${e.path}:${e.line}`)}s.push(``)}if(n.length>0){s.push(`### Imports (${n.length})`);for(let e of n)s.push(`- ${e.symbol} — ${e.path}:${e.line}`);s.push(``)}if(r.length>0){s.push(`### Imported by (${r.length})`);for(let e of r)s.push(`- ${e.path}:${e.line}`);s.push(``)}if(i.length>0){s.push(`### References (${i.length})`);for(let e of i)s.push(`- ${e.path}:${e.line}`);s.push(``)}}return s.push(`---`,"_Next: `symbol` for definition details | `compact` to read a referenced file | `blast_radius` for impact analysis_"),{content:[{type:`text`,text:s.join(`
7
- `)}],structuredContent:{start:o.start,direction:o.direction,depth:o.depth,nodes:o.nodes,graphContext:o.graphContext??null}}}catch(e){return E.error(`Trace failed`,g(e)),{content:[{type:`text`,text:`Trace failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function N(t,r,i){let a=e(`dead_symbols`);t.registerTool(`dead_symbols`,{title:a.title,description:`Find exported symbols that appear to be unused because they are never imported or re-exported.`,outputSchema:n,inputSchema:{path:f.string().optional().describe(`Root path to scope the search (default: cwd)`),limit:f.number().min(1).max(500).default(100).optional().describe(`Maximum exported symbols to scan`)},annotations:a.annotations},async({path:e,limit:t})=>{try{let n=await b(r,i,{rootPath:e,limit:t}),a=[`## Dead Symbol Analysis`,``,`**Exports scanned:** ${n.totalExports}`,`**Dead in source:** ${n.totalDeadSource} (actionable)`,`**Dead in docs:** ${n.totalDeadDocs} (informational — code samples in .md files)`,``];if(n.deadInSource.length>0){a.push(`### Dead in Source (actionable)`);for(let e of n.deadInSource)a.push(`- \`${e.name}\` (${e.kind}) — ${e.path}:${e.line}`);a.push(``)}if(n.deadInDocs.length>0){a.push(`### Dead in Docs (informational)`),a.push(`_${n.totalDeadDocs} symbol(s) found only in documentation code samples — not actionable dead code._`);for(let e of n.deadInDocs.slice(0,5))a.push(`- \`${e.name}\` — ${e.path}:${e.line}`);n.deadInDocs.length>5&&a.push(`- _... ${n.deadInDocs.length-5} more omitted_`)}return n.totalDeadSource>0?a.push(``,`---`,`_Next: \`codemod\` to remove ${n.totalDeadSource} unused exports | \`symbol\` to verify usage before removing_`):a.push(``,`---`,"_Next: `check` — no dead symbols found, validate types and lint_"),{content:[{type:`text`,text:a.join(`
8
- `)}],structuredContent:{symbols:[...n.deadInSource,...n.deadInDocs].map(e=>({name:e.name,path:e.path,...e.line===void 0?{}:{line:e.line},kind:e.kind})),totalDead:n.totalDeadSource+n.totalDeadDocs}}}catch(e){return E.error(`Dead symbol scan failed`,g(e)),{content:[{type:`text`,text:`Dead symbol scan failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function P(e){let t=[`Symbol: ${e.name}`];if(e.definedIn){let n=`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`;e.definedIn.signature&&(n+=`\nSignature: ${e.definedIn.signature}`),t.push(n)}else t.push(`Defined in: not found`);if(t.push(``,`Imported by:`),e.importedBy.length===0)t.push(` none`);else for(let n of e.importedBy)t.push(` - ${n.path}:${n.line} ${n.importStatement}`);if(t.push(``,`Referenced in:`),e.referencedIn.length===0)t.push(` none`);else for(let n of e.referencedIn){let e=`scope`in n&&n.scope?` in ${n.scope}()`:``;t.push(` - ${n.path}:${n.line}${e} ${n.context}`)}if(e.graphContext){let n=e.graphContext;t.push(``,`Graph context:`),n.definingModule&&t.push(` Module: ${n.definingModule}`),n.importedByModules.length>0&&t.push(` Imported by modules: ${n.importedByModules.join(`, `)}`),n.siblingSymbols.length>0&&t.push(` Sibling symbols: ${n.siblingSymbols.join(`, `)}`)}return t.join(`
9
- `)}function F(e){let t=[e.path,`Language: ${e.language}`,`Lines: ${e.lines}`,`Estimated tokens: ~${e.estimatedTokens}`,``,`Imports (${e.imports.length}):`,...I(e.imports),``,`Exports (${e.exports.length}):`,...I(e.exports),``,`Functions (${e.functions.length}):`,...I(e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${`signature`in e&&e.signature?` — ${e.signature}`:``}`)),``,`Classes (${e.classes.length}):`,...I(e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${e.signature?` — ${e.signature}`:``}`)),``,`Interfaces (${e.interfaces.length}):`,...I(e.interfaces.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`)),``,`Types (${e.types.length}):`,...I(e.types.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`))];if(`importDetails`in e&&e.importDetails&&e.importDetails.length>0){let n=e.importDetails.filter(e=>e.isExternal).length,r=e.importDetails.length-n;t.push(``,`Import breakdown: ${n} external, ${r} internal`)}if(`callEdges`in e&&e.callEdges&&e.callEdges.length>0){t.push(``,`Call edges (${e.callEdges.length} intra-file):`);for(let n of e.callEdges.slice(0,30))t.push(` - ${n.caller}() → ${n.callee}() @ line ${n.line}`);e.callEdges.length>30&&t.push(` - ... ${e.callEdges.length-30} more`)}return t.join(`
10
- `)}function I(e){return e.length===0?[` none`]:e.map(e=>` - ${e}`)}export{D as registerCompactTool,N as registerDeadSymbolsTool,j as registerFileSummaryTool,k as registerFindTool,O as registerScopeMapTool,A as registerSymbolTool,M as registerTraceTool};
6
+ `)}],structuredContent:{matches:p.results.map(e=>({path:e.path,...e.lineRange?{line:e.lineRange.start}:{},matchType:e.source,preview:e.preview?.slice(0,200)??``})),totalMatches:p.totalFound,pattern:e??t??i??``,truncated:p.results.length<p.totalFound}}}catch(e){return O.error(`Find failed`,_(e)),{content:[{type:`text`,text:`Find failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function M(t,n,r,i){let a=e(`symbol`);t.registerTool(`symbol`,{title:a.title,description:`Find definition, imports, and references of a named symbol (function, class, type). For tracing data flow across call sites use trace instead.`,inputSchema:{name:f.string().describe(`Symbol name to look up (function, class, type, etc.)`),limit:f.number().min(1).max(50).default(20).describe(`Max results per category`),workspaces:f.array(f.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`)},outputSchema:o,annotations:a.annotations},async({name:e,limit:t,workspaces:a})=>{try{let o=await T(n,r,{name:e,limit:t,graphStore:i});if(a&&a.length>0){let r=l(a,h(process.cwd()));if(r.length>0){let{stores:i,closeAll:a}=await c(r);try{for(let[r,a]of i){let i=await T(n,a,{name:e,limit:t});i.definedIn&&!o.definedIn&&(o.definedIn={...i.definedIn,path:`[${r}] ${i.definedIn.path}`});for(let e of i.referencedIn)o.referencedIn.push({...e,path:`[${r}] ${e.path}`});if(i.importedBy){o.importedBy=o.importedBy??[];for(let e of i.importedBy)o.importedBy.push({...e,path:`[${r}] ${e.path}`})}}}finally{await a()}}}let s={name:o.name,definedIn:o.definedIn??null,importedBy:o.importedBy??[],referencedIn:o.referencedIn??[],graphContext:o.graphContext??null};return{content:[{type:`text`,text:I(o)}],structuredContent:s}}catch(e){return O.error(`Symbol lookup failed`,_(e)),{content:[{type:`text`,text:`Symbol lookup failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function N(t,n,i){let a=new v,o=e(`file_summary`);t.registerTool(`file_summary`,{title:o.title,description:`Create a concise structural summary of a source file: imports, exports, functions, classes, interfaces, and types.`,outputSchema:r,inputSchema:{path:f.string().describe(`Absolute path to the file to summarize`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response.`)},annotations:o.annotations},async({path:e,max_tokens:t})=>{try{let r=u(e)?e:d(i,e);if((await p(r)).isDirectory()){let n=await a.analyze(r,{format:`markdown`,maxDepth:3,maxTokens:t}),i=n.data.stats?.languages??{},o=Object.entries(i).sort((e,t)=>t[1]-e[1])[0]?.[0],s=`📁 **Directory**: \`${e}\`\n\n${n.output}\n\n---\n_Path is a directory. Showing structure analysis. Use \`analyze_structure\` for deeper analysis with custom depth._`;return{content:[{type:`text`,text:t?D(s,t):s}],structuredContent:{path:r,language:o??`directory`,lines:0,imports:0,exports:0,functions:0,classes:0}}}let o=await b({path:r,content:(await n.get(r)).content});return{content:[{type:`text`,text:L(o)}],structuredContent:{path:o.path,language:o.language,lines:o.lines,imports:o.imports?.length??0,exports:o.exports?.length??0,functions:o.functions?.length??0,classes:o.classes?.length??0}}}catch(e){return O.error(`File summary failed`,_(e)),{content:[{type:`text`,text:`File summary failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function P(t,n,r,i){let a=e(`trace`);t.registerTool(`trace`,{title:a.title,description:`Follow data flow forward/backward across imports and call sites from a starting symbol or file:line. For finding a single symbol definition use symbol instead.`,inputSchema:{start:f.string().describe(`Starting point — symbol name or file:line reference`),direction:f.enum([`forward`,`backward`,`both`]).describe(`Which direction to trace relationships`),max_depth:f.number().min(1).max(10).default(3).optional().describe(`Maximum trace depth`)},annotations:a.annotations},async({start:e,direction:t,max_depth:a})=>{try{let o=await E(n,r,{start:e,direction:t,maxDepth:a,graphStore:i}),s=[`## Trace: ${o.start}`,`Direction: ${o.direction} | Depth: ${o.depth}`,``];if(o.graphContext&&(s.push(`### Graph Context`),o.graphContext.definingModule&&s.push(`- Module: ${o.graphContext.definingModule}`),o.graphContext.community&&s.push(`- Community: ${o.graphContext.community}`),o.graphContext.importedByModules.length>0&&s.push(`- Imported by modules: ${o.graphContext.importedByModules.join(`, `)}`),o.graphContext.siblingSymbols.length>0&&s.push(`- Sibling symbols: ${o.graphContext.siblingSymbols.join(`, `)}`),s.push(``)),o.nodes.length===0)s.push(`No connections found.`);else{let e=o.nodes.filter(e=>e.relationship===`calls`),t=o.nodes.filter(e=>e.relationship===`called-by`),n=o.nodes.filter(e=>e.relationship===`imports`),r=o.nodes.filter(e=>e.relationship===`imported-by`),i=o.nodes.filter(e=>e.relationship===`references`);if(e.length>0){s.push(`### Calls (${e.length})`);for(let t of e){let e=t.scope?` (from ${t.scope}())`:``;s.push(`- ${t.symbol}() — ${t.path}:${t.line}${e}`)}s.push(``)}if(t.length>0){s.push(`### Called by (${t.length})`);for(let e of t){let t=e.scope?` in ${e.scope}()`:``;s.push(`- ${e.symbol}()${t} — ${e.path}:${e.line}`)}s.push(``)}if(n.length>0){s.push(`### Imports (${n.length})`);for(let e of n)s.push(`- ${e.symbol} — ${e.path}:${e.line}`);s.push(``)}if(r.length>0){s.push(`### Imported by (${r.length})`);for(let e of r)s.push(`- ${e.path}:${e.line}`);s.push(``)}if(i.length>0){s.push(`### References (${i.length})`);for(let e of i)s.push(`- ${e.path}:${e.line}`);s.push(``)}}return s.push(`---`,"_Next: `symbol` for definition details | `compact` to read a referenced file | `blast_radius` for impact analysis_"),{content:[{type:`text`,text:s.join(`
7
+ `)}],structuredContent:{start:o.start,direction:o.direction,depth:o.depth,nodes:o.nodes,graphContext:o.graphContext??null}}}catch(e){return O.error(`Trace failed`,_(e)),{content:[{type:`text`,text:`Trace failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function F(t,r,i){let a=e(`dead_symbols`);t.registerTool(`dead_symbols`,{title:a.title,description:`Find exported symbols that appear to be unused because they are never imported or re-exported.`,outputSchema:n,inputSchema:{path:f.string().optional().describe(`Root path to scope the search (default: cwd)`),limit:f.number().min(1).max(500).default(100).optional().describe(`Maximum exported symbols to scan`)},annotations:a.annotations},async({path:e,limit:t})=>{try{let n=await S(r,i,{rootPath:e,limit:t}),a=[`## Dead Symbol Analysis`,``,`**Exports scanned:** ${n.totalExports}`,`**Dead in source:** ${n.totalDeadSource} (actionable)`,`**Dead in docs:** ${n.totalDeadDocs} (informational — code samples in .md files)`,``];if(n.deadInSource.length>0){a.push(`### Dead in Source (actionable)`);for(let e of n.deadInSource)a.push(`- \`${e.name}\` (${e.kind}) — ${e.path}:${e.line}`);a.push(``)}if(n.deadInDocs.length>0){a.push(`### Dead in Docs (informational)`),a.push(`_${n.totalDeadDocs} symbol(s) found only in documentation code samples — not actionable dead code._`);for(let e of n.deadInDocs.slice(0,5))a.push(`- \`${e.name}\` — ${e.path}:${e.line}`);n.deadInDocs.length>5&&a.push(`- _... ${n.deadInDocs.length-5} more omitted_`)}return n.totalDeadSource>0?a.push(``,`---`,`_Next: \`codemod\` to remove ${n.totalDeadSource} unused exports | \`symbol\` to verify usage before removing_`):a.push(``,`---`,"_Next: `check` — no dead symbols found, validate types and lint_"),{content:[{type:`text`,text:a.join(`
8
+ `)}],structuredContent:{symbols:[...n.deadInSource,...n.deadInDocs].map(e=>({name:e.name,path:e.path,...e.line===void 0?{}:{line:e.line},kind:e.kind})),totalDead:n.totalDeadSource+n.totalDeadDocs}}}catch(e){return O.error(`Dead symbol scan failed`,_(e)),{content:[{type:`text`,text:`Dead symbol scan failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function I(e){let t=[`Symbol: ${e.name}`];if(e.definedIn){let n=`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`;e.definedIn.signature&&(n+=`\nSignature: ${e.definedIn.signature}`),t.push(n)}else t.push(`Defined in: not found`);if(t.push(``,`Imported by:`),e.importedBy.length===0)t.push(` none`);else for(let n of e.importedBy)t.push(` - ${n.path}:${n.line} ${n.importStatement}`);if(t.push(``,`Referenced in:`),e.referencedIn.length===0)t.push(` none`);else for(let n of e.referencedIn){let e=`scope`in n&&n.scope?` in ${n.scope}()`:``;t.push(` - ${n.path}:${n.line}${e} ${n.context}`)}if(e.graphContext){let n=e.graphContext;t.push(``,`Graph context:`),n.definingModule&&t.push(` Module: ${n.definingModule}`),n.importedByModules.length>0&&t.push(` Imported by modules: ${n.importedByModules.join(`, `)}`),n.siblingSymbols.length>0&&t.push(` Sibling symbols: ${n.siblingSymbols.join(`, `)}`)}return t.join(`
9
+ `)}function L(e){let t=[e.path,`Language: ${e.language}`,`Lines: ${e.lines}`,`Estimated tokens: ~${e.estimatedTokens}`,``,`Imports (${e.imports.length}):`,...R(e.imports),``,`Exports (${e.exports.length}):`,...R(e.exports),``,`Functions (${e.functions.length}):`,...R(e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${`signature`in e&&e.signature?` — ${e.signature}`:``}`)),``,`Classes (${e.classes.length}):`,...R(e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${e.signature?` — ${e.signature}`:``}`)),``,`Interfaces (${e.interfaces.length}):`,...R(e.interfaces.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`)),``,`Types (${e.types.length}):`,...R(e.types.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`))];if(`importDetails`in e&&e.importDetails&&e.importDetails.length>0){let n=e.importDetails.filter(e=>e.isExternal).length,r=e.importDetails.length-n;t.push(``,`Import breakdown: ${n} external, ${r} internal`)}if(`callEdges`in e&&e.callEdges&&e.callEdges.length>0){t.push(``,`Call edges (${e.callEdges.length} intra-file):`);for(let n of e.callEdges.slice(0,30))t.push(` - ${n.caller}() → ${n.callee}() @ line ${n.line}`);e.callEdges.length>30&&t.push(` - ... ${e.callEdges.length-30} more`)}return t.join(`
10
+ `)}function R(e){return e.length===0?[` none`]:e.map(e=>` - ${e}`)}export{k as registerCompactTool,F as registerDeadSymbolsTool,N as registerFileSummaryTool,j as registerFindTool,A as registerScopeMapTool,M as registerSymbolTool,P as registerTraceTool};
@@ -1,4 +1,4 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{HealthOutputSchema as t}from"../output-schemas.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";import{guide as a,health as o,processList as s,processLogs as c,processStart as l,processStatus as u,processStop as d,watchList as f,watchStart as p,watchStop as m,webFetch as h}from"../../../tools/dist/index.js";const g=r(`tools:infra`);function _(t){let r=e(`process`);t.registerTool(`process`,{title:r.title,description:`Start, stop, inspect, list, and tail logs for in-memory managed child processes.`,inputSchema:{action:n.enum([`start`,`stop`,`status`,`list`,`logs`]).describe(`Process action to perform`),id:n.string().optional().describe(`Managed process ID`),command:n.string().optional().describe(`Executable to start`),args:n.array(n.string()).optional().describe(`Arguments for start actions`),tail:n.number().min(1).max(500).optional().describe(`Log lines to return for logs actions`)},annotations:r.annotations},async({action:e,id:t,command:n,args:r,tail:a})=>{try{switch(e){case`start`:if(!t||!n)throw Error(`id and command are required for start`);return{content:[{type:`text`,text:JSON.stringify(l(t,n,r??[]))}]};case`stop`:if(!t)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify(d(t)??null)}]};case`status`:if(!t)throw Error(`id is required for status`);return{content:[{type:`text`,text:JSON.stringify(u(t)??null)}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(s())}]};case`logs`:if(!t)throw Error(`id is required for logs`);return{content:[{type:`text`,text:JSON.stringify(c(t,a))}]}}}catch(e){return g.error(`Process action failed`,i(e)),{content:[{type:`text`,text:`Process action failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function v(t){let r=e(`watch`);t.registerTool(`watch`,{title:r.title,description:`Watch a directory for file changes (create/modify/delete). Actions: start (begin watching), stop (by ID), list (show active watchers). Events are emitted as structured JSON with path, event type, and timestamp.`,inputSchema:{action:n.enum([`start`,`stop`,`list`]).describe(`Watch action to perform`),path:n.string().optional().describe(`Directory path to watch for start actions`),id:n.string().optional().describe(`Watcher ID for stop actions`)},annotations:r.annotations},async({action:e,path:t,id:n})=>{try{switch(e){case`start`:if(!t)throw Error(`path is required for start`);return{content:[{type:`text`,text:JSON.stringify(p({path:t}))}]};case`stop`:if(!n)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify({stopped:m(n)})}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(f())}]}}}catch(e){return g.error(`Watch action failed`,i(e)),{content:[{type:`text`,text:`Watch action failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function y(r){let a=e(`health`);r.registerTool(`health`,{title:a.title,description:`Run project health checks — verifies package.json, tsconfig, scripts, lockfile, README, LICENSE, .gitignore.`,outputSchema:t,inputSchema:{path:n.string().optional().describe(`Root directory to check (defaults to cwd)`)},annotations:a.annotations},async({path:e})=>{try{let t=o(e),n={ok:t.checks.every(e=>e.status!==`fail`),checks:t.checks.map(e=>({name:e.name,ok:e.status===`pass`,message:e.message}))};return{content:[{type:`text`,text:JSON.stringify(t)}],structuredContent:n}}catch(e){return g.error(`Health check failed`,i(e)),{content:[{type:`text`,text:`Health check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function b(t){let r=e(`web_fetch`);t.registerTool(`web_fetch`,{title:r.title,description:`PREFERRED web fetcher — fetch one or many URLs and convert to LLM-optimized markdown. Pass one URL or multiple for parallel fetching. Supports CSS selectors, 4 output modes (markdown/raw/links/outline), smart paragraph-boundary truncation. Strips scripts/styles/nav automatically.`,inputSchema:{urls:n.array(n.string().url()).min(1).max(10).describe('URLs to fetch (1–10). Single URL: `["https://..."]`. Multiple fetched in parallel.'),mode:n.enum([`markdown`,`raw`,`links`,`outline`]).default(`markdown`).describe(`Output mode: markdown (clean content), raw (HTML), links (extracted URLs), outline (heading hierarchy)`),selector:n.string().optional().describe(`CSS selector to extract a specific element instead of auto-detecting main content`),max_length:n.number().min(500).max(1e5).default(15e3).describe(`Max characters in output — truncates at paragraph boundaries`),include_metadata:n.boolean().default(!0).describe(`Include page title, description, and URL as a header`),include_links:n.boolean().default(!1).describe(`Append extracted links list at the end`),include_images:n.boolean().default(!1).describe(`Include image alt texts inline`),timeout:n.number().min(1e3).max(6e4).default(15e3).describe(`Request timeout in milliseconds`)},annotations:r.annotations},async({urls:e,mode:t,selector:n,max_length:r,include_metadata:a,include_links:o,include_images:s,timeout:c})=>{let l=e,u=async(e,i)=>{let l=await h({url:e,mode:t,selector:n,maxLength:r,includeMetadata:a,includeLinks:o,includeImages:s,timeout:c}),u=[i?`## ${i} ${l.title||`Web Page`}\n> Source: ${e}`:`## ${l.title||`Web Page`}`,``,l.content];return l.truncated&&u.push(``,`_Original length: ${l.originalLength.toLocaleString()} chars_`),u.join(`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{HealthOutputSchema as t}from"../output-schemas.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";import{guide as a,health as o,processList as s,processLogs as c,processStart as l,processStatus as u,processStop as d,watchList as f,watchStart as p,watchStop as m,webFetch as h}from"../../../tools/dist/index.js";const g=r(`tools:infra`);function _(t){let r=e(`process`);t.registerTool(`process`,{title:r.title,description:`Start, stop, inspect, list, and tail logs for in-memory managed child processes.`,inputSchema:{action:n.enum([`start`,`stop`,`status`,`list`,`logs`]).describe(`Process action to perform`),id:n.string().optional().describe(`Managed process ID`),command:n.string().optional().describe(`Executable to start`),args:n.array(n.string()).optional().describe(`Arguments for start actions`),tail:n.number().min(1).max(500).optional().describe(`Log lines to return for logs actions`)},annotations:r.annotations},async({action:e,id:t,command:n,args:r,tail:a})=>{try{switch(e){case`start`:if(!t||!n)throw Error(`id and command are required for start`);return{content:[{type:`text`,text:JSON.stringify(l(t,n,r??[]))}]};case`stop`:if(!t)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify(d(t)??null)}]};case`status`:if(!t)throw Error(`id is required for status`);return{content:[{type:`text`,text:JSON.stringify(u(t)??null)}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(s())}]};case`logs`:if(!t)throw Error(`id is required for logs`);return{content:[{type:`text`,text:JSON.stringify(c(t,a))}]}}}catch(e){return g.error(`Process action failed`,i(e)),{content:[{type:`text`,text:`Process action failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function v(t){let r=e(`watch`);t.registerTool(`watch`,{title:r.title,description:`Watch a directory for file changes (create/modify/delete). Actions: start (begin watching), stop (by ID), list (show active watchers). Events are emitted as structured JSON with path, event type, and timestamp.`,inputSchema:{action:n.enum([`start`,`stop`,`list`]).describe(`Watch action to perform`),path:n.string().optional().describe(`Directory path to watch for start actions`),id:n.string().optional().describe(`Watcher ID for stop actions`)},annotations:r.annotations},async({action:e,path:t,id:n})=>{try{switch(e){case`start`:if(!t)throw Error(`path is required for start`);return{content:[{type:`text`,text:JSON.stringify(p({path:t}))}]};case`stop`:if(!n)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify({stopped:m(n)})}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(f())}]}}}catch(e){return g.error(`Watch action failed`,i(e)),{content:[{type:`text`,text:`Watch action failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function y(r){let a=e(`health`);r.registerTool(`health`,{title:a.title,description:`Run project health checks — verifies package.json, tsconfig, scripts, lockfile, README, LICENSE, .gitignore.`,outputSchema:t,inputSchema:{path:n.string().optional().describe(`Root directory to check (defaults to cwd)`)},annotations:a.annotations},async({path:e})=>{try{let t=o(e),n={ok:t.checks.every(e=>e.status!==`fail`),checks:t.checks.map(e=>({name:e.name,ok:e.status===`pass`,message:e.message}))};return{content:[{type:`text`,text:JSON.stringify(t)}],structuredContent:n}}catch(e){return g.error(`Health check failed`,i(e)),{content:[{type:`text`,text:`Health check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function b(t){let r=e(`web_fetch`);t.registerTool(`web_fetch`,{title:r.title,description:`PREFERRED web fetcher — fetch one or many URLs and convert to LLM-optimized markdown. Pass one URL or multiple for parallel fetching. Supports CSS selectors, 4 output modes (markdown/raw/links/outline), smart paragraph-boundary truncation. Strips scripts/styles/nav automatically.`,inputSchema:{urls:n.array(n.string().url()).min(1).max(10).describe('URLs to fetch (1–10). Single URL: `["https://..."]`. Multiple fetched in parallel.'),mode:n.enum([`markdown`,`raw`,`links`,`outline`]).default(`markdown`).describe(`Output mode: markdown (clean content), raw (HTML), links (extracted URLs), outline (heading hierarchy)`),selector:n.string().optional().describe(`CSS selector to extract a specific element instead of auto-detecting main content`),max_length:n.number().min(500).max(1e5).default(15e3).describe(`Max characters in output — truncates at paragraph boundaries`),include_metadata:n.boolean().default(!0).describe(`Include page title, description, and URL as a header`),include_links:n.boolean().default(!1).describe(`Append extracted links list at the end`),include_images:n.boolean().default(!1).describe(`Include image alt texts inline`),timeout:n.number().min(1e3).max(12e4).default(3e4).describe(`Request timeout in milliseconds`)},annotations:r.annotations},async({urls:e,mode:t,selector:n,max_length:r,include_metadata:a,include_links:o,include_images:s,timeout:c})=>{let l=e,u=async(e,i)=>{let l=await h({url:e,mode:t,selector:n,maxLength:r,includeMetadata:a,includeLinks:o,includeImages:s,timeout:c}),u=[i?`## ${i} ${l.title||`Web Page`}\n> Source: ${e}`:`## ${l.title||`Web Page`}`,``,l.content];return l.truncated&&u.push(``,`_Original length: ${l.originalLength.toLocaleString()} chars_`),u.join(`
2
2
  `)};if(l.length===1)try{return{content:[{type:`text`,text:await u(l[0])+"\n\n---\n_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._"}]}}catch(e){let t=e instanceof Error?e.message:String(e);return/HTTP [45]\d{2}/.test(t)?g.warn(`Web fetch failed`,{error:t}):g.error(`Web fetch failed`,i(e)),{content:[{type:`text`,text:`Web fetch failed: ${t}`}],isError:!0}}let d=l.length,f=await Promise.allSettled(l.map((e,t)=>u(e,`[${t+1}/${d}]`))),p=[],m=0;for(let e=0;e<f.length;e++){let t=f[e];if(t.status===`fulfilled`)p.push(t.value);else{m++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);/HTTP [45]\d{2}/.test(n)?g.warn(`Web fetch failed`,{url:l[e],error:n}):g.error(`Web fetch failed`,{url:l[e],...i(t.reason)}),p.push(`## ❌ Failed: ${l[e]}\n\n${n}`)}}let _=`_Fetched ${f.length-m}/${f.length} URLs successfully._`;return p.push(``,`---`,_,"_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._"),{content:[{type:`text`,text:p.join(`
3
3
 
4
4
  `)}],...m===f.length?{isError:!0}:{}}})}function x(t,r){let o=e(`guide`);t.registerTool(`guide`,{title:o.title,description:`Tool discovery — given a goal description, recommends which AI Kit tools to use and in what order. Matches against 10 predefined workflows: onboard, audit, bugfix, implement, refactor, search, context, memory, validate, analyze.`,inputSchema:{goal:n.string().describe(`What you want to accomplish (e.g., "audit this monorepo", "fix a failing test")`),max_recommendations:n.number().min(1).max(10).default(5).describe(`Maximum number of tool recommendations`)},annotations:o.annotations},async({goal:e,max_recommendations:t})=>{try{let n=a(e,t,r),i=[`## Recommended Workflow: **${n.workflow}**`,n.description,``,`### Tools`,...n.tools.map(e=>{let t=e.suggestedArgs?` — \`${JSON.stringify(e.suggestedArgs)}\``:``;return`${e.order}. **${e.tool}** — ${e.reason}${t}`})];return n.alternativeWorkflows.length>0&&i.push(``,`_Alternative workflows: ${n.alternativeWorkflows.join(`, `)}_`),i.push(``,`---`,"_Next: Run the first recommended tool, or use `guide` again with a more specific goal._"),{content:[{type:`text`,text:i.join(`
@@ -1,3 +1,3 @@
1
- import{getGcStatus as e}from"../auto-gc.js";import{getToolTelemetry as t}from"../replay-interceptor.js";import{getToolMeta as n}from"../tool-metadata.js";import{StatusOutputSchema as r}from"../output-schemas.js";import{autoUpgradeScaffold as i,getCurrentVersion as a,getUpgradeState as o}from"../version-check.js";import{existsSync as s,readFileSync as c,statSync as l}from"node:fs";import{resolve as u}from"node:path";import{homedir as d}from"node:os";import{AIKIT_PATHS as f,createLogger as p,serializeError as m}from"../../../core/dist/index.js";import{WasmRuntime as h}from"../../../chunker/dist/index.js";const g=p(`tools`);function _(e,t,n,r=15e3){let i,a=new Promise(e=>{i=setTimeout(()=>{g.warn(`Status sub-operation "${n}" timed out after ${r}ms`),e({value:t,timedOut:!0})},r)});return Promise.race([e.then(e=>(clearTimeout(i),{value:e,timedOut:!1}),e=>(clearTimeout(i),g.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}const v=5*6e4;let y=null,b=null;function x(){let e=Date.now();if(y&&e-y.ts<v)return y.value;try{let t=u(d(),`.copilot`,`.aikit-scaffold.json`);if(!s(t))return y={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return y={value:n,ts:e},n}catch{return y={value:null,ts:e},null}}function S(){let e=Date.now();if(b&&e-b.ts<v)return b.value;try{let t=u(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!s(t))return b={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return b={value:n,ts:e},n}catch{return b={value:null,ts:e},null}}function C(e){let t=n(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:t.annotations},async()=>{let e=a(),t=x(),n=S(),r=t!=null&&t!==e,s=n!=null&&n!==e,c=[`## AI Kit Status`,``,`⏳ **AI Kit is initializing** — index stats will be available shortly.`,``,`### Runtime`,`- **Tree-sitter (WASM)**: ${h.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`,``,`### Version`,`- **Server**: ${e}`,`- **Scaffold (user)**: ${t??`not installed`}`,`- **Scaffold (workspace)**: ${n??`not installed`}`];if(r||s){let a=o(),l=[];r&&l.push(`user scaffold v${t}`),s&&l.push(`workspace scaffold v${n}`);let u=l.join(`, `);a.state===`success`?c.push(``,`### ✅ Upgrade Applied`,`- Server v${e} — ${u} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):a.state===`pending`?c.push(``,`### ⏳ Upgrade In Progress`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade is running in the background…`):a.state===`failed`?(i(),c.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${e} ≠ ${u}`,`- Error: ${a.error??`unknown`}`)):(i(),c.push(``,`### ⬆ Upgrade Available`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade triggered — check again shortly.`))}let l={totalRecords:0,totalFiles:0,lastIndexedAt:null,onboarded:!1,onboardDir:``,contentTypes:{},wasmAvailable:!!h.get(),graphStats:null,curatedCount:0,serverVersion:e,scaffoldVersion:t??null,workspaceScaffoldVersion:n??null,upgradeAvailable:r||s};return{content:[{type:`text`,text:c.join(`
2
- `)}],structuredContent:l}})}function w(c,d,p,v,y,b,C,w){let T=n(`status`);c.registerTool(`status`,{title:T.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:T.annotations},async()=>{let n=[];try{let[r,c]=await Promise.all([_(d.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),_(d.listSourcePaths(),[],`store.listSourcePaths`)]),m=r.value;r.timedOut&&n.push(`⚠ Index stats timed out — values may be incomplete`);let g=c.value;c.timedOut&&n.push(`⚠ File listing timed out`);let T=null,E=0,D=[`## AI Kit Status`,``,`- **Total Records**: ${m.totalRecords}`,`- **Total Files**: ${m.totalFiles}`,`- **Last Indexed**: ${m.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(m.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...g.slice(0,50).map(e=>`- ${e}`),g.length>50?`\n... and ${g.length-50} more files`:``];if(p)try{let e=await _(p.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(e.timedOut)n.push(`⚠ Graph stats timed out`),D.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let t=e.value;T={nodes:t.nodeCount,edges:t.edgeCount},D.push(``,`### Knowledge Graph`,`- **Nodes**: ${t.nodeCount}`,`- **Edges**: ${t.edgeCount}`,...Object.entries(t.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await _(p.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||D.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&D.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{D.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let O=b?.onboardDir??u(process.cwd(),f.aiContext),k=s(O),A=y?.onboardComplete||k;if(D.push(``,`### Onboard Status`,A?`- ✅ Complete${y?.onboardTimestamp?` (last: ${y.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${O}\``),v)try{let e=await _(v.list(),[],`curated.list`);if(e.timedOut)n.push(`⚠ Curated knowledge listing timed out`),D.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let t=e.value;E=t.length,D.push(``,`### Curated Knowledge`,t.length>0?`- ${t.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{D.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let j=0;if(m.lastIndexedAt){j=new Date(m.lastIndexedAt).getTime();let e=(Date.now()-j)/(1e3*60*60);D.push(``,`### Index Freshness`,e>24?C===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}if(C===`smart`)if(D.push(``,`### Smart Indexing`),w){let e=w();e?D.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):D.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else D.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);{try{let e=u(process.cwd(),f.data,`stash`);if(s(e)){let t=l(e).mtimeMs;t>j&&(j=t)}}catch{}let e=[];if(v)try{let t=E>0?await v.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>j&&(j=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=j>0?Date.now()-j:0;if(t>=144e5){let n=Math.floor(t/36e5);if(D.push(``,`### 🌅 Session Briefing`,`_${n}+ hours since last activity — here's what to pick up:_`,``),e.length>0){D.push(`**Recent decisions/notes:**`);for(let t of e)D.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}D.push(``,`**Suggested next steps:**`,'- `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — find your last checkpoint',"- `restore({})` — resume from a saved checkpoint","- `list()` — browse all stored knowledge")}}D.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${h.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`);let M=x(),N=S(),P=a(),F=M!=null&&M!==P,I=N!=null&&N!==P;if(F||I){let e=o(),t=[];F&&t.push(`user scaffold v${M}`),I&&t.push(`workspace scaffold v${N}`);let n=t.join(`, `);e.state===`success`?D.push(``,`### ✅ Upgrade Applied`,`- Server v${P} — ${n} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?D.push(``,`### ⏳ Upgrade In Progress`,`- Server v${P} ≠ ${n}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(i(),D.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${P} ≠ ${n}`,`- Error: ${e.error??`unknown`}`)):(i(),D.push(``,`### ⬆ Upgrade Available`,`- Server v${P} ≠ ${n}`,`- Auto-upgrade triggered — check again shortly.`))}n.length>0&&D.push(``,`### ⚠ Warnings`,...n.map(e=>`- ${e}`));let L=t();if(L.length>0){let e=L.sort((e,t)=>t.callCount-e.callCount);D.push(``,`### Tool Usage This Session`,``),D.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),D.push(`|------|-------|-----------|------------|--------|-------------|`);for(let t of e.slice(0,15)){let e=Math.round(t.totalInputChars/4),n=Math.round(t.totalOutputChars/4),r=Math.round(t.totalDurationMs/t.callCount);D.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let R=e();if(R.bufferSize>=10){let e=R.state===`healthy`?`🟢`:R.state===`degraded`?`🔴`:`🟡`;D.push(``,`### Auto-GC: ${e} ${R.state}`),D.push(`- p95 latency: ${R.p95}ms | buffer: ${R.bufferSize} samples`),R.gcCount>0&&D.push(`- GC cycles triggered: ${R.gcCount}`)}let z=D.join(`
3
- `),B={totalRecords:m.totalRecords,totalFiles:m.totalFiles,lastIndexedAt:m.lastIndexedAt??null,onboarded:A,onboardDir:O,contentTypes:m.contentTypeBreakdown,wasmAvailable:!!h.get(),graphStats:T,curatedCount:E,serverVersion:P,scaffoldVersion:M??null,workspaceScaffoldVersion:N??null,upgradeAvailable:F||I};return{content:[{type:`text`,text:z+(C===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph(stats)` to explore the knowledge graph. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._")}],structuredContent:B}}catch(e){return g.error(`Status failed`,m(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{x as getScaffoldVersion,S as getWorkspaceScaffoldVersion,C as registerEarlyStatusTool,w as registerStatusTool};
1
+ import{getGcStatus as e}from"../auto-gc.js";import{getToolTelemetry as t}from"../replay-interceptor.js";import{getToolMeta as n}from"../tool-metadata.js";import{StatusOutputSchema as r}from"../output-schemas.js";import{autoUpgradeScaffold as i,getCurrentVersion as a,getUpgradeState as o}from"../version-check.js";import{existsSync as s,readFileSync as c,statSync as l}from"node:fs";import{resolve as u}from"node:path";import{homedir as d}from"node:os";import{AIKIT_PATHS as f,createLogger as p,serializeError as m}from"../../../core/dist/index.js";import{WasmRuntime as h}from"../../../chunker/dist/index.js";const g=p(`tools`);function _(e,t,n,r=15e3){let i,a=new Promise(e=>{i=setTimeout(()=>{g.warn(`Status sub-operation "${n}" timed out after ${r}ms`),e({value:t,timedOut:!0})},r)});return Promise.race([e.then(e=>(clearTimeout(i),{value:e,timedOut:!1}),e=>(clearTimeout(i),g.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}const v=5*6e4;let y=null,b=null;function x(e,t,n,r){let i=Math.min(e/2e4,1),a=Math.min((t+n)/5e4,1),o=Math.min(r/200,1);return Math.round(i*40+a*35+o*25)}function S(){let e=Date.now();if(y&&e-y.ts<v)return y.value;try{let t=u(d(),`.copilot`,`.aikit-scaffold.json`);if(!s(t))return y={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return y={value:n,ts:e},n}catch{return y={value:null,ts:e},null}}function C(){let e=Date.now();if(b&&e-b.ts<v)return b.value;try{let t=u(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!s(t))return b={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return b={value:n,ts:e},n}catch{return b={value:null,ts:e},null}}function w(e){let t=n(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:t.annotations},async()=>{let e=a(),t=S(),n=C(),r=t!=null&&t!==e,s=n!=null&&n!==e,c=[`## AI Kit Status`,``,`⏳ **AI Kit is initializing** — index stats will be available shortly.`,``,`### Runtime`,`- **Tree-sitter (WASM)**: ${h.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`,``,`### Version`,`- **Server**: ${e}`,`- **Scaffold (user)**: ${t??`not installed`}`,`- **Scaffold (workspace)**: ${n??`not installed`}`];if(r||s){let a=o(),l=[];r&&l.push(`user scaffold v${t}`),s&&l.push(`workspace scaffold v${n}`);let u=l.join(`, `);a.state===`success`?c.push(``,`### ✅ Upgrade Applied`,`- Server v${e} — ${u} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):a.state===`pending`?c.push(``,`### ⏳ Upgrade In Progress`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade is running in the background…`):a.state===`failed`?(i(),c.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${e} ≠ ${u}`,`- Error: ${a.error??`unknown`}`)):(i(),c.push(``,`### ⬆ Upgrade Available`,`- Server v${e} ≠ ${u}`,`- Auto-upgrade triggered — check again shortly.`))}let l={totalRecords:0,totalFiles:0,lastIndexedAt:null,onboarded:!1,onboardDir:``,contentTypes:{},wasmAvailable:!!h.get(),graphStats:null,curatedCount:0,serverVersion:e,scaffoldVersion:t??null,workspaceScaffoldVersion:n??null,upgradeAvailable:r||s,contextPressure:0};return{content:[{type:`text`,text:c.join(`
2
+ `)}],structuredContent:l}})}function T(c,d,p,v,y,b,w,T){let E=n(`status`);c.registerTool(`status`,{title:E.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:E.annotations},async()=>{let n=[];try{let[r,c]=await Promise.all([_(d.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),_(d.listSourcePaths(),[],`store.listSourcePaths`)]),m=r.value;r.timedOut&&n.push(`⚠ Index stats timed out — values may be incomplete`);let g=c.value;c.timedOut&&n.push(`⚠ File listing timed out`);let E=null,D=0,O=[`## AI Kit Status`,``,`- **Total Records**: ${m.totalRecords}`,`- **Total Files**: ${m.totalFiles}`,`- **Last Indexed**: ${m.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(m.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...g.slice(0,50).map(e=>`- ${e}`),g.length>50?`\n... and ${g.length-50} more files`:``];if(p)try{let e=await _(p.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(e.timedOut)n.push(`⚠ Graph stats timed out`),O.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let t=e.value;E={nodes:t.nodeCount,edges:t.edgeCount},O.push(``,`### Knowledge Graph`,`- **Nodes**: ${t.nodeCount}`,`- **Edges**: ${t.edgeCount}`,...Object.entries(t.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await _(p.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||O.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&O.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{O.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let k=b?.onboardDir??u(process.cwd(),f.aiContext),A=s(k),j=y?.onboardComplete||A;if(O.push(``,`### Onboard Status`,j?`- ✅ Complete${y?.onboardTimestamp?` (last: ${y.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${k}\``),v)try{let e=await _(v.list(),[],`curated.list`);if(e.timedOut)n.push(`⚠ Curated knowledge listing timed out`),O.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let t=e.value;D=t.length,O.push(``,`### Curated Knowledge`,t.length>0?`- ${t.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{O.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let M=x(m.totalRecords,E?.nodes??0,E?.edges??0,D);O.push(``),O.push(`## 📊 Context Pressure: ${M}/100`),M>=80?O.push(`⚠️ High pressure — consider pruning stale entries or compacting context.`):M>=50?O.push(`ℹ️ Moderate pressure — knowledge base is well-populated.`):O.push(`✅ Low pressure — plenty of headroom for more content.`);let N=0;if(m.lastIndexedAt){N=new Date(m.lastIndexedAt).getTime();let e=(Date.now()-N)/(1e3*60*60);O.push(``,`### Index Freshness`,e>24?w===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}if(w===`smart`)if(O.push(``,`### Smart Indexing`),T){let e=T();e?O.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):O.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else O.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);{try{let e=u(process.cwd(),f.data,`stash`);if(s(e)){let t=l(e).mtimeMs;t>N&&(N=t)}}catch{}let e=[];if(v)try{let t=D>0?await v.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>N&&(N=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=N>0?Date.now()-N:0;if(t>=144e5){let n=Math.floor(t/36e5);if(O.push(``,`### 🌅 Session Briefing`,`_${n}+ hours since last activity — here's what to pick up:_`,``),e.length>0){O.push(`**Recent decisions/notes:**`);for(let t of e)O.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}O.push(``,`**Suggested next steps:**`,'- `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — find your last checkpoint',"- `restore({})` — resume from a saved checkpoint","- `list()` — browse all stored knowledge")}}O.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${h.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`);let P=S(),F=C(),I=a(),L=P!=null&&P!==I,R=F!=null&&F!==I;if(L||R){let e=o(),t=[];L&&t.push(`user scaffold v${P}`),R&&t.push(`workspace scaffold v${F}`);let n=t.join(`, `);e.state===`success`?O.push(``,`### ✅ Upgrade Applied`,`- Server v${I} — ${n} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?O.push(``,`### ⏳ Upgrade In Progress`,`- Server v${I} ≠ ${n}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(i(),O.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${I} ≠ ${n}`,`- Error: ${e.error??`unknown`}`)):(i(),O.push(``,`### ⬆ Upgrade Available`,`- Server v${I} ≠ ${n}`,`- Auto-upgrade triggered — check again shortly.`))}n.length>0&&O.push(``,`### ⚠ Warnings`,...n.map(e=>`- ${e}`));let z=t();if(z.length>0){let e=z.sort((e,t)=>t.callCount-e.callCount);O.push(``,`### Tool Usage This Session`,``),O.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),O.push(`|------|-------|-----------|------------|--------|-------------|`);for(let t of e.slice(0,15)){let e=Math.round(t.totalInputChars/4),n=Math.round(t.totalOutputChars/4),r=Math.round(t.totalDurationMs/t.callCount);O.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let B=e();if(B.bufferSize>=10){let e=B.state===`healthy`?`🟢`:B.state===`degraded`?`🔴`:`🟡`;O.push(``,`### Auto-GC: ${e} ${B.state}`),O.push(`- p95 latency: ${B.p95}ms | buffer: ${B.bufferSize} samples`),B.gcCount>0&&O.push(`- GC cycles triggered: ${B.gcCount}`)}let V=O.join(`
3
+ `),H={totalRecords:m.totalRecords,totalFiles:m.totalFiles,lastIndexedAt:m.lastIndexedAt??null,onboarded:j,onboardDir:k,contentTypes:m.contentTypeBreakdown,wasmAvailable:!!h.get(),graphStats:E,curatedCount:D,serverVersion:I,scaffoldVersion:P??null,workspaceScaffoldVersion:F??null,upgradeAvailable:L||R,contextPressure:M};return{content:[{type:`text`,text:V+(w===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph(stats)` to explore the knowledge graph. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._")}],structuredContent:H}}catch(e){return g.error(`Status failed`,m(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{S as getScaffoldVersion,C as getWorkspaceScaffoldVersion,w as registerEarlyStatusTool,T as registerStatusTool};
@@ -1 +1 @@
1
- const e=[{name:`onboard`,description:`First-time codebase exploration and understanding`,keywords:[`onboard`,`new project`,`understand`,`explore`,`first time`,`getting started`,`learn`,`overview`],tools:[{tool:`status`,reason:`Check index health and record count`,order:1},{tool:`onboard`,reason:`Run all analysis tools in one command`,order:2,suggestedArgs:{path:`.`}},{tool:`search`,reason:`Find specific topics of interest`,order:3},{tool:`graph`,reason:`Explore module relationships`,order:4,suggestedArgs:{action:`stats`}}]},{name:`audit`,description:`Assess project health, quality, and structure`,keywords:[`audit`,`health`,`quality`,`assess`,`review project`,`check quality`,`code quality`,`tech debt`],tools:[{tool:`status`,reason:`Check index freshness`,order:1},{tool:`audit`,reason:`Unified audit report with score and recommendations`,order:2,suggestedArgs:{detail:`summary`}},{tool:`check`,reason:`Typecheck + lint validation`,order:3},{tool:`health`,reason:`Detailed health checks on package.json, tsconfig, etc.`,order:4}]},{name:`bugfix`,description:`Diagnose and fix a bug or failing test`,keywords:[`bug`,`fix`,`debug`,`error`,`failing`,`broken`,`crash`,`wrong`,`issue`,`problem`,`not working`],tools:[{tool:`parse_output`,reason:`Parse error output from build tools (tsc, vitest, biome)`,order:1},{tool:`symbol`,reason:`Find definition and all references of the failing symbol`,order:2},{tool:`trace`,reason:`Trace call chain backward from the failure point`,order:3,suggestedArgs:{direction:`backward`}},{tool:`search`,reason:`Search for related patterns or similar fixes`,order:4},{tool:`test_run`,reason:`Re-run tests after fix`,order:5}]},{name:`implement`,description:`Add a new feature or implement a change`,keywords:[`implement`,`add feature`,`new feature`,`build`,`create`,`add`,`develop`,`write code`],tools:[{tool:`scope_map`,reason:`Generate a reading plan for affected files`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2},{tool:`find`,reason:`Find usage examples of similar patterns`,order:3,suggestedArgs:{mode:`examples`}},{tool:`check`,reason:`Validate after implementation`,order:4},{tool:`test_run`,reason:`Run tests to verify`,order:5},{tool:`blast_radius`,reason:`Check impact of changes`,order:6}]},{name:`refactor`,description:`Restructure or clean up existing code`,keywords:[`refactor`,`restructure`,`clean up`,`reorganize`,`rename`,`move`,`extract`,`DRY`,`dead code`],tools:[{tool:`dead_symbols`,reason:`Find unused exports to remove`,order:1},{tool:`symbol`,reason:`Find all references before renaming`,order:2},{tool:`blast_radius`,reason:`Assess impact before making changes`,order:3},{tool:`rename`,reason:`Safe cross-file rename`,order:4},{tool:`check`,reason:`Validate after refactoring`,order:5},{tool:`test_run`,reason:`Ensure no regressions`,order:6}]},{name:`search`,description:`Find specific code, patterns, or information`,keywords:[`find`,`search`,`where`,`locate`,`look for`,`grep`,`which file`,`how does`],tools:[{tool:`search`,reason:`Hybrid semantic + keyword search`,order:1},{tool:`find`,reason:`Federated search with glob and regex`,order:2},{tool:`symbol`,reason:`Resolve a specific symbol definition and references`,order:3},{tool:`graph`,reason:`Explore entity relationships`,order:4,suggestedArgs:{action:`neighbors`}}]},{name:`context`,description:`Compress or manage context for efficient LLM interaction`,keywords:[`context`,`compress`,`summarize`,`too long`,`token`,`budget`,`reduce`,`compact`],tools:[{tool:`file_summary`,reason:`Quick structural overview without reading full file`,order:1},{tool:`compact`,reason:`Compress file to relevant sections`,order:2,suggestedArgs:{segmentation:`paragraph`}},{tool:`digest`,reason:`Compress multiple sources into budgeted summary`,order:3},{tool:`stratum_card`,reason:`Generate reusable context cards`,order:4}]},{name:`memory`,description:`Manage persistent knowledge across sessions`,keywords:[`memory`,`remember`,`persist`,`save`,`recall`,`decision`,`convention`,`session`,`checkpoint`],tools:[{tool:`list`,reason:`See all stored knowledge entries`,order:1},{tool:`search`,reason:`Search curated knowledge`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Store a new decision or pattern`,order:3},{tool:`checkpoint`,reason:`Save/restore session progress`,order:4},{tool:`stash`,reason:`Temporary key-value storage within session`,order:5}]},{name:`validate`,description:`Run checks, tests, and validation`,keywords:[`validate`,`check`,`test`,`lint`,`typecheck`,`verify`,`CI`,`pass`,`run tests`],tools:[{tool:`check`,reason:`Typecheck + lint in one call`,order:1,suggestedArgs:{detail:`errors`}},{tool:`test_run`,reason:`Run tests with structured output`,order:2},{tool:`health`,reason:`Project health assessment`,order:3}]},{name:`analyze`,description:`Deep analysis of codebase structure, dependencies, or patterns`,keywords:[`analyze`,`dependency`,`structure`,`pattern`,`architecture`,`diagram`,`entry point`,`import`],tools:[{tool:`analyze_structure`,reason:`Project structure overview`,order:1},{tool:`analyze_dependencies`,reason:`Dependency graph and analysis`,order:2},{tool:`analyze_patterns`,reason:`Detect code patterns and conventions`,order:3},{tool:`analyze_entry_points`,reason:`Find handlers, exports, and entry points`,order:4},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams`,order:5}]},{name:`upgrade`,description:`Update AI Kit agents, prompts, skills, and scaffold to the latest version (user-level and workspace-level)`,keywords:[`upgrade`,`update`,`version`,`scaffold`,`outdated`,`mismatch`,`deploy`,`install`,`refresh`],tools:[{tool:`status`,reason:`Check current versions and detect mismatches — auto-triggers upgrade when a version mismatch is found`,order:1},{tool:`reindex`,reason:`Refresh the index after the upgrade completes`,order:2},{tool:`produce_knowledge`,reason:`Regenerate codebase analysis with updated tooling`,order:3,suggestedArgs:{path:`.`}}]},{name:`flow`,description:`Manage development flows — structured step-by-step processes for tasks`,keywords:[`flow`,`workflow`,`step`,`process`,`pipeline`,`lifecycle`,`sequence`,`start flow`,`flow status`],tools:[{tool:`flow_list`,reason:`List all available flows (builtin + custom)`,order:1},{tool:`flow_status`,reason:`Check current active flow and step`,order:2},{tool:`flow_start`,reason:`Start a named flow`,order:3},{tool:`flow_step`,reason:`Advance to next step, skip, or redo`,order:4},{tool:`flow_read_instruction`,reason:`Read the current step instruction`,order:5},{tool:`flow_info`,reason:`Get detailed info about a specific flow`,order:6},{tool:`flow_add`,reason:`Install a new custom flow`,order:7},{tool:`flow_update`,reason:`Update an existing custom flow`,order:8},{tool:`flow_remove`,reason:`Remove a custom flow`,order:9},{tool:`flow_reset`,reason:`Clear active flow state to start over`,order:10}]},{name:`web`,description:`Fetch web pages, search the web, or make HTTP API calls`,keywords:[`web`,`fetch`,`url`,`website`,`api`,`http`,`request`,`download`,`scrape`,`browse`,`web search`,`online`],tools:[{tool:`web_search`,reason:`Search the web for information`,order:1},{tool:`web_fetch`,reason:`Fetch and extract content from URLs`,order:2},{tool:`http`,reason:`Make raw HTTP requests to APIs`,order:3}]},{name:`brainstorm`,description:`Interactive ideation and creative exploration for design decisions`,keywords:[`brainstorm`,`ideate`,`ideas`,`explore`,`creative`,`design`,`options`,`approach`,`alternatives`,`think`],tools:[{tool:`brainstorm`,reason:`Interactive structured ideation session`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Persist chosen direction as a decision`,order:3,suggestedArgs:{category:`decisions`}}]},{name:`present`,description:`Display rich visual content — dashboards, charts, tables, timelines`,keywords:[`present`,`dashboard`,`chart`,`table`,`visualize`,`display`,`show`,`render`,`report`,`timeline`],tools:[{tool:`present`,reason:`Render rich HTML dashboards, charts, and tables`,order:1},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams for architecture views`,order:2},{tool:`measure`,reason:`Collect metrics to visualize`,order:3}]},{name:`quality`,description:`FORGE quality gates — classify task complexity, ground requirements, verify evidence`,keywords:[`quality`,`forge`,`evidence`,`gate`,`classify`,`ground`,`tier`,`critical`,`verify`,`proof`],tools:[{tool:`forge_classify`,reason:`Determine task tier (Floor/Standard/Critical)`,order:1},{tool:`forge_ground`,reason:`Ground requirements with evidence criteria`,order:2},{tool:`evidence_map`,reason:`Map evidence and run quality gates`,order:3,suggestedArgs:{action:`gate`}},{tool:`check`,reason:`Typecheck + lint validation`,order:4},{tool:`test_run`,reason:`Run tests for coverage evidence`,order:5}]},{name:`transform`,description:`Automated code transformations — codemods, renames, data transforms`,keywords:[`transform`,`codemod`,`rename`,`replace`,`migrate`,`convert`,`data transform`,`rewrite`,`bulk edit`],tools:[{tool:`rename`,reason:`Safe cross-file symbol rename`,order:1},{tool:`codemod`,reason:`Apply AST-level code transformations`,order:2},{tool:`data_transform`,reason:`Transform data between formats`,order:3},{tool:`diff_parse`,reason:`Parse and analyze diffs`,order:4},{tool:`blast_radius`,reason:`Check impact of transformations`,order:5}]},{name:`git`,description:`Git context, changelogs, and version tracking`,keywords:[`git`,`commit`,`diff`,`changelog`,`history`,`branch`,`version`,`release`,`changes`,`what changed`],tools:[{tool:`git_context`,reason:`Get git status, diff, and branch info`,order:1},{tool:`changelog`,reason:`Generate changelog from git history`,order:2},{tool:`blast_radius`,reason:`Assess impact of changed files`,order:3}]},{name:`indexing`,description:`Manage smart indexing, trickle mode, and index maintenance`,keywords:[`index`,`indexing`,`smart index`,`trickle`,`reindex`,`index mode`,`index status`,`queue`,`stale index`],tools:[{tool:`status`,reason:`Check index mode, queue size, and freshness`,order:1},{tool:`reindex`,reason:`Force a full reindex (only when smart mode cannot keep up)`,order:2,suggestedArgs:{force:!0}},{tool:`produce_knowledge`,reason:`Regenerate curated resource analysis`,order:3,suggestedArgs:{path:`.`}}]}];function t(t,n=5,r){let i=t.toLowerCase(),a=e.map(e=>{let t=0;for(let n of e.keywords)i.includes(n)&&(t+=n.includes(` `)?2:1);return{workflow:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score),o=e.find(e=>e.name===`search`)??e[0],s=a[0]?.workflow??o,c=a.slice(1,4).map(e=>e.workflow.name).filter(e=>e!==s.name),l={workflow:s.name,description:s.description,tools:s.tools.slice(0,n),alternativeWorkflows:c};return r===`smart`&&(l.tools=l.tools.map(e=>e.tool===`reindex`?{...e,reason:`Smart indexing is active — files are indexed automatically. Use reindex({ force: true }) only if the index is severely outdated.`,suggestedArgs:{force:!0}}:e)),l}export{t as guide};
1
+ const e=[{name:`onboard`,description:`First-time codebase exploration and understanding`,keywords:[`onboard`,`new project`,`understand`,`explore`,`first time`,`getting started`,`learn`,`overview`],tools:[{tool:`status`,reason:`Check index health and record count`,order:1},{tool:`onboard`,reason:`Run all analysis tools in one command`,order:2,suggestedArgs:{path:`.`}},{tool:`search`,reason:`Find specific topics of interest`,order:3},{tool:`graph`,reason:`Module & symbol relationship map — stats for overview, neighbors for exploration`,order:4,suggestedArgs:{action:`stats`}}]},{name:`audit`,description:`Assess project health, quality, and structure`,keywords:[`audit`,`health`,`quality`,`assess`,`review project`,`check quality`,`code quality`,`tech debt`],tools:[{tool:`status`,reason:`Check index freshness`,order:1},{tool:`audit`,reason:`Unified audit report with score and recommendations`,order:2,suggestedArgs:{detail:`summary`}},{tool:`check`,reason:`Typecheck + lint validation`,order:3},{tool:`health`,reason:`Detailed health checks on package.json, tsconfig, etc.`,order:4}]},{name:`bugfix`,description:`Diagnose and fix a bug or failing test`,keywords:[`bug`,`fix`,`debug`,`error`,`failing`,`broken`,`crash`,`wrong`,`issue`,`problem`,`not working`],tools:[{tool:`parse_output`,reason:`Parse error output from build tools (tsc, vitest, biome)`,order:1},{tool:`symbol`,reason:`Find definition and all references of the failing symbol`,order:2},{tool:`trace`,reason:`Trace call chain backward from the failure point`,order:3,suggestedArgs:{direction:`backward`}},{tool:`graph`,reason:`Understand module context — what imports the failing module`,order:4,suggestedArgs:{action:`neighbors`}},{tool:`search`,reason:`Search for related patterns or similar fixes`,order:5},{tool:`test_run`,reason:`Re-run tests after fix`,order:6}]},{name:`implement`,description:`Add a new feature or implement a change`,keywords:[`implement`,`add feature`,`new feature`,`build`,`create`,`add`,`develop`,`write code`],tools:[{tool:`scope_map`,reason:`Generate a reading plan for affected files`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2},{tool:`find`,reason:`Find usage examples of similar patterns`,order:3,suggestedArgs:{mode:`examples`}},{tool:`graph`,reason:`Map module dependencies before adding new code`,order:4,suggestedArgs:{action:`neighbors`}},{tool:`symbol`,reason:`Find existing patterns to follow`,order:5},{tool:`trace`,reason:`Understand call chains to integrate with`,order:6},{tool:`check`,reason:`Validate after implementation`,order:7},{tool:`test_run`,reason:`Run tests to verify`,order:8},{tool:`blast_radius`,reason:`Check impact of changes`,order:9}]},{name:`refactor`,description:`Restructure or clean up existing code`,keywords:[`refactor`,`restructure`,`clean up`,`reorganize`,`rename`,`move`,`extract`,`DRY`,`dead code`],tools:[{tool:`dead_symbols`,reason:`Find unused exports to remove`,order:1},{tool:`graph`,reason:`Map module dependency graph before restructuring`,order:2,suggestedArgs:{action:`neighbors`}},{tool:`trace`,reason:`Understand call chains affected by refactoring`,order:3},{tool:`symbol`,reason:`Find all references before renaming`,order:4},{tool:`blast_radius`,reason:`Assess impact before making changes`,order:5},{tool:`rename`,reason:`Safe cross-file rename`,order:6},{tool:`check`,reason:`Validate after refactoring`,order:7},{tool:`test_run`,reason:`Ensure no regressions`,order:8}]},{name:`search`,description:`Find specific code, patterns, or information`,keywords:[`find`,`search`,`where`,`locate`,`look for`,`grep`,`which file`,`how does`],tools:[{tool:`search`,reason:`Hybrid semantic + keyword search`,order:1},{tool:`find`,reason:`Federated search with glob and regex`,order:2},{tool:`symbol`,reason:`Resolve a specific symbol definition and references`,order:3},{tool:`graph`,reason:`Explore cross-module import relationships and connected symbols`,order:4,suggestedArgs:{action:`neighbors`}}]},{name:`code-navigation`,description:`Understand code structure, module relationships, and cross-package dependencies`,keywords:[`navigate`,`understand`,`module`,`import`,`dependency`,`relationship`,`call chain`,`who calls`,`who uses`,`connected`,`cross-package`],tools:[{tool:`graph`,reason:`Module import graph — see who imports whom across packages`,order:1,suggestedArgs:{action:`neighbors`}},{tool:`symbol`,reason:`Resolve symbol definitions and all references`,order:2},{tool:`trace`,reason:`Follow call chains forward or backward`,order:3},{tool:`file_summary`,reason:`Structural overview of target files`,order:4}]},{name:`context`,description:`Compress or manage context for efficient LLM interaction`,keywords:[`context`,`compress`,`summarize`,`too long`,`token`,`budget`,`reduce`,`compact`],tools:[{tool:`file_summary`,reason:`Quick structural overview without reading full file`,order:1},{tool:`compact`,reason:`Compress file to relevant sections`,order:2,suggestedArgs:{segmentation:`paragraph`}},{tool:`digest`,reason:`Compress multiple sources into budgeted summary`,order:3},{tool:`stratum_card`,reason:`Generate reusable context cards`,order:4}]},{name:`memory`,description:`Manage persistent knowledge across sessions`,keywords:[`memory`,`remember`,`persist`,`save`,`recall`,`decision`,`convention`,`session`,`checkpoint`],tools:[{tool:`list`,reason:`See all stored knowledge entries`,order:1},{tool:`search`,reason:`Search curated knowledge`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Store a new decision or pattern`,order:3},{tool:`checkpoint`,reason:`Save/restore session progress`,order:4},{tool:`stash`,reason:`Temporary key-value storage within session`,order:5}]},{name:`validate`,description:`Run checks, tests, and validation`,keywords:[`validate`,`check`,`test`,`lint`,`typecheck`,`verify`,`CI`,`pass`,`run tests`],tools:[{tool:`check`,reason:`Typecheck + lint in one call`,order:1,suggestedArgs:{detail:`errors`}},{tool:`test_run`,reason:`Run tests with structured output`,order:2},{tool:`health`,reason:`Project health assessment`,order:3}]},{name:`analyze`,description:`Deep analysis of codebase structure, dependencies, or patterns`,keywords:[`analyze`,`dependency`,`structure`,`pattern`,`architecture`,`diagram`,`entry point`,`import`],tools:[{tool:`analyze_structure`,reason:`Project structure overview`,order:1},{tool:`analyze_dependencies`,reason:`Dependency graph and analysis`,order:2},{tool:`graph`,reason:`Traverse module import graph for cross-package relationships`,order:3,suggestedArgs:{action:`neighbors`}},{tool:`symbol`,reason:`Deep-dive into specific symbols`,order:4},{tool:`trace`,reason:`Follow data flow and call chains`,order:5},{tool:`analyze_patterns`,reason:`Detect code patterns and conventions`,order:6},{tool:`analyze_entry_points`,reason:`Find handlers, exports, and entry points`,order:7},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams`,order:8}]},{name:`upgrade`,description:`Update AI Kit agents, prompts, skills, and scaffold to the latest version (user-level and workspace-level)`,keywords:[`upgrade`,`update`,`version`,`scaffold`,`outdated`,`mismatch`,`deploy`,`install`,`refresh`],tools:[{tool:`status`,reason:`Check current versions and detect mismatches — auto-triggers upgrade when a version mismatch is found`,order:1},{tool:`reindex`,reason:`Refresh the index after the upgrade completes`,order:2},{tool:`produce_knowledge`,reason:`Regenerate codebase analysis with updated tooling`,order:3,suggestedArgs:{path:`.`}}]},{name:`flow`,description:`Manage development flows — structured step-by-step processes for tasks`,keywords:[`flow`,`workflow`,`step`,`process`,`pipeline`,`lifecycle`,`sequence`,`start flow`,`flow status`],tools:[{tool:`flow_list`,reason:`List all available flows (builtin + custom)`,order:1},{tool:`flow_status`,reason:`Check current active flow and step`,order:2},{tool:`flow_start`,reason:`Start a named flow`,order:3},{tool:`flow_step`,reason:`Advance to next step, skip, or redo`,order:4},{tool:`flow_read_instruction`,reason:`Read the current step instruction`,order:5},{tool:`flow_info`,reason:`Get detailed info about a specific flow`,order:6},{tool:`flow_add`,reason:`Install a new custom flow`,order:7},{tool:`flow_update`,reason:`Update an existing custom flow`,order:8},{tool:`flow_remove`,reason:`Remove a custom flow`,order:9},{tool:`flow_reset`,reason:`Clear active flow state to start over`,order:10}]},{name:`web`,description:`Fetch web pages, search the web, or make HTTP API calls`,keywords:[`web`,`fetch`,`url`,`website`,`api`,`http`,`request`,`download`,`scrape`,`browse`,`web search`,`online`],tools:[{tool:`web_search`,reason:`Search the web for information`,order:1},{tool:`web_fetch`,reason:`Fetch and extract content from URLs`,order:2},{tool:`http`,reason:`Make raw HTTP requests to APIs`,order:3}]},{name:`brainstorm`,description:`Interactive ideation and creative exploration for design decisions`,keywords:[`brainstorm`,`ideate`,`ideas`,`explore`,`creative`,`design`,`options`,`approach`,`alternatives`,`think`],tools:[{tool:`brainstorm`,reason:`Interactive structured ideation session`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Persist chosen direction as a decision`,order:3,suggestedArgs:{category:`decisions`}}]},{name:`present`,description:`Display rich visual content — dashboards, charts, tables, timelines`,keywords:[`present`,`dashboard`,`chart`,`table`,`visualize`,`display`,`show`,`render`,`report`,`timeline`],tools:[{tool:`present`,reason:`Render rich HTML dashboards, charts, and tables`,order:1},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams for architecture views`,order:2},{tool:`measure`,reason:`Collect metrics to visualize`,order:3}]},{name:`quality`,description:`FORGE quality gates — classify task complexity, ground requirements, verify evidence`,keywords:[`quality`,`forge`,`evidence`,`gate`,`classify`,`ground`,`tier`,`critical`,`verify`,`proof`],tools:[{tool:`forge_classify`,reason:`Determine task tier (Floor/Standard/Critical)`,order:1},{tool:`forge_ground`,reason:`Ground requirements with evidence criteria`,order:2},{tool:`evidence_map`,reason:`Map evidence and run quality gates`,order:3,suggestedArgs:{action:`gate`}},{tool:`check`,reason:`Typecheck + lint validation`,order:4},{tool:`test_run`,reason:`Run tests for coverage evidence`,order:5}]},{name:`transform`,description:`Automated code transformations — codemods, renames, data transforms`,keywords:[`transform`,`codemod`,`rename`,`replace`,`migrate`,`convert`,`data transform`,`rewrite`,`bulk edit`],tools:[{tool:`rename`,reason:`Safe cross-file symbol rename`,order:1},{tool:`codemod`,reason:`Apply AST-level code transformations`,order:2},{tool:`data_transform`,reason:`Transform data between formats`,order:3},{tool:`diff_parse`,reason:`Parse and analyze diffs`,order:4},{tool:`blast_radius`,reason:`Check impact of transformations`,order:5}]},{name:`git`,description:`Git context, changelogs, and version tracking`,keywords:[`git`,`commit`,`diff`,`changelog`,`history`,`branch`,`version`,`release`,`changes`,`what changed`],tools:[{tool:`git_context`,reason:`Get git status, diff, and branch info`,order:1},{tool:`changelog`,reason:`Generate changelog from git history`,order:2},{tool:`blast_radius`,reason:`Assess impact of changed files`,order:3}]},{name:`indexing`,description:`Manage smart indexing, trickle mode, and index maintenance`,keywords:[`index`,`indexing`,`smart index`,`trickle`,`reindex`,`index mode`,`index status`,`queue`,`stale index`],tools:[{tool:`status`,reason:`Check index mode, queue size, and freshness`,order:1},{tool:`reindex`,reason:`Force a full reindex (only when smart mode cannot keep up)`,order:2,suggestedArgs:{force:!0}},{tool:`produce_knowledge`,reason:`Regenerate curated resource analysis`,order:3,suggestedArgs:{path:`.`}}]}];function t(t,n=5,r){let i=t.toLowerCase(),a=e.map(e=>{let t=0;for(let n of e.keywords)i.includes(n)&&(t+=n.includes(` `)?2:1);return{workflow:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score),o=e.find(e=>e.name===`search`)??e[0],s=a[0]?.workflow??o,c=a.slice(1,4).map(e=>e.workflow.name).filter(e=>e!==s.name),l={workflow:s.name,description:s.description,tools:s.tools.slice(0,n),alternativeWorkflows:c};return r===`smart`&&(l.tools=l.tools.map(e=>e.tool===`reindex`?{...e,reason:`Smart indexing is active — files are indexed automatically. Use reindex({ force: true }) only if the index is severely outdated.`,suggestedArgs:{force:!0}}:e)),l}export{t as guide};
@@ -1,3 +1,3 @@
1
1
  import{escapeRegExp as e}from"./regex-utils.js";import{extname as t}from"node:path";import{SUPPORTED_EXTENSIONS as n,WasmRuntime as r,extractSymbols as i,resolveScopes as a}from"../../chunker/dist/index.js";async function o(o,s,c){let{name:l,limit:u=20,graphStore:d}=c,f=o.embedQuery?.bind(o)??o.embed.bind(o),p=[`export function ${l}`,`export class ${l}`,`export const ${l}`,`export interface ${l}`,`export type ${l}`,`export enum ${l}`].join(` | `),m=await s.search(await f(p),{limit:u*2}),h=RegExp(`^export\\s+(?:default\\s+)?(?:async\\s+)?(?:function|class|const|let|interface|type|enum)\\s+${e(l)}\\b`,`m`),g;for(let e of m){if(!h.test(e.record.content))continue;let a=e.record.content.match(/export\s+(?:default\s+)?(?:async\s+)?(\w+)/)?.[1]??`unknown`;g={path:e.record.sourcePath,line:e.record.startLine,kind:a};let o=t(e.record.sourcePath);if(r.get()&&n.has(o))try{let t=(await i(e.record.content,o,e.record.sourcePath)).find(e=>e.name===l&&e.exported);t&&(g.kind=t.kind,t.signature&&(g.signature=t.signature))}catch{}break}let _=RegExp(`import\\s+.*\\b${e(l)}\\b.*from\\s+`,`m`),v=await s.search(await f(`import ${l} from`),{limit:u*3}),y=[],b=new Set;for(let e of v){let t=e.record.content.split(`
2
2
  `);for(let n=0;n<t.length;n++){let r=t[n];if(!_.test(r))continue;let i=`${e.record.sourcePath}:${r.trim()}`;b.has(i)||(b.add(i),y.push({path:e.record.sourcePath,line:e.record.startLine+n,importStatement:r.trim()}))}}let x=RegExp(`\\b${e(l)}\\b`),S=await s.search(await f(l),{limit:u*3}),C=[],w=new Set;for(let e of S){if(C.length>=u)break;if(g&&e.record.sourcePath===g.path)continue;let i=e.record.content.split(`
3
- `);for(let o=0;o<i.length;o++){let s=i[o];if(!x.test(s)||_.test(s))continue;let c=`${e.record.sourcePath}:${e.record.startLine+o}`;if(w.has(c))continue;w.add(c);let l,u=t(e.record.sourcePath);if(r.get()&&n.has(u))try{let t=await a(e.record.content,u,o+1);t.length>0&&(l=t[0].name)}catch{}C.push({path:e.record.sourcePath,line:e.record.startLine+o,context:s.trim().slice(0,120),scope:l});break}}let T;if(d)try{let e={importedByModules:[],siblingSymbols:[]},t=await d.findNodes({namePattern:l});if(t.length>0){let n=t[0];n.sourcePath?e.definingModule=n.sourcePath:g&&(e.definingModule=g.path);let r=await d.getNeighbors(n.id,{direction:`incoming`,edgeType:`imports`});for(let t of r.nodes)e.importedByModules.push(t.sourcePath??t.name);if(e.definingModule){let t=await d.findNodes({sourcePath:e.definingModule});for(let n of t)n.name!==l&&n.type!==`module`&&e.siblingSymbols.push(`${n.type}:${n.name}`);e.siblingSymbols=e.siblingSymbols.slice(0,15)}}(e.definingModule||e.importedByModules.length>0||e.siblingSymbols.length>0)&&(T=e)}catch{}return{name:l,definedIn:g,importedBy:y.slice(0,u),referencedIn:C.slice(0,u),graphContext:T}}export{o as symbol};
3
+ `);for(let o=0;o<i.length;o++){let s=i[o];if(!x.test(s)||_.test(s))continue;let c=`${e.record.sourcePath}:${e.record.startLine+o}`;if(w.has(c))continue;w.add(c);let l,u=t(e.record.sourcePath);if(r.get()&&n.has(u))try{let t=await a(e.record.content,u,o+1);t.length>0&&(l=t[0].name)}catch{}C.push({path:e.record.sourcePath,line:e.record.startLine+o,context:s.trim().slice(0,120),scope:l});break}}let T;if(d)try{let e={importedByModules:[],siblingSymbols:[]},t=await d.findNodes({namePattern:l});if(t.length>0){let n=t[0];if(n.sourcePath?e.definingModule=n.sourcePath:g&&(e.definingModule=g.path),n.sourcePath){let t=(await d.findNodes({sourcePath:n.sourcePath,type:`module`}))[0];if(t){let n=await d.getNeighbors(t.id,{direction:`incoming`,edgeType:`imports`});for(let t of n.nodes)e.importedByModules.push(t.sourcePath??t.name)}}if(e.definingModule){let t=await d.findNodes({sourcePath:e.definingModule});for(let n of t)n.name!==l&&n.type!==`module`&&e.siblingSymbols.push(`${n.type}:${n.name}`);e.siblingSymbols=e.siblingSymbols.slice(0,15)}}(e.definingModule||e.importedByModules.length>0||e.siblingSymbols.length>0)&&(T=e)}catch{}return{name:l,definedIn:g,importedBy:y.slice(0,u),referencedIn:C.slice(0,u),graphContext:T}}export{o as symbol};
@@ -1,2 +1,2 @@
1
1
  import{escapeRegExp as e}from"./regex-utils.js";import{readFile as t}from"node:fs/promises";import{extname as n}from"node:path";import{SUPPORTED_EXTENSIONS as r,WasmRuntime as i,extractCalls as a}from"../../chunker/dist/index.js";async function o(t,n,r){let{start:a,direction:o,maxDepth:f=3,graphStore:p}=r,m=[],h=new Set,g=new Set,_=!!i.get(),v=new Map,y=await t.embed(a);if((await n.search(y,{limit:10})).length===0)return{start:a,direction:o,nodes:m,depth:0};let b=[{target:a,depth:0}],x=0;for(;b.length>0;){let r=b.shift();if(!r)break;if(r.depth>=f||h.has(r.target))continue;h.add(r.target);let i=await t.embed(r.target),a=await n.search(i,{limit:20}),s=e(r.target),d=u(r.target);for(let e of a){let t=e.record.sourcePath,n=e.record.content.split(`
2
- `);if(_&&!d){let e=await c(v,t);for(let n of e)o!==`backward`&&n.callerName===r.target&&(l(g,m,{path:t,symbol:n.calleeName,line:n.line,relationship:`calls`,scope:n.callerName}),x=Math.max(x,r.depth+1),b.push({target:n.calleeName,depth:r.depth+1})),o!==`forward`&&n.calleeName===r.target&&(l(g,m,{path:t,symbol:n.callerName,line:n.line,relationship:`called-by`,scope:n.callerName}),x=Math.max(x,r.depth+1),b.push({target:n.callerName,depth:r.depth+1}))}for(let i=0;i<n.length;i+=1){let a=n[i],c=e.record.startLine+i;if(o!==`forward`&&RegExp(d?`from\\s+['"]${s}['"]`:`import\\s+.*\\b${s}\\b.*from\\s+`).test(a)){l(g,m,{path:t,symbol:r.target,line:c,relationship:`imported-by`}),x=Math.max(x,r.depth+1);let e=a.match(/from\s+['"]([^'"]+)['"]/);!d&&e&&b.push({target:e[1],depth:r.depth+1})}o!==`backward`&&(d?RegExp(`from\\s+['"]${s}['"]`).test(a)&&(l(g,m,{path:t,symbol:r.target,line:c,relationship:`imports`}),x=Math.max(x,r.depth+1)):_||RegExp(`\\b${s}\\s*\\(`).test(a)&&!/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(a)&&(l(g,m,{path:t,symbol:r.target,line:c,relationship:`calls`}),x=Math.max(x,r.depth+1))),RegExp(d?`['"]${s}['"]`:`\\b${s}\\b`).test(a)&&!/^\s*import\s/.test(a)&&!/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(a)&&(l(g,m,{path:t,symbol:r.target,line:c,relationship:`references`}),x=Math.max(x,r.depth+1))}}}let S=p?await s(a,p):void 0;return{start:a,direction:o,nodes:d(m),depth:x,graphContext:S}}async function s(e,t){try{let n=await t.findNodes({namePattern:e,limit:10}),r=n.find(t=>t.name===e&&t.type!==`module`)??n.find(t=>t.name===e)??n[0];if(!r)return;let i={definingModule:r.sourcePath,community:r.community,importedByModules:[],siblingSymbols:[]};try{let e=await t.getSymbol360(r.id);i.community=e.community??i.community,i.definingModule=e.node.sourcePath??i.definingModule}catch{}return i.importedByModules=f((await t.getNeighbors(r.id,{direction:`incoming`,edgeType:`imports`})).nodes.map(e=>e.sourcePath??e.name)),i.definingModule&&(i.siblingSymbols=f((await t.findNodes({sourcePath:i.definingModule,limit:50})).filter(e=>e.name!==r.name&&e.type!==`module`).map(e=>`${e.type}:${e.name}`)).slice(0,15)),i.definingModule||i.community||i.importedByModules.length>0||i.siblingSymbols.length>0?i:void 0}catch{return}}async function c(e,i){let o=e.get(i);if(o)return o;let s=n(i);if(!r.has(s))return e.set(i,[]),[];try{let n=await a(await t(i,`utf-8`),s,i);return e.set(i,n),n}catch{return e.set(i,[]),[]}}function l(e,t,n){let r=`${n.path}:${n.line}:${n.relationship}`;e.has(r)||(e.add(r),t.push(n))}function u(e){return/[./\\]/.test(e)}function d(e){let t=new Set;return e.filter(e=>{let n=`${e.path}:${e.line}:${e.relationship}`;return t.has(n)?!1:(t.add(n),!0)})}function f(e){return[...new Set(e.filter(e=>e.length>0))]}export{o as trace};
2
+ `);if(_&&!d){let e=await c(v,t);for(let n of e)o!==`backward`&&n.callerName===r.target&&(l(g,m,{path:t,symbol:n.calleeName,line:n.line,relationship:`calls`,scope:n.callerName}),x=Math.max(x,r.depth+1),b.push({target:n.calleeName,depth:r.depth+1})),o!==`forward`&&n.calleeName===r.target&&(l(g,m,{path:t,symbol:n.callerName,line:n.line,relationship:`called-by`,scope:n.callerName}),x=Math.max(x,r.depth+1),b.push({target:n.callerName,depth:r.depth+1}))}for(let i=0;i<n.length;i+=1){let a=n[i],c=e.record.startLine+i;if(o!==`forward`&&RegExp(d?`from\\s+['"]${s}['"]`:`import\\s+.*\\b${s}\\b.*from\\s+`).test(a)){l(g,m,{path:t,symbol:r.target,line:c,relationship:`imported-by`}),x=Math.max(x,r.depth+1);let e=a.match(/from\s+['"]([^'"]+)['"]/);!d&&e&&b.push({target:e[1],depth:r.depth+1})}o!==`backward`&&(d?RegExp(`from\\s+['"]${s}['"]`).test(a)&&(l(g,m,{path:t,symbol:r.target,line:c,relationship:`imports`}),x=Math.max(x,r.depth+1)):_||RegExp(`\\b${s}\\s*\\(`).test(a)&&!/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(a)&&(l(g,m,{path:t,symbol:r.target,line:c,relationship:`calls`}),x=Math.max(x,r.depth+1))),RegExp(d?`['"]${s}['"]`:`\\b${s}\\b`).test(a)&&!/^\s*import\s/.test(a)&&!/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(a)&&(l(g,m,{path:t,symbol:r.target,line:c,relationship:`references`}),x=Math.max(x,r.depth+1))}}}let S=p?await s(a,p):void 0;return{start:a,direction:o,nodes:d(m),depth:x,graphContext:S}}async function s(e,t){try{let n=await t.findNodes({namePattern:e,limit:10}),r=n.find(t=>t.name===e&&t.type!==`module`)??n.find(t=>t.name===e)??n[0];if(!r)return;let i={definingModule:r.sourcePath,community:r.community,importedByModules:[],siblingSymbols:[]};try{let e=await t.getSymbol360(r.id);i.community=e.community??i.community,i.definingModule=e.node.sourcePath??i.definingModule}catch{}if(r.sourcePath){let[e]=await t.findNodes({sourcePath:r.sourcePath,type:`module`});e&&(i.importedByModules=f((await t.getNeighbors(e.id,{direction:`incoming`,edgeType:`imports`})).nodes.map(e=>e.sourcePath??e.name)))}return i.definingModule&&(i.siblingSymbols=f((await t.findNodes({sourcePath:i.definingModule,limit:50})).filter(e=>e.name!==r.name&&e.type!==`module`).map(e=>`${e.type}:${e.name}`)).slice(0,15)),i.definingModule||i.community||i.importedByModules.length>0||i.siblingSymbols.length>0?i:void 0}catch{return}}async function c(e,i){let o=e.get(i);if(o)return o;let s=n(i);if(!r.has(s))return e.set(i,[]),[];try{let n=await a(await t(i,`utf-8`),s,i);return e.set(i,n),n}catch{return e.set(i,[]),[]}}function l(e,t,n){let r=`${n.path}:${n.line}:${n.relationship}`;e.has(r)||(e.add(r),t.push(n))}function u(e){return/[./\\]/.test(e)}function d(e){let t=new Set;return e.filter(e=>{let n=`${e.path}:${e.line}:${e.relationship}`;return t.has(n)?!1:(t.add(n),!0)})}function f(e){return[...new Set(e.filter(e=>e.length>0))]}export{o as trace};
@@ -1,4 +1,4 @@
1
- import{paragraphTruncate as e}from"./truncation.js";import t from"turndown";const n=`script,style,noscript,iframe,svg,nav,footer,header,aside,form,button,input,select,textarea,[role="navigation"],[role="banner"],[role="contentinfo"],[aria-hidden="true"],.sidebar,.nav,.menu,.footer,.header,.ad,.advertisement,.cookie-banner,.popup,.modal`.split(`,`),r=[`article`,`[role="main"]`,`main`,`.post-content`,`.article-content`,`.entry-content`,`.content`,`#content`,`.prose`,`.markdown-body`,`.documentation`,`.doc-content`];async function i(e){let{url:t,mode:i=`markdown`,selector:d,maxLength:f=15e3,includeMetadata:p=!0,includeLinks:m=!1,includeImages:h=!1,timeout:g=6e4}=e,_=new URL(t);if(_.protocol!==`http:`&&_.protocol!==`https:`)throw Error(`Unsupported protocol: ${_.protocol} — only http/https allowed`);let v=new AbortController,y=setTimeout(()=>v.abort(),g),b,x,S=``,C=!1,w=``;try{if(b=await fetch(t,{signal:v.signal,headers:{"User-Agent":`aikit-web-fetch/1.0 (LLM context tool)`,Accept:`text/html,application/xhtml+xml,text/plain`},redirect:`follow`}),!b.ok)throw Error(`HTTP ${b.status}: ${b.statusText}`);x=await b.text(),S=b.headers.get(`content-type`)??``,C=/text\/html|application\/xhtml\+xml/i.test(S),w=b.url}finally{clearTimeout(y)}if(!C){let e=x,t=w.split(`/`).pop()??``;p&&(e=c(t,``,w)+e);let n=e.length,r=n>f;return r&&(e=u(e,f)),{content:e,title:t,description:``,url:w,originalLength:n,truncated:r}}let{parseHTML:T}=await import(`linkedom`),{document:E}=T(x),D=E.querySelector(`title`)?.textContent?.trim()??E.querySelector(`meta[property="og:title"]`)?.getAttribute(`content`)?.trim()??``,O=E.querySelector(`meta[name="description"]`)?.getAttribute(`content`)?.trim()??E.querySelector(`meta[property="og:description"]`)?.getAttribute(`content`)?.trim()??``;for(let e of n)for(let t of E.querySelectorAll(e))t.remove();if(!h)for(let e of E.querySelectorAll(`img`))e.remove();let k=null;if(d){if(k=E.querySelector(d),!k)throw Error(`Selector "${d}" matched no elements on the page`)}else{for(let e of r)if(k=E.querySelector(e),k)break;k||=E.querySelector(`body`)}if(!k)return{content:`(empty page — no content found)`,title:D,description:O,url:w,originalLength:0,truncated:!1};let A=k.innerHTML,j=[];if(m||i===`links`)for(let e of k.querySelectorAll(`a[href]`)){let t=e.textContent?.trim(),n=e.getAttribute(`href`);t&&n&&!n.startsWith(`#`)&&!n.startsWith(`javascript:`)&&j.push({text:t,href:l(n,w)})}let M;switch(i){case`raw`:M=A;break;case`links`:M=s(j);break;case`outline`:M=o(k);break;default:M=a(A,h);break}p&&i!==`links`&&(M=c(D,O,w)+M),m&&i!==`links`&&j.length>0&&(M+=`\n\n---\n\n## Links\n\n${s(j)}`);let N=M.length,P=N>f;return P&&(M=u(M,f)),{content:M,title:D,description:O,url:w,originalLength:N,truncated:P}}function a(e,n){let r=new t({headingStyle:`atx`,codeBlockStyle:`fenced`,bulletListMarker:`-`});r.addRule(`emptyLinks`,{filter:e=>e.nodeName===`A`&&!e.textContent?.trim(),replacement:()=>``}),n||r.addRule(`removeImages`,{filter:`img`,replacement:()=>``});let i=r.turndown(e);return i=i.replace(/\n{3,}/g,`
1
+ import{paragraphTruncate as e}from"./truncation.js";import t from"turndown";const n=`script,style,noscript,iframe,svg,nav,footer,header,aside,form,button,input,select,textarea,[role="navigation"],[role="banner"],[role="contentinfo"],[aria-hidden="true"],.sidebar,.nav,.menu,.footer,.header,.ad,.advertisement,.cookie-banner,.popup,.modal`.split(`,`),r=[`article`,`[role="main"]`,`main`,`.post-content`,`.article-content`,`.entry-content`,`.content`,`#content`,`.prose`,`.markdown-body`,`.documentation`,`.doc-content`];async function i(e){let{url:t,mode:i=`markdown`,selector:d,maxLength:f=15e3,includeMetadata:p=!0,includeLinks:m=!1,includeImages:h=!1,timeout:g=6e4}=e,_=new URL(t);if(_.protocol!==`http:`&&_.protocol!==`https:`)throw Error(`Unsupported protocol: ${_.protocol} — only http/https allowed`);let v=new AbortController,y=setTimeout(()=>v.abort(),g),b,x,S=``,C=!1,w=``;try{if(b=await fetch(t,{signal:v.signal,headers:{"User-Agent":`aikit-web-fetch/1.0 (LLM context tool)`,Accept:`text/html,application/xhtml+xml,text/plain`},redirect:`follow`}),!b.ok)throw Error(`HTTP ${b.status}: ${b.statusText}`);x=await b.text(),S=b.headers.get(`content-type`)??``,C=/text\/html|application\/xhtml\+xml/i.test(S),w=b.url}catch(e){throw e instanceof DOMException&&e.name===`AbortError`?Error(`Request to ${t} timed out after ${g}ms. Try increasing the timeout parameter.`):e}finally{clearTimeout(y)}if(!C){let e=x,t=w.split(`/`).pop()??``;p&&(e=c(t,``,w)+e);let n=e.length,r=n>f;return r&&(e=u(e,f)),{content:e,title:t,description:``,url:w,originalLength:n,truncated:r}}let{parseHTML:T}=await import(`linkedom`),{document:E}=T(x),D=E.querySelector(`title`)?.textContent?.trim()??E.querySelector(`meta[property="og:title"]`)?.getAttribute(`content`)?.trim()??``,O=E.querySelector(`meta[name="description"]`)?.getAttribute(`content`)?.trim()??E.querySelector(`meta[property="og:description"]`)?.getAttribute(`content`)?.trim()??``;for(let e of n)for(let t of E.querySelectorAll(e))t.remove();if(!h)for(let e of E.querySelectorAll(`img`))e.remove();let k=null;if(d){if(k=E.querySelector(d),!k)throw Error(`Selector "${d}" matched no elements on the page`)}else{for(let e of r)if(k=E.querySelector(e),k)break;k||=E.querySelector(`body`)}if(!k)return{content:`(empty page — no content found)`,title:D,description:O,url:w,originalLength:0,truncated:!1};let A=k.innerHTML,j=[];if(m||i===`links`)for(let e of k.querySelectorAll(`a[href]`)){let t=e.textContent?.trim(),n=e.getAttribute(`href`);t&&n&&!n.startsWith(`#`)&&!n.startsWith(`javascript:`)&&j.push({text:t,href:l(n,w)})}let M;switch(i){case`raw`:M=A;break;case`links`:M=s(j);break;case`outline`:M=o(k);break;default:M=a(A,h);break}p&&i!==`links`&&(M=c(D,O,w)+M),m&&i!==`links`&&j.length>0&&(M+=`\n\n---\n\n## Links\n\n${s(j)}`);let N=M.length,P=N>f;return P&&(M=u(M,f)),{content:M,title:D,description:O,url:w,originalLength:N,truncated:P}}function a(e,n){let r=new t({headingStyle:`atx`,codeBlockStyle:`fenced`,bulletListMarker:`-`});r.addRule(`emptyLinks`,{filter:e=>e.nodeName===`A`&&!e.textContent?.trim(),replacement:()=>``}),n||r.addRule(`removeImages`,{filter:`img`,replacement:()=>``});let i=r.turndown(e);return i=i.replace(/\n{3,}/g,`
2
2
 
3
3
  `).trim(),i}function o(e){let t=e.querySelectorAll(`h1, h2, h3, h4, h5, h6`),n=[];for(let e of t){let t=Number.parseInt(e.tagName.slice(1),10),r=` `.repeat(t-1),i=e.textContent?.trim()??``;i&&n.push(`${r}- ${i}`)}return n.length>0?n.join(`
4
4
  `):`(no headings found)`}function s(e){if(e.length===0)return`(no links found)`;let t=new Set,n=[];for(let r of e)t.has(r.href)||(t.add(r.href),n.push(r));return n.map(e=>`- [${e.text}](${e.href})`).join(`
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { generateCopilot } from '../adapters/copilot.mjs';
4
+ import { PROTOCOLS } from '../definitions/protocols.mjs';
5
+
6
+ function getGeneratedFile(files, path) {
7
+ const file = files.find((entry) => entry.path === path);
8
+ expect(file, `Missing generated file: ${path}`).toBeTruthy();
9
+ return file;
10
+ }
11
+
12
+ describe('generateCopilot shared protocol inlining', () => {
13
+ it('inlines shared protocol content into generated agent files while still emitting shared files', () => {
14
+ const files = generateCopilot();
15
+
16
+ const implementer = getGeneratedFile(files, 'agents/Implementer.agent.md');
17
+ const security = getGeneratedFile(files, 'agents/Security.agent.md');
18
+ const documenter = getGeneratedFile(files, 'agents/Documenter.agent.md');
19
+ const researcher = getGeneratedFile(files, 'agents/Researcher-Alpha.agent.md');
20
+ const orchestrator = getGeneratedFile(files, 'agents/Orchestrator.agent.md');
21
+ const sharedProtocol = getGeneratedFile(files, 'agents/_shared/code-agent-base.md');
22
+
23
+ expect(implementer.content).toContain(PROTOCOLS['code-agent-base']);
24
+ expect(security.content).toContain(PROTOCOLS['code-agent-base']);
25
+ expect(documenter.content).toContain(PROTOCOLS['code-agent-base']);
26
+ expect(researcher.content).toContain(PROTOCOLS['researcher-base']);
27
+ expect(orchestrator.content).toContain(PROTOCOLS['decision-protocol']);
28
+ expect(orchestrator.content).toContain(PROTOCOLS['forge-protocol']);
29
+
30
+ expect(implementer.content).not.toContain('Read _shared/code-agent-base.md NOW');
31
+ expect(security.content).not.toContain('Read _shared/code-agent-base.md NOW');
32
+ expect(documenter.content).not.toContain('Read _shared/code-agent-base.md NOW');
33
+ expect(researcher.content).not.toContain('Read .github/agents/_shared/');
34
+ expect(orchestrator.content).not.toContain('_shared/decision-protocol.md');
35
+ expect(orchestrator.content).not.toContain('_shared/forge-protocol.md');
36
+
37
+ expect(sharedProtocol.content).toBe(PROTOCOLS['code-agent-base']);
38
+ });
39
+ });
@@ -117,9 +117,8 @@ function generateVariantAgent(roleName, suffix, def) {
117
117
  ? `, the primary ${roleName} agent.`
118
118
  : `, a variant of ${roleName}. Same responsibilities, different model perspective.`);
119
119
 
120
- const sharedRef = def.sharedBase
121
- ? `\n**Read .github/agents/_shared/${def.sharedBase}.md NOW** — it contains your complete workflow and guidelines. All instructions there apply to you.`
122
- : '';
120
+ const sharedContent =
121
+ def.sharedBase && PROTOCOLS[def.sharedBase] ? `\n\n${PROTOCOLS[def.sharedBase]}` : '';
123
122
 
124
123
  const extra = def.extraBody ? `\n\n${def.extraBody}` : '';
125
124
 
@@ -138,7 +137,7 @@ model: ${model}
138
137
  # ${fullName} - ${title}
139
138
 
140
139
  You are **${fullName}**${identity}${extra}
141
- ${sharedRef}${skillsSection}
140
+ ${sharedContent}${skillsSection}
142
141
 
143
142
  ${FLOWS_SECTION}
144
143
  `;
@@ -151,6 +150,13 @@ function generateSingleAgent(name, def) {
151
150
  ? AGENT_BODIES[name](buildAgentTable())
152
151
  : AGENT_BODIES[name] || '';
153
152
 
153
+ const sharedContent =
154
+ def.sharedBase && PROTOCOLS[def.sharedBase] ? `\n\n${PROTOCOLS[def.sharedBase]}` : '';
155
+
156
+ const additionalContent = (def.sharedProtocols || [])
157
+ .map((key) => (PROTOCOLS[key] ? `\n\n${PROTOCOLS[key]}` : ''))
158
+ .join('');
159
+
154
160
  const title = def.title || name;
155
161
  const skillsSection = def.skills?.length
156
162
  ? `\n## Skills (load on demand)\n\n| Skill | When to load |\n|-------|--------------|\n${def.skills.map(([s, w]) => `| ${s} | ${w} |`).join('\n')}\n`
@@ -166,7 +172,7 @@ model: ${model}
166
172
 
167
173
  You are the **${name}**, ${def.description.toLowerCase().replace(/^./, (c) => c.toLowerCase())}
168
174
 
169
- ${body}${skillsSection}
175
+ ${body}${sharedContent}${additionalContent}${skillsSection}
170
176
 
171
177
  ${FLOWS_SECTION}
172
178
  `;