@vpxa/kb 0.1.31 → 0.1.33

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 (62) hide show
  1. package/package.json +1 -1
  2. package/packages/analyzers/dist/diagram-generator.js +2 -2
  3. package/packages/analyzers/dist/pattern-analyzer.js +1 -1
  4. package/packages/analyzers/dist/regex-call-graph.js +1 -1
  5. package/packages/cli/dist/commands/init/constants.d.ts +2 -0
  6. package/packages/cli/dist/commands/init/constants.js +1 -1
  7. package/packages/cli/dist/commands/init/index.d.ts +9 -1
  8. package/packages/cli/dist/commands/init/index.js +1 -1
  9. package/packages/cli/dist/commands/upgrade.js +1 -1
  10. package/packages/present/dist/index.html +321 -22
  11. package/packages/server/dist/output-schemas.d.ts +1 -0
  12. package/packages/server/dist/output-schemas.js +1 -1
  13. package/packages/server/dist/server.js +2 -2
  14. package/packages/server/dist/tools/context.tools.d.ts +2 -2
  15. package/packages/server/dist/tools/context.tools.js +9 -9
  16. package/packages/server/dist/tools/onboard.tool.js +2 -2
  17. package/packages/server/dist/tools/present/browser.d.ts +4 -0
  18. package/packages/server/dist/tools/present/browser.js +93 -0
  19. package/packages/server/dist/tools/present/helpers.d.ts +13 -0
  20. package/packages/server/dist/tools/present/helpers.js +1 -0
  21. package/packages/server/dist/tools/present/html.d.ts +18 -0
  22. package/packages/server/dist/tools/present/html.js +5 -0
  23. package/packages/server/dist/tools/present/index.d.ts +2 -0
  24. package/packages/server/dist/tools/present/index.js +1 -0
  25. package/packages/server/dist/tools/present/markdown.d.ts +17 -0
  26. package/packages/server/dist/tools/present/markdown.js +8 -0
  27. package/packages/server/dist/tools/present/templates.d.ts +14 -0
  28. package/packages/server/dist/tools/present/templates.js +472 -0
  29. package/packages/server/dist/tools/present/tool.d.ts +23 -0
  30. package/packages/server/dist/tools/present/tool.js +19 -0
  31. package/packages/server/dist/tools/present.tool.d.ts +1 -6
  32. package/packages/server/dist/tools/present.tool.js +1 -114
  33. package/packages/server/dist/tools/status.tool.d.ts +2 -1
  34. package/packages/server/dist/tools/status.tool.js +3 -3
  35. package/packages/server/dist/version-check.d.ts +12 -1
  36. package/packages/server/dist/version-check.js +1 -1
  37. package/packages/tools/dist/compact.js +1 -1
  38. package/packages/tools/dist/file-cache.js +3 -3
  39. package/packages/tools/dist/file-summary.js +1 -1
  40. package/packages/tools/dist/guide.js +1 -1
  41. package/packages/tools/dist/onboard.d.ts +7 -0
  42. package/packages/tools/dist/onboard.js +4 -4
  43. package/scaffold/adapters/copilot.mjs +4 -3
  44. package/scaffold/definitions/tools.mjs +3 -2
  45. package/scaffold/general/agents/Architect-Reviewer-Alpha.agent.md +1 -1
  46. package/scaffold/general/agents/Architect-Reviewer-Beta.agent.md +1 -1
  47. package/scaffold/general/agents/Code-Reviewer-Alpha.agent.md +1 -1
  48. package/scaffold/general/agents/Code-Reviewer-Beta.agent.md +1 -1
  49. package/scaffold/general/agents/Debugger.agent.md +1 -1
  50. package/scaffold/general/agents/Documenter.agent.md +1 -1
  51. package/scaffold/general/agents/Explorer.agent.md +1 -1
  52. package/scaffold/general/agents/Frontend.agent.md +1 -1
  53. package/scaffold/general/agents/Implementer.agent.md +1 -1
  54. package/scaffold/general/agents/Orchestrator.agent.md +1 -1
  55. package/scaffold/general/agents/Planner.agent.md +1 -1
  56. package/scaffold/general/agents/Refactor.agent.md +1 -1
  57. package/scaffold/general/agents/Researcher-Alpha.agent.md +1 -1
  58. package/scaffold/general/agents/Researcher-Beta.agent.md +1 -1
  59. package/scaffold/general/agents/Researcher-Delta.agent.md +1 -1
  60. package/scaffold/general/agents/Researcher-Gamma.agent.md +1 -1
  61. package/scaffold/general/agents/Security.agent.md +1 -1
  62. package/skills/present/SKILL.md +283 -12
@@ -24,6 +24,7 @@ declare const StatusOutputSchema: z.ZodObject<{
24
24
  curatedCount: z.ZodNumber;
25
25
  serverVersion: z.ZodString;
26
26
  scaffoldVersion: z.ZodNullable<z.ZodString>;
27
+ workspaceScaffoldVersion: z.ZodNullable<z.ZodString>;
27
28
  upgradeAvailable: z.ZodBoolean;
28
29
  }, z.core.$strip>;
29
30
  declare const ListOutputSchema: z.ZodObject<{
@@ -1 +1 @@
1
- import{z as e}from"zod";const t=e.object({totalRecords:e.number(),totalFiles:e.number(),lastIndexedAt:e.string().nullable(),onboarded:e.boolean(),onboardDir:e.string(),contentTypes:e.record(e.string(),e.number()),wasmAvailable:e.boolean(),graphStats:e.object({nodes:e.number(),edges:e.number()}).nullable(),curatedCount:e.number(),serverVersion:e.string(),scaffoldVersion:e.string().nullable(),upgradeAvailable:e.boolean()}),n=e.object({entries:e.array(e.object({path:e.string(),title:e.string(),category:e.string(),tags:e.array(e.string()),version:e.number(),preview:e.string()})),totalCount:e.number()}),r=e.object({ok:e.boolean(),checks:e.array(e.object({name:e.string(),ok:e.boolean(),message:e.string().optional()}))}),i=e.object({summary:e.object({totalFiles:e.number(),totalLines:e.number(),totalCodeLines:e.number(),totalFunctions:e.number(),avgComplexity:e.number(),maxComplexity:e.object({value:e.number(),file:e.string()})}),files:e.array(e.object({path:e.string(),lines:e.number(),code:e.number(),complexity:e.number(),functions:e.number()}))}),a=e.object({platform:e.string(),arch:e.string(),nodeVersion:e.string(),cwd:e.string(),cpus:e.number(),memoryFreeGb:e.number(),memoryTotalGb:e.number()}),o=e.object({iso:e.string(),unix:e.number(),timezone:e.string(),formatted:e.string()}),s=e.object({passed:e.boolean(),errorCount:e.number(),warningCount:e.number(),topErrors:e.array(e.string())}),c=e.object({passed:e.boolean(),tsc:s,biome:s}),l=e.object({name:e.string(),definedIn:e.object({path:e.string(),line:e.number(),kind:e.string(),signature:e.string().optional()}).nullable(),importedBy:e.array(e.object({path:e.string(),line:e.number(),importStatement:e.string()})),referencedIn:e.array(e.object({path:e.string(),line:e.number(),context:e.string(),scope:e.string().optional()})),graphContext:e.object({definingModule:e.string().optional(),importedByModules:e.array(e.string()),siblingSymbols:e.array(e.string())}).nullable()}),u=e.object({sourcePath:e.string(),contentType:e.string(),score:e.number(),headingPath:e.string().optional(),startLine:e.number().optional(),endLine:e.number().optional(),origin:e.string().optional(),category:e.string().optional(),tags:e.array(e.string()).optional()}),d=e.object({results:e.array(u),totalResults:e.number(),searchMode:e.string(),query:e.string()}),f=e.object({path:e.string(),line:e.number().optional(),matchType:e.string(),preview:e.string()}),p=e.object({matches:e.array(f),totalMatches:e.number(),pattern:e.string(),truncated:e.boolean()}),m=e.object({path:e.string(),relevance:e.number(),estimatedTokens:e.number(),focusLines:e.array(e.string()).optional()}),h=e.object({files:e.array(m),totalFiles:e.number(),totalEstimatedTokens:e.number(),task:e.string()}),g=e.object({path:e.string(),impact:e.string(),reason:e.string()}),_=e.object({changedFiles:e.array(e.string()),affectedFiles:e.array(g),totalAffected:e.number(),riskLevel:e.string()}),v=e.object({name:e.string(),passed:e.boolean(),message:e.string().optional(),severity:e.string().optional()}),y=e.object({passed:e.boolean(),score:e.number(),checks:e.array(v),summary:e.string()}),b=e.object({id:e.string(),name:e.string(),type:e.string(),sourcePath:e.string().optional()}),x=e.object({fromId:e.string(),toId:e.string(),type:e.string()}),S=e.object({nodes:e.array(b),edges:e.array(x),totalNodes:e.number(),totalEdges:e.number(),query:e.string()}),C=e.object({symbols:e.array(e.object({name:e.string(),path:e.string(),line:e.number().optional(),kind:e.string()})),totalDead:e.number()}),w=e.object({files:e.number(),packages:e.number(),languages:e.record(e.string(),e.number()),tree:e.string()}),T=e.object({path:e.string(),language:e.string(),lines:e.number(),imports:e.number(),exports:e.number(),functions:e.number(),classes:e.number()}),E=e.object({gitRoot:e.string(),branch:e.string(),commitCount:e.number(),hasUncommitted:e.boolean(),recentCommits:e.array(e.object({hash:e.string(),message:e.string(),author:e.string()}))}),D=e.object({originalChars:e.number(),compressedChars:e.number(),ratio:e.number(),segmentsKept:e.number(),segmentsTotal:e.number()});export{w as AnalyzeStructureOutputSchema,y as AuditOutputSchema,_ as BlastRadiusOutputSchema,c as CheckOutputSchema,D as CompactOutputSchema,C as DeadSymbolsOutputSchema,a as EnvOutputSchema,T as FileSummaryOutputSchema,p as FindOutputSchema,E as GitContextOutputSchema,S as GraphOutputSchema,r as HealthOutputSchema,n as ListOutputSchema,i as MeasureOutputSchema,h as ScopeMapOutputSchema,d as SearchOutputSchema,t as StatusOutputSchema,l as SymbolOutputSchema,o as TimeOutputSchema};
1
+ import{z as e}from"zod";const t=e.object({totalRecords:e.number(),totalFiles:e.number(),lastIndexedAt:e.string().nullable(),onboarded:e.boolean(),onboardDir:e.string(),contentTypes:e.record(e.string(),e.number()),wasmAvailable:e.boolean(),graphStats:e.object({nodes:e.number(),edges:e.number()}).nullable(),curatedCount:e.number(),serverVersion:e.string(),scaffoldVersion:e.string().nullable(),workspaceScaffoldVersion:e.string().nullable(),upgradeAvailable:e.boolean()}),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{installStructuredContentGuard as l}from"./structured-content-guard.js";import{getToolMeta as u}from"./tool-metadata.js";import{installToolPrefix as d}from"./tool-prefix.js";import{registerAnalyzeDependenciesTool as f,registerAnalyzeDiagramTool as p,registerAnalyzeEntryPointsTool as m,registerAnalyzePatternsTool as h,registerAnalyzeStructureTool as ee,registerAnalyzeSymbolsTool as g,registerBlastRadiusTool as _}from"./tools/analyze.tools.js";import{registerAuditTool as v}from"./tools/audit.tool.js";import{registerBrainstormTool as y}from"./tools/brainstorm.tool.js";import{initBridgeComponents as b,registerErPullTool as x,registerErPushTool as te,registerErSyncStatusTool as S}from"./tools/bridge.tools.js";import{registerCompactTool as C,registerDeadSymbolsTool as ne,registerFileSummaryTool as re,registerFindTool as ie,registerScopeMapTool as ae,registerSymbolTool as oe,registerTraceTool as se}from"./tools/context.tools.js";import{registerErEvolveReviewTool as ce}from"./tools/evolution.tools.js";import{registerBatchTool as le,registerCheckTool as ue,registerDelegateTool as w,registerEvalTool as T,registerParseOutputTool as E,registerTestRunTool as D}from"./tools/execution.tools.js";import{registerDigestTool as de,registerEvidenceMapTool as O,registerForgeClassifyTool as k,registerForgeGroundTool as fe,registerStratumCardTool as pe}from"./tools/forge.tools.js";import{registerForgetTool as me}from"./tools/forget.tool.js";import{registerGraphTool as he}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 ge}from"./tools/list.tool.js";import{registerLookupTool as _e}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 ve}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 ye}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 be}from"./tools/read.tool.js";import{registerReindexTool as xe}from"./tools/reindex.tool.js";import{registerRememberTool as Se}from"./tools/remember.tool.js";import{registerReplayTool as Ce}from"./tools/replay.tool.js";import{registerRestoreTool as we}from"./tools/restore.tool.js";import{registerSearchTool as Te}from"./tools/search.tool.js";import{getCurrentVersion as Ee}from"./version-check.js";import{registerEarlyStatusTool as De,registerStatusTool as Oe}from"./tools/status.tool.js";import{registerUpdateTool as ke}from"./tools/update.tool.js";import{registerChangelogTool as Ae,registerEncodeTool as je,registerEnvTool as Me,registerHttpTool as Ne,registerMeasureTool as Pe,registerRegexTestTool as Fe,registerSchemaValidateTool as Ie,registerSnippetTool as Le,registerTimeTool as Re,registerWebSearchTool as ze}from"./tools/utility.tools.js";import{existsSync as Be,statSync as Ve}from"node:fs";import{resolve as He}from"node:path";import{KB_PATHS as Ue,createLogger as We,serializeError as q}from"../../core/dist/index.js";import{initializeWasm as Ge}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ke}from"../../embeddings/dist/index.js";import{EvolutionCollector as qe,PolicyStore as Je}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Ye,IncrementalIndexer as Xe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ze,createStore as Qe}from"../../store/dist/index.js";import{FileCache as $e}from"../../tools/dist/index.js";import{McpServer as J}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=We(`server`);async function X(t){Y.info(`Initializing knowledge base components`);let[n,r,i,a]=await Promise.all([(async()=>{let e=new Ke({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 Qe({backend:t.store.backend,path:t.store.path});return await e.initialize(),Y.info(`Store initialized`),e})(),(async()=>{let e=new Ze({path:t.store.path});return await e.initialize(),Y.info(`Graph store initialized`),e})(),(async()=>{let e=await Ge();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 Xe(n,r),s=new Ye(t.store.path);s.load(),o.setHashCache(s);let c=t.curated.path,l=new e(c,r,n);o.setGraphStore(i);let u=b(t.er),d=u?new Je(t.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new qe:void 0,p=He(t.sources[0]?.path??process.cwd(),Ue.aiKb),m=Be(p),h;if(m)try{h=Ve(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 $e,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:m,onboardTimestamp:h}}function et(e,n){let a=new J({name:n.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}});return r(a),d(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),l(e),Te(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),_e(e,t.store),Oe(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n),xe(e,t.indexer,n,t.curated,t.store,i),Se(e,t.curated,t.policyStore,t.evolutionCollector,i),ke(e,t.curated,i),me(e,t.curated,i),be(e,t.curated),ge(e,t.curated),ee(e,t.store,t.embedder),f(e,t.store,t.embedder),g(e,t.store,t.embedder),h(e,t.store,t.embedder),m(e,t.store,t.embedder),p(e,t.store,t.embedder),_(e,t.store,t.embedder,t.graphStore),K(e,n),ve(e,t.store,t.embedder,n),he(e,t.graphStore),v(e,t.store,t.embedder),C(e,t.embedder,t.fileCache),ae(e,t.embedder,t.store),ie(e,t.embedder,t.store),E(e),W(e),ue(e),le(e,t.embedder,t.store),oe(e,t.embedder,t.store,t.graphStore),T(e),D(e),U(e),R(e),L(e),z(e),F(e),we(e),re(e,t.fileCache),B(e),I(e),se(e,t.embedder,t.store),M(e),N(e),ne(e,t.embedder,t.store),w(e,o),j(e),V(e),H(e),P(e),A(e),O(e),de(e,t.embedder),k(e),pe(e,t.embedder,t.fileCache),fe(e,t.embedder,t.store),G(e,r),r&&y(e,r),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(e),t.bridge&&(te(e,t.bridge,t.evolutionCollector),x(e,t.bridge),S(e,t.bridge)),t.policyStore&&ye(e,t.policyStore),t.evolutionCollector&&ce(e,t.evolutionCollector),s(e,t.store,t.curated),Ce(e)}async function tt(e){let t=await X(e),n=et(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`,q(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`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(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 nt=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(`.`)),rt=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.status.test_run.time.watch.web_fetch.web_search.workset`.split(`.`));function it(e){ue(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),we(e),V(e),H(e),j(e),M(e),N(e),P(e),A(e),O(e),k(e),G(e),y(e,n),K(e),Ce(e),De(e),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(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 at(e){let n=new J({name:e.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}}),a=`initializing`,s=``,l=!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{installStructuredContentGuard as l}from"./structured-content-guard.js";import{getToolMeta as u}from"./tool-metadata.js";import{installToolPrefix as d}from"./tool-prefix.js";import{registerAnalyzeDependenciesTool as f,registerAnalyzeDiagramTool as p,registerAnalyzeEntryPointsTool as m,registerAnalyzePatternsTool as h,registerAnalyzeStructureTool as g,registerAnalyzeSymbolsTool as _,registerBlastRadiusTool as v}from"./tools/analyze.tools.js";import{registerAuditTool as y}from"./tools/audit.tool.js";import{registerBrainstormTool as b}from"./tools/brainstorm.tool.js";import{initBridgeComponents as x,registerErPullTool as S,registerErPushTool as ee,registerErSyncStatusTool as C}from"./tools/bridge.tools.js";import{registerCompactTool as w,registerDeadSymbolsTool as te,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 T,registerDelegateTool as le,registerEvalTool as E,registerParseOutputTool as D,registerTestRunTool as O}from"./tools/execution.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as k,registerForgeClassifyTool as A,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 j,registerHealthTool as M,registerProcessTool as N,registerWatchTool as P,registerWebFetchTool as F}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 I,registerDataTransformTool as L,registerDiffParseTool as R,registerGitContextTool as z,registerRenameTool as B}from"./tools/manipulation.tools.js";import{registerOnboardTool as _e}from"./tools/onboard.tool.js";import{registerCheckpointTool as V,registerLaneTool as H,registerQueueTool as U,registerStashTool as W,registerWorksetTool as G}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as ve}from"./tools/policy.tools.js";import{registerPresentTool as K}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as ye}from"./tools/produce.tool.js";import{registerReadTool as be}from"./tools/read.tool.js";import{registerReindexTool as xe}from"./tools/reindex.tool.js";import{registerRememberTool as Se}from"./tools/remember.tool.js";import{registerReplayTool as Ce}from"./tools/replay.tool.js";import{registerRestoreTool as we}from"./tools/restore.tool.js";import{registerSearchTool as Te}from"./tools/search.tool.js";import{getCurrentVersion as Ee}from"./version-check.js";import{registerEarlyStatusTool as De,registerStatusTool as Oe}from"./tools/status.tool.js";import{registerUpdateTool as ke}from"./tools/update.tool.js";import{registerChangelogTool as Ae,registerEncodeTool as je,registerEnvTool as Me,registerHttpTool as Ne,registerMeasureTool as Pe,registerRegexTestTool as Fe,registerSchemaValidateTool as Ie,registerSnippetTool as Le,registerTimeTool as Re,registerWebSearchTool as ze}from"./tools/utility.tools.js";import{existsSync as Be,statSync as Ve}from"node:fs";import{resolve as He}from"node:path";import{KB_PATHS as Ue,createLogger as We,serializeError as q}from"../../core/dist/index.js";import{initializeWasm as Ge}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ke}from"../../embeddings/dist/index.js";import{EvolutionCollector as qe,PolicyStore as Je}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Ye,IncrementalIndexer as Xe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ze,createStore as Qe}from"../../store/dist/index.js";import{FileCache as $e}from"../../tools/dist/index.js";import{McpServer as J}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=We(`server`);async function X(t){Y.info(`Initializing knowledge base components`);let[n,r,i,a]=await Promise.all([(async()=>{let e=new Ke({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 Qe({backend:t.store.backend,path:t.store.path});return await e.initialize(),Y.info(`Store initialized`),e})(),(async()=>{let e=new Ze({path:t.store.path});return await e.initialize(),Y.info(`Graph store initialized`),e})(),(async()=>{let e=await Ge();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 Xe(n,r),s=new Ye(t.store.path);s.load(),o.setHashCache(s);let c=t.curated.path,l=new e(c,r,n);o.setGraphStore(i);let u=x(t.er),d=u?new Je(t.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new qe:void 0,p=He(t.sources[0]?.path??process.cwd(),Ue.aiKb),m=Be(p),h=t.onboardDir?Be(t.onboardDir):!1,g=m||h,_,v=m?p:t.onboardDir;if(g&&v)try{_=Ve(v).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:n,store:r,indexer:o,curated:l,graphStore:i,fileCache:new $e,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function et(e,n){let a=new J({name:n.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}});return r(a),d(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),l(e),Te(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),ge(e,t.store),Oe(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n),xe(e,t.indexer,n,t.curated,t.store,i),Se(e,t.curated,t.policyStore,t.evolutionCollector,i),ke(e,t.curated,i),pe(e,t.curated,i),be(e,t.curated),he(e,t.curated),g(e,t.store,t.embedder),f(e,t.store,t.embedder),_(e,t.store,t.embedder),h(e,t.store,t.embedder),m(e,t.store,t.embedder),p(e,t.store,t.embedder),v(e,t.store,t.embedder,t.graphStore),ye(e,n),_e(e,t.store,t.embedder,n),me(e,t.graphStore),y(e,t.store,t.embedder);let c=n.sources[0]?.path??process.cwd();w(e,t.embedder,t.fileCache,c),ie(e,t.embedder,t.store),re(e,t.embedder,t.store),D(e),G(e),T(e),ce(e,t.embedder,t.store),ae(e,t.embedder,t.store,t.graphStore),E(e),O(e),W(e),z(e),R(e),B(e),I(e),we(e),ne(e,t.fileCache,c),V(e),L(e),oe(e,t.embedder,t.store),N(e),P(e),te(e,t.embedder,t.store),le(e,o),M(e),H(e),U(e),F(e),j(e),k(e),ue(e,t.embedder),A(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),K(e,r),r&&b(e,r),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(e),t.bridge&&(ee(e,t.bridge,t.evolutionCollector),S(e,t.bridge),C(e,t.bridge)),t.policyStore&&ve(e,t.policyStore),t.evolutionCollector&&se(e,t.evolutionCollector),s(e,t.store,t.curated),Ce(e)}async function tt(e){let t=await X(e),n=et(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`,q(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`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(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 nt=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(`.`)),rt=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.status.test_run.time.watch.web_fetch.web_search.workset`.split(`.`));function it(e){T(e),E(e),O(e),D(e),le(e),z(e),R(e),B(e),I(e),L(e),G(e),W(e),V(e),we(e),H(e),U(e),M(e),N(e),P(e),F(e),j(e),k(e),A(e),K(e),b(e,n),ye(e),Ce(e),De(e),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(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 at(e){let n=new J({name:e.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}}),a=`initializing`,s=``,l=!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
- `);r(n),d(n,e.toolPrefix??``);let p=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let m=[];for(let e of $){let t=u(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)}it(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,y=new Promise(e=>{v=e}),b=()=>v?.(),x=(async()=>{await y;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 u=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let d=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=u,n.sendPromptListChanged=d,n.sendResourceListChanged=f,Promise.resolve(n.sendToolListChanged()).catch(()=>{}),Promise.resolve(n.sendPromptListChanged()).catch(()=>{}),Promise.resolve(n.sendResourceListChanged()).catch(()=>{});let b=n._registeredTools??{};for(let[e,t]of Object.entries(b)){if(nt.has(e))continue;let n=t.handler;t.handler=async(...t)=>{if(!r.indexer.isIndexing)return n(...t);let i=l?`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 (${rt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),rt));return Promise.race([n(...t),a])}}let x=Object.keys(b).length;x!==$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:x}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4}),g?.(r)})(),te=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}))});l=!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`,q(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`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(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:b,ready:x,runInitialIndex:te}}export{$ as ALL_TOOL_NAMES,at as createLazyServer,et as createMcpServer,tt as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
3
+ `);r(n),d(n,e.toolPrefix??``);let p=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let m=[];for(let e of $){let t=u(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)}it(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`}]})),g=n.prompt(`_init`,`KB is initializing prompts...`,async()=>({messages:[{role:`user`,content:{type:`text`,text:f()}}]})),_,v=new Promise(e=>{_=e}),y,b=new Promise(e=>{y=e}),x=()=>y?.(),S=(async()=>{await b;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 u=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let d=n.sendPromptListChanged.bind(n);n.sendPromptListChanged=()=>{};let f=n.sendResourceListChanged.bind(n);n.sendResourceListChanged=()=>{};for(let e of m)e.remove();h.remove(),g.remove();let p=n._registeredTools??{};for(let e of Q)p[e]?.remove();let v=new o(n),y=c(n);Z(n,r,e,t(n),v,y),i(n),n.sendToolListChanged=u,n.sendPromptListChanged=d,n.sendResourceListChanged=f,Promise.resolve(n.sendToolListChanged()).catch(()=>{}),Promise.resolve(n.sendPromptListChanged()).catch(()=>{}),Promise.resolve(n.sendResourceListChanged()).catch(()=>{});let x=n._registeredTools??{};for(let[e,t]of Object.entries(x)){if(nt.has(e))continue;let n=t.handler;t.handler=async(...t)=>{if(!r.indexer.isIndexing)return n(...t);let i=l?`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 (${rt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),rt));return Promise.race([n(...t),a])}}let S=Object.keys(x).length;S!==$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:S}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4}),_?.(r)})(),ee=async()=>{let t=await v;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}))});l=!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`,q(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`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(e))}},C=process.ppid,w=setInterval(()=>{try{process.kill(C,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:C}),clearInterval(w),v.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 w.unref(),{server:n,startInit:x,ready:S,runInitialIndex:ee}}export{$ as ALL_TOOL_NAMES,at as createLazyServer,et as createMcpServer,tt as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
@@ -4,11 +4,11 @@ import { IGraphStore, IKnowledgeStore } from "../../../store/dist/index.js";
4
4
  import { IEmbedder } from "../../../embeddings/dist/index.js";
5
5
 
6
6
  //#region packages/server/src/tools/context.tools.d.ts
7
- declare function registerCompactTool(server: McpServer, embedder: IEmbedder, cache: FileCache): void;
7
+ declare function registerCompactTool(server: McpServer, embedder: IEmbedder, cache: FileCache, rootPath: string): void;
8
8
  declare function registerScopeMapTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore): void;
9
9
  declare function registerFindTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore): void;
10
10
  declare function registerSymbolTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore, graphStore?: IGraphStore): void;
11
- declare function registerFileSummaryTool(server: McpServer, cache: FileCache): void;
11
+ declare function registerFileSummaryTool(server: McpServer, cache: FileCache, rootPath: string): void;
12
12
  declare function registerTraceTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore): void;
13
13
  declare function registerDeadSymbolsTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore): void;
14
14
  //#endregion
@@ -1,10 +1,10 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{CompactOutputSchema as t,DeadSymbolsOutputSchema as n,FileSummaryOutputSchema as r,FindOutputSchema as i,ScopeMapOutputSchema as a,SymbolOutputSchema as o}from"../output-schemas.js";import{fanOutSearch as s,openWorkspaceStores as c,resolveWorkspaces as l}from"../cross-workspace.js";import{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`),token_budget:u.number().min(50).max(12500).optional().describe(`Token budget — overrides max_chars (approx 4 chars per token). Use to fit output into a specific context window.`)},annotations:a.annotations},async({text:e,path:t,query:n,max_chars:a,segmentation:o,token_budget:s})=>{try{if(!e&&!t)return{content:[{type:`text`,text:`Error: Either "text" or "path" must be provided.`}],isError:!0};let c=await h(r,{text:e,path:t,query:n,maxChars:a,tokenBudget:s,segmentation:o,cache:i});return{content:[{type:`text`,text:[`Compressed ${c.originalChars} → ${c.compressedChars} chars (${(c.ratio*100).toFixed(0)}%)`,`Kept ${c.segmentsKept}/${c.segmentsTotal} segments`,``,c.text].join(`
2
- `)}],structuredContent:{originalChars:c.originalChars,compressedChars:c.compressedChars,ratio:c.ratio,segmentsKept:c.segmentsKept,segmentsTotal:c.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.${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(`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{CompactOutputSchema as t,DeadSymbolsOutputSchema as n,FileSummaryOutputSchema as r,FindOutputSchema as i,ScopeMapOutputSchema as a,SymbolOutputSchema as o}from"../output-schemas.js";import{fanOutSearch as s,openWorkspaceStores as c,resolveWorkspaces as l}from"../cross-workspace.js";import{isAbsolute as u,resolve as d}from"node:path";import{z as f}from"zod";import{CONTENT_TYPES as p,computePartitionKey as m,createLogger as h,serializeError as g}from"../../../core/dist/index.js";import{compact as _,fileSummary as v,find as y,findDeadSymbols as b,findExamples as x,scopeMap as S,symbol as C,trace as w,truncateToTokenBudget as T}from"../../../tools/dist/index.js";const E=h(`tools:context`);function D(n,r,i,a){let o=e(`compact`);n.registerTool(`compact`,{title:o.title,description:"Compress text to relevant sections using embedding similarity (no LLM). Provide either `text` or `path` (server reads the file — saves a round-trip). Segments by paragraph/sentence/line.",outputSchema:t,inputSchema:{text:f.string().optional().describe(`The text to compress (provide this OR path, not both)`),path:f.string().optional().describe(`File path to read server-side — avoids read_file round-trip + token doubling (provide this OR text)`),query:f.string().describe(`Focus query — what are you trying to understand?`),max_chars:f.number().min(100).max(5e4).default(3e3).describe(`Target output size in characters`),segmentation:f.enum([`paragraph`,`sentence`,`line`]).default(`paragraph`).describe(`How to split the text for scoring`),token_budget:f.number().min(50).max(12500).optional().describe(`Token budget — overrides max_chars (approx 4 chars per token). Use to fit output into a specific context window.`)},annotations:o.annotations},async({text:e,path:t,query:n,max_chars:o,segmentation:s,token_budget:c})=>{try{let l=t&&!u(t)?d(a,t):t;if(!e&&!l)return{content:[{type:`text`,text:`Error: Either "text" or "path" must be provided.`}],isError:!0};let f=await _(r,{text:e,path:l,query:n,maxChars:o,tokenBudget:c,segmentation:s,cache:i});return{content:[{type:`text`,text:[`Compressed ${f.originalChars} → ${f.compressedChars} chars (${(f.ratio*100).toFixed(0)}%)`,`Kept ${f.segmentsKept}/${f.segmentsTotal} segments`,``,f.text].join(`
2
+ `)}],structuredContent:{originalChars:f.originalChars,compressedChars:f.compressedChars,ratio:f.ratio,segmentsKept:f.segmentsKept,segmentsTotal:f.segmentsTotal}}}catch(e){return E.error(`Compact failed`,g(e)),{content:[{type:`text`,text:`Compact failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function O(t,n,r){let i=e(`scope_map`);t.registerTool(`scope_map`,{title:i.title,description:`Generate a task-scoped reading plan. Given a task description, identifies which files and sections are relevant, with estimated token counts and suggested reading order.`,outputSchema:a,inputSchema:{task:f.string().describe(`Description of the task to scope`),max_files:f.number().min(1).max(50).default(15).describe(`Maximum files to include`),content_type:f.enum(p).optional().describe(`Filter by content type`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`)},annotations:i.annotations},async({task:e,max_files:t,content_type:i,max_tokens:a})=>{try{let o=await S(n,r,{task:e,maxFiles:t,contentType:i}),s=[`## Scope Map: ${e}`,`Total estimated tokens: ~${o.totalEstimatedTokens}`,``,`### Files (by relevance)`,...o.files.map((e,t)=>`${t+1}. **${e.path}** (~${e.estimatedTokens} tokens, ${(e.relevance*100).toFixed(0)}% relevant)\n ${e.reason}\n Focus: ${e.focusRanges.map(e=>`L${e.start}-${e.end}`).join(`, `)}`),``,`### Suggested Reading Order`,...o.readingOrder.map((e,t)=>`${t+1}. ${e}`),``,`### Suggested Compact Calls`,`_Estimated compressed total: ~${Math.ceil(o.totalEstimatedTokens/5)} tokens_`,...o.compactCommands.map((e,t)=>`${t+1}. ${e}`)].join(`
3
+ `)+"\n\n---\n_Next: Use `search` to dive into specific files, or `compact` to compress file contents for context._";return{content:[{type:`text`,text:a?T(s,a):s}],structuredContent:{files:o.files.map(e=>({path:e.path,relevance:e.relevance,estimatedTokens:e.estimatedTokens,...e.focusRanges.length>0?{focusLines:e.focusRanges.map(e=>`L${e.start}-${e.end}`)}:{}})),totalFiles:o.files.length,totalEstimatedTokens:o.totalEstimatedTokens,task:e}}}catch(e){return E.error(`Scope map failed`,g(e)),{content:[{type:`text`,text:`Scope map failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function k(t,n,r){let a=e(`find`);t.registerTool(`find`,{title:a.title,description:`Multi-strategy search combining vector, FTS, glob, and regex. Use for precise queries needing multiple strategies. mode=examples finds real usage of a symbol. For general discovery use search instead.`,outputSchema:i,inputSchema:{query:f.string().optional().describe(`Semantic/keyword search query (required for mode "examples")`),glob:f.string().optional().describe(`File glob pattern (search mode only)`),pattern:f.string().optional().describe(`Regex pattern to match in content (search mode only)`),limit:f.number().min(1).max(50).default(10).describe(`Max results`),content_type:f.enum(p).optional().describe(`Filter by content type`),mode:f.enum([`search`,`examples`]).default(`search`).describe(`Mode: "search" (default) for federated search, "examples" to find usage examples of a symbol/pattern`),max_tokens:f.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),workspaces:f.array(f.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`)},annotations:a.annotations},async({query:e,glob:t,pattern:i,limit:a,content_type:o,mode:u,max_tokens:d,workspaces:f})=>{try{if(u===`examples`){if(!e)return{content:[{type:`text`,text:`Error: "query" is required for mode "examples".`}],isError:!0};let t=await x(n,r,{query:e,limit:a,contentType:o}),i=JSON.stringify(t);return{content:[{type:`text`,text:d?T(i,d):i}]}}let p=await y(n,r,{query:e,glob:t,pattern:i,limit:a,contentType:o}),h=``;if(f&&f.length>0&&e){let t=l(f,m(process.cwd()));if(t.length>0){let{stores:r,closeAll:i}=await c(t);try{let i=await s(r,await n.embedQuery(e),{limit:a,contentType:o});for(let e of i)p.results.push({path:`[${e.workspace}] ${e.record.sourcePath}`,score:e.score,source:`cross-workspace`,lineRange:e.record.startLine?{start:e.record.startLine,end:e.record.endLine}:void 0,preview:e.record.content.slice(0,200)});p.results.sort((e,t)=>t.score-e.score),p.results=p.results.slice(0,a),p.totalFound=p.results.length,h=` + ${t.length} workspace(s)`}finally{await i()}}}if(p.results.length===0)return{content:[{type:`text`,text:`No results found.${p.failedStrategies?.length?`\nStrategies attempted: ${p.strategies.join(`, `)}\nFailed: ${p.failedStrategies.map(e=>`${e.strategy} (${e.reason})`).join(`, `)}`:p.strategies.length===0?`
4
+ No search strategies were activated. Provide at least one of: query, glob, or pattern.`:``}`}],structuredContent:{matches:[],totalMatches:0,pattern:e??t??i??``,truncated:!1}};let g=[`Found ${p.totalFound} results via ${p.strategies.join(` + `)}${h}`,``,...p.results.map(e=>{let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``,n=e.preview?`\n ${e.preview.slice(0,100)}...`:``;return`- [${e.source}] ${e.path}${t} (${(e.score*100).toFixed(0)}%)${n}`})];return{content:[{type:`text`,text:d?T(g.join(`
5
5
  `),d):g.join(`
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(`
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(`
8
- `)}],structuredContent:{symbols:[...n.deadInSource,...n.deadInDocs].map(e=>({name:e.name,path:e.path,...e.line===void 0?{}:{line:e.line},kind:e.kind})),totalDead:n.totalDeadSource+n.totalDeadDocs}}}catch(e){return w.error(`Dead symbol scan failed`,m(e)),{content:[{type:`text`,text:`Dead symbol scan failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function M(e){let t=[`Symbol: ${e.name}`];if(e.definedIn){let n=`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`;e.definedIn.signature&&(n+=`\nSignature: ${e.definedIn.signature}`),t.push(n)}else t.push(`Defined in: not found`);if(t.push(``,`Imported by:`),e.importedBy.length===0)t.push(` none`);else for(let n of e.importedBy)t.push(` - ${n.path}:${n.line} ${n.importStatement}`);if(t.push(``,`Referenced in:`),e.referencedIn.length===0)t.push(` none`);else for(let n of e.referencedIn){let e=`scope`in n&&n.scope?` in ${n.scope}()`:``;t.push(` - ${n.path}:${n.line}${e} ${n.context}`)}if(e.graphContext){let n=e.graphContext;t.push(``,`Graph context:`),n.definingModule&&t.push(` Module: ${n.definingModule}`),n.importedByModules.length>0&&t.push(` Imported by modules: ${n.importedByModules.join(`, `)}`),n.siblingSymbols.length>0&&t.push(` Sibling symbols: ${n.siblingSymbols.join(`, `)}`)}return t.join(`
9
- `)}function N(e){let t=[e.path,`Language: ${e.language}`,`Lines: ${e.lines}`,`Estimated tokens: ~${e.estimatedTokens}`,``,`Imports (${e.imports.length}):`,...P(e.imports),``,`Exports (${e.exports.length}):`,...P(e.exports),``,`Functions (${e.functions.length}):`,...P(e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${`signature`in e&&e.signature?` — ${e.signature}`:``}`)),``,`Classes (${e.classes.length}):`,...P(e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${e.signature?` — ${e.signature}`:``}`)),``,`Interfaces (${e.interfaces.length}):`,...P(e.interfaces.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`)),``,`Types (${e.types.length}):`,...P(e.types.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`))];if(`importDetails`in e&&e.importDetails&&e.importDetails.length>0){let n=e.importDetails.filter(e=>e.isExternal).length,r=e.importDetails.length-n;t.push(``,`Import breakdown: ${n} external, ${r} internal`)}if(`callEdges`in e&&e.callEdges&&e.callEdges.length>0){t.push(``,`Call edges (${e.callEdges.length} intra-file):`);for(let n of e.callEdges.slice(0,30))t.push(` - ${n.caller}() → ${n.callee}() @ line ${n.line}`);e.callEdges.length>30&&t.push(` - ... ${e.callEdges.length-30} more`)}return t.join(`
10
- `)}function P(e){return e.length===0?[` none`]:e.map(e=>` - ${e}`)}export{T as registerCompactTool,j as registerDeadSymbolsTool,k as registerFileSummaryTool,D as registerFindTool,E as registerScopeMapTool,O as registerSymbolTool,A as registerTraceTool};
6
+ `)}],structuredContent:{matches:p.results.map(e=>({path:e.path,...e.lineRange?{line:e.lineRange.start}:{},matchType:e.source,preview:e.preview?.slice(0,200)??``})),totalMatches:p.totalFound,pattern:e??t??i??``,truncated:p.results.length<p.totalFound}}}catch(e){return E.error(`Find failed`,g(e)),{content:[{type:`text`,text:`Find failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function A(t,n,r,i){let a=e(`symbol`);t.registerTool(`symbol`,{title:a.title,description:`Find definition, imports, and references of a named symbol (function, class, type). For tracing data flow across call sites use trace instead.`,inputSchema:{name:f.string().describe(`Symbol name to look up (function, class, type, etc.)`),limit:f.number().min(1).max(50).default(20).describe(`Max results per category`),workspaces:f.array(f.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`)},outputSchema:o,annotations:a.annotations},async({name:e,limit:t,workspaces:a})=>{try{let o=await C(n,r,{name:e,limit:t,graphStore:i});if(a&&a.length>0){let r=l(a,m(process.cwd()));if(r.length>0){let{stores:i,closeAll:a}=await c(r);try{for(let[r,a]of i){let i=await C(n,a,{name:e,limit:t});i.definedIn&&!o.definedIn&&(o.definedIn={...i.definedIn,path:`[${r}] ${i.definedIn.path}`});for(let e of i.referencedIn)o.referencedIn.push({...e,path:`[${r}] ${e.path}`});if(i.importedBy){o.importedBy=o.importedBy??[];for(let e of i.importedBy)o.importedBy.push({...e,path:`[${r}] ${e.path}`})}}}finally{await a()}}}let s={name:o.name,definedIn:o.definedIn??null,importedBy:o.importedBy??[],referencedIn:o.referencedIn??[],graphContext:o.graphContext??null};return{content:[{type:`text`,text:P(o)}],structuredContent:s}}catch(e){return E.error(`Symbol lookup failed`,g(e)),{content:[{type:`text`,text:`Symbol lookup failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function j(t,n,i){let a=e(`file_summary`);t.registerTool(`file_summary`,{title:a.title,description:`Create a concise structural summary of a source file: imports, exports, functions, classes, interfaces, and types.`,outputSchema:r,inputSchema:{path:f.string().describe(`Absolute path to the file to summarize`)},annotations:a.annotations},async({path:e})=>{try{let t=u(e)?e:d(i,e),r=await v({path:t,content:(await n.get(t)).content});return{content:[{type:`text`,text:F(r)}],structuredContent:{path:r.path,language:r.language,lines:r.lines,imports:r.imports?.length??0,exports:r.exports?.length??0,functions:r.functions?.length??0,classes:r.classes?.length??0}}}catch(e){return E.error(`File summary failed`,g(e)),{content:[{type:`text`,text:`File summary failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function M(t,n,r){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:f.string().describe(`Starting point — symbol name or file:line reference`),direction:f.enum([`forward`,`backward`,`both`]).describe(`Which direction to trace relationships`),max_depth:f.number().min(1).max(10).default(3).optional().describe(`Maximum trace depth`)},annotations:i.annotations},async({start:e,direction:t,max_depth:i})=>{try{let a=await w(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(`
7
+ `)}]}}catch(e){return E.error(`Trace failed`,g(e)),{content:[{type:`text`,text:`Trace failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function N(t,r,i){let a=e(`dead_symbols`);t.registerTool(`dead_symbols`,{title:a.title,description:`Find exported symbols that appear to be unused because they are never imported or re-exported.`,outputSchema:n,inputSchema:{path:f.string().optional().describe(`Root path to scope the search (default: cwd)`),limit:f.number().min(1).max(500).default(100).optional().describe(`Maximum exported symbols to scan`)},annotations:a.annotations},async({path:e,limit:t})=>{try{let n=await b(r,i,{rootPath:e,limit:t}),a=[`## Dead Symbol Analysis`,``,`**Exports scanned:** ${n.totalExports}`,`**Dead in source:** ${n.totalDeadSource} (actionable)`,`**Dead in docs:** ${n.totalDeadDocs} (informational — code samples in .md files)`,``];if(n.deadInSource.length>0){a.push(`### Dead in Source (actionable)`);for(let e of n.deadInSource)a.push(`- \`${e.name}\` (${e.kind}) — ${e.path}:${e.line}`);a.push(``)}if(n.deadInDocs.length>0){a.push(`### Dead in Docs (informational)`),a.push(`_${n.totalDeadDocs} symbol(s) found only in documentation code samples — not actionable dead code._`);for(let e of n.deadInDocs.slice(0,5))a.push(`- \`${e.name}\` — ${e.path}:${e.line}`);n.deadInDocs.length>5&&a.push(`- _... ${n.deadInDocs.length-5} more omitted_`)}return n.totalDeadSource>0?a.push(``,`---`,`_Next: \`codemod\` to remove ${n.totalDeadSource} unused exports | \`symbol\` to verify usage before removing_`):a.push(``,`---`,"_Next: `check` — no dead symbols found, validate types and lint_"),{content:[{type:`text`,text:a.join(`
8
+ `)}],structuredContent:{symbols:[...n.deadInSource,...n.deadInDocs].map(e=>({name:e.name,path:e.path,...e.line===void 0?{}:{line:e.line},kind:e.kind})),totalDead:n.totalDeadSource+n.totalDeadDocs}}}catch(e){return E.error(`Dead symbol scan failed`,g(e)),{content:[{type:`text`,text:`Dead symbol scan failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function P(e){let t=[`Symbol: ${e.name}`];if(e.definedIn){let n=`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`;e.definedIn.signature&&(n+=`\nSignature: ${e.definedIn.signature}`),t.push(n)}else t.push(`Defined in: not found`);if(t.push(``,`Imported by:`),e.importedBy.length===0)t.push(` none`);else for(let n of e.importedBy)t.push(` - ${n.path}:${n.line} ${n.importStatement}`);if(t.push(``,`Referenced in:`),e.referencedIn.length===0)t.push(` none`);else for(let n of e.referencedIn){let e=`scope`in n&&n.scope?` in ${n.scope}()`:``;t.push(` - ${n.path}:${n.line}${e} ${n.context}`)}if(e.graphContext){let n=e.graphContext;t.push(``,`Graph context:`),n.definingModule&&t.push(` Module: ${n.definingModule}`),n.importedByModules.length>0&&t.push(` Imported by modules: ${n.importedByModules.join(`, `)}`),n.siblingSymbols.length>0&&t.push(` Sibling symbols: ${n.siblingSymbols.join(`, `)}`)}return t.join(`
9
+ `)}function F(e){let t=[e.path,`Language: ${e.language}`,`Lines: ${e.lines}`,`Estimated tokens: ~${e.estimatedTokens}`,``,`Imports (${e.imports.length}):`,...I(e.imports),``,`Exports (${e.exports.length}):`,...I(e.exports),``,`Functions (${e.functions.length}):`,...I(e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${`signature`in e&&e.signature?` — ${e.signature}`:``}`)),``,`Classes (${e.classes.length}):`,...I(e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}${e.signature?` — ${e.signature}`:``}`)),``,`Interfaces (${e.interfaces.length}):`,...I(e.interfaces.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`)),``,`Types (${e.types.length}):`,...I(e.types.map(e=>`${e.name} @ line ${e.line}${`exported`in e&&e.exported?` [exported]`:``}`))];if(`importDetails`in e&&e.importDetails&&e.importDetails.length>0){let n=e.importDetails.filter(e=>e.isExternal).length,r=e.importDetails.length-n;t.push(``,`Import breakdown: ${n} external, ${r} internal`)}if(`callEdges`in e&&e.callEdges&&e.callEdges.length>0){t.push(``,`Call edges (${e.callEdges.length} intra-file):`);for(let n of e.callEdges.slice(0,30))t.push(` - ${n.caller}() → ${n.callee}() @ line ${n.line}`);e.callEdges.length>30&&t.push(` - ... ${e.callEdges.length-30} more`)}return t.join(`
10
+ `)}function I(e){return e.length===0?[` none`]:e.map(e=>` - ${e}`)}export{D as registerCompactTool,N as registerDeadSymbolsTool,j as registerFileSummaryTool,k as registerFindTool,O as registerScopeMapTool,A as registerSymbolTool,M as registerTraceTool};
@@ -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,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
- `)}]}}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
+ 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)})}}async function u(e,t,r){if(r.autoRemember?.length)for(let i of r.autoRemember)try{let r=n(`sha256`).update(`onboard-remember::${i.title}`).digest(`hex`).slice(0,16),a=new Date().toISOString(),o={id:r,content:`# ${i.title}\n\n${i.content}`,sourcePath:`curated/onboard/${i.category}/${r}.md`,contentType:`curated`,chunkIndex:0,totalChunks:1,startLine:0,endLine:0,fileHash:n(`sha256`).update(i.content).digest(`hex`).slice(0,16),indexedAt:a,origin:`curated`,tags:i.tags,category:i.category,version:1},[s]=await t.embedBatch([o.content]);await e.upsert([o],[s])}catch(e){s.warn(`Auto-persist remember entry failed`,{title:i.title,...a(e)})}}function d(n,i,d,f){let p=e(`onboard`);n.registerTool(`onboard`,{title:p.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:p.annotations},async({path:e,mode:n,out_dir:r},p)=>{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 m=await o({path:e,mode:n,outDir:r??f?.onboardDir}),h=t(p).createTask(`Onboard`,m.steps.length);for(let e=0;e<m.steps.length;e++){let t=m.steps[e];h.progress(e,`${t.name}: ${t.status}`)}h.complete(`Onboard complete: ${m.steps.filter(e=>e.status===`success`).length}/${m.steps.length} steps succeeded`),l(i,d,m),m.autoRemember?.length&&u(i,d,m).catch(e=>{s.warn(`Auto-persist autoRemember failed`,a(e))});let g=[`## Onboard Complete`,``,`**Path:** \`${m.path}\``,`**Mode:** ${m.mode}`,`**Duration:** ${m.totalDurationMs}ms`,``];m.outDir&&(g.push(`**Output directory:** \`${m.outDir}\``),g.push(``)),g.push(`### Analysis Results`,``);let _=[],v=[];for(let e of m.steps)e.status===`success`?_.push(`- ✓ **${e.name}** (${e.durationMs}ms) — ${e.output.length} chars`):v.push(`- ✗ **${e.name}** — ${e.error}`);g.push(..._),v.length>0&&g.push(``,`### Failed`,``,...v),g.push(``,`---`,``);for(let e of m.steps)e.status===`success`&&g.push(`### ${e.name}`,``,e.output,``,`---`,``);return g.push(`_All results auto-saved to KB.`,m.mode===`generate`?` Files written to \`${m.outDir}\`.`:``," Next: Use `search` to query the knowledge, or `remember` to add custom insights._"),{content:[{type:`text`,text:g.join(`
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{d as registerOnboardTool};
@@ -0,0 +1,4 @@
1
+ //#region packages/server/src/tools/present/browser.d.ts
2
+ declare function buildBrowserHtml(title: string | undefined, content: unknown, actions?: unknown, template?: string): string;
3
+ //#endregion
4
+ export { buildBrowserHtml };
@@ -0,0 +1,93 @@
1
+ import{FONT_LINK as e,getDesignSystemCSS as t}from"../present-theme.js";import{escHtml as n}from"../present-utils.js";import{contentToHtml as r}from"./html.js";import{buildTemplateHtml as i}from"./templates.js";function a(a,o,s,c){let l=c&&c!==`auto`?i(c,o):r(a,o);return`<!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
+ <title>${n(a??`KB Dashboard`)}</title>
7
+ ${e}
8
+ <style>${t()}</style>
9
+ </head>
10
+ <body>
11
+ <div class="dashboard">
12
+ <div class="header">
13
+ <h1>${n(a??`KB Dashboard`)}</h1>
14
+ <div class="subtitle">Knowledge Base</div>
15
+ </div>
16
+ ${l}
17
+ ${(()=>{let e=Array.isArray(s)?s:[];return e.length===0?``:`
18
+ <div class="actions-bar">
19
+ <h2>Actions</h2>
20
+ <div class="actions-grid">${e.map(e=>{let t=String(e.id??``);if(e.type===`select`&&Array.isArray(e.options)){let r=e.options.map(e=>{let t=typeof e==`string`?e:e.label;return`<option value="${n(typeof e==`string`?e:e.value)}">${n(t)}</option>`}).join(``);return`<div class="action-group"><label>${n(String(e.label??``))}</label><select data-action-id="${n(t)}" onchange="sendCallback(${n(JSON.stringify(t))},this.value)">${r}</select></div>`}return`<button class="action-btn action-${String(e.variant??`default`)}" onclick="sendCallback(${n(JSON.stringify(t))},'clicked')">${n(String(e.label??``))}</button>`}).join(`
21
+ `)}</div>
22
+ <div id="action-feedback" class="action-feedback"></div>
23
+ </div>
24
+ <script>
25
+ let _cbSent=false;
26
+ function sendCallback(actionId,value){
27
+ if(_cbSent)return;
28
+ _cbSent=true;
29
+ document.querySelectorAll('.action-btn,.action-group select').forEach(el=>{el.disabled=true;el.style.opacity='0.5'});
30
+ const fb=document.getElementById('action-feedback');
31
+ fb.textContent='⏳ Sending selection: '+actionId+' = '+value;
32
+ fb.className='action-feedback sent';
33
+ fetch('/callback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({actionId,value})})
34
+ .then(()=>{
35
+ fb.textContent='✓ Selection sent: '+actionId+' = '+value;
36
+ })
37
+ .catch(e=>{
38
+ fb.textContent='✗ Callback failed — '+e.message;
39
+ fb.style.color='var(--error)';
40
+ _cbSent=false;
41
+ document.querySelectorAll('.action-btn,.action-group select').forEach(el=>{el.disabled=false;el.style.opacity='1'});
42
+ });
43
+ }
44
+ <\/script>`})()}
45
+ <div class="footer">KB MCP Server &middot; Generated ${new Date().toLocaleString()}</div>
46
+ </div>
47
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>
48
+ <script>
49
+ if(document.querySelector('.mermaid'))mermaid.initialize({theme:'dark',startOnLoad:true});
50
+
51
+ document.querySelectorAll('table').forEach(table=>{
52
+ const headers=table.querySelectorAll('th');
53
+ headers.forEach((th,i)=>{
54
+ let asc=true;
55
+ th.addEventListener('click',()=>{
56
+ const tbody=table.querySelector('tbody')||table;
57
+ const rows=[...tbody.querySelectorAll('tr')].filter(r=>r.querySelector('td'));
58
+ rows.sort((a,b)=>{
59
+ const at=(a.cells[i]?.textContent||'').trim();
60
+ const bt=(b.cells[i]?.textContent||'').trim();
61
+ return asc?at.localeCompare(bt,undefined,{numeric:true}):bt.localeCompare(at,undefined,{numeric:true});
62
+ });
63
+ rows.forEach(r=>tbody.appendChild(r));
64
+ asc=!asc;
65
+ headers.forEach(h=>h.style.color='');
66
+ th.style.color='var(--primary)';
67
+ });
68
+ });
69
+ });
70
+
71
+ document.querySelectorAll('.table-wrap').forEach(wrap=>{
72
+ const table=wrap.querySelector('table');
73
+ if(!table||table.querySelectorAll('tr').length<5)return;
74
+ const bar=document.createElement('div');
75
+ bar.className='search-bar';
76
+ const input=document.createElement('input');
77
+ input.placeholder='Filter rows...';
78
+ const count=document.createElement('span');
79
+ count.className='count';
80
+ bar.appendChild(input);bar.appendChild(count);
81
+ wrap.parentNode.insertBefore(bar,wrap);
82
+ const rows=[...table.querySelectorAll('tbody tr, tr')].filter(r=>r.querySelector('td'));
83
+ const updateCount=()=>{const v=rows.filter(r=>r.style.display!=='none').length;count.textContent=v+'/'+rows.length};
84
+ updateCount();
85
+ input.addEventListener('input',()=>{
86
+ const q=input.value.toLowerCase();
87
+ rows.forEach(r=>{r.style.display=r.textContent.toLowerCase().includes(q)?'':'none'});
88
+ updateCount();
89
+ });
90
+ });
91
+ <\/script>
92
+ </body>
93
+ </html>`}export{a as buildBrowserHtml};
@@ -0,0 +1,13 @@
1
+ //#region packages/server/src/tools/present/helpers.d.ts
2
+ interface TypedBlock {
3
+ type: string;
4
+ title?: string;
5
+ value?: unknown;
6
+ language?: string;
7
+ [key: string]: unknown;
8
+ }
9
+ declare function formatValue(value: unknown): string;
10
+ declare function sanitizeId(value: string): string;
11
+ declare function isTypedBlock(value: unknown): value is TypedBlock;
12
+ //#endregion
13
+ export { TypedBlock, formatValue, isTypedBlock, sanitizeId };
@@ -0,0 +1 @@
1
+ function e(t){return t==null?`null`:Array.isArray(t)?`[${t.map(e).join(`, `)}]`:String(t)}function t(e){return e.replace(/[^a-zA-Z0-9_]/g,`_`)}function n(e){return typeof e==`object`&&!!e&&`type`in e&&`value`in e}export{e as formatValue,n as isTypedBlock,t as sanitizeId};
@@ -0,0 +1,18 @@
1
+ import { TypedBlock } from "./helpers.js";
2
+
3
+ //#region packages/server/src/tools/present/html.d.ts
4
+ declare function contentToHtml(title: string | undefined, content: unknown): string;
5
+ declare function renderBlockAsHtml(block: TypedBlock): string;
6
+ declare function arrayToHtmlTable(rows: Record<string, unknown>[]): string;
7
+ declare function metricsToHtml(metrics: Array<{
8
+ label: string;
9
+ value: string | number;
10
+ }>): string;
11
+ declare function cardsToHtml(cards: Record<string, unknown>[]): string;
12
+ declare function objectToHtmlTree(obj: Record<string, unknown>): string;
13
+ declare function graphToMermaidRaw(data: {
14
+ nodes: unknown[];
15
+ edges: unknown[];
16
+ }): string;
17
+ //#endregion
18
+ export { arrayToHtmlTable, cardsToHtml, contentToHtml, graphToMermaidRaw, metricsToHtml, objectToHtmlTree, renderBlockAsHtml };
@@ -0,0 +1,5 @@
1
+ import{escHtml as e}from"../present-utils.js";import{renderChecklistHtml as t,renderComparisonHtml as n,renderProgressHtml as r,renderPromptHtml as i,renderStatusBoardHtml as a,renderTimelineHtml as o}from"../present-blocks.js";import{renderChartAsHtml as s}from"../present-charts.js";import{formatValue as c,isTypedBlock as l,sanitizeId as u}from"./helpers.js";import{marked as d}from"marked";d.setOptions({async:!1,gfm:!0,breaks:!0}),d.use({renderer:{html(t){return e(t.text)}}});function f(t,n){let r=[];if(t&&r.push(`<h1>${e(t)}</h1>`),typeof n==`string`)r.push(`<div class="md-content">${d.parse(n)}</div>`);else if(Array.isArray(n))if(n.length===0)r.push(`<p><em>empty</em></p>`);else if(l(n[0]))for(let e of n)r.push(p(e));else typeof n[0]==`object`&&n[0]!==null?r.push(m(n)):r.push(`<ul>${n.map(t=>`<li>${e(String(t))}</li>`).join(``)}</ul>`);else if(typeof n==`object`&&n){let t=n;Array.isArray(t.metrics)?r.push(h(t.metrics)):Array.isArray(t.nodes)&&Array.isArray(t.edges)?(r.push(`<pre class="mermaid">${e(v(t))}</pre>`),r.push(`<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>`),r.push(`<script>mermaid.run();<\/script>`)):r.push(_(t))}else r.push(`<p>${e(String(n))}</p>`);return r.join(`
2
+ `)}function p(c){let l=[];switch(c.title&&l.push(`<h2>${e(c.title)}</h2>`),c.type){case`markdown`:l.push(`<div class="md-content">${d.parse(String(c.value??``))}</div>`);break;case`code`:l.push(`<pre><code>${e(String(c.value??``))}</code></pre>`);break;case`mermaid`:l.push(`<pre class="mermaid">${e(String(c.value??``))}</pre>`);break;case`table`:if(Array.isArray(c.value)){let e=c.value;if(e.length>0&&Array.isArray(e[0])){let t=e,n=t[0].map(String),r=t.slice(1).map(e=>Object.fromEntries(n.map((t,n)=>[t,e[n]])));l.push(m(r))}else l.push(m(e))}break;case`metrics`:{let e;Array.isArray(c.value)?e=c.value:c.value&&typeof c.value==`object`&&(e=Object.entries(c.value).map(([e,t])=>({label:e,value:String(t)}))),e&&l.push(h(e));break}case`cards`:Array.isArray(c.value)&&l.push(g(c.value));break;case`tree`:c.value&&typeof c.value==`object`&&l.push(_(c.value));break;case`graph`:c.value&&typeof c.value==`object`&&l.push(`<pre class="mermaid">${e(v(c.value))}</pre>`);break;case`chart`:{let e=c.value;if(e&&!e.chartType&&e.type&&Array.isArray(e.labels)&&Array.isArray(e.datasets)){let t=e.labels,n=e.datasets,r=n.map((e,t)=>e.label??`series${t+1}`),i=t.map((e,t)=>{let i={_label:e};return n.forEach((e,n)=>{i[r[n]]=e.data[t]??0}),i}),a={type:`chart`,title:c.title,value:{chartType:String(e.type),data:i,xKey:`_label`,yKeys:r}};l.push(s(a))}else l.push(s(c));break}case`timeline`:{let e=c.value;Array.isArray(e)&&(e={items:e.map(e=>({title:String(e.event??e.title??``),phase:e.date==null?e.phase==null?void 0:String(e.phase):String(e.date),description:e.description==null?void 0:String(e.description),status:e.status??`done`}))}),e&&l.push(o(e));break}case`checklist`:c.value&&l.push(t(c.value));break;case`comparison`:c.value&&l.push(n(c.value));break;case`status-board`:c.value&&l.push(a(c.value));break;case`prompt`:c.value&&l.push(i(c.value));break;case`progress`:c.value&&l.push(r(c.value));break;case`text`:l.push(`<div class="md-content">${d.parse(String(c.value??``))}</div>`);break;case`heading`:l.push(`<h2>${e(String(c.value??``))}</h2>`);break;case`separator`:l.push(`<hr class="separator">`);break;default:l.push(`<pre>${e(JSON.stringify(c.value,null,2))}</pre>`)}return l.join(`
3
+ `)}function m(t){if(t.length===0)return`<p><em>empty table</em></p>`;let n=Object.keys(t[0]);return`<div class="table-wrap"><table><thead><tr>${n.map(t=>`<th>${e(t)}</th>`).join(``)}</tr></thead><tbody>${t.map(t=>`<tr>${n.map(n=>`<td>${e(String(t[n]??``))}</td>`).join(``)}</tr>`).join(`
4
+ `)}</tbody></table></div>`}function h(t){return`<div class="metric-grid">${t.map(t=>`<div class="metric"><div class="metric-value">${e(String(t.value))}</div><div class="metric-label">${e(t.label)}</div></div>`).join(``)}</div>`}function g(t){return`<div class="card-grid">${t.map(t=>{let n=[`<div class="card">`];return t.title&&n.push(`<div class="card-title">${e(String(t.title))}</div>`),(t.body||t.description)&&n.push(`<div class="card-body">${e(String(t.body??t.description))}</div>`),(t.badge||t.status)&&n.push(`<span class="badge">${e(String(t.badge??t.status))}</span>`),n.push(`</div>`),n.join(``)}).join(``)}</div>`}function _(t){let n=[];for(let[r,i]of Object.entries(t))typeof i==`object`&&i&&!Array.isArray(i)?n.push(`<div class="tree-node"><span class="tree-key">${e(r)}:</span><div class="tree-children">${_(i)}</div></div>`):n.push(`<div class="tree-node"><span class="tree-key">${e(r)}:</span> ${e(c(i))}</div>`);return n.join(``)}function v(e){let t=[`graph LR`];for(let n of e.nodes){let e=u(String(n.id??n.name??``)),r=String(n.label??n.name??e);t.push(` ${e}["${r}"]`)}for(let n of e.edges){let e=u(String(n.source??n.from??``)),r=u(String(n.target??n.to??``)),i=n.label?`|${String(n.label)}|`:``;t.push(` ${e} -->${i} ${r}`)}return t.join(`
5
+ `)}export{m as arrayToHtmlTable,g as cardsToHtml,f as contentToHtml,v as graphToMermaidRaw,h as metricsToHtml,_ as objectToHtmlTree,p as renderBlockAsHtml};
@@ -0,0 +1,2 @@
1
+ import { registerPresentTool } from "./tool.js";
2
+ export { registerPresentTool };
@@ -0,0 +1 @@
1
+ import{registerPresentTool as e}from"./tool.js";export{e as registerPresentTool};
@@ -0,0 +1,17 @@
1
+ import { TypedBlock } from "./helpers.js";
2
+
3
+ //#region packages/server/src/tools/present/markdown.d.ts
4
+ declare function buildMarkdown(title: string | undefined, content: unknown): string;
5
+ declare function renderBlockAsMarkdown(block: TypedBlock): string;
6
+ declare function arrayToMarkdownTable(rows: Record<string, unknown>[]): string;
7
+ declare function metricsToMarkdown(metrics: Array<{
8
+ label: string;
9
+ value: string | number;
10
+ }>): string;
11
+ declare function graphToMermaid(data: {
12
+ nodes: unknown[];
13
+ edges: unknown[];
14
+ }): string;
15
+ declare function objectToMarkdownTree(obj: Record<string, unknown>, indent?: number): string;
16
+ //#endregion
17
+ export { arrayToMarkdownTable, buildMarkdown, graphToMermaid, metricsToMarkdown, objectToMarkdownTree, renderBlockAsMarkdown };
@@ -0,0 +1,8 @@
1
+ import{formatValue as e,isTypedBlock as t,sanitizeId as n}from"./helpers.js";function r(e,n){let r=[];if(e&&r.push(`# ${e}\n`),typeof n==`string`)r.push(n);else if(Array.isArray(n))if(n.length===0)r.push(`*(empty)*`);else if(t(n[0]))for(let e of n)r.push(i(e));else if(typeof n[0]==`object`&&n[0]!==null)r.push(a(n));else for(let e of n)r.push(`- ${String(e)}`);else if(typeof n==`object`&&n){let e=n;Array.isArray(e.nodes)&&Array.isArray(e.edges)?r.push(s(e)):Array.isArray(e.metrics)?r.push(o(e.metrics)):r.push(c(e))}else r.push(String(n));return r.join(`
2
+ `)}function i(e){let t=[];switch(e.title&&t.push(`## ${e.title}\n`),e.type){case`markdown`:t.push(String(e.value??``));break;case`code`:t.push(`\`\`\`${e.language??``}\n${String(e.value??``)}\n\`\`\``);break;case`mermaid`:t.push(`\`\`\`mermaid\n${String(e.value??``)}\n\`\`\``);break;case`table`:Array.isArray(e.value)&&t.push(a(e.value));break;case`metrics`:Array.isArray(e.value)&&t.push(o(e.value));break;case`graph`:e.value&&typeof e.value==`object`&&t.push(s(e.value));break;case`cards`:if(Array.isArray(e.value))for(let n of e.value)t.push(`### ${n.title??`Card`}`),(n.body||n.description)&&t.push(String(n.body??n.description)),(n.badge||n.status)&&t.push(`> **${n.badge??n.status}**`),t.push(``);break;case`tree`:e.value&&typeof e.value==`object`&&t.push(c(e.value));break;case`chart`:{let n=e.value;n?.data&&Array.isArray(n.data)&&t.push(`*${String(n.chartType??`chart`)} chart — ${n.data.length} data points*`);break}case`timeline`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.status===`done`?`✅`:e.status===`active`?`🔄`:e.status===`error`?`❌`:`⬜`;t.push(`${n} **${e.title}**${e.description?` — ${e.description}`:``}`)}break}case`checklist`:{let n=e.value;if(n?.items)for(let e of n.items)t.push(`- [${e.checked?`x`:` `}] ${e.label}${e.note?` — ${e.note}`:``}`);break}case`comparison`:{let n=e.value;if(n?.columns&&n.columns.length>0){let e=Math.max(...n.columns.map(e=>e.items?.length??0)),r=n.columns.map(e=>e.title);t.push(`| ${r.join(` | `)} |`),t.push(`| ${r.map(()=>`---`).join(` | `)} |`);for(let r=0;r<e;r++)t.push(`| ${n.columns.map(e=>e.items?.[r]??``).join(` | `)} |`)}break}case`status-board`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.status===`success`?`🟢`:e.status===`warning`?`🟡`:e.status===`error`?`🔴`:e.status===`info`?`🔵`:`⚪`;t.push(`${n} **${e.label}**${e.detail?` — ${e.detail}`:``}`)}break}case`prompt`:{let n=e.value;n?.question&&(t.push(`> **${n.question}**`),n.context&&t.push(`> ${n.context}`));break}case`progress`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.max??100,r=n>0?Math.round(e.value/n*100):0,i=Math.round(r/5),a=`█`.repeat(i)+`░`.repeat(20-i);t.push(`${e.label}: ${a} ${r}%`)}break}case`text`:t.push(String(e.value??``));break;case`heading`:t.push(`## ${String(e.value??``)}\n`);break;case`separator`:t.push(`---
3
+ `);break;default:t.push(JSON.stringify(e.value,null,2))}return t.push(``),t.join(`
4
+ `)}function a(e){if(e.length===0)return`*(empty table)*`;let t=Object.keys(e[0]),n=[];n.push(`| ${t.join(` | `)} |`),n.push(`| ${t.map(()=>`---`).join(` | `)} |`);for(let r of e)n.push(`| ${t.map(e=>String(r[e]??``)).join(` | `)} |`);return n.join(`
5
+ `)}function o(e){return e.map(e=>`- **${e.label}**: ${e.value}`).join(`
6
+ `)}function s(e){let t=["```mermaid",`graph LR`];for(let r of e.nodes){let e=n(String(r.id??r.name??``)),i=String(r.label??r.name??e);t.push(` ${e}["${i}"]`)}for(let r of e.edges){let e=n(String(r.source??r.from??``)),i=n(String(r.target??r.to??``)),a=r.label?`|${String(r.label)}|`:``;t.push(` ${e} -->${a} ${i}`)}return t.push("```"),t.join(`
7
+ `)}function c(t,n=0){let r=` `.repeat(n),i=[];for(let[a,o]of Object.entries(t))typeof o==`object`&&o&&!Array.isArray(o)?(i.push(`${r}- **${a}**:`),i.push(c(o,n+1))):i.push(`${r}- **${a}**: ${e(o)}`);return i.join(`
8
+ `)}export{a as arrayToMarkdownTable,r as buildMarkdown,s as graphToMermaid,o as metricsToMarkdown,c as objectToMarkdownTree,i as renderBlockAsMarkdown};
@@ -0,0 +1,14 @@
1
+ //#region packages/server/src/tools/present/templates.d.ts
2
+ declare function buildTemplateHtml(template: string, content: unknown): string;
3
+ declare function buildListSortHtml(data: Record<string, unknown>): string;
4
+ declare function buildDataTableHtml(data: Record<string, unknown>): string;
5
+ declare function buildPickerHtml(data: Record<string, unknown>): string;
6
+ declare function buildFlameGraphHtml(data: Record<string, unknown>): string;
7
+ declare function buildFormHtml(data: Record<string, unknown>): string;
8
+ declare function buildTimelineHtml(data: Record<string, unknown>): string;
9
+ declare function buildKanbanHtml(data: Record<string, unknown>): string;
10
+ declare function buildTreeHtml(data: Record<string, unknown>): string;
11
+ declare function buildDiffViewHtml(data: Record<string, unknown>): string;
12
+ declare function buildDashboardHtml(data: Record<string, unknown>): string;
13
+ //#endregion
14
+ export { buildDashboardHtml, buildDataTableHtml, buildDiffViewHtml, buildFlameGraphHtml, buildFormHtml, buildKanbanHtml, buildListSortHtml, buildPickerHtml, buildTemplateHtml, buildTimelineHtml, buildTreeHtml };