@vpxa/aikit 0.1.33 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpxa/aikit",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "type": "module",
5
5
  "description": "Local-first AI developer toolkit — knowledge base, code analysis, context management, and developer tools for LLM agents",
6
6
  "license": "MIT",
@@ -13,6 +13,7 @@ declare class OnnxEmbedder implements IEmbedder {
13
13
  });
14
14
  private detectQueryPrefix;
15
15
  initialize(): Promise<void>;
16
+ private isCorruptionError;
16
17
  shutdown(): Promise<void>;
17
18
  embed(text: string): Promise<Float32Array>;
18
19
  embedQuery(query: string): Promise<Float32Array>;
@@ -1 +1 @@
1
- import{homedir as e}from"node:os";import{join as t}from"node:path";import{EMBEDDING_DEFAULTS as n}from"../../core/dist/index.js";import{env as r,pipeline as i}from"@huggingface/transformers";r.cacheDir=t(e(),`.cache`,`huggingface`,`transformers-js`);var a=class{pipe=null;dimensions;modelId;queryPrefix;constructor(e){this.modelId=e?.model??n.model,this.dimensions=e?.dimensions??n.dimensions,this.queryPrefix=e?.queryPrefix??this.detectQueryPrefix(this.modelId)}detectQueryPrefix(e){let t=e.toLowerCase();return t.includes(`bge`)||t.includes(`mxbai-embed`)?`Represent this sentence for searching relevant passages: `:t.includes(`/e5-`)||t.includes(`multilingual-e5`)?`query: `:``}async initialize(){if(!this.pipe)try{this.pipe=await i(`feature-extraction`,this.modelId,{dtype:`q8`})}catch(e){throw Error(`Failed to initialize embedding model "${this.modelId}": ${e.message}`)}}async shutdown(){this.pipe=null}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t)throw Error(`Embedding pipeline returned no output`);return new Float32Array(t.data)}async embedQuery(e){return this.embed(this.queryPrefix+e)}async embedBatch(e,t=64){if(e.length===0)return[];this.pipe||await this.initialize();let n=[];for(let r=0;r<e.length;r+=t){let i=e.slice(r,r+t),a=await this.pipe?.(i,{pooling:`mean`,normalize:!0});if(!a)throw Error(`Embedding pipeline returned no output`);if(i.length===1)n.push(new Float32Array(a.data));else for(let e=0;e<i.length;e++){let t=e*this.dimensions,r=a.data.slice(t,t+this.dimensions);n.push(new Float32Array(r))}}return n}};export{a as OnnxEmbedder};
1
+ import{rm as e}from"node:fs/promises";import{homedir as t}from"node:os";import{join as n}from"node:path";import{EMBEDDING_DEFAULTS as r}from"../../core/dist/index.js";import{env as i,pipeline as a}from"@huggingface/transformers";i.cacheDir=n(t(),`.cache`,`huggingface`,`transformers-js`);var o=class{pipe=null;dimensions;modelId;queryPrefix;constructor(e){this.modelId=e?.model??r.model,this.dimensions=e?.dimensions??r.dimensions,this.queryPrefix=e?.queryPrefix??this.detectQueryPrefix(this.modelId)}detectQueryPrefix(e){let t=e.toLowerCase();return t.includes(`bge`)||t.includes(`mxbai-embed`)?`Represent this sentence for searching relevant passages: `:t.includes(`/e5-`)||t.includes(`multilingual-e5`)?`query: `:``}async initialize(){if(!this.pipe)try{this.pipe=await a(`feature-extraction`,this.modelId,{dtype:`q8`})}catch(r){let o=r.message?.toLowerCase()??``;if(this.isCorruptionError(o)){let r=n(i.cacheDir??n(t(),`.cache`,`huggingface`,`transformers-js`),this.modelId);console.error(`[aikit:auto-heal] Detected corrupted model cache for "${this.modelId}". Clearing cache at ${r} and retrying download...`);try{await e(r,{recursive:!0,force:!0})}catch{}try{this.pipe=await a(`feature-extraction`,this.modelId,{dtype:`q8`}),console.error(`[aikit:auto-heal] Model "${this.modelId}" re-downloaded successfully.`);return}catch(e){throw Error(`Failed to initialize embedding model "${this.modelId}" after auto-heal: ${e.message}`)}}throw Error(`Failed to initialize embedding model "${this.modelId}": ${r.message}`)}}isCorruptionError(e){return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`checksum`,`corrupt`,`could not load`,`onnx`,`malformed`].some(t=>e.includes(t))}async shutdown(){this.pipe=null}async embed(e){this.pipe||await this.initialize();let t=await this.pipe?.(e,{pooling:`mean`,normalize:!0});if(!t)throw Error(`Embedding pipeline returned no output`);return new Float32Array(t.data)}async embedQuery(e){return this.embed(this.queryPrefix+e)}async embedBatch(e,t=64){if(e.length===0)return[];this.pipe||await this.initialize();let n=[];for(let r=0;r<e.length;r+=t){let i=e.slice(r,r+t),a=await this.pipe?.(i,{pooling:`mean`,normalize:!0});if(!a)throw Error(`Embedding pipeline returned no output`);if(i.length===1)n.push(new Float32Array(a.data));else for(let e=0;e<i.length;e++){let t=e*this.dimensions,r=a.data.slice(t,t+this.dimensions);n.push(new Float32Array(r))}}return n}};export{o as OnnxEmbedder};
@@ -46,7 +46,7 @@ declare function createServer(config: KBConfig): Promise<{
46
46
  runInitialIndex: () => Promise<void>;
47
47
  shutdown: () => Promise<void>;
48
48
  }>;
49
- declare const ALL_TOOL_NAMES: readonly ["analyze_dependencies", "analyze_diagram", "analyze_entry_points", "analyze_patterns", "analyze_structure", "analyze_symbols", "audit", "batch", "blast_radius", "brainstorm", "changelog", "check", "checkpoint", "codemod", "compact", "config", "data_transform", "dead_symbols", "delegate", "diff_parse", "digest", "encode", "env", "eval", "evidence_map", "file_summary", "find", "flow_info", "flow_list", "flow_reset", "flow_start", "flow_status", "flow_step", "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"];
49
+ declare const ALL_TOOL_NAMES: readonly ["analyze_dependencies", "analyze_diagram", "analyze_entry_points", "analyze_patterns", "analyze_structure", "analyze_symbols", "audit", "batch", "blast_radius", "brainstorm", "changelog", "check", "checkpoint", "codemod", "compact", "config", "data_transform", "dead_symbols", "delegate", "diff_parse", "digest", "encode", "env", "eval", "evidence_map", "file_summary", "find", "flow_info", "flow_list", "flow_reset", "flow_start", "flow_status", "flow_step", "flow_add", "flow_update", "flow_remove", "flow_read_instruction", "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"];
50
50
  declare function createLazyServer(config: KBConfig, indexMode?: string): {
51
51
  server: McpServer; /** Call after MCP roots are resolved (or fallback decided) to start heavy init. */
52
52
  startInit: () => void;
@@ -1,3 +1,3 @@
1
- import{BackgroundTaskScheduler as e}from"./background-task.js";import{clearCompletionCache as t}from"./completions.js";import{installCompressionInterceptor as n}from"./compression-interceptor.js";import{CuratedKnowledgeManager as r}from"./curated-manager.js";import{createElicitor as i,noopElicitor as a}from"./elicitor.js";import{IdleTimer as o}from"./idle-timer.js";import{bridgeMcpLogging as s}from"./mcp-logging.js";import{MemoryMonitor as c}from"./memory-monitor.js";import{registerPrompts as l}from"./prompts.js";import{installReplayInterceptor as u}from"./replay-interceptor.js";import{ResourceNotifier as d}from"./resources/resource-notifier.js";import{registerResources as f}from"./resources/resources.js";import{createSamplingClient as p}from"./sampling.js";import{installStructuredContentGuard as m}from"./structured-content-guard.js";import{getToolMeta as h}from"./tool-metadata.js";import{installToolPrefix as g}from"./tool-prefix.js";import{ToolTimeoutError as _,getToolTimeout as v,withTimeout as ee}from"./tool-timeout.js";import{registerAnalyzeDependenciesTool as y,registerAnalyzeDiagramTool as b,registerAnalyzeEntryPointsTool as x,registerAnalyzePatternsTool as te,registerAnalyzeStructureTool as S,registerAnalyzeSymbolsTool as C,registerBlastRadiusTool as w}from"./tools/analyze.tools.js";import{registerAuditTool as ne}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 re}from"./tools/bridge.tools.js";import{registerConfigTool as k}from"./tools/config.tool.js";import{registerCompactTool as A,registerDeadSymbolsTool as j,registerFileSummaryTool as M,registerFindTool as ie,registerScopeMapTool as N,registerSymbolTool as P,registerTraceTool as ae}from"./tools/context.tools.js";import{registerErEvolveReviewTool as oe}from"./tools/evolution.tools.js";import{registerBatchTool as se,registerCheckTool as F,registerDelegateTool as I,registerEvalTool as L,registerParseOutputTool as R,registerTestRunTool as z}from"./tools/execution.tools.js";import{registerFlowTools as ce}from"./tools/flow.tools.js";import{registerDigestTool as le,registerEvidenceMapTool as B,registerForgeClassifyTool as V,registerForgeGroundTool as ue,registerStratumCardTool as de}from"./tools/forge.tools.js";import{registerForgetTool as fe}from"./tools/forget.tool.js";import{registerGraphTool as pe}from"./tools/graph.tool.js";import{registerGuideTool as H,registerHealthTool as U,registerProcessTool as W,registerWatchTool as G,registerWebFetchTool as K}from"./tools/infra.tools.js";import{registerListTool as me}from"./tools/list.tool.js";import{registerLookupTool as he}from"./tools/lookup.tool.js";import{registerCodemodTool as ge,registerDataTransformTool as q,registerDiffParseTool as _e,registerGitContextTool as ve,registerRenameTool as ye}from"./tools/manipulation.tools.js";import{registerOnboardTool as be}from"./tools/onboard.tool.js";import{registerCheckpointTool as xe,registerLaneTool as Se,registerQueueTool as Ce,registerStashTool as we,registerWorksetTool as Te}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as Ee}from"./tools/policy.tools.js";import{registerPresentTool as De}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as Oe}from"./tools/produce.tool.js";import{registerReadTool as ke}from"./tools/read.tool.js";import{registerReindexTool as Ae}from"./tools/reindex.tool.js";import{registerRememberTool as je}from"./tools/remember.tool.js";import{registerReplayTool as Me}from"./tools/replay.tool.js";import{registerRestoreTool as Ne}from"./tools/restore.tool.js";import{registerSearchTool as Pe}from"./tools/search.tool.js";import{getCurrentVersion as Fe}from"./version-check.js";import{registerEarlyStatusTool as Ie,registerStatusTool as Le}from"./tools/status.tool.js";import{registerUpdateTool as Re}from"./tools/update.tool.js";import{registerChangelogTool as ze,registerEncodeTool as Be,registerEnvTool as Ve,registerHttpTool as He,registerMeasureTool as Ue,registerRegexTestTool as We,registerSchemaValidateTool as Ge,registerSnippetTool as Ke,registerTimeTool as qe,registerWebSearchTool as Je}from"./tools/utility.tools.js";import{existsSync as Ye,statSync as Xe}from"node:fs";import{resolve as Ze}from"node:path";import{AIKIT_PATHS as Qe,createLogger as $e,serializeError as J}from"../../core/dist/index.js";import{initializeWasm as et}from"../../chunker/dist/index.js";import{OnnxEmbedder as tt}from"../../embeddings/dist/index.js";import{EvolutionCollector as nt,PolicyStore as rt}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as it,IncrementalIndexer as at}from"../../indexer/dist/index.js";import{SqliteGraphStore as ot,createStore as st}from"../../store/dist/index.js";import{FileCache as ct}from"../../tools/dist/index.js";import{completable as lt}from"@modelcontextprotocol/sdk/server/completable.js";import{McpServer as ut}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as dt}from"zod";const Y=$e(`server`);async function X(e){Y.info(`Initializing AI Kit components`);let[t,n,i,a]=await Promise.all([(async()=>{let t=new tt({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 st({backend:e.store.backend,path:e.store.path});return await t.initialize(),Y.info(`Store initialized`),t})(),(async()=>{let t=new ot({path:e.store.path});return await t.initialize(),Y.info(`Graph store initialized`),t})(),(async()=>{let e=await et();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 at(t,n),s=new it(e.store.path);s.load(),o.setHashCache(s);let c=e.curated.path,l=new r(c,n,t);o.setGraphStore(i);let u=E(e.er),d=u?new rt(e.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new nt:void 0,p=Ze(e.sources[0]?.path??process.cwd(),Qe.aiKb),m=Ye(p),h=e.onboardDir?Ye(e.onboardDir):!1,g=m||h,_,v=m?p:e.onboardDir;if(g&&v)try{_=Xe(v).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:t,store:n,indexer:o,curated:l,graphStore:i,fileCache:new ct,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function ft(e,t){let n=new ut({name:t.serverName??`aikit`,version:Fe()},{capabilities:{logging:{},completions:{},prompts:{}}});return s(n),g(n,t.toolPrefix??``),Z(n,e,t,i(n),new d(n),p(n)),l(n,{curated:e.curated,store:e.store,graphStore:e.graphStore},t.indexMode),n}function Z(e,t,r,i,a,o,s,c){u(e),m(e),n(e),Pe(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),he(e,t.store);let l={onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp};Le(e,t.store,t.graphStore,t.curated,l,r,s,c),k(e,r),Ae(e,t.indexer,r,t.curated,t.store,a,s),je(e,t.curated,t.policyStore,t.evolutionCollector,a),Re(e,t.curated,a),fe(e,t.curated,a),ke(e,t.curated),me(e,t.curated),S(e,t.store,t.embedder),y(e,t.store,t.embedder),C(e,t.store,t.embedder),te(e,t.store,t.embedder),x(e,t.store,t.embedder),b(e,t.store,t.embedder),w(e,t.store,t.embedder,t.graphStore),Oe(e,r),be(e,t.store,t.embedder,r,l),pe(e,t.graphStore),ne(e,t.store,t.embedder);let d=r.sources[0]?.path??process.cwd();A(e,t.embedder,t.fileCache,d),N(e,t.embedder,t.store),ie(e,t.embedder,t.store),R(e),Te(e),F(e),se(e,t.embedder,t.store),P(e,t.embedder,t.store,t.graphStore),L(e),z(e),we(e),ve(e),_e(e),ye(e),ge(e),Ne(e),M(e,t.fileCache,d),xe(e),q(e),ae(e,t.embedder,t.store,t.graphStore),W(e),G(e),j(e,t.embedder,t.store),(process.env.AIKIT_DELEGATE===`1`||process.env.AIKIT_DELEGATE===`true`)&&I(e,o),U(e),Se(e),Ce(e),K(e),H(e,s),B(e),le(e,t.embedder),V(e),de(e,t.embedder,t.fileCache),ue(e,t.embedder,t.store),De(e,i),i&&T(e,i),Je(e),He(e),We(e),Be(e),Ue(e),ze(e),Ge(e),Ke(e),Ve(e),qe(e),ce(e,r),t.bridge&&(O(e,t.bridge,t.evolutionCollector),D(e,t.bridge),re(e,t.bridge)),t.policyStore&&Ee(e,t.policyStore),t.evolutionCollector&&oe(e,t.evolutionCollector),f(e,t.store,t.curated),Me(e)}async function pt(e){let t=await X(e),n=ft(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 Promise.all([t.embedder.shutdown().catch(()=>{}),t.graphStore.close().catch(()=>{}),t.store.close().catch(()=>{})]),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 mt=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.config.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(`.`)),ht=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 gt(e){F(e),L(e),z(e),R(e),(process.env.AIKIT_DELEGATE===`1`||process.env.AIKIT_DELEGATE===`true`)&&I(e),ve(e),_e(e),ye(e),ge(e),q(e),Te(e),we(e),xe(e),Ne(e),Se(e),Ce(e),U(e),W(e),G(e),K(e),H(e),B(e),V(e),De(e),T(e,a),Oe(e),Me(e),Ie(e),Je(e),He(e),We(e),Be(e),Ue(e),ze(e),Ge(e),Ke(e),Ve(e),qe(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.config.data_transform.dead_symbols.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.flow_info.flow_list.flow_reset.flow_start.flow_status.flow_step.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 _t(n,r){let a=new ut({name:n.serverName??`aikit`,version:Fe()},{capabilities:{logging:{},completions:{},prompts:{}}}),u=`initializing`,f=``,m=!1,y=null,b=null,x=null;function te(e){if(!e||typeof e!=`object`)return[];let t=e,n=[];for(let e of[`path`,`file`,`source_path`,`sourcePath`,`filePath`]){let r=t[e];typeof r==`string`&&r&&n.push(r)}for(let e of[`changed_files`,`paths`,`files`]){let r=t[e];if(Array.isArray(r))for(let e of r){if(typeof e==`string`){n.push(e);continue}e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path)}}if(Array.isArray(t.sources))for(let e of t.sources)e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path);return n}let S=()=>u===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,f?`Error: ${f}`:``,``,`**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
- `);s(a),g(a,n.toolPrefix??``);let C=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let w=[];for(let e of $){let t=h(e),n=a.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:S()}]}));Q.has(e)?n.remove():w.push(n)}gt(a),a.sendToolListChanged=C;let ne=a.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`}]})),T=a.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:lt(dt.string(),()=>[])}},async()=>({messages:[]})),E,D=new Promise(e=>{E=e}),O,re=new Promise(e=>{O=e}),k=()=>O?.(),A=(async()=>{await re;let e;try{e=await X(n)}catch(e){u=`failed`,f=e instanceof Error?e.message:String(e),Y.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:f});return}let s=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let h=a.sendPromptListChanged.bind(a);a.sendPromptListChanged=()=>{};let g=a.sendResourceListChanged.bind(a);a.sendResourceListChanged=()=>{};for(let e of w)e.remove();ne.remove(),T.remove();let S=a._registeredTools??{};for(let e of Q)S[e]?.remove();let C=new d(a),D=p(a);Z(a,e,n,i(a),C,D,r,r===`smart`?(()=>{let e=x;return e?.getState?e.getState():null}):null),l(a,{curated:e.curated,store:e.store,graphStore:e.graphStore},r),a.sendToolListChanged=s,a.sendPromptListChanged=h,a.sendResourceListChanged=g,Promise.resolve(a.sendToolListChanged()).catch(()=>{}),Promise.resolve(a.sendPromptListChanged()).catch(()=>{}),Promise.resolve(a.sendResourceListChanged()).catch(()=>{});let O=a._registeredTools??{};for(let[t,n]of Object.entries(O)){if(mt.has(t))continue;let r=n.handler;n.handler=async(...n)=>{if(!e.indexer.isIndexing)return r(...n);let i=m?`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 (${ht/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),ht));return Promise.race([r(...n),a])}}for(let[e,t]of Object.entries(O)){let n=t.handler,r=v(e);t.handler=async(...t)=>{try{return await ee(()=>n(...t),r,e)}catch(t){if(t instanceof _)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 k=Object.keys(O).length;k<$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:k}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4});let A=new c;A.onPressure((e,n)=>{e===`warning`&&t(),e===`critical`&&(Y.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(n/1024/1024)}),t())}),A.start();let j=new o;b=j,j.onIdle(async()=>{if(M.isRunning||e.indexer.isIndexing){Y.info(`Idle cleanup deferred — background tasks still running`),j.touch();return}Y.info(`Idle cleanup: closing store and graph connections`);try{await Promise.all([e.store.close().catch(()=>{}),e.graphStore.close().catch(()=>{})])}catch{}}),j.touch();for(let e of Object.values(O)){let t=e.handler;e.handler=async(...e)=>{if(j.touch(),x){let t=te(e[0]);t.length>0&&x.prioritize(...t)}return t(...e)}}y=e,E?.(e)})(),j=async()=>{let e=await D;b?.setBusy(!0);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}))});m=!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))}finally{b?.setBusy(!1)}},M=new e,ie=()=>M.schedule({name:`initial-index`,fn:j}),N=process.ppid,P=setInterval(()=>{try{process.kill(N,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:N}),clearInterval(P),D.then(async e=>{await Promise.all([e.embedder.shutdown().catch(()=>{}),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return P.unref(),{server:a,startInit:k,ready:A,runInitialIndex:ie,get kb(){return y},scheduler:M,setSmartScheduler(e){x=e}}}export{$ as ALL_TOOL_NAMES,_t as createLazyServer,ft as createMcpServer,pt as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
1
+ import{BackgroundTaskScheduler as e}from"./background-task.js";import{clearCompletionCache as t}from"./completions.js";import{installCompressionInterceptor as n}from"./compression-interceptor.js";import{CuratedKnowledgeManager as r}from"./curated-manager.js";import{createElicitor as i,noopElicitor as a}from"./elicitor.js";import{IdleTimer as o}from"./idle-timer.js";import{bridgeMcpLogging as s}from"./mcp-logging.js";import{MemoryMonitor as c}from"./memory-monitor.js";import{registerPrompts as l}from"./prompts.js";import{installReplayInterceptor as u}from"./replay-interceptor.js";import{ResourceNotifier as d}from"./resources/resource-notifier.js";import{registerResources as f}from"./resources/resources.js";import{createSamplingClient as p}from"./sampling.js";import{installStructuredContentGuard as m}from"./structured-content-guard.js";import{getToolMeta as h}from"./tool-metadata.js";import{installToolPrefix as g}from"./tool-prefix.js";import{ToolTimeoutError as _,getToolTimeout as v,withTimeout as ee}from"./tool-timeout.js";import{registerAnalyzeDependenciesTool as y,registerAnalyzeDiagramTool as b,registerAnalyzeEntryPointsTool as x,registerAnalyzePatternsTool as te,registerAnalyzeStructureTool as S,registerAnalyzeSymbolsTool as C,registerBlastRadiusTool as w}from"./tools/analyze.tools.js";import{registerAuditTool as ne}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 re}from"./tools/bridge.tools.js";import{registerConfigTool as k}from"./tools/config.tool.js";import{registerCompactTool as A,registerDeadSymbolsTool as j,registerFileSummaryTool as M,registerFindTool as ie,registerScopeMapTool as N,registerSymbolTool as P,registerTraceTool as ae}from"./tools/context.tools.js";import{registerErEvolveReviewTool as oe}from"./tools/evolution.tools.js";import{registerBatchTool as se,registerCheckTool as F,registerDelegateTool as I,registerEvalTool as L,registerParseOutputTool as R,registerTestRunTool as ce}from"./tools/execution.tools.js";import{registerFlowTools as z}from"./tools/flow.tools.js";import{registerDigestTool as le,registerEvidenceMapTool as B,registerForgeClassifyTool as V,registerForgeGroundTool as ue,registerStratumCardTool as de}from"./tools/forge.tools.js";import{registerForgetTool as fe}from"./tools/forget.tool.js";import{registerGraphTool as pe}from"./tools/graph.tool.js";import{registerGuideTool as H,registerHealthTool as U,registerProcessTool as W,registerWatchTool as G,registerWebFetchTool as me}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 _e,registerDataTransformTool as K,registerDiffParseTool as ve,registerGitContextTool as ye,registerRenameTool as be}from"./tools/manipulation.tools.js";import{registerOnboardTool as xe}from"./tools/onboard.tool.js";import{registerCheckpointTool as Se,registerLaneTool as Ce,registerQueueTool as we,registerStashTool as Te,registerWorksetTool as Ee}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as De}from"./tools/policy.tools.js";import{registerPresentTool as Oe}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as ke}from"./tools/produce.tool.js";import{registerReadTool as Ae}from"./tools/read.tool.js";import{registerReindexTool as je}from"./tools/reindex.tool.js";import{registerRememberTool as Me}from"./tools/remember.tool.js";import{registerReplayTool as Ne}from"./tools/replay.tool.js";import{registerRestoreTool as Pe}from"./tools/restore.tool.js";import{registerSearchTool as Fe}from"./tools/search.tool.js";import{getCurrentVersion as Ie}from"./version-check.js";import{registerEarlyStatusTool as Le,registerStatusTool as Re}from"./tools/status.tool.js";import{registerUpdateTool as ze}from"./tools/update.tool.js";import{registerChangelogTool as Be,registerEncodeTool as Ve,registerEnvTool as He,registerHttpTool as Ue,registerMeasureTool as We,registerRegexTestTool as Ge,registerSchemaValidateTool as Ke,registerSnippetTool as qe,registerTimeTool as Je,registerWebSearchTool as Ye}from"./tools/utility.tools.js";import{existsSync as Xe,statSync as Ze}from"node:fs";import{join as q,resolve as Qe}from"node:path";import{AIKIT_PATHS as $e,EMBEDDING_DEFAULTS as et,createLogger as tt,serializeError as J}from"../../core/dist/index.js";import{homedir as nt}from"node:os";import{initializeWasm as rt}from"../../chunker/dist/index.js";import{OnnxEmbedder as it}from"../../embeddings/dist/index.js";import{EvolutionCollector as at,PolicyStore as ot}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as st,IncrementalIndexer as ct}from"../../indexer/dist/index.js";import{SqliteGraphStore as lt,createStore as ut}from"../../store/dist/index.js";import{FileCache as dt}from"../../tools/dist/index.js";import{completable as ft}from"@modelcontextprotocol/sdk/server/completable.js";import{McpServer as pt}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as mt}from"zod";const Y=tt(`server`);function ht(e){let t=e.toLowerCase();return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`failed to initialize embedding`,`checksum`,`corrupt`,`malformed`,`could not load`,`onnx`,`database disk image is malformed`,`file is not a database`,`lance`].some(e=>t.includes(e))}async function gt(e,t){let n=t.toLowerCase(),r;try{({rm:r}=await import(`node:fs/promises`))}catch{return}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model??et.model,n=q(nt(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(n,{recursive:!0,force:!0}),Y.info(`Auto-heal: cleared embedding model cache`,{path:n})}catch{}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=q(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Y.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=q(e.store.path,`graph.db`);try{await r(t,{force:!0}),Y.info(`Auto-heal: cleared graph database`,{path:t})}catch{}}}async function X(e){Y.info(`Initializing AI Kit components`);let[t,n,i,a]=await Promise.all([(async()=>{let t=new it({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 ut({backend:e.store.backend,path:e.store.path});return await t.initialize(),Y.info(`Store initialized`),t})(),(async()=>{let t=new lt({path:e.store.path});return await t.initialize(),Y.info(`Graph store initialized`),t})(),(async()=>{let e=await rt();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 ct(t,n),s=new st(e.store.path);s.load(),o.setHashCache(s);let c=e.curated.path,l=new r(c,n,t);o.setGraphStore(i);let u=E(e.er),d=u?new ot(e.curated.path):void 0;d&&Y.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new at:void 0,p=Qe(e.sources[0]?.path??process.cwd(),$e.aiKb),m=Xe(p),h=e.onboardDir?Xe(e.onboardDir):!1,g=m||h,_,v=m?p:e.onboardDir;if(g&&v)try{_=Ze(v).mtime.toISOString()}catch{}return Y.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:t,store:n,indexer:o,curated:l,graphStore:i,fileCache:new dt,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function _t(e,t){let n=new pt({name:t.serverName??`aikit`,version:Ie()},{capabilities:{logging:{},completions:{},prompts:{}}});return s(n),g(n,t.toolPrefix??``),Z(n,e,t,i(n),new d(n),p(n)),l(n,{curated:e.curated,store:e.store,graphStore:e.graphStore},t.indexMode),n}function Z(e,t,r,i,a,o,s,c){u(e),m(e),n(e),Fe(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,o),ge(e,t.store);let l={onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp};Re(e,t.store,t.graphStore,t.curated,l,r,s,c),k(e,r),je(e,t.indexer,r,t.curated,t.store,a,s),Me(e,t.curated,t.policyStore,t.evolutionCollector,a),ze(e,t.curated,a),fe(e,t.curated,a),Ae(e,t.curated),he(e,t.curated),S(e,t.store,t.embedder),y(e,t.store,t.embedder),C(e,t.store,t.embedder),te(e,t.store,t.embedder),x(e,t.store,t.embedder),b(e,t.store,t.embedder),w(e,t.store,t.embedder,t.graphStore),ke(e,r),xe(e,t.store,t.embedder,r,l),pe(e,t.graphStore),ne(e,t.store,t.embedder);let d=r.sources[0]?.path??process.cwd();A(e,t.embedder,t.fileCache,d),N(e,t.embedder,t.store),ie(e,t.embedder,t.store),R(e),Ee(e),F(e),se(e,t.embedder,t.store),P(e,t.embedder,t.store,t.graphStore),L(e),ce(e),Te(e),ye(e),ve(e),be(e),_e(e),Pe(e),M(e,t.fileCache,d),Se(e),K(e),ae(e,t.embedder,t.store,t.graphStore),W(e),G(e),j(e,t.embedder,t.store),(process.env.AIKIT_DELEGATE===`1`||process.env.AIKIT_DELEGATE===`true`)&&I(e,o),U(e),Ce(e),we(e),me(e),H(e,s),B(e),le(e,t.embedder),V(e),de(e,t.embedder,t.fileCache),ue(e,t.embedder,t.store),Oe(e,i),i&&T(e,i),Ye(e),Ue(e),Ge(e),Ve(e),We(e),Be(e),Ke(e),qe(e),He(e),Je(e),z(e,r),t.bridge&&(O(e,t.bridge,t.evolutionCollector),D(e,t.bridge),re(e,t.bridge)),t.policyStore&&De(e,t.policyStore),t.evolutionCollector&&oe(e,t.evolutionCollector),f(e,t.store,t.curated),Ne(e)}async function vt(e){let t=await X(e),n=_t(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 Promise.all([t.embedder.shutdown().catch(()=>{}),t.graphStore.close().catch(()=>{}),t.store.close().catch(()=>{})]),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 yt=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.config.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(`.`)),bt=5e3,Q=new Set(`brainstorm.changelog.check.checkpoint.codemod.data_transform.delegate.diff_parse.encode.env.eval.evidence_map.flow_info.flow_list.flow_reset.flow_start.flow_status.flow_step.flow_add.flow_update.flow_remove.flow_read_instruction.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 xt(e,t){F(e),L(e),ce(e),R(e),(process.env.AIKIT_DELEGATE===`1`||process.env.AIKIT_DELEGATE===`true`)&&I(e),ye(e),ve(e),be(e),_e(e),K(e),Ee(e),Te(e),Se(e),Pe(e),Ce(e),we(e),U(e),W(e),G(e),me(e),H(e),B(e),V(e),Oe(e),T(e,a),ke(e),Ne(e),Le(e),z(e,t),Ye(e),Ue(e),Ge(e),Ve(e),We(e),Be(e),Ke(e),qe(e),He(e),Je(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.config.data_transform.dead_symbols.delegate.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.flow_info.flow_list.flow_reset.flow_start.flow_status.flow_step.flow_add.flow_update.flow_remove.flow_read_instruction.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 St(n,r){let a=new pt({name:n.serverName??`aikit`,version:Ie()},{capabilities:{logging:{},completions:{},prompts:{}}}),u=`initializing`,f=``,m=!1,y=null,b=null,x=null;function te(e){if(!e||typeof e!=`object`)return[];let t=e,n=[];for(let e of[`path`,`file`,`source_path`,`sourcePath`,`filePath`]){let r=t[e];typeof r==`string`&&r&&n.push(r)}for(let e of[`changed_files`,`paths`,`files`]){let r=t[e];if(Array.isArray(r))for(let e of r){if(typeof e==`string`){n.push(e);continue}e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path)}}if(Array.isArray(t.sources))for(let e of t.sources)e&&typeof e==`object`&&typeof e.path==`string`&&n.push(e.path);return n}let S=()=>u===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,f?`Error: ${f}`:``,``,`**${Q.size} tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow_list, flow_status, flow_start, flow_read_instruction, regex_test, encode,`,`stash, checkpoint, lane, process, time, env, and more.`,``,`To fix embedding errors, try deleting the cached model:`,` rm -rf ~/.cache/huggingface/transformers-js/mixedbread-ai/`,`Then restart the server to re-download a fresh copy.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
2
+ `):[`AI Kit is still initializing (loading embeddings model & store).`,``,`**${Q.size} tools are already available** while initialization completes — including:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow_list, flow_status, flow_start, flow_read_instruction, 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
+ `);s(a),g(a,n.toolPrefix??``);let C=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let w=[];for(let e of $){let t=h(e),n=a.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:S()}]}));Q.has(e)?n.remove():w.push(n)}xt(a,n),a.sendToolListChanged=C;let ne=a.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`}]})),T=a.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:ft(mt.string(),()=>[])}},async()=>({messages:[]})),E,D=new Promise(e=>{E=e}),O,re=new Promise(e=>{O=e}),k=()=>O?.(),A=(async()=>{await re;let e;try{e=await X(n)}catch(t){let r=t instanceof Error?t.message:String(t);if(ht(r)){Y.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:r}),await gt(n,r);try{e=await X(n),Y.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){u=`failed`,f=e instanceof Error?e.message:String(e),Y.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:f,originalError:r});return}}else{u=`failed`,f=r,Y.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:f});return}}let s=a.sendToolListChanged.bind(a);a.sendToolListChanged=()=>{};let h=a.sendPromptListChanged.bind(a);a.sendPromptListChanged=()=>{};let g=a.sendResourceListChanged.bind(a);a.sendResourceListChanged=()=>{};for(let e of w)e.remove();ne.remove(),T.remove();let S=a._registeredTools??{};for(let e of Q)S[e]?.remove();let C=new d(a),D=p(a);Z(a,e,n,i(a),C,D,r,r===`smart`?(()=>{let e=x;return e?.getState?e.getState():null}):null),l(a,{curated:e.curated,store:e.store,graphStore:e.graphStore},r),a.sendToolListChanged=s,a.sendPromptListChanged=h,a.sendResourceListChanged=g,Promise.resolve(a.sendToolListChanged()).catch(()=>{}),Promise.resolve(a.sendPromptListChanged()).catch(()=>{}),Promise.resolve(a.sendResourceListChanged()).catch(()=>{});let O=a._registeredTools??{};for(let[t,n]of Object.entries(O)){if(yt.has(t))continue;let r=n.handler;n.handler=async(...n)=>{if(!e.indexer.isIndexing)return r(...n);let i=m?`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 (${bt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),bt));return Promise.race([r(...n),a])}}for(let[e,t]of Object.entries(O)){let n=t.handler,r=v(e);t.handler=async(...t)=>{try{return await ee(()=>n(...t),r,e)}catch(t){if(t instanceof _)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 k=Object.keys(O).length;k<$.length&&Y.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:k}),Y.info(`MCP server configured`,{toolCount:$.length,resourceCount:4});let A=new c;A.onPressure((e,n)=>{e===`warning`&&t(),e===`critical`&&(Y.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(n/1024/1024)}),t())}),A.start();let j=new o;b=j,j.onIdle(async()=>{if(M.isRunning||e.indexer.isIndexing){Y.info(`Idle cleanup deferred — background tasks still running`),j.touch();return}Y.info(`Idle cleanup: closing store and graph connections`);try{await Promise.all([e.store.close().catch(()=>{}),e.graphStore.close().catch(()=>{})])}catch{}}),j.touch();for(let e of Object.values(O)){let t=e.handler;e.handler=async(...e)=>{if(j.touch(),x){let t=te(e[0]);t.length>0&&x.prioritize(...t)}return t(...e)}}y=e,E?.(e)})(),j=async()=>{let e=await D;b?.setBusy(!0);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}))});m=!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))}finally{b?.setBusy(!1)}},M=new e,ie=()=>M.schedule({name:`initial-index`,fn:j}),N=process.ppid,P=setInterval(()=>{try{process.kill(N,0)}catch{Y.info(`Parent process died; shutting down`,{parentPid:N}),clearInterval(P),D.then(async e=>{await Promise.all([e.embedder.shutdown().catch(()=>{}),e.graphStore.close().catch(()=>{}),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return P.unref(),{server:a,startInit:k,ready:A,runInitialIndex:ie,get kb(){return y},scheduler:M,setSmartScheduler(e){x=e}}}export{$ as ALL_TOOL_NAMES,St as createLazyServer,_t as createMcpServer,vt as createServer,X as initializeKnowledgeBase,Z as registerMcpTools};
@@ -1 +1 @@
1
- import{getToolMeta as e}from"../tool-metadata.js";import{existsSync as t}from"node:fs";import{basename as n,join as r,resolve as i}from"node:path";import{z as a}from"zod";import{readFile as o}from"node:fs/promises";import{createLogger as s,getGlobalDataDir as c,serializeError as l}from"../../../core/dist/index.js";import{homedir as u}from"node:os";const d=s(`flow-tools`);function f(e){return{content:[{type:`text`,text:e}]}}function p(e){return e instanceof Error?e.message:String(e)}function m(s,m){function h(){return m.sources?.[0]?.path??process.cwd()}function g(){return r(c(),`flows`,`registry.json`)}function _(){return r(m.stateDir??r(h(),`.aikit-state`),`flows`,`state.json`)}function v(e,n){let r=i(u(),`.copilot`,`flows`,e).replaceAll(`\\`,`/`);if(t(r))return r;let a=i(u(),`.claude`,`flows`,e).replaceAll(`\\`,`/`);return t(a)?a:n?.installPath?n.installPath.replaceAll(`\\`,`/`):null}function y(e,t){let n=v(e.name,e);return n?i(n,t).replaceAll(`\\`,`/`):t}async function b(){let{FlowRegistryManager:e,FlowStateMachine:t,FlowLoader:n,GitInstaller:i}=await import(`../../../flows/dist/index.js`),a=r(m.stateDir??r(h(),`.aikit-state`),`flows`,`installed`);return{registry:new e(g()),stateMachine:new t(_()),loader:new n,installer:new i(a)}}let x=e(`flow_list`);s.registerTool(`flow_list`,{title:x.title,description:`List all installed flows and their steps`,annotations:x.annotations,inputSchema:{}},async()=>{try{let{registry:e,stateMachine:t,installer:n}=await b(),r=e.list(),i=t.getStatus(),a={flows:r.map(e=>{let t={name:e.name,version:e.version,source:e.source,sourceType:e.sourceType,format:e.format,steps:e.manifest.steps.map(e=>e.id)};if(e.sourceType===`git`&&e.commitSha){let r=n.hasUpdates(e.installPath);return{...t,commitSha:e.commitSha,updateAvailable:r.success&&r.data?r.data.hasUpdates:void 0}}return t}),activeFlow:i.success&&i.data?{flow:i.data.flow,status:i.data.status,currentStep:i.data.currentStep}:null};return f(JSON.stringify(a,null,2))}catch(e){return d.error(`flow_list failed`,l(e)),f(`Error: ${p(e)}`)}});let S=e(`flow_info`);s.registerTool(`flow_info`,{title:S.title,description:`Show detailed information about a specific flow`,annotations:S.annotations,inputSchema:{name:a.string().describe(`Flow name to get info for`)}},async({name:e})=>{try{let{registry:t,installer:n}=await b(),r=t.get(e);if(!r)return f(`Flow "${e}" not found. Use flow_list to see available flows.`);let i=r.commitSha??null,a;if(r.sourceType===`git`&&r.installPath){let e=n.hasUpdates(r.installPath);a=e.success&&e.data?e.data.hasUpdates:void 0}let o={name:r.name,version:r.version,description:r.manifest.description,source:r.source,sourceType:r.sourceType,format:r.format,commitSha:i,updateAvailable:a,installPath:v(r.name,r),registeredAt:r.registeredAt,updatedAt:r.updatedAt,steps:r.manifest.steps.map(e=>({id:e.id,name:e.name,instruction:y(r,e.instruction),produces:e.produces,requires:e.requires,description:e.description})),agents:r.manifest.agents,artifactsDir:r.manifest.artifacts_dir,install:r.manifest.install};return f(JSON.stringify(o,null,2))}catch(e){return d.error(`flow_info failed`,l(e)),f(`Error: ${p(e)}`)}});let C=e(`flow_start`);s.registerTool(`flow_start`,{title:C.title,description:`Start a flow. Sets the active flow and positions at the first step.`,annotations:C.annotations,inputSchema:{flow:a.string().describe(`Flow name to start (use flow_list to see options)`)}},async({flow:e})=>{try{let{registry:t,stateMachine:n}=await b(),r=t.get(e);if(!r)return f(`Flow "${e}" not found. Use flow_list to see available flows.`);let i=n.start(r.name,r.manifest);if(!i.success||!i.data)return f(`Cannot start: ${i.error}`);let a=i.data,o=r.manifest.steps.find(e=>e.id===a.currentStep),s={started:!0,flow:a.flow,currentStep:a.currentStep,currentStepInstruction:r&&o?y(r,o.instruction):null,currentStepDescription:o?.description??null,totalSteps:r.manifest.steps.length,stepSequence:r.manifest.steps.map(e=>e.id),artifactsDir:r.manifest.artifacts_dir};return f(JSON.stringify(s,null,2))}catch(e){return d.error(`flow_start failed`,l(e)),f(`Error: ${p(e)}`)}});let w=e(`flow_step`);s.registerTool(`flow_step`,{title:w.title,description:`Advance the active flow: complete current step and move to next, skip current step, or redo current step.`,annotations:w.annotations,inputSchema:{action:a.enum([`next`,`skip`,`redo`]).describe(`next: mark current step done and advance. skip: skip current step. redo: repeat current step.`)}},async({action:e})=>{try{let{registry:t,stateMachine:n}=await b(),r=n.load();if(!r)return f(`No active flow. Use flow_start first.`);let i=t.get(r.flow);if(!i)return f(`Flow "${r.flow}" not found in registry.`);let a=n.step(e,i.manifest);if(!a.success||!a.data)return f(`Cannot ${e}: ${a.error}`);let o=a.data,s=o.currentStep?i.manifest.steps.find(e=>e.id===o.currentStep):null,c={flow:o.flow,status:o.status,action:e,currentStep:o.currentStep,currentStepInstruction:i&&s?y(i,s.instruction):null,currentStepDescription:s?.description??null,completedSteps:o.completedSteps,skippedSteps:o.skippedSteps,totalSteps:i.manifest.steps.length,remaining:i.manifest.steps.filter(e=>!o.completedSteps.includes(e.id)&&!o.skippedSteps.includes(e.id)&&e.id!==o.currentStep).map(e=>e.id)};return f(JSON.stringify(c,null,2))}catch(e){return d.error(`flow_step failed`,l(e)),f(`Error: ${p(e)}`)}});let T=e(`flow_status`);s.registerTool(`flow_status`,{title:T.title,description:`Show the current flow execution state — which flow is active, current step, completed steps, and artifacts.`,annotations:T.annotations,inputSchema:{}},async()=>{try{let{registry:e,stateMachine:t}=await b(),n=t.getStatus();if(!n.success||!n.data)return f(`No active flow. Use flow_start to begin one, or flow_list to see available flows.`);let r=n.data,i=e.get(r.flow),a=i?.manifest.steps.find(e=>e.id===r.currentStep),o=i&&a?y(i,a.instruction):null,s={flow:r.flow,status:r.status,currentStep:r.currentStep,currentStepInstruction:o,instructionPath:o,currentStepDescription:a?.description??null,completedSteps:r.completedSteps,skippedSteps:r.skippedSteps,artifacts:r.artifacts,startedAt:r.startedAt,updatedAt:r.updatedAt,totalSteps:i?.manifest.steps.length??0,progress:i?`${r.completedSteps.length+r.skippedSteps.length}/${i.manifest.steps.length}`:`unknown`};return f(JSON.stringify(s,null,2))}catch(e){return d.error(`flow_status failed`,l(e)),f(`Error: ${p(e)}`)}});let E=e(`flow_read_instruction`);s.registerTool(`flow_read_instruction`,{title:E.title===`flow_read_instruction`?`Flow Read Instruction`:E.title,description:`Read the instruction content for a flow step. If step is omitted, reads the current step.`,annotations:E.title===`flow_read_instruction`?{readOnlyHint:!0,idempotentHint:!0}:E.annotations,inputSchema:{step:a.string().optional().describe(`Step id or name to read. Defaults to the current step.`)}},async({step:e})=>{try{let{registry:t,stateMachine:n}=await b(),r=n.getStatus();if(!r.success||!r.data)return f(`No active flow. Use flow_start to begin one, or flow_list to see available flows.`);let i=r.data,a=t.get(i.flow);if(!a)return f(`Flow "${i.flow}" not found in registry.`);let s=e??i.currentStep;if(!s)return f(`No current step is available for the active flow.`);let c=a.manifest.steps.find(e=>e.id===s||e.name===s);return f(c?await o(y(a,c.instruction),`utf-8`):`Step "${s}" not found in flow "${i.flow}".`)}catch(e){return d.error(`flow_read_instruction failed`,l(e)),e instanceof Error&&`code`in e&&e.code===`ENOENT`?f(`Could not read instruction file: ${e.message}`):f(`Error: ${p(e)}`)}});let D=e(`flow_reset`);s.registerTool(`flow_reset`,{title:D.title,description:`Reset the active flow, clearing all state. Use to start over or switch to a different flow.`,annotations:D.annotations,inputSchema:{}},async()=>{try{let{stateMachine:e}=await b(),t=e.reset();return t.success?f(`Flow state reset. Use flow_start to begin a new flow.`):f(`Reset failed: ${t.error}`)}catch(e){return d.error(`flow_reset failed`,l(e)),f(`Error: ${p(e)}`)}});let O=e(`flow_add`);s.registerTool(`flow_add`,{title:O.title,description:`Install a new development flow from a git repository URL or local directory path. Use when the user wants to add, install, import, or onboard a new workflow — for example: "use this as a flow", "add this flow", "add this flow URL", "install a flow", or "onboard a flow". Accepts git URLs (https://..., git@...) and local filesystem paths.`,annotations:O.annotations,inputSchema:{source:a.string().describe(`Git repository URL (https://... or git@...) or absolute/local directory path containing a flow definition.`),name:a.string().optional().describe(`Optional override for the installed flow name. If omitted, the name comes from the flow manifest.`)}},async({source:e,name:t})=>{try{let{registry:r,loader:a,installer:o}=await b(),s=/^https?:\/\/|^git@/.test(e),c;if(s){let t=o.clone(e);if(!t.success||!t.data)return f(`Failed to clone flow: ${t.error}`);c=t.data}else{let r=i(e),a=t||n(r)||`custom-flow`,s=o.copyLocal(r,a);if(!s.success||!s.data)return f(`Failed to copy flow: ${s.error}`);c=s.data}let l=await a.load(c);if(!l.success||!l.data)return o.remove(c),f(`Failed to load flow manifest: ${l.error}`);let{manifest:u,format:d}=l.data,p=t||u.name;if(r.has(p))return o.remove(c),f(`Flow "${p}" is already installed. Use flow_update to update it, or flow_remove then flow_add to replace.`);if(u.install.length>0){let e=o.runInstallDeps(u.install);if(!e.success)return o.remove(c),f(`Dependency install failed: ${e.error}`)}let m=new Date().toISOString(),h=s?o.getLocalCommit(c):void 0,g=r.register({name:p,version:u.version,source:e,sourceType:s?`git`:`local`,installPath:c,format:d,registeredAt:m,updatedAt:m,manifest:u,...h?{commitSha:h}:{}});if(!g.success)return o.remove(c),f(`Failed to register flow: ${g.error}`);let _=u.steps.length;return f(`Flow "${p}" installed successfully (${_} steps). Use flow_start({ flow: "${p}" }) to begin.`)}catch(e){return d.error(`flow_add failed`,l(e)),f(`Error: ${p(e)}`)}});let k=e(`flow_remove`);s.registerTool(`flow_remove`,{title:k.title,description:`Remove an installed flow by name. Unregisters it and deletes its files when applicable. Builtin flows cannot be removed.`,annotations:k.annotations,inputSchema:{name:a.string().describe(`Name of the flow to remove.`)}},async({name:e})=>{try{let{registry:t,installer:n}=await b();if(!t.has(e))return f(`Flow "${e}" is not installed.`);let r=t.get(e);if(!r)return f(`Flow "${e}" is not installed.`);if(r.sourceType===`builtin`)return f(`Cannot remove builtin flow "${e}".`);let i=n.remove(r.installPath);if(!i.success)return f(`Failed to remove flow files: ${i.error}`);let a=t.unregister(e);return a.success?f(`Flow "${e}" removed successfully.`):f(`Failed to unregister flow: ${a.error}`)}catch(e){return d.error(`flow_remove failed`,l(e)),f(`Error: ${p(e)}`)}});let A=e(`flow_update`);s.registerTool(`flow_update`,{title:A.title,description:`Update an installed git-based flow to its latest version by pulling changes. Only works for flows installed from git repositories.`,annotations:A.annotations,inputSchema:{name:a.string().describe(`Name of the flow to update.`)}},async({name:e})=>{try{let{registry:t,loader:n,installer:r}=await b();if(!t.has(e))return f(`Flow "${e}" is not installed.`);let i=t.get(e);if(!i||i.sourceType!==`git`)return f(`Flow "${e}" was not installed from git — cannot update. Remove and re-add instead.`);let a=r.update(i.installPath);if(!a.success)return f(`Update failed: ${a.error}`);let o=await n.load(i.installPath,{forceAssetSync:!0}),s=o.success&&o.data?o.data.manifest:null,c=o.success&&o.data?o.data.format:i.format;if(s){let e=r.getLocalCommit(i.installPath),n=t.register({...i,version:s.version,format:c,manifest:s,updatedAt:new Date().toISOString(),...e?{commitSha:e}:{}});if(!n.success)return f(`Failed to refresh flow registry entry: ${n.error}`)}let l=s?.install??i.manifest.install;if(l.length>0){let e=r.runInstallDeps(l);if(!e.success)return f(`Dependency install failed: ${e.error}`)}return f(`Flow "${e}" updated successfully.`)}catch(e){return d.error(`flow_update failed`,l(e)),f(`Error: ${p(e)}`)}})}export{m as registerFlowTools};
1
+ import{getToolMeta as e}from"../tool-metadata.js";import{existsSync as t}from"node:fs";import{basename as n,join as r,resolve as i}from"node:path";import{homedir as a}from"node:os";import{z as o}from"zod";import{readFile as s}from"node:fs/promises";import{createLogger as c,getGlobalDataDir as l,serializeError as u}from"../../../core/dist/index.js";const d=c(`flow-tools`);function f(e){return{content:[{type:`text`,text:e}]}}function p(e){return e instanceof Error?e.message:String(e)}function m(c,m){function h(){return m.sources?.[0]?.path??process.cwd()}function g(){return r(l(),`flows`,`registry.json`)}function _(){return r(m.stateDir??r(h(),`.aikit-state`),`flows`,`state.json`)}function v(e,n){let r=i(a(),`.copilot`,`flows`,e).replaceAll(`\\`,`/`);if(t(r))return r;let o=i(a(),`.claude`,`flows`,e).replaceAll(`\\`,`/`);return t(o)?o:n?.installPath?n.installPath.replaceAll(`\\`,`/`):null}function y(e,t){let n=v(e.name,e);return n?i(n,t).replaceAll(`\\`,`/`):t}async function b(){let{FlowRegistryManager:e,FlowStateMachine:t,FlowLoader:n,GitInstaller:i}=await import(`../../../flows/dist/index.js`),a=r(m.stateDir??r(h(),`.aikit-state`),`flows`,`installed`);return{registry:new e(g()),stateMachine:new t(_()),loader:new n,installer:new i(a)}}let x=e(`flow_list`);c.registerTool(`flow_list`,{title:x.title,description:`List all installed flows and their steps`,annotations:x.annotations,inputSchema:{}},async()=>{try{let{registry:e,stateMachine:t,installer:n}=await b(),r=e.list(),i=t.getStatus(),a={flows:r.map(e=>{let t={name:e.name,version:e.version,source:e.source,sourceType:e.sourceType,format:e.format,steps:e.manifest.steps.map(e=>e.id)};if(e.sourceType===`git`&&e.commitSha){let r=n.hasUpdates(e.installPath);return{...t,commitSha:e.commitSha,updateAvailable:r.success&&r.data?r.data.hasUpdates:void 0}}return t}),activeFlow:i.success&&i.data?{flow:i.data.flow,status:i.data.status,currentStep:i.data.currentStep}:null};return f(JSON.stringify(a,null,2))}catch(e){return d.error(`flow_list failed`,u(e)),f(`Error: ${p(e)}`)}});let S=e(`flow_info`);c.registerTool(`flow_info`,{title:S.title,description:`Show detailed information about a specific flow`,annotations:S.annotations,inputSchema:{name:o.string().describe(`Flow name to get info for`)}},async({name:e})=>{try{let{registry:t,installer:n}=await b(),r=t.get(e);if(!r)return f(`Flow "${e}" not found. Use flow_list to see available flows.`);let i=r.commitSha??null,a;if(r.sourceType===`git`&&r.installPath){let e=n.hasUpdates(r.installPath);a=e.success&&e.data?e.data.hasUpdates:void 0}let o={name:r.name,version:r.version,description:r.manifest.description,source:r.source,sourceType:r.sourceType,format:r.format,commitSha:i,updateAvailable:a,installPath:v(r.name,r),registeredAt:r.registeredAt,updatedAt:r.updatedAt,steps:r.manifest.steps.map(e=>({id:e.id,name:e.name,instruction:y(r,e.instruction),produces:e.produces,requires:e.requires,description:e.description})),agents:r.manifest.agents,artifactsDir:r.manifest.artifacts_dir,install:r.manifest.install};return f(JSON.stringify(o,null,2))}catch(e){return d.error(`flow_info failed`,u(e)),f(`Error: ${p(e)}`)}});let C=e(`flow_start`);c.registerTool(`flow_start`,{title:C.title,description:`Start a flow. Sets the active flow and positions at the first step.`,annotations:C.annotations,inputSchema:{flow:o.string().describe(`Flow name to start (use flow_list to see options)`)}},async({flow:e})=>{try{let{registry:t,stateMachine:n}=await b(),r=t.get(e);if(!r)return f(`Flow "${e}" not found. Use flow_list to see available flows.`);let i=n.start(r.name,r.manifest);if(!i.success||!i.data)return f(`Cannot start: ${i.error}`);let a=i.data,o=r.manifest.steps.find(e=>e.id===a.currentStep),s={started:!0,flow:a.flow,currentStep:a.currentStep,currentStepInstruction:r&&o?y(r,o.instruction):null,currentStepDescription:o?.description??null,totalSteps:r.manifest.steps.length,stepSequence:r.manifest.steps.map(e=>e.id),artifactsDir:r.manifest.artifacts_dir};return f(JSON.stringify(s,null,2))}catch(e){return d.error(`flow_start failed`,u(e)),f(`Error: ${p(e)}`)}});let w=e(`flow_step`);c.registerTool(`flow_step`,{title:w.title,description:`Advance the active flow: complete current step and move to next, skip current step, or redo current step.`,annotations:w.annotations,inputSchema:{action:o.enum([`next`,`skip`,`redo`]).describe(`next: mark current step done and advance. skip: skip current step. redo: repeat current step.`)}},async({action:e})=>{try{let{registry:t,stateMachine:n}=await b(),r=n.load();if(!r)return f(`No active flow. Use flow_start first.`);let i=t.get(r.flow);if(!i)return f(`Flow "${r.flow}" not found in registry.`);let a=n.step(e,i.manifest);if(!a.success||!a.data)return f(`Cannot ${e}: ${a.error}`);let o=a.data,s=o.currentStep?i.manifest.steps.find(e=>e.id===o.currentStep):null,c={flow:o.flow,status:o.status,action:e,currentStep:o.currentStep,currentStepInstruction:i&&s?y(i,s.instruction):null,currentStepDescription:s?.description??null,completedSteps:o.completedSteps,skippedSteps:o.skippedSteps,totalSteps:i.manifest.steps.length,remaining:i.manifest.steps.filter(e=>!o.completedSteps.includes(e.id)&&!o.skippedSteps.includes(e.id)&&e.id!==o.currentStep).map(e=>e.id)};return f(JSON.stringify(c,null,2))}catch(e){return d.error(`flow_step failed`,u(e)),f(`Error: ${p(e)}`)}});let T=e(`flow_status`);c.registerTool(`flow_status`,{title:T.title,description:`Show the current flow execution state — which flow is active, current step, completed steps, and artifacts.`,annotations:T.annotations,inputSchema:{}},async()=>{try{let{registry:e,stateMachine:t}=await b(),n=t.getStatus();if(!n.success||!n.data)return f(`No active flow. Use flow_start to begin one, or flow_list to see available flows.`);let r=n.data,i=e.get(r.flow),a=i?.manifest.steps.find(e=>e.id===r.currentStep),o=i&&a?y(i,a.instruction):null,s={flow:r.flow,status:r.status,currentStep:r.currentStep,currentStepInstruction:o,instructionPath:o,currentStepDescription:a?.description??null,completedSteps:r.completedSteps,skippedSteps:r.skippedSteps,artifacts:r.artifacts,startedAt:r.startedAt,updatedAt:r.updatedAt,totalSteps:i?.manifest.steps.length??0,progress:i?`${r.completedSteps.length+r.skippedSteps.length}/${i.manifest.steps.length}`:`unknown`};return f(JSON.stringify(s,null,2))}catch(e){return d.error(`flow_status failed`,u(e)),f(`Error: ${p(e)}`)}});let E=e(`flow_read_instruction`);c.registerTool(`flow_read_instruction`,{title:E.title===`flow_read_instruction`?`Flow Read Instruction`:E.title,description:`Read the instruction content for a flow step. If step is omitted, reads the current step.`,annotations:E.title===`flow_read_instruction`?{readOnlyHint:!0,idempotentHint:!0}:E.annotations,inputSchema:{step:o.string().optional().describe(`Step id or name to read. Defaults to the current step.`)}},async({step:e})=>{try{let{registry:t,stateMachine:n}=await b(),r=n.getStatus();if(!r.success||!r.data)return f(`No active flow. Use flow_start to begin one, or flow_list to see available flows.`);let i=r.data,a=t.get(i.flow);if(!a)return f(`Flow "${i.flow}" not found in registry.`);let o=e??i.currentStep;if(!o)return f(`No current step is available for the active flow.`);let c=a.manifest.steps.find(e=>e.id===o||e.name===o);return f(c?await s(y(a,c.instruction),`utf-8`):`Step "${o}" not found in flow "${i.flow}".`)}catch(e){return d.error(`flow_read_instruction failed`,u(e)),e instanceof Error&&`code`in e&&e.code===`ENOENT`?f(`Could not read instruction file: ${e.message}`):f(`Error: ${p(e)}`)}});let D=e(`flow_reset`);c.registerTool(`flow_reset`,{title:D.title,description:`Reset the active flow, clearing all state. Use to start over or switch to a different flow.`,annotations:D.annotations,inputSchema:{}},async()=>{try{let{stateMachine:e}=await b(),t=e.reset();return t.success?f(`Flow state reset. Use flow_start to begin a new flow.`):f(`Reset failed: ${t.error}`)}catch(e){return d.error(`flow_reset failed`,u(e)),f(`Error: ${p(e)}`)}});let O=e(`flow_add`);c.registerTool(`flow_add`,{title:O.title,description:`Install a new development flow from a git repository URL or local directory path. Use when the user wants to add, install, import, or onboard a new workflow — for example: "use this as a flow", "add this flow", "add this flow URL", "install a flow", or "onboard a flow". Accepts git URLs (https://..., git@...) and local filesystem paths.`,annotations:O.annotations,inputSchema:{source:o.string().describe(`Git repository URL (https://... or git@...) or absolute/local directory path containing a flow definition.`),name:o.string().optional().describe(`Optional override for the installed flow name. If omitted, the name comes from the flow manifest.`)}},async({source:e,name:t})=>{try{let{registry:r,loader:a,installer:o}=await b(),s=/^https?:\/\/|^git@/.test(e),c;if(s){let t=o.clone(e);if(!t.success||!t.data)return f(`Failed to clone flow: ${t.error}`);c=t.data}else{let r=i(e),a=t||n(r)||`custom-flow`,s=o.copyLocal(r,a);if(!s.success||!s.data)return f(`Failed to copy flow: ${s.error}`);c=s.data}let l=await a.load(c);if(!l.success||!l.data)return o.remove(c),f(`Failed to load flow manifest: ${l.error}`);let{manifest:u,format:d}=l.data,p=t||u.name;if(r.has(p))return o.remove(c),f(`Flow "${p}" is already installed. Use flow_update to update it, or flow_remove then flow_add to replace.`);if(u.install.length>0){let e=o.runInstallDeps(u.install);if(!e.success)return o.remove(c),f(`Dependency install failed: ${e.error}`)}let m=new Date().toISOString(),h=s?o.getLocalCommit(c):void 0,g=r.register({name:p,version:u.version,source:e,sourceType:s?`git`:`local`,installPath:c,format:d,registeredAt:m,updatedAt:m,manifest:u,...h?{commitSha:h}:{}});if(!g.success)return o.remove(c),f(`Failed to register flow: ${g.error}`);let _=u.steps.length;return f(`Flow "${p}" installed successfully (${_} steps). Use flow_start({ flow: "${p}" }) to begin.`)}catch(e){return d.error(`flow_add failed`,u(e)),f(`Error: ${p(e)}`)}});let k=e(`flow_remove`);c.registerTool(`flow_remove`,{title:k.title,description:`Remove an installed flow by name. Unregisters it and deletes its files when applicable. Builtin flows cannot be removed.`,annotations:k.annotations,inputSchema:{name:o.string().describe(`Name of the flow to remove.`)}},async({name:e})=>{try{let{registry:t,installer:n}=await b();if(!t.has(e))return f(`Flow "${e}" is not installed.`);let r=t.get(e);if(!r)return f(`Flow "${e}" is not installed.`);if(r.sourceType===`builtin`)return f(`Cannot remove builtin flow "${e}".`);let i=n.remove(r.installPath);if(!i.success)return f(`Failed to remove flow files: ${i.error}`);let a=t.unregister(e);return a.success?f(`Flow "${e}" removed successfully.`):f(`Failed to unregister flow: ${a.error}`)}catch(e){return d.error(`flow_remove failed`,u(e)),f(`Error: ${p(e)}`)}});let A=e(`flow_update`);c.registerTool(`flow_update`,{title:A.title,description:`Update an installed git-based flow to its latest version by pulling changes. Only works for flows installed from git repositories.`,annotations:A.annotations,inputSchema:{name:o.string().describe(`Name of the flow to update.`)}},async({name:e})=>{try{let{registry:t,loader:n,installer:r}=await b();if(!t.has(e))return f(`Flow "${e}" is not installed.`);let i=t.get(e);if(!i||i.sourceType!==`git`)return f(`Flow "${e}" was not installed from git — cannot update. Remove and re-add instead.`);let a=r.update(i.installPath);if(!a.success)return f(`Update failed: ${a.error}`);let o=await n.load(i.installPath,{forceAssetSync:!0}),s=o.success&&o.data?o.data.manifest:null,c=o.success&&o.data?o.data.format:i.format;if(s){let e=r.getLocalCommit(i.installPath),n=t.register({...i,version:s.version,format:c,manifest:s,updatedAt:new Date().toISOString(),...e?{commitSha:e}:{}});if(!n.success)return f(`Failed to refresh flow registry entry: ${n.error}`)}let l=s?.install??i.manifest.install;if(l.length>0){let e=r.runInstallDeps(l);if(!e.success)return f(`Dependency install failed: ${e.error}`)}return f(`Flow "${e}" updated successfully.`)}catch(e){return d.error(`flow_update failed`,u(e)),f(`Error: ${p(e)}`)}})}export{m as registerFlowTools};
@@ -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=15e3){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])}const v=5*6e4;let y=null,b=null;function x(){let e=Date.now();if(y&&e-y.ts<v)return y.value;try{let t=u(h(),`.copilot`,`.aikit-scaffold.json`);if(!s(t))return y={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return y={value:n,ts:e},n}catch{return y={value:null,ts:e},null}}function S(){let e=Date.now();if(b&&e-b.ts<v)return b.value;try{let t=u(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!s(t))return b={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return b={value:n,ts:e},n}catch{return b={value:null,ts:e},null}}function C(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=x(),n=S(),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 w(c,f,h,v,y,b,C,w){let T=n(`status`);c.registerTool(`status`,{title:T.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:T.annotations},async()=>{let n=[];try{let[r,c]=await Promise.all([_(f.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),_(f.listSourcePaths(),[],`store.listSourcePaths`)]),p=r.value;r.timedOut&&n.push(`⚠ Index stats timed out — values may be incomplete`);let g=c.value;c.timedOut&&n.push(`⚠ File listing timed out`);let T=null,E=0,D=[`## AI Kit Status`,``,`- **Total Records**: ${p.totalRecords}`,`- **Total Files**: ${p.totalFiles}`,`- **Last Indexed**: ${p.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(p.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`),D.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let t=e.value;T={nodes:t.nodeCount,edges:t.edgeCount},D.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||D.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&D.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{D.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let O=b?.onboardDir??u(process.cwd(),d.aiKb),k=s(O),A=y?.onboardComplete||k;if(D.push(``,`### Onboard Status`,A?`- ✅ Complete${y?.onboardTimestamp?` (last: ${y.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${O}\``),v)try{let e=await _(v.list(),[],`curated.list`);if(e.timedOut)n.push(`⚠ Curated knowledge listing timed out`),D.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let t=e.value;E=t.length,D.push(``,`### Curated Knowledge`,t.length>0?`- ${t.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{D.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let j=0;if(p.lastIndexedAt){j=new Date(p.lastIndexedAt).getTime();let e=(Date.now()-j)/(1e3*60*60);D.push(``,`### Index Freshness`,e>24?C===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}if(C===`smart`)if(D.push(``,`### Smart Indexing`),w){let e=w();e?D.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):D.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else D.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);{try{let e=u(process.cwd(),d.data,`stash`);if(s(e)){let t=l(e).mtimeMs;t>j&&(j=t)}}catch{}let e=[];if(v)try{let t=E>0?await v.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>j&&(j=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=j>0?Date.now()-j:0;if(t>=144e5){let n=Math.floor(t/36e5);if(D.push(``,`### 🌅 Session Briefing`,`_${n}+ hours since last activity — here's what to pick up:_`,``),e.length>0){D.push(`**Recent decisions/notes:**`);for(let t of e)D.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}D.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")}}D.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${m.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`);let M=x(),N=S(),P=a(),F=M!=null&&M!==P,I=N!=null&&N!==P;if(F||I){let e=o(),t=[];F&&t.push(`user scaffold v${M}`),I&&t.push(`workspace scaffold v${N}`);let n=t.join(`, `);e.state===`success`?D.push(``,`### ✅ Upgrade Applied`,`- Server v${P} — ${n} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?D.push(``,`### ⏳ Upgrade In Progress`,`- Server v${P} ≠ ${n}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(i(),D.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${P} ≠ ${n}`,`- Error: ${e.error??`unknown`}`)):(i(),D.push(``,`### ⬆ Upgrade Available`,`- Server v${P} ≠ ${n}`,`- Auto-upgrade triggered — check again shortly.`))}n.length>0&&D.push(``,`### ⚠ Warnings`,...n.map(e=>`- ${e}`));let L=t();if(L.length>0){let e=L.sort((e,t)=>t.callCount-e.callCount);D.push(``,`### Tool Usage This Session`,``),D.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),D.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);D.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let R=e();if(R.bufferSize>=10){let e=R.state===`healthy`?`🟢`:R.state===`degraded`?`🔴`:`🟡`;D.push(``,`### Auto-GC: ${e} ${R.state}`),D.push(`- p95 latency: ${R.p95}ms | buffer: ${R.bufferSize} samples`),R.gcCount>0&&D.push(`- GC cycles triggered: ${R.gcCount}`)}let z=D.join(`
3
- `),B={totalRecords:p.totalRecords,totalFiles:p.totalFiles,lastIndexedAt:p.lastIndexedAt??null,onboarded:A,onboardDir:O,contentTypes:p.contentTypeBreakdown,wasmAvailable:!!m.get(),graphStats:T,curatedCount:E,serverVersion:P,scaffoldVersion:M??null,workspaceScaffoldVersion:N??null,upgradeAvailable:F||I};return{content:[{type:`text`,text:z+(C===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph(stats)` to explore the knowledge graph. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._")}],structuredContent:B}}catch(e){return g.error(`Status failed`,p(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{x as getScaffoldVersion,S as getWorkspaceScaffoldVersion,C as registerEarlyStatusTool,w as registerStatusTool};
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{homedir as d}from"node:os";import{AIKIT_PATHS as f,createLogger as p,serializeError as m}from"../../../core/dist/index.js";import{WasmRuntime as h}from"../../../chunker/dist/index.js";const g=p(`tools`);function _(e,t,n,r=15e3){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])}const v=5*6e4;let y=null,b=null;function x(){let e=Date.now();if(y&&e-y.ts<v)return y.value;try{let t=u(d(),`.copilot`,`.aikit-scaffold.json`);if(!s(t))return y={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return y={value:n,ts:e},n}catch{return y={value:null,ts:e},null}}function S(){let e=Date.now();if(b&&e-b.ts<v)return b.value;try{let t=u(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!s(t))return b={value:null,ts:e},null;let n=JSON.parse(c(t,`utf-8`)).version??null;return b={value:n,ts:e},n}catch{return b={value:null,ts:e},null}}function C(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=x(),n=S(),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)**: ${h.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:!!h.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 w(c,d,p,v,y,b,C,w){let T=n(`status`);c.registerTool(`status`,{title:T.title,description:`Get the current status and statistics of the AI Kit index.`,outputSchema:r,annotations:T.annotations},async()=>{let n=[];try{let[r,c]=await Promise.all([_(d.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),_(d.listSourcePaths(),[],`store.listSourcePaths`)]),m=r.value;r.timedOut&&n.push(`⚠ Index stats timed out — values may be incomplete`);let g=c.value;c.timedOut&&n.push(`⚠ File listing timed out`);let T=null,E=0,D=[`## AI Kit Status`,``,`- **Total Records**: ${m.totalRecords}`,`- **Total Files**: ${m.totalFiles}`,`- **Last Indexed**: ${m.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(m.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(p)try{let e=await _(p.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(e.timedOut)n.push(`⚠ Graph stats timed out`),D.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let t=e.value;T={nodes:t.nodeCount,edges:t.edgeCount},D.push(``,`### Knowledge Graph`,`- **Nodes**: ${t.nodeCount}`,`- **Edges**: ${t.edgeCount}`,...Object.entries(t.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await _(p.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||D.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&D.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{D.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let O=b?.onboardDir??u(process.cwd(),f.aiKb),k=s(O),A=y?.onboardComplete||k;if(D.push(``,`### Onboard Status`,A?`- ✅ Complete${y?.onboardTimestamp?` (last: ${y.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${O}\``),v)try{let e=await _(v.list(),[],`curated.list`);if(e.timedOut)n.push(`⚠ Curated knowledge listing timed out`),D.push(``,`### Curated Knowledge`,`- Listing timed out`);else{let t=e.value;E=t.length,D.push(``,`### Curated Knowledge`,t.length>0?`- ${t.length} entries`:"- Empty — use `remember()` to persist decisions")}}catch{D.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let j=0;if(m.lastIndexedAt){j=new Date(m.lastIndexedAt).getTime();let e=(Date.now()-j)/(1e3*60*60);D.push(``,`### Index Freshness`,e>24?C===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}if(C===`smart`)if(D.push(``,`### Smart Indexing`),w){let e=w();e?D.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):D.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else D.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);{try{let e=u(process.cwd(),f.data,`stash`);if(s(e)){let t=l(e).mtimeMs;t>j&&(j=t)}}catch{}let e=[];if(v)try{let t=E>0?await v.list():[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>j&&(j=t)}e.push(...t.sort((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()).slice(0,5))}catch{}let t=j>0?Date.now()-j:0;if(t>=144e5){let n=Math.floor(t/36e5);if(D.push(``,`### 🌅 Session Briefing`,`_${n}+ hours since last activity — here's what to pick up:_`,``),e.length>0){D.push(`**Recent decisions/notes:**`);for(let t of e)D.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}D.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")}}D.push(``,`### Runtime`,`- **Tree-sitter (WASM)**: ${h.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`);let M=x(),N=S(),P=a(),F=M!=null&&M!==P,I=N!=null&&N!==P;if(F||I){let e=o(),t=[];F&&t.push(`user scaffold v${M}`),I&&t.push(`workspace scaffold v${N}`);let n=t.join(`, `);e.state===`success`?D.push(``,`### ✅ Upgrade Applied`,`- Server v${P} — ${n} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?D.push(``,`### ⏳ Upgrade In Progress`,`- Server v${P} ≠ ${n}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(i(),D.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${P} ≠ ${n}`,`- Error: ${e.error??`unknown`}`)):(i(),D.push(``,`### ⬆ Upgrade Available`,`- Server v${P} ≠ ${n}`,`- Auto-upgrade triggered — check again shortly.`))}n.length>0&&D.push(``,`### ⚠ Warnings`,...n.map(e=>`- ${e}`));let L=t();if(L.length>0){let e=L.sort((e,t)=>t.callCount-e.callCount);D.push(``,`### Tool Usage This Session`,``),D.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),D.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);D.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let R=e();if(R.bufferSize>=10){let e=R.state===`healthy`?`🟢`:R.state===`degraded`?`🔴`:`🟡`;D.push(``,`### Auto-GC: ${e} ${R.state}`),D.push(`- p95 latency: ${R.p95}ms | buffer: ${R.bufferSize} samples`),R.gcCount>0&&D.push(`- GC cycles triggered: ${R.gcCount}`)}let z=D.join(`
3
+ `),B={totalRecords:m.totalRecords,totalFiles:m.totalFiles,lastIndexedAt:m.lastIndexedAt??null,onboarded:A,onboardDir:O,contentTypes:m.contentTypeBreakdown,wasmAvailable:!!h.get(),graphStats:T,curatedCount:E,serverVersion:P,scaffoldVersion:M??null,workspaceScaffoldVersion:N??null,upgradeAvailable:F||I};return{content:[{type:`text`,text:z+(C===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph(stats)` to explore the knowledge graph. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph(stats)` to explore the knowledge graph, or `reindex` to refresh the index._")}],structuredContent:B}}catch(e){return g.error(`Status failed`,m(e)),{content:[{type:`text`,text:`Status check failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{x as getScaffoldVersion,S as getWorkspaceScaffoldVersion,C as registerEarlyStatusTool,w as registerStatusTool};
@@ -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 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:`.`}}]},{name:`indexing`,description:`Manage smart indexing, trickle mode, and index maintenance`,keywords:[`index`,`indexing`,`smart index`,`trickle`,`reindex`,`index mode`,`index status`,`queue`,`stale index`],tools:[{tool:`status`,reason:`Check index mode, queue size, and freshness`,order:1},{tool:`reindex`,reason:`Force a full reindex (only when smart mode cannot keep up)`,order:2,suggestedArgs:{force:!0}},{tool:`produce_knowledge`,reason:`Regenerate curated resource analysis`,order:3,suggestedArgs:{path:`.`}}]}];function t(t,n=5,r){let i=t.toLowerCase(),a=e.map(e=>{let t=0;for(let n of e.keywords)i.includes(n)&&(t+=n.includes(` `)?2:1);return{workflow:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score),o=e.find(e=>e.name===`search`)??e[0],s=a[0]?.workflow??o,c=a.slice(1,4).map(e=>e.workflow.name).filter(e=>e!==s.name),l={workflow:s.name,description:s.description,tools:s.tools.slice(0,n),alternativeWorkflows:c};return r===`smart`&&(l.tools=l.tools.map(e=>e.tool===`reindex`?{...e,reason:`Smart indexing is active — files are indexed automatically. Use reindex({ force: true }) only if the index is severely outdated.`,suggestedArgs:{force:!0}}:e)),l}export{t as guide};
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:`.`}}]},{name:`flow`,description:`Manage development flows — structured step-by-step processes for tasks`,keywords:[`flow`,`workflow`,`step`,`process`,`pipeline`,`lifecycle`,`sequence`,`start flow`,`flow status`],tools:[{tool:`flow_list`,reason:`List all available flows (builtin + custom)`,order:1},{tool:`flow_status`,reason:`Check current active flow and step`,order:2},{tool:`flow_start`,reason:`Start a named flow`,order:3},{tool:`flow_step`,reason:`Advance to next step, skip, or redo`,order:4},{tool:`flow_read_instruction`,reason:`Read the current step instruction`,order:5},{tool:`flow_info`,reason:`Get detailed info about a specific flow`,order:6},{tool:`flow_add`,reason:`Install a new custom flow`,order:7},{tool:`flow_update`,reason:`Update an existing custom flow`,order:8},{tool:`flow_remove`,reason:`Remove a custom flow`,order:9},{tool:`flow_reset`,reason:`Clear active flow state to start over`,order:10}]},{name:`web`,description:`Fetch web pages, search the web, or make HTTP API calls`,keywords:[`web`,`fetch`,`url`,`website`,`api`,`http`,`request`,`download`,`scrape`,`browse`,`web search`,`online`],tools:[{tool:`web_search`,reason:`Search the web for information`,order:1},{tool:`web_fetch`,reason:`Fetch and extract content from URLs`,order:2},{tool:`http`,reason:`Make raw HTTP requests to APIs`,order:3}]},{name:`brainstorm`,description:`Interactive ideation and creative exploration for design decisions`,keywords:[`brainstorm`,`ideate`,`ideas`,`explore`,`creative`,`design`,`options`,`approach`,`alternatives`,`think`],tools:[{tool:`brainstorm`,reason:`Interactive structured ideation session`,order:1},{tool:`search`,reason:`Find related patterns and prior art`,order:2,suggestedArgs:{origin:`curated`}},{tool:`remember`,reason:`Persist chosen direction as a decision`,order:3,suggestedArgs:{category:`decisions`}}]},{name:`present`,description:`Display rich visual content — dashboards, charts, tables, timelines`,keywords:[`present`,`dashboard`,`chart`,`table`,`visualize`,`display`,`show`,`render`,`report`,`timeline`],tools:[{tool:`present`,reason:`Render rich HTML dashboards, charts, and tables`,order:1},{tool:`analyze_diagram`,reason:`Generate Mermaid diagrams for architecture views`,order:2},{tool:`measure`,reason:`Collect metrics to visualize`,order:3}]},{name:`quality`,description:`FORGE quality gates — classify task complexity, ground requirements, verify evidence`,keywords:[`quality`,`forge`,`evidence`,`gate`,`classify`,`ground`,`tier`,`critical`,`verify`,`proof`],tools:[{tool:`forge_classify`,reason:`Determine task tier (Floor/Standard/Critical)`,order:1},{tool:`forge_ground`,reason:`Ground requirements with evidence criteria`,order:2},{tool:`evidence_map`,reason:`Map evidence and run quality gates`,order:3,suggestedArgs:{action:`gate`}},{tool:`check`,reason:`Typecheck + lint validation`,order:4},{tool:`test_run`,reason:`Run tests for coverage evidence`,order:5}]},{name:`transform`,description:`Automated code transformations — codemods, renames, data transforms`,keywords:[`transform`,`codemod`,`rename`,`replace`,`migrate`,`convert`,`data transform`,`rewrite`,`bulk edit`],tools:[{tool:`rename`,reason:`Safe cross-file symbol rename`,order:1},{tool:`codemod`,reason:`Apply AST-level code transformations`,order:2},{tool:`data_transform`,reason:`Transform data between formats`,order:3},{tool:`diff_parse`,reason:`Parse and analyze diffs`,order:4},{tool:`blast_radius`,reason:`Check impact of transformations`,order:5}]},{name:`git`,description:`Git context, changelogs, and version tracking`,keywords:[`git`,`commit`,`diff`,`changelog`,`history`,`branch`,`version`,`release`,`changes`,`what changed`],tools:[{tool:`git_context`,reason:`Get git status, diff, and branch info`,order:1},{tool:`changelog`,reason:`Generate changelog from git history`,order:2},{tool:`blast_radius`,reason:`Assess impact of changed files`,order:3}]},{name:`indexing`,description:`Manage smart indexing, trickle mode, and index maintenance`,keywords:[`index`,`indexing`,`smart index`,`trickle`,`reindex`,`index mode`,`index status`,`queue`,`stale index`],tools:[{tool:`status`,reason:`Check index mode, queue size, and freshness`,order:1},{tool:`reindex`,reason:`Force a full reindex (only when smart mode cannot keep up)`,order:2,suggestedArgs:{force:!0}},{tool:`produce_knowledge`,reason:`Regenerate curated resource analysis`,order:3,suggestedArgs:{path:`.`}}]}];function t(t,n=5,r){let i=t.toLowerCase(),a=e.map(e=>{let t=0;for(let n of e.keywords)i.includes(n)&&(t+=n.includes(` `)?2:1);return{workflow:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score),o=e.find(e=>e.name===`search`)??e[0],s=a[0]?.workflow??o,c=a.slice(1,4).map(e=>e.workflow.name).filter(e=>e!==s.name),l={workflow:s.name,description:s.description,tools:s.tools.slice(0,n),alternativeWorkflows:c};return r===`smart`&&(l.tools=l.tools.map(e=>e.tool===`reindex`?{...e,reason:`Smart indexing is active — files are indexed automatically. Use reindex({ force: true }) only if the index is severely outdated.`,suggestedArgs:{force:!0}}:e)),l}export{t as guide};