@vpxa/kb 0.1.23 → 0.1.25
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/README.md +3 -3
- package/package.json +9 -2
- package/packages/analyzers/dist/symbol-analyzer.js +5 -5
- package/packages/cli/dist/commands/init/adapters.js +1 -1
- package/packages/cli/dist/commands/init/constants.d.ts +4 -1
- package/packages/cli/dist/commands/init/constants.js +1 -1
- package/packages/cli/dist/commands/init/frontmatter.d.ts +54 -0
- package/packages/cli/dist/commands/init/frontmatter.js +2 -0
- package/packages/cli/dist/commands/init/index.js +4 -4
- package/packages/cli/dist/commands/init/manifest.d.ts +71 -0
- package/packages/cli/dist/commands/init/manifest.js +1 -0
- package/packages/cli/dist/commands/init/scaffold.d.ts +28 -5
- package/packages/cli/dist/commands/init/scaffold.js +1 -1
- package/packages/cli/dist/commands/init/templates.js +38 -9
- package/packages/cli/dist/commands/init/user.d.ts +1 -1
- package/packages/cli/dist/commands/init/user.js +4 -4
- package/packages/cli/dist/commands/system.js +2 -2
- package/packages/cli/dist/kb-init.js +1 -1
- package/packages/core/dist/errors.d.ts +2 -2
- package/packages/core/dist/errors.js +1 -1
- package/packages/core/dist/logger.d.ts +2 -1
- package/packages/core/dist/logger.js +1 -1
- package/packages/core/dist/types.d.ts +6 -0
- package/packages/dashboard/dist/assets/index-9ysCkze9.js +21 -0
- package/packages/dashboard/dist/assets/index-9ysCkze9.js.map +1 -0
- package/packages/dashboard/dist/assets/index-CHpVij2M.css +1 -0
- package/packages/dashboard/dist/index.html +18 -0
- package/packages/elicitation/dist/__tests__/build.test.d.ts +1 -0
- package/packages/elicitation/dist/__tests__/build.test.js +35 -0
- package/packages/elicitation/dist/__tests__/fields.test.d.ts +1 -0
- package/packages/elicitation/dist/__tests__/fields.test.js +81 -0
- package/packages/elicitation/dist/__tests__/normalize.test.d.ts +1 -0
- package/packages/elicitation/dist/__tests__/normalize.test.js +60 -0
- package/packages/elicitation/dist/build.d.ts +13 -0
- package/packages/elicitation/dist/build.js +23 -0
- package/packages/elicitation/dist/fields.d.ts +41 -0
- package/packages/elicitation/dist/fields.js +62 -0
- package/packages/elicitation/dist/index.d.ts +10 -0
- package/packages/elicitation/dist/index.js +12 -0
- package/packages/elicitation/dist/normalize.d.ts +15 -0
- package/packages/elicitation/dist/normalize.js +31 -0
- package/packages/elicitation/dist/types.d.ts +85 -0
- package/packages/elicitation/dist/types.js +8 -0
- package/packages/kb-client/dist/direct-client.d.ts +37 -0
- package/packages/kb-client/dist/direct-client.js +1 -0
- package/packages/kb-client/dist/index.d.ts +5 -0
- package/packages/kb-client/dist/index.js +1 -0
- package/packages/kb-client/dist/mcp-client.d.ts +19 -0
- package/packages/kb-client/dist/mcp-client.js +4 -0
- package/packages/kb-client/dist/parsers.d.ts +35 -0
- package/packages/kb-client/dist/parsers.js +2 -0
- package/packages/kb-client/dist/types.d.ts +62 -0
- package/packages/kb-client/dist/types.js +1 -0
- package/packages/present/dist/index.html +384 -0
- package/packages/server/dist/completions.d.ts +14 -0
- package/packages/server/dist/completions.js +1 -0
- package/packages/server/dist/config.js +1 -1
- package/packages/server/dist/dashboard-static.d.ts +27 -0
- package/packages/server/dist/dashboard-static.js +1 -0
- package/packages/server/dist/elicitor.d.ts +18 -0
- package/packages/server/dist/elicitor.js +1 -0
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/mcp-logging.js +1 -1
- package/packages/server/dist/output-schemas.d.ts +118 -1
- package/packages/server/dist/output-schemas.js +1 -1
- package/packages/server/dist/prompts.d.ts +9 -2
- package/packages/server/dist/prompts.js +13 -6
- package/packages/server/dist/resources/curated-resources.js +1 -1
- package/packages/server/dist/resources/resource-notifier.d.ts +45 -0
- package/packages/server/dist/resources/resource-notifier.js +1 -0
- package/packages/server/dist/sampling.d.ts +41 -0
- package/packages/server/dist/sampling.js +2 -0
- package/packages/server/dist/server.d.ts +5 -2
- package/packages/server/dist/server.js +3 -1
- package/packages/server/dist/task-manager.d.ts +40 -0
- package/packages/server/dist/task-manager.js +1 -0
- package/packages/server/dist/tool-metadata.js +1 -1
- package/packages/server/dist/tool-prefix.d.ts +12 -0
- package/packages/server/dist/tool-prefix.js +1 -0
- package/packages/server/dist/tools/analyze.tools.js +4 -4
- package/packages/server/dist/tools/audit.tool.js +1 -1
- package/packages/server/dist/tools/brainstorm.tool.d.ts +7 -0
- package/packages/server/dist/tools/brainstorm.tool.js +9 -0
- package/packages/server/dist/tools/bridge.tools.js +1 -1
- package/packages/server/dist/tools/context.tools.js +9 -9
- package/packages/server/dist/tools/execution.tools.d.ts +2 -1
- package/packages/server/dist/tools/execution.tools.js +4 -3
- package/packages/server/dist/tools/forge.tools.js +10 -10
- package/packages/server/dist/tools/forget.tool.d.ts +2 -1
- package/packages/server/dist/tools/forget.tool.js +1 -1
- package/packages/server/dist/tools/graph.tool.js +2 -2
- package/packages/server/dist/tools/infra.tools.js +2 -2
- package/packages/server/dist/tools/list.tool.js +2 -2
- package/packages/server/dist/tools/lookup.tool.js +1 -1
- package/packages/server/dist/tools/manipulation.tools.js +4 -4
- package/packages/server/dist/tools/onboard.tool.js +2 -2
- package/packages/server/dist/tools/persistence.tools.js +4 -4
- package/packages/server/dist/tools/policy.tools.js +3 -2
- package/packages/server/dist/tools/present-blocks.d.ts +46 -0
- package/packages/server/dist/tools/present-blocks.js +27 -0
- package/packages/server/dist/tools/present-charts.d.ts +31 -0
- package/packages/server/dist/tools/present-charts.js +34 -0
- package/packages/server/dist/tools/present-theme.d.ts +14 -0
- package/packages/server/dist/tools/present-theme.js +395 -0
- package/packages/server/dist/tools/present-utils.d.ts +11 -0
- package/packages/server/dist/tools/present-utils.js +1 -0
- package/packages/server/dist/tools/present.tool.d.ts +7 -0
- package/packages/server/dist/tools/present.tool.js +113 -0
- package/packages/server/dist/tools/produce.tool.js +2 -2
- package/packages/server/dist/tools/read.tool.js +1 -1
- package/packages/server/dist/tools/reindex.tool.d.ts +2 -1
- package/packages/server/dist/tools/reindex.tool.js +2 -2
- package/packages/server/dist/tools/remember.tool.d.ts +2 -1
- package/packages/server/dist/tools/remember.tool.js +2 -2
- package/packages/server/dist/tools/replay.tool.js +2 -2
- package/packages/server/dist/tools/search.tool.d.ts +2 -1
- package/packages/server/dist/tools/search.tool.js +5 -4
- package/packages/server/dist/tools/status.tool.js +2 -2
- package/packages/server/dist/tools/update.tool.d.ts +2 -1
- package/packages/server/dist/tools/update.tool.js +1 -1
- package/packages/server/dist/tools/utility.tools.js +8 -8
- package/packages/store/dist/lance-store.d.ts +1 -0
- package/packages/store/dist/lance-store.js +1 -1
- package/packages/tools/dist/audit.js +1 -1
- package/packages/tools/dist/batch.js +1 -1
- package/packages/tools/dist/check.js +1 -1
- package/packages/tools/dist/checkpoint.js +1 -1
- package/packages/tools/dist/compact.js +2 -2
- package/packages/tools/dist/config-extractor.d.ts +9 -0
- package/packages/tools/dist/config-extractor.js +7 -0
- package/packages/tools/dist/dead-symbols.js +2 -2
- package/packages/tools/dist/diagram-builder.d.ts +9 -0
- package/packages/tools/dist/diagram-builder.js +9 -0
- package/packages/tools/dist/eval.js +2 -2
- package/packages/tools/dist/evidence-map.d.ts +12 -1
- package/packages/tools/dist/evidence-map.js +2 -2
- package/packages/tools/dist/file-summary.js +2 -2
- package/packages/tools/dist/find-examples.js +2 -2
- package/packages/tools/dist/forge-classify.d.ts +4 -0
- package/packages/tools/dist/forge-classify.js +1 -1
- package/packages/tools/dist/git-context.d.ts +1 -0
- package/packages/tools/dist/git-context.js +3 -3
- package/packages/tools/dist/index.d.ts +3 -2
- package/packages/tools/dist/index.js +1 -1
- package/packages/tools/dist/onboard-utils.d.ts +12 -0
- package/packages/tools/dist/onboard-utils.js +1 -0
- package/packages/tools/dist/onboard.js +2 -21
- package/packages/tools/dist/queue.js +1 -1
- package/packages/tools/dist/regex-utils.d.ts +8 -0
- package/packages/tools/dist/regex-utils.js +1 -0
- package/packages/tools/dist/rename.js +2 -2
- package/packages/tools/dist/replay.d.ts +2 -1
- package/packages/tools/dist/replay.js +4 -4
- package/packages/tools/dist/symbol.js +3 -3
- package/packages/tools/dist/synthesis-engine.d.ts +13 -0
- package/packages/tools/dist/synthesis-engine.js +6 -0
- package/packages/tools/dist/test-run.d.ts +3 -1
- package/packages/tools/dist/test-run.js +1 -1
- package/packages/tools/dist/trace.js +2 -2
- package/packages/tui/dist/App-DXY0-tlW.js +2 -0
- package/packages/tui/dist/App.d.ts +3 -3
- package/packages/tui/dist/App.js +1 -1
- package/packages/tui/dist/CuratedPanel-BIamXLNy.js +2 -0
- package/packages/tui/dist/LogPanel-D6u6o84n.js +3 -0
- package/packages/tui/dist/SearchPanel-CpJGczAc.js +2 -0
- package/packages/tui/dist/StatusPanel-BAbUxyqQ.js +2 -0
- package/packages/tui/dist/hooks/useKBClient.d.ts +9 -0
- package/packages/tui/dist/hooks/useKBClient.js +2 -0
- package/packages/tui/dist/hooks/usePolling.d.ts +8 -0
- package/packages/tui/dist/hooks/usePolling.js +2 -0
- package/packages/tui/dist/index.d.ts +6 -2
- package/packages/tui/dist/index.js +1 -1
- package/packages/tui/dist/jsx-runtime-y6Gdq5PZ.js +294 -0
- package/packages/tui/dist/panels/CuratedPanel.d.ts +1 -7
- package/packages/tui/dist/panels/CuratedPanel.js +1 -1
- package/packages/tui/dist/panels/LogPanel.js +1 -1
- package/packages/tui/dist/panels/SearchPanel.d.ts +1 -10
- package/packages/tui/dist/panels/SearchPanel.js +1 -1
- package/packages/tui/dist/panels/StatusPanel.d.ts +1 -7
- package/packages/tui/dist/panels/StatusPanel.js +1 -1
- package/packages/tui/dist/react-D__J1GQe.js +24 -0
- package/packages/tui/dist/types-VcTHNV6s.d.ts +64 -0
- package/packages/tui/dist/useKBClient-C35iA4uG.js +2 -0
- package/packages/tui/dist/usePolling-BbjnRWgx.js +2 -0
- package/scaffold/adapters/copilot.mjs +9 -81
- package/scaffold/definitions/agents.mjs +12 -0
- package/scaffold/definitions/bodies.mjs +39 -14
- package/scaffold/definitions/protocols.mjs +149 -0
- package/scaffold/definitions/tools.mjs +40 -5
- package/scaffold/general/agents/Architect-Reviewer-Alpha.agent.md +1 -1
- package/scaffold/general/agents/Architect-Reviewer-Beta.agent.md +1 -1
- package/scaffold/general/agents/Code-Reviewer-Alpha.agent.md +1 -1
- package/scaffold/general/agents/Code-Reviewer-Beta.agent.md +1 -1
- package/scaffold/general/agents/Debugger.agent.md +2 -2
- package/scaffold/general/agents/Documenter.agent.md +2 -2
- package/scaffold/general/agents/Explorer.agent.md +4 -3
- package/scaffold/general/agents/Frontend.agent.md +1 -1
- package/scaffold/general/agents/Implementer.agent.md +1 -1
- package/scaffold/general/agents/Orchestrator.agent.md +16 -1
- package/scaffold/general/agents/Planner.agent.md +11 -4
- package/scaffold/general/agents/Refactor.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Alpha.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Beta.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Delta.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Gamma.agent.md +1 -1
- package/scaffold/general/agents/Security.agent.md +10 -8
- package/scaffold/general/agents/_shared/architect-reviewer-base.md +1 -0
- package/scaffold/general/agents/_shared/code-agent-base.md +28 -0
- package/scaffold/general/agents/_shared/code-reviewer-base.md +1 -0
- package/scaffold/general/agents/_shared/forge-protocol.md +44 -0
- package/scaffold/general/agents/_shared/researcher-base.md +14 -0
- package/scaffold/general/agents/templates/adr-template.md +1 -0
- package/scaffold/general/agents/templates/execution-state.md +1 -0
- package/skills/knowledge-base/SKILL.md +19 -6
- package/skills/present/SKILL.md +153 -0
- package/packages/server/dist/tools/toolkit.tools.d.ts +0 -36
- package/packages/server/dist/tools/toolkit.tools.js +0 -20
- package/packages/tui/dist/App-DE_tdOhs.js +0 -2
- package/packages/tui/dist/CuratedPanel-sYdZAICX.js +0 -2
- package/packages/tui/dist/LogPanel-Ce3jMQbH.js +0 -3
- package/packages/tui/dist/SearchPanel-DREo6zgt.js +0 -2
- package/packages/tui/dist/StatusPanel-2ex8fLOO.js +0 -2
- package/packages/tui/dist/embedder.interface-IFCBpOlX.d.ts +0 -28
- package/packages/tui/dist/index-C8NmOF18.d.ts +0 -13
- package/packages/tui/dist/jsx-runtime-Cof-kwFn.js +0 -316
- package/packages/tui/dist/store.interface-CnY6SPOH.d.ts +0 -150
- /package/packages/tui/dist/{devtools-DUyj952l.js → devtools-DMOZMn70.js} +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{createLogger as n,serializeError as r}from"../../../core/dist/index.js";import{replayClear as i,replayList as a,replayTrim as o}from"../../../tools/dist/index.js";const s=n(`tools`);function c(n){let c=e(`replay`);n.registerTool(`replay`,{title:c.title,description:`View or clear the audit trail of recent MCP tool and CLI invocations. Shows tool name, duration, status, and input/output summaries.`,inputSchema:{action:t.enum([`list`,`clear`]).default(`list`).describe(`Action: "list" (default) to view entries, "clear" to wipe the log`),last:t.number().optional().describe(`Number of entries to return (default: 20, list only)`),tool:t.string().optional().describe(`Filter by tool name (list only)`),source:t.enum([`mcp`,`cli`]).optional().describe(`Filter by source: "mcp" or "cli" (list only)`),since:t.string().optional().describe(`ISO timestamp — only show entries after this time (list only)`)},annotations:c.annotations},async({action:e,last:t,tool:n,source:c,since:l})=>{try{if(e===`clear`)return i(),{content:[{type:`text`,text:`Replay log cleared.`}]};let r=a({last:t,tool:n,source:c,since:l});if(r.length===0)return{content:[{type:`text`,text:`No replay entries found. Activity is logged when tools are invoked via MCP or CLI.`}]};let s=r.map(e=>`${e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts} ${e.status===`ok`?`✓`:`✗`} ${e.tool} (${e.durationMs}ms) [${e.source}]\n in: ${e.input}\n out: ${e.output}`);return o(),{content:[{type:`text`,text:`**Replay Log** (${r.length} entries)\n\n${s.join(`
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{createLogger as n,serializeError as r}from"../../../core/dist/index.js";import{replayClear as i,replayList as a,replayTrim as o}from"../../../tools/dist/index.js";const s=n(`tools`);function c(n){let c=e(`replay`);n.registerTool(`replay`,{title:c.title,description:`View or clear the audit trail of recent MCP tool and CLI invocations. Shows tool name, duration, status, and input/output summaries.`,inputSchema:{action:t.enum([`list`,`clear`]).default(`list`).describe(`Action: "list" (default) to view entries, "clear" to wipe the log`),last:t.number().optional().describe(`Number of entries to return (default: 20, list only)`),tool:t.string().optional().describe(`Filter by tool name (list only)`),source:t.enum([`mcp`,`cli`]).optional().describe(`Filter by source: "mcp" or "cli" (list only)`),since:t.string().optional().describe(`ISO timestamp — only show entries after this time (list only)`)},annotations:c.annotations},async({action:e,last:t,tool:n,source:c,since:l})=>{try{if(e===`clear`)return i(),{content:[{type:`text`,text:`Replay log cleared.`}]};let r=a({last:t,tool:n,source:c,since:l});if(r.length===0)return{content:[{type:`text`,text:`No replay entries found. Activity is logged when tools are invoked via MCP or CLI.`}]};let s=r.map(e=>`${e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts} ${e.status===`ok`?`✓`:`✗`} ${e.tool} (${e.durationMs}ms) [${e.source}]\n in: ${e.input}\n out: ${e.output}`);return o().catch(()=>{}),{content:[{type:`text`,text:`**Replay Log** (${r.length} entries)\n\n${s.join(`
|
|
2
2
|
|
|
3
|
-
`)}`}]}}catch(e){return s.error(`Replay failed`,r(e)),{content:[{type:`text`,text:`Replay failed
|
|
3
|
+
`)}`}]}}catch(e){return s.error(`Replay failed`,r(e)),{content:[{type:`text`,text:`Replay failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{c as registerReplayTool};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ISamplingClient } from "../sampling.js";
|
|
1
2
|
import { BridgeComponents } from "./bridge.tools.js";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
import { IEmbedder } from "@kb/embeddings";
|
|
@@ -5,6 +6,6 @@ import { EvolutionCollector } from "@kb/enterprise-bridge";
|
|
|
5
6
|
import { IGraphStore, IKnowledgeStore } from "@kb/store";
|
|
6
7
|
|
|
7
8
|
//#region packages/server/src/tools/search.tool.d.ts
|
|
8
|
-
declare function registerSearchTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore, graphStore?: IGraphStore, bridge?: BridgeComponents, evolutionCollector?: EvolutionCollector): void;
|
|
9
|
+
declare function registerSearchTool(server: McpServer, embedder: IEmbedder, store: IKnowledgeStore, graphStore?: IGraphStore, bridge?: BridgeComponents, evolutionCollector?: EvolutionCollector, samplingClient?: ISamplingClient): void;
|
|
9
10
|
//#endregion
|
|
10
11
|
export { registerSearchTool };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{fanOutFtsSearch as
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{SearchOutputSchema as t}from"../output-schemas.js";import{fanOutFtsSearch as n,fanOutSearch as r,openWorkspaceStores as i,resolveWorkspaces as a}from"../cross-workspace.js";import{curatedResourceLink as o,extractCuratedPath as s}from"../resource-links.js";import{stat as c}from"node:fs/promises";import{z as l}from"zod";import{CONTENT_TYPES as u,KNOWLEDGE_ORIGINS as d,SOURCE_TYPES as f,computePartitionKey as p,createLogger as m,serializeError as h}from"../../../core/dist/index.js";import{graphAugmentSearch as g,truncateToTokenBudget as _}from"../../../tools/dist/index.js";import{mergeResults as v}from"../../../enterprise-bridge/dist/index.js";const y=m(`tools`);async function b(e,t,n,r,i){if(!e||t>=e.config.fallbackThreshold&&n.length>0)return{results:n,triggered:!1,cacheHit:!1};let a=!1;try{let t=e.cache.get(r);return t?a=!0:(t=await e.client.search(r,i),t.length>0&&e.cache.set(r,t)),t.length>0?{results:v(n,t,i).map(e=>({record:{id:`er:${e.sourcePath}`,content:e.content,sourcePath:e.source===`er`?`[ER] ${e.sourcePath}`:e.sourcePath,startLine:e.startLine??0,endLine:e.endLine??0,contentType:e.contentType??`documentation`,headingPath:e.headingPath,origin:e.source===`er`?`curated`:e.origin??`indexed`,category:e.category,tags:e.tags??[],chunkIndex:0,totalChunks:1,fileHash:``,indexedAt:new Date().toISOString(),version:1},score:e.score})),triggered:!0,cacheHit:a}:{results:n,triggered:!0,cacheHit:a}}catch(e){return y.warn(`ER fallback failed`,h(e)),{results:n,triggered:!0,cacheHit:a}}}function x(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score).map(({record:e,score:t})=>({record:e,score:t}))}function S(e,t){let n=t.toLowerCase().split(/\s+/).filter(e=>e.length>=2);return n.length<2?e:e.map(e=>{let t=e.record.content.toLowerCase(),r=n.map(e=>{let n=[],r=t.indexOf(e);for(;r!==-1;)n.push(r),r=t.indexOf(e,r+1);return n});if(r.some(e=>e.length===0))return e;let i=t.length;for(let e of r[0]){let t=e,a=e+n[0].length;for(let i=1;i<r.length;i++){let o=r[i][0],s=Math.abs(o-e);for(let t=1;t<r[i].length;t++){let n=Math.abs(r[i][t]-e);n<s&&(s=n,o=r[i][t])}t=Math.min(t,o),a=Math.max(a,o+n[i].length)}i=Math.min(i,a-t)}let a=1+.25/(1+i/200);return{record:e.record,score:e.score*a}}).sort((e,t)=>t.score-e.score)}function C(e,t,n=8){let r=new Set(t.toLowerCase().split(/\s+/).filter(e=>e.length>=2)),i=new Map,a=e.length;for(let t of e){let e=new Set(t.record.content.split(/[^a-zA-Z0-9_]+/).filter(e=>e.length>=3&&!w.has(e.toLowerCase())));for(let t of e){let e=t.toLowerCase();/[_A-Z]/.test(t)&&i.set(`__id__${e}`,1)}let n=new Set(t.record.content.toLowerCase().split(/[^a-zA-Z0-9_]+/).filter(e=>e.length>=3&&!w.has(e)));for(let e of n)i.set(e,(i.get(e)??0)+1)}let o=[];for(let[e,t]of i){if(e.startsWith(`__id__`)||r.has(e)||t>a*.8)continue;let n=Math.log(a/t),s=i.has(`__id__${e}`)?1:0,c=e.length>8?.5:0;o.push({term:e,score:n+s+c})}return o.sort((e,t)=>t.score-e.score).slice(0,n).map(e=>e.term)}const w=new Set(`the.and.for.are.but.not.you.all.can.had.her.was.one.our.out.has.have.from.this.that.with.they.been.said.each.which.their.will.other.about.many.then.them.these.some.would.make.like.into.could.time.very.when.come.just.know.take.people.also.back.after.only.more.than.over.such.import.export.const.function.return.true.false.null.undefined.string.number.boolean.void.type.interface`.split(`.`));async function T(e,t){try{let n=await e.getStats();if(!n.lastIndexedAt)return;let r=new Date(n.lastIndexedAt).getTime(),i=Date.now(),a=[...new Set(t.map(e=>e.record.sourcePath))].filter(e=>!e.startsWith(`[ER]`)).slice(0,5);if(a.length===0)return;let o=0;for(let e of a)try{(await c(e)).mtimeMs>r&&o++}catch{o++}if(o>0){let e=i-r,t=Math.floor(e/6e4),n=t<1?`<1 min`:`${t} min`;return`> ⚠️ **Index may be stale** — ${o} file(s) modified since last index (${n} ago). Use \`reindex\` to refresh.`}}catch{}}function E(c,m,v,w,E,D,O){let k=e(`search`);c.registerTool(`search`,{title:k.title,description:`Search the knowledge base for code, docs, and prior decisions. Default choice for discovery. Modes: hybrid (default), semantic, keyword. For multi-strategy precision queries use find; for a known file path use lookup.`,outputSchema:t,inputSchema:{query:l.string().max(5e3).describe(`Natural language search query`),limit:l.number().min(1).max(20).default(5).describe(`Maximum results to return`),search_mode:l.enum([`hybrid`,`semantic`,`keyword`]).default(`hybrid`).describe(`Search strategy: hybrid (vector + FTS + RRF fusion, default), semantic (vector only), keyword (FTS only)`),content_type:l.enum(u).optional().describe(`Filter by content type`),source_type:l.enum(f).optional().describe(`Coarse filter: "source" (code only), "documentation" (md, curated), "test", "config". Overrides content_type if both set.`),origin:l.enum(d).optional().describe(`Filter by knowledge origin`),category:l.string().optional().describe(`Filter by category (e.g., decisions, patterns, conventions)`),tags:l.array(l.string()).optional().describe(`Filter by tags (returns results matching ANY of the specified tags)`),min_score:l.number().min(0).max(1).default(.25).describe(`Minimum similarity score`),graph_hops:l.number().min(0).max(3).default(1).describe(`Number of graph hops to augment results with connected entities (0 = disabled, 1 = direct connections, 2-3 = deeper traversal). Default 1 provides module/symbol context automatically.`),max_tokens:l.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),dedup:l.enum([`file`,`chunk`]).default(`chunk`).describe(`Deduplication mode: "chunk" (default, show all matching chunks) or "file" (collapse chunks from same file into single result with merged line ranges)`),workspaces:l.array(l.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all registered workspaces. Only works in user-level install mode.`)},annotations:k.annotations},async({query:e,limit:t,search_mode:c,content_type:l,source_type:u,origin:d,category:f,tags:k,min_score:A,graph_hops:j,max_tokens:M,dedup:N,workspaces:P})=>{try{let F={limit:t,minScore:A,contentType:l,sourceType:u,origin:d,category:f,tags:k},I,L=!1,R=!1,z=``;if(c===`keyword`)I=await v.ftsSearch(e,F),I=I.slice(0,t);else if(c===`semantic`){let n=await m.embedQuery(e);I=await v.search(n,F);let r=await b(E,I[0]?.score??0,I,e,t);I=r.results,L=r.triggered,R=r.cacheHit}else{let n=await m.embedQuery(e),[r,i]=await Promise.all([v.search(n,{...F,limit:t*2}),v.ftsSearch(e,{...F,limit:t*2}).catch(()=>[])]);I=x(r,i).slice(0,t);let a=await b(E,r[0]?.score??0,I,e,t);I=a.results,L=a.triggered,R=a.cacheHit}D&&D.recordSearch(e,L,R),I.length>1&&(I=S(I,e));let B=``;if(P&&P.length>0){let o=a(P,p(process.cwd()));if(o.length>0){let{stores:a,closeAll:s}=await i(o);try{let i;i=c===`keyword`?await n(a,e,{...F,limit:t}):await r(a,await m.embedQuery(e),{...F,limit:t});for(let e of i)I.push({record:{...e.record,sourcePath:`[${e.workspace}] ${e.record.sourcePath}`},score:e.score});I=I.sort((e,t)=>t.score-e.score).slice(0,t),B=` + ${o.length} workspace(s)`}finally{await s()}}}if(N===`file`&&I.length>1){let e=new Map;for(let t of I){let n=t.record.sourcePath,r=e.get(n);r?(t.score>r.best.score&&(r.best=t),r.ranges.push({start:t.record.startLine,end:t.record.endLine})):e.set(n,{best:t,ranges:[{start:t.record.startLine,end:t.record.endLine}]})}I=[...e.values()].sort((e,t)=>t.best.score-e.best.score).map(({best:e,ranges:t})=>({record:{...e.record,content:t.length>1?`${e.record.content}\n\n_Matched ${t.length} sections: ${t.sort((e,t)=>e.start-t.start).map(e=>`L${e.start}-${e.end}`).join(`, `)}_`:e.record.content},score:e.score}))}if(I.length===0){if(O?.available)try{let t=(await O.createMessage({prompt:`The search query "${e}" returned 0 results in a code knowledge base. Suggest ONE alternative search query that might find relevant results. Reply with ONLY the alternative query, nothing else.`,systemPrompt:`You are a search query optimizer for a code knowledge base. Generate a single alternative query.`,maxTokens:100})).text.trim().split(`
|
|
2
|
+
`)[0].slice(0,500);if(t&&t!==e){let n=await m.embedQuery(t),r=await v.search(n,F);r.length>0&&(I=r,z=`> _Original query "${e}" returned 0 results. Auto-reformulated to "${t}"._\n\n`,y.info(`Smart search fallback succeeded`,{originalQuery:e,altQuery:t,resultCount:r.length}))}}catch(e){y.debug(`Smart search fallback failed`,{error:String(e)})}if(I.length===0)return{content:[{type:`text`,text:`No results found for the given query.`}],structuredContent:{results:[],totalResults:0,searchMode:c,query:e}}}let V,H;if(j>0&&!w&&(H="> **Note:** `graph_hops` was set but no graph store is available. Graph augmentation skipped."),j>0&&w)try{let e=await g(w,I.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:j,maxPerHit:5});V=new Map;for(let t of e)if(t.graphContext.nodes.length>0){let e=t.graphContext.nodes.slice(0,5).map(e=>` - **${e.name}** (${e.type})`).join(`
|
|
2
3
|
`),n=t.graphContext.edges.slice(0,5).map(e=>` - ${e.fromId} —[${e.type}]→ ${e.toId}`).join(`
|
|
3
|
-
`),r=[`- **Graph Context** (${
|
|
4
|
-
`))}}catch(e){
|
|
4
|
+
`),r=[`- **Graph Context** (${j} hop${j>1?`s`:``}):`];e&&r.push(` Entities:\n${e}`),n&&r.push(` Relationships:\n${n}`),V.set(t.recordId,r.join(`
|
|
5
|
+
`))}}catch(e){y.warn(`Graph augmentation failed`,h(e)),H=`> **Note:** Graph augmentation failed. Results shown without graph context.`}let U=I.map((e,t)=>{let n=e.record;return`${`### Result ${t+1} (score: ${e.score.toFixed(3)})`}\n${[`- **Source**: ${n.sourcePath}`,n.headingPath?`- **Section**: ${n.headingPath}`:null,`- **Type**: ${n.contentType}`,n.startLine?`- **Lines**: ${n.startLine}-${n.endLine}`:null,n.origin===`indexed`?null:`- **Origin**: ${n.origin}`,n.category?`- **Category**: ${n.category}`:null,n.tags?.length?`- **Tags**: ${n.tags.join(`, `)}`:null,V?.get(n.id)??null].filter(Boolean).join(`
|
|
5
6
|
`)}\n\n${n.content}`}).join(`
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
9
|
-
`),
|
|
10
|
+
`),W=(c===`hybrid`?`hybrid (vector + keyword RRF)`:c===`keyword`?`keyword (FTS)`:`semantic (vector)`)+B,G=C(I,e),K=G.length>0?`\n_Distinctive terms: ${G.map(e=>`\`${e}\``).join(`, `)}_`:``,q=await T(v,I),J=[];if(I.length===0)J.push("`reindex` — no results found, index may be stale"),J.push("`find` — try federated search with glob/regex");else{let e=I[0]?.record.sourcePath;e&&J.push(`\`lookup\` — see all chunks from \`${e}\``),J.push("`symbol` — resolve a specific symbol from the results"),J.push("`compact` — compress a result file for focused reading")}let Y=[H?`${H}\n\n`:``,q?`${q}\n\n`:``,U,`\n\n---\n_Search mode: ${W} | ${I.length} results_${K}`,`\n_Next: ${J.join(` | `)}_`],X=z+Y.join(``);M&&(X=_(X,M));let Z=new Set,Q=[];for(let e of I){if(e.record.origin!==`curated`||e.record.sourcePath.startsWith(`[`))continue;let t=s(e.record.sourcePath);if(!t)continue;let n=o(t,e.record.headingPath??t);n&&!Z.has(n.uri)&&(Z.add(n.uri),Q.push(n))}return{content:[{type:`text`,text:X},...Q],structuredContent:{results:I.map(e=>({sourcePath:e.record.sourcePath,contentType:e.record.contentType,score:e.score,...e.record.headingPath?{headingPath:e.record.headingPath}:{},...e.record.startLine?{startLine:e.record.startLine}:{},...e.record.endLine?{endLine:e.record.endLine}:{},...e.record.origin===`indexed`?{}:{origin:e.record.origin},...e.record.category?{category:e.record.category}:{},...e.record.tags?.length?{tags:e.record.tags}:{}})),totalResults:I.length,searchMode:c,query:e}}}catch(e){return y.error(`Search failed`,h(e)),{content:[{type:`text`,text:`Search failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{E as registerSearchTool};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{StatusOutputSchema as t}from"../output-schemas.js";import{existsSync as n}from"node:fs";import{resolve as r}from"node:path";import{
|
|
2
|
-
`),
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{StatusOutputSchema as t}from"../output-schemas.js";import{existsSync as n}from"node:fs";import{resolve as r}from"node:path";import{KB_PATHS as i,createLogger as a,serializeError as o}from"../../../core/dist/index.js";import{WasmRuntime as s}from"../../../chunker/dist/index.js";const c=a(`tools`);function l(e,t,n,r=4e3){let i,a=new Promise(e=>{i=setTimeout(()=>{c.warn(`Status sub-operation "${n}" timed out after ${r}ms`),e({value:t,timedOut:!0})},r)});return Promise.race([e.then(e=>(clearTimeout(i),{value:e,timedOut:!1}),e=>(clearTimeout(i),c.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}function u(a,u,d,f,p){let m=e(`status`);a.registerTool(`status`,{title:m.title,description:`Get the current status and statistics of the knowledge base index.`,outputSchema:t,annotations:m.annotations},async()=>{let e=[];try{let t=await l(u.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),a=t.value;t.timedOut&&e.push(`⚠ Index stats timed out — values may be incomplete`);let o=await l(u.listSourcePaths(),[],`store.listSourcePaths`),c=o.value;o.timedOut&&e.push(`⚠ File listing timed out`);let m=null,h=0,g=[`## Knowledge Base Status`,``,`- **Total Records**: ${a.totalRecords}`,`- **Total Files**: ${a.totalFiles}`,`- **Last Indexed**: ${a.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(a.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...c.slice(0,50).map(e=>`- ${e}`),c.length>50?`\n... and ${c.length-50} more files`:``];if(d)try{let t=await l(d.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(t.timedOut)e.push(`⚠ Graph stats timed out`),g.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let e=t.value;m={nodes:e.nodeCount,edges:e.edgeCount},g.push(``,`### Knowledge Graph`,`- **Nodes**: ${e.nodeCount}`,`- **Edges**: ${e.edgeCount}`,...Object.entries(e.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await l(d.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||g.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&g.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{g.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let _=n(r(process.cwd(),i.aiKb)),v=p?.onboardComplete??_;if(g.push(``,`### Onboard Status`,v?`- ✅ Complete${p?.onboardTimestamp?` (last: ${p.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase'),f)try{let t=await l(f.list(),[],`curated.list`);if(t.timedOut)e.push(`⚠ Curated knowledge listing timed out`),g.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let e=t.value;h=e.length,g.push(``,`### Curated Knowledge`,e.length>0?`- ${e.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{g.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}if(a.lastIndexedAt){let e=new Date(a.lastIndexedAt),t=(Date.now()-e.getTime())/(1e3*60*60);g.push(``,`### Index Freshness`,t>24?`- ⚠ Last indexed ${Math.floor(t)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${t<1?`less than 1h`:`${Math.floor(t)}h`} ago`)}g.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${s.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`),e.length>0&&g.push(``,`### ⚠ Warnings`,...e.map(e=>`- ${e}`));let y=g.join(`
|
|
2
|
+
`),b={totalRecords:a.totalRecords,totalFiles:a.totalFiles,lastIndexedAt:a.lastIndexedAt??null,onboarded:v,contentTypes:a.contentTypeBreakdown,wasmAvailable:!!s.get(),graphStats:m,curatedCount:h};return{content:[{type:`text`,text:y+"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._"}],structuredContent:b}}catch(e){return c.error(`Status failed`,o(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{u as registerStatusTool};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { CuratedKnowledgeManager } from "../curated-manager.js";
|
|
2
|
+
import { ResourceNotifier } from "../resources/resource-notifier.js";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
|
|
4
5
|
//#region packages/server/src/tools/update.tool.d.ts
|
|
5
|
-
declare function registerUpdateTool(server: McpServer, curated: CuratedKnowledgeManager): void;
|
|
6
|
+
declare function registerUpdateTool(server: McpServer, curated: CuratedKnowledgeManager, resourceNotifier?: ResourceNotifier): void;
|
|
6
7
|
//#endregion
|
|
7
8
|
export { registerUpdateTool };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{createLogger as n,serializeError as r}from"../../../core/dist/index.js";const i=n(`tools`);function a(n,a){let
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{createLogger as n,serializeError as r}from"../../../core/dist/index.js";const i=n(`tools`);function a(n,a,o){let s=e(`update`);n.registerTool(`update`,{title:s.title,description:`Update an existing curated knowledge entry. Increments version and records the reason in the changelog.`,inputSchema:{path:t.string().describe(`Relative path within .ai/curated/ (e.g., "decisions/use-lancedb.md")`),content:t.string().min(10).max(1e5).describe(`New markdown content to replace existing content`),reason:t.string().min(3).max(1e3).describe(`Why this update is being made (recorded in changelog)`)},annotations:s.annotations},async({path:e,content:t,reason:n})=>{try{let r=await a.update(e,t,n);return o&&o.notifyAfterCuratedWrite(e).catch(()=>{}),{content:[{type:`text`,text:`Updated: \`.ai/curated/${r.path}\` → version ${r.version}\n\nReason: ${n}\n\n---\n_Next: Use \`read\` to verify the updated content, or \`search\` to test searchability._`}]}}catch(e){return i.error(`Update failed`,r(e)),{content:[{type:`text`,text:`Update failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{a as registerUpdateTool};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
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
|
|
3
|
-
`)}]}}catch(e){return _.error(`HTTP request failed`,o(e)),{content:[{type:`text`,text:`HTTP request failed
|
|
4
|
-
`)}]}})}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
|
|
5
|
-
`)}],structuredContent:i}}catch(e){return _.error(`Measure failed`,o(e)),{content:[{type:`text`,text:`Measure failed
|
|
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(`
|
|
3
|
+
`)}]}}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
|
+
`)}]}})}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
|
+
`)}],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
|
|
6
6
|
|
|
7
7
|
Data matches the schema.`}]};let r=[`## Validation: FAILED`,``,`**${n.errors.length} error(s):**`,``];for(let e of n.errors){let t=e.expected?` (expected: ${e.expected}, got: ${e.received})`:``;r.push(`- \`${e.path}\`: ${e.message}${t}`)}return{content:[{type:`text`,text:r.join(`
|
|
8
|
-
`)}]}}catch(e){return _.error(`Schema validation failed`,o(e)),{content:[{type:`text`,text:`Schema validation failed
|
|
9
|
-
`)}]}}let s=o,c=s.tags.length>0?`\nTags: ${s.tags.join(`, `)}`:``;return{content:[{type:`text`,text:`## ${s.name} (${s.language})${c}\n\n\`\`\`${s.language}\n${s.code}\n\`\`\``}]}}catch(e){return _.error(`Snippet failed`,o(e)),{content:[{type:`text`,text:`Snippet failed
|
|
10
|
-
`)}],structuredContent:a}})}function D(t){let n=e(`time`);t.registerTool(`time`,{title:n.title,description:`Parse dates, convert timezones, calculate durations, add time. Supports ISO 8601, unix timestamps, and human-readable formats.`,outputSchema:r,inputSchema:{operation:i.enum([`now`,`parse`,`convert`,`diff`,`add`]).describe(`now: current time | parse: parse a date string | convert: timezone conversion | diff: duration between two dates | add: add duration to date`),input:i.string().optional().describe(`Date input (ISO, unix timestamp, or parseable string). For diff: two comma-separated dates`),timezone:i.string().optional().describe(`Target timezone (e.g., "America/New_York", "Asia/Tokyo")`),duration:i.string().optional().describe(`Duration to add (e.g., "2h30m", "1d", "30s") — for add operation`)},annotations:n.annotations},async({operation:e,input:t,timezone:n,duration:r})=>{try{let i=h({operation:e,input:t,timezone:n,duration:r}),a=[`**${i.output}**`,``,`ISO: ${i.iso}`,`Unix: ${i.unix}`];i.details&&a.push(``,"```json",JSON.stringify(i.details
|
|
11
|
-
`)}],structuredContent:o}}catch(e){return _.error(`Time failed`,o(e)),{content:[{type:`text`,text:`Time failed
|
|
8
|
+
`)}]}}catch(e){return _.error(`Schema validation failed`,o(e)),{content:[{type:`text`,text:`Schema validation failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function T(t){let n=e(`snippet`);t.registerTool(`snippet`,{title:n.title,description:`Save, retrieve, search, and manage persistent code snippets/templates.`,inputSchema:{action:i.enum([`save`,`get`,`list`,`search`,`delete`]).describe(`Operation to perform`),name:i.string().optional().describe(`Snippet name (required for save/get/delete)`),language:i.string().optional().describe(`Language tag (for save)`),code:i.string().max(1e5).optional().describe(`Code content (for save)`),tags:i.array(i.string()).optional().describe(`Tags for categorization (for save)`),query:i.string().optional().describe(`Search query (for search)`)},annotations:n.annotations},async({action:e,name:t,language:n,code:r,tags:i,query:a})=>{try{let o=m({action:e,name:t,language:n,code:r,tags:i,query:a});if(`deleted`in o)return{content:[{type:`text`,text:o.deleted?`Snippet "${t}" deleted.`:`Snippet "${t}" not found.`}]};if(`snippets`in o){if(o.snippets.length===0)return{content:[{type:`text`,text:`No snippets found.`}]};let e=[`## Snippets`,``];for(let t of o.snippets){let n=t.tags.length>0?` [${t.tags.join(`, `)}]`:``;e.push(`- **${t.name}** (${t.language})${n}`)}return{content:[{type:`text`,text:e.join(`
|
|
9
|
+
`)}]}}let s=o,c=s.tags.length>0?`\nTags: ${s.tags.join(`, `)}`:``;return{content:[{type:`text`,text:`## ${s.name} (${s.language})${c}\n\n\`\`\`${s.language}\n${s.code}\n\`\`\``}]}}catch(e){return _.error(`Snippet failed`,o(e)),{content:[{type:`text`,text:`Snippet failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function E(n){let r=e(`env`);n.registerTool(`env`,{title:r.title,description:`Get system and runtime environment info. Sensitive env vars are redacted by default.`,outputSchema:t,inputSchema:{include_env:i.boolean().default(!1).describe(`Include environment variables`),filter_env:i.string().optional().describe(`Filter env vars by name substring`),show_sensitive:i.boolean().default(!1).describe(`Show sensitive values (keys, tokens, etc.) — redacted by default`)},annotations:r.annotations},async({include_env:e,filter_env:t,show_sensitive:n})=>{let r=l({includeEnv:e,filterEnv:t,showSensitive:n}),i=[`## Environment`,``,`**Platform:** ${r.system.platform} ${r.system.arch}`,`**OS:** ${r.system.type} ${r.system.release}`,`**Host:** ${r.system.hostname}`,`**CPUs:** ${r.system.cpus}`,`**Memory:** ${r.system.memoryFreeGb}GB free / ${r.system.memoryTotalGb}GB total`,``,`**Node:** ${r.runtime.node}`,`**V8:** ${r.runtime.v8}`,`**CWD:** ${r.cwd}`];if(r.env){i.push(``,`### Environment Variables`,``);for(let[e,t]of Object.entries(r.env))i.push(`- \`${e}\`: ${t}`)}let a={platform:r.system.platform,arch:r.system.arch,nodeVersion:r.runtime.node,cwd:r.cwd,cpus:r.system.cpus,memoryFreeGb:r.system.memoryFreeGb,memoryTotalGb:r.system.memoryTotalGb};return{content:[{type:`text`,text:i.join(`
|
|
10
|
+
`)}],structuredContent:a}})}function D(t){let n=e(`time`);t.registerTool(`time`,{title:n.title,description:`Parse dates, convert timezones, calculate durations, add time. Supports ISO 8601, unix timestamps, and human-readable formats.`,outputSchema:r,inputSchema:{operation:i.enum([`now`,`parse`,`convert`,`diff`,`add`]).describe(`now: current time | parse: parse a date string | convert: timezone conversion | diff: duration between two dates | add: add duration to date`),input:i.string().optional().describe(`Date input (ISO, unix timestamp, or parseable string). For diff: two comma-separated dates`),timezone:i.string().optional().describe(`Target timezone (e.g., "America/New_York", "Asia/Tokyo")`),duration:i.string().optional().describe(`Duration to add (e.g., "2h30m", "1d", "30s") — for add operation`)},annotations:n.annotations},async({operation:e,input:t,timezone:n,duration:r})=>{try{let i=h({operation:e,input:t,timezone:n,duration:r}),a=[`**${i.output}**`,``,`ISO: ${i.iso}`,`Unix: ${i.unix}`];i.details&&a.push(``,"```json",JSON.stringify(i.details),"```");let o={iso:i.iso,unix:i.unix,timezone:n??Intl.DateTimeFormat().resolvedOptions().timeZone,formatted:i.output};return{content:[{type:`text`,text:a.join(`
|
|
11
|
+
`)}],structuredContent:o}}catch(e){return _.error(`Time failed`,o(e)),{content:[{type:`text`,text:`Time failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{C as registerChangelogTool,x as registerEncodeTool,E as registerEnvTool,y as registerHttpTool,S as registerMeasureTool,b as registerRegexTestTool,w as registerSchemaValidateTool,T as registerSnippetTool,D as registerTimeTool,v as registerWebSearchTool};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EMBEDDING_DEFAULTS as e,SEARCH_DEFAULTS as t,STORE_DEFAULTS as n,createLogger as r,serializeError as i,sourceTypeContentTypes as a}from"../../core/dist/index.js";import{Index as o,connect as s}from"@lancedb/lancedb";function c(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}const l=/^[\w.\-/ ]+$/,u=r(`store`);function d(e,t){if(!l.test(e))throw Error(`Invalid ${t} filter value: contains disallowed characters`);return e.replace(/'/g,`''`)}var f=class{db=null;table=null;dbPath;tableName;_writeQueue=Promise.resolve();enqueueWrite(e){let t=this._writeQueue.then(()=>e());return this._writeQueue=t.then(()=>void 0,()=>void 0),t}constructor(e){this.dbPath=e?.path??n.path,this.tableName=e?.tableName??n.tableName}async initialize(){this.db=await s(this.dbPath),(await this.db.tableNames()).includes(this.tableName)&&(this.table=await this.db.openTable(this.tableName),await this.createFtsIndex())}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async _upsertImpl(e,t){let n=e.map((e,n)=>({id:e.id,vector:Array.from(t[n]),content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath??``,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,indexedAt:e.indexedAt,origin:e.origin,tags:JSON.stringify(e.tags),category:e.category??``,version:e.version}));if(this.table){let t=[...new Set(e.map(e=>e.sourcePath))];for(let e of t)try{await this.table.delete(`sourcePath = '${d(e,`sourcePath`)}'`)}catch{}await this.table.add(n)}else try{this.table=await this.db?.createTable(this.tableName,n)??null}catch(e){if(String(e).includes(`already exists`)&&this.db)this.table=await this.db.openTable(this.tableName),await this.table.add(n);else throw e}}async search(e,n){if(!this.table)return[];let r=n?.limit??t.maxResults,i=n?.minScore??t.minScore,a=this.table.search(e).limit(r*2),o=this.buildFilterString(n);return o&&(a=a.where(o)),(await a.toArray()).map(e=>({record:this.fromLanceRecord(e),score:1-(e._distance??1)})).filter(e=>e.score>=i).slice(0,r)}async createFtsIndex(){return this.enqueueWrite(()=>this._createFtsIndexImpl())}async _createFtsIndexImpl(){if(this.table)try{await this.table.createIndex(`content`,{config:o.fts(),replace:!0}),u.info(`FTS index created/updated`,{column:`content`})}catch(e){u.warn(`FTS index creation failed`,i(e))}}async ftsSearch(e,n){if(!this.table)return[];let r=n?.limit??t.maxResults;try{let t=this.table.search(e).limit(r*2),i=this.buildFilterString(n);return i&&(t=t.where(i)),(await t.toArray()).map(e=>({record:this.fromLanceRecord(e),score:e._score??e._relevance_score??0}))}catch(e){return u.warn(`FTS search failed`,i(e)),[]}}async getById(e){if(!this.table)return null;let t=await this.table.query().where(`id = '${d(e,`id`)}'`).limit(1).toArray();return t.length===0?null:this.fromLanceRecord(t[0])}async deleteBySourcePath(e){return this.enqueueWrite(()=>this._deleteBySourcePathImpl(e))}async _deleteBySourcePathImpl(e){if(!this.table)return 0;let t=await this.getBySourcePath(e);return t.length===0?0:(await this.table.delete(`sourcePath = '${d(e,`sourcePath`)}'`),t.length)}async deleteById(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e))}async _deleteByIdImpl(e){return!this.table||!await this.getById(e)?!1:(await this.table.delete(`id = '${d(e,`id`)}'`),!0)}async getBySourcePath(e){return this.table?(await this.table.query().where(`sourcePath = '${d(e,`sourcePath`)}'`).limit(1e3).toArray()).map(e=>this.fromLanceRecord(e)):[]}async getStats(){if(!this.table)return{totalRecords:0,totalFiles:0,contentTypeBreakdown:{},lastIndexedAt:null,storeBackend:`lancedb`,embeddingModel:e.model};let t=await this.table.countRows(),n=await this.table.query().select([`sourcePath`,`contentType`,`indexedAt`]).limit(1e5).toArray(),r={},i=new Set,a=null;for(let e of n){let t=e;r[t.contentType]=(r[t.contentType]??0)+1,i.add(t.sourcePath),(!a||t.indexedAt>a)&&(a=t.indexedAt)}return{totalRecords:t,totalFiles:i.size,contentTypeBreakdown:r,lastIndexedAt:a,storeBackend:`lancedb`,embeddingModel:e.model}}async listSourcePaths(){if(!this.table)return[];let e=await this.table.query().select([`sourcePath`]).limit(1e5).toArray();return[...new Set(e.map(e=>e.sourcePath))]}async dropTable(){return this.enqueueWrite(()=>this._dropTableImpl())}async _dropTableImpl(){if(this.db&&(await this.db.tableNames()).includes(this.tableName))for(let e=1;e<=3;e++)try{await this.db.dropTable(this.tableName);break}catch(t){if(e===3)throw t;let n=e*500;u.warn(`dropTable attempt failed, retrying`,{attempt:e,delayMs:n}),await new Promise(e=>setTimeout(e,n))}this.table=null}async close(){try{this.db&&typeof this.db.close==`function`&&await this.db.close()}catch{}this.table=null,this.db=null}buildFilterString(e){let t=[];if(e?.contentType&&t.push(`contentType = '${d(e.contentType,`contentType`)}'`),e?.sourceType){let n=a(e.sourceType);if(n.length>0){let e=n.map(e=>`'${d(e,`sourceType`)}'`).join(`, `);t.push(`contentType IN (${e})`)}}if(e?.origin&&t.push(`origin = '${d(e.origin,`origin`)}'`),e?.category&&t.push(`category = '${d(e.category,`category`)}'`),e?.tags&&e.tags.length>0){let n=e.tags.map(e=>`tags LIKE '%${d(e,`tag`)}%'`);t.push(`(${n.join(` OR `)})`)}return t.length>0?t.join(` AND `):null}fromLanceRecord(e){return{id:e.id,content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath||void 0,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,indexedAt:e.indexedAt,origin:e.origin,tags:c(e.tags),category:e.category||void 0,version:e.version}}};export{f as LanceStore};
|
|
1
|
+
import{EMBEDDING_DEFAULTS as e,SEARCH_DEFAULTS as t,STORE_DEFAULTS as n,createLogger as r,serializeError as i,sourceTypeContentTypes as a}from"../../core/dist/index.js";import{Index as o,connect as s}from"@lancedb/lancedb";function c(e){if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}const l=/^[\w.\-/ ]+$/,u=r(`store`);function d(e,t){if(!l.test(e))throw Error(`Invalid ${t} filter value: contains disallowed characters`);return e.replace(/'/g,`''`)}var f=class{db=null;table=null;dbPath;tableName;_ftsReady=!1;_writeQueue=Promise.resolve();enqueueWrite(e){let t=this._writeQueue.then(()=>e());return this._writeQueue=t.then(()=>void 0,()=>void 0),t}constructor(e){this.dbPath=e?.path??n.path,this.tableName=e?.tableName??n.tableName}async initialize(){this.db=await s(this.dbPath),(await this.db.tableNames()).includes(this.tableName)&&(this.table=await this.db.openTable(this.tableName),await this.createFtsIndex())}async upsert(e,t){if(e.length!==0){if(e.length!==t.length)throw Error(`Record count (${e.length}) does not match vector count (${t.length})`);return this.enqueueWrite(()=>this._upsertImpl(e,t))}}async _upsertImpl(e,t){let n=e.map((e,n)=>({id:e.id,vector:Array.from(t[n]),content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath??``,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,indexedAt:e.indexedAt,origin:e.origin,tags:JSON.stringify(e.tags),category:e.category??``,version:e.version}));if(this.table){let t=[...new Set(e.map(e=>e.sourcePath))];for(let e of t)try{await this.table.delete(`sourcePath = '${d(e,`sourcePath`)}'`)}catch{}await this.table.add(n)}else try{this.table=await this.db?.createTable(this.tableName,n)??null}catch(e){if(String(e).includes(`already exists`)&&this.db)this.table=await this.db.openTable(this.tableName),await this.table.add(n);else throw e}}async search(e,n){if(!this.table)return[];let r=n?.limit??t.maxResults,i=n?.minScore??t.minScore,a=this.table.search(e).limit(r*2),o=this.buildFilterString(n);return o&&(a=a.where(o)),(await a.toArray()).map(e=>({record:this.fromLanceRecord(e),score:1-(e._distance??1)})).filter(e=>e.score>=i).slice(0,r)}async createFtsIndex(){return this.enqueueWrite(()=>this._createFtsIndexImpl())}async _createFtsIndexImpl(){if(this.table)try{await this.table.createIndex(`content`,{config:o.fts(),replace:!0}),this._ftsReady=!0,u.info(`FTS index created/updated`,{column:`content`})}catch(e){u.warn(`FTS index creation failed`,i(e))}}async ftsSearch(e,n){if(!this.table||!this._ftsReady)return[];let r=n?.limit??t.maxResults;try{let t=this.table.search(e).limit(r*2),i=this.buildFilterString(n);return i&&(t=t.where(i)),(await t.toArray()).map(e=>({record:this.fromLanceRecord(e),score:e._score??e._relevance_score??0}))}catch(e){return(e instanceof Error?e.message:String(e)).includes(`INVERTED index`)?(u.debug(`FTS search skipped — index not yet available`),this._ftsReady=!1):u.warn(`FTS search failed`,i(e)),[]}}async getById(e){if(!this.table)return null;let t=await this.table.query().where(`id = '${d(e,`id`)}'`).limit(1).toArray();return t.length===0?null:this.fromLanceRecord(t[0])}async deleteBySourcePath(e){return this.enqueueWrite(()=>this._deleteBySourcePathImpl(e))}async _deleteBySourcePathImpl(e){if(!this.table)return 0;let t=await this.getBySourcePath(e);return t.length===0?0:(await this.table.delete(`sourcePath = '${d(e,`sourcePath`)}'`),t.length)}async deleteById(e){return this.enqueueWrite(()=>this._deleteByIdImpl(e))}async _deleteByIdImpl(e){return!this.table||!await this.getById(e)?!1:(await this.table.delete(`id = '${d(e,`id`)}'`),!0)}async getBySourcePath(e){return this.table?(await this.table.query().where(`sourcePath = '${d(e,`sourcePath`)}'`).limit(1e3).toArray()).map(e=>this.fromLanceRecord(e)):[]}async getStats(){if(!this.table)return{totalRecords:0,totalFiles:0,contentTypeBreakdown:{},lastIndexedAt:null,storeBackend:`lancedb`,embeddingModel:e.model};let t=await this.table.countRows(),n=await this.table.query().select([`sourcePath`,`contentType`,`indexedAt`]).limit(1e5).toArray(),r={},i=new Set,a=null;for(let e of n){let t=e;r[t.contentType]=(r[t.contentType]??0)+1,i.add(t.sourcePath),(!a||t.indexedAt>a)&&(a=t.indexedAt)}return{totalRecords:t,totalFiles:i.size,contentTypeBreakdown:r,lastIndexedAt:a,storeBackend:`lancedb`,embeddingModel:e.model}}async listSourcePaths(){if(!this.table)return[];let e=await this.table.query().select([`sourcePath`]).limit(1e5).toArray();return[...new Set(e.map(e=>e.sourcePath))]}async dropTable(){return this.enqueueWrite(()=>this._dropTableImpl())}async _dropTableImpl(){if(this.db&&(await this.db.tableNames()).includes(this.tableName))for(let e=1;e<=3;e++)try{await this.db.dropTable(this.tableName);break}catch(t){if(e===3)throw t;let n=e*500;u.warn(`dropTable attempt failed, retrying`,{attempt:e,delayMs:n}),await new Promise(e=>setTimeout(e,n))}this.table=null}async close(){try{this.db&&typeof this.db.close==`function`&&await this.db.close()}catch{}this.table=null,this.db=null}buildFilterString(e){let t=[];if(e?.contentType&&t.push(`contentType = '${d(e.contentType,`contentType`)}'`),e?.sourceType){let n=a(e.sourceType);if(n.length>0){let e=n.map(e=>`'${d(e,`sourceType`)}'`).join(`, `);t.push(`contentType IN (${e})`)}}if(e?.origin&&t.push(`origin = '${d(e.origin,`origin`)}'`),e?.category&&t.push(`category = '${d(e.category,`category`)}'`),e?.tags&&e.tags.length>0){let n=e.tags.map(e=>`tags LIKE '%${d(e,`tag`)}%'`);t.push(`(${n.join(` OR `)})`)}return t.length>0?t.join(` AND `):null}fromLanceRecord(e){return{id:e.id,content:e.content,sourcePath:e.sourcePath,contentType:e.contentType,headingPath:e.headingPath||void 0,chunkIndex:e.chunkIndex,totalChunks:e.totalChunks,startLine:e.startLine,endLine:e.endLine,fileHash:e.fileHash,indexedAt:e.indexedAt,origin:e.origin,tags:c(e.tags),category:e.category||void 0,version:e.version}}};export{f as LanceStore};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{check as e,summarizeCheckResult as t}from"./check.js";import{findDeadSymbols as n}from"./dead-symbols.js";import{health as r}from"./health.js";import{resolvePath as i}from"./path-resolver.js";import{errorResponse as a,okResponse as o}from"./response-envelope.js";import{DependencyAnalyzer as s,EntryPointAnalyzer as c,PatternAnalyzer as l,StructureAnalyzer as u}from"../../analyzers/dist/index.js";const d=[`structure`,`dependencies`,`patterns`,`health`,`dead_symbols`,`check`,`entry_points`];async function f(f,m,h={}){let g=Date.now(),_=i(h.path),v=h.checks??d,y=h.detail??`summary`,b=[],x={score:100,recommendations:b};try{let i=[];v.includes(`structure`)&&i.push((async()=>{let e=await new u().analyze(_,{format:`json`}),t=e.data;x.structure={files:t.stats?.totalFiles??e.meta.fileCount,packages:Array.isArray(t.packages)?t.packages.length:0,languages:t.stats?.languages??{}}})()),v.includes(`dependencies`)&&i.push((async()=>{let e=(await new s().analyze(_)).data,t=e.imports??[];x.dependencies={external:e.external?.length??t.filter(e=>e.isExternal).length,internal:e.internal?.length??t.filter(e=>!e.isExternal).length}})()),v.includes(`patterns`)&&i.push((async()=>{x.patterns=((await new l().analyze(_)).data.patterns??[]).map(e=>({name:e.pattern,confidence:e.confidence,count:e.locations.length}))})()),v.includes(`entry_points`)&&i.push((async()=>{let e=(await new c().analyze(_)).data,t=e.entryPoints??[],n={};for(let e of t)n[e.type]=(n[e.type]??0)+1;x.entryPoints={total:e.total??t.length,types:n}})()),v.includes(`health`)&&i.push((async()=>{let e=r(_);x.health={score:e.score,checks:e.checks.length,passed:e.checks.filter(e=>e.status===`pass`).length,warned:e.checks.filter(e=>e.status===`warn`).length,failed:e.checks.filter(e=>e.status===`fail`).length},e.score<70&&b.push({priority:`medium`,area:`health`,message:`Health score ${e.score}/100 — ${x.health.failed} failed checks`})})()),v.includes(`dead_symbols`)&&i.push((async()=>{let e=await n(m,f,{rootPath:_});x.deadSymbols={source:e.totalDeadSource,docs:e.totalDeadDocs},e.totalDeadSource>0&&b.push({priority:e.totalDeadSource>10?`high`:`medium`,area:`dead-code`,message:`${e.totalDeadSource} unused exports in source files`})})()),v.includes(`check`)&&i.push((async()=>{let n=t(await e({cwd:_}));x.typecheck={passed:n.tsc.passed,errorCount:n.tsc.errorCount,topErrors:n.tsc.topErrors},x.lint={passed:n.biome.passed,errorCount:n.biome.errorCount,topErrors:n.biome.topErrors},n.tsc.passed||b.push({priority:`high`,area:`type-safety`,message:`Fix ${n.tsc.errorCount} tsc error(s)`}),n.biome.passed||b.push({priority:`medium`,area:`lint`,message:`Fix ${n.biome.errorCount} lint error(s)`})})()),await Promise.all(i);let a=0;x.typecheck&&!x.typecheck.passed&&(a+=15),x.lint&&!x.lint.passed&&(a+=5),x.health&&x.health.score<80&&(a+=10),x.deadSymbols&&x.deadSymbols.source>10&&(a+=5),x.entryPoints&&x.entryPoints.total===0&&(a+=5),x.score=Math.max(0,100-a);let d={high:0,medium:1,low:2};b.sort((e,t)=>d[e.priority]-d[t.priority]);let h=p(x,y),S=[];return x.typecheck&&!x.typecheck.passed&&S.push({tool:`check`,reason:`Get full error details`,suggested_args:{detail:`errors`}}),x.deadSymbols&&x.deadSymbols.source>0&&S.push({tool:`dead_symbols`,reason:`See which exports are unused`,suggested_args:{root_path:_}}),o(`audit`,h,x,{durationMs:Date.now()-g,detail:y},S)}catch{return a(`audit`,{code:`ANALYSIS_FAILED`,category:`runtime`,retryable:!1,message:`Audit failed
|
|
1
|
+
import{check as e,summarizeCheckResult as t}from"./check.js";import{findDeadSymbols as n}from"./dead-symbols.js";import{health as r}from"./health.js";import{resolvePath as i}from"./path-resolver.js";import{errorResponse as a,okResponse as o}from"./response-envelope.js";import{DependencyAnalyzer as s,EntryPointAnalyzer as c,PatternAnalyzer as l,StructureAnalyzer as u}from"../../analyzers/dist/index.js";const d=[`structure`,`dependencies`,`patterns`,`health`,`dead_symbols`,`check`,`entry_points`];async function f(f,m,h={}){let g=Date.now(),_=i(h.path),v=h.checks??d,y=h.detail??`summary`,b=[],x={score:100,recommendations:b};try{let i=[];v.includes(`structure`)&&i.push((async()=>{let e=await new u().analyze(_,{format:`json`}),t=e.data;x.structure={files:t.stats?.totalFiles??e.meta.fileCount,packages:Array.isArray(t.packages)?t.packages.length:0,languages:t.stats?.languages??{}}})()),v.includes(`dependencies`)&&i.push((async()=>{let e=(await new s().analyze(_)).data,t=e.imports??[];x.dependencies={external:e.external?.length??t.filter(e=>e.isExternal).length,internal:e.internal?.length??t.filter(e=>!e.isExternal).length}})()),v.includes(`patterns`)&&i.push((async()=>{x.patterns=((await new l().analyze(_)).data.patterns??[]).map(e=>({name:e.pattern,confidence:e.confidence,count:e.locations.length}))})()),v.includes(`entry_points`)&&i.push((async()=>{let e=(await new c().analyze(_)).data,t=e.entryPoints??[],n={};for(let e of t)n[e.type]=(n[e.type]??0)+1;x.entryPoints={total:e.total??t.length,types:n}})()),v.includes(`health`)&&i.push((async()=>{let e=r(_);x.health={score:e.score,checks:e.checks.length,passed:e.checks.filter(e=>e.status===`pass`).length,warned:e.checks.filter(e=>e.status===`warn`).length,failed:e.checks.filter(e=>e.status===`fail`).length},e.score<70&&b.push({priority:`medium`,area:`health`,message:`Health score ${e.score}/100 — ${x.health.failed} failed checks`})})()),v.includes(`dead_symbols`)&&i.push((async()=>{let e=await n(m,f,{rootPath:_});x.deadSymbols={source:e.totalDeadSource,docs:e.totalDeadDocs},e.totalDeadSource>0&&b.push({priority:e.totalDeadSource>10?`high`:`medium`,area:`dead-code`,message:`${e.totalDeadSource} unused exports in source files`})})()),v.includes(`check`)&&i.push((async()=>{let n=t(await e({cwd:_}));x.typecheck={passed:n.tsc.passed,errorCount:n.tsc.errorCount,topErrors:n.tsc.topErrors},x.lint={passed:n.biome.passed,errorCount:n.biome.errorCount,topErrors:n.biome.topErrors},n.tsc.passed||b.push({priority:`high`,area:`type-safety`,message:`Fix ${n.tsc.errorCount} tsc error(s)`}),n.biome.passed||b.push({priority:`medium`,area:`lint`,message:`Fix ${n.biome.errorCount} lint error(s)`})})()),await Promise.all(i);let a=0;x.typecheck&&!x.typecheck.passed&&(a+=15),x.lint&&!x.lint.passed&&(a+=5),x.health&&x.health.score<80&&(a+=10),x.deadSymbols&&x.deadSymbols.source>10&&(a+=5),x.entryPoints&&x.entryPoints.total===0&&(a+=5),x.score=Math.max(0,100-a);let d={high:0,medium:1,low:2};b.sort((e,t)=>d[e.priority]-d[t.priority]);let h=p(x,y),S=[];return x.typecheck&&!x.typecheck.passed&&S.push({tool:`check`,reason:`Get full error details`,suggested_args:{detail:`errors`}}),x.deadSymbols&&x.deadSymbols.source>0&&S.push({tool:`dead_symbols`,reason:`See which exports are unused`,suggested_args:{root_path:_}}),o(`audit`,h,x,{durationMs:Date.now()-g,detail:y},S)}catch(e){return a(`audit`,{code:`ANALYSIS_FAILED`,category:`runtime`,retryable:!1,message:`Audit failed: ${e instanceof Error?e.message:String(e)}`},Date.now()-g)}}function p(e,t){let n=[];if(n.push(`## Audit Report — Score: ${e.score}/100\n`),e.structure&&n.push(`**Structure:** ${e.structure.files} files, ${e.structure.packages} packages, ${Object.keys(e.structure.languages).length} languages`),e.entryPoints){let t=Object.entries(e.entryPoints.types).map(([e,t])=>`${t} ${e}`).join(`, `);n.push(`**Entry Points:** ${e.entryPoints.total} (${t||`none`})`)}if(e.dependencies&&n.push(`**Dependencies:** ${e.dependencies.external} external, ${e.dependencies.internal} internal`),e.health&&n.push(`**Health:** ${e.health.score}/100 (${e.health.passed}✓ ${e.health.warned}⚠ ${e.health.failed}✗)`),e.deadSymbols&&n.push(`**Dead Symbols:** ${e.deadSymbols.source} in source (actionable), ${e.deadSymbols.docs} in docs`),e.typecheck){let t=e.typecheck.passed?`✓ passed`:`✗ ${e.typecheck.errorCount} errors`;n.push(`**Typecheck:** ${t}`)}if(e.lint){let t=e.lint.passed?`✓ passed`:`✗ ${e.lint.errorCount} errors`;n.push(`**Lint:** ${t}`)}if(e.recommendations.length>0){n.push(`
|
|
2
2
|
### Recommendations
|
|
3
3
|
`);for(let t of e.recommendations){let e=t.priority===`high`?`🔴`:t.priority===`medium`?`🟡`:`🟢`;n.push(`${e} **${t.area}:** ${t.message}`)}}if(t===`full`&&e.patterns&&e.patterns.length>0){n.push(`
|
|
4
4
|
### Patterns Detected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function e(e,t,n={}){let r=Math.max(1,n.concurrency??4),i=[],a=[...e];async function o(e){let n=Date.now();try{let r=await t(e);return{id:e.id,status:`success`,result:r,durationMs:Date.now()-n}}catch(t){return{id:e.id,status:`error`,error:t instanceof Error?t.message:String(t),durationMs:Date.now()-n}}}for(;a.length>0;){let e=a.splice(0,r),t=await Promise.allSettled(e.map(e=>o(e)));for(let
|
|
1
|
+
async function e(e,t,n={}){let r=Math.max(1,n.concurrency??4),i=[],a=[...e];async function o(e){let n=Date.now();try{let r=await t(e);return{id:e.id,status:`success`,result:r,durationMs:Date.now()-n}}catch(t){return{id:e.id,status:`error`,error:t instanceof Error?t.message:String(t),durationMs:Date.now()-n}}}for(;a.length>0;){let e=a.splice(0,r),t=await Promise.allSettled(e.map(e=>o(e)));for(let n=0;n<t.length;n++){let r=t[n];if(r.status===`fulfilled`){i.push(r.value);continue}i.push({id:e[n]?.id??`unknown`,status:`error`,error:r.reason instanceof Error?r.reason.message:`Promise rejected`,durationMs:0})}}return i}export{e as batch};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{parseBiome as e,parseTsc as t}from"./parse-output.js";import{exec as n}from"node:child_process";import{readFile as r}from"node:fs/promises";import{join as i}from"node:path";import{promisify as a}from"node:util";const o=a(n);let s=0;function c(e){let t=e;return[t.stdout?.toString()??``,t.stderr?.toString()??``].filter(Boolean).join(`
|
|
2
|
-
`).trim()||t.message||`Command failed`}async function l(e={}){if(s>=2)throw Error(`Too many concurrent check runs (max 2). Try again later.`);s++;try{return await u(e)}finally{s--}}async function u(n){let a=n.cwd??process.cwd(),s={errors:[],passed:!0,raw:``},l={errors:[],passed:!0,raw:``};if(!n.skipTypes)try{let e=i(a,`package.json`),t=!1;try{t=!!JSON.parse(await r(e,`utf-8`)).scripts?.typecheck}catch{}if(t&&!n.files?.length)await o(`npx turbo run typecheck`,{cwd:a,timeout:12e4});else{let e=[`--noEmit`];n.files?.length&&e.push(...n.files),await o(`npx tsc ${e.join(` `)}`,{cwd:a,timeout:12e4})}}catch(e){s.raw=c(e),s.errors=t(s.raw),s.passed=s.errors.length===0}if(!n.skipLint)try{let e=[`check`];n.files?.length&&e.push(...n.files),await o(`npx biome ${e.join(` `)}`,{cwd:a,timeout:12e4})}catch(t){l.raw=c(t),l.errors=e(l.raw),l.passed=l.errors.length===0}let u=n.detail??`
|
|
2
|
+
`).trim()||t.message||`Command failed`}async function l(e={}){if(s>=2)throw Error(`Too many concurrent check runs (max 2). Try again later.`);s++;try{return await u(e)}finally{s--}}async function u(n){let a=n.cwd??process.cwd(),s={errors:[],passed:!0,raw:``},l={errors:[],passed:!0,raw:``};if(!n.skipTypes)try{let e=i(a,`package.json`),t=!1;try{t=!!JSON.parse(await r(e,`utf-8`)).scripts?.typecheck}catch{}if(t&&!n.files?.length)await o(`npx turbo run typecheck`,{cwd:a,timeout:12e4});else{let e=[`--noEmit`];n.files?.length&&e.push(...n.files),await o(`npx tsc ${e.join(` `)}`,{cwd:a,timeout:12e4})}}catch(e){s.raw=c(e),s.errors=t(s.raw),s.passed=s.errors.length===0}if(!n.skipLint)try{let e=[`check`];n.files?.length&&e.push(...n.files),await o(`npx biome ${e.join(` `)}`,{cwd:a,timeout:12e4})}catch(t){l.raw=c(t),l.errors=e(l.raw),l.passed=l.errors.length===0}let u=n.detail??`errors`,d={tsc:s,biome:l,passed:s.passed&&l.passed};return u===`full`?d:{tsc:{errors:s.errors,passed:s.passed},biome:{errors:l.errors,passed:l.passed},passed:d.passed}}function d(e){let t=e.tsc.errors.filter(e=>e.severity===`error`),n=e.tsc.errors.filter(e=>e.severity===`warning`),r=e.biome.errors.filter(e=>e.severity===`error`),i=e.biome.errors.filter(e=>e.severity===`warning`);return{passed:e.passed,tsc:{passed:e.tsc.passed,errorCount:t.length,warningCount:n.length,topErrors:t.slice(0,3).map(e=>`${e.file}:${e.line} — ${e.message}`)},biome:{passed:e.biome.passed,errorCount:r.length,warningCount:i.length,topErrors:r.slice(0,3).map(e=>`${e.file}:${e.line} — ${e.message}`)}}}export{l as check,d as summarizeCheckResult};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolve as e}from"node:path";import{existsSync as t,mkdirSync as n,readFileSync as r,readdirSync as i,writeFileSync as a}from"node:fs";import{KB_PATHS as o}from"../../core/dist/index.js";const s=`${o.state}/checkpoints`;function c(r){let i=e(r??process.cwd(),s);return t(i)||n(i,{recursive:!0}),i}function l(t,n,r){let i=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``)||`checkpoint`,o={id:`${Date.now()}-${i}`,label:t,createdAt:new Date().toISOString(),data:n,files:r?.files,notes:r?.notes};return a(e(c(r?.cwd),`${o.id}.json`),`${JSON.stringify(o,null,2)}\n`,`utf-8`),o}function u(n,i){let a=
|
|
1
|
+
import{resolve as e}from"node:path";import{existsSync as t,mkdirSync as n,readFileSync as r,readdirSync as i,writeFileSync as a}from"node:fs";import{KB_PATHS as o}from"../../core/dist/index.js";const s=`${o.state}/checkpoints`;function c(r){let i=e(r??process.cwd(),s);return t(i)||n(i,{recursive:!0}),i}function l(t,n,r){let i=t.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``)||`checkpoint`,o={id:`${Date.now()}-${i}`,label:t,createdAt:new Date().toISOString(),data:n,files:r?.files,notes:r?.notes};return a(e(c(r?.cwd),`${o.id}.json`),`${JSON.stringify(o,null,2)}\n`,`utf-8`),o}function u(n,i){let a=c(i),o=e(a,`${n}.json`);if(o.startsWith(e(a))&&t(o))try{return JSON.parse(r(o,`utf-8`))}catch{return}}function d(t){let n=c(t);return i(n).filter(e=>e.endsWith(`.json`)).flatMap(t=>{try{return[JSON.parse(r(e(n,t),`utf-8`))]}catch{return[]}}).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}function f(e){return d(e)[0]}export{f as checkpointLatest,d as checkpointList,u as checkpointLoad,l as checkpointSave};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{cosineSimilarity as e,segment as t}from"./text-utils.js";import{readFile as n}from"node:fs/promises";async function
|
|
1
|
+
import{cosineSimilarity as e,segment as t}from"./text-utils.js";import{readFile as n,stat as r}from"node:fs/promises";async function i(i,a){let{query:o,maxChars:s=3e3,minScore:c=.3,segmentation:l=`paragraph`}=a,u;if(a.text)u=a.text;else if(a.path){let e;try{e=await r(a.path)}catch(e){let t=e.code;throw t===`ENOENT`?Error(`File not found: ${a.path}. Check the path and try again.`):t===`EACCES`||t===`EPERM`?Error(`Permission denied reading ${a.path}. The file exists but is not accessible.`):e}if(e.size>1e7)throw Error(`File too large (${(e.size/1e6).toFixed(1)}MB). compact supports files up to 10MB. Consider splitting or using search instead.`);u=a.cache?(await a.cache.get(a.path)).content:await n(a.path,`utf-8`)}else throw Error(`Either "text" or "path" must be provided`);if(u.length<=s)return{text:u,originalChars:u.length,compressedChars:u.length,ratio:1,segmentsKept:1,segmentsTotal:1};let d=t(u,l);if(d.length===0)return{text:``,originalChars:u.length,compressedChars:0,ratio:0,segmentsKept:0,segmentsTotal:0};let f=await i.embed(o),p=[];for(let t=0;t<d.length;t++){let n=e(f,await i.embed(d[t]));p.push({text:d[t],score:n,index:t})}let m=p.filter(e=>e.score>=c).sort((e,t)=>t.score-e.score),h=[],g=0;for(let e of m){if(g+e.text.length>s){g===0&&(h.push({...e,text:e.text.slice(0,s)}),g=s);break}h.push(e),g+=e.text.length+2}h.sort((e,t)=>e.index-t.index);let _=h.map(e=>e.text).join(`
|
|
2
2
|
|
|
3
|
-
`);return{text:
|
|
3
|
+
`);return{text:_,originalChars:u.length,compressedChars:_.length,ratio:_.length/u.length,segmentsKept:h.length,segmentsTotal:d.length}}export{i as compact};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region packages/tools/src/config-extractor.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Configuration values extraction for onboard.
|
|
4
|
+
* Scans config files (.env, package.json, application.properties, etc.)
|
|
5
|
+
* and produces a Markdown summary with sensitive value masking.
|
|
6
|
+
*/
|
|
7
|
+
declare function extractConfigValues(rootPath: string, projectName: string): Promise<string>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { extractConfigValues };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{readFile as e,readdir as t}from"node:fs/promises";import{basename as n,join as r,relative as i}from"node:path";const a=new Set([`node_modules`,`.git`,`dist`,`build`,`coverage`,`.turbo`,`.cache`,`cdk.out`,`__pycache__`,`.venv`,`target`,`obj`,`.gradle`]),o=[{glob:/\.env(?:\.\w+)?$/,type:`env`},{glob:/\.env\.example$/,type:`env`},{glob:/package\.json$/,type:`package-json`},{glob:/^(?:app|config|settings|default)\.(?:json|ya?ml|toml)$/i,type:`config`},{glob:/docker-compose\.ya?ml$/,type:`docker`},{glob:/cdk\.json$/,type:`cdk`},{glob:/turbo\.json$/,type:`tooling`},{glob:/application\.(?:properties|ya?ml)$/i,type:`spring`},{glob:/settings\.py$/,type:`django`},{glob:/\.flaskenv$/,type:`env`},{glob:/appsettings\.(?:\w+\.)?json$/i,type:`dotnet`}];async function s(t,n){let r=[],a=await c(t),o=/kb\.config\.json$/;for(let n of a)try{let a=i(t,n).replace(/\\/g,`/`);if(o.test(a))continue;let s=await e(n,`utf-8`),c=l(n);if(a.split(`/`).length-1>1&&c===`tooling`)continue;let u=d(s,c);u.length>0&&r.push({file:a,type:c,values:u})}catch{}return p(r,n)}async function c(e){let n=[],i=async(e,s)=>{if(!(s>3))try{let c=await t(e,{withFileTypes:!0});for(let t of c){if(a.has(t.name))continue;let c=r(e,t.name);t.isDirectory()&&!t.name.startsWith(`.`)?await i(c,s+1):t.isFile()&&o.some(e=>e.glob.test(t.name))&&n.push(c)}}catch{}};return await i(e,0),n}function l(e){let t=n(e);for(let e of o)if(e.glob.test(t))return e.type;return`unknown`}const u=/(?:secret|password|token|key|api.?key|auth|credential|private)/i;function d(e,t){let n=[];if(t===`env`)for(let t of e.split(`
|
|
2
|
+
`)){let e=t.trim();if(!e||e.startsWith(`#`))continue;let r=e.indexOf(`=`);if(r===-1)continue;let i=e.slice(0,r).trim(),a=e.slice(r+1).trim(),o=u.test(i);n.push({key:i,value:o?`***`:a,sensitive:o})}else if(t===`package-json`)try{let t=JSON.parse(e);if(t.scripts)for(let[e,r]of Object.entries(t.scripts))n.push({key:`scripts.${e}`,value:String(r),sensitive:!1});if(t.engines)for(let[e,r]of Object.entries(t.engines))n.push({key:`engines.${e}`,value:String(r),sensitive:!1})}catch{}else if(t===`spring`)for(let t of e.split(`
|
|
3
|
+
`)){let e=t.trim();if(!e||e.startsWith(`#`)||e.startsWith(`---`))continue;let r=e.match(/^([\w.[\]-]+)\s*[=:]\s*(.*)$/);if(r){let e=r[1],t=r[2].trim(),i=u.test(e);n.push({key:e,value:i?`***`:t,sensitive:i})}}else if(t===`json`||t===`config`||t===`cdk`||t===`tooling`||t===`dotnet`)try{f(JSON.parse(e),``,n,0)}catch{}else if(t===`django`)for(let t of e.split(`
|
|
4
|
+
`)){let e=t.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.+)$/);if(e){let t=e[1],r=e[2].trim(),i=u.test(t);n.push({key:t,value:i?`***`:r.slice(0,100),sensitive:i})}}return n}function f(e,t,n,r){if(!(r>3)&&typeof e==`object`&&e&&!Array.isArray(e))for(let[i,a]of Object.entries(e)){let e=t?`${t}.${i}`:i;if(typeof a==`object`&&a&&!Array.isArray(a))f(a,e,n,r+1);else{let t=u.test(i),r=Array.isArray(a)?`[${a.length} items]`:String(a);n.push({key:e,value:t?`***`:r.slice(0,120),sensitive:t})}}}function p(e,t){let n=[];if(n.push(`## Configuration Values: ${t}\n`),e.length===0)return n.push(`No configuration files detected.`),n.join(`
|
|
5
|
+
`);n.push(`**${e.length} config files** found\n`);let r=new Map;for(let t of e)r.has(t.type)||r.set(t.type,[]),r.get(t.type)?.push(t);for(let[e,t]of r){if(e===`package-json`&&t.length>2){n.push(`### ${e}\n`);let r=t.find(e=>e.file===`package.json`);if(r){n.push(`#### ${r.file}\n`),n.push(`| Key | Value | Sensitive |`),n.push(`|-----|-------|-----------|`);for(let e of r.values.slice(0,50)){let t=e.value.replace(/\|/g,`\\|`);n.push(`| ${e.key} | ${t} | ${e.sensitive?`⚠️ yes`:`no`} |`)}n.push(``)}let i=t.filter(e=>e.file!==`package.json`);if(i.length>0){let e=new Map;for(let t of i)for(let n of t.values){let t=`${n.key}=${n.value}`;e.set(t,(e.get(t)??0)+1)}let t=Math.max(2,Math.floor(i.length*.5));n.push(`#### Sub-packages (${i.length} packages)\n`);let r=[...e.entries()].filter(([,e])=>e>=t).map(([e])=>{let[t,...n]=e.split(`=`);return{key:t,value:n.join(`=`)}});if(r.length>0){n.push(`**Common scripts** (shared by most sub-packages):
|
|
6
|
+
`),n.push(`| Key | Value |`),n.push(`|-----|-------|`);for(let e of r)n.push(`| ${e.key} | ${e.value.replace(/\|/g,`\\|`)} |`);n.push(``)}let a=new Map;for(let n of i){let r=n.values.filter(n=>{let r=`${n.key}=${n.value}`;return(e.get(r)??0)<t});if(r.length===0)continue;let i=r.map(e=>`${e.key}=${e.value}`).sort().join(`||`),o=a.get(i);o?o.files.push(n.file):a.set(i,{files:[n.file],entries:r.map(e=>({key:e.key,value:e.value}))})}for(let[,e]of a){e.files.length>1?n.push(`**${e.files.length} packages** (${e.files.map(e=>e.split(`/`).slice(-2,-1)[0]||e).join(`, `)}):`):n.push(`**${e.files[0]}**:`),n.push(`| Key | Value |`),n.push(`|-----|-------|`);for(let t of e.entries)n.push(`| ${t.key} | ${t.value.replace(/\|/g,`\\|`)} |`);n.push(``)}}continue}if(t.length>3){let r=t.map(e=>e.values.map(e=>`${e.key}=${e.value}`).sort().join(`||`)),i=r.sort((e,t)=>r.filter(e=>e===t).length-r.filter(t=>t===e).length)[0];if(r.filter(e=>e===i).length>2){n.push(`### ${e}\n`);let a=t[r.indexOf(i)],o=t.filter((e,t)=>r[t]===i).map(e=>e.file),s=t.filter((e,t)=>r[t]!==i);n.push(`**${o.length} identical files**: ${o.join(`, `)}\n`),n.push(`| Key | Value | Sensitive |`),n.push(`|-----|-------|-----------|`);for(let e of a.values.slice(0,30)){let t=e.value.replace(/\|/g,`\\|`);n.push(`| ${e.key} | ${t} | ${e.sensitive?`⚠️ yes`:`no`} |`)}n.push(``);for(let e of s){n.push(`#### ${e.file}\n`),n.push(`| Key | Value | Sensitive |`),n.push(`|-----|-------|-----------|`);for(let t of e.values.slice(0,30)){let e=t.value.replace(/\|/g,`\\|`);n.push(`| ${t.key} | ${e} | ${t.sensitive?`⚠️ yes`:`no`} |`)}n.push(``)}continue}}n.push(`### ${e}\n`);for(let e of t){n.push(`#### ${e.file}\n`),n.push(`| Key | Value | Sensitive |`),n.push(`|-----|-------|-----------|`);for(let t of e.values.slice(0,50)){let e=t.value.replace(/\|/g,`\\|`);n.push(`| ${t.key} | ${e} | ${t.sensitive?`⚠️ yes`:`no`} |`)}e.values.length>50&&n.push(`\n_...and ${e.values.length-50} more values._`),n.push(``)}}let i=e.reduce((e,t)=>e+t.values.filter(e=>e.sensitive).length,0);return i>0&&n.push(`\n**⚠️ ${i} sensitive values detected** (values masked).`),n.join(`
|
|
7
|
+
`)}export{s as extractConfigValues};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`).length-1,a=t.slice(r).match(/export\s+(?:async\s+)?(\w+)/);g.push({name:n[1],path:e.record.sourcePath,line:e.record.startLine+i,kind:a?.[1]??`unknown`})}}let y=new Map;for(let e of g){let t=`${e.path}:${e.name}`;y.has(t)||y.set(t,e)}let b=[];for(let
|
|
1
|
+
import{escapeRegExp as e}from"./regex-utils.js";import{readFile as t}from"node:fs/promises";import{extname as n}from"node:path";import{SUPPORTED_EXTENSIONS as r,WasmRuntime as i,extractSymbols as a}from"../../chunker/dist/index.js";const o=new Set([`.md`,`.mdx`]);async function s(s,l,u={}){let{rootPath:d,limit:f=100}=u,p=await s.embed(`export function class const type interface enum`),m=await l.search(p,{limit:f*3}),h=/^export\s+(?:async\s+)?(?:function|class|const|let|interface|type|enum)\s+(\w+)/gm,g=[],_=new Map;for(let e of m){if(!c(e.record.sourcePath,d))continue;let t=_.get(e.record.sourcePath)??[];t.push(e),_.set(e.record.sourcePath,t)}let v=new Set;if(i.get())for(let[e]of _){let i=n(e);if(r.has(i))try{let n=await a(await t(e,`utf-8`),i,e);for(let t of n)t.exported&&g.push({name:t.name,path:e,line:t.line,kind:t.kind});v.add(e)}catch{}}for(let[e,t]of _)if(!v.has(e))for(let e of t){let t=e.record.content;h.lastIndex=0;for(let n of t.matchAll(h)){let r=n.index??0,i=t.slice(0,r).split(`
|
|
2
|
+
`).length-1,a=t.slice(r).match(/export\s+(?:async\s+)?(\w+)/);g.push({name:n[1],path:e.record.sourcePath,line:e.record.startLine+i,kind:a?.[1]??`unknown`})}}let y=new Map;for(let e of g){let t=`${e.path}:${e.name}`;y.has(t)||y.set(t,e)}let b=[];for(let t of y.values()){let n=e(t.name),r=RegExp(`import\\s+.*\\b${n}\\b.*from`,`m`),i=RegExp(`export\\s+\\{[^}]*\\b${n}\\b`,`m`),a=await l.ftsSearch(`import ${t.name}`,{limit:10}),o=a.some(e=>e.record.sourcePath!==t.path&&r.test(e.record.content)),s=a.some(e=>e.record.sourcePath!==t.path&&i.test(e.record.content));!o&&!s&&b.push(t)}let x=(e,t)=>e.path===t.path?e.line-t.line:e.path.localeCompare(t.path),S=[],C=[];for(let e of b){let t=n(e.path).toLowerCase();o.has(t)?C.push(e):S.push(e)}return S.sort(x),C.sort(x),{deadInSource:S,deadInDocs:C,totalExports:y.size,totalDeadSource:S.length,totalDeadDocs:C.length}}function c(e,t){if(!t)return!0;let n=l(t).replace(/\/+$/,``),r=l(e);return r===n||r.startsWith(`${n}/`)}function l(e){return e.replace(/\\/g,`/`).replace(/^\.\//,``)}export{s as findDeadSymbols};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region packages/tools/src/diagram-builder.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Architecture diagram generation for onboard.
|
|
4
|
+
* Produces C4 Container + Architectural Flow Mermaid diagrams
|
|
5
|
+
* from AST call graph and analyzer data.
|
|
6
|
+
*/
|
|
7
|
+
declare function buildDiagrams(callGraph: Map<string, Map<string, string[]>>, dataMap: Map<string, Record<string, unknown>>, projectName: string): string;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { buildDiagrams };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{getPackageKey as e,isTestPath as t}from"./onboard-utils.js";function n(n,r,i){let a=r.get(`symbols`),o=r.get(`entry-points`),s=r.get(`dependencies`),c=new Map;for(let[r,i]of n)if(!t(r))for(let[n,a]of i){if(t(n))continue;let i=e(r),o=e(n);if(i===o)continue;let s=`${i}|${o}`;c.set(s,(c.get(s)??0)+a.length)}if(c.size===0)return`## Architecture Diagram
|
|
2
|
+
|
|
3
|
+
No cross-package dependencies detected.`;let l=new Set;for(let e of c.keys()){let[t,n]=e.split(`|`);l.add(t),l.add(n)}let u=new Map;if(a?.symbols)for(let n of a.symbols){if(!n.exported)continue;let r=n.filePath.replace(/\\/g,`/`);if(t(r))continue;let i=e(r);u.set(i,(u.get(i)??0)+1)}let d=new Map;if(o?.entryPoints)for(let t of o.entryPoints){let n=e(t.filePath.replace(/\\/g,`/`)),r=d.get(n);r?(r.count++,t.trigger&&r.triggers.add(t.trigger)):d.set(n,{count:1,triggers:new Set(t.trigger?[t.trigger]:[])})}let f=[];if(s?.external){let e=s.external,t={"client-dynamodb":{id:`dynamodb`,name:`DynamoDB`},"lib-dynamodb":{id:`dynamodb`,name:`DynamoDB`},"client-sqs":{id:`sqs`,name:`SQS`},"client-ses":{id:`ses`,name:`SES`},"client-sesv2":{id:`ses`,name:`SES`},"client-s3":{id:`s3`,name:`S3`},"client-eventbridge":{id:`eventbridge`,name:`EventBridge`},"client-sns":{id:`sns`,name:`SNS`},"client-secrets-manager":{id:`secrets`,name:`Secrets Manager`},"client-scheduler":{id:`scheduler`,name:`EventBridge Scheduler`},"client-apigatewaymanagementapi":{id:`apigw`,name:`API Gateway`},"client-cloudwatch":{id:`cloudwatch`,name:`CloudWatch`}},n=new Set;for(let r of Object.keys(e))for(let[e,i]of Object.entries(t))r.includes(e)&&!n.has(i.id)&&(n.add(i.id),f.push(i));f.sort((e,t)=>e.name.localeCompare(t.name))}let p=new Map;for(let e of[...l].sort()){let t=e.split(`/`)[0],n=p.get(t);n?n.push(e):p.set(t,[e])}let m=new Map;if(a?.symbols){let t=new Map;for(let n of a.symbols){let r=n.filePath.replace(/\\/g,`/`),i=e(r),a=r.match(/\.[^./]+$/)?.[0]||``;t.has(i)||t.set(i,new Map);let o=t.get(i);o.set(a,(o.get(a)??0)+1)}let n={".ts":`TypeScript`,".tsx":`TypeScript`,".js":`JavaScript`,".jsx":`JavaScript`,".java":`Java`,".kt":`Kotlin`,".scala":`Scala`,".py":`Python`,".go":`Go`,".rs":`Rust`,".cs":`C#`,".rb":`Ruby`,".php":`PHP`,".swift":`Swift`};for(let[e,r]of t){let t=``,i=0;for(let[e,n]of r)n>i&&(i=n,t=e);m.set(e,n[t]||`TypeScript`)}}let h=e=>e.replace(/[^a-zA-Z0-9]/g,`_`),g=[];g.push("```mermaid"),g.push(`C4Container`),g.push(` title C4 Container: ${i}`),g.push(``);let _=e=>{let t=[],n=d.get(e);n&&(t.push(`${n.count} handlers`),n.triggers.size>0&&t.push([...n.triggers].join(`, `)));let r=u.get(e);return r&&t.push(`${r} exports`),t.join(` · `)||``},v=e=>{let t=m.get(e)||`TypeScript`;if(e.startsWith(`infra`))return`CDK/${t}`;if(d.has(e)){let n=d.get(e);if(n?.triggers.has(`SQS`)||n?.triggers.has(`SNS`)||n?.triggers.has(`API Gateway`))return`Lambda/${t}`;if(n?.triggers.has(`HTTP Server`)||n?.triggers.has(`HTTP Endpoint`))return`Spring Boot/${t}`}return t};for(let[e,t]of[...p.entries()].sort()){let n=new Set([`com`,`org`,`net`,`io`,`dev`,`src`]).has(e)?i.charAt(0).toUpperCase()+i.slice(1):e.charAt(0).toUpperCase()+e.slice(1);if(t.length===1&&t[0]===e){let e=t[0];g.push(` Container(${h(e)}, "${e}", "${v(e)}", "${_(e)}")`)}else{g.push(` System_Boundary(${h(e)}_boundary, "${n}") {`);for(let e of t){let t=e.split(`/`).slice(1).join(`/`)||e;g.push(` Container(${h(e)}, "${t}", "${v(e)}", "${_(e)}")`)}g.push(` }`)}g.push(``)}if(f.length>0){for(let e of f)g.push(` System_Ext(ext_${e.id}, "${e.name}", "AWS")`);g.push(``)}let y=[...c.entries()].sort((e,t)=>t[1]-e[1]);for(let[e,t]of y.slice(0,30)){let[n,r]=e.split(`|`);g.push(` Rel(${h(n)}, ${h(r)}, "Uses", "${t} calls")`)}g.push("```");let b=`## C4 Container Diagram\n\n${g.join(`
|
|
4
|
+
`)}`,x=[];x.push("```mermaid"),x.push(`graph TB`);let S=new Set;for(let[,e]of d)for(let t of e.triggers)S.add(t);if(S.size>0){x.push(` subgraph Triggers["External Triggers"]`);for(let e of[...S].sort()){let t=`trigger_${e.replace(/[^a-zA-Z0-9]/g,`_`)}`;x.push(` ${t}(("${e}"))`)}x.push(` end`),x.push(``)}let C=[...l].filter(e=>d.has(e)).sort(),w=[...l].filter(e=>!d.has(e)).sort();if(C.length>0){x.push(` subgraph Services["Service Layer"]`);for(let e of C){let t=`flow_${h(e)}`,n=e.includes(`/`)?e.split(`/`).pop()??e:e,r=d.get(e);x.push(` ${t}["${n} (${r?.count??0} handlers)"]`)}x.push(` end`),x.push(``)}if(w.length>0){x.push(` subgraph Libraries["Shared Libraries"]`);for(let e of w){let t=`flow_${h(e)}`,n=e.includes(`/`)?e.split(`/`).pop()??e:e;x.push(` ${t}["${n}"]`)}x.push(` end`),x.push(``)}if(f.length>0){x.push(` subgraph External["AWS Services"]`);for(let e of f)x.push(` flow_ext_${e.id}[("${e.name}")]`);x.push(` end`),x.push(``)}for(let e of C){let t=d.get(e);if(!t)continue;let n=`flow_${h(e)}`;for(let e of t.triggers){let t=`trigger_${e.replace(/[^a-zA-Z0-9]/g,`_`)}`;x.push(` ${t} --> ${n}`)}}let T=y.filter(([e])=>{let[t,n]=e.split(`|`);return d.has(t)&&!d.has(n)});for(let[e,t]of T.slice(0,15)){let[n,r]=e.split(`|`);x.push(` flow_${h(n)} -->|${t}| flow_${h(r)}`)}let E=y.filter(([e])=>{let[t,n]=e.split(`|`);return!d.has(t)&&!d.has(n)});for(let[e,t]of E.slice(0,10)){let[n,r]=e.split(`|`);x.push(` flow_${h(n)} -->|${t}| flow_${h(r)}`)}x.push("```");let D=`## Architectural Flow\n\n${x.join(`
|
|
5
|
+
`)}`,O=[`# Architecture Diagrams: ${i}\n`];return O.push(b),O.push(D),O.join(`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
`)}export{n as buildDiagrams};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"node:vm";function t(t){let{code:i,lang:a=`js`,timeout:o=5e3}=t,s=Date.now();try{let t=a===`ts`?r(i):i,
|
|
2
|
-
`)+(d===void 0?``:`\n→ ${n(d)}`):d===void 0?`(no output)`:n(d),durationMs:Date.now()-
|
|
1
|
+
import e from"node:vm";function t(t){let{code:i,lang:a=`js`,timeout:o=5e3}=t,s=Math.min(Math.max(o,100),1e4),c=Date.now();try{let t=a===`ts`?r(i):i,o=[],l={console:{log:(...e)=>o.push(e.map(String).join(` `)),error:(...e)=>o.push(`[error] ${e.map(String).join(` `)}`),warn:(...e)=>o.push(`[warn] ${e.map(String).join(` `)}`)},setTimeout:void 0,setInterval:void 0,setImmediate:void 0,fetch:void 0,process:void 0,require:void 0,JSON,Math,Date,Array,Object,String,Number,Boolean,Map,Set,RegExp,Error,Promise,parseInt,parseFloat,isNaN,isFinite},u=e.createContext(l,{codeGeneration:{strings:!1,wasm:!1}}),d=e.runInContext(t,u,{timeout:s});return{success:!0,output:o.length>0?o.join(`
|
|
2
|
+
`)+(d===void 0?``:`\n→ ${n(d)}`):d===void 0?`(no output)`:n(d),durationMs:Date.now()-c}}catch(e){return{success:!1,output:``,error:e.message,durationMs:Date.now()-c}}}function n(e){if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`object`)try{return JSON.stringify(e,null,2)}catch{return String(e)}return String(e)}function r(e){return e.replace(/^\s*import\s+type\s+.*?;\s*$/gm,``).replace(/^\s*(?:export\s+)?interface\s+\w+[^{]*\{[\s\S]*?^\s*}\s*$/gm,``).replace(/^\s*(?:export\s+)?type\s+\w+\s*=.*?;\s*$/gm,``).replace(/([,(]\s*[A-Za-z_$][\w$]*)\s*:\s*[^,)=\n]+/g,`$1`).replace(/\)\s*:\s*[^={\n]+(?=\s*(?:=>|\{))/g,`)`).replace(/\s+as\s+[A-Za-z_$][\w$<>,[\]|&\s.]*/g,``).replace(/<(?:[A-Za-z_$][\w$]*\s*,?\s*)+>(?=\s*\()/g,``)}export{t as evaluate};
|
|
@@ -9,6 +9,7 @@ type EvidenceStatus = 'V' | 'A' | 'U';
|
|
|
9
9
|
type UnknownType = 'contract' | 'convention' | 'freshness' | 'runtime' | 'data-flow' | 'impact';
|
|
10
10
|
type GateDecision = 'YIELD' | 'HOLD' | 'HARD_BLOCK' | 'FORCED_DELIVERY';
|
|
11
11
|
type ForgeTier = 'floor' | 'standard' | 'critical';
|
|
12
|
+
type SafetyGate = 'provenance' | 'commitment' | 'coverage';
|
|
12
13
|
interface EvidenceEntry {
|
|
13
14
|
id: number;
|
|
14
15
|
claim: string;
|
|
@@ -16,6 +17,7 @@ interface EvidenceEntry {
|
|
|
16
17
|
receipt: string;
|
|
17
18
|
criticalPath: boolean;
|
|
18
19
|
unknownType?: UnknownType;
|
|
20
|
+
safetyGate?: SafetyGate;
|
|
19
21
|
}
|
|
20
22
|
interface EvidenceMapState {
|
|
21
23
|
taskId: string;
|
|
@@ -24,6 +26,12 @@ interface EvidenceMapState {
|
|
|
24
26
|
createdAt: string;
|
|
25
27
|
updatedAt: string;
|
|
26
28
|
}
|
|
29
|
+
interface SafetyGateResult {
|
|
30
|
+
provenance: 'pass' | 'fail';
|
|
31
|
+
commitment: 'pass' | 'fail';
|
|
32
|
+
coverage: 'pass' | 'fail';
|
|
33
|
+
failures: string[];
|
|
34
|
+
}
|
|
27
35
|
interface GateResult {
|
|
28
36
|
decision: GateDecision;
|
|
29
37
|
reason: string;
|
|
@@ -35,6 +43,7 @@ interface GateResult {
|
|
|
35
43
|
assumed: number;
|
|
36
44
|
unresolved: number;
|
|
37
45
|
};
|
|
46
|
+
safetyGates?: SafetyGateResult;
|
|
38
47
|
annotation?: string;
|
|
39
48
|
}
|
|
40
49
|
type EvidenceMapAction = {
|
|
@@ -49,6 +58,7 @@ type EvidenceMapAction = {
|
|
|
49
58
|
receipt: string;
|
|
50
59
|
criticalPath?: boolean;
|
|
51
60
|
unknownType?: UnknownType;
|
|
61
|
+
safetyGate?: SafetyGate;
|
|
52
62
|
} | {
|
|
53
63
|
action: 'update';
|
|
54
64
|
taskId: string;
|
|
@@ -77,5 +87,6 @@ interface EvidenceMapResult {
|
|
|
77
87
|
formattedMap?: string;
|
|
78
88
|
}
|
|
79
89
|
declare function evidenceMap(action: EvidenceMapAction, cwd?: string): EvidenceMapResult;
|
|
90
|
+
declare function autoClaimTestFailures(taskId: string, failures: string[], cwd?: string): EvidenceEntry[];
|
|
80
91
|
//#endregion
|
|
81
|
-
export { EvidenceEntry, EvidenceMapAction, EvidenceMapResult, EvidenceMapState, EvidenceStatus, ForgeTier, GateDecision, GateResult, UnknownType, evidenceMap };
|
|
92
|
+
export { EvidenceEntry, EvidenceMapAction, EvidenceMapResult, EvidenceMapState, EvidenceStatus, ForgeTier, GateDecision, GateResult, SafetyGate, SafetyGateResult, UnknownType, autoClaimTestFailures, evidenceMap };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{dirname as e,resolve as t}from"node:path";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{KB_PATHS as o}from"../../core/dist/index.js";const s=o.state;function c(e){return t(e??process.cwd(),s,`evidence-maps.json`)}function l(e){let t=c(e);if(!n(t))return{};try{let e=i(t,`utf-8`);return JSON.parse(e)}catch{return{}}}function u(t,i){let o=c(i),s=e(o);n(s)||r(s,{recursive:!0}),a(o,`${JSON.stringify(t,null,2)}\n`,`utf-8`)}function d(e,t){let n=l(t),r=n[e];if(!r)throw Error(`Evidence map not found: ${e}`);return{maps:n,state:r}}function f(e){return e.reduce((e,t)=>Math.max(e,t.id),0)+1}function p(e){let t=e.trim();if(!t)throw Error(`Claim is required`);if(/\r?\n/.test(t))throw Error(`Claim must be a single line`);return t}function m(e){return(e??``).replace(/\r?\n/g,` `).replace(/\|/g,`\\|`)}function h(e){let t=[`| # | Claim | Status | Receipt | Critical | Type
|
|
2
|
-
`)}function g(e){return{total:e.length,verified:e.filter(e=>e.status===`V`).length,assumed:e.filter(e=>e.status===`A`).length,unresolved:e.filter(e=>e.status===`U`).length}}function _(e){let t=[];for(let n of e.entries)n.status===`V`&&n.receipt.trim()===``&&t.push(`V entry without receipt`),n.status===`A`&&e.tier===`critical`&&n.unknownType===`contract`&&t.push(`Assumed contract at Critical tier — should be Verified`);return t}function v(e){return`FORCED DELIVERY annotation: unresolved entries remain -> ${e.filter(e=>e.status===`U`).map(e=>`#${e.id} ${e.claim}`).join(`; `)}`}function y(e,t=0){let n=e.entries.filter(e=>e.criticalPath&&e.status===`U`),r=_(e),i=g(e.entries);return n.find(e=>e.unknownType===`contract`)?{decision:`HARD_BLOCK`,reason:`Unresolved contract unknown on critical path`,unresolvedCritical:n,warnings:r,stats:i}:n.length>0&&t===0?{decision:`HOLD`,reason:`Unresolved critical-path unknown — retry available`,unresolvedCritical:n,warnings:r,stats:i}:n.length>0&&t>=1?{decision:`FORCED_DELIVERY`,reason:`Unresolved critical-path unknown after retry`,unresolvedCritical:n,warnings:r,stats:i,annotation:v(e.entries)}:{decision:`YIELD`,reason:`All critical-path claims satisfy gate rules`,unresolvedCritical:[],warnings:r,stats:i}}function
|
|
1
|
+
import{dirname as e,resolve as t}from"node:path";import{existsSync as n,mkdirSync as r,readFileSync as i,writeFileSync as a}from"node:fs";import{KB_PATHS as o}from"../../core/dist/index.js";const s=o.state;function c(e){return t(e??process.cwd(),s,`evidence-maps.json`)}function l(e){let t=c(e);if(!n(t))return{};try{let e=i(t,`utf-8`);return JSON.parse(e)}catch{return{}}}function u(t,i){let o=c(i),s=e(o);n(s)||r(s,{recursive:!0}),a(o,`${JSON.stringify(t,null,2)}\n`,`utf-8`)}function d(e,t){let n=l(t),r=n[e];if(!r)throw Error(`Evidence map not found: ${e}`);return{maps:n,state:r}}function f(e){return e.reduce((e,t)=>Math.max(e,t.id),0)+1}function p(e){let t=e.trim();if(!t)throw Error(`Claim is required`);if(/\r?\n/.test(t))throw Error(`Claim must be a single line`);return t}function m(e){return(e??``).replace(/\r?\n/g,` `).replace(/\|/g,`\\|`)}function h(e){let t=[`| # | Claim | Status | Receipt | Critical | Type | Safety |`,`|---|-------|--------|---------|----------|------|--------|`];for(let n of e.entries)t.push(`| ${n.id} | ${m(n.claim)} | ${n.status} | ${m(n.receipt)} | ${n.criticalPath?`yes`:`no`} | ${m(n.unknownType)} | ${m(n.safetyGate)} |`);return t.join(`
|
|
2
|
+
`)}function g(e){return{total:e.length,verified:e.filter(e=>e.status===`V`).length,assumed:e.filter(e=>e.status===`A`).length,unresolved:e.filter(e=>e.status===`U`).length}}function _(e){let t=[];for(let n of e.entries)n.status===`V`&&n.receipt.trim()===``&&t.push(`V entry without receipt`),n.status===`A`&&e.tier===`critical`&&n.unknownType===`contract`&&t.push(`Assumed contract at Critical tier — should be Verified`);return t}function v(e){return`FORCED DELIVERY annotation: unresolved entries remain -> ${e.filter(e=>e.status===`U`).map(e=>`#${e.id} ${e.claim}`).join(`; `)}`}function y(e){let t=[],n=e.entries.filter(e=>e.status===`V`&&!e.receipt.trim());n.length>0&&t.push(`Provenance: ${n.length} verified claim(s) lack receipts`);let r=e.entries.filter(e=>e.safetyGate===`commitment`&&e.status!==`V`);r.length>0&&t.push(`Commitment: ${r.length} commitment(s) not verified`);let i=e.entries.some(e=>e.safetyGate===`coverage`&&e.status===`U`);return i&&t.push(`Coverage: unresolved coverage entries remain`),{provenance:n.length>0?`fail`:`pass`,commitment:r.length>0?`fail`:`pass`,coverage:i?`fail`:`pass`,failures:t}}function b(e,t=0){let n=e.entries.filter(e=>e.criticalPath&&e.status===`U`),r=_(e),i=g(e.entries);return n.find(e=>e.unknownType===`contract`)?{decision:`HARD_BLOCK`,reason:`Unresolved contract unknown on critical path`,unresolvedCritical:n,warnings:r,stats:i}:n.length>0&&t===0?{decision:`HOLD`,reason:`Unresolved critical-path unknown — retry available`,unresolvedCritical:n,warnings:r,stats:i}:n.length>0&&t>=1?{decision:`FORCED_DELIVERY`,reason:`Unresolved critical-path unknown after retry`,unresolvedCritical:n,warnings:r,stats:i,annotation:v(e.entries)}:{decision:`YIELD`,reason:`All critical-path claims satisfy gate rules`,unresolvedCritical:[],warnings:r,stats:i,...x(e,r,i)}}function x(e,t,n){if(!e.entries.some(e=>e.safetyGate)||e.tier===`floor`)return{};let r=y(e);return r.failures.length>0?{safetyGates:r,decision:`HOLD`,reason:`Safety gate failure: ${r.failures.join(`; `)}`,warnings:[...t,...r.failures]}:{safetyGates:r}}function S(e,t){switch(e.action){case`create`:{let n=l(t),r=new Date().toISOString(),i={taskId:e.taskId,tier:e.tier,entries:[],createdAt:r,updatedAt:r};return n[e.taskId]=i,u(n,t),{state:i,formattedMap:h(i)}}case`add`:{let{maps:n,state:r}=d(e.taskId,t),i={id:f(r.entries),claim:p(e.claim),status:e.status,receipt:e.receipt,criticalPath:e.criticalPath??!1,unknownType:e.unknownType,safetyGate:e.safetyGate};return r.entries.push(i),r.updatedAt=new Date().toISOString(),n[e.taskId]=r,u(n,t),{state:r,entry:i,formattedMap:h(r)}}case`update`:{let{maps:n,state:r}=d(e.taskId,t),i=r.entries.find(t=>t.id===e.id);if(!i)throw Error(`Evidence entry not found: ${e.id}`);return i.status=e.status,i.receipt=e.receipt,r.updatedAt=new Date().toISOString(),n[e.taskId]=r,u(n,t),{state:r,entry:i,formattedMap:h(r)}}case`get`:{let{state:n}=d(e.taskId,t);return{state:n,formattedMap:h(n)}}case`gate`:{let{state:n}=d(e.taskId,t);return{state:n,gate:b(n,e.retryCount??0),formattedMap:h(n)}}case`list`:return{states:Object.values(l(t)).sort((e,t)=>e.createdAt.localeCompare(t.createdAt))};case`delete`:{let n=l(t);return e.taskId in n?(delete n[e.taskId],u(n,t),{deleted:!0}):{deleted:!1}}}}function C(e,t,n){let r=[];for(let i of t){let t=S({action:`add`,taskId:e,claim:`Test failure: ${i}`,status:`U`,receipt:``,criticalPath:!0},n);t.entry&&r.push(t.entry)}return r}export{C as autoClaimTestFailures,S as evidenceMap};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readFile as e}from"node:fs/promises";import{extname as
|
|
2
|
-
`),
|
|
1
|
+
import{readFile as e,stat as t}from"node:fs/promises";import{extname as n}from"node:path";import{SUPPORTED_EXTENSIONS as r,WasmRuntime as i,extractCalls as a,extractImports as o,extractSymbols as s}from"../../chunker/dist/index.js";async function c(a){let{path:o,previewLines:s=3}=a;if(!a.content){let e;try{e=await t(o)}catch(e){let t=e.code;throw t===`ENOENT`?Error(`File not found: ${o}. Check the path and try again.`):t===`EACCES`||t===`EPERM`?Error(`Permission denied reading ${o}. The file exists but is not accessible.`):e}if(e.size>1e7)throw Error(`File too large (${(e.size/1e6).toFixed(1)}MB). file_summary supports files up to 10MB. Use search or compact with a query instead.`)}let c=a.content??await e(o,`utf-8`),d=c.split(`
|
|
2
|
+
`),f=o.split(`.`).pop()??``,p=n(o);return i.get()&&r.has(p)?l(o,c,d,f,p):u(o,c,d,f)}async function l(e,t,n,r,i){let[c,l,u]=await Promise.all([s(t,i,e),o(t,i,e),a(t,i,e).catch(()=>[])]),f=l.map(e=>`import ${e.specifiers.length>0?`{ ${e.specifiers.join(`, `)} }`:`*`} from '${e.source}'`),p=[],m=[],h=[],g=[],_=[];for(let e of c)switch(e.exported&&p.push(e.name),e.kind){case`function`:case`method`:m.push({name:e.name,line:e.line,exported:e.exported,signature:e.signature});break;case`class`:h.push({name:e.name,line:e.line,exported:e.exported,signature:e.signature});break;case`interface`:g.push({name:e.name,line:e.line,exported:e.exported});break;case`type`:_.push({name:e.name,line:e.line,exported:e.exported});break}let v=l.map(e=>({source:e.source,specifiers:e.specifiers,isExternal:e.isExternal})),y=u.map(e=>({caller:e.callerName,callee:e.calleeName,line:e.line}));return{path:e,lines:n.length,language:d(r),imports:f,exports:p,functions:m,classes:h,interfaces:g,types:_,importDetails:v,callEdges:y.length>0?y:void 0,estimatedTokens:Math.ceil(t.length/4)}}function u(e,t,n,r){let i=[],a=[],o=[],s=[],c=[],l=[];for(let e=0;e<n.length;e+=1){let t=n[e],r=e+1;if(/^import\s+.+/.test(t)){i.push(t.trim());continue}let u=t.match(/^export\s+(?:async\s+)?function\s+(\w+)/);if(u){o.push({name:u[1],line:r,exported:!0}),a.push(u[1]);continue}let d=t.match(/^(?:async\s+)?function\s+(\w+)/);if(d){o.push({name:d[1],line:r,exported:!1});continue}let f=t.match(/^(export\s+)?const\s+(\w+)\s*=.*(?:=>|\bfunction\b)/);if(f){let e=!!f[1];o.push({name:f[2],line:r,exported:e}),e&&a.push(f[2]);continue}let p=t.match(/^export\s+const\s+(\w+)\s*=/);if(p){a.push(p[1]);continue}let m=t.match(/^(export\s+)?(?:abstract\s+)?class\s+(\w+)/);if(m){let e=!!m[1];s.push({name:m[2],line:r,exported:e}),e&&a.push(m[2]);continue}let h=t.match(/^(export\s+)?interface\s+(\w+)/);if(h){let e=!!h[1];c.push({name:h[2],line:r,exported:e}),e&&a.push(h[2]);continue}let g=t.match(/^(export\s+)?type\s+(\w+)/);if(g){let e=!!g[1];l.push({name:g[2],line:r,exported:e}),e&&a.push(g[2]);continue}let _=t.match(/^export\s+\{(.+)\}/);if(_){let e=_[1].split(`,`).map(e=>e.trim().split(/\s+as\s+/).pop()?.trim()??``).filter(Boolean);a.push(...e)}}return{path:e,lines:n.length,language:d(r),imports:i,exports:a,functions:o,classes:s,interfaces:c,types:l,estimatedTokens:Math.ceil(t.length/4)}}function d(e){return{ts:`typescript`,tsx:`typescript-jsx`,js:`javascript`,jsx:`javascript-jsx`,py:`python`,rs:`rust`,go:`go`,java:`java`,rb:`ruby`,md:`markdown`,json:`json`,yaml:`yaml`,yml:`yaml`,css:`css`,html:`html`,sh:`shell`,bash:`shell`}[e]??e}export{c as fileSummary};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
async function
|
|
1
|
+
import{escapeRegExp as e}from"./regex-utils.js";async function t(t,n,r){let{query:i,limit:a=5,contentType:o}=r,s=`usage example of ${i}`,c=await t.embed(s),l=await n.search(c,{limit:a*3,contentType:o}),u=RegExp(`\\b${e(i)}\\b`,`i`),d=l.filter(e=>u.test(e.record.content));return{query:i,examples:d.map(e=>{let t=e.record.content,n=/export\s+(?:async\s+)?(?:function|class|const|interface|type)\s/.test(t),r=/^\s*import\s/m.test(t),i=/(?:^|[\\/])(test|tests|__tests__|spec)(?:[\\/]|$)/i.test(e.record.sourcePath)||/\.(test|spec)\.[jt]sx?$/i.test(e.record.sourcePath),a=0;n||(a+=.1),r||(a+=.05),i&&(a+=.05);let o=t.split(`
|
|
2
2
|
`),s=o.findIndex(e=>u.test(e)),c=Math.max(0,s-2),l=Math.min(o.length,s+5),d=o.slice(c,l).join(`
|
|
3
|
-
`);return{path:e.record.sourcePath,startLine:e.record.startLine,endLine:e.record.endLine,content:d||t.slice(0,300),relevance:Math.min(1,e.score+a),context:i?`test`:n?`definition`:`usage`}}).sort((e,t)=>t.relevance-e.relevance).slice(0,a),totalFound:d.length}}
|
|
3
|
+
`);return{path:e.record.sourcePath,startLine:e.record.startLine,endLine:e.record.endLine,content:d||t.slice(0,300),relevance:Math.min(1,e.score+a),context:i?`test`:n?`definition`:`usage`}}).sort((e,t)=>t.relevance-e.relevance).slice(0,a),totalFound:d.length}}export{t as findExamples};
|
|
@@ -34,6 +34,10 @@ interface ForgeClassifyResult {
|
|
|
34
34
|
hasSecurityPath: boolean;
|
|
35
35
|
typedUnknownSeeds: TypedUnknownSeed[];
|
|
36
36
|
ceremony: ForgeClassifyCeremony;
|
|
37
|
+
reclassifyHint?: {
|
|
38
|
+
suggestedTier: ForgeTier;
|
|
39
|
+
reason: string;
|
|
40
|
+
};
|
|
37
41
|
}
|
|
38
42
|
declare function forgeClassify(options: ForgeClassifyOptions): Promise<ForgeClassifyResult>;
|
|
39
43
|
//#endregion
|