@vpxa/aikit 0.1.380 → 0.1.382
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/claude-desktop/dist/manifest.json +1 -1
- package/packages/cli/dist/index.js +3 -3
- package/packages/cli/dist/{init-BTsNYC02.js → init-DMj2ctyd.js} +1 -1
- package/packages/cli/dist/{templates-CRs_gkfS.js → templates-DLra78_O.js} +30 -30
- package/packages/server/dist/bin.js +2 -2
- package/packages/server/dist/{config-DZskEKrY.js → config-CQKoGfwD.js} +1 -1
- package/packages/server/dist/{config-Bz8Uyzuq.js → config-DX1KYSbN.js} +1 -1
- package/packages/server/dist/{curated-manager-CBKTmAjM.js → curated-manager-D4MOFQ-t.js} +1 -1
- package/packages/server/dist/{dashboard-static-NghHzTNh.js → dashboard-static-C6RP0VA7.js} +1 -1
- package/packages/server/dist/{dashboard-static-gAOiHHqI.js → dashboard-static-DdsIJd-u.js} +1 -1
- package/packages/server/dist/index.d.ts +1 -1
- package/packages/server/dist/index.js +2 -2
- package/packages/server/dist/{observations-CfglxBMB.js → observations-BhMmh4uj.js} +1 -1
- package/packages/server/dist/{observations-CrQU_HVm.js → observations-Cri43dvk.js} +1 -1
- package/packages/server/dist/register-tools-C49Lkpvq.js +3044 -0
- package/packages/server/dist/register-tools-i_1kjBhi.js +3043 -0
- package/packages/server/dist/{server-C43D7SrT.js → server-CTUxU4KX.js} +11 -11
- package/packages/server/dist/{server-BmVdf84Q.js → server-Dm2u4PSm.js} +11 -11
- package/packages/server/dist/{server-http-YQ9jxThI.js → server-http-D8Wemu8Y.js} +1 -1
- package/packages/server/dist/{server-http-BCpGwi0k.js → server-http-DcgFpWra.js} +1 -1
- package/packages/server/dist/{server-stdio-3hhuJU8B.js → server-stdio-Bpoo8KOT.js} +1 -1
- package/packages/server/dist/{server-stdio-CuLAgQjc.js → server-stdio-CskpvBew.js} +1 -1
- package/packages/server/dist/{settings-static-DcTUiqr7.js → settings-static-C0oT3Ctk.js} +1 -1
- package/packages/server/dist/{settings-static-PjpMR9Q7.js → settings-static-DVMG47Oh.js} +1 -1
- package/packages/server/dist/startup-maintenance-cbRSFMY5.js +21 -0
- package/packages/server/dist/startup-maintenance-kHH8tjds.js +20 -0
- package/packages/tools/dist/index.d.ts +23 -3
- package/packages/tools/dist/index.js +111 -105
- package/scaffold/dist/adapters/_shared.mjs +1 -1
- package/scaffold/dist/adapters/hermes.mjs +1 -1
- package/scaffold/dist/definitions/agents.mjs +1 -1
- package/scaffold/dist/definitions/bodies.mjs +21 -16
- package/scaffold/dist/definitions/exec-hooks.mjs +1 -1
- package/scaffold/dist/definitions/flows.mjs +5 -5
- package/scaffold/dist/definitions/hooks.mjs +1 -1
- package/scaffold/dist/definitions/protocols.mjs +26 -26
- package/scaffold/dist/definitions/skills/aikit.mjs +2 -152
- package/scaffold/dist/definitions/skills/browser-use.mjs +1 -1
- package/scaffold/dist/definitions/skills/c4-architecture.mjs +5 -5
- package/scaffold/dist/definitions/skills/docs.mjs +12 -10
- package/scaffold/dist/definitions/skills/multi-agents-development.mjs +4 -4
- package/scaffold/dist/definitions/skills/orchestrator.mjs +50 -8
- package/packages/server/dist/register-tools-Dgu64Px5.js +0 -3034
- package/packages/server/dist/register-tools-jgdif5r4.js +0 -3035
- package/packages/server/dist/startup-maintenance-B4xWqEjc.js +0 -20
- package/packages/server/dist/startup-maintenance-BnTozHs1.js +0 -21
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
2
|
+
import{c as e,f as t,p as n,s as r}from"./startup-maintenance-cbRSFMY5.js";import{n as i,t as a}from"./bin.js";import{reconfigureForWorkspace as o}from"./config-DX1KYSbN.js";import{S as s,_ as c,b as l,c as u,d,f,g as p,h as m,i as h,l as g,m as _,n as ee,o as v,p as te,r as y,s as b,t as x,u as S,v as C,x as w,y as ne}from"./register-tools-C49Lkpvq.js";import{fileURLToPath as T}from"node:url";import{AIKIT_PATHS as re,DISPLAY_SERVER_NAME as E,EMBEDDING_DEFAULTS as D,MODEL_REGISTRY as O,addLogListener as k,computePartitionKey as A,createLogger as j,safeCwdOrHome as M,serializeError as N}from"../../core/dist/index.js";import{existsSync as P,mkdirSync as F,statSync as ie}from"node:fs";import{join as I,resolve as ae}from"node:path";import{FileCache as oe,checkpointList as L,checkpointSave as se,listWorksets as R,stashList as ce}from"../../tools/dist/index.js";import{homedir as z}from"node:os";import{McpServer as le}from"@modelcontextprotocol/sdk/server/mcp.js";import{WasmDiagnostics as B,initializeWasm as ue}from"../../chunker/dist/index.js";import{z as V}from"zod";import{EvolutionCollector as de,PolicyStore as fe}from"../../enterprise-bridge/dist/index.js";import{SqliteGraphStore as pe,allMigrations as me,createSqliteAdapter as H,createStateStore as he,createStore as ge,runMigrations as _e}from"../../store/dist/index.js";import{RootsListChangedNotificationSchema as ve}from"@modelcontextprotocol/sdk/types.js";import{buildFormSchema as U,field as W,normalizeResponse as ye}from"../../elicitation/dist/index.js";import{completable as G}from"@modelcontextprotocol/sdk/server/completable.js";import{EmbedderProxy as be}from"../../embeddings/dist/index.js";import{FileHashCache as xe,IncrementalIndexer as Se}from"../../indexer/dist/index.js";import{AsyncLocalStorage as Ce}from"node:async_hooks";function we(e){function t(){return!!e.server?.getClientCapabilities?.()?.elicitation}async function n(n,r){if(t())try{let t=await e.server.elicitInput({message:n,requestedSchema:r});return ye(t?{action:t.action,content:t.content}:void 0)}catch{return}}return{get available(){return t()},async ask(e){return await n(e.message,e.schema)||{action:`decline`}},async confirm(e){let t=await n(e,U({confirmed:W.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,U({selection:W.select(`Choose one`,t)}));if(r?.action!==`accept`)return null;let i=r.content?.selection;return typeof i==`string`?i:null},async selectMany(e,t){let r=await n(e,U({selections:W.multi(`Choose one or more`,t)}));if(r?.action!==`accept`)return[];let i=r.content?.selections;return Array.isArray(i)?i:[]},async promptText(e,t){let r=await n(e,U({text:W.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Te={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function Ee(e){return k(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Te[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const K=3e4,q=new Map;function De(e,t,n){let r=q.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(q.set(e,{data:n,expires:Date.now()+t}),n))}function Oe(){q.clear()}function ke(e,t){return De(`curated-paths`,K,async()=>e.listPaths({limit:5e3})).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Ae(e,t){return De(`file-paths`,K,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function je(e,t){return De(`symbol-names`,K,async()=>(await e.findNodes({type:`symbol`,limit:500})).map(e=>e.name)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Me(e,t){return t?ce(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Ne(e){return R().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function Pe(e,t){return t?L(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Fe(e,t,n){if(e.registerPrompt(`ready`,{title:`AI Kit Ready`,description:`AI Kit is ready — quick-start guide for search, onboard, and workflows`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`AI Kit is ready. Quick start:`,``,'• **New project?** → `onboard({ path: "." })` for full codebase analysis','• **Returning?** → `status({})` then `search({ query: "SESSION CHECKPOINT", origin: "curated" })`','• **Exploring?** → `guide({ goal: "your task" })` for workflow recommendations','• **Quick lookup?** → `search({ query: "your question" })`'].join(`
|
|
3
3
|
`)}}]})),e.registerPrompt(`onboard`,{title:`Onboard Codebase`,description:`Analyze the codebase for first-time onboarding — runs all analyzers and produces a knowledge summary`,argsSchema:{path:V.string().optional().describe(`Path to analyze (default: workspace root)`)}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the full onboarding workflow for "${e??`.`}"`,``,`1. \`onboard({ path: "${e??`.`}" })\` — full codebase analysis`,`2. \`produce_knowledge({ path: "${e??`.`}" })\` — generate synthesis`,'3. `knowledge({ action: "remember", ... })` for key curated entries',"4. `status` to verify index health"].join(`
|
|
4
4
|
`)}}]})),e.registerPrompt(`sessionStart`,{title:`Start AI Kit Session`,description:`Initialize an AI Kit session — check status, list knowledge, and resume from last checkpoint`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session start protocol:`,``,"1. `status({})` — check AI Kit health and onboard state",'2. `knowledge({ action: "list" })` — see stored knowledge entries','3. `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — resume prior work'].join(`
|
|
5
5
|
`)}}]})),e.registerPrompt(`sessionEnd`,{title:`End AI Kit Session`,description:`Persist decisions and create a session checkpoint before ending`,argsSchema:{summary:V.string().describe(`Brief summary of decisions made, blockers encountered, and next steps`)}},async({summary:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session end protocol:`,``,'1. `knowledge({ action: "remember", title: "Session checkpoint: '+e.slice(0,60)+`...", content: "`+e.replace(/"/g,`\\"`)+'", category: "session" })` — persist findings',n===`smart`?`2. Smart indexing is active — index refreshes automatically`:"2. `reindex({})` — refresh search index if files changed",`3. Confirm session data saved`].join(`
|
|
6
|
-
`)}}]})),e.registerPrompt(`search`,{title:`Search AI Kit`,description:`Search AI Kit with hybrid semantic + keyword search`,argsSchema:{query:V.string().describe(`Search query`)}},async({query:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Search AI Kit for: "${e}"\n\nUse \`search({ query: "${e.replace(/"/g,`\\"`)}" })\` to find relevant code, documentation, and curated knowledge.`}}]})),e.registerPrompt(`remember`,{title:`Remember Knowledge`,description:`Store a decision, convention, or finding as curated knowledge`,argsSchema:{title:V.string().describe(`Title of the knowledge entry`),content:V.string().describe(`Content to remember`),category:V.enum([`conventions`,`decisions`,`patterns`,`blockers`,`tasks`]).optional().describe(`Category (default: conventions)`)}},async({title:e,content:t,category:n})=>({messages:[{role:`user`,content:{type:`text`,text:`Store this knowledge:\n\n\`knowledge({ action: "remember", title: "${e.replace(/"/g,`\\"`)}", content: "${t.replace(/"/g,`\\"`).slice(0,200)}...", category: "${n??`conventions`}" })\``}}]})),e.registerPrompt(`planTask`,{title:`Plan a Task`,description:`Generate a reading plan and scope map for a development task`,argsSchema:{task:V.string().describe(`Description of the task to plan`)}},async({task:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Plan implementation for: "${e}"`,``,'1. `search({ query: "'+e.replace(/"/g,`\\"`)+'" })` — find related code and prior decisions','2. `scope_map({ task: "'+e.replace(/"/g,`\\"`)+'" })` — generate a reading plan',
|
|
7
|
-
`)}}]})),e.registerPrompt(`investigate`,{title:`Investigate Bug`,description:`Bug investigation workflow — parse error, find symbols, trace data flow, assess impact`,argsSchema:{error:V.string().describe(`Error message, stack trace, or bug description`)}},async({error:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Investigate this error:`,"```",e,"```",``,`Follow the bug investigation workflow:`,"1. `parse_output({ text: <error> })` — extract structured data from the error","2. `symbol({ name: <relevant symbol> })` — find definition and references",'3. `trace({ symbol: <symbol>, direction: "backward" })` — trace data flow to find root cause',"4. `blast_radius({
|
|
6
|
+
`)}}]})),e.registerPrompt(`search`,{title:`Search AI Kit`,description:`Search AI Kit with hybrid semantic + keyword search`,argsSchema:{query:V.string().describe(`Search query`)}},async({query:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Search AI Kit for: "${e}"\n\nUse \`search({ query: "${e.replace(/"/g,`\\"`)}" })\` to find relevant code, documentation, and curated knowledge.`}}]})),e.registerPrompt(`remember`,{title:`Remember Knowledge`,description:`Store a decision, convention, or finding as curated knowledge`,argsSchema:{title:V.string().describe(`Title of the knowledge entry`),content:V.string().describe(`Content to remember`),category:V.enum([`conventions`,`decisions`,`patterns`,`blockers`,`tasks`]).optional().describe(`Category (default: conventions)`)}},async({title:e,content:t,category:n})=>({messages:[{role:`user`,content:{type:`text`,text:`Store this knowledge:\n\n\`knowledge({ action: "remember", title: "${e.replace(/"/g,`\\"`)}", content: "${t.replace(/"/g,`\\"`).slice(0,200)}...", category: "${n??`conventions`}" })\``}}]})),e.registerPrompt(`planTask`,{title:`Plan a Task`,description:`Generate a reading plan and scope map for a development task`,argsSchema:{task:V.string().describe(`Description of the task to plan`)}},async({task:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Plan implementation for: "${e}"`,``,'1. `search({ query: "'+e.replace(/"/g,`\\"`)+'" })` — find related code and prior decisions','2. `scope_map({ task: "'+e.replace(/"/g,`\\"`)+'" })` — generate a reading plan','3. For each recommended file, use `file_summary` with `tier: "T2"` and `query` for detail',"4. `blast_radius` on planned changes to assess impact"].join(`
|
|
7
|
+
`)}}]})),e.registerPrompt(`investigate`,{title:`Investigate Bug`,description:`Bug investigation workflow — parse error, find symbols, trace data flow, assess impact`,argsSchema:{error:V.string().describe(`Error message, stack trace, or bug description`)}},async({error:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Investigate this error:`,"```",e,"```",``,`Follow the bug investigation workflow:`,"1. `parse_output({ text: <error> })` — extract structured data from the error","2. `symbol({ name: <relevant symbol> })` — find definition and references",'3. `trace({ symbol: <symbol>, direction: "backward" })` — trace data flow to find root cause',"4. `blast_radius({ files: [<affected files>] })` — assess fix impact"].join(`
|
|
8
8
|
`)}}]})),!t)return;let{curated:r,store:i,graphStore:a}=t;e.registerPrompt(`read_knowledge`,{title:`Read Knowledge`,description:`Read a curated knowledge entry by path — with autocomplete`,argsSchema:{path:G(V.string().describe(`Path of the curated entry (e.g. conventions/naming.md)`),async e=>ke(r,e))}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Read the curated knowledge entry: \`knowledge({ action: "read", path: "${e}" })\``}}]})),e.registerPrompt(`update_knowledge`,{title:`Update Knowledge`,description:`Update an existing curated knowledge entry — with autocomplete`,argsSchema:{path:G(V.string().describe(`Path of the curated entry to update`),async e=>ke(r,e)),content:V.string().describe(`New content for the entry`)}},async({path:e,content:t})=>({messages:[{role:`user`,content:{type:`text`,text:`Update the curated entry at "${e}":\n\n\`knowledge({ action: "update", path: "${e}", content: "${t.replace(/"/g,`\\"`).slice(0,200)}..." })\``}}]})),e.registerPrompt(`forget_knowledge`,{title:`Forget Knowledge`,description:`Delete a curated knowledge entry — with autocomplete`,argsSchema:{path:G(V.string().describe(`Path of the curated entry to delete`),async e=>ke(r,e))}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Delete the curated entry: \`knowledge({ action: "forget", path: "${e}" })\``}}]})),e.registerPrompt(`lookup_file`,{title:`Lookup File`,description:`Look up an indexed file — with autocomplete`,argsSchema:{path:G(V.string().describe(`Source file path`),async e=>Ae(i,e))}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Look up the indexed file: \`file_summary({ path: "${e}" })\``}}]})),e.registerPrompt(`find_symbol`,{title:`Find Symbol`,description:`Find a symbol definition and references — with autocomplete`,argsSchema:{name:G(V.string().describe(`Symbol name`),async e=>je(a,e))}},async({name:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Find symbol: \`symbol({ name: "${e}" })\``}}]})),e.registerPrompt(`get_stash`,{title:`Get Stash`,description:`Retrieve a stashed value by key — with autocomplete`,argsSchema:{key:G(V.string().describe(`Stash key`),e=>Me(e,t?.stateStore))}},async({key:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Get stashed value: \`stash({ action: "get", key: "${e}" })\``}}]})),e.registerPrompt(`get_workset`,{title:`Get Workset`,description:`Load a saved workset by name — with autocomplete`,argsSchema:{name:G(V.string().describe(`Workset name`),e=>Ne(e))}},async({name:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Load workset: \`workset({ action: "load", name: "${e}" })\``}}]})),e.registerPrompt(`load_checkpoint`,{title:`Load Checkpoint`,description:`Restore a saved checkpoint by name — with autocomplete`,argsSchema:{name:G(V.string().describe(`Checkpoint name`),e=>Pe(e,t?.stateStore))}},async({name:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Load checkpoint: \`checkpoint({ action: "load", name: "${e}" })\``}}]})),e.registerPrompt(`audit_workflow`,{title:`Audit Workflow`,description:`Run a full project quality audit: check → test_run → audit → produce recommendations`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Audit Workflow`,``,`Execute the following tools in sequence:`,``,"1. `check({})` — Run typecheck + lint","2. `test_run({})` — Run all tests","3. `audit({})` — Full project audit","4. Review findings and `remember` important patterns",``,`Report: pass/fail status, error counts, audit recommendations, and suggested next steps.`].join(`
|
|
9
|
-
`)}}]})),e.registerPrompt(`refactor_workflow`,{title:`Refactor Workflow`,description:`Safe refactoring workflow: analyze → blast_radius → implement → verify`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Refactor Workflow`,``,`For the target files/symbols:`,``,'1. `analyze({ aspect: "structure", path })` — Understand current structure','2. `analyze({ aspect: "dependencies", path })` — Map dependency graph',"3. `blast_radius({
|
|
9
|
+
`)}}]})),e.registerPrompt(`refactor_workflow`,{title:`Refactor Workflow`,description:`Safe refactoring workflow: analyze → blast_radius → implement → verify`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Refactor Workflow`,``,`For the target files/symbols:`,``,'1. `analyze({ aspect: "structure", path })` — Understand current structure','2. `analyze({ aspect: "dependencies", path })` — Map dependency graph',"3. `blast_radius({ files })` — Assess impact scope",`4. Implement changes carefully`,"5. `check({})` + `test_run({})` — Verify nothing broke",n===`smart`?`6. Smart indexing is active — changes will be indexed automatically`:"6. `reindex({})` — Update AI Kit with changes",``,`What would you like to refactor?`].join(`
|
|
10
10
|
`)}}]})),e.registerPrompt(`forge_workflow`,{title:`FORGE Workflow`,description:`Full FORGE protocol: classify → ground → implement with quality gates`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## FORGE Quality Gate Workflow`,``,"1. `forge_classify({ task })` — Determine complexity tier (floor/standard/critical)","2. `forge_ground({ task, files, root_path })` — Full grounding analysis",`3. Review typed unknowns and constraints`,`4. Implement with evidence tracking`,'5. `evidence_map({ action: "validate" })` — Verify all claims',"6. `check({})` + `test_run({})` — Final verification",``,`Describe the task to classify:`].join(`
|
|
11
|
-
`)}}]})),e.registerPrompt(`investigate_workflow`,{title:`Investigate Issue`,description:`Bug investigation workflow: trace → analyze → find root cause → fix`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Bug Investigation Workflow`,``,"1. `parse_output({ output })` — Parse error messages if available","2. `symbol({ name })` — Find the failing symbol",'3. `trace({ symbol, direction: "backward" })` — Trace data flow to root cause',"4. `blast_radius({
|
|
12
|
-
`)}}]})),e.registerPrompt(`context_workflow`,{title:`Build Context`,description:`Progressive context building: file_summary →
|
|
11
|
+
`)}}]})),e.registerPrompt(`investigate_workflow`,{title:`Investigate Issue`,description:`Bug investigation workflow: trace → analyze → find root cause → fix`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Bug Investigation Workflow`,``,"1. `parse_output({ output })` — Parse error messages if available","2. `symbol({ name })` — Find the failing symbol",'3. `trace({ symbol, direction: "backward" })` — Trace data flow to root cause',"4. `blast_radius({ files })` — Assess impact of fix",`5. Implement fix`,"6. `check({})` + `test_run({})` — Verify fix works",``,`Describe the issue:`].join(`
|
|
12
|
+
`)}}]})),e.registerPrompt(`context_workflow`,{title:`Build Context`,description:`Progressive context building: file_summary(T1) → file_summary(T2+query) → digest for deep understanding`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Context Building Workflow`,``,`Build understanding progressively:`,``,"1. `file_summary({ path })` — Structure overview (~50 tokens)",'2. `file_summary({ files, tier: "T2", query })` or `file_summary({ ref })` — Extract relevant sections (5-20x reduction)',"3. `digest({ sources })` — Multi-file compressed summary","4. `stratum_card({ files })` — Reusable reference card",``,`For project-wide context:`,"- `scope_map({ task })` — Reading plan for a specific task",'- `workset({ action: "save" })` — Save working set for later',``,`What do you need to understand?`].join(`
|
|
13
13
|
`)}}]})),e.registerPrompt(`migrate_workflow`,{title:`Migration Workflow`,description:`Code migration workflow: analyze → plan → migrate → verify → document`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Migration Workflow`,``,'1. `analyze({ aspect: "structure", path })` — Current codebase state','2. `analyze({ aspect: "patterns", path })` — Identify patterns to migrate',"3. `dead_symbols({ path })` — Find unused code to remove",'4. `scope_map({ task: "migration" })` — Plan migration scope',"5. Use `codemod` for bulk transformations","6. `check({})` + `test_run({})` — Verify after each step","7. `changelog({ from })` — Document changes",``,`What are you migrating from/to?`].join(`
|
|
14
14
|
`)}}]}))}const Ie=j(`resource-notifier`);var Le=class{mcpServer;constructor(e){this.mcpServer=e}async notifyStatusChanged(){await this.sendUpdate(`aikit://status`)}async notifyFileTreeChanged(){await this.sendUpdate(`aikit://file-tree`)}async notifyCuratedIndexChanged(){await this.sendUpdate(`aikit://curated`)}async notifyCuratedEntryChanged(e){await this.sendUpdate(`aikit://curated/${e}`)}async notifyResourceListChanged(){try{await this.mcpServer.server.sendResourceListChanged()}catch(e){Ie.debug(`sendResourceListChanged failed`,{error:String(e)})}}async notifyL0CardChanged(){await this.sendUpdate(`aikit://l0/workspace-core`),await this.sendUpdate(`aikit://l0`)}async notifyAfterReindex(){await Promise.allSettled([this.notifyStatusChanged(),this.notifyFileTreeChanged()])}async notifyAfterCuratedWrite(e){let t=[this.notifyStatusChanged(),this.notifyCuratedIndexChanged()];e&&t.push(this.notifyCuratedEntryChanged(e)),await Promise.allSettled(t)}async sendUpdate(e){try{await this.mcpServer.server.sendResourceUpdated({uri:e})}catch(t){Ie.debug(`sendResourceUpdated failed`,{uri:e,error:String(t)})}}};const J=j(`server`);function Re(e){let t=e?.trim().toLowerCase();return t===`1`||t===`true`||t===`yes`||t===`on`}async function Y(e){J.info(`Initializing AI Kit components`);let t=e.store.backend,n=e.embedding,r=O[n.model],o={model:n.model,nativeDim:n.nativeDim??r?.nativeDim??D.nativeDim,dimensions:n.dimensions??r?.dimensions??D.dimensions,queryPrefix:n.queryPrefix??r?.queryPrefix??D.queryPrefix,pooling:n.pooling??r?.pooling??`mean`},s=e.store.path,l=Re(process.env.AIKIT_SPLIT_STATE),d=I(s,`aikit.db`),f={splitEnabled:l,contentDbPath:d,controlDbPath:l?I(s,`aikit-control.db`):d},p=null;if(t===`sqlite-vec`){let e=f.contentDbPath;P(s)||F(s,{recursive:!0}),p=await H(e),J.debug(`SQLite adapter ready`,{type:p.type,vectorCapable:p.vectorCapable,dbPath:e}),p.vectorCapable||J.warn(`┌──────────────────────────────────────────────────────────────────┐
|
|
15
15
|
│ ⚠ SQLite vector extension unavailable — DEGRADED MODE │
|
|
16
16
|
│ Vector search is disabled. Hybrid search returns FTS only. │
|
|
17
17
|
│ To enable: install/rebuild better-sqlite3 (native module). │
|
|
18
18
|
└──────────────────────────────────────────────────────────────────┘`);let t=I(s,`lance`);P(t)&&J.info(`Old LanceDB data found at ${t} — ignored. Safe to delete after verifying sqlite-vec works.`)}let m;if(p)if(f.splitEnabled&&f.controlDbPath!==f.contentDbPath){let{migrateToSplitState:e}=await import(`../../store/dist/index.js`);await e(f),m=await H(f.controlDbPath),_e(m,me),J.info(`State store adapter ready`,{type:m.type,dbPath:f.controlDbPath,splitEnabled:!0})}else m=p;else{let e=I(s,`aikit-state.db`);P(s)||F(s,{recursive:!0}),m=await H(e),_e(m,me),J.info(`State store adapter ready`,{type:m.type,dbPath:e})}let[h,g,_,ee]=await Promise.all([(async()=>{try{if(e.embedding.childProcess!==!1){let e=new be({model:o.model,dimensions:o.dimensions,nativeDim:o.nativeDim,queryPrefix:o.queryPrefix,pooling:o.pooling,interOpNumThreads:n.interOpNumThreads,intraOpNumThreads:n.intraOpNumThreads,idleTimeoutMs:n.idleTimeoutMs});return await e.initialize(),J.debug(`Embedder loaded (child process)`,{modelId:e.modelId,dimensions:e.dimensions}),e}let{OnnxEmbedder:t}=await import(`../../embeddings/dist/index.js`),r=new t({model:o.model,dimensions:o.dimensions,nativeDim:o.nativeDim,queryPrefix:o.queryPrefix,pooling:o.pooling,interOpNumThreads:n.interOpNumThreads,intraOpNumThreads:n.intraOpNumThreads});return await r.initialize(),J.debug(`Embedder loaded (in-process)`,{modelId:r.modelId,dimensions:r.dimensions}),r}catch(e){return J.warn(`Embedder initialization failed — vector search degraded to FTS-only`,{error:N(e)}),{dimensions:0,modelId:`unavailable`,initialize:async()=>{},embed:async()=>{throw Error(`Embedder unavailable`)},embedQuery:async()=>{throw Error(`Embedder unavailable`)},embedBatch:async()=>{throw Error(`Embedder unavailable`)}}}})(),(async()=>{let e=t===`sqlite-vec`?await ge({backend:t,path:s,adapter:p??void 0,embeddingDim:o.dimensions,embeddingProfile:o,partition:f}):await ge({backend:t,path:s,adapter:p??void 0,embeddingDim:o.dimensions,partition:void 0});return await e.initialize(),J.debug(`Store initialized`,{backend:t}),e})(),(async()=>{let e=p?new pe({adapter:p}):new pe({path:s});return await e.initialize(),J.debug(`Graph store initialized`,{shared:!!p}),e})(),(async()=>{let e=await ue();if(e){let e=B.get();J.debug(`WASM tree-sitter enabled`,{grammars:e.grammarCount,dir:e.wasmDir})}else{let e=B.get();J.warn(`WASM tree-sitter not available; analyzers will use regex fallback`,{reason:e.reason,os:e.os,arch:e.arch,healAttempted:e.healAttempted,healSuccess:e.healSuccess,healError:e.healError,pathsChecked:e.pathsChecked.map(e=>`${e.path} (${e.exists?`found`:`missing`})`)})}return e})()]),v=new Se(h,g),te=he(m),y=new xe(e.store.path);y.load(),v.setHashCache(y);let b=e.curated.path,x=new i(b);await x.initialize();let S=new a(b,g,h,x);v.setGraphStore(_);let C=u(e.er),w=C?new fe(e.curated.path):void 0;w&&J.debug(`Policy store initialized`,{ruleCount:w.getRules().length});let ne=C?new de:void 0,T=ae(e.sources[0]?.path??M(),re.aiContext),E=P(T),k=e.onboardDir?P(e.onboardDir):!1,A=E||k,j,L=E?T:e.onboardDir;if(A&&L)try{j=ie(L).mtime.toISOString()}catch{}return J.debug(`Onboard state detected`,{onboardComplete:A,onboardTimestamp:j,aiKbExists:E,onboardDirExists:k}),{embedder:h,store:g,stateStore:te,closeStateStore:m===p?void 0:async()=>m.close(),indexer:v,curated:S,graphStore:_,fileCache:new oe,bridge:C,policyStore:w,evolutionCollector:ne,onboardComplete:A,onboardTimestamp:j,eventBus:new c}}function ze(e,t,n){if(e.serverInstructions)return e.serverInstructions;let r=new Set;for(let e of t){let t=n[e];if(t?.category)for(let e of t.category)r.add(e)}let i=[`This server provides ${t.size} tools across ${r.size} categories: ${[...r].sort().join(`, `)}.`,`TOOL ROUTING:`,`- Understand a file -> file_summary (T1=structure, T2=content)`,`- Find code/symbols -> search (hybrid) or symbol (definition + refs)`,`- Validate changes -> check (typecheck+lint) or test_run (tests)`,`- Read file for editing -> read_file (only for exact lines before edits)`,`FORBIDDEN: DO NOT USE native equivalents when AI Kit provides same:`,`- grep/find -> search or find tool`,`- cat/read_file (for understanding) -> file_summary`,`- terminal tsc/lint -> check tool`,`- terminal test -> test_run tool`];return e.readOnly&&i.push(`Server is in read-only mode. Mutating operations are disabled.`),e.features?.length&&i.push(`Active feature groups: ${e.features.join(`, `)}.`),i.join(`
|
|
19
|
-
`)}const Be=j(`background-task`);var Ve=class{queue=[];running=null;get isRunning(){return this.running!==null}get currentTask(){return this.running}get pendingCount(){return this.queue.length}schedule(e){return new Promise((t,n)=>{this.queue.push({...e,resolve:t,reject:n}),this.running||this.processQueue()})}async processQueue(){for(;this.queue.length>0;){let e=this.queue.shift();if(!e)break;this.running=e.name,Be.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Be.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Be.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const X=j(`idle-timer`);var He=class{timer=null;cleanupFns=[];idleMs;disposed=!1;sessionActive=!1;_busy=!1;constructor(e){this.idleMs=e?.idleMs??3e5}setBusy(e){this._busy=e,e?this.cancel():this.touch()}onIdle(e){this.cleanupFns.push(e)}markSessionActive(){this.sessionActive=!0}touch(){this.disposed||this._busy||(this.cancel(),this.timer=setTimeout(()=>{this.runCleanup()},this.idleMs),this.timer.unref&&this.timer.unref())}cancel(){this.timer&&=(clearTimeout(this.timer),null)}dispose(){this.cancel(),this.cleanupFns.length=0,this.disposed=!0}async runCleanup(){if(!this.sessionActive){X.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){X.info(`Skipping idle cleanup — background work in progress`);return}X.info(`Idle for ${this.idleMs/1e3}s — running cleanup`);let e=await Promise.allSettled(this.cleanupFns.map(e=>e()));for(let t of e)t.status===`rejected`&&X.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const Z=j(`memory-monitor`);var Ue=class{timer=null;warningBytes;criticalBytes;intervalMs;pressureFns=[];memoryPressureFns=[];lastLevel=`normal`;constructor(e){this.warningBytes=e?.warningBytes??3221225472,this.criticalBytes=e?.criticalBytes??6442450944,this.intervalMs=e?.intervalMs??3e4}onPressure(e){this.pressureFns.push(e)}registerMemoryPressureCallback(e){this.memoryPressureFns.push(e)}start(){this.timer||(this.timer=setInterval(()=>this.check(),this.intervalMs),this.timer.unref&&this.timer.unref(),Z.debug(`Memory monitor started`,{warningMB:Math.round(this.warningBytes/1024/1024),criticalMB:Math.round(this.criticalBytes/1024/1024),intervalSec:Math.round(this.intervalMs/1e3)}))}stop(){this.timer&&=(clearInterval(this.timer),null)}getRssBytes(){return process.memoryUsage.rss()}check(){let e=this.getRssBytes(),t=`normal`;if(e>=this.criticalBytes?t=`critical`:e>=this.warningBytes&&(t=`warning`),t!==this.lastLevel||t===`critical`){let n=Math.round(e/1024/1024);t===`critical`?Z.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?Z.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&Z.info(`Memory returned to normal: ${n}MB RSS`),this.lastLevel=t}if(t!==`normal`)for(let n of this.pressureFns)try{n(t,e)}catch{}if(t===`critical`)for(let e of this.memoryPressureFns)try{let t=e();t&&typeof t.catch==`function`&&t.catch(()=>{})}catch{}return t===`critical`&&typeof globalThis.gc==`function`&&globalThis.gc(),t}};const We=new Ce;function Ge(e,t){return We.run(e,async()=>{try{return await t()}finally{}})}j(`tool-timeout`);const Ke=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var qe=class extends Error{toolName;timeoutMs;constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function Je(e){return Ke.has(e)?6e5:12e4}function Ye(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new qe(n,t);i.aborted||r.abort(e),o(e)},t);s.unref();try{e(i).then(a,o).finally(()=>clearTimeout(s))}catch(e){clearTimeout(s),o(e instanceof Error?e:Error(String(e)))}})}const Q=j(`server`),Xe=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function Ze(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function Qe(e){let t=[`query`,`path`,`task`,`name`,`start`,`symbol`,`file`,`pattern`],n=[];for(let r of t){let t=e[r];typeof t==`string`&&t.length>0&&t.length<200&&n.push(t)}return n.join(` `).slice(0,200)}async function $e(e,t,n,r){let i=[];if(n){let t=await et(e,n);t&&i.push(t)}try{if(t.statePath){let{ensureLegacyStashImported:n}=await import(`../../tools/dist/index.js`);n(e.stateStore,{stateDir:t.statePath})}let r=e.stateStore.stashList().map(e=>e.key);if(r.length>0){let e=n?n.toLowerCase().split(/\s+/).filter(e=>e.length>2):[];if(e.length===0)i.push(`📦 stash: ${r.length} entries`);else{let t=r.filter(t=>e.some(e=>t.toLowerCase().includes(e))).slice(0,3);t.length>0&&i.push(`📦 stash: ${t.map(e=>`"${Ze(e)}"`).join(`, `)}${r.length>t.length?` (+${r.length-t.length})`:``}`)}}}catch{}if(i.length===0&&!r)return null;if(r){let n=e,r=n.curated;if(r?.list&&n.stateStore)try{let{buildPreludeInjection:e,generatePrelude:a}=await import(`./startup-maintenance-
|
|
19
|
+
`)}const Be=j(`background-task`);var Ve=class{queue=[];running=null;get isRunning(){return this.running!==null}get currentTask(){return this.running}get pendingCount(){return this.queue.length}schedule(e){return new Promise((t,n)=>{this.queue.push({...e,resolve:t,reject:n}),this.running||this.processQueue()})}async processQueue(){for(;this.queue.length>0;){let e=this.queue.shift();if(!e)break;this.running=e.name,Be.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Be.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Be.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const X=j(`idle-timer`);var He=class{timer=null;cleanupFns=[];idleMs;disposed=!1;sessionActive=!1;_busy=!1;constructor(e){this.idleMs=e?.idleMs??3e5}setBusy(e){this._busy=e,e?this.cancel():this.touch()}onIdle(e){this.cleanupFns.push(e)}markSessionActive(){this.sessionActive=!0}touch(){this.disposed||this._busy||(this.cancel(),this.timer=setTimeout(()=>{this.runCleanup()},this.idleMs),this.timer.unref&&this.timer.unref())}cancel(){this.timer&&=(clearTimeout(this.timer),null)}dispose(){this.cancel(),this.cleanupFns.length=0,this.disposed=!0}async runCleanup(){if(!this.sessionActive){X.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){X.info(`Skipping idle cleanup — background work in progress`);return}X.info(`Idle for ${this.idleMs/1e3}s — running cleanup`);let e=await Promise.allSettled(this.cleanupFns.map(e=>e()));for(let t of e)t.status===`rejected`&&X.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const Z=j(`memory-monitor`);var Ue=class{timer=null;warningBytes;criticalBytes;intervalMs;pressureFns=[];memoryPressureFns=[];lastLevel=`normal`;constructor(e){this.warningBytes=e?.warningBytes??3221225472,this.criticalBytes=e?.criticalBytes??6442450944,this.intervalMs=e?.intervalMs??3e4}onPressure(e){this.pressureFns.push(e)}registerMemoryPressureCallback(e){this.memoryPressureFns.push(e)}start(){this.timer||(this.timer=setInterval(()=>this.check(),this.intervalMs),this.timer.unref&&this.timer.unref(),Z.debug(`Memory monitor started`,{warningMB:Math.round(this.warningBytes/1024/1024),criticalMB:Math.round(this.criticalBytes/1024/1024),intervalSec:Math.round(this.intervalMs/1e3)}))}stop(){this.timer&&=(clearInterval(this.timer),null)}getRssBytes(){return process.memoryUsage.rss()}check(){let e=this.getRssBytes(),t=`normal`;if(e>=this.criticalBytes?t=`critical`:e>=this.warningBytes&&(t=`warning`),t!==this.lastLevel||t===`critical`){let n=Math.round(e/1024/1024);t===`critical`?Z.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?Z.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&Z.info(`Memory returned to normal: ${n}MB RSS`),this.lastLevel=t}if(t!==`normal`)for(let n of this.pressureFns)try{n(t,e)}catch{}if(t===`critical`)for(let e of this.memoryPressureFns)try{let t=e();t&&typeof t.catch==`function`&&t.catch(()=>{})}catch{}return t===`critical`&&typeof globalThis.gc==`function`&&globalThis.gc(),t}};const We=new Ce;function Ge(e,t){return We.run(e,async()=>{try{return await t()}finally{}})}j(`tool-timeout`);const Ke=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var qe=class extends Error{toolName;timeoutMs;constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function Je(e){return Ke.has(e)?6e5:12e4}function Ye(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new qe(n,t);i.aborted||r.abort(e),o(e)},t);s.unref();try{e(i).then(a,o).finally(()=>clearTimeout(s))}catch(e){clearTimeout(s),o(e instanceof Error?e:Error(String(e)))}})}const Q=j(`server`),Xe=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function Ze(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function Qe(e){let t=[`query`,`path`,`task`,`name`,`start`,`symbol`,`file`,`pattern`],n=[];for(let r of t){let t=e[r];typeof t==`string`&&t.length>0&&t.length<200&&n.push(t)}return n.join(` `).slice(0,200)}async function $e(e,t,n,r){let i=[];if(n){let t=await et(e,n);t&&i.push(t)}try{if(t.statePath){let{ensureLegacyStashImported:n}=await import(`../../tools/dist/index.js`);n(e.stateStore,{stateDir:t.statePath})}let r=e.stateStore.stashList().map(e=>e.key);if(r.length>0){let e=n?n.toLowerCase().split(/\s+/).filter(e=>e.length>2):[];if(e.length===0)i.push(`📦 stash: ${r.length} entries`);else{let t=r.filter(t=>e.some(e=>t.toLowerCase().includes(e))).slice(0,3);t.length>0&&i.push(`📦 stash: ${t.map(e=>`"${Ze(e)}"`).join(`, `)}${r.length>t.length?` (+${r.length-t.length})`:``}`)}}}catch{}if(i.length===0&&!r)return null;if(r){let n=e,r=n.curated;if(r?.list&&n.stateStore)try{let{buildPreludeInjection:e,generatePrelude:a}=await import(`./startup-maintenance-cbRSFMY5.js`).then(e=>e.a),o=e(await a(r,n.stateStore,void 0,t.skillDir),500);o.lines.length>0&&i.push(o.lines.join(`
|
|
20
20
|
`))}catch(e){Q.debug?.(`Periodic prelude injection failed`,{error:String(e)})}}return i.length===0?null:`\n${i.join(`
|
|
21
|
-
`)}`}async function et(
|
|
21
|
+
`)}`}async function et(e,n){try{let r=await Promise.race([e.store.ftsSearch(n,{limit:3}),new Promise(e=>{let t=setTimeout(()=>e(null),1e3);t.unref&&t.unref()})]);if(!Array.isArray(r)||r.length===0)return null;let i=[];for(let e of r){if(!e||typeof e!=`object`)continue;let n=e.record;if(!n)continue;let r=n.origin;if(r!==`curated`&&r!==`produced`)continue;let a=n.content??``;if(!(!a||a.length<20)){if(a.length<=400){let e=n.headingPath?.trim()||``,t=a.slice(0,400),r=e?`📚 ${e}: ${t}`:`📚 ${t}`;i.push(r)}else{let e=t(a,400),r=n.headingPath?.trim()||``,o=r?`📚 ${r}: ${e}`:`📚 ${e}`;i.push(o)}if(i.length>=2)break}}return i.length===0?null:i.join(`
|
|
22
22
|
`)}catch{return null}}function tt(e,t,n){let r=5,i=0;for(let[a,o]of Object.entries(e)){let e=o.handler;o.handler=async(...o)=>{let s=await e(...o);if(!s||typeof s!=`object`||r<=0||s.isError||Xe.has(a))return s;try{r--,i++;let e=o[0],a=await $e(t,n,Qe(e&&typeof e==`object`?e:{}),i%5==0);a&&(s.content=Array.isArray(s.content)?s.content:[],s.content.push({type:`text`,text:a}))}catch{}return s}}}function nt(e){let t=e.toLowerCase();return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`failed to initialize embedding`,`checksum`,`corrupt`,`malformed`,`could not load`,`onnx`,`database is locked`,`database disk image is malformed`,`file is not a database`,`lance`,`cannot find module`,`cannot find package`,`module not found`,`operation not permitted`,`permission denied`].some(e=>t.includes(e))}function rt(e){return v(e)?[`Auto-heal tried to repair missing runtime dependency files in the npx install.`,`If this persists, clear the broken npx cache and restart:`,` npm cache clean --force`,` npx -y @vpxa/aikit@latest serve`].join(`
|
|
23
23
|
`):[`To fix embedding errors, try deleting the cached model:`,` rm -rf ~/.cache/huggingface/transformers-js/mixedbread-ai/`,`Then restart the server to re-download a fresh copy.`].join(`
|
|
24
|
-
`)}async function it(){try{let{existsSync:
|
|
25
|
-
`),`utf8`),Q.info(`Auto-heal: created ESM shim for @huggingface/transformers (.mjs wrapper → .cjs)`,{path:t}))}catch(e){Q.warn(`Auto-heal: failed to create ESM shim`,{error:e instanceof Error?e.message:String(e),path:t})}}}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model;if(t){let e=I(z(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(e,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared embedding model cache`,{path:e})}catch{}}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=I(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database is locked`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=I(e.store.path,`graph.db`);try{await r(t,{force:!0}),Q.info(`Auto-heal: cleared graph database`,{path:t})}catch{}let i=I(e.store.path,`aikit.db`);try{n.includes(`database is locked`)?(await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: removed stale WAL/shm files for locked database`,{path:i})):(await r(i,{force:!0}),await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: cleared corrupted aikit database`,{path:i}))}catch{}}if(n.includes(`wasm`)||n.includes(`tree-sitter`)||n.includes(`.tmp-`))try{let{readdirSync:e,existsSync:t}=await import(`node:fs`),{join:n}=await import(`node:path`),{homedir:i}=await import(`node:os`),a=n(i(),`.aikit`,`cache`,`wasm`);if(t(a)){let t=e(a).filter(e=>e.includes(`.tmp-`)||e.endsWith(`.wasm.tmp`));for(let e of t)try{await r(n(a,e),{force:!0}),Q.debug(`Auto-heal: removed stale WASM temp file`,{file:e})}catch{}}}catch{}if(v(t)){let e=await b(t);e.repaired||Q.warn(`Auto-heal: missing runtime dependency repair did not complete`,{packages:e.packages,reason:e.reason,error:e.error,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}else n.includes(`cannot find module`)&&!n.includes(`.cache`)&&Q.warn(`Auto-heal: missing module detected during initialization cleanup`,{hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}function ot(
|
|
24
|
+
`)}async function it(){try{let{existsSync:t,readFileSync:n}=await import(`node:fs`),r=I(z(),`.aikit`,`current-version.json`);if(!t(r))return null;let i=JSON.parse(n(r,`utf-8`));if(!i.version)return null;let a=e();return i.version===a?null:i.version}catch{return null}}async function at(e,t){let n=t.toLowerCase(),r;try{({rm:r}=await import(`node:fs/promises`))}catch{return}if(n.includes(`transformers.node.mjs`)&&n.includes(`cannot find module`)){let e=t.match(/Cannot find module '([^']+transformers\.node\.mjs)'/);if(e){let t=e[1],n=t.replace(/\.mjs$/,`.cjs`);try{let{existsSync:e,writeFileSync:r}=await import(`node:fs`);e(n)&&!e(t)&&(r(t,[`// Auto-generated ESM shim — published package missing this file`,`import { createRequire } from 'node:module';`,`const require = createRequire(import.meta.url);`,`const mod = require('./transformers.node.cjs');`,`export default mod;`,``].join(`
|
|
25
|
+
`),`utf8`),Q.info(`Auto-heal: created ESM shim for @huggingface/transformers (.mjs wrapper → .cjs)`,{path:t}))}catch(e){Q.warn(`Auto-heal: failed to create ESM shim`,{error:e instanceof Error?e.message:String(e),path:t})}}}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model;if(t){let e=I(z(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(e,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared embedding model cache`,{path:e})}catch{}}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=I(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database is locked`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=I(e.store.path,`graph.db`);try{await r(t,{force:!0}),Q.info(`Auto-heal: cleared graph database`,{path:t})}catch{}let i=I(e.store.path,`aikit.db`);try{n.includes(`database is locked`)?(await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: removed stale WAL/shm files for locked database`,{path:i})):(await r(i,{force:!0}),await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: cleared corrupted aikit database`,{path:i}))}catch{}}if(n.includes(`wasm`)||n.includes(`tree-sitter`)||n.includes(`.tmp-`))try{let{readdirSync:e,existsSync:t}=await import(`node:fs`),{join:n}=await import(`node:path`),{homedir:i}=await import(`node:os`),a=n(i(),`.aikit`,`cache`,`wasm`);if(t(a)){let t=e(a).filter(e=>e.includes(`.tmp-`)||e.endsWith(`.wasm.tmp`));for(let e of t)try{await r(n(a,e),{force:!0}),Q.debug(`Auto-heal: removed stale WASM temp file`,{file:e})}catch{}}}catch{}if(v(t)){let e=await b(t);e.repaired||Q.warn(`Auto-heal: missing runtime dependency repair did not complete`,{packages:e.packages,reason:e.reason,error:e.error,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}else n.includes(`cannot find module`)&&!n.includes(`.cache`)&&Q.warn(`Auto-heal: missing module detected during initialization cleanup`,{hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}function ot(t,i){let a=g(t,C,l,m(t)),o=ze(t,a,l),c=new le({name:t.serverName??E,version:e()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:o}),u=`initializing`,_=``,ee=!1,v=null,b=null,T=null;function re(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 D=()=>u===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,_?`Error: ${_}`:``,``,`**${w.size} tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, regex_test, encode,`,`stash, checkpoint, lane, process, time, env, and more.`,``,rt(_),``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
|
|
26
26
|
`):[`AI Kit is still initializing (loading embeddings model & store).`,``,`**${w.size} tools are already available** while initialization completes — including:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, 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(`
|
|
27
|
-
`);Ee(c);let O=new p;O.use(d(),{order:1,name:`structured-content-guard`}),S(c,O,e.toolPrefix??``);let k=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let A=[];for(let e of C){if(!a.has(e))continue;let t=s(e),n=c.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:D()}]}));w.has(e)?n.remove():A.push(n)}h(c,e,a),c.sendToolListChanged=k;let j=c.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`}]})),M=c.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:G(V.string(),()=>[])}},async()=>({messages:[]})),P,F,ie=new Promise((e,t)=>{P=e,F=t}),I,ae=new Promise(e=>{I=e}),oe=()=>I?.(),L=(async()=>{await ae;try{let{createRequire:e}=await import(`node:module`),{readFileSync:t,existsSync:n}=await import(`node:fs`),{fileURLToPath:r}=await import(`node:url`),{resolve:i,dirname:a}=await import(`node:path`),o=e(import.meta.url),s=a(r(import.meta.url)),c=i(s,`..`,`package.json`),l=i(s,`..`,`..`),u=JSON.parse(t(c,`utf8`)),d=Object.keys(u.dependencies??{}),f=[`@mixmark-io/domino`],p=[...d,...f.filter(e=>!d.includes(e))],m=p.filter(e=>!e.startsWith(`@aikit/`)),h=p.filter(e=>e.startsWith(`@aikit/`)),g=[];for(let e of m)try{o.resolve(e)}catch{try{o.resolve(`${e}/package.json`)}catch{g.push(e)}}g.length>0&&Q.warn(`Dependencies not resolvable — server may operate in degraded mode`,{missing:g,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`});let _=[];if(h.length>0){for(let e of h)n(i(l,e.slice(7),`dist`))||_.push(e);_.length>0&&Q.warn(`Workspace sibling packages missing dist — server may have degraded features`,{missing:_,hint:`Reinstall: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}}catch{}let a;try{a=await Y(e)}catch(t){let n=t instanceof Error?t.message:String(t);if(nt(n)){let t=await it();if(t){u=`failed`,_=`Server v${r()} superseded by installed v${t}. Restart the MCP server to use the new version.`,Q.info(_),F?.(Error(_));return}Q.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:n}),await at(e,n);try{a=await Y(e),Q.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){u=`failed`,_=e instanceof Error?e.message:String(e),Q.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:_,originalError:n}),F?.(e instanceof Error?e:Error(_));return}}else{u=`failed`,_=n,Q.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:_}),F?.(t instanceof Error?t:Error(_));return}}n();let o=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let s=c.sendPromptListChanged.bind(c);c.sendPromptListChanged=()=>{};let l=c.sendResourceListChanged.bind(c);c.sendResourceListChanged=()=>{};for(let e of A)e.remove();j.remove(),M.remove();let d=c._registeredTools??{};for(let e of w)d[e]?.remove();let p=new Le(c),m=t(c);y({server:c,aikit:a,config:e,elicitor:we(c),resourceNotifier:p,samplingClient:m,indexMode:i,getSmartState:i===`smart`?(()=>{let e=T;return e?.getState?e.getState():null}):null,getSmartScheduler:i===`smart`?()=>{let e=T;return e?{prioritize:e.prioritize.bind(e)}:null}:null}),Fe(c,{curated:a.curated,store:a.store,graphStore:a.graphStore,stateStore:a.stateStore},i),c.sendToolListChanged=o,c.sendPromptListChanged=s,c.sendResourceListChanged=l,Promise.resolve(c.sendToolListChanged()).catch(()=>{}),Promise.resolve(c.sendPromptListChanged()).catch(()=>{}),Promise.resolve(c.sendResourceListChanged()).catch(()=>{});let h=c._registeredTools??{};for(let[e,t]of Object.entries(h)){if(ne.has(e))continue;let n=t.handler;t.handler=async(...r)=>{if(!a.indexer.isIndexing)return n(...r);let i=ee?`re-indexing`:`running initial index`,o=new Promise(n=>setTimeout(()=>n({content:[{type:`text`,text:`⏳ AI Kit is ${i}. The tool "${e}" timed out waiting for index data (${te/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}}),te));return Promise.race([n(...r),o])}}for(let[e,t]of Object.entries(h)){let n=t.handler,r=Je(e);t.handler=async(...i)=>{try{return await Ye(e=>Ge(e,()=>n(...i)),r,e)}catch(n){if(n instanceof qe)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.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}};throw n}}}let g=Object.keys(h).length;g<C.length&&Q.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:C.length,registeredToolCount:g}),Q.debug(`MCP server configured`,{toolCount:C.length,resourceCount:4});let x=new Ue;x.onPressure((e,t)=>{e===`warning`&&Oe(),e===`critical`&&(Q.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),Oe())}),x.registerMemoryPressureCallback(()=>a.embedder.shutdown?.()),x.start();let S=new He;b=S,S.onIdle(async()=>{if(R.isRunning||a.indexer.isIndexing){Q.info(`Idle cleanup deferred — background tasks still running`),S.touch();return}Q.info(`Idle cleanup: releasing cached memory (connections stay open)`);try{a.store.releaseMemory?.(),a.graphStore.releaseMemory?.()}catch{}}),S.touch();let E=!1;for(let e of Object.values(h)){let t=e.handler;e.handler=async(...e)=>{if(E||(E=!0,S.markSessionActive()),S.touch(),T){let t=re(e[0]);t.length>0&&T.prioritize(...t)}return t(...e)}}tt(h,a,{statePath:e.stateDir??``,skillDir:e.skillDir});for(let[,e]of Object.entries(h)){let t=e.config?.outputSchema;if(!t)continue;let n=e.handler;e.handler=async(...e)=>{let r=await n(...e);if(!r||typeof r!=`object`)return r;let i=r;return!(`content`in i)||i.isError||i.structuredContent!=null&&typeof i.structuredContent==`object`?r:(i.structuredContent=f(t),i.structuredContent??={},r)}}process.stdin.on(`end`,()=>(Q.info(`stdin closed — MCP client disconnected. Shutting down.`),process.exit(0))),process.stdin.on(`error`,()=>(Q.info(`stdin error — MCP client disconnected. Shutting down.`),process.exit(0))),v=a,P?.(a)})(),se=async()=>{let t;try{t=await ie}catch{Q.warn(`Skipping initial index — AI Kit initialization failed`);return}b?.setBusy(!0);try{let n=e.sources.map(e=>e.path).join(`, `);Q.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&&Q.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Q.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});ee=!0,Q.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Q.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();Q.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Q.error(`Curated re-index failed`,N(e))}}catch(e){Q.error(`Initial index failed; will retry on aikit_reindex`,N(e))}finally{b?.setBusy(!1)}},R=new Ve,ce=()=>R.schedule({name:`initial-index`,fn:se}),z=process.ppid,B=setInterval(()=>{try{process.kill(z,0)}catch{Q.info(`Parent process died; shutting down`,{parentPid:z}),clearInterval(B),x(),T?.stop&&T.stop(),import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),ie.then(async e=>{await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.closeStateStore?.().catch(()=>{})??Promise.resolve(),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return B.unref(),{server:c,startInit:oe,ready:L,runInitialIndex:ce,get aikit(){return v},scheduler:R,setSmartScheduler(e){T=e}}}const $=j(`server`);function st(e,n){let i=g(n,[...C,..._],l,m(n)),a=ze(n,i,l),s=new le({name:n.serverName??E,version:r()},{capabilities:{logging:{},completions:{},prompts:{},extensions:{roots:{}}},instructions:a}),c=s;c.setNotificationHandler(ve,async()=>{try{let{roots:e}=await c.listRoots();if(e&&e.length>0){let t=T(e[0].uri);process.env.AIKIT_TRANSPORT===`http`?(n.sources[0]={path:t,excludePatterns:n.sources[0]?.excludePatterns??[]},n.allRoots=e.map(e=>T(e.uri)),$.info(`Workspace root updated (HTTP mode)`,{rootPath:t,sourceCount:n.sources.length})):(o(n,t),$.info(`Workspace root updated (stdio mode)`,{rootPath:t}))}}catch(e){$.debug(`MCP roots/list not available`,{error:N(e)})}}),Ee(s),y({server:s,aikit:e,config:n,elicitor:we(s),resourceNotifier:new Le(s),samplingClient:t(s),precomputedActiveTools:i});let u=n.sources[0]?.path??M();return e.eventBus?.emit({type:`session:start`,serverVersion:r(),workspaceRoot:u,timestamp:Date.now(),eventId:`sess-start-${Date.now()}`,workspaceId:A(u),source:`server`}),Fe(s,{curated:e.curated,store:e.store,graphStore:e.graphStore,stateStore:e.stateStore},n.indexMode),s}async function ct(e){let t=await Y(e),n=st(t,e);$.debug(`MCP server configured`,{toolCount:C.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);$.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&&$.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&$.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});$.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){$.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();$.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){$.error(`Curated re-index failed`,N(e))}}catch(e){$.error(`Initial index failed; will retry on aikit_reindex`,N(e))}},i=async()=>{$.info(`Shutting down`);try{await ee(),$.info(`Auto-knowledge flushed on shutdown`)}catch(e){$.warn(`Auto-knowledge flush failed on shutdown`,{error:String(e)})}try{t.stateStore&&await se(t.stateStore,`session-end`,{reason:`server-shutdown`,timestamp:Date.now()},{notes:`Server shutdown checkpoint`})}catch(e){$.warn(`Session-end checkpoint save failed`,{error:String(e)})}x(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await Promise.all([t.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),t.graphStore.close().catch(()=>{}),t.closeStateStore?.().catch(()=>{})??Promise.resolve(),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{$.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{C as ALL_TOOL_NAMES,ot as createLazyServer,st as createMcpServer,ct as createServer,Y as initializeAikit,y as registerMcpTools};
|
|
27
|
+
`);Ee(c);let O=new p;O.use(d(),{order:1,name:`structured-content-guard`}),S(c,O,t.toolPrefix??``);let k=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let A=[];for(let e of C){if(!a.has(e))continue;let t=s(e),n=c.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:D()}]}));w.has(e)?n.remove():A.push(n)}h(c,t,a),c.sendToolListChanged=k;let j=c.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`}]})),M=c.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:G(V.string(),()=>[])}},async()=>({messages:[]})),P,F,ie=new Promise((e,t)=>{P=e,F=t}),I,ae=new Promise(e=>{I=e}),oe=()=>I?.(),L=(async()=>{await ae;try{let{createRequire:e}=await import(`node:module`),{readFileSync:t,existsSync:n}=await import(`node:fs`),{fileURLToPath:r}=await import(`node:url`),{resolve:i,dirname:a}=await import(`node:path`),o=e(import.meta.url),s=a(r(import.meta.url)),c=i(s,`..`,`package.json`),l=i(s,`..`,`..`),u=JSON.parse(t(c,`utf8`)),d=Object.keys(u.dependencies??{}),f=[`@mixmark-io/domino`],p=[...d,...f.filter(e=>!d.includes(e))],m=p.filter(e=>!e.startsWith(`@aikit/`)),h=p.filter(e=>e.startsWith(`@aikit/`)),g=[];for(let e of m)try{o.resolve(e)}catch{try{o.resolve(`${e}/package.json`)}catch{g.push(e)}}g.length>0&&Q.warn(`Dependencies not resolvable — server may operate in degraded mode`,{missing:g,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`});let _=[];if(h.length>0){for(let e of h)n(i(l,e.slice(7),`dist`))||_.push(e);_.length>0&&Q.warn(`Workspace sibling packages missing dist — server may have degraded features`,{missing:_,hint:`Reinstall: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}}catch{}let a;try{a=await Y(t)}catch(n){let r=n instanceof Error?n.message:String(n);if(nt(r)){let n=await it();if(n){u=`failed`,_=`Server v${e()} superseded by installed v${n}. Restart the MCP server to use the new version.`,Q.info(_),F?.(Error(_));return}Q.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:r}),await at(t,r);try{a=await Y(t),Q.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){u=`failed`,_=e instanceof Error?e.message:String(e),Q.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:_,originalError:r}),F?.(e instanceof Error?e:Error(_));return}}else{u=`failed`,_=r,Q.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:_}),F?.(n instanceof Error?n:Error(_));return}}r();let o=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let s=c.sendPromptListChanged.bind(c);c.sendPromptListChanged=()=>{};let l=c.sendResourceListChanged.bind(c);c.sendResourceListChanged=()=>{};for(let e of A)e.remove();j.remove(),M.remove();let d=c._registeredTools??{};for(let e of w)d[e]?.remove();let p=new Le(c),m=n(c);y({server:c,aikit:a,config:t,elicitor:we(c),resourceNotifier:p,samplingClient:m,indexMode:i,getSmartState:i===`smart`?(()=>{let e=T;return e?.getState?e.getState():null}):null,getSmartScheduler:i===`smart`?()=>{let e=T;return e?{prioritize:e.prioritize.bind(e)}:null}:null}),Fe(c,{curated:a.curated,store:a.store,graphStore:a.graphStore,stateStore:a.stateStore},i),c.sendToolListChanged=o,c.sendPromptListChanged=s,c.sendResourceListChanged=l,Promise.resolve(c.sendToolListChanged()).catch(()=>{}),Promise.resolve(c.sendPromptListChanged()).catch(()=>{}),Promise.resolve(c.sendResourceListChanged()).catch(()=>{});let h=c._registeredTools??{};for(let[e,t]of Object.entries(h)){if(ne.has(e))continue;let n=t.handler;t.handler=async(...r)=>{if(!a.indexer.isIndexing)return n(...r);let i=ee?`re-indexing`:`running initial index`,o=new Promise(n=>setTimeout(()=>n({content:[{type:`text`,text:`⏳ AI Kit is ${i}. The tool "${e}" timed out waiting for index data (${te/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}}),te));return Promise.race([n(...r),o])}}for(let[e,t]of Object.entries(h)){let n=t.handler,r=Je(e);t.handler=async(...i)=>{try{return await Ye(e=>Ge(e,()=>n(...i)),r,e)}catch(n){if(n instanceof qe)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.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}};throw n}}}let g=Object.keys(h).length;g<C.length&&Q.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:C.length,registeredToolCount:g}),Q.debug(`MCP server configured`,{toolCount:C.length,resourceCount:4});let x=new Ue;x.onPressure((e,t)=>{e===`warning`&&Oe(),e===`critical`&&(Q.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),Oe())}),x.registerMemoryPressureCallback(()=>a.embedder.shutdown?.()),x.start();let S=new He;b=S,S.onIdle(async()=>{if(R.isRunning||a.indexer.isIndexing){Q.info(`Idle cleanup deferred — background tasks still running`),S.touch();return}Q.info(`Idle cleanup: releasing cached memory (connections stay open)`);try{a.store.releaseMemory?.(),a.graphStore.releaseMemory?.()}catch{}}),S.touch();let E=!1;for(let e of Object.values(h)){let t=e.handler;e.handler=async(...e)=>{if(E||(E=!0,S.markSessionActive()),S.touch(),T){let t=re(e[0]);t.length>0&&T.prioritize(...t)}return t(...e)}}tt(h,a,{statePath:t.stateDir??``,skillDir:t.skillDir});for(let[,e]of Object.entries(h)){let t=e.config?.outputSchema;if(!t)continue;let n=e.handler;e.handler=async(...e)=>{let r=await n(...e);if(!r||typeof r!=`object`)return r;let i=r;return!(`content`in i)||i.isError||i.structuredContent!=null&&typeof i.structuredContent==`object`?r:(i.structuredContent=f(t),i.structuredContent??={},r)}}process.stdin.on(`end`,()=>(Q.info(`stdin closed — MCP client disconnected. Shutting down.`),process.exit(0))),process.stdin.on(`error`,()=>(Q.info(`stdin error — MCP client disconnected. Shutting down.`),process.exit(0))),v=a,P?.(a)})(),se=async()=>{let e;try{e=await ie}catch{Q.warn(`Skipping initial index — AI Kit initialization failed`);return}b?.setBusy(!0);try{let n=t.sources.map(e=>e.path).join(`, `);Q.info(`Running initial index`,{sourcePaths:n});let r=await e.indexer.index(t,e=>{e.phase===`crawling`||e.phase===`done`||(e.phase===`chunking`&&e.currentFile&&Q.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Q.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});ee=!0,Q.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await e.store.createFtsIndex()}catch(e){Q.warn(`FTS index creation failed`,N(e))}try{let t=await e.curated.reindexAll();Q.info(`Curated re-index complete`,{indexed:t.indexed})}catch(e){Q.error(`Curated re-index failed`,N(e))}}catch(e){Q.error(`Initial index failed; will retry on aikit_reindex`,N(e))}finally{b?.setBusy(!1)}},R=new Ve,ce=()=>R.schedule({name:`initial-index`,fn:se}),z=process.ppid,B=setInterval(()=>{try{process.kill(z,0)}catch{Q.info(`Parent process died; shutting down`,{parentPid:z}),clearInterval(B),x(),T?.stop&&T.stop(),import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),ie.then(async e=>{await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.closeStateStore?.().catch(()=>{})??Promise.resolve(),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return B.unref(),{server:c,startInit:oe,ready:L,runInitialIndex:ce,get aikit(){return v},scheduler:R,setSmartScheduler(e){T=e}}}const $=j(`server`);function st(t,r){let i=g(r,[...C,..._],l,m(r)),a=ze(r,i,l),s=new le({name:r.serverName??E,version:e()},{capabilities:{logging:{},completions:{},prompts:{},extensions:{roots:{}}},instructions:a}),c=s;c.setNotificationHandler(ve,async()=>{try{let{roots:e}=await c.listRoots();if(e&&e.length>0){let t=T(e[0].uri);process.env.AIKIT_TRANSPORT===`http`?(r.sources[0]={path:t,excludePatterns:r.sources[0]?.excludePatterns??[]},r.allRoots=e.map(e=>T(e.uri)),$.info(`Workspace root updated (HTTP mode)`,{rootPath:t,sourceCount:r.sources.length})):(o(r,t),$.info(`Workspace root updated (stdio mode)`,{rootPath:t}))}}catch(e){$.debug(`MCP roots/list not available`,{error:N(e)})}}),Ee(s),y({server:s,aikit:t,config:r,elicitor:we(s),resourceNotifier:new Le(s),samplingClient:n(s),precomputedActiveTools:i});let u=r.sources[0]?.path??M();return t.eventBus?.emit({type:`session:start`,serverVersion:e(),workspaceRoot:u,timestamp:Date.now(),eventId:`sess-start-${Date.now()}`,workspaceId:A(u),source:`server`}),Fe(s,{curated:t.curated,store:t.store,graphStore:t.graphStore,stateStore:t.stateStore},r.indexMode),s}async function ct(e){let t=await Y(e),n=st(t,e);$.debug(`MCP server configured`,{toolCount:C.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);$.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&&$.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&$.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});$.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){$.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();$.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){$.error(`Curated re-index failed`,N(e))}}catch(e){$.error(`Initial index failed; will retry on aikit_reindex`,N(e))}},i=async()=>{$.info(`Shutting down`);try{await ee(),$.info(`Auto-knowledge flushed on shutdown`)}catch(e){$.warn(`Auto-knowledge flush failed on shutdown`,{error:String(e)})}try{t.stateStore&&await se(t.stateStore,`session-end`,{reason:`server-shutdown`,timestamp:Date.now()},{notes:`Server shutdown checkpoint`})}catch(e){$.warn(`Session-end checkpoint save failed`,{error:String(e)})}x(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await Promise.all([t.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),t.graphStore.close().catch(()=>{}),t.closeStateStore?.().catch(()=>{})??Promise.resolve(),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{$.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{C as ALL_TOOL_NAMES,ot as createLazyServer,st as createMcpServer,ct as createServer,Y as initializeAikit,y as registerMcpTools};
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import{n as e,t}from"./curated-manager-
|
|
1
|
+
import{n as e,t}from"./curated-manager-D4MOFQ-t.js";import{c as n,f as r,p as i,s as a}from"./startup-maintenance-kHH8tjds.js";import{reconfigureForWorkspace as o}from"./config-CQKoGfwD.js";import{S as s,_ as c,b as l,c as u,d,f,g as p,h as m,i as h,l as g,m as _,n as ee,o as v,p as te,r as y,s as b,t as x,u as S,v as C,x as w,y as ne}from"./register-tools-i_1kjBhi.js";import{fileURLToPath as T}from"node:url";import{AIKIT_PATHS as re,DISPLAY_SERVER_NAME as E,EMBEDDING_DEFAULTS as D,MODEL_REGISTRY as O,addLogListener as k,computePartitionKey as A,createLogger as j,safeCwdOrHome as M,serializeError as N}from"../../core/dist/index.js";import{existsSync as P,mkdirSync as F,statSync as ie}from"node:fs";import{join as I,resolve as ae}from"node:path";import{FileCache as oe,checkpointList as L,checkpointSave as se,listWorksets as R,stashList as ce}from"../../tools/dist/index.js";import{homedir as z}from"node:os";import{McpServer as le}from"@modelcontextprotocol/sdk/server/mcp.js";import{WasmDiagnostics as B,initializeWasm as ue}from"../../chunker/dist/index.js";import{z as V}from"zod";import{EvolutionCollector as de,PolicyStore as fe}from"../../enterprise-bridge/dist/index.js";import{SqliteGraphStore as pe,allMigrations as me,createSqliteAdapter as H,createStateStore as he,createStore as ge,runMigrations as _e}from"../../store/dist/index.js";import{RootsListChangedNotificationSchema as ve}from"@modelcontextprotocol/sdk/types.js";import{buildFormSchema as U,field as W,normalizeResponse as ye}from"../../elicitation/dist/index.js";import{completable as G}from"@modelcontextprotocol/sdk/server/completable.js";import{EmbedderProxy as be}from"../../embeddings/dist/index.js";import{FileHashCache as xe,IncrementalIndexer as Se}from"../../indexer/dist/index.js";import{AsyncLocalStorage as Ce}from"node:async_hooks";function we(e){function t(){return!!e.server?.getClientCapabilities?.()?.elicitation}async function n(n,r){if(t())try{let t=await e.server.elicitInput({message:n,requestedSchema:r});return ye(t?{action:t.action,content:t.content}:void 0)}catch{return}}return{get available(){return t()},async ask(e){return await n(e.message,e.schema)||{action:`decline`}},async confirm(e){let t=await n(e,U({confirmed:W.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,U({selection:W.select(`Choose one`,t)}));if(r?.action!==`accept`)return null;let i=r.content?.selection;return typeof i==`string`?i:null},async selectMany(e,t){let r=await n(e,U({selections:W.multi(`Choose one or more`,t)}));if(r?.action!==`accept`)return[];let i=r.content?.selections;return Array.isArray(i)?i:[]},async promptText(e,t){let r=await n(e,U({text:W.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const Te={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function Ee(e){return k(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:Te[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const K=3e4,q=new Map;function De(e,t,n){let r=q.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(q.set(e,{data:n,expires:Date.now()+t}),n))}function Oe(){q.clear()}function ke(e,t){return De(`curated-paths`,K,async()=>e.listPaths({limit:5e3})).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Ae(e,t){return De(`file-paths`,K,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function je(e,t){return De(`symbol-names`,K,async()=>(await e.findNodes({type:`symbol`,limit:500})).map(e=>e.name)).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function Me(e,t){return t?ce(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Ne(e){return R().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function Pe(e,t){return t?L(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function Fe(e,t,n){if(e.registerPrompt(`ready`,{title:`AI Kit Ready`,description:`AI Kit is ready — quick-start guide for search, onboard, and workflows`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`AI Kit is ready. Quick start:`,``,'• **New project?** → `onboard({ path: "." })` for full codebase analysis','• **Returning?** → `status({})` then `search({ query: "SESSION CHECKPOINT", origin: "curated" })`','• **Exploring?** → `guide({ goal: "your task" })` for workflow recommendations','• **Quick lookup?** → `search({ query: "your question" })`'].join(`
|
|
2
2
|
`)}}]})),e.registerPrompt(`onboard`,{title:`Onboard Codebase`,description:`Analyze the codebase for first-time onboarding — runs all analyzers and produces a knowledge summary`,argsSchema:{path:V.string().optional().describe(`Path to analyze (default: workspace root)`)}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the full onboarding workflow for "${e??`.`}"`,``,`1. \`onboard({ path: "${e??`.`}" })\` — full codebase analysis`,`2. \`produce_knowledge({ path: "${e??`.`}" })\` — generate synthesis`,'3. `knowledge({ action: "remember", ... })` for key curated entries',"4. `status` to verify index health"].join(`
|
|
3
3
|
`)}}]})),e.registerPrompt(`sessionStart`,{title:`Start AI Kit Session`,description:`Initialize an AI Kit session — check status, list knowledge, and resume from last checkpoint`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session start protocol:`,``,"1. `status({})` — check AI Kit health and onboard state",'2. `knowledge({ action: "list" })` — see stored knowledge entries','3. `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — resume prior work'].join(`
|
|
4
4
|
`)}}]})),e.registerPrompt(`sessionEnd`,{title:`End AI Kit Session`,description:`Persist decisions and create a session checkpoint before ending`,argsSchema:{summary:V.string().describe(`Brief summary of decisions made, blockers encountered, and next steps`)}},async({summary:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Run the session end protocol:`,``,'1. `knowledge({ action: "remember", title: "Session checkpoint: '+e.slice(0,60)+`...", content: "`+e.replace(/"/g,`\\"`)+'", category: "session" })` — persist findings',n===`smart`?`2. Smart indexing is active — index refreshes automatically`:"2. `reindex({})` — refresh search index if files changed",`3. Confirm session data saved`].join(`
|
|
5
|
-
`)}}]})),e.registerPrompt(`search`,{title:`Search AI Kit`,description:`Search AI Kit with hybrid semantic + keyword search`,argsSchema:{query:V.string().describe(`Search query`)}},async({query:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Search AI Kit for: "${e}"\n\nUse \`search({ query: "${e.replace(/"/g,`\\"`)}" })\` to find relevant code, documentation, and curated knowledge.`}}]})),e.registerPrompt(`remember`,{title:`Remember Knowledge`,description:`Store a decision, convention, or finding as curated knowledge`,argsSchema:{title:V.string().describe(`Title of the knowledge entry`),content:V.string().describe(`Content to remember`),category:V.enum([`conventions`,`decisions`,`patterns`,`blockers`,`tasks`]).optional().describe(`Category (default: conventions)`)}},async({title:e,content:t,category:n})=>({messages:[{role:`user`,content:{type:`text`,text:`Store this knowledge:\n\n\`knowledge({ action: "remember", title: "${e.replace(/"/g,`\\"`)}", content: "${t.replace(/"/g,`\\"`).slice(0,200)}...", category: "${n??`conventions`}" })\``}}]})),e.registerPrompt(`planTask`,{title:`Plan a Task`,description:`Generate a reading plan and scope map for a development task`,argsSchema:{task:V.string().describe(`Description of the task to plan`)}},async({task:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Plan implementation for: "${e}"`,``,'1. `search({ query: "'+e.replace(/"/g,`\\"`)+'" })` — find related code and prior decisions','2. `scope_map({ task: "'+e.replace(/"/g,`\\"`)+'" })` — generate a reading plan',
|
|
6
|
-
`)}}]})),e.registerPrompt(`investigate`,{title:`Investigate Bug`,description:`Bug investigation workflow — parse error, find symbols, trace data flow, assess impact`,argsSchema:{error:V.string().describe(`Error message, stack trace, or bug description`)}},async({error:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Investigate this error:`,"```",e,"```",``,`Follow the bug investigation workflow:`,"1. `parse_output({ text: <error> })` — extract structured data from the error","2. `symbol({ name: <relevant symbol> })` — find definition and references",'3. `trace({ symbol: <symbol>, direction: "backward" })` — trace data flow to find root cause',"4. `blast_radius({
|
|
5
|
+
`)}}]})),e.registerPrompt(`search`,{title:`Search AI Kit`,description:`Search AI Kit with hybrid semantic + keyword search`,argsSchema:{query:V.string().describe(`Search query`)}},async({query:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Search AI Kit for: "${e}"\n\nUse \`search({ query: "${e.replace(/"/g,`\\"`)}" })\` to find relevant code, documentation, and curated knowledge.`}}]})),e.registerPrompt(`remember`,{title:`Remember Knowledge`,description:`Store a decision, convention, or finding as curated knowledge`,argsSchema:{title:V.string().describe(`Title of the knowledge entry`),content:V.string().describe(`Content to remember`),category:V.enum([`conventions`,`decisions`,`patterns`,`blockers`,`tasks`]).optional().describe(`Category (default: conventions)`)}},async({title:e,content:t,category:n})=>({messages:[{role:`user`,content:{type:`text`,text:`Store this knowledge:\n\n\`knowledge({ action: "remember", title: "${e.replace(/"/g,`\\"`)}", content: "${t.replace(/"/g,`\\"`).slice(0,200)}...", category: "${n??`conventions`}" })\``}}]})),e.registerPrompt(`planTask`,{title:`Plan a Task`,description:`Generate a reading plan and scope map for a development task`,argsSchema:{task:V.string().describe(`Description of the task to plan`)}},async({task:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Plan implementation for: "${e}"`,``,'1. `search({ query: "'+e.replace(/"/g,`\\"`)+'" })` — find related code and prior decisions','2. `scope_map({ task: "'+e.replace(/"/g,`\\"`)+'" })` — generate a reading plan','3. For each recommended file, use `file_summary` with `tier: "T2"` and `query` for detail',"4. `blast_radius` on planned changes to assess impact"].join(`
|
|
6
|
+
`)}}]})),e.registerPrompt(`investigate`,{title:`Investigate Bug`,description:`Bug investigation workflow — parse error, find symbols, trace data flow, assess impact`,argsSchema:{error:V.string().describe(`Error message, stack trace, or bug description`)}},async({error:e})=>({messages:[{role:`user`,content:{type:`text`,text:[`Investigate this error:`,"```",e,"```",``,`Follow the bug investigation workflow:`,"1. `parse_output({ text: <error> })` — extract structured data from the error","2. `symbol({ name: <relevant symbol> })` — find definition and references",'3. `trace({ symbol: <symbol>, direction: "backward" })` — trace data flow to find root cause',"4. `blast_radius({ files: [<affected files>] })` — assess fix impact"].join(`
|
|
7
7
|
`)}}]})),!t)return;let{curated:r,store:i,graphStore:a}=t;e.registerPrompt(`read_knowledge`,{title:`Read Knowledge`,description:`Read a curated knowledge entry by path — with autocomplete`,argsSchema:{path:G(V.string().describe(`Path of the curated entry (e.g. conventions/naming.md)`),async e=>ke(r,e))}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Read the curated knowledge entry: \`knowledge({ action: "read", path: "${e}" })\``}}]})),e.registerPrompt(`update_knowledge`,{title:`Update Knowledge`,description:`Update an existing curated knowledge entry — with autocomplete`,argsSchema:{path:G(V.string().describe(`Path of the curated entry to update`),async e=>ke(r,e)),content:V.string().describe(`New content for the entry`)}},async({path:e,content:t})=>({messages:[{role:`user`,content:{type:`text`,text:`Update the curated entry at "${e}":\n\n\`knowledge({ action: "update", path: "${e}", content: "${t.replace(/"/g,`\\"`).slice(0,200)}..." })\``}}]})),e.registerPrompt(`forget_knowledge`,{title:`Forget Knowledge`,description:`Delete a curated knowledge entry — with autocomplete`,argsSchema:{path:G(V.string().describe(`Path of the curated entry to delete`),async e=>ke(r,e))}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Delete the curated entry: \`knowledge({ action: "forget", path: "${e}" })\``}}]})),e.registerPrompt(`lookup_file`,{title:`Lookup File`,description:`Look up an indexed file — with autocomplete`,argsSchema:{path:G(V.string().describe(`Source file path`),async e=>Ae(i,e))}},async({path:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Look up the indexed file: \`file_summary({ path: "${e}" })\``}}]})),e.registerPrompt(`find_symbol`,{title:`Find Symbol`,description:`Find a symbol definition and references — with autocomplete`,argsSchema:{name:G(V.string().describe(`Symbol name`),async e=>je(a,e))}},async({name:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Find symbol: \`symbol({ name: "${e}" })\``}}]})),e.registerPrompt(`get_stash`,{title:`Get Stash`,description:`Retrieve a stashed value by key — with autocomplete`,argsSchema:{key:G(V.string().describe(`Stash key`),e=>Me(e,t?.stateStore))}},async({key:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Get stashed value: \`stash({ action: "get", key: "${e}" })\``}}]})),e.registerPrompt(`get_workset`,{title:`Get Workset`,description:`Load a saved workset by name — with autocomplete`,argsSchema:{name:G(V.string().describe(`Workset name`),e=>Ne(e))}},async({name:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Load workset: \`workset({ action: "load", name: "${e}" })\``}}]})),e.registerPrompt(`load_checkpoint`,{title:`Load Checkpoint`,description:`Restore a saved checkpoint by name — with autocomplete`,argsSchema:{name:G(V.string().describe(`Checkpoint name`),e=>Pe(e,t?.stateStore))}},async({name:e})=>({messages:[{role:`user`,content:{type:`text`,text:`Load checkpoint: \`checkpoint({ action: "load", name: "${e}" })\``}}]})),e.registerPrompt(`audit_workflow`,{title:`Audit Workflow`,description:`Run a full project quality audit: check → test_run → audit → produce recommendations`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Audit Workflow`,``,`Execute the following tools in sequence:`,``,"1. `check({})` — Run typecheck + lint","2. `test_run({})` — Run all tests","3. `audit({})` — Full project audit","4. Review findings and `remember` important patterns",``,`Report: pass/fail status, error counts, audit recommendations, and suggested next steps.`].join(`
|
|
8
|
-
`)}}]})),e.registerPrompt(`refactor_workflow`,{title:`Refactor Workflow`,description:`Safe refactoring workflow: analyze → blast_radius → implement → verify`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Refactor Workflow`,``,`For the target files/symbols:`,``,'1. `analyze({ aspect: "structure", path })` — Understand current structure','2. `analyze({ aspect: "dependencies", path })` — Map dependency graph',"3. `blast_radius({
|
|
8
|
+
`)}}]})),e.registerPrompt(`refactor_workflow`,{title:`Refactor Workflow`,description:`Safe refactoring workflow: analyze → blast_radius → implement → verify`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Refactor Workflow`,``,`For the target files/symbols:`,``,'1. `analyze({ aspect: "structure", path })` — Understand current structure','2. `analyze({ aspect: "dependencies", path })` — Map dependency graph',"3. `blast_radius({ files })` — Assess impact scope",`4. Implement changes carefully`,"5. `check({})` + `test_run({})` — Verify nothing broke",n===`smart`?`6. Smart indexing is active — changes will be indexed automatically`:"6. `reindex({})` — Update AI Kit with changes",``,`What would you like to refactor?`].join(`
|
|
9
9
|
`)}}]})),e.registerPrompt(`forge_workflow`,{title:`FORGE Workflow`,description:`Full FORGE protocol: classify → ground → implement with quality gates`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## FORGE Quality Gate Workflow`,``,"1. `forge_classify({ task })` — Determine complexity tier (floor/standard/critical)","2. `forge_ground({ task, files, root_path })` — Full grounding analysis",`3. Review typed unknowns and constraints`,`4. Implement with evidence tracking`,'5. `evidence_map({ action: "validate" })` — Verify all claims',"6. `check({})` + `test_run({})` — Final verification",``,`Describe the task to classify:`].join(`
|
|
10
|
-
`)}}]})),e.registerPrompt(`investigate_workflow`,{title:`Investigate Issue`,description:`Bug investigation workflow: trace → analyze → find root cause → fix`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Bug Investigation Workflow`,``,"1. `parse_output({ output })` — Parse error messages if available","2. `symbol({ name })` — Find the failing symbol",'3. `trace({ symbol, direction: "backward" })` — Trace data flow to root cause',"4. `blast_radius({
|
|
11
|
-
`)}}]})),e.registerPrompt(`context_workflow`,{title:`Build Context`,description:`Progressive context building: file_summary →
|
|
10
|
+
`)}}]})),e.registerPrompt(`investigate_workflow`,{title:`Investigate Issue`,description:`Bug investigation workflow: trace → analyze → find root cause → fix`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Bug Investigation Workflow`,``,"1. `parse_output({ output })` — Parse error messages if available","2. `symbol({ name })` — Find the failing symbol",'3. `trace({ symbol, direction: "backward" })` — Trace data flow to root cause',"4. `blast_radius({ files })` — Assess impact of fix",`5. Implement fix`,"6. `check({})` + `test_run({})` — Verify fix works",``,`Describe the issue:`].join(`
|
|
11
|
+
`)}}]})),e.registerPrompt(`context_workflow`,{title:`Build Context`,description:`Progressive context building: file_summary(T1) → file_summary(T2+query) → digest for deep understanding`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Context Building Workflow`,``,`Build understanding progressively:`,``,"1. `file_summary({ path })` — Structure overview (~50 tokens)",'2. `file_summary({ files, tier: "T2", query })` or `file_summary({ ref })` — Extract relevant sections (5-20x reduction)',"3. `digest({ sources })` — Multi-file compressed summary","4. `stratum_card({ files })` — Reusable reference card",``,`For project-wide context:`,"- `scope_map({ task })` — Reading plan for a specific task",'- `workset({ action: "save" })` — Save working set for later',``,`What do you need to understand?`].join(`
|
|
12
12
|
`)}}]})),e.registerPrompt(`migrate_workflow`,{title:`Migration Workflow`,description:`Code migration workflow: analyze → plan → migrate → verify → document`},async()=>({messages:[{role:`user`,content:{type:`text`,text:[`## Migration Workflow`,``,'1. `analyze({ aspect: "structure", path })` — Current codebase state','2. `analyze({ aspect: "patterns", path })` — Identify patterns to migrate',"3. `dead_symbols({ path })` — Find unused code to remove",'4. `scope_map({ task: "migration" })` — Plan migration scope',"5. Use `codemod` for bulk transformations","6. `check({})` + `test_run({})` — Verify after each step","7. `changelog({ from })` — Document changes",``,`What are you migrating from/to?`].join(`
|
|
13
13
|
`)}}]}))}const Ie=j(`resource-notifier`);var Le=class{mcpServer;constructor(e){this.mcpServer=e}async notifyStatusChanged(){await this.sendUpdate(`aikit://status`)}async notifyFileTreeChanged(){await this.sendUpdate(`aikit://file-tree`)}async notifyCuratedIndexChanged(){await this.sendUpdate(`aikit://curated`)}async notifyCuratedEntryChanged(e){await this.sendUpdate(`aikit://curated/${e}`)}async notifyResourceListChanged(){try{await this.mcpServer.server.sendResourceListChanged()}catch(e){Ie.debug(`sendResourceListChanged failed`,{error:String(e)})}}async notifyL0CardChanged(){await this.sendUpdate(`aikit://l0/workspace-core`),await this.sendUpdate(`aikit://l0`)}async notifyAfterReindex(){await Promise.allSettled([this.notifyStatusChanged(),this.notifyFileTreeChanged()])}async notifyAfterCuratedWrite(e){let t=[this.notifyStatusChanged(),this.notifyCuratedIndexChanged()];e&&t.push(this.notifyCuratedEntryChanged(e)),await Promise.allSettled(t)}async sendUpdate(e){try{await this.mcpServer.server.sendResourceUpdated({uri:e})}catch(t){Ie.debug(`sendResourceUpdated failed`,{uri:e,error:String(t)})}}};const J=j(`server`);function Re(e){let t=e?.trim().toLowerCase();return t===`1`||t===`true`||t===`yes`||t===`on`}async function Y(n){J.info(`Initializing AI Kit components`);let r=n.store.backend,i=n.embedding,a=O[i.model],o={model:i.model,nativeDim:i.nativeDim??a?.nativeDim??D.nativeDim,dimensions:i.dimensions??a?.dimensions??D.dimensions,queryPrefix:i.queryPrefix??a?.queryPrefix??D.queryPrefix,pooling:i.pooling??a?.pooling??`mean`},s=n.store.path,l=Re(process.env.AIKIT_SPLIT_STATE),d=I(s,`aikit.db`),f={splitEnabled:l,contentDbPath:d,controlDbPath:l?I(s,`aikit-control.db`):d},p=null;if(r===`sqlite-vec`){let e=f.contentDbPath;P(s)||F(s,{recursive:!0}),p=await H(e),J.debug(`SQLite adapter ready`,{type:p.type,vectorCapable:p.vectorCapable,dbPath:e}),p.vectorCapable||J.warn(`┌──────────────────────────────────────────────────────────────────┐
|
|
14
14
|
│ ⚠ SQLite vector extension unavailable — DEGRADED MODE │
|
|
15
15
|
│ Vector search is disabled. Hybrid search returns FTS only. │
|
|
16
16
|
│ To enable: install/rebuild better-sqlite3 (native module). │
|
|
17
17
|
└──────────────────────────────────────────────────────────────────┘`);let t=I(s,`lance`);P(t)&&J.info(`Old LanceDB data found at ${t} — ignored. Safe to delete after verifying sqlite-vec works.`)}let m;if(p)if(f.splitEnabled&&f.controlDbPath!==f.contentDbPath){let{migrateToSplitState:e}=await import(`../../store/dist/index.js`);await e(f),m=await H(f.controlDbPath),_e(m,me),J.info(`State store adapter ready`,{type:m.type,dbPath:f.controlDbPath,splitEnabled:!0})}else m=p;else{let e=I(s,`aikit-state.db`);P(s)||F(s,{recursive:!0}),m=await H(e),_e(m,me),J.info(`State store adapter ready`,{type:m.type,dbPath:e})}let[h,g,_,ee]=await Promise.all([(async()=>{try{if(n.embedding.childProcess!==!1){let e=new be({model:o.model,dimensions:o.dimensions,nativeDim:o.nativeDim,queryPrefix:o.queryPrefix,pooling:o.pooling,interOpNumThreads:i.interOpNumThreads,intraOpNumThreads:i.intraOpNumThreads,idleTimeoutMs:i.idleTimeoutMs});return await e.initialize(),J.debug(`Embedder loaded (child process)`,{modelId:e.modelId,dimensions:e.dimensions}),e}let{OnnxEmbedder:e}=await import(`../../embeddings/dist/index.js`),t=new e({model:o.model,dimensions:o.dimensions,nativeDim:o.nativeDim,queryPrefix:o.queryPrefix,pooling:o.pooling,interOpNumThreads:i.interOpNumThreads,intraOpNumThreads:i.intraOpNumThreads});return await t.initialize(),J.debug(`Embedder loaded (in-process)`,{modelId:t.modelId,dimensions:t.dimensions}),t}catch(e){return J.warn(`Embedder initialization failed — vector search degraded to FTS-only`,{error:N(e)}),{dimensions:0,modelId:`unavailable`,initialize:async()=>{},embed:async()=>{throw Error(`Embedder unavailable`)},embedQuery:async()=>{throw Error(`Embedder unavailable`)},embedBatch:async()=>{throw Error(`Embedder unavailable`)}}}})(),(async()=>{let e=r===`sqlite-vec`?await ge({backend:r,path:s,adapter:p??void 0,embeddingDim:o.dimensions,embeddingProfile:o,partition:f}):await ge({backend:r,path:s,adapter:p??void 0,embeddingDim:o.dimensions,partition:void 0});return await e.initialize(),J.debug(`Store initialized`,{backend:r}),e})(),(async()=>{let e=p?new pe({adapter:p}):new pe({path:s});return await e.initialize(),J.debug(`Graph store initialized`,{shared:!!p}),e})(),(async()=>{let e=await ue();if(e){let e=B.get();J.debug(`WASM tree-sitter enabled`,{grammars:e.grammarCount,dir:e.wasmDir})}else{let e=B.get();J.warn(`WASM tree-sitter not available; analyzers will use regex fallback`,{reason:e.reason,os:e.os,arch:e.arch,healAttempted:e.healAttempted,healSuccess:e.healSuccess,healError:e.healError,pathsChecked:e.pathsChecked.map(e=>`${e.path} (${e.exists?`found`:`missing`})`)})}return e})()]),v=new Se(h,g),te=he(m),y=new xe(n.store.path);y.load(),v.setHashCache(y);let b=n.curated.path,x=new e(b);await x.initialize();let S=new t(b,g,h,x);v.setGraphStore(_);let C=u(n.er),w=C?new fe(n.curated.path):void 0;w&&J.debug(`Policy store initialized`,{ruleCount:w.getRules().length});let ne=C?new de:void 0,T=ae(n.sources[0]?.path??M(),re.aiContext),E=P(T),k=n.onboardDir?P(n.onboardDir):!1,A=E||k,j,L=E?T:n.onboardDir;if(A&&L)try{j=ie(L).mtime.toISOString()}catch{}return J.debug(`Onboard state detected`,{onboardComplete:A,onboardTimestamp:j,aiKbExists:E,onboardDirExists:k}),{embedder:h,store:g,stateStore:te,closeStateStore:m===p?void 0:async()=>m.close(),indexer:v,curated:S,graphStore:_,fileCache:new oe,bridge:C,policyStore:w,evolutionCollector:ne,onboardComplete:A,onboardTimestamp:j,eventBus:new c}}function ze(e,t,n){if(e.serverInstructions)return e.serverInstructions;let r=new Set;for(let e of t){let t=n[e];if(t?.category)for(let e of t.category)r.add(e)}let i=[`This server provides ${t.size} tools across ${r.size} categories: ${[...r].sort().join(`, `)}.`,`TOOL ROUTING:`,`- Understand a file -> file_summary (T1=structure, T2=content)`,`- Find code/symbols -> search (hybrid) or symbol (definition + refs)`,`- Validate changes -> check (typecheck+lint) or test_run (tests)`,`- Read file for editing -> read_file (only for exact lines before edits)`,`FORBIDDEN: DO NOT USE native equivalents when AI Kit provides same:`,`- grep/find -> search or find tool`,`- cat/read_file (for understanding) -> file_summary`,`- terminal tsc/lint -> check tool`,`- terminal test -> test_run tool`];return e.readOnly&&i.push(`Server is in read-only mode. Mutating operations are disabled.`),e.features?.length&&i.push(`Active feature groups: ${e.features.join(`, `)}.`),i.join(`
|
|
18
|
-
`)}const Be=j(`background-task`);var Ve=class{queue=[];running=null;get isRunning(){return this.running!==null}get currentTask(){return this.running}get pendingCount(){return this.queue.length}schedule(e){return new Promise((t,n)=>{this.queue.push({...e,resolve:t,reject:n}),this.running||this.processQueue()})}async processQueue(){for(;this.queue.length>0;){let e=this.queue.shift();if(!e)break;this.running=e.name,Be.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Be.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Be.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const X=j(`idle-timer`);var He=class{timer=null;cleanupFns=[];idleMs;disposed=!1;sessionActive=!1;_busy=!1;constructor(e){this.idleMs=e?.idleMs??3e5}setBusy(e){this._busy=e,e?this.cancel():this.touch()}onIdle(e){this.cleanupFns.push(e)}markSessionActive(){this.sessionActive=!0}touch(){this.disposed||this._busy||(this.cancel(),this.timer=setTimeout(()=>{this.runCleanup()},this.idleMs),this.timer.unref&&this.timer.unref())}cancel(){this.timer&&=(clearTimeout(this.timer),null)}dispose(){this.cancel(),this.cleanupFns.length=0,this.disposed=!0}async runCleanup(){if(!this.sessionActive){X.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){X.info(`Skipping idle cleanup — background work in progress`);return}X.info(`Idle for ${this.idleMs/1e3}s — running cleanup`);let e=await Promise.allSettled(this.cleanupFns.map(e=>e()));for(let t of e)t.status===`rejected`&&X.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const Z=j(`memory-monitor`);var Ue=class{timer=null;warningBytes;criticalBytes;intervalMs;pressureFns=[];memoryPressureFns=[];lastLevel=`normal`;constructor(e){this.warningBytes=e?.warningBytes??3221225472,this.criticalBytes=e?.criticalBytes??6442450944,this.intervalMs=e?.intervalMs??3e4}onPressure(e){this.pressureFns.push(e)}registerMemoryPressureCallback(e){this.memoryPressureFns.push(e)}start(){this.timer||(this.timer=setInterval(()=>this.check(),this.intervalMs),this.timer.unref&&this.timer.unref(),Z.debug(`Memory monitor started`,{warningMB:Math.round(this.warningBytes/1024/1024),criticalMB:Math.round(this.criticalBytes/1024/1024),intervalSec:Math.round(this.intervalMs/1e3)}))}stop(){this.timer&&=(clearInterval(this.timer),null)}getRssBytes(){return process.memoryUsage.rss()}check(){let e=this.getRssBytes(),t=`normal`;if(e>=this.criticalBytes?t=`critical`:e>=this.warningBytes&&(t=`warning`),t!==this.lastLevel||t===`critical`){let n=Math.round(e/1024/1024);t===`critical`?Z.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?Z.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&Z.info(`Memory returned to normal: ${n}MB RSS`),this.lastLevel=t}if(t!==`normal`)for(let n of this.pressureFns)try{n(t,e)}catch{}if(t===`critical`)for(let e of this.memoryPressureFns)try{let t=e();t&&typeof t.catch==`function`&&t.catch(()=>{})}catch{}return t===`critical`&&typeof globalThis.gc==`function`&&globalThis.gc(),t}};const We=new Ce;function Ge(e,t){return We.run(e,async()=>{try{return await t()}finally{}})}j(`tool-timeout`);const Ke=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var qe=class extends Error{toolName;timeoutMs;constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function Je(e){return Ke.has(e)?6e5:12e4}function Ye(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new qe(n,t);i.aborted||r.abort(e),o(e)},t);s.unref();try{e(i).then(a,o).finally(()=>clearTimeout(s))}catch(e){clearTimeout(s),o(e instanceof Error?e:Error(String(e)))}})}const Q=j(`server`),Xe=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function Ze(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function Qe(e){let t=[`query`,`path`,`task`,`name`,`start`,`symbol`,`file`,`pattern`],n=[];for(let r of t){let t=e[r];typeof t==`string`&&t.length>0&&t.length<200&&n.push(t)}return n.join(` `).slice(0,200)}async function $e(e,t,n,r){let i=[];if(n){let t=await et(e,n);t&&i.push(t)}try{if(t.statePath){let{ensureLegacyStashImported:n}=await import(`../../tools/dist/index.js`);n(e.stateStore,{stateDir:t.statePath})}let r=e.stateStore.stashList().map(e=>e.key);if(r.length>0){let e=n?n.toLowerCase().split(/\s+/).filter(e=>e.length>2):[];if(e.length===0)i.push(`📦 stash: ${r.length} entries`);else{let t=r.filter(t=>e.some(e=>t.toLowerCase().includes(e))).slice(0,3);t.length>0&&i.push(`📦 stash: ${t.map(e=>`"${Ze(e)}"`).join(`, `)}${r.length>t.length?` (+${r.length-t.length})`:``}`)}}}catch{}if(i.length===0&&!r)return null;if(r){let n=e,r=n.curated;if(r?.list&&n.stateStore)try{let{buildPreludeInjection:e,generatePrelude:a}=await import(`./startup-maintenance-
|
|
18
|
+
`)}const Be=j(`background-task`);var Ve=class{queue=[];running=null;get isRunning(){return this.running!==null}get currentTask(){return this.running}get pendingCount(){return this.queue.length}schedule(e){return new Promise((t,n)=>{this.queue.push({...e,resolve:t,reject:n}),this.running||this.processQueue()})}async processQueue(){for(;this.queue.length>0;){let e=this.queue.shift();if(!e)break;this.running=e.name,Be.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Be.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Be.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const X=j(`idle-timer`);var He=class{timer=null;cleanupFns=[];idleMs;disposed=!1;sessionActive=!1;_busy=!1;constructor(e){this.idleMs=e?.idleMs??3e5}setBusy(e){this._busy=e,e?this.cancel():this.touch()}onIdle(e){this.cleanupFns.push(e)}markSessionActive(){this.sessionActive=!0}touch(){this.disposed||this._busy||(this.cancel(),this.timer=setTimeout(()=>{this.runCleanup()},this.idleMs),this.timer.unref&&this.timer.unref())}cancel(){this.timer&&=(clearTimeout(this.timer),null)}dispose(){this.cancel(),this.cleanupFns.length=0,this.disposed=!0}async runCleanup(){if(!this.sessionActive){X.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){X.info(`Skipping idle cleanup — background work in progress`);return}X.info(`Idle for ${this.idleMs/1e3}s — running cleanup`);let e=await Promise.allSettled(this.cleanupFns.map(e=>e()));for(let t of e)t.status===`rejected`&&X.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const Z=j(`memory-monitor`);var Ue=class{timer=null;warningBytes;criticalBytes;intervalMs;pressureFns=[];memoryPressureFns=[];lastLevel=`normal`;constructor(e){this.warningBytes=e?.warningBytes??3221225472,this.criticalBytes=e?.criticalBytes??6442450944,this.intervalMs=e?.intervalMs??3e4}onPressure(e){this.pressureFns.push(e)}registerMemoryPressureCallback(e){this.memoryPressureFns.push(e)}start(){this.timer||(this.timer=setInterval(()=>this.check(),this.intervalMs),this.timer.unref&&this.timer.unref(),Z.debug(`Memory monitor started`,{warningMB:Math.round(this.warningBytes/1024/1024),criticalMB:Math.round(this.criticalBytes/1024/1024),intervalSec:Math.round(this.intervalMs/1e3)}))}stop(){this.timer&&=(clearInterval(this.timer),null)}getRssBytes(){return process.memoryUsage.rss()}check(){let e=this.getRssBytes(),t=`normal`;if(e>=this.criticalBytes?t=`critical`:e>=this.warningBytes&&(t=`warning`),t!==this.lastLevel||t===`critical`){let n=Math.round(e/1024/1024);t===`critical`?Z.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?Z.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&Z.info(`Memory returned to normal: ${n}MB RSS`),this.lastLevel=t}if(t!==`normal`)for(let n of this.pressureFns)try{n(t,e)}catch{}if(t===`critical`)for(let e of this.memoryPressureFns)try{let t=e();t&&typeof t.catch==`function`&&t.catch(()=>{})}catch{}return t===`critical`&&typeof globalThis.gc==`function`&&globalThis.gc(),t}};const We=new Ce;function Ge(e,t){return We.run(e,async()=>{try{return await t()}finally{}})}j(`tool-timeout`);const Ke=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var qe=class extends Error{toolName;timeoutMs;constructor(e,t){super(`Tool "${e}" timed out after ${t}ms`),this.toolName=e,this.timeoutMs=t,this.name=`ToolTimeoutError`}};function Je(e){return Ke.has(e)?6e5:12e4}function Ye(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new qe(n,t);i.aborted||r.abort(e),o(e)},t);s.unref();try{e(i).then(a,o).finally(()=>clearTimeout(s))}catch(e){clearTimeout(s),o(e instanceof Error?e:Error(String(e)))}})}const Q=j(`server`),Xe=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function Ze(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function Qe(e){let t=[`query`,`path`,`task`,`name`,`start`,`symbol`,`file`,`pattern`],n=[];for(let r of t){let t=e[r];typeof t==`string`&&t.length>0&&t.length<200&&n.push(t)}return n.join(` `).slice(0,200)}async function $e(e,t,n,r){let i=[];if(n){let t=await et(e,n);t&&i.push(t)}try{if(t.statePath){let{ensureLegacyStashImported:n}=await import(`../../tools/dist/index.js`);n(e.stateStore,{stateDir:t.statePath})}let r=e.stateStore.stashList().map(e=>e.key);if(r.length>0){let e=n?n.toLowerCase().split(/\s+/).filter(e=>e.length>2):[];if(e.length===0)i.push(`📦 stash: ${r.length} entries`);else{let t=r.filter(t=>e.some(e=>t.toLowerCase().includes(e))).slice(0,3);t.length>0&&i.push(`📦 stash: ${t.map(e=>`"${Ze(e)}"`).join(`, `)}${r.length>t.length?` (+${r.length-t.length})`:``}`)}}}catch{}if(i.length===0&&!r)return null;if(r){let n=e,r=n.curated;if(r?.list&&n.stateStore)try{let{buildPreludeInjection:e,generatePrelude:a}=await import(`./startup-maintenance-kHH8tjds.js`).then(e=>e.a),o=e(await a(r,n.stateStore,void 0,t.skillDir),500);o.lines.length>0&&i.push(o.lines.join(`
|
|
19
19
|
`))}catch(e){Q.debug?.(`Periodic prelude injection failed`,{error:String(e)})}}return i.length===0?null:`\n${i.join(`
|
|
20
|
-
`)}`}async function et(e,t){try{let
|
|
20
|
+
`)}`}async function et(e,t){try{let n=await Promise.race([e.store.ftsSearch(t,{limit:3}),new Promise(e=>{let t=setTimeout(()=>e(null),1e3);t.unref&&t.unref()})]);if(!Array.isArray(n)||n.length===0)return null;let i=[];for(let e of n){if(!e||typeof e!=`object`)continue;let t=e.record;if(!t)continue;let n=t.origin;if(n!==`curated`&&n!==`produced`)continue;let a=t.content??``;if(!(!a||a.length<20)){if(a.length<=400){let e=t.headingPath?.trim()||``,n=a.slice(0,400),r=e?`📚 ${e}: ${n}`:`📚 ${n}`;i.push(r)}else{let e=r(a,400),n=t.headingPath?.trim()||``,o=n?`📚 ${n}: ${e}`:`📚 ${e}`;i.push(o)}if(i.length>=2)break}}return i.length===0?null:i.join(`
|
|
21
21
|
`)}catch{return null}}function tt(e,t,n){let r=5,i=0;for(let[a,o]of Object.entries(e)){let e=o.handler;o.handler=async(...o)=>{let s=await e(...o);if(!s||typeof s!=`object`||r<=0||s.isError||Xe.has(a))return s;try{r--,i++;let e=o[0],a=await $e(t,n,Qe(e&&typeof e==`object`?e:{}),i%5==0);a&&(s.content=Array.isArray(s.content)?s.content:[],s.content.push({type:`text`,text:a}))}catch{}return s}}}function nt(e){let t=e.toLowerCase();return[`protobuf`,`invalid model`,`invalid onnx`,`unexpected end`,`unexpected token`,`failed to load`,`failed to initialize embedding`,`checksum`,`corrupt`,`malformed`,`could not load`,`onnx`,`database is locked`,`database disk image is malformed`,`file is not a database`,`lance`,`cannot find module`,`cannot find package`,`module not found`,`operation not permitted`,`permission denied`].some(e=>t.includes(e))}function rt(e){return v(e)?[`Auto-heal tried to repair missing runtime dependency files in the npx install.`,`If this persists, clear the broken npx cache and restart:`,` npm cache clean --force`,` npx -y @vpxa/aikit@latest serve`].join(`
|
|
22
22
|
`):[`To fix embedding errors, try deleting the cached model:`,` rm -rf ~/.cache/huggingface/transformers-js/mixedbread-ai/`,`Then restart the server to re-download a fresh copy.`].join(`
|
|
23
|
-
`)}async function it(){try{let{existsSync:e,readFileSync:t}=await import(`node:fs`),
|
|
24
|
-
`),`utf8`),Q.info(`Auto-heal: created ESM shim for @huggingface/transformers (.mjs wrapper → .cjs)`,{path:t}))}catch(e){Q.warn(`Auto-heal: failed to create ESM shim`,{error:e instanceof Error?e.message:String(e),path:t})}}}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model;if(t){let e=I(z(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(e,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared embedding model cache`,{path:e})}catch{}}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=I(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database is locked`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=I(e.store.path,`graph.db`);try{await r(t,{force:!0}),Q.info(`Auto-heal: cleared graph database`,{path:t})}catch{}let i=I(e.store.path,`aikit.db`);try{n.includes(`database is locked`)?(await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: removed stale WAL/shm files for locked database`,{path:i})):(await r(i,{force:!0}),await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: cleared corrupted aikit database`,{path:i}))}catch{}}if(n.includes(`wasm`)||n.includes(`tree-sitter`)||n.includes(`.tmp-`))try{let{readdirSync:e,existsSync:t}=await import(`node:fs`),{join:n}=await import(`node:path`),{homedir:i}=await import(`node:os`),a=n(i(),`.aikit`,`cache`,`wasm`);if(t(a)){let t=e(a).filter(e=>e.includes(`.tmp-`)||e.endsWith(`.wasm.tmp`));for(let e of t)try{await r(n(a,e),{force:!0}),Q.debug(`Auto-heal: removed stale WASM temp file`,{file:e})}catch{}}}catch{}if(v(t)){let e=await b(t);e.repaired||Q.warn(`Auto-heal: missing runtime dependency repair did not complete`,{packages:e.packages,reason:e.reason,error:e.error,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}else n.includes(`cannot find module`)&&!n.includes(`.cache`)&&Q.warn(`Auto-heal: missing module detected during initialization cleanup`,{hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}function ot(e,t){let
|
|
23
|
+
`)}async function it(){try{let{existsSync:e,readFileSync:t}=await import(`node:fs`),r=I(z(),`.aikit`,`current-version.json`);if(!e(r))return null;let i=JSON.parse(t(r,`utf-8`));if(!i.version)return null;let a=n();return i.version===a?null:i.version}catch{return null}}async function at(e,t){let n=t.toLowerCase(),r;try{({rm:r}=await import(`node:fs/promises`))}catch{return}if(n.includes(`transformers.node.mjs`)&&n.includes(`cannot find module`)){let e=t.match(/Cannot find module '([^']+transformers\.node\.mjs)'/);if(e){let t=e[1],n=t.replace(/\.mjs$/,`.cjs`);try{let{existsSync:e,writeFileSync:r}=await import(`node:fs`);e(n)&&!e(t)&&(r(t,[`// Auto-generated ESM shim — published package missing this file`,`import { createRequire } from 'node:module';`,`const require = createRequire(import.meta.url);`,`const mod = require('./transformers.node.cjs');`,`export default mod;`,``].join(`
|
|
24
|
+
`),`utf8`),Q.info(`Auto-heal: created ESM shim for @huggingface/transformers (.mjs wrapper → .cjs)`,{path:t}))}catch(e){Q.warn(`Auto-heal: failed to create ESM shim`,{error:e instanceof Error?e.message:String(e),path:t})}}}if(n.includes(`embedding`)||n.includes(`onnx`)||n.includes(`protobuf`)||n.includes(`model`)){let t=e.embedding?.model;if(t){let e=I(z(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(e,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared embedding model cache`,{path:e})}catch{}}}if(n.includes(`lance`)||n.includes(`database`)||n.includes(`store`)){let t=I(e.store.path,`lance`);try{await r(t,{recursive:!0,force:!0}),Q.info(`Auto-heal: cleared LanceDB store`,{path:t})}catch{}}if(n.includes(`sqlite`)||n.includes(`database is locked`)||n.includes(`database disk image`)||n.includes(`graph`)){let t=I(e.store.path,`graph.db`);try{await r(t,{force:!0}),Q.info(`Auto-heal: cleared graph database`,{path:t})}catch{}let i=I(e.store.path,`aikit.db`);try{n.includes(`database is locked`)?(await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: removed stale WAL/shm files for locked database`,{path:i})):(await r(i,{force:!0}),await r(`${i}-wal`,{force:!0}).catch(()=>{}),await r(`${i}-shm`,{force:!0}).catch(()=>{}),Q.info(`Auto-heal: cleared corrupted aikit database`,{path:i}))}catch{}}if(n.includes(`wasm`)||n.includes(`tree-sitter`)||n.includes(`.tmp-`))try{let{readdirSync:e,existsSync:t}=await import(`node:fs`),{join:n}=await import(`node:path`),{homedir:i}=await import(`node:os`),a=n(i(),`.aikit`,`cache`,`wasm`);if(t(a)){let t=e(a).filter(e=>e.includes(`.tmp-`)||e.endsWith(`.wasm.tmp`));for(let e of t)try{await r(n(a,e),{force:!0}),Q.debug(`Auto-heal: removed stale WASM temp file`,{file:e})}catch{}}}catch{}if(v(t)){let e=await b(t);e.repaired||Q.warn(`Auto-heal: missing runtime dependency repair did not complete`,{packages:e.packages,reason:e.reason,error:e.error,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}else n.includes(`cannot find module`)&&!n.includes(`.cache`)&&Q.warn(`Auto-heal: missing module detected during initialization cleanup`,{hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}function ot(e,t){let r=g(e,C,l,m(e)),o=ze(e,r,l),c=new le({name:e.serverName??E,version:n()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:o}),u=`initializing`,_=``,ee=!1,v=null,b=null,T=null;function re(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 D=()=>u===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,_?`Error: ${_}`:``,``,`**${w.size} tools are still available** and fully functional:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, regex_test, encode,`,`stash, checkpoint, lane, process, time, env, and more.`,``,rt(_),``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
|
|
25
25
|
`):[`AI Kit is still initializing (loading embeddings model & store).`,``,`**${w.size} tools are already available** while initialization completes — including:`,`check, eval, test_run, git_context, health, measure, web_fetch, web_search,`,`flow, 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(`
|
|
26
|
-
`);Ee(c);let O=new p;O.use(d(),{order:1,name:`structured-content-guard`}),S(c,O,e.toolPrefix??``);let k=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let A=[];for(let e of C){if(!n.has(e))continue;let t=s(e),r=c.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:D()}]}));w.has(e)?r.remove():A.push(r)}h(c,e,n),c.sendToolListChanged=k;let j=c.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`}]})),M=c.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:G(V.string(),()=>[])}},async()=>({messages:[]})),P,F,ie=new Promise((e,t)=>{P=e,F=t}),I,ae=new Promise(e=>{I=e}),oe=()=>I?.(),L=(async()=>{await ae;try{let{createRequire:e}=await import(`node:module`),{readFileSync:t,existsSync:n}=await import(`node:fs`),{fileURLToPath:r}=await import(`node:url`),{resolve:i,dirname:a}=await import(`node:path`),o=e(import.meta.url),s=a(r(import.meta.url)),c=i(s,`..`,`package.json`),l=i(s,`..`,`..`),u=JSON.parse(t(c,`utf8`)),d=Object.keys(u.dependencies??{}),f=[`@mixmark-io/domino`],p=[...d,...f.filter(e=>!d.includes(e))],m=p.filter(e=>!e.startsWith(`@aikit/`)),h=p.filter(e=>e.startsWith(`@aikit/`)),g=[];for(let e of m)try{o.resolve(e)}catch{try{o.resolve(`${e}/package.json`)}catch{g.push(e)}}g.length>0&&Q.warn(`Dependencies not resolvable — server may operate in degraded mode`,{missing:g,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`});let _=[];if(h.length>0){for(let e of h)n(i(l,e.slice(7),`dist`))||_.push(e);_.length>0&&Q.warn(`Workspace sibling packages missing dist — server may have degraded features`,{missing:_,hint:`Reinstall: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}}catch{}let n;try{n=await Y(e)}catch(t){let r=t instanceof Error?t.message:String(t);if(nt(r)){let t=await it();if(t){u=`failed`,_=`Server v${a()} superseded by installed v${t}. Restart the MCP server to use the new version.`,Q.info(_),F?.(Error(_));return}Q.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:r}),await at(e,r);try{n=await Y(e),Q.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){u=`failed`,_=e instanceof Error?e.message:String(e),Q.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:_,originalError:r}),F?.(e instanceof Error?e:Error(_));return}}else{u=`failed`,_=r,Q.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:_}),F?.(t instanceof Error?t:Error(_));return}}i();let o=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let s=c.sendPromptListChanged.bind(c);c.sendPromptListChanged=()=>{};let l=c.sendResourceListChanged.bind(c);c.sendResourceListChanged=()=>{};for(let e of A)e.remove();j.remove(),M.remove();let d=c._registeredTools??{};for(let e of w)d[e]?.remove();let p=new Le(c),m=r(c);y({server:c,aikit:n,config:e,elicitor:we(c),resourceNotifier:p,samplingClient:m,indexMode:t,getSmartState:t===`smart`?(()=>{let e=T;return e?.getState?e.getState():null}):null,getSmartScheduler:t===`smart`?()=>{let e=T;return e?{prioritize:e.prioritize.bind(e)}:null}:null}),Fe(c,{curated:n.curated,store:n.store,graphStore:n.graphStore,stateStore:n.stateStore},t),c.sendToolListChanged=o,c.sendPromptListChanged=s,c.sendResourceListChanged=l,Promise.resolve(c.sendToolListChanged()).catch(()=>{}),Promise.resolve(c.sendPromptListChanged()).catch(()=>{}),Promise.resolve(c.sendResourceListChanged()).catch(()=>{});let h=c._registeredTools??{};for(let[e,t]of Object.entries(h)){if(ne.has(e))continue;let r=t.handler;t.handler=async(...i)=>{if(!n.indexer.isIndexing)return r(...i);let a=ee?`re-indexing`:`running initial index`,o=new Promise(n=>setTimeout(()=>n({content:[{type:`text`,text:`⏳ AI Kit is ${a}. The tool "${e}" timed out waiting for index data (${te/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}}),te));return Promise.race([r(...i),o])}}for(let[e,t]of Object.entries(h)){let n=t.handler,r=Je(e);t.handler=async(...i)=>{try{return await Ye(e=>Ge(e,()=>n(...i)),r,e)}catch(n){if(n instanceof qe)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.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}};throw n}}}let g=Object.keys(h).length;g<C.length&&Q.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:C.length,registeredToolCount:g}),Q.debug(`MCP server configured`,{toolCount:C.length,resourceCount:4});let x=new Ue;x.onPressure((e,t)=>{e===`warning`&&Oe(),e===`critical`&&(Q.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),Oe())}),x.registerMemoryPressureCallback(()=>n.embedder.shutdown?.()),x.start();let S=new He;b=S,S.onIdle(async()=>{if(R.isRunning||n.indexer.isIndexing){Q.info(`Idle cleanup deferred — background tasks still running`),S.touch();return}Q.info(`Idle cleanup: releasing cached memory (connections stay open)`);try{n.store.releaseMemory?.(),n.graphStore.releaseMemory?.()}catch{}}),S.touch();let E=!1;for(let e of Object.values(h)){let t=e.handler;e.handler=async(...e)=>{if(E||(E=!0,S.markSessionActive()),S.touch(),T){let t=re(e[0]);t.length>0&&T.prioritize(...t)}return t(...e)}}tt(h,n,{statePath:e.stateDir??``,skillDir:e.skillDir});for(let[,e]of Object.entries(h)){let t=e.config?.outputSchema;if(!t)continue;let n=e.handler;e.handler=async(...e)=>{let r=await n(...e);if(!r||typeof r!=`object`)return r;let i=r;return!(`content`in i)||i.isError||i.structuredContent!=null&&typeof i.structuredContent==`object`?r:(i.structuredContent=f(t),i.structuredContent??={},r)}}process.stdin.on(`end`,()=>(Q.info(`stdin closed — MCP client disconnected. Shutting down.`),process.exit(0))),process.stdin.on(`error`,()=>(Q.info(`stdin error — MCP client disconnected. Shutting down.`),process.exit(0))),v=n,P?.(n)})(),se=async()=>{let t;try{t=await ie}catch{Q.warn(`Skipping initial index — AI Kit initialization failed`);return}b?.setBusy(!0);try{let n=e.sources.map(e=>e.path).join(`, `);Q.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&&Q.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Q.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});ee=!0,Q.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Q.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();Q.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Q.error(`Curated re-index failed`,N(e))}}catch(e){Q.error(`Initial index failed; will retry on aikit_reindex`,N(e))}finally{b?.setBusy(!1)}},R=new Ve,ce=()=>R.schedule({name:`initial-index`,fn:se}),z=process.ppid,B=setInterval(()=>{try{process.kill(z,0)}catch{Q.info(`Parent process died; shutting down`,{parentPid:z}),clearInterval(B),x(),T?.stop&&T.stop(),import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),ie.then(async e=>{await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.closeStateStore?.().catch(()=>{})??Promise.resolve(),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return B.unref(),{server:c,startInit:oe,ready:L,runInitialIndex:ce,get aikit(){return v},scheduler:R,setSmartScheduler(e){T=e}}}const $=j(`server`);function st(e,t){let n=g(t,[...C,..._],l,m(t)),i=ze(t,n,l),s=new le({name:t.serverName??E,version:a()},{capabilities:{logging:{},completions:{},prompts:{},extensions:{roots:{}}},instructions:i}),c=s;c.setNotificationHandler(ve,async()=>{try{let{roots:e}=await c.listRoots();if(e&&e.length>0){let n=T(e[0].uri);process.env.AIKIT_TRANSPORT===`http`?(t.sources[0]={path:n,excludePatterns:t.sources[0]?.excludePatterns??[]},t.allRoots=e.map(e=>T(e.uri)),$.info(`Workspace root updated (HTTP mode)`,{rootPath:n,sourceCount:t.sources.length})):(o(t,n),$.info(`Workspace root updated (stdio mode)`,{rootPath:n}))}}catch(e){$.debug(`MCP roots/list not available`,{error:N(e)})}}),Ee(s),y({server:s,aikit:e,config:t,elicitor:we(s),resourceNotifier:new Le(s),samplingClient:r(s),precomputedActiveTools:n});let u=t.sources[0]?.path??M();return e.eventBus?.emit({type:`session:start`,serverVersion:a(),workspaceRoot:u,timestamp:Date.now(),eventId:`sess-start-${Date.now()}`,workspaceId:A(u),source:`server`}),Fe(s,{curated:e.curated,store:e.store,graphStore:e.graphStore,stateStore:e.stateStore},t.indexMode),s}async function ct(e){let t=await Y(e),n=st(t,e);$.debug(`MCP server configured`,{toolCount:C.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);$.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&&$.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&$.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});$.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){$.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();$.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){$.error(`Curated re-index failed`,N(e))}}catch(e){$.error(`Initial index failed; will retry on aikit_reindex`,N(e))}},i=async()=>{$.info(`Shutting down`);try{await ee(),$.info(`Auto-knowledge flushed on shutdown`)}catch(e){$.warn(`Auto-knowledge flush failed on shutdown`,{error:String(e)})}try{t.stateStore&&await se(t.stateStore,`session-end`,{reason:`server-shutdown`,timestamp:Date.now()},{notes:`Server shutdown checkpoint`})}catch(e){$.warn(`Session-end checkpoint save failed`,{error:String(e)})}x(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await Promise.all([t.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),t.graphStore.close().catch(()=>{}),t.closeStateStore?.().catch(()=>{})??Promise.resolve(),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{$.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{C as ALL_TOOL_NAMES,ot as createLazyServer,st as createMcpServer,ct as createServer,Y as initializeAikit,y as registerMcpTools};
|
|
26
|
+
`);Ee(c);let O=new p;O.use(d(),{order:1,name:`structured-content-guard`}),S(c,O,e.toolPrefix??``);let k=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let A=[];for(let e of C){if(!r.has(e))continue;let t=s(e),n=c.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:D()}]}));w.has(e)?n.remove():A.push(n)}h(c,e,r),c.sendToolListChanged=k;let j=c.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`}]})),M=c.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:G(V.string(),()=>[])}},async()=>({messages:[]})),P,F,ie=new Promise((e,t)=>{P=e,F=t}),I,ae=new Promise(e=>{I=e}),oe=()=>I?.(),L=(async()=>{await ae;try{let{createRequire:e}=await import(`node:module`),{readFileSync:t,existsSync:n}=await import(`node:fs`),{fileURLToPath:r}=await import(`node:url`),{resolve:i,dirname:a}=await import(`node:path`),o=e(import.meta.url),s=a(r(import.meta.url)),c=i(s,`..`,`package.json`),l=i(s,`..`,`..`),u=JSON.parse(t(c,`utf8`)),d=Object.keys(u.dependencies??{}),f=[`@mixmark-io/domino`],p=[...d,...f.filter(e=>!d.includes(e))],m=p.filter(e=>!e.startsWith(`@aikit/`)),h=p.filter(e=>e.startsWith(`@aikit/`)),g=[];for(let e of m)try{o.resolve(e)}catch{try{o.resolve(`${e}/package.json`)}catch{g.push(e)}}g.length>0&&Q.warn(`Dependencies not resolvable — server may operate in degraded mode`,{missing:g,hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`});let _=[];if(h.length>0){for(let e of h)n(i(l,e.slice(7),`dist`))||_.push(e);_.length>0&&Q.warn(`Workspace sibling packages missing dist — server may have degraded features`,{missing:_,hint:`Reinstall: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}}catch{}let r;try{r=await Y(e)}catch(t){let i=t instanceof Error?t.message:String(t);if(nt(i)){let t=await it();if(t){u=`failed`,_=`Server v${n()} superseded by installed v${t}. Restart the MCP server to use the new version.`,Q.info(_),F?.(Error(_));return}Q.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:i}),await at(e,i);try{r=await Y(e),Q.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){u=`failed`,_=e instanceof Error?e.message:String(e),Q.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:_,originalError:i}),F?.(e instanceof Error?e:Error(_));return}}else{u=`failed`,_=i,Q.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:_}),F?.(t instanceof Error?t:Error(_));return}}a();let o=c.sendToolListChanged.bind(c);c.sendToolListChanged=()=>{};let s=c.sendPromptListChanged.bind(c);c.sendPromptListChanged=()=>{};let l=c.sendResourceListChanged.bind(c);c.sendResourceListChanged=()=>{};for(let e of A)e.remove();j.remove(),M.remove();let d=c._registeredTools??{};for(let e of w)d[e]?.remove();let p=new Le(c),m=i(c);y({server:c,aikit:r,config:e,elicitor:we(c),resourceNotifier:p,samplingClient:m,indexMode:t,getSmartState:t===`smart`?(()=>{let e=T;return e?.getState?e.getState():null}):null,getSmartScheduler:t===`smart`?()=>{let e=T;return e?{prioritize:e.prioritize.bind(e)}:null}:null}),Fe(c,{curated:r.curated,store:r.store,graphStore:r.graphStore,stateStore:r.stateStore},t),c.sendToolListChanged=o,c.sendPromptListChanged=s,c.sendResourceListChanged=l,Promise.resolve(c.sendToolListChanged()).catch(()=>{}),Promise.resolve(c.sendPromptListChanged()).catch(()=>{}),Promise.resolve(c.sendResourceListChanged()).catch(()=>{});let h=c._registeredTools??{};for(let[e,t]of Object.entries(h)){if(ne.has(e))continue;let n=t.handler;t.handler=async(...i)=>{if(!r.indexer.isIndexing)return n(...i);let a=ee?`re-indexing`:`running initial index`,o=new Promise(n=>setTimeout(()=>n({content:[{type:`text`,text:`⏳ AI Kit is ${a}. The tool "${e}" timed out waiting for index data (${te/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}}),te));return Promise.race([n(...i),o])}}for(let[e,t]of Object.entries(h)){let n=t.handler,r=Je(e);t.handler=async(...i)=>{try{return await Ye(e=>Ge(e,()=>n(...i)),r,e)}catch(n){if(n instanceof qe)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.`}],...t.config?.outputSchema?{structuredContent:f(t.config.outputSchema)}:{}};throw n}}}let g=Object.keys(h).length;g<C.length&&Q.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:C.length,registeredToolCount:g}),Q.debug(`MCP server configured`,{toolCount:C.length,resourceCount:4});let x=new Ue;x.onPressure((e,t)=>{e===`warning`&&Oe(),e===`critical`&&(Q.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),Oe())}),x.registerMemoryPressureCallback(()=>r.embedder.shutdown?.()),x.start();let S=new He;b=S,S.onIdle(async()=>{if(R.isRunning||r.indexer.isIndexing){Q.info(`Idle cleanup deferred — background tasks still running`),S.touch();return}Q.info(`Idle cleanup: releasing cached memory (connections stay open)`);try{r.store.releaseMemory?.(),r.graphStore.releaseMemory?.()}catch{}}),S.touch();let E=!1;for(let e of Object.values(h)){let t=e.handler;e.handler=async(...e)=>{if(E||(E=!0,S.markSessionActive()),S.touch(),T){let t=re(e[0]);t.length>0&&T.prioritize(...t)}return t(...e)}}tt(h,r,{statePath:e.stateDir??``,skillDir:e.skillDir});for(let[,e]of Object.entries(h)){let t=e.config?.outputSchema;if(!t)continue;let n=e.handler;e.handler=async(...e)=>{let r=await n(...e);if(!r||typeof r!=`object`)return r;let i=r;return!(`content`in i)||i.isError||i.structuredContent!=null&&typeof i.structuredContent==`object`?r:(i.structuredContent=f(t),i.structuredContent??={},r)}}process.stdin.on(`end`,()=>(Q.info(`stdin closed — MCP client disconnected. Shutting down.`),process.exit(0))),process.stdin.on(`error`,()=>(Q.info(`stdin error — MCP client disconnected. Shutting down.`),process.exit(0))),v=r,P?.(r)})(),se=async()=>{let t;try{t=await ie}catch{Q.warn(`Skipping initial index — AI Kit initialization failed`);return}b?.setBusy(!0);try{let n=e.sources.map(e=>e.path).join(`, `);Q.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&&Q.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&Q.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});ee=!0,Q.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){Q.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();Q.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){Q.error(`Curated re-index failed`,N(e))}}catch(e){Q.error(`Initial index failed; will retry on aikit_reindex`,N(e))}finally{b?.setBusy(!1)}},R=new Ve,ce=()=>R.schedule({name:`initial-index`,fn:se}),z=process.ppid,B=setInterval(()=>{try{process.kill(z,0)}catch{Q.info(`Parent process died; shutting down`,{parentPid:z}),clearInterval(B),x(),T?.stop&&T.stop(),import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),ie.then(async e=>{await Promise.all([e.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),e.graphStore.close().catch(()=>{}),e.closeStateStore?.().catch(()=>{})??Promise.resolve(),e.store.close().catch(()=>{})])}).catch(()=>{}).finally(()=>process.exit(0))}},5e3);return B.unref(),{server:c,startInit:oe,ready:L,runInitialIndex:ce,get aikit(){return v},scheduler:R,setSmartScheduler(e){T=e}}}const $=j(`server`);function st(e,t){let r=g(t,[...C,..._],l,m(t)),a=ze(t,r,l),s=new le({name:t.serverName??E,version:n()},{capabilities:{logging:{},completions:{},prompts:{},extensions:{roots:{}}},instructions:a}),c=s;c.setNotificationHandler(ve,async()=>{try{let{roots:e}=await c.listRoots();if(e&&e.length>0){let n=T(e[0].uri);process.env.AIKIT_TRANSPORT===`http`?(t.sources[0]={path:n,excludePatterns:t.sources[0]?.excludePatterns??[]},t.allRoots=e.map(e=>T(e.uri)),$.info(`Workspace root updated (HTTP mode)`,{rootPath:n,sourceCount:t.sources.length})):(o(t,n),$.info(`Workspace root updated (stdio mode)`,{rootPath:n}))}}catch(e){$.debug(`MCP roots/list not available`,{error:N(e)})}}),Ee(s),y({server:s,aikit:e,config:t,elicitor:we(s),resourceNotifier:new Le(s),samplingClient:i(s),precomputedActiveTools:r});let u=t.sources[0]?.path??M();return e.eventBus?.emit({type:`session:start`,serverVersion:n(),workspaceRoot:u,timestamp:Date.now(),eventId:`sess-start-${Date.now()}`,workspaceId:A(u),source:`server`}),Fe(s,{curated:e.curated,store:e.store,graphStore:e.graphStore,stateStore:e.stateStore},t.indexMode),s}async function ct(e){let t=await Y(e),n=st(t,e);$.debug(`MCP server configured`,{toolCount:C.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);$.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&&$.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&$.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});$.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){$.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();$.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){$.error(`Curated re-index failed`,N(e))}}catch(e){$.error(`Initial index failed; will retry on aikit_reindex`,N(e))}},i=async()=>{$.info(`Shutting down`);try{await ee(),$.info(`Auto-knowledge flushed on shutdown`)}catch(e){$.warn(`Auto-knowledge flush failed on shutdown`,{error:String(e)})}try{t.stateStore&&await se(t.stateStore,`session-end`,{reason:`server-shutdown`,timestamp:Date.now()},{notes:`Server shutdown checkpoint`})}catch(e){$.warn(`Session-end checkpoint save failed`,{error:String(e)})}x(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await Promise.all([t.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),t.graphStore.close().catch(()=>{}),t.closeStateStore?.().catch(()=>{})??Promise.resolve(),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{$.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{C as ALL_TOOL_NAMES,ot as createLazyServer,st as createMcpServer,ct as createServer,Y as initializeAikit,y as registerMcpTools};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./startup-maintenance-BnTozHs1.js";import{a as n,i as r,o as i,s as a}from"./bin.js";import{t as o}from"./register-tools-jgdif5r4.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!f(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-Bz8Uyzuq.js`),import(`./dashboard-static-gAOiHHqI.js`),import(`./settings-static-PjpMR9Q7.js`),import(`./routes-Ct7q5jrL.js`),import(`./auth-bEP-6uqy.js`)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=i(`AIKIT_HTTP_MAX_SESSIONS`,8),M=i(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=i(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=a({requestOrigin:r,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(i.warn&&!F&&(F=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let I=w();E.use(C(I)),E.use(`/mcp`,(e,t,r)=>{let i=n(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.getRetryAfterMs(i)/1e3));t.setHeader(`Retry-After`,String(a)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,t)=>{if(!z||!H||!U){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[e.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(t=>{let n=setTimeout(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=n(e);if(!G){if(r){t.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,t,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{i()}},X=async(e,t)=>{let r=n(e);if(W&&(!G||r!==K)){await W.handleRequest(e,t,e.body);return}await Y(e,t)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:n,createMcpServer:r,ALL_TOOL_NAMES:i},{StreamableHTTPServerTransport:a},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-C43D7SrT.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-BnTozHs1.js`).then(e=>e.l)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=n(T,d);q=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},H=f.server,U=a,z=!0,v.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:i.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-BnTozHs1.js`).then(e=>e.b),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return r(f.aikit,T)},createTransport:e=>new a(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(t){v.error(`Initial index failed; will retry on aikit_reindex`,e(s,t))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(t){v.error(`Failed to start smart index scheduler`,e(s,t))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(t=>{v.error(`AI Kit initialization failed`,e(s,t)),z=!1,u=!0,H=null,U=null,q=null}),t(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(t){v.error(`Failed to load server modules`,e(s,t)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y as startHttpMode};
|
|
2
|
+
import{n as e,t}from"./startup-maintenance-cbRSFMY5.js";import{a as n,i as r,o as i,s as a}from"./bin.js";import{t as o}from"./register-tools-C49Lkpvq.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!f(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-DX1KYSbN.js`),import(`./dashboard-static-DdsIJd-u.js`),import(`./settings-static-DVMG47Oh.js`),import(`./routes-Ct7q5jrL.js`),import(`./auth-bEP-6uqy.js`)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=i(`AIKIT_HTTP_MAX_SESSIONS`,8),M=i(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=i(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((e,t,n)=>{let r=Array.isArray(e.headers.origin)?e.headers.origin[0]:e.headers.origin,i=a({requestOrigin:r,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(i.warn&&!F&&(F=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:r,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),r&&!i.allowOrigin){t.status(403).json({error:`Origin not allowed`});return}if(i.allowOrigin&&t.setHeader(`Access-Control-Allow-Origin`,i.allowOrigin),t.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),t.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),t.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),e.method===`OPTIONS`){t.status(204).end();return}n()});let I=w();E.use(C(I)),E.use(`/mcp`,(e,t,r)=>{let i=n(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.getRetryAfterMs(i)/1e3));t.setHeader(`Retry-After`,String(a)),t.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,t)=>{if(!z||!H||!U){t.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[e.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(t=>{let n=setTimeout(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=n(e);if(!G){if(r){t.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,t,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(e)),!t.headersSent){let n=e instanceof Error?e.message:String(e),r=n.includes(`Not Acceptable`);t.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?n:`Internal server error`},id:null})}}finally{i()}},X=async(e,t)=>{let r=n(e);if(W&&(!G||r!==K)){await W.handleRequest(e,t,e.body);return}await Y(e,t)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:n,createMcpServer:r,ALL_TOOL_NAMES:i},{StreamableHTTPServerTransport:a},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-CTUxU4KX.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-cbRSFMY5.js`).then(e=>e.u)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=n(T,d);q=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},H=f.server,U=a,z=!0,v.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:i.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-cbRSFMY5.js`).then(e=>e.x),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return r(f.aikit,T)},createTransport:e=>new a(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(t){v.error(`Initial index failed; will retry on aikit_reindex`,e(s,t))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(t){v.error(`Failed to start smart index scheduler`,e(s,t))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(t=>{v.error(`AI Kit initialization failed`,e(s,t)),z=!1,u=!0,H=null,U=null,q=null}),t(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(t){v.error(`Failed to load server modules`,e(s,t)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y as startHttpMode};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,n as t,r as n,t as r}from"./server-utils-De-aZNQa.js";import{n as i,t as a}from"./startup-maintenance-B4xWqEjc.js";import{t as o}from"./register-tools-Dgu64Px5.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!f(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-DZskEKrY.js`),import(`./dashboard-static-NghHzTNh.js`),import(`./settings-static-DcTUiqr7.js`),import(`./routes-DsSm9ea0.js`),import(`./auth-7LFAZQBu.js`).then(e=>e.t)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=n(`AIKIT_HTTP_MAX_SESSIONS`,8),M=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((t,n,r)=>{let i=Array.isArray(t.headers.origin)?t.headers.origin[0]:t.headers.origin,a=e({requestOrigin:i,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(a.warn&&!F&&(F=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:i,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),i&&!a.allowOrigin){n.status(403).json({error:`Origin not allowed`});return}if(a.allowOrigin&&n.setHeader(`Access-Control-Allow-Origin`,a.allowOrigin),n.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),n.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),n.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),t.method===`OPTIONS`){n.status(204).end();return}r()});let I=w();E.use(C(I)),E.use(`/mcp`,(e,n,r)=>{let i=t(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.getRetryAfterMs(i)/1e3));n.setHeader(`Retry-After`,String(a)),n.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,n)=>{if(!z||!H||!U){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[e.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(t=>{let n=setTimeout(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=t(e);if(!G){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},X=async(e,n)=>{let r=t(e);if(W&&(!G||r!==K)){await W.handleRequest(e,n,e.body);return}await Y(e,n)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-BmVdf84Q.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-B4xWqEjc.js`).then(e=>e.l)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=e(T,d);q=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},H=f.server,U=r,z=!0,v.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-B4xWqEjc.js`).then(e=>e.b),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,T)},createTransport:e=>new r(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(e){v.error(`Initial index failed; will retry on aikit_reindex`,i(s,e))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,i(s,e))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{v.error(`AI Kit initialization failed`,i(s,e)),z=!1,u=!0,H=null,U=null,q=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(e){v.error(`Failed to load server modules`,i(s,e)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y as startHttpMode};
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./server-utils-De-aZNQa.js";import{n as i,t as a}from"./startup-maintenance-kHH8tjds.js";import{t as o}from"./register-tools-i_1kjBhi.js";import{createLogger as s,serializeError as c,setDetailedErrorLoggingEnabled as l}from"../../core/dist/index.js";import{randomUUID as u}from"node:crypto";const d=`__pending__:`;function f(e){return e.startsWith(d)}function p(e){let t=e.headers[`mcp-session-id`];return Array.isArray(t)?t[0]:t}function m(e,t,n,r){e.status(t).json({jsonrpc:`2.0`,error:{code:n,message:r},id:null})}var h=class{options;runtimes=new Map;maxSessions;sessionTimeoutMs;now;constructor(e){this.options=e,this.maxSessions=e.maxSessions??8,this.sessionTimeoutMs=(e.sessionTimeoutMinutes??30)*60*1e3,this.now=e.now??(()=>Date.now())}hasSession(e){return this.runtimes.has(e)}getSessionCount(){return this.runtimes.size}async handleRequest(e,t,n=e.body){let r=p(e),i=r?this.runtimes.get(r):void 0;if(r&&!i){m(t,404,-32001,`Session not found`);return}if(!i){if(e.method!==`POST`){m(t,400,-32e3,`Session required`);return}if(i=await this.createRuntime(t),!i)return}await this.withRuntimeLock(i,async()=>{await i.transport.handleRequest(e,t,n),i.lastAccessAt=this.now();let r=i.transport.sessionId??i.id;e.method!==`DELETE`&&!f(r)&&this.options.onSessionActivity?.(r),e.method===`DELETE`&&!f(r)&&await this.closeSession(r,{closeTransport:!1})})}async closeExpiredSessions(){let e=[...this.runtimes.values()].filter(e=>this.now()-e.lastAccessAt>=this.sessionTimeoutMs).map(e=>e.id);for(let t of e)await this.closeSession(t);return e.length}async closeSession(e,t={}){let n=this.runtimes.get(e);return n?(this.runtimes.delete(e),t.notifySessionEnd!==!1&&!f(e)&&this.options.onSessionEnd?.(e),t.closeTransport!==!1&&await n.transport.close().catch(()=>void 0),await n.server.close().catch(()=>void 0),!0):!1}async closeAll(){let e=[...this.runtimes.keys()];for(let t of e)await this.closeSession(t)}async createRuntime(e){if(await this.closeExpiredSessions(),this.runtimes.size>=this.maxSessions){m(e,503,-32003,`Session capacity reached`);return}let t=this.now(),n=await this.options.createServer(),r={id:`${d}${u()}`,transport:void 0,createdAt:t,lastAccessAt:t,server:n,requestChain:Promise.resolve()},i=this.options.createTransport({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{this.runtimes.delete(r.id),r.id=e,this.runtimes.set(e,r),this.options.onSessionStart?.(e)},onsessionclosed:async e=>{e&&await this.closeSession(e,{closeTransport:!1})}});return r.transport=i,i.onclose=()=>{let e=r.transport.sessionId??r.id;this.closeSession(e,{closeTransport:!1})},this.runtimes.set(r.id,r),await n.connect(i),r}async withRuntimeLock(e,t){let n=e.requestChain,r;e.requestChain=new Promise(e=>{r=e}),await n;try{await t()}finally{r()}}};function g(e){let t=e.includes(`T`)?e:`${e.replace(` `,`T`)}Z`;return Date.parse(t)}var _=class{stateStore;options;gcTimer=null;constructor(e,t={}){this.stateStore=e,this.options=t}onSessionStart(e,t){this.stateStore.sessionCreate(e,t)}onSessionActivity(e){this.stateStore.sessionTouch(e)}onSessionEnd(e){this.stateStore.sessionDelete(e),Promise.resolve(this.options.onSessionEndMaintenance?.(e)).catch(()=>{})}startGC(){if(this.gcTimer)return;let e=(this.options.gcIntervalMinutes??5)*60*1e3;this.gcTimer=setInterval(()=>{this.runGC()},e),this.gcTimer.unref()}runGC(){let e=this.getStaleSessionIds();for(let t of e)this.options.onBeforeSessionDelete?.(t),Promise.resolve(this.options.onSessionEndMaintenance?.(t)).catch(()=>{}),this.stateStore.sessionDelete(t);return e.length}stop(){this.gcTimer&&=(clearInterval(this.gcTimer),null)}getActiveSessions(){return this.stateStore.sessionList().length}listSessions(){return this.stateStore.sessionList()}getStaleSessionIds(e=Date.now()){let t=(this.options.staleTimeoutMinutes??30)*60*1e3;return this.stateStore.sessionList().filter(n=>{let r=g(n.lastActivity);return Number.isFinite(r)&&e-r>=t}).map(e=>e.sessionId)}};const v=s(`server`);async function y(s,d){let[{default:f},{loadConfig:p,resolveIndexMode:m},{registerDashboardRoutes:g,resolveDashboardDir:y},{registerSettingsRoutes:b,resolveSettingsDir:x},{createSettingsRouter:S},{authMiddleware:C,getOrCreateToken:w}]=await Promise.all([import(`express`),import(`./config-CQKoGfwD.js`),import(`./dashboard-static-C6RP0VA7.js`),import(`./settings-static-C0oT3Ctk.js`),import(`./routes-DsSm9ea0.js`),import(`./auth-7LFAZQBu.js`).then(e=>e.t)]),T=p();l(T.logging?.errorDetails===!0),T.configError&&v.warn(`Config load failure`,{error:T.configError}),v.info(`Config loaded`,{sourceCount:T.sources.length,storePath:T.store.path});let E=f();E.use(f.json({limit:`1mb`}));let D=Number(d),O=`http://localhost:${D}`,k=process.env.AIKIT_CORS_ORIGIN??O,A=process.env.AIKIT_ALLOW_ANY_ORIGIN===`true`,j=n(`AIKIT_HTTP_MAX_SESSIONS`,8),M=n(`AIKIT_HTTP_SESSION_TIMEOUT_MINUTES`,30),N=n(`AIKIT_HTTP_SESSION_GC_INTERVAL_MINUTES`,5),P=r({limit:100,windowMs:6e4}),F=!1;E.use((t,n,r)=>{let i=Array.isArray(t.headers.origin)?t.headers.origin[0]:t.headers.origin,a=e({requestOrigin:i,configuredOrigin:k,allowAnyOrigin:A,fallbackOrigin:O});if(a.warn&&!F&&(F=!0,v.warn(`Rejected non-local CORS origin while AIKIT_CORS_ORIGIN=*`,{origin:i,allowAnyOriginEnv:`AIKIT_ALLOW_ANY_ORIGIN=true`})),i&&!a.allowOrigin){n.status(403).json({error:`Origin not allowed`});return}if(a.allowOrigin&&n.setHeader(`Access-Control-Allow-Origin`,a.allowOrigin),n.setHeader(`Access-Control-Allow-Methods`,`GET, POST, PUT, PATCH, DELETE, OPTIONS`),n.setHeader(`Access-Control-Allow-Headers`,`Content-Type, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID`),n.setHeader(`Access-Control-Expose-Headers`,`Mcp-Session-Id`),t.method===`OPTIONS`){n.status(204).end();return}r()});let I=w();E.use(C(I)),E.use(`/mcp`,(e,n,r)=>{let i=t(e)??e.ip??e.socket.remoteAddress??`anonymous`;if(P.allow(i)){r();return}let a=Math.max(1,Math.ceil(P.getRetryAfterMs(i)/1e3));n.setHeader(`Retry-After`,String(a)),n.status(429).json({jsonrpc:`2.0`,error:{code:-32003,message:`Rate limit exceeded`},id:null})});let L;E.use(`/mcp`,(e,t,n)=>{if(!L){let t=e.headers[`x-workspace-root`];typeof t==`string`&&t.length>0&&(L=t,v.debug(`Captured workspace root from proxy header`,{wsRoot:t}))}n()}),g(E,y(),v);let R=new Date().toISOString();E.use(`/settings/api`,S({log:v,mcpInfo:()=>({transport:`http`,port:D,pid:process.pid,startedAt:R})})),b(E,x(),v),E.get(`/health`,(e,t)=>{t.json({status:`ok`})});let z=!1,B=null,V=null,H=null,U=null,W=null,G=null,K=null,q=null,J=Promise.resolve(),Y=async(e,n)=>{if(!z||!H||!U){n.status(503).json({jsonrpc:`2.0`,error:{code:-32603,message:`Server initializing — please retry in a few seconds`},id:null});return}let r=J,i;J=new Promise(e=>{i=e});let a={POST:6e4,GET:1e4,DELETE:1e4}[e.method]??3e4;if(!await Promise.race([r.then(()=>!0),new Promise(t=>{let n=setTimeout(()=>{v.warn(`mcpLock timed out waiting for previous request, resetting lock chain`,{method:e.method,timeoutMs:a}),t(!1)},a);n.unref&&n.unref()})])&&(J=Promise.resolve(),i=()=>{},G)){let e=G;G=null,K=null,e.close().catch(()=>{})}try{let r=t(e);if(!G){if(r){n.status(404).json({jsonrpc:`2.0`,error:{code:-32001,message:`Session not found`},id:null});return}let e=new U({sessionIdGenerator:()=>u(),onsessioninitialized:async e=>{K=e,V?.onSessionStart(e,{transport:`http`})},onsessionclosed:async e=>{e&&V?.onSessionEnd(e),K=null}});e.onclose=()=>{G===e&&(G=null),K===e.sessionId&&(K=null)},G=e,await H.connect(e)}let i=G;await i.handleRequest(e,n,e.body),e.method!==`DELETE`&&(!r&&i.sessionId?(K=i.sessionId,V?.onSessionStart(i.sessionId,{transport:`http`}),V?.onSessionActivity(i.sessionId)):r&&V?.onSessionActivity(r))}catch(e){if(v.error(`MCP handler error`,c(e)),!n.headersSent){let t=e instanceof Error?e.message:String(e),r=t.includes(`Not Acceptable`);n.status(r?406:500).json({jsonrpc:`2.0`,error:{code:r?-32e3:-32603,message:r?t:`Internal server error`},id:null})}}finally{i()}},X=async(e,n)=>{let r=t(e);if(W&&(!G||r!==K)){await W.handleRequest(e,n,e.body);return}await Y(e,n)};E.post(`/mcp`,X),E.get(`/mcp`,X),E.delete(`/mcp`,X);let Z=E.listen(D,`127.0.0.1`,()=>{v.info(`MCP server listening`,{url:`http://127.0.0.1:${D}/mcp`,port:D}),setTimeout(async()=>{try{typeof L==`string`&&L.length>0&&(T.sources[0]={path:L,excludePatterns:T.sources[0]?.excludePatterns??[]},T.allRoots=[L],v.debug(`Workspace root applied from proxy header`,{wsRoot:L}));let[{createLazyServer:e,createMcpServer:t,ALL_TOOL_NAMES:n},{StreamableHTTPServerTransport:r},{checkForUpdates:o,autoUpgradeScaffold:l}]=await Promise.all([import(`./server-Dm2u4PSm.js`),import(`@modelcontextprotocol/sdk/server/streamableHttp.js`),import(`./startup-maintenance-kHH8tjds.js`).then(e=>e.u)]);o(),l(),setInterval(o,1440*60*1e3).unref();let u=!1,d=m(T),f=e(T,d);q=async()=>{f.aikit&&await Promise.all([f.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),f.aikit.graphStore.close().catch(()=>{}),f.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),f.aikit.store.close().catch(()=>{})])},H=f.server,U=r,z=!0,v.debug(`MCP server configured (lazy — AI Kit initializing in background)`,{toolCount:n.length,resourceCount:2}),f.startInit(),f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);V=new _(f.aikit.stateStore,{staleTimeoutMinutes:M,gcIntervalMinutes:N,onBeforeSessionDelete:e=>{if(K===e&&G){let e=G;G=null,K=null,e.close().catch(()=>void 0)}W?.closeSession(e,{notifySessionEnd:!1})},onSessionEndMaintenance:async()=>{if(!f.aikit?.curated||!f.aikit?.stateStore)return;let{pruneLessons:e}=await import(`./startup-maintenance-kHH8tjds.js`).then(e=>e.x),t=await e(f.aikit.curated,f.aikit.stateStore,{dryRun:!1});t.pruned.length>0&&v.info(`Session-end lesson prune`,{pruned:t.pruned.length})}}),W=new h({createServer:()=>{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);return t(f.aikit,T)},createTransport:e=>new r(e),maxSessions:j,sessionTimeoutMinutes:M,onSessionStart:e=>V?.onSessionStart(e,{transport:`http`}),onSessionActivity:e=>V?.onSessionActivity(e),onSessionEnd:e=>V?.onSessionEnd(e)}),V.startGC(),K&&(V.onSessionStart(K,{transport:`http`}),V.onSessionActivity(K)),v.info(`HTTP session runtime ready`,{maxSessions:j,sessionTimeoutMinutes:M,gcIntervalMinutes:N})}catch(e){v.error(`Failed to start session manager`,c(e)),z=!1,u=!0,H=null,U=null,q=null}}),d===`auto`?f.ready.then(async()=>{try{let e=T.sources.map(e=>e.path).join(`, `);v.info(`Running initial index`,{sourcePaths:e}),await f.runInitialIndex(),v.info(`Initial index complete`)}catch(e){v.error(`Initial index failed; will retry on aikit_reindex`,i(s,e))}}):d===`smart`?u||f.ready.then(async()=>{try{if(!f.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(f.aikit.indexer,T,f.aikit.store),n=f.aikit.store;B=t,t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),f.setSmartScheduler(t),v.debug(`Smart index scheduler started (HTTP mode)`)}catch(e){v.error(`Failed to start smart index scheduler`,i(s,e))}}):v.info(`Initial full indexing skipped in HTTP mode`,{indexMode:d}),f.ready.catch(e=>{v.error(`AI Kit initialization failed`,i(s,e)),z=!1,u=!0,H=null,U=null,q=null}),a(f.ready,()=>f.aikit?{curated:f.aikit.curated,stateStore:f.aikit.stateStore}:null,s)}catch(e){v.error(`Failed to load server modules`,i(s,e)),z=!1,q=null}},100)}),Q=!1,$=async e=>{Q||(Q=!0,v.info(`Shutdown signal received`,{signal:e}),o(),B?.stop(),V?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await W?.closeAll().catch(()=>void 0),K&&V?.onSessionEnd(K),G&&(await G.close().catch(()=>void 0),G=null,K=null),Z.close(),H&&await H.close(),await q?.().catch(()=>void 0),process.exit(0))};process.on(`SIGINT`,()=>$(`SIGINT`)),process.on(`SIGTERM`,()=>$(`SIGTERM`))}export{y as startHttpMode};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./startup-maintenance-
|
|
2
|
+
import{n as e,t}from"./startup-maintenance-cbRSFMY5.js";import{r as n}from"./bin.js";import{a as r,t as i}from"./register-tools-C49Lkpvq.js";import{createLogger as a,serializeError as o,setDetailedErrorLoggingEnabled as s}from"../../core/dist/index.js";const c=a(`server`);var l=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return c.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function u(r){let[{loadConfig:a,reconfigureForWorkspace:u,resolveIndexMode:d},{createLazyServer:f},{checkForUpdates:p,autoUpgradeScaffold:m},{RootsListChangedNotificationSchema:h}]=await Promise.all([import(`./config-DX1KYSbN.js`),import(`./server-CTUxU4KX.js`),import(`./startup-maintenance-cbRSFMY5.js`).then(e=>e.u),import(`@modelcontextprotocol/sdk/types.js`)]),g=a();s(g.logging?.errorDetails===!0),g.configError&&c.warn(`Config load failure`,{error:g.configError}),c.info(`Config loaded`,{sourceCount:g.sources.length,storePath:g.store.path}),m(),setInterval(p,1440*60*1e3).unref();let _=d(g),v=f(g,_),{server:y,startInit:b,ready:x,runInitialIndex:S}=v,{StdioServerTransport:C}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),w=new C;if(typeof w._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);w._readBuffer=new l,c.debug(`JSON repair installed on stdio transport`),await y.connect(w),c.debug(`MCP server started`,{transport:`stdio`}),await n({config:g,indexMode:_,log:c,rootsChangedNotificationSchema:h,reconfigureForWorkspace:u,runInitialIndex:S,server:y,startInit:b,version:r});let T=null,E=null,D=!1,O=async e=>{D||(D=!0,c.info(`Shutdown signal received`,{signal:e}),i(),T&&=(clearTimeout(T),null),E?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await w.close().catch(()=>void 0),await y.close().catch(()=>void 0),v.aikit&&await Promise.all([v.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),v.aikit.graphStore.close().catch(()=>{}),v.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),v.aikit.store.close().catch(()=>{})]),process.exit(0))},k=()=>{T&&clearTimeout(T),T=setTimeout(async()=>{c.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`),i();try{let e=v.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){c.warn(`Resource release failed during shutdown`,o(e))}},18e5),T.unref&&T.unref()};k(),process.stdin.on(`data`,()=>k()),process.stdin.on(`end`,()=>void O(`stdin-end`)),process.stdin.on(`close`,()=>void O(`stdin-close`)),process.stdin.on(`error`,()=>void O(`stdin-error`)),process.on(`SIGINT`,()=>void O(`SIGINT`)),process.on(`SIGTERM`,()=>void O(`SIGTERM`)),x.catch(t=>{c.error(`Initialization failed — server will continue with limited tools`,e(r,t))}),_===`smart`?x.then(async()=>{try{if(!v.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(v.aikit.indexer,g,v.aikit.store);E=t;let n=v.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),v.setSmartScheduler(t),c.debug(`Smart index scheduler started (stdio mode)`)}catch(t){c.error(`Failed to start smart index scheduler`,e(r,t))}}).catch(t=>c.error(`AI Kit init failed for smart scheduler`,e(r,t))):c.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:_}),t(x,()=>v.aikit?{curated:v.aikit.curated,stateStore:v.aikit.stateStore}:null,r)}export{u as startStdioMode};
|