@vpxa/kb 0.1.11 → 0.1.12

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.11",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- import{parseArgs as f}from"node:util";import{loadConfig as m}from"./config.js";import{createLazyServer as w,createMcpServer as x,initializeKnowledgeBase as g}from"./server.js";const{values:h}=f({options:{transport:{type:"string",default:process.env.KB_TRANSPORT??"stdio"},port:{type:"string",default:process.env.KB_PORT??"3210"}}});async function I(){console.error("[KB] Starting MCP Knowledge Base server...");const t=m();if(console.error(`[KB] Config loaded: ${t.sources.length} source(s), store at ${t.store.path}`),h.transport==="http"){const{StreamableHTTPServerTransport:l}=await import("@modelcontextprotocol/sdk/server/streamableHttp.js"),a=(await import("express")).default,i=await g(t),c=x(i,t);console.error("[KB] MCP server configured with 46 tools and 2 resources");const n=a();n.use(a.json()),n.use((s,e,o)=>{if(e.setHeader("Access-Control-Allow-Origin",process.env.KB_CORS_ORIGIN??"*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, DELETE, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),s.method==="OPTIONS"){e.status(204).end();return}o()}),n.get("/health",(s,e)=>{e.json({status:"ok"})}),n.post("/mcp",async(s,e)=>{try{const o=new l({sessionIdGenerator:void 0});await c.connect(o),await o.handleRequest(s,e,s.body),e.on("close",()=>{o.close()})}catch(o){console.error("[KB] MCP handler error:",o),e.headersSent||e.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}}),n.get("/mcp",(s,e)=>{e.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}),n.delete("/mcp",(s,e)=>{e.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))});const d=Number(h.port),p=n.listen(d,()=>{console.error(`[KB] MCP server listening on http://0.0.0.0:${d}/mcp`),(async()=>{try{const e=t.sources.map(r=>r.path).join(", ");console.error(`[KB] Running initial index for sources: ${e}`);const o=await i.indexer.index(t,r=>{r.phase==="crawling"||r.phase==="done"||r.phase==="chunking"&&r.currentFile&&console.error(`[KB] [${r.filesProcessed+1}/${r.filesTotal}] ${r.currentFile}`)});console.error(`[KB] Indexed ${o.filesProcessed} files (${o.filesSkipped} skipped, ${o.chunksCreated} chunks) in ${(o.durationMs/1e3).toFixed(1)}s`);try{const r=await i.curated.reindexAll();console.error(`[KB] Curated re-index: ${r.indexed} entries restored to vector store`)}catch(r){console.error("[KB] Curated re-index failed:",r)}}catch(e){console.error("[KB] Initial index failed (will retry on kb_reindex):",e)}})()}),u=async s=>{console.error(`[KB] ${s} received \u2014 shutting down...`),p.close(),await c.close(),await i.store.close(),await i.embedder.shutdown(),process.exit(0)};process.on("SIGINT",()=>u("SIGINT")),process.on("SIGTERM",()=>u("SIGTERM"))}else{const{server:l,ready:a,runInitialIndex:i}=w(t),{StdioServerTransport:c}=await import("@modelcontextprotocol/sdk/server/stdio.js"),n=new c;await l.connect(n),console.error("[KB] MCP server started (stdio)"),a.catch(p=>{console.error("[KB] Initialization failed:",p),process.exit(1)}),process.env.KB_AUTO_INDEX!=="false"?i():console.error("[KB] Auto-index disabled (KB_AUTO_INDEX=false). Use kb_reindex to index manually.")}}I().catch(t=>{console.error("[KB] Fatal error:",t),process.exit(1)});
1
+ import{parseArgs as m}from"node:util";import{loadConfig as f}from"./config.js";import{createLazyServer as w,createMcpServer as x,initializeKnowledgeBase as g}from"./server.js";import{checkForUpdates as I}from"./version-check.js";const{values:h}=m({options:{transport:{type:"string",default:process.env.KB_TRANSPORT??"stdio"},port:{type:"string",default:process.env.KB_PORT??"3210"}}});async function B(){console.error("[KB] Starting MCP Knowledge Base server...");const t=f();if(console.error(`[KB] Config loaded: ${t.sources.length} source(s), store at ${t.store.path}`),I(),h.transport==="http"){const{StreamableHTTPServerTransport:d}=await import("@modelcontextprotocol/sdk/server/streamableHttp.js"),a=(await import("express")).default,i=await g(t),c=x(i,t);console.error("[KB] MCP server configured with 46 tools and 2 resources");const n=a();n.use(a.json()),n.use((s,e,o)=>{if(e.setHeader("Access-Control-Allow-Origin",process.env.KB_CORS_ORIGIN??"*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, DELETE, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization"),s.method==="OPTIONS"){e.status(204).end();return}o()}),n.get("/health",(s,e)=>{e.json({status:"ok"})}),n.post("/mcp",async(s,e)=>{try{const o=new d({sessionIdGenerator:void 0});await c.connect(o),await o.handleRequest(s,e,s.body),e.on("close",()=>{o.close()})}catch(o){console.error("[KB] MCP handler error:",o),e.headersSent||e.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:"Internal server error"},id:null})}}),n.get("/mcp",(s,e)=>{e.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))}),n.delete("/mcp",(s,e)=>{e.writeHead(405).end(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}))});const l=Number(h.port),p=n.listen(l,()=>{console.error(`[KB] MCP server listening on http://0.0.0.0:${l}/mcp`),(async()=>{try{const e=t.sources.map(r=>r.path).join(", ");console.error(`[KB] Running initial index for sources: ${e}`);const o=await i.indexer.index(t,r=>{r.phase==="crawling"||r.phase==="done"||r.phase==="chunking"&&r.currentFile&&console.error(`[KB] [${r.filesProcessed+1}/${r.filesTotal}] ${r.currentFile}`)});console.error(`[KB] Indexed ${o.filesProcessed} files (${o.filesSkipped} skipped, ${o.chunksCreated} chunks) in ${(o.durationMs/1e3).toFixed(1)}s`);try{const r=await i.curated.reindexAll();console.error(`[KB] Curated re-index: ${r.indexed} entries restored to vector store`)}catch(r){console.error("[KB] Curated re-index failed:",r)}}catch(e){console.error("[KB] Initial index failed (will retry on kb_reindex):",e)}})()}),u=async s=>{console.error(`[KB] ${s} received \u2014 shutting down...`),p.close(),await c.close(),await i.store.close(),await i.embedder.shutdown(),process.exit(0)};process.on("SIGINT",()=>u("SIGINT")),process.on("SIGTERM",()=>u("SIGTERM"))}else{const{server:d,ready:a,runInitialIndex:i}=w(t),{StdioServerTransport:c}=await import("@modelcontextprotocol/sdk/server/stdio.js"),n=new c;await d.connect(n),console.error("[KB] MCP server started (stdio)"),a.catch(p=>{console.error("[KB] Initialization failed:",p),process.exit(1)}),process.env.KB_AUTO_INDEX!=="false"?i():console.error("[KB] Auto-index disabled (KB_AUTO_INDEX=false). Use kb_reindex to index manually.")}}B().catch(t=>{console.error("[KB] Fatal error:",t),process.exit(1)});
@@ -23,19 +23,6 @@ export declare function createServer(config: KBConfig): Promise<{
23
23
  runInitialIndex: () => Promise<void>;
24
24
  shutdown: () => Promise<void>;
25
25
  }>;
26
- /**
27
- * Create an MCP server for stdio mode with lazy initialization.
28
- *
29
- * The MCP SDK forbids registering capabilities after connect(), but
30
- * `setToolRequestHandlers()` (which registers the tools capability) is a
31
- * one-time init guarded by `_toolHandlersInitialized`. So we register a
32
- * temporary `status` tool before connect() to prime that flag, then after
33
- * heavy init completes we remove it and register all 64 real tools.
34
- * The SDK auto-sends `notifications/tools/list_changed` for each mutation.
35
- *
36
- * This lets the MCP handshake + initial tools/list complete in <1s
37
- * (vs 5-7s when blocking on ONNX model load).
38
- */
39
26
  export declare function createLazyServer(config: KBConfig): {
40
27
  server: McpServer;
41
28
  ready: Promise<void>;
@@ -1 +1 @@
1
- import{initializeTreeSitter as f}from"../../chunker/dist/index.js";import{OnnxEmbedder as x}from"../../embeddings/dist/index.js";import{IncrementalIndexer as w}from"../../indexer/dist/index.js";import{createStore as K,SqliteGraphStore as S}from"../../store/dist/index.js";import{McpServer as u}from"@modelcontextprotocol/sdk/server/mcp.js";import{CuratedKnowledgeManager as B}from"./curated-manager.js";import{installReplayInterceptor as y}from"./replay-interceptor.js";import{registerResources as C}from"./resources/resources.js";import{registerAnalyzeDependenciesTool as I,registerAnalyzeDiagramTool as P,registerAnalyzeEntryPointsTool as $,registerAnalyzePatternsTool as z,registerAnalyzeStructureTool as F,registerAnalyzeSymbolsTool as M,registerBlastRadiusTool as R}from"./tools/analyze.tools.js";import{registerDigestTool as E,registerEvidenceMapTool as A,registerForgeClassifyTool as G,registerForgeGroundTool as D,registerStratumCardTool as b}from"./tools/forge.tools.js";import{registerForgetTool as j}from"./tools/forget.tool.js";import{registerGraphTool as L}from"./tools/graph.tool.js";import{registerListTool as O}from"./tools/list.tool.js";import{registerLookupTool as W}from"./tools/lookup.tool.js";import{registerOnboardTool as H}from"./tools/onboard.tool.js";import{registerProduceKnowledgeTool as _}from"./tools/produce.tool.js";import{registerReadTool as q}from"./tools/read.tool.js";import{registerReindexTool as N}from"./tools/reindex.tool.js";import{registerRememberTool as Q}from"./tools/remember.tool.js";import{registerReplayTool as U}from"./tools/replay.tool.js";import{registerSearchTool as V}from"./tools/search.tool.js";import{registerStatusTool as J}from"./tools/status.tool.js";import{registerBatchTool as X,registerCheckpointTool as Y,registerCheckTool as Z,registerCodemodTool as k,registerCompactTool as v,registerDataTransformTool as ee,registerDeadSymbolsTool as oe,registerDelegateTool as re,registerDiffParseTool as te,registerEvalTool as ie,registerFileSummaryTool as ne,registerFindExamplesTool as se,registerFindTool as ae,registerGitContextTool as le,registerHealthTool as de,registerLaneTool as ce,registerParseOutputTool as me,registerProcessTool as pe,registerQueueTool as ge,registerRenameTool as ue,registerScopeMapTool as Te,registerStashTool as he,registerSymbolTool as fe,registerTestRunTool as xe,registerTraceTool as we,registerWatchTool as Ke,registerWebFetchTool as Se,registerWorksetTool as Be}from"./tools/toolkit.tools.js";import{registerUpdateTool as ye}from"./tools/update.tool.js";import{registerChangelogTool as Ce,registerEncodeTool as Ie,registerEnvTool as Pe,registerHttpTool as $e,registerMeasureTool as ze,registerRegexTestTool as Fe,registerSchemaValidateTool as Me,registerSnippetTool as Re,registerTimeTool as Ee,registerWebSearchTool as Ae}from"./tools/utility.tools.js";async function T(e){console.error("[KB] Initializing knowledge base components...");const o=new x({model:e.embedding.model,dimensions:e.embedding.dimensions});await o.initialize(),console.error(`[KB] Embedder loaded: ${o.modelId} (${o.dimensions}d)`);const i=await K({backend:e.store.backend,path:e.store.path});await i.initialize(),console.error("[KB] Store initialized");const d=new w(o,i),s=e.curated.path,c=new B(s,i,o),a=new S({path:e.store.path});await a.initialize(),console.error("[KB] Graph store initialized"),d.setGraphStore(a);const l=await f();return console.error(l?"[KB] Tree-sitter chunking enabled":"[KB] Tree-sitter not available \u2014 using regex-based code chunking"),{embedder:o,store:i,indexer:d,curated:c,graphStore:a}}function Ge(e,o){const i=new u({name:"kb",version:"0.1.0"});return h(i,e,o),i}function h(e,o,i){y(e),V(e,o.embedder,o.store,o.graphStore),W(e,o.store),J(e,o.store,o.graphStore),N(e,o.indexer,i,o.curated,o.store),Q(e,o.curated),ye(e,o.curated),j(e,o.curated),q(e,o.curated),O(e,o.curated),F(e,o.store,o.embedder),I(e,o.store,o.embedder),M(e,o.store,o.embedder),z(e,o.store,o.embedder),$(e,o.store,o.embedder),P(e,o.store,o.embedder),R(e,o.store,o.embedder),_(e),H(e,o.store,o.embedder),L(e,o.graphStore),v(e,o.embedder),Te(e,o.embedder,o.store),ae(e,o.embedder,o.store),me(e),Be(e),Z(e),X(e,o.embedder,o.store),fe(e,o.embedder,o.store),ie(e),xe(e),he(e),le(e),te(e),ue(e),k(e),ne(e),Y(e),ee(e),we(e,o.embedder,o.store),se(e,o.embedder,o.store),pe(e),Ke(e),oe(e,o.embedder,o.store),re(e),de(e),ce(e),ge(e),Se(e),A(e),E(e,o.embedder),G(e),b(e,o.embedder),D(e,o.embedder,o.store),Ae(e),$e(e),Fe(e),Ie(e),ze(e),Ce(e),Me(e),Re(e),Pe(e),Ee(e),C(e,o.store),U(e)}async function so(e){const o=await T(e),i=Ge(o,e);console.error("[KB] MCP server configured with 64 tools and 2 resources");const d=async()=>{try{const l=e.sources.map(r=>r.path).join(", ");console.error(`[KB] Running initial index for sources: ${l}`);const m=await o.indexer.index(e,r=>{r.phase==="crawling"||r.phase==="done"||(r.phase==="chunking"&&r.currentFile&&console.error(`[KB] [${r.filesProcessed+1}/${r.filesTotal}] ${r.currentFile}`),r.phase==="cleanup"&&console.error(`[KB] cleanup: removing ${r.filesTotal-r.filesProcessed} stale entries`))});console.error(`[KB] Indexed ${m.filesProcessed} files (${m.filesSkipped} skipped, ${m.chunksCreated} chunks) in ${(m.durationMs/1e3).toFixed(1)}s`);try{await o.store.createFtsIndex()}catch(r){console.error("[KB] FTS index creation failed (non-fatal):",r)}try{const r=await o.curated.reindexAll();console.error(`[KB] Curated re-index: ${r.indexed} entries restored to vector store`)}catch(r){console.error("[KB] Curated re-index failed:",r)}}catch(l){console.error("[KB] Initial index failed (will retry on kb_reindex):",l)}},s=async()=>{console.error("[KB] Shutting down..."),await o.graphStore.close().catch(()=>{}),await o.store.close(),process.exit(0)};process.on("SIGINT",s),process.on("SIGTERM",s);const c=process.ppid,a=setInterval(()=>{try{process.kill(c,0)}catch{console.error("[KB] Parent process died \u2014 orphan detected, shutting down..."),clearInterval(a),s()}},5e3);return a.unref(),{server:i,runInitialIndex:d,shutdown:s}}function ao(e){const o=new u({name:"kb",version:"0.1.0"}),i=o.registerTool("status",{description:"Knowledge base status (initializing...)",inputSchema:{}},async()=>({content:[{type:"text",text:"KB is still initializing, please retry in a few seconds."}]})),d=o.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"}]}));let s;const c=new Promise(n=>{s=n}),a=(async()=>{const n=await T(e);i.remove(),d.remove(),h(o,n,e),console.error("[KB] MCP server configured with 64 tools and 2 resources"),s?.(n)})(),l=async()=>{const n=await c;try{const g=e.sources.map(t=>t.path).join(", ");console.error(`[KB] Running initial index for sources: ${g}`);const p=await n.indexer.index(e,t=>{t.phase==="crawling"||t.phase==="done"||(t.phase==="chunking"&&t.currentFile&&console.error(`[KB] [${t.filesProcessed+1}/${t.filesTotal}] ${t.currentFile}`),t.phase==="cleanup"&&console.error(`[KB] cleanup: removing ${t.filesTotal-t.filesProcessed} stale entries`))});console.error(`[KB] Indexed ${p.filesProcessed} files (${p.filesSkipped} skipped, ${p.chunksCreated} chunks) in ${(p.durationMs/1e3).toFixed(1)}s`);try{await n.store.createFtsIndex()}catch(t){console.error("[KB] FTS index creation failed (non-fatal):",t)}try{const t=await n.curated.reindexAll();console.error(`[KB] Curated re-index: ${t.indexed} entries restored to vector store`)}catch(t){console.error("[KB] Curated re-index failed:",t)}}catch(g){console.error("[KB] Initial index failed (will retry on kb_reindex):",g)}},m=process.ppid,r=setInterval(()=>{try{process.kill(m,0)}catch{console.error("[KB] Parent process died \u2014 orphan detected, shutting down..."),clearInterval(r),c.then(n=>{n.graphStore.close().catch(()=>{}),n.store.close()}).catch(()=>{}),process.exit(0)}},5e3);return r.unref(),{server:o,ready:a,runInitialIndex:l}}export{ao as createLazyServer,Ge as createMcpServer,so as createServer,T as initializeKnowledgeBase,h as registerMcpTools};
1
+ import{initializeTreeSitter as x}from"../../chunker/dist/index.js";import{OnnxEmbedder as y}from"../../embeddings/dist/index.js";import{IncrementalIndexer as w}from"../../indexer/dist/index.js";import{createStore as K,SqliteGraphStore as S}from"../../store/dist/index.js";import{McpServer as h}from"@modelcontextprotocol/sdk/server/mcp.js";import{CuratedKnowledgeManager as B}from"./curated-manager.js";import{installReplayInterceptor as C}from"./replay-interceptor.js";import{registerResources as _}from"./resources/resources.js";import{registerAnalyzeDependenciesTool as I,registerAnalyzeDiagramTool as P,registerAnalyzeEntryPointsTool as z,registerAnalyzePatternsTool as $,registerAnalyzeStructureTool as M,registerAnalyzeSymbolsTool as F,registerBlastRadiusTool as R}from"./tools/analyze.tools.js";import{registerDigestTool as E,registerEvidenceMapTool as b,registerForgeClassifyTool as A,registerForgeGroundTool as G,registerStratumCardTool as D}from"./tools/forge.tools.js";import{registerForgetTool as L}from"./tools/forget.tool.js";import{registerGraphTool as O}from"./tools/graph.tool.js";import{registerListTool as j}from"./tools/list.tool.js";import{registerLookupTool as W}from"./tools/lookup.tool.js";import{registerOnboardTool as q}from"./tools/onboard.tool.js";import{registerProduceKnowledgeTool as H}from"./tools/produce.tool.js";import{registerReadTool as N}from"./tools/read.tool.js";import{registerReindexTool as Q}from"./tools/reindex.tool.js";import{registerRememberTool as U}from"./tools/remember.tool.js";import{registerReplayTool as V}from"./tools/replay.tool.js";import{registerSearchTool as J}from"./tools/search.tool.js";import{registerStatusTool as X}from"./tools/status.tool.js";import{registerBatchTool as Y,registerCheckpointTool as Z,registerCheckTool as k,registerCodemodTool as v,registerCompactTool as ee,registerDataTransformTool as oe,registerDeadSymbolsTool as re,registerDelegateTool as te,registerDiffParseTool as ie,registerEvalTool as ne,registerFileSummaryTool as se,registerFindExamplesTool as ae,registerFindTool as le,registerGitContextTool as de,registerHealthTool as ce,registerLaneTool as me,registerParseOutputTool as pe,registerProcessTool as ge,registerQueueTool as ue,registerRenameTool as he,registerScopeMapTool as fe,registerStashTool as Te,registerSymbolTool as xe,registerTestRunTool as ye,registerTraceTool as we,registerWatchTool as Ke,registerWebFetchTool as Se,registerWorksetTool as Be}from"./tools/toolkit.tools.js";import{registerUpdateTool as Ce}from"./tools/update.tool.js";import{registerChangelogTool as _e,registerEncodeTool as Ie,registerEnvTool as Pe,registerHttpTool as ze,registerMeasureTool as $e,registerRegexTestTool as Me,registerSchemaValidateTool as Fe,registerSnippetTool as Re,registerTimeTool as Ee,registerWebSearchTool as be}from"./tools/utility.tools.js";async function f(e){console.error("[KB] Initializing knowledge base components...");const o=new y({model:e.embedding.model,dimensions:e.embedding.dimensions});await o.initialize(),console.error(`[KB] Embedder loaded: ${o.modelId} (${o.dimensions}d)`);const n=await K({backend:e.store.backend,path:e.store.path});await n.initialize(),console.error("[KB] Store initialized");const d=new w(o,n),a=e.curated.path,c=new B(a,n,o),s=new S({path:e.store.path});await s.initialize(),console.error("[KB] Graph store initialized"),d.setGraphStore(s);const l=await x();return console.error(l?"[KB] Tree-sitter chunking enabled":"[KB] Tree-sitter not available \u2014 using regex-based code chunking"),{embedder:o,store:n,indexer:d,curated:c,graphStore:s}}function Ae(e,o){const n=new h({name:"kb",version:"0.1.0"});return T(n,e,o),n}function T(e,o,n){C(e),J(e,o.embedder,o.store,o.graphStore),W(e,o.store),X(e,o.store,o.graphStore),Q(e,o.indexer,n,o.curated,o.store),U(e,o.curated),Ce(e,o.curated),L(e,o.curated),N(e,o.curated),j(e,o.curated),M(e,o.store,o.embedder),I(e,o.store,o.embedder),F(e,o.store,o.embedder),$(e,o.store,o.embedder),z(e,o.store,o.embedder),P(e,o.store,o.embedder),R(e,o.store,o.embedder),H(e),q(e,o.store,o.embedder),O(e,o.graphStore),ee(e,o.embedder),fe(e,o.embedder,o.store),le(e,o.embedder,o.store),pe(e),Be(e),k(e),Y(e,o.embedder,o.store),xe(e,o.embedder,o.store),ne(e),ye(e),Te(e),de(e),ie(e),he(e),v(e),se(e),Z(e),oe(e),we(e,o.embedder,o.store),ae(e,o.embedder,o.store),ge(e),Ke(e),re(e,o.embedder,o.store),te(e),ce(e),me(e),ue(e),Se(e),b(e),E(e,o.embedder),A(e),D(e,o.embedder),G(e,o.embedder,o.store),be(e),ze(e),Me(e),Ie(e),$e(e),_e(e),Fe(e),Re(e),Pe(e),Ee(e),_(e,o.store),V(e)}async function lo(e){const o=await f(e),n=Ae(o,e);console.error("[KB] MCP server configured with 64 tools and 2 resources");const d=async()=>{try{const l=e.sources.map(r=>r.path).join(", ");console.error(`[KB] Running initial index for sources: ${l}`);const m=await o.indexer.index(e,r=>{r.phase==="crawling"||r.phase==="done"||(r.phase==="chunking"&&r.currentFile&&console.error(`[KB] [${r.filesProcessed+1}/${r.filesTotal}] ${r.currentFile}`),r.phase==="cleanup"&&console.error(`[KB] cleanup: removing ${r.filesTotal-r.filesProcessed} stale entries`))});console.error(`[KB] Indexed ${m.filesProcessed} files (${m.filesSkipped} skipped, ${m.chunksCreated} chunks) in ${(m.durationMs/1e3).toFixed(1)}s`);try{await o.store.createFtsIndex()}catch(r){console.error("[KB] FTS index creation failed (non-fatal):",r)}try{const r=await o.curated.reindexAll();console.error(`[KB] Curated re-index: ${r.indexed} entries restored to vector store`)}catch(r){console.error("[KB] Curated re-index failed:",r)}}catch(l){console.error("[KB] Initial index failed (will retry on kb_reindex):",l)}},a=async()=>{console.error("[KB] Shutting down..."),await o.graphStore.close().catch(()=>{}),await o.store.close(),process.exit(0)};process.on("SIGINT",a),process.on("SIGTERM",a);const c=process.ppid,s=setInterval(()=>{try{process.kill(c,0)}catch{console.error("[KB] Parent process died \u2014 orphan detected, shutting down..."),clearInterval(s),a()}},5e3);return s.unref(),{server:n,runInitialIndex:d,shutdown:a}}const Ge=["analyze_dependencies","analyze_diagram","analyze_entry_points","analyze_patterns","analyze_structure","analyze_symbols","batch","blast_radius","changelog","check","checkpoint","codemod","compact","data_transform","dead_symbols","delegate","diff_parse","digest","encode","env","eval","evidence_map","file_summary","find","find_examples","forge_classify","forge_ground","forget","git_context","graph","health","http","lane","list","lookup","measure","onboard","parse_output","process","produce_knowledge","queue","read","regex_test","reindex","remember","rename","replay_clear","replay_list","schema_validate","scope_map","search","snippet","stash","status","stratum_card","symbol","test_run","time","trace","update","watch","web_fetch","web_search","workset"];function co(e){const o=new h({name:"kb",version:"0.1.0"}),n="KB is still initializing, please retry in a few seconds.",d=Ge.map(i=>o.registerTool(i,{description:`${i} (initializing...)`,inputSchema:{}},async()=>({content:[{type:"text",text:n}]}))),a=o.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"}]}));let c;const s=new Promise(i=>{c=i}),l=(async()=>{const i=await f(e);for(const p of d)p.remove();a.remove(),T(o,i,e),console.error("[KB] MCP server configured with 64 tools and 2 resources"),c?.(i)})(),m=async()=>{const i=await s;try{const p=e.sources.map(t=>t.path).join(", ");console.error(`[KB] Running initial index for sources: ${p}`);const g=await i.indexer.index(e,t=>{t.phase==="crawling"||t.phase==="done"||(t.phase==="chunking"&&t.currentFile&&console.error(`[KB] [${t.filesProcessed+1}/${t.filesTotal}] ${t.currentFile}`),t.phase==="cleanup"&&console.error(`[KB] cleanup: removing ${t.filesTotal-t.filesProcessed} stale entries`))});console.error(`[KB] Indexed ${g.filesProcessed} files (${g.filesSkipped} skipped, ${g.chunksCreated} chunks) in ${(g.durationMs/1e3).toFixed(1)}s`);try{await i.store.createFtsIndex()}catch(t){console.error("[KB] FTS index creation failed (non-fatal):",t)}try{const t=await i.curated.reindexAll();console.error(`[KB] Curated re-index: ${t.indexed} entries restored to vector store`)}catch(t){console.error("[KB] Curated re-index failed:",t)}}catch(p){console.error("[KB] Initial index failed (will retry on kb_reindex):",p)}},r=process.ppid,u=setInterval(()=>{try{process.kill(r,0)}catch{console.error("[KB] Parent process died \u2014 orphan detected, shutting down..."),clearInterval(u),s.then(i=>{i.graphStore.close().catch(()=>{}),i.store.close()}).catch(()=>{}),process.exit(0)}},5e3);return u.unref(),{server:o,ready:l,runInitialIndex:m}}export{co as createLazyServer,Ae as createMcpServer,lo as createServer,f as initializeKnowledgeBase,T as registerMcpTools};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Non-blocking check for newer @vpxa/kb versions on npm.
3
+ * Logs a warning to stderr if the running version is outdated.
4
+ */
5
+ /**
6
+ * Check for a newer version on npm and log a warning if outdated.
7
+ * This is fire-and-forget — it never throws and never blocks startup.
8
+ */
9
+ export declare function checkForUpdates(): void;
10
+ //# sourceMappingURL=version-check.d.ts.map
@@ -0,0 +1 @@
1
+ import{readFileSync as s}from"node:fs";import{dirname as c,resolve as p}from"node:path";import{fileURLToPath as a}from"node:url";const u="@vpxa/kb",m=`https://registry.npmjs.org/${u}/latest`;function f(){const n=c(a(import.meta.url)),r=p(n,"..","..","..","package.json");try{return JSON.parse(s(r,"utf-8")).version??"0.0.0"}catch{return"0.0.0"}}function l(n,r){const t=n.split(".").map(Number),i=r.split(".").map(Number);for(let e=0;e<3;e++){const o=(t[e]??0)-(i[e]??0);if(o!==0)return o>0?1:-1}return 0}function h(){const n=f();fetch(m,{signal:AbortSignal.timeout(5e3)}).then(r=>{if(r.ok)return r.json()}).then(r=>{if(!r||typeof r!="object")return;const t=r.version;t&&l(n,t)<0&&console.error(`[KB] \u26A0 Update available: ${n} \u2192 ${t}. Run \`npx @vpxa/kb@${t} serve\` or update your mcp.json.`)}).catch(()=>{})}export{h as checkForUpdates};