@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.
- package/package.json +1 -1
- package/packages/analyzers/dist/symbol-analyzer.js +4 -4
- package/packages/analyzers/dist/types.d.ts +8 -0
- package/packages/chunker/dist/chunker.interface.d.ts +1 -1
- package/packages/chunker/dist/code-chunker.d.ts +1 -1
- package/packages/chunker/dist/extractors/symbol-extractor.js +3 -1
- package/packages/chunker/dist/extractors/types.d.ts +8 -0
- package/packages/chunker/dist/generic-chunker.d.ts +1 -1
- package/packages/chunker/dist/markdown-chunker.d.ts +1 -1
- package/packages/chunker/dist/wasm-chunker.d.ts +1 -1
- package/packages/cli/dist/commands/upgrade.d.ts +6 -0
- package/packages/cli/dist/commands/upgrade.js +1 -0
- package/packages/cli/dist/helpers.d.ts +2 -2
- package/packages/cli/dist/index.js +2 -2
- package/packages/cli/dist/kb-init.d.ts +4 -4
- package/packages/core/dist/types.d.ts +2 -0
- package/packages/elicitation/dist/index.d.ts +2 -2
- package/packages/elicitation/dist/index.js +2 -2
- package/packages/enterprise-bridge/dist/result-merger.d.ts +1 -1
- package/packages/indexer/dist/graph-extractor.d.ts +1 -1
- package/packages/indexer/dist/incremental-indexer.d.ts +3 -3
- package/packages/kb-client/dist/direct-client.d.ts +2 -2
- package/packages/present/dist/index.html +4 -4
- package/packages/server/dist/completions.d.ts +1 -1
- package/packages/server/dist/config.d.ts +1 -1
- package/packages/server/dist/config.js +1 -1
- package/packages/server/dist/cross-workspace.d.ts +2 -2
- package/packages/server/dist/curated-manager.d.ts +2 -2
- package/packages/server/dist/dashboard-static.d.ts +2 -2
- package/packages/server/dist/elicitor.d.ts +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/output-schemas.d.ts +4 -0
- package/packages/server/dist/output-schemas.js +1 -1
- package/packages/server/dist/prompts.d.ts +1 -1
- package/packages/server/dist/resources/resources.d.ts +1 -1
- package/packages/server/dist/server.d.ts +7 -7
- package/packages/server/dist/server.js +2 -2
- package/packages/server/dist/structured-content-guard.d.ts +26 -0
- package/packages/server/dist/structured-content-guard.js +1 -0
- package/packages/server/dist/tools/analyze.tools.d.ts +2 -2
- package/packages/server/dist/tools/audit.tool.d.ts +2 -2
- package/packages/server/dist/tools/brainstorm.tool.d.ts +1 -1
- package/packages/server/dist/tools/bridge.tools.d.ts +1 -1
- package/packages/server/dist/tools/context.tools.d.ts +3 -3
- package/packages/server/dist/tools/context.tools.js +2 -1
- package/packages/server/dist/tools/evolution.tools.d.ts +1 -1
- package/packages/server/dist/tools/execution.tools.d.ts +2 -2
- package/packages/server/dist/tools/forge.tools.d.ts +3 -3
- package/packages/server/dist/tools/graph.tool.d.ts +1 -1
- package/packages/server/dist/tools/infra.tools.js +4 -2
- package/packages/server/dist/tools/lookup.tool.d.ts +1 -1
- package/packages/server/dist/tools/onboard.tool.d.ts +4 -3
- package/packages/server/dist/tools/onboard.tool.js +1 -1
- package/packages/server/dist/tools/policy.tools.d.ts +1 -1
- package/packages/server/dist/tools/present.tool.d.ts +1 -1
- package/packages/server/dist/tools/produce.tool.d.ts +2 -1
- package/packages/server/dist/tools/produce.tool.js +2 -2
- package/packages/server/dist/tools/reindex.tool.d.ts +3 -3
- package/packages/server/dist/tools/remember.tool.d.ts +1 -1
- package/packages/server/dist/tools/search.tool.d.ts +3 -3
- package/packages/server/dist/tools/status.tool.d.ts +3 -2
- package/packages/server/dist/tools/status.tool.js +2 -2
- package/packages/server/dist/tools/utility.tools.js +4 -2
- package/packages/server/dist/version-check.js +1 -1
- package/packages/store/dist/lance-store.d.ts +1 -1
- package/packages/store/dist/store.interface.d.ts +1 -1
- package/packages/tools/dist/audit.d.ts +2 -2
- package/packages/tools/dist/compact.d.ts +1 -1
- package/packages/tools/dist/dead-symbols.d.ts +2 -2
- package/packages/tools/dist/digest.d.ts +1 -1
- package/packages/tools/dist/find-examples.d.ts +3 -3
- package/packages/tools/dist/find.d.ts +7 -3
- package/packages/tools/dist/find.js +1 -1
- package/packages/tools/dist/forge-ground.d.ts +2 -2
- package/packages/tools/dist/graph-query.d.ts +1 -1
- package/packages/tools/dist/onboard.js +18 -2
- package/packages/tools/dist/scope-map.d.ts +3 -3
- package/packages/tools/dist/stratum-card.d.ts +1 -1
- package/packages/tools/dist/symbol.d.ts +2 -2
- package/packages/tools/dist/trace.d.ts +2 -2
- package/packages/tui/dist/App.d.ts +1 -1
- package/packages/tui/dist/hooks/useKBClient.d.ts +3 -3
- package/packages/tui/dist/index.d.ts +1 -1
- package/scaffold/README.md +192 -0
- package/scaffold/definitions/bodies.mjs +140 -28
- package/scaffold/definitions/protocols.mjs +232 -24
- package/scaffold/general/agents/Debugger.agent.md +9 -6
- package/scaffold/general/agents/Documenter.agent.md +13 -2
- package/scaffold/general/agents/Explorer.agent.md +12 -0
- package/scaffold/general/agents/Frontend.agent.md +1 -1
- package/scaffold/general/agents/Implementer.agent.md +3 -1
- package/scaffold/general/agents/Orchestrator.agent.md +67 -11
- package/scaffold/general/agents/Planner.agent.md +19 -2
- package/scaffold/general/agents/Refactor.agent.md +1 -1
- package/scaffold/general/agents/Security.agent.md +13 -2
- package/scaffold/general/agents/_shared/architect-reviewer-base.md +11 -2
- package/scaffold/general/agents/_shared/code-agent-base.md +181 -17
- package/scaffold/general/agents/_shared/code-reviewer-base.md +11 -2
- package/scaffold/general/agents/_shared/researcher-base.md +29 -3
- package/packages/elicitation/dist/__tests__/build.test.d.ts +0 -1
- package/packages/elicitation/dist/__tests__/fields.test.d.ts +0 -1
- package/packages/elicitation/dist/__tests__/normalize.test.d.ts +0 -1
- package/packages/elicitation/dist/build.d.ts +0 -13
- package/packages/elicitation/dist/fields.d.ts +0 -41
- package/packages/elicitation/dist/normalize.d.ts +0 -15
- package/packages/elicitation/dist/types.d.ts +0 -85
- /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:{
|
|
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}}
|
|
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
|
|
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 "
|
|
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 "
|
|
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 "
|
|
3
|
-
import { IKnowledgeStore } from "
|
|
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
|
-
import { IEmbedder } from "
|
|
2
|
-
import { IKnowledgeStore } from "
|
|
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,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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 "
|
|
5
|
-
import { IKnowledgeStore } from "
|
|
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 "
|
|
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
|
|
2
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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
|
-
import { IEmbedder } from "
|
|
2
|
-
import { IGraphStore, IKnowledgeStore } from "
|
|
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 "
|
|
2
|
-
import { IKnowledgeStore } from "
|
|
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 "./
|
|
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 "../
|
|
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 "./
|
|
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?)
|