@vpxa/kb 0.1.19 → 0.1.20

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.20",
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",
@@ -15,5 +15,23 @@ declare const MCP_SERVER_ENTRY: {
15
15
  };
16
16
  /** Skills shipped with the KB package and installed during init. */
17
17
  declare const SKILL_NAMES: readonly ["knowledge-base", "brainstorming", "session-handoff", "requirements-clarity", "lesson-learned", "c4-architecture", "adr-skill"];
18
+ /**
19
+ * VS Code settings merged into each VS Code-family IDE's settings.json.
20
+ *
21
+ * - agentFilesLocations: Disables ~/.claude/agents so agents are only loaded
22
+ * from ~/.copilot/agents (our scaffold root) and workspace .github/agents/.
23
+ * Without this, VS Code discovers both locations causing duplicates with
24
+ * mismatched tool-name formats.
25
+ * - copilotMemory: Enables Copilot Memory so KB `remember` persists across sessions.
26
+ * - customAgentInSubagent: Enables custom agents as subagents — required for
27
+ * Orchestrator's multi-agent `runSubagent` workflow.
28
+ * - useNestedAgentsMdFiles: Agents reference _shared/*.md protocol files —
29
+ * without this, shared protocols are silently ignored.
30
+ * - useAgentSkills: Agents load SKILL.md files on demand (brainstorming,
31
+ * session-handoff, etc.) — without this, skills never activate.
32
+ * - switchAgent: Orchestrator uses the switchAgent tool to hand off to Plan —
33
+ * without this, agent switching is unavailable.
34
+ */
35
+ declare const VSCODE_SETTINGS: Record<string, unknown>;
18
36
  //#endregion
19
- export { MCP_SERVER_ENTRY, SERVER_NAME, SKILL_NAMES };
37
+ 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`],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};
@@ -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};