@vpxa/aikit 0.1.1 β 0.1.2
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 +8 -8
- package/package.json +1 -1
- package/packages/aikit-client/dist/types.d.ts +3 -3
- package/packages/cli/dist/aikit-init.d.ts +1 -1
- package/packages/cli/dist/aikit-init.js +1 -1
- package/packages/cli/dist/commands/context-cmds.js +1 -1
- package/packages/cli/dist/commands/environment.js +1 -1
- package/packages/cli/dist/commands/init/config.d.ts +1 -1
- package/packages/cli/dist/commands/init/config.js +2 -2
- package/packages/cli/dist/commands/init/constants.d.ts +3 -3
- package/packages/cli/dist/commands/init/index.d.ts +4 -4
- package/packages/cli/dist/commands/init/index.js +4 -4
- package/packages/cli/dist/commands/init/templates.js +12 -12
- package/packages/cli/dist/commands/init/user.d.ts +3 -3
- package/packages/cli/dist/commands/init/user.js +2 -2
- package/packages/cli/dist/commands/search.js +1 -1
- package/packages/cli/dist/commands/system.js +4 -4
- package/packages/cli/dist/commands/upgrade.js +1 -1
- package/packages/cli/dist/commands/workspace.js +1 -1
- package/packages/cli/dist/helpers.js +1 -1
- package/packages/cli/dist/index.d.ts +1 -1
- package/packages/core/dist/constants.d.ts +3 -3
- package/packages/core/dist/global-registry.d.ts +7 -1
- package/packages/core/dist/global-registry.js +1 -1
- package/packages/core/dist/index.d.ts +2 -2
- package/packages/core/dist/index.js +1 -1
- package/packages/core/dist/types.d.ts +4 -2
- package/packages/dashboard/dist/assets/{index-BjA4YODs.js β index-CO2S9BKY.js} +2 -2
- package/packages/dashboard/dist/assets/index-CO2S9BKY.js.map +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/enterprise-bridge/dist/er-client.d.ts +1 -1
- package/packages/indexer/dist/incremental-indexer.js +1 -1
- package/packages/kb-client/dist/__tests__/direct-client.test.d.ts +1 -0
- package/packages/kb-client/dist/__tests__/mcp-client.test.d.ts +1 -0
- package/packages/kb-client/dist/__tests__/parsers.test.d.ts +1 -0
- package/packages/kb-client/dist/direct-client.d.ts +38 -0
- package/packages/kb-client/dist/direct-client.js +1 -0
- package/packages/kb-client/dist/index.d.ts +4 -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 +32 -0
- package/packages/kb-client/dist/parsers.js +2 -0
- package/packages/kb-client/dist/types.d.ts +59 -0
- package/packages/kb-client/dist/types.js +1 -0
- package/packages/present/dist/index.html +3 -3
- package/packages/server/dist/background-task.d.ts +47 -0
- package/packages/server/dist/background-task.js +1 -0
- package/packages/server/dist/config.js +1 -1
- package/packages/server/dist/idle-timer.d.ts +29 -0
- package/packages/server/dist/idle-timer.js +1 -0
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/memory-monitor.d.ts +37 -0
- package/packages/server/dist/memory-monitor.js +1 -0
- package/packages/server/dist/prompts.js +5 -5
- package/packages/server/dist/resource-links.d.ts +1 -1
- package/packages/server/dist/resource-links.js +1 -1
- package/packages/server/dist/resources/curated-resources.d.ts +2 -2
- package/packages/server/dist/resources/curated-resources.js +2 -2
- package/packages/server/dist/resources/resource-notifier.d.ts +1 -1
- package/packages/server/dist/resources/resource-notifier.js +1 -1
- package/packages/server/dist/resources/resources.js +1 -1
- package/packages/server/dist/server.d.ts +3 -1
- package/packages/server/dist/server.js +3 -3
- package/packages/server/dist/tool-metadata.d.ts +1 -1
- package/packages/server/dist/tool-metadata.js +1 -1
- package/packages/server/dist/tool-timeout.d.ts +27 -0
- package/packages/server/dist/tool-timeout.js +1 -0
- package/packages/server/dist/tools/bridge.tools.d.ts +1 -1
- package/packages/server/dist/tools/bridge.tools.js +3 -3
- package/packages/server/dist/tools/evolution.tools.js +1 -1
- package/packages/server/dist/tools/infra.tools.js +1 -1
- package/packages/server/dist/tools/onboard.tool.js +1 -1
- package/packages/server/dist/tools/present/browser.js +4 -4
- package/packages/server/dist/tools/present/tool.js +1 -1
- package/packages/server/dist/tools/reindex.tool.js +1 -1
- package/packages/server/dist/tools/search.tool.js +1 -1
- package/packages/server/dist/tools/status.tool.d.ts +1 -1
- package/packages/server/dist/tools/status.tool.js +2 -2
- package/packages/tools/dist/checkpoint.js +1 -1
- package/packages/tools/dist/config-extractor.js +1 -1
- package/packages/tools/dist/evidence-map.js +2 -2
- package/packages/tools/dist/find.d.ts +1 -1
- package/packages/tools/dist/forge-ground.d.ts +1 -1
- package/packages/tools/dist/guide.js +1 -1
- package/packages/tools/dist/lane.js +1 -1
- package/packages/tools/dist/onboard.d.ts +2 -2
- package/packages/tools/dist/onboard.js +2 -2
- package/packages/tools/dist/queue.js +1 -1
- package/packages/tools/dist/replay.js +1 -1
- package/packages/tools/dist/response-envelope.d.ts +1 -1
- package/packages/tools/dist/snippet.js +1 -1
- package/packages/tools/dist/stash.js +1 -1
- package/packages/tools/dist/synthesis-engine.js +2 -2
- package/packages/tools/dist/workset.js +1 -1
- package/packages/tui/dist/{App-DU2KEylW.js β App-B2-KJPt4.js} +1 -1
- package/packages/tui/dist/App.d.ts +1 -1
- package/packages/tui/dist/App.js +1 -1
- package/packages/tui/dist/LogPanel-E_1Do4-j.js +3 -0
- package/packages/tui/dist/hooks/useKBClient.d.ts +1 -1
- package/packages/tui/dist/{index-BXafekwr.d.ts β index-MXJeXmCf.d.ts} +3 -3
- package/packages/tui/dist/index.d.ts +1 -1
- package/packages/tui/dist/index.js +1 -1
- package/packages/tui/dist/panels/LogPanel.js +1 -1
- package/scaffold/README.md +192 -192
- package/scaffold/definitions/bodies.mjs +16 -16
- package/scaffold/definitions/plugins.mjs +1 -1
- package/scaffold/definitions/prompts.mjs +6 -6
- package/scaffold/definitions/protocols.mjs +12 -12
- package/scaffold/definitions/tools.mjs +1 -1
- package/scaffold/flows/aikit-advanced/skills/execute/SKILL.md +124 -124
- package/scaffold/flows/aikit-advanced/skills/plan/SKILL.md +100 -100
- package/scaffold/flows/aikit-advanced/skills/spec/SKILL.md +100 -100
- package/scaffold/flows/aikit-advanced/skills/task/SKILL.md +99 -99
- package/scaffold/flows/aikit-advanced/skills/verify/SKILL.md +122 -122
- package/scaffold/flows/aikit-basic/skills/assess/SKILL.md +82 -82
- package/scaffold/flows/aikit-basic/skills/implement/SKILL.md +105 -105
- package/scaffold/flows/aikit-basic/skills/verify/SKILL.md +96 -96
- 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 +2 -2
- package/scaffold/general/agents/Frontend.agent.md +1 -1
- package/scaffold/general/agents/Implementer.agent.md +2 -2
- package/scaffold/general/agents/Orchestrator.agent.md +1 -1
- package/scaffold/general/agents/Planner.agent.md +2 -2
- package/scaffold/general/agents/Refactor.agent.md +2 -2
- package/scaffold/general/agents/Security.agent.md +2 -2
- package/scaffold/general/agents/_shared/architect-reviewer-base.md +1 -1
- package/scaffold/general/agents/_shared/code-agent-base.md +6 -6
- package/scaffold/general/agents/_shared/code-reviewer-base.md +1 -1
- package/scaffold/general/agents/_shared/forge-protocol.md +1 -1
- package/scaffold/general/agents/_shared/researcher-base.md +3 -3
- package/scaffold/general/prompts/ask.prompt.md +4 -4
- package/scaffold/general/prompts/debug.prompt.md +1 -1
- package/scaffold/general/prompts/plan.prompt.md +1 -1
- package/scaffold/general/skills/aikit/SKILL.md +5 -5
- package/scaffold/general/skills/multi-agents-development/SKILL.md +2 -2
- package/scaffold/general/skills/present/SKILL.md +1 -1
- package/packages/dashboard/dist/assets/index-BjA4YODs.js.map +0 -1
- package/packages/tui/dist/LogPanel-Bo8a8QXB.js +0 -3
|
@@ -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 C,registerErSyncStatusTool as w}from"./tools/bridge.tools.js";import{registerCompactTool as T,registerDeadSymbolsTool as ee,registerFileSummaryTool as te,registerFindTool as ne,registerScopeMapTool as re,registerSymbolTool as ie,registerTraceTool as ae}from"./tools/context.tools.js";import{registerErEvolveReviewTool as oe}from"./tools/evolution.tools.js";import{registerBatchTool as se,registerCheckTool as E,registerDelegateTool as ce,registerEvalTool as D,registerParseOutputTool as O,registerTestRunTool as k}from"./tools/execution.tools.js";import{registerFlowTools as le}from"./tools/flow.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as A,registerForgeClassifyTool as j,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 M,registerHealthTool as N,registerProcessTool as P,registerWatchTool as F,registerWebFetchTool as I}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 L,registerDataTransformTool as R,registerDiffParseTool as z,registerGitContextTool as B,registerRenameTool as V}from"./tools/manipulation.tools.js";import{registerOnboardTool as _e}from"./tools/onboard.tool.js";import{registerCheckpointTool as H,registerLaneTool as U,registerQueueTool as W,registerStashTool as G,registerWorksetTool as K}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as ve}from"./tools/policy.tools.js";import{registerPresentTool as q}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{AIKIT_PATHS as Ue,createLogger as We,serializeError as J}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 et}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 tt(e,n){let a=new et({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();T(e,t.embedder,t.fileCache,c),re(e,t.embedder,t.store),ne(e,t.embedder,t.store),O(e),K(e),E(e),se(e,t.embedder,t.store),ie(e,t.embedder,t.store,t.graphStore),D(e),k(e),G(e),B(e),z(e),V(e),L(e),we(e),te(e,t.fileCache,c),H(e),R(e),ae(e,t.embedder,t.store),P(e),F(e),ee(e,t.embedder,t.store),ce(e,o),N(e),U(e),W(e),I(e),M(e),A(e),ue(e,t.embedder),j(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),q(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),le(e,n),t.bridge&&(C(e,t.bridge,t.evolutionCollector),S(e,t.bridge),w(e,t.bridge)),t.policyStore&&ve(e,t.policyStore),t.evolutionCollector&&oe(e,t.evolutionCollector),s(e,t.store,t.curated),Ce(e)}async function nt(e){let t=await X(e),n=tt(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`,J(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`,J(e))}}catch(e){Y.error(`Initial index failed; will retry on aikit_reindex`,J(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 rt=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(`.`)),it=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 at(e){E(e),D(e),k(e),O(e),ce(e),B(e),z(e),V(e),L(e),R(e),K(e),G(e),H(e),we(e),U(e),W(e),N(e),P(e),F(e),I(e),M(e),A(e),j(e),q(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 ot(e){let n=new et({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
|
-
`):[`
|
|
3
|
-
`);
|
|
1
|
+
import{BackgroundTaskScheduler as e}from"./background-task.js";import{clearCompletionCache as t}from"./completions.js";import{CuratedKnowledgeManager as n}from"./curated-manager.js";import{createElicitor as r,noopElicitor as i}from"./elicitor.js";import{IdleTimer as a}from"./idle-timer.js";import{bridgeMcpLogging as o}from"./mcp-logging.js";import{MemoryMonitor as s}from"./memory-monitor.js";import{registerPrompts as c}from"./prompts.js";import{installReplayInterceptor as l}from"./replay-interceptor.js";import{ResourceNotifier as u}from"./resources/resource-notifier.js";import{registerResources as d}from"./resources/resources.js";import{createSamplingClient as f}from"./sampling.js";import{installStructuredContentGuard as p}from"./structured-content-guard.js";import{getToolMeta as m}from"./tool-metadata.js";import{installToolPrefix as h}from"./tool-prefix.js";import{ToolTimeoutError as g,getToolTimeout as _,withTimeout as v}from"./tool-timeout.js";import{registerAnalyzeDependenciesTool as y,registerAnalyzeDiagramTool as b,registerAnalyzeEntryPointsTool as x,registerAnalyzePatternsTool as ee,registerAnalyzeStructureTool as te,registerAnalyzeSymbolsTool as S,registerBlastRadiusTool as C}from"./tools/analyze.tools.js";import{registerAuditTool as w}from"./tools/audit.tool.js";import{registerBrainstormTool as T}from"./tools/brainstorm.tool.js";import{initBridgeComponents as E,registerErPullTool as D,registerErPushTool as O,registerErSyncStatusTool as k}from"./tools/bridge.tools.js";import{registerCompactTool as A,registerDeadSymbolsTool as j,registerFileSummaryTool as M,registerFindTool as ne,registerScopeMapTool as re,registerSymbolTool as ie,registerTraceTool as ae}from"./tools/context.tools.js";import{registerErEvolveReviewTool as oe}from"./tools/evolution.tools.js";import{registerBatchTool as se,registerCheckTool as N,registerDelegateTool as ce,registerEvalTool as P,registerParseOutputTool as F,registerTestRunTool as I}from"./tools/execution.tools.js";import{registerFlowTools as le}from"./tools/flow.tools.js";import{registerDigestTool as ue,registerEvidenceMapTool as L,registerForgeClassifyTool as R,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 z,registerHealthTool as B,registerProcessTool as V,registerWatchTool as H,registerWebFetchTool as U}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 W,registerDataTransformTool as G,registerDiffParseTool as K,registerGitContextTool as q,registerRenameTool as _e}from"./tools/manipulation.tools.js";import{registerOnboardTool as ve}from"./tools/onboard.tool.js";import{registerCheckpointTool as ye,registerLaneTool as be,registerQueueTool as xe,registerStashTool as Se,registerWorksetTool as Ce}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as we}from"./tools/policy.tools.js";import{registerPresentTool as Te}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as Ee}from"./tools/produce.tool.js";import{registerReadTool as De}from"./tools/read.tool.js";import{registerReindexTool as Oe}from"./tools/reindex.tool.js";import{registerRememberTool as ke}from"./tools/remember.tool.js";import{registerReplayTool as Ae}from"./tools/replay.tool.js";import{registerRestoreTool as je}from"./tools/restore.tool.js";import{registerSearchTool as Me}from"./tools/search.tool.js";import{getCurrentVersion as Ne}from"./version-check.js";import{registerEarlyStatusTool as Pe,registerStatusTool as Fe}from"./tools/status.tool.js";import{registerUpdateTool as Ie}from"./tools/update.tool.js";import{registerChangelogTool as Le,registerEncodeTool as Re,registerEnvTool as ze,registerHttpTool as Be,registerMeasureTool as Ve,registerRegexTestTool as He,registerSchemaValidateTool as Ue,registerSnippetTool as We,registerTimeTool as Ge,registerWebSearchTool as Ke}from"./tools/utility.tools.js";import{existsSync as qe,statSync as Je}from"node:fs";import{resolve as Ye}from"node:path";import{AIKIT_PATHS as Xe,createLogger as Ze,serializeError as J}from"../../core/dist/index.js";import{initializeWasm as Qe}from"../../chunker/dist/index.js";import{OnnxEmbedder as $e}from"../../embeddings/dist/index.js";import{EvolutionCollector as et,PolicyStore as tt}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as nt,IncrementalIndexer as rt}from"../../indexer/dist/index.js";import{SqliteGraphStore as it,createStore as at}from"../../store/dist/index.js";import{FileCache as ot}from"../../tools/dist/index.js";import{McpServer as st}from"@modelcontextprotocol/sdk/server/mcp.js";const Y=Ze(`server`);async function X(e){Y.info(`Initializing AI Kit components`);let[t,r,i,a]=await Promise.all([(async()=>{let t=new $e({model:e.embedding.model,dimensions:e.embedding.dimensions});return await t.initialize(),Y.info(`Embedder loaded`,{modelId:t.modelId,dimensions:t.dimensions}),t})(),(async()=>{let t=await at({backend:e.store.backend,path:e.store.path});return await t.initialize(),Y.info(`Store initialized`),t})(),(async()=>{let t=new it({path:e.store.path});return await t.initialize(),Y.info(`Graph store initialized`),t})(),(async()=>{let e=await Qe();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 rt(t,r),s=new nt(e.store.path);s.load(),o.setHashCache(s);let c=e.curated.path,l=new n(c,r,t);o.setGraphStore(i);let u=E(e.er),d=u?new tt(e.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new et:void 0,p=Ye(e.sources[0]?.path??process.cwd(),Xe.aiKb),m=qe(p),h=e.onboardDir?qe(e.onboardDir):!1,g=m||h,_,v=m?p:e.onboardDir;if(g&&v)try{_=Je(v).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:t,store:r,indexer:o,curated:l,graphStore:i,fileCache:new ot,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function ct(e,t){let n=new st({name:t.serverName??`aikit`,version:Ne()},{capabilities:{logging:{}}});return o(n),h(n,t.toolPrefix??``),Z(n,e,t,r(n),new u(n),f(n)),c(n,{curated:e.curated,store:e.store,graphStore:e.graphStore}),n}function Z(e,t,n,r,i,a){l(e),p(e),Me(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,a),ge(e,t.store),Fe(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n),Oe(e,t.indexer,n,t.curated,t.store,i),ke(e,t.curated,t.policyStore,t.evolutionCollector,i),Ie(e,t.curated,i),pe(e,t.curated,i),De(e,t.curated),he(e,t.curated),te(e,t.store,t.embedder),y(e,t.store,t.embedder),S(e,t.store,t.embedder),ee(e,t.store,t.embedder),x(e,t.store,t.embedder),b(e,t.store,t.embedder),C(e,t.store,t.embedder,t.graphStore),Ee(e,n),ve(e,t.store,t.embedder,n),me(e,t.graphStore),w(e,t.store,t.embedder);let o=n.sources[0]?.path??process.cwd();A(e,t.embedder,t.fileCache,o),re(e,t.embedder,t.store),ne(e,t.embedder,t.store),F(e),Ce(e),N(e),se(e,t.embedder,t.store),ie(e,t.embedder,t.store,t.graphStore),P(e),I(e),Se(e),q(e),K(e),_e(e),W(e),je(e),M(e,t.fileCache,o),ye(e),G(e),ae(e,t.embedder,t.store),V(e),H(e),j(e,t.embedder,t.store),ce(e,a),B(e),be(e),xe(e),U(e),z(e),L(e),ue(e,t.embedder),R(e),fe(e,t.embedder,t.fileCache),de(e,t.embedder,t.store),Te(e,r),r&&T(e,r),Ke(e),Be(e),He(e),Re(e),Ve(e),Le(e),Ue(e),We(e),ze(e),Ge(e),le(e,n),t.bridge&&(O(e,t.bridge,t.evolutionCollector),D(e,t.bridge),k(e,t.bridge)),t.policyStore&&we(e,t.policyStore),t.evolutionCollector&&oe(e,t.evolutionCollector),d(e,t.store,t.curated),Ae(e)}async function lt(e){let t=await X(e),n=ct(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`,J(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`,J(e))}}catch(e){Y.error(`Initial index failed; will retry on aikit_reindex`,J(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 ut=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(`.`)),dt=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 ft(e){N(e),P(e),I(e),F(e),ce(e),q(e),K(e),_e(e),W(e),G(e),Ce(e),Se(e),ye(e),je(e),be(e),xe(e),B(e),V(e),H(e),U(e),z(e),L(e),R(e),Te(e),T(e,i),Ee(e),Ae(e),Pe(e),Ke(e),Be(e),He(e),Re(e),Ve(e),Le(e),Ue(e),We(e),ze(e),Ge(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 pt(n){let i=new st({name:n.serverName??`aikit`,version:Ne()},{capabilities:{logging:{}}}),l=`initializing`,d=``,p=!1,y=()=>l===`failed`?[`β AI Kit initialization failed β this tool is unavailable.`,``,d?`Error: ${d}`:``,``,`**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
|
+
`):[`AI Kit 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 AI Kit index. Please retry in a few seconds,`,`or use one of the available tools above in the meantime.`].join(`
|
|
3
|
+
`);o(i),h(i,n.toolPrefix??``);let b=i.sendToolListChanged.bind(i);i.sendToolListChanged=()=>{};let x=[];for(let e of $){let t=m(e),n=i.registerTool(e,{title:t.title,description:`${t.title} β initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:y()}]}));Q.has(e)?n.remove():x.push(n)}ft(i),i.sendToolListChanged=b;let ee=i.registerResource(`aikit-status`,`aikit://status`,{description:`AI Kit status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`aikit://status`,text:`AI Kit is initializing...`,mimeType:`text/plain`}]})),te=i.registerPrompt(`_init`,{description:`AI Kit is initializing prompts...`},async()=>({messages:[{role:`user`,content:{type:`text`,text:y()}}]})),S,C=new Promise(e=>{S=e}),w,T=new Promise(e=>{w=e}),E=()=>w?.(),D=(async()=>{await T;let e;try{e=await X(n)}catch(e){l=`failed`,d=e instanceof Error?e.message:String(e),Y.error(`AI Kit initialization failed β server continuing with zero-dep tools only`,{error:d});return}let o=i.sendToolListChanged.bind(i);i.sendToolListChanged=()=>{};let m=i.sendPromptListChanged.bind(i);i.sendPromptListChanged=()=>{};let h=i.sendResourceListChanged.bind(i);i.sendResourceListChanged=()=>{};for(let e of x)e.remove();ee.remove(),te.remove();let y=i._registeredTools??{};for(let e of Q)y[e]?.remove();let b=new u(i),C=f(i);Z(i,e,n,r(i),b,C),c(i),i.sendToolListChanged=o,i.sendPromptListChanged=m,i.sendResourceListChanged=h,Promise.resolve(i.sendToolListChanged()).catch(()=>{}),Promise.resolve(i.sendPromptListChanged()).catch(()=>{}),Promise.resolve(i.sendResourceListChanged()).catch(()=>{});let w=i._registeredTools??{};for(let[t,n]of Object.entries(w)){if(ut.has(t))continue;let r=n.handler;n.handler=async(...n)=>{if(!e.indexer.isIndexing)return r(...n);let i=p?`re-indexing`:`running initial index`,a=new Promise(e=>setTimeout(()=>e({content:[{type:`text`,text:`β³ AI Kit is ${i}. The tool "${t}" timed out waiting for index data (${dt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly β indexing will complete automatically.`}]}),dt));return Promise.race([r(...n),a])}}for(let[e,t]of Object.entries(w)){let n=t.handler,r=_(e);t.handler=async(...t)=>{try{return await v(()=>n(...t),r,e)}catch(t){if(t instanceof g)return{content:[{type:`text`,text:`β³ Tool "${e}" timed out after ${r/1e3}s. This may indicate a long-running operation. Please retry or break the task into smaller steps.`}]};throw t}}}let E=Object.keys(w).length;E!==$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:E}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4});let D=new s;D.onPressure((e,n)=>{e===`warning`&&t(),e===`critical`&&(Y.warn(`Memory pressure critical β consider restarting`,{rssMB:Math.round(n/1024/1024)}),t())}),D.start();let O=new a;O.onIdle(async()=>{Y.info(`Idle cleanup: closing store and graph connections`);try{await e.store.close().catch(()=>{}),await e.graphStore.close().catch(()=>{})}catch{}}),O.touch();for(let e of Object.values(w)){let t=e.handler;e.handler=async(...e)=>(O.touch(),t(...e))}S?.(e)})(),O=async()=>{let e=await C;try{let t=n.sources.map(e=>e.path).join(`, `);Y.info(`Running initial index`,{sourcePaths:t});let r=await e.indexer.index(n,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}))});p=!0,Y.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await e.store.createFtsIndex()}catch(e){Y.warn(`FTS index creation failed`,J(e))}try{let t=await e.curated.reindexAll();Y.info(`Curated re-index complete`,{indexed:t.indexed})}catch(e){Y.error(`Curated re-index failed`,J(e))}}catch(e){Y.error(`Initial index failed; will retry on aikit_reindex`,J(e))}},k=new e,A=()=>k.schedule({name:`initial-index`,fn:O}),j=process.ppid,M=setInterval(()=>{try{process.kill(j,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:j}),clearInterval(M),C.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 M.unref(),{server:i,startInit:E,ready:D,runInitialIndex:A,scheduler:k}}export{$ as ALL_TOOL_NAMES,pt as createLazyServer,ct as createMcpServer,lt as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region packages/server/src/tool-metadata.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Centralized tool metadata registry for all
|
|
3
|
+
* Centralized tool metadata registry for all AI Kit MCP tools.
|
|
4
4
|
*
|
|
5
5
|
* Provides `title` and `annotations` (readOnlyHint, destructiveHint) for each tool.
|
|
6
6
|
* Used by both placeholder registration (lazy startup) and real tool registration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0}},symbol:{title:`Symbol Resolver`,annotations:{readOnlyHint:!0,idempotentHint:!0}},trace:{title:`Data Flow Tracer`,annotations:{readOnlyHint:!0,idempotentHint:!0}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0}},lookup:{title:`Chunk Lookup`,annotations:{readOnlyHint:!0,idempotentHint:!0}},dead_symbols:{title:`Dead Symbol Finder`,annotations:{readOnlyHint:!0,idempotentHint:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_structure:{title:`Analyze Structure`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_dependencies:{title:`Analyze Dependencies`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_symbols:{title:`Analyze Symbols`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_patterns:{title:`Analyze Patterns`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_entry_points:{title:`Analyze Entry Points`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_diagram:{title:`Analyze Diagram`,annotations:{readOnlyHint:!0,idempotentHint:!0}},blast_radius:{title:`Blast Radius`,annotations:{readOnlyHint:!0,idempotentHint:!0}},brainstorm:{title:`Brainstorm Session`,annotations:{readOnlyHint:!0,idempotentHint:!0}},remember:{title:`Remember Knowledge`,annotations:{readOnlyHint:!1}},read:{title:`Read Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},update:{title:`Update Knowledge`,annotations:{readOnlyHint:!1}},forget:{title:`Forget Knowledge`,annotations:{readOnlyHint:!1,destructiveHint:!0}},list:{title:`List Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},compact:{title:`Semantic Compactor`,annotations:{readOnlyHint:!0,idempotentHint:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stratum_card:{title:`Stratum Card`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_classify:{title:`FORGE Classify`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0}},batch:{title:`Batch Operations`,annotations:{readOnlyHint:!0,idempotentHint:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0}},data_transform:{title:`Data Transform`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stash:{title:`Stash Values`,annotations:{readOnlyHint:!1}},checkpoint:{title:`Session Checkpoint`,annotations:{readOnlyHint:!1}},workset:{title:`Workset Manager`,annotations:{readOnlyHint:!1}},lane:{title:`Exploration Lane`,annotations:{readOnlyHint:!1}},git_context:{title:`Git Context`,annotations:{readOnlyHint:!0,idempotentHint:!0}},diff_parse:{title:`Diff Parser`,annotations:{readOnlyHint:!0,idempotentHint:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0}},watch:{title:`File Watcher`,annotations:{readOnlyHint:!1,openWorldHint:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0}},status:{title:`
|
|
1
|
+
const e={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0}},symbol:{title:`Symbol Resolver`,annotations:{readOnlyHint:!0,idempotentHint:!0}},trace:{title:`Data Flow Tracer`,annotations:{readOnlyHint:!0,idempotentHint:!0}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0}},lookup:{title:`Chunk Lookup`,annotations:{readOnlyHint:!0,idempotentHint:!0}},dead_symbols:{title:`Dead Symbol Finder`,annotations:{readOnlyHint:!0,idempotentHint:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_structure:{title:`Analyze Structure`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_dependencies:{title:`Analyze Dependencies`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_symbols:{title:`Analyze Symbols`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_patterns:{title:`Analyze Patterns`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_entry_points:{title:`Analyze Entry Points`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_diagram:{title:`Analyze Diagram`,annotations:{readOnlyHint:!0,idempotentHint:!0}},blast_radius:{title:`Blast Radius`,annotations:{readOnlyHint:!0,idempotentHint:!0}},brainstorm:{title:`Brainstorm Session`,annotations:{readOnlyHint:!0,idempotentHint:!0}},remember:{title:`Remember Knowledge`,annotations:{readOnlyHint:!1}},read:{title:`Read Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},update:{title:`Update Knowledge`,annotations:{readOnlyHint:!1}},forget:{title:`Forget Knowledge`,annotations:{readOnlyHint:!1,destructiveHint:!0}},list:{title:`List Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},compact:{title:`Semantic Compactor`,annotations:{readOnlyHint:!0,idempotentHint:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stratum_card:{title:`Stratum Card`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_classify:{title:`FORGE Classify`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0}},batch:{title:`Batch Operations`,annotations:{readOnlyHint:!0,idempotentHint:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0}},data_transform:{title:`Data Transform`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stash:{title:`Stash Values`,annotations:{readOnlyHint:!1}},checkpoint:{title:`Session Checkpoint`,annotations:{readOnlyHint:!1}},workset:{title:`Workset Manager`,annotations:{readOnlyHint:!1}},lane:{title:`Exploration Lane`,annotations:{readOnlyHint:!1}},git_context:{title:`Git Context`,annotations:{readOnlyHint:!0,idempotentHint:!0}},diff_parse:{title:`Diff Parser`,annotations:{readOnlyHint:!0,idempotentHint:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0}},watch:{title:`File Watcher`,annotations:{readOnlyHint:!1,openWorldHint:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0}},status:{title:`AI Kit Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},health:{title:`Health Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},reindex:{title:`Reindex`,annotations:{readOnlyHint:!1}},onboard:{title:`Onboard Codebase`,annotations:{readOnlyHint:!1}},graph:{title:`Knowledge Graph`,annotations:{readOnlyHint:!1}},guide:{title:`Tool Guide`,annotations:{readOnlyHint:!0,idempotentHint:!0}},replay:{title:`Replay History`,annotations:{readOnlyHint:!0,idempotentHint:!0}},changelog:{title:`Generate Changelog`,annotations:{readOnlyHint:!0,idempotentHint:!0}},regex_test:{title:`Regex Tester`,annotations:{readOnlyHint:!0,idempotentHint:!0}},encode:{title:`Encode / Decode`,annotations:{readOnlyHint:!0,idempotentHint:!0}},measure:{title:`Code Metrics`,annotations:{readOnlyHint:!0,idempotentHint:!0}},schema_validate:{title:`Schema Validator`,annotations:{readOnlyHint:!0,idempotentHint:!0}},snippet:{title:`Code Snippets`,annotations:{readOnlyHint:!1}},env:{title:`Environment Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},time:{title:`Date & Time`,annotations:{readOnlyHint:!0,idempotentHint:!0}},web_fetch:{title:`Web Fetch`,annotations:{readOnlyHint:!0,openWorldHint:!0}},web_search:{title:`Web Search`,annotations:{readOnlyHint:!0,openWorldHint:!0}},http:{title:`HTTP Request`,annotations:{readOnlyHint:!1,openWorldHint:!0}},queue:{title:`Operation Queue`,annotations:{readOnlyHint:!1}},bridge_push:{title:`Bridge Push`,annotations:{readOnlyHint:!1}},bridge_pull:{title:`Bridge Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0}},bridge_sync:{title:`Bridge Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evolution_state:{title:`Evolution State`,annotations:{readOnlyHint:!1}},policy_check:{title:`Policy Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_list:{title:`Flow List`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_info:{title:`Flow Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_start:{title:`Flow Start`,annotations:{readOnlyHint:!1}},flow_step:{title:`Flow Step`,annotations:{readOnlyHint:!1}},flow_status:{title:`Flow Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_reset:{title:`Flow Reset`,annotations:{readOnlyHint:!1}}};function t(t){return e[t]??{title:t,annotations:{readOnlyHint:!1}}}export{e as TOOL_METADATA,t as getToolMeta};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region packages/server/src/tool-timeout.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Tool timeout wrapper β ensures no tool handler can run indefinitely.
|
|
4
|
+
*
|
|
5
|
+
* Every MCP tool handler is wrapped with a configurable timeout.
|
|
6
|
+
* Heavy tools (onboard, reindex, produce_knowledge, analyzers) get a longer deadline.
|
|
7
|
+
*/
|
|
8
|
+
/** Default timeout for normal tool handlers (120 seconds). */
|
|
9
|
+
declare const DEFAULT_TOOL_TIMEOUT_MS = 120000;
|
|
10
|
+
/** Extended timeout for heavy tool handlers (10 minutes). */
|
|
11
|
+
declare const HEAVY_TOOL_TIMEOUT_MS = 600000;
|
|
12
|
+
declare class ToolTimeoutError extends Error {
|
|
13
|
+
readonly toolName: string;
|
|
14
|
+
readonly timeoutMs: number;
|
|
15
|
+
constructor(toolName: string, timeoutMs: number);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Return the timeout for a given tool name.
|
|
19
|
+
*/
|
|
20
|
+
declare function getToolTimeout(toolName: string): number;
|
|
21
|
+
/**
|
|
22
|
+
* Wrap an async function with a timeout. If the function doesn't resolve
|
|
23
|
+
* within `timeoutMs`, the returned promise rejects with a `ToolTimeoutError`.
|
|
24
|
+
*/
|
|
25
|
+
declare function withTimeout<T>(fn: () => Promise<T>, timeoutMs: number, toolName: string): Promise<T>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { DEFAULT_TOOL_TIMEOUT_MS, HEAVY_TOOL_TIMEOUT_MS, ToolTimeoutError, getToolTimeout, withTimeout };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createLogger as e}from"../../core/dist/index.js";const t=e(`tool-timeout`),n=12e4,r=6e5,i=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze_structure`,`analyze_dependencies`,`analyze_symbols`,`analyze_patterns`,`analyze_entry_points`,`analyze_diagram`,`codemod`,`batch`,`audit`]);var a=class extends Error{constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function o(e){return i.has(e)?r:n}function s(e,n,r){return new Promise((i,o)=>{let s=!1,c=setTimeout(()=>{if(!s){s=!0;let e=new a(r,n);t.warn(e.message),o(e)}},n);c.unref&&c.unref(),e().then(e=>{s||(s=!0,clearTimeout(c),i(e))},e=>{s||(s=!0,clearTimeout(c),o(e))})})}export{n as DEFAULT_TOOL_TIMEOUT_MS,r as HEAVY_TOOL_TIMEOUT_MS,a as ToolTimeoutError,o as getToolTimeout,s as withTimeout};
|
|
@@ -2,7 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
2
2
|
import { ERBridgeConfig, ERCache, ERClient, EvolutionCollector, PushAdapter } from "../../../enterprise-bridge/dist/index.js";
|
|
3
3
|
|
|
4
4
|
//#region packages/server/src/tools/bridge.tools.d.ts
|
|
5
|
-
/** Resolve ER bridge config from
|
|
5
|
+
/** Resolve ER bridge config from server config + env */
|
|
6
6
|
declare function resolveErBridgeConfig(erConfig?: {
|
|
7
7
|
enabled: boolean;
|
|
8
8
|
baseUrl: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
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{ERCache as i,ERClient as a,PushAdapter as o}from"../../../enterprise-bridge/dist/index.js";const s=n(`tools`);function c(e){if(!e?.enabled)return;let t=process.env.AIKIT_ER_API_KEY;if(!t){s.warn(`ER bridge enabled but AIKIT_ER_API_KEY not set; disabling`);return}return{enabled:!0,baseUrl:e.baseUrl,apiKey:t,timeoutMs:e.timeoutMs??5e3,cacheTtlMs:e.cacheTtlMs??360*60*1e3,cacheMaxEntries:e.cacheMaxEntries??100,fallbackThreshold:e.fallbackThreshold??.45}}function l(e){let t=c(e);if(t)try{let e=new a(t),n=new i({maxEntries:t.cacheMaxEntries,defaultTtl:t.cacheTtlMs}),r=new o(e);try{let e=new URL(t.baseUrl).hostname;s.info(`ER bridge initialized`,{host:e})}catch{s.info(`ER bridge initialized`)}return{client:e,cache:n,pushAdapter:r,config:t}}catch(e){s.warn(`ER bridge initialization failed`,r(e));return}}function u(n,i,a){let o=e(`er_push`);n.registerTool(`er_push`,{title:o.title,description:`Push a curated knowledge entry to Enterprise RAG. The entry is stored via ER's curated_remember tool and becomes immediately searchable in the enterprise
|
|
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{ERCache as i,ERClient as a,PushAdapter as o}from"../../../enterprise-bridge/dist/index.js";const s=n(`tools`);function c(e){if(!e?.enabled)return;let t=process.env.AIKIT_ER_API_KEY;if(!t){s.warn(`ER bridge enabled but AIKIT_ER_API_KEY not set; disabling`);return}return{enabled:!0,baseUrl:e.baseUrl,apiKey:t,timeoutMs:e.timeoutMs??5e3,cacheTtlMs:e.cacheTtlMs??360*60*1e3,cacheMaxEntries:e.cacheMaxEntries??100,fallbackThreshold:e.fallbackThreshold??.45}}function l(e){let t=c(e);if(t)try{let e=new a(t),n=new i({maxEntries:t.cacheMaxEntries,defaultTtl:t.cacheTtlMs}),r=new o(e);try{let e=new URL(t.baseUrl).hostname;s.info(`ER bridge initialized`,{host:e})}catch{s.info(`ER bridge initialized`)}return{client:e,cache:n,pushAdapter:r,config:t}}catch(e){s.warn(`ER bridge initialization failed`,r(e));return}}function u(n,i,a){let o=e(`er_push`);n.registerTool(`er_push`,{title:o.title,description:`Push a curated knowledge entry to Enterprise RAG. The entry is stored via ER's curated_remember tool and becomes immediately searchable in the enterprise AI Kit.`,inputSchema:{title:t.string().min(3).max(120).describe(`Title for the knowledge entry`),content:t.string().min(10).max(1e5).describe(`Markdown content to push (max 100KB)`),category:t.string().regex(/^[a-z][a-z0-9-]*$/).default(`conventions`).describe(`Category slug (e.g., "decisions", "patterns", "conventions")`),tags:t.array(t.string()).default([]).describe(`Optional tags`),rule_id:t.string().optional().describe(`ID of the classification rule that motivated this push (from remember classification signals). Improves rule effectiveness tracking.`)},annotations:o.annotations},async({title:e,content:t,category:n,tags:o,rule_id:c})=>{try{let r=`${n}/${e.toLowerCase().replace(/[^a-z0-9]+/g,`-`)}`,s=await i.pushAdapter.push(r,{title:e,content:t,category:n,tags:o});return s.pushed?(a&&a.recordPush(r,s.pushed,c),{content:[{type:`text`,text:`Pushed to ER: **${e}**\n\nRemote path: \`${s.remotePath??`unknown`}\`\nTimestamp: ${s.timestamp}\n\n---\n_Next: Use \`er_pull\` to verify the entry is searchable in ER, or \`er_sync_status\` to see push history._`}]}):(a&&a.recordPush(r,!1,c),{content:[{type:`text`,text:`ER push failed: ${s.error??`Unknown error`}\n\n_The local AI Kit is unaffected. You can retry or check ER health with \`er_sync_status\`._`}],isError:!0})}catch(t){if(s.error(`ER push failed`,r(t)),a){let t=`${n}/${e.toLowerCase().replace(/[^a-z0-9]+/g,`-`)}`;a.recordPush(t,!1,c)}return{content:[{type:`text`,text:`ER push failed: operation unsuccessful
|
|
2
2
|
|
|
3
|
-
_The local
|
|
3
|
+
_The local AI Kit is unaffected. You can retry or check ER health with \`er_sync_status\`._`}],isError:!0}}})}function d(n,i){let a=e(`er_pull`);n.registerTool(`er_pull`,{title:a.title,description:`Explicitly search the Enterprise RAG AI Kit. Returns results from the enterprise system only (not local AI Kit). Uses a cache with 6-hour TTL to reduce API calls.`,inputSchema:{query:t.string().min(1).max(2e3).describe(`Search query for Enterprise RAG AI Kit (max 2000 chars)`),max_results:t.number().min(1).max(20).default(5).describe(`Maximum results to return`),bypass_cache:t.boolean().default(!0).describe(`Skip cache and fetch fresh results from ER (default: true per DR-001)`)},annotations:a.annotations},async({query:e,max_results:t,bypass_cache:n})=>{try{if(!n){let n=i.cache.get(e);if(n)return{content:[{type:`text`,text:`${n.slice(0,t).map((e,t)=>`### Result ${t+1} (score: ${e.score.toFixed(3)}, source: ER cached)\n- **Source**: ${e.sourcePath}\n\n${e.content}`).join(`
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,6 +10,6 @@ _The local KB is unaffected. You can retry or check ER health with \`er_sync_sta
|
|
|
10
10
|
|
|
11
11
|
`)}\n\n---\n_Source: Enterprise RAG (${r.length} results) | Results cached for ${Math.floor(i.config.cacheTtlMs/36e5)}h_`}]}}catch(e){return s.error(`ER pull failed`,r(e)),{content:[{type:`text`,text:`ER pull failed: search request unsuccessful
|
|
12
12
|
|
|
13
|
-
_Enterprise RAG may be unavailable. Local
|
|
13
|
+
_Enterprise RAG may be unavailable. Local AI Kit search is unaffected._`}],isError:!0}}})}function f(n,i){let a=e(`er_sync_status`);n.registerTool(`er_sync_status`,{title:a.title,description:`Show the status of the Enterprise RAG bridge: health, cache stats, and push history.`,inputSchema:{check_health:t.boolean().default(!0).describe(`Whether to ping ER health endpoint (adds latency)`)},annotations:a.annotations},async({check_health:e})=>{try{let t=i.cache.stats(),n=i.pushAdapter.getStatus(),r=new URL(i.config.baseUrl),a=`${r.protocol}//${r.hostname}${r.port?`:${r.port}`:``}`,o=`_Health check skipped_`;if(e){let e=await i.client.health();o=e.healthy?`β
Healthy (HTTP ${e.status})`:`β Unhealthy${e.status?` (HTTP ${e.status})`:``}`}let s=[`## ER Bridge Status
|
|
14
14
|
`,`**Endpoint**: \`${a}\``,`**Health**: ${o}`,`**Threshold**: ${i.config.fallbackThreshold} (vector similarity for auto-fallback)`,``,`### Cache`,`- Entries: ${t.size} / ${t.maxEntries}`,`- TTL: ${Math.floor(t.defaultTtlMs/36e5)}h`,``,`### Push History`,`- Total pushed: ${n.totalPushed}`,`- Successful: ${n.successCount}`,`- Failed: ${n.failCount}`];return n.lastPush&&s.push(`- Last push: "${n.lastPush.title}" at ${n.lastPush.pushedAt} (${n.lastPush.status})`),s.push("\n---\n_Next: Use `er_push` to send knowledge to ER, or `er_pull` to search ER._"),{content:[{type:`text`,text:s.join(`
|
|
15
15
|
`)}]}}catch(e){return s.error(`ER sync status failed`,r(e)),{content:[{type:`text`,text:`ER sync status failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{l as initBridgeComponents,d as registerErPullTool,u as registerErPushTool,f as registerErSyncStatusTool,c as resolveErBridgeConfig};
|
|
@@ -1,4 +1,4 @@
|
|
|
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 o=e(`er_evolve_review`);n.registerTool(`er_evolve_review`,{title:o.title,description:`Review evolution metrics for the
|
|
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 o=e(`er_evolve_review`);n.registerTool(`er_evolve_review`,{title:o.title,description:`Review evolution metrics for the AI Kit β ER bridge. Shows local miss rates, push acceptance, rule effectiveness, and top missed queries. Use this to reason about improving classification rules and knowledge flow.`,inputSchema:{include_details:t.boolean().default(!0).describe(`Include detailed breakdowns (top missed queries, rule stats)`),reset_after:t.boolean().default(!1).describe(`Reset collected metrics after review`)},annotations:o.annotations},async({include_details:e,reset_after:t})=>{try{let n=a.getMetrics(),r=[`## ER Evolution Review
|
|
2
2
|
`,`**Period**: ${n.period.startedAt} β ${n.period.queriedAt}`,`**Total events**: ${n.period.totalEvents}\n`,`### Search`,`- Total searches: ${n.search.totalSearches}`,`- ER fallback triggered: ${n.search.erFallbackCount} (${(n.search.erFallbackRate*100).toFixed(1)}%)`,`- ER cache hits: ${n.search.erCacheHitCount} (${(n.search.erCacheHitRate*100).toFixed(1)}% of fallbacks)`];if(e&&n.search.topMissedQueries.length>0){r.push(`
|
|
3
3
|
**Top missed queries** (triggered ER fallback):`);for(let e of n.search.topMissedQueries.slice(0,10)){let t=e.query.length>60?`${e.query.slice(0,57)}...`:e.query;r.push(` - "${t}" (${e.count}x)`)}}if(r.push(``,`### Push`,`- Total pushes: ${n.push.totalPushes} (${n.push.successCount} ok, ${n.push.failCount} failed)`,`- Classification match rate: ${(n.push.classificationMatchRate*100).toFixed(1)}%`,`- Push acceptance rate: ${(n.push.pushAcceptanceRate*100).toFixed(1)}%`),r.push(``,`### Rule Effectiveness`),Object.keys(n.rules.matchCounts).length>0)for(let[e,t]of Object.entries(n.rules.matchCounts)){let i=n.rules.pushCounts[e]??0,a=t>0?(i/t*100).toFixed(0):`0`;r.push(`- **${e}**: ${t} matches β ${i} pushes (${a}% conversion)`)}else r.push(`- _No rule activity recorded yet_`);if(e&&n.rules.lowConversionRules.length>0){r.push(``,`### β οΈ Low Conversion Rules (potential false positives)`);for(let e of n.rules.lowConversionRules)r.push(`- **${e.ruleId}**: ${e.matchCount} matches, ${e.pushCount} pushes (${(e.conversionRate*100).toFixed(0)}% conversion) β consider tightening patterns`)}return r.push(``,`---`,"_Next: Use `er_update_policy` to refine rules based on these metrics, or `er_push` to share high-value knowledge._"),t&&(i.info(`Evolution metrics reset requested`,{requestedAt:new Date().toISOString(),clearedEvents:n.period.totalEvents}),a.reset(),r.push(`
|
|
4
4
|
_Metrics have been reset._`)),{content:[{type:`text`,text:r.join(`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{getToolMeta as e}from"../tool-metadata.js";import{HealthOutputSchema as t}from"../output-schemas.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";import{guide as a,health as o,processList as s,processLogs as c,processStart as l,processStatus as u,processStop as d,watchList as f,watchStart as p,watchStop as m,webFetch as h}from"../../../tools/dist/index.js";const g=r(`tools:infra`);function _(t){let r=e(`process`);t.registerTool(`process`,{title:r.title,description:`Start, stop, inspect, list, and tail logs for in-memory managed child processes.`,inputSchema:{action:n.enum([`start`,`stop`,`status`,`list`,`logs`]).describe(`Process action to perform`),id:n.string().optional().describe(`Managed process ID`),command:n.string().optional().describe(`Executable to start`),args:n.array(n.string()).optional().describe(`Arguments for start actions`),tail:n.number().min(1).max(500).optional().describe(`Log lines to return for logs actions`)},annotations:r.annotations},async({action:e,id:t,command:n,args:r,tail:a})=>{try{switch(e){case`start`:if(!t||!n)throw Error(`id and command are required for start`);return{content:[{type:`text`,text:JSON.stringify(l(t,n,r??[]))}]};case`stop`:if(!t)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify(d(t)??null)}]};case`status`:if(!t)throw Error(`id is required for status`);return{content:[{type:`text`,text:JSON.stringify(u(t)??null)}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(s())}]};case`logs`:if(!t)throw Error(`id is required for logs`);return{content:[{type:`text`,text:JSON.stringify(c(t,a))}]}}}catch(e){return g.error(`Process action failed`,i(e)),{content:[{type:`text`,text:`Process action failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function v(t){let r=e(`watch`);t.registerTool(`watch`,{title:r.title,description:`Watch a directory for file changes (create/modify/delete). Actions: start (begin watching), stop (by ID), list (show active watchers). Events are emitted as structured JSON with path, event type, and timestamp.`,inputSchema:{action:n.enum([`start`,`stop`,`list`]).describe(`Watch action to perform`),path:n.string().optional().describe(`Directory path to watch for start actions`),id:n.string().optional().describe(`Watcher ID for stop actions`)},annotations:r.annotations},async({action:e,path:t,id:n})=>{try{switch(e){case`start`:if(!t)throw Error(`path is required for start`);return{content:[{type:`text`,text:JSON.stringify(p({path:t}))}]};case`stop`:if(!n)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify({stopped:m(n)})}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(f())}]}}}catch(e){return g.error(`Watch action failed`,i(e)),{content:[{type:`text`,text:`Watch action failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function y(r){let a=e(`health`);r.registerTool(`health`,{title:a.title,description:`Run project health checks β verifies package.json, tsconfig, scripts, lockfile, README, LICENSE, .gitignore.`,outputSchema:t,inputSchema:{path:n.string().optional().describe(`Root directory to check (defaults to cwd)`)},annotations:a.annotations},async({path:e})=>{try{let t=o(e),n={ok:t.checks.every(e=>e.status!==`fail`),checks:t.checks.map(e=>({name:e.name,ok:e.status===`pass`,message:e.message}))};return{content:[{type:`text`,text:JSON.stringify(t)}],structuredContent:n}}catch(e){return g.error(`Health check failed`,i(e)),{content:[{type:`text`,text:`Health check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}function b(t){let r=e(`web_fetch`);t.registerTool(`web_fetch`,{title:r.title,description:`PREFERRED web fetcher β fetch one or many URLs and convert to LLM-optimized markdown. Pass one URL or multiple for parallel fetching. Supports CSS selectors, 4 output modes (markdown/raw/links/outline), smart paragraph-boundary truncation. Strips scripts/styles/nav automatically.`,inputSchema:{urls:n.array(n.string().url()).min(1).max(10).describe('URLs to fetch (1β10). Single URL: `["https://..."]`. Multiple fetched in parallel.'),mode:n.enum([`markdown`,`raw`,`links`,`outline`]).default(`markdown`).describe(`Output mode: markdown (clean content), raw (HTML), links (extracted URLs), outline (heading hierarchy)`),selector:n.string().optional().describe(`CSS selector to extract a specific element instead of auto-detecting main content`),max_length:n.number().min(500).max(1e5).default(15e3).describe(`Max characters in output β truncates at paragraph boundaries`),include_metadata:n.boolean().default(!0).describe(`Include page title, description, and URL as a header`),include_links:n.boolean().default(!1).describe(`Append extracted links list at the end`),include_images:n.boolean().default(!1).describe(`Include image alt texts inline`),timeout:n.number().min(1e3).max(6e4).default(15e3).describe(`Request timeout in milliseconds`)},annotations:r.annotations},async({urls:e,mode:t,selector:n,max_length:r,include_metadata:a,include_links:o,include_images:s,timeout:c})=>{let l=e,u=async(e,i)=>{let l=await h({url:e,mode:t,selector:n,maxLength:r,includeMetadata:a,includeLinks:o,includeImages:s,timeout:c}),u=[i?`## ${i} ${l.title||`Web Page`}\n> Source: ${e}`:`## ${l.title||`Web Page`}`,``,l.content];return l.truncated&&u.push(``,`_Original length: ${l.originalLength.toLocaleString()} chars_`),u.join(`
|
|
2
2
|
`)};if(l.length===1)try{return{content:[{type:`text`,text:await u(l[0])+"\n\n---\n_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._"}]}}catch(e){let t=e instanceof Error?e.message:String(e);return/HTTP [45]\d{2}/.test(t)?g.warn(`Web fetch failed`,{error:t}):g.error(`Web fetch failed`,i(e)),{content:[{type:`text`,text:`Web fetch failed: ${t}`}],isError:!0}}let d=l.length,f=await Promise.allSettled(l.map((e,t)=>u(e,`[${t+1}/${d}]`))),p=[],m=0;for(let e=0;e<f.length;e++){let t=f[e];if(t.status===`fulfilled`)p.push(t.value);else{m++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);/HTTP [45]\d{2}/.test(n)?g.warn(`Web fetch failed`,{url:l[e],error:n}):g.error(`Web fetch failed`,{url:l[e],...i(t.reason)}),p.push(`## β Failed: ${l[e]}\n\n${n}`)}}let _=`_Fetched ${f.length-m}/${f.length} URLs successfully._`;return p.push(``,`---`,_,"_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._"),{content:[{type:`text`,text:p.join(`
|
|
3
3
|
|
|
4
|
-
`)}],...m===f.length?{isError:!0}:{}}})}function x(t){let r=e(`guide`);t.registerTool(`guide`,{title:r.title,description:`Tool discovery β given a goal description, recommends which
|
|
4
|
+
`)}],...m===f.length?{isError:!0}:{}}})}function x(t){let r=e(`guide`);t.registerTool(`guide`,{title:r.title,description:`Tool discovery β given a goal description, recommends which AI Kit tools to use and in what order. Matches against 10 predefined workflows: onboard, audit, bugfix, implement, refactor, search, context, memory, validate, analyze.`,inputSchema:{goal:n.string().describe(`What you want to accomplish (e.g., "audit this monorepo", "fix a failing test")`),max_recommendations:n.number().min(1).max(10).default(5).describe(`Maximum number of tool recommendations`)},annotations:r.annotations},async({goal:e,max_recommendations:t})=>{try{let n=a(e,t),r=[`## Recommended Workflow: **${n.workflow}**`,n.description,``,`### Tools`,...n.tools.map(e=>{let t=e.suggestedArgs?` β \`${JSON.stringify(e.suggestedArgs)}\``:``;return`${e.order}. **${e.tool}** β ${e.reason}${t}`})];return n.alternativeWorkflows.length>0&&r.push(``,`_Alternative workflows: ${n.alternativeWorkflows.join(`, `)}_`),r.push(``,`---`,"_Next: Run the first recommended tool, or use `guide` again with a more specific goal._"),{content:[{type:`text`,text:r.join(`
|
|
5
5
|
`)}]}}catch(e){return g.error(`Guide failed`,i(e)),{content:[{type:`text`,text:`Guide failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{x as registerGuideTool,y as registerHealthTool,_ as registerProcessTool,v as registerWatchTool,b as registerWebFetchTool};
|
|
@@ -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)})}}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
|
|
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 AI Kit + write .ai/kb/ files; memory = AI Kit 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
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};
|
|
@@ -3,15 +3,15 @@ import{FONT_LINK as e,getDesignSystemCSS as t}from"../present-theme.js";import{e
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
6
|
-
<title>${n(a??`
|
|
6
|
+
<title>${n(a??`AI Kit Dashboard`)}</title>
|
|
7
7
|
${e}
|
|
8
8
|
<style>${t()}</style>
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div class="dashboard">
|
|
12
12
|
<div class="header">
|
|
13
|
-
<h1>${n(a??`
|
|
14
|
-
<div class="subtitle">
|
|
13
|
+
<h1>${n(a??`AI Kit Dashboard`)}</h1>
|
|
14
|
+
<div class="subtitle">AI Kit</div>
|
|
15
15
|
</div>
|
|
16
16
|
${l}
|
|
17
17
|
${(()=>{let e=Array.isArray(s)?s:[];return e.length===0?``:`
|
|
@@ -42,7 +42,7 @@ ${e}
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
<\/script>`})()}
|
|
45
|
-
<div class="footer">
|
|
45
|
+
<div class="footer">AI Kit MCP Server · Generated ${new Date().toLocaleString()}</div>
|
|
46
46
|
</div>
|
|
47
47
|
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>
|
|
48
48
|
<script>
|
|
@@ -11,7 +11,7 @@ import{getToolMeta as e}from"../../tool-metadata.js";import{buildBrowserHtml as
|
|
|
11
11
|
- kanban: drag-drop board β content: { columns: [{id, label, color?}], cards: [{id, title, column, tags?[], priority?}] }
|
|
12
12
|
- tree: collapsible tree view β content: { root: {label, children?:[...]} | [...] }
|
|
13
13
|
- diff-view: side-by-side diff β content: { files: [{path, status, additions, deletions, hunks:[{header, changes:[{type, content}]}]}] }
|
|
14
|
-
- dashboard: metric cards grid β content: { metrics: [{label, value, trend?, status?, type?}] }`)};let v,y=!1,b=null;process.on(`exit`,()=>{if(b){try{b.close()}catch{}b=null}});function x(){return a(m,`..`,`..`,`..`,`..`,`present`,`dist`,`index.html`)}function S(){if(!v)try{v=r(x(),`utf-8`)}catch{v=``}return v}function C(t,n){let r=e(`present`);y||=(f(t,`
|
|
14
|
+
- dashboard: metric cards grid β content: { metrics: [{label, value, trend?, status?, type?}] }`)};let v,y=!1,b=null;process.on(`exit`,()=>{if(b){try{b.close()}catch{}b=null}});function x(){return a(m,`..`,`..`,`..`,`..`,`present`,`dist`,`index.html`)}function S(){if(!v)try{v=r(x(),`utf-8`)}catch{v=``}return v}function C(t,n){let r=e(`present`);y||=(f(t,`AI Kit Present App`,h,{description:`Rich interactive content viewer for AI Kit tools`},async()=>({contents:[{uri:h,mimeType:d,text:S()}]})),!0),p(t,`present`,{title:r.title,description:`Present content to the user in the best format. Two modes:
|
|
15
15
|
- "html" (default): Rich markdown in chat + embedded UIResource. Use for display-only content (tables, charts, reports, status boards) where no user interaction is needed.
|
|
16
16
|
- "browser": Serves a themed dashboard on a local URL. Use ONLY when you need user interaction back (confirmations, selections, form input). The tool blocks until user clicks an action button, then returns their selection.
|
|
17
17
|
FORMAT RULE: If no user interaction is needed β use "html". If you need user input back β use "browser".
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";const a=r(`tools`);function o(r,o,s,c,l,u){let d=e(`reindex`);r.registerTool(`reindex`,{title:d.title,description:`Trigger re-indexing of the
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";const a=r(`tools`);function o(r,o,s,c,l,u){let d=e(`reindex`);r.registerTool(`reindex`,{title:d.title,description:`Trigger re-indexing of the AI Kit index. Can do incremental (only changed files) or full re-index.`,inputSchema:{full:n.boolean().default(!1).describe(`If true, force full re-index ignoring file hashes`)},annotations:d.annotations},async({full:e},n)=>{try{if(o.isIndexing)return{content:[{type:`text`,text:`## Reindex Already in Progress
|
|
2
2
|
|
|
3
3
|
A reindex operation is currently running. Search and other tools continue to work with existing data. Use \`status({})\` to check when it completes.`}]};let r=t(n).createTask(`Reindex`,1);r.progress(0,`Starting ${e?`full`:`incremental`} reindex`),a.info(`Starting background re-index`,{mode:e?`full`:`incremental`});let d=e=>t=>{t.phase===`chunking`&&t.currentFile&&a.debug(`Re-index progress`,{prefix:e,current:t.filesProcessed+1,total:t.filesTotal,file:t.currentFile})};return(e?o.reindexAll(s,d(`Reindex`)):o.index(s,d(`Index`))).then(async e=>{if(a.info(`Background re-index complete`,{filesProcessed:e.filesProcessed,chunksCreated:e.chunksCreated,durationMs:e.durationMs}),r.complete(`Reindex complete: ${e.filesProcessed} files, ${e.chunksCreated} chunks in ${e.durationMs}ms`),l)try{await l.createFtsIndex(),a.info(`FTS index rebuilt after reindex`)}catch(e){a.warn(`FTS index rebuild failed`,i(e))}try{let e=await c.reindexAll();a.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){a.warn(`Curated re-index failed`,i(e))}if(u)try{await u.notifyAfterReindex()}catch(e){a.warn(`Post-reindex resource notification failed`,i(e))}}).catch(e=>{r.fail(`Reindex failed: ${e instanceof Error?e.message:String(e)}`),a.error(`Background reindex failed`,i(e))}),{content:[{type:`text`,text:`## Reindex Started (Background)\n\n- **Mode**: ${e?`Full`:`Incremental`}\n- Search and other tools continue to work with existing data during reindex.\n- Completion will be logged. Use \`status({})\` to check index stats afterward.\n\n---\n_Next: Continue working β the reindex runs in the background._`}]}}catch(e){return a.error(`Reindex failed`,i(e)),{content:[{type:`text`,text:`Reindex failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{o as registerReindexTool};
|
|
@@ -1,4 +1,4 @@
|
|
|
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{basename as c}from"node:path";import{stat as l}from"node:fs/promises";import{z as u}from"zod";import{CONTENT_TYPES as d,KNOWLEDGE_ORIGINS as f,SOURCE_TYPES as p,computePartitionKey as m,createLogger as h,serializeError as g}from"../../../core/dist/index.js";import{bookendReorder as _,graphAugmentSearch as v,stashGet as y,truncateToTokenBudget as ee}from"../../../tools/dist/index.js";import{mergeResults as b}from"../../../enterprise-bridge/dist/index.js";const x=h(`tools`);function S(e){let t=[],n=c(process.cwd());n&&t.push(`[project: ${n}]`);let r=y(`__context_boost`);return r&&t.push(`[focus: ${r.value}]`),t.length===0?e:`${t.join(` `)} ${e}`}async function C(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:b(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 x.warn(`ER fallback failed`,g(e)),{results:n,triggered:!0,cacheHit:a}}}function te(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 w(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 T(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&&!E.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&&!E.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 E=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 D(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 l(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 O(c,l,h,y,b,E,O){let k=e(`search`);c.registerTool(`search`,{title:k.title,description:`Search
|
|
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{basename as c}from"node:path";import{stat as l}from"node:fs/promises";import{z as u}from"zod";import{CONTENT_TYPES as d,KNOWLEDGE_ORIGINS as f,SOURCE_TYPES as p,computePartitionKey as m,createLogger as h,serializeError as g}from"../../../core/dist/index.js";import{bookendReorder as _,graphAugmentSearch as v,stashGet as y,truncateToTokenBudget as ee}from"../../../tools/dist/index.js";import{mergeResults as b}from"../../../enterprise-bridge/dist/index.js";const x=h(`tools`);function S(e){let t=[],n=c(process.cwd());n&&t.push(`[project: ${n}]`);let r=y(`__context_boost`);return r&&t.push(`[focus: ${r.value}]`),t.length===0?e:`${t.join(` `)} ${e}`}async function C(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:b(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 x.warn(`ER fallback failed`,g(e)),{results:n,triggered:!0,cacheHit:a}}}function te(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 w(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 T(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&&!E.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&&!E.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 E=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 D(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 l(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 O(c,l,h,y,b,E,O){let k=e(`search`);c.registerTool(`search`,{title:k.title,description:`Search AI Kit 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:u.string().max(5e3).describe(`Natural language search query`),limit:u.number().min(1).max(20).default(5).describe(`Maximum results to return`),search_mode:u.enum([`hybrid`,`semantic`,`keyword`]).default(`hybrid`).describe(`Search strategy: hybrid (vector + FTS + RRF fusion, default), semantic (vector only), keyword (FTS only)`),content_type:u.enum(d).optional().describe(`Filter by content type`),source_type:u.enum(p).optional().describe(`Coarse filter: "source" (code only), "documentation" (md, curated), "test", "config". Overrides content_type if both set.`),origin:u.enum(f).optional().describe(`Filter by knowledge origin`),category:u.string().optional().describe(`Filter by category (e.g., decisions, patterns, conventions)`),tags:u.array(u.string()).optional().describe(`Filter by tags (returns results matching ANY of the specified tags)`),min_score:u.number().min(0).max(1).default(.25).describe(`Minimum similarity score`),graph_hops:u.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:u.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),dedup:u.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:u.array(u.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:u,source_type:d,origin:f,category:p,tags:k,min_score:ne,graph_hops:A,max_tokens:j,dedup:M,workspaces:N})=>{try{let P={limit:t,minScore:ne,contentType:u,sourceType:d,origin:f,category:p,tags:k},F,I=!1,L=!1,R=``,z=S(e);if(c===`keyword`)F=await h.ftsSearch(e,P),F=F.slice(0,t);else if(c===`semantic`){let n=await l.embedQuery(z);F=await h.search(n,P);let r=await C(b,F[0]?.score??0,F,e,t);F=r.results,I=r.triggered,L=r.cacheHit}else{let n=await l.embedQuery(z),[r,i]=await Promise.all([h.search(n,{...P,limit:t*2}),h.ftsSearch(e,{...P,limit:t*2}).catch(()=>[])]);F=te(r,i).slice(0,t);let a=await C(b,r[0]?.score??0,F,e,t);F=a.results,I=a.triggered,L=a.cacheHit}E&&E.recordSearch(e,I,L),F.length>1&&(F=w(F,e));let B=``;if(N&&N.length>0){let o=a(N,m(process.cwd()));if(o.length>0){let{stores:a,closeAll:s}=await i(o);try{let i;i=c===`keyword`?await n(a,e,{...P,limit:t}):await r(a,await l.embedQuery(e),{...P,limit:t});for(let e of i)F.push({record:{...e.record,sourcePath:`[${e.workspace}] ${e.record.sourcePath}`},score:e.score});F=F.sort((e,t)=>t.score-e.score).slice(0,t),B=` + ${o.length} workspace(s)`}finally{await s()}}}if(M===`file`&&F.length>1){let e=new Map;for(let t of F){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}]})}F=[...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(F.length===0){if(O?.available)try{let t=(await O.createMessage({prompt:`The search query "${e}" returned 0 results in AI Kit code search. 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 AI Kit code search. Generate a single alternative query.`,maxTokens:100})).text.trim().split(`
|
|
2
2
|
`)[0].slice(0,500);if(t&&t!==e){let n=await l.embedQuery(t),r=await h.search(n,P);r.length>0&&(F=r,R=`> _Original query "${e}" returned 0 results. Auto-reformulated to "${t}"._\n\n`,x.info(`Smart search fallback succeeded`,{originalQuery:e,altQuery:t,resultCount:r.length}))}}catch(e){x.debug(`Smart search fallback failed`,{error:String(e)})}if(F.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(A>0&&!y&&(H="> **Note:** `graph_hops` was set but no graph store is available. Graph augmentation skipped."),A>0&&y)try{let e=await v(y,F.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:A,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(`
|
|
3
3
|
`),n=t.graphContext.edges.slice(0,5).map(e=>` - ${e.fromId} β[${e.type}]β ${e.toId}`).join(`
|
|
4
4
|
`),r=[`- **Graph Context** (${A} hop${A>1?`s`:``}):`];e&&r.push(` Entities:\n${e}`),n&&r.push(` Relationships:\n${n}`),V.set(t.recordId,r.join(`
|
|
@@ -12,7 +12,7 @@ declare function getScaffoldVersion(): string | null;
|
|
|
12
12
|
declare function getWorkspaceScaffoldVersion(): string | null;
|
|
13
13
|
/**
|
|
14
14
|
* Lightweight status tool registered during init β returns version info
|
|
15
|
-
* without needing the
|
|
15
|
+
* without needing the AI Kit store, graph, or curated manager.
|
|
16
16
|
*/
|
|
17
17
|
declare function registerEarlyStatusTool(server: McpServer): void;
|
|
18
18
|
declare function registerStatusTool(server: McpServer, store: IKnowledgeStore, graphStore?: IGraphStore, curated?: CuratedKnowledgeManager, onboardState?: OnboardState, config?: KBConfig): void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{getGcStatus as e}from"../auto-gc.js";import{getToolTelemetry as t}from"../replay-interceptor.js";import{getToolMeta as n}from"../tool-metadata.js";import{StatusOutputSchema as r}from"../output-schemas.js";import{autoUpgradeScaffold as i,getCurrentVersion as a,getUpgradeState as o}from"../version-check.js";import{existsSync as s,readFileSync as c,statSync as l}from"node:fs";import{resolve as u}from"node:path";import{AIKIT_PATHS as d,createLogger as f,serializeError as p}from"../../../core/dist/index.js";import{WasmRuntime as m}from"../../../chunker/dist/index.js";import{homedir as h}from"node:os";const g=f(`tools`);function _(e,t,n,r=4e3){let i,a=new Promise(e=>{i=setTimeout(()=>{g.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),g.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}function v(){try{let e=u(h(),`.copilot`,`.aikit-scaffold.json`);return s(e)?JSON.parse(c(e,`utf-8`)).version??null:null}catch{return null}}function y(){try{let e=u(process.cwd(),`.github`,`.aikit-scaffold.json`);return s(e)?JSON.parse(c(e,`utf-8`)).version??null:null}catch{return null}}function b(e){let t=n(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the
|
|
2
|
-
`)}],structuredContent:l}})}function x(c,f,h,b,x,S){let C=n(`status`);c.registerTool(`status`,{title:C.title,description:`Get the current status and statistics of the
|
|
1
|
+
import{getGcStatus as e}from"../auto-gc.js";import{getToolTelemetry as t}from"../replay-interceptor.js";import{getToolMeta as n}from"../tool-metadata.js";import{StatusOutputSchema as r}from"../output-schemas.js";import{autoUpgradeScaffold as i,getCurrentVersion as a,getUpgradeState as o}from"../version-check.js";import{existsSync as s,readFileSync as c,statSync as l}from"node:fs";import{resolve as u}from"node:path";import{AIKIT_PATHS as d,createLogger as f,serializeError as p}from"../../../core/dist/index.js";import{WasmRuntime as m}from"../../../chunker/dist/index.js";import{homedir as h}from"node:os";const g=f(`tools`);function _(e,t,n,r=4e3){let i,a=new Promise(e=>{i=setTimeout(()=>{g.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),g.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}function v(){try{let e=u(h(),`.copilot`,`.aikit-scaffold.json`);return s(e)?JSON.parse(c(e,`utf-8`)).version??null:null}catch{return null}}function y(){try{let e=u(process.cwd(),`.github`,`.aikit-scaffold.json`);return s(e)?JSON.parse(c(e,`utf-8`)).version??null:null}catch{return null}}function b(e){let t=n(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:t.annotations},async()=>{let e=a(),t=v(),n=y(),r=t!=null&&t!==e,s=n!=null&&n!==e,c=[`## AI Kit Status`,``,`β³ **AI Kit is initializing** β index stats will be available shortly.`,``,`### Runtime`,`- **Tree-sitter (WASM)**: ${m.get()?`β
Available (AST analysis)`:`β Unavailable (regex fallback)`}`,``,`### Version`,`- **Server**: ${e}`,`- **Scaffold (user)**: ${t??`not installed`}`,`- **Scaffold (workspace)**: ${n??`not installed`}`];if(r||s){let a=o(),l=[];r&&l.push(`user scaffold v${t}`),s&&l.push(`workspace scaffold v${n}`);let u=l.join(`, `);a.state===`success`?c.push(``,`### β
Upgrade Applied`,`- Server v${e} β ${u} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):a.state===`pending`?c.push(``,`### β³ Upgrade In Progress`,`- Server v${e} β ${u}`,`- Auto-upgrade is running in the backgroundβ¦`):a.state===`failed`?(i(),c.push(``,`### β¬ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${e} β ${u}`,`- Error: ${a.error??`unknown`}`)):(i(),c.push(``,`### β¬ Upgrade Available`,`- Server v${e} β ${u}`,`- Auto-upgrade triggered β check again shortly.`))}let l={totalRecords:0,totalFiles:0,lastIndexedAt:null,onboarded:!1,onboardDir:``,contentTypes:{},wasmAvailable:!!m.get(),graphStats:null,curatedCount:0,serverVersion:e,scaffoldVersion:t??null,workspaceScaffoldVersion:n??null,upgradeAvailable:r||s};return{content:[{type:`text`,text:c.join(`
|
|
2
|
+
`)}],structuredContent:l}})}function x(c,f,h,b,x,S){let C=n(`status`);c.registerTool(`status`,{title:C.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:C.annotations},async()=>{let n=[];try{let r=await _(f.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),c=r.value;r.timedOut&&n.push(`β Index stats timed out β values may be incomplete`);let p=await _(f.listSourcePaths(),[],`store.listSourcePaths`),g=p.value;p.timedOut&&n.push(`β File listing timed out`);let C=null,w=0,T=[`## AI Kit Status`,``,`- **Total Records**: ${c.totalRecords}`,`- **Total Files**: ${c.totalFiles}`,`- **Last Indexed**: ${c.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(c.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...g.slice(0,50).map(e=>`- ${e}`),g.length>50?`\n... and ${g.length-50} more files`:``];if(h)try{let e=await _(h.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(e.timedOut)n.push(`β Graph stats timed out`),T.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let t=e.value;C={nodes:t.nodeCount,edges:t.edgeCount},T.push(``,`### Knowledge Graph`,`- **Nodes**: ${t.nodeCount}`,`- **Edges**: ${t.edgeCount}`,...Object.entries(t.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await _(h.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||T.push(`- **β Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&T.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{T.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let E=S?.onboardDir??u(process.cwd(),d.aiKb),D=s(E),O=x?.onboardComplete??D;if(T.push(``,`### Onboard Status`,O?`- β
Complete${x?.onboardTimestamp?` (last: ${x.onboardTimestamp})`:``}`:'- β Not run β call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${E}\``),b)try{let e=await _(b.list(),[],`curated.list`);if(e.timedOut)n.push(`β Curated knowledge listing timed out`),T.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let t=e.value;w=t.length,T.push(``,`### Curated Knowledge`,t.length>0?`- ${t.length} entries`:"- Empty β use `remember()` to persist decisions")}}catch{T.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let k=0;if(c.lastIndexedAt){k=new Date(c.lastIndexedAt).getTime();let e=(Date.now()-k)/(1e3*60*60);T.push(``,`### Index Freshness`,e>24?`- β Last indexed ${Math.floor(e)}h ago β may be stale. Run \`reindex({})\``:`- β
Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}{try{let e=u(process.cwd(),d.data,`stash`);if(s(e)){let t=l(e).mtimeMs;t>k&&(k=t)}}catch{}let e=[];if(b)try{let t=w>0?await b.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>k&&(k=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=k>0?Date.now()-k:0;if(t>=144e5){let n=Math.floor(t/36e5);if(T.push(``,`### π
Session Briefing`,`_${n}+ hours since last activity β here's what to pick up:_`,``),e.length>0){T.push(`**Recent decisions/notes:**`);for(let t of e)T.push(`- **${t.title}** (${t.category??`note`}) β ${(t.contentPreview??``).slice(0,80)}β¦`)}T.push(``,`**Suggested next steps:**`,'- `search({ query: "SESSION CHECKPOINT", origin: "curated" })` β find your last checkpoint',"- `restore({})` β resume from a saved checkpoint","- `list()` β browse all stored knowledge")}}T.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${m.get()?`β
Available (AST analysis)`:`β Unavailable (regex fallback)`}`);let A=v(),j=y(),M=a(),N=A!=null&&A!==M,P=j!=null&&j!==M;if(N||P){let e=o(),t=[];N&&t.push(`user scaffold v${A}`),P&&t.push(`workspace scaffold v${j}`);let n=t.join(`, `);e.state===`success`?T.push(``,`### β
Upgrade Applied`,`- Server v${M} β ${n} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?T.push(``,`### β³ Upgrade In Progress`,`- Server v${M} β ${n}`,`- Auto-upgrade is running in the backgroundβ¦`):e.state===`failed`?(i(),T.push(``,`### β¬ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${M} β ${n}`,`- Error: ${e.error??`unknown`}`)):(i(),T.push(``,`### β¬ Upgrade Available`,`- Server v${M} β ${n}`,`- Auto-upgrade triggered β check again shortly.`))}n.length>0&&T.push(``,`### β Warnings`,...n.map(e=>`- ${e}`));let F=t();if(F.length>0){let e=F.sort((e,t)=>t.callCount-e.callCount);T.push(``,`### Tool Usage This Session`,``),T.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),T.push(`|------|-------|-----------|------------|--------|-------------|`);for(let t of e.slice(0,15)){let e=Math.round(t.totalInputChars/4),n=Math.round(t.totalOutputChars/4),r=Math.round(t.totalDurationMs/t.callCount);T.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let I=e();if(I.bufferSize>=10){let e=I.state===`healthy`?`π’`:I.state===`degraded`?`π΄`:`π‘`;T.push(``,`### Auto-GC: ${e} ${I.state}`),T.push(`- p95 latency: ${I.p95}ms | buffer: ${I.bufferSize} samples`),I.gcCount>0&&T.push(`- GC cycles triggered: ${I.gcCount}`)}let L=T.join(`
|
|
3
3
|
`),R={totalRecords:c.totalRecords,totalFiles:c.totalFiles,lastIndexedAt:c.lastIndexedAt??null,onboarded:O,onboardDir:E,contentTypes:c.contentTypeBreakdown,wasmAvailable:!!m.get(),graphStats:C,curatedCount:w,serverVersion:M,scaffoldVersion:A??null,workspaceScaffoldVersion:j??null,upgradeAvailable:N||P};return{content:[{type:`text`,text:L+"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._"}],structuredContent:R}}catch(e){return g.error(`Status failed`,p(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{v as getScaffoldVersion,y as getWorkspaceScaffoldVersion,b as registerEarlyStatusTool,x as registerStatusTool};
|
|
@@ -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{
|
|
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{resolveStateDir as o}from"../../core/dist/index.js";function s(r){let i=e(o(r??process.cwd()),`checkpoints`);return t(i)||n(i,{recursive:!0}),i}function c(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(s(r?.cwd),`${o.id}.json`),`${JSON.stringify(o,null,2)}\n`,`utf-8`),o}function l(n,i){let a=s(i),o=e(a,`${n}.json`);if(o.startsWith(e(a))&&t(o))try{return JSON.parse(r(o,`utf-8`))}catch{return}}function u(t){let n=s(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 d(e){return u(e)[0]}export{d as checkpointLatest,u as checkpointList,l as checkpointLoad,c as checkpointSave};
|
|
@@ -1,4 +1,4 @@
|
|
|
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=/
|
|
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=/aikit\.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
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
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
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(`
|
|
@@ -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{
|
|
2
|
-
`)}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{resolveStateDir as o}from"../../core/dist/index.js";function s(e){return t(o(e??process.cwd()),`evidence-maps.json`)}function c(e){let t=s(e);if(!n(t))return{};try{let e=i(t,`utf-8`);return JSON.parse(e)}catch{return{}}}function l(t,i){let o=s(i),c=e(o);n(c)||r(c,{recursive:!0}),a(o,`${JSON.stringify(t,null,2)}\n`,`utf-8`)}function u(e,t){let n=c(t),r=n[e];if(!r)throw Error(`Evidence map not found: ${e}`);return{maps:n,state:r}}function d(e){return e.reduce((e,t)=>Math.max(e,t.id),0)+1}function f(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 p(e){return(e??``).replace(/\r?\n/g,` `).replace(/\|/g,`\\|`)}function m(e){let t=[`| # | Claim | Status | Receipt | Critical | Type | Safety |`,`|---|-------|--------|---------|----------|------|--------|`];for(let n of e.entries)t.push(`| ${n.id} | ${p(n.claim)} | ${n.status} | ${p(n.receipt)} | ${n.criticalPath?`yes`:`no`} | ${p(n.unknownType)} | ${p(n.safetyGate)} |`);return t.join(`
|
|
2
|
+
`)}function h(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 g(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 _(e){return`FORCED DELIVERY annotation: unresolved entries remain -> ${e.filter(e=>e.status===`U`).map(e=>`#${e.id} ${e.claim}`).join(`; `)}`}function v(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 y(e,t=0){let n=e.entries.filter(e=>e.criticalPath&&e.status===`U`),r=g(e),i=h(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:_(e.entries)}:{decision:`YIELD`,reason:`All critical-path claims satisfy gate rules`,unresolvedCritical:[],warnings:r,stats:i,...b(e,r,i)}}function b(e,t,n){if(!e.entries.some(e=>e.safetyGate)||e.tier===`floor`)return{};let r=v(e);return r.failures.length>0?{safetyGates:r,decision:`HOLD`,reason:`Safety gate failure: ${r.failures.join(`; `)}`,warnings:[...t,...r.failures]}:{safetyGates:r}}function x(e,t){switch(e.action){case`create`:{let n=c(t),r=new Date().toISOString(),i={taskId:e.taskId,tier:e.tier,entries:[],createdAt:r,updatedAt:r};return n[e.taskId]=i,l(n,t),{state:i,formattedMap:m(i)}}case`add`:{let{maps:n,state:r}=u(e.taskId,t),i={id:d(r.entries),claim:f(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,l(n,t),{state:r,entry:i,formattedMap:m(r)}}case`update`:{let{maps:n,state:r}=u(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,l(n,t),{state:r,entry:i,formattedMap:m(r)}}case`get`:{let{state:n}=u(e.taskId,t);return{state:n,formattedMap:m(n)}}case`gate`:{let{state:n}=u(e.taskId,t);return{state:n,gate:y(n,e.retryCount??0),formattedMap:m(n)}}case`list`:return{states:Object.values(c(t)).sort((e,t)=>e.createdAt.localeCompare(t.createdAt))};case`delete`:{let n=c(t);return e.taskId in n?(delete n[e.taskId],l(n,t),{deleted:!0}):{deleted:!1}}}}function S(e,t,n){let r=[];for(let i of t){let t=x({action:`add`,taskId:e,claim:`Test failure: ${i}`,status:`U`,receipt:``,criticalPath:!0},n);t.entry&&r.push(t.entry)}return r}export{S as autoClaimTestFailures,x as evidenceMap};
|
|
@@ -24,7 +24,7 @@ interface FindResult {
|
|
|
24
24
|
source: 'vector' | 'keyword' | 'glob' | 'pattern';
|
|
25
25
|
/** Relevance score (0-1 for vector/keyword, 1 for glob/pattern matches) */
|
|
26
26
|
score: number;
|
|
27
|
-
/** Line range if from
|
|
27
|
+
/** Line range if from AI Kit search */
|
|
28
28
|
lineRange?: {
|
|
29
29
|
start: number;
|
|
30
30
|
end: number;
|
|
@@ -33,7 +33,7 @@ interface ForgeGroundResult {
|
|
|
33
33
|
scopeMap: ScopeMapResult | null;
|
|
34
34
|
/** Typed Unknown Queue seeds */
|
|
35
35
|
typedUnknownSeeds: TypedUnknownSeed[];
|
|
36
|
-
/** Constraint seed β relevant
|
|
36
|
+
/** Constraint seed β relevant AI Kit entries from decisions/patterns */
|
|
37
37
|
constraints: ConstraintRef[];
|
|
38
38
|
/** File summaries for target files */
|
|
39
39
|
fileSummaries: Array<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=[{name:`onboard`,description:`First-time codebase exploration and understanding`,keywords:[`onboard`,`new project`,`understand`,`explore`,`first time`,`getting started`,`learn`,`overview`],tools:[{tool:`status`,reason:`Check index health and record count`,order:1},{tool:`onboard`,reason:`Run all analysis tools in one command`,order:2,suggestedArgs:{path:`.`}},{tool:`search`,reason:`Find specific topics of interest`,order:3},{tool:`graph`,reason:`Explore module relationships`,order:4,suggestedArgs:{action:`stats`}}]},{name:`audit`,description:`Assess project health, quality, and structure`,keywords:[`audit`,`health`,`quality`,`assess`,`review project`,`check quality`,`code quality`,`tech debt`],tools:[{tool:`status`,reason:`Check index freshness`,order:1},{tool:`audit`,reason:`Unified audit report with score and recommendations`,order:2,suggestedArgs:{detail:`summary`}},{tool:`check`,reason:`Typecheck + lint validation`,order:3},{tool:`health`,reason:`Detailed health checks on package.json, tsconfig, etc.`,order:4}]},{name:`bugfix`,description:`Diagnose and fix a bug or failing test`,keywords:[`bug`,`fix`,`debug`,`error`,`failing`,`broken`,`crash`,`wrong`,`issue`,`problem`,`not working`],tools:[{tool:`parse_output`,reason:`Parse error output from build tools (tsc, vitest, biome)`,order:1},{tool:`symbol`,reason:`Find definition and all references of the failing symbol`,order:2},{tool:`trace`,reason:`Trace call chain backward from the failure point`,order:3,suggestedArgs:{direction:`backward`}},{tool:`search`,reason:`Search for related patterns or similar fixes`,order:4},{tool:`test_run`,reason:`Re-run tests after fix`,order:5}]},{name:`implement`,description:`Add a new feature or implement a change`,keywords:[`implement`,`add feature`,`new feature`,`build`,`create`,`add`,`develop`,`write code`],tools:[{tool:`scope_map`,reason:`Generate a reading plan for affected files`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2},{tool:`find`,reason:`Find usage examples of similar patterns`,order:3,suggestedArgs:{mode:`examples`}},{tool:`check`,reason:`Validate after implementation`,order:4},{tool:`test_run`,reason:`Run tests to verify`,order:5},{tool:`blast_radius`,reason:`Check impact of changes`,order:6}]},{name:`refactor`,description:`Restructure or clean up existing code`,keywords:[`refactor`,`restructure`,`clean up`,`reorganize`,`rename`,`move`,`extract`,`DRY`,`dead code`],tools:[{tool:`dead_symbols`,reason:`Find unused exports to remove`,order:1},{tool:`symbol`,reason:`Find all references before renaming`,order:2},{tool:`blast_radius`,reason:`Assess impact before making changes`,order:3},{tool:`rename`,reason:`Safe cross-file rename`,order:4},{tool:`check`,reason:`Validate after refactoring`,order:5},{tool:`test_run`,reason:`Ensure no regressions`,order:6}]},{name:`search`,description:`Find specific code, patterns, or information`,keywords:[`find`,`search`,`where`,`locate`,`look for`,`grep`,`which file`,`how does`],tools:[{tool:`search`,reason:`Hybrid semantic + keyword search`,order:1},{tool:`find`,reason:`Federated search with glob and regex`,order:2},{tool:`symbol`,reason:`Resolve a specific symbol definition and references`,order:3},{tool:`graph`,reason:`Explore entity relationships`,order:4,suggestedArgs:{action:`neighbors`}}]},{name:`context`,description:`Compress or manage context for efficient LLM interaction`,keywords:[`context`,`compress`,`summarize`,`too long`,`token`,`budget`,`reduce`,`compact`],tools:[{tool:`file_summary`,reason:`Quick structural overview without reading full file`,order:1},{tool:`compact`,reason:`Compress file to relevant sections`,order:2,suggestedArgs:{segmentation:`paragraph`}},{tool:`digest`,reason:`Compress multiple sources into budgeted summary`,order:3},{tool:`stratum_card`,reason:`Generate reusable context cards`,order:4}]},{name:`memory`,description:`Manage persistent knowledge across sessions`,keywords:[`memory`,`remember`,`persist`,`save`,`recall`,`decision`,`convention`,`session`,`checkpoint`],tools:[{tool:`list`,reason:`See all stored knowledge entries`,order:1},{tool:`search`,reason:`Search curated knowledge`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Store a new decision or pattern`,order:3},{tool:`checkpoint`,reason:`Save/restore session progress`,order:4},{tool:`stash`,reason:`Temporary key-value storage within session`,order:5}]},{name:`validate`,description:`Run checks, tests, and validation`,keywords:[`validate`,`check`,`test`,`lint`,`typecheck`,`verify`,`CI`,`pass`,`run tests`],tools:[{tool:`check`,reason:`Typecheck + lint in one call`,order:1,suggestedArgs:{detail:`errors`}},{tool:`test_run`,reason:`Run tests with structured output`,order:2},{tool:`health`,reason:`Project health assessment`,order:3}]},{name:`analyze`,description:`Deep analysis of codebase structure, dependencies, or patterns`,keywords:[`analyze`,`dependency`,`structure`,`pattern`,`architecture`,`diagram`,`entry point`,`import`],tools:[{tool:`analyze_structure`,reason:`Project structure overview`,order:1},{tool:`analyze_dependencies`,reason:`Dependency graph and analysis`,order:2},{tool:`analyze_patterns`,reason:`Detect code patterns and conventions`,order:3},{tool:`analyze_entry_points`,reason:`Find handlers, exports, and entry points`,order:4},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams`,order:5}]},{name:`upgrade`,description:`Update
|
|
1
|
+
const e=[{name:`onboard`,description:`First-time codebase exploration and understanding`,keywords:[`onboard`,`new project`,`understand`,`explore`,`first time`,`getting started`,`learn`,`overview`],tools:[{tool:`status`,reason:`Check index health and record count`,order:1},{tool:`onboard`,reason:`Run all analysis tools in one command`,order:2,suggestedArgs:{path:`.`}},{tool:`search`,reason:`Find specific topics of interest`,order:3},{tool:`graph`,reason:`Explore module relationships`,order:4,suggestedArgs:{action:`stats`}}]},{name:`audit`,description:`Assess project health, quality, and structure`,keywords:[`audit`,`health`,`quality`,`assess`,`review project`,`check quality`,`code quality`,`tech debt`],tools:[{tool:`status`,reason:`Check index freshness`,order:1},{tool:`audit`,reason:`Unified audit report with score and recommendations`,order:2,suggestedArgs:{detail:`summary`}},{tool:`check`,reason:`Typecheck + lint validation`,order:3},{tool:`health`,reason:`Detailed health checks on package.json, tsconfig, etc.`,order:4}]},{name:`bugfix`,description:`Diagnose and fix a bug or failing test`,keywords:[`bug`,`fix`,`debug`,`error`,`failing`,`broken`,`crash`,`wrong`,`issue`,`problem`,`not working`],tools:[{tool:`parse_output`,reason:`Parse error output from build tools (tsc, vitest, biome)`,order:1},{tool:`symbol`,reason:`Find definition and all references of the failing symbol`,order:2},{tool:`trace`,reason:`Trace call chain backward from the failure point`,order:3,suggestedArgs:{direction:`backward`}},{tool:`search`,reason:`Search for related patterns or similar fixes`,order:4},{tool:`test_run`,reason:`Re-run tests after fix`,order:5}]},{name:`implement`,description:`Add a new feature or implement a change`,keywords:[`implement`,`add feature`,`new feature`,`build`,`create`,`add`,`develop`,`write code`],tools:[{tool:`scope_map`,reason:`Generate a reading plan for affected files`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2},{tool:`find`,reason:`Find usage examples of similar patterns`,order:3,suggestedArgs:{mode:`examples`}},{tool:`check`,reason:`Validate after implementation`,order:4},{tool:`test_run`,reason:`Run tests to verify`,order:5},{tool:`blast_radius`,reason:`Check impact of changes`,order:6}]},{name:`refactor`,description:`Restructure or clean up existing code`,keywords:[`refactor`,`restructure`,`clean up`,`reorganize`,`rename`,`move`,`extract`,`DRY`,`dead code`],tools:[{tool:`dead_symbols`,reason:`Find unused exports to remove`,order:1},{tool:`symbol`,reason:`Find all references before renaming`,order:2},{tool:`blast_radius`,reason:`Assess impact before making changes`,order:3},{tool:`rename`,reason:`Safe cross-file rename`,order:4},{tool:`check`,reason:`Validate after refactoring`,order:5},{tool:`test_run`,reason:`Ensure no regressions`,order:6}]},{name:`search`,description:`Find specific code, patterns, or information`,keywords:[`find`,`search`,`where`,`locate`,`look for`,`grep`,`which file`,`how does`],tools:[{tool:`search`,reason:`Hybrid semantic + keyword search`,order:1},{tool:`find`,reason:`Federated search with glob and regex`,order:2},{tool:`symbol`,reason:`Resolve a specific symbol definition and references`,order:3},{tool:`graph`,reason:`Explore entity relationships`,order:4,suggestedArgs:{action:`neighbors`}}]},{name:`context`,description:`Compress or manage context for efficient LLM interaction`,keywords:[`context`,`compress`,`summarize`,`too long`,`token`,`budget`,`reduce`,`compact`],tools:[{tool:`file_summary`,reason:`Quick structural overview without reading full file`,order:1},{tool:`compact`,reason:`Compress file to relevant sections`,order:2,suggestedArgs:{segmentation:`paragraph`}},{tool:`digest`,reason:`Compress multiple sources into budgeted summary`,order:3},{tool:`stratum_card`,reason:`Generate reusable context cards`,order:4}]},{name:`memory`,description:`Manage persistent knowledge across sessions`,keywords:[`memory`,`remember`,`persist`,`save`,`recall`,`decision`,`convention`,`session`,`checkpoint`],tools:[{tool:`list`,reason:`See all stored knowledge entries`,order:1},{tool:`search`,reason:`Search curated knowledge`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Store a new decision or pattern`,order:3},{tool:`checkpoint`,reason:`Save/restore session progress`,order:4},{tool:`stash`,reason:`Temporary key-value storage within session`,order:5}]},{name:`validate`,description:`Run checks, tests, and validation`,keywords:[`validate`,`check`,`test`,`lint`,`typecheck`,`verify`,`CI`,`pass`,`run tests`],tools:[{tool:`check`,reason:`Typecheck + lint in one call`,order:1,suggestedArgs:{detail:`errors`}},{tool:`test_run`,reason:`Run tests with structured output`,order:2},{tool:`health`,reason:`Project health assessment`,order:3}]},{name:`analyze`,description:`Deep analysis of codebase structure, dependencies, or patterns`,keywords:[`analyze`,`dependency`,`structure`,`pattern`,`architecture`,`diagram`,`entry point`,`import`],tools:[{tool:`analyze_structure`,reason:`Project structure overview`,order:1},{tool:`analyze_dependencies`,reason:`Dependency graph and analysis`,order:2},{tool:`analyze_patterns`,reason:`Detect code patterns and conventions`,order:3},{tool:`analyze_entry_points`,reason:`Find handlers, exports, and entry points`,order:4},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams`,order:5}]},{name:`upgrade`,description:`Update AI Kit agents, prompts, skills, and scaffold to the latest version (user-level and workspace-level)`,keywords:[`upgrade`,`update`,`version`,`scaffold`,`outdated`,`mismatch`,`deploy`,`install`,`refresh`],tools:[{tool:`status`,reason:`Check current versions and detect mismatches β auto-triggers upgrade when a version mismatch is found`,order:1},{tool:`reindex`,reason:`Refresh the index after the upgrade completes`,order:2},{tool:`produce_knowledge`,reason:`Regenerate codebase analysis with updated tooling`,order:3,suggestedArgs:{path:`.`}}]}];function t(t,n=5){let r=t.toLowerCase(),i=e.map(e=>{let t=0;for(let n of e.keywords)r.includes(n)&&(t+=n.includes(` `)?2:1);return{workflow:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score),a=e.find(e=>e.name===`search`)??e[0],o=i[0]?.workflow??a,s=i.slice(1,4).map(e=>e.workflow.name).filter(e=>e!==o.name);return{workflow:o.name,description:o.description,tools:o.tools.slice(0,n),alternativeWorkflows:s}}export{t as guide};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{join as e,relative as t,resolve as n}from"node:path";import{cpSync as r,existsSync as i,mkdirSync as a,readFileSync as o,readdirSync as s,rmSync as c,statSync as l,writeFileSync as u}from"node:fs";import{
|
|
1
|
+
import{join as e,relative as t,resolve as n}from"node:path";import{cpSync as r,existsSync as i,mkdirSync as a,readFileSync as o,readdirSync as s,rmSync as c,statSync as l,writeFileSync as u}from"node:fs";import{resolveStateDir as d}from"../../core/dist/index.js";function f(e){return n(d(e??process.cwd()),`lanes`)}const p=`.lane-meta.json`;function m(e){return f(e)}function h(e,t){let r=m(t),i=n(r,e);if(!i.startsWith(n(r)))throw Error(`Invalid lane name: "${e}"`);return i}function g(t,n){let r=e(h(t,n),p);if(!i(r))throw Error(`Lane "${t}" does not exist`);try{return JSON.parse(o(r,`utf-8`))}catch{throw Error(`Lane "${t}" has corrupted metadata`)}}function _(o,s,c){let l=c??process.cwd(),d=h(o,c);if(i(d))throw Error(`Lane "${o}" already exists`);a(d,{recursive:!0});let f=[];for(let o of s){let s=n(l,o);if(!i(s))throw Error(`Source file does not exist: ${o}`);let c=t(l,s).replace(/\\/g,`/`),u=e(d,c);a(e(u,`..`),{recursive:!0}),r(s,u),f.push(c)}let m={name:o,createdAt:new Date().toISOString(),sourceFiles:f,rootPath:l};return u(e(d,p),`${JSON.stringify(m,null,2)}\n`,`utf-8`),m}function v(t){let n=m(t);if(!i(n))return[];let r=s(n),a=[];for(let t of r){let r=e(n,t,p);if(i(r))try{a.push(JSON.parse(o(r,`utf-8`)))}catch{}}return a}function y(t,r){let a=g(t,r),s=h(t,r),c=a.rootPath,l=[];for(let t of a.sourceFiles){let r=n(c,t),a=e(s,t);if(!i(a)){l.push({file:t,status:`deleted`});continue}if(!i(r)){l.push({file:t,status:`added`});continue}o(r,`utf-8`)===o(a,`utf-8`)?l.push({file:t,status:`unchanged`}):l.push({file:t,status:`modified`})}let u=C(s);for(let e of u)a.sourceFiles.includes(e)||l.push({file:e,status:`added`});return{name:t,entries:l,modified:l.filter(e=>e.status===`modified`).length,added:l.filter(e=>e.status===`added`).length,deleted:l.filter(e=>e.status===`deleted`).length}}function b(t,r){let a=g(t,r),s=h(t,r),c=a.rootPath,l=[],u=new Set(a.sourceFiles);for(let e of C(s))u.add(e);for(let t of u){let r=n(c,t),a=e(s,t),u=i(r),d=i(a);if(!d&&u){l.push({file:t,status:`deleted`});continue}if(d&&!u){let e=o(a,`utf-8`);l.push({file:t,status:`added`,diff:e.split(`
|
|
2
2
|
`).map(e=>`+${e}`).join(`
|
|
3
3
|
`)});continue}if(!d||!u)continue;let f=o(r,`utf-8`),p=o(a,`utf-8`);f===p?l.push({file:t,status:`unchanged`}):l.push({file:t,status:`modified`,diff:w(f,p)})}return{name:t,entries:l,modified:l.filter(e=>e.status===`modified`).length,added:l.filter(e=>e.status===`added`).length,deleted:l.filter(e=>e.status===`deleted`).length}}function x(t,o){let s=g(t,o),l=h(t,o),u=s.rootPath,d=[],f=new Set(s.sourceFiles);for(let e of C(l))f.add(e);for(let t of f){let o=e(l,t);if(!i(o))continue;let s=n(u,t);a(e(s,`..`),{recursive:!0}),r(o,s),d.push(t)}return c(l,{recursive:!0,force:!0}),{name:t,filesMerged:d.length,files:d}}function S(e,t){let n=h(e,t);return i(n)?(c(n,{recursive:!0,force:!0}),!0):!1}function C(n){let r=[];function a(i){for(let o of s(i)){if(o===p)continue;let s=e(i,o);l(s).isDirectory()?a(s):r.push(t(n,s).replace(/\\/g,`/`))}}return i(n)&&a(n),r.sort()}function w(e,t){let n=e.split(`
|
|
4
4
|
`),r=t.split(`
|