@vpxa/aikit 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/cli/dist/commands/init/adapters.js +1 -1
- package/packages/cli/dist/commands/init/user.d.ts +2 -2
- package/packages/cli/dist/commands/init/user.js +4 -4
- package/packages/server/dist/server.js +1 -1
- package/packages/server/dist/tool-metadata.js +1 -1
- package/packages/server/dist/tools/flow.tools.js +1 -1
- package/packages/server/dist/tools/present/tool.js +3 -3
- package/packages/server/dist/tools/status.tool.js +1 -1
- package/scaffold/definitions/protocols.mjs +25 -2
- package/scaffold/general/agents/Orchestrator.agent.md +48 -30
- package/scaffold/general/agents/_shared/code-agent-base.md +25 -10
- package/scaffold/general/skills/aikit/SKILL.md +49 -98
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{MCP_SERVER_ENTRY as e}from"./constants.js";import{buildAgentsMd as t,buildCopilotInstructions as n}from"./templates.js";import{existsSync as r,mkdirSync as i,writeFileSync as
|
|
1
|
+
import{MCP_SERVER_ENTRY as e}from"./constants.js";import{buildAgentsMd as t,buildCopilotInstructions as n}from"./templates.js";import{existsSync as r,mkdirSync as i,unlinkSync as a,writeFileSync as o}from"node:fs";import{basename as s,resolve as c}from"node:path";function l(e){return r(c(e,`.cursor`))?`cursor`:r(c(e,`.claude`))?`claude-code`:r(c(e,`.windsurf`))?`windsurf`:`copilot`}function u(t){return{servers:{[t]:{...e}}}}function d(t){let{type:n,...r}=e;return{mcpServers:{[t]:r}}}const f={scaffoldDir:`general`,writeMcpConfig(e,t){let n=c(e,`.vscode`),a=c(n,`mcp.json`);r(a)||(i(n,{recursive:!0}),o(a,`${JSON.stringify(u(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json`))},writeInstructions(e,t){let r=c(e,`.github`),a=c(r,`copilot-instructions.md`);i(r,{recursive:!0}),o(a,n(s(e),t),`utf-8`),console.log(` Updated .github/copilot-instructions.md`)},writeAgentsMd(e,n){o(c(e,`AGENTS.md`),t(s(e),n),`utf-8`),console.log(` Updated AGENTS.md`)}},p={scaffoldDir:`general`,writeMcpConfig(e,t){let n=c(e,`.mcp.json`);r(n)||(o(n,`${JSON.stringify(d(t),null,2)}\n`,`utf-8`),console.log(` Created .mcp.json`))},writeInstructions(e,r){let i=c(e,`CLAUDE.md`),a=s(e);o(i,`${n(a,r)}\n---\n\n${t(a,r)}`,`utf-8`),console.log(` Updated CLAUDE.md`)},writeAgentsMd(e,t){}},m={scaffoldDir:`general`,writeMcpConfig(e,t){let n=c(e,`.cursor`),a=c(n,`mcp.json`);r(a)||(i(n,{recursive:!0}),o(a,`${JSON.stringify(d(t),null,2)}\n`,`utf-8`),console.log(` Created .cursor/mcp.json`))},writeInstructions(e,l){let u=c(e,`.cursor`,`rules`),d=c(u,`aikit.mdc`);i(u,{recursive:!0});let f=s(e);o(d,`${n(f,l)}\n---\n\n${t(f,l)}`,`utf-8`),console.log(` Updated .cursor/rules/aikit.mdc`);let p=c(u,`kb.mdc`);r(p)&&p!==d&&(a(p),console.log(` Removed legacy .cursor/rules/kb.mdc`))},writeAgentsMd(e,t){}},h={scaffoldDir:`general`,writeMcpConfig(e,t){let n=c(e,`.vscode`),a=c(n,`mcp.json`);r(a)||(i(n,{recursive:!0}),o(a,`${JSON.stringify(u(t),null,2)}\n`,`utf-8`),console.log(` Created .vscode/mcp.json (Windsurf-compatible)`))},writeInstructions(e,r){let i=c(e,`.windsurfrules`),a=s(e);o(i,`${n(a,r)}\n---\n\n${t(a,r)}`,`utf-8`),console.log(` Updated .windsurfrules`)},writeAgentsMd(e,t){}};function g(e){switch(e){case`copilot`:return f;case`claude-code`:return p;case`cursor`:return m;case`windsurf`:return h}}export{p as claudeCodeAdapter,f as copilotAdapter,m as cursorAdapter,l as detectIde,g as getAdapter,h as windsurfAdapter};
|
|
@@ -44,8 +44,8 @@ declare function writeVscodeSettings(idePath: UserLevelIdePath, force?: boolean)
|
|
|
44
44
|
* Each IDE has its own global discovery path:
|
|
45
45
|
* - VS Code / VSCodium: ~/.copilot/ (agents/, prompts/, skills/, instructions/)
|
|
46
46
|
* - Claude Code: ~/.claude/ (CLAUDE.md, agents/)
|
|
47
|
-
* - Cursor: ~/.cursor/ (rules/
|
|
48
|
-
* - Windsurf: ~/.windsurf/ (rules/
|
|
47
|
+
* - Cursor: ~/.cursor/ (rules/aikit.mdc, agents/, prompts/, skills/)
|
|
48
|
+
* - Windsurf: ~/.windsurf/ (rules/aikit.md, agents/, prompts/, skills/)
|
|
49
49
|
*
|
|
50
50
|
* Multiple IDEs may share the same root (e.g. VS Code + VSCodium both use ~/.copilot/).
|
|
51
51
|
* We deduplicate scaffold files but generate IDE-specific instruction files.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{FLOW_DIRS as e,MCP_SERVER_ENTRY as t,SERVER_NAME as n,SKILL_NAMES as r,VSCODE_SETTINGS as i}from"./constants.js";import{buildAgentsMd as a,buildCopilotInstructions as o}from"./templates.js";import{smartCopySubdir as s}from"./scaffold.js";import{existsSync as c,mkdirSync as l,readFileSync as u,writeFileSync as
|
|
2
|
-
No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${o.length} IDE(s):`);for(let n of o)
|
|
3
|
-
Installing scaffold files:`),
|
|
1
|
+
import{FLOW_DIRS as e,MCP_SERVER_ENTRY as t,SERVER_NAME as n,SKILL_NAMES as r,VSCODE_SETTINGS as i}from"./constants.js";import{buildAgentsMd as a,buildCopilotInstructions as o}from"./templates.js";import{smartCopySubdir as s}from"./scaffold.js";import{existsSync as c,mkdirSync as l,readFileSync as u,unlinkSync as d,writeFileSync as f}from"node:fs";import{dirname as p,resolve as m}from"node:path";import{fileURLToPath as h}from"node:url";import{getGlobalDataDir as g,saveRegistry as _}from"../../../../core/dist/index.js";import{homedir as v}from"node:os";function y(){let e=v(),t=process.platform,n=[],r=m(e,`.copilot`),i=m(r,`instructions`),a=m(e,`.claude`),o=m(e,`.cursor`),s=m(e,`.windsurf`);if(t===`win32`){let t=process.env.APPDATA??m(e,`AppData`,`Roaming`);n.push({ide:`VS Code`,configDir:m(t,`Code`,`User`),mcpConfigPath:m(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:m(t,`Code - Insiders`,`User`),mcpConfigPath:m(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:m(t,`VSCodium`,`User`),mcpConfigPath:m(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:m(t,`Cursor`,`User`),mcpConfigPath:m(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:m(t,`Cursor Nightly`,`User`),mcpConfigPath:m(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:m(t,`Windsurf`,`User`),mcpConfigPath:m(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}else if(t===`darwin`){let t=m(e,`Library`,`Application Support`);n.push({ide:`VS Code`,configDir:m(t,`Code`,`User`),mcpConfigPath:m(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:m(t,`Code - Insiders`,`User`),mcpConfigPath:m(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:m(t,`VSCodium`,`User`),mcpConfigPath:m(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:m(t,`Cursor`,`User`),mcpConfigPath:m(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:m(t,`Cursor Nightly`,`User`),mcpConfigPath:m(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:m(t,`Windsurf`,`User`),mcpConfigPath:m(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}else{let t=process.env.XDG_CONFIG_HOME??m(e,`.config`);n.push({ide:`VS Code`,configDir:m(t,`Code`,`User`),mcpConfigPath:m(t,`Code`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VS Code Insiders`,configDir:m(t,`Code - Insiders`,`User`),mcpConfigPath:m(t,`Code - Insiders`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`VSCodium`,configDir:m(t,`VSCodium`,`User`),mcpConfigPath:m(t,`VSCodium`,`User`,`mcp.json`),globalScaffoldRoot:r,instructionsRoot:i},{ide:`Cursor`,configDir:m(t,`Cursor`,`User`),mcpConfigPath:m(t,`Cursor`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Cursor Nightly`,configDir:m(t,`Cursor Nightly`,`User`),mcpConfigPath:m(t,`Cursor Nightly`,`User`,`mcp.json`),globalScaffoldRoot:o,instructionsRoot:null},{ide:`Windsurf`,configDir:m(t,`Windsurf`,`User`),mcpConfigPath:m(t,`Windsurf`,`User`,`mcp.json`),globalScaffoldRoot:s,instructionsRoot:null})}return n.push({ide:`Claude Code`,configDir:m(e,`.claude`),mcpConfigPath:m(e,`.claude`,`mcp.json`),globalScaffoldRoot:a,instructionsRoot:null}),n.filter(e=>c(e.configDir))}function b(e,n,r=!1){let{mcpConfigPath:i,configDir:a}=e,o={...t},s={};if(c(i)){try{let e=u(i,`utf-8`);s=JSON.parse(e)}catch{let e=`${i}.bak`;f(e,u(i,`utf-8`),`utf-8`),console.log(` Backed up invalid ${i} to ${e}`),s={}}if((s.servers??s.mcpServers??{})[n]&&!r){console.log(` ${e.ide}: ${n} already configured (use --force to update)`);return}}let d=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`,`Windsurf`]).has(e.ide)?`servers`:`mcpServers`,p=s[d]??{};p[n]=o,s[d]=p,l(a,{recursive:!0}),f(i,`${JSON.stringify(s,null,2)}\n`,`utf-8`),console.log(` ${e.ide}: configured ${n} in ${i}`)}const x=new Set([`VS Code`,`VS Code Insiders`,`VSCodium`]);function S(e,t=!1){if(!x.has(e.ide))return;let n=m(e.configDir,`settings.json`),r={};if(c(n))try{let e=u(n,`utf-8`);r=JSON.parse(e)}catch{console.log(` ${e.ide}: skipped settings.json (invalid JSON)`);return}let a=!1;for(let[e,n]of Object.entries(i))if(typeof n==`object`&&n){let t=typeof r[e]==`object`&&r[e]!==null?r[e]:{},i={...t,...n};JSON.stringify(i)!==JSON.stringify(t)&&(r[e]=i,a=!0)}else (t||!(e in r))&&(r[e]=n,a=!0);a&&(f(n,`${JSON.stringify(r,null,2)}\n`,`utf-8`),console.log(` ${e.ide}: updated settings.json`))}function C(t,n,i,u,d=!1){let p=new Set;for(let e of n)e.globalScaffoldRoot&&p.add(e.globalScaffoldRoot);if(p.size===0){console.log(` No IDEs with global scaffold support detected.`);return}let h=m(t,`scaffold`,`general`);for(let n of p){s(h,n,`agents`,u,d),s(h,n,`prompts`,u,d);let i=0;for(let e of r)c(m(h,`skills`,e))&&(s(h,n,`skills/${e}`,u,d),i++);for(let r of e){let e=m(t,`scaffold`,`flows`,r);c(m(e,`skills`))&&s(e,m(n,`flows`,r),`skills`,u,d)}console.log(` ${n}: scaffold updated (${i} skills)`)}let g=new Set,_=o(`aikit`,i),v=a(`aikit`,i);for(let e of n){if(!e.globalScaffoldRoot)continue;let t=e.globalScaffoldRoot;if(e.ide===`Claude Code`){let e=m(t,`CLAUDE.md`);f(e,`${_}\n---\n\n${v}`,`utf-8`),g.add(e)}else if(e.ide===`VS Code`||e.ide===`VS Code Insiders`||e.ide===`VSCodium`){let n=e.instructionsRoot??t;l(n,{recursive:!0});let r=m(n,`aikit.instructions.md`);g.has(r)||(f(r,`---\napplyTo: "**"\n---\n\n${_}\n---\n\n${v}`,`utf-8`),g.add(r))}else if(e.ide===`Cursor`||e.ide===`Cursor Nightly`){let e=m(t,`rules`);l(e,{recursive:!0});let n=m(e,`aikit.mdc`);g.has(n)||(f(n,`${_}\n---\n\n${v}`,`utf-8`),g.add(n))}else if(e.ide===`Windsurf`){let e=m(t,`rules`);l(e,{recursive:!0});let n=m(e,`aikit.md`);g.has(n)||(f(n,`${_}\n---\n\n${v}`,`utf-8`),g.add(n))}}g.size>0&&console.log(` Instruction files: ${[...g].join(`, `)}`)}function w(e){let t=[];for(let n of e){if(!n.globalScaffoldRoot)continue;let e=n.globalScaffoldRoot;if(n.ide===`VS Code`||n.ide===`VS Code Insiders`||n.ide===`VSCodium`){let r=n.instructionsRoot??e;t.push(m(r,`kb.instructions.md`))}else n.ide===`Cursor`||n.ide===`Cursor Nightly`?t.push(m(e,`rules`,`kb.mdc`)):n.ide===`Windsurf`&&t.push(m(e,`rules`,`kb.md`))}for(let e of t)c(e)&&(d(e),console.log(` Removed legacy file: ${e}`))}async function T(e){let t=n,r=m(p(h(import.meta.url)),`..`,`..`,`..`,`..`,`..`,`package.json`),i=JSON.parse(u(r,`utf-8`)).version;console.log(`Initializing @vpxa/aikit v${i}...\n`);let a=g();l(a,{recursive:!0}),console.log(` Global data store: ${a}`),_({version:1,workspaces:{}}),console.log(` Created registry.json`);let o=y();if(o.length===0)console.log(`
|
|
2
|
+
No supported IDEs detected. You can manually add the MCP server config.`);else{console.log(`\n Detected ${o.length} IDE(s):`);for(let n of o)b(n,t,e.force),S(n,e.force)}let s=m(p(h(import.meta.url)),`..`,`..`,`..`,`..`,`..`);console.log(`
|
|
3
|
+
Installing scaffold files:`),C(s,o,t,i,e.force),w(o),console.log(`
|
|
4
4
|
User-level AI Kit installation complete!`),console.log(`
|
|
5
|
-
Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}export{
|
|
5
|
+
Next steps:`),console.log(` 1. Open any workspace in your IDE`),console.log(` 2. The AI Kit server will auto-start and index the workspace`),console.log(` 3. Agents, prompts, skills & instructions are available globally`),console.log(` 4. No per-workspace init needed — just open a project and start coding`)}export{y as detectInstalledIdes,T as initUser,C as installGlobalScaffold,b as writeUserLevelMcpConfig,S as writeVscodeSettings};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{BackgroundTaskScheduler as e}from"./background-task.js";import{clearCompletionCache as t}from"./completions.js";import{CuratedKnowledgeManager as n}from"./curated-manager.js";import{createElicitor as r,noopElicitor as i}from"./elicitor.js";import{IdleTimer as a}from"./idle-timer.js";import{bridgeMcpLogging as o}from"./mcp-logging.js";import{MemoryMonitor as s}from"./memory-monitor.js";import{registerPrompts as c}from"./prompts.js";import{installReplayInterceptor as l}from"./replay-interceptor.js";import{ResourceNotifier as u}from"./resources/resource-notifier.js";import{registerResources as d}from"./resources/resources.js";import{createSamplingClient as f}from"./sampling.js";import{installStructuredContentGuard as p}from"./structured-content-guard.js";import{getToolMeta as m}from"./tool-metadata.js";import{installToolPrefix as h}from"./tool-prefix.js";import{ToolTimeoutError as g,getToolTimeout as _,withTimeout as v}from"./tool-timeout.js";import{registerAnalyzeDependenciesTool as y,registerAnalyzeDiagramTool as b,registerAnalyzeEntryPointsTool as x,registerAnalyzePatternsTool as S,registerAnalyzeStructureTool as ee,registerAnalyzeSymbolsTool as C,registerBlastRadiusTool as w}from"./tools/analyze.tools.js";import{registerAuditTool as T}from"./tools/audit.tool.js";import{registerBrainstormTool as E}from"./tools/brainstorm.tool.js";import{initBridgeComponents as te,registerErPullTool as D,registerErPushTool as O,registerErSyncStatusTool as k}from"./tools/bridge.tools.js";import{registerConfigTool as ne}from"./tools/config.tool.js";import{registerCompactTool as A,registerDeadSymbolsTool as j,registerFileSummaryTool as M,registerFindTool as N,registerScopeMapTool as re,registerSymbolTool as P,registerTraceTool as F}from"./tools/context.tools.js";import{registerErEvolveReviewTool as ie}from"./tools/evolution.tools.js";import{registerBatchTool as ae,registerCheckTool as oe,registerDelegateTool as se,registerEvalTool as ce,registerParseOutputTool as le,registerTestRunTool as I}from"./tools/execution.tools.js";import{registerFlowTools as ue}from"./tools/flow.tools.js";import{registerDigestTool as de,registerEvidenceMapTool as L,registerForgeClassifyTool as R,registerForgeGroundTool as fe,registerStratumCardTool as pe}from"./tools/forge.tools.js";import{registerForgetTool as me}from"./tools/forget.tool.js";import{registerGraphTool as he}from"./tools/graph.tool.js";import{registerGuideTool as z,registerHealthTool as B,registerProcessTool as V,registerWatchTool as H,registerWebFetchTool as U}from"./tools/infra.tools.js";import{registerListTool as ge}from"./tools/list.tool.js";import{registerLookupTool as _e}from"./tools/lookup.tool.js";import{registerCodemodTool as W,registerDataTransformTool as G,registerDiffParseTool as K,registerGitContextTool as q,registerRenameTool as ve}from"./tools/manipulation.tools.js";import{registerOnboardTool as ye}from"./tools/onboard.tool.js";import{registerCheckpointTool as be,registerLaneTool as xe,registerQueueTool as Se,registerStashTool as Ce,registerWorksetTool as we}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as Te}from"./tools/policy.tools.js";import{registerPresentTool as Ee}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as De}from"./tools/produce.tool.js";import{registerReadTool as Oe}from"./tools/read.tool.js";import{registerReindexTool as ke}from"./tools/reindex.tool.js";import{registerRememberTool as Ae}from"./tools/remember.tool.js";import{registerReplayTool as je}from"./tools/replay.tool.js";import{registerRestoreTool as Me}from"./tools/restore.tool.js";import{registerSearchTool as Ne}from"./tools/search.tool.js";import{getCurrentVersion as Pe}from"./version-check.js";import{registerEarlyStatusTool as Fe,registerStatusTool as Ie}from"./tools/status.tool.js";import{registerUpdateTool as Le}from"./tools/update.tool.js";import{registerChangelogTool as Re,registerEncodeTool as ze,registerEnvTool as Be,registerHttpTool as Ve,registerMeasureTool as He,registerRegexTestTool as Ue,registerSchemaValidateTool as We,registerSnippetTool as Ge,registerTimeTool as J,registerWebSearchTool as Ke}from"./tools/utility.tools.js";import{existsSync as qe,statSync as Je}from"node:fs";import{resolve as Ye}from"node:path";import{AIKIT_PATHS as Xe,createLogger as Ze,serializeError as Y}from"../../core/dist/index.js";import{initializeWasm as Qe}from"../../chunker/dist/index.js";import{OnnxEmbedder as $e}from"../../embeddings/dist/index.js";import{EvolutionCollector as et,PolicyStore as tt}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as nt,IncrementalIndexer as rt}from"../../indexer/dist/index.js";import{SqliteGraphStore as it,createStore as at}from"../../store/dist/index.js";import{FileCache as ot}from"../../tools/dist/index.js";import{McpServer as st}from"@modelcontextprotocol/sdk/server/mcp.js";const X=Ze(`server`);async function Z(e){X.info(`Initializing AI Kit components`);let[t,r,i,a]=await Promise.all([(async()=>{let t=new $e({model:e.embedding.model,dimensions:e.embedding.dimensions});return await t.initialize(),X.info(`Embedder loaded`,{modelId:t.modelId,dimensions:t.dimensions}),t})(),(async()=>{let t=await at({backend:e.store.backend,path:e.store.path});return await t.initialize(),X.info(`Store initialized`),t})(),(async()=>{let t=new it({path:e.store.path});return await t.initialize(),X.info(`Graph store initialized`),t})(),(async()=>{let e=await Qe();return e?X.info(`WASM tree-sitter enabled for AST analysis`):X.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),o=new rt(t,r),s=new nt(e.store.path);s.load(),o.setHashCache(s);let c=e.curated.path,l=new n(c,r,t);o.setGraphStore(i);let u=te(e.er),d=u?new tt(e.curated.path):void 0;d&&X.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new et:void 0,p=Ye(e.sources[0]?.path??process.cwd(),Xe.aiKb),m=qe(p),h=e.onboardDir?qe(e.onboardDir):!1,g=m||h,_,v=m?p:e.onboardDir;if(g&&v)try{_=Je(v).mtime.toISOString()}catch{}return X.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:t,store:r,indexer:o,curated:l,graphStore:i,fileCache:new ot,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function ct(e,t){let n=new st({name:t.serverName??`aikit`,version:Pe()},{capabilities:{logging:{}}});return o(n),h(n,t.toolPrefix??``),Q(n,e,t,r(n),new u(n),f(n)),c(n,{curated:e.curated,store:e.store,graphStore:e.graphStore},t.indexMode),n}function Q(e,t,n,r,i,a,o,s){l(e),p(e),Ne(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,a),_e(e,t.store),Ie(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n,o,s),ne(e,n),ke(e,t.indexer,n,t.curated,t.store,i,o),Ae(e,t.curated,t.policyStore,t.evolutionCollector,i),Le(e,t.curated,i),me(e,t.curated,i),Oe(e,t.curated),ge(e,t.curated),ee(e,t.store,t.embedder),y(e,t.store,t.embedder),C(e,t.store,t.embedder),S(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),De(e,n),ye(e,t.store,t.embedder,n),he(e,t.graphStore),T(e,t.store,t.embedder);let c=n.sources[0]?.path??process.cwd();A(e,t.embedder,t.fileCache,c),re(e,t.embedder,t.store),N(e,t.embedder,t.store),le(e),we(e),oe(e),ae(e,t.embedder,t.store),P(e,t.embedder,t.store,t.graphStore),ce(e),I(e),Ce(e),q(e),K(e),ve(e),W(e),Me(e),M(e,t.fileCache,c),be(e),G(e),F(e,t.embedder,t.store,t.graphStore),V(e),H(e),j(e,t.embedder,t.store),se(e,a),B(e),xe(e),Se(e),U(e),z(e,o),L(e),de(e,t.embedder),R(e),pe(e,t.embedder,t.fileCache),fe(e,t.embedder,t.store),Ee(e,r),r&&E(e,r),Ke(e),Ve(e),Ue(e),ze(e),He(e),Re(e),We(e),Ge(e),Be(e),J(e),ue(e,n),t.bridge&&(O(e,t.bridge,t.evolutionCollector),D(e,t.bridge),k(e,t.bridge)),t.policyStore&&Te(e,t.policyStore),t.evolutionCollector&&ie(e,t.evolutionCollector),d(e,t.store,t.curated),je(e)}async function lt(e){let t=await Z(e),n=ct(t,e);X.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);X.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&&X.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&X.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});X.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){X.warn(`FTS index creation failed`,Y(e))}try{let e=await t.curated.reindexAll();X.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){X.error(`Curated re-index failed`,Y(e))}}catch(e){X.error(`Initial index failed; will retry on aikit_reindex`,Y(e))}},i=async()=>{X.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{X.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const ut=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.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(`.`)),dt=5e3,ft=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 pt(e){oe(e),ce(e),I(e),le(e),se(e),q(e),K(e),ve(e),W(e),G(e),we(e),Ce(e),be(e),Me(e),xe(e),Se(e),B(e),V(e),H(e),U(e),z(e),L(e),R(e),Ee(e),E(e,i),De(e),je(e),Fe(e),Ke(e),Ve(e),Ue(e),ze(e),He(e),Re(e),We(e),Ge(e),Be(e),J(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 mt(n,i){let l=new st({name:n.serverName??`aikit`,version:Pe()},{capabilities:{logging:{}}}),d=`initializing`,p=``,y=!1,b=null,x=null,S=null;function ee(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 C=()=>d===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,p?`Error: ${p}`:``,``,`**35 tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
|
|
1
|
+
import{BackgroundTaskScheduler as e}from"./background-task.js";import{clearCompletionCache as t}from"./completions.js";import{CuratedKnowledgeManager as n}from"./curated-manager.js";import{createElicitor as r,noopElicitor as i}from"./elicitor.js";import{IdleTimer as a}from"./idle-timer.js";import{bridgeMcpLogging as o}from"./mcp-logging.js";import{MemoryMonitor as s}from"./memory-monitor.js";import{registerPrompts as c}from"./prompts.js";import{installReplayInterceptor as l}from"./replay-interceptor.js";import{ResourceNotifier as u}from"./resources/resource-notifier.js";import{registerResources as d}from"./resources/resources.js";import{createSamplingClient as f}from"./sampling.js";import{installStructuredContentGuard as p}from"./structured-content-guard.js";import{getToolMeta as m}from"./tool-metadata.js";import{installToolPrefix as h}from"./tool-prefix.js";import{ToolTimeoutError as g,getToolTimeout as _,withTimeout as v}from"./tool-timeout.js";import{registerAnalyzeDependenciesTool as y,registerAnalyzeDiagramTool as b,registerAnalyzeEntryPointsTool as x,registerAnalyzePatternsTool as S,registerAnalyzeStructureTool as ee,registerAnalyzeSymbolsTool as C,registerBlastRadiusTool as w}from"./tools/analyze.tools.js";import{registerAuditTool as T}from"./tools/audit.tool.js";import{registerBrainstormTool as E}from"./tools/brainstorm.tool.js";import{initBridgeComponents as te,registerErPullTool as D,registerErPushTool as O,registerErSyncStatusTool as k}from"./tools/bridge.tools.js";import{registerConfigTool as ne}from"./tools/config.tool.js";import{registerCompactTool as A,registerDeadSymbolsTool as j,registerFileSummaryTool as M,registerFindTool as N,registerScopeMapTool as re,registerSymbolTool as P,registerTraceTool as F}from"./tools/context.tools.js";import{registerErEvolveReviewTool as ie}from"./tools/evolution.tools.js";import{registerBatchTool as ae,registerCheckTool as oe,registerDelegateTool as se,registerEvalTool as ce,registerParseOutputTool as le,registerTestRunTool as I}from"./tools/execution.tools.js";import{registerFlowTools as ue}from"./tools/flow.tools.js";import{registerDigestTool as de,registerEvidenceMapTool as L,registerForgeClassifyTool as R,registerForgeGroundTool as fe,registerStratumCardTool as pe}from"./tools/forge.tools.js";import{registerForgetTool as me}from"./tools/forget.tool.js";import{registerGraphTool as he}from"./tools/graph.tool.js";import{registerGuideTool as z,registerHealthTool as B,registerProcessTool as V,registerWatchTool as H,registerWebFetchTool as U}from"./tools/infra.tools.js";import{registerListTool as ge}from"./tools/list.tool.js";import{registerLookupTool as _e}from"./tools/lookup.tool.js";import{registerCodemodTool as W,registerDataTransformTool as G,registerDiffParseTool as K,registerGitContextTool as q,registerRenameTool as ve}from"./tools/manipulation.tools.js";import{registerOnboardTool as ye}from"./tools/onboard.tool.js";import{registerCheckpointTool as be,registerLaneTool as xe,registerQueueTool as Se,registerStashTool as Ce,registerWorksetTool as we}from"./tools/persistence.tools.js";import{registerErUpdatePolicyTool as Te}from"./tools/policy.tools.js";import{registerPresentTool as Ee}from"./tools/present/tool.js";import"./tools/present/index.js";import{registerProduceKnowledgeTool as De}from"./tools/produce.tool.js";import{registerReadTool as Oe}from"./tools/read.tool.js";import{registerReindexTool as ke}from"./tools/reindex.tool.js";import{registerRememberTool as Ae}from"./tools/remember.tool.js";import{registerReplayTool as je}from"./tools/replay.tool.js";import{registerRestoreTool as Me}from"./tools/restore.tool.js";import{registerSearchTool as Ne}from"./tools/search.tool.js";import{getCurrentVersion as Pe}from"./version-check.js";import{registerEarlyStatusTool as Fe,registerStatusTool as Ie}from"./tools/status.tool.js";import{registerUpdateTool as Le}from"./tools/update.tool.js";import{registerChangelogTool as Re,registerEncodeTool as ze,registerEnvTool as Be,registerHttpTool as Ve,registerMeasureTool as He,registerRegexTestTool as Ue,registerSchemaValidateTool as We,registerSnippetTool as Ge,registerTimeTool as J,registerWebSearchTool as Ke}from"./tools/utility.tools.js";import{existsSync as qe,statSync as Je}from"node:fs";import{resolve as Ye}from"node:path";import{AIKIT_PATHS as Xe,createLogger as Ze,serializeError as Y}from"../../core/dist/index.js";import{initializeWasm as Qe}from"../../chunker/dist/index.js";import{OnnxEmbedder as $e}from"../../embeddings/dist/index.js";import{EvolutionCollector as et,PolicyStore as tt}from"../../enterprise-bridge/dist/index.js";import{FileHashCache as nt,IncrementalIndexer as rt}from"../../indexer/dist/index.js";import{SqliteGraphStore as it,createStore as at}from"../../store/dist/index.js";import{FileCache as ot}from"../../tools/dist/index.js";import{McpServer as st}from"@modelcontextprotocol/sdk/server/mcp.js";const X=Ze(`server`);async function Z(e){X.info(`Initializing AI Kit components`);let[t,r,i,a]=await Promise.all([(async()=>{let t=new $e({model:e.embedding.model,dimensions:e.embedding.dimensions});return await t.initialize(),X.info(`Embedder loaded`,{modelId:t.modelId,dimensions:t.dimensions}),t})(),(async()=>{let t=await at({backend:e.store.backend,path:e.store.path});return await t.initialize(),X.info(`Store initialized`),t})(),(async()=>{let t=new it({path:e.store.path});return await t.initialize(),X.info(`Graph store initialized`),t})(),(async()=>{let e=await Qe();return e?X.info(`WASM tree-sitter enabled for AST analysis`):X.warn(`WASM tree-sitter not available; analyzers will use regex fallback`),e})()]),o=new rt(t,r),s=new nt(e.store.path);s.load(),o.setHashCache(s);let c=e.curated.path,l=new n(c,r,t);o.setGraphStore(i);let u=te(e.er),d=u?new tt(e.curated.path):void 0;d&&X.info(`Policy store initialized`,{ruleCount:d.getRules().length});let f=u?new et:void 0,p=Ye(e.sources[0]?.path??process.cwd(),Xe.aiKb),m=qe(p),h=e.onboardDir?qe(e.onboardDir):!1,g=m||h,_,v=m?p:e.onboardDir;if(g&&v)try{_=Je(v).mtime.toISOString()}catch{}return X.info(`Onboard state detected`,{onboardComplete:g,onboardTimestamp:_,aiKbExists:m,onboardDirExists:h}),{embedder:t,store:r,indexer:o,curated:l,graphStore:i,fileCache:new ot,bridge:u,policyStore:d,evolutionCollector:f,onboardComplete:g,onboardTimestamp:_}}function ct(e,t){let n=new st({name:t.serverName??`aikit`,version:Pe()},{capabilities:{logging:{},completions:{}}});return o(n),h(n,t.toolPrefix??``),Q(n,e,t,r(n),new u(n),f(n)),c(n,{curated:e.curated,store:e.store,graphStore:e.graphStore},t.indexMode),n}function Q(e,t,n,r,i,a,o,s){l(e),p(e),Ne(e,t.embedder,t.store,t.graphStore,t.bridge,t.evolutionCollector,a),_e(e,t.store),Ie(e,t.store,t.graphStore,t.curated,{onboardComplete:t.onboardComplete,onboardTimestamp:t.onboardTimestamp},n,o,s),ne(e,n),ke(e,t.indexer,n,t.curated,t.store,i,o),Ae(e,t.curated,t.policyStore,t.evolutionCollector,i),Le(e,t.curated,i),me(e,t.curated,i),Oe(e,t.curated),ge(e,t.curated),ee(e,t.store,t.embedder),y(e,t.store,t.embedder),C(e,t.store,t.embedder),S(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),De(e,n),ye(e,t.store,t.embedder,n),he(e,t.graphStore),T(e,t.store,t.embedder);let c=n.sources[0]?.path??process.cwd();A(e,t.embedder,t.fileCache,c),re(e,t.embedder,t.store),N(e,t.embedder,t.store),le(e),we(e),oe(e),ae(e,t.embedder,t.store),P(e,t.embedder,t.store,t.graphStore),ce(e),I(e),Ce(e),q(e),K(e),ve(e),W(e),Me(e),M(e,t.fileCache,c),be(e),G(e),F(e,t.embedder,t.store,t.graphStore),V(e),H(e),j(e,t.embedder,t.store),se(e,a),B(e),xe(e),Se(e),U(e),z(e,o),L(e),de(e,t.embedder),R(e),pe(e,t.embedder,t.fileCache),fe(e,t.embedder,t.store),Ee(e,r),r&&E(e,r),Ke(e),Ve(e),Ue(e),ze(e),He(e),Re(e),We(e),Ge(e),Be(e),J(e),ue(e,n),t.bridge&&(O(e,t.bridge,t.evolutionCollector),D(e,t.bridge),k(e,t.bridge)),t.policyStore&&Te(e,t.policyStore),t.evolutionCollector&&ie(e,t.evolutionCollector),d(e,t.store,t.curated),je(e)}async function lt(e){let t=await Z(e),n=ct(t,e);X.info(`MCP server configured`,{toolCount:$.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);X.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&&X.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&X.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});X.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){X.warn(`FTS index creation failed`,Y(e))}try{let e=await t.curated.reindexAll();X.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){X.error(`Curated re-index failed`,Y(e))}}catch(e){X.error(`Initial index failed; will retry on aikit_reindex`,Y(e))}},i=async()=>{X.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{X.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}const ut=new Set(`batch.brainstorm.changelog.check.checkpoint.codemod.compact.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(`.`)),dt=5e3,ft=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 pt(e){oe(e),ce(e),I(e),le(e),se(e),q(e),K(e),ve(e),W(e),G(e),we(e),Ce(e),be(e),Me(e),xe(e),Se(e),B(e),V(e),H(e),U(e),z(e),L(e),R(e),Ee(e),E(e,i),De(e),je(e),Fe(e),Ke(e),Ve(e),Ue(e),ze(e),He(e),Re(e),We(e),Ge(e),Be(e),J(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 mt(n,i){let l=new st({name:n.serverName??`aikit`,version:Pe()},{capabilities:{logging:{},completions:{}}}),d=`initializing`,p=``,y=!1,b=null,x=null,S=null;function ee(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 C=()=>d===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,p?`Error: ${p}`:``,``,`**35 tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`regex_test, encode, stash, checkpoint, lane, process, time, env, and more.`,``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
|
|
2
2
|
`):[`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
3
|
`);o(l),h(l,n.toolPrefix??``);let w=l.sendToolListChanged.bind(l);l.sendToolListChanged=()=>{};let T=[];for(let e of $){let t=m(e),n=l.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:C()}]}));ft.has(e)?n.remove():T.push(n)}pt(l),l.sendToolListChanged=w;let E=l.registerResource(`aikit-status`,`aikit://status`,{description:`AI Kit status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`aikit://status`,text:`AI Kit is initializing...`,mimeType:`text/plain`}]})),te=l.registerPrompt(`_init`,{description:`AI Kit is initializing prompts...`},async()=>({messages:[{role:`user`,content:{type:`text`,text:C()}}]})),D,O=new Promise(e=>{D=e}),k,ne=new Promise(e=>{k=e}),A=()=>k?.(),j=(async()=>{await ne;let e;try{e=await Z(n)}catch(e){d=`failed`,p=e instanceof Error?e.message:String(e),X.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:p});return}let o=l.sendToolListChanged.bind(l);l.sendToolListChanged=()=>{};let m=l.sendPromptListChanged.bind(l);l.sendPromptListChanged=()=>{};let h=l.sendResourceListChanged.bind(l);l.sendResourceListChanged=()=>{};for(let e of T)e.remove();E.remove(),te.remove();let C=l._registeredTools??{};for(let e of ft)C[e]?.remove();let w=new u(l),O=f(l);Q(l,e,n,r(l),w,O,i,i===`smart`?(()=>{let e=S;return e?.getState?e.getState():null}):null),c(l,{curated:e.curated,store:e.store,graphStore:e.graphStore},i),l.sendToolListChanged=o,l.sendPromptListChanged=m,l.sendResourceListChanged=h,Promise.resolve(l.sendToolListChanged()).catch(()=>{}),Promise.resolve(l.sendPromptListChanged()).catch(()=>{}),Promise.resolve(l.sendResourceListChanged()).catch(()=>{});let k=l._registeredTools??{};for(let[t,n]of Object.entries(k)){if(ut.has(t))continue;let r=n.handler;n.handler=async(...n)=>{if(!e.indexer.isIndexing)return r(...n);let i=y?`re-indexing`:`running initial index`,a=new Promise(e=>setTimeout(()=>e({content:[{type:`text`,text:`⏳ AI Kit is ${i}. The tool "${t}" timed out waiting for index data (${dt/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}]}),dt));return Promise.race([r(...n),a])}}for(let[e,t]of Object.entries(k)){let n=t.handler,r=_(e);t.handler=async(...t)=>{try{return await v(()=>n(...t),r,e)}catch(t){if(t instanceof g)return{content:[{type:`text`,text:`⏳ Tool "${e}" timed out after ${r/1e3}s. This may indicate a long-running operation. Please retry or break the task into smaller steps.`}]};throw t}}}let A=Object.keys(k).length;A<$.length&&X.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:$.length,registeredToolCount:A}),X.info(`MCP server configured`,{toolCount:$.length,resourceCount:4});let j=new s;j.onPressure((e,n)=>{e===`warning`&&t(),e===`critical`&&(X.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(n/1024/1024)}),t())}),j.start();let M=new a;x=M,M.onIdle(async()=>{if(N.isRunning||e.indexer.isIndexing){X.info(`Idle cleanup deferred — background tasks still running`),M.touch();return}X.info(`Idle cleanup: closing store and graph connections`);try{await Promise.all([e.store.close().catch(()=>{}),e.graphStore.close().catch(()=>{})])}catch{}}),M.touch();for(let e of Object.values(k)){let t=e.handler;e.handler=async(...e)=>{if(M.touch(),S){let t=ee(e[0]);t.length>0&&S.prioritize(...t)}return t(...e)}}b=e,D?.(e)})(),M=async()=>{let e=await O;x?.setBusy(!0);try{let t=n.sources.map(e=>e.path).join(`, `);X.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&&X.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&X.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});y=!0,X.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await e.store.createFtsIndex()}catch(e){X.warn(`FTS index creation failed`,Y(e))}try{let t=await e.curated.reindexAll();X.info(`Curated re-index complete`,{indexed:t.indexed})}catch(e){X.error(`Curated re-index failed`,Y(e))}}catch(e){X.error(`Initial index failed; will retry on aikit_reindex`,Y(e))}finally{x?.setBusy(!1)}},N=new e,re=()=>N.schedule({name:`initial-index`,fn:M}),P=process.ppid,F=setInterval(()=>{try{process.kill(P,0)}catch{X.info(`Parent process died; shutting down`,{parentPid:P}),clearInterval(F),O.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 F.unref(),{server:l,startInit:A,ready:j,runInitialIndex:re,get kb(){return b},scheduler:N,setSmartScheduler(e){S=e}}}export{$ as ALL_TOOL_NAMES,mt as createLazyServer,ct as createMcpServer,lt as createServer,Z as initializeKnowledgeBase,Q as registerMcpTools};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0}},symbol:{title:`Symbol Resolver`,annotations:{readOnlyHint:!0,idempotentHint:!0}},trace:{title:`Data Flow Tracer`,annotations:{readOnlyHint:!0,idempotentHint:!0}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0}},lookup:{title:`Chunk Lookup`,annotations:{readOnlyHint:!0,idempotentHint:!0}},dead_symbols:{title:`Dead Symbol Finder`,annotations:{readOnlyHint:!0,idempotentHint:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_structure:{title:`Analyze Structure`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_dependencies:{title:`Analyze Dependencies`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_symbols:{title:`Analyze Symbols`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_patterns:{title:`Analyze Patterns`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_entry_points:{title:`Analyze Entry Points`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_diagram:{title:`Analyze Diagram`,annotations:{readOnlyHint:!0,idempotentHint:!0}},blast_radius:{title:`Blast Radius`,annotations:{readOnlyHint:!0,idempotentHint:!0}},brainstorm:{title:`Brainstorm Session`,annotations:{readOnlyHint:!0,idempotentHint:!0}},remember:{title:`Remember Knowledge`,annotations:{readOnlyHint:!1}},read:{title:`Read Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},update:{title:`Update Knowledge`,annotations:{readOnlyHint:!1}},forget:{title:`Forget Knowledge`,annotations:{readOnlyHint:!1,destructiveHint:!0}},list:{title:`List Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},compact:{title:`Semantic Compactor`,annotations:{readOnlyHint:!0,idempotentHint:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stratum_card:{title:`Stratum Card`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_classify:{title:`FORGE Classify`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0}},batch:{title:`Batch Operations`,annotations:{readOnlyHint:!0,idempotentHint:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0}},data_transform:{title:`Data Transform`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stash:{title:`Stash Values`,annotations:{readOnlyHint:!1}},checkpoint:{title:`Session Checkpoint`,annotations:{readOnlyHint:!1}},workset:{title:`Workset Manager`,annotations:{readOnlyHint:!1}},lane:{title:`Exploration Lane`,annotations:{readOnlyHint:!1}},git_context:{title:`Git Context`,annotations:{readOnlyHint:!0,idempotentHint:!0}},diff_parse:{title:`Diff Parser`,annotations:{readOnlyHint:!0,idempotentHint:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0}},watch:{title:`File Watcher`,annotations:{readOnlyHint:!1,openWorldHint:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0}},config:{title:`Configuration Manager`,annotations:{readOnlyHint:!1}},status:{title:`AI Kit Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},health:{title:`Health Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},reindex:{title:`Reindex`,annotations:{readOnlyHint:!1}},onboard:{title:`Onboard Codebase`,annotations:{readOnlyHint:!1}},graph:{title:`Knowledge Graph`,annotations:{readOnlyHint:!1}},guide:{title:`Tool Guide`,annotations:{readOnlyHint:!0,idempotentHint:!0}},replay:{title:`Replay History`,annotations:{readOnlyHint:!0,idempotentHint:!0}},changelog:{title:`Generate Changelog`,annotations:{readOnlyHint:!0,idempotentHint:!0}},regex_test:{title:`Regex Tester`,annotations:{readOnlyHint:!0,idempotentHint:!0}},encode:{title:`Encode / Decode`,annotations:{readOnlyHint:!0,idempotentHint:!0}},measure:{title:`Code Metrics`,annotations:{readOnlyHint:!0,idempotentHint:!0}},schema_validate:{title:`Schema Validator`,annotations:{readOnlyHint:!0,idempotentHint:!0}},snippet:{title:`Code Snippets`,annotations:{readOnlyHint:!1}},env:{title:`Environment Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},time:{title:`Date & Time`,annotations:{readOnlyHint:!0,idempotentHint:!0}},web_fetch:{title:`Web Fetch`,annotations:{readOnlyHint:!0,openWorldHint:!0}},web_search:{title:`Web Search`,annotations:{readOnlyHint:!0,openWorldHint:!0}},http:{title:`HTTP Request`,annotations:{readOnlyHint:!1,openWorldHint:!0}},queue:{title:`Operation Queue`,annotations:{readOnlyHint:!1}},bridge_push:{title:`Bridge Push`,annotations:{readOnlyHint:!1}},bridge_pull:{title:`Bridge Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0}},bridge_sync:{title:`Bridge Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evolution_state:{title:`Evolution State`,annotations:{readOnlyHint:!1}},policy_check:{title:`Policy Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_list:{title:`Flow List`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_info:{title:`Flow Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_start:{title:`Flow Start`,annotations:{readOnlyHint:!1}},flow_step:{title:`Flow Step`,annotations:{readOnlyHint:!1}},flow_status:{title:`Flow Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_reset:{title:`Flow Reset`,annotations:{readOnlyHint:!1}}};function t(t){return e[t]??{title:t,annotations:{readOnlyHint:!1}}}export{e as TOOL_METADATA,t as getToolMeta};
|
|
1
|
+
const e={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0}},symbol:{title:`Symbol Resolver`,annotations:{readOnlyHint:!0,idempotentHint:!0}},trace:{title:`Data Flow Tracer`,annotations:{readOnlyHint:!0,idempotentHint:!0}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0}},lookup:{title:`Chunk Lookup`,annotations:{readOnlyHint:!0,idempotentHint:!0}},dead_symbols:{title:`Dead Symbol Finder`,annotations:{readOnlyHint:!0,idempotentHint:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_structure:{title:`Analyze Structure`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_dependencies:{title:`Analyze Dependencies`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_symbols:{title:`Analyze Symbols`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_patterns:{title:`Analyze Patterns`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_entry_points:{title:`Analyze Entry Points`,annotations:{readOnlyHint:!0,idempotentHint:!0}},analyze_diagram:{title:`Analyze Diagram`,annotations:{readOnlyHint:!0,idempotentHint:!0}},blast_radius:{title:`Blast Radius`,annotations:{readOnlyHint:!0,idempotentHint:!0}},brainstorm:{title:`Brainstorm Session`,annotations:{readOnlyHint:!0,idempotentHint:!0}},remember:{title:`Remember Knowledge`,annotations:{readOnlyHint:!1}},read:{title:`Read Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},update:{title:`Update Knowledge`,annotations:{readOnlyHint:!1}},forget:{title:`Forget Knowledge`,annotations:{readOnlyHint:!1,destructiveHint:!0}},list:{title:`List Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0}},compact:{title:`Semantic Compactor`,annotations:{readOnlyHint:!0,idempotentHint:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stratum_card:{title:`Stratum Card`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0}},forge_classify:{title:`FORGE Classify`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0}},batch:{title:`Batch Operations`,annotations:{readOnlyHint:!0,idempotentHint:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0}},data_transform:{title:`Data Transform`,annotations:{readOnlyHint:!0,idempotentHint:!0}},stash:{title:`Stash Values`,annotations:{readOnlyHint:!1}},checkpoint:{title:`Session Checkpoint`,annotations:{readOnlyHint:!1}},workset:{title:`Workset Manager`,annotations:{readOnlyHint:!1}},lane:{title:`Exploration Lane`,annotations:{readOnlyHint:!1}},git_context:{title:`Git Context`,annotations:{readOnlyHint:!0,idempotentHint:!0}},diff_parse:{title:`Diff Parser`,annotations:{readOnlyHint:!0,idempotentHint:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0}},watch:{title:`File Watcher`,annotations:{readOnlyHint:!1,openWorldHint:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0}},config:{title:`Configuration Manager`,annotations:{readOnlyHint:!1}},status:{title:`AI Kit Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},health:{title:`Health Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},reindex:{title:`Reindex`,annotations:{readOnlyHint:!1}},onboard:{title:`Onboard Codebase`,annotations:{readOnlyHint:!1}},graph:{title:`Knowledge Graph`,annotations:{readOnlyHint:!1}},guide:{title:`Tool Guide`,annotations:{readOnlyHint:!0,idempotentHint:!0}},replay:{title:`Replay History`,annotations:{readOnlyHint:!0,idempotentHint:!0}},changelog:{title:`Generate Changelog`,annotations:{readOnlyHint:!0,idempotentHint:!0}},regex_test:{title:`Regex Tester`,annotations:{readOnlyHint:!0,idempotentHint:!0}},encode:{title:`Encode / Decode`,annotations:{readOnlyHint:!0,idempotentHint:!0}},measure:{title:`Code Metrics`,annotations:{readOnlyHint:!0,idempotentHint:!0}},schema_validate:{title:`Schema Validator`,annotations:{readOnlyHint:!0,idempotentHint:!0}},snippet:{title:`Code Snippets`,annotations:{readOnlyHint:!1}},env:{title:`Environment Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},time:{title:`Date & Time`,annotations:{readOnlyHint:!0,idempotentHint:!0}},web_fetch:{title:`Web Fetch`,annotations:{readOnlyHint:!0,openWorldHint:!0}},web_search:{title:`Web Search`,annotations:{readOnlyHint:!0,openWorldHint:!0}},http:{title:`HTTP Request`,annotations:{readOnlyHint:!1,openWorldHint:!0}},queue:{title:`Operation Queue`,annotations:{readOnlyHint:!1}},bridge_push:{title:`Bridge Push`,annotations:{readOnlyHint:!1}},bridge_pull:{title:`Bridge Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0}},bridge_sync:{title:`Bridge Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},evolution_state:{title:`Evolution State`,annotations:{readOnlyHint:!1}},policy_check:{title:`Policy Check`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_list:{title:`Flow List`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_info:{title:`Flow Info`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_start:{title:`Flow Start`,annotations:{readOnlyHint:!1}},flow_step:{title:`Flow Step`,annotations:{readOnlyHint:!1}},flow_status:{title:`Flow Status`,annotations:{readOnlyHint:!0,idempotentHint:!0}},flow_reset:{title:`Flow Reset`,annotations:{readOnlyHint:!1}},flow_read_skill:{title:`Flow Read Skill`,annotations:{readOnlyHint:!0,idempotentHint:!0}}};function t(t){return e[t]??{title:t,annotations:{readOnlyHint:!1}}}export{e as TOOL_METADATA,t as getToolMeta};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{join as t}from"node:path";import{z as
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{join as t,resolve as n}from"node:path";import{readFile as r}from"node:fs/promises";import{z as i}from"zod";import{createLogger as a,serializeError as o}from"../../../core/dist/index.js";const s=a(`flow-tools`);function c(e){return{content:[{type:`text`,text:e}]}}function l(e){return e instanceof Error?e.message:String(e)}function u(a,u){let d=t(u.stateDir??t(u.sources[0].path,`.aikit-state`),`flows`),f=t(d,`registry.json`),p=t(d,`state.json`);async function m(){let{FlowRegistryManager:e,FlowStateMachine:t}=await import(`../../../flows/dist/index.js`);return{registry:new e(f),stateMachine:new t(p)}}let h=e(`flow_list`);a.registerTool(`flow_list`,{title:h.title,description:`List all installed flows and their steps`,annotations:h.annotations,inputSchema:{}},async()=>{try{let{registry:e,stateMachine:t}=await m(),n=e.list(),r=t.getStatus(),i={flows:n.map(e=>({name:e.name,version:e.version,source:e.source,sourceType:e.sourceType,format:e.format,steps:e.manifest.steps.map(e=>e.id)})),activeFlow:r.success&&r.data?{flow:r.data.flow,status:r.data.status,currentStep:r.data.currentStep}:null};return c(JSON.stringify(i,null,2))}catch(e){return s.error(`flow_list failed`,o(e)),c(`Error: ${l(e)}`)}});let g=e(`flow_info`);a.registerTool(`flow_info`,{title:g.title,description:`Show detailed information about a specific flow`,annotations:g.annotations,inputSchema:{name:i.string().describe(`Flow name to get info for`)}},async({name:e})=>{try{let{registry:t}=await m(),r=t.get(e);if(!r)return c(`Flow "${e}" not found. Use flow_list to see available flows.`);let i={name:r.name,version:r.version,description:r.manifest.description,source:r.source,sourceType:r.sourceType,format:r.format,installPath:r.installPath,registeredAt:r.registeredAt,updatedAt:r.updatedAt,steps:r.manifest.steps.map(e=>({id:e.id,name:e.name,skill:n(r.installPath,e.skill),produces:e.produces,requires:e.requires,description:e.description})),agents:r.manifest.agents,artifactsDir:r.manifest.artifacts_dir,install:r.manifest.install};return c(JSON.stringify(i,null,2))}catch(e){return s.error(`flow_info failed`,o(e)),c(`Error: ${l(e)}`)}});let _=e(`flow_start`);a.registerTool(`flow_start`,{title:_.title,description:`Start a flow. Sets the active flow and positions at the first step.`,annotations:_.annotations,inputSchema:{flow:i.string().describe(`Flow name to start (use flow_list to see options)`)}},async({flow:e})=>{try{let{registry:t,stateMachine:n}=await m(),r=t.get(e);if(!r)return c(`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 c(`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,currentStepSkill:o?.skill??null,currentStepDescription:o?.description??null,totalSteps:r.manifest.steps.length,stepSequence:r.manifest.steps.map(e=>e.id),artifactsDir:r.manifest.artifacts_dir};return c(JSON.stringify(s,null,2))}catch(e){return s.error(`flow_start failed`,o(e)),c(`Error: ${l(e)}`)}});let v=e(`flow_step`);a.registerTool(`flow_step`,{title:v.title,description:`Advance the active flow: complete current step and move to next, skip current step, or redo current step.`,annotations:v.annotations,inputSchema:{action:i.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 m(),r=n.load();if(!r)return c(`No active flow. Use flow_start first.`);let i=t.get(r.flow);if(!i)return c(`Flow "${r.flow}" not found in registry.`);let a=n.step(e,i.manifest);if(!a.success||!a.data)return c(`Cannot ${e}: ${a.error}`);let o=a.data,s=o.currentStep?i.manifest.steps.find(e=>e.id===o.currentStep):null,l={flow:o.flow,status:o.status,action:e,currentStep:o.currentStep,currentStepSkill:s?.skill??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 c(JSON.stringify(l,null,2))}catch(e){return s.error(`flow_step failed`,o(e)),c(`Error: ${l(e)}`)}});let y=e(`flow_status`);a.registerTool(`flow_status`,{title:y.title,description:`Show the current flow execution state — which flow is active, current step, completed steps, and artifacts.`,annotations:y.annotations,inputSchema:{}},async()=>{try{let{registry:e,stateMachine:t}=await m(),r=t.getStatus();if(!r.success||!r.data)return c(`No active flow. Use flow_start to begin one, or flow_list to see available flows.`);let i=r.data,a=e.get(i.flow),o=a?.manifest.steps.find(e=>e.id===i.currentStep),s=a&&o?n(a.installPath,o.skill):null,l={flow:i.flow,status:i.status,currentStep:i.currentStep,currentStepSkill:o?.skill??null,skillPath:s,currentStepDescription:o?.description??null,completedSteps:i.completedSteps,skippedSteps:i.skippedSteps,artifacts:i.artifacts,startedAt:i.startedAt,updatedAt:i.updatedAt,totalSteps:a?.manifest.steps.length??0,progress:a?`${i.completedSteps.length+i.skippedSteps.length}/${a.manifest.steps.length}`:`unknown`};return c(JSON.stringify(l,null,2))}catch(e){return s.error(`flow_status failed`,o(e)),c(`Error: ${l(e)}`)}});let b=e(`flow_read_skill`);a.registerTool(`flow_read_skill`,{title:b.title===`flow_read_skill`?`Flow Read Skill`:b.title,description:`Read the skill or instruction content for a flow step. If step is omitted, reads the current step.`,annotations:b.title===`flow_read_skill`?{readOnlyHint:!0,idempotentHint:!0}:b.annotations,inputSchema:{step:i.string().optional().describe(`Step id or name to read. Defaults to the current step.`)}},async({step:e})=>{try{let{registry:t,stateMachine:i}=await m(),a=i.getStatus();if(!a.success||!a.data)return c(`No active flow. Use flow_start to begin one, or flow_list to see available flows.`);let o=a.data,s=t.get(o.flow);if(!s)return c(`Flow "${o.flow}" not found in registry.`);let l=e??o.currentStep;if(!l)return c(`No current step is available for the active flow.`);let u=s.manifest.steps.find(e=>e.id===l||e.name===l);return c(u?await r(n(s.installPath,u.skill),`utf-8`):`Step "${l}" not found in flow "${o.flow}".`)}catch(e){return s.error(`flow_read_skill failed`,o(e)),e instanceof Error&&`code`in e&&e.code===`ENOENT`?c(`Could not read skill file: ${e.message}`):c(`Error: ${l(e)}`)}});let x=e(`flow_reset`);a.registerTool(`flow_reset`,{title:x.title,description:`Reset the active flow, clearing all state. Use to start over or switch to a different flow.`,annotations:x.annotations,inputSchema:{}},async()=>{try{let{stateMachine:e}=await m(),t=e.reset();return t.success?c(`Flow state reset. Use flow_start to begin a new flow.`):c(`Reset failed: ${t.error}`)}catch(e){return s.error(`flow_reset failed`,o(e)),c(`Error: ${l(e)}`)}})}export{u as registerFlowTools};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../../tool-metadata.js";import{buildBrowserHtml as t}from"./browser.js";import{buildMarkdown as n}from"./markdown.js";import{readFileSync as r}from"node:fs";import{dirname as i,join as a}from"node:path";import{fileURLToPath as o}from"node:url";import{z as s}from"zod";import{RESOURCE_MIME_TYPE as c,registerAppResource as l,registerAppTool as u}from"@modelcontextprotocol/ext-apps/server";import{exec as d}from"node:child_process";import{createServer as f}from"node:http";import{createUIResource as p}from"@mcp-ui/server";const m=import.meta.dirname??i(o(import.meta.url)),h=`ui://
|
|
1
|
+
import{getToolMeta as e}from"../../tool-metadata.js";import{buildBrowserHtml as t}from"./browser.js";import{buildMarkdown as n}from"./markdown.js";import{readFileSync as r}from"node:fs";import{dirname as i,join as a}from"node:path";import{fileURLToPath as o}from"node:url";import{z as s}from"zod";import{RESOURCE_MIME_TYPE as c,registerAppResource as l,registerAppTool as u}from"@modelcontextprotocol/ext-apps/server";import{exec as d}from"node:child_process";import{createServer as f}from"node:http";import{createUIResource as p}from"@mcp-ui/server";const m=import.meta.dirname??i(o(import.meta.url)),h=`ui://aikit/present.html`,g=s.object({type:s.enum([`button`,`select`]).describe(`Action type`),id:s.string().describe(`Unique action identifier`),label:s.string().describe(`Display label`),variant:s.enum([`primary`,`danger`,`default`]).optional().describe(`Button style variant`),options:s.array(s.union([s.string(),s.object({label:s.string(),value:s.string()})])).optional().describe(`Select options (for type=select)`)}),_={format:s.enum([`html`,`browser`]).default(`html`).describe(`Output format.
|
|
2
2
|
- "html" (default): Rich markdown in chat + embedded UIResource for MCP-UI hosts. Actions shown as numbered choices.
|
|
3
3
|
- "browser": Rich markdown in chat + opens beautiful themed dashboard in the browser. When actions are provided, the browser shows interactive buttons and the tool blocks until user clicks, returning their selection.`),title:s.string().optional().describe(`Optional heading`),content:s.any().describe(`Content to present. Accepts: markdown string, array of objects (→ table), { nodes, edges } (→ mermaid graph), typed blocks [{ type, value }], or any JSON (→ tree).`),actions:s.array(g).optional().describe(`Interactive actions (buttons/selects). In html mode, shown as numbered choices. In browser mode, rendered as clickable buttons and the tool blocks until user clicks.`),template:s.enum([`auto`,`list-sort`,`data-table`,`picker`,`flame-graph`,`form`,`timeline`,`kanban`,`tree`,`diff-view`,`dashboard`]).optional().describe(`UI template for interactive display in MCP Apps hosts.
|
|
4
4
|
- auto (default): detect from content shape
|
|
@@ -15,5 +15,5 @@ import{getToolMeta as e}from"../../tool-metadata.js";import{buildBrowserHtml as
|
|
|
15
15
|
- "html" (default): Rich markdown in chat + embedded UIResource. Use for display-only content (tables, charts, reports, status boards) where no user interaction is needed.
|
|
16
16
|
- "browser": Serves a themed dashboard on a local URL. Use ONLY when you need user interaction back (confirmations, selections, form input). The tool blocks until user clicks an action button, then returns their selection.
|
|
17
17
|
FORMAT RULE: If no user interaction is needed → use "html". If you need user input back → use "browser".
|
|
18
|
-
BROWSER WORKFLOW: After calling present with format "browser", you MUST extract the URL from the response and call openBrowserPage({ url }) to open it in VS Code Simple Browser. A system browser fallback also opens automatically, but always call openBrowserPage yourself.`,annotations:r.annotations,inputSchema:_,_meta:{ui:{resourceUri:h}}},async({format:e,title:t,content:r,actions:i,template:a})=>(e??`html`)===`browser`?await w(t,r,i,n,a):T(t,r,i,a))}async function w(e,r,i,a,o){let s=n(e,r),c=t(e,r,i,o),l=p({uri:`ui://
|
|
19
|
-
`)}`}let c=p({uri:`ui://
|
|
18
|
+
BROWSER WORKFLOW: After calling present with format "browser", you MUST extract the URL from the response and call openBrowserPage({ url }) to open it in VS Code Simple Browser. A system browser fallback also opens automatically, but always call openBrowserPage yourself.`,annotations:r.annotations,inputSchema:_,_meta:{ui:{resourceUri:h}}},async({format:e,title:t,content:r,actions:i,template:a})=>(e??`html`)===`browser`?await w(t,r,i,n,a):T(t,r,i,a))}async function w(e,r,i,a,o){let s=n(e,r),c=t(e,r,i,o),l=p({uri:`ui://aikit/present-browser.html`,content:{type:`rawHtml`,htmlString:c},encoding:`text`,adapters:{mcpApps:{enabled:!0}}}),u,m,h=Array.isArray(i)?i:[],g=``,_;try{b&&=(b.close(),null),h.length>0&&(u=new Promise(e=>{m=e}));let e=!1;g=await new Promise((t,n)=>{let r=f((t,n)=>{if(e||(e=!0,_&&clearTimeout(_)),t.method===`POST`&&t.url===`/callback`){let e=``;t.on(`data`,t=>{e+=t.toString()}),t.on(`end`,()=>{n.writeHead(200,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":`*`}),n.end(`{"ok":true}`);try{let t=JSON.parse(e);m?.(t)}catch{}});return}if(t.method===`OPTIONS`){n.writeHead(204,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST`,"Access-Control-Allow-Headers":`Content-Type`}),n.end();return}n.writeHead(200,{"Content-Type":`text/html; charset=utf-8`}),n.end(c)});r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i){b=r;let n=`http://127.0.0.1:${i.port}`;_=setTimeout(()=>{if(!e)try{d(process.platform===`win32`?`start "" "${n}"`:process.platform===`darwin`?`open "${n}"`:`xdg-open "${n}"`)}catch{}},8e3),_.unref(),t(n)}else n(Error(`Failed to start present server`))}),setTimeout(()=>{r.close(),b===r&&(b=null)},300*1e3).unref()})}catch{}let v=g?`${s}\n\n---\n🌐 **Dashboard opened in browser:** ${g}\n\n**IMPORTANT:** You MUST now open this URL using the \`openBrowserPage\` tool (Simple Browser). If that tool is unavailable, open the URL in the system browser as a fallback. If neither works, ask the user to open the URL manually.`:s;if(h.length>0&&a?.available&&u)try{let e=await Promise.race([u,new Promise((e,t)=>setTimeout(()=>t(Error(`timeout`)),300*1e3))]);return{content:[{type:`text`,text:`${v}\n\n✅ **Selected:** ${e.actionId} = \`${e.value}\``},l]}}catch{return{content:[{type:`text`,text:`${v}\n\n⚠️ *No selection received (timed out).*`},l]}}return{content:[{type:`text`,text:v},l]}}function T(e,r,i,a){let o=Array.isArray(i)?i:[],s=n(e,r);if(o.length>0){let e=[``];for(let t=0;t<o.length;t++){let n=o[t],r=typeof n.label==`string`?n.label:`Action ${t+1}`;if(n.type===`select`&&Array.isArray(n.options)){let i=n.options.map(e=>typeof e==`string`?e:e.label).join(`, `);e.push(`${t+1}. **${r}** — choose: ${i}`)}else e.push(`${t+1}. **${r}**`)}s+=`\n${e.join(`
|
|
19
|
+
`)}`}let c=p({uri:`ui://aikit/present-static.html`,content:{type:`rawHtml`,htmlString:t(e,r,i,a)},encoding:`text`,adapters:{mcpApps:{enabled:!0}}});return{content:[{type:`text`,text:s},c],structuredContent:{title:e,content:r,actions:o}}}export{w as formatAsBrowser,T as formatAsHtml,S as getPresentHtml,C as registerPresentTool,x as resolvePresentHtml};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
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();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}`)}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(`
|
|
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
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};
|
|
@@ -45,9 +45,9 @@ You may be invoked in two modes:
|
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
-
## MANDATORY FIRST ACTION —
|
|
48
|
+
## MANDATORY FIRST ACTION — AI Kit Initialization
|
|
49
49
|
|
|
50
|
-
**Before ANY other work**, check the
|
|
50
|
+
**Before ANY other work**, check the AI Kit index:
|
|
51
51
|
|
|
52
52
|
1. Run \`status({})\` — check **Onboard Status** and note the **Onboard Directory** path
|
|
53
53
|
2. If onboard shows ❌:
|
|
@@ -62,6 +62,29 @@ You may be invoked in two modes:
|
|
|
62
62
|
|
|
63
63
|
---
|
|
64
64
|
|
|
65
|
+
## Session Protocol
|
|
66
|
+
|
|
67
|
+
### Start (do ALL)
|
|
68
|
+
|
|
69
|
+
\`\`\`
|
|
70
|
+
flow_status({}) # Check/resume active flow FIRST
|
|
71
|
+
# If flow active → flow_read_skill({ step }) → follow skill instructions
|
|
72
|
+
status({}) # Check AI Kit health + onboard state
|
|
73
|
+
# If onboard not run → onboard({ path: "." }) # First-time codebase analysis
|
|
74
|
+
flow_list({}) # See available flows
|
|
75
|
+
# Select flow based on task → flow_start({ flow: "<name>" }) # Start flow if appropriate
|
|
76
|
+
list() # See stored knowledge
|
|
77
|
+
search({ query: "SESSION CHECKPOINT", origin: "curated" }) # Resume prior work
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
## MCP Tool Categories
|
|
81
|
+
|
|
82
|
+
| Category | Tools | Purpose |
|
|
83
|
+
|----------|-------|---------|
|
|
84
|
+
| Flows | \`flow_list\`, \`flow_info\`, \`flow_start\`, \`flow_step\`, \`flow_status\`, \`flow_read_skill\`, \`flow_reset\` | Structured multi-step workflows |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
65
88
|
## Information Lookup Order (MANDATORY)
|
|
66
89
|
|
|
67
90
|
Always follow this order when you need to understand something. **Never skip to step 3 without checking steps 1-2 first.**
|
|
@@ -10,12 +10,59 @@ You are the **Orchestrator**, master conductor that orchestrates the full develo
|
|
|
10
10
|
|
|
11
11
|
You orchestrate the full development lifecycle: **planning → implementation → review → recovery → commit**. You own the contract — what gets done, in what order, by whom. The `multi-agents-development` skill owns the craft — how to decompose, dispatch, and review. **Load that skill before any delegation work.**
|
|
12
12
|
|
|
13
|
+
## Flow System — Primary Workflow
|
|
14
|
+
|
|
15
|
+
Flows are the **primary workflow system**. Orchestrator phases (below) are the **fallback** when no flow is active or the user explicitly skips flows.
|
|
16
|
+
|
|
17
|
+
### Flow Selection Matrix
|
|
18
|
+
|
|
19
|
+
| Task Type | Flow | Why |
|
|
20
|
+
|-----------|------|-----|
|
|
21
|
+
| Bug fix, config change, small refactor | `aikit:basic` | Known scope, low risk |
|
|
22
|
+
| New feature in existing module | `aikit:basic` | Clear boundaries |
|
|
23
|
+
| New system/service/module | `aikit:advanced` | Needs spec + planning |
|
|
24
|
+
| Cross-service changes | `aikit:advanced` | Multiple boundaries |
|
|
25
|
+
| Architectural change | `aikit:advanced` | High impact |
|
|
26
|
+
| Unclear scope or exploratory | No flow | Use Orchestrator phases |
|
|
27
|
+
|
|
28
|
+
### Flow ↔ Phase Mapping
|
|
29
|
+
|
|
30
|
+
When a flow IS active, its steps map to Orchestrator phases:
|
|
31
|
+
|
|
32
|
+
| Orchestrator Phase | `aikit:basic` step | `aikit:advanced` step |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| Phase 0: Design Gate | — | `spec` |
|
|
35
|
+
| Phase 1: Planning | `assess` | `plan` → `task` |
|
|
36
|
+
| Phase 2: Implementation | `implement` | `execute` |
|
|
37
|
+
| Phase 3: Completion | `verify` | `verify` |
|
|
38
|
+
|
|
39
|
+
### Flow MCP Tools
|
|
40
|
+
|
|
41
|
+
| Tool | Purpose |
|
|
42
|
+
|------|---------|
|
|
43
|
+
| `flow_status` | Check if a flow is active + current step |
|
|
44
|
+
| `flow_list` | List available flows |
|
|
45
|
+
| `flow_info` | Get flow details including steps and skill paths |
|
|
46
|
+
| `flow_start` | Start a named flow |
|
|
47
|
+
| `flow_step` | Advance: next, skip, or redo current step |
|
|
48
|
+
| `flow_read_skill` | Read the current step's skill content |
|
|
49
|
+
| `flow_reset` | Clear flow state to start over |
|
|
50
|
+
|
|
13
51
|
## Bootstrap (before any work)
|
|
14
52
|
|
|
53
|
+
0. `flow_status({})` — **check for active flow FIRST**
|
|
54
|
+
- If active → read step skill via `flow_read_skill({ step: "<current>" })`, follow its instructions, **skip remaining bootstrap**
|
|
55
|
+
- If not active → continue to step 1
|
|
15
56
|
1. `status({})` — if onboard ❌ → `onboard({ path: "." })`, wait for completion, note **Onboard Directory**
|
|
16
57
|
2. Read onboard artifacts: `compact({ path: "<Onboard Dir>/synthesis-guide.md" })`, `structure.md`, `code-map.md`
|
|
17
58
|
3. Read `aikit` skill, check `AGENTS.md`, read `_shared/decision-protocol.md` + `_shared/forge-protocol.md`
|
|
18
59
|
4. Read `multi-agents-development` skill — **REQUIRED before any delegation**
|
|
60
|
+
5. Select and start flow:
|
|
61
|
+
- `flow_list({})` — see available flows
|
|
62
|
+
- Choose flow using **Flow Selection Matrix** (above)
|
|
63
|
+
- `flow_start({ flow: "<chosen>" })` — start the flow
|
|
64
|
+
- `flow_read_skill({ step: "<first>" })` — load first step's skill
|
|
65
|
+
- Follow the skill instructions
|
|
19
66
|
|
|
20
67
|
## Agent Arsenal
|
|
21
68
|
|
|
@@ -45,6 +92,7 @@ You orchestrate the full development lifecycle: **planning → implementation
|
|
|
45
92
|
|
|
46
93
|
| Situation | Route |
|
|
47
94
|
|-----------|-------|
|
|
95
|
+
| Flow active | **→ Follow flow step** — skip Phase 0 entirely |
|
|
48
96
|
| New feature/component/behavior | **Brainstorming skill** → user dialogue → design doc |
|
|
49
97
|
| Non-trivial technical decision | **Decision protocol** → 4 Researchers parallel → synthesize → ADR |
|
|
50
98
|
| Both | Brainstorming first → escalate unresolved decisions to protocol |
|
|
@@ -186,33 +234,3 @@ Before every tool call, verify:
|
|
|
186
234
|
| `brainstorming` | Before creative/design work (Phase 0) |
|
|
187
235
|
| `session-handoff` | Context filling up, session ending, or major milestone |
|
|
188
236
|
| `lesson-learned` | After completing work — extract engineering principles |
|
|
189
|
-
|
|
190
|
-
## Flow-Aware Routing
|
|
191
|
-
|
|
192
|
-
At session start, check for an active flow:
|
|
193
|
-
1. Call `flow_status` to check if a flow is active
|
|
194
|
-
2. If active and status is 'active':
|
|
195
|
-
- Note the current step name and skill path
|
|
196
|
-
- Load the current step's skill file
|
|
197
|
-
- Follow its instructions for this step
|
|
198
|
-
- When step is complete, call `flow_step({ action: 'next' })`
|
|
199
|
-
3. If no active flow:
|
|
200
|
-
- Check `flow_list` for available flows
|
|
201
|
-
- Suggest starting a flow based on the task type
|
|
202
|
-
- Use `flow_start({ flow: '<name>' })` to begin
|
|
203
|
-
|
|
204
|
-
### Flow MCP Tools
|
|
205
|
-
| Tool | Purpose |
|
|
206
|
-
|------|---------|
|
|
207
|
-
| `flow_list` | List installed flows and active flow |
|
|
208
|
-
| `flow_info` | Get detailed flow info including steps |
|
|
209
|
-
| `flow_start` | Start a named flow |
|
|
210
|
-
| `flow_step` | Advance: next, skip, or redo current step |
|
|
211
|
-
| `flow_status` | Check current execution state |
|
|
212
|
-
| `flow_reset` | Clear flow state to start over |
|
|
213
|
-
|
|
214
|
-
## Flows
|
|
215
|
-
|
|
216
|
-
This project uses aikit's pluggable flow system. Check flow status with the `flow_status` MCP tool.
|
|
217
|
-
If a flow is active, follow the current step's skill instructions. Advance with `flow_step({ action: 'next' })`.
|
|
218
|
-
Use `flow_list` to see available flows and `flow_start` to begin one.
|
|
@@ -37,18 +37,25 @@ You may be invoked in two modes:
|
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
## MANDATORY FIRST ACTION —
|
|
40
|
+
## MANDATORY FIRST ACTION — AI Kit Initialization
|
|
41
41
|
|
|
42
|
-
**Before ANY other work**, check the
|
|
42
|
+
**Before ANY other work**, check the AI Kit index:
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
```text
|
|
45
|
+
flow_status({}) # Check/resume active flow FIRST
|
|
46
|
+
# If flow active → follow current step skill instructions, skip remaining init
|
|
47
|
+
status({}) # Check AI Kit health + onboard state
|
|
48
|
+
# If onboard not run → onboard({ path: "." }) # First-time codebase analysis
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If onboard shows ❌:
|
|
52
|
+
- Run `onboard({ path: "." })` — `path` is the codebase root to analyze
|
|
53
|
+
- Artifacts are written to the **Onboard Directory** automatically (the server resolves the correct location for workspace or user-level mode — you don't need to specify `out_dir`)
|
|
54
|
+
- Wait for completion (~30s) — the result shows the output directory path
|
|
55
|
+
- Do NOT proceed with any other work until onboard finishes
|
|
56
|
+
|
|
57
|
+
If onboard shows ✅:
|
|
58
|
+
- Proceed to **Information Lookup Order** below
|
|
52
59
|
|
|
53
60
|
**This is non-negotiable.** Without onboarding, you waste 10-50x tokens on blind exploration.
|
|
54
61
|
|
|
@@ -282,3 +289,11 @@ Always return this structure when invoked as a sub-agent:
|
|
|
282
289
|
</handoff>
|
|
283
290
|
```
|
|
284
291
|
|
|
292
|
+
## Flows
|
|
293
|
+
|
|
294
|
+
This project uses AI Kit's flow system for structured multi-step workflows.
|
|
295
|
+
- At session start: `flow_status({})` — check for active flows before other work
|
|
296
|
+
- If active: `flow_read_skill({ step })` — read current step skill and follow it
|
|
297
|
+
- To advance: `flow_step({ action: "next" })` — move to next step
|
|
298
|
+
- To see available flows: `flow_list({})` — then `flow_start({ flow: "<name>" })`
|
|
299
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: aikit
|
|
3
|
-
description: "Use the @vpxa/aikit
|
|
3
|
+
description: "Use the @vpxa/aikit AI Kit MCP server for codebase search, analysis, and persistent memory. Load this skill when using aikit_search, aikit_remember, aikit_analyze_*, or any aikit_* tool. Covers all 67 MCP tools: search (hybrid/semantic/keyword), code analysis (structure, dependencies, symbols, patterns, entry points, diagrams, blast radius), knowledge graph (auto-populated module/symbol/import graph with traversal), context management (worksets, stash, checkpoints, restore, lanes), code manipulation (rename, codemod, eval), knowledge management (remember/read/update/forget), web access (fetch, search, http), FORGE protocol (ground, classify, evidence map, stratum cards, digest), brainstorming (interactive ideation sessions), presentation (rich dashboards via present tool), onboarding (full codebase analysis in one call), and developer utilities (regex, encode, measure, changelog, schema-validate, snippet, env, time)."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# @vpxa/aikit —
|
|
6
|
+
# @vpxa/aikit — AI Kit
|
|
7
7
|
|
|
8
8
|
Local-first AI developer toolkit — 67 MCP tools for search, analysis, context compression, FORGE quality gates, knowledge management, code manipulation, execution, web access, brainstorming, presentation, and developer utilities.
|
|
9
9
|
|
|
@@ -40,11 +40,16 @@ core → store → embeddings → chunker → indexer → analyzers → tools
|
|
|
40
40
|
|
|
41
41
|
## Session Protocol (MANDATORY)
|
|
42
42
|
|
|
43
|
-
### Start
|
|
43
|
+
### Start (do ALL)
|
|
44
44
|
```
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
flow_status({}) # Check/resume active flow FIRST
|
|
46
|
+
# If flow active → flow_read_skill({ step }) → follow skill instructions
|
|
47
|
+
status({}) # Check AI Kit health + onboard state
|
|
48
|
+
# If onboard not run → onboard({ path: "." }) # First-time codebase analysis
|
|
49
|
+
flow_list({}) # See available flows
|
|
50
|
+
# Select flow based on task → flow_start({ flow: "<name>" }) # Start flow if appropriate
|
|
51
|
+
list() # See stored knowledge
|
|
52
|
+
search({ query: "SESSION CHECKPOINT", origin: "curated" }) # Resume prior work
|
|
48
53
|
```
|
|
49
54
|
|
|
50
55
|
### During Session
|
|
@@ -176,6 +181,17 @@ Lane actions: `create` (copy files to lane), `list`, `status` (modified/added/de
|
|
|
176
181
|
| `queue` | `aikit queue` | Task queue for sequential agent operations (create/push/next/done/fail) |
|
|
177
182
|
| `replay` | `aikit replay` | View or clear the audit trail of tool invocations (action: list/clear) |
|
|
178
183
|
|
|
184
|
+
### Flows (7)
|
|
185
|
+
| Tool | CLI | Purpose |
|
|
186
|
+
|------|-----|---------|
|
|
187
|
+
| `flow_list` | `aikit flow list` | List available flows |
|
|
188
|
+
| `flow_info` | `aikit flow info` | Get flow details including steps and skill paths |
|
|
189
|
+
| `flow_start` | `aikit flow start` | Start a named flow |
|
|
190
|
+
| `flow_step` | `aikit flow step` | Advance, skip, or redo the current step |
|
|
191
|
+
| `flow_status` | `aikit flow status` | Check if a flow is active and view the current step |
|
|
192
|
+
| `flow_read_skill` | `aikit flow read-skill` | Read the current step's skill file content directly |
|
|
193
|
+
| `flow_reset` | `aikit flow reset` | Clear flow state to start over |
|
|
194
|
+
|
|
179
195
|
### Presentation (1)
|
|
180
196
|
| Tool | CLI | Purpose |
|
|
181
197
|
|------|-----|---------|
|
|
@@ -420,102 +436,37 @@ node bin/aikit.mjs serve --http --port 3210
|
|
|
420
436
|
|
|
421
437
|
---
|
|
422
438
|
|
|
423
|
-
##
|
|
424
|
-
|
|
425
|
-
Flows are **pluggable, multi-step development workflows** that orchestrate agents through structured phases. Each flow is a directory containing a manifest (`flow.json`) and step skills (`skills/<step>/SKILL.md`).
|
|
426
|
-
|
|
427
|
-
### Architecture
|
|
428
|
-
|
|
429
|
-
```
|
|
430
|
-
Flow Layer — Pluggable workflows (git repos, local dirs, built-in)
|
|
431
|
-
Foundation Layer — Agents, MCP tools, skills (what you already have)
|
|
432
|
-
Base Layer — aikit MCP server, CLI, index engine
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
Flows compose Foundation Layer components (agents + skills + tools) into repeatable processes. They do NOT replace the foundation — they orchestrate it.
|
|
436
|
-
|
|
437
|
-
### Built-in Flows
|
|
439
|
+
## Flows
|
|
438
440
|
|
|
439
|
-
|
|
440
|
-
|------|-------|----------|
|
|
441
|
-
| `aikit:basic` | assess → implement → verify | Bug fixes, small features, refactoring |
|
|
442
|
-
| `aikit:advanced` | spec → plan → task → execute → verify | New features, API design, architecture changes |
|
|
441
|
+
Flows are structured multi-step workflows that guide agents through complex tasks. They are the **primary workflow system** — use them instead of ad-hoc planning when a matching flow exists.
|
|
443
442
|
|
|
444
|
-
### Flow
|
|
445
|
-
|
|
446
|
-
```json
|
|
447
|
-
{
|
|
448
|
-
"name": "aikit:basic",
|
|
449
|
-
"version": "0.1.0",
|
|
450
|
-
"description": "Quick development flow",
|
|
451
|
-
"steps": [
|
|
452
|
-
{
|
|
453
|
-
"id": "assess",
|
|
454
|
-
"name": "Assessment",
|
|
455
|
-
"skill": "skills/assess/SKILL.md",
|
|
456
|
-
"produces": ["assessment.md"],
|
|
457
|
-
"requires": [],
|
|
458
|
-
"agents": ["Explorer", "Researcher-Alpha"],
|
|
459
|
-
"description": "Understand scope, analyze codebase"
|
|
460
|
-
}
|
|
461
|
-
],
|
|
462
|
-
"artifacts_dir": ".spec",
|
|
463
|
-
"install": []
|
|
464
|
-
}
|
|
465
|
-
```
|
|
443
|
+
### Flow Tools
|
|
466
444
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
445
|
+
| Tool | Purpose |
|
|
446
|
+
|------|---------|
|
|
447
|
+
| `flow_status` | Check if a flow is active + current step |
|
|
448
|
+
| `flow_list` | List available flows |
|
|
449
|
+
| `flow_info` | Get flow details including steps and skill paths |
|
|
450
|
+
| `flow_start` | Start a named flow |
|
|
451
|
+
| `flow_step` | Advance: `next`, `skip`, or `redo` current step |
|
|
452
|
+
| `flow_read_skill` | Read the current step's skill file content directly |
|
|
453
|
+
| `flow_reset` | Clear flow state to start over |
|
|
471
454
|
|
|
472
|
-
###
|
|
455
|
+
### Flow Selection
|
|
473
456
|
|
|
474
|
-
|
|
|
475
|
-
|
|
476
|
-
|
|
|
477
|
-
|
|
|
478
|
-
|
|
|
479
|
-
|
|
|
480
|
-
|
|
|
481
|
-
|
|
|
482
|
-
| `aikit flow reset` | Reset flow state to beginning |
|
|
457
|
+
| Task Type | Flow | Why |
|
|
458
|
+
|-----------|------|-----|
|
|
459
|
+
| Bug fix, config change, small refactor | `aikit:basic` | Known scope, low risk |
|
|
460
|
+
| New feature in existing module | `aikit:basic` | Clear boundaries |
|
|
461
|
+
| New system/service/module | `aikit:advanced` | Needs spec + planning |
|
|
462
|
+
| Cross-service changes | `aikit:advanced` | Multiple boundaries |
|
|
463
|
+
| Architectural change | `aikit:advanced` | High impact |
|
|
464
|
+
| Unclear scope or exploratory | No flow | Use agent's native workflow |
|
|
483
465
|
|
|
484
|
-
###
|
|
485
|
-
|
|
486
|
-
Flow progress is tracked in `.spec/flow-state.json`:
|
|
487
|
-
|
|
488
|
-
```json
|
|
489
|
-
{
|
|
490
|
-
"flow": "aikit:basic",
|
|
491
|
-
"current_step": "implement",
|
|
492
|
-
"steps": {
|
|
493
|
-
"assess": { "status": "completed", "artifacts": ["assessment.md"] },
|
|
494
|
-
"implement": { "status": "in_progress", "artifacts": [] },
|
|
495
|
-
"verify": { "status": "pending", "artifacts": [] }
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
Step transitions: `pending` → `in_progress` → `completed` (or `failed` → retry). A step can only start when all its `requires` artifacts exist.
|
|
501
|
-
|
|
502
|
-
### Flow Sources
|
|
503
|
-
|
|
504
|
-
Flows can be installed from three sources:
|
|
505
|
-
|
|
506
|
-
1. **Built-in** — Ship with aikit (`aikit:basic`, `aikit:advanced`)
|
|
507
|
-
2. **Git** — `aikit flow add https://github.com/org/my-flow.git`
|
|
508
|
-
3. **Local** — `aikit flow add ./my-custom-flow`
|
|
509
|
-
|
|
510
|
-
### Creating Custom Flows
|
|
511
|
-
|
|
512
|
-
```
|
|
513
|
-
my-flow/
|
|
514
|
-
flow.json # Manifest with steps, agents, dependencies
|
|
515
|
-
skills/
|
|
516
|
-
step-one/SKILL.md
|
|
517
|
-
step-two/SKILL.md
|
|
518
|
-
README.md # Optional documentation
|
|
519
|
-
```
|
|
466
|
+
### Flow Lifecycle
|
|
520
467
|
|
|
521
|
-
|
|
468
|
+
1. **Start**: `flow_list({})` → choose flow → `flow_start({ flow: "<name>" })`
|
|
469
|
+
2. **Each step**: `flow_read_skill({ step: "<name>" })` → follow skill instructions → complete work
|
|
470
|
+
3. **Advance**: `flow_step({ action: "next" })` → repeat from step 2
|
|
471
|
+
4. **Resume**: `flow_status({})` → if active, `flow_read_skill` for current step → continue
|
|
472
|
+
5. **Reset**: `flow_reset({})` if you need to start over
|