@vpxa/kb 0.1.32 → 0.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/analyzers/dist/diagram-generator.js +2 -2
- package/packages/analyzers/dist/pattern-analyzer.js +1 -1
- package/packages/analyzers/dist/regex-call-graph.js +1 -1
- package/packages/cli/dist/commands/init/constants.d.ts +2 -0
- package/packages/cli/dist/commands/init/constants.js +1 -1
- package/packages/present/dist/index.html +321 -22
- package/packages/server/dist/server.js +1 -1
- package/packages/server/dist/tools/onboard.tool.js +2 -2
- package/packages/server/dist/tools/present/browser.d.ts +4 -0
- package/packages/server/dist/tools/present/browser.js +93 -0
- package/packages/server/dist/tools/present/helpers.d.ts +13 -0
- package/packages/server/dist/tools/present/helpers.js +1 -0
- package/packages/server/dist/tools/present/html.d.ts +18 -0
- package/packages/server/dist/tools/present/html.js +5 -0
- package/packages/server/dist/tools/present/index.d.ts +2 -0
- package/packages/server/dist/tools/present/index.js +1 -0
- package/packages/server/dist/tools/present/markdown.d.ts +17 -0
- package/packages/server/dist/tools/present/markdown.js +8 -0
- package/packages/server/dist/tools/present/templates.d.ts +14 -0
- package/packages/server/dist/tools/present/templates.js +472 -0
- package/packages/server/dist/tools/present/tool.d.ts +23 -0
- package/packages/server/dist/tools/present/tool.js +19 -0
- package/packages/server/dist/tools/present.tool.d.ts +1 -6
- package/packages/server/dist/tools/present.tool.js +1 -114
- package/packages/tools/dist/compact.js +1 -1
- package/packages/tools/dist/file-cache.js +3 -3
- package/packages/tools/dist/file-summary.js +1 -1
- package/packages/tools/dist/onboard.d.ts +7 -0
- package/packages/tools/dist/onboard.js +4 -4
- package/skills/present/SKILL.md +283 -12
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{CuratedKnowledgeManager as e}from"./curated-manager.js";import{createElicitor as t,noopElicitor as n}from"./elicitor.js";import{bridgeMcpLogging as r}from"./mcp-logging.js";import{registerPrompts as i}from"./prompts.js";import{installReplayInterceptor as a}from"./replay-interceptor.js";import{ResourceNotifier as o}from"./resources/resource-notifier.js";import{registerResources as s}from"./resources/resources.js";import{createSamplingClient as c}from"./sampling.js";import{installStructuredContentGuard as l}from"./structured-content-guard.js";import{getToolMeta as u}from"./tool-metadata.js";import{installToolPrefix as d}from"./tool-prefix.js";import{registerAnalyzeDependenciesTool as f,registerAnalyzeDiagramTool as p,registerAnalyzeEntryPointsTool as m,registerAnalyzePatternsTool as h,registerAnalyzeStructureTool as g,registerAnalyzeSymbolsTool as _,registerBlastRadiusTool as v}from"./tools/analyze.tools.js";import{registerAuditTool as y}from"./tools/audit.tool.js";import{registerBrainstormTool as b}from"./tools/brainstorm.tool.js";import{initBridgeComponents as x,registerErPullTool as S,registerErPushTool as ee,registerErSyncStatusTool as C}from"./tools/bridge.tools.js";import{registerCompactTool as w,registerDeadSymbolsTool as te,registerFileSummaryTool as ne,registerFindTool as re,registerScopeMapTool as ie,registerSymbolTool as ae,registerTraceTool as oe}from"./tools/context.tools.js";import{registerErEvolveReviewTool as se}from"./tools/evolution.tools.js";import{registerBatchTool as ce,registerCheckTool as T,registerDelegateTool as le,registerEvalTool as E,registerParseOutputTool as D,registerTestRunTool as O}from"./tools/execution.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as k,registerForgeClassifyTool as A,registerForgeGroundTool as de,registerStratumCardTool as fe}from"./tools/forge.tools.js";import{registerForgetTool as pe}from"./tools/forget.tool.js";import{registerGraphTool as me}from"./tools/graph.tool.js";import{registerGuideTool as j,registerHealthTool as M,registerProcessTool as N,registerWatchTool as P,registerWebFetchTool as F}from"./tools/infra.tools.js";import{registerListTool as he}from"./tools/list.tool.js";import{registerLookupTool as ge}from"./tools/lookup.tool.js";import{registerCodemodTool as I,registerDataTransformTool as L,registerDiffParseTool as R,registerGitContextTool as z,registerRenameTool as B}from"./tools/manipulation.tools.js";import{registerOnboardTool as _e}from"./tools/onboard.tool.js";import{registerCheckpointTool as V,registerLaneTool as H,registerQueueTool as U,registerStashTool as W,registerWorksetTool as G}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as ve}from"./tools/policy.tools.js";import{registerPresentTool as K}from"./tools/present.tool.js";import{registerProduceKnowledgeTool as ye}from"./tools/produce.tool.js";import{registerReadTool as be}from"./tools/read.tool.js";import{registerReindexTool as xe}from"./tools/reindex.tool.js";import{registerRememberTool as Se}from"./tools/remember.tool.js";import{registerReplayTool as Ce}from"./tools/replay.tool.js";import{registerRestoreTool as we}from"./tools/restore.tool.js";import{registerSearchTool as Te}from"./tools/search.tool.js";import{getCurrentVersion as Ee}from"./version-check.js";import{registerEarlyStatusTool as De,registerStatusTool as Oe}from"./tools/status.tool.js";import{registerUpdateTool as ke}from"./tools/update.tool.js";import{registerChangelogTool as Ae,registerEncodeTool as je,registerEnvTool as Me,registerHttpTool as Ne,registerMeasureTool as Pe,registerRegexTestTool as Fe,registerSchemaValidateTool as Ie,registerSnippetTool as Le,registerTimeTool as Re,registerWebSearchTool as ze}from"./tools/utility.tools.js";import{existsSync as Be,statSync as Ve}from"node:fs";import{resolve as He}from"node:path";import{KB_PATHS as Ue,createLogger as We,serializeError as q}from"../../core/dist/index.js";import{initializeWasm as Ge}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ke}from"../../embeddings/dist/index.js";import{EvolutionCollector as qe,PolicyStore as Je}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Ye,IncrementalIndexer as Xe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ze,createStore as Qe}from"../../store/dist/index.js";import{FileCache as $e}from"../../tools/dist/index.js";import{McpServer as J}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=We(`server`);async function X(t){Y.info(`Initializing knowledge base components`);let[n,r,i,a]=await Promise.all([(async()=>{let e=new Ke({model:t.embedding.model,dimensions:t.embedding.dimensions});return await e.initialize(),Y.info(`Embedder loaded`,{modelId:e.modelId,dimensions:e.dimensions}),e})(),(async()=>{let e=await Qe({backend:t.store.backend,path:t.store.path});return await e.initialize(),Y.info(`Store initialized`),e})(),(async()=>{let e=new Ze({path:t.store.path});return await e.initialize(),Y.info(`Graph store initialized`),e})(),(async()=>{let e=await Ge();return e?Y.info(`WASM tree-sitter enabled for AST analysis`):Y.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),o=new Xe(n,r),s=new Ye(t.store.path);s.load(),o.setHashCache(s);let c=t.curated.path,l=new e(c,r,n);o.setGraphStore(i);let u=x(t.er),d=u?new Je(t.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new qe:void 0,p=He(t.sources[0]?.path??process.cwd(),Ue.aiKb),m=Be(p),h=t.onboardDir?Be(t.onboardDir):!1,g=m||h,_,v=m?p:t.onboardDir;if(g&&v)try{_=Ve(v).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:n,store:r,indexer:o,curated:l,graphStore:i,fileCache:new $e,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function et(e,n){let a=new J({name:n.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}});return r(a),d(a,n.toolPrefix??``),Z(a,e,n,t(a),new o(a),c(a)),i(a,{curated:e.curated,store:e.store,graphStore:e.graphStore}),a}function Z(e,t,n,r,i,o){a(e),l(e),Te(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),ge(e,t.store),Oe(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n),xe(e,t.indexer,n,t.curated,t.store,i),Se(e,t.curated,t.policyStore,t.evolutionCollector,i),ke(e,t.curated,i),pe(e,t.curated,i),be(e,t.curated),he(e,t.curated),g(e,t.store,t.embedder),f(e,t.store,t.embedder),_(e,t.store,t.embedder),h(e,t.store,t.embedder),m(e,t.store,t.embedder),p(e,t.store,t.embedder),v(e,t.store,t.embedder,t.graphStore),ye(e,n),_e(e,t.store,t.embedder,n),me(e,t.graphStore),y(e,t.store,t.embedder);let c=n.sources[0]?.path??process.cwd();w(e,t.embedder,t.fileCache,c),ie(e,t.embedder,t.store),re(e,t.embedder,t.store),D(e),G(e),T(e),ce(e,t.embedder,t.store),ae(e,t.embedder,t.store,t.graphStore),E(e),O(e),W(e),z(e),R(e),B(e),I(e),we(e),ne(e,t.fileCache,c),V(e),L(e),oe(e,t.embedder,t.store),N(e),P(e),te(e,t.embedder,t.store),le(e,o),M(e),H(e),U(e),F(e),j(e),k(e),ue(e,t.embedder),A(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),K(e,r),r&&b(e,r),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(e),t.bridge&&(ee(e,t.bridge,t.evolutionCollector),S(e,t.bridge),C(e,t.bridge)),t.policyStore&&ve(e,t.policyStore),t.evolutionCollector&&se(e,t.evolutionCollector),s(e,t.store,t.curated),Ce(e)}async function tt(e){let t=await X(e),n=et(t,e);Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Y.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Y.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,q(e))}try{let e=await t.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Y.error(`Curated re-index failed`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(e))}},i=async()=>{Y.info(`Shutting down`),await t.embedder.shutdown().catch(()=>{}),await t.graphStore.close().catch(()=>{}),await t.store.close(),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i);let a=process.ppid,o=setInterval(()=>{try{process.kill(a,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const nt=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.forge_classify.git_context.graph.guide.health.http.lane.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.snippet.stash.status.stratum_card.test_run.time.update.forget.list.watch.web_fetch.web_search.workset`.split(`.`)),rt=5e3,Q=new Set(`brainstorm.changelog.check.checkpoint.codemod.data_transform.delegate.diff_parse.encode.env.eval.evidence_map.forge_classify.git_context.guide.present.health.http.lane.measure.parse_output.process.produce_knowledge.queue.regex_test.rename.replay.restore.schema_validate.snippet.stash.status.test_run.time.watch.web_fetch.web_search.workset`.split(`.`));function it(e){T(e),E(e),O(e),D(e),le(e),z(e),R(e),B(e),I(e),L(e),G(e),W(e),V(e),we(e),H(e),U(e),M(e),N(e),P(e),F(e),j(e),k(e),A(e),K(e),b(e,n),ye(e),Ce(e),De(e),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(e)}const $=`analyze_dependencies.analyze_diagram.analyze_entry_points.analyze_patterns.analyze_structure.analyze_symbols.audit.batch.blast_radius.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.dead_symbols.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.forge_classify.forge_ground.forget.git_context.graph.guide.health.http.lane.list.lookup.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.search.snippet.stash.status.stratum_card.symbol.test_run.time.trace.update.watch.web_fetch.web_search.workset`.split(`.`);function at(e){let n=new J({name:e.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}}),a=`initializing`,s=``,l=!1,f=()=>a===`failed`?[`❌ KB initialization failed — this tool is unavailable.`,``,s?`Error: ${s}`:``,``,`**35 tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
|
|
1
|
+
import{CuratedKnowledgeManager as e}from"./curated-manager.js";import{createElicitor as t,noopElicitor as n}from"./elicitor.js";import{bridgeMcpLogging as r}from"./mcp-logging.js";import{registerPrompts as i}from"./prompts.js";import{installReplayInterceptor as a}from"./replay-interceptor.js";import{ResourceNotifier as o}from"./resources/resource-notifier.js";import{registerResources as s}from"./resources/resources.js";import{createSamplingClient as c}from"./sampling.js";import{installStructuredContentGuard as l}from"./structured-content-guard.js";import{getToolMeta as u}from"./tool-metadata.js";import{installToolPrefix as d}from"./tool-prefix.js";import{registerAnalyzeDependenciesTool as f,registerAnalyzeDiagramTool as p,registerAnalyzeEntryPointsTool as m,registerAnalyzePatternsTool as h,registerAnalyzeStructureTool as g,registerAnalyzeSymbolsTool as _,registerBlastRadiusTool as v}from"./tools/analyze.tools.js";import{registerAuditTool as y}from"./tools/audit.tool.js";import{registerBrainstormTool as b}from"./tools/brainstorm.tool.js";import{initBridgeComponents as x,registerErPullTool as S,registerErPushTool as ee,registerErSyncStatusTool as C}from"./tools/bridge.tools.js";import{registerCompactTool as w,registerDeadSymbolsTool as te,registerFileSummaryTool as ne,registerFindTool as re,registerScopeMapTool as ie,registerSymbolTool as ae,registerTraceTool as oe}from"./tools/context.tools.js";import{registerErEvolveReviewTool as se}from"./tools/evolution.tools.js";import{registerBatchTool as ce,registerCheckTool as T,registerDelegateTool as le,registerEvalTool as E,registerParseOutputTool as D,registerTestRunTool as O}from"./tools/execution.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as k,registerForgeClassifyTool as A,registerForgeGroundTool as de,registerStratumCardTool as fe}from"./tools/forge.tools.js";import{registerForgetTool as pe}from"./tools/forget.tool.js";import{registerGraphTool as me}from"./tools/graph.tool.js";import{registerGuideTool as j,registerHealthTool as M,registerProcessTool as N,registerWatchTool as P,registerWebFetchTool as F}from"./tools/infra.tools.js";import{registerListTool as he}from"./tools/list.tool.js";import{registerLookupTool as ge}from"./tools/lookup.tool.js";import{registerCodemodTool as I,registerDataTransformTool as L,registerDiffParseTool as R,registerGitContextTool as z,registerRenameTool as B}from"./tools/manipulation.tools.js";import{registerOnboardTool as _e}from"./tools/onboard.tool.js";import{registerCheckpointTool as V,registerLaneTool as H,registerQueueTool as U,registerStashTool as W,registerWorksetTool as G}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as ve}from"./tools/policy.tools.js";import{registerPresentTool as K}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as ye}from"./tools/produce.tool.js";import{registerReadTool as be}from"./tools/read.tool.js";import{registerReindexTool as xe}from"./tools/reindex.tool.js";import{registerRememberTool as Se}from"./tools/remember.tool.js";import{registerReplayTool as Ce}from"./tools/replay.tool.js";import{registerRestoreTool as we}from"./tools/restore.tool.js";import{registerSearchTool as Te}from"./tools/search.tool.js";import{getCurrentVersion as Ee}from"./version-check.js";import{registerEarlyStatusTool as De,registerStatusTool as Oe}from"./tools/status.tool.js";import{registerUpdateTool as ke}from"./tools/update.tool.js";import{registerChangelogTool as Ae,registerEncodeTool as je,registerEnvTool as Me,registerHttpTool as Ne,registerMeasureTool as Pe,registerRegexTestTool as Fe,registerSchemaValidateTool as Ie,registerSnippetTool as Le,registerTimeTool as Re,registerWebSearchTool as ze}from"./tools/utility.tools.js";import{existsSync as Be,statSync as Ve}from"node:fs";import{resolve as He}from"node:path";import{KB_PATHS as Ue,createLogger as We,serializeError as q}from"../../core/dist/index.js";import{initializeWasm as Ge}from"../../chunker/dist/index.js";import{OnnxEmbedder as Ke}from"../../embeddings/dist/index.js";import{EvolutionCollector as qe,PolicyStore as Je}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as Ye,IncrementalIndexer as Xe}from"../../indexer/dist/index.js";import{SqliteGraphStore as Ze,createStore as Qe}from"../../store/dist/index.js";import{FileCache as $e}from"../../tools/dist/index.js";import{McpServer as J}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=We(`server`);async function X(t){Y.info(`Initializing knowledge base components`);let[n,r,i,a]=await Promise.all([(async()=>{let e=new Ke({model:t.embedding.model,dimensions:t.embedding.dimensions});return await e.initialize(),Y.info(`Embedder loaded`,{modelId:e.modelId,dimensions:e.dimensions}),e})(),(async()=>{let e=await Qe({backend:t.store.backend,path:t.store.path});return await e.initialize(),Y.info(`Store initialized`),e})(),(async()=>{let e=new Ze({path:t.store.path});return await e.initialize(),Y.info(`Graph store initialized`),e})(),(async()=>{let e=await Ge();return e?Y.info(`WASM tree-sitter enabled for AST analysis`):Y.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),o=new Xe(n,r),s=new Ye(t.store.path);s.load(),o.setHashCache(s);let c=t.curated.path,l=new e(c,r,n);o.setGraphStore(i);let u=x(t.er),d=u?new Je(t.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new qe:void 0,p=He(t.sources[0]?.path??process.cwd(),Ue.aiKb),m=Be(p),h=t.onboardDir?Be(t.onboardDir):!1,g=m||h,_,v=m?p:t.onboardDir;if(g&&v)try{_=Ve(v).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:n,store:r,indexer:o,curated:l,graphStore:i,fileCache:new $e,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function et(e,n){let a=new J({name:n.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}});return r(a),d(a,n.toolPrefix??``),Z(a,e,n,t(a),new o(a),c(a)),i(a,{curated:e.curated,store:e.store,graphStore:e.graphStore}),a}function Z(e,t,n,r,i,o){a(e),l(e),Te(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),ge(e,t.store),Oe(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n),xe(e,t.indexer,n,t.curated,t.store,i),Se(e,t.curated,t.policyStore,t.evolutionCollector,i),ke(e,t.curated,i),pe(e,t.curated,i),be(e,t.curated),he(e,t.curated),g(e,t.store,t.embedder),f(e,t.store,t.embedder),_(e,t.store,t.embedder),h(e,t.store,t.embedder),m(e,t.store,t.embedder),p(e,t.store,t.embedder),v(e,t.store,t.embedder,t.graphStore),ye(e,n),_e(e,t.store,t.embedder,n),me(e,t.graphStore),y(e,t.store,t.embedder);let c=n.sources[0]?.path??process.cwd();w(e,t.embedder,t.fileCache,c),ie(e,t.embedder,t.store),re(e,t.embedder,t.store),D(e),G(e),T(e),ce(e,t.embedder,t.store),ae(e,t.embedder,t.store,t.graphStore),E(e),O(e),W(e),z(e),R(e),B(e),I(e),we(e),ne(e,t.fileCache,c),V(e),L(e),oe(e,t.embedder,t.store),N(e),P(e),te(e,t.embedder,t.store),le(e,o),M(e),H(e),U(e),F(e),j(e),k(e),ue(e,t.embedder),A(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),K(e,r),r&&b(e,r),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(e),t.bridge&&(ee(e,t.bridge,t.evolutionCollector),S(e,t.bridge),C(e,t.bridge)),t.policyStore&&ve(e,t.policyStore),t.evolutionCollector&&se(e,t.evolutionCollector),s(e,t.store,t.curated),Ce(e)}async function tt(e){let t=await X(e),n=et(t,e);Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Y.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Y.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,q(e))}try{let e=await t.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Y.error(`Curated re-index failed`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(e))}},i=async()=>{Y.info(`Shutting down`),await t.embedder.shutdown().catch(()=>{}),await t.graphStore.close().catch(()=>{}),await t.store.close(),process.exit(0)};process.on(`SIGINT`,i),process.on(`SIGTERM`,i);let a=process.ppid,o=setInterval(()=>{try{process.kill(a,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const nt=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.forge_classify.git_context.graph.guide.health.http.lane.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.snippet.stash.status.stratum_card.test_run.time.update.forget.list.watch.web_fetch.web_search.workset`.split(`.`)),rt=5e3,Q=new Set(`brainstorm.changelog.check.checkpoint.codemod.data_transform.delegate.diff_parse.encode.env.eval.evidence_map.forge_classify.git_context.guide.present.health.http.lane.measure.parse_output.process.produce_knowledge.queue.regex_test.rename.replay.restore.schema_validate.snippet.stash.status.test_run.time.watch.web_fetch.web_search.workset`.split(`.`));function it(e){T(e),E(e),O(e),D(e),le(e),z(e),R(e),B(e),I(e),L(e),G(e),W(e),V(e),we(e),H(e),U(e),M(e),N(e),P(e),F(e),j(e),k(e),A(e),K(e),b(e,n),ye(e),Ce(e),De(e),ze(e),Ne(e),Fe(e),je(e),Pe(e),Ae(e),Ie(e),Le(e),Me(e),Re(e)}const $=`analyze_dependencies.analyze_diagram.analyze_entry_points.analyze_patterns.analyze_structure.analyze_symbols.audit.batch.blast_radius.brainstorm.changelog.check.checkpoint.codemod.compact.data_transform.dead_symbols.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.forge_classify.forge_ground.forget.git_context.graph.guide.health.http.lane.list.lookup.measure.onboard.parse_output.present.process.produce_knowledge.queue.read.regex_test.reindex.remember.rename.replay.restore.schema_validate.scope_map.search.snippet.stash.status.stratum_card.symbol.test_run.time.trace.update.watch.web_fetch.web_search.workset`.split(`.`);function at(e){let n=new J({name:e.serverName??`knowledge-base`,version:Ee()},{capabilities:{logging:{}}}),a=`initializing`,s=``,l=!1,f=()=>a===`failed`?[`❌ KB initialization failed — this tool is unavailable.`,``,s?`Error: ${s}`:``,``,`**35 tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
|
|
2
2
|
`):[`KB is still initializing (loading embeddings model & store).`,``,`**35 tools are already available** while initialization completes — including:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`This tool requires the knowledge base index. Please retry in a few seconds,`,`or use one of the available tools above in the meantime.`].join(`
|
|
3
3
|
`);r(n),d(n,e.toolPrefix??``);let p=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let m=[];for(let e of $){let t=u(e),r=n.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:f()}]}));Q.has(e)?r.remove():m.push(r)}it(n),n.sendToolListChanged=p;let h=n.resource(`kb-status`,`kb://status`,{description:`Knowledge base status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`kb://status`,text:`KB is initializing...`,mimeType:`text/plain`}]})),g=n.prompt(`_init`,`KB is initializing prompts...`,async()=>({messages:[{role:`user`,content:{type:`text`,text:f()}}]})),_,v=new Promise(e=>{_=e}),y,b=new Promise(e=>{y=e}),x=()=>y?.(),S=(async()=>{await b;let r;try{r=await X(e)}catch(e){a=`failed`,s=e instanceof Error?e.message:String(e),Y.error(`KB initialization failed — server continuing with zero-dep tools only`,{error:s});return}let u=n.sendToolListChanged.bind(n);n.sendToolListChanged=()=>{};let d=n.sendPromptListChanged.bind(n);n.sendPromptListChanged=()=>{};let f=n.sendResourceListChanged.bind(n);n.sendResourceListChanged=()=>{};for(let e of m)e.remove();h.remove(),g.remove();let p=n._registeredTools??{};for(let e of Q)p[e]?.remove();let v=new o(n),y=c(n);Z(n,r,e,t(n),v,y),i(n),n.sendToolListChanged=u,n.sendPromptListChanged=d,n.sendResourceListChanged=f,Promise.resolve(n.sendToolListChanged()).catch(()=>{}),Promise.resolve(n.sendPromptListChanged()).catch(()=>{}),Promise.resolve(n.sendResourceListChanged()).catch(()=>{});let x=n._registeredTools??{};for(let[e,t]of Object.entries(x)){if(nt.has(e))continue;let n=t.handler;t.handler=async(...t)=>{if(!r.indexer.isIndexing)return n(...t);let i=l?`re-indexing`:`running initial index`,a=new Promise(t=>setTimeout(()=>t({content:[{type:`text`,text:`⏳ KB is ${i}. The tool "${e}" timed out waiting for index data (${rt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),rt));return Promise.race([n(...t),a])}}let S=Object.keys(x).length;S!==$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:S}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4}),_?.(r)})(),ee=async()=>{let t=await v;try{let n=e.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:n});let r=await t.indexer.index(e,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Y.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Y.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});l=!0,Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,q(e))}try{let e=await t.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Y.error(`Curated re-index failed`,q(e))}}catch(e){Y.error(`Initial index failed; will retry on kb_reindex`,q(e))}},C=process.ppid,w=setInterval(()=>{try{process.kill(C,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:C}),clearInterval(w),v.then(async e=>{await e.embedder.shutdown().catch(()=>{}),await e.graphStore.close().catch(()=>{}),await e.store.close().catch(()=>{})}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return w.unref(),{server:n,startInit:x,ready:S,runInitialIndex:ee}}export{$ as ALL_TOOL_NAMES,at as createLazyServer,et as createMcpServer,tt as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{createHash as n}from"node:crypto";import{z as r}from"zod";import{createLogger as i,serializeError as a}from"../../../core/dist/index.js";import{onboard as o}from"../../../tools/dist/index.js";const s=i(`tools`);let c=!1;async function l(e,t,r){for(let i of r.steps)if(!(i.status!==`success`||!i.output))try{let a=n(`sha256`).update(r.path).digest(`hex`).slice(0,12),o=`produced/onboard/${i.name}/${a}.md`,s=n(`sha256`).update(i.output).digest(`hex`).slice(0,16),c=new Date().toISOString(),l=i.output.length>2e3?i.output.split(/(?=^## )/m).filter(e=>e.trim().length>0):[i.output],u=l.map((e,t)=>({id:n(`sha256`).update(`${o}::${t}`).digest(`hex`).slice(0,16),content:e.trim(),sourcePath:o,contentType:`produced-knowledge`,chunkIndex:t,totalChunks:l.length,startLine:0,endLine:0,fileHash:s,indexedAt:c,origin:`produced`,tags:[`onboard`,i.name],category:`analysis`,version:1})),d=await t.embedBatch(u.map(e=>e.content));await e.upsert(u,d)}catch(e){s.warn(`Auto-persist onboard step failed`,{stepName:i.name,...a(e)})}}function u(n,i,
|
|
2
|
-
`)}]}}catch(e){return s.error(`Onboard failed`,a(e)),{content:[{type:`text`,text:`Onboard failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}finally{c=!1}})}export{
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{createHash as n}from"node:crypto";import{z as r}from"zod";import{createLogger as i,serializeError as a}from"../../../core/dist/index.js";import{onboard as o}from"../../../tools/dist/index.js";const s=i(`tools`);let c=!1;async function l(e,t,r){for(let i of r.steps)if(!(i.status!==`success`||!i.output))try{let a=n(`sha256`).update(r.path).digest(`hex`).slice(0,12),o=`produced/onboard/${i.name}/${a}.md`,s=n(`sha256`).update(i.output).digest(`hex`).slice(0,16),c=new Date().toISOString(),l=i.output.length>2e3?i.output.split(/(?=^## )/m).filter(e=>e.trim().length>0):[i.output],u=l.map((e,t)=>({id:n(`sha256`).update(`${o}::${t}`).digest(`hex`).slice(0,16),content:e.trim(),sourcePath:o,contentType:`produced-knowledge`,chunkIndex:t,totalChunks:l.length,startLine:0,endLine:0,fileHash:s,indexedAt:c,origin:`produced`,tags:[`onboard`,i.name],category:`analysis`,version:1})),d=await t.embedBatch(u.map(e=>e.content));await e.upsert(u,d)}catch(e){s.warn(`Auto-persist onboard step failed`,{stepName:i.name,...a(e)})}}async function u(e,t,r){if(r.autoRemember?.length)for(let i of r.autoRemember)try{let r=n(`sha256`).update(`onboard-remember::${i.title}`).digest(`hex`).slice(0,16),a=new Date().toISOString(),o={id:r,content:`# ${i.title}\n\n${i.content}`,sourcePath:`curated/onboard/${i.category}/${r}.md`,contentType:`curated`,chunkIndex:0,totalChunks:1,startLine:0,endLine:0,fileHash:n(`sha256`).update(i.content).digest(`hex`).slice(0,16),indexedAt:a,origin:`curated`,tags:i.tags,category:i.category,version:1},[s]=await t.embedBatch([o.content]);await e.upsert([o],[s])}catch(e){s.warn(`Auto-persist remember entry failed`,{title:i.title,...a(e)})}}function d(n,i,d,f){let p=e(`onboard`);n.registerTool(`onboard`,{title:p.title,description:`First-time codebase onboarding: runs all analysis tools (structure, dependencies, entry-points, symbols, patterns, diagram) in one command. Results are auto-persisted to KB. Use mode=generate to also write structured output to .ai/kb/ directory.`,inputSchema:{path:r.string().describe(`Root path of the codebase to onboard`),mode:r.enum([`memory`,`generate`]).default(`generate`).describe(`Output mode: generate (default) = persist to KB + write .ai/kb/ files; memory = KB vector store only`),out_dir:r.string().optional().describe(`Custom output directory for generate mode (default: <path>/.ai/kb)`)},annotations:p.annotations},async({path:e,mode:n,out_dir:r},p)=>{try{if(c)return{content:[{type:`text`,text:`Onboard is already running. Please wait for it to complete before starting another.`}]};c=!0,s.info(`Starting onboard`,{path:e,mode:n});let m=await o({path:e,mode:n,outDir:r??f?.onboardDir}),h=t(p).createTask(`Onboard`,m.steps.length);for(let e=0;e<m.steps.length;e++){let t=m.steps[e];h.progress(e,`${t.name}: ${t.status}`)}h.complete(`Onboard complete: ${m.steps.filter(e=>e.status===`success`).length}/${m.steps.length} steps succeeded`),l(i,d,m),m.autoRemember?.length&&u(i,d,m).catch(e=>{s.warn(`Auto-persist autoRemember failed`,a(e))});let g=[`## Onboard Complete`,``,`**Path:** \`${m.path}\``,`**Mode:** ${m.mode}`,`**Duration:** ${m.totalDurationMs}ms`,``];m.outDir&&(g.push(`**Output directory:** \`${m.outDir}\``),g.push(``)),g.push(`### Analysis Results`,``);let _=[],v=[];for(let e of m.steps)e.status===`success`?_.push(`- ✓ **${e.name}** (${e.durationMs}ms) — ${e.output.length} chars`):v.push(`- ✗ **${e.name}** — ${e.error}`);g.push(..._),v.length>0&&g.push(``,`### Failed`,``,...v),g.push(``,`---`,``);for(let e of m.steps)e.status===`success`&&g.push(`### ${e.name}`,``,e.output,``,`---`,``);return g.push(`_All results auto-saved to KB.`,m.mode===`generate`?` Files written to \`${m.outDir}\`.`:``," Next: Use `search` to query the knowledge, or `remember` to add custom insights._"),{content:[{type:`text`,text:g.join(`
|
|
2
|
+
`)}]}}catch(e){return s.error(`Onboard failed`,a(e)),{content:[{type:`text`,text:`Onboard failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}finally{c=!1}})}export{d as registerOnboardTool};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import{FONT_LINK as e,getDesignSystemCSS as t}from"../present-theme.js";import{escHtml as n}from"../present-utils.js";import{contentToHtml as r}from"./html.js";import{buildTemplateHtml as i}from"./templates.js";function a(a,o,s,c){let l=c&&c!==`auto`?i(c,o):r(a,o);return`<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
6
|
+
<title>${n(a??`KB Dashboard`)}</title>
|
|
7
|
+
${e}
|
|
8
|
+
<style>${t()}</style>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div class="dashboard">
|
|
12
|
+
<div class="header">
|
|
13
|
+
<h1>${n(a??`KB Dashboard`)}</h1>
|
|
14
|
+
<div class="subtitle">Knowledge Base</div>
|
|
15
|
+
</div>
|
|
16
|
+
${l}
|
|
17
|
+
${(()=>{let e=Array.isArray(s)?s:[];return e.length===0?``:`
|
|
18
|
+
<div class="actions-bar">
|
|
19
|
+
<h2>Actions</h2>
|
|
20
|
+
<div class="actions-grid">${e.map(e=>{let t=String(e.id??``);if(e.type===`select`&&Array.isArray(e.options)){let r=e.options.map(e=>{let t=typeof e==`string`?e:e.label;return`<option value="${n(typeof e==`string`?e:e.value)}">${n(t)}</option>`}).join(``);return`<div class="action-group"><label>${n(String(e.label??``))}</label><select data-action-id="${n(t)}" onchange="sendCallback(${n(JSON.stringify(t))},this.value)">${r}</select></div>`}return`<button class="action-btn action-${String(e.variant??`default`)}" onclick="sendCallback(${n(JSON.stringify(t))},'clicked')">${n(String(e.label??``))}</button>`}).join(`
|
|
21
|
+
`)}</div>
|
|
22
|
+
<div id="action-feedback" class="action-feedback"></div>
|
|
23
|
+
</div>
|
|
24
|
+
<script>
|
|
25
|
+
let _cbSent=false;
|
|
26
|
+
function sendCallback(actionId,value){
|
|
27
|
+
if(_cbSent)return;
|
|
28
|
+
_cbSent=true;
|
|
29
|
+
document.querySelectorAll('.action-btn,.action-group select').forEach(el=>{el.disabled=true;el.style.opacity='0.5'});
|
|
30
|
+
const fb=document.getElementById('action-feedback');
|
|
31
|
+
fb.textContent='⏳ Sending selection: '+actionId+' = '+value;
|
|
32
|
+
fb.className='action-feedback sent';
|
|
33
|
+
fetch('/callback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({actionId,value})})
|
|
34
|
+
.then(()=>{
|
|
35
|
+
fb.textContent='✓ Selection sent: '+actionId+' = '+value;
|
|
36
|
+
})
|
|
37
|
+
.catch(e=>{
|
|
38
|
+
fb.textContent='✗ Callback failed — '+e.message;
|
|
39
|
+
fb.style.color='var(--error)';
|
|
40
|
+
_cbSent=false;
|
|
41
|
+
document.querySelectorAll('.action-btn,.action-group select').forEach(el=>{el.disabled=false;el.style.opacity='1'});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
<\/script>`})()}
|
|
45
|
+
<div class="footer">KB MCP Server · Generated ${new Date().toLocaleString()}</div>
|
|
46
|
+
</div>
|
|
47
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>
|
|
48
|
+
<script>
|
|
49
|
+
if(document.querySelector('.mermaid'))mermaid.initialize({theme:'dark',startOnLoad:true});
|
|
50
|
+
|
|
51
|
+
document.querySelectorAll('table').forEach(table=>{
|
|
52
|
+
const headers=table.querySelectorAll('th');
|
|
53
|
+
headers.forEach((th,i)=>{
|
|
54
|
+
let asc=true;
|
|
55
|
+
th.addEventListener('click',()=>{
|
|
56
|
+
const tbody=table.querySelector('tbody')||table;
|
|
57
|
+
const rows=[...tbody.querySelectorAll('tr')].filter(r=>r.querySelector('td'));
|
|
58
|
+
rows.sort((a,b)=>{
|
|
59
|
+
const at=(a.cells[i]?.textContent||'').trim();
|
|
60
|
+
const bt=(b.cells[i]?.textContent||'').trim();
|
|
61
|
+
return asc?at.localeCompare(bt,undefined,{numeric:true}):bt.localeCompare(at,undefined,{numeric:true});
|
|
62
|
+
});
|
|
63
|
+
rows.forEach(r=>tbody.appendChild(r));
|
|
64
|
+
asc=!asc;
|
|
65
|
+
headers.forEach(h=>h.style.color='');
|
|
66
|
+
th.style.color='var(--primary)';
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
document.querySelectorAll('.table-wrap').forEach(wrap=>{
|
|
72
|
+
const table=wrap.querySelector('table');
|
|
73
|
+
if(!table||table.querySelectorAll('tr').length<5)return;
|
|
74
|
+
const bar=document.createElement('div');
|
|
75
|
+
bar.className='search-bar';
|
|
76
|
+
const input=document.createElement('input');
|
|
77
|
+
input.placeholder='Filter rows...';
|
|
78
|
+
const count=document.createElement('span');
|
|
79
|
+
count.className='count';
|
|
80
|
+
bar.appendChild(input);bar.appendChild(count);
|
|
81
|
+
wrap.parentNode.insertBefore(bar,wrap);
|
|
82
|
+
const rows=[...table.querySelectorAll('tbody tr, tr')].filter(r=>r.querySelector('td'));
|
|
83
|
+
const updateCount=()=>{const v=rows.filter(r=>r.style.display!=='none').length;count.textContent=v+'/'+rows.length};
|
|
84
|
+
updateCount();
|
|
85
|
+
input.addEventListener('input',()=>{
|
|
86
|
+
const q=input.value.toLowerCase();
|
|
87
|
+
rows.forEach(r=>{r.style.display=r.textContent.toLowerCase().includes(q)?'':'none'});
|
|
88
|
+
updateCount();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
<\/script>
|
|
92
|
+
</body>
|
|
93
|
+
</html>`}export{a as buildBrowserHtml};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region packages/server/src/tools/present/helpers.d.ts
|
|
2
|
+
interface TypedBlock {
|
|
3
|
+
type: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
value?: unknown;
|
|
6
|
+
language?: string;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
declare function formatValue(value: unknown): string;
|
|
10
|
+
declare function sanitizeId(value: string): string;
|
|
11
|
+
declare function isTypedBlock(value: unknown): value is TypedBlock;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { TypedBlock, formatValue, isTypedBlock, sanitizeId };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(t){return t==null?`null`:Array.isArray(t)?`[${t.map(e).join(`, `)}]`:String(t)}function t(e){return e.replace(/[^a-zA-Z0-9_]/g,`_`)}function n(e){return typeof e==`object`&&!!e&&`type`in e&&`value`in e}export{e as formatValue,n as isTypedBlock,t as sanitizeId};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TypedBlock } from "./helpers.js";
|
|
2
|
+
|
|
3
|
+
//#region packages/server/src/tools/present/html.d.ts
|
|
4
|
+
declare function contentToHtml(title: string | undefined, content: unknown): string;
|
|
5
|
+
declare function renderBlockAsHtml(block: TypedBlock): string;
|
|
6
|
+
declare function arrayToHtmlTable(rows: Record<string, unknown>[]): string;
|
|
7
|
+
declare function metricsToHtml(metrics: Array<{
|
|
8
|
+
label: string;
|
|
9
|
+
value: string | number;
|
|
10
|
+
}>): string;
|
|
11
|
+
declare function cardsToHtml(cards: Record<string, unknown>[]): string;
|
|
12
|
+
declare function objectToHtmlTree(obj: Record<string, unknown>): string;
|
|
13
|
+
declare function graphToMermaidRaw(data: {
|
|
14
|
+
nodes: unknown[];
|
|
15
|
+
edges: unknown[];
|
|
16
|
+
}): string;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { arrayToHtmlTable, cardsToHtml, contentToHtml, graphToMermaidRaw, metricsToHtml, objectToHtmlTree, renderBlockAsHtml };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{escHtml as e}from"../present-utils.js";import{renderChecklistHtml as t,renderComparisonHtml as n,renderProgressHtml as r,renderPromptHtml as i,renderStatusBoardHtml as a,renderTimelineHtml as o}from"../present-blocks.js";import{renderChartAsHtml as s}from"../present-charts.js";import{formatValue as c,isTypedBlock as l,sanitizeId as u}from"./helpers.js";import{marked as d}from"marked";d.setOptions({async:!1,gfm:!0,breaks:!0}),d.use({renderer:{html(t){return e(t.text)}}});function f(t,n){let r=[];if(t&&r.push(`<h1>${e(t)}</h1>`),typeof n==`string`)r.push(`<div class="md-content">${d.parse(n)}</div>`);else if(Array.isArray(n))if(n.length===0)r.push(`<p><em>empty</em></p>`);else if(l(n[0]))for(let e of n)r.push(p(e));else typeof n[0]==`object`&&n[0]!==null?r.push(m(n)):r.push(`<ul>${n.map(t=>`<li>${e(String(t))}</li>`).join(``)}</ul>`);else if(typeof n==`object`&&n){let t=n;Array.isArray(t.metrics)?r.push(h(t.metrics)):Array.isArray(t.nodes)&&Array.isArray(t.edges)?(r.push(`<pre class="mermaid">${e(v(t))}</pre>`),r.push(`<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>`),r.push(`<script>mermaid.run();<\/script>`)):r.push(_(t))}else r.push(`<p>${e(String(n))}</p>`);return r.join(`
|
|
2
|
+
`)}function p(c){let l=[];switch(c.title&&l.push(`<h2>${e(c.title)}</h2>`),c.type){case`markdown`:l.push(`<div class="md-content">${d.parse(String(c.value??``))}</div>`);break;case`code`:l.push(`<pre><code>${e(String(c.value??``))}</code></pre>`);break;case`mermaid`:l.push(`<pre class="mermaid">${e(String(c.value??``))}</pre>`);break;case`table`:if(Array.isArray(c.value)){let e=c.value;if(e.length>0&&Array.isArray(e[0])){let t=e,n=t[0].map(String),r=t.slice(1).map(e=>Object.fromEntries(n.map((t,n)=>[t,e[n]])));l.push(m(r))}else l.push(m(e))}break;case`metrics`:{let e;Array.isArray(c.value)?e=c.value:c.value&&typeof c.value==`object`&&(e=Object.entries(c.value).map(([e,t])=>({label:e,value:String(t)}))),e&&l.push(h(e));break}case`cards`:Array.isArray(c.value)&&l.push(g(c.value));break;case`tree`:c.value&&typeof c.value==`object`&&l.push(_(c.value));break;case`graph`:c.value&&typeof c.value==`object`&&l.push(`<pre class="mermaid">${e(v(c.value))}</pre>`);break;case`chart`:{let e=c.value;if(e&&!e.chartType&&e.type&&Array.isArray(e.labels)&&Array.isArray(e.datasets)){let t=e.labels,n=e.datasets,r=n.map((e,t)=>e.label??`series${t+1}`),i=t.map((e,t)=>{let i={_label:e};return n.forEach((e,n)=>{i[r[n]]=e.data[t]??0}),i}),a={type:`chart`,title:c.title,value:{chartType:String(e.type),data:i,xKey:`_label`,yKeys:r}};l.push(s(a))}else l.push(s(c));break}case`timeline`:{let e=c.value;Array.isArray(e)&&(e={items:e.map(e=>({title:String(e.event??e.title??``),phase:e.date==null?e.phase==null?void 0:String(e.phase):String(e.date),description:e.description==null?void 0:String(e.description),status:e.status??`done`}))}),e&&l.push(o(e));break}case`checklist`:c.value&&l.push(t(c.value));break;case`comparison`:c.value&&l.push(n(c.value));break;case`status-board`:c.value&&l.push(a(c.value));break;case`prompt`:c.value&&l.push(i(c.value));break;case`progress`:c.value&&l.push(r(c.value));break;case`text`:l.push(`<div class="md-content">${d.parse(String(c.value??``))}</div>`);break;case`heading`:l.push(`<h2>${e(String(c.value??``))}</h2>`);break;case`separator`:l.push(`<hr class="separator">`);break;default:l.push(`<pre>${e(JSON.stringify(c.value,null,2))}</pre>`)}return l.join(`
|
|
3
|
+
`)}function m(t){if(t.length===0)return`<p><em>empty table</em></p>`;let n=Object.keys(t[0]);return`<div class="table-wrap"><table><thead><tr>${n.map(t=>`<th>${e(t)}</th>`).join(``)}</tr></thead><tbody>${t.map(t=>`<tr>${n.map(n=>`<td>${e(String(t[n]??``))}</td>`).join(``)}</tr>`).join(`
|
|
4
|
+
`)}</tbody></table></div>`}function h(t){return`<div class="metric-grid">${t.map(t=>`<div class="metric"><div class="metric-value">${e(String(t.value))}</div><div class="metric-label">${e(t.label)}</div></div>`).join(``)}</div>`}function g(t){return`<div class="card-grid">${t.map(t=>{let n=[`<div class="card">`];return t.title&&n.push(`<div class="card-title">${e(String(t.title))}</div>`),(t.body||t.description)&&n.push(`<div class="card-body">${e(String(t.body??t.description))}</div>`),(t.badge||t.status)&&n.push(`<span class="badge">${e(String(t.badge??t.status))}</span>`),n.push(`</div>`),n.join(``)}).join(``)}</div>`}function _(t){let n=[];for(let[r,i]of Object.entries(t))typeof i==`object`&&i&&!Array.isArray(i)?n.push(`<div class="tree-node"><span class="tree-key">${e(r)}:</span><div class="tree-children">${_(i)}</div></div>`):n.push(`<div class="tree-node"><span class="tree-key">${e(r)}:</span> ${e(c(i))}</div>`);return n.join(``)}function v(e){let t=[`graph LR`];for(let n of e.nodes){let e=u(String(n.id??n.name??``)),r=String(n.label??n.name??e);t.push(` ${e}["${r}"]`)}for(let n of e.edges){let e=u(String(n.source??n.from??``)),r=u(String(n.target??n.to??``)),i=n.label?`|${String(n.label)}|`:``;t.push(` ${e} -->${i} ${r}`)}return t.join(`
|
|
5
|
+
`)}export{m as arrayToHtmlTable,g as cardsToHtml,f as contentToHtml,v as graphToMermaidRaw,h as metricsToHtml,_ as objectToHtmlTree,p as renderBlockAsHtml};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerPresentTool as e}from"./tool.js";export{e as registerPresentTool};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TypedBlock } from "./helpers.js";
|
|
2
|
+
|
|
3
|
+
//#region packages/server/src/tools/present/markdown.d.ts
|
|
4
|
+
declare function buildMarkdown(title: string | undefined, content: unknown): string;
|
|
5
|
+
declare function renderBlockAsMarkdown(block: TypedBlock): string;
|
|
6
|
+
declare function arrayToMarkdownTable(rows: Record<string, unknown>[]): string;
|
|
7
|
+
declare function metricsToMarkdown(metrics: Array<{
|
|
8
|
+
label: string;
|
|
9
|
+
value: string | number;
|
|
10
|
+
}>): string;
|
|
11
|
+
declare function graphToMermaid(data: {
|
|
12
|
+
nodes: unknown[];
|
|
13
|
+
edges: unknown[];
|
|
14
|
+
}): string;
|
|
15
|
+
declare function objectToMarkdownTree(obj: Record<string, unknown>, indent?: number): string;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { arrayToMarkdownTable, buildMarkdown, graphToMermaid, metricsToMarkdown, objectToMarkdownTree, renderBlockAsMarkdown };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{formatValue as e,isTypedBlock as t,sanitizeId as n}from"./helpers.js";function r(e,n){let r=[];if(e&&r.push(`# ${e}\n`),typeof n==`string`)r.push(n);else if(Array.isArray(n))if(n.length===0)r.push(`*(empty)*`);else if(t(n[0]))for(let e of n)r.push(i(e));else if(typeof n[0]==`object`&&n[0]!==null)r.push(a(n));else for(let e of n)r.push(`- ${String(e)}`);else if(typeof n==`object`&&n){let e=n;Array.isArray(e.nodes)&&Array.isArray(e.edges)?r.push(s(e)):Array.isArray(e.metrics)?r.push(o(e.metrics)):r.push(c(e))}else r.push(String(n));return r.join(`
|
|
2
|
+
`)}function i(e){let t=[];switch(e.title&&t.push(`## ${e.title}\n`),e.type){case`markdown`:t.push(String(e.value??``));break;case`code`:t.push(`\`\`\`${e.language??``}\n${String(e.value??``)}\n\`\`\``);break;case`mermaid`:t.push(`\`\`\`mermaid\n${String(e.value??``)}\n\`\`\``);break;case`table`:Array.isArray(e.value)&&t.push(a(e.value));break;case`metrics`:Array.isArray(e.value)&&t.push(o(e.value));break;case`graph`:e.value&&typeof e.value==`object`&&t.push(s(e.value));break;case`cards`:if(Array.isArray(e.value))for(let n of e.value)t.push(`### ${n.title??`Card`}`),(n.body||n.description)&&t.push(String(n.body??n.description)),(n.badge||n.status)&&t.push(`> **${n.badge??n.status}**`),t.push(``);break;case`tree`:e.value&&typeof e.value==`object`&&t.push(c(e.value));break;case`chart`:{let n=e.value;n?.data&&Array.isArray(n.data)&&t.push(`*${String(n.chartType??`chart`)} chart — ${n.data.length} data points*`);break}case`timeline`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.status===`done`?`✅`:e.status===`active`?`🔄`:e.status===`error`?`❌`:`⬜`;t.push(`${n} **${e.title}**${e.description?` — ${e.description}`:``}`)}break}case`checklist`:{let n=e.value;if(n?.items)for(let e of n.items)t.push(`- [${e.checked?`x`:` `}] ${e.label}${e.note?` — ${e.note}`:``}`);break}case`comparison`:{let n=e.value;if(n?.columns&&n.columns.length>0){let e=Math.max(...n.columns.map(e=>e.items?.length??0)),r=n.columns.map(e=>e.title);t.push(`| ${r.join(` | `)} |`),t.push(`| ${r.map(()=>`---`).join(` | `)} |`);for(let r=0;r<e;r++)t.push(`| ${n.columns.map(e=>e.items?.[r]??``).join(` | `)} |`)}break}case`status-board`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.status===`success`?`🟢`:e.status===`warning`?`🟡`:e.status===`error`?`🔴`:e.status===`info`?`🔵`:`⚪`;t.push(`${n} **${e.label}**${e.detail?` — ${e.detail}`:``}`)}break}case`prompt`:{let n=e.value;n?.question&&(t.push(`> **${n.question}**`),n.context&&t.push(`> ${n.context}`));break}case`progress`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.max??100,r=n>0?Math.round(e.value/n*100):0,i=Math.round(r/5),a=`█`.repeat(i)+`░`.repeat(20-i);t.push(`${e.label}: ${a} ${r}%`)}break}case`text`:t.push(String(e.value??``));break;case`heading`:t.push(`## ${String(e.value??``)}\n`);break;case`separator`:t.push(`---
|
|
3
|
+
`);break;default:t.push(JSON.stringify(e.value,null,2))}return t.push(``),t.join(`
|
|
4
|
+
`)}function a(e){if(e.length===0)return`*(empty table)*`;let t=Object.keys(e[0]),n=[];n.push(`| ${t.join(` | `)} |`),n.push(`| ${t.map(()=>`---`).join(` | `)} |`);for(let r of e)n.push(`| ${t.map(e=>String(r[e]??``)).join(` | `)} |`);return n.join(`
|
|
5
|
+
`)}function o(e){return e.map(e=>`- **${e.label}**: ${e.value}`).join(`
|
|
6
|
+
`)}function s(e){let t=["```mermaid",`graph LR`];for(let r of e.nodes){let e=n(String(r.id??r.name??``)),i=String(r.label??r.name??e);t.push(` ${e}["${i}"]`)}for(let r of e.edges){let e=n(String(r.source??r.from??``)),i=n(String(r.target??r.to??``)),a=r.label?`|${String(r.label)}|`:``;t.push(` ${e} -->${a} ${i}`)}return t.push("```"),t.join(`
|
|
7
|
+
`)}function c(t,n=0){let r=` `.repeat(n),i=[];for(let[a,o]of Object.entries(t))typeof o==`object`&&o&&!Array.isArray(o)?(i.push(`${r}- **${a}**:`),i.push(c(o,n+1))):i.push(`${r}- **${a}**: ${e(o)}`);return i.join(`
|
|
8
|
+
`)}export{a as arrayToMarkdownTable,r as buildMarkdown,s as graphToMermaid,o as metricsToMarkdown,c as objectToMarkdownTree,i as renderBlockAsMarkdown};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region packages/server/src/tools/present/templates.d.ts
|
|
2
|
+
declare function buildTemplateHtml(template: string, content: unknown): string;
|
|
3
|
+
declare function buildListSortHtml(data: Record<string, unknown>): string;
|
|
4
|
+
declare function buildDataTableHtml(data: Record<string, unknown>): string;
|
|
5
|
+
declare function buildPickerHtml(data: Record<string, unknown>): string;
|
|
6
|
+
declare function buildFlameGraphHtml(data: Record<string, unknown>): string;
|
|
7
|
+
declare function buildFormHtml(data: Record<string, unknown>): string;
|
|
8
|
+
declare function buildTimelineHtml(data: Record<string, unknown>): string;
|
|
9
|
+
declare function buildKanbanHtml(data: Record<string, unknown>): string;
|
|
10
|
+
declare function buildTreeHtml(data: Record<string, unknown>): string;
|
|
11
|
+
declare function buildDiffViewHtml(data: Record<string, unknown>): string;
|
|
12
|
+
declare function buildDashboardHtml(data: Record<string, unknown>): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { buildDashboardHtml, buildDataTableHtml, buildDiffViewHtml, buildFlameGraphHtml, buildFormHtml, buildKanbanHtml, buildListSortHtml, buildPickerHtml, buildTemplateHtml, buildTimelineHtml, buildTreeHtml };
|