@vpxa/kb 0.1.20 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/kb",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -11,7 +11,6 @@ declare const MCP_SERVER_ENTRY: {
11
11
  readonly type: "stdio";
12
12
  readonly command: "npx";
13
13
  readonly args: readonly ["-y", "@vpxa/kb", "serve"];
14
- readonly cwd: "${workspaceFolder}";
15
14
  };
16
15
  /** Skills shipped with the KB package and installed during init. */
17
16
  declare const SKILL_NAMES: readonly ["knowledge-base", "brainstorming", "session-handoff", "requirements-clarity", "lesson-learned", "c4-architecture", "adr-skill"];
@@ -1 +1 @@
1
- const e=`knowledge-base`,t={type:`stdio`,command:`npx`,args:[`-y`,`@vpxa/kb`,`serve`],cwd:"${workspaceFolder}"},n=[`knowledge-base`,`brainstorming`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`],r={"chat.agentFilesLocations":{"~/.claude/agents":!1},"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0};export{t as MCP_SERVER_ENTRY,e as SERVER_NAME,n as SKILL_NAMES,r as VSCODE_SETTINGS};
1
+ const e=`knowledge-base`,t={type:`stdio`,command:`npx`,args:[`-y`,`@vpxa/kb`,`serve`]},n=[`knowledge-base`,`brainstorming`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`],r={"chat.agentFilesLocations":{"~/.claude/agents":!1},"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0};export{t as MCP_SERVER_ENTRY,e as SERVER_NAME,n as SKILL_NAMES,r as VSCODE_SETTINGS};
@@ -2,5 +2,13 @@ import { KBConfig } from "@kb/core";
2
2
 
3
3
  //#region packages/server/src/config.d.ts
4
4
  declare function loadConfig(): KBConfig;
5
+ /**
6
+ * Re-target an existing config to a new workspace root.
7
+ *
8
+ * Called after MCP roots are resolved — the initial config was built with
9
+ * `process.cwd()` (unknown at user-level), so we re-point source paths,
10
+ * store path, and curated path to the actual workspace the IDE has open.
11
+ */
12
+ declare function reconfigureForWorkspace(config: KBConfig, workspaceRoot: string): void;
5
13
  //#endregion
6
- export { loadConfig };
14
+ export { loadConfig, reconfigureForWorkspace };
@@ -1 +1 @@
1
- import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{KB_PATHS as a,createLogger as o,getPartitionDir as s,isUserInstalled as c,registerWorkspace as l,serializeError as u}from"../../core/dist/index.js";const d=n(i(import.meta.url)),f=o(`server`);function p(e,t,n){let i=r(e),a=r(t);if(!i.startsWith(a))throw Error(`Config ${n} path escapes workspace root: ${e} is not under ${t}`);return i}function m(){let i=process.env.KB_CONFIG_PATH??(e(r(process.cwd(),`kb.config.json`))?r(process.cwd(),`kb.config.json`):r(d,`..`,`..`,`..`,`kb.config.json`));try{let e=t(i,`utf-8`),o=JSON.parse(e);if(!o.sources||!Array.isArray(o.sources)||o.sources.length===0)throw Error(`Config must have at least one source`);if(!o.store?.path)throw Error(`Config must specify store.path`);let s=n(i);return o.sources=o.sources.map(e=>({...e,path:p(r(s,e.path),s,`source`)})),o.store.path=p(r(s,o.store.path),s,`store`),o.curated=o.curated??{path:a.aiCurated},o.curated.path=p(r(s,o.curated.path),s,`curated`),g(o,s),o}catch(e){return f.error(`Failed to load config`,{configPath:i,...u(e)}),f.warn(`Falling back to default configuration`,{configPath:i}),h()}}function h(){let e=process.env.KB_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`knowledge-base`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:`mixedbread-ai/mxbai-embed-large-v1`,dimensions:1024},store:{backend:`lancedb`,path:r(e,a.data)},curated:{path:r(e,a.aiCurated)}};return g(t,e),t}function g(e,t){if(!c())return;let n=t,i=l(n);e.store.path=r(s(i.partition)),e.curated||={path:r(n,a.aiCurated)}}export{m as loadConfig};
1
+ import{existsSync as e,readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{KB_PATHS as a,createLogger as o,getPartitionDir as s,isUserInstalled as c,registerWorkspace as l,serializeError as u}from"../../core/dist/index.js";const d=n(i(import.meta.url)),f=o(`server`);function p(e,t,n){let i=r(e),a=r(t);if(!i.startsWith(a))throw Error(`Config ${n} path escapes workspace root: ${e} is not under ${t}`);return i}function m(){let i=process.env.KB_CONFIG_PATH??(e(r(process.cwd(),`kb.config.json`))?r(process.cwd(),`kb.config.json`):r(d,`..`,`..`,`..`,`kb.config.json`));try{let e=t(i,`utf-8`),o=JSON.parse(e);if(!o.sources||!Array.isArray(o.sources)||o.sources.length===0)throw Error(`Config must have at least one source`);if(!o.store?.path)throw Error(`Config must specify store.path`);let s=n(i);return o.sources=o.sources.map(e=>({...e,path:p(r(s,e.path),s,`source`)})),o.store.path=p(r(s,o.store.path),s,`store`),o.curated=o.curated??{path:a.aiCurated},o.curated.path=p(r(s,o.curated.path),s,`curated`),g(o,s),o}catch(e){return f.error(`Failed to load config`,{configPath:i,...u(e)}),f.warn(`Falling back to default configuration`,{configPath:i}),h()}}function h(){let e=process.env.KB_WORKSPACE_ROOT??process.cwd(),t={sources:[{path:e,excludePatterns:[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],serverName:`knowledge-base`,indexing:{chunkSize:1500,chunkOverlap:200,minChunkSize:100},embedding:{model:`mixedbread-ai/mxbai-embed-large-v1`,dimensions:1024},store:{backend:`lancedb`,path:r(e,a.data)},curated:{path:r(e,a.aiCurated)}};return g(t,e),t}function g(e,t){if(!c())return;let n=t,i=l(n);e.store.path=r(s(i.partition)),e.curated||={path:r(n,a.aiCurated)}}function _(e,t){f.info(`Reconfiguring for workspace root`,{workspaceRoot:t}),e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],e.store.path=r(t,a.data),e.curated={path:r(t,a.aiCurated)},g(e,t)}export{m as loadConfig,_ as reconfigureForWorkspace};
@@ -1 +1 @@
1
- import{loadConfig as e}from"./config.js";import{checkForUpdates as t}from"./version-check.js";import{ALL_TOOL_NAMES as n,createLazyServer as r,createMcpServer as i,initializeKnowledgeBase as a}from"./server.js";import{createLogger as o,serializeError as s}from"../../core/dist/index.js";import{parseArgs as c}from"node:util";const l=o(`server`),{values:u}=c({options:{transport:{type:`string`,default:process.env.KB_TRANSPORT??`stdio`},port:{type:`string`,default:process.env.KB_PORT??`3210`}}});async function d(){process.on(`unhandledRejection`,e=>{l.error(`Unhandled rejection`,s(e))}),l.info(`Starting MCP Knowledge Base server`);let o=e();if(l.info(`Config loaded`,{sourceCount:o.sources.length,storePath:o.store.path}),t(),u.transport===`http`){let{StreamableHTTPServerTransport:e}=await import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),t=(await import(`express`)).default,r=await a(o),c=i(r,o);l.info(`MCP server configured`,{toolCount:n.length,resourceCount:2});let d=t();d.use(t.json()),d.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.KB_CORS_ORIGIN??`*`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),d.get(`/health`,(e,t)=>{t.json({status:`ok`})}),d.post(`/mcp`,async(t,n)=>{try{let r=new e({sessionIdGenerator:void 0});await c.connect(r),await r.handleRequest(t,n,t.body),n.on(`close`,()=>{r.close()})}catch(e){l.error(`MCP handler error`,s(e)),n.headersSent||n.status(500).json({jsonrpc:`2.0`,error:{code:-32603,message:`Internal server error`},id:null})}}),d.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),d.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let f=Number(u.port),p=d.listen(f,()=>{l.info(`MCP server listening`,{url:`http://0.0.0.0:${f}/mcp`,port:f}),(async()=>{try{let e=o.sources.map(e=>e.path).join(`, `);l.info(`Running initial index`,{sourcePaths:e});let t=await r.indexer.index(o,e=>{e.phase===`crawling`||e.phase===`done`||e.phase===`chunking`&&e.currentFile&&l.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile})});l.info(`Initial index complete`,{filesProcessed:t.filesProcessed,filesSkipped:t.filesSkipped,chunksCreated:t.chunksCreated,durationMs:t.durationMs});try{let e=await r.curated.reindexAll();l.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){l.error(`Curated re-index failed`,s(e))}}catch(e){l.error(`Initial index failed; will retry on kb_reindex`,s(e))}})().catch(e=>l.error(`Initial index failed`,s(e)))}),m=async e=>{l.info(`Shutdown signal received`,{signal:e}),p.close(),await c.close(),await r.graphStore.close().catch(()=>{}),await r.store.close(),await r.embedder.shutdown(),process.exit(0)};process.on(`SIGINT`,()=>m(`SIGINT`)),process.on(`SIGTERM`,()=>m(`SIGTERM`))}else{let{server:e,ready:t,runInitialIndex:n}=r(o),{StdioServerTransport:i}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),a=new i;await e.connect(a),l.info(`MCP server started`,{transport:`stdio`}),t.catch(e=>{l.error(`Initialization failed`,s(e)),process.exit(1)}),process.env.KB_AUTO_INDEX===`false`?l.warn(`Auto-index disabled; use kb_reindex to index manually`):n().catch(e=>l.error(`Initial index failed`,s(e)))}}d().catch(e=>{l.error(`Fatal error`,s(e)),process.exit(1)});export{};
1
+ import{loadConfig as e,reconfigureForWorkspace as t}from"./config.js";import{checkForUpdates as n}from"./version-check.js";import{ALL_TOOL_NAMES as r,createLazyServer as i,createMcpServer as a,initializeKnowledgeBase as o}from"./server.js";import{fileURLToPath as s}from"node:url";import{createLogger as c,serializeError as l}from"../../core/dist/index.js";import{parseArgs as u}from"node:util";const d=c(`server`),{values:f}=u({options:{transport:{type:`string`,default:process.env.KB_TRANSPORT??`stdio`},port:{type:`string`,default:process.env.KB_PORT??`3210`}}});async function p(){process.on(`unhandledRejection`,e=>{d.error(`Unhandled rejection`,l(e))}),d.info(`Starting MCP Knowledge Base server`);let c=e();if(d.info(`Config loaded`,{sourceCount:c.sources.length,storePath:c.store.path}),n(),f.transport===`http`){let{StreamableHTTPServerTransport:e}=await import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),t=(await import(`express`)).default,n=await o(c),i=a(n,c);d.info(`MCP server configured`,{toolCount:r.length,resourceCount:2});let s=t();s.use(t.json()),s.use((e,t,n)=>{if(t.setHeader(`Access-Control-Allow-Origin`,process.env.KB_CORS_ORIGIN??`*`),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization`),e.method===`OPTIONS`){t.status(204).end();return}n()}),s.get(`/health`,(e,t)=>{t.json({status:`ok`})}),s.post(`/mcp`,async(t,n)=>{try{let r=new e({sessionIdGenerator:void 0});await i.connect(r),await r.handleRequest(t,n,t.body),n.on(`close`,()=>{r.close()})}catch(e){d.error(`MCP handler error`,l(e)),n.headersSent||n.status(500).json({jsonrpc:`2.0`,error:{code:-32603,message:`Internal server error`},id:null})}}),s.get(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))}),s.delete(`/mcp`,(e,t)=>{t.writeHead(405).end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32e3,message:`Method not allowed.`},id:null}))});let u=Number(f.port),p=s.listen(u,()=>{d.info(`MCP server listening`,{url:`http://0.0.0.0:${u}/mcp`,port:u}),(async()=>{try{let e=c.sources.map(e=>e.path).join(`, `);d.info(`Running initial index`,{sourcePaths:e});let t=await n.indexer.index(c,e=>{e.phase===`crawling`||e.phase===`done`||e.phase===`chunking`&&e.currentFile&&d.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile})});d.info(`Initial index complete`,{filesProcessed:t.filesProcessed,filesSkipped:t.filesSkipped,chunksCreated:t.chunksCreated,durationMs:t.durationMs});try{let e=await n.curated.reindexAll();d.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){d.error(`Curated re-index failed`,l(e))}}catch(e){d.error(`Initial index failed; will retry on kb_reindex`,l(e))}})().catch(e=>d.error(`Initial index failed`,l(e)))}),m=async e=>{d.info(`Shutdown signal received`,{signal:e}),p.close(),await i.close(),await n.graphStore.close().catch(()=>{}),await n.store.close(),await n.embedder.shutdown(),process.exit(0)};process.on(`SIGINT`,()=>m(`SIGINT`)),process.on(`SIGTERM`,()=>m(`SIGTERM`))}else{let{server:e,startInit:n,ready:r,runInitialIndex:a}=i(c),{StdioServerTransport:o}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),u=new o;await e.connect(u),d.info(`MCP server started`,{transport:`stdio`});try{let n=await e.server.listRoots();if(n.roots.length>0){let e=n.roots[0].uri,r=e.startsWith(`file://`)?s(e):e;d.info(`MCP roots resolved`,{rootUri:e,rootPath:r,rootCount:n.roots.length}),t(c,r)}else d.warn(`No MCP roots returned by client; using cwd fallback`,{cwd:process.cwd()})}catch(e){d.warn(`MCP roots/list not supported by client; using cwd fallback`,{cwd:process.cwd(),...l(e)})}n(),r.catch(e=>{d.error(`Initialization failed`,l(e)),process.exit(1)}),process.env.KB_AUTO_INDEX===`false`?d.warn(`Auto-index disabled; use kb_reindex to index manually`):a().catch(e=>d.error(`Initial index failed`,l(e)))}}p().catch(e=>{d.error(`Fatal error`,l(e)),process.exit(1)});export{};
@@ -35,7 +35,8 @@ declare function createServer(config: KBConfig): Promise<{
35
35
  }>;
36
36
  declare const ALL_TOOL_NAMES: readonly ["analyze_dependencies", "analyze_diagram", "analyze_entry_points", "analyze_patterns", "analyze_structure", "analyze_symbols", "audit", "batch", "blast_radius", "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", "process", "produce_knowledge", "queue", "read", "regex_test", "reindex", "remember", "rename", "replay", "schema_validate", "scope_map", "search", "snippet", "stash", "status", "stratum_card", "symbol", "test_run", "time", "trace", "update", "watch", "web_fetch", "web_search", "workset"];
37
37
  declare function createLazyServer(config: KBConfig): {
38
- server: McpServer;
38
+ server: McpServer; /** Call after MCP roots are resolved (or fallback decided) to start heavy init. */
39
+ startInit: () => void;
39
40
  ready: Promise<void>;
40
41
  runInitialIndex: () => Promise<void>;
41
42
  };
@@ -1 +1 @@
1
- import{CuratedKnowledgeManager as e}from"./curated-manager.js";import{installReplayInterceptor as t}from"./replay-interceptor.js";import{registerResources as n}from"./resources/resources.js";import{registerAnalyzeDependenciesTool as r,registerAnalyzeDiagramTool as i,registerAnalyzeEntryPointsTool as a,registerAnalyzePatternsTool as o,registerAnalyzeStructureTool as s,registerAnalyzeSymbolsTool as c,registerBlastRadiusTool as l}from"./tools/analyze.tools.js";import{registerAuditTool as u}from"./tools/audit.tool.js";import{initBridgeComponents as d,registerErPullTool as f,registerErPushTool as p,registerErSyncStatusTool as m}from"./tools/bridge.tools.js";import{registerErEvolveReviewTool as h}from"./tools/evolution.tools.js";import{registerDigestTool as ee,registerEvidenceMapTool as te,registerForgeClassifyTool as ne,registerForgeGroundTool as re,registerStratumCardTool as ie}from"./tools/forge.tools.js";import{registerForgetTool as ae}from"./tools/forget.tool.js";import{registerGraphTool as oe}from"./tools/graph.tool.js";import{registerListTool as se}from"./tools/list.tool.js";import{registerLookupTool as ce}from"./tools/lookup.tool.js";import{registerOnboardTool as le}from"./tools/onboard.tool.js";import{registerErUpdatePolicyTool as ue}from"./tools/policy.tools.js";import{registerProduceKnowledgeTool as g}from"./tools/produce.tool.js";import{registerReadTool as _}from"./tools/read.tool.js";import{registerReindexTool as v}from"./tools/reindex.tool.js";import{registerRememberTool as y}from"./tools/remember.tool.js";import{registerReplayTool as b}from"./tools/replay.tool.js";import{registerSearchTool as x}from"./tools/search.tool.js";import{registerStatusTool as S}from"./tools/status.tool.js";import{registerBatchTool as C,registerCheckTool as w,registerCheckpointTool as T,registerCodemodTool as E,registerCompactTool as D,registerDataTransformTool as O,registerDeadSymbolsTool as k,registerDelegateTool as A,registerDiffParseTool as j,registerEvalTool as M,registerFileSummaryTool as N,registerFindTool as P,registerGitContextTool as F,registerGuideTool as I,registerHealthTool as L,registerLaneTool as R,registerParseOutputTool as z,registerProcessTool as B,registerQueueTool as V,registerRenameTool as H,registerScopeMapTool as U,registerStashTool as de,registerSymbolTool as fe,registerTestRunTool as pe,registerTraceTool as me,registerWatchTool as he,registerWebFetchTool as ge,registerWorksetTool as _e}from"./tools/toolkit.tools.js";import{registerUpdateTool as ve}from"./tools/update.tool.js";import{registerChangelogTool as ye,registerEncodeTool as be,registerEnvTool as xe,registerHttpTool as Se,registerMeasureTool as Ce,registerRegexTestTool as we,registerSchemaValidateTool as Te,registerSnippetTool as Ee,registerTimeTool as De,registerWebSearchTool as Oe}from"./tools/utility.tools.js";import{getCurrentVersion as W}from"./version-check.js";import{existsSync as ke,statSync as Ae}from"node:fs";import{resolve as je}from"node:path";import{KB_PATHS as Me,createLogger as Ne,serializeError as G}from"../../core/dist/index.js";import{initializeWasm as Pe}from"../../chunker/dist/index.js";import{OnnxEmbedder as Fe}from"../../embeddings/dist/index.js";import{EvolutionCollector as Ie,PolicyStore as Le}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Re,IncrementalIndexer as ze}from"../../indexer/dist/index.js";import{SqliteGraphStore as Be,createStore as Ve}from"../../store/dist/index.js";import{FileCache as K}from"../../tools/dist/index.js";import{McpServer as q}from"@modelcontextprotocol/sdk/server/mcp.js";const J=Ne(`server`);async function Y(t){J.info(`Initializing knowledge base components`);let n=new Fe({model:t.embedding.model,dimensions:t.embedding.dimensions});await n.initialize(),J.info(`Embedder loaded`,{modelId:n.modelId,dimensions:n.dimensions});let r=await Ve({backend:t.store.backend,path:t.store.path});await r.initialize(),J.info(`Store initialized`);let i=new ze(n,r),a=new Re(t.store.path);a.load(),i.setHashCache(a);let o=t.curated.path,s=new e(o,r,n),c=new Be({path:t.store.path});await c.initialize(),J.info(`Graph store initialized`),i.setGraphStore(c),await Pe()?J.info(`WASM tree-sitter enabled for AST analysis`):J.warn(`WASM tree-sitter not available; analyzers will use regex fallback`);let l=d(t.er),u=l?new Le(t.curated.path):void 0;u&&J.info(`Policy store initialized`,{ruleCount:u.getRules().length});let f=l?new Ie:void 0,p=je(process.cwd(),Me.aiKb),m=ke(p),h;if(m)try{h=Ae(p).mtime.toISOString()}catch{}return J.info(`Onboard state detected`,{onboardComplete:m,onboardTimestamp:h}),{embedder:n,store:r,indexer:i,curated:s,graphStore:c,fileCache:new K,bridge:l,policyStore:u,evolutionCollector:f,onboardComplete:m,onboardTimestamp:h}}function X(e,t){let n=new q({name:t.serverName??`knowledge-base`,version:W()});return Z(n,e,t),n}function Z(e,d,W){t(e),x(e,d.embedder,d.store,d.graphStore,d.bridge,d.evolutionCollector),ce(e,d.store),S(e,d.store,d.graphStore,d.curated,{onboardComplete:d.onboardComplete,onboardTimestamp:d.onboardTimestamp}),v(e,d.indexer,W,d.curated,d.store),y(e,d.curated,d.policyStore,d.evolutionCollector),ve(e,d.curated),ae(e,d.curated),_(e,d.curated),se(e,d.curated),s(e,d.store,d.embedder),r(e,d.store,d.embedder),c(e,d.store,d.embedder),o(e,d.store,d.embedder),a(e,d.store,d.embedder),i(e,d.store,d.embedder),l(e,d.store,d.embedder,d.graphStore),g(e),le(e,d.store,d.embedder),oe(e,d.graphStore),u(e,d.store,d.embedder),D(e,d.embedder,d.fileCache),U(e,d.embedder,d.store),P(e,d.embedder,d.store),z(e),_e(e),w(e),C(e,d.embedder,d.store),fe(e,d.embedder,d.store,d.graphStore),M(e),pe(e),de(e),F(e),j(e),H(e),E(e),N(e,d.fileCache),T(e),O(e),me(e,d.embedder,d.store),B(e),he(e),k(e,d.embedder,d.store),A(e),L(e),R(e),V(e),ge(e),I(e),te(e),ee(e,d.embedder),ne(e),ie(e,d.embedder,d.fileCache),re(e,d.embedder,d.store),Oe(e),Se(e),we(e),be(e),Ce(e),ye(e),Te(e),Ee(e),xe(e),De(e),d.bridge&&(p(e,d.bridge,d.evolutionCollector),f(e,d.bridge),m(e,d.bridge)),d.policyStore&&ue(e,d.policyStore),d.evolutionCollector&&h(e,d.evolutionCollector),n(e,d.store),b(e)}async function He(e){let t=await Y(e),n=X(t,e);J.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);J.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&&J.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&J.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});J.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){J.warn(`FTS index creation failed`,G(e))}try{let e=await t.curated.reindexAll();J.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){J.error(`Curated re-index failed`,G(e))}}catch(e){J.error(`Initial index failed; will retry on kb_reindex`,G(e))}},i=async()=>{J.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{J.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const Ue=new Set(`batch.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.process.queue.read.regex_test.reindex.remember.rename.replay.schema_validate.scope_map.snippet.stash.status.stratum_card.test_run.time.update.forget.list.watch.web_fetch.web_search.workset`.split(`.`)),Q=5e3,$=`analyze_dependencies.analyze_diagram.analyze_entry_points.analyze_patterns.analyze_structure.analyze_symbols.audit.batch.blast_radius.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.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.schema_validate.scope_map.search.snippet.stash.status.stratum_card.symbol.test_run.time.trace.update.watch.web_fetch.web_search.workset`.split(`.`);function We(e){let t=new q({name:e.serverName??`knowledge-base`,version:W()}),n=t.sendToolListChanged.bind(t);t.sendToolListChanged=()=>{};let r=$.map(e=>t.registerTool(e,{description:`${e} (initializing...)`,inputSchema:{}},async()=>({content:[{type:`text`,text:`KB is still initializing, please retry in a few seconds.`}]})));t.sendToolListChanged=n;let i=t.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`}]})),a,o=new Promise(e=>{a=e}),s=(async()=>{let n=await Y(e),o=t.sendToolListChanged.bind(t);t.sendToolListChanged=()=>{};for(let e of r)e.remove();i.remove(),Z(t,n,e),t.sendToolListChanged=o,t.sendToolListChanged();let s=t._registeredTools??{};for(let[e,t]of Object.entries(s)){if(Ue.has(e))continue;let r=t.handler;t.handler=async(...t)=>{if(!n.indexer.isIndexing)return r(...t);let i=new Promise(t=>setTimeout(()=>t({content:[{type:`text`,text:`⏳ KB is re-indexing. The tool "${e}" timed out waiting for index data (${Q/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),Q));return Promise.race([r(...t),i])}}let c=Object.keys(s).length;c!==$.length&&J.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:c}),J.info(`MCP server configured`,{toolCount:$.length,resourceCount:2}),a?.(n)})(),c=async()=>{let t=await o;try{let n=e.sources.map(e=>e.path).join(`, `);J.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&&J.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&J.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});J.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){J.warn(`FTS index creation failed`,G(e))}try{let e=await t.curated.reindexAll();J.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){J.error(`Curated re-index failed`,G(e))}}catch(e){J.error(`Initial index failed; will retry on kb_reindex`,G(e))}},l=process.ppid,u=setInterval(()=>{try{process.kill(l,0)}catch{J.info(`Parent process died; shutting down`,{parentPid:l}),clearInterval(u),o.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 u.unref(),{server:t,ready:s,runInitialIndex:c}}export{$ as ALL_TOOL_NAMES,We as createLazyServer,X as createMcpServer,He as createServer,Y as initializeKnowledgeBase,Z as registerMcpTools};
1
+ import{CuratedKnowledgeManager as e}from"./curated-manager.js";import{installReplayInterceptor as t}from"./replay-interceptor.js";import{registerResources as n}from"./resources/resources.js";import{registerAnalyzeDependenciesTool as r,registerAnalyzeDiagramTool as i,registerAnalyzeEntryPointsTool as a,registerAnalyzePatternsTool as o,registerAnalyzeStructureTool as s,registerAnalyzeSymbolsTool as c,registerBlastRadiusTool as l}from"./tools/analyze.tools.js";import{registerAuditTool as u}from"./tools/audit.tool.js";import{initBridgeComponents as d,registerErPullTool as f,registerErPushTool as p,registerErSyncStatusTool as m}from"./tools/bridge.tools.js";import{registerErEvolveReviewTool as h}from"./tools/evolution.tools.js";import{registerDigestTool as ee,registerEvidenceMapTool as te,registerForgeClassifyTool as ne,registerForgeGroundTool as re,registerStratumCardTool as ie}from"./tools/forge.tools.js";import{registerForgetTool as ae}from"./tools/forget.tool.js";import{registerGraphTool as oe}from"./tools/graph.tool.js";import{registerListTool as se}from"./tools/list.tool.js";import{registerLookupTool as ce}from"./tools/lookup.tool.js";import{registerOnboardTool as le}from"./tools/onboard.tool.js";import{registerErUpdatePolicyTool as ue}from"./tools/policy.tools.js";import{registerProduceKnowledgeTool as g}from"./tools/produce.tool.js";import{registerReadTool as _}from"./tools/read.tool.js";import{registerReindexTool as v}from"./tools/reindex.tool.js";import{registerRememberTool as y}from"./tools/remember.tool.js";import{registerReplayTool as b}from"./tools/replay.tool.js";import{registerSearchTool as x}from"./tools/search.tool.js";import{registerStatusTool as S}from"./tools/status.tool.js";import{registerBatchTool as C,registerCheckTool as w,registerCheckpointTool as T,registerCodemodTool as E,registerCompactTool as D,registerDataTransformTool as O,registerDeadSymbolsTool as k,registerDelegateTool as A,registerDiffParseTool as j,registerEvalTool as M,registerFileSummaryTool as N,registerFindTool as P,registerGitContextTool as F,registerGuideTool as I,registerHealthTool as L,registerLaneTool as R,registerParseOutputTool as z,registerProcessTool as B,registerQueueTool as V,registerRenameTool as H,registerScopeMapTool as U,registerStashTool as de,registerSymbolTool as fe,registerTestRunTool as pe,registerTraceTool as me,registerWatchTool as he,registerWebFetchTool as ge,registerWorksetTool as _e}from"./tools/toolkit.tools.js";import{registerUpdateTool as ve}from"./tools/update.tool.js";import{registerChangelogTool as ye,registerEncodeTool as be,registerEnvTool as xe,registerHttpTool as Se,registerMeasureTool as Ce,registerRegexTestTool as we,registerSchemaValidateTool as Te,registerSnippetTool as Ee,registerTimeTool as De,registerWebSearchTool as Oe}from"./tools/utility.tools.js";import{getCurrentVersion as W}from"./version-check.js";import{existsSync as ke,statSync as Ae}from"node:fs";import{resolve as je}from"node:path";import{KB_PATHS as Me,createLogger as Ne,serializeError as G}from"../../core/dist/index.js";import{initializeWasm as Pe}from"../../chunker/dist/index.js";import{OnnxEmbedder as Fe}from"../../embeddings/dist/index.js";import{EvolutionCollector as Ie,PolicyStore as Le}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Re,IncrementalIndexer as ze}from"../../indexer/dist/index.js";import{SqliteGraphStore as Be,createStore as Ve}from"../../store/dist/index.js";import{FileCache as K}from"../../tools/dist/index.js";import{McpServer as q}from"@modelcontextprotocol/sdk/server/mcp.js";const J=Ne(`server`);async function Y(t){J.info(`Initializing knowledge base components`);let n=new Fe({model:t.embedding.model,dimensions:t.embedding.dimensions});await n.initialize(),J.info(`Embedder loaded`,{modelId:n.modelId,dimensions:n.dimensions});let r=await Ve({backend:t.store.backend,path:t.store.path});await r.initialize(),J.info(`Store initialized`);let i=new ze(n,r),a=new Re(t.store.path);a.load(),i.setHashCache(a);let o=t.curated.path,s=new e(o,r,n),c=new Be({path:t.store.path});await c.initialize(),J.info(`Graph store initialized`),i.setGraphStore(c),await Pe()?J.info(`WASM tree-sitter enabled for AST analysis`):J.warn(`WASM tree-sitter not available; analyzers will use regex fallback`);let l=d(t.er),u=l?new Le(t.curated.path):void 0;u&&J.info(`Policy store initialized`,{ruleCount:u.getRules().length});let f=l?new Ie:void 0,p=je(t.sources[0]?.path??process.cwd(),Me.aiKb),m=ke(p),h;if(m)try{h=Ae(p).mtime.toISOString()}catch{}return J.info(`Onboard state detected`,{onboardComplete:m,onboardTimestamp:h}),{embedder:n,store:r,indexer:i,curated:s,graphStore:c,fileCache:new K,bridge:l,policyStore:u,evolutionCollector:f,onboardComplete:m,onboardTimestamp:h}}function X(e,t){let n=new q({name:t.serverName??`knowledge-base`,version:W()});return Z(n,e,t),n}function Z(e,d,W){t(e),x(e,d.embedder,d.store,d.graphStore,d.bridge,d.evolutionCollector),ce(e,d.store),S(e,d.store,d.graphStore,d.curated,{onboardComplete:d.onboardComplete,onboardTimestamp:d.onboardTimestamp}),v(e,d.indexer,W,d.curated,d.store),y(e,d.curated,d.policyStore,d.evolutionCollector),ve(e,d.curated),ae(e,d.curated),_(e,d.curated),se(e,d.curated),s(e,d.store,d.embedder),r(e,d.store,d.embedder),c(e,d.store,d.embedder),o(e,d.store,d.embedder),a(e,d.store,d.embedder),i(e,d.store,d.embedder),l(e,d.store,d.embedder,d.graphStore),g(e),le(e,d.store,d.embedder),oe(e,d.graphStore),u(e,d.store,d.embedder),D(e,d.embedder,d.fileCache),U(e,d.embedder,d.store),P(e,d.embedder,d.store),z(e),_e(e),w(e),C(e,d.embedder,d.store),fe(e,d.embedder,d.store,d.graphStore),M(e),pe(e),de(e),F(e),j(e),H(e),E(e),N(e,d.fileCache),T(e),O(e),me(e,d.embedder,d.store),B(e),he(e),k(e,d.embedder,d.store),A(e),L(e),R(e),V(e),ge(e),I(e),te(e),ee(e,d.embedder),ne(e),ie(e,d.embedder,d.fileCache),re(e,d.embedder,d.store),Oe(e),Se(e),we(e),be(e),Ce(e),ye(e),Te(e),Ee(e),xe(e),De(e),d.bridge&&(p(e,d.bridge,d.evolutionCollector),f(e,d.bridge),m(e,d.bridge)),d.policyStore&&ue(e,d.policyStore),d.evolutionCollector&&h(e,d.evolutionCollector),n(e,d.store),b(e)}async function He(e){let t=await Y(e),n=X(t,e);J.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);J.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&&J.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&J.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});J.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){J.warn(`FTS index creation failed`,G(e))}try{let e=await t.curated.reindexAll();J.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){J.error(`Curated re-index failed`,G(e))}}catch(e){J.error(`Initial index failed; will retry on kb_reindex`,G(e))}},i=async()=>{J.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{J.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const Ue=new Set(`batch.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.process.queue.read.regex_test.reindex.remember.rename.replay.schema_validate.scope_map.snippet.stash.status.stratum_card.test_run.time.update.forget.list.watch.web_fetch.web_search.workset`.split(`.`)),Q=5e3,$=`analyze_dependencies.analyze_diagram.analyze_entry_points.analyze_patterns.analyze_structure.analyze_symbols.audit.batch.blast_radius.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.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.schema_validate.scope_map.search.snippet.stash.status.stratum_card.symbol.test_run.time.trace.update.watch.web_fetch.web_search.workset`.split(`.`);function We(e){let t=new q({name:e.serverName??`knowledge-base`,version:W()}),n=t.sendToolListChanged.bind(t);t.sendToolListChanged=()=>{};let r=$.map(e=>t.registerTool(e,{description:`${e} (initializing...)`,inputSchema:{}},async()=>({content:[{type:`text`,text:`KB is still initializing, please retry in a few seconds.`}]})));t.sendToolListChanged=n;let i=t.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`}]})),a,o=new Promise(e=>{a=e}),s,c=new Promise(e=>{s=e}),l=()=>s?.(),u=(async()=>{await c;let n=await Y(e),o=t.sendToolListChanged.bind(t);t.sendToolListChanged=()=>{};for(let e of r)e.remove();i.remove(),Z(t,n,e),t.sendToolListChanged=o,t.sendToolListChanged();let s=t._registeredTools??{};for(let[e,t]of Object.entries(s)){if(Ue.has(e))continue;let r=t.handler;t.handler=async(...t)=>{if(!n.indexer.isIndexing)return r(...t);let i=new Promise(t=>setTimeout(()=>t({content:[{type:`text`,text:`⏳ KB is re-indexing. The tool "${e}" timed out waiting for index data (${Q/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),Q));return Promise.race([r(...t),i])}}let l=Object.keys(s).length;l!==$.length&&J.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:l}),J.info(`MCP server configured`,{toolCount:$.length,resourceCount:2}),a?.(n)})(),d=async()=>{let t=await o;try{let n=e.sources.map(e=>e.path).join(`, `);J.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&&J.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&J.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});J.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){J.warn(`FTS index creation failed`,G(e))}try{let e=await t.curated.reindexAll();J.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){J.error(`Curated re-index failed`,G(e))}}catch(e){J.error(`Initial index failed; will retry on kb_reindex`,G(e))}},f=process.ppid,p=setInterval(()=>{try{process.kill(f,0)}catch{J.info(`Parent process died; shutting down`,{parentPid:f}),clearInterval(p),o.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 p.unref(),{server:t,startInit:l,ready:u,runInitialIndex:d}}export{$ as ALL_TOOL_NAMES,We as createLazyServer,X as createMcpServer,He as createServer,Y as initializeKnowledgeBase,Z as registerMcpTools};