@vpxa/kb 0.1.27 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/package.json +1 -1
  2. package/packages/analyzers/dist/symbol-analyzer.js +4 -4
  3. package/packages/analyzers/dist/types.d.ts +8 -0
  4. package/packages/chunker/dist/chunker.interface.d.ts +1 -1
  5. package/packages/chunker/dist/code-chunker.d.ts +1 -1
  6. package/packages/chunker/dist/extractors/symbol-extractor.js +3 -1
  7. package/packages/chunker/dist/extractors/types.d.ts +8 -0
  8. package/packages/chunker/dist/generic-chunker.d.ts +1 -1
  9. package/packages/chunker/dist/markdown-chunker.d.ts +1 -1
  10. package/packages/chunker/dist/wasm-chunker.d.ts +1 -1
  11. package/packages/cli/dist/commands/upgrade.d.ts +6 -0
  12. package/packages/cli/dist/commands/upgrade.js +1 -0
  13. package/packages/cli/dist/helpers.d.ts +2 -2
  14. package/packages/cli/dist/index.js +2 -2
  15. package/packages/cli/dist/kb-init.d.ts +4 -4
  16. package/packages/core/dist/types.d.ts +2 -0
  17. package/packages/elicitation/dist/index.d.ts +2 -2
  18. package/packages/elicitation/dist/index.js +2 -2
  19. package/packages/enterprise-bridge/dist/result-merger.d.ts +1 -1
  20. package/packages/indexer/dist/graph-extractor.d.ts +1 -1
  21. package/packages/indexer/dist/incremental-indexer.d.ts +3 -3
  22. package/packages/kb-client/dist/direct-client.d.ts +2 -2
  23. package/packages/present/dist/index.html +4 -4
  24. package/packages/server/dist/completions.d.ts +1 -1
  25. package/packages/server/dist/config.d.ts +1 -1
  26. package/packages/server/dist/config.js +1 -1
  27. package/packages/server/dist/cross-workspace.d.ts +2 -2
  28. package/packages/server/dist/curated-manager.d.ts +2 -2
  29. package/packages/server/dist/dashboard-static.d.ts +2 -2
  30. package/packages/server/dist/elicitor.d.ts +1 -1
  31. package/packages/server/dist/index.js +1 -1
  32. package/packages/server/dist/output-schemas.d.ts +4 -0
  33. package/packages/server/dist/output-schemas.js +1 -1
  34. package/packages/server/dist/prompts.d.ts +1 -1
  35. package/packages/server/dist/resources/resources.d.ts +1 -1
  36. package/packages/server/dist/server.d.ts +7 -7
  37. package/packages/server/dist/server.js +2 -2
  38. package/packages/server/dist/structured-content-guard.d.ts +26 -0
  39. package/packages/server/dist/structured-content-guard.js +1 -0
  40. package/packages/server/dist/tools/analyze.tools.d.ts +2 -2
  41. package/packages/server/dist/tools/audit.tool.d.ts +2 -2
  42. package/packages/server/dist/tools/brainstorm.tool.d.ts +1 -1
  43. package/packages/server/dist/tools/bridge.tools.d.ts +1 -1
  44. package/packages/server/dist/tools/context.tools.d.ts +3 -3
  45. package/packages/server/dist/tools/context.tools.js +2 -1
  46. package/packages/server/dist/tools/evolution.tools.d.ts +1 -1
  47. package/packages/server/dist/tools/execution.tools.d.ts +2 -2
  48. package/packages/server/dist/tools/forge.tools.d.ts +3 -3
  49. package/packages/server/dist/tools/graph.tool.d.ts +1 -1
  50. package/packages/server/dist/tools/infra.tools.js +4 -2
  51. package/packages/server/dist/tools/lookup.tool.d.ts +1 -1
  52. package/packages/server/dist/tools/onboard.tool.d.ts +4 -3
  53. package/packages/server/dist/tools/onboard.tool.js +1 -1
  54. package/packages/server/dist/tools/policy.tools.d.ts +1 -1
  55. package/packages/server/dist/tools/present.tool.d.ts +1 -1
  56. package/packages/server/dist/tools/produce.tool.d.ts +2 -1
  57. package/packages/server/dist/tools/produce.tool.js +2 -2
  58. package/packages/server/dist/tools/reindex.tool.d.ts +3 -3
  59. package/packages/server/dist/tools/remember.tool.d.ts +1 -1
  60. package/packages/server/dist/tools/search.tool.d.ts +3 -3
  61. package/packages/server/dist/tools/status.tool.d.ts +3 -2
  62. package/packages/server/dist/tools/status.tool.js +2 -2
  63. package/packages/server/dist/tools/utility.tools.js +4 -2
  64. package/packages/server/dist/version-check.js +1 -1
  65. package/packages/store/dist/lance-store.d.ts +1 -1
  66. package/packages/store/dist/store.interface.d.ts +1 -1
  67. package/packages/tools/dist/audit.d.ts +2 -2
  68. package/packages/tools/dist/compact.d.ts +1 -1
  69. package/packages/tools/dist/dead-symbols.d.ts +2 -2
  70. package/packages/tools/dist/digest.d.ts +1 -1
  71. package/packages/tools/dist/find-examples.d.ts +3 -3
  72. package/packages/tools/dist/find.d.ts +7 -3
  73. package/packages/tools/dist/find.js +1 -1
  74. package/packages/tools/dist/forge-ground.d.ts +2 -2
  75. package/packages/tools/dist/graph-query.d.ts +1 -1
  76. package/packages/tools/dist/onboard.js +18 -2
  77. package/packages/tools/dist/scope-map.d.ts +3 -3
  78. package/packages/tools/dist/stratum-card.d.ts +1 -1
  79. package/packages/tools/dist/symbol.d.ts +2 -2
  80. package/packages/tools/dist/trace.d.ts +2 -2
  81. package/packages/tui/dist/App.d.ts +1 -1
  82. package/packages/tui/dist/hooks/useKBClient.d.ts +3 -3
  83. package/packages/tui/dist/index.d.ts +1 -1
  84. package/scaffold/README.md +192 -0
  85. package/scaffold/definitions/bodies.mjs +140 -28
  86. package/scaffold/definitions/protocols.mjs +232 -24
  87. package/scaffold/general/agents/Debugger.agent.md +9 -6
  88. package/scaffold/general/agents/Documenter.agent.md +13 -2
  89. package/scaffold/general/agents/Explorer.agent.md +12 -0
  90. package/scaffold/general/agents/Frontend.agent.md +1 -1
  91. package/scaffold/general/agents/Implementer.agent.md +3 -1
  92. package/scaffold/general/agents/Orchestrator.agent.md +67 -11
  93. package/scaffold/general/agents/Planner.agent.md +19 -2
  94. package/scaffold/general/agents/Refactor.agent.md +1 -1
  95. package/scaffold/general/agents/Security.agent.md +13 -2
  96. package/scaffold/general/agents/_shared/architect-reviewer-base.md +11 -2
  97. package/scaffold/general/agents/_shared/code-agent-base.md +181 -17
  98. package/scaffold/general/agents/_shared/code-reviewer-base.md +11 -2
  99. package/scaffold/general/agents/_shared/researcher-base.md +29 -3
  100. package/packages/elicitation/dist/__tests__/build.test.d.ts +0 -1
  101. package/packages/elicitation/dist/__tests__/fields.test.d.ts +0 -1
  102. package/packages/elicitation/dist/__tests__/normalize.test.d.ts +0 -1
  103. package/packages/elicitation/dist/build.d.ts +0 -13
  104. package/packages/elicitation/dist/fields.d.ts +0 -41
  105. package/packages/elicitation/dist/normalize.d.ts +0 -15
  106. package/packages/elicitation/dist/types.d.ts +0 -85
  107. /package/packages/tui/dist/{types-VcTHNV6s.d.ts → index-Cvx1a7S7.d.ts} +0 -0
@@ -1,5 +1,7 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{EnvOutputSchema as t,MeasureOutputSchema as n,TimeOutputSchema as r}from"../output-schemas.js";import{z as i}from"zod";import{createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{changelog as s,encode as c,envInfo as l,httpRequest as u,measure as d,regexTest as f,schemaValidate as p,snippet as m,timeUtils as h,webSearch as g}from"../../../tools/dist/index.js";const _=a(`tools`);function v(t){let n=e(`web_search`);t.registerTool(`web_search`,{title:n.title,description:`PREFERRED web search — search the web via DuckDuckGo (no API key). Returns structured results with title, URL, and snippet.`,inputSchema:{query:i.string().max(2e3).describe(`Search query`),limit:i.number().min(1).max(20).default(5).describe(`Max results to return`),site:i.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`)},annotations:n.annotations},async({query:e,limit:t,site:n})=>{try{let r=await g({query:e,limit:t,site:n}),i=[`## Search: ${r.query}`,``];if(r.results.length===0)i.push(`No results found.`);else for(let e of r.results)i.push(`### [${e.title}](${e.url})`,e.snippet,``);return i.push(`---`,"_Next: Use `web_fetch` to read any of these pages in full._"),{content:[{type:`text`,text:i.join(`
2
- `)}]}}catch(e){return _.error(`Web search failed`,o(e)),{content:[{type:`text`,text:`Web search failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function y(t){let n=e(`http`);t.registerTool(`http`,{title:n.title,description:`Make HTTP requests (GET/POST/PUT/PATCH/DELETE/HEAD) for API testing. Returns status, headers, and formatted body with timing info.`,inputSchema:{url:i.string().url().describe(`Request URL (http/https only)`),method:i.enum([`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`]).default(`GET`).describe(`HTTP method`),headers:i.record(i.string(),i.string()).optional().describe(`Request headers as key-value pairs`),body:i.string().optional().describe(`Request body (for POST/PUT/PATCH)`),timeout:i.number().min(1e3).max(6e4).default(15e3).describe(`Timeout in milliseconds`)},annotations:n.annotations},async({url:e,method:t,headers:n,body:r,timeout:i})=>{try{let a=await u({url:e,method:t,headers:n,body:r,timeout:i}),o=[`## ${t} ${e}`,``,`**Status:** ${a.status} ${a.statusText}`,`**Time:** ${a.durationMs}ms`,`**Size:** ${a.sizeBytes} bytes`,`**Content-Type:** ${a.contentType}`,``,`### Headers`,"```json",JSON.stringify(a.headers),"```",``,`### Body`,a.contentType.includes(`json`)?"```json":"```",a.body,"```"];return a.truncated&&o.push(``,`_Response truncated total size: ${a.sizeBytes} bytes_`),{content:[{type:`text`,text:o.join(`
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{EnvOutputSchema as t,MeasureOutputSchema as n,TimeOutputSchema as r}from"../output-schemas.js";import{z as i}from"zod";import{createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{changelog as s,encode as c,envInfo as l,httpRequest as u,measure as d,regexTest as f,schemaValidate as p,snippet as m,timeUtils as h,webSearch as g}from"../../../tools/dist/index.js";const _=a(`tools`);function v(t){let n=e(`web_search`);t.registerTool(`web_search`,{title:n.title,description:`PREFERRED web search — search the web via DuckDuckGo (no API key). Pass one query or multiple for parallel searching. Returns structured results with title, URL, and snippet.`,inputSchema:{queries:i.array(i.string().max(2e3)).min(1).max(5).describe('Search queries (1–5). Single: `["react hooks"]`. Multiple searched in parallel.'),limit:i.number().min(1).max(20).default(5).describe(`Max results per query`),site:i.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`)},annotations:n.annotations},async({queries:e,limit:t,site:n})=>{let r=e,i=async e=>{let r=await g({query:e,limit:t,site:n}),i=[`## Search: ${r.query}`,``];if(r.results.length===0)i.push(`No results found.`);else for(let e of r.results)i.push(`### [${e.title}](${e.url})`,e.snippet,``);return i.join(`
2
+ `)};if(r.length===1)try{return{content:[{type:`text`,text:`${await i(r[0])}\n---\n_Next: Use \`web_fetch\` to read any of these pages in full._`}]}}catch(e){return _.error(`Web search failed`,o(e)),{content:[{type:`text`,text:`Web search failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}let a=await Promise.allSettled(r.map(e=>i(e))),s=[],c=0;for(let e=0;e<a.length;e++){let t=a[e];if(t.status===`fulfilled`)s.push(t.value);else{c++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);_.error(`Web search failed`,{query:r[e],error:n}),s.push(`## Search failed: ${r[e]}\n\n${n}`)}}let l=`_Searched ${a.length-c}/${a.length} queries successfully._`;return s.push(``,`---`,l,"_Next: Use `web_fetch` to read any of these pages in full._"),{content:[{type:`text`,text:s.join(`
3
+
4
+ `)}],...c===a.length?{isError:!0}:{}}})}function y(t){let n=e(`http`);t.registerTool(`http`,{title:n.title,description:`Make HTTP requests (GET/POST/PUT/PATCH/DELETE/HEAD) for API testing. Returns status, headers, and formatted body with timing info.`,inputSchema:{url:i.string().url().describe(`Request URL (http/https only)`),method:i.enum([`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`]).default(`GET`).describe(`HTTP method`),headers:i.record(i.string(),i.string()).optional().describe(`Request headers as key-value pairs`),body:i.string().optional().describe(`Request body (for POST/PUT/PATCH)`),timeout:i.number().min(1e3).max(6e4).default(15e3).describe(`Timeout in milliseconds`)},annotations:n.annotations},async({url:e,method:t,headers:n,body:r,timeout:i})=>{try{let a=await u({url:e,method:t,headers:n,body:r,timeout:i}),o=[`## ${t} ${e}`,``,`**Status:** ${a.status} ${a.statusText}`,`**Time:** ${a.durationMs}ms`,`**Size:** ${a.sizeBytes} bytes`,`**Content-Type:** ${a.contentType}`,``,`### Headers`,"```json",JSON.stringify(a.headers),"```",``,`### Body`,a.contentType.includes(`json`)?"```json":"```",a.body,"```"];return a.truncated&&o.push(``,`_Response truncated — total size: ${a.sizeBytes} bytes_`),{content:[{type:`text`,text:o.join(`
3
5
  `)}]}}catch(e){return _.error(`HTTP request failed`,o(e)),{content:[{type:`text`,text:`HTTP request failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function b(t){let n=e(`regex_test`);t.registerTool(`regex_test`,{title:n.title,description:`Test a regex pattern against sample strings. Supports match, replace, and split modes.`,inputSchema:{pattern:i.string().max(500).describe(`Regex pattern (without delimiters)`),flags:i.string().max(10).regex(/^[gimsuy]*$/).default(``).describe(`Regex flags (g, i, m, s, etc.)`),test_strings:i.array(i.string().max(1e4)).max(50).describe(`Strings to test the pattern against`),mode:i.enum([`match`,`replace`,`split`]).default(`match`).describe(`Test mode`),replacement:i.string().optional().describe(`Replacement string (for replace mode)`)},annotations:n.annotations},async({pattern:e,flags:t,test_strings:n,mode:r,replacement:i})=>{let a=f({pattern:e,flags:t,testStrings:n,mode:r,replacement:i});if(!a.valid)return{content:[{type:`text`,text:`Invalid regex: ${a.error}`}],isError:!0};let o=[`## Regex: \`/${a.pattern}/${a.flags}\``,``,`Mode: ${r}`,``];for(let e of a.results){if(o.push(`**Input:** \`${e.input}\``),o.push(`**Matched:** ${e.matched}`),e.matches)for(let t of e.matches){let e=t.groups.length>0?` groups: [${t.groups.join(`, `)}]`:``;o.push(` - "${t.full}" at index ${t.index}${e}`)}e.replaced!==void 0&&o.push(`**Result:** \`${e.replaced}\``),e.split&&o.push(`**Split:** ${JSON.stringify(e.split)}`),o.push(``)}return{content:[{type:`text`,text:o.join(`
4
6
  `)}]}})}function x(t){let n=e(`encode`);t.registerTool(`encode`,{title:n.title,description:`Encode, decode, or hash text. Supports base64, URL encoding, SHA-256, MD5, JWT decode, hex.`,inputSchema:{operation:i.enum([`base64_encode`,`base64_decode`,`url_encode`,`url_decode`,`sha256`,`md5`,`jwt_decode`,`hex_encode`,`hex_decode`]).describe(`Operation to perform`),input:i.string().max(1e6).describe(`Input text`)},annotations:n.annotations},async({operation:e,input:t})=>{try{let n=c({operation:e,input:t});return{content:[{type:`text`,text:`## ${e}\n\n**Input:** \`${t.length>100?`${t.slice(0,100)}...`:t}\`\n**Output:**\n\`\`\`\n${n.output}\n\`\`\``}]}}catch(e){return _.error(`Encode failed`,o(e)),{content:[{type:`text`,text:`Encode failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function S(t){let r=e(`measure`);t.registerTool(`measure`,{title:r.title,description:`Measure code complexity, line counts, and function counts for a file or directory. Returns per-file metrics sorted by complexity.`,outputSchema:n,inputSchema:{path:i.string().describe(`File or directory path to measure`),extensions:i.array(i.string()).optional().describe(`File extensions to include (default: .ts,.tsx,.js,.jsx)`)},annotations:r.annotations},async({path:e,extensions:t})=>{try{let n=await d({path:e,extensions:t}),r=[`## Code Metrics`,``,`**Files:** ${n.summary.totalFiles}`,`**Total lines:** ${n.summary.totalLines} (${n.summary.totalCodeLines} code)`,`**Functions:** ${n.summary.totalFunctions}`,`**Avg complexity:** ${n.summary.avgComplexity}`,`**Max complexity:** ${n.summary.maxComplexity.value} (${n.summary.maxComplexity.file})`,``,`### Top files by complexity`,``,`| File | Lines | Code | Complexity | Cognitive | Functions | Imports |`,`|------|-------|------|------------|-----------|-----------|---------|`];for(let e of n.files.slice(0,20)){let t=e.cognitiveComplexity===void 0?`—`:String(e.cognitiveComplexity);r.push(`| ${e.path} | ${e.lines.total} | ${e.lines.code} | ${e.complexity} | ${t} | ${e.functions} | ${e.imports} |`)}n.files.length>20&&r.push(``,`_...and ${n.files.length-20} more files_`);let i={summary:{totalFiles:n.summary.totalFiles,totalLines:n.summary.totalLines,totalCodeLines:n.summary.totalCodeLines,totalFunctions:n.summary.totalFunctions,avgComplexity:n.summary.avgComplexity,maxComplexity:{value:n.summary.maxComplexity.value,file:n.summary.maxComplexity.file}},files:n.files.map(e=>({path:e.path,lines:e.lines.total,code:e.lines.code,complexity:e.complexity,functions:e.functions}))};return{content:[{type:`text`,text:r.join(`
5
7
  `)}],structuredContent:i}}catch(e){return _.error(`Measure failed`,o(e)),{content:[{type:`text`,text:`Measure failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function C(t){let n=e(`changelog`);t.registerTool(`changelog`,{title:n.title,description:`Generate a changelog from git history between two refs. Groups by conventional commit type.`,inputSchema:{from:i.string().max(200).describe(`Start ref (tag, SHA, HEAD~N)`),to:i.string().max(200).default(`HEAD`).describe(`End ref (default: HEAD)`),format:i.enum([`grouped`,`chronological`,`per-scope`]).default(`grouped`).describe(`Output format`),include_breaking:i.boolean().default(!0).describe(`Highlight breaking changes`),cwd:i.string().optional().describe(`Repository root or working directory`)},annotations:n.annotations},async({from:e,to:t,format:n,include_breaking:r,cwd:i})=>{try{let a=s({from:e,to:t,format:n,includeBreaking:r,cwd:i}),o=`${a.stats.total} commits (${Object.entries(a.stats.types).map(([e,t])=>`${t} ${e}`).join(`, `)})`;return{content:[{type:`text`,text:`${a.markdown}\n---\n_${o}_`}]}}catch(e){return _.error(`Changelog failed`,o(e)),{content:[{type:`text`,text:`Changelog failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function w(t){let n=e(`schema_validate`);t.registerTool(`schema_validate`,{title:n.title,description:`Validate JSON data against a JSON Schema. Supports type, required, properties, items, enum, pattern, min/max.`,inputSchema:{data:i.string().max(5e5).describe(`JSON data to validate (as string)`),schema:i.string().max(5e5).describe(`JSON Schema to validate against (as string)`)},annotations:n.annotations},async({data:e,schema:t})=>{try{let n=p({data:JSON.parse(e),schema:JSON.parse(t)});if(n.valid)return{content:[{type:`text`,text:`## Validation: PASSED
@@ -1 +1 @@
1
- import{readFileSync as e}from"node:fs";import{dirname as t,resolve as n}from"node:path";import{fileURLToPath as r}from"node:url";import{createLogger as i}from"../../core/dist/index.js";const a=i(`server`);function o(){let i=n(t(r(import.meta.url)),`..`,`..`,`..`,`package.json`);try{return JSON.parse(e(i,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function s(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t>0?1:-1}return 0}function c(){let e=o();fetch(`https://registry.npmjs.org/@vpxa/kb/latest`,{signal:AbortSignal.timeout(5e3)}).then(e=>{if(e.ok)return e.json()}).then(t=>{if(!t||typeof t!=`object`)return;let n=t.version;n&&s(e,n)<0&&a.warn(`Update available`,{currentVersion:e,latestVersion:n,updateCommand:`npx @vpxa/kb@${n} serve`,configHint:`update your mcp.json`})}).catch(()=>{})}export{c as checkForUpdates,o as getCurrentVersion};
1
+ import{readFileSync as e}from"node:fs";import{dirname as t,resolve as n}from"node:path";import{fileURLToPath as r}from"node:url";import{createLogger as i}from"../../core/dist/index.js";const a=i(`server`);function o(){let i=n(t(r(import.meta.url)),`..`,`..`,`..`,`package.json`);try{return JSON.parse(e(i,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function s(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t>0?1:-1}return 0}function c(){let e=o();fetch(`https://registry.npmjs.org/@vpxa/kb/latest`,{signal:AbortSignal.timeout(5e3)}).then(e=>{if(e.ok)return e.json()}).then(t=>{if(!t||typeof t!=`object`)return;let n=t.version;n&&s(e,n)<0&&a.warn(`Update available`,{currentVersion:e,latestVersion:n,updateCommand:`npx -y @vpxa/kb upgrade`})}).catch(()=>{})}export{c as checkForUpdates,o as getCurrentVersion};
@@ -1,5 +1,5 @@
1
1
  import { IKnowledgeStore, SearchOptions } from "./store.interface.js";
2
- import { IndexStats, KnowledgeRecord, SearchResult } from "@kb/core";
2
+ import { IndexStats, KnowledgeRecord, SearchResult } from "../../core/dist/index.js";
3
3
 
4
4
  //#region packages/store/src/lance-store.d.ts
5
5
  declare class LanceStore implements IKnowledgeStore {
@@ -1,4 +1,4 @@
1
- import { ContentType, IndexStats, KnowledgeOrigin, KnowledgeRecord, SearchResult, SourceType } from "@kb/core";
1
+ import { ContentType, IndexStats, KnowledgeOrigin, KnowledgeRecord, SearchResult, SourceType } from "../../core/dist/index.js";
2
2
 
3
3
  //#region packages/store/src/store.interface.d.ts
4
4
  /** Options for searching the store */
@@ -1,6 +1,6 @@
1
1
  import { KBResponse } from "./response-envelope.js";
2
- import { IEmbedder } from "@kb/embeddings";
3
- import { IKnowledgeStore } from "@kb/store";
2
+ import { IEmbedder } from "../../embeddings/dist/index.js";
3
+ import { IKnowledgeStore } from "../../store/dist/index.js";
4
4
 
5
5
  //#region packages/tools/src/audit.d.ts
6
6
  type AuditCheck = 'structure' | 'dependencies' | 'patterns' | 'health' | 'dead_symbols' | 'check' | 'entry_points';
@@ -1,5 +1,5 @@
1
1
  import { FileCache } from "./file-cache.js";
2
- import { IEmbedder } from "@kb/embeddings";
2
+ import { IEmbedder } from "../../embeddings/dist/index.js";
3
3
 
4
4
  //#region packages/tools/src/compact.d.ts
5
5
  interface CompactOptions {
@@ -1,5 +1,5 @@
1
- import { IEmbedder } from "@kb/embeddings";
2
- import { IKnowledgeStore } from "@kb/store";
1
+ import { IEmbedder } from "../../embeddings/dist/index.js";
2
+ import { IKnowledgeStore } from "../../store/dist/index.js";
3
3
 
4
4
  //#region packages/tools/src/dead-symbols.d.ts
5
5
  interface DeadSymbolOptions {
@@ -1,4 +1,4 @@
1
- import { IEmbedder } from "@kb/embeddings";
1
+ import { IEmbedder } from "../../embeddings/dist/index.js";
2
2
 
3
3
  //#region packages/tools/src/digest.d.ts
4
4
  interface DigestSource {
@@ -1,6 +1,6 @@
1
- import { IEmbedder } from "@kb/embeddings";
2
- import { IKnowledgeStore } from "@kb/store";
3
- import { ContentType } from "@kb/core";
1
+ import { ContentType } from "../../core/dist/index.js";
2
+ import { IEmbedder } from "../../embeddings/dist/index.js";
3
+ import { IKnowledgeStore } from "../../store/dist/index.js";
4
4
 
5
5
  //#region packages/tools/src/find-examples.d.ts
6
6
  interface FindExamplesOptions {
@@ -1,6 +1,6 @@
1
- import { IEmbedder } from "@kb/embeddings";
2
- import { IKnowledgeStore } from "@kb/store";
3
- import { ContentType } from "@kb/core";
1
+ import { ContentType } from "../../core/dist/index.js";
2
+ import { IEmbedder } from "../../embeddings/dist/index.js";
3
+ import { IKnowledgeStore } from "../../store/dist/index.js";
4
4
 
5
5
  //#region packages/tools/src/find.d.ts
6
6
  interface FindOptions {
@@ -36,6 +36,10 @@ interface FindResults {
36
36
  results: FindResult[];
37
37
  strategies: string[];
38
38
  totalFound: number;
39
+ failedStrategies?: Array<{
40
+ strategy: string;
41
+ reason: string;
42
+ }>;
39
43
  }
40
44
  /**
41
45
  * Run federated search across multiple strategies.
@@ -1 +1 @@
1
- import{KB_PATHS as e}from"../../core/dist/index.js";async function t(t,n,r){let{query:i,glob:a,pattern:o,limit:s=10,contentType:c,cwd:l=process.cwd()}=r,u=[],d=[],f=new Set;if(i){u.push(`vector`);let e=await t.embed(i),r={limit:s,contentType:c},a=await n.search(e,r);for(let e of a){let t=`${e.record.sourcePath}:${e.record.startLine}`;f.has(t)||(f.add(t),d.push({path:e.record.sourcePath,source:`vector`,score:e.score,lineRange:{start:e.record.startLine,end:e.record.endLine},preview:e.record.content.slice(0,200)}))}}if(i){u.push(`keyword`);try{let e=await n.ftsSearch(i,{limit:s,contentType:c});for(let t of e){let e=`${t.record.sourcePath}:${t.record.startLine}`;f.has(e)||(f.add(e),d.push({path:t.record.sourcePath,source:`keyword`,score:t.score,lineRange:{start:t.record.startLine,end:t.record.endLine},preview:t.record.content.slice(0,200)}))}}catch{}}if(a){u.push(`glob`);try{let{globSync:t}=await import(`node:fs`),n=t(a,{cwd:l,withFileTypes:!1}),r=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,e.state,e.data]),i=n.filter(e=>!e.replace(/\\/g,`/`).split(`/`).some(e=>r.has(e)));for(let e of i.slice(0,s)){let t=`glob:${e}`;f.has(t)||(f.add(t),d.push({path:e,source:`glob`,score:1}))}}catch{}}if(o){u.push(`pattern`);try{let e=new RegExp(o,`i`),t=await n.ftsSearch(o,{limit:s*2,contentType:c});for(let n of t)if(e.test(n.record.content)){let e=`${n.record.sourcePath}:${n.record.startLine}`;f.has(e)||(f.add(e),d.push({path:n.record.sourcePath,source:`pattern`,score:n.score,lineRange:{start:n.record.startLine,end:n.record.endLine},preview:n.record.content.slice(0,200)}))}}catch{}}return d.sort((e,t)=>t.score-e.score),{results:d.slice(0,s),strategies:u,totalFound:d.length}}export{t as find};
1
+ import{KB_PATHS as e}from"../../core/dist/index.js";async function t(t,n,r){let{query:i,glob:a,pattern:o,limit:s=10,contentType:c,cwd:l=process.cwd()}=r,u=[],d=[],f=new Set,p=[];if(i){u.push(`vector`);let e=await t.embed(i),r={limit:s,contentType:c},a=await n.search(e,r);for(let e of a){let t=`${e.record.sourcePath}:${e.record.startLine}`;f.has(t)||(f.add(t),d.push({path:e.record.sourcePath,source:`vector`,score:e.score,lineRange:{start:e.record.startLine,end:e.record.endLine},preview:e.record.content.slice(0,200)}))}}if(i){u.push(`keyword`);try{let e=await n.ftsSearch(i,{limit:s,contentType:c});for(let t of e){let e=`${t.record.sourcePath}:${t.record.startLine}`;f.has(e)||(f.add(e),d.push({path:t.record.sourcePath,source:`keyword`,score:t.score,lineRange:{start:t.record.startLine,end:t.record.endLine},preview:t.record.content.slice(0,200)}))}}catch(e){p.push({strategy:`keyword`,reason:e instanceof Error?e.message:String(e)})}}if(a){u.push(`glob`);try{let{globSync:t}=await import(`node:fs`),n=t(a,{cwd:l,withFileTypes:!1}),r=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,e.state,e.data]),i=n.filter(e=>!e.replace(/\\/g,`/`).split(`/`).some(e=>r.has(e)));for(let e of i.slice(0,s)){let t=`glob:${e}`;f.has(t)||(f.add(t),d.push({path:e,source:`glob`,score:1}))}}catch(e){p.push({strategy:`glob`,reason:e instanceof Error?e.message:String(e)})}}if(o){u.push(`pattern`);try{let e=new RegExp(o,`i`),t=await n.ftsSearch(o,{limit:s*2,contentType:c});for(let n of t)if(e.test(n.record.content)){let e=`${n.record.sourcePath}:${n.record.startLine}`;f.has(e)||(f.add(e),d.push({path:n.record.sourcePath,source:`pattern`,score:n.score,lineRange:{start:n.record.startLine,end:n.record.endLine},preview:n.record.content.slice(0,200)}))}}catch(e){p.push({strategy:`pattern`,reason:e instanceof Error?e.message:String(e)})}}return d.sort((e,t)=>t.score-e.score),{results:d.slice(0,s),strategies:u,totalFound:d.length,...p.length>0&&{failedStrategies:p}}}export{t as find};
@@ -1,8 +1,8 @@
1
1
  import { ForgeTier } from "./evidence-map.js";
2
2
  import { ClassifyTrigger, TypedUnknownSeed } from "./forge-classify.js";
3
3
  import { ScopeMapResult } from "./scope-map.js";
4
- import { IEmbedder } from "@kb/embeddings";
5
- import { IKnowledgeStore } from "@kb/store";
4
+ import { IEmbedder } from "../../embeddings/dist/index.js";
5
+ import { IKnowledgeStore } from "../../store/dist/index.js";
6
6
 
7
7
  //#region packages/tools/src/forge-ground.d.ts
8
8
  interface ForgeGroundOptions {
@@ -1,4 +1,4 @@
1
- import { GraphEdge, GraphNode, GraphStats, GraphTraversalResult, GraphValidationResult, IGraphStore } from "@kb/store";
1
+ import { GraphEdge, GraphNode, GraphStats, GraphTraversalResult, GraphValidationResult, IGraphStore } from "../../store/dist/index.js";
2
2
 
3
3
  //#region packages/tools/src/graph-query.d.ts
4
4
  interface GraphQueryOptions {
@@ -1,2 +1,18 @@
1
- import{extractConfigValues as e}from"./config-extractor.js";import{buildDiagrams as t}from"./diagram-builder.js";import{buildCodeMap as n,buildSynthesisGuide as r}from"./synthesis-engine.js";import{DependencyAnalyzer as i,DiagramGenerator as a,EntryPointAnalyzer as o,PatternAnalyzer as s,StructureAnalyzer as c,SymbolAnalyzer as l,extractRegexCallGraph as u,extractTsCallGraph as d}from"../../analyzers/dist/index.js";import{basename as f,join as p,resolve as m}from"node:path";import{existsSync as h,mkdirSync as g,readdirSync as _,rmSync as v,writeFileSync as y}from"node:fs";import{KB_PATHS as b}from"../../core/dist/index.js";const x={structure:`Project Structure`,dependencies:`Dependencies`,"entry-points":`Entry Points`,symbols:`Symbols`,patterns:`Patterns`,diagram:`C4 Container Diagram`,"code-map":`Code Map (Module Graph)`,"config-values":`Configuration Values`,"synthesis-guide":`Synthesis Guide`};async function S(S){let C=Date.now(),w=m(S.path),T=f(w),E=S.mode??`memory`,D=S.outDir??p(w,b.aiKb),O=new c,k=new i,A=new l,j=new s,M=new o,N=new a,P=[{name:`structure`,fn:()=>O.analyze(w,{format:`markdown`,maxDepth:3,sourceOnly:!0})},{name:`dependencies`,fn:()=>k.analyze(w,{format:`markdown`})},{name:`entry-points`,fn:()=>M.analyze(w)},{name:`symbols`,fn:()=>A.analyze(w,{format:`markdown`})},{name:`patterns`,fn:()=>j.analyze(w)},{name:`diagram`,fn:()=>N.analyze(w,{diagramType:`architecture`})}],F=await Promise.allSettled(P.map(async e=>{let t=Date.now(),n=await e.fn();return{name:e.name,result:n,durationMs:Date.now()-t}})),I=[],L=new Map,R=new Map;for(let e of F)if(e.status===`fulfilled`){let{name:t,result:n,durationMs:r}=e.value,i=n;I.push({name:t,status:`success`,output:i.output,durationMs:r}),L.set(t,i.output),R.set(t,i.data)}else{let t=e.reason,n=P[F.indexOf(e)].name;I.push({name:n,status:`failed`,output:``,durationMs:0,error:t.message})}let z=Date.now(),B=null;try{let e=await d(w);if((!e||e.edges.length===0)&&(e=await u(w)),e&&e.edges.length>0){B=new Map;for(let t of e.edges){let e=B.get(t.from);e||(e=new Map,B.set(t.from,e));let n=e.get(t.to);if(n)for(let e of t.symbols)n.includes(e)||n.push(e);else e.set(t.to,[...t.symbols])}}}catch{}let V=Date.now()-z,H=Date.now(),U=n(R,T,B),W=Date.now()-H+V;if(I.push({name:`code-map`,status:`success`,output:U,durationMs:W}),L.set(`code-map`,U),B&&B.size>0){let e=t(B,R,T),n=I.find(e=>e.name===`diagram`);n&&(n.output=e,L.set(`diagram`,e))}let G=Date.now(),K=await e(w,T),q=Date.now()-G;I.push({name:`config-values`,status:`success`,output:K,durationMs:q}),L.set(`config-values`,K);let J=r(I,E,T,R);if(I.push({name:`synthesis-guide`,status:`success`,output:J,durationMs:0}),L.set(`synthesis-guide`,J),E===`generate`){if(h(D))for(let e of _(D))(e.endsWith(`.md`)||e.endsWith(`.json`))&&v(p(D,e),{force:!0});g(D,{recursive:!0});let e=new Date().toISOString();for(let[t,n]of L){let r=p(D,`${t}.md`),i=n.replaceAll(w,T);y(r,`<!-- Generated: ${e} -->\n<!-- Project: ${T} -->\n<!-- Source: ${w} -->\n\n`+i,`utf-8`)}let t=[`<!-- Generated: ${e} -->`,`<!-- Project: ${T} -->`,`<!-- Source: ${w} -->`,``,`# ${T} — Codebase Knowledge`,``,`## Contents`,``];for(let e of I){let n=`${e.name}.md`,r=x[e.name]??e.name,i=e.status===`success`?`✓`:`✗`,a=e.durationMs>0?` (${e.durationMs}ms)`:``;t.push(`- ${i} [${r}](./${n})${a}`)}t.push(``),y(p(D,`README.md`),t.join(`
2
- `),`utf-8`)}return{path:w,mode:E,steps:I,outDir:E===`generate`?D:void 0,totalDurationMs:Date.now()-C}}export{S as onboard};
1
+ import{extractConfigValues as e}from"./config-extractor.js";import{buildDiagrams as t}from"./diagram-builder.js";import{buildCodeMap as n,buildSynthesisGuide as r}from"./synthesis-engine.js";import{DependencyAnalyzer as i,DiagramGenerator as a,EntryPointAnalyzer as o,PatternAnalyzer as s,StructureAnalyzer as c,SymbolAnalyzer as l,extractRegexCallGraph as u,extractTsCallGraph as d}from"../../analyzers/dist/index.js";import{basename as f,join as p,resolve as m}from"node:path";import{existsSync as h,mkdirSync as g,readdirSync as _,rmSync as v,writeFileSync as y}from"node:fs";import{KB_PATHS as b}from"../../core/dist/index.js";const x={structure:`Project Structure`,dependencies:`Dependencies`,"entry-points":`Entry Points`,symbols:`Symbols`,patterns:`Patterns`,diagram:`C4 Container Diagram`,"code-map":`Code Map (Module Graph)`,"config-values":`Configuration Values`,"synthesis-guide":`Synthesis Guide`,"api-surface":`API Surface`,"type-inventory":`Type Inventory`};function S(e){let t=e.get(`symbols`);if(!t?.symbols?.length)return`# API Surface
2
+
3
+ *No symbol data available.*
4
+ `;let n=t.symbols.filter(e=>e.exported);if(n.length===0)return`# API Surface
5
+
6
+ *No exported symbols found.*
7
+ `;let r=new Map;for(let e of n){let t=r.get(e.filePath)??[];t.push(e),r.set(e.filePath,t)}let i=[`# API Surface
8
+ `];for(let[e,t]of[...r.entries()].sort(([e],[t])=>e.localeCompare(t))){i.push(`## ${e}\n`);for(let e of t){e.decorators?.length&&i.push(e.decorators.join(` `));let t=e.signature??``,n=e.returnType?`: ${e.returnType}`:``;if(e.kind===`function`||e.kind===`method`)i.push(`### \`${e.name}${t}${n}\``);else if(e.kind===`class`)i.push(`### class \`${e.name}\`${t?` ${t}`:``}`);else if(e.kind===`interface`||e.kind===`type`){let t=e.typeBody?` ${e.typeBody}`:``;i.push(`### ${e.kind} \`${e.name}\`${t}`)}else i.push(`### ${e.kind} \`${e.name}\`${t?`: ${t}`:``}`);e.jsdoc&&i.push(`> ${e.jsdoc}`),i.push(``)}}let a=i.join(`
9
+ `);return a.length>1e5?`${a.slice(0,1e5)}\n\n*[truncated]*`:a}function C(e){let t=e.get(`symbols`);if(!t?.symbols?.length)return`# Type Inventory
10
+
11
+ *No symbol data available.*
12
+ `;let n=t.symbols.filter(e=>e.exported&&(e.kind===`interface`||e.kind===`type`||e.kind===`enum`));if(n.length===0)return`# Type Inventory
13
+
14
+ *No exported types/interfaces found.*
15
+ `;let r=new Map;for(let e of n){let t=r.get(e.filePath)??[];t.push(e),r.set(e.filePath,t)}let i=[`# Type Inventory
16
+ `];for(let[e,t]of[...r.entries()].sort(([e],[t])=>e.localeCompare(t))){i.push(`## ${e}\n`);for(let e of t){let t=e.typeBody??`*body not available*`;e.jsdoc&&i.push(`> ${e.jsdoc}`),i.push(`### ${e.kind} \`${e.name}\``),i.push("```"),i.push(t),i.push("```\n")}}let a=i.join(`
17
+ `);return a.length>1e5?`${a.slice(0,1e5)}\n\n*[truncated]*`:a}async function w(w){let T=Date.now(),E=m(w.path),D=f(E),O=w.mode??`generate`,k=w.outDir??p(E,b.aiKb),A=new c,j=new i,M=new l,N=new s,P=new o,F=new a,I=[{name:`structure`,fn:()=>A.analyze(E,{format:`markdown`,maxDepth:3,sourceOnly:!0})},{name:`dependencies`,fn:()=>j.analyze(E,{format:`markdown`})},{name:`entry-points`,fn:()=>P.analyze(E)},{name:`symbols`,fn:()=>M.analyze(E,{format:`markdown`})},{name:`patterns`,fn:()=>N.analyze(E)},{name:`diagram`,fn:()=>F.analyze(E,{diagramType:`architecture`})}],L=await Promise.allSettled(I.map(async e=>{let t=Date.now(),n=await e.fn();return{name:e.name,result:n,durationMs:Date.now()-t}})),R=[],z=new Map,B=new Map;for(let e of L)if(e.status===`fulfilled`){let{name:t,result:n,durationMs:r}=e.value,i=n;R.push({name:t,status:`success`,output:i.output,durationMs:r}),z.set(t,i.output),B.set(t,i.data)}else{let t=e.reason,n=I[L.indexOf(e)].name;R.push({name:n,status:`failed`,output:``,durationMs:0,error:t.message})}let V=Date.now(),H=null;try{let e=await d(E);if((!e||e.edges.length===0)&&(e=await u(E)),e&&e.edges.length>0){H=new Map;for(let t of e.edges){let e=H.get(t.from);e||(e=new Map,H.set(t.from,e));let n=e.get(t.to);if(n)for(let e of t.symbols)n.includes(e)||n.push(e);else e.set(t.to,[...t.symbols])}}}catch{}let U=Date.now()-V,W=Date.now(),G=n(B,D,H),K=Date.now()-W+U;if(R.push({name:`code-map`,status:`success`,output:G,durationMs:K}),z.set(`code-map`,G),H&&H.size>0){let e=t(H,B,D),n=R.find(e=>e.name===`diagram`);n&&(n.output=e,z.set(`diagram`,e))}let q=Date.now(),J=await e(E,D),Y=Date.now()-q;R.push({name:`config-values`,status:`success`,output:J,durationMs:Y}),z.set(`config-values`,J);let X=r(R,O,D,B);R.push({name:`synthesis-guide`,status:`success`,output:X,durationMs:0}),z.set(`synthesis-guide`,X);let Z=S(B);R.push({name:`api-surface`,status:`success`,output:Z,durationMs:0}),z.set(`api-surface`,Z);let Q=C(B);if(R.push({name:`type-inventory`,status:`success`,output:Q,durationMs:0}),z.set(`type-inventory`,Q),O===`generate`){if(h(k))for(let e of _(k))(e.endsWith(`.md`)||e.endsWith(`.json`))&&v(p(k,e),{force:!0});g(k,{recursive:!0});let e=new Date().toISOString();for(let[t,n]of z){let r=p(k,`${t}.md`),i=n.replaceAll(E,D);y(r,`<!-- Generated: ${e} -->\n<!-- Project: ${D} -->\n<!-- Source: ${E} -->\n\n`+i,`utf-8`)}let t=[`<!-- Generated: ${e} -->`,`<!-- Project: ${D} -->`,`<!-- Source: ${E} -->`,``,`# ${D} — Codebase Knowledge`,``,`## Contents`,``];for(let e of R){let n=`${e.name}.md`,r=x[e.name]??e.name,i=e.status===`success`?`✓`:`✗`,a=e.durationMs>0?` (${e.durationMs}ms)`:``;t.push(`- ${i} [${r}](./${n})${a}`)}t.push(``),y(p(k,`README.md`),t.join(`
18
+ `),`utf-8`)}return{path:E,mode:O,steps:R,outDir:O===`generate`?k:void 0,totalDurationMs:Date.now()-T}}export{w as onboard};
@@ -1,6 +1,6 @@
1
- import { IEmbedder } from "@kb/embeddings";
2
- import { IKnowledgeStore } from "@kb/store";
3
- import { ContentType, KnowledgeOrigin } from "@kb/core";
1
+ import { ContentType, KnowledgeOrigin } from "../../core/dist/index.js";
2
+ import { IEmbedder } from "../../embeddings/dist/index.js";
3
+ import { IKnowledgeStore } from "../../store/dist/index.js";
4
4
 
5
5
  //#region packages/tools/src/scope-map.d.ts
6
6
  interface ScopeMapOptions {
@@ -1,5 +1,5 @@
1
1
  import { FileCache } from "./file-cache.js";
2
- import { IEmbedder } from "@kb/embeddings";
2
+ import { IEmbedder } from "../../embeddings/dist/index.js";
3
3
 
4
4
  //#region packages/tools/src/stratum-card.d.ts
5
5
  interface StratumCardOptions {
@@ -1,5 +1,5 @@
1
- import { IEmbedder } from "@kb/embeddings";
2
- import { IGraphStore, IKnowledgeStore } from "@kb/store";
1
+ import { IEmbedder } from "../../embeddings/dist/index.js";
2
+ import { IGraphStore, IKnowledgeStore } from "../../store/dist/index.js";
3
3
 
4
4
  //#region packages/tools/src/symbol.d.ts
5
5
  interface SymbolGraphContext {
@@ -1,5 +1,5 @@
1
- import { IEmbedder } from "@kb/embeddings";
2
- import { IKnowledgeStore } from "@kb/store";
1
+ import { IEmbedder } from "../../embeddings/dist/index.js";
2
+ import { IKnowledgeStore } from "../../store/dist/index.js";
3
3
 
4
4
  //#region packages/tools/src/trace.d.ts
5
5
  interface TraceOptions {
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
- import { t as IKBClient } from "./types-VcTHNV6s.js";
2
+ import { t as IKBClient } from "./index-Cvx1a7S7.js";
3
3
  import React from "react";
4
4
 
5
5
  //#region packages/tui/src/App.d.ts
@@ -1,9 +1,9 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
- import { t as IKBClient } from "../types-VcTHNV6s.js";
3
- import * as react from "react";
2
+ import { t as IKBClient } from "../index-Cvx1a7S7.js";
3
+ import * as _$react from "react";
4
4
 
5
5
  //#region packages/tui/src/hooks/useKBClient.d.ts
6
- declare const KBClientProvider: react.Provider<IKBClient | null>;
6
+ declare const KBClientProvider: _$react.Provider<IKBClient | null>;
7
7
  declare function useKBClient(): IKBClient;
8
8
  //#endregion
9
9
  export { KBClientProvider, useKBClient };
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
- import { t as IKBClient } from "./types-VcTHNV6s.js";
2
+ import { t as IKBClient } from "./index-Cvx1a7S7.js";
3
3
 
4
4
  //#region packages/tui/src/index.d.ts
5
5
  declare function launch(client: IKBClient): void;
@@ -0,0 +1,192 @@
1
+ # Scaffold System — Contributor Guide
2
+
3
+ > **⚠️ GOLDEN RULE: Never edit files in `scaffold/general/` or `scaffold/claude-code/` directly.**
4
+ > They are **generated output** and will be overwritten by `generate.mjs`.
5
+ > Always edit the **source files** in `scaffold/definitions/`.
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ scaffold/
11
+ ├── definitions/ ← SOURCE OF TRUTH (edit here)
12
+ │ ├── agents.mjs Agent metadata (name, description, model, tools, category)
13
+ │ ├── bodies.mjs Agent body text (mode instructions per agent)
14
+ │ ├── models.mjs Available models per IDE
15
+ │ ├── protocols.mjs Shared protocol files (_shared/*.md) + templates
16
+ │ ├── tools.mjs Tool capability → IDE tool mappings
17
+ │ ├── prompts.mjs Prompt file content
18
+ │ ├── hooks.mjs Hook definitions
19
+ │ └── plugins.mjs Plugin definitions
20
+
21
+ ├── adapters/ ← IDE-specific generators
22
+ │ ├── copilot.mjs GitHub Copilot adapter (active — generates ~32 files)
23
+ │ └── claude-code.mjs Claude Code adapter (stub — no output yet)
24
+
25
+ ├── generate.mjs ← BUILD SCRIPT (run after any change)
26
+
27
+ ├── general/ ← GENERATED OUTPUT for Copilot (DO NOT EDIT)
28
+ │ ├── agents/
29
+ │ │ ├── _shared/ Protocol files (from PROTOCOLS in protocols.mjs)
30
+ │ │ ├── templates/ Template files (from TEMPLATES in protocols.mjs)
31
+ │ │ └── *.agent.md Agent files (from AGENT_BODIES in bodies.mjs)
32
+ │ └── prompts/ Prompt files (from PROMPTS in prompts.mjs)
33
+
34
+ └── claude-code/ ← GENERATED OUTPUT for Claude Code (stub, DO NOT EDIT)
35
+ ```
36
+
37
+ ### Data Flow
38
+
39
+ ```
40
+ definitions/*.mjs → generate.mjs → scaffold/general/ → kb init → .github/ (user project)
41
+ (source) (build script) (generated output) (deploy) (user workspace)
42
+ ```
43
+
44
+ ## How to Make Changes
45
+
46
+ ### Step 1: Edit Source Files
47
+
48
+ | What you want to change | Edit this file |
49
+ |--------------------------|---------------|
50
+ | An agent's body/instructions | `definitions/bodies.mjs` → `AGENT_BODIES[agentName]` |
51
+ | Shared rules for code agents | `definitions/protocols.mjs` → `PROTOCOLS['code-agent-base']` |
52
+ | Shared rules for researchers | `definitions/protocols.mjs` → `PROTOCOLS['researcher-base']` |
53
+ | Agent metadata (model, tools) | `definitions/agents.mjs` → `AGENTS[agentName]` |
54
+ | Available models | `definitions/models.mjs` |
55
+ | Tool mappings | `definitions/tools.mjs` |
56
+ | Prompt files | `definitions/prompts.mjs` |
57
+
58
+ ### Step 2: Regenerate Output
59
+
60
+ ```bash
61
+ node scaffold/generate.mjs
62
+ ```
63
+
64
+ This will:
65
+ 1. Clean `general/agents/` and `general/prompts/` directories
66
+ 2. Regenerate all files from definitions via the copilot adapter
67
+ 3. Print every file written (expect ~32 files)
68
+
69
+ To generate for a specific IDE only:
70
+ ```bash
71
+ node scaffold/generate.mjs --ide copilot
72
+ node scaffold/generate.mjs --ide claude-code
73
+ ```
74
+
75
+ ### Step 3: Verify
76
+
77
+ ```bash
78
+ # Syntax check the source file you edited
79
+ node -c scaffold/definitions/bodies.mjs
80
+ node -c scaffold/definitions/protocols.mjs
81
+
82
+ # Verify your changes appear in generated output
83
+ # (use grep/Select-String for key phrases)
84
+ grep -r "your key phrase" scaffold/general/agents/
85
+ ```
86
+
87
+ ### Step 4: Commit Both Source AND Generated
88
+
89
+ Always commit the definition source files AND the regenerated output together.
90
+ The generated files are checked into git so `kb init` can deploy them without
91
+ running the generator.
92
+
93
+ ## Source File Details
94
+
95
+ ### bodies.mjs
96
+
97
+ Contains `AGENT_BODIES` — an object mapping agent names to their body text.
98
+
99
+ - Most values are **template literal strings** (`` `...` ``)
100
+ - The **Orchestrator** body is a **function** `(agentTable) => string` because it
101
+ dynamically includes the agent roster table
102
+ - Backticks inside content must be escaped: `` \` ``
103
+
104
+ ```js
105
+ export const AGENT_BODIES = {
106
+ Orchestrator: (agentTable) => `# Orchestrator\n${agentTable}\n...`,
107
+ Implementer: `# Implementer\n...`,
108
+ Debugger: `# Debugger\n...`,
109
+ // ...
110
+ };
111
+ ```
112
+
113
+ ### protocols.mjs
114
+
115
+ Contains `PROTOCOLS` and `TEMPLATES` — objects mapping names to markdown content.
116
+
117
+ - Each `PROTOCOLS` key becomes a file in `_shared/`:
118
+ - `'code-agent-base'` → `agents/_shared/code-agent-base.md`
119
+ - `'researcher-base'` → `agents/_shared/researcher-base.md`
120
+ - `'decision-protocol'` → `agents/_shared/decision-protocol.md`
121
+ - etc.
122
+ - Each `TEMPLATES` key becomes a file in `templates/`
123
+ - All values are template literals — escape backticks as `` \` ``
124
+
125
+ **Protocol → Agent mapping:**
126
+
127
+ | Protocol | Used by |
128
+ |----------|---------|
129
+ | `code-agent-base` | Implementer, Frontend, Refactor, Debugger |
130
+ | `researcher-base` | Researcher-Alpha/Beta/Gamma/Delta |
131
+ | `code-reviewer-base` | Code-Reviewer-Alpha/Beta |
132
+ | `architect-reviewer-base` | Architect-Reviewer-Alpha/Beta |
133
+ | `decision-protocol` | Referenced by Orchestrator workflow |
134
+ | `forge-protocol` | Referenced by code-agent-base |
135
+
136
+ ### agents.mjs
137
+
138
+ Defines every agent's metadata:
139
+ - `description`, `argumentHint` — displayed in the agent picker
140
+ - `model` — which LLM model to use
141
+ - `tools` — abstract capability list (mapped to IDE-specific tools by the adapter)
142
+ - `category` — orchestration, implementation, diagnostics, research, review, etc.
143
+ - `sharedBase` — for variant agents (e.g., Researcher-Alpha uses `researcher-base`)
144
+
145
+ ## How Users Receive Changes
146
+
147
+ When users run `kb init`, the scaffold files are deployed to their `.github/` directory.
148
+
149
+ ### First Install (Legacy Path)
150
+
151
+ `copyDirectoryRecursive()` — copies all scaffold files, **skips existing** files.
152
+ No tracking, no merging.
153
+
154
+ ### Updates (Smart Path)
155
+
156
+ `smartCopyScaffold()` — manifest-based with `.kb-scaffold.json`:
157
+
158
+ | File Status | Strategy | Behavior |
159
+ |-------------|----------|----------|
160
+ | `new` (not in manifest, not on disk) | deploy | Copy file, record hash |
161
+ | `new` (not in manifest, exists on disk) | record | Record hash only (preserve user edits) |
162
+ | `outdated` (source hash changed) | `merge-frontmatter` | **Agent files**: update body, union tools, keep user's model choice |
163
+ | `outdated` (source hash changed) | `overwrite` | **Protocol/shared files**: replace entirely |
164
+ | `current` (unchanged) | skip | No action |
165
+
166
+ The update strategy is determined by `getUpdateStrategy(relPath)` based on the file path.
167
+
168
+ **Key implication**: When you update an agent body in `bodies.mjs`, existing users will
169
+ get the updated body text while preserving their custom model choice and any extra tools
170
+ they added. Protocol files (`_shared/*.md`) are fully replaced.
171
+
172
+ ## Common Mistakes
173
+
174
+ | Mistake | Why it's wrong | What to do instead |
175
+ |---------|---------------|-------------------|
176
+ | Editing `.agent.md` in `general/agents/` | Will be overwritten by `generate.mjs` | Edit `bodies.mjs` for agent bodies |
177
+ | Editing `_shared/*.md` in `general/agents/` | Will be overwritten by `generate.mjs` | Edit `protocols.mjs` PROTOCOLS constant |
178
+ | Forgetting to run `generate.mjs` | Generated files will be stale, `kb init` deploys stale files | Always run after editing definitions |
179
+ | Committing only source OR only generated | Source and output will be out of sync | Commit both together |
180
+ | Unescaped backticks in template literals | JS syntax error in definitions | Use `` \` `` inside template literal strings |
181
+
182
+ ## PR Checklist
183
+
184
+ - [ ] Changes made in `scaffold/definitions/*.mjs` (NOT in generated output)
185
+ - [ ] `node -c scaffold/definitions/<changed-file>.mjs` passes (syntax check)
186
+ - [ ] `node scaffold/generate.mjs` runs without errors
187
+ - [ ] Generated output contains expected changes (verified with grep)
188
+ - [ ] Both source and generated files included in commit
189
+ - [ ] If adding a new agent: entry in `agents.mjs` + body in `bodies.mjs`
190
+ - [ ] If adding a new protocol: entry in `protocols.mjs` + reference in relevant agent bodies
191
+ - [ ] If adding a new file type: check `getUpdateStrategy()` returns correct merge strategy
192
+ - [ ] Consider impact on existing user installations (will merge preserve their customizations?)