@vpxa/kb 0.1.19 → 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.19",
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,9 +11,26 @@ 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"];
17
+ /**
18
+ * VS Code settings merged into each VS Code-family IDE's settings.json.
19
+ *
20
+ * - agentFilesLocations: Disables ~/.claude/agents so agents are only loaded
21
+ * from ~/.copilot/agents (our scaffold root) and workspace .github/agents/.
22
+ * Without this, VS Code discovers both locations causing duplicates with
23
+ * mismatched tool-name formats.
24
+ * - copilotMemory: Enables Copilot Memory so KB `remember` persists across sessions.
25
+ * - customAgentInSubagent: Enables custom agents as subagents — required for
26
+ * Orchestrator's multi-agent `runSubagent` workflow.
27
+ * - useNestedAgentsMdFiles: Agents reference _shared/*.md protocol files —
28
+ * without this, shared protocols are silently ignored.
29
+ * - useAgentSkills: Agents load SKILL.md files on demand (brainstorming,
30
+ * session-handoff, etc.) — without this, skills never activate.
31
+ * - switchAgent: Orchestrator uses the switchAgent tool to hand off to Plan —
32
+ * without this, agent switching is unavailable.
33
+ */
34
+ declare const VSCODE_SETTINGS: Record<string, unknown>;
18
35
  //#endregion
19
- export { MCP_SERVER_ENTRY, SERVER_NAME, SKILL_NAMES };
36
+ export { MCP_SERVER_ENTRY, SERVER_NAME, SKILL_NAMES, VSCODE_SETTINGS };
@@ -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`];export{t as MCP_SERVER_ENTRY,e as SERVER_NAME,n as SKILL_NAMES};
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};
@@ -32,6 +32,11 @@ declare function detectInstalledIdes(): UserLevelIdePath[];
32
32
  * Preserves all existing non-KB entries. Backs up existing file before writing.
33
33
  */
34
34
  declare function writeUserLevelMcpConfig(idePath: UserLevelIdePath, serverName: string, force?: boolean): void;
35
+ /**
36
+ * Merge KB-related settings into a VS Code-family IDE's settings.json.
37
+ * Preserves all existing settings. Only writes keys defined in VSCODE_SETTINGS.
38
+ */
39
+ declare function writeVscodeSettings(idePath: UserLevelIdePath, force?: boolean): void;
35
40
  /**
36
41
  * Install agents, prompts, skills, and instruction files to each detected IDE's
37
42
  * global scaffold root.
@@ -53,4 +58,4 @@ declare function initUser(options: {
53
58
  force: boolean;
54
59
  }): Promise<void>;
55
60
  //#endregion
56
- export { UserLevelIdePath, detectInstalledIdes, initUser, installGlobalScaffold, writeUserLevelMcpConfig };
61
+ export { UserLevelIdePath, detectInstalledIdes, initUser, installGlobalScaffold, writeUserLevelMcpConfig, writeVscodeSettings };
@@ -1,6 +1,6 @@
1
- import{MCP_SERVER_ENTRY as e,SERVER_NAME as t,SKILL_NAMES as n}from"./constants.js";import{buildAgentsMd as r,buildCopilotInstructions as i}from"./templates.js";import{copyDirectoryRecursive as a}from"./scaffold.js";import{copyFileSync as o,existsSync as s,mkdirSync as c,readFileSync as l,readdirSync as u,statSync as d,writeFileSync as f}from"node:fs";import{dirname as p,resolve as m}from"node:path";import{fileURLToPath as h}from"node:url";import{getGlobalDataDir as g,saveRegistry as _}from"../../../../core/dist/index.js";import{homedir as v}from"node:os";function y(){let e=v(),t=process.platform,n=[],r=m(e,`.copilot`),i=m(e,`.github`),a=m(e,`.claude`),o=m(e,`.cursor`),c=m(e,`.windsurf`);if(t===`win32`){let t=process.env.APPDATA??m(e,`AppData`,`Roaming`);n.push({ide:`VS Code`,configDir:m(t,`Code`,`User`),mcpConfigPath:m(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:m(t,`Code - Insiders`,`User`),mcpConfigPath:m(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:m(t,`VSCodium`,`User`),mcpConfigPath:m(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:m(t,`Cursor`,`User`),mcpConfigPath:m(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:m(t,`Cursor Nightly`,`User`),mcpConfigPath:m(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:m(t,`Windsurf`,`User`),mcpConfigPath:m(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:c,instructionsRoot:null})}else if(t===`darwin`){let t=m(e,`Library`,`Application Support`);n.push({ide:`VS Code`,configDir:m(t,`Code`,`User`),mcpConfigPath:m(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:m(t,`Code - Insiders`,`User`),mcpConfigPath:m(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:m(t,`VSCodium`,`User`),mcpConfigPath:m(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:m(t,`Cursor`,`User`),mcpConfigPath:m(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:m(t,`Cursor Nightly`,`User`),mcpConfigPath:m(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:m(t,`Windsurf`,`User`),mcpConfigPath:m(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:c,instructionsRoot:null})}else{let t=process.env.XDG_CONFIG_HOME??m(e,`.config`);n.push({ide:`VS Code`,configDir:m(t,`Code`,`User`),mcpConfigPath:m(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:m(t,`Code - Insiders`,`User`),mcpConfigPath:m(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:m(t,`VSCodium`,`User`),mcpConfigPath:m(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:m(t,`Cursor`,`User`),mcpConfigPath:m(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:m(t,`Cursor Nightly`,`User`),mcpConfigPath:m(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:m(t,`Windsurf`,`User`),mcpConfigPath:m(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:c,instructionsRoot:null})}return n.push({ide:`Claude Code`,configDir:m(e,`.claude`),mcpConfigPath:m(e,`.claude`,`mcp.json`),globalScaffoldRoot:a,instructionsRoot:null}),n.filter(e=>s(e.configDir))}function b(t,n,r=!1){let{mcpConfigPath:i,configDir:a}=t,o={...e},u={};if(s(i)){try{let e=l(i,`utf-8`);u=JSON.parse(e)}catch{let e=`${i}.bak`;f(e,l(i,`utf-8`),`utf-8`),console.log(` Backed up invalid ${i} to ${e}`),u={}}if((u.servers??u.mcpServers??{})[n]&&!r){console.log(` ${t.ide}: ${n} already configured (use --force to update)`);return}}let d=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`,`Windsurf`]).has(t.ide)?`servers`:`mcpServers`,p=u[d]??{};p[n]=o,u[d]=p,c(a,{recursive:!0}),f(i,`${JSON.stringify(u,null,2)}\n`,`utf-8`),console.log(` ${t.ide}: configured ${n} in ${i}`)}function x(e,t,n,r){let i=m(t,n);c(i,{recursive:!0});let l=m(e,`scaffold`,`general`,n);if(!s(l))return 0;let f=0;for(let e of u(l)){let t=m(l,e),c=m(i,e);d(t).isDirectory()?a(t,c,`${n}/${e}`,r):(r||!s(c))&&(o(t,c),f++)}return f}function S(e,t,o,l=!1){let u=new Set;for(let e of t)e.globalScaffoldRoot&&u.add(e.globalScaffoldRoot);if(u.size===0){console.log(` No IDEs with global scaffold support detected.`);return}for(let t of u){let r=x(e,t,`agents`,l),i=x(e,t,`prompts`,l),o=m(t,`skills`),c=0;for(let t of n){let n=m(e,`skills`,t);s(n)&&(a(n,m(o,t),`skills/${t}`,l),c++)}console.log(` ${t}: ${r} agents, ${i} prompts, ${c} skills`)}let d=new Set,p=i(`kb`,o),h=r(`kb`,o);for(let e of t){if(!e.globalScaffoldRoot)continue;let t=e.globalScaffoldRoot;if(e.ide===`Claude Code`){let e=m(t,`CLAUDE.md`);(l||!s(e))&&(f(e,`${p}\n---\n\n${h}`,`utf-8`),d.add(e))}else if(e.ide===`VS Code`||e.ide===`VS Code Insiders`||e.ide===`VSCodium`){let n=e.instructionsRoot??t;c(n,{recursive:!0});let r=m(n,`copilot-instructions.md`);d.has(r)||(l||!s(r))&&(f(r,`${p}\n---\n\n${h}`,`utf-8`),d.add(r))}else if(e.ide===`Cursor`||e.ide===`Cursor Nightly`){let e=m(t,`rules`);c(e,{recursive:!0});let n=m(e,`kb.mdc`);d.has(n)||(l||!s(n))&&(f(n,`${p}\n---\n\n${h}`,`utf-8`),d.add(n))}else if(e.ide===`Windsurf`){let e=m(t,`rules`);c(e,{recursive:!0});let n=m(e,`kb.md`);d.has(n)||(l||!s(n))&&(f(n,`${p}\n---\n\n${h}`,`utf-8`),d.add(n))}}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}async function C(e){let n=t;console.log(`Initializing user-level KB installation...
2
- `);let r=g();c(r,{recursive:!0}),console.log(` Global data store: ${r}`),_({version:1,workspaces:{}}),console.log(` Created registry.json`);let i=y();if(i.length===0)console.log(`
3
- No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${i.length} IDE(s):`);for(let t of i)b(t,n,e.force)}let a=m(p(h(import.meta.url)),`..`,`..`,`..`,`..`,`..`);console.log(`
4
- Installing scaffold files:`),S(a,i,n,e.force),console.log(`
1
+ import{MCP_SERVER_ENTRY as e,SERVER_NAME as t,SKILL_NAMES as n,VSCODE_SETTINGS as r}from"./constants.js";import{buildAgentsMd as i,buildCopilotInstructions as a}from"./templates.js";import{copyDirectoryRecursive as o}from"./scaffold.js";import{copyFileSync as s,existsSync as c,mkdirSync as l,readFileSync as u,readdirSync as d,statSync as f,writeFileSync as p}from"node:fs";import{dirname as m,resolve as h}from"node:path";import{fileURLToPath as g}from"node:url";import{getGlobalDataDir as _,saveRegistry as v}from"../../../../core/dist/index.js";import{homedir as y}from"node:os";function b(){let e=y(),t=process.platform,n=[],r=h(e,`.copilot`),i=h(e,`.github`),a=h(e,`.claude`),o=h(e,`.cursor`),s=h(e,`.windsurf`);if(t===`win32`){let t=process.env.APPDATA??h(e,`AppData`,`Roaming`);n.push({ide:`VS Code`,configDir:h(t,`Code`,`User`),mcpConfigPath:h(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:h(t,`Code - Insiders`,`User`),mcpConfigPath:h(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:h(t,`VSCodium`,`User`),mcpConfigPath:h(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:h(t,`Cursor`,`User`),mcpConfigPath:h(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:h(t,`Cursor Nightly`,`User`),mcpConfigPath:h(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:h(t,`Windsurf`,`User`),mcpConfigPath:h(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}else if(t===`darwin`){let t=h(e,`Library`,`Application Support`);n.push({ide:`VS Code`,configDir:h(t,`Code`,`User`),mcpConfigPath:h(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:h(t,`Code - Insiders`,`User`),mcpConfigPath:h(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:h(t,`VSCodium`,`User`),mcpConfigPath:h(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:h(t,`Cursor`,`User`),mcpConfigPath:h(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:h(t,`Cursor Nightly`,`User`),mcpConfigPath:h(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:h(t,`Windsurf`,`User`),mcpConfigPath:h(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}else{let t=process.env.XDG_CONFIG_HOME??h(e,`.config`);n.push({ide:`VS Code`,configDir:h(t,`Code`,`User`),mcpConfigPath:h(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:h(t,`Code - Insiders`,`User`),mcpConfigPath:h(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:h(t,`VSCodium`,`User`),mcpConfigPath:h(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:h(t,`Cursor`,`User`),mcpConfigPath:h(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:h(t,`Cursor Nightly`,`User`),mcpConfigPath:h(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:h(t,`Windsurf`,`User`),mcpConfigPath:h(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}return n.push({ide:`Claude Code`,configDir:h(e,`.claude`),mcpConfigPath:h(e,`.claude`,`mcp.json`),globalScaffoldRoot:a,instructionsRoot:null}),n.filter(e=>c(e.configDir))}function x(t,n,r=!1){let{mcpConfigPath:i,configDir:a}=t,o={...e},s={};if(c(i)){try{let e=u(i,`utf-8`);s=JSON.parse(e)}catch{let e=`${i}.bak`;p(e,u(i,`utf-8`),`utf-8`),console.log(` Backed up invalid ${i} to ${e}`),s={}}if((s.servers??s.mcpServers??{})[n]&&!r){console.log(` ${t.ide}: ${n} already configured (use --force to update)`);return}}let d=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`,`Windsurf`]).has(t.ide)?`servers`:`mcpServers`,f=s[d]??{};f[n]=o,s[d]=f,l(a,{recursive:!0}),p(i,`${JSON.stringify(s,null,2)}\n`,`utf-8`),console.log(` ${t.ide}: configured ${n} in ${i}`)}const S=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function C(e,t=!1){if(!S.has(e.ide))return;let n=h(e.configDir,`settings.json`),i={};if(c(n))try{let e=u(n,`utf-8`);i=JSON.parse(e)}catch{console.log(` ${e.ide}: skipped settings.json (invalid JSON)`);return}let a=!1;for(let[e,n]of Object.entries(r))if(typeof n==`object`&&n){let t=typeof i[e]==`object`&&i[e]!==null?i[e]:{},r={...t,...n};JSON.stringify(r)!==JSON.stringify(t)&&(i[e]=r,a=!0)}else (t||!(e in i))&&(i[e]=n,a=!0);a&&(p(n,`${JSON.stringify(i,null,2)}\n`,`utf-8`),console.log(` ${e.ide}: updated settings.json`))}function w(e,t,n,r){let i=h(t,n);l(i,{recursive:!0});let a=h(e,`scaffold`,`general`,n);if(!c(a))return 0;let u=0;for(let e of d(a)){let t=h(a,e),l=h(i,e);f(t).isDirectory()?o(t,l,`${n}/${e}`,r):(r||!c(l))&&(s(t,l),u++)}return u}function T(e,t,r,s=!1){let u=new Set;for(let e of t)e.globalScaffoldRoot&&u.add(e.globalScaffoldRoot);if(u.size===0){console.log(` No IDEs with global scaffold support detected.`);return}for(let t of u){let r=w(e,t,`agents`,s),i=w(e,t,`prompts`,s),a=h(t,`skills`),l=0;for(let t of n){let n=h(e,`skills`,t);c(n)&&(o(n,h(a,t),`skills/${t}`,s),l++)}console.log(` ${t}: ${r} agents, ${i} prompts, ${l} skills`)}let d=new Set,f=a(`kb`,r),m=i(`kb`,r);for(let e of t){if(!e.globalScaffoldRoot)continue;let t=e.globalScaffoldRoot;if(e.ide===`Claude Code`){let e=h(t,`CLAUDE.md`);(s||!c(e))&&(p(e,`${f}\n---\n\n${m}`,`utf-8`),d.add(e))}else if(e.ide===`VS Code`||e.ide===`VS Code Insiders`||e.ide===`VSCodium`){let n=e.instructionsRoot??t;l(n,{recursive:!0});let r=h(n,`copilot-instructions.md`);d.has(r)||(s||!c(r))&&(p(r,`${f}\n---\n\n${m}`,`utf-8`),d.add(r))}else if(e.ide===`Cursor`||e.ide===`Cursor Nightly`){let e=h(t,`rules`);l(e,{recursive:!0});let n=h(e,`kb.mdc`);d.has(n)||(s||!c(n))&&(p(n,`${f}\n---\n\n${m}`,`utf-8`),d.add(n))}else if(e.ide===`Windsurf`){let e=h(t,`rules`);l(e,{recursive:!0});let n=h(e,`kb.md`);d.has(n)||(s||!c(n))&&(p(n,`${f}\n---\n\n${m}`,`utf-8`),d.add(n))}}d.size>0&&console.log(` Instruction files: ${[...d].join(`, `)}`)}async function E(e){let n=t;console.log(`Initializing user-level KB installation...
2
+ `);let r=_();l(r,{recursive:!0}),console.log(` Global data store: ${r}`),v({version:1,workspaces:{}}),console.log(` Created registry.json`);let i=b();if(i.length===0)console.log(`
3
+ No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${i.length} IDE(s):`);for(let t of i)x(t,n,e.force),C(t,e.force)}let a=h(m(g(import.meta.url)),`..`,`..`,`..`,`..`,`..`);console.log(`
4
+ Installing scaffold files:`),T(a,i,n,e.force),console.log(`
5
5
  User-level KB installation complete!`),console.log(`
6
- Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The KB server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}export{y as detectInstalledIdes,C as initUser,S as installGlobalScaffold,b as writeUserLevelMcpConfig};
6
+ Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The KB server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}export{b as detectInstalledIdes,E as initUser,T as installGlobalScaffold,x as writeUserLevelMcpConfig,C as writeVscodeSettings};
@@ -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};