@vpxa/kb 0.1.26 → 0.1.28

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 (38) hide show
  1. package/package.json +2 -1
  2. package/packages/analyzers/dist/symbol-analyzer.js +4 -4
  3. package/packages/analyzers/dist/types.d.ts +8 -0
  4. package/packages/chunker/dist/extractors/symbol-extractor.js +3 -1
  5. package/packages/chunker/dist/extractors/types.d.ts +8 -0
  6. package/packages/core/dist/types.d.ts +2 -0
  7. package/packages/server/dist/config.js +1 -1
  8. package/packages/server/dist/output-schemas.d.ts +1 -0
  9. package/packages/server/dist/output-schemas.js +1 -1
  10. package/packages/server/dist/server.js +1 -1
  11. package/packages/server/dist/tools/context.tools.js +2 -1
  12. package/packages/server/dist/tools/infra.tools.js +4 -2
  13. package/packages/server/dist/tools/onboard.tool.d.ts +2 -1
  14. package/packages/server/dist/tools/onboard.tool.js +1 -1
  15. package/packages/server/dist/tools/produce.tool.d.ts +2 -1
  16. package/packages/server/dist/tools/produce.tool.js +2 -2
  17. package/packages/server/dist/tools/status.tool.d.ts +2 -1
  18. package/packages/server/dist/tools/status.tool.js +2 -2
  19. package/packages/server/dist/tools/utility.tools.js +4 -2
  20. package/packages/tools/dist/find.d.ts +4 -0
  21. package/packages/tools/dist/find.js +1 -1
  22. package/packages/tools/dist/onboard.js +18 -2
  23. package/scaffold/README.md +192 -0
  24. package/scaffold/definitions/bodies.mjs +140 -28
  25. package/scaffold/definitions/protocols.mjs +232 -24
  26. package/scaffold/general/agents/Debugger.agent.md +9 -6
  27. package/scaffold/general/agents/Documenter.agent.md +13 -2
  28. package/scaffold/general/agents/Explorer.agent.md +12 -0
  29. package/scaffold/general/agents/Frontend.agent.md +1 -1
  30. package/scaffold/general/agents/Implementer.agent.md +3 -1
  31. package/scaffold/general/agents/Orchestrator.agent.md +67 -11
  32. package/scaffold/general/agents/Planner.agent.md +19 -2
  33. package/scaffold/general/agents/Refactor.agent.md +1 -1
  34. package/scaffold/general/agents/Security.agent.md +13 -2
  35. package/scaffold/general/agents/_shared/architect-reviewer-base.md +11 -2
  36. package/scaffold/general/agents/_shared/code-agent-base.md +181 -17
  37. package/scaffold/general/agents/_shared/code-reviewer-base.md +11 -2
  38. package/scaffold/general/agents/_shared/researcher-base.md +29 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/kb",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
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",
@@ -51,6 +51,7 @@
51
51
  "@modelcontextprotocol/sdk": "^1.x",
52
52
  "express": "^5.x",
53
53
  "linkedom": "^0.x",
54
+ "marked": "^17.x",
54
55
  "minimatch": "^10.x",
55
56
  "sql.js": "^1.x",
56
57
  "tree-sitter-wasms": "~0.1.13",
@@ -1,9 +1,9 @@
1
- import{readFile as e,readdir as t,stat as n}from"node:fs/promises";import{dirname as r,extname as i,join as a,relative as o}from"node:path";import{SUPPORTED_EXTENSIONS as s,WasmRuntime as c,extractCalls as l,extractSymbols as u}from"../../chunker/dist/index.js";const d=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.java`,`.py`,`.go`,`.cs`,`.rb`,`.kt`,`.scala`,`.rs`,`.php`,`.swift`]),f=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,`__pycache__`,`.venv`,`target`,`bin`,`obj`,`.gradle`,`venv`,`env`]),p={exported:[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:`function`},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^export\s+interface\s+(\w+)/gm,kind:`interface`},{pattern:/^export\s+type\s+(\w+)/gm,kind:`type`},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:`const`},{pattern:/^export\s+enum\s+(\w+)/gm,kind:`enum`}],local:[{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:`function`},{pattern:/^class\s+(\w+)/gm,kind:`class`},{pattern:/^interface\s+(\w+)/gm,kind:`interface`},{pattern:/^type\s+(\w+)/gm,kind:`type`},{pattern:/^(?:const|let)\s+(\w+)\s*=/gm,kind:`const`},{pattern:/^enum\s+(\w+)/gm,kind:`enum`}]},m={exported:[{pattern:/^[ \t]*public\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,kind:`enum`},{pattern:/^[ \t]*public\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:abstract\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*[;=]/gm,kind:`variable`}],skipIndentFilter:!0},h={exported:[{pattern:/^def\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^async\s+def\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^class\s+(\w+)/gm,kind:`class`}],local:[{pattern:/^[ \t]+def\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^[ \t]+async\s+def\s+(\w+)\s*\(/gm,kind:`function`}],skipIndentFilter:!0},g={exported:[{pattern:/^func\s+([A-Z]\w*)\s*\(/gm,kind:`function`},{pattern:/^func\s+\([^)]+\)\s+([A-Z]\w*)\s*\(/gm,kind:`function`},{pattern:/^type\s+([A-Z]\w*)\s+struct\b/gm,kind:`class`},{pattern:/^type\s+([A-Z]\w*)\s+interface\b/gm,kind:`interface`},{pattern:/^type\s+([A-Z]\w*)\s+/gm,kind:`type`}],local:[{pattern:/^func\s+([a-z]\w*)\s*\(/gm,kind:`function`},{pattern:/^func\s+\([^)]+\)\s+([a-z]\w*)\s*\(/gm,kind:`function`},{pattern:/^type\s+([a-z]\w*)\s+struct\b/gm,kind:`class`},{pattern:/^type\s+([a-z]\w*)\s+/gm,kind:`type`}],skipIndentFilter:!0},_={exported:[{pattern:/^[ \t]*public\s+(?:static\s+)?(?:partial\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,kind:`enum`},{pattern:/^[ \t]*public\s+(?:static\s+)?(?:virtual\s+)?(?:override\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])?)\s+(\w+)\s*\(/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*\(/gm,kind:`function`}],skipIndentFilter:!0},v={exported:[{pattern:/^(?:open\s+|data\s+|sealed\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^(?:fun|suspend\s+fun)\s+(\w+)\s*[(<]/gm,kind:`function`},{pattern:/^interface\s+(\w+)/gm,kind:`interface`},{pattern:/^object\s+(\w+)/gm,kind:`class`},{pattern:/^enum\s+class\s+(\w+)/gm,kind:`enum`}],local:[{pattern:/^[ \t]+(?:private|internal)\s+(?:fun|suspend\s+fun)\s+(\w+)/gm,kind:`function`},{pattern:/^[ \t]+(?:private|internal)\s+(?:val|var)\s+(\w+)/gm,kind:`variable`}],skipIndentFilter:!0},y={exported:[{pattern:/^class\s+(\w+)/gm,kind:`class`},{pattern:/^module\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]+def\s+self\.(\w+)/gm,kind:`function`}],local:[{pattern:/^[ \t]+def\s+(\w+)/gm,kind:`function`}],skipIndentFilter:!0},b={exported:[{pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)/gm,kind:`function`},{pattern:/^pub\s+struct\s+(\w+)/gm,kind:`class`},{pattern:/^pub\s+trait\s+(\w+)/gm,kind:`interface`},{pattern:/^pub\s+enum\s+(\w+)/gm,kind:`enum`},{pattern:/^pub\s+type\s+(\w+)/gm,kind:`type`}],local:[{pattern:/^(?:async\s+)?fn\s+(\w+)/gm,kind:`function`},{pattern:/^struct\s+(\w+)/gm,kind:`class`},{pattern:/^trait\s+(\w+)/gm,kind:`interface`},{pattern:/^enum\s+(\w+)/gm,kind:`enum`}],skipIndentFilter:!0},x={exported:[{pattern:/^[ \t]*(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*interface\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*public\s+(?:static\s+)?function\s+(\w+)/gm,kind:`function`},{pattern:/^function\s+(\w+)\s*\(/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?function\s+(\w+)/gm,kind:`function`}],skipIndentFilter:!0},S={exported:[{pattern:/^[ \t]*(?:open|public)\s+class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:open|public)\s+struct\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:open|public)\s+protocol\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*(?:open|public)\s+enum\s+(\w+)/gm,kind:`enum`},{pattern:/^[ \t]*(?:open|public)\s+func\s+(\w+)/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|fileprivate|internal)\s+func\s+(\w+)/gm,kind:`function`},{pattern:/^[ \t]*(?:private|fileprivate|internal)\s+class\s+(\w+)/gm,kind:`class`}],skipIndentFilter:!0},C={exported:[{pattern:/^[ \t]*(?:case\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*object\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*trait\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*def\s+(\w+)/gm,kind:`function`}],local:[],skipIndentFilter:!0};function w(e){switch(e){case`.ts`:case`.tsx`:case`.js`:case`.jsx`:return p;case`.java`:return m;case`.py`:return h;case`.go`:return g;case`.cs`:return _;case`.kt`:return v;case`.rb`:return y;case`.rs`:return b;case`.php`:return x;case`.swift`:return S;case`.scala`:return C;default:return p}}function T(e,t){let n=``,r=0,i=!1;for(let a=t;a<Math.min(t+5,e.length);a++){let t=e[a].trim();n+=(n?` `:``)+t;for(let e of t)e===`(`&&(r++,i=!0),e===`)`&&r--;if(i&&r<=0)return n.replace(/\s*\{.*$/,``).replace(/\s*:\s*$/,``).trim()}return n.trim()||void 0}var E=class{name=`symbols`;async analyze(t,n={}){let{format:a=`markdown`,filter:d}=n,f=Date.now(),p=await this.collectFiles(t),m=p.length===1&&p[0]===t?r(t):t,h=[],g=[],_=!1;try{await c.ensure(),_=!0}catch{}for(let t of p){let n=await e(t,`utf-8`),r=o(m,t).replace(/\\/g,`/`),a=i(t);if(_&&s.has(a)){let e=await u(n,a,r);if(e.length>0){h.push(...e);let t=await l(n,a,r);g.push(...t)}else{let e=this.extractSymbolsRegex(n,r);h.push(...e)}}else{let e=this.extractSymbolsRegex(n,r);h.push(...e)}}if(d){let e=d.toLowerCase();h=h.filter(t=>t.name.toLowerCase().includes(e))}return{output:a===`json`?JSON.stringify(h,null,2):this.formatMarkdown(h,m,g),data:{symbols:h,byKind:this.groupByKind(h),exportedCount:h.filter(e=>e.exported).length,totalCount:h.length,callEdges:g},meta:{analyzedAt:new Date().toISOString(),scope:t,fileCount:p.length,durationMs:Date.now()-f}}}async collectFiles(e){let r=[],o;try{o=await n(e)}catch{throw Error(`Path does not exist: ${e}`)}if(o.isFile()){if(d.has(i(e)))return[e];throw Error(`Not a recognized source file: ${e}`)}if(!o.isDirectory())throw Error(`Not a file or directory: ${e}`);let s=async e=>{let n=await t(e,{withFileTypes:!0});for(let t of n){if(f.has(t.name)||t.name.startsWith(`.`))continue;let n=a(e,t.name);t.isDirectory()?await s(n):d.has(i(t.name))&&r.push(n)}};return await s(e),r}extractSymbolsRegex(e,t){let n=[],r=e.split(`
1
+ import{readFile as e,readdir as t,stat as n}from"node:fs/promises";import{dirname as r,extname as i,join as a,relative as o}from"node:path";import{SUPPORTED_EXTENSIONS as s,WasmRuntime as c,extractCalls as l,extractSymbols as u}from"../../chunker/dist/index.js";const d=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.java`,`.py`,`.go`,`.cs`,`.rb`,`.kt`,`.scala`,`.rs`,`.php`,`.swift`]),f=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,`__pycache__`,`.venv`,`target`,`bin`,`obj`,`.gradle`,`venv`,`env`]),p={exported:[{pattern:/^export\s+(?:async\s+)?function\s+(\w+)/gm,kind:`function`},{pattern:/^export\s+(?:default\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^export\s+interface\s+(\w+)/gm,kind:`interface`},{pattern:/^export\s+type\s+(\w+)/gm,kind:`type`},{pattern:/^export\s+(?:const|let)\s+(\w+)/gm,kind:`const`},{pattern:/^export\s+enum\s+(\w+)/gm,kind:`enum`}],local:[{pattern:/^(?:async\s+)?function\s+(\w+)/gm,kind:`function`},{pattern:/^class\s+(\w+)/gm,kind:`class`},{pattern:/^interface\s+(\w+)/gm,kind:`interface`},{pattern:/^type\s+(\w+)/gm,kind:`type`},{pattern:/^(?:const|let)\s+(\w+)\s*=/gm,kind:`const`},{pattern:/^enum\s+(\w+)/gm,kind:`enum`}]},m={exported:[{pattern:/^[ \t]*public\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,kind:`enum`},{pattern:/^[ \t]*public\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:abstract\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:synchronized\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])*)\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?(?:final\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*[;=]/gm,kind:`variable`}],skipIndentFilter:!0},h={exported:[{pattern:/^def\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^async\s+def\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^class\s+(\w+)/gm,kind:`class`}],local:[{pattern:/^[ \t]+def\s+(\w+)\s*\(/gm,kind:`function`},{pattern:/^[ \t]+async\s+def\s+(\w+)\s*\(/gm,kind:`function`}],skipIndentFilter:!0},g={exported:[{pattern:/^func\s+([A-Z]\w*)\s*\(/gm,kind:`function`},{pattern:/^func\s+\([^)]+\)\s+([A-Z]\w*)\s*\(/gm,kind:`function`},{pattern:/^type\s+([A-Z]\w*)\s+struct\b/gm,kind:`class`},{pattern:/^type\s+([A-Z]\w*)\s+interface\b/gm,kind:`interface`},{pattern:/^type\s+([A-Z]\w*)\s+/gm,kind:`type`}],local:[{pattern:/^func\s+([a-z]\w*)\s*\(/gm,kind:`function`},{pattern:/^func\s+\([^)]+\)\s+([a-z]\w*)\s*\(/gm,kind:`function`},{pattern:/^type\s+([a-z]\w*)\s+struct\b/gm,kind:`class`},{pattern:/^type\s+([a-z]\w*)\s+/gm,kind:`type`}],skipIndentFilter:!0},_={exported:[{pattern:/^[ \t]*public\s+(?:static\s+)?(?:partial\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*public\s+(?:static\s+)?interface\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*public\s+(?:static\s+)?enum\s+(\w+)/gm,kind:`enum`},{pattern:/^[ \t]*public\s+(?:static\s+)?(?:virtual\s+)?(?:override\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?(?:\[\])?)\s+(\w+)\s*\(/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:private|protected|internal)\s+(?:static\s+)?(?:async\s+)?(?:\w+(?:<[^>]*>)?)\s+(\w+)\s*\(/gm,kind:`function`}],skipIndentFilter:!0},v={exported:[{pattern:/^(?:open\s+|data\s+|sealed\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^(?:fun|suspend\s+fun)\s+(\w+)\s*[(<]/gm,kind:`function`},{pattern:/^interface\s+(\w+)/gm,kind:`interface`},{pattern:/^object\s+(\w+)/gm,kind:`class`},{pattern:/^enum\s+class\s+(\w+)/gm,kind:`enum`}],local:[{pattern:/^[ \t]+(?:private|internal)\s+(?:fun|suspend\s+fun)\s+(\w+)/gm,kind:`function`},{pattern:/^[ \t]+(?:private|internal)\s+(?:val|var)\s+(\w+)/gm,kind:`variable`}],skipIndentFilter:!0},y={exported:[{pattern:/^class\s+(\w+)/gm,kind:`class`},{pattern:/^module\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]+def\s+self\.(\w+)/gm,kind:`function`}],local:[{pattern:/^[ \t]+def\s+(\w+)/gm,kind:`function`}],skipIndentFilter:!0},b={exported:[{pattern:/^pub\s+(?:async\s+)?fn\s+(\w+)/gm,kind:`function`},{pattern:/^pub\s+struct\s+(\w+)/gm,kind:`class`},{pattern:/^pub\s+trait\s+(\w+)/gm,kind:`interface`},{pattern:/^pub\s+enum\s+(\w+)/gm,kind:`enum`},{pattern:/^pub\s+type\s+(\w+)/gm,kind:`type`}],local:[{pattern:/^(?:async\s+)?fn\s+(\w+)/gm,kind:`function`},{pattern:/^struct\s+(\w+)/gm,kind:`class`},{pattern:/^trait\s+(\w+)/gm,kind:`interface`},{pattern:/^enum\s+(\w+)/gm,kind:`enum`}],skipIndentFilter:!0},x={exported:[{pattern:/^[ \t]*(?:abstract\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*interface\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*public\s+(?:static\s+)?function\s+(\w+)/gm,kind:`function`},{pattern:/^function\s+(\w+)\s*\(/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|protected)\s+(?:static\s+)?function\s+(\w+)/gm,kind:`function`}],skipIndentFilter:!0},S={exported:[{pattern:/^[ \t]*(?:open|public)\s+class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:open|public)\s+struct\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*(?:open|public)\s+protocol\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*(?:open|public)\s+enum\s+(\w+)/gm,kind:`enum`},{pattern:/^[ \t]*(?:open|public)\s+func\s+(\w+)/gm,kind:`function`}],local:[{pattern:/^[ \t]*(?:private|fileprivate|internal)\s+func\s+(\w+)/gm,kind:`function`},{pattern:/^[ \t]*(?:private|fileprivate|internal)\s+class\s+(\w+)/gm,kind:`class`}],skipIndentFilter:!0},C={exported:[{pattern:/^[ \t]*(?:case\s+)?class\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*object\s+(\w+)/gm,kind:`class`},{pattern:/^[ \t]*trait\s+(\w+)/gm,kind:`interface`},{pattern:/^[ \t]*def\s+(\w+)/gm,kind:`function`}],local:[],skipIndentFilter:!0};function w(e){switch(e){case`.ts`:case`.tsx`:case`.js`:case`.jsx`:return p;case`.java`:return m;case`.py`:return h;case`.go`:return g;case`.cs`:return _;case`.kt`:return v;case`.rb`:return y;case`.rs`:return b;case`.php`:return x;case`.swift`:return S;case`.scala`:return C;default:return p}}function T(e,t){let n=``,r=0,i=!1;for(let a=t;a<Math.min(t+5,e.length);a++){let t=e[a].trim();n+=(n?` `:``)+t;for(let e of t)e===`(`&&(r++,i=!0),e===`)`&&r--;if(i&&r<=0)return n.replace(/\s*\{.*$/,``).replace(/\s*:\s*$/,``).trim()}return n.trim()||void 0}function E(e,t){let n=T(e,t);if(!n)return;let r=n.match(/\)\s*:\s*([^{=]+)/);if(r)return r[1].trim().slice(0,200)||void 0;let i=n.match(/=>\s*([^{]+)/);if(i)return i[1].trim().slice(0,200)||void 0}function D(e,t){for(let n=t-1;n>=Math.max(0,t-10);n--){let t=e[n].trim();if(t!==``){if(t.endsWith(`*/`)){for(let t=n;t>=Math.max(0,n-20);t--)if(e[t].trim().startsWith(`/**`)||e[t].trim().startsWith(`/*`)){for(let r=t;r<=n;r++){let t=e[r].replace(/^\s*\/\*\*?\s*/,``).replace(/\s*\*\/\s*$/,``).replace(/^\s*\*\s?/,``).trim();if(t.length>0&&!t.startsWith(`@`))return t.slice(0,200)}return}}if(t.startsWith(`//`))return t.replace(/^\/\/\s*/,``).slice(0,200)||void 0;break}}}function O(e,t){let n=``,r=0,i=!1;for(let a=t;a<Math.min(t+30,e.length);a++){let t=e[a];n+=` ${t.trim()}`;for(let e of t)e===`{`&&(r++,i=!0),e===`}`&&r--;if(i&&r<=0){let e=n.match(/\{([\s\S]*)\}/);if(e){let t=`{ ${e[1].replace(/\n\s*/g,` `).replace(/\s+/g,` `).trim()} }`;return t.length>500?`${t.slice(0,500)}…`:t}return}}}var k=class{name=`symbols`;async analyze(t,n={}){let{format:a=`markdown`,filter:d}=n,f=Date.now(),p=await this.collectFiles(t),m=p.length===1&&p[0]===t?r(t):t,h=[],g=[],_=!1;try{await c.ensure(),_=!0}catch{}for(let t of p){let n=await e(t,`utf-8`),r=o(m,t).replace(/\\/g,`/`),a=i(t);if(_&&s.has(a)){let e=await u(n,a,r);if(e.length>0){h.push(...e);let t=await l(n,a,r);g.push(...t)}else{let e=this.extractSymbolsRegex(n,r);h.push(...e)}}else{let e=this.extractSymbolsRegex(n,r);h.push(...e)}}if(d){let e=d.toLowerCase();h=h.filter(t=>t.name.toLowerCase().includes(e))}return{output:a===`json`?JSON.stringify(h,null,2):this.formatMarkdown(h,m,g),data:{symbols:h,byKind:this.groupByKind(h),exportedCount:h.filter(e=>e.exported).length,totalCount:h.length,callEdges:g},meta:{analyzedAt:new Date().toISOString(),scope:t,fileCount:p.length,durationMs:Date.now()-f}}}async collectFiles(e){let r=[],o;try{o=await n(e)}catch{throw Error(`Path does not exist: ${e}`)}if(o.isFile()){if(d.has(i(e)))return[e];throw Error(`Not a recognized source file: ${e}`)}if(!o.isDirectory())throw Error(`Not a file or directory: ${e}`);let s=async e=>{let n=await t(e,{withFileTypes:!0});for(let t of n){if(f.has(t.name)||t.name.startsWith(`.`))continue;let n=a(e,t.name);t.isDirectory()?await s(n):d.has(i(t.name))&&r.push(n)}};return await s(e),r}extractSymbolsRegex(e,t){let n=[],r=e.split(`
2
2
  `),a=new Set,o=w(i(t));for(let{pattern:i,kind:s}of o.exported){let o=new RegExp(i.source,i.flags),c;for(;(c=o.exec(e))!==null;){let i=c[1];a.add(i);let o=e.slice(0,c.index).split(`
3
- `).length,l=s===`function`||s===`method`?T(r,o-1):void 0;n.push({name:i,kind:s,exported:!0,filePath:t,line:o,signature:l})}}for(let{pattern:i,kind:s}of o.local){let c=new RegExp(i.source,i.flags),l;for(;(l=c.exec(e))!==null;){let i=l[1];if(a.has(i))continue;if(!o.skipIndentFilter){let t=r[e.slice(0,l.index).split(`
3
+ `).length,l=s===`function`||s===`method`?T(r,o-1):void 0,u=s===`function`||s===`method`?E(r,o-1):void 0,d=D(r,o-1),f=s===`interface`||s===`type`?O(r,o-1):void 0;n.push({name:i,kind:s,exported:!0,filePath:t,line:o,signature:l,returnType:u,jsdoc:d,typeBody:f})}}for(let{pattern:i,kind:s}of o.local){let c=new RegExp(i.source,i.flags),l;for(;(l=c.exec(e))!==null;){let i=l[1];if(a.has(i))continue;if(!o.skipIndentFilter){let t=r[e.slice(0,l.index).split(`
4
4
  `).length-1]??``;if(t.startsWith(` `)||t.startsWith(` `))continue}let c=e.slice(0,l.index).split(`
5
- `).length,u=s===`function`||s===`method`?T(r,c-1):void 0;n.push({name:i,kind:s,exported:!1,filePath:t,line:c,signature:u})}}return n}groupByKind(e){let t={};for(let n of e)t[n.kind]=(t[n.kind]??0)+1;return t}formatMarkdown(e,t,n=[]){let r=[],i=e.filter(e=>e.exported).length;r.push(`## Symbols: ${t}\n`),r.push(`**${e.length} symbols** (${i} exported)\n`);let a={};for(let t of e)a[t.kind]=(a[t.kind]??0)+1;let o=Object.entries(a).sort((e,t)=>t[1]-e[1]).map(([e,t])=>`${t} ${e===`class`?`classes`:`${e}s`}`).join(`, `);r.push(`**Breakdown**: ${o}\n`);let s={};for(let t of e)s[t.filePath]||(s[t.filePath]=[]),s[t.filePath].push(t);r.push(`**${Object.keys(s).length} files** with symbols\n`);let c=0,l=Object.entries(s).sort((e,t)=>{let n=e[1].filter(e=>e.exported).length;return t[1].filter(e=>e.exported).length-n});for(let[e,t]of l){let n=t.filter(e=>e.exported);if(n.length===0)continue;let i=[`### ${e}\n`];for(let e of n){let t=e.signature?` — \`${e.signature}\``:``;i.push(`- 📤 \`${e.kind}\` **${e.name}** (line ${e.line})${t}`)}let a=t.length-n.length;a>0&&i.push(`- _${a} internal ${a===1?`symbol`:`symbols`}_`),i.push(``);let o=i.join(`
5
+ `).length,u=s===`function`||s===`method`?T(r,c-1):void 0,d=s===`function`||s===`method`?E(r,c-1):void 0,f=D(r,c-1),p=s===`interface`||s===`type`?O(r,c-1):void 0;n.push({name:i,kind:s,exported:!1,filePath:t,line:c,signature:u,returnType:d,jsdoc:f,typeBody:p})}}return n}groupByKind(e){let t={};for(let n of e)t[n.kind]=(t[n.kind]??0)+1;return t}formatMarkdown(e,t,n=[]){let r=[],i=e.filter(e=>e.exported).length;r.push(`## Symbols: ${t}\n`),r.push(`**${e.length} symbols** (${i} exported)\n`);let a={};for(let t of e)a[t.kind]=(a[t.kind]??0)+1;let o=Object.entries(a).sort((e,t)=>t[1]-e[1]).map(([e,t])=>`${t} ${e===`class`?`classes`:`${e}s`}`).join(`, `);r.push(`**Breakdown**: ${o}\n`);let s={};for(let t of e)s[t.filePath]||(s[t.filePath]=[]),s[t.filePath].push(t);r.push(`**${Object.keys(s).length} files** with symbols\n`);let c=0,l=Object.entries(s).sort((e,t)=>{let n=e[1].filter(e=>e.exported).length;return t[1].filter(e=>e.exported).length-n});for(let[e,t]of l){let n=t.filter(e=>e.exported);if(n.length===0)continue;let i=[`### ${e}\n`];for(let e of n){let t=e.signature?` — \`${e.signature}\``:``,n=e.returnType?`: ${e.returnType}`:``,r=e.decorators?.length?` ${e.decorators.join(` `)}`:``;i.push(`- 📤 \`${e.kind}\` **${e.name}** (line ${e.line})${t}${n}`),r&&i.push(` ${r}`),e.jsdoc&&i.push(` > ${e.jsdoc}`),e.typeBody&&i.push(` \`${e.typeBody}\``)}let a=t.length-n.length;a>0&&i.push(`- _${a} internal ${a===1?`symbol`:`symbols`}_`),i.push(``);let o=i.join(`
6
6
  `);if(c+=o.length,c>81920){r.push(`\n_Output truncated at 80KB. ${Object.keys(s).length-r.filter(e=>e.startsWith(`### `)).length} files omitted._`);break}r.push(o)}return n.length>0&&r.push(this.formatCallGraph(n)),r.join(`
7
7
  `)}formatCallGraph(e){let t=new Map;for(let n of e){if(n.callerName===`<module>`)continue;let e=`${n.callerFile}:${n.callerName}->${n.calleeName}`,r=t.get(e);r?r.count++:t.set(e,{callerFile:n.callerFile,callerName:n.callerName,calleeName:n.calleeName,count:1})}if(t.size===0)return``;let n=[];n.push(`### Call Graph Summary
8
8
  `),n.push(`**${e.length} call edges** across analyzed files\n`);let r=new Map;for(let e of t.values()){let t=`${e.callerFile}#${e.callerName}`;r.has(t)||r.set(t,[]),r.get(t)?.push(e.calleeName)}let i=[...r.entries()].sort((e,t)=>t[1].length-e[1].length).slice(0,30);for(let[e,t]of i){let[r,i]=e.split(`#`);n.push(`- **${i}** (${r}) → ${t.join(`, `)}`)}return n.push(``),n.join(`
9
- `)}};export{E as SymbolAnalyzer};
9
+ `)}};export{k as SymbolAnalyzer};
@@ -72,6 +72,14 @@ interface SymbolInfo {
72
72
  line: number;
73
73
  /** Full signature for functions/methods (parameter list + return type) */
74
74
  signature?: string;
75
+ /** Return type annotation (e.g. "Promise<void>", "string") */
76
+ returnType?: string;
77
+ /** First line of JSDoc/docstring */
78
+ jsdoc?: string;
79
+ /** Decorator names (e.g. ["@Controller('/api')", "@Injectable"]) */
80
+ decorators?: string[];
81
+ /** Condensed body for interfaces/types (e.g. "{ id: string; name: string }") */
82
+ typeBody?: string;
75
83
  }
76
84
  interface PatternMatch {
77
85
  pattern: string;
@@ -1 +1,3 @@
1
- import{WasmRuntime as e}from"../wasm/runtime.js";import{QueryExecutor as t}from"../wasm/query-executor.js";const n=new t,r={function_declaration:`function`,class_declaration:`class`,interface_declaration:`interface`,type_alias_declaration:`type`,enum_declaration:`enum`,lexical_declaration:`const`,method_definition:`method`,public_field_definition:`variable`,field_definition:`variable`,function_definition:`function`,class_definition:`class`,expression_statement:`variable`,method_declaration:`method`,constructor_declaration:`method`,field_declaration:`variable`,type_spec:`type`,type_declaration:`type`,const_spec:`const`,var_spec:`variable`,function_item:`function`,struct_item:`class`,enum_item:`enum`,trait_item:`interface`,impl_item:`type`,const_item:`const`,static_item:`variable`,type_item:`type`};async function i(t,r,i=``){let o=await e.ensure(),s=await o.parse(t,r);if(!s)return[];let c=o.getLanguage(r);return c?a(n.execute(s.rootNode,c,r,`symbols`),r,i):[]}function a(e,t,n){let i=new Map;for(let n of e){let e=n.captures.get(`name`);if(!e)continue;let r=`${e.text}:${(n.captures.get(`node`)?.startLine??e.startLine)+1}`,a=o(n,t),s=i.get(r);(!s||!s.exported&&a)&&i.set(r,{match:n,exported:a})}let a=[];for(let{match:e,exported:o}of i.values()){let i=e.captures.get(`name`),l=e.captures.get(`node`);if(!i)continue;let u=r[l?.nodeType??i.nodeType]??`variable`,d=(l?.startLine??i.startLine)+1,f=s(u,l?.node,t);a.push({name:i.text,kind:f,exported:o,filePath:n,line:d,signature:c(l?.node,f)})}return a}function o(e,t){if(e.captures.has(`exported`))return!0;let n=e.captures.get(`name`)?.text;if(!n)return!1;if(t===`.py`)return!n.startsWith(`_`);if(t===`.go`)return/^[A-Z]/.test(n);if(t===`.java`){let t=e.captures.get(`node`)?.text??``;return/\bpublic\b/.test(t)}return!1}function s(e,t,n){if(n===`.go`&&e===`type`&&t?.children){let e=t.type===`type_declaration`?t.children.flatMap(e=>e.children??[]):t.children;for(let t of e){if(t.type===`interface_type`)return`interface`;if(t.type===`struct_type`)return`class`}}return e}function c(e,t){if(e){if(t===`function`||t===`method`)return l(e);if(t===`class`)return u(e);if(t===`interface`)return f(e)}}function l(e){let t=e.childForFieldName(`parameters`)??e.childForFieldName(`parameter_list`),n=e.childForFieldName(`return_type`)??e.childForFieldName(`type`),r=e.childForFieldName(`result`);if(!t){for(let t of e.children)if(t.type===`formal_parameters`||t.type===`parameter_list`||t.type===`parameters`){let e=t.text;return n&&(e+=n.text),r&&(e+=` ${r.text}`),e.length>120?`${e.slice(0,117)}...`:e}return}let i=t.text;return n&&(i+=n.text),r&&(i+=` ${r.text}`),i.length>120?`${i.slice(0,117)}...`:i}function u(e){let t=e.childForFieldName(`body`)??e.childForFieldName(`field_declaration_list`);if(!t){for(let t of e.children)if(t.type===`struct_type`||t.type===`class_body`)return d(t);return}return d(t)}function d(e){let t=[];for(let n of e.children){if(n.type===`method_definition`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`method_declaration`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`field_declaration`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`function_definition`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}}if(t.length===0)return;let n=t.join(`, `);return n.length>120?`${n.slice(0,117)}...`:n}function f(e){let t=e.childForFieldName(`body`);if(!t){for(let t of e.children)if(t.type===`interface_type`)return p(t);return}return p(t)}function p(e){let t=[];for(let n of e.children){if(n.type===`property_signature`||n.type===`method_signature`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`method_declaration`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`method_spec`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`function_signature_item`||n.type===`declaration_list`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}}if(t.length===0)return;let n=t.join(`, `);return n.length>120?`${n.slice(0,117)}...`:n}export{i as extractSymbols};
1
+ import{WasmRuntime as e}from"../wasm/runtime.js";import{QueryExecutor as t}from"../wasm/query-executor.js";const n=new t,r={function_declaration:`function`,class_declaration:`class`,interface_declaration:`interface`,type_alias_declaration:`type`,enum_declaration:`enum`,lexical_declaration:`const`,method_definition:`method`,public_field_definition:`variable`,field_definition:`variable`,function_definition:`function`,class_definition:`class`,expression_statement:`variable`,method_declaration:`method`,constructor_declaration:`method`,field_declaration:`variable`,type_spec:`type`,type_declaration:`type`,const_spec:`const`,var_spec:`variable`,function_item:`function`,struct_item:`class`,enum_item:`enum`,trait_item:`interface`,impl_item:`type`,const_item:`const`,static_item:`variable`,type_item:`type`};async function i(t,r,i=``){let o=await e.ensure(),s=await o.parse(t,r);if(!s)return[];let c=o.getLanguage(r);return c?a(n.execute(s.rootNode,c,r,`symbols`),r,i):[]}function a(e,t,n){let i=new Map;for(let n of e){let e=n.captures.get(`name`);if(!e)continue;let r=`${e.text}:${(n.captures.get(`node`)?.startLine??e.startLine)+1}`,a=o(n,t),s=i.get(r);(!s||!s.exported&&a)&&i.set(r,{match:n,exported:a})}let a=[];for(let{match:e,exported:o}of i.values()){let i=e.captures.get(`name`),l=e.captures.get(`node`);if(!i)continue;let u=r[l?.nodeType??i.nodeType]??`variable`,d=(l?.startLine??i.startLine)+1,f=s(u,l?.node,t),p=l?.node??i.node;a.push({name:i.text,kind:f,exported:o,filePath:n,line:d,signature:c(l?.node,f),returnType:m(l?.node,f),jsdoc:h(p),decorators:g(p),typeBody:_(l?.node,f)})}return a}function o(e,t){if(e.captures.has(`exported`))return!0;let n=e.captures.get(`name`)?.text;if(!n)return!1;if(t===`.py`)return!n.startsWith(`_`);if(t===`.go`)return/^[A-Z]/.test(n);if(t===`.java`){let t=e.captures.get(`node`)?.text??``;return/\bpublic\b/.test(t)}return!1}function s(e,t,n){if(n===`.go`&&e===`type`&&t?.children){let e=t.type===`type_declaration`?t.children.flatMap(e=>e.children??[]):t.children;for(let t of e){if(t.type===`interface_type`)return`interface`;if(t.type===`struct_type`)return`class`}}return e}function c(e,t){if(e){if(t===`function`||t===`method`)return l(e);if(t===`class`)return u(e);if(t===`interface`)return f(e)}}function l(e){let t=e.childForFieldName(`parameters`)??e.childForFieldName(`parameter_list`),n=e.childForFieldName(`return_type`)??e.childForFieldName(`type`),r=e.childForFieldName(`result`);if(!t){for(let t of e.children)if(t.type===`formal_parameters`||t.type===`parameter_list`||t.type===`parameters`){let e=t.text;return n&&(e+=n.text),r&&(e+=` ${r.text}`),e.length>120?`${e.slice(0,117)}...`:e}return}let i=t.text;return n&&(i+=n.text),r&&(i+=` ${r.text}`),i.length>120?`${i.slice(0,117)}...`:i}function u(e){let t=e.childForFieldName(`body`)??e.childForFieldName(`field_declaration_list`);if(!t){for(let t of e.children)if(t.type===`struct_type`||t.type===`class_body`)return d(t);return}return d(t)}function d(e){let t=[];for(let n of e.children){if(n.type===`method_definition`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`method_declaration`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`field_declaration`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`function_definition`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}}if(t.length===0)return;let n=t.join(`, `);return n.length>120?`${n.slice(0,117)}...`:n}function f(e){let t=e.childForFieldName(`body`);if(!t){for(let t of e.children)if(t.type===`interface_type`)return p(t);return}return p(t)}function p(e){let t=[];for(let n of e.children){if(n.type===`property_signature`||n.type===`method_signature`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`method_declaration`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`method_spec`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}if(n.type===`function_signature_item`||n.type===`declaration_list`){let e=n.childForFieldName(`name`);e&&t.push(e.text)}}if(t.length===0)return;let n=t.join(`, `);return n.length>120?`${n.slice(0,117)}...`:n}function m(e,t){if(!e||t!==`function`&&t!==`method`)return;let n=e.childForFieldName(`return_type`)??e.childForFieldName(`type`);if(n){let e=n.text.replace(/^:\s*/,``).trim();return e.length>200?`${e.slice(0,200)}…`:e}let r=e.childForFieldName(`result`);if(r)return r.text.trim()}function h(e){let t=e.parent;if(!t?.children)return;let n=t.children.indexOf(e);if(n<=0)return;let r=t.children[n-1];if(r){if(r.type===`comment`||r.type===`block_comment`||r.type===`doc_comment`)return r.text.replace(/^\/\*\*?\s*|\s*\*\/$/g,``).split(`
2
+ `).map(e=>e.replace(/^\s*\*\s?/,``).trim()).filter(e=>e.length>0&&!e.startsWith(`@`))[0]?.slice(0,200)||void 0;if(e.children[0]?.type===`expression_statement`){let t=e.children[0].children[0];if(t&&(t.type===`string`||t.type===`concatenated_string`))return t.text.replace(/^['"`]{1,3}|['"`]{1,3}$/g,``).trim().split(`
3
+ `)[0]?.trim()?.slice(0,200)||void 0}}}function g(e){let t=e.parent;if(!t?.children)return;let n=t.children.indexOf(e),r=[];for(let e=n-1;e>=0;e--){let n=t.children[e];if(n.type===`decorator`||n.type===`annotation`||n.type===`marker_annotation`){let e=n.text.trim();r.unshift(e.length>100?`${e.slice(0,100)}…`:e)}else if(n.type!==`comment`&&n.type!==`block_comment`&&n.type!==`doc_comment`)break}return r.length>0?r:void 0}function _(e,t){if(!e||t!==`interface`&&t!==`type`)return;let n=e.childForFieldName(`body`)??e.childForFieldName(`value`)??e.children.find(e=>e.type===`object_type`||e.type===`interface_body`||e.type===`type_body`);if(!n)return;let r=n.text.replace(/\n\s*/g,` `).replace(/\s+/g,` `).trim();return r.length>500?`${r.slice(0,500)}…`:r}export{i as extractSymbols};
@@ -12,6 +12,14 @@ interface SymbolInfo {
12
12
  filePath: string;
13
13
  line: number;
14
14
  signature?: string;
15
+ /** Return type annotation (e.g. "Promise<void>", "string") */
16
+ returnType?: string;
17
+ /** First line of JSDoc/docstring */
18
+ jsdoc?: string;
19
+ /** Decorator names (e.g. ["@Controller('/api')", "@Injectable"]) */
20
+ decorators?: string[];
21
+ /** Condensed body for interfaces/types (e.g. "{ id: string; name: string }") */
22
+ typeBody?: string;
15
23
  }
16
24
  interface ImportInfo {
17
25
  source: string;
@@ -108,6 +108,8 @@ interface KBConfig {
108
108
  curated: {
109
109
  path: string;
110
110
  };
111
+ /** Resolved directory for onboard/produce_knowledge output. User-level mode redirects this outside the project. */
112
+ onboardDir?: string;
111
113
  /** Enterprise RAG bridge configuration (optional) */
112
114
  er?: {
113
115
  /** Whether ER integration is enabled */enabled: boolean; /** Base URL of the ER API (e.g., https://xxx.execute-api.region.amazonaws.com/prod) */
@@ -1 +1 @@
1
- import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{KB_PATHS as a,createLogger as o,getPartitionDir as s,isUserInstalled as c,registerWorkspace as l,serializeError as u}from"../../core/dist/index.js";const d=n(i(import.meta.url)),f=o(`server`);function p(e,t,n){let i=r(e),a=r(t);if(!i.startsWith(a))throw Error(`Config ${n} path escapes workspace root: ${e} is not under ${t}`);return i}function m(){let i=process.env.KB_CONFIG_PATH??(e(r(process.cwd(),`kb.config.json`))?r(process.cwd(),`kb.config.json`):r(d,`..`,`..`,`..`,`kb.config.json`));try{if(!e(i))return f.info(`No config file found, using defaults`,{configPath:i}),h();let o=t(i,`utf-8`),s=JSON.parse(o);if(!s.sources||!Array.isArray(s.sources)||s.sources.length===0)throw Error(`Config must have at least one source`);if(!s.store?.path)throw Error(`Config must specify store.path`);let c=n(i);return s.sources=s.sources.map(e=>({...e,path:p(r(c,e.path),c,`source`)})),s.store.path=p(r(c,s.store.path),c,`store`),s.curated=s.curated??{path:a.aiCurated},s.curated.path=p(r(c,s.curated.path),c,`curated`),g(s,c),s}catch(e){return f.error(`Failed to load config`,{configPath:i,...u(e)}),f.warn(`Falling back to default configuration`,{configPath:i}),h()}}function h(){let e=process.env.KB_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`knowledge-base`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:`mixedbread-ai/mxbai-embed-large-v1`,dimensions:1024},store:{backend:`lancedb`,path:r(e,a.data)},curated:{path:r(e,a.aiCurated)}};return g(t,e),t}function g(e,t){if(!c())return;let n=t,i=l(n);e.store.path=r(s(i.partition)),e.curated||={path:r(n,a.aiCurated)}}function _(e,t){f.info(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),f.info(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){f.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...u(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],e.store.path=r(t,a.data),e.curated={path:r(t,a.aiCurated)},g(e,t)}export{m as loadConfig,_ as reconfigureForWorkspace};
1
+ import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{KB_PATHS as a,createLogger as o,getPartitionDir as s,isUserInstalled as c,registerWorkspace as l,serializeError as u}from"../../core/dist/index.js";const d=n(i(import.meta.url)),f=o(`server`);function p(e,t,n){let i=r(e),a=r(t);if(!i.startsWith(a))throw Error(`Config ${n} path escapes workspace root: ${e} is not under ${t}`);return i}function m(){let i=process.env.KB_CONFIG_PATH??(e(r(process.cwd(),`kb.config.json`))?r(process.cwd(),`kb.config.json`):r(d,`..`,`..`,`..`,`kb.config.json`));try{if(!e(i))return f.info(`No config file found, using defaults`,{configPath:i}),h();let o=t(i,`utf-8`),s=JSON.parse(o);if(!s.sources||!Array.isArray(s.sources)||s.sources.length===0)throw Error(`Config must have at least one source`);if(!s.store?.path)throw Error(`Config must specify store.path`);let c=n(i);return s.sources=s.sources.map(e=>({...e,path:p(r(c,e.path),c,`source`)})),s.store.path=p(r(c,s.store.path),c,`store`),s.curated=s.curated??{path:a.aiCurated},s.curated.path=p(r(c,s.curated.path),c,`curated`),g(s,c),s}catch(e){return f.error(`Failed to load config`,{configPath:i,...u(e)}),f.warn(`Falling back to default configuration`,{configPath:i}),h()}}function h(){let e=process.env.KB_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`knowledge-base`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:`mixedbread-ai/mxbai-embed-large-v1`,dimensions:1024},store:{backend:`lancedb`,path:r(e,a.data)},curated:{path:r(e,a.aiCurated)},onboardDir:r(e,a.aiKb)};return g(t,e),t}function g(e,t){if(!c())return;let n=t,i=l(n);e.store.path=r(s(i.partition)),e.onboardDir=r(s(i.partition),`onboard`),e.curated||={path:r(n,a.aiCurated)}}function _(e,t){f.info(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),f.info(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){f.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...u(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],e.store.path=r(t,a.data),e.curated={path:r(t,a.aiCurated)},e.onboardDir=r(t,a.aiKb),g(e,t)}export{m as loadConfig,_ as reconfigureForWorkspace};
@@ -14,6 +14,7 @@ declare const StatusOutputSchema: z.ZodObject<{
14
14
  totalFiles: z.ZodNumber;
15
15
  lastIndexedAt: z.ZodNullable<z.ZodString>;
16
16
  onboarded: z.ZodBoolean;
17
+ onboardDir: z.ZodString;
17
18
  contentTypes: z.ZodRecord<z.ZodString, z.ZodNumber>;
18
19
  wasmAvailable: z.ZodBoolean;
19
20
  graphStats: z.ZodNullable<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(),contentTypes:e.record(e.string(),e.number()),wasmAvailable:e.boolean(),graphStats:e.object({nodes:e.number(),edges:e.number()}).nullable(),curatedCount:e.number()}),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()}))}),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()}),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()}))}),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,3 +1,3 @@
1
- import{CuratedKnowledgeManager as e}from"./curated-manager.js";import{createElicitor as t,noopElicitor as n}from"./elicitor.js";import{bridgeMcpLogging as r}from"./mcp-logging.js";import{registerPrompts as i}from"./prompts.js";import{installReplayInterceptor as a}from"./replay-interceptor.js";import{ResourceNotifier as o}from"./resources/resource-notifier.js";import{registerResources as s}from"./resources/resources.js";import{createSamplingClient as c}from"./sampling.js";import{getToolMeta as l}from"./tool-metadata.js";import{installToolPrefix as u}from"./tool-prefix.js";import{registerAnalyzeDependenciesTool as d,registerAnalyzeDiagramTool as f,registerAnalyzeEntryPointsTool as p,registerAnalyzePatternsTool as m,registerAnalyzeStructureTool as h,registerAnalyzeSymbolsTool as ee,registerBlastRadiusTool as g}from"./tools/analyze.tools.js";import{registerAuditTool as _}from"./tools/audit.tool.js";import{registerBrainstormTool as v}from"./tools/brainstorm.tool.js";import{initBridgeComponents as te,registerErPullTool as y,registerErPushTool as b,registerErSyncStatusTool as x}from"./tools/bridge.tools.js";import{registerCompactTool as S,registerDeadSymbolsTool as C,registerFileSummaryTool as ne,registerFindTool as re,registerScopeMapTool as ie,registerSymbolTool as ae,registerTraceTool as oe}from"./tools/context.tools.js";import{registerErEvolveReviewTool as se}from"./tools/evolution.tools.js";import{registerBatchTool as ce,registerCheckTool as le,registerDelegateTool as w,registerEvalTool as T,registerParseOutputTool as E,registerTestRunTool as D}from"./tools/execution.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as O,registerForgeClassifyTool as k,registerForgeGroundTool as de,registerStratumCardTool as fe}from"./tools/forge.tools.js";import{registerForgetTool as pe}from"./tools/forget.tool.js";import{registerGraphTool as me}from"./tools/graph.tool.js";import{registerGuideTool as A,registerHealthTool as j,registerProcessTool as M,registerWatchTool as N,registerWebFetchTool as P}from"./tools/infra.tools.js";import{registerListTool as he}from"./tools/list.tool.js";import{registerLookupTool as ge}from"./tools/lookup.tool.js";import{registerCodemodTool as F,registerDataTransformTool as I,registerDiffParseTool as L,registerGitContextTool as R,registerRenameTool as z}from"./tools/manipulation.tools.js";import{registerOnboardTool as _e}from"./tools/onboard.tool.js";import{registerCheckpointTool as B,registerLaneTool as V,registerQueueTool as H,registerStashTool as U,registerWorksetTool as W}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as ve}from"./tools/policy.tools.js";import{registerPresentTool as G}from"./tools/present.tool.js";import{registerProduceKnowledgeTool as K}from"./tools/produce.tool.js";import{registerReadTool as ye}from"./tools/read.tool.js";import{registerReindexTool as be}from"./tools/reindex.tool.js";import{registerRememberTool as xe}from"./tools/remember.tool.js";import{registerReplayTool as q}from"./tools/replay.tool.js";import{registerRestoreTool as Se}from"./tools/restore.tool.js";import{registerSearchTool as Ce}from"./tools/search.tool.js";import{registerStatusTool as we}from"./tools/status.tool.js";import{registerUpdateTool as Te}from"./tools/update.tool.js";import{registerChangelogTool as Ee,registerEncodeTool as De,registerEnvTool as Oe,registerHttpTool as ke,registerMeasureTool as Ae,registerRegexTestTool as je,registerSchemaValidateTool as Me,registerSnippetTool as Ne,registerTimeTool as Pe,registerWebSearchTool as Fe}from"./tools/utility.tools.js";import{getCurrentVersion as Ie}from"./version-check.js";import{existsSync as Le,statSync as Re}from"node:fs";import{resolve as ze}from"node:path";import{KB_PATHS as Be,createLogger as Ve,serializeError as J}from"../../core/dist/index.js";import{initializeWasm as He}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ue}from"../../embeddings/dist/index.js";import{EvolutionCollector as We,PolicyStore as Ge}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Ke,IncrementalIndexer as qe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Je,createStore as Ye}from"../../store/dist/index.js";import{FileCache as Xe}from"../../tools/dist/index.js";import{McpServer as Ze}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=Ve(`server`);async function X(t){Y.info(`Initializing knowledge base components`);let[n,r,i,a]=await Promise.all([(async()=>{let e=new Ue({model:t.embedding.model,dimensions:t.embedding.dimensions});return await e.initialize(),Y.info(`Embedder loaded`,{modelId:e.modelId,dimensions:e.dimensions}),e})(),(async()=>{let e=await Ye({backend:t.store.backend,path:t.store.path});return await e.initialize(),Y.info(`Store initialized`),e})(),(async()=>{let e=new Je({path:t.store.path});return await e.initialize(),Y.info(`Graph store initialized`),e})(),(async()=>{let e=await He();return e?Y.info(`WASM tree-sitter enabled for AST analysis`):Y.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),o=new qe(n,r),s=new Ke(t.store.path);s.load(),o.setHashCache(s);let c=t.curated.path,l=new e(c,r,n);o.setGraphStore(i);let u=te(t.er),d=u?new Ge(t.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new We:void 0,p=ze(t.sources[0]?.path??process.cwd(),Be.aiKb),m=Le(p),h;if(m)try{h=Re(p).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:m,onboardTimestamp:h}),{embedder:n,store:r,indexer:o,curated:l,graphStore:i,fileCache:new Xe,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:m,onboardTimestamp:h}}function Qe(e,n){let a=new Ze({name:n.serverName??`knowledge-base`,version:Ie()},{capabilities:{logging:{}}});return r(a),u(a,n.toolPrefix??``),Z(a,e,n,t(a),new o(a),c(a)),i(a,{curated:e.curated,store:e.store,graphStore:e.graphStore}),a}function Z(e,t,n,r,i,o){a(e),Ce(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),ge(e,t.store),we(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp}),be(e,t.indexer,n,t.curated,t.store,i),xe(e,t.curated,t.policyStore,t.evolutionCollector,i),Te(e,t.curated,i),pe(e,t.curated,i),ye(e,t.curated),he(e,t.curated),h(e,t.store,t.embedder),d(e,t.store,t.embedder),ee(e,t.store,t.embedder),m(e,t.store,t.embedder),p(e,t.store,t.embedder),f(e,t.store,t.embedder),g(e,t.store,t.embedder,t.graphStore),K(e),_e(e,t.store,t.embedder),me(e,t.graphStore),_(e,t.store,t.embedder),S(e,t.embedder,t.fileCache),ie(e,t.embedder,t.store),re(e,t.embedder,t.store),E(e),W(e),le(e),ce(e,t.embedder,t.store),ae(e,t.embedder,t.store,t.graphStore),T(e),D(e),U(e),R(e),L(e),z(e),F(e),Se(e),ne(e,t.fileCache),B(e),I(e),oe(e,t.embedder,t.store),M(e),N(e),C(e,t.embedder,t.store),w(e,o),j(e),V(e),H(e),P(e),A(e),O(e),ue(e,t.embedder),k(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),G(e,r),r&&v(e,r),Fe(e),ke(e),je(e),De(e),Ae(e),Ee(e),Me(e),Ne(e),Oe(e),Pe(e),t.bridge&&(b(e,t.bridge,t.evolutionCollector),y(e,t.bridge),x(e,t.bridge)),t.policyStore&&ve(e,t.policyStore),t.evolutionCollector&&se(e,t.evolutionCollector),s(e,t.store,t.curated),q(e)}async function $e(e){let t=await X(e),n=Qe(t,e);Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Y.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Y.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,J(e))}try{let e=await t.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Y.error(`Curated re-index failed`,J(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,J(e))}},i=async()=>{Y.info(`Shutting down`),await t.embedder.shutdown().catch(()=>{}),await t.graphStore.close().catch(()=>{}),await t.store.close(),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i);let a=process.ppid,o=setInterval(()=>{try{process.kill(a,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const et=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.forge_classify.git_context.graph.guide.health.http.lane.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.snippet.stash.status.stratum_card.test_run.time.update.forget.list.watch.web_fetch.web_search.workset`.split(`.`)),tt=5e3,Q=new Set(`brainstorm.changelog.check.checkpoint.codemod.data_transform.delegate.diff_parse.encode.env.eval.evidence_map.forge_classify.git_context.guide.present.health.http.lane.measure.parse_output.process.produce_knowledge.queue.regex_test.rename.replay.restore.schema_validate.snippet.stash.test_run.time.watch.web_fetch.web_search.workset`.split(`.`));function nt(e){le(e),T(e),D(e),E(e),w(e),R(e),L(e),z(e),F(e),I(e),W(e),U(e),B(e),Se(e),V(e),H(e),j(e),M(e),N(e),P(e),A(e),O(e),k(e),G(e),v(e,n),K(e),q(e),Fe(e),ke(e),je(e),De(e),Ae(e),Ee(e),Me(e),Ne(e),Oe(e),Pe(e)}const $=`analyze_dependencies.analyze_diagram.analyze_entry_points.analyze_patterns.analyze_structure.analyze_symbols.audit.batch.blast_radius.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.dead_symbols.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.forge_classify.forge_ground.forget.git_context.graph.guide.health.http.lane.list.lookup.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.search.snippet.stash.status.stratum_card.symbol.test_run.time.trace.update.watch.web_fetch.web_search.workset`.split(`.`);function rt(e){let n=new Ze({name:e.serverName??`knowledge-base`,version:Ie()},{capabilities:{logging:{}}}),a=`initializing`,s=``,d=!1,f=()=>a===`failed`?[`❌ KB initialization failed — this tool is unavailable.`,``,s?`Error: ${s}`:``,``,`**35 tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
1
+ import{CuratedKnowledgeManager as e}from"./curated-manager.js";import{createElicitor as t,noopElicitor as n}from"./elicitor.js";import{bridgeMcpLogging as r}from"./mcp-logging.js";import{registerPrompts as i}from"./prompts.js";import{installReplayInterceptor as a}from"./replay-interceptor.js";import{ResourceNotifier as o}from"./resources/resource-notifier.js";import{registerResources as s}from"./resources/resources.js";import{createSamplingClient as c}from"./sampling.js";import{getToolMeta as l}from"./tool-metadata.js";import{installToolPrefix as u}from"./tool-prefix.js";import{registerAnalyzeDependenciesTool as d,registerAnalyzeDiagramTool as f,registerAnalyzeEntryPointsTool as p,registerAnalyzePatternsTool as m,registerAnalyzeStructureTool as h,registerAnalyzeSymbolsTool as ee,registerBlastRadiusTool as g}from"./tools/analyze.tools.js";import{registerAuditTool as _}from"./tools/audit.tool.js";import{registerBrainstormTool as v}from"./tools/brainstorm.tool.js";import{initBridgeComponents as te,registerErPullTool as y,registerErPushTool as b,registerErSyncStatusTool as x}from"./tools/bridge.tools.js";import{registerCompactTool as S,registerDeadSymbolsTool as C,registerFileSummaryTool as ne,registerFindTool as re,registerScopeMapTool as ie,registerSymbolTool as ae,registerTraceTool as oe}from"./tools/context.tools.js";import{registerErEvolveReviewTool as se}from"./tools/evolution.tools.js";import{registerBatchTool as ce,registerCheckTool as le,registerDelegateTool as w,registerEvalTool as T,registerParseOutputTool as E,registerTestRunTool as D}from"./tools/execution.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as O,registerForgeClassifyTool as k,registerForgeGroundTool as de,registerStratumCardTool as fe}from"./tools/forge.tools.js";import{registerForgetTool as pe}from"./tools/forget.tool.js";import{registerGraphTool as me}from"./tools/graph.tool.js";import{registerGuideTool as A,registerHealthTool as j,registerProcessTool as M,registerWatchTool as N,registerWebFetchTool as P}from"./tools/infra.tools.js";import{registerListTool as he}from"./tools/list.tool.js";import{registerLookupTool as ge}from"./tools/lookup.tool.js";import{registerCodemodTool as F,registerDataTransformTool as I,registerDiffParseTool as L,registerGitContextTool as R,registerRenameTool as z}from"./tools/manipulation.tools.js";import{registerOnboardTool as _e}from"./tools/onboard.tool.js";import{registerCheckpointTool as B,registerLaneTool as V,registerQueueTool as H,registerStashTool as U,registerWorksetTool as W}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as ve}from"./tools/policy.tools.js";import{registerPresentTool as G}from"./tools/present.tool.js";import{registerProduceKnowledgeTool as K}from"./tools/produce.tool.js";import{registerReadTool as ye}from"./tools/read.tool.js";import{registerReindexTool as be}from"./tools/reindex.tool.js";import{registerRememberTool as xe}from"./tools/remember.tool.js";import{registerReplayTool as q}from"./tools/replay.tool.js";import{registerRestoreTool as Se}from"./tools/restore.tool.js";import{registerSearchTool as Ce}from"./tools/search.tool.js";import{registerStatusTool as we}from"./tools/status.tool.js";import{registerUpdateTool as Te}from"./tools/update.tool.js";import{registerChangelogTool as Ee,registerEncodeTool as De,registerEnvTool as Oe,registerHttpTool as ke,registerMeasureTool as Ae,registerRegexTestTool as je,registerSchemaValidateTool as Me,registerSnippetTool as Ne,registerTimeTool as Pe,registerWebSearchTool as Fe}from"./tools/utility.tools.js";import{getCurrentVersion as Ie}from"./version-check.js";import{existsSync as Le,statSync as Re}from"node:fs";import{resolve as ze}from"node:path";import{KB_PATHS as Be,createLogger as Ve,serializeError as J}from"../../core/dist/index.js";import{initializeWasm as He}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ue}from"../../embeddings/dist/index.js";import{EvolutionCollector as We,PolicyStore as Ge}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Ke,IncrementalIndexer as qe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Je,createStore as Ye}from"../../store/dist/index.js";import{FileCache as Xe}from"../../tools/dist/index.js";import{McpServer as Ze}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=Ve(`server`);async function X(t){Y.info(`Initializing knowledge base components`);let[n,r,i,a]=await Promise.all([(async()=>{let e=new Ue({model:t.embedding.model,dimensions:t.embedding.dimensions});return await e.initialize(),Y.info(`Embedder loaded`,{modelId:e.modelId,dimensions:e.dimensions}),e})(),(async()=>{let e=await Ye({backend:t.store.backend,path:t.store.path});return await e.initialize(),Y.info(`Store initialized`),e})(),(async()=>{let e=new Je({path:t.store.path});return await e.initialize(),Y.info(`Graph store initialized`),e})(),(async()=>{let e=await He();return e?Y.info(`WASM tree-sitter enabled for AST analysis`):Y.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),o=new qe(n,r),s=new Ke(t.store.path);s.load(),o.setHashCache(s);let c=t.curated.path,l=new e(c,r,n);o.setGraphStore(i);let u=te(t.er),d=u?new Ge(t.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new We:void 0,p=ze(t.sources[0]?.path??process.cwd(),Be.aiKb),m=Le(p),h;if(m)try{h=Re(p).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:m,onboardTimestamp:h}),{embedder:n,store:r,indexer:o,curated:l,graphStore:i,fileCache:new Xe,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:m,onboardTimestamp:h}}function Qe(e,n){let a=new Ze({name:n.serverName??`knowledge-base`,version:Ie()},{capabilities:{logging:{}}});return r(a),u(a,n.toolPrefix??``),Z(a,e,n,t(a),new o(a),c(a)),i(a,{curated:e.curated,store:e.store,graphStore:e.graphStore}),a}function Z(e,t,n,r,i,o){a(e),Ce(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),ge(e,t.store),we(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n),be(e,t.indexer,n,t.curated,t.store,i),xe(e,t.curated,t.policyStore,t.evolutionCollector,i),Te(e,t.curated,i),pe(e,t.curated,i),ye(e,t.curated),he(e,t.curated),h(e,t.store,t.embedder),d(e,t.store,t.embedder),ee(e,t.store,t.embedder),m(e,t.store,t.embedder),p(e,t.store,t.embedder),f(e,t.store,t.embedder),g(e,t.store,t.embedder,t.graphStore),K(e,n),_e(e,t.store,t.embedder,n),me(e,t.graphStore),_(e,t.store,t.embedder),S(e,t.embedder,t.fileCache),ie(e,t.embedder,t.store),re(e,t.embedder,t.store),E(e),W(e),le(e),ce(e,t.embedder,t.store),ae(e,t.embedder,t.store,t.graphStore),T(e),D(e),U(e),R(e),L(e),z(e),F(e),Se(e),ne(e,t.fileCache),B(e),I(e),oe(e,t.embedder,t.store),M(e),N(e),C(e,t.embedder,t.store),w(e,o),j(e),V(e),H(e),P(e),A(e),O(e),ue(e,t.embedder),k(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),G(e,r),r&&v(e,r),Fe(e),ke(e),je(e),De(e),Ae(e),Ee(e),Me(e),Ne(e),Oe(e),Pe(e),t.bridge&&(b(e,t.bridge,t.evolutionCollector),y(e,t.bridge),x(e,t.bridge)),t.policyStore&&ve(e,t.policyStore),t.evolutionCollector&&se(e,t.evolutionCollector),s(e,t.store,t.curated),q(e)}async function $e(e){let t=await X(e),n=Qe(t,e);Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Y.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Y.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,J(e))}try{let e=await t.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Y.error(`Curated re-index failed`,J(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,J(e))}},i=async()=>{Y.info(`Shutting down`),await t.embedder.shutdown().catch(()=>{}),await t.graphStore.close().catch(()=>{}),await t.store.close(),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i);let a=process.ppid,o=setInterval(()=>{try{process.kill(a,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const et=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.forge_classify.git_context.graph.guide.health.http.lane.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.snippet.stash.status.stratum_card.test_run.time.update.forget.list.watch.web_fetch.web_search.workset`.split(`.`)),tt=5e3,Q=new Set(`brainstorm.changelog.check.checkpoint.codemod.data_transform.delegate.diff_parse.encode.env.eval.evidence_map.forge_classify.git_context.guide.present.health.http.lane.measure.parse_output.process.produce_knowledge.queue.regex_test.rename.replay.restore.schema_validate.snippet.stash.test_run.time.watch.web_fetch.web_search.workset`.split(`.`));function nt(e){le(e),T(e),D(e),E(e),w(e),R(e),L(e),z(e),F(e),I(e),W(e),U(e),B(e),Se(e),V(e),H(e),j(e),M(e),N(e),P(e),A(e),O(e),k(e),G(e),v(e,n),K(e),q(e),Fe(e),ke(e),je(e),De(e),Ae(e),Ee(e),Me(e),Ne(e),Oe(e),Pe(e)}const $=`analyze_dependencies.analyze_diagram.analyze_entry_points.analyze_patterns.analyze_structure.analyze_symbols.audit.batch.blast_radius.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.dead_symbols.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.forge_classify.forge_ground.forget.git_context.graph.guide.health.http.lane.list.lookup.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.search.snippet.stash.status.stratum_card.symbol.test_run.time.trace.update.watch.web_fetch.web_search.workset`.split(`.`);function rt(e){let n=new Ze({name:e.serverName??`knowledge-base`,version:Ie()},{capabilities:{logging:{}}}),a=`initializing`,s=``,d=!1,f=()=>a===`failed`?[`❌ KB initialization failed — this tool is unavailable.`,``,s?`Error: ${s}`:``,``,`**35 tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
2
2
  `):[`KB is still initializing (loading embeddings model & store).`,``,`**35 tools are already available** while initialization completes — including:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`This tool requires the knowledge base index. Please retry in a few seconds,`,`or use one of the available tools above in the meantime.`].join(`
3
3
  `);r(n),u(n,e.toolPrefix??``);let p=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let m=[];for(let e of $){let t=l(e),r=n.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:f()}]}));Q.has(e)?r.remove():m.push(r)}nt(n),n.sendToolListChanged=p;let h=n.resource(`kb-status`,`kb://status`,{description:`Knowledge base status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`kb://status`,text:`KB is initializing...`,mimeType:`text/plain`}]})),ee=n.prompt(`_init`,`KB is initializing prompts...`,async()=>({messages:[{role:`user`,content:{type:`text`,text:f()}}]})),g,_=new Promise(e=>{g=e}),v,te=new Promise(e=>{v=e}),y=()=>v?.(),b=(async()=>{await te;let r;try{r=await X(e)}catch(e){a=`failed`,s=e instanceof Error?e.message:String(e),Y.error(`KB initialization failed — server continuing with zero-dep tools only`,{error:s});return}let l=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let u=n.sendPromptListChanged.bind(n);n.sendPromptListChanged=()=>{};let f=n.sendResourceListChanged.bind(n);n.sendResourceListChanged=()=>{};for(let e of m)e.remove();h.remove(),ee.remove();let p=n._registeredTools??{};for(let e of Q)p[e]?.remove();let _=new o(n),v=c(n);Z(n,r,e,t(n),_,v),i(n),n.sendToolListChanged=l,n.sendPromptListChanged=u,n.sendResourceListChanged=f,Promise.resolve(n.sendToolListChanged()).catch(()=>{}),Promise.resolve(n.sendPromptListChanged()).catch(()=>{}),Promise.resolve(n.sendResourceListChanged()).catch(()=>{});let y=n._registeredTools??{};for(let[e,t]of Object.entries(y)){if(et.has(e))continue;let n=t.handler;t.handler=async(...t)=>{if(!r.indexer.isIndexing)return n(...t);let i=d?`re-indexing`:`running initial index`,a=new Promise(t=>setTimeout(()=>t({content:[{type:`text`,text:`⏳ KB is ${i}. The tool "${e}" timed out waiting for index data (${tt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),tt));return Promise.race([n(...t),a])}}let b=Object.keys(y).length;b!==$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:b}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4}),g?.(r)})(),x=async()=>{let t=await _;try{let n=e.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Y.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Y.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});d=!0,Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,J(e))}try{let e=await t.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Y.error(`Curated re-index failed`,J(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,J(e))}},S=process.ppid,C=setInterval(()=>{try{process.kill(S,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:S}),clearInterval(C),_.then(async e=>{await e.embedder.shutdown().catch(()=>{}),await e.graphStore.close().catch(()=>{}),await e.store.close().catch(()=>{})}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return C.unref(),{server:n,startInit:y,ready:b,runInitialIndex:x}}export{$ as ALL_TOOL_NAMES,rt as createLazyServer,Qe as createMcpServer,$e as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
@@ -1,6 +1,7 @@
1
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{z as u}from"zod";import{CONTENT_TYPES as d,computePartitionKey as f,createLogger as p,serializeError as m}from"../../../core/dist/index.js";import{compact as h,fileSummary as g,find as _,findDeadSymbols as v,findExamples as y,scopeMap as b,symbol as x,trace as S,truncateToTokenBudget as C}from"../../../tools/dist/index.js";const w=p(`tools:context`);function T(n,r,i){let a=e(`compact`);n.registerTool(`compact`,{title:a.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:u.string().optional().describe(`The text to compress (provide this OR path, not both)`),path:u.string().optional().describe(`File path to read server-side — avoids read_file round-trip + token doubling (provide this OR text)`),query:u.string().describe(`Focus query — what are you trying to understand?`),max_chars:u.number().min(100).max(5e4).default(3e3).describe(`Target output size in characters`),segmentation:u.enum([`paragraph`,`sentence`,`line`]).default(`paragraph`).describe(`How to split the text for scoring`)},annotations:a.annotations},async({text:e,path:t,query:n,max_chars:a,segmentation:o})=>{try{if(!e&&!t)return{content:[{type:`text`,text:`Error: Either "text" or "path" must be provided.`}],isError:!0};let s=await h(r,{text:e,path:t,query:n,maxChars:a,segmentation:o,cache:i});return{content:[{type:`text`,text:[`Compressed ${s.originalChars} → ${s.compressedChars} chars (${(s.ratio*100).toFixed(0)}%)`,`Kept ${s.segmentsKept}/${s.segmentsTotal} segments`,``,s.text].join(`
2
2
  `)}],structuredContent:{originalChars:s.originalChars,compressedChars:s.compressedChars,ratio:s.ratio,segmentsKept:s.segmentsKept,segmentsTotal:s.segmentsTotal}}}catch(e){return w.error(`Compact failed`,m(e)),{content:[{type:`text`,text:`Compact failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function E(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:u.string().describe(`Description of the task to scope`),max_files:u.number().min(1).max(50).default(15).describe(`Maximum files to include`),content_type:u.enum(d).optional().describe(`Filter by content type`),max_tokens:u.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 b(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?C(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 w.error(`Scope map failed`,m(e)),{content:[{type:`text`,text:`Scope map failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function D(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:u.string().optional().describe(`Semantic/keyword search query (required for mode "examples")`),glob:u.string().optional().describe(`File glob pattern (search mode only)`),pattern:u.string().optional().describe(`Regex pattern to match in content (search mode only)`),limit:u.number().min(1).max(50).default(10).describe(`Max results`),content_type:u.enum(d).optional().describe(`Filter by content type`),mode:u.enum([`search`,`examples`]).default(`search`).describe(`Mode: "search" (default) for federated search, "examples" to find usage examples of a symbol/pattern`),max_tokens:u.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),workspaces:u.array(u.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:p})=>{try{if(u===`examples`){if(!e)return{content:[{type:`text`,text:`Error: "query" is required for mode "examples".`}],isError:!0};let t=await y(n,r,{query:e,limit:a,contentType:o}),i=JSON.stringify(t);return{content:[{type:`text`,text:d?C(i,d):i}]}}let m=await _(n,r,{query:e,glob:t,pattern:i,limit:a,contentType:o}),h=``;if(p&&p.length>0&&e){let t=l(p,f(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)m.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)});m.results.sort((e,t)=>t.score-e.score),m.results=m.results.slice(0,a),m.totalFound=m.results.length,h=` + ${t.length} workspace(s)`}finally{await i()}}}if(m.results.length===0)return{content:[{type:`text`,text:`No results found.`}],structuredContent:{matches:[],totalMatches:0,pattern:e??t??i??``,truncated:!1}};let g=[`Found ${m.totalFound} results via ${m.strategies.join(` + `)}${h}`,``,...m.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?C(g.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?C(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 w.error(`Scope map failed`,m(e)),{content:[{type:`text`,text:`Scope map failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function D(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:u.string().optional().describe(`Semantic/keyword search query (required for mode "examples")`),glob:u.string().optional().describe(`File glob pattern (search mode only)`),pattern:u.string().optional().describe(`Regex pattern to match in content (search mode only)`),limit:u.number().min(1).max(50).default(10).describe(`Max results`),content_type:u.enum(d).optional().describe(`Filter by content type`),mode:u.enum([`search`,`examples`]).default(`search`).describe(`Mode: "search" (default) for federated search, "examples" to find usage examples of a symbol/pattern`),max_tokens:u.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),workspaces:u.array(u.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:p})=>{try{if(u===`examples`){if(!e)return{content:[{type:`text`,text:`Error: "query" is required for mode "examples".`}],isError:!0};let t=await y(n,r,{query:e,limit:a,contentType:o}),i=JSON.stringify(t);return{content:[{type:`text`,text:d?C(i,d):i}]}}let m=await _(n,r,{query:e,glob:t,pattern:i,limit:a,contentType:o}),h=``;if(p&&p.length>0&&e){let t=l(p,f(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)m.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)});m.results.sort((e,t)=>t.score-e.score),m.results=m.results.slice(0,a),m.totalFound=m.results.length,h=` + ${t.length} workspace(s)`}finally{await i()}}}if(m.results.length===0)return{content:[{type:`text`,text:`No results found.${m.failedStrategies?.length?`\nStrategies attempted: ${m.strategies.join(`, `)}\nFailed: ${m.failedStrategies.map(e=>`${e.strategy} (${e.reason})`).join(`, `)}`:m.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 ${m.totalFound} results via ${m.strategies.join(` + `)}${h}`,``,...m.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?C(g.join(`
4
5
  `),d):g.join(`
5
6
  `)}],structuredContent:{matches:m.results.map(e=>({path:e.path,...e.lineRange?{line:e.lineRange.start}:{},matchType:e.source,preview:e.preview?.slice(0,200)??``})),totalMatches:m.totalFound,pattern:e??t??i??``,truncated:m.results.length<m.totalFound}}}catch(e){return w.error(`Find failed`,m(e)),{content:[{type:`text`,text:`Find failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function O(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:u.string().describe(`Symbol name to look up (function, class, type, etc.)`),limit:u.number().min(1).max(50).default(20).describe(`Max results per category`),workspaces:u.array(u.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 x(n,r,{name:e,limit:t,graphStore:i});if(a&&a.length>0){let r=l(a,f(process.cwd()));if(r.length>0){let{stores:i,closeAll:a}=await c(r);try{for(let[r,a]of i){let i=await x(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:M(o)}],structuredContent:s}}catch(e){return w.error(`Symbol lookup failed`,m(e)),{content:[{type:`text`,text:`Symbol lookup failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function k(t,n){let i=e(`file_summary`);t.registerTool(`file_summary`,{title:i.title,description:`Create a concise structural summary of a source file: imports, exports, functions, classes, interfaces, and types.`,outputSchema:r,inputSchema:{path:u.string().describe(`Absolute path to the file to summarize`)},annotations:i.annotations},async({path:e})=>{try{let t=await g({path:e,content:(await n.get(e)).content});return{content:[{type:`text`,text:N(t)}],structuredContent:{path:t.path,language:t.language,lines:t.lines,imports:t.imports?.length??0,exports:t.exports?.length??0,functions:t.functions?.length??0,classes:t.classes?.length??0}}}catch(e){return w.error(`File summary failed`,m(e)),{content:[{type:`text`,text:`File summary failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function A(t,n,r){let i=e(`trace`);t.registerTool(`trace`,{title:i.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:u.string().describe(`Starting point — symbol name or file:line reference`),direction:u.enum([`forward`,`backward`,`both`]).describe(`Which direction to trace relationships`),max_depth:u.number().min(1).max(10).default(3).optional().describe(`Maximum trace depth`)},annotations:i.annotations},async({start:e,direction:t,max_depth:i})=>{try{let a=await S(n,r,{start:e,direction:t,maxDepth:i}),o=[`## Trace: ${a.start}`,`Direction: ${a.direction} | Depth: ${a.depth}`,``];if(a.nodes.length===0)o.push(`No connections found.`);else{let e=a.nodes.filter(e=>e.relationship===`calls`),t=a.nodes.filter(e=>e.relationship===`called-by`),n=a.nodes.filter(e=>e.relationship===`imports`),r=a.nodes.filter(e=>e.relationship===`imported-by`),i=a.nodes.filter(e=>e.relationship===`references`);if(e.length>0){o.push(`### Calls (${e.length})`);for(let t of e){let e=t.scope?` (from ${t.scope}())`:``;o.push(`- ${t.symbol}() — ${t.path}:${t.line}${e}`)}o.push(``)}if(t.length>0){o.push(`### Called by (${t.length})`);for(let e of t){let t=e.scope?` in ${e.scope}()`:``;o.push(`- ${e.symbol}()${t} — ${e.path}:${e.line}`)}o.push(``)}if(n.length>0){o.push(`### Imports (${n.length})`);for(let e of n)o.push(`- ${e.symbol} — ${e.path}:${e.line}`);o.push(``)}if(r.length>0){o.push(`### Imported by (${r.length})`);for(let e of r)o.push(`- ${e.path}:${e.line}`);o.push(``)}if(i.length>0){o.push(`### References (${i.length})`);for(let e of i)o.push(`- ${e.path}:${e.line}`);o.push(``)}}return o.push(`---`,"_Next: `symbol` for definition details | `compact` to read a referenced file | `blast_radius` for impact analysis_"),{content:[{type:`text`,text:o.join(`
6
7
  `)}]}}catch(e){return w.error(`Trace failed`,m(e)),{content:[{type:`text`,text:`Trace failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function j(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:u.string().optional().describe(`Root path to scope the search (default: cwd)`),limit:u.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 v(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(`
@@ -1,3 +1,5 @@
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 any URL and convert to LLM-optimized markdown. Supports CSS selectors, 4 output modes (markdown/raw/links/outline), smart paragraph-boundary truncation. Strips scripts/styles/nav automatically.`,inputSchema:{url:n.string().url().describe(`URL to fetch (http/https only)`),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({url:e,mode:t,selector:n,max_length:r,include_metadata:a,include_links:o,include_images:s,timeout:c})=>{try{let i=await h({url:e,mode:t,selector:n,maxLength:r,includeMetadata:a,includeLinks:o,includeImages:s,timeout:c}),l=[`## ${i.title||`Web Page`}`,``,i.content];return i.truncated&&l.push(``,`_Original length: ${i.originalLength.toLocaleString()} chars_`),l.push(``,`---`,"_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._"),{content:[{type:`text`,text:l.join(`
2
- `)}]}}catch(e){return g.error(`Web fetch failed`,i(e)),{content:[{type:`text`,text:`Web fetch failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function x(t){let r=e(`guide`);t.registerTool(`guide`,{title:r.title,description:`Tool discovery — given a goal description, recommends which KB 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:r.annotations},async({goal:e,max_recommendations:t})=>{try{let n=a(e,t),r=[`## 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&&r.push(``,`_Alternative workflows: ${n.alternativeWorkflows.join(`, `)}_`),r.push(``,`---`,"_Next: Run the first recommended tool, or use `guide` again with a more specific goal._"),{content:[{type:`text`,text:r.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(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(`
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
+
4
+ `)}],...m===f.length?{isError:!0}:{}}})}function x(t){let r=e(`guide`);t.registerTool(`guide`,{title:r.title,description:`Tool discovery — given a goal description, recommends which KB 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:r.annotations},async({goal:e,max_recommendations:t})=>{try{let n=a(e,t),r=[`## 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&&r.push(``,`_Alternative workflows: ${n.alternativeWorkflows.join(`, `)}_`),r.push(``,`---`,"_Next: Run the first recommended tool, or use `guide` again with a more specific goal._"),{content:[{type:`text`,text:r.join(`
3
5
  `)}]}}catch(e){return g.error(`Guide failed`,i(e)),{content:[{type:`text`,text:`Guide failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{x as registerGuideTool,y as registerHealthTool,_ as registerProcessTool,v as registerWatchTool,b as registerWebFetchTool};
@@ -1,8 +1,9 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { KBConfig } from "@kb/core";
2
3
  import { IEmbedder } from "@kb/embeddings";
3
4
  import { IKnowledgeStore } from "@kb/store";
4
5
 
5
6
  //#region packages/server/src/tools/onboard.tool.d.ts
6
- declare function registerOnboardTool(server: McpServer, store: IKnowledgeStore, embedder: IEmbedder): void;
7
+ declare function registerOnboardTool(server: McpServer, store: IKnowledgeStore, embedder: IEmbedder, config?: KBConfig): void;
7
8
  //#endregion
8
9
  export { registerOnboardTool };
@@ -1,2 +1,2 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{createHash as n}from"node:crypto";import{z as r}from"zod";import{createLogger as i,serializeError as a}from"../../../core/dist/index.js";import{onboard as o}from"../../../tools/dist/index.js";const s=i(`tools`);let c=!1;async function l(e,t,r){for(let i of r.steps)if(!(i.status!==`success`||!i.output))try{let a=n(`sha256`).update(r.path).digest(`hex`).slice(0,12),o=`produced/onboard/${i.name}/${a}.md`,s=n(`sha256`).update(i.output).digest(`hex`).slice(0,16),c=new Date().toISOString(),l=i.output.length>2e3?i.output.split(/(?=^## )/m).filter(e=>e.trim().length>0):[i.output],u=l.map((e,t)=>({id:n(`sha256`).update(`${o}::${t}`).digest(`hex`).slice(0,16),content:e.trim(),sourcePath:o,contentType:`produced-knowledge`,chunkIndex:t,totalChunks:l.length,startLine:0,endLine:0,fileHash:s,indexedAt:c,origin:`produced`,tags:[`onboard`,i.name],category:`analysis`,version:1})),d=await t.embedBatch(u.map(e=>e.content));await e.upsert(u,d)}catch(e){s.warn(`Auto-persist onboard step failed`,{stepName:i.name,...a(e)})}}function u(n,i,u){let d=e(`onboard`);n.registerTool(`onboard`,{title:d.title,description:`First-time codebase onboarding: runs all analysis tools (structure, dependencies, entry-points, symbols, patterns, diagram) in one command. Results are auto-persisted to KB. Use mode=generate to also write structured output to .ai/kb/ directory.`,inputSchema:{path:r.string().describe(`Root path of the codebase to onboard`),mode:r.enum([`memory`,`generate`]).default(`memory`).describe(`Output mode: memory = KB vector store only; generate = also write to .ai/kb/ directory`),out_dir:r.string().optional().describe(`Custom output directory for generate mode (default: <path>/.ai/kb)`)},annotations:d.annotations},async({path:e,mode:n,out_dir:r},d)=>{try{if(c)return{content:[{type:`text`,text:`Onboard is already running. Please wait for it to complete before starting another.`}]};c=!0,s.info(`Starting onboard`,{path:e,mode:n});let a=await o({path:e,mode:n,outDir:r}),f=t(d).createTask(`Onboard`,a.steps.length);for(let e=0;e<a.steps.length;e++){let t=a.steps[e];f.progress(e,`${t.name}: ${t.status}`)}f.complete(`Onboard complete: ${a.steps.filter(e=>e.status===`success`).length}/${a.steps.length} steps succeeded`),l(i,u,a);let p=[`## Onboard Complete`,``,`**Path:** \`${a.path}\``,`**Mode:** ${a.mode}`,`**Duration:** ${a.totalDurationMs}ms`,``];a.outDir&&(p.push(`**Output directory:** \`${a.outDir}\``),p.push(``)),p.push(`### Analysis Results`,``);let m=[],h=[];for(let e of a.steps)e.status===`success`?m.push(`- ✓ **${e.name}** (${e.durationMs}ms) — ${e.output.length} chars`):h.push(`- ✗ **${e.name}** — ${e.error}`);p.push(...m),h.length>0&&p.push(``,`### Failed`,``,...h),p.push(``,`---`,``);for(let e of a.steps)e.status===`success`&&p.push(`### ${e.name}`,``,e.output,``,`---`,``);return p.push(`_All results auto-saved to KB.`,a.mode===`generate`?` Files written to \`${a.outDir}\`.`:``," Next: Use `search` to query the knowledge, or `remember` to add custom insights._"),{content:[{type:`text`,text:p.join(`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{createHash as n}from"node:crypto";import{z as r}from"zod";import{createLogger as i,serializeError as a}from"../../../core/dist/index.js";import{onboard as o}from"../../../tools/dist/index.js";const s=i(`tools`);let c=!1;async function l(e,t,r){for(let i of r.steps)if(!(i.status!==`success`||!i.output))try{let a=n(`sha256`).update(r.path).digest(`hex`).slice(0,12),o=`produced/onboard/${i.name}/${a}.md`,s=n(`sha256`).update(i.output).digest(`hex`).slice(0,16),c=new Date().toISOString(),l=i.output.length>2e3?i.output.split(/(?=^## )/m).filter(e=>e.trim().length>0):[i.output],u=l.map((e,t)=>({id:n(`sha256`).update(`${o}::${t}`).digest(`hex`).slice(0,16),content:e.trim(),sourcePath:o,contentType:`produced-knowledge`,chunkIndex:t,totalChunks:l.length,startLine:0,endLine:0,fileHash:s,indexedAt:c,origin:`produced`,tags:[`onboard`,i.name],category:`analysis`,version:1})),d=await t.embedBatch(u.map(e=>e.content));await e.upsert(u,d)}catch(e){s.warn(`Auto-persist onboard step failed`,{stepName:i.name,...a(e)})}}function u(n,i,u,d){let f=e(`onboard`);n.registerTool(`onboard`,{title:f.title,description:`First-time codebase onboarding: runs all analysis tools (structure, dependencies, entry-points, symbols, patterns, diagram) in one command. Results are auto-persisted to KB. Use mode=generate to also write structured output to .ai/kb/ directory.`,inputSchema:{path:r.string().describe(`Root path of the codebase to onboard`),mode:r.enum([`memory`,`generate`]).default(`generate`).describe(`Output mode: generate (default) = persist to KB + write .ai/kb/ files; memory = KB vector store only`),out_dir:r.string().optional().describe(`Custom output directory for generate mode (default: <path>/.ai/kb)`)},annotations:f.annotations},async({path:e,mode:n,out_dir:r},f)=>{try{if(c)return{content:[{type:`text`,text:`Onboard is already running. Please wait for it to complete before starting another.`}]};c=!0,s.info(`Starting onboard`,{path:e,mode:n});let a=await o({path:e,mode:n,outDir:r??d?.onboardDir}),p=t(f).createTask(`Onboard`,a.steps.length);for(let e=0;e<a.steps.length;e++){let t=a.steps[e];p.progress(e,`${t.name}: ${t.status}`)}p.complete(`Onboard complete: ${a.steps.filter(e=>e.status===`success`).length}/${a.steps.length} steps succeeded`),l(i,u,a);let m=[`## Onboard Complete`,``,`**Path:** \`${a.path}\``,`**Mode:** ${a.mode}`,`**Duration:** ${a.totalDurationMs}ms`,``];a.outDir&&(m.push(`**Output directory:** \`${a.outDir}\``),m.push(``)),m.push(`### Analysis Results`,``);let h=[],g=[];for(let e of a.steps)e.status===`success`?h.push(`- ✓ **${e.name}** (${e.durationMs}ms) — ${e.output.length} chars`):g.push(`- ✗ **${e.name}** — ${e.error}`);m.push(...h),g.length>0&&m.push(``,`### Failed`,``,...g),m.push(``,`---`,``);for(let e of a.steps)e.status===`success`&&m.push(`### ${e.name}`,``,e.output,``,`---`,``);return m.push(`_All results auto-saved to KB.`,a.mode===`generate`?` Files written to \`${a.outDir}\`.`:``," Next: Use `search` to query the knowledge, or `remember` to add custom insights._"),{content:[{type:`text`,text:m.join(`
2
2
  `)}]}}catch(e){return s.error(`Onboard failed`,a(e)),{content:[{type:`text`,text:`Onboard failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}finally{c=!1}})}export{u as registerOnboardTool};
@@ -1,6 +1,7 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { KBConfig } from "@kb/core";
2
3
 
3
4
  //#region packages/server/src/tools/produce.tool.d.ts
4
- declare function registerProduceKnowledgeTool(server: McpServer): void;
5
+ declare function registerProduceKnowledgeTool(server: McpServer, config?: KBConfig): void;
5
6
  //#endregion
6
7
  export { registerProduceKnowledgeTool };
@@ -1,4 +1,4 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{createLogger as n,serializeError as r}from"../../../core/dist/index.js";import{DependencyAnalyzer as i,DiagramGenerator as a,EntryPointAnalyzer as o,KnowledgeProducer as s,PatternAnalyzer as c,StructureAnalyzer as l,SymbolAnalyzer as u}from"../../../analyzers/dist/index.js";const d=n(`tools`);function f(n){let f=new s({structure:new l,dependencies:new i,symbols:new u,patterns:new c,entryPoints:new o,diagrams:new a}),p=e(`produce_knowledge`);n.registerTool(`produce_knowledge`,{title:p.title,description:`Run automated codebase analysis and produce synthesis instructions. Executes Tier 1 deterministic analyzers, then returns structured baselines and instructions for you to synthesize knowledge using remember.`,inputSchema:{scope:t.string().optional().describe(`Root path to analyze (defaults to workspace root)`),aspects:t.array(t.enum([`all`,`structure`,`dependencies`,`symbols`,`patterns`,`entry-points`,`diagrams`])).default([`all`]).describe(`Which analysis aspects to run`)},annotations:p.annotations},async({scope:e,aspects:t})=>{try{let n=e??`.`;d.info(`Running knowledge production`,{rootPath:n,aspects:t});let r=await f.runExtraction(n,t);return{content:[{type:`text`,text:f.buildSynthesisInstructions(r,t)+`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{mkdirSync as t,writeFileSync as n}from"node:fs";import{join as r}from"node:path";import{z as i}from"zod";import{createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{DependencyAnalyzer as s,DiagramGenerator as c,EntryPointAnalyzer as l,KnowledgeProducer as u,PatternAnalyzer as d,StructureAnalyzer as f,SymbolAnalyzer as p}from"../../../analyzers/dist/index.js";const m=a(`tools`);function h(a,h){let g=new u({structure:new f,dependencies:new s,symbols:new p,patterns:new d,entryPoints:new l,diagrams:new c}),_=e(`produce_knowledge`);a.registerTool(`produce_knowledge`,{title:_.title,description:`Run automated codebase analysis and produce synthesis instructions. Executes Tier 1 deterministic analyzers, then returns structured baselines and instructions for you to synthesize knowledge using remember.`,inputSchema:{scope:i.string().optional().describe(`Root path to analyze (defaults to workspace root)`),aspects:i.array(i.enum([`all`,`structure`,`dependencies`,`symbols`,`patterns`,`entry-points`,`diagrams`])).default([`all`]).describe(`Which analysis aspects to run`)},annotations:_.annotations},async({scope:e,aspects:i})=>{try{let a=e??`.`;m.info(`Running knowledge production`,{rootPath:a,aspects:i});let s=await g.runExtraction(a,i);try{let e=h?.onboardDir??r(a,`.ai`,`kb`);t(e,{recursive:!0});let i=`<!-- Generated by produce_knowledge at ${new Date().toISOString()} -->\n\n`;for(let[t,a]of Object.entries(s))a&&typeof a==`string`&&n(r(e,`${t}.md`),i+a,`utf-8`);m.info(`Knowledge persisted to .ai/kb/`,{files:Object.keys(s).length})}catch(e){m.warn(`Failed to persist knowledge to .ai/kb/`,{error:o(e)})}return{content:[{type:`text`,text:g.buildSynthesisInstructions(s,i)+`
2
2
 
3
3
  ---
4
- _Next: Review the baselines above and use \`remember\` to store synthesized knowledge entries._`}]}}catch(e){return d.error(`Knowledge production failed`,r(e)),{content:[{type:`text`,text:`Knowledge production failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{f as registerProduceKnowledgeTool};
4
+ _Next: Review the baselines above and use \`remember\` to store synthesized knowledge entries._`}]}}catch(e){return m.error(`Knowledge production failed`,o(e)),{content:[{type:`text`,text:`Knowledge production failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{h as registerProduceKnowledgeTool};
@@ -1,5 +1,6 @@
1
1
  import { CuratedKnowledgeManager } from "../curated-manager.js";
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { KBConfig } from "@kb/core";
3
4
  import { IGraphStore, IKnowledgeStore } from "@kb/store";
4
5
 
5
6
  //#region packages/server/src/tools/status.tool.d.ts
@@ -7,6 +8,6 @@ interface OnboardState {
7
8
  onboardComplete: boolean;
8
9
  onboardTimestamp?: string;
9
10
  }
10
- declare function registerStatusTool(server: McpServer, store: IKnowledgeStore, graphStore?: IGraphStore, curated?: CuratedKnowledgeManager, onboardState?: OnboardState): void;
11
+ declare function registerStatusTool(server: McpServer, store: IKnowledgeStore, graphStore?: IGraphStore, curated?: CuratedKnowledgeManager, onboardState?: OnboardState, config?: KBConfig): void;
11
12
  //#endregion
12
13
  export { OnboardState, registerStatusTool };
@@ -1,2 +1,2 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{StatusOutputSchema as t}from"../output-schemas.js";import{existsSync as n}from"node:fs";import{resolve as r}from"node:path";import{KB_PATHS as i,createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{WasmRuntime as s}from"../../../chunker/dist/index.js";const c=a(`tools`);function l(e,t,n,r=4e3){let i,a=new Promise(e=>{i=setTimeout(()=>{c.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),c.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}function u(a,u,d,f,p){let m=e(`status`);a.registerTool(`status`,{title:m.title,description:`Get the current status and statistics of the knowledge base index.`,outputSchema:t,annotations:m.annotations},async()=>{let e=[];try{let t=await l(u.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),a=t.value;t.timedOut&&e.push(`⚠ Index stats timed out — values may be incomplete`);let o=await l(u.listSourcePaths(),[],`store.listSourcePaths`),c=o.value;o.timedOut&&e.push(`⚠ File listing timed out`);let m=null,h=0,g=[`## Knowledge Base Status`,``,`- **Total Records**: ${a.totalRecords}`,`- **Total Files**: ${a.totalFiles}`,`- **Last Indexed**: ${a.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(a.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...c.slice(0,50).map(e=>`- ${e}`),c.length>50?`\n... and ${c.length-50} more files`:``];if(d)try{let t=await l(d.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(t.timedOut)e.push(`⚠ Graph stats timed out`),g.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let e=t.value;m={nodes:e.nodeCount,edges:e.edgeCount},g.push(``,`### Knowledge Graph`,`- **Nodes**: ${e.nodeCount}`,`- **Edges**: ${e.edgeCount}`,...Object.entries(e.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await l(d.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||g.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&g.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{g.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let _=n(r(process.cwd(),i.aiKb)),v=p?.onboardComplete??_;if(g.push(``,`### Onboard Status`,v?`- ✅ Complete${p?.onboardTimestamp?` (last: ${p.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase'),f)try{let t=await l(f.list(),[],`curated.list`);if(t.timedOut)e.push(`⚠ Curated knowledge listing timed out`),g.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let e=t.value;h=e.length,g.push(``,`### Curated Knowledge`,e.length>0?`- ${e.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{g.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}if(a.lastIndexedAt){let e=new Date(a.lastIndexedAt),t=(Date.now()-e.getTime())/(1e3*60*60);g.push(``,`### Index Freshness`,t>24?`- ⚠ Last indexed ${Math.floor(t)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${t<1?`less than 1h`:`${Math.floor(t)}h`} ago`)}g.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${s.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`),e.length>0&&g.push(``,`### ⚠ Warnings`,...e.map(e=>`- ${e}`));let y=g.join(`
2
- `),b={totalRecords:a.totalRecords,totalFiles:a.totalFiles,lastIndexedAt:a.lastIndexedAt??null,onboarded:v,contentTypes:a.contentTypeBreakdown,wasmAvailable:!!s.get(),graphStats:m,curatedCount:h};return{content:[{type:`text`,text:y+"\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 c.error(`Status failed`,o(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{u as registerStatusTool};
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{StatusOutputSchema as t}from"../output-schemas.js";import{existsSync as n}from"node:fs";import{resolve as r}from"node:path";import{KB_PATHS as i,createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{WasmRuntime as s}from"../../../chunker/dist/index.js";const c=a(`tools`);function l(e,t,n,r=4e3){let i,a=new Promise(e=>{i=setTimeout(()=>{c.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),c.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}function u(a,u,d,f,p,m){let h=e(`status`);a.registerTool(`status`,{title:h.title,description:`Get the current status and statistics of the knowledge base index.`,outputSchema:t,annotations:h.annotations},async()=>{let e=[];try{let t=await l(u.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),a=t.value;t.timedOut&&e.push(`⚠ Index stats timed out — values may be incomplete`);let o=await l(u.listSourcePaths(),[],`store.listSourcePaths`),c=o.value;o.timedOut&&e.push(`⚠ File listing timed out`);let h=null,g=0,_=[`## Knowledge Base Status`,``,`- **Total Records**: ${a.totalRecords}`,`- **Total Files**: ${a.totalFiles}`,`- **Last Indexed**: ${a.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(a.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...c.slice(0,50).map(e=>`- ${e}`),c.length>50?`\n... and ${c.length-50} more files`:``];if(d)try{let t=await l(d.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(t.timedOut)e.push(`⚠ Graph stats timed out`),_.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let e=t.value;h={nodes:e.nodeCount,edges:e.edgeCount},_.push(``,`### Knowledge Graph`,`- **Nodes**: ${e.nodeCount}`,`- **Edges**: ${e.edgeCount}`,...Object.entries(e.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await l(d.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||_.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&_.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{_.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let v=m?.onboardDir??r(process.cwd(),i.aiKb),y=n(v),b=p?.onboardComplete??y;if(_.push(``,`### Onboard Status`,b?`- ✅ Complete${p?.onboardTimestamp?` (last: ${p.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${v}\``),f)try{let t=await l(f.list(),[],`curated.list`);if(t.timedOut)e.push(`⚠ Curated knowledge listing timed out`),_.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let e=t.value;g=e.length,_.push(``,`### Curated Knowledge`,e.length>0?`- ${e.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{_.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}if(a.lastIndexedAt){let e=new Date(a.lastIndexedAt),t=(Date.now()-e.getTime())/(1e3*60*60);_.push(``,`### Index Freshness`,t>24?`- ⚠ Last indexed ${Math.floor(t)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${t<1?`less than 1h`:`${Math.floor(t)}h`} ago`)}_.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${s.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`),e.length>0&&_.push(``,`### ⚠ Warnings`,...e.map(e=>`- ${e}`));let x=_.join(`
2
+ `),S={totalRecords:a.totalRecords,totalFiles:a.totalFiles,lastIndexedAt:a.lastIndexedAt??null,onboarded:b,onboardDir:v,contentTypes:a.contentTypeBreakdown,wasmAvailable:!!s.get(),graphStats:h,curatedCount:g};return{content:[{type:`text`,text:x+"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._"}],structuredContent:S}}catch(e){return c.error(`Status failed`,o(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{u as registerStatusTool};
@@ -1,5 +1,7 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{EnvOutputSchema as t,MeasureOutputSchema as n,TimeOutputSchema as r}from"../output-schemas.js";import{z as i}from"zod";import{createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{changelog as s,encode as c,envInfo as l,httpRequest as u,measure as d,regexTest as f,schemaValidate as p,snippet as m,timeUtils as h,webSearch as g}from"../../../tools/dist/index.js";const _=a(`tools`);function v(t){let n=e(`web_search`);t.registerTool(`web_search`,{title:n.title,description:`PREFERRED web search — search the web via DuckDuckGo (no API key). Returns structured results with title, URL, and snippet.`,inputSchema:{query:i.string().max(2e3).describe(`Search query`),limit:i.number().min(1).max(20).default(5).describe(`Max results to return`),site:i.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`)},annotations:n.annotations},async({query:e,limit:t,site:n})=>{try{let r=await g({query:e,limit:t,site:n}),i=[`## Search: ${r.query}`,``];if(r.results.length===0)i.push(`No results found.`);else for(let e of r.results)i.push(`### [${e.title}](${e.url})`,e.snippet,``);return i.push(`---`,"_Next: Use `web_fetch` to read any of these pages in full._"),{content:[{type:`text`,text:i.join(`
2
- `)}]}}catch(e){return _.error(`Web search failed`,o(e)),{content:[{type:`text`,text:`Web search failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function y(t){let n=e(`http`);t.registerTool(`http`,{title:n.title,description:`Make HTTP requests (GET/POST/PUT/PATCH/DELETE/HEAD) for API testing. Returns status, headers, and formatted body with timing info.`,inputSchema:{url:i.string().url().describe(`Request URL (http/https only)`),method:i.enum([`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`]).default(`GET`).describe(`HTTP method`),headers:i.record(i.string(),i.string()).optional().describe(`Request headers as key-value pairs`),body:i.string().optional().describe(`Request body (for POST/PUT/PATCH)`),timeout:i.number().min(1e3).max(6e4).default(15e3).describe(`Timeout in milliseconds`)},annotations:n.annotations},async({url:e,method:t,headers:n,body:r,timeout:i})=>{try{let a=await u({url:e,method:t,headers:n,body:r,timeout:i}),o=[`## ${t} ${e}`,``,`**Status:** ${a.status} ${a.statusText}`,`**Time:** ${a.durationMs}ms`,`**Size:** ${a.sizeBytes} bytes`,`**Content-Type:** ${a.contentType}`,``,`### Headers`,"```json",JSON.stringify(a.headers),"```",``,`### Body`,a.contentType.includes(`json`)?"```json":"```",a.body,"```"];return a.truncated&&o.push(``,`_Response truncated total size: ${a.sizeBytes} bytes_`),{content:[{type:`text`,text:o.join(`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{EnvOutputSchema as t,MeasureOutputSchema as n,TimeOutputSchema as r}from"../output-schemas.js";import{z as i}from"zod";import{createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{changelog as s,encode as c,envInfo as l,httpRequest as u,measure as d,regexTest as f,schemaValidate as p,snippet as m,timeUtils as h,webSearch as g}from"../../../tools/dist/index.js";const _=a(`tools`);function v(t){let n=e(`web_search`);t.registerTool(`web_search`,{title:n.title,description:`PREFERRED web search — search the web via DuckDuckGo (no API key). Pass one query or multiple for parallel searching. Returns structured results with title, URL, and snippet.`,inputSchema:{queries:i.array(i.string().max(2e3)).min(1).max(5).describe('Search queries (1–5). Single: `["react hooks"]`. Multiple searched in parallel.'),limit:i.number().min(1).max(20).default(5).describe(`Max results per query`),site:i.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`)},annotations:n.annotations},async({queries:e,limit:t,site:n})=>{let r=e,i=async e=>{let r=await g({query:e,limit:t,site:n}),i=[`## Search: ${r.query}`,``];if(r.results.length===0)i.push(`No results found.`);else for(let e of r.results)i.push(`### [${e.title}](${e.url})`,e.snippet,``);return i.join(`
2
+ `)};if(r.length===1)try{return{content:[{type:`text`,text:`${await i(r[0])}\n---\n_Next: Use \`web_fetch\` to read any of these pages in full._`}]}}catch(e){return _.error(`Web search failed`,o(e)),{content:[{type:`text`,text:`Web search failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}let a=await Promise.allSettled(r.map(e=>i(e))),s=[],c=0;for(let e=0;e<a.length;e++){let t=a[e];if(t.status===`fulfilled`)s.push(t.value);else{c++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);_.error(`Web search failed`,{query:r[e],error:n}),s.push(`## Search failed: ${r[e]}\n\n${n}`)}}let l=`_Searched ${a.length-c}/${a.length} queries successfully._`;return s.push(``,`---`,l,"_Next: Use `web_fetch` to read any of these pages in full._"),{content:[{type:`text`,text:s.join(`
3
+
4
+ `)}],...c===a.length?{isError:!0}:{}}})}function y(t){let n=e(`http`);t.registerTool(`http`,{title:n.title,description:`Make HTTP requests (GET/POST/PUT/PATCH/DELETE/HEAD) for API testing. Returns status, headers, and formatted body with timing info.`,inputSchema:{url:i.string().url().describe(`Request URL (http/https only)`),method:i.enum([`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`]).default(`GET`).describe(`HTTP method`),headers:i.record(i.string(),i.string()).optional().describe(`Request headers as key-value pairs`),body:i.string().optional().describe(`Request body (for POST/PUT/PATCH)`),timeout:i.number().min(1e3).max(6e4).default(15e3).describe(`Timeout in milliseconds`)},annotations:n.annotations},async({url:e,method:t,headers:n,body:r,timeout:i})=>{try{let a=await u({url:e,method:t,headers:n,body:r,timeout:i}),o=[`## ${t} ${e}`,``,`**Status:** ${a.status} ${a.statusText}`,`**Time:** ${a.durationMs}ms`,`**Size:** ${a.sizeBytes} bytes`,`**Content-Type:** ${a.contentType}`,``,`### Headers`,"```json",JSON.stringify(a.headers),"```",``,`### Body`,a.contentType.includes(`json`)?"```json":"```",a.body,"```"];return a.truncated&&o.push(``,`_Response truncated — total size: ${a.sizeBytes} bytes_`),{content:[{type:`text`,text:o.join(`
3
5
  `)}]}}catch(e){return _.error(`HTTP request failed`,o(e)),{content:[{type:`text`,text:`HTTP request failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function b(t){let n=e(`regex_test`);t.registerTool(`regex_test`,{title:n.title,description:`Test a regex pattern against sample strings. Supports match, replace, and split modes.`,inputSchema:{pattern:i.string().max(500).describe(`Regex pattern (without delimiters)`),flags:i.string().max(10).regex(/^[gimsuy]*$/).default(``).describe(`Regex flags (g, i, m, s, etc.)`),test_strings:i.array(i.string().max(1e4)).max(50).describe(`Strings to test the pattern against`),mode:i.enum([`match`,`replace`,`split`]).default(`match`).describe(`Test mode`),replacement:i.string().optional().describe(`Replacement string (for replace mode)`)},annotations:n.annotations},async({pattern:e,flags:t,test_strings:n,mode:r,replacement:i})=>{let a=f({pattern:e,flags:t,testStrings:n,mode:r,replacement:i});if(!a.valid)return{content:[{type:`text`,text:`Invalid regex: ${a.error}`}],isError:!0};let o=[`## Regex: \`/${a.pattern}/${a.flags}\``,``,`Mode: ${r}`,``];for(let e of a.results){if(o.push(`**Input:** \`${e.input}\``),o.push(`**Matched:** ${e.matched}`),e.matches)for(let t of e.matches){let e=t.groups.length>0?` groups: [${t.groups.join(`, `)}]`:``;o.push(` - "${t.full}" at index ${t.index}${e}`)}e.replaced!==void 0&&o.push(`**Result:** \`${e.replaced}\``),e.split&&o.push(`**Split:** ${JSON.stringify(e.split)}`),o.push(``)}return{content:[{type:`text`,text:o.join(`
4
6
  `)}]}})}function x(t){let n=e(`encode`);t.registerTool(`encode`,{title:n.title,description:`Encode, decode, or hash text. Supports base64, URL encoding, SHA-256, MD5, JWT decode, hex.`,inputSchema:{operation:i.enum([`base64_encode`,`base64_decode`,`url_encode`,`url_decode`,`sha256`,`md5`,`jwt_decode`,`hex_encode`,`hex_decode`]).describe(`Operation to perform`),input:i.string().max(1e6).describe(`Input text`)},annotations:n.annotations},async({operation:e,input:t})=>{try{let n=c({operation:e,input:t});return{content:[{type:`text`,text:`## ${e}\n\n**Input:** \`${t.length>100?`${t.slice(0,100)}...`:t}\`\n**Output:**\n\`\`\`\n${n.output}\n\`\`\``}]}}catch(e){return _.error(`Encode failed`,o(e)),{content:[{type:`text`,text:`Encode failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function S(t){let r=e(`measure`);t.registerTool(`measure`,{title:r.title,description:`Measure code complexity, line counts, and function counts for a file or directory. Returns per-file metrics sorted by complexity.`,outputSchema:n,inputSchema:{path:i.string().describe(`File or directory path to measure`),extensions:i.array(i.string()).optional().describe(`File extensions to include (default: .ts,.tsx,.js,.jsx)`)},annotations:r.annotations},async({path:e,extensions:t})=>{try{let n=await d({path:e,extensions:t}),r=[`## Code Metrics`,``,`**Files:** ${n.summary.totalFiles}`,`**Total lines:** ${n.summary.totalLines} (${n.summary.totalCodeLines} code)`,`**Functions:** ${n.summary.totalFunctions}`,`**Avg complexity:** ${n.summary.avgComplexity}`,`**Max complexity:** ${n.summary.maxComplexity.value} (${n.summary.maxComplexity.file})`,``,`### Top files by complexity`,``,`| File | Lines | Code | Complexity | Cognitive | Functions | Imports |`,`|------|-------|------|------------|-----------|-----------|---------|`];for(let e of n.files.slice(0,20)){let t=e.cognitiveComplexity===void 0?`—`:String(e.cognitiveComplexity);r.push(`| ${e.path} | ${e.lines.total} | ${e.lines.code} | ${e.complexity} | ${t} | ${e.functions} | ${e.imports} |`)}n.files.length>20&&r.push(``,`_...and ${n.files.length-20} more files_`);let i={summary:{totalFiles:n.summary.totalFiles,totalLines:n.summary.totalLines,totalCodeLines:n.summary.totalCodeLines,totalFunctions:n.summary.totalFunctions,avgComplexity:n.summary.avgComplexity,maxComplexity:{value:n.summary.maxComplexity.value,file:n.summary.maxComplexity.file}},files:n.files.map(e=>({path:e.path,lines:e.lines.total,code:e.lines.code,complexity:e.complexity,functions:e.functions}))};return{content:[{type:`text`,text:r.join(`
5
7
  `)}],structuredContent:i}}catch(e){return _.error(`Measure failed`,o(e)),{content:[{type:`text`,text:`Measure failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function C(t){let n=e(`changelog`);t.registerTool(`changelog`,{title:n.title,description:`Generate a changelog from git history between two refs. Groups by conventional commit type.`,inputSchema:{from:i.string().max(200).describe(`Start ref (tag, SHA, HEAD~N)`),to:i.string().max(200).default(`HEAD`).describe(`End ref (default: HEAD)`),format:i.enum([`grouped`,`chronological`,`per-scope`]).default(`grouped`).describe(`Output format`),include_breaking:i.boolean().default(!0).describe(`Highlight breaking changes`),cwd:i.string().optional().describe(`Repository root or working directory`)},annotations:n.annotations},async({from:e,to:t,format:n,include_breaking:r,cwd:i})=>{try{let a=s({from:e,to:t,format:n,includeBreaking:r,cwd:i}),o=`${a.stats.total} commits (${Object.entries(a.stats.types).map(([e,t])=>`${t} ${e}`).join(`, `)})`;return{content:[{type:`text`,text:`${a.markdown}\n---\n_${o}_`}]}}catch(e){return _.error(`Changelog failed`,o(e)),{content:[{type:`text`,text:`Changelog failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function w(t){let n=e(`schema_validate`);t.registerTool(`schema_validate`,{title:n.title,description:`Validate JSON data against a JSON Schema. Supports type, required, properties, items, enum, pattern, min/max.`,inputSchema:{data:i.string().max(5e5).describe(`JSON data to validate (as string)`),schema:i.string().max(5e5).describe(`JSON Schema to validate against (as string)`)},annotations:n.annotations},async({data:e,schema:t})=>{try{let n=p({data:JSON.parse(e),schema:JSON.parse(t)});if(n.valid)return{content:[{type:`text`,text:`## Validation: PASSED
@@ -36,6 +36,10 @@ interface FindResults {
36
36
  results: FindResult[];
37
37
  strategies: string[];
38
38
  totalFound: number;
39
+ failedStrategies?: Array<{
40
+ strategy: string;
41
+ reason: string;
42
+ }>;
39
43
  }
40
44
  /**
41
45
  * Run federated search across multiple strategies.
@@ -1 +1 @@
1
- import{KB_PATHS as e}from"../../core/dist/index.js";async function t(t,n,r){let{query:i,glob:a,pattern:o,limit:s=10,contentType:c,cwd:l=process.cwd()}=r,u=[],d=[],f=new Set;if(i){u.push(`vector`);let e=await t.embed(i),r={limit:s,contentType:c},a=await n.search(e,r);for(let e of a){let t=`${e.record.sourcePath}:${e.record.startLine}`;f.has(t)||(f.add(t),d.push({path:e.record.sourcePath,source:`vector`,score:e.score,lineRange:{start:e.record.startLine,end:e.record.endLine},preview:e.record.content.slice(0,200)}))}}if(i){u.push(`keyword`);try{let e=await n.ftsSearch(i,{limit:s,contentType:c});for(let t of e){let e=`${t.record.sourcePath}:${t.record.startLine}`;f.has(e)||(f.add(e),d.push({path:t.record.sourcePath,source:`keyword`,score:t.score,lineRange:{start:t.record.startLine,end:t.record.endLine},preview:t.record.content.slice(0,200)}))}}catch{}}if(a){u.push(`glob`);try{let{globSync:t}=await import(`node:fs`),n=t(a,{cwd:l,withFileTypes:!1}),r=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,e.state,e.data]),i=n.filter(e=>!e.replace(/\\/g,`/`).split(`/`).some(e=>r.has(e)));for(let e of i.slice(0,s)){let t=`glob:${e}`;f.has(t)||(f.add(t),d.push({path:e,source:`glob`,score:1}))}}catch{}}if(o){u.push(`pattern`);try{let e=new RegExp(o,`i`),t=await n.ftsSearch(o,{limit:s*2,contentType:c});for(let n of t)if(e.test(n.record.content)){let e=`${n.record.sourcePath}:${n.record.startLine}`;f.has(e)||(f.add(e),d.push({path:n.record.sourcePath,source:`pattern`,score:n.score,lineRange:{start:n.record.startLine,end:n.record.endLine},preview:n.record.content.slice(0,200)}))}}catch{}}return d.sort((e,t)=>t.score-e.score),{results:d.slice(0,s),strategies:u,totalFound:d.length}}export{t as find};
1
+ import{KB_PATHS as e}from"../../core/dist/index.js";async function t(t,n,r){let{query:i,glob:a,pattern:o,limit:s=10,contentType:c,cwd:l=process.cwd()}=r,u=[],d=[],f=new Set,p=[];if(i){u.push(`vector`);let e=await t.embed(i),r={limit:s,contentType:c},a=await n.search(e,r);for(let e of a){let t=`${e.record.sourcePath}:${e.record.startLine}`;f.has(t)||(f.add(t),d.push({path:e.record.sourcePath,source:`vector`,score:e.score,lineRange:{start:e.record.startLine,end:e.record.endLine},preview:e.record.content.slice(0,200)}))}}if(i){u.push(`keyword`);try{let e=await n.ftsSearch(i,{limit:s,contentType:c});for(let t of e){let e=`${t.record.sourcePath}:${t.record.startLine}`;f.has(e)||(f.add(e),d.push({path:t.record.sourcePath,source:`keyword`,score:t.score,lineRange:{start:t.record.startLine,end:t.record.endLine},preview:t.record.content.slice(0,200)}))}}catch(e){p.push({strategy:`keyword`,reason:e instanceof Error?e.message:String(e)})}}if(a){u.push(`glob`);try{let{globSync:t}=await import(`node:fs`),n=t(a,{cwd:l,withFileTypes:!1}),r=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,e.state,e.data]),i=n.filter(e=>!e.replace(/\\/g,`/`).split(`/`).some(e=>r.has(e)));for(let e of i.slice(0,s)){let t=`glob:${e}`;f.has(t)||(f.add(t),d.push({path:e,source:`glob`,score:1}))}}catch(e){p.push({strategy:`glob`,reason:e instanceof Error?e.message:String(e)})}}if(o){u.push(`pattern`);try{let e=new RegExp(o,`i`),t=await n.ftsSearch(o,{limit:s*2,contentType:c});for(let n of t)if(e.test(n.record.content)){let e=`${n.record.sourcePath}:${n.record.startLine}`;f.has(e)||(f.add(e),d.push({path:n.record.sourcePath,source:`pattern`,score:n.score,lineRange:{start:n.record.startLine,end:n.record.endLine},preview:n.record.content.slice(0,200)}))}}catch(e){p.push({strategy:`pattern`,reason:e instanceof Error?e.message:String(e)})}}return d.sort((e,t)=>t.score-e.score),{results:d.slice(0,s),strategies:u,totalFound:d.length,...p.length>0&&{failedStrategies:p}}}export{t as find};
@@ -1,2 +1,18 @@
1
- import{extractConfigValues as e}from"./config-extractor.js";import{buildDiagrams as t}from"./diagram-builder.js";import{buildCodeMap as n,buildSynthesisGuide as r}from"./synthesis-engine.js";import{DependencyAnalyzer as i,DiagramGenerator as a,EntryPointAnalyzer as o,PatternAnalyzer as s,StructureAnalyzer as c,SymbolAnalyzer as l,extractRegexCallGraph as u,extractTsCallGraph as d}from"../../analyzers/dist/index.js";import{basename as f,join as p,resolve as m}from"node:path";import{existsSync as h,mkdirSync as g,readdirSync as _,rmSync as v,writeFileSync as y}from"node:fs";import{KB_PATHS as b}from"../../core/dist/index.js";const x={structure:`Project Structure`,dependencies:`Dependencies`,"entry-points":`Entry Points`,symbols:`Symbols`,patterns:`Patterns`,diagram:`C4 Container Diagram`,"code-map":`Code Map (Module Graph)`,"config-values":`Configuration Values`,"synthesis-guide":`Synthesis Guide`};async function S(S){let C=Date.now(),w=m(S.path),T=f(w),E=S.mode??`memory`,D=S.outDir??p(w,b.aiKb),O=new c,k=new i,A=new l,j=new s,M=new o,N=new a,P=[{name:`structure`,fn:()=>O.analyze(w,{format:`markdown`,maxDepth:3,sourceOnly:!0})},{name:`dependencies`,fn:()=>k.analyze(w,{format:`markdown`})},{name:`entry-points`,fn:()=>M.analyze(w)},{name:`symbols`,fn:()=>A.analyze(w,{format:`markdown`})},{name:`patterns`,fn:()=>j.analyze(w)},{name:`diagram`,fn:()=>N.analyze(w,{diagramType:`architecture`})}],F=await Promise.allSettled(P.map(async e=>{let t=Date.now(),n=await e.fn();return{name:e.name,result:n,durationMs:Date.now()-t}})),I=[],L=new Map,R=new Map;for(let e of F)if(e.status===`fulfilled`){let{name:t,result:n,durationMs:r}=e.value,i=n;I.push({name:t,status:`success`,output:i.output,durationMs:r}),L.set(t,i.output),R.set(t,i.data)}else{let t=e.reason,n=P[F.indexOf(e)].name;I.push({name:n,status:`failed`,output:``,durationMs:0,error:t.message})}let z=Date.now(),B=null;try{let e=await d(w);if((!e||e.edges.length===0)&&(e=await u(w)),e&&e.edges.length>0){B=new Map;for(let t of e.edges){let e=B.get(t.from);e||(e=new Map,B.set(t.from,e));let n=e.get(t.to);if(n)for(let e of t.symbols)n.includes(e)||n.push(e);else e.set(t.to,[...t.symbols])}}}catch{}let V=Date.now()-z,H=Date.now(),U=n(R,T,B),W=Date.now()-H+V;if(I.push({name:`code-map`,status:`success`,output:U,durationMs:W}),L.set(`code-map`,U),B&&B.size>0){let e=t(B,R,T),n=I.find(e=>e.name===`diagram`);n&&(n.output=e,L.set(`diagram`,e))}let G=Date.now(),K=await e(w,T),q=Date.now()-G;I.push({name:`config-values`,status:`success`,output:K,durationMs:q}),L.set(`config-values`,K);let J=r(I,E,T,R);if(I.push({name:`synthesis-guide`,status:`success`,output:J,durationMs:0}),L.set(`synthesis-guide`,J),E===`generate`){if(h(D))for(let e of _(D))(e.endsWith(`.md`)||e.endsWith(`.json`))&&v(p(D,e),{force:!0});g(D,{recursive:!0});let e=new Date().toISOString();for(let[t,n]of L){let r=p(D,`${t}.md`),i=n.replaceAll(w,T);y(r,`<!-- Generated: ${e} -->\n<!-- Project: ${T} -->\n<!-- Source: ${w} -->\n\n`+i,`utf-8`)}let t=[`<!-- Generated: ${e} -->`,`<!-- Project: ${T} -->`,`<!-- Source: ${w} -->`,``,`# ${T} — Codebase Knowledge`,``,`## Contents`,``];for(let e of I){let n=`${e.name}.md`,r=x[e.name]??e.name,i=e.status===`success`?`✓`:`✗`,a=e.durationMs>0?` (${e.durationMs}ms)`:``;t.push(`- ${i} [${r}](./${n})${a}`)}t.push(``),y(p(D,`README.md`),t.join(`
2
- `),`utf-8`)}return{path:w,mode:E,steps:I,outDir:E===`generate`?D:void 0,totalDurationMs:Date.now()-C}}export{S as onboard};
1
+ import{extractConfigValues as e}from"./config-extractor.js";import{buildDiagrams as t}from"./diagram-builder.js";import{buildCodeMap as n,buildSynthesisGuide as r}from"./synthesis-engine.js";import{DependencyAnalyzer as i,DiagramGenerator as a,EntryPointAnalyzer as o,PatternAnalyzer as s,StructureAnalyzer as c,SymbolAnalyzer as l,extractRegexCallGraph as u,extractTsCallGraph as d}from"../../analyzers/dist/index.js";import{basename as f,join as p,resolve as m}from"node:path";import{existsSync as h,mkdirSync as g,readdirSync as _,rmSync as v,writeFileSync as y}from"node:fs";import{KB_PATHS as b}from"../../core/dist/index.js";const x={structure:`Project Structure`,dependencies:`Dependencies`,"entry-points":`Entry Points`,symbols:`Symbols`,patterns:`Patterns`,diagram:`C4 Container Diagram`,"code-map":`Code Map (Module Graph)`,"config-values":`Configuration Values`,"synthesis-guide":`Synthesis Guide`,"api-surface":`API Surface`,"type-inventory":`Type Inventory`};function S(e){let t=e.get(`symbols`);if(!t?.symbols?.length)return`# API Surface
2
+
3
+ *No symbol data available.*
4
+ `;let n=t.symbols.filter(e=>e.exported);if(n.length===0)return`# API Surface
5
+
6
+ *No exported symbols found.*
7
+ `;let r=new Map;for(let e of n){let t=r.get(e.filePath)??[];t.push(e),r.set(e.filePath,t)}let i=[`# API Surface
8
+ `];for(let[e,t]of[...r.entries()].sort(([e],[t])=>e.localeCompare(t))){i.push(`## ${e}\n`);for(let e of t){e.decorators?.length&&i.push(e.decorators.join(` `));let t=e.signature??``,n=e.returnType?`: ${e.returnType}`:``;if(e.kind===`function`||e.kind===`method`)i.push(`### \`${e.name}${t}${n}\``);else if(e.kind===`class`)i.push(`### class \`${e.name}\`${t?` ${t}`:``}`);else if(e.kind===`interface`||e.kind===`type`){let t=e.typeBody?` ${e.typeBody}`:``;i.push(`### ${e.kind} \`${e.name}\`${t}`)}else i.push(`### ${e.kind} \`${e.name}\`${t?`: ${t}`:``}`);e.jsdoc&&i.push(`> ${e.jsdoc}`),i.push(``)}}let a=i.join(`
9
+ `);return a.length>1e5?`${a.slice(0,1e5)}\n\n*[truncated]*`:a}function C(e){let t=e.get(`symbols`);if(!t?.symbols?.length)return`# Type Inventory
10
+
11
+ *No symbol data available.*
12
+ `;let n=t.symbols.filter(e=>e.exported&&(e.kind===`interface`||e.kind===`type`||e.kind===`enum`));if(n.length===0)return`# Type Inventory
13
+
14
+ *No exported types/interfaces found.*
15
+ `;let r=new Map;for(let e of n){let t=r.get(e.filePath)??[];t.push(e),r.set(e.filePath,t)}let i=[`# Type Inventory
16
+ `];for(let[e,t]of[...r.entries()].sort(([e],[t])=>e.localeCompare(t))){i.push(`## ${e}\n`);for(let e of t){let t=e.typeBody??`*body not available*`;e.jsdoc&&i.push(`> ${e.jsdoc}`),i.push(`### ${e.kind} \`${e.name}\``),i.push("```"),i.push(t),i.push("```\n")}}let a=i.join(`
17
+ `);return a.length>1e5?`${a.slice(0,1e5)}\n\n*[truncated]*`:a}async function w(w){let T=Date.now(),E=m(w.path),D=f(E),O=w.mode??`generate`,k=w.outDir??p(E,b.aiKb),A=new c,j=new i,M=new l,N=new s,P=new o,F=new a,I=[{name:`structure`,fn:()=>A.analyze(E,{format:`markdown`,maxDepth:3,sourceOnly:!0})},{name:`dependencies`,fn:()=>j.analyze(E,{format:`markdown`})},{name:`entry-points`,fn:()=>P.analyze(E)},{name:`symbols`,fn:()=>M.analyze(E,{format:`markdown`})},{name:`patterns`,fn:()=>N.analyze(E)},{name:`diagram`,fn:()=>F.analyze(E,{diagramType:`architecture`})}],L=await Promise.allSettled(I.map(async e=>{let t=Date.now(),n=await e.fn();return{name:e.name,result:n,durationMs:Date.now()-t}})),R=[],z=new Map,B=new Map;for(let e of L)if(e.status===`fulfilled`){let{name:t,result:n,durationMs:r}=e.value,i=n;R.push({name:t,status:`success`,output:i.output,durationMs:r}),z.set(t,i.output),B.set(t,i.data)}else{let t=e.reason,n=I[L.indexOf(e)].name;R.push({name:n,status:`failed`,output:``,durationMs:0,error:t.message})}let V=Date.now(),H=null;try{let e=await d(E);if((!e||e.edges.length===0)&&(e=await u(E)),e&&e.edges.length>0){H=new Map;for(let t of e.edges){let e=H.get(t.from);e||(e=new Map,H.set(t.from,e));let n=e.get(t.to);if(n)for(let e of t.symbols)n.includes(e)||n.push(e);else e.set(t.to,[...t.symbols])}}}catch{}let U=Date.now()-V,W=Date.now(),G=n(B,D,H),K=Date.now()-W+U;if(R.push({name:`code-map`,status:`success`,output:G,durationMs:K}),z.set(`code-map`,G),H&&H.size>0){let e=t(H,B,D),n=R.find(e=>e.name===`diagram`);n&&(n.output=e,z.set(`diagram`,e))}let q=Date.now(),J=await e(E,D),Y=Date.now()-q;R.push({name:`config-values`,status:`success`,output:J,durationMs:Y}),z.set(`config-values`,J);let X=r(R,O,D,B);R.push({name:`synthesis-guide`,status:`success`,output:X,durationMs:0}),z.set(`synthesis-guide`,X);let Z=S(B);R.push({name:`api-surface`,status:`success`,output:Z,durationMs:0}),z.set(`api-surface`,Z);let Q=C(B);if(R.push({name:`type-inventory`,status:`success`,output:Q,durationMs:0}),z.set(`type-inventory`,Q),O===`generate`){if(h(k))for(let e of _(k))(e.endsWith(`.md`)||e.endsWith(`.json`))&&v(p(k,e),{force:!0});g(k,{recursive:!0});let e=new Date().toISOString();for(let[t,n]of z){let r=p(k,`${t}.md`),i=n.replaceAll(E,D);y(r,`<!-- Generated: ${e} -->\n<!-- Project: ${D} -->\n<!-- Source: ${E} -->\n\n`+i,`utf-8`)}let t=[`<!-- Generated: ${e} -->`,`<!-- Project: ${D} -->`,`<!-- Source: ${E} -->`,``,`# ${D} — Codebase Knowledge`,``,`## Contents`,``];for(let e of R){let n=`${e.name}.md`,r=x[e.name]??e.name,i=e.status===`success`?`✓`:`✗`,a=e.durationMs>0?` (${e.durationMs}ms)`:``;t.push(`- ${i} [${r}](./${n})${a}`)}t.push(``),y(p(k,`README.md`),t.join(`
18
+ `),`utf-8`)}return{path:E,mode:O,steps:R,outDir:O===`generate`?k:void 0,totalDurationMs:Date.now()-T}}export{w as onboard};